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}