initial pandora port
[fceu.git] / drivers / pandora / pandora.c
CommitLineData
b054fd77 1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <fcntl.h>
7#include <sys/ioctl.h>
8#include <unistd.h>
9#include <linux/input.h>
10#include <linux/omapfb.h>
11
12#include "../common/platform.h"
13#include "../common/input.h"
14#include "../common/settings.h"
15#include "../common/main.h"
16#include "../common/args.h"
17#include "../../video.h"
18#include "../arm/asmutils.h"
19#include "../libpicofe/input.h"
20#include "../libpicofe/plat.h"
21#include "../libpicofe/menu.h"
22#include "../libpicofe/linux/in_evdev.h"
23#include "../libpicofe/linux/fbdev.h"
24#include "../libpicofe/linux/xenv.h"
25
26static int g_layer_x, g_layer_y, g_layer_w, g_layer_h;
27static struct vout_fbdev *main_fb, *layer_fb;
28static void *layer_buf;
29static int bounce_buf[320 * 241 / 4];
30static unsigned short pal[256];
31
32static const struct in_default_bind in_evdev_defbinds[] = {
33 { KEY_UP, IN_BINDTYPE_PLAYER12, NKEYB_UP },
34 { KEY_DOWN, IN_BINDTYPE_PLAYER12, NKEYB_DOWN },
35 { KEY_LEFT, IN_BINDTYPE_PLAYER12, NKEYB_LEFT },
36 { KEY_RIGHT, IN_BINDTYPE_PLAYER12, NKEYB_RIGHT },
37 { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, NKEYB_B },
38 { KEY_END, IN_BINDTYPE_PLAYER12, NKEYB_A },
39 { KEY_HOME, IN_BINDTYPE_PLAYER12, NKEYB_B_TURBO },
40 { KEY_PAGEUP, IN_BINDTYPE_PLAYER12, NKEYB_A_TURBO },
41 { KEY_LEFTCTRL, IN_BINDTYPE_PLAYER12, NKEYB_SELECT },
42 { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, NKEYB_START },
43 { KEY_SPACE, IN_BINDTYPE_EMU, EACTB_ENTER_MENU },
44 { 0, 0, 0 }
45};
46
47static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h)
48{
49 struct omapfb_plane_info pi = { 0, };
50 struct omapfb_mem_info mi = { 0, };
51 int ret;
52
53 ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
54 if (ret != 0) {
55 perror("QUERY_PLANE");
56 return -1;
57 }
58
59 ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);
60 if (ret != 0) {
61 perror("QUERY_MEM");
62 return -1;
63 }
64
65 /* must disable when changing stuff */
66 if (pi.enabled) {
67 pi.enabled = 0;
68 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
69 if (ret != 0)
70 perror("SETUP_PLANE");
71 }
72
73 if (mi.size < 640*512*3*3) {
74 mi.size = 640*512*3*3;
75 ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
76 if (ret != 0) {
77 perror("SETUP_MEM");
78 return -1;
79 }
80 }
81
82 pi.pos_x = x;
83 pi.pos_y = y;
84 pi.out_width = w;
85 pi.out_height = h;
86 pi.enabled = enabled;
87
88 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
89 if (ret != 0) {
90 perror("SETUP_PLANE");
91 return -1;
92 }
93
94 return 0;
95}
96
97static int omap_enable_layer(int enabled)
98{
99 return omap_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled,
100 g_layer_x, g_layer_y, g_layer_w, g_layer_h);
101}
102
103void platform_init(void)
104{
105 const char *main_fb_name, *layer_fb_name;
106 int fd, ret, w, h;
107
108 memset(&Settings, 0, sizeof(Settings));
109 Settings.frameskip = 0;
110 Settings.sound_rate = 44100;
111 Settings.turbo_rate_add = (8*2 << 24) / 60 + 1; // 8Hz turbofire
112 Settings.gamma = 100;
113 Settings.sstate_confirm = 1;
114
115 main_fb_name = getenv("FBDEV_MAIN");
116 if (main_fb_name == NULL)
117 main_fb_name = "/dev/fb0";
118
119 layer_fb_name = getenv("FBDEV_LAYER");
120 if (layer_fb_name == NULL)
121 layer_fb_name = "/dev/fb1";
122
123 // must set the layer up first to be able to use it
124 fd = open(layer_fb_name, O_RDWR);
125 if (fd == -1) {
126 fprintf(stderr, "%s: ", layer_fb_name);
127 perror("open");
128 exit(1);
129 }
130
131 g_layer_x = 80, g_layer_y = 0;
132 g_layer_w = 640, g_layer_h = 480;
133
134 ret = omap_setup_layer_(fd, 0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);
135 close(fd);
136 if (ret != 0) {
137 fprintf(stderr, "failed to set up layer, exiting.\n");
138 exit(1);
139 }
140
141 xenv_init(NULL, "fceu");
142
143 w = h = 0;
144 main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);
145 if (main_fb == NULL) {
146 fprintf(stderr, "couldn't init fb: %s\n", main_fb_name);
147 exit(1);
148 }
149
150 g_menuscreen_w = w;
151 g_menuscreen_h = h;
152 g_menuscreen_ptr = vout_fbdev_flip(main_fb);
153
154 w = 640;
155 h = 512;
156 layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 3);
157 if (layer_fb == NULL) {
158 fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name);
159 goto fail0;
160 }
161 layer_buf = vout_fbdev_resize(layer_fb, 256, 240, 16,
162 0, 0, 0, 0, 3);
163 if (layer_buf == NULL) {
164 fprintf(stderr, "couldn't get layer buf\n");
165 goto fail1;
166 }
167
168 plat_target_init();
169 omap_enable_layer(1);
170
171 XBuf = (void *)bounce_buf;
172
173 return;
174
175fail1:
176 vout_fbdev_finish(layer_fb);
177fail0:
178 vout_fbdev_finish(main_fb);
179 xenv_finish();
180 exit(1);
181}
182
183void platform_late_init(void)
184{
185 in_evdev_init(in_evdev_defbinds);
186 in_probe();
187 plat_target_setup_input();
188}
189
190/* video */
191void CleanSurface(void)
192{
193 memset(bounce_buf, 0, sizeof(bounce_buf));
194 vout_fbdev_clear(layer_fb);
195}
196
197void KillVideo(void)
198{
199}
200
201int InitVideo(void)
202{
203 CleanSurface();
204
205 srendline = 0;
206 erendline = 239;
207
208 return 1;
209}
210
211// 16: rrrr rggg gg0b bbbb
212void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
213{
214 pal[index] = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
215}
216
217void FCEUD_GetPalette(uint8 index, uint8 *r, uint8 *g, uint8 *b)
218{
219 unsigned int v = pal[index];
220 *r = (v >> 8) & 0xf8;
221 *g = (v >> 3) & 0xfc;
222 *b = v << 3;
223}
224
225void BlitPrepare(int skip)
226{
227 if (skip)
228 return;
229
230 if (eoptions & EO_CLIPSIDES)
231 {
232 int i, *p = bounce_buf + 32/4;
233 for (i = 240; i; i--, p += 320/4)
234 {
235 p[0] = p[1] = p[62] = p[63] = 0;
236 }
237 }
238
239 if (Settings.accurate_mode)
240 {
241 int i, *p = bounce_buf + 32/4;
242 if (srendline > 0)
243 for (i = srendline; i > 0; i--, p += 320/4)
244 memset(p, 0, 256);
245 if (erendline < 239)
246 {
247 int *p = bounce_buf + erendline*320/4 + 32/4;
248 for (i = 239-srendline; i > 0; i--, p += 320/4)
249 memset(p, 0, 256);
250 }
251 }
252}
253
254void BlitScreen(int skip)
255{
256 char *s = (char *)bounce_buf + 32;
257 short *d = (short *)layer_buf;
258 int i;
259
260 if (skip)
261 return;
262
263 for (i = 0; i < 239; i++, d += 256, s += 320)
264 do_clut(d, s, pal, 256);
265
266 layer_buf = vout_fbdev_flip(layer_fb);
267}
268
269void platform_apply_config(void)
270{
271}
272
273void platform_set_volume(int val)
274{
275}
276
277void plat_video_menu_enter(int is_rom_loaded)
278{
279 omap_enable_layer(0);
280}
281
282void plat_video_menu_begin(void)
283{
284}
285
286void plat_video_menu_end(void)
287{
288 g_menuscreen_ptr = vout_fbdev_flip(main_fb);
289}
290
291void plat_video_menu_leave(void)
292{
293 memset(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
294 g_menuscreen_ptr = vout_fbdev_flip(main_fb);
295
296 omap_enable_layer(1);
297}
298
299char *DriverUsage="";
300
301ARGPSTRUCT DriverArgs[]={
302 {0,0,0,0}
303};
304
305void DoDriverArgs(void)
306{
307}
308
309void GetBaseDirectory(char *BaseDirectory)
310{
311 strcpy(BaseDirectory, "fceultra");
312}
313
314void platform_finish(void)
315{
316 omap_enable_layer(0);
317 vout_fbdev_finish(layer_fb);
318 vout_fbdev_finish(main_fb);
319 xenv_finish();
320}