From dc8b044b50bf423659ee45815b6962f7eeefa49d Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Tue, 13 May 2025 02:23:48 +0200 Subject: [PATCH] miniwin: Init graphics API (#73) --- CMakeLists.txt | 13 ++++++ miniwin/miniwin.cpp | 62 +++++++++++++++++++++++++ {util => miniwin}/miniwin.h | 7 +-- miniwin/miniwin_d3d.cpp | 26 +++++++++++ {util => miniwin}/miniwin_d3d.h | 3 +- {util => miniwin}/miniwin_d3drm.h | 0 miniwin/miniwin_ddraw.cpp | 71 +++++++++++++++++++++++++++++ {util => miniwin}/miniwin_ddraw.h | 18 ++------ {util => miniwin}/miniwin_dinput.h | 0 {util => miniwin}/miniwin_direct.h | 0 {util => miniwin}/miniwin_process.h | 0 11 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 miniwin/miniwin.cpp rename {util => miniwin}/miniwin.h (99%) create mode 100644 miniwin/miniwin_d3d.cpp rename {util => miniwin}/miniwin_d3d.h (95%) rename {util => miniwin}/miniwin_d3drm.h (100%) create mode 100644 miniwin/miniwin_ddraw.cpp rename {util => miniwin}/miniwin_ddraw.h (97%) rename {util => miniwin}/miniwin_dinput.h (100%) rename {util => miniwin}/miniwin_direct.h (100%) rename {util => miniwin}/miniwin_process.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c393978..6caa0243 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,6 +155,14 @@ if(WIN32) else() target_link_libraries(tglrl-interface INTERFACE d3drm) endif() +else() + include_directories("${CMAKE_SOURCE_DIR}/miniwin") + add_library(miniwin STATIC + miniwin/miniwin.cpp + miniwin/miniwin_ddraw.cpp + miniwin/miniwin_d3d.cpp) + target_link_libraries(miniwin PRIVATE SDL3::SDL3) + target_link_libraries(tglrl-interface INTERFACE miniwin) endif() add_lego1_static_library(realtime @@ -447,6 +455,8 @@ set(lego1_objects) set(lego1_link_libraries) if(WIN32) list(APPEND lego1_link_libraries dxguid d3drm_guid) +else() + list(APPEND lego1_link_libraries miniwin) endif() foreach(lego1_library IN LISTS lego1_targets) target_compile_definitions(${lego1_library}-objects PRIVATE LEGO1_DLL) @@ -518,6 +528,9 @@ if (ISLE_BUILD_CONFIG) list(APPEND config_SRC util/stdafx.cpp) endif() add_executable(config ${config_SRC}) + if(NOT WIN32) + target_link_libraries(config PUBLIC miniwin) + endif() target_compile_definitions(config PRIVATE _AFXDLL MXDIRECTX_FOR_CONFIG) target_include_directories(config PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/util" "${CMAKE_CURRENT_SOURCE_DIR}/LEGO1") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) diff --git a/miniwin/miniwin.cpp b/miniwin/miniwin.cpp new file mode 100644 index 00000000..e207df49 --- /dev/null +++ b/miniwin/miniwin.cpp @@ -0,0 +1,62 @@ +#include "miniwin.h" + +#include "miniwin_d3d.h" +#include "miniwin_d3drm.h" +#include "miniwin_ddraw.h" + +#include + +bool IsEqualGUID(const GUID& a, const GUID& b) +{ + return a.m_data1 == b.m_data1 && a.m_data2 == b.m_data2 && a.m_data3 == b.m_data3 && a.m_data4 == b.m_data4; +} + +HRESULT IUnknown::QueryInterface(const GUID& riid, void** ppvObject) +{ + if (!ppvObject) { + return DDERR_INVALIDPARAMS; + } + + if (IsEqualGUID(riid, IID_IDirectDraw2)) { + *ppvObject = new IDirectDraw2(); + return S_OK; + } + + if (IsEqualGUID(riid, IID_IDirectDrawSurface3)) { + *ppvObject = new IDirectDrawSurface3(); + return S_OK; + } + + if (IsEqualGUID(riid, IID_IDirect3D2)) { + *ppvObject = new IDirect3D2(); + return S_OK; + } + + if (IsEqualGUID(riid, IID_IDirect3DRM2)) { + *ppvObject = new IDirect3DRM2(); + return S_OK; + } + + if (IsEqualGUID(riid, IID_IDirect3DRMWinDevice)) { + *ppvObject = new IDirect3DRMWinDevice(); + return S_OK; + } + + if (IsEqualGUID(riid, IID_IDirect3DRMMesh) || + IsEqualGUID(riid, IID_IDirect3DRMMeshBuilder)) { // Work around bug in GroupImpl::Bounds() + *ppvObject = new IDirect3DRMMesh(); + return S_OK; + } + + if (IsEqualGUID(riid, IID_IDirect3DRMTexture2)) { + *ppvObject = new IDirect3DRMTexture2(); + return S_OK; + } + + return DDERR_INVALIDPARAMS; +} + +void OutputDebugString(const char* lpOutputString) +{ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", lpOutputString); +} diff --git a/util/miniwin.h b/miniwin/miniwin.h similarity index 99% rename from util/miniwin.h rename to miniwin/miniwin.h index 9ca9d01f..34288ddc 100644 --- a/util/miniwin.h +++ b/miniwin/miniwin.h @@ -198,7 +198,7 @@ typedef GUID* LPGUID; struct IUnknown { virtual ULONG AddRef() { return 0; } virtual ULONG Release() { return 0; } - virtual HRESULT QueryInterface(const GUID& riid, void** ppvObject) { return S_OK; } + virtual HRESULT QueryInterface(const GUID& riid, void** ppvObject); }; typedef struct IUnknown* LPUNKNOWN; @@ -517,10 +517,7 @@ inline BOOL CheckDlgButton(int nIDButton, BOOL uCheck) return TRUE; } -inline void OutputDebugString(const char* lpOutputString) -{ - fprintf(stderr, "%s", lpOutputString); -} +void OutputDebugString(const char* lpOutputString); inline void Enable3dControls() { diff --git a/miniwin/miniwin_d3d.cpp b/miniwin/miniwin_d3d.cpp new file mode 100644 index 00000000..037e92a3 --- /dev/null +++ b/miniwin/miniwin_d3d.cpp @@ -0,0 +1,26 @@ +#include "miniwin_d3d.h" + +HRESULT IDirect3D2::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) +{ + if (!cb) { + return DDERR_INVALIDPARAMS; + } + + GUID deviceGuid = {0xa4665c, 0x2673, 0x11ce, 0x8034a0}; + + char* deviceName = (char*) "MiniWin 3D Device"; + char* deviceDesc = (char*) "Stubbed 3D device"; + + D3DDEVICEDESC halDesc = {}; + halDesc.dcmColorModel = D3DCOLOR_RGB; + halDesc.dwDeviceZBufferBitDepth = DDBD_16; + halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; + D3DDEVICEDESC helDesc = {}; + halDesc.dcmColorModel = D3DCOLOR_RGB; + halDesc.dwDeviceZBufferBitDepth = DDBD_16; + halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; + + cb(&deviceGuid, deviceName, deviceDesc, &halDesc, &helDesc, ctx); + + return S_OK; +} diff --git a/util/miniwin_d3d.h b/miniwin/miniwin_d3d.h similarity index 95% rename from util/miniwin_d3d.h rename to miniwin/miniwin_d3d.h index 911cf80c..2d03489b 100644 --- a/util/miniwin_d3d.h +++ b/miniwin/miniwin_d3d.h @@ -6,7 +6,6 @@ #define D3DPAL_RESERVED 0x00000000 #define D3DPAL_READONLY 0x00000001 #define D3DPTEXTURECAPS_PERSPECTIVE 0x00000001 -#define D3DDD_DEVICEZBUFFERBITDEPTH 32 // --- Enums --- enum D3DCOLORMODEL { @@ -46,6 +45,6 @@ struct IDirect3D2 { { return DDERR_GENERIC; } - virtual HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) { return S_OK; }; + virtual HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx); }; typedef IDirect3D2* LPDIRECT3D2; diff --git a/util/miniwin_d3drm.h b/miniwin/miniwin_d3drm.h similarity index 100% rename from util/miniwin_d3drm.h rename to miniwin/miniwin_d3drm.h diff --git a/miniwin/miniwin_ddraw.cpp b/miniwin/miniwin_ddraw.cpp new file mode 100644 index 00000000..a08947e4 --- /dev/null +++ b/miniwin/miniwin_ddraw.cpp @@ -0,0 +1,71 @@ +#include "miniwin_ddraw.h" + +#include + +HRESULT IDirectDraw::EnumDisplayModes( + DWORD dwFlags, + LPDDSURFACEDESC lpDDSurfaceDesc, + LPVOID lpContext, + LPDDENUMMODESCALLBACK lpEnumModesCallback +) +{ + DDSURFACEDESC ddsd = {}; + ddsd.dwSize = sizeof(DDSURFACEDESC); + ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; + ddsd.dwWidth = 640; + ddsd.dwHeight = 480; + ddsd.lPitch = 0; + + ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | D3DDD_DEVICEZBUFFERBITDEPTH; + ddsd.ddpfPixelFormat.dwRGBBitCount = 16; // Game only accpets 8 or 16 + + if (!lpEnumModesCallback(&ddsd, lpContext)) { + return DDERR_GENERIC; + } + + return S_OK; +} + +HRESULT IDirectDraw::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) +{ + if (lpDDDriverCaps) { + memset(lpDDDriverCaps, 0, sizeof(DDCAPS)); + lpDDDriverCaps->dwSize = sizeof(DDCAPS); + lpDDDriverCaps->dwCaps = 0; + } + + if (lpDDHELCaps) { + memset(lpDDHELCaps, 0, sizeof(DDCAPS)); + lpDDHELCaps->dwSize = sizeof(DDCAPS); + lpDDHELCaps->dwCaps = 0; + } + + return S_OK; +} + +HRESULT DirectDrawCreate(LPGUID lpGuid, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOuter) +{ + if (!lplpDD) { + return DDERR_INVALIDPARAMS; + } + + *lplpDD = new IDirectDraw(); + + return DD_OK; +} + +HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context) +{ + int numDrivers = SDL_GetNumVideoDrivers(); + + for (int i = 0; i < numDrivers; ++i) { + const char* driverName = SDL_GetVideoDriver(i); + + if (!cb(NULL, (LPSTR) driverName, NULL, context)) { + return DDERR_GENERIC; + } + } + + return DD_OK; +} diff --git a/util/miniwin_ddraw.h b/miniwin/miniwin_ddraw.h similarity index 97% rename from util/miniwin_ddraw.h rename to miniwin/miniwin_ddraw.h index ed79e265..ce9051d2 100644 --- a/util/miniwin_ddraw.h +++ b/miniwin/miniwin_ddraw.h @@ -42,6 +42,7 @@ #define DDBLT_KEYSRC 0x00000002 #define DDBLT_ROP 0x00000010 +#define D3DDD_DEVICEZBUFFERBITDEPTH 0x00000010 #define DDPF_PALETTEINDEXED8 0x00000020 #define DDPF_RGB 0x00000040 @@ -311,10 +312,7 @@ struct IDirectDraw : public IUnknown { LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback - ) - { - return DD_OK; - } + ); virtual HRESULT EnumSurfaces( DWORD dwFlags, LPDDSURFACEDESC lpDDSD, @@ -325,7 +323,7 @@ struct IDirectDraw : public IUnknown { return DD_OK; } virtual HRESULT FlipToGDISurface() { return DD_OK; } - virtual HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) { return DDERR_GENERIC; } + virtual HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps); virtual HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) { return DD_OK; } virtual HRESULT Initialize(GUID* lpGUID) { return DD_OK; } virtual HRESULT RestoreDisplayMode() { return DD_OK; } @@ -357,13 +355,7 @@ inline BOOL ClientToScreen(HWND hWnd, LPPOINT lpPoint) return TRUE; } -inline HRESULT DirectDrawCreate(LPGUID lpGuid, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOuter) -{ - return DDERR_GENERIC; -} +HRESULT DirectDrawCreate(LPGUID lpGuid, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOuter); typedef BOOL (*LPDDENUMCALLBACKA)(GUID*, LPSTR, LPSTR, LPVOID); -inline HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context) -{ - return DDERR_GENERIC; -} +HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context); diff --git a/util/miniwin_dinput.h b/miniwin/miniwin_dinput.h similarity index 100% rename from util/miniwin_dinput.h rename to miniwin/miniwin_dinput.h diff --git a/util/miniwin_direct.h b/miniwin/miniwin_direct.h similarity index 100% rename from util/miniwin_direct.h rename to miniwin/miniwin_direct.h diff --git a/util/miniwin_process.h b/miniwin/miniwin_process.h similarity index 100% rename from util/miniwin_process.h rename to miniwin/miniwin_process.h