X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=gp2x%2Femu.c;h=f43f9b72b4d3c8d50d867169669fbf9a1a6de945;hb=0d0558bde90234a0413433f743cd85aee645eeef;hp=c8c4f8a2c2fa0589c2c76983e74fd00255926f8d;hpb=70d2ecc5ebd5465ad000ff648abe79b3b4969e64;p=libpicofe.git diff --git a/gp2x/emu.c b/gp2x/emu.c index c8c4f8a..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 @@ -169,31 +170,31 @@ int find_bios(int region, char **bios_file) /* checks if romFileName points to valid MegaCD image * if so, checks for suitable BIOS */ -static int cd_check(char *ext, char **bios_file) +static int cd_check(char **bios_file) { unsigned char buf[32]; - FILE *cd_f; + pm_file *cd_f; int type = 0, region = 4; // 1: Japan, 4: US, 8: Europe - cd_f = fopen(romFileName, "rb"); + cd_f = pm_open(romFileName); if (!cd_f) return 0; // let the upper level handle this - if (fread(buf, 1, 32, cd_f) != 32) { - fclose(cd_f); + if (pm_read(buf, 32, cd_f) != 32) { + pm_close(cd_f); return 0; } if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) type = 1; // Sega CD (ISO) if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x10, 14)) type = 2; // Sega CD (BIN) if (type == 0) { - fclose(cd_f); + pm_close(cd_f); return 0; } /* it seems we have a CD image here. Try to detect region and load a suitable BIOS now.. */ - fseek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET); - fread(buf, 1, 1, cd_f); - fclose(cd_f); + pm_seek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET); + pm_read(buf, 1, cd_f); + pm_close(cd_f); if (buf[0] == 0x64) region = 8; // EU if (buf[0] == 0xa1) region = 1; // JAP @@ -217,7 +218,7 @@ int emu_ReloadRom(void) unsigned int rom_size = 0; char *used_rom_name = romFileName; char ext[5]; - FILE *rom; + pm_file *rom; int ret, cd_state; printf("emu_ReloadRom(%s)\n", romFileName); @@ -284,7 +285,7 @@ int emu_ReloadRom(void) } // check for MegaCD image - cd_state = cd_check(ext, &used_rom_name); + cd_state = cd_check(&used_rom_name); if (cd_state > 0) { PicoMCD |= 1; get_ext(used_rom_name, ext); @@ -296,7 +297,7 @@ int emu_ReloadRom(void) PicoMCD &= ~1; } - rom = fopen(used_rom_name, "rb"); + rom = pm_open(used_rom_name); if(!rom) { sprintf(menuErrorMsg, "Failed to open rom."); return 0; @@ -308,25 +309,13 @@ int emu_ReloadRom(void) rom_size = 0; } - // zipfile support - if(!strcasecmp(ext, ".zip")) { - fclose(rom); - ret = CartLoadZip(used_rom_name, &rom_data, &rom_size); - if(ret) { - if (ret == 4) strcpy(menuErrorMsg, "No ROMs found in zip."); - else sprintf(menuErrorMsg, "Unzip failed with code %i", ret); - printf("%s\n", menuErrorMsg); - return 0; - } - } else { - if( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) { - sprintf(menuErrorMsg, "PicoCartLoad() failed."); - printf("%s\n", menuErrorMsg); - fclose(rom); - return 0; - } - fclose(rom); + if( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) { + sprintf(menuErrorMsg, "PicoCartLoad() failed."); + printf("%s\n", menuErrorMsg); + pm_close(rom); + return 0; } + pm_close(rom); // detect wrong files (Pico crashes on very small files), also see if ROM EP is good if(rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 || @@ -405,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 @@ -421,6 +412,7 @@ void emu_Init(void) mkdir("cfg", 0777); PicoInit(); + PicoMessage = emu_msg_cb; // logf = fopen("log.txt", "w"); } @@ -508,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 { @@ -529,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"; @@ -557,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); @@ -567,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); @@ -780,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); @@ -958,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; - } } @@ -986,7 +993,6 @@ void emu_forced_frame(void) PicoOpt |= 0x10; PicoFrameFull(); - PicoOpt = po_old; if (!(Pico.video.reg[12]&1)) { vidCpyM2 = vidCpyM2_32col; @@ -996,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) @@ -1080,6 +1088,9 @@ void emu_Loop(void) PsndOut = 0; } + // prepare CD buffer + if (PicoMCD & 1) PicoCDBufferInit(); + // loop? while (engineState == PGS_Running) { @@ -1160,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++) { @@ -1177,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; } @@ -1245,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 @@ -1265,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..");