Forráskód Böngészése

psp code updated for latest base, black level

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@415 be3aeb3a-fb24-0410-a615-afba39da0efa
notaz 16 éve
szülő
commit
6fc5714482

+ 8 - 1
Pico/carthw/svp/svp.c

@@ -38,16 +38,21 @@ static void PicoSVPReset(void)
 
 
 	memcpy(svp->iram_rom + 0x800, Pico.rom + 0x800, 0x20000 - 0x800);
 	memcpy(svp->iram_rom + 0x800, Pico.rom + 0x800, 0x20000 - 0x800);
 	ssp1601_reset(&svp->ssp1601);
 	ssp1601_reset(&svp->ssp1601);
+#ifndef PSP
 	if ((PicoOpt&POPT_EN_SVP_DRC) && svp_dyn_ready)
 	if ((PicoOpt&POPT_EN_SVP_DRC) && svp_dyn_ready)
 		ssp1601_dyn_reset(&svp->ssp1601);
 		ssp1601_dyn_reset(&svp->ssp1601);
+#endif
 }
 }
 
 
 
 
 static void PicoSVPLine(int count)
 static void PicoSVPLine(int count)
 {
 {
+#ifndef PSP
 	if ((PicoOpt&POPT_EN_SVP_DRC) && svp_dyn_ready)
 	if ((PicoOpt&POPT_EN_SVP_DRC) && svp_dyn_ready)
 		ssp1601_dyn_run(PicoSVPCycles * count);
 		ssp1601_dyn_run(PicoSVPCycles * count);
-	else {
+	else
+#endif
+	{
 		ssp1601_run(PicoSVPCycles * count);
 		ssp1601_run(PicoSVPCycles * count);
 		svp_dyn_ready = 0; // just in case
 		svp_dyn_ready = 0; // just in case
 	}
 	}
@@ -126,10 +131,12 @@ void PicoSVPStartup(void)
 
 
 	// init SVP compiler
 	// init SVP compiler
 	svp_dyn_ready = 0;
 	svp_dyn_ready = 0;
+#ifndef PSP
 	if (PicoOpt&POPT_EN_SVP_DRC) {
 	if (PicoOpt&POPT_EN_SVP_DRC) {
 		if (ssp1601_dyn_startup()) return;
 		if (ssp1601_dyn_startup()) return;
 		svp_dyn_ready = 1;
 		svp_dyn_ready = 1;
 	}
 	}
+#endif
 
 
 	// init ok, setup hooks..
 	// init ok, setup hooks..
 	PicoRead16Hook = PicoSVPRead16;
 	PicoRead16Hook = PicoSVPRead16;

+ 15 - 6
platform/base_readme.txt

@@ -636,8 +636,16 @@ Additional thanks
 
 
 Changelog
 Changelog
 ---------
 ---------
+1.40b
+  * Fixed sprite masking code. Thanks to Lordus for explaining how it works.
+  + Added "disable sprite limit" option.
+  + PSP: added black level adjustment to display options.
+  * Changed reset to act as 'soft' reset.
+  + Added detection for Puggsy (it doesn't really have sram).
+  * Some small timing adjustments.
+
 1.40a
 1.40a
-  * Fixed a binding problem with up and down keys.
+  * GP2X: Fixed a binding problem with up and down keys.
   * Default game config no longer overrides global user config.
   * Default game config no longer overrides global user config.
 
 
 1.40
 1.40
@@ -648,16 +656,17 @@ Changelog
     configs are now held in single file (but old game config files are still
     configs are now held in single file (but old game config files are still
     read when new one is missing).
     read when new one is missing).
   * Fixed a bug where some key combos didn't work as expected.
   * Fixed a bug where some key combos didn't work as expected.
-  * Fixed a regression in renderer (some graphic glitches in rare cases).
+  * Fixed a regression in renderer (ARM ports only, some graphic glitches in
+    rare cases).
   * Adjusted fast renderer to work with more games, including VR.
   * Adjusted fast renderer to work with more games, including VR.
   * Fixed a problem where SegaCD RAM cart data was getting lost on reset.
   * Fixed a problem where SegaCD RAM cart data was getting lost on reset.
-  * Greatly reduced SegaCD FMV game slowdowns by disabling read-ahead in the
-    Linux kernel and C library (thanks to Rokas and Exophase for ideas again).
-    Be sure to keep "ReadAhead buffer" OFF to avoid slowdowns.
+  * GP2X: Greatly reduced SegaCD FMV game slowdowns by disabling read-ahead
+    in the Linux kernel and C library (thanks to Rokas and Exophase for ideas
+    again). Be sure to keep "ReadAhead buffer" OFF to avoid slowdowns.
   + PicoDrive now comes with a game config file for some games which need
   + PicoDrive now comes with a game config file for some games which need
     special settings, so they should now work out-of-the-box. More games will
     special settings, so they should now work out-of-the-box. More games will
     be added with later updates.
     be added with later updates.
-  + Files now can be deleted by pressing A+SELECT in the file browser.
+  + GP2X: Files now can be deleted by pressing A+SELECT in the file browser.
 
 
 1.35b
 1.35b
   * PSP: mp3 code should no longer fail on 1.5 firmware.
   * PSP: mp3 code should no longer fail on 1.5 firmware.

+ 131 - 9
platform/common/config.c

@@ -17,9 +17,30 @@ extern menu_entry cdopt_entries[];
 extern const int opt_entry_count;
 extern const int opt_entry_count;
 extern const int opt2_entry_count;
 extern const int opt2_entry_count;
 extern const int cdopt_entry_count;
 extern const int cdopt_entry_count;
+#ifdef PSP
+extern menu_entry opt3_entries[];
+extern const int opt3_entry_count;
+#endif
 
 
-static menu_entry *cfg_opts[] = { opt_entries, opt2_entries, cdopt_entries };
-static const int *cfg_opt_counts[] = { &opt_entry_count, &opt2_entry_count, &cdopt_entry_count };
+static menu_entry *cfg_opts[] =
+{
+	opt_entries,
+	opt2_entries,
+	cdopt_entries,
+#ifdef PSP
+	opt3_entries,
+#endif
+};
+
+static const int *cfg_opt_counts[] =
+{
+	&opt_entry_count,
+	&opt2_entry_count,
+	&cdopt_entry_count,
+#ifdef PSP
+	&opt3_entry_count,
+#endif
+};
 
 
 #define NL "\r\n"
 #define NL "\r\n"
 
 
@@ -73,9 +94,17 @@ static void custom_write(FILE *f, const menu_entry *me, int no_def)
 			if (no_def && !((defaultConfig.s_PicoOpt^PicoOpt)&POPT_ALT_RENDERER) &&
 			if (no_def && !((defaultConfig.s_PicoOpt^PicoOpt)&POPT_ALT_RENDERER) &&
 				!((defaultConfig.EmuOpt^currentConfig.EmuOpt)&0x80)) return;
 				!((defaultConfig.EmuOpt^currentConfig.EmuOpt)&0x80)) return;
 			if (PicoOpt&POPT_ALT_RENDERER)
 			if (PicoOpt&POPT_ALT_RENDERER)
-				str = "8bit fast";
+				str =
+#ifndef PSP
+				"8bit "
+#endif
+				"fast";
 			else if (currentConfig.EmuOpt&0x80)
 			else if (currentConfig.EmuOpt&0x80)
-				str = "16bit accurate";
+				str =
+#ifndef PSP
+				"16bit "
+#endif
+				"accurate";
 			else
 			else
 				str = "8bit accurate";
 				str = "8bit accurate";
 			fprintf(f, "Renderer = %s", str);
 			fprintf(f, "Renderer = %s", str);
@@ -83,13 +112,16 @@ static void custom_write(FILE *f, const menu_entry *me, int no_def)
 
 
 		case MA_OPT_SCALING:
 		case MA_OPT_SCALING:
 			if (no_def && defaultConfig.scaling == currentConfig.scaling) return;
 			if (no_def && defaultConfig.scaling == currentConfig.scaling) return;
+#ifdef __GP2X__
 			switch (currentConfig.scaling) {
 			switch (currentConfig.scaling) {
 				default: str = "OFF"; break;
 				default: str = "OFF"; break;
 				case 1:  str = "hw horizontal";     break;
 				case 1:  str = "hw horizontal";     break;
 				case 2:  str = "hw horiz. + vert."; break;
 				case 2:  str = "hw horiz. + vert."; break;
 				case 3:  str = "sw horizontal";     break;
 				case 3:  str = "sw horizontal";     break;
+				case 1:  str = "ON";  break;
 			}
 			}
 			fprintf(f, "Scaling = %s", str);
 			fprintf(f, "Scaling = %s", str);
+#endif
 			break;
 			break;
 		case MA_OPT_FRAMESKIP:
 		case MA_OPT_FRAMESKIP:
 			if (no_def && defaultConfig.Frameskip == currentConfig.Frameskip) return;
 			if (no_def && defaultConfig.Frameskip == currentConfig.Frameskip) return;
@@ -107,7 +139,8 @@ static void custom_write(FILE *f, const menu_entry *me, int no_def)
 		case MA_OPT_REGION:
 		case MA_OPT_REGION:
 			if (no_def && defaultConfig.s_PicoRegion == PicoRegionOverride &&
 			if (no_def && defaultConfig.s_PicoRegion == PicoRegionOverride &&
 				defaultConfig.s_PicoAutoRgnOrder == PicoAutoRgnOrder) return;
 				defaultConfig.s_PicoAutoRgnOrder == PicoAutoRgnOrder) return;
-			fprintf(f, "Region = %s", me_region_name(PicoRegionOverride, PicoAutoRgnOrder));
+			strncpy(str24, me_region_name(PicoRegionOverride, PicoAutoRgnOrder), 23); str24[23] = 0;
+			fprintf(f, "Region = %s", mystrip(str24));
 			break;
 			break;
 		case MA_OPT_CONFIRM_STATES:
 		case MA_OPT_CONFIRM_STATES:
 			if (no_def && !((defaultConfig.EmuOpt^currentConfig.EmuOpt)&(5<<9))) return;
 			if (no_def && !((defaultConfig.EmuOpt^currentConfig.EmuOpt)&(5<<9))) return;
@@ -121,7 +154,11 @@ static void custom_write(FILE *f, const menu_entry *me, int no_def)
 			break;
 			break;
 		case MA_OPT_CPU_CLOCKS:
 		case MA_OPT_CPU_CLOCKS:
 			if (no_def && defaultConfig.CPUclock == currentConfig.CPUclock) return;
 			if (no_def && defaultConfig.CPUclock == currentConfig.CPUclock) return;
+#ifdef __GP2X__
 			fprintf(f, "GP2X CPU clocks = %i", currentConfig.CPUclock);
 			fprintf(f, "GP2X CPU clocks = %i", currentConfig.CPUclock);
+#elif defined(PSP)
+			fprintf(f, "PSP CPU clock = %i", currentConfig.CPUclock);
+#endif
 			break;
 			break;
 		case MA_OPT2_GAMMA:
 		case MA_OPT2_GAMMA:
 			if (no_def && defaultConfig.gamma == currentConfig.gamma) return;
 			if (no_def && defaultConfig.gamma == currentConfig.gamma) return;
@@ -136,6 +173,38 @@ static void custom_write(FILE *f, const menu_entry *me, int no_def)
 			sprintf(str24, "%i", PicoCDBuffers * 2);
 			sprintf(str24, "%i", PicoCDBuffers * 2);
 			fprintf(f, "ReadAhead buffer = %s", str24);
 			fprintf(f, "ReadAhead buffer = %s", str24);
 			break;
 			break;
+		/* PSP */
+		case MA_OPT3_SCALE:
+			if (no_def && defaultConfig.scale == currentConfig.scale) return;
+			fprintf(f, "Scale factor = %.2f", currentConfig.scale);
+			break;
+		case MA_OPT3_HSCALE32:
+			if (no_def && defaultConfig.hscale32 == currentConfig.hscale32) return;
+			fprintf(f, "Hor. scale (for low res. games) = %.2f", currentConfig.hscale32);
+			break;
+		case MA_OPT3_HSCALE40:
+			if (no_def && defaultConfig.hscale40 == currentConfig.hscale40) return;
+			fprintf(f, "Hor. scale (for hi res. games) = %.2f", currentConfig.hscale40);
+			break;
+		case MA_OPT3_FILTERING:
+			if (no_def && defaultConfig.scaling == currentConfig.scaling) return;
+			fprintf(f, "Bilinear filtering = %i", currentConfig.scaling);
+			break;
+		case MA_OPT3_GAMMAA:
+			if (no_def && defaultConfig.gamma == currentConfig.gamma) return;
+			fprintf(f, "Gamma adjustment = %i", currentConfig.gamma);
+			break;
+		case MA_OPT3_BLACKLVL:
+			if (no_def && defaultConfig.gamma2 == currentConfig.gamma2) return;
+			fprintf(f, "Black level = %i", currentConfig.gamma2);
+			break;
+		case MA_OPT3_VSYNC:
+			if (no_def && (defaultConfig.EmuOpt&0x12000) == (currentConfig.gamma2&0x12000)) return;
+			strcpy(str24, "never");
+			if (currentConfig.EmuOpt & 0x2000)
+				strcpy(str24, (currentConfig.EmuOpt & 0x10000) ? "sometimes" : "always");
+			fprintf(f, "Wait for vsync = %s", str24);
+			break;
 
 
 		default:
 		default:
 			lprintf("unhandled custom_write: %i\n", me->id);
 			lprintf("unhandled custom_write: %i\n", me->id);
@@ -154,7 +223,7 @@ static const char *joyKeyNames[32] =
 };
 };
 
 
 static void keys_write(FILE *fn, const char *bind_str, const int binds[32],
 static void keys_write(FILE *fn, const char *bind_str, const int binds[32],
-		const int def_binds[32], const char *names[32], int no_defaults)
+		const int def_binds[32], const char * const names[32], int no_defaults)
 {
 {
 	int t, i;
 	int t, i;
 	char act[48];
 	char act[48];
@@ -168,6 +237,11 @@ static void keys_write(FILE *fn, const char *bind_str, const int binds[32],
 #ifdef __GP2X__
 #ifdef __GP2X__
 		if (strcmp(names[t], "SELECT") == 0) continue;
 		if (strcmp(names[t], "SELECT") == 0) continue;
 #endif
 #endif
+		if (binds[t] == 0 && def_binds[t] != 0) {
+			fprintf(fn, "%s %s =" NL, bind_str, names[t]); // no binds
+			continue;
+		}
+
 		for (i = 0; i < sizeof(me_ctrl_actions) / sizeof(me_ctrl_actions[0]); i++) {
 		for (i = 0; i < sizeof(me_ctrl_actions) / sizeof(me_ctrl_actions[0]); i++) {
 			if (me_ctrl_actions[i].mask & binds[t]) {
 			if (me_ctrl_actions[i].mask & binds[t]) {
 				strncpy(act, me_ctrl_actions[i].name, 31);
 				strncpy(act, me_ctrl_actions[i].name, 31);
@@ -322,8 +396,10 @@ write:
 	keys_write(fn, "bind_joy2", currentConfig.JoyBinds[2], defaultConfig.JoyBinds[2], joyKeyNames, 1);
 	keys_write(fn, "bind_joy2", currentConfig.JoyBinds[2], defaultConfig.JoyBinds[2], joyKeyNames, 1);
 	keys_write(fn, "bind_joy3", currentConfig.JoyBinds[3], defaultConfig.JoyBinds[3], joyKeyNames, 1);
 	keys_write(fn, "bind_joy3", currentConfig.JoyBinds[3], defaultConfig.JoyBinds[3], joyKeyNames, 1);
 
 
+#ifndef PSP
 	if (section == NULL)
 	if (section == NULL)
 		fprintf(fn, "Sound Volume = %i" NL, currentConfig.volume);
 		fprintf(fn, "Sound Volume = %i" NL, currentConfig.volume);
+#endif
 
 
 	fprintf(fn, NL);
 	fprintf(fn, NL);
 
 
@@ -437,10 +513,10 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
 	{
 	{
 		case MA_OPT_RENDERER:
 		case MA_OPT_RENDERER:
 			if (strcasecmp(var, "Renderer") != 0) return 0;
 			if (strcasecmp(var, "Renderer") != 0) return 0;
-			if      (strcasecmp(val, "8bit fast") == 0) {
+			if      (strcasecmp(val, "8bit fast") == 0 || strcasecmp(val, "fast") == 0) {
 				PicoOpt |=  POPT_ALT_RENDERER;
 				PicoOpt |=  POPT_ALT_RENDERER;
 			}
 			}
-			else if (strcasecmp(val, "16bit accurate") == 0) {
+			else if (strcasecmp(val, "16bit accurate") == 0 || strcasecmp(val, "accurate") == 0) {
 				PicoOpt &= ~POPT_ALT_RENDERER;
 				PicoOpt &= ~POPT_ALT_RENDERER;
 				currentConfig.EmuOpt |=  0x80;
 				currentConfig.EmuOpt |=  0x80;
 			}
 			}
@@ -453,6 +529,7 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
 			return 1;
 			return 1;
 
 
 		case MA_OPT_SCALING:
 		case MA_OPT_SCALING:
+#ifdef __GP2X__
 			if (strcasecmp(var, "Scaling") != 0) return 0;
 			if (strcasecmp(var, "Scaling") != 0) return 0;
 			if        (strcasecmp(val, "OFF") == 0) {
 			if        (strcasecmp(val, "OFF") == 0) {
 				currentConfig.scaling = 0;
 				currentConfig.scaling = 0;
@@ -465,6 +542,9 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
 			} else
 			} else
 				return 0;
 				return 0;
 			return 1;
 			return 1;
+#else
+			return 0;
+#endif
 
 
 		case MA_OPT_FRAMESKIP:
 		case MA_OPT_FRAMESKIP:
 			if (strcasecmp(var, "Frameskip") != 0) return 0;
 			if (strcasecmp(var, "Frameskip") != 0) return 0;
@@ -540,7 +620,11 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
 			return 1;
 			return 1;
 
 
 		case MA_OPT_CPU_CLOCKS:
 		case MA_OPT_CPU_CLOCKS:
+#ifdef __GP2X__
 			if (strcasecmp(var, "GP2X CPU clocks") != 0) return 0;
 			if (strcasecmp(var, "GP2X CPU clocks") != 0) return 0;
+#elif defined(PSP)
+			if (strcasecmp(var, "PSP CPU clock") != 0) return 0;
+#endif
 			currentConfig.CPUclock = atoi(val);
 			currentConfig.CPUclock = atoi(val);
 			return 1;
 			return 1;
 
 
@@ -561,6 +645,44 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
 			PicoCDBuffers = atoi(val) / 2;
 			PicoCDBuffers = atoi(val) / 2;
 			return 1;
 			return 1;
 
 
+		/* PSP */
+		case MA_OPT3_SCALE:
+			if (strcasecmp(var, "Scale factor") != 0) return 0;
+			currentConfig.scale = atof(val);
+			return 1;
+		case MA_OPT3_HSCALE32:
+			if (strcasecmp(var, "Hor. scale (for low res. games)") != 0) return 0;
+			currentConfig.hscale32 = atof(val);
+			return 1;
+		case MA_OPT3_HSCALE40:
+			if (strcasecmp(var, "Hor. scale (for hi res. games)") != 0) return 0;
+			currentConfig.hscale40 = atof(val);
+			return 1;
+		case MA_OPT3_FILTERING:
+			if (strcasecmp(var, "Bilinear filtering") != 0) return 0;
+			currentConfig.scaling = atoi(val);
+			return 1;
+		case MA_OPT3_GAMMAA:
+			if (strcasecmp(var, "Gamma adjustment") != 0) return 0;
+			currentConfig.gamma = atoi(val);
+			return 1;
+		case MA_OPT3_BLACKLVL:
+			if (strcasecmp(var, "Black level") != 0) return 0;
+			currentConfig.gamma2 = atoi(val);
+			return 1;
+		case MA_OPT3_VSYNC:
+			if (strcasecmp(var, "Wait for vsync") != 0) return 0;
+			if        (strcasecmp(val, "never") == 0) {
+				currentConfig.EmuOpt &= ~0x12000;
+			} else if (strcasecmp(val, "sometimes") == 0) {
+				currentConfig.EmuOpt |=  0x12000;
+			} else if (strcasecmp(val, "always") == 0) {
+				currentConfig.EmuOpt &= ~0x12000;
+				currentConfig.EmuOpt |=  0x02000;
+			} else
+				return 0;
+			return 1;
+
 		default:
 		default:
 			lprintf("unhandled custom_read: %i\n", me->id);
 			lprintf("unhandled custom_read: %i\n", me->id);
 			return 0;
 			return 0;
@@ -570,7 +692,7 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
 
 
 static unsigned int keys_encountered = 0;
 static unsigned int keys_encountered = 0;
 
 
-static void keys_parse(const char *var, const char *val, int binds[32], const char *names[32])
+static void keys_parse(const char *var, const char *val, int binds[32], const char * const names[32])
 {
 {
 	int t, i;
 	int t, i;
 	unsigned int player;
 	unsigned int player;

+ 11 - 4
platform/common/emu.c

@@ -572,6 +572,7 @@ int emu_ReadConfig(int game, int no_defaults)
 	if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;
 	if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;
 #ifdef PSP
 #ifdef PSP
 	if (currentConfig.gamma < -4 || currentConfig.gamma >  16) currentConfig.gamma = 0;
 	if (currentConfig.gamma < -4 || currentConfig.gamma >  16) currentConfig.gamma = 0;
+	if (currentConfig.gamma2 < 0 || currentConfig.gamma2 > 2)  currentConfig.gamma2 = 0;
 #else
 #else
 	if (currentConfig.gamma < 10 || currentConfig.gamma > 300) currentConfig.gamma = 100;
 	if (currentConfig.gamma < 10 || currentConfig.gamma > 300) currentConfig.gamma = 100;
 #endif
 #endif
@@ -672,6 +673,12 @@ void emu_textOut16(int x, int y, const char *text)
 	}
 	}
 }
 }
 
 
+#ifdef PSP
+#define MAX_COMBO_KEY 23
+#else
+#define MAX_COMBO_KEY 31
+#endif
+
 void emu_findKeyBindCombos(void)
 void emu_findKeyBindCombos(void)
 {
 {
 	int act, u;
 	int act, u;
@@ -684,15 +691,15 @@ void emu_findKeyBindCombos(void)
 		if (act == 16 || act == 17) continue; // player2 flag
 		if (act == 16 || act == 17) continue; // player2 flag
 		if (act > 17)
 		if (act > 17)
 		{
 		{
-			for (u = 0; u < 32; u++)
+			for (u = 0; u <= MAX_COMBO_KEY; u++)
 				if (currentConfig.KeyBinds[u] & (1 << act)) keyc++;
 				if (currentConfig.KeyBinds[u] & (1 << act)) keyc++;
 		}
 		}
 		else
 		else
 		{
 		{
-			for (u = 0; u < 32; u++)
+			for (u = 0; u <= MAX_COMBO_KEY; u++)
 				if ((currentConfig.KeyBinds[u] & 0x30000) == 0 && // pl. 1
 				if ((currentConfig.KeyBinds[u] & 0x30000) == 0 && // pl. 1
 					(currentConfig.KeyBinds[u] & (1 << act))) keyc++;
 					(currentConfig.KeyBinds[u] & (1 << act))) keyc++;
-			for (u = 0; u < 32; u++)
+			for (u = 0; u <= MAX_COMBO_KEY; u++)
 				if ((currentConfig.KeyBinds[u] & 0x30000) == 1 && // pl. 2
 				if ((currentConfig.KeyBinds[u] & 0x30000) == 1 && // pl. 2
 					(currentConfig.KeyBinds[u] & (1 << act))) keyc2++;
 					(currentConfig.KeyBinds[u] & (1 << act))) keyc2++;
 			if (keyc2 > keyc) keyc = keyc2;
 			if (keyc2 > keyc) keyc = keyc2;
@@ -700,7 +707,7 @@ void emu_findKeyBindCombos(void)
 		if (keyc > 1)
 		if (keyc > 1)
 		{
 		{
 			// loop again and mark those keys and actions as combo
 			// loop again and mark those keys and actions as combo
-			for (u = 0; u < 32; u++)
+			for (u = 0; u <= MAX_COMBO_KEY; u++)
 			{
 			{
 				if (currentConfig.KeyBinds[u] & (1 << act)) {
 				if (currentConfig.KeyBinds[u] & (1 << act)) {
 					kb_combo_keys |= 1 << u;
 					kb_combo_keys |= 1 << u;

+ 2 - 1
platform/common/emu.h

@@ -24,6 +24,7 @@ typedef struct {
 	int scaling; // gp2x: 0=center, 1=hscale, 2=hvscale, 3=hsoftscale; psp: bilinear filtering
 	int scaling; // gp2x: 0=center, 1=hscale, 2=hvscale, 3=hsoftscale; psp: bilinear filtering
 	float scale; // psp: screen scale
 	float scale; // psp: screen scale
 	float hscale32, hscale40; // psp: horizontal scale
 	float hscale32, hscale40; // psp: horizontal scale
+	int gamma2;  // psp: black level
 } currentConfig_t;
 } currentConfig_t;
 
 
 extern currentConfig_t currentConfig, defaultConfig;
 extern currentConfig_t currentConfig, defaultConfig;
@@ -52,5 +53,5 @@ void  emu_textOut16(int x, int y, const char *text);
 char *emu_makeRomId(void);
 char *emu_makeRomId(void);
 void  emu_findKeyBindCombos(void);
 void  emu_findKeyBindCombos(void);
 
 
-extern const char *keyNames[];
+extern const char * const keyNames[];
 void  emu_prepareDefaultConfig(void);
 void  emu_prepareDefaultConfig(void);

+ 1 - 0
platform/common/menu.h

@@ -76,6 +76,7 @@ typedef enum
 	MA_OPT3_FILTERING,
 	MA_OPT3_FILTERING,
 	MA_OPT3_VSYNC,
 	MA_OPT3_VSYNC,
 	MA_OPT3_GAMMAA,
 	MA_OPT3_GAMMAA,
+	MA_OPT3_BLACKLVL,
 	MA_OPT3_DONE,
 	MA_OPT3_DONE,
 	MA_CDOPT_TESTBIOS_USA,
 	MA_CDOPT_TESTBIOS_USA,
 	MA_CDOPT_TESTBIOS_EUR,
 	MA_CDOPT_TESTBIOS_EUR,

+ 2 - 1
platform/gizmondo/menu.c

@@ -969,6 +969,7 @@ static void cd_menu_loop_options(void)
 
 
 menu_entry opt2_entries[] =
 menu_entry opt2_entries[] =
 {
 {
+	{ "Disable sprite limit",      MB_ONOFF, MA_OPT2_NO_SPRITE_LIM, &PicoOpt, 0x40000, 0, 0, 1, 1 },
 	{ "Emulate Z80",               MB_ONOFF, MA_OPT2_ENABLE_Z80,    &currentConfig.PicoOpt,0x0004, 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 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 },
 	{ "Emulate SN76496 (PSG)",     MB_ONOFF, MA_OPT2_ENABLE_SN76496,&currentConfig.PicoOpt,0x0002, 0, 0, 1 },
@@ -1314,7 +1315,7 @@ static void draw_menu_credits(void)
 	int tl_x = 15, tl_y = 64, y;
 	int tl_x = 15, tl_y = 64, y;
 	menu_draw_begin(1);
 	menu_draw_begin(1);
 
 
-	text_out16(tl_x, 20, "PicoDrive v" VERSION " (c) notaz, 2006,2007");
+	text_out16(tl_x, 20, "PicoDrive v" VERSION " (c) notaz, 2006-2008");
 
 
 	y = tl_y;
 	y = tl_y;
 	text_out16(tl_x, y, "Credits:");
 	text_out16(tl_x, y, "Credits:");

+ 6 - 3
platform/psp/Makefile

@@ -27,7 +27,7 @@ endif
 OBJS += main.o emu.o mp3.o menu.o psp.o asm_utils.o
 OBJS += main.o emu.o mp3.o menu.o psp.o asm_utils.o
 
 
 # common
 # common
-OBJS += ../common/emu.o ../common/menu.o ../common/fonts.o ../common/readpng.o
+OBJS += ../common/emu.o ../common/menu.o ../common/fonts.o ../common/config.o ../common/readpng.o
 
 
 # Pico
 # Pico
 ifeq "$(amalgamate)" "1"
 ifeq "$(amalgamate)" "1"
@@ -40,6 +40,9 @@ OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.
 OBJS += ../../Pico/cd/Pico.o ../../Pico/cd/Memory.o ../../Pico/cd/Sek.o ../../Pico/cd/LC89510.o \
 OBJS += ../../Pico/cd/Pico.o ../../Pico/cd/Memory.o ../../Pico/cd/Sek.o ../../Pico/cd/LC89510.o \
 		../../Pico/cd/cd_sys.o ../../Pico/cd/cd_file.o ../../Pico/cd/gfx_cd.o \
 		../../Pico/cd/cd_sys.o ../../Pico/cd/cd_file.o ../../Pico/cd/gfx_cd.o \
 		../../Pico/cd/Area.o ../../Pico/cd/Misc.o ../../Pico/cd/pcm.o ../../Pico/cd/buffering.o
 		../../Pico/cd/Area.o ../../Pico/cd/Misc.o ../../Pico/cd/pcm.o ../../Pico/cd/buffering.o
+# Pico - carthw
+OBJS += ../../Pico/carthw/carthw.o ../../Pico/carthw/svp/svp.o ../../Pico/carthw/svp/Memory.o \
+		../../Pico/carthw/svp/ssp16.o
 endif
 endif
 
 
 # Pico - sound
 # Pico - sound
@@ -170,14 +173,14 @@ endif
 endif
 endif
 
 
 # ?
 # ?
-rel: EBOOT.PBP readme.txt
+rel: EBOOT.PBP readme.txt ../game_def.cfg
 	mkdir -p PicoDrive/skin/
 	mkdir -p PicoDrive/skin/
 	cp $^ PicoDrive/
 	cp $^ PicoDrive/
 	cp skin/* PicoDrive/skin/
 	cp skin/* PicoDrive/skin/
 	zip -9 -r ../../PicoDrive_psp_$(VER).zip PicoDrive
 	zip -9 -r ../../PicoDrive_psp_$(VER).zip PicoDrive
 	rm -rf PicoDrive
 	rm -rf PicoDrive
 
 
-rel_kxploit: readme.txt
+rel_kxploit: readme.txt ../game_def.cfg
 	mkdir -p PicoDrive/skin/
 	mkdir -p PicoDrive/skin/
 	cp $^ PicoDrive/
 	cp $^ PicoDrive/
 	cp skin/* PicoDrive/skin/
 	cp skin/* PicoDrive/skin/

+ 2 - 2
platform/psp/asm_utils.h

@@ -1,2 +1,2 @@
-// pointers must be word aligned
-void do_pal_convert(unsigned short *dest, unsigned short *src, int gammaa_val);
+// pointers must be word aligned, gammaa_val = -4..16, black_lvl = {0,1,2}
+void do_pal_convert(unsigned short *dest, unsigned short *src, int gammaa_val, int black_lvl);

+ 17 - 4
platform/psp/asm_utils.s

@@ -14,7 +14,7 @@
 .byte  0,  2,  7, 12, 16, 21, 26, 31 # -3
 .byte  0,  2,  7, 12, 16, 21, 26, 31 # -3
 .byte  0,  3,  7, 12, 17, 22, 26, 31 # -2
 .byte  0,  3,  7, 12, 17, 22, 26, 31 # -2
 .byte  0,  4,  8, 13, 17, 22, 26, 31 # -1
 .byte  0,  4,  8, 13, 17, 22, 26, 31 # -1
-gmtab:
+pal_gmtab:
 .byte  0,  5, 10, 15, 16, 21, 26, 31 #  0
 .byte  0,  5, 10, 15, 16, 21, 26, 31 #  0
 .byte  0,  6, 10, 15, 19, 23, 27, 31
 .byte  0,  6, 10, 15, 19, 23, 27, 31
 .byte  0,  7, 11, 15, 19, 23, 27, 31
 .byte  0,  7, 11, 15, 19, 23, 27, 31
@@ -38,11 +38,13 @@ gmtab:
 
 
 # bbbb bggg gggr rrrr
 # bbbb bggg gggr rrrr
 
 
-.global do_pal_convert # dest, src, gammaa_val
+#.global pal_gmtab
+.global do_pal_convert # dest, src, gammaa_val, black_lvl
 
 
 do_pal_convert:
 do_pal_convert:
     bnez    $a2, dpc_gma
     bnez    $a2, dpc_gma
     li      $t0, 64/2
     li      $t0, 64/2
+    bnez    $a3, dpc_gma
     lui     $t2, 0x00e
     lui     $t2, 0x00e
     ori     $t2, 0x00e
     ori     $t2, 0x00e
     lui     $t3, 0x006
     lui     $t3, 0x006
@@ -80,11 +82,22 @@ dpc_loop:
     jr      $ra
     jr      $ra
     nop
     nop
 
 
+# non-zero gamma
 dpc_gma:
 dpc_gma:
+    slt     $t2, $a2, $0
     sll     $a2, 3
     sll     $a2, 3
-    lui     $t1, %hi(gmtab)
-    addiu   $t1, %lo(gmtab)
+    lui     $t1, %hi(pal_gmtab)
+    addiu   $t1, %lo(pal_gmtab)
     addu    $a2, $t1
     addu    $a2, $t1
+    beqz    $a3, dpc_gma_loop
+    sb      $0,  0($a2)        # black level 0
+    bnez    $t2, dpc_gma_loop  # gamma < 0, keep black at 0
+    addiu   $a3, -2
+    slt     $t2, $a3, $0       # t2 = a3_orig == 1 ? 1 : 0
+    lb      $t1, 1($a2)
+    addiu   $t1, -2
+    srlv    $t1, $t1, $t2
+    sb      $t1, 0($a2)
 
 
 dpc_gma_loop:
 dpc_gma_loop:
     lw      $v0, 0($a1)
     lw      $v0, 0($a1)

+ 88 - 72
platform/psp/emu.c

@@ -19,6 +19,7 @@
 #include "mp3.h"
 #include "mp3.h"
 #include "asm_utils.h"
 #include "asm_utils.h"
 #include "../common/emu.h"
 #include "../common/emu.h"
+#include "../common/config.h"
 #include "../common/lprintf.h"
 #include "../common/lprintf.h"
 #include "../../Pico/PicoInt.h"
 #include "../../Pico/PicoInt.h"
 
 
@@ -117,38 +118,46 @@ void emu_Deinit(void)
 	sound_deinit();
 	sound_deinit();
 }
 }
 
 
+void emu_prepareDefaultConfig(void)
+{
+	memset(&defaultConfig, 0, sizeof(defaultConfig));
+	defaultConfig.EmuOpt    = 0x1d | 0x680; // | <- confirm_save, cd_leds, acc rend
+	defaultConfig.s_PicoOpt = 0x0f | POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_MCD_GFX;
+	defaultConfig.s_PsndRate = 22050;
+	defaultConfig.s_PicoRegion = 0; // auto
+	defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP
+	defaultConfig.s_PicoCDBuffers = 64;
+	defaultConfig.Frameskip = -1; // auto
+	defaultConfig.CPUclock = 333;
+	defaultConfig.KeyBinds[ 4] = 1<<0; // SACB RLDU
+	defaultConfig.KeyBinds[ 6] = 1<<1;
+	defaultConfig.KeyBinds[ 7] = 1<<2;
+	defaultConfig.KeyBinds[ 5] = 1<<3;
+	defaultConfig.KeyBinds[14] = 1<<4;
+	defaultConfig.KeyBinds[13] = 1<<5;
+	defaultConfig.KeyBinds[15] = 1<<6;
+	defaultConfig.KeyBinds[ 3] = 1<<7;
+	defaultConfig.KeyBinds[12] = 1<<26; // switch rnd
+	defaultConfig.KeyBinds[ 8] = 1<<27; // save state
+	defaultConfig.KeyBinds[ 9] = 1<<28; // load state
+	defaultConfig.KeyBinds[28] = 1<<0; // num "buttons"
+	defaultConfig.KeyBinds[30] = 1<<1;
+	defaultConfig.KeyBinds[31] = 1<<2;
+	defaultConfig.KeyBinds[29] = 1<<3;
+	defaultConfig.scaling = 1;     // bilinear filtering for psp
+	defaultConfig.scale = 1.20;    // fullscreen
+	defaultConfig.hscale40 = 1.25;
+	defaultConfig.hscale32 = 1.56;
+}
+
 void emu_setDefaultConfig(void)
 void emu_setDefaultConfig(void)
 {
 {
-	memset(&currentConfig, 0, sizeof(currentConfig));
-	currentConfig.lastRomFile[0] = 0;
-	currentConfig.EmuOpt  = 0x1d | 0x680;  // | confirm_save, cd_leds, acc rend
-	currentConfig.PicoOpt = 0x0f | 0x1c00; // | gfx_cd, cd_pcm, cd_cdda
-	currentConfig.PsndRate = 22050;
-	currentConfig.PicoRegion = 0; // auto
-	currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP
-	currentConfig.Frameskip = -1; // auto
-	currentConfig.volume = 50;
-	currentConfig.CPUclock = 333;
-	currentConfig.KeyBinds[ 4] = 1<<0; // SACB RLDU
-	currentConfig.KeyBinds[ 6] = 1<<1;
-	currentConfig.KeyBinds[ 7] = 1<<2;
-	currentConfig.KeyBinds[ 5] = 1<<3;
-	currentConfig.KeyBinds[14] = 1<<4;
-	currentConfig.KeyBinds[13] = 1<<5;
-	currentConfig.KeyBinds[15] = 1<<6;
-	currentConfig.KeyBinds[ 3] = 1<<7;
-	currentConfig.KeyBinds[12] = 1<<26; // switch rnd
-	currentConfig.KeyBinds[ 8] = 1<<27; // save state
-	currentConfig.KeyBinds[ 9] = 1<<28; // load state
-	currentConfig.KeyBinds[28] = 1<<0; // num "buttons"
-	currentConfig.KeyBinds[30] = 1<<1;
-	currentConfig.KeyBinds[31] = 1<<2;
-	currentConfig.KeyBinds[29] = 1<<3;
-	currentConfig.PicoCDBuffers = 64;
-	currentConfig.scaling = 1;     // bilinear filtering for psp
-	currentConfig.scale = 1.20;    // fullscreen
-	currentConfig.hscale40 = 1.25;
-	currentConfig.hscale32 = 1.56;
+	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;
 }
 }
 
 
 
 
@@ -233,7 +242,7 @@ static void do_pal_update(int allow_sh)
 
 
 	//for (i = 0x3f/2; i >= 0; i--)
 	//for (i = 0x3f/2; i >= 0; i--)
 	//	dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4);
 	//	dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4);
-	do_pal_convert(localPal, Pico.cram, currentConfig.gamma);
+	do_pal_convert(localPal, Pico.cram, currentConfig.gamma, currentConfig.gamma2);
 
 
 	if (allow_sh && (Pico.video.reg[0xC]&8)) // shadow/hilight?
 	if (allow_sh && (Pico.video.reg[0xC]&8)) // shadow/hilight?
 	{
 	{
@@ -276,7 +285,17 @@ static void EmuScanPrepare(void)
 		do_pal_update(1);
 		do_pal_update(1);
 }
 }
 
 
-static int EmuScanSlow(unsigned int num)
+static int EmuScanSlowBegin(unsigned int num)
+{
+	if (!(Pico.video.reg[1]&8)) num += 8;
+
+	if (!dynamic_palette)
+		HighCol = (unsigned char *)VRAM_CACHED_STUFF + num * 512 + 8;
+
+	return 0;
+}
+
+static int EmuScanSlowEnd(unsigned int num)
 {
 {
 	if (!(Pico.video.reg[1]&8)) num += 8;
 	if (!(Pico.video.reg[1]&8)) num += 8;
 
 
@@ -292,8 +311,7 @@ static int EmuScanSlow(unsigned int num)
 		int line_len = (Pico.video.reg[12]&1) ? 320 : 256;
 		int line_len = (Pico.video.reg[12]&1) ? 320 : 256;
 		void *dst = (char *)VRAM_STUFF + 512*240 + 512*2*num;
 		void *dst = (char *)VRAM_STUFF + 512*240 + 512*2*num;
 		amips_clut(dst, HighCol + 8, localPal, line_len);
 		amips_clut(dst, HighCol + 8, localPal, line_len);
-	} else
-		HighCol = (unsigned char *)VRAM_CACHED_STUFF + (num+1)*512 + 8;
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -467,7 +485,8 @@ static void vidResetMode(void)
 
 
 	// slow rend.
 	// slow rend.
 	PicoDrawSetColorFormat(-1);
 	PicoDrawSetColorFormat(-1);
-	PicoScanEnd = EmuScanSlow;
+	PicoScanBegin = EmuScanSlowBegin;
+	PicoScanEnd = EmuScanSlowEnd;
 
 
 	localPal[0xe0] = 0;
 	localPal[0xe0] = 0;
 	Pico.m.dirtyPal = 1;
 	Pico.m.dirtyPal = 1;
@@ -670,7 +689,8 @@ void emu_forcedFrame(void)
 	memset32_uncached((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
 	memset32_uncached((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
 
 
 	PicoDrawSetColorFormat(-1);
 	PicoDrawSetColorFormat(-1);
-	PicoScanEnd = EmuScanSlow;
+	PicoScanBegin = EmuScanSlowBegin;
+	PicoScanEnd = EmuScanSlowEnd;
 	EmuScanPrepare();
 	EmuScanPrepare();
 	PicoFrameDrawOnly();
 	PicoFrameDrawOnly();
 	blit1();
 	blit1();
@@ -789,21 +809,6 @@ static void updateKeys(void)
 
 
 	events = (allActions[0] | allActions[1]) >> 16;
 	events = (allActions[0] | allActions[1]) >> 16;
 
 
-	// volume is treated in special way and triggered every frame
-	if ((events & 0x6000) && PsndOut != NULL)
-	{
-		int vol = currentConfig.volume;
-		if (events & 0x2000) {
-			if (vol < 100) vol++;
-		} else {
-			if (vol >   0) vol--;
-		}
-		// FrameworkAudio_SetVolume(vol, vol); // TODO
-		sprintf(noticeMsg, "VOL: %02i ", vol);
-		noticeMsgTime = sceKernelGetSystemTimeLow();
-		currentConfig.volume = vol;
-	}
-
 	events &= ~prevEvents;
 	events &= ~prevEvents;
 	if (events) RunEvents(events);
 	if (events) RunEvents(events);
 	if (movie_data) emu_updateMovie();
 	if (movie_data) emu_updateMovie();
@@ -827,9 +832,10 @@ void emu_Loop(void)
 {
 {
 	static int mp3_init_done = 0;
 	static int mp3_init_done = 0;
 	char fpsbuff[24]; // fps count c string
 	char fpsbuff[24]; // fps count c string
-	unsigned int tval, tval_prev = 0, tval_thissec = 0; // timing
-	int frames_done = 0, frames_shown = 0, oldmodes = 0;
-	int target_fps, target_frametime, lim_time, tval_diff, i;
+	unsigned int tval, tval_thissec = 0; // timing
+	int target_fps, target_frametime, lim_time, tval_diff, i, oldmodes = 0;
+	int pframes_done, pframes_shown; // "period" frames, used for sync
+	int  frames_done,  frames_shown, tval_fpsc = 0; // actual frames
 	char *notice = NULL;
 	char *notice = NULL;
 
 
 	lprintf("entered emu_Loop()\n");
 	lprintf("entered emu_Loop()\n");
@@ -874,6 +880,10 @@ void emu_Loop(void)
 	}
 	}
 
 
 	sceDisplayWaitVblankStart();
 	sceDisplayWaitVblankStart();
+	pframes_shown = pframes_done =
+	 frames_shown =  frames_done = 0;
+
+	tval_fpsc = sceKernelGetSystemTimeLow();
 
 
 	// loop?
 	// loop?
 	while (engineState == PGS_Running)
 	while (engineState == PGS_Running)
@@ -881,11 +891,11 @@ void emu_Loop(void)
 		int modes;
 		int modes;
 
 
 		tval = sceKernelGetSystemTimeLow();
 		tval = sceKernelGetSystemTimeLow();
-		if (reset_timing || tval < tval_prev) {
+		if (reset_timing || tval < tval_fpsc) {
 			//stdbg("timing reset");
 			//stdbg("timing reset");
 			reset_timing = 0;
 			reset_timing = 0;
 			tval_thissec = tval;
 			tval_thissec = tval;
-			frames_shown = frames_done = 0;
+			pframes_shown = pframes_done = 0;
 		}
 		}
 
 
 		// show notice message?
 		// show notice message?
@@ -911,37 +921,41 @@ void emu_Loop(void)
 		}
 		}
 
 
 		// second passed?
 		// second passed?
+		if (tval - tval_fpsc >= 1000000)
+		{
+			if (currentConfig.EmuOpt & 2)
+				sprintf(fpsbuff, "%02i/%02i  ", frames_shown, frames_done);
+			frames_done = frames_shown = 0;
+			tval_fpsc += 1000000;
+		}
+
 		if (tval - tval_thissec >= 1000000)
 		if (tval - tval_thissec >= 1000000)
 		{
 		{
 			// missing 1 frame?
 			// missing 1 frame?
-			if (currentConfig.Frameskip < 0 && frames_done < target_fps) {
-				SkipFrame(); frames_done++;
+			if (currentConfig.Frameskip < 0 && pframes_done < target_fps) {
+				SkipFrame(); pframes_done++; frames_done++;
 			}
 			}
 
 
-			if (currentConfig.EmuOpt & 2)
-				sprintf(fpsbuff, "%02i/%02i  ", frames_shown, frames_done);
-
 			tval_thissec += 1000000;
 			tval_thissec += 1000000;
 
 
 			if (currentConfig.Frameskip < 0) {
 			if (currentConfig.Frameskip < 0) {
-				frames_done  -= target_fps; if (frames_done  < 0) frames_done  = 0;
-				frames_shown -= target_fps; if (frames_shown < 0) frames_shown = 0;
-				if (frames_shown > frames_done) frames_shown = frames_done;
+				pframes_done  -= target_fps; if (pframes_done  < 0) pframes_done  = 0;
+				pframes_shown -= target_fps; if (pframes_shown < 0) pframes_shown = 0;
+				if (pframes_shown > pframes_done) pframes_shown = pframes_done;
 			} else {
 			} else {
-				frames_done = frames_shown = 0;
+				pframes_done = pframes_shown = 0;
 			}
 			}
 		}
 		}
 #ifdef PFRAMES
 #ifdef PFRAMES
 		sprintf(fpsbuff, "%i", Pico.m.frame_count);
 		sprintf(fpsbuff, "%i", Pico.m.frame_count);
 #endif
 #endif
 
 
-		tval_prev = tval;
-		lim_time = (frames_done+1) * target_frametime;
+		lim_time = (pframes_done+1) * target_frametime;
 		if (currentConfig.Frameskip >= 0) // frameskip enabled
 		if (currentConfig.Frameskip >= 0) // frameskip enabled
 		{
 		{
 			for (i = 0; i < currentConfig.Frameskip; i++) {
 			for (i = 0; i < currentConfig.Frameskip; i++) {
 				updateKeys();
 				updateKeys();
-				SkipFrame(); frames_done++;
+				SkipFrame(); pframes_done++; frames_done++;
 				if (!(currentConfig.EmuOpt&0x40000)) { // do framelimitting if needed
 				if (!(currentConfig.EmuOpt&0x40000)) { // do framelimitting if needed
 					int tval_diff;
 					int tval_diff;
 					tval = sceKernelGetSystemTimeLow();
 					tval = sceKernelGetSystemTimeLow();
@@ -957,7 +971,7 @@ void emu_Loop(void)
 			int tval_diff;
 			int tval_diff;
 			tval = sceKernelGetSystemTimeLow();
 			tval = sceKernelGetSystemTimeLow();
 			tval_diff = (int)(tval - tval_thissec) << 8;
 			tval_diff = (int)(tval - tval_thissec) << 8;
-			if (tval_diff > lim_time && (frames_done/16 < frames_shown))
+			if (tval_diff > lim_time && (pframes_done/16 < pframes_shown))
 			{
 			{
 				// no time left for this frame - skip
 				// no time left for this frame - skip
 				if (tval_diff - lim_time >= (300000<<8)) {
 				if (tval_diff - lim_time >= (300000<<8)) {
@@ -965,7 +979,7 @@ void emu_Loop(void)
 					continue;
 					continue;
 				}
 				}
 				updateKeys();
 				updateKeys();
-				SkipFrame(); frames_done++;
+				SkipFrame(); pframes_done++; frames_done++;
 				continue;
 				continue;
 			}
 			}
 		}
 		}
@@ -985,8 +999,9 @@ void emu_Loop(void)
 
 
 		blit2(fpsbuff, notice, tval_diff > lim_time);
 		blit2(fpsbuff, notice, tval_diff > lim_time);
 
 
-		if (currentConfig.Frameskip < 0 && tval_diff - lim_time >= (300000<<8)) // slowdown detection
+		if (currentConfig.Frameskip < 0 && tval_diff - lim_time >= (300000<<8)) { // slowdown detection
 			reset_timing = 1;
 			reset_timing = 1;
+		}
 		else if (!(currentConfig.EmuOpt&0x40000) || currentConfig.Frameskip < 0)
 		else if (!(currentConfig.EmuOpt&0x40000) || currentConfig.Frameskip < 0)
 		{
 		{
 			// sleep if we are still too fast
 			// sleep if we are still too fast
@@ -997,7 +1012,8 @@ void emu_Loop(void)
 			}
 			}
 		}
 		}
 
 
-		frames_done++; frames_shown++;
+		pframes_done++; pframes_shown++;
+		 frames_done++;  frames_shown++;
 	}
 	}
 
 
 
 

+ 2 - 1
platform/psp/main.c

@@ -33,6 +33,7 @@ int pico_main(void)
 {
 {
 	lprintf("\nPicoDrive v" VERSION " " __DATE__ " " __TIME__ "\n");
 	lprintf("\nPicoDrive v" VERSION " " __DATE__ " " __TIME__ "\n");
 	psp_init();
 	psp_init();
+	emu_prepareDefaultConfig();
 	emu_ReadConfig(0, 0);
 	emu_ReadConfig(0, 0);
 	emu_Init();
 	emu_Init();
 	menu_init();
 	menu_init();
@@ -49,7 +50,7 @@ int pico_main(void)
 #ifndef GPROF
 #ifndef GPROF
 				menu_loop();
 				menu_loop();
 #else
 #else
-				strcpy(romFileName, currentConfig.lastRomFile);
+				strcpy(romFileName, lastRomFile);
 				engineState = PGS_ReloadRom;
 				engineState = PGS_ReloadRom;
 #endif
 #endif
 				break;
 				break;

+ 81 - 75
platform/psp/menu.c

@@ -33,7 +33,7 @@
 
 
 
 
 #define pspKeyUnkn "???"
 #define pspKeyUnkn "???"
-static const char * const pspKeyNames[] = {
+const char * const keyNames[] = {
 	"SELECT",   pspKeyUnkn, pspKeyUnkn, "START",    "UP",       "RIGHT",     "DOWN",     "LEFT",
 	"SELECT",   pspKeyUnkn, pspKeyUnkn, "START",    "UP",       "RIGHT",     "DOWN",     "LEFT",
 	"L",        "R",        pspKeyUnkn, pspKeyUnkn, "TRIANGLE", "CIRCLE",    "X",        "SQUARE",
 	"L",        "R",        pspKeyUnkn, pspKeyUnkn, "TRIANGLE", "CIRCLE",    "X",        "SQUARE",
 	"HOME",     "HOLD",     "WLAN_UP",  "REMOTE",   "VOLUP",    "VOLDOWN",   "SCREEN",   "NOTE",
 	"HOME",     "HOLD",     "WLAN_UP",  "REMOTE",   "VOLUP",    "VOLDOWN",   "SCREEN",   "NOTE",
@@ -668,10 +668,10 @@ static char *action_binds(int player_idx, int action_mask)
 			if (player_idx >= 0 && ((currentConfig.KeyBinds[i] >> 16) & 3) != player_idx) continue;
 			if (player_idx >= 0 && ((currentConfig.KeyBinds[i] >> 16) & 3) != player_idx) continue;
 			if (strkeys[0]) {
 			if (strkeys[0]) {
 				strcat(strkeys, i >= 28 ? ", " : " + "); // nub "buttons" don't create combos
 				strcat(strkeys, i >= 28 ? ", " : " + "); // nub "buttons" don't create combos
-				strcat(strkeys, pspKeyNames[i]);
+				strcat(strkeys, keyNames[i]);
 				break;
 				break;
 			}
 			}
-			else strcpy(strkeys, pspKeyNames[i]);
+			else strcpy(strkeys, keyNames[i]);
 		}
 		}
 	}
 	}
 
 
@@ -699,7 +699,7 @@ static int count_bound_keys(int action, int pl_idx)
 	return keys;
 	return keys;
 }
 }
 
 
-static void draw_key_config(const bind_action_t *opts, int opt_cnt, int player_idx, int sel)
+static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_idx, int sel)
 {
 {
 	int x, y, tl_y = 16+40, i;
 	int x, y, tl_y = 16+40, i;
 
 
@@ -733,7 +733,7 @@ static void draw_key_config(const bind_action_t *opts, int opt_cnt, int player_i
 	menu_draw_end();
 	menu_draw_end();
 }
 }
 
 
-static void key_config_loop(const bind_action_t *opts, int opt_cnt, int player_idx)
+static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_idx)
 {
 {
 	int sel = 0, menu_sel_max = opt_cnt, prev_select = 0, i;
 	int sel = 0, menu_sel_max = opt_cnt, prev_select = 0, i;
 	unsigned long inp = 0;
 	unsigned long inp = 0;
@@ -804,7 +804,7 @@ static void kc_sel_loop(void)
 {
 {
 	int menu_sel = 3, menu_sel_max = 3;
 	int menu_sel = 3, menu_sel_max = 3;
 	unsigned long inp = 0;
 	unsigned long inp = 0;
-	int is_6button = currentConfig.PicoOpt & 0x020;
+	int is_6button = PicoOpt & POPT_6BTN_PAD;
 
 
 	while (1)
 	while (1)
 	{
 	{
@@ -831,20 +831,21 @@ static void kc_sel_loop(void)
 
 
 menu_entry cdopt_entries[] =
 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 },
 };
 };
 
 
 #define CDOPT_ENTRY_COUNT (sizeof(cdopt_entries) / sizeof(cdopt_entries[0]))
 #define CDOPT_ENTRY_COUNT (sizeof(cdopt_entries) / sizeof(cdopt_entries[0]))
+const int cdopt_entry_count = CDOPT_ENTRY_COUNT;
 
 
 
 
 struct bios_names_t
 struct bios_names_t
@@ -984,19 +985,21 @@ static void cd_menu_loop_options(void)
 
 
 menu_entry opt3_entries[] =
 menu_entry opt3_entries[] =
 {
 {
-	{ NULL,                        MB_NONE,  MA_OPT3_SCALE,         NULL, 0, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT3_HSCALE32,      NULL, 0, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT3_HSCALE40,      NULL, 0, 0, 0, 1 },
-	{ NULL,                        MB_ONOFF, MA_OPT3_FILTERING,     &currentConfig.scaling, 1,  0,  0, 1 },
-	{ NULL,                        MB_RANGE, MA_OPT3_GAMMAA,        &currentConfig.gamma,   0, -4, 16, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT3_VSYNC,         NULL, 0, 0, 0, 1 },
-	{ "Set to unscaled centered",  MB_NONE,  MA_OPT3_PRES_NOSCALE,  NULL, 0, 0, 0, 1 },
-	{ "Set to 4:3 scaled",         MB_NONE,  MA_OPT3_PRES_SCALE43,  NULL, 0, 0, 0, 1 },
-	{ "Set to fullscreen",         MB_NONE,  MA_OPT3_PRES_FULLSCR,  NULL, 0, 0, 0, 1 },
-	{ "done",                      MB_NONE,  MA_OPT3_DONE,          NULL, 0, 0, 0, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT3_SCALE,         NULL, 0, 0, 0, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT3_HSCALE32,      NULL, 0, 0, 0, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT3_HSCALE40,      NULL, 0, 0, 0, 1, 1 },
+	{ NULL,                        MB_ONOFF, MA_OPT3_FILTERING,     &currentConfig.scaling, 1,  0,  0, 1, 1 },
+	{ NULL,                        MB_RANGE, MA_OPT3_GAMMAA,        &currentConfig.gamma,   0, -4, 16, 1, 1 },
+	{ NULL,                        MB_RANGE, MA_OPT3_BLACKLVL,      &currentConfig.gamma2,  0,  0,  2, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT3_VSYNC,         NULL, 0, 0, 0, 1, 1 },
+	{ "Set to unscaled centered",  MB_NONE,  MA_OPT3_PRES_NOSCALE,  NULL, 0, 0, 0, 1, 0 },
+	{ "Set to 4:3 scaled",         MB_NONE,  MA_OPT3_PRES_SCALE43,  NULL, 0, 0, 0, 1, 0 },
+	{ "Set to fullscreen",         MB_NONE,  MA_OPT3_PRES_FULLSCR,  NULL, 0, 0, 0, 1, 0 },
+	{ "done",                      MB_NONE,  MA_OPT3_DONE,          NULL, 0, 0, 0, 1, 0 },
 };
 };
 
 
 #define OPT3_ENTRY_COUNT (sizeof(opt3_entries) / sizeof(opt3_entries[0]))
 #define OPT3_ENTRY_COUNT (sizeof(opt3_entries) / sizeof(opt3_entries[0]))
+const int opt3_entry_count = OPT3_ENTRY_COUNT;
 
 
 
 
 static void menu_opt3_cust_draw(const menu_entry *entry, int x, int y, void *param)
 static void menu_opt3_cust_draw(const menu_entry *entry, int x, int y, void *param)
@@ -1018,6 +1021,9 @@ static void menu_opt3_cust_draw(const menu_entry *entry, int x, int y, void *par
 		case MA_OPT3_GAMMAA:
 		case MA_OPT3_GAMMAA:
 			text_out16(x, y, "Gamma adjustment                  %2i", currentConfig.gamma);
 			text_out16(x, y, "Gamma adjustment                  %2i", currentConfig.gamma);
 			break;
 			break;
+		case MA_OPT3_BLACKLVL:
+			text_out16(x, y, "Black level                       %2i", currentConfig.gamma2);
+			break;
 		case MA_OPT3_VSYNC: {
 		case MA_OPT3_VSYNC: {
 			char *val = "    never";
 			char *val = "    never";
 			if (currentConfig.EmuOpt & 0x2000)
 			if (currentConfig.EmuOpt & 0x2000)
@@ -1102,8 +1108,10 @@ static void dispmenu_loop_options(void)
 				case MA_OPT3_HSCALE40:	setting = &currentConfig.hscale40; is_32col = 0; break;
 				case MA_OPT3_HSCALE40:	setting = &currentConfig.hscale40; is_32col = 0; break;
 				case MA_OPT3_HSCALE32:	setting = &currentConfig.hscale32; is_32col = 1; break;
 				case MA_OPT3_HSCALE32:	setting = &currentConfig.hscale32; is_32col = 1; break;
 				case MA_OPT3_FILTERING:
 				case MA_OPT3_FILTERING:
-				case MA_OPT3_GAMMAA:	menu_opt3_preview(is_32col); break;
-				case MA_OPT3_VSYNC:    tmp = ((currentConfig.EmuOpt>>13)&1) | ((currentConfig.EmuOpt>>15)&2);
+				case MA_OPT3_GAMMAA:
+				case MA_OPT3_BLACKLVL:	menu_opt3_preview(is_32col); break;
+				case MA_OPT3_VSYNC:
+					tmp = ((currentConfig.EmuOpt>>13)&1) | ((currentConfig.EmuOpt>>15)&2);
 					tmp = (inp & BTN_LEFT) ? (tmp>>1) : ((tmp<<1)|1);
 					tmp = (inp & BTN_LEFT) ? (tmp>>1) : ((tmp<<1)|1);
 					if (tmp > 3) tmp = 3;
 					if (tmp > 3) tmp = 3;
 					currentConfig.EmuOpt &= ~0x12000;
 					currentConfig.EmuOpt &= ~0x12000;
@@ -1156,17 +1164,19 @@ static void dispmenu_loop_options(void)
 
 
 menu_entry opt2_entries[] =
 menu_entry opt2_entries[] =
 {
 {
-	{ "Emulate Z80",               MB_ONOFF, MA_OPT2_ENABLE_Z80,     &currentConfig.PicoOpt,0x00004, 0, 0, 1 },
-	{ "Emulate YM2612 (FM)",       MB_ONOFF, MA_OPT2_ENABLE_YM2612,  &currentConfig.PicoOpt,0x00001, 0, 0, 1 },
-	{ "Emulate SN76496 (PSG)",     MB_ONOFF, MA_OPT2_ENABLE_SN76496, &currentConfig.PicoOpt,0x00002, 0, 0, 1 },
-	{ "gzip savestates",           MB_ONOFF, MA_OPT2_GZIP_STATES,    &currentConfig.EmuOpt, 0x00008, 0, 0, 1 },
-	{ "Don't save last used ROM",  MB_ONOFF, MA_OPT2_NO_LAST_ROM,    &currentConfig.EmuOpt, 0x00020, 0, 0, 1 },
-	{ "Status line in main menu",  MB_ONOFF, MA_OPT2_STATUS_LINE,    &currentConfig.EmuOpt, 0x20000, 0, 0, 1 },
-	{ "Disable frame limitter",    MB_ONOFF, MA_OPT2_NO_FRAME_LIMIT, &currentConfig.EmuOpt, 0x40000, 0, 0, 1 },
-	{ "done",                      MB_NONE,  MA_OPT2_DONE,           NULL, 0, 0, 0, 1 },
+	{ "Disable sprite limit",      MB_ONOFF, MA_OPT2_NO_SPRITE_LIM,  &PicoOpt, 0x40000, 0, 0, 1, 1 },
+	{ "Emulate Z80",               MB_ONOFF, MA_OPT2_ENABLE_Z80,     &PicoOpt, 0x00004, 0, 0, 1, 1 },
+	{ "Emulate YM2612 (FM)",       MB_ONOFF, MA_OPT2_ENABLE_YM2612,  &PicoOpt, 0x00001, 0, 0, 1, 1 },
+	{ "Emulate SN76496 (PSG)",     MB_ONOFF, MA_OPT2_ENABLE_SN76496, &PicoOpt, 0x00002, 0, 0, 1, 1 },
+	{ "gzip savestates",           MB_ONOFF, MA_OPT2_GZIP_STATES,    &currentConfig.EmuOpt, 0x00008, 0, 0, 1, 1 },
+	{ "Don't save last used ROM",  MB_ONOFF, MA_OPT2_NO_LAST_ROM,    &currentConfig.EmuOpt, 0x00020, 0, 0, 1, 1 },
+	{ "Status line in main menu",  MB_ONOFF, MA_OPT2_STATUS_LINE,    &currentConfig.EmuOpt, 0x20000, 0, 0, 1, 1 },
+	{ "Disable frame limitter",    MB_ONOFF, MA_OPT2_NO_FRAME_LIMIT, &currentConfig.EmuOpt, 0x40000, 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]))
 #define OPT2_ENTRY_COUNT (sizeof(opt2_entries) / sizeof(opt2_entries[0]))
+const int opt2_entry_count = OPT2_ENTRY_COUNT;
 
 
 
 
 static void draw_amenu_options(int menu_sel)
 static void draw_amenu_options(int menu_sel)
@@ -1219,28 +1229,29 @@ static void amenu_loop_options(void)
 
 
 menu_entry opt_entries[] =
 menu_entry opt_entries[] =
 {
 {
-	{ NULL,                        MB_NONE,  MA_OPT_RENDERER,      NULL, 0, 0, 0, 1 },
-	{ "Accurate timing (slower)",  MB_ONOFF, MA_OPT_ACC_TIMING,    &currentConfig.PicoOpt, 0x0040, 0, 0, 1 },
-	{ "Accurate sprites (slower)", MB_ONOFF, MA_OPT_ACC_SPRITES,   &currentConfig.PicoOpt, 0x0080, 0, 0, 1 },
-	{ "Show FPS",                  MB_ONOFF, MA_OPT_SHOW_FPS,      &currentConfig.EmuOpt,  0x0002, 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,  0x0004, 0, 0, 1 },
-	{ NULL,                        MB_NONE,  MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1 },
-	{ "6 button pad",              MB_ONOFF, MA_OPT_6BUTTON_PAD,   &currentConfig.PicoOpt, 0x0020, 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,  0x0001, 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 },
-	{ "[Display options]",         MB_NONE,  MA_OPT_DISP_OPTS,     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 },
+	{ "Accurate timing (slower)",  MB_ONOFF, MA_OPT_ACC_TIMING,    &PicoOpt, 0x0040, 0, 0, 1, 1 },
+	{ "Accurate sprites (slower)", MB_ONOFF, MA_OPT_ACC_SPRITES,   &PicoOpt, 0x0080, 0, 0, 1, 1 },
+	{ "Show FPS",                  MB_ONOFF, MA_OPT_SHOW_FPS,      &currentConfig.EmuOpt,  0x0002,  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,  0x0004,  0,  0, 1, 1 },
+	{ NULL,                        MB_NONE,  MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1, 1 },
+	{ "6 button pad",              MB_ONOFF, MA_OPT_6BUTTON_PAD,   &PicoOpt, 0x0020, 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,  0x0001, 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 },
+	{ "[Display options]",         MB_NONE,  MA_OPT_DISP_OPTS,     NULL, 0, 0, 0, 1, 0 },
+	{ "[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]))
 #define OPT_ENTRY_COUNT (sizeof(opt_entries) / sizeof(opt_entries[0]))
+const int opt_entry_count = OPT_ENTRY_COUNT;
 
 
 
 
 static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *param)
 static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *param)
@@ -1250,9 +1261,9 @@ static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *para
 	switch (entry->id)
 	switch (entry->id)
 	{
 	{
 		case MA_OPT_RENDERER:
 		case MA_OPT_RENDERER:
-			if (currentConfig.PicoOpt&0x10)
+			if (PicoOpt & 0x10)
 				str = "fast";
 				str = "fast";
-			else if (currentConfig.EmuOpt&0x80)
+			else if (currentConfig.EmuOpt & 0x80)
 				str = "accurate";
 				str = "accurate";
 			else
 			else
 				str = " 8bit accurate"; // n/a
 				str = " 8bit accurate"; // n/a
@@ -1265,8 +1276,8 @@ static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *para
 			text_out16(x, y, "Frameskip                  %s", str24);
 			text_out16(x, y, "Frameskip                  %s", str24);
 			break;
 			break;
 		case MA_OPT_SOUND_QUALITY:
 		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;
 			break;
 		case MA_OPT_REGION:
 		case MA_OPT_REGION:
 			text_out16(x, y, "Region:              %s", me_region_name(PicoRegionOverride, PicoAutoRgnOrder));
 			text_out16(x, y, "Region:              %s", me_region_name(PicoRegionOverride, PicoAutoRgnOrder));
@@ -1350,13 +1361,11 @@ static void region_prevnext(int right)
 
 
 static void menu_options_save(void)
 static void menu_options_save(void)
 {
 {
-	PicoOpt = currentConfig.PicoOpt;
-	PsndRate = currentConfig.PsndRate;
 	if (PicoRegionOverride) {
 	if (PicoRegionOverride) {
 		// force setting possibly changed..
 		// force setting possibly changed..
 		Pico.m.pal = (PicoRegionOverride == 2 || PicoRegionOverride == 8) ? 1 : 0;
 		Pico.m.pal = (PicoRegionOverride == 2 || PicoRegionOverride == 8) ? 1 : 0;
 	}
 	}
-	if (!(PicoOpt & 0x20)) {
+	if (!(PicoOpt & POPT_6BTN_PAD)) {
 		// unbind XYZ MODE, just in case
 		// unbind XYZ MODE, just in case
 		unbind_action(0xf00);
 		unbind_action(0xf00);
 	}
 	}
@@ -1369,9 +1378,6 @@ static int menu_loop_options(void)
 	unsigned long inp = 0;
 	unsigned long inp = 0;
 	menu_id selected_id;
 	menu_id selected_id;
 
 
-	currentConfig.PicoOpt = PicoOpt;
-	currentConfig.PsndRate = PsndRate;
-
 	me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_SAVECFG_GAME, rom_loaded);
 	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);
 	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;
 	menu_sel_max = me_count_enabled(opt_entries, OPT_ENTRY_COUNT) - 1;
@@ -1388,16 +1394,16 @@ static int menu_loop_options(void)
 			if (!me_process(opt_entries, OPT_ENTRY_COUNT, selected_id, (inp&BTN_RIGHT) ? 1 : 0)) {
 			if (!me_process(opt_entries, OPT_ENTRY_COUNT, selected_id, (inp&BTN_RIGHT) ? 1 : 0)) {
 				switch (selected_id) {
 				switch (selected_id) {
 					case MA_OPT_RENDERER:
 					case MA_OPT_RENDERER:
-						if ((currentConfig.PicoOpt&0x10) || !(currentConfig.EmuOpt &0x80)) {
-							currentConfig.PicoOpt&= ~0x10;
+						if ((PicoOpt & 0x10) || !(currentConfig.EmuOpt & 0x80)) {
+							PicoOpt &= ~0x10;
 							currentConfig.EmuOpt |=  0x80;
 							currentConfig.EmuOpt |=  0x80;
 						} else {
 						} else {
-							currentConfig.PicoOpt|=  0x10;
+							PicoOpt |=  0x10;
 							currentConfig.EmuOpt &= ~0x80;
 							currentConfig.EmuOpt &= ~0x80;
 						}
 						}
 						break;
 						break;
 					case MA_OPT_SOUND_QUALITY:
 					case MA_OPT_SOUND_QUALITY:
-						currentConfig.PsndRate = sndrate_prevnext(currentConfig.PsndRate, inp & BTN_RIGHT);
+						PsndRate = sndrate_prevnext(PsndRate, inp & BTN_RIGHT);
 						break;
 						break;
 					case MA_OPT_REGION:
 					case MA_OPT_REGION:
 						region_prevnext(inp & BTN_RIGHT);
 						region_prevnext(inp & BTN_RIGHT);
@@ -1493,7 +1499,7 @@ static void draw_menu_credits(void)
 	int tl_x = 80+15, tl_y = 16+64, y;
 	int tl_x = 80+15, tl_y = 16+64, y;
 	menu_draw_begin();
 	menu_draw_begin();
 
 
-	text_out16(tl_x, 16+20, "PicoDrive v" VERSION " (c) notaz, 2006,2007");
+	text_out16(tl_x, 16+20, "PicoDrive v" VERSION " (c) notaz, 2006-2008");
 
 
 	y = tl_y;
 	y = tl_y;
 	text_out16(tl_x, y, "Credits:");
 	text_out16(tl_x, y, "Credits:");
@@ -1633,10 +1639,10 @@ static void menu_loop_root(void)
 				{
 				{
 					char curr_path[PATH_MAX], *selfname;
 					char curr_path[PATH_MAX], *selfname;
 					FILE *tstf;
 					FILE *tstf;
-					if ( (tstf = fopen(currentConfig.lastRomFile, "rb")) )
+					if ( (tstf = fopen(lastRomFile, "rb")) )
 					{
 					{
 						fclose(tstf);
 						fclose(tstf);
-						strcpy(curr_path, currentConfig.lastRomFile);
+						strcpy(curr_path, lastRomFile);
 					}
 					}
 					else
 					else
 						getcwd(curr_path, PATH_MAX);
 						getcwd(curr_path, PATH_MAX);
@@ -1779,10 +1785,10 @@ int menu_loop_tray(void)
 
 
 	menu_gfx_prepare();
 	menu_gfx_prepare();
 
 
-	if ( (tstf = fopen(currentConfig.lastRomFile, "rb")) )
+	if ( (tstf = fopen(lastRomFile, "rb")) )
 	{
 	{
 		fclose(tstf);
 		fclose(tstf);
-		strcpy(curr_path, currentConfig.lastRomFile);
+		strcpy(curr_path, lastRomFile);
 	}
 	}
 	else
 	else
 	{
 	{

+ 1 - 1
platform/psp/version.h

@@ -1,2 +1,2 @@
-#define VERSION "1.40"
+#define VERSION "1.40b"