fully reinit drc on change
[pcsx_rearmed.git] / frontend / menu.c
index d3ce06c..eb004d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * (C) Gražvydas "notaz" Ignotas, 2010-2011
+ * (C) Gražvydas "notaz" Ignotas, 2010-2013
  *
  * This work is licensed under the terms of any of these licenses
  * (at your option):
  *
  * This work is licensed under the terms of any of these licenses
  * (at your option):
@@ -8,6 +8,7 @@
  * See the COPYING file in the top-level directory.
  */
 
  * See the COPYING file in the top-level directory.
  */
 
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
@@ -16,6 +17,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <dirent.h>
 
 #include "main.h"
 #include "menu.h"
 
 #include "main.h"
 #include "menu.h"
 #include "plugin_lib.h"
 #include "plat.h"
 #include "pcnt.h"
 #include "plugin_lib.h"
 #include "plat.h"
 #include "pcnt.h"
-#include "common/plat.h"
-#include "common/input.h"
-#include "linux/in_evdev.h"
+#include "libpicofe/plat.h"
+#include "libpicofe/input.h"
+#include "libpicofe/linux/in_evdev.h"
+#include "libpicofe/plat.h"
 #include "../libpcsxcore/misc.h"
 #include "../libpcsxcore/cdrom.h"
 #include "../libpcsxcore/cdriso.h"
 #include "../libpcsxcore/cheat.h"
 #include "../libpcsxcore/misc.h"
 #include "../libpcsxcore/cdrom.h"
 #include "../libpcsxcore/cdriso.h"
 #include "../libpcsxcore/cheat.h"
-#include "../libpcsxcore/psemu_plugin_defs.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
-#include "../plugins/dfinput/main.h"
+#include "../plugins/dfinput/externals.h"
 #include "../plugins/gpulib/cspace.h"
 #include "../plugins/gpulib/cspace.h"
+#include "psemu_plugin_defs.h"
 #include "revision.h"
 
 #define REARMED_BIRTHDAY_TIME 1293306830       /* 25 Dec 2010 */
 #include "revision.h"
 
 #define REARMED_BIRTHDAY_TIME 1293306830       /* 25 Dec 2010 */
@@ -72,23 +75,24 @@ typedef enum
        MA_OPT_SAVECFG_GAME,
        MA_OPT_CPU_CLOCKS,
        MA_OPT_DISP_OPTS,
        MA_OPT_SAVECFG_GAME,
        MA_OPT_CPU_CLOCKS,
        MA_OPT_DISP_OPTS,
-       MA_OPT_SCALER,
+       MA_OPT_VARSCALER,
+       MA_OPT_VARSCALER_C,
        MA_OPT_SCALER2,
        MA_OPT_SCALER2,
-       MA_OPT_FILTERING,
-       MA_OPT_FILTERING2,
-       MA_OPT_SCALER_C,
+       MA_OPT_HWFILTER,
+       MA_OPT_SWFILTER,
+       MA_OPT_GAMMA,
+       MA_OPT_VOUT_MODE,
 } menu_id;
 
 static int last_vout_w, last_vout_h, last_vout_bpp;
 static int cpu_clock, cpu_clock_st, volume_boost, frameskip;
 } menu_id;
 
 static int last_vout_w, last_vout_h, last_vout_bpp;
 static int cpu_clock, cpu_clock_st, volume_boost, frameskip;
-static char rom_fname_reload[MAXPATHLEN];
 static char last_selected_fname[MAXPATHLEN];
 static char last_selected_fname[MAXPATHLEN];
-static int warned_about_bios, region, in_type_sel1, in_type_sel2;
+static int config_save_counter, region, in_type_sel1, in_type_sel2;
 static int psx_clock;
 static int memcard1_sel, memcard2_sel;
 static int psx_clock;
 static int memcard1_sel, memcard2_sel;
-int g_opts, g_scaler;
+int g_opts, g_scaler, g_gamma = 100;
 int soft_scaling, analog_deadzone; // for Caanoo
 int soft_scaling, analog_deadzone; // for Caanoo
-int filter, soft_filter;
+int soft_filter;
 
 #ifdef __ARM_ARCH_7A__
 #define DEFAULT_PSX_CLOCK 57
 
 #ifdef __ARM_ARCH_7A__
 #define DEFAULT_PSX_CLOCK 57
@@ -110,6 +114,18 @@ static const char *spu_plugins[16];
 static const char *memcards[32];
 static int bios_sel, gpu_plugsel, spu_plugsel;
 
 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
+#define MENU_SHOW_VIBRATION 0
+#define MENU_SHOW_DEADZONE 0
+#define MENU_SHOW_MINIMIZE 0
+#define MENU_SHOW_FULLSCREEN 1
+#define MENU_SHOW_VOLUME 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; }
 
 static int min(int x, int y) { return x < y ? x : y; }
 static int max(int x, int y) { return x > y ? x : y; }
@@ -172,6 +188,107 @@ static int emu_save_load_game(int load, int unused)
        return ret;
 }
 
        return ret;
 }
 
+static void rm_namelist_entry(struct dirent **namelist,
+       int count, const char *name)
+{
+       int i;
+
+       for (i = 1; i < count; i++) {
+               if (namelist[i] == NULL || namelist[i]->d_type == DT_DIR)
+                       continue;
+
+               if (strcmp(name, namelist[i]->d_name) == 0) {
+                       free(namelist[i]);
+                       namelist[i] = NULL;
+                       break;
+               }
+       }
+}
+
+static int optional_cdimg_filter(struct dirent **namelist, int count,
+       const char *basedir)
+{
+       const char *ext, *p;
+       char buf[256], buf2[256];
+       int i, d, ret, good_cue;
+       struct stat statf;
+       FILE *f;
+
+       for (i = 1; i < count; i++) {
+               if (namelist[i] == NULL || namelist[i]->d_type == DT_DIR)
+                       continue;
+
+               ext = strrchr(namelist[i]->d_name, '.');
+               if (ext == NULL) {
+                       // should not happen but whatever
+                       free(namelist[i]);
+                       namelist[i] = NULL;
+                       continue;
+               }
+               ext++;
+
+               // first find .cue files and remove files they reference
+               if (strcasecmp(ext, "cue") == 0)
+               {
+                       snprintf(buf, sizeof(buf), "%s/%s", basedir,
+                               namelist[i]->d_name);
+
+                       f = fopen(buf, "r");
+                       if (f == NULL) {
+                               free(namelist[i]);
+                               namelist[i] = NULL;
+                               continue;
+                       }
+
+                       good_cue = 0;
+                       while (fgets(buf, sizeof(buf), f)) {
+                               ret = sscanf(buf, " FILE \"%256[^\"]\"", buf2);
+                               if (ret != 1)
+                                       ret = sscanf(buf, " FILE %256s", buf2);
+                               if (ret != 1)
+                                       continue;
+
+                               p = strrchr(buf2, '/');
+                               if (p == NULL)
+                                       p = strrchr(buf2, '\\');
+                               if (p == NULL)
+                                       p = buf2;
+
+                               snprintf(buf, sizeof(buf), "%s/%s", basedir, p);
+                               ret = stat(buf, &statf);
+                               if (ret == 0) {
+                                       rm_namelist_entry(namelist, count, p);
+                                       good_cue = 1;
+                               }
+                       }
+                       fclose(f);
+
+                       if (!good_cue) {
+                               free(namelist[i]);
+                               namelist[i] = NULL;
+                       }
+                       continue;
+               }
+
+               p = strcasestr(namelist[i]->d_name, "track");
+               if (p != NULL) {
+                       ret = strtoul(p + 5, NULL, 10);
+                       if (ret > 1) {
+                               free(namelist[i]);
+                               namelist[i] = NULL;
+                               continue;
+                       }
+               }
+       }
+
+       // compact namelist
+       for (i = d = 1; i < count; i++)
+               if (namelist[i] != NULL)
+                       namelist[d++] = namelist[i];
+
+       return d;
+}
+
 // propagate menu settings to the emu vars
 static void menu_sync_config(void)
 {
 // propagate menu settings to the emu vars
 static void menu_sync_config(void)
 {
@@ -215,6 +332,7 @@ static void menu_set_defconfig(void)
        analog_deadzone = 50;
        soft_scaling = 1;
        soft_filter = 0;
        analog_deadzone = 50;
        soft_scaling = 1;
        soft_filter = 0;
+       plat_target.vout_fullscreen = 0;
        psx_clock = DEFAULT_PSX_CLOCK;
 
        region = 0;
        psx_clock = DEFAULT_PSX_CLOCK;
 
        region = 0;
@@ -236,6 +354,9 @@ static void menu_set_defconfig(void)
 #define CE_INTVAL(val) \
        { #val, sizeof(val), &val }
 
 #define CE_INTVAL(val) \
        { #val, sizeof(val), &val }
 
+#define CE_INTVAL_N(name, val) \
+       { name, sizeof(val), &val }
+
 #define CE_INTVAL_P(val) \
        { #val, sizeof(pl_rearmed_cbs.val), &pl_rearmed_cbs.val }
 
 #define CE_INTVAL_P(val) \
        { #val, sizeof(pl_rearmed_cbs.val), &pl_rearmed_cbs.val }
 
@@ -259,7 +380,7 @@ static const struct {
        CE_CONFIG_STR(Spu),
 //     CE_CONFIG_STR(Cdr),
        CE_CONFIG_VAL(Xa),
        CE_CONFIG_STR(Spu),
 //     CE_CONFIG_STR(Cdr),
        CE_CONFIG_VAL(Xa),
-       CE_CONFIG_VAL(Sio),
+//     CE_CONFIG_VAL(Sio),
        CE_CONFIG_VAL(Mdec),
        CE_CONFIG_VAL(Cdda),
        CE_CONFIG_VAL(Debug),
        CE_CONFIG_VAL(Mdec),
        CE_CONFIG_VAL(Cdda),
        CE_CONFIG_VAL(Debug),
@@ -268,21 +389,24 @@ static const struct {
        CE_CONFIG_VAL(RCntFix),
        CE_CONFIG_VAL(VSyncWA),
        CE_CONFIG_VAL(Cpu),
        CE_CONFIG_VAL(RCntFix),
        CE_CONFIG_VAL(VSyncWA),
        CE_CONFIG_VAL(Cpu),
-       CE_CONFIG_VAL(CdrReschedule),
        CE_INTVAL(region),
        CE_INTVAL_V(g_scaler, 2),
        CE_INTVAL(g_layer_x),
        CE_INTVAL(g_layer_y),
        CE_INTVAL(g_layer_w),
        CE_INTVAL(g_layer_h),
        CE_INTVAL(region),
        CE_INTVAL_V(g_scaler, 2),
        CE_INTVAL(g_layer_x),
        CE_INTVAL(g_layer_y),
        CE_INTVAL(g_layer_w),
        CE_INTVAL(g_layer_h),
-       CE_INTVAL(filter),
        CE_INTVAL(soft_filter),
        CE_INTVAL(soft_filter),
+       CE_INTVAL(plat_target.vout_method),
+       CE_INTVAL(plat_target.hwfilter),
+       CE_INTVAL(plat_target.vout_fullscreen),
        CE_INTVAL(state_slot),
        CE_INTVAL(cpu_clock),
        CE_INTVAL(g_opts),
        CE_INTVAL(in_type_sel1),
        CE_INTVAL(in_type_sel2),
        CE_INTVAL(analog_deadzone),
        CE_INTVAL(state_slot),
        CE_INTVAL(cpu_clock),
        CE_INTVAL(g_opts),
        CE_INTVAL(in_type_sel1),
        CE_INTVAL(in_type_sel2),
        CE_INTVAL(analog_deadzone),
+       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, 3),
        CE_INTVAL_P(gpu_peops.iUseDither),
        CE_INTVAL_P(gpu_peops.dwActFixes),
        CE_INTVAL_V(frameskip, 3),
        CE_INTVAL_P(gpu_peops.iUseDither),
        CE_INTVAL_P(gpu_peops.dwActFixes),
@@ -306,7 +430,7 @@ static const struct {
        CE_INTVAL_V(iUseReverb, 3),
        CE_INTVAL_V(iXAPitch, 3),
        CE_INTVAL_V(iUseInterpolation, 3),
        CE_INTVAL_V(iUseReverb, 3),
        CE_INTVAL_V(iXAPitch, 3),
        CE_INTVAL_V(iUseInterpolation, 3),
-       CE_INTVAL(warned_about_bios),
+       CE_INTVAL(config_save_counter),
        CE_INTVAL(in_evdev_allow_abs_only),
        CE_INTVAL(volume_boost),
        CE_INTVAL(psx_clock),
        CE_INTVAL(in_evdev_allow_abs_only),
        CE_INTVAL(volume_boost),
        CE_INTVAL(psx_clock),
@@ -345,6 +469,8 @@ static int menu_write_config(int is_game)
        FILE *f;
        int i;
 
        FILE *f;
        int i;
 
+       config_save_counter++;
+
        make_cfg_fname(cfgfile, sizeof(cfgfile), is_game);
        f = fopen(cfgfile, "w");
        if (f == NULL) {
        make_cfg_fname(cfgfile, sizeof(cfgfile), is_game);
        f = fopen(cfgfile, "w");
        if (f == NULL) {
@@ -382,14 +508,18 @@ static int menu_write_config(int is_game)
 
 static int menu_do_last_cd_img(int is_get)
 {
 
 static int menu_do_last_cd_img(int is_get)
 {
+       static const char *defaults[] = { "/media", "/mnt/sd", "/mnt" };
        char path[256];
        char path[256];
+       struct stat st;
        FILE *f;
        FILE *f;
-       int ret;
+       int i, ret = -1;
 
        snprintf(path, sizeof(path), "." PCSX_DOT_DIR "lastcdimg.txt");
        f = fopen(path, is_get ? "r" : "w");
 
        snprintf(path, sizeof(path), "." PCSX_DOT_DIR "lastcdimg.txt");
        f = fopen(path, is_get ? "r" : "w");
-       if (f == NULL)
-               return -1;
+       if (f == NULL) {
+               ret = -1;
+               goto out;
+       }
 
        if (is_get) {
                ret = fread(last_selected_fname, 1, sizeof(last_selected_fname) - 1, f);
 
        if (is_get) {
                ret = fread(last_selected_fname, 1, sizeof(last_selected_fname) - 1, f);
@@ -400,6 +530,17 @@ static int menu_do_last_cd_img(int is_get)
                fprintf(f, "%s\n", last_selected_fname);
        fclose(f);
 
                fprintf(f, "%s\n", last_selected_fname);
        fclose(f);
 
+out:
+       if (is_get) {
+               for (i = 0; last_selected_fname[0] == 0
+                      || stat(last_selected_fname, &st) != 0; i++)
+               {
+                       if (i >= ARRAY_SIZE(defaults))
+                               break;
+                       strcpy(last_selected_fname, defaults[i]);
+               }
+       }
+
        return 0;
 }
 
        return 0;
 }
 
@@ -523,20 +664,25 @@ fail:
        return ret;
 }
 
        return ret;
 }
 
+static const char *filter_exts[] = {
+       "bin", "img", "mdf", "iso", "cue", "z",
+       "bz",  "znx", "pbp", "cbn"
+};
+
 // rrrr rggg gggb bbbb
 static unsigned short fname2color(const char *fname)
 {
 // rrrr rggg gggb bbbb
 static unsigned short fname2color(const char *fname)
 {
-       static const char *cdimg_exts[] = { ".bin", ".img", ".mdf", ".iso", ".cue", ".z",
-                                           ".bz", ".znx", ".pbp", ".cbn" };
-       static const char *other_exts[] = { ".ccd", ".toc", ".mds", ".sub",
-                                           ".table", ".index", ".sbi" };
+       static const char *other_exts[] = {
+               "ccd", "toc", "mds", "sub", "table", "index", "sbi"
+       };
        const char *ext = strrchr(fname, '.');
        int i;
 
        if (ext == NULL)
                return 0xffff;
        const char *ext = strrchr(fname, '.');
        int i;
 
        if (ext == NULL)
                return 0xffff;
-       for (i = 0; i < array_size(cdimg_exts); i++)
-               if (strcasecmp(ext, cdimg_exts[i]) == 0)
+       ext++;
+       for (i = 0; i < array_size(filter_exts); i++)
+               if (strcasecmp(ext, filter_exts[i]) == 0)
                        return 0x7bff;
        for (i = 0; i < array_size(other_exts); i++)
                if (strcasecmp(ext, other_exts[i]) == 0)
                        return 0x7bff;
        for (i = 0; i < array_size(other_exts); i++)
                if (strcasecmp(ext, other_exts[i]) == 0)
@@ -546,10 +692,6 @@ static unsigned short fname2color(const char *fname)
 
 static void draw_savestate_bg(int slot);
 
 
 static void draw_savestate_bg(int slot);
 
-static const char *filter_exts[] = {
-       ".mp3", ".MP3", ".txt", ".htm", "html", ".jpg", ".pnd"
-};
-
 #define MENU_ALIGN_LEFT
 #ifdef __ARM_ARCH_7A__ // assume hires device
 #define MENU_X2 1
 #define MENU_ALIGN_LEFT
 #ifdef __ARM_ARCH_7A__ // assume hires device
 #define MENU_X2 1
@@ -557,9 +699,7 @@ static const char *filter_exts[] = {
 #define MENU_X2 0
 #endif
 
 #define MENU_X2 0
 #endif
 
-#define menu_init menu_init_common
-#include "common/menu.c"
-#undef menu_init
+#include "libpicofe/menu.c"
 
 // a bit of black magic here
 static void draw_savestate_bg(int slot)
 
 // a bit of black magic here
 static void draw_savestate_bg(int slot)
@@ -607,12 +747,18 @@ static void draw_savestate_bg(int slot)
 
        x = gpu->ulControl[5] & 0x3ff;
        y = (gpu->ulControl[5] >> 10) & 0x1ff;
 
        x = gpu->ulControl[5] & 0x3ff;
        y = (gpu->ulControl[5] >> 10) & 0x1ff;
-       s = (u16 *)gpu->psxVRam + y * 1024 + x;
        w = psx_widths[(gpu->ulStatus >> 16) & 7];
        tmp = gpu->ulControl[7];
        h = ((tmp >> 10) & 0x3ff) - (tmp & 0x3ff);
        if (gpu->ulStatus & 0x80000) // doubleheight
                h *= 2;
        w = psx_widths[(gpu->ulStatus >> 16) & 7];
        tmp = gpu->ulControl[7];
        h = ((tmp >> 10) & 0x3ff) - (tmp & 0x3ff);
        if (gpu->ulStatus & 0x80000) // doubleheight
                h *= 2;
+       if (h <= 0 || h > 512)
+               goto out;
+       if (y > 512 - 64)
+               y = 0;
+       if (y + h > 512)
+               h = 512 - y;
+       s = (u16 *)gpu->psxVRam + y * 1024 + x;
 
        x = max(0, g_menuscreen_w - w) & ~3;
        y = max(0, g_menuscreen_h / 2 - h / 2);
 
        x = max(0, g_menuscreen_w - w) & ~3;
        y = max(0, g_menuscreen_h / 2 - h / 2);
@@ -666,16 +812,23 @@ me_bind_action emuctrl_actions[] =
        { "Next Save Slot   ", 1 << SACTION_NEXT_SSLOT },
        { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP },
        { "Take Screenshot  ", 1 << SACTION_SCREENSHOT },
        { "Next Save Slot   ", 1 << SACTION_NEXT_SSLOT },
        { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP },
        { "Take Screenshot  ", 1 << SACTION_SCREENSHOT },
+       { "Show/Hide FPS    ", 1 << SACTION_TOGGLE_FPS },
+#ifdef __ARM_ARCH_7A__
        { "Switch Renderer  ", 1 << SACTION_SWITCH_DISPMODE },
        { "Switch Renderer  ", 1 << SACTION_SWITCH_DISPMODE },
-       { "Enter Menu       ", 1 << SACTION_ENTER_MENU },
-#ifdef __ARM_ARCH_7A__ /* XXX */
+#endif
+       { "Fast Forward     ", 1 << SACTION_FAST_FORWARD },
+#if MENU_SHOW_MINIMIZE
        { "Minimize         ", 1 << SACTION_MINIMIZE },
 #endif
        { "Minimize         ", 1 << SACTION_MINIMIZE },
 #endif
+#if MENU_SHOW_FULLSCREEN
+       { "Toggle fullscreen", 1 << SACTION_TOGGLE_FULLSCREEN },
+#endif
+       { "Enter Menu       ", 1 << SACTION_ENTER_MENU },
        { "Gun Trigger      ", 1 << SACTION_GUN_TRIGGER },
        { "Gun A button     ", 1 << SACTION_GUN_A },
        { "Gun B button     ", 1 << SACTION_GUN_B },
        { "Gun Offscreen Trigger", 1 << SACTION_GUN_TRIGGER2 },
        { "Gun Trigger      ", 1 << SACTION_GUN_TRIGGER },
        { "Gun A button     ", 1 << SACTION_GUN_A },
        { "Gun B button     ", 1 << SACTION_GUN_B },
        { "Gun Offscreen Trigger", 1 << SACTION_GUN_TRIGGER2 },
-#ifndef __ARM_ARCH_7A__ /* XXX */
+#if MENU_SHOW_VOLUME
        { "Volume Up        ", 1 << SACTION_VOLUME_UP },
        { "Volume Down      ", 1 << SACTION_VOLUME_DOWN },
 #endif
        { "Volume Up        ", 1 << SACTION_VOLUME_UP },
        { "Volume Down      ", 1 << SACTION_VOLUME_DOWN },
 #endif
@@ -893,17 +1046,21 @@ static int key_config_loop_wrap(int id, int keys)
        return 0;
 }
 
        return 0;
 }
 
+static const char h_nubmode[] = "Maps nub-like analog controls to PSX ones better\n"
+                               "Might cause problems with real analog sticks";
 static const char *adevnames[IN_MAX_DEVS + 2];
 static int stick_sel[2];
 
 static menu_entry e_menu_keyconfig_analog[] =
 {
 static const char *adevnames[IN_MAX_DEVS + 2];
 static int stick_sel[2];
 
 static menu_entry e_menu_keyconfig_analog[] =
 {
-       mee_enum ("Left stick (L3)",  0, stick_sel[0], adevnames),
-       mee_range("  X axis",    0, in_adev_axis[0][0], 0, 7),
-       mee_range("  Y axis",    0, in_adev_axis[0][1], 0, 7),
-       mee_enum ("Right stick (R3)", 0, stick_sel[1], adevnames),
-       mee_range("  X axis",    0, in_adev_axis[1][0], 0, 7),
-       mee_range("  Y axis",    0, in_adev_axis[1][1], 0, 7),
+       mee_enum   ("Left stick (L3)",  0, stick_sel[0], adevnames),
+       mee_range  ("  X axis",    0, in_adev_axis[0][0], 0, 7),
+       mee_range  ("  Y axis",    0, in_adev_axis[0][1], 0, 7),
+       mee_onoff_h("  nub mode",  0, in_adev_is_nublike[0], 1, h_nubmode),
+       mee_enum   ("Right stick (R3)", 0, stick_sel[1], adevnames),
+       mee_range  ("  X axis",    0, in_adev_axis[1][0], 0, 7),
+       mee_range  ("  Y axis",    0, in_adev_axis[1][1], 0, 7),
+       mee_onoff_h("  nub mode",  0, in_adev_is_nublike[1], 1, h_nubmode),
        mee_end,
 };
 
        mee_end,
 };
 
@@ -970,9 +1127,9 @@ static const char *mgn_saveloadcfg(int id, int *offs)
 static int mh_savecfg(int id, int keys)
 {
        if (menu_write_config(id == MA_OPT_SAVECFG_GAME ? 1 : 0) == 0)
 static int mh_savecfg(int id, int keys)
 {
        if (menu_write_config(id == MA_OPT_SAVECFG_GAME ? 1 : 0) == 0)
-               me_update_msg("config saved");
+               menu_update_msg("config saved");
        else
        else
-               me_update_msg("failed to write config");
+               menu_update_msg("failed to write config");
 
        return 1;
 }
 
        return 1;
 }
@@ -981,7 +1138,7 @@ static int mh_input_rescan(int id, int keys)
 {
        //menu_sync_config();
        in_probe();
 {
        //menu_sync_config();
        in_probe();
-       me_update_msg("rescan complete.");
+       menu_update_msg("rescan complete.");
 
        return 0;
 }
 
        return 0;
 }
@@ -1043,7 +1200,9 @@ static const char *men_soft_filter[] = { "None",
 static const char *men_dummy[] = { NULL };
 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 *men_dummy[] = { NULL };
 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_overlay[]   = "Overlay provides hardware accelerated scaling";
 static const char h_soft_filter[] = "Works only if game uses low resolution modes";
 static const char h_soft_filter[] = "Works only if game uses low resolution modes";
+static const char h_gamma[]     = "Gamma/brightness adjustment (default 100)";
 
 static int menu_loop_cscaler(int id, int keys)
 {
 
 static int menu_loop_cscaler(int id, int keys)
 {
@@ -1055,7 +1214,7 @@ static int menu_loop_cscaler(int id, int keys)
 
        for (;;)
        {
 
        for (;;)
        {
-               menu_draw_begin(0);
+               menu_draw_begin(0, 1);
                memset(g_menuscreen_ptr, 4, g_menuscreen_w * g_menuscreen_h * 2);
                text_out16(2, 2, "%d,%d", g_layer_x, g_layer_y);
                text_out16(2, 480 - 18, "%dx%d | d-pad: resize, R+d-pad: move", g_layer_w, g_layer_h);
                memset(g_menuscreen_ptr, 4, g_menuscreen_w * g_menuscreen_h * 2);
                text_out16(2, 2, "%d,%d", g_layer_x, g_layer_y);
                text_out16(2, 480 - 18, "%dx%d | d-pad: resize, R+d-pad: move", g_layer_w, g_layer_h);
@@ -1099,12 +1258,14 @@ static int menu_loop_cscaler(int id, int keys)
 
 static menu_entry e_menu_gfx_options[] =
 {
 
 static menu_entry e_menu_gfx_options[] =
 {
-       mee_enum      ("Scaler",                   MA_OPT_SCALER, g_scaler, men_scaler),
+       mee_enum      ("Scaler",                   MA_OPT_VARSCALER, g_scaler, men_scaler),
+       mee_enum      ("Video output mode",        MA_OPT_VOUT_MODE, plat_target.vout_method, men_dummy),
        mee_onoff     ("Software Scaling",         MA_OPT_SCALER2, soft_scaling, 1),
        mee_onoff     ("Software Scaling",         MA_OPT_SCALER2, soft_scaling, 1),
-       mee_enum      ("Filter",                   MA_OPT_FILTERING, filter, men_dummy),
-       mee_enum_h    ("Software Filter",          MA_OPT_FILTERING2, soft_filter, men_soft_filter, h_soft_filter),
+       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),
+       mee_range_h   ("Gamma adjustment",         MA_OPT_GAMMA, g_gamma, 1, 200, h_gamma),
 //     mee_onoff     ("Vsync",                    0, vsync, 1),
 //     mee_onoff     ("Vsync",                    0, vsync, 1),
-       mee_cust_h    ("Setup custom scaler",      MA_OPT_SCALER_C, menu_loop_cscaler, NULL, h_cscaler),
+       mee_cust_h    ("Setup custom scaler",      MA_OPT_VARSCALER_C, menu_loop_cscaler, NULL, h_cscaler),
        mee_end,
 };
 
        mee_end,
 };
 
@@ -1117,16 +1278,6 @@ static int menu_loop_gfx_options(int id, int keys)
        return 0;
 }
 
        return 0;
 }
 
-// XXX
-void menu_set_filter_list(void *filters)
-{
-       int i;
-
-       i = me_id2offset(e_menu_gfx_options, MA_OPT_FILTERING);
-       e_menu_gfx_options[i].data = filters;
-       me_enable(e_menu_gfx_options, MA_OPT_FILTERING, filters != NULL);
-}
-
 // ------------ bios/plugins ------------
 
 #ifdef __ARM_NEON__
 // ------------ bios/plugins ------------
 
 #ifdef __ARM_NEON__
@@ -1335,7 +1486,6 @@ static int menu_loop_speed_hacks(int id, int keys)
        return 0;
 }
 
        return 0;
 }
 
-static const char *men_cfg_cdrr[] = { "Auto", "ON", "OFF", NULL };
 static const char h_cfg_cpul[]   = "Shows CPU usage in %";
 static const char h_cfg_spu[]    = "Shows active SPU channels\n"
                                   "(green: normal, red: fmod, blue: noise)";
 static const char h_cfg_cpul[]   = "Shows CPU usage in %";
 static const char h_cfg_spu[]    = "Shows active SPU channels\n"
                                   "(green: normal, red: fmod, blue: noise)";
@@ -1349,7 +1499,6 @@ static const char h_cfg_rcnt1[]  = "Parasite Eve 2, Vandal Hearts 1/2 Fix\n"
                                   "(timing hack, breaks other games)";
 static const char h_cfg_rcnt2[]  = "InuYasha Sengoku Battle Fix\n"
                                   "(timing hack, breaks other games)";
                                   "(timing hack, breaks other games)";
 static const char h_cfg_rcnt2[]  = "InuYasha Sengoku Battle Fix\n"
                                   "(timing hack, breaks other games)";
-static const char h_cfg_cdrr[]   = "Compatibility tweak (CD timing hack, breaks FMVs)";
 static const char h_cfg_nodrc[]  = "Disable dynamic recompiler and use interpreter\n"
                                   "Might be useful to overcome some dynarec bugs";
 static const char h_cfg_shacks[] = "Breaks games but may give better performance\n"
 static const char h_cfg_nodrc[]  = "Disable dynamic recompiler and use interpreter\n"
                                   "Might be useful to overcome some dynarec bugs";
 static const char h_cfg_shacks[] = "Breaks games but may give better performance\n"
@@ -1362,11 +1511,10 @@ static menu_entry e_menu_adv_options[] =
        mee_onoff_h   ("Disable Frame Limiter",  0, g_opts, OPT_NO_FRAMELIM, h_cfg_fl),
        mee_onoff_h   ("Disable XA Decoding",    0, Config.Xa, 1, h_cfg_xa),
        mee_onoff_h   ("Disable CD Audio",       0, Config.Cdda, 1, h_cfg_cdda),
        mee_onoff_h   ("Disable Frame Limiter",  0, g_opts, OPT_NO_FRAMELIM, h_cfg_fl),
        mee_onoff_h   ("Disable XA Decoding",    0, Config.Xa, 1, h_cfg_xa),
        mee_onoff_h   ("Disable CD Audio",       0, Config.Cdda, 1, h_cfg_cdda),
-       mee_onoff_h   ("SIO IRQ Always Enabled", 0, Config.Sio, 1, h_cfg_sio),
+       //mee_onoff_h   ("SIO IRQ Always Enabled", 0, Config.Sio, 1, h_cfg_sio),
        mee_onoff_h   ("SPU IRQ Always Enabled", 0, Config.SpuIrq, 1, h_cfg_spuirq),
        //mee_onoff_h   ("Rootcounter hack",       0, Config.RCntFix, 1, h_cfg_rcnt1),
        mee_onoff_h   ("Rootcounter hack 2",     0, Config.VSyncWA, 1, h_cfg_rcnt2),
        mee_onoff_h   ("SPU IRQ Always Enabled", 0, Config.SpuIrq, 1, h_cfg_spuirq),
        //mee_onoff_h   ("Rootcounter hack",       0, Config.RCntFix, 1, h_cfg_rcnt1),
        mee_onoff_h   ("Rootcounter hack 2",     0, Config.VSyncWA, 1, h_cfg_rcnt2),
-       mee_enum_h    ("CD read reschedule hack",0, Config.CdrReschedule, men_cfg_cdrr, h_cfg_cdrr),
        mee_onoff_h   ("Disable dynarec (slow!)",0, Config.Cpu, 1, h_cfg_nodrc),
        mee_handler_h ("[Speed hacks]",             menu_loop_speed_hacks, h_cfg_shacks),
        mee_end,
        mee_onoff_h   ("Disable dynarec (slow!)",0, Config.Cpu, 1, h_cfg_nodrc),
        mee_handler_h ("[Speed hacks]",             menu_loop_speed_hacks, h_cfg_shacks),
        mee_end,
@@ -1384,7 +1532,7 @@ static int menu_loop_adv_options(int id, int keys)
 static int mh_restore_defaults(int id, int keys)
 {
        menu_set_defconfig();
 static int mh_restore_defaults(int id, int keys)
 {
        menu_set_defconfig();
-       me_update_msg("defaults restored");
+       menu_update_msg("defaults restored");
        return 1;
 }
 
        return 1;
 }
 
@@ -1466,7 +1614,7 @@ static void debug_menu_loop(void)
 
        while (1)
        {
 
        while (1)
        {
-               menu_draw_begin(0);
+               menu_draw_begin(0, 1);
                draw_frame_debug(gpuf, df_x, df_y);
                menu_draw_end();
 
                draw_frame_debug(gpuf, df_x, df_y);
                menu_draw_end();
 
@@ -1518,7 +1666,7 @@ static void draw_mc_bg(void)
                GetMcdBlockInfo(2, i + 1, &blocks2[i]);
        }
 
                GetMcdBlockInfo(2, i + 1, &blocks2[i]);
        }
 
-       menu_draw_begin(1);
+       menu_draw_begin(1, 1);
 
        memcpy(g_menuscreen_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2);
 
 
        memcpy(g_menuscreen_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2);
 
@@ -1599,7 +1747,7 @@ static void draw_cheatlist(int sel)
        max_cnt = g_menuscreen_h / me_sfont_h;
        start = max_cnt / 2 - sel;
 
        max_cnt = g_menuscreen_h / me_sfont_h;
        start = max_cnt / 2 - sel;
 
-       menu_draw_begin(1);
+       menu_draw_begin(1, 1);
 
        for (i = 0; i < NumCheats; i++) {
                pos = start + i;
 
        for (i = 0; i < NumCheats; i++) {
                pos = start + i;
@@ -1651,11 +1799,8 @@ static void menu_bios_warn(void)
        static const char msg[] =
                "You don't seem to have copied any BIOS\n"
                "files to\n"
        static const char msg[] =
                "You don't seem to have copied any BIOS\n"
                "files to\n"
-#ifdef __ARM_ARCH_7A__ // XXX
-               "<SD card>/pandora/appdata/pcsx_rearmed/bios/\n\n"
-#else
-               "pcsx_rearmed/bios/\n\n"
-#endif
+               MENU_BIOS_PATH "\n\n"
+
                "While many games work fine with fake\n"
                "(HLE) BIOS, others (like MGS and FF8)\n"
                "require BIOS to work.\n"
                "While many games work fine with fake\n"
                "(HLE) BIOS, others (like MGS and FF8)\n"
                "require BIOS to work.\n"
@@ -1702,7 +1847,7 @@ static void draw_frame_main(void)
        }
 
        if (ready_to_go) {
        }
 
        if (ready_to_go) {
-               capacity = plat_get_bat_capacity();
+               capacity = plat_target_bat_capacity_get();
                ltime = time(NULL);
                tmp = localtime(&ltime);
                strftime(ltime_s, sizeof(ltime_s), "%H:%M", tmp);
                ltime = time(NULL);
                tmp = localtime(&ltime);
                strftime(ltime_s, sizeof(ltime_s), "%H:%M", tmp);
@@ -1763,7 +1908,7 @@ static int reload_plugins(const char *cdimg)
        pcnt_hook_plugins();
        NetOpened = 0;
        if (OpenPlugins() == -1) {
        pcnt_hook_plugins();
        NetOpened = 0;
        if (OpenPlugins() == -1) {
-               me_update_msg("failed to open plugins");
+               menu_update_msg("failed to open plugins");
                return -1;
        }
        plugin_call_rearmed_cbs();
                return -1;
        }
        plugin_call_rearmed_cbs();
@@ -1793,7 +1938,8 @@ static int run_exe(void)
 {
        const char *fname;
 
 {
        const char *fname;
 
-       fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
+       fname = menu_loop_romsel(last_selected_fname,
+               sizeof(last_selected_fname), NULL);
        if (fname == NULL)
                return -1;
 
        if (fname == NULL)
                return -1;
 
@@ -1803,7 +1949,7 @@ static int run_exe(void)
 
        SysReset();
        if (Load(fname) != 0) {
 
        SysReset();
        if (Load(fname) != 0) {
-               me_update_msg("exe load failed, bad file?");
+               menu_update_msg("exe load failed, bad file?");
                printf("meh\n");
                return -1;
        }
                printf("meh\n");
                return -1;
        }
@@ -1823,7 +1969,7 @@ static int run_cd_image(const char *fname)
        if (CheckCdrom() == -1) {
                // Only check the CD if we are starting the console with a CD
                ClosePlugins();
        if (CheckCdrom() == -1) {
                // Only check the CD if we are starting the console with a CD
                ClosePlugins();
-               me_update_msg("unsupported/invalid CD image");
+               menu_update_msg("unsupported/invalid CD image");
                return -1;
        }
 
                return -1;
        }
 
@@ -1832,11 +1978,11 @@ static int run_cd_image(const char *fname)
        // Read main executable directly from CDRom and start it
        if (LoadCdrom() == -1) {
                ClosePlugins();
        // Read main executable directly from CDRom and start it
        if (LoadCdrom() == -1) {
                ClosePlugins();
-               me_update_msg("failed to load CD image");
+               menu_update_msg("failed to load CD image");
                return -1;
        }
 
                return -1;
        }
 
-       emu_on_new_cd();
+       emu_on_new_cd(1);
        ready_to_go = 1;
 
        return 0;
        ready_to_go = 1;
 
        return 0;
@@ -1847,7 +1993,8 @@ static int romsel_run(void)
        int prev_gpu, prev_spu;
        const char *fname;
 
        int prev_gpu, prev_spu;
        const char *fname;
 
-       fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
+       fname = menu_loop_romsel(last_selected_fname,
+               sizeof(last_selected_fname), optional_cdimg_filter);
        if (fname == NULL)
                return -1;
 
        if (fname == NULL)
                return -1;
 
@@ -1871,7 +2018,7 @@ static int romsel_run(void)
                        return -1;
        }
 
                        return -1;
        }
 
-       strcpy(last_selected_fname, rom_fname_reload);
+       strcpy(last_selected_fname, fname);
        menu_do_last_cd_img(0);
        return 0;
 }
        menu_do_last_cd_img(0);
        return 0;
 }
@@ -1880,7 +2027,8 @@ static int swap_cd_image(void)
 {
        char *fname;
 
 {
        char *fname;
 
-       fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
+       fname = menu_loop_romsel(last_selected_fname,
+               sizeof(last_selected_fname), optional_cdimg_filter);
        if (fname == NULL)
                return -1;
 
        if (fname == NULL)
                return -1;
 
@@ -1891,18 +2039,18 @@ static int swap_cd_image(void)
 
        set_cd_image(fname);
        if (ReloadCdromPlugin() < 0) {
 
        set_cd_image(fname);
        if (ReloadCdromPlugin() < 0) {
-               me_update_msg("failed to load cdr plugin");
+               menu_update_msg("failed to load cdr plugin");
                return -1;
        }
        if (CDR_open() < 0) {
                return -1;
        }
        if (CDR_open() < 0) {
-               me_update_msg("failed to open cdr plugin");
+               menu_update_msg("failed to open cdr plugin");
                return -1;
        }
 
        SetCdOpenCaseTime(time(NULL) + 2);
        LidInterrupt();
 
                return -1;
        }
 
        SetCdOpenCaseTime(time(NULL) + 2);
        LidInterrupt();
 
-       strcpy(last_selected_fname, rom_fname_reload);
+       strcpy(last_selected_fname, fname);
        return 0;
 }
 
        return 0;
 }
 
@@ -1914,7 +2062,7 @@ static int swap_cd_multidisk(void)
 
        CDR_close();
        if (CDR_open() < 0) {
 
        CDR_close();
        if (CDR_open() < 0) {
-               me_update_msg("failed to open cdr plugin");
+               menu_update_msg("failed to open cdr plugin");
                return -1;
        }
 
                return -1;
        }
 
@@ -1930,7 +2078,7 @@ static void load_pcsx_cht(void)
        char *fname;
 
        path[0] = 0;
        char *fname;
 
        path[0] = 0;
-       fname = menu_loop_romsel(path, sizeof(path));
+       fname = menu_loop_romsel(path, sizeof(path), NULL);
        if (fname == NULL)
                return;
 
        if (fname == NULL)
                return;
 
@@ -1938,10 +2086,10 @@ static void load_pcsx_cht(void)
        LoadCheats(fname);
 
        if (NumCheats == 0 && NumCodes == 0)
        LoadCheats(fname);
 
        if (NumCheats == 0 && NumCodes == 0)
-               me_update_msg("failed to load cheats");
+               menu_update_msg("failed to load cheats");
        else {
                snprintf(path, sizeof(path), "%d cheat(s) loaded", NumCheats + NumCodes);
        else {
                snprintf(path, sizeof(path), "%d cheat(s) loaded", NumCheats + NumCodes);
-               me_update_msg(path);
+               menu_update_msg(path);
        }
        me_enable(e_menu_main, MA_MAIN_CHEATS, ready_to_go && NumCheats);
 }
        }
        me_enable(e_menu_main, MA_MAIN_CHEATS, ready_to_go && NumCheats);
 }
@@ -2056,13 +2204,22 @@ static void menu_leave_emu(void);
 
 void menu_loop(void)
 {
 
 void menu_loop(void)
 {
+       static int warned_about_bios = 0;
        static int sel = 0;
 
        menu_leave_emu();
 
        static int sel = 0;
 
        menu_leave_emu();
 
-       if (bioses[1] == NULL && !warned_about_bios) {
-               menu_bios_warn();
-               warned_about_bios = 1;
+       if (config_save_counter == 0) {
+               // assume first run
+               if (bioses[1] != NULL) {
+                       // autoselect BIOS to make user's life easier
+                       snprintf(Config.Bios, sizeof(Config.Bios), "%s", bioses[1]);
+                       bios_sel = 1;
+               }
+               else if (!warned_about_bios) {
+                       menu_bios_warn();
+                       warned_about_bios = 1;
+               }
        }
 
        me_enable(e_menu_main, MA_MAIN_RESUME_GAME, ready_to_go);
        }
 
        me_enable(e_menu_main, MA_MAIN_RESUME_GAME, ready_to_go);
@@ -2240,13 +2397,12 @@ do_memcards:
 void menu_init(void)
 {
        char buff[MAXPATHLEN];
 void menu_init(void)
 {
        char buff[MAXPATHLEN];
+       int i;
 
 
-       strcpy(last_selected_fname, "/media");
-
-       cpu_clock_st = cpu_clock = plat_cpu_clock_get();
+       cpu_clock_st = cpu_clock = plat_target_cpu_clock_get();
 
        scan_bios_plugins();
 
        scan_bios_plugins();
-       menu_init_common();
+       menu_init_base();
 
        menu_set_defconfig();
        menu_load_config(0);
 
        menu_set_defconfig();
        menu_load_config(0);
@@ -2265,17 +2421,33 @@ void menu_init(void)
        emu_make_path(buff, "skin/background.png", sizeof(buff));
        readpng(g_menubg_src_ptr, buff, READPNG_BG, g_menuscreen_w, g_menuscreen_h);
 
        emu_make_path(buff, "skin/background.png", sizeof(buff));
        readpng(g_menubg_src_ptr, buff, READPNG_BG, g_menuscreen_w, g_menuscreen_h);
 
-#ifndef __ARM_ARCH_7A__ /* XXX */
-       me_enable(e_menu_gfx_options, MA_OPT_SCALER, 0);
-       me_enable(e_menu_gfx_options, MA_OPT_FILTERING, 0);
-       me_enable(e_menu_gfx_options, MA_OPT_FILTERING2, 0);
-       me_enable(e_menu_gfx_options, MA_OPT_SCALER_C, 0);
-       me_enable(e_menu_keyconfig, MA_CTRL_NUBS_BTNS, 0);
-#else
-       me_enable(e_menu_gfx_options, MA_OPT_SCALER2, 0);
-       me_enable(e_menu_keyconfig, MA_CTRL_VIBRATION, 0);
-       me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, 0);
+       i = plat_target.cpu_clock_set != NULL
+               && plat_target.cpu_clock_get != NULL && cpu_clock_st > 0;
+       me_enable(e_menu_gfx_options, MA_OPT_CPU_CLOCKS, i);
+
+       i = me_id2offset(e_menu_gfx_options, MA_OPT_VOUT_MODE);
+       e_menu_gfx_options[i].data = plat_target.vout_methods;
+       me_enable(e_menu_gfx_options, MA_OPT_VOUT_MODE,
+               plat_target.vout_methods != NULL);
+
+       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);
+
+#ifndef __ARM_ARCH_7A__
+       me_enable(e_menu_gfx_options, MA_OPT_SWFILTER, 0);
 #endif
 #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_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);
+       me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, MENU_SHOW_DEADZONE);
 }
 
 void menu_notify_mode_change(int w, int h, int bpp)
 }
 
 void menu_notify_mode_change(int w, int h, int bpp)
@@ -2317,7 +2489,7 @@ static void menu_leave_emu(void)
        }
 
        if (ready_to_go)
        }
 
        if (ready_to_go)
-               cpu_clock = plat_cpu_clock_get();
+               cpu_clock = plat_target_cpu_clock_get();
 }
 
 void menu_prepare_emu(void)
 }
 
 void menu_prepare_emu(void)
@@ -2327,9 +2499,12 @@ void menu_prepare_emu(void)
        plat_video_menu_leave();
 
        psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec;
        plat_video_menu_leave();
 
        psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec;
-       if (psxCpu != prev_cpu)
+       if (psxCpu != prev_cpu) {
+               prev_cpu->Shutdown();
+               psxCpu->Init();
                // note that this does not really reset, just clears drc caches
                psxCpu->Reset();
                // note that this does not really reset, just clears drc caches
                psxCpu->Reset();
+       }
 
        // core doesn't care about Config.Cdda changes,
        // so handle them manually here
 
        // core doesn't care about Config.Cdda changes,
        // so handle them manually here
@@ -2338,7 +2513,7 @@ void menu_prepare_emu(void)
 
        menu_sync_config();
        if (cpu_clock > 0)
 
        menu_sync_config();
        if (cpu_clock > 0)
-               plat_cpu_clock_apply(cpu_clock);
+               plat_target_cpu_clock_set(cpu_clock);
 
        // push config to GPU plugin
        plugin_call_rearmed_cbs();
 
        // push config to GPU plugin
        plugin_call_rearmed_cbs();
@@ -2352,7 +2527,7 @@ void menu_prepare_emu(void)
        dfinput_activate();
 }
 
        dfinput_activate();
 }
 
-void me_update_msg(const char *msg)
+void menu_update_msg(const char *msg)
 {
        strncpy(menu_error_msg, msg, sizeof(menu_error_msg));
        menu_error_msg[sizeof(menu_error_msg) - 1] = 0;
 {
        strncpy(menu_error_msg, msg, sizeof(menu_error_msg));
        menu_error_msg[sizeof(menu_error_msg) - 1] = 0;
@@ -2363,5 +2538,6 @@ void me_update_msg(const char *msg)
 
 void menu_finish(void)
 {
 
 void menu_finish(void)
 {
-       plat_cpu_clock_apply(cpu_clock_st);
+       if (cpu_clock_st > 0)
+               plat_target_cpu_clock_set(cpu_clock_st);
 }
 }