all repos — mgba @ 3d77a9d922dbdcf6e92b5f63e577f61fc43776aa

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 }
 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
 39		if (model) {
 40			if (strcasecmp(model, "DMG") == 0) {
 41				found = true;
 42				override->model = GB_MODEL_DMG;
 43			} else if (strcasecmp(model, "CGB") == 0) {
 44				found = true;
 45				override->model = GB_MODEL_CGB;
 46			} else if (strcasecmp(model, "AGB") == 0) {
 47				found = true;
 48				override->model = GB_MODEL_AGB;
 49			} else if (strcasecmp(model, "SGB") == 0) {
 50				found = true;
 51				override->model = GB_MODEL_DMG; // TODO
 52			} else if (strcasecmp(model, "MGB") == 0) {
 53				found = true;
 54				override->model = GB_MODEL_DMG; // TODO
 55			}
 56		}
 57
 58		if (mbc) {
 59			char* end;
 60			long type = strtoul(mbc, &end, 0);
 61			if (end && !*end) {
 62				override->mbc = type;
 63				found = true;
 64			}
 65		}
 66	}
 67	return found;
 68}
 69
 70void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) {
 71	char sectionName[24] = "";
 72	snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
 73	const char* model = 0;
 74	switch (override->model) {
 75	case GB_MODEL_DMG:
 76		model = "DMG";
 77		break;
 78	case GB_MODEL_SGB:
 79		model = "SGB";
 80		break;
 81	case GB_MODEL_CGB:
 82		model = "CGB";
 83		break;
 84	case GB_MODEL_AGB:
 85		model = "AGB";
 86		break;
 87	case GB_MODEL_AUTODETECT:
 88		break;
 89	}
 90	ConfigurationSetValue(config, sectionName, "model", model);
 91
 92	if (override->mbc != GB_MBC_AUTODETECT) {
 93		ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
 94	} else {
 95		ConfigurationClearValue(config, sectionName, "mbc");
 96	}
 97}
 98
 99void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override) {
100	if (override->model != GB_MODEL_AUTODETECT) {
101		gb->model = override->model;
102	}
103
104	if (override->mbc != GB_MBC_AUTODETECT) {
105		gb->memory.mbcType = override->mbc;
106		GBMBCInit(gb);
107	}
108}
109
110void GBOverrideApplyDefaults(struct GB* gb) {
111	struct GBCartridgeOverride override;
112	override.headerCrc32 = doCrc32(&gb->memory.rom[0x100], sizeof(struct GBCartridge));
113	if (GBOverrideFind(0, &override)) {
114		GBOverrideApply(gb, &override);
115	}
116}