comparison io.c @ 907:b5d35222047e

Mega mouse support is mostly done
author Michael Pavone <pavone@retrodev.com>
date Sat, 28 Nov 2015 21:27:21 -0800
parents 0e5f9d6135be
children c030e4af32b7
comparison
equal deleted inserted replaced
906:8cf57c6558ed 907:b5d35222047e
42 BIND_GAMEPAD3, 42 BIND_GAMEPAD3,
43 BIND_GAMEPAD4, 43 BIND_GAMEPAD4,
44 BIND_GAMEPAD5, 44 BIND_GAMEPAD5,
45 BIND_GAMEPAD6, 45 BIND_GAMEPAD6,
46 BIND_GAMEPAD7, 46 BIND_GAMEPAD7,
47 BIND_GAMEPAD8 47 BIND_GAMEPAD8,
48 BIND_MOUSE1,
49 BIND_MOUSE2,
50 BIND_MOUSE3,
51 BIND_MOUSE4,
52 BIND_MOUSE5,
53 BIND_MOUSE6,
54 BIND_MOUSE7,
55 BIND_MOUSE8
48 }; 56 };
49 57
50 typedef enum { 58 typedef enum {
51 UI_DEBUG_MODE_INC, 59 UI_DEBUG_MODE_INC,
52 UI_DEBUG_PAL_INC, 60 UI_DEBUG_PAL_INC,
70 keybinding bindings[4]; 78 keybinding bindings[4];
71 uint8_t state; 79 uint8_t state;
72 } joydpad; 80 } joydpad;
73 81
74 typedef struct { 82 typedef struct {
75 io_port *port; 83 io_port *motion_port;
76 uint8_t mode; 84 keybinding buttons[MAX_MOUSE_BUTTONS];
85 uint8_t bind_type;
86 uint8_t motion_mode;
77 } mousebinding; 87 } mousebinding;
78 88
79 keybinding * bindings[0x10000]; 89 keybinding * bindings[0x10000];
80 keybinding * joybindings[MAX_JOYSTICKS]; 90 keybinding * joybindings[MAX_JOYSTICKS];
81 joydpad * joydpads[MAX_JOYSTICKS]; 91 joydpad * joydpads[MAX_JOYSTICKS];
82 mousebinding *mice[MAX_MICE]; 92 mousebinding mice[MAX_MICE];
83 const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; 93 const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT};
84 94
85 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) 95 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value)
86 { 96 {
87 int bucket = keycode >> 15 & 0xFFFF; 97 int bucket = keycode >> 15 & 0xFFFF;
152 #define BUTTON_A GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x10) 162 #define BUTTON_A GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x10)
153 #define BUTTON_B GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x10) 163 #define BUTTON_B GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x10)
154 #define BUTTON_START GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x20) 164 #define BUTTON_START GAMEPAD_BUTTON(GAMEPAD_TH0, GAMEPAD_NONE, 0x20)
155 #define BUTTON_C GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x20) 165 #define BUTTON_C GAMEPAD_BUTTON(GAMEPAD_TH1, GAMEPAD_NONE, 0x20)
156 166
167 #define PSEUDO_BUTTON_MOTION 0xFFFF
168 #define MOUSE_LEFT 1
169 #define MOUSE_RIGHT 2
170 #define MOUSE_MIDDLE 4
171 #define MOUSE_START 8
172
173
174
157 void bind_gamepad(int keycode, int gamepadnum, int button) 175 void bind_gamepad(int keycode, int gamepadnum, int button)
158 { 176 {
159 177
160 if (gamepadnum < 1 || gamepadnum > 8) { 178 if (gamepadnum < 1 || gamepadnum > 8) {
161 return; 179 return;
197 bind_dpad(joystick, dpad, direction, BIND_UI, action, 0, param); 215 bind_dpad(joystick, dpad, direction, BIND_UI, action, 0, param);
198 } 216 }
199 217
200 void handle_binding_down(keybinding * binding) 218 void handle_binding_down(keybinding * binding)
201 { 219 {
202 if (binding->bind_type >= BIND_GAMEPAD1) 220 if (binding->bind_type >= BIND_GAMEPAD1 && binding->bind_type <= BIND_GAMEPAD8)
203 { 221 {
204 if (binding->subtype_a <= GAMEPAD_EXTRA && binding->port) { 222 if (binding->subtype_a <= GAMEPAD_EXTRA && binding->port) {
205 binding->port->input[binding->subtype_a] |= binding->value; 223 binding->port->input[binding->subtype_a] |= binding->value;
206 } 224 }
207 if (binding->subtype_b <= GAMEPAD_EXTRA && binding->port) { 225 if (binding->subtype_b <= GAMEPAD_EXTRA && binding->port) {
208 binding->port->input[binding->subtype_b] |= binding->value; 226 binding->port->input[binding->subtype_b] |= binding->value;
227 }
228 }
229 else if (binding->bind_type >= BIND_MOUSE1 && binding->bind_type <= BIND_MOUSE8)
230 {
231 if (binding->port) {
232 binding->port->input[0] |= binding->value;
209 } 233 }
210 } 234 }
211 } 235 }
212 236
213 void handle_keydown(int keycode) 237 void handle_keydown(int keycode)
228 } 252 }
229 keybinding * binding = joybindings[joystick] + button; 253 keybinding * binding = joybindings[joystick] + button;
230 handle_binding_down(binding); 254 handle_binding_down(binding);
231 } 255 }
232 256
257 void handle_mousedown(int mouse, int button)
258 {
259 if (mouse >= MAX_MICE || button > MAX_MOUSE_BUTTONS || button <= 0) {
260 return;
261 }
262 keybinding * binding = mice[mouse].buttons + button - 1;
263 handle_binding_down(binding);
264 }
265
233 uint8_t ui_debug_mode = 0; 266 uint8_t ui_debug_mode = 0;
234 uint8_t ui_debug_pal = 0; 267 uint8_t ui_debug_pal = 0;
235 268
236 int current_speed = 0; 269 int current_speed = 0;
237 int num_speeds = 1; 270 int num_speeds = 1;
241 { 274 {
242 switch(binding->bind_type) 275 switch(binding->bind_type)
243 { 276 {
244 case BIND_GAMEPAD1: 277 case BIND_GAMEPAD1:
245 case BIND_GAMEPAD2: 278 case BIND_GAMEPAD2:
279 case BIND_GAMEPAD3:
280 case BIND_GAMEPAD4:
281 case BIND_GAMEPAD5:
282 case BIND_GAMEPAD6:
283 case BIND_GAMEPAD7:
284 case BIND_GAMEPAD8:
246 if (binding->subtype_a <= GAMEPAD_EXTRA && binding->port) { 285 if (binding->subtype_a <= GAMEPAD_EXTRA && binding->port) {
247 binding->port->input[binding->subtype_a] &= ~binding->value; 286 binding->port->input[binding->subtype_a] &= ~binding->value;
248 } 287 }
249 if (binding->subtype_b <= GAMEPAD_EXTRA && binding->port) { 288 if (binding->subtype_b <= GAMEPAD_EXTRA && binding->port) {
250 binding->port->input[binding->subtype_b] &= ~binding->value; 289 binding->port->input[binding->subtype_b] &= ~binding->value;
290 }
291 break;
292 case BIND_MOUSE1:
293 case BIND_MOUSE2:
294 case BIND_MOUSE3:
295 case BIND_MOUSE4:
296 case BIND_MOUSE5:
297 case BIND_MOUSE6:
298 case BIND_MOUSE7:
299 case BIND_MOUSE8:
300 if (binding->port) {
301 binding->port->input[0] &= ~binding->value;
251 } 302 }
252 break; 303 break;
253 case BIND_UI: 304 case BIND_UI:
254 switch (binding->subtype_a) 305 switch (binding->subtype_a)
255 { 306 {
342 handle_binding_up(dpad->bindings + i); 393 handle_binding_up(dpad->bindings + i);
343 } 394 }
344 } 395 }
345 } 396 }
346 397
398 void handle_mouseup(int mouse, int button)
399 {
400 if (mouse >= MAX_MICE || button > MAX_MOUSE_BUTTONS || button <= 0) {
401 return;
402 }
403 keybinding * binding = mice[mouse].buttons + button - 1;
404 handle_binding_up(binding);
405 }
406
347 void handle_mouse_moved(int mouse, uint16_t x, uint16_t y) 407 void handle_mouse_moved(int mouse, uint16_t x, uint16_t y)
348 { 408 {
349 printf("mouse motion: %d - (%d, %d)\n", mouse, x, y); 409 if (mouse >= MAX_MICE || !mice[mouse].motion_port) {
350 if (mouse >= MAX_MICE || !mice[mouse]) { 410 return;
351 return; 411 }
352 } 412 //TODO: relative mode
353 413 //TODO: scale based on window size
354 } 414 mice[mouse].motion_port->device.mouse.cur_x = x;
355 415 mice[mouse].motion_port->device.mouse.cur_y = y;
356 int parse_binding_target(char * target, tern_node * padbuttons, int * ui_out, int * padnum_out, int * padbutton_out) 416 }
357 { 417
358 int gpadslen = strlen("gamepads."); 418 int parse_binding_target(char * target, tern_node * padbuttons, tern_node *mousebuttons, int * ui_out, int * padnum_out, int * padbutton_out)
419 {
420 const int gpadslen = strlen("gamepads.");
421 const int mouselen = strlen("mouse.");
359 if (!strncmp(target, "gamepads.", gpadslen)) { 422 if (!strncmp(target, "gamepads.", gpadslen)) {
360 if (target[gpadslen] >= '1' && target[gpadslen] <= '8') { 423 if (target[gpadslen] >= '1' && target[gpadslen] <= '8') {
361 int padnum = target[gpadslen] - '0'; 424 int padnum = target[gpadslen] - '0';
362 int button = tern_find_int(padbuttons, target + gpadslen + 1, 0); 425 int button = tern_find_int(padbuttons, target + gpadslen + 1, 0);
363 if (button) { 426 if (button) {
364 *padnum_out = padnum; 427 *padnum_out = padnum;
365 *padbutton_out = button; 428 *padbutton_out = button;
366 return 1; 429 return BIND_GAMEPAD1;
367 } else { 430 } else {
368 if (target[gpadslen+1]) { 431 if (target[gpadslen+1]) {
369 warning("Gamepad mapping string '%s' refers to an invalid button '%s'\n", target, target + gpadslen + 1); 432 warning("Gamepad mapping string '%s' refers to an invalid button '%s'\n", target, target + gpadslen + 1);
370 } else { 433 } else {
371 warning("Gamepad mapping string '%s' has no button component\n", target); 434 warning("Gamepad mapping string '%s' has no button component\n", target);
372 } 435 }
373 } 436 }
374 } else { 437 } else {
375 warning("Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]); 438 warning("Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]);
439 }
440 } else if(!strncmp(target, "mouse.", mouselen)) {
441 if (target[mouselen] >= '1' && target[mouselen] <= '8') {
442 int mousenum = target[mouselen] - '0';
443 int button = tern_find_int(mousebuttons, target + mouselen + 1, 0);
444 if (button) {
445 *padnum_out = mousenum;
446 *padbutton_out = button;
447 return BIND_MOUSE1;
448 } else {
449 if (target[mouselen+1]) {
450 warning("Mouse mapping string '%s' refers to an invalid button '%s'\n", target, target + mouselen + 1);
451 } else {
452 warning("Mouse mapping string '%s' has no button component\n", target);
453 }
454 }
455 } else {
456 warning("Gamepad mapping string '%s' refers to an invalid mouse number %c\n", target, target[mouselen]);
376 } 457 }
377 } else if(!strncmp(target, "ui.", strlen("ui."))) { 458 } else if(!strncmp(target, "ui.", strlen("ui."))) {
378 *padbutton_out = 0; 459 *padbutton_out = 0;
379 if (!strcmp(target + 3, "vdp_debug_mode")) { 460 if (!strcmp(target + 3, "vdp_debug_mode")) {
380 *ui_out = UI_DEBUG_MODE_INC; 461 *ui_out = UI_DEBUG_MODE_INC;
395 *ui_out = UI_EXIT; 476 *ui_out = UI_EXIT;
396 } else { 477 } else {
397 warning("Unreconized UI binding type %s\n", target); 478 warning("Unreconized UI binding type %s\n", target);
398 return 0; 479 return 0;
399 } 480 }
400 return 2; 481 return BIND_UI;
401 } else { 482 } else {
402 warning("Unrecognized binding type %s\n", target); 483 warning("Unrecognized binding type %s\n", target);
403 } 484 }
404 return 0; 485 return 0;
405 } 486 }
406 487
407 void process_keys(tern_node * cur, tern_node * special, tern_node * padbuttons, char * prefix) 488 void process_keys(tern_node * cur, tern_node * special, tern_node * padbuttons, tern_node *mousebuttons, char * prefix)
408 { 489 {
409 char * curstr = NULL; 490 char * curstr = NULL;
410 int len; 491 int len;
411 if (!cur) { 492 if (!cur) {
412 return; 493 return;
421 len = 0; 502 len = 0;
422 } 503 }
423 curstr[len] = cur->el; 504 curstr[len] = cur->el;
424 curstr[len+1] = 0; 505 curstr[len+1] = 0;
425 if (cur->el) { 506 if (cur->el) {
426 process_keys(cur->straight.next, special, padbuttons, curstr); 507 process_keys(cur->straight.next, special, padbuttons, mousebuttons, curstr);
427 } else { 508 } else {
428 int keycode = tern_find_int(special, curstr, 0); 509 int keycode = tern_find_int(special, curstr, 0);
429 if (!keycode) { 510 if (!keycode) {
430 keycode = curstr[0]; 511 keycode = curstr[0];
431 if (curstr[1] != 0) { 512 if (curstr[1] != 0) {
432 warning("%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]); 513 warning("%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]);
433 } 514 }
434 } 515 }
435 char * target = cur->straight.value.ptrval; 516 char * target = cur->straight.value.ptrval;
436 int ui_func, padnum, button; 517 int ui_func, padnum, button;
437 int bindtype = parse_binding_target(target, padbuttons, &ui_func, &padnum, &button); 518 int bindtype = parse_binding_target(target, padbuttons, mousebuttons, &ui_func, &padnum, &button);
438 if (bindtype == 1) { 519 if (bindtype == BIND_GAMEPAD1) {
439 bind_gamepad(keycode, padnum, button); 520 bind_gamepad(keycode, padnum, button);
440 } else if(bindtype == 2) { 521 } else if(bindtype == BIND_UI) {
441 bind_ui(keycode, ui_func, button); 522 bind_ui(keycode, ui_func, button);
442 } 523 }
443 } 524 }
444 process_keys(cur->left, special, padbuttons, prefix); 525 process_keys(cur->left, special, padbuttons, mousebuttons, prefix);
445 process_keys(cur->right, special, padbuttons, prefix); 526 process_keys(cur->right, special, padbuttons, mousebuttons, prefix);
446 if (curstr && len) { 527 if (curstr && len) {
447 free(curstr); 528 free(curstr);
448 } 529 }
449 } 530 }
450 531
518 } else { 599 } else {
519 port->device_type = IO_GAMEPAD6; 600 port->device_type = IO_GAMEPAD6;
520 } 601 }
521 port->device.pad.gamepad_num = device_type[gamepad_len+2] - '1'; 602 port->device.pad.gamepad_num = device_type[gamepad_len+2] - '1';
522 } else if(!strncmp(device_type, "mouse", mouse_len)) { 603 } else if(!strncmp(device_type, "mouse", mouse_len)) {
523 //TODO: do something with mouse number
524 port->device_type = IO_MOUSE; 604 port->device_type = IO_MOUSE;
605 port->device.mouse.mouse_num = device_type[mouse_len+1] - '1';
606 port->device.mouse.last_read_x = 0;
607 port->device.mouse.last_read_y = 0;
608 port->device.mouse.cur_x = 0;
609 port->device.mouse.cur_y = 0;
610 port->device.mouse.tr_counter = 0;
525 } else if(!strcmp(device_type, "sega_parallel")) { 611 } else if(!strcmp(device_type, "sega_parallel")) {
526 port->device_type = IO_SEGA_PARALLEL; 612 port->device_type = IO_SEGA_PARALLEL;
527 port->device.stream.data_fd = -1; 613 port->device.stream.data_fd = -1;
528 port->device.stream.listen_fd = -1; 614 port->device.stream.listen_fd = -1;
529 } else if(!strcmp(device_type, "generic")) { 615 } else if(!strcmp(device_type, "generic")) {
641 727
642 void map_bindings(io_port *ports, keybinding *bindings, int numbindings) 728 void map_bindings(io_port *ports, keybinding *bindings, int numbindings)
643 { 729 {
644 for (int i = 0; i < numbindings; i++) 730 for (int i = 0; i < numbindings; i++)
645 { 731 {
646 if (bindings[i].bind_type >= BIND_GAMEPAD1) 732 if (bindings[i].bind_type >= BIND_GAMEPAD1 && bindings[i].bind_type <= BIND_GAMEPAD8)
647 { 733 {
648 int num = bindings[i].bind_type - BIND_GAMEPAD1; 734 int num = bindings[i].bind_type - BIND_GAMEPAD1;
649 for (int j = 0; j < 3; j++) 735 for (int j = 0; j < 3; j++)
650 { 736 {
651 if ((ports[j].device_type == IO_GAMEPAD3 737 if ((ports[j].device_type == IO_GAMEPAD3
657 bindings[i].port = ports + j; 743 bindings[i].port = ports + j;
658 break; 744 break;
659 } 745 }
660 } 746 }
661 } 747 }
748 else if (bindings[i].bind_type >= BIND_MOUSE1 && bindings[i].bind_type <= BIND_MOUSE8)
749 {
750 int num = bindings[i].bind_type - BIND_MOUSE1;
751 for (int j = 0; j < 3; j++)
752 {
753 if (ports[j].device_type == IO_MOUSE && ports[j].device.mouse.mouse_num == num)
754 {
755 memset(ports[j].input, 0, sizeof(ports[j].input));
756 bindings[i].port = ports + j;
757 break;
758 }
759 }
760 }
761 }
762 }
763
764 typedef struct {
765 tern_node *padbuttons;
766 tern_node *mousebuttons;
767 int mouseidx;
768 } pmb_state;
769
770 void process_mouse_button(char *buttonstr, tern_val value, void *data)
771 {
772 pmb_state *state = data;
773 int buttonnum = atoi(buttonstr);
774 if (buttonnum < 1 || buttonnum > MAX_MOUSE_BUTTONS) {
775 warning("Mouse button %s is out of the supported range of 1-8\n", buttonstr);
776 return;
777 }
778 buttonnum--;
779 int ui_func, devicenum, button;
780 int bindtype = parse_binding_target(value.ptrval, state->padbuttons, state->mousebuttons, &ui_func, &devicenum, &button);
781 switch (bindtype)
782 {
783 case BIND_UI:
784 mice[state->mouseidx].buttons[buttonnum].subtype_a = ui_func;
785 break;
786 case BIND_GAMEPAD1:
787 mice[state->mouseidx].buttons[buttonnum].subtype_a = button >> 12;
788 mice[state->mouseidx].buttons[buttonnum].subtype_b = button >> 8 & 0xF;
789 mice[state->mouseidx].buttons[buttonnum].value = button & 0xFF;
790 break;
791 case BIND_MOUSE1:
792 mice[state->mouseidx].buttons[buttonnum].value = button & 0xFF;
793 break;
794 }
795 if (bindtype != BIND_UI) {
796 bindtype += devicenum-1;
797 }
798 mice[state->mouseidx].buttons[buttonnum].bind_type = bindtype;
799
800 }
801
802 void process_mouse(char *mousenum, tern_val value, void *data)
803 {
804 tern_node **buttonmaps = data;
805 tern_node *mousedef = tern_get_node(value);
806 tern_node *padbuttons = buttonmaps[0];
807 tern_node *mousebuttons = buttonmaps[1];
808
809 if (!mousedef) {
810 warning("Binding for mouse %s is a scalar!\n", mousenum);
811 return;
812 }
813 int mouseidx = atoi(mousenum);
814 if (mouseidx < 0 || mouseidx >= MAX_MICE) {
815 warning("Mouse numbers must be between 0 and %d, but %d is not\n", MAX_MICE, mouseidx);
816 return;
817 }
818 char *motion = tern_find_ptr(mousedef, "motion");
819 if (motion) {
820 int ui_func,devicenum,button;
821 int bindtype = parse_binding_target(motion, padbuttons, mousebuttons, &ui_func, &devicenum, &button);
822 if (bindtype != BIND_UI) {
823 bindtype += devicenum-1;
824 }
825 if (button == PSEUDO_BUTTON_MOTION) {
826 mice[mouseidx].bind_type = bindtype;
827 } else {
828 warning("Mouse motion can't be bound to target %s\n", motion);
829 }
830 }
831 tern_node *buttons = tern_get_node(tern_find_path(mousedef, "buttons\0\0"));
832 if (buttons) {
833 pmb_state state = {padbuttons, mousebuttons, mouseidx};
834 tern_foreach(buttons, process_mouse_button, &state);
662 } 835 }
663 } 836 }
664 837
665 void set_keybindings(io_port *ports) 838 void set_keybindings(io_port *ports)
666 { 839 {
687 padbuttons = tern_insert_int(padbuttons, ".x", BUTTON_X); 860 padbuttons = tern_insert_int(padbuttons, ".x", BUTTON_X);
688 padbuttons = tern_insert_int(padbuttons, ".y", BUTTON_Y); 861 padbuttons = tern_insert_int(padbuttons, ".y", BUTTON_Y);
689 padbuttons = tern_insert_int(padbuttons, ".z", BUTTON_Z); 862 padbuttons = tern_insert_int(padbuttons, ".z", BUTTON_Z);
690 padbuttons = tern_insert_int(padbuttons, ".start", BUTTON_START); 863 padbuttons = tern_insert_int(padbuttons, ".start", BUTTON_START);
691 padbuttons = tern_insert_int(padbuttons, ".mode", BUTTON_MODE); 864 padbuttons = tern_insert_int(padbuttons, ".mode", BUTTON_MODE);
865
866 tern_node *mousebuttons = tern_insert_int(NULL, ".left", MOUSE_LEFT);
867 mousebuttons = tern_insert_int(mousebuttons, ".middle", MOUSE_MIDDLE);
868 mousebuttons = tern_insert_int(mousebuttons, ".right", MOUSE_RIGHT);
869 mousebuttons = tern_insert_int(mousebuttons, ".start", MOUSE_START);
870 mousebuttons = tern_insert_int(mousebuttons, ".motion", PSEUDO_BUTTON_MOTION);
692 871
693 tern_node * keys = tern_get_node(tern_find_path(config, "bindings\0keys\0")); 872 tern_node * keys = tern_get_node(tern_find_path(config, "bindings\0keys\0"));
694 process_keys(keys, special, padbuttons, NULL); 873 process_keys(keys, special, padbuttons, mousebuttons, NULL);
695 char numstr[] = "00"; 874 char numstr[] = "00";
696 tern_node * pads = tern_get_node(tern_find_path(config, "bindings\0pads\0")); 875 tern_node * pads = tern_get_node(tern_find_path(config, "bindings\0pads\0"));
697 if (pads) { 876 if (pads) {
698 for (int i = 0; i < 100 && i < render_num_joysticks(); i++) 877 for (int i = 0; i < 100 && i < render_num_joysticks(); i++)
699 { 878 {
718 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; 897 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT};
719 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) { 898 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) {
720 char * target = tern_find_ptr(pad_dpad, dirs[dir]); 899 char * target = tern_find_ptr(pad_dpad, dirs[dir]);
721 if (target) { 900 if (target) {
722 int ui_func, padnum, button; 901 int ui_func, padnum, button;
723 int bindtype = parse_binding_target(target, padbuttons, &ui_func, &padnum, &button); 902 int bindtype = parse_binding_target(target, padbuttons, mousebuttons, &ui_func, &padnum, &button);
724 if (bindtype == 1) { 903 if (bindtype == BIND_GAMEPAD1) {
725 bind_dpad_gamepad(i, dpad, dirnums[dir], padnum, button); 904 bind_dpad_gamepad(i, dpad, dirnums[dir], padnum, button);
726 } else if (bindtype == 2) { 905 } else if (bindtype == BIND_UI) {
727 bind_dpad_ui(i, dpad, dirnums[dir], ui_func, button); 906 bind_dpad_ui(i, dpad, dirnums[dir], ui_func, button);
728 } 907 }
729 } 908 }
730 } 909 }
731 } 910 }
742 numstr[1] = but%10 + '0'; 921 numstr[1] = but%10 + '0';
743 } 922 }
744 char * target = tern_find_ptr(button_node, numstr); 923 char * target = tern_find_ptr(button_node, numstr);
745 if (target) { 924 if (target) {
746 int ui_func, padnum, button; 925 int ui_func, padnum, button;
747 int bindtype = parse_binding_target(target, padbuttons, &ui_func, &padnum, &button); 926 int bindtype = parse_binding_target(target, padbuttons, mousebuttons, &ui_func, &padnum, &button);
748 if (bindtype == 1) { 927 if (bindtype == BIND_GAMEPAD1) {
749 bind_button_gamepad(i, but, padnum, button); 928 bind_button_gamepad(i, but, padnum, button);
750 } else if (bindtype == 2) { 929 } else if (bindtype == BIND_UI) {
751 bind_button_ui(i, but, ui_func, button); 930 bind_button_ui(i, but, ui_func, button);
752 } 931 }
753 } 932 }
754 } 933 }
755 } 934 }
756 } 935 }
757 } 936 }
937 }
938 memset(mice, 0, sizeof(mice));
939 tern_node * mice = tern_get_node(tern_find_path(config, "bindings\0mice\0"));
940 if (mice) {
941 tern_node *buttonmaps[2] = {padbuttons, mousebuttons};
942 tern_foreach(mice, process_mouse, buttonmaps);
758 } 943 }
759 tern_node * speed_nodes = tern_get_node(tern_find_path(config, "clocks\0speeds\0")); 944 tern_node * speed_nodes = tern_get_node(tern_find_path(config, "clocks\0speeds\0"));
760 speeds = malloc(sizeof(uint32_t)); 945 speeds = malloc(sizeof(uint32_t));
761 speeds[0] = 100; 946 speeds[0] = 100;
762 process_speeds(speed_nodes, NULL); 947 process_speeds(speed_nodes, NULL);
788 } 973 }
789 if (joydpads[stick]) 974 if (joydpads[stick])
790 { 975 {
791 map_bindings(ports, joydpads[stick]->bindings, 4); 976 map_bindings(ports, joydpads[stick]->bindings, 4);
792 } 977 }
978 }
979 for (int mouse = 0; mouse < MAX_MICE; mouse++)
980 {
981 if (mice[mouse].bind_type >= BIND_MOUSE1 && mice[mouse].bind_type <= BIND_MOUSE8) {
982 int num = mice[mouse].bind_type - BIND_MOUSE1;
983 for (int j = 0; j < 3; j++)
984 {
985 if (ports[j].device_type == IO_MOUSE && ports[j].device.mouse.mouse_num == num)
986 {
987 memset(ports[j].input, 0, sizeof(ports[j].input));
988 mice[mouse].motion_port = ports + j;
989 break;
990 }
991 }
992 }
993 map_bindings(ports, mice[mouse].buttons, MAX_MOUSE_BUTTONS);
793 } 994 }
794 } 995 }
795 996
796 #define TH 0x40 997 #define TH 0x40
797 #define TR 0x20 998 #define TR 0x20
1012 input = 0x10; 1213 input = 0x10;
1013 } else { 1214 } else {
1014 input = 0; 1215 input = 0;
1015 } 1216 }
1016 } else { 1217 } else {
1017 int deltax = port->device.mouse.cur_x - port->device.mouse.last_read_x;
1018 int deltay = port->device.mouse.cur_y - port->device.mouse.last_read_y;
1019 switch (port->device.mouse.tr_counter) 1218 switch (port->device.mouse.tr_counter)
1020 { 1219 {
1021 case 0: 1220 case 0:
1022 input = 0xB; 1221 input = 0xB;
1023 break; 1222 break;
1025 case 2: 1224 case 2:
1026 input = 0xF; 1225 input = 0xF;
1027 break; 1226 break;
1028 case 3: 1227 case 3:
1029 input = 0; 1228 input = 0;
1030 if (deltay > 255 || deltay < -255) { 1229 //it would be unfortunate if our event handler updated cur_x or cur_y in the middle
1230 //of the mouse poll sequence, so we save the delta here
1231 port->device.mouse.delta_x = port->device.mouse.cur_x - port->device.mouse.last_read_x;
1232 port->device.mouse.delta_y = port->device.mouse.cur_y - port->device.mouse.last_read_y;
1233 if (port->device.mouse.delta_y > 255 || port->device.mouse.delta_y < -255) {
1031 input |= 8; 1234 input |= 8;
1032 } 1235 }
1033 if (deltax > 255 || deltax < -255) { 1236 if (port->device.mouse.delta_x > 255 || port->device.mouse.delta_x < -255) {
1034 input |= 4; 1237 input |= 4;
1035 } 1238 }
1036 if (deltay < 0) { 1239 if (port->device.mouse.delta_y < 0) {
1037 input |= 2; 1240 input |= 2;
1038 } 1241 }
1039 if (deltax < 0) { 1242 if (port->device.mouse.delta_x < 0) {
1040 input |= 1; 1243 input |= 1;
1041 } 1244 }
1042 break; 1245 break;
1043 case 4: 1246 case 4:
1044 input = port->input[0]; 1247 input = port->input[0];
1045 break; 1248 break;
1046 case 5: 1249 case 5:
1047 input = abs(deltax) >> 4 & 0xF; 1250 input = abs(port->device.mouse.delta_x) >> 4 & 0xF;
1048 break; 1251 break;
1049 case 6: 1252 case 6:
1050 input = abs(deltax) & 0xF; 1253 input = abs(port->device.mouse.delta_x) & 0xF;
1051 break; 1254 break;
1052 case 7: 1255 case 7:
1053 input = abs(deltay) >> 4 & 0xF; 1256 input = abs(port->device.mouse.delta_y) >> 4 & 0xF;
1054 break; 1257 break;
1055 case 8: 1258 case 8:
1056 input = abs(deltay) & 0xF; 1259 input = abs(port->device.mouse.delta_y) & 0xF;
1057 //need to figure out when this actually happens 1260 //need to figure out when this actually happens
1058 port->device.mouse.last_read_x = port->device.mouse.cur_x; 1261 port->device.mouse.last_read_x = port->device.mouse.cur_x;
1059 port->device.mouse.last_read_y = port->device.mouse.cur_y; 1262 port->device.mouse.last_read_y = port->device.mouse.cur_y;
1060 break; 1263 break;
1061 default: 1264 default: