diff --git a/LEGO1/lego3dmanager.h b/LEGO1/lego3dmanager.h index 0a856f90..2482218b 100644 --- a/LEGO1/lego3dmanager.h +++ b/LEGO1/lego3dmanager.h @@ -19,8 +19,8 @@ public: IDirectDrawPalette* m_ddPalette; // 0x14 BOOL m_isFullScreen; // 0x18 MxU32 m_flags; // 0x1c - IDirect3D* m_direct3d; // 0x20 - IDirect3DDevice* m_d3dDevice; // 0x24 + IDirect3D2* m_direct3d; // 0x20 + IDirect3DDevice2* m_d3dDevice; // 0x24 }; Lego3DManager(); diff --git a/LEGO1/mxdirect3d.cpp b/LEGO1/mxdirect3d.cpp index 517a9aad..a006b4bb 100644 --- a/LEGO1/mxdirect3d.cpp +++ b/LEGO1/mxdirect3d.cpp @@ -111,14 +111,89 @@ BOOL MxDirect3D::CreateIDirect3D() return TRUE; } -// STUB: LEGO1 0x1009b310 +// FUNCTION: LEGO1 0x1009b310 BOOL MxDirect3D::D3DSetMode() { - // TODO - // if (m_assignedDevice) - Error("This device cannot support the current display mode", 0); - OutputDebugString("MxDirect3D::D3DSetMode() front lock failed\n"); - OutputDebugString("MxDirect3D::D3DSetMode() back lock failed\n"); + if (m_assignedDevice->m_flags & MxAssignedDevice::Flag_HardwareMode) { + if (m_bOnlySoftRender) { + Error("Failed to place vital surfaces in video memory for hardware driver", DDERR_GENERIC); + return FALSE; + } + + if (m_assignedDevice->m_desc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) + m_unk0x88c = FALSE; + else + m_unk0x88c = TRUE; + + DWORD bitDepth = GetZBufferBitDepth(m_assignedDevice); + if (!CreateZBuffer(DDSCAPS_VIDEOMEMORY, bitDepth)) + return FALSE; + } + else { + if (m_assignedDevice->m_desc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE) + m_unk0x88c = FALSE; + else + m_unk0x88c = TRUE; + + DWORD bitDepth = GetZBufferBitDepth(m_assignedDevice); + if (!CreateZBuffer(DDSCAPS_SYSTEMMEMORY, bitDepth)) + return FALSE; + } + + HRESULT result = m_pDirect3d->CreateDevice(m_assignedDevice->m_guid, m_pBackBuffer, &m_pDirect3dDevice); + + if (result != DD_OK) { + Error("Create D3D device failed", result); + return FALSE; + } + + MxDirectDraw::Mode mode = m_currentMode; + + if (m_bFullScreen && !IsSupportedMode(mode.m_width, mode.m_height, mode.m_bitsPerPixel)) { + Error("This device cannot support the current display mode", DDERR_GENERIC); + return FALSE; + } + + LPDIRECTDRAWSURFACE frontBuffer = m_pFrontBuffer; + LPDIRECTDRAWSURFACE backBuffer = m_pBackBuffer; + + DDSURFACEDESC desc; + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + if (backBuffer->Lock(NULL, &desc, DDLOCK_WAIT, NULL) == DD_OK) { + MxU8* surface = (MxU8*) desc.lpSurface; + + for (MxS32 i = mode.m_height; i > 0; i--) { + memset(surface, 0, mode.m_width * desc.ddpfPixelFormat.dwRGBBitCount / 8); + surface += desc.lPitch; + } + + backBuffer->Unlock(desc.lpSurface); + } + else { + OutputDebugString("MxDirect3D::D3DSetMode() back lock failed\n"); + } + + if (m_bFullScreen) { + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + if (frontBuffer->Lock(NULL, &desc, DDLOCK_WAIT, NULL) == DD_OK) { + MxU8* surface = (MxU8*) desc.lpSurface; + + for (MxS32 i = mode.m_height; i > 0; i--) { + memset(surface, 0, mode.m_width * desc.ddpfPixelFormat.dwRGBBitCount / 8); + surface += desc.lPitch; + } + + frontBuffer->Unlock(desc.lpSurface); + } + else { + OutputDebugString("MxDirect3D::D3DSetMode() front lock failed\n"); + } + } + return TRUE; } diff --git a/LEGO1/mxdirect3d.h b/LEGO1/mxdirect3d.h index 8ad41593..41cafad9 100644 --- a/LEGO1/mxdirect3d.h +++ b/LEGO1/mxdirect3d.h @@ -61,15 +61,15 @@ public: BOOL SetDevice(MxDeviceEnumerate& p_deviceEnumerate, MxDriver* p_driver, MxDevice* p_device); inline MxAssignedDevice* GetAssignedDevice() { return this->m_assignedDevice; }; - inline IDirect3D* GetDirect3D() { return this->m_pDirect3d; } - inline IDirect3DDevice* GetDirect3DDevice() { return this->m_pDirect3dDevice; } + inline IDirect3D2* GetDirect3D() { return this->m_pDirect3d; } + inline IDirect3DDevice2* GetDirect3DDevice() { return this->m_pDirect3dDevice; } private: - MxAssignedDevice* m_assignedDevice; // 0x880 - IDirect3D* m_pDirect3d; // 0x884 - IDirect3DDevice* m_pDirect3dDevice; // 0x888 - undefined4 m_unk0x88c; // 0x88c - undefined4 m_unk0x890; // 0x890 + MxAssignedDevice* m_assignedDevice; // 0x880 + IDirect3D2* m_pDirect3d; // 0x884 + IDirect3DDevice2* m_pDirect3dDevice; // 0x888 + BOOL m_unk0x88c; // 0x88c + undefined4 m_unk0x890; // 0x890 }; // SIZE 0x1a4 diff --git a/LEGO1/mxdirectdraw.h b/LEGO1/mxdirectdraw.h index ce45a823..248537cd 100644 --- a/LEGO1/mxdirectdraw.h +++ b/LEGO1/mxdirectdraw.h @@ -68,7 +68,7 @@ protected: void* m_pFatalErrorHandlerArg; // 0x868 int m_pauseCount; // 0x86c DeviceModesInfo* m_pCurrentDeviceModesList; // 0x870 - Mode m_currentMode; // 0x87c + Mode m_currentMode; // 0x874 public: __declspec(dllexport) int FlipToGDISurface(); diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp index 3ffd8e7a..5ce00bab 100644 --- a/LEGO1/mxvideomanager.cpp +++ b/LEGO1/mxvideomanager.cpp @@ -120,7 +120,7 @@ void MxVideoManager::SortPresenterList() MxResult MxVideoManager::VTable0x28( MxVideoParam& p_videoParam, LPDIRECTDRAW p_pDirectDraw, - LPDIRECT3D p_pDirect3D, + LPDIRECT3D2 p_pDirect3D, LPDIRECTDRAWSURFACE p_ddSurface1, LPDIRECTDRAWSURFACE p_ddSurface2, LPDIRECTDRAWCLIPPER p_ddClipper, diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index 4b458f1b..41a7ce93 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -21,7 +21,7 @@ public: virtual MxResult VTable0x28( MxVideoParam& p_videoParam, LPDIRECTDRAW p_pDirectDraw, - LPDIRECT3D p_pDirect3D, + LPDIRECT3D2 p_pDirect3D, LPDIRECTDRAWSURFACE p_ddSurface1, LPDIRECTDRAWSURFACE p_ddSurface2, LPDIRECTDRAWCLIPPER p_ddClipper, @@ -47,7 +47,7 @@ public: protected: MxVideoParam m_videoParam; // 0x2c LPDIRECTDRAW m_pDirectDraw; // 0x50 - LPDIRECT3D m_pDirect3D; // 0x54 + LPDIRECT3D2 m_pDirect3D; // 0x54 MxDisplaySurface* m_displaySurface; // 0x58 MxRegion* m_region; // 0x5c MxBool m_unk0x60; // 0x60 diff --git a/LEGO1/tglsurface.h b/LEGO1/tglsurface.h index bafb2fb3..01bfad78 100644 --- a/LEGO1/tglsurface.h +++ b/LEGO1/tglsurface.h @@ -19,8 +19,8 @@ public: IDirectDrawPalette* m_ddPalette; // 0x14 BOOL m_isFullScreen; // 0x18 MxU32 m_flags; // 0x1c - IDirect3D* m_direct3d; // 0x20 - IDirect3DDevice* m_d3dDevice; // 0x24 + IDirect3D2* m_direct3d; // 0x20 + IDirect3DDevice2* m_d3dDevice; // 0x24 }; };