src/gb/cheats.c (view raw)
1/* Copyright (c) 2013-2016 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 "cheats.h"
7
8#include "util/string.h"
9
10static void GBCheatSetDeinit(struct mCheatSet* set);
11static void GBCheatAddSet(struct mCheatSet* cheats, struct mCheatDevice* device);
12static void GBCheatRemoveSet(struct mCheatSet* cheats, struct mCheatDevice* device);
13static void GBCheatRefresh(struct mCheatSet* cheats, struct mCheatDevice* device);
14static void GBCheatSetCopyProperties(struct mCheatSet* set, struct mCheatSet* oldSet);
15static bool GBCheatAddLine(struct mCheatSet*, const char* line, int type);
16
17static struct mCheatSet* GBCheatSetCreate(struct mCheatDevice* device, const char* name) {
18 UNUSED(device);
19 struct GBCheatSet* set = malloc(sizeof(*set));
20 mCheatSetInit(&set->d, name);
21
22 set->d.deinit = GBCheatSetDeinit;
23 set->d.add = GBCheatAddSet;
24 set->d.remove = GBCheatRemoveSet;
25
26 set->d.addLine = GBCheatAddLine;
27 set->d.copyProperties = GBCheatSetCopyProperties;
28
29 set->d.refresh = GBCheatRefresh;
30 return &set->d;
31}
32
33struct mCheatDevice* GBCheatDeviceCreate(void) {
34 struct mCheatDevice* device = malloc(sizeof(*device));
35 mCheatDeviceCreate(device);
36 device->createSet = GBCheatSetCreate;
37 return device;
38}
39
40static void GBCheatSetDeinit(struct mCheatSet* set) {
41 struct GBCheatSet* gbset = (struct GBCheatSet*) set;
42 UNUSED(gbset);
43}
44
45static void GBCheatAddSet(struct mCheatSet* cheats, struct mCheatDevice* device) {
46 struct GBCheatSet* gbset = (struct GBCheatSet*) cheats;
47 UNUSED(gbset);
48 UNUSED(device);
49}
50
51static void GBCheatRemoveSet(struct mCheatSet* cheats, struct mCheatDevice* device) {
52 struct GBCheatSet* gbset = (struct GBCheatSet*) cheats;
53 UNUSED(gbset);
54 UNUSED(device);
55}
56
57static bool GBCheatAddGameShark(struct GBCheatSet* cheats, uint32_t op) {
58 struct mCheat* cheat = mCheatListAppend(&cheats->d.list);
59 cheat->type = CHEAT_ASSIGN;
60 cheat->width = 1;
61 cheat->address = ((op & 0xFF) << 8) | ((op >> 8) & 0xFF);
62 cheat->operand = (op >> 16) & 0xFF;
63 cheat->repeat = 1;
64 cheat->negativeRepeat = 0;
65 return true;
66}
67
68static bool GBCheatAddGameSharkLine(struct GBCheatSet* cheats, const char* line) {
69 uint32_t op;
70 if (!hex32(line, &op)) {
71 return false;
72 }
73 return GBCheatAddGameShark(cheats, op);
74}
75
76static bool GBCheatAddVBALine(struct GBCheatSet* cheats, const char* line) {
77 uint16_t address;
78 uint8_t value;
79 const char* lineNext = hex16(line, &address);
80 if (!lineNext && lineNext[0] != ':') {
81 return false;
82 }
83 if (!hex8(line, &value)) {
84 return false;
85 }
86 struct mCheat* cheat = mCheatListAppend(&cheats->d.list);
87 cheat->type = CHEAT_ASSIGN;
88 cheat->width = 1;
89 cheat->address = address;
90 cheat->operand = value;
91 cheat->repeat = 1;
92 cheat->negativeRepeat = 0;
93 return true;
94}
95
96bool GBCheatAddLine(struct mCheatSet* set, const char* line, int type) {
97 struct GBCheatSet* cheats = (struct GBCheatSet*) set;
98 switch (type) {
99 case GB_CHEAT_AUTODETECT:
100 break;
101 case GB_CHEAT_GAME_GENIE:
102 return false;
103 case GB_CHEAT_GAMESHARK:
104 return GBCheatAddGameSharkLine(cheats, line);
105 case GB_CHEAT_VBA:
106 return GBCheatAddVBALine(cheats, line);
107 default:
108 return false;
109 }
110
111 uint16_t op1;
112 uint8_t op2;
113 uint8_t op3;
114 const char* lineNext = hex16(line, &op1);
115 if (!lineNext) {
116 return false;
117 }
118 if (lineNext[0] == ':') {
119 return GBCheatAddVBALine(cheats, line);
120 }
121 lineNext = hex8(lineNext, &op2);
122 if (!lineNext) {
123 return false;
124 }
125 if (lineNext[0] == '-') {
126 return false;
127 }
128 lineNext = hex8(lineNext, &op3);
129 if (!lineNext) {
130 return false;
131 }
132 uint32_t realOp = op1 << 16;
133 realOp |= op2 << 8;
134 realOp |= op3;
135 return GBCheatAddGameShark(cheats, realOp);
136}
137
138static void GBCheatRefresh(struct mCheatSet* cheats, struct mCheatDevice* device) {
139 struct GBCheatSet* gbset = (struct GBCheatSet*) cheats;
140 UNUSED(gbset);
141 UNUSED(device);
142}
143
144static void GBCheatSetCopyProperties(struct mCheatSet* set, struct mCheatSet* oldSet) {
145 UNUSED(set);
146 UNUSED(oldSet);
147}