io.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "../libpicofe/menu.h"
  5. #include "../libpicofe/input.h"
  6. #include "../libpicofe/linux/sndout_oss.h"
  7. #include "../common/emu.h"
  8. #include "../common/input_pico.h"
  9. #include "version.h"
  10. #include "log_io.h"
  11. int current_keys;
  12. unsigned char *PicoDraw2FB;
  13. #ifdef FBDEV
  14. #include "fbdev.h"
  15. #else
  16. #include <pthread.h>
  17. #include <semaphore.h>
  18. static int current_bpp = 16;
  19. static int current_pal[256];
  20. static const char *verstring = "PicoDrive " VERSION;
  21. static int scr_changed = 0, scr_w = SCREEN_WIDTH, scr_h = SCREEN_HEIGHT;
  22. /* faking GP2X pad */
  23. enum { GP2X_UP=0x1, GP2X_LEFT=0x4, GP2X_DOWN=0x10, GP2X_RIGHT=0x40,
  24. GP2X_START=1<<8, GP2X_SELECT=1<<9, GP2X_L=1<<10, GP2X_R=1<<11,
  25. GP2X_A=1<<12, GP2X_B=1<<13, GP2X_X=1<<14, GP2X_Y=1<<15,
  26. GP2X_VOL_UP=1<<23, GP2X_VOL_DOWN=1<<22, GP2X_PUSH=1<<27 };
  27. static void key_press_event(int keycode)
  28. {
  29. switch (keycode)
  30. {
  31. case 111:
  32. case 0x62: current_keys |= GP2X_UP; break;
  33. case 116:
  34. case 0x68: current_keys |= GP2X_DOWN; break;
  35. case 113:
  36. case 0x64: current_keys |= GP2X_LEFT; break;
  37. case 114:
  38. case 0x66: current_keys |= GP2X_RIGHT; break;
  39. case 0x24: current_keys |= GP2X_START; break; // enter
  40. case 0x23: current_keys |= GP2X_SELECT;break; // ]
  41. case 0x34: current_keys |= GP2X_A; break; // z
  42. case 0x35: current_keys |= GP2X_X; break; // x
  43. case 0x36: current_keys |= GP2X_B; break; // c
  44. case 0x37: current_keys |= GP2X_Y; break; // v
  45. case 0x27: current_keys |= GP2X_L; break; // s
  46. case 0x28: current_keys |= GP2X_R; break; // d
  47. case 0x29: current_keys |= GP2X_PUSH; break; // f
  48. case 0x18: current_keys |= GP2X_VOL_DOWN;break; // q
  49. case 0x19: current_keys |= GP2X_VOL_UP;break; // w
  50. case 0x2d: log_io_clear(); break; // k
  51. case 0x2e: log_io_dump(); break; // l
  52. case 0x17: { // tab
  53. extern int PicoReset(void);
  54. PicoReset();
  55. break;
  56. }
  57. }
  58. }
  59. static void key_release_event(int keycode)
  60. {
  61. switch (keycode)
  62. {
  63. case 111:
  64. case 0x62: current_keys &= ~GP2X_UP; break;
  65. case 116:
  66. case 0x68: current_keys &= ~GP2X_DOWN; break;
  67. case 113:
  68. case 0x64: current_keys &= ~GP2X_LEFT; break;
  69. case 114:
  70. case 0x66: current_keys &= ~GP2X_RIGHT; break;
  71. case 0x24: current_keys &= ~GP2X_START; break; // enter
  72. case 0x23: current_keys &= ~GP2X_SELECT;break; // ]
  73. case 0x34: current_keys &= ~GP2X_A; break; // z
  74. case 0x35: current_keys &= ~GP2X_X; break; // x
  75. case 0x36: current_keys &= ~GP2X_B; break; // c
  76. case 0x37: current_keys &= ~GP2X_Y; break; // v
  77. case 0x27: current_keys &= ~GP2X_L; break; // s
  78. case 0x28: current_keys &= ~GP2X_R; break; // d
  79. case 0x29: current_keys &= ~GP2X_PUSH; break; // f
  80. case 0x18: current_keys &= ~GP2X_VOL_DOWN;break; // q
  81. case 0x19: current_keys &= ~GP2X_VOL_UP;break; // w
  82. }
  83. }
  84. /* --- */
  85. #include <X11/Xlib.h>
  86. #include <X11/Xutil.h>
  87. static Display *xlib_display;
  88. static Window xlib_window;
  89. static XImage *ximage;
  90. static void ximage_realloc(Display *display, Visual *visual)
  91. {
  92. void *xlib_screen;
  93. XLockDisplay(xlib_display);
  94. if (ximage != NULL)
  95. XDestroyImage(ximage);
  96. ximage = NULL;
  97. xlib_screen = calloc(scr_w * scr_h, 4);
  98. if (xlib_screen != NULL)
  99. ximage = XCreateImage(display, visual, 24, ZPixmap, 0,
  100. xlib_screen, scr_w, scr_h, 32, 0);
  101. if (ximage == NULL)
  102. fprintf(stderr, "failed to alloc ximage\n");
  103. XUnlockDisplay(xlib_display);
  104. }
  105. static void xlib_update(void)
  106. {
  107. Status xstatus;
  108. XLockDisplay(xlib_display);
  109. xstatus = XPutImage(xlib_display, xlib_window, DefaultGC(xlib_display, 0), ximage,
  110. 0, 0, 0, 0, g_screen_width, g_screen_height);
  111. if (xstatus != 0)
  112. fprintf(stderr, "XPutImage %d\n", xstatus);
  113. XUnlockDisplay(xlib_display);
  114. }
  115. static void *xlib_threadf(void *targ)
  116. {
  117. unsigned int width, height, display_width, display_height;
  118. sem_t *sem = targ;
  119. XTextProperty windowName;
  120. Window win;
  121. XEvent report;
  122. Display *display;
  123. Visual *visual;
  124. int screen;
  125. XInitThreads();
  126. xlib_display = display = XOpenDisplay(NULL);
  127. if (display == NULL)
  128. {
  129. fprintf(stderr, "cannot connect to X server %s\n",
  130. XDisplayName(NULL));
  131. sem_post(sem);
  132. return NULL;
  133. }
  134. visual = DefaultVisual(display, 0);
  135. if (visual->class != TrueColor)
  136. {
  137. fprintf(stderr, "cannot handle non true color visual\n");
  138. XCloseDisplay(display);
  139. sem_post(sem);
  140. return NULL;
  141. }
  142. printf("X vendor: %s, rel: %d, display: %s, protocol ver: %d.%d\n", ServerVendor(display),
  143. VendorRelease(display), DisplayString(display), ProtocolVersion(display),
  144. ProtocolRevision(display));
  145. screen = DefaultScreen(display);
  146. ximage_realloc(display, visual);
  147. sem_post(sem);
  148. display_width = DisplayWidth(display, screen);
  149. display_height = DisplayHeight(display, screen);
  150. xlib_window = win = XCreateSimpleWindow(display,
  151. RootWindow(display, screen),
  152. display_width / 2 - scr_w / 2,
  153. display_height / 2 - scr_h / 2,
  154. scr_w + 2, scr_h + 2, 1,
  155. BlackPixel(display, screen),
  156. BlackPixel(display, screen));
  157. XStringListToTextProperty((char **)&verstring, 1, &windowName);
  158. XSetWMName(display, win, &windowName);
  159. XSelectInput(display, win, ExposureMask |
  160. KeyPressMask | KeyReleaseMask |
  161. StructureNotifyMask);
  162. XMapWindow(display, win);
  163. while (1)
  164. {
  165. XNextEvent(display, &report);
  166. switch (report.type)
  167. {
  168. case Expose:
  169. while (XCheckTypedEvent(display, Expose, &report))
  170. ;
  171. xlib_update();
  172. break;
  173. case ConfigureNotify:
  174. width = report.xconfigure.width;
  175. height = report.xconfigure.height;
  176. if (scr_w != width - 2 || scr_h != height - 2) {
  177. scr_w = width - 2;
  178. scr_h = height - 2;
  179. scr_changed = 1;
  180. }
  181. break;
  182. case ButtonPress:
  183. break;
  184. case KeyPress:
  185. key_press_event(report.xkey.keycode);
  186. break;
  187. case KeyRelease:
  188. key_release_event(report.xkey.keycode);
  189. break;
  190. default:
  191. break;
  192. }
  193. }
  194. }
  195. static void xlib_init(void)
  196. {
  197. pthread_t x_thread;
  198. sem_t xlib_sem;
  199. sem_init(&xlib_sem, 0, 0);
  200. pthread_create(&x_thread, NULL, xlib_threadf, &xlib_sem);
  201. pthread_detach(x_thread);
  202. sem_wait(&xlib_sem);
  203. sem_destroy(&xlib_sem);
  204. }
  205. /* --- */
  206. static void realloc_screen(void)
  207. {
  208. int size = scr_w * scr_h * 2;
  209. g_screen_width = g_menuscreen_w = scr_w;
  210. g_screen_height = g_menuscreen_h = scr_h;
  211. g_screen_ptr = realloc(g_screen_ptr, size);
  212. g_menubg_ptr = realloc(g_menubg_ptr, size);
  213. memset(g_screen_ptr, 0, size);
  214. memset(g_menubg_ptr, 0, size);
  215. PicoDraw2FB = g_menubg_ptr;
  216. scr_changed = 0;
  217. }
  218. void plat_video_flip(void)
  219. {
  220. unsigned int *image;
  221. int pixel_count, i;
  222. if (ximage == NULL)
  223. return;
  224. pixel_count = g_screen_width * g_screen_height;
  225. image = (void *)ximage->data;
  226. if (current_bpp == 8)
  227. {
  228. unsigned char *pixels = g_screen_ptr;
  229. int pix;
  230. for (i = 0; i < pixel_count; i++)
  231. {
  232. pix = current_pal[pixels[i]];
  233. image[i] = pix;
  234. }
  235. }
  236. else
  237. {
  238. unsigned short *pixels = g_screen_ptr;
  239. for (i = 0; i < pixel_count; i++)
  240. {
  241. /* in: rrrr rggg gggb bbbb */
  242. /* out: rrrr r000 gggg gg00 bbbb b000 */
  243. image[i] = (pixels[i] << 8) & 0xf80000;
  244. image[i] |= (pixels[i] << 5) & 0x00fc00;
  245. image[i] |= (pixels[i] << 3) & 0x0000f8;
  246. }
  247. }
  248. xlib_update();
  249. if (scr_changed) {
  250. realloc_screen();
  251. ximage_realloc(xlib_display, DefaultVisual(xlib_display, 0));
  252. // propagate new ponters to renderers
  253. plat_video_toggle_renderer(0, 0);
  254. }
  255. }
  256. void plat_video_wait_vsync(void)
  257. {
  258. }
  259. #endif // !FBDEV
  260. void plat_early_init(void)
  261. {
  262. }
  263. void plat_init(void)
  264. {
  265. #ifdef FBDEV
  266. int ret, w, h;
  267. ret = vout_fbdev_init(&w, &h);
  268. if (ret != 0)
  269. exit(1);
  270. g_screen_width = g_menuscreen_w = w;
  271. g_screen_height = g_menuscreen_h = h;
  272. g_menubg_ptr = realloc(g_menubg_ptr, w * g_screen_height * 2);
  273. PicoDraw2FB = g_menubg_ptr;
  274. #else
  275. realloc_screen();
  276. memset(g_screen_ptr, 0, g_screen_width * g_screen_height * 2);
  277. xlib_init();
  278. #endif
  279. // snd
  280. sndout_oss_init();
  281. }
  282. void plat_finish(void)
  283. {
  284. #ifdef FBDEV
  285. vout_fbdev_finish();
  286. #else
  287. free(g_screen_ptr);
  288. #endif
  289. sndout_oss_exit();
  290. }
  291. /* misc */
  292. int mp3_get_bitrate(void *f, int size)
  293. {
  294. return 128;
  295. }
  296. void mp3_start_play(void *f, int pos)
  297. {
  298. }
  299. void mp3_update(int *buffer, int length, int stereo)
  300. {
  301. }
  302. #include <linux/input.h>
  303. struct in_default_bind in_evdev_defbinds[] =
  304. {
  305. /* MXYZ SACB RLDU */
  306. { KEY_UP, IN_BINDTYPE_PLAYER12, 0 },
  307. { KEY_DOWN, IN_BINDTYPE_PLAYER12, 1 },
  308. { KEY_LEFT, IN_BINDTYPE_PLAYER12, 2 },
  309. { KEY_RIGHT, IN_BINDTYPE_PLAYER12, 3 },
  310. { KEY_S, IN_BINDTYPE_PLAYER12, 4 }, /* B */
  311. { KEY_D, IN_BINDTYPE_PLAYER12, 5 }, /* C */
  312. { KEY_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */
  313. { KEY_ENTER, IN_BINDTYPE_PLAYER12, 7 },
  314. { KEY_BACKSLASH, IN_BINDTYPE_EMU, PEVB_MENU },
  315. { 0, 0, 0 }
  316. };