summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2015-12-15 20:01:50 -0800
committerMichael Pavone <pavone@retrodev.com>2015-12-15 20:01:50 -0800
commit1d3342fd0952c57a737cf90794f20905bd48d5f1 (patch)
treeb0dcc2a9f41f538ddd3581a3d32158a9d7bc0748
parent9596af4ac4d0c8dcde83334889f60d6687940b12 (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.c56
-rw-r--r--io.h2
-rw-r--r--render.h2
-rwxr-xr-xrender_sdl.c10
-rw-r--r--rom.db1
-rw-r--r--romdb.c3
-rw-r--r--romdb.h1
7 files changed, 64 insertions, 11 deletions
diff --git a/io.c b/io.c
index 260ccb5..eee9e97 100644
--- a/io.c
+++ b/io.c
@@ -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);
+ }
+ }
}
}
}
diff --git a/io.h b/io.h
index 9ec1b4f..c61949f 100644
--- a/io.h
+++ b/io.h
@@ -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);
diff --git a/render.h b/render.h
index 02e8730..92bdbd3 100644
--- a/render.h
+++ b/render.h
@@ -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);
diff --git a/rom.db b/rom.db
index bfc41ec..4b45099 100644
--- a/rom.db
+++ b/rom.db
@@ -375,4 +375,5 @@ BlstMenu {
2 mouse.1
ext none
}
+ mouse_mode absolute
}
diff --git a/romdb.c b/romdb.c
index fe70eda..6dbf428 100644
--- a/romdb.c
+++ b/romdb.c
@@ -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;
}
diff --git a/romdb.h b/romdb.h
index e7e484d..724335e 100644
--- a/romdb.h
+++ b/romdb.h
@@ -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;