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}