1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
4 
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 // RomInfo.cpp : implementation file
20 //
21 
22 #include "stdafx.h"
23 #include "vba.h"
24 #include "RomInfo.h"
25 #include "WinResUtil.h"
26 
27 #ifdef _DEBUG
28 #define new DEBUG_NEW
29 #undef THIS_FILE
30 static char THIS_FILE[] = __FILE__;
31 #endif
32 
33 extern int gbRomSize;
34 
35 struct WinGBACompanyName {
36   LPCTSTR code;
37   LPCTSTR name;
38 };
39 
40 static WinGBACompanyName winGBARomInfoCompanies[] = {
41   { "01", "Nintendo" },
42   { "02", "Rocket Games" },
43   { "08", "Capcom" },
44   { "09", "Hot B Co." },
45   { "0A", "Jaleco" },
46   { "0B", "Coconuts Japan" },
47   { "0C", "Coconuts Japan/G.X.Media" },
48   { "0H", "Starfish" },
49   { "0L", "Warashi Inc." },
50   { "0N", "Nowpro" },
51   { "0P", "Game Village" },
52   { "13", "Electronic Arts Japan" },
53   { "18", "Hudson Soft Japan" },
54   { "19", "S.C.P." },
55   { "1A", "Yonoman" },
56   { "1G", "SMDE" },
57   { "1P", "Creatures Inc." },
58   { "1Q", "TDK Deep Impresion" },
59   { "20", "Destination Software" },
60   { "22", "VR 1 Japan" },
61   { "25", "San-X" },
62   { "28", "Kemco Japan" },
63   { "29", "Seta" },
64   { "2H", "Ubisoft Japan" },
65   { "2K", "NEC InterChannel" },
66   { "2L", "Tam" },
67   { "2M", "Jordan" },
68   { "2N", "Smilesoft" },
69   { "2Q", "Mediakite" },
70   { "36", "Codemasters" },
71   { "37", "GAGA Communications" },
72   { "38", "Laguna" },
73   { "39", "Telstar Fun and Games" },
74   { "41", "Ubi Soft Entertainment" },
75   { "42", "Sunsoft" },
76   { "47", "Spectrum Holobyte" },
77   { "49", "IREM" },
78   { "4D", "Malibu Games" },
79   { "4F", "Eidos/U.S. Gold" },
80   { "4J", "Fox Interactive" },
81   { "4K", "Time Warner Interactive" },
82   { "4Q", "Disney" },
83   { "4S", "Black Pearl" },
84   { "4X", "GT Interactive" },
85   { "4Y", "RARE" },
86   { "4Z", "Crave Entertainment" },
87   { "50", "Absolute Entertainment" },
88   { "51", "Acclaim" },
89   { "52", "Activision" },
90   { "53", "American Sammy Corp." },
91   { "54", "Take 2 Interactive" },
92   { "55", "Hi Tech" },
93   { "56", "LJN LTD." },
94   { "58", "Mattel" },
95   { "5A", "Mindscape/Red Orb Ent." },
96   { "5C", "Taxan" },
97   { "5D", "Midway" },
98   { "5F", "American Softworks" },
99   { "5G", "Majesco Sales Inc" },
100   { "5H", "3DO" },
101   { "5K", "Hasbro" },
102   { "5L", "NewKidCo" },
103   { "5M", "Telegames" },
104   { "5N", "Metro3D" },
105   { "5P", "Vatical Entertainment" },
106   { "5Q", "LEGO Media" },
107   { "5S", "Xicat Interactive" },
108   { "5T", "Cryo Interactive" },
109   { "5W", "Red Storm Ent./BKN Ent." },
110   { "5X", "Microids" },
111   { "5Z", "Conspiracy Entertainment Corp." },
112   { "60", "Titus Interactive Studios" },
113   { "61", "Virgin Interactive" },
114   { "62", "Maxis" },
115   { "64", "LucasArts Entertainment" },
116   { "67", "Ocean" },
117   { "69", "Electronic Arts" },
118   { "6E", "Elite Systems Ltd." },
119   { "6F", "Electro Brain" },
120   { "6G", "The Learning Company" },
121   { "6H", "BBC" },
122   { "6J", "Software 2000" },
123   { "6L", "BAM! Entertainment" },
124   { "6M", "Studio 3" },
125   { "6Q", "Classified Games" },
126   { "6S", "TDK Mediactive" },
127   { "6U", "DreamCatcher" },
128   { "6V", "JoWood Productions" },
129   { "6W", "SEGA" },
130   { "6X", "Wannado Edition" },
131   { "6Y", "LSP" },
132   { "6Z", "ITE Media" },
133   { "70", "Infogrames" },
134   { "71", "Interplay" },
135   { "72", "JVC Musical Industries Inc" },
136   { "73", "Parker Brothers" },
137   { "75", "SCI" },
138   { "78", "THQ" },
139   { "79", "Accolade" },
140   { "7A", "Triffix Ent. Inc." },
141   { "7C", "Microprose Software" },
142   { "7D", "Universal Interactive Studios" },
143   { "7F", "Kemco" },
144   { "7G", "Rage Software" },
145   { "7H", "Encore" },
146   { "7J", "Zoo" },
147   { "7K", "BVM" },
148   { "7L", "Simon & Schuster Interactive" },
149   { "7M", "Asmik Ace Entertainment Inc./AIA" },
150   { "7N", "Empire Interactive" },
151   { "7Q", "Jester Interactive" },
152   { "7T", "Scholastic" },
153   { "7U", "Ignition Entertainment" },
154   { "7W", "Stadlbauer" },
155   { "80", "Misawa" },
156   { "83", "LOZC" },
157   { "8B", "Bulletproof Software" },
158   { "8C", "Vic Tokai Inc." },
159   { "8J", "General Entertainment" },
160   { "8N", "Success" },
161   { "8P", "SEGA Japan" },
162   { "91", "Chun Soft" },
163   { "92", "Video System" },
164   { "93", "BEC" },
165   { "96", "Yonezawa/S'pal" },
166   { "97", "Kaneko" },
167   { "99", "Victor Interactive Software" },
168   { "9A", "Nichibutsu/Nihon Bussan" },
169   { "9B", "Tecmo" },
170   { "9C", "Imagineer" },
171   { "9F", "Nova" },
172   { "9H", "Bottom Up" },
173   { "9L", "Hasbro Japan" },
174   { "9N", "Marvelous Entertainment" },
175   { "9P", "Keynet Inc." },
176   { "9Q", "Hands-On Entertainment" },
177   { "A0", "Telenet" },
178   { "A1", "Hori" },
179   { "A4", "Konami" },
180   { "A6", "Kawada" },
181   { "A7", "Takara" },
182   { "A9", "Technos Japan Corp." },
183   { "AA", "JVC" },
184   { "AC", "Toei Animation" },
185   { "AD", "Toho" },
186   { "AF", "Namco" },
187   { "AG", "Media Rings Corporation" },
188   { "AH", "J-Wing" },
189   { "AK", "KID" },
190   { "AL", "MediaFactory" },
191   { "AP", "Infogrames Hudson" },
192   { "AQ", "Kiratto. Ludic Inc" },
193   { "B0", "Acclaim Japan" },
194   { "B1", "ASCII" },
195   { "B2", "Bandai" },
196   { "B4", "Enix" },
197   { "B6", "HAL Laboratory" },
198   { "B7", "SNK" },
199   { "B9", "Pony Canyon Hanbai" },
200   { "BA", "Culture Brain" },
201   { "BB", "Sunsoft" },
202   { "BD", "Sony Imagesoft" },
203   { "BF", "Sammy" },
204   { "BG", "Magical" },
205   { "BJ", "Compile" },
206   { "BL", "MTO Inc." },
207   { "BN", "Sunrise Interactive" },
208   { "BP", "Global A Entertainment" },
209   { "BQ", "Fuuki" },
210   { "C0", "Taito" },
211   { "C2", "Kemco" },
212   { "C3", "Square Soft" },
213   { "C5", "Data East" },
214   { "C6", "Tonkin House" },
215   { "C8", "Koei" },
216   { "CA", "Konami/Palcom/Ultra" },
217   { "CB", "Vapinc/NTVIC" },
218   { "CC", "Use Co.,Ltd." },
219   { "CD", "Meldac" },
220   { "CE", "FCI/Pony Canyon" },
221   { "CF", "Angel" },
222   { "CM", "Konami Computer Entertainment Osaka" },
223   { "CP", "Enterbrain" },
224   { "D1", "Sofel" },
225   { "D2", "Quest" },
226   { "D3", "Sigma Enterprises" },
227   { "D4", "Ask Kodansa" },
228   { "D6", "Naxat" },
229   { "D7", "Copya System" },
230   { "D9", "Banpresto" },
231   { "DA", "TOMY" },
232   { "DB", "LJN Japan" },
233   { "DD", "NCS" },
234   { "DF", "Altron Corporation" },
235   { "DH", "Gaps Inc." },
236   { "DN", "ELF" },
237   { "E2", "Yutaka" },
238   { "E3", "Varie" },
239   { "E5", "Epoch" },
240   { "E7", "Athena" },
241   { "E8", "Asmik Ace Entertainment Inc." },
242   { "E9", "Natsume" },
243   { "EA", "King Records" },
244   { "EB", "Atlus" },
245   { "EC", "Epic/Sony Records" },
246   { "EE", "IGS" },
247   { "EL", "Spike" },
248   { "EM", "Konami Computer Entertainment Tokyo" },
249   { "EN", "Alphadream Corporation" },
250   { "F0", "A Wave" },
251   { "G1", "PCCW" },
252   { "G4", "KiKi Co Ltd" },
253   { "G5", "Open Sesame Inc." },
254   { "G6", "Sims" },
255   { "G7", "Broccoli" },
256   { "G8", "Avex" },
257   { "G9", "D3 Publisher" },
258   { "GB", "Konami Computer Entertainment Japan" },
259   { "GD", "Square-Enix" },
260   { "HY", "Sachen" },
261   { NULL, NULL }
262 };
263 
winGBARomInfoFindMakerCode(LPCTSTR code)264 static LPCTSTR winGBARomInfoFindMakerCode(LPCTSTR code)
265 {
266   int i = 0;
267   while(winGBARomInfoCompanies[i].code) {
268     if(!strcmp(winGBARomInfoCompanies[i].code, code))
269       return winGBARomInfoCompanies[i].name;
270     i++;
271   }
272   return (LPCTSTR)winResLoadString(IDS_UNKNOWN);
273 }
274 
275 
276 /////////////////////////////////////////////////////////////////////////////
277 // RomInfoGB dialog
278 
279 
RomInfoGB(u8 * rom,CWnd * pParent)280 RomInfoGB::RomInfoGB(u8 *rom, CWnd* pParent /*=NULL*/)
281   : CDialog(RomInfoGB::IDD, pParent)
282 {
283   //{{AFX_DATA_INIT(RomInfoGB)
284   // NOTE: the ClassWizard will add member initialization here
285   //}}AFX_DATA_INIT
286   this->rom = rom;
287 }
288 
289 
DoDataExchange(CDataExchange * pDX)290 void RomInfoGB::DoDataExchange(CDataExchange* pDX)
291 {
292   CDialog::DoDataExchange(pDX);
293   //{{AFX_DATA_MAP(RomInfoGB)
294   // NOTE: the ClassWizard will add DDX and DDV calls here
295   //}}AFX_DATA_MAP
296 }
297 
298 
BEGIN_MESSAGE_MAP(RomInfoGB,CDialog)299 BEGIN_MESSAGE_MAP(RomInfoGB, CDialog)
300   //{{AFX_MSG_MAP(RomInfoGB)
301   ON_BN_CLICKED(ID_OK, OnOk)
302   //}}AFX_MSG_MAP
303   END_MESSAGE_MAP()
304 
305   /////////////////////////////////////////////////////////////////////////////
306 // RomInfoGB message handlers
307 
308 void RomInfoGB::OnOk()
309 {
310   EndDialog(TRUE);
311 }
312 
OnInitDialog()313 BOOL RomInfoGB::OnInitDialog()
314 {
315   CDialog::OnInitDialog();
316 
317   char buffer[128];
318 
319   strncpy(buffer, (const char *)&rom[0x134], 15);
320   buffer[15] = 0;
321   GetDlgItem(IDC_ROM_TITLE)->SetWindowText(buffer);
322 
323   sprintf(buffer, "%02x", rom[0x143]);
324   GetDlgItem(IDC_ROM_COLOR)->SetWindowText(buffer);
325 
326   strncpy(buffer, (const char *)&rom[0x144],2);
327   buffer[2] = 0;
328   GetDlgItem(IDC_ROM_MAKER_CODE)->SetWindowText(buffer);
329 
330   if(rom[0x14b] != 0x33) {
331     sprintf(buffer, "%02X", rom[0x14b]);
332     GetDlgItem(IDC_ROM_MAKER_CODE)->SetWindowText(buffer);
333   }
334   GetDlgItem(IDC_ROM_MAKER_NAME2)->SetWindowText(winGBARomInfoFindMakerCode(buffer));
335 
336   sprintf(buffer, "%02x", rom[0x146]);
337   GetDlgItem(IDC_ROM_UNIT_CODE)->SetWindowText(buffer);
338 
339   CString type = winResLoadString(IDS_UNKNOWN);
340   switch(rom[0x147]) {
341   case 0x00:
342     type = "ROM";
343     break;
344   case 0x01:
345     type = "ROM+MBC1";
346     break;
347   case 0x02:
348     type = "ROM+MBC1+RAM";
349     break;
350   case 0x03:
351     type = "ROM+MBC1+RAM+BATT";
352     break;
353   case 0x05:
354     type = "ROM+MBC2";
355     break;
356   case 0x06:
357     type = "ROM+MBC2+BATT";
358     break;
359   case 0x0f:
360     type = "ROM+MBC3+TIMER+BATT";
361     break;
362   case 0x10:
363     type = "ROM+MBC3+TIMER+RAM+BATT";
364     break;
365   case 0x11:
366     type = "ROM+MBC3";
367     break;
368   case 0x12:
369     type = "ROM+MBC3+RAM";
370     break;
371   case 0x13:
372     type = "ROM+MBC3+RAM+BATT";
373     break;
374   case 0x19:
375     type = "ROM+MBC5";
376     break;
377   case 0x1a:
378     type = "ROM+MBC5+RAM";
379     break;
380   case 0x1b:
381     type = "ROM+MBC5+RAM+BATT";
382     break;
383   case 0x1c:
384     type = "ROM+MBC5+RUMBLE";
385     break;
386   case 0x1d:
387     type = "ROM+MBC5+RUMBLE+RAM";
388     break;
389   case 0x1e:
390     type = "ROM+MBC5+RUMBLE+RAM+BATT";
391     break;
392   case 0x22:
393     type = "ROM+MBC7+BATT";
394     break;
395   case 0xfe:
396     type = "ROM+HuC-3";
397     break;
398   case 0xff:
399     type = "ROM+HuC-1";
400     break;
401   }
402   sprintf(buffer, "%02x (%s)", rom[0x147], (const char *)type);
403   GetDlgItem(IDC_ROM_DEVICE_TYPE)->SetWindowText(buffer);
404 
405   type = winResLoadString(IDS_UNKNOWN);
406   switch(rom[0x148]) {
407   case 0:
408     type = "32K";
409     break;
410   case 1:
411     type = "64K";
412     break;
413   case 2:
414     type = "128K";
415     break;
416   case 3:
417     type = "256K";
418     break;
419   case 4:
420     type = "512K";
421     break;
422   case 5:
423     type = "1M";
424     break;
425   case 6:
426     type = "2M";
427     break;
428   case 7:
429     type = "4M";
430     break;
431   }
432 
433   sprintf(buffer, "%02x (%s)", rom[0x148], (const char *)type);
434   GetDlgItem(IDC_ROM_SIZE)->SetWindowText(buffer);
435 
436   type = winResLoadString(IDS_UNKNOWN);
437   switch(rom[0x149]) {
438   case 0:
439     type = winResLoadString(IDS_NONE);
440     break;
441   case 1:
442     type = "2K";
443     break;
444   case 2:
445     type = "8K";
446     break;
447   case 3:
448     type = "32K";
449     break;
450   case 4:
451     type = "128K";
452     break;
453   case 5:
454     type = "64K";
455     break;
456   }
457 
458   sprintf(buffer, "%02x (%s)", rom[0x149], (const char *)type);
459   GetDlgItem(IDC_ROM_RAM_SIZE)->SetWindowText(buffer);
460 
461   sprintf(buffer, "%02x", rom[0x14a]);
462   GetDlgItem(IDC_ROM_DEST_CODE)->SetWindowText(buffer);
463 
464   sprintf(buffer, "%02x", rom[0x14b]);
465   GetDlgItem(IDC_ROM_LIC_CODE)->SetWindowText(buffer);
466 
467   sprintf(buffer, "%02x", rom[0x14c]);
468   GetDlgItem(IDC_ROM_VERSION)->SetWindowText(buffer);
469 
470   u8 crc = 25;
471   int i;
472   for(i = 0x134; i < 0x14d; i++) {
473     crc += rom[i];
474   }
475 
476   crc = 256 - crc;
477 
478   sprintf(buffer, "%02x (%02x)", crc, rom[0x14d]);
479   GetDlgItem(IDC_ROM_CRC)->SetWindowText(buffer);
480 
481   u16 crc16 = 0;
482   for(i = 0; i < gbRomSize; i++) {
483     crc16 += rom[i];
484   }
485 
486   crc16 -= rom[0x14e];
487   crc16 -= rom[0x14f];
488   sprintf(buffer, "%04x (%04x)", crc16, (rom[0x14e]<<8)|rom[0x14f]);
489   GetDlgItem(IDC_ROM_CHECKSUM)->SetWindowText(buffer);
490 
491   CenterWindow();
492 
493   return TRUE;  // return TRUE unless you set the focus to a control
494                 // EXCEPTION: OCX Property Pages should return FALSE
495 }
496 /////////////////////////////////////////////////////////////////////////////
497 // RomInfoGBA dialog
498 
499 
RomInfoGBA(u8 * rom,CWnd * pParent)500 RomInfoGBA::RomInfoGBA(u8 *rom, CWnd* pParent /*=NULL*/)
501   : CDialog(RomInfoGBA::IDD, pParent)
502 {
503   //{{AFX_DATA_INIT(RomInfoGBA)
504   // NOTE: the ClassWizard will add member initialization here
505   //}}AFX_DATA_INIT
506   this->rom = rom;
507 }
508 
509 
DoDataExchange(CDataExchange * pDX)510 void RomInfoGBA::DoDataExchange(CDataExchange* pDX)
511 {
512   CDialog::DoDataExchange(pDX);
513   //{{AFX_DATA_MAP(RomInfoGBA)
514   // NOTE: the ClassWizard will add DDX and DDV calls here
515   //}}AFX_DATA_MAP
516 }
517 
518 
BEGIN_MESSAGE_MAP(RomInfoGBA,CDialog)519 BEGIN_MESSAGE_MAP(RomInfoGBA, CDialog)
520   //{{AFX_MSG_MAP(RomInfoGBA)
521   ON_BN_CLICKED(ID_OK, OnOk)
522   //}}AFX_MSG_MAP
523   END_MESSAGE_MAP()
524 
525   /////////////////////////////////////////////////////////////////////////////
526 // RomInfoGBA message handlers
527 
528 void RomInfoGBA::OnOk()
529 {
530   EndDialog(TRUE);
531 }
532 
OnInitDialog()533 BOOL RomInfoGBA::OnInitDialog()
534 {
535   CDialog::OnInitDialog();
536 
537   char buffer[13];
538 
539   strncpy(buffer, (const char *)&rom[0xa0], 12);
540   buffer[12] = 0;
541   GetDlgItem(IDC_ROM_TITLE)->SetWindowText(buffer);
542 
543   strncpy(buffer, (const char *)&rom[0xac], 4);
544   buffer[4] = 0;
545   GetDlgItem(IDC_ROM_GAME_CODE)->SetWindowText(buffer);
546 
547   strncpy(buffer, (const char *)&rom[0xb0],2);
548   buffer[2] = 0;
549   GetDlgItem(IDC_ROM_MAKER_CODE)->SetWindowText(buffer);
550 
551   GetDlgItem(IDC_ROM_MAKER_NAME)->SetWindowText(winGBARomInfoFindMakerCode(buffer));
552 
553   sprintf(buffer, "%02x", rom[0xb3]);
554   GetDlgItem(IDC_ROM_UNIT_CODE)->SetWindowText(buffer);
555 
556   sprintf(buffer, "%02x", rom[0xb4]);
557   GetDlgItem(IDC_ROM_DEVICE_TYPE)->SetWindowText(buffer);
558 
559   sprintf(buffer, "%02x", rom[0xbc]);
560   GetDlgItem(IDC_ROM_VERSION)->SetWindowText(buffer);
561 
562   u8 crc = 0x19;
563   for(int i = 0xa0; i < 0xbd; i++) {
564     crc += rom[i];
565   }
566 
567   crc = (-crc) & 255;
568 
569   sprintf(buffer, "%02x (%02x)", crc, rom[0xbd]);
570   GetDlgItem(IDC_ROM_CRC)->SetWindowText(buffer);
571   CenterWindow();
572 
573   return TRUE;  // return TRUE unless you set the focus to a control
574                 // EXCEPTION: OCX Property Pages should return FALSE
575 }
576