Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
memcard.c
Go to the documentation of this file.
1#include "engine/game.h"
2#include <libgs.h>
3#include <libetc.h>
4#include <libsnd.h>
5
6/* Starts libmcrd and sets up MEMCARD: the save file name and the section sizes */
7void initMemCard(void) {
10 HEAP.zero(&MEMCARD, sizeof(MemCard));
12 MEMCARD.iconCount = -1;
14 MEMCARD.infoSize = 0x100;
15 MEMCARD.dataSize = 0x2700;
16}
17
18#if VERSION_US
19const char SAVE_FILE_NAME_JP[24] = "BISLPS-99999DMW3-JPN";
20
21const char SAVE_FILE_NAMES[6][24] = {
22 "BASLUS-01436DMW3-USA",
23 "BESLPS-99999DMW3-ENG",
24 "BESLPS-99999DMW3-FRA",
25 "BESLPS-99999DMW3-ITA",
26 "BESLPS-99999DMW3-GER",
27 "BESLPS-99999DMW3-SPN",
28};
29#elif VERSION_JP
30/* Only the first is read: the second is the USA release's name, the third
31 the placeholder the USA version keeps as SAVE_FILE_NAME_JP */
32const char SAVE_FILE_NAMES[3][24] = {
33 "BISLPS-03446DMW3-JPN",
34 "BASLUS-01436DMW3-USA",
35 "BISLPS-99999DMW3-JPN",
36};
37#endif
38
39#if VERSION_US || VERSION_JP
40/* The release saves as its own name, BASLUS-01436DMW3-USA in the US one
41 and BISLPS-03446DMW3-JPN in the Japanese one */
42void setSaveFileName(void) {
44}
45#elif VERSION_EU
46const char SAVE_FILE_NAME_JP[24] = "BISLPS-03446DMW3-JPN";
47
48const char SAVE_FILE_NAMES[2][24] = {
49 "BASLUS-01436DMW3-USA",
50 "BESLES-03936DMW3-EUR",
51};
52
53/*
54 * The save file name by the language: the Japanese, US or European
55 * release's, the same for each European language
56 */
57void setSaveFileName(void) {
58 switch (LANGUAGE) {
59 default:
60 case 0:
62 break;
63 case 1:
65 break;
66 case 2:
68 break;
69 case 3:
71 break;
72 case 4:
74 break;
75 case 5:
77 break;
78 case 6:
80 break;
81 }
82}
83#endif
84
85/* The save file header: title (Shift-JIS), icon CLUT and 1-3 icon frames */
86void setSaveHeader(char *title, CardClut *clut, s32 count, void **icons) {
87 s32 i;
88
89 if (count >= 1 && count <= SAVE_MAX_ICONS && (u32)strlen(title) <= sizeof(MEMCARD.header.title)) {
90 MEMCARD.iconCount = count;
92 MEMCARD.header.magic[0] = 'S';
93 MEMCARD.header.magic[1] = 'C';
96 strcpy(MEMCARD.header.title, title);
97 MEMCARD.header.clut = *clut;
98 for (i = 0; i < MEMCARD.iconCount; i++) {
99 MEMCARD.icons[i] = icons[i];
100 }
101 }
102}
103
104/* MemCardSync, retrying a failed command up to maxRetries times */
106 long cmds;
107 u_long result;
108 s32 ret = MemCardSync(1, &cmds, &result);
109
110 if (ret == 1) {
111 MEMCARD.cmd = cmds;
112 MEMCARD.result = result;
113 if (result <= CARD_ERR_NO_CARD || result == CARD_ERR_NEW_CARD) {
114 MEMCARD.retries = 0;
115 } else {
117 MEMCARD.restart = ret;
118 return 0;
119 }
120 MEMCARD.retries = 0;
121 MEMCARD.restart = 0;
122 }
123 }
124 return ret;
125}
126
127/* Checks whether a card is in port `port` (MemCardExist) */
129 switch (MEMCARD.state) {
130 case MEMCARD_IDLE:
131 default:
132 while (MemCardExist(port << 4) == 0) {
133 syncMemCard();
134 }
136 break;
137 case MEMCARD_CHECKING:
138 if (syncMemCard() != 0) {
141 return 1;
142 }
143 return MEMCARD.result + 1;
144 }
145 if (MEMCARD.restart != 0) {
146 MEMCARD.restart = 0;
147 while (MemCardExist(port << 4) == 0) {
148 syncMemCard();
149 }
150 }
151 break;
152 }
153 return 0;
154}
155
156/*
157 * Checks a card in port `port` in full, finding out whether it is new or unformatted
158 * (MemCardAccept)
159 */
161 switch (MEMCARD.state) {
162 case MEMCARD_IDLE:
163 default:
164 while (MemCardAccept(port << 4) == 0) {
165 syncMemCard();
166 }
168 break;
170 if (syncMemCard() != 0) {
173 return 1;
174 }
175 return MEMCARD.result + 1;
176 }
177 if (MEMCARD.restart != 0) {
178 MEMCARD.restart = 0;
179 while (MemCardAccept(port << 4) == 0) {
180 syncMemCard();
181 }
182 }
183 break;
184 }
185 return 0;
186}
187
188/* Reads a section of the save (SAVE_SECTION_*, then 2-4 for the data), a sector a call */
189s32 readSave(s32 port, void *buf, s32 size, s32 section) {
190 u8 *dst;
191
192 if (buf == NULL || size == 0) {
193 return 1;
194 }
195 if ((u32)(MEMCARD.iconCount - 1) >= SAVE_MAX_ICONS) {
196 return 1;
197 }
198 dst = buf;
199 switch (MEMCARD.state) {
200 case MEMCARD_IDLE:
201 default:
202 if (checkMemCard(port) == 0) {
203 return 0;
204 }
205 switch (MEMCARD.result) {
206 case CARD_ERR_NONE:
207 MEMCARD.progress = 0;
208 switch (section) {
210 default:
211 MEMCARD.offset = 0;
212 break;
215 break;
218 break;
219 case SAVE_SECTION_DATA + 1:
221 break;
222 case SAVE_SECTION_DATA + 2:
224 break;
225 }
226 while (MemCardReadFile(port << 4, MEMCARD.fileName, dst, MEMCARD.offset, CARD_SECTOR_SIZE) == 0) {
227 syncMemCard();
228 }
230 break;
231 default:
233 return MEMCARD.result + 1;
234 }
235 break;
236 case MEMCARD_READING:
237 if (syncMemCard() != 0) {
238 switch (MEMCARD.result) {
239 case CARD_ERR_NONE:
241 if (MEMCARD.progress >= size) {
243 return 1;
244 }
245 while (1) {
247 return 0;
248 }
249 syncMemCard();
250 }
251 default:
253 return MEMCARD.result + 1;
254 }
255 }
256 if (MEMCARD.restart != 0) {
257 MEMCARD.restart = 0;
258 MEMCARD.progress = 0;
259 while (MemCardReadFile(port << 4, MEMCARD.fileName, dst, MEMCARD.offset, CARD_SECTOR_SIZE) == 0) {
260 syncMemCard();
261 }
262 return 0;
263 }
264 break;
265 }
266 return 0;
267}
268
269/* Writes a section (as readSave; section 0 takes the offset from bits 8 and up) */
270s32 writeSave(s32 port, void *buf, s32 size, s32 section) {
271 u8 *dst;
272
273 if (buf == NULL || size == 0) {
274 return 1;
275 }
276 if ((u32)(MEMCARD.iconCount - 1) >= SAVE_MAX_ICONS) {
277 return 1;
278 }
279 dst = buf;
280 switch (MEMCARD.state) {
281 case MEMCARD_IDLE:
282 default:
283 if (checkMemCard(port) == 0) {
284 return 0;
285 }
286 switch (MEMCARD.result) {
287 case CARD_ERR_NONE:
288 MEMCARD.progress = 0;
289 switch (section & 0xFF) {
291 default:
292 MEMCARD.offset = section >> 8;
293 break;
296 break;
299 break;
300 case SAVE_SECTION_DATA + 1:
302 break;
303 case SAVE_SECTION_DATA + 2:
305 break;
306 }
307 while (MemCardWriteFile(port << 4, MEMCARD.fileName, dst, MEMCARD.offset, CARD_SECTOR_SIZE) == 0) {
308 syncMemCard();
309 }
311 break;
312 default:
314 return MEMCARD.result + 1;
315 }
316 break;
317 case MEMCARD_WRITING:
318 if (syncMemCard() != 0) {
319 switch (MEMCARD.result) {
320 case CARD_ERR_NONE:
322 if (MEMCARD.progress >= size) {
324 return 1;
325 }
326 while (1) {
328 return 0;
329 }
330 syncMemCard();
331 }
332 default:
334 return MEMCARD.result + 1;
335 }
336 }
337 if (MEMCARD.restart != 0) {
338 MEMCARD.restart = 0;
339 MEMCARD.progress = 0;
340 while (MemCardWriteFile(port << 4, MEMCARD.fileName, dst, MEMCARD.offset, CARD_SECTOR_SIZE) == 0) {
341 syncMemCard();
342 }
343 return 0;
344 }
345 break;
346 }
347 return 0;
348}
349
350/* Reads the directory, creates the save file, formats or unformats (MEMCARD_OP_*) */
352 switch (MEMCARD.state) {
353 case MEMCARD_IDLE:
354 default:
355 if (acceptMemCard(port) == 0) {
356 return 0;
357 }
358 switch (MEMCARD.result) {
359 case CARD_ERR_NONE:
361 break;
363 if (cmd == MEMCARD_OP_FORMAT) {
365 break;
366 }
368 return CARD_ERR_UNFORMATTED + 1;
369 default:
371 return MEMCARD.result + 1;
372 }
373 break;
374 case MEMCARD_COMMAND:
375 if ((MEMCARD.result == CARD_ERR_NONE && (cmd == MEMCARD_OP_LIST || cmd == MEMCARD_OP_CREATE || cmd == MEMCARD_OP_UNFORMAT)) ||
379 switch (cmd) {
380 case MEMCARD_OP_LIST:
381 default:
383 break;
386 break;
388 MEMCARD.result = MemCardFormat(port << 4);
389 break;
391 MEMCARD.result = MemCardUnformat(port << 4);
392 break;
393 }
394 if (MEMCARD.result == -1) {
396 }
397 }
400 return 1;
401 }
402 return MEMCARD.result + 1;
403 }
404 return 0;
405}
406
407/* Reads the card's directory into MEMCARD.files */
410
411 if (ret == 1) {
412 return 1;
413 }
414 return ret;
415}
416
417/* Creates the save file on the card */
420
421 if (ret == 1) {
422 return 1;
423 }
424 return ret;
425}
426
427/* Formats an unformatted card */
430
431 if (ret == 1) {
432 return 1;
433 }
434 return ret;
435}
436
437/* memCardCommand's MEMCARD_OP_UNFORMAT, left out: always fails as if there were no card */
439 return CARD_ERR_NO_CARD + 1;
440}
441
442/* XOR of every byte */
443s32 verifyChecksum(void *data, s32 size, char expected) {
444 u8 *byte = data;
445 u8 sum = 0;
446 s32 i;
447
448 for (i = 0; i < size; i++) {
449 sum ^= *byte++;
450 }
451 return ((expected ^ sum) & 0xFF) == 0;
452}
453
454/* The XOR of every byte, which verifyChecksum checks */
455u8 computeChecksum(void *data, s32 size) {
456 u8 *byte = data;
457 u8 sum = 0;
458 s32 i;
459
460 for (i = 0; i < size; i++) {
461 sum ^= *byte++;
462 }
463 return sum;
464}
465
467
472
473/* The commands of memCardCommand's operations */
char STR_ALL_FILES[16]
In the small data (.sdata) between system/main.c's and text/cursor.c's.
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
unsigned int u32
Definition common.h:12
unsigned char u8
Definition common.h:8
s32 LANGUAGE
The European version's settings, in the small data (.sdata) between file/file_table....
Definition eu_settings.c:13
int strlen(const char *)
SDK functions declared here rather than from their PsyQ headers: strings.h and memory....
char * strcpy(char *dst, const char *src)
Heap HEAP
The functions that return what a call left in v0 (allocMemHigh, findTask) and the ones that take othe...
Definition heap.c:184
u8 computeChecksum(void *data, s32 size)
The XOR of every byte, which verifyChecksum checks.
Definition memcard.c:455
const char SAVE_FILE_NAME_JP[24]
Definition memcard.c:46
s32 writeSave(s32 port, void *buf, s32 size, s32 section)
Writes a section (as readSave; section 0 takes the offset from bits 8 and up)
Definition memcard.c:270
MemCardFuncs MEMCARD_FUNCS
Definition memcard.c:468
void setSaveHeader(char *title, CardClut *clut, s32 count, void **icons)
The save file header: title (Shift-JIS), icon CLUT and 1-3 icon frames.
Definition memcard.c:86
MemCard MEMCARD
Definition memcard.c:466
s32 checkMemCard(s32 port)
Checks whether a card is in port port (MemCardExist)
Definition memcard.c:128
s32 formatMemCard(s32 port)
Formats an unformatted card.
Definition memcard.c:428
s32 readSave(s32 port, void *buf, s32 size, s32 section)
Reads a section of the save (SAVE_SECTION_*, then 2-4 for the data), a sector a call.
Definition memcard.c:189
s32 listSaves(s32 port)
Reads the card's directory into MEMCARD.files.
Definition memcard.c:408
void setSaveFileName(void)
Definition memcard.c:57
s32 memCardCommand(s32 port, s32 cmd)
Reads the directory, creates the save file, formats or unformats (MEMCARD_OP_*)
Definition memcard.c:351
void initMemCard(void)
Starts libmcrd and sets up MEMCARD: the save file name and the section sizes.
Definition memcard.c:7
s32 syncMemCard(void)
MemCardSync, retrying a failed command up to maxRetries times.
Definition memcard.c:105
const char SAVE_FILE_NAMES[2][24]
Definition memcard.c:48
s32 verifyChecksum(void *data, s32 size, char expected)
XOR of every byte.
Definition memcard.c:443
s32 unformatMemCard(void)
memCardCommand's MEMCARD_OP_UNFORMAT, left out: always fails as if there were no card
Definition memcard.c:438
s32 MEMCARD_SYNC_CMDS[MEMCARD_OP_UNFORMAT+1]
The commands of memCardCommand's operations.
Definition memcard.c:474
s32 acceptMemCard(s32 port)
Checks a card in port port in full, finding out whether it is new or unformatted (MemCardAccept)
Definition memcard.c:160
s32 createSave(s32 port)
Creates the save file on the card.
Definition memcard.c:418
long MemCardCreateFile(long chan, const char *file, long blocks)
long MemCardAccept(long chan)
#define CARD_ERR_NEW_CARD
Definition memcard.h:33
@ SAVE_SECTION_INFO
Definition memcard.h:51
@ SAVE_SECTION_HEADER
Definition memcard.h:51
@ SAVE_SECTION_DATA
Definition memcard.h:51
#define SAVE_BLOCKS
The blocks of the save file.
Definition memcard.h:15
#define CARD_SECTOR_SIZE
The bytes the card reads or writes at once: one sector.
Definition memcard.h:12
void MemCardInit(long val)
The memory card library, declared here rather than from libmcrd.h, which takes the buffers as u_long ...
long MemCardReadFile(long chan, const char *file, void *adrs, long ofs, long bytes)
#define CARD_HEADER_ICONS
CardHeader.type: this flag plus the icon frame count.
Definition memcard.h:21
void MemCardStart(void)
long MemCardGetDirentry(long chan, char *name, CardDirEntry *dir, long *files, long ofs, long max)
long MemCardUnformat(long chan)
#define CARD_ERR_UNFORMATTED
Definition memcard.h:34
long MemCardExist(long chan)
#define CARD_ERR_NO_CARD
Definition memcard.h:31
#define SAVE_MAX_ICONS
The icon frames a save may have.
Definition memcard.h:18
@ MEMCARD_OP_LIST
Definition memcard.h:54
@ MEMCARD_OP_UNFORMAT
Definition memcard.h:54
@ MEMCARD_OP_FORMAT
Definition memcard.h:54
@ MEMCARD_OP_CREATE
Definition memcard.h:54
long MemCardWriteFile(long chan, const char *file, void *adrs, long ofs, long bytes)
#define CARD_MAX_FILES
The files MEMCARD lists from a card's directory.
Definition memcard.h:24
long MemCardSync(long mode, long *cmds, u_long *result)
#define CARD_ERR_NONE
MemCard.result, as libmcrd's MemCardSync reports it (McErr*), plus CARD_ERR_NOT_STARTED when the comm...
Definition memcard.h:30
long MemCardFormat(long chan)
#define CARD_ERR_NOT_STARTED
Definition memcard.h:38
@ MEMCARD_WRITING
Definition memcard.h:46
@ MEMCARD_ACCEPTING
Definition memcard.h:44
@ MEMCARD_COMMAND
Definition memcard.h:47
@ MEMCARD_READING
Definition memcard.h:45
@ MEMCARD_IDLE
Definition memcard.h:42
@ MEMCARD_CHECKING
Definition memcard.h:43
Memory card save header (first CARD_SECTOR_SIZE bytes of a save)
Definition memcard.h:57
char magic[2]
Definition memcard.h:62
u8 blocks
Definition memcard.h:64
CardClut clut
Definition memcard.h:67
char title[64]
Definition memcard.h:65
void(* zero)(void *ptr, s32 size)
Definition heap.h:32
The memory card functions (MEMCARD_FUNCS); like MemCard's operations, the card ones return 0 while th...
Definition memcard.h:110
Memory card access (MEMCARD), one step per call: every operation returns 0 while it runs,...
Definition memcard.h:86
s32 dataSize
Definition memcard.h:101
long fileCount
long: MemCardGetDirentry writes it
Definition memcard.h:96
s32 infoSize
Definition memcard.h:102
s32 cmd
Definition memcard.h:91
u32 result
Definition memcard.h:92
s32 offset
Definition memcard.h:99
void * icons[3]
each frame's image (setSaveHeader)
Definition memcard.h:104
CardDirEntry files[15]
Definition memcard.h:97
s32 progress
Definition memcard.h:98
s32 restart
the command failed and must be reissued
Definition memcard.h:95
s32 iconCount
Definition memcard.h:103
const char * fileName
Definition memcard.h:89
s32 maxRetries
Definition memcard.h:94
s32 state
MEMCARD_*.
Definition memcard.h:87
CardHeader header
Definition memcard.h:90
s32 retries
Definition memcard.h:93