diff --git a/engine/client/in_touch.c b/engine/client/in_touch.c index 8b506b19..58f0d7b7 100644 --- a/engine/client/in_touch.c +++ b/engine/client/in_touch.c @@ -45,16 +45,14 @@ typedef enum typedef struct touch_button_s { - // Touch button type: tap, stick or slider touchButtonType type; - // Field of button + // button coordinates float x1, y1, x2, y2; - // Button texture - int texture; + int gl_texturenum; rgba_t color; - char texturefile[256]; + char texture[256]; char command[256]; char name[32]; int finger; @@ -72,7 +70,7 @@ typedef struct touch_button_s typedef struct touchdefaultbutton_s { char name[32]; - char texturefile[256]; + char texture[256]; char command[256]; float x1, y1, x2, y2; rgba_t color; @@ -139,8 +137,8 @@ static struct touch_s // private to the engine flags #define TOUCH_FL_UNPRIVILEGED BIT( 10 ) -touchdefaultbutton_t g_DefaultButtons[256]; -int g_LastDefaultButton; +static touchdefaultbutton_t *g_DefaultButtons; +static size_t g_DefaultButtonsLength; static CVAR_DEFINE_AUTO( touch_in_menu, "0", FCVAR_PRIVILEGED, "draw touch in menu (for internal use only)" ); static CVAR_DEFINE_AUTO( touch_forwardzone, "0.06", FCVAR_FILTERABLE, "forward touch zone" ); @@ -167,9 +165,6 @@ static CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_PRIVILEGED, "emulate touch wi CVAR_DEFINE_AUTO( touch_enable, DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" ); // code looks smaller with it -#define B(x) (button->x) -#define SCR_W ((float)refState.width) -#define SCR_H ((float)refState.height) #define TO_SCRN_Y(x) (refState.width * (x) * Touch_AspectRatio()) #define TO_SCRN_X(x) (refState.width * (x)) @@ -181,7 +176,7 @@ void Touch_NotifyResize( void ) { if( refState.width && refState.height && ( !touch.configchanged || !touch.actual_aspect_ratio )) { - float aspect_ratio = SCR_H/SCR_W; + float aspect_ratio = (float)refState.height / refState.width; if( aspect_ratio < 0.99 && aspect_ratio > touch.actual_aspect_ratio ) touch.actual_aspect_ratio = aspect_ratio; } @@ -191,14 +186,15 @@ static inline float Touch_AspectRatio( void ) { if( touch.config_aspect_ratio ) return touch.config_aspect_ratio; - else if( touch.actual_aspect_ratio ) - return touch.actual_aspect_ratio; - else if( refState.width && refState.height ) - return SCR_H/SCR_W; - else - return 9.0f / 16.0f; -} + if( touch.actual_aspect_ratio ) + return touch.actual_aspect_ratio; + + if( refState.width && refState.height ) + return (float)refState.height / refState.width; + + return 9.0f / 16.0f; +} static void Touch_ConfigAspectRatio_f( void ) { @@ -211,16 +207,15 @@ static void Touch_ConfigAspectRatio_f( void ) Touch_ExportButtonToConfig writes button data to config -returns 0 on success, non-zero on error ========================== */ -static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button, qboolean keepAspect ) +static void Touch_ExportButtonToConfig( file_t *f, const touch_button_t *button, qboolean keepAspect ) { string newCommand; int flags = button->flags; if( FBitSet( flags, TOUCH_FL_CLIENT )) - return 1; // skip temporary buttons + return; // skip temporary buttons if( FBitSet( flags, TOUCH_FL_DEF_SHOW )) ClearBits( flags, TOUCH_FL_HIDE ); @@ -228,21 +223,20 @@ static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button, if( FBitSet( flags, TOUCH_FL_DEF_HIDE )) SetBits( flags, TOUCH_FL_HIDE ); - Cmd_Escape( newCommand, B( command ), sizeof( newCommand )); + Cmd_Escape( newCommand, button->command, sizeof( newCommand )); - FS_Printf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %f %f %f %f %d %d %d %d %d", - B(name), B(texturefile), newCommand, - B(x1), B(y1), B(x2), B(y2), - B(color[0]), B(color[1]), B(color[2]), B(color[3]), flags ); + FS_Printf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %g %g %g %g %d %d %d %d %d", + button->name, button->texture, newCommand, + button->x1, button->y1, button->x2, button->y2, + button->color[0], button->color[1], button->color[2], button->color[3], + flags ); if( keepAspect ) { - float aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(Touch_AspectRatio()) ); - FS_Printf( f, " %f\n", aspect ); + float aspect = ( button->y2 - button->y1 ) / (( button->x2 - button->x1 ) / Touch_AspectRatio( )); + FS_Printf( f, " %g\n", aspect ); } else FS_Printf( f, "\n" ); - - return 0; } /* @@ -255,7 +249,7 @@ Dump config to file static qboolean Touch_DumpConfig( const char *name, const char *profilename ) { file_t *f; - touch_button_t *button; + const touch_button_t *button; f = FS_Open( name, "w", true ); @@ -272,46 +266,42 @@ static qboolean Touch_DumpConfig( const char *name, const char *profilename ) FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename ); FS_Printf( f, "\n// touch cvars\n" ); FS_Printf( f, "\n// sensitivity settings\n" ); - FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch.value ); - FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw.value ); - FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone.value ); - FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone.value ); + FS_Printf( f, "touch_pitch \"%g\"\n", touch_pitch.value ); + FS_Printf( f, "touch_yaw \"%g\"\n", touch_yaw.value ); + FS_Printf( f, "touch_forwardzone \"%g\"\n", touch_forwardzone.value ); + FS_Printf( f, "touch_sidezone \"%g\"\n", touch_sidezone.value ); FS_Printf( f, "touch_nonlinear_look \"%d\"\n", touch_nonlinear_look.value ? 1 : 0 ); - FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor.value ); - FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult.value ); - FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult.value ); + FS_Printf( f, "touch_pow_factor \"%g\"\n", touch_pow_factor.value ); + FS_Printf( f, "touch_pow_mult \"%g\"\n", touch_pow_mult.value ); + FS_Printf( f, "touch_exp_mult \"%g\"\n", touch_exp_mult.value ); FS_Printf( f, "\n// grid settings\n" ); FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count.value ); FS_Printf( f, "touch_grid_enable \"%d\"\n", touch_grid_enable.value ? 1 : 0 ); FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" ); FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] ); FS_Printf( f, "\n// highlight when pressed\n" ); - FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r.value ); - FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g.value ); - FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b.value ); - FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a.value ); + FS_Printf( f, "touch_highlight_r \"%g\"\n", touch_highlight_r.value ); + FS_Printf( f, "touch_highlight_g \"%g\"\n", touch_highlight_g.value ); + FS_Printf( f, "touch_highlight_b \"%g\"\n", touch_highlight_b.value ); + FS_Printf( f, "touch_highlight_a \"%g\"\n", touch_highlight_a.value ); FS_Printf( f, "\n// _joy and _dpad options\n" ); - FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius.value ); - FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius.value ); + FS_Printf( f, "touch_dpad_radius \"%g\"\n", touch_dpad_radius.value ); + FS_Printf( f, "touch_joy_radius \"%g\"\n", touch_joy_radius.value ); FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" ); - FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount.value ); + FS_Printf( f, "touch_precise_amount \"%g\"\n", touch_precise_amount.value ); FS_Printf( f, "\n// enable/disable move indicator\n" ); - FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator.value ); + FS_Printf( f, "touch_move_indicator \"%g\"\n", touch_move_indicator.value ); FS_Printf( f, "\n// reset menu state when execing config\n" ); FS_Printf( f, "touch_setclientonly 0\n" ); FS_Printf( f, "\n// touch buttons\n" ); FS_Printf( f, "touch_removeall\n" ); - FS_Printf( f, "touch_aspectratio %f\n", Touch_AspectRatio()); - + FS_Printf( f, "touch_aspectratio %g\n", Touch_AspectRatio()); for( button = touch.list_user.first; button; button = button->next ) - { Touch_ExportButtonToConfig( f, button, false ); - } FS_Close( f ); - return true; } @@ -324,7 +314,6 @@ save current touch configuration */ void Touch_WriteConfig( void ) { - file_t *f; string newconfigfile, oldconfigfile; if( !touch.list_user.first ) @@ -358,7 +347,7 @@ export current touch configuration into profile static void Touch_ExportConfig_f( void ) { const char *name; - string profilename, profilebase; + string profilename; if( Cmd_Argc() != 2 ) { @@ -366,12 +355,18 @@ static void Touch_ExportConfig_f( void ) return; } - if( !touch.list_user.first ) return; + if( !touch.list_user.first ) + { + Con_Printf( "%s: nothing to export\n", __func__ ); + return; + } name = Cmd_Argv( 1 ); if( Q_strstr( name, "touch_presets/" )) { + string profilebase; + COM_FileBase( name, profilebase, sizeof( profilebase )); Q_snprintf( profilename, sizeof( profilebase ), "touch_profiles/%s (copy).cfg", profilebase ); } @@ -390,15 +385,20 @@ export current touch configuration into C code */ static void Touch_GenerateCode_f( void ) { - touch_button_t *button; - rgba_t c = {0,0,0,0}; + const touch_button_t *button; + rgba_t c = { 0 }; - if( !touch.list_user.first ) return; + if( !touch.list_user.first ) + { + Con_Printf( "%s: nothing to export\n", __func__ ); + return; + } for( button = touch.list_user.first; button; button = button->next ) { float aspect; int flags = button->flags; + int round; if( FBitSet( flags, TOUCH_FL_CLIENT )) continue; // skip temporary buttons @@ -409,15 +409,29 @@ static void Touch_GenerateCode_f( void ) if( FBitSet( flags, TOUCH_FL_DEF_HIDE )) SetBits( flags, TOUCH_FL_HIDE ); - aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(Touch_AspectRatio()) ); - if( memcmp( &c, &B(color), sizeof( rgba_t ) ) ) + aspect = ( button->y2 - button->y1 ) / (( button->x2 - button->x1 ) / Touch_AspectRatio( )); + + if( memcmp( c, button->color, sizeof( c ))) { - Con_Printf( "unsigned char color[] = { %d, %d, %d, %d };\n", B(color[0]), B(color[1]), B(color[2]), B(color[3]) ); - memcpy( &c, &B(color), sizeof( rgba_t ) ); + Con_Printf( "unsigned char color[] = { %d, %d, %d, %d };\n", + button->color[0], button->color[1], button->color[2], button->color[3] ); + memcpy( c, button->color, sizeof( c )); } - Con_Printf( "TOUCH_ADDDEFAULT( \"%s\", \"%s\", \"%s\", %f, %f, %f, %f, color, %d, %f, %d );\n", - B(name), B(texturefile), B(command), - B(x1), B(y1), B(x2), B(y2), (B(type) == touch_command)?(fabs( aspect - 1.0f) < 0.0001)?2:1:0, aspect, flags ); + + if( button->type == touch_command ) + { + if( fabs( aspect - 1.0f ) < 0.001 ) + round = round_aspect; + else + round = round_grid; + } + else + round = round_none; + + Con_Printf( "TOUCH_ADDDEFAULT( \"%s\", \"%s\", \"%s\", %gf, %gf, %gf, %gf, color, %d, %g, %d );\n", + button->name, button->texture, button->command, + button->x1, button->y1, button->x2, button->y2, + round, aspect, flags ); } } @@ -429,25 +443,27 @@ static void Touch_RoundAll_f( void ) return; for( button = touch.list_user.first; button; button = button->next ) - IN_TouchCheckCoords( &B(x1), &B(y1), &B(x2), &B(y2) ); + IN_TouchCheckCoords( &button->x1, &button->y1, &button->x2, &button->y2 ); } static void Touch_ListButtons_f( void ) { touch_button_t *button; + Touch_InitConfig(); for( button = touch.list_user.first; button; button = button->next ) { - Con_Printf( "%s %s %s %f %f %f %f %d %d %d %d %d\n", - B(name), B(texturefile), B(command), - B(x1), B(y1), B(x2), B(y2), - B(color[0]), B(color[1]), B(color[2]), B(color[3]), B(flags) ); + Con_Printf( "%s %s %s %g %g %g %g %d %d %d %d %d\n", + button->name, button->texture, button->command, + button->x1, button->y1, button->x2, button->y2, + button->color[0], button->color[1], button->color[2], button->color[3], + button->flags ); - if( B(flags) & TOUCH_FL_CLIENT) + if( FBitSet( button->flags, TOUCH_FL_CLIENT )) continue; - UI_AddTouchButtonToList( B(name), B(texturefile), B(command),B(color), B(flags) ); + UI_AddTouchButtonToList( button->name, button->texture, button->command, button->color, button->flags ); } touch.configchanged = true; } @@ -464,57 +480,65 @@ static void Touch_Stroke_f( void ) MakeRGBA( touch.scolor, Q_atoi( Cmd_Argv( 2 ) ), Q_atoi( Cmd_Argv( 3 ) ), Q_atoi( Cmd_Argv( 4 ) ), Q_atoi( Cmd_Argv( 5 ) ) ); } -static touch_button_t *Touch_FindButton( touchbuttonlist_t *list, const char *name, qboolean privileged ) +static touch_button_t *Touch_FindNextNoPattern( touch_button_t *buttons, const char *name, qboolean privileged ) { - touch_button_t *button; + touch_button_t *b; - for( button = list->first; button; button = button->next ) + for( b = buttons; b; b = b->next ) { - if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED )) + if( !privileged && !FBitSet( b->flags, TOUCH_FL_UNPRIVILEGED )) continue; - if( Q_strncmp( button->name, name, sizeof( button->name ))) - continue; - - return button; + if( !Q_strncmp( b->name, name, sizeof( b->name ))) + return b; } return NULL; } -static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *name, qboolean privileged ) +static touch_button_t *Touch_FindButtonNoPattern( touchbuttonlist_t *list, const char *name, qboolean privileged ) { - touch_button_t *button; + return Touch_FindNextNoPattern( list->first, name, privileged ); +} - for( button = list->first; button; button = button->next ) +static touch_button_t *Touch_FindNext( touch_button_t *buttons, const char *name, qboolean privileged ) +{ + touch_button_t *b; + qboolean has_pattern = Q_strchr( name, '*' ) != NULL; + + if( !has_pattern ) + return Touch_FindNextNoPattern( buttons, name, privileged ); + + for( b = buttons; b; b = b->next ) { - if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED )) + if( !privileged && !FBitSet( b->flags, TOUCH_FL_UNPRIVILEGED )) continue; - if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name ))) - { - return button; - } + if( Q_stricmpext( name, b->name )) + return b; } + return NULL; } + +static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *name, qboolean privileged ) +{ + return Touch_FindNext( list->first, name, privileged ); +} + void Touch_SetClientOnly( byte state ) { // TODO: fix clash with vgui cursors touch.clientonly = state; - touch.move_finger = touch.look_finger = -1; + touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; touch.forward = touch.side = 0; if( state ) - { IN_DeactivateMouse(); - } else - { IN_ActivateMouse(); - } } static void Touch_SetClientOnly_f( void ) @@ -548,7 +572,6 @@ static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *nam Mem_Free( button ); } - } void Touch_RemoveButton( const char *name, qboolean privileged ) @@ -564,7 +587,7 @@ static void IN_TouchRemoveButton_f( void ) return; } - Touch_RemoveButton( Cmd_Argv( 1 ), Cmd_CurrentCommandIsPrivileged()); + Touch_RemoveButton( Cmd_Argv( 1 ), Cmd_CurrentCommandIsPrivileged( )); } static void Touch_ClearList( touchbuttonlist_t *list ) @@ -585,26 +608,23 @@ static void Touch_RemoveAll_f( void ) touch.config_aspect_ratio = 0.0f; } -static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *color ) +static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *color, qboolean privileged ) { - touch_button_t *button; + touch_button_t *b; - for( button = list->first; button; button = button->next ) - { - if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name ))) - MakeRGBA( button->color, color[0], color[1], color[2], color[3] ); - } + for( b = Touch_FindFirst( list, name, privileged ); b != NULL; b = Touch_FindNext( b->next, name, privileged )) + Vector4Copy( color, b->color ); } static void Touch_SetTexture( touchbuttonlist_t *list, const char *name, const char *texture, qboolean privileged ) { - touch_button_t *button = Touch_FindButton( list, name, privileged ); + touch_button_t *button = Touch_FindButtonNoPattern( list, name, privileged ); if( !button ) return; - button->texture = -1; // mark for texture load - Q_strncpy( button->texturefile, texture, sizeof( button->texturefile )); + button->gl_texturenum = -1; // mark for texture load + Q_strncpy( button->texture, texture, sizeof( button->texture )); } static void Touch_SetCommand( touch_button_t *button, const char *command ) @@ -619,26 +639,22 @@ static void Touch_SetCommand( touch_button_t *button, const char *command ) button->type = touch_joy; else if( !Q_strcmp( command, "_dpad" )) button->type = touch_dpad; - else if( Q_stricmpext( "_wheel *", command ) || Q_stricmpext( "_hwheel *", command )) + else if( !Q_strncmp( "_wheel ", command, 7 ) || !Q_strncmp( "_hwheel ", command, 8 )) button->type = touch_wheel; + else + button->type = touch_command; } void Touch_HideButtons( const char *name, byte hide, qboolean privileged ) { - touch_button_t *button; + touch_button_t *b; - for( button = touch.list_user.first; button; button = button->next) + for( b = Touch_FindFirst( &touch.list_user, name, privileged ); b != NULL; b = Touch_FindNext( b->next, name, privileged )) { - if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED )) - continue; - - if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name ))) - { - if( hide ) - SetBits( button->flags, TOUCH_FL_HIDE ); - else - ClearBits( button->flags, TOUCH_FL_HIDE ); - } + if( hide ) + SetBits( b->flags, TOUCH_FL_HIDE ); + else + ClearBits( b->flags, TOUCH_FL_HIDE ); } } @@ -656,7 +672,7 @@ static void Touch_Hide_f( void ) return; } - Touch_HideButtons( Cmd_Argv( 1 ), true, Cmd_CurrentCommandIsPrivileged() ); + Touch_HideButtons( Cmd_Argv( 1 ), true, Cmd_CurrentCommandIsPrivileged( )); } static void Touch_Show_f( void ) @@ -667,24 +683,19 @@ static void Touch_Show_f( void ) return; } - Touch_HideButtons( Cmd_Argv( 1 ), false, Cmd_CurrentCommandIsPrivileged() ); + Touch_HideButtons( Cmd_Argv( 1 ), false, Cmd_CurrentCommandIsPrivileged( )); } static void Touch_FadeButtons( touchbuttonlist_t *list, const char *name, float speed, float end, float start, qboolean privileged ) { - touch_button_t *button; - for( button = list->first; button; button = button->next) - { - if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED )) - continue; + touch_button_t *b; - if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name ))) - { - if( start >= 0 ) - button->fade = start; - button->fadespeed = speed; - button->fadeend = end; - } + for( b = Touch_FindFirst( list, name, privileged ); b != NULL; b = Touch_FindNext( b->next, name, privileged )) + { + if( start >= 0 ) + b->fade = start; + b->fadespeed = speed; + b->fadeend = end; } } @@ -703,29 +714,24 @@ static void Touch_Fade_f( void ) } Touch_FadeButtons( &touch.list_user,Cmd_Argv( 1 ), Q_atof( Cmd_Argv( 2 )), Q_atof( Cmd_Argv( 3 )), - start, Cmd_CurrentCommandIsPrivileged() ); + start, Cmd_CurrentCommandIsPrivileged( )); } static void Touch_SetColor_f( void ) { - rgba_t color; if( Cmd_Argc() == 6 ) { - MakeRGBA( color, Q_atoi( Cmd_Argv(2) ), Q_atoi( Cmd_Argv(3) ), Q_atoi( Cmd_Argv(4) ), Q_atoi( Cmd_Argv(5) ) ); - Touch_SetColor( &touch.list_user, Cmd_Argv(1), color ); - return; + rgba_t color = { Q_atoi( Cmd_Argv( 2 )), Q_atoi( Cmd_Argv( 3 )), Q_atoi( Cmd_Argv( 4 )), Q_atoi( Cmd_Argv( 5 )) }; + Touch_SetColor( &touch.list_user, Cmd_Argv( 1 ), color, Cmd_CurrentCommandIsPrivileged( )); } - Con_Printf( S_USAGE "touch_setcolor \n" ); + else Con_Printf( S_USAGE "touch_setcolor \n" ); } static void Touch_SetTexture_f( void ) { if( Cmd_Argc() == 3 ) - { - Touch_SetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ), Cmd_CurrentCommandIsPrivileged() ); - return; - } - Con_Printf( S_USAGE "touch_settexture \n" ); + Touch_SetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ), Cmd_CurrentCommandIsPrivileged( )); + else Con_Printf( S_USAGE "touch_settexture \n" ); } static void Touch_SetFlags_f( void ) @@ -733,31 +739,28 @@ static void Touch_SetFlags_f( void ) if( Cmd_Argc() == 3 ) { qboolean privileged = Cmd_CurrentCommandIsPrivileged(); + touch_button_t *button = Touch_FindButtonNoPattern( &touch.list_user, Cmd_Argv( 1 ), privileged ); - touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv( 1 ), privileged ); if( button ) - { button->flags = ( privileged ? 0 : TOUCH_FL_UNPRIVILEGED | TOUCH_FL_CLIENT ) | Q_atoi( Cmd_Argv( 2 )); - } - return; + else + Con_Printf( S_ERROR "no such button" ); } - Con_Printf( S_USAGE "touch_setflags \n" ); + else Con_Printf( S_USAGE "touch_setflags \n" ); } static void Touch_SetCommand_f( void ) { if( Cmd_Argc() == 3 ) { - touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv(1), Cmd_CurrentCommandIsPrivileged() ); + touch_button_t *button = Touch_FindButtonNoPattern( &touch.list_user, Cmd_Argv( 1 ), Cmd_CurrentCommandIsPrivileged( )); if( !button ) - Con_Printf( S_ERROR "no such button" ); - else Touch_SetCommand( button, Cmd_Argv( 2 ) ); - - return; + else + Con_Printf( S_ERROR "no such button" ); } - Con_Printf( S_USAGE "touch_setcommand \n" ); + else Con_Printf( S_USAGE "touch_setcommand \n" ); } static void Touch_LoadDefaults_f( void ); @@ -786,39 +789,38 @@ static void Touch_ReloadConfig_f( void ) } } -static touch_button_t *Touch_AddButton( touchbuttonlist_t *list, - const char *name, const char *texture, const char *command, - float x1, float y1, float x2, float y2, byte *color, - qboolean privileged ) +static touch_button_t *Touch_AddButton( touchbuttonlist_t *list, const char *name, const char *texture, const char *command, + float x1, float y1, float x2, float y2, byte *color, qboolean privileged ) { - touch_button_t *button = Mem_Calloc( touch.mempool, sizeof( touch_button_t ) ); + touch_button_t *b = Mem_Calloc( touch.mempool, sizeof( *b )); - button->texture = -1; - Q_strncpy( button->texturefile, texture, sizeof( B( texturefile ))); - Q_strncpy( button->name, name, sizeof( B( name ))); - Touch_RemoveButtonFromList( list, name, privileged ); //replace if exist - button->x1 = x1; - button->y1 = y1; - button->x2 = x2; - button->y2 = y2; - button->flags = privileged ? 0 : TOUCH_FL_UNPRIVILEGED | TOUCH_FL_CLIENT; - MakeRGBA( button->color, color[0], color[1], color[2], color[3] ); - button->command[0] = 0; - button->fade = 1; + Touch_RemoveButtonFromList( list, name, privileged ); // replace if exist - Touch_SetCommand( button, command ); + b->gl_texturenum = -1; + Q_strncpy( b->texture, texture, sizeof( b->texture )); + Q_strncpy( b->name, name, sizeof( b->name )); + b->x1 = x1; + b->y1 = y1; + b->x2 = x2; + b->y2 = y2; + Vector4Copy( color, b->color ); + b->fade = 1; - button->finger = -1; - button->next = NULL; - button->prev = list->last; - if( list->last ) - list->last->next = button; - list->last = button; + if( !privileged ) + SetBits( b->flags, TOUCH_FL_UNPRIVILEGED | TOUCH_FL_CLIENT ); + + Touch_SetCommand( b, command ); + + b->finger = -1; + b->prev = list->last; + if( b->prev ) + b->prev->next = b; + list->last = b; if( !list->first ) - list->first = button; + list->first = b; - return button; + return b; } void Touch_AddClientButton( const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags ) @@ -827,21 +829,22 @@ void Touch_AddClientButton( const char *name, const char *texture, const char *c if( !touch.initialized ) return; + if( round ) IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); + if( round == round_aspect ) - { y2 = y1 + ( x2 - x1 ) / (Touch_AspectRatio()) * aspect; - } + button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, true ); - button->flags |= flags | TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT; + SetBits( button->flags, TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT ); button->aspect = aspect; } static void Touch_LoadDefaults_f( void ) { int i; - for( i = 0; i < g_LastDefaultButton; i++ ) + for( i = 0; i < g_DefaultButtonsLength; i++ ) { touch_button_t *button; float x1 = g_DefaultButtons[i].x1, @@ -853,61 +856,67 @@ static void Touch_LoadDefaults_f( void ) if( g_DefaultButtons[i].aspect && g_DefaultButtons[i].round == round_aspect ) { - if( g_DefaultButtons[i].texturefile[0] == '#' ) - y2 = y1 + ( (float)clgame.scrInfo.iCharHeight / (float)clgame.scrInfo.iHeight ) * g_DefaultButtons[i].aspect + touch.swidth*2/SCR_H; + if( g_DefaultButtons[i].texture[0] == '#' ) + y2 = y1 + ( (float)clgame.scrInfo.iCharHeight / (float)clgame.scrInfo.iHeight ) * g_DefaultButtons[i].aspect + touch.swidth * 2.0f / refState.height; else y2 = y1 + (( x2 - x1 ) / Touch_AspectRatio()) * g_DefaultButtons[i].aspect; } IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); - button = Touch_AddButton( &touch.list_user, g_DefaultButtons[i].name, g_DefaultButtons[i].texturefile, g_DefaultButtons[i].command, x1, y1, x2, y2, g_DefaultButtons[i].color, true ); - button->flags |= g_DefaultButtons[i].flags; + + button = Touch_AddButton( &touch.list_user, g_DefaultButtons[i].name, g_DefaultButtons[i].texture, g_DefaultButtons[i].command, x1, y1, x2, y2, g_DefaultButtons[i].color, true ); + SetBits( button->flags, g_DefaultButtons[i].flags ); button->aspect = g_DefaultButtons[i].aspect; } touch.configchanged = true; } // Add default button from client -void Touch_AddDefaultButton( const char *name, const char *texturefile, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags ) +void Touch_AddDefaultButton( const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags ) { - touchdefaultbutton_t *button; + touchdefaultbutton_t *b; - if( g_LastDefaultButton >= 255 ) - return; + g_DefaultButtons = Mem_Realloc( touch.mempool, g_DefaultButtons, sizeof( *g_DefaultButtons ) * ( g_DefaultButtonsLength + 1 )); - button = g_DefaultButtons + g_LastDefaultButton; + b = &g_DefaultButtons[g_DefaultButtonsLength]; - Q_strncpy( B( name ), name, sizeof( B( name ))); - Q_strncpy( B( texturefile ), texturefile, sizeof( B( texturefile ))); - Q_strncpy( B( command ), command, sizeof( B( command ))); - B( x1 ) = x1; - B( y1 ) = y1; - B( x2 ) = x2; - B( y2 ) = y2; - MakeRGBA( B( color ), color[0], color[1], color[2], color[3] ); - B( round ) = round; - B( aspect ) = aspect; - B( flags ) = flags; - g_LastDefaultButton++; + Q_strncpy( b->name, name, sizeof( b->name )); + Q_strncpy( b->texture, texture, sizeof( b->texture )); + Q_strncpy( b->command, command, sizeof( b->command )); + b->x1 = x1; + b->y1 = y1; + b->x2 = x2; + b->y2 = y2; + Vector4Copy( color, b->color ); + b->round = round; + b->aspect = aspect; + b->flags = flags; + + g_DefaultButtonsLength++; } // Client may remove all default buttons from engine void Touch_ResetDefaultButtons( void ) { - g_LastDefaultButton = 0; + g_DefaultButtonsLength = 0; + + if( g_DefaultButtons ) + { + Mem_Free( g_DefaultButtons ); + g_DefaultButtons = NULL; + } } static void Touch_AddButton_f( void ) { - rgba_t color; - int argc = Cmd_Argc( ); + rgba_t color = { 255, 255, 255, 255 }; touch_button_t *button = NULL; const char *name, *command; - float x1, y1, x2, y2; + float x1 = 0.4f, y1 = 0.4f, x2 = 0.6f, y2 = 0.6f; qboolean privileged = Cmd_CurrentCommandIsPrivileged(); string texture; - if( argc < 4 ) + if( Cmd_Argc( ) < 4 ) { Con_Printf( S_USAGE "touch_addbutton [ [ r g b a ] ]\n" ); return; @@ -926,12 +935,7 @@ static void Touch_AddButton_f( void ) if( Q_stricmp( COM_FileExtension( texture ), "tga" )) COM_StripExtension( texture ); - if( argc < 8 ) - { - x1 = y1 = 0.4f; - x2 = y2 = 0.6f; - } - else + if( Cmd_Argc( ) >= 8 ) { x1 = Q_atof( Cmd_Argv( 4 )); y1 = Q_atof( Cmd_Argv( 5 )); @@ -939,49 +943,44 @@ static void Touch_AddButton_f( void ) y2 = Q_atof( Cmd_Argv( 7 )); } - if( argc < 12 ) + if( Cmd_Argc( ) >= 12 ) { - MakeRGBA( color, 255, 255, 255, 255 ); - } - else - { - MakeRGBA( color, - Q_atoi( Cmd_Argv( 8 )), - Q_atoi( Cmd_Argv( 9 )), - Q_atoi( Cmd_Argv( 10 )), - Q_atoi( Cmd_Argv( 11 ))); + color[0] = Q_atoi( Cmd_Argv( 8 )); + color[1] = Q_atoi( Cmd_Argv( 9 )); + color[2] = Q_atoi( Cmd_Argv( 10 )); + color[3] = Q_atoi( Cmd_Argv( 11 )); } button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, privileged ); - if( argc >= 13 ) - { + if( Cmd_Argc( ) >= 13 ) SetBits( button->flags, Q_atoi( Cmd_Argv( 12 ))); - } - if( argc >= 14 ) + if( Cmd_Argc( ) >= 14 ) { // Recalculate button coordinates aspect ratio // This is feature for distributed configs float aspect = Q_atof( Cmd_Argv( 13 )); if( aspect ) { - if( B( texturefile )[0] != '#' ) - B( y2 ) = B( y1 ) + (( B( x2 ) - B( x1 )) / Touch_AspectRatio() ) * aspect; - B( aspect ) = aspect; + if( button->texture[0] != '#' ) + button->y2 = button->y1 + (( button->x2 - button->x1 ) / Touch_AspectRatio( )) * aspect; + button->aspect = aspect; } } } static void Touch_EnableEdit_f( void ) { - touch_button_t *button; - float current_ratio = SCR_H/SCR_W; + float current_ratio = (float)refState.height / refState.width; + if( touch.state == state_none ) touch.state = state_edit; + touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; touch.move_button = NULL; touch.configchanged = true; + /* try determine the best ratio * User enters editor. Window now have correct size. Need to fix aspect ratio in some cases */ // Case A: no config was loaded, touch was generated with lower height, but window was resized higher, reset it to actual size @@ -991,19 +990,22 @@ static void Touch_EnableEdit_f( void ) touch.config_aspect_ratio = touch.actual_aspect_ratio; // Case B: config was loaded, but window may be resized later, so keep y coordinate as is touch.actual_aspect_ratio = current_ratio; + // convert coordinates to actual aspect ratio after it was updated if( touch.config_aspect_ratio != touch.actual_aspect_ratio ) { + touch_button_t *button; + for( button = touch.list_user.first; button; button = button->next ) { - B(y1) /= touch.actual_aspect_ratio / touch.config_aspect_ratio; - B(y2) /= touch.actual_aspect_ratio / touch.config_aspect_ratio; + button->y1 /= touch.actual_aspect_ratio / touch.config_aspect_ratio; + button->y2 /= touch.actual_aspect_ratio / touch.config_aspect_ratio; // clamp positions to make buttons visible by user - if( B(y2) > 1.0f ) + if( button->y2 > 1.0f ) { - B(y1) -= B(y2) - 1.0f; - B(y2) -= B(y2) - 1.0f; + button->y1 -= button->y2 - 1.0f; + button->y2 -= button->y2 - 1.0f; } } touch.config_aspect_ratio = touch.actual_aspect_ratio; @@ -1021,9 +1023,7 @@ static void Touch_DisableEdit_f( void ) touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; if( touch_in_menu.value ) - { - Cvar_Set( "touch_in_menu", "0" ); - } + Cvar_DirectSet( &touch_in_menu, "0" ); else if( cls.key_dest == key_game ) Touch_WriteConfig(); } @@ -1074,19 +1074,22 @@ static void Touch_InitEditor( void ) void Touch_Init( void ) { rgba_t color; + if( touch.initialized ) return; + touch.mempool = Mem_AllocPool( "Touch" ); //touch.first = touch.last = NULL; Con_Printf( "%s()\n", __func__ ); - touch.move_finger = touch.resize_finger = touch.look_finger = touch.wheel_finger = -1; + touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; touch.state = state_none; touch.showeditbuttons = true; touch.clientonly = false; touch.precision = false; MakeRGBA( touch.scolor, 255, 255, 255, 255 ); touch.swidth = 1; - g_LastDefaultButton = 0; + g_DefaultButtons = NULL; + g_DefaultButtonsLength = 0; touch.list_edit.first = touch.list_edit.last = NULL; touch.list_user.first = touch.list_user.last = NULL; @@ -1175,7 +1178,7 @@ void Touch_Init( void ) #if SDL_VERSION_ATLEAST( 2, 0, 10 ) SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" ); SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" ); -#elif defined(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH) +#elif defined( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH ) SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" ); #endif @@ -1185,13 +1188,7 @@ void Touch_Init( void ) //int pfnGetScreenInfo( SCREENINFO *pscrinfo ); static void Touch_InitConfig( void ) { - if( !touch.initialized ) - return; - - if( !host.config_executed ) - return; - - if( touch.config_loaded ) + if( !touch.initialized || !host.config_executed || touch.config_loaded ) return; /// TODO: hud font @@ -1201,10 +1198,7 @@ static void Touch_InitConfig( void ) Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file.string ); Cbuf_Execute(); } - else - { - Touch_LoadDefaults_f(); - } + else Touch_LoadDefaults_f(); Touch_InitEditor(); touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_NOMIPMAP ); @@ -1227,58 +1221,76 @@ static qboolean Touch_IsVisible( touch_button_t *button ) return false; // skip nonclient buttons in clientonly mode if( touch.state >= state_edit ) - return true; //!!! Draw when editor is open + return true; // draw when editor is open if( FBitSet( button->flags, TOUCH_FL_HIDE )) return false; // skip hidden - if( FBitSet( button->flags, TOUCH_FL_SP ) && cl.maxclients != 1 ) - return false; // skip singleplayer(load, save) buttons in multiplayer - - if( FBitSet( button->flags, TOUCH_FL_MP ) && cl.maxclients == 1 ) - return false; // skip multiplayer buttons in singleplayer + if( cl.maxclients == 1 ) + { + if( FBitSet( button->flags, TOUCH_FL_MP )) + return false; // skip multiplayer buttons in singleplayer + } + else + { + if( FBitSet( button->flags, TOUCH_FL_SP )) + return false; // skip singleplayer(load, save) buttons in multiplayer + } return true; } -static void Touch_DrawTexture ( float x1, float y1, float x2, float y2, int texture, byte r, byte g, byte b, byte a ) +static void Touch_DrawTexture( float x1, float y1, float x2, float y2, int texture, byte *color ) { - if( x1 >= x2 ) + if( x1 >= x2 || y1 >= y2 ) return; - if( y1 >= y2 ) - return; - - ref.dllFuncs.Color4ub( r, g, b, a ); - ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X(x1), - TO_SCRN_Y(y1), - TO_SCRN_X(x2 - x1), - TO_SCRN_Y(y2 - y1), + ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] ); + ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( x1 ), TO_SCRN_Y( y1 ), + TO_SCRN_X( x2 - x1 ), TO_SCRN_Y( y2 - y1 ), 0, 0, 1, 1, texture ); } -#define GRID_COUNT_X ((int)touch_grid_count.value) -#define GRID_COUNT_Y (((int)touch_grid_count.value) * Touch_AspectRatio()) -#define GRID_X (1.0f/GRID_COUNT_X) -#define GRID_Y (1.0f/Touch_AspectRatio()/GRID_COUNT_X) -#define GRID_ROUND_X(x) ((float)round( x * GRID_COUNT_X ) / GRID_COUNT_X) -#define GRID_ROUND_Y(x) ((float)round( x * GRID_COUNT_Y ) / GRID_COUNT_Y) +#define GRID_COUNT_X ((int)touch_grid_count.value ) +#define GRID_COUNT_Y (((int)touch_grid_count.value ) * Touch_AspectRatio( )) +#define GRID_X ( 1.0f / GRID_COUNT_X ) +#define GRID_Y ( 1.0f / Touch_AspectRatio() / GRID_COUNT_X ) +#define GRID_ROUND_X( x ) ((float)round(( x ) * GRID_COUNT_X ) / GRID_COUNT_X ) +#define GRID_ROUND_Y( x ) ((float)round(( x ) * GRID_COUNT_Y ) / GRID_COUNT_Y ) static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 ) { /// TODO: grid check here if( *x2 - *x1 < GRID_X * 2 ) *x2 = *x1 + GRID_X * 2; + if( *y2 - *y1 < GRID_Y * 2) *y2 = *y1 + GRID_Y * 2; + if( *x1 < 0 ) - *x2 -= *x1, *x1 = 0; + { + *x2 -= *x1; + *x1 = 0; + } + if( *y1 < 0 ) - *y2 -= *y1, *y1 = 0; + { + *y2 -= *y1; + *y1 = 0; + } + if( *y2 > 1 ) - *y1 -= *y2 - 1, *y2 = 1; + { + *y1 -= *y2 - 1; + *y2 = 1; + } + if( *x2 > 1 ) - *x1 -= *x2 - 1, *x2 = 1; + { + *x1 -= *x2 - 1; + *x2 = 1; + } + if( touch_grid_enable.value ) { *x1 = GRID_ROUND_X( *x1 ); @@ -1290,27 +1302,33 @@ static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 ) static float Touch_DrawCharacter( float x, float y, int number, float size ) { - float s1, s2, t1, t2, width, height; - int w, h; + float s1, s2, t1, t2, width, height; + int w, h; wrect_t *prc; + if( !cls.creditsFont.valid ) return 0; number &= 255; number = Con_UtfProcessChar( number ); + if( !number ) + return 0; + R_GetTextureParms( &w, &h, cls.creditsFont.hFontTexture ); prc = &cls.creditsFont.fontRc[number]; - s1 = ((float)prc->left) / (float)w; - t1 = ((float)prc->top) / (float)h; - s2 = ((float)prc->right) / (float)w; - t2 = ((float)prc->bottom) / (float)h; + s1 = prc->left / (float)w; + t1 = prc->top / (float)h; + s2 = prc->right / (float)w; + t2 = prc->bottom / (float)h; - width = ((float)( prc->right - prc->left )) / 1024.0f * size; - height = ((float)( prc->bottom - prc->top )) / 1024.0f * size; + width = ( prc->right - prc->left ) / 1024.0f * size; + height = ( prc->bottom - prc->top ) / 1024.0f * size; + + ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( x ), TO_SCRN_Y( y ), TO_SCRN_X( width ), TO_SCRN_X( height ), + s1, t1, s2, t2, cls.creditsFont.hFontTexture ); - ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X(x), TO_SCRN_Y(y), TO_SCRN_X(width), TO_SCRN_X(height), s1, t1, s2, t2, cls.creditsFont.hFontTexture ); return width; } @@ -1319,6 +1337,8 @@ static float Touch_DrawText( float x1, float y1, float x2, float y2, const char float x = x1; float maxy = y2; float maxx; + float alpha = color[3] / 255.0f; + if( x2 ) maxx = x2 - cls.creditsFont.charWidths['M'] / 1024.0f * size; else @@ -1326,17 +1346,16 @@ static float Touch_DrawText( float x1, float y1, float x2, float y2, const char if( !cls.creditsFont.valid ) return GRID_X * 2; - Con_UtfProcessChar( 0 ); + Con_UtfProcessChar( 0 ); ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); // text is additive and alpha does not work - ref.dllFuncs.Color4ub( color[0] * ( (float)color[3] /255.0f ), color[1] * ( (float)color[3] /255.0f ), - color[2] * ( (float)color[3] /255.0f ), 255 ); + ref.dllFuncs.Color4ub( color[0] * alpha, color[1] * alpha, color[2] * alpha, 255 ); while( *s ) { - while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ) ) + while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx )) x1 += Touch_DrawCharacter( x1, y1, *s++, size ); y1 += cls.creditsFont.charHeight / 1024.f * size / Touch_AspectRatio(); @@ -1347,92 +1366,114 @@ static float Touch_DrawText( float x1, float y1, float x2, float y2, const char s++; x1 = x; } - ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); return x1; } static void Touch_DrawButtons( touchbuttonlist_t *list ) { - touch_button_t *button; + touch_button_t *b; - for( button = list->first; button; button = button->next ) + for( b = list->first; b; b = b->next ) { - if( Touch_IsVisible( button ) ) + if( Touch_IsVisible( b )) { rgba_t color; - MakeRGBA( color, B( color[0] ), B( color[1] ), B( color[2] ), B( color[3] ) ); - if( B( fadespeed ) ) - { - button->fade += B( fadespeed ) * host.frametime; - button->fade = bound( 0, B(fade), 1 ); - if( ( B( fade ) == 0 ) || ( B(fade) == 1 ) ) - B( fadespeed ) = 0; - if( ( ( B( fade ) >= B( fadeend ) ) && ( B( fadespeed ) > 0 ) ) || - ( ( B( fade ) <= B( fadeend ) ) && ( B( fadespeed ) < 0 ) ) ) - B( fadespeed ) = 0, B( fade ) = B( fadeend ) ; - } + Vector4Copy( b->color, color ); - if( ( B( finger ) != -1 ) && !FBitSet( B( flags ), TOUCH_FL_CLIENT ) ) + if( b->fadespeed ) { - color[0] = bound( 0,(float) color[0] * touch_highlight_r.value, 255 ); - color[1] = bound( 0,(float) color[1] * touch_highlight_g.value, 255 ); - color[2] = bound( 0,(float) color[2] * touch_highlight_b.value, 255 ); - color[3] = bound( 0,(float) color[3] * touch_highlight_a.value, 255 ); - } + b->fade += b->fadespeed * host.frametime; + b->fade = bound( 0, b->fade, 1 ); + if( b->fade == 0 || b->fade == 1 ) + b->fadespeed = 0; - color[3] *= B( fade ); - if( button->texturefile[0] == '#' ) - Touch_DrawText( touch.swidth/SCR_W + B(x1), touch.swidth/SCR_H + B(y1), B(x2), B(y2), button->texturefile + 1, color, B( aspect )?B(aspect):1 ); - else if( button->texturefile[0] ) - { - if( button->texture == -1 ) + if(( b->fade >= b->fadeend && b->fadespeed > 0 ) || ( b->fade <= b->fadeend && b->fadespeed < 0 )) { - button->texture = ref.dllFuncs.GL_LoadTexture( button->texturefile, NULL, 0, TF_NOMIPMAP ); + b->fadespeed = 0; + b->fade = b->fadeend; } - - if( FBitSet( B(flags), TOUCH_FL_DRAW_ADDITIVE )) - ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); - - Touch_DrawTexture( B(x1), B(y1), B(x2), B(y2), B(texture), color[0], color[1], color[2], color[3] ); - - ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); } - if( FBitSet( B(flags), TOUCH_FL_STROKE )) + + if( b->finger != -1 && !FBitSet( b->flags, TOUCH_FL_CLIENT ) ) { - ref.dllFuncs.Color4ub( touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] * B( fade ) ); - ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X(B(x1)), - TO_SCRN_Y(B(y1)), - touch.swidth, - TO_SCRN_Y(B(y2)-B(y1)) - touch.swidth, - 0, 0, 1, 1, touch.whitetexture ); - ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X(B(x1)) + touch.swidth, - TO_SCRN_Y(B(y1)), - TO_SCRN_X(B(x2)-B(x1)) - touch.swidth, - touch.swidth, - 0, 0, 1, 1, touch.whitetexture ); - ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X(B(x2))-touch.swidth, - TO_SCRN_Y(B(y1)) + touch.swidth, - touch.swidth, - TO_SCRN_Y(B(y2)-B(y1)) - touch.swidth, - 0, 0, 1, 1, touch.whitetexture ); - ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X(B(x1)), - TO_SCRN_Y(B(y2))-touch.swidth, - TO_SCRN_X(B(x2)-B(x1)) - touch.swidth, - touch.swidth, - 0, 0, 1, 1, touch.whitetexture ); - ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); + color[0] = bound( 0, color[0] * touch_highlight_r.value, 255 ); + color[1] = bound( 0, color[1] * touch_highlight_g.value, 255 ); + color[2] = bound( 0, color[2] * touch_highlight_b.value, 255 ); + color[3] = bound( 0, color[3] * touch_highlight_a.value, 255 ); + } + + color[3] *= b->fade; + + if( b->texture[0] == '#' ) + { + Touch_DrawText( + touch.swidth / (float)refState.width + b->x1, + touch.swidth / (float)refState.height + b->y1, + b->x2, b->y2, b->texture + 1, color, b->aspect ? b->aspect : 1 ); + } + else if( b->texture[0] ) + { + if( b->gl_texturenum == -1 ) + b->gl_texturenum = ref.dllFuncs.GL_LoadTexture( b->texture, NULL, 0, TF_IMAGE ); + + if( FBitSet( b->flags, TOUCH_FL_DRAW_ADDITIVE )) + ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); + else + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); + + Touch_DrawTexture( b->x1, b->y1, b->x2, b->y2, b->gl_texturenum, color ); + } + + if( FBitSet( b->flags, TOUCH_FL_STROKE )) + { + rgba_t scolor; + const float x1_ = TO_SCRN_X( b->x1 ); + const float y1_ = TO_SCRN_Y( b->y1 ); + const float x2_ = TO_SCRN_X( b->x2 ); + const float y2_ = TO_SCRN_Y( b->y2 ); + const float swidth = touch.swidth; + + Vector4Copy( touch.scolor, scolor ); + scolor[3] *= b->fade; + + ref.dllFuncs.FillRGBA( kRenderTransTexture, + x1_, y1_, + swidth, y2_ - y1_ - swidth, + scolor[0], scolor[1], scolor[2], scolor[3] ); + + ref.dllFuncs.FillRGBA( kRenderTransTexture, + x2_ - swidth, y1_ + swidth, + swidth, y2_ - y1_ - swidth, + scolor[0], scolor[1], scolor[2], scolor[3] ); + + ref.dllFuncs.FillRGBA( kRenderTransTexture, + x1_ + swidth, y1_, + x2_ - x1_ - swidth, swidth, + scolor[0], scolor[1], scolor[2], scolor[3] ); + + ref.dllFuncs.FillRGBA( kRenderTransTexture, + x1_, y2_ - swidth, + x2_ - x1_ - swidth, swidth, + scolor[0], scolor[1], scolor[2], scolor[3] ); } } - if( touch.state >= state_edit && !( button->flags & TOUCH_FL_NOEDIT ) ) + + if( touch.state >= state_edit && !FBitSet( b->flags, TOUCH_FL_NOEDIT )) { rgba_t color; - if( !FBitSet( button->flags, TOUCH_FL_HIDE ) ) - Touch_DrawTexture( B(x1), B(y1), B(x2), B(y2), touch.whitetexture, 255, 255, 0, 32 ); + + if( !FBitSet( b->flags, TOUCH_FL_HIDE )) + MakeRGBA( color, 255, 255, 0, 32 ); else - Touch_DrawTexture( B(x1), B(y1), B(x2), B(y2), touch.whitetexture, 128, 128, 128, 128 ); - MakeRGBA( color, 255, 255,127, 255 ); - Con_DrawString( TO_SCRN_X( B(x1) ), TO_SCRN_Y( B(y1) ), B(name), color ); + MakeRGBA( color, 128, 128, 128, 128 ); + + ref.dllFuncs.FillRGBA( kRenderTransTexture, + TO_SCRN_X( b->x1 ), TO_SCRN_Y( b->y1 ), + TO_SCRN_X( b->x2 - b->x1 ), TO_SCRN_Y( b->y2 - b->y1 ), color[0], color[1], color[2], color[3] ); + + MakeRGBA( color, 255, 255, 127, 255 ); + Con_DrawString( TO_SCRN_X( b->x1 ), TO_SCRN_Y( b->y1 ), b->name, color ); } } @@ -1440,8 +1481,6 @@ static void Touch_DrawButtons( touchbuttonlist_t *list ) void Touch_Draw( void ) { - touch_button_t *button; - if( !touch.initialized || ( !touch_enable.value && !touch.clientonly )) return; @@ -1457,41 +1496,30 @@ void Touch_Draw( void ) float x; if( touch_in_menu.value ) - Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 32, 32, 32, 255 ); + ref.dllFuncs.FillRGBA( kRenderTransTexture, 0, 0, 1, 1, 32, 32, 32, 255 ); else - Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 0, 0, 0, 112 ); + ref.dllFuncs.FillRGBA( kRenderTransTexture, 0, 0, 1, 1, 0, 0, 0, 112 ); for( x = 0.0f; x < 1.0f; x += GRID_X ) - { ref.dllFuncs.FillRGBA( kRenderTransTexture, TO_SCRN_X( x ), 0, 1, TO_SCRN_Y( 1 ), 0, 224, 224, 112 ); - } for( x = 0.0f; x < 1.0f; x += GRID_Y ) - { ref.dllFuncs.FillRGBA( kRenderTransTexture, 0, TO_SCRN_Y( x ), TO_SCRN_X( 1 ), 1, 0, 224, 224, 112 ); - } } Touch_DrawButtons( &touch.list_user ); if( touch.state >= state_edit ) { - rgba_t color; - - MakeRGBA( color, 255, 255, 255, 255 ); - if( touch.edit ) { - float x1 = touch.edit->x1, - y1 = touch.edit->y1, - x2 = touch.edit->x2, - y2 = touch.edit->y2; + float x1 = touch.edit->x1, y1 = touch.edit->y1, x2 = touch.edit->x2, y2 = touch.edit->y2; IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); - Touch_DrawTexture( x1, y1, x2, y2, touch.whitetexture, 0, 255, 0, 32 ); + ref.dllFuncs.FillRGBA( kRenderTransTexture, TO_SCRN_X( x1 ), TO_SCRN_Y( y1 ), + TO_SCRN_X( x2 - x1 ), TO_SCRN_Y( y2 - y1 ), 0, 255, 0, 32 ); } - Touch_DrawTexture( 0, 0, GRID_X, GRID_Y, touch.whitetexture, 255, 255, 255, 64 ); - + ref.dllFuncs.FillRGBA( kRenderTransTexture, 0, 0, TO_SCRN_X( GRID_X ), TO_SCRN_Y( GRID_Y ), 255, 255, 255, 64 ); if( touch.showeditbuttons ) Touch_DrawButtons( &touch.list_edit ); @@ -1499,30 +1527,30 @@ void Touch_Draw( void ) /// TODO: move to mainui if( touch.selection ) { - button = touch.selection; - Touch_DrawTexture( B(x1), B(y1), B(x2), B(y2), touch.whitetexture, 255, 0, 0, 64 ); + char text[MAX_VA_STRING]; + rgba_t color = { 255, 255, 255, 255 }; + const touch_button_t *b = touch.selection; - Con_DrawString( 0, TO_SCRN_Y(GRID_Y * 11), "Selection:", color ); - Con_DrawString( Con_DrawString( 0, TO_SCRN_Y(GRID_Y*12), "Name: ", color ), - TO_SCRN_Y(GRID_Y*12), B(name), color ); - Con_DrawString( Con_DrawString( 0, TO_SCRN_Y(GRID_Y*13), "Texture: ", color ), - TO_SCRN_Y(GRID_Y*13), B(texturefile), color ); - Con_DrawString( Con_DrawString( 0, TO_SCRN_Y(GRID_Y*14), "Command: ", color ), - TO_SCRN_Y(GRID_Y*14), B(command), color ); + ref.dllFuncs.FillRGBA( kRenderTransTexture, TO_SCRN_X( b->x1 ), TO_SCRN_Y( b->y1 ), + TO_SCRN_X( b->x2 - b->x1 ), TO_SCRN_Y( b->y2 - b->y1 ), 255, 0, 0, 64 ); + + Q_snprintf( text, sizeof( text ), "Selection:\nName: %s\nTexture: %s\nCommand: %s", b->name, b->texture, b->command ); + + Con_DrawString( 0, TO_SCRN_Y( GRID_Y * 11 ), text, color ); } } - ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); - - if( ( touch.move_finger != -1 ) && touch.move_button && touch_move_indicator.value ) + if( touch.move_finger != -1 && touch.move_button && touch_move_indicator.value > 0.0f ) { - float width; - float height; + float width, height; + float size = touch_move_indicator.value; + if( FBitSet( touch_joy_texture.flags, FCVAR_CHANGED ) ) { ClearBits( touch_joy_texture.flags, FCVAR_CHANGED ); - touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_NOMIPMAP ); + touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_IMAGE ); } + if( touch.move_button->type == touch_move ) { width = touch_sidezone.value; @@ -1533,25 +1561,28 @@ void Touch_Draw( void ) width = (touch.move_button->x2 - touch.move_button->x1)/2; height = (touch.move_button->y2 - touch.move_button->y1)/2; } + + ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); ref.dllFuncs.Color4ub( 255, 255, 255, 128 ); - ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator.value ), - TO_SCRN_Y( touch.move_start_y - GRID_Y * touch_move_indicator.value ), - TO_SCRN_X( GRID_X * 2 * touch_move_indicator.value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator.value ), 0, 0, 1, 1, touch.joytexture ); + ref.dllFuncs.R_DrawStretchPic( + TO_SCRN_X( touch.move_start_x - GRID_X * size ), + TO_SCRN_Y( touch.move_start_y - GRID_Y * size ), + TO_SCRN_X( GRID_X * 2 * size ), + TO_SCRN_Y( GRID_Y * 2 * size ), + 0, 0, 1, 1, touch.joytexture ); ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); - ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * touch_move_indicator.value ), - TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * touch_move_indicator.value ), - TO_SCRN_X( GRID_X * 2 * touch_move_indicator.value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator.value ), 0, 0, 1, 1, touch.joytexture ); - + ref.dllFuncs.R_DrawStretchPic( + TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * size ), + TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * size ), + TO_SCRN_X( GRID_X * 2 * size ), + TO_SCRN_Y( GRID_Y * 2 * size ), + 0, 0, 1, 1, touch.joytexture ); } - } // clear move and selection state static void IN_TouchEditClear( void ) { - // allow keep move/look fingers when doing touch_removeall - //touch.move_finger = touch.look_finger = -1; - if( touch.state < state_edit ) return; @@ -1571,24 +1602,23 @@ static void Touch_EditMove( touchEventType type, int fingerID, float x, float y, { if( type == event_up ) // shutdown button move { - touch_button_t *button = touch.edit; - IN_TouchCheckCoords( &B(x1), &B(y1), &B(x2), &B(y2) ); + touch_button_t *b = touch.edit; + + IN_TouchCheckCoords( &b->x1, &b->y1, &b->x2, &b->y2 ); IN_TouchEditClear(); - if( button->type == touch_command ) - { - touch.selection = button; - // update "hide" editor button - touch.hidebutton->texture = -1; - touch.hidebutton->flags &= ~TOUCH_FL_HIDE; + touch.selection = b; - if( FBitSet( button->flags, TOUCH_FL_HIDE )) - Q_strncpy( touch.hidebutton->texturefile, "touch_default/edit_show", sizeof( touch.hidebutton->texturefile )); - else - Q_strncpy( touch.hidebutton->texturefile, "touch_default/edit_hide", sizeof( touch.hidebutton->texturefile )); - } + // update "hide" editor button + touch.hidebutton->gl_texturenum = -1; + ClearBits( touch.hidebutton->flags, TOUCH_FL_HIDE ); + + if( FBitSet( b->flags, TOUCH_FL_HIDE )) + Q_strncpy( touch.hidebutton->texture, "touch_default/edit_show", sizeof( touch.hidebutton->texture )); + else + Q_strncpy( touch.hidebutton->texture, "touch_default/edit_hide", sizeof( touch.hidebutton->texture )); } - if( type == event_motion ) // shutdown button move + else if( type == event_motion ) // shutdown button move { touch.edit->y1 += dy; touch.edit->y2 += dy; @@ -1601,18 +1631,14 @@ static void Touch_EditMove( touchEventType type, int fingerID, float x, float y, if( type == event_down ) // enable resizing { if( touch.resize_finger == -1 ) - { touch.resize_finger = fingerID; - } } - if( type == event_up ) // disable resizing + else if( type == event_up ) // disable resizing { if( touch.resize_finger == fingerID ) - { touch.resize_finger = -1; - } } - if( type == event_motion ) // perform resizing + else if( type == event_motion ) // perform resizing { if( touch.resize_finger == fingerID ) { @@ -1623,7 +1649,7 @@ static void Touch_EditMove( touchEventType type, int fingerID, float x, float y, } } -static void Touch_Motion( touchEventType type, int fingerID, float x, float y, float dx, float dy ) +static void Touch_Motion( int fingerID, float x, float y, float dx, float dy ) { // process wheel if( fingerID == touch.wheel_finger ) @@ -1636,41 +1662,52 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f touch.wheel_count++; touch.wheel_amount = 0; } + if( touch.wheel_amount < -0.1f ) { Cbuf_AddText( touch.wheel_up ); touch.wheel_count++; touch.wheel_amount = 0; } + return; } // walk if( fingerID == touch.move_finger ) { - // check bounds - if( touch_forwardzone.value <= 0 ) - Cvar_SetValue( "touch_forwardzone", 0.5 ); - if( touch_sidezone.value <= 0 ) - Cvar_SetValue( "touch_sidezone", 0.3 ); + const touch_button_t *b = touch.move_button; - if( !touch.move_button || touch.move_button->type == touch_move ) + if( !b || b->type == touch_move ) { + // check bounds + if( touch_forwardzone.value <= 0 ) + Cvar_DirectSet( &touch_forwardzone, "0.5" ); + + if( touch_sidezone.value <= 0 ) + Cvar_DirectSet( &touch_sidezone, "0.3" ); + // move relative to touch start touch.forward = ( touch.move_start_y - y ) / touch_forwardzone.value; touch.side = ( x - touch.move_start_x ) / touch_sidezone.value; } - else if( touch.move_button->type == touch_joy ) + else { // move relative to joy center - touch.forward = ( ( touch.move_button->y2 + touch.move_button->y1 ) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_joy_radius.value; - touch.side = ( x * 2 - ( touch.move_button->x2 + touch.move_button->x1 ) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_joy_radius.value; - } - else if( touch.move_button->type == touch_dpad ) - { - // like joy, but without acceleration. useful for bhop - touch.forward = round( ( (touch.move_button->y2 + touch.move_button->y1) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_dpad_radius.value ); - touch.side = round( ( x * 2 - (touch.move_button->x2 + touch.move_button->x1) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_dpad_radius.value ); + touch.forward = (( b->y2 + b->y1 ) - y * 2 ) / ( b->y2 - b->y1 ); + touch.side = ( x * 2 - ( b->x2 + b->x1 )) / ( b->x2 - b->x1 ); + + if( b->type == touch_joy ) + { + touch.forward *= touch_joy_radius.value; + touch.side *= touch_joy_radius.value; + } + else if( b->type == touch_dpad ) + { + // like joy, but without acceleration. useful for bhop + touch.forward = round( touch.forward * touch_dpad_radius.value ); + touch.side = round( touch.side * touch_dpad_radius.value ); + } } touch.forward = bound( -1, touch.forward, 1 ); @@ -1710,7 +1747,7 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f } // prevent breaking engine/client with bad values - if( IS_NAN( dx ) || IS_NAN( dy ) ) + if( IS_NAN( dx ) || IS_NAN( dy )) return; // accumulate @@ -1719,252 +1756,243 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f } } -static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type, int fingerID, float x, float y, float dx, float dy ) +static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type, int fingerID, float x, float y ) { touch_button_t *button; qboolean result = false; + if( type != event_down && type != event_up ) + return false; + // run from end(front) to start(back) for( button = list->last; button; button = button->prev ) { // skip invisible buttons - if( !Touch_IsVisible( button ) ) + if( !Touch_IsVisible( button )) continue; if( type == event_down ) { // button bounds check - if( ( x > button->x1 && - x < button->x2 ) && - ( y < button->y2 && - y > button->y1 ) ) + if( x < button->x1 || x > button->x2 || y < button->y1 || y > button->y2 ) + continue; + + button->finger = fingerID; + + if( button->type == touch_command ) { - button->finger = fingerID; + char command[256]; - if( button->type == touch_command ) + // command down: just execute command + Q_snprintf( command, sizeof( command ), "%s\n", button->command ); + if( FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED )) + Cbuf_AddFilteredText( command ); + else Cbuf_AddText( command ); + + // increase precision + if( FBitSet( button->flags, TOUCH_FL_PRECISION )) + touch.precision = true; + + result = true; + } + else if( button->type == touch_wheel ) + { + string command; + + touch.wheel_finger = fingerID; + touch.wheel_amount = touch.wheel_count = 0; + + Cmd_TokenizeString( button->command ); + + touch.wheel_horizontal = !Q_strcmp( Cmd_Argv( 0 ), "_hwheel" ); + Q_snprintf( touch.wheel_up, sizeof( touch.wheel_up ), "%s\n", Cmd_Argv( 1 )); + Q_snprintf( touch.wheel_down, sizeof( touch.wheel_down ), "%s\n", Cmd_Argv( 2 )); + Q_snprintf( touch.wheel_end, sizeof( touch.wheel_end ), "%s\n", Cmd_Argv( 3 )); + if( Q_snprintf( command, sizeof( command ), "%s\n", Cmd_Argv( 4 )) > 1 ) { - char command[256]; - - // command down: just execute command - Q_snprintf( command, sizeof( command ), "%s\n", button->command ); - if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED )) + if( FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED )) Cbuf_AddFilteredText( command ); else Cbuf_AddText( command ); - - // increase precision - if( FBitSet( B(flags), TOUCH_FL_PRECISION )) - touch.precision = true; - - result = true; + touch.wheel_count++; } - if( button->type == touch_wheel ) + // increase precision + if( FBitSet( button->flags, TOUCH_FL_PRECISION )) + touch.precision = true; + + result = true; + } + // initialize motion when player touched motion zone + else if( button->type == touch_move || button->type == touch_joy || button->type == touch_dpad ) + { + if( touch.move_finger !=-1 ) { - string command; - touch.wheel_finger = fingerID; - touch.wheel_amount = touch.wheel_count = 0; - - Cmd_TokenizeString( button->command ); - - touch.wheel_horizontal = !Q_strcmp( Cmd_Argv( 0 ), "_hwheel" ); - - Q_snprintf( touch.wheel_up, sizeof( touch.wheel_up ), "%s\n", Cmd_Argv( 1 ) ); - Q_snprintf( touch.wheel_down, sizeof( touch.wheel_down ), "%s\n", Cmd_Argv( 2 ) ); - Q_snprintf( touch.wheel_end, sizeof( touch.wheel_end ), "%s\n", Cmd_Argv( 3 ) ); - if( Q_snprintf( command, sizeof( command ), "%s\n", Cmd_Argv( 4 ) ) > 1) - { - if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED )) - Cbuf_AddFilteredText( command ); - else Cbuf_AddText( command ); - touch.wheel_count++; - } - - // increase precision - if( FBitSet( B(flags), TOUCH_FL_PRECISION )) - touch.precision = true; - - result = true; + // prevent initializing move while already moving + // revert finger switch, leave first finger + button->finger = touch.move_finger; + continue; } - // initialize motion when player touched motion zone - if( button->type == touch_move || button->type == touch_joy || button->type == touch_dpad ) + result = true; + + if( touch.look_finger == fingerID ) { - if( touch.move_finger !=-1 ) + touch_button_t *newbutton; + + // this is an error, try recover + touch.move_finger = touch.look_finger = -1; + + // player touched touch_move with enabled look mode + // and same finger id. release all move triggers + for( newbutton = list->first; newbutton; newbutton = newbutton->next ) { - // prevent initializing move while already moving - // revert finger switch, leave first finger - button->finger = touch.move_finger; - continue; + if( newbutton->type == touch_move || newbutton->type == touch_look ) + newbutton->finger = -1; } - result = true; - - if( touch.look_finger == fingerID ) - { - touch_button_t *newbutton; - - // this is an error, try recover - touch.move_finger = touch.look_finger = -1; - - // player touched touch_move with enabled look mode - // and same finger id. release all move triggers - for( newbutton = list->first; newbutton; newbutton = newbutton->next ) - if( ( newbutton->type == touch_move ) || ( newbutton->type == touch_look ) ) newbutton->finger = -1; - - Con_DPrintf( S_ERROR "Touch: touch_move on look finger %d!\n", fingerID ); - continue; - } - - // initialize move mode - touch.move_finger = fingerID; - touch.move_button = button; - - if( touch.move_button->type == touch_move ) - { - // initial position is first touch - touch.move_start_x = x; - touch.move_start_y = y; - } - else if( touch.move_button->type == touch_joy ) - { - // initial position is button center - touch.move_start_y = (touch.move_button->y2 + touch.move_button->y1) / 2; - touch.move_start_x = (touch.move_button->x2 + touch.move_button->x1) / 2; - - // start move instanly - touch.forward = ((touch.move_button->y2 + touch.move_button->y1) - y * 2) / (touch.move_button->y2 - touch.move_button->y1); - touch.side = (x * 2 - (touch.move_button->x2 + touch.move_button->x1)) / (touch.move_button->x2 - touch.move_button->x1); - } - else if( touch.move_button->type == touch_dpad ) - { - // dame as joy, but round - touch.move_start_y = (touch.move_button->y2 + touch.move_button->y1) / 2; - touch.move_start_x = (touch.move_button->x2 + touch.move_button->x1) / 2; - - // start move instanly - touch.forward = round(((touch.move_button->y2 + touch.move_button->y1) - y * 2) / (touch.move_button->y2 - touch.move_button->y1)); - touch.side = round((x * 2 - (touch.move_button->x2 + touch.move_button->x1)) / (touch.move_button->x2 - touch.move_button->x1)); - } + Con_DPrintf( S_ERROR "Touch: touch_move on look finger %d!\n", fingerID ); + continue; } - // initialize look - if( button->type == touch_look ) + // initialize move mode + touch.move_finger = fingerID; + touch.move_button = button; + + if( button->type == touch_move ) { - if( touch.look_finger !=-1 ) + // initial position is first touch + touch.move_start_x = x; + touch.move_start_y = y; + } + else + { + // initial position is button center + touch.move_start_y = ( button->y2 + button->y1 ) / 2; + touch.move_start_x = ( button->x2 + button->x1 ) / 2; + + // start move instanly + touch.forward = (( button->y2 + button->y1 ) - y * 2 ) / ( button->y2 - button->y1 ); + touch.side = (x * 2 - ( button->x2 + button->x1 )) / ( button->x2 - button->x1 ); + + // same as joy, but round + if( button->type == touch_dpad ) { - // prevent initializing look while already looking - // revert finger switch, leave first finger - button->finger = touch.look_finger; - continue; + touch.forward = round( touch.forward ); + touch.side = round( touch.side ); } - - result = true; - - if( touch.move_finger == fingerID ) - { - touch_button_t *newbutton; - - // this is an error, try recover - touch.move_finger = touch.look_finger = -1; - - // player touched touch_move with enabled look mode - // and same finger id. release all move triggers - for( newbutton = list->first; newbutton; newbutton = newbutton->next ) - if( ( newbutton->type == touch_move ) || ( newbutton->type == touch_look ) ) newbutton->finger = -1; - - Con_Printf( S_ERROR "touch: touch_look on move finger %d!\n", fingerID ); - continue; - } - - touch.look_finger = fingerID; } } - } + // initialize look + else if( button->type == touch_look ) + { + if( touch.look_finger !=-1 ) + { + // prevent initializing look while already looking + // revert finger switch, leave first finger + button->finger = touch.look_finger; + continue; + } - if( type == event_up ) + result = true; + + if( touch.move_finger == fingerID ) + { + touch_button_t *newbutton; + + // this is an error, try recover + touch.move_finger = touch.look_finger = -1; + + // player touched touch_move with enabled look mode + // and same finger id. release all move triggers + for( newbutton = list->first; newbutton; newbutton = newbutton->next ) + { + if( newbutton->type == touch_move || newbutton->type == touch_look ) + newbutton->finger = -1; + } + + Con_Printf( S_ERROR "touch: touch_look on move finger %d!\n", fingerID ); + continue; + } + + touch.look_finger = fingerID; + } + } + else if( type == event_up ) { // no bounds check here. // button released when finger released - if( fingerID == button->finger ) + if( fingerID != button->finger ) + continue; + + button->finger = -1; + + // handle +command, replace by -command + if( button->type == touch_command ) { - button->finger = -1; - - // handle +command, replace by -command - if( button->type == touch_command ) + if( button->command[0] == '+' ) { - if( button->command[0] == '+' ) - { - char command[256]; + char command[256]; - Q_snprintf( command, sizeof( command ), "%s\n", button->command ); - - command[0] = '-'; - - if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED )) - Cbuf_AddFilteredText( command ); - else Cbuf_AddText( command ); - } - - // disable precision mode - if( FBitSet( B(flags), TOUCH_FL_PRECISION )) - touch.precision = false; - - result = true; + Q_snprintf( command, sizeof( command ), "-%s\n", &button->command[1] ); + if( FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED )) + Cbuf_AddFilteredText( command ); + else Cbuf_AddText( command ); } - // handle wheel end - if( button->type == touch_wheel ) - { - if( touch.wheel_count ) - { - if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED )) - Cbuf_AddFilteredText( touch.wheel_end ); - else Cbuf_AddText( touch.wheel_end ); - } + // disable precision mode + if( FBitSet( button->flags, TOUCH_FL_PRECISION )) + touch.precision = false; - // disable precision mode - if( B(flags) & TOUCH_FL_PRECISION ) - touch.precision = false; - - touch.wheel_finger = -1; - - result = true; - } - - // release motion buttons - if( button->type == touch_move || button->type == touch_joy || button->type == touch_dpad ) - { - touch.move_finger = -1; - touch.forward = touch.side = 0; - touch.move_button = NULL; - } - - // release look buttons - if( button->type == touch_look ) - { - touch.look_finger = -1; - } + result = true; } + // handle wheel end + else if( button->type == touch_wheel ) + { + if( touch.wheel_count ) + { + if( FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED )) + Cbuf_AddFilteredText( touch.wheel_end ); + else Cbuf_AddText( touch.wheel_end ); + } + + // disable precision mode + if( FBitSet( button->flags, TOUCH_FL_PRECISION )) + touch.precision = false; + + touch.wheel_finger = -1; + + result = true; + } + // release motion buttons + else if( button->type == touch_move || button->type == touch_joy || button->type == touch_dpad ) + { + touch.move_finger = -1; + touch.forward = touch.side = 0; + touch.move_button = NULL; + } + // release look buttons + else if( button->type == touch_look ) + touch.look_finger = -1; } } return result; } -static qboolean Touch_ButtonEdit( touchEventType type, int fingerID, float x, float y, float dx, float dy ) +static qboolean Touch_ButtonEdit( touchEventType type, int fingerID, float x, float y ) { touch_button_t *button; // edit buttons are on y1 if( type == event_down ) { - if( (x < GRID_X) && (y < GRID_Y) ) + if( x < GRID_X && y < GRID_Y ) { - touch.showeditbuttons ^= true; + touch.showeditbuttons = !touch.showeditbuttons; return true; } - if( touch.showeditbuttons && Touch_ButtonPress( &touch.list_edit, type, fingerID, x, y, dx, dy ) ) + if( touch.showeditbuttons && Touch_ButtonPress( &touch.list_edit, type, fingerID, x, y )) return true; } @@ -1973,22 +2001,19 @@ static qboolean Touch_ButtonEdit( touchEventType type, int fingerID, float x, fl { if( type == event_down ) { - if( ( x > button->x1 && - x < button->x2 ) && - ( y < button->y2 && - y > button->y1 ) ) + if( x > button->x1 && x < button->x2 && y > button->y1 && y < button->y2 ) { button->finger = fingerID; // do not edit NOEDIT buttons if( FBitSet( button->flags, TOUCH_FL_NOEDIT )) - continue; + continue; touch.edit = button; touch.selection = NULL; // make button last to bring it up - if( ( button->next ) && ( button->type == touch_command ) ) + if( button->next && button->type == touch_command ) { if( button->prev ) button->prev->next = button->next; @@ -2005,9 +2030,12 @@ static qboolean Touch_ButtonEdit( touchEventType type, int fingerID, float x, fl return true; } } + if( type == event_up ) + { if( fingerID == button->finger ) button->finger = -1; + } } if( type == event_down ) @@ -2024,26 +2052,25 @@ static int Touch_ControlsEvent( touchEventType type, int fingerID, float x, floa if( touch.state == state_edit_move ) { Touch_EditMove( type, fingerID, x, y, dx, dy ); - return 1; + return true; } - if( touch.state == state_edit && Touch_ButtonEdit( type, fingerID, x, y, dx, dy ) ) + if( touch.state == state_edit && Touch_ButtonEdit( type, fingerID, x, y )) return true; - if( Touch_ButtonPress( &touch.list_user, type, fingerID, x, y, dx, dy ) ) + if( Touch_ButtonPress( &touch.list_user, type, fingerID, x, y )) return true; if( type == event_motion ) - Touch_Motion( type, fingerID, x, y, dx, dy ); + Touch_Motion( fingerID, x, y, dx, dy ); return true; } int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy ) { - y *= SCR_H/SCR_W/Touch_AspectRatio(); // Con_Printf("%f %f\n", TO_SCRN_X(x), TO_SCRN_Y(y)); // simulate menu mouse click if( cls.key_dest != key_game && !touch_in_menu.value ) { - touch.move_finger = touch.resize_finger = touch.look_finger = -1; + touch.move_finger = touch.resize_finger = touch.look_finger = touch.wheel_finger = -1; // Hack for keyboard, hope it help // a1ba: this is absolutely horrible if( cls.key_dest == key_console || cls.key_dest == key_message ) @@ -2063,6 +2090,7 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx y1 += dy; if( dy > 0.4f ) Con_Bottom(); + if( y1 > 0.01f ) { Con_PageUp( 1 ); @@ -2077,28 +2105,41 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx // exit of console area if( type == event_down && x < 0.1f && y > 0.9f ) - Cbuf_AddText( "escape\n" ); + { + if( cls.key_dest == key_console ) + Key_Console( K_ESCAPE ); + else + Key_Message( K_ESCAPE ); + return 0; + } // swipe from edge to exit console/chat - if(( x > 0.8f && x1 < -0.1f ) || ( x < 0.2f && x1 > 0.1f )) + if(( x > 0.7f && x1 < -0.1f ) || ( x < 0.3f && x1 > 0.1f )) { - Cbuf_AddText( "escape\n" ); + if( cls.key_dest == key_console ) + Key_Console( K_ESCAPE ); + else + Key_Message( K_ESCAPE ); x1 = 0.0f; + return 0; } } - UI_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) ); + UI_MouseMove( x * refState.width, y * refState.height ); + //MsgDev( D_NOTE, "touch %d %d\n", TO_SCRN_X(x), TO_SCRN_Y(y) ); if( type == event_down ) Key_Event( K_MOUSE1, true ); + if( type == event_up ) Key_Event( K_MOUSE1, false ); + return 0; } if( VGui_IsActive() ) { - VGui_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) ); + VGui_MouseMove( x * refState.width, y * refState.height ); switch( type ) { @@ -2108,12 +2149,15 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx case event_up: VGui_MouseEvent( K_MOUSE1, 0 ); break; - default: break; + default: + break; } } if( !touch.initialized || ( !touch_enable.value && !touch.clientonly )) - return 0; + return false; + + y *= (float)refState.height / refState.width / Touch_AspectRatio(); if( clgame.dllFuncs.pfnTouchEvent && clgame.dllFuncs.pfnTouchEvent( type, fingerID, x, y, dx, dy ) ) return true; @@ -2176,8 +2220,8 @@ void Touch_KeyEvent( int key, int down ) Platform_SetCursorType( dc_arrow ); Platform_GetMousePos( &xi, &yi ); - x = xi / SCR_W; - y = yi / SCR_H; + x = xi / (float)refState.width; + y = yi / (float)refState.height; // Con_DPrintf( "event %d %.2f %.2f %.2f %.2f\n", event, x, y, x - lx, y - ly );