#include <pspaudio.h>
#include "psp.h"
-#include "menu.h"
#include "emu.h"
#include "mp3.h"
+#include "in_psp.h"
#include "asm_utils.h"
#include "../common/emu.h"
-#include "../common/config.h"
+#include "../common/input_pico.h"
+#include "platform/libpicofe/input.h"
+#include "platform/libpicofe/menu.h"
+
#include <pico/pico_int.h>
+#include <pico/cd/genplus_macros.h>
+#include <pico/cd/cdd.h>
#include <pico/cd/cue.h>
#define OSD_FPS_X 432
-// additional pspaudio imports, credits to crazyc
-int sceAudio_38553111(unsigned short samples, unsigned short freq, char unknown); // play with conversion?
-int sceAudio_5C37C0AE(void); // end play?
-int sceAudio_E0727056(int volume, void *buffer); // blocking output
-int sceAudioOutput2GetRestSample();
-
-
-//unsigned char *Draw2FB = (unsigned char *)VRAM_CACHED_STUFF + 8; // +8 to be able to skip border with 1 quadword..
int engineStateSuspend;
#define PICO_PEN_ADJUST_X 4
#define PICO_PEN_ADJUST_Y 2
-static int pico_pen_x = 320/2, pico_pen_y = 240/2;
-static void sound_init(void);
-static void sound_deinit(void);
-static void blit2(const char *fps, const char *notice, int lagging_behind);
-static void clearArea(int full);
+struct Vertex
+{
+ short u,v;
+ short x,y,z;
+};
+
+static struct Vertex __attribute__((aligned(4))) g_vertices[2];
+static unsigned short __attribute__((aligned(16))) localPal[0x100];
+static int need_pal_upload = 0;
+static int fbimg_offs = 0;
+static int h32_mode = 0;
+
+static const struct in_default_bind in_psp_defbinds[] =
+{
+ { PSP_CTRL_UP, IN_BINDTYPE_PLAYER12, GBTN_UP },
+ { PSP_CTRL_DOWN, IN_BINDTYPE_PLAYER12, GBTN_DOWN },
+ { PSP_CTRL_LEFT, IN_BINDTYPE_PLAYER12, GBTN_LEFT },
+ { PSP_CTRL_RIGHT, IN_BINDTYPE_PLAYER12, GBTN_RIGHT },
+ { PSP_CTRL_SQUARE, IN_BINDTYPE_PLAYER12, GBTN_A },
+ { PSP_CTRL_CROSS, IN_BINDTYPE_PLAYER12, GBTN_B },
+ { PSP_CTRL_CIRCLE, IN_BINDTYPE_PLAYER12, GBTN_C },
+ { PSP_CTRL_START, IN_BINDTYPE_PLAYER12, GBTN_START },
+ { PSP_CTRL_TRIANGLE, IN_BINDTYPE_EMU, PEVB_SWITCH_RND },
+ { PSP_CTRL_LTRIGGER, IN_BINDTYPE_EMU, PEVB_STATE_SAVE },
+ { PSP_CTRL_RTRIGGER, IN_BINDTYPE_EMU, PEVB_STATE_LOAD },
+ { PSP_CTRL_SELECT, IN_BINDTYPE_EMU, PEVB_MENU },
+ { 0, 0, 0 }
+};
+
-int plat_get_root_dir(char *dst, int len)
+const char *renderer_names[] = { "16bit accurate", " 8bit accurate", " 8bit fast", NULL };
+const char *renderer_names32x[] = { "accurate", "faster", "fastest", NULL };
+enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT };
+
+#define is_16bit_mode() \
+ (get_renderer() == RT_16BIT || (PicoIn.AHW & PAHW_32X))
+
+static int get_renderer(void)
{
- if (len > 0) *dst = 0;
- return 0;
+ if (PicoIn.AHW & PAHW_32X)
+ return currentConfig.renderer32x;
+ else
+ return currentConfig.renderer;
+}
+
+static void change_renderer(int diff)
+{
+ int *r;
+ if (PicoIn.AHW & PAHW_32X)
+ r = ¤tConfig.renderer32x;
+ else
+ r = ¤tConfig.renderer;
+ *r += diff;
+
+ if (*r >= RT_COUNT)
+ *r = 0;
+ else if (*r < 0)
+ *r = RT_COUNT - 1;
+}
+
+static void apply_renderer(void)
+{
+ PicoIn.opt &= ~POPT_ALT_RENDERER;
+ PicoIn.opt |= POPT_DIS_32C_BORDER;
+
+ switch (currentConfig.renderer) {
+ case RT_16BIT:
+ PicoDrawSetOutFormat(PDF_RGB555, 0);
+ break;
+ case RT_8BIT_ACC:
+ PicoDrawSetOutFormat(PDF_8BIT, 0);
+ break;
+ case RT_8BIT_FAST:
+ PicoIn.opt |= POPT_ALT_RENDERER;
+ PicoDrawSetOutFormat(PDF_NONE, 0);
+ break;
+ }
}
static void osd_text(int x, const char *text, int is_active, int clear_all)
unsigned short *screen = is_active ? psp_video_get_active_fb() : psp_screen;
int len = clear_all ? (480 / 2) : (strlen(text) * 8 / 2);
int *p, h;
- void *tmp;
+ void *tmp = g_screen_ptr;
for (h = 0; h < 8; h++) {
p = (int *) (screen+x+512*(264+h));
p = (int *) ((int)p & ~3); // align
memset32_uncached(p, 0, len);
}
- if (is_active) { tmp = psp_screen; psp_screen = screen; } // nasty pointer tricks
+ g_screen_ptr = screen; // nasty pointer tricks
emu_text_out16(x, 264, text);
- if (is_active) psp_screen = tmp;
-}
-
-void emu_msg_cb(const char *msg)
-{
- osd_text(4, msg, 1, 1);
- noticeMsgTime = sceKernelGetSystemTimeLow() - 2000000;
-
- /* assumption: emu_msg_cb gets called only when something slow is about to happen */
- reset_timing = 1;
-}
-
-/* FIXME: move to plat */
-void emu_Init(void)
-{
- sound_init();
-}
-
-void emu_Deinit(void)
-{
- sound_deinit();
-}
-
-void pemu_prep_defconfig(void)
-{
- defaultConfig.s_PsndRate = 22050;
- defaultConfig.s_PicoCDBuffers = 64;
- defaultConfig.CPUclock = 333;
- defaultConfig.KeyBinds[ 4] = 1<<0; // SACB RLDU
- defaultConfig.KeyBinds[ 6] = 1<<1;
- defaultConfig.KeyBinds[ 7] = 1<<2;
- defaultConfig.KeyBinds[ 5] = 1<<3;
- defaultConfig.KeyBinds[14] = 1<<4;
- defaultConfig.KeyBinds[13] = 1<<5;
- defaultConfig.KeyBinds[15] = 1<<6;
- defaultConfig.KeyBinds[ 3] = 1<<7;
- defaultConfig.KeyBinds[12] = 1<<26; // switch rnd
- defaultConfig.KeyBinds[ 8] = 1<<27; // save state
- defaultConfig.KeyBinds[ 9] = 1<<28; // load state
- defaultConfig.KeyBinds[28] = 1<<0; // num "buttons"
- defaultConfig.KeyBinds[30] = 1<<1;
- defaultConfig.KeyBinds[31] = 1<<2;
- defaultConfig.KeyBinds[29] = 1<<3;
- defaultConfig.scaling = 1; // bilinear filtering for psp
- defaultConfig.scale = 1.20; // fullscreen
- defaultConfig.hscale40 = 1.25;
- defaultConfig.hscale32 = 1.56;
+ g_screen_ptr = tmp;
}
-extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count);
-extern void amips_clut_6bit(unsigned short *dst, unsigned char *src, unsigned short *pal, int count);
-
-static void (*amips_clut_f)(unsigned short *dst, unsigned char *src, unsigned short *pal, int count) = NULL;
-
-struct Vertex
-{
- short u,v;
- short x,y,z;
-};
-
-static struct Vertex __attribute__((aligned(4))) g_vertices[2];
-static unsigned short __attribute__((aligned(16))) localPal[0x100];
-static int dynamic_palette = 0, need_pal_upload = 0, blit_16bit_mode = 0;
-static int fbimg_offs = 0;
-
static void set_scaling_params(void)
{
int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs, border_hack = 0;
g_vertices[0].z = g_vertices[1].z = 0;
fbimg_height = (int)(240.0 * currentConfig.scale + 0.5);
- if (Pico.video.reg[12] & 1) {
+ if (!h32_mode) {
fbimg_width = (int)(320.0 * currentConfig.scale * currentConfig.hscale40 + 0.5);
src_width = 320;
} else {
g_vertices[1].u--;
g_vertices[1].x--;
}
+ if (!is_16bit_mode()) {
+ // 8-bit modes have an 8 px overlap area on the left
+ g_vertices[0].u += 8;
+ g_vertices[1].u += 8;
+ }
fbimg_offs = (fbimg_yoffs*512 + fbimg_xoffs) * 2; // dst is always 16bit
/*
*/
}
-static void do_pal_update(int allow_sh, int allow_as)
+static void do_pal_update(void)
{
unsigned int *dpal=(void *)localPal;
int i;
//for (i = 0x3f/2; i >= 0; i--)
// dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4);
- if ((currentConfig.EmuOpt&0x80) || (PicoOpt&0x10)) {
- do_pal_convert(localPal, Pico.cram, currentConfig.gamma, currentConfig.gamma2);
+ if (PicoIn.opt & POPT_ALT_RENDERER) {
+ do_pal_convert(localPal, PicoMem.cram, currentConfig.gamma, currentConfig.gamma2);
Pico.m.dirtyPal = 0;
}
- else if (Pico.est.rendstatus&0x20)
+ else if (Pico.est.rendstatus & PDRAW_SONIC_MODE)
{
switch (Pico.est.SonicPalCount) {
- case 3: do_pal_convert(localPal+0xc0, Pico.est.SonicPal+0xc0, currentConfig.gamma, currentConfig.gamma2);
- case 2: do_pal_convert(localPal+0x80, Pico.est.SonicPal+0x80, currentConfig.gamma, currentConfig.gamma2);
- case 1: do_pal_convert(localPal+0x40, Pico.est.SonicPal+0x40, currentConfig.gamma, currentConfig.gamma2);
+ case 3: do_pal_convert(localPal+0xc0/2, Pico.est.SonicPal+0xc0, currentConfig.gamma, currentConfig.gamma2);
+ case 2: do_pal_convert(localPal+0x80/2, Pico.est.SonicPal+0x80, currentConfig.gamma, currentConfig.gamma2);
+ case 1: do_pal_convert(localPal+0x40/2, Pico.est.SonicPal+0x40, currentConfig.gamma, currentConfig.gamma2);
default:do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
}
}
- else if (allow_sh && (Pico.video.reg[0xC]&8)) // shadow/hilight?
+ else if (Pico.video.reg[0xC]&8) // shadow/hilight?
{
do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
// shadowed pixels
- for (i = 0x3f/2; i >= 0; i--)
- dpal[0x20|i] = dpal[0x60|i] = (dpal[i]>>1)&0x7bcf7bcf;
+ for (i = 0; i < 0x40 / 2; i++) {
+ dpal[0xc0/2 + i] = dpal[i];
+ dpal[0x80/2 + i] = (dpal[i] >> 1) & 0x738e738e;
+ }
// hilighted pixels
- for (i = 0x3f; i >= 0; i--) {
- int t=localPal[i]&0xf79e;t+=0x4208;
- if (t&0x20) t|=0x1e;
- if (t&0x800) t|=0x780;
- if (t&0x10000) t|=0xf000;
- t&=0xf79e;
- localPal[0x80|i]=(unsigned short)t;
+ for (i = 0; i < 0x40 / 2; i++) {
+ u32 t = ((dpal[i] >> 1) & 0x738e738e) + 0x738e738e;
+ t |= (t >> 4) & 0x08610861;
+ dpal[0x40/2 + i] = t;
}
- localPal[0xe0] = 0;
- localPal[0xf0] = 0x001f;
}
- else if (allow_as && (Pico.est.rendstatus & PDRAW_SPR_LO_ON_HI))
+ else
{
do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
memcpy((int *)dpal+0x40/2, (void *)localPal, 0x40*2);
memcpy((int *)dpal+0x80/2, (void *)localPal, 0x80*2);
}
+ localPal[0xe0] = 0;
+ localPal[0xf0] = 0x001f;
if (Pico.m.dirtyPal == 2)
Pico.m.dirtyPal = 0;
need_pal_upload = 1;
}
-static void do_slowmode_lines(int line_to)
-{
- int line = 0, line_len = (Pico.video.reg[12]&1) ? 320 : 256;
- unsigned short *dst = (unsigned short *)VRAM_STUFF + 512*240/2;
- unsigned char *src = (unsigned char *)VRAM_CACHED_STUFF + 16;
- if (!(Pico.video.reg[1]&8)) { line = 8; dst += 512*8; src += 512*8; }
-
- for (; line < line_to; line++, dst+=512, src+=512)
- amips_clut_f(dst, src, localPal, line_len);
-}
-
-static void EmuScanPrepare(void)
-{
- Pico.est.HighCol = (unsigned char *)VRAM_CACHED_STUFF + 8;
- if (!(Pico.video.reg[1]&8)) Pico.est.HighCol += 8*512;
-
- if (dynamic_palette > 0)
- dynamic_palette--;
-
- if (Pico.m.dirtyPal)
- do_pal_update(1, 1);
- if (!(Pico.video.reg[0xC] & 8))
- amips_clut_f = amips_clut_6bit;
- else amips_clut_f = amips_clut;
-}
-
-static int EmuScanSlowBegin(unsigned int num)
-{
- if (!dynamic_palette)
- Pico.est.HighCol = (unsigned char *)VRAM_CACHED_STUFF + num * 512 + 8;
-
- return 0;
-}
-
-static int EmuScanSlowEnd(unsigned int num)
-{
- if (Pico.m.dirtyPal) {
- if (!dynamic_palette) {
- do_slowmode_lines(num);
- dynamic_palette = 3; // last for 2 more frames
- }
- do_pal_update(1, 1);
- }
-
- if (dynamic_palette) {
- int line_len = (Pico.video.reg[12]&1) ? 320 : 256;
- void *dst = (char *)VRAM_STUFF + 512*240 + 512*2*num;
- amips_clut_f(dst, Pico.est.HighCol + 8, localPal, line_len);
- }
-
- return 0;
-}
-
static void blitscreen_clut(void)
{
int offs = fbimg_offs;
sceGuSync(0,0); // sync with prev
sceGuStart(GU_DIRECT, guCmdList);
sceGuDrawBuffer(GU_PSM_5650, (void *)offs, 512); // point to back buffer
+ sceGuTexMode(is_16bit_mode() ? GU_PSM_5650:GU_PSM_T8,0,0,0);
+ sceGuTexImage(0,512,512,512,g_screen_ptr);
- if (dynamic_palette)
- {
- if (!blit_16bit_mode) { // the current mode is not 16bit
- sceGuTexMode(GU_PSM_5650, 0, 0, 0);
- sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 512*240);
-
- blit_16bit_mode = 1;
- }
- }
- else
- {
- if (blit_16bit_mode) {
- sceGuClutMode(GU_PSM_5650,0,0xff,0);
- sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image
- sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16);
- blit_16bit_mode = 0;
- }
-
- if ((PicoIn.opt&0x10) && Pico.m.dirtyPal)
- do_pal_update(0, 0);
+ if (Pico.m.dirtyPal)
+ do_pal_update();
- sceKernelDcacheWritebackAll();
+ sceKernelDcacheWritebackAll();
- if (need_pal_upload) {
- need_pal_upload = 0;
- sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256)
- }
+ if (need_pal_upload) {
+ need_pal_upload = 0;
+ sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256)
}
#if 1
static void draw_pico_ptr(void)
{
- unsigned char *p = (unsigned char *)VRAM_STUFF + 16;
+ unsigned char *p = (unsigned char *)VRAM_CACHED_STUFF + 8;
// only if pen enabled and for 8bit mode
- if (pico_inp_mode == 0 || blit_16bit_mode) return;
+ if (pico_inp_mode == 0 || is_16bit_mode()) return;
p += 512 * (pico_pen_y + PICO_PEN_ADJUST_Y);
p += pico_pen_x + PICO_PEN_ADJUST_X;
}
-#if 0
-static void dbg_text(void)
-{
- int *p, h, len;
- char text[128];
-
- sprintf(text, "sl: %i, 16b: %i", g_vertices[0].u == 0 && g_vertices[1].u == g_vertices[1].x, blit_16bit_mode);
- len = strlen(text) * 8 / 2;
- for (h = 0; h < 8; h++) {
- p = (int *) ((unsigned short *) psp_screen+2+512*(256+h));
- p = (int *) ((int)p & ~3); // align
- memset32_uncached(p, 0, len);
- }
- emu_text_out16(2, 256, text);
-}
-#endif
-
-/* called after rendering is done, but frame emulation is not finished */
-void blit1(void)
-{
- if (PicoIn.opt&0x10)
- {
- int i;
- unsigned char *pd;
- // clear top and bottom trash
- for (pd = Pico.est.Draw2FB+8, i = 8; i > 0; i--, pd += 512)
- memset32((int *)pd, 0xe0e0e0e0, 320/4);
- for (pd = Pico.est.Draw2FB+512*232+8, i = 8; i > 0; i--, pd += 512)
- memset32((int *)pd, 0xe0e0e0e0, 320/4);
- }
-
- if (PicoIn.AHW & PAHW_PICO)
- draw_pico_ptr();
-
- blitscreen_clut();
-}
-
-
-static void blit2(const char *fps, const char *notice, int lagging_behind)
-{
- int vsync = 0, emu_opt = currentConfig.EmuOpt;
-
- if (notice || (emu_opt & 2)) {
- if (notice) osd_text(4, notice, 0, 0);
- if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0, 0);
- }
-
- //dbg_text();
-
- if ((emu_opt & 0x400) && (PicoIn.AHW & PAHW_MCD))
- cd_leds();
-
- if (currentConfig.EmuOpt & 0x2000) { // want vsync
- if (!(currentConfig.EmuOpt & 0x10000) || !lagging_behind) vsync = 1;
- }
-
- psp_video_flip(vsync);
-}
-
// clears whole screen or just the notice area (in all buffers)
static void clearArea(int full)
{
+ void *fb = psp_video_get_active_fb();
+
if (full) {
memset32_uncached(psp_screen, 0, 512*272*2/4);
- psp_video_flip(0);
- memset32_uncached(psp_screen, 0, 512*272*2/4);
+ memset32_uncached(fb, 0, 512*272*2/4);
memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*240/4);
memset32((int *)VRAM_CACHED_STUFF+512*240/4, 0, 512*240*2/4);
} else {
- void *fb = psp_video_get_active_fb();
memset32_uncached((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4);
memset32_uncached((int *)((char *)fb + 512*264*2), 0, 512*8*2/4);
}
sceGuStart(GU_DIRECT, guCmdList);
sceGuClutMode(GU_PSM_5650,0,0xff,0);
- sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image
sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB);
if (currentConfig.scaling)
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
sceGuTexScale(1.0f,1.0f);
sceGuTexOffset(0.0f,0.0f);
- sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16);
-
- // slow rend.
- PicoDrawSetOutFormat(PDF_NONE, 0);
- PicoDrawSetCallbacks(EmuScanSlowBegin, EmuScanSlowEnd);
-
- localPal[0xe0] = 0;
- localPal[0xf0] = 0x001f;
Pico.m.dirtyPal = 1;
- blit_16bit_mode = dynamic_palette = 0;
sceGuFinish();
set_scaling_params();
sceGuSync(0,0);
}
-void plat_debug_cat(char *str)
-{
- strcat(str, blit_16bit_mode ? "soft clut\n" : "hard clut\n");
-}
-
-
/* sound stuff */
#define SOUND_BLOCK_SIZE_NTSC (1470*2) // 1024 // 1152
#define SOUND_BLOCK_SIZE_PAL (1764*2)
// lprintf("sthr: got data: %i\n", samples_made - samples_done);
- ret = sceAudio_E0727056(PSP_AUDIO_VOLUME_MAX, snd_playptr);
+ ret = sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, snd_playptr);
samples_done += samples_block;
snd_playptr += samples_block;
snd_playptr = sndBuffer;
// 1.5 kernel returns 0, newer ones return # of samples queued
if (ret < 0)
- lprintf("sthr: sceAudio_E0727056: %08x; pos %i/%i\n", ret, samples_done, samples_made);
+ lprintf("sthr: sceAudioSRCOutputBlocking: %08x; pos %i/%i\n", ret, samples_done, samples_made);
// shouln't happen, but just in case
if (samples_made - samples_done >= samples_block*3) {
void pemu_sound_start(void)
{
static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0;
+ static int mp3_init_done;
int ret, stereo;
samples_made = samples_done = 0;
+ if (PicoIn.AHW & PAHW_MCD) {
+ // mp3...
+ if (!mp3_init_done) {
+ ret = mp3_init();
+ mp3_init_done = 1;
+ if (ret) emu_status_msg("mp3 init failed (%i)", ret);
+ }
+ }
+
if (PicoIn.sndRate != PsndRate_old || (PicoIn.opt&0x0b) != (PicoOpt_old&0x0b) || Pico.m.pal != pal_old) {
PsndRerate(Pico.m.frame_count ? 1 : 0);
}
PicoIn.sndRate, Pico.snd.len, stereo, Pico.m.pal, samples_block);
// while (sceAudioOutput2GetRestSample() > 0) psp_msleep(100);
- // sceAudio_5C37C0AE();
- ret = sceAudio_38553111(samples_block/2, PicoIn.sndRate, 2); // seems to not need that stupid 64byte alignment
+ // sceAudioSRCChRelease();
+ ret = sceAudioSRCChReserve(samples_block/2, PicoIn.sndRate, 2); // seems to not need that stupid 64byte alignment
if (ret < 0) {
- lprintf("sceAudio_38553111() failed: %i\n", ret);
+ lprintf("sceAudioSRCChReserve() failed: %i\n", ret);
emu_status_msg("sound init failed (%i), snd disabled", ret);
currentConfig.EmuOpt &= ~EOPT_EN_SOUND;
} else {
int i;
if (samples_done == 0)
{
- // if no data is written between sceAudio_38553111 and sceAudio_5C37C0AE calls,
- // we get a deadlock on next sceAudio_38553111 call
+ // if no data is written between sceAudioSRCChReserve and sceAudioSRCChRelease calls,
+ // we get a deadlock on next sceAudioSRCChReserve call
// so this is yet another workaround:
memset32((int *)(void *)sndBuffer, 0, samples_block*4/4);
samples_made = samples_block * 3;
samples_made = samples_done = 0;
for (i = 0; sceAudioOutput2GetRestSample() > 0 && i < 16; i++)
psp_msleep(100);
- sceAudio_5C37C0AE();
+ sceAudioSRCChRelease();
}
/* wait until we can write more sound */
}
-static void SkipFrame(void)
+/* set default configuration values */
+void pemu_prep_defconfig(void)
{
- PicoIn.skipFrame=1;
- PicoFrame();
- PicoIn.skipFrame=0;
+ defaultConfig.s_PsndRate = 22050;
+ defaultConfig.s_PicoCDBuffers = 64;
+ defaultConfig.CPUclock = 333;
+ defaultConfig.scaling = 1; // bilinear filtering for psp
+ defaultConfig.scale = 1.20; // fullscreen
+ defaultConfig.hscale40 = 1.25;
+ defaultConfig.hscale32 = 1.56;
}
-void pemu_forced_frame(int no_scale, int do_emu)
+/* check configuration for inconsistencies */
+void pemu_validate_config(void)
{
- int po_old = PicoIn.opt;
- int eo_old = currentConfig.EmuOpt;
+ if (currentConfig.CPUclock < 33 || currentConfig.CPUclock > 333)
+ currentConfig.CPUclock = 333;
+}
- PicoIn.opt &= ~POPT_ALT_RENDERER;
- PicoIn.opt |= POPT_ACC_SPRITES;
- if (!no_scale && defaultConfig.scaling)
- PicoIn.opt |= POPT_EN_SOFTSCALE;
- currentConfig.EmuOpt |= 0x80;
+/* finalize rendering a frame */
+void pemu_finalize_frame(const char *fps, const char *notice)
+{
+ int emu_opt = currentConfig.EmuOpt;
- vidResetMode();
- memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders
- memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4);
- memset32_uncached((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
-
- PicoDrawSetOutFormat(PDF_NONE, 0);
- PicoDrawSetCallbacks(EmuScanSlowBegin, EmuScanSlowEnd);
- EmuScanPrepare();
- PicoFrameDrawOnly();
- blit1();
- sceGuSync(0,0);
+ if (PicoIn.AHW & PAHW_PICO)
+ draw_pico_ptr();
+
+ blitscreen_clut();
- PicoIn.opt = po_old;
- currentConfig.EmuOpt = eo_old;
+ // XXX move this to flip to give texture renderer more time?
+ if (notice) osd_text(4, notice, 0, 0);
+ if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0, 0);
+
+ if ((emu_opt & 0x400) && (PicoIn.AHW & PAHW_MCD))
+ cd_leds();
}
+/* FIXME: move plat_* to plat? */
-static void RunEventsPico(unsigned int events, unsigned int keys)
+void plat_debug_cat(char *str)
{
- emu_RunEventsPico(events);
-
- if (pico_inp_mode != 0)
- {
- PicoIn.pad[0] &= ~0x0f; // release UDLR
- if (keys & PBTN_UP) { pico_pen_y--; if (pico_pen_y < 8) pico_pen_y = 8; }
- if (keys & PBTN_DOWN) { pico_pen_y++; if (pico_pen_y > 224-PICO_PEN_ADJUST_Y) pico_pen_y = 224-PICO_PEN_ADJUST_Y; }
- if (keys & PBTN_LEFT) { pico_pen_x--; if (pico_pen_x < 0) pico_pen_x = 0; }
- if (keys & PBTN_RIGHT) {
- int lim = (Pico.video.reg[12]&1) ? 319 : 255;
- pico_pen_x++;
- if (pico_pen_x > lim-PICO_PEN_ADJUST_X)
- pico_pen_x = lim-PICO_PEN_ADJUST_X;
- }
- PicoPicohw.pen_pos[0] = pico_pen_x;
- if (!(Pico.video.reg[12]&1)) PicoPicohw.pen_pos[0] += pico_pen_x/4;
- PicoPicohw.pen_pos[0] += 0x3c;
- PicoPicohw.pen_pos[1] = pico_inp_mode == 1 ? (0x2f8 + pico_pen_y) : (0x1fc + pico_pen_y);
- }
}
-static void RunEvents(unsigned int which)
+/* platform dependend emulator initialization */
+void plat_init(void)
{
- if (which & 0x1800) // save or load (but not both)
- {
- int do_it = 1;
-
- if ( emu_check_save_file(state_slot) &&
- (( (which & 0x1000) && (currentConfig.EmuOpt & 0x800)) || // load
- (!(which & 0x1000) && (currentConfig.EmuOpt & 0x200))) ) // save
- {
- int keys;
- sceGuSync(0,0);
- blit2("", (which & 0x1000) ? "LOAD STATE? (X=yes, O=no)" : "OVERWRITE SAVE? (X=yes, O=no)", 0);
- while( !((keys = psp_pad_read(1)) & (PBTN_X|PBTN_CIRCLE)) )
- psp_msleep(50);
- if (keys & PBTN_CIRCLE) do_it = 0;
- while( ((keys = psp_pad_read(1)) & (PBTN_X|PBTN_CIRCLE)) ) // wait for release
- psp_msleep(50);
- clearArea(0);
- }
-
- if (do_it)
- {
- osd_text(4, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME", 1, 0);
- PicoStateProgressCB = emu_msg_cb;
- emu_save_load_game((which & 0x1000) >> 12, 0);
- PicoStateProgressCB = NULL;
- psp_msleep(0);
- }
-
- reset_timing = 1;
- }
- if (which & 0x0400) // switch renderer
- {
- if (PicoIn.opt&0x10) { PicoIn.opt&=~0x10; currentConfig.EmuOpt |= 0x80; }
- else { PicoIn.opt|= 0x10; currentConfig.EmuOpt &= ~0x80; }
-
- vidResetMode();
+ flip_after_sync = 1;
+ in_psp_init(in_psp_defbinds);
+ in_probe();
+ sound_init();
+}
- if (PicoIn.opt & POPT_ALT_RENDERER)
- emu_status_msg("fast renderer");
- else if (currentConfig.EmuOpt&0x80)
- emu_status_msg("accurate renderer");
- }
- if (which & 0x0300)
- {
- if(which&0x0200) {
- state_slot -= 1;
- if(state_slot < 0) state_slot = 9;
- } else {
- state_slot += 1;
- if(state_slot > 9) state_slot = 0;
- }
- emu_status_msg("SAVE SLOT %i [%s]", state_slot,
- emu_check_save_file(state_slot) ? "USED" : "FREE");
- }
+/* platform dependend emulator deinitialization */
+void plat_finish(void)
+{
+ sound_deinit();
}
-static void updateKeys(void)
+/* display emulator status messages before holding emulation */
+void plat_status_msg_busy_first(const char *msg)
{
- unsigned int keys, allActions[2] = { 0, 0 }, events;
- static unsigned int prevEvents = 0;
- int i;
+ plat_status_msg_busy_next(msg);
+}
- /* FIXME: port to input fw, merge with emu.c:emu_update_input() */
- keys = psp_pad_read(0);
- if (keys & PSP_CTRL_HOME)
- sceDisplayWaitVblankStart();
+void plat_status_msg_busy_next(const char *msg)
+{
+ plat_status_msg_clear();
+ pemu_finalize_frame("", msg);
+ plat_video_flip();
+ emu_status_msg("");
+ reset_timing = 1;
+}
- if (keys & PBTN_SELECT)
- engineState = PGS_Menu;
+/* clear status message area */
+void plat_status_msg_clear(void)
+{
+ clearArea(0);
+}
- keys &= CONFIGURABLE_KEYS;
+/* change the audio volume setting */
+void plat_update_volume(int has_changed, int is_up)
+{
+}
- PicoIn.pad[0] = allActions[0] & 0xfff;
- PicoIn.pad[1] = allActions[1] & 0xfff;
+/* prepare for MD screen mode change */
+void emu_video_mode_change(int start_line, int line_count, int is_32cols)
+{
+ h32_mode = is_32cols;
+ vidResetMode();
+ if (h32_mode) // clear borders from h40 remnants
+ clearArea(1);
+}
- if (allActions[0] & 0x7000) emu_DoTurbo(&PicoIn.pad[0], allActions[0]);
- if (allActions[1] & 0x7000) emu_DoTurbo(&PicoIn.pad[1], allActions[1]);
+/* render one frame in RGB */
+void pemu_forced_frame(int no_scale, int do_emu)
+{
+ PicoIn.opt &= ~POPT_DIS_32C_BORDER;
+ PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2);
+ Pico.m.dirtyPal = 1;
- events = (allActions[0] | allActions[1]) >> 16;
+ if (!no_scale)
+ no_scale = currentConfig.scaling == EOPT_SCALE_NONE;
+ emu_cmn_forced_frame(no_scale, do_emu);
+}
- if ((events ^ prevEvents) & 0x40) {
- emu_set_fastforward(events & 0x40);
- reset_timing = 1;
- }
+/* change the platform output rendering */
+void plat_video_toggle_renderer(int change, int is_menu_call)
+{
+ change_renderer(change);
- events &= ~prevEvents;
+ if (is_menu_call)
+ return;
- if (PicoIn.AHW == PAHW_PICO)
- RunEventsPico(events, keys);
- if (events) RunEvents(events);
- if (movie_data) emu_updateMovie();
+ apply_renderer();
+ vidResetMode();
+ rendstatus_old = -1;
- prevEvents = (allActions[0] | allActions[1]) >> 16;
+ if (PicoIn.AHW & PAHW_32X)
+ emu_status_msg(renderer_names32x[get_renderer()]);
+ else
+ emu_status_msg(renderer_names[get_renderer()]);
}
-
-static void simpleWait(unsigned int until)
+/* set the buffer for emulator output rendering */
+void plat_video_set_buffer(void *buf)
{
- unsigned int tval;
- int diff;
-
- tval = sceKernelGetSystemTimeLow();
- diff = (int)until - (int)tval;
- if (diff >= 512 && diff < 100*1024)
- sceKernelDelayThread(diff);
+ if (currentConfig.renderer == RT_16BIT || (PicoIn.AHW & PAHW_32X))
+ PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2);
+ else
+ PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch);
}
-void pemu_loop(void)
+/* prepare for emulator output rendering */
+void plat_video_loop_prepare(void)
{
- static int mp3_init_done = 0;
- char fpsbuff[24]; // fps count c string
- unsigned int tval, tval_thissec = 0; // timing
- int target_fps, target_frametime, lim_time, tval_diff, i, oldmodes = 0;
- int pframes_done, pframes_shown; // "period" frames, used for sync
- int frames_done, frames_shown, tval_fpsc = 0; // actual frames
- char *notice = NULL;
-
- lprintf("entered emu_Loop()\n");
-
- fpsbuff[0] = 0;
-
- if (currentConfig.CPUclock != psp_get_cpu_clock()) {
- lprintf("setting cpu clock to %iMHz... ", currentConfig.CPUclock);
- i = psp_set_cpu_clock(currentConfig.CPUclock);
- lprintf(i ? "failed\n" : "done\n");
- currentConfig.CPUclock = psp_get_cpu_clock();
- }
-
- // make sure we are in correct mode
+ apply_renderer();
vidResetMode();
clearArea(1);
- Pico.m.dirtyPal = 1;
- oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc;
-
- // pal/ntsc might have changed, reset related stuff
- target_fps = Pico.m.pal ? 50 : 60;
- target_frametime = Pico.m.pal ? (1000000<<8)/50 : (1000000<<8)/60+1;
- reset_timing = 1;
-
- if (PicoIn.AHW & PAHW_MCD) {
- // prepare CD buffer
- PicoCDBufferInit();
- // mp3...
- if (!mp3_init_done) {
- i = mp3_init();
- mp3_init_done = 1;
- if (i) { engineState = PGS_Menu; return; }
- }
- }
-
- // prepare sound stuff
- PicoIn.sndOut = NULL;
- if (currentConfig.EmuOpt & EOPT_EN_SOUND)
- {
- pemu_sound_start();
- }
-
- sceDisplayWaitVblankStart();
- pframes_shown = pframes_done =
- frames_shown = frames_done = 0;
-
- tval_fpsc = sceKernelGetSystemTimeLow();
-
- // loop?
- while (engineState == PGS_Running)
- {
- int modes;
-
- tval = sceKernelGetSystemTimeLow();
- if (reset_timing || tval < tval_fpsc) {
- //stdbg("timing reset");
- reset_timing = 0;
- tval_thissec = tval;
- pframes_shown = pframes_done = 0;
- }
-
- // show notice message?
- if (noticeMsgTime) {
- static int noticeMsgSum;
- if (tval - noticeMsgTime > 2000000) { // > 2.0 sec
- noticeMsgTime = 0;
- clearArea(0);
- notice = 0;
- } else {
- int sum = noticeMsg[0]+noticeMsg[1]+noticeMsg[2];
- if (sum != noticeMsgSum) { clearArea(0); noticeMsgSum = sum; }
- notice = noticeMsg;
- }
- }
-
- // check for mode changes
- modes = ((Pico.video.reg[12]&1)<<2)|(Pico.video.reg[1]&8);
- if (modes != oldmodes) {
- oldmodes = modes;
- clearArea(1);
- set_scaling_params();
- }
-
- // second passed?
- if (tval - tval_fpsc >= 1000000)
- {
- if (currentConfig.EmuOpt & 2)
- sprintf(fpsbuff, "%02i/%02i ", frames_shown, frames_done);
- frames_done = frames_shown = 0;
- tval_fpsc += 1000000;
- }
-
- if (tval - tval_thissec >= 1000000)
- {
- // missing 1 frame?
- if (currentConfig.Frameskip < 0 && pframes_done < target_fps) {
- SkipFrame(); pframes_done++; frames_done++;
- }
-
- tval_thissec += 1000000;
-
- if (currentConfig.Frameskip < 0) {
- pframes_done -= target_fps; if (pframes_done < 0) pframes_done = 0;
- pframes_shown -= target_fps; if (pframes_shown < 0) pframes_shown = 0;
- if (pframes_shown > pframes_done) pframes_shown = pframes_done;
- } else {
- pframes_done = pframes_shown = 0;
- }
- }
-#ifdef PFRAMES
- sprintf(fpsbuff, "%i", Pico.m.frame_count);
-#endif
-
- lim_time = (pframes_done+1) * target_frametime;
- if (currentConfig.Frameskip >= 0) // frameskip enabled
- {
- for (i = 0; i < currentConfig.Frameskip; i++) {
- updateKeys();
- SkipFrame(); pframes_done++; frames_done++;
- if (!(currentConfig.EmuOpt&0x40000)) { // do framelimitting if needed
- int tval_diff;
- tval = sceKernelGetSystemTimeLow();
- tval_diff = (int)(tval - tval_thissec) << 8;
- if (tval_diff < lim_time) // we are too fast
- simpleWait(tval + ((lim_time - tval_diff)>>8));
- }
- lim_time += target_frametime;
- }
- }
- else // auto frameskip
- {
- int tval_diff;
- tval = sceKernelGetSystemTimeLow();
- tval_diff = (int)(tval - tval_thissec) << 8;
- if (tval_diff > lim_time && (pframes_done/16 < pframes_shown))
- {
- // no time left for this frame - skip
- if (tval_diff - lim_time >= (300000<<8)) {
- reset_timing = 1;
- continue;
- }
- updateKeys();
- SkipFrame(); pframes_done++; frames_done++;
- continue;
- }
- }
-
- updateKeys();
-
- if (!(PicoIn.opt&0x10))
- EmuScanPrepare();
-
- PicoFrame();
-
- sceGuSync(0,0);
-
- // check time
- tval = sceKernelGetSystemTimeLow();
- tval_diff = (int)(tval - tval_thissec) << 8;
-
- blit2(fpsbuff, notice, tval_diff > lim_time);
-
- if (currentConfig.Frameskip < 0 && tval_diff - lim_time >= (300000<<8)) { // slowdown detection
- reset_timing = 1;
- }
- else if (!(currentConfig.EmuOpt&0x40000) || currentConfig.Frameskip < 0)
- {
- // sleep if we are still too fast
- if (tval_diff < lim_time)
- {
- // we are too fast
- simpleWait(tval + ((lim_time - tval_diff) >> 8));
- }
- }
-
- pframes_done++; pframes_shown++;
- frames_done++; frames_shown++;
- }
-
-
- emu_set_fastforward(0);
-
- if (PicoIn.AHW & PAHW_MCD) PicoCDBufferFree();
-
- if (PicoIn.sndOut != NULL) {
- pemu_sound_stop();
- PicoIn.sndOut = NULL;
- }
+}
- // save SRAM
- if ((currentConfig.EmuOpt & 1) && SRam.changed) {
- emu_msg_cb("Writing SRAM/BRAM..");
- emu_save_load_game(0, 1);
- SRam.changed = 0;
- }
+/* prepare for entering the emulator loop */
+void pemu_loop_prep(void)
+{
+}
- // clear fps counters and stuff
- memset32_uncached((int *)psp_video_get_active_fb() + 512*264*2/4, 0, 512*8*2/4);
+/* terminate the emulator loop */
+void pemu_loop_end(void)
+{
+ pemu_sound_stop();
}
-void emu_HandleResume(void)
+// TODO
+void emu_handle_resume(void)
{
if (!(PicoIn.AHW & PAHW_MCD)) return;
// reopen first CD track
- if (Pico_mcd->TOC.Tracks[0].F != NULL)
+ if (cdd.toc.tracks[0].fd != NULL)
{
char *fname = rom_fname_reload;
int len = strlen(rom_fname_reload);
}
lprintf("emu_HandleResume: reopen %s\n", fname);
- pm_close(Pico_mcd->TOC.Tracks[0].F);
- Pico_mcd->TOC.Tracks[0].F = pm_open(fname);
- lprintf("reopen %s\n", Pico_mcd->TOC.Tracks[0].F != NULL ? "ok" : "failed");
+ pm_close(cdd.toc.tracks[0].fd);
+ cdd.toc.tracks[0].fd = pm_open(fname);
+ lprintf("reopen %s\n", cdd.toc.tracks[0].fd != NULL ? "ok" : "failed");
if (cue_data != NULL) cue_destroy(cue_data);
}
mp3_reopen_file();
- if (!(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1))
- cdda_start_play();
+#if 0 // TODO
+ if (!(Pico_mcd->s68k_regs[0x36] & 1)/* && (Pico_mcd->scd.Status_CDC & 1)*/)
+ cdd_change_track(cdd.index, cdd.lba);
+#endif
}
-/*
- * PicoDrive
- * (C) notaz, 2006-2008
- *
- * This work is licensed under the terms of MAME license.
- * See COPYING file in the top-level directory.
- */
-// don't like to use loads of #ifdefs, so duplicating GP2X code
-// horribly instead
+// TODO scaling configuration non-functional ATM
-#include <string.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <unistd.h>
-#include <sys/syslimits.h> // PATH_MAX
+static const char *men_scaler[] = { "unscaled", "4:3", "fullscreen", NULL };
+#if 0
+static const char h_cscaler40[] = "Configures the custom scaler for wide resolution";
+static const char h_cscaler32[] = "Configures the custom scaler for narrow resolution";
-#include <pspdisplay.h>
-#include <pspgu.h>
-#include <pspiofilemgr.h>
-#include <psputils.h>
-
-#include "psp.h"
-#include "emu.h"
-#include "menu.h"
-#include "mp3.h"
-#include "../common/menu.h"
-#include "../common/emu.h"
-#include "../common/readpng.h"
-#include "../common/input.h"
-#include "../common/version.h"
-
-#include <pico/pico_int.h>
-#include <pico/patch.h>
-#include <zlib.h>
-
-
-#define pspKeyUnkn "???"
-const char * const keyNames[] = {
- "SELECT", pspKeyUnkn, pspKeyUnkn, "START", "UP", "RIGHT", "DOWN", "LEFT",
- "L", "R", pspKeyUnkn, pspKeyUnkn, "TRIANGLE", "CIRCLE", "X", "SQUARE",
- "HOME", "HOLD", "WLAN_UP", "REMOTE", "VOLUP", "VOLDOWN", "SCREEN", "NOTE",
- pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, "NUB UP", "NUB RIGHT", "NUB DOWN", "NUB LEFT" // fake
-};
-
-static unsigned short bg_buffer[480*272] __attribute__((aligned(16)));
-#define menu_screen psp_screen
-
-void menu_darken_bg(void *dst, const void *src, int pixels, int darker);
-static void menu_prepare_bg(int use_game_bg, int use_fg);
-
-
-void menu_draw_begin(void)
-{
- // short *src = (short *)bg_buffer, *dst = (short *)menu_screen;
- // int i;
-
- // for (i = 272; i >= 0; i--, dst += 512, src += 480)
- // memcpy((int *)dst, (int *)src, 480*2);
-
- sceGuSync(0,0); // sync with prev
- sceGuStart(GU_DIRECT, guCmdList);
- sceGuCopyImage(GU_PSM_5650, 0, 0, 480, 272, 480, bg_buffer, 0, 0, 512, menu_screen);
- sceGuFinish();
- sceGuSync(0,0);
-}
-
-
-void menu_draw_end(void)
-{
- psp_video_flip(1);
-}
-
-
-// --------- loading ROM screen ----------
-
-static int lcdr_line = 0;
-
-static void load_progress_cb(int percent)
-{
- int ln, len = percent * 480 / 100;
- unsigned short *dst;
-
- //sceDisplayWaitVblankStart();
-
- dst = (unsigned short *)menu_screen + 512*10*lcdr_line;
-
- if (len > 480) len = 480;
- for (ln = 8; ln > 0; ln--, dst += 512)
- memset(dst, 0xff, len*2);
-}
-
-static void cdload_progress_cb(int percent)
-{
- int ln, len = percent * 480 / 100;
- unsigned short *dst;
-
- if (lcdr_line <= 2) {
- lcdr_line++;
- smalltext_out16(1, lcdr_line++ * 10, "Processing CD image / MP3s", 0xffff);
- smalltext_out16_lim(1, lcdr_line++ * 10, romFileName, 0xffff, 80);
- }
-
- dst = (unsigned short *)menu_screen + 512*10*lcdr_line;
-
- if (len > 480) len = 480;
- for (ln = 8; ln > 0; ln--, dst += 512)
- memset(dst, 0xff, len*2);
-}
-
-void menu_romload_prepare(const char *rom_name)
-{
- const char *p = rom_name + strlen(rom_name);
- while (p > rom_name && *p != '/') p--;
-
- psp_video_switch_to_single();
- if (rom_loaded) menu_draw_begin();
- else memset32_uncached(psp_screen, 0, 512*272*2/4);
-
- smalltext_out16(1, 1, "Loading", 0xffff);
- smalltext_out16_lim(1, 10, p, 0xffff, 80);
- PicoCartLoadProgressCB = load_progress_cb;
- PicoCDLoadProgressCB = cdload_progress_cb;
- lcdr_line = 2;
-}
-
-void menu_romload_end(void)
-{
- PicoCartLoadProgressCB = PicoCDLoadProgressCB = NULL;
- smalltext_out16(1, ++lcdr_line*10, "Starting emulation...", 0xffff);
-}
-
-// -------------- ROM selector --------------
-
-struct my_dirent
-{
- unsigned int d_type;
- char d_name[255];
-};
-
-// bbbb bggg gggr rrrr
-static unsigned short file2color(const char *fname)
-{
- const char *ext = fname + strlen(fname) - 3;
- static const char *rom_exts[] = { "zip", "bin", "smd", "gen", "iso", "cso", "cue" };
- static const char *other_exts[] = { "gmv", "pat" };
- int i;
-
- if (ext < fname) ext = fname;
- for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++)
- if (strcasecmp(ext, rom_exts[i]) == 0) return 0xfdf7;
- for (i = 0; i < sizeof(other_exts)/sizeof(other_exts[0]); i++)
- if (strcasecmp(ext, other_exts[i]) == 0) return 0xaff5;
- return 0xffff;
-}
-
-static void draw_dirlist(char *curdir, struct my_dirent **namelist, int n, int sel)
-{
- int start, i, pos;
-
- start = 13 - sel;
- n--; // exclude current dir (".")
-
- menu_draw_begin();
-
- if (!rom_loaded) {
-// menu_darken_bg(menu_screen, menu_screen, 321*240, 0);
- }
-
- menu_darken_bg((char *)menu_screen + 512*129*2, (char *)menu_screen + 512*129*2, 512*10, 0);
-
- if (start - 2 >= 0)
- smalltext_out16_lim(14, (start - 2)*10, curdir, 0xffff, 53-2);
- for (i = 0; i < n; i++) {
- pos = start + i;
- if (pos < 0) continue;
- if (pos > 26) break;
- if (namelist[i+1]->d_type & FIO_S_IFDIR) {
- smalltext_out16_lim(14, pos*10, "/", 0xd7ff, 1);
- smalltext_out16_lim(14+6, pos*10, namelist[i+1]->d_name, 0xd7ff, 80-3);
- } else {
- unsigned short color = file2color(namelist[i+1]->d_name);
- smalltext_out16_lim(14, pos*10, namelist[i+1]->d_name, color, 80-2);
- }
- }
- text_out16(5, 130, ">");
- menu_draw_end();
-}
-
-static int scandir_cmp(const void *p1, const void *p2)
+static int menu_loop_cscaler(int id, int keys)
{
- struct my_dirent **d1 = (struct my_dirent **)p1, **d2 = (struct my_dirent **)p2;
- if ((*d1)->d_type & (*d2)->d_type & FIO_S_IFDIR)
- return strcasecmp((*d1)->d_name, (*d2)->d_name);
- if ((*d1)->d_type & FIO_S_IFDIR) return -1; // put before
- if ((*d2)->d_type & FIO_S_IFDIR) return 1;
- return strcasecmp((*d1)->d_name, (*d2)->d_name);
-}
-
-static char *filter_exts[] = {
- ".mp3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html",
- ".jpg", ".pbp"
-};
-
-static int scandir_filter(const struct my_dirent *ent)
-{
- const char *p;
- int i;
-
- if (ent == NULL || ent->d_name == NULL) return 0;
- if (strlen(ent->d_name) < 5) return 1;
-
- p = ent->d_name + strlen(ent->d_name) - 4;
-
- for (i = 0; i < sizeof(filter_exts)/sizeof(filter_exts[0]); i++)
- {
- if (strcasecmp(p, filter_exts[i]) == 0) return 0;
- }
-
- return 1;
-}
-
-static int my_scandir(const char *dir, struct my_dirent ***namelist_out,
- int(*filter)(const struct my_dirent *),
- int(*compar)(const void *, const void *))
-{
- int ret = -1, dir_uid = -1, name_alloc = 4, name_count = 0;
- struct my_dirent **namelist = NULL, *ent;
- SceIoDirent sce_ent;
-
- namelist = malloc(sizeof(*namelist) * name_alloc);
- if (namelist == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
-
- // try to read first..
- dir_uid = sceIoDopen(dir);
- if (dir_uid >= 0)
- {
- /* it is very important to clear SceIoDirent to be passed to sceIoDread(), */
- /* or else it may crash, probably misinterpreting something in it. */
- memset(&sce_ent, 0, sizeof(sce_ent));
- ret = sceIoDread(dir_uid, &sce_ent);
- if (ret < 0)
- {
- lprintf("sceIoDread(\"%s\") failed with %i\n", dir, ret);
- goto fail;
- }
- }
- else
- lprintf("sceIoDopen(\"%s\") failed with %i\n", dir, dir_uid);
-
- while (ret > 0)
- {
- ent = malloc(sizeof(*ent));
- if (ent == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
- ent->d_type = sce_ent.d_stat.st_mode;
- strncpy(ent->d_name, sce_ent.d_name, sizeof(ent->d_name));
- ent->d_name[sizeof(ent->d_name)-1] = 0;
- if (filter == NULL || filter(ent))
- namelist[name_count++] = ent;
- else free(ent);
-
- if (name_count >= name_alloc)
- {
- void *tmp;
- name_alloc *= 2;
- tmp = realloc(namelist, sizeof(*namelist) * name_alloc);
- if (tmp == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
- namelist = tmp;
- }
-
- memset(&sce_ent, 0, sizeof(sce_ent));
- ret = sceIoDread(dir_uid, &sce_ent);
- }
-
- // sort
- if (compar != NULL && name_count > 3) qsort(&namelist[2], name_count - 2, sizeof(namelist[0]), compar);
-
- // all done.
- ret = name_count;
- *namelist_out = namelist;
- goto end;
-
-fail:
- if (namelist != NULL)
- {
- while (name_count--)
- free(namelist[name_count]);
- free(namelist);
- }
-end:
- if (dir_uid >= 0) sceIoDclose(dir_uid);
- return ret;
-}
+ unsigned int inp;
+ currentConfig.scaling = SCALE_CUSTOM;
-static SceIoStat cpstat;
-
-static char *romsel_loop(char *curr_path)
-{
- struct my_dirent **namelist;
- int n, iret, sel = 0;
- unsigned long inp = 0;
- char *ret = NULL, *fname = NULL;
-
- // is this a dir or a full path?
- memset(&cpstat, 0, sizeof(cpstat));
- iret = sceIoGetstat(curr_path, &cpstat);
- if (iret >= 0 && (cpstat.st_mode & FIO_S_IFDIR)); // dir
- else if (iret >= 0 && (cpstat.st_mode & FIO_S_IFREG)) { // file
- char *p;
- for (p = curr_path + strlen(curr_path) - 1; p > curr_path && *p != '/'; p--);
- if (p > curr_path) {
- *p = 0;
- fname = p+1;
- }
- else strcpy(curr_path, "ms0:/");
- }
- else strcpy(curr_path, "ms0:/"); // something else
-
- n = my_scandir(curr_path, &namelist, scandir_filter, scandir_cmp);
- if (n < 0) {
- // try root..
- n = my_scandir("ms0:/", &namelist, scandir_filter, scandir_cmp);
- if (n < 0) {
- // oops, we failed
- lprintf("scandir failed, dir: "); lprintf(curr_path); lprintf("\n");
- return NULL;
- }
- }
-
- // try to find sel
- if (fname != NULL) {
- int i;
- for (i = 1; i < n; i++) {
- if (strcmp(namelist[i]->d_name, fname) == 0) {
- sel = i - 1;
- break;
- }
- }
- }
+ pnd_setup_layer(1, g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
+ pnd_restore_layer_data();
for (;;)
{
- draw_dirlist(curr_path, namelist, n, sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R|PBTN_X|PBTN_CIRCLE, 0);
- if(inp & PBTN_UP ) { sel--; if (sel < 0) sel = n-2; }
- if(inp & PBTN_DOWN) { sel++; if (sel > n-2) sel = 0; }
- if(inp & PBTN_LEFT) { sel-=10; if (sel < 0) sel = 0; }
- if(inp & PBTN_L) { sel-=24; if (sel < 0) sel = 0; }
- if(inp & PBTN_RIGHT) { sel+=10; if (sel > n-2) sel = n-2; }
- if(inp & PBTN_R) { sel+=24; if (sel > n-2) sel = n-2; }
- if(inp & PBTN_CIRCLE) // enter dir/select
- {
- if (namelist[sel+1]->d_type & FIO_S_IFDIR)
- {
- int newlen = strlen(curr_path) + strlen(namelist[sel+1]->d_name) + 2;
- char *p, *newdir = malloc(newlen);
- if (strcmp(namelist[sel+1]->d_name, "..") == 0) {
- char *start = curr_path;
- p = start + strlen(start) - 1;
- while (*p == '/' && p > start) p--;
- while (*p != '/' && *p != ':' && p > start) p--;
- if (p <= start || *p == ':') strcpy(newdir, "ms0:/");
- else { strncpy(newdir, start, p-start); newdir[p-start] = 0; }
- } else {
- strcpy(newdir, curr_path);
- p = newdir + strlen(newdir) - 1;
- while (*p == '/' && p >= newdir) *p-- = 0;
- strcat(newdir, "/");
- strcat(newdir, namelist[sel+1]->d_name);
- }
- ret = romsel_loop(newdir);
- free(newdir);
- break;
- }
- else if (namelist[sel+1]->d_type & FIO_S_IFREG)
- {
- strcpy(romFileName, curr_path);
- strcat(romFileName, "/");
- strcat(romFileName, namelist[sel+1]->d_name);
- ret = romFileName;
- break;
- }
- }
- if(inp & PBTN_X) break; // cancel
- }
-
- if (n > 0) {
- while(n--) free(namelist[n]);
- free(namelist);
- }
-
- return ret;
-}
-
-// ------------ patch/gg menu ------------
-
-static void draw_patchlist(int sel)
-{
- int start, i, pos, active;
-
- start = 13 - sel;
-
- menu_draw_begin();
-
- for (i = 0; i < PicoPatchCount; i++) {
- pos = start + i;
- if (pos < 0) continue;
- if (pos > 26) break;
- active = PicoPatches[i].active;
- smalltext_out16_lim(14, pos*10, active ? "ON " : "OFF", active ? 0xfff6 : 0xffff, 3);
- smalltext_out16_lim(14+6*4, pos*10, PicoPatches[i].name, active ? 0xfff6 : 0xffff, 53-6);
- }
- pos = start + i;
- if (pos < 27) smalltext_out16_lim(14, pos*10, "done", 0xffff, 4);
-
- text_out16(5, 130, ">");
- menu_draw_end();
-}
-
-
-static void patches_menu_loop(void)
-{
- int menu_sel = 0;
- unsigned long inp = 0;
+ menu_draw_begin(0, 1);
+ menuscreen_memset_lines(g_menuscreen_ptr, 0, g_menuscreen_h);
+ text_out16(2, 480 - 18, "%dx%d | d-pad to resize, R+d-pad to move", g_layer_cw, g_layer_ch);
+ menu_draw_end();
- for(;;)
- {
- draw_patchlist(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R|PBTN_X|PBTN_CIRCLE, 0);
- 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; }
- if(inp &(PBTN_RIGHT|PBTN_R)) { menu_sel+=10; if (menu_sel > PicoPatchCount) menu_sel = PicoPatchCount; }
- if(inp & PBTN_CIRCLE) { // action
- if (menu_sel < PicoPatchCount)
- PicoPatches[menu_sel].active = !PicoPatches[menu_sel].active;
- else return;
- }
- if(inp & PBTN_X) return;
- }
-
-}
-
-// ------------ savestate loader ------------
-
-static int state_slot_flags = 0;
-
-static void state_check_slots(void)
-{
- int slot;
-
- state_slot_flags = 0;
-
- for (slot = 0; slot < 10; slot++)
- {
- if (emu_checkSaveFile(slot))
- {
- state_slot_flags |= 1 << slot;
- }
- }
-}
-
-static void *get_oldstate_for_preview(void)
-{
- unsigned char *ptr = malloc(sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram) + sizeof(Pico.video));
- if (ptr == NULL) return NULL;
-
- memcpy(ptr, Pico.vram, sizeof(Pico.vram));
- memcpy(ptr + sizeof(Pico.vram), Pico.cram, sizeof(Pico.cram));
- memcpy(ptr + sizeof(Pico.vram) + sizeof(Pico.cram), Pico.vsram, sizeof(Pico.vsram));
- memcpy(ptr + sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram), &Pico.video, sizeof(Pico.video));
- return ptr;
-}
-
-static void restore_oldstate(void *ptrx)
-{
- unsigned char *ptr = ptrx;
- memcpy(Pico.vram, ptr, sizeof(Pico.vram));
- memcpy(Pico.cram, ptr + sizeof(Pico.vram), sizeof(Pico.cram));
- memcpy(Pico.vsram, ptr + sizeof(Pico.vram) + sizeof(Pico.cram), sizeof(Pico.vsram));
- memcpy(&Pico.video,ptr + sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram), sizeof(Pico.video));
- free(ptrx);
-}
-
-static void draw_savestate_bg(int slot)
-{
- void *file, *oldstate;
- char *fname;
-
- fname = emu_GetSaveFName(1, 0, slot);
- if (!fname) return;
-
- oldstate = get_oldstate_for_preview();
- if (oldstate == NULL) return;
-
- if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) {
- file = gzopen(fname, "rb");
- emu_setSaveStateCbs(1);
- } else {
- file = fopen(fname, "rb");
- emu_setSaveStateCbs(0);
- }
-
- if (file) {
- if (PicoIn.AHW & PAHW_MCD) {
- PicoCdLoadStateGfx(file);
- } else {
- areaSeek(file, 0x10020, SEEK_SET); // skip header and RAM in state file
- areaRead(Pico.vram, 1, sizeof(Pico.vram), file);
- areaSeek(file, 0x2000, SEEK_CUR);
- areaRead(Pico.cram, 1, sizeof(Pico.cram), file);
- areaRead(Pico.vsram, 1, sizeof(Pico.vsram), file);
- areaSeek(file, 0x221a0, SEEK_SET);
- areaRead(&Pico.video, 1, sizeof(Pico.video), file);
- }
- areaClose(file);
- }
-
- emu_forcedFrame(0);
- menu_prepare_bg(1, 0);
-
- restore_oldstate(oldstate);
-}
-
-static void draw_savestate_menu(int menu_sel, int is_loading)
-{
- int tl_x = 80+25, tl_y = 16+60, y, i;
-
- if (state_slot_flags & (1 << menu_sel))
- draw_savestate_bg(menu_sel);
- menu_draw_begin();
-
- text_out16(tl_x, 16+30, is_loading ? "Load state" : "Save state");
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 108);
-
- /* draw all 10 slots */
- y = tl_y;
- for (i = 0; i < 10; i++, y+=10)
- {
- text_out16(tl_x, y, "SLOT %i (%s)", i, (state_slot_flags & (1 << i)) ? "USED" : "free");
- }
- text_out16(tl_x, y, "back");
-
- menu_draw_end();
-}
-
-static int savestate_menu_loop(int is_loading)
-{
- static int menu_sel = 10;
- int menu_sel_max = 10;
- unsigned long inp = 0;
-
- state_check_slots();
-
- for(;;)
- {
- draw_savestate_menu(menu_sel, is_loading);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_X|PBTN_CIRCLE, 0);
- if(inp & PBTN_UP ) {
- do {
- menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max;
- } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
- }
- if(inp & PBTN_DOWN) {
- do {
- menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0;
- } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
- }
- if(inp & PBTN_CIRCLE) { // save/load
- if (menu_sel < 10) {
- state_slot = menu_sel;
- PicoStateProgressCB = emu_msg_cb; /* also suitable for menu */
- if (emu_SaveLoadGame(is_loading, 0)) {
- strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed");
- return 1;
- }
- return 0;
- } else return 1;
- }
- if(inp & PBTN_X) return 1;
- }
-}
-
-// -------------- key config --------------
-
-static char *action_binds(int player_idx, int action_mask)
-{
- static char strkeys[32*5];
- int i;
-
- strkeys[0] = 0;
- for (i = 0; i < 32; i++) // i is key index
- {
- if (currentConfig.KeyBinds[i] & action_mask)
- {
- if (player_idx >= 0 && ((currentConfig.KeyBinds[i] >> 16) & 3) != player_idx) continue;
- if (strkeys[0]) {
- strcat(strkeys, i >= 28 ? ", " : " + "); // nub "buttons" don't create combos
- strcat(strkeys, keyNames[i]);
- break;
- }
- else strcpy(strkeys, keyNames[i]);
+ inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT
+ |PBTN_R|PBTN_MOK|PBTN_MBACK, NULL, 40);
+ if (inp & PBTN_UP) g_layer_cy--;
+ if (inp & PBTN_DOWN) g_layer_cy++;
+ if (inp & PBTN_LEFT) g_layer_cx--;
+ if (inp & PBTN_RIGHT) g_layer_cx++;
+ if (!(inp & PBTN_R)) {
+ if (inp & PBTN_UP) g_layer_ch += 2;
+ if (inp & PBTN_DOWN) g_layer_ch -= 2;
+ if (inp & PBTN_LEFT) g_layer_cw += 2;
+ if (inp & PBTN_RIGHT) g_layer_cw -= 2;
}
- }
-
- return strkeys;
-}
-
-static void unbind_action(int action)
-{
- int i;
-
- for (i = 0; i < 32; i++)
- currentConfig.KeyBinds[i] &= ~action;
-}
-
-static int count_bound_keys(int action, int pl_idx)
-{
- int i, keys = 0;
-
- for (i = 0; i < 32; i++)
- {
- if (pl_idx >= 0 && (currentConfig.KeyBinds[i]&0x30000) != (pl_idx<<16)) continue;
- if (currentConfig.KeyBinds[i] & action) keys++;
- }
-
- return keys;
-}
-
-static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_idx, int sel)
-{
- int x, y, tl_y = 16+20, i;
-
- menu_draw_begin();
- if (player_idx >= 0) {
- text_out16(80+80, 16, "Player %i controls", player_idx + 1);
- x = 80+80;
- } else {
- text_out16(80+80, 16, "Emulator controls");
- x = 80+40;
- }
-
- menu_draw_selection(x - 16, tl_y + sel*10, (player_idx >= 0) ? 66 : 130);
-
- y = tl_y;
- for (i = 0; i < opt_cnt; i++, y+=10)
- text_out16(x, y, "%s : %s", opts[i].name, action_binds(player_idx, opts[i].mask));
-
- text_out16(x, y, "Done");
-
- if (sel < opt_cnt) {
- text_out16(80+30, 220, "Press a button to bind/unbind");
- text_out16(80+30, 230, "Use SELECT to clear");
- text_out16(80+30, 240, "To bind UP/DOWN, hold SELECT");
- text_out16(80+30, 250, "Select \"Done\" to exit");
- } else {
- text_out16(80+30, 230, "Use Options -> Save cfg");
- text_out16(80+30, 240, "to save controls");
- text_out16(80+30, 250, "Press X or O to exit");
- }
- menu_draw_end();
-}
-
-static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_idx)
-{
- int sel = 0, menu_sel_max = opt_cnt, prev_select = 0, i;
- unsigned long inp = 0;
-
- for (;;)
- {
- draw_key_config(opts, opt_cnt, player_idx, sel);
- inp = in_menu_wait(CONFIGURABLE_KEYS|PBTN_SELECT, 1);
- if (!(inp & PBTN_SELECT)) {
- prev_select = 0;
- if(inp & PBTN_UP ) { sel--; if (sel < 0) sel = menu_sel_max; continue; }
- if(inp & PBTN_DOWN) { sel++; if (sel > menu_sel_max) sel = 0; continue; }
- }
- if (sel >= opt_cnt) {
- if (inp & (PBTN_X|PBTN_CIRCLE)) break;
- else continue;
- }
- // if we are here, we want to bind/unbind something
- if ((inp & PBTN_SELECT) && !prev_select)
- unbind_action(opts[sel].mask);
- prev_select = inp & PBTN_SELECT;
- inp &= CONFIGURABLE_KEYS;
- inp &= ~PBTN_SELECT;
- for (i = 0; i < 32; i++)
- if (inp & (1 << i)) {
- if (count_bound_keys(opts[sel].mask, player_idx) >= 2)
- currentConfig.KeyBinds[i] &= ~opts[sel].mask; // allow to unbind only
- else currentConfig.KeyBinds[i] ^= opts[sel].mask;
- if (player_idx >= 0 && (currentConfig.KeyBinds[i] & opts[sel].mask)) {
- currentConfig.KeyBinds[i] &= ~(3 << 16);
- currentConfig.KeyBinds[i] |= player_idx << 16;
- }
- }
- }
-}
-
-menu_entry ctrlopt_entries[] =
-{
- { "Player 1", MB_NONE, MA_CTRL_PLAYER1, NULL, 0, 0, 0, 1, 0 },
- { "Player 2", MB_NONE, MA_CTRL_PLAYER2, NULL, 0, 0, 0, 1, 0 },
- { "Emulator controls", MB_NONE, MA_CTRL_EMU, NULL, 0, 0, 0, 1, 0 },
- { "6 button pad", MB_ONOFF, MA_OPT_6BUTTON_PAD, &PicoIn.opt, 0x020, 0, 0, 1, 1 },
- { "Turbo rate", MB_RANGE, MA_CTRL_TURBO_RATE, ¤tConfig.turbo_rate, 0, 1, 30, 1, 1 },
- { "Done", MB_NONE, MA_CTRL_DONE, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define CTRLOPT_ENTRY_COUNT (sizeof(ctrlopt_entries) / sizeof(ctrlopt_entries[0]))
-const int ctrlopt_entry_count = CTRLOPT_ENTRY_COUNT;
-
-static void draw_kc_sel(int menu_sel)
-{
- int tl_x = 80+25+40, tl_y = 16+60, y;
-
- y = tl_y;
- menu_draw_begin();
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 138);
-
- me_draw(ctrlopt_entries, ctrlopt_entry_count, tl_x, tl_y, NULL, NULL);
-
- menu_draw_end();
-}
-
-
-// player2_flag, ?, ?, ?, ?, ?, ?, menu
-// "NEXT SAVE SLOT", "PREV SAVE SLOT", "SWITCH RENDERER", "SAVE STATE",
-// "LOAD STATE", "VOLUME UP", "VOLUME DOWN", "DONE"
-me_bind_action emuctrl_actions[] =
-{
- { "Load State ", 1<<28 },
- { "Save State ", 1<<27 },
- { "Prev Save Slot ", 1<<25 },
- { "Next Save Slot ", 1<<24 },
- { "Switch Renderer ", 1<<26 },
- { "Fast forward ", 1<<22 },
- { "Pico Next page ", 1<<21 },
- { "Pico Prev page ", 1<<20 },
- { "Pico Switch input", 1<<19 },
- { NULL, 0 }
-};
-
-static void kc_sel_loop(void)
-{
- int menu_sel = 5, menu_sel_max = 5;
- unsigned long inp = 0;
- menu_id selected_id;
-
- while (1)
- {
- draw_kc_sel(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
- selected_id = me_index2id(ctrlopt_entries, CTRLOPT_ENTRY_COUNT, menu_sel);
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) // multi choise
- me_process(ctrlopt_entries, CTRLOPT_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- if (inp & PBTN_CIRCLE) {
- int is_6button = PicoIn.opt & POPT_6BTN_PAD;
- switch (selected_id) {
- case MA_CTRL_PLAYER1: key_config_loop(me_ctrl_actions, is_6button ? 15 : 11, 0); return;
- case MA_CTRL_PLAYER2: key_config_loop(me_ctrl_actions, is_6button ? 15 : 11, 1); return;
- case MA_CTRL_EMU: key_config_loop(emuctrl_actions,
- sizeof(emuctrl_actions)/sizeof(emuctrl_actions[0]) - 1, -1); return;
- case MA_CTRL_DONE: if (!rom_loaded) emu_WriteConfig(0); return;
- default: return;
- }
- }
- if (inp & PBTN_X) return;
- }
-}
-
-
-// --------- sega/mega cd options ----------
-
-menu_entry cdopt_entries[] =
-{
- { NULL, MB_NONE, MA_CDOPT_TESTBIOS_USA, NULL, 0, 0, 0, 1, 0 },
- { NULL, MB_NONE, MA_CDOPT_TESTBIOS_EUR, NULL, 0, 0, 0, 1, 0 },
- { NULL, MB_NONE, MA_CDOPT_TESTBIOS_JAP, NULL, 0, 0, 0, 1, 0 },
- { "CD LEDs", MB_ONOFF, MA_CDOPT_LEDS, ¤tConfig.EmuOpt, 0x0400, 0, 0, 1, 1 },
- { "CDDA audio", MB_ONOFF, MA_CDOPT_CDDA, &PicoIn.opt, 0x0800, 0, 0, 1, 1 },
- { "PCM audio", MB_ONOFF, MA_CDOPT_PCM, &PicoIn.opt, 0x0400, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_CDOPT_READAHEAD, NULL, 0, 0, 0, 1, 1 },
- { "SaveRAM cart", MB_ONOFF, MA_CDOPT_SAVERAM, &PicoIn.opt, 0x8000, 0, 0, 1, 1 },
- { "Scale/Rot. fx (slow)", MB_ONOFF, MA_CDOPT_SCALEROT_CHIP,&PicoIn.opt, 0x1000, 0, 0, 1, 1 },
- { "Better sync (slow)", MB_ONOFF, MA_CDOPT_BETTER_SYNC, &PicoIn.opt, 0x2000, 0, 0, 1, 1 },
- { "done", MB_NONE, MA_CDOPT_DONE, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define CDOPT_ENTRY_COUNT (sizeof(cdopt_entries) / sizeof(cdopt_entries[0]))
-const int cdopt_entry_count = CDOPT_ENTRY_COUNT;
-
-
-struct bios_names_t
-{
- char us[32], eu[32], jp[32];
-};
-
-static void menu_cdopt_cust_draw(const menu_entry *entry, int x, int y, void *param)
-{
- struct bios_names_t *bios_names = param;
- char ra_buff[16];
-
- switch (entry->id)
- {
- case MA_CDOPT_TESTBIOS_USA: text_out16(x, y, "USA BIOS: %s", bios_names->us); break;
- case MA_CDOPT_TESTBIOS_EUR: text_out16(x, y, "EUR BIOS: %s", bios_names->eu); break;
- case MA_CDOPT_TESTBIOS_JAP: text_out16(x, y, "JAP BIOS: %s", bios_names->jp); break;
- case MA_CDOPT_READAHEAD:
- if (PicoCDBuffers > 1) sprintf(ra_buff, "%5iK", PicoCDBuffers * 2);
- else strcpy(ra_buff, " OFF");
- text_out16(x, y, "ReadAhead buffer %s", ra_buff);
+ if (inp & (PBTN_MOK|PBTN_MBACK))
break;
- default:break;
- }
-}
-
-static void draw_cd_menu_options(int menu_sel, struct bios_names_t *bios_names)
-{
- int tl_x = 80+25, tl_y = 16+60;
- menu_id selected_id;
- char ra_buff[16];
-
- if (PicoCDBuffers > 1) sprintf(ra_buff, "%5iK", PicoCDBuffers * 2);
- else strcpy(ra_buff, " OFF");
-
- menu_draw_begin();
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 246);
-
- me_draw(cdopt_entries, CDOPT_ENTRY_COUNT, tl_x, tl_y, menu_cdopt_cust_draw, bios_names);
-
- selected_id = me_index2id(cdopt_entries, CDOPT_ENTRY_COUNT, menu_sel);
- if ((selected_id == MA_CDOPT_TESTBIOS_USA && strcmp(bios_names->us, "NOT FOUND")) ||
- (selected_id == MA_CDOPT_TESTBIOS_EUR && strcmp(bios_names->eu, "NOT FOUND")) ||
- (selected_id == MA_CDOPT_TESTBIOS_JAP && strcmp(bios_names->jp, "NOT FOUND")))
- text_out16(tl_x, 250, "Press start to test selected BIOS");
-
- menu_draw_end();
-}
-
-static void cd_menu_loop_options(void)
-{
- static int menu_sel = 0;
- int menu_sel_max = 10;
- unsigned long inp = 0;
- struct bios_names_t bios_names;
- menu_id selected_id;
- char *bios, *p;
-
- if (emu_findBios(4, &bios)) { // US
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
- if (*p == '/') p++;
- strncpy(bios_names.us, p, sizeof(bios_names.us)); bios_names.us[sizeof(bios_names.us)-1] = 0;
- } else strcpy(bios_names.us, "NOT FOUND");
-
- if (emu_findBios(8, &bios)) { // EU
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
- if (*p == '/') p++;
- strncpy(bios_names.eu, p, sizeof(bios_names.eu)); bios_names.eu[sizeof(bios_names.eu)-1] = 0;
- } else strcpy(bios_names.eu, "NOT FOUND");
-
- if (emu_findBios(1, &bios)) { // JP
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
- if (*p == '/') p++;
- strncpy(bios_names.jp, p, sizeof(bios_names.jp)); bios_names.jp[sizeof(bios_names.jp)-1] = 0;
- } else strcpy(bios_names.jp, "NOT FOUND");
-
- menuErrorMsg[0] = 0;
-
- for (;;)
- {
- draw_cd_menu_options(menu_sel, &bios_names);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE|PBTN_START, 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- selected_id = me_index2id(cdopt_entries, CDOPT_ENTRY_COUNT, menu_sel);
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) { // multi choise
- if (!me_process(cdopt_entries, CDOPT_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0) &&
- selected_id == MA_CDOPT_READAHEAD) {
- if (inp & PBTN_LEFT) {
- PicoCDBuffers >>= 1;
- if (PicoCDBuffers < 2) PicoCDBuffers = 0;
- } else {
- if (PicoCDBuffers < 2) PicoCDBuffers = 2;
- else PicoCDBuffers <<= 1;
- if (PicoCDBuffers > 8*1024) PicoCDBuffers = 8*1024; // 16M
- }
- }
- }
- if (inp & PBTN_CIRCLE) // toggleable options
- if (!me_process(cdopt_entries, CDOPT_ENTRY_COUNT, selected_id, 1) &&
- selected_id == MA_CDOPT_DONE) {
- return;
- }
- if (inp & PBTN_START) {
- switch (selected_id) { // BIOS testers
- case MA_CDOPT_TESTBIOS_USA:
- if (emu_findBios(4, &bios)) { // test US
- strcpy(romFileName, bios);
- engineState = PGS_ReloadRom;
- return;
- }
- break;
- case MA_CDOPT_TESTBIOS_EUR:
- if (emu_findBios(8, &bios)) { // test EU
- strcpy(romFileName, bios);
- engineState = PGS_ReloadRom;
- return;
- }
- break;
- case MA_CDOPT_TESTBIOS_JAP:
- if (emu_findBios(1, &bios)) { // test JP
- strcpy(romFileName, bios);
- engineState = PGS_ReloadRom;
- return;
- }
- break;
- default:
- break;
- }
- }
- if (inp & PBTN_X) return;
- }
-}
-
-// --------- display options ----------
-
-menu_entry opt3_entries[] =
-{
- { NULL, MB_NONE, MA_OPT3_SCALE, NULL, 0, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT3_HSCALE32, NULL, 0, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT3_HSCALE40, NULL, 0, 0, 0, 1, 1 },
- { NULL, MB_ONOFF, MA_OPT3_FILTERING, ¤tConfig.scaling, 1, 0, 0, 1, 1 },
- { NULL, MB_RANGE, MA_OPT3_GAMMAA, ¤tConfig.gamma, 0, -4, 16, 1, 1 },
- { NULL, MB_RANGE, MA_OPT3_BLACKLVL, ¤tConfig.gamma2, 0, 0, 2, 1, 1 },
- { NULL, MB_NONE, MA_OPT3_VSYNC, NULL, 0, 0, 0, 1, 1 },
- { "Set to unscaled centered", MB_NONE, MA_OPT3_PRES_NOSCALE, NULL, 0, 0, 0, 1, 0 },
- { "Set to 4:3 scaled", MB_NONE, MA_OPT3_PRES_SCALE43, NULL, 0, 0, 0, 1, 0 },
- { "Set to fullscreen", MB_NONE, MA_OPT3_PRES_FULLSCR, NULL, 0, 0, 0, 1, 0 },
- { "done", MB_NONE, MA_OPT3_DONE, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define OPT3_ENTRY_COUNT (sizeof(opt3_entries) / sizeof(opt3_entries[0]))
-const int opt3_entry_count = OPT3_ENTRY_COUNT;
-
-
-static void menu_opt3_cust_draw(const menu_entry *entry, int x, int y, void *param)
-{
- switch (entry->id)
- {
- case MA_OPT3_SCALE:
- text_out16(x, y, "Scale factor: %.2f", currentConfig.scale);
- break;
- case MA_OPT3_HSCALE32:
- text_out16(x, y, "Hor. scale (for low res. games): %.2f", currentConfig.hscale32);
- break;
- case MA_OPT3_HSCALE40:
- text_out16(x, y, "Hor. scale (for hi res. games): %.2f", currentConfig.hscale40);
- break;
- case MA_OPT3_FILTERING:
- text_out16(x, y, "Bilinear filtering %s", currentConfig.scaling?"ON":"OFF");
- break;
- case MA_OPT3_GAMMAA:
- text_out16(x, y, "Gamma adjustment %2i", currentConfig.gamma);
- break;
- case MA_OPT3_BLACKLVL:
- text_out16(x, y, "Black level %2i", currentConfig.gamma2);
- break;
- case MA_OPT3_VSYNC: {
- char *val = " never";
- if (currentConfig.EmuOpt & 0x2000)
- val = (currentConfig.EmuOpt & 0x10000) ? "sometimes" : " always";
- text_out16(x, y, "Wait for vsync (slow) %s", val);
- break;
- }
- default: break;
- }
-}
-
-static void menu_opt3_preview(int is_32col)
-{
- void *oldstate = NULL;
-
- if (!rom_loaded || ((Pico.video.reg[12]&1)^1) != is_32col)
- {
- extern char bgdatac32_start[], bgdatac40_start[];
- extern int bgdatac32_size, bgdatac40_size;
- void *bgdata = is_32col ? bgdatac32_start : bgdatac40_start;
- unsigned long insize = is_32col ? bgdatac32_size : bgdatac40_size, outsize = 65856;
- int ret;
- ret = uncompress((Bytef *)bg_buffer, &outsize, bgdata, insize);
- if (ret == 0)
- {
- if (rom_loaded) oldstate = get_oldstate_for_preview();
- memcpy(Pico.vram, bg_buffer, sizeof(Pico.vram));
- memcpy(Pico.cram, (char *)bg_buffer + 0x10000, 0x40*2);
- memcpy(Pico.vsram, (char *)bg_buffer + 0x10080, 0x40*2);
- memcpy(&Pico.video,(char *)bg_buffer + 0x10100, 0x40);
- }
- else
- lprintf("uncompress returned %i\n", ret);
- }
-
- memset32_uncached(psp_screen, 0, 512*272*2/4);
- emu_forcedFrame(0);
- menu_prepare_bg(1, 0);
-
- if (oldstate) restore_oldstate(oldstate);
-}
-
-static void draw_dispmenu_options(int menu_sel)
-{
- int tl_x = 80, tl_y = 16+50;
-
- menu_draw_begin();
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 316);
-
- me_draw(opt3_entries, OPT3_ENTRY_COUNT, tl_x, tl_y, menu_opt3_cust_draw, NULL);
-
- menu_draw_end();
-}
-
-static void dispmenu_loop_options(void)
-{
- static int menu_sel = 0;
- int menu_sel_max, is_32col = (Pico.video.reg[12]&1)^1;
- unsigned long inp = 0;
- menu_id selected_id;
-
- menu_sel_max = me_count_enabled(opt3_entries, OPT3_ENTRY_COUNT) - 1;
-
- for (;;)
- {
- draw_dispmenu_options(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- selected_id = me_index2id(opt3_entries, OPT3_ENTRY_COUNT, menu_sel);
- if (selected_id == MA_OPT3_HSCALE40 && is_32col) { is_32col = 0; menu_opt3_preview(is_32col); }
- if (selected_id == MA_OPT3_HSCALE32 && !is_32col) { is_32col = 1; menu_opt3_preview(is_32col); }
-
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) // multi choise
- {
- float *setting = NULL;
- int tmp;
- me_process(opt3_entries, OPT3_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0);
- switch (selected_id) {
- case MA_OPT3_SCALE: setting = ¤tConfig.scale; break;
- case MA_OPT3_HSCALE40: setting = ¤tConfig.hscale40; is_32col = 0; break;
- case MA_OPT3_HSCALE32: setting = ¤tConfig.hscale32; is_32col = 1; break;
- case MA_OPT3_FILTERING:
- case MA_OPT3_GAMMAA:
- case MA_OPT3_BLACKLVL: menu_opt3_preview(is_32col); break;
- case MA_OPT3_VSYNC:
- tmp = ((currentConfig.EmuOpt>>13)&1) | ((currentConfig.EmuOpt>>15)&2);
- tmp = (inp & PBTN_LEFT) ? (tmp>>1) : ((tmp<<1)|1);
- if (tmp > 3) tmp = 3;
- currentConfig.EmuOpt &= ~0x12000;
- currentConfig.EmuOpt |= ((tmp&2)<<15) | ((tmp&1)<<13);
- break;
- default: break;
- }
- if (setting != NULL) {
- while ((inp = psp_pad_read(0)) & (PBTN_LEFT|PBTN_RIGHT)) {
- *setting += (inp & PBTN_LEFT) ? -0.01 : 0.01;
- if (*setting <= 0) *setting = 0.01;
- menu_opt3_preview(is_32col);
- draw_dispmenu_options(menu_sel); // will wait vsync
- }
- }
- }
- if (inp & PBTN_CIRCLE) { // toggleable options
- me_process(opt3_entries, OPT3_ENTRY_COUNT, selected_id, 1);
- switch (selected_id) {
- case MA_OPT3_DONE:
- return;
- case MA_OPT3_PRES_NOSCALE:
- currentConfig.scale = currentConfig.hscale40 = currentConfig.hscale32 = 1.0;
- menu_opt3_preview(is_32col);
- break;
- case MA_OPT3_PRES_SCALE43:
- currentConfig.scale = 1.20;
- currentConfig.hscale40 = 1.00;
- currentConfig.hscale32 = 1.25;
- menu_opt3_preview(is_32col);
- break;
- case MA_OPT3_PRES_FULLSCR:
- currentConfig.scale = 1.20;
- currentConfig.hscale40 = 1.25;
- currentConfig.hscale32 = 1.56;
- menu_opt3_preview(is_32col);
- break;
- case MA_OPT3_FILTERING:
- menu_opt3_preview(is_32col);
- break;
- default: break;
- }
- }
- if (inp & PBTN_X) return;
- }
-}
-
-
-// --------- advanced options ----------
-
-menu_entry opt2_entries[] =
-{
- { "Disable sprite limit", MB_ONOFF, MA_OPT2_NO_SPRITE_LIM, &PicoIn.opt, 0x40000, 0, 0, 1, 1 },
- { "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, &PicoIn.opt, 0x00004, 0, 0, 1, 1 },
- { "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &PicoIn.opt, 0x00001, 0, 0, 1, 1 },
- { "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496, &PicoIn.opt, 0x00002, 0, 0, 1, 1 },
- { "Emulate YM2413 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2413, &PicoIn.opt, 0x00020, 0, 0, 1, 1 },
- { "gzip savestates", MB_ONOFF, MA_OPT2_GZIP_STATES, ¤tConfig.EmuOpt, 0x00008, 0, 0, 1, 1 },
- { "Don't save last used ROM", MB_ONOFF, MA_OPT2_NO_LAST_ROM, ¤tConfig.EmuOpt, 0x00020, 0, 0, 1, 1 },
- { "Status line in main menu", MB_ONOFF, MA_OPT2_STATUS_LINE, ¤tConfig.EmuOpt, 0x20000, 0, 0, 1, 1 },
- { "Disable idle loop patching",MB_ONOFF, MA_OPT2_NO_IDLE_LOOPS, &PicoIn.opt, 0x80000, 0, 0, 1, 1 },
- { "Disable frame limiter", MB_ONOFF, MA_OPT2_NO_FRAME_LIMIT, ¤tConfig.EmuOpt, 0x40000, 0, 0, 1, 1 },
- { "done", MB_NONE, MA_OPT2_DONE, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define OPT2_ENTRY_COUNT (sizeof(opt2_entries) / sizeof(opt2_entries[0]))
-const int opt2_entry_count = OPT2_ENTRY_COUNT;
-
-
-static void draw_amenu_options(int menu_sel)
-{
- int tl_x = 80+25, tl_y = 16+50;
-
- menu_draw_begin();
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 252);
-
- me_draw(opt2_entries, OPT2_ENTRY_COUNT, tl_x, tl_y, NULL, NULL);
-
- menu_draw_end();
-}
-
-static void amenu_loop_options(void)
-{
- static int menu_sel = 0;
- int menu_sel_max;
- unsigned long inp = 0;
- menu_id selected_id;
-
- menu_sel_max = me_count_enabled(opt2_entries, OPT2_ENTRY_COUNT) - 1;
-
- for(;;)
- {
- draw_amenu_options(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- selected_id = me_index2id(opt2_entries, OPT2_ENTRY_COUNT, menu_sel);
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) { // multi choise
- if (!me_process(opt2_entries, OPT2_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0) &&
- selected_id == MA_OPT2_GAMMA) {
- // TODO?
- }
- }
- if (inp & PBTN_CIRCLE) { // toggleable options
- if (!me_process(opt2_entries, OPT2_ENTRY_COUNT, selected_id, 1) &&
- selected_id == MA_OPT2_DONE) {
- return;
- }
- }
- if (inp & PBTN_X) return;
- }
-}
-
-// -------------- options --------------
-
-
-menu_entry opt_entries[] =
-{
- { NULL, MB_NONE, MA_OPT_RENDERER, NULL, 0, 0, 0, 1, 1 },
- { "Accurate sprites", MB_ONOFF, MA_OPT_ACC_SPRITES, &PicoIn.opt, 0x080, 0, 0, 0, 1 },
- { "Show FPS", MB_ONOFF, MA_OPT_SHOW_FPS, ¤tConfig.EmuOpt, 0x0002, 0, 0, 1, 1 },
- { NULL, MB_RANGE, MA_OPT_FRAMESKIP, ¤tConfig.Frameskip, 0, -1, 16, 1, 1 },
- { "Enable sound", MB_ONOFF, MA_OPT_ENABLE_SOUND, ¤tConfig.EmuOpt, 0x0004, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT_REGION, NULL, 0, 0, 0, 1, 1 },
- { "Use SRAM/BRAM savestates", MB_ONOFF, MA_OPT_SRAM_STATES, ¤tConfig.EmuOpt, 0x0001, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT_CONFIRM_STATES,NULL, 0, 0, 0, 1, 1 },
- { "Save slot", MB_RANGE, MA_OPT_SAVE_SLOT, &state_slot, 0, 0, 9, 1, 1 },
- { NULL, MB_NONE, MA_OPT_CPU_CLOCKS, NULL, 0, 0, 0, 1, 1 },
- { "[Display options]", MB_NONE, MA_OPT_DISP_OPTS, NULL, 0, 0, 0, 1, 0 },
- { "[Sega/Mega CD options]", MB_NONE, MA_OPT_SCD_OPTS, NULL, 0, 0, 0, 1, 0 },
- { "[Advanced options]", MB_NONE, MA_OPT_ADV_OPTS, NULL, 0, 0, 0, 1, 0 },
- { NULL, MB_NONE, MA_OPT_SAVECFG, NULL, 0, 0, 0, 1, 0 },
- { "Save cfg for current game only",MB_NONE,MA_OPT_SAVECFG_GAME,NULL, 0, 0, 0, 1, 0 },
- { NULL, MB_NONE, MA_OPT_LOADCFG, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define OPT_ENTRY_COUNT (sizeof(opt_entries) / sizeof(opt_entries[0]))
-const int opt_entry_count = OPT_ENTRY_COUNT;
-
-
-static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *param)
-{
- char *str, str24[24];
-
- switch (entry->id)
- {
- case MA_OPT_RENDERER:
- if (PicoIn.opt & 0x10)
- str = "fast";
- else if (currentConfig.EmuOpt & 0x80)
- str = "accurate";
- else
- str = " 8bit accurate"; // n/a
- text_out16(x, y, "Renderer: %s", str);
- break;
- case MA_OPT_FRAMESKIP:
- if (currentConfig.Frameskip < 0)
- strcpy(str24, "Auto");
- else sprintf(str24, "%i", currentConfig.Frameskip);
- text_out16(x, y, "Frameskip %s", str24);
- break;
- case MA_OPT_SOUND_QUALITY:
- str = (PicoIn.opt&0x08)?"stereo":"mono";
- text_out16(x, y, "Sound Quality: %5iHz %s", PicoIn.sndRate, str);
- break;
- case MA_OPT_REGION:
- text_out16(x, y, "Region: %s", me_region_name(PicoIn.regionOverride, PicoIn.autoRgnOrder));
- break;
- case MA_OPT_CONFIRM_STATES:
- switch ((currentConfig.EmuOpt >> 9) & 5) {
- default: str = "OFF"; break;
- case 1: str = "writes"; break;
- case 4: str = "loads"; break;
- case 5: str = "both"; break;
- }
- text_out16(x, y, "Confirm savestate %s", str);
- break;
- case MA_OPT_CPU_CLOCKS:
- text_out16(x, y, "CPU/bus clock %3i/%3iMHz", currentConfig.CPUclock, currentConfig.CPUclock/2);
- break;
- case MA_OPT_SAVECFG:
- str24[0] = 0;
- if (config_slot != 0) sprintf(str24, " (profile: %i)", config_slot);
- text_out16(x, y, "Save cfg as default%s", str24);
- break;
- case MA_OPT_LOADCFG:
- text_out16(x, y, "Load cfg from profile %i", config_slot);
- break;
- default:
- lprintf("%s: unimplemented (%i)\n", __FUNCTION__, entry->id);
- break;
- }
-}
-
-
-static void draw_menu_options(int menu_sel)
-{
- int tl_x = 80+25, tl_y = 16+24;
- menu_draw_begin();
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 284);
-
- me_draw(opt_entries, OPT_ENTRY_COUNT, tl_x, tl_y, menu_opt_cust_draw, NULL);
-
- menu_draw_end();
-}
-
-static int sndrate_prevnext(int rate, int dir)
-{
- int i, rates[] = { 11025, 22050, 44100 };
-
- for (i = 0; i < 5; i++)
- if (rates[i] == rate) break;
-
- i += dir ? 1 : -1;
- if (i > 2) return dir ? 44100 : 22050;
- if (i < 0) return dir ? 22050 : 11025;
- return rates[i];
-}
-
-static void region_prevnext(int right)
-{
- // jp_ntsc=1, jp_pal=2, usa=4, eu=8
- static int rgn_orders[] = { 0x148, 0x184, 0x814, 0x418, 0x841, 0x481 };
- int i;
- if (right) {
- if (!PicoIn.regionOverride) {
- for (i = 0; i < 6; i++)
- if (rgn_orders[i] == PicoIn.autoRgnOrder) break;
- if (i < 5) PicoIn.autoRgnOrder = rgn_orders[i+1];
- else PicoIn.regionOverride=1;
+ if (inp & (PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT)) {
+ if (g_layer_cx < 0) g_layer_cx = 0;
+ if (g_layer_cx > 640) g_layer_cx = 640;
+ if (g_layer_cy < 0) g_layer_cy = 0;
+ if (g_layer_cy > 420) g_layer_cy = 420;
+ if (g_layer_cw < 160) g_layer_cw = 160;
+ if (g_layer_ch < 60) g_layer_ch = 60;
+ if (g_layer_cx + g_layer_cw > 800)
+ g_layer_cw = 800 - g_layer_cx;
+ if (g_layer_cy + g_layer_ch > 480)
+ g_layer_ch = 480 - g_layer_cy;
+ pnd_setup_layer(1, g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
}
- else PicoIn.regionOverride<<=1;
- if (PicoIn.regionOverride > 8) PicoIn.regionOverride = 8;
- } else {
- if (!PicoIn.regionOverride) {
- for (i = 0; i < 6; i++)
- if (rgn_orders[i] == PicoIn.autoRgnOrder) break;
- if (i > 0) PicoIn.autoRgnOrder = rgn_orders[i-1];
- }
- else PicoIn.regionOverride>>=1;
- }
-}
-
-static void menu_options_save(void)
-{
- if (PicoIn.regionOverride) {
- // force setting possibly changed..
- Pico.m.pal = (PicoIn.regionOverride == 2 || PicoIn.regionOverride == 8) ? 1 : 0;
- }
- if (!(PicoIn.opt & POPT_6BTN_PAD)) {
- // unbind XYZ MODE, just in case
- unbind_action(0xf00);
}
-}
-static int menu_loop_options(void)
-{
- static int menu_sel = 0;
- int menu_sel_max, ret;
- unsigned long inp = 0;
- menu_id selected_id;
+ pnd_setup_layer(0, g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
- me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_SAVECFG_GAME, rom_loaded);
- me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_LOADCFG, config_slot != config_slot_current);
- menu_sel_max = me_count_enabled(opt_entries, OPT_ENTRY_COUNT) - 1;
- if (menu_sel > menu_sel_max) menu_sel = menu_sel_max;
-
- while (1)
- {
- draw_menu_options(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- selected_id = me_index2id(opt_entries, OPT_ENTRY_COUNT, menu_sel);
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) { // multi choise
- if (!me_process(opt_entries, OPT_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0)) {
- switch (selected_id) {
- case MA_OPT_RENDERER:
- if ((PicoIn.opt & 0x10) || !(currentConfig.EmuOpt & 0x80)) {
- PicoIn.opt &= ~0x10;
- currentConfig.EmuOpt |= 0x80;
- } else {
- PicoIn.opt |= 0x10;
- currentConfig.EmuOpt &= ~0x80;
- }
- break;
- case MA_OPT_SOUND_QUALITY:
- PicoIn.sndRate = sndrate_prevnext(PicoIn.sndRate, inp & PBTN_RIGHT);
- break;
- case MA_OPT_REGION:
- region_prevnext(inp & PBTN_RIGHT);
- break;
- case MA_OPT_CONFIRM_STATES: {
- int n = ((currentConfig.EmuOpt>>9)&1) | ((currentConfig.EmuOpt>>10)&2);
- n += (inp & PBTN_LEFT) ? -1 : 1;
- if (n < 0) n = 0; else if (n > 3) n = 3;
- n |= n << 1; n &= ~2;
- currentConfig.EmuOpt &= ~0xa00;
- currentConfig.EmuOpt |= n << 9;
- break;
- }
- case MA_OPT_SAVE_SLOT:
- if (inp & PBTN_RIGHT) {
- state_slot++; if (state_slot > 9) state_slot = 0;
- } else {state_slot--; if (state_slot < 0) state_slot = 9;
- }
- break;
- case MA_OPT_CPU_CLOCKS:
- while ((inp = psp_pad_read(0)) & (PBTN_LEFT|PBTN_RIGHT)) {
- currentConfig.CPUclock += (inp & PBTN_LEFT) ? -1 : 1;
- if (currentConfig.CPUclock < 19) currentConfig.CPUclock = 19;
- if (currentConfig.CPUclock > 333) currentConfig.CPUclock = 333;
- draw_menu_options(menu_sel); // will wait vsync
- }
- break;
- case MA_OPT_SAVECFG:
- case MA_OPT_SAVECFG_GAME:
- case MA_OPT_LOADCFG:
- config_slot += (inp&PBTN_RIGHT) ? 1 : -1;
- if (config_slot > 9) config_slot = 0;
- if (config_slot < 0) config_slot = 9;
- me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_LOADCFG, config_slot != config_slot_current);
- menu_sel_max = me_count_enabled(opt_entries, OPT_ENTRY_COUNT) - 1;
- if (menu_sel > menu_sel_max) menu_sel = menu_sel_max;
- break;
- default:
- //lprintf("%s: something unknown selected (%i)\n", __FUNCTION__, selected_id);
- break;
- }
- }
- }
- if (inp & PBTN_CIRCLE) {
- if (!me_process(opt_entries, OPT_ENTRY_COUNT, selected_id, 1))
- {
- switch (selected_id)
- {
- case MA_OPT_DISP_OPTS:
- dispmenu_loop_options();
- break;
- case MA_OPT_SCD_OPTS:
- cd_menu_loop_options();
- if (engineState == PGS_ReloadRom)
- return 0; // test BIOS
- break;
- case MA_OPT_ADV_OPTS:
- amenu_loop_options();
- break;
- case MA_OPT_SAVECFG: // done (update and write)
- menu_options_save();
- if (emu_WriteConfig(0)) strcpy(menuErrorMsg, "config saved");
- else strcpy(menuErrorMsg, "failed to write config");
- return 1;
- case MA_OPT_SAVECFG_GAME: // done (update and write for current game)
- menu_options_save();
- if (emu_WriteConfig(1)) strcpy(menuErrorMsg, "config saved");
- else strcpy(menuErrorMsg, "failed to write config");
- return 1;
- case MA_OPT_LOADCFG:
- ret = emu_ReadConfig(1, 1);
- if (!ret) ret = emu_ReadConfig(0, 1);
- if (ret) strcpy(menuErrorMsg, "config loaded");
- else strcpy(menuErrorMsg, "failed to load config");
- return 1;
- default:
- //lprintf("%s: something unknown selected (%i)\n", __FUNCTION__, selected_id);
- break;
- }
- }
- }
- if(inp & PBTN_X) {
- menu_options_save();
- return 0; // done (update, no write)
- }
- }
+ return 0;
}
+#endif
-// -------------- credits --------------
-
-static void draw_menu_credits(void)
-{
- int tl_x = 80+15, tl_y = 16+64, y;
- menu_draw_begin();
-
- text_out16(tl_x, 16+20, "PicoDrive v" VERSION " (c) notaz, 2006-2008");
-
- y = tl_y;
- text_out16(tl_x, y, "Credits:");
- text_out16(tl_x, (y+=10), "fDave: base code of PicoDrive");
- text_out16(tl_x, (y+=10), "Chui: Fame/C");
- text_out16(tl_x, (y+=10), "NJ: CZ80");
- text_out16(tl_x, (y+=10), "MAME devs: YM2612 and SN76496 cores");
- text_out16(tl_x, (y+=10), "ps2dev.org people: PSP SDK/code");
- text_out16(tl_x, (y+=10), "ketchupgun: skin design");
-
- text_out16(tl_x, (y+=20), "special thanks (for docs, ideas):");
- text_out16(tl_x, (y+=10), " Charles MacDonald, Haze,");
- text_out16(tl_x, (y+=10), " Stephane Dallongeville,");
- text_out16(tl_x, (y+=10), " Lordus, Exophase, Rokas,");
- text_out16(tl_x, (y+=10), " Nemesis, Tasco Deluxe");
-
- menu_draw_end();
-}
-
-
-// -------------- root menu --------------
-
-menu_entry main_entries[] =
-{
- { "Resume game", MB_NONE, MA_MAIN_RESUME_GAME, NULL, 0, 0, 0, 0 },
- { "Save State", MB_NONE, MA_MAIN_SAVE_STATE, NULL, 0, 0, 0, 0 },
- { "Load State", MB_NONE, MA_MAIN_LOAD_STATE, NULL, 0, 0, 0, 0 },
- { "Reset game", MB_NONE, MA_MAIN_RESET_GAME, NULL, 0, 0, 0, 0 },
- { "Load new ROM/ISO", MB_NONE, MA_MAIN_LOAD_ROM, NULL, 0, 0, 0, 1 },
- { "Change options", MB_NONE, MA_MAIN_OPTIONS, NULL, 0, 0, 0, 1 },
- { "Configure controls", MB_NONE, MA_MAIN_CONTROLS, NULL, 0, 0, 0, 1 },
- { "Credits", MB_NONE, MA_MAIN_CREDITS, NULL, 0, 0, 0, 1 },
- { "Patches / GameGenie",MB_NONE, MA_MAIN_PATCHES, NULL, 0, 0, 0, 0 },
- { "Exit", MB_NONE, MA_MAIN_EXIT, NULL, 0, 0, 0, 1 }
-};
-
-#define MAIN_ENTRY_COUNT (sizeof(main_entries) / sizeof(main_entries[0]))
-
-static void draw_menu_root(int menu_sel)
-{
- const int tl_x = 86+70, tl_y = 16+70;
- char *stat = NULL;
-
- menu_draw_begin();
-
- if ((currentConfig.EmuOpt&0x20000) && (stat = psp_get_status_line()))
- text_out16(287, 12, "%s", stat);
-
- text_out16(tl_x, 48, "PicoDrive v" VERSION);
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 146);
-
- me_draw(main_entries, MAIN_ENTRY_COUNT, tl_x, tl_y, NULL, NULL);
-
- // error
- if (menuErrorMsg[0])
- text_out16(10, 252, menuErrorMsg);
- menu_draw_end();
-}
-
-
-static void menu_loop_root(void)
-{
- static int menu_sel = 0;
- int ret, menu_sel_max;
- unsigned long inp = 0;
-
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_RESUME_GAME, rom_loaded);
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_SAVE_STATE, rom_loaded);
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_LOAD_STATE, rom_loaded);
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_RESET_GAME, rom_loaded);
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_PATCHES, PicoPatches != NULL);
-
- menu_sel_max = me_count_enabled(main_entries, MAIN_ENTRY_COUNT) - 1;
- if (menu_sel > menu_sel_max) menu_sel = menu_sel_max;
-
- // mp3 errors?
- if (mp3_last_error != 0) {
- if (mp3_last_error == -1)
- sprintf(menuErrorMsg, "Unsupported mp3 format, use 44kHz stereo");
- else sprintf(menuErrorMsg, "mp3 init failed, code %08x", mp3_last_error);
- mp3_last_error = 0;
- }
-
- /* make sure action buttons are not pressed on entering menu */
- draw_menu_root(menu_sel);
-
- while (psp_pad_read(1) & (PBTN_X|PBTN_CIRCLE|PBTN_SELECT)) psp_msleep(50);
-
- for (;;)
- {
- draw_menu_root(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_X|PBTN_CIRCLE|PBTN_SELECT|PBTN_L|PBTN_R, 0);
- if(inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if(inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- if((inp & (PBTN_L|PBTN_R)) == (PBTN_L|PBTN_R)) debug_menu_loop();
- if( inp & (PBTN_SELECT|PBTN_X)) {
- if (rom_loaded) {
- while (psp_pad_read(1) & (PBTN_SELECT|PBTN_X)) psp_msleep(50); // wait until released
- engineState = PGS_Running;
- break;
- }
- }
- if(inp & PBTN_CIRCLE) {
- menuErrorMsg[0] = 0; // clear error msg
- switch (me_index2id(main_entries, MAIN_ENTRY_COUNT, menu_sel))
- {
- case MA_MAIN_RESUME_GAME:
- if (rom_loaded) {
- while (psp_pad_read(1) & PBTN_CIRCLE) psp_msleep(50);
- engineState = PGS_Running;
- return;
- }
- break;
- case MA_MAIN_SAVE_STATE:
- if (rom_loaded) {
- if(savestate_menu_loop(0))
- continue;
- engineState = PGS_Running;
- return;
- }
- break;
- case MA_MAIN_LOAD_STATE:
- if (rom_loaded) {
- if(savestate_menu_loop(1))
- continue;
- while (psp_pad_read(1) & PBTN_CIRCLE) psp_msleep(50);
- engineState = PGS_Running;
- return;
- }
- break;
- case MA_MAIN_RESET_GAME:
- if (rom_loaded) {
- emu_ResetGame();
- while (psp_pad_read(1) & PBTN_CIRCLE) psp_msleep(50);
- engineState = PGS_Running;
- return;
- }
- break;
- case MA_MAIN_LOAD_ROM:
- {
- char curr_path[PATH_MAX], *selfname;
- FILE *tstf;
- if ( (tstf = fopen(loadedRomFName, "rb")) )
- {
- fclose(tstf);
- strcpy(curr_path, loadedRomFName);
- }
- else
- getcwd(curr_path, PATH_MAX);
- selfname = romsel_loop(curr_path);
- if (selfname) {
- lprintf("selected file: %s\n", selfname);
- engineState = PGS_ReloadRom;
- return;
- }
- break;
- }
- case MA_MAIN_OPTIONS:
- ret = menu_loop_options();
- if (ret == 1) continue; // status update
- if (engineState == PGS_ReloadRom)
- return; // BIOS test
- break;
- case MA_MAIN_CONTROLS:
- kc_sel_loop();
- break;
- case MA_MAIN_CREDITS:
- draw_menu_credits();
- psp_msleep(500);
- inp = 0;
- while (!(inp & (PBTN_X|PBTN_CIRCLE)))
- inp = in_menu_wait(PBTN_X|PBTN_CIRCLE, 0);
- break;
- case MA_MAIN_EXIT:
- engineState = PGS_Quit;
- return;
- case MA_MAIN_PATCHES:
- if (rom_loaded && PicoPatches) {
- patches_menu_loop();
- PicoPatchApply();
- strcpy(menuErrorMsg, "Patches applied");
- continue;
- }
- break;
- default:
- lprintf("%s: something unknown selected\n", __FUNCTION__);
- break;
- }
- }
- }
-}
-
-void menu_darken_bg(void *dst, const void *src, int pixels, int darker)
-{
- unsigned int *dest = dst;
- const unsigned int *srce = src;
- pixels /= 2;
- if (darker)
- {
- while (pixels--)
- {
- unsigned int p = *srce++;
- *dest++ = ((p&0xf79ef79e)>>1) - ((p&0xc618c618)>>3);
- }
- }
- else
- {
- while (pixels--)
- {
- unsigned int p = *srce++;
- *dest++ = (p&0xf79ef79e)>>1;
- }
- }
-}
-
-static void menu_prepare_bg(int use_game_bg, int use_fg)
-{
- if (use_game_bg)
- {
- // darken the active framebuffer
- unsigned short *dst = bg_buffer;
- unsigned short *src = use_fg ? psp_video_get_active_fb() : psp_screen;
- int i;
- for (i = 272; i > 0; i--, dst += 480, src += 512)
- menu_darken_bg(dst, src, 480, 1);
- //memset32_uncached((int *)(bg_buffer + 480*264), 0, 480*8*2/4);
- }
- else
- {
- // should really only happen once, on startup..
- memset32_uncached((int *)(void *)bg_buffer, 0, sizeof(bg_buffer)/4);
- readpng(bg_buffer, "skin/background.png", READPNG_BG);
- }
- sceKernelDcacheWritebackAll();
-}
-
-static void menu_gfx_prepare(void)
-{
- menu_prepare_bg(rom_loaded, 1);
-
- menu_draw_begin();
- menu_draw_end();
-}
-
-
-void menu_loop(void)
-{
- menu_gfx_prepare();
-
- menu_loop_root();
-
- menuErrorMsg[0] = 0;
-}
-
-
-// --------- CD tray close menu ----------
-
-static void draw_menu_tray(int menu_sel)
-{
- int tl_x = 70, tl_y = 90, y;
-
- menu_draw_begin();
-
- text_out16(tl_x, 20, "The unit is about to");
- text_out16(tl_x, 30, "close the CD tray.");
-
- y = tl_y;
- text_out16(tl_x, y, "Load new CD image");
- text_out16(tl_x, (y+=10), "Insert nothing");
-
- // draw cursor
- text_out16(tl_x - 16, tl_y + menu_sel*10, ">");
- // error
- if (menuErrorMsg[0]) text_out16(5, 226, menuErrorMsg);
- menu_draw_end();
-}
-
-
-int menu_loop_tray(void)
-{
- int menu_sel = 0, menu_sel_max = 1;
- unsigned long inp = 0;
- char curr_path[PATH_MAX], *selfname;
- FILE *tstf;
-
- menu_gfx_prepare();
-
- if ( (tstf = fopen(loadedRomFName, "rb")) )
- {
- fclose(tstf);
- strcpy(curr_path, loadedRomFName);
- }
- else
- {
- getcwd(curr_path, PATH_MAX);
- }
-
- /* make sure action buttons are not pressed on entering menu */
- draw_menu_tray(menu_sel);
- while (psp_pad_read(1) & PBTN_CIRCLE) psp_msleep(50);
-
- for (;;)
- {
- draw_menu_tray(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_CIRCLE, 0);
- if(inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if(inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- if(inp & PBTN_CIRCLE) {
- switch (menu_sel) {
- case 0: // select image
- selfname = romsel_loop(curr_path);
- if (selfname) {
- int ret = -1;
- cd_img_type cd_type;
- cd_type = emu_cdCheck(NULL, romFileName);
- if (cd_type != CIT_NOT_CD)
- ret = Insert_CD(romFileName, cd_type);
- if (ret != 0) {
- sprintf(menuErrorMsg, "Load failed, invalid CD image?");
- lprintf("%s\n", menuErrorMsg);
- continue;
- }
- engineState = PGS_RestartRun;
- return 1;
- }
- break;
- case 1: // insert nothing
- engineState = PGS_RestartRun;
- return 0;
- }
- }
- menuErrorMsg[0] = 0; // clear error msg
- }
-}
+#define MENU_OPTIONS_GFX \
+ mee_enum ("Scaler", MA_OPT_SCALING, currentConfig.scaling, \
+ men_scaler), \
+ mee_onoff ("Vsync", MA_OPT3_VSYNC, currentConfig.EmuOpt, EOPT_VSYNC), \
+ /* mee_cust_h ("Setup custom scaler", MA_NONE, menu_loop_cscaler, NULL, h_cscaler), \*/
+#define MENU_OPTIONS_ADV