1 /*****************************************************************************
2 ** $Source: /cygdrive/d/Private/_SVNROOT/bluemsx/blueMSX/Src/Media/MediaDb.cpp,v $
3 **
4 ** $Revision: 1.91 $
5 **
6 ** $Date: 2009-04-30 03:53:28 $
7 **
8 ** More info: http://www.bluemsx.com
9 **
10 ** Copyright (C) 2003-2006 Daniel Vik
11 **
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License as published by
14 ** the Free Software Foundation; either version 2 of the License, or
15 ** (at your option) any later version.
16 **
17 ** This program is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ** GNU General Public License for more details.
21 **
22 ** You should have received a copy of the GNU General Public License
23 ** along with this program; if not, write to the Free Software
24 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 **
26 ******************************************************************************
27 */
28 extern "C" {
29 #include "MsxTypes.h"
30 #include "MediaDb.h"
31 #include "Crc32Calc.h"
32 #include "TokenExtract.h"
33 #include "StrcmpNoCase.h"
34 #include "ArchGlob.h"
35 #include "Board.h"
36 #include "Language.h"
37 }
38
39 #include "tinyxml.h"
40 #include "Sha1.h"
41 #include <string>
42 #include <map>
43
44 using namespace std;
45
46 typedef map<UInt32, MediaType*> CrcMap;
47 typedef map<string, MediaType*> Sha1Map;
48
49
50 struct MediaDb {
51 Sha1Map sha1Map;
52 CrcMap crcMap;
53 };
54
55 struct MediaType {
MediaTypeMediaType56 MediaType(RomType rt, const string t, const string c = "", const string y = "", const string ct = "", const string r = "", string s = "") :
57 romType(rt), title(t), company(c), year(y), country(ct), remark(r), start(s) {}
58
MediaTypeMediaType59 MediaType(const MediaType& mt) :
60 romType(mt.romType), title(mt.title), company(mt.company), year(mt.year),
61 country(mt.country), remark(mt.remark), start(mt.start) {}
62
63 string title;
64 string company;
65 string year;
66 string country;
67 string remark;
68 RomType romType;
69 string start;
70 };
71
72 static MediaDb* romdb;
73 static MediaDb* diskdb;
74 static MediaDb* casdb;
75 static RomType romdbDefaultType = ROM_UNKNOWN;
76
77
parseCountryCode(const string & code)78 static string parseCountryCode(const string& code)
79 {
80 if (code == "SE" || code == "se") return "Sweden";
81 if (code == "JP" || code == "jp") return "Japan";
82 if (code == "KR" || code == "kr") return "Korea";
83 if (code == "NL" || code == "nl") return "The Netherlands";
84 if (code == "GB" || code == "gb") return "England";
85 if (code == "FR" || code == "fr") return "France";
86 if (code == "ES" || code == "es") return "Spain";
87 if (code == "BR" || code == "br") return "Brazil";
88 if (code == "MA" || code == "ma") return "Arabic";
89
90 return code;
91 }
92
iequals(const string & a,const string & b)93 static bool iequals(const string& a, const string& b)
94 {
95 unsigned int sz = a.size();
96 if (b.size() != sz)
97 return false;
98 for (unsigned int i = 0; i < sz; ++i)
99 if (tolower(a[i]) != tolower(b[i]))
100 return false;
101 return true;
102 }
103
mediaDbStringToType(const char * romName)104 RomType mediaDbStringToType(const char* romName)
105 {
106 const std::string name = romName;
107
108 // Megaroms
109 if (iequals(name, "ASCII16")) return ROM_ASCII16;
110 if (iequals(name, "ASCII16SRAM2")) return ROM_ASCII16SRAM;
111 if (iequals(name, "ASCII8")) return ROM_ASCII8;
112 if (iequals(name, "ASCII8SRAM8")) return ROM_ASCII8SRAM;
113 if (iequals(name, "KoeiSRAM8")) return ROM_KOEI;
114 if (iequals(name, "KoeiSRAM32")) return ROM_KOEI;
115 if (iequals(name, "Konami")) return ROM_KONAMI4;
116 if (iequals(name, "KonamiSCC")) return ROM_KONAMI5;
117 if (iequals(name, "MuPack")) return ROM_MUPACK;
118 if (iequals(name, "Manbow2")) return ROM_MANBOW2;
119 if (iequals(name, "Manbow2v2")) return ROM_MANBOW2_V2;
120 if (iequals(name, "HamarajaNight")) return ROM_HAMARAJANIGHT;
121 if (iequals(name, "MegaFlashRomScc")) return ROM_MEGAFLSHSCC;
122 if (iequals(name, "MegaFlashRomSccPlus")) return ROM_MEGAFLSHSCCPLUS;
123 if (iequals(name, "Halnote")) return ROM_HALNOTE;
124 if (iequals(name, "HarryFox")) return ROM_HARRYFOX;
125 if (iequals(name, "Playball")) return ROM_PLAYBALL;
126 if (iequals(name, "Dooly")) return ROM_DOOLY;
127 if (iequals(name, "HolyQuran")) return ROM_HOLYQURAN;
128 if (iequals(name, "CrossBlaim")) return ROM_CROSSBLAIM;
129 if (iequals(name, "Zemina80in1")) return ROM_KOREAN80;
130 if (iequals(name, "Zemina90in1")) return ROM_KOREAN90;
131 if (iequals(name, "Zemina126in1")) return ROM_KOREAN126;
132 if (iequals(name, "Wizardry")) return ROM_ASCII8SRAM;
133 if (iequals(name, "GameMaster2")) return ROM_GAMEMASTER2;
134 if (iequals(name, "SuperLodeRunner")) return ROM_LODERUNNER;
135 if (iequals(name, "R-Type")) return ROM_RTYPE;
136 if (iequals(name, "Majutsushi")) return ROM_MAJUTSUSHI;
137 if (iequals(name, "Synthesizer")) return ROM_KONAMISYNTH;
138 if (iequals(name, "KeyboardMaster")) return ROM_KONAMKBDMAS;
139 if (iequals(name, "GenericKonami")) return ROM_KONAMI4NF;
140 if (iequals(name, "SuperPierrot")) return ROM_ASCII16NF;
141 if (iequals(name, "WordPro")) return ROM_KONWORDPRO;
142 if (iequals(name, "Normal")) return ROM_STANDARD;
143 if (iequals(name, "MatraInk")) return ROM_MATRAINK;
144 if (iequals(name, "NettouYakyuu")) return ROM_NETTOUYAKYUU;
145
146 // System roms
147 if (iequals(name, "Bunsetsu")) return ROM_BUNSETU;
148 if (iequals(name, "CasPatch")) return ROM_CASPATCH;
149 if (iequals(name, "Coleco")) return ROM_COLECO;
150 if (iequals(name, "MegaCart")) return ROM_CVMEGACART;
151 if (iequals(name, "ActivisionPCB")) return ROM_ACTIVISIONPCB;
152 if (iequals(name, "ActivisionPCB 2K")) return ROM_ACTIVISIONPCB_2K;
153 if (iequals(name, "ActivisionPCB 16K")) return ROM_ACTIVISIONPCB_16K;
154 if (iequals(name, "ActivisionPCB 256K")) return ROM_ACTIVISIONPCB_256K;
155 if (iequals(name, "SG1000")) return ROM_SG1000;
156 if (iequals(name, "SC3000")) return ROM_SC3000;
157 if (iequals(name, "SG1000Castle")) return ROM_SG1000CASTLE;
158 if (iequals(name, "SG1000RamA")) return ROM_SG1000_RAMEXPANDER_A;
159 if (iequals(name, "SG1000RamB")) return ROM_SG1000_RAMEXPANDER_B;
160 if (iequals(name, "SegaBasic")) return ROM_SEGABASIC;
161 if (iequals(name, "FMPAC")) return ROM_FMPAC;
162 if (iequals(name, "FMPAK")) return ROM_FMPAK;
163 if (iequals(name, "DiskPatch")) return ROM_DISKPATCH;
164 if (iequals(name, "Jisyo")) return ROM_JISYO;
165 if (iequals(name, "Kanji1")) return ROM_KANJI;
166 if (iequals(name, "Kanji12")) return ROM_KANJI12;
167 if (iequals(name, "MB8877A")) return ROM_NATIONALFDC;
168 if (iequals(name, "SVI707FDC")) return ROM_SVI707FDC;
169 if (iequals(name, "SVI738FDC")) return ROM_SVI738FDC;
170 if (iequals(name, "TC8566AF")) return ROM_TC8566AF;
171 if (iequals(name, "TC8566AFTR")) return ROM_TC8566AF_TR;
172 if (iequals(name, "WD2793")) return ROM_PHILIPSFDC;
173 if (iequals(name, "Microsol")) return ROM_MICROSOL;
174 if (iequals(name, "ARC")) return ROM_ARC;
175 if (iequals(name, "MoonSound")) return ROM_MOONSOUND;
176
177 if (iequals(name, "SunriseIDE")) return ROM_SUNRISEIDE;
178 if (iequals(name, "BeerIDE")) return ROM_BEERIDE;
179 if (iequals(name, "GIDE")) return ROM_GIDE;
180 if (iequals(name, "GoudaSCSI")) return ROM_GOUDASCSI;
181
182 if (iequals(name, "NMS1210")) return ROM_NMS1210;
183
184 if (iequals(name, "fsa1fm2")) return ROM_PANASONIC8;
185 if (iequals(name, "FSA1FM2")) return ROM_PANASONIC8;
186 if (iequals(name, "Panasonic8")) return ROM_PANASONIC8;
187 if (iequals(name, "PanasonicDram"))return ROM_DRAM;
188 if (iequals(name, "PanasonicWx16"))return ROM_PANASONICWX16;
189 if (iequals(name, "Panasonic16")) return ROM_PANASONIC16;
190 if (iequals(name, "Panasonic32")) return ROM_PANASONIC32;
191 if (iequals(name, "A1FMModem")) return ROM_FSA1FMMODEM;
192 if (iequals(name, "fsa1fm1")) return ROM_FSA1FMMODEM;
193 if (iequals(name, "FSA1FM1")) return ROM_FSA1FMMODEM;
194 if (iequals(name, "Standard16K")) return ROM_MSXDOS2;
195 if (iequals(name, "SVI328CART")) return ROM_SVI328CART;
196 if (iequals(name, "SVI328COL80")) return ROM_SVI328COL80;
197 if (iequals(name, "SVI727COL80")) return ROM_SVI727COL80;
198 if (iequals(name, "SVI707FDC")) return ROM_SVI707FDC;
199 if (iequals(name, "SVI738FDC")) return ROM_SVI738FDC;
200 if (iequals(name, "MSX-AUDIO")) return ROM_MSXAUDIO;
201 if (iequals(name, "MSX-MUSIC")) return ROM_MSXMUSIC;
202 if (iequals(name, "National")) return ROM_NATIONAL;
203 if (iequals(name, "CX5M-MUSIC")) return ROM_YAMAHASFG05;
204 if (iequals(name, "VMX80")) return ROM_MICROSOL80;
205 if (iequals(name, "HBI-V1")) return ROM_SONYHBIV1;
206 if (iequals(name, "SFG-01")) return ROM_YAMAHASFG01;
207 if (iequals(name, "SFG-05")) return ROM_YAMAHASFG05;
208 if (iequals(name, "NET")) return ROM_YAMAHANET;
209 if (iequals(name, "SF-7000IPL")) return ROM_SF7000IPL;
210 if (iequals(name, "FMDAS")) return ROM_FMDAS;
211 if (iequals(name, "Obsonet")) return ROM_OBSONET;
212 if (iequals(name, "Dumas")) return ROM_DUMAS;
213 if (iequals(name, "NoWind")) return ROM_NOWIND;
214
215 // Roms not supproted in this format in the db
216 if (iequals(name, "0x4000")) return ROM_0x4000;
217 if (iequals(name, "0xC000")) return ROM_0xC000;
218 if (iequals(name, "auto")) return ROM_PLAIN;
219 if (iequals(name, "basic")) return ROM_BASIC;
220
221 if (iequals(name, "mirrored")) return ROM_PLAIN;
222 if (iequals(name, "forteII")) return ROM_FORTEII;
223 if (iequals(name, "msxdos2")) return ROM_MSXDOS2;
224 if (iequals(name, "konami5")) return ROM_KONAMI5;
225 if (iequals(name, "MuPack")) return ROM_MUPACK;
226 if (iequals(name, "konami4")) return ROM_KONAMI4;
227 if (iequals(name, "ascii8")) return ROM_ASCII8;
228 if (iequals(name, "halnote")) return ROM_HALNOTE;
229 if (iequals(name, "konamisynth")) return ROM_KONAMISYNTH;
230 if (iequals(name, "kbdmaster")) return ROM_KONAMKBDMAS;
231 if (iequals(name, "majutsushi")) return ROM_MAJUTSUSHI;
232 if (iequals(name, "ascii16")) return ROM_ASCII16;
233 if (iequals(name, "gamemaster2")) return ROM_GAMEMASTER2;
234 if (iequals(name, "ascii8sram")) return ROM_ASCII8SRAM;
235 if (iequals(name, "koei")) return ROM_KOEI;
236 if (iequals(name, "ascii16sram")) return ROM_ASCII16SRAM;
237 if (iequals(name, "konami4nf")) return ROM_KONAMI4NF;
238 if (iequals(name, "ascii16nf")) return ROM_ASCII16NF;
239 if (iequals(name, "snatcher")) return ROM_SNATCHER;
240 if (iequals(name, "sdsnatcher")) return ROM_SDSNATCHER;
241 if (iequals(name, "sccmirrored")) return ROM_SCCMIRRORED;
242 if (iequals(name, "sccexpanded")) return ROM_SCCEXTENDED;
243 if (iequals(name, "scc")) return ROM_SCC;
244 if (iequals(name, "sccplus")) return ROM_SCCPLUS;
245 if (iequals(name, "scc-i")) return ROM_SCCPLUS;
246 if (iequals(name, "scc+")) return ROM_SCCPLUS;
247 if (iequals(name, "pac")) return ROM_PAC;
248 if (iequals(name, "fmpac")) return ROM_FMPAC;
249 if (iequals(name, "fmpak")) return ROM_FMPAK;
250 if (iequals(name, "rtype")) return ROM_RTYPE;
251 if (iequals(name, "crossblaim")) return ROM_CROSSBLAIM;
252 if (iequals(name, "harryfox")) return ROM_HARRYFOX;
253 if (iequals(name, "loderunner")) return ROM_LODERUNNER;
254 if (iequals(name, "korean80")) return ROM_KOREAN80;
255 if (iequals(name, "korean90")) return ROM_KOREAN90;
256 if (iequals(name, "korean126")) return ROM_KOREAN126;
257 if (iequals(name, "holyquran")) return ROM_HOLYQURAN;
258 if (iequals(name, "opcodesave")) return ROM_OPCODESAVE;
259 if (iequals(name, "opcodebios")) return ROM_OPCODEBIOS;
260 if (iequals(name, "opcodeslot")) return ROM_OPCODESLOT;
261 if (iequals(name, "opcodeega")) return ROM_OPCODEMEGA;
262 if (iequals(name, "coleco")) return ROM_COLECO;
263
264
265 // SG-1000 roms
266 if (iequals(name, "sg1000")) return ROM_SG1000;
267 if (iequals(name, "castle")) return ROM_SG1000CASTLE;
268 if (iequals(name, "sg1000ramA")) return ROM_SG1000_RAMEXPANDER_A;
269 if (iequals(name, "sg1000ramB")) return ROM_SG1000_RAMEXPANDER_B;
270 if (iequals(name, "sg1000castle")) return ROM_SG1000CASTLE;
271
272
273 return ROM_UNKNOWN;
274 }
275
276
mediaDbGetRemarks(TiXmlElement * dmp)277 static string mediaDbGetRemarks(TiXmlElement* dmp)
278 {
279 string remark;
280
281 for (TiXmlElement* it = dmp->FirstChildElement(); it != NULL; it = it->NextSiblingElement()) {
282 if (strcmp(it->Value(), "remark") == 0) {
283 for (TiXmlElement* i = it->FirstChildElement(); i != NULL; i = i->NextSiblingElement()) {
284 if (strcmp(i->Value(), "text") == 0) {
285 TiXmlNode* name = i->FirstChild();
286 if (name != NULL) {
287 if (remark.length()) {
288 remark += "\n";
289 }
290 remark += name->Value();
291 }
292 }
293 }
294 }
295 }
296
297 return remark;
298 }
299
mediaDbGetStart(TiXmlElement * dmp)300 static string mediaDbGetStart(TiXmlElement* dmp)
301 {
302 string start;
303
304 for (TiXmlElement* it = dmp->FirstChildElement(); it != NULL; it = it->NextSiblingElement()) {
305 if (strcmp(it->Value(), "start") == 0) {
306 for (TiXmlElement* i = it->FirstChildElement(); i != NULL; i = i->NextSiblingElement()) {
307 if (strcmp(i->Value(), "text") == 0) {
308 TiXmlNode* name = i->FirstChild();
309 if (name != NULL) {
310 if (start.length()) {
311 start += "\n";
312 }
313 start += name->Value();
314 }
315 }
316 }
317 }
318 }
319 return start;
320 }
321
mediaDbAddItem(MediaDb * mediaDb,TiXmlElement * dmp,const MediaType & mediaType)322 static void mediaDbAddItem(MediaDb* mediaDb, TiXmlElement* dmp, const MediaType& mediaType)
323 {
324 for (TiXmlElement* it = dmp->FirstChildElement(); it != NULL; it = it->NextSiblingElement()) {
325 if (strcmp(it->Value(), "hash") == 0) {
326 const char* type = it->Attribute("algo");
327 if (type != NULL) {
328 if (strcmp(type, "sha1") == 0) {
329 TiXmlNode* hash = it->FirstChild();
330 string sha1(hash->Value());
331 mediaDb->sha1Map[sha1] = new MediaType(mediaType);
332 // if (mediaDb == casdb) printf("Adding: %s: %s\n", mediaType.title.c_str(), sha1.c_str());
333 }
334 if (strcmp(type, "crc32") == 0) {
335 UInt32 crc32;
336 TiXmlNode* hash = it->FirstChild();
337 if (sscanf(hash->Value(), "%x", &crc32) == 1) {
338 mediaDb->crcMap[crc32] = new MediaType(mediaType);
339 }
340 }
341 }
342 }
343 }
344 }
345
mediaDbAddDump(TiXmlElement * dmp,string & title,string & company,string & country,string & year,string & system)346 static void mediaDbAddDump(TiXmlElement* dmp,
347 string& title,
348 string& company,
349 string& country,
350 string& year,
351 string& system)
352 {
353 if (strcmp(dmp->Value(), "megarom") == 0 || strcmp(dmp->Value(), "systemrom") == 0 || strcmp(dmp->Value(), "rom") == 0) {
354 RomType romType = strcmp(dmp->Value(), "rom") == 0 ? ROM_PLAIN : ROM_UNKNOWN;
355
356 for (TiXmlElement* it = dmp->FirstChildElement(); it != NULL; it = it->NextSiblingElement()) {
357 if (strcmp(it->Value(), "type") == 0) {
358 TiXmlNode* name = it->FirstChild();
359 if (name != NULL) {
360 romType = mediaDbStringToType(name->Value());
361 }
362 }
363 }
364
365 if (romType != ROM_CVMEGACART &&
366 romType != ROM_ACTIVISIONPCB && romType != ROM_ACTIVISIONPCB_2K &&
367 romType != ROM_ACTIVISIONPCB_16K && romType != ROM_ACTIVISIONPCB_256K) {
368 if (strcmpnocase(system.c_str(), "coleco") == 0) {
369 romType = ROM_COLECO;
370 }
371 }
372
373 if (strcmpnocase(system.c_str(), "svi") == 0) {
374 if (romType != ROM_SVI328COL80) {
375 romType = ROM_SVI328CART;
376 }
377 }
378
379 if (romType != ROM_SG1000CASTLE && romType != ROM_SEGABASIC &&
380 romType != ROM_SG1000_RAMEXPANDER_A && romType != ROM_SG1000_RAMEXPANDER_B) {
381 if (strcmpnocase(system.c_str(), "sg1000") == 0) {
382 romType = ROM_SG1000;
383 }
384
385 if (strcmpnocase(system.c_str(), "sc3000") == 0 ||
386 strcmpnocase(system.c_str(), "sf7000") == 0)
387 {
388 romType = ROM_SC3000;
389 }
390 }
391
392 // For standard roms, a start tag is used to specify start address
393 if (romType == ROM_STANDARD) {
394 for (TiXmlElement* it = dmp->FirstChildElement(); it != NULL; it = it->NextSiblingElement()) {
395 if (strcmp(it->Value(), "start") == 0) {
396 TiXmlNode* name = it->FirstChild();
397 if (name != NULL) {
398 if (strcmp(name->Value(), "0x0000") == 0) {
399 romType = ROM_STANDARD;
400 }
401 if (strcmp(name->Value(), "0x4000") == 0) {
402 romType = ROM_0x4000;
403 }
404 if (strcmp(name->Value(), "0x8000") == 0) {
405 romType = ROM_BASIC;
406 }
407 if (strcmp(name->Value(), "0xC000") == 0) {
408 romType = ROM_0xC000;
409 }
410 }
411 }
412 }
413 }
414
415 string remark = mediaDbGetRemarks(dmp);
416
417 mediaDbAddItem(romdb, dmp, MediaType(romType, title, company, year, country, remark));
418 }
419
420 if (strcmp(dmp->Value(), "sccpluscart") == 0) {
421 RomType romType = ROM_SCC;
422
423
424 for (TiXmlElement* it = dmp->FirstChildElement(); it != NULL; it = it->NextSiblingElement()) {
425 if (strcmp(it->Value(), "boot") == 0) {
426 TiXmlNode* name = it->FirstChild();
427 if (name != NULL && strcmp(name->Value(), "scc+") == 0) {
428 romType = ROM_SCCPLUS;
429 }
430 }
431 }
432
433 string remark = mediaDbGetRemarks(dmp);
434
435 mediaDbAddItem(romdb, dmp, MediaType(romType, title, company, year, country, remark));
436 }
437
438 if (strcmp(dmp->Value(), "cas") == 0) {
439 string start = mediaDbGetStart(dmp);
440 string remark = mediaDbGetRemarks(dmp);
441
442 for (TiXmlElement* itt = dmp->FirstChildElement(); itt != NULL; itt = itt->NextSiblingElement()) {
443 if (strcmp(itt->Value(), "format") == 0) {
444 const char* type = itt->Attribute("type");
445 if (type != NULL && strcmp(type, "cas") == 0) {
446 mediaDbAddItem(casdb, itt, MediaType(ROM_UNKNOWN, title, company, year, country, remark, start));
447 }
448 }
449 }
450 }
451
452 if (strcmp(dmp->Value(), "dsk") == 0) {
453 string start = mediaDbGetStart(dmp);
454 string remark = mediaDbGetRemarks(dmp);
455
456 for (TiXmlElement* itt = dmp->FirstChildElement(); itt != NULL; itt = itt->NextSiblingElement()) {
457 if (strcmp(itt->Value(), "format") == 0) {
458 const char* type = itt->Attribute("type");
459 if (type != NULL && strcmp(type, "dsk") == 0) {
460 mediaDbAddItem(diskdb, itt, MediaType(ROM_UNKNOWN, title, company, year, country, remark, start));
461 }
462 }
463 }
464 }
465 }
466
mediaDbAddFromXmlFile(const char * fileName)467 static void mediaDbAddFromXmlFile(const char* fileName)
468 {
469 static const char* rootTag = "softwaredb";
470
471 if (fileName == NULL) {
472 return;
473 }
474
475 TiXmlDocument doc(fileName);
476
477 doc.LoadFile();
478 if (doc.Error()) {
479 return;
480 }
481
482 TiXmlElement* root = doc.RootElement();
483 if (root == NULL || strcmp(root->Value(), rootTag) != 0) {
484 return;
485 }
486
487 for (TiXmlElement* sw = root->FirstChildElement(); sw != NULL; sw = sw->NextSiblingElement()) {
488 if (strcmp(sw->Value(), "software") != 0) {
489 continue;
490 }
491
492 string title;
493 string company;
494 string country;
495 string year;
496 string system;
497
498 TiXmlElement* item;
499
500 for (item = sw->FirstChildElement(); item != NULL; item = item->NextSiblingElement()) {
501 if (strcmp(item->Value(), "system") == 0) {
502 TiXmlNode* name = item->FirstChild();
503 if (name != NULL) {
504 system = name->Value();
505 }
506 }
507 if (strcmp(item->Value(), "title") == 0) {
508 TiXmlNode* name = item->FirstChild();
509 if (name != NULL) {
510 title = name->Value();
511 }
512 }
513 if (strcmp(item->Value(), "company") == 0) {
514 TiXmlNode* name = item->FirstChild();
515 if (name != NULL) {
516 company = name->Value();
517 }
518 }
519 if (strcmp(item->Value(), "country") == 0) {
520 TiXmlNode* name = item->FirstChild();
521 if (name != NULL) {
522 country = parseCountryCode(name->Value());
523 }
524 }
525 if (strcmp(item->Value(), "year") == 0) {
526 TiXmlNode* name = item->FirstChild();
527 if (name != NULL) {
528 year = name->Value();
529 }
530 }
531 }
532
533 for (item = sw->FirstChildElement(); item != NULL; item = item->NextSiblingElement()) {
534 if (strcmp(item->Value(), "dump") != 0) {
535 continue;
536 }
537
538 string start;
539
540 for (TiXmlElement* dmp = item->FirstChildElement(); dmp != NULL; dmp = dmp->NextSiblingElement()) {
541 if (strcmp(dmp->Value(), "group") == 0) {
542 for (TiXmlElement* it = dmp->FirstChildElement(); it != NULL; it = it->NextSiblingElement()) {
543 mediaDbAddDump(it, title, company, country, year, system);
544 }
545 continue;
546 }
547 mediaDbAddDump(dmp, title, company, country, year, system);
548 }
549 }
550 }
551 }
552
mediaDbLookup(MediaDb * mediaDb,const void * buffer,int size)553 extern MediaType* mediaDbLookup(MediaDb* mediaDb, const void *buffer, int size)
554 {
555 if (size > 2 * 1024 * 1024) {
556 return NULL;
557 }
558
559 SHA1 sha1;
560 sha1.update((const UInt8*)buffer, size);
561
562 // printf("SHA1: %s\n", sha1.hex_digest().c_str());
563
564 Sha1Map::iterator iterSha1 = mediaDb->sha1Map.find(sha1.hex_digest());
565 if (iterSha1 != mediaDb->sha1Map.end()) {
566 return iterSha1->second;
567 }
568
569 UInt32 crc = calcCrc32(buffer, size);
570
571 CrcMap::iterator iterCrc = mediaDb->crcMap.find(crc);
572 if (iterCrc != mediaDb->crcMap.end()) {
573 return iterCrc->second;
574 }
575
576 return NULL;
577 }
578
romTypeToString(RomType romType)579 extern "C" const char* romTypeToString(RomType romType)
580 {
581 switch (romType) {
582 case ROM_STANDARD: return langRomTypeStandard();
583 case ROM_MSXDOS2: return langRomTypeMsxdos2();
584 case ROM_KONAMI5: return langRomTypeKonamiScc();
585 case ROM_MUPACK: return "Mu-Pack";
586 case ROM_MANBOW2: return langRomTypeManbow2();
587 case ROM_HAMARAJANIGHT:return "Hamaraja Night";
588 case ROM_MANBOW2_V2: return "Manbow 2 v2";
589 case ROM_MEGAFLSHSCC: return langRomTypeMegaFlashRomScc();
590 case ROM_MEGAFLSHSCCPLUS: return "Mega Flash Rom SCC+";
591 case ROM_OBSONET: return langRomTypeObsonet();
592 case ROM_DUMAS: return langRomTypeDumas();
593 case ROM_NOWIND: return langRomTypeNoWind();
594 case ROM_KONAMI4: return langRomTypeKonami();
595 case ROM_ASCII8: return langRomTypeAscii8();
596 case ROM_ASCII16: return langRomTypeAscii16();
597 case ROM_GAMEMASTER2: return langRomTypeGameMaster2();
598 case ROM_ASCII8SRAM: return langRomTypeAscii8Sram();
599 case ROM_ASCII16SRAM: return langRomTypeAscii16Sram();
600 case ROM_RTYPE: return langRomTypeRtype();
601 case ROM_CROSSBLAIM: return langRomTypeCrossblaim();
602 case ROM_HARRYFOX: return langRomTypeHarryFox();
603 case ROM_MAJUTSUSHI: return langRomTypeMajutsushi();
604 case ROM_KOREAN80: return langRomTypeZenima80();
605 case ROM_KOREAN90: return langRomTypeZenima90();
606 case ROM_KOREAN126: return langRomTypeZenima126();
607 case ROM_SCC: return langRomTypeScc();
608 case ROM_SCCPLUS: return langRomTypeSccPlus();
609 case ROM_SNATCHER: return langRomTypeSnatcher();
610 case ROM_SDSNATCHER: return langRomTypeSdSnatcher();
611 case ROM_SCCMIRRORED: return langRomTypeSccMirrored();
612 case ROM_SCCEXTENDED: return langRomTypeSccExtended();
613 case ROM_FMPAC: return langRomTypeFmpac();
614 case ROM_FMPAK: return langRomTypeFmpak();
615 case ROM_KONAMI4NF: return langRomTypeKonamiGeneric();
616 case ROM_ASCII16NF: return langRomTypeSuperPierrot();
617 case ROM_PLAIN: return langRomTypeMirrored();
618 case ROM_NETTOUYAKYUU:return "Jaleco Moero!! Nettou Yakyuu '88";
619 case ROM_MATRAINK: return "Matra INK";
620 case ROM_FORTEII: return "Forte II";
621 case ROM_NORMAL: return langRomTypeNormal();
622 case ROM_DISKPATCH: return langRomTypeDiskPatch();
623 case ROM_CASPATCH: return langRomTypeCasPatch();
624 case ROM_TC8566AF: return langRomTypeTc8566afFdc();
625 case ROM_TC8566AF_TR: return langRomTypeTc8566afTrFdc();
626 case ROM_MICROSOL: return langRomTypeMicrosolFdc();
627 case ROM_ARC: return "Parallax ARC";
628 case ROM_NATIONALFDC: return langRomTypeNationalFdc();
629 case ROM_PHILIPSFDC: return langRomTypePhilipsFdc();
630 case ROM_SVI707FDC: return langRomTypeSvi707Fdc();
631 case ROM_SVI738FDC: return langRomTypeSvi738Fdc();
632 case RAM_MAPPER: return langRomTypeMappedRam();
633 case RAM_1KB_MIRRORED:return langRomTypeMirroredRam1k();
634 case RAM_2KB_MIRRORED:return langRomTypeMirroredRam2k();
635 case RAM_NORMAL: return langRomTypeNormalRam();
636 case ROM_KANJI: return langRomTypeKanji();
637 case ROM_HOLYQURAN: return langRomTypeHolyQuran();
638 case SRAM_MATSUCHITA: return langRomTypeMatsushitaSram();
639 case SRAM_MATSUCHITA_INV: return langRomTypeMasushitaSramInv();
640 case ROM_PANASONIC8: return langRomTypePanasonic8();
641 case ROM_PANASONICWX16:return langRomTypePanasonicWx16();
642 case ROM_PANASONIC16: return langRomTypePanasonic16();
643 case ROM_PANASONIC32: return langRomTypePanasonic32();
644 case ROM_FSA1FMMODEM: return langRomTypePanasonicModem();
645 case ROM_DRAM: return langRomTypeDram();
646 case ROM_BUNSETU: return langRomTypeBunsetsu();
647 case ROM_JISYO: return langRomTypeJisyo();
648 case ROM_KANJI12: return langRomTypeKanji12();
649 case ROM_NATIONAL: return langRomTypeNationalSram();
650 case SRAM_S1985: return langRomTypeS1985();
651 case ROM_S1990: return langRomTypeS1990();
652 case ROM_TURBORIO: return langRomTypeTurborPause();
653 case ROM_F4DEVICE: return langRomTypeF4deviceNormal();
654 case ROM_F4INVERTED: return langRomTypeF4deviceInvert();
655 case ROM_MSXMIDI: return langRomTypeMsxMidi();
656 case ROM_MSXMIDI_EXTERNAL: return langRomTypeMsxMidiExternal();
657 case ROM_TURBORTIMER: return langRomTypeTurborTimer();
658 case ROM_KOEI: return langRomTypeKoei();
659 case ROM_BASIC: return langRomTypeBasic();
660 case ROM_HALNOTE: return langRomTypeHalnote();
661 case ROM_LODERUNNER: return langRomTypeLodeRunner();
662 case ROM_0x4000: return langRomTypeNormal4000();
663 case ROM_0xC000: return langRomTypeNormalC000();
664 case ROM_KONAMISYNTH: return langRomTypeKonamiSynth();
665 case ROM_KONAMKBDMAS: return langRomTypeKonamiKbdMast();
666 case ROM_KONWORDPRO: return langRomTypeKonamiWordPro();
667 case ROM_PAC: return langRomTypePac();
668 case ROM_MEGARAM: return langRomTypeMegaRam();
669 case ROM_MEGARAM128: return langRomTypeMegaRam128();
670 case ROM_MEGARAM256: return langRomTypeMegaRam256();
671 case ROM_MEGARAM512: return langRomTypeMegaRam512();
672 case ROM_MEGARAM768: return langRomTypeMegaRam768();
673 case ROM_MEGARAM2M: return langRomTypeMegaRam2mb();
674 case ROM_EXTRAM: return langRomTypeExtRam();
675 case ROM_EXTRAM16KB: return langRomTypeExtRam16();
676 case ROM_EXTRAM32KB: return langRomTypeExtRam32();
677 case ROM_EXTRAM48KB: return langRomTypeExtRam48();
678 case ROM_EXTRAM64KB: return langRomTypeExtRam64();
679 case ROM_EXTRAM512KB: return langRomTypeExtRam512();
680 case ROM_EXTRAM1MB: return langRomTypeExtRam1mb();
681 case ROM_EXTRAM2MB: return langRomTypeExtRam2mb();
682 case ROM_EXTRAM4MB: return langRomTypeExtRam4mb();
683 case ROM_MSXMUSIC: return langRomTypeMsxMusic();
684 case ROM_MSXAUDIO: return langRomTypeMsxAudio();
685 case ROM_MOONSOUND: return langRomTypeMoonsound();
686 case ROM_SVI328CART: return langRomTypeSvi328Cart();
687 case ROM_SVI328FDC: return langRomTypeSvi328Fdc();
688 case ROM_SVI328PRN: return langRomTypeSvi328Prn();
689 case ROM_SVI328RS232: return langRomTypeSvi328Uart();
690 case ROM_SVI328COL80: return langRomTypeSvi328col80();
691 case ROM_SVI328RSIDE: return langRomTypeSvi328RsIde();
692 case ROM_SVI727COL80: return langRomTypeSvi727col80();
693 case ROM_COLECO: return langRomTypeColecoCart();
694 case ROM_SG1000: return langRomTypeSg1000Cart();
695 case ROM_SC3000: return langRomTypeSc3000Cart();
696 case ROM_SG1000CASTLE:return langRomTypeTheCastle();
697 case ROM_SG1000_RAMEXPANDER_A: return "Sega Ram Expander Type A";
698 case ROM_SG1000_RAMEXPANDER_B: return "Sega Ram Expander Type B";
699 case ROM_SEGABASIC: return langRomTypeSegaBasic();
700 case ROM_SONYHBI55: return langRomTypeSonyHbi55();
701 case ROM_MSXAUDIODEV: return langRomTypeY8950();
702 case ROM_MSXPRN: return langRomTypeMsxPrinter();
703 case ROM_TURBORPCM: return langRomTypeTurborPcm();
704 case ROM_JOYREXPSG: return "Joyrex PSG";
705 case ROM_OPCODEPSG: return "Opcode PSG";
706 case ROM_GAMEREADER: return langRomTypeGameReader();
707 case ROM_SUNRISEIDE: return langRomTypeSunriseIde();
708 case ROM_BEERIDE: return langRomTypeBeerIde();
709 case ROM_NMS1210: return "Philips NMS1210 Serial Interface";
710 case ROM_GIDE: return langRomTypeGide();
711 case ROM_MICROSOL80: return langRomTypeVmx80();
712 case ROM_NMS8280DIGI: return langRomTypeNms8280Digitiz();
713 case ROM_SONYHBIV1: return langRomTypeHbiV1Digitiz();
714 case ROM_PLAYBALL: return langRomTypePlayBall();
715 case ROM_DOOLY: return "Dooly";
716 case ROM_FMDAS: return langRomTypeFmdas();
717 case ROM_YAMAHASFG01: return langRomTypeSfg01();
718 case ROM_YAMAHASFG05: return langRomTypeSfg05();
719 case ROM_YAMAHANET: return "Yamaha Net";
720 case ROM_SF7000IPL: return "SF-7000 IPL";
721 case ROM_OPCODEBIOS: return "ColecoVision Opcode Bios";
722 case ROM_OPCODEMEGA: return "ColecoVision Opcode MegaRam";
723 case ROM_OPCODESAVE: return "ColecoVision Opcode SaveRam";
724 case ROM_OPCODESLOT: return "ColecoVision Opcode Slot Manager";
725 case ROM_CVMEGACART: return "ColecoVision MegaCart(R)";
726 case ROM_ACTIVISIONPCB: return "Colecovision Activision PCB";
727 case ROM_ACTIVISIONPCB_2K: return "Colecovision Activision PCB 2K";
728 case ROM_ACTIVISIONPCB_16K: return "Colecovision Activision PCB 16K";
729 case ROM_ACTIVISIONPCB_256K: return "Colecovision Activision PCB 256K";
730 case SRAM_MEGASCSI: return langRomTypeMegaSCSI();
731 case SRAM_MEGASCSI128:return langRomTypeMegaSCSI128();
732 case SRAM_MEGASCSI256:return langRomTypeMegaSCSI256();
733 case SRAM_MEGASCSI512:return langRomTypeMegaSCSI512();
734 case SRAM_MEGASCSI1MB:return langRomTypeMegaSCSI1mb();
735 case SRAM_ESERAM: return langRomTypeEseRam();
736 case SRAM_ESERAM128: return langRomTypeEseRam128();
737 case SRAM_ESERAM256: return langRomTypeEseRam256();
738 case SRAM_ESERAM512: return langRomTypeEseRam512();
739 case SRAM_ESERAM1MB: return langRomTypeEseRam1mb();
740 case SRAM_WAVESCSI: return langRomTypeWaveSCSI();
741 case SRAM_WAVESCSI128:return langRomTypeWaveSCSI128();
742 case SRAM_WAVESCSI256:return langRomTypeWaveSCSI256();
743 case SRAM_WAVESCSI512:return langRomTypeWaveSCSI512();
744 case SRAM_WAVESCSI1MB:return langRomTypeWaveSCSI1mb();
745 case SRAM_ESESCC: return langRomTypeEseSCC();
746 case SRAM_ESESCC128: return langRomTypeEseSCC128();
747 case SRAM_ESESCC256: return langRomTypeEseSCC256();
748 case SRAM_ESESCC512: return langRomTypeEseSCC512();
749 case ROM_GOUDASCSI: return langRomTypeGoudaSCSI();
750
751 case ROM_UNKNOWN: return langTextUnknown();
752 }
753
754 return langTextUnknown();
755 }
756
romTypeToShortString(RomType romType)757 extern "C" const char* romTypeToShortString(RomType romType)
758 {
759 switch (romType) {
760 case ROM_STANDARD: return "STANDARD";
761 case ROM_MSXDOS2: return "MSXDOS2";
762 case ROM_KONAMI5: return "KONAMI SCC";
763 case ROM_MUPACK: return "MU-PACK";
764 case ROM_MANBOW2: return "MANBOW 2";
765 case ROM_HAMARAJANIGHT:return "HAMARAJANGT";
766 case ROM_MANBOW2_V2: return "MANBOW 2 v2";
767 case ROM_MEGAFLSHSCC: return "MEGAFLSHSCC";
768 case ROM_MEGAFLSHSCCPLUS: return "MEGAFLSHSCC+";
769 case ROM_OBSONET: return "OBSONET";
770 case ROM_DUMAS: return "DUMAS";
771 case ROM_NOWIND: return "NOWIND";
772 case ROM_KONAMI4: return "KONAMI";
773 case ROM_ASCII8: return "ASCII8";
774 case ROM_ASCII16: return "ASCII16";
775 case ROM_GAMEMASTER2: return "GMASTER2";
776 case ROM_ASCII8SRAM: return "ASCII8SRAM";
777 case ROM_ASCII16SRAM: return "ASCII16SRAM";
778 case ROM_RTYPE: return "R-TYPE";
779 case ROM_CROSSBLAIM: return "CROSSBLAIM";
780 case ROM_HARRYFOX: return "HARRYFOX";
781 case ROM_KOREAN80: return "ZEM 80IN1";
782 case ROM_KOREAN126: return "ZEM 126IN1";
783 case ROM_KOREAN90: return "ZEM 90IN1";
784 case ROM_SCC: return "SCC";
785 case ROM_SCCPLUS: return "SCC-I";
786 case ROM_SNATCHER: return "SNATCHER";
787 case ROM_SDSNATCHER: return "SDSNATCHER";
788 case ROM_SCCMIRRORED: return "SCCMIRRORED";
789 case ROM_SCCEXTENDED: return "SCCEXTENDED";
790 case ROM_FMPAC: return "FMPAC";
791 case ROM_FMPAK: return "FMPAK";
792 case ROM_KONAMI4NF: return "KONAMI GEN";
793 case ROM_ASCII16NF: return "SUPERPIERR";
794 case ROM_PLAIN: return "MIRRORED";
795 case ROM_NETTOUYAKYUU:return "NETTOU YAKYUU";
796 case ROM_MATRAINK: return "MATRA INK";
797 case ROM_FORTEII: return "FORTE II";
798 case ROM_NORMAL: return "NORMAL";
799 case ROM_DRAM: return "DRAM";
800 case ROM_DISKPATCH: return "DISKPATCH";
801 case ROM_CASPATCH: return "CASPATCH";
802 case ROM_TC8566AF: return "TC8566AF";
803 case ROM_TC8566AF_TR: return "TC8566AF";
804 case ROM_MICROSOL: return "MICROSOL";
805 case ROM_ARC: return "ARC";
806 case ROM_NATIONALFDC: return "NATNL FDC";
807 case ROM_PHILIPSFDC: return "PHILIPSFDC";
808 case ROM_SVI707FDC: return "SVI707 FDC";
809 case ROM_SVI738FDC: return "SVI738 FDC";
810 case RAM_MAPPER: return "MAPPED RAM";
811 case RAM_1KB_MIRRORED:return "1K MIR RAM";
812 case RAM_2KB_MIRRORED:return "2K MIR RAM";
813 case RAM_NORMAL: return "NORMAL RAM";
814 case ROM_KANJI: return "KANJI";
815 case ROM_HOLYQURAN: return "HOLYQURAN";
816 case SRAM_MATSUCHITA: return "MATSUSHITA";
817 case SRAM_MATSUCHITA_INV: return "MATSUS INV";
818 case ROM_PANASONICWX16: return "PANASON 16";
819 case ROM_PANASONIC16: return "PANASON 16";
820 case ROM_PANASONIC32: return "PANASON 32";
821 case ROM_BUNSETU: return "BUNSETSU";
822 case ROM_JISYO: return "JISYO";
823 case ROM_KANJI12: return "KANJI12";
824 case ROM_NATIONAL: return "NATIONAL";
825 case SRAM_S1985: return "S1985";
826 case ROM_S1990: return "S1990";
827 case ROM_TURBORIO: return "TR PAUSE";
828 case ROM_F4DEVICE: return "F4NORMAL";
829 case ROM_F4INVERTED: return "F4INV";
830 case ROM_MSXMIDI: return "MSX-MIDI";
831 case ROM_MSXMIDI_EXTERNAL: return "MSX-MIDIEX";
832 case ROM_TURBORTIMER: return "TURBORTMR";
833 case ROM_KOEI: return "KOEI";
834 case ROM_BASIC: return "BASIC";
835 case ROM_HALNOTE: return "HALNOTE";
836 case ROM_LODERUNNER: return "LODERUNNER";
837 case ROM_0x4000: return "4000h";
838 case ROM_0xC000: return "C000h";
839 case ROM_KONAMISYNTH: return "KONSYNTH";
840 case ROM_KONAMKBDMAS: return "KBDMASTER";
841 case ROM_KONWORDPRO: return "KONWORDPRO";
842 case ROM_MAJUTSUSHI: return "MAJUTSUSHI";
843 case ROM_PAC: return "PAC";
844 case ROM_MEGARAM: return "MEGARAM";
845 case ROM_MEGARAM128: return "MEGARAM128";
846 case ROM_MEGARAM256: return "MEGARAM256";
847 case ROM_MEGARAM512: return "MEGARAM512";
848 case ROM_MEGARAM768: return "MEGARAM768";
849 case ROM_MEGARAM2M: return "MEGARAM2MB";
850 case ROM_EXTRAM: return "EXTERN RAM";
851 case ROM_EXTRAM16KB: return "EXTRAM 16";
852 case ROM_EXTRAM32KB: return "EXTRAM 32";
853 case ROM_EXTRAM48KB: return "EXTRAM 48";
854 case ROM_EXTRAM64KB: return "EXTRAM 64";
855 case ROM_EXTRAM512KB: return "EXTRAM 512";
856 case ROM_EXTRAM1MB: return "EXTRAM 2MB";
857 case ROM_EXTRAM2MB: return "EXTRAM 1MB";
858 case ROM_EXTRAM4MB: return "EXTRAM 4MB";
859 case ROM_MSXMUSIC: return "MSXMUSIC";
860 case ROM_MSXAUDIO: return "MSXAUDIO";
861 case ROM_MOONSOUND: return "MOONSOUND";
862 case ROM_SVI328CART: return "SVI328CART";
863 case ROM_SVI328FDC: return "SVI328FDC";
864 case ROM_SVI328PRN: return "SVI328PRN";
865 case ROM_SVI328RS232: return "SVI328RS232";
866 case ROM_SVI328COL80: return "SVI328COL80";
867 case ROM_SVI328RSIDE: return "SVI328RSIDE";
868 case ROM_SVI727COL80: return "SVI727COL80";
869 case ROM_COLECO: return "COLECO";
870 case ROM_SG1000: return "SG-1000";
871 case ROM_SC3000: return "SC-3000";
872 case ROM_SG1000CASTLE:return "THECASTLE";
873 case ROM_SEGABASIC: return "SEGABASIC";
874 case ROM_SG1000_RAMEXPANDER_A: return "SEGARAM A";
875 case ROM_SG1000_RAMEXPANDER_B: return "SEGARAM B";
876 case ROM_SONYHBI55: return "HBI-55";
877 case ROM_MSXAUDIODEV: return "MSXAUDIO";
878 case ROM_MSXPRN: return "MSXPRN";
879 case ROM_TURBORPCM: return "TURBOR PCM";
880 case ROM_JOYREXPSG: return "JOYREX PSG";
881 case ROM_OPCODEPSG: return "OPCODE PSG";
882 case ROM_OPCODEBIOS: return "OPCODE BIOS";
883 case ROM_OPCODEMEGA: return "OPCODE MEGA";
884 case ROM_OPCODESAVE: return "OPCODE SAVE";
885 case ROM_OPCODESLOT: return "OPCODE SLOT";
886 case ROM_GAMEREADER: return "GAMEREADER";
887 case ROM_SUNRISEIDE: return "SUNRISEIDE";
888 case ROM_BEERIDE: return "BEER IDE";
889 case ROM_NMS1210: return "NMS1210";
890 case ROM_GIDE: return "GIDE";
891 case ROM_MICROSOL80: return "MICROSOL80";
892 case ROM_NMS8280DIGI: return "8280 DIGI";
893 case ROM_SONYHBIV1: return "SONY HBI-V1";
894 case ROM_PLAYBALL: return "PLAYBALL";
895 case ROM_DOOLY: return "DOOLY";
896 case ROM_FMDAS: return "FM-DAS";
897 case ROM_YAMAHASFG01: return "SFG-01";
898 case ROM_YAMAHASFG05: return "SFG-05";
899 case ROM_YAMAHANET: return "YAMAHA NET";
900 case ROM_SF7000IPL: return "SF-7000 IPL";
901 case ROM_CVMEGACART: return "MEGACART";
902 case ROM_ACTIVISIONPCB: return "ACTIVISION";
903 case ROM_ACTIVISIONPCB_2K: return "ACTIVISN2";
904 case ROM_ACTIVISIONPCB_16K: return "ACTIVISI16";
905 case ROM_ACTIVISIONPCB_256K:return "ACTIVISI256";
906 case SRAM_MEGASCSI: return "MEGASCSI";
907 case SRAM_MEGASCSI128:return "MEGASCSI128";
908 case SRAM_MEGASCSI256:return "MEGASCSI256";
909 case SRAM_MEGASCSI512:return "MEGASCSI512";
910 case SRAM_MEGASCSI1MB:return "MEGASCSI1MB";
911 case SRAM_ESERAM: return "ESE-RAM";
912 case SRAM_ESERAM128: return "ESE-RAM128";
913 case SRAM_ESERAM256: return "ESE-RAM256";
914 case SRAM_ESERAM512: return "ESE-RAM512";
915 case SRAM_ESERAM1MB: return "ESE-RAM1MB";
916 case SRAM_WAVESCSI: return "WAVESCSI";
917 case SRAM_WAVESCSI128:return "WAVESCSI128";
918 case SRAM_WAVESCSI256:return "WAVESCSI256";
919 case SRAM_WAVESCSI512:return "WAVESCSI512";
920 case SRAM_WAVESCSI1MB:return "WAVESCSI1MB";
921 case SRAM_ESESCC: return "ESE-SCC";
922 case SRAM_ESESCC128: return "ESE-SCC128";
923 case SRAM_ESESCC256: return "ESE-SCC256";
924 case SRAM_ESESCC512: return "ESE-SCC512";
925 case ROM_GOUDASCSI: return "GOUDA SCSI";
926
927 case ROM_UNKNOWN: return "UNKNOWN";
928 }
929
930 return "UNKNOWN";
931 }
932
romTypeIsRom(RomType romType)933 int romTypeIsRom(RomType romType) {
934 switch (romType) {
935 case ROM_SCC: return 1;
936 case ROM_SCCPLUS: return 1;
937 case ROM_MOONSOUND: return 1;
938 case ROM_SNATCHER: return 1;
939 case ROM_SDSNATCHER: return 1;
940 case ROM_SCCMIRRORED: return 1;
941 case ROM_SCCEXTENDED: return 1;
942 case ROM_PLAIN: return 1;
943 case ROM_NETTOUYAKYUU:return 1;
944 case ROM_MATRAINK: return 1;
945 case ROM_FORTEII: return 1;
946 case ROM_FMPAK: return 1;
947 case ROM_NORMAL: return 1;
948 case ROM_DRAM: return 1;
949 case ROM_DISKPATCH: return 1;
950 case ROM_CASPATCH: return 1;
951 case ROM_MICROSOL: return 1;
952 case ROM_ARC: return 1;
953 case ROM_NATIONALFDC: return 1;
954 case ROM_PHILIPSFDC: return 1;
955 case ROM_SVI707FDC: return 1;
956 case ROM_SVI738FDC: return 1;
957 case ROM_HOLYQURAN: return 1;
958 case SRAM_MATSUCHITA: return 1;
959 case SRAM_MATSUCHITA_INV: return 1;
960 case ROM_BASIC: return 1;
961 case ROM_0x4000: return 1;
962 case ROM_0xC000: return 1;
963 case ROM_KONAMISYNTH: return 1;
964 case ROM_KONAMKBDMAS: return 1;
965 case ROM_KONWORDPRO: return 1;
966 case ROM_MICROSOL80: return 1;
967 case ROM_SONYHBIV1: return 1;
968 case ROM_PLAYBALL: return 1;
969 case ROM_DOOLY: return 1;
970 case ROM_FMDAS: return 1;
971 case ROM_YAMAHASFG01: return 1;
972 case ROM_YAMAHASFG05: return 1;
973 case ROM_SF7000IPL: return 1;
974 case ROM_YAMAHANET: return 1;
975 case ROM_EXTRAM16KB: return 1;
976 case ROM_EXTRAM32KB: return 1;
977 case ROM_EXTRAM48KB: return 1;
978 case ROM_EXTRAM64KB: return 1;
979 }
980 return 0;
981 }
982
romTypeIsMegaRom(RomType romType)983 int romTypeIsMegaRom(RomType romType) {
984 switch (romType) {
985 case ROM_STANDARD: return 1;
986 case ROM_MSXDOS2: return 1;
987 case ROM_KONAMI5: return 1;
988 case ROM_MUPACK: return 1;
989 case ROM_MANBOW2: return 1;
990 case ROM_HAMARAJANIGHT: return 1;
991 case ROM_MANBOW2_V2: return 1;
992 case ROM_MEGAFLSHSCC: return 1;
993 case ROM_MEGAFLSHSCCPLUS: return 1;
994 case ROM_OBSONET: return 1;
995 case ROM_DUMAS: return 1;
996 case ROM_NOWIND: return 1;
997 case ROM_KONAMI4: return 1;
998 case ROM_ASCII8: return 1;
999 case ROM_ASCII16: return 1;
1000 case ROM_GAMEMASTER2: return 1;
1001 case ROM_ASCII8SRAM: return 1;
1002 case ROM_TC8566AF: return 1;
1003 case ROM_TC8566AF_TR: return 1;
1004 case ROM_ASCII16SRAM: return 1;
1005 case ROM_RTYPE: return 1;
1006 case ROM_CROSSBLAIM: return 1;
1007 case ROM_HARRYFOX: return 1;
1008 case ROM_KOREAN80: return 1;
1009 case ROM_KOREAN126: return 1;
1010 case ROM_KONAMI4NF: return 1;
1011 case ROM_ASCII16NF: return 1;
1012 case ROM_HOLYQURAN: return 1;
1013 case ROM_MAJUTSUSHI: return 1;
1014 case ROM_KOEI: return 1;
1015 case ROM_HALNOTE: return 1;
1016 case ROM_LODERUNNER: return 1;
1017 case ROM_MSXAUDIO: return 1;
1018 case ROM_KOREAN90: return 1;
1019 case ROM_SONYHBI55: return 1;
1020 case ROM_EXTRAM512KB: return 1;
1021 case ROM_EXTRAM1MB: return 1;
1022 case ROM_EXTRAM2MB: return 1;
1023 case ROM_EXTRAM4MB: return 1;
1024 case ROM_GAMEREADER: return 1;
1025 case ROM_SUNRISEIDE: return 1;
1026 case ROM_BEERIDE: return 1;
1027 case SRAM_MEGASCSI: return 1;
1028 case SRAM_MEGASCSI128:return 1;
1029 case SRAM_MEGASCSI256:return 1;
1030 case SRAM_MEGASCSI512:return 1;
1031 case SRAM_MEGASCSI1MB:return 1;
1032 case SRAM_ESERAM: return 1;
1033 case SRAM_ESERAM128: return 1;
1034 case SRAM_ESERAM256: return 1;
1035 case SRAM_ESERAM512: return 1;
1036 case SRAM_ESERAM1MB: return 1;
1037 case SRAM_WAVESCSI: return 1;
1038 case SRAM_WAVESCSI128:return 1;
1039 case SRAM_WAVESCSI256:return 1;
1040 case SRAM_WAVESCSI512:return 1;
1041 case SRAM_WAVESCSI1MB:return 1;
1042 case SRAM_ESESCC: return 1;
1043 case SRAM_ESESCC128: return 1;
1044 case SRAM_ESESCC256: return 1;
1045 case SRAM_ESESCC512: return 1;
1046 }
1047 return 0;
1048 }
1049
romTypeIsMegaRam(RomType romType)1050 int romTypeIsMegaRam(RomType romType) {
1051 switch (romType) {
1052 case ROM_MEGARAM: return 1;
1053 case ROM_MEGARAM128: return 1;
1054 case ROM_MEGARAM256: return 1;
1055 case ROM_MEGARAM512: return 1;
1056 case ROM_MEGARAM768: return 1;
1057 case ROM_MEGARAM2M: return 1;
1058 }
1059 return 0;
1060 }
1061
romTypeIsFmPac(RomType romType)1062 int romTypeIsFmPac(RomType romType) {
1063 switch (romType) {
1064 case ROM_FMPAC: return 1;
1065 }
1066 return 0;
1067 }
1068
mediaDbLoad(const char * directory)1069 extern "C" void mediaDbLoad(const char* directory)
1070 {
1071 if (romdb == NULL) {
1072 romdb = new MediaDb;
1073 }
1074 if (diskdb == NULL) {
1075 diskdb = new MediaDb;
1076 }
1077 if (casdb == NULL) {
1078 casdb = new MediaDb;
1079 }
1080
1081 string path = directory;
1082 path += "/";
1083
1084 string searchPath = path + "*.xml";
1085
1086 ArchGlob* glob = archGlob(searchPath.c_str(), ARCH_GLOB_FILES);
1087
1088 if (glob != NULL) {
1089 for (int i = 0; i < glob->count; i++) {
1090 mediaDbAddFromXmlFile(glob->pathVector[i]);
1091 }
1092 archGlobFree(glob);
1093 }
1094 }
1095
mediaDbLookupRom(const void * buffer,int size)1096 extern "C" MediaType* mediaDbLookupRom(const void *buffer, int size)
1097 {
1098 const char* romData = (const char*)buffer;
1099 static MediaType defaultColeco(ROM_COLECO, "Unknown Coleco rom");
1100 static MediaType defaultSvi(ROM_SVI328CART, "Unknown SVI rom");
1101 static MediaType defaultSg1000(ROM_SG1000, "Unknown SG-1000 rom");
1102 static MediaType defaultSc3000(ROM_SC3000, "Unknown SC-3000 rom");
1103
1104 if (romdb == NULL) {
1105 return NULL;
1106 }
1107 MediaType* mediaType = mediaDbLookup(romdb, buffer, size);
1108
1109 if (mediaType == NULL &&
1110 size <= 0x8000 && (unsigned char)romData[0] == 0xF3 && romData[1] == 0x31)
1111 {
1112 mediaType = &defaultSvi;
1113 }
1114
1115 if (mediaType == NULL &&
1116 size <= 0x8000 && (unsigned char)romData[0] == 0x55 && (unsigned char)romData[1] == 0xAA)
1117 {
1118 mediaType = &defaultColeco;
1119 }
1120 #if 0
1121 if (mediaType == NULL &&
1122 size <= 0x8000 && (unsigned char)romData[0] == 0x55 && (unsigned char)romData[1] == 0xAA)
1123 {
1124 mediaType = &defaultSg1000;
1125 }
1126 #endif
1127 return mediaType;
1128 }
1129
mediaDbLookupDisk(const void * buffer,int size)1130 extern "C" MediaType* mediaDbLookupDisk(const void *buffer, int size)
1131 {
1132 if (diskdb == NULL) {
1133 return NULL;
1134 }
1135 return mediaDbLookup(diskdb, buffer, size);
1136 }
1137
mediaDbLookupCas(const void * buffer,int size)1138 extern "C" MediaType* mediaDbLookupCas(const void *buffer, int size)
1139 {
1140 if (casdb == NULL) {
1141 return NULL;
1142 }
1143 return mediaDbLookup(casdb, buffer, size);
1144 }
1145
mediaDbGetRomType(MediaType * mediaType)1146 RomType mediaDbGetRomType(MediaType* mediaType)
1147 {
1148 return mediaType->romType;
1149 }
1150
mediaDbGetTitle(MediaType * mediaType)1151 extern "C" const char* mediaDbGetTitle(MediaType* mediaType)
1152 {
1153 return mediaType->title.c_str();
1154 }
1155
mediaDbGetYear(MediaType * mediaType)1156 extern "C" const char* mediaDbGetYear(MediaType* mediaType)
1157 {
1158 return mediaType->year.c_str();
1159 }
1160
mediaDbGetCompany(MediaType * mediaType)1161 extern "C" const char* mediaDbGetCompany(MediaType* mediaType)
1162 {
1163 return mediaType->company.c_str();
1164 }
1165
mediaDbGetRemark(MediaType * mediaType)1166 extern "C" const char* mediaDbGetRemark(MediaType* mediaType)
1167 {
1168 return mediaType->remark.c_str();
1169 }
1170
mediaDbGetPrettyString(MediaType * mediaType)1171 extern "C" const char* mediaDbGetPrettyString(MediaType* mediaType)
1172 {
1173 static char prettyString[512];
1174
1175 prettyString[0] = 0;
1176
1177 if (mediaType != NULL) {
1178 strcat(prettyString, mediaType->title.c_str());
1179 if (mediaType->company.length() || mediaType->year.length() || mediaType->country.length()) {
1180 strcat(prettyString, " -");
1181 }
1182
1183 if (mediaType->company.length()) {
1184 strcat(prettyString, " ");
1185 strcat(prettyString, mediaType->company.c_str());
1186 }
1187
1188 if (mediaType->year.length()) {
1189 strcat(prettyString, " ");
1190 strcat(prettyString, mediaType->year.c_str());
1191 }
1192
1193 if (mediaType->country.length()) {
1194 strcat(prettyString, " ");
1195 strcat(prettyString, mediaType->country.c_str());
1196 }
1197
1198 if (mediaType->remark.length()) {
1199 std::string remark = " : ";
1200 for (int i = 0; mediaType->remark[i] != '\r' && mediaType->remark[i] != '\n' && mediaType->remark[i] != '\0'; i++) {
1201 remark += mediaType->remark[i];
1202 }
1203 int remarkLength = 35 - mediaType->start.length();
1204 if (remarkLength > 0) {
1205 if (remark.length() > 35) {
1206 remark = remark.substr(0, 35) + "...";
1207 }
1208 strcat(prettyString, remark.c_str());
1209 }
1210 }
1211
1212 if (mediaType->start.length()) {
1213 strcat(prettyString, " [ ");
1214 strcat(prettyString, mediaType->start.c_str());
1215 strcat(prettyString, " ]");
1216 }
1217 }
1218
1219 return prettyString;
1220 }
1221
1222
mediaDbSetDefaultRomType(RomType romType)1223 extern "C" void mediaDbSetDefaultRomType(RomType romType)
1224 {
1225 romdbDefaultType = romType;
1226 }
1227
mediaDbGuessRom(const void * buffer,int size)1228 extern "C" MediaType* mediaDbGuessRom(const void *buffer, int size)
1229 {
1230 static MediaType staticMediaType(ROM_UNKNOWN, "Unknown MSX rom");
1231
1232 const UInt8* romData = (const UInt8*)buffer;
1233 int i;
1234 int mapper;
1235 UInt32 counters[6] = { 0, 0, 0, 0, 0, 0 };
1236
1237 staticMediaType.romType = romdbDefaultType;
1238
1239 if (size < 128) {
1240 return &staticMediaType;
1241 }
1242
1243 MediaType* mediaType = mediaDbLookupRom(buffer, size);
1244 if (mediaType == NULL) {
1245 mediaType = &staticMediaType;
1246 // printf("xx %d\n", romdbDefaultType);
1247 }
1248
1249 if (mediaType->romType != ROM_UNKNOWN) {
1250 return mediaType;
1251 }
1252
1253 BoardType boardType = boardGetType();
1254
1255 switch (boardType) {
1256 case BOARD_SVI:
1257 staticMediaType.romType = ROM_SVI328CART;
1258 return &staticMediaType;
1259 case BOARD_COLECO:
1260 case BOARD_COLECOADAM:
1261 staticMediaType.romType = ROM_COLECO;
1262 return &staticMediaType;
1263 case BOARD_SG1000:
1264 staticMediaType.romType = ROM_SG1000;
1265 return &staticMediaType;
1266 case BOARD_SC3000:
1267 case BOARD_SF7000:
1268 staticMediaType.romType = ROM_SC3000;
1269 return &staticMediaType;
1270 case BOARD_MSX_FORTE_II:
1271 break;
1272 case BOARD_MSX:
1273 break;
1274 }
1275
1276
1277 if (size <= 0x10000) {
1278 if (size == 0x10000) {
1279 if (romData[0x4000] == 'A' && romData[0x4001] == 'B') mediaType->romType = ROM_PLAIN;
1280 else mediaType->romType = ROM_ASCII16;
1281 return mediaType;
1282 }
1283
1284 if (size <= 0x4000 && romData[0] == 'A' && romData[1] == 'B') {
1285 UInt16 init = romData[2] + 256 * romData[3];
1286 UInt16 text = romData[8] + 256 * romData[9];
1287 // if (init == 0 && (text & 0xc000) == 0x8000) {
1288 if ((text & 0xc000) == 0x8000) {
1289 mediaType->romType = ROM_BASIC;
1290 return mediaType;
1291 }
1292 }
1293 mediaType->romType = ROM_PLAIN;
1294 return mediaType;
1295 }
1296
1297 const char ManbowTag[] = "Mapper: Manbow 2";
1298 UInt32 tagLength = strlen(ManbowTag);
1299 for (i = 0; i < (int)(size - tagLength); i++) {
1300 if (romData[i] == ManbowTag[0]) {
1301 if (memcmp(romData + i, ManbowTag, tagLength) == 0) {
1302 mediaType->romType = ROM_MANBOW2;
1303 return mediaType;
1304 }
1305 }
1306 }
1307
1308 /* Count occurences of characteristic addresses */
1309 for (i = 0; i < size - 3; i++) {
1310 if (romData[i] == 0x32) {
1311 UInt32 value = romData[i + 1] + ((UInt32)romData[i + 2] << 8);
1312
1313 switch(value) {
1314 case 0x4000:
1315 case 0x8000:
1316 case 0xa000:
1317 counters[3]++;
1318 break;
1319
1320 case 0x5000:
1321 case 0x9000:
1322 case 0xb000:
1323 counters[2]++;
1324 break;
1325
1326 case 0x6000:
1327 counters[3]++;
1328 counters[4]++;
1329 counters[5]++;
1330 break;
1331
1332 case 0x6800:
1333 case 0x7800:
1334 counters[4]++;
1335 break;
1336
1337 case 0x7000:
1338 counters[2]++;
1339 counters[4]++;
1340 counters[5]++;
1341 break;
1342
1343 case 0x77ff:
1344 counters[5]++;
1345 break;
1346 }
1347 }
1348 }
1349
1350 /* Find which mapper type got more hits */
1351 mapper = 0;
1352
1353 counters[4] -= counters[4] ? 1 : 0;
1354
1355 for (i = 0; i <= 5; i++) {
1356 if (counters[i] > 0 && counters[i] >= counters[mapper]) {
1357 mapper = i;
1358 }
1359 }
1360
1361 if (mapper == 5 && counters[0] == counters[5]) {
1362 mapper = 0;
1363 }
1364
1365 switch (mapper) {
1366 default:
1367 case 0: mediaType->romType = ROM_STANDARD; break;
1368 case 1: mediaType->romType = ROM_MSXDOS2; break;
1369 case 2: mediaType->romType = ROM_KONAMI5; break;
1370 case 3: mediaType->romType = ROM_KONAMI4; break;
1371 case 4: mediaType->romType = ROM_ASCII8; break;
1372 case 5: mediaType->romType = ROM_ASCII16; break;
1373 }
1374
1375 return mediaType;
1376 }
1377
1378
mediaDbCreateRomdb()1379 extern "C" void mediaDbCreateRomdb()
1380 {
1381 if (romdb == NULL) {
1382 romdb = new MediaDb;
1383 }
1384 }
1385
mediaDbCreateDiskdb()1386 extern "C" void mediaDbCreateDiskdb()
1387 {
1388 if (diskdb == NULL) {
1389 diskdb = new MediaDb;
1390 }
1391 }
1392
mediaDbCreateCasdb()1393 extern "C" void mediaDbCreateCasdb()
1394 {
1395 if (casdb == NULL) {
1396 casdb = new MediaDb;
1397 }
1398 }
1399
1400