What is free-direct?

free-direct is a C++20 static library that reimplements a focused, game-driven subset of the Microsoft DirectX 3 API — specifically the 2D portions needed to run Speedy Blupi / Speedy Eggbert and Planet Blupi on modern, non-Windows platforms.

It provides the same header-level API shapes as the original DirectDraw, DirectSound, and DirectPlay interfaces so that legacy C++ game code can include <ddraw.h>, <dsound.h>, and <dplay.h> and compile without any change. Internally, the library delegates all rendering to SDL 3, all audio to SDL3 audio streams, and provides dummy stubs for network calls.

Why does it exist?

The original games were Windows-only and depend on the DirectX 3 runtime, which is a proprietary Microsoft technology. Making them run on Linux, macOS, Android, or the Web requires either:

  • Running the Windows binary through a compatibility layer (Wine, etc.), or
  • Recompiling the game source against a portable reimplementation of the DirectX APIs.

free-direct takes the second approach. It lets the game source compile as portable C++20 and link against SDL 3 for the actual platform-specific work. The original game logic is untouched.

Relationship to Speedy Blupi / Speedy Eggbert and Planet Blupi

Speedy Blupi (also known as Speedy Eggbert) and Planet Blupi are classic 2D games that use a fixed, well-known subset of DirectDraw for 2D blitting, palette management, and surface operations. They use DirectSound for PCM sound effects, and they reference DirectPlay for (optional) multiplayer networking.

free-direct is explicitly scoped to the call sites present in those games. Methods and flags that the games never invoke are either stubbed or left unimplemented — the goal is a correct, minimal, and maintainable subset rather than a complete DirectX clone.

Scope note

Compatibility behavior is driven by real call sites in the target game code, not by the DirectX 3 specification. If a feature is not exercised by those games, it is likely missing.

Difference from the original Microsoft DirectX runtime

AspectOriginal DirectX 3free-direct
Platform Windows only Linux, macOS, Windows, Android (partial), Web (planned)
Rendering Hardware-accelerated (HAL / HEL) SDL3 renderer + CPU pixel buffers (software path)
Pixel format Matches physical device Fixed internally to 8-bit paletted or 32-bit RGBA
Flip chain Real page-flip with back buffers Simplified: CPU buffer upload + SDL_RenderPresent
COM Full IUnknown / QueryInterface support Minimal: AddRef/Release work; QueryInterface returns DDERR_UNSUPPORTED
DirectPlay Real UDP/IPX/modem networking All stubs; returns success but performs no I/O
DirectInput Keyboard, mouse, joystick Not implemented; input goes through the free-api WinAPI layer
Direct3D Full 3D pipeline (D3D 5-era) Not implemented; out of scope
License Proprietary MIT

Difference from free-api

The project depends on a companion library called free-api, which is a separate repository. The two libraries have complementary roles:

LibraryWhat it reimplementsTypical headers
free-api WinAPI subset: window creation, message loop, GDI basics, WinMM timers, wide/ANSI string helpers, registry stubs windows.h, mmsystem.h, winuser.h
free-direct DirectX 3 2D subset: DirectDraw, DirectSound, DirectPlay ddraw.h, dsound.h, dplay.h

free-direct is built on top of free-api: its public headers include <windows.h> from free-api (for HWND, HRESULT, DWORD, etc.) and link against free-api::free-api. Game code that uses both DirectX and WinAPI includes both sets of headers.

Design principles

  • Minimal by design — only implement what the target games actually call.
  • SDL3 as the only backend — SDL 3 is used internally and never exposed in public headers.
  • CPU pixel buffers everywhere — all surfaces are backed by std::vector<uint8_t> for simplicity and portability.
  • No COM correctnessQueryInterface is stubbed; reference counting works for memory management, not for COM aggregation.
  • Honest limitations — partial or stub behavior is documented and flagged in code rather than silently misbehaving.

Non-goals

  • Full DirectX 3 API coverage.
  • Hardware-accurate frame timing or color depth emulation.
  • Direct3D (3D pipeline) support.
  • DirectInput support (handled by free-api instead).
  • Real DirectPlay networking.
  • Expanding the implementation beyond what the target games require.