event.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /* MegaZeux
  2. *
  3. * Copyright (C) 2004 Gilead Kutnick <exophase@adelphia.net>
  4. * Copyright (C) 2007-2009 Kevin Vance <kvance@kvance.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or (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 GNU
  14. * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "../../src/event.h"
  21. #include "../../src/platform.h"
  22. #include "../../src/graphics.h"
  23. #include <nds/arm9/keyboard.h>
  24. #include "render.h"
  25. #include "evq.h"
  26. void nds_update_input(void);
  27. static boolean process_event(NDSEvent *event);
  28. extern struct input_status input;
  29. static boolean keyboard_allow_release = true;
  30. boolean __update_event_status(void)
  31. {
  32. boolean retval = false;
  33. NDSEvent event;
  34. while(nds_event_poll(&event))
  35. retval |= process_event(&event);
  36. return retval;
  37. }
  38. void __wait_event(void)
  39. {
  40. NDSEvent event;
  41. while(!nds_event_poll(&event))
  42. swiWaitForVBlank();
  43. process_event(&event);
  44. }
  45. void real_warp_mouse(int x, int y)
  46. {
  47. const struct buffered_status *status = load_status();
  48. if(x < 0)
  49. x = status->real_mouse_x;
  50. if(y < 0)
  51. y = status->real_mouse_y;
  52. // Since we can't warp a touchscreen stylus, focus there instead.
  53. focus_pixel(x, y);
  54. }
  55. void initialize_joysticks(void)
  56. {
  57. // stub (we have a hardcoded 0-axis, 8-button joystick)
  58. }
  59. static int nds_map_joystick(int nds_button, boolean *is_hat)
  60. {
  61. // Determine how to handle this particular joystick input.
  62. // Map the directional pad to the hat and everything else to buttons.
  63. *is_hat = false;
  64. switch(nds_button)
  65. {
  66. case KEY_UP: *is_hat = true; return JOYHAT_UP;
  67. case KEY_DOWN: *is_hat = true; return JOYHAT_DOWN;
  68. case KEY_LEFT: *is_hat = true; return JOYHAT_LEFT;
  69. case KEY_RIGHT: *is_hat = true; return JOYHAT_RIGHT;
  70. case KEY_A: return 0;
  71. case KEY_B: return 1;
  72. case KEY_X: return 2;
  73. case KEY_Y: return 3;
  74. case KEY_L: return 4;
  75. case KEY_R: return 5;
  76. case KEY_SELECT: return 6;
  77. case KEY_START: return 7;
  78. }
  79. return -1;
  80. }
  81. static void convert_nds_internal(int key, int *internal_code, int *unicode)
  82. {
  83. // Actually ASCIIish, but close enough.
  84. if(key > 0)
  85. *unicode = key;
  86. else
  87. *unicode = 0;
  88. // Uppercase letters
  89. if(key >= 65 && key <= 90)
  90. *internal_code = key + 32;
  91. // Arrow keys
  92. else if(key == -17)
  93. *internal_code = IKEY_UP;
  94. else if(key == -19)
  95. *internal_code = IKEY_DOWN;
  96. else if(key == -20)
  97. *internal_code = IKEY_LEFT;
  98. else if(key == -18)
  99. *internal_code = IKEY_RIGHT;
  100. // Other keys
  101. else if(key == -23)
  102. *internal_code = IKEY_ESCAPE;
  103. else if(key == -15)
  104. *internal_code = IKEY_CAPSLOCK;
  105. else if(key == 10)
  106. *internal_code = IKEY_RETURN;
  107. else if(key == -14)
  108. *internal_code = IKEY_LSHIFT;
  109. else if(key == -16)
  110. *internal_code = IKEY_LCTRL;
  111. else if(key == -26)
  112. *internal_code = IKEY_LALT;
  113. else if(key == -5)
  114. *internal_code = IKEY_MENU;
  115. // ASCIIish keys
  116. else if(key > 0 && key < 512)
  117. *internal_code = key;
  118. // Unknown key
  119. else
  120. *internal_code = IKEY_UNKNOWN;
  121. }
  122. static boolean process_event(NDSEvent *event)
  123. {
  124. struct buffered_status *status = store_status();
  125. boolean retval = true;
  126. switch(event->type)
  127. {
  128. // Hardware key pressed
  129. case NDS_EVENT_KEY_DOWN:
  130. {
  131. boolean is_hat;
  132. int button;
  133. // Special case- R is currently hardcoded to the keyboard.
  134. if(event->key == KEY_R)
  135. {
  136. nds_subscreen_switch();
  137. retval = false;
  138. break;
  139. }
  140. button = nds_map_joystick(event->key, &is_hat);
  141. if(button >= 0)
  142. {
  143. if(is_hat)
  144. joystick_hat_update(status, 0, button, true);
  145. else
  146. joystick_button_press(status, 0, button);
  147. }
  148. break;
  149. }
  150. case NDS_EVENT_KEY_UP:
  151. {
  152. boolean is_hat;
  153. int button;
  154. button = nds_map_joystick(event->key, &is_hat);
  155. if(button >= 0)
  156. {
  157. if(is_hat)
  158. joystick_hat_update(status, 0, button, false);
  159. else
  160. joystick_button_release(status, 0, button);
  161. }
  162. break;
  163. }
  164. // Software key down
  165. case NDS_EVENT_KEYBOARD_DOWN:
  166. {
  167. int internal_code, unicode;
  168. convert_nds_internal(event->key, &internal_code, &unicode);
  169. key_press(status, internal_code, unicode);
  170. keyboard_allow_release = true;
  171. break;
  172. }
  173. case NDS_EVENT_KEYBOARD_UP:
  174. {
  175. int internal_code, unicode;
  176. convert_nds_internal(event->key, &internal_code, &unicode);
  177. key_release(status, internal_code);
  178. break;
  179. }
  180. // Touchscreen stylus down
  181. case NDS_EVENT_TOUCH_DOWN:
  182. {
  183. int button = MOUSE_BUTTON_LEFT;
  184. status->mouse_button = button;
  185. status->mouse_repeat = button;
  186. status->mouse_button_state |= MOUSE_BUTTON(button);
  187. status->mouse_repeat_state = 1;
  188. status->mouse_drag_state = -1;
  189. status->mouse_time = get_ticks();
  190. break;
  191. }
  192. // Touchscreen stylus up
  193. case NDS_EVENT_TOUCH_UP:
  194. {
  195. int button = MOUSE_BUTTON_LEFT;
  196. status->mouse_button_state &= ~MOUSE_BUTTON(button);
  197. status->mouse_repeat = 0;
  198. status->mouse_drag_state = 0;
  199. status->mouse_repeat_state = 0;
  200. nds_mouselook(false);
  201. break;
  202. }
  203. // Touchscreen stylus drag
  204. case NDS_EVENT_TOUCH_MOVE:
  205. {
  206. int mx = event->x * 640 / 256;
  207. int my = event->y * 350 / 192;
  208. // Update the MZX mouse state.
  209. status->real_mouse_x = mx;
  210. status->real_mouse_y = my;
  211. status->mouse_x = mx / 8;
  212. status->mouse_y = my / 14;
  213. status->mouse_moved = true;
  214. // Update our internal mouselook state.
  215. nds_mouselook(false);
  216. focus_pixel(mx, my);
  217. nds_mouselook(true);
  218. break;
  219. }
  220. // Unknown event?
  221. default:
  222. {
  223. retval = false;
  224. break;
  225. }
  226. };
  227. return retval;
  228. }
  229. static void nds_update_hw_keys(void)
  230. {
  231. static int last_keys_mask = 0;
  232. int keys = keysHeld();
  233. int check[] = { KEY_A, KEY_B, KEY_SELECT, KEY_START, KEY_RIGHT, KEY_LEFT,
  234. KEY_UP, KEY_DOWN, KEY_R, KEY_L, KEY_X, KEY_Y };
  235. NDSEvent event;
  236. for(size_t i = 0; i < sizeof(check)/sizeof(*check); i++)
  237. {
  238. int keybit = check[i];
  239. if(keybit & keys)
  240. {
  241. if(!(keybit & last_keys_mask))
  242. {
  243. // Key pressed
  244. nds_event_fill_key_down(&event, keybit);
  245. nds_event_push(&event);
  246. last_keys_mask |= keybit;
  247. }
  248. }
  249. else if(keybit & last_keys_mask)
  250. {
  251. // Key released
  252. nds_event_fill_key_up(&event, keybit);
  253. nds_event_push(&event);
  254. last_keys_mask &= ~keybit;
  255. }
  256. }
  257. }
  258. static void nds_update_sw_keyboard(void)
  259. {
  260. static int last_key = -1;
  261. NDSEvent event;
  262. // Release last key
  263. if(keyboard_allow_release && last_key != -1)
  264. {
  265. nds_event_fill_keyboard_up(&event, last_key);
  266. nds_event_push(&event);
  267. last_key = -1;
  268. }
  269. // Press new key (only allow if the keyboard is active)
  270. if(subscreen_mode == SUBSCREEN_KEYBOARD && last_key == -1)
  271. {
  272. int c = keyboardUpdate();
  273. if(c != -1)
  274. {
  275. nds_event_fill_keyboard_down(&event, c);
  276. nds_event_push(&event);
  277. keyboard_allow_release = false;
  278. last_key = c;
  279. }
  280. }
  281. }
  282. static void nds_update_mouse(void)
  283. {
  284. static boolean last_touch_press = false;
  285. static int last_touch_x = -1;
  286. static int last_touch_y = -1;
  287. NDSEvent new_event;
  288. if(is_scaled_mode(subscreen_mode))
  289. {
  290. // Inject mouse motion events.
  291. if(keysHeld() & KEY_TOUCH)
  292. {
  293. touchPosition touch;
  294. touchRead(&touch);
  295. if(touch.px != last_touch_x || touch.py != last_touch_y)
  296. {
  297. // Add the event.
  298. nds_event_fill_touch_move(&new_event, touch.px, touch.py);
  299. nds_event_push(&new_event);
  300. last_touch_x = touch.px;
  301. last_touch_y = touch.py;
  302. }
  303. if(!last_touch_press)
  304. {
  305. nds_event_fill_touch_down(&new_event);
  306. nds_event_push(&new_event);
  307. last_touch_press = true;
  308. }
  309. }
  310. else if(last_touch_press)
  311. {
  312. nds_event_fill_touch_up(&new_event);
  313. nds_event_push(&new_event);
  314. last_touch_press = false;
  315. }
  316. }
  317. }
  318. void nds_update_input(void)
  319. {
  320. scanKeys();
  321. nds_update_hw_keys();
  322. nds_update_sw_keyboard();
  323. nds_update_mouse();
  324. }