Implement TextureData::Create (#586)

* Implement TextureData::Create

* Fix names

* Rename

* Fix name

* Fix annotation

* Add missing annotation

* Fix annotation

* More annotation fixes

* Compat template type ambiguity

* Fix
This commit is contained in:
Christian Semmler
2024-02-22 16:59:44 -05:00
committed by GitHub
parent 688dc0b6ee
commit 9d8820ee06
13 changed files with 422 additions and 259 deletions

View File

@@ -1,62 +0,0 @@
#include "gifmanager.h"
DECOMP_SIZE_ASSERT(GifData, 0x14);
DECOMP_SIZE_ASSERT(GifMap, 0x10);
DECOMP_SIZE_ASSERT(GifManagerBase, 0x18);
DECOMP_SIZE_ASSERT(GifManager, 0x24);
// FUNCTION: LEGO1 0x10065c00
GifData::~GifData()
{
if (m_name) {
delete[] m_name;
m_name = NULL;
}
if (m_palette) {
m_palette->Release();
m_palette = NULL;
}
if (m_surface) {
m_surface->Release();
m_surface = NULL;
}
if (m_texture) {
m_texture->Release();
m_texture = NULL;
}
}
// FUNCTION: LEGO1 0x10099870
GifManager::~GifManager()
{
}
// FUNCTION: LEGO1 0x10099cc0
void GifManager::FUN_10099cc0(GifData* p_data)
{
if (p_data == NULL) {
return;
}
#ifdef COMPAT_MODE
GifList::iterator it;
for (it = m_list.begin(); it != m_list.end(); it++) {
#else
for (GifList::iterator it = m_list.begin(); it != m_list.end(); it++) {
#endif
if (*it == p_data) {
// TODO: This is wrong, but what is at +0x0c on the iterator?
*it = NULL;
if (p_data->m_texture->Release() == TRUE) {
delete p_data;
m_list.erase(it);
}
return;
}
}
}

View File

@@ -0,0 +1,188 @@
#include "legocontainer.h"
#include "lego/sources/misc/legoimage.h"
#include "lego/sources/misc/legotexture.h"
#include "legoomni.h"
#include "legovideomanager.h"
#include "tgl/d3drm/impl.h"
DECOMP_SIZE_ASSERT(TextureData, 0x10);
DECOMP_SIZE_ASSERT(LegoContainerInfo<LegoTexture>, 0x10);
// DECOMP_SIZE_ASSERT(LegoContainer<LegoTexture>, 0x18);
DECOMP_SIZE_ASSERT(LegoTextureContainer, 0x24);
// FUNCTION: LEGO1 0x10065bf0
TextureData::TextureData()
{
m_name = NULL;
m_surface = NULL;
m_palette = NULL;
m_texture = NULL;
}
// FUNCTION: LEGO1 0x10065c00
TextureData::~TextureData()
{
if (m_name) {
delete[] m_name;
m_name = NULL;
}
if (m_palette) {
m_palette->Release();
m_palette = NULL;
}
if (m_surface) {
m_surface->Release();
m_surface = NULL;
}
if (m_texture) {
m_texture->Release();
m_texture = NULL;
}
}
// FUNCTION: LEGO1 0x10065c60
TextureData* TextureData::Create(const char* p_name, LegoTexture* p_texture)
{
TextureData* texture = new TextureData();
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);
}
LPDIRECTDRAW pDirectDraw = VideoManager()->GetDirect3D()->DirectDraw();
LegoImage* image = p_texture->GetImage();
DDSURFACEDESC desc;
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
desc.dwWidth = image->GetWidth();
desc.dwHeight = image->GetHeight();
desc.ddsCaps.dwCaps = DDCAPS_OVERLAYCANTCLIP | DDCAPS_OVERLAY;
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
desc.ddpfPixelFormat.dwRGBBitCount = 8;
MxS32 i;
LegoU8* bits;
MxU8* surface;
if (pDirectDraw->CreateSurface(&desc, &texture->m_surface, NULL) != DD_OK) {
goto done;
}
bits = image->GetBits();
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
if (texture->m_surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR, NULL) != DD_OK) {
goto done;
}
surface = (MxU8*) desc.lpSurface;
if (desc.dwWidth == desc.lPitch) {
memcpy(surface, bits, desc.dwWidth * desc.dwHeight);
}
else {
for (i = 0; i < desc.dwHeight; i++) {
*(MxU32*) surface = *(MxU32*) bits;
surface += desc.lPitch;
bits += desc.dwWidth;
}
}
texture->m_surface->Unlock(desc.lpSurface);
PALETTEENTRY entries[256];
memset(entries, 0, sizeof(entries));
for (i = 0; i < _countof(entries); i++) {
if (i < image->GetCount()) {
entries[i].peFlags = 0;
entries[i].peRed = image->GetPaletteEntry(i).GetRed();
entries[i].peGreen = image->GetPaletteEntry(i).GetGreen();
entries[i].peBlue = image->GetPaletteEntry(i).GetBlue();
}
else {
entries[i].peFlags = 0x80;
}
}
if (pDirectDraw->CreatePalette(DDPCAPS_ALLOW256 | DDPCAPS_8BIT, entries, &texture->m_palette, NULL) != DD_OK) {
goto done;
}
texture->m_surface->SetPalette(texture->m_palette);
if (((TglImpl::RendererImpl*) VideoManager()->GetRenderer())
->CreateTextureFromSurface(texture->m_surface, &texture->m_texture) != D3DRM_OK) {
goto done;
}
texture->m_texture->SetAppData((DWORD) texture);
return texture;
done:
if (texture->m_name != NULL) {
delete[] texture->m_name;
texture->m_name = NULL;
}
if (texture->m_palette != NULL) {
texture->m_palette->Release();
texture->m_palette = NULL;
}
if (texture->m_surface != NULL) {
texture->m_surface->Release();
texture->m_surface = NULL;
}
if (texture != NULL) {
delete texture;
}
return NULL;
}
// FUNCTION: LEGO1 0x10099870
LegoTextureContainer::~LegoTextureContainer()
{
}
// FUNCTION: LEGO1 0x10099cc0
void LegoTextureContainer::FUN_10099cc0(TextureData* p_data)
{
if (p_data == NULL) {
return;
}
#ifdef COMPAT_MODE
TextureList::iterator it;
for (it = m_list.begin(); it != m_list.end(); it++) {
#else
for (TextureList::iterator it = m_list.begin(); it != m_list.end(); it++) {
#endif
if (*it == p_data) {
// TODO: This is wrong, but what is at +0x0c on the iterator?
*it = NULL;
if (p_data->m_texture->Release() == TRUE) {
delete p_data;
m_list.erase(it);
}
return;
}
}
}

View File

@@ -1,8 +1,8 @@
#include "score.h"
#include "ambulancemissionstate.h"
#include "gifmanager.h"
#include "jukebox.h"
#include "legocontainer.h"
#include "legocontrolmanager.h"
#include "legogamestate.h"
#include "legoinputmanager.h"
@@ -233,7 +233,7 @@ void Score::Enable(MxBool p_enable)
// FUNCTION: LEGO1 0x100019d0
void Score::Paint()
{
GifData* gd = GetGifManager()->Get("bigcube.gif");
TextureData* gd = GetTextureContainer()->Get("bigcube.gif");
if (gd) {
RaceState* l78 = (RaceState*) GameState()->GetState("JetskiRaceState");

View File

@@ -1,8 +1,8 @@
#include "legoomni.h"
#include "gifmanager.h"
#include "legoanimationmanager.h"
#include "legobuildingmanager.h"
#include "legocontainer.h"
#include "legogamestate.h"
#include "legoinputmanager.h"
#include "legoobjectfactory.h"
@@ -215,9 +215,9 @@ LegoBuildingManager* BuildingManager()
}
// FUNCTION: LEGO1 0x10015800
GifManager* GetGifManager()
LegoTextureContainer* GetTextureContainer()
{
return LegoOmni::GetInstance()->GetGifManager();
return LegoOmni::GetInstance()->GetTextureContainer();
}
// FUNCTION: LEGO1 0x10015820
@@ -466,9 +466,9 @@ void LegoOmni::Init()
{
MxOmni::Init();
m_scripts = NULL;
m_inputMgr = NULL;
m_inputManager = NULL;
m_viewLODListManager = NULL;
m_gifManager = NULL;
m_textureContainer = NULL;
m_worldList = NULL;
m_currentWorld = NULL;
m_exit = FALSE;
@@ -520,9 +520,9 @@ void LegoOmni::Destroy()
m_buildingManager = NULL;
}
if (m_gifManager) {
delete m_gifManager;
m_gifManager = NULL;
if (m_textureContainer) {
delete m_textureContainer;
m_textureContainer = NULL;
}
if (m_viewLODListManager) {
@@ -530,14 +530,14 @@ void LegoOmni::Destroy()
m_viewLODListManager = NULL;
}
if (m_inputMgr) {
delete m_inputMgr;
m_inputMgr = NULL;
if (m_inputManager) {
delete m_inputManager;
m_inputManager = NULL;
}
if (m_inputMgr) {
delete m_inputMgr;
m_inputMgr = NULL;
if (m_inputManager) {
delete m_inputManager;
m_inputManager = NULL;
}
// todo FUN_10046de0
@@ -598,15 +598,15 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
goto done;
}
if (!(m_inputMgr = new LegoInputManager()) || m_inputMgr->Create(p_param.GetWindowHandle()) != SUCCESS) {
delete m_inputMgr;
m_inputMgr = NULL;
if (!(m_inputManager = new LegoInputManager()) || m_inputManager->Create(p_param.GetWindowHandle()) != SUCCESS) {
delete m_inputManager;
m_inputManager = NULL;
goto done;
}
m_viewLODListManager = new ViewLODListManager();
m_gifManager = new GifManager();
m_gifManager->SetOwnership(FALSE);
m_textureContainer = new LegoTextureContainer();
m_textureContainer->SetOwnership(FALSE);
// FUN_10046c10
m_saveDataWriter = new LegoUnkSaveDataWriter();
@@ -616,7 +616,7 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param)
m_gameState = new LegoGameState();
m_worldList = new LegoWorldList(TRUE);
if (!m_viewLODListManager || !m_gifManager || !m_worldList || !m_saveDataWriter || !m_plantManager ||
if (!m_viewLODListManager || !m_textureContainer || !m_worldList || !m_saveDataWriter || !m_plantManager ||
!m_animationManager || !m_buildingManager) {
goto done;
}
@@ -900,7 +900,7 @@ void LegoOmni::FUN_1005b4f0(MxBool p_disable, MxU16 p_flags)
{
if (p_disable) {
if (p_flags & c_disableInput) {
m_inputMgr->DisableInputProcessing();
m_inputManager->DisableInputProcessing();
}
if (p_flags & c_disable3d) {
@@ -912,7 +912,7 @@ void LegoOmni::FUN_1005b4f0(MxBool p_disable, MxU16 p_flags)
}
}
else {
m_inputMgr->EnableInputProcessing();
m_inputManager->EnableInputProcessing();
((LegoVideoManager*) m_videoManager)->SetRender3D(TRUE);
((LegoVideoManager*) m_videoManager)->UpdateView(0, 0, 0, 0);
}

View File

@@ -57,33 +57,45 @@ void LegoAnimPresenter::Destroy(MxBool p_fromDestructor)
MxResult LegoAnimPresenter::VTable0x88(MxStreamChunk* p_chunk)
{
MxResult result = FAILURE;
LegoMemory stream((char*) p_chunk->GetData());
LegoMemory storage(p_chunk->GetData());
MxS32 magicSig;
MxS32 val2 = 0;
LegoS32 parseScene = 0;
MxS32 val3;
if (stream.Read(&magicSig, sizeof(MxS32)) == SUCCESS && magicSig == 0x11) {
if (stream.Read(&m_unk0xa4, sizeof(MxU32)) == SUCCESS) {
if (stream.Read(&m_unk0xa8[0], sizeof(float)) == SUCCESS) {
if (stream.Read(&m_unk0xa8[1], sizeof(float)) == SUCCESS) {
if (stream.Read(&m_unk0xa8[2], sizeof(float)) == SUCCESS) {
if (stream.Read(&val2, sizeof(MxS32)) == SUCCESS) {
if (stream.Read(&val3, sizeof(MxS32)) == SUCCESS) {
m_anim = new LegoAnim();
if (m_anim) {
if (m_anim->Read(&stream, val2) == SUCCESS) {
result = SUCCESS;
}
}
}
}
}
}
}
}
if (storage.Read(&magicSig, sizeof(magicSig)) != SUCCESS || magicSig != 0x11) {
goto done;
}
if (storage.Read(&m_unk0xa4, sizeof(m_unk0xa4)) != SUCCESS) {
goto done;
}
if (storage.Read(&m_unk0xa8[0], sizeof(m_unk0xa8[0])) != SUCCESS) {
goto done;
}
if (storage.Read(&m_unk0xa8[1], sizeof(m_unk0xa8[1])) != SUCCESS) {
goto done;
}
if (storage.Read(&m_unk0xa8[2], sizeof(m_unk0xa8[2])) != SUCCESS) {
goto done;
}
if (storage.Read(&parseScene, sizeof(parseScene)) != SUCCESS) {
goto done;
}
if (storage.Read(&val3, sizeof(val3)) != SUCCESS) {
goto done;
}
m_anim = new LegoAnim();
if (!m_anim) {
goto done;
}
if (m_anim->Read(&storage, parseScene) != SUCCESS) {
goto done;
}
result = SUCCESS;
done:
if (result != SUCCESS) {
delete m_anim;
Init();