diff --git a/LEGO1/tgl/d3drm/impl.h b/LEGO1/tgl/d3drm/impl.h index fe79e01b..4c304278 100644 --- a/LEGO1/tgl/d3drm/impl.h +++ b/LEGO1/tgl/d3drm/impl.h @@ -636,7 +636,7 @@ class TextureImpl : public Texture { 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 +647,7 @@ class TextureImpl : public Texture { 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..1ca1bf3a 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()); @@ -86,6 +89,7 @@ void TglD3DRMIMAGE::Destroy() delete m_image.palette; } +// FUNCTION: BETA10 0x101699a0 inline static int IsPowerOfTwo(int v) { int m = 0; @@ -99,16 +103,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 +129,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 +143,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 @@ -163,64 +183,142 @@ Result TglD3DRMIMAGE::InitializePalette(int paletteSize, PaletteEntry* pEntries) 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 @@ class MeshBuilder : public Object { 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 @@ class Texture : public Object { int* pDepth, void** ppBuffer, int* pPaletteSize, - PaletteEntry** ppPalette + unsigned char (*pEntries)[3] ) = 0; virtual Result SetPalette(int entryCount, PaletteEntry* pEntries) = 0;