diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index d22054b..55989d6 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -160,6 +160,9 @@ typedef struct { static NES_INPUT_T nes_input = { 0 }; enum RetroZapperInputModes{RetroCLightgun, RetroSTLightgun, RetroMouse, RetroPointer}; enum RetroZapperInputModes zappermode = RetroCLightgun; +enum RetroArkanoidInputModes{RetroArkanoidMouse, RetroArkanoidPointer, RetroArkanoidAbsMouse, RetroArkanoidStelladaptor}; +enum RetroArkanoidInputModes arkanoidmode = RetroArkanoidMouse; +static int mouseSensitivity = 100; extern int switchZapper; static bool libretro_supports_bitmasks = false; @@ -1991,6 +1994,24 @@ static void check_variables(bool startup) } } + var.key = "fceumm_arkanoid_mode"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (!strcmp(var.value, "touchscreen")) { + arkanoidmode = RetroArkanoidPointer; + } + else if (!strcmp(var.value, "abs_mouse")) { + arkanoidmode = RetroArkanoidAbsMouse; + } + else if (!strcmp(var.value, "stelladaptor")) { + arkanoidmode = RetroArkanoidStelladaptor; + } + else { + arkanoidmode = RetroArkanoidMouse; /*default setting*/ + } + } + var.key = "fceumm_zapper_tolerance"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) @@ -1998,6 +2019,13 @@ static void check_variables(bool startup) FCEU_ZapperSetTolerance(atoi(var.value)); } + var.key = "fceumm_mouse_sensitivity"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + mouseSensitivity = atoi(var.value); + } + var.key = "fceumm_show_crosshair"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) @@ -2268,15 +2296,19 @@ void add_powerpad_input(unsigned port, uint32 variant, uint32_t *ppdata) static int mzx = 0, mzy = 0; -void get_mouse_input(unsigned port, uint32_t *zapdata) +void get_mouse_input(unsigned port, uint32 variant, uint32_t *mousedata) { int min_width, min_height, max_width, max_height; max_width = 256; max_height = 240; - zapdata[2] = 0; /* reset click state */ + mousedata[2] = 0; /* reset click state */ + + if (variant == RETRO_DEVICE_FC_ARKANOID) + variant = RETRO_DEVICE_ARKANOID; - if (zappermode == RetroMouse) /* mouse device */ + if ((variant != RETRO_DEVICE_ARKANOID && zappermode == RetroMouse) || + (variant == RETRO_DEVICE_ARKANOID && arkanoidmode == RetroArkanoidMouse)) /* mouse device */ { int mouse_Lbutton; int mouse_Rbutton; @@ -2286,29 +2318,37 @@ void get_mouse_input(unsigned port, uint32_t *zapdata) max_width -= crop_overscan_h_right; max_height -= crop_overscan_v_bottom; - /* TODO: Add some sort of mouse sensitivity */ - mzx += input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X); - mzy += input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y); + mzx += mouseSensitivity * input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X) / 100; + mzy += mouseSensitivity * input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y) / 100; + switch(variant) { + case RETRO_DEVICE_ARKANOID: + if (mzx < 0) mzx = 0; + else if (mzx > 240) mzx = 240; + if (mzy < min_height) mzy = min_height; + else if (mzy > max_height) mzy = max_height; + mousedata[1] = mzy; + break; + + case RETRO_DEVICE_ZAPPER: + default: /* Set crosshair within the limits of current screen resolution */ if (mzx < min_width) mzx = min_width; else if (mzx > max_width) mzx = max_width; + break; + } - if (mzy < min_height) mzy = min_height; - else if (mzy > max_height) mzy = max_height; - - zapdata[0] = mzx; - zapdata[1] = mzy; + mousedata[0] = mzx; mouse_Lbutton = input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT); mouse_Rbutton = input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT); if (mouse_Lbutton) - zapdata[2] |= 0x1; + mousedata[2] |= 0x1; if (mouse_Rbutton) - zapdata[2] |= 0x2; + mousedata[2] |= 0x2; } - else if (zappermode == RetroPointer) { + else if (variant != RETRO_DEVICE_ARKANOID && zappermode == RetroPointer) { int offset_x = (crop_overscan_h_left * 0x120) - 1; int offset_y = (crop_overscan_v_top * 0x133) + 1; @@ -2317,17 +2357,64 @@ void get_mouse_input(unsigned port, uint32_t *zapdata) if (_x == 0 && _y == 0) { - zapdata[0] = 0; - zapdata[1] = 0; + mousedata[0] = 0; } else { - zapdata[0] = (_x + (0x7FFF + offset_x)) * max_width / ((0x7FFF + offset_x) * 2); - zapdata[1] = (_y + (0x7FFF + offset_y)) * max_height / ((0x7FFF + offset_y) * 2); + mousedata[0] = (_x + (0x7FFF + offset_x)) * max_width / ((0x7FFF + offset_x) * 2); + mousedata[1] = (_y + (0x7FFF + offset_y)) * max_height / ((0x7FFF + offset_y) * 2); } if (input_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED)) - zapdata[2] |= 0x1; + mousedata[2] |= 0x1; + } + else if (variant == RETRO_DEVICE_ARKANOID && (arkanoidmode == RetroArkanoidAbsMouse || arkanoidmode == RetroArkanoidPointer)) { + int offset_x = (crop_overscan_h_left * 0x120) - 1; + + int _x = input_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X); + int _y = input_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y); + + if (_x != 0 || _y != 0) + { + int32 raw = (_x + (0x7FFF + offset_x)) * max_width / ((0x7FFF + offset_x) * 2); + if (arkanoidmode == RetroArkanoidAbsMouse) { + // remap so full screen movement ends up within the encoder range 0-240 + // game board: 176 wide + // paddle: 32 + // range of movement: 176-32 = 144 + // left edge: 16 + // right edge: 64 + + // increase movement by 10 to allow edges to be reached in case of problems + raw = (raw - 128) * 140 / 128 + 128; + if (raw < 0) + raw = 0; + else if (raw > 255) + raw = 255; + + mousedata[0] = raw * 240 / 255; + } + else { + // remap so full board movement ends up within the encoder range 0-240 + if (mousedata[0] < 16+(32/2)) + mousedata[0] = 0; + else + mousedata[0] -= 16+(32/2); + if (mousedata[0] > 144) + mousedata[0] = 144; + mousedata[0] = raw * 240 / 144; + } + } + + + if (input_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED)) + mousedata[2] |= 0x1; + } + else if (variant == RETRO_DEVICE_ARKANOID && arkanoidmode == RetroArkanoidStelladaptor) { + int x = input_cb(port, RETRO_DEVICE_ANALOG, 0, RETRO_DEVICE_ID_ANALOG_X); + mousedata[0] = (x+32768)*240/65535; + if (input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A) || input_cb(port, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B)) + mousedata[2] |= 0x1; } else if (zappermode == RetroCLightgun) /* Crosshair lightgun device */ { @@ -2343,25 +2430,25 @@ void get_mouse_input(unsigned port, uint32_t *zapdata) if ( offscreen || offscreen_shot ) { - zapdata[0] = 0; - zapdata[1] = 0; + mousedata[0] = 0; + mousedata[1] = 0; } else { int _x = input_cb( port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X ); int _y = input_cb( port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y ); - zapdata[0] = (_x + (0x7FFF + offset_x)) * max_width / ((0x7FFF + offset_x) * 2); - zapdata[1] = (_y + (0x7FFF + offset_y)) * max_height / ((0x7FFF + offset_y) * 2); + mousedata[0] = (_x + (0x7FFF + offset_x)) * max_width / ((0x7FFF + offset_x) * 2); + mousedata[1] = (_y + (0x7FFF + offset_y)) * max_height / ((0x7FFF + offset_y) * 2); } if ( trigger || offscreen_shot ) - zapdata[2] |= 0x1; + mousedata[2] |= 0x1; } else /* Sequential targets lightgun device integration */ { - zapdata[2] = input_cb( port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER ); - zapdata[3] = input_cb( port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_A ); + mousedata[2] = input_cb( port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER ); + mousedata[3] = input_cb( port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_A ); } } @@ -2508,8 +2595,9 @@ static void FCEUD_UpdateInput(void) switch (nes_input.type[port]) { case RETRO_DEVICE_ARKANOID: + case RETRO_DEVICE_FC_ARKANOID: case RETRO_DEVICE_ZAPPER: - get_mouse_input(port, nes_input.MouseData[port]); + get_mouse_input(port, nes_input.type[port], nes_input.MouseData[port]); break; } } @@ -2532,7 +2620,7 @@ static void FCEUD_UpdateInput(void) case RETRO_DEVICE_FC_ARKANOID: case RETRO_DEVICE_FC_OEKAKIDS: case RETRO_DEVICE_FC_SHADOW: - get_mouse_input(0, nes_input.FamicomData); + get_mouse_input(0, nes_input.type[4], nes_input.FamicomData); break; case RETRO_DEVICE_FC_HYPERSHOT: { diff --git a/src/drivers/libretro/libretro_core_options.h b/src/drivers/libretro/libretro_core_options.h index 35709ad..d964ebe 100644 --- a/src/drivers/libretro/libretro_core_options.h +++ b/src/drivers/libretro/libretro_core_options.h @@ -55,7 +55,7 @@ struct retro_core_option_v2_category option_cats_us[] = { { "input", "Input", - "Change turbo and light gun settings." + "Change turbo, Arkanoid and light gun settings." }, { "hacks", @@ -591,6 +591,53 @@ struct retro_core_option_v2_definition option_defs[] = { }, "enabled", }, + { + "fceumm_arkanoid_mode", + "Arkanoid Mode", + NULL, + "Selects device to use for Arkanoid games.", + NULL, + "input", + { + { "abs_mouse", "Absolute mouse" }, + { "mouse", "Mouse" }, + { "stelladaptor", "Stelladaptor" }, + { "touchscreen", "Touchscreen" }, + { NULL, NULL }, + }, + "mouse", + }, + { + "fceumm_mouse_sensitivity", + "Mouse Sensitivity", + NULL, + "Mouse sensitivity in percent.", + NULL, + "input", + { + { "20", NULL }, + { "30", NULL }, + { "40", NULL }, + { "50", NULL }, + { "60", NULL }, + { "70", NULL }, + { "80", NULL }, + { "90", NULL }, + { "100", NULL }, + { "110", NULL }, + { "120", NULL }, + { "130", NULL }, + { "140", NULL }, + { "150", NULL }, + { "160", NULL }, + { "170", NULL }, + { "180", NULL }, + { "190", NULL }, + { "200", NULL }, + { NULL, NULL }, + }, + "100", + }, { "fceumm_up_down_allowed", "Allow Opposing Directions",