psp code updated for latest base, black level

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@415 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-04-05 19:51:49 +00:00
parent 6c25471008
commit 6fc5714482
14 changed files with 367 additions and 180 deletions

View file

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

View file

@ -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 * GP2X: Greatly reduced SegaCD FMV game slowdowns by disabling read-ahead
Linux kernel and C library (thanks to Rokas and Exophase for ideas again). in the Linux kernel and C library (thanks to Rokas and Exophase for ideas
Be sure to keep "ReadAhead buffer" OFF to avoid slowdowns. 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.

View file

@ -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 menu_entry *cfg_opts[] =
static const int *cfg_opt_counts[] = { &opt_entry_count, &opt2_entry_count, &cdopt_entry_count }; {
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;

View file

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

View file

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

View file

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

View file

@ -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:");

View file

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

View file

@ -1,2 +1,2 @@
// pointers must be word aligned // 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); void do_pal_convert(unsigned short *dest, unsigned short *src, int gammaa_val, int black_lvl);

View file

@ -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) lui $t1, %hi(pal_gmtab)
addiu $t1, %lo(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)

View file

@ -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)); memcpy(&currentConfig, &defaultConfig, sizeof(currentConfig));
currentConfig.lastRomFile[0] = 0; PicoOpt = currentConfig.s_PicoOpt;
currentConfig.EmuOpt = 0x1d | 0x680; // | confirm_save, cd_leds, acc rend PsndRate = currentConfig.s_PsndRate;
currentConfig.PicoOpt = 0x0f | 0x1c00; // | gfx_cd, cd_pcm, cd_cdda PicoRegionOverride = currentConfig.s_PicoRegion;
currentConfig.PsndRate = 22050; PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder;
currentConfig.PicoRegion = 0; // auto PicoCDBuffers = currentConfig.s_PicoCDBuffers;
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;
} }
@ -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 unsigned int tval, tval_thissec = 0; // timing
int frames_done = 0, frames_shown = 0, oldmodes = 0; int target_fps, target_frametime, lim_time, tval_diff, i, oldmodes = 0;
int target_fps, target_frametime, lim_time, tval_diff, i; 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) { if (currentConfig.Frameskip < 0 && pframes_done < target_fps) {
SkipFrame(); frames_done++; 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; pframes_done -= target_fps; if (pframes_done < 0) pframes_done = 0;
frames_shown -= target_fps; if (frames_shown < 0) frames_shown = 0; pframes_shown -= target_fps; if (pframes_shown < 0) pframes_shown = 0;
if (frames_shown > frames_done) frames_shown = frames_done; 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 = (pframes_done+1) * target_frametime;
lim_time = (frames_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++;
} }

View file

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

View file

@ -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_USA, NULL, 0, 0, 0, 1, 0 },
{ NULL, MB_NONE, MA_CDOPT_TESTBIOS_EUR, NULL, 0, 0, 0, 1 }, { 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 }, { 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 }, { "CD LEDs", MB_ONOFF, MA_CDOPT_LEDS, &currentConfig.EmuOpt, 0x0400, 0, 0, 1, 1 },
{ "CDDA audio (using mp3s)", MB_ONOFF, MA_CDOPT_CDDA, &currentConfig.PicoOpt, 0x0800, 0, 0, 1 }, { "CDDA audio (using mp3s)", MB_ONOFF, MA_CDOPT_CDDA, &PicoOpt, 0x0800, 0, 0, 1, 1 },
{ "PCM audio", MB_ONOFF, MA_CDOPT_PCM, &currentConfig.PicoOpt, 0x0400, 0, 0, 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 }, { NULL, MB_NONE, MA_CDOPT_READAHEAD, NULL, 0, 0, 0, 1, 1 },
{ "SaveRAM cart", MB_ONOFF, MA_CDOPT_SAVERAM, &currentConfig.PicoOpt, 0x8000, 0, 0, 1 }, { "SaveRAM cart", MB_ONOFF, MA_CDOPT_SAVERAM, &PicoOpt, 0x8000, 0, 0, 1, 1 },
{ "Scale/Rot. fx (slow)", MB_ONOFF, MA_CDOPT_SCALEROT_CHIP,&currentConfig.PicoOpt, 0x1000, 0, 0, 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, &currentConfig.PicoOpt, 0x2000, 0, 0, 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 }, { "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_SCALE, NULL, 0, 0, 0, 1, 1 },
{ NULL, MB_NONE, MA_OPT3_HSCALE32, NULL, 0, 0, 0, 1 }, { NULL, MB_NONE, MA_OPT3_HSCALE32, NULL, 0, 0, 0, 1, 1 },
{ NULL, MB_NONE, MA_OPT3_HSCALE40, NULL, 0, 0, 0, 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 }, { 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 }, { NULL, MB_RANGE, MA_OPT3_GAMMAA, &currentConfig.gamma, 0, -4, 16, 1, 1 },
{ NULL, MB_NONE, MA_OPT3_VSYNC, NULL, 0, 0, 0, 1 }, { NULL, MB_RANGE, MA_OPT3_BLACKLVL, &currentConfig.gamma2, 0, 0, 2, 1, 1 },
{ "Set to unscaled centered", MB_NONE, MA_OPT3_PRES_NOSCALE, NULL, 0, 0, 0, 1 }, { NULL, MB_NONE, MA_OPT3_VSYNC, NULL, 0, 0, 0, 1, 1 },
{ "Set to 4:3 scaled", MB_NONE, MA_OPT3_PRES_SCALE43, NULL, 0, 0, 0, 1 }, { "Set to unscaled centered", MB_NONE, MA_OPT3_PRES_NOSCALE, NULL, 0, 0, 0, 1, 0 },
{ "Set to fullscreen", MB_NONE, MA_OPT3_PRES_FULLSCR, NULL, 0, 0, 0, 1 }, { "Set to 4:3 scaled", MB_NONE, MA_OPT3_PRES_SCALE43, NULL, 0, 0, 0, 1, 0 },
{ "done", MB_NONE, MA_OPT3_DONE, NULL, 0, 0, 0, 1 }, { "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_GAMMAA:
case MA_OPT3_VSYNC: tmp = ((currentConfig.EmuOpt>>13)&1) | ((currentConfig.EmuOpt>>15)&2); 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 }, { "Disable sprite limit", MB_ONOFF, MA_OPT2_NO_SPRITE_LIM, &PicoOpt, 0x40000, 0, 0, 1, 1 },
{ "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &currentConfig.PicoOpt,0x00001, 0, 0, 1 }, { "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, &PicoOpt, 0x00004, 0, 0, 1, 1 },
{ "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496, &currentConfig.PicoOpt,0x00002, 0, 0, 1 }, { "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &PicoOpt, 0x00001, 0, 0, 1, 1 },
{ "gzip savestates", MB_ONOFF, MA_OPT2_GZIP_STATES, &currentConfig.EmuOpt, 0x00008, 0, 0, 1 }, { "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496, &PicoOpt, 0x00002, 0, 0, 1, 1 },
{ "Don't save last used ROM", MB_ONOFF, MA_OPT2_NO_LAST_ROM, &currentConfig.EmuOpt, 0x00020, 0, 0, 1 }, { "gzip savestates", MB_ONOFF, MA_OPT2_GZIP_STATES, &currentConfig.EmuOpt, 0x00008, 0, 0, 1, 1 },
{ "Status line in main menu", MB_ONOFF, MA_OPT2_STATUS_LINE, &currentConfig.EmuOpt, 0x20000, 0, 0, 1 }, { "Don't save last used ROM", MB_ONOFF, MA_OPT2_NO_LAST_ROM, &currentConfig.EmuOpt, 0x00020, 0, 0, 1, 1 },
{ "Disable frame limitter", MB_ONOFF, MA_OPT2_NO_FRAME_LIMIT, &currentConfig.EmuOpt, 0x40000, 0, 0, 1 }, { "Status line in main menu", MB_ONOFF, MA_OPT2_STATUS_LINE, &currentConfig.EmuOpt, 0x20000, 0, 0, 1, 1 },
{ "done", MB_NONE, MA_OPT2_DONE, NULL, 0, 0, 0, 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 }, { NULL, MB_NONE, MA_OPT_RENDERER, NULL, 0, 0, 0, 1, 1 },
{ "Accurate timing (slower)", MB_ONOFF, MA_OPT_ACC_TIMING, &currentConfig.PicoOpt, 0x0040, 0, 0, 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, &currentConfig.PicoOpt, 0x0080, 0, 0, 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 }, { "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 }, { 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 }, { "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 }, { NULL, MB_NONE, MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1, 1 },
{ "6 button pad", MB_ONOFF, MA_OPT_6BUTTON_PAD, &currentConfig.PicoOpt, 0x0020, 0, 0, 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 }, { 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 }, { "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 }, { 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 }, { "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 }, { 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 }, { "[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 }, { "[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 }, { "[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 }, { 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 }, { "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 }, { 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"; str = (PicoOpt&0x08)?"stereo":"mono";
text_out16(x, y, "Sound Quality: %5iHz %s", currentConfig.PsndRate, str); 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)) { if ((PicoOpt & 0x10) || !(currentConfig.EmuOpt & 0x80)) {
currentConfig.PicoOpt&= ~0x10; 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
{ {

View file

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