all repos — mgba @ fa884d071ecaa3e05ff20b45a67bf9500dd3d6b6

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
 10#include <mgba-util/configuration.h>
 11#include <mgba-util/crc32.h>
 12
 13static const struct GBCartridgeOverride _overrides[] = {
 14	// None yet
 15	{ 0, 0, 0 }
 16};
 17
 18bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverride* override) {
 19	override->model = GB_MODEL_AUTODETECT;
 20	override->mbc = GB_MBC_AUTODETECT;
 21	bool found = false;
 22
 23	int i;
 24	for (i = 0; _overrides[i].headerCrc32; ++i) {
 25		if (override->headerCrc32 == _overrides[i].headerCrc32) {
 26			*override = _overrides[i];
 27			found = true;
 28			break;
 29		}
 30	}
 31
 32	if (config) {
 33		char sectionName[24] = "";
 34		snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
 35		const char* model = ConfigurationGetValue(config, sectionName, "model");
 36		const char* mbc = ConfigurationGetValue(config, sectionName, "mbc");
 37
 38		if (model) {
 39			if (strcasecmp(model, "DMG") == 0) {
 40				found = true;
 41				override->model = GB_MODEL_DMG;
 42			} else if (strcasecmp(model, "CGB") == 0) {
 43				found = true;
 44				override->model = GB_MODEL_CGB;
 45			} else if (strcasecmp(model, "AGB") == 0) {
 46				found = true;
 47				override->model = GB_MODEL_AGB;
 48			} else if (strcasecmp(model, "SGB") == 0) {
 49				found = true;
 50				override->model = GB_MODEL_DMG; // TODO
 51			} else if (strcasecmp(model, "MGB") == 0) {
 52				found = true;
 53				override->model = GB_MODEL_DMG; // TODO
 54			}
 55		}
 56
 57		if (mbc) {
 58			char* end;
 59			long type = strtoul(mbc, &end, 0);
 60			if (end && !*end) {
 61				override->mbc = type;
 62				found = true;
 63			}
 64		}
 65	}
 66	return found;
 67}
 68
 69void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) {
 70	char sectionName[24] = "";
 71	snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
 72	const char* model = 0;
 73	switch (override->model) {
 74	case GB_MODEL_DMG:
 75		model = "DMG";
 76		break;
 77	case GB_MODEL_SGB:
 78		model = "SGB";
 79		break;
 80	case GB_MODEL_CGB:
 81		model = "CGB";
 82		break;
 83	case GB_MODEL_AGB:
 84		model = "AGB";
 85		break;
 86	case GB_MODEL_AUTODETECT:
 87		break;
 88	}
 89	ConfigurationSetValue(config, sectionName, "model", model);
 90
 91	if (override->mbc != GB_MBC_AUTODETECT) {
 92		ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
 93	} else {
 94		ConfigurationClearValue(config, sectionName, "mbc");
 95	}
 96}
 97
 98void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override) {
 99	if (override->model != GB_MODEL_AUTODETECT) {
100		gb->model = override->model;
101	}
102
103	if (override->mbc != GB_MBC_AUTODETECT) {
104		gb->memory.mbcType = override->mbc;
105	}
106}
107
108void GBOverrideApplyDefaults(struct GB* gb) {
109	struct GBCartridgeOverride override;
110	override.headerCrc32 = doCrc32(&gb->memory.rom[0x100], sizeof(struct GBCartridge));
111	if (GBOverrideFind(0, &override)) {
112		GBOverrideApply(gb, &override);
113	}
114}