# HG changeset patch # User nkeynes # Date 1192620405 0 # Node ID 207461e79f21a4d299c2a9c6440bfcec5e47b34e # Parent 21440948c684ef3ec632660e9484e8bc21d01481 Split config management out to config.[ch] Manage config filename Check home dir + sysconfdir for conf file Initial work on a path settings dialog --- a/src/Makefile.am Tue Oct 16 12:38:01 2007 +0000 +++ b/src/Makefile.am Wed Oct 17 11:26:45 2007 +0000 @@ -3,6 +3,7 @@ INCLUDES = \ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ + -DPACKAGE_CONF_DIR=\""$(sysconfdir)"\" \ -Ish4 \ @PACKAGE_CFLAGS@ @@ -14,7 +15,7 @@ genglsl_SOURCES = tools/genglsl.c lxdream_SOURCES = \ - main.c \ + main.c config.c config.h \ mem.c mem.h mmio.h watch.c \ asic.c asic.h \ syscall.c syscall.h bios.c dcload.c \ @@ -39,7 +40,7 @@ gui/debugif.c gui/debugif.h \ gui/debugcb.c gui/debugcb.h \ gui/mmr_win.c gui/debug_win.c gui/dump_win.c \ - gui/ctrl_dlg.c \ + gui/ctrl_dlg.c gui/path_dlg.c \ loader.c bootstrap.c util.c \ display.c display.h \ drivers/audio_null.c drivers/audio_esd.c \ --- a/src/Makefile.in Tue Oct 16 12:38:01 2007 +0000 +++ b/src/Makefile.in Wed Oct 17 11:26:45 2007 +0000 @@ -136,6 +136,7 @@ INCLUDES = \ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ + -DPACKAGE_CONF_DIR=\""$(sysconfdir)"\" \ -Ish4 \ @PACKAGE_CFLAGS@ @@ -148,7 +149,7 @@ genglsl_SOURCES = tools/genglsl.c lxdream_SOURCES = \ - main.c \ + main.c config.c config.h \ mem.c mem.h mmio.h watch.c \ asic.c asic.h \ syscall.c syscall.h bios.c dcload.c \ @@ -173,7 +174,7 @@ gui/debugif.c gui/debugif.h \ gui/debugcb.c gui/debugcb.h \ gui/mmr_win.c gui/debug_win.c gui/dump_win.c \ - gui/ctrl_dlg.c \ + gui/ctrl_dlg.c gui/path_dlg.c \ loader.c bootstrap.c util.c \ display.c display.h \ drivers/audio_null.c drivers/audio_esd.c \ @@ -221,8 +222,8 @@ genglsl_OBJECTS = $(am_genglsl_OBJECTS) genglsl_DEPENDENCIES = genglsl_LDFLAGS = -am_lxdream_OBJECTS = main.$(OBJEXT) mem.$(OBJEXT) watch.$(OBJEXT) \ - asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \ +am_lxdream_OBJECTS = main.$(OBJEXT) config.$(OBJEXT) mem.$(OBJEXT) \ + watch.$(OBJEXT) asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \ dcload.$(OBJEXT) ide.$(OBJEXT) gdimage.$(OBJEXT) \ gdrom.$(OBJEXT) nrg.$(OBJEXT) cdi.$(OBJEXT) linux.$(OBJEXT) \ dreamcast.$(OBJEXT) eventq.$(OBJEXT) sh4.$(OBJEXT) \ @@ -239,11 +240,12 @@ controller.$(OBJEXT) gtkui.$(OBJEXT) main_win.$(OBJEXT) \ gtkcb.$(OBJEXT) support.$(OBJEXT) debugif.$(OBJEXT) \ debugcb.$(OBJEXT) mmr_win.$(OBJEXT) debug_win.$(OBJEXT) \ - dump_win.$(OBJEXT) ctrl_dlg.$(OBJEXT) loader.$(OBJEXT) \ - bootstrap.$(OBJEXT) util.$(OBJEXT) display.$(OBJEXT) \ - audio_null.$(OBJEXT) audio_esd.$(OBJEXT) video_null.$(OBJEXT) \ - video_gtk.$(OBJEXT) video_x11.$(OBJEXT) gl_common.$(OBJEXT) \ - gl_fbo.$(OBJEXT) gl_sl.$(OBJEXT) gl_slsrc.$(OBJEXT) + dump_win.$(OBJEXT) ctrl_dlg.$(OBJEXT) path_dlg.$(OBJEXT) \ + loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \ + display.$(OBJEXT) audio_null.$(OBJEXT) audio_esd.$(OBJEXT) \ + video_null.$(OBJEXT) video_gtk.$(OBJEXT) video_x11.$(OBJEXT) \ + gl_common.$(OBJEXT) gl_fbo.$(OBJEXT) gl_sl.$(OBJEXT) \ + gl_slsrc.$(OBJEXT) lxdream_OBJECTS = $(am_lxdream_OBJECTS) lxdream_DEPENDENCIES = lxdream_LDFLAGS = @@ -270,24 +272,25 @@ @AMDEP_TRUE@ ./$(DEPDIR)/audio.Po ./$(DEPDIR)/audio_esd.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/audio_null.Po ./$(DEPDIR)/bios.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/bootstrap.Po ./$(DEPDIR)/cdi.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/controller.Po ./$(DEPDIR)/ctrl_dlg.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/dcload.Po ./$(DEPDIR)/debug_win.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/debugcb.Po ./$(DEPDIR)/debugif.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/dis-buf.Po ./$(DEPDIR)/dis-init.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/display.Po ./$(DEPDIR)/dmac.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/dreamcast.Po ./$(DEPDIR)/dump_win.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/eventq.Po ./$(DEPDIR)/gdimage.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gdrom.Po ./$(DEPDIR)/gendec.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/genglsl.Po ./$(DEPDIR)/gl_common.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gl_fbo.Po ./$(DEPDIR)/gl_sl.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gl_slsrc.Po ./$(DEPDIR)/gtkcb.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gtkui.Po ./$(DEPDIR)/i386-dis.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/ide.Po ./$(DEPDIR)/insparse.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/linux.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/main_win.Po ./$(DEPDIR)/maple.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mmr_win.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/nrg.Po ./$(DEPDIR)/pvr2.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/config.Po ./$(DEPDIR)/controller.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ctrl_dlg.Po ./$(DEPDIR)/dcload.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/debug_win.Po ./$(DEPDIR)/debugcb.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/debugif.Po ./$(DEPDIR)/dis-buf.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/dis-init.Po ./$(DEPDIR)/display.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/dmac.Po ./$(DEPDIR)/dreamcast.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/eventq.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/gdimage.Po ./$(DEPDIR)/gdrom.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/gendec.Po ./$(DEPDIR)/genglsl.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/gl_common.Po ./$(DEPDIR)/gl_fbo.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/gl_sl.Po ./$(DEPDIR)/gl_slsrc.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/gtkcb.Po ./$(DEPDIR)/gtkui.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/i386-dis.Po ./$(DEPDIR)/ide.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/insparse.Po ./$(DEPDIR)/intc.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/linux.Po ./$(DEPDIR)/loader.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/main_win.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/nrg.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/path_dlg.Po ./$(DEPDIR)/pvr2.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/pvr2mem.Po ./$(DEPDIR)/rendbkg.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/rendcore.Po ./$(DEPDIR)/render.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/rendsave.Po ./$(DEPDIR)/rendsort.Po \ @@ -386,6 +389,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bios.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bootstrap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controller.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctrl_dlg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dcload.Po@am__quote@ @@ -421,6 +425,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmr_win.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path_dlg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvr2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvr2mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendbkg.Po@am__quote@ @@ -1663,6 +1668,28 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ctrl_dlg.obj `if test -f 'gui/ctrl_dlg.c'; then $(CYGPATH_W) 'gui/ctrl_dlg.c'; else $(CYGPATH_W) '$(srcdir)/gui/ctrl_dlg.c'; fi` +path_dlg.o: gui/path_dlg.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT path_dlg.o -MD -MP -MF "$(DEPDIR)/path_dlg.Tpo" \ +@am__fastdepCC_TRUE@ -c -o path_dlg.o `test -f 'gui/path_dlg.c' || echo '$(srcdir)/'`gui/path_dlg.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/path_dlg.Tpo" "$(DEPDIR)/path_dlg.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/path_dlg.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gui/path_dlg.c' object='path_dlg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/path_dlg.Po' tmpdepfile='$(DEPDIR)/path_dlg.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o path_dlg.o `test -f 'gui/path_dlg.c' || echo '$(srcdir)/'`gui/path_dlg.c + +path_dlg.obj: gui/path_dlg.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT path_dlg.obj -MD -MP -MF "$(DEPDIR)/path_dlg.Tpo" \ +@am__fastdepCC_TRUE@ -c -o path_dlg.obj `if test -f 'gui/path_dlg.c'; then $(CYGPATH_W) 'gui/path_dlg.c'; else $(CYGPATH_W) '$(srcdir)/gui/path_dlg.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/path_dlg.Tpo" "$(DEPDIR)/path_dlg.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/path_dlg.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gui/path_dlg.c' object='path_dlg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/path_dlg.Po' tmpdepfile='$(DEPDIR)/path_dlg.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o path_dlg.obj `if test -f 'gui/path_dlg.c'; then $(CYGPATH_W) 'gui/path_dlg.c'; else $(CYGPATH_W) '$(srcdir)/gui/path_dlg.c'; fi` + audio_null.o: drivers/audio_null.c @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT audio_null.o -MD -MP -MF "$(DEPDIR)/audio_null.Tpo" \ @am__fastdepCC_TRUE@ -c -o audio_null.o `test -f 'drivers/audio_null.c' || echo '$(srcdir)/'`drivers/audio_null.c; \ --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config.c Wed Oct 17 11:26:45 2007 +0000 @@ -0,0 +1,294 @@ +/** + * $Id: config.c,v 1.1 2007-10-17 11:26:45 nkeynes Exp $ + * + * User configuration support + * + * Copyright (c) 2005 Nathan Keynes. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "dream.h" +#include "config.h" +#include "maple/maple.h" + +gboolean lxdream_load_config_file( const gchar *filename ); +gboolean lxdream_save_config_file( const gchar *filename ); +gboolean lxdream_load_config_stream( FILE *f ); +gboolean lxdream_save_config_stream( FILE *f ); + +static struct lxdream_config_entry global_config[] = + {{ "bios", CONFIG_TYPE_FILE, "dcboot.rom" }, + { "flash", CONFIG_TYPE_FILE, "dcflash.rom" }, + { "default path", CONFIG_TYPE_PATH, "." }, + { "save path", CONFIG_TYPE_PATH, "save" }, + { "bootstrap", CONFIG_TYPE_FILE, "IP.BIN" }, + { NULL, CONFIG_TYPE_NONE }}; + +static struct lxdream_config_entry serial_config[] = + {{ "device", CONFIG_TYPE_FILE, "/dev/ttyS1" }, + { NULL, CONFIG_TYPE_NONE }}; + +struct lxdream_config_group lxdream_config_root[] = + {{ "global", global_config }, + { "controllers", NULL }, + { "serial", serial_config }, + { NULL, CONFIG_TYPE_NONE }}; + +static gchar *lxdream_config_load_filename = NULL; +static gchar *lxdream_config_save_filename = NULL; + +gboolean lxdream_find_config() +{ + char *home = getenv("HOME"); + if( lxdream_config_save_filename == NULL ) { + lxdream_config_save_filename = g_strdup_printf("%s/.%s", home, DEFAULT_CONFIG_FILENAME); + } + if( lxdream_config_load_filename == NULL ) { + if( access(lxdream_config_save_filename, R_OK) == 0 ) { + lxdream_config_load_filename = g_strdup(lxdream_config_save_filename); + } else if( access( PACKAGE_CONF_DIR "/" DEFAULT_CONFIG_FILENAME, R_OK ) == 0 ) { + lxdream_config_load_filename = g_strdup(PACKAGE_CONF_DIR "/" DEFAULT_CONFIG_FILENAME); + } else if( access( "./" DEFAULT_CONFIG_FILENAME, R_OK ) == 0 ) { + lxdream_config_load_filename = g_strdup("./" DEFAULT_CONFIG_FILENAME); + } else { + lxdream_config_load_filename = g_strdup(lxdream_config_save_filename); + } + } +} + +void lxdream_set_config_filename( const gchar *filename ) +{ + if( lxdream_config_load_filename != NULL ) { + g_free(lxdream_config_load_filename); + } + lxdream_config_load_filename = g_strdup(filename); + if( lxdream_config_save_filename != NULL ) { + g_free(lxdream_config_save_filename); + } + lxdream_config_save_filename = g_strdup(filename); +} + +void lxdream_set_default_config( ) +{ + struct lxdream_config_group *group = lxdream_config_root; + while( group->key != NULL ) { + struct lxdream_config_entry *param = group->params; + if( param != NULL ) { + while( param->key != NULL ) { + if( param->value != param->default_value ) { + if( param->value != NULL ) + free( param->value ); + param->value = (gchar *)param->default_value; + } + param++; + } + } + group++; + } + maple_detach_all(); +} + +const gchar *lxdream_get_config_value( int key ) +{ + return global_config[key].value; +} + +void lxdream_set_config_value( int key, const gchar *value ) +{ + struct lxdream_config_entry *param = &global_config[key]; + if( param->value != param->default_value && param->value != NULL ) { + free( param->value ); + } + param->value = g_strdup(value); +} + +gboolean lxdream_load_config( ) +{ + if( lxdream_config_load_filename == NULL ) { + lxdream_find_config(); + } + return lxdream_load_config_file(lxdream_config_load_filename); +} + +gboolean lxdream_save_config( ) +{ + if( lxdream_config_save_filename == NULL ) { + lxdream_find_config(); + } + return lxdream_save_config_file(lxdream_config_save_filename); +} + +gboolean lxdream_load_config_file( const gchar *filename ) +{ + FILE *f; + gboolean result; + + if( access(filename, F_OK) != 0 ) { + INFO( "Configuration file '%s' does not exist, creating from defaults" ); + lxdream_set_default_config(); + lxdream_save_config(); + } + + f = fopen(filename, "ro"); + if( f == NULL ) { + ERROR( "Unable to open configuration file '%s': %s", filename, strerror(errno) ); + lxdream_set_default_config(); + return FALSE; + } + + result = lxdream_load_config_stream( f ); + fclose(f); + return result; +} + +gboolean lxdream_load_config_stream( FILE *f ) +{ + + char buf[512]; + int maple_device = -1, maple_subdevice = -1; + struct lxdream_config_group devgroup; + struct lxdream_config_group *group = NULL; + maple_device_t device = NULL; + lxdream_set_default_config(); + + while( fgets( buf, sizeof(buf), f ) != NULL ) { + g_strstrip(buf); + if( buf[0] == '#' ) + continue; + if( *buf == '[' ) { + char *p = strchr(buf, ']'); + if( p != NULL ) { + struct lxdream_config_group *tmp_group; + maple_device = maple_subdevice = -1; + *p = '\0'; + g_strstrip(buf+1); + tmp_group = &lxdream_config_root[0]; + while( tmp_group->key != NULL ) { + if( strcasecmp(tmp_group->key, buf+1) == 0 ) { + group = tmp_group; + break; + } + tmp_group++; + } + } + } else if( group != NULL ) { + char *value = strchr( buf, '=' ); + if( value != NULL ) { + struct lxdream_config_entry *param = group->params; + *value = '\0'; + value++; + g_strstrip(buf); + g_strstrip(value); + if( strcmp(group->key,"controllers") == 0 ) { + if( g_strncasecmp( buf, "device ", 7 ) == 0 ) { + maple_device = strtoul( buf+7, NULL, 0 ); + if( maple_device < 0 || maple_device > 3 ) { + ERROR( "Device number must be between 0..3 (not '%s')", buf+7); + continue; + } + maple_subdevice = 0; + device = maple_new_device( value ); + if( device == NULL ) { + ERROR( "Unrecognized device '%s'", value ); + } else { + devgroup.key = "controllers"; + devgroup.params = maple_get_device_config(device); + maple_attach_device( device, maple_device, maple_subdevice ); + group = &devgroup; + } + continue; + } else if( g_strncasecmp( buf, "subdevice ", 10 ) == 0 ) { + maple_subdevice = strtoul( buf+10, NULL, 0 ); + if( maple_device == -1 ) { + ERROR( "Subdevice not allowed without primary device" ); + } else if( maple_subdevice < 1 || maple_subdevice > 5 ) { + ERROR( "Subdevice must be between 1..5 (not '%s')", buf+10 ); + } else if( (device = maple_new_device(value)) == NULL ) { + ERROR( "Unrecognized subdevice '%s'", value ); + } else { + devgroup.key = "controllers"; + devgroup.params = maple_get_device_config(device); + maple_attach_device( device, maple_device, maple_subdevice ); + group = &devgroup; + } + continue; + } + } + while( param->key != NULL ) { + if( strcasecmp( param->key, buf ) == 0 ) { + param->value = g_strdup(value); + break; + } + param++; + } + } + } + } + return TRUE; +} + +gboolean lxdream_save_config_file( const gchar *filename ) +{ + FILE *f = fopen(filename, "wo"); + gboolean result; + if( f == NULL ) { + ERROR( "Unable to open '%s': %s", filename, strerror(errno) ); + return FALSE; + } + result = lxdream_save_config_stream(f); + fclose(f); + return TRUE; +} + +gboolean lxdream_save_config_stream( FILE *f ) +{ + struct lxdream_config_group *group = &lxdream_config_root[0]; + + while( group->key != NULL ) { + struct lxdream_config_entry *entry = group->params; + fprintf( f, "[%s]\n", group->key ); + + if( entry != NULL ) { + while( entry->key != NULL ) { + fprintf( f, "%s = %s\n", entry->key, entry->value ); + entry++; + } + } else if( strcmp(group->key, "controllers") == 0 ) { + int i,j; + for( i=0; i<4; i++ ) { + for( j=0; j<6; j++ ) { + maple_device_t dev = maple_get_device( i, j ); + if( dev != NULL ) { + if( j == 0 ) + fprintf( f, "Device %d = %s\n", i, dev->device_class->name ); + else + fprintf( f, "Subdevice %d = %s\n", j, dev->device_class->name ); + entry = dev->get_config(dev); + while( entry->key != NULL ) { + fprintf( f, "%*c%s = %s\n", j==0?4:8, ' ',entry->key, entry->value ); + entry++; + } + } + } + } + } + fprintf( f, "\n" ); + group++; + } + return TRUE; +} --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config.h Wed Oct 17 11:26:45 2007 +0000 @@ -0,0 +1,83 @@ +/** + * $Id: config.h,v 1.1 2007-10-17 11:26:45 nkeynes Exp $ + * + * User configuration support + * + * Copyright (c) 2005 Nathan Keynes. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef lxdream_config_H +#define lxdream_config_H 1 + +#include + +#define CONFIG_TYPE_NONE 0 +#define CONFIG_TYPE_FILE 1 +#define CONFIG_TYPE_PATH 2 +#define CONFIG_TYPE_KEY 3 + +#define DEFAULT_CONFIG_FILENAME "lxdreamrc" + +typedef struct lxdream_config_entry { + const gchar *key; + const int type; + const gchar *default_value; + gchar *value; +} *lxdream_config_entry_t; + +typedef struct lxdream_config_group { + const gchar *key; + struct lxdream_config_entry *params; +} *lxdream_config_group_t; + +#define CONFIG_BIOS_PATH 0 +#define CONFIG_FLASH_PATH 1 +#define CONFIG_DEFAULT_PATH 2 +#define CONFIG_SAVE_PATH 3 +#define CONFIG_BOOTSTRAP 4 + +extern struct lxdream_config_group lxdream_config_root[]; + +/* Global config values */ +const gchar *lxdream_get_config_value( int key ); + +void lxdream_set_config_value( int key, const gchar *value ); + +/** + * Search the standard locations for the configuration file: + * $HOME/.lxdreamrc + * $CWD/lxdreamrc + * $SYSCONF_DIR/lxdreamrc + * @return TRUE if the file was found, otherwise FALSE. + */ +gboolean lxdream_find_config( ); + +/** + * Set the configuration file filename to the supplied string. + * The string is copied internally (ie can be released by the + * caller). + */ +void lxdream_set_config_filename( const gchar *filename ); + +/** + * Load the configuration from the previously determined filename. + */ +gboolean lxdream_load_config( ); + +/** + * Update the configuration + */ +gboolean lxdream_save_config( ); + + +#endif /* !lxdream_config_H */ --- a/src/dreamcast.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/dreamcast.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: dreamcast.c,v 1.23 2007-10-06 08:59:42 nkeynes Exp $ + * $Id: dreamcast.c,v 1.24 2007-10-17 11:26:45 nkeynes Exp $ * Central switchboard for the system. This pulls all the individual modules * together into some kind of coherent structure. This is also where you'd * add Naomi support, if I ever get a board to play with... @@ -18,8 +18,8 @@ */ #include -#include #include "dream.h" +#include "config.h" #include "mem.h" #include "aica/aica.h" #include "asic.h" @@ -67,13 +67,13 @@ mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO ); mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH ); mem_create_ram_region( 0x05000000, 8 MB, MEM_REGION_VIDEO ); - if( mem_load_rom( dreamcast_get_config_value(CONFIG_BIOS_PATH), + if( mem_load_rom( lxdream_get_config_value(CONFIG_BIOS_PATH), 0x00000000, 0x00200000, 0x89f2b1a1 ) == NULL ) { /* Bios wasn't found. Dump an empty ram region in there for something to do */ mem_create_ram_region( 0x00000000, 0x00200000, MEM_REGION_BIOS ); } mem_create_ram_region( 0x00200000, 0x00020000, MEM_REGION_FLASH ); - mem_load_block( dreamcast_get_config_value(CONFIG_FLASH_PATH), + mem_load_block( lxdream_get_config_value(CONFIG_FLASH_PATH), 0x00200000, 0x00020000 ); /* Load in the rest of the core modules */ @@ -87,7 +87,7 @@ void dreamcast_save_flash() { - const char *file = dreamcast_get_config_value(CONFIG_FLASH_PATH); + const char *file = lxdream_get_config_value(CONFIG_FLASH_PATH); mem_save_block( file, 0x00200000, 0x00020000 ); } @@ -207,204 +207,6 @@ return dreamcast_state == STATE_RUNNING; } -/***************************** User Configuration **************************/ - - -static struct dreamcast_config_entry global_config[] = - {{ "bios", CONFIG_TYPE_FILE, "dcboot.rom" }, - { "flash", CONFIG_TYPE_FILE, "dcflash.rom" }, - { "default path", CONFIG_TYPE_PATH, "." }, - { "save path", CONFIG_TYPE_PATH, "save" }, - { "bootstrap", CONFIG_TYPE_FILE, "IP.BIN" }, - { NULL, CONFIG_TYPE_NONE }}; - -static struct dreamcast_config_entry serial_config[] = - {{ "device", CONFIG_TYPE_FILE, "/dev/ttyS1" }, - { NULL, CONFIG_TYPE_NONE }}; - -struct dreamcast_config_group dreamcast_config_root[] = - {{ "global", global_config }, - { "controllers", NULL }, - { "serial", serial_config }, - { NULL, CONFIG_TYPE_NONE }}; - -void dreamcast_set_default_config( ) -{ - struct dreamcast_config_group *group = dreamcast_config_root; - while( group->key != NULL ) { - struct dreamcast_config_entry *param = group->params; - if( param != NULL ) { - while( param->key != NULL ) { - if( param->value != param->default_value ) { - if( param->value != NULL ) - free( param->value ); - param->value = (gchar *)param->default_value; - } - param++; - } - } - group++; - } - maple_detach_all(); -} - -const gchar *dreamcast_get_config_value( int key ) -{ - return global_config[key].value; -} - -gboolean dreamcast_load_config( const gchar *filename ) -{ - FILE *f = fopen(filename, "ro"); - gboolean result; - - if( f == NULL ) { - ERROR( "Unable to open '%s': %s", filename, strerror(errno) ); - return FALSE; - } - - result = dreamcast_load_config_stream( f ); - fclose(f); - return result; -} - -gboolean dreamcast_load_config_stream( FILE *f ) -{ - - char buf[512]; - int maple_device = -1, maple_subdevice = -1; - struct dreamcast_config_group devgroup; - struct dreamcast_config_group *group = NULL; - maple_device_t device = NULL; - dreamcast_set_default_config(); - - while( fgets( buf, sizeof(buf), f ) != NULL ) { - g_strstrip(buf); - if( buf[0] == '#' ) - continue; - if( *buf == '[' ) { - char *p = strchr(buf, ']'); - if( p != NULL ) { - struct dreamcast_config_group *tmp_group; - maple_device = maple_subdevice = -1; - *p = '\0'; - g_strstrip(buf+1); - tmp_group = &dreamcast_config_root[0]; - while( tmp_group->key != NULL ) { - if( strcasecmp(tmp_group->key, buf+1) == 0 ) { - group = tmp_group; - break; - } - tmp_group++; - } - } - } else if( group != NULL ) { - char *value = strchr( buf, '=' ); - if( value != NULL ) { - struct dreamcast_config_entry *param = group->params; - *value = '\0'; - value++; - g_strstrip(buf); - g_strstrip(value); - if( strcmp(group->key,"controllers") == 0 ) { - if( g_strncasecmp( buf, "device ", 7 ) == 0 ) { - maple_device = strtoul( buf+7, NULL, 0 ); - if( maple_device < 0 || maple_device > 3 ) { - ERROR( "Device number must be between 0..3 (not '%s')", buf+7); - continue; - } - maple_subdevice = 0; - device = maple_new_device( value ); - if( device == NULL ) { - ERROR( "Unrecognized device '%s'", value ); - } else { - devgroup.key = "controllers"; - devgroup.params = maple_get_device_config(device); - maple_attach_device( device, maple_device, maple_subdevice ); - group = &devgroup; - } - continue; - } else if( g_strncasecmp( buf, "subdevice ", 10 ) == 0 ) { - maple_subdevice = strtoul( buf+10, NULL, 0 ); - if( maple_device == -1 ) { - ERROR( "Subdevice not allowed without primary device" ); - } else if( maple_subdevice < 1 || maple_subdevice > 5 ) { - ERROR( "Subdevice must be between 1..5 (not '%s')", buf+10 ); - } else if( (device = maple_new_device(value)) == NULL ) { - ERROR( "Unrecognized subdevice '%s'", value ); - } else { - devgroup.key = "controllers"; - devgroup.params = maple_get_device_config(device); - maple_attach_device( device, maple_device, maple_subdevice ); - group = &devgroup; - } - continue; - } - } - while( param->key != NULL ) { - if( strcasecmp( param->key, buf ) == 0 ) { - param->value = g_strdup(value); - break; - } - param++; - } - } - } - } - return TRUE; -} - -gboolean dreamcast_save_config( const gchar *filename ) -{ - FILE *f = fopen(filename, "wo"); - gboolean result; - if( f == NULL ) { - ERROR( "Unable to open '%s': %s", filename, strerror(errno) ); - return FALSE; - } - result = dreamcast_save_config_stream(f); - fclose(f); - return TRUE; -} - -gboolean dreamcast_save_config_stream( FILE *f ) -{ - struct dreamcast_config_group *group = &dreamcast_config_root[0]; - - while( group->key != NULL ) { - struct dreamcast_config_entry *entry = group->params; - fprintf( f, "[%s]\n", group->key ); - - if( entry != NULL ) { - while( entry->key != NULL ) { - fprintf( f, "%s = %s\n", entry->key, entry->value ); - entry++; - } - } else if( strcmp(group->key, "controllers") == 0 ) { - int i,j; - for( i=0; i<4; i++ ) { - for( j=0; j<6; j++ ) { - maple_device_t dev = maple_get_device( i, j ); - if( dev != NULL ) { - if( j == 0 ) - fprintf( f, "Device %d = %s\n", i, dev->device_class->name ); - else - fprintf( f, "Subdevice %d = %s\n", j, dev->device_class->name ); - entry = dev->get_config(dev); - while( entry->key != NULL ) { - fprintf( f, "%*c%s = %s\n", j==0?4:8, ' ',entry->key, entry->value ); - entry++; - } - } - } - } - } - fprintf( f, "\n" ); - group++; - } - return TRUE; -} - /********************************* Save States *****************************/ struct save_state_header { --- a/src/dreamcast.h Tue Oct 16 12:38:01 2007 +0000 +++ b/src/dreamcast.h Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: dreamcast.h,v 1.17 2007-10-09 08:12:29 nkeynes Exp $ + * $Id: dreamcast.h,v 1.18 2007-10-17 11:26:45 nkeynes Exp $ * * Public interface for dreamcast.c - * Central switchboard for the system. This pulls all the individual modules @@ -38,25 +38,6 @@ #define XLAT_TEMP_CACHE_SIZE 2 MB #define XLAT_OLD_CACHE_SIZE 8 MB -#define CONFIG_TYPE_NONE 0 -#define CONFIG_TYPE_FILE 1 -#define CONFIG_TYPE_PATH 2 -#define CONFIG_TYPE_KEY 3 - -#define DEFAULT_CONFIG_FILENAME "lxdream.rc" - -typedef struct dreamcast_config_entry { - const gchar *key; - const int type; - const gchar *default_value; - gchar *value; -} *dreamcast_config_entry_t; - -typedef struct dreamcast_config_group { - const gchar *key; - struct dreamcast_config_entry *params; -} *dreamcast_config_group_t; - void dreamcast_configure(void); void dreamcast_configure_aica_only(void); void dreamcast_init(void); @@ -67,11 +48,6 @@ void dreamcast_shutdown(void); gboolean dreamcast_is_running(void); -gboolean dreamcast_load_config( const gchar *filename ); -gboolean dreamcast_save_config( const gchar *filename ); -gboolean dreamcast_load_config_stream( FILE *f ); -gboolean dreamcast_save_config_stream( FILE *f ); - #define DREAMCAST_SAVE_MAGIC "%!-lxDream!Save\0" #define DREAMCAST_SAVE_VERSION 0x00010000 @@ -81,16 +57,6 @@ #define SCENE_SAVE_MAGIC "%!-lxDream!Scene" #define SCENE_SAVE_VERSION 0x00010000 -extern struct dreamcast_config_group dreamcast_config_root[]; - -/* Global config values */ -const gchar *dreamcast_get_config_value( int key ); -#define CONFIG_BIOS_PATH 0 -#define CONFIG_FLASH_PATH 1 -#define CONFIG_DEFAULT_PATH 2 -#define CONFIG_SAVE_PATH 3 -#define CONFIG_BOOTSTRAP 4 - #ifdef __cplusplus } #endif --- a/src/gui/ctrl_dlg.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/gui/ctrl_dlg.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: ctrl_dlg.c,v 1.1 2007-10-16 12:36:29 nkeynes Exp $ + * $Id: ctrl_dlg.c,v 1.2 2007-10-17 11:26:45 nkeynes Exp $ * * Define the main (emu) GTK window, along with its menubars, * toolbars, etc. @@ -79,7 +79,7 @@ } } } - dreamcast_save_config("testrc"); + lxdream_save_config(); } void controller_cancel_changes( ) @@ -93,7 +93,7 @@ } } -GtkWidget *controller_pane_new() +GtkWidget *controller_panel_new() { GtkWidget *table = gtk_table_new(4, 3, TRUE); GtkTreeIter iter; @@ -125,7 +125,7 @@ maple_data[i].new_device = device; maple_data[i].combo = combo; maple_data[i].button = button; - g_signal_connect( button, "activate", + g_signal_connect( button, "clicked", G_CALLBACK( controller_properties_activated ), &maple_data[i] ); g_signal_connect( combo, "changed", G_CALLBACK( controller_device_changed ), &maple_data[i] ); @@ -136,18 +136,7 @@ void controller_dialog_run( GtkWindow *parent ) { - GtkWidget *dialog = - gtk_dialog_new_with_buttons("Controller Settings", parent, - GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, - GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, - NULL); - GtkWidget *panel = controller_pane_new(); - gint result; - gtk_widget_show_all(panel); - gtk_container_add( GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), panel ); - result = gtk_dialog_run( GTK_DIALOG(dialog) ); - gtk_widget_destroy( dialog ); + gint result = gtk_gui_run_property_dialog( "Controller Settings", controller_panel_new() ); if( result == GTK_RESPONSE_ACCEPT ) { controller_commit_changes(); } else { --- a/src/gui/debugcb.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/gui/debugcb.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: debugcb.c,v 1.1 2007-10-10 11:02:04 nkeynes Exp $ + * $Id: debugcb.c,v 1.2 2007-10-17 11:26:45 nkeynes Exp $ * * All GTK callbacks go here (stubs are autogenerated by Glade) * @@ -16,12 +16,9 @@ * GNU General Public License for more details. */ -#ifdef HAVE_CONFIG_H -# include -#endif - #include +#include "config.h" #include "gui/debugcb.h" #include "gui/debugif.h" #include "gui/gtkui.h" @@ -49,7 +46,7 @@ on_open1_activate (GtkMenuItem *menuitem, gpointer user_data) { - const gchar *dir = dreamcast_get_config_value(CONFIG_DEFAULT_PATH); + const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH); open_file_dialog( "Open...", file_load_magic, NULL, NULL, dir ); } @@ -73,7 +70,7 @@ on_save_next_scene_activate( GtkMenuItem *menuitem, gpointer user_data) { - const gchar *dir = dreamcast_get_config_value(CONFIG_SAVE_PATH); + const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH); save_file_dialog( "Save next scene...", pvr2_save_next_scene, "*.dsc", "lxdream scene file (*.dsc)", dir ); } @@ -106,7 +103,7 @@ on_load_btn_clicked (GtkButton *button, gpointer user_data) { - const gchar *dir = dreamcast_get_config_value(CONFIG_DEFAULT_PATH); + const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH); open_file_dialog( "Open...", gdrom_mount_image, NULL, NULL, dir ); } @@ -344,7 +341,7 @@ on_loadstate_button_clicked (GtkToolButton *toolbutton, gpointer user_data) { - const gchar *dir = dreamcast_get_config_value(CONFIG_SAVE_PATH); + const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH); open_file_dialog( "Load state...", dreamcast_load_state, "*.dst", "lxDream Save State (*.dst)", dir ); } @@ -353,7 +350,7 @@ on_savestate_button_clicked (GtkToolButton *toolbutton, gpointer user_data) { - const gchar *dir = dreamcast_get_config_value(CONFIG_SAVE_PATH); + const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH); save_file_dialog( "Save state...", dreamcast_save_state, "*.dst", "lxDream Save State (*.dst)", dir ); } --- a/src/gui/gtkcb.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/gui/gtkcb.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: gtkcb.c,v 1.3 2007-10-16 12:36:29 nkeynes Exp $ + * $Id: gtkcb.c,v 1.4 2007-10-17 11:26:45 nkeynes Exp $ * * Action callbacks from the main window * @@ -17,6 +17,7 @@ */ #include "dream.h" +#include "config.h" #include "dreamcast.h" #include "gdrom/gdrom.h" #include "gui/gtkui.h" @@ -113,7 +114,7 @@ void mount_action_callback( GtkAction *action, gpointer user_data) { - const gchar *dir = dreamcast_get_config_value(CONFIG_DEFAULT_PATH); + const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH); open_file_dialog( "Open...", gdrom_mount_image, NULL, NULL, dir ); } void reset_action_callback( GtkAction *action, gpointer user_data) @@ -133,12 +134,12 @@ void load_state_action_callback( GtkAction *action, gpointer user_data) { - const gchar *dir = dreamcast_get_config_value(CONFIG_SAVE_PATH); + const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH); open_file_dialog( "Load state...", dreamcast_load_state, "*.dst", "lxDream Save State (*.dst)", dir ); } void save_state_action_callback( GtkAction *action, gpointer user_data) { - const gchar *dir = dreamcast_get_config_value(CONFIG_SAVE_PATH); + const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH); save_file_dialog( "Save state...", dreamcast_save_state, "*.dst", "lxDream Save State (*.dst)", dir ); } void about_action_callback( GtkAction *action, gpointer user_data) @@ -167,6 +168,7 @@ void path_settings_callback( GtkAction *action, gpointer user_data) { + path_dialog_run(); } void audio_settings_callback( GtkAction *action, gpointer user_data) @@ -175,7 +177,7 @@ void controller_settings_callback( GtkAction *action, gpointer user_data) { - controller_dialog_run( NULL ); + controller_dialog_run( ); } void network_settings_callback( GtkAction *action, gpointer user_data) --- a/src/gui/gtkui.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/gui/gtkui.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: gtkui.c,v 1.3 2007-10-16 12:36:29 nkeynes Exp $ + * $Id: gtkui.c,v 1.4 2007-10-17 11:26:45 nkeynes Exp $ * * Core GTK-based user interface * @@ -210,3 +210,19 @@ gdk_colormap_alloc_color(map, &gui_colour_white, TRUE, TRUE); gui_fixed_font = pango_font_description_from_string("Courier 10"); } + +gint gtk_gui_run_property_dialog( const gchar *title, GtkWidget *panel ) +{ + GtkWidget *dialog = + gtk_dialog_new_with_buttons(title, main_window_get_frame(main_win), + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + NULL); + gint result; + gtk_widget_show_all(panel); + gtk_container_add( GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), panel ); + result = gtk_dialog_run( GTK_DIALOG(dialog) ); + gtk_widget_destroy( dialog ); + return result; +} --- a/src/gui/gtkui.h Tue Oct 16 12:38:01 2007 +0000 +++ b/src/gui/gtkui.h Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: gtkui.h,v 1.3 2007-10-16 12:36:29 nkeynes Exp $ + * $Id: gtkui.h,v 1.4 2007-10-17 11:26:45 nkeynes Exp $ * * Core GTK-based user interface * @@ -34,7 +34,6 @@ * opaque pointer to the window. */ main_window_t main_window_new( const gchar *title ); - GtkWindow *main_window_get_frame( main_window_t win ); GtkWidget *main_window_get_renderarea( main_window_t win ); void main_window_set_running( main_window_t win, gboolean running ); @@ -42,14 +41,19 @@ void main_window_set_speed( main_window_t win, double speed ); debug_window_t debug_window_new(); - void debug_window_show( debug_window_t win, gboolean show ); void debug_window_set_running( debug_window_t win, gboolean running ); void debug_window_update(debug_window_t win); mmio_window_t mmio_window_new(); +void mmio_window_show( mmio_window_t win, gboolean show ); -void mmio_window_show( mmio_window_t win, gboolean show ); +void controller_dialog_run(); +void path_dialog_run(); + +/********************* Helper functions **********************/ + +gint gtk_gui_run_property_dialog( const gchar *title, GtkWidget *panel ); /******************** Video driver hooks *********************/ --- a/src/gui/main_win.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/gui/main_win.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: main_win.c,v 1.4 2007-10-16 12:36:29 nkeynes Exp $ + * $Id: main_win.c,v 1.5 2007-10-17 11:26:45 nkeynes Exp $ * * Define the main (emu) GTK window, along with its menubars, * toolbars, etc. @@ -54,7 +54,7 @@ { "About", GTK_STOCK_ABOUT, "_About...", NULL, "About lxdream", G_CALLBACK(about_action_callback) } }; static const GtkToggleActionEntry ui_toggle_actions[] = { - { "FullScreen", NULL, "_Full Screen", "F9", "Toggle full screen video", G_CALLBACK(fullscreen_toggle_callback), 0 }, + { "FullScreen", NULL, "_Full Screen", "Return", "Toggle full screen video", G_CALLBACK(fullscreen_toggle_callback), 0 }, }; @@ -74,6 +74,7 @@ " " " " " " + " " " " " " " " --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gui/path_dlg.c Wed Oct 17 11:26:45 2007 +0000 @@ -0,0 +1,141 @@ +/** + * $Id: path_dlg.c,v 1.1 2007-10-17 11:26:45 nkeynes Exp $ + * + * Define the main (emu) GTK window, along with its menubars, + * toolbars, etc. + * + * Copyright (c) 2005 Nathan Keynes. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "dream.h" +#include "config.h" +#include "gui/gtkui.h" + +static const gchar *path_label[] = { "Bios rom", "Flash rom", "Default disc path", + "Save state path", "Bootstrap IP.BIN" }; +static const int path_id[] = { CONFIG_BIOS_PATH, CONFIG_FLASH_PATH, CONFIG_DEFAULT_PATH, + CONFIG_SAVE_PATH, CONFIG_BOOTSTRAP }; +static GtkFileChooserAction path_action[] = { + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + GTK_FILE_CHOOSER_ACTION_OPEN }; + +static GtkWidget *path_entry[5]; + +static gboolean path_file_button_clicked( GtkWidget *button, gpointer user_data ) +{ + GtkWidget *entry = GTK_WIDGET(user_data); + GtkWidget *file = gtk_file_chooser_dialog_new( "Select file", NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL ); + const gchar *filename = gtk_entry_get_text(GTK_ENTRY(entry)); + gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(file), filename ); + gtk_window_set_modal( GTK_WINDOW(file), TRUE ); + gtk_widget_show_all( file ); + gint result = gtk_dialog_run(GTK_DIALOG(file)); + if( result == GTK_RESPONSE_ACCEPT ) { + filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ); + gtk_entry_set_text(GTK_ENTRY(entry), filename); + } + gtk_widget_destroy(file); +} + +static gboolean path_dir_button_clicked( GtkWidget *button, gpointer user_data ) +{ + GtkWidget *entry = GTK_WIDGET(user_data); + GtkWidget *file = gtk_file_chooser_dialog_new( "Select file", NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL ); + const gchar *filename = gtk_entry_get_text(GTK_ENTRY(entry)); + gtk_file_chooser_set_action( GTK_FILE_CHOOSER(file), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ); + gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(file), filename ); + gtk_window_set_modal( GTK_WINDOW(file), TRUE ); + gtk_widget_show_all( file ); + gint result = gtk_dialog_run(GTK_DIALOG(file)); + if( result == GTK_RESPONSE_ACCEPT ) { + filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ); + gtk_entry_set_text(GTK_ENTRY(entry), filename); + } + gtk_widget_destroy(file); +} + +static gboolean path_text_changed( GtkWidget *entry, gpointer user_data ) +{ + const gchar *text = gtk_entry_get_text( GTK_ENTRY(entry) ); +} + +GtkWidget *path_panel_new(void) +{ + GtkWidget *table = gtk_table_new( 5, 3, FALSE ); + GtkWidget *desc = gtk_label_new(NULL); + int i; + for( i=0; i<5; i++ ) { + GtkWidget *text = path_entry[i] = gtk_entry_new(); + GtkWidget *button = gtk_button_new(); + gtk_table_attach( GTK_TABLE(table), gtk_label_new(path_label[i]), 0, 1, i, i+1, + GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_entry_set_text( GTK_ENTRY(text), lxdream_get_config_value(path_id[i]) ); + gtk_table_attach_defaults( GTK_TABLE(table), text, 1, 2, i, i+1 ); + gtk_table_attach( GTK_TABLE(table), button, 2, 3, i, i+1, GTK_SHRINK, GTK_SHRINK, 0, 0 ); + if( path_action[i] == GTK_FILE_CHOOSER_ACTION_OPEN ) { + GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image( GTK_BUTTON(button), image ); + g_signal_connect( button, "clicked", G_CALLBACK(path_file_button_clicked), text ); + } else { + GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image( GTK_BUTTON(button), image ); + g_signal_connect( button, "clicked", G_CALLBACK(path_dir_button_clicked), text ); + } + } + return table; + +} + +void path_panel_commit_changes() +{ + int i; + for(i=0; i<5; i++ ) { + const char *filename = gtk_entry_get_text( GTK_ENTRY(path_entry[i]) ); + lxdream_set_config_value( path_id[i], filename ); + } + + lxdream_save_config(); +} + +void path_dialog_run( void ) +{ + GtkWidget *dialog = + gtk_dialog_new_with_buttons("Path Settings", NULL, + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + NULL); + gint result; + GtkWidget *panel = path_panel_new(); + gtk_widget_show_all(panel); + gtk_container_add( GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), panel ); + result = gtk_dialog_run( GTK_DIALOG(dialog) ); + if( result == GTK_RESPONSE_ACCEPT ) { + path_panel_commit_changes(); + } + gtk_widget_destroy( dialog ); +} --- a/src/loader.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/loader.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: loader.c,v 1.18 2007-10-16 12:28:42 nkeynes Exp $ + * $Id: loader.c,v 1.19 2007-10-17 11:26:45 nkeynes Exp $ * * File loading routines, mostly for loading demos without going through the * whole procedure of making a CD image for them. @@ -27,6 +27,7 @@ #include "sh4core.h" #include "bootstrap.h" #include "dreamcast.h" +#include "config.h" #include "loader.h" #include "syscall.h" @@ -109,7 +110,7 @@ void file_load_postload( int pc ) { - const gchar *bootstrap_file = dreamcast_get_config_value(CONFIG_BOOTSTRAP); + const gchar *bootstrap_file = lxdream_get_config_value(CONFIG_BOOTSTRAP); if( bootstrap_file != NULL ) { /* Load in a bootstrap before the binary, to initialize everything * correctly --- a/src/main.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/main.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: main.c,v 1.29 2007-10-16 12:28:42 nkeynes Exp $ + * $Id: main.c,v 1.30 2007-10-17 11:26:44 nkeynes Exp $ * * Main program, initializes dreamcast and gui, then passes control off to * the gtk main loop (currently). @@ -19,18 +19,16 @@ * GNU General Public License for more details. */ -#ifdef HAVE_CONFIG_H -# include -#endif #include #include -#include "gui.h" #include "dream.h" +#include "config.h" #include "syscall.h" #include "mem.h" #include "dreamcast.h" #include "display.h" #include "loader.h" +#include "gui.h" #include "aica/audio.h" #include "gdrom/gdrom.h" #include "maple/maple.h" @@ -45,7 +43,6 @@ char *disc_file = NULL; char *display_driver_name = "gtk"; char *audio_driver_name = "esd"; -char *config_file = DEFAULT_CONFIG_FILENAME; gboolean start_immediately = FALSE; gboolean headless = FALSE; gboolean without_bios = FALSE; @@ -79,7 +76,7 @@ aica_program = optarg; break; case 'c': /* Config file */ - config_file = optarg; + lxdream_set_config_filename(optarg); break; case 'd': /* Mount disc */ disc_file = optarg; @@ -124,7 +121,7 @@ } } - dreamcast_load_config( config_file ); + lxdream_load_config( ); if( aica_program == NULL ) { dreamcast_init(); --- a/src/maple/controller.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/maple/controller.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: controller.c,v 1.6 2007-10-08 11:49:35 nkeynes Exp $ + * $Id: controller.c,v 1.7 2007-10-17 11:26:45 nkeynes Exp $ * * Implements the standard dreamcast controller * @@ -29,14 +29,14 @@ void controller_detach( maple_device_t dev ); void controller_destroy( maple_device_t dev ); maple_device_t controller_new(); -dreamcast_config_entry_t controller_get_config( maple_device_t dev ); +lxdream_config_entry_t controller_get_config( maple_device_t dev ); int controller_get_cond( maple_device_t dev, int function, unsigned char *outbuf, int *outlen ); typedef struct controller_device { struct maple_device dev; uint32_t condition[2]; - struct dreamcast_config_entry config[CONTROLLER_CONFIG_ENTRIES]; + struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES]; } *controller_device_t; struct maple_device_class controller_class = { "Sega Controller", controller_new }; @@ -119,7 +119,7 @@ } } -dreamcast_config_entry_t controller_get_config( maple_device_t mdev ) +lxdream_config_entry_t controller_get_config( maple_device_t mdev ) { controller_device_t dev = (controller_device_t)mdev; return dev->config; --- a/src/maple/maple.c Tue Oct 16 12:38:01 2007 +0000 +++ b/src/maple/maple.c Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: maple.c,v 1.10 2007-10-16 12:36:29 nkeynes Exp $ + * $Id: maple.c,v 1.11 2007-10-17 11:26:45 nkeynes Exp $ * * Implements the core Maple bus, including DMA transfers to and from the bus. * @@ -59,7 +59,7 @@ return maple_device_classes; } -dreamcast_config_entry_t maple_get_device_config( maple_device_t dev ) +lxdream_config_entry_t maple_get_device_config( maple_device_t dev ) { if( dev->get_config == NULL ) return NULL; --- a/src/maple/maple.h Tue Oct 16 12:38:01 2007 +0000 +++ b/src/maple/maple.h Wed Oct 17 11:26:45 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: maple.h,v 1.6 2007-10-16 12:36:29 nkeynes Exp $ + * $Id: maple.h,v 1.7 2007-10-17 11:26:45 nkeynes Exp $ * * Maple bus definitions * @@ -16,10 +16,11 @@ * GNU General Public License for more details. */ -#ifndef dream_maple_H -#define dream_maple_H 1 +#ifndef lxdream_maple_H +#define lxdream_maple_H 1 -#include "dreamcast.h" +#include +#include "config.h" #define MAPLE_CMD_INFO 1 /* Request device information */ #define MAPLE_CMD_EXT_INFO 2 /* Request extended information */ @@ -70,7 +71,7 @@ maple_device_class_t device_class; unsigned char ident[112]; unsigned char version[80]; - dreamcast_config_entry_t (*get_config)(struct maple_device *dev); + lxdream_config_entry_t (*get_config)(struct maple_device *dev); void (*attach)(struct maple_device *dev); void (*detach)(struct maple_device *dev); void (*destroy)(struct maple_device *dev); @@ -93,7 +94,7 @@ maple_device_t maple_get_device( unsigned int port, unsigned int periph ); const maple_device_class_t maple_get_device_class( const gchar *name ); const struct maple_device_class **maple_get_device_classes(); -dreamcast_config_entry_t maple_get_device_config( maple_device_t dev ); +lxdream_config_entry_t maple_get_device_config( maple_device_t dev ); void maple_handle_buffer( uint32_t buffer ); void maple_attach_device( maple_device_t dev, unsigned int port, unsigned int periph ); @@ -101,4 +102,4 @@ void maple_detach_all( ); void maple_reattach_all( ); -#endif /* !dream_maple_H */ +#endif /* !lxdream_maple_H */