diff --git a/custom/mupen64plus-core/plugin/emulate_game_controller_via_libretro.c b/custom/mupen64plus-core/plugin/emulate_game_controller_via_libretro.c index 8a132d4a6..3e8f07bd5 100644 --- a/custom/mupen64plus-core/plugin/emulate_game_controller_via_libretro.c +++ b/custom/mupen64plus-core/plugin/emulate_game_controller_via_libretro.c @@ -47,6 +47,14 @@ extern int l_cbutton; extern int d_cbutton; extern int u_cbutton; extern bool alternate_mapping; +extern bool mouse_mode; +extern int mouse_sensitivity_x; +extern int mouse_sensitivity_y; +extern int mouse_left_btn; +extern int mouse_right_btn; +extern int mouse_middle_btn; +extern int mouse_wheel_up_btn; +extern int mouse_wheel_down_btn; static bool libretro_supports_bitmasks = false; extern m64p_rom_header ROM_HEADER; @@ -278,6 +286,24 @@ EXPORT void CALL inputControllerCommand(int Control, unsigned char *Command) #define CSTICK_DOWN 0x400 +static void apply_mouse_button(BUTTONS* Keys, int btn_mapping) +{ + switch (btn_mapping) + { + case 1: Keys->Z_TRIG = 1; break; + case 2: Keys->A_BUTTON = 1; break; + case 3: Keys->B_BUTTON = 1; break; + case 4: Keys->L_TRIG = 1; break; + case 5: Keys->R_TRIG = 1; break; + case 6: Keys->START_BUTTON = 1; break; + case 7: Keys->U_CBUTTON = 1; break; + case 8: Keys->D_CBUTTON = 1; break; + case 9: Keys->L_CBUTTON = 1; break; + case 10: Keys->R_CBUTTON = 1; break; + default: break; + } +} + static void inputGetKeys_reuse(int16_t analogX, int16_t analogY, int Control, BUTTONS* Keys) { double radius, angle; @@ -306,6 +332,26 @@ static void inputGetKeys_reuse(int16_t analogX, int16_t analogY, int Control, BU Keys->X_AXIS = 0; Keys->Y_AXIS = 0; } + + if (mouse_mode && Control == 0 && Keys->X_AXIS == 0 && Keys->Y_AXIS == 0) // Only player 1 + { + int32_t stickX = (int32_t)(input_cb(Control, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X) * mouse_sensitivity_x / 50.0f); + int32_t stickY = (int32_t)(input_cb(Control, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y) * mouse_sensitivity_y / 50.0f); + + Keys->X_AXIS = (stickX > 80.0f) ? 80 : (stickX < -80.0f) ? -80 : (int32_t)stickX; + Keys->Y_AXIS = (stickY > 80.0f) ? 80 : (stickY < -80.0f) ? -80 : (int32_t)stickY; + + if (input_cb(Control, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT)) + apply_mouse_button(Keys, mouse_left_btn); + if (input_cb(Control, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT)) + apply_mouse_button(Keys, mouse_right_btn); + if (input_cb(Control, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE)) + apply_mouse_button(Keys, mouse_middle_btn); + if (input_cb(Control, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELUP)) + apply_mouse_button(Keys, mouse_wheel_up_btn); + if (input_cb(Control, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN)) + apply_mouse_button(Keys, mouse_wheel_down_btn); + } } void inputGetKeys_default( int Control, BUTTONS *Keys ) diff --git a/libretro/libretro.c b/libretro/libretro.c index c4f570f3b..2f2b11f83 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -124,6 +124,14 @@ int l_cbutton; int d_cbutton; int u_cbutton; bool alternate_mapping; +bool mouse_mode; +int mouse_sensitivity_x; +int mouse_sensitivity_y; +int mouse_left_btn; +int mouse_right_btn; +int mouse_middle_btn; +int mouse_wheel_up_btn; +int mouse_wheel_down_btn; static uint8_t* game_data = NULL; static uint32_t game_size = 0; @@ -843,6 +851,60 @@ void update_controllers() if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) astick_sensitivity = atoi(var.value); + var.key = CORE_NAME "-mouse-mode"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + mouse_mode = !strcmp(var.value, "True"); + + var.key = CORE_NAME "-mouse-sensitivity-x"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + int val = atoi(var.value); + mouse_sensitivity_x = (val < -500) ? -500 : (val > 500) ? 500 : val; + } + + var.key = CORE_NAME "-mouse-sensitivity-y"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + int val = atoi(var.value); + mouse_sensitivity_y = (val < -500) ? -500 : (val > 500) ? 500 : val; + } + + #define PARSE_MOUSE_BTN(val) \ + (!strcmp(val, "None") ? 0 : !strcmp(val, "Z") ? 1 : !strcmp(val, "A") ? 2 : \ + !strcmp(val, "B") ? 3 : !strcmp(val, "L") ? 4 : !strcmp(val, "R") ? 5 : \ + !strcmp(val, "Start") ? 6 : !strcmp(val, "C-Up") ? 7 : !strcmp(val, "C-Down") ? 8 : \ + !strcmp(val, "C-Left") ? 9 : !strcmp(val, "C-Right") ? 10 : 0) + + var.key = CORE_NAME "-mouse-left"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + mouse_left_btn = PARSE_MOUSE_BTN(var.value); + + var.key = CORE_NAME "-mouse-right"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + mouse_right_btn = PARSE_MOUSE_BTN(var.value); + + var.key = CORE_NAME "-mouse-middle"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + mouse_middle_btn = PARSE_MOUSE_BTN(var.value); + + var.key = CORE_NAME "-mouse-wheel-up"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + mouse_wheel_up_btn = PARSE_MOUSE_BTN(var.value); + + var.key = CORE_NAME "-mouse-wheel-down"; + var.value = NULL; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + mouse_wheel_down_btn = PARSE_MOUSE_BTN(var.value); + + #undef PARSE_MOUSE_BTN + var.key = CORE_NAME "-r-cbutton"; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) diff --git a/libretro/libretro_core_options.h b/libretro/libretro_core_options.h index fb39aa98e..061a35fc6 100644 --- a/libretro/libretro_core_options.h +++ b/libretro/libretro_core_options.h @@ -1582,6 +1582,154 @@ struct retro_core_option_v2_definition option_defs_us[] = { }, "100" }, + { + CORE_NAME "-mouse-mode", + "Mouse to Analog Stick", + NULL, + "Use mouse input to control the N64 analog stick. Useful for FPS games.", + NULL, + "input", + { + {"False", "Disabled"}, + {"True", "Enabled"}, + { NULL, NULL }, + }, + "False" + }, + { + CORE_NAME "-mouse-sensitivity-x", + "Mouse Sensitivity X (percent)", + NULL, + "Horizontal mouse sensitivity. Negative values invert axis. Set to 0 to disable.", + NULL, + "input", + { + {"-500", NULL}, {"-400", NULL}, {"-300", NULL}, {"-250", NULL}, {"-200", NULL}, + {"-175", NULL}, {"-150", NULL}, {"-125", NULL}, {"-100", NULL}, {"-75", NULL}, {"-50", NULL}, + {"0", NULL}, + {"50", NULL}, {"75", NULL}, {"100", NULL}, {"125", NULL}, {"150", NULL}, + {"175", NULL}, {"200", NULL}, {"250", NULL}, {"300", NULL}, {"400", NULL}, {"500", NULL}, + { NULL, NULL }, + }, + "100" + }, + { + CORE_NAME "-mouse-sensitivity-y", + "Mouse Sensitivity Y (percent)", + NULL, + "Vertical mouse sensitivity. Negative values invert axis. Set to 0 for Doom-like horizontal-only control.", + NULL, + "input", + { + {"-500", NULL}, {"-400", NULL}, {"-300", NULL}, {"-250", NULL}, {"-200", NULL}, + {"-175", NULL}, {"-150", NULL}, {"-125", NULL}, {"-100", NULL}, {"-75", NULL}, {"-50", NULL}, + {"0", NULL}, + {"50", NULL}, {"75", NULL}, {"100", NULL}, {"125", NULL}, {"150", NULL}, + {"175", NULL}, {"200", NULL}, {"250", NULL}, {"300", NULL}, {"400", NULL}, {"500", NULL}, + { NULL, NULL }, + }, + "-100" + }, + { + CORE_NAME "-mouse-left", + "Mouse Left Click", + NULL, + "Map mouse left click to N64 button.", + NULL, + "input", + { + {"Z", "Z Trigger"}, + {"A", "A Button"}, + {"B", "B Button"}, + {"L", "L Trigger"}, + {"R", "R Trigger"}, + {"Start", "Start"}, + {"C-Up", NULL}, {"C-Down", NULL}, {"C-Left", NULL}, {"C-Right", NULL}, + {"None", "Disabled"}, + { NULL, NULL }, + }, + "Z" + }, + { + CORE_NAME "-mouse-right", + "Mouse Right Click", + NULL, + "Map mouse right click to N64 button.", + NULL, + "input", + { + {"A", "A Button"}, + {"B", "B Button"}, + {"Z", "Z Trigger"}, + {"L", "L Trigger"}, + {"R", "R Trigger"}, + {"Start", "Start"}, + {"C-Up", NULL}, {"C-Down", NULL}, {"C-Left", NULL}, {"C-Right", NULL}, + {"None", "Disabled"}, + { NULL, NULL }, + }, + "A" + }, + { + CORE_NAME "-mouse-middle", + "Mouse Middle Click", + NULL, + "Map mouse middle click to N64 button.", + NULL, + "input", + { + {"None", "Disabled"}, + {"A", "A Button"}, + {"B", "B Button"}, + {"Z", "Z Trigger"}, + {"L", "L Trigger"}, + {"R", "R Trigger"}, + {"Start", "Start"}, + {"C-Up", NULL}, {"C-Down", NULL}, {"C-Left", NULL}, {"C-Right", NULL}, + { NULL, NULL }, + }, + "None" + }, + { + CORE_NAME "-mouse-wheel-up", + "Mouse Wheel Up", + NULL, + "Map mouse wheel up to N64 button.", + NULL, + "input", + { + {"L", "L Trigger"}, + {"R", "R Trigger"}, + {"A", "A Button"}, + {"B", "B Button"}, + {"Z", "Z Trigger"}, + {"Start", "Start"}, + {"C-Up", NULL}, {"C-Down", NULL}, {"C-Left", NULL}, {"C-Right", NULL}, + {"None", "Disabled"}, + { NULL, NULL }, + }, + "L" + }, + { + CORE_NAME "-mouse-wheel-down", + "Mouse Wheel Down", + NULL, + "Map mouse wheel down to N64 button.", + NULL, + "input", + { + {"R", "R Trigger"}, + {"L", "L Trigger"}, + {"A", "A Button"}, + {"B", "B Button"}, + {"Z", "Z Trigger"}, + {"Start", "Start"}, + {"C-Up", NULL}, {"C-Down", NULL}, {"C-Left", NULL}, {"C-Right", NULL}, + {"None", "Disabled"}, + { NULL, NULL }, + }, + "R" + }, { CORE_NAME "-r-cbutton", "Right C Button",