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