#define OSD_FPS_X 260\r
#endif\r
\r
-// PicoPad[] format: SACB RLDU\r
-char *actionNames[] = {\r
- "UP", "DOWN", "LEFT", "RIGHT", "B", "C", "A", "START",\r
- 0, 0, 0, 0, 0, 0, 0, 0, // Z, Y, X, MODE (enabled only when needed), ?, ?, ?, ?\r
- 0, 0, 0, 0, 0, 0, 0, "ENTER MENU", // player2_flag, ?, ?, ?, ?, ?, ?, menu\r
- "NEXT SAVE SLOT", "PREV SAVE SLOT", "SWITCH RENDERER", "SAVE STATE",\r
- "LOAD STATE", "VOLUME UP", "VOLUME DOWN", "DONE"\r
-};\r
\r
int engineState;\r
int select_exits = 0;\r
unsigned char *framebuff = 0; // temporary buffer for alt renderer\r
int state_slot = 0;\r
int reset_timing = 0;\r
+int config_slot = 0, config_slot_current = 0;\r
\r
\r
// utilities\r
return 0;\r
}\r
\r
+ menu_romload_prepare(used_rom_name);\r
+\r
if(rom_data) {\r
free(rom_data);\r
rom_data = 0;\r
sprintf(menuErrorMsg, "PicoCartLoad() failed.");\r
printf("%s\n", menuErrorMsg);\r
pm_close(rom);\r
+ menu_romload_end();\r
return 0;\r
}\r
pm_close(rom);\r
+ menu_romload_end();\r
\r
// detect wrong files (Pico crashes on very small files), also see if ROM EP is good\r
if(rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 ||\r
}\r
\r
// load config for this ROM (do this before insert to get correct region)\r
- ret = emu_ReadConfig(1);\r
+ ret = emu_ReadConfig(1, 1);\r
if (!ret)\r
- emu_ReadConfig(0);\r
+ emu_ReadConfig(0, 1);\r
\r
printf("PicoCartInsert(%p, %d);\n", rom_data, rom_size);\r
if(PicoCartInsert(rom_data, rom_size)) {\r
}\r
\r
\r
-int emu_ReadConfig(int game)\r
+int emu_ReadConfig(int game, int no_defaults)\r
{\r
FILE *f;\r
- char cfg[512];\r
+ char cfg[512], extbuf[16];\r
int bread = 0;\r
\r
if (!game)\r
{\r
- // set default config\r
- memset(¤tConfig, 0, sizeof(currentConfig));\r
- currentConfig.lastRomFile[0] = 0;\r
- currentConfig.EmuOpt = 0x1f | 0x600; // | confirm_save, cd_leds\r
- currentConfig.PicoOpt = 0x0f | 0xe00; // | use_940, cd_pcm, cd_cdda\r
- currentConfig.PsndRate = 22050; // 44100;\r
- currentConfig.PicoRegion = 0; // auto\r
- currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP\r
- currentConfig.Frameskip = -1; // auto\r
- currentConfig.CPUclock = 200;\r
- currentConfig.volume = 50;\r
- currentConfig.KeyBinds[ 0] = 1<<0; // SACB RLDU\r
- currentConfig.KeyBinds[ 4] = 1<<1;\r
- currentConfig.KeyBinds[ 2] = 1<<2;\r
- currentConfig.KeyBinds[ 6] = 1<<3;\r
- currentConfig.KeyBinds[14] = 1<<4;\r
- currentConfig.KeyBinds[13] = 1<<5;\r
- currentConfig.KeyBinds[12] = 1<<6;\r
- currentConfig.KeyBinds[ 8] = 1<<7;\r
- currentConfig.KeyBinds[15] = 1<<26; // switch rend\r
- currentConfig.KeyBinds[10] = 1<<27; // save state\r
- currentConfig.KeyBinds[11] = 1<<28; // load state\r
- currentConfig.KeyBinds[23] = 1<<29; // vol up\r
- currentConfig.KeyBinds[22] = 1<<30; // vol down\r
- currentConfig.gamma = 100;\r
- currentConfig.PicoCDBuffers = 64;\r
- currentConfig.scaling = 0;\r
+ if (!no_defaults)\r
+ {\r
+ // set default config\r
+ memset(¤tConfig, 0, sizeof(currentConfig));\r
+ currentConfig.lastRomFile[0] = 0;\r
+ currentConfig.EmuOpt = 0x1f | 0x600; // | confirm_save, cd_leds\r
+ currentConfig.PicoOpt = 0x0f | 0xe00; // | use_940, cd_pcm, cd_cdda\r
+ currentConfig.PsndRate = 22050; // 44100;\r
+ currentConfig.PicoRegion = 0; // auto\r
+ currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP\r
+ currentConfig.Frameskip = -1; // auto\r
+ currentConfig.CPUclock = 200;\r
+ currentConfig.volume = 50;\r
+ currentConfig.KeyBinds[ 0] = 1<<0; // SACB RLDU\r
+ currentConfig.KeyBinds[ 4] = 1<<1;\r
+ currentConfig.KeyBinds[ 2] = 1<<2;\r
+ currentConfig.KeyBinds[ 6] = 1<<3;\r
+ currentConfig.KeyBinds[14] = 1<<4;\r
+ currentConfig.KeyBinds[13] = 1<<5;\r
+ currentConfig.KeyBinds[12] = 1<<6;\r
+ currentConfig.KeyBinds[ 8] = 1<<7;\r
+ currentConfig.KeyBinds[15] = 1<<26; // switch rend\r
+ currentConfig.KeyBinds[10] = 1<<27; // save state\r
+ currentConfig.KeyBinds[11] = 1<<28; // load state\r
+ currentConfig.KeyBinds[23] = 1<<29; // vol up\r
+ currentConfig.KeyBinds[22] = 1<<30; // vol down\r
+ currentConfig.gamma = 100;\r
+ currentConfig.PicoCDBuffers = 64;\r
+ currentConfig.scaling = 0;\r
+ }\r
strncpy(cfg, PicoConfigFile, 511);\r
+ if (config_slot != 0)\r
+ {\r
+ char *p = strrchr(cfg, '.');\r
+ if (p == NULL) p = cfg + strlen(cfg);\r
+ sprintf(extbuf, ".%i.pbcfg", config_slot);\r
+ strncpy(p, extbuf, 511 - (p - cfg));\r
+ }\r
cfg[511] = 0;\r
} else {\r
- romfname_ext(cfg, "cfg/", ".pbcfg");\r
+ if (config_slot != 0)\r
+ sprintf(extbuf, ".%i.pbcfg", config_slot);\r
+ else strcpy(extbuf, ".pbcfg");\r
+ romfname_ext(cfg, "cfg/", extbuf);\r
f = fopen(cfg, "rb");\r
if (!f) romfname_ext(cfg, NULL, ".pbcfg");\r
else fclose(f);\r
PicoRegionOverride = currentConfig.PicoRegion;\r
PicoAutoRgnOrder = currentConfig.PicoAutoRgnOrder;\r
PicoCDBuffers = currentConfig.PicoCDBuffers;\r
- if (PicoOpt & 0x20) {\r
- actionNames[ 8] = "Z"; actionNames[ 9] = "Y";\r
- actionNames[10] = "X"; actionNames[11] = "MODE";\r
- }\r
scaling_update();\r
// some sanity checks\r
if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;\r
currentConfig.KeyBinds[22] = 1<<30; // vol down\r
}\r
\r
+ if (bread > 0) config_slot_current = config_slot;\r
return (bread > 0); // == sizeof(currentConfig));\r
}\r
\r
int emu_WriteConfig(int game)\r
{\r
FILE *f;\r
- char cfg[512];\r
+ char cfg[512], extbuf[16];\r
int bwrite = 0;\r
\r
if (!game)\r
{\r
strncpy(cfg, PicoConfigFile, 511);\r
+ if (config_slot != 0)\r
+ {\r
+ char *p = strrchr(cfg, '.');\r
+ if (p == NULL) p = cfg + strlen(cfg);\r
+ sprintf(extbuf, ".%i.pbcfg", config_slot);\r
+ strncpy(p, extbuf, 511 - (p - cfg));\r
+ }\r
cfg[511] = 0;\r
} else {\r
- romfname_ext(cfg, "cfg/", ".pbcfg");\r
+ if (config_slot != 0)\r
+ sprintf(extbuf, ".%i.pbcfg", config_slot);\r
+ else strcpy(extbuf, ".pbcfg");\r
+ romfname_ext(cfg, "cfg/", extbuf);\r
}\r
\r
printf("emu_WriteConfig: %s ", cfg);\r
}\r
printf((bwrite == sizeof(currentConfig)) ? "(ok)\n" : "(failed)\n");\r
\r
+ if (bwrite == sizeof(currentConfig)) config_slot_current = config_slot;\r
return (bwrite == sizeof(currentConfig));\r
}\r
\r
\r
// restore gamma\r
if (gp2x_old_gamma != 100)\r
- set_gamma(100);\r
+ set_gamma(100, 0);\r
}\r
\r
\r
void emu_Loop(void)\r
{\r
static int gp2x_old_clock = 200;\r
- static int PsndRate_old = 0, PicoOpt_old = 0, PsndLen_real = 0, pal_old = 0;\r
+ static int PsndRate_old = 0, PicoOpt_old = 0, EmuOpt_old = 0, PsndLen_real = 0, pal_old = 0;\r
char fpsbuff[24]; // fps count c string\r
struct timeval tval; // timing\r
int thissec = 0, frames_done = 0, frames_shown = 0, oldmodes = 0;\r
- int target_fps, target_frametime, lim_time, i;\r
+ int target_fps, target_frametime, lim_time, vsync_offset, i;\r
char *notice = 0;\r
\r
printf("entered emu_Loop()\n");\r
printf(" done\n");\r
}\r
\r
- if (gp2x_old_gamma != currentConfig.gamma) {\r
- set_gamma(currentConfig.gamma);\r
+ if (gp2x_old_gamma != currentConfig.gamma || (EmuOpt_old&0x1000) != (currentConfig.EmuOpt&0x1000)) {\r
+ set_gamma(currentConfig.gamma, !!(currentConfig.EmuOpt&0x1000));\r
gp2x_old_gamma = currentConfig.gamma;\r
- printf("updated gamma to %i\n", currentConfig.gamma);\r
+ printf("updated gamma to %i, A_SN's curve: %i\n", currentConfig.gamma, !!(currentConfig.EmuOpt&0x1000));\r
}\r
\r
+ if ((EmuOpt_old&0x2000) != (currentConfig.EmuOpt&0x2000)) {\r
+ if (currentConfig.EmuOpt&0x2000)\r
+ set_LCD_custom_rate(Pico.m.pal ? LCDR_100 : LCDR_120);\r
+ else unset_LCD_custom_rate();\r
+ }\r
+\r
+ EmuOpt_old = currentConfig.EmuOpt;\r
fpsbuff[0] = 0;\r
\r
// make sure we are in correct mode\r
// prepare CD buffer\r
if (PicoMCD & 1) PicoCDBufferInit();\r
\r
+ // calc vsync offset to sync timing code with vsync\r
+ if (currentConfig.EmuOpt&0x2000) {\r
+ gettimeofday(&tval, 0);\r
+ gp2x_video_wait_vsync();\r
+ gettimeofday(&tval, 0);\r
+ vsync_offset = tval.tv_usec;\r
+ while (vsync_offset >= target_frametime)\r
+ vsync_offset -= target_frametime;\r
+ if (!vsync_offset) vsync_offset++;\r
+ printf("vsync_offset: %i\n", vsync_offset);\r
+ } else\r
+ vsync_offset = 0;\r
+\r
// loop?\r
while (engineState == PGS_Running)\r
{\r
if (frames_shown > frames_done) frames_shown = frames_done;\r
}\r
}\r
-#if 0\r
- sprintf(fpsbuff, "%05i", Pico.m.frame_count);\r
-#endif\r
- lim_time = (frames_done+1) * target_frametime;\r
+\r
+ lim_time = (frames_done+1) * target_frametime + vsync_offset;\r
if(currentConfig.Frameskip >= 0) { // frameskip enabled\r
for(i = 0; i < currentConfig.Frameskip; i++) {\r
updateKeys();\r
reset_timing = 1;\r
else if (PsndOut != NULL || currentConfig.Frameskip < 0)\r
{\r
- // sleep if we are still too fast\r
+ // sleep or vsync if we are still too fast\r
// usleep sleeps for ~20ms minimum, so it is not a solution here\r
if(tval.tv_usec < lim_time)\r
{\r
// we are too fast\r
- simpleWait(thissec, lim_time);\r
+ if (vsync_offset) {\r
+ if (lim_time - tval.tv_usec > target_frametime/2)\r
+ simpleWait(thissec, lim_time - target_frametime/4);\r
+ gp2x_video_wait_vsync();\r
+ } else {\r
+ simpleWait(thissec, lim_time);\r
+ }\r
}\r
}\r
\r