all repos — mgba @ b11171c6f1144ff00d5094454662f3ad4e4f5b4f

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