add guncon support
authornotaz <notasas@gmail.com>
Mon, 8 Aug 2011 22:16:59 +0000 (01:16 +0300)
committernotaz <notasas@gmail.com>
Fri, 12 Aug 2011 21:56:33 +0000 (00:56 +0300)
a bit basic but works

18 files changed:
Makefile
frontend/main.c
frontend/main.h
frontend/menu.c
frontend/menu.h
frontend/pl_gun_ts.c [new file with mode: 0644]
frontend/pl_gun_ts.h [new file with mode: 0644]
frontend/plat_omap.c
frontend/plugin.c
frontend/plugin_lib.c
frontend/plugin_lib.h
libpcsxcore/psemu_plugin_defs.h
maemo/hildon.c
plugins/dfinput/guncon.c [new file with mode: 0644]
plugins/dfinput/main.c [new file with mode: 0644]
plugins/dfinput/main.h [new file with mode: 0644]
plugins/dfinput/pad.c
plugins/dfinput/pad.h [deleted file]

index 11b7387..b95f7f2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -88,7 +88,7 @@ endif
 OBJS += plugins/cdrcimg/cdrcimg.o
 
 # dfinput
-OBJS += plugins/dfinput/pad.o
+OBJS += plugins/dfinput/main.o plugins/dfinput/pad.o plugins/dfinput/guncon.o
 
 # gui
 OBJS += frontend/main.o frontend/plugin.o
@@ -117,6 +117,10 @@ endif
 ifdef PCNT
 CFLAGS += -DPCNT
 endif
+ifndef NO_TSLIB
+frontend/%.o: CFLAGS += -DHAVE_TSLIB
+OBJS += frontend/pl_gun_ts.o
+endif
 frontend/%.o: CFLAGS += -DIN_EVDEV
 frontend/menu.o: frontend/revision.h
 
index b17df53..c5520cf 100644 (file)
@@ -149,8 +149,6 @@ void do_emu_action(void)
        emu_action_old = emu_action;
 
        switch (emu_action) {
-       case SACTION_NONE:
-               return;
        case SACTION_ENTER_MENU:
                menu_loop();
                return;
@@ -196,6 +194,8 @@ void do_emu_action(void)
                                snprintf(hud_msg, sizeof(hud_msg), "SCREENSHOT TAKEN");
                        break;
                }
+       default:
+               return;
        }
        hud_new_msg = 3;
        return;
@@ -204,6 +204,7 @@ 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;
+       printf("* %s\n", hud_msg);
 }
 
 int main(int argc, char *argv[])
@@ -317,6 +318,7 @@ int main(int argc, char *argv[])
        //in_probe();
        plat_init();
        menu_init(); // loads config
+       pl_init();
 
        if (psxout)
                Config.PsxOut = 1;
index eadb3c6..7267f2b 100644 (file)
@@ -57,8 +57,14 @@ enum sched_action {
        SACTION_PREV_SSLOT,
        SACTION_TOGGLE_FSKIP,
        SACTION_SCREENSHOT,
+       SACTION_GUN_TRIGGER = 16,
+       SACTION_GUN_A,
+       SACTION_GUN_B,
+       SACTION_GUN_TRIGGER2,
 };
 
+#define SACTION_GUN_MASK (0x0f << SACTION_GUN_TRIGGER)
+
 static inline void emu_set_action(enum sched_action action_)
 {
        extern enum sched_action emu_action, emu_action_old;
index 6a07c8c..8b51c06 100644 (file)
@@ -30,7 +30,7 @@
 #include "../libpcsxcore/cdrom.h"
 #include "../libpcsxcore/psemu_plugin_defs.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
-#include "../plugins/dfinput/pad.h"
+#include "../plugins/dfinput/main.h"
 #include "revision.h"
 
 #define MENU_X2 1
@@ -73,7 +73,7 @@ static int last_psx_w, last_psx_h, last_psx_bpp;
 static int scaling, filter, cpu_clock, cpu_clock_st, volume_boost;
 static char rom_fname_reload[MAXPATHLEN];
 static char last_selected_fname[MAXPATHLEN];
-static int warned_about_bios, region, in_type_sel;
+static int warned_about_bios, region, in_type_sel1, in_type_sel2;
 static int memcard1_sel, memcard2_sel;
 int g_opts;
 
@@ -143,7 +143,16 @@ static void menu_sync_config(void)
                Config.PsxAuto = 0;
                Config.PsxType = region - 1;
        }
-       in_type = in_type_sel ? PSE_PAD_TYPE_ANALOGPAD : PSE_PAD_TYPE_STANDARD;
+       switch (in_type_sel1) {
+       case 1:  in_type1 = PSE_PAD_TYPE_ANALOGPAD; break;
+       case 2:  in_type1 = PSE_PAD_TYPE_GUNCON;    break;
+       default: in_type1 = PSE_PAD_TYPE_STANDARD;
+       }
+       switch (in_type_sel2) {
+       case 1:  in_type2 = PSE_PAD_TYPE_ANALOGPAD; break;
+       case 2:  in_type2 = PSE_PAD_TYPE_GUNCON;    break;
+       default: in_type2 = PSE_PAD_TYPE_STANDARD;
+       }
        if (in_evdev_allow_abs_only != allow_abs_only_old) {
                pandora_rescan_inputs();
                allow_abs_only_old = in_evdev_allow_abs_only;
@@ -165,7 +174,7 @@ static void menu_set_defconfig(void)
        volume_boost = 0;
 
        region = 0;
-       in_type_sel = 0;
+       in_type_sel1 = in_type_sel2 = 0;
        in_evdev_allow_abs_only = 0;
        Config.Xa = Config.Cdda = Config.Sio =
        Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0;
@@ -233,7 +242,8 @@ static const struct {
        CE_INTVAL(state_slot),
        CE_INTVAL(cpu_clock),
        CE_INTVAL(g_opts),
-       CE_INTVAL(in_type_sel),
+       CE_INTVAL(in_type_sel1),
+       CE_INTVAL(in_type_sel2),
        CE_INTVAL_P(frameskip),
        CE_INTVAL_P(gpu_peops.iUseDither),
        CE_INTVAL_P(gpu_peops.dwActFixes),
@@ -708,6 +718,10 @@ me_bind_action emuctrl_actions[] =
        { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP },
        { "Take Screenshot  ", 1 << SACTION_SCREENSHOT },
        { "Enter Menu       ", 1 << SACTION_ENTER_MENU },
+       { "Gun Trigger      ", 1 << SACTION_GUN_TRIGGER },
+       { "Gun A button     ", 1 << SACTION_GUN_A },
+       { "Gun B button     ", 1 << SACTION_GUN_B },
+       { "Gun Offscreen Trigger", 1 << SACTION_GUN_TRIGGER2 },
        { NULL,                0 }
 };
 
@@ -943,17 +957,25 @@ static int mh_input_rescan(int id, int keys)
        return 0;
 }
 
-static const char *men_in_type_sel[] = { "Standard (SCPH-1080)", "Analog (SCPH-1150)", NULL };
+static const char *men_in_type_sel[] = {
+       "Standard (SCPH-1080)",
+       "Analog (SCPH-1150)",
+       "GunCon",
+       NULL
+};
 static const char h_nub_btns[] = "Experimental, keep this OFF if unsure. Select rescan after change.";
+static const char h_notsgun[] =  "Don't trigger (shoot) when touching screen in gun games.";
 
 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_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/Gun controls", MA_CTRL_EMU,        key_config_loop_wrap),
        mee_label     (""),
-       mee_enum      ("Controller",        0, in_type_sel,     men_in_type_sel),
+       mee_enum      ("Port 1 device",     0, in_type_sel1,    men_in_type_sel),
+       mee_enum      ("Port 2 device",     0, in_type_sel2,    men_in_type_sel),
        mee_onoff_h   ("Nubs as buttons",   0, in_evdev_allow_abs_only, 1, h_nub_btns),
+       mee_onoff_h   ("No TS Gun trigger", 0, g_opts, OPT_TSGUN_NOTRIGGER, h_notsgun),
        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_handler   ("Rescan devices",  mh_input_rescan),
@@ -2000,7 +2022,7 @@ void menu_prepare_emu(void)
                        fprintf(stderr, "Warning: GPU_open returned %d\n", ret);
        }
 
-       dfinput_activate(in_type == PSE_PAD_TYPE_ANALOGPAD);
+       dfinput_activate();
 }
 
 void me_update_msg(const char *msg)
index 7e401a3..1635146 100644 (file)
@@ -10,6 +10,7 @@ enum opts {
        OPT_SHOWCPU = 1 << 1,
        OPT_NO_FRAMELIM = 1 << 2,
        OPT_SHOWSPU = 1 << 3,
+       OPT_TSGUN_NOTRIGGER = 1 << 4,
 };
 
 extern int g_opts;
diff --git a/frontend/pl_gun_ts.c b/frontend/pl_gun_ts.c
new file mode 100644 (file)
index 0000000..63cf33f
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * (C) Gražvydas "notaz" Ignotas, 2011
+ *
+ * This work is licensed under the terms of any of these licenses
+ * (at your option):
+ *  - GNU GPL, version 2 or later.
+ *  - GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <tslib.h>
+#include "plugin_lib.h"
+#include "pl_gun_ts.h"
+#include "menu.h"
+#include "../plugins/dfinput/main.h"
+
+static int gun_x, gun_y, gun_in;
+static int ts_multiplier_x, ts_multiplier_y, ts_offs_x, ts_offs_y;
+static int (*pts_read)(struct tsdev *dev, struct ts_sample *sample, int nr);
+
+#define limit(v, min, max) \
+       if (v < min) v = min; \
+       else if (v > max) v = max
+
+void pl_gun_ts_update(struct tsdev *ts, int *x, int *y, int *in)
+{
+       struct ts_sample sample;
+       int sx = 0, sy = 0, sp = 0, updated = 0;
+
+       if (ts != NULL) {
+               while (pts_read(ts, &sample, 1) > 0) {
+                       sx = sample.x;
+                       sy = sample.y;
+                       sp = sample.pressure;
+                       updated = 1;
+               }
+
+               if (updated) {
+                       gun_x = (sx - ts_offs_x) * ts_multiplier_x >> 10;
+                       gun_y = (sy - ts_offs_y) * ts_multiplier_y >> 10;
+                       limit(gun_x, 0, 1023);
+                       limit(gun_y, 0, 1023);
+                       if (sp && !(g_opts & OPT_TSGUN_NOTRIGGER))
+                               gun_in |= GUNIN_TRIGGER;
+                       else
+                               gun_in &= ~GUNIN_TRIGGER;
+               }
+       }
+
+       *x = gun_x;
+       *y = gun_y;
+       *in = gun_in | in_state_gun;
+}
+
+void pl_set_gun_rect(int x, int y, int w, int h)
+{
+       ts_offs_x = x;
+       ts_offs_y = y;
+       ts_multiplier_x = (1<<20) / w;
+       ts_multiplier_y = (1<<20) / h;
+}
+
+struct tsdev *pl_gun_ts_init(void)
+{
+       struct tsdev *(*pts_open)(const char *dev_name, int nonblock) = NULL;
+       int (*pts_config)(struct tsdev *) = NULL;
+       int (*pts_close)(struct tsdev *) = NULL;
+       const char *tsdevname;
+       struct tsdev *ts;
+       void *ltsh;
+
+       tsdevname = getenv("TSLIB_TSDEVICE");
+       if (tsdevname == NULL)
+               tsdevname = "/dev/input/touchscreen0";
+
+       // avoid hard dep on tslib
+       ltsh = dlopen("/usr/lib/libts-1.0.so.0", RTLD_LAZY);
+       if (ltsh == NULL)
+               ltsh = dlopen("/usr/lib/libts-0.0.so.0", RTLD_LAZY);
+       if (ltsh == NULL) {
+               fprintf(stderr, "%s\n", dlerror());
+               goto fail;
+       }
+
+       pts_open = dlsym(ltsh, "ts_open");
+       pts_config = dlsym(ltsh, "ts_config");
+       pts_read = dlsym(ltsh, "ts_read");
+       pts_close = dlsym(ltsh, "ts_close");
+       if (pts_open == NULL || pts_config == NULL || pts_read == NULL || pts_close == NULL) {
+               fprintf(stderr, "%s\n", dlerror());
+               goto fail_dlsym;
+       }
+
+       ts = pts_open(tsdevname, 1);
+       if (ts == NULL)
+               goto fail_open;
+       if (pts_config(ts) != 0)
+               goto fail_config;
+
+       // FIXME: we should be able to get this somewhere
+       // the problem is this doesn't always match resolution due to different display modes
+       pl_set_gun_rect(0, 0, 800, 480);
+       return ts;
+
+fail_config:
+       pts_close(ltsh);
+fail_open:
+fail_dlsym:
+       dlclose(ltsh);
+       ltsh = NULL;
+fail:
+       fprintf(stderr, "Could not open touchscreen\n");
+       return NULL;
+}
+
diff --git a/frontend/pl_gun_ts.h b/frontend/pl_gun_ts.h
new file mode 100644 (file)
index 0000000..c68272a
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_TSLIB
+
+struct tsdev;
+
+struct tsdev *pl_gun_ts_init(void);
+void pl_gun_ts_update(struct tsdev *ts, int *x, int *y, int *in);
+void pl_set_gun_rect(int x, int y, int w, int h);
+
+#else
+
+#define pl_gun_ts_init() NULL
+#define pl_gun_ts_update(...) do {} while (0)
+
+#endif
index 516e06f..5939dcb 100644 (file)
@@ -18,6 +18,7 @@
 #include "linux/fbdev.h"
 #include "linux/oshide.h"
 #include "plugin_lib.h"
+#include "pl_gun_ts.h"
 #include "omap.h"
 #include "pandora.h"
 
@@ -80,6 +81,9 @@ static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h, in
 
 int omap_enable_layer(int enabled)
 {
+       if (enabled)
+               pl_set_gun_rect(g_layer_x, g_layer_y, g_layer_w, g_layer_h);
+
        return omap_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled,
                g_layer_x, g_layer_y, g_layer_w, g_layer_h, 0);
 }
index 7b0d301..fa4cf21 100644 (file)
@@ -43,9 +43,9 @@ extern void SPUplayCDDAchannel(short *, int);
 /* PAD */
 static long PADreadPort1(PadDataS *pad)
 {
-       pad->controllerType = in_type;
+       pad->controllerType = in_type1;
        pad->buttonStatus = ~in_keystate;
-       if (in_type == PSE_PAD_TYPE_ANALOGPAD) {
+       if (in_type1 == PSE_PAD_TYPE_ANALOGPAD) {
                pad->leftJoyX = in_a1[0];
                pad->leftJoyY = in_a1[1];
                pad->rightJoyX = in_a2[0];
@@ -56,7 +56,7 @@ static long PADreadPort1(PadDataS *pad)
 
 static long PADreadPort2(PadDataS *pad)
 {
-       pad->controllerType = PSE_PAD_TYPE_STANDARD;
+       pad->controllerType = in_type2;
        pad->buttonStatus = ~in_keystate >> 16;
        return 0;
 }
index 8d5605f..bde4f9c 100644 (file)
 #include "menu.h"
 #include "main.h"
 #include "pcnt.h"
+#include "pl_gun_ts.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 #include "../libpcsxcore/psemu_plugin_defs.h"
 
 void *pl_fbdev_buf;
 int pl_frame_interval;
-int in_type, in_keystate, in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
+int in_type1, in_type2;
+int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
+int in_keystate, in_state_gun;
+static void *ts;
 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 vsync_usec_time;
 
-static int get_cpu_ticks(void)
+
+static __attribute__((noinline)) int get_cpu_ticks(void)
 {
        static unsigned long last_utime;
        static int fd;
@@ -185,9 +190,12 @@ static void update_input(void)
        unsigned int emu_act;
 
        in_update(actions);
-       if (in_type == PSE_PAD_TYPE_ANALOGPAD)
+       if (in_type1 == PSE_PAD_TYPE_ANALOGPAD)
                in_update_analogs();
        emu_act = actions[IN_BINDTYPE_EMU];
+       in_state_gun = (emu_act & SACTION_GUN_MASK) >> SACTION_GUN_TRIGGER;
+
+       emu_act &= ~SACTION_GUN_MASK;
        if (emu_act) {
                int which = 0;
                for (; !(emu_act & 1); emu_act >>= 1, which++)
@@ -205,6 +213,15 @@ static void update_input(void)
 #endif
 }
 
+void pl_update_gun(int *xn, int *xres, int *y, int *in)
+{
+       if (ts)
+               pl_gun_ts_update(ts, xn, y, in);
+
+       *xres = pl_fbdev_w;
+       *y = *y * pl_fbdev_h >> 10;
+}
+
 #define MAX_LAG_FRAMES 3
 
 #define tvdiff(tv, tv_old) \
@@ -396,3 +413,7 @@ void pl_start_watchdog(void)
                fprintf(stderr, "could not start watchdog: %d\n", ret);
 }
 
+void pl_init(void)
+{
+       ts = pl_gun_ts_init();
+}
index 49894af..759e125 100644 (file)
@@ -17,7 +17,8 @@ enum {
        DKEY_CROSS,
        DKEY_SQUARE,
 };
-extern int in_type, in_keystate, in_a1[2], in_a2[2];
+extern int in_type1, in_type2;
+extern int in_keystate, in_state_gun, in_a1[2], in_a2[2];
 void in_update_analogs(void);
 
 extern void *pl_fbdev_buf;
@@ -30,6 +31,9 @@ void  pl_fbdev_close(void);
 void  pl_text_out16(int x, int y, const char *texto, ...);
 void  pl_start_watchdog(void);
 void *pl_prepare_screenshot(int *w, int *h, int *bpp);
+void  pl_init(void);
+
+void  pl_update_gun(int *xn, int *xres, int *y, int *in);
 
 struct rearmed_cbs {
        void  (*pl_get_layer_pos)(int *x, int *y, int *w, int *h);
index d1b05ac..3926ccd 100644 (file)
@@ -54,8 +54,8 @@ extern "C" {
 
 typedef struct
 {
-       uint32_t        flags;
-       uint32_t        status;
+       unsigned int flags;
+       unsigned int status;
        void*   window;
        unsigned char reserved[100];
 } gpuQueryS;
index 342ac19..6c59b6f 100644 (file)
@@ -18,7 +18,7 @@ static HildonAnimationActor *actor;
 static GtkWidget *window, *drawing;
 
 void *pl_fbdev_buf;
-int in_type = PSE_PAD_TYPE_STANDARD;
+int in_type1 = PSE_PAD_TYPE_STANDARD, in_type2 = PSE_PAD_TYPE_STANDARD;
 int in_keystate, in_a1[2], in_a2[2];
 
 static int keymap[65536];
diff --git a/plugins/dfinput/guncon.c b/plugins/dfinput/guncon.c
new file mode 100644 (file)
index 0000000..b4f103c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * (C) Gražvydas "notaz" Ignotas, 2011
+ *
+ * This work is licensed under the terms of any of these licenses
+ * (at your option):
+ *  - GNU GPL, version 2 or later.
+ *  - GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <string.h>
+#include "main.h"
+
+static unsigned char buf[8];
+
+unsigned char PADpoll_guncon(unsigned char value)
+{
+       if (CurByte == 0) {
+               CurCmd = value;
+               CurByte++;
+               return 0x63;    // regardless of cmd
+       }
+
+       if (CurCmd != 0x42 || CurByte >= 8)
+               return 0xff;    // verified
+
+       return buf[CurByte++];
+}
+
+unsigned char PADstartPoll_guncon(int pad)
+{
+       int x, xn = 0, y = 0, in = 0, xres = 256;
+       CurByte = 0;
+
+       buf[2] = buf[3] = 0xff;
+       pl_update_gun(&xn, &xres, &y, &in);
+
+       // while y = const + line counter, what is x?
+       // for 256 mode, hw dumped offsets x, y: 0x5a, 0x20
+       //x = 0x5a + (356 * xn >> 10);
+       x = 0x5a - (xres - 256) / 3 + (((xres - 256) / 3 + 356) * xn >> 10);
+       y = 0x20 + y;
+
+       if (in & GUNIN_TRIGGER)
+               buf[3] &= ~0x20;
+       if (in & GUNIN_BTNA)
+               buf[2] &= ~0x08;
+       if (in & GUNIN_BTNB)
+               buf[3] &= ~0x40;
+       if (in & GUNIN_TRIGGER2) {
+               buf[3] &= ~0x20;
+               x = 1;
+               y = 10;
+       }
+       buf[4] = x;
+       buf[5] = x >> 8;
+       buf[6] = y;
+       buf[7] = y >> 8;
+
+       return 0xff;
+}
+
+void guncon_init(void)
+{
+       memset(buf, 0xff, sizeof(buf));
+       buf[1] = 0x5a;
+}
+
diff --git a/plugins/dfinput/main.c b/plugins/dfinput/main.c
new file mode 100644 (file)
index 0000000..73b2bda
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * (C) Gražvydas "notaz" Ignotas, 2011
+ *
+ * This work is licensed under the terms of any of these licenses
+ * (at your option):
+ *  - GNU GPL, version 2 or later.
+ *  - GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "main.h"
+
+unsigned char CurPad, CurByte, CurCmd, CmdLen;
+
+/* since this is not a proper plugin, so we'll hook emu internals in a hackish way like this */
+extern void *PAD1_startPoll, *PAD1_poll;
+extern void *PAD2_startPoll, *PAD2_poll;
+extern unsigned char PAD1__startPoll(int pad);
+extern unsigned char PAD2__startPoll(int pad);
+extern unsigned char PAD1__poll(unsigned char value);
+extern unsigned char PAD2__poll(unsigned char value);
+
+static int old_controller_type1 = -1, old_controller_type2 = -1;
+
+#define select_pad(n) \
+       if (pad.controllerType != old_controller_type##n) \
+       { \
+               switch (pad.controllerType) \
+               { \
+               case PSE_PAD_TYPE_ANALOGPAD: \
+                       PAD##n##_startPoll = PADstartPoll_pad; \
+                       PAD##n##_poll = PADpoll_pad; \
+                       pad_init(); \
+                       break; \
+               case PSE_PAD_TYPE_GUNCON: \
+                       PAD##n##_startPoll = PADstartPoll_guncon; \
+                       PAD##n##_poll = PADpoll_guncon; \
+                       guncon_init(); \
+                       break; \
+               case PSE_PAD_TYPE_GUN: \
+               default: \
+                       PAD##n##_startPoll = PAD##n##__startPoll; \
+                       PAD##n##_poll = PAD##n##__poll; \
+                       break; \
+               } \
+       }
+
+void dfinput_activate(void)
+{
+       PadDataS pad;
+
+       PAD1_readPort1(&pad);
+       select_pad(1);
+
+       PAD2_readPort2(&pad);
+       select_pad(2);
+}
diff --git a/plugins/dfinput/main.h b/plugins/dfinput/main.h
new file mode 100644 (file)
index 0000000..ee30165
--- /dev/null
@@ -0,0 +1,26 @@
+#include "../../libpcsxcore/psemu_plugin_defs.h"
+
+extern unsigned char CurPad, CurByte, CurCmd, CmdLen;
+
+/* analog pad */
+unsigned char PADpoll_pad(unsigned char value);
+unsigned char PADstartPoll_pad(int pad);
+void pad_init(void);
+
+/* GunCon */
+unsigned char PADpoll_guncon(unsigned char value);
+unsigned char PADstartPoll_guncon(int pad);
+void guncon_init(void);
+
+void dfinput_activate(void);
+
+/* get button state and pad type from main emu */
+extern long (*PAD1_readPort1)(PadDataS *pad);
+extern long (*PAD2_readPort2)(PadDataS *pad);
+
+/* get gunstate from emu frontend, x range 0-1023 */
+#define GUNIN_TRIGGER  (1<<0)
+#define GUNIN_BTNA     (1<<1)
+#define GUNIN_BTNB     (1<<2)
+#define GUNIN_TRIGGER2 (1<<3)  /* offscreen trigger */
+extern void pl_update_gun(int *xn, int *xres, int *y, int *in);
index 9a09563..90fde88 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdint.h>
 
 #include "../../libpcsxcore/psemu_plugin_defs.h"
+#include "main.h"
 
 enum {
        ANALOG_LEFT = 0,
@@ -102,7 +103,6 @@ static uint8_t stdmodel[2][8] = {
         0x00}
 };
 
-static uint8_t CurPad = 0, CurByte = 0, CurCmd = 0, CmdLen = 0;
 static uint8_t *buf;
 
 static uint8_t do_cmd(void)
@@ -206,7 +206,18 @@ static void do_cmd2(unsigned char value)
        }
 }
 
-static unsigned char PADpoll_(unsigned char value) {
+#if 0
+#include <stdio.h>
+unsigned char PADpoll_(unsigned char value);
+unsigned char PADpoll(unsigned char value) {
+       unsigned char b = CurByte, r = PADpoll_(value);
+       printf("poll[%d] %02x %02x\n", b, value, r);
+       return r;
+}
+#define PADpoll PADpoll_
+#endif
+
+unsigned char PADpoll_pad(unsigned char value) {
 
        if (CurByte == 0) {
                CurCmd = value;
@@ -228,57 +239,27 @@ static unsigned char PADpoll_(unsigned char value) {
        return buf[CurByte++];
 }
 
-#if 0
-#include <stdio.h>
-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;
-}
-#else
-#define PADpoll PADpoll_
-#endif
-
-/* hack.. */
-extern long (*PAD1_readPort1)(PadDataS *pad);
-
-static unsigned char PADstartPoll1(int pad) {
-       CurPad = 0;
+unsigned char PADstartPoll_pad(int pad) {
+       CurPad = pad - 1;
        CurByte = 0;
 
-       PAD1_readPort1(&padstate[0].pad);
+       if (pad == 1)
+               PAD1_readPort1(&padstate[0].pad);
+       else
+               PAD2_readPort2(&padstate[1].pad);
 
        return 0xFF;
 }
 
-/* some more hacks here but oh well */
-extern void *PAD1_startPoll, *PAD1_poll;
-
-void dfinput_activate(int yes)
+void pad_init(void)
 {
-       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;
+       int i;
 
        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;
+       PAD2_readPort2(&padstate[1].pad);
 
-       padstate[1].PadID = 0x41;
-       padstate[1].PadMode = 0;
+       for (i = 0; i < 2; i++) {
+               padstate[i].PadID = padstate[i].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD ? 0x73 : 0x41;
+               padstate[i].PadMode = padstate[i].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD;
+       }
 }
-
diff --git a/plugins/dfinput/pad.h b/plugins/dfinput/pad.h
deleted file mode 100644 (file)
index 60a46f0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-void dfinput_activate(int yes);
-