From f5cb2d47324118c91e4f1760885752c91c49321d Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Fri, 16 May 2025 04:22:40 +0200 Subject: [PATCH 1/8] Use consts in callbacks (#1494) --- LEGO1/mxdirectx/mxdirectxinfo.cpp | 16 ++++++++-------- LEGO1/mxdirectx/mxdirectxinfo.h | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/LEGO1/mxdirectx/mxdirectxinfo.cpp b/LEGO1/mxdirectx/mxdirectxinfo.cpp index 4d2950e3..11ca9da2 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.cpp +++ b/LEGO1/mxdirectx/mxdirectxinfo.cpp @@ -41,7 +41,7 @@ MxDriver::MxDriver(LPGUID p_guid) // FUNCTION: CONFIG 0x00401180 // FUNCTION: LEGO1 0x1009ba80 // FUNCTION: BETA10 0x1011d8b6 -MxDriver::MxDriver(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) +MxDriver::MxDriver(LPGUID p_guid, LPCSTR p_driverDesc, LPCSTR p_driverName) { m_guid = NULL; m_driverDesc = NULL; @@ -70,7 +70,7 @@ MxDriver::~MxDriver() // FUNCTION: CONFIG 0x00401330 // FUNCTION: LEGO1 0x1009bc30 // FUNCTION: BETA10 0x1011da89 -void MxDriver::Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) +void MxDriver::Init(LPGUID p_guid, LPCSTR p_driverDesc, LPCSTR p_driverName) { if (m_driverDesc) { delete[] m_driverDesc; @@ -103,8 +103,8 @@ void MxDriver::Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName) // FUNCTION: BETA10 0x1011dbd0 Direct3DDeviceInfo::Direct3DDeviceInfo( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ) @@ -135,8 +135,8 @@ Direct3DDeviceInfo::~Direct3DDeviceInfo() // FUNCTION: BETA10 0x1011dca6 void Direct3DDeviceInfo::Initialize( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ) @@ -320,8 +320,8 @@ HRESULT MxDeviceEnumerate::EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd) // FUNCTION: BETA10 0x1011e32f HRESULT MxDeviceEnumerate::EnumDevicesCallback( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ) diff --git a/LEGO1/mxdirectx/mxdirectxinfo.h b/LEGO1/mxdirectx/mxdirectxinfo.h index ac68af79..ba6b1f00 100644 --- a/LEGO1/mxdirectx/mxdirectxinfo.h +++ b/LEGO1/mxdirectx/mxdirectxinfo.h @@ -67,16 +67,16 @@ struct Direct3DDeviceInfo { ~Direct3DDeviceInfo(); Direct3DDeviceInfo( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ); void Initialize( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ); @@ -115,9 +115,9 @@ struct MxDriver { MxDriver() {} ~MxDriver(); MxDriver(LPGUID p_guid); - MxDriver(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName); + MxDriver(LPGUID p_guid, LPCSTR p_driverDesc, LPCSTR p_driverName); - void Init(LPGUID p_guid, LPSTR p_driverDesc, LPSTR p_driverName); + void Init(LPGUID p_guid, LPCSTR p_driverDesc, LPCSTR p_driverName); LPGUID m_guid; // 0x00 char* m_driverDesc; // 0x04 @@ -198,8 +198,8 @@ class MxDeviceEnumerate { HRESULT EnumDisplayModesCallback(LPDDSURFACEDESC p_ddsd); HRESULT EnumDevicesCallback( LPGUID p_guid, - LPSTR p_deviceDesc, - LPSTR p_deviceName, + LPCSTR p_deviceDesc, + LPCSTR p_deviceName, LPD3DDEVICEDESC p_HWDesc, LPD3DDEVICEDESC p_HELDesc ); From 46ae3fbe892c88d07d5fb88b5c97d29be7b58232 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Fri, 16 May 2025 06:11:06 +0200 Subject: [PATCH 2/8] Order enums the same way in both places (#1495) To match LEGO1/mxdirectx/mxdirectdraw.cpp so it's not so confusing to compare uage --- LEGO1/omni/src/video/mxdisplaysurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index 3e235d9c..86f1b4dc 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -196,7 +196,7 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam) ddsd.dwSize = sizeof(ddsd); ddsd.dwBackBufferCount = m_videoParam.GetBackBuffers(); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX; if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface1, NULL)) { goto done; From 115fa35d5ab9e4f55a78bec3e905c70ea9618094 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Fri, 16 May 2025 15:32:39 +0200 Subject: [PATCH 3/8] Implement more D3DRM skeleton (#94) --- miniwin/miniwin/src/miniwin_d3drm.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/miniwin/miniwin/src/miniwin_d3drm.cpp b/miniwin/miniwin/src/miniwin_d3drm.cpp index 7a7eb589..867240ad 100644 --- a/miniwin/miniwin/src/miniwin_d3drm.cpp +++ b/miniwin/miniwin/src/miniwin_d3drm.cpp @@ -3,6 +3,21 @@ #include #include +struct Direct3DRMTextureImpl : public IDirect3DRMTexture2 { + HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) override { return DD_OK; } + LPVOID GetAppData() override { return m_data; } + HRESULT SetAppData(LPD3DRM_APPDATA appData) override + { + m_data = appData; + return DD_OK; + } + HRESULT SetTexture(const IDirect3DRMTexture* texture) override { return DD_OK; } + HRESULT Changed(BOOL arg1, BOOL arg2) override { return DD_OK; } + +private: + LPD3DRM_APPDATA m_data; +}; + struct Direct3DRMDevice2Impl : public IDirect3DRMDevice2 { unsigned long GetWidth() override { return 640; } unsigned long GetHeight() override { return 480; } @@ -191,17 +206,17 @@ struct Direct3DRMImpl : public IDirect3DRM2 { } HRESULT CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) override { - assert(false && "unimplemented"); + *outTexture = static_cast(new Direct3DRMTextureImpl); return DDERR_GENERIC; } HRESULT CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture) override { - assert(false && "unimplemented"); + *outTexture = static_cast(new Direct3DRMTextureImpl); return DDERR_GENERIC; } HRESULT CreateMesh(IDirect3DRMMesh** outMesh) override { - assert(false && "unimplemented"); + // TODO return DDERR_GENERIC; } HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) override From c99f7c36c6d5f4b6620a97f1ca9d4afe8de3959b Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 16 May 2025 21:37:16 +0200 Subject: [PATCH 4/8] Split miniwin headers and implementation (#96) * Split miniwin headers and implementation * Update miniwin/miniwin/src/miniwin_ddsurface.cpp Co-authored-by: Anders Jenbo * Update miniwin/miniwin/src/miniwin_ddraw.cpp Co-authored-by: Anders Jenbo * Update miniwin/miniwin/src/miniwin_ddsurface.cpp Co-authored-by: Anders Jenbo * Update miniwin/miniwin/src/miniwin_ddsurface.cpp * Update miniwin/miniwin/src/miniwin_ddraw.cpp Co-authored-by: Anders Jenbo * Update miniwin/miniwin/src/miniwin_ddraw.cpp Co-authored-by: Anders Jenbo --------- Co-authored-by: Anders Jenbo --- CMakeLists.txt | 5 +- .../miniwin/src/include/miniwin_ddclipper_p.h | 14 + .../miniwin/src/include/miniwin_ddpalette_p.h | 10 + miniwin/miniwin/src/include/miniwin_ddraw_p.h | 37 ++ .../miniwin/src/include/miniwin_ddsurface_p.h | 43 ++ miniwin/miniwin/src/include/miniwin_p.h | 25 + miniwin/miniwin/src/miniwin.cpp | 1 - miniwin/miniwin/src/miniwin_d3d.cpp | 1 - miniwin/miniwin/src/miniwin_d3drm.cpp | 2 + miniwin/miniwin/src/miniwin_ddclipper.cpp | 15 + miniwin/miniwin/src/miniwin_ddpalette.cpp | 21 + miniwin/miniwin/src/miniwin_ddraw.cpp | 542 +++++++----------- miniwin/miniwin/src/miniwin_ddsurface.cpp | 216 +++++++ 13 files changed, 585 insertions(+), 347 deletions(-) create mode 100644 miniwin/miniwin/src/include/miniwin_ddclipper_p.h create mode 100644 miniwin/miniwin/src/include/miniwin_ddpalette_p.h create mode 100644 miniwin/miniwin/src/include/miniwin_ddraw_p.h create mode 100644 miniwin/miniwin/src/include/miniwin_ddsurface_p.h create mode 100644 miniwin/miniwin/src/include/miniwin_p.h delete mode 100644 miniwin/miniwin/src/miniwin_d3d.cpp create mode 100644 miniwin/miniwin/src/miniwin_ddclipper.cpp create mode 100644 miniwin/miniwin/src/miniwin_ddpalette.cpp create mode 100644 miniwin/miniwin/src/miniwin_ddsurface.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 303e7619..b0a952a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,11 +87,14 @@ endif() #if (NOT WIN32) add_library(miniwin STATIC EXCLUDE_FROM_ALL miniwin/miniwin/src/miniwin.cpp + miniwin/miniwin/src/miniwin_ddclipper.cpp + miniwin/miniwin/src/miniwin_ddpalette.cpp + miniwin/miniwin/src/miniwin_ddsurface.cpp miniwin/miniwin/src/miniwin_ddraw.cpp - miniwin/miniwin/src/miniwin_d3d.cpp miniwin/miniwin/src/miniwin_d3drm.cpp ) target_include_directories(miniwin PUBLIC "$") +target_include_directories(miniwin PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/miniwin/miniwin/src/include") target_compile_definitions(miniwin PUBLIC "MINIWIN") target_link_libraries(miniwin PRIVATE SDL3::SDL3) diff --git a/miniwin/miniwin/src/include/miniwin_ddclipper_p.h b/miniwin/miniwin/src/include/miniwin_ddclipper_p.h new file mode 100644 index 00000000..0c094824 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_ddclipper_p.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +class DirectDrawImpl; + +struct DirectDrawClipperImpl : public IDirectDrawClipper { + DirectDrawClipperImpl(DirectDrawImpl* lpDD); + ~DirectDrawClipperImpl() override; + + // IDirectDrawClipper interface + HRESULT SetHWnd(DWORD unnamedParam1, HWND hWnd) override; +}; diff --git a/miniwin/miniwin/src/include/miniwin_ddpalette_p.h b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h new file mode 100644 index 00000000..04804431 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h @@ -0,0 +1,10 @@ +#pragma once + +#include "miniwin_ddraw.h" + +struct DirectDrawPaletteImpl : public IDirectDrawPalette { + DirectDrawPaletteImpl(LPPALETTEENTRY lpColorTable); + HRESULT GetCaps(LPDWORD lpdwCaps) override; + HRESULT GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) override; + HRESULT SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) override; +}; diff --git a/miniwin/miniwin/src/include/miniwin_ddraw_p.h b/miniwin/miniwin/src/include/miniwin_ddraw_p.h new file mode 100644 index 00000000..1dba2d71 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_ddraw_p.h @@ -0,0 +1,37 @@ +#pragma once + +#include "miniwin_d3d.h" +#include "miniwin_ddraw.h" + +extern struct SDL_Renderer* renderer; + +struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 { + // IUnknown interface + HRESULT QueryInterface(const GUID& riid, void** ppvObject) override; + // IDirectDraw interface + HRESULT CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) override; + HRESULT + CreatePalette( + DDPixelCaps dwFlags, + LPPALETTEENTRY lpColorTable, + LPDIRECTDRAWPALETTE* lplpDDPalette, + IUnknown* pUnkOuter + ) override; + HRESULT CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter) + override; + HRESULT EnumDisplayModes( + DWORD dwFlags, + LPDDSURFACEDESC lpDDSurfaceDesc, + LPVOID lpContext, + LPDDENUMMODESCALLBACK lpEnumModesCallback + ) override; + HRESULT FlipToGDISurface() override; + HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) override; + HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) override; + HRESULT RestoreDisplayMode() override; + HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) override; + HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) override; + // IDirect3D2 interface + HRESULT CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) override; + HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) override; +}; diff --git a/miniwin/miniwin/src/include/miniwin_ddsurface_p.h b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h new file mode 100644 index 00000000..df8ec4a8 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { + DirectDrawSurfaceImpl(); + DirectDrawSurfaceImpl(int width, int height); + ~DirectDrawSurfaceImpl() override; + + // IUnknown interface + HRESULT QueryInterface(const GUID& riid, void** ppvObject) override; + // IDirectDrawSurface interface + HRESULT AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) override; + HRESULT Blt( + LPRECT lpDestRect, + LPDIRECTDRAWSURFACE lpDDSrcSurface, + LPRECT lpSrcRect, + DDBltFlags dwFlags, + LPDDBLTFX lpDDBltFx + ) override; + HRESULT BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans) + override; + HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override; + HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) override; + HRESULT GetCaps(LPDDSCAPS lpDDSCaps) override; + HRESULT GetDC(HDC* lphDC) override; + HRESULT GetOverlayPosition(LPLONG lplX, LPLONG lplY) override; + HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override; + HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override; + HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) override; + HRESULT IsLost() override; + HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override; + HRESULT ReleaseDC(HDC hDC) override; + HRESULT Restore() override; + HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) override; + HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override; + HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override; + HRESULT Unlock(LPVOID lpSurfaceData) override; + +private: + SDL_Texture* texture = nullptr; +}; diff --git a/miniwin/miniwin/src/include/miniwin_p.h b/miniwin/miniwin/src/include/miniwin_p.h new file mode 100644 index 00000000..c5fcc201 --- /dev/null +++ b/miniwin/miniwin/src/include/miniwin_p.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#define LOG_CATEGORY_MINIWIN (SDL_LOG_CATEGORY_CUSTOM) + +#define MINIWIN_TRACE(FUNCTION, MSG, ...) \ + do { \ + SDL_LogTrace(LOG_CATEGORY_MINIWIN, FUNCTION); \ + } + +#define MINIWIN_ERROR(MSG) \ + do { \ + SDL_LogError(LOG_CATEGORY_MINIWIN, "%s:%s", __func__, MSG); \ + } while (0) + +static SDL_FRect ConvertRect(const RECT* r) +{ + SDL_FRect sdlRect; + sdlRect.x = r->left; + sdlRect.y = r->top; + sdlRect.w = r->right - r->left; + sdlRect.h = r->bottom - r->top; + return sdlRect; +} diff --git a/miniwin/miniwin/src/miniwin.cpp b/miniwin/miniwin/src/miniwin.cpp index 92da13ce..7eaad90e 100644 --- a/miniwin/miniwin/src/miniwin.cpp +++ b/miniwin/miniwin/src/miniwin.cpp @@ -1,7 +1,6 @@ #include "miniwin.h" #include -#include #include ULONG IUnknown::AddRef() diff --git a/miniwin/miniwin/src/miniwin_d3d.cpp b/miniwin/miniwin/src/miniwin_d3d.cpp deleted file mode 100644 index f91143af..00000000 --- a/miniwin/miniwin/src/miniwin_d3d.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "miniwin_d3d.h" diff --git a/miniwin/miniwin/src/miniwin_d3drm.cpp b/miniwin/miniwin/src/miniwin_d3drm.cpp index 867240ad..a7fc9fd2 100644 --- a/miniwin/miniwin/src/miniwin_d3drm.cpp +++ b/miniwin/miniwin/src/miniwin_d3drm.cpp @@ -1,5 +1,7 @@ #include "miniwin_d3drm.h" +#include "miniwin_ddsurface_p.h" + #include #include diff --git a/miniwin/miniwin/src/miniwin_ddclipper.cpp b/miniwin/miniwin/src/miniwin_ddclipper.cpp new file mode 100644 index 00000000..79dfa882 --- /dev/null +++ b/miniwin/miniwin/src/miniwin_ddclipper.cpp @@ -0,0 +1,15 @@ +#include "miniwin_ddclipper_p.h" +#include "miniwin_ddraw_p.h" + +DirectDrawClipperImpl::DirectDrawClipperImpl(DirectDrawImpl* lpDD) +{ +} + +DirectDrawClipperImpl::~DirectDrawClipperImpl() +{ +} + +HRESULT DirectDrawClipperImpl::SetHWnd(DWORD unnamedParam1, HWND hWnd) +{ + return DD_OK; +} diff --git a/miniwin/miniwin/src/miniwin_ddpalette.cpp b/miniwin/miniwin/src/miniwin_ddpalette.cpp new file mode 100644 index 00000000..0615f06c --- /dev/null +++ b/miniwin/miniwin/src/miniwin_ddpalette.cpp @@ -0,0 +1,21 @@ +#include "miniwin_ddpalette_p.h" +#include "miniwin_ddraw.h" + +DirectDrawPaletteImpl::DirectDrawPaletteImpl(LPPALETTEENTRY lpColorTable) +{ +} + +HRESULT DirectDrawPaletteImpl::GetCaps(LPDWORD lpdwCaps) +{ + return DD_OK; +} + +HRESULT DirectDrawPaletteImpl::GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) +{ + return DD_OK; +} + +HRESULT DirectDrawPaletteImpl::SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) +{ + return DD_OK; +} diff --git a/miniwin/miniwin/src/miniwin_ddraw.cpp b/miniwin/miniwin/src/miniwin_ddraw.cpp index 85036003..7d4a7c43 100644 --- a/miniwin/miniwin/src/miniwin_ddraw.cpp +++ b/miniwin/miniwin/src/miniwin_ddraw.cpp @@ -1,6 +1,10 @@ -#include "miniwin_ddraw.h" #include "miniwin_d3d.h" +#include "miniwin_ddclipper_p.h" +#include "miniwin_ddpalette_p.h" +#include "miniwin_ddraw_p.h" +#include "miniwin_ddsurface_p.h" +#include "miniwin_p.h" #include #include @@ -10,360 +14,96 @@ SDL_Renderer* renderer; -static SDL_FRect ConvertRect(const RECT* r) +HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject) { - SDL_FRect sdlRect; - sdlRect.x = r->left; - sdlRect.y = r->top; - sdlRect.w = r->right - r->left; - sdlRect.h = r->bottom - r->top; - return sdlRect; + if (SDL_memcmp(&riid, &IID_IDirectDraw2, sizeof(GUID)) == 0) { + this->IUnknown::AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } + if (SDL_memcmp(&riid, &IID_IDirect3D2, sizeof(GUID)) == 0) { + this->IUnknown::AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } + SDL_LogError(LOG_CATEGORY_MINIWIN, "DirectDrawImpl does not implement guid"); + return E_NOINTERFACE; } -struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { - DirectDrawSurfaceImpl() {} - DirectDrawSurfaceImpl(int width, int height) - { - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError()); - } - } +// IDirectDraw interface +HRESULT DirectDrawImpl::CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) +{ + *lplpDDClipper = static_cast(new DirectDrawClipperImpl(this)); - ~DirectDrawSurfaceImpl() override - { - if (texture) { - SDL_DestroyTexture(texture); - } - } - // IUnknown interface - HRESULT QueryInterface(const GUID& riid, void** ppvObject) override - { - if (SDL_memcmp(&riid, &IID_IDirectDrawSurface3, sizeof(GUID)) == 0) { - this->IUnknown::AddRef(); - *ppvObject = static_cast(this); - return S_OK; - } - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDrawImpl does not implement guid"); - return E_NOINTERFACE; - } - // IDirectDrawSurface interface - HRESULT AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) override { return DD_OK; } - HRESULT Blt( - LPRECT lpDestRect, - LPDIRECTDRAWSURFACE lpDDSrcSurface, - LPRECT lpSrcRect, - DDBltFlags dwFlags, - LPDDBLTFX lpDDBltFx - ) override - { - if (!renderer) { - return DDERR_GENERIC; - } - SDL_FRect srcRect = ConvertRect(lpSrcRect); - SDL_FRect dstRect = ConvertRect(lpDestRect); - SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->texture, &srcRect, &dstRect); - SDL_RenderPresent(renderer); - return DD_OK; - } - HRESULT BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans) - override - { - if (!renderer) { - return DDERR_GENERIC; - } - SDL_FRect dstRect = { - (float) dwX, - (float) dwY, - (float) (lpSrcRect->right - lpSrcRect->left), - (float) (lpSrcRect->bottom - lpSrcRect->top) - }; - SDL_FRect srcRect = ConvertRect(lpSrcRect); - SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->texture, &srcRect, &dstRect); - SDL_RenderPresent(renderer); - return DD_OK; - } - HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override - { - if (!renderer || !texture) { - return DDERR_GENERIC; - } - float width, height; - SDL_GetTextureSize(texture, &width, &height); - SDL_FRect rect{0, 0, width, height}; - SDL_RenderTexture(renderer, texture, &rect, &rect); - SDL_RenderPresent(renderer); - return DD_OK; - } - HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) override - { - if ((lpDDSCaps->dwCaps & DDSCAPS_BACKBUFFER) != DDSCAPS_BACKBUFFER) { - return DDERR_INVALIDPARAMS; - } - *lplpDDAttachedSurface = static_cast(this); - return DD_OK; - } - HRESULT GetCaps(LPDDSCAPS lpDDSCaps) override { return DD_OK; } - HRESULT GetDC(HDC* lphDC) override { return DD_OK; } - HRESULT GetOverlayPosition(LPLONG lplX, LPLONG lplY) override { return DD_OK; } - HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override { return DDERR_GENERIC; } - HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override - { - memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat)); - lpDDPixelFormat->dwFlags = DDPF_RGB; - return DD_OK; - } - HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) override - { - if (!texture) { - return DDERR_GENERIC; - } - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); - lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; - lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; - lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; - return DD_OK; - } - HRESULT IsLost() override { return DD_OK; } - HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override - { - if (!lpDDSurfaceDesc) { - return DDERR_INVALIDPARAMS; - } - if (!texture) { - return DDERR_GENERIC; - } + return DD_OK; +} - int pitch = 0; - void* pixels = nullptr; - if (SDL_LockTexture(texture, (SDL_Rect*) lpDestRect, &pixels, &pitch) < 0) { - return DDERR_GENERIC; - } +HRESULT DirectDrawImpl::CreatePalette( + DDPixelCaps dwFlags, + LPPALETTEENTRY lpColorTable, + LPDIRECTDRAWPALETTE* lplpDDPalette, + IUnknown* pUnkOuter +) +{ + *lplpDDPalette = static_cast(new DirectDrawPaletteImpl(lpColorTable)); + return DD_OK; +} - lpDDSurfaceDesc->lpSurface = pixels; - lpDDSurfaceDesc->lPitch = pitch; - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); - lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; - lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; - lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; - - return DD_OK; - } - HRESULT ReleaseDC(HDC hDC) override { return DD_OK; } - HRESULT Restore() override { return DD_OK; } - HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) override { return DD_OK; } - HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override { return DD_OK; } - HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override { return DD_OK; } - HRESULT Unlock(LPVOID lpSurfaceData) override - { - if (texture) { - SDL_UnlockTexture(texture); +HRESULT DirectDrawImpl::CreateSurface( + LPDDSURFACEDESC lpDDSurfaceDesc, + LPDIRECTDRAWSURFACE* lplpDDSurface, + IUnknown* pUnkOuter +) +{ + if ((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) == DDSD_CAPS) { + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER) { + if ((lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) != DDSD_ZBUFFERBITDEPTH) { + return DDERR_INVALIDPARAMS; + } + SDL_Log("Todo: Set %dbit Z-Buffer", lpDDSurfaceDesc->dwZBufferBitDepth); + *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl); return DD_OK; } - return DDERR_GENERIC; - } - -private: - SDL_Texture* texture = nullptr; -}; - -struct DirectDrawClipperImpl : public IDirectDrawClipper { - // IDirectDrawClipper interface - HRESULT SetHWnd(DWORD unnamedParam1, HWND hWnd) override { return DD_OK; } -}; - -struct DirectDrawPaletteImpl : public IDirectDrawPalette { - HRESULT GetCaps(LPDWORD lpdwCaps) override { return DD_OK; } - HRESULT GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) override - { - return DD_OK; - } - HRESULT SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) override - { - return DD_OK; - } -}; - -struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 { - // IUnknown interface - HRESULT QueryInterface(const GUID& riid, void** ppvObject) override - { - if (SDL_memcmp(&riid, &IID_IDirectDraw2, sizeof(GUID)) == 0) { - this->IUnknown::AddRef(); - *ppvObject = static_cast(this); - return S_OK; - } - if (SDL_memcmp(&riid, &IID_IDirect3D2, sizeof(GUID)) == 0) { - this->IUnknown::AddRef(); - *ppvObject = static_cast(this); - return S_OK; - } - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDrawImpl does not implement guid"); - return E_NOINTERFACE; - } - // IDirecdtDraw interface - HRESULT CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) override - { - *lplpDDClipper = static_cast(new DirectDrawClipperImpl); - - return DD_OK; - } - HRESULT CreatePalette( - DDPixelCaps dwFlags, - LPPALETTEENTRY lpColorTable, - LPDIRECTDRAWPALETTE* lplpDDPalette, - IUnknown* pUnkOuter - ) override - { - *lplpDDPalette = static_cast(new DirectDrawPaletteImpl); - return DD_OK; - } - HRESULT CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter) - override - { - if ((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) == DDSD_CAPS) { - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER) { - if ((lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) != DDSD_ZBUFFERBITDEPTH) { - return DDERR_INVALIDPARAMS; - } - SDL_Log("Todo: Set %dbit Z-Buffer", lpDDSurfaceDesc->dwZBufferBitDepth); - *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl); - return DD_OK; - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) { - if ((lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT) == DDSD_BACKBUFFERCOUNT) { - SDL_Log("Todo: Switch to %d buffering", lpDDSurfaceDesc->dwBackBufferCount); - } - int width, height; - SDL_GetRenderOutputSize(renderer, &width, &height); - *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); - return DD_OK; - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) == DDSCAPS_OFFSCREENPLAIN) { - SDL_Log("DDSCAPS_OFFSCREENPLAIN"); // 2D surfaces? - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) == DDSCAPS_SYSTEMMEMORY) { - SDL_Log("DDSCAPS_SYSTEMMEMORY"); // Software rendering? - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) == DDSCAPS_TEXTURE) { - SDL_Log("DDSCAPS_TEXTURE"); // Texture for use in 3D - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) == DDSCAPS_3DDEVICE) { - SDL_Log("DDSCAPS_3DDEVICE"); // back buffer - } - if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) == DDSCAPS_VIDEOMEMORY) { - SDL_Log("DDSCAPS_VIDEOMEMORY"); // front / back buffer + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) { + if ((lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT) == DDSD_BACKBUFFERCOUNT) { + SDL_Log("Todo: Switch to %d buffering", lpDDSurfaceDesc->dwBackBufferCount); } + int width, height; + SDL_GetRenderOutputSize(renderer, &width, &height); + *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); + return DD_OK; } - - if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) { - if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) { - SDL_Log("DDPF_RGB"); // Use dwRGBBitCount to choose the texture format - } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) == DDSCAPS_OFFSCREENPLAIN) { + SDL_Log("DDSCAPS_OFFSCREENPLAIN"); // 2D surfaces? } - - if ((lpDDSurfaceDesc->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) != (DDSD_WIDTH | DDSD_HEIGHT)) { - return DDERR_INVALIDPARAMS; + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) == DDSCAPS_SYSTEMMEMORY) { + SDL_Log("DDSCAPS_SYSTEMMEMORY"); // Software rendering? + } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) == DDSCAPS_TEXTURE) { + SDL_Log("DDSCAPS_TEXTURE"); // Texture for use in 3D + } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) == DDSCAPS_3DDEVICE) { + SDL_Log("DDSCAPS_3DDEVICE"); // back buffer + } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) == DDSCAPS_VIDEOMEMORY) { + SDL_Log("DDSCAPS_VIDEOMEMORY"); // front / back buffer } - - int width = lpDDSurfaceDesc->dwWidth; - int height = lpDDSurfaceDesc->dwHeight; - *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); - return DD_OK; } - HRESULT EnumDisplayModes( - DWORD dwFlags, - LPDDSURFACEDESC lpDDSurfaceDesc, - LPVOID lpContext, - LPDDENUMMODESCALLBACK lpEnumModesCallback - ) override; - HRESULT FlipToGDISurface() override { return DD_OK; } - HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) override; - HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) override - { - SDL_DisplayID displayID = SDL_GetPrimaryDisplay(); - if (!displayID) { - return DDERR_GENERIC; + + if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) { + if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) { + SDL_Log("DDPF_RGB"); // Use dwRGBBitCount to choose the texture format } - - const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(displayID); - if (!mode) { - return DDERR_GENERIC; - } - - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(mode->format); - - lpDDSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT; - lpDDSurfaceDesc->dwWidth = mode->w; - lpDDSurfaceDesc->dwHeight = mode->h; - lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; - lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; - lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; - - return DD_OK; } - HRESULT RestoreDisplayMode() override { return DD_OK; } - HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) override - { - if (hWnd) { - renderer = SDL_CreateRenderer(hWnd, NULL); - } - return DD_OK; - } - HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) override { return DD_OK; } - // IDirect3D2 interface - HRESULT CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) override - { - *ppDirect3DDevice = new IDirect3DDevice2; - return DD_OK; - } - HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) override; -}; -HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) -{ - if (!cb) { + if ((lpDDSurfaceDesc->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) != (DDSD_WIDTH | DDSD_HEIGHT)) { return DDERR_INVALIDPARAMS; } - int numDrivers = SDL_GetNumRenderDrivers(); - if (numDrivers <= 0) { - return DDERR_GENERIC; - } - - const char* deviceDesc = "SDL3-backed renderer"; - char* deviceDescDup = SDL_strdup(deviceDesc); - - for (int i = 0; i < numDrivers; ++i) { - const char* deviceName = SDL_GetRenderDriver(i); - if (!deviceName) { - return DDERR_GENERIC; - } - - GUID deviceGuid = {0x682656F3, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (uint8_t) i}}; - - D3DDEVICEDESC halDesc = {}; - halDesc.dcmColorModel = D3DCOLORMODEL::RGB; - halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH; - halDesc.dwDeviceZBufferBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32; - halDesc.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16; - halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; - halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND; - halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR; - - char* deviceNameDup = SDL_strdup(deviceName); - cb(&deviceGuid, deviceNameDup, deviceDescDup, &halDesc, &halDesc, ctx); - SDL_free(deviceNameDup); - } - SDL_free(deviceDescDup); - - return S_OK; + int width = lpDDSurfaceDesc->dwWidth; + int height = lpDDSurfaceDesc->dwHeight; + *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); + return DD_OK; } HRESULT DirectDrawImpl::EnumDisplayModes( @@ -417,25 +157,137 @@ HRESULT DirectDrawImpl::EnumDisplayModes( return status; } +HRESULT DirectDrawImpl::FlipToGDISurface() +{ + return DD_OK; +} + HRESULT DirectDrawImpl::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) { if (lpDDDriverCaps) { - memset(lpDDDriverCaps, 0, sizeof(DDCAPS)); - lpDDDriverCaps->dwSize = sizeof(DDCAPS); - lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting + if (lpDDDriverCaps->dwSize >= sizeof(DDCAPS)) { + lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting + } } if (lpDDHELCaps) { - memset(lpDDHELCaps, 0, sizeof(DDCAPS)); - lpDDHELCaps->dwSize = sizeof(DDCAPS); - lpDDHELCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting + if (lpDDDriverCaps->dwSize >= sizeof(DDCAPS)) { + lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED; // Required to enable lighting + } } return S_OK; } +HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) +{ + if (!cb) { + return DDERR_INVALIDPARAMS; + } + + int numDrivers = SDL_GetNumRenderDrivers(); + if (numDrivers <= 0) { + return DDERR_GENERIC; + } + + const char* deviceDesc = "SDL3 SDL_Renderer"; + + for (int i = 0; i < numDrivers; ++i) { + const char* deviceName = SDL_GetRenderDriver(i); + if (!deviceName) { + return DDERR_GENERIC; + } + + GUID deviceGuid = {0x682656F3, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (uint8_t) i}}; + + D3DDEVICEDESC halDesc = {}; + halDesc.dcmColorModel = D3DCOLORMODEL::RGB; + halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH; + halDesc.dwDeviceZBufferBitDepth = DDBD_8 | DDBD_16 | DDBD_24 | DDBD_32; + halDesc.dwDeviceRenderBitDepth = DDBD_8 | DDBD_16; + halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; + halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND; + halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR; + + char* deviceNameDup = SDL_strdup(deviceName); + char* deviceDescDup = SDL_strdup(deviceDesc); + cb(&deviceGuid, deviceNameDup, deviceDescDup, &halDesc, &halDesc, ctx); + SDL_free(deviceDescDup); + SDL_free(deviceNameDup); + } + + return S_OK; +} + +HRESULT DirectDrawImpl::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) +{ + SDL_DisplayID displayID = SDL_GetPrimaryDisplay(); + if (!displayID) { + return DDERR_GENERIC; + } + + const SDL_DisplayMode* mode = SDL_GetCurrentDisplayMode(displayID); + if (!mode) { + return DDERR_GENERIC; + } + + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(mode->format); + + lpDDSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT; + lpDDSurfaceDesc->dwWidth = mode->w; + lpDDSurfaceDesc->dwHeight = mode->h; + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; + + return DD_OK; +} + +HRESULT DirectDrawImpl::RestoreDisplayMode() +{ + return DD_OK; +} + +HRESULT DirectDrawImpl::SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) +{ + if (hWnd) { + bool fullscreen; + if ((dwFlags & DDSCL_NORMAL) == DDSCL_NORMAL) { + fullscreen = false; + } + else if ((dwFlags & DDSCL_FULLSCREEN) == DDSCL_FULLSCREEN) { + fullscreen = true; + } + else { + return DDERR_INVALIDPARAMS; + } + + if (!SDL_SetWindowFullscreen(hWnd, fullscreen)) { + return DDERR_GENERIC; + } + renderer = SDL_CreateRenderer(hWnd, NULL); + } + return DD_OK; +} + +HRESULT DirectDrawImpl::SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) +{ + return DD_OK; +} +// IDirect3D2 interface +HRESULT DirectDrawImpl::CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) +{ + *ppDirect3DDevice = new IDirect3DDevice2; + return DD_OK; +} + HRESULT DirectDrawCreate(LPGUID lpGuid, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOuter) { + if (lpGuid) { + MINIWIN_ERROR("Specifying a DirectDraw driver is not implemented"); + } if (!lplpDD) { return DDERR_INVALIDPARAMS; } @@ -451,8 +303,10 @@ HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context) for (int i = 0; i < numDrivers; ++i) { const char* driverName = SDL_GetVideoDriver(i); - - if (!cb(NULL, (LPSTR) driverName, NULL, context)) { + char* driverNameDup = SDL_strdup(driverName); + BOOL callback_result = cb(NULL, driverNameDup, NULL, context); + SDL_free(driverNameDup); + if (!callback_result) { return DDERR_GENERIC; } } diff --git a/miniwin/miniwin/src/miniwin_ddsurface.cpp b/miniwin/miniwin/src/miniwin_ddsurface.cpp new file mode 100644 index 00000000..e4461d2a --- /dev/null +++ b/miniwin/miniwin/src/miniwin_ddsurface.cpp @@ -0,0 +1,216 @@ +#include "miniwin_ddraw_p.h" +#include "miniwin_ddsurface_p.h" +#include "miniwin_p.h" + +#include + +DirectDrawSurfaceImpl::DirectDrawSurfaceImpl() +{ +} + +DirectDrawSurfaceImpl::DirectDrawSurfaceImpl(int width, int height) +{ + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); + if (!texture) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError()); + } +} + +DirectDrawSurfaceImpl::~DirectDrawSurfaceImpl() +{ + if (texture) { + SDL_DestroyTexture(texture); + } +} + +// IUnknown interface +HRESULT DirectDrawSurfaceImpl::QueryInterface(const GUID& riid, void** ppvObject) +{ + if (SDL_memcmp(&riid, &IID_IDirectDrawSurface3, sizeof(GUID)) == 0) { + this->IUnknown::AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDrawImpl does not implement guid"); + return E_NOINTERFACE; +} + +// IDirectDrawSurface interface +HRESULT DirectDrawSurfaceImpl::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) +{ + return DD_OK; +} +HRESULT DirectDrawSurfaceImpl::Blt( + LPRECT lpDestRect, + LPDIRECTDRAWSURFACE lpDDSrcSurface, + LPRECT lpSrcRect, + DDBltFlags dwFlags, + LPDDBLTFX lpDDBltFx +) +{ + if (!renderer) { + return DDERR_GENERIC; + } + SDL_FRect srcRect = ConvertRect(lpSrcRect); + SDL_FRect dstRect = ConvertRect(lpDestRect); + SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->texture, &srcRect, &dstRect); + SDL_RenderPresent(renderer); + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::BltFast( + DWORD dwX, + DWORD dwY, + LPDIRECTDRAWSURFACE lpDDSrcSurface, + LPRECT lpSrcRect, + DDBltFastFlags dwTrans +) +{ + if (!renderer) { + return DDERR_GENERIC; + } + SDL_FRect dstRect = { + (float) dwX, + (float) dwY, + (float) (lpSrcRect->right - lpSrcRect->left), + (float) (lpSrcRect->bottom - lpSrcRect->top) + }; + SDL_FRect srcRect = ConvertRect(lpSrcRect); + SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->texture, &srcRect, &dstRect); + SDL_RenderPresent(renderer); + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) +{ + if (!renderer || !texture) { + return DDERR_GENERIC; + } + float width, height; + SDL_GetTextureSize(texture, &width, &height); + SDL_FRect rect{0, 0, width, height}; + SDL_RenderTexture(renderer, texture, &rect, &rect); + SDL_RenderPresent(renderer); + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) +{ + if ((lpDDSCaps->dwCaps & DDSCAPS_BACKBUFFER) != DDSCAPS_BACKBUFFER) { + return DDERR_INVALIDPARAMS; + } + *lplpDDAttachedSurface = static_cast(this); + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetCaps(LPDDSCAPS lpDDSCaps) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetDC(HDC* lphDC) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetOverlayPosition(LPLONG lplX, LPLONG lplY) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) +{ + assert(false && "unimplemented"); + return DDERR_GENERIC; +} + +HRESULT DirectDrawSurfaceImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) +{ + memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat)); + lpDDPixelFormat->dwFlags = DDPF_RGB; + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) +{ + if (!texture) { + return DDERR_GENERIC; + } + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::IsLost() +{ + return DD_OK; +} +HRESULT DirectDrawSurfaceImpl::Lock( + LPRECT lpDestRect, + LPDDSURFACEDESC lpDDSurfaceDesc, + DDLockFlags dwFlags, + HANDLE hEvent +) +{ + if (!lpDDSurfaceDesc) { + return DDERR_INVALIDPARAMS; + } + if (!texture) { + return DDERR_GENERIC; + } + + int pitch = 0; + void* pixels = nullptr; + if (SDL_LockTexture(texture, (SDL_Rect*) lpDestRect, &pixels, &pitch) < 0) { + return DDERR_GENERIC; + } + + lpDDSurfaceDesc->lpSurface = pixels; + lpDDSurfaceDesc->lPitch = pitch; + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; + + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::ReleaseDC(HDC hDC) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::Restore() +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) +{ + return DD_OK; +} + +HRESULT DirectDrawSurfaceImpl::Unlock(LPVOID lpSurfaceData) +{ + if (!texture) { + return DDERR_GENERIC; + } + SDL_UnlockTexture(texture); + return DD_OK; +} From d58ce5e9a93c3392163a50f65bdc9dd1c9184207 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Fri, 16 May 2025 22:28:02 +0200 Subject: [PATCH 5/8] Implement SetWindowPos (#98) --- miniwin/miniwin/include/miniwin.h | 7 ++----- miniwin/miniwin/src/miniwin.cpp | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/miniwin/miniwin/include/miniwin.h b/miniwin/miniwin/include/miniwin.h index dd095581..b976a279 100644 --- a/miniwin/miniwin/include/miniwin.h +++ b/miniwin/miniwin/include/miniwin.h @@ -16,7 +16,7 @@ #define CALLBACK #define FAR #define WINAPI -#define HWND_NOTOPMOST (HWND) - 2 +#define HWND_NOTOPMOST -2 #define RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16)) #define S_OK ((HRESULT) 0) #define E_NOINTERFACE (0x80004002) @@ -147,10 +147,7 @@ struct IUnknown { int m_refCount; }; -inline BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) -{ - return TRUE; -} +BOOL SetWindowPos(HWND hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); inline HDC WINAPI GetDC(HWND hWnd) { diff --git a/miniwin/miniwin/src/miniwin.cpp b/miniwin/miniwin/src/miniwin.cpp index 7eaad90e..9e26a590 100644 --- a/miniwin/miniwin/src/miniwin.cpp +++ b/miniwin/miniwin/src/miniwin.cpp @@ -24,6 +24,27 @@ HRESULT IUnknown::QueryInterface(const GUID& riid, void** ppvObject) return E_NOINTERFACE; } +BOOL SetWindowPos(HWND hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) +{ + if (!hWnd) { + return FALSE; + } + + if (!(uFlags & SWP_NOACTIVATE)) { + SDL_RaiseWindow(hWnd); + } + + if (!(uFlags & SWP_NOSIZE)) { + SDL_SetWindowSize(hWnd, cx, cy); + } + + if (!(uFlags & SWP_NOMOVE)) { + SDL_SetWindowPosition(hWnd, X, Y); + } + + return TRUE; +} + VOID WINAPI Sleep(DWORD dwMilliseconds) { SDL_Delay(dwMilliseconds); From 0c0e494b38970df58fe207b11749ecd02213f40f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 16 May 2025 22:28:29 +0200 Subject: [PATCH 6/8] ci: merge all workflows (#97) * ci: merge all workflows * Update .github/workflows/ci.yml Co-authored-by: Anders Jenbo * ci: correct vcvars --------- Co-authored-by: Anders Jenbo --- .github/workflows/ci.yml | 137 ++++++++++++++++++++++++++++++++++ .github/workflows/format.yml | 19 ----- .github/workflows/linux.yml | 45 ----------- .github/workflows/mac.yml | 46 ------------ .github/workflows/naming.yml | 43 ----------- .github/workflows/windows.yml | 120 ----------------------------- CMakeLists.txt | 34 ++++++++- 7 files changed, 169 insertions(+), 275 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/format.yml delete mode 100644 .github/workflows/linux.yml delete mode 100644 .github/workflows/mac.yml delete mode 100644 .github/workflows/naming.yml delete mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..3bb10018 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,137 @@ +name: CI + +on: [push, pull_request] + +jobs: + clang-format: + name: 'clang-format' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run clang-format + run: | + find CONFIG LEGO1 ISLE miniwin -iname '*.h' -o -iname '*.cpp' | xargs \ + pipx run "clang-format>=17,<18" \ + --style=file \ + -i + - name: Check diff + run: | + git diff --exit-code + + build: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + defaults: + run: + shell: ${{ matrix.shell || 'sh' }} + + strategy: + fail-fast: false + matrix: + include: + - { name: 'Linux', os: 'ubuntu-latest', dx5: false, build-type: 'Debug', linux: true, werror: true, clang-tify: true } + - { name: 'MSVC (x86)', os: 'windows-latest', dx5: true, build-type: 'Debug', msvc: true, werror: false, clang-tify: false, vc-arch: 'amd64_x86' } + - { name: 'MSVC (x64)', os: 'windows-latest', dx5: false, build-type: 'Debug', msvc: true, werror: false, clang-tify: false, vc-arch: 'amd64' } + - { name: 'MSVC (arm64)', os: 'windows-latest', dx5: false, build-type: 'Debug', msvc: true, werror: false, clang-tify: false, vc-arch: 'amd64_arm64' } + - { name: 'msys2 mingw32', os: 'windows-latest', dx5: false, build-type: 'Debug', mingw: true, werror: true, clang-tify: true, msystem: 'mingw32', msys-env: 'mingw-w64-i686', shell: 'msys2 {0}' } + - { name: 'msys2 mingw64', os: 'windows-latest', dx5: false, build-type: 'Debug', mingw: true, werror: true, clang-tify: true, msystem: 'mingw64', msys-env: 'mingw-w64-x86_64', shell: 'msys2 {0}' } + - { name: 'macOS', os: 'macos-latest', dx5: false, build-type: 'Debug', brew: true, werror: true, clang-tify: true } + steps: + - name: Setup vcvars + if: ${{ !!matrix.msvc }} + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.vc-arch }} + + - name: Set up MSYS2 + if: ${{ !!matrix.msystem }} + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.msystem }} + install: >- + ${{ matrix.msys-env }}-cc + ${{ matrix.msys-env }}-cmake + ${{ matrix.msys-env }}-ninja + ${{ matrix.msys-env }}-clang-tools-extra + + - name: Install Linux dependencies (apt-get) + if: ${{ matrix.linux }} + run: | + sudo apt-get update + sudo apt-get install -y \ + libx11-dev libxext-dev libxrandr-dev libxrender-dev libxfixes-dev libxi-dev libxinerama-dev libxcursor-dev libwayland-dev libxkbcommon-dev wayland-protocols + + - name: Install macOS dependencies (brew) + if: ${{ matrix.brew }} + run: | + brew update + brew install cmake ninja llvm + echo "LLVM_ROOT=$(brew --prefix llvm)/bin" >> $GITHUB_ENV + + - name: Setup ninja + if: ${{ matrix.msvc }} + uses: ashutoshvarma/setup-ninja@master + + - uses: actions/checkout@v4 + + - name: Configure (CMake) + run: | + cmake -S . -B build -GNinja \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ + -DISLE_USE_DX5=${{ !!matrix.dx5 }} \ + -DENABLE_CLANG_TIDY=${{ !!matrix.clang-tidy }} \ + -DISLE_WERROR=${{ !!matrix.werror }} \ + -Werror=dev + + - name: Build (CMake) + run: cmake --build build --verbose -- -k0 + + - name: Package (CPack) + run: | + cd build + cpack . + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: '${{ matrix.name }} ${{ matrix.build-type }}' + path: build/dist/isle-* + + ncc: + name: 'C++' + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install LLVM and Clang + uses: KyleMayes/install-llvm-action@v1 + with: + version: "16" + + - name: Install python libraries + run: | + pip install -r tools/requirements.txt + + - name: Run ncc + run: | + action_headers=$(find LEGO1/lego/legoomni/include/actions \ + -name '*.h' -print0 | xargs -0 echo) + + python3 tools/ncc/ncc.py \ + --clang-lib ${{ env.LLVM_PATH }}/lib/libclang.so \ + --recurse \ + --style tools/ncc/ncc.style \ + --skip tools/ncc/skip.yml \ + --definition WINAPI FAR BOOL CALLBACK HWND__=HWND SDLCALL \ + --include \ + util \ + LEGO1 \ + LEGO1/omni/include \ + LEGO1/lego/legoomni/include \ + LEGO1/lego/sources \ + --exclude \ + LEGO1/omni/include/flic.h \ + LEGO1/omni/src/video/flic.cpp \ + $action_headers \ + --path LEGO1/omni LEGO1/lego/legoomni diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml deleted file mode 100644 index e5f2d4de..00000000 --- a/.github/workflows/format.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Format - -on: [push, pull_request] - -jobs: - clang-format: - name: 'C++' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Run clang-format - run: | - find CONFIG LEGO1 ISLE miniwin -iname '*.h' -o -iname '*.cpp' | xargs \ - pipx run "clang-format>=17,<18" \ - --style=file \ - -i - git diff --exit-code diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml deleted file mode 100644 index 242ca537..00000000 --- a/.github/workflows/linux.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Linux - -on: [push, pull_request] - -jobs: - build-linux: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - build-type: [Release, Debug] - - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - libx11-dev libxext-dev libxrandr-dev libxrender-dev libxfixes-dev libxi-dev libxinerama-dev libxcursor-dev libwayland-dev libxkbcommon-dev wayland-protocols - - - name: Configure - run: | - cmake -S . -B build -GNinja \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ - -DISLE_USE_DX5=OFF \ - -DENABLE_CLANG_TIDY=ON \ - -DISLE_WERROR=ON \ - -Werror=dev - - - name: Build - run: cmake --build build -- -k0 - - - name: Make Artifact Archive - run: | - cd build - zip "isle-portable-linux-${{ matrix.build-type }}.zip" \ - config isle liblego1.so - - - name: Upload Build Artifacts - uses: actions/upload-artifact@v4 - with: - name: linux-artifacts-${{ matrix.build-type }} - path: build/isle-portable-linux-${{ matrix.build-type }}.zip diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml deleted file mode 100644 index f8f97029..00000000 --- a/.github/workflows/mac.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: macOS - -on: [push, pull_request] - -jobs: - build-macos: - runs-on: macos-latest - - strategy: - fail-fast: false - matrix: - build-type: [Release, Debug] - - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - brew update - brew install cmake ninja llvm - echo "CLANG_TIDY=$(brew --prefix llvm)/bin/clang-tidy" >> $GITHUB_ENV - - - name: Configure - run: | - cmake -S . -B build -GNinja \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ - -DISLE_USE_DX5=OFF \ - -DENABLE_CLANG_TIDY=ON \ - -DCLANG_TIDY_BIN=$CLANG_TIDY \ - -DISLE_WERROR=ON \ - -Werror=dev - - - name: Build - run: cmake --build build -- -k0 - - - name: Make Artifact Archive - run: | - cd build - zip "isle-portable-macos-${{ matrix.build-type }}.zip" \ - config isle liblego1.dylib - - - name: Upload Build Artifacts - uses: actions/upload-artifact@v4 - with: - name: macos-artifacts-${{ matrix.build-type }} - path: build/isle-portable-macos-${{ matrix.build-type }}.zip diff --git a/.github/workflows/naming.yml b/.github/workflows/naming.yml deleted file mode 100644 index 20ffddff..00000000 --- a/.github/workflows/naming.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Naming - -on: [push, pull_request] - -jobs: - ncc: - name: 'C++' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Install LLVM and Clang - uses: KyleMayes/install-llvm-action@v1 - with: - version: "16" - - - name: Install python libraries - run: | - pip install -r tools/requirements.txt - - - name: Run ncc - run: | - action_headers=$(find LEGO1/lego/legoomni/include/actions \ - -name '*.h' -print0 | xargs -0 echo) - - python3 tools/ncc/ncc.py \ - --clang-lib ${{ env.LLVM_PATH }}/lib/libclang.so \ - --recurse \ - --style tools/ncc/ncc.style \ - --skip tools/ncc/skip.yml \ - --definition WINAPI FAR BOOL CALLBACK HWND__=HWND SDLCALL \ - --include \ - util \ - LEGO1 \ - LEGO1/omni/include \ - LEGO1/lego/legoomni/include \ - LEGO1/lego/sources \ - --exclude \ - LEGO1/omni/include/flic.h \ - LEGO1/omni/src/video/flic.cpp \ - $action_headers \ - --path LEGO1/omni LEGO1/lego/legoomni diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index 9d63a110..00000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,120 +0,0 @@ -name: Windows - -on: [push, pull_request] - -jobs: - build-current-toolchain: - name: 'Current ${{ matrix.toolchain.name }}' - runs-on: windows-latest - defaults: - run: - shell: ${{ matrix.toolchain.shell }} - strategy: - fail-fast: false - matrix: - toolchain: - - { name: 'MSVC (32-bit, Release)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64_x86', dx5-libs: true, build-type: 'Release' } - - { name: 'MSVC (32-bit, Debug)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64_x86', dx5-libs: true, build-type: 'Debug' } - - { name: 'MSVC (64-bit, Debug)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64', dx5-libs: false, build-type: 'Debug' } - - { name: 'MSVC (ARM64, Debug)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64_arm64', dx5-libs: false, build-type: 'Debug' } - - { name: 'msys2 mingw32 (Debug)', shell: 'msys2 {0}', msystem: mingw32, msys-env: mingw-w64-i686, clang-tidy: true, werror: true, dx5-libs: false, build-type: 'Debug' } - - { name: 'msys2 mingw64 (Debug)', shell: 'msys2 {0}', msystem: mingw64, msys-env: mingw-w64-x86_64, clang-tidy: true, werror: true, dx5-libs: false, build-type: 'Debug' } - # - { name: 'msys2 clang32', shell: 'msys2 {0}', msystem: clang32, msys-env: mingw-w64-clang-i686, clang-tidy: true, werror: true, dx5-libs: true, d3drm-from-wine: true } - - steps: - - name: Setup vcvars - if: matrix.toolchain.setup-msvc - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: ${{ matrix.toolchain.vc-arch }} - # Figure out how to build for 32-bit arch - # - name: Set up SDL - # id: sdl - # uses: libsdl-org/setup-sdl@main - # with: - # version: sdl3-head - - - name: Set up MSYS2 - if: ${{ !!matrix.toolchain.msystem }} - uses: msys2/setup-msys2@v2 - with: - msystem: ${{ matrix.toolchain.msystem }} - install: >- - ${{ matrix.toolchain.msys-env }}-cc - ${{ matrix.toolchain.msys-env }}-cmake - ${{ matrix.toolchain.msys-env }}-ninja - ${{ matrix.toolchain.msys-env }}-clang-tools-extra - - - name: Setup cmake - if: matrix.toolchain.setup-cmake - uses: jwlawson/actions-setup-cmake@v1.13 - - - name: Setup ninja - if: matrix.toolchain.setup-ninja - uses: ashutoshvarma/setup-ninja@master - - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Build - # Add -DDOWNLOAD_DEPENDENCIES=OFF once setup-sdl works - run: | - cmake -S . -B build -GNinja \ - -DCMAKE_BUILD_TYPE=${{ matrix.toolchain.build-type }} \ - -DISLE_USE_DX5=${{ matrix.toolchain.dx5-libs }} \ - -DENABLE_CLANG_TIDY=${{ !!matrix.toolchain.clang-tidy }} \ - -DISLE_WERROR=${{ !!matrix.toolchain.werror }} \ - -Werror=dev - cmake --build build -- -k0 - - # Needs to be reworked when cross-platform building is achieved - - - name: Make Artifact Archive - shell: bash - run: | - cd build - 7z a "isle-portable (${{ matrix.toolchain.name }}).zip" \ - isle.exe lego1.dll sdl3.dll - - - name: Upload Build Artifacts (MSVC (32-bit)) - if: ${{ matrix.toolchain.name == 'MSVC (32-bit, Release)' || matrix.toolchain.name == 'MSVC (32-bit, Debug)' }} - uses: actions/upload-artifact@v4 - with: - name: msvc32-artifacts-${{ matrix.toolchain.name }} - path: | - build/isle-portable (${{ matrix.toolchain.name }}).zip - - merge-artifacts: - name: 'Merge artifacts' - runs-on: ubuntu-latest - needs: build-current-toolchain - steps: - - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 - with: - name: msvc32-artifacts - pattern: msvc32-artifacts-* - - upload: - name: 'Upload artifacts' - needs: merge-artifacts - runs-on: ubuntu-latest - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'isledecomp/isle-portable' }} - steps: - - uses: actions/checkout@v4 - with: - repository: 'probonopd/uploadtool' - - - uses: actions/download-artifact@v4 - with: - name: msvc32-artifacts - path: build - - - name: Upload Continuous Release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - UPLOAD_KEY: ${{ secrets.UPLOAD_KEY }} - run: | - ./upload.sh \ - build/*.zip diff --git a/CMakeLists.txt b/CMakeLists.txt index b0a952a4..3b523183 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.25...4.0 FATAL_ERROR) -project(isle CXX C) +project(isle LANGUAGES CXX C VERSION 0.1) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") @@ -69,7 +69,7 @@ endif() set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if (ENABLE_CLANG_TIDY) - find_program(CLANG_TIDY_BIN NAMES "clang-tidy") + find_program(CLANG_TIDY_BIN NAMES "clang-tidy" ENV "LLVM_ROOT" REQUIRED) set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_BIN}") set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN}") endif() @@ -573,3 +573,33 @@ if (EXISTS "${CLANGFORMAT_BIN}") endif() endif() endif() + +set(install_extra_targets) +if(DOWNLOAD_DEPENDENCIES) + get_property(sdl3_type TARGET SDL3::SDL3 PROPERTY TYPE) + if(sdl3_type STREQUAL "SHARED_LIBRARY") + list(APPEND install_extra_targets "SDL3-shared") + endif() +endif() + +if(MSVC) + set(CMAKE_INSTALL_BINDIR "." CACHE PATH "Binary install directory") + set(CMAKE_INSTALL_LIBDIR "." CACHE PATH "Binary install directory") +else() + include(GNUInstallDirs) +endif() + +set(ISLE_PACKAGE_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}" CACHE STRING "Platform name of the package") +install(TARGETS isle lego1 ${install_extra_targets} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) + +set(CPACK_PACKAGE_DIRECTORY "dist") +set(CPACK_PACKAGE_FILE_NAME "isle-${PROJECT_VERSION}-${ISLE_PACKAGE_NAME}-${CMAKE_SYSTEM_PROCESSOR}") +if(MSVC) + set(CPACK_GENERATOR ZIP) +else() + set(CPACK_GENERATOR TGZ) +endif() +include(CPack) From b1dfbe99259503f377e4308650187d5df7780348 Mon Sep 17 00:00:00 2001 From: AllMeatball <181806857+AllMeatball@users.noreply.github.com> Date: Fri, 16 May 2025 21:08:45 +0000 Subject: [PATCH 7/8] isleapp: Show error dialog if NOCD.si or ISLE.si fails to load (#95) * isleapp: Show error dialog if NOCD.si fails to load * isleapp: Return bool in IsleApp::Tick foxtacles recommended me to return a boolean for if tick failed instead of just setting `g_closed` and setting `g_closeResult` to set the return value of the program exit. I also think this is the better solution. since a similar solution was used in LoadConfig. * isleapp: Better error logs & return false in places foxtacles recommended to use SDL's logging api to show detailed errors and using false in two places where it should exit because of failure. This commit adds these two things. * isleapp: Add missing error dialog when ISLE.si fails * isleapp: Add missing error dialog when ISLE.si fails * isleapp: Remove weird duplicate message box * Move error dialog to loop --------- Co-authored-by: Christian Semmler --- ISLE/isleapp.cpp | 51 ++++++++++++++++++++++++++++++++++++------------ ISLE/isleapp.h | 2 +- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index ae034a2e..a16b6251 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -30,6 +30,8 @@ #include "roi/legoroi.h" #include "viewmanager/viewmanager.h" +#include + #define SDL_MAIN_USE_CALLBACKS #include #include @@ -289,7 +291,16 @@ SDL_AppResult SDL_AppIterate(void* appstate) return SDL_APP_SUCCESS; } - g_isle->Tick(); + if (!g_isle->Tick()) { + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_ERROR, + "LEGO® Island Error", + "\"LEGO® Island\" failed to start.\nPlease quit all other applications and try again." + "\nFailed to initialize; see logs for details", + NULL + ); + return SDL_APP_FAILURE; + } if (!g_closed) { if (g_reqEnableRMDevice) { @@ -304,7 +315,16 @@ SDL_AppResult SDL_AppIterate(void* appstate) } if (g_mousedown && g_mousemoved && g_isle) { - g_isle->Tick(); + if (!g_isle->Tick()) { + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_ERROR, + "LEGO® Island Error", + "\"LEGO® Island\" failed to start.\nPlease quit all other applications and try again." + "\nFailed to initialize; see logs for details", + NULL + ); + return SDL_APP_FAILURE; + } } if (g_mousemoved) { @@ -683,7 +703,7 @@ bool IsleApp::LoadConfig() } // FUNCTION: ISLE 0x402c20 -inline void IsleApp::Tick() +inline bool IsleApp::Tick() { // GLOBAL: ISLE 0x4101c0 static MxLong g_lastFrameTime = 0; @@ -693,17 +713,17 @@ inline void IsleApp::Tick() if (!m_windowActive) { SDL_Delay(1); - return; + return true; } if (!Lego()) { - return; + return true; } if (!TickleManager()) { - return; + return true; } if (!Timer()) { - return; + return true; } MxLong currentTime = Timer()->GetRealTime(); @@ -713,7 +733,7 @@ inline void IsleApp::Tick() if (m_frameDelta + g_lastFrameTime >= currentTime) { SDL_Delay(1); - return; + return true; } if (!Lego()->IsPaused()) { @@ -722,12 +742,12 @@ inline void IsleApp::Tick() g_lastFrameTime = currentTime; if (g_startupDelay == 0) { - return; + return true; } g_startupDelay--; if (g_startupDelay != 0) { - return; + return true; } LegoOmni::GetInstance()->CreateBackgroundAudio(); @@ -739,7 +759,8 @@ inline void IsleApp::Tick() if (!stream) { stream = Streamer()->Open("\\lego\\scripts\\nocd", MxStreamer::e_diskStream); if (!stream) { - return; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open NOCD.si: Streamer failed to load"); + return false; } ds.SetAtomId(stream->GetAtom()); @@ -748,7 +769,8 @@ inline void IsleApp::Tick() VideoManager()->EnableFullScreenMovie(TRUE, TRUE); if (Start(&ds) != SUCCESS) { - return; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open NOCD.si: Failed to start initial action"); + return false; } } else { @@ -756,10 +778,13 @@ inline void IsleApp::Tick() ds.SetUnknown24(-1); ds.SetObjectId(0); if (Start(&ds) != SUCCESS) { - return; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to open ISLE.si: Failed to start initial action"); + return false; } m_gameStarted = TRUE; } + + return true; } // FUNCTION: ISLE 0x402e80 diff --git a/ISLE/isleapp.h b/ISLE/isleapp.h index 979ef16c..7fd3c84f 100644 --- a/ISLE/isleapp.h +++ b/ISLE/isleapp.h @@ -37,7 +37,7 @@ class IsleApp { MxResult SetupWindow(); bool LoadConfig(); - void Tick(); + bool Tick(); void SetupCursor(Cursor p_cursor); static MxU8 MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags); From 543edf292aad81884292492324dd694ef47b96ed Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 17 May 2025 02:51:43 +0200 Subject: [PATCH 8/8] Implement all D3DRM interfaces (#99) * Implement (most) IDirect3DRMObject methods * Implement all interfaces --------- Co-authored-by: Anonymous Maarten --- miniwin/minimfc/include/minimfc.h | 4 +- miniwin/miniwin/include/miniwin.h | 2 +- miniwin/miniwin/include/miniwin_d3drm.h | 88 ++-- .../miniwin/src/include/miniwin_ddsurface_p.h | 3 +- miniwin/miniwin/src/miniwin_d3drm.cpp | 450 ++++++++++++++---- miniwin/miniwin/src/miniwin_ddraw.cpp | 11 - miniwin/miniwin/src/miniwin_ddsurface.cpp | 43 +- 7 files changed, 427 insertions(+), 174 deletions(-) diff --git a/miniwin/minimfc/include/minimfc.h b/miniwin/minimfc/include/minimfc.h index 02aa9a52..5df522a3 100644 --- a/miniwin/minimfc/include/minimfc.h +++ b/miniwin/minimfc/include/minimfc.h @@ -24,8 +24,6 @@ #define FAILED(hr) (((HRESULT) (hr)) < 0) #define InterlockedIncrement(x) __sync_add_and_fetch(x, 1) -#define INVALID_HANDLE ((HANDLE) -1) -#define INVALID_HANDLE_VALUE ((HANDLE) -1) #define HKEY_LOCAL_MACHINE ((HKEY) 0x80000002) #define LOWORD(l) ((WORD) (((DWORD_PTR) (l)) & 0xffff)) #define MAKEINTRESOURCE(i) (reinterpret_cast((ULONG_PTR) ((WORD) (i)))) @@ -130,7 +128,7 @@ struct CMenu { struct CWinApp { CWinApp(); - virtual ~CWinApp() = default; + ~CWinApp() = default; virtual BOOL InitInstance() = 0; virtual int ExitInstance(); }; diff --git a/miniwin/miniwin/include/miniwin.h b/miniwin/miniwin/include/miniwin.h index b976a279..5350128f 100644 --- a/miniwin/miniwin/include/miniwin.h +++ b/miniwin/miniwin/include/miniwin.h @@ -143,7 +143,7 @@ struct IUnknown { virtual HRESULT QueryInterface(const GUID& riid, void** ppvObject); virtual ~IUnknown() = default; -private: +protected: int m_refCount; }; diff --git a/miniwin/miniwin/include/miniwin_d3drm.h b/miniwin/miniwin/include/miniwin_d3drm.h index c42bab0b..d6fc97b6 100644 --- a/miniwin/miniwin/include/miniwin_d3drm.h +++ b/miniwin/miniwin/include/miniwin_d3drm.h @@ -8,6 +8,7 @@ #define D3DRM_OK DD_OK #define MAXSHORT ((short) 0x7fff) #define SUCCEEDED(hr) ((hr) >= D3DRM_OK) +#define D3DRMERR_NOTFOUND MAKE_DDHRESULT(785) // --- Typedefs --- typedef float D3DVAL; @@ -16,6 +17,9 @@ typedef unsigned long D3DRMGROUPINDEX; typedef DWORD D3DCOLOR, *LPD3DCOLOR; typedef float D3DVALUE, *LPD3DVALUE; +typedef struct IDirect3DRMObject* LPDIRECT3DRMOBJECT; +typedef void (*D3DRMOBJECTCALLBACK)(LPDIRECT3DRMOBJECT obj, LPVOID arg); + // --- Enums --- #define D3DRMCOMBINE_REPLACE D3DRMCOMBINETYPE::REPLACE enum class D3DRMCOMBINETYPE { @@ -140,35 +144,31 @@ struct D3DRMVERTEX { float tu, tv; }; -struct IDirect3DRMVisual : virtual public IUnknown {}; -typedef IDirect3DRMVisual* LPDIRECT3DRMVISUAL; - -struct IDirect3DRMObject : virtual public IUnknown { +struct IDirect3DRMObject : public IUnknown { virtual HRESULT Clone(void** ppObject) = 0; - virtual HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) = 0; - virtual HRESULT DeleteDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) = 0; + virtual HRESULT AddDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) = 0; + virtual HRESULT DeleteDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) = 0; virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0; virtual LPVOID GetAppData() = 0; virtual HRESULT SetName(const char* name) = 0; virtual HRESULT GetName(DWORD* size, char* name) = 0; - virtual HRESULT GetClassName(DWORD* size, char* name) = 0; }; -struct IDirect3DRMTexture : virtual public IUnknown { - virtual HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) = 0; - virtual LPVOID GetAppData() = 0; - virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0; - virtual HRESULT SetTexture(const IDirect3DRMTexture* texture) = 0; - virtual HRESULT Changed(BOOL arg1, BOOL arg2) = 0; + +struct IDirect3DRMVisual : public IDirect3DRMObject {}; +typedef IDirect3DRMVisual* LPDIRECT3DRMVISUAL; + +struct IDirect3DRMTexture : public IDirect3DRMVisual { + virtual HRESULT Changed(BOOL pixels, BOOL palette) = 0; }; typedef IDirect3DRMTexture* LPDIRECT3DRMTEXTURE; struct IDirect3DRMTexture2 : public IDirect3DRMTexture {}; typedef IDirect3DRMTexture2* LPDIRECT3DRMTEXTURE2; -struct IDirect3DRMMaterial : virtual public IUnknown {}; +struct IDirect3DRMMaterial : public IDirect3DRMObject {}; typedef IDirect3DRMMaterial *LPDIRECT3DRMMATERIAL, **LPLPDIRECT3DRMMATERIAL; -struct IDirect3DRMMesh : virtual public IUnknown { +struct IDirect3DRMMesh : public IDirect3DRMVisual { virtual HRESULT Clone(int flags, GUID iid, void** object) = 0; virtual HRESULT GetBox(D3DRMBOX* box) = 0; virtual HRESULT AddGroup( @@ -188,7 +188,7 @@ struct IDirect3DRMMesh : virtual public IUnknown { ) = 0; virtual HRESULT SetGroupColor(int groupIndex, D3DCOLOR color) = 0; virtual HRESULT SetGroupColorRGB(int groupIndex, float r, float g, float b) = 0; - virtual HRESULT SetGroupTexture(int groupIndex, const IDirect3DRMTexture* texture) = 0; + virtual HRESULT SetGroupTexture(int groupIndex, IDirect3DRMTexture* texture) = 0; virtual HRESULT SetGroupMaterial(int groupIndex, IDirect3DRMMaterial* material) = 0; virtual HRESULT SetGroupMapping(D3DRMGROUPINDEX groupIndex, D3DRMMAPPING mapping) = 0; virtual HRESULT SetGroupQuality(int groupIndex, D3DRMRENDERQUALITY quality) = 0; @@ -200,24 +200,28 @@ struct IDirect3DRMMesh : virtual public IUnknown { virtual HRESULT GetVertices(int groupIndex, int startIndex, int count, D3DRMVERTEX* vertices) = 0; }; -struct IDirect3DRMLight : virtual public IUnknown { +struct IDirect3DRMLight : public IDirect3DRMObject { virtual HRESULT SetColorRGB(float r, float g, float b) = 0; }; -struct IDirect3DRMLightArray : virtual public IUnknown { +struct IDirect3DRMArray : public IUnknown { virtual DWORD GetSize() = 0; - virtual HRESULT GetElement(int index, IDirect3DRMLight** light) const = 0; }; -struct IDirect3DRMVisualArray : virtual public IUnknown { - virtual DWORD GetSize() = 0; - virtual HRESULT GetElement(int index, IDirect3DRMVisual** visual) const = 0; +struct IDirect3DRMLightArray : public IDirect3DRMArray { + virtual HRESULT GetElement(DWORD index, IDirect3DRMLight** out) = 0; + virtual HRESULT AddElement(IDirect3DRMLight* in) = 0; + virtual HRESULT DeleteElement(IDirect3DRMLight* element) = 0; +}; + +struct IDirect3DRMVisualArray : public IDirect3DRMArray { + virtual HRESULT GetElement(DWORD index, IDirect3DRMVisual** out) = 0; + virtual HRESULT AddElement(IDirect3DRMVisual* in) = 0; + virtual HRESULT DeleteElement(IDirect3DRMVisual* element) = 0; }; typedef struct IDirect3DRMFrameArray* LPDIRECT3DRMFRAMEARRAY; -struct IDirect3DRMFrame : virtual public IUnknown { - virtual HRESULT SetAppData(LPD3DRM_APPDATA appData) = 0; - virtual LPVOID GetAppData() = 0; +struct IDirect3DRMFrame : public IDirect3DRMVisual { virtual HRESULT AddChild(IDirect3DRMFrame* child) = 0; virtual HRESULT DeleteChild(IDirect3DRMFrame* child) = 0; virtual HRESULT SetSceneBackgroundRGB(float r, float g, float b) = 0; @@ -232,7 +236,7 @@ struct IDirect3DRMFrame : virtual public IUnknown { virtual HRESULT AddVisual(IDirect3DRMFrame* visual) = 0; virtual HRESULT DeleteVisual(IDirect3DRMFrame* visual) = 0; virtual HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) = 0; - virtual HRESULT SetTexture(const IDirect3DRMTexture* texture) = 0; + virtual HRESULT SetTexture(IDirect3DRMTexture* texture) = 0; virtual HRESULT GetTexture(IDirect3DRMTexture** texture) = 0; virtual HRESULT SetColor(float r, float g, float b, float a) = 0; virtual HRESULT SetColor(D3DCOLOR) = 0; @@ -242,22 +246,22 @@ struct IDirect3DRMFrame : virtual public IUnknown { }; typedef IDirect3DRMFrame* LPDIRECT3DRMFRAME; +struct IDirect3DRMFrameArray : public IDirect3DRMArray { + virtual HRESULT GetElement(DWORD index, IDirect3DRMFrame** out) = 0; + virtual HRESULT AddElement(IDirect3DRMFrame* in) = 0; + virtual HRESULT DeleteElement(IDirect3DRMFrame* element) = 0; +}; + struct IDirect3DRMFrame2 : public IDirect3DRMFrame {}; typedef IDirect3DRMFrame2* LPDIRECT3DRMFRAME2; -struct IDirect3DRMFrameArray : virtual public IUnknown { - virtual DWORD GetSize() = 0; - virtual HRESULT GetElement(DWORD index, IDirect3DRMFrame** frame) = 0; -}; - struct D3DRMPICKDESC { IDirect3DRMVisual* visual; IDirect3DRMFrame* frame; float dist; }; -struct IDirect3DRMPickedArray : virtual public IUnknown { - virtual DWORD GetSize() = 0; +struct IDirect3DRMPickedArray : public IDirect3DRMArray { virtual HRESULT GetPick( DWORD index, IDirect3DRMVisual** visual, @@ -288,19 +292,20 @@ struct IDirect3DRMViewport : public IDirect3DRMObject { virtual HRESULT Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) = 0; }; -struct IDirect3DRMWinDevice : virtual public IUnknown { +struct IDirect3DRMViewportArray : public IDirect3DRMArray { + virtual HRESULT GetElement(DWORD index, IDirect3DRMViewport** out) = 0; + virtual HRESULT AddElement(IDirect3DRMViewport* in) = 0; + virtual HRESULT DeleteElement(IDirect3DRMViewport* element) = 0; +}; + +struct IDirect3DRMWinDevice : virtual public IDirect3DRMObject { virtual HRESULT Activate() = 0; virtual HRESULT Paint() = 0; virtual void HandleActivate(WORD wParam) = 0; virtual void HandlePaint(void* p_dc) = 0; }; -struct IDirect3DRMViewportArray : virtual public IUnknown { - virtual DWORD GetSize() = 0; - virtual HRESULT GetElement(int index, IDirect3DRMViewport** viewport) = 0; -}; - -struct IDirect3DRMDevice2 : virtual public IUnknown { +struct IDirect3DRMDevice : virtual public IDirect3DRMObject { virtual unsigned long GetWidth() = 0; virtual unsigned long GetHeight() = 0; virtual HRESULT SetBufferCount(int count) = 0; @@ -316,9 +321,12 @@ struct IDirect3DRMDevice2 : virtual public IUnknown { virtual HRESULT SetRenderMode(D3DRMRENDERMODE mode) = 0; virtual D3DRMRENDERMODE GetRenderMode() = 0; virtual HRESULT Update() = 0; + virtual HRESULT AddViewport(IDirect3DRMViewport* viewport) = 0; virtual HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) = 0; }; +struct IDirect3DRMDevice2 : virtual public IDirect3DRMDevice {}; + struct IDirect3DRM : virtual public IUnknown { virtual HRESULT CreateDeviceFromD3D( const IDirect3D2* d3d, diff --git a/miniwin/miniwin/src/include/miniwin_ddsurface_p.h b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h index df8ec4a8..e20d42ac 100644 --- a/miniwin/miniwin/src/include/miniwin_ddsurface_p.h +++ b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h @@ -39,5 +39,6 @@ struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { HRESULT Unlock(LPVOID lpSurfaceData) override; private: - SDL_Texture* texture = nullptr; + SDL_Texture* m_texture = nullptr; + IDirectDrawPalette* m_palette = nullptr; }; diff --git a/miniwin/miniwin/src/miniwin_d3drm.cpp b/miniwin/miniwin/src/miniwin_d3drm.cpp index a7fc9fd2..e613326d 100644 --- a/miniwin/miniwin/src/miniwin_d3drm.cpp +++ b/miniwin/miniwin/src/miniwin_d3drm.cpp @@ -3,24 +3,271 @@ #include "miniwin_ddsurface_p.h" #include +#include #include +#include -struct Direct3DRMTextureImpl : public IDirect3DRMTexture2 { - HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) override { return DD_OK; } - LPVOID GetAppData() override { return m_data; } - HRESULT SetAppData(LPD3DRM_APPDATA appData) override +template +class Direct3DRMArrayBase : public ArrayInterface { +public: + ~Direct3DRMArrayBase() override { - m_data = appData; + for (auto* item : items) { + if (item) { + item->Release(); + } + } + } + DWORD GetSize() override { return static_cast(items.size()); } + HRESULT AddElement(InterfaceType* in) override + { + if (!in) { + return DDERR_INVALIDPARAMS; + } + in->AddRef(); + items.push_back(in); return DD_OK; } - HRESULT SetTexture(const IDirect3DRMTexture* texture) override { return DD_OK; } - HRESULT Changed(BOOL arg1, BOOL arg2) override { return DD_OK; } + HRESULT GetElement(DWORD index, InterfaceType** out) override + { + if (index >= items.size()) { + return DDERR_INVALIDPARAMS; + } + *out = static_cast(items[index]); + if (*out) { + (*out)->AddRef(); + } + return DD_OK; + } + HRESULT DeleteElement(InterfaceType* element) override + { + auto it = std::find(items.begin(), items.end(), element); + if (it == items.end()) { + return DDERR_INVALIDPARAMS; + } -private: - LPD3DRM_APPDATA m_data; + (*it)->Release(); + items.erase(it); + return DD_OK; + } + +protected: + std::vector items; }; -struct Direct3DRMDevice2Impl : public IDirect3DRMDevice2 { +struct Direct3DRMFrameArrayImpl : public Direct3DRMArrayBase { + using Direct3DRMArrayBase::Direct3DRMArrayBase; +}; + +struct Direct3DRMLightArrayImpl : public Direct3DRMArrayBase { + using Direct3DRMArrayBase::Direct3DRMArrayBase; +}; + +struct Direct3DRMViewportArrayImpl : public Direct3DRMArrayBase { + using Direct3DRMArrayBase::Direct3DRMArrayBase; +}; + +struct Direct3DRMVisualArrayImpl : public Direct3DRMArrayBase { + using Direct3DRMArrayBase::Direct3DRMArrayBase; +}; + +struct PickRecord { + IDirect3DRMVisual* visual; + IDirect3DRMFrameArray* frameArray; + D3DRMPICKDESC desc; +}; + +struct Direct3DRMPickedArrayImpl : public IDirect3DRMPickedArray { + ~Direct3DRMPickedArrayImpl() override + { + for (PickRecord& pick : picks) { + if (pick.visual) { + pick.visual->Release(); + } + if (pick.frameArray) { + pick.frameArray->Release(); + } + } + } + DWORD GetSize() override { return static_cast(picks.size()); } + HRESULT GetPick(DWORD index, IDirect3DRMVisual** visual, IDirect3DRMFrameArray** frameArray, D3DRMPICKDESC* desc) + override + { + if (index >= picks.size()) { + return DDERR_INVALIDPARAMS; + } + + const PickRecord& pick = picks[index]; + + *visual = pick.visual; + *frameArray = pick.frameArray; + *desc = pick.desc; + + if (*visual) { + (*visual)->AddRef(); + } + if (*frameArray) { + (*frameArray)->AddRef(); + } + + return DD_OK; + } + +private: + std::vector picks; +}; + +struct Direct3DRMWinDeviceImpl : public IDirect3DRMWinDevice { + HRESULT Activate() override { return DD_OK; } + HRESULT Paint() override { return DD_OK; } + void HandleActivate(WORD wParam) override {} + void HandlePaint(void* p_dc) override {} +}; + +template +struct Direct3DRMObjectBase : public T { + ULONG Release() override + { + if (IUnknown::m_refCount == 1) { + for (auto it = m_callbacks.cbegin(); it != m_callbacks.cend(); it++) { + it->first(this, it->second); + } + } + return this->T::Release(); + } + HRESULT AddDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) override + { + m_callbacks.push_back(std::make_pair(callback, arg)); + return D3DRM_OK; + } + HRESULT DeleteDestroyCallback(D3DRMOBJECTCALLBACK callback, void* arg) override + { + for (auto it = m_callbacks.cbegin(); it != m_callbacks.cend(); it++) { + if (it->first == callback && it->second == arg) { + m_callbacks.erase(it); + return D3DRM_OK; + } + } + return D3DRMERR_NOTFOUND; + } + HRESULT SetAppData(LPD3DRM_APPDATA appData) override + { + m_appData = appData; + return D3DRM_OK; + } + LPVOID GetAppData() override { return m_appData; } + HRESULT SetName(const char* name) override + { + SDL_free(m_name); + m_name = NULL; + if (name) { + m_name = SDL_strdup(name); + } + return D3DRM_OK; + } + HRESULT GetName(DWORD* size, char* name) override + { + if (!size) { + return DDERR_INVALIDPARAMS; + } + const char* s = m_name ? m_name : ""; + size_t l = SDL_strlen(s); + if (name) { + SDL_strlcpy(name, s, *size); + } + else { + *size = l + 1; + } + return D3DRM_OK; + } + +private: + std::vector> m_callbacks; + LPD3DRM_APPDATA m_appData = NULL; + char* m_name = nullptr; +}; + +struct Direct3DRMMeshImpl : public Direct3DRMObjectBase { + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMMeshImpl); + return DD_OK; + } + HRESULT Clone(int flags, GUID iid, void** object) override + { + if (SDL_memcmp(&iid, &IID_IDirect3DRMMesh, sizeof(GUID)) == 0) { + *object = static_cast(new Direct3DRMMeshImpl); + return S_OK; + } + + return DDERR_GENERIC; + } + HRESULT GetBox(D3DRMBOX* box) override { return DD_OK; } + HRESULT AddGroup(int vertexCount, int faceCount, int vertexPerFace, void* faceBuffer, D3DRMGROUPINDEX* groupIndex) + override + { + return DD_OK; + } + HRESULT GetGroup( + int groupIndex, + unsigned int* vertexCount, + unsigned int* faceCount, + unsigned int* vertexPerFace, + DWORD* dataSize, + unsigned int* data + ) override + { + return DD_OK; + } + HRESULT SetGroupColor(int groupIndex, D3DCOLOR color) override { return DD_OK; } + HRESULT SetGroupColorRGB(int groupIndex, float r, float g, float b) override { return DD_OK; } + HRESULT SetGroupMaterial(int groupIndex, IDirect3DRMMaterial* material) override { return DD_OK; } + HRESULT SetGroupMapping(D3DRMGROUPINDEX groupIndex, D3DRMMAPPING mapping) override { return DD_OK; } + HRESULT SetGroupQuality(int groupIndex, D3DRMRENDERQUALITY quality) override { return DD_OK; } + HRESULT SetVertices(int groupIndex, int offset, int count, D3DRMVERTEX* vertices) override { return DD_OK; } + HRESULT SetGroupTexture(int groupIndex, IDirect3DRMTexture* texture) override + { + m_groupTexture = texture; + return DD_OK; + } + HRESULT GetGroupTexture(int groupIndex, LPDIRECT3DRMTEXTURE* texture) override + { + if (!m_groupTexture) { + return DDERR_GENERIC; + } + *texture = m_groupTexture; + return DD_OK; + } + D3DRMMAPPING GetGroupMapping(int groupIndex) override { return D3DRMMAP_PERSPCORRECT; } + D3DRMRENDERQUALITY GetGroupQuality(int groupIndex) override { return D3DRMRENDER_GOURAUD; } + HRESULT GetGroupColor(D3DRMGROUPINDEX index) override { return DD_OK; } + HRESULT GetVertices(int groupIndex, int startIndex, int count, D3DRMVERTEX* vertices) override { return DD_OK; } + +private: + IDirect3DRMTexture* m_groupTexture; +}; + +struct Direct3DRMTextureImpl : public Direct3DRMObjectBase { + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMTextureImpl); + return DD_OK; + } + HRESULT Changed(BOOL pixels, BOOL palette) override { return DD_OK; } +}; + +struct Direct3DRMDevice2Impl : public Direct3DRMObjectBase { + Direct3DRMDevice2Impl() + { + m_viewports = new Direct3DRMViewportArrayImpl; + m_viewports->AddRef(); + } + ~Direct3DRMDevice2Impl() override { m_viewports->Release(); } + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMDevice2Impl); + return DD_OK; + } unsigned long GetWidth() override { return 640; } unsigned long GetHeight() override { return 480; } HRESULT SetBufferCount(int count) override { return DD_OK; } @@ -36,83 +283,82 @@ struct Direct3DRMDevice2Impl : public IDirect3DRMDevice2 { HRESULT SetRenderMode(D3DRMRENDERMODE mode) override { return DD_OK; } D3DRMRENDERMODE GetRenderMode() override { return D3DRMRENDERMODE::BLENDEDTRANSPARENCY; } HRESULT Update() override { return DD_OK; } + HRESULT AddViewport(IDirect3DRMViewport* viewport) override { return m_viewports->AddElement(viewport); } HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *ppViewportArray = m_viewports; + return DD_OK; } + +private: + IDirect3DRMViewportArray* m_viewports; }; -struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 { - HRESULT SetAppData(LPD3DRM_APPDATA appData) override +struct Direct3DRMFrameImpl : public Direct3DRMObjectBase { + Direct3DRMFrameImpl() { - m_data = appData; - return DD_OK; - } - LPVOID GetAppData() override { return m_data; } - HRESULT AddChild(IDirect3DRMFrame* child) override - { - child->AddRef(); - return DD_OK; - } - HRESULT DeleteChild(IDirect3DRMFrame* child) override - { - child->Release(); + m_children = new Direct3DRMFrameArrayImpl; + m_children->AddRef(); + m_lights = new Direct3DRMLightArrayImpl; + m_lights->AddRef(); + m_visuals = new Direct3DRMVisualArrayImpl; + m_visuals->AddRef(); + } + ~Direct3DRMFrameImpl() override + { + m_children->Release(); + m_lights->Release(); + m_visuals->Release(); + if (m_texture) { + m_texture->Release(); + } + } + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMFrameImpl); return DD_OK; } + HRESULT AddChild(IDirect3DRMFrame* child) override { return m_children->AddElement(child); } + HRESULT DeleteChild(IDirect3DRMFrame* child) override { return m_children->DeleteElement(child); } HRESULT SetSceneBackgroundRGB(float r, float g, float b) override { return DD_OK; } - HRESULT AddLight(IDirect3DRMLight* light) override - { - light->AddRef(); - return DD_OK; - } + HRESULT AddLight(IDirect3DRMLight* light) override { return m_lights->AddElement(light); } HRESULT GetLights(IDirect3DRMLightArray** lightArray) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *lightArray = m_lights; + m_lights->AddRef(); + return DD_OK; } HRESULT AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix) override { return DD_OK; } HRESULT GetPosition(int index, D3DVECTOR* position) override { return DD_OK; } - HRESULT AddVisual(IDirect3DRMVisual* visual) override - { - visual->AddRef(); - return DD_OK; - } - HRESULT DeleteVisual(IDirect3DRMVisual* visual) override - { - visual->Release(); - return DD_OK; - } - HRESULT AddVisual(IDirect3DRMMesh* visual) override - { - visual->AddRef(); - return DD_OK; - } - HRESULT DeleteVisual(IDirect3DRMMesh* visual) override - { - visual->Release(); - return DD_OK; - } - HRESULT AddVisual(IDirect3DRMFrame* visual) override - { - visual->AddRef(); - return DD_OK; - } - HRESULT DeleteVisual(IDirect3DRMFrame* visual) override - { - visual->Release(); - return DD_OK; - } + HRESULT AddVisual(IDirect3DRMVisual* visual) override { return m_visuals->AddElement(visual); } + HRESULT DeleteVisual(IDirect3DRMVisual* visual) override { return m_visuals->DeleteElement(visual); } + HRESULT AddVisual(IDirect3DRMMesh* visual) override { return m_visuals->AddElement(visual); } + HRESULT DeleteVisual(IDirect3DRMMesh* visual) override { return m_visuals->DeleteElement(visual); } + HRESULT AddVisual(IDirect3DRMFrame* visual) override { return m_visuals->AddElement(visual); } + HRESULT DeleteVisual(IDirect3DRMFrame* visual) override { return m_visuals->DeleteElement(visual); } HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *visuals = m_visuals; + m_visuals->AddRef(); + return DD_OK; + } + HRESULT SetTexture(IDirect3DRMTexture* texture) override + { + if (m_texture) { + m_texture->Release(); + } + m_texture = texture; + m_texture->AddRef(); + return DD_OK; } - HRESULT SetTexture(const IDirect3DRMTexture* texture) override { return DD_OK; } HRESULT GetTexture(IDirect3DRMTexture** texture) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + if (!m_texture) { + return DDERR_GENERIC; + } + *texture = m_texture; + m_texture->AddRef(); + return DD_OK; } HRESULT SetColor(float r, float g, float b, float a) override { return DD_OK; } HRESULT SetColor(D3DCOLOR) override { return DD_OK; } @@ -120,40 +366,36 @@ struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 { HRESULT SetMaterialMode(D3DRMMATERIALMODE mode) override { return DD_OK; } HRESULT GetChildren(IDirect3DRMFrameArray** children) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *children = m_children; + m_children->AddRef(); + return DD_OK; } private: - LPD3DRM_APPDATA m_data; + IDirect3DRMFrameArray* m_children; + IDirect3DRMLightArray* m_lights; + IDirect3DRMVisualArray* m_visuals; + IDirect3DRMTexture* m_texture; }; -struct Direct3DRMViewportImpl : public IDirect3DRMViewport { - Direct3DRMViewportImpl() : m_data(nullptr) {} +struct Direct3DRMViewportImpl : public Direct3DRMObjectBase { HRESULT Clone(void** ppObject) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; - } - HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) override { return DD_OK; } - HRESULT DeleteDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) override { return DD_OK; } - HRESULT SetAppData(LPD3DRM_APPDATA appData) override - { - m_data = appData; + *ppObject = static_cast(new Direct3DRMViewportImpl); return DD_OK; } - LPVOID GetAppData() override { return m_data; } - HRESULT SetName(const char* name) override { return DD_OK; } - HRESULT GetName(DWORD* size, char* name) override { return DD_OK; } - HRESULT GetClassName(DWORD* size, char* name) override { return DD_OK; } HRESULT Render(IDirect3DRMFrame* group) override { return DD_OK; } HRESULT ForceUpdate(int x, int y, int w, int h) override { return DD_OK; } HRESULT Clear() override { return DD_OK; } - HRESULT SetCamera(IDirect3DRMFrame* camera) override { return DD_OK; } + HRESULT SetCamera(IDirect3DRMFrame* camera) override + { + m_camera = camera; + return DD_OK; + } HRESULT GetCamera(IDirect3DRMFrame** camera) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *camera = m_camera; + return DD_OK; } HRESULT SetProjection(D3DRMPROJECTIONTYPE type) override { return DD_OK; } D3DRMPROJECTIONTYPE GetProjection() override { return D3DRMPROJECTIONTYPE::PERSPECTIVE; } @@ -170,14 +412,27 @@ struct Direct3DRMViewportImpl : public IDirect3DRMViewport { HRESULT Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) override { return DD_OK; } private: - LPD3DRM_APPDATA m_data; + IDirect3DRMFrame* m_camera; }; -struct Direct3DRMLightImpl : public IDirect3DRMLight { +struct Direct3DRMLightImpl : public Direct3DRMObjectBase { + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMLightImpl); + return DD_OK; + } HRESULT SetColorRGB(float r, float g, float b) override { return DD_OK; } }; -struct Direct3DRMImpl : public IDirect3DRM2 { +struct Direct3DRMMaterialImpl : public Direct3DRMObjectBase { + HRESULT Clone(void** ppObject) override + { + *ppObject = static_cast(new Direct3DRMMaterialImpl); + return DD_OK; + } +}; + +struct Direct3DRMImpl : virtual public IDirect3DRM2 { // IUnknown interface HRESULT QueryInterface(const GUID& riid, void** ppvObject) override { @@ -203,27 +458,27 @@ struct Direct3DRMImpl : public IDirect3DRM2 { IDirect3DRMDevice2** outDevice ) override { - assert(false && "unimplemented"); - return DDERR_GENERIC; + *outDevice = static_cast(new Direct3DRMDevice2Impl); + return S_OK; } HRESULT CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) override { *outTexture = static_cast(new Direct3DRMTextureImpl); - return DDERR_GENERIC; + return S_OK; } HRESULT CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture) override { *outTexture = static_cast(new Direct3DRMTextureImpl); - return DDERR_GENERIC; + return S_OK; } HRESULT CreateMesh(IDirect3DRMMesh** outMesh) override { - // TODO + *outMesh = static_cast(new Direct3DRMMeshImpl); return DDERR_GENERIC; } HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) override { - *outMaterial = new IDirect3DRMMaterial; + *outMaterial = static_cast(new Direct3DRMMaterialImpl); return DD_OK; } HRESULT CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight) override @@ -247,6 +502,7 @@ struct Direct3DRMImpl : public IDirect3DRM2 { ) override { *outViewport = static_cast(new Direct3DRMViewportImpl); + device->AddViewport(*outViewport); return DD_OK; } HRESULT SetDefaultTextureShades(unsigned int count) override { return DD_OK; } diff --git a/miniwin/miniwin/src/miniwin_ddraw.cpp b/miniwin/miniwin/src/miniwin_ddraw.cpp index 7d4a7c43..c6026930 100644 --- a/miniwin/miniwin/src/miniwin_ddraw.cpp +++ b/miniwin/miniwin/src/miniwin_ddraw.cpp @@ -113,10 +113,6 @@ HRESULT DirectDrawImpl::EnumDisplayModes( LPDDENUMMODESCALLBACK lpEnumModesCallback ) { - if (!lpEnumModesCallback) { - return DDERR_INVALIDPARAMS; - } - SDL_DisplayID displayID = SDL_GetPrimaryDisplay(); if (!displayID) { return DDERR_GENERIC; @@ -181,10 +177,6 @@ HRESULT DirectDrawImpl::GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) { - if (!cb) { - return DDERR_INVALIDPARAMS; - } - int numDrivers = SDL_GetNumRenderDrivers(); if (numDrivers <= 0) { return DDERR_GENERIC; @@ -288,9 +280,6 @@ HRESULT DirectDrawCreate(LPGUID lpGuid, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOute if (lpGuid) { MINIWIN_ERROR("Specifying a DirectDraw driver is not implemented"); } - if (!lplpDD) { - return DDERR_INVALIDPARAMS; - } *lplpDD = new DirectDrawImpl; diff --git a/miniwin/miniwin/src/miniwin_ddsurface.cpp b/miniwin/miniwin/src/miniwin_ddsurface.cpp index e4461d2a..0ed41e9e 100644 --- a/miniwin/miniwin/src/miniwin_ddsurface.cpp +++ b/miniwin/miniwin/src/miniwin_ddsurface.cpp @@ -10,16 +10,16 @@ DirectDrawSurfaceImpl::DirectDrawSurfaceImpl() DirectDrawSurfaceImpl::DirectDrawSurfaceImpl(int width, int height) { - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); - if (!texture) { + m_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); + if (!m_texture) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError()); } } DirectDrawSurfaceImpl::~DirectDrawSurfaceImpl() { - if (texture) { - SDL_DestroyTexture(texture); + if (m_texture) { + SDL_DestroyTexture(m_texture); } } @@ -53,7 +53,7 @@ HRESULT DirectDrawSurfaceImpl::Blt( } SDL_FRect srcRect = ConvertRect(lpSrcRect); SDL_FRect dstRect = ConvertRect(lpDestRect); - SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->texture, &srcRect, &dstRect); + SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->m_texture, &srcRect, &dstRect); SDL_RenderPresent(renderer); return DD_OK; } @@ -76,20 +76,20 @@ HRESULT DirectDrawSurfaceImpl::BltFast( (float) (lpSrcRect->bottom - lpSrcRect->top) }; SDL_FRect srcRect = ConvertRect(lpSrcRect); - SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->texture, &srcRect, &dstRect); + SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->m_texture, &srcRect, &dstRect); SDL_RenderPresent(renderer); return DD_OK; } HRESULT DirectDrawSurfaceImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) { - if (!renderer || !texture) { + if (!renderer || !m_texture) { return DDERR_GENERIC; } float width, height; - SDL_GetTextureSize(texture, &width, &height); + SDL_GetTextureSize(m_texture, &width, &height); SDL_FRect rect{0, 0, width, height}; - SDL_RenderTexture(renderer, texture, &rect, &rect); + SDL_RenderTexture(renderer, m_texture, &rect, &rect); SDL_RenderPresent(renderer); return DD_OK; } @@ -120,8 +120,12 @@ HRESULT DirectDrawSurfaceImpl::GetOverlayPosition(LPLONG lplX, LPLONG lplY) HRESULT DirectDrawSurfaceImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) { - assert(false && "unimplemented"); - return DDERR_GENERIC; + if (!m_palette) { + return DDERR_GENERIC; + } + m_palette->AddRef(); + *lplpDDPalette = m_palette; + return DD_OK; } HRESULT DirectDrawSurfaceImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) @@ -133,10 +137,10 @@ HRESULT DirectDrawSurfaceImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) HRESULT DirectDrawSurfaceImpl::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) { - if (!texture) { + if (!m_texture) { return DDERR_GENERIC; } - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(m_texture->format); lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; @@ -156,22 +160,19 @@ HRESULT DirectDrawSurfaceImpl::Lock( HANDLE hEvent ) { - if (!lpDDSurfaceDesc) { - return DDERR_INVALIDPARAMS; - } - if (!texture) { + if (!m_texture) { return DDERR_GENERIC; } int pitch = 0; void* pixels = nullptr; - if (SDL_LockTexture(texture, (SDL_Rect*) lpDestRect, &pixels, &pitch) < 0) { + if (SDL_LockTexture(m_texture, (SDL_Rect*) lpDestRect, &pixels, &pitch) < 0) { return DDERR_GENERIC; } lpDDSurfaceDesc->lpSurface = pixels; lpDDSurfaceDesc->lPitch = pitch; - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(texture->format); + const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(m_texture->format); lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = (format->bits_per_pixel == 8) ? 8 : 16; lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = format->Rmask; @@ -208,9 +209,9 @@ HRESULT DirectDrawSurfaceImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) HRESULT DirectDrawSurfaceImpl::Unlock(LPVOID lpSurfaceData) { - if (!texture) { + if (!m_texture) { return DDERR_GENERIC; } - SDL_UnlockTexture(texture); + SDL_UnlockTexture(m_texture); return DD_OK; }