src/gb/overrides.c (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/internal/gb/overrides.h>
7
8#include <mgba/internal/gb/gb.h>
9#include <mgba/internal/gb/mbc.h>
10
11#include <mgba-util/configuration.h>
12#include <mgba-util/crc32.h>
13
14#define PAL_ENTRY(A, B, C, D) \
15 0xFF000000 | M_RGB5_TO_RGB8(A), \
16 0xFF000000 | M_RGB5_TO_RGB8(B), \
17 0xFF000000 | M_RGB5_TO_RGB8(C), \
18 0xFF000000 | M_RGB5_TO_RGB8(D)
19
20#define PAL0 PAL_ENTRY(0x7FFF, 0x32BF, 0x00D0, 0x0000)
21#define PAL1 PAL_ENTRY(0x639F, 0x4279, 0x15B0, 0x04CB)
22#define PAL2 PAL_ENTRY(0x7FFF, 0x6E31, 0x454A, 0x0000)
23#define PAL3 PAL_ENTRY(0x7FFF, 0x1BEF, 0x0200, 0x0000)
24#define PAL4 PAL_ENTRY(0x7FFF, 0x421F, 0x1CF2, 0x0000)
25#define PAL5 PAL_ENTRY(0x7FFF, 0x5294, 0x294A, 0x0000)
26#define PAL6 PAL_ENTRY(0x7FFF, 0x03FF, 0x012F, 0x0000)
27#define PAL7 PAL_ENTRY(0x7FFF, 0x03EF, 0x01D6, 0x0000)
28#define PAL8 PAL_ENTRY(0x7FFF, 0x42B5, 0x3DC8, 0x0000)
29#define PAL9 PAL_ENTRY(0x7E74, 0x03FF, 0x0180, 0x0000)
30#define PAL10 PAL_ENTRY(0x67FF, 0x77AC, 0x1A13, 0x2D6B)
31#define PAL11 PAL_ENTRY(0x7ED6, 0x4BFF, 0x2175, 0x0000)
32#define PAL12 PAL_ENTRY(0x53FF, 0x4A5F, 0x7E52, 0x0000)
33#define PAL13 PAL_ENTRY(0x4FFF, 0x7ED2, 0x3A4C, 0x1CE0)
34#define PAL14 PAL_ENTRY(0x03ED, 0x7FFF, 0x255F, 0x0000)
35#define PAL15 PAL_ENTRY(0x036A, 0x021F, 0x03FF, 0x7FFF)
36#define PAL16 PAL_ENTRY(0x7FFF, 0x01DF, 0x0112, 0x0000)
37#define PAL17 PAL_ENTRY(0x231F, 0x035F, 0x00F2, 0x0009)
38#define PAL18 PAL_ENTRY(0x7FFF, 0x03EA, 0x011F, 0x0000)
39#define PAL19 PAL_ENTRY(0x299F, 0x001A, 0x000C, 0x0000)
40#define PAL20 PAL_ENTRY(0x7FFF, 0x027F, 0x001F, 0x0000)
41#define PAL21 PAL_ENTRY(0x7FFF, 0x03E0, 0x0206, 0x0120)
42#define PAL22 PAL_ENTRY(0x7FFF, 0x7EEB, 0x001F, 0x7C00)
43#define PAL23 PAL_ENTRY(0x7FFF, 0x3FFF, 0x7E00, 0x001F)
44#define PAL24 PAL_ENTRY(0x7FFF, 0x03FF, 0x001F, 0x0000)
45#define PAL25 PAL_ENTRY(0x03FF, 0x001F, 0x000C, 0x0000)
46#define PAL26 PAL_ENTRY(0x7FFF, 0x033F, 0x0193, 0x0000)
47#define PAL27 PAL_ENTRY(0x0000, 0x4200, 0x037F, 0x7FFF)
48#define PAL28 PAL_ENTRY(0x7FFF, 0x7E8C, 0x7C00, 0x0000)
49#define PAL29 PAL_ENTRY(0x7FFF, 0x1BEF, 0x6180, 0x0000)
50#define PAL30 PAL_ENTRY(0x7C00, 0x7FFF, 0x3FFF, 0x7E00)
51#define PAL31 PAL_ENTRY(0x7FFF, 0x7FFF, 0x7E8C, 0x7C00)
52#define PAL32 PAL_ENTRY(0x0000, 0x7FFF, 0x421F, 0x1CF2)
53
54#define PALETTE(X, Y, Z) { PAL ## X, PAL ## Y, PAL ## Z }
55
56static const struct GBCartridgeOverride _colorOverrides[] = {
57 // Adventures of Lolo (Europe)
58 { 0xFBE65286, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
59
60 // Alleyway (World)
61 { 0xCBAA161B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 9, 9) },
62
63 // Arcade Classic No. 1 - Asteroids & Missile Command (USA, Europe)
64 { 0x309FDB70, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
65
66 // Arcade Classic No. 3 - Galaga & Galaxian (USA)
67 { 0xE13EF629, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) },
68
69 // Arcade Classic No. 4 - Defender & Joust (USA, Europe)
70 { 0x5C8B229D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
71
72 // Balloon Kid (USA, Europe)
73 { 0xEC3438FA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 20) },
74
75 // Baseball (World)
76 { 0xE02904BD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(15, 31, 4) },
77
78 // Battle Arena Toshinden (USA)
79 { 0xA2C3DF62, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
80
81 // Battletoads in Ragnarok's World (Europe)
82 { 0x51B259CF, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 3) },
83
84 // Chessmaster, The (DMG-EM) (Europe)
85 { 0x96A68366, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) },
86
87 // David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (Europe)
88 { 0x6413F5E2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 28) },
89
90 // Donkey Kong (Japan, USA)
91 { 0xA777EE2F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 4, 4) },
92
93 // Donkey Kong (World) (Rev A)
94 { 0xC8F8ACDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 4, 4) },
95
96 // Donkey Kong Land (Japan)
97 { 0x2CA7EEF3, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) },
98
99 // Donkey Kong Land (USA, Europe)
100 { 0x0D3E401D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(13, 17, 4) },
101
102 // Donkey Kong Land 2 (USA, Europe)
103 { 0x07ED9445, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) },
104
105 // Donkey Kong Land III (USA, Europe)
106 { 0xCA01A31C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) },
107
108 // Donkey Kong Land III (USA, Europe) (Rev A)
109 { 0x6805BA1E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) },
110
111 // Dr. Mario (World)
112 { 0xA3C2C1E9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 28, 4) },
113
114 // Dr. Mario (World) (Rev A)
115 { 0x69975661, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 28, 4) },
116
117 // Dr. Mario (World) (Beta)
118 { 0x22E55535, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
119
120 // Dynablaster (Europe)
121 { 0xD9D0211F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) },
122
123 // F-1 Race (World)
124 { 0x8434CB2C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
125
126 // F-1 Race (World) (Rev A)
127 { 0xBA63383B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
128
129 // Game & Watch Gallery (Europe)
130 { 0x4A43B8B9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
131
132 // Game & Watch Gallery (USA)
133 { 0xBD0736D4, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
134
135 // Game & Watch Gallery (USA) (Rev A)
136 { 0xA969B4F0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
137
138 // Game Boy Camera Gold (USA)
139 { 0x83947EC8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
140
141 // Game Boy Gallery (Japan)
142 { 0xDC3C3642, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
143
144 // Game Boy Gallery - 5 Games in One (Europe)
145 { 0xD83E3F82, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
146
147 // Game Boy Gallery 2 (Australia)
148 { 0x6C477A30, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
149
150 // Game Boy Gallery 2 (Japan)
151 { 0xC5AAAFDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) },
152
153 // Game Boy Wars (Japan)
154 { 0x03E3ED72, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 22) },
155
156 // Golf (World)
157 { 0x885C242D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
158
159 // Hoshi no Kirby (Japan)
160 { 0x4AA02A13, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
161
162 // Hoshi no Kirby (Japan) (Rev A)
163 { 0x88D03280, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
164
165 // Hoshi no Kirby 2 (Japan)
166 { 0x58B7A321, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
167
168 // James Bond 007 (USA, Europe)
169 { 0x7DDEB68E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) },
170
171 // Kaeru no Tame ni Kane wa Naru (Japan)
172 { 0x7F805941, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 2) },
173
174 // Kid Icarus - Of Myths and Monsters (USA, Europe)
175 { 0x5D93DB0F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 4) },
176
177 // Killer Instinct (USA, Europe)
178 { 0x117043A9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 0) },
179
180 // King of Fighters '95, The (USA)
181 { 0x0F81CC70, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
182
183 // King of the Zoo (Europe)
184 { 0xB492FB51, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) },
185
186 // Kirby no Block Ball (Japan)
187 { 0x4203B79F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
188
189 // Kirby no Kirakira Kids (Japan)
190 { 0x74C3A937, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
191
192 // Kirby no Pinball (Japan)
193 { 0x89239AED, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 19) },
194
195 // Kirby's Block Ball (USA, Europe)
196 { 0xCE8B1B18, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
197
198 // Kirby's Dream Land (USA, Europe)
199 { 0x302017CC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
200
201 // Kirby's Dream Land 2 (USA, Europe)
202 { 0xF6C9E5A8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) },
203
204 // Kirby's Pinball Land (USA, Europe)
205 { 0x9C4AA9D8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 19) },
206
207 // Kirby's Star Stacker (USA, Europe)
208 { 0xC1B481CA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
209
210 // Legend of Zelda, The - Link's Awakening (Canada)
211 { 0x9F54D47B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
212
213 // Legend of Zelda, The - Link's Awakening (France)
214 { 0x441D7FAD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
215
216 // Legend of Zelda, The - Link's Awakening (Germany)
217 { 0x838D65D6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
218
219 // Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev A)
220 { 0x24CAAB4D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
221
222 // Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev B)
223 { 0xBCBB6BDB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
224
225 // Legend of Zelda, The - Link's Awakening (USA, Europe)
226 { 0x9A193109, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
227
228 // Magnetic Soccer (Europe)
229 { 0x6735A1F5, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
230
231 // Mario & Yoshi (Europe)
232 { 0xEC14B007, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) },
233
234 // Mario no Picross (Japan)
235 { 0x602C2371, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
236
237 // Mario's Picross (USA, Europe)
238 { 0x725BBFF6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
239
240 // Mega Man - Dr. Wily's Revenge (Europe)
241 { 0xB2FE1EDB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
242
243 // Mega Man II (Europe)
244 { 0xC5EE1580, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
245
246 // Mega Man III (Europe)
247 { 0x88249B90, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
248
249 // Metroid II - Return of Samus (World)
250 { 0xBDCCC648, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 25, 3) },
251
252 // Moguranya (Japan)
253 { 0x41C1D13C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 16) },
254
255 // Mole Mania (USA, Europe)
256 { 0x32E8EEA3, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 16) },
257
258 // Mystic Quest (Europe)
259 { 0x8DC57012, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
260
261 // Mystic Quest (France)
262 { 0x09728780, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
263
264 // Mystic Quest (Germany)
265 { 0x6F8568A8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
266
267 // Nigel Mansell's World Championship Racing (Europe)
268 { 0xAC2D636D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
269
270 // Nintendo World Cup (USA, Europe)
271 { 0xB43E44C1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
272
273 // Othello (Europe)
274 { 0x45F34317, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
275
276 // Pac-In-Time (Europe)
277 { 0x8C608574, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 28) },
278
279 // Picross 2 (Japan)
280 { 0xBA91DDD8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
281
282 // Pinocchio (Europe)
283 { 0x849C74C0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 2, 17) },
284
285 // Play Action Football (USA)
286 { 0x2B703514, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
287
288 // Pocket Bomberman (Europe)
289 { 0x9C5E0D5E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 17) },
290
291 // Pocket Camera (Japan) (Rev A)
292 { 0x211A85AC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(26, 26, 26) },
293
294 // Pocket Monsters - Aka (Japan)
295 { 0x29D07340, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
296
297 // Pocket Monsters - Aka (Japan) (Rev A)
298 { 0x6BB566EC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
299
300 // Pocket Monsters - Ao (Japan)
301 { 0x65EF364B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
302
303 // Pocket Monsters - Midori (Japan)
304 { 0x923D46DD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) },
305
306 // Pocket Monsters - Midori (Japan) (Rev A)
307 { 0x6C926BFF, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) },
308
309 // Pocket Monsters - Pikachu (Japan)
310 { 0xF52AD7C1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
311
312 // Pocket Monsters - Pikachu (Japan) (Rev A)
313 { 0x0B54FAEB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
314
315 // Pocket Monsters - Pikachu (Japan) (Rev B)
316 { 0x9A161366, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
317
318 // Pocket Monsters - Pikachu (Japan) (Rev C)
319 { 0x8E1C14E4, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
320
321 // Pokemon - Blaue Edition (Germany)
322 { 0x6C3587F2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
323
324 // Pokemon - Blue Version (USA, Europe)
325 { 0x28323CE0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
326
327 // Pokemon - Edicion Azul (Spain)
328 { 0x93FCE15B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
329
330 // Pokemon - Edicion Roja (Spain)
331 { 0xFD20BB1C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
332
333 // Pokemon - Red Version (USA, Europe)
334 { 0xCC25454F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
335
336 // Pokemon - Rote Edition (Germany)
337 { 0xE5DD23CE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
338
339 // Pokemon - Version Bleue (France)
340 { 0x98BFEC5A, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
341
342 // Pokemon - Version Rouge (France)
343 { 0x1D6D8022, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
344
345 // Pokemon - Versione Blu (Italy)
346 { 0x7864DECC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) },
347
348 // Pokemon - Versione Rossa (Italy)
349 { 0xFE2A3F93, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) },
350
351 // QIX (World)
352 { 0x5EECB346, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) },
353
354 // Radar Mission (Japan)
355 { 0xD03B1A15, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 8) },
356
357 // Radar Mission (USA, Europe)
358 { 0xCEDD9FEB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 8) },
359
360 // Soccer (Europe)
361 { 0xB0274CDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) },
362
363 // SolarStriker (World)
364 { 0x981620E7, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) },
365
366 // Space Invaders (Europe)
367 { 0x3B032784, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) },
368
369 // Space Invaders (USA)
370 { 0x63A767E2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) },
371
372 // Star Wars (USA, Europe) (Rev A)
373 { 0x44CE17EE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 28) },
374
375 // Street Fighter II (USA)
376 { 0xC512D0B1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
377
378 // Street Fighter II (USA, Europe) (Rev A)
379 { 0x79E16545, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
380
381 // Super Donkey Kong GB (Japan)
382 { 0x940D4974, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(13, 17, 4) },
383
384 // Super Mario Land (World)
385 { 0x6C0ACA9F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(11, 32, 32) },
386
387 // Super Mario Land (World) (Rev A)
388 { 0xCA117ACC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(11, 32, 32) },
389
390 // Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev A)
391 { 0x423E09E6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
392
393 // Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev B)
394 { 0x445A0358, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
395
396 // Super Mario Land 2 - 6 Golden Coins (USA, Europe)
397 { 0xDE2960A1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
398
399 // Super Mario Land 2 - 6-tsu no Kinka (Japan)
400 { 0xD47CED78, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
401
402 // Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev A)
403 { 0xA4B4F9F9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
404
405 // Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev B)
406 { 0x5842F25D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) },
407
408 // Super R.C. Pro-Am (USA, Europe)
409 { 0x8C39B1C8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) },
410
411 // Tennis (World)
412 { 0xD2BEBF08, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) },
413
414 // Tetris (World)
415 { 0xE906C6A6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
416
417 // Tetris (World) (Rev A)
418 { 0x4674B43F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) },
419
420 // Tetris 2 (USA)
421 { 0x687505F1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) },
422
423 // Tetris 2 (USA, Europe)
424 { 0x6761459F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) },
425
426 // Tetris Attack (USA)
427 { 0x00E9474B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) },
428
429 // Tetris Blast (USA, Europe)
430 { 0xDDDEEEDE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 20) },
431
432 // Tetris Attack (USA, Europe) (Rev A)
433 { 0x6628C535, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) },
434
435 // Tetris Flash (Japan)
436 { 0xED669A78, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) },
437
438 // Top Rank Tennis (USA)
439 { 0xA6497CC0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) },
440
441 // Top Ranking Tennis (Europe)
442 { 0x62C12E05, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) },
443
444 // Toy Story (Europe)
445 { 0x67066E28, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) },
446
447 // Vegas Stakes (USA, Europe)
448 { 0x80CB217F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) },
449
450 // Wario Land - Super Mario Land 3 (World)
451 { 0xF1EA10E9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 22) },
452
453 // Wario Land II (USA, Europe)
454 { 0xD56A50A1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 0, 28) },
455
456 // Wave Race (USA, Europe)
457 { 0x52A6E4CC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 23) },
458
459 // X (Japan)
460 { 0xFED4C47F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(5, 5, 5) },
461
462 // Yakuman (Japan)
463 { 0x40604F17, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
464
465 // Yakuman (Japan) (Rev A)
466 { 0x2959ACFC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) },
467
468 // Yoshi (USA)
469 { 0xAB1605B9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) },
470
471 // Yoshi no Cookie (Japan)
472 { 0x841753DA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 22) },
473
474 // Yoshi no Panepon (Japan)
475 { 0xAA1AD903, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) },
476
477 // Yoshi no Tamago (Japan)
478 { 0xD4098A6B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) },
479
480 // Yoshi's Cookie (USA, Europe)
481 { 0x940EDD87, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 22) },
482
483 // Zelda no Densetsu - Yume o Miru Shima (Japan)
484 { 0x259C9A82, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
485
486 // Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev A)
487 { 0x61F269CD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) },
488};
489
490static const struct GBCartridgeOverride _overrides[] = {
491 // Pokemon Spaceworld 1997 demo
492 { 0x232a067d, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Gold (debug)
493 { 0x630ed957, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Gold (non-debug)
494 { 0x5aff0038, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Silver (debug)
495 { 0xa61856bd, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Silver (non-debug)
496
497 { 0, 0, 0, { 0 } }
498};
499
500bool GBOverrideColorFind(struct GBCartridgeOverride* override) {
501 int i;
502 for (i = 0; _colorOverrides[i].headerCrc32; ++i) {
503 if (override->headerCrc32 == _colorOverrides[i].headerCrc32) {
504 memcpy(override->gbColors, _colorOverrides[i].gbColors, sizeof(override->gbColors));
505 return true;
506 }
507 }
508 return false;
509}
510
511bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverride* override) {
512 override->model = GB_MODEL_AUTODETECT;
513 override->mbc = GB_MBC_AUTODETECT;
514 memset(override->gbColors, 0, sizeof(override->gbColors));
515 bool found = false;
516
517 int i;
518 for (i = 0; _overrides[i].headerCrc32; ++i) {
519 if (override->headerCrc32 == _overrides[i].headerCrc32) {
520 *override = _overrides[i];
521 found = true;
522 break;
523 }
524 }
525
526 if (config) {
527 char sectionName[24] = "";
528 snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
529 const char* model = ConfigurationGetValue(config, sectionName, "model");
530 const char* mbc = ConfigurationGetValue(config, sectionName, "mbc");
531 const char* pal[12] = {
532 ConfigurationGetValue(config, sectionName, "pal[0]"),
533 ConfigurationGetValue(config, sectionName, "pal[1]"),
534 ConfigurationGetValue(config, sectionName, "pal[2]"),
535 ConfigurationGetValue(config, sectionName, "pal[3]"),
536 ConfigurationGetValue(config, sectionName, "pal[4]"),
537 ConfigurationGetValue(config, sectionName, "pal[5]"),
538 ConfigurationGetValue(config, sectionName, "pal[6]"),
539 ConfigurationGetValue(config, sectionName, "pal[7]"),
540 ConfigurationGetValue(config, sectionName, "pal[8]"),
541 ConfigurationGetValue(config, sectionName, "pal[9]"),
542 ConfigurationGetValue(config, sectionName, "pal[10]"),
543 ConfigurationGetValue(config, sectionName, "pal[11]")
544 };
545
546 if (model) {
547 override->model = GBNameToModel(model);
548 found = override->model != GB_MODEL_AUTODETECT;
549 }
550
551 if (mbc) {
552 char* end;
553 long type = strtoul(mbc, &end, 0);
554 if (end && !*end) {
555 override->mbc = type;
556 found = true;
557 }
558 }
559
560 for (i = 0; i < 12; ++i) {
561 if (!pal[i]) {
562 continue;
563 }
564 char* end;
565 unsigned long value = strtoul(pal[i], &end, 10);
566 if (end == &pal[i][1] && *end == 'x') {
567 value = strtoul(pal[i], &end, 16);
568 }
569 if (*end) {
570 continue;
571 }
572 value |= 0xFF000000;
573 override->gbColors[i] = value;
574 if (i < 8) {
575 override->gbColors[i + 4] = value;
576 }
577 if (i < 4) {
578 override->gbColors[i + 8] = value;
579 }
580 }
581 }
582 return found;
583}
584
585void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) {
586 char sectionName[24] = "";
587 snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
588 const char* model = GBModelToName(override->model);
589 ConfigurationSetValue(config, sectionName, "model", model);
590
591 if (override->gbColors[0] & 0xFF000000) {
592 ConfigurationSetIntValue(config, sectionName, "pal[0]", override->gbColors[0] & ~0xFF000000);
593 }
594 if (override->gbColors[1] & 0xFF000000) {
595 ConfigurationSetIntValue(config, sectionName, "pal[1]", override->gbColors[1] & ~0xFF000000);
596 }
597 if (override->gbColors[2] & 0xFF000000) {
598 ConfigurationSetIntValue(config, sectionName, "pal[2]", override->gbColors[2] & ~0xFF000000);
599 }
600 if (override->gbColors[3] & 0xFF000000) {
601 ConfigurationSetIntValue(config, sectionName, "pal[3]", override->gbColors[3] & ~0xFF000000);
602 }
603 if (override->gbColors[4] & 0xFF000000) {
604 ConfigurationSetIntValue(config, sectionName, "pal[4]", override->gbColors[4] & ~0xFF000000);
605 }
606 if (override->gbColors[5] & 0xFF000000) {
607 ConfigurationSetIntValue(config, sectionName, "pal[5]", override->gbColors[5] & ~0xFF000000);
608 }
609 if (override->gbColors[6] & 0xFF000000) {
610 ConfigurationSetIntValue(config, sectionName, "pal[6]", override->gbColors[6] & ~0xFF000000);
611 }
612 if (override->gbColors[7] & 0xFF000000) {
613 ConfigurationSetIntValue(config, sectionName, "pal[7]", override->gbColors[7] & ~0xFF000000);
614 }
615 if (override->gbColors[8] & 0xFF000000) {
616 ConfigurationSetIntValue(config, sectionName, "pal[8]", override->gbColors[8] & ~0xFF000000);
617 }
618 if (override->gbColors[9] & 0xFF000000) {
619 ConfigurationSetIntValue(config, sectionName, "pal[9]", override->gbColors[9] & ~0xFF000000);
620 }
621 if (override->gbColors[10] & 0xFF000000) {
622 ConfigurationSetIntValue(config, sectionName, "pal[10]", override->gbColors[10] & ~0xFF000000);
623 }
624 if (override->gbColors[11] & 0xFF000000) {
625 ConfigurationSetIntValue(config, sectionName, "pal[11]", override->gbColors[11] & ~0xFF000000);
626 }
627
628 if (override->mbc != GB_MBC_AUTODETECT) {
629 ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
630 } else {
631 ConfigurationClearValue(config, sectionName, "mbc");
632 }
633}
634
635void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override) {
636 if (override->model != GB_MODEL_AUTODETECT) {
637 gb->model = override->model;
638 }
639
640 if (override->mbc != GB_MBC_AUTODETECT) {
641 gb->memory.mbcType = override->mbc;
642 GBMBCInit(gb);
643 }
644
645 int i;
646 for (i = 0; i < 12; ++i) {
647 if (!(override->gbColors[i] & 0xFF000000)) {
648 continue;
649 }
650 GBVideoSetPalette(&gb->video, i, override->gbColors[i]);
651 if (i < 8) {
652 GBVideoSetPalette(&gb->video, i + 4, override->gbColors[i]);
653 }
654 if (i < 4) {
655 GBVideoSetPalette(&gb->video, i + 8, override->gbColors[i]);
656 }
657 }
658}
659
660void GBOverrideApplyDefaults(struct GB* gb) {
661 struct GBCartridgeOverride override;
662 override.headerCrc32 = doCrc32(&gb->memory.rom[0x100], sizeof(struct GBCartridge));
663 if (GBOverrideFind(0, &override)) {
664 GBOverrideApply(gb, &override);
665 }
666}