* 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
This commit is contained in:
parent
4075dad0a8
commit
c9a7a0d744
|
@ -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},
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
// save state.
|
||||
savestate_cmd = 1;
|
||||
printf("saving state\n");
|
||||
return 1;
|
||||
if (evt->Modifiers == 0x4) SaveState(1 + (evt->Scancode - 0x3B));
|
||||
else if (evt->Modifiers == 0x0) LoadState(1 + (evt->Scancode - 0x3B));
|
||||
}
|
||||
if (evt->Scancode == 0x3C) // F2
|
||||
else if (evt->Scancode == 0x43) // F9, savestate from/to file
|
||||
{
|
||||
// load state.
|
||||
savestate_cmd = 2;
|
||||
printf("loading state\n");
|
||||
return 1;
|
||||
if (evt->Modifiers == 0x4) SaveState(0);
|
||||
else if (evt->Modifiers == 0x0) LoadState(0);
|
||||
}
|
||||
else if (evt->Scancode == 0x58) // F12, undo savestate
|
||||
{
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue