From 8a91c95002469962824499b6d47005eae02288c5 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Wed, 22 Sep 2010 22:53:23 +1000 Subject: [PATCH] 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. --- bsnes/Makefile | 10 +- bsnes/phoenix/gtk/editbox.cpp | 4 +- bsnes/phoenix/gtk/gtk.hpp | 3 +- bsnes/phoenix/gtk/textbox.cpp | 4 +- bsnes/phoenix/gtk/window.cpp | 12 ++- bsnes/phoenix/windows/editbox.cpp | 4 +- bsnes/phoenix/windows/label.cpp | 4 +- bsnes/phoenix/windows/listbox.cpp | 4 + bsnes/phoenix/windows/object.cpp | 2 + bsnes/phoenix/windows/textbox.cpp | 18 +++- bsnes/phoenix/windows/widget.cpp | 2 +- bsnes/phoenix/windows/windows.cpp | 10 +- bsnes/phoenix/windows/windows.hpp | 2 + bsnes/snes/snes.hpp | 2 +- bsnes/ui-phoenix/Makefile | 3 +- bsnes/ui-phoenix/base.hpp | 7 ++ bsnes/ui-phoenix/cartridge/cartridge.cpp | 2 + bsnes/ui-phoenix/config.cpp | 2 + bsnes/ui-phoenix/config.hpp | 4 + bsnes/ui-phoenix/general/main-window.cpp | 10 +- bsnes/ui-phoenix/general/main-window.hpp | 1 + bsnes/ui-phoenix/interface.cpp | 3 + bsnes/ui-phoenix/main.cpp | 8 ++ bsnes/ui-phoenix/settings/advanced.cpp | 22 ++-- bsnes/ui-phoenix/settings/advanced.hpp | 4 + bsnes/ui-phoenix/settings/video.cpp | 5 - bsnes/ui-phoenix/tools/cheat-editor.cpp | 129 +++++++++++++++++++++++ bsnes/ui-phoenix/tools/cheat-editor.hpp | 20 ++++ bsnes/ui-phoenix/tools/tools.cpp | 2 + bsnes/ui-phoenix/tools/tools.hpp | 1 + 30 files changed, 271 insertions(+), 33 deletions(-) create mode 100755 bsnes/ui-phoenix/tools/cheat-editor.cpp create mode 100755 bsnes/ui-phoenix/tools/cheat-editor.hpp create mode 100755 bsnes/ui-phoenix/tools/tools.cpp create mode 100755 bsnes/ui-phoenix/tools/tools.hpp diff --git a/bsnes/Makefile b/bsnes/Makefile index 81a01fd8..709fc739 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -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 diff --git a/bsnes/phoenix/gtk/editbox.cpp b/bsnes/phoenix/gtk/editbox.cpp index 04add4a4..d09b59a0 100755 --- a/bsnes/phoenix/gtk/editbox.cpp +++ b/bsnes/phoenix/gtk/editbox.cpp @@ -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; } diff --git a/bsnes/phoenix/gtk/gtk.hpp b/bsnes/phoenix/gtk/gtk.hpp index 58560866..3cfa3ba9 100755 --- a/bsnes/phoenix/gtk/gtk.hpp +++ b/bsnes/phoenix/gtk/gtk.hpp @@ -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 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); diff --git a/bsnes/phoenix/gtk/textbox.cpp b/bsnes/phoenix/gtk/textbox.cpp index a1e32297..f6ea00dc 100755 --- a/bsnes/phoenix/gtk/textbox.cpp +++ b/bsnes/phoenix/gtk/textbox.cpp @@ -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; } diff --git a/bsnes/phoenix/gtk/window.cpp b/bsnes/phoenix/gtk/window.cpp index 378410b0..83c140e3 100755 --- a/bsnes/phoenix/gtk/window.cpp +++ b/bsnes/phoenix/gtk/window.cpp @@ -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); diff --git a/bsnes/phoenix/windows/editbox.cpp b/bsnes/phoenix/windows/editbox.cpp index 68b9ea9d..21a2e01d 100755 --- a/bsnes/phoenix/windows/editbox.cpp +++ b/bsnes/phoenix/windows/editbox.cpp @@ -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) { diff --git a/bsnes/phoenix/windows/label.cpp b/bsnes/phoenix/windows/label.cpp index 924c57d7..eb047d80 100755 --- a/bsnes/phoenix/windows/label.cpp +++ b/bsnes/phoenix/windows/label.cpp @@ -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); diff --git a/bsnes/phoenix/windows/listbox.cpp b/bsnes/phoenix/windows/listbox.cpp index ccd29bf0..51b9d1bf 100755 --- a/bsnes/phoenix/windows/listbox.cpp +++ b/bsnes/phoenix/windows/listbox.cpp @@ -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); diff --git a/bsnes/phoenix/windows/object.cpp b/bsnes/phoenix/windows/object.cpp index 64e8ac87..d9e7002d 100755 --- a/bsnes/phoenix/windows/object.cpp +++ b/bsnes/phoenix/windows/object.cpp @@ -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; } diff --git a/bsnes/phoenix/windows/textbox.cpp b/bsnes/phoenix/windows/textbox.cpp index f4a7d63f..d815dab9 100755 --- a/bsnes/phoenix/windows/textbox.cpp +++ b/bsnes/phoenix/windows/textbox.cpp @@ -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); } diff --git a/bsnes/phoenix/windows/widget.cpp b/bsnes/phoenix/windows/widget.cpp index 439d761a..62f3cf77 100755 --- a/bsnes/phoenix/windows/widget.cpp +++ b/bsnes/phoenix/windows/widget.cpp @@ -20,7 +20,7 @@ void Widget::setEnabled(bool enabled) { } bool Widget::focused() { - return GetDesktopWindow() == widget->window; + return (GetForegroundWindow() == widget->window); } void Widget::setFocused() { diff --git a/bsnes/phoenix/windows/windows.cpp b/bsnes/phoenix/windows/windows.cpp index 8076d993..b00ecd42 100755 --- a/bsnes/phoenix/windows/windows.cpp +++ b/bsnes/phoenix/windows/windows.cpp @@ -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(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(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(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(); } } } diff --git a/bsnes/phoenix/windows/windows.hpp b/bsnes/phoenix/windows/windows.hpp index 63223e75..993eefeb 100755 --- a/bsnes/phoenix/windows/windows.hpp +++ b/bsnes/phoenix/windows/windows.hpp @@ -213,6 +213,8 @@ struct RadioBox : Widget { struct TextBox : Widget { nall::function 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); }; diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 19137623..8b9a409d 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -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; } } diff --git a/bsnes/ui-phoenix/Makefile b/bsnes/ui-phoenix/Makefile index 8fd9e41b..2154a8c1 100755 --- a/bsnes/ui-phoenix/Makefile +++ b/bsnes/ui-phoenix/Makefile @@ -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/*) diff --git a/bsnes/ui-phoenix/base.hpp b/bsnes/ui-phoenix/base.hpp index 76e69c30..ddf3912b 100755 --- a/bsnes/ui-phoenix/base.hpp +++ b/bsnes/ui-phoenix/base.hpp @@ -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 diff --git a/bsnes/ui-phoenix/cartridge/cartridge.cpp b/bsnes/ui-phoenix/cartridge/cartridge.cpp index db37ec53..48eea227 100755 --- a/bsnes/ui-phoenix/cartridge/cartridge.cpp +++ b/bsnes/ui-phoenix/cartridge/cartridge.cpp @@ -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(); diff --git a/bsnes/ui-phoenix/config.cpp b/bsnes/ui-phoenix/config.cpp index bc375a02..fc8ab1a0 100755 --- a/bsnes/ui-phoenix/config.cpp +++ b/bsnes/ui-phoenix/config.cpp @@ -21,4 +21,6 @@ void Configuration::create() { attach(audio.mute = false, "audio.mute"); attach(input.driver = "", "input.driver"); + + attach(settings.focusPolicy = 0, "settings.focusPolicy"); } diff --git a/bsnes/ui-phoenix/config.hpp b/bsnes/ui-phoenix/config.hpp index 2f74cdeb..91548130 100755 --- a/bsnes/ui-phoenix/config.hpp +++ b/bsnes/ui-phoenix/config.hpp @@ -23,6 +23,10 @@ struct Configuration : public configuration { string driver; } input; + struct Settings { + unsigned focusPolicy; + } settings; + void load(); void save(); void create(); diff --git a/bsnes/ui-phoenix/general/main-window.cpp b/bsnes/ui-phoenix/general/main-window.cpp index a2d49958..f7572c78 100755 --- a/bsnes/ui-phoenix/general/main-window.cpp +++ b/bsnes/ui-phoenix/general/main-window.cpp @@ -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; diff --git a/bsnes/ui-phoenix/general/main-window.hpp b/bsnes/ui-phoenix/general/main-window.hpp index 8f3da0d7..8ca3b99a 100755 --- a/bsnes/ui-phoenix/general/main-window.hpp +++ b/bsnes/ui-phoenix/general/main-window.hpp @@ -11,6 +11,7 @@ struct MainWindow : Window { MenuItem settingsVideo; MenuItem settingsAdvanced; Menu tools; + MenuItem toolsCheatEditor; Menu help; Viewport viewport; diff --git a/bsnes/ui-phoenix/interface.cpp b/bsnes/ui-phoenix/interface.cpp index c6951482..27ed0834 100755 --- a/bsnes/ui-phoenix/interface.cpp +++ b/bsnes/ui-phoenix/interface.cpp @@ -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) { diff --git a/bsnes/ui-phoenix/main.cpp b/bsnes/ui-phoenix/main.cpp index 1adf9717..8796734b 100755 --- a/bsnes/ui-phoenix/main.cpp +++ b/bsnes/ui-phoenix/main.cpp @@ -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); diff --git a/bsnes/ui-phoenix/settings/advanced.cpp b/bsnes/ui-phoenix/settings/advanced.cpp index 0f2c7d93..07bd5dad 100755 --- a/bsnes/ui-phoenix/settings/advanced.cpp +++ b/bsnes/ui-phoenix/settings/advanced.cpp @@ -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; }; } diff --git a/bsnes/ui-phoenix/settings/advanced.hpp b/bsnes/ui-phoenix/settings/advanced.hpp index 18052f6e..9bbc8cfa 100755 --- a/bsnes/ui-phoenix/settings/advanced.hpp +++ b/bsnes/ui-phoenix/settings/advanced.hpp @@ -6,6 +6,10 @@ struct AdvancedSettingsWindow : Window { ComboBox audioDriverBox; Label inputDriverLabel; ComboBox inputDriverBox; + Label focusPolicyLabel; + RadioBox focusPolicyPause; + RadioBox focusPolicyIgnore; + RadioBox focusPolicyAllow; void create(); }; diff --git a/bsnes/ui-phoenix/settings/video.cpp b/bsnes/ui-phoenix/settings/video.cpp index 896ba590..0b4e5764 100755 --- a/bsnes/ui-phoenix/settings/video.cpp +++ b/bsnes/ui-phoenix/settings/video.cpp @@ -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() { diff --git a/bsnes/ui-phoenix/tools/cheat-editor.cpp b/bsnes/ui-phoenix/tools/cheat-editor.cpp new file mode 100755 index 00000000..cf439ec9 --- /dev/null +++ b/bsnes/ui-phoenix/tools/cheat-editor.cpp @@ -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(); + } +} diff --git a/bsnes/ui-phoenix/tools/cheat-editor.hpp b/bsnes/ui-phoenix/tools/cheat-editor.hpp new file mode 100755 index 00000000..8e2c19dc --- /dev/null +++ b/bsnes/ui-phoenix/tools/cheat-editor.hpp @@ -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; diff --git a/bsnes/ui-phoenix/tools/tools.cpp b/bsnes/ui-phoenix/tools/tools.cpp new file mode 100755 index 00000000..5e37026e --- /dev/null +++ b/bsnes/ui-phoenix/tools/tools.cpp @@ -0,0 +1,2 @@ +#include "../base.hpp" +#include "cheat-editor.cpp" diff --git a/bsnes/ui-phoenix/tools/tools.hpp b/bsnes/ui-phoenix/tools/tools.hpp new file mode 100755 index 00000000..97db5ccf --- /dev/null +++ b/bsnes/ui-phoenix/tools/tools.hpp @@ -0,0 +1 @@ +#include "cheat-editor.hpp"