From 9d0ff0425c18851cd698e8ec1643004adc5a2353 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 23 Feb 2024 12:54:45 -0500 Subject: [PATCH] Implement LegoTextureContainer::Insert (#589) * WIP * Fix * Fix * Match * Match --- CMakeLists.txt | 2 +- .../legoomni/src/common/legotextureinfo.cpp | 44 +++---- LEGO1/lego/sources/misc/legocontainer.cpp | 111 ++++++++++++++++-- LEGO1/lego/sources/misc/legocontainer.h | 10 +- 4 files changed, 130 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91e85359..87e23acb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,7 +164,7 @@ add_library(misc STATIC ) register_lego1_target(misc) set_property(TARGET misc PROPERTY ARCHIVE_OUTPUT_NAME "misc$<$:d>") -target_include_directories(misc PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1/omni/include" "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE_SOURCE_DIR}/util") +target_include_directories(misc PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1/omni/include" "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE_SOURCE_DIR}/LEGO1/lego/sources" "${CMAKE_SOURCE_DIR}/util") target_link_libraries(misc PRIVATE) add_library(3dmanager STATIC diff --git a/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp b/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp index 84c587cf..539c1f48 100644 --- a/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp +++ b/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp @@ -44,15 +44,15 @@ LegoTextureInfo::~LegoTextureInfo() // FUNCTION: LEGO1 0x10065c60 LegoTextureInfo* LegoTextureInfo::Create(const char* p_name, LegoTexture* p_texture) { - LegoTextureInfo* texture = new LegoTextureInfo(); + LegoTextureInfo* textureInfo = new LegoTextureInfo(); if (p_name == NULL || p_texture == NULL) { return NULL; } if (p_name) { - texture->m_name = new char[strlen(p_name) + 1]; - strcpy(texture->m_name, p_name); + textureInfo->m_name = new char[strlen(p_name) + 1]; + strcpy(textureInfo->m_name, p_name); } LPDIRECTDRAW pDirectDraw = VideoManager()->GetDirect3D()->DirectDraw(); @@ -73,7 +73,7 @@ LegoTextureInfo* LegoTextureInfo::Create(const char* p_name, LegoTexture* p_text LegoU8* bits; MxU8* surface; - if (pDirectDraw->CreateSurface(&desc, &texture->m_surface, NULL) != DD_OK) { + if (pDirectDraw->CreateSurface(&desc, &textureInfo->m_surface, NULL) != DD_OK) { goto done; } @@ -82,7 +82,7 @@ LegoTextureInfo* LegoTextureInfo::Create(const char* p_name, LegoTexture* p_text memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); - if (texture->m_surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR, NULL) != DD_OK) { + if (textureInfo->m_surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR, NULL) != DD_OK) { goto done; } @@ -98,7 +98,7 @@ LegoTextureInfo* LegoTextureInfo::Create(const char* p_name, LegoTexture* p_text } } - texture->m_surface->Unlock(desc.lpSurface); + textureInfo->m_surface->Unlock(desc.lpSurface); PALETTEENTRY entries[256]; memset(entries, 0, sizeof(entries)); @@ -115,38 +115,38 @@ LegoTextureInfo* LegoTextureInfo::Create(const char* p_name, LegoTexture* p_text } } - if (pDirectDraw->CreatePalette(DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &texture->m_palette, NULL) != DD_OK) { + if (pDirectDraw->CreatePalette(DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &textureInfo->m_palette, NULL) != DD_OK) { goto done; } - texture->m_surface->SetPalette(texture->m_palette); + textureInfo->m_surface->SetPalette(textureInfo->m_palette); if (((TglImpl::RendererImpl*) VideoManager()->GetRenderer()) - ->CreateTextureFromSurface(texture->m_surface, &texture->m_texture) != D3DRM_OK) { + ->CreateTextureFromSurface(textureInfo->m_surface, &textureInfo->m_texture) != D3DRM_OK) { goto done; } - texture->m_texture->SetAppData((DWORD) texture); - return texture; + textureInfo->m_texture->SetAppData((DWORD) textureInfo); + return textureInfo; done: - if (texture->m_name != NULL) { - delete[] texture->m_name; - texture->m_name = NULL; + if (textureInfo->m_name != NULL) { + delete[] textureInfo->m_name; + textureInfo->m_name = NULL; } - if (texture->m_palette != NULL) { - texture->m_palette->Release(); - texture->m_palette = NULL; + if (textureInfo->m_palette != NULL) { + textureInfo->m_palette->Release(); + textureInfo->m_palette = NULL; } - if (texture->m_surface != NULL) { - texture->m_surface->Release(); - texture->m_surface = NULL; + if (textureInfo->m_surface != NULL) { + textureInfo->m_surface->Release(); + textureInfo->m_surface = NULL; } - if (texture != NULL) { - delete texture; + if (textureInfo != NULL) { + delete textureInfo; } return NULL; diff --git a/LEGO1/lego/sources/misc/legocontainer.cpp b/LEGO1/lego/sources/misc/legocontainer.cpp index 75efabfb..aebfc96d 100644 --- a/LEGO1/lego/sources/misc/legocontainer.cpp +++ b/LEGO1/lego/sources/misc/legocontainer.cpp @@ -1,5 +1,9 @@ #include "legocontainer.h" +#include "lego/legoomni/include/legoomni.h" +#include "lego/legoomni/include/legovideomanager.h" +#include "tgl/d3drm/impl.h" + DECOMP_SIZE_ASSERT(LegoContainerInfo, 0x10); // DECOMP_SIZE_ASSERT(LegoContainer, 0x18); DECOMP_SIZE_ASSERT(LegoTextureContainer, 0x24); @@ -9,16 +13,106 @@ LegoTextureContainer::~LegoTextureContainer() { } -// STUB: LEGO1 0x100998e0 -LegoTextureInfo* LegoTextureContainer::Create(undefined* p_und) +// FUNCTION: LEGO1 0x100998e0 +LegoTextureInfo* LegoTextureContainer::Insert(LegoTextureInfo* p_textureInfo) { + DDSURFACEDESC desc, newDesc; + DWORD width, height; + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + if (p_textureInfo->m_surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR, NULL) == DD_OK) { + width = desc.dwWidth; + height = desc.dwHeight; + p_textureInfo->m_surface->Unlock(desc.lpSurface); + } + + for (LegoTextureList::iterator it = m_list.begin(); it != m_list.end(); it++) { + if ((*it).second == FALSE && (*it).first->m_texture->AddRef() != 0 && (*it).first->m_texture->Release() == 1) { + if (!strcmp((*it).first->m_name, p_textureInfo->m_name)) { + memset(&newDesc, 0, sizeof(newDesc)); + newDesc.dwSize = sizeof(newDesc); + + if ((*it).first->m_surface->Lock(NULL, &newDesc, DDLOCK_SURFACEMEMORYPTR, NULL) == DD_OK) { + BOOL und = FALSE; + if (newDesc.dwWidth == width && newDesc.dwHeight == height) { + und = TRUE; + } + + (*it).first->m_surface->Unlock(newDesc.lpSurface); + + if (und) { + (*it).second = TRUE; + (*it).first->m_texture->AddRef(); + return (*it).first; + } + } + } + } + } + + LegoTextureInfo* textureInfo = new LegoTextureInfo(); + + textureInfo->m_palette = p_textureInfo->m_palette; + p_textureInfo->m_palette->Release(); + + memset(&newDesc, 0, sizeof(newDesc)); + newDesc.dwWidth = desc.dwWidth; + newDesc.dwHeight = desc.dwHeight; + newDesc.dwSize = sizeof(newDesc); + newDesc.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + newDesc.ddsCaps.dwCaps = DDCAPS_OVERLAYCANTCLIP | DDCAPS_OVERLAY; + newDesc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat); + newDesc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8; + newDesc.ddpfPixelFormat.dwRGBBitCount = 8; + + if (VideoManager()->GetDirect3D()->DirectDraw()->CreateSurface(&newDesc, &textureInfo->m_surface, NULL) == DD_OK) { + RECT rect; + rect.left = 0; + rect.top = newDesc.dwWidth - 1; + rect.right = 0; + rect.bottom = newDesc.dwHeight - 1; + + textureInfo->m_surface->SetPalette(textureInfo->m_palette); + + if (textureInfo->m_surface->BltFast(0, 0, p_textureInfo->m_surface, &rect, DDBLTFAST_WAIT) != DD_OK) { + textureInfo->m_surface->Release(); + textureInfo->m_palette->Release(); + delete textureInfo; + return NULL; + } + else { + if (((TglImpl::RendererImpl*) VideoManager()->GetRenderer()) + ->CreateTextureFromSurface(textureInfo->m_surface, &textureInfo->m_texture) != D3DRM_OK) { + textureInfo->m_surface->Release(); + textureInfo->m_palette->Release(); + delete textureInfo; + return NULL; + } + else { + textureInfo->m_texture->SetAppData((DWORD) textureInfo); + m_list.push_back(LegoTextureListElement(textureInfo, TRUE)); + + textureInfo->m_texture->AddRef(); + + if (textureInfo->m_name != NULL) { + delete[] textureInfo->m_name; + } + + textureInfo->m_name = new char[strlen(p_textureInfo->m_name) + 1]; + strcpy(textureInfo->m_name, p_textureInfo->m_name); + return textureInfo; + } + } + } + return NULL; } // FUNCTION: LEGO1 0x10099cc0 -void LegoTextureContainer::Destroy(LegoTextureInfo* p_data) +void LegoTextureContainer::Erase(LegoTextureInfo* p_textureInfo) { - if (p_data == NULL) { + if (p_textureInfo == NULL) { return; } @@ -28,12 +122,11 @@ void LegoTextureContainer::Destroy(LegoTextureInfo* p_data) #else for (LegoTextureList::iterator it = m_list.begin(); it != m_list.end(); it++) { #endif - if (((*it).first) == p_data) { - // TODO: Element type - (*it).second = 0; + if ((*it).first == p_textureInfo) { + (*it).second = FALSE; - if (p_data->m_texture->Release() == TRUE) { - delete p_data; + if (p_textureInfo->m_texture->Release() == TRUE) { + delete p_textureInfo; m_list.erase(it); } diff --git a/LEGO1/lego/sources/misc/legocontainer.h b/LEGO1/lego/sources/misc/legocontainer.h index a4c2b148..89bdaea9 100644 --- a/LEGO1/lego/sources/misc/legocontainer.h +++ b/LEGO1/lego/sources/misc/legocontainer.h @@ -67,7 +67,7 @@ class LegoContainer { // class LegoContainer // TODO: Element type -typedef pair LegoTextureListElement; +typedef pair LegoTextureListElement; typedef list LegoTextureList; // VTABLE: LEGO1 0x100d86fc @@ -77,8 +77,8 @@ class LegoTextureContainer : public LegoContainer { LegoTextureContainer() { m_ownership = TRUE; } ~LegoTextureContainer() override; - LegoTextureInfo* Create(undefined* p_und); - void Destroy(LegoTextureInfo* p_data); + LegoTextureInfo* Insert(LegoTextureInfo* p_textureInfo); + void Erase(LegoTextureInfo* p_textureInfo); protected: LegoTextureList m_list; // 0x18 @@ -119,7 +119,7 @@ class LegoTextureContainer : public LegoContainer { // _Tree,map >::_Kfn,LegoContainerInfoComparator,allocator >::_Erase // TEMPLATE: LEGO1 0x1005a250 -// list,allocator > >::~list,allocator > > +// list,allocator > >::~list,allocator > > // TEMPLATE: LEGO1 0x1005a2c0 // map >::~map > @@ -137,7 +137,7 @@ class LegoTextureContainer : public LegoContainer { // LegoTextureContainer::`scalar deleting destructor' // TEMPLATE: LEGO1 0x1005a5a0 -// List >::~List > +// List >::~List > // TEMPLATE: LEGO1 0x1005b660 // LegoContainer::~LegoContainer