diff --git a/desmume/src/gtk-glade/Makefile.am b/desmume/src/gtk-glade/Makefile.am index c50a64314..f86952eda 100644 --- a/desmume/src/gtk-glade/Makefile.am +++ b/desmume/src/gtk-glade/Makefile.am @@ -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 diff --git a/desmume/src/gtk-glade/callbacks.c b/desmume/src/gtk-glade/callbacks.c index 7b98e80a3..84e768513 100755 --- a/desmume/src/gtk-glade/callbacks.c +++ b/desmume/src/gtk-glade/callbacks.c @@ -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 ***** ***** ***** ***** */ diff --git a/desmume/src/gtk-glade/desmume.c b/desmume/src/gtk-glade/desmume.c index 2deef6fe7..fef44c4fd 100755 --- a/desmume/src/gtk-glade/desmume.c +++ b/desmume/src/gtk-glade/desmume.c @@ -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() diff --git a/desmume/src/gtk-glade/glade/DeSmuMe.glade b/desmume/src/gtk-glade/glade/DeSmuMe.glade index 15afbb31f..453bac9f2 100755 --- a/desmume/src/gtk-glade/glade/DeSmuMe.glade +++ b/desmume/src/gtk-glade/glade/DeSmuMe.glade @@ -413,7 +413,7 @@ True 0 True - False + True @@ -511,7 +511,7 @@ True 9 True - True + False fs0 @@ -535,7 +535,7 @@ True 1x True - False + True @@ -556,7 +556,7 @@ True 3x True - True + False size1x diff --git a/desmume/src/gtk-glade/globals.h b/desmume/src/gtk-glade/globals.h index 1df79ccc1..e6b94158d 100755 --- a/desmume/src/gtk-glade/globals.h +++ b/desmume/src/gtk-glade/globals.h @@ -45,6 +45,7 @@ #include "../sndsdl.h" #include "../ctrlssdl.h" #include "../types.h" +#include "../saves.h" #include "desmume.h" uint Frameskip; diff --git a/desmume/src/gtk-glade/main.c b/desmume/src/gtk-glade/main.c index a253a9621..d45b12c1f 100755 --- a/desmume/src/gtk-glade/main.c +++ b/desmume/src/gtk-glade/main.c @@ -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 ***** ***** */ diff --git a/desmume/src/saves.c b/desmume/src/saves.c index d30b85df3..d6f807efe 100644 --- a/desmume/src/saves.c +++ b/desmume/src/saves.c @@ -26,6 +26,8 @@ #include "saves.h" #include "MMU.h" #include "NDSSystem.h" +#include +#include #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) diff --git a/desmume/src/saves.h b/desmume/src/saves.h index d76a41824..9d31300ef 100644 --- a/desmume/src/saves.h +++ b/desmume/src/saves.h @@ -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 }