Implement a functional DirectDraw (#81)

This commit is contained in:
Anders Jenbo 2025-05-16 05:45:53 +02:00 committed by GitHub
parent ab83cd51c1
commit 9ae96cbff6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 300 additions and 128 deletions

View File

@ -13,12 +13,12 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
toolchain: toolchain:
- { name: 'MSVC (32-bit, Release)', shell: 'sh', setup-cmake: true, setup-ninja: true, setup-msvc: true, vc-arch: 'amd64_x86', dx5-libs: true, d3drm-wrapper: false, build-type: 'Release' } - { 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, d3drm-wrapper: false, build-type: 'Debug' } - { 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, d3drm-wrapper: 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, d3drm-wrapper: true, 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, d3drm-wrapper: 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, d3drm-wrapper: 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 } # - { 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: steps:
@ -63,7 +63,6 @@ jobs:
cmake -S . -B build -GNinja \ cmake -S . -B build -GNinja \
-DCMAKE_BUILD_TYPE=${{ matrix.toolchain.build-type }} \ -DCMAKE_BUILD_TYPE=${{ matrix.toolchain.build-type }} \
-DISLE_USE_DX5=${{ matrix.toolchain.dx5-libs }} \ -DISLE_USE_DX5=${{ matrix.toolchain.dx5-libs }} \
-DISLE_D3DRM_WRAPPER=${{ matrix.toolchain.d3drm-wrapper }} \
-DENABLE_CLANG_TIDY=${{ !!matrix.toolchain.clang-tidy }} \ -DENABLE_CLANG_TIDY=${{ !!matrix.toolchain.clang-tidy }} \
-DISLE_WERROR=${{ !!matrix.toolchain.werror }} \ -DISLE_WERROR=${{ !!matrix.toolchain.werror }} \
-Werror=dev -Werror=dev

View File

@ -73,6 +73,8 @@ MxS32 g_reqEnableRMDevice = FALSE;
// STRING: ISLE 0x4101dc // STRING: ISLE 0x4101dc
#define WINDOW_TITLE "LEGO®" #define WINDOW_TITLE "LEGO®"
SDL_Window* window;
// FUNCTION: ISLE 0x401000 // FUNCTION: ISLE 0x401000
IsleApp::IsleApp() IsleApp::IsleApp()
{ {
@ -260,7 +262,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
SDL_MESSAGEBOX_ERROR, SDL_MESSAGEBOX_ERROR,
"LEGO® Island Error", "LEGO® Island Error",
"\"LEGO® Island\" failed to start. Invalid CLI arguments.", "\"LEGO® Island\" failed to start. Invalid CLI arguments.",
g_isle->GetWindowHandle() window
); );
return SDL_APP_FAILURE; return SDL_APP_FAILURE;
} }
@ -271,7 +273,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
SDL_MESSAGEBOX_ERROR, SDL_MESSAGEBOX_ERROR,
"LEGO® Island Error", "LEGO® Island Error",
"\"LEGO® Island\" failed to start.\nPlease quit all other applications and try again.", "\"LEGO® Island\" failed to start.\nPlease quit all other applications and try again.",
g_isle->GetWindowHandle() window
); );
return SDL_APP_FAILURE; return SDL_APP_FAILURE;
} }
@ -479,7 +481,13 @@ MxResult IsleApp::SetupWindow()
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, m_fullScreen); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, m_fullScreen);
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, WINDOW_TITLE); SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, WINDOW_TITLE);
m_windowHandle = SDL_CreateWindowWithProperties(props); window = SDL_CreateWindowWithProperties(props);
#ifndef MINIWIN
m_windowHandle =
(HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
#else
m_windowHandle = window;
#endif
SDL_DestroyProperties(props); SDL_DestroyProperties(props);
@ -493,7 +501,7 @@ MxResult IsleApp::SetupWindow()
SDL_Surface* icon = SDL_LoadBMP_IO(icon_stream, true); SDL_Surface* icon = SDL_LoadBMP_IO(icon_stream, true);
if (icon) { if (icon) {
SDL_SetWindowIcon(m_windowHandle, icon); SDL_SetWindowIcon(window, icon);
SDL_DestroySurface(icon); SDL_DestroySurface(icon);
} }
else { else {

View File

@ -42,7 +42,7 @@ class IsleApp {
static MxU8 MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags); static MxU8 MapMouseButtonFlagsToModifier(SDL_MouseButtonFlags p_flags);
SDL_Window* GetWindowHandle() { return m_windowHandle; } HWND GetWindowHandle() { return m_windowHandle; }
MxLong GetFrameDelta() { return m_frameDelta; } MxLong GetFrameDelta() { return m_frameDelta; }
MxS32 GetFullScreen() { return m_fullScreen; } MxS32 GetFullScreen() { return m_fullScreen; }
SDL_Cursor* GetCursorCurrent() { return m_cursorCurrent; } SDL_Cursor* GetCursorCurrent() { return m_cursorCurrent; }
@ -76,7 +76,7 @@ class IsleApp {
MxLong m_frameDelta; // 0x48 MxLong m_frameDelta; // 0x48
MxVideoParam m_videoParam; // 0x4c MxVideoParam m_videoParam; // 0x4c
MxS32 m_windowActive; // 0x70 MxS32 m_windowActive; // 0x70
SDL_Window* m_windowHandle; // 0x74 HWND m_windowHandle; // 0x74
MxS32 m_drawCursor; // 0x78 MxS32 m_drawCursor; // 0x78
SDL_Cursor* m_cursorArrow; // 0x7c SDL_Cursor* m_cursorArrow; // 0x7c
SDL_Cursor* m_cursorBusy; // 0x80 SDL_Cursor* m_cursorBusy; // 0x80

View File

@ -197,13 +197,7 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
goto done; goto done;
} }
// [library:dinput] if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(p_param.GetWindowHandle()) != SUCCESS) {
hWnd = (HWND) SDL_GetPointerProperty(
SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()),
SDL_PROP_WINDOW_WIN32_HWND_POINTER,
NULL
);
if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(hWnd) != SUCCESS) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoInputManager"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create LegoInputManager");
delete m_inputManager; delete m_inputManager;
m_inputManager = NULL; m_inputManager = NULL;

View File

@ -86,12 +86,7 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM
Mx3DPointFloat dirVec(0.0, 0.0, 1.0); Mx3DPointFloat dirVec(0.0, 0.0, 1.0);
Mx3DPointFloat upVec(0.0, 1.0, 0.0); Mx3DPointFloat upVec(0.0, 1.0, 0.0);
MxMatrix outMatrix; MxMatrix outMatrix;
// [library:ddraw] [library:d3d] HWND hwnd = MxOmni::GetInstance()->GetWindowHandle();
HWND hwnd = (HWND) SDL_GetPointerProperty(
SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()),
SDL_PROP_WINDOW_WIN32_HWND_POINTER,
NULL
);
MxS32 bits = p_videoParam.Flags().Get16Bit() ? 16 : 8; MxS32 bits = p_videoParam.Flags().Get16Bit() ? 16 : 8;
if (!p_videoParam.GetPalette()) { if (!p_videoParam.GetPalette()) {
@ -189,11 +184,7 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM
Lego3DManager::CreateStruct createStruct; Lego3DManager::CreateStruct createStruct;
memset(&createStruct, 0, sizeof(createStruct)); memset(&createStruct, 0, sizeof(createStruct));
createStruct.m_hWnd = (HWND) SDL_GetPointerProperty( createStruct.m_hWnd = LegoOmni::GetInstance()->GetWindowHandle();
SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()),
SDL_PROP_WINDOW_WIN32_HWND_POINTER,
NULL
);
createStruct.m_pDirectDraw = m_pDirectDraw; createStruct.m_pDirectDraw = m_pDirectDraw;
createStruct.m_pFrontBuffer = m_displaySurface->GetDirectDrawSurface1(); createStruct.m_pFrontBuffer = m_displaySurface->GetDirectDrawSurface1();
createStruct.m_pBackBuffer = m_displaySurface->GetDirectDrawSurface2(); createStruct.m_pBackBuffer = m_displaySurface->GetDirectDrawSurface2();

View File

@ -66,7 +66,7 @@ class MxOmni : public MxCore {
static void SetInstance(MxOmni* p_instance); static void SetInstance(MxOmni* p_instance);
static MxBool ActionSourceEquals(MxDSAction* p_action, const char* p_name); static MxBool ActionSourceEquals(MxDSAction* p_action, const char* p_name);
SDL_Window* GetWindowHandle() const { return m_windowHandle; } HWND GetWindowHandle() const { return m_windowHandle; }
// FUNCTION: BETA10 0x10125100 // FUNCTION: BETA10 0x10125100
MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; }
@ -107,7 +107,7 @@ class MxOmni : public MxCore {
static MxOmni* g_instance; static MxOmni* g_instance;
MxString m_mediaPath; // 0x08 MxString m_mediaPath; // 0x08
SDL_Window* m_windowHandle; // 0x18 HWND m_windowHandle; // 0x18
MxObjectFactory* m_objectFactory; // 0x1c MxObjectFactory* m_objectFactory; // 0x1c
MxVariableTable* m_variableTable; // 0x20 MxVariableTable* m_variableTable; // 0x20
MxTickleManager* m_tickleManager; // 0x24 MxTickleManager* m_tickleManager; // 0x24

View File

@ -15,7 +15,7 @@ class MxOmniCreateParam : public MxParam {
public: public:
LEGO1_EXPORT MxOmniCreateParam( LEGO1_EXPORT MxOmniCreateParam(
const char* p_mediaPath, const char* p_mediaPath,
SDL_Window* p_windowHandle, HWND p_windowHandle,
MxVideoParam& p_vparam, MxVideoParam& p_vparam,
MxOmniCreateFlags p_flags MxOmniCreateFlags p_flags
); );
@ -24,7 +24,7 @@ class MxOmniCreateParam : public MxParam {
MxOmniCreateFlags& CreateFlags() { return this->m_createFlags; } MxOmniCreateFlags& CreateFlags() { return this->m_createFlags; }
const MxString& GetMediaPath() const { return m_mediaPath; } const MxString& GetMediaPath() const { return m_mediaPath; }
SDL_Window* GetWindowHandle() const { return m_windowHandle; } HWND GetWindowHandle() const { return m_windowHandle; }
MxVideoParam& GetVideoParam() { return m_videoParam; } MxVideoParam& GetVideoParam() { return m_videoParam; }
const MxVideoParam& GetVideoParam() const { return m_videoParam; } const MxVideoParam& GetVideoParam() const { return m_videoParam; }
@ -34,7 +34,7 @@ class MxOmniCreateParam : public MxParam {
private: private:
MxString m_mediaPath; // 0x04 MxString m_mediaPath; // 0x04
SDL_Window* m_windowHandle; // 0x14 HWND m_windowHandle; // 0x14
MxVideoParam m_videoParam; // 0x18 MxVideoParam m_videoParam; // 0x18
MxOmniCreateFlags m_createFlags; // 0x3c MxOmniCreateFlags m_createFlags; // 0x3c
}; };

View File

@ -8,7 +8,7 @@ DECOMP_SIZE_ASSERT(MxOmniCreateParam, 0x40)
// FUNCTION: BETA10 0x10130b6b // FUNCTION: BETA10 0x10130b6b
MxOmniCreateParam::MxOmniCreateParam( MxOmniCreateParam::MxOmniCreateParam(
const char* p_mediaPath, const char* p_mediaPath,
SDL_Window* p_windowHandle, HWND p_windowHandle,
MxVideoParam& p_vparam, MxVideoParam& p_vparam,
MxOmniCreateFlags p_flags MxOmniCreateFlags p_flags
) )

View File

@ -147,15 +147,7 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
DDSURFACEDESC ddsd; DDSURFACEDESC ddsd;
MxResult result = FAILURE; MxResult result = FAILURE;
LPDIRECTDRAW lpDirectDraw = MVideoManager()->GetDirectDraw(); LPDIRECTDRAW lpDirectDraw = MVideoManager()->GetDirectDraw();
SDL_Window* window = MxOmni::GetInstance()->GetWindowHandle(); HWND hWnd = MxOmni::GetInstance()->GetWindowHandle();
// [library:ddraw]
HWND hWnd =
(HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
if (!hWnd) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDisplaySurface::Create: HWND is NULL");
goto done;
}
m_initialized = TRUE; m_initialized = TRUE;
m_videoParam = p_videoParam; m_videoParam = p_videoParam;
@ -876,13 +868,7 @@ void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p
} }
else { else {
MxPoint32 point(0, 0); MxPoint32 point(0, 0);
// [library:ddraw] ClientToScreen(MxOmni::GetInstance()->GetWindowHandle(), (LPPOINT) &point);
HWND hWnd = (HWND) SDL_GetPointerProperty(
SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()),
SDL_PROP_WINDOW_WIN32_HWND_POINTER,
NULL
);
ClientToScreen(hWnd, (LPPOINT) &point);
p_left2 += m_videoParam.GetRect().GetLeft() + point.GetX(); p_left2 += m_videoParam.GetRect().GetLeft() + point.GetX();
p_top2 += m_videoParam.GetRect().GetTop() + point.GetY(); p_top2 += m_videoParam.GetRect().GetTop() + point.GetY();

View File

@ -245,13 +245,7 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS,
goto done; goto done;
} }
// [library:ddraw] if (m_pDirectDraw->SetCooperativeLevel(MxOmni::GetInstance()->GetWindowHandle(), DDSCL_NORMAL) != DD_OK) {
hWnd = (HWND) SDL_GetPointerProperty(
SDL_GetWindowProperties(MxOmni::GetInstance()->GetWindowHandle()),
SDL_PROP_WINDOW_WIN32_HWND_POINTER,
NULL
);
if (m_pDirectDraw->SetCooperativeLevel(hWnd, DDSCL_NORMAL) != DD_OK) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "IDirectDraw::SetCooperativeLevel failed"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "IDirectDraw::SetCooperativeLevel failed");
goto done; goto done;
} }

View File

@ -82,23 +82,17 @@ struct OSVERSIONINFOA {
typedef struct IUnknown* LPUNKNOWN; typedef struct IUnknown* LPUNKNOWN;
struct CWnd { struct CWnd {
void* m_hWnd; HWND m_hWnd;
void EnableWindow(bool bEnable) {} void EnableWindow(bool bEnable) {}
void SetWindowText(const char* text) {} void SetWindowText(const char* text) {}
}; };
struct CPaintDC {
void* m_hDC;
CPaintDC(HWND hWnd) {}
void Draw() {}
};
struct CDataExchange { struct CDataExchange {
bool m_bSaveAndValidate; bool m_bSaveAndValidate;
}; };
struct CDialog { struct CDialog {
void* m_hWnd; HWND m_hWnd;
int m_nIDTemplate; int m_nIDTemplate;
CWnd* m_pParentWnd; CWnd* m_pParentWnd;
CDialog() : m_nIDTemplate(0), m_pParentWnd(nullptr) {} CDialog() : m_nIDTemplate(0), m_pParentWnd(nullptr) {}
@ -113,6 +107,12 @@ struct CDialog {
virtual void DoDataExchange(CDataExchange* pDX) {} virtual void DoDataExchange(CDataExchange* pDX) {}
}; };
struct CPaintDC {
void* m_hDC;
CPaintDC(CDialog* hWnd) {}
void Draw() {}
};
struct CMenu { struct CMenu {
void* m_hMenu; void* m_hMenu;
CMenu() : m_hMenu(nullptr) {} CMenu() : m_hMenu(nullptr) {}
@ -166,7 +166,7 @@ inline BOOL ShowWindow(HWND hWnd, int nCmdShow)
return TRUE; return TRUE;
} }
inline BOOL SetWindowPos(HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) inline BOOL SetWindowPos(CWinApp** hWnd, int X, int Y, int cx, int cy, UINT uFlags)
{ {
return TRUE; return TRUE;
} }

View File

@ -90,26 +90,13 @@ void AfxMessageBox(const char* message)
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, NULL); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, NULL);
} }
static std::vector<std::pair<SDL_Window*, HWND>> sdl_hwnd_mapping;
SDL_Window* miniwin_GetSdlWindow(HWND hWnd)
{
for (size_t i = 0; i < sdl_hwnd_mapping.size(); i++) {
if (sdl_hwnd_mapping[i].second == hWnd) {
return sdl_hwnd_mapping[i].first;
}
}
return NULL;
}
BOOL GetWindowRect(HWND hWnd, RECT* Rect) BOOL GetWindowRect(HWND hWnd, RECT* Rect)
{ {
int x, y, w, h; int x, y, w, h;
if (!Rect) { if (!Rect) {
return FALSE; return FALSE;
} }
SDL_Window* window = miniwin_GetSdlWindow(hWnd); if (hWnd == NULL) {
if (window == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unregistered HWND %p", hWnd); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unregistered HWND %p", hWnd);
Rect->left = 0; Rect->left = 0;
Rect->top = 0; Rect->top = 0;
@ -117,8 +104,8 @@ BOOL GetWindowRect(HWND hWnd, RECT* Rect)
Rect->bottom = 480; Rect->bottom = 480;
return FALSE; return FALSE;
} }
SDL_GetWindowPosition(window, &x, &y); SDL_GetWindowPosition(hWnd, &x, &y);
SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSize(hWnd, &w, &h);
Rect->right = x; Rect->right = x;
Rect->top = y; Rect->top = y;

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <SDL3/SDL_video.h>
#include <limits.h> #include <limits.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -70,9 +71,10 @@ typedef void* LPVOID;
typedef char* LPSTR; typedef char* LPSTR;
typedef const char* LPCSTR; typedef const char* LPCSTR;
typedef void* HANDLE; typedef void* HANDLE;
typedef HANDLE HMENU, HICON, HFONT; typedef HANDLE HICON, HFONT;
typedef struct HINSTANCE__* HINSTANCE; typedef struct HINSTANCE__* HINSTANCE;
typedef HANDLE HWND, HMODULE, HDC, HPALETTE, HFILE, HCURSOR; typedef SDL_Window *HMENU, *HWND;
typedef HANDLE HMODULE, HDC, HPALETTE, HFILE, HCURSOR;
typedef LONG LSTATUS, HKEY, REGSAM; typedef LONG LSTATUS, HKEY, REGSAM;
// --- Structs --- // --- Structs ---

View File

@ -294,7 +294,6 @@ typedef struct IDirectDraw* LPDIRECTDRAW;
struct IDirectDrawPalette : virtual public IUnknown { struct IDirectDrawPalette : virtual public IUnknown {
virtual HRESULT GetCaps(LPDWORD lpdwCaps) = 0; virtual HRESULT GetCaps(LPDWORD lpdwCaps) = 0;
virtual HRESULT GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) = 0; virtual HRESULT GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) = 0;
virtual HRESULT Initialize(LPDIRECTDRAW lpDD, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable) = 0;
virtual HRESULT SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) = 0; virtual HRESULT SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) = 0;
}; };
typedef struct IDirectDrawPalette* LPDIRECTDRAWPALETTE; typedef struct IDirectDrawPalette* LPDIRECTDRAWPALETTE;
@ -322,7 +321,6 @@ struct IDirectDrawSurface : virtual public IUnknown {
LPRECT lpSrcRect, LPRECT lpSrcRect,
DDBltFastFlags dwTrans DDBltFastFlags dwTrans
) = 0; ) = 0;
virtual HRESULT DeleteAttachedSurface(DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface) = 0;
virtual HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) = 0; virtual HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) = 0;
virtual HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) = 0; virtual HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) = 0;
virtual HRESULT GetCaps(LPDDSCAPS lpDDSCaps) = 0; virtual HRESULT GetCaps(LPDDSCAPS lpDDSCaps) = 0;
@ -331,7 +329,6 @@ struct IDirectDrawSurface : virtual public IUnknown {
virtual HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) = 0; virtual HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) = 0;
virtual HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) = 0; virtual HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) = 0;
virtual HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) = 0; virtual HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) = 0;
virtual HRESULT Initialize(LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) = 0;
virtual HRESULT IsLost() = 0; virtual HRESULT IsLost() = 0;
virtual HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) = 0; virtual HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) = 0;
virtual HRESULT ReleaseDC(HDC hDC) = 0; virtual HRESULT ReleaseDC(HDC hDC) = 0;
@ -365,16 +362,9 @@ struct IDirectDraw : virtual public IUnknown {
LPVOID lpContext, LPVOID lpContext,
LPDDENUMMODESCALLBACK lpEnumModesCallback LPDDENUMMODESCALLBACK lpEnumModesCallback
) = 0; ) = 0;
virtual HRESULT EnumSurfaces(
DWORD dwFlags,
LPDDSURFACEDESC lpDDSD,
LPVOID lpContext,
LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback
) = 0;
virtual HRESULT FlipToGDISurface() = 0; virtual HRESULT FlipToGDISurface() = 0;
virtual HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) = 0; virtual HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) = 0;
virtual HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) = 0; virtual HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) = 0;
virtual HRESULT Initialize(GUID* lpGUID) = 0;
virtual HRESULT RestoreDisplayMode() = 0; virtual HRESULT RestoreDisplayMode() = 0;
virtual HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) = 0; virtual HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) = 0;
virtual HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) = 0; virtual HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) = 0;

View File

@ -19,12 +19,20 @@ struct Direct3DRMDevice2Impl : public IDirect3DRMDevice2 {
HRESULT SetRenderMode(D3DRMRENDERMODE mode) override { return DD_OK; } HRESULT SetRenderMode(D3DRMRENDERMODE mode) override { return DD_OK; }
D3DRMRENDERMODE GetRenderMode() override { return D3DRMRENDERMODE::BLENDEDTRANSPARENCY; } D3DRMRENDERMODE GetRenderMode() override { return D3DRMRENDERMODE::BLENDEDTRANSPARENCY; }
HRESULT Update() override { return DD_OK; } HRESULT Update() override { return DD_OK; }
HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) override { return DD_OK; } HRESULT GetViewports(IDirect3DRMViewportArray** ppViewportArray) override
{
assert(false && "unimplemented");
return DDERR_GENERIC;
}
}; };
struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 { struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 {
HRESULT SetAppData(LPD3DRM_APPDATA appData) override { return DD_OK; } HRESULT SetAppData(LPD3DRM_APPDATA appData) override
LPVOID GetAppData() override { return 0; } {
m_data = appData;
return DD_OK;
}
LPVOID GetAppData() override { return m_data; }
HRESULT AddChild(IDirect3DRMFrame* child) override HRESULT AddChild(IDirect3DRMFrame* child) override
{ {
child->AddRef(); child->AddRef();
@ -41,7 +49,11 @@ struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 {
light->AddRef(); light->AddRef();
return DD_OK; return DD_OK;
} }
HRESULT GetLights(IDirect3DRMLightArray** lightArray) override { return DD_OK; } HRESULT GetLights(IDirect3DRMLightArray** lightArray) override
{
assert(false && "unimplemented");
return DDERR_GENERIC;
}
HRESULT AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix) override { return DD_OK; } HRESULT AddTransform(D3DRMCOMBINETYPE combine, D3DRMMATRIX4D matrix) override { return DD_OK; }
HRESULT GetPosition(int index, D3DVECTOR* position) override { return DD_OK; } HRESULT GetPosition(int index, D3DVECTOR* position) override { return DD_OK; }
HRESULT AddVisual(IDirect3DRMVisual* visual) override HRESULT AddVisual(IDirect3DRMVisual* visual) override
@ -74,19 +86,38 @@ struct Direct3DRMFrameImpl : public IDirect3DRMFrame2 {
visual->Release(); visual->Release();
return DD_OK; return DD_OK;
} }
HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) override { return DD_OK; } HRESULT GetVisuals(IDirect3DRMVisualArray** visuals) override
{
assert(false && "unimplemented");
return DDERR_GENERIC;
}
HRESULT SetTexture(const IDirect3DRMTexture* texture) override { return DD_OK; } HRESULT SetTexture(const IDirect3DRMTexture* texture) override { return DD_OK; }
HRESULT GetTexture(IDirect3DRMTexture** texture) override { return DD_OK; } HRESULT GetTexture(IDirect3DRMTexture** texture) override
{
assert(false && "unimplemented");
return DDERR_GENERIC;
}
HRESULT SetColor(float r, float g, float b, float a) override { return DD_OK; } HRESULT SetColor(float r, float g, float b, float a) override { return DD_OK; }
HRESULT SetColor(D3DCOLOR) override { return DD_OK; } HRESULT SetColor(D3DCOLOR) override { return DD_OK; }
HRESULT SetColorRGB(float r, float g, float b) override { return DD_OK; } HRESULT SetColorRGB(float r, float g, float b) override { return DD_OK; }
HRESULT SetMaterialMode(D3DRMMATERIALMODE mode) override { return DD_OK; } HRESULT SetMaterialMode(D3DRMMATERIALMODE mode) override { return DD_OK; }
HRESULT GetChildren(IDirect3DRMFrameArray** children) override { return DD_OK; } HRESULT GetChildren(IDirect3DRMFrameArray** children) override
{
assert(false && "unimplemented");
return DDERR_GENERIC;
}
private:
LPD3DRM_APPDATA m_data;
}; };
struct Direct3DRMViewportImpl : public IDirect3DRMViewport { struct Direct3DRMViewportImpl : public IDirect3DRMViewport {
Direct3DRMViewportImpl() : m_data(nullptr) {} Direct3DRMViewportImpl() : m_data(nullptr) {}
HRESULT Clone(void** ppObject) override { return DD_OK; } HRESULT Clone(void** ppObject) override
{
assert(false && "unimplemented");
return DDERR_GENERIC;
}
HRESULT AddDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) override { return DD_OK; } 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 DeleteDestroyCallback(void (*cb)(IDirect3DRMObject*, void*), void* arg) override { return DD_OK; }
HRESULT SetAppData(LPD3DRM_APPDATA appData) override HRESULT SetAppData(LPD3DRM_APPDATA appData) override
@ -102,7 +133,11 @@ struct Direct3DRMViewportImpl : public IDirect3DRMViewport {
HRESULT ForceUpdate(int x, int y, int w, int h) 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 Clear() override { return DD_OK; }
HRESULT SetCamera(IDirect3DRMFrame* camera) override { return DD_OK; } HRESULT SetCamera(IDirect3DRMFrame* camera) override { return DD_OK; }
HRESULT GetCamera(IDirect3DRMFrame** camera) override { return DD_OK; } HRESULT GetCamera(IDirect3DRMFrame** camera) override
{
assert(false && "unimplemented");
return DDERR_GENERIC;
}
HRESULT SetProjection(D3DRMPROJECTIONTYPE type) override { return DD_OK; } HRESULT SetProjection(D3DRMPROJECTIONTYPE type) override { return DD_OK; }
D3DRMPROJECTIONTYPE GetProjection() override { return D3DRMPROJECTIONTYPE::PERSPECTIVE; } D3DRMPROJECTIONTYPE GetProjection() override { return D3DRMPROJECTIONTYPE::PERSPECTIVE; }
HRESULT SetFront(D3DVALUE z) override { return DD_OK; } HRESULT SetFront(D3DVALUE z) override { return DD_OK; }
@ -171,8 +206,8 @@ struct Direct3DRMImpl : public IDirect3DRM2 {
} }
HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) override HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) override
{ {
assert(false && "unimplemented"); *outMaterial = new IDirect3DRMMaterial;
return DDERR_GENERIC; return DD_OK;
} }
HRESULT CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight) override HRESULT CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight) override
{ {

View File

@ -3,8 +3,39 @@
#include "miniwin_d3d.h" #include "miniwin_d3d.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <assert.h>
#include <cstdint>
#include <cstdlib>
#include <cstring>
SDL_Renderer* renderer;
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;
}
struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 { 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());
}
}
~DirectDrawSurfaceImpl() override
{
if (texture) {
SDL_DestroyTexture(texture);
}
}
// IUnknown interface // IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override HRESULT QueryInterface(const GUID& riid, void** ppvObject) override
{ {
@ -26,18 +57,51 @@ struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 {
LPDDBLTFX lpDDBltFx LPDDBLTFX lpDDBltFx
) override ) override
{ {
if (!renderer) {
return DDERR_GENERIC;
}
SDL_FRect srcRect = ConvertRect(lpSrcRect);
SDL_FRect dstRect = ConvertRect(lpDestRect);
SDL_RenderTexture(renderer, static_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface)->texture, &srcRect, &dstRect);
SDL_RenderPresent(renderer);
return DD_OK; return DD_OK;
} }
HRESULT BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans) HRESULT BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans)
override 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<DirectDrawSurfaceImpl*>(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; return DD_OK;
} }
HRESULT DeleteAttachedSurface(DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface) override { return DD_OK; }
HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override { return DDERR_GENERIC; }
HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) override HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) override
{ {
return DDERR_GENERIC; if ((lpDDSCaps->dwCaps & DDSCAPS_BACKBUFFER) != DDSCAPS_BACKBUFFER) {
return DDERR_INVALIDPARAMS;
}
*lplpDDAttachedSurface = static_cast<IDirectDrawSurface*>(this);
return DD_OK;
} }
HRESULT GetCaps(LPDDSCAPS lpDDSCaps) override { return DD_OK; } HRESULT GetCaps(LPDDSCAPS lpDDSCaps) override { return DD_OK; }
HRESULT GetDC(HDC* lphDC) override { return DD_OK; } HRESULT GetDC(HDC* lphDC) override { return DD_OK; }
@ -49,11 +113,44 @@ struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 {
lpDDPixelFormat->dwFlags = DDPF_RGB; lpDDPixelFormat->dwFlags = DDPF_RGB;
return DD_OK; return DD_OK;
} }
HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) override { return DD_OK; } HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) override
HRESULT Initialize(LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) override { return DD_OK; } {
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 IsLost() override { return DD_OK; }
HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override
{ {
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; return DD_OK;
} }
HRESULT ReleaseDC(HDC hDC) override { return DD_OK; } HRESULT ReleaseDC(HDC hDC) override { return DD_OK; }
@ -61,7 +158,17 @@ struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 {
HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) override { return DD_OK; } HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) override { return DD_OK; }
HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override { return DD_OK; } HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override { return DD_OK; }
HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override { return DD_OK; } HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override { return DD_OK; }
HRESULT Unlock(LPVOID lpSurfaceData) override { return DD_OK; } HRESULT Unlock(LPVOID lpSurfaceData) override
{
if (texture) {
SDL_UnlockTexture(texture);
return DD_OK;
}
return DDERR_GENERIC;
}
private:
SDL_Texture* texture = nullptr;
}; };
struct DirectDrawClipperImpl : public IDirectDrawClipper { struct DirectDrawClipperImpl : public IDirectDrawClipper {
@ -69,6 +176,18 @@ struct DirectDrawClipperImpl : public IDirectDrawClipper {
HRESULT SetHWnd(DWORD unnamedParam1, HWND hWnd) override { return DD_OK; } 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 { struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
// IUnknown interface // IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override HRESULT QueryInterface(const GUID& riid, void** ppvObject) override
@ -100,13 +219,60 @@ struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
IUnknown* pUnkOuter IUnknown* pUnkOuter
) override ) override
{ {
return DDERR_GENERIC; *lplpDDPalette = static_cast<LPDIRECTDRAWPALETTE>(new DirectDrawPaletteImpl);
return DD_OK;
} }
HRESULT CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter) HRESULT CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter)
override override
{ {
*lplpDDSurface = static_cast<IDirectDrawSurface*>(new DirectDrawSurfaceImpl); 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<IDirectDrawSurface*>(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<IDirectDrawSurface*>(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->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<IDirectDrawSurface*>(new DirectDrawSurfaceImpl(width, height));
return DD_OK; return DD_OK;
} }
HRESULT EnumDisplayModes( HRESULT EnumDisplayModes(
@ -115,21 +281,41 @@ struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
LPVOID lpContext, LPVOID lpContext,
LPDDENUMMODESCALLBACK lpEnumModesCallback LPDDENUMMODESCALLBACK lpEnumModesCallback
) override; ) override;
HRESULT EnumSurfaces(
DWORD dwFlags,
LPDDSURFACEDESC lpDDSD,
LPVOID lpContext,
LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback
) override
{
return DD_OK;
}
HRESULT FlipToGDISurface() override { return DD_OK; } HRESULT FlipToGDISurface() override { return DD_OK; }
HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) override; HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) override;
HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) override { return DD_OK; } HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) override
HRESULT Initialize(GUID* lpGUID) override { return DD_OK; } {
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 RestoreDisplayMode() override { return DD_OK; } HRESULT RestoreDisplayMode() override { return DD_OK; }
HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) 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; } HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) override { return DD_OK; }
// IDirect3D2 interface // IDirect3D2 interface
HRESULT CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) override HRESULT CreateDevice(const GUID& guid, void* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice) override