2 * Copyright (c) 2009, Wei Mingzhi <whistler@openoffice.org>.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses>.
18 * this is only pure emulation code to handle analogs,
19 * extracted from dfinput.
24 #include "../../libpcsxcore/psemu_plugin_defs.h"
34 CMD_READ_DATA_AND_VIBRATE = 0x42,
35 CMD_CONFIG_MODE = 0x43,
36 CMD_SET_MODE_AND_LOCK = 0x44,
37 CMD_QUERY_MODEL_AND_MODE = 0x45,
38 CMD_QUERY_ACT = 0x46, // ??
39 CMD_QUERY_COMB = 0x47, // ??
40 CMD_QUERY_MODE = 0x4C, // QUERY_MODE ??
41 CMD_VIBRATION_TOGGLE = 0x4D,
51 static uint8_t stdpar[2][8] = {
52 {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80},
53 {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}
56 static uint8_t unk46[2][8] = {
57 {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A},
58 {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}
61 static uint8_t unk47[2][8] = {
62 {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00},
63 {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}
66 static uint8_t unk4c[2][8] = {
67 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
68 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
71 static uint8_t unk4d[2][8] = {
72 {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
73 {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
76 static uint8_t stdcfg[2][8] = {
77 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
78 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
81 static uint8_t stdmode[2][8] = {
82 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
83 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
86 static uint8_t stdmodel[2][8] = {
89 0x01, // 03 - dualshock2, 01 - dualshock
90 0x02, // number of modes
91 0x01, // current mode: 01 - analog, 00 - digital
97 0x01, // 03 - dualshock2, 01 - dualshock
98 0x02, // number of modes
99 0x01, // current mode: 01 - analog, 00 - digital
105 static uint8_t CurPad = 0, CurByte = 0, CurCmd = 0, CmdLen = 0;
108 static uint8_t do_cmd(void)
110 PadDataS *pad = &padstate[CurPad].pad;
111 int pad_num = CurPad;
115 case CMD_SET_MODE_AND_LOCK:
116 buf = stdmode[pad_num];
119 case CMD_QUERY_MODEL_AND_MODE:
120 buf = stdmodel[pad_num];
121 buf[4] = padstate[pad_num].PadMode;
125 buf = unk46[pad_num];
129 buf = unk47[pad_num];
133 buf = unk4c[pad_num];
136 case CMD_VIBRATION_TOGGLE:
137 buf = unk4d[pad_num];
140 case CMD_CONFIG_MODE:
141 if (padstate[pad_num].ConfigMode) {
142 buf = stdcfg[pad_num];
147 case CMD_READ_DATA_AND_VIBRATE:
149 buf = stdpar[pad_num];
151 buf[2] = pad->buttonStatus;
152 buf[3] = pad->buttonStatus >> 8;
154 if (padstate[pad_num].PadMode == 1) {
155 buf[4] = pad->rightJoyX;
156 buf[5] = pad->rightJoyY;
157 buf[6] = pad->leftJoyX;
158 buf[7] = pad->leftJoyY;
163 return padstate[pad_num].PadID;
167 static void do_cmd2(unsigned char value)
170 case CMD_CONFIG_MODE:
171 padstate[CurPad].ConfigMode = value;
174 case CMD_SET_MODE_AND_LOCK:
175 padstate[CurPad].PadMode = value;
176 padstate[CurPad].PadID = value ? 0x73 : 0x41;
187 case 1: // Param std conf change
197 case 0: // mode 0 - digital mode
198 buf[5] = PSE_PAD_TYPE_STANDARD;
201 case 1: // mode 1 - analog mode
202 buf[5] = PSE_PAD_TYPE_ANALOGPAD;
209 static unsigned char PADpoll_(unsigned char value) {
215 // Don't enable Analog/Vibration for a standard pad
216 if (padstate[CurPad].pad.controllerType != PSE_PAD_TYPE_ANALOGPAD)
217 CurCmd = CMD_READ_DATA_AND_VIBRATE;
225 if (CurByte >= CmdLen)
228 return buf[CurByte++];
233 static unsigned char PADpoll(unsigned char value) {
234 unsigned char b = CurByte, r = PADpoll_(value);
235 printf("poll[%d] %02x %02x\n", b, value, r);
239 #define PADpoll PADpoll_
243 extern long (*PAD1_readPort1)(PadDataS *pad);
245 static unsigned char PADstartPoll1(int pad) {
249 PAD1_readPort1(&padstate[0].pad);
254 /* some more hacks here but oh well */
255 extern void *PAD1_startPoll, *PAD1_poll;
257 void dfinput_activate(int yes)
259 static void *old_start, *old_poll;
262 if (PAD1_startPoll == PADstartPoll1)
263 PAD1_startPoll = old_start;
264 if (PAD1_poll == PADpoll)
265 PAD1_poll = old_poll;
269 if (PAD1_startPoll == PADstartPoll1 && PAD1_poll == PADpoll)
272 old_start = PAD1_startPoll;
273 old_poll = PAD1_poll;
274 PAD1_startPoll = PADstartPoll1;
277 PAD1_readPort1(&padstate[0].pad);
278 padstate[0].PadID = padstate[0].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD ? 0x73 : 0x41;
279 padstate[0].PadMode = padstate[0].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD;
281 padstate[1].PadID = 0x41;
282 padstate[1].PadMode = 0;