frontend: update libpicofe, fix missed callbacks
[pcsx_rearmed.git] / frontend / menu.c
index 51cb377..b50f05a 100644 (file)
@@ -9,15 +9,12 @@
  */
 
 #define _GNU_SOURCE 1
-#ifdef __FreeBSD__
-#define STAT stat
-#else
-#define STAT stat64
-#endif
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#ifndef NO_DYLIB
 #include <dlfcn.h>
+#endif
 #include <zlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include "libpicofe/plat.h"
 #include "../libpcsxcore/misc.h"
 #include "../libpcsxcore/cdrom.h"
+#include "../libpcsxcore/cdrom-async.h"
 #include "../libpcsxcore/cdriso.h"
 #include "../libpcsxcore/cheat.h"
+#include "../libpcsxcore/ppf.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 #include "../plugins/dfsound/spu_config.h"
 #include "psemu_plugin_defs.h"
+#include "compiler_features.h"
 #include "arm_features.h"
 #include "revision.h"
 
 #define REARMED_BIRTHDAY_TIME 1293306830       /* 25 Dec 2010 */
+#if defined(__linux__) && (!defined(__SIZEOF_POINTER__) || __SIZEOF_POINTER__ == 4)
+#define STAT stat64
+#else
+#define STAT stat
+#endif
 
 #define array_size(x) (sizeof(x) / sizeof(x[0]))
 
@@ -89,9 +94,12 @@ typedef enum
        MA_OPT_SWFILTER,
        MA_OPT_GAMMA,
        MA_OPT_VOUT_MODE,
+       MA_OPT_VOUT_FULL,
        MA_OPT_SCANLINES,
        MA_OPT_SCANLINE_LEVEL,
        MA_OPT_CENTERING,
+       MA_OPT_OVERSCAN,
+       MA_OPT_VSYNC,
 } menu_id;
 
 static int last_vout_w, last_vout_h, last_vout_bpp;
@@ -101,12 +109,14 @@ static char last_selected_fname[MAXPATHLEN];
 static int config_save_counter, region, in_type_sel1, in_type_sel2;
 static int psx_clock;
 static int memcard1_sel = -1, memcard2_sel = -1;
+static int cd_buf_count;
 extern int g_autostateld_opt;
 static int menu_iopts[8];
 int g_opts, g_scaler, g_gamma = 100;
 int scanlines, scanline_level = 20;
 int soft_scaling, analog_deadzone; // for Caanoo
 int soft_filter;
+int in_evdev_allow_abs_only attr_weak; // FIXME
 
 #ifndef HAVE_PRE_ARMV7
 #define DEFAULT_PSX_CLOCK (10000 / CYCLE_MULT_DEFAULT)
@@ -123,8 +133,6 @@ static const char *memcards[32];
 static int bios_sel, gpu_plugsel, spu_plugsel;
 
 #ifndef UI_FEATURES_H
-#define MENU_BIOS_PATH "bios/"
-#define MENU_SHOW_VARSCALER 0
 #define MENU_SHOW_VOUTMODE 1
 #define MENU_SHOW_SCALER2 0
 #define MENU_SHOW_NUBS_BTNS 0
@@ -134,22 +142,16 @@ static int bios_sel, gpu_plugsel, spu_plugsel;
 #define MENU_SHOW_FULLSCREEN 1
 #define MENU_SHOW_VOLUME 0
 #endif
+#ifndef MENU_SHOW_VARSCALER
+#define MENU_SHOW_VARSCALER 0
+#endif
+#ifndef MENU_SHOW_VARSCALER_C
+#define MENU_SHOW_VARSCALER_C 0
+#endif
 
 static int min(int x, int y) { return x < y ? x : y; }
 static int max(int x, int y) { return x > y ? x : y; }
 
-void emu_make_path(char *buff, const char *end, int size)
-{
-       int pos, end_len;
-
-       end_len = strlen(end);
-       pos = plat_get_root_dir(buff, size);
-       strncpy(buff + pos, end, size - pos);
-       buff[size - 1] = 0;
-       if (pos + end_len > size - 1)
-               printf("Warning: path truncated: %s\n", buff);
-}
-
 static int emu_check_save_file(int slot, int *time)
 {
        char fname[MAXPATHLEN];
@@ -408,7 +410,10 @@ static const struct {
        CE_CONFIG_VAL(DisableStalls),
        CE_CONFIG_VAL(Cpu),
        CE_CONFIG_VAL(GpuListWalking),
+       CE_CONFIG_VAL(FractionalFramerate),
        CE_CONFIG_VAL(PreciseExceptions),
+       CE_CONFIG_VAL(TurboCD),
+       CE_CONFIG_VAL(SlowBoot),
        CE_INTVAL(region),
        CE_INTVAL_V(g_scaler, 3),
        CE_INTVAL(g_gamma),
@@ -431,26 +436,26 @@ static const struct {
        CE_INTVAL(memcard1_sel),
        CE_INTVAL(memcard2_sel),
        CE_INTVAL(g_autostateld_opt),
+       CE_INTVAL(cd_buf_count),
+       CE_INTVAL_N("adev0_axis0", in_adev_axis[0][0]),
+       CE_INTVAL_N("adev0_axis1", in_adev_axis[0][1]),
+       CE_INTVAL_N("adev1_axis0", in_adev_axis[1][0]),
+       CE_INTVAL_N("adev1_axis1", in_adev_axis[1][1]),
        CE_INTVAL_N("adev0_is_nublike", in_adev_is_nublike[0]),
        CE_INTVAL_N("adev1_is_nublike", in_adev_is_nublike[1]),
        CE_INTVAL_V(frameskip, 4),
-       CE_INTVAL_P(gpu_peops.iUseDither),
+       CE_INTVAL_PV(dithering, 2),
        CE_INTVAL_P(gpu_peops.dwActFixes),
-       CE_INTVAL_P(gpu_unai_old.lineskip),
-       CE_INTVAL_P(gpu_unai_old.abe_hack),
-       CE_INTVAL_P(gpu_unai_old.no_light),
-       CE_INTVAL_P(gpu_unai_old.no_blend),
+       CE_INTVAL_P(gpu_unai.old_renderer),
        CE_INTVAL_P(gpu_unai.ilace_force),
-       CE_INTVAL_P(gpu_unai.pixel_skip),
        CE_INTVAL_P(gpu_unai.lighting),
        CE_INTVAL_P(gpu_unai.fast_lighting),
        CE_INTVAL_P(gpu_unai.blending),
-       CE_INTVAL_P(gpu_unai.dithering),
        CE_INTVAL_P(gpu_unai.scale_hires),
        CE_INTVAL_P(gpu_neon.allow_interlace),
        CE_INTVAL_P(gpu_neon.enhancement_enable),
        CE_INTVAL_P(gpu_neon.enhancement_no_main),
-       CE_INTVAL_P(gpu_neon.enhancement_tex_adj),
+       CE_INTVAL_PV(gpu_neon.enhancement_tex_adj, 2),
        CE_INTVAL_P(gpu_peopsgl.bDrawDither),
        CE_INTVAL_P(gpu_peopsgl.iFilterType),
        CE_INTVAL_P(gpu_peopsgl.iFrameTexType),
@@ -464,6 +469,8 @@ static const struct {
        CE_INTVAL_P(screen_centering_type),
        CE_INTVAL_P(screen_centering_x),
        CE_INTVAL_P(screen_centering_y),
+       CE_INTVAL_P(screen_centering_h_adj),
+       CE_INTVAL_P(show_overscan),
        CE_INTVAL(spu_config.iUseReverb),
        CE_INTVAL(spu_config.iXAPitch),
        CE_INTVAL(spu_config.iUseInterpolation),
@@ -473,7 +480,7 @@ static const struct {
        CE_INTVAL(in_evdev_allow_abs_only),
        CE_INTVAL(volume_boost),
        CE_INTVAL(psx_clock),
-       CE_INTVAL(new_dynarec_hacks),
+       CE_INTVAL(ndrc_g.hacks),
        CE_INTVAL(in_enable_vibration),
 };
 
@@ -493,10 +500,14 @@ static char *get_cd_label(void)
 
 static void make_cfg_fname(char *buf, size_t size, int is_game)
 {
-       if (is_game)
-               snprintf(buf, size, "." PCSX_DOT_DIR "cfg/%.32s-%.9s.cfg", get_cd_label(), CdromId);
+       char id_buf[64];
+       if (is_game) {
+               snprintf(id_buf, sizeof(id_buf), "%.32s-%.9s.cfg",
+                       get_cd_label(), CdromId);
+               emu_make_path(buf, size, CFG_DIR, id_buf);
+       }
        else
-               snprintf(buf, size, "." PCSX_DOT_DIR "%s", cfgfile_basename);
+               emu_make_path(buf, size, PCSX_DOT_DIR, cfgfile_basename);
 }
 
 static void keys_write_all(FILE *f);
@@ -524,6 +535,8 @@ static int menu_write_config(int is_game)
                return -1;
        }
 
+       cd_buf_count = cdra_get_buf_count();
+
        for (i = 0; i < ARRAY_SIZE(config_data); i++) {
                fprintf(f, "%s = ", config_data[i].name);
                switch (config_data[i].len) {
@@ -560,7 +573,7 @@ static int menu_do_last_cd_img(int is_get)
        FILE *f;
        int i, ret = -1;
 
-       snprintf(path, sizeof(path), "." PCSX_DOT_DIR "lastcdimg.txt");
+       emu_make_path(path, sizeof(path), PCSX_DOT_DIR, "lastcdimg.txt");
        f = fopen(path, is_get ? "r" : "w");
        if (f == NULL) {
                ret = -1;
@@ -685,6 +698,7 @@ int menu_load_config(int is_game)
        }
 
        keys_load_all(cfg);
+       cdra_set_buf_count(cd_buf_count);
        ret = 0;
 fail_read:
        free(cfg);
@@ -738,7 +752,7 @@ static const char *filter_exts[] = {
        #ifdef HAVE_CHD
        "chd",
        #endif
-       "bz",  "znx", "pbp", "cbn", NULL
+       "bz",  "znx", "pbp", "cbn", "ppf", NULL
 };
 
 // rrrr rggg gggb bbbb
@@ -1104,6 +1118,10 @@ static void keys_load_all(const char *cfg)
 
 static int key_config_loop_wrap(int id, int keys)
 {
+       int d;
+
+       for (d = 0; d < IN_MAX_DEVS; d++)
+               in_set_config_int(d, IN_CFG_ANALOG_MAP_ULDR, 0);
        switch (id) {
                case MA_CTRL_PLAYER1:
                        key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 0);
@@ -1117,6 +1135,9 @@ static int key_config_loop_wrap(int id, int keys)
                default:
                        break;
        }
+       for (d = 0; d < IN_MAX_DEVS; d++)
+               in_set_config_int(d, IN_CFG_ANALOG_MAP_ULDR, 1);
+
        return 0;
 }
 
@@ -1268,22 +1289,27 @@ static int menu_loop_keyconfig(int id, int keys)
 // ------------ gfx options menu ------------
 
 static const char *men_scaler[] = {
-       "1x1", "integer scaled 2x", "scaled 4:3", "integer scaled 4:3", "fullscreen", "custom", NULL
+       "1x1", "integer scaled 2x", "scaled 4:3", "integer scaled 4:3", "fullscreen",
+#if MENU_SHOW_VARSCALER_C
+       "custom",
+#endif
+       NULL
 };
 static const char *men_soft_filter[] = { "None",
-#ifdef __ARM_NEON__
+#ifdef HAVE_NEON32
        "scale2x", "eagle2x",
 #endif
        NULL };
 static const char *men_dummy[] = { NULL };
 static const char *men_centering[] = { "Auto", "Ingame", "Borderless", "Force", NULL };
+static const char *men_overscan[] = { "OFF", "Auto", "Hack", NULL };
 static const char h_scaler[]    = "int. 2x  - scales w. or h. 2x if it fits on screen\n"
                                  "int. 4:3 - uses integer if possible, else fractional";
 static const char h_cscaler[]   = "Displays the scaler layer, you can resize it\n"
                                  "using d-pad or move it using R+d-pad";
 static const char h_soft_filter[] = "Works only if game uses low resolution modes";
 static const char h_gamma[]     = "Gamma/brightness adjustment (default 100)";
-#ifdef __ARM_NEON__
+#ifdef HAVE_NEON32
 static const char *men_scanlines[] = { "OFF", "1", "2", "3", NULL };
 static const char h_scanline_l[]  = "Scanline brightness, 0-100%";
 #endif
@@ -1313,7 +1339,7 @@ static int menu_loop_cscaler(int id, int keys)
        for (;;)
        {
                if (saved_layer && last_vout_bpp == 16) {
-                       int top_x = max(0, -g_layer_x * last_vout_h / 800) + 1;
+                       int top_x = max(0, -g_layer_x * last_vout_w / 800) + 1;
                        int top_y = max(0, -g_layer_y * last_vout_h / 480) + 1;
                        char text[128];
                        memcpy(pl_vout_buf, saved_layer, saved_layer_size);
@@ -1372,18 +1398,20 @@ static int menu_loop_cscaler(int id, int keys)
 
 static menu_entry e_menu_gfx_options[] =
 {
-       mee_enum      ("Screen centering",         MA_OPT_CENTERING, pl_rearmed_cbs.screen_centering_type, men_centering),
+       mee_enum      ("PSX Screen centering",     MA_OPT_CENTERING, pl_rearmed_cbs.screen_centering_type, men_centering),
+       mee_enum      ("Show overscan",            MA_OPT_OVERSCAN, pl_rearmed_cbs.show_overscan, men_overscan),
        mee_enum_h    ("Scaler",                   MA_OPT_VARSCALER, g_scaler, men_scaler, h_scaler),
        mee_enum      ("Video output mode",        MA_OPT_VOUT_MODE, plat_target.vout_method, men_dummy),
+       mee_onoff     ("Fullscreen mode",          MA_OPT_VOUT_FULL, plat_target.vout_fullscreen, 1),
        mee_onoff     ("Software Scaling",         MA_OPT_SCALER2, soft_scaling, 1),
-       mee_enum      ("Hardware Filter",          MA_OPT_HWFILTER, plat_target.hwfilter, men_dummy),
        mee_enum_h    ("Software Filter",          MA_OPT_SWFILTER, soft_filter, men_soft_filter, h_soft_filter),
-#ifdef __ARM_NEON__
+       mee_enum      ("Hardware Filter",          MA_OPT_HWFILTER, plat_target.hwfilter, men_dummy),
+#ifdef HAVE_NEON32
        mee_enum      ("Scanlines",                MA_OPT_SCANLINES, scanlines, men_scanlines),
        mee_range_h   ("Scanline brightness",      MA_OPT_SCANLINE_LEVEL, scanline_level, 0, 100, h_scanline_l),
 #endif
        mee_range_h   ("Gamma adjustment",         MA_OPT_GAMMA, g_gamma, 1, 200, h_gamma),
-//     mee_onoff     ("Vsync",                    0, vsync, 1),
+       mee_onoff     ("OpenGL Vsync",             MA_OPT_VSYNC, g_opts, OPT_VSYNC),
        mee_cust_h    ("Setup custom scaler",      MA_OPT_VARSCALER_C, menu_loop_cscaler, NULL, h_cscaler),
        mee_end,
 };
@@ -1399,71 +1427,34 @@ static int menu_loop_gfx_options(int id, int keys)
 
 // ------------ bios/plugins ------------
 
-#ifdef BUILTIN_GPU_NEON
-
-static const char h_gpu_neon[] =
-       "Configure built-in NEON GPU plugin";
 static const char h_gpu_neon_enhanced[] =
-       "Renders in double resolution at the cost of lower performance\n"
+       "Renders in double resolution at perf. cost\n"
        "(not available for high resolution games)";
 static const char h_gpu_neon_enhanced_hack[] =
        "Speed hack for above option (glitches some games)";
+static const char h_gpu_neon_enhanced_texadj[] =
+       "Solves some Enh. res. texture issues, some perf hit";
 static const char *men_gpu_interlace[] = { "Off", "On", "Auto", NULL };
 
 static menu_entry e_menu_plugin_gpu_neon[] =
 {
-       mee_enum      ("Enable interlace mode",      0, pl_rearmed_cbs.gpu_neon.allow_interlace, men_gpu_interlace),
        mee_onoff_h   ("Enhanced resolution",        0, pl_rearmed_cbs.gpu_neon.enhancement_enable, 1, h_gpu_neon_enhanced),
        mee_onoff_h   ("Enhanced res. speed hack",   0, pl_rearmed_cbs.gpu_neon.enhancement_no_main, 1, h_gpu_neon_enhanced_hack),
-       mee_onoff     ("Enh. res. texture adjust",   0, pl_rearmed_cbs.gpu_neon.enhancement_tex_adj, 1),
-       mee_end,
-};
-
-static int menu_loop_plugin_gpu_neon(int id, int keys)
-{
-       static int sel = 0;
-       me_loop(e_menu_plugin_gpu_neon, &sel);
-       return 0;
-}
-
-#endif
-
-static menu_entry e_menu_plugin_gpu_unai_old[] =
-{
-       mee_onoff     ("Skip every 2nd line",        0, pl_rearmed_cbs.gpu_unai_old.lineskip, 1),
-       mee_onoff     ("Abe's Odyssey hack",         0, pl_rearmed_cbs.gpu_unai_old.abe_hack, 1),
-       mee_onoff     ("Disable lighting",           0, pl_rearmed_cbs.gpu_unai_old.no_light, 1),
-       mee_onoff     ("Disable blending",           0, pl_rearmed_cbs.gpu_unai_old.no_blend, 1),
+       mee_onoff_h   ("Enh. res. texture adjust",   0, pl_rearmed_cbs.gpu_neon.enhancement_tex_adj, 1, h_gpu_neon_enhanced_texadj),
+       mee_enum      ("Enable interlace mode",      0, pl_rearmed_cbs.gpu_neon.allow_interlace, men_gpu_interlace),
        mee_end,
 };
 
-static int menu_loop_plugin_gpu_unai_old(int id, int keys)
-{
-       int sel = 0;
-       me_loop(e_menu_plugin_gpu_unai_old, &sel);
-       return 0;
-}
-
 static menu_entry e_menu_plugin_gpu_unai[] =
 {
-       mee_onoff     ("Interlace",                  0, pl_rearmed_cbs.gpu_unai.ilace_force, 1),
-       mee_onoff     ("Dithering",                  0, pl_rearmed_cbs.gpu_unai.dithering, 1),
+       mee_onoff     ("Old renderer",               0, pl_rearmed_cbs.gpu_unai.old_renderer, 1),
+       mee_onoff     ("Skip every 2nd line",        0, pl_rearmed_cbs.gpu_unai.ilace_force, 1),
        mee_onoff     ("Lighting",                   0, pl_rearmed_cbs.gpu_unai.lighting, 1),
        mee_onoff     ("Fast lighting",              0, pl_rearmed_cbs.gpu_unai.fast_lighting, 1),
        mee_onoff     ("Blending",                   0, pl_rearmed_cbs.gpu_unai.blending, 1),
-       mee_onoff     ("Pixel skip",                 0, pl_rearmed_cbs.gpu_unai.pixel_skip, 1),
        mee_end,
 };
 
-static int menu_loop_plugin_gpu_unai(int id, int keys)
-{
-       int sel = 0;
-       me_loop(e_menu_plugin_gpu_unai, &sel);
-       return 0;
-}
-
-
-static const char *men_gpu_dithering[] = { "None", "Game dependant", "Always", NULL };
 //static const char h_gpu_0[]            = "Needed for Chrono Cross";
 static const char h_gpu_1[]            = "Capcom fighting games";
 static const char h_gpu_2[]            = "Black screens in Lunar";
@@ -1476,7 +1467,6 @@ static const char h_gpu_10[]           = "Toggle busy flags after drawing";
 
 static menu_entry e_menu_plugin_gpu_peops[] =
 {
-       mee_enum      ("Dithering",                  0, pl_rearmed_cbs.gpu_peops.iUseDither, men_gpu_dithering),
 //     mee_onoff_h   ("Odd/even bit hack",          0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<0, h_gpu_0),
        mee_onoff_h   ("Expand screen width",        0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<1, h_gpu_1),
        mee_onoff_h   ("Ignore brightness color",    0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<2, h_gpu_2),
@@ -1489,13 +1479,6 @@ static menu_entry e_menu_plugin_gpu_peops[] =
        mee_end,
 };
 
-static int menu_loop_plugin_gpu_peops(int id, int keys)
-{
-       static int sel = 0;
-       me_loop(e_menu_plugin_gpu_peops, &sel);
-       return 0;
-}
-
 static const char *men_peopsgl_texfilter[] = { "None", "Standard", "Extended",
        "Standard-sprites", "Extended-sprites", "Standard+sprites", "Extended+sprites", NULL };
 static const char *men_peopsgl_fbtex[] = { "Emulated VRam", "Black", "Card", "Card+soft" };
@@ -1526,13 +1509,6 @@ static menu_entry e_menu_plugin_gpu_peopsgl[] =
        mee_end,
 };
 
-static int menu_loop_plugin_gpu_peopsgl(int id, int keys)
-{
-       static int sel = 0;
-       me_loop(e_menu_plugin_gpu_peopsgl, &sel);
-       return 0;
-}
-
 static const char *men_spu_interp[] = { "None", "Simple", "Gaussian", "Cubic", NULL };
 static const char h_spu_volboost[]  = "Large values cause distortion";
 static const char h_spu_tempo[]     = "Slows down audio if emu is too slow\n"
@@ -1555,38 +1531,75 @@ static int menu_loop_plugin_spu(int id, int keys)
        return 0;
 }
 
+static const char *men_gpu_dithering[] = { "OFF", "ON", "Force", NULL };
+
 static const char h_bios[]       = "HLE is simulated BIOS. BIOS selection is saved in\n"
                                   "savestates and can't be changed there. Must save\n"
                                   "config and reload the game for change to take effect";
 static const char h_plugin_gpu[] = 
-#ifdef BUILTIN_GPU_NEON
+#if defined(BUILTIN_GPU_NEON)
                                   "builtin_gpu is the NEON GPU, very fast and accurate\n"
+#elif defined(BUILTIN_GPU_PEOPS)
+                                  "builtin_gpu is the P.E.Op.S GPU, slow but accurate\n"
+#elif defined(BUILTIN_GPU_UNAI)
+                                  "builtin_gpu is the Unai GPU, very fast\n"
+#endif
+#ifndef NO_DYLIB
+#if !defined(BUILTIN_GPU_NEON) && defined(GPU_NEON)
+                                  "gpu_neon is Exophase's NEON GPU, fast and accurate\n"
 #endif
+#ifndef BUILTIN_GPU_PEOPS
                                   "gpu_peops is Pete's soft GPU, slow but accurate\n"
-                                  "gpu_unai_old is from old PCSX4ALL, fast but glitchy\n"
-                                  "gpu_unai is newer, more accurate but slower\n"
+#endif
+#ifndef BUILTIN_GPU_UNAI
+                                  "gpu_unai is the GPU renderer from PCSX4ALL\n"
+#endif
+#ifdef HAVE_GLES
                                   "gpu_gles Pete's hw GPU, uses 3D chip but is glitchy\n"
-                                  "must save config and reload the game if changed";
-static const char h_plugin_spu[] = "spunull effectively disables sound\n"
-                                  "must save config and reload the game if changed";
-static const char h_gpu_peops[]  = "Configure P.E.Op.S. SoftGL Driver V1.17";
-static const char h_gpu_peopsgl[]= "Configure P.E.Op.S. MesaGL Driver V1.78";
-static const char h_gpu_unai_old[] = "Configure Unai/PCSX4ALL Team GPU plugin (old)";
-static const char h_gpu_unai[]   = "Configure Unai/PCSX4ALL Team plugin (new)";
+#endif
+                                  "must save config and reload the game if changed"
+#endif
+                                  ;
+static const char h_plugin_spu[] = ""
+#ifndef NO_DYLIB
+                                  "spunull effectively disables sound\n"
+                                  "must save config and reload the game if changed"
+#endif
+;
+// static const char h_gpu_peops[]  = "Configure P.E.Op.S. SoftGL Driver V1.17";
+// static const char h_gpu_peopsgl[]= "Configure P.E.Op.S. MesaGL Driver V1.78";
+// static const char h_gpu_unai[]   = "Configure Unai/PCSX4ALL Team plugin (new)";
 static const char h_spu[]        = "Configure built-in P.E.Op.S. Sound Driver V1.7";
 
+static int menu_loop_pluginsel_options(int id, int keys)
+{
+       static int sel = 0;
+       if (strcmp(gpu_plugins[gpu_plugsel], "gpu_peops.so") == 0)
+               me_loop(e_menu_plugin_gpu_peops, &sel);
+       else if (strcmp(gpu_plugins[gpu_plugsel], "gpu_unai.so") == 0)
+               me_loop(e_menu_plugin_gpu_unai, &sel);
+       else if (strcmp(gpu_plugins[gpu_plugsel], "gpu_gles.so") == 0)
+               me_loop(e_menu_plugin_gpu_peopsgl, &sel);
+       else if (strcmp(gpu_plugins[gpu_plugsel], "gpu_neon.so") == 0)
+               me_loop(e_menu_plugin_gpu_neon, &sel);
+       else
+#if defined(BUILTIN_GPU_NEON)
+               me_loop(e_menu_plugin_gpu_neon, &sel);
+#elif defined(BUILTIN_GPU_PEOPS)
+               me_loop(e_menu_plugin_gpu_peops, &sel);
+#elif defined(BUILTIN_GPU_UNAI)
+               me_loop(e_menu_plugin_gpu_unai, &sel);
+#endif
+       return 0;
+}
+
 static menu_entry e_menu_plugin_options[] =
 {
        mee_enum_h    ("BIOS",                          0, bios_sel, bioses, h_bios),
+       mee_enum      ("GPU Dithering",                 0, pl_rearmed_cbs.dithering, men_gpu_dithering),
        mee_enum_h    ("GPU plugin",                    0, gpu_plugsel, gpu_plugins, h_plugin_gpu),
        mee_enum_h    ("SPU plugin",                    0, spu_plugsel, spu_plugins, h_plugin_spu),
-#ifdef BUILTIN_GPU_NEON
-       mee_handler_h ("Configure built-in GPU plugin", menu_loop_plugin_gpu_neon, h_gpu_neon),
-#endif
-       mee_handler_h ("Configure gpu_peops plugin",    menu_loop_plugin_gpu_peops, h_gpu_peops),
-       mee_handler_h ("Configure gpu_unai_old GPU plugin", menu_loop_plugin_gpu_unai_old, h_gpu_unai_old),
-       mee_handler_h ("Configure gpu_unai GPU plugin", menu_loop_plugin_gpu_unai, h_gpu_unai),
-       mee_handler_h ("Configure gpu_gles GPU plugin", menu_loop_plugin_gpu_peopsgl, h_gpu_peopsgl),
+       mee_handler   ("Configure selected GPU plugin", menu_loop_pluginsel_options),
        mee_handler_h ("Configure built-in SPU plugin", menu_loop_plugin_spu, h_spu),
        mee_end,
 };
@@ -1620,10 +1633,10 @@ static const char h_cfg_stalls[]  = "Will cause some games to run too fast";
 static menu_entry e_menu_speed_hacks[] =
 {
 #ifndef DRC_DISABLE
-       mee_onoff_h   ("Disable compat hacks",     0, new_dynarec_hacks, NDHACK_NO_COMPAT_HACKS, h_cfg_noch),
-       mee_onoff_h   ("Disable SMC checks",       0, new_dynarec_hacks, NDHACK_NO_SMC_CHECK, h_cfg_nosmc),
-       mee_onoff_h   ("Assume GTE regs unneeded", 0, new_dynarec_hacks, NDHACK_GTE_UNNEEDED, h_cfg_gteunn),
-       mee_onoff_h   ("Disable GTE flags",        0, new_dynarec_hacks, NDHACK_GTE_NO_FLAGS, h_cfg_gteflgs),
+       mee_onoff_h   ("Disable compat hacks",     0, ndrc_g.hacks, NDHACK_NO_COMPAT_HACKS, h_cfg_noch),
+       mee_onoff_h   ("Disable SMC checks",       0, ndrc_g.hacks, NDHACK_NO_SMC_CHECK, h_cfg_nosmc),
+       mee_onoff_h   ("Assume GTE regs unneeded", 0, ndrc_g.hacks, NDHACK_GTE_UNNEEDED, h_cfg_gteunn),
+       mee_onoff_h   ("Disable GTE flags",        0, ndrc_g.hacks, NDHACK_GTE_NO_FLAGS, h_cfg_gteflgs),
 #endif
        mee_onoff_h   ("Disable CPU/GTE stalls",   0, menu_iopts[0], 1, h_cfg_stalls),
        mee_end,
@@ -1638,7 +1651,7 @@ static int menu_loop_speed_hacks(int id, int keys)
        return 0;
 }
 
-static const char *men_gpul[]    = { "Auto", "Off", "On", NULL };
+static const char *men_autooo[]  = { "Auto", "Off", "On", NULL };
 
 static const char h_cfg_cpul[]   = "Shows CPU usage in %";
 static const char h_cfg_spu[]    = "Shows active SPU channels\n"
@@ -1657,10 +1670,13 @@ static const char h_cfg_exc[]    = "Emulate some PSX's debug hw like breakpoints
                                   "and exceptions (slow, interpreter only, keep off)";
 static const char h_cfg_gpul[]   = "Try enabling this if the game misses some graphics\n"
                                   "causes a performance hit";
+static const char h_cfg_ffps[]   = "Instead of 50/60fps for PAL/NTSC use ~49.75/59.81\n"
+                                  "Closer to real hw but doesn't match modern displays.";
+static const char h_cfg_tcd[]    = "Greatly reduce CD load times. Breaks some games.";
 static const char h_cfg_psxclk[]  = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n"
                                    "(adjust this if the game is too slow/too fast/hangs)";
 
-enum { AMO_XA, AMO_CDDA, AMO_IC, AMO_BP, AMO_CPU, AMO_GPUL };
+enum { AMO_XA, AMO_CDDA, AMO_IC, AMO_BP, AMO_CPU, AMO_GPUL, AMO_FFPS, AMO_TCD };
 
 static menu_entry e_menu_adv_options[] =
 {
@@ -1671,7 +1687,12 @@ static menu_entry e_menu_adv_options[] =
        mee_onoff_h   ("Disable CD Audio",       0, menu_iopts[AMO_CDDA], 1, h_cfg_cdda),
        mee_onoff_h   ("ICache emulation",       0, menu_iopts[AMO_IC],   1, h_cfg_icache),
        mee_onoff_h   ("BP exception emulation", 0, menu_iopts[AMO_BP],   1, h_cfg_exc),
-       mee_enum_h    ("GPU l-list slow walking",0, menu_iopts[AMO_GPUL], men_gpul, h_cfg_gpul),
+       mee_enum_h    ("GPU l-list slow walking",0, menu_iopts[AMO_GPUL], men_autooo, h_cfg_gpul),
+       mee_enum_h    ("Fractional framerate",   0, menu_iopts[AMO_FFPS], men_autooo, h_cfg_ffps),
+       mee_onoff_h   ("Turbo CD-ROM ",          0, menu_iopts[AMO_TCD], 1, h_cfg_tcd),
+#ifdef USE_ASYNC_CDROM
+       mee_range     ("CD-ROM read-ahead",      0, cd_buf_count, 0, 1024),
+#endif
 #if !defined(DRC_DISABLE) || defined(LIGHTREC)
        mee_onoff_h   ("Disable dynarec (slow!)",0, menu_iopts[AMO_CPU],  1, h_cfg_nodrc),
 #endif
@@ -1692,17 +1713,21 @@ static int menu_loop_adv_options(int id, int keys)
                { &Config.icache_emulation, &menu_iopts[AMO_IC] },
                { &Config.PreciseExceptions, &menu_iopts[AMO_BP] },
                { &Config.Cpu,     &menu_iopts[AMO_CPU] },
+               { &Config.TurboCD, &menu_iopts[AMO_TCD] },
        };
        int i;
        for (i = 0; i < ARRAY_SIZE(opts); i++)
                *opts[i].mopt = *opts[i].opt;
        menu_iopts[AMO_GPUL] = Config.GpuListWalking + 1;
+       menu_iopts[AMO_FFPS] = Config.FractionalFramerate + 1;
 
        me_loop(e_menu_adv_options, &sel);
 
        for (i = 0; i < ARRAY_SIZE(opts); i++)
                *opts[i].opt = *opts[i].mopt;
        Config.GpuListWalking = menu_iopts[AMO_GPUL] - 1;
+       Config.FractionalFramerate = menu_iopts[AMO_FFPS] - 1;
+       cdra_set_buf_count(cd_buf_count);
 
        return 0;
 }
@@ -1883,10 +1908,10 @@ static void handle_memcard_sel(void)
 {
        strcpy(Config.Mcd1, "none");
        if (memcard1_sel != 0)
-               snprintf(Config.Mcd1, sizeof(Config.Mcd1), ".%s%s", MEMCARD_DIR, memcards[memcard1_sel]);
+               emu_make_path(Config.Mcd1, sizeof(Config.Mcd1), MEMCARD_DIR, memcards[memcard1_sel]);
        strcpy(Config.Mcd2, "none");
        if (memcard2_sel != 0)
-               snprintf(Config.Mcd2, sizeof(Config.Mcd2), ".%s%s", MEMCARD_DIR, memcards[memcard2_sel]);
+               emu_make_path(Config.Mcd2, sizeof(Config.Mcd2), MEMCARD_DIR, memcards[memcard2_sel]);
        LoadMcds(Config.Mcd1, Config.Mcd2);
        draw_mc_bg();
 }
@@ -1983,8 +2008,7 @@ static void menu_bios_warn(void)
        int inp;
        static const char msg[] =
                "You don't seem to have copied any BIOS\n"
-               "files to\n"
-               MENU_BIOS_PATH "\n\n"
+               "files to\n%s\n\n"
 
                "While many games work fine with fake\n"
                "(HLE) BIOS, others (like MGS and FF8)\n"
@@ -1998,7 +2022,7 @@ static void menu_bios_warn(void)
                "Press %s or %s to continue";
        char tmp_msg[sizeof(msg) + 64];
 
-       snprintf(tmp_msg, sizeof(tmp_msg), msg,
+       snprintf(tmp_msg, sizeof(tmp_msg), msg, Config.BiosDir,
                in_get_key_name(-1, -PBTN_MOK), in_get_key_name(-1, -PBTN_MBACK));
        while (1)
        {
@@ -2056,9 +2080,7 @@ static const char credits_text[] =
        "(C) 2005-2009 PCSX-df Team\n"
        "(C) 2009-2011 PCSX-Reloaded Team\n\n"
        "ARM recompiler (C) 2009-2011 Ari64\n"
-#ifdef BUILTIN_GPU_NEON
        "ARM NEON GPU (c) 2011-2012 Exophase\n"
-#endif
        "PEOpS GPU and SPU by Pete Bernert\n"
        "  and the P.E.Op.S. team\n"
        "PCSX4ALL plugin by PCSX4ALL team\n"
@@ -2087,7 +2109,6 @@ static int reload_plugins(const char *cdimg)
        set_cd_image(cdimg);
        LoadPlugins();
        pcnt_hook_plugins();
-       NetOpened = 0;
        if (OpenPlugins() == -1) {
                menu_update_msg("failed to open plugins");
                return -1;
@@ -2147,6 +2168,18 @@ static int run_exe(void)
 static int run_cd_image(const char *fname)
 {
        int autoload_state = g_autostateld_opt;
+       size_t fname_len = strlen(fname);
+       const char *ppfname = NULL;
+       char fname2[256];
+
+       // simle ppf handling, like game.chd.ppf
+       if (4 < fname_len && fname_len < sizeof(fname2)
+           && strcasecmp(fname + fname_len - 4, ".ppf") == 0) {
+               memcpy(fname2, fname, fname_len - 4);
+               fname2[fname_len - 4] = 0;
+               ppfname = fname;
+               fname = fname2;
+       }
 
        ready_to_go = 0;
        reload_plugins(fname);
@@ -2160,6 +2193,8 @@ static int run_cd_image(const char *fname)
                menu_update_msg("unsupported/invalid CD image");
                return -1;
        }
+       if (ppfname)
+               BuildPPFCache(ppfname);
 
        SysReset();
 
@@ -2175,7 +2210,7 @@ static int run_cd_image(const char *fname)
 
        if (autoload_state) {
                unsigned int newest = 0;
-               int time, slot, newest_slot = -1;
+               int time = 0, slot, newest_slot = -1;
 
                for (slot = 0; slot < 10; slot++) {
                        if (emu_check_save_file(slot, &time)) {
@@ -2211,7 +2246,7 @@ static int romsel_run(void)
 
        printf("selected file: %s\n", fname);
 
-       new_dynarec_clear_full();
+       ndrc_clear_full();
 
        if (run_cd_image(fname) != 0)
                return -1;
@@ -2254,7 +2289,7 @@ static int swap_cd_image(void)
                menu_update_msg("failed to load cdr plugin");
                return -1;
        }
-       if (CDR_open() < 0) {
+       if (cdra_open() < 0) {
                menu_update_msg("failed to open cdr plugin");
                return -1;
        }
@@ -2272,8 +2307,8 @@ static int swap_cd_multidisk(void)
        CdromId[0] = '\0';
        CdromLabel[0] = '\0';
 
-       CDR_close();
-       if (CDR_open() < 0) {
+       cdra_close();
+       if (cdra_open() < 0) {
                menu_update_msg("failed to open cdr plugin");
                return -1;
        }
@@ -2468,7 +2503,6 @@ static void scan_bios_plugins(void)
        char fname[MAXPATHLEN];
        struct dirent *ent;
        int bios_i, gpu_i, spu_i, mc_i;
-       char *p;
        DIR *dir;
 
        bioses[0] = "HLE";
@@ -2481,7 +2515,11 @@ static void scan_bios_plugins(void)
        dir = opendir(fname);
        if (dir == NULL) {
                perror("scan_bios_plugins bios opendir");
+#ifndef NO_DYLIB
                goto do_plugins;
+#else
+               goto do_memcards;
+#endif
        }
 
        while (1) {
@@ -2515,6 +2553,7 @@ static void scan_bios_plugins(void)
 
        closedir(dir);
 
+#ifndef NO_DYLIB
 do_plugins:
        snprintf(fname, sizeof(fname), "%s/", Config.PluginsDir);
        dir = opendir(fname);
@@ -2525,6 +2564,7 @@ do_plugins:
 
        while (1) {
                void *h, *tmp;
+               char *p;
 
                errno = 0;
                ent = readdir(dir);
@@ -2566,9 +2606,11 @@ do_plugins:
        }
 
        closedir(dir);
+#endif
 
 do_memcards:
-       dir = opendir("." MEMCARD_DIR);
+       emu_make_path(fname, sizeof(fname), MEMCARD_DIR, NULL);
+       dir = opendir(fname);
        if (dir == NULL) {
                perror("scan_bios_plugins memcards opendir");
                return;
@@ -2588,7 +2630,7 @@ do_memcards:
                if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
                        continue;
 
-               snprintf(fname, sizeof(fname), "." MEMCARD_DIR "%s", ent->d_name);
+               emu_make_path(fname, sizeof(fname), MEMCARD_DIR, ent->d_name);
                if (stat(fname, &st) != 0) {
                        printf("bad memcard file: %s\n", ent->d_name);
                        continue;
@@ -2632,7 +2674,7 @@ void menu_init(void)
                exit(1);
        }
 
-       emu_make_path(buff, "skin/background.png", sizeof(buff));
+       emu_make_data_path(buff, "skin/background.png", sizeof(buff));
        readpng(g_menubg_src_ptr, buff, READPNG_BG, g_menuscreen_w, g_menuscreen_h);
 
        i = plat_target.cpu_clock_set != NULL
@@ -2644,20 +2686,27 @@ void menu_init(void)
        me_enable(e_menu_gfx_options, MA_OPT_VOUT_MODE,
                plat_target.vout_methods != NULL);
 
+#ifndef SDL_OVERLAY_2X
+       i = me_id2offset(e_menu_gfx_options, MA_OPT_VOUT_FULL);
+       e_menu_gfx_options[i].data = plat_target.vout_methods;
+       me_enable(e_menu_gfx_options, MA_OPT_VOUT_FULL, 0);
+#endif
+
        i = me_id2offset(e_menu_gfx_options, MA_OPT_HWFILTER);
        e_menu_gfx_options[i].data = plat_target.hwfilters;
-       me_enable(e_menu_gfx_options, MA_OPT_HWFILTER,
-               plat_target.hwfilters != NULL);
-
-       me_enable(e_menu_gfx_options, MA_OPT_GAMMA,
-               plat_target.gamma_set != NULL);
+       me_enable(e_menu_gfx_options, MA_OPT_HWFILTER, plat_target.hwfilters != NULL);
+       if (plat_target.hwfilters && !strcmp(plat_target.hwfilters[0], "linear"))
+               e_menu_gfx_options[i].name = "OpenGL filter";
+       else
+               me_enable(e_menu_gfx_options, MA_OPT_VSYNC, 0);
 
-#ifdef HAVE_PRE_ARMV7
+       me_enable(e_menu_gfx_options, MA_OPT_GAMMA, plat_target.gamma_set != NULL);
+#ifndef HAVE_NEON32
        me_enable(e_menu_gfx_options, MA_OPT_SWFILTER, 0);
 #endif
        me_enable(e_menu_gfx_options, MA_OPT_VARSCALER, MENU_SHOW_VARSCALER);
        me_enable(e_menu_gfx_options, MA_OPT_VOUT_MODE, MENU_SHOW_VOUTMODE);
-       me_enable(e_menu_gfx_options, MA_OPT_VARSCALER_C, MENU_SHOW_VARSCALER);
+       me_enable(e_menu_gfx_options, MA_OPT_VARSCALER_C, MENU_SHOW_VARSCALER_C);
        me_enable(e_menu_gfx_options, MA_OPT_SCALER2, MENU_SHOW_SCALER2);
        me_enable(e_menu_keyconfig, MA_CTRL_NUBS_BTNS, MENU_SHOW_NUBS_BTNS);
        me_enable(e_menu_keyconfig, MA_CTRL_VIBRATION, MENU_SHOW_VIBRATION);
@@ -2721,18 +2770,12 @@ void menu_prepare_emu(void)
                prev_cpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, NULL);
                prev_cpu->Shutdown();
                psxCpu->Init();
-               psxCpu->Reset();
                psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL);
        }
 
        menu_sync_config();
        psxCpu->ApplyConfig();
 
-       // core doesn't care about Config.Cdda changes,
-       // so handle them manually here
-       if (Config.Cdda)
-               CDR_stop();
-
        if (cpu_clock > 0)
                plat_target_cpu_clock_set(cpu_clock);