Browse Source

engine: client: touch: generalise touch emulation code

* fix doubleclicks and wheels in VGUI
pull/2/head
Alibek Omarov 2 years ago
parent
commit
2d2523df4a
  1. 98
      engine/client/in_touch.c
  2. 64
      engine/client/input.c
  3. 5
      engine/client/input.h
  4. 1
      engine/client/keys.c
  5. 73
      engine/client/vgui/vgui_draw.c
  6. 2
      engine/client/vgui/vgui_draw.h
  7. 21
      engine/platform/linux/in_evdev.c
  8. 37
      engine/platform/sdl/events.c
  9. 7
      engine/platform/sdl/in_sdl.c

98
engine/client/in_touch.c

@ -151,7 +151,6 @@ convar_t *touch_exp_mult; @@ -151,7 +151,6 @@ convar_t *touch_exp_mult;
convar_t *touch_grid_enable;
convar_t *touch_grid_count;
convar_t *touch_config_file;
convar_t *touch_enable;
convar_t *touch_in_menu;
convar_t *touch_joy_radius;
convar_t *touch_dpad_radius;
@ -162,7 +161,9 @@ convar_t *touch_highlight_b; @@ -162,7 +161,9 @@ convar_t *touch_highlight_b;
convar_t *touch_highlight_a;
convar_t *touch_precise_amount;
convar_t *touch_joy_texture;
convar_t *touch_emulate;
CVAR_DEFINE_AUTO( touch_enable, DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
// code looks smaller with it
#define B(x) (button->x)
@ -1080,8 +1081,8 @@ void Touch_Init( void ) @@ -1080,8 +1081,8 @@ void Touch_Init( void )
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator");
// input devices cvar
touch_enable = Cvar_Get( "touch_enable", DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
touch_emulate = Cvar_Get( "touch_emulate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
Cvar_RegisterVariable( &touch_enable );
Cvar_RegisterVariable( &touch_emulate );
/// TODO: touch sdl platform
// SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
@ -1343,7 +1344,7 @@ void Touch_Draw( void ) @@ -1343,7 +1344,7 @@ void Touch_Draw( void )
{
touch_button_t *button;
if( !touch.initialized || (!CVAR_TO_BOOL(touch_enable) && !touch.clientonly) )
if( !touch.initialized || ( !touch_enable.value && !touch.clientonly ))
return;
Touch_InitConfig();
@ -1937,9 +1938,8 @@ static int Touch_ControlsEvent( touchEventType type, int fingerID, float x, floa @@ -1937,9 +1938,8 @@ static int Touch_ControlsEvent( touchEventType type, int fingerID, float x, floa
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy )
{
// simulate menu mouse click
if( cls.key_dest != key_game && !CVAR_TO_BOOL(touch_in_menu) )
if( cls.key_dest != key_game && !CVAR_TO_BOOL( touch_in_menu ))
{
touch.move_finger = touch.resize_finger = touch.look_finger = -1;
// Hack for keyboard, hope it help
@ -1982,25 +1982,20 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx @@ -1982,25 +1982,20 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx
{
VGui_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) );
if( type != event_motion )
VGui_KeyEvent( K_MOUSE1, type == event_down ? 1 : 0 );
// allow scoreboard scroll
if( host.mouse_visible && type == event_motion )
return 0;
switch( type )
{
case event_down:
VGui_MouseEvent( K_MOUSE1, 1 );
break;
case event_up:
VGui_MouseEvent( K_MOUSE1, 0 );
break;
default: break;
}
}
if( !touch.initialized || (!CVAR_TO_BOOL(touch_enable) && !touch.clientonly) )
{
#if 0
if( type == event_down )
Key_Event( K_MOUSE1, true );
if( type == event_up )
Key_Event( K_MOUSE1, false );
Android_AddMove( dx * (float)refState.width, dy * (float)refState.height );
#endif
if( !touch.initialized || ( !touch_enable.value && !touch.clientonly ))
return 0;
}
if( clgame.dllFuncs.pfnTouchEvent && clgame.dllFuncs.pfnTouchEvent( type, fingerID, x, y, dx, dy ) )
return true;
@ -2019,35 +2014,60 @@ void Touch_GetMove( float *forward, float *side, float *yaw, float *pitch ) @@ -2019,35 +2014,60 @@ void Touch_GetMove( float *forward, float *side, float *yaw, float *pitch )
void Touch_KeyEvent( int key, int down )
{
int xi, yi;
float x, y;
static float lx, ly;
static int kidNamedFinger = -1;
touchEventType event;
float x, y;
int finger, xi, yi;
if( !CVAR_TO_BOOL(touch_emulate) )
if( !touch_emulate.value )
{
if( CVAR_TO_BOOL(touch_enable) )
if( touch_enable.value )
return;
if( !touch.clientonly )
return;
}
Platform_GetMousePos( &xi, &yi );
x = xi/SCR_W;
y = yi/SCR_H;
if( !key )
{
if( kidNamedFinger < 0 )
return;
if( cls.key_dest == key_menu && down < 2 && key == K_MOUSE1 )
finger = kidNamedFinger;
event = event_motion;
}
else
{
UI_MouseMove( xi, yi );
UI_KeyEvent( key, down );
finger = key == K_MOUSE1 ? 0 : 1;
if( down )
{
event = event_down;
kidNamedFinger = finger;
}
else
{
event = event_up;
kidNamedFinger = -1;
}
}
if( down == 1 )
Touch_ControlsEvent( event_down, key == K_MOUSE1?0:1, x, y, 0, 0 );
else
Touch_ControlsEvent( down? event_motion: event_up, key == K_MOUSE1?0:1, x, y, x-lx, y-ly );
lx = x, ly = y;
// don't deactivate mouse in game
// checking a case when mouse and touchscreen
// can be used simultaneously
Platform_SetCursorType( dc_arrow );
Platform_GetMousePos( &xi, &yi );
x = xi / SCR_W;
y = yi / SCR_H;
Con_DPrintf( "event %d %.2f %.2f %.2f %.2f\n",
event, x, y, x - lx, y - ly );
IN_TouchEvent( event, finger, x, y, x - lx, y - ly );
lx = x;
ly = y;
}
void Touch_Shutdown( void )

64
engine/client/input.c

@ -63,7 +63,7 @@ uint IN_CollectInputDevices( void ) @@ -63,7 +63,7 @@ uint IN_CollectInputDevices( void )
if( !m_ignore->value ) // no way to check is mouse connected, so use cvar only
ret |= INPUT_DEVICE_MOUSE;
if( CVAR_TO_BOOL(touch_enable) )
if( touch_enable.value )
ret |= INPUT_DEVICE_TOUCH;
if( Joy_IsActive() ) // connected or enabled
@ -94,13 +94,13 @@ void IN_LockInputDevices( qboolean lock ) @@ -94,13 +94,13 @@ void IN_LockInputDevices( qboolean lock )
{
SetBits( m_ignore->flags, FCVAR_READ_ONLY );
SetBits( joy_enable->flags, FCVAR_READ_ONLY );
SetBits( touch_enable->flags, FCVAR_READ_ONLY );
SetBits( touch_enable.flags, FCVAR_READ_ONLY );
}
else
{
ClearBits( m_ignore->flags, FCVAR_READ_ONLY );
ClearBits( joy_enable->flags, FCVAR_READ_ONLY );
ClearBits( touch_enable->flags, FCVAR_READ_ONLY );
ClearBits( touch_enable.flags, FCVAR_READ_ONLY );
}
}
@ -308,25 +308,39 @@ IN_MouseMove @@ -308,25 +308,39 @@ IN_MouseMove
*/
void IN_MouseMove( void )
{
POINT current_pos;
int x, y;
if( !in_mouseinitialized )
return;
if( FBitSet( touch_emulate.flags, FCVAR_CHANGED ))
{
// FIXME: do not hide cursor if it was requested by GUI
if( !touch_emulate.value )
Platform_SetCursorType( dc_none );
ClearBits( touch_emulate.flags, FCVAR_CHANGED );
}
if( touch_emulate.value )
{
// touch emulation overrides all input
Touch_KeyEvent( 0, 0 );
return;
}
// find mouse movement
Platform_GetMousePos( &current_pos.x, &current_pos.y );
Platform_GetMousePos( &x, &y );
VGui_MouseMove( current_pos.x, current_pos.y );
VGui_MouseMove( x, y );
// HACKHACK: show cursor in UI, as mainui doesn't call
// platform-dependent SetCursor anymore
#if XASH_SDL
if( UI_IsVisible() )
SDL_ShowCursor( SDL_TRUE );
#endif
if( UI_IsVisible( ))
Platform_SetCursorType( dc_arrow );
// if the menu is visible, move the menu cursor
UI_MouseMove( current_pos.x, current_pos.y );
UI_MouseMove( x, y );
}
/*
@ -336,8 +350,6 @@ IN_MouseEvent @@ -336,8 +350,6 @@ IN_MouseEvent
*/
void IN_MouseEvent( int key, int down )
{
int i;
if( !in_mouseinitialized )
return;
@ -345,10 +357,15 @@ void IN_MouseEvent( int key, int down ) @@ -345,10 +357,15 @@ void IN_MouseEvent( int key, int down )
SetBits( in_mstate, BIT( key ));
else ClearBits( in_mstate, BIT( key ));
if( cls.key_dest == key_game )
// touch emulation overrides all input
if( touch_emulate.value )
{
Touch_KeyEvent( K_MOUSE1 + key, down );
}
else if( cls.key_dest == key_game )
{
// perform button actions
VGui_KeyEvent( K_MOUSE1 + key, down );
VGui_MouseEvent( K_MOUSE1 + key, down );
// don't do Key_Event here
// client may override IN_MouseEvent
@ -363,6 +380,23 @@ void IN_MouseEvent( int key, int down ) @@ -363,6 +380,23 @@ void IN_MouseEvent( int key, int down )
}
}
/*
==============
IN_MWheelEvent
direction is negative for wheel down, otherwise wheel up
==============
*/
void IN_MWheelEvent( int y )
{
int b = y > 0 ? K_MWHEELUP : K_MWHEELDOWN;
VGui_MWheelEvent( y );
Key_Event( b, true );
Key_Event( b, false );
}
/*
===========
IN_Shutdown

5
engine/client/input.h

@ -34,6 +34,7 @@ void IN_Init( void ); @@ -34,6 +34,7 @@ void IN_Init( void );
void Host_InputFrame( void );
void IN_Shutdown( void );
void IN_MouseEvent( int key, int down );
void IN_MWheelEvent( int direction );
void IN_ActivateMouse( void );
void IN_DeactivateMouse( void );
void IN_MouseSavePos( void );
@ -57,8 +58,8 @@ typedef enum @@ -57,8 +58,8 @@ typedef enum
event_motion
} touchEventType;
extern convar_t *touch_enable;
extern convar_t *touch_emulate;
extern convar_t touch_enable;
extern convar_t touch_emulate;
void Touch_Draw( void );
void Touch_SetClientOnly( byte state );

1
engine/client/keys.c

@ -712,7 +712,6 @@ void GAME_EXPORT Key_Event( int key, int down ) @@ -712,7 +712,6 @@ void GAME_EXPORT Key_Event( int key, int down )
}
VGui_KeyEvent( key, down );
Touch_KeyEvent( key, down );
// console key is hardcoded, so the user can never unbind it
if( key == '`' || key == '~' )

73
engine/client/vgui/vgui_draw.c

@ -402,9 +402,8 @@ enum VGUI_KeyCode VGUI_MapKey( int keyCode ) @@ -402,9 +402,8 @@ enum VGUI_KeyCode VGUI_MapKey( int keyCode )
{
VGUI_InitKeyTranslationTable();
if( keyCode < 0 || keyCode >= (int)sizeof( s_pVirtualKeyTrans ) / (int)sizeof( s_pVirtualKeyTrans[0] ))
if( keyCode < 0 || keyCode >= ARRAYSIZE( s_pVirtualKeyTrans ))
{
//Assert( false );
return (enum VGUI_KeyCode)-1;
}
else
@ -413,48 +412,66 @@ enum VGUI_KeyCode VGUI_MapKey( int keyCode ) @@ -413,48 +412,66 @@ enum VGUI_KeyCode VGUI_MapKey( int keyCode )
}
}
void VGui_KeyEvent( int key, int down )
void VGui_MouseEvent( int key, int clicks )
{
enum VGUI_MouseAction mact;
enum VGUI_MouseCode code;
if( !vgui.initialized )
return;
switch( key )
{
case K_MOUSE1:
if( down && host.mouse_visible ) {
Key_EnableTextInput(true, false);
}
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_LEFT );
return;
case K_MOUSE2:
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_RIGHT );
return;
case K_MOUSE3:
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_MIDDLE );
case K_MOUSE1: code = MOUSE_LEFT; break;
case K_MOUSE2: code = MOUSE_RIGHT; break;
case K_MOUSE3: code = MOUSE_MIDDLE; break;
default: return;
}
if( clicks >= 2 )
mact = MA_DOUBLE;
else if( clicks == 1 )
mact = MA_PRESSED;
else
mact = MA_RELEASED;
vgui.Mouse( mact, code );
}
void VGui_MWheelEvent( int y )
{
if( !vgui.initialized )
return;
case K_MWHEELDOWN:
vgui.Mouse( MA_WHEEL, 1 );
vgui.Mouse( MA_WHEEL, y );
}
void VGui_KeyEvent( int key, int down )
{
enum VGUI_KeyCode code;
if( !vgui.initialized )
return;
case K_MWHEELUP:
vgui.Mouse( MA_WHEEL, -1 );
if(( code = VGUI_MapKey( key )) < 0 )
return;
default:
break;
}
if( down == 2 )
vgui.Key( KA_TYPED, VGUI_MapKey( key ) );
else
vgui.Key( down?KA_PRESSED:KA_RELEASED, VGUI_MapKey( key ) );
//Msg("VGui_KeyEvent %d %d %d\n", key, VGUI_MapKey( key ), down );
if( down )
{
vgui.Key( KA_PRESSED, code );
vgui.Key( KA_TYPED, code );
}
else vgui.Key( KA_RELEASED, code );
}
void VGui_MouseMove( int x, int y )
{
float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
if( vgui.initialized )
{
float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
vgui.MouseMove( x / xscale, y / yscale );
}
}
void VGui_Paint( void )

2
engine/client/vgui/vgui_draw.h

@ -29,6 +29,8 @@ void VGui_Startup( const char *clientlib, int width, int height ); @@ -29,6 +29,8 @@ void VGui_Startup( const char *clientlib, int width, int height );
void VGui_Shutdown( void );
void VGui_Paint( void );
void VGui_RunFrame( void );
void VGui_MouseEvent( int key, int clicks );
void VGui_MWheelEvent( int y );
void VGui_KeyEvent( int key, int down );
void VGui_MouseMove( int x, int y );
qboolean VGui_IsActive( void );

21
engine/platform/linux/in_evdev.c

@ -343,23 +343,16 @@ void IN_EvdevFrame ( void ) @@ -343,23 +343,16 @@ void IN_EvdevFrame ( void )
{
switch ( ev.code )
{
case REL_X: dx += ev.value;
case REL_X:
dx += ev.value;
break;
case REL_Y: dy += ev.value;
case REL_Y:
dy += ev.value;
break;
case REL_WHEEL:
if( ev.value > 0)
{
Key_Event( K_MWHEELDOWN, 1 );
Key_Event( K_MWHEELDOWN, 0 );
}
else
{
Key_Event( K_MWHEELUP, 1 );
Key_Event( K_MWHEELUP, 0 );
}
case REL_WHEEL:
IN_MWheelEvent( ev.value );
break;
}
}
@ -367,7 +360,7 @@ void IN_EvdevFrame ( void ) @@ -367,7 +360,7 @@ void IN_EvdevFrame ( void )
{
int key = KeycodeFromEvdev( ev.code, ev.value );
if( CVAR_TO_BOOL(evdev_keydebug) )
if( CVAR_TO_BOOL( evdev_keydebug ))
Con_Printf( "key %d %d %d\n", ev.code, key, ev.value );
Key_Event( key , ev.value );

37
engine/platform/sdl/events.c

@ -250,18 +250,6 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key ) @@ -250,18 +250,6 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key )
Key_Event( keynum, down );
}
static void SDLash_MouseKey( int key, int down, int istouch )
{
if( CVAR_TO_BOOL( touch_emulate ) )
{
Touch_KeyEvent( key, down );
}
else if( in_mouseinitialized && !m_ignore->value && !istouch )
{
Key_Event( key, down );
}
}
/*
=============
SDLash_MouseEvent
@ -270,14 +258,20 @@ SDLash_MouseEvent @@ -270,14 +258,20 @@ SDLash_MouseEvent
*/
static void SDLash_MouseEvent( SDL_MouseButtonEvent button )
{
int down = button.state != SDL_RELEASED;
uint mstate = 0;
int down;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( button.which == SDL_TOUCH_MOUSEID )
return;
#endif
if( button.state == SDL_RELEASED )
down = 0;
else if( button.clicks >= 2 )
down = 2; // special state for double-click in UI
else
down = 1;
switch( button.button )
{
case SDL_BUTTON_LEFT:
@ -297,10 +291,10 @@ static void SDLash_MouseEvent( SDL_MouseButtonEvent button ) @@ -297,10 +291,10 @@ static void SDLash_MouseEvent( SDL_MouseButtonEvent button )
break;
#if ! SDL_VERSION_ATLEAST( 2, 0, 0 )
case SDL_BUTTON_WHEELUP:
Key_Event( K_MWHEELUP, down );
IN_MWheelEvent( -1 );
break;
case SDL_BUTTON_WHEELDOWN:
Key_Event( K_MWHEELDOWN, down );
IN_MWheelEvent( 1 );
break;
#endif // ! SDL_VERSION_ATLEAST( 2, 0, 0 )
default:
@ -435,9 +429,7 @@ static void SDLash_EventFilter( SDL_Event *event ) @@ -435,9 +429,7 @@ static void SDLash_EventFilter( SDL_Event *event )
/* Mouse events */
case SDL_MOUSEMOTION:
if( host.mouse_visible )
{
SDL_GetRelativeMouseState( NULL, NULL );
}
break;
case SDL_MOUSEBUTTONUP:
@ -478,12 +470,8 @@ static void SDLash_EventFilter( SDL_Event *event ) @@ -478,12 +470,8 @@ static void SDLash_EventFilter( SDL_Event *event )
break;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
case SDL_MOUSEWHEEL:
{
int wheelbutton = event->wheel.y < 0 ? K_MWHEELDOWN : K_MWHEELUP;
Key_Event( wheelbutton, true );
Key_Event( wheelbutton, false );
IN_MWheelEvent( event->wheel.y );
break;
}
/* Touch events */
case SDL_FINGERDOWN:
@ -556,7 +544,8 @@ static void SDLash_EventFilter( SDL_Event *event ) @@ -556,7 +544,8 @@ static void SDLash_EventFilter( SDL_Event *event )
{
// Swap axis to follow default axis binding:
// LeftX, LeftY, RightX, RightY, TriggerRight, TriggerLeft
static int sdlControllerAxisToEngine[] = {
static int sdlControllerAxisToEngine[] =
{
JOY_AXIS_SIDE, // SDL_CONTROLLER_AXIS_LEFTX,
JOY_AXIS_FWD, // SDL_CONTROLLER_AXIS_LEFTY,
JOY_AXIS_PITCH, // SDL_CONTROLLER_AXIS_RIGHTX,

7
engine/platform/sdl/in_sdl.c

@ -333,11 +333,12 @@ void Platform_SetCursorType( VGUI_DefaultCursor type ) @@ -333,11 +333,12 @@ void Platform_SetCursorType( VGUI_DefaultCursor type )
break;
}
host.mouse_visible = visible;
if( CVAR_TO_BOOL( touch_emulate ))
// never disable cursor in touch emulation mode
if( !visible && touch_emulate.value )
return;
host.mouse_visible = visible;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( host.mouse_visible )
{

Loading…
Cancel
Save