integrate M-HT's neon scalers
authornotaz <notasas@gmail.com>
Sun, 16 Sep 2012 20:27:40 +0000 (23:27 +0300)
committernotaz <notasas@gmail.com>
Sun, 16 Sep 2012 20:32:31 +0000 (23:32 +0300)
Makefile.pandora
drivers/arm/neon_eagle2x.S
drivers/arm/neon_scale2x.S
drivers/common/main.c
drivers/common/menu.c
drivers/common/settings.h
drivers/pandora/pandora.c

index ee90099..4364f1f 100644 (file)
@@ -4,6 +4,7 @@ AS      = $(CROSS_COMPILE)as
 STRIP  = $(CROSS_COMPILE)strip
 TFLAGS  = -Winline -Izlib -DLSB_FIRST -DUNIX -DPSS_STYLE=1 -DHAVE_ASPRINTF -DZLIB -DFRAMESKIP -D_REENTRANT
 RM     = rm -f
+A      = drivers/arm/
 C      = drivers/common/
 L      = drivers/libpicofe/
 
@@ -15,7 +16,7 @@ else
 TFLAGS += -O2
 LDRIVER        += -O2
 endif
-ASFLAGS += -mcpu=cortex-a8
+ASFLAGS += -mcpu=cortex-a8 -mfpu=neon
 NOSTRIP = 1
 asm_6502=1
 
@@ -23,7 +24,8 @@ all:          fceu
 
 include zlib/Makefile
 
-OBJDRIVER = drivers/pandora/pandora.o drivers/arm/asmutils.o \
+OBJDRIVER = drivers/pandora/pandora.o \
+       ${A}asmutils.o ${A}neon_scale2x.o ${A}neon_eagle2x.o \
        ${L}fonts.o ${L}readpng.o ${L}input.o ${L}config_file.o \
        ${L}linux/in_evdev.o ${L}linux/plat.o ${L}linux/sndout_oss.o \
        ${L}linux/fbdev.o ${L}linux/xenv.o ${L}pandora/plat.o \
index c4e96c2..aa70021 100644 (file)
@@ -22,8 +22,8 @@
 \r
 .arm\r
 \r
-.include "neon_eagle2x.Sinc"\r
-.include "neon_normalxx.Sinc"\r
+#include "neon_eagle2x.Sinc"\r
+#include "neon_normalxx.Sinc"\r
 \r
 .global neon_eagle2x_8_8\r
 .global neon_eagle2x_16_16\r
index 5df6ee5..5c68cc6 100644 (file)
@@ -22,8 +22,8 @@
 \r
 .arm\r
 \r
-.include "neon_scale2x.Sinc"\r
-.include "neon_normalxx.Sinc"\r
+#include "neon_scale2x.Sinc"\r
+#include "neon_normalxx.Sinc"\r
 \r
 .global neon_scale2x_8_8\r
 .global neon_scale2x_16_16\r
index 60d4f1d..bc2ef06 100644 (file)
@@ -60,6 +60,7 @@ CFGSTRUCT DriverConfig[]={
        AC(Settings.gamma),
        AC(Settings.perfect_vsync),
        AC(Settings.accurate_mode),
+       AC(Settings.sw_filter),
        AC(Settings.hw_filter),
        ENDCFGSTRUCT
 };
index f2b9916..4184b2e 100644 (file)
@@ -57,8 +57,9 @@ typedef enum
        MA_OPT_GG,
        MA_OPT_SHOWFPS,
        MA_OPT_FSKIP,
-       MA_OPT_SCALING,
+       MA_OPT_SWFILTER,
        MA_OPT_HWFILTER,
+       MA_OPT_SCALING,
        MA_OPT_RENDERER,
        MA_OPT_SOUNDON,
        MA_OPT_SOUNDRATE,
@@ -428,6 +429,7 @@ static int menu_loop_fceu_options(int id, int keys)
 // -------------- options --------------
 
 static const char *men_frameskip[] = { "Auto", "0", "1", "2", "3", "4", NULL };
+static const char *men_swfilter[] = { "none", "Scale2x", "Eagle2x", 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 };
@@ -456,7 +458,8 @@ static menu_entry e_menu_options[] =
 {
 //     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       ("Softwere filter",         MA_OPT_SWFILTER, Settings.sw_filter, men_swfilter),
+       mee_enum       ("Hardware 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),
@@ -512,7 +515,8 @@ static const char credits_text[] =
        "         - Credits -\n"
        "Bero: FCE\n"
        "Xodnizel: FCE Ultra\n"
-       "FCA author: 6502 core\n";
+       "FCA author: 6502 core\n"
+       "M-HT: NEON scalers\n";
 
 static void draw_frame_credits(void)
 {
index ae87993..e8e6122 100644 (file)
@@ -17,6 +17,7 @@ typedef struct {
        int perfect_vsync;
        // pandora
        int hw_filter;
+       int sw_filter;
 } DSETTINGS;
 
 extern DSETTINGS Settings;
index 2ea239e..115e7b7 100644 (file)
@@ -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,14 +30,21 @@ 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,
+       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 },
   { KEY_DOWN,     IN_BINDTYPE_PLAYER12, NKEYB_DOWN },
@@ -84,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");
@@ -166,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);
@@ -225,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)
@@ -238,8 +249,8 @@ void FCEUD_GetPalette(uint8 index, uint8 *r, uint8 *g, uint8 *b)
 
 void BlitPrepare(int skip)
 {
-       char *s;
-       short *d;
+       unsigned char *s;
+       unsigned short *d;
        int *p, i;
 
        if (skip)
@@ -266,11 +277,23 @@ void BlitPrepare(int skip)
        }
 
        /* this is called before throttle, so we blit here too */
-       s = (char *)bounce_buf + 32;
-       d = (short *)layer_buf;
+       s = (unsigned char *)bounce_buf + 32;
+       d = (unsigned short *)layer_buf;
 
-       for (i = 0; i < 239; i++, d += 256, s += 320)
-               do_clut(d, s, pal, 256);
+       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);
 }
@@ -345,28 +368,52 @@ void SpeedThrottle(void)
 /* 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 = 256;
-               g_layer_h = 240;
+               g_layer_w = fb_w;
+               g_layer_h = fb_h;
                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;
+               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;