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 | |
27 | enum { |
28 | ANALOG_LEFT = 0, |
29 | ANALOG_RIGHT, |
30 | |
31 | ANALOG_TOTAL |
32 | }; |
33 | |
34 | enum { |
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 | |
45 | static struct { |
46 | uint8_t PadMode; |
47 | uint8_t PadID; |
cdd215d3 |
48 | uint8_t ConfigMode; |
384f5f43 |
49 | PadDataS pad; |
50 | } padstate[2]; |
51 | |
52 | static 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 | |
57 | static 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 | |
62 | static 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 | |
67 | static 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 | |
72 | static 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 | |
77 | static 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 | |
82 | static 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 | |
87 | static 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 |
106 | static uint8_t *buf; |
107 | |
108 | static 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 | |
167 | static 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 |
214 | static 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> |
226 | unsigned char PADpoll_(unsigned char value); |
227 | unsigned 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 | |
235 | unsigned 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 |
261 | unsigned 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 |
273 | void 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 | } |