strlwr_(ext);\r
}\r
\r
+static void fname_ext(char *dst, int dstlen, const char *prefix, const char *ext, const char *fname)\r
+{\r
+ int prefix_len = 0;\r
+ const char *p;\r
+\r
+ *dst = 0;\r
+ if (prefix) {\r
+ int len = plat_get_root_dir(dst, dstlen);\r
+ strcpy(dst + len, prefix);\r
+ prefix_len = len + strlen(prefix);\r
+ }\r
+\r
+ p = fname + strlen(fname) - 1;\r
+ for (; p >= fname && *p != PATH_SEP_C; p--)\r
+ ;\r
+ p++;\r
+ strncpy(dst + prefix_len, p, dstlen - prefix_len - 1);\r
+\r
+ dst[dstlen - 8] = 0;\r
+ if (dst[strlen(dst) - 4] == '.')\r
+ dst[strlen(dst) - 4] = 0;\r
+ if (ext)\r
+ strcat(dst, ext);\r
+}\r
+\r
+static void romfname_ext(char *dst, int dstlen, const char *prefix, const char *ext)\r
+{\r
+ fname_ext(dst, dstlen, prefix, ext, rom_fname_loaded);\r
+}\r
+\r
void emu_status_msg(const char *format, ...)\r
{\r
va_list vl;\r
return p - dest;\r
}\r
\r
-static char *emu_make_rom_id(void)\r
+static char *emu_make_rom_id(const char *fname)\r
{\r
static char id_string[3+0xe*3+0x3*3+0x30*3+3];\r
int pos, swab = 1;\r
strcpy(id_string, "CD|");\r
swab = 0;\r
}\r
- else strcpy(id_string, "MD|");\r
+ else if (PicoAHW & PAHW_SMS)\r
+ strcpy(id_string, "MS|");\r
+ else strcpy(id_string, "MD|");\r
pos = 3;\r
\r
- pos += extract_text(id_string + pos, id_header + 0x80, 0x0e, swab); // serial\r
- id_string[pos] = '|'; pos++;\r
- pos += extract_text(id_string + pos, id_header + 0xf0, 0x03, swab); // region\r
- id_string[pos] = '|'; pos++;\r
- pos += extract_text(id_string + pos, id_header + 0x50, 0x30, swab); // overseas name\r
- id_string[pos] = 0;\r
+ if (!(PicoAHW & PAHW_SMS)) {\r
+ pos += extract_text(id_string + pos, id_header + 0x80, 0x0e, swab); // serial\r
+ id_string[pos] = '|'; pos++;\r
+ pos += extract_text(id_string + pos, id_header + 0xf0, 0x03, swab); // region\r
+ id_string[pos] = '|'; pos++;\r
+ pos += extract_text(id_string + pos, id_header + 0x50, 0x30, swab); // overseas name\r
+ id_string[pos] = 0;\r
+ if (pos > 5)\r
+ return id_string;\r
+ pos = 3;\r
+ }\r
+\r
+ // can't find name in ROM, use filename\r
+ fname_ext(id_string + 3, sizeof(id_string) - 3, NULL, NULL, fname);\r
\r
return id_string;\r
}\r
\r
static void system_announce(void)\r
{\r
- const char *sys_name, *tv_standard;\r
+ const char *sys_name, *tv_standard, *extra = "";\r
int fps;\r
\r
if (PicoAHW & PAHW_SMS) {\r
sys_name = "Master System";\r
+#ifdef NO_SMS\r
+ extra = " [no support]";\r
+#endif\r
} else if (PicoAHW & PAHW_PICO) {\r
sys_name = "Pico";\r
} else if (PicoAHW & PAHW_MCD) {\r
tv_standard = Pico.m.pal ? "PAL" : "NTSC";\r
fps = Pico.m.pal ? 50 : 60;\r
\r
- emu_status_msg("%s %s / %dFPS", tv_standard, sys_name, fps);\r
+ emu_status_msg("%s %s / %dFPS%s", tv_standard, sys_name, fps, extra);\r
}\r
\r
// note: this function might mangle rom_fname\r
// valid CD image, check for BIOS..\r
\r
// we need to have config loaded at this point\r
- ret = emu_read_config(1, 0);\r
- if (!ret) emu_read_config(0, 0);\r
+ ret = emu_read_config(rom_fname, 0);\r
+ if (!ret) emu_read_config(NULL, 0);\r
cfg_loaded = 1;\r
\r
if (PicoRegionOverride) {\r
if (!(PicoAHW & PAHW_MCD))\r
memcpy(id_header, rom_data + 0x100, sizeof(id_header));\r
if (!cfg_loaded) {\r
- ret = emu_read_config(1, 0);\r
- if (!ret) emu_read_config(0, 0);\r
+ ret = emu_read_config(rom_fname, 0);\r
+ if (!ret) emu_read_config(NULL, 0);\r
}\r
\r
emu_make_path(static_buff, "carthw.cfg", sizeof(static_buff));\r
return 1;\r
}\r
\r
-static void romfname_ext(char *dst, const char *prefix, const char *ext)\r
-{\r
- char *p;\r
- int prefix_len = 0;\r
-\r
- // make save filename\r
- p = rom_fname_loaded + strlen(rom_fname_loaded) - 1;\r
- for (; p >= rom_fname_loaded && *p != PATH_SEP_C; p--); p++;\r
- *dst = 0;\r
- if (prefix) {\r
- int len = plat_get_root_dir(dst, 512);\r
- strcpy(dst + len, prefix);\r
- prefix_len = len + strlen(prefix);\r
- }\r
-#ifdef UIQ3\r
- else p = rom_fname_loaded; // backward compatibility\r
-#endif\r
- strncpy(dst + prefix_len, p, 511-prefix_len);\r
- dst[511-8] = 0;\r
- if (dst[strlen(dst)-4] == '.') dst[strlen(dst)-4] = 0;\r
- if (ext) strcat(dst, ext);\r
-}\r
-\r
// <base dir><end>\r
void emu_make_path(char *buff, const char *end, int size)\r
{\r
cfg_buff_512[511] = 0;\r
}\r
\r
+void emu_prep_defconfig(void)\r
+{\r
+ memset(&defaultConfig, 0, sizeof(defaultConfig));\r
+ defaultConfig.EmuOpt = 0x9d | EOPT_RAM_TIMINGS|EOPT_EN_CD_LEDS;\r
+ defaultConfig.s_PicoOpt = POPT_EN_STEREO|POPT_EN_FM|POPT_EN_PSG|POPT_EN_Z80 |\r
+ POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_SVP_DRC|POPT_ACC_SPRITES |\r
+ POPT_EN_32X|POPT_EN_PWM;\r
+ defaultConfig.s_PsndRate = 44100;\r
+ defaultConfig.s_PicoRegion = 0; // auto\r
+ defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP\r
+ defaultConfig.s_PicoCDBuffers = 0;\r
+ defaultConfig.confirm_save = EOPT_CONFIRM_SAVE;\r
+ defaultConfig.Frameskip = -1; // auto\r
+ defaultConfig.volume = 50;\r
+ defaultConfig.gamma = 100;\r
+ defaultConfig.scaling = 0;\r
+ defaultConfig.turbo_rate = 15;\r
+\r
+ // platform specific overrides\r
+ pemu_prep_defconfig();\r
+}\r
+\r
void emu_set_defconfig(void)\r
{\r
memcpy(¤tConfig, &defaultConfig, sizeof(currentConfig));\r
PicoRegionOverride = currentConfig.s_PicoRegion;\r
PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder;\r
PicoCDBuffers = currentConfig.s_PicoCDBuffers;\r
+ p32x_msh2_multiplier = MSH2_MULTI_DEFAULT;\r
+ p32x_ssh2_multiplier = SSH2_MULTI_DEFAULT;\r
}\r
\r
-int emu_read_config(int game, int no_defaults)\r
+int emu_read_config(const char *rom_fname, int no_defaults)\r
{\r
char cfg[512];\r
int ret;\r
if (!no_defaults)\r
emu_set_defconfig();\r
\r
- if (!game)\r
+ if (rom_fname == NULL)\r
{\r
+ // global config\r
make_config_cfg(cfg);\r
ret = config_readsect(cfg, NULL);\r
}\r
else\r
{\r
- char *sect = emu_make_rom_id();\r
+ char *sect = emu_make_rom_id(rom_fname);\r
\r
- // try new .cfg way\r
if (config_slot != 0)\r
sprintf(cfg, "game.%i.cfg", config_slot);\r
else strcpy(cfg, "game.cfg");\r
}\r
}\r
\r
- plat_validate_config();\r
+ pemu_validate_config();\r
\r
// some sanity checks\r
#ifdef PSP\r
if (config_slot != 0)\r
sprintf(cfg, "game.%i.cfg", config_slot);\r
else strcpy(cfg, "game.cfg");\r
- game_sect = emu_make_rom_id();\r
+ game_sect = emu_make_rom_id(rom_fname_loaded);\r
lprintf("emu_write_config: sect \"%s\"\n", game_sect);\r
}\r
\r
if (is_sram)\r
{\r
strcpy(ext, (PicoAHW & PAHW_MCD) ? ".brm" : ".srm");\r
- romfname_ext(saveFname, (PicoAHW & PAHW_MCD) ? "brm"PATH_SEP : "srm"PATH_SEP, ext);\r
+ romfname_ext(saveFname, sizeof(static_buff),\r
+ (PicoAHW & PAHW_MCD) ? "brm"PATH_SEP : "srm"PATH_SEP, ext);\r
if (!load)\r
return saveFname;\r
\r
if (try_ropen_file(saveFname))\r
return saveFname;\r
\r
- romfname_ext(saveFname, NULL, ext);\r
+ romfname_ext(saveFname, sizeof(static_buff), NULL, ext);\r
if (try_ropen_file(saveFname))\r
return saveFname;\r
}\r
strcat(ext, ext_main);\r
\r
if (!load) {\r
- romfname_ext(saveFname, "mds" PATH_SEP, ext);\r
+ romfname_ext(saveFname, sizeof(static_buff), "mds" PATH_SEP, ext);\r
return saveFname;\r
}\r
else {\r
- romfname_ext(saveFname, "mds" PATH_SEP, ext);\r
+ romfname_ext(saveFname, sizeof(static_buff), "mds" PATH_SEP, ext);\r
if (try_ropen_file(saveFname))\r
return saveFname;\r
\r
- romfname_ext(saveFname, NULL, ext);\r
+ romfname_ext(saveFname, sizeof(static_buff), NULL, ext);\r
if (try_ropen_file(saveFname))\r
return saveFname;\r
\r
sprintf(ext, ".%i", slot);\r
strcat(ext, ext_othr);\r
\r
- romfname_ext(saveFname, "mds"PATH_SEP, ext);\r
+ romfname_ext(saveFname, sizeof(static_buff), "mds"PATH_SEP, ext);\r
if (try_ropen_file(saveFname))\r
return saveFname;\r
}\r
\r
void emu_32x_startup(void)\r
{\r
- plat_video_toggle_renderer(0, 1, 0);\r
+ plat_video_toggle_renderer(0, 0);\r
system_announce();\r
}\r
\r
{\r
int do_it = 1;\r
if ( emu_check_save_file(state_slot) &&\r
- (((which & PEV_STATE_LOAD) && (currentConfig.EmuOpt & EOPT_CONFIRM_LOAD)) ||\r
- ((which & PEV_STATE_SAVE) && (currentConfig.EmuOpt & EOPT_CONFIRM_SAVE))) )\r
+ (((which & PEV_STATE_LOAD) && (currentConfig.confirm_save & EOPT_CONFIRM_LOAD)) ||\r
+ ((which & PEV_STATE_SAVE) && (currentConfig.confirm_save & EOPT_CONFIRM_SAVE))) )\r
{\r
const char *nm;\r
char tmp[64];\r
PicoStateProgressCB = NULL;\r
}\r
}\r
- if ((which & PEV_SWITCH_RND) && !(PicoAHW & PAHW_32X))\r
+ if (which & PEV_SWITCH_RND)\r
{\r
- plat_video_toggle_renderer(1, 0, 0);\r
+ plat_video_toggle_renderer(1, 0);\r
}\r
if (which & (PEV_SSLOT_PREV|PEV_SSLOT_NEXT))\r
{\r
mkdir_path(path, pos, "srm");\r
mkdir_path(path, pos, "brm");\r
\r
+ pprof_init();\r
+\r
make_config_cfg(path);\r
config_readlrom(path);\r
\r
#endif\r
}\r
\r
+ pprof_finish();\r
+\r
PicoExit();\r
}\r
\r
Pico.m.dirtyPal = 1;\r
rendstatus_old = -1;\r
\r
+ PicoLoopPrepare();\r
+\r
+ // prepare CD buffer\r
+ if (PicoAHW & PAHW_MCD)\r
+ PicoCDBufferInit();\r
+\r
+ pemu_loop_prep();\r
+\r
/* number of ticks per frame */\r
if (Pico.m.pal) {\r
target_fps = 50;\r
target_frametime = ms_to_ticks(1000) / 60 + 1;\r
}\r
\r
- // prepare CD buffer\r
- if (PicoAHW & PAHW_MCD)\r
- PicoCDBufferInit();\r
- PicoLoopPrepare();\r
-\r
- pemu_loop_prep();\r
-\r
timestamp_fps = get_ticks();\r
reset_timing = 1;\r
\r
unsigned int timestamp;\r
int diff, diff_lim;\r
\r
+ pprof_start(main);\r
+\r
timestamp = get_ticks();\r
if (reset_timing) {\r
reset_timing = 0;\r
}\r
bench_fps += frames_shown;\r
sprintf(fpsbuff, "%02i/%02i/%02i", frames_shown, bench_fps_s, (bf[0]+bf[1]+bf[2]+bf[3])>>2);\r
+ printf("%s\n", fpsbuff);\r
#else\r
if (currentConfig.EmuOpt & EOPT_SHOW_FPS) {\r
sprintf(fpsbuff, "%02i/%02i", frames_shown, frames_done);\r
{\r
if ((currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) && currentConfig.Frameskip >= 0)\r
pframes_done = 0;\r
- else {\r
+ else\r
pframes_done -= target_fps;\r
- /* don't allow it to drift during heavy slowdowns */\r
- if (pframes_done < -5) {\r
- reset_timing = 1;\r
- continue;\r
- }\r
- if (pframes_done < -2)\r
- pframes_done = -2;\r
+ if (pframes_done < -2) {\r
+ /* don't drag more than 2 frames behind */\r
+ pframes_done = -2;\r
+ timestamp_base = timestamp - 2 * target_frametime;\r
}\r
- timestamp_base += ms_to_ticks(1000);\r
+ else\r
+ timestamp_base += ms_to_ticks(1000);\r
}\r
\r
diff = timestamp - timestamp_base;\r
else if (diff > diff_lim)\r
{\r
/* no time left for this frame - skip */\r
- if (diff - diff_lim >= ms_to_ticks(200)) {\r
- /* if too much behind, reset instead */\r
- reset_timing = 1;\r
+ /* limit auto frameskip to 8 */\r
+ if (frames_done / 8 <= frames_shown) {\r
+ emu_update_input();\r
+ skip_frame(diff < diff_lim + target_frametime * 16);\r
+ pframes_done++; frames_done++;\r
continue;\r
}\r
- emu_update_input();\r
- skip_frame(diff < diff_lim + target_frametime * 2);\r
- pframes_done++; frames_done++;\r
- continue;\r
}\r
\r
emu_update_input();\r
PicoFrame();\r
+ pemu_finalize_frame(fpsbuff, notice_msg);\r
+\r
+ // plat_video_flip();\r
\r
/* frame limiter */\r
if (!reset_timing && !(currentConfig.EmuOpt & (EOPT_NO_FRMLIMIT|EOPT_EXT_FRMLIMIT)))\r
}\r
}\r
\r
- pemu_update_display(fpsbuff, notice_msg);\r
+ // XXX: for some plats it might be better to flip before vsync\r
+ // (due to shadow registers in display hw)\r
+ plat_video_flip();\r
\r
pframes_done++; frames_done++; frames_shown++;\r
+\r
+ pprof_end(main);\r
}\r
\r
emu_set_fastforward(0);\r