From cb97d98ad21fe9f05147d37d6ace290c067edac5 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Mon, 7 May 2012 09:27:42 +1000 Subject: [PATCH] Update to v088r14 release. byuu says: Changelog: - added NSS DIP switch settings window (when loading NSS carts with appropriate manifest.xml file) - added video shader selection (they go in ~/.config/bsnes/Video Shaders/ now) - added driver selection - added timing settings (not only allows video/audio settings, also has code to dynamically compute the values for you ... and it actually works pretty good!) - moved "None" controller device to bottom of list (it is the least likely to be used, after all) - added Interface::path() to support MSU1, USART, Link - input and hotkey mappings remember list position after assignment - and more! target-ethos now has all of the functionality of target-ui, and more. Final code size for the port is 101.2KB (ethos) vs 167.6KB (ui). A ~67% reduction in code size, yet it does even more! And you can add or remove an entire system with only three lines of code (Makefile include, header include, interface append.) The only problem left is that the BS-X BIOS won't load the BS Zelda no Densetsu file. I can't figure out why it's not working, would appreciate any assistance, but otherwise I'm probably just going to leave it broken for v089, sorry. So the show stoppers for a new release at this point are: - fix laevateinn to compile with the new interface changes (shouldn't be too hard, it'll still use the old, direct interface.) - clean up Emulator::Interface as much as possible (trim down Information, mediaRequest should use an alternate struct designed to load firmware / slots separately) - enhance purify to strip SNES ROM headers, and it really needs a GUI interface - it would be highly desirable to make a launcher that can create a cartridge folder from an existing ROM set (* ethos will need to accept command-line arguments for this.) - probably need to remember which controller was selected in each port for each system across runs - need to fix the cursor for Super Scope / Justifier games (move from 19-bit to 32-bit colors broke it) - have to refactor that cache.(hv)offset thing to fix ASP --- bsnes/emulator/emulator.hpp | 2 +- bsnes/emulator/interface.hpp | 16 + bsnes/fc/interface/interface.cpp | 8 + bsnes/fc/interface/interface.hpp | 3 + bsnes/gb/interface/interface.cpp | 8 + bsnes/gb/interface/interface.hpp | 3 + bsnes/gba/interface/interface.cpp | 8 + bsnes/gba/interface/interface.hpp | 3 + bsnes/nall/directory.hpp | 18 + bsnes/nall/file.hpp | 18 + bsnes/nall/platform.hpp | 3 - bsnes/phoenix/core/core.cpp | 12 + bsnes/phoenix/core/core.hpp | 3 + bsnes/sfc/cartridge/cartridge.cpp | 1 - bsnes/sfc/cartridge/cartridge.hpp | 8 - bsnes/sfc/cartridge/markup.cpp | 17 +- bsnes/sfc/chip/link/link.cpp | 5 +- bsnes/sfc/chip/msu1/msu1.cpp | 4 +- bsnes/sfc/chip/msu1/serialization.cpp | 4 +- bsnes/sfc/chip/nss/nss.cpp | 2 +- bsnes/sfc/chip/nss/nss.hpp | 8 +- bsnes/sfc/controller/usart/usart.cpp | 2 +- bsnes/sfc/interface/interface.cpp | 35 +- bsnes/sfc/interface/interface.hpp | 4 +- bsnes/sfc/system/input.hpp | 2 +- bsnes/sfc/system/system.cpp | 18 +- bsnes/target-ethos/bootstrap.cpp | 2 + .../configuration/configuration.cpp | 7 +- .../configuration/configuration.hpp | 9 + bsnes/target-ethos/ethos.cpp | 23 +- bsnes/target-ethos/general/dip-switches.cpp | 68 +++ .../general/dip-switches.hpp | 18 +- bsnes/target-ethos/general/general.cpp | 1 + bsnes/target-ethos/general/general.hpp | 1 + bsnes/target-ethos/general/presentation.cpp | 43 +- bsnes/target-ethos/general/presentation.hpp | 5 + bsnes/target-ethos/interface/interface.cpp | 8 + bsnes/target-ethos/interface/interface.hpp | 2 + bsnes/target-ethos/settings/driver.cpp | 42 ++ bsnes/target-ethos/settings/driver.hpp | 14 + bsnes/target-ethos/settings/hotkey.cpp | 5 +- bsnes/target-ethos/settings/input.cpp | 12 +- bsnes/target-ethos/settings/input.hpp | 1 + bsnes/target-ethos/settings/settings.cpp | 11 + bsnes/target-ethos/settings/settings.hpp | 2 + bsnes/target-ethos/settings/timing.cpp | 130 +++++ bsnes/target-ethos/settings/timing.hpp | 36 ++ bsnes/target-ethos/tools/cheat-editor.cpp | 2 +- bsnes/target-ethos/tools/state-manager.cpp | 2 +- bsnes/target-ethos/utility/utility.cpp | 41 +- bsnes/target-ethos/utility/utility.hpp | 2 + .../Makefile | 0 .../base.hpp | 0 .../breakpoint/breakpoint.cpp | 0 .../breakpoint/breakpoint.hpp | 0 .../console/about.cpp | 0 .../console/console.cpp | 0 .../console/console.hpp | 0 .../cpu/cpu.cpp | 0 .../cpu/cpu.hpp | 0 .../cpu/registers.cpp | 0 .../debugger/debugger.cpp | 0 .../debugger/debugger.hpp | 0 .../debugger/hook.cpp | 0 .../debugger/usage.cpp | 0 .../interface/interface.cpp | 0 .../interface/interface.hpp | 0 .../main.cpp | 0 .../memory/memory.cpp | 0 .../memory/memory.hpp | 0 .../properties/properties.cpp | 0 .../properties/properties.hpp | 0 .../resource.rc | 0 .../settings/settings.cpp | 0 .../settings/settings.hpp | 0 .../smp/registers.cpp | 0 .../smp/smp.cpp | 0 .../smp/smp.hpp | 0 .../tracer/tracer.cpp | 0 .../tracer/tracer.hpp | 0 .../video/video.cpp | 0 .../video/video.hpp | 0 .../vram/vram.cpp | 0 .../vram/vram.hpp | 0 .../window/window.cpp | 0 .../window/window.hpp | 0 bsnes/target-ui/Makefile | 91 ---- bsnes/target-ui/base.hpp | 66 --- bsnes/target-ui/config/config.cpp | 52 -- bsnes/target-ui/config/config.hpp | 59 --- bsnes/target-ui/general/dip-switches.cpp | 69 --- bsnes/target-ui/general/file-browser.cpp | 141 ------ bsnes/target-ui/general/file-browser.hpp | 37 -- bsnes/target-ui/general/general.cpp | 5 - bsnes/target-ui/general/general.hpp | 4 - .../target-ui/general/information-window.cpp | 43 -- .../target-ui/general/information-window.hpp | 11 - bsnes/target-ui/general/main-window.cpp | 446 ------------------ bsnes/target-ui/general/main-window.hpp | 99 ---- bsnes/target-ui/input/gb.cpp | 53 --- bsnes/target-ui/input/gb.hpp | 20 - bsnes/target-ui/input/gba.cpp | 64 --- bsnes/target-ui/input/gba.hpp | 21 - bsnes/target-ui/input/input.cpp | 217 --------- bsnes/target-ui/input/input.hpp | 75 --- bsnes/target-ui/input/nes.cpp | 60 --- bsnes/target-ui/input/nes.hpp | 27 -- bsnes/target-ui/input/snes.cpp | 184 -------- bsnes/target-ui/input/snes.hpp | 66 --- bsnes/target-ui/input/user-interface.cpp | 116 ----- bsnes/target-ui/input/user-interface.hpp | 33 -- bsnes/target-ui/interface/core.cpp | 61 --- bsnes/target-ui/interface/gb/gb.cpp | 121 ----- bsnes/target-ui/interface/gb/gb.hpp | 23 - bsnes/target-ui/interface/gba/gba.cpp | 104 ---- bsnes/target-ui/interface/gba/gba.hpp | 23 - bsnes/target-ui/interface/interface.cpp | 284 ----------- bsnes/target-ui/interface/interface.hpp | 91 ---- bsnes/target-ui/interface/nes/nes.cpp | 136 ------ bsnes/target-ui/interface/nes/nes.hpp | 25 - bsnes/target-ui/interface/snes/snes.cpp | 390 --------------- bsnes/target-ui/interface/snes/snes.hpp | 37 -- bsnes/target-ui/main.cpp | 153 ------ bsnes/target-ui/resource.rc | 2 - bsnes/target-ui/settings/advanced.cpp | 78 --- bsnes/target-ui/settings/advanced.hpp | 18 - bsnes/target-ui/settings/audio.cpp | 160 ------- bsnes/target-ui/settings/audio.hpp | 35 -- bsnes/target-ui/settings/input.cpp | 151 ------ bsnes/target-ui/settings/input.hpp | 30 -- bsnes/target-ui/settings/settings.cpp | 67 --- bsnes/target-ui/settings/settings.hpp | 24 - bsnes/target-ui/settings/video.cpp | 107 ----- bsnes/target-ui/settings/video.hpp | 29 -- bsnes/target-ui/tools/cheat-database.cpp | 81 ---- bsnes/target-ui/tools/cheat-database.hpp | 18 - bsnes/target-ui/tools/cheat-editor.cpp | 188 -------- bsnes/target-ui/tools/cheat-editor.hpp | 36 -- bsnes/target-ui/tools/state-manager.cpp | 155 ------ bsnes/target-ui/tools/state-manager.hpp | 39 -- bsnes/target-ui/tools/tools.cpp | 4 - bsnes/target-ui/tools/tools.hpp | 3 - bsnes/target-ui/utility/utility.cpp | 181 ------- bsnes/target-ui/utility/utility.hpp | 20 - bsnes/target-ui/window/window.cpp | 53 --- bsnes/target-ui/window/window.hpp | 22 - 146 files changed, 604 insertions(+), 5106 deletions(-) create mode 100755 bsnes/target-ethos/general/dip-switches.cpp rename bsnes/{target-ui => target-ethos}/general/dip-switches.hpp (58%) create mode 100755 bsnes/target-ethos/settings/driver.cpp create mode 100755 bsnes/target-ethos/settings/driver.hpp create mode 100755 bsnes/target-ethos/settings/timing.cpp create mode 100755 bsnes/target-ethos/settings/timing.hpp rename bsnes/{target-debugger => target-laevateinn}/Makefile (100%) rename bsnes/{target-debugger => target-laevateinn}/base.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/breakpoint/breakpoint.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/breakpoint/breakpoint.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/console/about.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/console/console.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/console/console.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/cpu/cpu.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/cpu/cpu.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/cpu/registers.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/debugger/debugger.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/debugger/debugger.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/debugger/hook.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/debugger/usage.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/interface/interface.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/interface/interface.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/main.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/memory/memory.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/memory/memory.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/properties/properties.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/properties/properties.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/resource.rc (100%) rename bsnes/{target-debugger => target-laevateinn}/settings/settings.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/settings/settings.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/smp/registers.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/smp/smp.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/smp/smp.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/tracer/tracer.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/tracer/tracer.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/video/video.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/video/video.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/vram/vram.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/vram/vram.hpp (100%) rename bsnes/{target-debugger => target-laevateinn}/window/window.cpp (100%) rename bsnes/{target-debugger => target-laevateinn}/window/window.hpp (100%) delete mode 100755 bsnes/target-ui/Makefile delete mode 100755 bsnes/target-ui/base.hpp delete mode 100755 bsnes/target-ui/config/config.cpp delete mode 100755 bsnes/target-ui/config/config.hpp delete mode 100755 bsnes/target-ui/general/dip-switches.cpp delete mode 100755 bsnes/target-ui/general/file-browser.cpp delete mode 100755 bsnes/target-ui/general/file-browser.hpp delete mode 100755 bsnes/target-ui/general/general.cpp delete mode 100755 bsnes/target-ui/general/general.hpp delete mode 100755 bsnes/target-ui/general/information-window.cpp delete mode 100755 bsnes/target-ui/general/information-window.hpp delete mode 100755 bsnes/target-ui/general/main-window.cpp delete mode 100755 bsnes/target-ui/general/main-window.hpp delete mode 100755 bsnes/target-ui/input/gb.cpp delete mode 100755 bsnes/target-ui/input/gb.hpp delete mode 100755 bsnes/target-ui/input/gba.cpp delete mode 100755 bsnes/target-ui/input/gba.hpp delete mode 100755 bsnes/target-ui/input/input.cpp delete mode 100755 bsnes/target-ui/input/input.hpp delete mode 100755 bsnes/target-ui/input/nes.cpp delete mode 100755 bsnes/target-ui/input/nes.hpp delete mode 100755 bsnes/target-ui/input/snes.cpp delete mode 100755 bsnes/target-ui/input/snes.hpp delete mode 100755 bsnes/target-ui/input/user-interface.cpp delete mode 100755 bsnes/target-ui/input/user-interface.hpp delete mode 100755 bsnes/target-ui/interface/core.cpp delete mode 100755 bsnes/target-ui/interface/gb/gb.cpp delete mode 100755 bsnes/target-ui/interface/gb/gb.hpp delete mode 100755 bsnes/target-ui/interface/gba/gba.cpp delete mode 100755 bsnes/target-ui/interface/gba/gba.hpp delete mode 100755 bsnes/target-ui/interface/interface.cpp delete mode 100755 bsnes/target-ui/interface/interface.hpp delete mode 100755 bsnes/target-ui/interface/nes/nes.cpp delete mode 100755 bsnes/target-ui/interface/nes/nes.hpp delete mode 100755 bsnes/target-ui/interface/snes/snes.cpp delete mode 100755 bsnes/target-ui/interface/snes/snes.hpp delete mode 100755 bsnes/target-ui/main.cpp delete mode 100755 bsnes/target-ui/resource.rc delete mode 100755 bsnes/target-ui/settings/advanced.cpp delete mode 100755 bsnes/target-ui/settings/advanced.hpp delete mode 100755 bsnes/target-ui/settings/audio.cpp delete mode 100755 bsnes/target-ui/settings/audio.hpp delete mode 100755 bsnes/target-ui/settings/input.cpp delete mode 100755 bsnes/target-ui/settings/input.hpp delete mode 100755 bsnes/target-ui/settings/settings.cpp delete mode 100755 bsnes/target-ui/settings/settings.hpp delete mode 100755 bsnes/target-ui/settings/video.cpp delete mode 100755 bsnes/target-ui/settings/video.hpp delete mode 100755 bsnes/target-ui/tools/cheat-database.cpp delete mode 100755 bsnes/target-ui/tools/cheat-database.hpp delete mode 100755 bsnes/target-ui/tools/cheat-editor.cpp delete mode 100755 bsnes/target-ui/tools/cheat-editor.hpp delete mode 100755 bsnes/target-ui/tools/state-manager.cpp delete mode 100755 bsnes/target-ui/tools/state-manager.hpp delete mode 100755 bsnes/target-ui/tools/tools.cpp delete mode 100755 bsnes/target-ui/tools/tools.hpp delete mode 100755 bsnes/target-ui/utility/utility.cpp delete mode 100755 bsnes/target-ui/utility/utility.hpp delete mode 100755 bsnes/target-ui/window/window.cpp delete mode 100755 bsnes/target-ui/window/window.hpp diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index e6f9b57e..06c4a7dd 100755 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -3,7 +3,7 @@ namespace Emulator { static const char Name[] = "bsnes"; - static const char Version[] = "088.13"; + static const char Version[] = "088.14"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; } diff --git a/bsnes/emulator/interface.hpp b/bsnes/emulator/interface.hpp index 0e8c1e98..b571361c 100755 --- a/bsnes/emulator/interface.hpp +++ b/bsnes/emulator/interface.hpp @@ -59,6 +59,8 @@ struct Interface { function audioSample; function inputPoll; function mediaRequest; + function dipSettings; + function path; } callback; //callback bindings (provided by user interface) @@ -84,6 +86,20 @@ struct Interface { if(callback.mediaRequest) return callback.mediaRequest(media); } + virtual unsigned dipSettings(const XML::Node &node) { + if(callback.dipSettings) return callback.dipSettings(node); + return 0u; + } + + virtual string path(unsigned group) { + if(callback.path) return callback.path(group); + return ""; + } + + //information + virtual double videoFrequency() = 0; + virtual double audioFrequency() = 0; + //media interface virtual bool loaded() { return false; } virtual string sha256() { return ""; } diff --git a/bsnes/fc/interface/interface.cpp b/bsnes/fc/interface/interface.cpp index a1b333ec..ef4632ad 100755 --- a/bsnes/fc/interface/interface.cpp +++ b/bsnes/fc/interface/interface.cpp @@ -4,6 +4,14 @@ namespace Famicom { Interface *interface = nullptr; +double Interface::videoFrequency() { + return 21477272.0 / (262.0 * 1364.0 - 4.0); +} + +double Interface::audioFrequency() { + return 21477272.0 / 12.0; +} + bool Interface::loaded() { return cartridge.loaded(); } diff --git a/bsnes/fc/interface/interface.hpp b/bsnes/fc/interface/interface.hpp index d167cc1a..81dc5f30 100755 --- a/bsnes/fc/interface/interface.hpp +++ b/bsnes/fc/interface/interface.hpp @@ -15,6 +15,9 @@ struct ID { }; struct Interface : Emulator::Interface { + double videoFrequency(); + double audioFrequency(); + bool loaded(); string sha256(); void load(unsigned id, const stream &stream, const string &markup = ""); diff --git a/bsnes/gb/interface/interface.cpp b/bsnes/gb/interface/interface.cpp index 6e93f56c..f75a5285 100755 --- a/bsnes/gb/interface/interface.cpp +++ b/bsnes/gb/interface/interface.cpp @@ -4,6 +4,14 @@ namespace GameBoy { Interface *interface = nullptr; +double Interface::videoFrequency() { + return 4194304.0 / (154.0 * 456.0); +} + +double Interface::audioFrequency() { + return 4194304.0; +} + bool Interface::loaded() { return cartridge.loaded(); } diff --git a/bsnes/gb/interface/interface.hpp b/bsnes/gb/interface/interface.hpp index b41e8209..453774f4 100755 --- a/bsnes/gb/interface/interface.hpp +++ b/bsnes/gb/interface/interface.hpp @@ -22,6 +22,9 @@ struct Interface : Emulator::Interface { virtual void lcdScanline() {} virtual void joypWrite(bool p15, bool p14) {} + double videoFrequency(); + double audioFrequency(); + bool loaded(); string sha256(); void load(unsigned id, const stream &stream, const string &markup = ""); diff --git a/bsnes/gba/interface/interface.cpp b/bsnes/gba/interface/interface.cpp index b5dee7c4..342f5918 100755 --- a/bsnes/gba/interface/interface.cpp +++ b/bsnes/gba/interface/interface.cpp @@ -4,6 +4,14 @@ namespace GameBoyAdvance { Interface *interface = nullptr; +double Interface::videoFrequency() { + return 16777216.0 / (228.0 * 1232.0); +} + +double Interface::audioFrequency() { + return 16777216.0 / 512.0; +} + bool Interface::loaded() { return cartridge.loaded(); } diff --git a/bsnes/gba/interface/interface.hpp b/bsnes/gba/interface/interface.hpp index 8f58fa21..22e3fed0 100755 --- a/bsnes/gba/interface/interface.hpp +++ b/bsnes/gba/interface/interface.hpp @@ -17,6 +17,9 @@ struct ID { }; struct Interface : Emulator::Interface { + double videoFrequency(); + double audioFrequency(); + bool loaded(); void load(unsigned id, const stream &stream, const string &markup = ""); void save(unsigned id, const stream &stream); diff --git a/bsnes/nall/directory.hpp b/bsnes/nall/directory.hpp index ff439803..5d832e43 100755 --- a/bsnes/nall/directory.hpp +++ b/bsnes/nall/directory.hpp @@ -17,6 +17,8 @@ namespace nall { struct directory { + static bool create(const string &pathname, unsigned permissions = 0755); + static bool remove(const string &pathname); static bool exists(const string &pathname); static lstring folders(const string &pathname, const string &pattern = "*"); static lstring files(const string &pathname, const string &pattern = "*"); @@ -24,6 +26,14 @@ struct directory { }; #if defined(PLATFORM_WINDOWS) + inline bool directory::create(const string &pathname, unsigned permissions) { + return _wmkdir(utf16_t(pathname)) == 0; + } + + inline bool directory::remove(const string &pathname) { + return _wrmdir(utf16_t(pathname)) == 0; + } + inline bool directory::exists(const string &pathname) { DWORD result = GetFileAttributes(utf16_t(pathname)); if(result == INVALID_FILE_ATTRIBUTES) return false; @@ -94,6 +104,14 @@ struct directory { return folders; } #else + inline bool directory::create(const string &pathname, unsigned permissions) { + return mkdir(pathname, permissions) == 0; + } + + inline bool directory::remove(const string &pathname) { + return rmdir(pathname) == 0; + } + inline bool directory::exists(const string &pathname) { DIR *dp = opendir(pathname); if(!dp) return false; diff --git a/bsnes/nall/file.hpp b/bsnes/nall/file.hpp index 830c5a1a..9a38c176 100755 --- a/bsnes/nall/file.hpp +++ b/bsnes/nall/file.hpp @@ -22,6 +22,24 @@ namespace nall { enum class index : unsigned { absolute, relative }; enum class time : unsigned { create, modify, access }; + static bool remove(const string &filename) { + return unlink(filename) == 0; + } + + static bool truncate(const string &filename, unsigned size) { + #if !defined(_WIN32) + return truncate(filename, size) == 0; + #else + bool result = false; + FILE *fp = fopen(filename, "rb+"); + if(fp) { + result = _chsize(fileno(fp), size) == 0; + fclose(fp); + } + return result; + #endif + } + static vector read(const string &filename) { vector memory; file fp; diff --git a/bsnes/nall/platform.hpp b/bsnes/nall/platform.hpp index e775ab8f..e1a8f5d6 100755 --- a/bsnes/nall/platform.hpp +++ b/bsnes/nall/platform.hpp @@ -60,10 +60,7 @@ #if defined(_WIN32) #define getcwd _getcwd - #define ftruncate _chsize - #define mkdir(n, m) _wmkdir(nall::utf16_t(n)) #define putenv _putenv - #define rmdir _rmdir #define vsnprintf _vsnprintf inline void usleep(unsigned milliseconds) { Sleep(milliseconds / 1000); } #endif diff --git a/bsnes/phoenix/core/core.cpp b/bsnes/phoenix/core/core.cpp index d7aa15e9..277c5728 100755 --- a/bsnes/phoenix/core/core.cpp +++ b/bsnes/phoenix/core/core.cpp @@ -562,6 +562,10 @@ void RadioItem::setText(const string &text) { return p.setText(text); } +string RadioItem::text() { + return state.text; +} + RadioItem::RadioItem(): state(*new State), base_from_member(*new pRadioItem(*this)), @@ -850,6 +854,14 @@ void ComboBox::setSelection(unsigned row) { return p.setSelection(row); } +string ComboBox::text() { + return state.text(selection()); +} + +string ComboBox::text(unsigned row) { + return state.text(row); +} + ComboBox::ComboBox(): state(*new State), base_from_member(*new pComboBox(*this)), diff --git a/bsnes/phoenix/core/core.hpp b/bsnes/phoenix/core/core.hpp index d8494342..d4172fee 100755 --- a/bsnes/phoenix/core/core.hpp +++ b/bsnes/phoenix/core/core.hpp @@ -289,6 +289,7 @@ struct RadioItem : private nall::base_from_member, Action { bool checked(); void setChecked(); void setText(const nall::string &text); + nall::string text(); RadioItem(); ~RadioItem(); @@ -403,6 +404,8 @@ struct ComboBox : private nall::base_from_member, Widget { void reset(); unsigned selection(); void setSelection(unsigned row); + nall::string text(); + nall::string text(unsigned row); ComboBox(); ~ComboBox(); diff --git a/bsnes/sfc/cartridge/cartridge.cpp b/bsnes/sfc/cartridge/cartridge.cpp index afa8a9ba..d7a30fe5 100755 --- a/bsnes/sfc/cartridge/cartridge.cpp +++ b/bsnes/sfc/cartridge/cartridge.cpp @@ -9,7 +9,6 @@ namespace SuperFamicom { Cartridge cartridge; void Cartridge::load(const string &markup, const stream &stream) { - information.markup = markup; rom.copy(stream); region = Region::NTSC; diff --git a/bsnes/sfc/cartridge/cartridge.hpp b/bsnes/sfc/cartridge/cartridge.hpp index 0ae79020..d1f11cd6 100755 --- a/bsnes/sfc/cartridge/cartridge.hpp +++ b/bsnes/sfc/cartridge/cartridge.hpp @@ -68,14 +68,6 @@ struct Cartridge : property { }; linear_vector mapping; - struct Information { - string markup; - struct NSS { - lstring setting; - lstring option[16]; - } nss; - } information; - void load(const string &markup, const stream &stream); void unload(); diff --git a/bsnes/sfc/cartridge/markup.cpp b/bsnes/sfc/cartridge/markup.cpp index 9a887541..8c5e2452 100755 --- a/bsnes/sfc/cartridge/markup.cpp +++ b/bsnes/sfc/cartridge/markup.cpp @@ -2,7 +2,6 @@ void Cartridge::parse_markup(const char *markup) { mapping.reset(); - information.nss.setting.reset(); XML::Document document(markup); auto &cartridge = document["cartridge"]; @@ -89,20 +88,8 @@ void Cartridge::parse_markup_ram(XML::Node &root) { void Cartridge::parse_markup_nss(XML::Node &root) { if(root.exists() == false) return; has_nss_dip = true; - for(auto &node : root) { - if(node.name != "setting") continue; - unsigned number = information.nss.setting.size(); - if(number >= 16) break; //more than 16 DIP switches is not physically possible - information.nss.option[number].reset(); - information.nss.setting.append(node["name"].data); - for(auto &leaf : node) { - if(leaf.name != "option") continue; - string name = leaf["name"].data; - unsigned value = numeral(leaf["value"].data); - information.nss.option[number].append({ hex<4>(value), ":", name }); - } - } + nss.dip = interface->dipSettings(root); } void Cartridge::parse_markup_icd2(XML::Node &root) { @@ -467,7 +454,7 @@ void Cartridge::parse_markup_obc1(XML::Node &root) { void Cartridge::parse_markup_msu1(XML::Node &root) { if(root.exists() == false) { - has_msu1 = file::exists(interface->path((unsigned)Cartridge::Slot::Base, "msu1.rom")); + has_msu1 = file::exists({interface->path(0), "msu1.rom"}); if(has_msu1) { Mapping m({ &MSU1::mmio_read, &msu1 }, { &MSU1::mmio_write, &msu1 }); m.banklo = 0x00, m.bankhi = 0x3f, m.addrlo = 0x2000, m.addrhi = 0x2007; diff --git a/bsnes/sfc/chip/link/link.cpp b/bsnes/sfc/chip/link/link.cpp index a14d947c..6e89c581 100755 --- a/bsnes/sfc/chip/link/link.cpp +++ b/bsnes/sfc/chip/link/link.cpp @@ -22,10 +22,7 @@ void Link::init() { void Link::load() { if(opened()) close(); - string basename = interface->path((unsigned)Cartridge::Slot::Base, ""); - string name = program != "" ? program : notdir(basename); - string path = dir(basename); - if(open(name, path)) { + if(open("link.so", interface->path(0))) { link_power = sym("link_power"); link_reset = sym("link_reset"); link_run = sym("link_run" ); diff --git a/bsnes/sfc/chip/msu1/msu1.cpp b/bsnes/sfc/chip/msu1/msu1.cpp index 76b61544..0c0b4616 100755 --- a/bsnes/sfc/chip/msu1/msu1.cpp +++ b/bsnes/sfc/chip/msu1/msu1.cpp @@ -52,7 +52,7 @@ void MSU1::init() { void MSU1::load() { if(datafile.open()) datafile.close(); - datafile.open(interface->path((unsigned)Cartridge::Slot::Base, "msu1.rom"), file::mode::read); + datafile.open({interface->path(0), "msu1.rom"}, file::mode::read); } void MSU1::unload() { @@ -112,7 +112,7 @@ void MSU1::mmio_write(unsigned addr, uint8 data) { case 4: mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0); case 5: mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8); if(audiofile.open()) audiofile.close(); - if(audiofile.open(interface->path((unsigned)Cartridge::Slot::Base, { "track-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) { + if(audiofile.open({interface->path(0), "track-", mmio.audio_track, ".pcm"}, file::mode::read)) { uint32 header = audiofile.readm(4); if(header != 0x4d535531) { //verify 'MSU1' header audiofile.close(); diff --git a/bsnes/sfc/chip/msu1/serialization.cpp b/bsnes/sfc/chip/msu1/serialization.cpp index 35a970b3..531651a4 100755 --- a/bsnes/sfc/chip/msu1/serialization.cpp +++ b/bsnes/sfc/chip/msu1/serialization.cpp @@ -16,12 +16,12 @@ void MSU1::serialize(serializer &s) { s.integer(mmio.audio_play); if(datafile.open()) datafile.close(); - if(datafile.open(interface->path((unsigned)Cartridge::Slot::Base, "msu1.rom"), file::mode::read)) { + if(datafile.open({interface->path(0), "msu1.rom"}, file::mode::read)) { datafile.seek(mmio.data_offset); } if(audiofile.open()) audiofile.close(); - if(audiofile.open(interface->path((unsigned)Cartridge::Slot::Base, { "track-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) { + if(audiofile.open({interface->path(0), "track-", mmio.audio_track, ".pcm"}, file::mode::read)) { audiofile.seek(mmio.audio_offset); } } diff --git a/bsnes/sfc/chip/nss/nss.cpp b/bsnes/sfc/chip/nss/nss.cpp index c4866732..8c935fcf 100755 --- a/bsnes/sfc/chip/nss/nss.cpp +++ b/bsnes/sfc/chip/nss/nss.cpp @@ -6,10 +6,10 @@ namespace SuperFamicom { NSS nss; void NSS::init() { + dip = 0x0000; } void NSS::load() { - dip = 0x0000; bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4100, 0x4101, { &NSS::read, this }, { &NSS::write, this }); bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4100, 0x4101, { &NSS::read, this }, { &NSS::write, this }); } diff --git a/bsnes/sfc/chip/nss/nss.hpp b/bsnes/sfc/chip/nss/nss.hpp index 3cab46da..52cc5d98 100755 --- a/bsnes/sfc/chip/nss/nss.hpp +++ b/bsnes/sfc/chip/nss/nss.hpp @@ -1,5 +1,6 @@ -class NSS { -public: +struct NSS { + uint16 dip; + void init(); void load(); void unload(); @@ -9,9 +10,6 @@ public: void set_dip(uint16 dip); uint8 read(unsigned addr); void write(unsigned addr, uint8 data); - -private: - uint16 dip; }; extern NSS nss; diff --git a/bsnes/sfc/controller/usart/usart.cpp b/bsnes/sfc/controller/usart/usart.cpp index dc0b8eba..6a9c03c9 100755 --- a/bsnes/sfc/controller/usart/usart.cpp +++ b/bsnes/sfc/controller/usart/usart.cpp @@ -122,7 +122,7 @@ USART::USART(bool port) : Controller(port) { txlength = 0; txdata = 0; - string filename = interface->path((unsigned)Cartridge::Slot::Base, "usart.so"); + string filename = {interface->path(0), "usart.so"}; if(open_absolute(filename)) { init = sym("usart_init"); main = sym("usart_main"); diff --git a/bsnes/sfc/interface/interface.cpp b/bsnes/sfc/interface/interface.cpp index 7c50021e..371ed425 100755 --- a/bsnes/sfc/interface/interface.cpp +++ b/bsnes/sfc/interface/interface.cpp @@ -4,6 +4,17 @@ namespace SuperFamicom { Interface *interface = nullptr; +double Interface::videoFrequency() { + switch(system.region()) { default: + case System::Region::NTSC: return system.cpu_frequency() / (262.0 * 1364.0 - 4.0); + case System::Region::PAL: return system.cpu_frequency() / (312.0 * 1364.0); + } +} + +double Interface::audioFrequency() { + return system.apu_frequency() / 768.0; +} + bool Interface::loaded() { return cartridge.loaded(); } @@ -236,12 +247,7 @@ Interface::Interface() { media.append({ID::ROM, "Sufami Turbo", "sfc", "program.rom", "st" }); { - Device device{0, ID::Port1 | ID::Port2, "None"}; - this->device.append(device); - } - - { - Device device{1, ID::Port1 | ID::Port2, "Controller"}; + Device device{0, ID::Port1 | ID::Port2, "Controller"}; device.input.append({ 0, 0, "B" }); device.input.append({ 1, 0, "Y" }); device.input.append({ 2, 0, "Select"}); @@ -259,7 +265,7 @@ Interface::Interface() { } { - Device device{2, ID::Port1 | ID::Port2, "Multitap"}; + Device device{1, ID::Port1 | ID::Port2, "Multitap"}; for(unsigned p = 1, n = 0; p <= 4; p++, n += 12) { device.input.append({n + 0, 0, {"Port ", p, " - ", "B" }}); device.input.append({n + 1, 0, {"Port ", p, " - ", "Y" }}); @@ -280,7 +286,7 @@ Interface::Interface() { } { - Device device{3, ID::Port1 | ID::Port2, "Mouse"}; + Device device{2, ID::Port1 | ID::Port2, "Mouse"}; device.input.append({0, 1, "X-axis"}); device.input.append({1, 1, "Y-axis"}); device.input.append({2, 0, "Left" }); @@ -290,7 +296,7 @@ Interface::Interface() { } { - Device device{4, ID::Port2, "Super Scope"}; + Device device{3, ID::Port2, "Super Scope"}; device.input.append({0, 1, "X-axis" }); device.input.append({1, 1, "Y-axis" }); device.input.append({2, 0, "Trigger"}); @@ -302,7 +308,7 @@ Interface::Interface() { } { - Device device{5, ID::Port2, "Justifier"}; + Device device{4, ID::Port2, "Justifier"}; device.input.append({0, 1, "X-axis" }); device.input.append({1, 1, "Y-axis" }); device.input.append({2, 0, "Trigger"}); @@ -312,7 +318,7 @@ Interface::Interface() { } { - Device device{6, ID::Port2, "Justifiers"}; + Device device{5, ID::Port2, "Justifiers"}; device.input.append({0, 1, "Port 1 - X-axis" }); device.input.append({1, 1, "Port 1 - Y-axis" }); device.input.append({2, 0, "Port 1 - Trigger"}); @@ -327,7 +333,12 @@ Interface::Interface() { } { - Device device{7, ID::Port1, "Serial USART"}; + Device device{6, ID::Port1, "Serial USART"}; + this->device.append(device); + } + + { + Device device{7, ID::Port1 | ID::Port2, "None"}; this->device.append(device); } diff --git a/bsnes/sfc/interface/interface.hpp b/bsnes/sfc/interface/interface.hpp index 3daeb99f..9d2715d1 100755 --- a/bsnes/sfc/interface/interface.hpp +++ b/bsnes/sfc/interface/interface.hpp @@ -33,8 +33,8 @@ struct ID { }; struct Interface : Emulator::Interface { - virtual string path(unsigned slot, const string &hint) { return ""; } - virtual void message(const string &text) {} + double videoFrequency(); + double audioFrequency(); bool loaded(); string sha256(); diff --git a/bsnes/sfc/system/input.hpp b/bsnes/sfc/system/input.hpp index 7a6bd9e7..1c28e433 100755 --- a/bsnes/sfc/system/input.hpp +++ b/bsnes/sfc/system/input.hpp @@ -1,6 +1,5 @@ struct Input { enum class Device : unsigned { - None, Joypad, Multitap, Mouse, @@ -8,6 +7,7 @@ struct Input { Justifier, Justifiers, USART, + None, }; enum class JoypadID : unsigned { diff --git a/bsnes/sfc/system/system.cpp b/bsnes/sfc/system/system.cpp index 2c9f814a..9103c39d 100755 --- a/bsnes/sfc/system/system.cpp +++ b/bsnes/sfc/system/system.cpp @@ -94,6 +94,15 @@ void System::term() { } void System::load() { + region = config.region; + expansion = config.expansion_port; + if(region == Region::Autodetect) { + region = (cartridge.region() == Cartridge::Region::NTSC ? Region::NTSC : Region::PAL); + } + + cpu_frequency = region() == Region::NTSC ? config.cpu.ntsc_frequency : config.cpu.pal_frequency; + apu_frequency = region() == Region::NTSC ? config.smp.ntsc_frequency : config.smp.pal_frequency; + audio.coprocessor_enable(false); bus.map_reset(); @@ -151,15 +160,6 @@ void System::unload() { void System::power() { random.seed((unsigned)time(0)); - region = config.region; - expansion = config.expansion_port; - if(region == Region::Autodetect) { - region = (cartridge.region() == Cartridge::Region::NTSC ? Region::NTSC : Region::PAL); - } - - cpu_frequency = region() == Region::NTSC ? config.cpu.ntsc_frequency : config.cpu.pal_frequency; - apu_frequency = region() == Region::NTSC ? config.smp.ntsc_frequency : config.smp.pal_frequency; - cpu.power(); smp.power(); dsp.power(); diff --git a/bsnes/target-ethos/bootstrap.cpp b/bsnes/target-ethos/bootstrap.cpp index 143bef4e..74929e78 100755 --- a/bsnes/target-ethos/bootstrap.cpp +++ b/bsnes/target-ethos/bootstrap.cpp @@ -17,6 +17,8 @@ void Application::bootstrap() { system->callback.audioSample = {&Interface::audioSample, interface}; system->callback.inputPoll = {&Interface::inputPoll, interface}; system->callback.mediaRequest = {&Interface::mediaRequest, interface}; + system->callback.dipSettings = {&Interface::dipSettings, interface}; + system->callback.path = {&Interface::path, interface}; for(auto &firmware : system->firmware) { filestream fs{application->path({firmware.name, ".", firmware.type, "/", firmware.path})}; diff --git a/bsnes/target-ethos/configuration/configuration.cpp b/bsnes/target-ethos/configuration/configuration.cpp index c05b3dfa..151ec56e 100755 --- a/bsnes/target-ethos/configuration/configuration.cpp +++ b/bsnes/target-ethos/configuration/configuration.cpp @@ -2,7 +2,9 @@ Configuration *config = nullptr; Configuration::Configuration() { + append(video.driver = ruby::video.default_driver(), "Video::Driver"); append(video.synchronize = false, "Video::Synchronize"); + append(video.shader = "Blur", "Video::Shader"); append(video.scaleMode = 0, "Video::ScaleMode"); append(video.aspectCorrection = true, "Video::AspectCorrection"); append(video.maskOverscan = false, "Video::MaskOverscan"); @@ -11,15 +13,18 @@ Configuration::Configuration() { append(video.saturation = 100, "Video::Saturation"); append(video.gamma = 150, "Video::Gamma"); append(video.luminance = 100, "Video::Luminance"); + append(audio.driver = ruby::audio.default_driver(), "Audio::Driver"); append(audio.synchronize = true, "Audio::Synchronize"); append(audio.frequency = 48000, "Audio::Frequency"); append(audio.latency = 60, "Audio::Latency"); append(audio.resampler = 2, "Audio::Resampler"); append(audio.volume = 100, "Audio::Volume"); append(audio.mute = false, "Audio::Mute"); + append(input.driver = ruby::input.default_driver(), "Input::Driver"); append(input.focusPause = false, "Input::Focus::Pause"); append(input.focusAllow = false, "Input::Focus::AllowInput"); - + append(timing.video = 60.0, "Timing::Video"); + append(timing.audio = 48000.0, "Timing::Audio"); load(); } diff --git a/bsnes/target-ethos/configuration/configuration.hpp b/bsnes/target-ethos/configuration/configuration.hpp index 5606cc25..dd64cab5 100755 --- a/bsnes/target-ethos/configuration/configuration.hpp +++ b/bsnes/target-ethos/configuration/configuration.hpp @@ -1,6 +1,8 @@ struct Configuration : configuration { struct Video { + string driver; bool synchronize; + string shader; unsigned scaleMode; bool aspectCorrection; bool maskOverscan; @@ -12,6 +14,7 @@ struct Configuration : configuration { } video; struct Audio { + string driver; bool synchronize; unsigned frequency; unsigned latency; @@ -21,10 +24,16 @@ struct Configuration : configuration { } audio; struct Input { + string driver; bool focusPause; bool focusAllow; } input; + struct Timing { + double video; + double audio; + } timing; + void load(); void save(); Configuration(); diff --git a/bsnes/target-ethos/ethos.cpp b/bsnes/target-ethos/ethos.cpp index 6e27f8a7..61b09aa1 100755 --- a/bsnes/target-ethos/ethos.cpp +++ b/bsnes/target-ethos/ethos.cpp @@ -5,8 +5,7 @@ Application *application = nullptr; DSP dspaudio; Emulator::Interface& system() { - struct application_interface_null{}; - if(application->active == nullptr) throw application_interface_null(); + if(application->active == nullptr) throw; return *application->active; } @@ -47,7 +46,7 @@ Application::Application(int argc, char **argv) { } else { userpath.append(".config/ethos/"); } - mkdir(userpath, 0755); + directory::create(userpath); bootstrap(); active = nullptr; @@ -64,20 +63,23 @@ Application::Application(int argc, char **argv) { monospaceFont = "Liberation Mono, 8"; } - video.driver("OpenGL"); - audio.driver("ALSA"); - input.driver("SDL"); - config = new Configuration; + video.driver(config->video.driver); + audio.driver(config->audio.driver); + input.driver(config->input.driver); + utility = new Utility; inputManager = new InputManager; windowManager = new WindowManager; browser = new Browser; presentation = new Presentation; + dipSwitches = new DipSwitches; videoSettings = new VideoSettings; audioSettings = new AudioSettings; inputSettings = new InputSettings; hotkeySettings = new HotkeySettings; + timingSettings = new TimingSettings; + driverSettings = new DriverSettings; settings = new Settings; cheatDatabase = new CheatDatabase; cheatEditor = new CheatEditor; @@ -89,19 +91,20 @@ Application::Application(int argc, char **argv) { if(!video.cap(Video::Depth) || !video.set(Video::Depth, depth = 30u)) { video.set(Video::Depth, depth = 24u); } - video.init(); + if(video.init() == false) { video.driver("None"); video.init(); } audio.set(Audio::Handle, presentation->viewport.handle()); - audio.init(); + if(audio.init() == false) { audio.driver("None"); audio.init(); } input.set(Input::Handle, presentation->viewport.handle()); - input.init(); + if(input.init() == false) { input.driver("None"); input.init(); } dspaudio.setPrecision(16); dspaudio.setBalance(0.0); dspaudio.setFrequency(96000); utility->synchronizeRuby(); + utility->updateShader(); while(quit == false) { OS::processEvents(); diff --git a/bsnes/target-ethos/general/dip-switches.cpp b/bsnes/target-ethos/general/dip-switches.cpp new file mode 100755 index 00000000..46240985 --- /dev/null +++ b/bsnes/target-ethos/general/dip-switches.cpp @@ -0,0 +1,68 @@ +DipSwitches *dipSwitches = nullptr; + +DipSwitch::DipSwitch() { + append(name, {100, 0}, 5); + append(value, {~0, 0}); +} + +DipSwitches::DipSwitches() { + setTitle("DIP Switches"); + layout.setMargin(5); + accept.setText("Accept"); + + append(layout); + for(auto &dip : this->dip) layout.append(dip, {~0, 0}, 5); + layout.append(controlLayout, {~0, 0}); + controlLayout.append(spacer, {~0, 0}); + controlLayout.append(accept, {80, 0}); + + setGeometry({128, 128, 250, layout.minimumGeometry().height}); + + onClose = accept.onActivate = [&] { quit = true; }; +} + +unsigned DipSwitches::run(const XML::Node &node) { + audio.clear(); + setModal(true); + quit = false; + + for(auto &dip : this->dip) { + dip.name.setEnabled(false); + dip.name.setText("(empty)"); + dip.value.setEnabled(false); + dip.value.reset(); + dip.values.reset(); + } + + unsigned index = 0; + for(auto &setting : node) { + if(setting.name != "setting") continue; + dip[index].name.setEnabled(); + dip[index].name.setText(setting["name"].data); + dip[index].value.setEnabled(); + for(auto &option : setting) { + if(option.name != "option") continue; + dip[index].value.append(option["name"].data); + dip[index].values.append(fixedpoint::parse(option["value"].data)); + } + + if(++index >= Slots) break; + } + + setVisible(); + accept.setFocused(); + + while(quit == false) { + OS::processEvents(); + } + + setModal(false); + setVisible(false); + + unsigned result = 0; + for(auto &dip : this->dip) { + if(dip.value.enabled() == false) continue; + result |= dip.values[dip.value.selection()]; + } + return result; +} diff --git a/bsnes/target-ui/general/dip-switches.hpp b/bsnes/target-ethos/general/dip-switches.hpp similarity index 58% rename from bsnes/target-ui/general/dip-switches.hpp rename to bsnes/target-ethos/general/dip-switches.hpp index 2b023738..7ba17869 100755 --- a/bsnes/target-ui/general/dip-switches.hpp +++ b/bsnes/target-ethos/general/dip-switches.hpp @@ -1,23 +1,25 @@ struct DipSwitch : HorizontalLayout { Label name; ComboBox value; + vector values; DipSwitch(); }; struct DipSwitches : Window { - VerticalLayout layout; - DipSwitch dip[8]; - HorizontalLayout controlLayout; - Widget spacer; - Button acceptButton; + enum : unsigned { Slots = 8 }; - void load(); - void accept(); + VerticalLayout layout; + DipSwitch dip[Slots]; + HorizontalLayout controlLayout; + Widget spacer; + Button accept; + + unsigned run(const XML::Node &node); DipSwitches(); private: - unsigned values[8][16]; + bool quit; }; extern DipSwitches *dipSwitches; diff --git a/bsnes/target-ethos/general/general.cpp b/bsnes/target-ethos/general/general.cpp index cfd89a30..0d376dcf 100755 --- a/bsnes/target-ethos/general/general.cpp +++ b/bsnes/target-ethos/general/general.cpp @@ -1,3 +1,4 @@ #include "../ethos.hpp" #include "browser.cpp" #include "presentation.cpp" +#include "dip-switches.cpp" diff --git a/bsnes/target-ethos/general/general.hpp b/bsnes/target-ethos/general/general.hpp index 5f65c61c..04176b63 100755 --- a/bsnes/target-ethos/general/general.hpp +++ b/bsnes/target-ethos/general/general.hpp @@ -1,2 +1,3 @@ #include "browser.hpp" #include "presentation.hpp" +#include "dip-switches.hpp" diff --git a/bsnes/target-ethos/general/presentation.cpp b/bsnes/target-ethos/general/presentation.cpp index 8dafa03c..0da005c3 100755 --- a/bsnes/target-ethos/general/presentation.cpp +++ b/bsnes/target-ethos/general/presentation.cpp @@ -9,6 +9,15 @@ void Presentation::synchronize() { } } + shaderNone.setChecked(); + if(config->video.shader == "None") shaderNone.setChecked(); + if(config->video.shader == "Blur") shaderBlur.setChecked(); + for(auto &shader : shaderList) { + string name = notdir(nall::basename(config->video.shader)); + if(auto position = name.position(".")) name[position()] = 0; + if(name == shader->text()) shader->setChecked(); + } + switch(config->video.scaleMode) { case 0: centerVideo.setChecked(); break; case 1: scaleVideo.setChecked(); break; @@ -29,6 +38,7 @@ void Presentation::setSystemName(const string &name) { Presentation::Presentation() : active(nullptr) { bootstrap(); + loadShaders(); setGeometry({1024, 600, 720, 480}); windowManager->append(this, "Presentation"); @@ -46,6 +56,9 @@ Presentation::Presentation() : active(nullptr) { RadioItem::group(centerVideo, scaleVideo, stretchVideo); aspectCorrection.setText("Aspect Correction"); maskOverscan.setText("Mask Overscan"); + shaderMenu.setText("Shader"); + shaderNone.setText("None"); + shaderBlur.setText("Blur"); synchronizeVideo.setText("Synchronize Video"); synchronizeAudio.setText("Synchronize Audio"); muteAudio.setText("Mute Audio"); @@ -69,6 +82,10 @@ Presentation::Presentation() : active(nullptr) { append(settingsMenu); settingsMenu.append(videoMenu); videoMenu.append(centerVideo, scaleVideo, stretchVideo, *new Separator, aspectCorrection, maskOverscan); + settingsMenu.append(shaderMenu); + shaderMenu.append(shaderNone, shaderBlur); + if(shaderList.size() > 0) shaderMenu.append(*new Separator); + for(auto &shader : shaderList) shaderMenu.append(*shader); settingsMenu.append(*new Separator); settingsMenu.append(synchronizeVideo, synchronizeAudio, muteAudio); settingsMenu.append(*new Separator); @@ -87,6 +104,8 @@ Presentation::Presentation() : active(nullptr) { onSize = [&] { utility->resize(); }; onClose = [&] { application->quit = true; }; + shaderNone.onActivate = [&] { config->video.shader = "None"; utility->updateShader(); }; + shaderBlur.onActivate = [&] { config->video.shader = "Blur"; utility->updateShader(); }; centerVideo.onActivate = [&] { config->video.scaleMode = 0; utility->resize(); }; scaleVideo.onActivate = [&] { config->video.scaleMode = 1; utility->resize(); }; stretchVideo.onActivate = [&] { config->video.scaleMode = 2; utility->resize(); }; @@ -135,7 +154,7 @@ void Presentation::bootstrap() { for(auto &device : port.device) { auto iDevice = new RadioItem; iDevice->setText(device.name); - iDevice->onActivate = [=] { utility->connect(portNumber, deviceNumber); }; + iDevice->onActivate = [=] { utility->connect(portNumber, device.id); }; iPort->group.append(*iDevice); iPort->device.append(iDevice); deviceNumber++; @@ -169,3 +188,25 @@ void Presentation::bootstrap() { emulatorList.append(iEmulator); } } + +void Presentation::loadShaders() { + string pathname = application->path("Video Shaders/"); + lstring files = directory::files(pathname); + for(auto &filename : files) { + auto shader = new RadioItem; + string name = filename; + if(auto position = name.position(".")) name[position()] = 0; + shader->setText(name); + shader->onActivate = [=] { + config->video.shader = {pathname, filename}; + utility->updateShader(); + }; + shaderList.append(shader); + } + + set group; + group.append(shaderNone); + group.append(shaderBlur); + for(auto &shader : shaderList) group.append(*shader); + RadioItem::group(group); +} diff --git a/bsnes/target-ethos/general/presentation.hpp b/bsnes/target-ethos/general/presentation.hpp index f9b15023..50542353 100755 --- a/bsnes/target-ethos/general/presentation.hpp +++ b/bsnes/target-ethos/general/presentation.hpp @@ -30,6 +30,10 @@ struct Presentation : Window { RadioItem stretchVideo; CheckItem aspectCorrection; CheckItem maskOverscan; + Menu shaderMenu; + RadioItem shaderNone; + RadioItem shaderBlur; + vector shaderList; CheckItem synchronizeVideo; CheckItem synchronizeAudio; CheckItem muteAudio; @@ -46,6 +50,7 @@ struct Presentation : Window { void synchronize(); void setSystemName(const string &name); + void loadShaders(); void bootstrap(); Presentation(); diff --git a/bsnes/target-ethos/interface/interface.cpp b/bsnes/target-ethos/interface/interface.cpp index afad547a..09aa6c0f 100755 --- a/bsnes/target-ethos/interface/interface.cpp +++ b/bsnes/target-ethos/interface/interface.cpp @@ -99,3 +99,11 @@ int16_t Interface::inputPoll(unsigned port, unsigned device, unsigned input) { void Interface::mediaRequest(Emulator::Interface::Media media) { utility->loadMedia(media); } + +unsigned Interface::dipSettings(const XML::Node &node) { + return dipSwitches->run(node); +} + +string Interface::path(unsigned group) { + return utility->path(group); +} diff --git a/bsnes/target-ethos/interface/interface.hpp b/bsnes/target-ethos/interface/interface.hpp index ecfb9502..c6e1d663 100755 --- a/bsnes/target-ethos/interface/interface.hpp +++ b/bsnes/target-ethos/interface/interface.hpp @@ -4,6 +4,8 @@ struct Interface { void audioSample(int16_t lsample, int16_t rsample); int16_t inputPoll(unsigned port, unsigned device, unsigned input); void mediaRequest(Emulator::Interface::Media media); + unsigned dipSettings(const XML::Node &node); + string path(unsigned group); }; extern Interface *interface; diff --git a/bsnes/target-ethos/settings/driver.cpp b/bsnes/target-ethos/settings/driver.cpp new file mode 100755 index 00000000..324f334a --- /dev/null +++ b/bsnes/target-ethos/settings/driver.cpp @@ -0,0 +1,42 @@ +DriverSettings *driverSettings = nullptr; + +DriverSettings::DriverSettings() { + title.setFont(application->titleFont); + title.setText("Driver Configuration"); + videoLabel.setText("Video:"); + audioLabel.setText("Audio:"); + inputLabel.setText("Input:"); + + lstring list; + + list.split(";", video.driver_list()); + for(unsigned n = 0; n < list.size(); n++) { + videoDriver.append(list[n]); + if(list[n] == config->video.driver) videoDriver.setSelection(n); + } + + list.split(";", audio.driver_list()); + for(unsigned n = 0; n < list.size(); n++) { + audioDriver.append(list[n]); + if(list[n] == config->audio.driver) audioDriver.setSelection(n); + } + + list.split(";", input.driver_list()); + for(unsigned n = 0; n < list.size(); n++) { + inputDriver.append(list[n]); + if(list[n] == config->input.driver) inputDriver.setSelection(n); + } + + append(title, {~0, 0}, 5); + append(driverLayout, {~0, 0}); + driverLayout.append(videoLabel, {0, 0}, 5); + driverLayout.append(videoDriver, {~0, 0}, 5); + driverLayout.append(audioLabel, {0, 0}, 5); + driverLayout.append(audioDriver, {~0, 0}, 5); + driverLayout.append(inputLabel, {0, 0}, 5); + driverLayout.append(inputDriver, {~0, 0}); + + videoDriver.onChange = [&] { config->video.driver = videoDriver.text(); }; + audioDriver.onChange = [&] { config->audio.driver = audioDriver.text(); }; + inputDriver.onChange = [&] { config->input.driver = inputDriver.text(); }; +} diff --git a/bsnes/target-ethos/settings/driver.hpp b/bsnes/target-ethos/settings/driver.hpp new file mode 100755 index 00000000..aa847d4c --- /dev/null +++ b/bsnes/target-ethos/settings/driver.hpp @@ -0,0 +1,14 @@ +struct DriverSettings : SettingsLayout { + Label title; + HorizontalLayout driverLayout; + Label videoLabel; + ComboBox videoDriver; + Label audioLabel; + ComboBox audioDriver; + Label inputLabel; + ComboBox inputDriver; + + DriverSettings(); +}; + +extern DriverSettings *driverSettings; diff --git a/bsnes/target-ethos/settings/hotkey.cpp b/bsnes/target-ethos/settings/hotkey.cpp index b93fd2c6..c73d6068 100755 --- a/bsnes/target-ethos/settings/hotkey.cpp +++ b/bsnes/target-ethos/settings/hotkey.cpp @@ -18,6 +18,7 @@ HotkeySettings::HotkeySettings() : activeInput(nullptr) { inputList.onActivate = {&HotkeySettings::assignInput, this}; eraseButton.onActivate = {&HotkeySettings::eraseInput, this}; + for(auto &hotkey : inputManager->hotkeyMap) inputList.append("", ""); refresh(); } @@ -26,13 +27,13 @@ void HotkeySettings::synchronize() { } void HotkeySettings::refresh() { - inputList.reset(); + unsigned index = 0; for(auto &hotkey : inputManager->hotkeyMap) { string mapping = hotkey->mapping; mapping.replace("KB0::", ""); mapping.replace("MS0::", "Mouse::"); mapping.replace(",", " and "); - inputList.append(hotkey->name, mapping); + inputList.modify(index++, hotkey->name, mapping); } synchronize(); } diff --git a/bsnes/target-ethos/settings/input.cpp b/bsnes/target-ethos/settings/input.cpp index 4b3f8ba9..3c4bdd04 100755 --- a/bsnes/target-ethos/settings/input.cpp +++ b/bsnes/target-ethos/settings/input.cpp @@ -114,6 +114,13 @@ void InputSettings::portChanged() { void InputSettings::deviceChanged() { inputList.reset(); + for(unsigned number : activeDevice().order) inputList.append("", ""); + inputChanged(); + synchronize(); +} + +void InputSettings::inputChanged() { + unsigned index = 0; for(unsigned number : activeDevice().order) { auto &input = activeDevice().input[number]; auto abstract = inputManager->inputMap(input.guid); @@ -121,9 +128,8 @@ void InputSettings::deviceChanged() { mapping.replace("KB0::", ""); mapping.replace("MS0::", "Mouse::"); mapping.replace(",", " or "); - inputList.append(input.name, mapping); + inputList.modify(index++, input.name, mapping); } - synchronize(); } void InputSettings::resetInput() { @@ -176,7 +182,7 @@ void InputSettings::inputEvent(unsigned scancode, int16_t value, bool allowMouse if(activeInput->bind(scancode, value) == false) return; activeInput = nullptr; - deviceChanged(); + inputChanged(); settings->setStatusText(""); settings->layout.setEnabled(true); setEnabled(true); diff --git a/bsnes/target-ethos/settings/input.hpp b/bsnes/target-ethos/settings/input.hpp index 623ea0d1..db5460b7 100755 --- a/bsnes/target-ethos/settings/input.hpp +++ b/bsnes/target-ethos/settings/input.hpp @@ -24,6 +24,7 @@ struct InputSettings : SettingsLayout { void systemChanged(); void portChanged(); void deviceChanged(); + void inputChanged(); void resetInput(); void eraseInput(); void assignInput(); diff --git a/bsnes/target-ethos/settings/settings.cpp b/bsnes/target-ethos/settings/settings.cpp index 5d0c2991..745eb8cc 100755 --- a/bsnes/target-ethos/settings/settings.cpp +++ b/bsnes/target-ethos/settings/settings.cpp @@ -3,6 +3,8 @@ #include "audio.cpp" #include "input.cpp" #include "hotkey.cpp" +#include "timing.cpp" +#include "driver.cpp" Settings *settings = nullptr; void SettingsLayout::append(Sizable &sizable, const Size &size, unsigned spacing) { @@ -28,6 +30,8 @@ Settings::Settings() { panelList.append("Audio"); panelList.append("Input"); panelList.append("Hotkeys"); + panelList.append("Timing"); + panelList.append("Driver"); append(layout); layout.append(panelList, {120, ~0}, 5); @@ -35,6 +39,8 @@ Settings::Settings() { append(*audioSettings); append(*inputSettings); append(*hotkeySettings); + append(*timingSettings); + append(*driverSettings); panelList.onChange = {&Settings::panelChanged, this}; @@ -43,10 +49,13 @@ Settings::Settings() { } void Settings::panelChanged() { + setStatusText(""); videoSettings->setVisible(false); audioSettings->setVisible(false); inputSettings->setVisible(false); hotkeySettings->setVisible(false); + timingSettings->setVisible(false); + driverSettings->setVisible(false); if(panelList.selected() == false) return; switch(panelList.selection()) { @@ -54,5 +63,7 @@ void Settings::panelChanged() { case 1: return audioSettings->setVisible(); case 2: return inputSettings->setVisible(); case 3: return hotkeySettings->setVisible(); + case 4: return timingSettings->setVisible(); + case 5: return driverSettings->setVisible(); } } diff --git a/bsnes/target-ethos/settings/settings.hpp b/bsnes/target-ethos/settings/settings.hpp index f0ed1026..d436cdc1 100755 --- a/bsnes/target-ethos/settings/settings.hpp +++ b/bsnes/target-ethos/settings/settings.hpp @@ -10,6 +10,8 @@ struct SettingsLayout : HorizontalLayout { #include "audio.hpp" #include "input.hpp" #include "hotkey.hpp" +#include "timing.hpp" +#include "driver.hpp" struct Settings : Window { HorizontalLayout layout; diff --git a/bsnes/target-ethos/settings/timing.cpp b/bsnes/target-ethos/settings/timing.cpp new file mode 100755 index 00000000..cd734454 --- /dev/null +++ b/bsnes/target-ethos/settings/timing.cpp @@ -0,0 +1,130 @@ +TimingSettings *timingSettings = nullptr; + +TimingAdjustment::TimingAdjustment() { + assign.setEnabled(false); + assign.setText("Assign"); + analyze.setText("Analyze"); + stop.setEnabled(false); + stop.setText("Stop"); + + append(name, {40, 0}); + append(value, {100, 0}, 5); + append(assign, {80, 0}, 5); + append(spacer, {~0, 0}); + append(analyze, {80, 0}, 5); + append(stop, {80, 0}); +} + +TimingSettings::TimingSettings() { + title.setFont(application->titleFont); + title.setText("Audiovisual Synchronization"); + videoAdjust.name.setText("Video:"); + videoAdjust.value.setText({config->timing.video}); + audioAdjust.name.setText("Audio:"); + audioAdjust.value.setText({config->timing.audio}); + + append(title, {~0, 0}, 5); + append(videoAdjust, {~0, 0}, 5); + append(audioAdjust, {~0, 0}, 5); + + videoAdjust.value.onChange = [&] { videoAdjust.assign.setEnabled(true); }; + audioAdjust.value.onChange = [&] { audioAdjust.assign.setEnabled(true); }; + videoAdjust.assign.onActivate = [&] { + config->timing.video = atof(videoAdjust.value.text()); + videoAdjust.value.setText({config->timing.video}); + videoAdjust.assign.setEnabled(false); + utility->synchronizeDSP(); + }; + audioAdjust.assign.onActivate = [&] { + config->timing.audio = atof(audioAdjust.value.text()); + audioAdjust.value.setText({config->timing.audio}); + audioAdjust.assign.setEnabled(false); + utility->synchronizeDSP(); + }; + videoAdjust.analyze.onActivate = {&TimingSettings::analyzeVideoFrequency, this}; + audioAdjust.analyze.onActivate = {&TimingSettings::analyzeAudioFrequency, this}; + videoAdjust.stop.onActivate = audioAdjust.stop.onActivate = [&] { analysis.stop = true; }; +} + +void TimingSettings::analyzeVideoFrequency() { + video.set(Video::Synchronize, true); + audio.set(Audio::Synchronize, false); + videoAdjust.stop.setEnabled(true); + analyzeStart(); + do { + uint32_t *output; + unsigned pitch; + if(video.lock(output, pitch, 16, 16)) { + pitch >>= 2; + for(unsigned y = 0; y < 16; y++) memset(output + y * pitch, 0, 4 * 16); + video.unlock(); + video.refresh(); + } + } while(analyzeTick("Video")); + analyzeStop(); +} + +void TimingSettings::analyzeAudioFrequency() { + video.set(Video::Synchronize, false); + audio.set(Audio::Synchronize, true); + audioAdjust.stop.setEnabled(true); + analyzeStart(); + do { + audio.sample(0, 0); + } while(analyzeTick("Audio")); + analyzeStop(); +} + +void TimingSettings::analyzeStart() { + audio.clear(); + settings->setModal(true); + settings->panelList.setEnabled(false); + videoAdjust.analyze.setEnabled(false); + audioAdjust.analyze.setEnabled(false); + settings->setStatusText("Initiailizing ..."); + OS::processEvents(); + + analysis.stop = false; + analysis.seconds = 0; + analysis.counter = 0; + analysis.sample.reset(); + analysis.systemTime = time(0); +} + +bool TimingSettings::analyzeTick(const string &type) { + analysis.counter++; + + time_t systemTime = time(0); + if(systemTime > analysis.systemTime) { + analysis.systemTime = systemTime; + OS::processEvents(); + + if(analysis.seconds < 3) { + analysis.seconds++; + } else { + analysis.sample.append(analysis.counter); + uintmax_t sum = 0; + for(auto &point : analysis.sample) sum += point; + settings->setStatusText({ + type, " sample rate: ", (double)sum / analysis.sample.size(), "hz", + " (", analysis.sample.size(), " sample points)" + }); + } + + analysis.counter = 0; + } + + return !analysis.stop; +} + +void TimingSettings::analyzeStop() { + video.set(Video::Synchronize, config->video.synchronize); + audio.set(Audio::Synchronize, config->audio.synchronize); + + settings->panelList.setEnabled(true); + videoAdjust.analyze.setEnabled(true); + audioAdjust.analyze.setEnabled(true); + videoAdjust.stop.setEnabled(false); + audioAdjust.stop.setEnabled(false); + settings->setModal(false); +} diff --git a/bsnes/target-ethos/settings/timing.hpp b/bsnes/target-ethos/settings/timing.hpp new file mode 100755 index 00000000..27eee702 --- /dev/null +++ b/bsnes/target-ethos/settings/timing.hpp @@ -0,0 +1,36 @@ +struct TimingAdjustment : HorizontalLayout { + Label name; + LineEdit value; + Button assign; + Widget spacer; + Button analyze; + Button stop; + + TimingAdjustment(); +}; + +struct TimingSettings : SettingsLayout { + Label title; + TimingAdjustment videoAdjust; + TimingAdjustment audioAdjust; + + void analyzeVideoFrequency(); + void analyzeAudioFrequency(); + + void analyzeStart(); + bool analyzeTick(const string &type); + void analyzeStop(); + + TimingSettings(); + +private: + struct Analysis { + bool stop; + unsigned seconds; + unsigned counter; + vector sample; + time_t systemTime; + } analysis; +}; + +extern TimingSettings *timingSettings; diff --git a/bsnes/target-ethos/tools/cheat-editor.cpp b/bsnes/target-ethos/tools/cheat-editor.cpp index d673f86f..4f6d5494 100755 --- a/bsnes/target-ethos/tools/cheat-editor.cpp +++ b/bsnes/target-ethos/tools/cheat-editor.cpp @@ -153,7 +153,7 @@ bool CheatEditor::save(const string &filename) { } if(lastSave == -1) { - unlink(filename); + file::remove(filename); return true; } diff --git a/bsnes/target-ethos/tools/state-manager.cpp b/bsnes/target-ethos/tools/state-manager.cpp index eee5c024..7c3a94da 100755 --- a/bsnes/target-ethos/tools/state-manager.cpp +++ b/bsnes/target-ethos/tools/state-manager.cpp @@ -97,7 +97,7 @@ bool StateManager::save(const string &filename, unsigned revision) { bool hasSave = false; for(auto &slot : this->slot) hasSave |= slot.capacity() > 0; if(hasSave == false) { - unlink(filename); + file::remove(filename); return true; } diff --git a/bsnes/target-ethos/utility/utility.cpp b/bsnes/target-ethos/utility/utility.cpp index 77e9c9bb..ee3eab16 100755 --- a/bsnes/target-ethos/utility/utility.cpp +++ b/bsnes/target-ethos/utility/utility.cpp @@ -67,7 +67,7 @@ void Utility::saveMemory() { system().save(memory.id, fs); } - mkdir(string{pathname[0], "bsnes/"}, 0755); + directory::create({pathname[0], "bsnes/"}); cheatEditor->save({pathname[0], "cheats.xml"}); stateManager->save({pathname[0], "bsnes/states.bsa"}, 1); } @@ -100,7 +100,7 @@ void Utility::load() { loadMemory(); system().updatePalette(); - dspaudio.setFrequency(system().information.frequency); + synchronizeDSP(); resize(); cheatEditor->synchronize(); @@ -118,15 +118,18 @@ void Utility::unload() { stateManager->reset(); setInterface(nullptr); - presentation->setTitle({Emulator::Name, " v", Emulator::Version}); video.clear(); + audio.clear(); + presentation->setTitle({Emulator::Name, " v", Emulator::Version}); + cheatEditor->synchronize(); + stateManager->synchronize(); } void Utility::saveState(unsigned slot) { if(application->active == nullptr) return; serializer s = system().serialize(); if(s.size() == 0) return; - mkdir(string{pathname[0], "bsnes/"}, 0755); + directory::create({pathname[0], "bsnes/"}); if(file::write({pathname[0], "bsnes/state-", slot, ".bsa"}, s.data(), s.size()) == false); showMessage({"Save to slot ", slot}); } @@ -140,6 +143,20 @@ void Utility::loadState(unsigned slot) { showMessage({"Loaded from slot ", slot}); } +void Utility::synchronizeDSP() { + if(application->active == nullptr) return; + + if(config->video.synchronize == false) { + return dspaudio.setFrequency(system().audioFrequency()); + } + + double inputRatio = system().audioFrequency() / system().videoFrequency(); + double outputRatio = config->timing.audio / config->timing.video; + double frequency = inputRatio / outputRatio * config->audio.frequency; + + dspaudio.setFrequency(frequency); +} + void Utility::synchronizeRuby() { video.set(Video::Synchronize, config->video.synchronize); audio.set(Audio::Synchronize, config->audio.synchronize); @@ -155,6 +172,22 @@ void Utility::synchronizeRuby() { dspaudio.setVolume(config->audio.mute ? 0.0 : config->audio.volume * 0.01); } +void Utility::updateShader() { + if(config->video.shader == "None") { + video.set(Video::Shader, (const char*)""); + video.set(Video::Filter, 0u); + return; + } + if(config->video.shader == "Blur") { + video.set(Video::Shader, (const char*)""); + video.set(Video::Filter, 1u); + return; + } + string data; + data.readfile(config->video.shader); + video.set(Video::Shader, (const char*)data); +} + void Utility::resize(bool resizeWindow) { if(application->active == nullptr) return; Geometry geometry = presentation->geometry(); diff --git a/bsnes/target-ethos/utility/utility.hpp b/bsnes/target-ethos/utility/utility.hpp index 2bfeb98a..0e1d5bdd 100755 --- a/bsnes/target-ethos/utility/utility.hpp +++ b/bsnes/target-ethos/utility/utility.hpp @@ -15,7 +15,9 @@ struct Utility { void saveState(unsigned slot); void loadState(unsigned slot); + void synchronizeDSP(); void synchronizeRuby(); + void updateShader(); void resize(bool resizeWindow = false); void toggleFullScreen(); diff --git a/bsnes/target-debugger/Makefile b/bsnes/target-laevateinn/Makefile similarity index 100% rename from bsnes/target-debugger/Makefile rename to bsnes/target-laevateinn/Makefile diff --git a/bsnes/target-debugger/base.hpp b/bsnes/target-laevateinn/base.hpp similarity index 100% rename from bsnes/target-debugger/base.hpp rename to bsnes/target-laevateinn/base.hpp diff --git a/bsnes/target-debugger/breakpoint/breakpoint.cpp b/bsnes/target-laevateinn/breakpoint/breakpoint.cpp similarity index 100% rename from bsnes/target-debugger/breakpoint/breakpoint.cpp rename to bsnes/target-laevateinn/breakpoint/breakpoint.cpp diff --git a/bsnes/target-debugger/breakpoint/breakpoint.hpp b/bsnes/target-laevateinn/breakpoint/breakpoint.hpp similarity index 100% rename from bsnes/target-debugger/breakpoint/breakpoint.hpp rename to bsnes/target-laevateinn/breakpoint/breakpoint.hpp diff --git a/bsnes/target-debugger/console/about.cpp b/bsnes/target-laevateinn/console/about.cpp similarity index 100% rename from bsnes/target-debugger/console/about.cpp rename to bsnes/target-laevateinn/console/about.cpp diff --git a/bsnes/target-debugger/console/console.cpp b/bsnes/target-laevateinn/console/console.cpp similarity index 100% rename from bsnes/target-debugger/console/console.cpp rename to bsnes/target-laevateinn/console/console.cpp diff --git a/bsnes/target-debugger/console/console.hpp b/bsnes/target-laevateinn/console/console.hpp similarity index 100% rename from bsnes/target-debugger/console/console.hpp rename to bsnes/target-laevateinn/console/console.hpp diff --git a/bsnes/target-debugger/cpu/cpu.cpp b/bsnes/target-laevateinn/cpu/cpu.cpp similarity index 100% rename from bsnes/target-debugger/cpu/cpu.cpp rename to bsnes/target-laevateinn/cpu/cpu.cpp diff --git a/bsnes/target-debugger/cpu/cpu.hpp b/bsnes/target-laevateinn/cpu/cpu.hpp similarity index 100% rename from bsnes/target-debugger/cpu/cpu.hpp rename to bsnes/target-laevateinn/cpu/cpu.hpp diff --git a/bsnes/target-debugger/cpu/registers.cpp b/bsnes/target-laevateinn/cpu/registers.cpp similarity index 100% rename from bsnes/target-debugger/cpu/registers.cpp rename to bsnes/target-laevateinn/cpu/registers.cpp diff --git a/bsnes/target-debugger/debugger/debugger.cpp b/bsnes/target-laevateinn/debugger/debugger.cpp similarity index 100% rename from bsnes/target-debugger/debugger/debugger.cpp rename to bsnes/target-laevateinn/debugger/debugger.cpp diff --git a/bsnes/target-debugger/debugger/debugger.hpp b/bsnes/target-laevateinn/debugger/debugger.hpp similarity index 100% rename from bsnes/target-debugger/debugger/debugger.hpp rename to bsnes/target-laevateinn/debugger/debugger.hpp diff --git a/bsnes/target-debugger/debugger/hook.cpp b/bsnes/target-laevateinn/debugger/hook.cpp similarity index 100% rename from bsnes/target-debugger/debugger/hook.cpp rename to bsnes/target-laevateinn/debugger/hook.cpp diff --git a/bsnes/target-debugger/debugger/usage.cpp b/bsnes/target-laevateinn/debugger/usage.cpp similarity index 100% rename from bsnes/target-debugger/debugger/usage.cpp rename to bsnes/target-laevateinn/debugger/usage.cpp diff --git a/bsnes/target-debugger/interface/interface.cpp b/bsnes/target-laevateinn/interface/interface.cpp similarity index 100% rename from bsnes/target-debugger/interface/interface.cpp rename to bsnes/target-laevateinn/interface/interface.cpp diff --git a/bsnes/target-debugger/interface/interface.hpp b/bsnes/target-laevateinn/interface/interface.hpp similarity index 100% rename from bsnes/target-debugger/interface/interface.hpp rename to bsnes/target-laevateinn/interface/interface.hpp diff --git a/bsnes/target-debugger/main.cpp b/bsnes/target-laevateinn/main.cpp similarity index 100% rename from bsnes/target-debugger/main.cpp rename to bsnes/target-laevateinn/main.cpp diff --git a/bsnes/target-debugger/memory/memory.cpp b/bsnes/target-laevateinn/memory/memory.cpp similarity index 100% rename from bsnes/target-debugger/memory/memory.cpp rename to bsnes/target-laevateinn/memory/memory.cpp diff --git a/bsnes/target-debugger/memory/memory.hpp b/bsnes/target-laevateinn/memory/memory.hpp similarity index 100% rename from bsnes/target-debugger/memory/memory.hpp rename to bsnes/target-laevateinn/memory/memory.hpp diff --git a/bsnes/target-debugger/properties/properties.cpp b/bsnes/target-laevateinn/properties/properties.cpp similarity index 100% rename from bsnes/target-debugger/properties/properties.cpp rename to bsnes/target-laevateinn/properties/properties.cpp diff --git a/bsnes/target-debugger/properties/properties.hpp b/bsnes/target-laevateinn/properties/properties.hpp similarity index 100% rename from bsnes/target-debugger/properties/properties.hpp rename to bsnes/target-laevateinn/properties/properties.hpp diff --git a/bsnes/target-debugger/resource.rc b/bsnes/target-laevateinn/resource.rc similarity index 100% rename from bsnes/target-debugger/resource.rc rename to bsnes/target-laevateinn/resource.rc diff --git a/bsnes/target-debugger/settings/settings.cpp b/bsnes/target-laevateinn/settings/settings.cpp similarity index 100% rename from bsnes/target-debugger/settings/settings.cpp rename to bsnes/target-laevateinn/settings/settings.cpp diff --git a/bsnes/target-debugger/settings/settings.hpp b/bsnes/target-laevateinn/settings/settings.hpp similarity index 100% rename from bsnes/target-debugger/settings/settings.hpp rename to bsnes/target-laevateinn/settings/settings.hpp diff --git a/bsnes/target-debugger/smp/registers.cpp b/bsnes/target-laevateinn/smp/registers.cpp similarity index 100% rename from bsnes/target-debugger/smp/registers.cpp rename to bsnes/target-laevateinn/smp/registers.cpp diff --git a/bsnes/target-debugger/smp/smp.cpp b/bsnes/target-laevateinn/smp/smp.cpp similarity index 100% rename from bsnes/target-debugger/smp/smp.cpp rename to bsnes/target-laevateinn/smp/smp.cpp diff --git a/bsnes/target-debugger/smp/smp.hpp b/bsnes/target-laevateinn/smp/smp.hpp similarity index 100% rename from bsnes/target-debugger/smp/smp.hpp rename to bsnes/target-laevateinn/smp/smp.hpp diff --git a/bsnes/target-debugger/tracer/tracer.cpp b/bsnes/target-laevateinn/tracer/tracer.cpp similarity index 100% rename from bsnes/target-debugger/tracer/tracer.cpp rename to bsnes/target-laevateinn/tracer/tracer.cpp diff --git a/bsnes/target-debugger/tracer/tracer.hpp b/bsnes/target-laevateinn/tracer/tracer.hpp similarity index 100% rename from bsnes/target-debugger/tracer/tracer.hpp rename to bsnes/target-laevateinn/tracer/tracer.hpp diff --git a/bsnes/target-debugger/video/video.cpp b/bsnes/target-laevateinn/video/video.cpp similarity index 100% rename from bsnes/target-debugger/video/video.cpp rename to bsnes/target-laevateinn/video/video.cpp diff --git a/bsnes/target-debugger/video/video.hpp b/bsnes/target-laevateinn/video/video.hpp similarity index 100% rename from bsnes/target-debugger/video/video.hpp rename to bsnes/target-laevateinn/video/video.hpp diff --git a/bsnes/target-debugger/vram/vram.cpp b/bsnes/target-laevateinn/vram/vram.cpp similarity index 100% rename from bsnes/target-debugger/vram/vram.cpp rename to bsnes/target-laevateinn/vram/vram.cpp diff --git a/bsnes/target-debugger/vram/vram.hpp b/bsnes/target-laevateinn/vram/vram.hpp similarity index 100% rename from bsnes/target-debugger/vram/vram.hpp rename to bsnes/target-laevateinn/vram/vram.hpp diff --git a/bsnes/target-debugger/window/window.cpp b/bsnes/target-laevateinn/window/window.cpp similarity index 100% rename from bsnes/target-debugger/window/window.cpp rename to bsnes/target-laevateinn/window/window.cpp diff --git a/bsnes/target-debugger/window/window.hpp b/bsnes/target-laevateinn/window/window.hpp similarity index 100% rename from bsnes/target-debugger/window/window.hpp rename to bsnes/target-laevateinn/window/window.hpp diff --git a/bsnes/target-ui/Makefile b/bsnes/target-ui/Makefile deleted file mode 100755 index 8c3d2635..00000000 --- a/bsnes/target-ui/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -processors := arm gsu hg51b lr35902 r6502 r65816 spc700 upd96050 -include processor/Makefile - -include $(fc)/Makefile -include $(sfc)/Makefile -include $(gb)/Makefile -include $(gba)/Makefile -name := bsnes - -ui_objects := ui-main ui-config ui-interface ui-input ui-utility -ui_objects += ui-window ui-general ui-settings ui-tools -ui_objects += phoenix ruby -ui_objects += $(if $(call streq,$(platform),win),resource) - -# platform -ifeq ($(platform),x) - ruby := video.glx video.xv video.sdl - ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao - ruby += input.sdl input.x -else ifeq ($(platform),osx) - ruby := - ruby += audio.openal - ruby += input.carbon -else ifeq ($(platform),win) - ruby := video.direct3d video.wgl video.directdraw video.gdi - ruby += audio.directsound audio.xaudio2 - ruby += input.rawinput input.directinput -endif - -# phoenix -include phoenix/Makefile -link += $(phoenixlink) - -# ruby -include ruby/Makefile -link += $(rubylink) - -# rules -objects := $(ui_objects) $(objects) -objects := $(patsubst %,obj/%.o,$(objects)) - -obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/) -obj/ui-config.o: $(ui)/config/config.cpp $(call rwildcard,$(ui)/) -obj/ui-interface.o: $(ui)/interface/interface.cpp $(call rwildcard,$(ui)/) -obj/ui-input.o: $(ui)/input/input.cpp $(call rwildcard,$(ui)/) -obj/ui-utility.o: $(ui)/utility/utility.cpp $(call rwildcard,$(ui)/) -obj/ui-window.o: $(ui)/window/window.cpp $(call rwildcard,$(ui)/) -obj/ui-general.o: $(ui)/general/general.cpp $(call rwildcard,$(ui)/) -obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/) -obj/ui-tools.o: $(ui)/tools/tools.cpp $(call rwildcard,$(ui)/) - -obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*) - $(call compile,$(rubyflags)) - -obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*) - $(call compile,$(phoenixflags)) - -obj/resource.o: $(ui)/resource.rc -# windres --target=pe-i386 $(ui)/resource.rc obj/resource.o - windres $(ui)/resource.rc obj/resource.o - -# targets -build: $(objects) -ifeq ($(platform),osx) - test -d ../$(name).app || mkdir -p ../$(name).app/Contents/MacOS - $(strip $(cpp) -o ../$(name).app/Contents/MacOS/$(name) $(objects) $(link)) -else - $(strip $(cpp) -o out/$(name) $(objects) $(link)) -endif - -install: -ifeq ($(USER),root) - @echo Please do not run make install as root. - @echo The installer needs to know your home directory to install important files. -else ifeq ($(platform),x) - sudo install -D -m 755 out/$(name) $(DESTDIR)$(prefix)/bin/$(name) - sudo install -D -m 644 data/$(name).png $(DESTDIR)$(prefix)/share/pixmaps/$(name).png - sudo install -D -m 644 data/$(name).desktop $(DESTDIR)$(prefix)/share/applications/$(name).desktop - - mkdir -p ~/.config/$(name) - cp -R profile/* ~/.config/$(name) - cp data/cheats.xml ~/.config/$(name)/cheats.xml - chmod -R 777 ~/.config/$(name) -endif - -uninstall: -ifeq ($(platform),x) - sudo rm $(DESTDIR)$(prefix)/bin/$(name) - sudo rm $(DESTDIR)$(prefix)/share/pixmaps/$(name).png - sudo rm $(DESTDIR)$(prefix)/share/applications/$(name).desktop -endif diff --git a/bsnes/target-ui/base.hpp b/bsnes/target-ui/base.hpp deleted file mode 100755 index e03e1433..00000000 --- a/bsnes/target-ui/base.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include - -namespace FC = Famicom; -namespace SFC = SuperFamicom; -namespace GB = GameBoy; -namespace GBA = GameBoyAdvance; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace nall; - -#include -using namespace phoenix; - -#include -using namespace ruby; - -#include "config/config.hpp" -#include "interface/interface.hpp" -#include "input/input.hpp" -#include "utility/utility.hpp" -#include "window/window.hpp" -#include "general/general.hpp" -#include "settings/settings.hpp" -#include "tools/tools.hpp" - -struct Application { - bool quit; - bool pause; - bool autopause; - bool compositionEnable; - unsigned depth; - - string basepath; - string userpath; - string path(const string &filename); - - string title; - string normalFont; - string boldFont; - string titleFont; - string monospaceFont; - - void run(); - Application(int argc, char **argv); - ~Application(); -}; - -extern Application *application; -extern nall::DSP dspaudio; diff --git a/bsnes/target-ui/config/config.cpp b/bsnes/target-ui/config/config.cpp deleted file mode 100755 index 3583777d..00000000 --- a/bsnes/target-ui/config/config.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "../base.hpp" -Config *config = nullptr; - -Config::Config() { - append(video.driver = "", "Video::Driver"); - append(video.filter = "None", "Video::Filter"); - append(video.shader = "Blur", "Video::Shader"); - append(video.synchronize = true, "Video::Synchronize"); - append(video.correctAspectRatio = true, "Video::CorrectAspectRatio"); - - append(video.maskOverscan = false, "Video::MaskOverscan"); - append(video.maskOverscanHorizontal = 8, "Video::MaskOverscanHorizontal"); - append(video.maskOverscanVertical = 8, "Video::MaskOverscanVertical"); - - append(video.brightness = 100, "Video::Brightness"); - append(video.contrast = 100, "Video::Contrast"); - append(video.gamma = 50, "Video::Gamma"); - - append(video.fullScreenMode = 0, "Video::FullScreenMode"); - - append(video.startFullScreen = false, "Video::StartFullScreen"); - append(video.compositionMode = 0, "Video::CompositionMode"); - - append(audio.driver = "", "Audio::Driver"); - append(audio.synchronize = true, "Audio::Synchronize"); - append(audio.mute = false, "Audio::Mute"); - append(audio.volume = 100, "Audio::Volume"); - append(audio.latency = 60, "Audio::Latency"); - append(audio.resampler = "sinc", "Audio::Resampler"); - - append(audio.frequency = 48000, "Audio::Frequency::Native"); - append(audio.frequencyNES = 1789772, "Audio::Frequency::NES"); - append(audio.frequencySNES = 32000, "Audio::Frequency::SNES"); - append(audio.frequencyGB = 4194304, "Audio::Frequency::GB"); - append(audio.frequencyGBA = 32768, "Audio::Frequency::GBA"); - - append(input.driver = "", "Input::Driver"); - append(input.focusPolicy = 1, "Input::FocusPolicy"); - - append(nes.controllerPort1Device = 1, "Famicom::Controller::Port1"); - append(nes.controllerPort2Device = 0, "Famicom::Controller::Port2"); - - append(snes.controllerPort1Device = 1, "SuperFamciom::Controller::Port1"); - append(snes.controllerPort2Device = 0, "SuperFamicom::Controller::Port2"); - - load(application->path("settings.cfg")); - save(application->path("settings.cfg")); -} - -Config::~Config() { - save(application->path("settings.cfg")); -} diff --git a/bsnes/target-ui/config/config.hpp b/bsnes/target-ui/config/config.hpp deleted file mode 100755 index b30441ea..00000000 --- a/bsnes/target-ui/config/config.hpp +++ /dev/null @@ -1,59 +0,0 @@ -struct Config : public configuration { - struct Video { - string driver; - - string filter; - string shader; - - bool synchronize; - bool correctAspectRatio; - - bool maskOverscan; - unsigned maskOverscanHorizontal; - unsigned maskOverscanVertical; - - unsigned brightness; - unsigned contrast; - unsigned gamma; - - unsigned fullScreenMode; - unsigned compositionMode; - - bool startFullScreen; - } video; - - struct Audio { - string driver; - bool synchronize; - bool mute; - unsigned volume; - unsigned latency; - string resampler; - - unsigned frequency; - unsigned frequencyNES; - unsigned frequencySNES; - unsigned frequencyGB; - unsigned frequencyGBA; - } audio; - - struct Input { - string driver; - unsigned focusPolicy; - } input; - - struct NES { - unsigned controllerPort1Device; - unsigned controllerPort2Device; - } nes; - - struct SNES { - unsigned controllerPort1Device; - unsigned controllerPort2Device; - } snes; - - Config(); - ~Config(); -}; - -extern Config *config; diff --git a/bsnes/target-ui/general/dip-switches.cpp b/bsnes/target-ui/general/dip-switches.cpp deleted file mode 100755 index c0513b53..00000000 --- a/bsnes/target-ui/general/dip-switches.cpp +++ /dev/null @@ -1,69 +0,0 @@ -DipSwitches *dipSwitches = nullptr; - -DipSwitch::DipSwitch() { - append(name, {~0, 0}, 5); - append(value, {~0, 0}, 0); -} - -DipSwitches::DipSwitches() { - setTitle("DIP Switches"); - - layout.setMargin(5); - acceptButton.setText("Accept"); - - append(layout); - for(unsigned n = 0; n < 8; n++) - layout.append(dip[n], {~0, 0}, 5); - layout.append(controlLayout, {~0, 0}, 5); - controlLayout.append(spacer, {~0, 0}, 0); - controlLayout.append(acceptButton, { 0, 0}, 0); - - setGeometry({128, 128, 400, layout.minimumGeometry().height}); - windowManager->append(this, "DipSwitches"); - - acceptButton.onActivate = { &DipSwitches::accept, this }; -} - -void DipSwitches::load() { - if(interface->mode() != Interface::Mode::SFC || SFC::cartridge.has_nss_dip() == false) return; - application->pause = true; - - auto info = SFC::cartridge.information.nss; - unsigned count = info.setting.size(); - - for(unsigned n = 0; n < min(8, count); n++) { - dip[n].setEnabled(true); - dip[n].name.setText(info.setting[n]); - dip[n].value.reset(); - for(unsigned z = 0; z < min(16, info.option[n].size()); z++) { - lstring part; - part.split<1>(":", info.option[n][z]); - values[n][z] = hex(part[0]); - dip[n].value.append(part[1]); - } - } - - for(unsigned n = count; n < 8; n++) { - dip[n].setEnabled(false); - dip[n].name.setText("(unused)"); - dip[n].value.reset(); - dip[n].value.append("(unused)"); - } - - acceptButton.setFocused(); - setVisible(); -} - -void DipSwitches::accept() { - auto info = SFC::cartridge.information.nss; - unsigned count = info.setting.size(); - - unsigned result = 0x0000; - for(unsigned n = 0; n < min(8, count); n++) { - result |= values[n][dip[n].value.selection()]; - } - - setVisible(false); - SFC::nss.set_dip(result); - application->pause = false; -} diff --git a/bsnes/target-ui/general/file-browser.cpp b/bsnes/target-ui/general/file-browser.cpp deleted file mode 100755 index 8b9aa94d..00000000 --- a/bsnes/target-ui/general/file-browser.cpp +++ /dev/null @@ -1,141 +0,0 @@ -FileBrowser *fileBrowser = nullptr; - -FileBrowser::FileBrowser() { - setGeometry({ 128, 128, 640, 400 }); - windowManager->append(this, "FileBrowser"); - - layout.setMargin(5); - pathBrowse.setText("Browse ..."); - pathUp.setText(".."); - openButton.setText("Open"); - - append(layout); - layout.append(pathLayout, { ~0, 0 }, 5); - pathLayout.append(pathEdit, { ~0, 0 }, 5); - pathLayout.append(pathBrowse, { 0, 0 }, 5); - pathLayout.append(pathUp, { 0, 0 }); - layout.append(fileList, { ~0, ~0 }, 5); - layout.append(controlLayout, { ~0, 0 }); - controlLayout.append(filterLabel, { ~0, 0 }, 5); - controlLayout.append(openButton, { 80, 0 }); - - pathEdit.onActivate = [&] { - string path = pathEdit.text(); - path.transform("\\", "/"); - if(path.endswith("/") == false) path.append("/"); - setPath(path); - }; - - pathBrowse.onActivate = [&] { - string path = DialogWindow::folderSelect(*this, mode->path); - if(path != "") setPath(path); - }; - - pathUp.onActivate = [&] { - if(mode->path == "/") return; - string path = mode->path; - path.rtrim<1>("/"); - path = dir(path); - setPath(path); - }; - - fileList.onChange = { &FileBrowser::synchronize, this }; - fileList.onActivate = openButton.onActivate = { &FileBrowser::fileListActivate, this }; - - filterModes.append({ "Default", "", { "*" } }); - filterModes.append({ "Famicom", "", { "*.fc", "*.nes" } }); - filterModes.append({ "SuperFamicom", "", { "*.sfc" } }); - filterModes.append({ "GameBoy", "", { "*.gb", "*.gbb" } }); - filterModes.append({ "GameBoyColor", "", { "*.gbc", "*.gbb" } }); - filterModes.append({ "GameBoyAdvance", "", { "*.gba" } }); - filterModes.append({ "Satellaview", "", { "*.bs" } }); - filterModes.append({ "SufamiTurbo", "", { "*.st" } }); - mode = &filterModes[Mode::Default]; - - for(auto &mode : filterModes) config.attach(mode.path, mode.name); - config.load(application->path("paths.cfg")); - config.save(application->path("paths.cfg")); - synchronize(); -} - -void FileBrowser::synchronize() { - openButton.setEnabled(fileList.selected()); -} - -FileBrowser::~FileBrowser() { - config.save(application->path("paths.cfg")); -} - -void FileBrowser::open(const string &title, unsigned requestedMode, function requestedCallback) { - callback = requestedCallback; - if(mode == &filterModes[requestedMode]) { - setVisible(); - fileList.setFocused(); - return; - } - mode = &filterModes[requestedMode]; - - setTitle(title); - setPath(mode->path); - - string filterText = "Files of type: "; - for(auto &filter : mode->filter) filterText.append(filter, ", "); - filterText.trim<1>(", "); - filterLabel.setText(filterText); - - setVisible(); - fileList.setFocused(); -} - -void FileBrowser::setPath(const string &path) { - mode->path = path; - if(mode->path == "") mode->path = application->basepath; - pathEdit.setText(mode->path); - - fileList.reset(); - fileNameList.reset(); - - lstring contentsList = directory::contents(path); - for(auto &fileName : contentsList) { - if(fileName.endswith("/")) { - fileNameList.append(fileName); - } else for(auto &filter : mode->filter) { - if(fileName.wildcard(filter)) { - fileNameList.append(fileName); - break; - } - } - } - - for(auto &fileName : fileNameList) fileList.append(fileName); - fileList.setSelection(0); - fileList.setFocused(); - synchronize(); -} - -void FileBrowser::fileListActivate() { - unsigned selection = fileList.selection(); - string fileName = fileNameList[selection]; - if(fileName.endswith("/")) { - if(loadFolder({ mode->path, fileName })) return; - return setPath({ mode->path, fileName }); - } - loadFile({ mode->path, fileName }); -} - -bool FileBrowser::loadFolder(const string &requestedPath) { - bool accept = false; - string path = requestedPath; - path.rtrim<1>("/"); - for(auto &filter : mode->filter) { - if(path.wildcard(filter)) accept = true; - } - if(accept == false) return false; - loadFile(requestedPath); - return true; -} - -void FileBrowser::loadFile(const string &filename) { - setVisible(false); - if(callback) callback(filename); -} diff --git a/bsnes/target-ui/general/file-browser.hpp b/bsnes/target-ui/general/file-browser.hpp deleted file mode 100755 index 8092cb3a..00000000 --- a/bsnes/target-ui/general/file-browser.hpp +++ /dev/null @@ -1,37 +0,0 @@ -struct FileBrowser : Window { - VerticalLayout layout; - HorizontalLayout pathLayout; - LineEdit pathEdit; - Button pathBrowse; - Button pathUp; - ListView fileList; - HorizontalLayout controlLayout; - Label filterLabel; - Button openButton; - - struct Mode { enum : unsigned { Default, NES, SNES, GameBoy, GameBoyColor, GameBoyAdvance, Satellaview, SufamiTurbo }; }; - void open(const string &title, unsigned mode, function callback); - - FileBrowser(); - ~FileBrowser(); - -private: - configuration config; - struct FilterMode { - string name; - string path; - lstring filter; - } *mode; - vector filterModes; - - lstring fileNameList; - function callback; - - void synchronize(); - void setPath(const string &path); - void fileListActivate(); - bool loadFolder(const string &path); - void loadFile(const string &filename); -}; - -extern FileBrowser *fileBrowser; diff --git a/bsnes/target-ui/general/general.cpp b/bsnes/target-ui/general/general.cpp deleted file mode 100755 index 1a39b2c1..00000000 --- a/bsnes/target-ui/general/general.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "../base.hpp" -#include "main-window.cpp" -#include "file-browser.cpp" -#include "dip-switches.cpp" -#include "information-window.cpp" diff --git a/bsnes/target-ui/general/general.hpp b/bsnes/target-ui/general/general.hpp deleted file mode 100755 index 5f51a006..00000000 --- a/bsnes/target-ui/general/general.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "main-window.hpp" -#include "file-browser.hpp" -#include "dip-switches.hpp" -#include "information-window.hpp" diff --git a/bsnes/target-ui/general/information-window.cpp b/bsnes/target-ui/general/information-window.cpp deleted file mode 100755 index 8f15ec06..00000000 --- a/bsnes/target-ui/general/information-window.cpp +++ /dev/null @@ -1,43 +0,0 @@ -InformationWindow *informationWindow = nullptr; - -InformationWindow::InformationWindow() { - setTitle("Information"); - - layout.setMargin(5); - markup.setFont(application->monospaceFont); - markupXML.setChecked(); - markupXML.setText("Show original XML markup"); - - append(layout); - layout.append(markup, {~0, ~0}, 5); - layout.append(markupXML, {~0, 0}); - - setGeometry({128, 128, 600, 360}); - windowManager->append(this, "InformationWindow"); - - markupXML.onToggle = { &InformationWindow::update, this }; -} - -void InformationWindow::update() { - string markupData = interface->markup(); - if(markupXML.checked()) { - markup.setText(markupData); - return; - } - - XML::Document document(markupData); - markupData = ""; - parse(document, markupData, 0); - markup.setText(markupData); -} - -void InformationWindow::parse(XML::Node &header, string &output, unsigned depth) { - for(auto &node : header) { - if(node.name.beginswith("?")) continue; - for(unsigned n = 0; n < depth; n++) output.append(" "); - output.append(node.name); - if(node.children.size() == 0 && !node.data.empty()) output.append(": ", node.data); - output.append("\n"); - parse(node, output, depth + 1); - } -} diff --git a/bsnes/target-ui/general/information-window.hpp b/bsnes/target-ui/general/information-window.hpp deleted file mode 100755 index 96b77e67..00000000 --- a/bsnes/target-ui/general/information-window.hpp +++ /dev/null @@ -1,11 +0,0 @@ -struct InformationWindow : Window { - VerticalLayout layout; - TextEdit markup; - CheckBox markupXML; - - void update(); - void parse(XML::Node &node, string &output, unsigned depth); - InformationWindow(); -}; - -extern InformationWindow *informationWindow; diff --git a/bsnes/target-ui/general/main-window.cpp b/bsnes/target-ui/general/main-window.cpp deleted file mode 100755 index 045294b7..00000000 --- a/bsnes/target-ui/general/main-window.cpp +++ /dev/null @@ -1,446 +0,0 @@ -MainWindow *mainWindow = nullptr; - -MainWindow::MainWindow() { - setTitle(application->title); - setGeometry({ 256, 256, 626, 480 }); - setBackgroundColor({ 0, 0, 0 }); - windowManager->append(this, "MainWindow"); - - cartridgeMenu.setText("&Load"); - cartridgeLoadNES.setText("&Famicom ..."); - cartridgeLoadSNES.setText("&Super Famicom ..."); - cartridgeLoadGameBoy.setText("&Game Boy ..."); - cartridgeLoadGameBoyColor.setText("Game Boy &Color ..."); - cartridgeLoadGameBoyAdvance.setText("Game Boy &Advance ..."); - cartridgeLoadSuperGameBoy.setText("Super Game Boy ..."); - cartridgeLoadSatellaview.setText("BS-X Satellaview ..."); - cartridgeLoadSufamiTurbo.setText("Sufami Turbo ..."); - - nesMenu.setText("&Famicom"); - nesPower.setText("&Power Cycle"); - nesReset.setText("&Reset"); - nesPort1.setText("Controller Port &1"); - nesPort1Device[0].setText("None"); - nesPort1Device[1].setText("Gamepad"); - RadioItem::group(nesPort1Device[0], nesPort1Device[1]); - nesPort1Device[config->nes.controllerPort1Device].setChecked(); - nesPort2.setText("Controller Port &2"); - nesPort2Device[0].setText("None"); - nesPort2Device[1].setText("Gamepad"); - RadioItem::group(nesPort2Device[0], nesPort2Device[1]); - nesPort2Device[config->nes.controllerPort2Device].setChecked(); - nesCartridgeUnload.setText("&Unload Cartridge"); - - snesMenu.setText("&Super Famicom"); - snesPower.setText("&Power Cycle"); - snesReset.setText("&Reset"); - snesPort1.setText("Controller Port &1"); - snesPort1Device[0].setText("None"); - snesPort1Device[1].setText("Gamepad"); - snesPort1Device[2].setText("Multitap"); - snesPort1Device[3].setText("Mouse"); - snesPort1Device[4].setText("Serial USART"); - RadioItem::group(snesPort1Device[0], snesPort1Device[1], snesPort1Device[2], snesPort1Device[3], - snesPort1Device[4]); - snesPort1Device[config->snes.controllerPort1Device].setChecked(); - snesPort2.setText("Controller Port &2"); - snesPort2Device[0].setText("None"); - snesPort2Device[1].setText("Gamepad"); - snesPort2Device[2].setText("Multitap"); - snesPort2Device[3].setText("Mouse"); - snesPort2Device[4].setText("Super Scope"); - snesPort2Device[5].setText("Justifier"); - snesPort2Device[6].setText("Dual Justifiers"); - snesPort2Device[7].setText("Serial USART"); - RadioItem::group(snesPort2Device[0], snesPort2Device[1], snesPort2Device[2], snesPort2Device[3], - snesPort2Device[4], snesPort2Device[5], snesPort2Device[6], snesPort2Device[7]); - snesPort2Device[config->snes.controllerPort2Device].setChecked(); - snesCartridgeUnload.setText("&Unload Cartridge"); - - gameBoyMenu.setText("&Game Boy"); - gameBoyPower.setText("&Power Cycle"); - gameBoyCartridgeUnload.setText("&Unload Cartridge"); - - gameBoyAdvanceMenu.setText("&Game Boy Advance"); - gameBoyAdvancePower.setText("&Power Cycle"); - gameBoyAdvanceCartridgeUnload.setText("&Unload Cartridge"); - - settingsMenu.setText("S&ettings"); - settingsVideoFilter.setText("Video &Filter"); - settingsVideoFilterNone.setText("None"); - setupVideoFilters(); - settingsVideoShader.setText("Video &Shader"); - settingsVideoShaderNone.setText("None"); - settingsVideoShaderBlur.setText("Blur"); - setupVideoShaders(); - settingsSynchronizeVideo.setText("Synchronize &Video"); - settingsSynchronizeVideo.setChecked(config->video.synchronize); - settingsSynchronizeAudio.setText("Synchronize &Audio"); - settingsSynchronizeAudio.setChecked(config->audio.synchronize); - settingsCorrectAspectRatio.setText("Correct Aspect &Ratio"); - settingsCorrectAspectRatio.setChecked(config->video.correctAspectRatio); - settingsMaskOverscan.setText("Mask &Overscan"); - settingsMaskOverscan.setChecked(config->video.maskOverscan); - settingsMuteAudio.setText("&Mute Audio"); - settingsMuteAudio.setChecked(config->audio.mute); - settingsConfiguration.setText("&Configuration ..."); - - toolsMenu.setText("&Tools"); - toolsStateSave.setText("&Save State"); - toolsStateSave1.setText("Slot &1"); - toolsStateSave2.setText("Slot &2"); - toolsStateSave3.setText("Slot &3"); - toolsStateSave4.setText("Slot &4"); - toolsStateSave5.setText("Slot &5"); - toolsStateLoad.setText("&Load State"); - toolsStateLoad1.setText("Slot &1"); - toolsStateLoad2.setText("Slot &2"); - toolsStateLoad3.setText("Slot &3"); - toolsStateLoad4.setText("Slot &4"); - toolsStateLoad5.setText("Slot &5"); - toolsInformationWindow.setText("&Information ..."); - toolsShrinkWindow.setText("Shrink &Window"); - toolsCheatEditor.setText("&Cheat Editor ..."); - toolsStateManager.setText("State &Manager ..."); - - append(cartridgeMenu); - cartridgeMenu.append(cartridgeLoadNES); - cartridgeMenu.append(cartridgeLoadSNES); - cartridgeMenu.append(cartridgeLoadGameBoy); - cartridgeMenu.append(cartridgeLoadGameBoyColor); - cartridgeMenu.append(cartridgeLoadGameBoyAdvance); - cartridgeMenu.append(cartridgeSeparator); - cartridgeMenu.append(cartridgeLoadSuperGameBoy); - cartridgeMenu.append(cartridgeLoadSatellaview); - cartridgeMenu.append(cartridgeLoadSufamiTurbo); - - append(nesMenu); - nesMenu.append(nesPower); - nesMenu.append(nesReset); - nesMenu.append(nesSeparator1); - nesMenu.append(nesPort1); - nesPort1.append(nesPort1Device[0]); - nesPort1.append(nesPort1Device[1]); - nesMenu.append(nesPort2); - nesPort2.append(nesPort2Device[0]); - nesPort2.append(nesPort2Device[1]); - nesMenu.append(nesSeparator2); - nesMenu.append(nesCartridgeUnload); - - append(snesMenu); - snesMenu.append(snesPower); - snesMenu.append(snesReset); - snesMenu.append(snesSeparator1); - snesMenu.append(snesPort1); - for(auto &item : snesPort1Device) snesPort1.append(item); - snesMenu.append(snesPort2); - for(auto &item : snesPort2Device) snesPort2.append(item); - snesMenu.append(snesSeparator2); - snesMenu.append(snesCartridgeUnload); - - append(gameBoyMenu); - gameBoyMenu.append(gameBoyPower); - gameBoyMenu.append(gameBoySeparator); - gameBoyMenu.append(gameBoyCartridgeUnload); - - append(gameBoyAdvanceMenu); - gameBoyAdvanceMenu.append(gameBoyAdvancePower); - gameBoyAdvanceMenu.append(gameBoyAdvanceSeparator); - gameBoyAdvanceMenu.append(gameBoyAdvanceCartridgeUnload); - - append(settingsMenu); - settingsMenu.append(settingsVideoFilter); - settingsVideoFilter.append(settingsVideoFilterNone); - if(videoFilterName.size()) - settingsVideoFilter.append(settingsVideoFilterSeparator); - for(unsigned n = 0; n < videoFilterName.size(); n++) - settingsVideoFilter.append(settingsVideoFilterList[n]); - settingsMenu.append(settingsVideoShader); - settingsVideoShader.append(settingsVideoShaderNone); - settingsVideoShader.append(settingsVideoShaderBlur); - if(videoShaderName.size()) - settingsVideoShader.append(settingsVideoShaderSeparator); - for(unsigned n = 0; n < videoShaderName.size(); n++) - settingsVideoShader.append(settingsVideoShaderList[n]); - settingsMenu.append(settingsSeparator1); - settingsMenu.append(settingsSynchronizeVideo); - settingsMenu.append(settingsSynchronizeAudio); - settingsMenu.append(settingsSeparator2); - settingsMenu.append(settingsCorrectAspectRatio); - settingsMenu.append(settingsMaskOverscan); - settingsMenu.append(settingsMuteAudio); - settingsMenu.append(settingsSeparator3); - settingsMenu.append(settingsConfiguration); - - append(toolsMenu); - toolsMenu.append(toolsStateSave); - toolsStateSave.append(toolsStateSave1); - toolsStateSave.append(toolsStateSave2); - toolsStateSave.append(toolsStateSave3); - toolsStateSave.append(toolsStateSave4); - toolsStateSave.append(toolsStateSave5); - toolsMenu.append(toolsStateLoad); - toolsStateLoad.append(toolsStateLoad1); - toolsStateLoad.append(toolsStateLoad2); - toolsStateLoad.append(toolsStateLoad3); - toolsStateLoad.append(toolsStateLoad4); - toolsStateLoad.append(toolsStateLoad5); - toolsMenu.append(toolsSeparator); - toolsMenu.append(toolsInformationWindow); - toolsMenu.append(toolsShrinkWindow); - toolsMenu.append(toolsCheatEditor); - toolsMenu.append(toolsStateManager); - - setMenuVisible(); - - setStatusText("No cartridge loaded"); - setStatusVisible(); - - layout.append(viewport, { 0, 0, 512, 480 }); - append(layout); - - onClose = [&] { application->quit = true; }; - onSize = [&] { utility->resizeMainWindow(); }; - - cartridgeLoadNES.onActivate = [&] { - fileBrowser->open("Load Cartridge - Famicom", FileBrowser::Mode::NES, [](string filename) { - interface->nes.loadCartridge(filename); - }); - }; - - cartridgeLoadSNES.onActivate = [&] { - fileBrowser->open("Load Cartridge - Super Famicom", FileBrowser::Mode::SNES, [](string filename) { - string filedata; - filedata.readfile({dir(filename),"manifest.xml"}); - XML::Document document(filedata); - if(document["cartridge"]["bsx"]["slot"].exists() - && MessageWindow::question(*mainWindow, "Load BS-X Satellaview data pack?") == MessageWindow::Response::Yes) { - mainWindow->filename = filename; - fileBrowser->open("Load Cartridge - BS-X Satellaview", FileBrowser::Mode::Satellaview, [](string filename) { - interface->snes.loadSatellaviewSlottedCartridge(mainWindow->filename, filename); - }); - } else { - interface->snes.loadCartridge(filename); - } - }); - }; - - cartridgeLoadGameBoy.onActivate = [&] { - fileBrowser->open("Load Cartridge - Game Boy", FileBrowser::Mode::GameBoy, [](string filename) { - interface->gb.loadCartridge(GB::System::Revision::GameBoy, filename); - }); - }; - - cartridgeLoadGameBoyColor.onActivate = [&] { - fileBrowser->open("Load Cartridge - Game Boy Color", FileBrowser::Mode::GameBoyColor, [](string filename) { - interface->gb.loadCartridge(GB::System::Revision::GameBoyColor, filename); - }); - }; - - cartridgeLoadGameBoyAdvance.onActivate = [&] { - fileBrowser->open("Load Cartridge - Game Boy Advance", FileBrowser::Mode::GameBoyAdvance, [](string filename) { - interface->gba.loadCartridge(filename); - }); - }; - - cartridgeLoadSuperGameBoy.onActivate = [&] { - fileBrowser->open("Load Cartridge - Super Game Boy", FileBrowser::Mode::GameBoy, [](string filename) { - interface->snes.loadSuperGameBoyCartridge(application->path("Super Game Boy.sfc/"), filename); - }); - }; - - cartridgeLoadSatellaview.onActivate = [&] { - fileBrowser->open("Load Cartridge - BS-X Satellaview", FileBrowser::Mode::Satellaview, [](string filename) { - interface->snes.loadSatellaviewCartridge(application->path("BS-X Satellaview.sfc/"), filename); - }); - }; - - cartridgeLoadSufamiTurbo.onActivate = [&] { - fileBrowser->open("Load Cartridge - Sufami Turbo", FileBrowser::Mode::SufamiTurbo, [](string filename) { - string filedata; - filedata.readfile({dir(filename),"manifest.xml"}); - XML::Document document(filedata); - if(document["cartridge"]["linkable"].data == "true" - && MessageWindow::question(*mainWindow, "Load linkable cartridge?") == MessageWindow::Response::Yes) { - mainWindow->filename = filename; - fileBrowser->open("Load Cartridge - Sufami Turbo", FileBrowser::Mode::SufamiTurbo, [](string filename) { - if(mainWindow->filename == filename) { - MessageWindow::critical(*mainWindow, "It is physically impossible to have the same cartridge in two slots at the same time."); - } else { - interface->snes.loadSufamiTurboCartridge(application->path("Sufami Turbo.sfc/"), mainWindow->filename, filename); - } - }); - } else { - interface->snes.loadSufamiTurboCartridge(application->path("Sufami Turbo.sfc/"), filename, ""); - } - }); - }; - - nesPower.onActivate = { &Interface::power, interface }; - nesReset.onActivate = { &Interface::reset, interface }; - - nesPort1Device[0].onActivate = [&] { interface->setController(0, 0); }; - nesPort1Device[1].onActivate = [&] { interface->setController(0, 1); }; - - nesPort2Device[0].onActivate = [&] { interface->setController(1, 0); }; - nesPort2Device[1].onActivate = [&] { interface->setController(1, 1); }; - - nesCartridgeUnload.onActivate = { &Interface::unloadCartridge, interface }; - - snesPower.onActivate = { &Interface::power, interface }; - snesReset.onActivate = { &Interface::reset, interface }; - - snesPort1Device[0].onActivate = [&] { interface->setController(0, 0); }; - snesPort1Device[1].onActivate = [&] { interface->setController(0, 1); }; - snesPort1Device[2].onActivate = [&] { interface->setController(0, 2); }; - snesPort1Device[3].onActivate = [&] { interface->setController(0, 3); }; - snesPort1Device[4].onActivate = [&] { interface->setController(0, 4); }; - - snesPort2Device[0].onActivate = [&] { interface->setController(1, 0); }; - snesPort2Device[1].onActivate = [&] { interface->setController(1, 1); }; - snesPort2Device[2].onActivate = [&] { interface->setController(1, 2); }; - snesPort2Device[3].onActivate = [&] { interface->setController(1, 3); }; - snesPort2Device[4].onActivate = [&] { interface->setController(1, 4); }; - snesPort2Device[5].onActivate = [&] { interface->setController(1, 5); }; - snesPort2Device[6].onActivate = [&] { interface->setController(1, 6); }; - snesPort2Device[7].onActivate = [&] { interface->setController(1, 7); }; - - snesCartridgeUnload.onActivate = { &Interface::unloadCartridge, interface }; - - gameBoyPower.onActivate = { &Interface::power, interface }; - gameBoyCartridgeUnload.onActivate = { &Interface::unloadCartridge, interface }; - - gameBoyAdvancePower.onActivate = { &Interface::power, interface }; - gameBoyAdvanceCartridgeUnload.onActivate = { &Interface::unloadCartridge, interface }; - - settingsVideoFilterNone.onActivate = [&] { - config->video.filter = "None"; - utility->bindVideoFilter(); - }; - - settingsVideoShaderNone.onActivate = [&] { - config->video.shader = "None"; - utility->bindVideoShader(); - }; - - settingsVideoShaderBlur.onActivate = [&] { - config->video.shader = "Blur"; - utility->bindVideoShader(); - }; - - settingsSynchronizeVideo.onToggle = [&] { - config->video.synchronize = settingsSynchronizeVideo.checked(); - video.set(Video::Synchronize, config->video.synchronize); - }; - - settingsSynchronizeAudio.onToggle = [&] { - config->audio.synchronize = settingsSynchronizeAudio.checked(); - audio.set(Audio::Synchronize, config->audio.synchronize); - }; - - settingsCorrectAspectRatio.onToggle = [&] { - config->video.correctAspectRatio = settingsCorrectAspectRatio.checked(); - utility->resizeMainWindow(); - }; - - settingsMaskOverscan.onToggle = [&] { - config->video.maskOverscan = settingsMaskOverscan.checked(); - }; - - settingsMuteAudio.onToggle = [&] { - config->audio.mute = settingsMuteAudio.checked(); - dspaudio.setVolume(config->audio.mute == false ? (double)config->audio.volume / 100.0 : 0.0); - }; - - settingsConfiguration.onActivate = [&] { settingsWindow->setVisible(); }; - - toolsStateSave1.onActivate = [&] { interface->saveState(1); }; - toolsStateSave2.onActivate = [&] { interface->saveState(2); }; - toolsStateSave3.onActivate = [&] { interface->saveState(3); }; - toolsStateSave4.onActivate = [&] { interface->saveState(4); }; - toolsStateSave5.onActivate = [&] { interface->saveState(5); }; - - toolsStateLoad1.onActivate = [&] { interface->loadState(1); }; - toolsStateLoad2.onActivate = [&] { interface->loadState(2); }; - toolsStateLoad3.onActivate = [&] { interface->loadState(3); }; - toolsStateLoad4.onActivate = [&] { interface->loadState(4); }; - toolsStateLoad5.onActivate = [&] { interface->loadState(5); }; - - toolsInformationWindow.onActivate = [&] { informationWindow->setVisible(); }; - toolsShrinkWindow.onActivate = [&] { utility->resizeMainWindow(true); }; - toolsCheatEditor.onActivate = [&] { cheatEditor->setVisible(); }; - toolsStateManager.onActivate = [&] { stateManager->setVisible(); }; - - synchronize(); -} - -void MainWindow::synchronize() { - bool enable = interface->cartridgeLoaded(); - toolsStateSave.setEnabled(enable); - toolsStateLoad.setEnabled(enable); - toolsInformationWindow.setEnabled(enable); -} - -void MainWindow::setupVideoFilters() { - string path = { application->basepath, "filters/" }; - lstring files = directory::files(path, "*.filter"); - if(files.size() == 0) { - path = { application->userpath, "filters/" }; - files = directory::files(path, "*.filter"); - } - set group; - - settingsVideoFilterList = new RadioItem[files.size()]; - for(unsigned n = 0; n < files.size(); n++) { - string name = files[n]; - videoFilterName.append({ path, name }); - if(auto position = name.position(".filter")) name[position()] = 0; - - settingsVideoFilterList[n].setText(name); - settingsVideoFilterList[n].onActivate = [&, n] { - config->video.filter = videoFilterName[n]; - utility->bindVideoFilter(); - }; - } - - group.append(settingsVideoFilterNone); - for(unsigned n = 0; n < files.size(); n++) group.append(settingsVideoFilterList[n]); - RadioItem::group(group); - - if(config->video.filter == "None") settingsVideoFilterNone.setChecked(); - for(unsigned n = 0; n < files.size(); n++) - if(config->video.filter == videoFilterName[n]) settingsVideoFilterList[n].setChecked(); -} - -void MainWindow::setupVideoShaders() { - string path = { application->basepath, "shaders/" }; - lstring files = directory::files(path, { "*.", config->video.driver, ".shader" }); - if(files.size() == 0) { - path = { application->userpath, "shaders/" }; - files = directory::files(path, { "*.", config->video.driver, ".shader" }); - } - set group; - - settingsVideoShaderList = new RadioItem[files.size()]; - for(unsigned n = 0; n < files.size(); n++) { - string name = files[n]; - videoShaderName.append({ path, name }); - if(auto position = name.position(string{ ".", config->video.driver, ".shader" })) name[position()] = 0; - - settingsVideoShaderList[n].setText(name); - settingsVideoShaderList[n].onActivate = [&, n] { - config->video.shader = videoShaderName[n]; - utility->bindVideoShader(); - }; - } - - group.append(settingsVideoShaderNone); - group.append(settingsVideoShaderBlur); - for(unsigned n = 0; n < files.size(); n++) group.append(settingsVideoShaderList[n]); - RadioItem::group(group); - - if(config->video.shader == "None") settingsVideoShaderNone.setChecked(); - if(config->video.shader == "Blur") settingsVideoShaderBlur.setChecked(); - for(unsigned n = 0; n < files.size(); n++) - if(config->video.shader == videoShaderName[n]) settingsVideoShaderList[n].setChecked(); -} diff --git a/bsnes/target-ui/general/main-window.hpp b/bsnes/target-ui/general/main-window.hpp deleted file mode 100755 index bed390a5..00000000 --- a/bsnes/target-ui/general/main-window.hpp +++ /dev/null @@ -1,99 +0,0 @@ -struct MainWindow : Window { - FixedLayout layout; - Viewport viewport; - - Menu cartridgeMenu; - Item cartridgeLoadSNES; - Item cartridgeLoadNES; - Item cartridgeLoadGameBoy; - Item cartridgeLoadGameBoyColor; - Item cartridgeLoadGameBoyAdvance; - Separator cartridgeSeparator; - Item cartridgeLoadSuperGameBoy; - Item cartridgeLoadSatellaview; - Item cartridgeLoadSufamiTurbo; - - Menu nesMenu; - Item nesPower; - Item nesReset; - Separator nesSeparator1; - Menu nesPort1; - RadioItem nesPort1Device[2]; - Menu nesPort2; - RadioItem nesPort2Device[2]; - Separator nesSeparator2; - Item nesCartridgeUnload; - - Menu snesMenu; - Item snesPower; - Item snesReset; - Separator snesSeparator1; - Menu snesPort1; - RadioItem snesPort1Device[5]; - Menu snesPort2; - RadioItem snesPort2Device[8]; - Separator snesSeparator2; - Item snesCartridgeUnload; - - Menu gameBoyMenu; - Item gameBoyPower; - Separator gameBoySeparator; - Item gameBoyCartridgeUnload; - - Menu gameBoyAdvanceMenu; - Item gameBoyAdvancePower; - Separator gameBoyAdvanceSeparator; - Item gameBoyAdvanceCartridgeUnload; - - Menu settingsMenu; - Menu settingsVideoFilter; - RadioItem settingsVideoFilterNone; - Separator settingsVideoFilterSeparator; - RadioItem *settingsVideoFilterList; - Menu settingsVideoShader; - RadioItem settingsVideoShaderNone; - RadioItem settingsVideoShaderBlur; - Separator settingsVideoShaderSeparator; - RadioItem *settingsVideoShaderList; - Separator settingsSeparator1; - CheckItem settingsSynchronizeVideo; - CheckItem settingsSynchronizeAudio; - Separator settingsSeparator2; - CheckItem settingsCorrectAspectRatio; - CheckItem settingsMaskOverscan; - CheckItem settingsMuteAudio; - Separator settingsSeparator3; - Item settingsConfiguration; - - Menu toolsMenu; - Menu toolsStateSave; - Item toolsStateSave1; - Item toolsStateSave2; - Item toolsStateSave3; - Item toolsStateSave4; - Item toolsStateSave5; - Menu toolsStateLoad; - Item toolsStateLoad1; - Item toolsStateLoad2; - Item toolsStateLoad3; - Item toolsStateLoad4; - Item toolsStateLoad5; - Separator toolsSeparator; - Item toolsInformationWindow; - Item toolsShrinkWindow; - Item toolsCheatEditor; - Item toolsStateManager; - - void synchronize(); - MainWindow(); - -private: - lstring videoFilterName; - lstring videoShaderName; - string filename; - - void setupVideoFilters(); - void setupVideoShaders(); -}; - -extern MainWindow *mainWindow; diff --git a/bsnes/target-ui/input/gb.cpp b/bsnes/target-ui/input/gb.cpp deleted file mode 100755 index 5720d42f..00000000 --- a/bsnes/target-ui/input/gb.cpp +++ /dev/null @@ -1,53 +0,0 @@ -int16_t GbController::poll(unsigned n) { - switch(n) { - case 0: return up.poll() & !down.poll(); - case 1: return down.poll() & !up.poll(); - case 2: return left.poll() & !right.poll(); - case 3: return right.poll() & !left.poll(); - case 4: return b.poll() | bTurbo.poll(); - case 5: return a.poll() | aTurbo.poll(); - case 6: return select.poll(); - case 7: return start.poll(); - } - return 0; -} - -GbController::GbController() { - name = "Controller"; - - up.name = "Up"; - down.name = "Down"; - left.name = "Left"; - right.name = "Right"; - b.name = "B"; - a.name = "A"; - select.name = "Select"; - start.name = "Start"; - bTurbo.name = "Turbo B"; - aTurbo.name = "Turbo A"; - - up.mapping = "KB0::Up"; - down.mapping = "KB0::Down"; - left.mapping = "KB0::Left"; - right.mapping = "KB0::Right"; - b.mapping = "KB0::Z"; - a.mapping = "KB0::X"; - select.mapping = "KB0::Apostrophe"; - start.mapping = "KB0::Return"; - - append(up, down, left, right, b, a, select, start, bTurbo, aTurbo); -} - -// - -GbDevice::GbDevice() { - name = "Device"; - append(controller); -} - -// - -GbInput::GbInput() { - name = "Game Boy"; - append(device); -} diff --git a/bsnes/target-ui/input/gb.hpp b/bsnes/target-ui/input/gb.hpp deleted file mode 100755 index 8ebe9d2a..00000000 --- a/bsnes/target-ui/input/gb.hpp +++ /dev/null @@ -1,20 +0,0 @@ -struct GbController : TertiaryInput { - DigitalInput up, down, left, right; - DigitalInput b, a, select, start; - TurboInput bTurbo, aTurbo; - - int16_t poll(unsigned n); - GbController(); -}; - -struct GbDevice : SecondaryInput { - GbController controller; - - GbDevice(); -}; - -struct GbInput : PrimaryInput { - GbDevice device; - - GbInput(); -}; diff --git a/bsnes/target-ui/input/gba.cpp b/bsnes/target-ui/input/gba.cpp deleted file mode 100755 index 43440070..00000000 --- a/bsnes/target-ui/input/gba.cpp +++ /dev/null @@ -1,64 +0,0 @@ -int16_t GbaController::poll(unsigned n) { - switch((GBA::Input)n) { - case GBA::Input::Up: return up.poll() & !down.poll(); - case GBA::Input::Down: return down.poll() & !up.poll(); - case GBA::Input::Left: return left.poll() & !right.poll(); - case GBA::Input::Right: return right.poll() & !left.poll(); - case GBA::Input::B: return b.poll() | bTurbo.poll(); - case GBA::Input::A: return a.poll() | aTurbo.poll(); - case GBA::Input::L: return l.poll() | lTurbo.poll(); - case GBA::Input::R: return r.poll() | rTurbo.poll(); - case GBA::Input::Select: return select.poll(); - case GBA::Input::Start: return start.poll(); - } - - return 0; //never reached -} - -GbaController::GbaController() { - name = "Controller"; - - up.name = "Up"; - down.name = "Down"; - left.name = "Left"; - right.name = "Right"; - b.name = "B"; - a.name = "A"; - l.name = "L"; - r.name = "R"; - select.name = "Select"; - start.name = "Start"; - - bTurbo.name = "Turbo B"; - aTurbo.name = "Turbo A"; - lTurbo.name = "Turbo L"; - rTurbo.name = "Turbo R"; - - up.mapping = "KB0::Up"; - down.mapping = "KB0::Down"; - left.mapping = "KB0::Left"; - right.mapping = "KB0::Right"; - b.mapping = "KB0::Z"; - a.mapping = "KB0::X"; - l.mapping = "KB0::A"; - r.mapping = "KB0::S"; - select.mapping = "KB0::Apostrophe"; - start.mapping = "KB0::Return"; - - append(up, down, left, right, b, a, l, r, select, start); - append(bTurbo, aTurbo, lTurbo, rTurbo); -} - -// - -GbaDevice::GbaDevice() { - name = "Device"; - append(controller); -} - -// - -GbaInput::GbaInput() { - name = "Game Boy Advance"; - append(device); -} diff --git a/bsnes/target-ui/input/gba.hpp b/bsnes/target-ui/input/gba.hpp deleted file mode 100755 index 726b4cb6..00000000 --- a/bsnes/target-ui/input/gba.hpp +++ /dev/null @@ -1,21 +0,0 @@ -struct GbaController : TertiaryInput { - DigitalInput up, down, left, right; - DigitalInput b, a, l, r; - DigitalInput select, start; - TurboInput bTurbo, aTurbo, lTurbo, rTurbo; - - int16_t poll(unsigned n); - GbaController(); -}; - -struct GbaDevice : SecondaryInput { - GbaController controller; - - GbaDevice(); -}; - -struct GbaInput : PrimaryInput { - GbaDevice device; - - GbaInput(); -}; diff --git a/bsnes/target-ui/input/input.cpp b/bsnes/target-ui/input/input.cpp deleted file mode 100755 index 33cd49d3..00000000 --- a/bsnes/target-ui/input/input.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include "../base.hpp" -#include "nes.cpp" -#include "snes.cpp" -#include "gb.cpp" -#include "gba.cpp" -#include "user-interface.cpp" -InputManager *inputManager = nullptr; - -void AbstractInput::attach(const string &primaryName, const string &secondaryName, const string &tertiaryName) { - string name = { primaryName, "::", secondaryName, "::", tertiaryName, "::", this->name }; - name.replace(" ", ""); - inputManager->config.attach(mapping, name); -} - -void AbstractInput::bind() { - if(mapping == "") type = Type::Button, mapping = "None"; - - if(mapping.endswith(".Up")) type = Type::HatUp; - else if(mapping.endswith(".Down")) type = Type::HatDown; - else if(mapping.endswith(".Left")) type = Type::HatLeft; - else if(mapping.endswith(".Right")) type = Type::HatRight; - else if(mapping.endswith(".Lo")) type = Type::AxisLo; - else if(mapping.endswith(".Hi")) type = Type::AxisHi; - else if(mapping.beginswith("JP") && mapping.position("Axis")) type = Type::Axis; - else if(mapping.beginswith("MS") && mapping.endswith("axis")) type = Type::MouseAxis; - else if(mapping.beginswith("MS")) type = Type::MouseButton; - else type = Type::Button; - - string decode = mapping; - if(auto position = decode.position(".")) decode[position()] = 0; - scancode = Scancode::decode(decode); -} - -int16_t AbstractInput::poll() { - if(config->input.focusPolicy == 1 && mainWindow->focused() == false) return 0; - return inputManager->scancode[inputManager->activeScancode][scancode]; -} - -// - -bool AnalogInput::bind(int16_t scancode, int16_t value) { - using nall::Mouse; - string encode = Scancode::encode(scancode); - Type type = Type::Button; - - if(scancode == Scancode::None) goto bind; - if(Mouse::isAnyAxis(scancode)) { type = Type::MouseAxis; goto bind; } - if(Joypad::isAnyAxis(scancode)) { type = Type::Axis; goto bind; } - - return false; - -bind: - mapping = encode; - this->scancode = scancode; - this->type = Type::Axis; - return true; -} - -int16_t AnalogInput::poll() { - int16_t value = AbstractInput::poll(); - switch(type) { - case Type::MouseAxis: return input.acquired() ? value : 0; - case Type::Axis: return value; - } - return 0; -} - -// - -bool DigitalInput::bind(int16_t scancode, int16_t value) { - using nall::Keyboard; - using nall::Mouse; - string encode = Scancode::encode(scancode); - Type type = Type::Button; - - if(scancode == Scancode::None) goto bind; - - if(Keyboard::isAnyKey(scancode) || Keyboard::isAnyModifier(scancode) || Joypad::isAnyButton(scancode)) { - if(value == 0) return false; - type = Type::Button; - goto bind; - } - - if(Mouse::isAnyButton(scancode)) { - if(value == 0) return false; - type = Type::MouseButton; - goto bind; - } - - if(Joypad::isAnyHat(scancode)) { - if(value & Joypad::HatUp ) { type = Type::HatUp; encode.append(".Up" ); goto bind; } - if(value & Joypad::HatDown ) { type = Type::HatDown; encode.append(".Down" ); goto bind; } - if(value & Joypad::HatLeft ) { type = Type::HatLeft; encode.append(".Left" ); goto bind; } - if(value & Joypad::HatRight) { type = Type::HatRight; encode.append(".Right"); goto bind; } - } - - if(Joypad::isAnyAxis(scancode)) { - if(value < -12288) { type = Type::AxisLo; encode.append(".Lo"); goto bind; } - if(value > +24576) { type = Type::AxisHi; encode.append(".Hi"); goto bind; } - } - - return false; - -bind: - mapping = encode; - this->scancode = scancode; - this->type = type; - return true; -} - -int16_t DigitalInput::poll() { - int16_t value = AbstractInput::poll(); - switch(type) { - case Type::Button: return (bool)(value); - case Type::MouseButton: return (bool)(value & input.acquired()); - case Type::HatUp: return (bool)(value & Joypad::HatUp); - case Type::HatDown: return (bool)(value & Joypad::HatDown); - case Type::HatLeft: return (bool)(value & Joypad::HatLeft); - case Type::HatRight: return (bool)(value & Joypad::HatRight); - case Type::AxisLo: return (bool)(value < -16384); - case Type::AxisHi: return (bool)(value > +16384); - } - return 0; -} - -// - -int16_t TurboInput::poll() { - int16_t result = DigitalInput::poll(); - if(phase < 3) result = 0; - if(++phase >= 6) phase = 0; - return result; -} - -TurboInput::TurboInput() : phase(0) { -} - -// - -void TertiaryInput::attach(const string &primaryName, const string &secondaryName) { - for(unsigned n = 0; n < size(); n++) { - operator[](n).attach(primaryName, secondaryName, name); - } -} - -void TertiaryInput::bind() { - for(unsigned n = 0; n < size(); n++) { - operator[](n).bind(); - } -} - -int16_t TertiaryInput::poll(unsigned n) { - return operator[](n).poll(); -} - -// - -void SecondaryInput::attach(const string &primaryName) { - for(unsigned n = 0; n < size(); n++) { - operator[](n).attach(primaryName, name); - } -} - -void SecondaryInput::bind() { - for(unsigned n = 0; n < size(); n++) { - operator[](n).bind(); - } -} - -// - -void PrimaryInput::attach() { - for(unsigned n = 0; n < size(); n++) { - operator[](n).attach(name); - } -} - -void PrimaryInput::bind() { - for(unsigned n = 0; n < size(); n++) { - operator[](n).bind(); - } -} - -// - -void InputManager::scan() { - activeScancode = !activeScancode; - input.poll(scancode[activeScancode]); - - for(unsigned n = 0; n < Scancode::Limit; n++) { - if(scancode[!activeScancode][n] != scancode[activeScancode][n]) { - if(settingsWindow->focused()) inputSettings->inputEvent(n, scancode[activeScancode][n]); - if(mainWindow->focused()) userInterface.inputEvent(n, scancode[activeScancode][n]); - } - } -} - -InputManager::InputManager() { - inputManager = this; - - inputList.append(nes); - inputList.append(snes); - inputList.append(gb); - inputList.append(gba); - inputList.append(userInterface); - - for(unsigned n = 0; n < inputList.size(); n++) inputList[n].attach(); - config.load(application->path("input.cfg")); - config.save(application->path("input.cfg")); - for(unsigned n = 0; n < inputList.size(); n++) inputList[n].bind(); - - activeScancode = 0; -} - -InputManager::~InputManager() { - config.save(application->path("input.cfg")); -} diff --git a/bsnes/target-ui/input/input.hpp b/bsnes/target-ui/input/input.hpp deleted file mode 100755 index b60d7bce..00000000 --- a/bsnes/target-ui/input/input.hpp +++ /dev/null @@ -1,75 +0,0 @@ -struct AbstractInput { - enum class Type : unsigned { Button, MouseButton, MouseAxis, HatUp, HatDown, HatLeft, HatRight, Axis, AxisLo, AxisHi } type; - string name; - string mapping; - unsigned scancode; - - virtual void attach(const string &primaryName, const string &secondaryName, const string &tertiaryName); - virtual void bind(); - virtual bool bind(int16_t scancode, int16_t value) = 0; - virtual int16_t poll(); -}; - -struct AnalogInput : AbstractInput { - bool bind(int16_t scancode, int16_t value); - int16_t poll(); -}; - -struct DigitalInput : AbstractInput { - bool bind(int16_t scancode, int16_t value); - int16_t poll(); -}; - -struct TurboInput : DigitalInput { - unsigned phase; - - int16_t poll(); - TurboInput(); -}; - -struct TertiaryInput : set { - string name; - - virtual void attach(const string &primaryName, const string &secondaryName); - virtual void bind(); - virtual int16_t poll(unsigned n); -}; - -struct SecondaryInput : set { - string name; - - virtual void attach(const string &primaryName); - virtual void bind(); -}; - -struct PrimaryInput : set { - string name; - - virtual void attach(); - virtual void bind(); -}; - -#include "nes.hpp" -#include "snes.hpp" -#include "gb.hpp" -#include "gba.hpp" -#include "user-interface.hpp" - -struct InputManager { - configuration config; - int16_t scancode[2][Scancode::Limit]; - bool activeScancode; - - set inputList; - NesInput nes; - SnesInput snes; - GbInput gb; - GbaInput gba; - UserInterfaceInput userInterface; - - void scan(); - InputManager(); - ~InputManager(); -}; - -extern InputManager *inputManager; diff --git a/bsnes/target-ui/input/nes.cpp b/bsnes/target-ui/input/nes.cpp deleted file mode 100755 index 96b0f40e..00000000 --- a/bsnes/target-ui/input/nes.cpp +++ /dev/null @@ -1,60 +0,0 @@ -int16_t NesGamepad::poll(unsigned n) { - switch(n) { - case 0: return a.poll() | aTurbo.poll(); - case 1: return b.poll() | bTurbo.poll(); - case 2: return select.poll(); - case 3: return start.poll(); - case 4: return up.poll() & !down.poll(); - case 5: return down.poll() & !up.poll(); - case 6: return left.poll() & !right.poll(); - case 7: return right.poll() & !left.poll(); - } - return 0; -} - -NesGamepad::NesGamepad() { - name = "Gamepad"; - - up.name = "Up"; - down.name = "Down"; - left.name = "Left"; - right.name = "Right"; - b.name = "B"; - a.name = "A"; - select.name = "Select"; - start.name = "Start"; - bTurbo.name = "Turbo B"; - aTurbo.name = "Turbo A"; - - up.mapping = "KB0::Up"; - down.mapping = "KB0::Down"; - left.mapping = "KB0::Left"; - right.mapping = "KB0::Right"; - b.mapping = "KB0::Z"; - a.mapping = "KB0::X"; - select.mapping = "KB0::Apostrophe"; - start.mapping = "KB0::Return"; - - append(up, down, left, right, b,a, select, start, bTurbo, aTurbo); -} - -// - -NesPort1Input::NesPort1Input() { - name = "Controller Port 1"; - append(gamepad); -} - -// - -NesPort2Input::NesPort2Input() { - name = "Controller Port 2"; - append(gamepad); -} - -// - -NesInput::NesInput() { - name = "Famicom"; - append(port1, port2); -} diff --git a/bsnes/target-ui/input/nes.hpp b/bsnes/target-ui/input/nes.hpp deleted file mode 100755 index b3199e27..00000000 --- a/bsnes/target-ui/input/nes.hpp +++ /dev/null @@ -1,27 +0,0 @@ -struct NesGamepad : TertiaryInput { - DigitalInput up, down, left, right; - DigitalInput b, a, select, start; - TurboInput bTurbo, aTurbo; - - int16_t poll(unsigned n); - NesGamepad(); -}; - -struct NesPort1Input : SecondaryInput { - NesGamepad gamepad; - - NesPort1Input(); -}; - -struct NesPort2Input : SecondaryInput { - NesGamepad gamepad; - - NesPort2Input(); -}; - -struct NesInput : PrimaryInput { - NesPort1Input port1; - NesPort2Input port2; - - NesInput(); -}; diff --git a/bsnes/target-ui/input/snes.cpp b/bsnes/target-ui/input/snes.cpp deleted file mode 100755 index 0b558510..00000000 --- a/bsnes/target-ui/input/snes.cpp +++ /dev/null @@ -1,184 +0,0 @@ -int16_t SnesGamepad::poll(unsigned n) { - switch((SFC::Input::JoypadID)n) { - case SFC::Input::JoypadID::Up: return up.poll() & !down.poll(); - case SFC::Input::JoypadID::Down: return down.poll() & !up.poll(); - case SFC::Input::JoypadID::Left: return left.poll() & !right.poll(); - case SFC::Input::JoypadID::Right: return right.poll() & !left.poll(); - case SFC::Input::JoypadID::B: return b.poll() | bTurbo.poll(); - case SFC::Input::JoypadID::A: return a.poll() | aTurbo.poll(); - case SFC::Input::JoypadID::Y: return y.poll() | yTurbo.poll(); - case SFC::Input::JoypadID::X: return x.poll() | xTurbo.poll(); - case SFC::Input::JoypadID::L: return l.poll() | lTurbo.poll(); - case SFC::Input::JoypadID::R: return r.poll() | rTurbo.poll(); - case SFC::Input::JoypadID::Select: return select.poll(); - case SFC::Input::JoypadID::Start: return start.poll(); - } - return 0; -} - -SnesGamepad::SnesGamepad(const string &name, bool defaultBindings) { - this->name = name; - - up.name = "Up", down.name = "Down", left.name = "Left", right.name = "Right"; - b.name = "B", a.name = "A", y.name = "Y", x.name = "X"; - l.name = "L", r.name = "R", select.name = "Select", start.name = "Start"; - bTurbo.name = "Turbo B", aTurbo.name = "Turbo A", yTurbo.name = "Turbo Y", xTurbo.name = "Turbo X"; - lTurbo.name = "Turbo L", rTurbo.name = "Turbo R"; - - if(defaultBindings) { - up.mapping = "KB0::Up"; - down.mapping = "KB0::Down"; - left.mapping = "KB0::Left"; - right.mapping = "KB0::Right"; - b.mapping = "KB0::Z"; - a.mapping = "KB0::X"; - y.mapping = "KB0::A"; - x.mapping = "KB0::S"; - l.mapping = "KB0::D"; - r.mapping = "KB0::C"; - select.mapping = "KB0::Apostrophe"; - start.mapping = "KB0::Return"; - } - - append(up, down, left, right, b, a, y, x, l, r, select, start); - append(bTurbo, aTurbo, yTurbo, xTurbo, lTurbo, rTurbo); -} - -// - -int16_t SnesMouse::poll(unsigned n) { - switch((SFC::Input::MouseID)n) { - case SFC::Input::MouseID::X: return xaxis.poll(); - case SFC::Input::MouseID::Y: return yaxis.poll(); - case SFC::Input::MouseID::Left: return left.poll(); - case SFC::Input::MouseID::Right: return right.poll(); - } - return 0; -} - -SnesMouse::SnesMouse(const string &name, bool defaultBindings) { - this->name = name; - - xaxis.name = "X-axis", yaxis.name = "Y-axis"; - left.name = "Left button", right.name = "Right button"; - - if(defaultBindings) { - xaxis.mapping = "MS0::Xaxis"; - yaxis.mapping = "MS0::Yaxis"; - left.mapping = "MS0::Button0"; - right.mapping = "MS0::Button2"; - } - - append(xaxis, yaxis, left, right); -} - -// - -int16_t SnesSuperScope::poll(unsigned n) { - switch((SFC::Input::SuperScopeID)n) { - case SFC::Input::SuperScopeID::X: return xaxis.poll(); - case SFC::Input::SuperScopeID::Y: return yaxis.poll(); - case SFC::Input::SuperScopeID::Trigger: return trigger.poll(); - case SFC::Input::SuperScopeID::Cursor: return cursor.poll(); - case SFC::Input::SuperScopeID::Turbo: return turbo.poll(); - case SFC::Input::SuperScopeID::Pause: return pause.poll(); - } - return 0; -} - -SnesSuperScope::SnesSuperScope(const string &name, bool defaultBindings) { - this->name = name; - - xaxis.name = "X-axis", yaxis.name = "Y-axis"; - trigger.name = "Trigger", cursor.name = "Cursor", turbo.name = "Turbo", pause.name = "Pause"; - - if(defaultBindings) { - xaxis.mapping = "MS0::Xaxis"; - yaxis.mapping = "MS0::Yaxis"; - trigger.mapping = "MS0::Button0"; - cursor.mapping = "MS0::Button2"; - turbo.mapping = "KB0::T"; - pause.mapping = "KB0::P"; - } - - append(xaxis, yaxis, trigger, cursor, turbo, pause); -} - -// - -int16_t SnesJustifier::poll(unsigned n) { - switch((SFC::Input::JustifierID)n) { - case SFC::Input::JustifierID::X: return xaxis.poll(); - case SFC::Input::JustifierID::Y: return yaxis.poll(); - case SFC::Input::JustifierID::Trigger: return trigger.poll(); - case SFC::Input::JustifierID::Start: return start.poll(); - } - return 0; -} - -SnesJustifier::SnesJustifier(const string &name, bool defaultBindings) { - this->name = name; - - xaxis.name = "X-axis", yaxis.name = "Y-axis"; - trigger.name = "Trigger", start.name = "Start"; - - if(defaultBindings) { - xaxis.mapping = "MS0::Xaxis"; - yaxis.mapping = "MS0::Yaxis"; - trigger.mapping = "MS0::Button0"; - start.mapping = "MS0::Button2"; - } - - append(xaxis, yaxis, trigger, start); -} - -// - -SnesPort1Input::SnesPort1Input(): -gamepad("Gamepad", true), -multitap1("Multitap - Port 1", false), -multitap2("Multitap - Port 2", false), -multitap3("Multitap - Port 3", false), -multitap4("Multitap - Port 4", false), -mouse("Mouse", true) -{ - name = "Controller Port 1"; - append(gamepad); - append(multitap1); - append(multitap2); - append(multitap3); - append(multitap4); - append(mouse); -} - -// - -SnesPort2Input::SnesPort2Input(): -gamepad("Gamepad", false), -multitap1("Multitap - Port 1", false), -multitap2("Multitap - Port 2", false), -multitap3("Multitap - Port 3", false), -multitap4("Multitap - Port 4", false), -mouse("Mouse", true), -superScope("Super Scope", true), -justifier1("Justifier - Port 1", true), -justifier2("Justifier - Port 2", false) -{ - name = "Controller Port 2"; - append(gamepad); - append(multitap1); - append(multitap2); - append(multitap3); - append(multitap4); - append(mouse); - append(superScope); - append(justifier1); - append(justifier2); -} - -// - -SnesInput::SnesInput() { - name = "Super Famicom"; - append(port1, port2); -} diff --git a/bsnes/target-ui/input/snes.hpp b/bsnes/target-ui/input/snes.hpp deleted file mode 100755 index a9e343a2..00000000 --- a/bsnes/target-ui/input/snes.hpp +++ /dev/null @@ -1,66 +0,0 @@ -struct SnesGamepad : TertiaryInput { - DigitalInput up, down, left, right; - DigitalInput b, a, y, x; - DigitalInput l, r, select, start; - TurboInput bTurbo, aTurbo, yTurbo, xTurbo; - TurboInput lTurbo, rTurbo; - - int16_t poll(unsigned n); - SnesGamepad(const string &name, bool defaultBindings); -}; - -struct SnesMouse : TertiaryInput { - AnalogInput xaxis, yaxis; - DigitalInput left, right; - - int16_t poll(unsigned n); - SnesMouse(const string &name, bool defaultBindings); -}; - -struct SnesSuperScope : TertiaryInput { - AnalogInput xaxis, yaxis; - DigitalInput trigger, cursor, turbo, pause; - - int16_t poll(unsigned n); - SnesSuperScope(const string &name, bool defaultBindings); -}; - -struct SnesJustifier : TertiaryInput { - AnalogInput xaxis, yaxis; - DigitalInput trigger, start; - - int16_t poll(unsigned n); - SnesJustifier(const string &name, bool defaultBindings); -}; - -struct SnesPort1Input : SecondaryInput { - SnesGamepad gamepad; - SnesGamepad multitap1; - SnesGamepad multitap2; - SnesGamepad multitap3; - SnesGamepad multitap4; - SnesMouse mouse; - - SnesPort1Input(); -}; - -struct SnesPort2Input : SecondaryInput { - SnesGamepad gamepad; - SnesGamepad multitap1; - SnesGamepad multitap2; - SnesGamepad multitap3; - SnesGamepad multitap4; - SnesMouse mouse; - SnesSuperScope superScope; - SnesJustifier justifier1; - SnesJustifier justifier2; - - SnesPort2Input(); -}; - -struct SnesInput : PrimaryInput { - SnesPort1Input port1; - SnesPort2Input port2; - - SnesInput(); -}; diff --git a/bsnes/target-ui/input/user-interface.cpp b/bsnes/target-ui/input/user-interface.cpp deleted file mode 100755 index 90ce26d2..00000000 --- a/bsnes/target-ui/input/user-interface.cpp +++ /dev/null @@ -1,116 +0,0 @@ -void HotkeyGeneral::inputEvent(int16_t scancode, int16_t value) { - if(scancode == saveState.scancode && value) { - interface->saveState(activeSlot); - } - - if(scancode == loadState.scancode && value) { - interface->loadState(activeSlot); - } - - if(scancode == decrementSlot.scancode && value) { - if(--activeSlot == 0) activeSlot = 5; - utility->showMessage({ "Selected slot ", activeSlot }); - } - - if(scancode == incrementSlot.scancode && value) { - if(++activeSlot == 6) activeSlot = 1; - utility->showMessage({ "Selected slot ", activeSlot }); - } - - if(scancode == toggleMouseCapture.scancode && value) { - if(mainWindow->fullScreen() == false) { - input.acquired() ? input.unacquire() : input.acquire(); - } - } - - if(scancode == toggleFullScreen.scancode && value) { - utility->toggleFullScreen(); - } - - if(scancode == pause.scancode && value) { - application->pause = !application->pause; - } - - if(scancode == turboMode.scancode) { - if(value) { - video.set(Video::Synchronize, false); - audio.set(Audio::Synchronize, false); - } else { - video.set(Video::Synchronize, config->video.synchronize); - audio.set(Audio::Synchronize, config->audio.synchronize); - } - } - - if(scancode == power.scancode && value) { - interface->power(); - } - - if(scancode == reset.scancode && value) { - interface->reset(); - } - - if(scancode == quit.scancode && value) { - application->quit = true; - } -} - -HotkeyGeneral::HotkeyGeneral() { - name = "General"; - - saveState.name = "Save state"; - loadState.name = "Load state"; - decrementSlot.name = "Decrement state slot"; - incrementSlot.name = "Increment state slot"; - toggleMouseCapture.name = "Toggle mouse capture"; - toggleFullScreen.name = "Toggle fullscreen"; - pause.name = "Pause emulation"; - turboMode.name = "Turbo mode"; - power.name = "Power cycle"; - reset.name = "Reset"; - quit.name = "Close emulator"; - - saveState.mapping = "KB0::F5"; - loadState.mapping = "KB0::F7"; - decrementSlot.mapping = "KB0::F6"; - incrementSlot.mapping = "KB0::F8"; - toggleMouseCapture.mapping = "KB0::F12"; - toggleFullScreen.mapping = "KB0::F11"; - pause.mapping = "KB0::P"; - turboMode.mapping = "KB0::Tilde"; - - append(saveState); - append(loadState); - append(decrementSlot); - append(incrementSlot); - append(toggleMouseCapture); - append(toggleFullScreen); - append(pause); - append(turboMode); - append(power); - append(reset); - append(quit); - - activeSlot = 1; -} - -// - -void HotkeyInput::inputEvent(int16_t scancode, int16_t value) { - general.inputEvent(scancode, value); -} - -HotkeyInput::HotkeyInput() { - name = "Hotkeys"; - append(general); -} - -// - -void UserInterfaceInput::inputEvent(int16_t scancode, int16_t value) { - hotkey.inputEvent(scancode, value); -} - -UserInterfaceInput::UserInterfaceInput() { - name = "User Interface"; - append(hotkey); -} diff --git a/bsnes/target-ui/input/user-interface.hpp b/bsnes/target-ui/input/user-interface.hpp deleted file mode 100755 index 62134c2d..00000000 --- a/bsnes/target-ui/input/user-interface.hpp +++ /dev/null @@ -1,33 +0,0 @@ -struct HotkeyGeneral : TertiaryInput { - DigitalInput saveState; - DigitalInput loadState; - DigitalInput decrementSlot; - DigitalInput incrementSlot; - DigitalInput toggleMouseCapture; - DigitalInput toggleFullScreen; - DigitalInput pause; - DigitalInput turboMode; - DigitalInput power; - DigitalInput reset; - DigitalInput quit; - - void inputEvent(int16_t scancode, int16_t value); - HotkeyGeneral(); - -private: - unsigned activeSlot; -}; - -struct HotkeyInput : SecondaryInput { - HotkeyGeneral general; - - void inputEvent(int16_t scancode, int16_t value); - HotkeyInput(); -}; - -struct UserInterfaceInput : PrimaryInput { - HotkeyInput hotkey; - - void inputEvent(int16_t scancode, int16_t value); - UserInterfaceInput(); -}; diff --git a/bsnes/target-ui/interface/core.cpp b/bsnes/target-ui/interface/core.cpp deleted file mode 100755 index 922ead91..00000000 --- a/bsnes/target-ui/interface/core.cpp +++ /dev/null @@ -1,61 +0,0 @@ -bool InterfaceCore::loadFirmware(string filename, string keyname, uint8_t *targetdata, unsigned targetsize) { - bool result = false; - - filename = application->path(filename); - string markup; - markup.readfile(filename); - XML::Document document(markup); - lstring keypart = keyname.split<1>("."); - - if(document[keypart[0]][keypart[1]].exists()) { - auto &key = document[keypart[0]][keypart[1]]; - string firmware = key["firmware"].data; - string hash = key["sha256"].data; - - if(auto memory = file::read({dir(filename),firmware})) { - if(nall::sha256(memory.data(), memory.size()) == hash) { - memcpy(targetdata, memory.data(), min(targetsize, memory.size())); - result = true; - } else { - MessageWindow::information(Window::None, {"Warning: Firmware SHA256 sum is incorrect:\n\n", dir(filename), firmware}); - } - } - } - - return result; -} - -/* 5-bit -> 8-bit -static const uint8_t gammaRamp[32] = { - 0x00, 0x01, 0x03, 0x06, 0x0a, 0x0f, 0x15, 0x1c, - 0x24, 0x2d, 0x37, 0x42, 0x4e, 0x5b, 0x69, 0x78, - 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0, - 0xc8, 0xd0, 0xd8, 0xe0, 0xe8, 0xf0, 0xf8, 0xff, -};*/ - -uint32_t InterfaceCore::color(uint16_t r, uint16_t g, uint16_t b) { - auto gamma = [](uint16_t n) { - double exponent = 1.0 + (double)config->video.gamma * 0.01; - return n < 32768 ? 32767 * pow(((double)n / 32767), exponent) : n; - }; - - auto contrast = [](uint16_t n) { - double contrast = config->video.contrast * 0.01; - signed result = n * contrast; - return max(0, min(65535, result)); - }; - - auto brightness = [](uint16_t n) { - signed brightness = (config->video.brightness - 100) * 256; - signed result = n + brightness; - return max(0, min(65535, result)); - }; - - r = brightness(contrast(gamma(r))); - g = brightness(contrast(gamma(g))); - b = brightness(contrast(gamma(b))); - - if(application->depth == 30) { r >>= 6, g >>= 6, b >>= 6; return r << 20 | g << 10 | b << 0; } - if(application->depth == 24) { r >>= 8, g >>= 8, b >>= 8; return r << 16 | g << 8 | b << 0; } - return 0u; -} diff --git a/bsnes/target-ui/interface/gb/gb.cpp b/bsnes/target-ui/interface/gb/gb.cpp deleted file mode 100755 index 6d1af4cc..00000000 --- a/bsnes/target-ui/interface/gb/gb.cpp +++ /dev/null @@ -1,121 +0,0 @@ -void InterfaceGB::initialize() { - loadFirmware("Game Boy.sys/manifest.xml", "system.boot", GB::system.bootROM.dmg, 256u); - loadFirmware("Super Game Boy.sfc/manifest.xml", "cartridge.boot", GB::system.bootROM.sgb, 256u); - loadFirmware("Game Boy Color.sys/manifest.xml", "system.boot", GB::system.bootROM.cgb, 2048u); - - GB::interface = this; - GB::system.init(); -} - -string InterfaceGB::markup() { - return GB::cartridge.information.markup; -} - -bool InterfaceGB::cartridgeLoaded() { - return GB::cartridge.loaded(); -} - -bool InterfaceGB::loadCartridge(GB::System::Revision revision, const string &filename) { - interface->unloadCartridge(); - - vector memory; - if(filename.endswith("/")) { - memory = file::read({filename, "program.rom"}); - interface->base = {true, filename}; - } else { - memory = file::read(filename); - interface->base = {false, nall::basename(filename)}; - } - if(memory.empty()) return false; - - interface->game = interface->base; - interface->cartridgeTitle = interface->base.title(); - interface->applyPatch(interface->base, memory); - - string markup; - markup.readfile(interface->base.filename("manifest.xml", ".xml")); - if(markup.empty()) markup = GameBoyCartridge(memory.data(), memory.size()).markup; - - GB::cartridge.load(revision, markup, vectorstream{memory}); - GB::system.power(); - - if(GB::cartridge.ramsize) { - filestream fs{interface->base.filename("save.ram", ".sav")}; - fs.read(GB::cartridge.ramdata, min(GB::cartridge.ramsize, fs.size())); - } - - GB::interface = this; - GB::video.generate_palette(); - interface->loadCartridge(::Interface::Mode::GB); - return true; -} - -void InterfaceGB::unloadCartridge() { - if(GB::cartridge.ramsize) { - file::write(interface->base.filename("save.ram", ".sav"), GB::cartridge.ramdata, GB::cartridge.ramsize); - } - - GB::cartridge.unload(); - interface->base.name = ""; -} - -void InterfaceGB::power() { - GB::system.power(); -} - -void InterfaceGB::reset() { - GB::system.power(); //Game Boy lacks reset button -} - -void InterfaceGB::run() { - do { - GB::system.run(); - } while(GB::scheduler.exit_reason() != GB::Scheduler::ExitReason::FrameEvent); -} - -serializer InterfaceGB::serialize() { - GB::system.runtosave(); - return GB::system.serialize(); -} - -bool InterfaceGB::unserialize(serializer &s) { - return GB::system.unserialize(s); -} - -void InterfaceGB::setCheats(const lstring &list) { - GB::cheat.reset(); - for(auto &code : list) { - lstring codelist; - codelist.split("+", code); - for(auto &part : codelist) { - unsigned addr, data, comp; - if(GB::Cheat::decode(part, addr, data, comp)) { - GB::cheat.append({ addr, data, comp }); - } - } - } - GB::cheat.synchronize(); -} - -// - -uint32_t InterfaceGB::videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { - return color(red, green, blue); -} - -void InterfaceGB::videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height) { - interface->videoRefresh(data, pitch, width, height); -} - -void InterfaceGB::audioSample(int16_t lsample, int16_t rsample) { - signed samples[] = {lsample, rsample}; - dspaudio.sample(samples); - while(dspaudio.pending()) { - dspaudio.read(samples); - audio.sample(samples[0], samples[1]); - } -} - -int16_t InterfaceGB::inputPoll(unsigned port, unsigned device, unsigned id) { - return inputManager->gb.device.controller.poll(id); -} diff --git a/bsnes/target-ui/interface/gb/gb.hpp b/bsnes/target-ui/interface/gb/gb.hpp deleted file mode 100755 index 2abc4f5d..00000000 --- a/bsnes/target-ui/interface/gb/gb.hpp +++ /dev/null @@ -1,23 +0,0 @@ -struct InterfaceGB : InterfaceCore, GB::Interface { - void initialize(); - - string markup(); - - bool cartridgeLoaded(); - bool loadCartridge(GB::System::Revision revision, const string &filename); - void unloadCartridge(); - - void power(); - void reset(); - void run(); - - serializer serialize(); - bool unserialize(serializer&); - - void setCheats(const lstring &list = lstring{}); - - uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue); - void videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height); - void audioSample(int16_t lsample, int16_t rsample); - int16_t inputPoll(unsigned port, unsigned device, unsigned id); -}; diff --git a/bsnes/target-ui/interface/gba/gba.cpp b/bsnes/target-ui/interface/gba/gba.cpp deleted file mode 100755 index a890b664..00000000 --- a/bsnes/target-ui/interface/gba/gba.cpp +++ /dev/null @@ -1,104 +0,0 @@ -void InterfaceGBA::initialize() { - loadFirmware("Game Boy Advance.sys/manifest.xml", "system.bios", GBA::bios.data, 16384u); - - GBA::interface = this; - GBA::system.init(); -} - -string InterfaceGBA::markup() { - return GBA::cartridge.information.markup; -} - -bool InterfaceGBA::cartridgeLoaded() { - return GBA::cartridge.loaded(); -} - -bool InterfaceGBA::loadCartridge(const string &filename) { - interface->unloadCartridge(); - - vector memory; - if(filename.endswith("/")) { - memory = file::read({filename, "program.rom"}); - interface->base = {true, filename}; - } else { - memory = file::read(filename); - interface->base = {false, nall::basename(filename)}; - } - if(memory.empty()) return false; - - interface->game = interface->base; - interface->cartridgeTitle = interface->base.title(); - interface->applyPatch(interface->base, memory); - - string markup; - markup.readfile(interface->base.filename("manifest.xml", ".xml")); - if(markup.empty()) markup = GameBoyAdvanceCartridge(memory.data(), memory.size()).markup; - - GBA::cartridge.load(markup, vectorstream{memory}); - GBA::system.power(); - - if(GBA::cartridge.ram_size()) { - filestream fs{interface->base.filename("save.ram", ".sav")}; - fs.read(GBA::cartridge.ram_data(), min(GBA::cartridge.ram_size(), fs.size())); - } - - GBA::video.generate_palette(); - interface->loadCartridge(::Interface::Mode::GBA); - return true; -} - -void InterfaceGBA::unloadCartridge() { - if(GBA::cartridge.ram_size()) { - file::write(interface->base.filename("save.ram", ".sav"), GBA::cartridge.ram_data(), GBA::cartridge.ram_size()); - } - - GBA::cartridge.unload(); - interface->base.name = ""; -} - -void InterfaceGBA::power() { - return GBA::system.power(); -} - -void InterfaceGBA::reset() { - return GBA::system.power(); //GBA has no reset button -} - -void InterfaceGBA::run() { - return GBA::system.run(); -} - -serializer InterfaceGBA::serialize() { - GBA::system.runtosave(); - return GBA::system.serialize(); -} - -bool InterfaceGBA::unserialize(serializer &s) { - return GBA::system.unserialize(s); -} - -void InterfaceGBA::setCheats(const lstring &list) { -} - -// - -uint32_t InterfaceGBA::videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { - return color(red, green, blue); -} - -void InterfaceGBA::videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height) { - interface->videoRefresh(data, pitch, width, height); -} - -void InterfaceGBA::audioSample(int16_t lsample, int16_t rsample) { - signed samples[] = { lsample, rsample }; - dspaudio.sample(samples); - while(dspaudio.pending()) { - dspaudio.read(samples); - audio.sample(samples[0], samples[1]); - } -} - -int16_t InterfaceGBA::inputPoll(unsigned port, unsigned device, unsigned id) { - return inputManager->gba.device.controller.poll(id); -} diff --git a/bsnes/target-ui/interface/gba/gba.hpp b/bsnes/target-ui/interface/gba/gba.hpp deleted file mode 100755 index a6b3b4ed..00000000 --- a/bsnes/target-ui/interface/gba/gba.hpp +++ /dev/null @@ -1,23 +0,0 @@ -struct InterfaceGBA : InterfaceCore, GBA::Interface { - void initialize(); - - string markup(); - - bool cartridgeLoaded(); - bool loadCartridge(const string &filename); - void unloadCartridge(); - - void power(); - void reset(); - void run(); - - serializer serialize(); - bool unserialize(serializer&); - - void setCheats(const lstring &list = lstring{}); - - uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue); - void videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height); - void audioSample(int16_t lsample, int16_t rsample); - int16_t inputPoll(unsigned port, unsigned device, unsigned id); -}; diff --git a/bsnes/target-ui/interface/interface.cpp b/bsnes/target-ui/interface/interface.cpp deleted file mode 100755 index cc5298cb..00000000 --- a/bsnes/target-ui/interface/interface.cpp +++ /dev/null @@ -1,284 +0,0 @@ -#include "../base.hpp" -#include "core.cpp" -#include "nes/nes.cpp" -#include "snes/snes.cpp" -#include "gb/gb.cpp" -#include "gba/gba.cpp" -Interface *interface = nullptr; - -Filter filter; - -void Filter::render(const uint32_t *input, unsigned inputPitch, unsigned inputWidth, unsigned inputHeight) { - width = inputWidth, height = inputHeight; - dl_size(width, height); - dl_render(data, pitch, input, inputPitch, inputWidth, inputHeight); -} - -Filter::Filter() { - data = new uint32_t[2048 * 2048]; - pitch = 2048 * sizeof(uint32_t); -} - -Filter::~Filter() { - delete[] data; -} - -string CartridgePath::filename(const string &folderName, const string &fileName) const { - if(name.empty()) return ""; - if(folder) return { name, folderName }; - return { name, fileName }; -} - -string CartridgePath::title() const { - if(name.empty()) return ""; - if(folder) { - string title = name; - title.rtrim<1>("/"); - title = notdir(nall::basename(title)); - return title; - } - return notdir(name); -} - -void Interface::bindControllers() { - switch(mode()) { - case Mode::FC: - nes.setController(0, config->nes.controllerPort1Device); - nes.setController(1, config->nes.controllerPort2Device); - break; - - case Mode::SFC: - snes.setController(0, config->snes.controllerPort1Device); - snes.setController(1, config->snes.controllerPort2Device); - break; - } -} - -void Interface::setController(unsigned port, unsigned device) { - switch(mode()) { - case Mode::FC: return nes.setController(port, device); - case Mode::SFC: return snes.setController(port, device); - } -} - -void Interface::updateDSP() { - audio.set(Audio::Frequency, config->audio.frequency); - audio.set(Audio::Latency, config->audio.latency); - - if(config->audio.resampler == "linear" ) dspaudio.setResampler(DSP::ResampleEngine::Linear); - if(config->audio.resampler == "hermite") dspaudio.setResampler(DSP::ResampleEngine::Hermite); - if(config->audio.resampler == "sinc" ) dspaudio.setResampler(DSP::ResampleEngine::Sinc); - dspaudio.setResamplerFrequency(config->audio.frequency); - dspaudio.setVolume(config->audio.mute == false ? (double)config->audio.volume / 100.0 : 0.0); - - switch(mode()) { - case Mode::FC: return dspaudio.setFrequency(config->audio.frequencyNES); - case Mode::SFC: return dspaudio.setFrequency(config->audio.frequencySNES); - case Mode::GB: return dspaudio.setFrequency(config->audio.frequencyGB); - case Mode::GBA: return dspaudio.setFrequency(config->audio.frequencyGBA); - } -} - -string Interface::markup() { - if(core) return core->markup(); - return ""; -} - -bool Interface::cartridgeLoaded() { - if(core) return core->cartridgeLoaded(); - return false; -} - -void Interface::loadCartridge(Mode mode) { - switch(mode) { - case Mode::FC: core = &nes; break; - case Mode::SFC: core = &snes; break; - case Mode::GB: core = &gb; break; - case Mode::GBA: core = &gba; break; - default: core = nullptr; break; - } - utility->setMode(this->mode = mode); - - bindControllers(); - cheatEditor->load(game.filename("cheats.xml", ".cht")); - stateManager->load(game.filename("states.bsa", ".bsa"), 0u); - dipSwitches->load(); - utility->showMessage({ "Loaded ", cartridgeTitle }); -} - -bool Interface::loadCartridge(string filename) { - filename.trim<1>("\""); - filename.transform("\\", "/"); - bool result = false; - if(filename.endswith(".nes") || filename.endswith(".nes/")) result = nes.loadCartridge(filename); - if(filename.endswith(".sfc") || filename.endswith(".sfc/")) result = snes.loadCartridge(filename); - if(filename.endswith(".gb" ) || filename.endswith(".gb/" )) result = gb.loadCartridge(GB::System::Revision::GameBoy, filename); - if(filename.endswith(".gbc") || filename.endswith(".gbc/")) result = gb.loadCartridge(GB::System::Revision::GameBoyColor, filename); - if(filename.endswith(".gba") || filename.endswith(".gba/")) result = gba.loadCartridge(filename); - return result; -} - -void Interface::unloadCartridge() { - if(cartridgeLoaded() == false) return; - cheatDatabase->setVisible(false); - cheatEditor->save(game.filename("cheats.xml", ".cht")); - stateManager->save(game.filename("states.bsa", ".bsa"), 0u); - setCheatCodes(); - - if(core) core->unloadCartridge(); - core = nullptr; - cartridgeTitle = ""; - utility->setMode(mode = Mode::None); -} - -void Interface::power() { - if(core == nullptr) return; - core->power(); - utility->showMessage("System power was cycled"); -} - -void Interface::reset() { - if(core == nullptr) return; - core->reset(); - utility->showMessage("System was reset"); -} - -void Interface::run() { - if(core == nullptr) return; - core->run(); -} - -serializer Interface::serialize() { - if(core == nullptr) return serializer(); - return core->serialize(); -} - -bool Interface::unserialize(serializer &s) { - if(core == nullptr) return false; - return core->unserialize(s); -} - -bool Interface::saveState(unsigned slot) { - string filename = game.filename({ "state-", slot, ".bst" }, { "-", slot, ".bst" }); - serializer s = serialize(); - bool result = file::write(filename, s.data(), s.size()); - utility->showMessage(result == true ? string{ "Saved state ", slot } : "Failed to save state"); - return result; -} - -bool Interface::loadState(unsigned slot) { - string filename = game.filename({ "state-", slot, ".bst" }, { "-", slot, ".bst" }); - auto memory = file::read(filename); - if(memory.empty()) { - utility->showMessage(string{ "Slot ", slot, " save file not found" }); - return false; - } - serializer s(memory.data(), memory.size()); - bool result = unserialize(s); - utility->showMessage(result == true ? string{ "Loaded state ", slot } : "Failed to load state"); - return result; -} - -void Interface::setCheatCodes(const lstring &list) { - if(core) return core->setCheats(list); -} - -void Interface::updatePalette() { - switch(mode()) { - case Mode::FC: return FC::video.generate_palette(); - case Mode::SFC: return SFC::video.generate_palette(); - case Mode::GB: return GB::video.generate_palette(); - case Mode::GBA: return GBA::video.generate_palette(); - } -} - -string Interface::sha256() { - switch(mode()) { - case Mode::FC: return FC::cartridge.sha256(); - case Mode::SFC: return SFC::cartridge.sha256(); - case Mode::GB: return GB::cartridge.sha256(); - case Mode::GBA: return GBA::cartridge.sha256(); - } - return "{None}"; -} - -Interface::Interface() : core(nullptr) { - mode = Mode::None; - nes.initialize(); - snes.initialize(); - gb.initialize(); - gba.initialize(); -} - -//internal - -bool Interface::applyPatch(CartridgePath &filepath, vector &memory) { - string patchname = filepath.filename("patch.bps", ".bps"); - if(file::exists(patchname) == false) return false; - - bpspatch bps; - bps.modify(patchname); - bps.source(memory.data(), memory.size()); - unsigned targetSize = bps.size(); - uint8_t *targetData = new uint8_t[targetSize]; - bps.target(targetData, targetSize); - if(bps.apply() != bpspatch::result::success) { - delete[] targetData; - return false; - } - - memory.resize(targetSize); - memcpy(memory.data(), targetData, targetSize); - delete[] targetData; - return true; -} - -void Interface::videoRefresh(const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height) { - uint32_t *output; - unsigned outputPitch; - - if(application->depth == 30 && filter.opened()) { - filter.render(input, inputPitch, width, height); - input = filter.data; - inputPitch = filter.pitch; - width = filter.width; - height = filter.height; - } - - if(video.lock(output, outputPitch, width, height)) { - inputPitch >>= 2, outputPitch >>= 2; - - for(unsigned y = 0; y < height; y++) { - memcpy(output + y * outputPitch, input + y * inputPitch, width * sizeof(uint32_t)); - } - - if(config->video.maskOverscan && (mode() == Mode::FC || mode() == Mode::SFC)) { - unsigned h = config->video.maskOverscanHorizontal; - unsigned v = config->video.maskOverscanVertical; - - if(h) for(unsigned y = 0; y < height; y++) { - memset(output + y * outputPitch, 0, h * sizeof(uint32_t)); - memset(output + y * outputPitch + (width - h), 0, h * sizeof(uint32_t)); - } - - if(v) for(unsigned y = 0; y < v; y++) { - memset(output + y * outputPitch, 0, width * sizeof(uint32_t)); - memset(output + (height - 1 - y) * outputPitch, 0, width * sizeof(uint32_t)); - } - } - - video.unlock(); - video.refresh(); - } - - static unsigned frameCounter = 0; - static time_t previous, current; - frameCounter++; - - time(¤t); - if(current != previous) { - previous = current; - utility->setStatusText({ "FPS: ", frameCounter }); - frameCounter = 0; - } -} diff --git a/bsnes/target-ui/interface/interface.hpp b/bsnes/target-ui/interface/interface.hpp deleted file mode 100755 index 86552931..00000000 --- a/bsnes/target-ui/interface/interface.hpp +++ /dev/null @@ -1,91 +0,0 @@ -struct InterfaceCore { - bool loadFirmware(string filename, string keyname, uint8_t *targetdata, unsigned targetsize); - uint32_t color(uint16_t red, uint16_t green, uint16_t blue); - - virtual string markup() = 0; - virtual bool cartridgeLoaded() = 0; - virtual void unloadCartridge() = 0; - - virtual void power() = 0; - virtual void reset() = 0; - virtual void run() = 0; - - virtual serializer serialize() = 0; - virtual bool unserialize(serializer&) = 0; - - virtual void setCheats(const lstring &list = lstring{}) = 0; -}; - -struct CartridgePath { - bool folder; - string name; - string filename(const string &folderName, const string &fileName) const; - string title() const; -}; - -#include "nes/nes.hpp" -#include "snes/snes.hpp" -#include "gb/gb.hpp" -#include "gba/gba.hpp" - -struct Filter : public library { - function dl_size; - function dl_render; - void render(const uint32_t*, unsigned, unsigned, unsigned); - Filter(); - ~Filter(); - - uint32_t *data; - unsigned pitch; - unsigned width; - unsigned height; -}; - -extern Filter filter; - -struct Interface : property { - enum class Mode : unsigned { None, FC, SFC, GB, GBA }; - readonly mode; - - void bindControllers(); - void setController(unsigned port, unsigned device); - void updateDSP(); - - string markup(); - - bool cartridgeLoaded(); - void loadCartridge(Mode mode); - bool loadCartridge(string filename); //auto-detect system-type based on file extension - void unloadCartridge(); - - void power(); - void reset(); - void run(); - - serializer serialize(); - bool unserialize(serializer&); - - bool saveState(unsigned slot); - bool loadState(unsigned slot); - void setCheatCodes(const lstring &list = lstring{}); - void updatePalette(); - string sha256(); - - Interface(); - - bool applyPatch(CartridgePath &filepath, vector &memory); - void videoRefresh(const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height); - - CartridgePath base; //base cartridge connected to emulated system - CartridgePath slot[2]; //slot cartridges connected to base cartridge - CartridgePath game; //where to store resources (cheats.xml, states.bsa, ...) - string cartridgeTitle; //combined name of game ([base] + [slot ...]) - - InterfaceCore *core; - InterfaceNES nes; - InterfaceSNES snes; - InterfaceGB gb; - InterfaceGBA gba; -}; - -extern Interface *interface; diff --git a/bsnes/target-ui/interface/nes/nes.cpp b/bsnes/target-ui/interface/nes/nes.cpp deleted file mode 100755 index 521b2bf2..00000000 --- a/bsnes/target-ui/interface/nes/nes.cpp +++ /dev/null @@ -1,136 +0,0 @@ -void InterfaceNES::initialize() { - FC::interface = this; - FC::system.init(); -} - -string InterfaceNES::markup() { - return FC::cartridge.information.markup; -} - -void InterfaceNES::setController(bool port, unsigned device) { - if(port == 0) config->nes.controllerPort1Device = device; - if(port == 1) config->nes.controllerPort2Device = device; - - if(port == 0) switch(device) { - case 0: return FC::input.connect(0, FC::Input::Device::None); - case 1: return FC::input.connect(0, FC::Input::Device::Joypad); - } - - if(port == 1) switch(device) { - case 0: return FC::input.connect(1, FC::Input::Device::None); - case 1: return FC::input.connect(1, FC::Input::Device::Joypad); - } -} - -bool InterfaceNES::cartridgeLoaded() { - return FC::cartridge.loaded(); -} - -bool InterfaceNES::loadCartridge(const string &filename) { - interface->unloadCartridge(); - - vector memory; - if(filename.endswith("/")) { - memory = file::read({filename, "program.rom"}); - interface->base = {true, filename}; - } else { - memory = file::read(filename); - interface->base = {false, nall::basename(filename)}; - } - if(memory.empty()) return false; - - interface->game = interface->base; - interface->cartridgeTitle = interface->base.title(); - interface->applyPatch(interface->base, memory); - - string markup; - markup.readfile(interface->base.filename("manifest.xml", ".xml")); - if(markup.empty()) markup = FamicomCartridge(memory.data(), memory.size()).markup; - - FC::cartridge.load(markup, vectorstream{memory}); - FC::system.power(); - - if(FC::cartridge.ram_size()) { - filestream fs{interface->base.filename("save.ram", ".sav")}; - fs.read(FC::cartridge.ram_data(), min(FC::cartridge.ram_size(), fs.size())); - } - - interface->loadCartridge(::Interface::Mode::FC); - FC::video.generate_palette(); - return true; -} - -void InterfaceNES::unloadCartridge() { - if(FC::cartridge.ram_size()) { - file::write(interface->base.filename("save.ram", ".sav"), FC::cartridge.ram_data(), FC::cartridge.ram_size()); - } - FC::cartridge.unload(); - interface->base.name = ""; -} - -// - -void InterfaceNES::power() { - FC::system.power(); -} - -void InterfaceNES::reset() { - FC::system.reset(); -} - -void InterfaceNES::run() { - FC::system.run(); -} - -// - -serializer InterfaceNES::serialize() { - FC::system.runtosave(); - return FC::system.serialize(); -} - -bool InterfaceNES::unserialize(serializer &s) { - return FC::system.unserialize(s); -} - -// - -void InterfaceNES::setCheats(const lstring &list) { - FC::cheat.reset(); - for(auto &code : list) { - lstring codelist; - codelist.split("+", code); - for(auto &part : codelist) { - unsigned addr, data, comp; - if(FC::Cheat::decode(part, addr, data, comp)) { - FC::cheat.append({ addr, data, comp }); - } - } - } - FC::cheat.synchronize(); -} - -// - -uint32_t InterfaceNES::videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { - return color(red, green, blue); -} - -void InterfaceNES::videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height) { - interface->videoRefresh(data, pitch, width, height); -} - -void InterfaceNES::audioSample(int16_t lsample, int16_t rsample) { - //NES audio output is monaural; ruby only takes stereo audio - signed samples[] = {lsample}; - dspaudio.sample(samples); - while(dspaudio.pending()) { - dspaudio.read(samples); - audio.sample(samples[0], samples[0]); - } -} - -int16_t InterfaceNES::inputPoll(unsigned port, unsigned device, unsigned id) { - if(port == 0 && device == 0) return inputManager->nes.port1.gamepad.poll(id); - return 0; -} diff --git a/bsnes/target-ui/interface/nes/nes.hpp b/bsnes/target-ui/interface/nes/nes.hpp deleted file mode 100755 index 7af61a52..00000000 --- a/bsnes/target-ui/interface/nes/nes.hpp +++ /dev/null @@ -1,25 +0,0 @@ -struct InterfaceNES : InterfaceCore, FC::Interface { - void initialize(); - - string markup(); - - void setController(bool port, unsigned device); - - bool cartridgeLoaded(); - bool loadCartridge(const string &filename); - void unloadCartridge(); - - void power(); - void reset(); - void run(); - - serializer serialize(); - bool unserialize(serializer&); - - void setCheats(const lstring &list = lstring{}); - - uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue); - void videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height); - void audioSample(int16_t lsample, int16_t rsample); - int16_t inputPoll(unsigned port, unsigned device, unsigned id); -}; diff --git a/bsnes/target-ui/interface/snes/snes.cpp b/bsnes/target-ui/interface/snes/snes.cpp deleted file mode 100755 index 536e4189..00000000 --- a/bsnes/target-ui/interface/snes/snes.cpp +++ /dev/null @@ -1,390 +0,0 @@ -void InterfaceSNES::initialize() { - loadFirmware("Super Famicom.sys/manifest.xml", "system.smp", SFC::smp.iplrom, 64u); - - SFC::interface = this; - SFC::system.init(); -} - -string InterfaceSNES::markup() { - return SFC::cartridge.information.markup; -} - -void InterfaceSNES::setController(bool port, unsigned device) { - if(port == 0) config->snes.controllerPort1Device = device; - if(port == 1) config->snes.controllerPort2Device = device; - - if(port == 0) switch(device) { default: - case 0: return SFC::input.connect(0, SFC::Input::Device::None); - case 1: return SFC::input.connect(0, SFC::Input::Device::Joypad); - case 2: return SFC::input.connect(0, SFC::Input::Device::Multitap); - case 3: return SFC::input.connect(0, SFC::Input::Device::Mouse); - case 4: return SFC::input.connect(0, SFC::Input::Device::USART); - } - - if(port == 1) switch(device) { default: - case 0: return SFC::input.connect(1, SFC::Input::Device::None); - case 1: return SFC::input.connect(1, SFC::Input::Device::Joypad); - case 2: return SFC::input.connect(1, SFC::Input::Device::Multitap); - case 3: return SFC::input.connect(1, SFC::Input::Device::Mouse); - case 4: return SFC::input.connect(1, SFC::Input::Device::SuperScope); - case 5: return SFC::input.connect(1, SFC::Input::Device::Justifier); - case 6: return SFC::input.connect(1, SFC::Input::Device::Justifiers); - case 7: return SFC::input.connect(1, SFC::Input::Device::USART); - } -} - -bool InterfaceSNES::cartridgeLoaded() { - return SFC::cartridge.loaded(); -} - -vector InterfaceSNES::loadCartridge(const string &filename, CartridgePath &cartridge) { - vector memory; - auto backup = cartridge; - string suffix; - if(filename.endswith("/")) { - cartridge = {true, filename}; - } else { - suffix = {".", extension(filename)}; - cartridge = {false, nall::basename(filename)}; - } - memory = file::read(cartridge.filename("program.rom", suffix)); - interface->applyPatch(cartridge, memory); - if(memory.empty()) cartridge = backup; - return memory; -} - -bool InterfaceSNES::loadCartridge(string basename) { - interface->unloadCartridge(); - - auto memory = loadCartridge(basename, interface->base); - if(memory.empty()) return false; - - interface->game = interface->base; - interface->cartridgeTitle = interface->base.title(); - - string markup; - markup.readfile(interface->base.filename("manifest.xml", ".xml")); - if(markup.empty()) markup = SuperFamicomCartridge(memory.data(), memory.size()).markup; - - SFC::cartridge.rom.copy(vectorstream{memory}); - SFC::cartridge.load(SFC::Cartridge::Mode::Normal, markup); - SFC::system.power(); - - loadMemory(); - interface->loadCartridge(::Interface::Mode::SFC); - SFC::video.generate_palette(); - return true; -} - -bool InterfaceSNES::loadSatellaviewSlottedCartridge(string basename, string slotname) { - interface->unloadCartridge(); - - auto memory = loadCartridge(basename, interface->base); - if(memory.empty()) return false; - auto memoryBS = loadCartridge(slotname, interface->slot[0]); - - interface->game = memoryBS.empty() ? interface->base : interface->slot[0]; //TODO: subfolder for folders; concatenation for files - interface->cartridgeTitle = interface->base.title(); - if(memoryBS) interface->cartridgeTitle.append(" + ", interface->slot[0].title()); - - string markup; - markup.readfile(interface->base.filename("manifest.xml", ".xml")); - if(markup.empty()) markup = SuperFamicomCartridge(memory.data(), memory.size()).markup; - - SFC::cartridge.rom.copy(vectorstream{memory}); - if(memoryBS) SFC::bsxflash.memory.copy(vectorstream{memoryBS}); - SFC::cartridge.load(SFC::Cartridge::Mode::BsxSlotted, markup); - SFC::system.power(); - - loadMemory(); - interface->loadCartridge(::Interface::Mode::SFC); - SFC::video.generate_palette(); - return true; -} - -bool InterfaceSNES::loadSatellaviewCartridge(string basename, string slotname) { - interface->unloadCartridge(); - - auto memory = loadCartridge(basename, interface->base); - if(memory.empty()) return false; - auto memoryBS = loadCartridge(slotname, interface->slot[0]); - - interface->game = memoryBS.empty() ? interface->base : interface->slot[0]; - interface->cartridgeTitle = interface->base.title(); - if(memoryBS) interface->cartridgeTitle = interface->slot[0].title(); - - string markup; - markup.readfile(interface->base.filename("manifest.xml", ".xml")); - if(markup.empty()) markup = SuperFamicomCartridge(memory.data(), memory.size()).markup; - - SFC::cartridge.rom.copy(vectorstream{memory}); - if(memoryBS) SFC::bsxflash.memory.copy(vectorstream{memoryBS}); - SFC::cartridge.load(SFC::Cartridge::Mode::Bsx, markup); - SFC::system.power(); - - loadMemory(); - interface->loadCartridge(::Interface::Mode::SFC); - SFC::video.generate_palette(); - return true; -} - -bool InterfaceSNES::loadSufamiTurboCartridge(string basename, string slotAname, string slotBname) { - interface->unloadCartridge(); - - auto memory = loadCartridge(basename, interface->base); - if(memory.empty()) return false; - auto memorySTA = loadCartridge(slotAname, interface->slot[0]); - auto memorySTB = loadCartridge(slotBname, interface->slot[1]); - - interface->game = memorySTA.empty() ? interface->base : interface->slot[0]; //TODO: subfolder for folders; concatenation for files - interface->cartridgeTitle = interface->base.title(); - if( memorySTA && !memorySTB) interface->cartridgeTitle = interface->slot[0].title(); - if(!memorySTA && memorySTB) interface->cartridgeTitle = interface->slot[1].title(); - if( memorySTA && memorySTB) interface->cartridgeTitle = { - interface->slot[0].title(), " + ", interface->slot[1].title() - }; - - string markup; - markup.readfile(interface->base.filename("manifest.xml", ".xml")); - if(markup.empty()) markup = SuperFamicomCartridge(memory.data(), memory.size()).markup; - - SFC::cartridge.rom.copy(vectorstream{memory}); - if(memorySTA) SFC::sufamiturbo.slotA.rom.copy(vectorstream{memory}); - if(memorySTB) SFC::sufamiturbo.slotB.rom.copy(vectorstream{memory}); - SFC::cartridge.load(SFC::Cartridge::Mode::SufamiTurbo, markup); - SFC::system.power(); - - loadMemory(); - interface->loadCartridge(::Interface::Mode::SFC); - SFC::video.generate_palette(); - return true; -} - -bool InterfaceSNES::loadSuperGameBoyCartridge(string basename, string slotname) { - interface->unloadCartridge(); - - auto memory = loadCartridge(basename, interface->base); - if(memory.empty()) return false; - auto memoryGB = loadCartridge(slotname, interface->slot[0]); - - interface->game = memoryGB.empty() ? interface->base : interface->slot[0]; - interface->cartridgeTitle = interface->base.title(); - if(memoryGB) interface->cartridgeTitle = interface->slot[0].title(); - - string markup; - markup.readfile(interface->base.filename("manifest.xml", ".xml")); - if(markup.empty()) markup = SuperFamicomCartridge(memory.data(), memory.size()).markup; - - string gbMarkup; - gbMarkup.readfile(interface->slot[0].filename("manifest.xml", ".xml")); - if(gbMarkup.empty()) gbMarkup = GameBoyCartridge(memoryGB.data(), memoryGB.size()).markup; - - SFC::cartridge.rom.copy(vectorstream{memory}); - GB::cartridge.load(GB::System::Revision::SuperGameBoy, gbMarkup, vectorstream{memoryGB}); - SFC::cartridge.load(SFC::Cartridge::Mode::SuperGameBoy, markup); - SFC::system.power(); - - loadMemory(); - interface->loadCartridge(::Interface::Mode::SFC); - SFC::video.generate_palette(); - return true; -} - -void InterfaceSNES::unloadCartridge() { - saveMemory(); - SFC::cartridge.unload(); -} - -void InterfaceSNES::power() { - SFC::system.power(); -} - -void InterfaceSNES::reset() { - SFC::system.reset(); -} - -void InterfaceSNES::run() { - SFC::system.run(); -} - -string InterfaceSNES::memoryName(SFC::Cartridge::NonVolatileRAM &memory) { - if(memory.slot == SFC::Cartridge::Slot::Base) { - if(memory.id == "save.ram") return interface->base.filename("save.ram", ".srm"); - if(memory.id == "rtc.ram") return interface->base.filename("rtc.ram", ".rtc"); - if(memory.id == "upd96050.ram") return interface->base.filename("upd96050.ram", ".nec"); - if(memory.id == "bsx.ram") return interface->base.filename("bsx.ram", ".bss"); - if(memory.id == "bsx.psram") return interface->base.filename("bsx.psram", ".bsp"); - } - if(memory.slot == SFC::Cartridge::Slot::SufamiTurboA) { - if(memory.id == "save.ram") return interface->slot[0].filename("save.ram", ".sts"); - } - if(memory.slot == SFC::Cartridge::Slot::SufamiTurboB) { - if(memory.id == "save.ram") return interface->slot[1].filename("save.ram", ".sts"); - } - return ""; -} - -void InterfaceSNES::loadMemory() { - for(auto &memory : SFC::cartridge.nvram) { - if(memory.size == 0) continue; - - string filename = memoryName(memory); - if(filename.empty()) continue; - - if(auto read = file::read(filename)) { - memcpy(memory.data, read.data(), min(memory.size, read.size())); - } - } - - if(SFC::cartridge.mode() == SFC::Cartridge::Mode::SuperGameBoy) { - if(GB::cartridge.ramsize) { - filestream fs{interface->slot[0].filename("save.ram", ".sav")}; - fs.read(GB::cartridge.ramdata, min(GB::cartridge.ramsize, fs.size())); - } - } -} - -void InterfaceSNES::saveMemory() { - for(auto &memory : SFC::cartridge.nvram) { - if(memory.size == 0) continue; - - string filename = memoryName(memory); - if(filename.empty()) continue; - - file::write(filename, memory.data, memory.size); - } - - if(SFC::cartridge.mode() == SFC::Cartridge::Mode::SuperGameBoy) { - if(GB::cartridge.ramsize) { - file::write(interface->slot[0].filename("save.ram", ".sav"), - GB::cartridge.ramdata, GB::cartridge.ramsize - ); - } - } -} - -serializer InterfaceSNES::serialize() { - SFC::system.runtosave(); - return SFC::system.serialize(); -} - -bool InterfaceSNES::unserialize(serializer &s) { - return SFC::system.unserialize(s); -} - -void InterfaceSNES::setCheats(const lstring &list) { - if(SFC::cartridge.mode() == SFC::Cartridge::Mode::SuperGameBoy) { - GB::cheat.reset(); - for(auto &code : list) { - lstring codelist; - codelist.split("+", code); - for(auto &part : codelist) { - unsigned addr, data, comp; - if(GB::Cheat::decode(part, addr, data, comp)) { - GB::cheat.append({ addr, data, comp }); - } - } - } - GB::cheat.synchronize(); - return; - } - - SFC::cheat.reset(); - for(auto &code : list) { - lstring codelist; - codelist.split("+", code); - for(auto &part : codelist) { - unsigned addr, data; - if(SFC::Cheat::decode(part, addr, data)) { - SFC::cheat.append({ addr, data }); - } - } - } - SFC::cheat.synchronize(); -} - -// - -uint32_t InterfaceSNES::videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { - return color(red, green, blue); -} - -void InterfaceSNES::videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height) { -//unsigned width = 256 << hires; -//unsigned height = 240 << interlace; -//unsigned pitch = 1024 >> interlace; - - bool overscan = false; - - //skip first line; as it is always blank (by SNES design) - if(overscan == false) data += 1 * 1024; // 8 + 224 + 8 - if(overscan == true ) data += 9 * 1024; // 0 + 240 + 0 - - interface->videoRefresh(data, pitch, width, height); -} - -void InterfaceSNES::audioSample(int16_t lsample, int16_t rsample) { - signed samples[] = {lsample, rsample}; - dspaudio.sample(samples); - while(dspaudio.pending()) { - dspaudio.read(samples); - audio.sample(samples[0], samples[1]); - } -} - -int16_t InterfaceSNES::inputPoll(unsigned port, unsigned device, unsigned id) { - if(port == 0) { - if(device == (unsigned)SFC::Input::Device::Joypad) return inputManager->snes.port1.gamepad.poll(id); - if(device == (unsigned)SFC::Input::Device::Multitap) { - unsigned index = id >> 16; - id &= 65535; - if(index == 0) return inputManager->snes.port1.multitap1.poll(id); - if(index == 1) return inputManager->snes.port1.multitap2.poll(id); - if(index == 2) return inputManager->snes.port1.multitap3.poll(id); - if(index == 3) return inputManager->snes.port1.multitap4.poll(id); - } - if(device == (unsigned)SFC::Input::Device::Mouse) return inputManager->snes.port1.mouse.poll(id); - } - - if(port == 1) { - if(device == (unsigned)SFC::Input::Device::Joypad) return inputManager->snes.port2.gamepad.poll(id); - if(device == (unsigned)SFC::Input::Device::Multitap) { - unsigned index = id >> 16; - id &= 65535; - if(index == 0) return inputManager->snes.port2.multitap1.poll(id); - if(index == 1) return inputManager->snes.port2.multitap2.poll(id); - if(index == 2) return inputManager->snes.port2.multitap3.poll(id); - if(index == 3) return inputManager->snes.port2.multitap4.poll(id); - } - if(device == (unsigned)SFC::Input::Device::Mouse) return inputManager->snes.port2.mouse.poll(id); - if(device == (unsigned)SFC::Input::Device::SuperScope) return inputManager->snes.port2.superScope.poll(id); - if(device == (unsigned)SFC::Input::Device::Justifier) return inputManager->snes.port2.justifier1.poll(id); - if(device == (unsigned)SFC::Input::Device::Justifiers) { - unsigned index = id >> 16; - id &= 65535; - if(index == 0) return inputManager->snes.port2.justifier1.poll(id); - if(index == 1) return inputManager->snes.port2.justifier2.poll(id); - } - } - - return 0; -} - -string InterfaceSNES::path(SFC::Cartridge::Slot slot, const string &hint) { - if(slot == SFC::Cartridge::Slot::Base) { - if(hint == "msu1.rom") return interface->base.filename("msu1.rom", ".msu"); - if(hint.wildcard("track-*.pcm")) { - string track = hint; - track.trim<1>("track-", ".pcm"); - return interface->base.filename(hint, { "-", decimal(track), ".pcm" }); - } - if(hint == "uart.so") return { dir(interface->base.name), "uart.so" }; - if(hint == "usart.so") return { dir(interface->base.name), "usart.so" }; - if(hint.endswith(".rom")) return { dir(interface->base.name), hint }; - } - return { dir(interface->base.name), hint }; -} - -void InterfaceSNES::message(const string &text) { - MessageWindow::information(*mainWindow, text); -} diff --git a/bsnes/target-ui/interface/snes/snes.hpp b/bsnes/target-ui/interface/snes/snes.hpp deleted file mode 100755 index 108cbcaa..00000000 --- a/bsnes/target-ui/interface/snes/snes.hpp +++ /dev/null @@ -1,37 +0,0 @@ -struct InterfaceSNES : InterfaceCore, SFC::Interface { - void initialize(); - - string markup(); - - void setController(bool port, unsigned device); - - bool cartridgeLoaded(); - vector loadCartridge(const string &filename, CartridgePath &cartridge); - bool loadCartridge(string basename); - bool loadSatellaviewSlottedCartridge(string basename, string slotname); - bool loadSatellaviewCartridge(string basename, string slotname); - bool loadSufamiTurboCartridge(string basename, string slotAname, string slotBname); - bool loadSuperGameBoyCartridge(string basename, string slotname); - void unloadCartridge(); - - void power(); - void reset(); - void run(); - - string memoryName(SFC::Cartridge::NonVolatileRAM &memory); - void loadMemory(); - void saveMemory(); - - serializer serialize(); - bool unserialize(serializer&); - - void setCheats(const lstring &list = lstring{}); - - uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue); - void videoRefresh(const uint32_t *data, unsigned pitch, unsigned width, unsigned height); - void audioSample(int16_t lsample, int16_t rsample); - int16_t inputPoll(unsigned port, unsigned device, unsigned id); - - string path(SFC::Cartridge::Slot slot, const string &hint); - void message(const string &text); -}; diff --git a/bsnes/target-ui/main.cpp b/bsnes/target-ui/main.cpp deleted file mode 100755 index 675da4e6..00000000 --- a/bsnes/target-ui/main.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "base.hpp" - -Application *application = nullptr; -nall::DSP dspaudio; - -//allow files to exist in the same folder as binary; -//otherwise default to home folder -string Application::path(const string &filename) { - string result = {basepath, filename}; - if(file::exists(result)) return result; - return {userpath, filename}; -} - -void Application::run() { - inputManager->scan(); - - autopause = (mainWindow->focused() == false && config->input.focusPolicy == 2); - utility->updateStatus(); - - if(interface->cartridgeLoaded() == false || pause || autopause) { - audio.clear(); - usleep(20 * 1000); - return; - } - - interface->run(); -} - -Application::Application(int argc, char **argv) { - title = {"bsnes v", Version}; - - application = this; - quit = false; - pause = false; - autopause = false; - - { - char path[PATH_MAX]; - auto unused = ::realpath(argv[0], path); - basepath = dir(path); - unused = ::userpath(path); - userpath = path; - if(Intrinsics::platform() == Intrinsics::Platform::Windows) { - userpath.append("bsnes/"); - } else { - userpath.append(".config/bsnes/"); - } - mkdir(userpath, 0755); - } - - config = new Config; - interface = new Interface; - inputManager = new InputManager; - utility = new Utility; - - string fontFamily = Intrinsics::platform() == Intrinsics::Platform::Windows ? "Tahoma, " : "Sans, "; - string monoFamily = Intrinsics::platform() == Intrinsics::Platform::Windows ? "Lucida Console, " : "Liberation Mono, "; - normalFont = {fontFamily, "8"}; - boldFont = {fontFamily, "8, Bold"}; - titleFont = {fontFamily, "16, Bold"}; - monospaceFont = {monoFamily, "8"}; - - compositionEnable = compositor::enabled(); - if(config->video.compositionMode == 2) compositor::enable(false); - - windowManager = new WindowManager; - mainWindow = new MainWindow; - fileBrowser = new FileBrowser; - dipSwitches = new DipSwitches; - informationWindow = new InformationWindow; - settingsWindow = new SettingsWindow; - cheatDatabase = new CheatDatabase; - cheatEditor = new CheatEditor; - stateManager = new StateManager; - windowManager->loadGeometry(); - - utility->setMode(Interface::Mode::None); - mainWindow->setVisible(); - - video.driver(config->video.driver); - video.set(Video::Handle, mainWindow->viewport.handle()); - video.set(Video::Synchronize, config->video.synchronize); - if(!video.cap(Video::Depth) || !video.set(Video::Depth, depth = 30u)) { - video.set(Video::Depth, depth = 24u); - } - if(video.init() == false) { - MessageWindow::critical(*mainWindow, {"Failed to initialize ", config->video.driver, " video driver."}); - video.driver("None"); - video.init(); - } - utility->bindVideoFilter(); - utility->bindVideoShader(); - - audio.driver(config->audio.driver); - audio.set(Audio::Handle, mainWindow->viewport.handle()); - audio.set(Audio::Synchronize, config->audio.synchronize); - audio.set(Audio::Latency, config->audio.latency); - audio.set(Audio::Frequency, config->audio.frequency); - if(audio.init() == false) { - MessageWindow::critical(*mainWindow, {"Failed to initialize ", config->audio.driver, " audio driver."}); - audio.driver("None"); - audio.init(); - } - - dspaudio.setPrecision(16); - dspaudio.setVolume(config->audio.mute == false ? (double)config->audio.volume / 100.0 : 0.0); - dspaudio.setBalance(0.0); - dspaudio.setResampler(DSP::ResampleEngine::Sinc); - dspaudio.setResamplerFrequency(config->audio.frequency); - - input.driver(config->input.driver); - input.set(Input::Handle, mainWindow->viewport.handle()); - if(input.init() == false) { - MessageWindow::critical(*mainWindow, {"Failed to initialize ", config->input.driver, " input driver."}); - input.driver("None"); - input.init(); - } - - if(config->video.startFullScreen) utility->toggleFullScreen(); - if(argc == 2) interface->loadCartridge(argv[1]); - - while(quit == false) { - OS::processEvents(); - Application::run(); - } - - interface->unloadCartridge(); - windowManager->saveGeometry(); - windowManager->hideAll(); - if(compositionEnable) compositor::enable(true); -} - -Application::~Application() { - delete stateManager; - delete cheatEditor; - delete cheatDatabase; - delete settingsWindow; - delete informationWindow; - delete dipSwitches; - delete fileBrowser; - delete mainWindow; - delete windowManager; - delete utility; - delete inputManager; - delete interface; - delete config; -} - -int main(int argc, char **argv) { - new Application(argc, argv); - delete application; - return 0; -} diff --git a/bsnes/target-ui/resource.rc b/bsnes/target-ui/resource.rc deleted file mode 100755 index 7fc5b0e3..00000000 --- a/bsnes/target-ui/resource.rc +++ /dev/null @@ -1,2 +0,0 @@ -1 24 "../data/bsnes.Manifest" -2 ICON DISCARDABLE "../data/bsnes.ico" diff --git a/bsnes/target-ui/settings/advanced.cpp b/bsnes/target-ui/settings/advanced.cpp deleted file mode 100755 index cf43888e..00000000 --- a/bsnes/target-ui/settings/advanced.cpp +++ /dev/null @@ -1,78 +0,0 @@ -AdvancedSettings *advancedSettings = nullptr; - -AdvancedSettings::AdvancedSettings() { - title.setFont(application->titleFont); - title.setText("Advanced Settings"); - driverLabel.setFont(application->boldFont); - driverLabel.setText("Driver selection: (changes require restart to take effect)"); - videoLabel.setText("Video:"); - audioLabel.setText("Audio:"); - inputLabel.setText("Input:"); - focusPolicyLabel.setFont(application->boldFont); - focusPolicyLabel.setText("When emulation window does not have focus:"); - focusPolicy[0].setText("Allow input"); - focusPolicy[1].setText("Ignore input"); - focusPolicy[2].setText("Pause emulation"); - RadioBox::group(focusPolicy[0], focusPolicy[1], focusPolicy[2]); - focusPolicy[config->input.focusPolicy].setChecked(); - - lstring list; - - list.split(";", video.driver_list()); - for(unsigned n = 0; n < list.size(); n++) { - videoDriver.append(list[n]); - if(list[n] == config->video.driver) videoDriver.setSelection(n); - if(list[n] == video.default_driver() && config->video.driver == "") videoDriver.setSelection(n); - } - - list.split(";", audio.driver_list()); - for(unsigned n = 0; n < list.size(); n++) { - audioDriver.append(list[n]); - if(list[n] == config->audio.driver) audioDriver.setSelection(n); - if(list[n] == audio.default_driver() && config->audio.driver == "") audioDriver.setSelection(n); - } - - list.split(";", input.driver_list()); - for(unsigned n = 0; n < list.size(); n++) { - inputDriver.append(list[n]); - if(list[n] == config->input.driver) inputDriver.setSelection(n); - if(list[n] == input.default_driver() && config->input.driver == "") inputDriver.setSelection(n); - } - - append(title, { ~0, 0 }, 5); - append(driverLabel, { ~0, 0 }, 0); - append(driverLayout, { ~0, 0 }, 5); - driverLayout.append(videoLabel, { 0, 0 }, 5); - driverLayout.append(videoDriver, { ~0, 0 }, 5); - driverLayout.append(audioLabel, { 0, 0 }, 5); - driverLayout.append(audioDriver, { ~0, 0 }, 5); - driverLayout.append(inputLabel, { 0, 0 }, 5); - driverLayout.append(inputDriver, { ~0, 0 }, 0); - append(focusPolicyLabel, { ~0, 0 }, 0); - append(focusPolicyLayout, { ~0, 0 }, 5); - focusPolicyLayout.append(focusPolicy[0], { ~0, 0 }, 5); - focusPolicyLayout.append(focusPolicy[1], { ~0, 0 }, 5); - focusPolicyLayout.append(focusPolicy[2], { ~0, 0 }, 0); - - videoDriver.onChange = [&] { - lstring list; - list.split(";", video.driver_list()); - config->video.driver = list[videoDriver.selection()]; - }; - - audioDriver.onChange = [&] { - lstring list; - list.split(";", audio.driver_list()); - config->audio.driver = list[audioDriver.selection()]; - }; - - inputDriver.onChange = [&] { - lstring list; - list.split(";", input.driver_list()); - config->input.driver = list[inputDriver.selection()]; - }; - - focusPolicy[0].onActivate = [&] { config->input.focusPolicy = 0; }; - focusPolicy[1].onActivate = [&] { config->input.focusPolicy = 1; }; - focusPolicy[2].onActivate = [&] { config->input.focusPolicy = 2; }; -} diff --git a/bsnes/target-ui/settings/advanced.hpp b/bsnes/target-ui/settings/advanced.hpp deleted file mode 100755 index 860527d8..00000000 --- a/bsnes/target-ui/settings/advanced.hpp +++ /dev/null @@ -1,18 +0,0 @@ -struct AdvancedSettings : SettingsLayout { - Label title; - Label driverLabel; - HorizontalLayout driverLayout; - Label videoLabel; - ComboBox videoDriver; - Label audioLabel; - ComboBox audioDriver; - Label inputLabel; - ComboBox inputDriver; - Label focusPolicyLabel; - HorizontalLayout focusPolicyLayout; - RadioBox focusPolicy[3]; - - AdvancedSettings(); -}; - -extern AdvancedSettings *advancedSettings; diff --git a/bsnes/target-ui/settings/audio.cpp b/bsnes/target-ui/settings/audio.cpp deleted file mode 100755 index 1d9ccc08..00000000 --- a/bsnes/target-ui/settings/audio.cpp +++ /dev/null @@ -1,160 +0,0 @@ -AudioSettings *audioSettings = nullptr; - -AudioSlider::AudioSlider() { - append(name, { 50, 0 }); - append(value, { 75, 0 }); - append(slider, { ~0, 0 }); -} - -unsigned AudioSlider::position() { - unsigned value = slider.position(), center = slider.length() >> 1; - if(value > center) return base + (value - center) * step; - if(value < center) return base - (center - value) * step; - return base; -} - -void AudioSlider::setPosition(unsigned position) { - signed value = position - base, center = slider.length() >> 1; - if(value < 0) return slider.setPosition(center - (abs(value) / step)); - if(value > 0) return slider.setPosition((abs(value) / step) + center); - return slider.setPosition(center); -} - -AudioSettings::AudioSettings() { - title.setFont(application->titleFont); - title.setText("Audio Settings"); - - outputLabel.setFont(application->boldFont); - outputLabel.setText("Output settings:"); - - frequencyLabel.setText("Frequency:"); - frequencySelection.append("32000hz"); - frequencySelection.append("44100hz"); - frequencySelection.append("48000hz"); - frequencySelection.append("96000hz"); - - latencyLabel.setText("Latency:"); - latencySelection.append( "40ms"); - latencySelection.append( "60ms"); - latencySelection.append( "80ms"); - latencySelection.append("100ms"); - latencySelection.append("120ms"); - - resamplerLabel.setText("Resampler:"); - resamplerSelection.append("Linear"); - resamplerSelection.append("Hermite"); - resamplerSelection.append("Sinc"); - - volume.name.setText("Volume:"); - volume.slider.setLength(201); - volume.base = 100; - volume.step = 1; - - frequencyAdjustmentLabel.setFont(application->boldFont); - frequencyAdjustmentLabel.setText("Frequency: (lower to reduce audio crackling; raise to reduce video tearing)"); - - nes.name.setText("FC:"); - nes.slider.setLength(2001); - nes.base = 1789772; - nes.step = 56; - - snes.name.setText("SFC:"); - snes.slider.setLength(2001); - snes.base = 32000; - snes.step = 1; - - gb.name.setText("GB:"); - gb.slider.setLength(2001); - gb.base = 4194304; - gb.step = 131; - - gba.name.setText("GBA:"); - gba.slider.setLength(2001); - gba.base = 32768; - gba.step = 1; - - append(title, { ~0, 0 }, 5); - append(outputLabel, { ~0, 0 }, 0); - append(outputLayout, { ~0, 0 }, 5); - outputLayout.append(frequencyLabel, { 0, 0 }, 5); - outputLayout.append(frequencySelection, { ~0, 0 }, 5); - outputLayout.append(latencyLabel, { 0, 0 }, 5); - outputLayout.append(latencySelection, { ~0, 0 }, 5); - outputLayout.append(resamplerLabel, { 0, 0 }, 5); - outputLayout.append(resamplerSelection, { ~0, 0 }, 0); - append(volume, { ~0, 0 }, 5); - append(frequencyAdjustmentLabel, { ~0, 0 }, 0); - append(nes, { ~0, 0 }, 0); - append(snes, { ~0, 0 }, 0); - append(gb, { ~0, 0 }, 0); - append(gba, { ~0, 0 }, 0); - - frequencySelection.setSelection( - config->audio.frequency == 32000 ? 0 : - config->audio.frequency == 44100 ? 1 : - config->audio.frequency == 48000 ? 2 : - config->audio.frequency == 96000 ? 3 : 0 - ); - - latencySelection.setSelection( - config->audio.latency == 40 ? 0 : - config->audio.latency == 60 ? 1 : - config->audio.latency == 80 ? 2 : - config->audio.latency == 100 ? 3 : - config->audio.latency == 120 ? 4 : 0 - ); - - resamplerSelection.setSelection( - config->audio.resampler == "linear" ? 0 : - config->audio.resampler == "hermite" ? 1 : - config->audio.resampler == "sinc" ? 2 : 0 - ); - - volume.setPosition(config->audio.volume); - - nes.setPosition(config->audio.frequencyNES); - snes.setPosition(config->audio.frequencySNES); - gb.setPosition(config->audio.frequencyGB); - gba.setPosition(config->audio.frequencyGBA); - - frequencySelection.onChange = latencySelection.onChange = resamplerSelection.onChange = volume.slider.onChange = - nes.slider.onChange = snes.slider.onChange = gb.slider.onChange = gba.slider.onChange = - { &AudioSettings::synchronize, this }; - - synchronize(); -} - -void AudioSettings::synchronize() { - config->audio.frequency = - frequencySelection.selection() == 0 ? 32000 : - frequencySelection.selection() == 1 ? 44100 : - frequencySelection.selection() == 2 ? 48000 : - frequencySelection.selection() == 3 ? 96000 : 48000; - - config->audio.latency = - latencySelection.selection() == 0 ? 40 : - latencySelection.selection() == 1 ? 60 : - latencySelection.selection() == 2 ? 80 : - latencySelection.selection() == 3 ? 100 : - latencySelection.selection() == 4 ? 120 : 60; - - config->audio.resampler = - resamplerSelection.selection() == 0 ? "linear" : - resamplerSelection.selection() == 1 ? "hermite" : - resamplerSelection.selection() == 2 ? "sinc" : "sinc"; - - config->audio.volume = volume.position(); - - config->audio.frequencyNES = nes.position(); - config->audio.frequencySNES = snes.position(); - config->audio.frequencyGB = gb.position(); - config->audio.frequencyGBA = gba.position(); - - nes.value.setText({ nes.position(), "hz" }); - snes.value.setText({ snes.position(), "hz" }); - gb.value.setText({ gb.position(), "hz" }); - gba.value.setText({ gba.position(), "hz" }); - volume.value.setText({ volume.position(), "%" }); - - interface->updateDSP(); -} diff --git a/bsnes/target-ui/settings/audio.hpp b/bsnes/target-ui/settings/audio.hpp deleted file mode 100755 index dfff2db3..00000000 --- a/bsnes/target-ui/settings/audio.hpp +++ /dev/null @@ -1,35 +0,0 @@ -struct AudioSlider : HorizontalLayout { - Label name; - Label value; - HorizontalSlider slider; - - unsigned base; - unsigned step; - - unsigned position(); - void setPosition(unsigned position); - AudioSlider(); -}; - -struct AudioSettings : SettingsLayout { - Label title; - Label outputLabel; - HorizontalLayout outputLayout; - Label frequencyLabel; - ComboBox frequencySelection; - Label latencyLabel; - ComboBox latencySelection; - Label resamplerLabel; - ComboBox resamplerSelection; - AudioSlider volume; - Label frequencyAdjustmentLabel; - AudioSlider nes; - AudioSlider snes; - AudioSlider gb; - AudioSlider gba; - - void synchronize(); - AudioSettings(); -}; - -extern AudioSettings *audioSettings; diff --git a/bsnes/target-ui/settings/input.cpp b/bsnes/target-ui/settings/input.cpp deleted file mode 100755 index 80244f9d..00000000 --- a/bsnes/target-ui/settings/input.cpp +++ /dev/null @@ -1,151 +0,0 @@ -InputSettings *inputSettings = nullptr; - -InputSettings::InputSettings() : activeInput(0) { - title.setFont(application->titleFont); - title.setText("Input Settings"); - inputList.setHeaderText("Name", "Mapping"); - inputList.setHeaderVisible(); - assignPrimary.setVisible(false); - assignSecondary.setVisible(false); - assignTertiary.setVisible(false); - clearButton.setText("Clear"); - - for(unsigned n = 0; n < inputManager->inputList.size(); n++) { - primary.append(inputManager->inputList[n].name); - } - primaryChange(); - - append(title, { ~0, 0 }, 5); - append(selectionLayout, { ~0, 0 }, 5); - selectionLayout.append(primary, { ~0, 0 }, 5); - selectionLayout.append(secondary, { ~0, 0 }, 5); - selectionLayout.append(tertiary, { ~0, 0 }, 0); - append(inputList, { ~0, ~0 }, 5); - append(controlLayout, { ~0, 0 }, 0); - controlLayout.append(assignPrimary, { 100, 0 }, 5); - controlLayout.append(assignSecondary, { 100, 0 }, 5); - controlLayout.append(assignTertiary, { 100, 0 }, 5); - controlLayout.append(spacer, { ~0, 0 }, 0); - controlLayout.append(clearButton, { 80, 0 }, 0); - - primary.onChange = { &InputSettings::primaryChange, this }; - secondary.onChange = { &InputSettings::secondaryChange, this }; - tertiary.onChange = { &InputSettings::tertiaryChange, this }; - inputList.onChange = { &InputSettings::synchronize, this }; - inputList.onActivate = { &InputSettings::assignInput, this }; - assignPrimary.onActivate = [&] { assignMouseInput(0); }; - assignSecondary.onActivate = [&] { assignMouseInput(1); }; - assignTertiary.onActivate = [&] { assignMouseInput(2); }; - clearButton.onActivate = { &InputSettings::clearInput, this }; - - synchronize(); -} - -void InputSettings::synchronize() { - PrimaryInput &pinput = inputManager->inputList[primary.selection()]; - SecondaryInput &sinput = pinput[secondary.selection()]; - TertiaryInput &tinput = sinput[tertiary.selection()]; - secondary.setEnabled(pinput.size() > 1); - tertiary.setEnabled(sinput.size() > 1); - clearButton.setEnabled(inputList.selected()); -} - -void InputSettings::primaryChange() { - secondary.reset(); - tertiary.reset(); - PrimaryInput &input = inputManager->inputList[primary.selection()]; - for(unsigned n = 0; n < input.size(); n++) { - secondary.append(input[n].name); - } - secondaryChange(); -} - -void InputSettings::secondaryChange() { - tertiary.reset(); - PrimaryInput &pinput = inputManager->inputList[primary.selection()]; - SecondaryInput &input = pinput[secondary.selection()]; - for(unsigned n = 0; n < input.size(); n++) { - tertiary.append(input[n].name); - } - tertiaryChange(); -} - -void InputSettings::tertiaryChange() { - inputList.reset(); - PrimaryInput &pinput = inputManager->inputList[primary.selection()]; - SecondaryInput &sinput = pinput[secondary.selection()]; - TertiaryInput &input = sinput[tertiary.selection()]; - for(unsigned n = 0; n < input.size(); n++) { - inputList.append(input[n].name, input[n].mapping); - } - synchronize(); - inputList.autoSizeColumns(); -} - -void InputSettings::assignInput() { - PrimaryInput &pinput = inputManager->inputList[primary.selection()]; - SecondaryInput &sinput = pinput[secondary.selection()]; - TertiaryInput &tinput = sinput[tertiary.selection()]; - activeInput = &tinput[inputList.selection()]; - - settingsWindow->setStatusText({ "Set asssignment for [", tinput.name, "::", activeInput->name, "] ..." }); - settingsWindow->panelList.setEnabled(false); - primary.setEnabled(false); - secondary.setEnabled(false); - tertiary.setEnabled(false); - inputList.setEnabled(false); - - if(dynamic_cast(activeInput)) { - assignPrimary.setText("Mouse X-axis"); - assignSecondary.setText("Mouse Y-axis"); - assignPrimary.setVisible(true); - assignSecondary.setVisible(true); - } - - if(dynamic_cast(activeInput)) { - assignPrimary.setText("Mouse Left"); - assignSecondary.setText("Mouse Middle"); - assignTertiary.setText("Mouse Right"); - assignPrimary.setVisible(true); - assignSecondary.setVisible(true); - assignTertiary.setVisible(true); - } -} - -void InputSettings::assignMouseInput(unsigned n) { - if(activeInput == 0) return; - - if(dynamic_cast(activeInput)) { - return inputEvent(mouse(0).axis(n), 1u, true); - } - - if(dynamic_cast(activeInput)) { - return inputEvent(mouse(0).button(n), 1u, true); - } -} - -void InputSettings::clearInput() { - PrimaryInput &pinput = inputManager->inputList[primary.selection()]; - SecondaryInput &sinput = pinput[secondary.selection()]; - TertiaryInput &tinput = sinput[tertiary.selection()]; - activeInput = &tinput[inputList.selection()]; - inputEvent(Scancode::None, 1u); -} - -void InputSettings::inputEvent(int16_t scancode, int16_t value, bool allowMouseInput) { - using nall::Mouse; - if(activeInput == 0) return; - if(allowMouseInput == false && (Mouse::isAnyButton(scancode) || Mouse::isAnyAxis(scancode))) return; - if(activeInput->bind(scancode, value) == false) return; - - activeInput = 0; - tertiaryChange(); - settingsWindow->setStatusText(""); - settingsWindow->panelList.setEnabled(true); - primary.setEnabled(true); - inputList.setEnabled(true); - assignPrimary.setVisible(false); - assignSecondary.setVisible(false); - assignTertiary.setVisible(false); - synchronize(); -} diff --git a/bsnes/target-ui/settings/input.hpp b/bsnes/target-ui/settings/input.hpp deleted file mode 100755 index 34d8c11f..00000000 --- a/bsnes/target-ui/settings/input.hpp +++ /dev/null @@ -1,30 +0,0 @@ -struct InputSettings : SettingsLayout { - Label title; - HorizontalLayout selectionLayout; - ComboBox primary; - ComboBox secondary; - ComboBox tertiary; - ListView inputList; - HorizontalLayout controlLayout; - Button assignPrimary; - Button assignSecondary; - Button assignTertiary; - Widget spacer; - Button clearButton; - - InputSettings(); - - void synchronize(); - void primaryChange(); - void secondaryChange(); - void tertiaryChange(); - void assignInput(); - void assignMouseInput(unsigned); - void clearInput(); - void inputEvent(int16_t scancode, int16_t value, bool allowMouseInput = false); - -private: - AbstractInput *activeInput; -}; - -extern InputSettings *inputSettings; diff --git a/bsnes/target-ui/settings/settings.cpp b/bsnes/target-ui/settings/settings.cpp deleted file mode 100755 index d1ff6654..00000000 --- a/bsnes/target-ui/settings/settings.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "../base.hpp" -#include "video.cpp" -#include "audio.cpp" -#include "input.cpp" -#include "advanced.cpp" -SettingsWindow *settingsWindow = nullptr; - -void SettingsLayout::append(Sizable &sizable, const Size &size, unsigned spacing) { - layout.append(sizable, size, spacing); -} - -SettingsLayout::SettingsLayout() { - setMargin(5); - HorizontalLayout::append(spacer, { 120, ~0 }, 5); - HorizontalLayout::append(layout, { ~0, ~0 }, 0); -} - -SettingsWindow::SettingsWindow() { - setTitle("Configuration Settings"); - setGeometry({ 128, 128, 640, 360 }); - setStatusVisible(); - windowManager->append(this, "SettingsWindow"); - - layout.setMargin(5); - panelList.setFont(application->boldFont); - panelList.append("Video"); - panelList.append("Audio"); - panelList.append("Input"); - panelList.append("Advanced"); - - videoSettings = new VideoSettings; - audioSettings = new AudioSettings; - inputSettings = new InputSettings; - advancedSettings = new AdvancedSettings; - - append(layout); - layout.append(panelList, { 120, ~0 }, 5); - append(*videoSettings); - append(*audioSettings); - append(*inputSettings); - append(*advancedSettings); - - panelList.onChange = { &SettingsWindow::panelChanged, this }; - panelList.setSelection(2); - panelChanged(); -} - -SettingsWindow::~SettingsWindow() { - delete advancedSettings; - delete inputSettings; - delete audioSettings; - delete videoSettings; -} - -void SettingsWindow::panelChanged() { - videoSettings->setVisible(false); - audioSettings->setVisible(false); - inputSettings->setVisible(false); - advancedSettings->setVisible(false); - - if(panelList.selected()) switch(panelList.selection()) { - case 0: return videoSettings->setVisible(); - case 1: return audioSettings->setVisible(); - case 2: return inputSettings->setVisible(); - case 3: return advancedSettings->setVisible(); - } -} diff --git a/bsnes/target-ui/settings/settings.hpp b/bsnes/target-ui/settings/settings.hpp deleted file mode 100755 index eee9cc14..00000000 --- a/bsnes/target-ui/settings/settings.hpp +++ /dev/null @@ -1,24 +0,0 @@ -struct SettingsLayout : HorizontalLayout { - Widget spacer; - VerticalLayout layout; - - void append(Sizable &widget, const Size &size, unsigned spacing = 0); - SettingsLayout(); -}; - -#include "video.hpp" -#include "audio.hpp" -#include "input.hpp" -#include "advanced.hpp" - -struct SettingsWindow : Window { - HorizontalLayout layout; - ListView panelList; - - void panelChanged(); - - SettingsWindow(); - ~SettingsWindow(); -}; - -extern SettingsWindow *settingsWindow; diff --git a/bsnes/target-ui/settings/video.cpp b/bsnes/target-ui/settings/video.cpp deleted file mode 100755 index 420f2009..00000000 --- a/bsnes/target-ui/settings/video.cpp +++ /dev/null @@ -1,107 +0,0 @@ -VideoSettings *videoSettings = nullptr; - -VideoSlider::VideoSlider() { - append(name, { 75, 0 }); - append(value, { 75, 0 }); - append(slider, { ~0, 0 }); -} - -VideoSettings::VideoSettings() { - title.setFont(application->titleFont); - title.setText("Video Settings"); - colorAdjustment.setFont(application->boldFont); - colorAdjustment.setText("Color adjustment:"); - brightness.name.setText("Brightness:"); - brightness.slider.setLength(201); - contrast.name.setText("Contrast:"); - contrast.slider.setLength(201); - gamma.name.setText("Gamma:"); - gamma.slider.setLength(101); - overscanAdjustment.setFont(application->boldFont); - overscanAdjustment.setText("Overscan mask:"); - overscanHorizontal.name.setText("Horizontal:"); - overscanHorizontal.slider.setLength(17); - overscanVertical.name.setText("Vertical:"); - overscanVertical.slider.setLength(17); - fullScreenMode.setFont(application->boldFont); - fullScreenMode.setText("Fullscreen mode:"); - fullScreen[0].setText("Center"); - fullScreen[1].setText("Scale"); - fullScreen[2].setText("Stretch"); - RadioBox::group(fullScreen[0], fullScreen[1], fullScreen[2]); - compositorLabel.setText("Disable window compositor:"); - compositorLabel.setFont(application->boldFont); - compositor[0].setText("Never"); - compositor[1].setText("Fullscreen"); - compositor[2].setText("Always"); - RadioBox::group(compositor[0], compositor[1], compositor[2]); - - append(title, { ~0, 0 }, 5); - append(colorAdjustment, { ~0, 0 }, 0); - append(brightness, { ~0, 0 }, 0); - append(contrast, { ~0, 0 }, 0); - append(gamma, { ~0, 0 }, 5); - append(overscanAdjustment, { ~0, 0 }, 0); - append(overscanHorizontal, { ~0, 0 }, 0); - append(overscanVertical, { ~0, 0 }, 5); - append(fullScreenMode, { ~0, 0 }, 0); - append(fullScreenLayout, { ~0, 0 }, 5); - fullScreenLayout.append(fullScreen[0], { ~0, 0 }, 5); - fullScreenLayout.append(fullScreen[1], { ~0, 0 }, 5); - fullScreenLayout.append(fullScreen[2], { ~0, 0 }, 0); - append(compositorLabel, { ~0, 0 }, 0); - append(compositorLayout, { ~0, 0 }, 0); - compositorLayout.append(compositor[0], { ~0, 0 }, 5); - compositorLayout.append(compositor[1], { ~0, 0 }, 5); - compositorLayout.append(compositor[2], { ~0, 0 }, 0); - - brightness.slider.setPosition(config->video.brightness); - contrast.slider.setPosition(config->video.contrast); - gamma.slider.setPosition(config->video.gamma); - overscanHorizontal.slider.setPosition(config->video.maskOverscanHorizontal); - overscanVertical.slider.setPosition(config->video.maskOverscanVertical); - fullScreen[config->video.fullScreenMode].setChecked(); - compositor[config->video.compositionMode].setChecked(); - - synchronize(); - - brightness.slider.onChange = contrast.slider.onChange = gamma.slider.onChange = - overscanHorizontal.slider.onChange = overscanVertical.slider.onChange = - { &VideoSettings::synchronize, this }; - - fullScreen[0].onActivate = [&] { config->video.fullScreenMode = 0; }; - fullScreen[1].onActivate = [&] { config->video.fullScreenMode = 1; }; - fullScreen[2].onActivate = [&] { config->video.fullScreenMode = 2; }; - - compositor[0].onActivate = [&] { - config->video.compositionMode = 0; - compositor::enable(application->compositionEnable); - }; - - compositor[1].onActivate = [&] { - config->video.compositionMode = 1; - compositor::enable(application->compositionEnable && mainWindow->fullScreen() == false); - }; - - compositor[2].onActivate = [&] { - config->video.compositionMode = 2; - compositor::enable(false); - }; -} - -void VideoSettings::synchronize() { - config->video.brightness = brightness.slider.position(); - config->video.contrast = contrast.slider.position(); - config->video.gamma = gamma.slider.position(); - config->video.maskOverscanHorizontal = overscanHorizontal.slider.position(); - config->video.maskOverscanVertical = overscanVertical.slider.position(); - - brightness.value.setText({ config->video.brightness, "%" }); - contrast.value.setText({ config->video.contrast, "%" }); - gamma.value.setText({ 100 + config->video.gamma, "%" }); - - overscanHorizontal.value.setText({ config->video.maskOverscanHorizontal, "px" }); - overscanVertical.value.setText({ config->video.maskOverscanVertical, "px" }); - - interface->updatePalette(); -} diff --git a/bsnes/target-ui/settings/video.hpp b/bsnes/target-ui/settings/video.hpp deleted file mode 100755 index ce5866d1..00000000 --- a/bsnes/target-ui/settings/video.hpp +++ /dev/null @@ -1,29 +0,0 @@ -struct VideoSlider : HorizontalLayout { - Label name; - Label value; - HorizontalSlider slider; - - VideoSlider(); -}; - -struct VideoSettings : SettingsLayout { - Label title; - Label colorAdjustment; - VideoSlider brightness; - VideoSlider contrast; - VideoSlider gamma; - Label overscanAdjustment; - VideoSlider overscanHorizontal; - VideoSlider overscanVertical; - Label fullScreenMode; - HorizontalLayout fullScreenLayout; - RadioBox fullScreen[3]; - Label compositorLabel; - HorizontalLayout compositorLayout; - RadioBox compositor[3]; - - void synchronize(); - VideoSettings(); -}; - -extern VideoSettings *videoSettings; diff --git a/bsnes/target-ui/tools/cheat-database.cpp b/bsnes/target-ui/tools/cheat-database.cpp deleted file mode 100755 index 9b71a512..00000000 --- a/bsnes/target-ui/tools/cheat-database.cpp +++ /dev/null @@ -1,81 +0,0 @@ -CheatDatabase *cheatDatabase = nullptr; - -CheatDatabase::CheatDatabase() { - setGeometry({ 128, 128, 640, 400 }); - windowManager->append(this, "CheatDatabase"); - - layout.setMargin(5); - cheatList.setCheckable(); - selectAllButton.setText("Select All"); - unselectAllButton.setText("Unselect All"); - acceptButton.setText("Add Codes"); - - append(layout); - layout.append(cheatList, { ~0, ~0 }, 5); - layout.append(controlLayout, { ~0, 0 }, 0); - controlLayout.append(selectAllButton, { 100, 0 }, 5); - controlLayout.append(unselectAllButton, { 100, 0 }, 0); - controlLayout.append(spacer, { ~0, 0 }, 0); - controlLayout.append(acceptButton, { 80, 0 }, 0); - - selectAllButton.onActivate = [&] { - for(unsigned n = 0; n < cheatCode.size(); n++) cheatList.setChecked(n, true); - }; - - unselectAllButton.onActivate = [&] { - for(unsigned n = 0; n < cheatCode.size(); n++) cheatList.setChecked(n, false); - }; - - acceptButton.onActivate = { &CheatDatabase::addCodes, this }; -} - -void CheatDatabase::findCodes() { - cheatList.reset(); - cheatCode.reset(); - - string data; - data.readfile(application->path("cheats.xml")); - XML::Document document(data); - for(auto &node : document["database"]) { - if(node.name != "cartridge") continue; - if(node["sha256"].data != interface->sha256()) continue; - - setTitle(node["title"].data); - for(auto &cheat : node) { - if(cheat.name != "cheat") continue; - cheatList.append(cheat["description"].data); - - string codeList; - for(auto &code : cheat) { - if(code.name != "code") continue; - codeList.append(code.data, "+"); - } - codeList.rtrim<1>("+"); - - cheatCode.append({ codeList, "\t", cheat["description"].data }); - } - - setVisible(); - return; - } - - MessageWindow::information(*cheatEditor, "Sorry, no cheat codes were found for this cartridge."); -} - -void CheatDatabase::addCodes() { - for(unsigned n = 0; n < cheatCode.size(); n++) { - if(cheatList.checked(n)) { - lstring part; - part.split<1>("\t", cheatCode[n]); - if(cheatEditor->addCode(part[0], part[1]) == false) { - MessageWindow::warning(*this, "Ran out of empty slots for cheat codes.\nNot all cheat codes were added."); - break; - } - } - } - - setVisible(false); - cheatEditor->updateUI(); - cheatEditor->updateInterface(); - cheatEditor->synchronize(); -} diff --git a/bsnes/target-ui/tools/cheat-database.hpp b/bsnes/target-ui/tools/cheat-database.hpp deleted file mode 100755 index 7c4a89c4..00000000 --- a/bsnes/target-ui/tools/cheat-database.hpp +++ /dev/null @@ -1,18 +0,0 @@ -struct CheatDatabase : Window { - VerticalLayout layout; - ListView cheatList; - HorizontalLayout controlLayout; - Button selectAllButton; - Button unselectAllButton; - Widget spacer; - Button acceptButton; - - void findCodes(); - void addCodes(); - CheatDatabase(); - -private: - lstring cheatCode; -}; - -extern CheatDatabase *cheatDatabase; diff --git a/bsnes/target-ui/tools/cheat-editor.cpp b/bsnes/target-ui/tools/cheat-editor.cpp deleted file mode 100755 index 08368f7d..00000000 --- a/bsnes/target-ui/tools/cheat-editor.cpp +++ /dev/null @@ -1,188 +0,0 @@ -CheatEditor *cheatEditor = nullptr; - -CheatEditor::CheatEditor() { - setTitle("Cheat Editor"); - setGeometry({ 128, 128, 600, 360 }); - windowManager->append(this, "CheatEditor"); - - cheatList.setHeaderText("Slot", "Code", "Description"); - cheatList.setHeaderVisible(); - cheatList.setCheckable(); - codeLabel.setText("Code(s):"); - descLabel.setText("Description:"); - findButton.setText("Find Codes ..."); - clearAllButton.setText("Clear All"); - clearButton.setText("Clear"); - - append(layout); - layout.setMargin(5); - layout.append(cheatList, { ~0, ~0 }, 5); - layout.append(codeLayout, { ~0, 0 }, 5); - codeLayout.append(codeLabel, { 80, 0 }, 0); - codeLayout.append(codeEdit, { ~0, 0 }, 0); - layout.append(descLayout, { ~0, 0 }, 5); - descLayout.append(descLabel, { 80, 0 }, 0); - descLayout.append(descEdit, { ~0, 0 }, 0); - layout.append(controlLayout, { ~0, 0 }, 0); - controlLayout.append(findButton, { 100, 0 }, 0); - controlLayout.append(spacer, { ~0, 0 }, 0); - controlLayout.append(clearAllButton, { 80, 0 }, 5); - controlLayout.append(clearButton, { 80, 0 }, 0); - - for(unsigned n = 0; n < 128; n++) cheatList.append("", "", ""); - updateUI(); - synchronize(); - - cheatList.onChange = { &CheatEditor::synchronize, this }; - cheatList.onToggle = [&](unsigned) { updateInterface(); }; - codeEdit.onChange = { &CheatEditor::updateCode, this }; - descEdit.onChange = { &CheatEditor::updateDesc, this }; - findButton.onActivate = { &CheatDatabase::findCodes, cheatDatabase }; - clearAllButton.onActivate = { &CheatEditor::clearAll, this }; - clearButton.onActivate = { &CheatEditor::clearSelected, this }; -} - -void CheatEditor::synchronize() { - layout.setEnabled(interface->cartridgeLoaded()); - - if(cheatList.selected()) { - unsigned n = cheatList.selection(); - codeEdit.setText(cheatText[n][Code]); - descEdit.setText(cheatText[n][Desc]); - codeEdit.setEnabled(true); - descEdit.setEnabled(true); - clearButton.setEnabled(true); - } else { - codeEdit.setText(""); - codeEdit.setEnabled(false); - descEdit.setText(""); - descEdit.setEnabled(false); - clearButton.setEnabled(false); - } -} - -void CheatEditor::updateUI() { - for(unsigned n = 0; n < 128; n++) { - string code = cheatText[n][Code]; - string description = cheatText[n][Code] == "" && cheatText[n][Desc] == "" ? "(empty)" : cheatText[n][Desc]; - lstring codes; - codes.split("+", code); - cheatList.modify(n, decimal<3>(n + 1), codes.size() == 1 ? code : string{ codes[0], "+..." }, description); - } - cheatList.autoSizeColumns(); -} - -void CheatEditor::updateInterface() { - lstring cheatCodes; - for(unsigned n = 0; n < 128; n++) { - string code = cheatText[n][Code]; - if(cheatList.checked(n) && code != "") cheatCodes.append(code.replace(" ", "")); - } - interface->setCheatCodes(cheatCodes); -} - -void CheatEditor::updateCode() { - unsigned n = cheatList.selection(); - cheatText[n][Code] = codeEdit.text(); - updateUI(), updateInterface(); -} - -void CheatEditor::updateDesc() { - unsigned n = cheatList.selection(); - cheatText[n][Desc] = descEdit.text(); - updateUI(), updateInterface(); -} - -void CheatEditor::clearAll() { - if(MessageWindow::question(*this, "Warning: all cheat codes will be permanently erased!\nAre you sure?") - == MessageWindow::Response::Yes) { - reset(); - } -} - -void CheatEditor::clearSelected() { - unsigned n = cheatList.selection(); - cheatList.setChecked(n, false); - cheatText[n][Code] = ""; - cheatText[n][Desc] = ""; - codeEdit.setText(""); - descEdit.setText(""); - updateUI(), updateInterface(); -} - -void CheatEditor::reset() { - synchronize(); - for(unsigned n = 0; n < 128; n++) { - cheatList.setChecked(n, false); - cheatText[n][Code] = ""; - cheatText[n][Desc] = ""; - } - codeEdit.setText(""); - descEdit.setText(""); - updateUI(), updateInterface(); -} - -bool CheatEditor::load(const string &filename) { - synchronize(); - - string data; - if(data.readfile(filename) == false) return false; - - unsigned n = 0; - XML::Document document(data); - for(auto &cheat : document["cartridge"]) { - if(cheat.name != "cheat") continue; - cheatList.setChecked(n, cheat["enable"].data == "true"); - cheatText[n][Code] = cheat["code"].data; - cheatText[n][Desc] = cheat["description"].data; - if(++n >= 128) break; - } - - updateUI(), updateInterface(); - return true; -} - -bool CheatEditor::save(const string &filename) { - synchronize(); - - signed lastSave = -1; - for(signed n = 127; n >= 0; n--) { - if(cheatText[n][Code] != "" || cheatText[n][Desc] != "") { - lastSave = n; - break; - } - } - - if(lastSave == -1) { - unlink(filename); - return true; - } - - file fp; - if(fp.open(filename, file::mode::write) == false) return false; - - fp.print("\n"); - fp.print("\n"); - for(unsigned n = 0; n <= lastSave; n++) { - fp.print(" \n"); - fp.print(" \n"); - fp.print(" \n"); - fp.print(" \n"); - } - fp.print("\n"); - - fp.close(); - return true; -} - -bool CheatEditor::addCode(const string &code, const string &description) { - for(unsigned n = 0; n < 128; n++) { - if(cheatText[n][Code] == "" && cheatText[n][Desc] == "") { - cheatList.setChecked(n, false); - cheatText[n][Code] = code; - cheatText[n][Desc] = description; - return true; - } - } - return false; -} diff --git a/bsnes/target-ui/tools/cheat-editor.hpp b/bsnes/target-ui/tools/cheat-editor.hpp deleted file mode 100755 index 39334337..00000000 --- a/bsnes/target-ui/tools/cheat-editor.hpp +++ /dev/null @@ -1,36 +0,0 @@ -struct CheatEditor : Window { - VerticalLayout layout; - ListView cheatList; - HorizontalLayout codeLayout; - Label codeLabel; - LineEdit codeEdit; - HorizontalLayout descLayout; - Label descLabel; - LineEdit descEdit; - HorizontalLayout controlLayout; - Button findButton; - Widget spacer; - Button clearAllButton; - Button clearButton; - - void synchronize(); - void updateUI(); - void updateInterface(); - void updateCode(); - void updateDesc(); - void clearAll(); - void clearSelected(); - - void reset(); - bool load(const string &filename); - bool save(const string &filename); - bool addCode(const string &code, const string &description); - - CheatEditor(); - -private: - enum : unsigned { Code = 0, Desc = 1 }; - string cheatText[128][2]; -}; - -extern CheatEditor *cheatEditor; diff --git a/bsnes/target-ui/tools/state-manager.cpp b/bsnes/target-ui/tools/state-manager.cpp deleted file mode 100755 index 28f369fc..00000000 --- a/bsnes/target-ui/tools/state-manager.cpp +++ /dev/null @@ -1,155 +0,0 @@ -StateManager *stateManager = nullptr; - -StateManager::StateManager() { - setTitle("State Manager"); - setGeometry({ 128, 128, 600, 360 }); - windowManager->append(this, "StateManager"); - - stateList.setHeaderText("Slot", "Description"); - stateList.setHeaderVisible(); - descLabel.setText("Description:"); - loadButton.setText("Load"); - saveButton.setText("Save"); - eraseButton.setText("Erase"); - - append(layout); - layout.setMargin(5); - layout.append(stateList, { ~0, ~0 }, 5); - layout.append(descLayout, { ~0, 0 }, 5); - descLayout.append(descLabel, { 0, 0 }, 5); - descLayout.append(descEdit, { ~0, 0 }, 0); - layout.append(controlLayout, { ~0, 0 }, 0); - controlLayout.append(spacer, { ~0, 0 }, 0); - controlLayout.append(loadButton, { 80, 0 }, 5); - controlLayout.append(saveButton, { 80, 0 }, 5); - controlLayout.append(eraseButton, { 80, 0 }, 0); - - for(unsigned n = 0; n < 32; n++) stateList.append(decimal<2>(n + 1), "(empty)"); - stateList.autoSizeColumns(); - - synchronize(); - - stateList.onActivate = { &StateManager::slotLoad, this }; - stateList.onChange = { &StateManager::synchronize, this }; - descEdit.onChange = { &StateManager::slotSaveDescription, this }; - loadButton.onActivate = { &StateManager::slotLoad, this }; - saveButton.onActivate = { &StateManager::slotSave, this }; - eraseButton.onActivate = { &StateManager::slotErase, this }; -} - -void StateManager::synchronize() { - layout.setEnabled(interface->cartridgeLoaded()); - - descEdit.setText(""); - descEdit.setEnabled(false); - controlLayout.setEnabled(stateList.selected()); - if(stateList.selected() == false) return; - - if(slot[stateList.selection()].capacity() > 0) { - descEdit.setText(slotLoadDescription(stateList.selection())); - descEdit.setEnabled(true); - } -} - -void StateManager::refresh() { - for(unsigned n = 0; n < 32; n++) { - stateList.modify(n, decimal<2>(n + 1), slotLoadDescription(n)); - } - stateList.autoSizeColumns(); -} - -void StateManager::reset() { - for(unsigned n = 0; n < 32; n++) slot[n] = serializer(); - synchronize(); - refresh(); -} - -bool StateManager::load(const string &filename, unsigned revision) { - for(unsigned n = 0; n < 32; n++) slot[n] = serializer(); - synchronize(); - - file fp; - if(fp.open(filename, file::mode::read) == false) return false; - - if(fp.readl(4) == 0x31415342) { - if(fp.readl(4) == revision) { //'BSA1' - for(unsigned n = 0; n < 32; n++) { - if(fp.read() == false) continue; - unsigned size = fp.readl(4); - uint8_t *data = new uint8_t[size]; - fp.read(data, size); - slot[n] = serializer(data, size); - delete[] data; - } - } - } - - refresh(); - return true; -} - -bool StateManager::save(const string &filename, unsigned revision) { - bool hasSave = false; - for(unsigned n = 0; n < 32; n++) { - if(slot[n].capacity() > 0) hasSave = true; - } - - if(hasSave == false) { - unlink(filename); - return true; - } - - file fp; - if(fp.open(filename, file::mode::write) == false) return false; - - fp.writel(0x31415342, 4); //'BSA1' - fp.writel(revision, 4); - for(unsigned n = 0; n < 32; n++) { - if(slot[n].capacity() == 0) { - fp.write(false); - } else { - fp.write(true); - fp.writel(slot[n].size(), 4); - fp.write(slot[n].data(), slot[n].size()); - } - } -} - -void StateManager::slotLoad() { - if(stateList.selected() == false) return; - serializer s(slot[stateList.selection()].data(), slot[stateList.selection()].capacity()); - interface->unserialize(s); -} - -void StateManager::slotSave() { - if(stateList.selected()) { - slot[stateList.selection()] = interface->serialize(); - } - refresh(); - synchronize(); - descEdit.setFocused(); -} - -void StateManager::slotErase() { - if(stateList.selected()) { - slot[stateList.selection()] = serializer(); - } - refresh(); - synchronize(); -} - -string StateManager::slotLoadDescription(unsigned n) { - if(slot[n].capacity() == 0) return "(empty)"; - char text[DescriptionLength]; - strmcpy(text, (const char*)slot[n].data() + HeaderLength, DescriptionLength); - return text; -} - -void StateManager::slotSaveDescription() { - if(stateList.selected() == false) return; - string text = descEdit.text(); - if(slot[stateList.selection()].capacity() > 0) { - strmcpy((char*)slot[stateList.selection()].data() + HeaderLength, (const char*)text, DescriptionLength); - } - refresh(); -} diff --git a/bsnes/target-ui/tools/state-manager.hpp b/bsnes/target-ui/tools/state-manager.hpp deleted file mode 100755 index 9d3e7a08..00000000 --- a/bsnes/target-ui/tools/state-manager.hpp +++ /dev/null @@ -1,39 +0,0 @@ -struct StateManager : Window { - VerticalLayout layout; - ListView stateList; - HorizontalLayout descLayout; - Label descLabel; - LineEdit descEdit; - HorizontalLayout controlLayout; - Widget spacer; - Button loadButton; - Button saveButton; - Button eraseButton; - - void synchronize(); - void refresh(); - - void reset(); - bool load(const string &filename, unsigned revision); - bool save(const string &filename, unsigned revision); - - void slotLoad(); - void slotSave(); - void slotErase(); - - string slotLoadDescription(unsigned n); - void slotSaveDescription(); - - StateManager(); - -private: - enum : unsigned { - //these valus are standardized across all emulated platforms: - //{ uint32 signature, version, checksum; char description[512]; ... } - HeaderLength = 12, - DescriptionLength = 512, - }; - serializer slot[32]; -}; - -extern StateManager *stateManager; diff --git a/bsnes/target-ui/tools/tools.cpp b/bsnes/target-ui/tools/tools.cpp deleted file mode 100755 index 7dcad7cf..00000000 --- a/bsnes/target-ui/tools/tools.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "../base.hpp" -#include "cheat-database.cpp" -#include "cheat-editor.cpp" -#include "state-manager.cpp" diff --git a/bsnes/target-ui/tools/tools.hpp b/bsnes/target-ui/tools/tools.hpp deleted file mode 100755 index d6df0ea7..00000000 --- a/bsnes/target-ui/tools/tools.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "cheat-database.hpp" -#include "cheat-editor.hpp" -#include "state-manager.hpp" diff --git a/bsnes/target-ui/utility/utility.cpp b/bsnes/target-ui/utility/utility.cpp deleted file mode 100755 index e11137f9..00000000 --- a/bsnes/target-ui/utility/utility.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "../base.hpp" -Utility *utility = nullptr; - -void Utility::setMode(Interface::Mode mode) { - video.clear(); - audio.clear(); - - mainWindow->nesMenu.setVisible(false); - mainWindow->snesMenu.setVisible(false); - mainWindow->gameBoyMenu.setVisible(false); - mainWindow->gameBoyAdvanceMenu.setVisible(false); - - if(mode == Interface::Mode::None) { - mainWindow->setTitle(application->title); - mainWindow->setStatusText("No cartridge loaded"); - cheatEditor->reset(); - stateManager->reset(); - } - - else if(mode == Interface::Mode::FC) { - mainWindow->setTitle(interface->cartridgeTitle); - mainWindow->nesMenu.setVisible(true); - dspaudio.setChannels(1); - } - - else if(mode == Interface::Mode::SFC) { - mainWindow->setTitle(interface->cartridgeTitle); - mainWindow->snesMenu.setVisible(true); - dspaudio.setChannels(2); - } - - else if(mode == Interface::Mode::GB) { - mainWindow->gameBoyMenu.setText( - GB::system.cgb() == false ? "Game Boy" : "Game Boy Color" - ); - mainWindow->setTitle(interface->cartridgeTitle); - mainWindow->gameBoyMenu.setVisible(true); - dspaudio.setChannels(2); - } - - else if(mode == Interface::Mode::GBA) { - mainWindow->setTitle(interface->cartridgeTitle); - mainWindow->gameBoyAdvanceMenu.setVisible(true); - dspaudio.setChannels(2); - } - - interface->updateDSP(); - mainWindow->synchronize(); - resizeMainWindow(); - informationWindow->update(); -} - -void Utility::resizeMainWindow(bool shrink) { - Geometry geometry = mainWindow->geometry(); - unsigned width = geometry.width, height = geometry.height; - - switch(interface->mode()) { - case Interface::Mode::None: return mainWindow->viewport.setGeometry({ 0, 0, 1, 1 }); - case Interface::Mode::FC: width = 256, height = 240; break; - case Interface::Mode::SFC: width = 256, height = 240; break; - case Interface::Mode::GB: width = 160, height = 144; break; - case Interface::Mode::GBA: width = 240, height = 160; break; - } - - if(config->video.correctAspectRatio) { - if(interface->mode() == Interface::Mode::FC - || interface->mode() == Interface::Mode::SFC - ) width = (double)width * 8.0 / 7.0; - } - - unsigned maxW = geometry.width / width; - unsigned maxH = geometry.height / height; - unsigned maxM = max(1u, min(maxW, maxH)); - - width = width * maxM; - height = height * maxM; - - if(mainWindow->fullScreen() == true) { - if(config->video.fullScreenMode == 1) { //scale - width = (double)width * ((double)geometry.height / height); - height = geometry.height; - } - - if(config->video.fullScreenMode == 2) { //stretch - width = geometry.width; - height = geometry.height; - } - } - - if(shrink == false) { - if(geometry.width < width ) width = geometry.width; - if(geometry.height < height) height = geometry.height; - - mainWindow->viewport.setGeometry({ - (geometry.width - width) / 2, (geometry.height - height) / 2, - width, height - }); - } else { - mainWindow->setGeometry({ geometry.x, geometry.y, width, height }); - mainWindow->viewport.setGeometry({ 0, 0, width, height }); - } -} - -void Utility::toggleFullScreen() { - static Geometry geometry; - - if(mainWindow->fullScreen() == false) { - geometry = mainWindow->geometry(); - mainWindow->setMenuVisible(false); - mainWindow->setStatusVisible(false); - mainWindow->setFullScreen(true); - input.acquire(); - } else { - input.unacquire(); - mainWindow->setMenuVisible(true); - mainWindow->setStatusVisible(true); - mainWindow->setFullScreen(false); - mainWindow->setGeometry(geometry); - } - - resizeMainWindow(); - if(application->compositionEnable) { - if(config->video.compositionMode == 1) { - compositor::enable(mainWindow->fullScreen() == false); - } - } -} - -void Utility::bindVideoFilter() { - if(filter.opened()) filter.close(); - if(config->video.filter == "None") return; - if(filter.open_absolute(config->video.filter)) { - filter.dl_size = filter.sym("filter_size"); - filter.dl_render = filter.sym("filter_render"); - if(!filter.dl_size || !filter.dl_render) filter.close(); - } -} - -void Utility::bindVideoShader() { - if(config->video.shader == "None") { - video.set(Video::Shader, (const char*)""); - video.set(Video::Filter, 0u); - } else if(config->video.shader == "Blur") { - video.set(Video::Shader, (const char*)""); - video.set(Video::Filter, 1u); - } else { - string data; - data.readfile(config->video.shader); - video.set(Video::Shader, (const char*)data); - } -} - -void Utility::updateStatus() { - time_t currentTime = time(0); - string text; - if((currentTime - statusTime) <= 2) { - text = statusMessage; - } else if(interface->cartridgeLoaded() == false) { - text = "No cartridge loaded"; - } else if(application->pause || application->autopause) { - text = "Paused"; - } else { - text = statusText; - } - if(text != mainWindow->statusText()) { - mainWindow->setStatusText(text); - } -} - -void Utility::setStatusText(const string &text) { - statusText = text; -} - -void Utility::showMessage(const string &message) { - statusTime = time(0); - statusMessage = message; -} - -Utility::Utility() { - statusTime = 0; -} diff --git a/bsnes/target-ui/utility/utility.hpp b/bsnes/target-ui/utility/utility.hpp deleted file mode 100755 index 50cfc3b5..00000000 --- a/bsnes/target-ui/utility/utility.hpp +++ /dev/null @@ -1,20 +0,0 @@ -struct Utility { - void setMode(Interface::Mode mode); - void resizeMainWindow(bool shrink = false); - void toggleFullScreen(); - void bindVideoFilter(); - void bindVideoShader(); - - void updateStatus(); - void setStatusText(const string &text); - void showMessage(const string &text); - - Utility(); - -private: - time_t statusTime; - string statusText; - string statusMessage; -}; - -extern Utility *utility; diff --git a/bsnes/target-ui/window/window.cpp b/bsnes/target-ui/window/window.cpp deleted file mode 100755 index 6fe91a70..00000000 --- a/bsnes/target-ui/window/window.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "../base.hpp" -WindowManager *windowManager = nullptr; - -void WindowManager::append(Window *window, const string &name) { - windowList.append({ window, name, geometry(window->geometry()) }); - - window->setMenuFont(application->normalFont); - window->setWidgetFont(application->normalFont); - window->setStatusFont(application->boldFont); -} - -string WindowManager::geometry(const Geometry &geometry) { - return { geometry.x, ",", geometry.y, ",", geometry.width, ",", geometry.height }; -} - -Geometry WindowManager::geometry(const string &geometry) { - lstring part; - part.split(",", geometry); - Geometry geom = { - (signed)integer(part[0]), (signed)integer(part[1]), - (unsigned)decimal(part[2]), (unsigned)decimal(part[3]) - }; - geom.x = max(0, min(7680, geom.x)); - geom.y = max(0, min(4800, geom.y)); - geom.width = min(7680, geom.width ); - geom.height = min(4800, geom.height); - return geom; -} - -void WindowManager::loadGeometry() { - for(auto &window : windowList) { - config.attach(window.geometry, window.name); - } - config.load(application->path("geometry.cfg")); - config.save(application->path("geometry.cfg")); - for(auto &window : windowList) { - window.window->setGeometry(geometry(window.geometry)); - } -} - -void WindowManager::saveGeometry() { - for(auto &window : windowList) { - window.geometry = geometry(window.window->geometry()); - } - config.save(application->path("geometry.cfg")); -} - -//phoenix can destruct windows that are hidden faster -void WindowManager::hideAll() { - for(auto &window : windowList) { - window.window->setVisible(false); - } -} diff --git a/bsnes/target-ui/window/window.hpp b/bsnes/target-ui/window/window.hpp deleted file mode 100755 index 41184cd3..00000000 --- a/bsnes/target-ui/window/window.hpp +++ /dev/null @@ -1,22 +0,0 @@ -struct WindowManager { - struct WindowList { - Window *window; - string name; - string geometry; - }; - vector windowList; - - void append(Window *window, const string &name); - - string geometry(const Geometry &geometry); - Geometry geometry(const string &geometry); - - void loadGeometry(); - void saveGeometry(); - void hideAll(); - -private: - configuration config; -}; - -extern WindowManager *windowManager;