A DirectDraw API compatibility layer that enables legacy games from the 1990s-2000s to run on modern Windows systems by translating DirectDraw 7 calls to modern rendering backends (OpenGL or Direct3D 9).
DxEmu (ddraw.dll) is a drop-in replacement for the deprecated DirectDraw library that acts as an emulation layer. Instead of delegating to the original DirectDraw, it translates API calls to modern graphics APIs, allowing classic games to render on contemporary hardware.
Games tested and known to work (partially or fully):
- Arcanum
- Icewind Dale
- Diablo
- Wing Commander series
- State of War
- Theme Hospital
- Submarine Titans
- Command & Conquer series
- Worms series
- Fallout series
- Age of Empires
- Planescape Torment
- Throne of Darkness
- Civilization 2
- Jagged Alliance 2 Gold
See TODO.txt for comprehensive game list and known issues per title.
-
DDraw Module (
ddraw/): DirectDraw API implementation- Interface implementations (IDirectDraw 1-7, IDirectDrawSurface 1-7)
- Surface management and blitting operations
- Color space and pixel format conversions
-
Rendering Backends:
- OpenGL (default): GLRenderContext manages OpenGL 1.1-2.0 contexts
- Direct3D 9: Placeholder implementation (not fully developed)
- Software: CPU-based fallback rendering
-
Core Infrastructure (
dxemu/):- Base COM class with ref-counting
- Centralized logging framework
- Interface wrapper macros
-
Input (
dinput/): DirectInput stub for keyboard/mouse input
Build with exactly one rendering backend enabled via defines in ddraw/ddraw_common.hpp:
#define DDRAW_OPENGL 1 // Default: OpenGL rendering
#define DDRAW_DIRECT3D 0 // Alternative: Direct3D 9
#define DDRAW_SOFTWARE 0 // Fallback: CPU blitting- Visual Studio 2010 or compatible C++ toolchain
- DirectX 7/8 SDK (included in
3rdparty/) - CMFramework (external dependency, expected at
../CMFramework/) - GLBind (external dependency, expected at
../GLBind/) - Windows SDK for Win32 APIs
- Open
dxEmu.slnin Visual Studio - Select configuration:
- Debug: Outputs to
D:\Games\BS\ - Release: Outputs to
D:\Games\State of War\
- Debug: Outputs to
- Build solution (F7 or Build menu)
ddraw.dll(32-bit): Drop into game directory or system folderddraw.lib: Import library for linkingddraw.pdb: Debug symbols
Note: Output paths are hardcoded in .vcxproj and target specific game directories. Modify OutDir property to change deployment location.
- Copy
ddraw.dllto your game's directory (same folder as the game executable) - Run the game normally
- DxEmu will intercept DirectDraw calls and translate them to OpenGL
Enable debug output in ddraw/ddraw_common.hpp:
#define DDRAW_DEBUG 1
#define DXEMU_DEBUG_TO_FILE 1Debug artifacts written to ./DxEmu/ (relative to game executable):
Logs/: API call logs and errorsSurfaceSnapshots/: Surface bitmap dumps for visual debuggingShaders/: Compiled shader source code
All DirectDraw interfaces follow a consistent wrapper pattern:
class CDirectDraw7 : DDrawIntefaceInheritance2(DirectDraw7)
{
// Conditional compilation for proxy vs. native implementation
#if DDRAW_PROXY
LPDIRECTDRAW7 m_iddraw7; // Pass-through to real ddraw
#else
GLRenderContext* m_renderContext; // Native OpenGL rendering
#endif
};- CreateSurface: Allocates
CDirectDrawSurface7with memory layout - Lock: Maps surface memory to CPU or GPU buffers
- Blit: Transfers/transforms pixels between surfaces
- Flip: Swaps front/back buffers for animation
- Unlock: Commits surface changes to rendering backend
- Windowed Mode: Renders to window's OpenGL context via WGL
- Fullscreen Mode: Creates full-screen window with exclusive rendering context
- Double Buffering: Managed via
SwapBuffers()for smooth animation
- Overlays: Not fully implemented
- Page Flipping: Edge cases may not work correctly
- Direct3D Backend: Incomplete; OpenGL is the only mature path
- Input: DirectInput stub only; mouse/keyboard minimal
- Fullscreen Transitions: Some games may not restore properly
See TODO.txt for game-specific workarounds and issues.
For contributing to DxEmu, see .github/copilot-instructions.md for architecture patterns, development workflows, and code conventions.
- Declare in
ddraw/iddraw*.hpp - Implement in
ddraw/iddraw*.cpp - Add debug logging via
DDrawDebugLog() - Wrap rendering-specific logic in
#if DDRAW_OPENGLblocks
- Enable debug snapshots: Set
DXEMU_DEBUG_TO_FILE=1indxemu_common.hpp - Check surface dumps: Look in
./DxEmu/SurfaceSnapshots/ - Search logs: Find API calls and errors in
./DxEmu/Logs/ - Test with specific game from
TODO.txtlist
- OpenGL Backend: Hardware-accelerated; 60+ FPS on modern GPUs
- Software Backend: CPU-bound; typically 10-30 FPS (fallback only)
- Memory: Minimal overhead; surfaces allocated on first use
SSE2 instructions used for optimized pixel operations (EnableEnhancedInstructionSet=StreamingSIMDExtensions2).
MIT License - See LICENSE file for details.
Copyright © 2026 Gabriel Max (dev.zetta@gmail.com)
- DirectDraw 7 Documentation: MSDN
- Game Compatibility: See
TODO.txtfor per-game notes and workarounds - Architecture: See
.github/copilot-instructions.mdfor implementation patterns
When modifying this codebase:
- Follow the COM interface pattern established in existing code
- Use the centralized logging framework (
DDrawDebugLog) - Test with games from the
TODO.txtcompatibility list - Document game-specific workarounds in
TODO.txt - Update this README if changing core architecture