Use SDL IOStream for WDB file

This commit is contained in:
Christian Semmler 2024-12-16 13:26:15 -07:00
parent b0357a79c1
commit e32e37ef26
5 changed files with 56 additions and 60 deletions

View File

@ -3,7 +3,7 @@
#include "legoentitypresenter.h" #include "legoentitypresenter.h"
#include <stdio.h> #include <SDL3/SDL_iostream.h>
class LegoWorld; class LegoWorld;
struct ModelDbPart; struct ModelDbPart;
@ -50,8 +50,8 @@ class LegoWorldPresenter : public LegoEntityPresenter {
// LegoWorldPresenter::`scalar deleting destructor' // LegoWorldPresenter::`scalar deleting destructor'
private: private:
MxResult FUN_10067360(ModelDbPart& p_part, FILE* p_wdbFile); MxResult FUN_10067360(ModelDbPart& p_part, SDL_IOStream* p_wdbFile);
MxResult FUN_100674b0(ModelDbModel& p_model, FILE* p_wdbFile, LegoWorld* p_world); MxResult FUN_100674b0(ModelDbModel& p_model, SDL_IOStream* p_wdbFile, LegoWorld* p_world);
undefined4 m_unk0x50; undefined4 m_unk0x50;
}; };

View File

@ -27,15 +27,13 @@
#include "mxstl/stlcompat.h" #include "mxstl/stlcompat.h"
#include "mxutilities.h" #include "mxutilities.h"
#include <io.h>
DECOMP_SIZE_ASSERT(LegoWorldPresenter, 0x54) DECOMP_SIZE_ASSERT(LegoWorldPresenter, 0x54)
// GLOBAL: LEGO1 0x100f75d4 // GLOBAL: LEGO1 0x100f75d4
MxS32 g_legoWorldPresenterQuality = 1; MxS32 g_legoWorldPresenterQuality = 1;
// GLOBAL: LEGO1 0x100f75d8 // GLOBAL: LEGO1 0x100f75d8
MxLong g_wdbOffset = 0; Sint64 g_wdbOffset = 0;
// FUNCTION: LEGO1 0x100665b0 // FUNCTION: LEGO1 0x100665b0
void LegoWorldPresenter::configureLegoWorldPresenter(MxS32 p_legoWorldPresenterQuality) void LegoWorldPresenter::configureLegoWorldPresenter(MxS32 p_legoWorldPresenterQuality)
@ -166,22 +164,26 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
char wdbPath[512]; char wdbPath[512];
sprintf(wdbPath, "%s", MxOmni::GetHD()); sprintf(wdbPath, "%s", MxOmni::GetHD());
if (wdbPath[strlen(wdbPath) - 1] != '\\') { if (wdbPath[strlen(wdbPath) - 1] != '\\' && wdbPath[strlen(wdbPath) - 1] != '/') {
strcat(wdbPath, "\\"); strcat(wdbPath, "\\");
} }
strcat(wdbPath, "lego\\data\\world.wdb"); strcat(wdbPath, "lego\\data\\world.wdb");
MxString::NormalizePath(wdbPath);
if (access(wdbPath, 4) != 0) { SDL_IOStream* wdbFile;
if ((wdbFile = SDL_IOFromFile(wdbPath, "rb")) == NULL) {
sprintf(wdbPath, "%s", MxOmni::GetCD()); sprintf(wdbPath, "%s", MxOmni::GetCD());
if (wdbPath[strlen(wdbPath) - 1] != '\\') { if (wdbPath[strlen(wdbPath) - 1] != '\\' && wdbPath[strlen(wdbPath) - 1] != '/') {
strcat(wdbPath, "\\"); strcat(wdbPath, "\\");
} }
strcat(wdbPath, "lego\\data\\world.wdb"); strcat(wdbPath, "lego\\data\\world.wdb");
MxString::NormalizePath(wdbPath);
if (access(wdbPath, 4) != 0) { if ((wdbFile = SDL_IOFromFile(wdbPath, "rb")) == NULL) {
return FAILURE; return FAILURE;
} }
} }
@ -190,11 +192,6 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
MxS32 numWorlds, i, j; MxS32 numWorlds, i, j;
MxU32 size; MxU32 size;
MxU8* buff; MxU8* buff;
FILE* wdbFile = fopen(wdbPath, "rb");
if (wdbFile == NULL) {
return FAILURE;
}
ReadModelDbWorlds(wdbFile, worlds, numWorlds); ReadModelDbWorlds(wdbFile, worlds, numWorlds);
@ -209,12 +206,12 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
} }
if (g_wdbOffset == 0) { if (g_wdbOffset == 0) {
if (fread(&size, sizeof(size), 1, wdbFile) != 1) { if (SDL_ReadIO(wdbFile, &size, sizeof(size)) != sizeof(size)) {
return FAILURE; return FAILURE;
} }
buff = new MxU8[size]; buff = new MxU8[size];
if (fread(buff, size, 1, wdbFile) != 1) { if (SDL_ReadIO(wdbFile, buff, size) != size) {
return FAILURE; return FAILURE;
} }
@ -229,12 +226,12 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
delete[] buff; delete[] buff;
if (fread(&size, sizeof(size), 1, wdbFile) != 1) { if (SDL_ReadIO(wdbFile, &size, sizeof(size)) != sizeof(size)) {
return FAILURE; return FAILURE;
} }
buff = new MxU8[size]; buff = new MxU8[size];
if (fread(buff, size, 1, wdbFile) != 1) { if (SDL_ReadIO(wdbFile, buff, size) != size) {
return FAILURE; return FAILURE;
} }
@ -248,10 +245,10 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
delete[] buff; delete[] buff;
g_wdbOffset = ftell(wdbFile); g_wdbOffset = SDL_TellIO(wdbFile);
} }
else { else {
if (fseek(wdbFile, g_wdbOffset, SEEK_SET) != 0) { if (SDL_SeekIO(wdbFile, g_wdbOffset, SDL_IO_SEEK_SET) != g_wdbOffset) {
return FAILURE; return FAILURE;
} }
} }
@ -309,18 +306,18 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world)
} }
FreeModelDbWorlds(worlds, numWorlds); FreeModelDbWorlds(worlds, numWorlds);
fclose(wdbFile); SDL_CloseIO(wdbFile);
return SUCCESS; return SUCCESS;
} }
// FUNCTION: LEGO1 0x10067360 // FUNCTION: LEGO1 0x10067360
MxResult LegoWorldPresenter::FUN_10067360(ModelDbPart& p_part, FILE* p_wdbFile) MxResult LegoWorldPresenter::FUN_10067360(ModelDbPart& p_part, SDL_IOStream* p_wdbFile)
{ {
MxResult result; MxResult result;
MxU8* buff = new MxU8[p_part.m_partDataLength]; MxU8* buff = new MxU8[p_part.m_partDataLength];
fseek(p_wdbFile, p_part.m_partDataOffset, 0); SDL_SeekIO(p_wdbFile, p_part.m_partDataOffset, SDL_IO_SEEK_SET);
if (fread(buff, p_part.m_partDataLength, 1, p_wdbFile) != 1) { if (SDL_ReadIO(p_wdbFile, buff, p_part.m_partDataLength) != p_part.m_partDataLength) {
return FAILURE; return FAILURE;
} }
@ -340,12 +337,12 @@ MxResult LegoWorldPresenter::FUN_10067360(ModelDbPart& p_part, FILE* p_wdbFile)
} }
// FUNCTION: LEGO1 0x100674b0 // FUNCTION: LEGO1 0x100674b0
MxResult LegoWorldPresenter::FUN_100674b0(ModelDbModel& p_model, FILE* p_wdbFile, LegoWorld* p_world) MxResult LegoWorldPresenter::FUN_100674b0(ModelDbModel& p_model, SDL_IOStream* p_wdbFile, LegoWorld* p_world)
{ {
MxU8* buff = new MxU8[p_model.m_unk0x04]; MxU8* buff = new MxU8[p_model.m_unk0x04];
fseek(p_wdbFile, p_model.m_unk0x08, 0); SDL_SeekIO(p_wdbFile, p_model.m_unk0x08, SDL_IO_SEEK_SET);
if (fread(buff, p_model.m_unk0x04, 1, p_wdbFile) != 1) { if (SDL_ReadIO(p_wdbFile, buff, p_model.m_unk0x04) != p_model.m_unk0x04) {
return FAILURE; return FAILURE;
} }

View File

@ -15,79 +15,81 @@ void ModelDbModel::Free()
} }
// FUNCTION: LEGO1 0x100276b0 // FUNCTION: LEGO1 0x100276b0
MxResult ModelDbModel::Read(FILE* p_file) MxResult ModelDbModel::Read(SDL_IOStream* p_file)
{ {
MxU32 len; MxU32 len;
if (fread(&len, sizeof(len), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &len, sizeof(len)) != sizeof(len)) {
return FAILURE; return FAILURE;
} }
m_modelName = new char[len]; m_modelName = new char[len];
if (fread(m_modelName, len, 1, p_file) != 1) { if (SDL_ReadIO(p_file, m_modelName, len) != len) {
return FAILURE; return FAILURE;
} }
if (fread(&m_unk0x04, sizeof(m_unk0x04), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &m_unk0x04, sizeof(m_unk0x04)) != sizeof(m_unk0x04)) {
return FAILURE; return FAILURE;
} }
if (fread(&m_unk0x08, sizeof(m_unk0x08), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &m_unk0x08, sizeof(m_unk0x08)) != sizeof(m_unk0x08)) {
return FAILURE; return FAILURE;
} }
if (fread(&len, sizeof(len), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &len, sizeof(len)) != sizeof(len)) {
return FAILURE; return FAILURE;
} }
m_presenterName = new char[len]; m_presenterName = new char[len];
if (fread(m_presenterName, len, 1, p_file) != 1) { if (SDL_ReadIO(p_file, m_presenterName, len) != len) {
return FAILURE; return FAILURE;
} }
if (fread(&m_location, sizeof(*m_location), 3, p_file) != 3) { if (SDL_ReadIO(p_file, m_location, sizeof(m_location)) != sizeof(m_location)) {
return FAILURE; return FAILURE;
} }
if (fread(&m_direction, sizeof(*m_direction), 3, p_file) != 3) { if (SDL_ReadIO(p_file, m_direction, sizeof(m_direction)) != sizeof(m_direction)) {
return FAILURE; return FAILURE;
} }
if (fread(&m_up, sizeof(*m_up), 3, p_file) != 3) { if (SDL_ReadIO(p_file, m_up, sizeof(m_up)) != sizeof(m_up)) {
return FAILURE; return FAILURE;
} }
return fread(&m_unk0x34, sizeof(m_unk0x34), 1, p_file) == 1 ? SUCCESS : FAILURE; return SDL_ReadIO(p_file, &m_unk0x34, sizeof(m_unk0x34)) == sizeof(m_unk0x34) ? SUCCESS : FAILURE;
} }
// FUNCTION: LEGO1 0x10027850 // FUNCTION: LEGO1 0x10027850
MxResult ModelDbPart::Read(FILE* p_file) MxResult ModelDbPart::Read(SDL_IOStream* p_file)
{ {
MxU32 len; MxU32 len;
char buff[128];
if (fread(&len, sizeof(len), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &len, sizeof(len)) != sizeof(len)) {
return FAILURE; return FAILURE;
} }
// (modernization) critical bug: buffer overrun char* buff = new char[len];
if (fread(buff, len, 1, p_file) != 1) {
if (SDL_ReadIO(p_file, buff, len) != len) {
return FAILURE; return FAILURE;
} }
m_roiName = buff; m_roiName = buff;
delete[] buff;
if (fread(&m_partDataLength, sizeof(m_partDataLength), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &m_partDataLength, sizeof(m_partDataLength)) != sizeof(m_partDataLength)) {
return FAILURE; return FAILURE;
} }
return fread(&m_partDataOffset, sizeof(m_partDataOffset), 1, p_file) == 1 ? SUCCESS : FAILURE; return SDL_ReadIO(p_file, &m_partDataOffset, sizeof(m_partDataOffset)) == sizeof(m_partDataOffset) ? SUCCESS
: FAILURE;
} }
// FUNCTION: LEGO1 0x10027910 // FUNCTION: LEGO1 0x10027910
MxResult ReadModelDbWorlds(FILE* p_file, ModelDbWorld*& p_worlds, MxS32& p_numWorlds) MxResult ReadModelDbWorlds(SDL_IOStream* p_file, ModelDbWorld*& p_worlds, MxS32& p_numWorlds)
{ {
p_worlds = NULL; p_worlds = NULL;
p_numWorlds = 0; p_numWorlds = 0;
MxS32 numWorlds; MxS32 numWorlds;
if (fread(&numWorlds, sizeof(numWorlds), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &numWorlds, sizeof(numWorlds)) != sizeof(numWorlds)) {
return FAILURE; return FAILURE;
} }
@ -95,16 +97,16 @@ MxResult ReadModelDbWorlds(FILE* p_file, ModelDbWorld*& p_worlds, MxS32& p_numWo
MxS32 worldNameLen, numParts, i, j; MxS32 worldNameLen, numParts, i, j;
for (i = 0; i < numWorlds; i++) { for (i = 0; i < numWorlds; i++) {
if (fread(&worldNameLen, sizeof(worldNameLen), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &worldNameLen, sizeof(worldNameLen)) != sizeof(worldNameLen)) {
return FAILURE; return FAILURE;
} }
worlds[i].m_worldName = new char[worldNameLen]; worlds[i].m_worldName = new char[worldNameLen];
if (fread(worlds[i].m_worldName, worldNameLen, 1, p_file) != 1) { if (SDL_ReadIO(p_file, worlds[i].m_worldName, worldNameLen) != worldNameLen) {
return FAILURE; return FAILURE;
} }
if (fread(&numParts, sizeof(numParts), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &numParts, sizeof(numParts)) != sizeof(numParts)) {
return FAILURE; return FAILURE;
} }
@ -120,7 +122,8 @@ MxResult ReadModelDbWorlds(FILE* p_file, ModelDbWorld*& p_worlds, MxS32& p_numWo
worlds[i].m_partList->Append(part); worlds[i].m_partList->Append(part);
} }
if (fread(&worlds[i].m_numModels, sizeof(worlds[i].m_numModels), 1, p_file) != 1) { if (SDL_ReadIO(p_file, &worlds[i].m_numModels, sizeof(worlds[i].m_numModels)) !=
sizeof(worlds[i].m_numModels)) {
return FAILURE; return FAILURE;
} }

View File

@ -6,11 +6,11 @@
#include "mxstring.h" #include "mxstring.h"
#include "mxtypes.h" #include "mxtypes.h"
#include <stdio.h> #include <SDL3/SDL_iostream.h>
// SIZE 0x18 // SIZE 0x18
struct ModelDbPart { struct ModelDbPart {
MxResult Read(FILE* p_file); MxResult Read(SDL_IOStream* p_file);
MxString m_roiName; // 0x00 MxString m_roiName; // 0x00
undefined4 m_partDataLength; // 0x10 undefined4 m_partDataLength; // 0x10
@ -92,7 +92,7 @@ class ModelDbPartListCursor : public MxListCursor<ModelDbPart*> {
// SIZE 0x38 // SIZE 0x38
struct ModelDbModel { struct ModelDbModel {
void Free(); void Free();
MxResult Read(FILE* p_file); MxResult Read(SDL_IOStream* p_file);
char* m_modelName; // 0x00 char* m_modelName; // 0x00
undefined4 m_unk0x04; // 0x04 undefined4 m_unk0x04; // 0x04
@ -113,7 +113,7 @@ struct ModelDbWorld {
undefined m_unk0x10[0x08]; // 0x10 undefined m_unk0x10[0x08]; // 0x10
}; };
MxResult ReadModelDbWorlds(FILE* p_file, ModelDbWorld*& p_worlds, MxS32& p_numWorlds); MxResult ReadModelDbWorlds(SDL_IOStream* p_file, ModelDbWorld*& p_worlds, MxS32& p_numWorlds);
void FreeModelDbWorlds(ModelDbWorld*& p_worlds, MxS32 p_numWorlds); void FreeModelDbWorlds(ModelDbWorld*& p_worlds, MxS32 p_numWorlds);
#endif // MODELDB_H #endif // MODELDB_H

View File

@ -33,10 +33,6 @@ MXIOINFO::~MXIOINFO()
// FUNCTION: BETA10 0x1015e189 // FUNCTION: BETA10 0x1015e189
MxU16 MXIOINFO::Open(const char* p_filename, MxULong p_flags) MxU16 MXIOINFO::Open(const char* p_filename, MxULong p_flags)
{ {
OutputDebugString("OPENING -> ");
OutputDebugString(p_filename);
OutputDebugString("\n");
// [library:filesystem] p_flags is always 0 (OF_READ) // [library:filesystem] p_flags is always 0 (OF_READ)
assert(p_flags == 0); assert(p_flags == 0);