all repos — mgba @ 890b063ea5e3f7e4a6e742a57619c7ef959d8a0e

mGBA Game Boy Advance Emulator

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}