feat: Implement several ::Serialize functions (#1017)

* feat: Implement many ::Serialize functions

* address review comments, part 1 [skip ci]

* address review comments, part 2 [skip ci]

* review comments (final part)

* refactor: Remove Read/Write duplication

* fix merge conflict

* Match PizzeriaState::Serialize again

* Remove unused variable, add LegoVehicleBuildState::Serialize

* Implement AnimState::Serialize

* fix: Conform with naming scheme

* refactor: change names back

* refactor: int to MxS32

---------

Co-authored-by: jonschz <jonschz@users.noreply.github.com>
This commit is contained in:
jonschz
2024-06-14 23:24:34 +02:00
committed by GitHub
parent 165785c434
commit a6644801f1
23 changed files with 335 additions and 168 deletions

View File

@@ -642,9 +642,35 @@ AmbulanceMissionState::AmbulanceMissionState()
m_laHighScore = 0;
}
// STUB: LEGO1 0x10037440
MxResult AmbulanceMissionState::Serialize(LegoFile* p_legoFile)
// FUNCTION: LEGO1 0x10037440
MxResult AmbulanceMissionState::Serialize(LegoFile* p_file)
{
// TODO
return LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
if (p_file->IsReadMode()) {
Read(p_file, &m_peScore);
Read(p_file, &m_maScore);
Read(p_file, &m_paScore);
Read(p_file, &m_niScore);
Read(p_file, &m_laScore);
Read(p_file, &m_peHighScore);
Read(p_file, &m_maHighScore);
Read(p_file, &m_paHighScore);
Read(p_file, &m_niHighScore);
Read(p_file, &m_laHighScore);
}
else if (p_file->IsWriteMode()) {
Write(p_file, m_peScore);
Write(p_file, m_maScore);
Write(p_file, m_paScore);
Write(p_file, m_niScore);
Write(p_file, m_laScore);
Write(p_file, m_peHighScore);
Write(p_file, m_maHighScore);
Write(p_file, m_paHighScore);
Write(p_file, m_niHighScore);
Write(p_file, m_laHighScore);
}
return SUCCESS;
}

View File

@@ -105,11 +105,23 @@ PizzaMissionState::PizzaMissionState()
// TODO
}
// STUB: LEGO1 0x100393c0
MxResult PizzaMissionState::Serialize(LegoFile* p_legoFile)
// FUNCTION: LEGO1 0x100393c0
MxResult PizzaMissionState::Serialize(LegoFile* p_file)
{
// TODO
return LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
if (p_file->IsReadMode()) {
for (MxS16 i = 0; i < 5; i++) {
m_state[i].ReadFromFile(p_file);
}
}
else if (p_file->IsWriteMode()) {
for (MxS16 i = 0; i < 5; i++) {
m_state[i].WriteToFile(p_file);
}
}
return SUCCESS;
}
// FUNCTION: LEGO1 0x10039510

View File

@@ -76,9 +76,22 @@ MxU32 PizzeriaState::FUN_10017d70()
return 0;
}
// STUB: LEGO1 0x10017da0
MxResult PizzeriaState::Serialize(LegoFile* p_legoFile)
// FUNCTION: LEGO1 0x10017da0
// FUNCTION: BETA10 0x100efe33
MxResult PizzeriaState::Serialize(LegoFile* p_file)
{
// TODO
return LegoState::Serialize(p_legoFile);
MxResult res = LegoState::Serialize(p_file);
if (p_file->IsReadMode()) {
for (MxS16 i = 0; i < 5; i++) {
m_unk0x08[i].ReadFromFile(p_file);
}
}
else {
for (MxS16 i = 0; i < 5; i++) {
m_unk0x08[i].WriteToFile(p_file);
}
}
return res;
}

View File

@@ -158,52 +158,33 @@ TowTrackMissionState::TowTrackMissionState()
}
// FUNCTION: LEGO1 0x1004dde0
MxResult TowTrackMissionState::Serialize(LegoFile* p_legoFile)
MxResult TowTrackMissionState::Serialize(LegoFile* p_file)
{
LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
if (p_legoFile->IsReadMode()) {
p_legoFile->Read(&m_unk0x12, sizeof(m_unk0x12));
p_legoFile->Read(&m_unk0x14, sizeof(m_unk0x14));
p_legoFile->Read(&m_unk0x16, sizeof(m_unk0x16));
p_legoFile->Read(&m_unk0x18, sizeof(m_unk0x18));
p_legoFile->Read(&m_unk0x1a, sizeof(m_unk0x1a));
p_legoFile->Read(&m_score1, sizeof(m_score1));
p_legoFile->Read(&m_score2, sizeof(m_score2));
p_legoFile->Read(&m_score3, sizeof(m_score3));
p_legoFile->Read(&m_score4, sizeof(m_score4));
p_legoFile->Read(&m_score5, sizeof(m_score5));
if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x12);
Read(p_file, &m_unk0x14);
Read(p_file, &m_unk0x16);
Read(p_file, &m_unk0x18);
Read(p_file, &m_unk0x1a);
Read(p_file, &m_score1);
Read(p_file, &m_score2);
Read(p_file, &m_score3);
Read(p_file, &m_score4);
Read(p_file, &m_score5);
}
else if (p_legoFile->IsWriteMode()) {
MxU16 write = m_unk0x12;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_unk0x14;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_unk0x16;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_unk0x18;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_unk0x1a;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_score1;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_score2;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_score3;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_score4;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_score5;
p_legoFile->Write(&write, sizeof(m_unk0x12));
else if (p_file->IsWriteMode()) {
Write(p_file, m_unk0x12);
Write(p_file, m_unk0x14);
Write(p_file, m_unk0x16);
Write(p_file, m_unk0x18);
Write(p_file, m_unk0x1a);
Write(p_file, m_score1);
Write(p_file, m_score2);
Write(p_file, m_score3);
Write(p_file, m_score4);
Write(p_file, m_score5);
}
return SUCCESS;

View File

@@ -73,9 +73,23 @@ LegoVehicleBuildState::LegoVehicleBuildState(const char* p_classType)
m_placedPartCount = 0;
}
// STUB: LEGO1 0x10026120
MxResult LegoVehicleBuildState::Serialize(LegoFile* p_legoFile)
// FUNCTION: LEGO1 0x10026120
MxResult LegoVehicleBuildState::Serialize(LegoFile* p_file)
{
// TODO
return LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x4c);
Read(p_file, &m_unk0x4d);
Read(p_file, &m_unk0x4e);
Read(p_file, &m_placedPartCount);
}
else {
Write(p_file, m_unk0x4c);
Write(p_file, m_unk0x4d);
Write(p_file, m_unk0x4e);
Write(p_file, m_placedPartCount);
}
return SUCCESS;
}

View File

@@ -2850,11 +2850,66 @@ void AnimState::FUN_10065240(MxU32, AnimInfo*, MxU32)
// TODO
}
// STUB: LEGO1 0x100652d0
MxResult AnimState::Serialize(LegoFile* p_legoFile)
// FUNCTION: LEGO1 0x100652d0
// FUNCTION: BETA10 0x10046621
MxResult AnimState::Serialize(LegoFile* p_file)
{
// TODO
return LegoState::Serialize(p_legoFile);
// These two are equivalent up to the order of some deallocation.
// Choose as needed to get 100 %.
// Option 1:
// LegoState::Serialize(p_file);
// Option 2:
if (p_file->IsWriteMode()) {
p_file->WriteString(ClassName());
}
if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x08);
// m_unk0x10_len and m_unk0x10
if (m_unk0x10) {
delete[] m_unk0x10;
}
Read(p_file, &m_unk0x0c);
if (m_unk0x0c != 0) {
m_unk0x10 = new undefined2[m_unk0x0c];
}
else {
m_unk0x10 = NULL;
}
for (MxS32 i = 0; i < m_unk0x0c; i++) {
Read(p_file, &m_unk0x10[i]);
}
// m_unk0x18_len and m_unk0x18
// Note that here we read first and then free memory in contrast to above
Read(p_file, &m_unk0x14);
if (m_unk0x18) {
delete[] m_unk0x18;
}
if (m_unk0x14 != 0) {
m_unk0x18 = new undefined[m_unk0x14];
}
else {
m_unk0x18 = NULL;
}
for (MxS32 j = 0; j < m_unk0x14; j++) {
Read(p_file, &m_unk0x18[j]);
}
}
else if (p_file->IsWriteMode()) {
Write(p_file, m_unk0x08);
Write(p_file, m_unk0x0c);
for (MxS32 i = 0; i < m_unk0x0c; i++) {
Write(p_file, m_unk0x10[i]);
}
Write(p_file, m_unk0x14);
for (MxS32 j = 0; j < m_unk0x14; j++) {
Write(p_file, m_unk0x18[j]);
}
}
return SUCCESS;
}
// STUB: LEGO1 0x100654f0

View File

@@ -134,11 +134,16 @@ RaceState::RaceState()
// TODO
}
// STUB: LEGO1 0x10016140
MxResult RaceState::Serialize(LegoFile* p_legoFile)
// FUNCTION: LEGO1 0x10016140
MxResult RaceState::Serialize(LegoFile* p_file)
{
// TODO
return LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
for (MxS16 i = 0; i < 5; i++) {
m_state[i].Serialize(p_file);
}
return SUCCESS;
}
// FUNCTION: LEGO1 0x10016280

View File

@@ -435,11 +435,27 @@ GasStationState::GasStationState()
unk0x08[2] = -1;
}
// STUB: LEGO1 0x10006300
MxResult GasStationState::Serialize(LegoFile* p_legoFile)
// FUNCTION: LEGO1 0x10006300
MxResult GasStationState::Serialize(LegoFile* p_file)
{
// TODO
return LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
if (p_file->IsWriteMode()) {
Write(p_file, m_unk0x18);
Write(p_file, m_unk0x1a);
Write(p_file, m_unk0x1c);
Write(p_file, m_unk0x1e);
Write(p_file, m_unk0x20);
}
else if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x18);
Read(p_file, &m_unk0x1a);
Read(p_file, &m_unk0x1c);
Read(p_file, &m_unk0x1e);
Read(p_file, &m_unk0x20);
}
return SUCCESS;
}
// STUB: LEGO1 0x10006430

View File

@@ -684,35 +684,25 @@ HospitalState::HospitalState()
}
// FUNCTION: LEGO1 0x10076530
MxResult HospitalState::Serialize(LegoFile* p_legoFile)
MxResult HospitalState::Serialize(LegoFile* p_file)
{
LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
if (p_legoFile->IsWriteMode()) {
// A write variable needs to be used here, otherwise
// the compiler aggresively optimizes the function
MxS16 write;
write = m_unk0x0c;
p_legoFile->Write(&write, sizeof(m_unk0x0c));
write = m_unk0x0e;
p_legoFile->Write(&write, sizeof(m_unk0x0e));
write = m_unk0x10;
p_legoFile->Write(&write, sizeof(m_unk0x10));
write = m_unk0x12;
p_legoFile->Write(&write, sizeof(m_unk0x12));
write = m_unk0x14;
p_legoFile->Write(&write, sizeof(m_unk0x14));
write = m_unk0x16;
p_legoFile->Write(&write, sizeof(m_unk0x16));
if (p_file->IsWriteMode()) {
Write(p_file, m_unk0x0c);
Write(p_file, m_unk0x0e);
Write(p_file, m_unk0x10);
Write(p_file, m_unk0x12);
Write(p_file, m_unk0x14);
Write(p_file, m_unk0x16);
}
else if (p_legoFile->IsReadMode()) {
p_legoFile->Read(&m_unk0x0c, sizeof(m_unk0x0c));
p_legoFile->Read(&m_unk0x0e, sizeof(m_unk0x0e));
p_legoFile->Read(&m_unk0x10, sizeof(m_unk0x10));
p_legoFile->Read(&m_unk0x12, sizeof(m_unk0x12));
p_legoFile->Read(&m_unk0x14, sizeof(m_unk0x14));
p_legoFile->Read(&m_unk0x16, sizeof(m_unk0x16));
else if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x0c);
Read(p_file, &m_unk0x0e);
Read(p_file, &m_unk0x10);
Read(p_file, &m_unk0x12);
Read(p_file, &m_unk0x14);
Read(p_file, &m_unk0x16);
}
return SUCCESS;

View File

@@ -1314,138 +1314,138 @@ Act1State::Act1State() : m_unk0x00c(0), m_unk0x00e(0), m_unk0x008(NULL), m_unk0x
}
// FUNCTION: LEGO1 0x10033ac0
MxResult Act1State::Serialize(LegoFile* p_legoFile)
MxResult Act1State::Serialize(LegoFile* p_file)
{
LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
m_unk0x024.Serialize(p_legoFile);
m_unk0x070.Serialize(p_legoFile);
m_unk0x0bc.Serialize(p_legoFile);
m_unk0x108.Serialize(p_legoFile);
m_unk0x164.Serialize(p_legoFile);
m_unk0x1bc.Serialize(p_legoFile);
m_unk0x210.Serialize(p_legoFile);
m_unk0x024.Serialize(p_file);
m_unk0x070.Serialize(p_file);
m_unk0x0bc.Serialize(p_file);
m_unk0x108.Serialize(p_file);
m_unk0x164.Serialize(p_file);
m_unk0x1bc.Serialize(p_file);
m_unk0x210.Serialize(p_file);
if (p_legoFile->IsWriteMode()) {
if (p_file->IsWriteMode()) {
if (m_unk0x108.GetName()->Compare("") != 0) {
if (m_unk0x154) {
WriteNamedTexture(p_legoFile, m_unk0x154);
WriteNamedTexture(p_file, m_unk0x154);
}
else {
FUN_1003f540(p_legoFile, "chwind.gif");
FUN_1003f540(p_file, "chwind.gif");
}
if (m_unk0x158) {
WriteNamedTexture(p_legoFile, m_unk0x158);
WriteNamedTexture(p_file, m_unk0x158);
}
else {
FUN_1003f540(p_legoFile, "chjetl.gif");
FUN_1003f540(p_file, "chjetl.gif");
}
if (m_unk0x15c) {
WriteNamedTexture(p_legoFile, m_unk0x15c);
WriteNamedTexture(p_file, m_unk0x15c);
}
else {
FUN_1003f540(p_legoFile, "chjetr.gif");
FUN_1003f540(p_file, "chjetr.gif");
}
}
if (m_unk0x164.GetName()->Compare("") != 0) {
if (m_unk0x1b0) {
WriteNamedTexture(p_legoFile, m_unk0x1b0);
WriteNamedTexture(p_file, m_unk0x1b0);
}
else {
FUN_1003f540(p_legoFile, "jsfrnt.gif");
FUN_1003f540(p_file, "jsfrnt.gif");
}
if (m_unk0x1b4) {
WriteNamedTexture(p_legoFile, m_unk0x1b4);
WriteNamedTexture(p_file, m_unk0x1b4);
}
else {
FUN_1003f540(p_legoFile, "jswnsh.gif");
FUN_1003f540(p_file, "jswnsh.gif");
}
}
if (m_unk0x1bc.GetName()->Compare("") != 0) {
if (m_unk0x208) {
WriteNamedTexture(p_legoFile, m_unk0x208);
WriteNamedTexture(p_file, m_unk0x208);
}
else {
FUN_1003f540(p_legoFile, "dbfrfn.gif");
FUN_1003f540(p_file, "dbfrfn.gif");
}
}
if (m_unk0x210.GetName()->Compare("") != 0) {
if (m_unk0x25c) {
WriteNamedTexture(p_legoFile, m_unk0x25c);
WriteNamedTexture(p_file, m_unk0x25c);
}
else {
FUN_1003f540(p_legoFile, "rcfrnt.gif");
FUN_1003f540(p_file, "rcfrnt.gif");
}
if (m_unk0x260) {
WriteNamedTexture(p_legoFile, m_unk0x260);
WriteNamedTexture(p_file, m_unk0x260);
}
else {
FUN_1003f540(p_legoFile, "rcback.gif");
FUN_1003f540(p_file, "rcback.gif");
}
if (m_unk0x264) {
WriteNamedTexture(p_legoFile, m_unk0x264);
WriteNamedTexture(p_file, m_unk0x264);
}
else {
FUN_1003f540(p_legoFile, "rctail.gif");
FUN_1003f540(p_file, "rctail.gif");
}
}
p_legoFile->Write(&m_unk0x010, sizeof(m_unk0x010));
p_legoFile->Write(&m_unk0x022, sizeof(m_unk0x022));
Write(p_file, m_unk0x010);
Write(p_file, m_unk0x022);
}
else if (p_legoFile->IsReadMode()) {
else if (p_file->IsReadMode()) {
if (m_unk0x108.GetName()->Compare("") != 0) {
m_unk0x154 = ReadNamedTexture(p_legoFile);
m_unk0x154 = ReadNamedTexture(p_file);
if (m_unk0x154 == NULL) {
return FAILURE;
}
m_unk0x158 = ReadNamedTexture(p_legoFile);
m_unk0x158 = ReadNamedTexture(p_file);
if (m_unk0x158 == NULL) {
return FAILURE;
}
m_unk0x15c = ReadNamedTexture(p_legoFile);
m_unk0x15c = ReadNamedTexture(p_file);
if (m_unk0x15c == NULL) {
return FAILURE;
}
}
if (m_unk0x164.GetName()->Compare("") != 0) {
m_unk0x1b0 = ReadNamedTexture(p_legoFile);
m_unk0x1b0 = ReadNamedTexture(p_file);
if (m_unk0x1b0 == NULL) {
return FAILURE;
}
m_unk0x1b4 = ReadNamedTexture(p_legoFile);
m_unk0x1b4 = ReadNamedTexture(p_file);
if (m_unk0x1b4 == NULL) {
return FAILURE;
}
}
if (m_unk0x1bc.GetName()->Compare("") != 0) {
m_unk0x208 = ReadNamedTexture(p_legoFile);
m_unk0x208 = ReadNamedTexture(p_file);
if (m_unk0x208 == NULL) {
return FAILURE;
}
}
if (m_unk0x210.GetName()->Compare("") != 0) {
m_unk0x25c = ReadNamedTexture(p_legoFile);
m_unk0x25c = ReadNamedTexture(p_file);
if (m_unk0x25c == NULL) {
return FAILURE;
}
m_unk0x260 = ReadNamedTexture(p_legoFile);
m_unk0x260 = ReadNamedTexture(p_file);
if (m_unk0x260 == NULL) {
return FAILURE;
}
m_unk0x264 = ReadNamedTexture(p_legoFile);
m_unk0x264 = ReadNamedTexture(p_file);
if (m_unk0x264 == NULL) {
return FAILURE;
}
}
p_legoFile->Read(&m_unk0x010, sizeof(m_unk0x010));
p_legoFile->Read(&m_unk0x022, sizeof(m_unk0x022));
Read(p_file, &m_unk0x010);
Read(p_file, &m_unk0x022);
}
// TODO

View File

@@ -206,16 +206,15 @@ PoliceState::PoliceState()
}
// FUNCTION: LEGO1 0x1005e990
MxResult PoliceState::Serialize(LegoFile* p_legoFile)
MxResult PoliceState::Serialize(LegoFile* p_file)
{
LegoState::Serialize(p_legoFile);
LegoState::Serialize(p_file);
if (p_legoFile->IsReadMode()) {
p_legoFile->Read(&m_policeScript, sizeof(m_policeScript));
if (p_file->IsReadMode()) {
Read(p_file, &m_policeScript);
}
else {
PoliceScript::Script policeScript = m_policeScript;
p_legoFile->Write(&policeScript, sizeof(m_policeScript));
Write(p_file, m_policeScript);
}
return SUCCESS;