Mercurial > vba-clojure
comparison src/common/Util.cpp @ 496:a6d060a64246
pixel introspection. but entire image is upside down.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 11 Jun 2012 06:04:25 -0500 |
parents | f94fa48624d0 |
children |
comparison
equal
deleted
inserted
replaced
495:1d81ddd4fa41 | 496:a6d060a64246 |
---|---|
46 //Kludge to get it to compile in Linux, GCC cannot convert | 46 //Kludge to get it to compile in Linux, GCC cannot convert |
47 //gzwrite function pointer to the type of utilGzWriteFunc | 47 //gzwrite function pointer to the type of utilGzWriteFunc |
48 //due to void* and const void* differences | 48 //due to void* and const void* differences |
49 //--Felipe | 49 //--Felipe |
50 int gzWrite(gzFile file, void* buf, unsigned len){ | 50 int gzWrite(gzFile file, void* buf, unsigned len){ |
51 return gzwrite(file,buf,len); | 51 return gzwrite(file,buf,len); |
52 } | 52 } |
53 | 53 |
54 void utilPutDword(u8 *p, u32 value) | 54 void utilPutDword(u8 *p, u32 value) |
55 { | 55 { |
56 *p++ = value & 255; | 56 *p++ = value & 255; |
57 *p++ = (value >> 8) & 255; | 57 *p++ = (value >> 8) & 255; |
58 *p++ = (value >> 16) & 255; | 58 *p++ = (value >> 16) & 255; |
59 *p = (value >> 24) & 255; | 59 *p = (value >> 24) & 255; |
60 } | 60 } |
61 | 61 |
62 void utilPutWord(u8 *p, u16 value) | 62 void utilPutWord(u8 *p, u16 value) |
63 { | 63 { |
64 *p++ = value & 255; | 64 *p++ = value & 255; |
65 *p = (value >> 8) & 255; | 65 *p = (value >> 8) & 255; |
66 } | 66 } |
67 | 67 |
68 void utilWriteBMP(u8 *b, int w, int h, int dstDepth, u8 *pix) | 68 void utilWriteBMP(u8 *b, int w, int h, int dstDepth, u8 *pix) |
69 { | 69 { |
70 int sizeX = w; | 70 int sizeX = w; |
71 int sizeY = h; | 71 int sizeY = h; |
72 | 72 |
73 switch (dstDepth > 0 ? dstDepth : systemColorDepth) | 73 switch (dstDepth > 0 ? dstDepth : systemColorDepth) |
74 { | 74 { |
75 case 16: | 75 case 16: |
76 { | 76 { |
77 u16 *p = (u16 *)(pix + (w + 2) * (h) * 2); // skip first black line | 77 u16 *p = (u16 *)(pix + (w + 2) * (h) * 2); // skip first black line |
78 for (int y = 0; y < sizeY; y++) | 78 for (int y = 0; y < sizeY; y++) |
79 { | 79 { |
80 for (int x = 0; x < sizeX; x++) | 80 for (int x = 0; x < sizeX; x++) |
81 { | 81 { |
82 u16 v = *p++; | 82 u16 v = *p++; |
83 | 83 |
84 *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B | 84 *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B |
85 *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G | 85 *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G |
86 *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R | 86 *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R |
87 } | 87 } |
88 p++; // skip black pixel for filters | 88 p++; // skip black pixel for filters |
89 p++; // skip black pixel for filters | 89 p++; // skip black pixel for filters |
90 p -= 2 * (w + 2); | 90 p -= 2 * (w + 2); |
91 } | 91 } |
92 break; | 92 break; |
93 } | 93 } |
94 case 24: | 94 case 24: |
95 { | 95 { |
96 u8 *pixU8 = (u8 *)pix + 3 * w * (h - 1); | 96 u8 *pixU8 = (u8 *)pix + 3 * w * (h - 1); |
97 for (int y = 0; y < sizeY; y++) | 97 for (int y = 0; y < sizeY; y++) |
98 { | 98 { |
99 for (int x = 0; x < sizeX; x++) | 99 for (int x = 0; x < sizeX; x++) |
100 { | 100 { |
101 if (systemRedShift > systemBlueShift) | 101 if (systemRedShift > systemBlueShift) |
102 { | 102 { |
103 *b++ = *pixU8++; // B | 103 *b++ = *pixU8++; // B |
104 *b++ = *pixU8++; // G | 104 *b++ = *pixU8++; // G |
105 *b++ = *pixU8++; // R | 105 *b++ = *pixU8++; // R |
106 } | 106 } |
107 else | 107 else |
108 { | 108 { |
109 int red = *pixU8++; | 109 int red = *pixU8++; |
110 int green = *pixU8++; | 110 int green = *pixU8++; |
111 int blue = *pixU8++; | 111 int blue = *pixU8++; |
112 | 112 |
113 *b++ = blue; | 113 *b++ = blue; |
114 *b++ = green; | 114 *b++ = green; |
115 *b++ = red; | 115 *b++ = red; |
116 } | 116 } |
117 } | 117 } |
118 pixU8 -= 2 * 3 * w; | 118 pixU8 -= 2 * 3 * w; |
119 } | 119 } |
120 break; | 120 break; |
121 } | 121 } |
122 case 32: | 122 case 32: |
123 { | 123 { |
124 u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h)); | 124 u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h)); |
125 for (int y = 0; y < sizeY; y++) | 125 for (int y = 0; y < sizeY; y++) |
126 { | 126 { |
127 for (int x = 0; x < sizeX; x++) | 127 for (int x = 0; x < sizeX; x++) |
128 { | 128 { |
129 u32 v = *pixU32++; | 129 u32 v = *pixU32++; |
130 | 130 //RLM pack bits for java ARGB |
131 *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B | 131 |
132 *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G | 132 |
133 *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R | 133 *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R |
134 } | 134 *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G |
135 pixU32++; | 135 *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B |
136 pixU32 -= 2 * (w + 1); | 136 *b++ = 0; // Alpha |
137 } | 137 |
138 break; | 138 |
139 } | 139 |
140 } | 140 // end RLM |
141 | |
142 | |
143 } | |
144 pixU32++; | |
145 pixU32 -= 2 * (w + 1); | |
146 } | |
147 break; | |
148 } | |
149 } | |
141 } | 150 } |
142 | 151 |
143 bool utilWriteBMPFile(const char *fileName, int w, int h, u8 *pix) | 152 bool utilWriteBMPFile(const char *fileName, int w, int h, u8 *pix) |
144 { | 153 { |
145 u8 writeBuffer[256 * 3]; | 154 u8 writeBuffer[256 * 3]; |
146 | 155 |
147 FILE *fp = fopen(fileName, "wb"); | 156 FILE *fp = fopen(fileName, "wb"); |
148 | 157 |
149 if (!fp) | 158 if (!fp) |
150 { | 159 { |
151 systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), fileName); | 160 systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), fileName); |
152 return false; | 161 return false; |
153 } | 162 } |
154 | 163 |
155 struct | 164 struct |
156 { | 165 { |
157 u8 ident[2]; | 166 u8 ident[2]; |
158 u8 filesize[4]; | 167 u8 filesize[4]; |
159 u8 reserved[4]; | 168 u8 reserved[4]; |
160 u8 dataoffset[4]; | 169 u8 dataoffset[4]; |
161 u8 headersize[4]; | 170 u8 headersize[4]; |
162 u8 width[4]; | 171 u8 width[4]; |
163 u8 height[4]; | 172 u8 height[4]; |
164 u8 planes[2]; | 173 u8 planes[2]; |
165 u8 bitsperpixel[2]; | 174 u8 bitsperpixel[2]; |
166 u8 compression[4]; | 175 u8 compression[4]; |
167 u8 datasize[4]; | 176 u8 datasize[4]; |
168 u8 hres[4]; | 177 u8 hres[4]; |
169 u8 vres[4]; | 178 u8 vres[4]; |
170 u8 colors[4]; | 179 u8 colors[4]; |
171 u8 importantcolors[4]; | 180 u8 importantcolors[4]; |
172 // u8 pad[2]; | 181 // u8 pad[2]; |
173 } bmpheader; | 182 } bmpheader; |
174 memset(&bmpheader, 0, sizeof(bmpheader)); | 183 memset(&bmpheader, 0, sizeof(bmpheader)); |
175 | 184 |
176 bmpheader.ident[0] = 'B'; | 185 bmpheader.ident[0] = 'B'; |
177 bmpheader.ident[1] = 'M'; | 186 bmpheader.ident[1] = 'M'; |
178 | 187 |
179 u32 fsz = sizeof(bmpheader) + w * h * 3; | 188 u32 fsz = sizeof(bmpheader) + w * h * 3; |
180 utilPutDword(bmpheader.filesize, fsz); | 189 utilPutDword(bmpheader.filesize, fsz); |
181 utilPutDword(bmpheader.dataoffset, 0x36); | 190 utilPutDword(bmpheader.dataoffset, 0x36); |
182 utilPutDword(bmpheader.headersize, 0x28); | 191 utilPutDword(bmpheader.headersize, 0x28); |
183 utilPutDword(bmpheader.width, w); | 192 utilPutDword(bmpheader.width, w); |
184 utilPutDword(bmpheader.height, h); | 193 utilPutDword(bmpheader.height, h); |
185 utilPutDword(bmpheader.planes, 1); | 194 utilPutDword(bmpheader.planes, 1); |
186 utilPutDword(bmpheader.bitsperpixel, 24); | 195 utilPutDword(bmpheader.bitsperpixel, 24); |
187 utilPutDword(bmpheader.datasize, 3 * w * h); | 196 utilPutDword(bmpheader.datasize, 3 * w * h); |
188 | 197 |
189 fwrite(&bmpheader, 1, sizeof(bmpheader), fp); | 198 fwrite(&bmpheader, 1, sizeof(bmpheader), fp); |
190 | 199 |
191 #if 0 | 200 #if 0 |
192 // FIXME: need sufficient buffer | 201 // FIXME: need sufficient buffer |
193 utilWriteBMP(writeBuffer, w, h, systemColorDepth, pix); | 202 utilWriteBMP(writeBuffer, w, h, systemColorDepth, pix); |
194 #else | 203 #else |
195 u8 *b = writeBuffer; | 204 u8 *b = writeBuffer; |
196 | 205 |
197 int sizeX = w; | 206 int sizeX = w; |
198 int sizeY = h; | 207 int sizeY = h; |
199 | 208 |
200 switch (systemColorDepth) | 209 switch (systemColorDepth) |
201 { | 210 { |
202 case 16: | 211 case 16: |
203 { | 212 { |
204 u16 *p = (u16 *)(pix + (w + 2) * (h) * 2); // skip first black line | 213 u16 *p = (u16 *)(pix + (w + 2) * (h) * 2); // skip first black line |
205 for (int y = 0; y < sizeY; y++) | 214 for (int y = 0; y < sizeY; y++) |
206 { | 215 { |
207 for (int x = 0; x < sizeX; x++) | 216 for (int x = 0; x < sizeX; x++) |
208 { | 217 { |
209 u16 v = *p++; | 218 u16 v = *p++; |
210 | 219 |
211 *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B | 220 *b++ = ((v >> systemBlueShift) & 0x01f) << 3; // B |
212 *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G | 221 *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G |
213 *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R | 222 *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R |
214 } | 223 } |
215 p++; // skip black pixel for filters | 224 p++; // skip black pixel for filters |
216 p++; // skip black pixel for filters | 225 p++; // skip black pixel for filters |
217 p -= 2 * (w + 2); | 226 p -= 2 * (w + 2); |
218 fwrite(writeBuffer, 1, 3 * w, fp); | 227 fwrite(writeBuffer, 1, 3 * w, fp); |
219 | 228 |
220 b = writeBuffer; | 229 b = writeBuffer; |
221 } | 230 } |
222 break; | 231 break; |
223 } | 232 } |
224 case 24: | 233 case 24: |
225 { | 234 { |
226 u8 *pixU8 = (u8 *)pix + 3 * w * (h - 1); | 235 u8 *pixU8 = (u8 *)pix + 3 * w * (h - 1); |
227 for (int y = 0; y < sizeY; y++) | 236 for (int y = 0; y < sizeY; y++) |
228 { | 237 { |
229 for (int x = 0; x < sizeX; x++) | 238 for (int x = 0; x < sizeX; x++) |
230 { | 239 { |
231 if (systemRedShift > systemBlueShift) | 240 if (systemRedShift > systemBlueShift) |
232 { | 241 { |
233 *b++ = *pixU8++; // B | 242 *b++ = *pixU8++; // B |
234 *b++ = *pixU8++; // G | 243 *b++ = *pixU8++; // G |
235 *b++ = *pixU8++; // R | 244 *b++ = *pixU8++; // R |
236 } | 245 } |
237 else | 246 else |
238 { | 247 { |
239 int red = *pixU8++; | 248 int red = *pixU8++; |
240 int green = *pixU8++; | 249 int green = *pixU8++; |
241 int blue = *pixU8++; | 250 int blue = *pixU8++; |
242 | 251 |
243 *b++ = blue; | 252 *b++ = blue; |
244 *b++ = green; | 253 *b++ = green; |
245 *b++ = red; | 254 *b++ = red; |
246 } | 255 } |
247 } | 256 } |
248 pixU8 -= 2 * 3 * w; | 257 pixU8 -= 2 * 3 * w; |
249 fwrite(writeBuffer, 1, 3 * w, fp); | 258 fwrite(writeBuffer, 1, 3 * w, fp); |
250 | 259 |
251 b = writeBuffer; | 260 b = writeBuffer; |
252 } | 261 } |
253 break; | 262 break; |
254 } | 263 } |
255 case 32: | 264 case 32: |
256 { | 265 { |
257 u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h)); | 266 u32 *pixU32 = (u32 *)(pix + 4 * (w + 1) * (h)); |
258 for (int y = 0; y < sizeY; y++) | 267 for (int y = 0; y < sizeY; y++) |
259 { | 268 { |
260 for (int x = 0; x < sizeX; x++) | 269 for (int x = 0; x < sizeX; x++) |
261 { | 270 { |
262 u32 v = *pixU32++; | 271 u32 v = *pixU32++; |
263 | 272 |
264 *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B | 273 *b++ = ((v >> systemBlueShift) & 0x001f) << 3; // B |
265 *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G | 274 *b++ = ((v >> systemGreenShift) & 0x001f) << 3; // G |
266 *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R | 275 *b++ = ((v >> systemRedShift) & 0x001f) << 3; // R |
267 } | 276 } |
268 pixU32++; | 277 pixU32++; |
269 pixU32 -= 2 * (w + 1); | 278 pixU32 -= 2 * (w + 1); |
270 | 279 |
271 fwrite(writeBuffer, 1, 3 * w, fp); | 280 fwrite(writeBuffer, 1, 3 * w, fp); |
272 | 281 |
273 b = writeBuffer; | 282 b = writeBuffer; |
274 } | 283 } |
275 break; | 284 break; |
276 } | 285 } |
277 } | 286 } |
278 #endif | 287 #endif |
279 | 288 |
280 fclose(fp); | 289 fclose(fp); |
281 | 290 |
282 return true; | 291 return true; |
283 } | 292 } |
284 | 293 |
285 bool utilWritePNGFile(const char *fileName, int w, int h, u8 *pix) | 294 bool utilWritePNGFile(const char *fileName, int w, int h, u8 *pix) |
286 { | 295 { |
287 u8 writeBuffer[256 * 3]; | 296 u8 writeBuffer[256 * 3]; |
424 return true; | 433 return true; |
425 } | 434 } |
426 | 435 |
427 static int utilReadInt2(FILE *f) | 436 static int utilReadInt2(FILE *f) |
428 { | 437 { |
429 int res = 0; | 438 int res = 0; |
430 int c = fgetc(f); | 439 int c = fgetc(f); |
431 if (c == EOF) | 440 if (c == EOF) |
432 return -1; | 441 return -1; |
433 res = c; | 442 res = c; |
434 c = fgetc(f); | 443 c = fgetc(f); |
435 if (c == EOF) | 444 if (c == EOF) |
436 return -1; | 445 return -1; |
437 return c + (res << 8); | 446 return c + (res << 8); |
438 } | 447 } |
439 | 448 |
440 static int utilReadInt3(FILE *f) | 449 static int utilReadInt3(FILE *f) |
441 { | 450 { |
442 int res = 0; | 451 int res = 0; |
443 int c = fgetc(f); | 452 int c = fgetc(f); |
444 if (c == EOF) | 453 if (c == EOF) |
445 return -1; | 454 return -1; |
446 res = c; | 455 res = c; |
447 c = fgetc(f); | 456 c = fgetc(f); |
448 if (c == EOF) | 457 if (c == EOF) |
449 return -1; | 458 return -1; |
450 res = c + (res << 8); | 459 res = c + (res << 8); |
451 c = fgetc(f); | 460 c = fgetc(f); |
452 if (c == EOF) | 461 if (c == EOF) |
453 return -1; | 462 return -1; |
454 return c + (res << 8); | 463 return c + (res << 8); |
455 } | 464 } |
456 | 465 |
457 void utilApplyIPS(const char *ips, u8 * *r, int *s) | 466 void utilApplyIPS(const char *ips, u8 * *r, int *s) |
458 { | 467 { |
459 // from the IPS spec at http://zerosoft.zophar.net/ips.htm | 468 // from the IPS spec at http://zerosoft.zophar.net/ips.htm |
460 FILE *f = fopen(ips, "rb"); | 469 FILE *f = fopen(ips, "rb"); |
461 if (!f) | 470 if (!f) |
462 return; | 471 return; |
463 u8 *rom = *r; | 472 u8 *rom = *r; |
464 int size = *s; | 473 int size = *s; |
465 if (fgetc(f) == 'P' && | 474 if (fgetc(f) == 'P' && |
466 fgetc(f) == 'A' && | 475 fgetc(f) == 'A' && |
467 fgetc(f) == 'T' && | 476 fgetc(f) == 'T' && |
468 fgetc(f) == 'C' && | 477 fgetc(f) == 'C' && |
469 fgetc(f) == 'H') | 478 fgetc(f) == 'H') |
470 { | 479 { |
471 int b; | 480 int b; |
472 int offset; | 481 int offset; |
473 int len; | 482 int len; |
474 for (;; ) | 483 for (;; ) |
484 { | |
485 // read offset | |
486 offset = utilReadInt3(f); | |
487 // if offset == EOF, end of patch | |
488 if (offset == 0x454f46) | |
489 break; | |
490 // read length | |
491 len = utilReadInt2(f); | |
492 if (!len) | |
493 { | |
494 // len == 0, RLE block | |
495 len = utilReadInt2(f); | |
496 // byte to fill | |
497 int c = fgetc(f); | |
498 if (c == -1) | |
499 break; | |
500 b = (u8)c; | |
501 } | |
502 else | |
503 b = -1; | |
504 // check if we need to reallocate our ROM | |
505 if ((offset + len) >= size) | |
506 { | |
507 size *= 2; | |
508 rom = (u8 *)realloc(rom, size); | |
509 *r = rom; | |
510 *s = size; | |
511 } | |
512 if (b == -1) | |
513 { | |
514 // normal block, just read the data | |
515 if (fread(&rom[offset], 1, len, f) != (size_t)len) | |
516 break; | |
517 } | |
518 else | |
519 { | |
520 // fill the region with the given byte | |
521 while (len--) | |
475 { | 522 { |
476 // read offset | 523 rom[offset++] = b; |
477 offset = utilReadInt3(f); | |
478 // if offset == EOF, end of patch | |
479 if (offset == 0x454f46) | |
480 break; | |
481 // read length | |
482 len = utilReadInt2(f); | |
483 if (!len) | |
484 { | |
485 // len == 0, RLE block | |
486 len = utilReadInt2(f); | |
487 // byte to fill | |
488 int c = fgetc(f); | |
489 if (c == -1) | |
490 break; | |
491 b = (u8)c; | |
492 } | |
493 else | |
494 b = -1; | |
495 // check if we need to reallocate our ROM | |
496 if ((offset + len) >= size) | |
497 { | |
498 size *= 2; | |
499 rom = (u8 *)realloc(rom, size); | |
500 *r = rom; | |
501 *s = size; | |
502 } | |
503 if (b == -1) | |
504 { | |
505 // normal block, just read the data | |
506 if (fread(&rom[offset], 1, len, f) != (size_t)len) | |
507 break; | |
508 } | |
509 else | |
510 { | |
511 // fill the region with the given byte | |
512 while (len--) | |
513 { | |
514 rom[offset++] = b; | |
515 } | |
516 } | |
517 } | 524 } |
518 } | 525 } |
519 // close the file | 526 } |
520 fclose(f); | 527 } |
528 // close the file | |
529 fclose(f); | |
521 } | 530 } |
522 | 531 |
523 extern bool8 cpuIsMultiBoot; | 532 extern bool8 cpuIsMultiBoot; |
524 | 533 |
525 bool utilIsGBAImage(const char *file) | 534 bool utilIsGBAImage(const char *file) |
526 { | 535 { |
527 cpuIsMultiBoot = false; | 536 cpuIsMultiBoot = false; |
528 if (strlen(file) > 4) | 537 if (strlen(file) > 4) |
529 { | 538 { |
530 const char *p = strrchr(file, '.'); | 539 const char *p = strrchr(file, '.'); |
531 | 540 |
532 if (p != NULL) | 541 if (p != NULL) |
533 { | 542 { |
534 if (_stricmp(p, ".gba") == 0) | 543 if (_stricmp(p, ".gba") == 0) |
535 return true; | 544 return true; |
536 if (_stricmp(p, ".agb") == 0) | 545 if (_stricmp(p, ".agb") == 0) |
537 return true; | 546 return true; |
538 if (_stricmp(p, ".bin") == 0) | 547 if (_stricmp(p, ".bin") == 0) |
539 return true; | 548 return true; |
540 if (_stricmp(p, ".elf") == 0) | 549 if (_stricmp(p, ".elf") == 0) |
541 return true; | 550 return true; |
542 if (_stricmp(p, ".mb") == 0) | 551 if (_stricmp(p, ".mb") == 0) |
543 { | 552 { |
544 cpuIsMultiBoot = true; | 553 cpuIsMultiBoot = true; |
545 return true; | 554 return true; |
546 } | 555 } |
547 } | 556 } |
548 } | 557 } |
549 | 558 |
550 return false; | 559 return false; |
551 } | 560 } |
552 | 561 |
553 bool utilIsGBImage(const char *file) | 562 bool utilIsGBImage(const char *file) |
554 { | 563 { |
555 if (strlen(file) > 4) | 564 if (strlen(file) > 4) |
556 { | 565 { |
557 const char *p = strrchr(file, '.'); | 566 const char *p = strrchr(file, '.'); |
558 | 567 |
559 if (p != NULL) | 568 if (p != NULL) |
560 { | 569 { |
561 if (_stricmp(p, ".gb") == 0) | 570 if (_stricmp(p, ".gb") == 0) |
562 return true; | 571 return true; |
563 if (_stricmp(p, ".gbc") == 0) | 572 if (_stricmp(p, ".gbc") == 0) |
564 return true; | 573 return true; |
565 if (_stricmp(p, ".cgb") == 0) | 574 if (_stricmp(p, ".cgb") == 0) |
566 return true; | 575 return true; |
567 if (_stricmp(p, ".sgb") == 0) | 576 if (_stricmp(p, ".sgb") == 0) |
568 return true; | 577 return true; |
569 } | 578 } |
570 } | 579 } |
571 | 580 |
572 return false; | 581 return false; |
573 } | 582 } |
574 | 583 |
575 bool utilIsGBABios(const char *file) | 584 bool utilIsGBABios(const char *file) |
576 { | 585 { |
577 if (strlen(file) > 4) | 586 if (strlen(file) > 4) |
578 { | 587 { |
579 const char *p = strrchr(file, '.'); | 588 const char *p = strrchr(file, '.'); |
580 | 589 |
581 if (p != NULL) | 590 if (p != NULL) |
582 { | 591 { |
583 if (_stricmp(p, ".gba") == 0) | 592 if (_stricmp(p, ".gba") == 0) |
584 return true; | 593 return true; |
585 if (_stricmp(p, ".agb") == 0) | 594 if (_stricmp(p, ".agb") == 0) |
586 return true; | 595 return true; |
587 if (_stricmp(p, ".bin") == 0) | 596 if (_stricmp(p, ".bin") == 0) |
588 return true; | 597 return true; |
589 if (_stricmp(p, ".bios") == 0) | 598 if (_stricmp(p, ".bios") == 0) |
590 return true; | 599 return true; |
591 if (_stricmp(p, ".rom") == 0) | 600 if (_stricmp(p, ".rom") == 0) |
592 return true; | 601 return true; |
593 } | 602 } |
594 } | 603 } |
595 | 604 |
596 return false; | 605 return false; |
597 } | 606 } |
598 | 607 |
599 bool utilIsGBBios(const char *file) | 608 bool utilIsGBBios(const char *file) |
600 { | 609 { |
601 if (strlen(file) > 4) | 610 if (strlen(file) > 4) |
602 { | 611 { |
603 const char *p = strrchr(file, '.'); | 612 const char *p = strrchr(file, '.'); |
604 | 613 |
605 if (p != NULL) | 614 if (p != NULL) |
606 { | 615 { |
607 if (_stricmp(p, ".gb") == 0) | 616 if (_stricmp(p, ".gb") == 0) |
608 return true; | 617 return true; |
609 if (_stricmp(p, ".bin") == 0) | 618 if (_stricmp(p, ".bin") == 0) |
610 return true; | 619 return true; |
611 if (_stricmp(p, ".bios") == 0) | 620 if (_stricmp(p, ".bios") == 0) |
612 return true; | 621 return true; |
613 if (_stricmp(p, ".rom") == 0) | 622 if (_stricmp(p, ".rom") == 0) |
614 return true; | 623 return true; |
615 } | 624 } |
616 } | 625 } |
617 | 626 |
618 return false; | 627 return false; |
619 } | 628 } |
620 | 629 |
621 bool utilIsELF(const char *file) | 630 bool utilIsELF(const char *file) |
622 { | 631 { |
623 if (strlen(file) > 4) | 632 if (strlen(file) > 4) |
624 { | 633 { |
625 const char *p = strrchr(file, '.'); | 634 const char *p = strrchr(file, '.'); |
626 | 635 |
627 if (p != NULL) | 636 if (p != NULL) |
628 { | 637 { |
629 if (_stricmp(p, ".elf") == 0) | 638 if (_stricmp(p, ".elf") == 0) |
630 return true; | 639 return true; |
631 } | 640 } |
632 } | 641 } |
633 return false; | 642 return false; |
634 } | 643 } |
635 | 644 |
636 bool utilIsZipFile(const char *file) | 645 bool utilIsZipFile(const char *file) |
637 { | 646 { |
638 if (strlen(file) > 4) | 647 if (strlen(file) > 4) |
639 { | 648 { |
640 const char *p = strrchr(file, '.'); | 649 const char *p = strrchr(file, '.'); |
641 | 650 |
642 if (p != NULL) | 651 if (p != NULL) |
643 { | 652 { |
644 if (_stricmp(p, ".zip") == 0) | 653 if (_stricmp(p, ".zip") == 0) |
645 return true; | 654 return true; |
646 } | 655 } |
647 } | 656 } |
648 | 657 |
649 return false; | 658 return false; |
650 } | 659 } |
651 | 660 |
652 #if 0 | 661 #if 0 |
653 bool utilIsRarFile(const char *file) | 662 bool utilIsRarFile(const char *file) |
654 { | 663 { |
655 if (strlen(file) > 4) | 664 if (strlen(file) > 4) |
656 { | 665 { |
657 char *p = strrchr(file, '.'); | 666 char *p = strrchr(file, '.'); |
658 | 667 |
659 if (p != NULL) | 668 if (p != NULL) |
669 { | |
670 if (_stricmp(p, ".rar") == 0) | |
671 return true; | |
672 } | |
673 } | |
674 | |
675 return false; | |
676 } | |
677 | |
678 #endif | |
679 | |
680 bool utilIsGzipFile(const char *file) | |
681 { | |
682 if (strlen(file) > 3) | |
683 { | |
684 const char *p = strrchr(file, '.'); | |
685 | |
686 if (p != NULL) | |
687 { | |
688 if (_stricmp(p, ".gz") == 0) | |
689 return true; | |
690 if (_stricmp(p, ".z") == 0) | |
691 return true; | |
692 } | |
693 } | |
694 | |
695 return false; | |
696 } | |
697 | |
698 void utilGetBaseName(const char *file, char *buffer) | |
699 { | |
700 strcpy(buffer, file); | |
701 | |
702 if (utilIsGzipFile(file)) | |
703 { | |
704 char *p = strrchr(buffer, '.'); | |
705 | |
706 if (p) | |
707 *p = 0; | |
708 } | |
709 } | |
710 | |
711 IMAGE_TYPE utilFindType(const char *file) | |
712 { | |
713 char buffer[2048]; | |
714 | |
715 if (utilIsZipFile(file)) | |
716 { | |
717 unzFile unz = unzOpen(file); | |
718 | |
719 if (unz == NULL) | |
720 { | |
721 systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), file); | |
722 return IMAGE_UNKNOWN; | |
723 } | |
724 | |
725 int r = unzGoToFirstFile(unz); | |
726 | |
727 if (r != UNZ_OK) | |
728 { | |
729 unzClose(unz); | |
730 systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file); | |
731 return IMAGE_UNKNOWN; | |
732 } | |
733 | |
734 IMAGE_TYPE found = IMAGE_UNKNOWN; | |
735 | |
736 unz_file_info info; | |
737 | |
738 while (true) | |
739 { | |
740 r = unzGetCurrentFileInfo(unz, | |
741 &info, | |
742 buffer, | |
743 sizeof(buffer), | |
744 NULL, | |
745 0, | |
746 NULL, | |
747 0); | |
748 | |
749 if (r != UNZ_OK) | |
750 { | |
751 unzClose(unz); | |
752 systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file); | |
753 return IMAGE_UNKNOWN; | |
754 } | |
755 | |
756 if (utilIsGBAImage(buffer)) | |
757 { | |
758 found = IMAGE_GBA; | |
759 break; | |
760 } | |
761 | |
762 if (utilIsGBImage(buffer)) | |
763 { | |
764 found = IMAGE_GB; | |
765 break; | |
766 } | |
767 | |
768 r = unzGoToNextFile(unz); | |
769 | |
770 if (r != UNZ_OK) | |
771 break; | |
772 } | |
773 unzClose(unz); | |
774 | |
775 if (found == IMAGE_UNKNOWN) | |
776 { | |
777 systemMessage(MSG_NO_IMAGE_ON_ZIP, | |
778 N_("No image found on ZIP file %s"), file); | |
779 return found; | |
780 } | |
781 return found; | |
782 #if 0 | |
783 } | |
784 else if (utilIsRarFile(file)) | |
785 { | |
786 IMAGE_TYPE found = IMAGE_UNKNOWN; | |
787 | |
788 ArchiveList_struct *rarList = NULL; | |
789 if (urarlib_list((void *)file, (ArchiveList_struct *)&rarList)) | |
790 { | |
791 ArchiveList_struct *p = rarList; | |
792 | |
793 while (p) | |
794 { | |
795 if (utilIsGBAImage(p->item.Name)) | |
660 { | 796 { |
661 if (_stricmp(p, ".rar") == 0) | 797 found = IMAGE_GBA; |
662 return true; | 798 break; |
663 } | 799 } |
664 } | 800 |
665 | 801 if (utilIsGBImage(p->item.Name)) |
666 return false; | 802 { |
667 } | 803 found = IMAGE_GB; |
668 | 804 break; |
805 } | |
806 p = p->next; | |
807 } | |
808 | |
809 urarlib_freelist(rarList); | |
810 } | |
811 return found; | |
669 #endif | 812 #endif |
670 | 813 } |
671 bool utilIsGzipFile(const char *file) | 814 else |
672 { | 815 { |
673 if (strlen(file) > 3) | 816 if (utilIsGzipFile(file)) |
674 { | 817 utilGetBaseName(file, buffer); |
675 const char *p = strrchr(file, '.'); | 818 else |
676 | |
677 if (p != NULL) | |
678 { | |
679 if (_stricmp(p, ".gz") == 0) | |
680 return true; | |
681 if (_stricmp(p, ".z") == 0) | |
682 return true; | |
683 } | |
684 } | |
685 | |
686 return false; | |
687 } | |
688 | |
689 void utilGetBaseName(const char *file, char *buffer) | |
690 { | |
691 strcpy(buffer, file); | 819 strcpy(buffer, file); |
692 | 820 |
693 if (utilIsGzipFile(file)) | 821 if (utilIsGBAImage(buffer)) |
694 { | 822 return IMAGE_GBA; |
695 char *p = strrchr(buffer, '.'); | 823 if (utilIsGBImage(buffer)) |
696 | 824 return IMAGE_GB; |
697 if (p) | 825 } |
698 *p = 0; | 826 return IMAGE_UNKNOWN; |
699 } | |
700 } | |
701 | |
702 IMAGE_TYPE utilFindType(const char *file) | |
703 { | |
704 char buffer[2048]; | |
705 | |
706 if (utilIsZipFile(file)) | |
707 { | |
708 unzFile unz = unzOpen(file); | |
709 | |
710 if (unz == NULL) | |
711 { | |
712 systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), file); | |
713 return IMAGE_UNKNOWN; | |
714 } | |
715 | |
716 int r = unzGoToFirstFile(unz); | |
717 | |
718 if (r != UNZ_OK) | |
719 { | |
720 unzClose(unz); | |
721 systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file); | |
722 return IMAGE_UNKNOWN; | |
723 } | |
724 | |
725 IMAGE_TYPE found = IMAGE_UNKNOWN; | |
726 | |
727 unz_file_info info; | |
728 | |
729 while (true) | |
730 { | |
731 r = unzGetCurrentFileInfo(unz, | |
732 &info, | |
733 buffer, | |
734 sizeof(buffer), | |
735 NULL, | |
736 0, | |
737 NULL, | |
738 0); | |
739 | |
740 if (r != UNZ_OK) | |
741 { | |
742 unzClose(unz); | |
743 systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file); | |
744 return IMAGE_UNKNOWN; | |
745 } | |
746 | |
747 if (utilIsGBAImage(buffer)) | |
748 { | |
749 found = IMAGE_GBA; | |
750 break; | |
751 } | |
752 | |
753 if (utilIsGBImage(buffer)) | |
754 { | |
755 found = IMAGE_GB; | |
756 break; | |
757 } | |
758 | |
759 r = unzGoToNextFile(unz); | |
760 | |
761 if (r != UNZ_OK) | |
762 break; | |
763 } | |
764 unzClose(unz); | |
765 | |
766 if (found == IMAGE_UNKNOWN) | |
767 { | |
768 systemMessage(MSG_NO_IMAGE_ON_ZIP, | |
769 N_("No image found on ZIP file %s"), file); | |
770 return found; | |
771 } | |
772 return found; | |
773 #if 0 | |
774 } | |
775 else if (utilIsRarFile(file)) | |
776 { | |
777 IMAGE_TYPE found = IMAGE_UNKNOWN; | |
778 | |
779 ArchiveList_struct *rarList = NULL; | |
780 if (urarlib_list((void *)file, (ArchiveList_struct *)&rarList)) | |
781 { | |
782 ArchiveList_struct *p = rarList; | |
783 | |
784 while (p) | |
785 { | |
786 if (utilIsGBAImage(p->item.Name)) | |
787 { | |
788 found = IMAGE_GBA; | |
789 break; | |
790 } | |
791 | |
792 if (utilIsGBImage(p->item.Name)) | |
793 { | |
794 found = IMAGE_GB; | |
795 break; | |
796 } | |
797 p = p->next; | |
798 } | |
799 | |
800 urarlib_freelist(rarList); | |
801 } | |
802 return found; | |
803 #endif | |
804 } | |
805 else | |
806 { | |
807 if (utilIsGzipFile(file)) | |
808 utilGetBaseName(file, buffer); | |
809 else | |
810 strcpy(buffer, file); | |
811 | |
812 if (utilIsGBAImage(buffer)) | |
813 return IMAGE_GBA; | |
814 if (utilIsGBImage(buffer)) | |
815 return IMAGE_GB; | |
816 } | |
817 return IMAGE_UNKNOWN; | |
818 } | 827 } |
819 | 828 |
820 static int utilGetSize(int size) | 829 static int utilGetSize(int size) |
821 { | 830 { |
822 int res = 1; | 831 int res = 1; |
823 while (res < size) | 832 while (res < size) |
824 res <<= 1; | 833 res <<= 1; |
825 return res; | 834 return res; |
826 } | 835 } |
827 | 836 |
828 static u8 *utilLoadFromZip(const char *file, | 837 static u8 *utilLoadFromZip(const char *file, |
829 bool (*accept)(const char *), | 838 bool (*accept)(const char *), |
830 u8 *data, | 839 u8 *data, |
831 int &size) | 840 int &size) |
832 { | 841 { |
833 char buffer[2048]; | 842 char buffer[2048]; |
834 | 843 |
835 unzFile unz = unzOpen(file); | 844 unzFile unz = unzOpen(file); |
836 | 845 |
837 if (unz == NULL) | 846 if (unz == NULL) |
838 { | 847 { |
839 systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), file); | 848 systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), file); |
840 return NULL; | 849 return NULL; |
841 } | 850 } |
842 int r = unzGoToFirstFile(unz); | 851 int r = unzGoToFirstFile(unz); |
843 | 852 |
844 if (r != UNZ_OK) | 853 if (r != UNZ_OK) |
845 { | 854 { |
846 unzClose(unz); | 855 unzClose(unz); |
847 systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file); | 856 systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file); |
848 return NULL; | 857 return NULL; |
849 } | 858 } |
850 | 859 |
851 bool found = false; | 860 bool found = false; |
852 | 861 |
853 unz_file_info info; | 862 unz_file_info info; |
854 | 863 |
855 while (true) | 864 while (true) |
856 { | 865 { |
857 r = unzGetCurrentFileInfo(unz, | 866 r = unzGetCurrentFileInfo(unz, |
858 &info, | 867 &info, |
859 buffer, | 868 buffer, |
860 sizeof(buffer), | 869 sizeof(buffer), |
861 NULL, | 870 NULL, |
862 0, | 871 0, |
863 NULL, | 872 NULL, |
864 0); | 873 0); |
865 | 874 |
866 if (r != UNZ_OK) | 875 if (r != UNZ_OK) |
867 { | 876 { |
868 unzClose(unz); | 877 unzClose(unz); |
869 systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file); | 878 systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file); |
870 return NULL; | 879 return NULL; |
871 } | 880 } |
872 | 881 |
873 if (accept(buffer)) | 882 if (accept(buffer)) |
874 { | 883 { |
875 found = true; | 884 found = true; |
876 break; | 885 break; |
877 } | 886 } |
878 | 887 |
879 r = unzGoToNextFile(unz); | 888 r = unzGoToNextFile(unz); |
880 | 889 |
881 if (r != UNZ_OK) | 890 if (r != UNZ_OK) |
882 break; | 891 break; |
883 } | 892 } |
884 | 893 |
885 if (!found) | 894 if (!found) |
886 { | 895 { |
887 unzClose(unz); | 896 unzClose(unz); |
888 systemMessage(MSG_NO_IMAGE_ON_ZIP, | 897 systemMessage(MSG_NO_IMAGE_ON_ZIP, |
889 N_("No image found on ZIP file %s"), file); | 898 N_("No image found on ZIP file %s"), file); |
890 return NULL; | 899 return NULL; |
891 } | 900 } |
892 | 901 |
893 int fileSize = info.uncompressed_size; | 902 int fileSize = info.uncompressed_size; |
894 if (size == 0) | 903 if (size == 0) |
895 size = fileSize; | 904 size = fileSize; |
896 r = unzOpenCurrentFile(unz); | 905 r = unzOpenCurrentFile(unz); |
897 | 906 |
898 if (r != UNZ_OK) | 907 if (r != UNZ_OK) |
899 { | 908 { |
900 unzClose(unz); | 909 unzClose(unz); |
901 systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), buffer); | 910 systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), buffer); |
902 return NULL; | 911 return NULL; |
903 } | 912 } |
904 | 913 |
905 u8 *image = data; | 914 u8 *image = data; |
906 | 915 |
907 if (image == NULL) | 916 if (image == NULL) |
908 { | 917 { |
909 image = (u8 *)malloc(utilGetSize(size)); | 918 image = (u8 *)malloc(utilGetSize(size)); |
910 if (image == NULL) | 919 if (image == NULL) |
911 { | 920 { |
912 unzCloseCurrentFile(unz); | 921 unzCloseCurrentFile(unz); |
913 unzClose(unz); | 922 unzClose(unz); |
914 systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), | 923 systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), |
915 "data"); | 924 "data"); |
916 return NULL; | 925 return NULL; |
917 } | 926 } |
918 size = fileSize; | 927 size = fileSize; |
919 } | 928 } |
920 int read = fileSize <= size ? fileSize : size; | 929 int read = fileSize <= size ? fileSize : size; |
921 r = unzReadCurrentFile(unz, | 930 r = unzReadCurrentFile(unz, |
922 image, | 931 image, |
923 read); | 932 read); |
924 | 933 |
925 unzCloseCurrentFile(unz); | 934 unzCloseCurrentFile(unz); |
926 unzClose(unz); | 935 unzClose(unz); |
927 | 936 |
928 if (r != (int)read) | 937 if (r != (int)read) |
929 { | 938 { |
930 systemMessage(MSG_ERROR_READING_IMAGE, | 939 systemMessage(MSG_ERROR_READING_IMAGE, |
931 N_("Error reading image %s"), buffer); | 940 N_("Error reading image %s"), buffer); |
932 if (data == NULL) | 941 if (data == NULL) |
933 free(image); | 942 free(image); |
934 return NULL; | 943 return NULL; |
935 } | 944 } |
936 | 945 |
937 size = fileSize; | 946 size = fileSize; |
938 | 947 |
939 return image; | 948 return image; |
940 } | 949 } |
941 | 950 |
942 static u8 *utilLoadGzipFile(const char *file, | 951 static u8 *utilLoadGzipFile(const char *file, |
943 bool (*accept)(const char *), | 952 bool (*accept)(const char *), |
944 u8 *data, | 953 u8 *data, |
945 int &size) | 954 int &size) |
946 { | 955 { |
947 FILE *f = fopen(file, "rb"); | 956 FILE *f = fopen(file, "rb"); |
948 | 957 |
949 if (f == NULL) | 958 if (f == NULL) |
950 { | 959 { |
951 systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file); | 960 systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file); |
952 return NULL; | 961 return NULL; |
953 } | 962 } |
954 | 963 |
955 fseek(f, -4, SEEK_END); | 964 fseek(f, -4, SEEK_END); |
956 int fileSize = fgetc(f) | (fgetc(f) << 8) | (fgetc(f) << 16) | (fgetc(f) << 24); | 965 int fileSize = fgetc(f) | (fgetc(f) << 8) | (fgetc(f) << 16) | (fgetc(f) << 24); |
957 fclose(f); | 966 fclose(f); |
958 if (size == 0) | 967 if (size == 0) |
959 size = fileSize; | 968 size = fileSize; |
960 | 969 |
961 gzFile gz = gzopen(file, "rb"); | 970 gzFile gz = gzopen(file, "rb"); |
962 | 971 |
963 if (gz == NULL) | 972 if (gz == NULL) |
964 { | 973 { |
965 // should not happen, but who knows? | 974 // should not happen, but who knows? |
966 systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file); | 975 systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file); |
967 return NULL; | 976 return NULL; |
968 } | 977 } |
969 | 978 |
970 u8 *image = data; | 979 u8 *image = data; |
971 | 980 |
972 if (image == NULL) | 981 if (image == NULL) |
973 { | 982 { |
974 image = (u8 *)malloc(utilGetSize(size)); | 983 image = (u8 *)malloc(utilGetSize(size)); |
975 if (image == NULL) | 984 if (image == NULL) |
976 { | 985 { |
977 systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), | 986 systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), |
978 "data"); | 987 "data"); |
979 fclose(f); | 988 fclose(f); |
980 return NULL; | 989 return NULL; |
981 } | 990 } |
982 size = fileSize; | 991 size = fileSize; |
983 } | 992 } |
984 int read = fileSize <= size ? fileSize : size; | 993 int read = fileSize <= size ? fileSize : size; |
985 int r = gzread(gz, image, read); | 994 int r = gzread(gz, image, read); |
986 gzclose(gz); | 995 gzclose(gz); |
987 | 996 |
988 if (r != (int)read) | 997 if (r != (int)read) |
989 { | 998 { |
990 systemMessage(MSG_ERROR_READING_IMAGE, | 999 systemMessage(MSG_ERROR_READING_IMAGE, |
991 N_("Error reading image %s"), file); | 1000 N_("Error reading image %s"), file); |
992 if (data == NULL) | 1001 if (data == NULL) |
993 free(image); | 1002 free(image); |
994 return NULL; | 1003 return NULL; |
995 } | 1004 } |
996 | 1005 |
997 size = fileSize; | 1006 size = fileSize; |
998 | 1007 |
999 return image; | 1008 return image; |
1000 } | 1009 } |
1001 | 1010 |
1002 #if 0 | 1011 #if 0 |
1003 static u8 *utilLoadRarFile(const char *file, | 1012 static u8 *utilLoadRarFile(const char *file, |
1004 bool (*accept)(const char *), | 1013 bool (*accept)(const char *), |
1005 u8 *data, | 1014 u8 *data, |
1006 int &size) | 1015 int &size) |
1007 { | 1016 { |
1008 char buffer[2048]; | 1017 char buffer[2048]; |
1009 | 1018 |
1010 ArchiveList_struct *rarList = NULL; | 1019 ArchiveList_struct *rarList = NULL; |
1011 if (urarlib_list((void *)file, (ArchiveList_struct *)&rarList)) | 1020 if (urarlib_list((void *)file, (ArchiveList_struct *)&rarList)) |
1012 { | 1021 { |
1013 ArchiveList_struct *p = rarList; | 1022 ArchiveList_struct *p = rarList; |
1014 | 1023 |
1015 bool found = false; | 1024 bool found = false; |
1016 while (p) | 1025 while (p) |
1017 { | 1026 { |
1018 if (accept(p->item.Name)) | 1027 if (accept(p->item.Name)) |
1019 { | 1028 { |
1020 strcpy(buffer, p->item.Name); | 1029 strcpy(buffer, p->item.Name); |
1021 found = true; | 1030 found = true; |
1022 break; | 1031 break; |
1023 } | 1032 } |
1024 p = p->next; | 1033 p = p->next; |
1025 } | 1034 } |
1026 if (found) | 1035 if (found) |
1027 { | 1036 { |
1028 void *memory = NULL; | 1037 void *memory = NULL; |
1029 unsigned long lsize = 0; | 1038 unsigned long lsize = 0; |
1030 size = p->item.UnpSize; | 1039 size = p->item.UnpSize; |
1031 int r = urarlib_get((void *)&memory, &lsize, buffer, (void *)file, ""); | 1040 int r = urarlib_get((void *)&memory, &lsize, buffer, (void *)file, ""); |
1032 if (!r) | 1041 if (!r) |
1033 { | 1042 { |
1034 systemMessage(MSG_ERROR_READING_IMAGE, | 1043 systemMessage(MSG_ERROR_READING_IMAGE, |
1035 N_("Error reading image %s"), buffer); | 1044 N_("Error reading image %s"), buffer); |
1036 urarlib_freelist(rarList); | 1045 urarlib_freelist(rarList); |
1037 return NULL; | 1046 return NULL; |
1038 } | 1047 } |
1039 u8 *image = (u8 *)memory; | 1048 u8 *image = (u8 *)memory; |
1040 if (data != NULL) | 1049 if (data != NULL) |
1041 { | 1050 { |
1042 memcpy(image, data, size); | 1051 memcpy(image, data, size); |
1043 } | 1052 } |
1044 urarlib_freelist(rarList); | 1053 urarlib_freelist(rarList); |
1045 return image; | 1054 return image; |
1046 } | 1055 } |
1047 systemMessage(MSG_NO_IMAGE_ON_ZIP, | 1056 systemMessage(MSG_NO_IMAGE_ON_ZIP, |
1048 N_("No image found on RAR file %s"), file); | 1057 N_("No image found on RAR file %s"), file); |
1049 urarlib_freelist(rarList); | 1058 urarlib_freelist(rarList); |
1050 return NULL; | 1059 return NULL; |
1051 } | 1060 } |
1052 // nothing found | 1061 // nothing found |
1053 return NULL; | 1062 return NULL; |
1054 } | 1063 } |
1055 | 1064 |
1056 #endif | 1065 #endif |
1057 | 1066 |
1058 // the caller is responsible for caling free(return value) to release the memory | 1067 // the caller is responsible for caling free(return value) to release the memory |
1059 u8 *utilLoad(const char *file, | 1068 u8 *utilLoad(const char *file, |
1060 bool (*accept)(const char *), | 1069 bool (*accept)(const char *), |
1061 u8 *data, | 1070 u8 *data, |
1062 int &size) | 1071 int &size) |
1063 { | 1072 { |
1064 if (utilIsZipFile(file)) | 1073 if (utilIsZipFile(file)) |
1065 { | 1074 { |
1066 return utilLoadFromZip(file, accept, data, size); | 1075 return utilLoadFromZip(file, accept, data, size); |
1067 } | 1076 } |
1068 if (utilIsGzipFile(file)) | 1077 if (utilIsGzipFile(file)) |
1069 { | 1078 { |
1070 return utilLoadGzipFile(file, accept, data, size); | 1079 return utilLoadGzipFile(file, accept, data, size); |
1071 } | 1080 } |
1072 #if 0 | 1081 #if 0 |
1073 if (utilIsRarFile(file)) | 1082 if (utilIsRarFile(file)) |
1074 { | 1083 { |
1075 return utilLoadRarFile(file, accept, data, size); | 1084 return utilLoadRarFile(file, accept, data, size); |
1076 } | 1085 } |
1077 #endif | 1086 #endif |
1078 | 1087 |
1079 u8 *image = data; | 1088 u8 *image = data; |
1080 | 1089 |
1081 FILE *f = fopen(file, "rb"); | 1090 FILE *f = fopen(file, "rb"); |
1082 | 1091 |
1083 if (!f) | 1092 if (!f) |
1084 { | 1093 { |
1085 systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file); | 1094 systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"), file); |
1086 return NULL; | 1095 return NULL; |
1087 } | 1096 } |
1088 | 1097 |
1089 fseek(f, 0, SEEK_END); | 1098 fseek(f, 0, SEEK_END); |
1090 int fileSize = ftell(f); | 1099 int fileSize = ftell(f); |
1091 fseek(f, 0, SEEK_SET); | 1100 fseek(f, 0, SEEK_SET); |
1092 if (size == 0) | 1101 if (size == 0) |
1093 size = fileSize; | 1102 size = fileSize; |
1094 | 1103 |
1095 if (image == NULL) | 1104 if (image == NULL) |
1096 { | 1105 { |
1097 image = (u8 *)malloc(utilGetSize(size)); | 1106 image = (u8 *)malloc(utilGetSize(size)); |
1098 if (image == NULL) | 1107 if (image == NULL) |
1108 { | |
1109 systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), | |
1110 "data"); | |
1111 fclose(f); | |
1112 return NULL; | |
1113 } | |
1114 size = fileSize; | |
1115 } | |
1116 int read = fileSize <= size ? fileSize : size; | |
1117 int r = fread(image, 1, read, f); | |
1118 fclose(f); | |
1119 | |
1120 if (r != (int)read) | |
1121 { | |
1122 systemMessage(MSG_ERROR_READING_IMAGE, | |
1123 N_("Error reading image %s"), file); | |
1124 if (data == NULL) | |
1125 free(image); | |
1126 return NULL; | |
1127 } | |
1128 | |
1129 size = fileSize; | |
1130 | |
1131 return image; | |
1132 } | |
1133 | |
1134 void utilWriteInt(gzFile gzFile, int32 i) | |
1135 { | |
1136 utilGzWrite(gzFile, &i, sizeof(int32)); | |
1137 } | |
1138 | |
1139 int32 utilReadInt(gzFile gzFile) | |
1140 { | |
1141 int32 i = 0; | |
1142 utilGzRead(gzFile, &i, sizeof(int32)); | |
1143 return i; | |
1144 } | |
1145 | |
1146 void utilReadData(gzFile gzFile, variable_desc *data) | |
1147 { | |
1148 while (data->address) | |
1149 { | |
1150 utilGzRead(gzFile, data->address, data->size); | |
1151 data++; | |
1152 } | |
1153 } | |
1154 | |
1155 void utilWriteData(gzFile gzFile, variable_desc *data) | |
1156 { | |
1157 while (data->address) | |
1158 { | |
1159 utilGzWrite(gzFile, data->address, data->size); | |
1160 data++; | |
1161 } | |
1162 } | |
1163 | |
1164 gzFile utilGzOpen(const char *file, const char *mode) | |
1165 { | |
1166 utilGzWriteFunc = gzWrite; | |
1167 utilGzReadFunc = gzread; | |
1168 utilGzCloseFunc = gzclose; | |
1169 utilGzSeekFunc = gzseek; | |
1170 utilGzTellFunc = gztell; | |
1171 | |
1172 return gzopen(file, mode); | |
1173 } | |
1174 | |
1175 gzFile utilGzReopen(int id, const char *mode) | |
1176 { | |
1177 utilGzWriteFunc = gzWrite; | |
1178 utilGzReadFunc = gzread; | |
1179 utilGzCloseFunc = gzclose; | |
1180 utilGzSeekFunc = gzseek; | |
1181 utilGzTellFunc = gztell; | |
1182 | |
1183 return gzdopen(id, mode); | |
1184 } | |
1185 | |
1186 gzFile utilMemGzOpen(char *memory, int available, char *mode) | |
1187 { | |
1188 utilGzWriteFunc = memgzwrite; | |
1189 utilGzReadFunc = memgzread; | |
1190 utilGzCloseFunc = memgzclose; | |
1191 utilGzSeekFunc = NULL; // FIXME: not implemented... | |
1192 utilGzTellFunc = memtell; | |
1193 | |
1194 return memgzopen(memory, available, mode); | |
1195 } | |
1196 | |
1197 int utilGzWrite(gzFile file, voidp buffer, unsigned int len) | |
1198 { | |
1199 return utilGzWriteFunc(file, buffer, len); | |
1200 } | |
1201 | |
1202 int utilGzRead(gzFile file, voidp buffer, unsigned int len) | |
1203 { | |
1204 return utilGzReadFunc(file, buffer, len); | |
1205 } | |
1206 | |
1207 int utilGzClose(gzFile file) | |
1208 { | |
1209 return utilGzCloseFunc(file); | |
1210 } | |
1211 | |
1212 z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence) | |
1213 { | |
1214 return utilGzSeekFunc(file, offset, whence); | |
1215 } | |
1216 | |
1217 z_off_t utilGzTell(gzFile file) | |
1218 { | |
1219 return utilGzTellFunc(file); | |
1220 } | |
1221 | |
1222 void utilGBAFindSave(const u8 *data, const int size) | |
1223 { | |
1224 u32 *p = (u32 *)data; | |
1225 u32 *end = (u32 *)(data + size); | |
1226 int saveType = 0; | |
1227 int flashSize = 0x10000; | |
1228 bool rtcFound = false; | |
1229 | |
1230 while (p < end) | |
1231 { | |
1232 u32 d = READ32LE(p); | |
1233 | |
1234 if (d == 0x52504545) | |
1235 { | |
1236 if (memcmp(p, "EEPROM_", 7) == 0) | |
1237 { | |
1238 if (saveType == 0) | |
1239 saveType = 1; | |
1240 } | |
1241 } | |
1242 else if (d == 0x4D415253) | |
1243 { | |
1244 if (memcmp(p, "SRAM_", 5) == 0) | |
1245 { | |
1246 if (saveType == 0) | |
1247 saveType = 2; | |
1248 } | |
1249 } | |
1250 else if (d == 0x53414C46) | |
1251 { | |
1252 if (memcmp(p, "FLASH1M_", 8) == 0) | |
1253 { | |
1254 if (saveType == 0) | |
1099 { | 1255 { |
1100 systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"), | 1256 saveType = 3; |
1101 "data"); | 1257 flashSize = 0x20000; |
1102 fclose(f); | |
1103 return NULL; | |
1104 } | 1258 } |
1105 size = fileSize; | 1259 } |
1106 } | 1260 else if (memcmp(p, "FLASH", 5) == 0) |
1107 int read = fileSize <= size ? fileSize : size; | 1261 { |
1108 int r = fread(image, 1, read, f); | 1262 if (saveType == 0) |
1109 fclose(f); | |
1110 | |
1111 if (r != (int)read) | |
1112 { | |
1113 systemMessage(MSG_ERROR_READING_IMAGE, | |
1114 N_("Error reading image %s"), file); | |
1115 if (data == NULL) | |
1116 free(image); | |
1117 return NULL; | |
1118 } | |
1119 | |
1120 size = fileSize; | |
1121 | |
1122 return image; | |
1123 } | |
1124 | |
1125 void utilWriteInt(gzFile gzFile, int32 i) | |
1126 { | |
1127 utilGzWrite(gzFile, &i, sizeof(int32)); | |
1128 } | |
1129 | |
1130 int32 utilReadInt(gzFile gzFile) | |
1131 { | |
1132 int32 i = 0; | |
1133 utilGzRead(gzFile, &i, sizeof(int32)); | |
1134 return i; | |
1135 } | |
1136 | |
1137 void utilReadData(gzFile gzFile, variable_desc *data) | |
1138 { | |
1139 while (data->address) | |
1140 { | |
1141 utilGzRead(gzFile, data->address, data->size); | |
1142 data++; | |
1143 } | |
1144 } | |
1145 | |
1146 void utilWriteData(gzFile gzFile, variable_desc *data) | |
1147 { | |
1148 while (data->address) | |
1149 { | |
1150 utilGzWrite(gzFile, data->address, data->size); | |
1151 data++; | |
1152 } | |
1153 } | |
1154 | |
1155 gzFile utilGzOpen(const char *file, const char *mode) | |
1156 { | |
1157 utilGzWriteFunc = gzWrite; | |
1158 utilGzReadFunc = gzread; | |
1159 utilGzCloseFunc = gzclose; | |
1160 utilGzSeekFunc = gzseek; | |
1161 utilGzTellFunc = gztell; | |
1162 | |
1163 return gzopen(file, mode); | |
1164 } | |
1165 | |
1166 gzFile utilGzReopen(int id, const char *mode) | |
1167 { | |
1168 utilGzWriteFunc = gzWrite; | |
1169 utilGzReadFunc = gzread; | |
1170 utilGzCloseFunc = gzclose; | |
1171 utilGzSeekFunc = gzseek; | |
1172 utilGzTellFunc = gztell; | |
1173 | |
1174 return gzdopen(id, mode); | |
1175 } | |
1176 | |
1177 gzFile utilMemGzOpen(char *memory, int available, char *mode) | |
1178 { | |
1179 utilGzWriteFunc = memgzwrite; | |
1180 utilGzReadFunc = memgzread; | |
1181 utilGzCloseFunc = memgzclose; | |
1182 utilGzSeekFunc = NULL; // FIXME: not implemented... | |
1183 utilGzTellFunc = memtell; | |
1184 | |
1185 return memgzopen(memory, available, mode); | |
1186 } | |
1187 | |
1188 int utilGzWrite(gzFile file, voidp buffer, unsigned int len) | |
1189 { | |
1190 return utilGzWriteFunc(file, buffer, len); | |
1191 } | |
1192 | |
1193 int utilGzRead(gzFile file, voidp buffer, unsigned int len) | |
1194 { | |
1195 return utilGzReadFunc(file, buffer, len); | |
1196 } | |
1197 | |
1198 int utilGzClose(gzFile file) | |
1199 { | |
1200 return utilGzCloseFunc(file); | |
1201 } | |
1202 | |
1203 z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence) | |
1204 { | |
1205 return utilGzSeekFunc(file, offset, whence); | |
1206 } | |
1207 | |
1208 z_off_t utilGzTell(gzFile file) | |
1209 { | |
1210 return utilGzTellFunc(file); | |
1211 } | |
1212 | |
1213 void utilGBAFindSave(const u8 *data, const int size) | |
1214 { | |
1215 u32 *p = (u32 *)data; | |
1216 u32 *end = (u32 *)(data + size); | |
1217 int saveType = 0; | |
1218 int flashSize = 0x10000; | |
1219 bool rtcFound = false; | |
1220 | |
1221 while (p < end) | |
1222 { | |
1223 u32 d = READ32LE(p); | |
1224 | |
1225 if (d == 0x52504545) | |
1226 { | 1263 { |
1227 if (memcmp(p, "EEPROM_", 7) == 0) | 1264 saveType = 3; |
1228 { | 1265 flashSize = 0x10000; |
1229 if (saveType == 0) | |
1230 saveType = 1; | |
1231 } | |
1232 } | 1266 } |
1233 else if (d == 0x4D415253) | 1267 } |
1234 { | 1268 } |
1235 if (memcmp(p, "SRAM_", 5) == 0) | 1269 else if (d == 0x52494953) |
1236 { | 1270 { |
1237 if (saveType == 0) | 1271 if (memcmp(p, "SIIRTC_V", 8) == 0) |
1238 saveType = 2; | 1272 rtcFound = true; |
1239 } | 1273 } |
1240 } | 1274 p++; |
1241 else if (d == 0x53414C46) | 1275 } |
1242 { | 1276 // if no matches found, then set it to NONE |
1243 if (memcmp(p, "FLASH1M_", 8) == 0) | 1277 if (saveType == 0) |
1244 { | 1278 { |
1245 if (saveType == 0) | 1279 saveType = 5; |
1246 { | 1280 } |
1247 saveType = 3; | 1281 rtcEnable(rtcFound); |
1248 flashSize = 0x20000; | 1282 cpuSaveType = saveType; |
1249 } | 1283 flashSetSize(flashSize); |
1250 } | |
1251 else if (memcmp(p, "FLASH", 5) == 0) | |
1252 { | |
1253 if (saveType == 0) | |
1254 { | |
1255 saveType = 3; | |
1256 flashSize = 0x10000; | |
1257 } | |
1258 } | |
1259 } | |
1260 else if (d == 0x52494953) | |
1261 { | |
1262 if (memcmp(p, "SIIRTC_V", 8) == 0) | |
1263 rtcFound = true; | |
1264 } | |
1265 p++; | |
1266 } | |
1267 // if no matches found, then set it to NONE | |
1268 if (saveType == 0) | |
1269 { | |
1270 saveType = 5; | |
1271 } | |
1272 rtcEnable(rtcFound); | |
1273 cpuSaveType = saveType; | |
1274 flashSetSize(flashSize); | |
1275 } | 1284 } |
1276 | 1285 |
1277 void utilUpdateSystemColorMaps() | 1286 void utilUpdateSystemColorMaps() |
1278 { | 1287 { |
1279 switch (systemColorDepth) | 1288 switch (systemColorDepth) |
1280 { | 1289 { |
1281 case 16: | 1290 case 16: |
1282 { | 1291 { |
1283 for (int i = 0; i < 0x10000; i++) | 1292 for (int i = 0; i < 0x10000; i++) |
1284 { | 1293 { |
1285 systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | | 1294 systemColorMap16[i] = ((i & 0x1f) << systemRedShift) | |
1286 (((i & 0x3e0) >> 5) << systemGreenShift) | | 1295 (((i & 0x3e0) >> 5) << systemGreenShift) | |
1287 (((i & 0x7c00) >> 10) << systemBlueShift); | 1296 (((i & 0x7c00) >> 10) << systemBlueShift); |
1288 } | 1297 } |
1289 break; | 1298 break; |
1290 } | 1299 } |
1291 case 24: | 1300 case 24: |
1292 case 32: | 1301 case 32: |
1293 { | 1302 { |
1294 for (int i = 0; i < 0x10000; i++) | 1303 for (int i = 0; i < 0x10000; i++) |
1295 { | 1304 { |
1296 systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | | 1305 systemColorMap32[i] = ((i & 0x1f) << systemRedShift) | |
1297 (((i & 0x3e0) >> 5) << systemGreenShift) | | 1306 (((i & 0x3e0) >> 5) << systemGreenShift) | |
1298 (((i & 0x7c00) >> 10) << systemBlueShift); | 1307 (((i & 0x7c00) >> 10) << systemBlueShift); |
1299 } | 1308 } |
1300 break; | 1309 break; |
1301 } | 1310 } |
1302 } | 1311 } |
1303 } | 1312 } |
1304 | 1313 |
1305 //// BIOS stuff | 1314 //// BIOS stuff |
1306 // systemType uses the same enum values as gbEmulatorType does | 1315 // systemType uses the same enum values as gbEmulatorType does |
1307 | 1316 |
1308 bool utilLoadBIOS(u8 *bios, const char *biosFileName, int systemType) | 1317 bool utilLoadBIOS(u8 *bios, const char *biosFileName, int systemType) |
1309 { | 1318 { |
1310 if (bios == NULL || strlen(biosFileName) == 0) | 1319 if (bios == NULL || strlen(biosFileName) == 0) |
1311 return false; | 1320 return false; |
1312 | 1321 |
1313 if (systemType == 4) | 1322 if (systemType == 4) |
1314 { | 1323 { |
1315 int biosSize = 0x4000; | 1324 int biosSize = 0x4000; |
1316 if (utilLoad(biosFileName, utilIsGBABios, bios, biosSize)) | 1325 if (utilLoad(biosFileName, utilIsGBABios, bios, biosSize)) |
1317 { | 1326 { |
1318 if (biosSize == 0x4000) | 1327 if (biosSize == 0x4000) |
1319 return true; | 1328 return true; |
1320 } | 1329 } |
1321 } | 1330 } |
1322 else | 1331 else |
1323 { | 1332 { |
1324 int biosSize = 0x100; | 1333 int biosSize = 0x100; |
1325 if (utilLoad(biosFileName, utilIsGBBios, bios, biosSize)) | 1334 if (utilLoad(biosFileName, utilIsGBBios, bios, biosSize)) |
1326 { | 1335 { |
1327 if (biosSize == 0x100) | 1336 if (biosSize == 0x100) |
1328 return true; | 1337 return true; |
1329 } | 1338 } |
1330 } | 1339 } |
1331 | 1340 |
1332 return false; | 1341 return false; |
1333 } | 1342 } |
1334 | 1343 |
1335 bool utilCheckBIOS(const char *biosFileName, int systemType) | 1344 bool utilCheckBIOS(const char *biosFileName, int systemType) |
1336 { | 1345 { |
1337 if (strlen(biosFileName) == 0) | 1346 if (strlen(biosFileName) == 0) |
1338 return false; | 1347 return false; |
1339 | 1348 |
1340 u8 * tempBIOS = (u8 *)malloc(systemType == 4 ? 0x4000 : 0x100); | 1349 u8 * tempBIOS = (u8 *)malloc(systemType == 4 ? 0x4000 : 0x100); |
1341 bool result = utilLoadBIOS(tempBIOS, biosFileName, systemType); | 1350 bool result = utilLoadBIOS(tempBIOS, biosFileName, systemType); |
1342 free(tempBIOS); | 1351 free(tempBIOS); |
1343 | 1352 |
1344 return result; | 1353 return result; |
1345 } | 1354 } |
1346 | 1355 |
1347 #if 0 | 1356 #if 0 |
1348 // returns the checksum of the BIOS that will be loaded after the next restart | 1357 // returns the checksum of the BIOS that will be loaded after the next restart |
1349 u16 utilCalcBIOSChecksum(const u8 *bios, int systemType) | 1358 u16 utilCalcBIOSChecksum(const u8 *bios, int systemType) |
1350 { | 1359 { |
1351 u32 biosChecksum = 0; | 1360 u32 biosChecksum = 0; |
1352 if (bios) | 1361 if (bios) |
1353 { | 1362 { |
1354 int biosSize = (systemType == 4 ? 0x4000 : 0x100); | 1363 int biosSize = (systemType == 4 ? 0x4000 : 0x100); |
1355 const u16 *data = reinterpret_cast<const u16 *>(bios); | 1364 const u16 *data = reinterpret_cast<const u16 *>(bios); |
1356 for (int i = biosSize; i > 0; i -= 2) | 1365 for (int i = biosSize; i > 0; i -= 2) |
1357 biosChecksum += *data++; | 1366 biosChecksum += *data++; |
1358 } | 1367 } |
1359 | 1368 |
1360 while ((biosChecksum >> 16) & 0xFFFF) | 1369 while ((biosChecksum >> 16) & 0xFFFF) |
1361 biosChecksum = (biosChecksum &0xFFFF) + ((biosChecksum >> 16) & 0xFFFF); | 1370 biosChecksum = (biosChecksum &0xFFFF) + ((biosChecksum >> 16) & 0xFFFF); |
1362 | 1371 |
1363 return biosChecksum & 0xFFFF; | 1372 return biosChecksum & 0xFFFF; |
1364 } | 1373 } |
1365 #else | 1374 #else |
1366 // returns the checksum of the BIOS that will be loaded after the next restart | 1375 // returns the checksum of the BIOS that will be loaded after the next restart |
1367 u16 utilCalcBIOSChecksum(const u8 *bios, int systemType) | 1376 u16 utilCalcBIOSChecksum(const u8 *bios, int systemType) |
1368 { | 1377 { |
1369 u32 biosChecksum = 0; | 1378 u32 biosChecksum = 0; |
1370 if (bios) | 1379 if (bios) |
1371 { | 1380 { |
1372 int biosSize = (systemType == 4 ? 0x4000 : 0x100); | 1381 int biosSize = (systemType == 4 ? 0x4000 : 0x100); |
1373 const u32 *data = reinterpret_cast<const u32 *>(bios); | 1382 const u32 *data = reinterpret_cast<const u32 *>(bios); |
1374 for (int i = biosSize; i > 0; i -= 4) | 1383 for (int i = biosSize; i > 0; i -= 4) |
1375 biosChecksum += *data++; | 1384 biosChecksum += *data++; |
1376 } | 1385 } |
1377 | 1386 |
1378 return biosChecksum & 0xFFFF; | 1387 return biosChecksum & 0xFFFF; |
1379 } | 1388 } |
1380 #endif | 1389 #endif |
1381 | 1390 |
1382 // returns the checksum of the BIOS file | 1391 // returns the checksum of the BIOS file |
1383 u16 utilCalcBIOSFileChecksum(const char *biosFileName, int systemType) | 1392 u16 utilCalcBIOSFileChecksum(const char *biosFileName, int systemType) |
1384 { | 1393 { |
1385 if (strlen(biosFileName) == 0) | 1394 if (strlen(biosFileName) == 0) |
1386 return 0; | 1395 return 0; |
1387 | 1396 |
1388 u16 biosChecksum = 0; | 1397 u16 biosChecksum = 0; |
1389 const int biosSize = (systemType == 4 ? 0x4000 : 0x100); | 1398 const int biosSize = (systemType == 4 ? 0x4000 : 0x100); |
1390 u8 * tempBIOS = (u8 *)malloc(biosSize); | 1399 u8 * tempBIOS = (u8 *)malloc(biosSize); |
1391 bool hasBIOS = utilLoadBIOS(tempBIOS, biosFileName, systemType); | 1400 bool hasBIOS = utilLoadBIOS(tempBIOS, biosFileName, systemType); |
1392 if (hasBIOS) | 1401 if (hasBIOS) |
1393 { | 1402 { |
1394 biosChecksum = utilCalcBIOSChecksum(tempBIOS, systemType); | 1403 biosChecksum = utilCalcBIOSChecksum(tempBIOS, systemType); |
1395 } | 1404 } |
1396 free(tempBIOS); | 1405 free(tempBIOS); |
1397 | 1406 |
1398 return biosChecksum; | 1407 return biosChecksum; |
1399 } | 1408 } |
1400 | 1409 |