Fix SaveFile struct (#74)

* fix SaveFile struct

* change remaining classes to structs for consistency
This commit is contained in:
Yanis
2026-06-03 23:57:30 +02:00
committed by GitHub
parent ecd01550da
commit 5a892963cd
11 changed files with 460 additions and 465 deletions
+328
View File
@@ -0,0 +1,328 @@
#pragma once
#include "Item/ItemManager.hpp"
#include "MainGame/MiscAdvManager.hpp"
#include "math.hpp"
#include "types.h"
#include <nitro/mi.h>
// probably related to the map data?
#define NUM_UNK_BLOCKS 120
#define SIZE_UNK_BLOCK 0x1000
#define MAX_SAVE_SLOTS 2
#define COUNT_DATA 2 // main data + backup (?)
#define LENGTH_PLAYER_NAME 8
struct SaveFile_00000_0000_Data_D8 {
/* 00 */ unk32 unk_00;
/* 04 */ STRUCT_PAD(0x04, 0x6C);
/* 6C */ u32 trackFlags[2];
/* 74 */ unk32 spiritTrackFlags[1];
/* 78 */ unk32 unk_74;
/* 7C */ unk32 unk_78;
/* 80 */
SaveFile_00000_0000_Data_D8();
};
struct SaveFile_00000_0000_Data_184 {
/* 00 */ unk32 unk_00;
/* 04 */ unk16 unk_04;
/* 06 */ unk16 unk_06;
/* 08 */
SaveFile_00000_0000_Data_184() :
unk_00(0),
unk_04(0) {}
};
struct SaveFile_00000_0000_Data_484 {
/* 00 */ unk32 unk_00;
/* 04 */ unk32 unk_04;
/* 08 */
SaveFile_00000_0000_Data_484() :
unk_00(0),
unk_04(0) {}
};
// same layout as `MiscAdvManager`
struct SaveMiscAdvManager {
/* 00 */ u16 stampDates[StampType_Max];
/* 28 */ u16 unk_28;
/* 2A */ u16 postDate;
/* 2C */ union {
Vec2b stampPositions[StampType_Max];
u16 stampPos[StampType_Max];
};
/* 54 */ s8 obtainedLetters[LetterType_Max];
/* 68 */ s8 obtainedStamps[StampType_Max];
/* 7C */ u8 lastRandomNum;
/* 7D */ u8 randomNum;
/* 7E */ s8 numPriceCards; // current amount of price cards
/* 7F */ s8 numPostedPriceCards; // current amount of posted price cards
/* 80 */ unk8 unk_80;
/* 81 */ unk8 unk_81; // pad?
/* 82 */ unk8 unk_82; // pad?
/* 83 */ unk8 unk_83; // pad?
/* 84 */ unk32 lettersRead; // bitfield
/* 88 */ unk32 stampsFlag; // bitfield, related to the checkmarks from the stampbook
/* 8C */ unk16 songs; // bitfield
/* 8E */ unk16 unk_8E; // pad?
/* 90 */
SaveMiscAdvManager() :
lettersRead(0),
stampsFlag(0),
songs(0) {}
};
struct SaveInventory {
/* 00 */ u32 adventureFlags[32];
/* 80 */ unk32 unk_80;
/* 84 */ u32 unk_84[2];
/* 8C */ u16 numRupees;
/* 8E */ u16 unk_8E;
/* 90 */ ItemFlag equippedItem;
/* 94 */ unk32 unk_94;
/* 98 */
SaveInventory() {
MI_CpuFill32(0, this->adventureFlags, sizeof(this->adventureFlags));
MI_CpuFill32(0, this->unk_84, sizeof(this->unk_84));
this->unk_8E = 0;
}
};
struct SaveFile_00000_0000_Data_158 {
/* 00 */ unk8 unk_00[0x0C];
/* 0C */ unk8 unk_0C[0x20];
/* 2C */
SaveFile_00000_0000_Data_158() {
MI_CpuFill32(0, this->unk_00, sizeof(this->unk_00));
MI_CpuFill32(0, this->unk_0C, sizeof(this->unk_0C));
}
};
struct SaveFile_00000_0000_Data_C84 {
/* 00 */ u32 unk_00[4];
/* 10 */
SaveFile_00000_0000_Data_C84() {
MI_CpuFill32(0, this->unk_00, sizeof(this->unk_00));
}
};
struct SaveFile_00000_0000_Data_TEST4 {
/* D24 */ unk32 unk_D4C;
/* D24 */ unk32 unk_D50;
/* D24 */ unk32 unk_D54;
/* D24 */ unk32 unk_D58;
/* D24 */ unk32 unk_D5C;
/* D24 */ unk32 unk_D60;
/* D24 */ unk32 unk_D64;
/* D24 */ unk32 unk_D68;
/* D6C */ unk8 unk_D6C[0x08];
/* D74 */ unk16 unk_D74;
SaveFile_00000_0000_Data_TEST4() {
MI_CpuFill32(0, this->unk_D6C, sizeof(this->unk_D6C));
this->unk_D74 = 0;
}
};
struct SaveInfoData {
/* 000 */ unk32 unk_000;
/* 004 */ unk32 unk_004;
/* 008 */ unk32 unk_008;
/* 00C */ unk32 unk_00C;
/* 010 */ unk32 unk_010;
/* 014 */ unk16 unk_014;
/* 016 */ u16 sceneIndex;
/* 018 */ u8 roomIndex;
/* 019 */ u8 spawnIndex;
/* 01A */ unk16 unk_01A;
/* 01C */ unk32 unk_01C;
/* 020 */ unk32 unk_020;
/* 024 */ unk32 unk_024;
/* 028 */ STRUCT_PAD(0x28, 0x40);
/* 040 */ SaveInventory inventory;
/* 0D8 */ SaveFile_00000_0000_Data_D8 unk_0D8;
/* 158 */ SaveFile_00000_0000_Data_158 unk_158;
/* 184 */ SaveFile_00000_0000_Data_184 unk_184[96];
/* 484 */ SaveFile_00000_0000_Data_484 unk_484[256];
/* C84 */ SaveFile_00000_0000_Data_C84 unk_C84;
/* C94 */ SaveMiscAdvManager miscAdvManager;
/* D24 */ unk32 unk_D24;
/* D24 */ unk32 unk_D28;
/* D24 */ unk32 unk_D2C;
/* D24 */ unk32 unk_D30;
/* D24 */ unk32 unk_D34;
/* D24 */ unk32 unk_D38;
/* D24 */ unk32 unk_D3C;
/* D24 */ unk32 unk_D40;
/* D24 */ unk32 unk_D44;
/* D24 */ unk32 unk_D48;
/* D4C */ SaveFile_00000_0000_Data_TEST4 unk_D4C;
/* D78 */ unk32 unk_D78;
/* D7C */ unk32 unk_D7C;
/* D80 */ unk32 unk_D80;
/* D84 */ unk32 unk_D84;
/* D88 */ unk32 unk_D88;
/* D8C */ unk32 unk_D8C;
/* D90 */ unk32 unk_D90;
/* D94 */ unk32 unk_D94;
/* D98 */ unk32 unk_D98;
/* D9C */ unk32 unk_D9C;
/* DA0 */ unk16 unk_DA0;
/* DA2 */ wchar_t mPlayerName[LENGTH_PLAYER_NAME + 1];
/* DB4 */ unk32 unk_DB4;
/* DB8 */ unk32 unk_DB8;
/* DBC */ unk32 unk_DBC;
/* DC0 */ unk32 unk_DC0;
/* DC4 */ unk32 unk_DC4;
/* DC8 */ unk32 unk_DC8;
/* DCC */ unk32 unk_DCC;
/* DD0 */ unk32 unk_DD0;
/* DD4 */ unk32 unk_DD4;
/* DD8 */ unk32 unk_DD8;
/* DDC */ unk32 unk_DDC;
/* DE0 */ unk32 unk_DE0;
/* DE4 */ unk32 unk_DE4;
/* DE8 */ unk32 unk_DE8;
/* DEC */ unk32 unk_DEC;
/* DF0 */ unk32 unk_DF0;
/* DF4 */ unk32 unk_DF4;
/* DF8 */ unk32 unk_DF8;
/* DFC */ unk16 unk_DFC;
/* DFE */ u16 unk_DFE;
/* E00 */
SaveInfoData() :
unk_014(0) {}
};
struct SaveTreasureData {
/* 00 */ STRUCT_PAD(0x00, 0x3C);
/* 3C */ s16 unk_3C[TreasureType_Max];
/* 5C */ unk16 unk_5C;
/* 5E */ unk16 unk_5E;
/* 60 */ STRUCT_PAD(0x60, 0x7E);
/* 7E */ u16 unk_7E;
/* 80 */
SaveTreasureData() :
unk_5C(0) {}
};
struct SaveFile_00000_1D00_Data {
/* 000 */ STRUCT_PAD(0x00, 0x3C4);
/* 3C4 */ wchar_t unk_3C4[LENGTH_PLAYER_NAME + 1];
/* 3D6 */ STRUCT_PAD(0x3D6, 0x3FE);
/* 3FE */ u16 unk_3FE;
/* 400 */
};
struct SaveFile_00000_2500_Data {
/* 00 */ unk8 unk_00[0x7E];
/* 7E */ u16 unk_7E;
/* 80 */
};
struct SaveFile_00000_2600_Data {
/* 00 */ u8 unk_00;
/* 01 */ u8 unk_01;
/* 02 */ u8 unk_02;
/* 03 */ Vec2b unk_03[61];
/* 7E */ u16 unk_7E;
/* 80 */
};
class SaveSlot {
public:
/* 0000 */ SaveInfoData mInfoData[COUNT_DATA];
/* 1C00 */ SaveTreasureData mTreasureData[COUNT_DATA];
/* 1D00 */ SaveFile_00000_1D00_Data mUnk_1D00[COUNT_DATA];
/* 2500 */ SaveFile_00000_2500_Data mUnk_2500[COUNT_DATA];
/* 2600 */ SaveFile_00000_2600_Data mUnk_2600[COUNT_DATA];
/* 2700 */
void func_ov000_020a1124(void);
bool GetAdventureFlag(AdventureFlag flag) {
return GET_FLAG(this->mInfoData[0].inventory.adventureFlags, flag);
}
wchar_t *GetPlayerName() {
return this->mInfoData[0].mPlayerName;
}
bool IsPlayerNameSet() {
return this->mInfoData[0].mPlayerName[0] != L'\0';
}
SaveFile_00000_2600_Data *Get2600Ptr() {
return this->mUnk_2600;
}
u8 Get2600_00() {
return this->mUnk_2600[0].unk_00;
}
u8 Get2600_01() {
return this->mUnk_2600[0].unk_01;
}
u8 Get2600_02() {
return this->mUnk_2600[0].unk_02;
}
static void func_ov000_020a1028(SaveInfoData *param1);
static void func_ov000_020a10f4(SaveFile_00000_2600_Data *param1);
static void func_ov000_020a12a0(SaveFile_00000_1D00_Data *param1);
static void func_ov019_020d14c0(SaveFile_00000_1D00_Data *param1);
static void func_ov019_020d14fc(SaveInfoData *param1);
static void func_ov019_020d15cc(SaveFile_00000_2500_Data *param1);
static void func_ov019_020d1400(SaveFile_00000_2600_Data *param1);
static void func_ov019_020d1600(SaveTreasureData *param1);
};
struct SaveFile_04E00 {
u16 unk_00;
SaveFile_04E00() :
unk_00(0) {}
};
class SaveFile {
public:
/* 00000 */ SaveSlot mSlots[MAX_SAVE_SLOTS];
/* 04E00 */ SaveFile_04E00 mUnk_04E00[2][2];
/* 04E08 */ unk16 mUnk_04E08;
/* 04E0A */ u16 mSaveSlotIndex;
/* 04E0C */ u8 mUnk_04E0C[NUM_UNK_BLOCKS * SIZE_UNK_BLOCK];
/* 7CE0C */
SaveFile();
unk16 func_ov019_020d0c4c(unk32 param1, unk32 param2);
unk16 func_ov019_020d0c90(unk32 param1);
void func_ov019_020d0d50();
void func_ov019_020d0e18(unk32 param1);
void func_ov019_020d0ea8();
void func_ov019_020d1108();
void func_ov019_020d127c();
void func_ov019_020d13b8();
void func_ov019_020d1434();
void func_ov019_020d1538();
void func_ov019_020d1634();
void func_ov019_020d16d0();
void func_ov019_020d17e0();
void func_ov019_020d1808(unk32 param1);
void func_ov019_020d1aac(unk32 param1, const wchar_t *param2);
void func_ov019_020d1b14(unk32 param1);
};
+1 -338
View File
@@ -3,23 +3,15 @@
#include "Item/ItemManager.hpp"
#include "MainGame/MiscAdvManager.hpp"
#include "Save/AdventureFlags.hpp"
#include "Save/SaveFile.hpp"
#include "System/SysNew.hpp"
#include "Unknown/UnkStruct_ov000_02067bc4.hpp"
#include "global.h"
#include "types.h"
#include <nitro/mi.h>
//! TODO: kinda draft state for now
// probably related to the map data?
#define NUM_UNK_BLOCKS 120
#define SIZE_UNK_BLOCK 0x1000
#define LENGTH_PLAYER_NAME 8
#define COUNT_DATA 2 // main data + backup (?)
#define SAVE_DATA_SIZE (sizeof(SaveSlot) + sizeof(u8) * NUM_UNK_BLOCKS * SIZE_UNK_BLOCK)
#define MAX_SAVE_SLOTS 2
enum {
SaveDataIndex_SaveInfo,
@@ -29,335 +21,6 @@ enum {
SaveDataIndex_04,
};
class SaveAdventureFlags {
public:
/* 00 */ u32 data[32];
/* 80 */
SaveAdventureFlags() {
MI_CpuFill32(0, this, sizeof(SaveAdventureFlags));
};
};
class SaveInventory {
public:
/* 00 */ unk32 mUnk_00;
/* 04 */ u32 mUnk_04[2];
/* 0C */ u16 mNumRupees;
/* 0E */ u16 mUnk_12;
/* 10 */ ItemFlag mEquippedItem;
/* 14 */ unk32 mUnk_14;
/* 18 */
SaveInventory() {
MI_CpuFill32(0, this->mUnk_04, sizeof(mUnk_04));
this->mUnk_12 = 0;
};
};
class TreasureData {
public:
/* 00 */ unk8 mUnk_00[0x3C];
/* 3C */ s16 mUnk_3C[TreasureType_Max];
/* 5C */ unk16 mUnk_5C;
/* 5E */ unk16 mUnk_5E;
/* 60 */ unsigned char _pad_0x60[(0x7E) - (0x60)];
/* 7E */ u16 mUnk_7E;
/* 80 */
TreasureData() :
mUnk_5C(0) {}
};
class SaveTreasures {
public:
/* 000 */ TreasureData mTreasureData[2];
/* 100 */
SaveTreasures() {}
void func_ov019_020d1600();
};
class SaveInfoSub5 {
public:
/* 00 */ unk32 mUnk_00;
SaveInfoSub5();
};
class SaveUnknown158 {
public:
/* 00 */ unk8 mUnk_00[0x0C];
SaveUnknown158() {
MI_CpuFill32(0, this, sizeof(SaveUnknown158));
};
};
class SaveUnknown164 {
public:
/* 00 */ unk8 mUnk_00[0x20];
SaveUnknown164() {
MI_CpuFill32(0, this, sizeof(SaveUnknown164));
};
};
class Sub1Test {
public:
int a;
short b;
short p;
Sub1Test() {
a = 0;
b = 0;
}
};
class Sub2Test {
public:
int a;
int b;
Sub2Test() {
a = 0;
b = 0;
}
};
class Sub2Test2 {
public:
Sub2Test tab2[0xE0];
/* C84 */ unk32 mUnk_00_SaveInfoSub10[4];
Sub2Test2() {
MI_CpuFill32(0, this->mUnk_00_SaveInfoSub10, 16);
}
};
class SaveUnknown184_Sub {
public:
/* */ u8 pad1[390];
/* */ Sub1Test tab1[0x4F];
/* */ Sub2Test2 tab2;
SaveUnknown184_Sub() {}
};
class SaveUnknown184 {
public:
/* 184 */ SaveUnknown184_Sub mUnk_184;
SaveUnknown184() {}
};
class SaveUnknown14C {
public:
/* 14C */ unk32 mSpiritTrackFlags[1];
/* 150 */ unk32 mUnk_150;
/* 154 */ unk32 mUnk_154;
/* 158 */ SaveUnknown158 mUnk_158;
/* 164 */ SaveUnknown164 mUnk_164;
/* 184 */ SaveUnknown184 mUnk_184;
/* C94 */ MiscAdvManager mMiscAdvManager;
/* D24 */ unk8 mUnk_00_SaveUnknownD24[0x48];
/* D6C */ unk8 mUnk_48_SaveUnknownD24[8];
/* D74 */ unk16 mUnk_50_SaveUnknownD24;
/* D76 */ unk16 mUnk_52_SaveUnknownD24;
/* D78 */ STRUCT_PAD(0xD78, 0xD8C);
/* D8C */
SaveUnknown14C() {
this->mMiscAdvManager.mLettersRead = 0;
this->mMiscAdvManager.mStampsFlag = 0;
this->mMiscAdvManager.mSongs = 0;
MI_CpuFill32(0, this->mUnk_48_SaveUnknownD24, sizeof(this->mUnk_48_SaveUnknownD24));
this->mUnk_50_SaveUnknownD24 = 0;
}
};
class SaveInfoData {
public:
/* 000 */ unk32 mUnk_000;
/* 004 */ unk32 mUnk_004;
/* 008 */ unk32 mUnk_008;
/* 00C */ unk32 mUnk_00C;
/* 010 */ unk32 mUnk_010;
/* 014 */ unk16 mUnk_014;
/* 016 */ u16 mSceneIndex;
/* 018 */ u8 mRoomIndex; // "house" index but could be more?
/* 019 */ u8 mSpawnIndex;
/* 01A */ unk16 mUnk_01A;
/* 01C */ unk32 mUnk_01C;
/* 020 */ unk32 mUnk_020;
/* 024 */ unk32 mUnk_024;
/* 028 */ STRUCT_PAD(0x28, 0x40);
/* 040 */ SaveAdventureFlags mAdventureFlags;
/* 0C0 */ SaveInventory mInventory;
/* 0D8 */ SaveInfoSub5 mUnk_0D8;
/* 0DC */ STRUCT_PAD(0xDC, 0x144);
/* 144 */ u32 mTrackFlags[2];
/* 14C */ SaveUnknown14C mUnk_14C;
/* D8C */ STRUCT_PAD(0xD8C, 0xDA2);
/* DA2 */ wchar_t mPlayerName[LENGTH_PLAYER_NAME + 1];
/* DB4 */ STRUCT_PAD(0xDB4, 0xDFE);
/* DFE */ u16 mUnk_DFE;
/* E00 */
SaveInfoData() :
mUnk_014(0) {}
};
class SaveInfo {
public:
/* 0000 */ SaveInfoData mSaveInfoData[COUNT_DATA];
/* 1C00 */
SaveInfo() {}
void func_ov000_020a1028(void);
void func_ov019_020d14fc(void);
};
class SaveSub15 {
public:
/* 000 */ unk8 mUnk_000[(0x3C4) - (0x000)];
/* 3C4 */ wchar_t mUnk_3C4[LENGTH_PLAYER_NAME + 1];
/* 3D6 */ STRUCT_PAD(0x3D6, 0x3FE);
/* 3FE */ u16 mUnk_3FE;
/* 400 */
// SaveSub15() {}
};
class SaveSub5 {
public:
/* 000 */ SaveSub15 mUnk_000[COUNT_DATA];
/* 800 */
void func_ov000_020a12a0();
void func_ov019_020d14c0();
};
class SaveSub16 {
public:
/* 00 */ unk8 mUnk_00[0x7E];
/* 7E */ u16 mUnk_7E;
/* 80 */
};
class SaveSub6 {
public:
/* 000 */ SaveSub16 mUnk_00[COUNT_DATA];
/* 100 */
void func_ov019_020d15cc();
};
struct SaveSub17_03 {
/* 00 */ u8 mUnk_00;
/* 01 */ u8 mUnk_01;
/* 02 */
};
class SaveSub17 {
public:
// /* 00 */ unk8 mUnk_00[0x7E];
/* 00 */ u8 mUnk_00;
/* 01 */ u8 mUnk_01;
/* 02 */ u8 mUnk_02;
/* 03 */ SaveSub17_03 mUnk_03[61];
/* 7E */ u16 mUnk_7E;
};
class SaveSub7 {
public:
/* 000 */ SaveSub17 mUnk_00[COUNT_DATA];
/* 100 */
void func_ov000_020a10f4();
void func_ov019_020d1400();
};
class SaveSlot {
public:
/* 0000 */ SaveInfo mSaveInfo;
/* 1C00 */ SaveTreasures mTreasures;
// /* 1D00 */ u8 mUnk_1D00[0x2500 - 0x1D00];
// /* 2500 */ u8 mUnk_2500[0x100];
// /* 2600 */ u8 mUnk_2600[0x100];
/* 1D00 */ SaveSub5 mUnk_1D00;
/* 2500 */ SaveSub6 mUnk_2500;
/* 2600 */ SaveSub7 mUnk_2600;
/* 2700 */
SaveSlot() {}
void func_ov000_020a1124(void);
bool GetAdventureFlag(AdventureFlag flag) {
return GET_FLAG(this->mSaveInfo.mSaveInfoData[0].mAdventureFlags.data, flag);
}
wchar_t *GetPlayerName() {
return this->mSaveInfo.mSaveInfoData[0].mPlayerName;
}
bool IsPlayerNameSet() {
return this->mSaveInfo.mSaveInfoData[0].mPlayerName[0] != L'\0';
}
SaveSub17 *Get2600Ptr() {
return this->mUnk_2600.mUnk_00;
}
u8 Get2600_00() {
return this->mUnk_2600.mUnk_00[0].mUnk_00;
}
u8 Get2600_01() {
return this->mUnk_2600.mUnk_00[0].mUnk_01;
}
u8 Get2600_02() {
return this->mUnk_2600.mUnk_00[0].mUnk_02;
}
};
class SaveFileSub1 {
public:
u16 mUnk_00;
SaveFileSub1() :
mUnk_00(0) {}
};
// save data
class SaveFile : public SysObject {
public:
/* 00000 */ SaveSlot mSlots[MAX_SAVE_SLOTS];
/* 04E00 */ SaveFileSub1 mUnk_04E00[2][2];
/* 04E08 */ unk16 mUnk_04E08;
/* 04E0A */ u16 mSaveSlotIndex;
/* 04E0C */ u8 mUnk_04E0C[NUM_UNK_BLOCKS * SIZE_UNK_BLOCK];
/* 7CE0C */
SaveFile();
unk16 func_ov019_020d0c4c(unk32 param1, unk32 param2);
unk16 func_ov019_020d0c90(unk32 param1);
void func_ov019_020d0d50();
void func_ov019_020d0e18(unk32 param1);
void func_ov019_020d0ea8();
void func_ov019_020d1108();
void func_ov019_020d127c();
void func_ov019_020d13b8();
void func_ov019_020d1434();
void func_ov019_020d1538();
void func_ov019_020d1634();
void func_ov019_020d16d0();
void func_ov019_020d17e0();
void func_ov019_020d1808(unk32 param1);
void func_ov019_020d1aac(unk32 param1, const wchar_t *param2);
void func_ov019_020d1b14(unk32 param1);
};
class SaveManager_21C {
public:
/* 00 */ unk32 mUnk_00;