detect undefined symbols early
[pcsx_rearmed.git] / plugins / dfinput / pad.c
CommitLineData
384f5f43 1/*
2 * Copyright (c) 2009, Wei Mingzhi <whistler@openoffice.org>.
3 * All Rights Reserved.
4 *
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.
9 *
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.
14 *
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>.
17 *
18 * this is only pure emulation code to handle analogs,
19 * extracted from dfinput.
20 */
21
22#include <stdint.h>
23
24#include "../../libpcsxcore/psemu_plugin_defs.h"
4c08b9e7 25#include "main.h"
384f5f43 26
27enum {
28 ANALOG_LEFT = 0,
29 ANALOG_RIGHT,
30
31 ANALOG_TOTAL
32};
33
34enum {
35 CMD_READ_DATA_AND_VIBRATE = 0x42,
36 CMD_CONFIG_MODE = 0x43,
37 CMD_SET_MODE_AND_LOCK = 0x44,
38 CMD_QUERY_MODEL_AND_MODE = 0x45,
39 CMD_QUERY_ACT = 0x46, // ??
40 CMD_QUERY_COMB = 0x47, // ??
41 CMD_QUERY_MODE = 0x4C, // QUERY_MODE ??
42 CMD_VIBRATION_TOGGLE = 0x4D,
43};
44
45static struct {
46 uint8_t PadMode;
47 uint8_t PadID;
cdd215d3 48 uint8_t ConfigMode;
384f5f43 49 PadDataS pad;
50} padstate[2];
51
52static uint8_t stdpar[2][8] = {
53 {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80},
54 {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}
55};
56
57static uint8_t unk46[2][8] = {
58 {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A},
59 {0xFF, 0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}
60};
61
62static uint8_t unk47[2][8] = {
63 {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00},
64 {0xFF, 0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}
65};
66
67static uint8_t unk4c[2][8] = {
68 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
69 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
70};
71
72static uint8_t unk4d[2][8] = {
73 {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
74 {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
75};
76
77static uint8_t stdcfg[2][8] = {
78 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
79 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
80};
81
82static uint8_t stdmode[2][8] = {
83 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
84 {0xFF, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
85};
86
87static uint8_t stdmodel[2][8] = {
88 {0xFF,
89 0x5A,
90 0x01, // 03 - dualshock2, 01 - dualshock
91 0x02, // number of modes
92 0x01, // current mode: 01 - analog, 00 - digital
93 0x02,
94 0x01,
95 0x00},
96 {0xFF,
97 0x5A,
98 0x01, // 03 - dualshock2, 01 - dualshock
99 0x02, // number of modes
100 0x01, // current mode: 01 - analog, 00 - digital
101 0x02,
102 0x01,
103 0x00}
104};
105
384f5f43 106static uint8_t *buf;
107
108static uint8_t do_cmd(void)
109{
110 PadDataS *pad = &padstate[CurPad].pad;
111 int pad_num = CurPad;
112
113 CmdLen = 8;
114 switch (CurCmd) {
384f5f43 115 case CMD_SET_MODE_AND_LOCK:
116 buf = stdmode[pad_num];
117 return 0xF3;
118
119 case CMD_QUERY_MODEL_AND_MODE:
120 buf = stdmodel[pad_num];
121 buf[4] = padstate[pad_num].PadMode;
122 return 0xF3;
123
124 case CMD_QUERY_ACT:
125 buf = unk46[pad_num];
126 return 0xF3;
127
128 case CMD_QUERY_COMB:
129 buf = unk47[pad_num];
130 return 0xF3;
131
132 case CMD_QUERY_MODE:
133 buf = unk4c[pad_num];
134 return 0xF3;
135
136 case CMD_VIBRATION_TOGGLE:
137 buf = unk4d[pad_num];
138 return 0xF3;
139
cdd215d3 140 case CMD_CONFIG_MODE:
141 if (padstate[pad_num].ConfigMode) {
142 buf = stdcfg[pad_num];
143 return 0xF3;
144 }
145 // else FALLTHROUGH
146
384f5f43 147 case CMD_READ_DATA_AND_VIBRATE:
148 default:
149 buf = stdpar[pad_num];
150
151 buf[2] = pad->buttonStatus;
152 buf[3] = pad->buttonStatus >> 8;
153
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;
159 } else {
160 CmdLen = 4;
161 }
162
163 return padstate[pad_num].PadID;
164 }
165}
166
167static void do_cmd2(unsigned char value)
168{
169 switch (CurCmd) {
170 case CMD_CONFIG_MODE:
cdd215d3 171 padstate[CurPad].ConfigMode = value;
384f5f43 172 break;
173
174 case CMD_SET_MODE_AND_LOCK:
175 padstate[CurPad].PadMode = value;
176 padstate[CurPad].PadID = value ? 0x73 : 0x41;
177 break;
178
179 case CMD_QUERY_ACT:
180 switch (value) {
181 case 0: // default
182 buf[5] = 0x02;
183 buf[6] = 0x00;
184 buf[7] = 0x0A;
185 break;
186
187 case 1: // Param std conf change
188 buf[5] = 0x01;
189 buf[6] = 0x01;
190 buf[7] = 0x14;
191 break;
192 }
193 break;
194
195 case CMD_QUERY_MODE:
196 switch (value) {
197 case 0: // mode 0 - digital mode
198 buf[5] = PSE_PAD_TYPE_STANDARD;
199 break;
200
201 case 1: // mode 1 - analog mode
202 buf[5] = PSE_PAD_TYPE_ANALOGPAD;
203 break;
204 }
205 break;
b944a30e 206
207 case CMD_READ_DATA_AND_VIBRATE:
208 if (value == 1 && CurPad == 0 && in_enable_vibration)
3a40ff14 209 plat_trigger_vibrate(0);
b944a30e 210 break;
384f5f43 211 }
212}
213
3a40ff14 214static void do_cmd3(unsigned char value)
215{
216 if (in_enable_vibration && CurCmd == CMD_READ_DATA_AND_VIBRATE && CurPad == 0) {
217 if (value >= 0xf0)
218 plat_trigger_vibrate(1);
219 else if (value > 0x40)
220 plat_trigger_vibrate(0);
221 }
222}
223
4c08b9e7 224#if 0
225#include <stdio.h>
226unsigned char PADpoll_(unsigned char value);
227unsigned char PADpoll(unsigned char value) {
228 unsigned char b = CurByte, r = PADpoll_(value);
229 printf("poll[%d] %02x %02x\n", b, value, r);
230 return r;
231}
232#define PADpoll PADpoll_
233#endif
234
235unsigned char PADpoll_pad(unsigned char value) {
384f5f43 236
3a40ff14 237 switch (CurByte) {
238 case 0:
384f5f43 239 CurCmd = value;
240 CurByte++;
241
242 // Don't enable Analog/Vibration for a standard pad
243 if (padstate[CurPad].pad.controllerType != PSE_PAD_TYPE_ANALOGPAD)
244 CurCmd = CMD_READ_DATA_AND_VIBRATE;
245
246 return do_cmd();
3a40ff14 247 case 2:
384f5f43 248 do_cmd2(value);
3a40ff14 249 break;
250 case 3:
251 do_cmd3(value);
252 break;
253 }
384f5f43 254
255 if (CurByte >= CmdLen)
9c1517da 256 return 0xff; // verified
384f5f43 257
258 return buf[CurByte++];
259}
260
4c08b9e7 261unsigned char PADstartPoll_pad(int pad) {
262 CurPad = pad - 1;
384f5f43 263 CurByte = 0;
264
4c08b9e7 265 if (pad == 1)
266 PAD1_readPort1(&padstate[0].pad);
267 else
268 PAD2_readPort2(&padstate[1].pad);
384f5f43 269
270 return 0xFF;
271}
272
4c08b9e7 273void pad_init(void)
384f5f43 274{
4c08b9e7 275 int i;
384f5f43 276
277 PAD1_readPort1(&padstate[0].pad);
4c08b9e7 278 PAD2_readPort2(&padstate[1].pad);
384f5f43 279
4c08b9e7 280 for (i = 0; i < 2; i++) {
281 padstate[i].PadID = padstate[i].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD ? 0x73 : 0x41;
282 padstate[i].PadMode = padstate[i].pad.controllerType == PSE_PAD_TYPE_ANALOGPAD;
283 }
384f5f43 284}