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 <stdlib.h>
19 
20 #ifndef __PSL1GHT__
21 #include <sdk_version.h>
22 #endif
23 
24 #include <boolean.h>
25 #include <libretro.h>
26 
27 #ifdef HAVE_CONFIG_H
28 #include "../../config.h"
29 #endif
30 
31 #include <defines/ps3_defines.h>
32 
33 #include "../input_driver.h"
34 
35 #ifdef HAVE_MOUSE
36 #ifndef MAX_MICE
37 #define MAX_MICE 7
38 #endif
39 #endif
40 
41 /* TODO/FIXME -
42  * fix game focus toggle */
43 
44 typedef struct
45 {
46    float x;
47    float y;
48    float z;
49 } sensor_t;
50 
51 typedef struct ps3_input
52 {
53 #ifdef HAVE_MOUSE
54    unsigned mice_connected;
55 #else
56    void *empty;
57 #endif
58 } ps3_input_t;
59 
60 #ifdef HAVE_MOUSE
ps3_input_poll(void * data)61 static void ps3_input_poll(void *data)
62 {
63    CellMouseInfo mouse_info;
64    ps3_input_t *ps3 = (ps3_input_t*)data;
65 
66    cellMouseGetInfo(&mouse_info);
67    ps3->mice_connected = mouse_info.now_connect;
68 }
69 
ps3_mouse_device_state(ps3_input_t * ps3,unsigned user,unsigned id)70 static int16_t ps3_mouse_device_state(ps3_input_t *ps3,
71       unsigned user, unsigned id)
72 {
73    CellMouseData mouse_state;
74    cellMouseGetData(id, &mouse_state);
75 
76    if (!ps3->mice_connected)
77       return 0;
78 
79    switch (id)
80    {
81       /* TODO: mouse wheel up/down */
82       case RETRO_DEVICE_ID_MOUSE_LEFT:
83          return (mouse_state.buttons & CELL_MOUSE_BUTTON_1);
84       case RETRO_DEVICE_ID_MOUSE_RIGHT:
85          return (mouse_state.buttons & CELL_MOUSE_BUTTON_2);
86       case RETRO_DEVICE_ID_MOUSE_X:
87          return (mouse_state.x_axis);
88       case RETRO_DEVICE_ID_MOUSE_Y:
89          return (mouse_state.y_axis);
90    }
91 
92    return 0;
93 }
94 #endif
95 
ps3_input_state(void * data,const input_device_driver_t * joypad,const input_device_driver_t * sec_joypad,rarch_joypad_info_t * joypad_info,const struct retro_keybind ** binds,bool keyboard_mapping_blocked,unsigned port,unsigned device,unsigned idx,unsigned id)96 static int16_t ps3_input_state(
97       void *data,
98       const input_device_driver_t *joypad,
99       const input_device_driver_t *sec_joypad,
100       rarch_joypad_info_t *joypad_info,
101       const struct retro_keybind **binds,
102       bool keyboard_mapping_blocked,
103       unsigned port,
104       unsigned device,
105       unsigned idx,
106       unsigned id)
107 {
108    ps3_input_t *ps3           = (ps3_input_t*)data;
109 
110    if (!ps3)
111       return 0;
112 
113    switch (device)
114    {
115       case RETRO_DEVICE_JOYPAD:
116       case RETRO_DEVICE_ANALOG:
117          break;
118 #if 0
119       case RETRO_DEVICE_SENSOR_ACCELEROMETER:
120          switch (id)
121          {
122             /* Fixed range of 0x000 - 0x3ff */
123             case RETRO_DEVICE_ID_SENSOR_ACCELEROMETER_X:
124                return ps3->accelerometer_state[port].x;
125             case RETRO_DEVICE_ID_SENSOR_ACCELEROMETER_Y:
126                return ps3->accelerometer_state[port].y;
127             case RETRO_DEVICE_ID_SENSOR_ACCELEROMETER_Z:
128                return ps3->accelerometer_state[port].z;
129             default:
130                break;
131          }
132          break;
133 #endif
134 #ifdef HAVE_MOUSE
135       case RETRO_DEVICE_MOUSE:
136          return ps3_mouse_device_state(data, port, id);
137 #endif
138    }
139 
140    return 0;
141 }
142 
ps3_input_free_input(void * data)143 static void ps3_input_free_input(void *data)
144 {
145    ps3_input_t *ps3 = (ps3_input_t*)data;
146 
147    if (!ps3)
148       return;
149 
150 #ifdef HAVE_MOUSE
151    cellMouseEnd();
152 #endif
153    free(data);
154 }
155 
ps3_input_init(const char * joypad_driver)156 static void* ps3_input_init(const char *joypad_driver)
157 {
158    ps3_input_t *ps3 = (ps3_input_t*)calloc(1, sizeof(*ps3));
159    if (!ps3)
160       return NULL;
161 
162 #ifdef HAVE_MOUSE
163    cellMouseInit(MAX_MICE);
164 #endif
165 
166    return ps3;
167 }
168 
ps3_input_get_capabilities(void * data)169 static uint64_t ps3_input_get_capabilities(void *data)
170 {
171    return
172 #ifdef HAVE_MOUSE
173       (1 << RETRO_DEVICE_MOUSE)  |
174 #endif
175       (1 << RETRO_DEVICE_JOYPAD) |
176       (1 << RETRO_DEVICE_ANALOG);
177 }
178 
ps3_input_set_sensor_state(void * data,unsigned port,enum retro_sensor_action action,unsigned event_rate)179 static bool ps3_input_set_sensor_state(void *data, unsigned port,
180       enum retro_sensor_action action, unsigned event_rate)
181 {
182    CellPadInfo2 pad_info;
183 
184    switch (action)
185    {
186       case RETRO_SENSOR_ACCELEROMETER_ENABLE:
187          cellPadGetInfo2(&pad_info);
188          if ((pad_info.device_capability[port]
189                   & CELL_PAD_CAPABILITY_SENSOR_MODE)
190                == CELL_PAD_CAPABILITY_SENSOR_MODE)
191          {
192             cellPadSetPortSetting(port, CELL_PAD_SETTING_SENSOR_ON);
193             return true;
194          }
195          break;
196       case RETRO_SENSOR_ACCELEROMETER_DISABLE:
197          cellPadSetPortSetting(port, 0);
198          return true;
199       default:
200          break;
201    }
202 
203    return false;
204 }
205 
206 input_driver_t input_ps3 = {
207    ps3_input_init,
208 #ifdef HAVE_MOUSE
209    ps3_input_poll,
210 #else
211    NULL,                         /* poll */
212 #endif
213    ps3_input_state,
214    ps3_input_free_input,
215    ps3_input_set_sensor_state,
216    NULL,
217    ps3_input_get_capabilities,
218    "ps3",
219 
220    NULL,                         /* grab_mouse */
221    NULL
222 };
223