Add touchscreen lightgun code

This commit is contained in:
libretroadmin 2022-05-26 17:08:52 +02:00
parent 3fa9226312
commit f628672c62
4 changed files with 149 additions and 38 deletions

166
input.cpp
View File

@ -26,6 +26,12 @@ static float mouse_sensitivity = 1.0f;
static unsigned geometry_width = 0;
static unsigned geometry_height = 0;
static int pointer_pressed = 0;
static const int POINTER_PRESSED_CYCLES = 4;
static int pointer_cycles_after_released = 0;
static int pointer_pressed_last_x = 0;
static int pointer_pressed_last_y = 0;
typedef union
{
uint8_t u8[ 32 ];
@ -947,29 +953,11 @@ void input_update( retro_input_state_t input_state_cb )
case RETRO_DEVICE_SS_GUN_US:
{
uint8_t shot_type;
int gun_x, gun_y;
int forced_reload;
forced_reload = input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD );
// off-screen?
if ( input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN ) ||
forced_reload ||
geometry_height == 0 )
{
shot_type = 0x4; // off-screen shot
gun_x = -16384; // magic position to disable cross-hair drawing.
gun_y = -16384;
}
else
{
shot_type = 0x1; // on-screen shot
if ( setting_gun_input == SETTING_GUN_INPUT_POINTER ) {
int gun_x, gun_y;
int gun_x_raw, gun_y_raw;
gun_x_raw = input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X );
gun_y_raw = input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y );
gun_x_raw = input_state_cb( iplayer, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
gun_y_raw = input_state_cb( iplayer, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
// .. scale into screen space:
// NOTE: the scaling here is empirical-guesswork.
@ -979,26 +967,128 @@ void input_update( retro_input_state_t input_state_cb )
const int scale_y = geometry_height;
const int offset_y = geometry_height - 240;
int is_offscreen = 0;
gun_x = ( ( gun_x_raw + 0x7fff ) * scale_x ) / (0x7fff << 1);
gun_y = ( ( gun_y_raw + 0x7fff ) * scale_y ) / (0x7fff << 1) + offset_y;
// Handle offscreen by checking corrected x and y values
if ( gun_x == 0 || gun_y == 0 )
{
is_offscreen = 1;
gun_x = -16384; // magic position to disable cross-hair drawing.
gun_y = -16384;
}
// Touch sensitivity: Keep the gun position held for a fixed number of cycles after touch is released
// because a very light touch can result in a misfire
if ( pointer_cycles_after_released > 0 && pointer_cycles_after_released < POINTER_PRESSED_CYCLES ) {
pointer_cycles_after_released++;
p_input->gun_pos[ 0 ] = pointer_pressed_last_x;
p_input->gun_pos[ 1 ] = pointer_pressed_last_y;
return;
}
// trigger
if ( input_state_cb( iplayer, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED ) )
{
pointer_pressed = 1;
pointer_cycles_after_released = 0;
pointer_pressed_last_x = gun_x;
pointer_pressed_last_y = gun_y;
} else if ( pointer_pressed ) {
pointer_cycles_after_released++;
pointer_pressed = 0;
p_input->gun_pos[ 0 ] = pointer_pressed_last_x;
p_input->gun_pos[ 1 ] = pointer_pressed_last_y;
p_input->u8[4] &= ~0x1;
return;
}
// position
p_input->gun_pos[ 0 ] = gun_x;
p_input->gun_pos[ 1 ] = gun_y;
// buttons
p_input->u8[ 4 ] = 0;
// use multi-touch to support different button inputs:
// 3-finger touch: START button
// 2-finger touch: Reload
// offscreen touch: Reload
int touch_count = input_state_cb( iplayer, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_COUNT );
if ( touch_count == 3 )
{
p_input->u8[ 4 ] |= 0x2;
}
else if ( touch_count == 2 )
{
p_input->u8[ 4 ] |= 0x4;
}
else if ( touch_count == 1 && is_offscreen )
{
p_input->u8[ 4 ] |= 0x4;
} else if ( touch_count == 1 )
{
p_input->u8[ 4 ] |= 0x1;
}
} else { // Lightgun input is default
uint8_t shot_type;
int gun_x, gun_y;
int forced_reload;
forced_reload = input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD );
// off-screen?
if ( input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN ) ||
forced_reload ||
geometry_height == 0 )
{
shot_type = 0x4; // off-screen shot
gun_x = -16384; // magic position to disable cross-hair drawing.
gun_y = -16384;
}
else
{
shot_type = 0x1; // on-screen shot
int gun_x_raw, gun_y_raw;
gun_x_raw = input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X );
gun_y_raw = input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y );
// .. scale into screen space:
// NOTE: the scaling here is empirical-guesswork.
// Tested at 352x240 (ntsc) and 352x256 (pal)
const int scale_x = 21472;
const int scale_y = geometry_height;
const int offset_y = geometry_height - 240;
gun_x = ( ( gun_x_raw + 0x7fff ) * scale_x ) / (0x7fff << 1);
gun_y = ( ( gun_y_raw + 0x7fff ) * scale_y ) / (0x7fff << 1) + offset_y;
}
// position
p_input->gun_pos[ 0 ] = gun_x;
p_input->gun_pos[ 1 ] = gun_y;
// buttons
p_input->u8[ 4 ] = 0;
// trigger
if ( input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER ) || forced_reload ) {
p_input->u8[ 4 ] |= shot_type;
}
// start
if ( input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_START ) ) {
p_input->u8[ 4 ] |= 0x2;
}
}
// position
p_input->gun_pos[ 0 ] = gun_x;
p_input->gun_pos[ 1 ] = gun_y;
// buttons
p_input->u8[ 4 ] = 0;
// trigger
if ( input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER ) || forced_reload ) {
p_input->u8[ 4 ] |= shot_type;
}
// start
if ( input_state_cb( iplayer, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_START ) ) {
p_input->u8[ 4 ] |= 0x2;
}
}
break;

View File

@ -465,6 +465,18 @@ static void check_variables(bool startup)
setting_gun_crosshair = SETTING_GUN_CROSSHAIR_DOT;
}
}
var.key = "beetle_saturn_virtuagun_input";
var.value = NULL;
if ( environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value )
{
if ( !strcmp(var.value, "Touchscreen") ) {
setting_gun_input = SETTING_GUN_INPUT_POINTER;
} else {
setting_gun_input = SETTING_GUN_INPUT_LIGHTGUN;
}
}
}
static bool MDFNI_LoadGame( const char *name )
@ -833,6 +845,7 @@ void retro_set_environment( retro_environment_t cb )
{ "beetle_saturn_trigger_deadzone", "Trigger Deadzone; 15%|20%|25%|30%|0%|5%|10%"},
{ "beetle_saturn_mouse_sensitivity", "Mouse Sensitivity; 100%|105%|110%|115%|120%|125%|130%|135%|140%|145%|150%|155%|160%|165%|170%|175%|180%|185%|190%|195%|200%|5%|10%|15%|20%|25%|30%|35%|40%|45%|50%|55%|60%|65%|70%|75%|80%|85%|90%|95%" },
{ "beetle_saturn_virtuagun_crosshair", "Gun Crosshair; Cross|Dot|Off" },
{ "beetle_saturn_virtuagun_input", "Gun Input Mode; Lightgun|Touchscreen" },
{ "beetle_saturn_cdimagecache", "CD Image Cache (restart); disabled|enabled" },
{ "beetle_saturn_autortc", "Automatically set RTC on game load; enabled|disabled" },
{ "beetle_saturn_autortc_lang", "BIOS language; english|german|french|spanish|italian|japanese" },

View File

@ -9,6 +9,7 @@ int setting_initial_scanline_pal = 0;
int setting_last_scanline = 239;
int setting_last_scanline_pal = 287;
int setting_gun_crosshair = SETTING_GUN_CROSSHAIR_CROSS;
int setting_gun_input = SETTING_GUN_INPUT_LIGHTGUN;
bool setting_disc_test = false;
bool setting_multitap_port1;
bool setting_multitap_port2;

View File

@ -10,6 +10,12 @@ enum
SETTING_GUN_CROSSHAIR_LAST,
};
enum
{
SETTING_GUN_INPUT_LIGHTGUN,
SETTING_GUN_INPUT_POINTER,
};
extern int setting_region;
extern int setting_cart;
extern bool setting_smpc_autortc;
@ -19,6 +25,7 @@ extern int setting_initial_scanline_pal;
extern int setting_last_scanline;
extern int setting_last_scanline_pal;
extern int setting_gun_crosshair;
extern int setting_gun_input;
extern bool setting_disc_test;
extern bool setting_multitap_port1;
extern bool setting_multitap_port2;