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 override->model = GBNameToModel(model);
47 found = override->model != GB_MODEL_AUTODETECT;
48 }
49
50 if (mbc) {
51 char* end;
52 long type = strtoul(mbc, &end, 0);
53 if (end && !*end) {
54 override->mbc = type;
55 found = true;
56 }
57 }
58
59 if (pal[0] && pal[1] && pal[2] && pal[3]) {
60 int i;
61 for (i = 0; i < 4; ++i) {
62 char* end;
63 unsigned long value = strtoul(pal[i], &end, 10);
64 if (end == &pal[i][1] && *end == 'x') {
65 value = strtoul(pal[i], &end, 16);
66 }
67 if (*end) {
68 continue;
69 }
70 override->gbColors[i] = value;
71 }
72 }
73 }
74 return found;
75}
76
77void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) {
78 char sectionName[24] = "";
79 snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
80 const char* model = GBModelToName(override->model);
81 ConfigurationSetValue(config, sectionName, "model", model);
82
83 if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
84 ConfigurationSetIntValue(config, sectionName, "pal[0]", override->gbColors[0]);
85 ConfigurationSetIntValue(config, sectionName, "pal[1]", override->gbColors[1]);
86 ConfigurationSetIntValue(config, sectionName, "pal[2]", override->gbColors[2]);
87 ConfigurationSetIntValue(config, sectionName, "pal[3]", override->gbColors[3]);
88 }
89 if (override->mbc != GB_MBC_AUTODETECT) {
90 ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
91 } else {
92 ConfigurationClearValue(config, sectionName, "mbc");
93 }
94}
95
96void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override) {
97 if (override->model != GB_MODEL_AUTODETECT) {
98 gb->model = override->model;
99 }
100
101 if (override->mbc != GB_MBC_AUTODETECT) {
102 gb->memory.mbcType = override->mbc;
103 GBMBCInit(gb);
104 }
105
106 if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
107 GBVideoSetPalette(&gb->video, 0, override->gbColors[0]);
108 GBVideoSetPalette(&gb->video, 1, override->gbColors[1]);
109 GBVideoSetPalette(&gb->video, 2, override->gbColors[2]);
110 GBVideoSetPalette(&gb->video, 3, override->gbColors[3]);
111 }
112}
113
114void GBOverrideApplyDefaults(struct GB* gb) {
115 struct GBCartridgeOverride override;
116 override.headerCrc32 = doCrc32(&gb->memory.rom[0x100], sizeof(struct GBCartridge));
117 if (GBOverrideFind(0, &override)) {
118 GBOverrideApply(gb, &override);
119 }
120}