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
10#include <mgba-util/configuration.h>
11#include <mgba-util/crc32.h>
12
13static const struct GBCartridgeOverride _overrides[] = {
14 // None yet
15 { 0, 0, 0 }
16};
17
18bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverride* override) {
19 override->model = GB_MODEL_AUTODETECT;
20 override->mbc = GB_MBC_AUTODETECT;
21 bool found = false;
22
23 int i;
24 for (i = 0; _overrides[i].headerCrc32; ++i) {
25 if (override->headerCrc32 == _overrides[i].headerCrc32) {
26 *override = _overrides[i];
27 found = true;
28 break;
29 }
30 }
31
32 if (config) {
33 char sectionName[24] = "";
34 snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
35 const char* model = ConfigurationGetValue(config, sectionName, "model");
36 const char* mbc = ConfigurationGetValue(config, sectionName, "mbc");
37
38 if (model) {
39 if (strcasecmp(model, "DMG") == 0) {
40 found = true;
41 override->model = GB_MODEL_DMG;
42 } else if (strcasecmp(model, "CGB") == 0) {
43 found = true;
44 override->model = GB_MODEL_CGB;
45 } else if (strcasecmp(model, "AGB") == 0) {
46 found = true;
47 override->model = GB_MODEL_AGB;
48 } else if (strcasecmp(model, "SGB") == 0) {
49 found = true;
50 override->model = GB_MODEL_DMG; // TODO
51 } else if (strcasecmp(model, "MGB") == 0) {
52 found = true;
53 override->model = GB_MODEL_DMG; // TODO
54 }
55 }
56
57 if (mbc) {
58 char* end;
59 long type = strtoul(mbc, &end, 0);
60 if (end && !*end) {
61 override->mbc = type;
62 found = true;
63 }
64 }
65 }
66 return found;
67}
68
69void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) {
70 char sectionName[24] = "";
71 snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
72 const char* model = 0;
73 switch (override->model) {
74 case GB_MODEL_DMG:
75 model = "DMG";
76 break;
77 case GB_MODEL_SGB:
78 model = "SGB";
79 break;
80 case GB_MODEL_CGB:
81 model = "CGB";
82 break;
83 case GB_MODEL_AGB:
84 model = "AGB";
85 break;
86 case GB_MODEL_AUTODETECT:
87 break;
88 }
89 ConfigurationSetValue(config, sectionName, "model", model);
90
91 if (override->mbc != GB_MBC_AUTODETECT) {
92 ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
93 } else {
94 ConfigurationClearValue(config, sectionName, "mbc");
95 }
96}
97
98void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override) {
99 if (override->model != GB_MODEL_AUTODETECT) {
100 gb->model = override->model;
101 }
102
103 if (override->mbc != GB_MBC_AUTODETECT) {
104 gb->memory.mbcType = override->mbc;
105 }
106}
107
108void GBOverrideApplyDefaults(struct GB* gb) {
109 struct GBCartridgeOverride override;
110 override.headerCrc32 = doCrc32(&gb->memory.rom[0x100], sizeof(struct GBCartridge));
111 if (GBOverrideFind(0, &override)) {
112 GBOverrideApply(gb, &override);
113 }
114}