SDL icon indicating copy to clipboard operation
SDL copied to clipboard

Proposal: Exploring ways to extend SDL3 compatibility for older systems

Open JordanCpp opened this issue 1 month ago • 24 comments

Hello SDL3 team and community,

First of all, thank you for your incredible work on SDL. It's a cornerstone of the cross-platform development world.

I'm writing to you with a proposal and to open a discussion about supporting older operating systems and toolchains in SDL3.

I understand that maintaining support for legacy platforms can be a significant burden and often conflicts with adopting modern APIs and language features. However, there is a niche but passionate community (in retro-gaming, legacy system maintenance, and education) that greatly benefits from having a modern library like SDL on older systems.

To demonstrate both the need and the feasibility, I've been working on two projects:

  1. SDL3Lite: A lightweight, API-compatible implementation of SDL3, written in C++98 for maximum portability. It targets Windows 95+ and old Linux distributions (Debian 3+).
  2. LDL (Little Directmedia Layer): A broader cross-platform media library inspired by SDL's philosophy, supporting even more legacy graphics APIs like DirectDraw, Direct3D 5, and 3dfx Glide.

You can see the projects, build instructions, and screenshots here: SDL3Lite LDL

My work proves that it's technically possible. The screenshots show SDL_Renderer, OpenGL 1.2/3.3 contexts, and texture loading working on these old platforms.

My question to you is: Would you be open to the idea of finding a way to make SDL3 itself more friendly to such porting efforts?

I'm not suggesting to halt progress or compromise SDL3's modern features. Instead, perhaps we could explore:

  • Conditional Compilation: Could key modern C++ features be hidden behind macros, allowing a "legacy mode"?
  • Modularity: Could platform-specific code for ancient systems be moved into separate, optional modules?
  • C Language Compatibility: To emphasize my commitment to portability, I want to state that I am fully ready to abandon C++ and develop a compatible layer purely in C. The language is not a principle for me; the goal of maximum portability is what matters most.
  • Documentation of Dependencies: A clear map of which SDL modules require which modern OS/compiler features.

I am fully aware of the maintenance cost. I am not just asking "if you can do it"; I am offering my help and expertise gained from my LDL and SDL3Lite projects to assist in such an endeavor. I am ready to contribute code, testing, and long-term maintenance for these legacy paths.

Thank you for your time and consideration. I look forward to hearing your thoughts.

Sincerely, Jordan.

JordanCpp avatar Nov 02 '25 20:11 JordanCpp

I've already done a bit of what you're doing, getting SDL3 to work on Windows versions as far back as Windows XP, but there are some restrictions to deal with for new legacy support. New legacy support can get in, if done well within the existing structure.

SDL has always been first and foremost a C library, so you won't get to write functionality in C++ for Windows support. In the case of code that can be C, the project requires it be C, and SDL3 also requires some, but not all, C99 features, like declaration of variables not just at the start of scope. There's a lot of cross platform C99 code every port uses, so all of that has to work on the legacy targets as-is. That means legacy C89 compilers will never be supported, like very old MSVC versions, which leaves you unable to target Windows 95 with the Windows 95 supporting MSVC versions. One of the few places C++ is used is for Haiku support, as Haiku's system APIs are natively C++, not C, with those parts exporting C interfaces for the rest of the code.

The codebase is already modularized for different backends and platforms as needed, so new Windows 9x parts could be added, so long as a working C99 compiler is available. Maybe some old version of GCC could work.

nightmareci avatar Nov 02 '25 22:11 nightmareci

Fwiw, I'm interested in Win95 support as well, but I'm stretched between a bunch of side projects at the moment.

A couple months ago I explored the toolchain problem nightmareci mentioned, and there should be a couple "simple" avenues to get modern language versions up and running, albeit, with outdated stdlibs. The main issue with mingw toolchains afaik is mostly just that the stdlib is compiled with higher requirements than 90s hardware, so you'd need to compile that yourself, some discussion on that here.

It should also be quite feasible to use clang with older MSVC stdlib/Windows SDKs for modern C and C++ language features. I've done some experiments there, and it seems to work, but I've not done anything as complex as SDL yet.

playmer avatar Nov 02 '25 22:11 playmer

Also you should know there's already been some work to bring SDL to DOS. Here's a PR where someone wrote a port for SDL2, and icculus linked to his own branch working on bringing SDL3 to DOS: https://github.com/libsdl-org/SDL/pull/13906#issuecomment-3267729953

So there's certainly interest here!

playmer avatar Nov 02 '25 23:11 playmer

These things can live in the SDL tree too. We aren't against old and weird platforms if someone is supporting the code in small ways.

As was mentioned, there are forks for MS-DOS, we've had OS/2 and QNX, etc.

As for compatibility libraries: Emscripten offers an SDL-1.2 compatible library written from-scratch in JavaScript. We don't care if people do these as external things that don't involve us...a thing written in C++ that targets Windows 95 that is mostly like SDL3 would probably fit in this category.

icculus avatar Nov 03 '25 00:11 icculus

Thank you for the quick and insightful responses! @nightmareci, @playmer, @icculus

I understand the requirements for using C and C99, and this aligns perfectly with my goals for maximum portability. I am fully prepared to work within these constraints.

Taking your comments into account, I would like to start by making a practical contribution. My plan is to begin porting individual SDL3 modules using pure C, conforming to the C99 standard, starting with support for Windows 9x.

My proposed plan of action:

I will start with the most suitable modules – for instance, those related to event handling or basic window management, where work with legacy APIs can be relatively isolated.

I will create Pull Requests focused on:

Pure C code (C99)

Minimal changes to the existing codebase

Clear separation of code using #ifdef SDL_PLATFORM_WIN9X (or a similar define)

Preserving all existing functionality for modern platforms

I will first focus on the toolchain – as @playmer noted, I will use a combination like Clang with older Windows SDKs to ensure compatibility.

A few questions for the team:

Are there any specific modules you would recommend as a starting point?

What prefix or #define do you prefer for conditional compilation targeting such legacy systems?

Are there any specific coding style guidelines I should follow meticulously?

I will begin this work in my fork and create an initial PR for discussion as soon as I have a working proof-of-concept for a module.

Thank you for your openness to this discussion! I look forward to any further advice you may have.

JordanCpp avatar Nov 03 '25 05:11 JordanCpp

My implementation plan:

First phase - stubs only

Create minimal stubs for problematic APIs

Ensure successful compilation for Windows 95

Functionality will be limited, but the code will compile

Second phase - gradual implementation

After successful compilation, I'll start filling the stubs with actual code

I'll add functionality module by module

I'll start with basic input (keyboard/mouse) and window management

I'll start by creating a PR containing only the stub system and conditional compilation to demonstrate the approach.

I'm starting work on the stubs now.

JordanCpp avatar Nov 03 '25 06:11 JordanCpp

I believe work on Win9x is already in progress. You should coordinate with @playmer and @nightmareci.

slouken avatar Nov 03 '25 06:11 slouken

Not sure if it's okay to infodump here, but I'll start here and we can move elsewhere if slouken would prefer it go out of here until it's further along 😅

I didn't get wildly far, but I spent some time trying to get SDL to compile while targeting Win95, that work is here: https://github.com/playmer/SDL-1/commit/465a2bd714b179aa0364d8713e15f2f438543cd8

It's likely I'm not going down a good path there, but I didn't spend too much time on it, I got it compiling (with a ton of stuff disabled, both in CMake and manually in code) with one of the toolchains I was playing with at the time, but it couldn't actually run any SDL applications. Since then I've been busy with other projects.

I've been cobbling together a bunch of scripts that try to assemble together a Clang/MSVC toolchain in this repo. It's not well documented, so I apologize for that. Basically InstallEverything.ps1 tries to go download and install VS2005 Express, the latest clang, the DX9 SDK, and the Windows2003 SDK. Regarding the Microsoft tooling, these were the lowest I could find available officially as download from Microsoft, ideally we'd go lower.

There's also some scripts and toolchain files that try to set up an environment that should allow usage of Clang alongside these SDKs with CMake. It's pretty hacky and certainly needs work. Feel free to grab this stuff and hack at it. The trickiest bit is getting lld-link to target Win95, but those bits in the toolchain files should be mostly correct.

playmer avatar Nov 03 '25 07:11 playmer

I propose the following experimental plan.

Windows 11: install MSVC 2022 and MSVC 2005 and mingw old versions.

Create manual .bat files to build a minimal sdl3.dll.

Include only the core, timer, and similar modules.

When building with MSVC 2022, verify that the build proceeds correctly.

When building with MSVC 2005, observe the errors and identify the necessary #defines for Windows 95/98.

Rewrite the modules to use the legacy WinAPI.

The first task should be to achieve a build with the header files from include/SDL3 and a single core module.

As an example, create the following directories:

  • src/main/win9x
  • src/core/win9x

Then add files and modules to the build one by one via the .bat files.

What do you think of this idea?

JordanCpp avatar Nov 03 '25 08:11 JordanCpp

I don't know that I'd rewrite the subsystems from scratch for 95. My general process would be to get the toolchain working, Make sure you can compile and run test applications utilizing the old SDKs and new compile for 95. Once there, try to build a minimal SDL and see where you run into issues. I'd think that the video subsystem could be reused for example, with hefty conditional compilation.

That said, maybe the maintenance burden is too high and it is just easier to have a different subsystem. You could at least start with the existing one and then trim down on unsupported things/rewrite pieces. Ultimately those decisions are way above my pay grade.

playmer avatar Nov 03 '25 08:11 playmer

For an appropriate toolchain, I've been using this gcc10 based one that targets the crtdll c runtime (available unchanged since windows nt 3.5) https://github.com/edo9300/mingw32-crtdll, for which I made a barebone docker image, it works good enough for my project using c++17 and lua (in this case lua is the only code doing the very few win32 calls). I actually tried compiling sdl3 with this toolchain once, but due to it using the original all mingw headers, there were plenty of missing functions and some other missing import libraries that require very crude patching on the sdl side. But the final library ended up working fine. The fact that the CRT DLL is very old shouldn't really impact sdl itself since sdl has its own c standard library implementation that should be used instead.

edo9300 avatar Nov 03 '25 14:11 edo9300

My suspicion is that for the most part, most of the existing code is close to usable.

The thing that will likely burn you worst is the lack of Unicode APIs on Win95, but we can either provide simple wrappers or require unicows.dll be included with the app.

Otherwise, most of it would follow the same tactics we use for Windows XP: newer system APIs are dynamically loaded and we add fallbacks where appropriate.

The only new modules we'd need would be for the renderer (no direct3d 9 support, I think? The software renderer and OpenGL likely works though, assuming GL drivers still exist) and maybe restore the winmm audio backend (but the directsound backend probably works, so maybe not worth it?).

(I haven't looked at playmer's code, he might have come to the same conclusions.)

icculus avatar Nov 03 '25 15:11 icculus

If SLD can work with opengl 1 it should work fine on those targets as well, as should always be available under windows (and apparently there's a wined3d port for 9x, giving you dx9 on w95 https://github.com/JHRobotics/wine9x). For Unicode APIs, yeah, unicows (or one of the Foss reimplementations) would be needed. Another possible issue would be the gotchas with different behaviors in random win32 APIs that have different workings on those platforms.

edo9300 avatar Nov 03 '25 15:11 edo9300

Thank you for your answers and your willingness to help.

There is a GCC 10 port for Windows 98. It runs on Windows 10 and produces binary code compatible with Windows 98.

I’ll try to integrate it with CMake on Windows.

https://github.com/fsb4000/gcc-for-Windows98?ysclid=mhj98mnd4y348015457

JordanCpp avatar Nov 03 '25 15:11 JordanCpp

Yes, OpenGL 1.2 works on Windows 95, including with 3dfx drivers. Also, opengl32.dll is already built into the operating system. It can operate using only the CPU.

I tested it in the 86Box emulator using Windows 95 OSR2.

JordanCpp avatar Nov 03 '25 16:11 JordanCpp

My suspicion is that for the most part, most of the existing code is close to usable.

The thing that will likely burn you worst is the lack of Unicode APIs on Win95, but we can either provide simple wrappers or require unicows.dll be included with the app.

We generally try to use the macro'd versions of APIs and TEXT() where appropriate, so this shouldn't be too bad.

Otherwise, most of it would follow the same tactics we use for Windows XP: newer system APIs are dynamically loaded and we add fallbacks where appropriate.

We should not start dynamically loading lots and lots of functions that we rely on for XP and Windows 2000 era functionality. A few of these is fine, but I suspect there will be pretty significant changes once this effort gets going. If we start doing this, we should just create a new platform directory for Windows 9x where this is starting to happen and copy and modify the existing Windows code.

slouken avatar Nov 03 '25 16:11 slouken

My suspicion is that for the most part, most of the existing code is close to usable. The thing that will likely burn you worst is the lack of Unicode APIs on Win95, but we can either provide simple wrappers or require unicows.dll be included with the app.

We generally try to use the macro'd versions of APIs and TEXT() where appropriate, so this shouldn't be too bad.

Otherwise, most of it would follow the same tactics we use for Windows XP: newer system APIs are dynamically loaded and we add fallbacks where appropriate.

We should not start dynamically loading lots and lots of functions that we rely on for XP and Windows 2000 era functionality. A few of these is fine, but I suspect there will be pretty significant changes once this effort gets going. If we start doing this, we should just create a new platform directory for Windows 9x where this is starting to happen and copy and modify the existing Windows code.

Having them as single target would allow having a single DLL working everywhere (or keep them separate but still load new APIs dynamically on the current win32 target), but if it ends up being too much of a burden then yeah them being separate would be for the better.

edo9300 avatar Nov 03 '25 17:11 edo9300

In the end, I will try to build SDL3.dll using the new CMake and several older versions of MinGW.

If this doesn’t work for a technical reason, I will use the option with BAT files.

For the modules, I will immediately create my own win9x directory: I will copy the code and remove everything that is not supported.

I have already analyzed the code, and I came up with an idea to create another empty option. These are just function stubs that SDL uses. It will be a template that can be taken, built, and filled with code specific to the operating system. Such an empty project can be built on any platform, as it is essentially a stub.

Thank you again. I suggest continuing the discussion on the SDL3 forum, where we can share our progress and achievements in porting.

JordanCpp avatar Nov 04 '25 07:11 JordanCpp

I was able to build SDL3.DLL using gcc for Windows 98. This does not work on Windows 98. However, the library is binary compatible with Windows 98.

Now I am moving on to the plan for creating SDL3 modules for Windows 98.

Image

SET "PATH=C:\Downloads\gcc_win98\bin"

C:\Downloads\cmake-4.2.0-rc2-windows-x86_64\bin\cmake C:\Repos\SDL\CMakeLists.txt -G "MinGW Makefiles" -DSDL_VIDEO_VULKAN=OFF -DSDL_RENDER_D3D11=OFF -DSDL_RENDER_D3D12=OFF -DSDL_HAPTIC=OFF -DSDL_AUDIO=OFF -DSDL_JOYSTICK=OFF

pause

SET "PATH=C:\MinGW\bin"

C:\Downloads\cmake-4.2.0-rc2-windows-x86_64\bin\cmake --build .

pause

JordanCpp avatar Nov 04 '25 14:11 JordanCpp

A few of these is fine, but I suspect there will be pretty significant changes once this effort gets going.

(Agreed, but I'm hoping it's not many. Knowing exactly what symbols we use that are XP-and-later would be a very good first step.)

icculus avatar Nov 04 '25 17:11 icculus

nm SDL/lib/windows-amd64/libSDL3.a |grep " U " |grep __imp_ |perl -w -p -e 's/\A\s+U __imp_//;'
List of all win32 API calls in SDL3, as of a few weeks ago. Click to see all 560 of them!
  • ExitProcess
  • GetCurrentProcess
  • TerminateProcess
  • __acrt_iob_func
  • AttachConsole
  • GetConsoleMode
  • GetLastError
  • GetStdHandle
  • OutputDebugStringW
  • WriteConsoleW
  • WriteFile
  • _beginthreadex
  • _endthreadex
  • _beginthreadex
  • _endthreadex
  • GetSystemInfo
  • GlobalMemoryStatusEx
  • FreeLibrary
  • GetEnvironmentVariableA
  • GetProcAddress
  • LoadLibraryA
  • MessageBoxA
  • GetDoubleClickTime
  • CancelIo
  • CloseHandle
  • CreateEventW
  • CreateFileW
  • CreateWindowExA
  • DefWindowProcW
  • DestroyWindow
  • DeviceIoControl
  • FormatMessageW
  • FreeLibrary
  • GetLastError
  • GetModuleHandleW
  • GetOverlappedResult
  • GetProcAddress
  • LoadLibraryW
  • MultiByteToWideChar
  • ReadFile
  • RegisterClassExA
  • RegisterDeviceNotificationW
  • ResetEvent
  • UnregisterClassA
  • UnregisterDeviceNotification
  • VerifyVersionInfoW
  • VerSetConditionMask
  • WaitForSingleObject
  • WriteFile
  • CloseHandle
  • CreateFileW
  • FlushFileBuffers
  • GetFileSizeEx
  • GetFileType
  • GetLastError
  • ReadFile
  • SetErrorMode
  • SetFilePointer
  • SetFilePointerEx
  • WriteFile
  • _beginthreadex
  • _endthreadex
  • CloseHandle
  • CreateFileW
  • GetFileTime
  • GetModuleHandleW
  • GetProcAddress
  • WaitForSingleObjectEx
  • FreeEnvironmentStringsW
  • GetEnvironmentStringsW
  • GetEnvironmentVariableA
  • GetLastError
  • SetEnvironmentVariableA
  • SetLastError
  • _i64toa
  • _ltoa
  • _strrev
  • _ui64toa
  • _ultoa
  • _beginthreadex
  • _endthreadex
  • _beginthreadex
  • _endthreadex
  • timeBeginPeriod
  • timeEndPeriod
  • FreeLibrary
  • GetProcAddress
  • LoadLibraryA
  • LoadLibraryW
  • CLSIDFromString
  • CoCreateInstance
  • CoTaskMemFree
  • PropVariantClear
  • CoInitializeEx
  • CoUninitialize
  • CreateWindowExW
  • DefWindowProcW
  • DestroyWindow
  • FormatMessageW
  • GetLastError
  • GetModuleHandleW
  • GetProcAddress
  • LoadLibraryExW
  • RegCloseKey
  • RegisterClassW
  • RegOpenKeyExW
  • RegQueryValueExW
  • UnregisterClassW
  • VerifyVersionInfoW
  • VerSetConditionMask
  • WideCharToMultiByte
  • FreeLibrary
  • GetProcAddress
  • LoadLibraryW
  • CommandLineToArgvW
  • GetCommandLineW
  • GetProcessHeap
  • HeapAlloc
  • HeapFree
  • LocalFree
  • WideCharToMultiByte
  • ShellExecuteW
  • GetDesktopWindow
  • CloseHandle
  • CoTaskMemFree
  • CreateEventW
  • FreeLibrary
  • GetProcAddress
  • LoadLibraryW
  • WaitForSingleObjectEx
  • CreateBitmap
  • CreateCompatibleDC
  • CreateDIBSection
  • CreateIconIndirect
  • DeleteDC
  • DeleteObject
  • GetDC
  • ReleaseDC
  • SelectObject
  • SetPixel
  • CloseClipboard
  • EmptyClipboard
  • EnumClipboardFormats
  • GetClipboardData
  • GetClipboardSequenceNumber
  • GlobalAlloc
  • GlobalFree
  • GlobalLock
  • GlobalSize
  • GlobalUnlock
  • IsClipboardFormatAvailable
  • OpenClipboard
  • SetClipboardData
  • AdjustWindowRectEx
  • BeginPaint
  • CallNextHookEx
  • CallWindowProcW
  • ClientToScreen
  • CloseHandle
  • CreateFileA
  • CreateSolidBrush
  • DefWindowProcW
  • DeleteObject
  • DestroyIcon
  • DispatchMessageW
  • DragFinish
  • DragQueryFileW
  • EndPaint
  • EnumResourceNamesW
  • FillRect
  • GetAsyncKeyState
  • GetClassInfoExW
  • GetClientRect
  • GetCurrentProcess
  • GetCursorPos
  • GetDC
  • GetForegroundWindow
  • GetKeyState
  • GetLastError
  • GetMenu
  • GetMessageExtraInfo
  • GetMessagePos
  • GetMessageTime
  • GetModuleHandleW
  • GetMonitorInfoW
  • GetPropW
  • GetRawInputBuffer
  • GetRawInputDeviceInfoA
  • GetRawInputDeviceList
  • GetSystemMetrics
  • GetTickCount
  • GetUpdateRect
  • GetWindowLongW
  • GetWindowPlacement
  • GetWindowRect
  • InvalidateRect
  • IsIconic
  • IsWow64Process
  • IsZoomed
  • KillTimer
  • LoadIconW
  • MapVirtualKeyW
  • MonitorFromPoint
  • MonitorFromWindow
  • MsgWaitForMultipleObjects
  • PeekMessageW
  • PostMessageW
  • RegisterClassExW
  • ScreenToClient
  • SendMessageW
  • SetCursor
  • SetRectEmpty
  • SetTimer
  • SetupDiDestroyDeviceInfoList
  • SetupDiEnumDeviceInfo
  • SetupDiGetClassDevsA
  • SetupDiGetDeviceInstanceIdA
  • SetupDiGetDeviceRegistryPropertyW
  • SetWindowPos
  • TrackMouseEvent
  • TranslateMessage
  • UnregisterClassW
  • ValidateRect
  • BitBlt
  • CreateCompatibleBitmap
  • CreateCompatibleDC
  • CreateDIBSection
  • DeleteDC
  • DeleteObject
  • GetDIBits
  • SelectObject
  • CompareStringA
  • GetKeyboardLayout
  • GetKeyboardState
  • GetKeyState
  • MapVirtualKeyW
  • ToUnicode
  • CreateCompatibleDC
  • CreateFontIndirectW
  • DeleteDC
  • DialogBoxIndirectParamW
  • DrawTextW
  • EndDialog
  • FreeLibrary
  • GetDC
  • GetDeviceCaps
  • GetDlgItem
  • GetModuleHandleW
  • GetProcAddress
  • GetSystemMetrics
  • GetTextExtentPoint32A
  • GetTextMetricsW
  • GetWindowLongPtrW
  • LoadLibraryW
  • MulDiv
  • PostMessageW
  • ReleaseDC
  • SelectObject
  • SetFocus
  • SetWindowLongPtrW
  • SystemParametersInfoA
  • SystemParametersInfoW
  • ChangeDisplaySettingsExW
  • CreateCompatibleBitmap
  • CreateDCW
  • DeleteDC
  • DeleteObject
  • EnumDisplayDevicesW
  • EnumDisplayMonitors
  • EnumDisplaySettingsW
  • GetDC
  • GetDeviceCaps
  • GetDIBits
  • GetMonitorInfoW
  • ReleaseDC
  • ClientToScreen
  • CreateBitmap
  • CreateDIBSection
  • CreateIconIndirect
  • DeleteObject
  • DestroyCursor
  • GetAsyncKeyState
  • GetCursorPos
  • GetSystemMetrics
  • GetTickCount
  • LoadCursorW
  • RegCloseKey
  • RegOpenKeyExW
  • RegQueryValueExW
  • ReleaseCapture
  • SetCapture
  • SetCursor
  • SetCursorPos
  • SystemParametersInfoW
  • ChoosePixelFormat
  • CreateWindowExW
  • DescribePixelFormat
  • DestroyWindow
  • GetDC
  • GetProcAddress
  • ReleaseDC
  • SetPixelFormat
  • SwapBuffers
  • CloseHandle
  • CreateEventW
  • CreateThread
  • CreateWindowExW
  • DestroyWindow
  • GetCurrentThread
  • GetQueueStatus
  • MsgWaitForMultipleObjects
  • RegisterRawInputDevices
  • SetEvent
  • SetThreadPriority
  • WaitForMultipleObjects
  • WaitForSingleObject
  • CombineRgn
  • CreateRectRgn
  • DeleteObject
  • SetWindowRgn
  • OleInitialize
  • OleUninitialize
  • RegCloseKey
  • RegisterWindowMessageA
  • RegOpenKeyExW
  • RegQueryValueExW
  • SetThreadExecutionState
  • AdjustWindowRectEx
  • AttachThreadInput
  • ClientToScreen
  • ClipCursor
  • CreateDCW
  • CreateIconFromResource
  • CreateRectRgn
  • CreateWindowExW
  • DeleteDC
  • DeleteObject
  • DescribePixelFormat
  • DestroyWindow
  • DragAcceptFiles
  • DragQueryFileW
  • EnableWindow
  • FlashWindowEx
  • FreeLibrary
  • GetClientRect
  • GetClipboardFormatNameA
  • GetClipCursor
  • GetCurrentThreadId
  • GetDC
  • GetFocus
  • GetForegroundWindow
  • GetICMProfileW
  • GetKeyboardState
  • GetLastError
  • GetMenu
  • GetModuleHandleExW
  • GetModuleHandleW
  • GetMonitorInfoW
  • GetPixelFormat
  • GetProcAddress
  • GetSystemMetrics
  • GetWindowLongPtrW
  • GetWindowLongW
  • GetWindowRect
  • GetWindowTextLengthW
  • GetWindowTextW
  • GetWindowThreadProcessId
  • GlobalLock
  • GlobalSize
  • GlobalUnlock
  • IntersectRect
  • LoadLibraryW
  • PtInRect
  • RegisterClipboardFormatW
  • RegisterDragDrop
  • ReleaseDC
  • ReleaseStgMedium
  • RemovePropW
  • RevokeDragDrop
  • ScreenToClient
  • SendMessageW
  • SetActiveWindow
  • SetFocus
  • SetForegroundWindow
  • SetLayeredWindowAttributes
  • SetParent
  • SetPixelFormat
  • SetPropW
  • SetWindowLongPtrW
  • SetWindowLongW
  • SetWindowPos
  • SetWindowsHookExW
  • SetWindowTextW
  • ShowWindow
  • UnhookWindowsHookEx
  • GetCurrentThreadId
  • GetModuleHandleW
  • GetProcAddress
  • DeleteCriticalSection
  • EnterCriticalSection
  • GetCurrentThreadId
  • GetModuleHandleW
  • GetProcAddress
  • InitializeCriticalSectionAndSpinCount
  • LeaveCriticalSection
  • TryEnterCriticalSection
  • GetModuleHandleW
  • GetProcAddress
  • CloseHandle
  • CreateSemaphoreW
  • GetModuleHandleW
  • GetProcAddress
  • ReleaseSemaphore
  • WaitForSingleObjectEx
  • AddVectoredExceptionHandler
  • CloseHandle
  • CreateThread
  • GetCurrentThread
  • GetCurrentThreadId
  • GetModuleHandleW
  • GetProcAddress
  • RaiseException
  • RemoveVectoredExceptionHandler
  • SetThreadPriority
  • WaitForSingleObjectEx
  • TlsAlloc
  • TlsFree
  • TlsGetValue
  • TlsSetValue
  • CoCreateInstance
  • SysFreeString
  • SystemTimeToFileTime
  • GetSystemPowerStatus
  • GetLocaleInfoA
  • GetModuleHandleW
  • GetProcAddress
  • CreateDirectoryW
  • FreeLibrary
  • GetCurrentDirectoryW
  • GetLastError
  • GetModuleFileNameW
  • GetProcAddress
  • LoadLibraryW
  • SHGetFolderPathW
  • CopyFileExW
  • CreateDirectoryW
  • DeleteFileW
  • FindClose
  • FindFirstFileExW
  • FindNextFileW
  • GetFileAttributesExW
  • GetLastError
  • GetLogicalDrives
  • MoveFileExW
  • RemoveDirectoryW
  • FileTimeToSystemTime
  • GetLastError
  • GetLocaleInfoW
  • GetModuleHandleW
  • GetProcAddress
  • GetSystemTimeAsFileTime
  • SystemTimeToFileTime
  • SystemTimeToTzSpecificLocalTime
  • CloseHandle
  • CreateEventW
  • GetModuleHandleW
  • GetProcAddress
  • QueryPerformanceCounter
  • QueryPerformanceFrequency
  • Sleep
  • WaitForSingleObject
  • WaitForSingleObjectEx
  • FreeLibrary
  • GetProcAddress
  • LoadLibraryW
  • CheckMenuItem
  • CreatePopupMenu
  • CreateWindowExW
  • DefWindowProcW
  • DeleteMenu
  • DestroyIcon
  • DestroyMenu
  • DestroyWindow
  • EnableMenuItem
  • GetMenuItemInfoW
  • GetModuleHandleW
  • GetWindowLongPtrW
  • InsertMenuW
  • LoadIconW
  • SetForegroundWindow
  • SetMenuItemInfoW
  • SetWindowLongPtrW
  • Shell_NotifyIconW
  • TrackPopupMenu
  • _beginthreadex
  • _endthreadex
  • _beginthreadex
  • _endthreadex
  • CoCreateInstance
  • GetLastError
  • GetModuleHandleW
  • CallWindowProcW
  • CloseHandle
  • CreateFileA
  • DefWindowProcW
  • GetRawInputData
  • GetRawInputDeviceInfoA
  • GetRawInputDeviceList
  • GetSystemMetrics
  • RegisterRawInputDevices
  • _beginthreadex
  • CallWindowProcW
  • CreateWindowExW
  • DestroyWindow
  • DispatchMessageW
  • _endthreadex
  • GetMessageW
  • GetModuleHandleW
  • KillTimer
  • PostThreadMessageW
  • RegisterClassExW
  • RegisterDeviceNotificationW
  • SetTimer
  • TranslateMessage
  • UnregisterClassW
  • UnregisterDeviceNotification
  • CoCreateInstance
  • GetLastError
  • GetModuleHandleW
  • CoTaskMemFree
  • FreeLibrary
  • GetProcAddress
  • LoadLibraryW
  • _beginthreadex
  • _endthreadex
  • GetProcAddress
  • LoadLibraryW
  • MultiByteToWideChar
  • SendMessageA
  • SHBrowseForFolderW
  • SHGetPathFromIDListW
  • WideCharToMultiByte
  • CloseHandle
  • CreateFileW
  • CreatePipe
  • CreateProcessW
  • DuplicateHandle
  • GetCurrentProcess
  • GetExitCodeProcess
  • GetFileType
  • GetStdHandle
  • SetHandleInformation
  • SetNamedPipeHandleState
  • TerminateProcess
  • WaitForSingleObject
  • CloseHandle
  • CreateEventW
  • FormatMessageA
  • IsWindow
  • WaitForMultipleObjects
  • WaitForSingleObject

icculus avatar Nov 04 '25 17:11 icculus

I've had some scripts lying around looking into the dlls Windows 95, here's the functions from that list that I couldn't find within all the dlls in WINDOWS/SYSTEM. I should probably ensure the symbols I did find are in the dlls we expect...but maybe later. Seems it's only about 39.

Functions that can't be found in Win95 dlls (includes unicows)

__acrt_iob_func AddVectoredExceptionHandler AttachConsole CancelIo CoInitializeEx EnumDisplayMonitors FindFirstFileExW FlashWindowEx GetClipboardSequenceNumber GetFileSizeEx GetModuleHandleExW GetRawInputBuffer GetRawInputData GetRawInputDeviceInfoA GetRawInputDeviceList GetWindowLongPtrW GlobalMemoryStatusEx InitializeCriticalSectionAndSpinCount IsWow64Process MonitorFromPoint MonitorFromWindow PropVariantClear RegisterRawInputDevices RemoveVectoredExceptionHandler SetFilePointerEx SetLayeredWindowAttributes SetThreadExecutionState SetupDiDestroyDeviceInfoList SetupDiEnumDeviceInfo SetupDiGetClassDevsA SetupDiGetDeviceInstanceIdA SetupDiGetDeviceRegistryPropertyW SetWindowLongPtrW SHGetFolderPathW TrackMouseEvent TryEnterCriticalSection UnregisterDeviceNotification VerifyVersionInfoW VerSetConditionMask

playmer avatar Nov 05 '25 00:11 playmer

The _ ones are from specific CRTs so they can be excluded from the count if compiling with an appropriate compiler (in this last list it would be __acrt_iob_func)

edo9300 avatar Nov 05 '25 05:11 edo9300

Yes, OpenGL 1.2 works on Windows 95, including with 3dfx drivers. Also, opengl32.dll is already built into the operating system. It can operate using only the CPU.

I tested it in the 86Box emulator using Windows 95 OSR2.

It should be noted that the RTM build of Windows 95 wasn't equipped with OpenGL support, but it was available back then as a separate redistributable package. There were 3 official versions of it: original 1.0 backport from NT 3.51, then fixed 1.0, and finally 1.1 from NT 4 which is most known.

https://www.vogons.org/viewtopic.php?f=63&t=98762&p=1323893#p1323893 https://www.vogons.org/viewtopic.php?f=61&t=92274&p=1306896#p1306896

cher-nov avatar Nov 10 '25 12:11 cher-nov