comparison io.c @ 915:9e882eca717e

Initial support for relative mouse mode and skeleton of support for capture mode. Avoid mouse position overflow in absolute mode. Allow absolute mode to be set by ROM DB.
author Michael Pavone <pavone@retrodev.com>
date Tue, 15 Dec 2015 20:01:50 -0800
parents 28ec32e720b2
children 20c464dbae8f
comparison
equal deleted inserted replaced
914:28ec32e720b2 915:9e882eca717e
66 UI_NEXT_SPEED, 66 UI_NEXT_SPEED,
67 UI_PREV_SPEED, 67 UI_PREV_SPEED,
68 UI_EXIT 68 UI_EXIT
69 } ui_action; 69 } ui_action;
70 70
71 typedef enum {
72 MOUSE_ABSOLUTE, //really only useful for menu ROM
73 MOUSE_RELATIVE, //for full screen
74 MOUSE_CAPTURE //for windowed mode
75 } mouse_modes;
76
77
71 typedef struct { 78 typedef struct {
72 io_port *port; 79 io_port *port;
73 uint8_t bind_type; 80 uint8_t bind_type;
74 uint8_t subtype_a; 81 uint8_t subtype_a;
75 uint8_t subtype_b; 82 uint8_t subtype_b;
83 90
84 typedef struct { 91 typedef struct {
85 io_port *motion_port; 92 io_port *motion_port;
86 keybinding buttons[MAX_MOUSE_BUTTONS]; 93 keybinding buttons[MAX_MOUSE_BUTTONS];
87 uint8_t bind_type; 94 uint8_t bind_type;
88 uint8_t motion_mode;
89 } mousebinding; 95 } mousebinding;
90 96
91 keybinding * bindings[0x10000]; 97 keybinding * bindings[0x10000];
92 keybinding * joybindings[MAX_JOYSTICKS]; 98 keybinding * joybindings[MAX_JOYSTICKS];
93 joydpad * joydpads[MAX_JOYSTICKS]; 99 joydpad * joydpads[MAX_JOYSTICKS];
94 mousebinding mice[MAX_MICE]; 100 mousebinding mice[MAX_MICE];
95 const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; 101 const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT};
102 mouse_modes mouse_mode;
96 103
97 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) 104 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value)
98 { 105 {
99 int bucket = keycode >> 15 & 0xFFFF; 106 int bucket = keycode >> 15 & 0xFFFF;
100 if (!bindings[bucket]) { 107 if (!bindings[bucket]) {
404 } 411 }
405 keybinding * binding = mice[mouse].buttons + button - 1; 412 keybinding * binding = mice[mouse].buttons + button - 1;
406 handle_binding_up(binding); 413 handle_binding_up(binding);
407 } 414 }
408 415
409 void handle_mouse_moved(int mouse, uint16_t x, uint16_t y) 416 void handle_mouse_moved(int mouse, uint16_t x, uint16_t y, int16_t deltax, int16_t deltay)
410 { 417 {
411 if (mouse >= MAX_MICE || !mice[mouse].motion_port) { 418 if (mouse >= MAX_MICE || !mice[mouse].motion_port) {
412 return; 419 return;
413 } 420 }
414 //TODO: relative mode 421 //TODO: relative mode
415 float scale_x = 640.0 / ((float)render_width()); 422 switch(mouse_mode)
416 float scale_y = 480.0 / ((float)render_height()); 423 {
417 float scale = scale_x > scale_y ? scale_y : scale_x; 424 case MOUSE_ABSOLUTE: {
418 mice[mouse].motion_port->device.mouse.cur_x = x * scale_x; 425 float scale_x = 640.0 / ((float)render_width());
419 mice[mouse].motion_port->device.mouse.cur_y = y * scale_y; 426 float scale_y = 480.0 / ((float)render_height());
427 float scale = scale_x > scale_y ? scale_y : scale_x;
428 mice[mouse].motion_port->device.mouse.cur_x = x * scale_x;
429 mice[mouse].motion_port->device.mouse.cur_y = y * scale_y;
430 break;
431 }
432 case MOUSE_RELATIVE: {
433 mice[mouse].motion_port->device.mouse.cur_x += deltax;
434 mice[mouse].motion_port->device.mouse.cur_y += deltay;
435 break;
436 }
437 case MOUSE_CAPTURE: {
438 }
439 }
420 } 440 }
421 441
422 int parse_binding_target(char * target, tern_node * padbuttons, tern_node *mousebuttons, int * ui_out, int * padnum_out, int * padbutton_out) 442 int parse_binding_target(char * target, tern_node * padbuttons, tern_node *mousebuttons, int * ui_out, int * padnum_out, int * padbutton_out)
423 { 443 {
424 const int gpadslen = strlen("gamepads."); 444 const int gpadslen = strlen("gamepads.");
655 char * io_ext = rom->ext_override ? rom->ext_override : tern_find_ptr(io_nodes, "ext"); 675 char * io_ext = rom->ext_override ? rom->ext_override : tern_find_ptr(io_nodes, "ext");
656 676
657 process_device(io_1, ports); 677 process_device(io_1, ports);
658 process_device(io_2, ports+1); 678 process_device(io_2, ports+1);
659 process_device(io_ext, ports+2); 679 process_device(io_ext, ports+2);
680
681 if (rom->mouse_mode && !strcmp(rom->mouse_mode, "absolute")) {
682 mouse_mode = MOUSE_ABSOLUTE;
683 } else {
684 if (render_fullscreen()) {
685 mouse_mode = MOUSE_RELATIVE;
686 render_relative_mouse(1);
687 } else {
688 mouse_mode = MOUSE_CAPTURE;
689 }
690 }
660 691
661 for (int i = 0; i < 3; i++) 692 for (int i = 0; i < 3; i++)
662 { 693 {
663 #ifndef _WIN32 694 #ifndef _WIN32
664 if (ports[i].device_type == IO_SEGA_PARALLEL) 695 if (ports[i].device_type == IO_SEGA_PARALLEL)
1011 port->device.mouse.tr_counter++; 1042 port->device.mouse.tr_counter++;
1012 port->device.mouse.ready_cycle = CYCLE_NEVER; 1043 port->device.mouse.ready_cycle = CYCLE_NEVER;
1013 if (port->device.mouse.tr_counter == 3) { 1044 if (port->device.mouse.tr_counter == 3) {
1014 port->device.mouse.latched_x = port->device.mouse.cur_x; 1045 port->device.mouse.latched_x = port->device.mouse.cur_x;
1015 port->device.mouse.latched_y = port->device.mouse.cur_y; 1046 port->device.mouse.latched_y = port->device.mouse.cur_y;
1047 if (mouse_mode == MOUSE_ABSOLUTE) {
1048 //avoid overflow in absolute mode
1049 int deltax = port->device.mouse.latched_x - port->device.mouse.last_read_x;
1050 if (abs(deltax) > 255) {
1051 port->device.mouse.latched_x = port->device.mouse.last_read_x + (deltax > 0 ? 255 : -255);
1052 }
1053 int deltay = port->device.mouse.latched_y - port->device.mouse.last_read_y;
1054 if (abs(deltay) > 255) {
1055 port->device.mouse.latched_y = port->device.mouse.last_read_y + (deltay > 0 ? 255 : -255);
1056 }
1057 }
1016 } 1058 }
1017 } 1059 }
1018 } 1060 }
1019 1061
1020 void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction) 1062 void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction)