From aa40e1b827555d6efb0cb9177b015ec02d44c7dd Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 5 Feb 2011 02:36:44 +0200 Subject: [PATCH 01/16] cdrom: remove cdrWrite3 reschedule shalma keeps adding and removing it, I think it does more harm then good --- libpcsxcore/cdrom.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index b063fa51..343d82c9 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -1894,9 +1894,15 @@ void cdrWrite3(unsigned char rt) { return; } + // XA streaming - incorrect timing because of this reschedule + // - Final Fantasy Tactics + // - various other games + + /* if (cdr.Reading && !cdr.ResultReady) { CDREAD_INT((cdr.Mode & MODE_SPEED) ? (cdReadTime / 2) : cdReadTime); } + */ return; } -- 2.39.2 From 7cd19de2fd689b38596df1c5821ce02f845dc654 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 5 Feb 2011 00:27:07 +0200 Subject: [PATCH 02/16] drc: sync gte with interpreter --- libpcsxcore/new_dynarec/assem_arm.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c index 976aac8c..c9505853 100644 --- a/libpcsxcore/new_dynarec/assem_arm.c +++ b/libpcsxcore/new_dynarec/assem_arm.c @@ -3556,9 +3556,6 @@ static void cop2_get_dreg(u_int copr,signed char tl,signed char temp) emit_writeword(tl,(int)®_cop2d[copr]); break; case 28: - case 30: - emit_movimm(0,tl); - break; case 29: emit_readword((int)®_cop2d[9],temp); emit_testimm(temp,0x8000); // do we need this? @@ -3613,8 +3610,6 @@ static void cop2_put_dreg(u_int copr,signed char sl,signed char temp) emit_writeword(sl,(int)®_cop2d[30]); emit_writeword(temp,(int)®_cop2d[31]); break; - case 7: - case 29: case 31: break; default: -- 2.39.2 From 018f9fea66b5ec11e4e7037d34f289e357b4873f Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 5 Feb 2011 01:31:47 +0200 Subject: [PATCH 03/16] drc: update memhandler according to pcsxr code --- libpcsxcore/new_dynarec/linkage_arm.s | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libpcsxcore/new_dynarec/linkage_arm.s b/libpcsxcore/new_dynarec/linkage_arm.s index 7b76aec3..8744608f 100644 --- a/libpcsxcore/new_dynarec/linkage_arm.s +++ b/libpcsxcore/new_dynarec/linkage_arm.s @@ -1000,13 +1000,23 @@ ari_read_io32: str\pf r1, [r2, r3] mov pc, lr 1: -.if \tab_shift == 1 @ write16 cmp r2, #0x1c00 blo 0b cmp r2, #0x1e00 +.if \tab_shift != 0 ldrlo pc, [fp, #spu_writef-dynarec_local] - nop +.else + @ write32 to SPU - very rare case (is this correct?) + bhs 0b + add r2, r0, #2 + mov r3, r1, lsr #16 + push {r2,r3,lr} + mov lr, pc + ldr pc, [fp, #spu_writef-dynarec_local] + pop {r0,r1,lr} + ldr pc, [fp, #spu_writef-dynarec_local] .endif + nop b 0b .endm -- 2.39.2 From c89cd762a63a78e30a59955e705e29ff3d5ae3b8 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 5 Feb 2011 02:31:47 +0200 Subject: [PATCH 04/16] frontend: redo frame skip/limiter yet again --- frontend/menu.c | 4 ++-- frontend/plugin_lib.c | 40 +++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/frontend/menu.c b/frontend/menu.c index ea1ebe51..754b6d23 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -1037,10 +1037,10 @@ const char *plat_get_credits(void) return "PCSX-ReARMed\n\n" "(C) 1999-2003 PCSX Team\n" "(C) 2005-2009 PCSX-df Team\n" - "(C) 2009-2010 PCSX-Reloaded Team\n\n" + "(C) 2009-2011 PCSX-Reloaded Team\n\n" "GPU and SPU code by Pete Bernert\n" " and the P.E.Op.S. team\n" - "ARM recompiler (C) 2009-2010 Ari64\n" + "ARM recompiler (C) 2009-2011 Ari64\n" "PCSX4ALL plugins by PCSX4ALL team\n" " Chui, Franxis, Unai\n\n" "integration, optimization and\n" diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 24817794..17ed79a9 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -31,6 +31,7 @@ int keystate; static int pl_fbdev_w, pl_fbdev_h, pl_fbdev_bpp; static int flip_cnt, vsync_cnt, flips_per_sec, tick_per_sec; static float vsps_cur; +static int plugin_skip_advice; // P.E.Op.S. extern int UseFrameSkip; extern float fps_skip; @@ -183,22 +184,25 @@ void pl_frame_limit(void) } #endif - if (!(g_opts & OPT_NO_FRAMELIM)) { - tvadd(tv_expect, pl_frame_interval); - diff = tvdiff(tv_expect, now); - if (diff > MAX_LAG_FRAMES * pl_frame_interval || diff < -MAX_LAG_FRAMES * pl_frame_interval) { - //printf("pl_frame_limit reset, diff=%d, iv %d\n", diff, pl_frame_interval); - tv_expect = now; - } - else if (diff > pl_frame_interval) { - // yay for working usleep on pandora! - //printf("usleep %d\n", diff - pl_frame_interval / 2); - usleep(diff - pl_frame_interval / 2); - } - else if (diff < 0 && UseFrameSkip) { - // P.E.Op.S. makes skip decision based on this - fps_skip = 1000000.0f / (float)-diff; - } + tvadd(tv_expect, pl_frame_interval); + diff = tvdiff(tv_expect, now); + if (diff > MAX_LAG_FRAMES * pl_frame_interval || diff < -MAX_LAG_FRAMES * pl_frame_interval) { + //printf("pl_frame_limit reset, diff=%d, iv %d\n", diff, pl_frame_interval); + tv_expect = now; + diff = 0; + } + + if (!(g_opts & OPT_NO_FRAMELIM) && diff > pl_frame_interval) { + // yay for working usleep on pandora! + //printf("usleep %d\n", diff - pl_frame_interval / 2); + usleep(diff - pl_frame_interval / 2); + } + + plugin_skip_advice = 0; + if (UseFrameSkip && diff < -pl_frame_interval) { + // P.E.Op.S. makes skip decision based on this + fps_skip = 1.0f; + plugin_skip_advice = 1; } pcnt_start(PCNT_ALL); @@ -248,15 +252,13 @@ static void pl_get_layer_pos(int *x, int *y, int *w, int *h) *h = g_layer_h; } -extern int UseFrameSkip; // hmh - const struct rearmed_cbs pl_rearmed_cbs = { pl_get_layer_pos, pl_fbdev_open, pl_fbdev_set_mode, pl_fbdev_flip, pl_fbdev_close, - &UseFrameSkip, + &plugin_skip_advice, }; /* watchdog */ -- 2.39.2 From 799b0b8773d6add1de99efd582c93701b82e970d Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 6 Feb 2011 01:27:48 +0200 Subject: [PATCH 05/16] frontend: support analog controller using nubs; some refactoring also enable frameskip by default, it makes the experience a bit better on most games. --- Makefile | 2 + frontend/main.c | 2 + frontend/menu.c | 21 ++++-- frontend/pandora.c | 153 ++++++++++++++++++++++++++++++++++++++++++ frontend/pandora.h | 1 + frontend/plat_dummy.c | 4 ++ frontend/plat_omap.c | 43 +----------- frontend/plugin.c | 12 +++- frontend/plugin_lib.c | 14 +++- frontend/plugin_lib.h | 3 +- pandora/pcsx.sh | 9 +++ pandora/readme.txt | 3 + 12 files changed, 213 insertions(+), 54 deletions(-) create mode 100644 frontend/pandora.c create mode 100644 frontend/pandora.h diff --git a/Makefile b/Makefile index 2ccd0e2a..db8e1f60 100644 --- a/Makefile +++ b/Makefile @@ -77,6 +77,7 @@ OBJS += frontend/main.o frontend/plugin.o ifeq "$(USE_GTK)" "1" OBJS += maemo/hildon.o maemo/main.o maemo/%.o: maemo/%.c +maemo/%.o: CFLAGS += -Wall else OBJS += frontend/plugin_lib.o frontend/menu.o OBJS += frontend/linux/fbdev.o frontend/linux/in_evdev.o @@ -84,6 +85,7 @@ OBJS += frontend/linux/plat.o frontend/linux/oshide.o OBJS += frontend/common/fonts.o frontend/common/input.o frontend/common/readpng.o ifeq "$(ARCH)" "arm" OBJS += frontend/plat_omap.o +OBJS += frontend/pandora.o else OBJS += frontend/plat_dummy.o endif diff --git a/frontend/main.c b/frontend/main.c index 550242a9..3344819c 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -20,6 +20,7 @@ #include "pcnt.h" #include "menu.h" #include "../libpcsxcore/misc.h" +#include "../libpcsxcore/new_dynarec/new_dynarec.h" #include "../plugins/cdrcimg/cdrcimg.h" #include "common/plat.h" #include "common/input.h" @@ -253,6 +254,7 @@ int main(int argc, char *argv[]) while (1) { + stop = 0; psxCpu->Execute(); menu_loop(); } diff --git a/frontend/menu.c b/frontend/menu.c index 754b6d23..0a4c271e 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -22,7 +22,7 @@ #include "omap.h" #include "common/plat.h" #include "../libpcsxcore/misc.h" -#include "../libpcsxcore/new_dynarec/new_dynarec.h" +#include "../libpcsxcore/psemu_plugin_defs.h" #include "revision.h" #define MENU_X2 1 @@ -63,7 +63,7 @@ static int last_psx_w, last_psx_h, last_psx_bpp; static int scaling, filter, state_slot, cpu_clock, cpu_clock_st; static char rom_fname_reload[MAXPATHLEN]; static char last_selected_fname[MAXPATHLEN]; -static int region; +static int region, in_type_sel; int g_opts; // from softgpu plugin @@ -147,8 +147,9 @@ static void menu_sync_config(void) Config.PsxAuto = 0; Config.PsxType = region - 1; } - pl_frame_interval = Config.PsxType ? 20000 : 16667; + in_type = in_type_sel ? PSE_PAD_TYPE_ANALOGPAD : PSE_PAD_TYPE_STANDARD; + pl_frame_interval = Config.PsxType ? 20000 : 16667; // used by P.E.Op.S. frameskip code fFrameRateHz = Config.PsxType ? 50.0f : 59.94f; dwFrameRateTicks = (100000*100 / (unsigned long)(fFrameRateHz*100)); @@ -160,10 +161,12 @@ static void menu_set_defconfig(void) scaling = SCALE_4_3; region = 0; + in_type_sel = 0; Config.Xa = Config.Cdda = Config.Sio = Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0; - iUseDither = UseFrameSkip = 0; + iUseDither = 0; + UseFrameSkip = 1; dwActFixes = 1<<7; iUseReverb = 2; @@ -215,6 +218,7 @@ static const struct { CE_INTVAL(state_slot), CE_INTVAL(cpu_clock), CE_INTVAL(g_opts), + CE_INTVAL(in_type_sel), CE_INTVAL(iUseDither), CE_INTVAL(UseFrameSkip), CE_INTVAL(dwActFixes), @@ -711,13 +715,17 @@ static int mh_savecfg(int id, int keys) return 1; } +static const char *men_in_type_sel[] = { "Standard (SCPH-1080)", "Analog (SCPH-1150)", NULL }; + static menu_entry e_menu_keyconfig[] = { mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap), mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap), mee_handler_id("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap), -// mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg), -// mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg), + mee_label (""), + mee_enum ("Controller", 0, in_type_sel, men_in_type_sel), + mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg), + mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg), mee_label (""), mee_label ("Input devices:"), mee_label_mk (MA_CTRL_DEV_FIRST, mgn_dev_name), @@ -1434,7 +1442,6 @@ void menu_prepare_emu(void) } apply_filter(filter); apply_cpu_clock(); - stop = 0; psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec; if (psxCpu != prev_cpu) diff --git a/frontend/pandora.c b/frontend/pandora.c new file mode 100644 index 00000000..8eacabb6 --- /dev/null +++ b/frontend/pandora.c @@ -0,0 +1,153 @@ +/* + * (C) notaz, 2011 + * + * This work is licensed under the terms of the GNU GPLv2 or later. + * See the COPYING file in the top-level directory. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/input.h" +#include "plugin_lib.h" + +static int fdnub[2]; +static int analog_init_done; + +static const char * const pandora_gpio_keys[KEY_MAX + 1] = { + [0 ... KEY_MAX] = NULL, + [KEY_UP] = "Up", + [KEY_LEFT] = "Left", + [KEY_RIGHT] = "Right", + [KEY_DOWN] = "Down", + [KEY_HOME] = "A", + [KEY_PAGEDOWN] = "X", + [KEY_END] = "B", + [KEY_PAGEUP] = "Y", + [KEY_RIGHTSHIFT]= "L", + [KEY_RIGHTCTRL] = "R", + [KEY_LEFTALT] = "Start", + [KEY_LEFTCTRL] = "Select", + [KEY_MENU] = "Pandora", +}; + +struct in_default_bind in_evdev_defbinds[] = { + { KEY_UP, IN_BINDTYPE_PLAYER12, DKEY_UP }, + { KEY_DOWN, IN_BINDTYPE_PLAYER12, DKEY_DOWN }, + { KEY_LEFT, IN_BINDTYPE_PLAYER12, DKEY_LEFT }, + { KEY_RIGHT, IN_BINDTYPE_PLAYER12, DKEY_RIGHT }, + { KEY_SPACE, IN_BINDTYPE_EMU, PEVB_MENU }, + { KEY_PAGEUP, IN_BINDTYPE_PLAYER12, DKEY_TRIANGLE }, + { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, DKEY_CROSS }, + { KEY_END, IN_BINDTYPE_PLAYER12, DKEY_CIRCLE }, + { KEY_HOME, IN_BINDTYPE_PLAYER12, DKEY_SQUARE }, + { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, DKEY_START }, + { KEY_LEFTCTRL, IN_BINDTYPE_PLAYER12, DKEY_SELECT }, + { KEY_RIGHTSHIFT,IN_BINDTYPE_PLAYER12, DKEY_L1 }, + { KEY_RIGHTCTRL, IN_BINDTYPE_PLAYER12, DKEY_R1 }, + { KEY_Q, IN_BINDTYPE_PLAYER12, DKEY_L2 }, + { KEY_P, IN_BINDTYPE_PLAYER12, DKEY_R2 }, + { 0, 0, 0 } +}; + +static void analog_init(void) +{ + int i, nub; + + fdnub[0] = fdnub[1] = -1; + + for (i = nub = 0; nub < 2; i++) + { + long absbits[(ABS_MAX+1) / sizeof(long) / 8]; + int ret, fd, support = 0; + char name[64]; + + snprintf(name, sizeof(name), "/dev/input/event%d", i); + fd = open(name, O_RDONLY|O_NONBLOCK); + if (fd == -1) { + if (errno == EACCES) + continue; /* maybe we can access next one */ + break; + } + + /* check supported events */ + ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support); + if (ret == -1) { + printf("pandora: ioctl failed on %s\n", name); + goto skip; + } + + if (!(support & (1 << EV_ABS))) + goto skip; + + ret = ioctl(fd, EVIOCGNAME(sizeof(name)), name); + if (ret == -1 || strncmp(name, "nub", 3) != 0) + goto skip; + + ret = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbits)), absbits); + if (ret == -1) + goto skip; + if ((absbits[0] & ((1 << ABS_X)|(1 << ABS_Y))) != ((1 << ABS_X)|(1 << ABS_Y))) + goto skip; + + printf("pandora: found analog #%d \"%s\"\n", nub, name); + fdnub[nub++] = fd; + continue; + +skip: + close(fd); + } + + if (nub != 2) + printf("pandora: warning: not all nubs found: %d\n", nub); + + analog_init_done = 1; +} + +void in_update_analogs(void) +{ + int *nubp[2] = { in_a1, in_a2 }; + struct input_absinfo ainfo; + int i, fd, v, ret; + + if (!analog_init_done) + analog_init(); + + for (i = 0; i < 2; i++) { + fd = fdnub[i]; + if (fd < 0) + continue; + + ret = ioctl(fd, EVIOCGABS(ABS_X), &ainfo); + if (ret == -1) { + perror("ioctl"); + continue; + } + v = ainfo.value / 2 + 127; + nubp[i][0] = v < 0 ? 0 : v; + + ret = ioctl(fd, EVIOCGABS(ABS_Y), &ainfo); + if (ret == -1) { + perror("ioctl"); + continue; + } + v = ainfo.value / 2 + 127; + nubp[i][1] = v < 0 ? 0 : v; + } + //printf("%4d %4d %4d %4d\n", in_a1[0], in_a1[1], in_a2[0], in_a2[1]); +} + +int pandora_init(void) +{ + in_set_config(in_name_to_id("evdev:gpio-keys"), IN_CFG_KEY_NAMES, + pandora_gpio_keys, sizeof(pandora_gpio_keys)); + + return 0; +} diff --git a/frontend/pandora.h b/frontend/pandora.h new file mode 100644 index 00000000..9bab84fc --- /dev/null +++ b/frontend/pandora.h @@ -0,0 +1 @@ +int pandora_init(void); diff --git a/frontend/plat_dummy.c b/frontend/plat_dummy.c index 44d9068a..6cbe7f8e 100644 --- a/frontend/plat_dummy.c +++ b/frontend/plat_dummy.c @@ -50,3 +50,7 @@ void bgr555_to_rgb565(void *d, void *s, int len) void bgr888_to_rgb888(void *d, void *s, int len) { } + +void in_update_analogs(void) +{ +} diff --git a/frontend/plat_omap.c b/frontend/plat_omap.c index e6a1105d..b479a66b 100644 --- a/frontend/plat_omap.c +++ b/frontend/plat_omap.c @@ -10,16 +10,16 @@ #include #include #include +#include #include -#include #include -#include "common/input.h" #include "common/menu.h" #include "linux/fbdev.h" #include "linux/oshide.h" #include "plugin_lib.h" #include "omap.h" +#include "pandora.h" static struct vout_fbdev *main_fb; @@ -28,42 +28,6 @@ int g_layer_w = 640, g_layer_h = 480; struct vout_fbdev *layer_fb; -static const char * const pandora_gpio_keys[KEY_MAX + 1] = { - [0 ... KEY_MAX] = NULL, - [KEY_UP] = "Up", - [KEY_LEFT] = "Left", - [KEY_RIGHT] = "Right", - [KEY_DOWN] = "Down", - [KEY_HOME] = "A", - [KEY_PAGEDOWN] = "X", - [KEY_END] = "B", - [KEY_PAGEUP] = "Y", - [KEY_RIGHTSHIFT]= "L", - [KEY_RIGHTCTRL] = "R", - [KEY_LEFTALT] = "Start", - [KEY_LEFTCTRL] = "Select", - [KEY_MENU] = "Pandora", -}; - -struct in_default_bind in_evdev_defbinds[] = { - { KEY_UP, IN_BINDTYPE_PLAYER12, DKEY_UP }, - { KEY_DOWN, IN_BINDTYPE_PLAYER12, DKEY_DOWN }, - { KEY_LEFT, IN_BINDTYPE_PLAYER12, DKEY_LEFT }, - { KEY_RIGHT, IN_BINDTYPE_PLAYER12, DKEY_RIGHT }, - { KEY_SPACE, IN_BINDTYPE_EMU, PEVB_MENU }, - { KEY_PAGEUP, IN_BINDTYPE_PLAYER12, DKEY_TRIANGLE }, - { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, DKEY_CROSS }, - { KEY_END, IN_BINDTYPE_PLAYER12, DKEY_CIRCLE }, - { KEY_HOME, IN_BINDTYPE_PLAYER12, DKEY_SQUARE }, - { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, DKEY_START }, - { KEY_LEFTCTRL, IN_BINDTYPE_PLAYER12, DKEY_SELECT }, - { KEY_RIGHTSHIFT,IN_BINDTYPE_PLAYER12, DKEY_L1 }, - { KEY_RIGHTCTRL, IN_BINDTYPE_PLAYER12, DKEY_R1 }, - { KEY_Q, IN_BINDTYPE_PLAYER12, DKEY_L2 }, - { KEY_P, IN_BINDTYPE_PLAYER12, DKEY_R2 }, - { 0, 0, 0 } -}; - static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h, int first_call) { struct omapfb_plane_info pi; @@ -205,8 +169,7 @@ void plat_init(void) } g_menubg_ptr = temp_frame; - in_set_config(in_name_to_id("evdev:gpio-keys"), IN_CFG_KEY_NAMES, - pandora_gpio_keys, sizeof(pandora_gpio_keys)); + pandora_init(); return; fail1: diff --git a/frontend/plugin.c b/frontend/plugin.c index c11a1f05..33efbf0b 100644 --- a/frontend/plugin.c +++ b/frontend/plugin.c @@ -43,15 +43,21 @@ extern void SPUplayCDDAchannel(short *, int); /* PAD */ static long PADreadPort1(PadDataS *pad) { - pad->controllerType = PSE_PAD_TYPE_STANDARD; - pad->buttonStatus = ~keystate; + pad->controllerType = in_type; + pad->buttonStatus = ~in_keystate; + if (in_type == PSE_PAD_TYPE_ANALOGPAD) { + pad->leftJoyX = in_a1[0]; + pad->leftJoyY = in_a1[1]; + pad->rightJoyX = in_a2[0]; + pad->rightJoyY = in_a2[1]; + } return 0; } static long PADreadPort2(PadDataS *pad) { pad->controllerType = PSE_PAD_TYPE_STANDARD; - pad->buttonStatus = ~keystate >> 16; + pad->buttonStatus = ~in_keystate >> 16; return 0; } diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 17ed79a9..a2fb4951 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -24,10 +25,11 @@ #include "menu.h" #include "pcnt.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" +#include "../libpcsxcore/psemu_plugin_defs.h" void *pl_fbdev_buf; int pl_frame_interval; -int keystate; +int in_type, in_keystate, in_a1[2], in_a2[2]; static int pl_fbdev_w, pl_fbdev_h, pl_fbdev_bpp; static int flip_cnt, vsync_cnt, flips_per_sec, tick_per_sec; static float vsps_cur; @@ -124,13 +126,15 @@ static void update_input(void) int actions[IN_BINDTYPE_COUNT] = { 0, }; in_update(actions); + if (in_type == PSE_PAD_TYPE_ANALOGPAD) + in_update_analogs(); if (actions[IN_BINDTYPE_EMU] & PEV_MENU) stop = 1; - keystate = actions[IN_BINDTYPE_PLAYER12]; + in_keystate = actions[IN_BINDTYPE_PLAYER12]; #ifdef X11 extern int x11_update_keys(void); - keystate |= x11_update_keys(); + in_keystate |= x11_update_keys(); #endif } @@ -268,6 +272,10 @@ static void *watchdog_thread(void *unused) int seen_dead = 0; int sleep_time = 5; +#ifndef NDEBUG + // don't interfere with debug + return NULL; +#endif while (1) { sleep(sleep_time); diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h index 6b01cea3..53a597f2 100644 --- a/frontend/plugin_lib.h +++ b/frontend/plugin_lib.h @@ -1,5 +1,4 @@ -extern int keystate; enum { DKEY_SELECT = 0, DKEY_L3, @@ -18,6 +17,8 @@ enum { DKEY_CROSS, DKEY_SQUARE, }; +extern int in_type, in_keystate, in_a1[2], in_a2[2]; +void in_update_analogs(void); extern void *pl_fbdev_buf; diff --git a/pandora/pcsx.sh b/pandora/pcsx.sh index a4017141..2062e782 100755 --- a/pandora/pcsx.sh +++ b/pandora/pcsx.sh @@ -1,6 +1,15 @@ #!/bin/sh +# stupid nub mode thing +nub0mode=`cat /proc/pandora/nub0/mode` +nub1mode=`cat /proc/pandora/nub1/mode` +echo absolute > /proc/pandora/nub0/mode +echo absolute > /proc/pandora/nub1/mode + ./pcsx "$@" # restore stuff if pcsx crashes ./picorestore + +echo "$nub0mode" > /proc/pandora/nub0/mode +echo "$nub1mode" > /proc/pandora/nub1/mode diff --git a/pandora/readme.txt b/pandora/readme.txt index 8939ece1..c0a59d2e 100644 --- a/pandora/readme.txt +++ b/pandora/readme.txt @@ -40,6 +40,9 @@ to work. To use real BIOS, copy uncompressed BIOS files to [sd card]/pandora/appdata/pcsx_rearmed/bios/ then select the BIOS you want to use in Options->BIOS/Plugins menu. +Analog controllers are supported using nubs, but this is disabled by +default and needs to be enabled in 'Controls' menu. + Plugins ------- -- 2.39.2 From 54b4a001cf0b0f165a59b727c4b201226eda014c Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 6 Feb 2011 02:22:05 +0200 Subject: [PATCH 06/16] maemo: update for recent changes, fix warnings --- Makefile.maemo | 4 ++-- maemo/hildon.c | 17 +++++++++++------ maemo/main.c | 28 +++++++++++++++++----------- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Makefile.maemo b/Makefile.maemo index 06f21dc7..2bed0792 100644 --- a/Makefile.maemo +++ b/Makefile.maemo @@ -8,8 +8,8 @@ EXTRA_CFLAGS += -march=armv7-a -O3 -mfpu=neon -funsafe-math-optimizations \ -mstructure-size-boundary=32 -falign-functions=32 -falign-loops \ -DMAEMO -DMAEMO_CHANGES $(shell pkg-config --cflags hildon-1) -#EXTRA_CFLAGS += -Imaemo/gtk-2.0 -Imaemo/hildon -Imaemo/glib-2.0 -Imaemo/cairo \ - -Imaemo/pango-1.0 -Imaemo/atk-1.0 -DMAEMO -DMAEMO_CHANGES +#EXTRA_CFLAGS += -Imaemo/i/gtk-2.0 -Imaemo/i/hildon -Imaemo/i/glib-2.0 -Imaemo/i/cairo \ + -Imaemo/i/pango-1.0 -Imaemo/i/atk-1.0 -DMAEMO -DMAEMO_CHANGES include Makefile diff --git a/maemo/hildon.c b/maemo/hildon.c index 2cea99a3..df42a90a 100644 --- a/maemo/hildon.c +++ b/maemo/hildon.c @@ -1,9 +1,11 @@ #include #include #include +#include #include #include #include "plugin_lib.h" +#include "../libpcsxcore/psemu_plugin_defs.h" #define X_RES 800 #define Y_RES 480 @@ -15,7 +17,8 @@ static HildonAnimationActor *actor; static GtkWidget *window, *drawing; void *pl_fbdev_buf; -int keystate; +int in_type = PSE_PAD_TYPE_STANDARD; +int in_keystate, in_a1[2], in_a2[2]; static int keymap[65536]; @@ -86,15 +89,15 @@ window_key_proxy(GtkWidget *widget, if (event->type == GDK_KEY_PRESS) { if (psxkey1 >= 0) - keystate |= 1 << psxkey1; + in_keystate |= 1 << psxkey1; if (psxkey2 >= 0) - keystate |= 1 << psxkey2; + in_keystate |= 1 << psxkey2; } else if (event->type == GDK_KEY_RELEASE) { if (psxkey1 >= 0) - keystate &= ~(1 << psxkey1); + in_keystate &= ~(1 << psxkey1); if (psxkey2 >= 0) - keystate &= ~(1 << psxkey2); + in_keystate &= ~(1 << psxkey2); } } @@ -148,7 +151,7 @@ void maemo_init(int *argc, char ***argv) void *pl_fbdev_set_mode(int w, int h, int bpp) { if (w <= 0 || h <= 0) - return; + return pl_fbdev_buf; if (image) gdk_image_destroy(image); image = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(), w, h ); @@ -169,6 +172,7 @@ void *pl_fbdev_set_mode(int w, int h, int bpp) void *pl_fbdev_flip(void) { gtk_widget_queue_draw (drawing); + return pl_fbdev_buf; } void pl_frame_limit(void) @@ -187,6 +191,7 @@ void pl_fbdev_close(void) int pl_fbdev_open(void) { + return 0; } static void pl_get_layer_pos(int *x, int *y, int *w, int *h) diff --git a/maemo/main.c b/maemo/main.c index 267fb55f..80919ace 100644 --- a/maemo/main.c +++ b/maemo/main.c @@ -7,17 +7,13 @@ #include #include -#include -#include -#include -#include +#include #include -#include #include "main.h" #include "plugin.h" #include "../libpcsxcore/misc.h" -#include "../plugins/cdrcimg/cdrcimg.h" +#include "../libpcsxcore/new_dynarec/new_dynarec.h" // from softgpu plugin extern int iUseDither; @@ -34,11 +30,14 @@ extern int iXAPitch; extern int iSPUIRQWait; extern int iUseTimer; +enum sched_action emu_action; +void do_emu_action(void); + static void ChangeWorkingDirectory(char *exe) { - s8 exepath[1024]; - s8* s; - sprintf(exepath, "%s", exe); + char exepath[1024]; + char *s; + snprintf(exepath, sizeof(exepath), "%s", exe); s = strrchr(exepath, '/'); if (s != NULL) { *s = '\0'; @@ -53,7 +52,6 @@ int maemo_main(int argc, char **argv) char path[MAXPATHLEN]; const char *cdfile = NULL; int loadst = 0; - void *tmp; int i; strcpy(Config.BiosDir, "/home/user/MyDocs"); @@ -190,7 +188,15 @@ int maemo_main(int argc, char **argv) return 0; } - psxCpu->Execute(); + while (1) + { + stop = 0; + emu_action = SACTION_NONE; + + psxCpu->Execute(); + if (emu_action != SACTION_NONE) + do_emu_action(); + } return 0; } -- 2.39.2 From 43bca6fbee5f6b26ee02e8850bf7dace8d63336b Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 7 Feb 2011 00:49:40 +0200 Subject: [PATCH 07/16] frontend: key config: save it and make more intuitive --- frontend/common/input.c | 33 ++++++-- frontend/common/menu.c | 78 +++++++++-------- frontend/menu.c | 180 ++++++++++++++++++++++++++++++++++++++++ frontend/pandora.c | 12 +-- 4 files changed, 256 insertions(+), 47 deletions(-) diff --git a/frontend/common/input.c b/frontend/common/input.c index 7bbb39c1..52505355 100644 --- a/frontend/common/input.c +++ b/frontend/common/input.c @@ -677,22 +677,39 @@ int in_bind_key(int dev_id, int keycode, int mask, int bind_type, int force_unbi return 0; } -void in_unbind_all(int dev_id, int act_mask, int bind_type) +/* + * Unbind act_mask on binds with type bind_type + * - if dev_id_ < 0, affects all devices + * else only affects dev_id_ + * - if act_mask == -1, unbind all keys + * else only actions in mask + */ +void in_unbind_all(int dev_id_, int act_mask, int bind_type) { + int dev_id = 0, dev_last = IN_MAX_DEVS - 1; int i, count; in_dev_t *dev; - if (dev_id < 0 || dev_id >= IN_MAX_DEVS || bind_type >= IN_BINDTYPE_COUNT) + if (dev_id_ >= 0) + dev_id = dev_last = dev_id_; + + if (bind_type >= IN_BINDTYPE_COUNT) return; - dev = &in_devices[dev_id]; - count = dev->key_count; + for (; dev_id <= dev_last; dev_id++) { + dev = &in_devices[dev_id]; + count = dev->key_count; - if (dev->binds == NULL) - return; + if (dev->binds == NULL) + continue; - for (i = 0; i < count; i++) - dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask; + if (act_mask != -1) { + for (i = 0; i < count; i++) + dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask; + } + else + memset(dev->binds, 0, sizeof(dev->binds[0]) * count * IN_BINDTYPE_COUNT); + } } /* returns device id, or -1 on error */ diff --git a/frontend/common/menu.c b/frontend/common/menu.c index aa76e431..31522f7e 100644 --- a/frontend/common/menu.c +++ b/frontend/common/menu.c @@ -1039,18 +1039,11 @@ static int menu_loop_savestate(int is_loading) static char *action_binds(int player_idx, int action_mask, int dev_id) { - int k, count = 0, can_combo = 0, type; - const int *binds; + int dev = 0, dev_last = IN_MAX_DEVS - 1; + int can_combo = 1, type; static_buff[0] = 0; - binds = in_get_dev_binds(dev_id); - if (binds == NULL) - return static_buff; - - in_get_config(dev_id, IN_CFG_BIND_COUNT, &count); - in_get_config(dev_id, IN_CFG_DOES_COMBOS, &can_combo); - type = IN_BINDTYPE_EMU; if (player_idx >= 0) { can_combo = 0; @@ -1059,22 +1052,37 @@ static char *action_binds(int player_idx, int action_mask, int dev_id) if (player_idx == 1) action_mask <<= 16; - for (k = 0; k < count; k++) - { - const char *xname; - int len; + if (dev_id >= 0) + dev = dev_last = dev_id; + + for (; dev <= dev_last; dev++) { + int k, count = 0, combo = 0; + const int *binds; - if (!(binds[IN_BIND_OFFS(k, type)] & action_mask)) + binds = in_get_dev_binds(dev); + if (binds == NULL) continue; - xname = in_get_key_name(dev_id, k); - len = strlen(static_buff); - if (len) { - strncat(static_buff, can_combo ? " + " : ", ", - sizeof(static_buff) - len - 1); - len += can_combo ? 3 : 2; + in_get_config(dev, IN_CFG_BIND_COUNT, &count); + in_get_config(dev, IN_CFG_DOES_COMBOS, &combo); + combo = combo && can_combo; + + for (k = 0; k < count; k++) { + const char *xname; + int len; + + if (!(binds[IN_BIND_OFFS(k, type)] & action_mask)) + continue; + + xname = in_get_key_name(dev, k); + len = strlen(static_buff); + if (len) { + strncat(static_buff, combo ? " + " : ", ", + sizeof(static_buff) - len - 1); + len += combo ? 3 : 2; + } + strncat(static_buff, xname, sizeof(static_buff) - len - 1); } - strncat(static_buff, xname, sizeof(static_buff) - len - 1); } return static_buff; @@ -1126,7 +1134,10 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ text_out16(x, y, "%s : %s", opts[i].name, action_binds(player_idx, opts[i].mask, dev_id)); - dev_name = in_get_dev_name(dev_id, 1, 1); + if (dev_id < 0) + dev_name = "(all devices)"; + else + dev_name = in_get_dev_name(dev_id, 1, 1); w = strlen(dev_name) * me_mfont_w; if (w < 30 * me_mfont_w) w = 30 * me_mfont_w; @@ -1155,7 +1166,7 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_idx) { int i, sel = 0, menu_sel_max = opt_cnt - 1, does_combos = 0; - int dev_id, dev_count, kc, is_down, mkey; + int dev_id, bind_dev_id, dev_count, kc, is_down, mkey; int unbind, bindtype, mask_shift; for (i = 0, dev_id = -1, dev_count = 0; i < IN_MAX_DEVS; i++) { @@ -1171,6 +1182,7 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ return; } + dev_id = -1; // show all mask_shift = 0; if (player_idx == 1) mask_shift = 16; @@ -1184,18 +1196,18 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ case PBTN_UP: sel--; if (sel < 0) sel = menu_sel_max; continue; case PBTN_DOWN: sel++; if (sel > menu_sel_max) sel = 0; continue; case PBTN_LEFT: - for (i = 0, dev_id--; i < IN_MAX_DEVS; i++, dev_id--) { - if (dev_id < 0) + for (i = 0, dev_id--; i < IN_MAX_DEVS + 1; i++, dev_id--) { + if (dev_id < -1) dev_id = IN_MAX_DEVS - 1; - if (in_get_dev_name(dev_id, 1, 0) != NULL) + if (dev_id == -1 || in_get_dev_name(dev_id, 1, 0) != NULL) break; } continue; case PBTN_RIGHT: for (i = 0, dev_id++; i < IN_MAX_DEVS; i++, dev_id++) { if (dev_id >= IN_MAX_DEVS) - dev_id = 0; - if (in_get_dev_name(dev_id, 1, 0) != NULL) + dev_id = -1; + if (dev_id == -1 || in_get_dev_name(dev_id, 1, 0) != NULL) break; } continue; @@ -1217,20 +1229,20 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_ /* wait for some up event */ for (is_down = 1; is_down; ) - kc = in_update_keycode(&dev_id, &is_down, -1); + kc = in_update_keycode(&bind_dev_id, &is_down, -1); - i = count_bound_keys(dev_id, opts[sel].mask << mask_shift, bindtype); + i = count_bound_keys(bind_dev_id, opts[sel].mask << mask_shift, bindtype); unbind = (i > 0); /* allow combos if device supports them */ - in_get_config(dev_id, IN_CFG_DOES_COMBOS, &does_combos); + in_get_config(bind_dev_id, IN_CFG_DOES_COMBOS, &does_combos); if (i == 1 && bindtype == IN_BINDTYPE_EMU && does_combos) unbind = 0; if (unbind) - in_unbind_all(dev_id, opts[sel].mask << mask_shift, bindtype); + in_unbind_all(bind_dev_id, opts[sel].mask << mask_shift, bindtype); - in_bind_key(dev_id, kc, opts[sel].mask << mask_shift, bindtype, 0); + in_bind_key(bind_dev_id, kc, opts[sel].mask << mask_shift, bindtype, 0); } } diff --git a/frontend/menu.c b/frontend/menu.c index 0a4c271e..e7d20ffe 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -251,6 +251,8 @@ static void make_cfg_fname(char *buf, size_t size, int is_game) snprintf(buf, size, "." PCSX_DOT_DIR "%s", cfgfile_basename); } +static void keys_write_all(FILE *f); + static int menu_write_config(int is_game) { char cfgfile[MAXPATHLEN]; @@ -289,7 +291,9 @@ static int menu_write_config(int is_game) if (!is_game) fprintf(f, "lastcdimg = %s\n", last_selected_fname); + keys_write_all(f); fclose(f); + return 0; } @@ -305,6 +309,8 @@ static void parse_str_val(char *cval, const char *src) *tmp = 0; } +static void keys_load_all(const char *cfg); + static int menu_load_config(int is_game) { char cfgfile[MAXPATHLEN]; @@ -400,6 +406,7 @@ static int menu_load_config(int is_game) if (strcmp(Config.Spu, spu_plugins[i]) == 0) { spu_plugsel = i; break; } + keys_load_all(cfg); ret = 0; fail_read: free(cfg); @@ -647,6 +654,8 @@ me_bind_action me_ctrl_actions[] = { "R1 ", 1 << DKEY_R1 }, { "L2 ", 1 << DKEY_L2 }, { "R2 ", 1 << DKEY_R2 }, + { "L3 ", 1 << DKEY_L3 }, + { "R3 ", 1 << DKEY_R3 }, { "START ", 1 << DKEY_START }, { "SELECT ", 1 << DKEY_SELECT }, { NULL, 0 } @@ -664,6 +673,177 @@ me_bind_action emuctrl_actions[] = { NULL, 0 } }; +static char *mystrip(char *str) +{ + int i, len; + + len = strlen(str); + for (i = 0; i < len; i++) + if (str[i] != ' ') break; + if (i > 0) memmove(str, str + i, len - i + 1); + + len = strlen(str); + for (i = len - 1; i >= 0; i--) + if (str[i] != ' ') break; + str[i+1] = 0; + + return str; +} + +static void get_line(char *d, size_t size, const char *s) +{ + const char *pe; + size_t len; + + for (pe = s; *pe != '\r' && *pe != '\n' && *pe != 0; pe++) + ; + len = pe - s; + if (len > size - 1) + len = size - 1; + strncpy(d, s, len); + d[len] = 0; + + mystrip(d); +} + +static void keys_write_all(FILE *f) +{ + int d; + + for (d = 0; d < IN_MAX_DEVS; d++) + { + const int *binds = in_get_dev_binds(d); + const char *name = in_get_dev_name(d, 0, 0); + int k, count = 0; + + if (binds == NULL || name == NULL) + continue; + + fprintf(f, "binddev = %s\n", name); + in_get_config(d, IN_CFG_BIND_COUNT, &count); + + for (k = 0; k < count; k++) + { + int i, kbinds, mask; + char act[32]; + + act[0] = act[31] = 0; + name = in_get_key_name(d, k); + + kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)]; + for (i = 0; kbinds && i < ARRAY_SIZE(me_ctrl_actions) - 1; i++) { + mask = me_ctrl_actions[i].mask; + if (mask & kbinds) { + strncpy(act, me_ctrl_actions[i].name, 31); + fprintf(f, "bind %s = player1 %s\n", name, mystrip(act)); + kbinds &= ~mask; + } + mask = me_ctrl_actions[i].mask << 16; + if (mask & kbinds) { + strncpy(act, me_ctrl_actions[i].name, 31); + fprintf(f, "bind %s = player2 %s\n", name, mystrip(act)); + kbinds &= ~mask; + } + } + + kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)]; + for (i = 0; kbinds && i < ARRAY_SIZE(emuctrl_actions) - 1; i++) { + mask = emuctrl_actions[i].mask; + if (mask & kbinds) { + strncpy(act, emuctrl_actions[i].name, 31); + fprintf(f, "bind %s = %s\n", name, mystrip(act)); + kbinds &= ~mask; + } + } + } + } +} + +static int parse_bind_val(const char *val, int *type) +{ + int i; + + *type = IN_BINDTYPE_NONE; + if (val[0] == 0) + return 0; + + if (strncasecmp(val, "player", 6) == 0) + { + int player, shift = 0; + player = atoi(val + 6) - 1; + + if ((unsigned int)player > 1) + return -1; + if (player == 1) + shift = 16; + + *type = IN_BINDTYPE_PLAYER12; + for (i = 0; me_ctrl_actions[i].name != NULL; i++) { + if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0) + return me_ctrl_actions[i].mask << shift; + } + } + for (i = 0; emuctrl_actions[i].name != NULL; i++) { + if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) { + *type = IN_BINDTYPE_EMU; + return emuctrl_actions[i].mask; + } + } + + return -1; +} + +static void keys_load_all(const char *cfg) +{ + char dev[256], key[128], *act; + const char *p; + int bind, bindtype; + int dev_id; + + p = cfg; + while (p != NULL && (p = strstr(p, "binddev = ")) != NULL) { + p += 10; + + get_line(dev, sizeof(dev), p); + dev_id = in_config_parse_dev(dev); + if (dev_id < 0) { + printf("input: can't handle dev: %s\n", dev); + continue; + } + + in_unbind_all(dev_id, -1, -1); + while ((p = strstr(p, "bind"))) { + if (strncmp(p, "binddev = ", 10) == 0) + break; + + p += 4; + if (*p != ' ') { + printf("input: parse error: %16s..\n", p); + continue; + } + + get_line(key, sizeof(key), p); + act = strchr(key, '='); + if (act == NULL) { + printf("parse failed: %16s..\n", p); + continue; + } + *act = 0; + act++; + mystrip(key); + mystrip(act); + + bind = parse_bind_val(act, &bindtype); + if (bind != -1 && bind != 0) { + printf("bind #%d '%s' %08x (%s)\n", dev_id, key, bind, act); + in_config_bind_key(dev_id, key, bind, bindtype); + } + else + lprintf("config: unhandled action \"%s\"\n", act); + } + } +} + static int key_config_loop_wrap(int id, int keys) { switch (id) { diff --git a/frontend/pandora.c b/frontend/pandora.c index 8eacabb6..cd50728e 100644 --- a/frontend/pandora.c +++ b/frontend/pandora.c @@ -27,12 +27,12 @@ static const char * const pandora_gpio_keys[KEY_MAX + 1] = { [KEY_LEFT] = "Left", [KEY_RIGHT] = "Right", [KEY_DOWN] = "Down", - [KEY_HOME] = "A", - [KEY_PAGEDOWN] = "X", - [KEY_END] = "B", - [KEY_PAGEUP] = "Y", - [KEY_RIGHTSHIFT]= "L", - [KEY_RIGHTCTRL] = "R", + [KEY_HOME] = "(A)", + [KEY_PAGEDOWN] = "(X)", + [KEY_END] = "(B)", + [KEY_PAGEUP] = "(Y)", + [KEY_RIGHTSHIFT]= "(L)", + [KEY_RIGHTCTRL] = "(R)", [KEY_LEFTALT] = "Start", [KEY_LEFTCTRL] = "Select", [KEY_MENU] = "Pandora", -- 2.39.2 From 8f8926485e641efb187ff9ae11cef9d23d1e8982 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 8 Feb 2011 01:21:46 +0200 Subject: [PATCH 08/16] frontend: support ingame actions (state load and such) --- frontend/main.c | 100 +++++++++++++++++++++++++++++++++++++++--- frontend/main.h | 30 +++++++++++++ frontend/menu.c | 39 ++++++---------- frontend/pandora.c | 8 +++- frontend/plugin_lib.c | 32 ++++++++++++-- maemo/hildon.c | 13 +++++- maemo/main.c | 7 +-- 7 files changed, 185 insertions(+), 44 deletions(-) diff --git a/frontend/main.c b/frontend/main.c index 3344819c..64a16d37 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -29,6 +29,13 @@ int ready_to_go; unsigned long gpuDisp; char cfgfile_basename[MAXPATHLEN]; static char *(*real_getenv)(const char *name); +int state_slot; +enum sched_action emu_action, emu_action_old; +char hud_msg[64]; +int hud_new_msg; + +// from softgpu plugin +extern int UseFrameSkip; static void make_path(char *buf, size_t size, const char *dir, const char *fname) { @@ -98,6 +105,51 @@ static void set_default_paths(void) snprintf(Config.PatchesDir, sizeof(Config.PatchesDir), "." PATCHES_DIR); } +void do_emu_action(void) +{ + int ret; + + emu_action_old = emu_action; + + switch (emu_action) { + case SACTION_NONE: + return; + case SACTION_ENTER_MENU: + menu_loop(); + return; + case SACTION_LOAD_STATE: + ret = emu_load_state(state_slot); + snprintf(hud_msg, sizeof(hud_msg), ret == 0 ? "LOADED" : "FAIL!"); + break; + case SACTION_SAVE_STATE: + ret = emu_save_state(state_slot); + snprintf(hud_msg, sizeof(hud_msg), ret == 0 ? "SAVED" : "FAIL!"); + break; + case SACTION_NEXT_SSLOT: + state_slot++; + if (state_slot > 9) + state_slot = 0; + goto do_state_slot; + case SACTION_PREV_SSLOT: + state_slot--; + if (state_slot < 0) + state_slot = 9; + goto do_state_slot; + case SACTION_TOGGLE_FSKIP: + UseFrameSkip ^= 1; + snprintf(hud_msg, sizeof(hud_msg), "FRAMESKIP %s", + UseFrameSkip ? "ON" : "OFF"); + break; + } + hud_new_msg = 3; + return; + +do_state_slot: + snprintf(hud_msg, sizeof(hud_msg), "STATE SLOT %d [%s]", state_slot, + emu_check_state(state_slot) == 0 ? "USED" : "FREE"); + hud_new_msg = 3; +} + int main(int argc, char *argv[]) { void *tmp; @@ -238,11 +290,8 @@ int main(int argc, char *argv[]) // If a state has been specified, then load that if (loadst) { - char state_filename[MAXPATHLEN]; - int ret = get_state_filename(state_filename, sizeof(state_filename), loadst - 1); - if (ret == 0) - ret = LoadState(state_filename); - printf("%s state %s\n", ret ? "failed to load" : "loaded", state_filename); + int ret = emu_load_state(loadst - 1); + printf("%s state %d\n", ret ? "failed to load" : "loaded", loadst); } if (ready_to_go) @@ -255,8 +304,11 @@ int main(int argc, char *argv[]) while (1) { stop = 0; + emu_action = SACTION_NONE; + psxCpu->Execute(); - menu_loop(); + if (emu_action != SACTION_NONE) + do_emu_action(); } return 0; @@ -345,6 +397,42 @@ int get_state_filename(char *buf, int size, int i) { return 0; } +int emu_check_state(int slot) +{ + char fname[MAXPATHLEN]; + int ret; + + ret = get_state_filename(fname, sizeof(fname), slot); + if (ret != 0) + return ret; + + return CheckState(fname); +} + +int emu_save_state(int slot) +{ + char fname[MAXPATHLEN]; + int ret; + + ret = get_state_filename(fname, sizeof(fname), slot); + if (ret != 0) + return ret; + + return SaveState(fname); +} + +int emu_load_state(int slot) +{ + char fname[MAXPATHLEN]; + int ret; + + ret = get_state_filename(fname, sizeof(fname), slot); + if (ret != 0) + return ret; + + return LoadState(fname); +} + void SysPrintf(const char *fmt, ...) { va_list list; char msg[512]; diff --git a/frontend/main.h b/frontend/main.h index 0ebb0fc2..b64bc4cd 100644 --- a/frontend/main.h +++ b/frontend/main.h @@ -34,10 +34,40 @@ extern char cfgfile_basename[MAXPATHLEN]; +extern int state_slot; int get_state_filename(char *buf, int size, int i); +int emu_check_state(int slot); +int emu_save_state(int slot); +int emu_load_state(int slot); + void set_cd_image(const char *fname); extern unsigned long gpuDisp; extern int ready_to_go; +extern char hud_msg[64]; +extern int hud_new_msg; + +enum sched_action { + SACTION_NONE, + SACTION_ENTER_MENU, + SACTION_LOAD_STATE, + SACTION_SAVE_STATE, + SACTION_NEXT_SSLOT, + SACTION_PREV_SSLOT, + SACTION_TOGGLE_FSKIP, +}; + +static inline void emu_set_action(enum sched_action action_) +{ + extern enum sched_action emu_action, emu_action_old; + extern int stop; + + if (action_ == SACTION_NONE) + emu_action_old = 0; + else if (action_ != emu_action_old) + stop = 1; + emu_action = action_; +} + #endif /* __LINUX_H__ */ diff --git a/frontend/menu.c b/frontend/menu.c index e7d20ffe..d5c7d91a 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -60,7 +60,7 @@ enum { }; static int last_psx_w, last_psx_h, last_psx_bpp; -static int scaling, filter, state_slot, cpu_clock, cpu_clock_st; +static int scaling, filter, cpu_clock, cpu_clock_st; static char rom_fname_reload[MAXPATHLEN]; static char last_selected_fname[MAXPATHLEN]; static int region, in_type_sel; @@ -103,28 +103,16 @@ void emu_make_path(char *buff, const char *end, int size) static int emu_check_save_file(int slot) { - char fname[MAXPATHLEN]; - int ret; - - ret = get_state_filename(fname, sizeof(fname), slot); - if (ret != 0) - return 0; - - ret = CheckState(fname); + int ret = emu_check_state(slot); return ret == 0 ? 1 : 0; } -static int emu_save_load_game(int load, int sram) +static int emu_save_load_game(int load, int unused) { - char fname[MAXPATHLEN]; int ret; - ret = get_state_filename(fname, sizeof(fname), state_slot); - if (ret != 0) - return 0; - if (load) { - ret = LoadState(fname); + ret = emu_load_state(state_slot); // reflect hle/bios mode from savestate if (Config.HLE) @@ -134,7 +122,7 @@ static int emu_save_load_game(int load, int sram) bios_sel = 1; } else - ret = SaveState(fname); + ret = emu_save_state(state_slot); return ret; } @@ -663,13 +651,12 @@ me_bind_action me_ctrl_actions[] = me_bind_action emuctrl_actions[] = { -/* - { "Load State ", PEV_STATE_LOAD }, - { "Save State ", PEV_STATE_SAVE }, - { "Prev Save Slot ", PEV_SSLOT_PREV }, - { "Next Save Slot ", PEV_SSLOT_NEXT }, -*/ - { "Enter Menu ", PEV_MENU }, + { "Save State ", 1 << SACTION_SAVE_STATE }, + { "Load State ", 1 << SACTION_LOAD_STATE }, + { "Prev Save Slot ", 1 << SACTION_PREV_SSLOT }, + { "Next Save Slot ", 1 << SACTION_NEXT_SSLOT }, + { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP }, + { "Enter Menu ", 1 << SACTION_ENTER_MENU }, { NULL, 0 } }; @@ -835,7 +822,7 @@ static void keys_load_all(const char *cfg) bind = parse_bind_val(act, &bindtype); if (bind != -1 && bind != 0) { - printf("bind #%d '%s' %08x (%s)\n", dev_id, key, bind, act); + //printf("bind #%d '%s' %08x (%s)\n", dev_id, key, bind, act); in_config_bind_key(dev_id, key, bind, bindtype); } else @@ -1095,7 +1082,7 @@ static int menu_loop_plugin_options(int id, int keys) // ------------ adv options menu ------------ -static const char h_cfg_cpul[] = "Shows CPU usage in %%"; +static const char h_cfg_cpul[] = "Shows CPU usage in %"; static const char h_cfg_fl[] = "Frame Limiter keeps the game from running too fast"; static const char h_cfg_xa[] = "Disables XA sound, which can sometimes improve performance"; static const char h_cfg_cdda[] = "Disable CD Audio for a performance boost\n" diff --git a/frontend/pandora.c b/frontend/pandora.c index cd50728e..677784e6 100644 --- a/frontend/pandora.c +++ b/frontend/pandora.c @@ -17,6 +17,7 @@ #include "common/input.h" #include "plugin_lib.h" +#include "main.h" static int fdnub[2]; static int analog_init_done; @@ -43,7 +44,6 @@ struct in_default_bind in_evdev_defbinds[] = { { KEY_DOWN, IN_BINDTYPE_PLAYER12, DKEY_DOWN }, { KEY_LEFT, IN_BINDTYPE_PLAYER12, DKEY_LEFT }, { KEY_RIGHT, IN_BINDTYPE_PLAYER12, DKEY_RIGHT }, - { KEY_SPACE, IN_BINDTYPE_EMU, PEVB_MENU }, { KEY_PAGEUP, IN_BINDTYPE_PLAYER12, DKEY_TRIANGLE }, { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, DKEY_CROSS }, { KEY_END, IN_BINDTYPE_PLAYER12, DKEY_CIRCLE }, @@ -54,6 +54,12 @@ struct in_default_bind in_evdev_defbinds[] = { { KEY_RIGHTCTRL, IN_BINDTYPE_PLAYER12, DKEY_R1 }, { KEY_Q, IN_BINDTYPE_PLAYER12, DKEY_L2 }, { KEY_P, IN_BINDTYPE_PLAYER12, DKEY_R2 }, + { KEY_SPACE, IN_BINDTYPE_EMU, SACTION_ENTER_MENU }, + { KEY_1, IN_BINDTYPE_EMU, SACTION_SAVE_STATE }, + { KEY_2, IN_BINDTYPE_EMU, SACTION_LOAD_STATE }, + { KEY_3, IN_BINDTYPE_EMU, SACTION_PREV_SSLOT }, + { KEY_4, IN_BINDTYPE_EMU, SACTION_NEXT_SSLOT }, + { KEY_5, IN_BINDTYPE_EMU, SACTION_TOGGLE_FSKIP }, { 0, 0, 0 } }; diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index a2fb4951..975fc0a5 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -1,5 +1,5 @@ /* - * (C) notaz, 2010 + * (C) notaz, 2010-2011 * * This work is licensed under the terms of the GNU GPLv2 or later. * See the COPYING file in the top-level directory. @@ -23,6 +23,7 @@ #include "common/input.h" #include "omap.h" #include "menu.h" +#include "main.h" #include "pcnt.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" #include "../libpcsxcore/psemu_plugin_defs.h" @@ -58,6 +59,12 @@ static int get_cpu_ticks(void) return ret; } +static void print_hud(void) +{ + if (pl_fbdev_bpp == 16) + pl_text_out16(2, pl_fbdev_h - 10, "%s", hud_msg); +} + static void print_fps(void) { if (pl_fbdev_bpp == 16) @@ -98,8 +105,11 @@ void *pl_fbdev_flip(void) flip_cnt++; if (pl_fbdev_buf != NULL) { - if (g_opts & OPT_SHOWFPS) + if (hud_msg[0] != 0) + print_hud(); + else if (g_opts & OPT_SHOWFPS) print_fps(); + if (g_opts & OPT_SHOWCPU) print_cpu_usage(); } @@ -124,12 +134,20 @@ void pl_fbdev_close(void) static void update_input(void) { int actions[IN_BINDTYPE_COUNT] = { 0, }; + unsigned int emu_act; in_update(actions); if (in_type == PSE_PAD_TYPE_ANALOGPAD) in_update_analogs(); - if (actions[IN_BINDTYPE_EMU] & PEV_MENU) - stop = 1; + emu_act = actions[IN_BINDTYPE_EMU]; + if (emu_act) { + int which = 0; + for (; !(emu_act & 1); emu_act >>= 1, which++) + ; + emu_act = which; + } + emu_set_action(emu_act); + in_keystate = actions[IN_BINDTYPE_PLAYER12]; #ifdef X11 @@ -179,6 +197,12 @@ void pl_frame_limit(void) tv_old = now; if (g_opts & OPT_SHOWCPU) tick_per_sec = get_cpu_ticks(); + + if (hud_new_msg > 0) { + hud_new_msg--; + if (hud_new_msg == 0) + hud_msg[0] = 0; + } } #ifdef PCNT static int ya_vsync_count; diff --git a/maemo/hildon.c b/maemo/hildon.c index df42a90a..37e67aff 100644 --- a/maemo/hildon.c +++ b/maemo/hildon.c @@ -5,6 +5,7 @@ #include #include #include "plugin_lib.h" +#include "main.h" #include "../libpcsxcore/psemu_plugin_defs.h" #define X_RES 800 @@ -80,10 +81,12 @@ window_key_proxy(GtkWidget *widget, psxkey2 = DKEY_RIGHT; break; case 19: - //SaveState(cfile); + if (event->type == GDK_KEY_PRESS) + emu_set_action(SACTION_SAVE_STATE); return; case 20: - //LoadState(cfile); + if (event->type == GDK_KEY_PRESS) + emu_set_action(SACTION_LOAD_STATE); return; } @@ -98,6 +101,8 @@ window_key_proxy(GtkWidget *widget, in_keystate &= ~(1 << psxkey1); if (psxkey2 >= 0) in_keystate &= ~(1 << psxkey2); + + emu_set_action(SACTION_NONE); } } @@ -148,6 +153,10 @@ void maemo_init(int *argc, char ***argv) gtk_widget_show_all (GTK_WIDGET (window)); } +void menu_loop(void) +{ +} + void *pl_fbdev_set_mode(int w, int h, int bpp) { if (w <= 0 || h <= 0) diff --git a/maemo/main.c b/maemo/main.c index 80919ace..f797c122 100644 --- a/maemo/main.c +++ b/maemo/main.c @@ -173,11 +173,8 @@ int maemo_main(int argc, char **argv) // If a state has been specified, then load that if (loadst) { - char state_filename[MAXPATHLEN]; - int ret = get_state_filename(state_filename, sizeof(state_filename), loadst - 1); - if (ret == 0) - ret = LoadState(state_filename); - printf("%s state %s\n", ret ? "failed to load" : "loaded", state_filename); + int ret = emu_load_state(loadst - 1); + printf("%s state %d\n", ret ? "failed to load" : "loaded", loadst); } if (ready_to_go) -- 2.39.2 From 8680e8229414b74335e2c1d05cc678cf8bab685b Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 8 Feb 2011 01:27:36 +0200 Subject: [PATCH 09/16] spu: handle channels better in 'IRQ wait' case --- plugins/dfsound/spu.c | 57 ++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 8936e45b..084fccf0 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -441,7 +441,7 @@ INLINE int iGetInterpolationVal(int ch) static void *MAINThread(void *arg) { - int s_1,s_2,fa,ns; + int s_1,s_2,fa,ns,ns_from,ns_to; #if !defined(_MACOSX) && !defined(__arm__) int voldiv = iVolume; #else @@ -480,17 +480,19 @@ static void *MAINThread(void *arg) //--------------------------------------------------// continue from irq handling in timer mode? + ns_from=0; + ns_to=NSSIZE; + ch=0; if(lastch>=0) // will be -1 if no continue is pending { - ch=lastch; ns=lastns; lastch=-1; // -> setup all kind of vars to continue - goto GOON; // -> directly jump to the continue point + ch=lastch; ns_from=lastns+1; lastch=-1; // -> setup all kind of vars to continue } //--------------------------------------------------// //- main channel loop -// //--------------------------------------------------// { - for(ch=0;ch Date: Tue, 8 Feb 2011 01:32:53 +0200 Subject: [PATCH 10/16] frontend: enable SPUIRQWait by default --- frontend/menu.c | 13 +++++++++---- plugins/dfsound/spu.c | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/frontend/menu.c b/frontend/menu.c index d5c7d91a..77629059 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -159,7 +159,8 @@ static void menu_set_defconfig(void) iUseReverb = 2; iUseInterpolation = 1; - iXAPitch = iSPUIRQWait = 0; + iXAPitch = 0; + iSPUIRQWait = 1; iUseTimer = 2; menu_sync_config(); @@ -177,6 +178,10 @@ static void menu_set_defconfig(void) #define CE_INTVAL(val) \ { #val, sizeof(val), &val } +// 'versioned' var, used when defaults change +#define CE_INTVAL_V(val, ver) \ + { #val #ver, sizeof(val), &val } + static const struct { const char *name; size_t len; @@ -211,9 +216,9 @@ static const struct { CE_INTVAL(UseFrameSkip), CE_INTVAL(dwActFixes), CE_INTVAL(iUseReverb), - CE_INTVAL(iUseInterpolation), CE_INTVAL(iXAPitch), - CE_INTVAL(iSPUIRQWait), + CE_INTVAL_V(iUseInterpolation, 2), + CE_INTVAL_V(iSPUIRQWait, 2), CE_INTVAL(iUseTimer), }; @@ -1026,7 +1031,7 @@ static int menu_loop_plugin_gpu(int id, int keys) static const char *men_spu_reverb[] = { "Off", "Fake", "On", NULL }; static const char *men_spu_interp[] = { "None", "Simple", "Gaussian", "Cubic", NULL }; -static const char h_spu_irq_wait[] = "Wait for CPU; only useful for some games, may cause glitches"; +static const char h_spu_irq_wait[] = "Wait for CPU (recommended set to ON)"; static const char h_spu_thread[] = "Run sound emulation in main thread (recommended)"; static menu_entry e_menu_plugin_spu[] = diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 084fccf0..c455d3d7 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -925,7 +925,7 @@ long CALLBACK SPUinit(void) pMixIrq = 0; memset((void *)s_chan, 0, (MAXCHAN + 1) * sizeof(SPUCHAN)); pSpuIrq = 0; - iSPUIRQWait = 0; + //iSPUIRQWait = 0; lastch = -1; //ReadConfigSPU(); // read user stuff -- 2.39.2 From 1df403c52368a3930b67dedabf8c0e1d522f1cc3 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 8 Feb 2011 18:21:17 +0200 Subject: [PATCH 11/16] add cd swap functionality --- frontend/menu.c | 38 ++++++++++++++++++++++++++++++++++++++ libpcsxcore/cdrom.h | 1 + libpcsxcore/plugins.c | 17 +++++++++++++++++ libpcsxcore/plugins.h | 3 ++- 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/frontend/menu.c b/frontend/menu.c index 77629059..20d334c1 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -22,6 +22,7 @@ #include "omap.h" #include "common/plat.h" #include "../libpcsxcore/misc.h" +#include "../libpcsxcore/cdrom.h" #include "../libpcsxcore/psemu_plugin_defs.h" #include "revision.h" @@ -36,6 +37,7 @@ typedef enum MA_MAIN_LOAD_STATE, MA_MAIN_RESET_GAME, MA_MAIN_LOAD_ROM, + MA_MAIN_SWAP_CD, MA_MAIN_RUN_BIOS, MA_MAIN_CONTROLS, MA_MAIN_CREDITS, @@ -1335,6 +1337,36 @@ static int romsel_run(void) return 0; } +static int swap_cd_image(void) +{ + char *fname; + + fname = menu_loop_romsel(last_selected_fname, sizeof(last_selected_fname)); + if (fname == NULL) + return -1; + + printf("selected file: %s\n", fname); + + CdromId[0] = '\0'; + CdromLabel[0] = '\0'; + + set_cd_image(fname); + if (ReloadCdromPlugin() < 0) { + me_update_msg("failed to load cdr plugin"); + return -1; + } + if (CDR_open() < 0) { + me_update_msg("failed to open cdr plugin"); + return -1; + } + + SetCdOpenCaseTime(time(NULL) + 2); + LidInterrupt(); + + strcpy(last_selected_fname, rom_fname_reload); + return 0; +} + static int main_menu_handler(int id, int keys) { switch (id) @@ -1359,6 +1391,10 @@ static int main_menu_handler(int id, int keys) if (romsel_run() == 0) return 1; break; + case MA_MAIN_SWAP_CD: + if (swap_cd_image() == 0) + return 1; + break; case MA_MAIN_RUN_BIOS: if (run_bios() == 0) return 1; @@ -1387,6 +1423,7 @@ static menu_entry e_menu_main[] = mee_handler_id("Load State", MA_MAIN_LOAD_STATE, main_menu_handler), mee_handler_id("Reset game", MA_MAIN_RESET_GAME, main_menu_handler), mee_handler_id("Load CD image", MA_MAIN_LOAD_ROM, main_menu_handler), + mee_handler_id("Change CD image", MA_MAIN_SWAP_CD, main_menu_handler), mee_handler_id("Run BIOS", MA_MAIN_RUN_BIOS, main_menu_handler), mee_handler ("Options", menu_loop_options), mee_handler ("Controls", menu_loop_keyconfig), @@ -1409,6 +1446,7 @@ void menu_loop(void) me_enable(e_menu_main, MA_MAIN_SAVE_STATE, ready_to_go && CdromId[0]); me_enable(e_menu_main, MA_MAIN_LOAD_STATE, ready_to_go && CdromId[0]); me_enable(e_menu_main, MA_MAIN_RESET_GAME, ready_to_go); + me_enable(e_menu_main, MA_MAIN_SWAP_CD, ready_to_go); me_enable(e_menu_main, MA_MAIN_RUN_BIOS, bios_sel != 0); in_set_config_int(0, IN_CFG_BLOCKING, 1); diff --git a/libpcsxcore/cdrom.h b/libpcsxcore/cdrom.h index 90523c30..1f70ff36 100644 --- a/libpcsxcore/cdrom.h +++ b/libpcsxcore/cdrom.h @@ -108,6 +108,7 @@ void cdrRepplayInterrupt(); void cdrLidSeekInterrupt(); void cdrPlayInterrupt(); void cdrDmaInterrupt(); +void LidInterrupt(); unsigned char cdrRead0(void); unsigned char cdrRead1(void); unsigned char cdrRead2(void); diff --git a/libpcsxcore/plugins.c b/libpcsxcore/plugins.c index f965e0d0..57e7ef2d 100644 --- a/libpcsxcore/plugins.c +++ b/libpcsxcore/plugins.c @@ -794,6 +794,23 @@ void ReleasePlugins() { #endif } +// for CD swap +int ReloadCdromPlugin() +{ + if (hCDRDriver != NULL || cdrIsoActive()) CDR_shutdown(); + if (hCDRDriver != NULL) SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; + + if (UsingIso()) { + LoadCDRplugin(NULL); + } else { + char Plugin[MAXPATHLEN]; + sprintf(Plugin, "%s/%s", Config.PluginsDir, Config.Cdr); + if (LoadCDRplugin(Plugin) == -1) return -1; + } + + return CDR_init(); +} + void SetIsoFile(const char *filename) { if (filename == NULL) { IsoFile[0] = '\0'; diff --git a/libpcsxcore/plugins.h b/libpcsxcore/plugins.h index 9c24ecef..8084143a 100644 --- a/libpcsxcore/plugins.h +++ b/libpcsxcore/plugins.h @@ -60,6 +60,7 @@ int LoadPlugins(); void ReleasePlugins(); int OpenPlugins(); void ClosePlugins(); +int ReloadCdromPlugin(); typedef unsigned long (CALLBACK* PSEgetLibType)(void); typedef unsigned long (CALLBACK* PSEgetLibVersion)(void); @@ -150,7 +151,7 @@ struct SubQ { unsigned char IndexNumber; unsigned char TrackRelativeAddress[3]; unsigned char Filler; - unsigned char AbsoluteAddress[3]; + unsigned char AbsoluteAddress[3]; unsigned char CRC[2]; char res1[72]; }; -- 2.39.2 From f1bad6e15fb5d34fb7269936068fc2540b461a4f Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 10 Feb 2011 01:16:49 +0200 Subject: [PATCH 12/16] dfxvideo: fix frameskip issue if display is never moved/resized, it's never updated in frameskip mode. Detect this. --- plugins/dfxvideo/gpu.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/dfxvideo/gpu.c b/plugins/dfxvideo/gpu.c index 7372ba4a..50d45d59 100644 --- a/plugins/dfxvideo/gpu.c +++ b/plugins/dfxvideo/gpu.c @@ -218,6 +218,8 @@ static void updateDisplay(void) // UPDATE DISPLAY bSkipNextFrame = FALSE; DoBufferSwap(); // -> swap } + + bDoVSyncUpdate=FALSE; // vsync done } //////////////////////////////////////////////////////////////////////// @@ -406,11 +408,14 @@ void CALLBACK GPUupdateLace(void) // VSYNC } else { - if(bDoVSyncUpdate && !UseFrameSkip) // some primitives drawn? - updateDisplay(); // -> update display + if((bDoVSyncUpdate && !UseFrameSkip) // some primitives drawn? + || bDoVSyncUpdate >= 8) // not syned for a while + updateDisplay(); // -> update display } } - bDoVSyncUpdate=FALSE; // vsync done + + if(bDoVSyncUpdate) // if display not synced + bDoVSyncUpdate++; // count how many times } //////////////////////////////////////////////////////////////////////// -- 2.39.2 From acb57d8d14a903b691ac06aced5829c31ef447ce Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 10 Feb 2011 02:31:08 +0200 Subject: [PATCH 13/16] release r6 --- .gitignore | 3 ++- pandora/readme.txt | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 12f27497..0e8f07fe 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ frontend/common frontend/X11 tags cscope.out -pandora/picorestore +pandora +pcsx.map diff --git a/pandora/readme.txt b/pandora/readme.txt index c0a59d2e..520a6390 100644 --- a/pandora/readme.txt +++ b/pandora/readme.txt @@ -62,6 +62,25 @@ spunull.so - NULL plugin, i.e. no sound emulation. Changelog --------- +r6 (2011-02-10) ++ added analog controller support using nubs (disabled by default) ++ added control config saving ++ added support for ingame actions (eg. savestate load) ++ added 'auto' region option and made it default ++ added cd swap functionality ++ added maemo frontend from Bonapart + (with some tuning, source code only) +* reworked key configuration to be less confusing +* fixed 'SPU IRQ wait' option sometimes causing noise + and turned it on by default +* fixed mono xa masking (was causing noise) +* fixed word access macros in dfxvideo (darkness problem) +* changed GPU DMA timing back to 1.92 levels +* backported more fixes from PCSX-Reloaded project + (mostly shalma's work, see GIT) +* fixed a few more recompiler issues ++ fixed frameskip in builtin plugin + r5 (2011-01-31) + added support for .bz format, also partial support for .znx and eboot.pbp formats -- 2.39.2 From 3e215238e4b5f93b471679d12cd2144cb49b95b1 Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 10 Feb 2011 23:31:59 +0200 Subject: [PATCH 14/16] frontend: tune frameskip a bit more also init analog vars as centered (in case they are never updated) --- frontend/plugin_lib.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 975fc0a5..5cf1ff4d 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -30,7 +30,7 @@ void *pl_fbdev_buf; int pl_frame_interval; -int in_type, in_keystate, in_a1[2], in_a2[2]; +int in_type, in_keystate, in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 }; static int pl_fbdev_w, pl_fbdev_h, pl_fbdev_bpp; static int flip_cnt, vsync_cnt, flips_per_sec, tick_per_sec; static float vsps_cur; @@ -226,11 +226,16 @@ void pl_frame_limit(void) usleep(diff - pl_frame_interval / 2); } - plugin_skip_advice = 0; - if (UseFrameSkip && diff < -pl_frame_interval) { - // P.E.Op.S. makes skip decision based on this - fps_skip = 1.0f; - plugin_skip_advice = 1; + if (UseFrameSkip) { + if (diff < -pl_frame_interval) { + // P.E.Op.S. makes skip decision based on this + fps_skip = 1.0f; + plugin_skip_advice = 1; + } + else if (diff >= 0) { + fps_skip = 100.0f; + plugin_skip_advice = 0; + } } pcnt_start(PCNT_ALL); -- 2.39.2 From 384f5f43a20879e2553acd17b76e82059092fafb Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 11 Feb 2011 00:02:11 +0200 Subject: [PATCH 15/16] use analog handling from dfinput --- Makefile | 4 + frontend/menu.c | 3 + plugins/dfinput/pad.c | 287 ++++++++++++++++++++++++++++++++++++++++++ plugins/dfinput/pad.h | 2 + 4 files changed, 296 insertions(+) create mode 100644 plugins/dfinput/pad.c create mode 100644 plugins/dfinput/pad.h diff --git a/Makefile b/Makefile index db8e1f60..89fc2a9c 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,10 @@ endif plugins/cdrcimg/%.o: CFLAGS += -Wall OBJS += plugins/cdrcimg/cdrcimg.o +# dfinput +plugins/dfinput/%.o: CFLAGS += -Wall +OBJS += plugins/dfinput/pad.o + # gui OBJS += frontend/main.o frontend/plugin.o ifeq "$(USE_GTK)" "1" diff --git a/frontend/menu.c b/frontend/menu.c index 20d334c1..9ebfa861 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -24,6 +24,7 @@ #include "../libpcsxcore/misc.h" #include "../libpcsxcore/cdrom.h" #include "../libpcsxcore/psemu_plugin_defs.h" +#include "../plugins/dfinput/pad.h" #include "revision.h" #define MENU_X2 1 @@ -1670,6 +1671,8 @@ void menu_prepare_emu(void) if (ret) fprintf(stderr, "Warning: GPU_open returned %d\n", ret); } + + dfinput_activate(in_type == PSE_PAD_TYPE_ANALOGPAD); } void me_update_msg(const char *msg) diff --git a/plugins/dfinput/pad.c b/plugins/dfinput/pad.c new file mode 100644 index 00000000..c5221171 --- /dev/null +++ b/plugins/dfinput/pad.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2009, Wei Mingzhi . + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * this is only pure emulation code to handle analogs, + * extracted from dfinput. + */ + +#include + +#include "../../libpcsxcore/psemu_plugin_defs.h" + +enum { + ANALOG_LEFT = 0, + ANALOG_RIGHT, + + ANALOG_TOTAL +}; + +enum { + CMD_READ_DATA_AND_VIBRATE = 0x42, + CMD_CONFIG_MODE = 0x43, + CMD_SET_MODE_AND_LOCK = 0x44, + CMD_QUERY_MODEL_AND_MODE = 0x45, + CMD_QUERY_ACT = 0x46, // ?? + CMD_QUERY_COMB = 0x47, // ?? + CMD_QUERY_MODE = 0x4C, // QUERY_MODE ?? + CMD_VIBRATION_TOGGLE = 0x4D, +}; + +static struct { + uint8_t PadMode; + uint8_t PadID; + PadDataS pad; +} padstate[2]; + +static uint8_t stdpar[2][8] = { + {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}, + {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80} +}; + +static uint8_t unk46[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}, + {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A} +}; + +static uint8_t unk47[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00} +}; + +static uint8_t unk4c[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; + +static uint8_t unk4d[2][8] = { + {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; + +static uint8_t stdcfg[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; + +static uint8_t stdmode[2][8] = { + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; + +static uint8_t stdmodel[2][8] = { + {0xFF, + 0x5A, + 0x01, // 03 - dualshock2, 01 - dualshock + 0x02, // number of modes + 0x01, // current mode: 01 - analog, 00 - digital + 0x02, + 0x01, + 0x00}, + {0xFF, + 0x5A, + 0x01, // 03 - dualshock2, 01 - dualshock + 0x02, // number of modes + 0x01, // current mode: 01 - analog, 00 - digital + 0x02, + 0x01, + 0x00} +}; + +static uint8_t CurPad = 0, CurByte = 0, CurCmd = 0, CmdLen = 0; +static uint8_t *buf; + +static uint8_t do_cmd(void) +{ + PadDataS *pad = &padstate[CurPad].pad; + int pad_num = CurPad; + + CmdLen = 8; + switch (CurCmd) { + case CMD_CONFIG_MODE: + buf = stdcfg[pad_num]; + if (stdcfg[pad_num][3] == 0xFF) return 0xF3; + else return padstate[pad_num].PadID; + + case CMD_SET_MODE_AND_LOCK: + buf = stdmode[pad_num]; + return 0xF3; + + case CMD_QUERY_MODEL_AND_MODE: + buf = stdmodel[pad_num]; + buf[4] = padstate[pad_num].PadMode; + return 0xF3; + + case CMD_QUERY_ACT: + buf = unk46[pad_num]; + return 0xF3; + + case CMD_QUERY_COMB: + buf = unk47[pad_num]; + return 0xF3; + + case CMD_QUERY_MODE: + buf = unk4c[pad_num]; + return 0xF3; + + case CMD_VIBRATION_TOGGLE: + buf = unk4d[pad_num]; + return 0xF3; + + case CMD_READ_DATA_AND_VIBRATE: + default: + buf = stdpar[pad_num]; + + buf[2] = pad->buttonStatus; + buf[3] = pad->buttonStatus >> 8; + + if (padstate[pad_num].PadMode == 1) { + buf[4] = pad->rightJoyX; + buf[5] = pad->rightJoyY; + buf[6] = pad->leftJoyX; + buf[7] = pad->leftJoyY; + } else { + CmdLen = 4; + } + + return padstate[pad_num].PadID; + } +} + +static void do_cmd2(unsigned char value) +{ + switch (CurCmd) { + case CMD_CONFIG_MODE: + switch (value) { + case 0: + buf[2] = 0; + buf[3] = 0; + break; + + case 1: + buf[2] = 0xFF; + buf[3] = 0xFF; + break; + } + break; + + case CMD_SET_MODE_AND_LOCK: + padstate[CurPad].PadMode = value; + padstate[CurPad].PadID = value ? 0x73 : 0x41; + break; + + case CMD_QUERY_ACT: + switch (value) { + case 0: // default + buf[5] = 0x02; + buf[6] = 0x00; + buf[7] = 0x0A; + break; + + case 1: // Param std conf change + buf[5] = 0x01; + buf[6] = 0x01; + buf[7] = 0x14; + break; + } + break; + + case CMD_QUERY_MODE: + switch (value) { + case 0: // mode 0 - digital mode + buf[5] = PSE_PAD_TYPE_STANDARD; + break; + + case 1: // mode 1 - analog mode + buf[5] = PSE_PAD_TYPE_ANALOGPAD; + break; + } + break; + } +} + +static unsigned char PADpoll_(unsigned char value) { + + if (CurByte == 0) { + CurCmd = value; + CurByte++; + + // Don't enable Analog/Vibration for a standard pad + if (padstate[CurPad].pad.controllerType != PSE_PAD_TYPE_ANALOGPAD) + CurCmd = CMD_READ_DATA_AND_VIBRATE; + + return do_cmd(); + } + + if (CurByte == 2) + do_cmd2(value); + + if (CurByte >= CmdLen) + return 0; + + return buf[CurByte++]; +} + +#include +static unsigned char PADpoll(unsigned char value) { + unsigned char b = CurByte, r = PADpoll_(value); + printf("poll[%d] %02x %02x\n", b, value, r); + return r; +} + +/* hack.. */ +extern long (*PAD1_readPort1)(PadDataS *pad); + +static unsigned char PADstartPoll1(int pad) { + CurPad = 0; + CurByte = 0; + + PAD1_readPort1(&padstate[0].pad); + + return 0xFF; +} + +/* some more hacks here but oh well */ +extern void *PAD1_startPoll, *PAD1_poll; + +void dfinput_activate(int yes) +{ + static void *old_start, *old_poll; + + if (!yes) { + if (PAD1_startPoll == PADstartPoll1) + PAD1_startPoll = old_start; + if (PAD1_poll == PADpoll) + PAD1_poll = old_poll; + return; + } + + if (PAD1_startPoll == PADstartPoll1 && PAD1_poll == PADpoll) + return; + + old_start = PAD1_startPoll; + old_poll = PAD1_poll; + PAD1_startPoll = PADstartPoll1; + PAD1_poll = PADpoll; + + PAD1_readPort1(&padstate[0].pad); + padstate[0].PadID = padstate[0].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD ? 0x73 : 0x41; + padstate[0].PadMode = padstate[0].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD; + + padstate[1].PadID = 0x41; + padstate[1].PadMode = 0; +} + diff --git a/plugins/dfinput/pad.h b/plugins/dfinput/pad.h new file mode 100644 index 00000000..60a46f04 --- /dev/null +++ b/plugins/dfinput/pad.h @@ -0,0 +1,2 @@ +void dfinput_activate(int yes); + -- 2.39.2 From 45d45c1e22620ef51023d0b8e09e85db9cb9380c Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 11 Feb 2011 00:31:33 +0200 Subject: [PATCH 16/16] main.c: load savestate after prepare --- Makefile | 2 +- frontend/main.c | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 89fc2a9c..63241e58 100644 --- a/Makefile +++ b/Makefile @@ -134,7 +134,7 @@ clean_plugins: PND_MAKE ?= $(HOME)/dev/pnd/src/pandora-libraries/testdata/scripts/pnd_make.sh -VER ?= $(shell git describe --abbrev=0 master) +VER ?= $(shell git describe master) rel: pcsx $(PLUGINS) \ pandora/pcsx.sh pandora/pcsx.pxml pandora/pcsx.png \ diff --git a/frontend/main.c b/frontend/main.c index 64a16d37..61f023f0 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -288,14 +288,15 @@ int main(int argc, char *argv[]) } } - // If a state has been specified, then load that - if (loadst) { - int ret = emu_load_state(loadst - 1); - printf("%s state %d\n", ret ? "failed to load" : "loaded", loadst); - } - - if (ready_to_go) + if (ready_to_go) { menu_prepare_emu(); + + // If a state has been specified, then load that + if (loadst) { + int ret = emu_load_state(loadst - 1); + printf("%s state %d\n", ret ? "failed to load" : "loaded", loadst); + } + } else menu_loop(); -- 2.39.2