1 /* gameplaySP - pandora backend
3 * Copyright (C) 2011 notaz <notasas@gmail.com>
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.
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.
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
20 #include "../common.h"
21 #include <X11/keysym.h>
22 #include "linux/omapfb.h" //
23 #include <sys/types.h>
26 #include <sys/ioctl.h>
28 #include "../arm/neon_scale2x.h"
29 #include "../arm/neon_scale3x.h"
30 #include "../arm/neon_eagle2x.h"
31 #include "linux/fbdev.h"
32 #include "linux/xenv.h"
54 u32 button_plat_mask_to_config[PLAT_BUTTON_COUNT] =
75 u32 gamepad_config_map[PLAT_BUTTON_COUNT] =
78 BUTTON_ID_LEFT, // Left
79 BUTTON_ID_DOWN, // Down
80 BUTTON_ID_RIGHT, // Right
81 BUTTON_ID_START, // Start
82 BUTTON_ID_SELECT, // Select
83 BUTTON_ID_L, // Ltrigger
84 BUTTON_ID_R, // Rtrigger
89 BUTTON_ID_SAVESTATE, // 1
90 BUTTON_ID_LOADSTATE, // 2
91 BUTTON_ID_FASTFORWARD, // 3
93 BUTTON_ID_MENU // Space
96 static const u32 xk_to_gkey[] = {
97 XK_Up, XK_Left, XK_Down, XK_Right, XK_Alt_L, XK_Control_L,
98 XK_Shift_R, XK_Control_R, XK_Home, XK_End, XK_Page_Down, XK_Page_Up,
99 XK_1, XK_2, XK_3, XK_4, XK_space,
102 static const u8 gkey_to_cursor[32] = {
103 [0 ... 31] = CURSOR_NONE,
104 [0] = CURSOR_UP, CURSOR_LEFT, CURSOR_DOWN, CURSOR_RIGHT, CURSOR_NONE, CURSOR_NONE,
105 CURSOR_L, CURSOR_R, CURSOR_SELECT, CURSOR_SELECT, CURSOR_EXIT, CURSOR_BACK,
108 struct vout_fbdev *fb;
109 static void *fb_current;
110 static int bounce_buf[400 * 272 * 2 / 4];
111 static int src_w = 240, src_h = 160;
112 static enum software_filter {
119 // (240*3 * 160*3 * 2 * 3)
120 #define MAX_VRAM_SIZE (400*2 * 272*2 * 2 * 3)
123 static int omap_setup_layer(int fd, int enabled, int x, int y, int w, int h)
125 struct omapfb_plane_info pi = { 0, };
126 struct omapfb_mem_info mi = { 0, };
129 ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
131 perror("QUERY_PLANE");
135 ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);
141 /* must disable when changing stuff */
144 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
146 perror("SETUP_PLANE");
149 /* alloc enough for 3x scaled tripple buffering */
150 if (mi.size < MAX_VRAM_SIZE) {
151 mi.size = MAX_VRAM_SIZE;
152 ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
163 pi.enabled = enabled;
165 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
167 perror("SETUP_PLANE");
174 void gpsp_plat_init(void)
177 const char *layer_fb_name;
179 ret = SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE);
181 fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
185 layer_fb_name = getenv("FBDEV_LAYER");
186 if (layer_fb_name == NULL)
187 layer_fb_name = "/dev/fb1";
191 fprintf(stderr, "xenv_init failed with %d\n", ret);
195 // must set the layer up first to be able to use it
196 fd = open(layer_fb_name, O_RDWR);
198 fprintf(stderr, "%s: ", layer_fb_name);
203 ret = omap_setup_layer(fd, 0, 0, 0, 400, 272);
206 fprintf(stderr, "failed to set up layer, exiting.\n");
210 // double of original menu size
213 fb = vout_fbdev_init("/dev/fb1", &w, &h, 16, 3);
215 fprintf(stderr, "vout_fbdev_init failed\n");
219 // default to 3x scale
223 void gpsp_plat_quit(void)
226 omap_setup_layer(vout_fbdev_get_fd(fb), 0, 0, 0, 0, 0);
227 vout_fbdev_finish(fb);
231 u32 gpsp_plat_joystick_read(void)
233 static int gkeystate;
237 key = xenv_update(&is_down);
238 for (i = 0; i < sizeof(xk_to_gkey) / sizeof(xk_to_gkey[0]); i++) {
239 if (key == xk_to_gkey[i]) {
247 gkeystate |= 1 << gkey;
249 gkeystate &= ~(1 << gkey);
255 u32 gpsp_plat_buttons_to_cursor(u32 buttons)
262 for (i = 0; (buttons & 1) == 0; i++, buttons >>= 1)
265 return gkey_to_cursor[i];
268 static void set_filter(int is_filtered)
270 static int was_filtered = -1;
273 if (is_filtered == was_filtered)
276 snprintf(buf, sizeof(buf), "sudo -n /usr/pandora/scripts/op_videofir.sh %s",
277 is_filtered ? "default" : "none");
279 was_filtered = is_filtered;
282 void *fb_flip_screen(void)
284 void *ret = bounce_buf;
285 void *s = bounce_buf;
288 case SWFILTER_SCALE2X:
289 neon_scale2x_16_16(s, fb_current, src_w, src_w*2, src_w*2*2, src_h);
291 case SWFILTER_SCALE3X:
292 neon_scale3x_16_16(s, fb_current, src_w, src_w*2, src_w*3*2, src_h);
294 case SWFILTER_EAGLE2X:
295 neon_eagle2x_16_16(s, fb_current, src_w, src_w*2, src_w*2*2, src_h);
302 fb_current = vout_fbdev_flip(fb);
303 if (sw_filter == SWFILTER_NONE)
309 void fb_wait_vsync(void)
311 vout_fbdev_wait_vsync(fb);
314 void fb_set_mode(int w, int h, int buffers, int scale,
315 int filter, int filter2)
317 int lx, ly, lw = w, lh = h;
342 fprintf(stderr, "unknown scale: %d\n", scale);
349 lx = 800 / 2 - lw / 2;
350 ly = 480 / 2 - lh / 2;
352 omap_setup_layer(vout_fbdev_get_fd(fb), 1, lx, ly, lw, lh);
356 if (w != 240) // menu
357 sw_filter = SWFILTER_SCALE2X;
360 case SWFILTER_SCALE2X:
363 case SWFILTER_SCALE3X:
366 case SWFILTER_EAGLE2X:
375 fb_current = vout_fbdev_resize(fb, w * multiplier, h * multiplier,
376 16, 0, 0, 0, 0, buffers);
381 // vim:shiftwidth=2:expandtab