Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
fio.c
Go to the documentation of this file.
1#include "fio.h"
2#include "PR/os_flash.h"
3#include "gcc/string.h"
4#include "dx/versioning.h"
5#include "dx/config.h"
6
7typedef struct SaveInfo {
8 /* 0x08 */ s32 slot;
9 /* 0x04 */ s32 count;
10} SaveInfo; // size = 0x8
11
12#define GLOBALS_PAGE_1 6
13#define GLOBALS_PAGE_2 7
14
16BSS SaveInfo LogicalSaveInfo[4]; // 4 save slots presented to the player
17BSS SaveInfo PhysicalSaveInfo[6]; // 6 saves as represented on the EEPROM
19
22
23char MagicSaveString[] = "Mario Story 006";
24
25b32 fio_read_flash(s32 pageNum, void* readBuffer, u32 numBytes);
26b32 fio_write_flash(s32 pageNum, s8* readBuffer, u32 numBytes);
27void fio_erase_flash(s32 pageNum);
28
30 s32 storyProgress = evt_get_variable(NULL, GB_StoryProgress);
31 s32 ret = 7;
32
33 if (storyProgress < evt_get_variable(NULL, STORY_CH1_STAR_SPIRIT_RESCUED)) {
34 ret = 0;
35 } else if (storyProgress < evt_get_variable(NULL, STORY_CH2_STAR_SPIRIT_RESCUED)) {
36 ret = 1;
37 } else if (storyProgress < evt_get_variable(NULL, STORY_CH3_STAR_SPIRIT_RESCUED)) {
38 ret = 2;
39 } else if (storyProgress < evt_get_variable(NULL, STORY_CH4_STAR_SPIRIT_RESCUED)) {
40 ret = 3;
41 } else if (storyProgress < evt_get_variable(NULL, STORY_CH5_OPENED_ESCAPE_ROUTE)) {
42 ret = 4;
43 } else if (storyProgress < evt_get_variable(NULL, STORY_CH6_STAR_SPIRIT_RESCUED)) {
44 ret = 5;
45 } else if (storyProgress < evt_get_variable(NULL, STORY_CH7_STAR_SPIRIT_RESCUED)) {
46 ret = 6;
47 }
48
49 return ret;
50}
51
53 s32* it = (s32*)&gSaveGlobals;
54 u32 sum = 0;
55 u32 i;
56
57 for (i = 0; i < sizeof(gSaveGlobals) / sizeof(*it); i++) {
58 sum += *it++;
59 }
60 return sum;
61}
62
64 SaveGlobals* header = &gSaveGlobals;
65
66 if (strcmp(header->magicString, MagicSaveString)) {
67 return FALSE;
68 }
69 if (header->crc1 != ~header->crc2) {
70 return FALSE;
71 }
72 return fio_calc_globals_checksum() == header->crc1;
73}
74
78 return TRUE;
79 }
80
83 return TRUE;
84 }
85
86 bzero(&gSaveGlobals, sizeof(gSaveGlobals));
87 return FALSE;
88}
89
91 s32 checksum;
92
95 gSaveGlobals.crc2 = ~gSaveGlobals.crc1;
96 checksum = fio_calc_globals_checksum();
97 gSaveGlobals.crc1 = checksum;
98 gSaveGlobals.crc2 = ~checksum;
103 return TRUE;
104}
105
107 s32* it = (s32*)saveData;
108 u32 sum = 0;
109 u32 i;
110
111 for (i = 0; i < sizeof(*saveData) / sizeof(*it); i++) {
112 sum += *it++;
113 }
114 return sum;
115}
116
118 if (!strcmp(saveData->magicString, MagicSaveString) && saveData->crc1 == ~saveData->crc2) {
119 return fio_calc_file_checksum(saveData) == saveData->crc1;
120 }
121 return FALSE;
122}
123
125 SaveData* fetchBuf = &FetchSaveBuffer; // temps required to match
126 SaveData* validBuf = fetchBuf;
127 s32 i, j, minSaveCount;
128
129 for (i = 0; i < ARRAY_COUNT(LogicalSaveInfo); i++) {
130 LogicalSaveInfo[i].slot = -1;
131 LogicalSaveInfo[i].count = -1;
132 }
133
134 for (i = 0; i < ARRAY_COUNT(PhysicalSaveInfo); i++) {
135 fio_read_flash(i, fetchBuf, sizeof(SaveData));
136 if (fio_validate_file_checksum(fetchBuf)) {
137 PhysicalSaveInfo[i].slot = validBuf->saveSlot;
138 PhysicalSaveInfo[i].count = validBuf->saveCount;
139 // logical saves only track the most recent physical save for each slot
140 if (LogicalSaveInfo[validBuf->saveSlot].count < validBuf->saveCount) {
141 LogicalSaveInfo[validBuf->saveSlot].slot = i;
142 LogicalSaveInfo[validBuf->saveSlot].count = validBuf->saveCount;
143 }
144 }
145 }
146
147 minSaveCount = 0x7FFFFFFF;
148 for (j = 0; j < ARRAY_COUNT(PhysicalSaveInfo); j++) {
149 // find a logical save for each physical save
150 for (i = 0; i < ARRAY_COUNT(LogicalSaveInfo); i++) {
151 if (j == LogicalSaveInfo[i].slot) {
152 break;
153 }
154 }
155 // condition holds only for physical saves not mapped to logical ones
156 if (i == ARRAY_COUNT(LogicalSaveInfo)) {
157 if (PhysicalSaveInfo[j].count < minSaveCount) {
158 // choose the least-recent unmapped physical save slot
159 minSaveCount = PhysicalSaveInfo[j].count;
161 }
162 }
163 }
164 return TRUE;
165}
166
183
219
220void fio_erase_game(s32 saveSlot) {
221 s32 i;
222
224
225 for (i = 0; i < ARRAY_COUNT(PhysicalSaveInfo); i++) {
226 if (PhysicalSaveInfo[i].slot == saveSlot) {
228 }
229 }
230}
231
232void fio_init_flash(void) {
233 osFlashInit();
234}
235
236b32 fio_read_flash(s32 pageNum, void* readBuffer, u32 numBytes) {
237 OSIoMesg mb;
238 OSMesgQueue mesgQueue;
239 OSMesg mesg;
240 s8* buf = (s8*)readBuffer;
241 s32 amt;
242 u16 i;
243
244 osInvalDCache(buf, numBytes);
245 osCreateMesgQueue(&mesgQueue, &mesg, 1);
246
247 i = 0;
248 while (numBytes != 0) {
249 if (numBytes > sizeof(SaveGlobals)) {
250 amt = sizeof(SaveGlobals);
251 } else {
252 amt = numBytes;
253 }
254
255 osFlashReadArray(&mb, 0, pageNum * sizeof(SaveGlobals) + i, buf, 1, &mesgQueue);
256 osRecvMesg(&mesgQueue, NULL, 1);
257 i++;
258 numBytes -= amt;
259 buf += amt;
260 }
261 return TRUE;
262}
263
264b32 fio_write_flash(s32 pageNum, s8* readBuffer, u32 numBytes) {
265 OSIoMesg mb;
266 OSMesgQueue mesgQueue;
267 OSMesg mesg;
268 s32 amt;
269 u16 i;
270
271 osWritebackDCache(readBuffer, numBytes);
272 osCreateMesgQueue(&mesgQueue, &mesg, 1);
273
274 i = 0;
275 while (numBytes != 0) {
276 if (numBytes > sizeof(SaveGlobals)) {
277 amt = sizeof(SaveGlobals);
278 } else {
279 amt = numBytes;
280 }
281
282 osFlashWriteBuffer(&mb, 0, readBuffer, &mesgQueue);
283 osFlashWriteArray((pageNum * sizeof(SaveGlobals)) + i);
284 osRecvMesg(&mesgQueue, NULL, 1);
285 i++;
286 numBytes -= amt;
287 readBuffer += amt;
288 }
289 return TRUE;
290}
291
292void fio_erase_flash(s32 pageNum) {
293 osFlashSectorErase(pageNum * sizeof(SaveGlobals));
294}
s32 b32
#define DX_MOD_VER_MAJOR
Definition config.h:8
#define DX_MOD_NAME
Creates the version string that appears on the file select menu.
Definition config.h:7
#define DX_MOD_VER_PATCH
Definition config.h:10
#define DX_MOD_VER_MINOR
Definition config.h:9
#define ASSERT(condition)
@ STORY_CH6_STAR_SPIRIT_RESCUED
Definition enums.h:195
@ STORY_CH4_STAR_SPIRIT_RESCUED
Definition enums.h:143
@ STORY_CH5_OPENED_ESCAPE_ROUTE
Definition enums.h:175
@ STORY_CH3_STAR_SPIRIT_RESCUED
Definition enums.h:123
@ STORY_CH1_STAR_SPIRIT_RESCUED
Definition enums.h:61
@ STORY_CH2_STAR_SPIRIT_RESCUED
Definition enums.h:83
@ STORY_CH7_STAR_SPIRIT_RESCUED
Definition enums.h:225
BSS SaveData FetchSaveBuffer
Definition fio.c:15
BSS SaveInfo LogicalSaveInfo[4]
Definition fio.c:16
#define GLOBALS_PAGE_2
Definition fio.c:13
b32 fio_load_globals(void)
Definition fio.c:75
b32 fio_load_game(s32 saveSlot)
Definition fio.c:167
b32 fio_save_globals(void)
Definition fio.c:90
s32 get_spirits_rescued(void)
Definition fio.c:29
void fio_erase_flash(s32 pageNum)
Definition fio.c:292
b32 fio_read_flash(s32 pageNum, void *readBuffer, u32 numBytes)
Definition fio.c:236
void fio_erase_game(s32 saveSlot)
Definition fio.c:220
b32 fio_fetch_saved_file_info(void)
Definition fio.c:124
SaveData gCurrentSaveFile
Definition fio.c:21
s32 fio_calc_globals_checksum(void)
Definition fio.c:52
b32 fio_write_flash(s32 pageNum, s8 *readBuffer, u32 numBytes)
Definition fio.c:264
BSS s32 NextAvailablePhysicalSave
Definition fio.c:18
s32 fio_calc_file_checksum(SaveData *saveData)
Definition fio.c:106
s32 slot
Definition fio.c:8
SaveGlobals gSaveGlobals
Definition fio.c:20
s32 count
Definition fio.c:9
b32 fio_validate_file_checksum(SaveData *saveData)
Definition fio.c:117
b32 fio_validate_globals_checksums(void)
Definition fio.c:63
BSS SaveInfo PhysicalSaveInfo[6]
Definition fio.c:17
void fio_save_game(s32 saveSlot)
Definition fio.c:184
void fio_init_flash(void)
Definition fio.c:232
char MagicSaveString[]
Definition fio.c:23
#define GLOBALS_PAGE_1
Definition fio.c:12
Definition fio.c:7
SaveFileSummary gSaveSlotSummary[4]
s32 evt_get_variable(Evt *script, Bytecode var)
Definition evt.c:1690
@ GB_StoryProgress
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
GameStatus * gGameStatusPtr
Definition main_loop.c:32
PlayerData gPlayerData
Definition 77480.c:40
void fio_deserialize_state()
Load game data from gCurrentSaveFile Performs version checking and supports potential migration betwe...
Definition versioning.c:36
void fio_serialize_state()
Store current game data to gCurrentSaveFile.
Definition versioning.c:9
s8 majorVersion
Definition versioning.h:146
char magicString[16]
Definition versioning.h:10
s8 minorVersion
Definition versioning.h:147
SaveFileSummary summary
Definition versioning.h:170
char modName[28]
Definition versioning.h:145
char magicString[16]
Definition versioning.h:144
s32 saveSlot
Definition versioning.h:152
s32 saveCount
Definition versioning.h:153
s8 patchVersion
Definition versioning.h:148
SaveData struct from unmodified Paper Mario.
Definition versioning.h:107