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_SGB;
58 } else if (strcasecmp(model, "MGB") == 0) {
59 found = true;
60 override->model = GB_MODEL_MGB;
61 } else if (strcasecmp(model, "SGB2") == 0) {
62 found = true;
63 override->model = GB_MODEL_SGB2;
64 }
65 }
66
67 if (mbc) {
68 char* end;
69 long type = strtoul(mbc, &end, 0);
70 if (end && !*end) {
71 override->mbc = type;
72 found = true;
73 }
74 }
75
76 if (pal[0] && pal[1] && pal[2] && pal[3]) {
77 int i;
78 for (i = 0; i < 4; ++i) {
79 char* end;
80 unsigned long value = strtoul(pal[i], &end, 10);
81 if (end == &pal[i][1] && *end == 'x') {
82 value = strtoul(pal[i], &end, 16);
83 }
84 if (*end) {
85 continue;
86 }
87 override->gbColors[i] = value;
88 }
89 }
90 }
91 return found;
92}
93
94void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) {
95 char sectionName[24] = "";
96 snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
97 const char* model = 0;
98 switch (override->model) {
99 case GB_MODEL_DMG:
100 model = "DMG";
101 break;
102 case GB_MODEL_SGB:
103 model = "SGB";
104 break;
105 case GB_MODEL_MGB:
106 model = "MGB";
107 break;
108 case GB_MODEL_SGB2:
109 model = "SGB2";
110 break;
111 case GB_MODEL_CGB:
112 model = "CGB";
113 break;
114 case GB_MODEL_AGB:
115 model = "AGB";
116 break;
117 case GB_MODEL_AUTODETECT:
118 break;
119 }
120 ConfigurationSetValue(config, sectionName, "model", model);
121
122 if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
123 ConfigurationSetIntValue(config, sectionName, "pal[0]", override->gbColors[0]);
124 ConfigurationSetIntValue(config, sectionName, "pal[1]", override->gbColors[1]);
125 ConfigurationSetIntValue(config, sectionName, "pal[2]", override->gbColors[2]);
126 ConfigurationSetIntValue(config, sectionName, "pal[3]", override->gbColors[3]);
127 }
128 if (override->mbc != GB_MBC_AUTODETECT) {
129 ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
130 } else {
131 ConfigurationClearValue(config, sectionName, "mbc");
132 }
133}
134
135void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override) {
136 if (override->model != GB_MODEL_AUTODETECT) {
137 gb->model = override->model;
138 }
139
140 if (override->mbc != GB_MBC_AUTODETECT) {
141 gb->memory.mbcType = override->mbc;
142 GBMBCInit(gb);
143 }
144
145 if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
146 GBVideoSetPalette(&gb->video, 0, override->gbColors[0]);
147 GBVideoSetPalette(&gb->video, 1, override->gbColors[1]);
148 GBVideoSetPalette(&gb->video, 2, override->gbColors[2]);
149 GBVideoSetPalette(&gb->video, 3, override->gbColors[3]);
150 }
151}
152
153void GBOverrideApplyDefaults(struct GB* gb) {
154 struct GBCartridgeOverride override;
155 override.headerCrc32 = doCrc32(&gb->memory.rom[0x100], sizeof(struct GBCartridge));
156 if (GBOverrideFind(0, &override)) {
157 GBOverrideApply(gb, &override);
158 }
159}