pandora: fix readme and pxml version
[picodrive.git] / platform / pandora / plat.c
CommitLineData
cff531af 1/*\r
2 * PicoDrive\r
3 * (C) notaz, 2010,2011\r
4 *\r
5 * This work is licensed under the terms of MAME license.\r
6 * See COPYING file in the top-level directory.\r
7 */\r
c7eb229a 8\r
9#include <stdio.h>\r
10#include <unistd.h>\r
c7eb229a 11#include <sys/types.h>\r
12#include <sys/stat.h>\r
13#include <fcntl.h>\r
14#include <sys/ioctl.h>\r
15#include <unistd.h>\r
16#include <linux/fb.h>\r
17#include <linux/omapfb.h>\r
d4d62665 18#include <linux/input.h>\r
c7eb229a 19\r
20#include "../common/emu.h"\r
c7eb229a 21#include "../common/arm_utils.h"\r
d4d62665 22#include "../common/input_pico.h"\r
bac44b18 23#include "../common/keyboard.h"\r
d4d62665 24#include "../common/version.h"\r
25#include "../libpicofe/input.h"\r
26#include "../libpicofe/menu.h"\r
27#include "../libpicofe/plat.h"\r
28#include "../libpicofe/linux/in_evdev.h"\r
29#include "../libpicofe/linux/sndout_oss.h"\r
30#include "../libpicofe/linux/fbdev.h"\r
31#include "../libpicofe/linux/xenv.h"\r
c7eb229a 32#include "plat.h"\r
33#include "asm_utils.h"\r
c7eb229a 34\r
35#include <pico/pico_int.h>\r
36\r
55d7dcb2 37#define LAYER_MEM_SIZE (320*240*2 * 4)\r
38\r
c7eb229a 39static struct vout_fbdev *main_fb, *layer_fb;\r
21ebcfd3 40// g_layer_* - in use, g_layer_c* - configured custom\r
8a407398 41int g_layer_cx = 80, g_layer_cy, g_layer_cw = 640, g_layer_ch = 480;\r
ca980e1b 42int saved_start_line = 0, saved_line_count = 240;\r
43int saved_start_col = 0, saved_col_count = 320;\r
c7eb229a 44static int g_layer_x, g_layer_y;\r
45static int g_layer_w = 320, g_layer_h = 240;\r
8a407398 46static int g_osd_start_x, g_osd_fps_x, g_osd_y, doing_bg_frame;\r
c7eb229a 47\r
d4d62665 48static unsigned char __attribute__((aligned(4))) fb_copy[320 * 240 * 2];\r
d40231e2 49static void *temp_frame;\r
c7eb229a 50const char *renderer_names[] = { NULL };\r
51const char *renderer_names32x[] = { NULL };\r
c7eb229a 52\r
d4d62665 53static struct in_default_bind in_evdev_defbinds[] =\r
54{\r
55 { KEY_UP, IN_BINDTYPE_PLAYER12, GBTN_UP },\r
56 { KEY_DOWN, IN_BINDTYPE_PLAYER12, GBTN_DOWN },\r
57 { KEY_LEFT, IN_BINDTYPE_PLAYER12, GBTN_LEFT },\r
58 { KEY_RIGHT, IN_BINDTYPE_PLAYER12, GBTN_RIGHT },\r
59 { KEY_A, IN_BINDTYPE_PLAYER12, GBTN_A },\r
60 { KEY_S, IN_BINDTYPE_PLAYER12, GBTN_B },\r
61 { KEY_D, IN_BINDTYPE_PLAYER12, GBTN_C },\r
62 { KEY_ENTER, IN_BINDTYPE_PLAYER12, GBTN_START },\r
9db6a544 63 { KEY_R, IN_BINDTYPE_EMU, PEVB_RESET },\r
b011c2af 64 { KEY_F, IN_BINDTYPE_EMU, PEVB_FF },\r
c7074ddb 65 { KEY_BACKSPACE,IN_BINDTYPE_EMU, PEVB_FF },\r
66 { KEY_BACKSLASH,IN_BINDTYPE_EMU, PEVB_MENU },\r
21ebcfd3 67 { KEY_SPACE, IN_BINDTYPE_EMU, PEVB_MENU },\r
c7074ddb 68 { KEY_LEFTCTRL, IN_BINDTYPE_EMU, PEVB_MENU },\r
d4d62665 69 { KEY_HOME, IN_BINDTYPE_PLAYER12, GBTN_A },\r
70 { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, GBTN_B },\r
71 { KEY_END, IN_BINDTYPE_PLAYER12, GBTN_C },\r
72 { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, GBTN_START },\r
c7074ddb 73 { KEY_1, IN_BINDTYPE_EMU, PEVB_STATE_SAVE },\r
74 { KEY_2, IN_BINDTYPE_EMU, PEVB_STATE_LOAD },\r
75 { KEY_3, IN_BINDTYPE_EMU, PEVB_SSLOT_PREV },\r
76 { KEY_4, IN_BINDTYPE_EMU, PEVB_SSLOT_NEXT },\r
77 { KEY_5, IN_BINDTYPE_EMU, PEVB_PICO_PPREV },\r
78 { KEY_6, IN_BINDTYPE_EMU, PEVB_PICO_PNEXT },\r
15cc45c0 79 { KEY_7, IN_BINDTYPE_EMU, PEVB_PICO_STORY },\r
80 { KEY_8, IN_BINDTYPE_EMU, PEVB_PICO_PAD },\r
21ebcfd3 81 { 0, 0, 0 }\r
82};\r
83\r
4e3551a5
PC
84static const struct menu_keymap key_pbtn_map[] =\r
85{\r
86 { KEY_UP, PBTN_UP },\r
87 { KEY_DOWN, PBTN_DOWN },\r
88 { KEY_LEFT, PBTN_LEFT },\r
89 { KEY_RIGHT, PBTN_RIGHT },\r
90 /* Pandora */\r
91 { KEY_END, PBTN_MOK },\r
92 { KEY_PAGEDOWN, PBTN_MBACK },\r
93 { KEY_HOME, PBTN_MA2 },\r
94 { KEY_PAGEUP, PBTN_MA3 },\r
95 { KEY_LEFTCTRL, PBTN_MENU },\r
96 { KEY_RIGHTSHIFT, PBTN_L },\r
97 { KEY_RIGHTCTRL, PBTN_R },\r
98 /* "normal" keyboards */\r
99 { KEY_ENTER, PBTN_MOK },\r
100 { KEY_ESC, PBTN_MBACK },\r
101 { KEY_SEMICOLON, PBTN_MA2 },\r
102 { KEY_APOSTROPHE, PBTN_MA3 },\r
103 { KEY_BACKSLASH, PBTN_MENU },\r
104 { KEY_LEFTBRACE, PBTN_L },\r
105 { KEY_RIGHTBRACE, PBTN_R },\r
106};\r
107\r
108static const struct in_pdata pandora_evdev_pdata = {\r
109 .defbinds = in_evdev_defbinds,\r
110 .key_map = key_pbtn_map,\r
111 .kmap_size = sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0]),\r
112};\r
113\r
c7eb229a 114void pemu_prep_defconfig(void)\r
115{\r
116 defaultConfig.EmuOpt |= EOPT_VSYNC|EOPT_16BPP;\r
92dfd9af 117 defaultConfig.s_PicoOpt |= POPT_EN_MCD_GFX;\r
c7eb229a 118 defaultConfig.scaling = SCALE_2x2_3x2;\r
119}\r
120\r
121void pemu_validate_config(void)\r
122{\r
d4d62665 123 currentConfig.CPUclock = plat_target_cpu_clock_get();\r
c7eb229a 124}\r
125\r
c7eb229a 126static void draw_cd_leds(void)\r
127{\r
128 int old_reg;\r
129 old_reg = Pico_mcd->s68k_regs[0];\r
130\r
dca20eff 131 // 16-bit modes\r
132 unsigned int *p = (unsigned int *)((short *)g_screen_ptr + g_screen_width*2+4);\r
133 unsigned int col_g = (old_reg & 2) ? 0x06000600 : 0;\r
134 unsigned int col_r = (old_reg & 1) ? 0xc000c000 : 0;\r
135 *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += g_screen_width/2 - 12/2;\r
136 *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += g_screen_width/2 - 12/2;\r
137 *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r;\r
138}\r
139\r
140static void draw_pico_ptr(void)\r
141{\r
c87e36d7 142 int up = (PicoPicohw.pen_pos[0]|PicoPicohw.pen_pos[1]) & 0x8000;\r
143 int o = (up ? 0x0000 : 0xffff), _ = (up ? 0xffff : 0x0000);\r
dca20eff 144 int x = pico_pen_x, y = pico_pen_y, pitch = g_screen_ppitch;\r
145 unsigned short *p = (unsigned short *)g_screen_ptr;\r
15cc45c0 146 // storyware pages are actually squished, 2:1\r
147 int h = (pico_inp_mode == 1 ? 160 : saved_line_count);\r
148 if (h < 224) y++;\r
dca20eff 149\r
15cc45c0 150 x = (x * saved_col_count * ((1ULL<<32) / 320 + 1)) >> 32;\r
151 y = (y * h * ((1ULL<<32) / 224 + 1)) >> 32;\r
dca20eff 152 p += (saved_start_col+x) + (saved_start_line+y) * pitch;\r
153\r
15cc45c0 154 p[-pitch-1] ^= o; p[-pitch] ^= _; p[-pitch+1] ^= _; p[-pitch+2] ^= o;\r
155 p[-1] ^= _; p[0] ^= o; p[1] ^= o; p[2] ^= _;\r
156 p[pitch-1] ^= _; p[pitch] ^= o; p[pitch+1] ^= o; p[pitch+2] ^= _;\r
157 p[2*pitch-1]^= o; p[2*pitch]^= _; p[2*pitch+1]^= _; p[2*pitch+2]^= o;\r
c7eb229a 158}\r
159\r
c7eb229a 160void pemu_finalize_frame(const char *fps, const char *notice)\r
161{\r
15cc45c0 162 if (PicoIn.AHW & PAHW_PICO) {\r
163 int h = saved_line_count, w = saved_col_count;\r
164 u16 *pd = g_screen_ptr + saved_start_line*g_screen_ppitch\r
165 + saved_start_col;\r
166\r
167 if (pico_inp_mode)\r
168 emu_pico_overlay(pd, w, h, g_screen_ppitch);\r
169 if (pico_inp_mode /*== 2 || overlay*/)\r
170 draw_pico_ptr();\r
171 }\r
bf61bea0 172 if (notice && notice[0])\r
8a407398 173 emu_osd_text16(2 + g_osd_start_x, g_osd_y, notice);\r
735a987b 174 if (fps && fps[0] && (currentConfig.EmuOpt & EOPT_SHOW_FPS)) {\r
175 const char *p;\r
176 // avoid wrapping when fps is very high\r
177 if (fps[5] != ' ' && (p = strchr(fps, '/')))\r
178 fps = p;\r
179 emu_osd_text16(g_osd_fps_x, g_osd_y, fps);\r
180 }\r
93f9619e 181 if ((PicoIn.AHW & PAHW_MCD) && (currentConfig.EmuOpt & EOPT_EN_CD_LEDS))\r
c7eb229a 182 draw_cd_leds();\r
bac44b18 183 // draw virtual keyboard on display\r
4814d19e 184 if (kbd_mode && currentConfig.keyboard == 1 && vkbd)\r
bac44b18 185 vkbd_draw(vkbd);\r
c7eb229a 186}\r
187\r
188void plat_video_flip(void)\r
189{\r
190 g_screen_ptr = vout_fbdev_flip(layer_fb);\r
41946d70 191 PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
10ef62e3 192\r
193 // XXX: drain OS event queue here, maybe we'll actually use it someday..\r
d4d62665 194 xenv_update(NULL, NULL, NULL, NULL);\r
c7eb229a 195}\r
196\r
bac44b18 197void plat_video_clear_buffers(void)\r
198{\r
199 vout_fbdev_clear(layer_fb);\r
200}\r
201\r
735a987b 202// pnd doesn't use multiple renderers, but we have to handle this since it's\r
203// called on 32x enable and PicoDrawSetOutFormat() sets up the 32x layers\r
c7eb229a 204void plat_video_toggle_renderer(int change, int is_menu)\r
205{\r
735a987b 206 if (!is_menu)\r
207 PicoDrawSetOutFormat(PDF_RGB555, 0);\r
c7eb229a 208}\r
209\r
7f4bfa96 210void plat_video_menu_update(void)\r
211{\r
212}\r
213\r
c7eb229a 214void plat_video_menu_enter(int is_rom_loaded)\r
215{\r
216}\r
217\r
218void plat_video_menu_begin(void)\r
219{\r
c7eb229a 220}\r
221\r
222void plat_video_menu_end(void)\r
223{\r
224 g_menuscreen_ptr = vout_fbdev_flip(main_fb);\r
225}\r
226\r
d4d62665 227void plat_video_menu_leave(void)\r
228{\r
229}\r
230\r
c7eb229a 231void plat_video_wait_vsync(void)\r
232{\r
233 vout_fbdev_wait_vsync(main_fb);\r
234}\r
235\r
236void plat_status_msg_clear(void)\r
237{\r
7c18e34a 238 vout_fbdev_clear_lines(layer_fb, g_osd_y, 8);\r
c7eb229a 239}\r
240\r
241void plat_status_msg_busy_next(const char *msg)\r
242{\r
243 plat_status_msg_clear();\r
244 pemu_finalize_frame("", msg);\r
245 plat_video_flip();\r
246 emu_status_msg("");\r
247 reset_timing = 1;\r
248}\r
249\r
250void plat_status_msg_busy_first(const char *msg)\r
251{\r
252 plat_status_msg_busy_next(msg);\r
253}\r
254\r
95b08943 255void plat_status_msg_busy_done(void)\r
256{\r
257}\r
258\r
c7eb229a 259void plat_update_volume(int has_changed, int is_up)\r
260{\r
45285368 261}\r
c7eb229a 262\r
45285368 263void pemu_forced_frame(int no_scale, int do_emu)\r
264{\r
d40231e2 265 doing_bg_frame = 1;\r
832faed3 266 // making a copy because enabling the layer clears it's mem\r
267 emu_cmn_forced_frame(no_scale, do_emu, fb_copy);\r
d40231e2 268 doing_bg_frame = 0;\r
45285368 269\r
d4d62665 270 g_menubg_src_ptr = fb_copy;\r
c7eb229a 271}\r
272\r
273void pemu_sound_start(void)\r
274{\r
d4d62665 275 emu_sound_start();\r
c7eb229a 276}\r
277\r
278void plat_debug_cat(char *str)\r
279{\r
280}\r
281\r
282static int pnd_setup_layer_(int fd, int enabled, int x, int y, int w, int h)\r
283{\r
284 struct omapfb_plane_info pi;\r
285 struct omapfb_mem_info mi;\r
55d7dcb2 286 int is_enabled;\r
287 int retval = 0;\r
c7eb229a 288 int ret;\r
289\r
290 ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);\r
291 if (ret != 0) {\r
292 perror("QUERY_PLANE");\r
293 return -1;\r
294 }\r
295\r
296 ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);\r
297 if (ret != 0) {\r
298 perror("QUERY_MEM");\r
299 return -1;\r
300 }\r
301\r
302 /* must disable when changing stuff */\r
55d7dcb2 303 is_enabled = pi.enabled;\r
304 if (is_enabled) {\r
c7eb229a 305 pi.enabled = 0;\r
306 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);\r
307 if (ret != 0)\r
308 perror("SETUP_PLANE");\r
55d7dcb2 309 else\r
310 is_enabled = 0;\r
c7eb229a 311 }\r
312\r
55d7dcb2 313 if (mi.size < LAYER_MEM_SIZE) {\r
314 unsigned int size_old = mi.size;\r
315\r
316 mi.size = LAYER_MEM_SIZE;\r
317 ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);\r
318 if (ret != 0) {\r
319 perror("SETUP_MEM");\r
320 fprintf(stderr, "(requested %u, had %u)\n",\r
321 mi.size, size_old);\r
322 return -1;\r
323 }\r
c7eb229a 324 }\r
325\r
326 pi.pos_x = x;\r
327 pi.pos_y = y;\r
328 pi.out_width = w;\r
329 pi.out_height = h;\r
330 pi.enabled = enabled;\r
331\r
332 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);\r
55d7dcb2 333 if (ret == 0) {\r
334 is_enabled = pi.enabled;\r
335 }\r
336 else {\r
c7eb229a 337 perror("SETUP_PLANE");\r
55d7dcb2 338 retval = -1;\r
c7eb229a 339 }\r
340\r
55d7dcb2 341 plat_target_switch_layer(1, is_enabled);\r
342\r
343 return retval;\r
c7eb229a 344}\r
345\r
346int pnd_setup_layer(int enabled, int x, int y, int w, int h)\r
347{\r
ca980e1b 348 // it's not allowed for the layer to be partially offscreen,\r
349 // instead it is faked by emu_video_mode_change()\r
350 if (x < 0) { w += x; x = 0; }\r
351 if (y < 0) { h += y; y = 0; }\r
352 if (x + w > 800) w = 800 - x;\r
353 if (y + h > 480) h = 480 - y;\r
354\r
c7eb229a 355 return pnd_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled, x, y, w, h);\r
356}\r
357\r
358void pnd_restore_layer_data(void)\r
359{\r
739e1043 360 short *t = (short *)fb_copy + 320*240 / 2 + 160;\r
c7eb229a 361\r
362 // right now this is used by menu, which wants to preview something\r
363 // so try to get something on the layer.\r
364 if ((t[0] | t[5] | t[13]) == 0)\r
365 memset32((void *)fb_copy, 0x07000700, sizeof(fb_copy) / 4);\r
366\r
d4d62665 367 memcpy(g_screen_ptr, (void *)fb_copy, 320*240*2);\r
c7eb229a 368 plat_video_flip();\r
369}\r
370\r
d5d17782 371void emu_video_mode_change(int start_line, int line_count, int start_col, int col_count)\r
c7eb229a 372{\r
ca980e1b 373 int fb_w, fb_h = 240, fb_left = 0, fb_right = 0, fb_top = 0, fb_bottom = 0;\r
c7eb229a 374\r
d40231e2 375 if (doing_bg_frame)\r
376 return;\r
377\r
c7eb229a 378 switch (currentConfig.scaling) {\r
379 case SCALE_1x1:\r
ca980e1b 380 g_layer_w = col_count;\r
c7eb229a 381 g_layer_h = fb_h;\r
382 break;\r
383 case SCALE_2x2_3x2:\r
ca980e1b 384 g_layer_w = col_count * (col_count < 320 ? 3 : 2);\r
c7eb229a 385 g_layer_h = fb_h * 2;\r
386 break;\r
387 case SCALE_2x2_2x2:\r
ca980e1b 388 g_layer_w = col_count * 2;\r
c7eb229a 389 g_layer_h = fb_h * 2;\r
390 break;\r
391 case SCALE_FULLSCREEN:\r
392 g_layer_w = 800;\r
393 g_layer_h = 480;\r
394 break;\r
395 case SCALE_CUSTOM:\r
396 g_layer_x = g_layer_cx;\r
397 g_layer_y = g_layer_cy;\r
398 g_layer_w = g_layer_cw;\r
399 g_layer_h = g_layer_ch;\r
400 break;\r
401 }\r
402\r
403 if (currentConfig.scaling != SCALE_CUSTOM) {\r
404 // center the layer\r
405 g_layer_x = 800 / 2 - g_layer_w / 2;\r
406 g_layer_y = 480 / 2 - g_layer_h / 2;\r
407 }\r
408\r
409 switch (currentConfig.scaling) {\r
410 case SCALE_FULLSCREEN:\r
411 case SCALE_CUSTOM:\r
412 fb_top = start_line;\r
ca980e1b 413 fb_h = start_line + line_count;\r
c7eb229a 414 break;\r
415 }\r
ca980e1b 416 fb_w = 320;\r
417 fb_left = start_col;\r
418 fb_right = 320 - (start_col + col_count);\r
419 if (currentConfig.scaling == SCALE_CUSTOM) {\r
420 int right = g_layer_x + g_layer_w;\r
421 int bottom = g_layer_y + g_layer_h;\r
422 if (g_layer_x < 0)\r
423 fb_left += -g_layer_x * col_count / g_menuscreen_w;\r
424 if (g_layer_y < 0)\r
425 fb_top += -g_layer_y * line_count / g_menuscreen_h;\r
426 if (right > g_menuscreen_w)\r
427 fb_right += (right - g_menuscreen_w) * col_count / g_menuscreen_w;\r
428 if (bottom > g_menuscreen_h)\r
429 fb_bottom += (bottom - g_menuscreen_h) * line_count / g_menuscreen_h;\r
430 }\r
431 fb_w -= fb_left + fb_right;\r
432 fb_h -= fb_top + fb_bottom;\r
c7eb229a 433\r
434 pnd_setup_layer(1, g_layer_x, g_layer_y, g_layer_w, g_layer_h);\r
f20ad523 435 vout_fbdev_resize(layer_fb, fb_w, fb_h, 16, fb_left, fb_right, fb_top, fb_bottom, 4, 0);\r
c7eb229a 436 vout_fbdev_clear(layer_fb);\r
bf61bea0 437 plat_video_flip();\r
ca980e1b 438\r
439 g_osd_start_x = start_col;\r
440 g_osd_fps_x = start_col + col_count - 5*8 - 2;\r
441 g_osd_y = fb_top + fb_h - 8;\r
442\r
443 saved_start_line = start_line, saved_line_count = line_count;\r
444 saved_start_col = start_col, saved_col_count = col_count;\r
c7eb229a 445}\r
446\r
d4d62665 447void plat_video_loop_prepare(void)\r
c7eb229a 448{\r
c7eb229a 449 // make sure there is no junk left behind the layer\r
d4d62665 450 memset(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);\r
c7eb229a 451 g_menuscreen_ptr = vout_fbdev_flip(main_fb);\r
452\r
92efe29e 453 PicoDrawSetOutFormat(PDF_RGB555, 0);\r
c7eb229a 454 // emu_video_mode_change will call pnd_setup_layer()\r
d4d62665 455}\r
c7eb229a 456\r
1777b86d 457void plat_show_cursor(int on)\r
458{\r
459}\r
460\r
461int plat_grab_cursor(int on)\r
462{\r
463 return 0;\r
464}\r
465\r
466int plat_has_wm(void)\r
467{\r
468 return 0;\r
469}\r
470\r
d4d62665 471void pemu_loop_prep(void)\r
472{\r
c7eb229a 473 // dirty buffers better go now than during gameplay\r
d9653efd 474 fflush(stdout);\r
475 fflush(stderr);\r
c7eb229a 476 sync();\r
477 sleep(0);\r
c7eb229a 478}\r
479\r
480void pemu_loop_end(void)\r
481{\r
8a407398 482 memset(fb_copy, 0, sizeof(fb_copy));\r
c7eb229a 483 /* do one more frame for menu bg */\r
45285368 484 pemu_forced_frame(0, 1);\r
c7eb229a 485\r
486 pnd_setup_layer(0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);\r
c7eb229a 487}\r
488\r
489void plat_wait_till_us(unsigned int us_to)\r
490{\r
491 unsigned int now;\r
492 signed int diff;\r
493\r
494 now = plat_get_ticks_us();\r
495\r
496 // XXX: need to check NOHZ\r
497 diff = (signed int)(us_to - now);\r
498 if (diff > 10000) {\r
499 //printf("sleep %d\n", us_to - now);\r
500 usleep(diff * 15 / 16);\r
501 now = plat_get_ticks_us();\r
502 //printf(" wake %d\n", (signed)(us_to - now));\r
503 }\r
504/*\r
505 while ((signed int)(us_to - now) > 512) {\r
506 spend_cycles(1024);\r
507 now = plat_get_ticks_us();\r
508 }\r
509*/\r
510}\r
511\r
759c9d38 512void *plat_mem_get_for_drc(size_t size)\r
513{\r
514 return NULL;\r
515}\r
516\r
58fc34b1 517int plat_parse_arg(int argc, char *argv[], int *x)\r
518{\r
519 return 1;\r
520}\r
521\r
c7eb229a 522void plat_early_init(void)\r
523{\r
524}\r
525\r
526void plat_init(void)\r
527{\r
528 const char *main_fb_name, *layer_fb_name;\r
529 int fd, ret, w, h;\r
530\r
531 main_fb_name = getenv("FBDEV_MAIN");\r
532 if (main_fb_name == NULL)\r
533 main_fb_name = "/dev/fb0";\r
534\r
535 layer_fb_name = getenv("FBDEV_LAYER");\r
536 if (layer_fb_name == NULL)\r
537 layer_fb_name = "/dev/fb1";\r
538\r
539 // must set the layer up first to be able to use it\r
540 fd = open(layer_fb_name, O_RDWR);\r
541 if (fd == -1) {\r
542 fprintf(stderr, "%s: ", layer_fb_name);\r
543 perror("open");\r
544 exit(1);\r
545 }\r
546\r
547 ret = pnd_setup_layer_(fd, 0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);\r
548 close(fd);\r
549 if (ret != 0) {\r
550 fprintf(stderr, "failed to set up layer, exiting.\n");\r
551 exit(1);\r
552 }\r
553\r
d4d62665 554 xenv_init(NULL, "PicoDrive " VERSION);\r
c7eb229a 555\r
556 w = h = 0;\r
21ebcfd3 557 main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);\r
c7eb229a 558 if (main_fb == NULL) {\r
559 fprintf(stderr, "couldn't init fb: %s\n", main_fb_name);\r
560 exit(1);\r
561 }\r
562\r
9cdfc191 563 g_menuscreen_w = g_menuscreen_pp = w;\r
d40231e2 564 g_menuscreen_h = h;\r
c7eb229a 565 g_menuscreen_ptr = vout_fbdev_flip(main_fb);\r
566\r
567 w = 320; h = 240;\r
b011c2af 568 layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 4);\r
c7eb229a 569 if (layer_fb == NULL) {\r
570 fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name);\r
571 goto fail0;\r
572 }\r
573\r
574 if (w != g_screen_width || h != g_screen_height) {\r
575 fprintf(stderr, "%dx%d not supported on %s\n", w, h, layer_fb_name);\r
576 goto fail1;\r
577 }\r
578 g_screen_ptr = vout_fbdev_flip(layer_fb);\r
579\r
d40231e2 580 temp_frame = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1);\r
581 if (temp_frame == NULL) {\r
582 fprintf(stderr, "OOM\n");\r
583 goto fail1;\r
584 }\r
c7eb229a 585 g_menubg_ptr = temp_frame;\r
586 g_menubg_src_ptr = temp_frame;\r
587\r
c7eb229a 588 pnd_menu_init();\r
45285368 589\r
55d7dcb2 590 // default ROM path\r
591 strcpy(rom_fname_loaded, "/media");\r
592\r
4e3551a5 593 in_evdev_init(&pandora_evdev_pdata);\r
d4d62665 594 in_probe();\r
595 plat_target_setup_input();\r
596\r
597 sndout_oss_frag_frames = 2;\r
598\r
c7eb229a 599 return;\r
600\r
601fail1:\r
602 vout_fbdev_finish(layer_fb);\r
603fail0:\r
604 vout_fbdev_finish(main_fb);\r
605 exit(1);\r
606}\r
607\r
608void plat_finish(void)\r
609{\r
c7eb229a 610 vout_fbdev_finish(main_fb);\r
10ef62e3 611 xenv_finish();\r
c7eb229a 612\r
613 printf("all done\n");\r
614}\r
615\r