Browse Source

new cfg file system

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@390 be3aeb3a-fb24-0410-a615-afba39da0efa
notaz 16 years ago
parent
commit
58c86d0018

+ 131 - 55
platform/common/emu.c

@@ -14,6 +14,7 @@
 #include "menu.h"
 #include "fonts.h"
 #include "lprintf.h"
+#include "config.h"
 
 #include <Pico/PicoInt.h>
 #include <Pico/Patch.h>
@@ -33,8 +34,8 @@
  #define SCREEN_BUFFER psp_screen
 #endif
 
-char *PicoConfigFile = "picoconfig.bin";
-currentConfig_t currentConfig;
+char *PicoConfigFile = "picoconfig.cfg";
+currentConfig_t currentConfig, defaultConfig;
 int rom_loaded = 0;
 char noticeMsg[64];
 int state_slot = 0;
@@ -150,6 +151,8 @@ static int emu_isBios(const char *name)
 	return 0;
 }
 
+static unsigned char scd_id_header[0x100];
+
 /* checks if romFileName points to valid MegaCD image
  * if so, checks for suitable BIOS */
 int emu_cdCheck(int *pregion)
@@ -173,6 +176,9 @@ int emu_cdCheck(int *pregion)
 		return 0;
 	}
 
+	pm_seek(cd_f, (type == 1) ? 0x100 : 0x110, SEEK_SET);
+	pm_read(scd_id_header, sizeof(scd_id_header), cd_f);
+
 	/* it seems we have a CD image here. Try to detect region now.. */
 	pm_seek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET);
 	pm_read(buf, 1, cd_f);
@@ -189,6 +195,68 @@ int emu_cdCheck(int *pregion)
 	return type;
 }
 
+static int extract_text(char *dest, unsigned char *src, int len, int swab)
+{
+	char *p = dest;
+	int i;
+
+	if (swab) swab = 1;
+
+	for (i = len - 1; i >= 0; i--)
+	{
+		if (src[i^swab] != ' ') break;
+	}
+	len = i + 1;
+
+	for (i = 0; i < len; i++)
+	{
+		unsigned char s = src[i^swab];
+		if (s >= 0x20 && s < 0x7f && s != '#' && s != '|' &&
+			s != '[' && s != ']' && s != '\\')
+		{
+			*p++ = s;
+		}
+		else
+		{
+			sprintf(p, "\\%02x", s);
+			p += 3;
+		}
+	}
+
+	return p - dest;
+}
+
+char *emu_makeRomId(void)
+{
+	static char id_string[3+0x11+0x11+0x30+16];
+	unsigned char *id_header;
+	int pos;
+
+	if (Pico.rom == NULL) {
+		id_string[0] = 0;
+		return id_string;
+	}
+
+	if (PicoMCD & 1) {
+		id_header = scd_id_header;
+		strcpy(id_string, "CD|");
+	} else {
+		id_header = Pico.rom + 0x100;
+		strcpy(id_string, "MD|");
+	}
+	pos = 3;
+
+	pos += extract_text(id_string + pos, id_header + 0x80, 0x10, 1); // seral
+	id_string[pos] = '|'; pos++;
+	pos += extract_text(id_string + pos, id_header + 0xf0, 0x10, 1); // region
+	id_string[pos] = '|'; pos++;
+	pos += extract_text(id_string + pos, id_header + 0x50, 0x30, 1); // overseas name
+	id_string[pos] = 0;
+
+	printf("id_string: %s\n", id_string);
+	return id_string;
+}
+
 int emu_ReloadRom(void)
 {
 	unsigned int rom_size = 0;
@@ -421,49 +489,68 @@ static void romfname_ext(char *dst, const char *prefix, const char *ext)
 
 int emu_ReadConfig(int game, int no_defaults)
 {
+	char cfg[512];
 	FILE *f;
-	char cfg[512], extbuf[16];
-	int bread = 0;
+	int ret;
 
 	if (!game)
 	{
 		if (!no_defaults)
-		{
 			emu_setDefaultConfig();
-		}
 		strncpy(cfg, PicoConfigFile, 511);
 		if (config_slot != 0)
 		{
 			char *p = strrchr(cfg, '.');
 			if (p == NULL) p = cfg + strlen(cfg);
-			sprintf(extbuf, ".%i.pbcfg", config_slot);
-			strncpy(p, extbuf, 511 - (p - cfg));
+			sprintf(p, ".%i.cfg", config_slot);
 		}
 		cfg[511] = 0;
-	} else {
-		if (config_slot != 0)
-		     sprintf(extbuf, ".%i.pbcfg", config_slot);
-		else strcpy(extbuf, ".pbcfg");
-		romfname_ext(cfg, "cfg/", extbuf);
-		f = fopen(cfg, "rb");
-		if (!f) romfname_ext(cfg, NULL, ".pbcfg");
-		else fclose(f);
+		ret = config_readsect(cfg, NULL);
 	}
+	else
+	{
+		if (!no_defaults)
+			emu_setDefaultConfig();
 
-	lprintf("emu_ReadConfig: %s ", cfg);
-	f = fopen(cfg, "rb");
-	if (f) {
-		bread = fread(&currentConfig, 1, sizeof(currentConfig), f);
-		fclose(f);
+		// try new .cfg way
+		if (config_slot != 0)
+		     sprintf(cfg, "game.%i.cfg", config_slot);
+		else strcpy(cfg,  "game.cfg");
+		ret = config_readsect(cfg, emu_makeRomId());
+
+		if (ret != 0)
+		{
+			// fall back to old
+			char extbuf[16];
+			if (config_slot != 0)
+				sprintf(extbuf, ".%i.pbcfg", config_slot);
+			else strcpy(extbuf, ".pbcfg");
+			romfname_ext(cfg, "cfg/", extbuf);
+			f = fopen(cfg, "rb");
+			if (!f) {
+				romfname_ext(cfg, NULL, ".pbcfg");
+				f = fopen(cfg, "rb");
+			}
+			if (f) {
+				int bread = fread(&currentConfig, 1, sizeof(currentConfig), f);
+				lprintf("emu_ReadConfig: %s %s\n", cfg, bread > 0 ? "(ok)" : "(failed)");
+				fclose(f);
+				ret = 0;
+			}
+
+			if (ret == 0) {
+				PicoOpt = currentConfig.s_PicoOpt;
+				PsndRate = currentConfig.s_PsndRate;
+				PicoRegionOverride = currentConfig.s_PicoRegion;
+				PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder;
+				PicoCDBuffers = currentConfig.s_PicoCDBuffers;
+			}
+		}
+		else
+		{
+		}
 	}
-	lprintf(bread > 0 ? "(ok)\n" : "(failed)\n");
 
-	PicoOpt = currentConfig.PicoOpt;
-	PsndRate = currentConfig.PsndRate;
-	PicoRegionOverride = currentConfig.PicoRegion;
-	PicoAutoRgnOrder = currentConfig.PicoAutoRgnOrder;
-	PicoCDBuffers = currentConfig.PicoCDBuffers;
-	//scaling_update();
 	// some sanity checks
 	if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;
 #ifdef PSP
@@ -479,54 +566,43 @@ int emu_ReadConfig(int game, int no_defaults)
 		currentConfig.KeyBinds[22] = 1<<30; // vol down
 	}
 #endif
-	if (bread > 0) config_slot_current = config_slot;
-	return (bread > 0); // == sizeof(currentConfig));
+	if (ret == 0) config_slot_current = config_slot;
+	return (ret == 0);
 }
 
 
-int emu_WriteConfig(int game)
+int emu_WriteConfig(int is_game)
 {
-	FILE *f;
-	char cfg[512], extbuf[16];
-	int bwrite = 0;
+	char cfg[512], *game_sect = NULL;
+	int ret, write_lrom = 0;
 
-	if (!game)
+	if (!is_game)
 	{
 		strncpy(cfg, PicoConfigFile, 511);
 		if (config_slot != 0)
 		{
 			char *p = strrchr(cfg, '.');
 			if (p == NULL) p = cfg + strlen(cfg);
-			sprintf(extbuf, ".%i.pbcfg", config_slot);
-			strncpy(p, extbuf, 511 - (p - cfg));
+			sprintf(p, ".%i.cfg", config_slot);
 		}
 		cfg[511] = 0;
+		write_lrom = 1;
 	} else {
 		if (config_slot != 0)
-		     sprintf(extbuf, ".%i.pbcfg", config_slot);
-		else strcpy(extbuf, ".pbcfg");
-		romfname_ext(cfg, "cfg/", extbuf);
+		     sprintf(cfg, "game.%i.cfg", config_slot);
+		else strcpy(cfg,  "game.cfg");
+		game_sect = emu_makeRomId();
 	}
 
 	lprintf("emu_WriteConfig: %s ", cfg);
-	f = fopen(cfg, "wb");
-	if (f) {
-		currentConfig.PicoOpt = PicoOpt;
-		currentConfig.PsndRate = PsndRate;
-		currentConfig.PicoRegion = PicoRegionOverride;
-		currentConfig.PicoAutoRgnOrder = PicoAutoRgnOrder;
-		currentConfig.PicoCDBuffers = PicoCDBuffers;
-		bwrite = fwrite(&currentConfig, 1, sizeof(currentConfig), f);
-		fflush(f);
-		fclose(f);
+	ret = config_writesect(cfg, game_sect);
 #ifndef NO_SYNC
-		sync();
+	sync();
 #endif
-	}
-	lprintf((bwrite == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n");
+	lprintf((ret == 0) ? "(ok)\n" : "(failed)\n");
 
-	if (bwrite == sizeof(currentConfig)) config_slot_current = config_slot;
-	return (bwrite == sizeof(currentConfig));
+	if (ret == 0) config_slot_current = config_slot;
+	return ret == 0;
 }
 
 

+ 8 - 7
platform/common/emu.h

@@ -10,24 +10,23 @@ typedef struct {
 					// craigix_ram, confirm_save, show_cd_leds, confirm_load
 					// A_SNs_gamma, perfect_vsync, giz_scanlines, giz_dblbuff
 					// vsync_mode, show_clock, no_frame_limitter
-	int PicoOpt;  // used for config saving only, see Pico.h
-	int PsndRate; // ditto
-	int PicoRegion; // ditto
+	int s_PicoOpt;		// for old cfg files only
+	int s_PsndRate;
+	int s_PicoRegion;
 	int Frameskip;
 	int CPUclock;
 	int KeyBinds[32];
 	int volume;
 	int gamma;
 	int JoyBinds[4][32];
-	int PicoAutoRgnOrder;
-	int PicoCDBuffers;
+	int s_PicoAutoRgnOrder;
+	int s_PicoCDBuffers;
 	int scaling; // gp2x: 0=center, 1=hscale, 2=hvscale, 3=hsoftscale; psp: bilinear filtering
 	float scale; // psp: screen scale
 	float hscale32, hscale40; // psp: horizontal scale
 } currentConfig_t;
 
-
-extern currentConfig_t currentConfig;
+extern currentConfig_t currentConfig, defaultConfig;
 extern char *PicoConfigFile;
 extern int rom_loaded;
 extern char noticeMsg[64];
@@ -48,4 +47,6 @@ int   emu_cdCheck(int *pregion);
 int   emu_findBios(int region, char **bios_file);
 void  emu_textOut8 (int x, int y, const char *text);
 void  emu_textOut16(int x, int y, const char *text);
+char *emu_makeRomId(void);
 
+void  emu_prepareDefaultConfig(void);

+ 21 - 1
platform/common/menu.c

@@ -322,5 +322,25 @@ int me_process(menu_entry *entries, int count, menu_id id, int is_next)
 	}
 }
 
-
+const char *me_region_name(unsigned int code, int auto_order)
+{
+	static const char *names[] = { "Auto", "      Japan NTSC", "      Japan PAL", "      USA", "      Europe" };
+	static const char *names_short[] = { "", " JP", " JP", " US", " EU" };
+	int u, i = 0;
+	if (code) {
+		code <<= 1;
+		while((code >>= 1)) i++;
+		if (i > 4) return "unknown";
+		return names[i];
+	} else {
+		static char name[24];
+		strcpy(name, "Auto:");
+		for (u = 0; u < 3; u++) {
+			i = 0; code = ((auto_order >> u*4) & 0xf) << 1;
+			while((code >>= 1)) i++;
+			strcat(name, names_short[i]);
+		}
+		return name;
+	}
+}
 

+ 2 - 0
platform/common/menu.h

@@ -99,6 +99,7 @@ typedef struct
 	signed char min;	/* for ranged integer settings, to be sign-extended */
 	signed char max;
 	char enabled;
+	char need_to_save;
 } menu_entry;
 
 
@@ -111,4 +112,5 @@ menu_id me_index2id(const menu_entry *entries, int count, int index);
 void    me_draw(const menu_entry *entries, int count, int x, int y, me_draw_custom_f *cust_draw, void *param);
 int     me_process(menu_entry *entries, int count, menu_id id, int is_next);
 
+const char *me_region_name(unsigned int code, int auto_order);
 

+ 2 - 13
platform/gizmondo/emu.c

@@ -109,19 +109,8 @@ void emu_Deinit(void)
 		SRam.changed = 0;
 	}
 
-	if (!(currentConfig.EmuOpt & 0x20)) {
-		FILE *f = fopen(PicoConfigFile, "r+b");
-		if (!f) emu_WriteConfig(0);
-		else {
-			// if we already have config, reload it, except last ROM
-			fseek(f, sizeof(currentConfig.lastRomFile), SEEK_SET);
-			fread(&currentConfig.EmuOpt, 1, sizeof(currentConfig) - sizeof(currentConfig.lastRomFile), f);
-			fseek(f, 0, SEEK_SET);
-			fwrite(&currentConfig, 1, sizeof(currentConfig), f);
-			fflush(f);
-			fclose(f);
-		}
-	}
+	if (!(currentConfig.EmuOpt & 0x20))
+		config_writelrom(PicoConfigFile);
 
 	PicoExit();
 }

+ 7 - 32
platform/gizmondo/menu.c

@@ -1080,29 +1080,6 @@ menu_entry opt_entries[] =
 #define OPT_ENTRY_COUNT (sizeof(opt_entries) / sizeof(opt_entries[0]))
 
 
-static const char *region_name(unsigned int code)
-{
-	static const char *names[] = { "Auto", "      Japan NTSC", "      Japan PAL", "      USA", "      Europe" };
-	static const char *names_short[] = { "", " JP", " JP", " US", " EU" };
-	int u, i = 0;
-	if (code) {
-		code <<= 1;
-		while((code >>= 1)) i++;
-		if (i > 4) return "unknown";
-		return names[i];
-	} else {
-		static char name[24];
-		strcpy(name, "Auto:");
-		for (u = 0; u < 3; u++) {
-			i = 0; code = ((PicoAutoRgnOrder >> u*4) & 0xf) << 1;
-			while((code >>= 1)) i++;
-			strcat(name, names_short[i]);
-		}
-		return name;
-	}
-}
-
-
 static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *param)
 {
 	char *str, str24[24];
@@ -1129,7 +1106,7 @@ static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *para
 			text_out16(x, y, "Sound Quality:     %5iHz %s", currentConfig.PsndRate, str);
 			break;
 		case MA_OPT_REGION:
-			text_out16(x, y, "Region:              %s", region_name(currentConfig.PicoRegion));
+			text_out16(x, y, "Region:              %s", me_region_name(PicoRegionOverride, PicoAutoRgnOrder));
 			break;
 		case MA_OPT_CONFIRM_STATES:
 			switch ((currentConfig.EmuOpt >> 9) & 5) {
@@ -1188,21 +1165,21 @@ static void region_prevnext(int right)
 	static int rgn_orders[] = { 0x148, 0x184, 0x814, 0x418, 0x841, 0x481 };
 	int i;
 	if (right) {
-		if (!currentConfig.PicoRegion) {
+		if (!PicoRegionOverride) {
 			for (i = 0; i < 6; i++)
 				if (rgn_orders[i] == PicoAutoRgnOrder) break;
 			if (i < 5) PicoAutoRgnOrder = rgn_orders[i+1];
-			else currentConfig.PicoRegion=1;
+			else PicoRegionOverride=1;
 		}
-		else currentConfig.PicoRegion<<=1;
-		if (currentConfig.PicoRegion > 8) currentConfig.PicoRegion = 8;
+		else PicoRegionOverride<<=1;
+		if (PicoRegionOverride > 8) PicoRegionOverride = 8;
 	} else {
-		if (!currentConfig.PicoRegion) {
+		if (!PicoRegionOverride) {
 			for (i = 0; i < 6; i++)
 				if (rgn_orders[i] == PicoAutoRgnOrder) break;
 			if (i > 0) PicoAutoRgnOrder = rgn_orders[i-1];
 		}
-		else currentConfig.PicoRegion>>=1;
+		else PicoRegionOverride>>=1;
 	}
 }
 
@@ -1210,7 +1187,6 @@ static void menu_options_save(void)
 {
 	PicoOpt = currentConfig.PicoOpt;
 	PsndRate = currentConfig.PsndRate;
-	PicoRegionOverride = currentConfig.PicoRegion;
 	if (PicoRegionOverride) {
 		// force setting possibly changed..
 		Pico.m.pal = (PicoRegionOverride == 2 || PicoRegionOverride == 8) ? 1 : 0;
@@ -1230,7 +1206,6 @@ static int menu_loop_options(void)
 
 	currentConfig.PicoOpt = PicoOpt;
 	currentConfig.PsndRate = PsndRate;
-	currentConfig.PicoRegion = PicoRegionOverride;
 
 	me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_SAVECFG_GAME, rom_loaded);
 	me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_LOADCFG, config_slot != config_slot_current);

+ 1 - 1
platform/gp2x/Makefile

@@ -58,7 +58,7 @@ OBJS += main.o menu.o gp2x.o usbjoy.o emu.o squidgehack.o cpuctrl.o
 OBJS += 940ctl.o
 
 # common
-OBJS += ../common/emu.o ../common/menu.o ../common/fonts.o ../common/arm_utils.o \
+OBJS += ../common/emu.o ../common/menu.o ../common/fonts.o ../common/config.o ../common/arm_utils.o \
 	../common/readpng.o ../common/mp3_helix.o
 
 # Pico

+ 39 - 38
platform/gp2x/emu.c

@@ -21,6 +21,7 @@
 #include "../common/arm_utils.h"
 #include "../common/fonts.h"
 #include "../common/emu.h"
+#include "../common/config.h"
 #include "cpuctrl.h"
 
 #include <Pico/PicoInt.h>
@@ -160,20 +161,10 @@ void emu_Deinit(void)
 	}
 
 	if (!(currentConfig.EmuOpt & 0x20)) {
-		FILE *f = fopen(PicoConfigFile, "r+b");
-		if (!f) emu_WriteConfig(0);
-		else {
-			// if we already have config, reload it, except last ROM
-			fseek(f, sizeof(currentConfig.lastRomFile), SEEK_SET);
-			fread(&currentConfig.EmuOpt, 1, sizeof(currentConfig) - sizeof(currentConfig.lastRomFile), f);
-			fseek(f, 0, SEEK_SET);
-			fwrite(&currentConfig, 1, sizeof(currentConfig), f);
-			fflush(f);
-			fclose(f);
+		config_writelrom(PicoConfigFile);
 #ifndef NO_SYNC
-			sync();
+		sync();
 #endif
-		}
 	}
 
 	free(PicoDraw2FB);
@@ -185,34 +176,44 @@ void emu_Deinit(void)
 		set_gamma(100, 0);
 }
 
+void emu_prepareDefaultConfig(void)
+{
+	memset(&defaultConfig, 0, sizeof(defaultConfig));
+	defaultConfig.lastRomFile[0] = 0;
+	defaultConfig.EmuOpt  = 0x1f | 0x600; // | confirm_save, cd_leds
+	defaultConfig.s_PicoOpt = 0x0f | 0xe00; // | use_940, cd_pcm, cd_cdda
+	defaultConfig.s_PsndRate = 44100;
+	defaultConfig.s_PicoRegion = 0; // auto
+	defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP
+	defaultConfig.s_PicoCDBuffers = 64;
+	defaultConfig.Frameskip = -1; // auto
+	defaultConfig.CPUclock = 200;
+	defaultConfig.volume = 50;
+	defaultConfig.KeyBinds[ 0] = 1<<0; // SACB RLDU
+	defaultConfig.KeyBinds[ 4] = 1<<1;
+	defaultConfig.KeyBinds[ 2] = 1<<2;
+	defaultConfig.KeyBinds[ 6] = 1<<3;
+	defaultConfig.KeyBinds[14] = 1<<4;
+	defaultConfig.KeyBinds[13] = 1<<5;
+	defaultConfig.KeyBinds[12] = 1<<6;
+	defaultConfig.KeyBinds[ 8] = 1<<7;
+	defaultConfig.KeyBinds[15] = 1<<26; // switch rend
+	defaultConfig.KeyBinds[10] = 1<<27; // save state
+	defaultConfig.KeyBinds[11] = 1<<28; // load state
+	defaultConfig.KeyBinds[23] = 1<<29; // vol up
+	defaultConfig.KeyBinds[22] = 1<<30; // vol down
+	defaultConfig.gamma = 100;
+	defaultConfig.scaling = 0;
+}
+
 void emu_setDefaultConfig(void)
 {
-	memset(&currentConfig, 0, sizeof(currentConfig));
-	currentConfig.lastRomFile[0] = 0;
-	currentConfig.EmuOpt  = 0x1f | 0x600; // | confirm_save, cd_leds
-	currentConfig.PicoOpt = 0x0f | 0xe00; // | use_940, cd_pcm, cd_cdda
-	currentConfig.PsndRate = 22050; // 44100;
-	currentConfig.PicoRegion = 0; // auto
-	currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP
-	currentConfig.Frameskip = -1; // auto
-	currentConfig.CPUclock = 200;
-	currentConfig.volume = 50;
-	currentConfig.KeyBinds[ 0] = 1<<0; // SACB RLDU
-	currentConfig.KeyBinds[ 4] = 1<<1;
-	currentConfig.KeyBinds[ 2] = 1<<2;
-	currentConfig.KeyBinds[ 6] = 1<<3;
-	currentConfig.KeyBinds[14] = 1<<4;
-	currentConfig.KeyBinds[13] = 1<<5;
-	currentConfig.KeyBinds[12] = 1<<6;
-	currentConfig.KeyBinds[ 8] = 1<<7;
-	currentConfig.KeyBinds[15] = 1<<26; // switch rend
-	currentConfig.KeyBinds[10] = 1<<27; // save state
-	currentConfig.KeyBinds[11] = 1<<28; // load state
-	currentConfig.KeyBinds[23] = 1<<29; // vol up
-	currentConfig.KeyBinds[22] = 1<<30; // vol down
-	currentConfig.gamma = 100;
-	currentConfig.PicoCDBuffers = 64;
-	currentConfig.scaling = 0;
+	memcpy(&currentConfig, &defaultConfig, sizeof(currentConfig));
+	PicoOpt = currentConfig.s_PicoOpt;
+	PsndRate = currentConfig.s_PsndRate;
+	PicoRegionOverride = currentConfig.s_PicoRegion;
+	PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder;
+	PicoCDBuffers = currentConfig.s_PicoCDBuffers;
 }
 
 void osd_text(int x, int y, const char *text)

+ 3 - 0
platform/gp2x/main.c

@@ -13,6 +13,7 @@
 #include "menu.h"
 #include "../common/menu.h"
 #include "../common/emu.h"
+#include "../common/config.h"
 #include "emu.h"
 #include "940ctl.h"
 #include "version.h"
@@ -81,7 +82,9 @@ int main(int argc, char *argv[])
 {
 	g_argv = argv;
 
+	emu_prepareDefaultConfig();
 	emu_ReadConfig(0, 0);
+
 	gp2x_init();
 	if (currentConfig.EmuOpt&0x10) {
 		int ret = mmuhack();

+ 77 - 104
platform/gp2x/menu.c

@@ -846,7 +846,7 @@ static void kc_sel_loop(void)
 {
 	int menu_sel = 3, menu_sel_max = 3;
 	unsigned long inp = 0;
-	int is_6button = currentConfig.PicoOpt & 0x020;
+	int is_6button = PicoOpt & 0x020;
 
 	while (1)
 	{
@@ -873,19 +873,20 @@ static void kc_sel_loop(void)
 
 menu_entry cdopt_entries[] =
 {
-	{ NULL,                        MB_NONE,  MA_CDOPT_TESTBIOS_USA, NULL, 0, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_CDOPT_TESTBIOS_EUR, NULL, 0, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_CDOPT_TESTBIOS_JAP, NULL, 0, 0, 0, 1 },
-	{ "CD LEDs",                   MB_ONOFF, MA_CDOPT_LEDS,         &currentConfig.EmuOpt,  0x0400, 0, 0, 1 },
-	{ "CDDA audio (using mp3s)",   MB_ONOFF, MA_CDOPT_CDDA,         &currentConfig.PicoOpt, 0x0800, 0, 0, 1 },
-	{ "PCM audio",                 MB_ONOFF, MA_CDOPT_PCM,          &currentConfig.PicoOpt, 0x0400, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_CDOPT_READAHEAD,    NULL, 0, 0, 0, 1 },
-	{ "SaveRAM cart",              MB_ONOFF, MA_CDOPT_SAVERAM,      &currentConfig.PicoOpt, 0x8000, 0, 0, 1 },
-	{ "Scale/Rot. fx (slow)",      MB_ONOFF, MA_CDOPT_SCALEROT_CHIP,&currentConfig.PicoOpt, 0x1000, 0, 0, 1 },
-	{ "Better sync (slow)",        MB_ONOFF, MA_CDOPT_BETTER_SYNC,  &currentConfig.PicoOpt, 0x2000, 0, 0, 1 },
-	{ "done",                      MB_NONE,  MA_CDOPT_DONE,         NULL, 0, 0, 0, 1 },
+	{ NULL,                        MB_NONE,  MA_CDOPT_TESTBIOS_USA, NULL, 0, 0, 0, 1, 0 },
+	{ NULL,                        MB_NONE,  MA_CDOPT_TESTBIOS_EUR, NULL, 0, 0, 0, 1, 0 },
+	{ NULL,                        MB_NONE,  MA_CDOPT_TESTBIOS_JAP, NULL, 0, 0, 0, 1, 0 },
+	{ "CD LEDs",                   MB_ONOFF, MA_CDOPT_LEDS,         &currentConfig.EmuOpt, 0x0400, 0, 0, 1, 1 },
+	{ "CDDA audio (using mp3s)",   MB_ONOFF, MA_CDOPT_CDDA,         &PicoOpt, 0x0800, 0, 0, 1, 1 },
+	{ "PCM audio",                 MB_ONOFF, MA_CDOPT_PCM,          &PicoOpt, 0x0400, 0, 0, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_CDOPT_READAHEAD,    NULL, 0, 0, 0, 1, 1 },
+	{ "SaveRAM cart",              MB_ONOFF, MA_CDOPT_SAVERAM,      &PicoOpt, 0x8000, 0, 0, 1, 1 },
+	{ "Scale/Rot. fx (slow)",      MB_ONOFF, MA_CDOPT_SCALEROT_CHIP,&PicoOpt, 0x1000, 0, 0, 1, 1 },
+	{ "Better sync (slow)",        MB_ONOFF, MA_CDOPT_BETTER_SYNC,  &PicoOpt, 0x2000, 0, 0, 1, 1 },
+	{ "done",                      MB_NONE,  MA_CDOPT_DONE,         NULL, 0, 0, 0, 1, 0 },
 };
 
+const int cdopt_entry_count = (sizeof(cdopt_entries) / sizeof(cdopt_entries[0]));
 #define CDOPT_ENTRY_COUNT (sizeof(cdopt_entries) / sizeof(cdopt_entries[0]))
 
 
@@ -1023,28 +1024,29 @@ static void cd_menu_loop_options(void)
 
 menu_entry opt2_entries[] =
 {
-	{ NULL,                        MB_NONE,  MA_OPT2_GAMMA,         NULL, 0, 0, 0, 1 },
-	{ "A_SN's gamma curve",        MB_ONOFF, MA_OPT2_A_SN_GAMMA,    &currentConfig.EmuOpt, 0x1000, 0, 0, 1 },
-	{ "Perfect vsync",             MB_ONOFF, MA_OPT2_VSYNC,         &currentConfig.EmuOpt, 0x2000, 0, 0, 1 },
-	{ "Emulate Z80",               MB_ONOFF, MA_OPT2_ENABLE_Z80,    &currentConfig.PicoOpt,0x0004, 0, 0, 1 },
-	{ "Emulate YM2612 (FM)",       MB_ONOFF, MA_OPT2_ENABLE_YM2612, &currentConfig.PicoOpt,0x0001, 0, 0, 1 },
-	{ "Emulate SN76496 (PSG)",     MB_ONOFF, MA_OPT2_ENABLE_SN76496,&currentConfig.PicoOpt,0x0002, 0, 0, 1 },
-	{ "gzip savestates",           MB_ONOFF, MA_OPT2_GZIP_STATES,   &currentConfig.EmuOpt, 0x0008, 0, 0, 1 },
-	{ "Don't save last used ROM",  MB_ONOFF, MA_OPT2_NO_LAST_ROM,   &currentConfig.EmuOpt, 0x0020, 0, 0, 1 },
-	{ "needs restart:",            MB_NONE,  MA_NONE,               NULL, 0, 0, 0, 1 },
-	{ "craigix's RAM timings",     MB_ONOFF, MA_OPT2_RAMTIMINGS,    &currentConfig.EmuOpt, 0x0100, 0, 0, 1 },
-	{ NULL,                        MB_ONOFF, MA_OPT2_SQUIDGEHACK,   &currentConfig.EmuOpt, 0x0010, 0, 0, 1 },
-	{ "done",                      MB_NONE,  MA_OPT2_DONE,          NULL, 0, 0, 0, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT2_GAMMA,         NULL, 0, 0, 0, 1, 1 },
+	{ "A_SN's gamma curve",        MB_ONOFF, MA_OPT2_A_SN_GAMMA,    &currentConfig.EmuOpt, 0x1000, 0, 0, 1, 1 },
+	{ "Perfect vsync",             MB_ONOFF, MA_OPT2_VSYNC,         &currentConfig.EmuOpt, 0x2000, 0, 0, 1, 1 },
+	{ "Emulate Z80",               MB_ONOFF, MA_OPT2_ENABLE_Z80,    &PicoOpt, 0x0004, 0, 0, 1, 1 },
+	{ "Emulate YM2612 (FM)",       MB_ONOFF, MA_OPT2_ENABLE_YM2612, &PicoOpt, 0x0001, 0, 0, 1, 1 },
+	{ "Emulate SN76496 (PSG)",     MB_ONOFF, MA_OPT2_ENABLE_SN76496,&PicoOpt, 0x0002, 0, 0, 1, 1 },
+	{ "gzip savestates",           MB_ONOFF, MA_OPT2_GZIP_STATES,   &currentConfig.EmuOpt, 0x0008, 0, 0, 1, 1 },
+	{ "Don't save last used ROM",  MB_ONOFF, MA_OPT2_NO_LAST_ROM,   &currentConfig.EmuOpt, 0x0020, 0, 0, 1, 1 },
+	{ "needs restart:",            MB_NONE,  MA_NONE,               NULL, 0, 0, 0, 1, 0 },
+	{ "craigix's RAM timings",     MB_ONOFF, MA_OPT2_RAMTIMINGS,    &currentConfig.EmuOpt, 0x0100, 0, 0, 1, 1 },
+	{ NULL,                        MB_ONOFF, MA_OPT2_SQUIDGEHACK,   &currentConfig.EmuOpt, 0x0010, 0, 0, 1, 1 },
+	{ "done",                      MB_NONE,  MA_OPT2_DONE,          NULL, 0, 0, 0, 1, 0 },
 };
 
 #define OPT2_ENTRY_COUNT (sizeof(opt2_entries) / sizeof(opt2_entries[0]))
+const int opt2_entry_count = (sizeof(opt2_entries) / sizeof(opt2_entries[0]));
 
 static void menu_opt2_cust_draw(const menu_entry *entry, int x, int y, void *param)
 {
 	if (entry->id == MA_OPT2_GAMMA)
 		text_out16(x, y, "Gamma correction           %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100);
 	else if (entry->id == MA_OPT2_SQUIDGEHACK)
-		text_out16(x, y, "squidgehack (now %s %s", mmuhack_status ? "active)  " : "inactive)",
+		text_out16(x, y, "Squidgehack (now %s %s", mmuhack_status ? "active)  " : "inactive)",
 			(currentConfig.EmuOpt&0x0010)?"ON":"OFF");
 }
 
@@ -1105,52 +1107,30 @@ static void amenu_loop_options(void)
 
 menu_entry opt_entries[] =
 {
-	{ NULL,                        MB_NONE,  MA_OPT_RENDERER,      NULL, 0, 0, 0, 1 },
-	{ NULL,                        MB_RANGE, MA_OPT_SCALING,       &currentConfig.scaling, 0, 0, 3, 1 },
-	{ "Accurate timing (slower)",  MB_ONOFF, MA_OPT_ACC_TIMING,    &currentConfig.PicoOpt, 0x040, 0, 0, 1 },
-	{ "Accurate sprites (slower)", MB_ONOFF, MA_OPT_ACC_SPRITES,   &currentConfig.PicoOpt, 0x080, 0, 0, 1 },
-	{ "Show FPS",                  MB_ONOFF, MA_OPT_SHOW_FPS,      &currentConfig.EmuOpt,  0x002, 0, 0, 1 },
-	{ NULL,                        MB_RANGE, MA_OPT_FRAMESKIP,     &currentConfig.Frameskip, 0, -1, 16, 1 },
-	{ "Enable sound",              MB_ONOFF, MA_OPT_ENABLE_SOUND,  &currentConfig.EmuOpt,  0x004, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1 },
-	{ "Use ARM940 core for sound", MB_ONOFF, MA_OPT_ARM940_SOUND,  &currentConfig.PicoOpt, 0x200, 0, 0, 1 },
-	{ "6 button pad",              MB_ONOFF, MA_OPT_6BUTTON_PAD,   &currentConfig.PicoOpt, 0x020, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT_REGION,        NULL, 0, 0, 0, 1 },
-	{ "Use SRAM/BRAM savestates",  MB_ONOFF, MA_OPT_SRAM_STATES,   &currentConfig.EmuOpt,  0x001, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT_CONFIRM_STATES,NULL, 0, 0, 0, 1 },
-	{ "Save slot",                 MB_RANGE, MA_OPT_SAVE_SLOT,     &state_slot, 0, 0, 9, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT_CPU_CLOCKS,    NULL, 0, 0, 0, 1 },
-	{ "[Sega/Mega CD options]",    MB_NONE,  MA_OPT_SCD_OPTS,      NULL, 0, 0, 0, 1 },
-	{ "[advanced options]",        MB_NONE,  MA_OPT_ADV_OPTS,      NULL, 0, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT_SAVECFG,       NULL, 0, 0, 0, 1 },
-	{ "Save cfg for current game only",MB_NONE,MA_OPT_SAVECFG_GAME,NULL, 0, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT_LOADCFG,       NULL, 0, 0, 0, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT_RENDERER,      NULL, 0, 0, 0, 1, 1 },
+	{ NULL,                        MB_RANGE, MA_OPT_SCALING,       &currentConfig.scaling, 0, 0, 3, 1, 1 },
+	{ "Accurate timing (slower)",  MB_ONOFF, MA_OPT_ACC_TIMING,    &PicoOpt, 0x040, 0, 0, 1, 1 },
+	{ "Accurate sprites (slower)", MB_ONOFF, MA_OPT_ACC_SPRITES,   &PicoOpt, 0x080, 0, 0, 1, 1 },
+	{ "Show FPS",                  MB_ONOFF, MA_OPT_SHOW_FPS,      &currentConfig.EmuOpt,  0x002, 0, 0, 1, 1 },
+	{ NULL,                        MB_RANGE, MA_OPT_FRAMESKIP,     &currentConfig.Frameskip, 0, -1, 16, 1, 1 },
+	{ "Enable sound",              MB_ONOFF, MA_OPT_ENABLE_SOUND,  &currentConfig.EmuOpt,  0x004, 0, 0, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1, 1 },
+	{ "Use ARM940 core for sound", MB_ONOFF, MA_OPT_ARM940_SOUND,  &PicoOpt, 0x200, 0, 0, 1, 1 },
+	{ "6 button pad",              MB_ONOFF, MA_OPT_6BUTTON_PAD,   &PicoOpt, 0x020, 0, 0, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT_REGION,        NULL, 0, 0, 0, 1, 1 },
+	{ "Use SRAM/BRAM savestates",  MB_ONOFF, MA_OPT_SRAM_STATES,   &currentConfig.EmuOpt,  0x001, 0, 0, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT_CONFIRM_STATES,NULL, 0, 0, 0, 1, 1 },
+	{ "Save slot",                 MB_RANGE, MA_OPT_SAVE_SLOT,     &state_slot, 0, 0, 9, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT_CPU_CLOCKS,    NULL, 0, 0, 0, 1, 1 },
+	{ "[Sega/Mega CD options]",    MB_NONE,  MA_OPT_SCD_OPTS,      NULL, 0, 0, 0, 1, 0 },
+	{ "[advanced options]",        MB_NONE,  MA_OPT_ADV_OPTS,      NULL, 0, 0, 0, 1, 0 },
+	{ NULL,                        MB_NONE,  MA_OPT_SAVECFG,       NULL, 0, 0, 0, 1, 0 },
+	{ "Save cfg for current game only",MB_NONE,MA_OPT_SAVECFG_GAME,NULL, 0, 0, 0, 1, 0 },
+	{ NULL,                        MB_NONE,  MA_OPT_LOADCFG,       NULL, 0, 0, 0, 1, 0 },
 };
 
 #define OPT_ENTRY_COUNT (sizeof(opt_entries) / sizeof(opt_entries[0]))
-
-
-static const char *region_name(unsigned int code)
-{
-	static const char *names[] = { "Auto", "      Japan NTSC", "      Japan PAL", "      USA", "      Europe" };
-	static const char *names_short[] = { "", " JP", " JP", " US", " EU" };
-	int u, i = 0;
-	if (code) {
-		code <<= 1;
-		while((code >>= 1)) i++;
-		if (i > 4) return "unknown";
-		return names[i];
-	} else {
-		static char name[24];
-		strcpy(name, "Auto:");
-		for (u = 0; u < 3; u++) {
-			i = 0; code = ((PicoAutoRgnOrder >> u*4) & 0xf) << 1;
-			while((code >>= 1)) i++;
-			strcat(name, names_short[i]);
-		}
-		return name;
-	}
-}
+const int opt_entry_count = OPT_ENTRY_COUNT;
 
 
 static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *param)
@@ -1160,7 +1140,7 @@ static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *para
 	switch (entry->id)
 	{
 		case MA_OPT_RENDERER:
-			if (currentConfig.PicoOpt&0x10)
+			if (PicoOpt&0x10)
 				str = " 8bit fast";
 			else if (currentConfig.EmuOpt&0x80)
 				str = "16bit accurate";
@@ -1184,11 +1164,11 @@ static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *para
 			text_out16(x, y, "Frameskip                  %s", str24);
 			break;
 		case MA_OPT_SOUND_QUALITY:
-			str = (currentConfig.PicoOpt&0x08)?"stereo":"mono";
-			text_out16(x, y, "Sound Quality:     %5iHz %s", currentConfig.PsndRate, str);
+			str = (PicoOpt&0x08)?"stereo":"mono";
+			text_out16(x, y, "Sound Quality:     %5iHz %s", PsndRate, str);
 			break;
 		case MA_OPT_REGION:
-			text_out16(x, y, "Region:              %s", region_name(currentConfig.PicoRegion));
+			text_out16(x, y, "Region:              %s", me_region_name(PicoRegionOverride, PicoAutoRgnOrder));
 			break;
 		case MA_OPT_CONFIRM_STATES:
 			switch ((currentConfig.EmuOpt >> 9) & 5) {
@@ -1250,29 +1230,26 @@ static void region_prevnext(int right)
 	static int rgn_orders[] = { 0x148, 0x184, 0x814, 0x418, 0x841, 0x481 };
 	int i;
 	if (right) {
-		if (!currentConfig.PicoRegion) {
+		if (!PicoRegionOverride) {
 			for (i = 0; i < 6; i++)
 				if (rgn_orders[i] == PicoAutoRgnOrder) break;
 			if (i < 5) PicoAutoRgnOrder = rgn_orders[i+1];
-			else currentConfig.PicoRegion=1;
+			else PicoRegionOverride=1;
 		}
-		else currentConfig.PicoRegion<<=1;
-		if (currentConfig.PicoRegion > 8) currentConfig.PicoRegion = 8;
+		else PicoRegionOverride<<=1;
+		if (PicoRegionOverride > 8) PicoRegionOverride = 8;
 	} else {
-		if (!currentConfig.PicoRegion) {
+		if (!PicoRegionOverride) {
 			for (i = 0; i < 6; i++)
 				if (rgn_orders[i] == PicoAutoRgnOrder) break;
 			if (i > 0) PicoAutoRgnOrder = rgn_orders[i-1];
 		}
-		else currentConfig.PicoRegion>>=1;
+		else PicoRegionOverride>>=1;
 	}
 }
 
 static void menu_options_save(void)
 {
-	PicoOpt = currentConfig.PicoOpt;
-	PsndRate = currentConfig.PsndRate;
-	PicoRegionOverride = currentConfig.PicoRegion;
 	if (PicoRegionOverride) {
 		// force setting possibly changed..
 		Pico.m.pal = (PicoRegionOverride == 2 || PicoRegionOverride == 8) ? 1 : 0;
@@ -1290,10 +1267,6 @@ static int menu_loop_options(void)
 	unsigned long inp = 0;
 	menu_id selected_id;
 
-	currentConfig.PicoOpt = PicoOpt;
-	currentConfig.PsndRate = PsndRate;
-	currentConfig.PicoRegion = PicoRegionOverride;
-
 	me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_SAVECFG_GAME, rom_loaded);
 	me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_LOADCFG, config_slot != config_slot_current);
 	menu_sel_max = me_count_enabled(opt_entries, OPT_ENTRY_COUNT) - 1;
@@ -1306,26 +1279,26 @@ static int menu_loop_options(void)
 		if (inp & GP2X_UP  ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
 		if (inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
 		selected_id = me_index2id(opt_entries, OPT_ENTRY_COUNT, menu_sel);
-		if (inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise
+		if (inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choice
 			if (!me_process(opt_entries, OPT_ENTRY_COUNT, selected_id, (inp&GP2X_RIGHT) ? 1 : 0)) {
 				switch (selected_id) {
 					case MA_OPT_RENDERER:
 						if (inp & GP2X_LEFT) {
-							if      (  currentConfig.PicoOpt&0x10) currentConfig.PicoOpt&= ~0x10;
+							if      (PicoOpt&0x10) PicoOpt&= ~0x10;
 							else if (!(currentConfig.EmuOpt &0x80))currentConfig.EmuOpt |=  0x80;
 							else if (  currentConfig.EmuOpt &0x80) break;
 						} else {
-							if      (  currentConfig.PicoOpt&0x10) break;
-							else if (!(currentConfig.EmuOpt &0x80))currentConfig.PicoOpt|=  0x10;
+							if      (PicoOpt&0x10) break;
+							else if (!(currentConfig.EmuOpt &0x80))PicoOpt|=  0x10;
 							else if (  currentConfig.EmuOpt &0x80) currentConfig.EmuOpt &= ~0x80;
 						}
 						break;
 					case MA_OPT_SOUND_QUALITY:
-						if ((inp & GP2X_RIGHT) && currentConfig.PsndRate == 44100 && !(currentConfig.PicoOpt&0x08)) {
-							currentConfig.PsndRate = 8000;  currentConfig.PicoOpt|= 0x08;
-						} else if ((inp & GP2X_LEFT) && currentConfig.PsndRate == 8000 && (currentConfig.PicoOpt&0x08)) {
-							currentConfig.PsndRate = 44100; currentConfig.PicoOpt&=~0x08;
-						} else currentConfig.PsndRate = sndrate_prevnext(currentConfig.PsndRate, inp & GP2X_RIGHT);
+						if ((inp & GP2X_RIGHT) && PsndRate == 44100 && !(PicoOpt&0x08)) {
+							PsndRate = 8000; PicoOpt|= 0x08;
+						} else if ((inp & GP2X_LEFT) && PsndRate == 8000 && (PicoOpt&0x08)) {
+							PsndRate = 44100; PicoOpt&=~0x08;
+						} else  PsndRate = sndrate_prevnext(PsndRate, inp & GP2X_RIGHT);
 						break;
 					case MA_OPT_REGION:
 						region_prevnext(inp & GP2X_RIGHT);
@@ -1444,16 +1417,16 @@ static void draw_menu_credits(void)
 
 menu_entry main_entries[] =
 {
-	{ "Resume game",        MB_NONE, MA_MAIN_RESUME_GAME, NULL, 0, 0, 0, 0 },
-	{ "Save State",         MB_NONE, MA_MAIN_SAVE_STATE,  NULL, 0, 0, 0, 0 },
-	{ "Load State",         MB_NONE, MA_MAIN_LOAD_STATE,  NULL, 0, 0, 0, 0 },
-	{ "Reset game",         MB_NONE, MA_MAIN_RESET_GAME,  NULL, 0, 0, 0, 0 },
-	{ "Load new ROM/ISO",   MB_NONE, MA_MAIN_LOAD_ROM,    NULL, 0, 0, 0, 1 },
-	{ "Change options",     MB_NONE, MA_MAIN_OPTIONS,     NULL, 0, 0, 0, 1 },
-	{ "Configure controls", MB_NONE, MA_MAIN_CONTROLS,    NULL, 0, 0, 0, 1 },
-	{ "Credits",            MB_NONE, MA_MAIN_CREDITS,     NULL, 0, 0, 0, 1 },
-	{ "Patches / GameGenie",MB_NONE, MA_MAIN_PATCHES,     NULL, 0, 0, 0, 0 },
-	{ "Exit",               MB_NONE, MA_MAIN_EXIT,        NULL, 0, 0, 0, 1 }
+	{ "Resume game",        MB_NONE, MA_MAIN_RESUME_GAME, NULL, 0, 0, 0, 0, 0 },
+	{ "Save State",         MB_NONE, MA_MAIN_SAVE_STATE,  NULL, 0, 0, 0, 0, 0 },
+	{ "Load State",         MB_NONE, MA_MAIN_LOAD_STATE,  NULL, 0, 0, 0, 0, 0 },
+	{ "Reset game",         MB_NONE, MA_MAIN_RESET_GAME,  NULL, 0, 0, 0, 0, 0 },
+	{ "Load new ROM/ISO",   MB_NONE, MA_MAIN_LOAD_ROM,    NULL, 0, 0, 0, 1, 0 },
+	{ "Change options",     MB_NONE, MA_MAIN_OPTIONS,     NULL, 0, 0, 0, 1, 0 },
+	{ "Configure controls", MB_NONE, MA_MAIN_CONTROLS,    NULL, 0, 0, 0, 1, 0 },
+	{ "Credits",            MB_NONE, MA_MAIN_CREDITS,     NULL, 0, 0, 0, 1, 0 },
+	{ "Patches / GameGenie",MB_NONE, MA_MAIN_PATCHES,     NULL, 0, 0, 0, 0, 0 },
+	{ "Exit",               MB_NONE, MA_MAIN_EXIT,        NULL, 0, 0, 0, 1, 0 }
 };
 
 #define MAIN_ENTRY_COUNT (sizeof(main_entries) / sizeof(main_entries[0]))

+ 1 - 1
platform/linux/Makefile

@@ -31,7 +31,7 @@ OBJS += platform/gp2x/main.o platform/gp2x/menu.o platform/gp2x/emu.o platform/g
 		gp2x.o 940ctl_ym2612.o log_io.o
 
 # common
-OBJS += platform/common/emu.o platform/common/menu.o platform/common/fonts.o \
+OBJS += platform/common/emu.o platform/common/menu.o platform/common/config.o platform/common/fonts.o \
 		platform/common/readpng.o platform/common/mp3_helix.o
 
 # Pico

+ 2 - 13
platform/psp/emu.c

@@ -111,19 +111,8 @@ void emu_Deinit(void)
 		SRam.changed = 0;
 	}
 
-	if (!(currentConfig.EmuOpt & 0x20)) {
-		FILE *f = fopen(PicoConfigFile, "r+b");
-		if (!f) emu_WriteConfig(0);
-		else {
-			// if we already have config, reload it, except last ROM
-			fseek(f, sizeof(currentConfig.lastRomFile), SEEK_SET);
-			fread(&currentConfig.EmuOpt, 1, sizeof(currentConfig) - sizeof(currentConfig.lastRomFile), f);
-			fseek(f, 0, SEEK_SET);
-			fwrite(&currentConfig, 1, sizeof(currentConfig), f);
-			fflush(f);
-			fclose(f);
-		}
-	}
+	if (!(currentConfig.EmuOpt & 0x20))
+		config_writelrom(PicoConfigFile);
 
 	PicoExit();
 	sound_deinit();

+ 7 - 32
platform/psp/menu.c

@@ -1261,29 +1261,6 @@ menu_entry opt_entries[] =
 #define OPT_ENTRY_COUNT (sizeof(opt_entries) / sizeof(opt_entries[0]))
 
 
-static const char *region_name(unsigned int code)
-{
-	static const char *names[] = { "Auto", "      Japan NTSC", "      Japan PAL", "      USA", "      Europe" };
-	static const char *names_short[] = { "", " JP", " JP", " US", " EU" };
-	int u, i = 0;
-	if (code) {
-		code <<= 1;
-		while((code >>= 1)) i++;
-		if (i > 4) return "unknown";
-		return names[i];
-	} else {
-		static char name[24];
-		strcpy(name, "Auto:");
-		for (u = 0; u < 3; u++) {
-			i = 0; code = ((PicoAutoRgnOrder >> u*4) & 0xf) << 1;
-			while((code >>= 1)) i++;
-			strcat(name, names_short[i]);
-		}
-		return name;
-	}
-}
-
-
 static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *param)
 {
 	char *str, str24[24];
@@ -1310,7 +1287,7 @@ static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *para
 			text_out16(x, y, "Sound Quality:     %5iHz %s", currentConfig.PsndRate, str);
 			break;
 		case MA_OPT_REGION:
-			text_out16(x, y, "Region:              %s", region_name(currentConfig.PicoRegion));
+			text_out16(x, y, "Region:              %s", me_region_name(PicoRegionOverride, PicoAutoRgnOrder));
 			break;
 		case MA_OPT_CONFIRM_STATES:
 			switch ((currentConfig.EmuOpt >> 9) & 5) {
@@ -1371,21 +1348,21 @@ static void region_prevnext(int right)
 	static int rgn_orders[] = { 0x148, 0x184, 0x814, 0x418, 0x841, 0x481 };
 	int i;
 	if (right) {
-		if (!currentConfig.PicoRegion) {
+		if (!PicoRegionOverride) {
 			for (i = 0; i < 6; i++)
 				if (rgn_orders[i] == PicoAutoRgnOrder) break;
 			if (i < 5) PicoAutoRgnOrder = rgn_orders[i+1];
-			else currentConfig.PicoRegion=1;
+			else PicoRegionOverride=1;
 		}
-		else currentConfig.PicoRegion<<=1;
-		if (currentConfig.PicoRegion > 8) currentConfig.PicoRegion = 8;
+		else PicoRegionOverride<<=1;
+		if (PicoRegionOverride > 8) PicoRegionOverride = 8;
 	} else {
-		if (!currentConfig.PicoRegion) {
+		if (!PicoRegionOverride) {
 			for (i = 0; i < 6; i++)
 				if (rgn_orders[i] == PicoAutoRgnOrder) break;
 			if (i > 0) PicoAutoRgnOrder = rgn_orders[i-1];
 		}
-		else currentConfig.PicoRegion>>=1;
+		else PicoRegionOverride>>=1;
 	}
 }
 
@@ -1393,7 +1370,6 @@ static void menu_options_save(void)
 {
 	PicoOpt = currentConfig.PicoOpt;
 	PsndRate = currentConfig.PsndRate;
-	PicoRegionOverride = currentConfig.PicoRegion;
 	if (PicoRegionOverride) {
 		// force setting possibly changed..
 		Pico.m.pal = (PicoRegionOverride == 2 || PicoRegionOverride == 8) ? 1 : 0;
@@ -1413,7 +1389,6 @@ static int menu_loop_options(void)
 
 	currentConfig.PicoOpt = PicoOpt;
 	currentConfig.PsndRate = PsndRate;
-	currentConfig.PicoRegion = PicoRegionOverride;
 
 	me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_SAVECFG_GAME, rom_loaded);
 	me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_LOADCFG, config_slot != config_slot_current);