X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=fceu.git;a=blobdiff_plain;f=drivers%2Fpandora%2Fpandora.c;fp=drivers%2Fpandora%2Fpandora.c;h=2ea239e915d120019d907376c03ca625b0755d85;hp=86f74b4640249b4dd0bfc475a46598d28a0bcb92;hb=44343b8775fd8c9cfa1a2f865be369e09d1984ff;hpb=e4434f79e73411f4d069831cb813f7db1b1f933b diff --git a/drivers/pandora/pandora.c b/drivers/pandora/pandora.c index 86f74b4..2ea239e 100644 --- a/drivers/pandora/pandora.c +++ b/drivers/pandora/pandora.c @@ -29,6 +29,13 @@ static void *layer_buf; static int bounce_buf[320 * 241 / 4]; static unsigned short pal[256]; +enum scaling { + SCALING_1X, + SCALING_PROPORTIONAL, + SCALING_4_3, + SCALING_FULLSCREEN, +}; + static const struct in_default_bind in_evdev_defbinds[] = { { KEY_UP, IN_BINDTYPE_PLAYER12, NKEYB_UP }, { KEY_DOWN, IN_BINDTYPE_PLAYER12, NKEYB_DOWN }, @@ -40,6 +47,13 @@ static const struct in_default_bind in_evdev_defbinds[] = { { KEY_PAGEUP, IN_BINDTYPE_PLAYER12, NKEYB_A_TURBO }, { KEY_LEFTCTRL, IN_BINDTYPE_PLAYER12, NKEYB_SELECT }, { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, NKEYB_START }, + { KEY_1, IN_BINDTYPE_EMU, EACTB_SAVE_STATE }, + { KEY_2, IN_BINDTYPE_EMU, EACTB_LOAD_STATE }, + { KEY_3, IN_BINDTYPE_EMU, EACTB_PREV_SLOT }, + { KEY_4, IN_BINDTYPE_EMU, EACTB_NEXT_SLOT }, + { KEY_5, IN_BINDTYPE_EMU, EACTB_FDS_INSERT }, + { KEY_6, IN_BINDTYPE_EMU, EACTB_FDS_SELECT }, + { KEY_7, IN_BINDTYPE_EMU, EACTB_INSERT_COIN }, { KEY_SPACE, IN_BINDTYPE_EMU, EACTB_ENTER_MENU }, { 0, 0, 0 } }; @@ -111,6 +125,7 @@ void platform_init(void) Settings.turbo_rate_add = (8*2 << 24) / 60 + 1; // 8Hz turbofire Settings.gamma = 100; Settings.sstate_confirm = 1; + Settings.scaling = SCALING_4_3; main_fb_name = getenv("FBDEV_MAIN"); if (main_fb_name == NULL) @@ -166,7 +181,6 @@ void platform_init(void) } plat_target_init(); - omap_enable_layer(1); XBuf = (void *)bounce_buf; @@ -224,6 +238,10 @@ void FCEUD_GetPalette(uint8 index, uint8 *r, uint8 *g, uint8 *b) void BlitPrepare(int skip) { + char *s; + short *d; + int *p, i; + if (skip) return; @@ -236,29 +254,20 @@ void BlitPrepare(int skip) } } - if (Settings.accurate_mode) + p = bounce_buf + 32/4; + if (srendline > 0) + for (i = srendline; i > 0; i--, p += 320/4) + memset(p, 0, 256); + if (erendline < 239) { - int i, *p = bounce_buf + 32/4; - if (srendline > 0) - for (i = srendline; i > 0; i--, p += 320/4) - memset(p, 0, 256); - if (erendline < 239) - { - int *p = bounce_buf + erendline*320/4 + 32/4; - for (i = 239-srendline; i > 0; i--, p += 320/4) - memset(p, 0, 256); - } + p = bounce_buf + erendline*320/4 + 32/4; + for (i = 239-erendline; i > 0; i--, p += 320/4) + memset(p, 0, 256); } -} -void BlitScreen(int skip) -{ - char *s = (char *)bounce_buf + 32; - short *d = (short *)layer_buf; - int i; - - if (skip) - return; + /* this is called before throttle, so we blit here too */ + s = (char *)bounce_buf + 32; + d = (short *)layer_buf; for (i = 0; i < 239; i++, d += 256, s += 320) do_clut(d, s, pal, 256); @@ -266,8 +275,113 @@ void BlitScreen(int skip) layer_buf = vout_fbdev_flip(layer_fb); } +void BlitScreen(int skip) +{ +} + +/* throttle */ +extern uint8 PAL; +extern int FSkip; +static struct timeval tv_expect; +static int skip_count = 0; +static int us_interval, us_interval1024; +#define MAX_LAG_FRAMES 3 + +void RefreshThrottleFPS(void) +{ + skip_count = 0; + us_interval = PAL ? 20000 : 16667; + us_interval1024 = PAL ? 20000*1024 : 17066667; + + vout_fbdev_wait_vsync(layer_fb); + gettimeofday(&tv_expect, 0); + tv_expect.tv_usec *= 1024; +} + +void SpeedThrottle(void) +{ + struct timeval now; + int diff; + + gettimeofday(&now, 0); + + // usec*1024 units to prevent drifting + tv_expect.tv_usec += us_interval1024; + if (tv_expect.tv_usec > 1000000 * 1024) { + tv_expect.tv_usec -= 1000000 * 1024; + tv_expect.tv_sec++; + } + + diff = (tv_expect.tv_sec - now.tv_sec) * 1000000 + + (tv_expect.tv_usec >> 10) - now.tv_usec; + + if (Settings.frameskip >= 0) + { + if (skip_count >= Settings.frameskip) + skip_count = 0; + else { + skip_count++; + FSkip = 1; + } + } + else + { + FSkip = diff < -us_interval; + } + + if (diff > MAX_LAG_FRAMES * us_interval + || diff < -MAX_LAG_FRAMES * us_interval) + { + //printf("reset %d\n", diff); + RefreshThrottleFPS(); + return; + } + else if (diff > us_interval) + { + usleep(diff - us_interval); + } +} + +/* called just before emulation */ void platform_apply_config(void) { + float mult; + + switch (Settings.scaling) + { + case SCALING_1X: + g_layer_w = 256; + g_layer_h = 240; + break; + case SCALING_PROPORTIONAL: + // assumes screen width > height + mult = (float)g_menuscreen_h / 240; + g_layer_w = (int)(256 * mult); + g_layer_h = g_menuscreen_h; + break; + case SCALING_4_3: + g_layer_w = g_menuscreen_h * 4 / 3; + g_layer_h = g_menuscreen_h; + break; + case SCALING_FULLSCREEN: + g_layer_w = g_menuscreen_w; + g_layer_h = g_menuscreen_h; + break; + } + if (g_layer_w > g_menuscreen_w) + g_layer_w = g_menuscreen_w; + if (g_layer_h > g_menuscreen_h) + g_layer_h = g_menuscreen_h; + g_layer_x = g_menuscreen_w / 2 - g_layer_w / 2; + g_layer_y = g_menuscreen_h / 2 - g_layer_h / 2; + + plat_target_set_filter(Settings.hw_filter); + plat_target_set_lcdrate(PAL); + + // adjust since we run at 60Hz, and real NES doesn't + FCEUI_Sound(Settings.sound_rate + Settings.sound_rate / 980); + + omap_enable_layer(1); } void platform_set_volume(int val) @@ -276,7 +390,34 @@ void platform_set_volume(int val) void plat_video_menu_enter(int is_rom_loaded) { + unsigned short *d = g_menubg_src_ptr; + unsigned char *s, *sr = (void *)bounce_buf; + int u, v = 240 / 2; + int x, y, w; + omap_enable_layer(0); + + if (!fceugi) + return; + + for (y = 0; y < g_menuscreen_h; y++) + { + s = sr + v * 320 + 32; + u = 256 / 2; + for (x = 0; x < g_menuscreen_w; ) + { + w = g_menuscreen_w - x; + if (w > 256 - u) + w = 256 - u; + do_clut(d + x, s + u, pal, w); + u = (u + w) & 255; + x += w; + } + d += x; + v++; + if (v > erendlinev[PAL]) + v = srendlinev[PAL]; + } } void plat_video_menu_begin(void) @@ -292,8 +433,7 @@ void plat_video_menu_leave(void) { memset(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2); g_menuscreen_ptr = vout_fbdev_flip(main_fb); - - omap_enable_layer(1); + // layer enabled in platform_apply_config() } char *DriverUsage="";