all repos — mgba @ b5af2b584adfa9b11ab0675872ec8993347507a9

mGBA Game Boy Advance Emulator

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
 14static const struct GBCartridgeOverride _overrides[] = {
 15	// Pokemon Spaceworld 1997 demo
 16	{ 0x232a067d, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Gold (debug)
 17	{ 0x630ed957, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Gold (non-debug)
 18	{ 0x5aff0038, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Silver (debug)
 19	{ 0xa61856bd, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Silver (non-debug)
 20
 21	{ 0, 0, 0, { 0 } }
 22};
 23
 24bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverride* override) {
 25	override->model = GB_MODEL_AUTODETECT;
 26	override->mbc = GB_MBC_AUTODETECT;
 27	memset(override->gbColors, 0, sizeof(override->gbColors));
 28	bool found = false;
 29
 30	int i;
 31	for (i = 0; _overrides[i].headerCrc32; ++i) {
 32		if (override->headerCrc32 == _overrides[i].headerCrc32) {
 33			*override = _overrides[i];
 34			found = true;
 35			break;
 36		}
 37	}
 38
 39	if (config) {
 40		char sectionName[24] = "";
 41		snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
 42		const char* model = ConfigurationGetValue(config, sectionName, "model");
 43		const char* mbc = ConfigurationGetValue(config, sectionName, "mbc");
 44		const char* pal[12] = {
 45			ConfigurationGetValue(config, sectionName, "pal[0]"),
 46			ConfigurationGetValue(config, sectionName, "pal[1]"),
 47			ConfigurationGetValue(config, sectionName, "pal[2]"),
 48			ConfigurationGetValue(config, sectionName, "pal[3]"),
 49			ConfigurationGetValue(config, sectionName, "pal[4]"),
 50			ConfigurationGetValue(config, sectionName, "pal[5]"),
 51			ConfigurationGetValue(config, sectionName, "pal[6]"),
 52			ConfigurationGetValue(config, sectionName, "pal[7]"),
 53			ConfigurationGetValue(config, sectionName, "pal[8]"),
 54			ConfigurationGetValue(config, sectionName, "pal[9]"),
 55			ConfigurationGetValue(config, sectionName, "pal[10]"),
 56			ConfigurationGetValue(config, sectionName, "pal[11]")
 57		};
 58
 59		if (model) {
 60			override->model = GBNameToModel(model);
 61			found = override->model != GB_MODEL_AUTODETECT;
 62		}
 63
 64		if (mbc) {
 65			char* end;
 66			long type = strtoul(mbc, &end, 0);
 67			if (end && !*end) {
 68				override->mbc = type;
 69				found = true;
 70			}
 71		}
 72
 73		for (i = 0; i < 12; ++i) {
 74			if (!pal[i]) {
 75				continue;
 76			}
 77			char* end;
 78			unsigned long value = strtoul(pal[i], &end, 10);
 79			if (end == &pal[i][1] && *end == 'x') {
 80				value = strtoul(pal[i], &end, 16);
 81			}
 82			if (*end) {
 83				continue;
 84			}
 85			value |= 0xFF000000;
 86			override->gbColors[i] = value;
 87			if (i < 8) {
 88				override->gbColors[i + 4] = value;
 89			}
 90			if (i < 4) {
 91				override->gbColors[i + 8] = value;
 92			}
 93		}
 94	}
 95	return found;
 96}
 97
 98void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) {
 99	char sectionName[24] = "";
100	snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
101	const char* model = GBModelToName(override->model);
102	ConfigurationSetValue(config, sectionName, "model", model);
103
104	if (override->gbColors[0] & 0xFF000000) {
105		ConfigurationSetIntValue(config, sectionName, "pal[0]", override->gbColors[0] & ~0xFF000000);
106	}
107	if (override->gbColors[1] & 0xFF000000) {
108		ConfigurationSetIntValue(config, sectionName, "pal[1]", override->gbColors[1] & ~0xFF000000);
109	}
110	if (override->gbColors[2] & 0xFF000000) {
111		ConfigurationSetIntValue(config, sectionName, "pal[2]", override->gbColors[2] & ~0xFF000000);
112	}
113	if (override->gbColors[3] & 0xFF000000) {
114		ConfigurationSetIntValue(config, sectionName, "pal[3]", override->gbColors[3] & ~0xFF000000);
115	}
116	if (override->gbColors[4] & 0xFF000000) {
117		ConfigurationSetIntValue(config, sectionName, "pal[4]", override->gbColors[4] & ~0xFF000000);
118	}
119	if (override->gbColors[5] & 0xFF000000) {
120		ConfigurationSetIntValue(config, sectionName, "pal[5]", override->gbColors[5] & ~0xFF000000);
121	}
122	if (override->gbColors[6] & 0xFF000000) {
123		ConfigurationSetIntValue(config, sectionName, "pal[6]", override->gbColors[6] & ~0xFF000000);
124	}
125	if (override->gbColors[7] & 0xFF000000) {
126		ConfigurationSetIntValue(config, sectionName, "pal[7]", override->gbColors[7] & ~0xFF000000);
127	}
128	if (override->gbColors[8] & 0xFF000000) {
129		ConfigurationSetIntValue(config, sectionName, "pal[8]", override->gbColors[8] & ~0xFF000000);
130	}
131	if (override->gbColors[9] & 0xFF000000) {
132		ConfigurationSetIntValue(config, sectionName, "pal[9]", override->gbColors[9] & ~0xFF000000);
133	}
134	if (override->gbColors[10] & 0xFF000000) {
135		ConfigurationSetIntValue(config, sectionName, "pal[10]", override->gbColors[10] & ~0xFF000000);
136	}
137	if (override->gbColors[11] & 0xFF000000) {
138		ConfigurationSetIntValue(config, sectionName, "pal[11]", override->gbColors[11] & ~0xFF000000);
139	}
140
141	if (override->mbc != GB_MBC_AUTODETECT) {
142		ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
143	} else {
144		ConfigurationClearValue(config, sectionName, "mbc");
145	}
146}
147
148void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override) {
149	if (override->model != GB_MODEL_AUTODETECT) {
150		gb->model = override->model;
151	}
152
153	if (override->mbc != GB_MBC_AUTODETECT) {
154		gb->memory.mbcType = override->mbc;
155		GBMBCInit(gb);
156	}
157
158	int i;
159	for (i = 0; i < 12; ++i) {
160		if (!(override->gbColors[i] & 0xFF000000)) {
161			continue;
162		}
163		GBVideoSetPalette(&gb->video, i, override->gbColors[i]);
164		if (i < 8) {
165			GBVideoSetPalette(&gb->video, i + 4, override->gbColors[i]);
166		}
167		if (i < 4) {
168			GBVideoSetPalette(&gb->video, i + 8, override->gbColors[i]);
169		}
170	}
171}
172
173void GBOverrideApplyDefaults(struct GB* gb) {
174	struct GBCartridgeOverride override;
175	override.headerCrc32 = doCrc32(&gb->memory.rom[0x100], sizeof(struct GBCartridge));
176	if (GBOverrideFind(0, &override)) {
177		GBOverrideApply(gb, &override);
178	}
179}