diff options
author | Michael Pavone <pavone@retrodev.com> | 2015-12-15 20:01:50 -0800 |
---|---|---|
committer | Michael Pavone <pavone@retrodev.com> | 2015-12-15 20:01:50 -0800 |
commit | 1d3342fd0952c57a737cf90794f20905bd48d5f1 (patch) | |
tree | b0dcc2a9f41f538ddd3581a3d32158a9d7bc0748 | |
parent | 9596af4ac4d0c8dcde83334889f60d6687940b12 (diff) |
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.
-rw-r--r-- | io.c | 56 | ||||
-rw-r--r-- | io.h | 2 | ||||
-rw-r--r-- | render.h | 2 | ||||
-rwxr-xr-x | render_sdl.c | 10 | ||||
-rw-r--r-- | rom.db | 1 | ||||
-rw-r--r-- | romdb.c | 3 | ||||
-rw-r--r-- | romdb.h | 1 |
7 files changed, 64 insertions, 11 deletions
@@ -68,6 +68,13 @@ typedef enum { 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 @@ typedef struct { 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 @@ keybinding * joybindings[MAX_JOYSTICKS]; 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 @@ void handle_mouseup(int mouse, int button) 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 @@ void setup_io_devices(tern_node * config, rom_info *rom, io_port * ports) 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 @@ void mouse_check_ready(io_port *port, uint32_t current_cycle) 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); + } + } } } } @@ -79,7 +79,7 @@ void handle_keyup(int keycode); 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); @@ -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_joystick_num_hats(int joystick); 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 --git a/render_sdl.c b/render_sdl.c index dbd7389..b60fc62 100755 --- a/render_sdl.c +++ b/render_sdl.c @@ -22,7 +22,7 @@ SDL_Texture *main_texture; 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 @@ int render_height() 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 @@ void render_init(int width, int height, char * title, uint32_t fps, uint8_t full } main_width = width; main_height = height; + is_fullscreen = fullscreen; render_gl = 0; @@ -559,7 +565,7 @@ int32_t handle_event(SDL_Event *event) 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); @@ -375,4 +375,5 @@ BlstMenu { 2 mouse.1 ext none } + mouse_mode absolute } @@ -551,7 +551,7 @@ rom_info configure_rom_heuristics(uint8_t *rom, uint32_t rom_size, memmap_chunk 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 @@ rom_info configure_rom(tern_node *rom_db, void *vrom, uint32_t rom_size, memmap_ } else { info.port1_override = info.port2_override = info.ext_override = NULL; } + info.mouse_mode = tern_find_ptr(entry, "mouse_mode"); return info; } @@ -43,6 +43,7 @@ typedef struct { char *port1_override; char *port2_override; char *ext_override; + char *mouse_mode; uint32_t num_eeprom; uint32_t map_chunks; uint32_t save_size; |