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)
This commit is contained in:
Tim Allen 2012-08-07 23:28:00 +10:00
parent 4cb8b51606
commit be625cc0fb
35 changed files with 168 additions and 100 deletions

View File

@ -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 <nall/platform.hpp>
#include <nall/algorithm.hpp>
#include <nall/directory.hpp>
#include <nall/dl.hpp>
#include <nall/dsp.hpp>
#include <nall/endian.hpp>

View File

@ -108,6 +108,7 @@ struct Interface {
//debugger functions
virtual bool tracerEnable(bool) { return false; }
virtual void exportMemory() {}
Interface() : bind(nullptr) {}
};

View File

@ -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)

View File

@ -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;
}

View File

@ -242,14 +242,14 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" <superfx revision='2'>\n"
" <map address='00-3f:3000-32ff' id='io'/>\n"
" <map address='80-bf:3000-32ff' id='io'/>\n"
" <rom name='program.rom' size='", hex(rom_size), "'/>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='80-bf:8000-ffff' id='rom' mode='linear'/>\n"
" <map address='40-5f:0000-ffff' id='rom' mode='linear'/>\n"
" <map address='c0-df:0000-ffff' id='rom' mode='linear'/>\n"
);
if(ram_size > 0) markup.append(
" <ram name='save.rwm' size='", hex(ram_size), "'/>\n"
" <ram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-3f:6000-7fff' id='ram' mode='linear' size='0x2000'/>\n"
" <map address='80-bf:6000-7fff' id='ram' mode='linear' size='0x2000'/>\n"
" <map address='60-7f:0000-ffff' id='ram' mode='linear'/>\n"
@ -265,7 +265,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" <sa1>\n"
" <map address='00-3f:2200-23ff' id='io'/>\n"
" <map address='80-bf:2200-23ff' id='io'/>\n"
" <rom name='program.rom' size='", hex(rom_size), "'/>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <map address='00-3f:8000-ffff' id='rom'/>\n"
" <map address='80-bf:8000-ffff' id='rom'/>\n"
" <map address='c0-ff:0000-ffff' id='rom'/>\n"
@ -274,7 +274,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" <map address='80-bf:3000-37ff' id='iram'/>\n"
);
if(ram_size > 0) markup.append(
" <bwram name='save.rwm' size='", hex(ram_size), "'/>\n"
" <bwram name='save.rwm' size='0x", hex(ram_size), "'/>\n"
" <map address='00-3f:6000-7fff' id='bwram'/>\n"
" <map address='80-bf:6000-7fff' id='bwram'/>\n"
" <map address='40-4f:0000-ffff' id='bwram'/>\n"

View File

@ -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:

View File

@ -38,6 +38,7 @@
#include <nall/string/trim.hpp>
#include <nall/string/replace.hpp>
#include <nall/string/split.hpp>
#include <nall/string/static.hpp>
#include <nall/string/utf8.hpp>
#include <nall/string/utility.hpp>
#include <nall/string/variadic.hpp>

View File

@ -22,6 +22,8 @@ namespace nall {
};
struct string {
inline static string read(const string &filename);
inline void reserve(unsigned);
inline bool empty() const;

13
bsnes/nall/string/static.hpp Executable file
View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -167,13 +167,14 @@ struct Timer : private nall::base_from_member<pTimer&>, Object {
};
struct Window : private nall::base_from_member<pWindow&>, Object {
static Window None;
nall::function<void ()> onClose;
nall::function<void (Keyboard::Keycode)> onKeyPress;
nall::function<void (Keyboard::Keycode)> onKeyRelease;
nall::function<void ()> onMove;
nall::function<void ()> onSize;
static Window& none();
inline void append() {}
inline void remove() {}
template<typename T, typename... Args> void append(T &arg, Args&... args) { append_(arg); append(args...); }

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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))
);
}

View File

@ -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!

View File

@ -117,6 +117,8 @@ public:
QStatusBar *qtStatus;
QWidget *qtContainer;
static Window& none();
void append(Layout &layout);
void append(Menu &menu);
void append(Widget &widget);

View File

@ -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;

View File

@ -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"";

View File

@ -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));
}

View File

@ -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();

View File

@ -1,4 +1,4 @@
static linear_vector<pTimer*> timers;
static vector<pTimer*> timers;
static void CALLBACK Timer_timeoutProc(HWND hwnd, UINT msg, UINT_PTR timerID, DWORD time) {
for(auto &timer : timers) {

View File

@ -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;

View File

@ -236,9 +236,9 @@ public:
uint16_t productId;
};
linear_vector<Keyboard> lkeyboard;
linear_vector<Mouse> lmouse;
linear_vector<Gamepad> lgamepad;
vector<Keyboard> lkeyboard;
vector<Mouse> lmouse;
vector<Gamepad> 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<Gamepad> lgamepad;
vector<Gamepad> 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<Gamepad> lgamepad;
vector<Gamepad> 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++;

View File

@ -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() {

View File

@ -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();

View File

@ -92,7 +92,9 @@ struct Interface : Emulator::Interface {
void paletteUpdate();
//debugger functions
bool tracerEnable(bool);
void exportMemory();
Interface();

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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(" ", "");