aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2018-10-23 19:57:01 +0200
committerStapleButter <thetotalworm@gmail.com>2018-10-23 19:57:01 +0200
commitc9a7a0d74418e8f4f9419704f96f8336ed1a8587 (patch)
tree5b3b1e026e80e4f981db3554e917843b33e89516
parent4075dad0a88699ea200a613bf136604c4c6dedd7 (diff)
* start coding UI shito for savestates
* change default mapping for L button to the key right next to Shift because we're gonna derp around with it * still some shito to fix, but hang on, we're getting there
-rw-r--r--src/Config.cpp2
-rw-r--r--src/Savestate.cpp6
-rw-r--r--src/libui_sdl/main.cpp273
3 files changed, 237 insertions, 44 deletions
diff --git a/src/Config.cpp b/src/Config.cpp
index 57c5abc..d98ffd3 100644
--- a/src/Config.cpp
+++ b/src/Config.cpp
@@ -75,7 +75,7 @@ ConfigEntry ConfigFile[] =
{"Key_Up", 0, &KeyMapping[6], 328, NULL, 0},
{"Key_Down", 0, &KeyMapping[7], 336, NULL, 0},
{"Key_R", 0, &KeyMapping[8], 54, NULL, 0},
- {"Key_L", 0, &KeyMapping[9], 42, NULL, 0},
+ {"Key_L", 0, &KeyMapping[9], 86, NULL, 0},
{"Key_X", 0, &KeyMapping[10], 17, NULL, 0},
{"Key_Y", 0, &KeyMapping[11], 30, NULL, 0},
diff --git a/src/Savestate.cpp b/src/Savestate.cpp
index 1b6619f..e295f4a 100644
--- a/src/Savestate.cpp
+++ b/src/Savestate.cpp
@@ -16,7 +16,9 @@
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
+#include <stdio.h>
#include "Savestate.h"
+#include "melon_fopen.h"
/*
Savestate format
@@ -54,7 +56,7 @@ Savestate::Savestate(char* filename, bool save)
if (save)
{
Saving = true;
- file = fopen(filename, "wb");
+ file = melon_fopen(filename, "wb");
if (!file)
{
printf("savestate: file %s doesn't exist\n", filename);
@@ -73,7 +75,7 @@ Savestate::Savestate(char* filename, bool save)
else
{
Saving = false;
- file = fopen(filename, "rb");
+ file = melon_fopen(filename, "rb");
if (!file)
{
printf("savestate: file %s doesn't exist\n", filename);
diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp
index 2870cd1..3cb37d3 100644
--- a/src/libui_sdl/main.cpp
+++ b/src/libui_sdl/main.cpp
@@ -40,6 +40,11 @@
#include "../Savestate.h"
+// savestate slot mapping
+// 1-8: regular slots (quick access)
+// '9': load/save arbitrary file
+const int kSavestateNum[9] = {1, 2, 3, 4, 5, 6, 7, 8, 0};
+
const int kScreenRot[4] = {0, 1, 2, 3};
const int kScreenGap[6] = {0, 1, 8, 64, 90, 128};
const int kScreenLayout[3] = {0, 1, 2};
@@ -49,6 +54,10 @@ const int kScreenSizing[4] = {0, 1, 2, 3};
uiWindow* MainWindow;
uiArea* MainDrawArea;
+uiMenuItem* MenuItem_SaveState;
+uiMenuItem* MenuItem_LoadState;
+uiMenuItem* MenuItem_UndoStateLoad;
+
uiMenuItem* MenuItem_Pause;
uiMenuItem* MenuItem_Reset;
uiMenuItem* MenuItem_Stop;
@@ -90,6 +99,10 @@ SDL_Joystick* Joystick;
void SetupScreenRects(int width, int height);
+void SaveState(int slot);
+void LoadState(int slot);
+void UndoStateLoad();
+
void UpdateWindowTitle(void* data)
@@ -141,9 +154,6 @@ void AudioCallback(void* data, Uint8* stream, int len)
}
}
-// hax.
-int savestate_cmd;
-
int EmuThreadFunc(void* burp)
{
NDS::Init();
@@ -156,8 +166,6 @@ int EmuThreadFunc(void* burp)
ScreenDrawInited = false;
Touching = false;
- savestate_cmd = 0;
-
SDL_AudioSpec whatIwant, whatIget;
memset(&whatIwant, 0, sizeof(SDL_AudioSpec));
whatIwant.freq = 47340;
@@ -197,31 +205,6 @@ int EmuThreadFunc(void* burp)
{
EmuStatus = 1;
- // HAX!!
- if (savestate_cmd)
- {
- if (savestate_cmd == 1)
- {
- Savestate* test = new Savestate("SAVEZORZ.bin", true);
- if (NDS::DoSavestate(test))
- printf("savestate saved OK\n");
- else
- printf("saving failed\n");
- delete test;
- }
- else if (savestate_cmd == 2)
- {
- Savestate* test = new Savestate("SAVEZORZ.bin", false);
- if (NDS::DoSavestate(test))
- printf("savestate loaded OK\n");
- else
- printf("loading failed\n");
- delete test;
- }
-
- savestate_cmd = 0;
- }
-
// poll input
u32 keymask = KeyInputMask;
u32 joymask = 0xFFF;
@@ -470,6 +453,10 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt)
if (evt->Modifiers == 0x2) // ALT+key
return 0;
+ // d0rp
+ if (!RunningSomething)
+ return 1;
+
if (evt->Up)
{
for (int i = 0; i < 12; i++)
@@ -478,20 +465,20 @@ int OnAreaKeyEvent(uiAreaHandler* handler, uiArea* area, uiAreaKeyEvent* evt)
}
else if (!evt->Repeat)
{
- // HAX
- if (evt->Scancode == 0x3B) // F1
+ // F keys: 3B-44, 57-58 | SHIFT: mod. 0x4
+ if (evt->Scancode >= 0x3B && evt->Scancode <= 0x42) // F1-F8, quick savestate
+ {
+ if (evt->Modifiers == 0x4) SaveState(1 + (evt->Scancode - 0x3B));
+ else if (evt->Modifiers == 0x0) LoadState(1 + (evt->Scancode - 0x3B));
+ }
+ else if (evt->Scancode == 0x43) // F9, savestate from/to file
{
- // save state.
- savestate_cmd = 1;
- printf("saving state\n");
- return 1;
+ if (evt->Modifiers == 0x4) SaveState(0);
+ else if (evt->Modifiers == 0x0) LoadState(0);
}
- if (evt->Scancode == 0x3C) // F2
+ else if (evt->Scancode == 0x58) // F12, undo savestate
{
- // load state.
- savestate_cmd = 2;
- printf("loading state\n");
- return 1;
+ if (evt->Modifiers == 0x0) UndoStateLoad();
}
for (int i = 0; i < 12; i++)
@@ -758,6 +745,10 @@ void Run()
EmuRunning = 1;
RunningSomething = true;
+ uiMenuItemEnable(MenuItem_SaveState);
+ uiMenuItemEnable(MenuItem_LoadState);
+ uiMenuItemEnable(MenuItem_UndoStateLoad);
+
uiMenuItemEnable(MenuItem_Pause);
uiMenuItemEnable(MenuItem_Reset);
uiMenuItemEnable(MenuItem_Stop);
@@ -771,6 +762,10 @@ void Stop(bool internal)
while (EmuStatus != 2);
RunningSomething = false;
+ uiMenuItemDisable(MenuItem_SaveState);
+ uiMenuItemDisable(MenuItem_LoadState);
+ uiMenuItemDisable(MenuItem_UndoStateLoad);
+
uiMenuItemDisable(MenuItem_Pause);
uiMenuItemDisable(MenuItem_Reset);
uiMenuItemDisable(MenuItem_Stop);
@@ -802,6 +797,143 @@ void TryLoadROM(char* file, int prevstatus)
}
+// SAVESTATE TODO
+// * configurable paths. not everyone wants their ROM directory to be polluted, I guess.
+
+void GetSavestateName(int slot, char* filename, int len)
+{
+ int pos;
+
+ if (ROMPath[0] == '\0') // running firmware, no ROM
+ {
+ strcpy(filename, "firmware");
+ pos = 8;
+ }
+ else
+ {
+ int len = strlen(ROMPath);
+ pos = len;
+ while (ROMPath[pos] != '.' && pos > 0) pos--;
+ if (pos == 0) pos = len;
+ else pos++;
+
+ // avoid buffer overflow. shoddy
+ if (pos > len-5) pos = len-5;
+
+ strncpy(&filename[0], ROMPath, pos);
+ }
+ strcpy(&filename[pos], ".ml");
+ filename[pos+3] = '0'+slot;
+ filename[pos+4] = '\0';
+}
+
+void LoadState(int slot)
+{
+ int prevstatus = EmuRunning;
+ EmuRunning = 2;
+ while (EmuStatus != 2);
+
+ char filename[1024];
+
+ if (slot > 0)
+ {
+ GetSavestateName(slot, filename, 1024);
+ }
+ else
+ {
+ char* file = uiOpenFile(MainWindow, "melonDS savestate|*.ml1;*.ml2;*.ml3;*.ml4;*.ml5;*.ml6;*.ml7;*.ml8;*.mln", NULL);
+ if (!file)
+ {
+ EmuRunning = prevstatus;
+ return;
+ }
+
+ strncpy(filename, file, 1023);
+ filename[1023] = '\0';
+ uiFreeText(file);
+ }
+
+ // backup
+ Savestate* backup = new Savestate("timewarp.mln", true);
+ NDS::DoSavestate(backup);
+ delete backup;
+
+ Savestate* state = new Savestate(filename, false);
+ if (state->Error)
+ {
+ delete state;
+
+ uiMsgBoxError(MainWindow, "Error", "Could not load savestate file.");
+
+ // current state might be crapoed, so restore from sane backup
+ state = new Savestate("timewarp.mln", false);
+ }
+
+ NDS::DoSavestate(state);
+ delete state;
+
+ EmuRunning = prevstatus;
+}
+
+void SaveState(int slot)
+{
+ int prevstatus = EmuRunning;
+ EmuRunning = 2;
+ while (EmuStatus != 2);
+
+ char filename[1024];
+
+ if (slot > 0)
+ {
+ GetSavestateName(slot, filename, 1024);
+ }
+ else
+ {
+ char* file = uiSaveFile(MainWindow, "melonDS savestate|*.ml1;*.ml2;*.ml3;*.ml4;*.ml5;*.ml6;*.ml7;*.ml8;*.mln", NULL);
+ if (!file)
+ {
+ EmuRunning = prevstatus;
+ return;
+ }
+
+ strncpy(filename, file, 1023);
+ filename[1023] = '\0';
+ uiFreeText(file);
+ }
+
+ Savestate* state = new Savestate(filename, true);
+ if (state->Error)
+ {
+ delete state;
+
+ uiMsgBoxError(MainWindow, "Error", "Could not save state.");
+ }
+ else
+ {
+ NDS::DoSavestate(state);
+ delete state;
+ }
+
+ EmuRunning = prevstatus;
+}
+
+void UndoStateLoad()
+{
+ int prevstatus = EmuRunning;
+ EmuRunning = 2;
+ while (EmuStatus != 2);
+
+ // pray that this works
+ // what do we do if it doesn't???
+ // but it should work.
+ Savestate* backup = new Savestate("timewarp.mln", false);
+ NDS::DoSavestate(backup);
+ delete backup;
+
+ EmuRunning = prevstatus;
+}
+
+
int OnCloseWindow(uiWindow* window, void* blarg)
{
if (RunningSomething)
@@ -864,6 +996,23 @@ void OnOpenFile(uiMenuItem* item, uiWindow* window, void* blarg)
uiFreeText(file);
}
+void OnSaveState(uiMenuItem* item, uiWindow* window, void* param)
+{
+ int slot = *(int*)param;
+ SaveState(slot);
+}
+
+void OnLoadState(uiMenuItem* item, uiWindow* window, void* param)
+{
+ int slot = *(int*)param;
+ LoadState(slot);
+}
+
+void OnUndoStateLoad(uiMenuItem* item, uiWindow* window, void* param)
+{
+ UndoStateLoad();
+}
+
void OnRun(uiMenuItem* item, uiWindow* window, void* blarg)
{
if (!RunningSomething)
@@ -1120,6 +1269,44 @@ int main(int argc, char** argv)
menuitem = uiMenuAppendItem(menu, "Open ROM...");
uiMenuItemOnClicked(menuitem, OnOpenFile, NULL);
uiMenuAppendSeparator(menu);
+ {
+ uiMenu* submenu = uiNewMenu("Save state");
+
+ for (int i = 0; i < 9; i++)
+ {
+ char name[32];
+ if (i < 8)
+ sprintf(name, "%d", kSavestateNum[i]);
+ else
+ strcpy(name, "File...");
+
+ uiMenuItem* ssitem = uiMenuAppendItem(submenu, name);
+ uiMenuItemOnClicked(ssitem, OnSaveState, (void*)&kSavestateNum[i]);
+ }
+
+ MenuItem_SaveState = uiMenuAppendSubmenu(menu, submenu);
+ }
+ {
+ uiMenu* submenu = uiNewMenu("Load state");
+
+ for (int i = 0; i < 9; i++)
+ {
+ char name[32];
+ if (i < 8)
+ sprintf(name, "%d", kSavestateNum[i]);
+ else
+ strcpy(name, "File...");
+
+ uiMenuItem* ssitem = uiMenuAppendItem(submenu, name);
+ uiMenuItemOnClicked(ssitem, OnLoadState, (void*)&kSavestateNum[i]);
+ }
+
+ MenuItem_LoadState = uiMenuAppendSubmenu(menu, submenu);
+ }
+ menuitem = uiMenuAppendItem(menu, "Undo state load\tF12");
+ uiMenuItemOnClicked(menuitem, OnUndoStateLoad, NULL);
+ MenuItem_UndoStateLoad = menuitem;
+ uiMenuAppendSeparator(menu);
menuitem = uiMenuAppendItem(menu, "Quit");
uiMenuItemOnClicked(menuitem, OnCloseByMenu, NULL);
@@ -1215,6 +1402,10 @@ int main(int argc, char** argv)
uiWindowOnGetFocus(MainWindow, OnGetFocus, NULL);
uiWindowOnLoseFocus(MainWindow, OnLoseFocus, NULL);
+ uiMenuItemDisable(MenuItem_SaveState);
+ uiMenuItemDisable(MenuItem_LoadState);
+ uiMenuItemDisable(MenuItem_UndoStateLoad);
+
uiMenuItemDisable(MenuItem_Pause);
uiMenuItemDisable(MenuItem_Reset);
uiMenuItemDisable(MenuItem_Stop);