2 * (C) GraÅžvydas "notaz" Ignotas, 2010-2011
4 * This work is licensed under the terms of any of these licenses
6 * - GNU GPL, version 2 or later.
7 * - GNU LGPL, version 2.1 or later.
8 * See the COPYING file in the top-level directory.
21 #include "plugin_lib.h"
25 #include "arm_utils.h"
26 #include "common/plat.h"
27 #include "common/input.h"
28 #include "linux/in_evdev.h"
29 #include "../libpcsxcore/misc.h"
30 #include "../libpcsxcore/cdrom.h"
31 #include "../libpcsxcore/psemu_plugin_defs.h"
32 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
33 #include "../plugins/dfinput/pad.h"
37 #define array_size(x) (sizeof(x) / sizeof(x[0]))
71 static int last_psx_w, last_psx_h, last_psx_bpp;
72 static int scaling, filter, cpu_clock, cpu_clock_st;
73 static char rom_fname_reload[MAXPATHLEN];
74 static char last_selected_fname[MAXPATHLEN];
75 static int warned_about_bios, region, in_type_sel;
79 extern int iUseReverb;
80 extern int iUseInterpolation;
82 extern int iSPUIRQWait;
85 static const char *bioses[24];
86 static const char *gpu_plugins[16];
87 static const char *spu_plugins[16];
88 static int bios_sel, gpu_plugsel, spu_plugsel;
91 static int min(int x, int y) { return x < y ? x : y; }
92 static int max(int x, int y) { return x > y ? x : y; }
94 void emu_make_path(char *buff, const char *end, int size)
98 end_len = strlen(end);
99 pos = plat_get_root_dir(buff, size);
100 strncpy(buff + pos, end, size - pos);
102 if (pos + end_len > size - 1)
103 printf("Warning: path truncated: %s\n", buff);
106 static int emu_check_save_file(int slot)
108 int ret = emu_check_state(slot);
109 return ret == 0 ? 1 : 0;
112 static int emu_save_load_game(int load, int unused)
117 ret = emu_load_state(state_slot);
119 // reflect hle/bios mode from savestate
122 else if (bios_sel == 0 && bioses[1] != NULL)
123 // XXX: maybe find the right bios instead
127 ret = emu_save_state(state_slot);
132 // propagate menu settings to the emu vars
133 static void menu_sync_config(void)
135 static int allow_abs_only_old;
140 Config.PsxType = region - 1;
142 in_type = in_type_sel ? PSE_PAD_TYPE_ANALOGPAD : PSE_PAD_TYPE_STANDARD;
143 if (in_evdev_allow_abs_only != allow_abs_only_old) {
144 pandora_rescan_inputs();
145 allow_abs_only_old = in_evdev_allow_abs_only;
148 pl_frame_interval = Config.PsxType ? 20000 : 16667;
149 // used by P.E.Op.S. frameskip code
150 pl_rearmed_cbs.gpu_peops.fFrameRateHz = Config.PsxType ? 50.0f : 59.94f;
151 pl_rearmed_cbs.gpu_peops.dwFrameRateTicks =
152 (100000*100 / (unsigned long)(pl_rearmed_cbs.gpu_peops.fFrameRateHz*100));
155 static void menu_set_defconfig(void)
162 in_evdev_allow_abs_only = 0;
163 Config.Xa = Config.Cdda = Config.Sio =
164 Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0;
166 pl_rearmed_cbs.frameskip = 0;
167 pl_rearmed_cbs.gpu_peops.iUseDither = 0;
168 pl_rearmed_cbs.gpu_peops.dwActFixes = 1<<7;
171 iUseInterpolation = 1;
179 #define CE_CONFIG_STR(val) \
180 { #val, 0, Config.val }
182 #define CE_CONFIG_VAL(val) \
183 { #val, sizeof(Config.val), &Config.val }
185 #define CE_STR(val) \
188 #define CE_INTVAL(val) \
189 { #val, sizeof(val), &val }
191 #define CE_INTVAL_P(val) \
192 { #val, sizeof(pl_rearmed_cbs.val), &pl_rearmed_cbs.val }
194 // 'versioned' var, used when defaults change
195 #define CE_INTVAL_V(val, ver) \
196 { #val #ver, sizeof(val), &val }
198 static const struct {
206 // CE_CONFIG_STR(Cdr),
211 CE_CONFIG_VAL(Debug),
212 CE_CONFIG_VAL(PsxOut),
213 CE_CONFIG_VAL(SpuIrq),
214 CE_CONFIG_VAL(RCntFix),
215 CE_CONFIG_VAL(VSyncWA),
219 CE_INTVAL(g_layer_x),
220 CE_INTVAL(g_layer_y),
221 CE_INTVAL(g_layer_w),
222 CE_INTVAL(g_layer_h),
224 CE_INTVAL(state_slot),
225 CE_INTVAL(cpu_clock),
227 CE_INTVAL(in_type_sel),
228 CE_INTVAL_P(frameskip),
229 CE_INTVAL_P(gpu_peops.iUseDither),
230 CE_INTVAL_P(gpu_peops.dwActFixes),
231 CE_INTVAL(iUseReverb),
233 CE_INTVAL_V(iUseInterpolation, 2),
234 CE_INTVAL_V(iSPUIRQWait, 2),
235 CE_INTVAL(iUseTimer),
236 CE_INTVAL(warned_about_bios),
237 CE_INTVAL(in_evdev_allow_abs_only),
240 static char *get_cd_label(void)
242 static char trimlabel[33];
245 strncpy(trimlabel, CdromLabel, 32);
247 for (j = 31; j >= 0; j--)
248 if (trimlabel[j] == ' ')
254 static void make_cfg_fname(char *buf, size_t size, int is_game)
257 snprintf(buf, size, "." PCSX_DOT_DIR "cfg/%.32s-%.9s.cfg", get_cd_label(), CdromId);
259 snprintf(buf, size, "." PCSX_DOT_DIR "%s", cfgfile_basename);
262 static void keys_write_all(FILE *f);
264 static int menu_write_config(int is_game)
266 char cfgfile[MAXPATHLEN];
270 make_cfg_fname(cfgfile, sizeof(cfgfile), is_game);
271 f = fopen(cfgfile, "w");
273 printf("menu_write_config: failed to open: %s\n", cfgfile);
277 for (i = 0; i < ARRAY_SIZE(config_data); i++) {
278 fprintf(f, "%s = ", config_data[i].name);
279 switch (config_data[i].len) {
281 fprintf(f, "%s\n", (char *)config_data[i].val);
284 fprintf(f, "%x\n", *(u8 *)config_data[i].val);
287 fprintf(f, "%x\n", *(u16 *)config_data[i].val);
290 fprintf(f, "%x\n", *(u32 *)config_data[i].val);
293 printf("menu_write_config: unhandled len %d for %s\n",
294 config_data[i].len, config_data[i].name);
300 fprintf(f, "lastcdimg = %s\n", last_selected_fname);
308 static void parse_str_val(char *cval, const char *src)
311 strncpy(cval, src, MAXPATHLEN);
312 cval[MAXPATHLEN - 1] = 0;
313 tmp = strchr(cval, '\n');
315 tmp = strchr(cval, '\r');
320 static void keys_load_all(const char *cfg);
322 static int menu_load_config(int is_game)
324 char cfgfile[MAXPATHLEN];
330 make_cfg_fname(cfgfile, sizeof(cfgfile), is_game);
331 f = fopen(cfgfile, "r");
333 printf("menu_load_config: failed to open: %s\n", cfgfile);
337 fseek(f, 0, SEEK_END);
340 printf("bad size %ld: %s\n", size, cfgfile);
344 cfg = malloc(size + 1);
348 fseek(f, 0, SEEK_SET);
349 if (fread(cfg, 1, size, f) != size) {
350 printf("failed to read: %s\n", cfgfile);
355 for (i = 0; i < ARRAY_SIZE(config_data); i++) {
359 tmp = strstr(cfg, config_data[i].name);
362 tmp += strlen(config_data[i].name);
363 if (strncmp(tmp, " = ", 3) != 0)
367 if (config_data[i].len == 0) {
368 parse_str_val(config_data[i].val, tmp);
373 val = strtoul(tmp, &tmp2, 16);
374 if (tmp2 == NULL || tmp == tmp2)
375 continue; // parse failed
377 switch (config_data[i].len) {
379 *(u8 *)config_data[i].val = val;
382 *(u16 *)config_data[i].val = val;
385 *(u32 *)config_data[i].val = val;
388 printf("menu_load_config: unhandled len %d for %s\n",
389 config_data[i].len, config_data[i].name);
395 char *tmp = strstr(cfg, "lastcdimg = ");
398 parse_str_val(last_selected_fname, tmp);
405 for (i = bios_sel = 0; bioses[i] != NULL; i++)
406 if (strcmp(Config.Bios, bioses[i]) == 0)
407 { bios_sel = i; break; }
409 for (i = gpu_plugsel = 0; gpu_plugins[i] != NULL; i++)
410 if (strcmp(Config.Gpu, gpu_plugins[i]) == 0)
411 { gpu_plugsel = i; break; }
413 for (i = spu_plugsel = 0; spu_plugins[i] != NULL; i++)
414 if (strcmp(Config.Spu, spu_plugins[i]) == 0)
415 { spu_plugsel = i; break; }
426 // rrrr rggg gggb bbbb
427 static unsigned short fname2color(const char *fname)
429 static const char *cdimg_exts[] = { ".bin", ".img", ".mdf", ".iso", ".cue", ".z", ".bz", ".znx", ".pbp" };
430 static const char *other_exts[] = { ".ccd", ".toc", ".mds", ".sub", ".table", ".index", ".sbi" };
431 const char *ext = strrchr(fname, '.');
436 for (i = 0; i < array_size(cdimg_exts); i++)
437 if (strcasecmp(ext, cdimg_exts[i]) == 0)
439 for (i = 0; i < array_size(other_exts); i++)
440 if (strcasecmp(ext, other_exts[i]) == 0)
445 static void draw_savestate_bg(int slot);
447 static const char *filter_exts[] = {
448 ".mp3", ".MP3", ".txt", ".htm", "html", ".jpg", ".pnd"
451 #define MENU_ALIGN_LEFT
452 #define menu_init menu_init_common
453 #include "common/menu.c"
456 // a bit of black magic here
457 static void draw_savestate_bg(int slot)
459 static const int psx_widths[8] = { 256, 368, 320, 384, 512, 512, 640, 640 };
461 char fname[MAXPATHLEN];
468 ret = get_state_filename(fname, sizeof(fname), slot);
472 f = gzopen(fname, "rb");
476 if (gzseek(f, 0x29933d, SEEK_SET) != 0x29933d) {
477 fprintf(stderr, "gzseek failed\n");
482 gpu = malloc(sizeof(*gpu));
488 ret = gzread(f, gpu, sizeof(*gpu));
490 if (ret != sizeof(*gpu)) {
491 fprintf(stderr, "gzread failed\n");
495 memcpy(g_menubg_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2);
497 if (gpu->ulStatus & 0x800000)
498 goto out; // disabled
500 x = gpu->ulControl[5] & 0x3ff;
501 y = (gpu->ulControl[5] >> 10) & 0x1ff;
502 s = (u16 *)gpu->psxVRam + y * 1024 + (x & ~1);
503 w = psx_widths[(gpu->ulStatus >> 16) & 7];
504 tmp = gpu->ulControl[7];
505 h = ((tmp >> 10) & 0x3ff) - (tmp & 0x3ff);
506 if (gpu->ulStatus & 0x80000) // doubleheight
509 x = max(0, g_menuscreen_w - w) & ~3;
510 y = max(0, g_menuscreen_h / 2 - h / 2);
511 w = min(g_menuscreen_w, w);
512 h = min(g_menuscreen_h, h);
513 d = (u16 *)g_menubg_ptr + g_menuscreen_w * y + x;
515 for (; h > 0; h--, d += g_menuscreen_w, s += 1024)
516 if (gpu->ulStatus & 0x200000)
517 bgr888_to_rgb565(d, s, w * 3);
519 bgr555_to_rgb565(d, s, w * 2);
525 // ---------- pandora specific -----------
527 static const char pnd_script_base[] = "sudo -n /usr/pandora/scripts";
528 static char **pnd_filter_list;
530 static int get_cpu_clock(void)
534 f = fopen("/proc/pandora/cpu_mhz_max", "r");
536 fscanf(f, "%d", &ret);
542 static void apply_cpu_clock(void)
546 if (cpu_clock != 0 && cpu_clock != get_cpu_clock()) {
547 snprintf(buf, sizeof(buf), "unset DISPLAY; echo y | %s/op_cpuspeed.sh %d",
548 pnd_script_base, cpu_clock);
553 static void apply_filter(int which)
559 if (pnd_filter_list == NULL || which == old)
562 for (i = 0; i < which; i++)
563 if (pnd_filter_list[i] == NULL)
566 if (pnd_filter_list[i] == NULL)
569 snprintf(buf, sizeof(buf), "%s/op_videofir.sh %s", pnd_script_base, pnd_filter_list[i]);
574 static void apply_lcdrate(int pal)
582 snprintf(buf, sizeof(buf), "%s/op_lcdrate.sh %d",
583 pnd_script_base, pal ? 50 : 60);
588 static menu_entry e_menu_gfx_options[];
590 static void pnd_menu_init(void)
598 cpu_clock_st = cpu_clock = get_cpu_clock();
600 dir = opendir("/etc/pandora/conf/dss_fir");
602 perror("filter opendir");
615 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
624 mfilters = calloc(count + 1, sizeof(mfilters[0]));
625 if (mfilters == NULL)
629 for (i = 0; (ent = readdir(dir)); ) {
632 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
635 len = strlen(ent->d_name);
637 // skip pre-HF5 extra files
638 if (len >= 3 && strcmp(ent->d_name + len - 3, "_v3") == 0)
640 if (len >= 3 && strcmp(ent->d_name + len - 3, "_v5") == 0)
643 // have to cut "_up_h" for pre-HF5
644 if (len > 5 && strcmp(ent->d_name + len - 5, "_up_h") == 0)
647 if (len > sizeof(buff) - 1)
650 strncpy(buff, ent->d_name, len);
652 mfilters[i] = strdup(buff);
653 if (mfilters[i] != NULL)
658 i = me_id2offset(e_menu_gfx_options, MA_OPT_FILTERING);
659 e_menu_gfx_options[i].data = (void *)mfilters;
660 pnd_filter_list = mfilters;
663 void menu_finish(void)
665 cpu_clock = cpu_clock_st;
669 // -------------- key config --------------
671 me_bind_action me_ctrl_actions[] =
673 { "UP ", 1 << DKEY_UP},
674 { "DOWN ", 1 << DKEY_DOWN },
675 { "LEFT ", 1 << DKEY_LEFT },
676 { "RIGHT ", 1 << DKEY_RIGHT },
677 { "TRIANGLE", 1 << DKEY_TRIANGLE },
678 { "CIRCLE ", 1 << DKEY_CIRCLE },
679 { "CROSS ", 1 << DKEY_CROSS },
680 { "SQUARE ", 1 << DKEY_SQUARE },
681 { "L1 ", 1 << DKEY_L1 },
682 { "R1 ", 1 << DKEY_R1 },
683 { "L2 ", 1 << DKEY_L2 },
684 { "R2 ", 1 << DKEY_R2 },
685 { "L3 ", 1 << DKEY_L3 },
686 { "R3 ", 1 << DKEY_R3 },
687 { "START ", 1 << DKEY_START },
688 { "SELECT ", 1 << DKEY_SELECT },
692 me_bind_action emuctrl_actions[] =
694 { "Save State ", 1 << SACTION_SAVE_STATE },
695 { "Load State ", 1 << SACTION_LOAD_STATE },
696 { "Prev Save Slot ", 1 << SACTION_PREV_SSLOT },
697 { "Next Save Slot ", 1 << SACTION_NEXT_SSLOT },
698 { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP },
699 { "Take Screenshot ", 1 << SACTION_SCREENSHOT },
700 { "Enter Menu ", 1 << SACTION_ENTER_MENU },
704 static char *mystrip(char *str)
709 for (i = 0; i < len; i++)
710 if (str[i] != ' ') break;
711 if (i > 0) memmove(str, str + i, len - i + 1);
714 for (i = len - 1; i >= 0; i--)
715 if (str[i] != ' ') break;
721 static void get_line(char *d, size_t size, const char *s)
726 for (pe = s; *pe != '\r' && *pe != '\n' && *pe != 0; pe++)
737 static void keys_write_all(FILE *f)
741 for (d = 0; d < IN_MAX_DEVS; d++)
743 const int *binds = in_get_dev_binds(d);
744 const char *name = in_get_dev_name(d, 0, 0);
747 if (binds == NULL || name == NULL)
750 fprintf(f, "binddev = %s\n", name);
751 in_get_config(d, IN_CFG_BIND_COUNT, &count);
753 for (k = 0; k < count; k++)
758 act[0] = act[31] = 0;
759 name = in_get_key_name(d, k);
761 kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)];
762 for (i = 0; kbinds && i < ARRAY_SIZE(me_ctrl_actions) - 1; i++) {
763 mask = me_ctrl_actions[i].mask;
765 strncpy(act, me_ctrl_actions[i].name, 31);
766 fprintf(f, "bind %s = player1 %s\n", name, mystrip(act));
769 mask = me_ctrl_actions[i].mask << 16;
771 strncpy(act, me_ctrl_actions[i].name, 31);
772 fprintf(f, "bind %s = player2 %s\n", name, mystrip(act));
777 kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)];
778 for (i = 0; kbinds && i < ARRAY_SIZE(emuctrl_actions) - 1; i++) {
779 mask = emuctrl_actions[i].mask;
781 strncpy(act, emuctrl_actions[i].name, 31);
782 fprintf(f, "bind %s = %s\n", name, mystrip(act));
790 static int parse_bind_val(const char *val, int *type)
794 *type = IN_BINDTYPE_NONE;
798 if (strncasecmp(val, "player", 6) == 0)
800 int player, shift = 0;
801 player = atoi(val + 6) - 1;
803 if ((unsigned int)player > 1)
808 *type = IN_BINDTYPE_PLAYER12;
809 for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
810 if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0)
811 return me_ctrl_actions[i].mask << shift;
814 for (i = 0; emuctrl_actions[i].name != NULL; i++) {
815 if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) {
816 *type = IN_BINDTYPE_EMU;
817 return emuctrl_actions[i].mask;
824 static void keys_load_all(const char *cfg)
826 char dev[256], key[128], *act;
832 while (p != NULL && (p = strstr(p, "binddev = ")) != NULL) {
835 get_line(dev, sizeof(dev), p);
836 dev_id = in_config_parse_dev(dev);
838 printf("input: can't handle dev: %s\n", dev);
842 in_unbind_all(dev_id, -1, -1);
843 while ((p = strstr(p, "bind"))) {
844 if (strncmp(p, "binddev = ", 10) == 0)
849 printf("input: parse error: %16s..\n", p);
853 get_line(key, sizeof(key), p);
854 act = strchr(key, '=');
856 printf("parse failed: %16s..\n", p);
864 bind = parse_bind_val(act, &bindtype);
865 if (bind != -1 && bind != 0) {
866 //printf("bind #%d '%s' %08x (%s)\n", dev_id, key, bind, act);
867 in_config_bind_key(dev_id, key, bind, bindtype);
870 lprintf("config: unhandled action \"%s\"\n", act);
876 static int key_config_loop_wrap(int id, int keys)
879 case MA_CTRL_PLAYER1:
880 key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 0);
882 case MA_CTRL_PLAYER2:
883 key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 1);
886 key_config_loop(emuctrl_actions, array_size(emuctrl_actions) - 1, -1);
894 static const char *mgn_dev_name(int id, int *offs)
896 const char *name = NULL;
899 if (id == MA_CTRL_DEV_FIRST)
902 for (; it < IN_MAX_DEVS; it++) {
903 name = in_get_dev_name(it, 1, 1);
912 static const char *mgn_saveloadcfg(int id, int *offs)
917 static int mh_savecfg(int id, int keys)
919 if (menu_write_config(id == MA_OPT_SAVECFG_GAME ? 1 : 0) == 0)
920 me_update_msg("config saved");
922 me_update_msg("failed to write config");
927 static int mh_input_rescan(int id, int keys)
929 //menu_sync_config();
930 pandora_rescan_inputs();
931 me_update_msg("rescan complete.");
936 static const char *men_in_type_sel[] = { "Standard (SCPH-1080)", "Analog (SCPH-1150)", NULL };
937 static const char h_nub_btns[] = "Experimental, keep this OFF if unsure. Select rescan after change.";
939 static menu_entry e_menu_keyconfig[] =
941 mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap),
942 mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap),
943 mee_handler_id("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap),
945 mee_enum ("Controller", 0, in_type_sel, men_in_type_sel),
946 mee_onoff_h ("Nubs as buttons", 0, in_evdev_allow_abs_only, 1, h_nub_btns),
947 mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg),
948 mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg),
949 mee_handler ("Rescan devices", mh_input_rescan),
951 mee_label ("Input devices:"),
952 mee_label_mk (MA_CTRL_DEV_FIRST, mgn_dev_name),
953 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
954 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
955 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
956 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
957 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
958 mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
962 static int menu_loop_keyconfig(int id, int keys)
966 // me_enable(e_menu_keyconfig, MA_OPT_SAVECFG_GAME, ready_to_go && CdromId[0]);
967 me_loop(e_menu_keyconfig, &sel, NULL);
971 // ------------ gfx options menu ------------
973 static const char *men_scaler[] = { "1x1", "scaled 4:3", "fullscreen", "custom", NULL };
974 static const char h_cscaler[] = "Displays the scaler layer, you can resize it\n"
975 "using d-pad or move it using R+d-pad";
976 static const char *men_dummy[] = { NULL };
978 static int menu_loop_cscaler(int id, int keys)
982 scaling = SCALE_CUSTOM;
984 omap_enable_layer(1);
989 memset(g_menuscreen_ptr, 4, g_menuscreen_w * g_menuscreen_h * 2);
990 text_out16(2, 2, "%d,%d", g_layer_x, g_layer_y);
991 text_out16(2, 480 - 18, "%dx%d | d-pad: resize, R+d-pad: move", g_layer_w, g_layer_h);
994 inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_R|PBTN_MOK|PBTN_MBACK, 40);
995 if (inp & PBTN_UP) g_layer_y--;
996 if (inp & PBTN_DOWN) g_layer_y++;
997 if (inp & PBTN_LEFT) g_layer_x--;
998 if (inp & PBTN_RIGHT) g_layer_x++;
999 if (!(inp & PBTN_R)) {
1000 if (inp & PBTN_UP) g_layer_h += 2;
1001 if (inp & PBTN_DOWN) g_layer_h -= 2;
1002 if (inp & PBTN_LEFT) g_layer_w += 2;
1003 if (inp & PBTN_RIGHT) g_layer_w -= 2;
1005 if (inp & (PBTN_MOK|PBTN_MBACK))
1008 if (inp & (PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT)) {
1009 if (g_layer_x < 0) g_layer_x = 0;
1010 if (g_layer_x > 640) g_layer_x = 640;
1011 if (g_layer_y < 0) g_layer_y = 0;
1012 if (g_layer_y > 420) g_layer_y = 420;
1013 if (g_layer_w < 160) g_layer_w = 160;
1014 if (g_layer_h < 60) g_layer_h = 60;
1015 if (g_layer_x + g_layer_w > 800)
1016 g_layer_w = 800 - g_layer_x;
1017 if (g_layer_y + g_layer_h > 480)
1018 g_layer_h = 480 - g_layer_y;
1019 omap_enable_layer(1);
1023 omap_enable_layer(0);
1028 static menu_entry e_menu_gfx_options[] =
1030 mee_enum ("Scaler", 0, scaling, men_scaler),
1031 mee_enum ("Filter", MA_OPT_FILTERING, filter, men_dummy),
1032 // mee_onoff ("Vsync", 0, vsync, 1),
1033 mee_cust_h ("Setup custom scaler", 0, menu_loop_cscaler, NULL, h_cscaler),
1037 static int menu_loop_gfx_options(int id, int keys)
1041 me_loop(e_menu_gfx_options, &sel, NULL);
1046 // ------------ bios/plugins ------------
1048 static const char *men_gpu_dithering[] = { "None", "Game dependant", "Always", NULL };
1049 static const char h_gpu_0[] = "Needed for Chrono Cross";
1050 static const char h_gpu_1[] = "Capcom fighting games";
1051 static const char h_gpu_2[] = "Black screens in Lunar";
1052 static const char h_gpu_3[] = "Compatibility mode";
1053 static const char h_gpu_6[] = "Pandemonium 2";
1054 static const char h_gpu_7[] = "Skip every second frame";
1055 static const char h_gpu_8[] = "Needed by Dark Forces";
1056 static const char h_gpu_9[] = "better g-colors, worse textures";
1057 static const char h_gpu_10[] = "Toggle busy flags after drawing";
1059 static menu_entry e_menu_plugin_gpu[] =
1061 mee_enum ("Dithering", 0, pl_rearmed_cbs.gpu_peops.iUseDither, men_gpu_dithering),
1062 mee_onoff_h ("Odd/even bit hack", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<0, h_gpu_0),
1063 mee_onoff_h ("Expand screen width", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<1, h_gpu_1),
1064 mee_onoff_h ("Ignore brightness color", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<2, h_gpu_2),
1065 mee_onoff_h ("Disable coordinate check", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<3, h_gpu_3),
1066 mee_onoff_h ("Lazy screen update", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<6, h_gpu_6),
1067 mee_onoff_h ("Old frame skipping", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<7, h_gpu_7),
1068 mee_onoff_h ("Repeated flat tex triangles ",0,pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<8, h_gpu_8),
1069 mee_onoff_h ("Draw quads with triangles", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<9, h_gpu_9),
1070 mee_onoff_h ("Fake 'gpu busy' states", 0, pl_rearmed_cbs.gpu_peops.dwActFixes, 1<<10, h_gpu_10),
1074 static int menu_loop_plugin_gpu(int id, int keys)
1077 me_loop(e_menu_plugin_gpu, &sel, NULL);
1081 static const char *men_spu_reverb[] = { "Off", "Fake", "On", NULL };
1082 static const char *men_spu_interp[] = { "None", "Simple", "Gaussian", "Cubic", NULL };
1083 static const char h_spu_irq_wait[] = "Wait for CPU (recommended set to ON)";
1084 static const char h_spu_thread[] = "Run sound emulation in main thread (recommended)";
1086 static menu_entry e_menu_plugin_spu[] =
1088 mee_enum ("Reverb", 0, iUseReverb, men_spu_reverb),
1089 mee_enum ("Interpolation", 0, iUseInterpolation, men_spu_interp),
1090 mee_onoff ("Adjust XA pitch", 0, iXAPitch, 1),
1091 mee_onoff_h ("SPU IRQ Wait", 0, iSPUIRQWait, 1, h_spu_irq_wait),
1092 mee_onoff_h ("Sound in main thread", 0, iUseTimer, 2, h_spu_thread),
1096 static int menu_loop_plugin_spu(int id, int keys)
1099 me_loop(e_menu_plugin_spu, &sel, NULL);
1103 static const char h_bios[] = "HLE is simulated BIOS. BIOS selection is saved in savestates\n"
1104 "and can't be changed there. Must save config and reload\n"
1105 "the game for change to take effect";
1106 static const char h_plugin_xpu[] = "Must save config and reload the game\n"
1107 "for plugin change to take effect";
1108 static const char h_gpu[] = "Configure P.E.Op.S. SoftGL Driver V1.17";
1109 static const char h_spu[] = "Configure built-in P.E.Op.S. Sound Driver V1.7";
1111 static menu_entry e_menu_plugin_options[] =
1113 mee_enum_h ("BIOS", 0, bios_sel, bioses, h_bios),
1114 mee_enum_h ("GPU plugin", 0, gpu_plugsel, gpu_plugins, h_plugin_xpu),
1115 mee_enum_h ("SPU plugin", 0, spu_plugsel, spu_plugins, h_plugin_xpu),
1116 mee_handler_h ("Configure gpu_peops plugin", menu_loop_plugin_gpu, h_gpu),
1117 mee_handler_h ("Configure built-in SPU plugin", menu_loop_plugin_spu, h_spu),
1121 static menu_entry e_menu_main[];
1123 static int menu_loop_plugin_options(int id, int keys)
1126 me_loop(e_menu_plugin_options, &sel, NULL);
1128 // sync BIOS/plugins
1129 snprintf(Config.Bios, sizeof(Config.Bios), "%s", bioses[bios_sel]);
1130 snprintf(Config.Gpu, sizeof(Config.Gpu), "%s", gpu_plugins[gpu_plugsel]);
1131 snprintf(Config.Spu, sizeof(Config.Spu), "%s", spu_plugins[spu_plugsel]);
1132 me_enable(e_menu_main, MA_MAIN_RUN_BIOS, bios_sel != 0);
1137 // ------------ adv options menu ------------
1139 static const char h_cfg_cpul[] = "Shows CPU usage in %";
1140 static const char h_cfg_fl[] = "Frame Limiter keeps the game from running too fast";
1141 static const char h_cfg_xa[] = "Disables XA sound, which can sometimes improve performance";
1142 static const char h_cfg_cdda[] = "Disable CD Audio for a performance boost\n"
1143 "(proper .cue/.bin dump is needed otherwise)";
1144 static const char h_cfg_sio[] = "This should be enabled for certain memcards/gamepads";
1145 static const char h_cfg_spuirq[] = "Compatibility tweak; should probably be left off";
1146 static const char h_cfg_rcnt1[] = "Parasite Eve 2, Vandal Hearts 1/2 Fix";
1147 static const char h_cfg_rcnt2[] = "InuYasha Sengoku Battle Fix";
1148 static const char h_cfg_nodrc[] = "Disable dynamic recompiler and use interpreter\n"
1149 "Might be useful to overcome some dynarec bugs";
1151 static menu_entry e_menu_adv_options[] =
1153 mee_onoff_h ("Show CPU load", 0, g_opts, OPT_SHOWCPU, h_cfg_cpul),
1154 mee_onoff_h ("Disable Frame Limiter", 0, g_opts, OPT_NO_FRAMELIM, h_cfg_fl),
1155 mee_onoff_h ("Disable XA Decoding", 0, Config.Xa, 1, h_cfg_xa),
1156 mee_onoff_h ("Disable CD Audio", 0, Config.Cdda, 1, h_cfg_cdda),
1157 mee_onoff_h ("SIO IRQ Always Enabled", 0, Config.Sio, 1, h_cfg_sio),
1158 mee_onoff_h ("SPU IRQ Always Enabled", 0, Config.SpuIrq, 1, h_cfg_spuirq),
1159 mee_onoff_h ("Rootcounter hack", 0, Config.RCntFix, 1, h_cfg_rcnt1),
1160 mee_onoff_h ("Rootcounter hack 2", 0, Config.VSyncWA, 1, h_cfg_rcnt2),
1161 mee_onoff_h ("Disable dynarec (slow!)",0, Config.Cpu, 1, h_cfg_nodrc),
1165 static int menu_loop_adv_options(int id, int keys)
1168 me_loop(e_menu_adv_options, &sel, NULL);
1172 // ------------ options menu ------------
1174 static int mh_restore_defaults(int id, int keys)
1176 menu_set_defconfig();
1177 me_update_msg("defaults restored");
1181 static const char *men_region[] = { "Auto", "NTSC", "PAL", NULL };
1183 static const char *men_confirm_save[] = { "OFF", "writes", "loads", "both", NULL };
1184 static const char h_confirm_save[] = "Ask for confirmation when overwriting save,\n"
1185 "loading state or both";
1187 static const char h_restore_def[] = "Switches back to default / recommended\n"
1189 static const char h_frameskip[] = "Warning: frameskip sometimes causes glitches\n";
1191 static menu_entry e_menu_options[] =
1193 // mee_range ("Save slot", 0, state_slot, 0, 9),
1194 // mee_enum_h ("Confirm savestate", 0, dummy, men_confirm_save, h_confirm_save),
1195 mee_onoff_h ("Frameskip", 0, pl_rearmed_cbs.frameskip, 1, h_frameskip),
1196 mee_onoff ("Show FPS", 0, g_opts, OPT_SHOWFPS),
1197 mee_enum ("Region", 0, region, men_region),
1198 mee_range ("CPU clock", MA_OPT_CPU_CLOCKS, cpu_clock, 20, 5000),
1199 mee_handler ("[Display]", menu_loop_gfx_options),
1200 mee_handler ("[BIOS/Plugins]", menu_loop_plugin_options),
1201 mee_handler ("[Advanced]", menu_loop_adv_options),
1202 mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg),
1203 mee_cust_nosave("Save cfg for loaded game",MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg),
1204 mee_handler_h ("Restore default config", mh_restore_defaults, h_restore_def),
1208 static int menu_loop_options(int id, int keys)
1213 i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);
1214 e_menu_options[i].enabled = cpu_clock != 0 ? 1 : 0;
1215 me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, ready_to_go && CdromId[0]);
1217 me_loop(e_menu_options, &sel, NULL);
1222 // ------------ debug menu ------------
1224 static void draw_frame_debug(GPUFreeze_t *gpuf)
1226 int w = min(g_menuscreen_w, 1024);
1227 int h = min(g_menuscreen_h, 512);
1228 u16 *d = g_menuscreen_ptr;
1229 u16 *s = (u16 *)gpuf->psxVRam;
1233 gpuf->ulFreezeVersion = 1;
1234 if (GPU_freeze != NULL)
1235 GPU_freeze(1, gpuf);
1237 for (; h > 0; h--, d += g_menuscreen_w, s += 1024)
1238 bgr555_to_rgb565(d, s, w * 2);
1240 smalltext_out16(4, 1, "build: "__DATE__ " " __TIME__ " " REV, 0xe7fc);
1241 snprintf(buff, sizeof(buff), "GPU sr: %08x", gpuf->ulStatus);
1242 smalltext_out16(4, (ty += me_sfont_h), buff, 0xe7fc);
1243 snprintf(buff, sizeof(buff), "PC/SP: %08x %08x", psxRegs.pc, psxRegs.GPR.n.sp);
1244 smalltext_out16(4, (ty += me_sfont_h), buff, 0xe7fc);
1247 static void debug_menu_loop(void)
1252 gpuf = malloc(sizeof(*gpuf));
1259 draw_frame_debug(gpuf);
1262 inp = in_menu_wait(PBTN_MOK|PBTN_MBACK|PBTN_MA2|PBTN_MA3|PBTN_L|PBTN_R |
1263 PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT, 70);
1264 if (inp & PBTN_MBACK)
1271 // ------------ main menu ------------
1273 static void menu_bios_warn(void)
1276 static const char msg[] =
1277 "You don't seem to have copied any BIOS files to\n"
1278 "<SD card>/pandora/appdata/pcsx_rearmed/bios/\n\n"
1279 "While many games work fine with fake (HLE) BIOS,\n"
1280 "others (like MGS and FF8) require BIOS to work.\n"
1281 "After copying the file, you'll also need to\n"
1282 "select it in the emu's options->[BIOS/Plugins]\n\n"
1283 "The file is usually named SCPH1001.BIN, but\n"
1284 "other not compressed files can be used too.\n\n"
1285 "Press (B) or (X) to continue";
1289 draw_menu_message(msg, NULL);
1291 inp = in_menu_wait(PBTN_MOK|PBTN_MBACK, 70);
1292 if (inp & (PBTN_MBACK|PBTN_MOK))
1297 // ------------ main menu ------------
1301 static void draw_frame_main(void)
1303 if (CdromId[0] != 0) {
1305 snprintf(buff, sizeof(buff), "%.32s/%.9s (running as %s, with %s)",
1306 get_cd_label(), CdromId, Config.PsxType ? "PAL" : "NTSC",
1307 Config.HLE ? "HLE" : "BIOS");
1308 smalltext_out16(4, 1, buff, 0x105f);
1312 static void draw_frame_credits(void)
1314 smalltext_out16(4, 1, "build: "__DATE__ " " __TIME__ " " REV, 0xe7fc);
1317 static const char credits_text[] =
1319 "(C) 1999-2003 PCSX Team\n"
1320 "(C) 2005-2009 PCSX-df Team\n"
1321 "(C) 2009-2011 PCSX-Reloaded Team\n\n"
1322 "GPU and SPU code by Pete Bernert\n"
1323 " and the P.E.Op.S. team\n"
1324 "ARM recompiler (C) 2009-2011 Ari64\n"
1325 "PCSX4ALL plugins by PCSX4ALL team\n"
1326 " Chui, Franxis, Unai\n\n"
1327 "integration, optimization and\n"
1328 " frontend (C) 2010-2011 notaz\n";
1330 static int reset_game(void)
1333 if (bios_sel == 0 && !Config.HLE)
1339 if (CheckCdrom() != -1) {
1345 static int run_bios(void)
1351 pl_fbdev_buf = NULL;
1356 pcnt_hook_plugins();
1358 if (OpenPlugins() == -1) {
1359 me_update_msg("failed to open plugins");
1362 plugin_call_rearmed_cbs();
1365 CdromLabel[0] = '\0';
1373 static int run_cd_image(const char *fname)
1376 pl_fbdev_buf = NULL;
1379 set_cd_image(fname);
1381 pcnt_hook_plugins();
1383 if (OpenPlugins() == -1) {
1384 me_update_msg("failed to open plugins");
1387 plugin_call_rearmed_cbs();
1389 if (CheckCdrom() == -1) {
1390 // Only check the CD if we are starting the console with a CD
1392 me_update_msg("unsupported/invalid CD image");
1398 // Read main executable directly from CDRom and start it
1399 if (LoadCdrom() == -1) {
1401 me_update_msg("failed to load CD image");
1409 static int romsel_run(void)
1411 int prev_gpu, prev_spu;
1414 fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
1418 printf("selected file: %s\n", fname);
1420 new_dynarec_clear_full();
1422 if (run_cd_image(fname) != 0)
1425 prev_gpu = gpu_plugsel;
1426 prev_spu = spu_plugsel;
1427 if (menu_load_config(1) != 0)
1428 menu_load_config(0);
1430 // check for plugin changes, have to repeat
1431 // loading if game config changed plugins to reload them
1432 if (prev_gpu != gpu_plugsel || prev_spu != spu_plugsel) {
1433 printf("plugin change detected, reloading plugins..\n");
1434 if (run_cd_image(fname) != 0)
1438 strcpy(last_selected_fname, rom_fname_reload);
1442 static int swap_cd_image(void)
1446 fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname));
1450 printf("selected file: %s\n", fname);
1453 CdromLabel[0] = '\0';
1455 set_cd_image(fname);
1456 if (ReloadCdromPlugin() < 0) {
1457 me_update_msg("failed to load cdr plugin");
1460 if (CDR_open() < 0) {
1461 me_update_msg("failed to open cdr plugin");
1465 SetCdOpenCaseTime(time(NULL) + 2);
1468 strcpy(last_selected_fname, rom_fname_reload);
1472 static int main_menu_handler(int id, int keys)
1476 case MA_MAIN_RESUME_GAME:
1480 case MA_MAIN_SAVE_STATE:
1482 return menu_loop_savestate(0);
1484 case MA_MAIN_LOAD_STATE:
1486 return menu_loop_savestate(1);
1488 case MA_MAIN_RESET_GAME:
1489 if (ready_to_go && reset_game() == 0)
1492 case MA_MAIN_LOAD_ROM:
1493 if (romsel_run() == 0)
1496 case MA_MAIN_SWAP_CD:
1497 if (swap_cd_image() == 0)
1500 case MA_MAIN_RUN_BIOS:
1501 if (run_bios() == 0)
1504 case MA_MAIN_CREDITS:
1505 draw_menu_message(credits_text, draw_frame_credits);
1506 in_menu_wait(PBTN_MOK|PBTN_MBACK, 70);
1512 lprintf("%s: something unknown selected\n", __FUNCTION__);
1519 static menu_entry e_menu_main[] =
1523 mee_handler_id("Resume game", MA_MAIN_RESUME_GAME, main_menu_handler),
1524 mee_handler_id("Save State", MA_MAIN_SAVE_STATE, main_menu_handler),
1525 mee_handler_id("Load State", MA_MAIN_LOAD_STATE, main_menu_handler),
1526 mee_handler_id("Reset game", MA_MAIN_RESET_GAME, main_menu_handler),
1527 mee_handler_id("Load CD image", MA_MAIN_LOAD_ROM, main_menu_handler),
1528 mee_handler_id("Change CD image", MA_MAIN_SWAP_CD, main_menu_handler),
1529 mee_handler_id("Run BIOS", MA_MAIN_RUN_BIOS, main_menu_handler),
1530 mee_handler ("Options", menu_loop_options),
1531 mee_handler ("Controls", menu_loop_keyconfig),
1532 mee_handler_id("Credits", MA_MAIN_CREDITS, main_menu_handler),
1533 mee_handler_id("Exit", MA_MAIN_EXIT, main_menu_handler),
1537 // ----------------------------
1539 static void menu_leave_emu(void);
1541 void menu_loop(void)
1547 if (bioses[1] == NULL && !warned_about_bios) {
1549 warned_about_bios = 1;
1552 me_enable(e_menu_main, MA_MAIN_RESUME_GAME, ready_to_go);
1553 me_enable(e_menu_main, MA_MAIN_SAVE_STATE, ready_to_go && CdromId[0]);
1554 me_enable(e_menu_main, MA_MAIN_LOAD_STATE, ready_to_go && CdromId[0]);
1555 me_enable(e_menu_main, MA_MAIN_RESET_GAME, ready_to_go);
1556 me_enable(e_menu_main, MA_MAIN_SWAP_CD, ready_to_go);
1557 me_enable(e_menu_main, MA_MAIN_RUN_BIOS, bios_sel != 0);
1559 in_set_config_int(0, IN_CFG_BLOCKING, 1);
1562 me_loop(e_menu_main, &sel, draw_frame_main);
1563 } while (!ready_to_go);
1565 /* wait until menu, ok, back is released */
1566 while (in_menu_wait_any(50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
1569 in_set_config_int(0, IN_CFG_BLOCKING, 0);
1574 static void scan_bios_plugins(void)
1576 char fname[MAXPATHLEN];
1578 int bios_i, gpu_i, spu_i;
1583 gpu_plugins[0] = "builtin_gpu";
1584 spu_plugins[0] = "builtin_spu";
1585 bios_i = gpu_i = spu_i = 1;
1587 snprintf(fname, sizeof(fname), "%s/", Config.BiosDir);
1588 dir = opendir(fname);
1590 perror("scan_bios_plugins bios opendir");
1605 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
1608 snprintf(fname, sizeof(fname), "%s/%s", Config.BiosDir, ent->d_name);
1609 if (stat(fname, &st) != 0 || st.st_size != 512*1024) {
1610 printf("bad BIOS file: %s\n", ent->d_name);
1614 if (bios_i < ARRAY_SIZE(bioses) - 1) {
1615 bioses[bios_i++] = strdup(ent->d_name);
1619 printf("too many BIOSes, dropping \"%s\"\n", ent->d_name);
1625 snprintf(fname, sizeof(fname), "%s/", Config.PluginsDir);
1626 dir = opendir(fname);
1628 perror("scan_bios_plugins opendir");
1642 p = strstr(ent->d_name, ".so");
1646 snprintf(fname, sizeof(fname), "%s/%s", Config.PluginsDir, ent->d_name);
1647 h = dlopen(fname, RTLD_LAZY | RTLD_LOCAL);
1649 fprintf(stderr, "%s\n", dlerror());
1653 // now what do we have here?
1654 tmp = dlsym(h, "GPUinit");
1657 if (gpu_i < ARRAY_SIZE(gpu_plugins) - 1)
1658 gpu_plugins[gpu_i++] = strdup(ent->d_name);
1662 tmp = dlsym(h, "SPUinit");
1665 if (spu_i < ARRAY_SIZE(spu_plugins) - 1)
1666 spu_plugins[spu_i++] = strdup(ent->d_name);
1670 fprintf(stderr, "ignoring unidentified plugin: %s\n", fname);
1677 void menu_init(void)
1679 char buff[MAXPATHLEN];
1681 strcpy(last_selected_fname, "/media");
1683 scan_bios_plugins();
1687 menu_set_defconfig();
1688 menu_load_config(0);
1693 g_menubg_src_ptr = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1);
1694 if (g_menubg_src_ptr == NULL)
1696 emu_make_path(buff, "skin/background.png", sizeof(buff));
1697 readpng(g_menubg_src_ptr, buff, READPNG_BG, g_menuscreen_w, g_menuscreen_h);
1700 void menu_notify_mode_change(int w, int h, int bpp)
1706 if (scaling == SCALE_1_1) {
1707 g_layer_x = 800/2 - w/2; g_layer_y = 480/2 - h/2;
1708 g_layer_w = w; g_layer_h = h;
1712 static void menu_leave_emu(void)
1714 if (GPU_close != NULL) {
1715 int ret = GPU_close();
1717 fprintf(stderr, "Warning: GPU_close returned %d\n", ret);
1720 memcpy(g_menubg_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2);
1721 if (pl_fbdev_buf != NULL && ready_to_go && last_psx_bpp == 16) {
1722 int x = max(0, g_menuscreen_w - last_psx_w);
1723 int y = max(0, g_menuscreen_h / 2 - last_psx_h / 2);
1724 int w = min(g_menuscreen_w, last_psx_w);
1725 int h = min(g_menuscreen_h, last_psx_h);
1726 u16 *d = (u16 *)g_menubg_ptr + g_menuscreen_w * y + x;
1727 u16 *s = pl_fbdev_buf;
1729 for (; h > 0; h--, d += g_menuscreen_w, s += last_psx_w)
1730 menu_darken_bg(d, s, w, 0);
1734 cpu_clock = get_cpu_clock();
1736 plat_video_menu_enter(ready_to_go);
1739 void menu_prepare_emu(void)
1741 R3000Acpu *prev_cpu = psxCpu;
1743 plat_video_menu_leave();
1747 menu_notify_mode_change(last_psx_w, last_psx_h, last_psx_bpp);
1750 g_layer_x = 80; g_layer_y = 0;
1751 g_layer_w = 640; g_layer_h = 480;
1753 case SCALE_FULLSCREEN:
1754 g_layer_x = 0; g_layer_y = 0;
1755 g_layer_w = 800; g_layer_h = 480;
1761 psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec;
1762 if (psxCpu != prev_cpu)
1763 // note that this does not really reset, just clears drc caches
1766 // core doesn't care about Config.Cdda changes,
1767 // so handle them manually here
1772 apply_lcdrate(Config.PsxType);
1773 apply_filter(filter);
1776 // push config to GPU plugin
1777 plugin_call_rearmed_cbs();
1779 if (GPU_open != NULL) {
1780 int ret = GPU_open(&gpuDisp, "PCSX", NULL);
1782 fprintf(stderr, "Warning: GPU_open returned %d\n", ret);
1785 dfinput_activate(in_type == PSE_PAD_TYPE_ANALOGPAD);
1788 void me_update_msg(const char *msg)
1790 strncpy(menu_error_msg, msg, sizeof(menu_error_msg));
1791 menu_error_msg[sizeof(menu_error_msg) - 1] = 0;
1793 menu_error_time = plat_get_ticks_ms();
1794 lprintf("msg: %s\n", menu_error_msg);