From be625cc0fb2d3ae26044c126d46822eba6193ac7 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 7 Aug 2012 23:28:00 +1000 Subject: [PATCH] Update to v089r18 release. byuu says: Changelog: - fixed bsnes to let config files and system folders to be in the same folder as the executable - fixed RawInput driver to compile again without linear_vector - fixed phoenix/Windows to compile again without linear_vector - fixed old vs new name warnings on MinGW w64 (technically the warnings were erroneous, but I worked around them anyway) - added memory export hotkey (SNES driver only; mainly for FEoEZ translation) - restored WRAM randomization for v090 stability (we can discuss that idea for v091+) - fixed SuperFX / SA-1 "0x" prefix in the header generation (drop it into the latest purify if you want) - added nall/Makefile uname support for UnxUtils (was breaking compilation with full UnxUtils in your path otherwise) --- bsnes/emulator/emulator.hpp | 3 +- bsnes/emulator/interface.hpp | 1 + bsnes/nall/Makefile | 3 + bsnes/nall/emulation/super-famicom-usart.hpp | 14 ++-- bsnes/nall/emulation/super-famicom.hpp | 8 +- bsnes/nall/stream/stream.hpp | 2 +- bsnes/nall/string.hpp | 1 + bsnes/nall/string/base.hpp | 2 + bsnes/nall/string/static.hpp | 13 ++++ bsnes/nall/vector.hpp | 2 +- bsnes/phoenix/core/core.cpp | 5 +- bsnes/phoenix/core/core.hpp | 3 +- bsnes/phoenix/gtk/dialog-window.cpp | 8 +- bsnes/phoenix/gtk/message-window.cpp | 8 +- bsnes/phoenix/gtk/platform.hpp | 2 + bsnes/phoenix/gtk/window.cpp | 6 ++ bsnes/phoenix/qt/dialog-window.cpp | 6 +- bsnes/phoenix/qt/message-window.cpp | 8 +- bsnes/phoenix/qt/platform.moc | 2 +- bsnes/phoenix/qt/platform.moc.hpp | 2 + bsnes/phoenix/qt/window.cpp | 6 ++ bsnes/phoenix/windows/dialog-window.cpp | 4 +- bsnes/phoenix/windows/message-window.cpp | 8 +- bsnes/phoenix/windows/platform.hpp | 4 +- bsnes/phoenix/windows/timer.cpp | 2 +- bsnes/phoenix/windows/window.cpp | 6 ++ bsnes/ruby/input/rawinput.cpp | 80 ++++++++++---------- bsnes/sfc/cpu/cpu.cpp | 2 +- bsnes/sfc/interface/interface.cpp | 14 +++- bsnes/sfc/interface/interface.hpp | 2 + bsnes/sfc/system/system.cpp | 5 -- bsnes/target-ethos/ethos.cpp | 2 +- bsnes/target-ethos/general/dip-switches.cpp | 20 ++--- bsnes/target-ethos/general/presentation.cpp | 2 +- bsnes/target-ethos/input/hotkeys.cpp | 12 +++ 35 files changed, 168 insertions(+), 100 deletions(-) create mode 100755 bsnes/nall/string/static.hpp diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index 6bfcfad0..0e83b052 100755 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -3,13 +3,14 @@ namespace Emulator { static const char Name[] = "bsnes"; - static const char Version[] = "089.17"; + static const char Version[] = "089.18"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; } #include #include +#include #include #include #include diff --git a/bsnes/emulator/interface.hpp b/bsnes/emulator/interface.hpp index 63e8e123..c6cd0ceb 100755 --- a/bsnes/emulator/interface.hpp +++ b/bsnes/emulator/interface.hpp @@ -108,6 +108,7 @@ struct Interface { //debugger functions virtual bool tracerEnable(bool) { return false; } + virtual void exportMemory() {} Interface() : bind(nullptr) {} }; diff --git a/bsnes/nall/Makefile b/bsnes/nall/Makefile index e4b0fd1c..bbc4b029 100755 --- a/bsnes/nall/Makefile +++ b/bsnes/nall/Makefile @@ -19,6 +19,9 @@ ifeq ($(platform),) ifeq ($(uname),) platform := win delete = del $(subst /,\,$1) + else ifneq ($(findstring Windows,$(uname)),) + platform := win + delete = del $(subst /,\,$1) else ifneq ($(findstring CYGWIN,$(uname)),) platform := win delete = del $(subst /,\,$1) diff --git a/bsnes/nall/emulation/super-famicom-usart.hpp b/bsnes/nall/emulation/super-famicom-usart.hpp index 60d8ebbd..68dea605 100755 --- a/bsnes/nall/emulation/super-famicom-usart.hpp +++ b/bsnes/nall/emulation/super-famicom-usart.hpp @@ -35,7 +35,7 @@ extern "C" usartproc void usart_init( usart_write = write; } -extern "C" usartproc void usart_main(); +extern "C" usartproc void usart_main(int, char**); // @@ -84,21 +84,19 @@ static void sigint(int) { } int main(int argc, char **argv) { - //requires superuser privileges; otherwise priority = +0 - setpriority(PRIO_PROCESS, 0, -20); + setpriority(PRIO_PROCESS, 0, -20); //requires superuser privileges; otherwise priority = +0 signal(SIGINT, sigint); - bool result = false; - if(argc == 1) result = usart.open("/dev/ttyACM0", 57600, true); - if(argc == 2) result = usart.open(argv[1], 57600, true); - if(result == false) { + if(usart.open("/dev/ttyACM0", 57600, true) == false) { printf("error: unable to open USART hardware device\n"); return 0; } + usart_is_virtual = false; usart_init(usarthw_quit, usarthw_usleep, usarthw_readable, usarthw_read, usarthw_writable, usarthw_write); - usart_main(); + usart_main(argc, argv); usart.close(); + return 0; } diff --git a/bsnes/nall/emulation/super-famicom.hpp b/bsnes/nall/emulation/super-famicom.hpp index 70990de0..597f9893 100755 --- a/bsnes/nall/emulation/super-famicom.hpp +++ b/bsnes/nall/emulation/super-famicom.hpp @@ -242,14 +242,14 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size) " \n" " \n" " \n" - " \n" + " \n" " \n" " \n" " \n" " \n" ); if(ram_size > 0) markup.append( - " \n" + " \n" " \n" " \n" " \n" @@ -265,7 +265,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size) " \n" " \n" " \n" - " \n" + " \n" " \n" " \n" " \n" @@ -274,7 +274,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size) " \n" ); if(ram_size > 0) markup.append( - " \n" + " \n" " \n" " \n" " \n" diff --git a/bsnes/nall/stream/stream.hpp b/bsnes/nall/stream/stream.hpp index d2ef44c5..9d937729 100755 --- a/bsnes/nall/stream/stream.hpp +++ b/bsnes/nall/stream/stream.hpp @@ -69,7 +69,7 @@ struct stream { struct byte { operator uint8_t() const { return s.read(offset); } - byte& operator=(uint8_t data) { s.write(offset, data); } + byte& operator=(uint8_t data) { s.write(offset, data); return *this; } byte(const stream &s, unsigned offset) : s(s), offset(offset) {} private: diff --git a/bsnes/nall/string.hpp b/bsnes/nall/string.hpp index 2fbc1619..8c4f6b2c 100755 --- a/bsnes/nall/string.hpp +++ b/bsnes/nall/string.hpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/bsnes/nall/string/base.hpp b/bsnes/nall/string/base.hpp index c3b01bb3..f70c1247 100755 --- a/bsnes/nall/string/base.hpp +++ b/bsnes/nall/string/base.hpp @@ -22,6 +22,8 @@ namespace nall { }; struct string { + inline static string read(const string &filename); + inline void reserve(unsigned); inline bool empty() const; diff --git a/bsnes/nall/string/static.hpp b/bsnes/nall/string/static.hpp new file mode 100755 index 00000000..ca521cb0 --- /dev/null +++ b/bsnes/nall/string/static.hpp @@ -0,0 +1,13 @@ +#ifdef NALL_STRING_INTERNAL_HPP + +namespace nall { + +string string::read(const string &filename) { + string data; + data.readfile(filename); + return data; +} + +} + +#endif diff --git a/bsnes/nall/vector.hpp b/bsnes/nall/vector.hpp index 3fbc61d0..13200ea6 100755 --- a/bsnes/nall/vector.hpp +++ b/bsnes/nall/vector.hpp @@ -29,7 +29,7 @@ namespace nall { unsigned capacity() const { return poolsize; } T* move() { - T *result = data; + T *result = pool; pool = nullptr; poolsize = 0; objectsize = 0; diff --git a/bsnes/phoenix/core/core.cpp b/bsnes/phoenix/core/core.cpp index 3a7b183e..a6a1ce38 100755 --- a/bsnes/phoenix/core/core.cpp +++ b/bsnes/phoenix/core/core.cpp @@ -14,7 +14,6 @@ #endif static bool OS_quit = false; -Window Window::None; //Color //===== @@ -211,6 +210,10 @@ Timer::~Timer() { //Window //====== +Window& Window::none() { + return pWindow::none(); +} + void Window::append_(Layout &layout) { if(state.layout.append(layout)) { ((Sizable&)layout).state.window = this; diff --git a/bsnes/phoenix/core/core.hpp b/bsnes/phoenix/core/core.hpp index 37930516..1e88ca5d 100755 --- a/bsnes/phoenix/core/core.hpp +++ b/bsnes/phoenix/core/core.hpp @@ -167,13 +167,14 @@ struct Timer : private nall::base_from_member, Object { }; struct Window : private nall::base_from_member, Object { - static Window None; nall::function onClose; nall::function onKeyPress; nall::function onKeyRelease; nall::function onMove; nall::function onSize; + static Window& none(); + inline void append() {} inline void remove() {} template void append(T &arg, Args&... args) { append_(arg); append(args...); } diff --git a/bsnes/phoenix/gtk/dialog-window.cpp b/bsnes/phoenix/gtk/dialog-window.cpp index b9d64886..eb04bd64 100755 --- a/bsnes/phoenix/gtk/dialog-window.cpp +++ b/bsnes/phoenix/gtk/dialog-window.cpp @@ -3,11 +3,11 @@ static string FileDialog(bool save, Window &parent, const string &path, const ls GtkWidget *dialog = gtk_file_chooser_dialog_new( save == 0 ? "Load File" : "Save File", - &parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0, + &parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr, save == 0 ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - (const gchar*)0 + (const gchar*)nullptr ); if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); @@ -47,11 +47,11 @@ string pDialogWindow::folderSelect(Window &parent, const string &path) { GtkWidget *dialog = gtk_file_chooser_dialog_new( "Select Folder", - &parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0, + &parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - (const gchar*)0 + (const gchar*)nullptr ); if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); diff --git a/bsnes/phoenix/gtk/message-window.cpp b/bsnes/phoenix/gtk/message-window.cpp index d0b4f7b4..7cd2172a 100755 --- a/bsnes/phoenix/gtk/message-window.cpp +++ b/bsnes/phoenix/gtk/message-window.cpp @@ -13,7 +13,7 @@ MessageWindow::Response pMessageWindow::information(Window &parent, const string if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL; if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO; GtkWidget *dialog = gtk_message_dialog_new( - &parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0, + &parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, buttonsType, "%s", (const char*)text ); gint response = gtk_dialog_run(GTK_DIALOG(dialog)); @@ -26,7 +26,7 @@ MessageWindow::Response pMessageWindow::question(Window &parent, const string &t if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL; if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO; GtkWidget *dialog = gtk_message_dialog_new( - &parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0, + &parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, buttonsType, "%s", (const char*)text ); gint response = gtk_dialog_run(GTK_DIALOG(dialog)); @@ -39,7 +39,7 @@ MessageWindow::Response pMessageWindow::warning(Window &parent, const string &te if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL; if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO; GtkWidget *dialog = gtk_message_dialog_new( - &parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0, + &parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, buttonsType, "%s", (const char*)text ); gint response = gtk_dialog_run(GTK_DIALOG(dialog)); @@ -52,7 +52,7 @@ MessageWindow::Response pMessageWindow::critical(Window &parent, const string &t if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL; if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO; GtkWidget *dialog = gtk_message_dialog_new( - &parent != &Window::None ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)0, + &parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, buttonsType, "%s", (const char*)text ); gint response = gtk_dialog_run(GTK_DIALOG(dialog)); diff --git a/bsnes/phoenix/gtk/platform.hpp b/bsnes/phoenix/gtk/platform.hpp index dfb4986c..344e8239 100755 --- a/bsnes/phoenix/gtk/platform.hpp +++ b/bsnes/phoenix/gtk/platform.hpp @@ -103,6 +103,8 @@ struct pWindow : public pObject { GtkAllocation lastAllocation; bool onSizePending; + static Window& none(); + void append(Layout &layout); void append(Menu &menu); void append(Widget &widget); diff --git a/bsnes/phoenix/gtk/window.cpp b/bsnes/phoenix/gtk/window.cpp index f1df5584..ae1521a3 100755 --- a/bsnes/phoenix/gtk/window.cpp +++ b/bsnes/phoenix/gtk/window.cpp @@ -116,6 +116,12 @@ static void Window_sizeRequest(GtkWidget *widget, GtkRequisition *requisition, W requisition->height = window->state.geometry.height; } +Window& pWindow::none() { + static Window *window = nullptr; + if(window == nullptr) window = new Window; + return *window; +} + void pWindow::append(Layout &layout) { Geometry geometry = this->geometry(); geometry.x = geometry.y = 0; diff --git a/bsnes/phoenix/qt/dialog-window.cpp b/bsnes/phoenix/qt/dialog-window.cpp index 82c6af5c..680a6e2e 100755 --- a/bsnes/phoenix/qt/dialog-window.cpp +++ b/bsnes/phoenix/qt/dialog-window.cpp @@ -16,7 +16,7 @@ string pDialogWindow::fileOpen(Window &parent, const string &path, const lstring } QString filename = QFileDialog::getOpenFileName( - &parent != &Window::None ? parent.p.qtWindow : 0, "Load File", + &parent != &Window::none() ? parent.p.qtWindow : nullptr, "Open File", QString::fromUtf8(path), QString::fromUtf8(filterList) ); return filename.toUtf8().constData(); @@ -40,7 +40,7 @@ string pDialogWindow::fileSave(Window &parent, const string &path, const lstring } QString filename = QFileDialog::getSaveFileName( - &parent != &Window::None ? parent.p.qtWindow : 0, "Save File", + &parent != &Window::none() ? parent.p.qtWindow : nullptr, "Save File", QString::fromUtf8(path), QString::fromUtf8(filterList) ); return filename.toUtf8().constData(); @@ -48,7 +48,7 @@ string pDialogWindow::fileSave(Window &parent, const string &path, const lstring string pDialogWindow::folderSelect(Window &parent, const string &path) { QString directory = QFileDialog::getExistingDirectory( - &parent != &Window::None ? parent.p.qtWindow : 0, "Select Directory", + &parent != &Window::none() ? parent.p.qtWindow : nullptr, "Select Directory", QString::fromUtf8(path), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks ); string name = directory.toUtf8().constData(); diff --git a/bsnes/phoenix/qt/message-window.cpp b/bsnes/phoenix/qt/message-window.cpp index c850547b..7bceba0f 100755 --- a/bsnes/phoenix/qt/message-window.cpp +++ b/bsnes/phoenix/qt/message-window.cpp @@ -20,28 +20,28 @@ static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons but MessageWindow::Response pMessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) { return MessageWindow_response( - buttons, QMessageBox::information(&parent != &Window::None ? parent.p.qtWindow : 0, " ", + buttons, QMessageBox::information(&parent != &Window::none() ? parent.p.qtWindow : nullptr, " ", QString::fromUtf8(text), MessageWindow_buttons(buttons)) ); } MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) { return MessageWindow_response( - buttons, QMessageBox::question(&parent != &Window::None ? parent.p.qtWindow : 0, " ", + buttons, QMessageBox::question(&parent != &Window::none() ? parent.p.qtWindow : nullptr, " ", QString::fromUtf8(text), MessageWindow_buttons(buttons)) ); } MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) { return MessageWindow_response( - buttons, QMessageBox::warning(&parent != &Window::None ? parent.p.qtWindow : 0, " ", + buttons, QMessageBox::warning(&parent != &Window::none() ? parent.p.qtWindow : nullptr, " ", QString::fromUtf8(text), MessageWindow_buttons(buttons)) ); } MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) { return MessageWindow_response( - buttons, QMessageBox::critical(&parent != &Window::None ? parent.p.qtWindow : 0, " ", + buttons, QMessageBox::critical(&parent != &Window::none() ? parent.p.qtWindow : nullptr, " ", QString::fromUtf8(text), MessageWindow_buttons(buttons)) ); } diff --git a/bsnes/phoenix/qt/platform.moc b/bsnes/phoenix/qt/platform.moc index 991dbebf..3b2db923 100755 --- a/bsnes/phoenix/qt/platform.moc +++ b/bsnes/phoenix/qt/platform.moc @@ -1,7 +1,7 @@ /**************************************************************************** ** Meta object code from reading C++ file 'platform.moc.hpp' ** -** Created: Mon Jun 18 07:31:52 2012 +** Created: Sun Jul 22 02:20:29 2012 ** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3) ** ** WARNING! All changes made in this file will be lost! diff --git a/bsnes/phoenix/qt/platform.moc.hpp b/bsnes/phoenix/qt/platform.moc.hpp index f3e39bb7..9e75fdc8 100755 --- a/bsnes/phoenix/qt/platform.moc.hpp +++ b/bsnes/phoenix/qt/platform.moc.hpp @@ -117,6 +117,8 @@ public: QStatusBar *qtStatus; QWidget *qtContainer; + static Window& none(); + void append(Layout &layout); void append(Menu &menu); void append(Widget &widget); diff --git a/bsnes/phoenix/qt/window.cpp b/bsnes/phoenix/qt/window.cpp index 9ea0d9a4..c6cb35d6 100755 --- a/bsnes/phoenix/qt/window.cpp +++ b/bsnes/phoenix/qt/window.cpp @@ -1,3 +1,9 @@ +Window& pWindow::none() { + static Window *window = nullptr; + if(window == nullptr) window = new Window; + return *window; +} + void pWindow::append(Layout &layout) { Geometry geometry = window.state.geometry; geometry.x = geometry.y = 0; diff --git a/bsnes/phoenix/windows/dialog-window.cpp b/bsnes/phoenix/windows/dialog-window.cpp index dda7d5c9..3005c020 100755 --- a/bsnes/phoenix/windows/dialog-window.cpp +++ b/bsnes/phoenix/windows/dialog-window.cpp @@ -33,7 +33,7 @@ static string FileDialog(bool save, Window &parent, const string &path, const ls OPENFILENAME ofn; memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = &parent != &Window::None ? parent.p.hwnd : 0; + ofn.hwndOwner = &parent != &Window::none() ? parent.p.hwnd : 0; ofn.lpstrFilter = wfilter; ofn.lpstrInitialDir = wdir; ofn.lpstrFile = wfilename; @@ -59,7 +59,7 @@ string pDialogWindow::fileSave(Window &parent, const string &path, const lstring string pDialogWindow::folderSelect(Window &parent, const string &path) { wchar_t wfilename[PATH_MAX + 1] = L""; BROWSEINFO bi; - bi.hwndOwner = &parent != &Window::None ? parent.p.hwnd : 0; + bi.hwndOwner = &parent != &Window::none() ? parent.p.hwnd : 0; bi.pidlRoot = NULL; bi.pszDisplayName = wfilename; bi.lpszTitle = L""; diff --git a/bsnes/phoenix/windows/message-window.cpp b/bsnes/phoenix/windows/message-window.cpp index 45008a95..fca126f4 100755 --- a/bsnes/phoenix/windows/message-window.cpp +++ b/bsnes/phoenix/windows/message-window.cpp @@ -13,7 +13,7 @@ MessageWindow::Response pMessageWindow::information(Window &parent, const string if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK; if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL; if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO; - return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.p.hwnd : 0, utf16_t(text), L"", flags)); + return MessageWindow_response(buttons, MessageBox(&parent != &Window::none() ? parent.p.hwnd : 0, utf16_t(text), L"", flags)); } MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) { @@ -21,7 +21,7 @@ MessageWindow::Response pMessageWindow::question(Window &parent, const string &t if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK; if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL; if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO; - return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.p.hwnd : 0, utf16_t(text), L"", flags)); + return MessageWindow_response(buttons, MessageBox(&parent != &Window::none() ? parent.p.hwnd : 0, utf16_t(text), L"", flags)); } MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) { @@ -29,7 +29,7 @@ MessageWindow::Response pMessageWindow::warning(Window &parent, const string &te if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK; if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL; if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO; - return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.p.hwnd : 0, utf16_t(text), L"", flags)); + return MessageWindow_response(buttons, MessageBox(&parent != &Window::none() ? parent.p.hwnd : 0, utf16_t(text), L"", flags)); } MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) { @@ -37,5 +37,5 @@ MessageWindow::Response pMessageWindow::critical(Window &parent, const string &t if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK; if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL; if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO; - return MessageWindow_response(buttons, MessageBox(&parent != &Window::None ? parent.p.hwnd : 0, utf16_t(text), L"", flags)); + return MessageWindow_response(buttons, MessageBox(&parent != &Window::none() ? parent.p.hwnd : 0, utf16_t(text), L"", flags)); } diff --git a/bsnes/phoenix/windows/platform.hpp b/bsnes/phoenix/windows/platform.hpp index ddc60ffd..96811796 100755 --- a/bsnes/phoenix/windows/platform.hpp +++ b/bsnes/phoenix/windows/platform.hpp @@ -96,6 +96,8 @@ struct pWindow : public pObject { HBRUSH brush; COLORREF brushColor; + static Window& none(); + void append(Layout &layout); void append(Menu &menu); void append(Widget &widget); @@ -228,7 +230,7 @@ struct pWidget : public pSizable { virtual void setGeometry(const Geometry &geometry); void setVisible(bool visible); - pWidget(Widget &widget) : pSizable(widget), widget(widget) { parentWindow = &Window::None; } + pWidget(Widget &widget) : pSizable(widget), widget(widget) { parentWindow = &Window::none(); } void constructor(); void destructor(); virtual void orphan(); diff --git a/bsnes/phoenix/windows/timer.cpp b/bsnes/phoenix/windows/timer.cpp index 39e32a56..99fb5c00 100755 --- a/bsnes/phoenix/windows/timer.cpp +++ b/bsnes/phoenix/windows/timer.cpp @@ -1,4 +1,4 @@ -static linear_vector timers; +static vector timers; static void CALLBACK Timer_timeoutProc(HWND hwnd, UINT msg, UINT_PTR timerID, DWORD time) { for(auto &timer : timers) { diff --git a/bsnes/phoenix/windows/window.cpp b/bsnes/phoenix/windows/window.cpp index 8552e40f..dc8aea28 100755 --- a/bsnes/phoenix/windows/window.cpp +++ b/bsnes/phoenix/windows/window.cpp @@ -12,6 +12,12 @@ void pWindow::updateModality() { static const unsigned FixedStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_BORDER; static const unsigned ResizableStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME; +Window& pWindow::none() { + static Window *window = nullptr; + if(window == nullptr) window = new Window; + return *window; +} + void pWindow::append(Layout &layout) { Geometry geom = window.state.geometry; geom.x = geom.y = 0; diff --git a/bsnes/ruby/input/rawinput.cpp b/bsnes/ruby/input/rawinput.cpp index c8789cc7..33544713 100755 --- a/bsnes/ruby/input/rawinput.cpp +++ b/bsnes/ruby/input/rawinput.cpp @@ -236,9 +236,9 @@ public: uint16_t productId; }; - linear_vector lkeyboard; - linear_vector lmouse; - linear_vector lgamepad; + vector lkeyboard; + vector lmouse; + vector lgamepad; LRESULT window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { if(msg == WM_INPUT) { @@ -250,15 +250,15 @@ public: if(input->header.dwType == RIM_TYPEKEYBOARD) { for(unsigned i = 0; i < lkeyboard.size(); i++) { - if(input->header.hDevice == lkeyboard[i].handle) { - lkeyboard[i].update(input); + if(input->header.hDevice == lkeyboard(i).handle) { + lkeyboard(i).update(input); break; } } } else if(input->header.dwType == RIM_TYPEMOUSE) { for(unsigned i = 0; i < lmouse.size(); i++) { - if(input->header.hDevice == lmouse[i].handle) { - lmouse[i].update(input); + if(input->header.hDevice == lmouse(i).handle) { + lmouse(i).update(input); break; } } @@ -327,26 +327,26 @@ public: if(info.dwType == RIM_TYPEKEYBOARD) { unsigned n = lkeyboard.size(); - lkeyboard[n].handle = pool[i].handle; + lkeyboard(n).handle = pool[i].handle; } else if(info.dwType == RIM_TYPEMOUSE) { unsigned n = lmouse.size(); - lmouse[n].handle = pool[i].handle; + lmouse(n).handle = pool[i].handle; } else if(info.dwType == RIM_TYPEHID) { //if this is a gamepad or joystick device ... if(info.hid.usUsagePage == 1 && (info.hid.usUsage == 4 || info.hid.usUsage == 5)) { //... then cache device information for later use unsigned n = lgamepad.size(); - lgamepad[n].handle = pool[i].handle; - lgamepad[n].vendorId = (uint16_t)info.hid.dwVendorId; - lgamepad[n].productId = (uint16_t)info.hid.dwProductId; + lgamepad(n).handle = pool[i].handle; + lgamepad(n).vendorId = (uint16_t)info.hid.dwVendorId; + lgamepad(n).productId = (uint16_t)info.hid.dwProductId; //per MSDN: XInput devices have "IG_" in their device strings, //which is how they should be identified. string p = (const char*)utf8_t(pool[i].name); if(auto position = strpos(p, "IG_")) { - lgamepad[n].isXInputDevice = true; + lgamepad(n).isXInputDevice = true; } else { - lgamepad[n].isXInputDevice = false; + lgamepad(n).isXInputDevice = false; } } } @@ -448,15 +448,15 @@ public: } }; - linear_vector lgamepad; + vector lgamepad; void poll() { if(!pXInputGetState) return; for(unsigned i = 0; i < lgamepad.size(); i++) { XINPUT_STATE state; - DWORD result = pXInputGetState(lgamepad[i].id, &state); - if(result == ERROR_SUCCESS) lgamepad[i].poll(state); + DWORD result = pXInputGetState(lgamepad(i).id, &state); + if(result == ERROR_SUCCESS) lgamepad(i).poll(state); } } @@ -470,7 +470,7 @@ public: if(result == ERROR_SUCCESS) { //valid controller detected, add to gamepad list unsigned n = lgamepad.size(); - lgamepad[n].id = i; + lgamepad(n).id = i; } } } @@ -542,18 +542,18 @@ public: for(unsigned n = 0; n < 128; n++) button[n] = false; } }; - linear_vector lgamepad; + vector lgamepad; void poll() { for(unsigned i = 0; i < lgamepad.size(); i++) { - if(FAILED(lgamepad[i].handle->Poll())) { - lgamepad[i].handle->Acquire(); + if(FAILED(lgamepad(i).handle->Poll())) { + lgamepad(i).handle->Acquire(); continue; } DIJOYSTATE2 state; - lgamepad[i].handle->GetDeviceState(sizeof(DIJOYSTATE2), &state); - lgamepad[i].poll(state); + lgamepad(i).handle->GetDeviceState(sizeof(DIJOYSTATE2), &state); + lgamepad(i).poll(state); } } @@ -561,9 +561,9 @@ public: //if this is an XInput device, do not acquire it via DirectInput ... //the XInput driver above will handle said device. for(unsigned i = 0; i < rawinput.lgamepad.size(); i++) { - uint32_t guid = MAKELONG(rawinput.lgamepad[i].vendorId, rawinput.lgamepad[i].productId); + uint32_t guid = MAKELONG(rawinput.lgamepad(i).vendorId, rawinput.lgamepad(i).productId); if(guid == instance->guidProduct.Data1) { - if(rawinput.lgamepad[i].isXInputDevice == true) { + if(rawinput.lgamepad(i).isXInputDevice == true) { return DIENUM_CONTINUE; } } @@ -577,7 +577,7 @@ public: device->SetCooperativeLevel(handle, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); device->EnumObjects(DirectInput_EnumJoypadAxesCallback, (void*)this, DIDFT_ABSAXIS); unsigned n = lgamepad.size(); - lgamepad[n].handle = device; + lgamepad(n).handle = device; return DIENUM_CONTINUE; } @@ -601,8 +601,8 @@ public: void term() { for(unsigned i = 0; i < lgamepad.size(); i++) { - lgamepad[i].handle->Unacquire(); - lgamepad[i].handle->Release(); + lgamepad(i).handle->Unacquire(); + lgamepad(i).handle->Release(); } lgamepad.reset(); @@ -699,7 +699,7 @@ public: for(unsigned n = 0; n < nall::Keyboard::Size; n++) { //using keyboard(0)|= instead of keyboard(i)= merges all keyboards to KB0 //this is done to favor ease of mapping over flexibility (eg share laptop+USB keyboard mapping) - table[keyboard(0).key(n)] |= rawinput.lkeyboard[i].state[n]; + table[keyboard(0).key(n)] |= rawinput.lkeyboard(i).state[n]; } } @@ -707,15 +707,15 @@ public: //Mice //==== for(unsigned i = 0; i < min(rawinput.lmouse.size(), (unsigned)Mouse::Count); i++) { - table[mouse(i).axis(0)] = rawinput.lmouse[i].xDistance; - table[mouse(i).axis(1)] = rawinput.lmouse[i].yDistance; - table[mouse(i).axis(2)] = rawinput.lmouse[i].zDistance; + table[mouse(i).axis(0)] = rawinput.lmouse(i).xDistance; + table[mouse(i).axis(1)] = rawinput.lmouse(i).yDistance; + table[mouse(i).axis(2)] = rawinput.lmouse(i).zDistance; for(unsigned n = 0; n < min(5U, (unsigned)Mouse::Buttons); n++) { - table[mouse(i).button(n)] = (bool)(rawinput.lmouse[i].buttonState & (1 << n)); + table[mouse(i).button(n)] = (bool)(rawinput.lmouse(i).buttonState & (1 << n)); } - rawinput.lmouse[i].sync(); + rawinput.lmouse(i).sync(); } ReleaseMutex(rawinput.mutex); @@ -729,14 +729,14 @@ public: for(unsigned i = 0; i < xinput.lgamepad.size(); i++) { if(joy >= Joypad::Count) break; - table[joypad(joy).hat(0)] = xinput.lgamepad[i].hat; + table[joypad(joy).hat(0)] = xinput.lgamepad(i).hat; for(unsigned axis = 0; axis < min(6U, (unsigned)Joypad::Axes); axis++) { - table[joypad(joy).axis(axis)] = xinput.lgamepad[i].axis[axis]; + table[joypad(joy).axis(axis)] = xinput.lgamepad(i).axis[axis]; } for(unsigned button = 0; button < min(10U, (unsigned)Joypad::Buttons); button++) { - table[joypad(joy).button(button)] = xinput.lgamepad[i].button[button]; + table[joypad(joy).button(button)] = xinput.lgamepad(i).button[button]; } joy++; @@ -750,15 +750,15 @@ public: if(joy >= Joypad::Count) break; for(unsigned hat = 0; hat < min(4U, (unsigned)Joypad::Hats); hat++) { - table[joypad(joy).hat(hat)] = dinput.lgamepad[i].hat[hat]; + table[joypad(joy).hat(hat)] = dinput.lgamepad(i).hat[hat]; } for(unsigned axis = 0; axis < min(6U, (unsigned)Joypad::Axes); axis++) { - table[joypad(joy).axis(axis)] = dinput.lgamepad[i].axis[axis]; + table[joypad(joy).axis(axis)] = dinput.lgamepad(i).axis[axis]; } for(unsigned button = 0; button < min(128U, (unsigned)Joypad::Buttons); button++) { - table[joypad(joy).button(button)] = dinput.lgamepad[i].button[button]; + table[joypad(joy).button(button)] = dinput.lgamepad(i).button[button]; } joy++; diff --git a/bsnes/sfc/cpu/cpu.cpp b/bsnes/sfc/cpu/cpu.cpp index cd559ffb..228536e4 100755 --- a/bsnes/sfc/cpu/cpu.cpp +++ b/bsnes/sfc/cpu/cpu.cpp @@ -121,6 +121,7 @@ void CPU::enable() { void CPU::power() { cpu_version = config.cpu.version; + for(auto &byte : wram) byte = random(config.cpu.wram_init_value); regs.a = regs.x = regs.y = 0x0000; regs.s = 0x01ff; @@ -156,7 +157,6 @@ void CPU::reset() { CPU::CPU() { PPUcounter::scanline = {&CPU::scanline, this}; - for(auto &n : wram) n = random(config.cpu.wram_init_value); } CPU::~CPU() { diff --git a/bsnes/sfc/interface/interface.cpp b/bsnes/sfc/interface/interface.cpp index fbce401c..dc4ebda6 100755 --- a/bsnes/sfc/interface/interface.cpp +++ b/bsnes/sfc/interface/interface.cpp @@ -284,7 +284,8 @@ void Interface::paletteUpdate() { } bool Interface::tracerEnable(bool trace) { - string pathname = path(group(ID::ROM)); + string pathname = {path(group(ID::ROM)), "debug/"}; + directory::create(pathname); if(trace == true && !tracer.open()) { for(unsigned n = 0; n <= 999; n++) { @@ -303,6 +304,17 @@ bool Interface::tracerEnable(bool trace) { return false; } +void Interface::exportMemory() { + string pathname = {path(group(ID::ROM)), "debug/"}; + directory::create(pathname); + + file::write({pathname, "wram.rwm"}, cpu.wram, 128 * 1024); + file::write({pathname, "vram.rwm"}, ppu.vram, 64 * 1024); + file::write({pathname, "oam.rwm"}, ppu.oam, 544); + file::write({pathname, "cgram.rwm"}, ppu.cgram, 512); + file::write({pathname, "apuram.rwm"}, smp.apuram, 64 * 1024); +} + Interface::Interface() { interface = this; system.init(); diff --git a/bsnes/sfc/interface/interface.hpp b/bsnes/sfc/interface/interface.hpp index b7b03608..3d84500e 100755 --- a/bsnes/sfc/interface/interface.hpp +++ b/bsnes/sfc/interface/interface.hpp @@ -92,7 +92,9 @@ struct Interface : Emulator::Interface { void paletteUpdate(); + //debugger functions bool tracerEnable(bool); + void exportMemory(); Interface(); diff --git a/bsnes/sfc/system/system.cpp b/bsnes/sfc/system/system.cpp index ffebdcda..feb48f00 100755 --- a/bsnes/sfc/system/system.cpp +++ b/bsnes/sfc/system/system.cpp @@ -101,8 +101,6 @@ void System::load() { interface->notify("Error: required firmware ", firmware, " not found.\n"); } - file::read({path, "wram.rwm"}, cpu.wram, 128 * 1024); - region = config.region; expansion = config.expansion_port; if(region == Region::Autodetect) { @@ -143,9 +141,6 @@ void System::load() { } void System::unload() { - string path = interface->path(ID::System); - file::write({path, "wram.rwm"}, cpu.wram, 128 * 1024); - if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.unload(); if(cartridge.has_gb_slot()) icd2.unload(); if(cartridge.has_bs_cart()) bsxcartridge.unload(); diff --git a/bsnes/target-ethos/ethos.cpp b/bsnes/target-ethos/ethos.cpp index 31162f4f..c0996637 100755 --- a/bsnes/target-ethos/ethos.cpp +++ b/bsnes/target-ethos/ethos.cpp @@ -58,7 +58,7 @@ Application::Application(int argc, char **argv) { pause = false; autopause = false; - basepath = realpath(argv[0]); + basepath = dir(realpath(argv[0])); userpath = {nall::configpath(), "bsnes/"}; directory::create(userpath); diff --git a/bsnes/target-ethos/general/dip-switches.cpp b/bsnes/target-ethos/general/dip-switches.cpp index 46240985..030c7671 100755 --- a/bsnes/target-ethos/general/dip-switches.cpp +++ b/bsnes/target-ethos/general/dip-switches.cpp @@ -11,7 +11,7 @@ DipSwitches::DipSwitches() { accept.setText("Accept"); append(layout); - for(auto &dip : this->dip) layout.append(dip, {~0, 0}, 5); + for(auto &dipItem : dip) layout.append(dipItem, {~0, 0}, 5); layout.append(controlLayout, {~0, 0}); controlLayout.append(spacer, {~0, 0}); controlLayout.append(accept, {80, 0}); @@ -26,12 +26,12 @@ unsigned DipSwitches::run(const XML::Node &node) { 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(); + for(auto &dipItem : dip) { + dipItem.name.setEnabled(false); + dipItem.name.setText("(empty)"); + dipItem.value.setEnabled(false); + dipItem.value.reset(); + dipItem.values.reset(); } unsigned index = 0; @@ -60,9 +60,9 @@ unsigned DipSwitches::run(const XML::Node &node) { setVisible(false); unsigned result = 0; - for(auto &dip : this->dip) { - if(dip.value.enabled() == false) continue; - result |= dip.values[dip.value.selection()]; + for(auto &dipItem : dip) { + if(dipItem.value.enabled() == false) continue; + result |= dipItem.values[dipItem.value.selection()]; } return result; } diff --git a/bsnes/target-ethos/general/presentation.cpp b/bsnes/target-ethos/general/presentation.cpp index 928fbf1a..5c5adab7 100755 --- a/bsnes/target-ethos/general/presentation.cpp +++ b/bsnes/target-ethos/general/presentation.cpp @@ -90,7 +90,7 @@ Presentation::Presentation() : active(nullptr) { loadMenu.append(*new Separator); for(auto &item : loadListSubsystem) loadMenu.append(*item); } - for(auto &system : emulatorList) append(system->menu); + for(auto &systemItem : emulatorList) append(systemItem->menu); append(settingsMenu); settingsMenu.append(videoMenu); videoMenu.append(centerVideo, scaleVideo, stretchVideo, *new Separator, aspectCorrection, maskOverscan); diff --git a/bsnes/target-ethos/input/hotkeys.cpp b/bsnes/target-ethos/input/hotkeys.cpp index 982abde6..978d5dfc 100755 --- a/bsnes/target-ethos/input/hotkeys.cpp +++ b/bsnes/target-ethos/input/hotkeys.cpp @@ -129,6 +129,18 @@ void InputManager::appendHotkeys() { }; } + { + auto hotkey = new HotkeyInput; + hotkey->name = "Export Memory"; + hotkey->mapping = "None"; + + hotkey->press = [&] { + if(application->active == nullptr) return; + system().exportMemory(); + utility->showMessage("Memory exported"); + }; + } + for(auto &hotkey : hotkeyMap) { string name = {"Hotkey::", hotkey->name}; name.replace(" ", "");