From b28fcae00580b3e5f0d6a8165b2f465aec763929 Mon Sep 17 00:00:00 2001 From: MS Date: Mon, 26 May 2025 12:46:22 -0400 Subject: [PATCH] Match `TextureImpl` functions (#1521) * TextureImpl functions * TglD3DRMIMAGE functions --- LEGO1/tgl/d3drm/impl.h | 9 +- LEGO1/tgl/d3drm/texture.cpp | 204 ++++++++++++++++++++++++++++-------- LEGO1/tgl/tgl.h | 4 +- 3 files changed, 169 insertions(+), 48 deletions(-) diff --git a/LEGO1/tgl/d3drm/impl.h b/LEGO1/tgl/d3drm/impl.h index fe79e01b..658ee1b2 100644 --- a/LEGO1/tgl/d3drm/impl.h +++ b/LEGO1/tgl/d3drm/impl.h @@ -612,7 +612,7 @@ public: int paletteSize, PaletteEntry* pEntries ); - ~TglD3DRMIMAGE() { Destroy(); } + ~TglD3DRMIMAGE(); Result CreateBuffer(int width, int height, int depth, void* pBuffer, int useBuffer); void Destroy(); @@ -621,6 +621,9 @@ public: D3DRMIMAGE m_image; int m_texelsAllocatedByClient; + + // SYNTHETIC: BETA10 0x1016abb0 + // TglImpl::TglD3DRMIMAGE::`scalar deleting destructor' }; // VTABLE: LEGO1 0x100dbb48 @@ -636,7 +639,7 @@ public: void* ImplementationDataPtr() override; // vtable+0x08 - Result SetTexels(int width, int height, int bitsPerTexel, void* pTexels) override; + Result SetTexels(int width, int height, int bitsPerTexel, void* pTexels, int pTexelsArePersistent) override; void FillRowsOfTexture(int y, int height, void* pBuffer) override; // vtable+0x10 @@ -647,7 +650,7 @@ public: int* pDepth, void** ppBuffer, int* ppPaletteSize, - PaletteEntry** ppPalette + unsigned char (*pEntries)[3] ) override; Result SetPalette(int entryCount, PaletteEntry* entries) override; diff --git a/LEGO1/tgl/d3drm/texture.cpp b/LEGO1/tgl/d3drm/texture.cpp index 5944d7ba..0a19c8c4 100644 --- a/LEGO1/tgl/d3drm/texture.cpp +++ b/LEGO1/tgl/d3drm/texture.cpp @@ -1,9 +1,12 @@ #include "impl.h" +#include + using namespace TglImpl; DECOMP_SIZE_ASSERT(TglD3DRMIMAGE, 0x40); +// FUNCTION: BETA10 0x1016f9f0 inline TglD3DRMIMAGE* TextureGetImage(IDirect3DRMTexture* pTexture) { return reinterpret_cast(pTexture->GetAppData()); @@ -13,36 +16,47 @@ inline TglD3DRMIMAGE* TextureGetImage(IDirect3DRMTexture* pTexture) void TextureDestroyCallback(IDirect3DRMObject* pObject, void* pArg); // FUNCTION: LEGO1 0x100a12a0 +// FUNCTION: BETA10 0x10169113 Result TextureImpl::SetImage(IDirect3DRMTexture* pSelf, TglD3DRMIMAGE* pImage) { void* appData; Result result; appData = pImage; + assert(reinterpret_cast(appData) == pImage); - // This is here because in the original code they asserted - // on the return value being NULL. - TextureGetImage(pSelf); + if (TextureGetImage(pSelf)) { + assert(0); + } result = ResultVal(pSelf->SetAppData((LPD3DRM_APPDATA) appData)); + assert(Succeeded(result)); + if (Succeeded(result) && pImage) { result = ResultVal(pSelf->AddDestroyCallback(TextureDestroyCallback, NULL)); + assert(Succeeded(result)); + if (!Succeeded(result)) { pSelf->SetAppData(0); } } + return result; } // FUNCTION: LEGO1 0x100a1300 +// FUNCTION: BETA10 0x10169278 void TextureDestroyCallback(IDirect3DRMObject* pObject, void* pArg) { TglD3DRMIMAGE* pImage = reinterpret_cast(pObject->GetAppData()); + assert(pImage); + delete pImage; pObject->SetAppData(0); } // FUNCTION: LEGO1 0x100a1330 +// FUNCTION: BETA10 0x101692e1 TglD3DRMIMAGE::TglD3DRMIMAGE( int width, int height, @@ -53,10 +67,10 @@ TglD3DRMIMAGE::TglD3DRMIMAGE( PaletteEntry* pEntries ) { - m_image.aspectx = 1; - m_image.aspecty = 1; m_image.width = 0; m_image.height = 0; + m_image.aspectx = 1; + m_image.aspecty = 1; m_image.depth = 0; m_image.rgb = 0; m_image.bytes_per_line = 0; @@ -69,23 +83,31 @@ TglD3DRMIMAGE::TglD3DRMIMAGE( m_image.palette_size = 0; m_image.palette = NULL; m_texelsAllocatedByClient = 0; + + Result result; if (pBuffer != NULL) { - CreateBuffer(width, height, depth, pBuffer, useBuffer); + result = CreateBuffer(width, height, depth, pBuffer, useBuffer); + assert(Succeeded(result)); } + if (pEntries != NULL) { - InitializePalette(paletteSize, pEntries); + result = InitializePalette(paletteSize, pEntries); + assert(Succeeded(result)); } } // FUNCTION: LEGO1 0x100a13b0 -void TglD3DRMIMAGE::Destroy() +// FUNCTION: BETA10 0x1016944b +TglD3DRMIMAGE::~TglD3DRMIMAGE() { if (m_texelsAllocatedByClient == 0) { delete[] ((char*) m_image.buffer1); } + delete m_image.palette; } +// FUNCTION: BETA10 0x101699a0 inline static int IsPowerOfTwo(int v) { int m = 0; @@ -99,16 +121,25 @@ inline static int IsPowerOfTwo(int v) } // FUNCTION: LEGO1 0x100a13e0 +// FUNCTION: BETA10 0x101694a4 Result TglD3DRMIMAGE::CreateBuffer(int width, int height, int depth, void* pBuffer, int useBuffer) { - if (!(IsPowerOfTwo(width) && IsPowerOfTwo(height) && width % 4 == 0)) { + int bytesPerScanline = width; + + assert(IsPowerOfTwo(width)); + assert(IsPowerOfTwo(height)); + assert((bytesPerScanline % 4) == 0); + + if (!(IsPowerOfTwo(width) && IsPowerOfTwo(height) && bytesPerScanline % 4 == 0)) { return Error; } + assert(!m_image.buffer1 || (m_image.buffer1 == pBuffer)); + m_image.width = width; m_image.height = height; m_image.depth = depth; - m_image.bytes_per_line = width; + m_image.bytes_per_line = bytesPerScanline; if (!m_texelsAllocatedByClient) { delete[] ((char*) m_image.buffer1); @@ -116,12 +147,13 @@ Result TglD3DRMIMAGE::CreateBuffer(int width, int height, int depth, void* pBuff } if (useBuffer) { - m_texelsAllocatedByClient = 1; m_image.buffer1 = (char*) pBuffer; + m_texelsAllocatedByClient = 1; } else { - m_image.buffer1 = new char[width * height]; - memcpy(m_image.buffer1, pBuffer, width * height); + int size = bytesPerScanline * height; + m_image.buffer1 = new char[size]; + memcpy(m_image.buffer1, pBuffer, size); m_texelsAllocatedByClient = 0; } @@ -129,14 +161,20 @@ Result TglD3DRMIMAGE::CreateBuffer(int width, int height, int depth, void* pBuff } // FUNCTION: LEGO1 0x100a1510 -Result TglD3DRMIMAGE::FillRowsOfTexture(int y, int height, char* pContent) +// FUNCTION: BETA10 0x1016969c +Result TglD3DRMIMAGE::FillRowsOfTexture(int destVOffset, int srcHeight, char* pTexels) { - // The purpose is clearly this but I can't get the assembly to line up. - memcpy((char*) m_image.buffer1 + (y * m_image.bytes_per_line), pContent, height * m_image.bytes_per_line); + assert(m_image.buffer1 && pTexels); + assert((destVOffset + srcHeight) <= m_image.height); + + int size = srcHeight * m_image.bytes_per_line; + char* pSrc = (char*) m_image.buffer1 + (destVOffset * m_image.bytes_per_line); + memcpy(pSrc, pTexels, size); return Success; } // FUNCTION: LEGO1 0x100a1550 +// FUNCTION: BETA10 0x10169758 Result TglD3DRMIMAGE::InitializePalette(int paletteSize, PaletteEntry* pEntries) { // This function is a 100% match if the PaletteEntry class is copied @@ -152,6 +190,7 @@ Result TglD3DRMIMAGE::InitializePalette(int paletteSize, PaletteEntry* pEntries) m_image.palette_size = paletteSize; } } + if (paletteSize > 0) { for (int i = 0; i < paletteSize; i++) { m_image.palette[i].red = pEntries[i].m_red; @@ -160,67 +199,146 @@ Result TglD3DRMIMAGE::InitializePalette(int paletteSize, PaletteEntry* pEntries) m_image.palette[i].flags = D3DRMPALETTE_READONLY; } } + return Success; } -// FUNCTION: LEGO1 0x100a3c10 -Result TextureImpl::SetTexels(int width, int height, int bitsPerTexel, void* pTexels) +// FUNCTION: BETA10 0x1016ee80 +inline Result TextureSetTexels( + IDirect3DRMTexture* pTexture, + int width, + int height, + int bitsPerTexel, + void* pTexels, + int pTexelsArePersistent +) { - TglD3DRMIMAGE* image = TextureGetImage(m_data); - Result result = image->CreateBuffer(width, height, bitsPerTexel, pTexels, TRUE); + TglD3DRMIMAGE* pImage = TextureGetImage(pTexture); + assert(pImage); + + Result result = pImage->CreateBuffer(width, height, bitsPerTexel, pTexels, pTexelsArePersistent); + assert(Succeeded(result)); + if (Succeeded(result)) { - result = ResultVal(m_data->Changed(TRUE, FALSE)); + result = ResultVal(pTexture->Changed(TRUE, FALSE)); + assert(Succeeded(result)); } + + return result; +} + +// FUNCTION: LEGO1 0x100a3c10 +// FUNCTION: BETA10 0x1016c390 +Result TextureImpl::SetTexels(int width, int height, int bitsPerTexel, void* pTexels, int pTexelsArePersistent) +{ + assert(m_data); + + return TextureSetTexels(m_data, width, height, bitsPerTexel, pTexels, pTexelsArePersistent); +} + +// FUNCTION: BETA10 0x1016f160 +inline Result TextureFillRowsOfTexture(IDirect3DRMTexture* pTexture, int y, int height, void* pBuffer) +{ + TglD3DRMIMAGE* pImage = TextureGetImage(pTexture); + assert(pImage); + + Result result = pImage->FillRowsOfTexture(y, height, (char*) pBuffer); + assert(Succeeded(result)); + return result; } // FUNCTION: LEGO1 0x100a3c60 +// FUNCTION: BETA10 0x1016c490 void TextureImpl::FillRowsOfTexture(int y, int height, void* pBuffer) { - TglD3DRMIMAGE* image = TextureGetImage(m_data); - image->FillRowsOfTexture(y, height, (char*) pBuffer); + assert(m_data); + + TextureFillRowsOfTexture(m_data, y, height, pBuffer); +} + +// FUNCTION: BETA10 0x1016f270 +inline Result TextureChanged(IDirect3DRMTexture* pTexture, int texelsChanged, int paletteChanged) +{ + Result result = ResultVal(pTexture->Changed(texelsChanged, paletteChanged)); + assert(Succeeded(result)); + return result; } // FUNCTION: LEGO1 0x100a3c90 +// FUNCTION: BETA10 0x1016c540 Result TextureImpl::Changed(int texelsChanged, int paletteChanged) { - return ResultVal(m_data->Changed(texelsChanged, paletteChanged)); + assert(m_data); + + return TextureChanged(m_data, texelsChanged, paletteChanged); +} + +// FUNCTION: BETA10 0x1016f4c0 +inline Result TextureGetBufferAndPalette( + IDirect3DRMTexture* pTexture, + int* width, + int* height, + int* depth, + void** pBuffer, + int* paletteSize, + unsigned char (*pEntries)[3] +) +{ + TglD3DRMIMAGE* pImage = TextureGetImage(pTexture); + assert(pImage); + + *width = pImage->m_image.width; + *height = pImage->m_image.height; + *depth = pImage->m_image.depth; + *pBuffer = pImage->m_image.buffer1; + *paletteSize = pImage->m_image.palette_size; + + for (int i = 0; i < *paletteSize; i++) { + pEntries[i][0] = pImage->m_image.palette[i].red; + pEntries[i][1] = pImage->m_image.palette[i].green; + pEntries[i][2] = pImage->m_image.palette[i].blue; + } + + return Success; } // FUNCTION: LEGO1 0x100a3cc0 +// FUNCTION: BETA10 0x1016c5d0 Result TextureImpl::GetBufferAndPalette( int* width, int* height, int* depth, void** pBuffer, int* paletteSize, - PaletteEntry** pEntries + unsigned char (*pEntries)[3] ) { - // Something really doesn't match here, not sure what's up. - TglD3DRMIMAGE* image = TextureGetImage(m_data); - *width = image->m_image.width; - *height = image->m_image.height; - *depth = image->m_image.depth; - *pBuffer = image->m_image.buffer1; - *paletteSize = image->m_image.palette_size; - for (int i = 0; i < image->m_image.palette_size; i++) { - pEntries[i]->m_red = image->m_image.palette[i].red; - pEntries[i]->m_green = image->m_image.palette[i].green; - pEntries[i]->m_blue = image->m_image.palette[i].blue; - } + assert(m_data); + + return TextureGetBufferAndPalette(m_data, width, height, depth, pBuffer, paletteSize, pEntries); +} + +// FUNCTION: BETA10 0x1016f730 +inline Result TextureSetPalette(IDirect3DRMTexture* pTexture, int entryCount, PaletteEntry* pEntries) +{ + TglD3DRMIMAGE* pImage = TextureGetImage(pTexture); + assert(pImage); + + pImage->InitializePalette(entryCount, pEntries); + Result result = ResultVal(pTexture->Changed(FALSE, TRUE)); + assert(Succeeded(result)); + return Success; } // FUNCTION: LEGO1 0x100a3d40 +// FUNCTION: BETA10 0x1016c6a0 Result TextureImpl::SetPalette(int entryCount, PaletteEntry* pEntries) { - // Not 100% confident this is supposed to directly be forwarding arguments, - // but it probably is given FillRowsOfTexture matches doing that. - TglD3DRMIMAGE* image = TextureGetImage(m_data); - image->InitializePalette(entryCount, pEntries); - m_data->Changed(FALSE, TRUE); - return Success; + assert(m_data); + + return TextureSetPalette(m_data, entryCount, pEntries); } // FUNCTION: LEGO1 0x100a3d70 diff --git a/LEGO1/tgl/tgl.h b/LEGO1/tgl/tgl.h index 3d27881e..cd3fccae 100644 --- a/LEGO1/tgl/tgl.h +++ b/LEGO1/tgl/tgl.h @@ -400,7 +400,7 @@ public: class Texture : public Object { public: // vtable+0x08 - virtual Result SetTexels(int width, int height, int bitsPerTexel, void* pTexels) = 0; + virtual Result SetTexels(int width, int height, int bitsPerTexel, void* pTexels, int pTexelsArePersistent) = 0; virtual void FillRowsOfTexture(int y, int height, void* pBuffer) = 0; // vtable+0x10 @@ -411,7 +411,7 @@ public: int* pDepth, void** ppBuffer, int* pPaletteSize, - PaletteEntry** ppPalette + unsigned char (*pEntries)[3] ) = 0; virtual Result SetPalette(int entryCount, PaletteEntry* pEntries) = 0;