mirror of https://github.com/bsnes-emu/bsnes.git
Update to v076r01 release.
byuu says: Changelog: - fixed linear mirroring issue in memory map (fixes dash in Mega Man X) - home path for Windows is now %APPDATA%/bsnes (not %APPDATA%/.bsnes) - home path for OS X and Linux is now ~/.config/bsnes (not ~/.bsnes) - bsnes-geometry.cfg is now geometry.cfg; and it stores width,height - I do not yet restore width, height; because the GTK+ and Qt APIs treat window resize as implying setMinimumSize - added bsnes/ui/path; which I have some significant plans for - fixed a bug in realpath (specified path is not always a folder, so we should not always append / as with userpath) - bsnes.cfg, geometry.cfg and cheats.xml may now optionally exist in the same folder as the binary itself - ruby only imports the nall namespace after including system headers (should fix OS X 'decimal' issue) - nall::fp now uses atof (fixes nall::fp("0.05")) - I split the CheatDatabase to a separate cheat-database.cpp file; it was pretty ugly packed into cheat-editor.cpp - Makefile now has "options := " line; where you can add "debugger" if you like, and in the future maybe more options - also works via command-line: make options=debugger
This commit is contained in:
parent
64072325c4
commit
bc5fd8c53c
|
@ -1,9 +1,12 @@
|
|||
include nall/Makefile
|
||||
snes := snes
|
||||
gameboy := gameboy
|
||||
profile := accuracy
|
||||
profile := compatibility
|
||||
ui := ui
|
||||
|
||||
# debugger
|
||||
options :=
|
||||
|
||||
# compiler
|
||||
c := $(compiler) -std=gnu99
|
||||
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||
|
@ -18,9 +21,11 @@ objects := libco
|
|||
# profile-guided optimization
|
||||
# flags += -fprofile-use
|
||||
|
||||
flags := $(flags) $(foreach o,$(call strupper,$(options)),-D$o)
|
||||
|
||||
# platform
|
||||
ifeq ($(platform),x)
|
||||
link += -s -ldl -lX11 -lXext
|
||||
link += -ldl -lX11 -lXext
|
||||
else ifeq ($(platform),osx)
|
||||
else ifeq ($(platform),win)
|
||||
link += -mwindows
|
||||
|
|
|
@ -117,38 +117,7 @@ uintmax_t binary(const char *str) {
|
|||
}
|
||||
|
||||
double fp(const char *str) {
|
||||
if(!str) return 0.0;
|
||||
bool negate = false;
|
||||
|
||||
//check for negation
|
||||
if(*str == '-') {
|
||||
negate = true;
|
||||
str++;
|
||||
}
|
||||
|
||||
intmax_t result_integral = 0;
|
||||
while(*str) {
|
||||
uint8_t x = *str++;
|
||||
if(x >= '0' && x <= '9') x -= '0';
|
||||
else if(x == '.' || x == ',') break; //break loop and read fractional part
|
||||
else return (double)result_integral; //invalid value, assume no fractional part
|
||||
result_integral = result_integral * 10 + x;
|
||||
}
|
||||
|
||||
intmax_t result_fractional = 0;
|
||||
while(*str) {
|
||||
uint8_t x = *str++;
|
||||
if(x >= '0' && x <= '9') x -= '0';
|
||||
else break; //stop at first invalid character
|
||||
result_fractional = result_fractional * 10 + x;
|
||||
}
|
||||
|
||||
//calculate fractional portion
|
||||
double result = (double)result_fractional;
|
||||
while((uintmax_t)result > 0) result /= 10.0;
|
||||
result += (double)result_integral;
|
||||
|
||||
return !negate ? result : -result;
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ string realpath(const char *name) {
|
|||
if(::realpath(name, path)) {
|
||||
string result(path);
|
||||
result.transform("\\", "/");
|
||||
if(result.endswith("/") == false) result.append("/");
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include <ruby/ruby.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#undef mkdir
|
||||
#undef usleep
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
ruby
|
||||
version: 0.06 (2009-05-22)
|
||||
version: 0.06a (2011-02-27)
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
using namespace nall;
|
||||
|
||||
/* Video */
|
||||
|
||||
#define DeclareVideo(Name) \
|
||||
|
|
|
@ -44,12 +44,8 @@ void Bus::map(
|
|||
for(unsigned bank = bank_lo; bank <= bank_hi; bank++) {
|
||||
for(unsigned addr = addr_lo; addr <= addr_hi; addr++) {
|
||||
unsigned destaddr = (bank << 16) | addr;
|
||||
if(mode == MapMode::Linear) {
|
||||
destaddr = mirror(base + offset, length);
|
||||
offset = (offset + 1) % length;
|
||||
} else if(mode == MapMode::Shadow) {
|
||||
destaddr = mirror(base + destaddr, length);
|
||||
}
|
||||
if(mode == MapMode::Linear) destaddr = mirror(base + offset++, length);
|
||||
if(mode == MapMode::Shadow) destaddr = mirror(base + destaddr, length);
|
||||
lookup[(bank << 16) | addr] = id;
|
||||
target[(bank << 16) | addr] = destaddr;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
namespace SNES {
|
||||
namespace Info {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "076";
|
||||
static const char Version[] = "076.01";
|
||||
static const unsigned SerializerVersion = 18;
|
||||
}
|
||||
}
|
||||
|
||||
//#define DEBUGGER
|
||||
|
||||
#include <libco/libco.h>
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
include $(snes)/Makefile
|
||||
include $(gameboy)/Makefile
|
||||
|
||||
ui_objects := ui-main ui-general ui-settings ui-tools ui-input ui-utility ui-cartridge ui-debugger
|
||||
ui_objects := ui-main ui-general ui-settings ui-tools ui-input ui-utility ui-path ui-cartridge ui-debugger
|
||||
ui_objects += ruby phoenix
|
||||
ui_objects += $(if $(call streq,$(platform),win),resource)
|
||||
|
||||
|
@ -68,6 +68,7 @@ obj/ui-tools.o: $(ui)/tools/tools.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwild
|
|||
obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/settings/*)
|
||||
obj/ui-input.o: $(ui)/input/input.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/input/*)
|
||||
obj/ui-utility.o: $(ui)/utility/utility.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/utility/*)
|
||||
obj/ui-path.o: $(ui)/path/path.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/path/*)
|
||||
obj/ui-cartridge.o: $(ui)/cartridge/cartridge.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/cartridge/*)
|
||||
obj/ui-debugger.o: $(ui)/debugger/debugger.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/debugger/*)
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ struct TopLevelWindow : Window {
|
|||
#include "tools/tools.hpp"
|
||||
#include "input/input.hpp"
|
||||
#include "utility/utility.hpp"
|
||||
#include "path/path.hpp"
|
||||
#include "cartridge/cartridge.hpp"
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
Configuration config;
|
||||
|
||||
void Configuration::load() {
|
||||
configuration::load(string(path.user, "bsnes.cfg"));
|
||||
configuration::load(::path.home("bsnes.cfg"));
|
||||
}
|
||||
|
||||
void Configuration::save() {
|
||||
mkdir(path.user, 0755);
|
||||
configuration::save(string(path.user, "bsnes.cfg"));
|
||||
configuration::save(::path.home("bsnes.cfg"));
|
||||
}
|
||||
|
||||
void Configuration::create() {
|
||||
|
|
|
@ -10,8 +10,8 @@ void Application::main(int argc, char **argv) {
|
|||
config.create();
|
||||
inputMapper.create();
|
||||
|
||||
config.path.base = realpath(argv[0]);
|
||||
config.path.user = { userpath(), ".bsnes/" };
|
||||
config.path.base = dir(realpath(argv[0]));
|
||||
config.path.user = userpath();
|
||||
|
||||
config.load();
|
||||
config.save();
|
||||
|
@ -57,6 +57,7 @@ void Application::main(int argc, char **argv) {
|
|||
inputSettings.create();
|
||||
advancedSettings.create();
|
||||
cheatEditor.create();
|
||||
cheatDatabase.create();
|
||||
stateManager.create();
|
||||
#if defined(DEBUGGER)
|
||||
debugger.create();
|
||||
|
@ -158,19 +159,23 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
void Application::loadGeometry() {
|
||||
geometryConfig.load(string(config.path.user, "bsnes-geometry.cfg"));
|
||||
geometryConfig.load(path.home("geometry.cfg"));
|
||||
foreach(window, windows) {
|
||||
lstring position;
|
||||
position.split(",", window->position);
|
||||
Geometry geom = window->geometry();
|
||||
window->setGeometry({ (signed)integer(position[0]), (signed)integer(position[1]), geom.width, geom.height });
|
||||
window->setGeometry({
|
||||
(signed)integer(position[0]), (signed)integer(position[1]),
|
||||
geom.width, geom.height
|
||||
//(unsigned)decimal(position[2]), (unsigned)decimal(position[3])
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Application::saveGeometry() {
|
||||
foreach(window, windows) {
|
||||
Geometry geom = window->geometry();
|
||||
window->position = { geom.x, ",", geom.y };
|
||||
window->position = { geom.x, ",", geom.y, ",", geom.width, ",", geom.height };
|
||||
}
|
||||
geometryConfig.save(string(config.path.user, "bsnes-geometry.cfg"));
|
||||
geometryConfig.save(path.home("geometry.cfg"));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#include "../base.hpp"
|
||||
Path path;
|
||||
|
||||
string Path::home(const string &filename) {
|
||||
string path = { config.path.base, filename };
|
||||
if(file::exists(path)) return path;
|
||||
|
||||
path = config.path.user;
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
|
||||
path.append(".config/");
|
||||
mkdir(path, 0755);
|
||||
path.append("bsnes/");
|
||||
mkdir(path, 0755);
|
||||
#else
|
||||
path.append("bsnes/");
|
||||
mkdir(path, 0755);
|
||||
#endif
|
||||
path.append(filename);
|
||||
return path;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
struct Path {
|
||||
string home(const string &filename);
|
||||
};
|
||||
|
||||
extern Path path;
|
|
@ -0,0 +1,93 @@
|
|||
CheatDatabase cheatDatabase;
|
||||
|
||||
void CheatDatabase::create() {
|
||||
application.addWindow(this, "CheatDatabase", "192,192");
|
||||
|
||||
listView.setCheckable(true);
|
||||
selectAllButton.setText("Select All");
|
||||
unselectAllButton.setText("Unselect All");
|
||||
okButton.setText("Ok");
|
||||
|
||||
layout.setMargin(5);
|
||||
layout.append(listView, 0, 0, 5);
|
||||
controlLayout.append(selectAllButton, 100, 0, 5);
|
||||
controlLayout.append(unselectAllButton, 100, 0);
|
||||
controlLayout.append(spacerWidget, 0, 0);
|
||||
controlLayout.append(okButton, 80, 0);
|
||||
layout.append(controlLayout, 0, Style::ButtonHeight);
|
||||
setGeometry({ 0, 0, 600, layout.minimumHeight() + 350 });
|
||||
append(layout);
|
||||
|
||||
selectAllButton.onTick = [this]() {
|
||||
foreach(item, this->listData, n) this->listView.setChecked(n, true);
|
||||
};
|
||||
|
||||
unselectAllButton.onTick = [this]() {
|
||||
foreach(item, this->listData, n) this->listView.setChecked(n, false);
|
||||
};
|
||||
|
||||
okButton.onTick = { &CheatDatabase::addCodes, this };
|
||||
}
|
||||
|
||||
void CheatDatabase::findCodes() {
|
||||
string data;
|
||||
data.readfile(path.home("cheats.xml"));
|
||||
if(auto position = strpos(data, SNES::cartridge.sha256())) {
|
||||
auto startPosition = strpos((const char*)data + position(), ">");
|
||||
auto endPosition = strpos((const char*)data + position(), "</cartridge>");
|
||||
string xmlData = {
|
||||
"<cartridge>\n",
|
||||
substr((const char*)data + position() + 1, startPosition(), endPosition() - startPosition() - 1),
|
||||
"</cartridge>\n"
|
||||
};
|
||||
|
||||
setTitle("");
|
||||
listView.reset();
|
||||
listData.reset();
|
||||
|
||||
xml_element document = xml_parse(xmlData);
|
||||
foreach(root, document.element) {
|
||||
if(root.name == "cartridge") foreach(node, root.element) {
|
||||
if(node.name == "name") setTitle(node.parse());
|
||||
else if(node.name == "cheat") {
|
||||
string description, code;
|
||||
foreach(element, node.element) {
|
||||
if(element.name == "description") description = element.parse();
|
||||
else if(element.name == "code") code.append(string(element.parse(), "+"));
|
||||
}
|
||||
code.rtrim<1>("+");
|
||||
code.append("\t");
|
||||
code.append(description);
|
||||
listView.append(description);
|
||||
listData.append(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setVisible(true);
|
||||
} else {
|
||||
MessageWindow::information(cheatEditor, "Sorry, no cheat codes found for this cartridge.");
|
||||
}
|
||||
}
|
||||
|
||||
void CheatDatabase::addCodes() {
|
||||
foreach(code, listData, n) {
|
||||
if(listView.checked(n)) {
|
||||
if(auto position = cheatEditor.findUnusedSlot()) {
|
||||
lstring part;
|
||||
part.split("\t", code);
|
||||
SNES::cheat[position()].enabled = false;
|
||||
SNES::cheat[position()] = part[0];
|
||||
cheatEditor.cheatList.setChecked(position(), false);
|
||||
cheatEditor.cheatText[position()][CheatEditor::CheatCode] = part[0];
|
||||
cheatEditor.cheatText[position()][CheatEditor::CheatDesc] = part[1];
|
||||
} else {
|
||||
MessageWindow::warning(*this, "Ran out of empty slots for cheat codes.\nNot all cheat codes were added.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setVisible(false);
|
||||
cheatEditor.refresh();
|
||||
cheatEditor.synchronize();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
struct CheatDatabase : TopLevelWindow {
|
||||
VerticalLayout layout;
|
||||
ListView listView;
|
||||
HorizontalLayout controlLayout;
|
||||
Button selectAllButton;
|
||||
Button unselectAllButton;
|
||||
Widget spacerWidget;
|
||||
Button okButton;
|
||||
lstring listData;
|
||||
|
||||
void create();
|
||||
void findCodes();
|
||||
void addCodes();
|
||||
};
|
||||
|
||||
extern CheatDatabase cheatDatabase;
|
|
@ -100,7 +100,7 @@ void CheatEditor::create() {
|
|||
descLayout.append(descEdit, 0, 0);
|
||||
layout.append(descLayout, 0, Style::LineEditHeight, 5);
|
||||
controlLayout.append(findButton, 100, 0);
|
||||
controlLayout.append(spacer, 0, 0);
|
||||
controlLayout.append(spacerWidget, 0, 0);
|
||||
controlLayout.append(clearAllButton, 80, 0, 5);
|
||||
controlLayout.append(clearButton, 80, 0);
|
||||
layout.append(controlLayout, 0, Style::ButtonHeight);
|
||||
|
@ -113,46 +113,13 @@ void CheatEditor::create() {
|
|||
cheatList.onChange = { &CheatEditor::synchronize, this };
|
||||
cheatList.onTick = { &CheatEditor::toggle, this };
|
||||
codeEdit.onChange = descEdit.onChange = { &CheatEditor::bind, this };
|
||||
findButton.onTick = { &CheatEditor::findCodes, this };
|
||||
findButton.onTick = { &CheatDatabase::findCodes, &cheatDatabase };
|
||||
clearAllButton.onTick = { &CheatEditor::clearAll, this };
|
||||
clearButton.onTick = { &CheatEditor::clear, this };
|
||||
|
||||
onClose = []() {
|
||||
cheatEditor.databaseWindow.setVisible(false);
|
||||
cheatDatabase.setVisible(false);
|
||||
};
|
||||
|
||||
//databaseWindow
|
||||
application.addWindow(&databaseWindow, "CheatDatabase", "192,192");
|
||||
|
||||
databaseList.setCheckable(true);
|
||||
databaseSelectAll.setText("Select All");
|
||||
databaseUnselectAll.setText("Unselect All");
|
||||
databaseOk.setText("Ok");
|
||||
|
||||
databaseLayout.setMargin(5);
|
||||
databaseLayout.append(databaseList, 0, 0, 5);
|
||||
databaseControlLayout.append(databaseSelectAll, 100, 0, 5);
|
||||
databaseControlLayout.append(databaseUnselectAll, 100, 0);
|
||||
databaseControlLayout.append(databaseSpacer, 0, 0);
|
||||
databaseControlLayout.append(databaseOk, 80, 0);
|
||||
databaseLayout.append(databaseControlLayout, 0, Style::ButtonHeight);
|
||||
|
||||
databaseWindow.setGeometry({ 0, 0, 600, layout.minimumHeight() + 250 });
|
||||
databaseWindow.append(databaseLayout);
|
||||
|
||||
databaseSelectAll.onTick = []() {
|
||||
for(unsigned i = 0; i < cheatEditor.databaseCode.size(); i++) {
|
||||
cheatEditor.databaseList.setChecked(i, true);
|
||||
}
|
||||
};
|
||||
|
||||
databaseUnselectAll.onTick = []() {
|
||||
for(unsigned i = 0; i < cheatEditor.databaseCode.size(); i++) {
|
||||
cheatEditor.databaseList.setChecked(i, false);
|
||||
}
|
||||
};
|
||||
|
||||
databaseOk.onTick = { &CheatEditor::addDatabaseCodes, this };
|
||||
}
|
||||
|
||||
void CheatEditor::synchronize() {
|
||||
|
@ -201,48 +168,6 @@ void CheatEditor::bind() {
|
|||
refresh();
|
||||
}
|
||||
|
||||
void CheatEditor::findCodes() {
|
||||
string data;
|
||||
data.readfile(string(config.path.user, "cheats.xml"));
|
||||
if(data == "") data.readfile(string(config.path.base, "cheats.xml"));
|
||||
if(auto position = strpos(data, SNES::cartridge.sha256())) {
|
||||
auto startPosition = strpos((const char*)data + position(), ">");
|
||||
auto endPosition = strpos((const char*)data + position(), "</cartridge>");
|
||||
string xmlData = {
|
||||
"<cartridge>\n",
|
||||
substr((const char*)data + position() + 1, startPosition(), endPosition() - startPosition() - 1),
|
||||
"</cartridge>\n"
|
||||
};
|
||||
|
||||
databaseWindow.setTitle("");
|
||||
databaseList.reset();
|
||||
databaseCode.reset();
|
||||
|
||||
xml_element document = xml_parse(xmlData);
|
||||
foreach(root, document.element) {
|
||||
if(root.name == "cartridge") foreach(node, root.element) {
|
||||
if(node.name == "name") databaseWindow.setTitle(node.parse());
|
||||
else if(node.name == "cheat") {
|
||||
string description, code;
|
||||
foreach(element, node.element) {
|
||||
if(element.name == "description") description = element.parse();
|
||||
else if(element.name == "code") code.append(string(element.parse(), "+"));
|
||||
}
|
||||
code.rtrim<1>("+");
|
||||
code.append("\t");
|
||||
code.append(description);
|
||||
databaseList.append(description);
|
||||
databaseCode.append(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
databaseWindow.setVisible(true);
|
||||
} else {
|
||||
MessageWindow::information(cheatEditor, "Sorry, no cheat codes found for this cartridge.");
|
||||
}
|
||||
}
|
||||
|
||||
optional<unsigned> CheatEditor::findUnusedSlot() {
|
||||
for(unsigned i = 0; i < 128; i++) {
|
||||
if(cheatText[i][CheatCode] == "" && cheatText[i][CheatDesc] == "") return { true, i };
|
||||
|
@ -250,28 +175,6 @@ optional<unsigned> CheatEditor::findUnusedSlot() {
|
|||
return { false, 0 };
|
||||
}
|
||||
|
||||
void CheatEditor::addDatabaseCodes() {
|
||||
for(unsigned n = 0; n < databaseCode.size(); n++) {
|
||||
if(databaseList.checked(n)) {
|
||||
if(auto position = findUnusedSlot()) {
|
||||
lstring part;
|
||||
part.split("\t", databaseCode[n]);
|
||||
SNES::cheat[position()].enabled = false;
|
||||
SNES::cheat[position()] = part[0];
|
||||
cheatList.setChecked(position(), false);
|
||||
cheatText[position()][CheatCode] = part[0];
|
||||
cheatText[position()][CheatDesc] = part[1];
|
||||
} else {
|
||||
MessageWindow::warning(databaseWindow, "Ran out of empty slots for cheat codes.\nNot all cheat codes were added.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
databaseWindow.setVisible(false);
|
||||
refresh();
|
||||
synchronize();
|
||||
}
|
||||
|
||||
void CheatEditor::clearAll() {
|
||||
if(MessageWindow::question(cheatEditor, "Permanently erase all entered cheat codes?", MessageWindow::Buttons::YesNo) == MessageWindow::Response::Yes) {
|
||||
for(unsigned i = 0; i < 128; i++) {
|
||||
|
|
|
@ -8,21 +8,11 @@ struct CheatEditor : TopLevelWindow {
|
|||
Label descLabel;
|
||||
LineEdit descEdit;
|
||||
HorizontalLayout controlLayout;
|
||||
Label spacer;
|
||||
Widget spacerWidget;
|
||||
Button findButton;
|
||||
Button clearAllButton;
|
||||
Button clearButton;
|
||||
|
||||
TopLevelWindow databaseWindow;
|
||||
VerticalLayout databaseLayout;
|
||||
ListView databaseList;
|
||||
HorizontalLayout databaseControlLayout;
|
||||
Button databaseSelectAll;
|
||||
Button databaseUnselectAll;
|
||||
Label databaseSpacer;
|
||||
Button databaseOk;
|
||||
lstring databaseCode;
|
||||
|
||||
void load(string filename);
|
||||
void save(string filename);
|
||||
void create();
|
||||
|
@ -34,11 +24,11 @@ private:
|
|||
void refresh();
|
||||
void toggle(unsigned row);
|
||||
void bind();
|
||||
void findCodes();
|
||||
optional<unsigned> findUnusedSlot();
|
||||
void addDatabaseCodes();
|
||||
void clearAll();
|
||||
void clear();
|
||||
|
||||
friend class CheatDatabase;
|
||||
};
|
||||
|
||||
extern CheatEditor cheatEditor;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "../base.hpp"
|
||||
#include "cheat-editor.cpp"
|
||||
#include "cheat-database.cpp"
|
||||
#include "state-manager.cpp"
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
#include "cheat-editor.hpp"
|
||||
#include "cheat-database.hpp"
|
||||
#include "state-manager.hpp"
|
||||
|
|
Loading…
Reference in New Issue