X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=gp2x%2Femu.c;h=cbf93efc4ba6784f5597de77dd72cb787eff1390;hb=dd5fd4778d797a1ef4767604b1c57c924ed0f64b;hp=1fd76657e999aed617256bd9a041933ea322de06;hpb=b3818d1ea48c4eaebc60dbc335133ccf44f95f95;p=libpicofe.git diff --git a/gp2x/emu.c b/gp2x/emu.c index 1fd7665..cbf93ef 100644 --- a/gp2x/emu.c +++ b/gp2x/emu.c @@ -21,6 +21,7 @@ #include "../common/arm_utils.h" #include "../common/fonts.h" #include "../common/emu.h" +#include "../common/config.h" #include "cpuctrl.h" #include @@ -47,7 +48,6 @@ extern int crashed_940; static short __attribute__((aligned(4))) sndBuffer[2*44100/50]; static struct timeval noticeMsgTime = { 0, 0 }; // when started showing 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; char noticeMsg[64]; // notice msg to draw unsigned char *PicoDraw2FB = NULL; // temporary buffer for alt renderer @@ -97,48 +97,6 @@ void emu_Init(void) } -static void find_combos(void) -{ - int act, u; - - // find out which keys and actions are combos - combo_keys = combo_acts = 0; - for (act = 0; act < 32; act++) - { - int keyc = 0, keyc2 = 0; - if (act == 16 || act == 17) continue; // player2 flag - if (act > 17) - { - for (u = 0; u < 32; u++) - if (currentConfig.KeyBinds[u] & (1 << act)) keyc++; - } - else - { - for (u = 0; u < 32; u++) - if ((currentConfig.KeyBinds[u] & 0x30000) == 0 && // pl. 1 - (currentConfig.KeyBinds[u] & (1 << act))) keyc++; - for (u = 0; u < 32; u++) - if ((currentConfig.KeyBinds[u] & 0x30000) == 1 && // pl. 2 - (currentConfig.KeyBinds[u] & (1 << act))) keyc2++; - if (keyc2 > keyc) keyc = keyc2; - } - if (keyc > 1) - { - // loop again and mark those keys and actions as combo - for (u = 0; u < 32; u++) - { - if (currentConfig.KeyBinds[u] & (1 << act)) { - combo_keys |= 1 << u; - combo_acts |= 1 << act; - } - } - } - } - - // printf("combo keys/acts: %08x %08x\n", combo_keys, combo_acts); -} - - static void scaling_update(void) { PicoOpt &= ~0x4100; @@ -160,20 +118,10 @@ void emu_Deinit(void) } if (!(currentConfig.EmuOpt & 0x20)) { - FILE *f = fopen(PicoConfigFile, "r+b"); - if (!f) emu_WriteConfig(0); - else { - // if we already have config, reload it, except last ROM - fseek(f, sizeof(currentConfig.lastRomFile), SEEK_SET); - fread(¤tConfig.EmuOpt, 1, sizeof(currentConfig) - sizeof(currentConfig.lastRomFile), f); - fseek(f, 0, SEEK_SET); - fwrite(¤tConfig, 1, sizeof(currentConfig), f); - fflush(f); - fclose(f); + config_writelrom(PicoConfigFile); #ifndef NO_SYNC - sync(); + sync(); #endif - } } free(PicoDraw2FB); @@ -185,34 +133,43 @@ void emu_Deinit(void) set_gamma(100, 0); } +void emu_prepareDefaultConfig(void) +{ + memset(&defaultConfig, 0, sizeof(defaultConfig)); + defaultConfig.EmuOpt = 0x1d | 0x00700; // | <- ram_tmng, confirm_save, cd_leds + defaultConfig.s_PicoOpt = 0x0f | 0x20e00; // | <- use_940, cd_pcm, cd_cdda, svp drc + defaultConfig.s_PsndRate = 44100; + defaultConfig.s_PicoRegion = 0; // auto + defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP + defaultConfig.s_PicoCDBuffers = 0; + defaultConfig.Frameskip = -1; // auto + defaultConfig.CPUclock = 200; + defaultConfig.volume = 50; + defaultConfig.KeyBinds[ 0] = 1<<0; // SACB RLDU + defaultConfig.KeyBinds[ 4] = 1<<1; + defaultConfig.KeyBinds[ 2] = 1<<2; + defaultConfig.KeyBinds[ 6] = 1<<3; + defaultConfig.KeyBinds[14] = 1<<4; + defaultConfig.KeyBinds[13] = 1<<5; + defaultConfig.KeyBinds[12] = 1<<6; + defaultConfig.KeyBinds[ 8] = 1<<7; + defaultConfig.KeyBinds[15] = 1<<26; // switch rend + defaultConfig.KeyBinds[10] = 1<<27; // save state + defaultConfig.KeyBinds[11] = 1<<28; // load state + defaultConfig.KeyBinds[23] = 1<<29; // vol up + defaultConfig.KeyBinds[22] = 1<<30; // vol down + defaultConfig.gamma = 100; + defaultConfig.scaling = 0; +} + void emu_setDefaultConfig(void) { - memset(¤tConfig, 0, sizeof(currentConfig)); - currentConfig.lastRomFile[0] = 0; - currentConfig.EmuOpt = 0x1f | 0x600; // | confirm_save, cd_leds - currentConfig.PicoOpt = 0x0f | 0xe00; // | use_940, cd_pcm, cd_cdda - currentConfig.PsndRate = 22050; // 44100; - currentConfig.PicoRegion = 0; // auto - currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP - currentConfig.Frameskip = -1; // auto - currentConfig.CPUclock = 200; - currentConfig.volume = 50; - currentConfig.KeyBinds[ 0] = 1<<0; // SACB RLDU - currentConfig.KeyBinds[ 4] = 1<<1; - currentConfig.KeyBinds[ 2] = 1<<2; - currentConfig.KeyBinds[ 6] = 1<<3; - currentConfig.KeyBinds[14] = 1<<4; - currentConfig.KeyBinds[13] = 1<<5; - currentConfig.KeyBinds[12] = 1<<6; - currentConfig.KeyBinds[ 8] = 1<<7; - currentConfig.KeyBinds[15] = 1<<26; // switch rend - currentConfig.KeyBinds[10] = 1<<27; // save state - currentConfig.KeyBinds[11] = 1<<28; // load state - currentConfig.KeyBinds[23] = 1<<29; // vol up - currentConfig.KeyBinds[22] = 1<<30; // vol down - currentConfig.gamma = 100; - currentConfig.PicoCDBuffers = 64; - currentConfig.scaling = 0; + memcpy(¤tConfig, &defaultConfig, sizeof(currentConfig)); + PicoOpt = currentConfig.s_PicoOpt; + PsndRate = currentConfig.s_PsndRate; + PicoRegionOverride = currentConfig.s_PicoRegion; + PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder; + PicoCDBuffers = currentConfig.s_PicoCDBuffers; } void osd_text(int x, int y, const char *text) @@ -268,18 +225,18 @@ static void cd_leds(void) } } -static int EmuScan16(unsigned int num, void *sdata) +static int EmuScanBegin16(unsigned int num) { if (!(Pico.video.reg[1]&8)) num += 8; - DrawLineDest = (unsigned short *) gp2x_screen + 320*(num+1); + DrawLineDest = (unsigned short *) gp2x_screen + 320 * num; return 0; } -static int EmuScan8(unsigned int num, void *sdata) +static int EmuScanBegin8(unsigned int num) { if (!(Pico.video.reg[1]&8)) num += 8; - DrawLineDest = (unsigned char *) gp2x_screen + 320*(num+1); + DrawLineDest = (unsigned char *) gp2x_screen + 320 * num; return 0; } @@ -309,19 +266,20 @@ static void blit(const char *fps, const char *notice) else if (!(emu_opt&0x80)) { // 8bit accurate renderer - if (Pico.m.dirtyPal) { + if (Pico.m.dirtyPal) + { Pico.m.dirtyPal = 0; if(Pico.video.reg[0xC]&8) { // shadow/hilight mode vidConvCpyRGB32(localPal, Pico.cram, 0x40); vidConvCpyRGB32sh(localPal+0x40, Pico.cram, 0x40); vidConvCpyRGB32hi(localPal+0x80, Pico.cram, 0x40); - blockcpy(localPal+0xc0, localPal+0x40, 0x40*4); + memcpy32(localPal+0xc0, localPal+0x40, 0x40); localPal[0xc0] = 0x0000c000; localPal[0xd0] = 0x00c00000; localPal[0xe0] = 0x00000000; // reserved pixels for OSD localPal[0xf0] = 0x00ffffff; gp2x_video_setpalette(localPal, 0x100); - } else if (rendstatus & 0x20) { // mid-frame palette changes + } else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes vidConvCpyRGB32(localPal, Pico.cram, 0x40); vidConvCpyRGB32(localPal+0x40, HighPal, 0x40); vidConvCpyRGB32(localPal+0x80, HighPal+0x40, 0x40); @@ -340,7 +298,7 @@ static void blit(const char *fps, const char *notice) if (emu_opt & 2) osd_text(osd_fps_x, h, fps); } - if ((emu_opt & 0x400) && (PicoMCD & 1)) + if ((emu_opt & 0x400) && (PicoAHW & PAHW_MCD)) cd_leds(); //gp2x_video_wait_vsync(); @@ -382,13 +340,11 @@ static void vidResetMode(void) } else if (currentConfig.EmuOpt&0x80) { gp2x_video_changemode(16); PicoDrawSetColorFormat(1); - PicoScan = EmuScan16; - PicoScan(0, 0); + PicoScanBegin = EmuScanBegin16; } else { gp2x_video_changemode(8); PicoDrawSetColorFormat(2); - PicoScan = EmuScan8; - PicoScan(0, 0); + PicoScanBegin = EmuScanBegin8; } if ((PicoOpt&0x10)||!(currentConfig.EmuOpt&0x80)) { // setup pal for 8-bit modes @@ -577,23 +533,26 @@ static void updateKeys(void) for (i = 0; i < 32; i++) { - if (keys & (1 << i)) { + if (keys & (1 << i)) + { int pl, acts = currentConfig.KeyBinds[i]; if (!acts) continue; pl = (acts >> 16) & 1; - if (combo_keys & (1 << i)) { - int u = i+1, acts_c = acts & combo_acts; + if (kb_combo_keys & (1 << i)) + { + int u = i+1, acts_c = acts & kb_combo_acts; // let's try to find the other one - if (acts_c) + if (acts_c) { for (; u < 32; u++) - if ( (currentConfig.KeyBinds[u] & acts_c) && (keys & (1 << u)) ) { - allActions[pl] |= acts_c; + if ( (keys & (1 << u)) && (currentConfig.KeyBinds[u] & acts_c) ) { + allActions[pl] |= acts_c & currentConfig.KeyBinds[u]; keys &= ~((1 << i) | (1 << u)); break; } + } // add non-combo actions if combo ones were not found if (!acts_c || u == 32) - allActions[pl] |= acts & ~combo_acts; + allActions[pl] |= acts & ~kb_combo_acts; } else { allActions[pl] |= acts; } @@ -665,8 +624,7 @@ void emu_forcedFrame(void) //vidResetMode(); PicoDrawSetColorFormat(1); - PicoScan = EmuScan16; - PicoScan(0, 0); + PicoScanBegin = EmuScanBegin16; Pico.m.dirtyPal = 1; PicoFrameDrawOnly(); @@ -690,15 +648,64 @@ static void simpleWait(int thissec, int lim_time) spend_cycles(1024); gettimeofday(&tval, 0); - if(thissec != tval.tv_sec) tval.tv_usec+=1000000; + if (thissec != tval.tv_sec) tval.tv_usec+=1000000; - while(tval.tv_usec < lim_time) + while (tval.tv_usec < lim_time) { spend_cycles(1024); gettimeofday(&tval, 0); - if(thissec != tval.tv_sec) tval.tv_usec+=1000000; + if (thissec != tval.tv_sec) tval.tv_usec+=1000000; + } +} + + +#if 0 +static void tga_dump(void) +{ +#define BYTE unsigned char +#define WORD unsigned short + struct + { + BYTE IDLength; /* 00h Size of Image ID field */ + BYTE ColorMapType; /* 01h Color map type */ + BYTE ImageType; /* 02h Image type code */ + WORD CMapStart; /* 03h Color map origin */ + WORD CMapLength; /* 05h Color map length */ + BYTE CMapDepth; /* 07h Depth of color map entries */ + WORD XOffset; /* 08h X origin of image */ + WORD YOffset; /* 0Ah Y origin of image */ + WORD Width; /* 0Ch Width of image */ + WORD Height; /* 0Eh Height of image */ + BYTE PixelDepth; /* 10h Image pixel size */ + BYTE ImageDescriptor; /* 11h Image descriptor byte */ + } __attribute__((packed)) TGAHEAD; + static unsigned short oldscr[320*240]; + FILE *f; char name[128]; int i; + + memset(&TGAHEAD, 0, sizeof(TGAHEAD)); + TGAHEAD.ImageType = 2; + TGAHEAD.Width = 320; + TGAHEAD.Height = 240; + TGAHEAD.PixelDepth = 16; + TGAHEAD.ImageDescriptor = 2<<4; // image starts at top-left + +#define CONV(X) (((X>>1)&0x7fe0)|(X&0x1f)) // 555? + + for (i = 0; i < 320*240; i++) + if(oldscr[i] != CONV(((unsigned short *)gp2x_screen)[i])) break; + if (i < 320*240) + { + for (i = 0; i < 320*240; i++) + oldscr[i] = CONV(((unsigned short *)gp2x_screen)[i]); + sprintf(name, "%05i.tga", Pico.m.frame_count); + f = fopen(name, "wb"); + if (!f) { printf("!f\n"); exit(1); } + fwrite(&TGAHEAD, 1, sizeof(TGAHEAD), f); + fwrite(oldscr, 1, 320*240*2, f); + fclose(f); } } +#endif void emu_Loop(void) @@ -707,8 +714,9 @@ void emu_Loop(void) static int PsndRate_old = 0, PicoOpt_old = 0, EmuOpt_old = 0, pal_old = 0; char fpsbuff[24]; // fps count c string struct timeval tval; // timing - int thissec = 0, frames_done = 0, frames_shown = 0, oldmodes = 0; - int target_fps, target_frametime, lim_time, vsync_offset, i; + int pframes_done, pframes_shown, pthissec; // "period" frames, used for sync + int frames_done, frames_shown, thissec; // actual frames + int oldmodes = 0, target_fps, target_frametime, lim_time, vsync_offset, i; char *notice = 0; printf("entered emu_Loop()\n"); @@ -740,7 +748,7 @@ void emu_Loop(void) scaling_update(); Pico.m.dirtyPal = 1; oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc; - find_combos(); + emu_findKeyBindCombos(); // pal/ntsc might have changed, reset related stuff target_fps = Pico.m.pal ? 50 : 60; @@ -772,7 +780,7 @@ void emu_Loop(void) } // prepare CD buffer - if (PicoMCD & 1) PicoCDBufferInit(); + if (PicoAHW & PAHW_MCD) PicoCDBufferInit(); // calc vsync offset to sync timing code with vsync if (currentConfig.EmuOpt&0x2000) { @@ -787,7 +795,10 @@ void emu_Loop(void) } else vsync_offset = 0; - // loop? + frames_done = frames_shown = thissec = + pframes_done = pframes_shown = pthissec = 0; + + // loop while (engineState == PGS_Running) { int modes; @@ -795,8 +806,8 @@ void emu_Loop(void) gettimeofday(&tval, 0); if (reset_timing) { reset_timing = 0; - thissec = tval.tv_sec; - frames_shown = frames_done = tval.tv_usec/target_frametime; + pthissec = tval.tv_sec; + pframes_shown = pframes_done = tval.tv_usec/target_frametime; } // show notice message? @@ -852,46 +863,55 @@ void emu_Loop(void) bench_fps += frames_shown; sprintf(fpsbuff, "%02i/%02i/%02i", frames_shown, bench_fps_s, (bf[0]+bf[1]+bf[2]+bf[3])>>2); #else - if (currentConfig.EmuOpt & 2) + if (currentConfig.EmuOpt & 2) { sprintf(fpsbuff, "%02i/%02i", frames_shown, frames_done); - if (fpsbuff[5] == 0) { fpsbuff[5] = fpsbuff[6] = ' '; fpsbuff[7] = 0; } + if (fpsbuff[5] == 0) { fpsbuff[5] = fpsbuff[6] = ' '; fpsbuff[7] = 0; } + } #endif + frames_shown = frames_done = 0; thissec = tval.tv_sec; + } +#ifdef PFRAMES + sprintf(fpsbuff, "%i", Pico.m.frame_count); +#endif + if (pthissec != tval.tv_sec) + { if (PsndOut == 0 && currentConfig.Frameskip >= 0) { - frames_done = frames_shown = 0; + pframes_done = pframes_shown = 0; } else { // it is quite common for this implementation to leave 1 fame unfinished // when second changes, but we don't want buffer to starve. - if(PsndOut && frames_done < target_fps && frames_done > target_fps-5) { + if(PsndOut && pframes_done < target_fps && pframes_done > target_fps-5) { updateKeys(); - SkipFrame(1); frames_done++; + SkipFrame(1); pframes_done++; } - frames_done -= target_fps; if (frames_done < 0) frames_done = 0; - frames_shown -= target_fps; if (frames_shown < 0) frames_shown = 0; - if (frames_shown > frames_done) frames_shown = frames_done; + pframes_done -= target_fps; if (pframes_done < 0) pframes_done = 0; + pframes_shown -= target_fps; if (pframes_shown < 0) pframes_shown = 0; + if (pframes_shown > pframes_done) pframes_shown = pframes_done; } + pthissec = tval.tv_sec; } -#ifdef PFRAMES - sprintf(fpsbuff, "%i", Pico.m.frame_count); -#endif - lim_time = (frames_done+1) * target_frametime + vsync_offset; - if(currentConfig.Frameskip >= 0) { // frameskip enabled + lim_time = (pframes_done+1) * target_frametime + vsync_offset; + if (currentConfig.Frameskip >= 0) // frameskip enabled + { for(i = 0; i < currentConfig.Frameskip; i++) { updateKeys(); - SkipFrame(1); frames_done++; + SkipFrame(1); pframes_done++; frames_done++; if (PsndOut && !reset_timing) { // do framelimitting if sound is enabled gettimeofday(&tval, 0); - if(thissec != tval.tv_sec) tval.tv_usec+=1000000; - if(tval.tv_usec < lim_time) { // we are too fast - simpleWait(thissec, lim_time); + if (pthissec != tval.tv_sec) tval.tv_usec+=1000000; + if (tval.tv_usec < lim_time) { // we are too fast + simpleWait(pthissec, lim_time); } } lim_time += target_frametime; } - } else if(tval.tv_usec > lim_time) { // auto frameskip + } + else if (tval.tv_usec > lim_time) // auto frameskip + { // no time left for this frame - skip if (tval.tv_usec - lim_time >= 300000) { /* something caused a slowdown for us (disk access? cache flush?) @@ -900,74 +920,16 @@ void emu_Loop(void) continue; } updateKeys(); - SkipFrame(tval.tv_usec < lim_time+target_frametime*2); frames_done++; + SkipFrame(tval.tv_usec < lim_time+target_frametime*2); pframes_done++; frames_done++; continue; } updateKeys(); PicoFrame(); -#if 0 -if (Pico.m.frame_count == 31563) { - FILE *f; - f = fopen("ram_p.bin", "wb"); - if (!f) { printf("!f\n"); exit(1); } - fwrite(Pico.ram, 1, 0x10000, f); - fclose(f); - exit(0); -} -#endif -#if 0 - // debug - { - #define BYTE unsigned char - #define WORD unsigned short - struct - { - BYTE IDLength; /* 00h Size of Image ID field */ - BYTE ColorMapType; /* 01h Color map type */ - BYTE ImageType; /* 02h Image type code */ - WORD CMapStart; /* 03h Color map origin */ - WORD CMapLength; /* 05h Color map length */ - BYTE CMapDepth; /* 07h Depth of color map entries */ - WORD XOffset; /* 08h X origin of image */ - WORD YOffset; /* 0Ah Y origin of image */ - WORD Width; /* 0Ch Width of image */ - WORD Height; /* 0Eh Height of image */ - BYTE PixelDepth; /* 10h Image pixel size */ - BYTE ImageDescriptor; /* 11h Image descriptor byte */ - } __attribute__((packed)) TGAHEAD; - static unsigned short oldscr[320*240]; - FILE *f; char name[128]; int i; - - memset(&TGAHEAD, 0, sizeof(TGAHEAD)); - TGAHEAD.ImageType = 2; - TGAHEAD.Width = 320; - TGAHEAD.Height = 240; - TGAHEAD.PixelDepth = 16; - TGAHEAD.ImageDescriptor = 2<<4; // image starts at top-left - - #define CONV(X) (((X>>1)&0x7fe0)|(X&0x1f)) // 555? - - for (i = 0; i < 320*240; i++) - if(oldscr[i] != CONV(((unsigned short *)gp2x_screen)[i])) break; - if (i < 320*240) - { - for (i = 0; i < 320*240; i++) - oldscr[i] = CONV(((unsigned short *)gp2x_screen)[i]); - sprintf(name, "%05i.tga", Pico.m.frame_count); - f = fopen(name, "wb"); - if (!f) { printf("!f\n"); exit(1); } - fwrite(&TGAHEAD, 1, sizeof(TGAHEAD), f); - fwrite(oldscr, 1, 320*240*2, f); - fclose(f); - } - } -#endif - // check time gettimeofday(&tval, 0); - if (thissec != tval.tv_sec) tval.tv_usec+=1000000; + if (pthissec != tval.tv_sec) tval.tv_usec+=1000000; if (currentConfig.Frameskip < 0 && tval.tv_usec - lim_time >= 300000) // slowdown detection reset_timing = 1; @@ -980,22 +942,23 @@ if (Pico.m.frame_count == 31563) { // we are too fast if (vsync_offset) { if (lim_time - tval.tv_usec > target_frametime/2) - simpleWait(thissec, lim_time - target_frametime/4); + simpleWait(pthissec, lim_time - target_frametime/4); gp2x_video_wait_vsync(); } else { - simpleWait(thissec, lim_time); + simpleWait(pthissec, lim_time); } } } blit(fpsbuff, notice); - frames_done++; frames_shown++; + pframes_done++; pframes_shown++; + frames_done++; frames_shown++; } change_fast_forward(0); - if (PicoMCD & 1) PicoCDBufferFree(); + if (PicoAHW & PAHW_MCD) PicoCDBufferFree(); // save SRAM if((currentConfig.EmuOpt & 1) && SRam.changed) { @@ -1012,8 +975,7 @@ if (Pico.m.frame_count == 31563) { void emu_ResetGame(void) { - PicoReset(0); + PicoReset(); reset_timing = 1; } -