1 /* RetroArch - A frontend for libretro.
2 * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3 * Copyright (C) 2011-2017 - Daniel De Matteis
4 *
5 * RetroArch is free software: you can redistribute it and/or modify it under the terms
6 * of the GNU General Public License as published by the Free Software Found-
7 * ation, either version 3 of the License, or (at your option) any later version.
8 *
9 * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along with RetroArch.
14 * If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <stdint.h>
18 #include <string.h>
19
20 #include "../../config.def.h"
21
22 #include "../input_driver.h"
23
24 #include "../../tasks/tasks_internal.h"
25
26 #include "../../configuration.h"
27
28 #include <defines/psp_defines.h>
29
30 #ifdef HAVE_MENU
31 #include "../../menu/menu_driver.h"
32 #endif
33
34 #if defined(VITA)
35 #include <psp2/kernel/sysmem.h>
36 #include <psp2/ctrl.h>
37 #include <psp2/touch.h>
38
39 /* TODO/FIXME - static globals */
40 static int psp2_model;
41 static SceCtrlPortInfo old_ctrl_info, curr_ctrl_info;
42 static SceCtrlActuator actuators[DEFAULT_MAX_PADS] = {0};
43
44 #define LERP(p, f, t) ((((p * 10) * (t * 10)) / (f * 10)) / 10)
45 #define AREA(lx, ly, rx, ry, x, y) (lx <= x && x < rx && ly <= y && y < ry)
46 #define TOUCH_MAX_WIDTH 1919
47 #define TOUCH_MAX_HEIGHT 1087
48 #define SCREEN_WIDTH PSP_FB_WIDTH
49 #define SCREEN_HEIGHT PSP_FB_HEIGHT
50 #define SCREEN_HALF_WIDTH SCREEN_WIDTH / 2
51 #define SCREEN_HALF_HEIGHT SCREEN_HEIGHT / 2
52 #define NW_AREA(x, y) AREA(0, 0, SCREEN_HALF_WIDTH, SCREEN_HALF_HEIGHT, (x), (y))
53 #define NE_AREA(x, y) AREA(SCREEN_HALF_WIDTH, 0, SCREEN_WIDTH, SCREEN_HALF_HEIGHT, (x), (y))
54 #define SW_AREA(x, y) AREA(0, SCREEN_HALF_HEIGHT, SCREEN_HALF_WIDTH, SCREEN_HEIGHT, (x), (y))
55 #define SE_AREA(x, y) AREA(SCREEN_HALF_WIDTH, SCREEN_HALF_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, (x), (y))
56 #endif
57
58 /* TODO/FIXME - static globals */
59 static uint64_t pad_state[DEFAULT_MAX_PADS];
60 static int16_t analog_state[DEFAULT_MAX_PADS][2][2];
61
62 /* TODO/FIXME - global referenced outside */
63 extern uint64_t lifecycle_state;
64
psp_joypad_name(unsigned pad)65 static const char *psp_joypad_name(unsigned pad)
66 {
67 #ifdef VITA
68 if (psp2_model != SCE_KERNEL_MODEL_VITATV)
69 return "Vita Controller";
70
71 switch (curr_ctrl_info.port[pad + 1])
72 {
73 case SCE_CTRL_TYPE_DS3:
74 return "DS3 Controller";
75 case SCE_CTRL_TYPE_DS4:
76 return "DS4 Controller";
77 default:
78 break;
79 }
80 return "Unpaired";
81 #else
82 return "PSP Controller";
83 #endif
84 }
85
psp_joypad_init(void * data)86 static void *psp_joypad_init(void *data)
87 {
88 unsigned i;
89 unsigned players_count = DEFAULT_MAX_PADS;
90
91 #if defined(VITA)
92 psp2_model = sceCtrlIsMultiControllerSupported()? SCE_KERNEL_MODEL_VITATV : SCE_KERNEL_MODEL_VITA;
93
94 if (psp2_model != SCE_KERNEL_MODEL_VITATV)
95 players_count = 1;
96 if (sceKernelGetModelForCDialog() != SCE_KERNEL_MODEL_VITATV)
97 {
98 sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK,
99 SCE_TOUCH_SAMPLING_STATE_START);
100 sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT,
101 SCE_TOUCH_SAMPLING_STATE_START);
102 }
103 sceCtrlGetControllerPortInfo(&curr_ctrl_info);
104 memcpy(&old_ctrl_info, &curr_ctrl_info, sizeof(SceCtrlPortInfo));
105 #endif
106
107 for (i = 0; i < players_count; i++)
108 input_autoconfigure_connect(
109 psp_joypad_name(i),
110 NULL,
111 psp_joypad.ident,
112 i,
113 0,
114 0
115 );
116
117 return (void*)-1;
118 }
119
psp_joypad_button(unsigned port,uint16_t joykey)120 static int16_t psp_joypad_button(unsigned port, uint16_t joykey)
121 {
122 if (port >= DEFAULT_MAX_PADS)
123 return 0;
124 return pad_state[port] & (UINT64_C(1) << joykey);
125 }
126
psp_joypad_get_buttons(unsigned port,input_bits_t * state)127 static void psp_joypad_get_buttons(unsigned port, input_bits_t *state)
128 {
129 if (port < DEFAULT_MAX_PADS)
130 {
131 BITS_COPY16_PTR( state, pad_state[port] );
132 }
133 else
134 BIT256_CLEAR_ALL_PTR(state);
135 }
136
psp_joypad_axis_state(unsigned port,uint32_t joyaxis)137 static int16_t psp_joypad_axis_state(unsigned port, uint32_t joyaxis)
138 {
139 int val = 0;
140 int axis = -1;
141 bool is_neg = false;
142 bool is_pos = false;
143
144 if (AXIS_NEG_GET(joyaxis) < 4)
145 {
146 axis = AXIS_NEG_GET(joyaxis);
147 is_neg = true;
148 }
149 else if (AXIS_POS_GET(joyaxis) < 4)
150 {
151 axis = AXIS_POS_GET(joyaxis);
152 is_pos = true;
153 }
154 else
155 return 0;
156
157 switch (axis)
158 {
159 case 0:
160 case 1:
161 val = analog_state[port][0][axis];
162 break;
163 case 2:
164 case 3:
165 val = analog_state[port][1][axis - 2];
166 break;
167 }
168
169 if (is_neg && val > 0)
170 return 0;
171 else if (is_pos && val < 0)
172 return 0;
173 return val;
174 }
175
psp_joypad_axis(unsigned port,uint32_t joyaxis)176 static int16_t psp_joypad_axis(unsigned port, uint32_t joyaxis)
177 {
178 if (port >= DEFAULT_MAX_PADS)
179 return 0;
180 return psp_joypad_axis_state(port, joyaxis);
181 }
182
psp_joypad_state(rarch_joypad_info_t * joypad_info,const struct retro_keybind * binds,unsigned port)183 static int16_t psp_joypad_state(
184 rarch_joypad_info_t *joypad_info,
185 const struct retro_keybind *binds,
186 unsigned port)
187 {
188 unsigned i;
189 int16_t ret = 0;
190 uint16_t port_idx = joypad_info->joy_idx;
191
192 if (port_idx >= DEFAULT_MAX_PADS)
193 return 0;
194
195 for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++)
196 {
197 /* Auto-binds are per joypad, not per user. */
198 const uint64_t joykey = (binds[i].joykey != NO_BTN)
199 ? binds[i].joykey : joypad_info->auto_binds[i].joykey;
200 const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE)
201 ? binds[i].joyaxis : joypad_info->auto_binds[i].joyaxis;
202 if (
203 (uint16_t)joykey != NO_BTN
204 && (pad_state[port_idx] & (UINT64_C(1) << (uint16_t)joykey))
205 )
206 ret |= ( 1 << i);
207 else if (joyaxis != AXIS_NONE &&
208 ((float)abs(psp_joypad_axis_state(port_idx, joyaxis))
209 / 0x8000) > joypad_info->axis_threshold)
210 ret |= (1 << i);
211 }
212
213 return ret;
214 }
215
psp_joypad_poll(void)216 static void psp_joypad_poll(void)
217 {
218 unsigned player;
219 unsigned players_count = DEFAULT_MAX_PADS;
220 #if defined(VITA)
221 settings_t *settings = config_get_ptr();
222 bool input_backtouch_enable = settings->bools.input_backtouch_enable;
223 bool input_backtouch_toggle = settings->bools.input_backtouch_toggle;
224 #endif
225
226 #ifdef PSP
227 sceCtrlSetSamplingCycle(0);
228 #endif
229
230 #ifdef VITA
231 if (psp2_model != SCE_KERNEL_MODEL_VITATV)
232 players_count = 1;
233 else
234 {
235 sceCtrlGetControllerPortInfo(&curr_ctrl_info);
236 for (player = 0; player < players_count; player++)
237 {
238 if (old_ctrl_info.port[player + 1] == curr_ctrl_info.port[player + 1])
239 continue;
240
241 if (old_ctrl_info.port[player + 1] != SCE_CTRL_TYPE_UNPAIRED &&
242 curr_ctrl_info.port[player + 1] == SCE_CTRL_TYPE_UNPAIRED)
243 {
244 memset(&actuators[player], 0, sizeof(SceCtrlActuator));
245 input_autoconfigure_disconnect(player, psp_joypad.ident);
246 }
247
248 if (old_ctrl_info.port[player + 1] == SCE_CTRL_TYPE_UNPAIRED &&
249 curr_ctrl_info.port[player + 1] != SCE_CTRL_TYPE_UNPAIRED)
250 input_autoconfigure_connect(
251 psp_joypad_name(player),
252 NULL,
253 psp_joypad.ident,
254 player,
255 0,
256 0
257 );
258 }
259 memcpy(&old_ctrl_info, &curr_ctrl_info, sizeof(SceCtrlPortInfo));
260 }
261 #endif
262
263 CtrlSetSamplingMode(DEFAULT_SAMPLING_MODE);
264
265 BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);
266
267 for (player = 0; player < players_count; player++)
268 {
269 unsigned j, k;
270 SceCtrlData state_tmp;
271 unsigned i = player;
272 #if defined(VITA)
273 unsigned p = (psp2_model == SCE_KERNEL_MODEL_VITATV)
274 ? player + 1 : player;
275 if (curr_ctrl_info.port[p] == SCE_CTRL_TYPE_UNPAIRED)
276 continue;
277 #elif defined(SN_TARGET_PSP2)
278 /* Dumb hack, but here's the explanation -
279 * sceCtrlPeekBufferPositive's port parameter
280 * can be 0 or 1 to read the first controller on
281 * a PSTV, but HAS to be 0 for a real VITA and 2
282 * for the 2nd controller on a PSTV */
283 unsigned p = (player > 0) ? player+1 : player;
284 #else
285 unsigned p = player;
286 #endif
287 int32_t ret = CtrlPeekBufferPositive(p, &state_tmp, 1);
288
289 pad_state[i] = 0;
290 analog_state[i][0][0] = analog_state[i][0][1] =
291 analog_state[i][1][0] = analog_state[i][1][1] = 0;
292
293 #if defined(SN_TARGET_PSP2) || defined(VITA)
294 if (ret < 0)
295 continue;
296 #endif
297 #if defined(VITA)
298 if (sceKernelGetModelForCDialog() == SCE_KERNEL_MODEL_VITA
299 && input_backtouch_enable)
300 {
301 unsigned i;
302 SceTouchData touch_surface = {0};
303 sceTouchPeek(input_backtouch_toggle
304 ? SCE_TOUCH_PORT_FRONT
305 : SCE_TOUCH_PORT_BACK,
306 &touch_surface, 1);
307
308 for (i = 0; i < touch_surface.reportNum; i++)
309 {
310 int x = LERP(touch_surface.report[i].x,
311 TOUCH_MAX_WIDTH, SCREEN_WIDTH);
312 int y = LERP(touch_surface.report[i].y,
313 TOUCH_MAX_HEIGHT, SCREEN_HEIGHT);
314 if (NW_AREA(x, y))
315 state_tmp.buttons |= PSP_CTRL_L2;
316 if (NE_AREA(x, y))
317 state_tmp.buttons |= PSP_CTRL_R2;
318 if (SW_AREA(x, y))
319 state_tmp.buttons |= PSP_CTRL_L3;
320 if (SE_AREA(x, y))
321 state_tmp.buttons |= PSP_CTRL_R3;
322 }
323 }
324 #endif
325 #ifdef HAVE_KERNEL_PRX
326 state_tmp.Buttons = (state_tmp.Buttons & 0x0000FFFF)
327 | (read_system_buttons() & 0xFFFF0000);
328 #endif
329
330 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_LEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
331 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_DOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
332 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_RIGHT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
333 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_UP) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
334 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_START) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0;
335 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_SELECT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0;
336 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_TRIANGLE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0;
337 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_SQUARE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0;
338 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_CROSS) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0;
339 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_CIRCLE) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0;
340 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_R) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0;
341 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_L) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0;
342 #if defined(VITA)
343 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_R2) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0;
344 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_L2) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0;
345 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_R3) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R3) : 0;
346 pad_state[i] |= (STATE_BUTTON(state_tmp) & PSP_CTRL_L3) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L3) : 0;
347 #endif
348
349 analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = (int16_t)(STATE_ANALOGLX(state_tmp)-128) * 256;
350 analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = (int16_t)(STATE_ANALOGLY(state_tmp)-128) * 256;
351 #if defined(SN_TARGET_PSP2) || defined(VITA)
352 analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = (int16_t)(STATE_ANALOGRX(state_tmp)-128) * 256;
353 analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = (int16_t)(STATE_ANALOGRY(state_tmp)-128) * 256;
354 #endif
355
356 #ifdef HAVE_KERNEL_PRX
357 if (STATE_BUTTON(state_tmp) & PSP_CTRL_NOTE)
358 BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
359 #endif
360
361 for (j = 0; j < 2; j++)
362 for (k = 0; k < 2; k++)
363 if (analog_state[i][j][k] == -0x8000)
364 analog_state[i][j][k] = -0x7fff;
365 }
366 }
367
psp_joypad_query_pad(unsigned pad)368 static bool psp_joypad_query_pad(unsigned pad)
369 {
370 return pad < DEFAULT_MAX_PADS && pad_state[pad];
371 }
372
psp_joypad_rumble(unsigned pad,enum retro_rumble_effect effect,uint16_t strength)373 static bool psp_joypad_rumble(unsigned pad,
374 enum retro_rumble_effect effect, uint16_t strength)
375 {
376 #ifdef VITA
377 if (psp2_model != SCE_KERNEL_MODEL_VITATV)
378 return false;
379 if(pad >= DEFAULT_MAX_PADS)
380 return false;
381 switch (effect)
382 {
383 case RETRO_RUMBLE_WEAK:
384 switch (curr_ctrl_info.port[pad + 1])
385 {
386 case SCE_CTRL_TYPE_DS3:
387 actuators[pad].small = strength > 1 ? 1 : 0;
388 break;
389 case SCE_CTRL_TYPE_DS4:
390 actuators[pad].small = LERP(strength, 0xffff, 0xff);
391 break;
392 default:
393 actuators[pad].small = 0;
394 }
395 break;
396 case RETRO_RUMBLE_STRONG:
397 switch (curr_ctrl_info.port[pad + 1])
398 {
399 case SCE_CTRL_TYPE_DS3:
400 actuators[pad].large = strength > 1 ? LERP(strength, 0xffff, 0xbf) + 0x40 : 0;
401 break;
402 case SCE_CTRL_TYPE_DS4:
403 actuators[pad].large = LERP(strength, 0xffff, 0xff);
404 break;
405 default:
406 actuators[pad].large = 0;
407 }
408 break;
409 case RETRO_RUMBLE_DUMMY:
410 default:
411 break;
412 }
413 sceCtrlSetActuator(pad + 1, &actuators[pad]);
414
415 return true;
416 #else
417 return false;
418 #endif
419 }
420
psp_joypad_destroy(void)421 static void psp_joypad_destroy(void)
422 {
423 }
424
425 input_device_driver_t psp_joypad = {
426 psp_joypad_init,
427 psp_joypad_query_pad,
428 psp_joypad_destroy,
429 psp_joypad_button,
430 psp_joypad_state,
431 psp_joypad_get_buttons,
432 psp_joypad_axis,
433 psp_joypad_poll,
434 psp_joypad_rumble,
435 psp_joypad_name,
436 #ifdef VITA
437 "vita",
438 #else
439 "psp",
440 #endif
441 };
442