X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=gp2x%2Femu.c;h=f43f9b72b4d3c8d50d867169669fbf9a1a6de945;hb=0d0558bde90234a0413433f743cd85aee645eeef;hp=3d6cd3a2ca94d1959a1ab500b549a9e5eaec985c;hpb=af6e9c49619b918da965e82e5ecb525d98aee862;p=libpicofe.git diff --git a/gp2x/emu.c b/gp2x/emu.c index 3d6cd3a..f43f9b7 100644 --- a/gp2x/emu.c +++ b/gp2x/emu.c @@ -54,13 +54,14 @@ extern int crashed_940; static short sndBuffer[2*44100/50]; static char noticeMsg[64]; // notice msg to draw static struct timeval noticeMsgTime = { 0, 0 }; // when started showing -static int reset_timing, osd_fps_x; +static int osd_fps_x; static int combo_keys = 0, combo_acts = 0; // keys and actions which need button combos static int gp2x_old_gamma = 100; static unsigned char *movie_data = NULL; static int movie_size = 0; unsigned char *framebuff = 0; // temporary buffer for alt renderer int state_slot = 0; +int reset_timing = 0; /* // tmp @@ -393,6 +394,8 @@ int emu_ReloadRom(void) } +static void emu_msg_cb(const char *msg); + void emu_Init(void) { // make temp buffer for alt renderer @@ -409,6 +412,7 @@ void emu_Init(void) mkdir("cfg", 0777); PicoInit(); + PicoMessage = emu_msg_cb; // logf = fopen("log.txt", "w"); } @@ -496,6 +500,7 @@ int emu_ReadConfig(int game) currentConfig.KeyBinds[23] = 1<<29; // vol up currentConfig.KeyBinds[22] = 1<<30; // vol down currentConfig.gamma = 100; + currentConfig.PicoCDBuffers = 64; strncpy(cfg, PicoConfigFile, 511); cfg[511] = 0; } else { @@ -517,6 +522,7 @@ int emu_ReadConfig(int game) PsndRate = currentConfig.PsndRate; PicoRegionOverride = currentConfig.PicoRegion; PicoAutoRgnOrder = currentConfig.PicoAutoRgnOrder; + PicoCDBuffers = currentConfig.PicoCDBuffers; if (PicoOpt & 0x20) { actionNames[ 8] = "Z"; actionNames[ 9] = "Y"; actionNames[10] = "X"; actionNames[11] = "MODE"; @@ -545,7 +551,7 @@ int emu_WriteConfig(int game) strncpy(cfg, PicoConfigFile, 511); cfg[511] = 0; } else { - romfname_ext(cfg, "cfg", ".pbcfg"); + romfname_ext(cfg, "cfg/", ".pbcfg"); } printf("emu_WriteConfig: %s ", cfg); @@ -555,6 +561,7 @@ int emu_WriteConfig(int game) currentConfig.PsndRate = PsndRate; currentConfig.PicoRegion = PicoRegionOverride; currentConfig.PicoAutoRgnOrder = PicoAutoRgnOrder; + currentConfig.PicoCDBuffers = PicoCDBuffers; bwrite = fwrite(¤tConfig, 1, sizeof(currentConfig), f); fflush(f); fclose(f); @@ -768,6 +775,26 @@ static void vidResetMode(void) } +static void emu_msg_cb(const char *msg) +{ + if ((PicoOpt&0x10)||!(currentConfig.EmuOpt&0x80)) { + // 8-bit renderers + gp2x_memset_all_buffers(320*232, 0xe0, 320*8); + osd_text(4, 232, msg); + gp2x_memcpy_all_buffers((char *)gp2x_screen+320*232, 320*232, 320*8); + } else { + // 16bit accurate renderer + gp2x_memset_all_buffers(320*232*2, 0, 320*8*2); + osd_text(4, 232, msg); + gp2x_memcpy_all_buffers((char *)gp2x_screen+320*232*2, 320*232*2, 320*8*2); + } + gettimeofday(¬iceMsgTime, 0); + noticeMsgTime.tv_sec -= 2; + + /* assumption: emu_msg_cb gets called only when something slow is about to happen */ + reset_timing = 1; +} + static void emu_state_cb(const char *str) { clearArea(0); @@ -946,25 +973,17 @@ static void updateSound(int len) { if (PicoOpt&8) len<<=1; - gp2x_sound_write(PsndOut, len<<1); + /* avoid writing audio when lagging behind to prevent audio lag */ + if (PicoSkipFrame != 2) + gp2x_sound_write(PsndOut, len<<1); } -static void SkipFrame(int do_sound) +static void SkipFrame(int do_audio) { - void *sndbuff_tmp = 0; - if (PsndOut && !do_sound) { - sndbuff_tmp = PsndOut; - PsndOut = 0; - } - - PicoSkipFrame=1; + PicoSkipFrame=do_audio ? 1 : 2; PicoFrame(); PicoSkipFrame=0; - - if (sndbuff_tmp && !do_sound) { - PsndOut = sndbuff_tmp; - } } @@ -974,7 +993,6 @@ void emu_forced_frame(void) PicoOpt |= 0x10; PicoFrameFull(); - PicoOpt = po_old; if (!(Pico.video.reg[12]&1)) { vidCpyM2 = vidCpyM2_32col; @@ -984,6 +1002,8 @@ void emu_forced_frame(void) vidCpyM2((unsigned char *)gp2x_screen+320*8, framebuff+328*8); vidConvCpyRGB32(localPal, Pico.cram, 0x40); gp2x_video_setpalette(localPal, 0x40); + + PicoOpt = po_old; } static void simpleWait(int thissec, int lim_time) @@ -1068,6 +1088,9 @@ void emu_Loop(void) PsndOut = 0; } + // prepare CD buffer + if (PicoMCD & 1) PicoCDBufferInit(); + // loop? while (engineState == PGS_Running) { @@ -1148,7 +1171,9 @@ void emu_Loop(void) if (frames_shown > frames_done) frames_shown = frames_done; } } - +#if 0 + sprintf(fpsbuff, "%05i", Pico.m.frame_count); +#endif lim_time = (frames_done+1) * target_frametime; if(currentConfig.Frameskip >= 0) { // frameskip enabled for(i = 0; i < currentConfig.Frameskip; i++) { @@ -1165,8 +1190,14 @@ void emu_Loop(void) } } else if(tval.tv_usec > lim_time) { // auto frameskip // no time left for this frame - skip + if (tval.tv_usec - lim_time >= 0x300000) { + /* something caused a slowdown for us (disk access? cache flush?) + * try to recover by resetting timing... */ + reset_timing = 1; + continue; + } updateKeys(); - SkipFrame(tval.tv_usec < lim_time+target_frametime); frames_done++; + SkipFrame(tval.tv_usec < lim_time+target_frametime*2); frames_done++; continue; } @@ -1233,14 +1264,14 @@ if (Pico.m.frame_count == 31563) { // check time gettimeofday(&tval, 0); - if(thissec != tval.tv_sec) tval.tv_usec+=1000000; + if (thissec != tval.tv_sec) tval.tv_usec+=1000000; - // sleep if we are still too fast - if(PsndOut != 0 || currentConfig.Frameskip < 0) + if (currentConfig.Frameskip < 0 && tval.tv_usec - lim_time >= 0x300000) // slowdown detection + reset_timing = 1; + else if (PsndOut != NULL || currentConfig.Frameskip < 0) { + // sleep if we are still too fast // usleep sleeps for ~20ms minimum, so it is not a solution here - gettimeofday(&tval, 0); - if(thissec != tval.tv_sec) tval.tv_usec+=1000000; if(tval.tv_usec < lim_time) { // we are too fast @@ -1253,6 +1284,9 @@ if (Pico.m.frame_count == 31563) { frames_done++; frames_shown++; } + + if (PicoMCD & 1) PicoCDBufferFree(); + // save SRAM if((currentConfig.EmuOpt & 1) && SRam.changed) { osd_text(4, 232, "Writing SRAM/BRAM..");