use analog handling from dfinput
authornotaz <notasas@gmail.com>
Thu, 10 Feb 2011 22:02:11 +0000 (00:02 +0200)
committernotaz <notasas@gmail.com>
Thu, 10 Feb 2011 22:02:11 +0000 (00:02 +0200)
Makefile
frontend/menu.c
plugins/dfinput/pad.c [new file with mode: 0644]
plugins/dfinput/pad.h [new file with mode: 0644]

index db8e1f6..89fc2a9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -72,6 +72,10 @@ endif
 plugins/cdrcimg/%.o: CFLAGS += -Wall
 OBJS += plugins/cdrcimg/cdrcimg.o
 
 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"
 # gui
 OBJS += frontend/main.o frontend/plugin.o 
 ifeq "$(USE_GTK)" "1"
index 20d334c..9ebfa86 100644 (file)
@@ -24,6 +24,7 @@
 #include "../libpcsxcore/misc.h"
 #include "../libpcsxcore/cdrom.h"
 #include "../libpcsxcore/psemu_plugin_defs.h"
 #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
 #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);
        }
                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)
 }
 
 void me_update_msg(const char *msg)
diff --git a/plugins/dfinput/pad.c b/plugins/dfinput/pad.c
new file mode 100644 (file)
index 0000000..c522117
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2009, Wei Mingzhi <whistler@openoffice.org>.
+ * 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 <http://www.gnu.org/licenses>.
+ *
+ * this is only pure emulation code to handle analogs,
+ * extracted from dfinput.
+ */
+
+#include <stdint.h>
+
+#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 <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;
+}
+
+/* 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 (file)
index 0000000..60a46f0
--- /dev/null
@@ -0,0 +1,2 @@
+void dfinput_activate(int yes);
+