input.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. let _input_occupied: bool = false;
  2. let _input_registered: bool = false;
  3. function input_reset() {
  4. // _input_occupied = false;
  5. mouse_reset();
  6. pen_reset();
  7. keyboard_reset();
  8. /// if WITH_GAMEPAD
  9. gamepad_reset();
  10. /// end
  11. }
  12. function input_end_frame() {
  13. mouse_end_frame();
  14. pen_end_frame();
  15. keyboard_end_frame();
  16. /// if WITH_GAMEPAD
  17. gamepad_end_frame();
  18. /// end
  19. }
  20. function input_on_foreground() {
  21. mouse_reset(); // Reset mouse delta on foreground
  22. }
  23. function input_register() {
  24. if (_input_registered) {
  25. return;
  26. }
  27. _input_registered = true;
  28. keyboard_reset();
  29. mouse_reset();
  30. /// if WITH_GAMEPAD
  31. gamepad_reset();
  32. /// end
  33. }
  34. let _mouse_buttons: string[] = [ "left", "right", "middle", "side1", "side2" ];
  35. let _mouse_buttons_down: bool[] = [ false, false, false, false, false ];
  36. let _mouse_buttons_started: bool[] = [ false, false, false, false, false ];
  37. let _mouse_buttons_released: bool[] = [ false, false, false, false, false ];
  38. let mouse_x: f32 = -1.0;
  39. let mouse_y: f32 = -1.0;
  40. let mouse_moved: bool = false;
  41. let mouse_movement_x: f32 = 0.0;
  42. let mouse_movement_y: f32 = 0.0;
  43. let mouse_wheel_delta: f32 = 0.0;
  44. let mouse_last_x: f32 = -1.0;
  45. let mouse_last_y: f32 = -1.0;
  46. function mouse_end_frame() {
  47. _mouse_buttons_started[0] = _mouse_buttons_started[1] = _mouse_buttons_started[2] = _mouse_buttons_started[3] = _mouse_buttons_started[4] = false;
  48. _mouse_buttons_released[0] = _mouse_buttons_released[1] = _mouse_buttons_released[2] = _mouse_buttons_released[3] = _mouse_buttons_released[4] = false;
  49. mouse_moved = false;
  50. mouse_movement_x = 0;
  51. mouse_movement_y = 0;
  52. mouse_wheel_delta = 0;
  53. }
  54. function mouse_reset() {
  55. _mouse_buttons_down[0] = _mouse_buttons_down[1] = _mouse_buttons_down[2] = _mouse_buttons_down[3] = _mouse_buttons_down[4] = false;
  56. mouse_end_frame();
  57. }
  58. function mouse_button_index(button: string): i32 {
  59. for (let i: i32 = 0; i < _mouse_buttons.length; ++i) {
  60. if (_mouse_buttons[i] == button) {
  61. return i;
  62. }
  63. }
  64. return 0;
  65. }
  66. function mouse_down(button: string = "left"): bool {
  67. return _mouse_buttons_down[mouse_button_index(button)];
  68. }
  69. function mouse_down_any(): bool {
  70. return _mouse_buttons_down[0] || _mouse_buttons_down[1] || _mouse_buttons_down[2] || _mouse_buttons_down[3] || _mouse_buttons_down[4];
  71. }
  72. function mouse_started(button: string = "left"): bool {
  73. return _mouse_buttons_started[mouse_button_index(button)];
  74. }
  75. function mouse_started_any(): bool {
  76. return _mouse_buttons_started[0] || _mouse_buttons_started[1] || _mouse_buttons_started[2] || _mouse_buttons_started[3] || _mouse_buttons_started[4];
  77. }
  78. function mouse_released(button: string = "left"): bool {
  79. return _mouse_buttons_released[mouse_button_index(button)];
  80. }
  81. function mouse_down_listener(index: i32, x: i32, y: i32) {
  82. if (pen_in_use) {
  83. return;
  84. }
  85. _mouse_buttons_down[index] = true;
  86. _mouse_buttons_started[index] = true;
  87. mouse_x = x;
  88. mouse_y = y;
  89. /// if (arm_android || arm_ios) // For movement delta using touch
  90. if (index == 0) {
  91. mouse_last_x = x;
  92. mouse_last_y = y;
  93. }
  94. /// end
  95. }
  96. function mouse_up_listener(index: i32, x: i32, y: i32) {
  97. if (pen_in_use) {
  98. return;
  99. }
  100. _mouse_buttons_down[index] = false;
  101. _mouse_buttons_released[index] = true;
  102. mouse_x = x;
  103. mouse_y = y;
  104. }
  105. function mouse_move_listener(x: i32, y: i32, movement_x: i32, movement_y: i32) {
  106. if (mouse_last_x == -1.0 && mouse_last_y == -1.0) { // First frame init
  107. mouse_last_x = x;
  108. mouse_last_y = y;
  109. }
  110. if (iron_mouse_is_locked()) {
  111. // Can be called multiple times per frame
  112. mouse_movement_x += movement_x;
  113. mouse_movement_y += movement_y;
  114. }
  115. else {
  116. mouse_movement_x += x - mouse_last_x;
  117. mouse_movement_y += y - mouse_last_y;
  118. }
  119. mouse_last_x = x;
  120. mouse_last_y = y;
  121. mouse_x = x;
  122. mouse_y = y;
  123. mouse_moved = true;
  124. }
  125. function mouse_wheel_listener(delta: f32) {
  126. mouse_wheel_delta = delta;
  127. }
  128. /// if (arm_android || arm_ios)
  129. function mouse_on_touch_down(index: i32, x: i32, y: i32) {
  130. if (index == 1) { // Two fingers down - right mouse button
  131. _mouse_buttons_down[0] = false;
  132. mouse_down_listener(1, math_floor(mouse_x), math_floor(mouse_y));
  133. mouse_pinch_started = true;
  134. mouse_pinch_total = 0.0;
  135. mouse_pinch_dist = 0.0;
  136. }
  137. else if (index == 2) { // Three fingers down - middle mouse button
  138. _mouse_buttons_down[1] = false;
  139. mouse_down_listener(2, math_floor(mouse_x), math_floor(mouse_y));
  140. }
  141. }
  142. function mouse_on_touch_up(index: i32, x: i32, y: i32) {
  143. if (index == 1) {
  144. mouse_up_listener(1, math_floor(mouse_x), math_floor(mouse_y));
  145. }
  146. else if (index == 2) {
  147. mouse_up_listener(2, math_floor(mouse_x), math_floor(mouse_y));
  148. }
  149. }
  150. let mouse_pinch_dist: f32 = 0.0;
  151. let mouse_pinch_total: f32 = 0.0;
  152. let mouse_pinch_started: bool = false;
  153. function mouse_on_touch_move(index: i32, x: i32, y: i32) {
  154. // Pinch to zoom - mouse wheel
  155. if (index == 1) {
  156. let last_dist: f32 = mouse_pinch_dist;
  157. let dx: f32 = mouse_x - x;
  158. let dy: f32 = mouse_y - y;
  159. mouse_pinch_dist = math_sqrt(dx * dx + dy * dy);
  160. mouse_pinch_total += last_dist != 0 ? last_dist - mouse_pinch_dist : 0;
  161. if (!mouse_pinch_started) {
  162. mouse_wheel_delta = mouse_pinch_total / 10.0;
  163. if (mouse_wheel_delta != 0.0) {
  164. mouse_pinch_total = 0.0;
  165. }
  166. }
  167. mouse_pinch_started = false;
  168. }
  169. }
  170. /// end
  171. function mouse_view_x(): f32 {
  172. return mouse_x - sys_x();
  173. }
  174. function mouse_view_y(): f32 {
  175. return mouse_y - sys_y();
  176. }
  177. let pen_buttons: string[] = [ "tip" ];
  178. let pen_buttons_down: bool[] = [ false ];
  179. let pen_buttons_started: bool[] = [ false ];
  180. let pen_buttons_released: bool[] = [ false ];
  181. let pen_x: f32 = 0.0;
  182. let pen_y: f32 = 0.0;
  183. let pen_moved: bool = false;
  184. let pen_movement_x: f32 = 0.0;
  185. let pen_movement_y: f32 = 0.0;
  186. let pen_pressure: f32 = 0.0;
  187. let pen_connected: bool = false;
  188. let pen_in_use: bool = false;
  189. let pen_last_x: f32 = -1.0;
  190. let pen_last_y: f32 = -1.0;
  191. function pen_end_frame() {
  192. pen_buttons_started[0] = false;
  193. pen_buttons_released[0] = false;
  194. pen_moved = false;
  195. pen_movement_x = 0;
  196. pen_movement_y = 0;
  197. pen_in_use = false;
  198. }
  199. function pen_reset() {
  200. pen_buttons_down[0] = false;
  201. pen_end_frame();
  202. }
  203. function pen_button_index(button: string): i32 {
  204. return 0;
  205. }
  206. function pen_down(button: string = "tip"): bool {
  207. return pen_buttons_down[pen_button_index(button)];
  208. }
  209. function pen_started(button: string = "tip"): bool {
  210. return pen_buttons_started[pen_button_index(button)];
  211. }
  212. function pen_released(button: string = "tip"): bool {
  213. return pen_buttons_released[pen_button_index(button)];
  214. }
  215. function pen_down_listener(x: i32, y: i32, pressure: f32) {
  216. pen_buttons_down[0] = true;
  217. pen_buttons_started[0] = true;
  218. pen_x = x;
  219. pen_y = y;
  220. pen_pressure = pressure;
  221. /// if (!arm_android && !arm_ios)
  222. mouse_down_listener(0, x, y);
  223. /// end
  224. }
  225. function pen_up_listener(x: i32, y: i32, pressure: f32) {
  226. /// if (!arm_android && !arm_ios)
  227. if (pen_buttons_started[0]) {
  228. pen_buttons_started[0] = false;
  229. pen_in_use = true;
  230. return;
  231. }
  232. /// end
  233. pen_buttons_down[0] = false;
  234. pen_buttons_released[0] = true;
  235. pen_x = x;
  236. pen_y = y;
  237. pen_pressure = pressure;
  238. /// if (!arm_android && !arm_ios)
  239. mouse_up_listener(0, x, y);
  240. pen_in_use = true; // On pen release, additional mouse down & up events are fired at once - filter those out
  241. /// end
  242. }
  243. function pen_move_listener(x: i32, y: i32, pressure: f32) {
  244. /// if arm_ios
  245. // Listen to pen hover if no other input is active
  246. if (!pen_buttons_down[0] && pressure == 0.0) {
  247. if (!mouse_down_any()) {
  248. mouse_move_listener(x, y, 0, 0);
  249. }
  250. return;
  251. }
  252. /// end
  253. if (pen_last_x == -1.0 && pen_last_y == -1.0) { // First frame init
  254. pen_last_x = x;
  255. pen_last_y = y;
  256. }
  257. pen_movement_x = x - pen_last_x;
  258. pen_movement_y = y - pen_last_y;
  259. pen_last_x = x;
  260. pen_last_y = y;
  261. pen_x = x;
  262. pen_y = y;
  263. pen_moved = true;
  264. pen_pressure = pressure;
  265. pen_connected = true;
  266. }
  267. function pen_view_x(): f32 {
  268. return pen_x - sys_x();
  269. }
  270. function pen_view_y(): f32 {
  271. return pen_y - sys_y();
  272. }
  273. let keyboard_keys: string[] = [
  274. "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
  275. "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "space", "backspace",
  276. "tab", "enter", "shift", "control", "alt", "win", "escape", "delete", "up", "down", "left", "right", "back", ",", ".", ":", ";", "<", "=",
  277. ">", "?", "!", "\"", "#", "$", "%", "&", "_", "(", ")", "*", "|", "{", "}", "[", "]", "~", "`",
  278. "/", "\\", "@", "+", "-", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12"
  279. ];
  280. let keyboard_keys_down: map_t<string, bool> = map_create();
  281. let keyboard_keys_started: map_t<string, bool> = map_create();
  282. let keyboard_keys_released: map_t<string, bool> = map_create();
  283. let keyboard_keys_frame: string[] = [];
  284. let keyboard_repeat_key: bool = false;
  285. let keyboard_repeat_time: f32 = 0.0;
  286. function keyboard_end_frame() {
  287. if (keyboard_keys_frame.length > 0) {
  288. for (let i: i32 = 0; i < keyboard_keys_frame.length; ++i) {
  289. let s: string = keyboard_keys_frame[i];
  290. map_set(keyboard_keys_started, s, false);
  291. map_set(keyboard_keys_released, s, false);
  292. }
  293. array_splice(keyboard_keys_frame, 0, keyboard_keys_frame.length);
  294. }
  295. if (sys_time() - keyboard_repeat_time > 0.05) {
  296. keyboard_repeat_time = sys_time();
  297. keyboard_repeat_key = true;
  298. }
  299. else {
  300. keyboard_repeat_key = false;
  301. }
  302. }
  303. function keyboard_reset() {
  304. // Use map_t for now..
  305. for (let i: i32 = 0; i < keyboard_keys.length; ++i) {
  306. let s: string = keyboard_keys[i];
  307. map_set(keyboard_keys_down, s, false);
  308. map_set(keyboard_keys_started, s, false);
  309. map_set(keyboard_keys_released, s, false);
  310. }
  311. keyboard_end_frame();
  312. }
  313. function keyboard_down(key: string): bool {
  314. return map_get(keyboard_keys_down, key);
  315. }
  316. function keyboard_started(key: string): bool {
  317. return map_get(keyboard_keys_started, key);
  318. }
  319. function keyboard_started_any(): bool {
  320. return keyboard_keys_frame.length > 0;
  321. }
  322. function keyboard_released(key: string): bool {
  323. return map_get(keyboard_keys_released, key);
  324. }
  325. function keyboard_repeat(key: string): bool {
  326. return map_get(keyboard_keys_started, key) || (keyboard_repeat_key && map_get(keyboard_keys_down, key));
  327. }
  328. function keyboard_key_code(key: key_code_t): string {
  329. if (key == key_code_t.SPACE) {
  330. return "space";
  331. }
  332. if (key == key_code_t.BACKSPACE) {
  333. return "backspace";
  334. }
  335. if (key == key_code_t.TAB) {
  336. return "tab";
  337. }
  338. if (key == key_code_t.RETURN) {
  339. return "enter";
  340. }
  341. if (key == key_code_t.SHIFT) {
  342. return "shift";
  343. }
  344. if (key == key_code_t.CONTROL) {
  345. return "control";
  346. }
  347. /// if arm_macos
  348. if (key == key_code_t.META) {
  349. return "control";
  350. }
  351. /// end
  352. if (key == key_code_t.ALT) {
  353. return "alt";
  354. }
  355. if (key == key_code_t.WIN) {
  356. return "win";
  357. }
  358. if (key == key_code_t.ESCAPE) {
  359. return "escape";
  360. }
  361. if (key == key_code_t.DELETE) {
  362. return "delete";
  363. }
  364. if (key == key_code_t.UP) {
  365. return "up";
  366. }
  367. if (key == key_code_t.DOWN) {
  368. return "down";
  369. }
  370. if (key == key_code_t.LEFT) {
  371. return "left";
  372. }
  373. if (key == key_code_t.RIGHT) {
  374. return "right";
  375. }
  376. if (key == key_code_t.BACK) {
  377. return "back";
  378. }
  379. if (key == key_code_t.COMMA) {
  380. return ",";
  381. }
  382. if (key == key_code_t.PERIOD) {
  383. return ".";
  384. }
  385. if (key == key_code_t.COLON) {
  386. return ":";
  387. }
  388. if (key == key_code_t.SEMICOLON) {
  389. return ";";
  390. }
  391. if (key == key_code_t.LESS_THAN) {
  392. return "<";
  393. }
  394. if (key == key_code_t.EQUALS) {
  395. return "=";
  396. }
  397. if (key == key_code_t.GREATER_THAN) {
  398. return ">";
  399. }
  400. if (key == key_code_t.QUESTION_MARK) {
  401. return "?";
  402. }
  403. if (key == key_code_t.EXCLAMATION) {
  404. return "!";
  405. }
  406. if (key == key_code_t.DOUBLE_QUOTE) {
  407. return "\"";
  408. }
  409. if (key == key_code_t.HASH) {
  410. return "#";
  411. }
  412. if (key == key_code_t.DOLLAR) {
  413. return "$";
  414. }
  415. if (key == key_code_t.PERCENT) {
  416. return "%";
  417. }
  418. if (key == key_code_t.AMPERSAND) {
  419. return "&";
  420. }
  421. if (key == key_code_t.UNDERSCORE) {
  422. return "_";
  423. }
  424. if (key == key_code_t.OPEN_PAREN) {
  425. return "(";
  426. }
  427. if (key == key_code_t.CLOSE_PAREN) {
  428. return ")";
  429. }
  430. if (key == key_code_t.ASTERISK) {
  431. return "*";
  432. }
  433. if (key == key_code_t.PIPE) {
  434. return "|";
  435. }
  436. if (key == key_code_t.OPEN_CURLY_BRACKET) {
  437. return "{";
  438. }
  439. if (key == key_code_t.CLOSE_CURLY_BRACKET) {
  440. return "}";
  441. }
  442. if (key == key_code_t.OPEN_BRACKET) {
  443. return "[";
  444. }
  445. if (key == key_code_t.CLOSE_BRACKET) {
  446. return "]";
  447. }
  448. if (key == key_code_t.TILDE) {
  449. return "~";
  450. }
  451. if (key == key_code_t.BACK_QUOTE) {
  452. return "`";
  453. }
  454. if (key == key_code_t.SLASH) {
  455. return "/";
  456. }
  457. if (key == key_code_t.BACK_SLASH) {
  458. return "\\";
  459. }
  460. if (key == key_code_t.AT) {
  461. return "@";
  462. }
  463. if (key == key_code_t.ADD) {
  464. return "+";
  465. }
  466. if (key == key_code_t.PLUS) {
  467. return "+";
  468. }
  469. if (key == key_code_t.SUBTRACT) {
  470. return "-";
  471. }
  472. if (key == key_code_t.HYPHEN_MINUS) {
  473. return "-";
  474. }
  475. if (key == key_code_t.MULTIPLY) {
  476. return "*";
  477. }
  478. if (key == key_code_t.DIVIDE) {
  479. return "/";
  480. }
  481. if (key == key_code_t.DECIMAL) {
  482. return ".";
  483. }
  484. if (key == key_code_t.ZERO) {
  485. return "0";
  486. }
  487. if (key == key_code_t.NUMPAD0) {
  488. return "0";
  489. }
  490. if (key == key_code_t.ONE) {
  491. return "1";
  492. }
  493. if (key == key_code_t.NUMPAD1) {
  494. return "1";
  495. }
  496. if (key == key_code_t.TWO) {
  497. return "2";
  498. }
  499. if (key == key_code_t.NUMPAD2) {
  500. return "2";
  501. }
  502. if (key == key_code_t.THREE) {
  503. return "3";
  504. }
  505. if (key == key_code_t.NUMPAD3) {
  506. return "3";
  507. }
  508. if (key == key_code_t.FOUR) {
  509. return "4";
  510. }
  511. if (key == key_code_t.NUMPAD4) {
  512. return "4";
  513. }
  514. if (key == key_code_t.FIVE) {
  515. return "5";
  516. }
  517. if (key == key_code_t.NUMPAD5) {
  518. return "5";
  519. }
  520. if (key == key_code_t.SIX) {
  521. return "6";
  522. }
  523. if (key == key_code_t.NUMPAD6) {
  524. return "6";
  525. }
  526. if (key == key_code_t.SEVEN) {
  527. return "7";
  528. }
  529. if (key == key_code_t.NUMPAD7) {
  530. return "7";
  531. }
  532. if (key == key_code_t.EIGHT) {
  533. return "8";
  534. }
  535. if (key == key_code_t.NUMPAD8) {
  536. return "8";
  537. }
  538. if (key == key_code_t.NINE) {
  539. return "9";
  540. }
  541. if (key == key_code_t.NUMPAD9) {
  542. return "9";
  543. }
  544. if (key == key_code_t.F1) {
  545. return "f1";
  546. }
  547. if (key == key_code_t.F2) {
  548. return "f2";
  549. }
  550. if (key == key_code_t.F3) {
  551. return "f3";
  552. }
  553. if (key == key_code_t.F4) {
  554. return "f4";
  555. }
  556. if (key == key_code_t.F5) {
  557. return "f5";
  558. }
  559. if (key == key_code_t.F6) {
  560. return "f6";
  561. }
  562. if (key == key_code_t.F7) {
  563. return "f7";
  564. }
  565. if (key == key_code_t.F8) {
  566. return "f8";
  567. }
  568. if (key == key_code_t.F9) {
  569. return "f9";
  570. }
  571. if (key == key_code_t.F10) {
  572. return "f10";
  573. }
  574. if (key == key_code_t.F11) {
  575. return "f11";
  576. }
  577. if (key == key_code_t.F12) {
  578. return "f12";
  579. }
  580. return to_lower_case(string_from_char_code(key));
  581. }
  582. function keyboard_down_listener(code: key_code_t) {
  583. let s: string = keyboard_key_code(code);
  584. array_push(keyboard_keys_frame, s);
  585. map_set(keyboard_keys_started, s, true);
  586. map_set(keyboard_keys_down, s, true);
  587. keyboard_repeat_time = sys_time() + 0.4;
  588. /// if arm_android_rmb // Detect right mouse button on Android..
  589. if (code == key_code_t.BACK) {
  590. if (!_mouse_buttons_down[1]) {
  591. mouse_down_listener(1, math_floor(mouse_x), math_floor(mouse_y));
  592. }
  593. }
  594. /// end
  595. }
  596. function keyboard_up_listener(code: key_code_t) {
  597. let s: string = keyboard_key_code(code);
  598. array_push(keyboard_keys_frame, s);
  599. map_set(keyboard_keys_released, s, true);
  600. map_set(keyboard_keys_down, s, false);
  601. /// if arm_android_rmb
  602. if (code == key_code_t.BACK) {
  603. mouse_up_listener(1, math_floor(mouse_x), math_floor(mouse_y));
  604. }
  605. /// end
  606. }
  607. /// if WITH_GAMEPAD
  608. let gamepad_buttons_ps: string[] =
  609. [ "cross", "circle", "square", "triangle", "l1", "r1", "l2", "r2", "share", "options", "l3", "r3", "up", "down", "left", "right", "home", "touchpad" ];
  610. let gamepad_buttons_xbox: string[] =
  611. [ "a", "b", "x", "y", "l1", "r1", "l2", "r2", "share", "options", "l3", "r3", "up", "down", "left", "right", "home", "touchpad" ];
  612. let gamepad_buttons: string[] = gamepad_buttons_ps;
  613. let gamepad_raws: gamepad_t[];
  614. function gamepad_end_frame() {
  615. // TODO: check valgrind error
  616. // for (let i: i32 = 0; i < gamepad_raws.length; ++i) {
  617. // let g: gamepad_t = gamepad_raws[i];
  618. // if (g.buttons_frame.length > 0) {
  619. // for (let j: i32 = 0; j < g.buttons_frame.length; ++j) {
  620. // let b: i32 = g.buttons_frame[j];
  621. // g.buttons_started[b] = false;
  622. // g.buttons_released[b] = false;
  623. // }
  624. // array_splice(g.buttons_frame, 0, g.buttons_frame.length);
  625. // }
  626. // g.left_stick.moved = false;
  627. // g.left_stick.movement_x = 0;
  628. // g.left_stick.movement_y = 0;
  629. // g.right_stick.moved = false;
  630. // g.right_stick.movement_x = 0;
  631. // g.right_stick.movement_y = 0;
  632. // }
  633. }
  634. function gamepad_stick_create(): gamepad_stick_t {
  635. let raw: gamepad_stick_t = {};
  636. raw.x = 0.0;
  637. raw.y = 0.0;
  638. raw.last_x = 0.0;
  639. raw.last_y = 0.0;
  640. raw.moved = false;
  641. raw.movement_x = 0.0;
  642. raw.movement_y = 0.0;
  643. return raw;
  644. }
  645. function gamepad_create(): gamepad_t {
  646. let raw: gamepad_t = {};
  647. raw.buttons_down = [];
  648. raw.buttons_started = [];
  649. raw.buttons_released = [];
  650. raw.buttons_frame = [];
  651. raw.left_stick = gamepad_stick_create();
  652. raw.right_stick = gamepad_stick_create();
  653. return raw;
  654. }
  655. function gamepad_reset() {
  656. gamepad_raws = [];
  657. for (let i: i32 = 0; i < 4; ++i) {
  658. let g: gamepad_t = gamepad_create();
  659. array_push(gamepad_raws, g);
  660. for (let i: i32 = 0; i < gamepad_buttons.length; ++i) {
  661. array_push(g.buttons_down, 0.0);
  662. array_push(g.buttons_started, false);
  663. array_push(g.buttons_released, false);
  664. }
  665. }
  666. gamepad_end_frame();
  667. }
  668. function gamepad_key_code(button: i32): string {
  669. return gamepad_buttons[button];
  670. }
  671. function gamepad_button_index(button: string): i32 {
  672. for (let i: i32 = 0; i < gamepad_buttons.length; ++i) {
  673. if (gamepad_buttons[i] == button) {
  674. return i;
  675. }
  676. }
  677. return 0;
  678. }
  679. function gamepad_down(i: i32, button: string): f32 {
  680. return gamepad_raws[i].buttons_down[gamepad_button_index(button)];
  681. }
  682. function gamepad_started(i: i32, button: string): bool {
  683. return gamepad_raws[i].buttons_started[gamepad_button_index(button)];
  684. }
  685. function gamepad_released(i: i32, button: string): bool {
  686. return gamepad_raws[i].buttons_released[gamepad_button_index(button)];
  687. }
  688. function gamepad_axis_listener(i: i32, axis: i32, value: f32) {
  689. let stick: gamepad_stick_t = axis <= 1 ? gamepad_raws[i].left_stick : gamepad_raws[i].right_stick;
  690. if (axis == 0 || axis == 2) { // X
  691. stick.last_x = stick.x;
  692. stick.x = value;
  693. stick.movement_x = stick.x - stick.last_x;
  694. }
  695. else if (axis == 1 || axis == 3) { // Y
  696. stick.last_y = stick.y;
  697. stick.y = value;
  698. stick.movement_y = stick.y - stick.last_y;
  699. }
  700. stick.moved = true;
  701. }
  702. function gamepad_button_listener(i: i32, button: i32, value: f32) {
  703. // array_push(gamepad_raws[i].buttons_frame, button);
  704. // gamepad_raws[i].buttons_down[button] = value;
  705. // if (value > 0) {
  706. // gamepad_raws[i].buttons_started[button] = true; // Will trigger L2/R2 multiple times..
  707. // }
  708. // else {
  709. // gamepad_raws[i].buttons_released[button] = true;
  710. // }
  711. }
  712. type gamepad_stick_t = {
  713. x?: f32;
  714. y?: f32;
  715. last_x?: f32;
  716. last_y?: f32;
  717. moved?: bool;
  718. movement_x?: f32;
  719. movement_y?: f32;
  720. };
  721. type gamepad_t = {
  722. buttons_down?: f32[]; // Intensity 0 - 1
  723. buttons_started?: bool[];
  724. buttons_released?: bool[];
  725. buttons_frame?: i32[];
  726. left_stick?: gamepad_stick_t;
  727. right_stick?: gamepad_stick_t;
  728. };
  729. /// end
  730. enum key_code_t {
  731. UNKNOWN = 0,
  732. BACK = 1, // Android
  733. CANCEL = 3,
  734. HELP = 6,
  735. BACKSPACE = 8,
  736. TAB = 9,
  737. RETURN = 13,
  738. SHIFT = 16,
  739. CONTROL = 17,
  740. ALT = 18,
  741. PAUSE = 19,
  742. CAPS_LOCK = 20,
  743. ESCAPE = 27,
  744. SPACE = 32,
  745. PAGE_UP = 33,
  746. PAGE_DOWN = 34,
  747. END = 35,
  748. HOME = 36,
  749. LEFT = 37,
  750. UP = 38,
  751. RIGHT = 39,
  752. DOWN = 40,
  753. PRINT_SCREEN = 44,
  754. INSERT = 45,
  755. DELETE = 46,
  756. ZERO = 48,
  757. ONE = 49,
  758. TWO = 50,
  759. THREE = 51,
  760. FOUR = 52,
  761. FIVE = 53,
  762. SIX = 54,
  763. SEVEN = 55,
  764. EIGHT = 56,
  765. NINE = 57,
  766. COLON = 58,
  767. SEMICOLON = 59,
  768. LESS_THAN = 60,
  769. EQUALS = 61,
  770. GREATER_THAN = 62,
  771. QUESTION_MARK = 63,
  772. AT = 64,
  773. A = 65,
  774. B = 66,
  775. C = 67,
  776. D = 68,
  777. E = 69,
  778. F = 70,
  779. G = 71,
  780. H = 72,
  781. I = 73,
  782. J = 74,
  783. K = 75,
  784. L = 76,
  785. M = 77,
  786. N = 78,
  787. O = 79,
  788. P = 80,
  789. Q = 81,
  790. R = 82,
  791. S = 83,
  792. T = 84,
  793. U = 85,
  794. V = 86,
  795. W = 87,
  796. X = 88,
  797. Y = 89,
  798. Z = 90,
  799. WIN = 91,
  800. CONTEXT_MENU = 93,
  801. SLEEP = 95,
  802. NUMPAD0 = 96,
  803. NUMPAD1 = 97,
  804. NUMPAD2 = 98,
  805. NUMPAD3 = 99,
  806. NUMPAD4 = 100,
  807. NUMPAD5 = 101,
  808. NUMPAD6 = 102,
  809. NUMPAD7 = 103,
  810. NUMPAD8 = 104,
  811. NUMPAD9 = 105,
  812. MULTIPLY = 106,
  813. ADD = 107,
  814. SEPARATOR = 108,
  815. SUBTRACT = 109,
  816. DECIMAL = 110,
  817. DIVIDE = 111,
  818. F1 = 112,
  819. F2 = 113,
  820. F3 = 114,
  821. F4 = 115,
  822. F5 = 116,
  823. F6 = 117,
  824. F7 = 118,
  825. F8 = 119,
  826. F9 = 120,
  827. F10 = 121,
  828. F11 = 122,
  829. F12 = 123,
  830. F13 = 124,
  831. F14 = 125,
  832. F15 = 126,
  833. F16 = 127,
  834. F17 = 128,
  835. F18 = 129,
  836. F19 = 130,
  837. F20 = 131,
  838. F21 = 132,
  839. F22 = 133,
  840. F23 = 134,
  841. F24 = 135,
  842. NUM_LOCK = 144,
  843. SCROLL_LOCK = 145,
  844. EXCLAMATION = 161,
  845. DOUBLE_QUOTE = 162,
  846. HASH = 163,
  847. DOLLAR = 164,
  848. PERCENT = 165,
  849. AMPERSAND = 166,
  850. UNDERSCORE = 167,
  851. OPEN_PAREN = 168,
  852. CLOSE_PAREN = 169,
  853. ASTERISK = 170,
  854. PLUS = 171,
  855. PIPE = 172,
  856. HYPHEN_MINUS = 173,
  857. OPEN_CURLY_BRACKET = 174,
  858. CLOSE_CURLY_BRACKET = 175,
  859. TILDE = 176,
  860. VOLUME_MUTE = 181,
  861. VOLUME_DOWN = 182,
  862. VOLUME_UP = 183,
  863. COMMA = 188,
  864. PERIOD = 190,
  865. SLASH = 191,
  866. BACK_QUOTE = 192,
  867. OPEN_BRACKET = 219,
  868. BACK_SLASH = 220,
  869. CLOSE_BRACKET = 221,
  870. QUOTE = 222,
  871. META = 224,
  872. ALTGR = 225,
  873. }