MA_OPT_GG,
MA_OPT_SHOWFPS,
MA_OPT_FSKIP,
+ MA_OPT_SCALING,
+ MA_OPT_HWFILTER,
MA_OPT_RENDERER,
MA_OPT_SOUNDON,
MA_OPT_SOUNDRATE,
// -------------- options --------------
static const char *men_frameskip[] = { "Auto", "0", "1", "2", "3", "4", NULL };
+static const char *men_scaling[] = { "1x", "proportional", "4:3 scaled", "fullscreen", NULL };
static const char *men_rates[] = { "8000", "11025", "16000", "22050", "44100", NULL };
static const int men_rates_i[] = { 8000 , 11025 , 16000 , 22050 , 44100 };
static const char *men_region[] = { "Auto", "NTSC", "PAL", NULL };
static menu_entry e_menu_options[] =
{
- mee_onoff ("Show FPS", MA_OPT_SHOWFPS, Settings.showfps, 1),
+// mee_onoff ("Show FPS", MA_OPT_SHOWFPS, Settings.showfps, 1),
mee_enum ("Frameskip", MA_OPT_FSKIP, frameskip_i, men_frameskip),
+ mee_enum ("HW filter", MA_OPT_HWFILTER, Settings.hw_filter, NULL),
+ mee_enum ("Scaling", MA_OPT_SCALING, Settings.scaling, men_scaling),
mee_onoff_h ("Accurate renderer (slow)",MA_OPT_RENDERER, Settings.accurate_mode, 1, h_renderer),
mee_onoff ("Enable sound", MA_OPT_SOUNDON, sndon, 1),
mee_enum ("Sound Rate", MA_OPT_SOUNDRATE, sndrate_i, men_rates),
mee_range ("Turbo rate (Hz)", MA_OPT_TURBO, turbo_i, 1, 30),
mee_enum ("Confirm savestate", MA_OPT_SSTATE, Settings.sstate_confirm, men_sstate),
mee_range ("Save slot", MA_OPT_SSLOT, CurrentState, 0, 9),
- mee_range ("Gamma correction", MA_OPT_GAMMA, Settings.gamma, 0, 300),
+// mee_range ("Gamma correction", MA_OPT_GAMMA, Settings.gamma, 0, 300),
mee_handler ("[FCE Ultra options]", menu_loop_fceu_options),
mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg),
mee_cust_nosave("Save cfg for loaded game",MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg),
int oldrate;
int i;
+ i = me_id2offset(e_menu_options, MA_OPT_HWFILTER);
+ e_menu_options[i].data = plat_target.filters;
+ me_enable(e_menu_options, MA_OPT_HWFILTER, plat_target.filters != NULL);
+
oldrate = Settings.sound_rate;
for (i = 0; i < array_size(men_rates_i); i++) {
if (Settings.sound_rate == men_rates_i[i]) {
me_enable(e_menu_main, MA_MAIN_CHEATS, fceugi && cheats);
plat_video_menu_enter(fceugi != NULL);
+ memcpy(g_menubg_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2);
in_set_config_int(0, IN_CFG_BLOCKING, 1);
do {
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 },
{ 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 }
};
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)
}
plat_target_init();
- omap_enable_layer(1);
XBuf = (void *)bounce_buf;
void BlitPrepare(int skip)
{
+ char *s;
+ short *d;
+ int *p, i;
+
if (skip)
return;
}
}
- 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);
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)
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)
{
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="";