From fb54b4d1c290f17404f996a38b20f0d533c4a368 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 17 May 2025 08:14:36 -0700 Subject: [PATCH 01/15] Use dynamically allocated buffer (#105) --- LEGO1/omni/src/audio/mxsoundmanager.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/LEGO1/omni/src/audio/mxsoundmanager.cpp b/LEGO1/omni/src/audio/mxsoundmanager.cpp index 141bfa64..0d14343c 100644 --- a/LEGO1/omni/src/audio/mxsoundmanager.cpp +++ b/LEGO1/omni/src/audio/mxsoundmanager.cpp @@ -136,15 +136,16 @@ void MxSoundManager::AudioStreamCallback( int p_totalAmount ) { - static MxU8 g_buffer[4096]; + static vector g_buffer; + g_buffer.reserve(p_additionalAmount); MxSoundManager* manager = (MxSoundManager*) p_userdata; ma_uint32 bytesPerFrame = ma_get_bytes_per_frame(ma_format_f32, ma_engine_get_channels(&manager->m_engine)); - ma_uint32 bufferSizeInFrames = (ma_uint32) SDL_min(sizeof(g_buffer), p_additionalAmount) / bytesPerFrame; + ma_uint32 bufferSizeInFrames = (ma_uint32) p_additionalAmount / bytesPerFrame; ma_uint64 framesRead; - if (ma_engine_read_pcm_frames(&manager->m_engine, g_buffer, bufferSizeInFrames, &framesRead) == MA_SUCCESS) { - SDL_PutAudioStreamData(manager->m_stream, g_buffer, framesRead * bytesPerFrame); + if (ma_engine_read_pcm_frames(&manager->m_engine, g_buffer.data(), bufferSizeInFrames, &framesRead) == MA_SUCCESS) { + SDL_PutAudioStreamData(manager->m_stream, g_buffer.data(), framesRead * bytesPerFrame); } } From 51d88b6cd8bc21aa2c2201d528d68f83455a6c2e Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 17 May 2025 17:45:38 +0200 Subject: [PATCH 02/15] Update README.md [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a19d52b8..1f29a2db 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ To achieve our goal of platform independence, we need to replace any Windows-onl | Keyboard/Mouse, DirectInput (Input) | [SDL3](https://www.libsdl.org/) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Ainput%5D%22&type=code) | | Joystick/Gamepad, DirectInput (Input) | [SDL3](https://www.libsdl.org/) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Ainput%5D%22&type=code) | | WinMM, DirectSound (Audio) | [SDL3](https://www.libsdl.org/), [miniaudio](https://miniaud.io/) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Aaudio%5D%22&type=code) | -| DirectDraw (2D video) | [SDL3](https://www.libsdl.org/) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3A2d%5D%22&type=code) | +| DirectDraw (2D video) | [SDL3](https://www.libsdl.org/) | 🚧 | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3A2d%5D%22&type=code) | | [Smacker](https://github.com/isledecomp/isle/tree/master/3rdparty/smacker) | [libsmacker](https://github.com/foxtacles/libsmacker) | ✅ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable%20%22%2F%2F%20%5Blibrary%3Alibsmacker%5D%22&type=code) | | Direct3D (3D video) | [SDL3](https://www.libsdl.org/), OpenGL ES (**TBD**) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3A3d%5D%22&type=code) | | Direct3D Retained Mode | Custom re-implementation (**TBD**) | ❌ | [Remarks](https://github.com/search?q=repo%3Aisledecomp%2Fisle-portable+%22%2F%2F+%5Blibrary%3Aretained%5D%22&type=code) | From 2d92aee5896b488dfc0eac9b7b530e33577e4b8e Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 17 May 2025 22:24:06 +0200 Subject: [PATCH 03/15] Correct delete[] in mxcontrolpresenter.cpp (#1498) --- LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp index 17beb3c1..4b412940 100644 --- a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp @@ -28,7 +28,7 @@ MxControlPresenter::MxControlPresenter() MxControlPresenter::~MxControlPresenter() { if (m_states) { - delete m_states; + delete[] m_states; } } From d3cd491765746b250d9fe0a244b5c5da48e79983 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 17 May 2025 22:25:22 +0200 Subject: [PATCH 04/15] Correct delete[] in legowegedge.cpp (#1499) --- LEGO1/lego/sources/geom/legowegedge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/lego/sources/geom/legowegedge.cpp b/LEGO1/lego/sources/geom/legowegedge.cpp index 110cd2c6..5c3a68d2 100644 --- a/LEGO1/lego/sources/geom/legowegedge.cpp +++ b/LEGO1/lego/sources/geom/legowegedge.cpp @@ -35,7 +35,7 @@ LegoWEGEdge::~LegoWEGEdge() delete[] m_edgeNormals; } if (m_pathTrigger) { - delete m_pathTrigger; + delete[] m_pathTrigger; } if (m_unk0x50) { delete m_unk0x50; From bc920a295b2bd5879c3f75edd761669653fac154 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 17 May 2025 22:26:01 +0200 Subject: [PATCH 05/15] Correct assert in view.cpp (#1500) --- LEGO1/tgl/d3drm/view.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LEGO1/tgl/d3drm/view.cpp b/LEGO1/tgl/d3drm/view.cpp index aba7df5a..654528fe 100644 --- a/LEGO1/tgl/d3drm/view.cpp +++ b/LEGO1/tgl/d3drm/view.cpp @@ -443,9 +443,9 @@ inline Result ViewRender(IDirect3DRMViewport* pViewport, const IDirect3DRMFrame2 pViewportAppData->m_backgroundColorGreen, pViewportAppData->m_backgroundColorBlue ); - } - assert(Succeeded(result)); + assert(Succeeded(result)); + } result = ResultVal(pViewport->Render(const_cast(pGroup))); assert(Succeeded(result)); From 45e0e5bdd15ff211ca703d8d4824084f9180669b Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 17 May 2025 23:22:30 +0200 Subject: [PATCH 06/15] Correct delete[] in mxflcpresenter.cpp (#1501) * Correct delete[] in mxflcpresenter.cpp * Update LEGO1/omni/src/video/mxflcpresenter.cpp Co-authored-by: Christian Semmler --------- Co-authored-by: Christian Semmler --- LEGO1/omni/src/video/mxflcpresenter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/omni/src/video/mxflcpresenter.cpp b/LEGO1/omni/src/video/mxflcpresenter.cpp index 57b734c1..eb075357 100644 --- a/LEGO1/omni/src/video/mxflcpresenter.cpp +++ b/LEGO1/omni/src/video/mxflcpresenter.cpp @@ -21,7 +21,7 @@ MxFlcPresenter::MxFlcPresenter() MxFlcPresenter::~MxFlcPresenter() { if (this->m_flcHeader) { - delete this->m_flcHeader; + delete[] ((MxU8*) this->m_flcHeader); } } From 3f0fe654fff71505d4982c00b68a4944424031d2 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 01:14:25 +0200 Subject: [PATCH 07/15] Fix delete[] in mxstillpresenter.cpp (#1496) * Fix delete[] in mxstillpresenter.cpp Without this the game doesn't run on Linux :) * Update LEGO1/omni/src/video/mxstillpresenter.cpp Co-authored-by: Christian Semmler * Update mxstillpresenter.cpp --------- Co-authored-by: Christian Semmler --- LEGO1/omni/src/video/mxstillpresenter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LEGO1/omni/src/video/mxstillpresenter.cpp b/LEGO1/omni/src/video/mxstillpresenter.cpp index 03ffcb31..a9731233 100644 --- a/LEGO1/omni/src/video/mxstillpresenter.cpp +++ b/LEGO1/omni/src/video/mxstillpresenter.cpp @@ -20,7 +20,7 @@ void MxStillPresenter::Destroy(MxBool p_fromDestructor) m_criticalSection.Enter(); if (m_bitmapInfo) { - delete m_bitmapInfo; + delete[] ((MxU8*) m_bitmapInfo); } m_bitmapInfo = NULL; @@ -35,7 +35,7 @@ void MxStillPresenter::Destroy(MxBool p_fromDestructor) void MxStillPresenter::LoadHeader(MxStreamChunk* p_chunk) { if (m_bitmapInfo) { - delete m_bitmapInfo; + delete[] ((MxU8*) m_bitmapInfo); } MxU8* data = new MxU8[p_chunk->GetLength()]; @@ -53,7 +53,7 @@ void MxStillPresenter::CreateBitmap() m_frameBitmap = new MxBitmap; m_frameBitmap->ImportBitmapInfo(m_bitmapInfo); - delete m_bitmapInfo; + delete[] ((MxU8*) m_bitmapInfo); m_bitmapInfo = NULL; } From 44122f2f8a9e31a9eb08808f0c0c04a65844f47e Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 01:17:07 +0200 Subject: [PATCH 08/15] Implement DirectDrawPalette methods (#106) * Implement palettes * Update miniwin/miniwin/src/miniwin_ddsurface.cpp Co-authored-by: Anonymous Maarten * Update miniwin/miniwin/src/miniwin_ddpalette.cpp * Update miniwin/miniwin/src/miniwin_ddraw.cpp --------- Co-authored-by: Anonymous Maarten --- .../miniwin/src/include/miniwin_ddpalette_p.h | 4 +++ miniwin/miniwin/src/miniwin_ddpalette.cpp | 25 +++++++++++++++++++ miniwin/miniwin/src/miniwin_ddraw.cpp | 4 +++ miniwin/miniwin/src/miniwin_ddsurface.cpp | 5 ++++ 4 files changed, 38 insertions(+) diff --git a/miniwin/miniwin/src/include/miniwin_ddpalette_p.h b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h index 04804431..59c69b6d 100644 --- a/miniwin/miniwin/src/include/miniwin_ddpalette_p.h +++ b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h @@ -4,7 +4,11 @@ struct DirectDrawPaletteImpl : public IDirectDrawPalette { DirectDrawPaletteImpl(LPPALETTEENTRY lpColorTable); + ~DirectDrawPaletteImpl() override; 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; + +private: + SDL_Palette* m_palette; }; diff --git a/miniwin/miniwin/src/miniwin_ddpalette.cpp b/miniwin/miniwin/src/miniwin_ddpalette.cpp index 0615f06c..7131ac13 100644 --- a/miniwin/miniwin/src/miniwin_ddpalette.cpp +++ b/miniwin/miniwin/src/miniwin_ddpalette.cpp @@ -1,8 +1,17 @@ #include "miniwin_ddpalette_p.h" #include "miniwin_ddraw.h" +#include + DirectDrawPaletteImpl::DirectDrawPaletteImpl(LPPALETTEENTRY lpColorTable) { + m_palette = SDL_CreatePalette(256); + SetEntries(0, 0, 256, lpColorTable); +} + +DirectDrawPaletteImpl::~DirectDrawPaletteImpl() +{ + SDL_DestroyPalette(m_palette); } HRESULT DirectDrawPaletteImpl::GetCaps(LPDWORD lpdwCaps) @@ -12,10 +21,26 @@ HRESULT DirectDrawPaletteImpl::GetCaps(LPDWORD lpdwCaps) HRESULT DirectDrawPaletteImpl::GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) { + for (int i = dwBase; i < dwNumEntries; i++) { + lpEntries[i].peRed = m_palette->colors[i].r; + lpEntries[i].peGreen = m_palette->colors[i].g; + lpEntries[i].peBlue = m_palette->colors[i].b; + lpEntries[i].peFlags = PC_NONE; + } return DD_OK; } HRESULT DirectDrawPaletteImpl::SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) { + SDL_Color colors[256]; + for (int i = 0; i < dwCount; i++) { + colors[i].r = lpEntries[i].peRed; + colors[i].g = lpEntries[i].peGreen; + colors[i].b = lpEntries[i].peBlue; + colors[i].a = SDL_ALPHA_OPAQUE; + } + + SDL_SetPaletteColors(m_palette, colors, dwStartingEntry, dwCount); + return DD_OK; } diff --git a/miniwin/miniwin/src/miniwin_ddraw.cpp b/miniwin/miniwin/src/miniwin_ddraw.cpp index c6026930..b0d60e17 100644 --- a/miniwin/miniwin/src/miniwin_ddraw.cpp +++ b/miniwin/miniwin/src/miniwin_ddraw.cpp @@ -45,6 +45,10 @@ HRESULT DirectDrawImpl::CreatePalette( IUnknown* pUnkOuter ) { + if ((dwFlags & DDPCAPS_8BIT) != DDPCAPS_8BIT) { + return DDERR_INVALIDPARAMS; + } + *lplpDDPalette = static_cast(new DirectDrawPaletteImpl(lpColorTable)); return DD_OK; } diff --git a/miniwin/miniwin/src/miniwin_ddsurface.cpp b/miniwin/miniwin/src/miniwin_ddsurface.cpp index 0ed41e9e..944c1e98 100644 --- a/miniwin/miniwin/src/miniwin_ddsurface.cpp +++ b/miniwin/miniwin/src/miniwin_ddsurface.cpp @@ -21,6 +21,9 @@ DirectDrawSurfaceImpl::~DirectDrawSurfaceImpl() if (m_texture) { SDL_DestroyTexture(m_texture); } + if (m_palette) { + m_palette->Release(); + } } // IUnknown interface @@ -204,6 +207,8 @@ HRESULT DirectDrawSurfaceImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY HRESULT DirectDrawSurfaceImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) { + m_palette = lpDDPalette; + m_palette->AddRef(); return DD_OK; } From 9b8bbc3e76c818e5b9be941d5da54f590fb99672 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 01:39:35 +0200 Subject: [PATCH 09/15] Fix game startup bits (#102) --- .../legoomni/src/video/legomodelpresenter.cpp | 2 +- miniwin/miniwin/src/miniwin_d3drm.cpp | 26 +++++++++---- miniwin/miniwin/src/miniwin_ddsurface.cpp | 39 ++++++++++++------- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp index 84e0ab24..d64ec94d 100644 --- a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp @@ -97,7 +97,7 @@ MxResult LegoModelPresenter::CreateROI(MxDSChunk* p_chunk) SDL_strlwr(textureName); if (textureName[0] == '^') { - strcpy(textureName, textureName + 1); + memmove(textureName, textureName + 1, strlen(textureName)); if (g_modelPresenterConfig) { texture = new LegoTexture(); diff --git a/miniwin/miniwin/src/miniwin_d3drm.cpp b/miniwin/miniwin/src/miniwin_d3drm.cpp index 564f5e3c..7f779eca 100644 --- a/miniwin/miniwin/src/miniwin_d3drm.cpp +++ b/miniwin/miniwin/src/miniwin_d3drm.cpp @@ -197,7 +197,7 @@ struct Direct3DRMMeshImpl : public Direct3DRMObjectBase { { if (SDL_memcmp(&iid, &IID_IDirect3DRMMesh, sizeof(GUID)) == 0) { *object = static_cast(new Direct3DRMMeshImpl); - return S_OK; + return DD_OK; } return DDERR_GENERIC; @@ -206,8 +206,7 @@ struct Direct3DRMMeshImpl : public Direct3DRMObjectBase { HRESULT AddGroup(int vertexCount, int faceCount, int vertexPerFace, void* faceBuffer, D3DRMGROUPINDEX* groupIndex) override { - assert(false && "Unimplemented"); - return DDERR_GENERIC; + return DD_OK; } HRESULT GetGroup( int groupIndex, @@ -236,6 +235,7 @@ struct Direct3DRMMeshImpl : public Direct3DRMObjectBase { if (!m_groupTexture) { return DDERR_GENERIC; } + m_groupTexture->AddRef(); *texture = m_groupTexture; return DD_OK; } @@ -249,6 +249,16 @@ struct Direct3DRMMeshImpl : public Direct3DRMObjectBase { }; struct Direct3DRMTextureImpl : public Direct3DRMObjectBase { + HRESULT QueryInterface(const GUID& riid, void** ppvObject) override + { + if (SDL_memcmp(&riid, &IID_IDirect3DRMTexture2, sizeof(GUID)) == 0) { + this->IUnknown::AddRef(); + *ppvObject = static_cast(this); + return DD_OK; + } + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Direct3DRMTextureImpl does not implement guid"); + return E_NOINTERFACE; + } HRESULT Clone(void** ppObject) override { *ppObject = static_cast(new Direct3DRMTextureImpl); @@ -440,7 +450,7 @@ struct Direct3DRMImpl : virtual public IDirect3DRM2 { if (SDL_memcmp(&riid, &IID_IDirect3DRM2, sizeof(GUID)) == 0) { this->IUnknown::AddRef(); *ppvObject = static_cast(this); - return S_OK; + return DD_OK; } SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DirectDrawImpl does not implement guid"); return E_NOINTERFACE; @@ -450,7 +460,7 @@ struct Direct3DRMImpl : virtual public IDirect3DRM2 { override { *outDevice = static_cast(new Direct3DRMDevice2Impl); - return S_OK; + return DD_OK; } HRESULT CreateDeviceFromSurface( const GUID* guid, @@ -460,17 +470,17 @@ struct Direct3DRMImpl : virtual public IDirect3DRM2 { ) override { *outDevice = static_cast(new Direct3DRMDevice2Impl); - return S_OK; + return DD_OK; } HRESULT CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) override { *outTexture = static_cast(new Direct3DRMTextureImpl); - return S_OK; + return DD_OK; } HRESULT CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture) override { *outTexture = static_cast(new Direct3DRMTextureImpl); - return S_OK; + return DD_OK; } HRESULT CreateMesh(IDirect3DRMMesh** outMesh) override { diff --git a/miniwin/miniwin/src/miniwin_ddsurface.cpp b/miniwin/miniwin/src/miniwin_ddsurface.cpp index 944c1e98..06dae67b 100644 --- a/miniwin/miniwin/src/miniwin_ddsurface.cpp +++ b/miniwin/miniwin/src/miniwin_ddsurface.cpp @@ -54,9 +54,21 @@ HRESULT DirectDrawSurfaceImpl::Blt( if (!renderer) { return DDERR_GENERIC; } - SDL_FRect srcRect = ConvertRect(lpSrcRect); - SDL_FRect dstRect = ConvertRect(lpDestRect); - SDL_RenderTexture(renderer, static_cast(lpDDSrcSurface)->m_texture, &srcRect, &dstRect); + auto srcSurface = static_cast(lpDDSrcSurface); + SDL_FRect srcRect, dstRect; + if (lpSrcRect) { + srcRect = ConvertRect(lpSrcRect); + } + else { + srcRect = {0, 0, (float) srcSurface->m_texture->w, (float) srcSurface->m_texture->h}; + } + if (lpDestRect) { + dstRect = ConvertRect(lpDestRect); + } + else { + dstRect = {0, 0, (float) m_texture->w, (float) m_texture->h}; + } + SDL_RenderTexture(renderer, srcSurface->m_texture, &srcRect, &dstRect); SDL_RenderPresent(renderer); return DD_OK; } @@ -72,14 +84,16 @@ HRESULT DirectDrawSurfaceImpl::BltFast( 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)->m_texture, &srcRect, &dstRect); + auto srcSurface = static_cast(lpDDSrcSurface); + SDL_FRect srcRect; + if (lpSrcRect) { + srcRect = ConvertRect(lpSrcRect); + } + else { + srcRect = {0, 0, (float) srcSurface->m_texture->w, (float) srcSurface->m_texture->h}; + } + SDL_FRect dstRect = {(float) dwX, (float) dwY, srcRect.w, srcRect.h}; + SDL_RenderTexture(renderer, srcSurface->m_texture, &srcRect, &dstRect); SDL_RenderPresent(renderer); return DD_OK; } @@ -90,8 +104,7 @@ HRESULT DirectDrawSurfaceImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverrid return DDERR_GENERIC; } float width, height; - SDL_GetTextureSize(m_texture, &width, &height); - SDL_FRect rect{0, 0, width, height}; + SDL_FRect rect{0, 0, (float) m_texture->w, (float) m_texture->h}; SDL_RenderTexture(renderer, m_texture, &rect, &rect); SDL_RenderPresent(renderer); return DD_OK; From d00c08cc197caa8887c32cd8d1d68681962814d7 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 03:01:29 +0200 Subject: [PATCH 10/15] Rename FUN_1009e020 to ClearBackBuffers (#1503) * Rename FUN_1009e020 to ClearBackBuffers * Update mxdirectdraw.h --- LEGO1/mxdirectx/mxdirectdraw.cpp | 4 ++-- LEGO1/mxdirectx/mxdirectdraw.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LEGO1/mxdirectx/mxdirectdraw.cpp b/LEGO1/mxdirectx/mxdirectdraw.cpp index ebdfafa7..86910dde 100644 --- a/LEGO1/mxdirectx/mxdirectdraw.cpp +++ b/LEGO1/mxdirectx/mxdirectdraw.cpp @@ -399,7 +399,7 @@ BOOL MxDirectDraw::DDSetMode(int width, int height, int bpp) DDSURFACEDESC ddsd; - FUN_1009e020(); + ClearBackBuffers(); if (!GetDDSurfaceDesc(&ddsd, m_pBackBuffer)) { return FALSE; @@ -549,7 +549,7 @@ BOOL MxDirectDraw::DDCreateSurfaces() // FUNCTION: LEGO1 0x1009e020 // FUNCTION: BETA10 0x10121700 -void MxDirectDraw::FUN_1009e020() +void MxDirectDraw::ClearBackBuffers() { HRESULT result; byte* line; diff --git a/LEGO1/mxdirectx/mxdirectdraw.h b/LEGO1/mxdirectx/mxdirectdraw.h index 75b0f965..dd16f2e8 100644 --- a/LEGO1/mxdirectx/mxdirectdraw.h +++ b/LEGO1/mxdirectx/mxdirectdraw.h @@ -79,7 +79,7 @@ class MxDirectDraw { void Error(const char* p_message, int p_error); BOOL RecreateDirectDraw(GUID** a2); - void FUN_1009e020(); + void ClearBackBuffers(); void FUN_1009d920(); // SYNTHETIC: LEGO1 0x1009d510 From c9b41e2db8457219bc7af20556871f23cf458c5b Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 04:09:44 +0200 Subject: [PATCH 11/15] Fix delete in legoanimmmpresenter.cpp (#1504) --- LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp index d579beb1..59c361df 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp @@ -44,7 +44,7 @@ LegoAnimMMPresenter::~LegoAnimMMPresenter() VideoManager()->UnregisterPresenter(*this); } - delete m_unk0x68; + delete[] m_unk0x68; NotificationManager()->Unregister(this); } From 95eed310879f970f1f829f82dcccfffd8a614522 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 05:45:37 +0200 Subject: [PATCH 12/15] Fix free in minimfc (#107) --- miniwin/minimfc/src/minimfc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miniwin/minimfc/src/minimfc.cpp b/miniwin/minimfc/src/minimfc.cpp index a00223e4..967c0b68 100644 --- a/miniwin/minimfc/src/minimfc.cpp +++ b/miniwin/minimfc/src/minimfc.cpp @@ -81,7 +81,7 @@ int main(int argc, char* argv[]) } int result = wndTop->ExitInstance(); - free(afxCurrentAppName); + delete[] afxCurrentAppName; return result; } From 5b3d99cb8fd78ade55d2c32424dde7aeeaa7e59e Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 15:51:41 +0200 Subject: [PATCH 13/15] miniwin: Remove some unused bits (#108) --- CMakeLists.txt | 1 - miniwin/miniwin/include/miniwin_ddraw.h | 5 +---- miniwin/miniwin/src/include/miniwin_ddclipper_p.h | 14 -------------- miniwin/miniwin/src/include/miniwin_ddpalette_p.h | 1 - miniwin/miniwin/src/include/miniwin_ddsurface_p.h | 2 -- miniwin/miniwin/src/miniwin_ddclipper.cpp | 15 --------------- miniwin/miniwin/src/miniwin_ddpalette.cpp | 5 ----- miniwin/miniwin/src/miniwin_ddraw.cpp | 4 ++-- miniwin/miniwin/src/miniwin_ddsurface.cpp | 11 +---------- 9 files changed, 4 insertions(+), 54 deletions(-) delete mode 100644 miniwin/miniwin/src/include/miniwin_ddclipper_p.h delete mode 100644 miniwin/miniwin/src/miniwin_ddclipper.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b523183..5b58261b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,6 @@ 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 diff --git a/miniwin/miniwin/include/miniwin_ddraw.h b/miniwin/miniwin/include/miniwin_ddraw.h index 4310779a..99dfe3f3 100644 --- a/miniwin/miniwin/include/miniwin_ddraw.h +++ b/miniwin/miniwin/include/miniwin_ddraw.h @@ -292,14 +292,13 @@ typedef LOGPALETTE* LPLOGPALETTE; typedef struct IDirectDraw* LPDIRECTDRAW; struct IDirectDrawPalette : virtual public IUnknown { - virtual HRESULT GetCaps(LPDWORD lpdwCaps) = 0; virtual HRESULT GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) = 0; virtual HRESULT SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) = 0; }; typedef struct IDirectDrawPalette* LPDIRECTDRAWPALETTE; struct IDirectDrawClipper : virtual public IUnknown { - virtual HRESULT SetHWnd(DWORD unnamedParam1, HWND hWnd) = 0; + virtual HRESULT SetHWnd(DWORD unnamedParam1, HWND hWnd) { return DD_OK; } }; typedef IDirectDrawClipper* LPDIRECTDRAWCLIPPER; @@ -323,9 +322,7 @@ struct IDirectDrawSurface : virtual public IUnknown { ) = 0; virtual HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) = 0; virtual HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) = 0; - virtual HRESULT GetCaps(LPDDSCAPS lpDDSCaps) = 0; virtual HRESULT GetDC(HDC* lphDC) = 0; - virtual HRESULT GetOverlayPosition(LPLONG lplX, LPLONG lplY) = 0; virtual HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) = 0; virtual HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) = 0; virtual HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) = 0; diff --git a/miniwin/miniwin/src/include/miniwin_ddclipper_p.h b/miniwin/miniwin/src/include/miniwin_ddclipper_p.h deleted file mode 100644 index 0c094824..00000000 --- a/miniwin/miniwin/src/include/miniwin_ddclipper_p.h +++ /dev/null @@ -1,14 +0,0 @@ -#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 index 59c69b6d..98fe64c8 100644 --- a/miniwin/miniwin/src/include/miniwin_ddpalette_p.h +++ b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h @@ -5,7 +5,6 @@ struct DirectDrawPaletteImpl : public IDirectDrawPalette { DirectDrawPaletteImpl(LPPALETTEENTRY lpColorTable); ~DirectDrawPaletteImpl() override; - 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_ddsurface_p.h b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h index e20d42ac..71be1003 100644 --- a/miniwin/miniwin/src/include/miniwin_ddsurface_p.h +++ b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h @@ -23,9 +23,7 @@ struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { 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; diff --git a/miniwin/miniwin/src/miniwin_ddclipper.cpp b/miniwin/miniwin/src/miniwin_ddclipper.cpp deleted file mode 100644 index 79dfa882..00000000 --- a/miniwin/miniwin/src/miniwin_ddclipper.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#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 index 7131ac13..96682a0e 100644 --- a/miniwin/miniwin/src/miniwin_ddpalette.cpp +++ b/miniwin/miniwin/src/miniwin_ddpalette.cpp @@ -14,11 +14,6 @@ DirectDrawPaletteImpl::~DirectDrawPaletteImpl() SDL_DestroyPalette(m_palette); } -HRESULT DirectDrawPaletteImpl::GetCaps(LPDWORD lpdwCaps) -{ - return DD_OK; -} - HRESULT DirectDrawPaletteImpl::GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) { for (int i = dwBase; i < dwNumEntries; i++) { diff --git a/miniwin/miniwin/src/miniwin_ddraw.cpp b/miniwin/miniwin/src/miniwin_ddraw.cpp index b0d60e17..e85b35b9 100644 --- a/miniwin/miniwin/src/miniwin_ddraw.cpp +++ b/miniwin/miniwin/src/miniwin_ddraw.cpp @@ -1,6 +1,5 @@ #include "miniwin_d3d.h" -#include "miniwin_ddclipper_p.h" #include "miniwin_ddpalette_p.h" #include "miniwin_ddraw_p.h" #include "miniwin_ddsurface_p.h" @@ -33,7 +32,7 @@ HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject) // IDirectDraw interface HRESULT DirectDrawImpl::CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) { - *lplpDDClipper = static_cast(new DirectDrawClipperImpl(this)); + *lplpDDClipper = new IDirectDrawClipper; return DD_OK; } @@ -272,6 +271,7 @@ HRESULT DirectDrawImpl::SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBP { return DD_OK; } + // IDirect3D2 interface HRESULT DirectDrawImpl::CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) { diff --git a/miniwin/miniwin/src/miniwin_ddsurface.cpp b/miniwin/miniwin/src/miniwin_ddsurface.cpp index 06dae67b..7d0393ff 100644 --- a/miniwin/miniwin/src/miniwin_ddsurface.cpp +++ b/miniwin/miniwin/src/miniwin_ddsurface.cpp @@ -119,21 +119,11 @@ HRESULT DirectDrawSurfaceImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTD 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) { if (!m_palette) { @@ -169,6 +159,7 @@ HRESULT DirectDrawSurfaceImpl::IsLost() { return DD_OK; } + HRESULT DirectDrawSurfaceImpl::Lock( LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, From d1e3a6914149a006af13695bce9bc4313b4f53f9 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 18:36:03 +0200 Subject: [PATCH 14/15] Use SDL_Surface instead of SDL_Texture (#103) --- CMakeLists.txt | 3 +- miniwin/miniwin/include/miniwin_ddraw.h | 2 + .../miniwin/src/include/miniwin_ddpalette_p.h | 1 - miniwin/miniwin/src/include/miniwin_ddraw_p.h | 2 - .../miniwin/src/include/miniwin_ddsurface_p.h | 6 +- miniwin/miniwin/src/include/miniwin_p.h | 9 +- miniwin/miniwin/src/miniwin_ddraw.cpp | 105 ++++++++++--- miniwin/miniwin/src/miniwin_ddsurface.cpp | 147 +++++++++++------- 8 files changed, 184 insertions(+), 91 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b58261b..dab8e65d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,7 +84,6 @@ if (ISLE_UBSAN) add_link_options(-fsanitize=undefined) endif() -#if (NOT WIN32) add_library(miniwin STATIC EXCLUDE_FROM_ALL miniwin/miniwin/src/miniwin.cpp miniwin/miniwin/src/miniwin_ddpalette.cpp @@ -92,6 +91,8 @@ add_library(miniwin STATIC EXCLUDE_FROM_ALL miniwin/miniwin/src/miniwin_ddraw.cpp miniwin/miniwin/src/miniwin_d3drm.cpp ) +# Force reported render mods from MiniWin +target_compile_definitions(miniwin PRIVATE MINIWIN_PIXELFORMAT=SDL_PIXELFORMAT_INDEX8) target_include_directories(miniwin PUBLIC "$") target_include_directories(miniwin PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/miniwin/miniwin/src/include") target_compile_definitions(miniwin PUBLIC "MINIWIN") diff --git a/miniwin/miniwin/include/miniwin_ddraw.h b/miniwin/miniwin/include/miniwin_ddraw.h index 99dfe3f3..15842aca 100644 --- a/miniwin/miniwin/include/miniwin_ddraw.h +++ b/miniwin/miniwin/include/miniwin_ddraw.h @@ -103,6 +103,8 @@ DEFINE_GUID(IID_IDirectDraw2, 0xB3A6F3E0, 0x2B43, 0x11CF, 0xA2, 0xDE, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56); DEFINE_GUID(IID_IDirectDrawSurface3, 0xDA044E00, 0x69B2, 0x11D0, 0xA1, 0xD5, 0x00, 0xAA, 0x00, 0xB8, 0xDF, 0xBB); +extern SDL_Window* DDWindow; + // --- Enums --- #define DDCKEY_SRCBLT DDColorKeyFlags::SRCBLT enum class DDColorKeyFlags : uint32_t { diff --git a/miniwin/miniwin/src/include/miniwin_ddpalette_p.h b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h index 98fe64c8..0d1b3766 100644 --- a/miniwin/miniwin/src/include/miniwin_ddpalette_p.h +++ b/miniwin/miniwin/src/include/miniwin_ddpalette_p.h @@ -8,6 +8,5 @@ struct DirectDrawPaletteImpl : public IDirectDrawPalette { HRESULT GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) override; HRESULT SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) override; -private: SDL_Palette* m_palette; }; diff --git a/miniwin/miniwin/src/include/miniwin_ddraw_p.h b/miniwin/miniwin/src/include/miniwin_ddraw_p.h index 1dba2d71..fca7a0e5 100644 --- a/miniwin/miniwin/src/include/miniwin_ddraw_p.h +++ b/miniwin/miniwin/src/include/miniwin_ddraw_p.h @@ -3,8 +3,6 @@ #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; diff --git a/miniwin/miniwin/src/include/miniwin_ddsurface_p.h b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h index 71be1003..610e17c0 100644 --- a/miniwin/miniwin/src/include/miniwin_ddsurface_p.h +++ b/miniwin/miniwin/src/include/miniwin_ddsurface_p.h @@ -5,7 +5,7 @@ struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { DirectDrawSurfaceImpl(); - DirectDrawSurfaceImpl(int width, int height); + DirectDrawSurfaceImpl(int width, int height, SDL_PixelFormat format); ~DirectDrawSurfaceImpl() override; // IUnknown interface @@ -34,9 +34,11 @@ struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) override; HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override; HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override; + void SetAutoFlip(bool enabled); HRESULT Unlock(LPVOID lpSurfaceData) override; private: - SDL_Texture* m_texture = nullptr; + bool m_autoFlip = false; + SDL_Surface* m_surface = nullptr; IDirectDrawPalette* m_palette = nullptr; }; diff --git a/miniwin/miniwin/src/include/miniwin_p.h b/miniwin/miniwin/src/include/miniwin_p.h index c5fcc201..7c1b6a83 100644 --- a/miniwin/miniwin/src/include/miniwin_p.h +++ b/miniwin/miniwin/src/include/miniwin_p.h @@ -14,12 +14,7 @@ SDL_LogError(LOG_CATEGORY_MINIWIN, "%s:%s", __func__, MSG); \ } while (0) -static SDL_FRect ConvertRect(const RECT* r) +static SDL_Rect 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; + return {r->left, r->top, r->right - r->left, r->bottom - r->top}; } diff --git a/miniwin/miniwin/src/miniwin_ddraw.cpp b/miniwin/miniwin/src/miniwin_ddraw.cpp index e85b35b9..ad23266f 100644 --- a/miniwin/miniwin/src/miniwin_ddraw.cpp +++ b/miniwin/miniwin/src/miniwin_ddraw.cpp @@ -11,7 +11,7 @@ #include #include -SDL_Renderer* renderer; +SDL_Window* DDWindow; HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject) { @@ -58,6 +58,24 @@ HRESULT DirectDrawImpl::CreateSurface( IUnknown* pUnkOuter ) { + SDL_PixelFormat format; +#ifdef MINIWIN_PIXELFORMAT + format = MINIWIN_PIXELFORMAT; +#else + format = SDL_PIXELFORMAT_RGBA8888; +#endif + if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) { + if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) { + switch (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount) { + case 8: + format = SDL_PIXELFORMAT_INDEX8; + break; + case 16: + format = SDL_PIXELFORMAT_RGB565; + break; + } + } + } if ((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) == DDSD_CAPS) { if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER) { if ((lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) != DDSD_ZBUFFERBITDEPTH) { @@ -72,8 +90,11 @@ HRESULT DirectDrawImpl::CreateSurface( SDL_Log("Todo: Switch to %d buffering", lpDDSurfaceDesc->dwBackBufferCount); } int width, height; - SDL_GetRenderOutputSize(renderer, &width, &height); - *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); + SDL_GetWindowSize(DDWindow, &width, &height); + bool implicitFlip = (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_FLIP) != DDSCAPS_FLIP; + auto frontBuffer = new DirectDrawSurfaceImpl(width, height, format); + frontBuffer->SetAutoFlip(implicitFlip); + *lplpDDSurface = static_cast(frontBuffer); return DD_OK; } if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) == DDSCAPS_OFFSCREENPLAIN) { @@ -93,19 +114,16 @@ HRESULT DirectDrawImpl::CreateSurface( } } - 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->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) != (DDSD_WIDTH | DDSD_HEIGHT)) { return DDERR_INVALIDPARAMS; } int width = lpDDSurfaceDesc->dwWidth; int height = lpDDSurfaceDesc->dwHeight; - *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height)); + if (width == 0 || height == 0) { + return DDERR_INVALIDPARAMS; + } + *lplpDDSurface = static_cast(new DirectDrawSurfaceImpl(width, height, format)); return DD_OK; } @@ -127,11 +145,18 @@ HRESULT DirectDrawImpl::EnumDisplayModes( return DDERR_GENERIC; } + SDL_PixelFormat format; HRESULT status = S_OK; for (int i = 0; i < count_modes; i++) { - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(modes[i]->format); - if (!format) { +#ifdef MINIWIN_PIXELFORMAT + format = MINIWIN_PIXELFORMAT; +#else + format = modes[i]->format; +#endif + + const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(format); + if (!details) { continue; } DDSURFACEDESC ddsd = {}; @@ -141,11 +166,13 @@ HRESULT DirectDrawImpl::EnumDisplayModes( ddsd.dwHeight = modes[i]->h; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; - ddsd.ddpfPixelFormat.dwRGBBitCount = - (format->bits_per_pixel == 8) ? 8 : 16; // Game only accepts 8 or 16 bit mode - ddsd.ddpfPixelFormat.dwRBitMask = format->Rmask; - ddsd.ddpfPixelFormat.dwGBitMask = format->Gmask; - ddsd.ddpfPixelFormat.dwBBitMask = format->Bmask; + ddsd.ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel; + if (details->bits_per_pixel == 8) { + ddsd.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; + } + ddsd.ddpfPixelFormat.dwRBitMask = details->Rmask; + ddsd.ddpfPixelFormat.dwGBitMask = details->Gmask; + ddsd.ddpfPixelFormat.dwBBitMask = details->Bmask; if (!lpEnumModesCallback(&ddsd, lpContext)) { status = DDERR_GENERIC; @@ -185,6 +212,26 @@ HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) return DDERR_GENERIC; } + DDBitDepths renderBitDepth = DDBD_32; + +#ifdef MINIWIN_PIXELFORMAT + SDL_PixelFormat format = MINIWIN_PIXELFORMAT; + const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(format); + switch (details->bits_per_pixel) { + case 8: + renderBitDepth = DDBD_8; + break; + case 16: + renderBitDepth = DDBD_16; + break; + case 24: + renderBitDepth = DDBD_24; + break; + default: + break; + } +#endif + const char* deviceDesc = "SDL3 SDL_Renderer"; for (int i = 0; i < numDrivers; ++i) { @@ -199,7 +246,7 @@ HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) 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.dwDeviceRenderBitDepth = renderBitDepth; halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE; halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND; halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR; @@ -226,16 +273,26 @@ HRESULT DirectDrawImpl::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) return DDERR_GENERIC; } - const SDL_PixelFormatDetails* format = SDL_GetPixelFormatDetails(mode->format); + SDL_PixelFormat format; +#ifdef MINIWIN_PIXELFORMAT + format = MINIWIN_PIXELFORMAT; +#else + format = mode->format; +#endif + + const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(format); lpDDSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT; lpDDSurfaceDesc->dwWidth = mode->w; lpDDSurfaceDesc->dwHeight = mode->h; + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel; 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; + if (details->bits_per_pixel == 8) { + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; + } + lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = details->Rmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = details->Gmask; + lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = details->Bmask; return DD_OK; } @@ -262,7 +319,7 @@ HRESULT DirectDrawImpl::SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) if (!SDL_SetWindowFullscreen(hWnd, fullscreen)) { return DDERR_GENERIC; } - renderer = SDL_CreateRenderer(hWnd, NULL); + DDWindow = hWnd; } return DD_OK; } diff --git a/miniwin/miniwin/src/miniwin_ddsurface.cpp b/miniwin/miniwin/src/miniwin_ddsurface.cpp index 7d0393ff..b2a9961f 100644 --- a/miniwin/miniwin/src/miniwin_ddsurface.cpp +++ b/miniwin/miniwin/src/miniwin_ddsurface.cpp @@ -1,3 +1,4 @@ +#include "miniwin_ddpalette_p.h" #include "miniwin_ddraw_p.h" #include "miniwin_ddsurface_p.h" #include "miniwin_p.h" @@ -8,18 +9,18 @@ DirectDrawSurfaceImpl::DirectDrawSurfaceImpl() { } -DirectDrawSurfaceImpl::DirectDrawSurfaceImpl(int width, int height) +DirectDrawSurfaceImpl::DirectDrawSurfaceImpl(int width, int height, SDL_PixelFormat format) { - 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()); + m_surface = SDL_CreateSurface(width, height, format); + if (!m_surface) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create surface: %s", SDL_GetError()); } } DirectDrawSurfaceImpl::~DirectDrawSurfaceImpl() { - if (m_texture) { - SDL_DestroyTexture(m_texture); + if (m_surface) { + SDL_DestroySurface(m_surface); } if (m_palette) { m_palette->Release(); @@ -43,6 +44,12 @@ HRESULT DirectDrawSurfaceImpl::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttac { return DD_OK; } + +void DirectDrawSurfaceImpl::SetAutoFlip(bool enabled) +{ + m_autoFlip = enabled; +} + HRESULT DirectDrawSurfaceImpl::Blt( LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, @@ -51,25 +58,46 @@ HRESULT DirectDrawSurfaceImpl::Blt( LPDDBLTFX lpDDBltFx ) { - if (!renderer) { + auto srcSurface = static_cast(lpDDSrcSurface); + if (!srcSurface || !srcSurface->m_surface) { return DDERR_GENERIC; } - auto srcSurface = static_cast(lpDDSrcSurface); - SDL_FRect srcRect, dstRect; + + SDL_Rect srcRect; if (lpSrcRect) { srcRect = ConvertRect(lpSrcRect); } else { - srcRect = {0, 0, (float) srcSurface->m_texture->w, (float) srcSurface->m_texture->h}; + srcRect = {0, 0, srcSurface->m_surface->w, srcSurface->m_surface->h}; } + + SDL_Rect dstRect; if (lpDestRect) { dstRect = ConvertRect(lpDestRect); } else { - dstRect = {0, 0, (float) m_texture->w, (float) m_texture->h}; + dstRect = {0, 0, m_surface->w, m_surface->h}; + } + + SDL_Surface* blitSource = srcSurface->m_surface; + + if (srcSurface->m_surface->format != m_surface->format) { + blitSource = SDL_ConvertSurface(srcSurface->m_surface, m_surface->format); + if (!blitSource) { + return DDERR_GENERIC; + } + } + + if (!SDL_BlitSurfaceScaled(blitSource, &srcRect, m_surface, &dstRect, SDL_SCALEMODE_NEAREST)) { + return DDERR_GENERIC; + } + + if (blitSource != srcSurface->m_surface) { + SDL_DestroySurface(blitSource); + } + if (m_autoFlip) { + return Flip(nullptr, DDFLIP_WAIT); } - SDL_RenderTexture(renderer, srcSurface->m_texture, &srcRect, &dstRect); - SDL_RenderPresent(renderer); return DD_OK; } @@ -81,32 +109,29 @@ HRESULT DirectDrawSurfaceImpl::BltFast( DDBltFastFlags dwTrans ) { - if (!renderer) { - return DDERR_GENERIC; - } - auto srcSurface = static_cast(lpDDSrcSurface); - SDL_FRect srcRect; - if (lpSrcRect) { - srcRect = ConvertRect(lpSrcRect); - } - else { - srcRect = {0, 0, (float) srcSurface->m_texture->w, (float) srcSurface->m_texture->h}; - } - SDL_FRect dstRect = {(float) dwX, (float) dwY, srcRect.w, srcRect.h}; - SDL_RenderTexture(renderer, srcSurface->m_texture, &srcRect, &dstRect); - SDL_RenderPresent(renderer); - return DD_OK; + RECT destRect = { + (int) dwX, + (int) dwY, + (int) (lpSrcRect->right - lpSrcRect->left + dwX), + (int) (lpSrcRect->bottom - lpSrcRect->top + dwY) + }; + return Blt(&destRect, lpDDSrcSurface, lpSrcRect, DDBLT_NONE, nullptr); } HRESULT DirectDrawSurfaceImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) { - if (!renderer || !m_texture) { + if (!m_surface) { return DDERR_GENERIC; } - float width, height; - SDL_FRect rect{0, 0, (float) m_texture->w, (float) m_texture->h}; - SDL_RenderTexture(renderer, m_texture, &rect, &rect); - SDL_RenderPresent(renderer); + SDL_Surface* windowSurface = SDL_GetWindowSurface(DDWindow); + if (!windowSurface) { + return DDERR_GENERIC; + } + SDL_Rect srcRect{0, 0, m_surface->w, m_surface->h}; + SDL_Surface* copy = SDL_ConvertSurface(m_surface, windowSurface->format); + SDL_BlitSurface(copy, &srcRect, windowSurface, &srcRect); + SDL_DestroySurface(copy); + SDL_UpdateWindowSurface(DDWindow); return DD_OK; } @@ -136,22 +161,34 @@ HRESULT DirectDrawSurfaceImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) HRESULT DirectDrawSurfaceImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) { + if (!m_surface) { + return DDERR_GENERIC; + } memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat)); lpDDPixelFormat->dwFlags = DDPF_RGB; + const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(m_surface->format); + if (details->bits_per_pixel == 8) { + lpDDPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8; + } + lpDDPixelFormat->dwRGBBitCount = details->bits_per_pixel; + lpDDPixelFormat->dwRBitMask = details->Rmask; + lpDDPixelFormat->dwGBitMask = details->Gmask; + lpDDPixelFormat->dwBBitMask = details->Bmask; return DD_OK; } HRESULT DirectDrawSurfaceImpl::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) { - if (!m_texture) { + if (!m_surface) { return DDERR_GENERIC; } - 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; - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; + lpDDSurfaceDesc->dwFlags = DDSD_PIXELFORMAT; + GetPixelFormat(&lpDDSurfaceDesc->ddpfPixelFormat); + if (m_surface) { + lpDDSurfaceDesc->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT; + lpDDSurfaceDesc->dwWidth = m_surface->w; + lpDDSurfaceDesc->dwHeight = m_surface->h; + } return DD_OK; } @@ -167,24 +204,17 @@ HRESULT DirectDrawSurfaceImpl::Lock( HANDLE hEvent ) { - if (!m_texture) { + if (!m_surface) { return DDERR_GENERIC; } - int pitch = 0; - void* pixels = nullptr; - if (SDL_LockTexture(m_texture, (SDL_Rect*) lpDestRect, &pixels, &pitch) < 0) { + if (SDL_LockSurface(m_surface) < 0) { return DDERR_GENERIC; } - lpDDSurfaceDesc->lpSurface = pixels; - lpDDSurfaceDesc->lPitch = pitch; - 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; - lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = format->Gmask; - lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = format->Bmask; + GetSurfaceDesc(lpDDSurfaceDesc); + lpDDSurfaceDesc->lpSurface = m_surface->pixels; + lpDDSurfaceDesc->lPitch = m_surface->pitch; return DD_OK; } @@ -211,16 +241,25 @@ HRESULT DirectDrawSurfaceImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY HRESULT DirectDrawSurfaceImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) { + if (m_surface->format != SDL_PIXELFORMAT_INDEX8) { + return DDERR_GENERIC; + } + + if (m_palette) { + m_palette->Release(); + } + m_palette = lpDDPalette; + SDL_SetSurfacePalette(m_surface, ((DirectDrawPaletteImpl*) m_palette)->m_palette); m_palette->AddRef(); return DD_OK; } HRESULT DirectDrawSurfaceImpl::Unlock(LPVOID lpSurfaceData) { - if (!m_texture) { + if (!m_surface) { return DDERR_GENERIC; } - SDL_UnlockTexture(m_texture); + SDL_UnlockSurface(m_surface); return DD_OK; } From 77cb46f91d643301f3a981d835f33fe313b612aa Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 18 May 2025 19:45:09 +0200 Subject: [PATCH 15/15] Add support for 8bit color key (#110) --- miniwin/miniwin/src/miniwin_ddsurface.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/miniwin/miniwin/src/miniwin_ddsurface.cpp b/miniwin/miniwin/src/miniwin_ddsurface.cpp index b2a9961f..854d3cb9 100644 --- a/miniwin/miniwin/src/miniwin_ddsurface.cpp +++ b/miniwin/miniwin/src/miniwin_ddsurface.cpp @@ -236,6 +236,17 @@ HRESULT DirectDrawSurfaceImpl::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) HRESULT DirectDrawSurfaceImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) { + if (!lpDDColorKey) { + return DDERR_INVALIDPARAMS; + } + if (m_surface->format != SDL_PIXELFORMAT_INDEX8) { + return DDERR_GENERIC; // Not currently supported + } + + if (SDL_SetSurfaceColorKey(m_surface, true, lpDDColorKey->dwColorSpaceLowValue) != 0) { + return DDERR_GENERIC; + } + return DD_OK; }