fix goofed up L key
[gpsp.git] / pandora / pnd.c
CommitLineData
eb3668fc 1/* gameplaySP - pandora backend
2 *
3 * Copyright (C) 2011 notaz <notasas@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (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 GNU
13 * 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, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include "../common.h"
21#include <X11/keysym.h>
22#include "linux/omapfb.h" //
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <sys/ioctl.h>
27
28#include "linux/fbdev.h"
29#include "linux/xenv.h"
30
31enum gpsp_key {
32 GKEY_UP = 1 << 0,
33 GKEY_LEFT = 1 << 1,
34 GKEY_DOWN = 1 << 2,
35 GKEY_RIGHT = 1 << 3,
36 GKEY_START = 1 << 4,
37 GKEY_SELECT = 1 << 5,
38 GKEY_L = 1 << 6,
39 GKEY_R = 1 << 7,
40 GKEY_A = 1 << 8,
41 GKEY_B = 1 << 9,
42 GKEY_X = 1 << 10,
43 GKEY_Y = 1 << 11,
44 GKEY_1 = 1 << 12,
45 GKEY_2 = 1 << 13,
46 GKEY_3 = 1 << 14,
47 GKEY_4 = 1 << 15,
48 GKEY_MENU = 1 << 16,
49};
50
51u32 button_plat_mask_to_config[PLAT_BUTTON_COUNT] =
52{
53 GKEY_UP,
54 GKEY_LEFT,
55 GKEY_DOWN,
56 GKEY_RIGHT,
57 GKEY_START,
58 GKEY_SELECT,
59 GKEY_L,
60 GKEY_R,
61 GKEY_A,
62 GKEY_B,
63 GKEY_X,
64 GKEY_Y,
65 GKEY_1,
66 GKEY_2,
67 GKEY_3,
68 GKEY_4,
69 GKEY_MENU,
70};
71
72u32 gamepad_config_map[PLAT_BUTTON_COUNT] =
73{
74 BUTTON_ID_UP, // Up
75 BUTTON_ID_LEFT, // Left
76 BUTTON_ID_DOWN, // Down
77 BUTTON_ID_RIGHT, // Right
78 BUTTON_ID_START, // Start
79 BUTTON_ID_SELECT, // Select
80 BUTTON_ID_L, // Ltrigger
81 BUTTON_ID_R, // Rtrigger
82 BUTTON_ID_FPS, // A
83 BUTTON_ID_A, // B
84 BUTTON_ID_B, // X
85 BUTTON_ID_MENU, // Y
86 BUTTON_ID_SAVESTATE, // 1
87 BUTTON_ID_LOADSTATE, // 2
88 BUTTON_ID_FASTFORWARD, // 3
89 BUTTON_ID_NONE, // 4
90 BUTTON_ID_MENU // Space
91};
92
93static const u32 xk_to_gkey[] = {
94 XK_Up, XK_Left, XK_Down, XK_Right, XK_Alt_L, XK_Control_L,
931b76c0 95 XK_Shift_R, XK_Control_R, XK_Home, XK_End, XK_Page_Down, XK_Page_Up,
eb3668fc 96 XK_1, XK_2, XK_3, XK_4, XK_space,
97};
98
99static const u8 gkey_to_cursor[32] = {
100 [0 ... 31] = CURSOR_NONE,
101 [0] = CURSOR_UP, CURSOR_LEFT, CURSOR_DOWN, CURSOR_RIGHT, CURSOR_NONE, CURSOR_NONE,
102 CURSOR_L, CURSOR_R, CURSOR_SELECT, CURSOR_SELECT, CURSOR_EXIT, CURSOR_BACK,
103};
104
105struct vout_fbdev *fb;
106
107static int omap_setup_layer(int fd, int enabled, int x, int y, int w, int h, int first_call)
108{
109 struct omapfb_plane_info pi = { 0, };
110 struct omapfb_mem_info mi = { 0, };
111 int ret;
112
113 ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
114 if (ret != 0) {
115 perror("QUERY_PLANE");
116 return -1;
117 }
118
119 ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);
120 if (ret != 0) {
121 perror("QUERY_MEM");
122 return -1;
123 }
124
125 /* must disable when changing stuff */
126 if (pi.enabled) {
127 pi.enabled = 0;
128 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
129 if (ret != 0)
130 perror("SETUP_PLANE");
131 }
132
133 if (first_call) {
134 mi.size = 640*512*3*3;
135 ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
136 if (ret != 0) {
137 perror("SETUP_MEM");
138 return -1;
139 }
140 }
141
142 pi.pos_x = x;
143 pi.pos_y = y;
144 pi.out_width = w;
145 pi.out_height = h;
146 pi.enabled = enabled;
147
148 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
149 if (ret != 0) {
150 perror("SETUP_PLANE");
151 return -1;
152 }
153
154 return 0;
155}
156
157void gpsp_plat_init(void)
158{
159 int ret, w, h, fd;
160 const char *layer_fb_name;
161
162 ret = SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE);
163 if (ret != 0) {
164 fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
165 exit(1);
166 }
167
168 layer_fb_name = getenv("FBDEV_LAYER");
169 if (layer_fb_name == NULL)
170 layer_fb_name = "/dev/fb1";
171
172 ret = xenv_init();
173 if (ret != 0) {
174 fprintf(stderr, "xenv_init failed with %d\n", ret);
175 exit(1);
176 }
177
178 // must set the layer up first to be able to use it
179 fd = open(layer_fb_name, O_RDWR);
180 if (fd == -1) {
181 fprintf(stderr, "%s: ", layer_fb_name);
182 perror("open");
183 exit(1);
184 }
185
186 ret = omap_setup_layer(fd, 0, 0, 0, 400, 272, 1);
187 close(fd);
188 if (ret != 0) {
189 fprintf(stderr, "failed to set up layer, exiting.\n");
190 exit(1);
191 }
192
193 w = 240;
194 h = 160;
195 fb = vout_fbdev_init("/dev/fb1", &w, &h, 16, 4);
196 if (fb == NULL) {
197 fprintf(stderr, "vout_fbdev_init failed\n");
198 exit(1);
199 }
200
201 // default to 3x scale
202 screen_scale = 2;
203}
204
205void gpsp_plat_quit(void)
206{
207 xenv_finish();
208 omap_setup_layer(vout_fbdev_get_fd(fb), 0, 0, 0, 0, 0, 0);
209 vout_fbdev_finish(fb);
210 SDL_Quit();
211}
212
213u32 gpsp_plat_joystick_read(void)
214{
215 static int gkeystate;
216 int key, is_down, i;
217 int gkey = -1;
218
219 key = xenv_update(&is_down);
220 for (i = 0; i < sizeof(xk_to_gkey) / sizeof(xk_to_gkey[0]); i++) {
221 if (key == xk_to_gkey[i]) {
222 gkey = i;
223 break;
224 }
225 }
226
227 if (gkey >= 0) {
228 if (is_down)
229 gkeystate |= 1 << gkey;
230 else
231 gkeystate &= ~(1 << gkey);
232 }
233
234 return gkeystate;
235}
236
237u32 gpsp_plat_buttons_to_cursor(u32 buttons)
238{
239 int i;
240
241 if (buttons == 0)
242 return CURSOR_NONE;
243
244 for (i = 0; (buttons & 1) == 0; i++, buttons >>= 1)
245 ;
246
247 return gkey_to_cursor[i];
248}
249
250static void set_filter(int is_filtered)
251{
252 static int was_filtered = -1;
253 char buf[128];
254
255 if (is_filtered == was_filtered)
256 return;
257
258 snprintf(buf, sizeof(buf), "sudo -n /usr/pandora/scripts/op_videofir.sh %s",
259 is_filtered ? "default" : "none");
260 system(buf);
261 was_filtered = is_filtered;
262}
263
264void *fb_flip_screen(void)
265{
266 return vout_fbdev_flip(fb);
267}
268
269void fb_wait_vsync(void)
270{
271 vout_fbdev_wait_vsync(fb);
272}
273
274void fb_set_mode(int w, int h, int buffers, int scale, int filter)
275{
276 int lx, ly, lw = w, lh = h;
277 switch (scale) {
278 case 0:
279 lw = w;
280 lh = h;
281 break;
282 case 1:
283 lw = w * 2;
284 lh = h * 2;
285 break;
286 case 2:
287 lw = w * 3;
288 lh = h * 3;
289 break;
290 case 3:
291 lw = 800;
292 lh = 480;
293 break;
294 case 15:
295 lw = w * 2;
296 lh = h + h /2;
297 break;
298 default:
299 fprintf(stderr, "unknown scale: %d\n", scale);
300 break;
301 }
302 if (lw > 800)
303 lw = 800;
304 if (lh > 480)
305 lh = 480;
306 lx = 800 / 2 - lw / 2;
307 ly = 480 / 2 - lh / 2;
308
309 omap_setup_layer(vout_fbdev_get_fd(fb), 1, lx, ly, lw, lh, 0);
310 set_filter(filter);
311
312 vout_fbdev_resize(fb, w, h, 16, 0, 0, 0, 0, buffers);
313}
314
315// vim:shiftwidth=2:expandtab