# HG changeset patch # User Michael Pavone # Date 1450238510 28800 # Node ID 9e882eca717ebffcb2ded0e2fd6366efda44d0d8 # Parent 28ec32e720b233f3be87c3fcd9dbef5fe8094167 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. diff -r 28ec32e720b2 -r 9e882eca717e io.c --- a/io.c Mon Dec 14 19:36:01 2015 -0800 +++ b/io.c Tue Dec 15 20:01:50 2015 -0800 @@ -68,6 +68,13 @@ UI_EXIT } ui_action; +typedef enum { + MOUSE_ABSOLUTE, //really only useful for menu ROM + MOUSE_RELATIVE, //for full screen + MOUSE_CAPTURE //for windowed mode +} mouse_modes; + + typedef struct { io_port *port; uint8_t bind_type; @@ -85,7 +92,6 @@ io_port *motion_port; keybinding buttons[MAX_MOUSE_BUTTONS]; uint8_t bind_type; - uint8_t motion_mode; } mousebinding; keybinding * bindings[0x10000]; @@ -93,6 +99,7 @@ joydpad * joydpads[MAX_JOYSTICKS]; mousebinding mice[MAX_MICE]; const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; +mouse_modes mouse_mode; void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) { @@ -406,17 +413,30 @@ handle_binding_up(binding); } -void handle_mouse_moved(int mouse, uint16_t x, uint16_t y) +void handle_mouse_moved(int mouse, uint16_t x, uint16_t y, int16_t deltax, int16_t deltay) { if (mouse >= MAX_MICE || !mice[mouse].motion_port) { return; } //TODO: relative mode - float scale_x = 640.0 / ((float)render_width()); - float scale_y = 480.0 / ((float)render_height()); - float scale = scale_x > scale_y ? scale_y : scale_x; - mice[mouse].motion_port->device.mouse.cur_x = x * scale_x; - mice[mouse].motion_port->device.mouse.cur_y = y * scale_y; + switch(mouse_mode) + { + case MOUSE_ABSOLUTE: { + float scale_x = 640.0 / ((float)render_width()); + float scale_y = 480.0 / ((float)render_height()); + float scale = scale_x > scale_y ? scale_y : scale_x; + mice[mouse].motion_port->device.mouse.cur_x = x * scale_x; + mice[mouse].motion_port->device.mouse.cur_y = y * scale_y; + break; + } + case MOUSE_RELATIVE: { + mice[mouse].motion_port->device.mouse.cur_x += deltax; + mice[mouse].motion_port->device.mouse.cur_y += deltay; + break; + } + case MOUSE_CAPTURE: { + } + } } int parse_binding_target(char * target, tern_node * padbuttons, tern_node *mousebuttons, int * ui_out, int * padnum_out, int * padbutton_out) @@ -658,6 +678,17 @@ process_device(io_2, ports+1); process_device(io_ext, ports+2); + if (rom->mouse_mode && !strcmp(rom->mouse_mode, "absolute")) { + mouse_mode = MOUSE_ABSOLUTE; + } else { + if (render_fullscreen()) { + mouse_mode = MOUSE_RELATIVE; + render_relative_mouse(1); + } else { + mouse_mode = MOUSE_CAPTURE; + } + } + for (int i = 0; i < 3; i++) { #ifndef _WIN32 @@ -1013,6 +1044,17 @@ if (port->device.mouse.tr_counter == 3) { port->device.mouse.latched_x = port->device.mouse.cur_x; port->device.mouse.latched_y = port->device.mouse.cur_y; + if (mouse_mode == MOUSE_ABSOLUTE) { + //avoid overflow in absolute mode + int deltax = port->device.mouse.latched_x - port->device.mouse.last_read_x; + if (abs(deltax) > 255) { + port->device.mouse.latched_x = port->device.mouse.last_read_x + (deltax > 0 ? 255 : -255); + } + int deltay = port->device.mouse.latched_y - port->device.mouse.last_read_y; + if (abs(deltay) > 255) { + port->device.mouse.latched_y = port->device.mouse.last_read_y + (deltay > 0 ? 255 : -255); + } + } } } } diff -r 28ec32e720b2 -r 9e882eca717e io.h --- a/io.h Mon Dec 14 19:36:01 2015 -0800 +++ b/io.h Tue Dec 15 20:01:50 2015 -0800 @@ -79,7 +79,7 @@ void handle_joydown(int joystick, int button); void handle_joyup(int joystick, int button); void handle_joy_dpad(int joystick, int dpad, uint8_t state); -void handle_mouse_moved(int mouse, uint16_t x, uint16_t y); +void handle_mouse_moved(int mouse, uint16_t x, uint16_t y, int16_t deltax, int16_t deltay); void handle_mousedown(int mouse, int button); void handle_mouseup(int mouse, int button); diff -r 28ec32e720b2 -r 9e882eca717e render.h --- a/render.h Mon Dec 14 19:36:01 2015 -0800 +++ b/render.h Tue Dec 15 20:01:50 2015 -0800 @@ -23,6 +23,7 @@ #define RENDER_DPAD_DOWN SDL_HAT_DOWN #define RENDER_DPAD_LEFT SDL_HAT_LEFT #define RENDER_DPAD_RIGHT SDL_HAT_RIGHT +#define render_relative_mouse SDL_SetRelativeMouseMode #define MAX_JOYSTICKS 8 #define MAX_MICE 8 @@ -59,6 +60,7 @@ int render_num_joysticks(); int render_width(); int render_height(); +int render_fullscreen(); void process_events(); void render_errorbox(char *title, char *message); void render_warnbox(char *title, char *message); diff -r 28ec32e720b2 -r 9e882eca717e render_sdl.c --- a/render_sdl.c Mon Dec 14 19:36:01 2015 -0800 +++ b/render_sdl.c Tue Dec 15 20:01:50 2015 -0800 @@ -22,7 +22,7 @@ SDL_Rect main_clip; SDL_GLContext *main_context; -int main_width, main_height; +int main_width, main_height, is_fullscreen; uint8_t render_dbg = 0; uint8_t debug_pal = 0; @@ -108,6 +108,11 @@ return main_height; } +int render_fullscreen() +{ + return is_fullscreen; +} + uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b) { return 255 << 24 | r << 16 | g << 8 | b; @@ -265,6 +270,7 @@ } main_width = width; main_height = height; + is_fullscreen = fullscreen; render_gl = 0; @@ -559,7 +565,7 @@ handle_joy_dpad(event->jbutton.which, event->jhat.hat, event->jhat.value); break; case SDL_MOUSEMOTION: - handle_mouse_moved(event->motion.which, event->motion.x, event->motion.y); + handle_mouse_moved(event->motion.which, event->motion.x, event->motion.y, event->motion.xrel, event->motion.yrel); break; case SDL_MOUSEBUTTONDOWN: handle_mousedown(event->button.which, event->button.button); diff -r 28ec32e720b2 -r 9e882eca717e rom.db --- a/rom.db Mon Dec 14 19:36:01 2015 -0800 +++ b/rom.db Tue Dec 15 20:01:50 2015 -0800 @@ -375,4 +375,5 @@ 2 mouse.1 ext none } + mouse_mode absolute } diff -r 28ec32e720b2 -r 9e882eca717e romdb.c --- a/romdb.c Mon Dec 14 19:36:01 2015 -0800 +++ b/romdb.c Tue Dec 15 20:01:50 2015 -0800 @@ -551,7 +551,7 @@ info.name = get_header_name(rom); info.regions = get_header_regions(rom); add_memmap_header(&info, rom, rom_size, base_map, base_chunks); - info.port1_override = info.port2_override = info.ext_override = NULL; + info.port1_override = info.port2_override = info.ext_override = info.mouse_mode = NULL; return info; } @@ -851,6 +851,7 @@ } else { info.port1_override = info.port2_override = info.ext_override = NULL; } + info.mouse_mode = tern_find_ptr(entry, "mouse_mode"); return info; } diff -r 28ec32e720b2 -r 9e882eca717e romdb.h --- a/romdb.h Mon Dec 14 19:36:01 2015 -0800 +++ b/romdb.h Tue Dec 15 20:01:50 2015 -0800 @@ -43,6 +43,7 @@ char *port1_override; char *port2_override; char *ext_override; + char *mouse_mode; uint32_t num_eeprom; uint32_t map_chunks; uint32_t save_size;