From: notaz <notasas@gmail.com>
Date: Thu, 10 Feb 2011 22:02:11 +0000 (+0200)
Subject: use analog handling from dfinput
X-Git-Tag: r7~36
X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=384f5f43a20879e2553acd17b76e82059092fafb;p=pcsx_rearmed.git

use analog handling from dfinput
---

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 <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
index 00000000..60a46f04
--- /dev/null
+++ b/plugins/dfinput/pad.h
@@ -0,0 +1,2 @@
+void dfinput_activate(int yes);
+