-#include "emu.h"
+/*
+ * PicoDrive
+ * (C) notaz, 2010,2011
+ *
+ * This work is licensed under the terms of MAME license.
+ * See COPYING file in the top-level directory.
+ */
+#include <stdio.h>
+#include <string.h>
-#include <version.h>
-#include <revision.h>
+#include "emu.h"
+#include "menu_pico.h"
+#include "input_pico.h"
+#include "version.h"
#include <pico/pico.h>
#include <pico/patch.h>
-#include "menu.c"
+#ifdef PANDORA
+#define MENU_X2 1
+#else
+#define MENU_X2 0
+#endif
+
+// FIXME
+#define REVISION "0"
+
+static const char *rom_exts[] = {
+ "zip",
+ "bin", "smd", "gen", "md",
+ "iso", "cso", "cue",
+ "32x",
+ "sms",
+ NULL
+};
+
+// rrrr rggg gggb bbbb
+static unsigned short fname2color(const char *fname)
+{
+ static const char *other_exts[] = { "gmv", "pat" };
+ const char *ext;
+ int i;
+
+ ext = strrchr(fname, '.');
+ if (ext++ == NULL) {
+ ext = fname + strlen(fname) - 3;
+ if (ext < fname) ext = fname;
+ }
+
+ for (i = 0; rom_exts[i] != NULL; i++)
+ if (strcasecmp(ext, rom_exts[i]) == 0) return 0xbdff; // FIXME: mk defines
+ for (i = 0; i < array_size(other_exts); i++)
+ if (strcasecmp(ext, other_exts[i]) == 0) return 0xaff5;
+ return 0xffff;
+}
+
+#include "../libpicofe/menu.c"
+
+static const char *men_dummy[] = { NULL };
/* platform specific options and handlers */
#if defined(__GP2X__)
#define menu_main_plat_draw NULL
#endif
+static void make_bg(int no_scale)
+{
+ unsigned short *src = (void *)g_menubg_src_ptr;
+ int w = g_screen_width, h = g_screen_height;
+ short *dst;
+ int x, y;
+
+ if (src == NULL) {
+ memset(g_menubg_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
+ return;
+ }
+
+ if (!no_scale && g_menuscreen_w / w >= 2 && g_menuscreen_h / h >= 2)
+ {
+ unsigned int t, *d = g_menubg_ptr;
+ d += (g_menuscreen_h / 2 - h * 2 / 2)
+ * g_menuscreen_w / 2;
+ d += (g_menuscreen_w / 2 - w * 2 / 2) / 2;
+ for (y = 0; y < h; y++, src += w, d += g_menuscreen_w*2/2) {
+ for (x = 0; x < w; x++) {
+ t = src[x];
+ t = ((t & 0xf79e)>>1) - ((t & 0xc618)>>3);
+ t |= t << 16;
+ d[x] = d[x + g_menuscreen_w / 2] = t;
+ }
+ }
+ return;
+ }
+
+ if (w > g_menuscreen_w)
+ w = g_menuscreen_w;
+ if (h > g_menuscreen_h)
+ h = g_menuscreen_h;
+ dst = (short *)g_menubg_ptr +
+ (g_menuscreen_h / 2 - h / 2) * g_menuscreen_w +
+ (g_menuscreen_w / 2 - w / 2);
+
+ // darken the active framebuffer
+ for (; h > 0; dst += g_menuscreen_w, src += g_screen_width, h--)
+ menu_darken_bg(dst, src, w, 1);
+}
+
+static void menu_enter(int is_rom_loaded)
+{
+ if (is_rom_loaded)
+ {
+ make_bg(0);
+ }
+ else
+ {
+ char buff[256];
+
+ // should really only happen once, on startup..
+ emu_make_path(buff, "skin/background.png", sizeof(buff));
+ if (readpng(g_menubg_ptr, buff, READPNG_BG, g_menuscreen_w, g_menuscreen_h) < 0)
+ memset(g_menubg_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
+ }
+
+ plat_video_menu_enter(is_rom_loaded);
+}
+
static void draw_savestate_bg(int slot)
{
const char *fname;
/* do a frame and fetch menu bg */
pemu_forced_frame(0, 0);
- menu_darken_bg(g_menubg_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h, 1);
+ make_bg(0);
PicoTmpStateRestore(tmp_state);
}
if (len > g_menuscreen_w)
len = g_menuscreen_w;
- menu_draw_begin(0);
+ menu_draw_begin(0, 1);
dst = (unsigned short *)g_menuscreen_ptr + g_menuscreen_w * me_sfont_h * 2;
for (ln = me_sfont_h - 2; ln > 0; ln--, dst += g_menuscreen_w)
memset(dst, 0xff, len * 2);
int ln, len = percent * g_menuscreen_w / 100;
unsigned short *dst;
- menu_draw_begin(0);
+ menu_draw_begin(0, 1);
dst = (unsigned short *)g_menuscreen_ptr + g_menuscreen_w * me_sfont_h * 2;
memset(dst, 0xff, g_menuscreen_w * (me_sfont_h - 2) * 2);
/* fill all buffers, callbacks won't update in full */
for (i = 0; i < 3; i++) {
- menu_draw_begin(1);
+ menu_draw_begin(1, 1);
smalltext_out16(1, 1, "Loading", 0xffff);
smalltext_out16(1, me_sfont_h, p, 0xffff);
menu_draw_end();
PicoCartLoadProgressCB = NULL;
PicoCDLoadProgressCB = NULL;
- menu_draw_begin(0);
+ menu_draw_begin(0, 1);
smalltext_out16(1, (cdload_called ? 6 : 3) * me_sfont_h,
"Starting emulation...", 0xffff);
menu_draw_end();
max_cnt = g_menuscreen_h / me_sfont_h;
start = max_cnt / 2 - sel;
- menu_draw_begin(1);
+ menu_draw_begin(1, 0);
for (i = 0; i < PicoPatchCount; i++) {
pos = start + i;
for (;;)
{
draw_patchlist(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R|PBTN_MOK|PBTN_MBACK, 33);
+ inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R
+ |PBTN_MOK|PBTN_MBACK, NULL, 33);
if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = PicoPatchCount; }
if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > PicoPatchCount) menu_sel = 0; }
if (inp &(PBTN_LEFT|PBTN_L)) { menu_sel-=10; if (menu_sel < 0) menu_sel = 0; }
{
static int sel = 0;
- me_enable(e_menu_keyconfig, MA_OPT_SAVECFG_GAME, rom_loaded);
- me_loop(e_menu_keyconfig, &sel, NULL);
+ me_enable(e_menu_keyconfig, MA_OPT_SAVECFG_GAME, PicoGameLoaded);
+ me_loop(e_menu_keyconfig, &sel);
return 0;
}
static int menu_loop_cd_options(int id, int keys)
{
static int sel = 0;
- me_loop(e_menu_cd_options, &sel, NULL);
+ me_loop(e_menu_cd_options, &sel);
return 0;
}
// convert from multiplier of VClk
static int mh_opt_sh2cycles(int id, int keys)
{
- int *mul = (id == MA_32XOPT_MSH2_CYCLES) ? &p32x_msh2_multiplier : &p32x_ssh2_multiplier;
+ int *khz = (id == MA_32XOPT_MSH2_CYCLES) ?
+ ¤tConfig.msh2_khz : ¤tConfig.ssh2_khz;
if (keys & (PBTN_LEFT|PBTN_RIGHT))
- *mul += (keys & PBTN_LEFT) ? -10 : 10;
+ *khz += (keys & PBTN_LEFT) ? -50 : 50;
if (keys & (PBTN_L|PBTN_R))
- *mul += (keys & PBTN_L) ? -100 : 100;
+ *khz += (keys & PBTN_L) ? -500 : 500;
- if (*mul < 1)
- *mul = 1;
- else if (*mul > (10 << SH2_MULTI_SHIFT))
- *mul = 10 << SH2_MULTI_SHIFT;
+ if (*khz < 1)
+ *khz = 1;
+ else if (*khz > 0x7fffffff / 1000)
+ *khz = 0x7fffffff / 1000;
return 0;
}
static const char *mgn_opt_sh2cycles(int id, int *offs)
{
- int mul = (id == MA_32XOPT_MSH2_CYCLES) ? p32x_msh2_multiplier : p32x_ssh2_multiplier;
-
- sprintf(static_buff, "%d", 7670 * mul >> SH2_MULTI_SHIFT);
+ int khz = (id == MA_32XOPT_MSH2_CYCLES) ?
+ currentConfig.msh2_khz : currentConfig.ssh2_khz;
+
+ sprintf(static_buff, "%d", khz);
return static_buff;
}
static const char h_32x_enable[] = "Enable emulation of the 32X addon";
static const char h_pwm[] = "Disabling may improve performance, but break sound";
static const char h_sh2cycles[] = "Cycles/millisecond (similar to DOSBox)\n"
- "lower values speed up emulation but break games\n"
- "at least 11000 recommended for compatibility";
+ "lower values speed up emulation but break games\n"
+ "at least 11000 recommended for compatibility";
static menu_entry e_menu_32x_options[] =
{
static int sel = 0;
me_enable(e_menu_32x_options, MA_32XOPT_RENDERER, renderer_names32x[0] != NULL);
- me_loop(e_menu_32x_options, &sel, NULL);
+ me_loop(e_menu_32x_options, &sel);
+
+ Pico32xSetClocks(currentConfig.msh2_khz * 1000, currentConfig.msh2_khz * 1000);
return 0;
}
static int menu_loop_adv_options(int id, int keys)
{
static int sel = 0;
- me_loop(e_menu_adv_options, &sel, NULL);
+ me_loop(e_menu_adv_options, &sel);
return 0;
}
// ------------ gfx options menu ------------
+static const char h_gamma[] = "Gamma/brightness adjustment (default 100)";
+
static menu_entry e_menu_gfx_options[] =
{
- mee_enum("Renderer", MA_OPT_RENDERER, currentConfig.renderer, renderer_names),
+ mee_enum ("Video output mode", MA_OPT_VOUT_MODE, plat_target.vout_method, men_dummy),
+ mee_enum ("Renderer", MA_OPT_RENDERER, currentConfig.renderer, renderer_names),
+ mee_enum ("Filter", MA_OPT3_FILTERING, currentConfig.filter, men_dummy),
+ mee_range_h("Gamma adjustment", MA_OPT3_GAMMA, currentConfig.gamma, 1, 200, h_gamma),
MENU_OPTIONS_GFX
mee_end,
};
static int sel = 0;
me_enable(e_menu_gfx_options, MA_OPT_RENDERER, renderer_names[0] != NULL);
- me_loop(e_menu_gfx_options, &sel, NULL);
+ me_loop(e_menu_gfx_options, &sel);
return 0;
}
case MA_OPT_SAVECFG:
case MA_OPT_SAVECFG_GAME:
if (emu_write_config(id == MA_OPT_SAVECFG_GAME ? 1 : 0))
- me_update_msg("config saved");
+ menu_update_msg("config saved");
else
- me_update_msg("failed to write config");
+ menu_update_msg("failed to write config");
break;
case MA_OPT_LOADCFG:
ret = emu_read_config(rom_fname_loaded, 1);
if (!ret) ret = emu_read_config(NULL, 1);
- if (ret) me_update_msg("config loaded");
- else me_update_msg("failed to load config");
+ if (ret) menu_update_msg("config loaded");
+ else menu_update_msg("failed to load config");
break;
default:
return 0;
static int mh_restore_defaults(int id, int keys)
{
emu_set_defconfig();
- me_update_msg("defaults restored");
+ menu_update_msg("defaults restored");
return 1;
}
i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);
e_menu_options[i].enabled = e_menu_options[i].name[0] ? 1 : 0;
- me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, rom_loaded);
+ me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, PicoGameLoaded);
me_enable(e_menu_options, MA_OPT_LOADCFG, config_slot != config_slot_current);
- me_loop(e_menu_options, &sel, NULL);
+ me_loop(e_menu_options, &sel);
return 0;
}
while (1)
{
PDebugZ80Frame();
- if (in_menu_wait_any(0) & PBTN_MA3)
+ if (in_menu_wait_any(NULL, 0) & PBTN_MA3)
break;
- pemu_sound_wait();
+ emu_sound_wait();
}
- pemu_sound_stop();
+ emu_sound_stop();
}
static void draw_text_debug(const char *str, int skip, int from)
if (PicoDrawMask & PDRAW_32X_ON) memcpy(layer_str + 26, "32x", 4);
pemu_forced_frame(1, 0);
- memcpy(g_menuscreen_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2);
+ make_bg(1);
+
smalltext_out16(4, 1, "build: r" REVISION " "__DATE__ " " __TIME__ " " COMPILER, 0xffff);
smalltext_out16(4, g_menuscreen_h - me_sfont_h, layer_str, 0xffff);
}
while (1)
{
- menu_draw_begin(1);
+ menu_draw_begin(1, 0);
switch (mode)
{
case 0: tmp = PDebugMain();
case 1: draw_frame_debug();
break;
case 2: pemu_forced_frame(1, 0);
- menu_darken_bg(g_menuscreen_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h, 0);
+ make_bg(1);
PDebugShowSpriteStats((unsigned short *)g_menuscreen_ptr + (g_menuscreen_h/2 - 240/2)*g_menuscreen_w +
g_menuscreen_w/2 - 320/2, g_menuscreen_w);
break;
menu_draw_end();
inp = in_menu_wait(PBTN_MOK|PBTN_MBACK|PBTN_MA2|PBTN_MA3|PBTN_L|PBTN_R |
- PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT, 70);
+ PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT, NULL, 70);
if (inp & PBTN_MBACK) return;
if (inp & PBTN_L) { mode--; if (mode < 0) mode = 4; }
if (inp & PBTN_R) { mode++; if (mode > 4) mode = 0; }
PDebugCPUStep();
if (inp & PBTN_MA3) {
while (inp & PBTN_MA3)
- inp = in_menu_wait_any(-1);
+ inp = in_menu_wait_any(NULL, -1);
mplayer_loop();
}
if ((inp & (PBTN_MA2|PBTN_LEFT)) == (PBTN_MA2|PBTN_LEFT)) {
mkdir("dumps", 0777);
PDebugDumpMem();
- while (inp & PBTN_MA2) inp = in_menu_wait_any(-1);
+ while (inp & PBTN_MA2) inp = in_menu_wait_any(NULL, -1);
dumped = 1;
}
break;
PicoSkipFrame = 1;
PicoFrame();
PicoSkipFrame = 0;
- while (inp & PBTN_MOK) inp = in_menu_wait_any(-1);
+ while (inp & PBTN_MOK) inp = in_menu_wait_any(NULL, -1);
}
break;
case 3:
// ------------ main menu ------------
-static char *romsel_run(void)
-{
- char *ret, *sel_name;
-
- sel_name = malloc(sizeof(rom_fname_loaded));
- if (sel_name == NULL)
- return NULL;
- strcpy(sel_name, rom_fname_loaded);
-
- ret = menu_loop_romsel(sel_name, sizeof(rom_fname_loaded));
- free(sel_name);
- return ret;
-}
+static const char credits[] =
+ "PicoDrive v" VERSION " (c) notaz, 2006-2011\n\n\n"
+ "Credits:\n"
+ "fDave: Cyclone 68000 core,\n"
+ " base code of PicoDrive\n"
+ "Reesy & FluBBa: DrZ80 core\n"
+ "MAME devs: YM2612 and SN76496 cores\n"
+ "Inder, ketchupgun: graphics\n"
+#ifdef __GP2X__
+ "rlyeh and others: minimal SDK\n"
+ "Squidge: mmuhack\n"
+ "Dzz: ARM940 sample\n"
+#endif
+ "\n"
+ "special thanks (for docs, ideas):\n"
+ " Charles MacDonald, Haze,\n"
+ " Stephane Dallongeville,\n"
+ " Lordus, Exophase, Rokas,\n"
+ " Nemesis, Tasco Deluxe";
static int main_menu_handler(int id, int keys)
{
- char *ret_name;
+ const char *ret_name;
switch (id)
{
case MA_MAIN_RESUME_GAME:
- if (rom_loaded)
+ if (PicoGameLoaded)
return 1;
break;
case MA_MAIN_SAVE_STATE:
- if (rom_loaded)
+ if (PicoGameLoaded)
return menu_loop_savestate(0);
break;
case MA_MAIN_LOAD_STATE:
- if (rom_loaded)
+ if (PicoGameLoaded)
return menu_loop_savestate(1);
break;
case MA_MAIN_RESET_GAME:
- if (rom_loaded) {
+ if (PicoGameLoaded) {
emu_reset_game();
return 1;
}
break;
case MA_MAIN_LOAD_ROM:
- ret_name = romsel_run();
+ rom_fname_reload = NULL;
+ ret_name = menu_loop_romsel(rom_fname_loaded,
+ sizeof(rom_fname_loaded), rom_exts, NULL);
if (ret_name != NULL) {
lprintf("selected file: %s\n", ret_name);
+ rom_fname_reload = ret_name;
engineState = PGS_ReloadRom;
return 1;
}
break;
case MA_MAIN_CREDITS:
- draw_menu_credits();
- in_menu_wait(PBTN_MOK|PBTN_MBACK, 70);
+ draw_menu_message(credits, NULL);
+ in_menu_wait(PBTN_MOK|PBTN_MBACK, NULL, 70);
break;
case MA_MAIN_EXIT:
engineState = PGS_Quit;
return 1;
case MA_MAIN_PATCHES:
- if (rom_loaded && PicoPatches) {
+ if (PicoGameLoaded && PicoPatches) {
menu_loop_patches();
PicoPatchApply();
- me_update_msg("Patches applied");
+ menu_update_msg("Patches applied");
}
break;
default:
{
static int sel = 0;
- me_enable(e_menu_main, MA_MAIN_RESUME_GAME, rom_loaded);
- me_enable(e_menu_main, MA_MAIN_SAVE_STATE, rom_loaded);
- me_enable(e_menu_main, MA_MAIN_LOAD_STATE, rom_loaded);
- me_enable(e_menu_main, MA_MAIN_RESET_GAME, rom_loaded);
+ me_enable(e_menu_main, MA_MAIN_RESUME_GAME, PicoGameLoaded);
+ me_enable(e_menu_main, MA_MAIN_SAVE_STATE, PicoGameLoaded);
+ me_enable(e_menu_main, MA_MAIN_LOAD_STATE, PicoGameLoaded);
+ me_enable(e_menu_main, MA_MAIN_RESET_GAME, PicoGameLoaded);
me_enable(e_menu_main, MA_MAIN_PATCHES, PicoPatches != NULL);
- menu_enter(rom_loaded);
+ menu_enter(PicoGameLoaded);
in_set_config_int(0, IN_CFG_BLOCKING, 1);
- me_loop(e_menu_main, &sel, menu_main_plat_draw);
+ me_loop_d(e_menu_main, &sel, NULL, menu_main_plat_draw);
- if (rom_loaded) {
+ if (PicoGameLoaded) {
if (engineState == PGS_Menu)
engineState = PGS_Running;
/* wait until menu, ok, back is released */
- while (in_menu_wait_any(50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
+ while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
;
}
in_set_config_int(0, IN_CFG_BLOCKING, 0);
+ plat_video_menu_leave();
}
// --------- CD tray close menu ----------
static int mh_tray_load_cd(int id, int keys)
{
- char *ret_name;
+ const char *ret_name;
- ret_name = romsel_run();
+ rom_fname_reload = NULL;
+ ret_name = menu_loop_romsel(rom_fname_loaded,
+ sizeof(rom_fname_loaded), rom_exts, NULL);
if (ret_name == NULL)
return 0;
+ rom_fname_reload = ret_name;
engineState = PGS_RestartRun;
return emu_swap_cd(ret_name);
}
{
int ret = 1, sel = 0;
- menu_enter(rom_loaded);
+ menu_enter(PicoGameLoaded);
in_set_config_int(0, IN_CFG_BLOCKING, 1);
- me_loop(e_menu_tray, &sel, NULL);
+ me_loop(e_menu_tray, &sel);
if (engineState != PGS_RestartRun) {
engineState = PGS_RestartRun;
ret = 0; /* no CD inserted */
}
- while (in_menu_wait_any(50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK));
+ while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
+ ;
in_set_config_int(0, IN_CFG_BLOCKING, 0);
+ plat_video_menu_leave();
return ret;
}
-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;
return me_list_i;
}
+void menu_init(void)
+{
+ int i;
+
+ menu_init_base();
+
+ 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_OPT3_FILTERING);
+ e_menu_gfx_options[i].data = plat_target.hwfilters;
+ me_enable(e_menu_gfx_options, MA_OPT3_FILTERING,
+ plat_target.hwfilters != NULL);
+
+ me_enable(e_menu_gfx_options, MA_OPT3_GAMMA,
+ plat_target.gamma_set != NULL);
+}