More work on savestates. There are still some things to solve:
- Setting the menu item as active will make DeSmuME go crazy!? - Saving the state doesn't always work i.e. the state is invalid?!
This commit is contained in:
parent
744b20c0e8
commit
7db290aeb3
|
@ -4,7 +4,7 @@ desmume_glade_SOURCES = \
|
|||
globals.h keyval_names.c main.c printscreen.c \
|
||||
dTools/callbacks_1_ioregs.c dTools/callbacks_2_memview.c \
|
||||
dTools/callbacks_3_palview.c dTools/callbacks_dtools.h \
|
||||
../sndsdl.h ../sndsdl.c ../ctrlssdl.h ../ctrlssdl.c
|
||||
../sndsdl.h ../sndsdl.c ../ctrlssdl.h ../ctrlssdl.c
|
||||
desmume_glade_LDADD = ../libdesmume.a $(SDL_LIBS) $(LIBGLADE_LIBS)
|
||||
desmume_glade_CFLAGS = $(SDL_CFLAGS) $(LIBGLADE_CFLAGS)
|
||||
desmume_glade_LDFLAGS = -rdynamic
|
||||
|
|
|
@ -28,7 +28,14 @@ gboolean ScreenGap=FALSE;
|
|||
|
||||
/* inline & protos */
|
||||
|
||||
inline void SET_SENSITIVE(gchar *w, gboolean b) {
|
||||
gtk_widget_set_sensitive(
|
||||
glade_xml_get_widget(xml, w), TRUE);
|
||||
}
|
||||
|
||||
void enable_rom_features() {
|
||||
scan_savestates();
|
||||
update_savestates_menu();
|
||||
SET_SENSITIVE("menu_exec", TRUE);
|
||||
SET_SENSITIVE("menu_pause", TRUE);
|
||||
SET_SENSITIVE("menu_reset", TRUE);
|
||||
|
@ -55,12 +62,6 @@ void MAINWINDOW_RESIZE() {
|
|||
gtk_window_resize ((GtkWindow*)pWindow,1,1);
|
||||
}
|
||||
|
||||
void inline SET_SENSITIVE(gchar *w, gboolean b) {
|
||||
gtk_widget_set_sensitive(
|
||||
glade_xml_get_widget(xml, w), TRUE);
|
||||
}
|
||||
|
||||
|
||||
/* MENU FILE ***** ***** ***** ***** */
|
||||
void inline ADD_FILTER(GtkWidget * filech, const char * pattern, const char * name) {
|
||||
GtkFileFilter *pFilter;
|
||||
|
@ -128,7 +129,6 @@ void on_menu_quit_activate (GtkMenuItem *menuitem, gpointer user_data) { gtk
|
|||
|
||||
|
||||
/* MENU SAVES ***** ***** ***** ***** */
|
||||
|
||||
void on_loadstate1_activate (GtkMenuItem *m, gpointer d) { loadstate_slot(1); }
|
||||
void on_loadstate2_activate (GtkMenuItem *m, gpointer d) { loadstate_slot(2); }
|
||||
void on_loadstate3_activate (GtkMenuItem *m, gpointer d) { loadstate_slot(3); }
|
||||
|
@ -140,16 +140,16 @@ void on_loadstate8_activate (GtkMenuItem *m, gpointer d) { loadstate_slot(8); }
|
|||
void on_loadstate9_activate (GtkMenuItem *m, gpointer d) { loadstate_slot(9); }
|
||||
void on_loadstate10_activate(GtkMenuItem *m, gpointer d) { loadstate_slot(10); }
|
||||
|
||||
void on_savestate1_activate (GtkMenuItem *m, gpointer d) { savestate_slot(1); }
|
||||
void on_savestate2_activate (GtkMenuItem *m, gpointer d) { savestate_slot(2); }
|
||||
void on_savestate3_activate (GtkMenuItem *m, gpointer d) { savestate_slot(3); }
|
||||
void on_savestate4_activate (GtkMenuItem *m, gpointer d) { savestate_slot(4); }
|
||||
void on_savestate5_activate (GtkMenuItem *m, gpointer d) { savestate_slot(5); }
|
||||
void on_savestate6_activate (GtkMenuItem *m, gpointer d) { savestate_slot(6); }
|
||||
void on_savestate7_activate (GtkMenuItem *m, gpointer d) { savestate_slot(7); }
|
||||
void on_savestate8_activate (GtkMenuItem *m, gpointer d) { savestate_slot(8); }
|
||||
void on_savestate9_activate (GtkMenuItem *m, gpointer d) { savestate_slot(9); }
|
||||
void on_savestate10_activate(GtkMenuItem *m, gpointer d) { savestate_slot(10); }
|
||||
void on_savestate1_activate (GtkMenuItem *m, gpointer d) { update_savestate(1); }
|
||||
void on_savestate2_activate (GtkMenuItem *m, gpointer d) { update_savestate(2); }
|
||||
void on_savestate3_activate (GtkMenuItem *m, gpointer d) { update_savestate(3); }
|
||||
void on_savestate4_activate (GtkMenuItem *m, gpointer d) { update_savestate(4); }
|
||||
void on_savestate5_activate (GtkMenuItem *m, gpointer d) { update_savestate(5); }
|
||||
void on_savestate6_activate (GtkMenuItem *m, gpointer d) { update_savestate(6); }
|
||||
void on_savestate7_activate (GtkMenuItem *m, gpointer d) { update_savestate(7); }
|
||||
void on_savestate8_activate (GtkMenuItem *m, gpointer d) { update_savestate(8); }
|
||||
void on_savestate9_activate (GtkMenuItem *m, gpointer d) { update_savestate(9); }
|
||||
void on_savestate10_activate(GtkMenuItem *m, gpointer d) { update_savestate(10); }
|
||||
|
||||
|
||||
/* MENU EMULATION ***** ***** ***** ***** */
|
||||
|
|
|
@ -50,8 +50,10 @@ void desmume_free()
|
|||
|
||||
int desmume_open(const char *filename)
|
||||
{
|
||||
int i = NDS_LoadROM(filename, MC_TYPE_AUTODETECT, 1);
|
||||
return i;
|
||||
int i;
|
||||
clear_savestates();
|
||||
i = NDS_LoadROM(filename, MC_TYPE_AUTODETECT, 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
void desmume_pause()
|
||||
|
@ -61,12 +63,10 @@ void desmume_pause()
|
|||
|
||||
void desmume_resume()
|
||||
{
|
||||
execute = TRUE;
|
||||
|
||||
execute = TRUE;
|
||||
if(!regMainLoop)
|
||||
{
|
||||
g_idle_add_full(EMULOOP_PRIO, &EmuLoop, NULL, NULL); regMainLoop = TRUE;
|
||||
}
|
||||
if(!regMainLoop)
|
||||
g_idle_add_full(EMULOOP_PRIO, &EmuLoop, NULL, NULL); regMainLoop = TRUE;
|
||||
}
|
||||
|
||||
void desmume_reset()
|
||||
|
|
|
@ -413,7 +413,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">0</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="activate" handler="on_fs0_activate" last_modification_time="Tue, 02 Jan 2007 14:35:13 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
@ -511,7 +511,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">9</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="group">fs0</property>
|
||||
<signal name="activate" handler="on_fs9_activate" last_modification_time="Mon, 01 Jan 2007 16:45:37 GMT"/>
|
||||
</widget>
|
||||
|
@ -535,7 +535,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">1x</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="activate" handler="on_size1x_activate" last_modification_time="Mon, 01 Jan 2007 20:14:20 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
@ -556,7 +556,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">3x</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="group">size1x</property>
|
||||
<signal name="activate" handler="on_size3x_activate" last_modification_time="Mon, 01 Jan 2007 20:14:20 GMT"/>
|
||||
</widget>
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "../sndsdl.h"
|
||||
#include "../ctrlssdl.h"
|
||||
#include "../types.h"
|
||||
#include "../saves.h"
|
||||
#include "desmume.h"
|
||||
|
||||
uint Frameskip;
|
||||
|
|
|
@ -122,10 +122,71 @@ int Write_ConfigFile()
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* ******** Savestate menu items handling ******** */
|
||||
|
||||
void set_menuitem_label(GtkWidget * w, char * text )
|
||||
{
|
||||
GtkLabel * child;
|
||||
|
||||
if ( GTK_BIN(w)->child )
|
||||
{
|
||||
child = GTK_BIN(w)->child;
|
||||
gtk_label_set_text(child, text);
|
||||
}
|
||||
}
|
||||
|
||||
void clear_savestate_menu(char * cb_name, u8 num)
|
||||
{
|
||||
GtkWidget * w;
|
||||
char cb[40];
|
||||
char text[40];
|
||||
|
||||
sprintf( cb, "%s%d", cb_name, num);
|
||||
sprintf( text, "State %d (empty)", num);
|
||||
w = glade_xml_get_widget(xml, cb);
|
||||
set_menuitem_label( w, text );
|
||||
gtk_check_menu_item_set_active((GtkCheckMenuItem*)w, FALSE);
|
||||
}
|
||||
|
||||
void update_savestate_menu(char * cb_name, u8 num)
|
||||
{
|
||||
GtkWidget * w;
|
||||
char cb[40];
|
||||
|
||||
sprintf( cb, "%s%d", cb_name, num);
|
||||
w = glade_xml_get_widget(xml, cb);
|
||||
set_menuitem_label( w, savestates[num-1].date );
|
||||
/* FIXME: Setting the menu item active makes DeSmuME go crazy!? */
|
||||
/* gtk_check_menu_item_set_active((GtkCheckMenuItem*)w, TRUE); */
|
||||
}
|
||||
|
||||
void update_savestates_menu()
|
||||
{
|
||||
char cb[15];
|
||||
u8 i;
|
||||
GtkWidget * w;
|
||||
|
||||
for( i = 1; i <= NB_STATES; i++ )
|
||||
{
|
||||
if( savestates[i-1].exists == TRUE )
|
||||
{
|
||||
update_savestate_menu("loadstate", i);
|
||||
update_savestate_menu("savestate", i);
|
||||
}
|
||||
else
|
||||
{
|
||||
clear_savestate_menu("loadstate", i);
|
||||
clear_savestate_menu("savestate", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_savestate(u8 num)
|
||||
{
|
||||
savestate_slot(num);
|
||||
update_savestate_menu("savestate", num);
|
||||
update_savestate_menu("loadstate", num);
|
||||
}
|
||||
|
||||
/* ***** ***** MAIN ***** ***** */
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "saves.h"
|
||||
#include "MMU.h"
|
||||
#include "NDSSystem.h"
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SAVESTATE_VERSION 010
|
||||
|
||||
|
@ -33,12 +35,58 @@
|
|||
#define MAX_PATH 256
|
||||
#endif
|
||||
|
||||
/* Format time and convert to string */
|
||||
char * format_time(time_t cal_time)
|
||||
{
|
||||
struct tm *time_struct;
|
||||
static char string[30];
|
||||
|
||||
time_struct=localtime(&cal_time);
|
||||
strftime(string, sizeof string, "%Y-%m-%d %H:%M", time_struct);
|
||||
|
||||
return(string);
|
||||
}
|
||||
|
||||
void clear_savestates()
|
||||
{
|
||||
u8 i;
|
||||
for( i = 0; i < NB_STATES; i++ )
|
||||
savestates[i].exists = FALSE;
|
||||
}
|
||||
|
||||
/* Scan for existing savestates and update struct */
|
||||
void scan_savestates()
|
||||
{
|
||||
struct stat sbuf;
|
||||
char filename[MAX_PATH];
|
||||
u8 i;
|
||||
|
||||
clear_savestates();
|
||||
|
||||
for( i = 1; i <= NB_STATES; i++ )
|
||||
{
|
||||
strcpy(filename, szRomBaseName);
|
||||
sprintf(filename+strlen(filename), "%d.dst", i);
|
||||
if( stat(filename,&sbuf) == -1 ) continue;
|
||||
savestates[i-1].exists = TRUE;
|
||||
strcpy(savestates[i-1].date, format_time(sbuf.st_mtime));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void savestate_slot(int num)
|
||||
{
|
||||
struct stat sbuf;
|
||||
char filename[MAX_PATH];
|
||||
|
||||
strcpy(filename, szRomBaseName);
|
||||
sprintf(filename+strlen(filename), "%d.dst", num);
|
||||
savestate_save(filename);
|
||||
|
||||
savestates[num-1].exists = TRUE;
|
||||
if( stat(filename,&sbuf) == -1 ) return;
|
||||
strcpy(savestates[num-1].date, format_time(sbuf.st_mtime));
|
||||
}
|
||||
|
||||
void loadstate_slot(int num)
|
||||
|
|
|
@ -26,20 +26,30 @@ extern "C" {
|
|||
|
||||
#include "types.h"
|
||||
|
||||
#define SRAM_ADDRESS 0x0A000000
|
||||
#define SRAM_SIZE 0x10000
|
||||
#define SRAM_ADDRESS 0x0A000000
|
||||
#define SRAM_SIZE 0x10000
|
||||
#define NB_STATES 10
|
||||
|
||||
u8 sram_read (u32 address);
|
||||
void sram_write (u32 address, u8 value);
|
||||
int sram_load (const char *file_name);
|
||||
int sram_save (const char *file_name);
|
||||
|
||||
int savestate_load (const char *file_name);
|
||||
int savestate_save (const char *file_name);
|
||||
typedef struct
|
||||
{
|
||||
BOOL exists;
|
||||
char date[40];
|
||||
} savestates_t;
|
||||
|
||||
savestates_t savestates[NB_STATES];
|
||||
|
||||
void savestate_slot(int num);
|
||||
void loadstate_slot(int num);
|
||||
void clear_savestates();
|
||||
void scan_savestates();
|
||||
u8 sram_read (u32 address);
|
||||
void sram_write (u32 address, u8 value);
|
||||
int sram_load (const char *file_name);
|
||||
int sram_save (const char *file_name);
|
||||
|
||||
int savestate_load (const char *file_name);
|
||||
int savestate_save (const char *file_name);
|
||||
|
||||
void savestate_slot(int num);
|
||||
void loadstate_slot(int num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue