Open Source · MIT License · C++20

Bring legacy Win32 games
to every platform

Free API is a minimal, SDL3-backed reimplementation of a Win32 / WinAPI subset (~1998 era). Drop it in place of windows.h and your old game compiles and runs on Linux, macOS, Android, and the Web — without Wine.

  Legacy game source code  (Speedy Blupi, Planet Blupi, …)
           │
           │  #include <windows.h>, <mmsystem.h>, …Free API  (include/ + src/)
           │
           │  SDL3 · POSIX · TinySoundFont · TinyMidiLoader
           ▼
  Linux · macOS · Windows · Android · Web (Emscripten)
      

What is Free API?

Free API is not Wine, not a full WinAPI emulator, and not a general-purpose compatibility layer. It is a deliberately small, readable C++20 library that covers exactly what classic games like Speedy Blupi and Planet Blupi need to compile and run natively on non-Windows platforms.

Design principles

  • WinAPI-like public headerswindows.h, mmsystem.h, io.h, direct.h and more, drop-in compatible.
  • SDL3 as the sole backend — windowing, events, timers, and audio all route through SDL3; no OS-specific code leaks into the public API.
  • Minimalism — only what is actually needed is implemented. Three stubs beat one wrong abstraction.
  • Hackable — all implementation in a handful of .cpp files; adding support for a new API takes minutes, not weeks.

Target games

The primary targets are Speedy Blupi and Planet Blupi — classic 1990s Windows games whose source code has since been released. Both depend on a small, well-defined WinAPI subset that Free API fully covers.

Note Free API is equally applicable to any other legacy Win32 game or application that uses a similar 1998-era API surface.

Implementation status tags

Every public symbol in Free API carries a status annotation so you always know how complete a given function is.

TagMeaning
IMPLEMENTEDUseful, non-trivial implementation for the target subset. Behaves like real Windows for the relevant call patterns.
PARTIALWorks for a narrow subset of flags or formats; may differ from real Windows in edge cases.
STUBPlaceholder: compiles, returns a fixed value or does nothing. Safe to call but has no real effect.
HEADER_ONLYMacro, typedef, or inline function in a header; no .cpp needed.

What Free API covers

A curated subset of Win32 APIs sufficient for 1990s-era games and applications.

🪟

Windowing

Full window lifecycle — RegisterClassA, CreateWindowExA, ShowWindow, DestroyWindow — backed by an SDL3 window.

📨

Message Loop

WinAPI-compatible message queue with PeekMessageA, GetMessageA, DispatchMessageA, PostMessageA, PostQuitMessage, and WaitMessage.

🖱️

Mouse Input

SDL3 mouse events translated to WM_MOUSEMOVE, WM_LBUTTONDOWN/UP, WM_RBUTTONDOWN/UP, WM_MBUTTONDOWN/UP with full MK_* modifier flags.

⌨️

Keyboard Input

Full VK_* key set: A–Z, 0–9, arrows, function keys F1–F12, Escape, Enter, Space, Tab, Backspace, Delete, Insert, Page Up/Down, Home, End, Shift, Ctrl, Alt.

🎵

MIDI / MCI Music

MIDI playback via TinySoundFont + TinyMidiLoader over SDL3 audio. Supports MCI_OPEN, MCI_PLAY, MCI_CLOSE, midiOutSetVolume. Requires a SoundFont .sf2 file.

⏱️

Multimedia Timers

timeSetEvent / timeKillEvent implemented with SDL3 timers. Periodic callbacks fire on a private thread; PostMessage from a timer callback is thread-safe.

🖼️

GDI Bitmap Subset

Memory DCs, bitmap loading (LoadImageA / BMP via SDL_image), SelectObject, StretchBlt with nearest-neighbour scaling, GetPixel / SetPixel.

📁

File / Path Helpers

POSIX wrappers for _lopen/_lread/_lclose, _findfirst/_findnext/_findclose, CreateDirectoryA, DeleteFileA, _chdir/_getcwd/_mkdir.

🔄

fopen Path Normaliser

Transparent wrapper that converts Windows backslash paths and drive letters to POSIX paths. Applied automatically when any C++ file includes <windows.h>.

🚀

WinMain Bridge

FREE_API_IMPLEMENT_WINMAIN() macro creates a standard main() that calls a WinMain-style entry point — zero source changes required.

🛠️

System Utilities

GetTickCount, Sleep, OutputDebugString, GetSystemMetrics, GlobalMemoryStatus, GetLastError / SetLastError.

🔡

CRT Extras

Legacy CRT helpers: wsprintfA (vsnprintf-based), memory macros ZeroMemory / CopyMemory / FillMemory, RGB() colour macro.

Platform support

Because Free API routes everything through SDL3, it inherits SDL3's broad platform reach.

🐧

Linux

Supported

🍎

macOS

Supported

🪟

Windows

Supported*

📱

Android

Supported

🌐

Web (Emscripten)

Supported†

* On Windows, Free API routes through SDL3 rather than WinMM for MIDI (native WinMM not used).
† Web audio may require a user gesture before playback starts due to browser autoplay policy.

Building Free API

Free API uses CMake and SDL3. The simplest build:

bash
# Clone the repository
git clone https://github.com/openeggbert/free-api.git
cd free-api

# Configure (tests enabled by default on non-Emscripten builds)
cmake -B build -DFREE_API_BUILD_TESTS=ON

# Build
cmake --build build

# Run tests
ctest --test-dir build
      
SDL3 dependency Free API expects SDL3, SDL3_image and SDL3_mixer targets to be available. When building as part of the free-eggbert super-project, the vendored SDL is set up automatically via ThirdPartySDL.cmake.

Web / Emscripten build

bash
emcmake cmake -B build-web -DFREE_API_BUILD_TESTS=OFF
cmake --build build-web
      

Android build

Android is supported when SDL3 is configured for Android. Package your SoundFont .sf2 in assets/soundfont/default.sf2 inside the APK.