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:
evilynux 2007-01-19 05:45:59 +00:00
parent 744b20c0e8
commit 7db290aeb3
8 changed files with 160 additions and 40 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -45,6 +45,7 @@
#include "../sndsdl.h"
#include "../ctrlssdl.h"
#include "../types.h"
#include "../saves.h"
#include "desmume.h"
uint Frameskip;

View File

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

View File

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

View File

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