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