X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=fceu.git;a=blobdiff_plain;f=drivers%2Fpandora%2Fpandora.c;h=c89681819832d494a8b71ca4583792be0edd751b;hp=86f74b4640249b4dd0bfc475a46598d28a0bcb92;hb=158d88bade9b4fc038e1c9cee3924f3c89a70caa;hpb=b054fd778fa1b8b16862bb0c9961067f30fdd608 diff --git a/drivers/pandora/pandora.c b/drivers/pandora/pandora.c index 86f74b4..c896818 100644 --- a/drivers/pandora/pandora.c +++ b/drivers/pandora/pandora.c @@ -16,6 +16,8 @@ #include "../common/args.h" #include "../../video.h" #include "../arm/asmutils.h" +#include "../arm/neon_scale2x.h" +#include "../arm/neon_eagle2x.h" #include "../libpicofe/input.h" #include "../libpicofe/plat.h" #include "../libpicofe/menu.h" @@ -28,6 +30,20 @@ static struct vout_fbdev *main_fb, *layer_fb; static void *layer_buf; static int bounce_buf[320 * 241 / 4]; static unsigned short pal[256]; +static unsigned int pal2[256]; // for neon_*2x + +enum scaling { + SCALING_1X = 0, + SCALING_PROPORTIONAL, + SCALING_4_3, + SCALING_FULLSCREEN, +}; + +enum sw_filter { + SWFILTER_NONE = 0, + SWFILTER_SCALE2X, + SWFILTER_EAGLE2X, +}; static const struct in_default_bind in_evdev_defbinds[] = { { KEY_UP, IN_BINDTYPE_PLAYER12, NKEYB_UP }, @@ -40,6 +56,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 } }; @@ -70,8 +93,8 @@ static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h) perror("SETUP_PLANE"); } - if (mi.size < 640*512*3*3) { - mi.size = 640*512*3*3; + if (mi.size < 256*2*240*2*3) { + mi.size = 256*2*240*2*3; ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi); if (ret != 0) { perror("SETUP_MEM"); @@ -111,6 +134,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) @@ -151,8 +175,8 @@ void platform_init(void) g_menuscreen_h = h; g_menuscreen_ptr = vout_fbdev_flip(main_fb); - w = 640; - h = 512; + w = 256*2; + h = 240*2; layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 3); if (layer_fb == NULL) { fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name); @@ -166,7 +190,6 @@ void platform_init(void) } plat_target_init(); - omap_enable_layer(1); XBuf = (void *)bounce_buf; @@ -211,7 +234,9 @@ int InitVideo(void) // 16: rrrr rggg gg0b bbbb void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b) { - pal[index] = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); + unsigned int v = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); + pal[index] = v; + pal2[index] = v; } void FCEUD_GetPalette(uint8 index, uint8 *r, uint8 *g, uint8 *b) @@ -224,6 +249,10 @@ void FCEUD_GetPalette(uint8 index, uint8 *r, uint8 *g, uint8 *b) void BlitPrepare(int skip) { + unsigned char *s; + unsigned short *d; + int *p, i; + if (skip) return; @@ -236,38 +265,170 @@ 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); } + + /* this is called before throttle, so we blit here too */ + s = (unsigned char *)bounce_buf + 32; + d = (unsigned short *)layer_buf; + + switch (Settings.sw_filter) + { + case SWFILTER_SCALE2X: + neon_scale2x_8_16(s, d, pal2, 256, 320, 256*2*2, 240); + break; + case SWFILTER_EAGLE2X: + neon_eagle2x_8_16(s, d, pal2, 256, 320, 256*2*2, 240); + break; + case SWFILTER_NONE: + default: + for (i = 0; i < 239; i++, d += 256, s += 320) + do_clut(d, s, pal, 256); + break; + } + + layer_buf = vout_fbdev_flip(layer_fb); } void BlitScreen(int skip) { - char *s = (char *)bounce_buf + 32; - short *d = (short *)layer_buf; - int i; +} - if (skip) - return; +/* 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 - for (i = 0; i < 239; i++, d += 256, s += 320) - do_clut(d, s, pal, 256); - - layer_buf = vout_fbdev_flip(layer_fb); +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) { + static int old_layer_w, old_layer_h; + int fb_w = 256, fb_h = 240; + float mult; + + if (Settings.sw_filter == SWFILTER_SCALE2X + || Settings.sw_filter == SWFILTER_EAGLE2X) + { + fb_w *= 2; + fb_h *= 2; + } + + if (fb_w != old_layer_w || fb_h != old_layer_h) + { + layer_buf = vout_fbdev_resize(layer_fb, fb_w, fb_h, 16, + 0, 0, 0, 0, 3); + if (layer_buf == NULL) { + fprintf(stderr, "fatal: mode change %dx%x -> %dx%d failed\n", + old_layer_w, old_layer_h, fb_w, fb_h); + exit(1); + } + + old_layer_w = fb_w; + old_layer_h = fb_h; + } + + switch (Settings.scaling) + { + case SCALING_1X: + g_layer_w = fb_w; + g_layer_h = fb_h; + break; + case SCALING_PROPORTIONAL: + // assumes screen width > height + mult = (float)g_menuscreen_h / fb_h; + g_layer_w = (int)(fb_w * mult); + g_layer_h = g_menuscreen_h; + break; + case SCALING_FULLSCREEN: + g_layer_w = g_menuscreen_w; + g_layer_h = g_menuscreen_h; + break; + case SCALING_4_3: + default: + g_layer_w = g_menuscreen_h * 4 / 3; + 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 +437,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 +480,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=""; @@ -311,6 +498,11 @@ void GetBaseDirectory(char *BaseDirectory) strcpy(BaseDirectory, "fceultra"); } +void platform_get_def_rompath(char *buf, int size) +{ + strcpy(buf, "/media"); +} + void platform_finish(void) { omap_enable_layer(0);