Implement/match TglSurface

This commit is contained in:
Christian Semmler 2024-01-06 15:15:55 -05:00
parent dc3500f631
commit e1ff2712ed
12 changed files with 377 additions and 86 deletions

View File

@ -17,6 +17,7 @@ jobs:
--style=file \ --style=file \
ISLE/*.cpp ISLE/*.h \ ISLE/*.cpp ISLE/*.h \
LEGO1/*.cpp LEGO1/*.h \ LEGO1/*.cpp LEGO1/*.h \
LEGO1/3dmanager/*.cpp LEGO1/3dmanager/*.h \
LEGO1/mxdirectx/*.h \ LEGO1/mxdirectx/*.h \
LEGO1/mxstl/*.h \ LEGO1/mxstl/*.h \
LEGO1/realtime/*.cpp LEGO1/realtime/*.h \ LEGO1/realtime/*.cpp LEGO1/realtime/*.h \

View File

@ -7,6 +7,7 @@ option(ISLE_USE_SMARTHEAP "Build with SmartHeap" ${MSVC})
option(ISLE_USE_DX5 "Build with internal DirectX 5 SDK" ON) option(ISLE_USE_DX5 "Build with internal DirectX 5 SDK" ON)
add_library(lego1 SHARED add_library(lego1 SHARED
LEGO1/3dmanager/tglsurface.cpp
LEGO1/act1state.cpp LEGO1/act1state.cpp
LEGO1/act2brick.cpp LEGO1/act2brick.cpp
LEGO1/act2policestation.cpp LEGO1/act2policestation.cpp

View File

@ -0,0 +1,224 @@
// TglSurface.cpp : implementation file
#include "tglsurface.h"
#include "decomp.h"
DECOMP_SIZE_ASSERT(TglSurface, 0x70);
using namespace Tgl;
/////////////////////////////////////////////////////////////////////////////
// TglSurface
// FUNCTION: LEGO1 0x100abbf0
TglSurface::TglSurface()
{
m_pRenderer = 0;
m_pDevice = 0;
m_pView = 0;
m_pScene = 0;
m_width = 0;
m_height = 0;
m_stopRendering = FALSE;
m_isInitialized = FALSE;
// statistics
m_frameCount = 0;
#ifdef _DEBUG
m_triangleCount = 0;
#endif
}
// FUNCTION: LEGO1 0x100abd60
TglSurface::~TglSurface()
{
Destroy();
}
// FUNCTION: LEGO1 0x100abde0
void TglSurface::Destroy()
{
DestroyView();
delete m_pDevice;
m_pDevice = 0;
m_pRenderer = 0;
m_pScene = 0;
}
// ???
// FUNCTION: LEGO1 0x100abe10
int GetBitsPerPixel(IDirectDrawSurface* pSurface)
{
DDPIXELFORMAT pixelFormat;
HRESULT result;
memset(&pixelFormat, 0, sizeof(pixelFormat));
pixelFormat.dwSize = sizeof(pixelFormat);
result = pSurface->GetPixelFormat(&pixelFormat);
assert(result == DD_OK);
assert(pixelFormat.dwFlags & DDPF_RGB);
return pixelFormat.dwRGBBitCount;
}
// FUNCTION: LEGO1 0x100abe50
BOOL TglSurface::Create(const CreateStruct& rCreateStruct, Renderer* pRenderer, Group* pScene)
{
DeviceDirect3DCreateData createData = {rCreateStruct.m_direct3d, rCreateStruct.m_d3dDevice};
int bitsPerPixel = GetBitsPerPixel(rCreateStruct.m_pFrontBuffer);
ColorModel colorModel = Ramp;
ShadingModel shadingModel = Gouraud;
int shadeCount = 32;
BOOL dither = TRUE;
int textureShadeCount = -1;
int textureColorCount = -1;
Result result;
m_pRenderer = pRenderer;
m_pScene = pScene;
m_pDevice = m_pRenderer->CreateDevice(createData);
if (!m_pDevice) {
assert(0);
m_pRenderer = 0;
m_pScene = 0;
return FALSE;
}
if (bitsPerPixel == 1) {
shadeCount = 4;
textureShadeCount = 4;
}
else if (bitsPerPixel == 8) {
shadeCount = 16;
dither = FALSE;
textureShadeCount = 16;
textureColorCount = 256;
}
else if (bitsPerPixel == 16) {
shadeCount = 32;
dither = FALSE;
textureShadeCount = 32;
textureColorCount = 256;
}
else if (bitsPerPixel >= 24) {
shadeCount = 256;
dither = FALSE;
textureShadeCount = 256;
textureColorCount = 64;
}
else {
dither = FALSE;
}
if (textureShadeCount != -1) {
result = pRenderer->SetTextureDefaultShadeCount(textureShadeCount);
assert(Succeeded(result));
}
if (textureColorCount != -1) {
result = pRenderer->SetTextureDefaultColorCount(textureColorCount);
assert(Succeeded(result));
}
result = m_pDevice->SetColorModel(colorModel);
assert(Succeeded(result));
result = m_pDevice->SetShadingModel(shadingModel);
assert(Succeeded(result));
result = m_pDevice->SetShadeCount(shadeCount);
assert(Succeeded(result));
result = m_pDevice->SetDither(dither);
assert(Succeeded(result));
m_width = m_pDevice->GetWidth();
m_height = m_pDevice->GetHeight();
m_pView = CreateView(m_pRenderer, m_pDevice);
if (!m_pView) {
delete m_pDevice;
m_pDevice = 0;
m_pRenderer = 0;
m_pScene = 0;
return FALSE;
}
m_frameRateMeter.Reset();
m_renderingRateMeter.Reset();
#ifdef _DEBUG
m_triangleRateMeter.Reset();
#endif
m_frameRateMeter.StartOperation();
m_isInitialized = TRUE;
return TRUE;
}
// FUNCTION: LEGO1 0x100ac030
void TglSurface::DestroyView()
{
delete m_pView;
m_pView = 0;
}
// FUNCTION: LEGO1 0x100ac050
double TglSurface::Render()
{
MxStopWatch renderTimer;
if (m_isInitialized && !m_stopRendering) {
Result result;
#ifdef _DEBUG
m_triangleRateMeter.StartOperation();
#endif
m_renderingRateMeter.StartOperation();
renderTimer.Start();
// TODO: Wrong interface
result = m_pView->Render((Tgl::Light*) m_pScene);
renderTimer.Stop();
assert(Succeeded(result));
m_renderingRateMeter.EndOperation();
#ifdef _DEBUG
m_triangleRateMeter.EndOperation();
#endif
m_frameRateMeter.EndOperation();
m_frameCount++;
#ifdef _DEBUG
{
unsigned long triangleCount = m_pDevice->GetDrawnTriangleCount();
m_triangleRateMeter.IncreaseOperationCount(triangleCount - m_triangleCount - 1);
m_triangleCount = triangleCount;
}
#endif
#if 0
// reset rate meters every 20 frames
if ((++m_frameCount % 20) == 0)
#else
// reset rate meters every 4 seconds
if (m_frameRateMeter.ElapsedSeconds() > 4.0)
#endif
{
m_frameRateMeter.Reset();
m_renderingRateMeter.Reset();
#ifdef _DEBUG
m_triangleRateMeter.Reset();
#endif
}
m_frameRateMeter.StartOperation();
}
return renderTimer.ElapsedSeconds();
}

View File

@ -0,0 +1,87 @@
#ifndef _TglSurface_h
#define _TglSurface_h
#include "../mxdirectx/mxstopwatch.h"
#include "../tgl/tgl.h"
class Tgl::Renderer;
class Tgl::Device;
class Tgl::View;
class Tgl::Group;
/////////////////////////////////////////////////////////////////////////////
// TglSurface
// VTABLE: LEGO1 0x100dc060
// SIZE 0x70
class TglSurface {
public:
// SIZE 0x28
struct CreateStruct {
const GUID* m_pDriverGUID; // 0x00
HWND m_hWnd; // 0x04
IDirectDraw* m_pDirectDraw; // 0x08
IDirectDrawSurface* m_pFrontBuffer; // 0x0c
IDirectDrawSurface* m_pBackBuffer; // 0x10
IDirectDrawPalette* m_pPalette; // 0x14
BOOL m_isFullScreen; // 0x18
unsigned long m_flags; // 0x1c
IDirect3D2* m_direct3d; // 0x20
IDirect3DDevice2* m_d3dDevice; // 0x24
};
public:
TglSurface();
virtual ~TglSurface();
virtual BOOL Create(const CreateStruct&, Tgl::Renderer*, Tgl::Group* pScene); // vtable+0x04
virtual void Destroy(); // vtable+0x08
virtual double Render(); // render time in seconds // vtable+0x0c
Tgl::Renderer* GetRenderer() const { return m_pRenderer; }
Tgl::Device* GetDevice() const { return m_pDevice; }
Tgl::View* GetView() const { return m_pView; }
Tgl::Group* GetScene() const { return m_pScene; }
unsigned long GetWidth() const { return m_width; }
unsigned long GetHeight() const { return m_height; }
double GetRenderingRate() const { return m_renderingRateMeter.Frequency(); }
double GetFrameRate() const { return m_frameRateMeter.Frequency(); }
unsigned long GetFrameCount() const { return m_frameCount; }
#ifdef _DEBUG
double GetTriangleRate() const { return m_triangleRateMeter.Frequency(); }
#endif
protected:
virtual Tgl::View* CreateView(Tgl::Renderer*, Tgl::Device*) = 0; // vtable+0x10
virtual void DestroyView(); // vtable+0x14
private:
Tgl::Renderer* m_pRenderer; // 0x08
Tgl::Device* m_pDevice; // 0x0c
Tgl::View* m_pView; // 0x10
Tgl::Group* m_pScene; // 0x14
unsigned long m_width; // 0x18
unsigned long m_height; // 0x1c
BOOL m_isInitialized; // 0x20
BOOL m_stopRendering; // 0x24
// statistics
MxFrequencyMeter m_renderingRateMeter; // 0x28
MxFrequencyMeter m_frameRateMeter; // 0x48
unsigned long m_frameCount; // 0x68
#ifdef _DEBUG
MxFrequencyMeter m_triangleRateMeter;
unsigned long m_triangleCount;
#endif
};
/////////////////////////////////////////////////////////////////////////////
// SYNTHETIC: LEGO1 0x100abcf0
// TglSurface::`scalar deleting destructor'
#endif /* _TglSurface_h */

View File

@ -1,8 +1,7 @@
#include "lego3dmanager.h" #include "lego3dmanager.h"
#include "3dmanager/tglsurface.h"
#include "decomp.h" #include "decomp.h"
#include "tgl/tgl.h"
#include "tglsurface.h"
#include "viewmanager/viewlodlist.h" #include "viewmanager/viewlodlist.h"
DECOMP_SIZE_ASSERT(Lego3DManager, 0x10); DECOMP_SIZE_ASSERT(Lego3DManager, 0x10);
@ -10,12 +9,12 @@ DECOMP_SIZE_ASSERT(Lego3DManager, 0x10);
// FUNCTION: LEGO1 0x100ab2d0 // FUNCTION: LEGO1 0x100ab2d0
BOOL InitializeCreateStruct(TglSurface::CreateStruct& p_tglSurface, const Lego3DManager::CreateStruct& p_createStruct) BOOL InitializeCreateStruct(TglSurface::CreateStruct& p_tglSurface, const Lego3DManager::CreateStruct& p_createStruct)
{ {
p_tglSurface.m_driverGUID = p_createStruct.m_driverGUID; p_tglSurface.m_pDriverGUID = p_createStruct.m_driverGUID;
p_tglSurface.m_hwnd = p_createStruct.m_hwnd; p_tglSurface.m_hWnd = p_createStruct.m_hwnd;
p_tglSurface.m_directDraw = p_createStruct.m_directDraw; p_tglSurface.m_pDirectDraw = p_createStruct.m_directDraw;
p_tglSurface.m_ddSurface1 = p_createStruct.m_ddSurface1; p_tglSurface.m_pFrontBuffer = p_createStruct.m_ddSurface1;
p_tglSurface.m_ddSurface2 = p_createStruct.m_ddSurface2; p_tglSurface.m_pBackBuffer = p_createStruct.m_ddSurface2;
p_tglSurface.m_ddPalette = p_createStruct.m_ddPalette; p_tglSurface.m_pPalette = p_createStruct.m_ddPalette;
p_tglSurface.m_isFullScreen = p_createStruct.m_isFullScreen; p_tglSurface.m_isFullScreen = p_createStruct.m_isFullScreen;
p_tglSurface.m_flags = p_createStruct.m_flags; p_tglSurface.m_flags = p_createStruct.m_flags;
p_tglSurface.m_direct3d = p_createStruct.m_direct3d; p_tglSurface.m_direct3d = p_createStruct.m_direct3d;

View File

@ -19,11 +19,11 @@ Lego3DView::~Lego3DView()
BOOL Lego3DView::Create(TglSurface::CreateStruct& p_createStruct, Tgl::Renderer* p_renderer) BOOL Lego3DView::Create(TglSurface::CreateStruct& p_createStruct, Tgl::Renderer* p_renderer)
{ {
Tgl::DeviceDirectDrawCreateData createData = { Tgl::DeviceDirectDrawCreateData createData = {
p_createStruct.m_driverGUID, p_createStruct.m_pDriverGUID,
p_createStruct.m_hwnd, p_createStruct.m_hWnd,
p_createStruct.m_directDraw, p_createStruct.m_pDirectDraw,
p_createStruct.m_ddSurface1, p_createStruct.m_pFrontBuffer,
p_createStruct.m_ddSurface2 p_createStruct.m_pBackBuffer
}; };
m_device = p_renderer->CreateDevice(createData); m_device = p_renderer->CreateDevice(createData);

View File

@ -1,9 +1,9 @@
#ifndef LEGO3DVIEW_H #ifndef LEGO3DVIEW_H
#define LEGO3DVIEW_H #define LEGO3DVIEW_H
#include "3dmanager/tglsurface.h"
#include "decomp.h"
#include "mxtypes.h" #include "mxtypes.h"
#include "tgl/d3drm/impl.h"
#include "tglsurface.h"
#include "viewmanager/viewmanager.h" #include "viewmanager/viewmanager.h"
class LegoROI; class LegoROI;

View File

@ -5,6 +5,7 @@
#include "mxtimer.h" #include "mxtimer.h"
#include "mxtransitionmanager.h" #include "mxtransitionmanager.h"
#include "realtime/matrix.h" #include "realtime/matrix.h"
#include "tgl/d3drm/impl.h"
#include "viewmanager/viewroi.h" #include "viewmanager/viewroi.h"
DECOMP_SIZE_ASSERT(LegoVideoManager, 0x590); DECOMP_SIZE_ASSERT(LegoVideoManager, 0x590);
@ -224,31 +225,6 @@ void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY)
m_cursorY = 463; m_cursorY = 463;
} }
inline void LegoVideoManager::DrawCursor()
{
if (m_cursorX != m_cursorXCopy || m_cursorY != m_cursorYCopy) {
if (m_cursorX >= 0 && m_cursorY >= 0) {
m_cursorXCopy = m_cursorX;
m_cursorYCopy = m_cursorY;
}
}
LPDIRECTDRAWSURFACE ddSurface2 = m_displaySurface->GetDirectDrawSurface2();
if (!m_unk0x514) {
m_unk0x518.top = 0;
m_unk0x518.left = 0;
m_unk0x518.bottom = 16;
m_unk0x518.right = 16;
m_unk0x514 = MxDisplaySurface::FUN_100bc070();
if (!m_unk0x514)
m_drawCursor = FALSE;
}
ddSurface2->BltFast(m_cursorXCopy, m_cursorYCopy, m_unk0x514, &m_unk0x518, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
}
// FUNCTION: LEGO1 0x1007b770 // FUNCTION: LEGO1 0x1007b770
MxResult LegoVideoManager::Tickle() MxResult LegoVideoManager::Tickle()
{ {
@ -321,6 +297,31 @@ MxResult LegoVideoManager::Tickle()
return SUCCESS; return SUCCESS;
} }
inline void LegoVideoManager::DrawCursor()
{
if (m_cursorX != m_cursorXCopy || m_cursorY != m_cursorYCopy) {
if (m_cursorX >= 0 && m_cursorY >= 0) {
m_cursorXCopy = m_cursorX;
m_cursorYCopy = m_cursorY;
}
}
LPDIRECTDRAWSURFACE ddSurface2 = m_displaySurface->GetDirectDrawSurface2();
if (!m_unk0x514) {
m_unk0x518.top = 0;
m_unk0x518.left = 0;
m_unk0x518.bottom = 16;
m_unk0x518.right = 16;
m_unk0x514 = MxDisplaySurface::FUN_100bc070();
if (!m_unk0x514)
m_drawCursor = FALSE;
}
ddSurface2->BltFast(m_cursorXCopy, m_cursorYCopy, m_unk0x514, &m_unk0x518, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
}
// STUB: LEGO1 0x1007bbc0 // STUB: LEGO1 0x1007bbc0
void LegoVideoManager::DrawFPS() void LegoVideoManager::DrawFPS()
{ {

View File

@ -2,7 +2,9 @@
#define _MxStopWatch_h #define _MxStopWatch_h
#include "assert.h" #include "assert.h"
#include "winbase.h"
#include <math.h>
#include <windows.h>
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
@ -13,6 +15,7 @@
#define HUGE_VAL_IMMEDIATE 1.7976931348623157e+308 #define HUGE_VAL_IMMEDIATE 1.7976931348623157e+308
// SIZE 0x18
class MxStopWatch { class MxStopWatch {
public: public:
MxStopWatch(); MxStopWatch();
@ -28,11 +31,11 @@ class MxStopWatch {
unsigned long TicksPerSeconds() const; unsigned long TicksPerSeconds() const;
private: private:
LARGE_INTEGER m_startTick; LARGE_INTEGER m_startTick; // 0x00
// ??? when we provide LARGE_INTEGER arithmetic, use a // ??? when we provide LARGE_INTEGER arithmetic, use a
// LARGE_INTEGER m_elapsedTicks rather than m_elapsedSeconds // LARGE_INTEGER m_elapsedTicks rather than m_elapsedSeconds
double m_elapsedSeconds; double m_elapsedSeconds; // 0x0c
unsigned long m_ticksPerSeconds; unsigned long m_ticksPerSeconds; // 0x14
}; };
inline MxStopWatch::MxStopWatch() inline MxStopWatch::MxStopWatch()
@ -99,6 +102,7 @@ inline double MxStopWatch::ElapsedSeconds() const
// MxFrequencyMeter // MxFrequencyMeter
// //
// SIZE 0x20
class MxFrequencyMeter { class MxFrequencyMeter {
public: public:
MxFrequencyMeter(); MxFrequencyMeter();
@ -114,8 +118,8 @@ class MxFrequencyMeter {
void IncreaseOperationCount(unsigned long); void IncreaseOperationCount(unsigned long);
private: private:
unsigned long m_operationCount; unsigned long m_operationCount; // 0x00
MxStopWatch m_stopWatch; MxStopWatch m_stopWatch; // 0x08
}; };
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,6 @@
#include "../tgl.h" #include "../tgl.h"
#include "compat.h"
#include "decomp.h" #include "decomp.h"
#include <d3drm.h> #include <d3drm.h>
@ -41,11 +42,11 @@ class RendererImpl : public Renderer {
RendererImpl() : m_data(0) {} RendererImpl() : m_data(0) {}
~RendererImpl() { Destroy(); }; ~RendererImpl() { Destroy(); };
virtual void* ImplementationDataPtr(); virtual void* ImplementationDataPtr() override;
// vtable+0x08 // vtable+0x08
virtual Device* CreateDevice(const DeviceDirect3DCreateData&); virtual Device* CreateDevice(const DeviceDirectDrawCreateData&) override;
virtual Device* CreateDevice(const DeviceDirectDrawCreateData&); virtual Device* CreateDevice(const DeviceDirect3DCreateData&) override;
// vtable+0x10 // vtable+0x10
virtual View* CreateView( virtual View* CreateView(
@ -55,14 +56,14 @@ class RendererImpl : public Renderer {
unsigned long y, unsigned long y,
unsigned long width, unsigned long width,
unsigned long height unsigned long height
); ) override;
virtual Camera* CreateCamera(); virtual Camera* CreateCamera() override;
virtual Light* CreateLight(LightType, float r, float g, float b); virtual Light* CreateLight(LightType, float r, float g, float b) override;
virtual Group* CreateGroup(const Group* pParent); virtual Group* CreateGroup(const Group* pParent) override;
// vtable+0x20 // vtable+0x20
virtual Unk* CreateUnk(); virtual Unk* CreateUnk() override;
virtual Texture* CreateTexture(); virtual Texture* CreateTexture() override;
virtual Texture* CreateTexture( virtual Texture* CreateTexture(
int width, int width,
int height, int height,
@ -71,11 +72,11 @@ class RendererImpl : public Renderer {
int pTexelsArePersistent, int pTexelsArePersistent,
int paletteEntryCount, int paletteEntryCount,
const PaletteEntry* pEntries const PaletteEntry* pEntries
); ) override;
virtual Result SetTextureDefaultShadeCount(unsigned long); virtual Result SetTextureDefaultShadeCount(unsigned long) override;
// vtable+0x30 // vtable+0x30
virtual Result SetTextureDefaultColorCount(unsigned long); virtual Result SetTextureDefaultColorCount(unsigned long) override;
public: public:
inline Result Create(); inline Result Create();

View File

@ -110,8 +110,8 @@ class Object {
class Renderer : public Object { class Renderer : public Object {
public: public:
// vtable+0x08 // vtable+0x08
virtual Device* CreateDevice(const DeviceDirect3DCreateData&) = 0;
virtual Device* CreateDevice(const DeviceDirectDrawCreateData&) = 0; virtual Device* CreateDevice(const DeviceDirectDrawCreateData&) = 0;
virtual Device* CreateDevice(const DeviceDirect3DCreateData&) = 0;
// vtable+0x10 // vtable+0x10
virtual View* CreateView( virtual View* CreateView(

View File

@ -1,27 +0,0 @@
#ifndef TGLSURFACE_H
#define TGLSURFACE_H
#include "decomp.h"
#include "mxtypes.h"
#include <d3d.h>
#include <windows.h>
class TglSurface {
public:
// SIZE 0x28
struct CreateStruct {
GUID* m_driverGUID; // 0x00
HWND m_hwnd; // 0x04
IDirectDraw* m_directDraw; // 0x08
IDirectDrawSurface* m_ddSurface1; // 0x0c
IDirectDrawSurface* m_ddSurface2; // 0x10
IDirectDrawPalette* m_ddPalette; // 0x14
BOOL m_isFullScreen; // 0x18
MxU32 m_flags; // 0x1c
IDirect3D2* m_direct3d; // 0x20
IDirect3DDevice2* m_d3dDevice; // 0x24
};
};
#endif // TGLSURFACE_H