diff options
Diffstat (limited to 'apps/plugins/rockboy/loader.c')
-rw-r--r-- | apps/plugins/rockboy/loader.c | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/apps/plugins/rockboy/loader.c b/apps/plugins/rockboy/loader.c new file mode 100644 index 0000000000..ad7c309bd8 --- /dev/null +++ b/apps/plugins/rockboy/loader.c | |||
@@ -0,0 +1,383 @@ | |||
1 | |||
2 | #include <stdio.h> | ||
3 | #include <string.h> | ||
4 | |||
5 | |||
6 | #include "rockmacros.h" | ||
7 | #include "defs.h" | ||
8 | #include "regs.h" | ||
9 | #include "mem.h" | ||
10 | #include "hw.h" | ||
11 | #include "rtc.h" | ||
12 | #include "rc.h" | ||
13 | #include "save.h" | ||
14 | #include "sound.h" | ||
15 | |||
16 | |||
17 | static int mbc_table[256] = | ||
18 | { | ||
19 | 0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, | ||
20 | 3, 3, 3, 3, 0, 0, 0, 0, 0, 5, 5, 5, MBC_RUMBLE, MBC_RUMBLE, MBC_RUMBLE, 0, | ||
21 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
22 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
23 | |||
24 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
26 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
27 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
28 | |||
29 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
30 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
33 | |||
34 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
36 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MBC_HUC3, MBC_HUC1 | ||
38 | }; | ||
39 | |||
40 | static int rtc_table[256] = | ||
41 | { | ||
42 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, | ||
43 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
44 | 0 | ||
45 | }; | ||
46 | |||
47 | static int batt_table[256] = | ||
48 | { | ||
49 | 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, | ||
50 | 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, | ||
51 | 0 | ||
52 | }; | ||
53 | |||
54 | static int romsize_table[256] = | ||
55 | { | ||
56 | 2, 4, 8, 16, 32, 64, 128, 256, 512, | ||
57 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
58 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
59 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
60 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
61 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
62 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
63 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
64 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
65 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
66 | 0, 0, 128, 128, 128 | ||
67 | /* 0, 0, 72, 80, 96 -- actual values but bad to use these! */ | ||
68 | }; | ||
69 | |||
70 | static int ramsize_table[256] = | ||
71 | { | ||
72 | 1, 1, 1, 4, 16, | ||
73 | 4 /* FIXME - what value should this be?! */ | ||
74 | }; | ||
75 | |||
76 | |||
77 | static char *romfile; | ||
78 | static char sramfile[500]; | ||
79 | static char rtcfile[500]; | ||
80 | static char saveprefix[500]; | ||
81 | |||
82 | static char *savename; | ||
83 | static char *savedir = "/.rockbox/rockboy"; | ||
84 | |||
85 | static int saveslot; | ||
86 | |||
87 | static int forcebatt, nobatt; | ||
88 | static int forcedmg; | ||
89 | |||
90 | static int memfill = -1, memrand = -1; | ||
91 | |||
92 | //static byte romMemory[4*1025*1024]; | ||
93 | int mp3_buffer_size; | ||
94 | void *bufferpos; | ||
95 | |||
96 | static void initmem(void *mem, int size) | ||
97 | { | ||
98 | char *p = mem; | ||
99 | if (memrand >= 0) | ||
100 | { | ||
101 | srand(memrand ? memrand : -6 ); //time(0)); | ||
102 | while(size--) *(p++) = rand(); | ||
103 | } | ||
104 | else if (memfill >= 0) | ||
105 | memset(p, memfill, size); | ||
106 | } | ||
107 | |||
108 | static byte *loadfile(int fd, int *len) | ||
109 | { | ||
110 | int c, l = 0, p = 0; | ||
111 | |||
112 | byte *d, buf[512]; | ||
113 | d=malloc(32768); | ||
114 | for(;;) | ||
115 | { | ||
116 | c = read(fd, buf, sizeof buf); | ||
117 | if (c <= 0) break; | ||
118 | l += c; | ||
119 | memcpy(d+p, buf, c); | ||
120 | p += c; | ||
121 | } | ||
122 | setmallocpos(d+p+64); | ||
123 | *len = l; | ||
124 | return d; | ||
125 | } | ||
126 | |||
127 | //static byte sram[65536]; | ||
128 | |||
129 | int rom_load(void) | ||
130 | { | ||
131 | int fd; | ||
132 | byte c, *data, *header; | ||
133 | int len = 0, rlen; | ||
134 | |||
135 | fd = open(romfile, O_RDONLY); | ||
136 | |||
137 | if (fd<0) { | ||
138 | die("cannot open rom file"); | ||
139 | die(romfile); | ||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | data = loadfile(fd, &len); | ||
144 | header = data; // no zip. = decompress(data, &len); | ||
145 | |||
146 | memcpy(rom.name, header+0x0134, 16); | ||
147 | if (rom.name[14] & 0x80) rom.name[14] = 0; | ||
148 | if (rom.name[15] & 0x80) rom.name[15] = 0; | ||
149 | rom.name[16] = 0; | ||
150 | |||
151 | c = header[0x0147]; | ||
152 | mbc.type = mbc_table[c]; | ||
153 | mbc.batt = (batt_table[c] && !nobatt) || forcebatt; | ||
154 | // mbc.batt = 1; // always store savegame mem. | ||
155 | rtc.batt = rtc_table[c]; | ||
156 | mbc.romsize = romsize_table[header[0x0148]]; | ||
157 | mbc.ramsize = ramsize_table[header[0x0149]]; | ||
158 | |||
159 | if (!mbc.romsize) { | ||
160 | die("unknown ROM size %02X\n", header[0x0148]); | ||
161 | return 1; | ||
162 | } | ||
163 | if (!mbc.ramsize) { | ||
164 | die("unknown SRAM size %02X\n", header[0x0149]); | ||
165 | return 1; | ||
166 | } | ||
167 | |||
168 | rlen = 16384 * mbc.romsize; | ||
169 | rom.bank = (void *) data; //realloc(data, rlen); | ||
170 | if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len); | ||
171 | |||
172 | ram.sbank = malloc(8192 * mbc.ramsize); | ||
173 | //ram.ibank = malloc(4096*8); | ||
174 | |||
175 | initmem(ram.sbank, 8192 * mbc.ramsize); | ||
176 | initmem(ram.ibank, 4096 * 8); | ||
177 | |||
178 | mbc.rombank = 1; | ||
179 | mbc.rambank = 0; | ||
180 | |||
181 | c = header[0x0143]; | ||
182 | hw.cgb = ((c == 0x80) || (c == 0xc0)) && !forcedmg; | ||
183 | hw.gba = 0; //(hw.cgb && gbamode); | ||
184 | |||
185 | close(fd); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | int sram_load(void) | ||
191 | { | ||
192 | int fd; | ||
193 | char meow[500]; | ||
194 | |||
195 | if (!mbc.batt || !sramfile || !*sramfile) return -1; | ||
196 | |||
197 | /* Consider sram loaded at this point, even if file doesn't exist */ | ||
198 | ram.loaded = 1; | ||
199 | |||
200 | fd = open(sramfile, O_RDONLY); | ||
201 | snprintf(meow,499,"Opening %s %d",sramfile,fd); | ||
202 | rb->splash(HZ*2, true, meow); | ||
203 | if (fd<0) return -1; | ||
204 | snprintf(meow,499,"Loading savedata from %s",sramfile); | ||
205 | rb->splash(HZ*2, true, meow); | ||
206 | read(fd,ram.sbank, 8192*mbc.ramsize); | ||
207 | close(fd); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | |||
213 | int sram_save(void) | ||
214 | { | ||
215 | int fd; | ||
216 | char meow[500]; | ||
217 | |||
218 | /* If we crash before we ever loaded sram, DO NOT SAVE! */ | ||
219 | if (!mbc.batt || !sramfile || !ram.loaded || !mbc.ramsize) | ||
220 | return -1; | ||
221 | fd = open(sramfile, O_WRONLY|O_CREAT); | ||
222 | // snprintf(meow,499,"Opening %s %d",sramfile,fd); | ||
223 | // rb->splash(HZ*2, true, meow); | ||
224 | if (fd<0) return -1; | ||
225 | snprintf(meow,499,"Saving savedata to %s",sramfile); | ||
226 | rb->splash(HZ*2, true, meow); | ||
227 | write(fd,ram.sbank, 8192*mbc.ramsize); | ||
228 | close(fd); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | |||
234 | void state_save(int n) | ||
235 | { | ||
236 | int fd; | ||
237 | char name[500]; | ||
238 | |||
239 | if (n < 0) n = saveslot; | ||
240 | if (n < 0) n = 0; | ||
241 | snprintf(name, 499,"%s.%03d", saveprefix, n); | ||
242 | |||
243 | if ((fd = open(name, O_WRONLY|O_CREAT)>=0)) | ||
244 | { | ||
245 | savestate(fd); | ||
246 | close(fd); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | |||
251 | void state_load(int n) | ||
252 | { | ||
253 | int fd; | ||
254 | char name[500]; | ||
255 | |||
256 | if (n < 0) n = saveslot; | ||
257 | if (n < 0) n = 0; | ||
258 | snprintf(name, 499, "%s.%03d", saveprefix, n); | ||
259 | |||
260 | if ((fd = open(name, O_RDONLY)>=0)) | ||
261 | { | ||
262 | loadstate(fd); | ||
263 | close(fd); | ||
264 | vram_dirty(); | ||
265 | pal_dirty(); | ||
266 | sound_dirty(); | ||
267 | mem_updatemap(); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | void rtc_save(void) | ||
272 | { | ||
273 | int fd; | ||
274 | if (!rtc.batt) return; | ||
275 | if ((fd = open(rtcfile, O_WRONLY|O_CREAT))<0) return; | ||
276 | rtc_save_internal(fd); | ||
277 | close(fd); | ||
278 | } | ||
279 | |||
280 | void rtc_load(void) | ||
281 | { | ||
282 | int fd; | ||
283 | if (!rtc.batt) return; | ||
284 | if ((fd = open(rtcfile, O_RDONLY))<0) return; | ||
285 | rtc_load_internal(fd); | ||
286 | close(fd); | ||
287 | } | ||
288 | |||
289 | |||
290 | void loader_unload(void) | ||
291 | { | ||
292 | sram_save(); | ||
293 | // if (romfile) free(romfile); | ||
294 | // if (sramfile) free(sramfile); | ||
295 | // if (saveprefix) free(saveprefix); | ||
296 | // if (rom.bank) free(rom.bank); | ||
297 | // if (ram.sbank) free(ram.sbank); | ||
298 | romfile = 0; | ||
299 | rom.bank = 0; | ||
300 | ram.sbank = 0; | ||
301 | mbc.type = mbc.romsize = mbc.ramsize = mbc.batt = 0; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | static char *base(char *s) | ||
306 | { | ||
307 | char *p; | ||
308 | p = strrchr(s, '/'); | ||
309 | if (p) return p+1; | ||
310 | return s; | ||
311 | } | ||
312 | |||
313 | |||
314 | static char *ldup(char *s) | ||
315 | { | ||
316 | int i; | ||
317 | char *n, *p; | ||
318 | p = n = malloc(strlen(s)); | ||
319 | for (i = 0; s[i]; i++) if (isalnum(s[i])) *(p++) = tolower(s[i]); | ||
320 | *p = 0; | ||
321 | return n; | ||
322 | }*/ | ||
323 | |||
324 | void cleanup(void) | ||
325 | { | ||
326 | sram_save(); | ||
327 | rtc_save(); | ||
328 | // IDEA - if error, write emergency savestate..? | ||
329 | } | ||
330 | |||
331 | void loader_init(char *s) | ||
332 | { | ||
333 | char *name; | ||
334 | DIR* dir; | ||
335 | |||
336 | // sys_checkdir(savedir, 1); /* needs to be writable */ | ||
337 | dir=opendir(savedir); | ||
338 | if(!dir) | ||
339 | mkdir(savedir,0); | ||
340 | else | ||
341 | closedir(dir); | ||
342 | |||
343 | romfile = s; | ||
344 | if(rom_load()) | ||
345 | return; | ||
346 | vid_settitle(rom.name); | ||
347 | name = rom.name; | ||
348 | |||
349 | snprintf(saveprefix, 499, "%s/%s", savedir, name); | ||
350 | |||
351 | strcpy(sramfile, saveprefix); | ||
352 | strcat(sramfile, ".sav"); | ||
353 | |||
354 | strcpy(rtcfile, saveprefix); | ||
355 | strcat(rtcfile, ".rtc"); | ||
356 | |||
357 | sram_load(); | ||
358 | rtc_load(); | ||
359 | |||
360 | //atexit(cleanup); | ||
361 | } | ||
362 | |||
363 | rcvar_t loader_exports[] = | ||
364 | { | ||
365 | RCV_STRING("savedir", &savedir), | ||
366 | RCV_STRING("savename", &savename), | ||
367 | RCV_INT("saveslot", &saveslot), | ||
368 | RCV_BOOL("forcebatt", &forcebatt), | ||
369 | RCV_BOOL("nobatt", &nobatt), | ||
370 | RCV_BOOL("forcedmg", &forcedmg), | ||
371 | RCV_INT("memfill", &memfill), | ||
372 | RCV_INT("memrand", &memrand), | ||
373 | RCV_END | ||
374 | }; | ||
375 | |||
376 | |||
377 | |||
378 | |||
379 | |||
380 | |||
381 | |||
382 | |||
383 | |||