main.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /*
  2. * meg4/platform/allegro/main.c
  3. *
  4. * Copyright (C) 2023 bzt
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. * @brief raylib "platform" for the MEG-4
  21. *
  22. */
  23. #define _POSIX_C_SOURCE 199309L /* needed for timespec and nanosleep() */
  24. #include <time.h>
  25. #include "meg4.h"
  26. /* direty hacks to get direct pixel access... */
  27. #define ALLEGRO_SRC
  28. #define ASSERT(x)
  29. #include <allegro5/allegro.h>
  30. #include <allegro5/allegro_audio.h>
  31. #include <allegro5/internal/aintern_bitmap.h>
  32. #define SAMPLES_PER_BUFFER 1024
  33. ALLEGRO_EVENT_QUEUE *queue = NULL;
  34. ALLEGRO_TIMER *timer = NULL;
  35. ALLEGRO_DISPLAY *disp = NULL;
  36. ALLEGRO_BITMAP *screen = NULL;
  37. ALLEGRO_JOYSTICK *controller[4] = { 0 };
  38. ALLEGRO_AUDIO_STREAM *stream = NULL;
  39. int main_w = 0, main_h = 0, win_w, win_h, win_f = 0, audio = 0, main_alt = 0, main_keymap[512];
  40. void main_delay(int msec);
  41. #define meg4_showcursor() al_show_mouse_cursor(disp);
  42. #define meg4_hidecursor() al_hide_mouse_cursor(disp);
  43. #include "../common.h"
  44. /**
  45. * Exit emulator
  46. */
  47. void main_quit(void)
  48. {
  49. main_log(1, "quitting... ");
  50. meg4_poweroff();
  51. if(screen) al_destroy_bitmap(screen);
  52. if(disp) al_destroy_display(disp);
  53. if(timer) al_destroy_timer(timer);
  54. if(queue) al_destroy_event_queue(queue);
  55. if(stream) { al_drain_audio_stream(stream); al_destroy_audio_stream(stream); }
  56. if(audio) al_uninstall_audio();
  57. exit(0);
  58. }
  59. /**
  60. * Create window
  61. */
  62. void main_win(int w, int h, int f)
  63. {
  64. ALLEGRO_BITMAP *icon;
  65. win_f = f;
  66. w = main_w / 320; h = main_h / 200; if(w > h) w = h;
  67. win_w = 320 * w; win_h = 200 * w;
  68. al_set_new_display_flags(ALLEGRO_RESIZABLE);
  69. if((disp = al_create_display(win_w, win_h))) {
  70. al_set_window_constraints(disp, 320, 200, main_w, main_h);
  71. al_set_window_title(disp, "MEG-4");
  72. if((icon = al_create_bitmap(meg4_icons.w, 64))) {
  73. memcpy(icon->memory, meg4_icons.buf, meg4_icons.w * 4 * 64);
  74. al_set_display_icon(disp, icon);
  75. al_destroy_bitmap(icon);
  76. }
  77. }
  78. }
  79. /**
  80. * Toggle fullscreen
  81. */
  82. void main_fullscreen(void)
  83. {
  84. win_f ^= 1;
  85. al_set_display_flag(disp, ALLEGRO_FULLSCREEN_WINDOW, !(al_get_display_flags(disp) & ALLEGRO_FULLSCREEN_WINDOW));
  86. }
  87. /**
  88. * Make window focused
  89. */
  90. void main_focus(void)
  91. {
  92. }
  93. /**
  94. * Mouse movement event callback
  95. */
  96. void main_pointer(int xpos, int ypos)
  97. {
  98. int x, y, w, h, ww, wh, xp = xpos, yp = ypos;
  99. if(!meg4.screen.w || !meg4.screen.h) return;
  100. ww = al_get_display_width(disp); wh = al_get_display_height(disp);
  101. w = ww; h = (int)meg4.screen.h * ww / (int)meg4.screen.w;
  102. if(h > wh) { h = wh; w = (int)meg4.screen.w * wh / (int)meg4.screen.h; }
  103. x = (ww - w) >> 1; y = (wh - h) >> 1;
  104. meg4_setptr(xp < x || !w ? 0 : (xp >= x + w ? meg4.screen.w : (xp - x) * meg4.screen.w / w),
  105. yp < y || !h ? 0 : (yp >= y + h ? meg4.screen.h : (yp - y) * meg4.screen.h / h));
  106. }
  107. /**
  108. * Get text from clipboard (must be freed by caller)
  109. */
  110. char *main_getclipboard(void)
  111. {
  112. /* this returns an allocated buffer */
  113. return (char*)al_get_clipboard_text(disp);
  114. }
  115. /**
  116. * Set text to clipboard
  117. */
  118. void main_setclipboard(char *str)
  119. {
  120. al_set_clipboard_text(disp, (const char*)str);
  121. }
  122. /**
  123. * Show on-screen keyboard
  124. */
  125. void main_osk_show(void)
  126. {
  127. }
  128. /**
  129. * Hide on-screen keyboard
  130. */
  131. void main_osk_hide(void)
  132. {
  133. }
  134. /**
  135. * Delay
  136. */
  137. void main_delay(int msec)
  138. {
  139. struct timespec tv;
  140. tv.tv_sec = 0; tv.tv_nsec = msec * 1000000;
  141. nanosleep(&tv, NULL);
  142. }
  143. /**
  144. * Print program version and copyright
  145. */
  146. void main_hdr(void)
  147. {
  148. printf("\r\nMEG-4 v%s (allegro%u, build %u) by bzt Copyright (C) 2023 GPLv3+\r\n\r\n", meg4ver, ALLEGRO_VERSION, BUILD);
  149. }
  150. /**
  151. * The real main procedure
  152. */
  153. int main(int argc, char **argv)
  154. {
  155. ALLEGRO_MOUSE_STATE state;
  156. ALLEGRO_MONITOR_INFO info;
  157. ALLEGRO_EVENT event;
  158. float *abuf;
  159. int i, w, h, ww, wh, redraw, running = 1;
  160. char **infile = NULL, *fn;
  161. char s[5];
  162. uint8_t *ptr;
  163. uint32_t ver;
  164. #ifdef __WIN32__
  165. char *lng = main_lng;
  166. #else
  167. char *lng = getenv("LANG");
  168. #endif
  169. main_parsecommandline(argc, argv, &lng, &infile);
  170. main_hdr();
  171. for(i = 0; i < 3; i++) printf(" %s\r\n", copyright[i]);
  172. printf("\r\n");
  173. fflush(stdout);
  174. if(!al_init()) {
  175. main_log(0, "unable to initialize allegro");
  176. return 1;
  177. }
  178. ver = al_get_allegro_version();
  179. sprintf(meg4plat, "allegro %u.%u.%u", (ver >> 24) & 0xff, (ver >> 16) & 0xff, (ver >> 8) & 0xff);
  180. al_install_keyboard();
  181. al_install_mouse();
  182. al_install_joystick();
  183. al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
  184. al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
  185. timer = al_create_timer(1.0 / 60.0);
  186. queue = al_create_event_queue();
  187. /* set up keymap */
  188. memset(main_keymap, 0, sizeof(main_keymap));
  189. main_keymap[ALLEGRO_KEY_SPACE] = MEG4_KEY_SPACE;
  190. main_keymap[ALLEGRO_KEY_QUOTE] = MEG4_KEY_APOSTROPHE;
  191. main_keymap[ALLEGRO_KEY_TILDE] = MEG4_KEY_BACKQUOTE;
  192. main_keymap[ALLEGRO_KEY_COMMA] = MEG4_KEY_COMMA;
  193. main_keymap[ALLEGRO_KEY_MINUS] = MEG4_KEY_MINUS;
  194. main_keymap[ALLEGRO_KEY_FULLSTOP] = MEG4_KEY_PERIOD;
  195. main_keymap[ALLEGRO_KEY_SLASH] = MEG4_KEY_SLASH;
  196. main_keymap[ALLEGRO_KEY_0] = MEG4_KEY_0;
  197. main_keymap[ALLEGRO_KEY_1] = MEG4_KEY_1;
  198. main_keymap[ALLEGRO_KEY_2] = MEG4_KEY_2;
  199. main_keymap[ALLEGRO_KEY_3] = MEG4_KEY_3;
  200. main_keymap[ALLEGRO_KEY_4] = MEG4_KEY_4;
  201. main_keymap[ALLEGRO_KEY_5] = MEG4_KEY_5;
  202. main_keymap[ALLEGRO_KEY_6] = MEG4_KEY_6;
  203. main_keymap[ALLEGRO_KEY_7] = MEG4_KEY_7;
  204. main_keymap[ALLEGRO_KEY_8] = MEG4_KEY_8;
  205. main_keymap[ALLEGRO_KEY_9] = MEG4_KEY_9;
  206. main_keymap[ALLEGRO_KEY_SEMICOLON] = MEG4_KEY_SEMICOLON;
  207. main_keymap[ALLEGRO_KEY_EQUALS] = MEG4_KEY_EQUAL;
  208. main_keymap[ALLEGRO_KEY_A] = MEG4_KEY_A;
  209. main_keymap[ALLEGRO_KEY_B] = MEG4_KEY_B;
  210. main_keymap[ALLEGRO_KEY_C] = MEG4_KEY_C;
  211. main_keymap[ALLEGRO_KEY_D] = MEG4_KEY_D;
  212. main_keymap[ALLEGRO_KEY_E] = MEG4_KEY_E;
  213. main_keymap[ALLEGRO_KEY_F] = MEG4_KEY_F;
  214. main_keymap[ALLEGRO_KEY_G] = MEG4_KEY_G;
  215. main_keymap[ALLEGRO_KEY_H] = MEG4_KEY_H;
  216. main_keymap[ALLEGRO_KEY_I] = MEG4_KEY_I;
  217. main_keymap[ALLEGRO_KEY_J] = MEG4_KEY_J;
  218. main_keymap[ALLEGRO_KEY_K] = MEG4_KEY_K;
  219. main_keymap[ALLEGRO_KEY_L] = MEG4_KEY_L;
  220. main_keymap[ALLEGRO_KEY_M] = MEG4_KEY_M;
  221. main_keymap[ALLEGRO_KEY_N] = MEG4_KEY_N;
  222. main_keymap[ALLEGRO_KEY_O] = MEG4_KEY_O;
  223. main_keymap[ALLEGRO_KEY_P] = MEG4_KEY_P;
  224. main_keymap[ALLEGRO_KEY_Q] = MEG4_KEY_Q;
  225. main_keymap[ALLEGRO_KEY_R] = MEG4_KEY_R;
  226. main_keymap[ALLEGRO_KEY_S] = MEG4_KEY_S;
  227. main_keymap[ALLEGRO_KEY_T] = MEG4_KEY_T;
  228. main_keymap[ALLEGRO_KEY_U] = MEG4_KEY_U;
  229. main_keymap[ALLEGRO_KEY_V] = MEG4_KEY_V;
  230. main_keymap[ALLEGRO_KEY_X] = MEG4_KEY_X;
  231. main_keymap[ALLEGRO_KEY_Y] = MEG4_KEY_Y;
  232. main_keymap[ALLEGRO_KEY_Z] = MEG4_KEY_Z;
  233. main_keymap[ALLEGRO_KEY_OPENBRACE] = MEG4_KEY_LBRACKET;
  234. main_keymap[ALLEGRO_KEY_BACKSLASH] = MEG4_KEY_BACKSLASH;
  235. main_keymap[ALLEGRO_KEY_CLOSEBRACE] = MEG4_KEY_RBRACKET;
  236. main_keymap[ALLEGRO_KEY_ENTER] = MEG4_KEY_ENTER;
  237. main_keymap[ALLEGRO_KEY_TAB] = MEG4_KEY_TAB;
  238. main_keymap[ALLEGRO_KEY_BACKSPACE] = MEG4_KEY_BACKSPACE;
  239. main_keymap[ALLEGRO_KEY_INSERT] = MEG4_KEY_INS;
  240. main_keymap[ALLEGRO_KEY_DELETE] = MEG4_KEY_DEL;
  241. main_keymap[ALLEGRO_KEY_RIGHT] = MEG4_KEY_RIGHT;
  242. main_keymap[ALLEGRO_KEY_LEFT] = MEG4_KEY_LEFT;
  243. main_keymap[ALLEGRO_KEY_DOWN] = MEG4_KEY_DOWN;
  244. main_keymap[ALLEGRO_KEY_UP] = MEG4_KEY_UP;
  245. main_keymap[ALLEGRO_KEY_PGUP] = MEG4_KEY_PGUP;
  246. main_keymap[ALLEGRO_KEY_PGDN] = MEG4_KEY_PGDN;
  247. main_keymap[ALLEGRO_KEY_HOME] = MEG4_KEY_HOME;
  248. main_keymap[ALLEGRO_KEY_END] = MEG4_KEY_END;
  249. main_keymap[ALLEGRO_KEY_CAPSLOCK] = MEG4_KEY_CAPSLOCK;
  250. main_keymap[ALLEGRO_KEY_SCROLLLOCK] = MEG4_KEY_SCRLOCK;
  251. main_keymap[ALLEGRO_KEY_NUMLOCK] = MEG4_KEY_NUMLOCK;
  252. main_keymap[ALLEGRO_KEY_PRINTSCREEN] = MEG4_KEY_PRSCR;
  253. main_keymap[ALLEGRO_KEY_PAUSE] = MEG4_KEY_PAUSE;
  254. main_keymap[ALLEGRO_KEY_F1] = MEG4_KEY_F1;
  255. main_keymap[ALLEGRO_KEY_F2] = MEG4_KEY_F2;
  256. main_keymap[ALLEGRO_KEY_F3] = MEG4_KEY_F3;
  257. main_keymap[ALLEGRO_KEY_F4] = MEG4_KEY_F4;
  258. main_keymap[ALLEGRO_KEY_F5] = MEG4_KEY_F5;
  259. main_keymap[ALLEGRO_KEY_F6] = MEG4_KEY_F6;
  260. main_keymap[ALLEGRO_KEY_F7] = MEG4_KEY_F7;
  261. main_keymap[ALLEGRO_KEY_F8] = MEG4_KEY_F8;
  262. main_keymap[ALLEGRO_KEY_F9] = MEG4_KEY_F9;
  263. main_keymap[ALLEGRO_KEY_F10] = MEG4_KEY_F10;
  264. main_keymap[ALLEGRO_KEY_F11] = MEG4_KEY_F11;
  265. main_keymap[ALLEGRO_KEY_F12] = MEG4_KEY_F12;
  266. main_keymap[ALLEGRO_KEY_PAD_0] = MEG4_KEY_KP_0;
  267. main_keymap[ALLEGRO_KEY_PAD_1] = MEG4_KEY_KP_1;
  268. main_keymap[ALLEGRO_KEY_PAD_2] = MEG4_KEY_KP_2;
  269. main_keymap[ALLEGRO_KEY_PAD_3] = MEG4_KEY_KP_3;
  270. main_keymap[ALLEGRO_KEY_PAD_4] = MEG4_KEY_KP_4;
  271. main_keymap[ALLEGRO_KEY_PAD_5] = MEG4_KEY_KP_5;
  272. main_keymap[ALLEGRO_KEY_PAD_6] = MEG4_KEY_KP_6;
  273. main_keymap[ALLEGRO_KEY_PAD_7] = MEG4_KEY_KP_7;
  274. main_keymap[ALLEGRO_KEY_PAD_8] = MEG4_KEY_KP_8;
  275. main_keymap[ALLEGRO_KEY_PAD_9] = MEG4_KEY_KP_9;
  276. main_keymap[ALLEGRO_KEY_PAD_DELETE] = MEG4_KEY_KP_DEC;
  277. main_keymap[ALLEGRO_KEY_PAD_SLASH] = MEG4_KEY_KP_DIV;
  278. main_keymap[ALLEGRO_KEY_PAD_ASTERISK] = MEG4_KEY_KP_MUL;
  279. main_keymap[ALLEGRO_KEY_PAD_MINUS] = MEG4_KEY_KP_SUB;
  280. main_keymap[ALLEGRO_KEY_PAD_PLUS] = MEG4_KEY_KP_ADD;
  281. main_keymap[ALLEGRO_KEY_PAD_ENTER] = MEG4_KEY_KP_ENTER;
  282. main_keymap[ALLEGRO_KEY_PAD_EQUALS] = MEG4_KEY_KP_EQUAL;
  283. main_keymap[ALLEGRO_KEY_LSHIFT] = MEG4_KEY_LSHIFT;
  284. main_keymap[ALLEGRO_KEY_LCTRL] = MEG4_KEY_LCTRL;
  285. main_keymap[ALLEGRO_KEY_ALT] = MEG4_KEY_LALT;
  286. main_keymap[ALLEGRO_KEY_LWIN] = MEG4_KEY_LSUPER;
  287. main_keymap[ALLEGRO_KEY_RSHIFT] = MEG4_KEY_RSHIFT;
  288. main_keymap[ALLEGRO_KEY_RCTRL] = MEG4_KEY_RCTRL;
  289. main_keymap[ALLEGRO_KEY_ALTGR] = MEG4_KEY_RALT;
  290. main_keymap[ALLEGRO_KEY_RWIN] = MEG4_KEY_RSUPER;
  291. main_keymap[ALLEGRO_KEY_MENU] = MEG4_KEY_MENU;
  292. audio = al_install_audio() && al_reserve_samples(0);
  293. if(audio) {
  294. stream = al_create_audio_stream(4, SAMPLES_PER_BUFFER, 44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_1);
  295. if(!stream) { al_uninstall_audio(); audio = 0; } else
  296. if(!al_attach_audio_stream_to_mixer(stream, al_get_default_mixer())) { al_destroy_audio_stream(stream); al_uninstall_audio(); audio = 0; }
  297. }
  298. if(verbose && audio) main_log(1, "audio opened %uHz, %u bits", 44100, 32);
  299. /* turn on the emulator */
  300. meg4_poweron(lng);
  301. #ifndef NOEDITORS
  302. for(; infile && *infile; infile++) {
  303. if((ptr = main_readfile(*infile, &i))) {
  304. fn = strrchr(*infile, SEP[0]); if(!fn) fn = *infile; else fn++;
  305. meg4_insert(fn, ptr, i);
  306. free(ptr);
  307. }
  308. }
  309. #else
  310. (void)ptr; (void)infile;
  311. #endif
  312. al_get_monitor_info(0, &info);
  313. main_w = info.x2 - info.x1; main_h = info.y2 - info.y1;
  314. #if DEBUG
  315. main_win(640, 400, 0);
  316. #else
  317. main_win(640/*main_w*/, 400/*main_h*/, 0/*1*/);
  318. if(!windowed) main_fullscreen();
  319. #endif
  320. if(!nearest) al_set_new_bitmap_flags(al_get_new_bitmap_flags() | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
  321. screen = al_create_bitmap(640, 400);
  322. al_register_event_source(queue, al_get_keyboard_event_source());
  323. al_register_event_source(queue, al_get_mouse_event_source());
  324. al_register_event_source(queue, al_get_joystick_event_source());
  325. al_register_event_source(queue, al_get_display_event_source(disp));
  326. al_register_event_source(queue, al_get_timer_event_source(timer));
  327. al_get_mouse_state(&state);
  328. main_pointer(al_get_mouse_state_axis(&state, 0), al_get_mouse_state_axis(&state, 1));
  329. meg4_hidecursor();
  330. al_reconfigure_joysticks();
  331. memset(controller, 0, sizeof(controller));
  332. for(i = 0; i < al_get_num_joysticks() && i < 4; i++)
  333. controller[i] = al_get_joystick(i);
  334. if(audio) al_register_event_source(queue, al_get_audio_stream_event_source(stream));
  335. al_start_timer(timer);
  336. redraw = 0; running = 1;
  337. while(running) {
  338. al_wait_for_event(queue, &event);
  339. switch(event.type) {
  340. case ALLEGRO_EVENT_DISPLAY_CLOSE: running = 0; break;
  341. case ALLEGRO_EVENT_DISPLAY_RESIZE: al_acknowledge_resize(disp); redraw = 1; break;
  342. case ALLEGRO_EVENT_TIMER: meg4_run(); redraw = 1; break;
  343. /* audio event */
  344. case ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT:
  345. if((abuf = al_get_audio_stream_fragment(stream))) {
  346. meg4_audiofeed(abuf, SAMPLES_PER_BUFFER);
  347. al_set_audio_stream_fragment(stream, abuf);
  348. }
  349. break;
  350. /* mouse events */
  351. case ALLEGRO_EVENT_MOUSE_AXES:
  352. main_pointer(event.mouse.x, event.mouse.y);
  353. if(event.mouse.dz || event.mouse.dw) meg4_setscr(event.mouse.dz > 0, event.mouse.dz < 0, event.mouse.dw > 0, event.mouse.dw < 0);
  354. break;
  355. case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
  356. main_pointer(event.mouse.x, event.mouse.y);
  357. switch(event.mouse.button) {
  358. case 1: meg4_setbtn(MEG4_BTN_L); break;
  359. case 2: meg4_setbtn(MEG4_BTN_R); break;
  360. case 3: meg4_setbtn(MEG4_BTN_M); break;
  361. }
  362. break;
  363. case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
  364. main_pointer(event.mouse.x, event.mouse.y);
  365. switch(event.mouse.button) {
  366. case 1: meg4_clrbtn(MEG4_BTN_L); break;
  367. case 2: meg4_clrbtn(MEG4_BTN_R); break;
  368. case 3: meg4_clrbtn(MEG4_BTN_M); break;
  369. }
  370. break;
  371. /* keyboard events */
  372. case ALLEGRO_EVENT_KEY_DOWN:
  373. switch(event.keyboard.keycode) {
  374. case ALLEGRO_KEY_ALT: case ALLEGRO_KEY_LCTRL: main_alt = 1; break;
  375. case ALLEGRO_KEY_ALTGR: main_alt = 0; break;
  376. case ALLEGRO_KEY_ENTER: if(main_alt) main_fullscreen(); else meg4_pushkey("\n\0\0"); break;
  377. case ALLEGRO_KEY_Q: if(main_alt) { running = 0; } break;
  378. case ALLEGRO_KEY_ESCAPE: if(main_alt) { running = 0; } else meg4_pushkey("\x1b\0\0"); break;
  379. /* only for special keys that aren't handled by SDL_TEXTINPUT events */
  380. case ALLEGRO_KEY_F1: meg4_pushkey("F1\0"); break;
  381. case ALLEGRO_KEY_F2: meg4_pushkey("F2\0"); break;
  382. case ALLEGRO_KEY_F3: meg4_pushkey("F3\0"); break;
  383. case ALLEGRO_KEY_F4: meg4_pushkey("F4\0"); break;
  384. case ALLEGRO_KEY_F5: meg4_pushkey("F5\0"); break;
  385. case ALLEGRO_KEY_F6: meg4_pushkey("F6\0"); break;
  386. case ALLEGRO_KEY_F7: meg4_pushkey("F7\0"); break;
  387. case ALLEGRO_KEY_F8: meg4_pushkey("F8\0"); break;
  388. case ALLEGRO_KEY_F9: meg4_pushkey("F9\0"); break;
  389. case ALLEGRO_KEY_F10: meg4_pushkey("F10"); break;
  390. case ALLEGRO_KEY_F11: main_fullscreen(); break;
  391. case ALLEGRO_KEY_F12: meg4_pushkey("F12"); break;
  392. case ALLEGRO_KEY_PRINTSCREEN: meg4_pushkey("PSc"); break;
  393. case ALLEGRO_KEY_SCROLLLOCK: meg4_pushkey("SLk"); break;
  394. case ALLEGRO_KEY_NUMLOCK: meg4_pushkey("NLk"); break;
  395. case ALLEGRO_KEY_BACKSPACE: meg4_pushkey("\b\0\0"); break;
  396. case ALLEGRO_KEY_TAB: meg4_pushkey("\t\0\0"); break;
  397. case ALLEGRO_KEY_CAPSLOCK: meg4_pushkey("CLk"); break;
  398. case ALLEGRO_KEY_UP: meg4_pushkey("Up\0"); break;
  399. case ALLEGRO_KEY_DOWN: meg4_pushkey("Down"); break;
  400. case ALLEGRO_KEY_LEFT: meg4_pushkey("Left"); break;
  401. case ALLEGRO_KEY_RIGHT: meg4_pushkey("Rght"); break;
  402. case ALLEGRO_KEY_HOME: meg4_pushkey("Home"); break;
  403. case ALLEGRO_KEY_END: meg4_pushkey("End"); break;
  404. case ALLEGRO_KEY_PGUP: meg4_pushkey("PgUp"); break;
  405. case ALLEGRO_KEY_PGDN: meg4_pushkey("PgDn"); break;
  406. case ALLEGRO_KEY_INSERT: meg4_pushkey("Ins"); break;
  407. case ALLEGRO_KEY_DELETE: meg4_pushkey("Del"); break;
  408. }
  409. if(event.keyboard.keycode < 512 && main_keymap[event.keyboard.keycode]) meg4_setkey(main_keymap[event.keyboard.keycode]);
  410. break;
  411. case ALLEGRO_EVENT_KEY_UP:
  412. switch(event.keyboard.keycode) {
  413. case ALLEGRO_KEY_ALT: case ALLEGRO_KEY_LCTRL: main_alt = 0; break;
  414. }
  415. if(event.keyboard.keycode < 512 && main_keymap[event.keyboard.keycode]) meg4_clrkey(main_keymap[event.keyboard.keycode]);
  416. break;
  417. case ALLEGRO_EVENT_KEY_CHAR:
  418. if(!main_alt && event.keyboard.unichar >= 32) {
  419. memset(s, 0, sizeof(s));
  420. if(event.keyboard.unichar<0x80) { s[0]=event.keyboard.unichar; } else
  421. if(event.keyboard.unichar<0x800) { s[0]=((event.keyboard.unichar>>6)&0x1F)|0xC0; s[1]=(event.keyboard.unichar&0x3F)|0x80; } else
  422. if(event.keyboard.unichar<0x10000) { s[0]=((event.keyboard.unichar>>12)&0x0F)|0xE0; s[1]=((event.keyboard.unichar>>6)&0x3F)|0x80; s[2]=(event.keyboard.unichar&0x3F)|0x80; }
  423. else { s[0]=((event.keyboard.unichar>>18)&0x07)|0xF0; s[1]=((event.keyboard.unichar>>12)&0x3F)|0x80; s[2]=((event.keyboard.unichar>>6)&0x3F)|0x80; s[3]=(event.keyboard.unichar&0x3F)|0x80; }
  424. meg4_pushkey(s);
  425. }
  426. break;
  427. /* gamepad events */
  428. case ALLEGRO_EVENT_JOYSTICK_CONFIGURATION:
  429. al_reconfigure_joysticks();
  430. memset(controller, 0, sizeof(controller));
  431. for(i = 0; i < al_get_num_joysticks() && i < 4; i++)
  432. controller[i] = al_get_joystick(i);
  433. break;
  434. case ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN:
  435. for(i = 0; i < 4 && controller[i] != event.joystick.id; i++);
  436. if(i < 4) {
  437. /* not sure about button order */
  438. switch(event.joystick.button) {
  439. case 0: meg4_setpad(i, MEG4_BTN_L); break;
  440. case 1: meg4_setpad(i, MEG4_BTN_U); break;
  441. case 2: meg4_setpad(i, MEG4_BTN_R); break;
  442. case 3: meg4_setpad(i, MEG4_BTN_D); break;
  443. case 4: meg4_setpad(i, MEG4_BTN_A); break;
  444. case 5: meg4_setpad(i, MEG4_BTN_B); break;
  445. case 6: meg4_setpad(i, MEG4_BTN_X); break;
  446. case 7: meg4_setpad(i, MEG4_BTN_Y); break;
  447. }
  448. }
  449. break;
  450. case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP:
  451. for(i = 0; i < 4 && controller[i] != event.joystick.id; i++);
  452. if(i < 4) {
  453. switch(event.joystick.button) {
  454. case 0: meg4_clrpad(i, MEG4_BTN_L); break;
  455. case 1: meg4_clrpad(i, MEG4_BTN_U); break;
  456. case 2: meg4_clrpad(i, MEG4_BTN_R); break;
  457. case 3: meg4_clrpad(i, MEG4_BTN_D); break;
  458. case 4: meg4_clrpad(i, MEG4_BTN_A); break;
  459. case 5: meg4_clrpad(i, MEG4_BTN_B); break;
  460. case 6: meg4_clrpad(i, MEG4_BTN_X); break;
  461. case 7: meg4_clrpad(i, MEG4_BTN_Y); break;
  462. }
  463. }
  464. break;
  465. case ALLEGRO_EVENT_JOYSTICK_AXIS:
  466. for(i = 0; i < 4 && controller[i] != event.joystick.id; i++);
  467. if(i < 4) {
  468. w = event.joystick.pos * 32767.0f;
  469. if(!event.joystick.axis) {
  470. meg4_clrpad(i, MEG4_BTN_L | MEG4_BTN_R);
  471. if(w < -le16toh(meg4.mmio.padtres)) meg4_setpad(i, MEG4_BTN_L);
  472. if(w > le16toh(meg4.mmio.padtres)) meg4_setpad(i, MEG4_BTN_R);
  473. } else {
  474. meg4_clrpad(i, MEG4_BTN_U | MEG4_BTN_D);
  475. if(w < -le16toh(meg4.mmio.padtres)) meg4_setpad(i, MEG4_BTN_U);
  476. if(w > le16toh(meg4.mmio.padtres)) meg4_setpad(i, MEG4_BTN_D);
  477. }
  478. }
  479. break;
  480. }
  481. if(redraw && al_is_event_queue_empty(queue)) {
  482. redraw = 0;
  483. /* display screen */
  484. meg4_redraw((uint32_t*)screen->memory, 640, 400, screen->pitch);
  485. al_clear_to_color(al_map_rgba_f(0, 0, 0, 1));
  486. ww = al_get_display_width(disp); wh = al_get_display_height(disp);
  487. if(!win_f && nearest) {
  488. i = ww / 320; h = wh / 200; if(i > h) i = h;
  489. w = 320 * i; h = 200 * i;
  490. } else {
  491. w = ww; h = (int)meg4.screen.h * ww / (int)meg4.screen.w;
  492. if(h > wh) { h = wh; w = (int)meg4.screen.w * wh / (int)meg4.screen.h; }
  493. }
  494. al_draw_scaled_bitmap(screen, 0, 0, (float)meg4.screen.w, (float)meg4.screen.h,
  495. (float)((ww - w) >> 1), (float)((wh - h) >> 1), (float)w, (float)h, 0);
  496. al_flip_display();
  497. }
  498. }
  499. main_quit();
  500. return 0;
  501. }