mirror of https://github.com/bsnes-emu/bsnes.git
Update to v068r22 release.
byuu says: Wanted to torture myself, so I implemented the hardest window of all, the cheat code editor. I had to sacrifice checkboxes inside lists, unfortunately, but it's a necessary evil. Maybe some day if we can port checkboxes inside list items to Windows and GTK+, we can add it back. It should be the only really apparent GUI sacrifice, though. You toggle cheats by double-clicking them in the list. Easy to do, but not apparent. I also added in the focus policy.
This commit is contained in:
parent
9484d1bc92
commit
8a91c95002
|
@ -53,15 +53,15 @@ objects := $(patsubst %,obj/%.o,$(objects))
|
|||
# targets
|
||||
build: ui_build $(objects)
|
||||
ifeq ($(platform),osx)
|
||||
test -d ../bsnes-$(profile).app || mkdir -p ../bsnes-$(profile).app/Contents/MacOS
|
||||
$(strip $(cpp) -o ../bsnes-$(profile).app/Contents/MacOS/bsnes-$(profile) $(objects) $(link))
|
||||
test -d ../bsnes.app || mkdir -p ../bsnes.app/Contents/MacOS
|
||||
$(strip $(cpp) -o ../bsnes.app/Contents/MacOS/bsnes $(objects) $(link))
|
||||
else
|
||||
$(strip $(cpp) -o out/bsnes-$(profile) $(objects) $(link))
|
||||
$(strip $(cpp) -o out/bsnes $(objects) $(link))
|
||||
endif
|
||||
|
||||
install:
|
||||
ifeq ($(platform),x)
|
||||
install -D -m 755 out/bsnes-$(profile) $(DESTDIR)$(prefix)/bin/bsnes-$(profile)
|
||||
install -D -m 755 out/bsnes $(DESTDIR)$(prefix)/bin/bsnes
|
||||
install -D -m 644 qt/data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
install -D -m 644 qt/data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
gconftool-2 --type bool --set /desktop/gnome/interface/menus_have_icons true
|
||||
|
@ -69,7 +69,7 @@ endif
|
|||
|
||||
uninstall:
|
||||
ifeq ($(platform),x)
|
||||
rm $(DESTDIR)$(prefix)/bin/bsnes-$(profile)
|
||||
rm $(DESTDIR)$(prefix)/bin/bsnes
|
||||
rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
static void EditBox_change(EditBox *self) {
|
||||
if(self->onChange) self->onChange();
|
||||
if(self->object->locked == false && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
|
@ -38,5 +38,7 @@ string EditBox::text() {
|
|||
}
|
||||
|
||||
void EditBox::setText(const char *text) {
|
||||
object->locked = true;
|
||||
gtk_text_buffer_set_text(object->textBuffer, text, -1);
|
||||
object->locked = false;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ struct Widget : Object {
|
|||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
bool focused();
|
||||
virtual bool focused();
|
||||
void setFocused();
|
||||
};
|
||||
|
||||
|
@ -82,6 +82,7 @@ struct Window : Widget {
|
|||
static Window None;
|
||||
nall::function<bool ()> onClose;
|
||||
void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
bool focused();
|
||||
void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
void setDefaultFont(Font &font);
|
||||
void setFont(Font &font);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
static void TextBox_change(TextBox *self) {
|
||||
if(self->onChange) self->onChange();
|
||||
if(self->object->locked == false && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
|
@ -21,5 +21,7 @@ string TextBox::text() {
|
|||
}
|
||||
|
||||
void TextBox::setText(const char *text) {
|
||||
object->locked = true;
|
||||
gtk_entry_set_text(GTK_ENTRY(object->widget), text);
|
||||
object->locked = false;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
static gint Window_close(Window *window) {
|
||||
if(window->onClose) return !window->onClose();
|
||||
return false;
|
||||
if(window->onClose) {
|
||||
if(window->onClose()) window->setVisible(false);
|
||||
return true;
|
||||
}
|
||||
window->setVisible(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
|
@ -35,6 +39,10 @@ void Window::create(unsigned x, unsigned y, unsigned width, unsigned height, con
|
|||
gtk_widget_realize(object->widget);
|
||||
}
|
||||
|
||||
bool Window::focused() {
|
||||
return gtk_window_is_active(GTK_WINDOW(object->widget));
|
||||
}
|
||||
|
||||
void Window::setGeometry(unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
gtk_window_move(GTK_WINDOW(object->widget), x, y);
|
||||
gtk_widget_set_size_request(object->formContainer, width, height);
|
||||
|
|
|
@ -12,7 +12,7 @@ void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, uns
|
|||
}
|
||||
|
||||
string EditBox::getText() {
|
||||
unsigned length = SendMessage(widget->window, WM_GETTEXTLENGTH, 0, 0);
|
||||
unsigned length = GetWindowTextLength(widget->window);
|
||||
wchar_t buffer[length + 1];
|
||||
GetWindowText(widget->window, buffer, length + 1);
|
||||
buffer[length] = 0;
|
||||
|
@ -25,7 +25,9 @@ void EditBox::setText(const char *text) {
|
|||
string output = text;
|
||||
output.replace("\r", "");
|
||||
output.replace("\n", "\r\n");
|
||||
object->locked = true;
|
||||
SetWindowText(widget->window, utf16_t(output));
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
void EditBox::setEditable(bool editable) {
|
||||
|
|
|
@ -46,8 +46,8 @@ LRESULT CALLBACK Label_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpa
|
|||
}
|
||||
RECT rc;
|
||||
GetClientRect(hwnd, &rc);
|
||||
unsigned length = GetWindowTextLength(hwnd) + 1;
|
||||
wchar_t text[length];
|
||||
unsigned length = GetWindowTextLength(hwnd);
|
||||
wchar_t text[length + 1];
|
||||
GetWindowText(hwnd, text, length + 1);
|
||||
text[length] = 0;
|
||||
DrawText(ps.hdc, text, -1, &rc, DT_CALCRECT | DT_END_ELLIPSIS);
|
||||
|
|
|
@ -34,6 +34,10 @@ void ListBox::setHeaderVisible(bool headerVisible) {
|
|||
);
|
||||
}
|
||||
|
||||
void ListBox::reset() {
|
||||
ListView_DeleteAllItems(widget->window);
|
||||
}
|
||||
|
||||
void ListBox::resizeColumnsToContent() {
|
||||
for(unsigned i = 0; i < listBox->columns; i++) {
|
||||
ListView_SetColumnWidth(widget->window, i, LVSCW_AUTOSIZE_USEHEADER);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
struct Object::Data {
|
||||
unsigned id;
|
||||
bool locked;
|
||||
};
|
||||
|
||||
struct Font::Data {
|
||||
|
@ -80,4 +81,5 @@ Object::Object() {
|
|||
static unsigned guid = 100;
|
||||
object = new Object::Data;
|
||||
object->id = guid++;
|
||||
object->locked = false;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,20 @@ void TextBox::create(Window &parent, unsigned x, unsigned y, unsigned width, uns
|
|||
SendMessage(widget->window, WM_SETFONT, (WPARAM)(parent.window->defaultFont ? parent.window->defaultFont : os.os->proportionalFont), 0);
|
||||
}
|
||||
|
||||
void TextBox::setEditable(bool editable) {
|
||||
SendMessage(widget->window, EM_SETREADONLY, editable == false, (LPARAM)0);
|
||||
string TextBox::text() {
|
||||
unsigned length = GetWindowTextLength(widget->window);
|
||||
wchar_t text[length + 1];
|
||||
GetWindowText(widget->window, text, length + 1);
|
||||
text[length] = 0;
|
||||
return utf8_t(text);
|
||||
}
|
||||
|
||||
void TextBox::setText(const char *text) {
|
||||
object->locked = true;
|
||||
SetWindowText(widget->window, utf16_t(text));
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
void TextBox::setEditable(bool editable) {
|
||||
SendMessage(widget->window, EM_SETREADONLY, editable == false, 0);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ void Widget::setEnabled(bool enabled) {
|
|||
}
|
||||
|
||||
bool Widget::focused() {
|
||||
return GetDesktopWindow() == widget->window;
|
||||
return (GetForegroundWindow() == widget->window);
|
||||
}
|
||||
|
||||
void Widget::setFocused() {
|
||||
|
|
|
@ -201,7 +201,11 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
|
|||
|
||||
switch(msg) {
|
||||
case WM_CLOSE: {
|
||||
if(window.onClose) return window.onClose();
|
||||
if(window.onClose) {
|
||||
if(window.onClose()) window.setVisible(false);
|
||||
} else {
|
||||
window.setVisible(false);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -268,7 +272,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
|
|||
} else if(dynamic_cast<EditBox*>(object_ptr)) {
|
||||
EditBox &editBox = (EditBox&)*object_ptr;
|
||||
if(HIWORD(wparam) == EN_CHANGE) {
|
||||
if(editBox.onChange) editBox.onChange();
|
||||
if(editBox.object->locked == false && editBox.onChange) editBox.onChange();
|
||||
}
|
||||
} else if(dynamic_cast<RadioBox*>(object_ptr)) {
|
||||
RadioBox &radioBox = (RadioBox&)*object_ptr;
|
||||
|
@ -279,7 +283,7 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
|
|||
} else if(dynamic_cast<TextBox*>(object_ptr)) {
|
||||
TextBox &textBox = (TextBox&)*object_ptr;
|
||||
if(HIWORD(wparam) == EN_CHANGE) {
|
||||
if(textBox.onChange) textBox.onChange();
|
||||
if(textBox.object->locked == false && textBox.onChange) textBox.onChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,6 +213,8 @@ struct RadioBox : Widget {
|
|||
struct TextBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
nall::string text();
|
||||
void setText(const char *text);
|
||||
void setEditable(bool editable = true);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace SNES {
|
||||
namespace Info {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "068.21";
|
||||
static const char Version[] = "068.22";
|
||||
static const unsigned SerializerVersion = 13;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
ui_objects := ui-main ui-general ui-settings ui-utility ui-cartridge
|
||||
ui_objects := ui-main ui-general ui-settings ui-tools ui-utility ui-cartridge
|
||||
ui_objects += ruby phoenix
|
||||
ui_objects += $(if $(call streq,$(platform),win),resource)
|
||||
|
||||
|
@ -54,6 +54,7 @@ objects := $(ui_objects) $(objects)
|
|||
|
||||
obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/*)
|
||||
obj/ui-general.o: $(ui)/general/general.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/general/*)
|
||||
obj/ui-tools.o: $(ui)/tools/tools.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/tools/*)
|
||||
obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/settings/*)
|
||||
obj/ui-utility.o: $(ui)/utility/utility.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/utility/*)
|
||||
obj/ui-cartridge.o: $(ui)/cartridge/cartridge.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/cartridge/*)
|
||||
|
|
|
@ -17,6 +17,7 @@ using namespace phoenix;
|
|||
#include "config.hpp"
|
||||
#include "general/general.hpp"
|
||||
#include "settings/settings.hpp"
|
||||
#include "tools/tools.hpp"
|
||||
#include "utility/utility.hpp"
|
||||
#include "cartridge/cartridge.hpp"
|
||||
|
||||
|
@ -35,15 +36,21 @@ extern Application application;
|
|||
struct Style {
|
||||
enum : unsigned {
|
||||
#if defined(PHOENIX_WINDOWS)
|
||||
CheckBoxHeight = 15,
|
||||
ComboBoxHeight = 22,
|
||||
EditBoxHeight = 22,
|
||||
LabelHeight = 15,
|
||||
SliderHeight = 25,
|
||||
#elif defined(PHOENIX_GTK)
|
||||
CheckBoxHeight = 15,
|
||||
ComboBoxHeight = 22,
|
||||
EditBoxHeight = 22,
|
||||
LabelHeight = 15,
|
||||
SliderHeight = 22,
|
||||
#elif defined(PHOENIX_QT)
|
||||
CheckBoxHeight = 15,
|
||||
ComboBoxHeight = 22,
|
||||
EditBoxHeight = 22,
|
||||
LabelHeight = 15,
|
||||
SliderHeight = 22,
|
||||
#endif
|
||||
|
|
|
@ -8,11 +8,13 @@ bool Cartridge::loadNormal(const char *filename) {
|
|||
loadMemory(SNES::memory::cartram, baseName, ".srm");
|
||||
loadMemory(SNES::memory::cartrtc, baseName, ".rtc");
|
||||
utility.setTitle(notdir(nall::basename(baseName)));
|
||||
cheatEditor.load(nall::basename(baseName));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cartridge::unload() {
|
||||
if(SNES::cartridge.loaded() == false) return;
|
||||
cheatEditor.save(nall::basename(baseName));
|
||||
saveMemory(SNES::memory::cartram, baseName, ".srm");
|
||||
saveMemory(SNES::memory::cartrtc, baseName, ".rtc");
|
||||
SNES::cartridge.unload();
|
||||
|
|
|
@ -21,4 +21,6 @@ void Configuration::create() {
|
|||
attach(audio.mute = false, "audio.mute");
|
||||
|
||||
attach(input.driver = "", "input.driver");
|
||||
|
||||
attach(settings.focusPolicy = 0, "settings.focusPolicy");
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ struct Configuration : public configuration {
|
|||
string driver;
|
||||
} input;
|
||||
|
||||
struct Settings {
|
||||
unsigned focusPolicy;
|
||||
} settings;
|
||||
|
||||
void load();
|
||||
void save();
|
||||
void create();
|
||||
|
|
|
@ -11,7 +11,7 @@ void MainWindow::create() {
|
|||
systemLoadCartridge.create(system, "Load Cartridge ...");
|
||||
systemSeparator.create(system);
|
||||
systemQuit.create(system, "Quit");
|
||||
setMenuVisible(true);
|
||||
|
||||
settings.create(*this, "Settings");
|
||||
settingsSynchronizeVideo.create(settings, "Synchronize Video");
|
||||
settingsSynchronizeVideo.setChecked(config.video.synchronize);
|
||||
|
@ -22,11 +22,15 @@ void MainWindow::create() {
|
|||
settingsSeparator.create(settings);
|
||||
settingsVideo.create(settings, "Video Settings ...");
|
||||
settingsAdvanced.create(settings, "Advanced Settings ...");
|
||||
|
||||
tools.create(*this, "Tools");
|
||||
toolsCheatEditor.create(tools, "Cheat Editor ...");
|
||||
|
||||
help.create(*this, "Help");
|
||||
|
||||
viewport.create(*this, 0, 0, 595, 448);
|
||||
utility.setStatus("");
|
||||
setMenuVisible(true);
|
||||
setStatusVisible(true);
|
||||
|
||||
systemLoadCartridge.onTick = []() {
|
||||
|
@ -59,6 +63,10 @@ void MainWindow::create() {
|
|||
advancedSettingsWindow.setVisible();
|
||||
};
|
||||
|
||||
toolsCheatEditor.onTick = []() {
|
||||
cheatEditor.setVisible();
|
||||
};
|
||||
|
||||
onClose = []() {
|
||||
application.quit = true;
|
||||
return false;
|
||||
|
|
|
@ -11,6 +11,7 @@ struct MainWindow : Window {
|
|||
MenuItem settingsVideo;
|
||||
MenuItem settingsAdvanced;
|
||||
Menu tools;
|
||||
MenuItem toolsCheatEditor;
|
||||
Menu help;
|
||||
Viewport viewport;
|
||||
|
||||
|
|
|
@ -103,6 +103,9 @@ void Interface::input_poll() {
|
|||
}
|
||||
|
||||
int16_t Interface::input_poll(bool port, SNES::Input::Device device, unsigned index, unsigned id) {
|
||||
//ignore input when main window is not active?
|
||||
if(config.settings.focusPolicy == 1 && mainWindow.focused() == false) return 0;
|
||||
|
||||
if(port == 0) {
|
||||
if(device == SNES::Input::Device::Joypad) {
|
||||
switch(id) {
|
||||
|
|
|
@ -32,6 +32,7 @@ void Application::main(int argc, char **argv) {
|
|||
mainWindow.create();
|
||||
videoSettingsWindow.create();
|
||||
advancedSettingsWindow.create();
|
||||
cheatEditor.create();
|
||||
mainWindow.setVisible();
|
||||
while(os.pending()) os.run();
|
||||
|
||||
|
@ -76,6 +77,13 @@ void Application::main(int argc, char **argv) {
|
|||
while(os.pending()) os.run();
|
||||
|
||||
if(SNES::cartridge.loaded()) {
|
||||
//pause emulator when main window is inactive?
|
||||
if(config.settings.focusPolicy == 0) {
|
||||
if(mainWindow.focused() == false) {
|
||||
usleep(20 * 1000);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
SNES::system.run();
|
||||
} else {
|
||||
usleep(20 * 1000);
|
||||
|
|
|
@ -15,9 +15,20 @@ void AdvancedSettingsWindow::create() {
|
|||
audioDriverLabel.create(*this, x + 200, y, 45, Style::ComboBoxHeight, "Audio:");
|
||||
audioDriverBox.create (*this, x + 245, y, 150, Style::ComboBoxHeight);
|
||||
inputDriverLabel.create(*this, x + 400, y, 45, Style::ComboBoxHeight, "Input:");
|
||||
inputDriverBox.create (*this, x + 445, y, 150, Style::ComboBoxHeight); y += Style::ComboBoxHeight;
|
||||
inputDriverBox.create (*this, x + 445, y, 150, Style::ComboBoxHeight); y += Style::ComboBoxHeight + 5;
|
||||
|
||||
setGeometry(0, 0, 605, y + 5);
|
||||
focusPolicyLabel.create(*this, x, y, 595, Style::LabelHeight, "Focus Policy :."); y += Style::LabelHeight + 5;
|
||||
focusPolicyLabel.setFont(application.proportionalFontBold);
|
||||
|
||||
focusPolicyPause.create(*this, x, y, 195, Style::CheckBoxHeight, "Pause emulator when inactive");
|
||||
focusPolicyIgnore.create(focusPolicyPause, x + 200, y, 195, Style::CheckBoxHeight, "Ignore input when inactive");
|
||||
focusPolicyAllow.create(focusPolicyPause, x + 400, y, 195, Style::CheckBoxHeight, "Always allow input"); y += Style::CheckBoxHeight + 5;
|
||||
|
||||
if(config.settings.focusPolicy == 0) focusPolicyPause.setChecked();
|
||||
if(config.settings.focusPolicy == 1) focusPolicyIgnore.setChecked();
|
||||
if(config.settings.focusPolicy == 2) focusPolicyAllow.setChecked();
|
||||
|
||||
setGeometry(0, 0, 605, y);
|
||||
|
||||
lstring list;
|
||||
|
||||
|
@ -57,8 +68,7 @@ void AdvancedSettingsWindow::create() {
|
|||
config.input.driver = list[advancedSettingsWindow.inputDriverBox.selection()];
|
||||
};
|
||||
|
||||
onClose = []() {
|
||||
advancedSettingsWindow.setVisible(false);
|
||||
return false;
|
||||
};
|
||||
focusPolicyPause.onTick = []() { config.settings.focusPolicy = 0; };
|
||||
focusPolicyIgnore.onTick = []() { config.settings.focusPolicy = 1; };
|
||||
focusPolicyAllow.onTick = []() { config.settings.focusPolicy = 2; };
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ struct AdvancedSettingsWindow : Window {
|
|||
ComboBox audioDriverBox;
|
||||
Label inputDriverLabel;
|
||||
ComboBox inputDriverBox;
|
||||
Label focusPolicyLabel;
|
||||
RadioBox focusPolicyPause;
|
||||
RadioBox focusPolicyIgnore;
|
||||
RadioBox focusPolicyAllow;
|
||||
|
||||
void create();
|
||||
};
|
||||
|
|
|
@ -33,11 +33,6 @@ void VideoSettingsWindow::create() {
|
|||
|
||||
contrastSlider.onChange = brightnessSlider.onChange = gammaSlider.onChange = gammaRampCheck.onTick =
|
||||
{ &VideoSettingsWindow::adjust, this };
|
||||
|
||||
onClose = []() {
|
||||
videoSettingsWindow.setVisible(false);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
void VideoSettingsWindow::adjust() {
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
CheatEditor cheatEditor;
|
||||
|
||||
void CheatEditor::load(string filename) {
|
||||
SNES::cheat.reset();
|
||||
cheatList.reset();
|
||||
for(unsigned i = 0; i < 128; i++) {
|
||||
cheatList.addItem("");
|
||||
cheatText[i][0] = strunsigned<3, ' '>(i + 1);
|
||||
cheatText[i][1] = " ";
|
||||
cheatText[i][2] = "";
|
||||
cheatText[i][3] = "";
|
||||
}
|
||||
|
||||
string data;
|
||||
if(data.readfile(string(filename, ".bsv"))) {
|
||||
lstring list;
|
||||
list.split("\n", data);
|
||||
for(unsigned i = 0; i < 128 && i < list.size(); i++) {
|
||||
lstring part;
|
||||
part.split("{}", list[i]);
|
||||
cheatText[i][1] = part[0];
|
||||
cheatText[i][2] = part[1];
|
||||
cheatText[i][3] = part[2];
|
||||
SNES::cheat[i].enabled = (cheatText[i][1] != " ");
|
||||
SNES::cheat[i] = cheatText[i][2];
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
void CheatEditor::save(string filename) {
|
||||
bool savesPresent = false;
|
||||
for(unsigned i = 0; i < 128; i++) {
|
||||
if(cheatText[i][2] != "" || cheatText[i][3] != "") {
|
||||
savesPresent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(savesPresent == false) {
|
||||
unlink(string(filename, ".bsv"));
|
||||
return;
|
||||
}
|
||||
|
||||
file fp;
|
||||
if(fp.open(string(filename, ".bsv"), file::mode_write)) {
|
||||
for(unsigned i = 0; i < 128; i++) {
|
||||
fp.print(string(cheatText[i][1], "{}", cheatText[i][2], "{}", cheatText[i][3], "\n"));
|
||||
}
|
||||
fp.close();
|
||||
}
|
||||
|
||||
cheatList.reset();
|
||||
cheatList.resizeColumnsToContent();
|
||||
}
|
||||
|
||||
void CheatEditor::create() {
|
||||
application.windows.append(this);
|
||||
Window::create(0, 0, 256, 256, "Cheat Editor");
|
||||
setDefaultFont(application.proportionalFont);
|
||||
|
||||
unsigned x = 5, y = 5;
|
||||
|
||||
cheatList.create(*this, x, y, 500, 250, "Slot\tOn\tCode\tDescription"); y += 255;
|
||||
cheatList.setHeaderVisible();
|
||||
|
||||
codeLabel.create(*this, x, y, 80, Style::EditBoxHeight, "Code(s):");
|
||||
codeEdit.create (*this, x + 80, y, 420, Style::EditBoxHeight); y += Style::EditBoxHeight + 5;
|
||||
|
||||
descLabel.create(*this, x, y, 80, Style::EditBoxHeight, "Description:");
|
||||
descEdit.create (*this, x + 80, y, 420, Style::EditBoxHeight); y+= Style::EditBoxHeight + 5;
|
||||
|
||||
setGeometry(0, 0, 510, y);
|
||||
synchronize();
|
||||
|
||||
cheatList.onActivate = { &CheatEditor::toggle, this };
|
||||
cheatList.onChange = { &CheatEditor::synchronize, this };
|
||||
codeEdit.onChange = descEdit.onChange = { &CheatEditor::bind, this };
|
||||
}
|
||||
|
||||
void CheatEditor::synchronize() {
|
||||
if(auto position = cheatList.selection()) {
|
||||
codeEdit.setText(cheatText[position()][2]);
|
||||
descEdit.setText(cheatText[position()][3]);
|
||||
codeEdit.setEnabled(true);
|
||||
descEdit.setEnabled(true);
|
||||
} else {
|
||||
codeEdit.setText("");
|
||||
descEdit.setText("");
|
||||
codeEdit.setEnabled(false);
|
||||
descEdit.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CheatEditor::refresh() {
|
||||
SNES::cheat.synchronize();
|
||||
for(unsigned i = 0; i < 128; i++) {
|
||||
lstring list;
|
||||
list.split("+", cheatText[i][2]);
|
||||
string cheatCode = list[0];
|
||||
if(list.size() > 1) cheatCode.append("...");
|
||||
|
||||
cheatList.setItem(i, string(
|
||||
cheatText[i][0], "\t", cheatText[i][1], "\t", cheatCode, "\t", cheatText[i][3]
|
||||
));
|
||||
}
|
||||
cheatList.resizeColumnsToContent();
|
||||
}
|
||||
|
||||
void CheatEditor::toggle() {
|
||||
if(auto position = cheatList.selection()) {
|
||||
if(cheatText[position()][1] == " ") {
|
||||
cheatText[position()][1] = "X";
|
||||
SNES::cheat[position()].enabled = true;
|
||||
} else {
|
||||
cheatText[position()][1] = " ";
|
||||
SNES::cheat[position()].enabled = false;
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
void CheatEditor::bind() {
|
||||
if(auto position = cheatList.selection()) {
|
||||
cheatText[position()][2] = codeEdit.text();
|
||||
cheatText[position()][3] = descEdit.text();
|
||||
SNES::cheat[position()] = cheatText[position()][2];
|
||||
refresh();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
struct CheatEditor : Window {
|
||||
ListBox cheatList;
|
||||
Label codeLabel;
|
||||
TextBox codeEdit;
|
||||
Label descLabel;
|
||||
TextBox descEdit;
|
||||
|
||||
void load(string filename);
|
||||
void save(string filename);
|
||||
void create();
|
||||
|
||||
private:
|
||||
string cheatText[128][4];
|
||||
void synchronize();
|
||||
void refresh();
|
||||
void toggle();
|
||||
void bind();
|
||||
};
|
||||
|
||||
extern CheatEditor cheatEditor;
|
|
@ -0,0 +1,2 @@
|
|||
#include "../base.hpp"
|
||||
#include "cheat-editor.cpp"
|
|
@ -0,0 +1 @@
|
|||
#include "cheat-editor.hpp"
|
Loading…
Reference in New Issue