frontend: initial cheats support
[pcsx_rearmed.git] / frontend / plat_pandora.c
1 /*
2  * (C) notaz, 2011
3  *
4  * This work is licensed under the terms of the GNU GPLv2 or later.
5  * See the COPYING file in the top-level directory.
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <sys/ioctl.h>
15 #include <unistd.h>
16 #include <linux/input.h>
17 #include <dirent.h>
18 #include <errno.h>
19
20 #include "common/input.h"
21 #include "linux/in_evdev.h"
22 #include "plugin_lib.h"
23 #include "plat.h"
24 #include "plat_omap.h"
25 #include "main.h"
26 #include "menu.h"
27
28 static const char * const pandora_gpio_keys[KEY_MAX + 1] = {
29         [0 ... KEY_MAX] = NULL,
30         [KEY_UP]        = "Up",
31         [KEY_LEFT]      = "Left",
32         [KEY_RIGHT]     = "Right",
33         [KEY_DOWN]      = "Down",
34         [KEY_HOME]      = "(A)",
35         [KEY_PAGEDOWN]  = "(X)",
36         [KEY_END]       = "(B)",
37         [KEY_PAGEUP]    = "(Y)",
38         [KEY_RIGHTSHIFT]= "(L)",
39         [KEY_RIGHTCTRL] = "(R)",
40         [KEY_LEFTALT]   = "Start",
41         [KEY_LEFTCTRL]  = "Select",
42         [KEY_MENU]      = "Pandora",
43 };
44
45 static const struct in_default_bind in_evdev_defbinds[] = {
46         { KEY_UP,       IN_BINDTYPE_PLAYER12, DKEY_UP },
47         { KEY_DOWN,     IN_BINDTYPE_PLAYER12, DKEY_DOWN },
48         { KEY_LEFT,     IN_BINDTYPE_PLAYER12, DKEY_LEFT },
49         { KEY_RIGHT,    IN_BINDTYPE_PLAYER12, DKEY_RIGHT },
50         { KEY_PAGEUP,   IN_BINDTYPE_PLAYER12, DKEY_TRIANGLE },
51         { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, DKEY_CROSS },
52         { KEY_END,      IN_BINDTYPE_PLAYER12, DKEY_CIRCLE },
53         { KEY_HOME,     IN_BINDTYPE_PLAYER12, DKEY_SQUARE },
54         { KEY_LEFTALT,  IN_BINDTYPE_PLAYER12, DKEY_START },
55         { KEY_LEFTCTRL, IN_BINDTYPE_PLAYER12, DKEY_SELECT },
56         { KEY_RIGHTSHIFT,IN_BINDTYPE_PLAYER12, DKEY_L1 },
57         { KEY_RIGHTCTRL, IN_BINDTYPE_PLAYER12, DKEY_R1 },
58         { KEY_Q,        IN_BINDTYPE_PLAYER12, DKEY_L2 },
59         { KEY_P,        IN_BINDTYPE_PLAYER12, DKEY_R2 },
60         { KEY_TAB,      IN_BINDTYPE_EMU, SACTION_MINIMIZE },
61         { KEY_SPACE,    IN_BINDTYPE_EMU, SACTION_ENTER_MENU },
62         { KEY_1,        IN_BINDTYPE_EMU, SACTION_SAVE_STATE },
63         { KEY_2,        IN_BINDTYPE_EMU, SACTION_LOAD_STATE },
64         { KEY_3,        IN_BINDTYPE_EMU, SACTION_PREV_SSLOT },
65         { KEY_4,        IN_BINDTYPE_EMU, SACTION_NEXT_SSLOT },
66         { KEY_5,        IN_BINDTYPE_EMU, SACTION_TOGGLE_FSKIP },
67         { KEY_6,        IN_BINDTYPE_EMU, SACTION_SCREENSHOT },
68         { 0, 0, 0 }
69 };
70
71 static const char pnd_script_base[] = "sudo -n /usr/pandora/scripts";
72 static char **pnd_filter_list;
73
74 static void scan_for_filters(void)
75 {
76         struct dirent *ent;
77         int i, count = 0;
78         char **mfilters;
79         char buff[64];
80         DIR *dir;
81
82         dir = opendir("/etc/pandora/conf/dss_fir");
83         if (dir == NULL) {
84                 perror("filter opendir");
85                 return;
86         }
87
88         while (1) {
89                 errno = 0;
90                 ent = readdir(dir);
91                 if (ent == NULL) {
92                         if (errno != 0)
93                                 perror("readdir");
94                         break;
95                 }
96
97                 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
98                         continue;
99
100                 count++;
101         }
102
103         if (count == 0)
104                 return;
105
106         mfilters = calloc(count + 1, sizeof(mfilters[0]));
107         if (mfilters == NULL)
108                 return;
109
110         rewinddir(dir);
111         for (i = 0; (ent = readdir(dir)); ) {
112                 size_t len;
113
114                 if (ent->d_type != DT_REG && ent->d_type != DT_LNK)
115                         continue;
116
117                 len = strlen(ent->d_name);
118
119                 // skip pre-HF5 extra files
120                 if (len >= 3 && strcmp(ent->d_name + len - 3, "_v3") == 0)
121                         continue;
122                 if (len >= 3 && strcmp(ent->d_name + len - 3, "_v5") == 0)
123                         continue;
124
125                 // have to cut "_up_h" for pre-HF5
126                 if (len > 5 && strcmp(ent->d_name + len - 5, "_up_h") == 0)
127                         len -= 5;
128
129                 if (len > sizeof(buff) - 1)
130                         continue;
131
132                 strncpy(buff, ent->d_name, len);
133                 buff[len] = 0;
134                 mfilters[i] = strdup(buff);
135                 if (mfilters[i] != NULL)
136                         i++;
137         }
138         closedir(dir);
139
140         pnd_filter_list = mfilters;
141         menu_set_filter_list((void *)mfilters);
142 }
143
144 int plat_init(void)
145 {
146         int gpiokeys_id;
147
148         plat_omap_init();
149
150         in_evdev_init(in_evdev_defbinds);
151         in_probe();
152         gpiokeys_id = in_name_to_id("evdev:gpio-keys");
153         in_set_config(gpiokeys_id, IN_CFG_KEY_NAMES,
154                       pandora_gpio_keys, sizeof(pandora_gpio_keys));
155         in_set_config(gpiokeys_id, IN_CFG_DEFAULT_DEV, NULL, 0);
156         in_adev[0] = in_name_to_id("evdev:nub0");
157         in_adev[1] = in_name_to_id("evdev:nub1");
158
159         scan_for_filters();
160
161         return 0;
162 }
163
164 void plat_finish(void)
165 {
166         plat_omap_finish();
167 }
168
169 static void apply_lcdrate(int pal)
170 {
171         char buf[128];
172
173         snprintf(buf, sizeof(buf), "%s/op_lcdrate.sh %d",
174                         pnd_script_base, pal ? 50 : 60);
175         system(buf);
176 }
177
178 static void apply_filter(int which)
179 {
180         char buf[128];
181         int i;
182
183         if (pnd_filter_list == NULL)
184                 return;
185
186         for (i = 0; i < which; i++)
187                 if (pnd_filter_list[i] == NULL)
188                         return;
189
190         if (pnd_filter_list[i] == NULL)
191                 return;
192
193         snprintf(buf, sizeof(buf), "%s/op_videofir.sh %s",
194                 pnd_script_base, pnd_filter_list[i]);
195         system(buf);
196 }
197
198 void plat_gvideo_open(int is_pal)
199 {
200         static int old_pal = -1, old_filter = -1;
201
202         if (is_pal != old_pal) {
203                 apply_lcdrate(is_pal);
204                 old_pal = is_pal;
205         }
206         if (filter != old_filter) {
207                 apply_filter(filter);
208                 old_filter = filter;
209         }
210
211         plat_omap_gvideo_open();
212 }
213
214 int plat_cpu_clock_get(void)
215 {
216         FILE *f;
217         int ret = 0;
218         f = fopen("/proc/pandora/cpu_mhz_max", "r");
219         if (f) {
220                 fscanf(f, "%d", &ret);
221                 fclose(f);
222         }
223         return ret;
224 }
225
226 int plat_cpu_clock_apply(int cpu_clock)
227 {
228         char buf[128];
229
230         if (cpu_clock != 0 && cpu_clock != plat_cpu_clock_get()) {
231                 snprintf(buf, sizeof(buf), "unset DISPLAY; echo y | %s/op_cpuspeed.sh %d",
232                          pnd_script_base, cpu_clock);
233                 system(buf);
234         }
235         return 0;
236 }
237
238 int plat_get_bat_capacity(void)
239 {
240         FILE *f;
241         int ret = 0;
242         f = fopen("/sys/class/power_supply/bq27500-0/capacity", "r");
243         if (f) {
244                 fscanf(f, "%d", &ret);
245                 fclose(f);
246         }
247         return ret;
248 }
249
250 void plat_step_volume(int is_up)
251 {
252 }
253
254 void plat_trigger_vibrate(int is_strong)
255 {
256 }
257