all repos — mgba @ a2c1ef2fcc0d3aab083962eb1efa09feee819c54

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	bool found = false;
 23
 24	int i;
 25	for (i = 0; _overrides[i].headerCrc32; ++i) {
 26		if (override->headerCrc32 == _overrides[i].headerCrc32) {
 27			*override = _overrides[i];
 28			found = true;
 29			break;
 30		}
 31	}
 32
 33	if (config) {
 34		char sectionName[24] = "";
 35		snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
 36		const char* model = ConfigurationGetValue(config, sectionName, "model");
 37		const char* mbc = ConfigurationGetValue(config, sectionName, "mbc");
 38		const char* pal[4] = {
 39			ConfigurationGetValue(config, sectionName, "pal[0]"),
 40			ConfigurationGetValue(config, sectionName, "pal[1]"),
 41			ConfigurationGetValue(config, sectionName, "pal[2]"),
 42			ConfigurationGetValue(config, sectionName, "pal[3]")
 43		};
 44
 45		if (model) {
 46			if (strcasecmp(model, "DMG") == 0) {
 47				found = true;
 48				override->model = GB_MODEL_DMG;
 49			} else if (strcasecmp(model, "CGB") == 0) {
 50				found = true;
 51				override->model = GB_MODEL_CGB;
 52			} else if (strcasecmp(model, "AGB") == 0) {
 53				found = true;
 54				override->model = GB_MODEL_AGB;
 55			} else if (strcasecmp(model, "SGB") == 0) {
 56				found = true;
 57				override->model = GB_MODEL_DMG; // TODO
 58			} else if (strcasecmp(model, "MGB") == 0) {
 59				found = true;
 60				override->model = GB_MODEL_DMG; // TODO
 61			}
 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		if (pal[0] && pal[1] && pal[2] && pal[3]) {
 74			int i;
 75			for (i = 0; i < 4; ++i) {
 76				char* end;
 77				unsigned long value = strtoul(pal[i], &end, 10);
 78				if (end == &pal[i][1] && *end == 'x') {
 79					value = strtoul(pal[i], &end, 16);
 80				}
 81				if (*end) {
 82					continue;
 83				}
 84				override->gbColors[i] = value;
 85			}
 86		}
 87	}
 88	return found;
 89}
 90
 91void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) {
 92	char sectionName[24] = "";
 93	snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
 94	const char* model = 0;
 95	switch (override->model) {
 96	case GB_MODEL_DMG:
 97		model = "DMG";
 98		break;
 99	case GB_MODEL_SGB:
100		model = "SGB";
101		break;
102	case GB_MODEL_CGB:
103		model = "CGB";
104		break;
105	case GB_MODEL_AGB:
106		model = "AGB";
107		break;
108	case GB_MODEL_AUTODETECT:
109		break;
110	}
111	ConfigurationSetValue(config, sectionName, "model", model);
112
113	if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
114		ConfigurationSetIntValue(config, sectionName, "pal[0]", override->gbColors[0]);
115		ConfigurationSetIntValue(config, sectionName, "pal[1]", override->gbColors[1]);
116		ConfigurationSetIntValue(config, sectionName, "pal[2]", override->gbColors[2]);
117		ConfigurationSetIntValue(config, sectionName, "pal[3]", override->gbColors[3]);
118	}
119	if (override->mbc != GB_MBC_AUTODETECT) {
120		ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
121	} else {
122		ConfigurationClearValue(config, sectionName, "mbc");
123	}
124}
125
126void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override) {
127	if (override->model != GB_MODEL_AUTODETECT) {
128		gb->model = override->model;
129	}
130
131	if (override->mbc != GB_MBC_AUTODETECT) {
132		gb->memory.mbcType = override->mbc;
133		GBMBCInit(gb);
134	}
135
136	if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
137		GBVideoSetPalette(&gb->video, 0, override->gbColors[0]);
138		GBVideoSetPalette(&gb->video, 1, override->gbColors[1]);
139		GBVideoSetPalette(&gb->video, 2, override->gbColors[2]);
140		GBVideoSetPalette(&gb->video, 3, override->gbColors[3]);
141	}
142}
143
144void GBOverrideApplyDefaults(struct GB* gb) {
145	struct GBCartridgeOverride override;
146	override.headerCrc32 = doCrc32(&gb->memory.rom[0x100], sizeof(struct GBCartridge));
147	if (GBOverrideFind(0, &override)) {
148		GBOverrideApply(gb, &override);
149	}
150}