diff --git a/engine/client/in_touch.c b/engine/client/in_touch.c index ce398f1c..812d6471 100644 --- a/engine/client/in_touch.c +++ b/engine/client/in_touch.c @@ -25,8 +25,8 @@ typedef enum touch_move, // like a joystick stick touch_joy, // like a joystick stick, centered touch_dpad, // only two directions - touch_look, // like a touchpad - touch_wheel // scroll-like + touch_look, // like a touchpad + touch_wheel // scroll-like } touchButtonType; typedef enum @@ -43,8 +43,6 @@ typedef enum round_aspect } touchRound; - - typedef struct touch_button_s { // Touch button type: tap, stick or slider @@ -69,7 +67,6 @@ typedef struct touch_button_s // Double-linked list struct touch_button_s *next; struct touch_button_s *prev; - } touch_button_t; typedef struct touchdefaultbutton_s @@ -171,33 +168,76 @@ convar_t *touch_emulate; #define TO_SCRN_Y(x) (refState.height * (x)) #define TO_SCRN_X(x) (refState.width * (x)) -int pfnDrawCharacter( int x, int y, int number, int r, int g, int b ); static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 ); static void IN_TouchEditClear( void ); static void Touch_InitConfig( 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 ) +{ + string newCommand; + int flags = button->flags; + + if( FBitSet( flags, TOUCH_FL_CLIENT )) + return 1; // skip temporary buttons + + if( FBitSet( flags, TOUCH_FL_DEF_SHOW )) + ClearBits( flags, TOUCH_FL_HIDE ); + + if( FBitSet( flags, TOUCH_FL_DEF_HIDE )) + SetBits( flags, TOUCH_FL_HIDE ); + + 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 ); + + if( keepAspect ) + { + float aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) ); + FS_Printf( f, " %f\n", aspect ); + } + else FS_Printf( f, "\n" ); + + return 0; +} + +/* +================= +Touch_WriteConfig + +save current touch configuration +================= +*/ void Touch_WriteConfig( void ) { file_t *f; - char newconfigfile[64]; - char oldconfigfile[64]; + string newconfigfile, oldconfigfile; - if( !touch.list_user.first ) return; + if( !touch.list_user.first ) + return; if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged || !touch.config_loaded ) return; Con_DPrintf( "Touch_WriteConfig(): %s\n", touch_config_file->string ); - Q_snprintf( newconfigfile, 64, "%s.new", touch_config_file->string ); - Q_snprintf( oldconfigfile, 64, "%s.bak", touch_config_file->string ); + Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file->string ); + Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file->string ); f = FS_Open( newconfigfile, "w", true ); if( f ) { touch_button_t *button; FS_Printf( f, "//=======================================================================\n"); - FS_Printf( f, "//\tCopyright SDLash3D team & XashXT group %s ©\n", Q_timestamp( TIME_YEAR_ONLY )); + FS_Printf( f, "//\tCopyright FWGS & XashXT group %s (c)\n", Q_timestamp( TIME_YEAR_ONLY )); FS_Printf( f, "//\t\t\ttouchscreen config\n" ); FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "\ntouch_config_file \"%s\"\n", touch_config_file->string ); @@ -210,7 +250,8 @@ void Touch_WriteConfig( void ) FS_Printf( f, "touch_nonlinear_look \"%d\"\n", CVAR_TO_BOOL(touch_nonlinear_look)); 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, "\n// grid settings\n" ); + FS_Printf( f, "touch_exp_mult \"%f\"\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", CVAR_TO_BOOL(touch_grid_enable)); FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" ); @@ -235,27 +276,7 @@ void Touch_WriteConfig( void ) for( button = touch.list_user.first; button; button = button->next ) { - string newCommand; - int flags = button->flags; - - if( flags & TOUCH_FL_CLIENT ) - continue; //skip temporary buttons - - if( flags & TOUCH_FL_DEF_SHOW ) - flags &= ~TOUCH_FL_HIDE; - - if( flags & TOUCH_FL_DEF_HIDE ) - flags |= TOUCH_FL_HIDE; - - /// TODO: EscapeCommand - //Com_EscapeCommand( newCommand, B(command), MAX_STRING ); - Q_strncpy( newCommand, B(command), MAX_STRING ); - - - FS_Printf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %f %f %f %f %d %d %d %d %d\n", - 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 ); + Touch_ExportButtonToConfig( f, button, false ); } FS_Close( f ); @@ -268,14 +289,21 @@ void Touch_WriteConfig( void ) else Con_Printf( S_ERROR "Couldn't write %s.\n", touch_config_file->string ); } -void Touch_ExportConfig_f( void ) +/* +================= +Touch_ExportConfig_f + +export current touch configuration into profile +================= +*/ +static void Touch_ExportConfig_f( void ) { file_t *f; const char *name; if( Cmd_Argc() != 2 ) { - Con_Printf( "Usage: touch_exportconfig \n" ); + Con_Printf( S_USAGE "touch_exportconfig \n" ); return; } @@ -287,17 +315,17 @@ void Touch_ExportConfig_f( void ) f = FS_Open( name, "w", true ); if( f ) { - char profilename[256]; - char profilebase[256]; + string profilename, profilebase; touch_button_t *button; + if( Q_strstr( name, "touch_presets/" ) ) { COM_FileBase( name, profilebase ); - Q_snprintf( profilename, 256, "touch_profiles/%s (copy).cfg", profilebase ); + Q_snprintf( profilename, sizeof( profilebase ), "touch_profiles/%s (copy).cfg", profilebase ); } - else Q_strncpy( profilename, name, 256 ); + else Q_strncpy( profilename, name, sizeof( profilename )); FS_Printf( f, "//=======================================================================\n"); - FS_Printf( f, "//\tCopyright SDLash3D team & XashXT group %s ©\n", Q_timestamp( TIME_YEAR_ONLY )); + FS_Printf( f, "//\tCopyright FWGS & XashXT group %s (c)\n", Q_timestamp( TIME_YEAR_ONLY )); FS_Printf( f, "//\t\t\ttouchscreen preset\n" ); FS_Printf( f, "//=======================================================================\n" ); FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename ); @@ -335,26 +363,7 @@ void Touch_ExportConfig_f( void ) FS_Printf( f, "touch_removeall\n" ); for( button = touch.list_user.first; button; button = button->next ) { - string newCommand; - float aspect; - int flags = button->flags; - if( flags & TOUCH_FL_CLIENT ) - continue; //skip temporary buttons - if( flags & TOUCH_FL_DEF_SHOW ) - flags &= ~TOUCH_FL_HIDE; - if( flags & TOUCH_FL_DEF_HIDE ) - flags |= TOUCH_FL_HIDE; - - aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) ); - - /// TODO: EscapeCommand - //Com_EscapeCommand( newCommand, B(command), MAX_STRING ); - Q_strncpy( newCommand, B(command), MAX_STRING ); - - FS_Printf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %f %f %f %f %d %d %d %d %d %f\n", - 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, aspect ); + Touch_ExportButtonToConfig( f, button, true ); } FS_Printf( f, "\n// round button coordinates to grid\n" ); FS_Printf( f, "touch_roundall\n" ); @@ -363,29 +372,33 @@ void Touch_ExportConfig_f( void ) else Con_Printf( S_ERROR "Couldn't write %s.\n", name ); } -void Touch_GenetateCode_f( void ) +/* +================= +Touch_GenerateCode_f + +export current touch configuration into C code +================= +*/ +static void Touch_GenerateCode_f( void ) { touch_button_t *button; rgba_t c = {0,0,0,0}; - if( Cmd_Argc() != 1 ) - { - Con_Printf( "Usage: touch_generate_code\n" ); - return; - } - if( !touch.list_user.first ) return; for( button = touch.list_user.first; button; button = button->next ) { float aspect; int flags = button->flags; - if( flags & TOUCH_FL_CLIENT ) - continue; //skip temporary buttons - if( flags & TOUCH_FL_DEF_SHOW ) - flags &= ~TOUCH_FL_HIDE; - if( flags & TOUCH_FL_DEF_HIDE ) - flags |= TOUCH_FL_HIDE; + + if( FBitSet( flags, TOUCH_FL_CLIENT )) + continue; // skip temporary buttons + + if( FBitSet( flags, TOUCH_FL_DEF_SHOW )) + ClearBits( flags, TOUCH_FL_HIDE ); + + if( FBitSet( flags, TOUCH_FL_DEF_HIDE )) + SetBits( flags, TOUCH_FL_HIDE ); aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) ); if( memcmp( &c, &B(color), sizeof( rgba_t ) ) ) @@ -399,16 +412,18 @@ void Touch_GenetateCode_f( void ) } } -void Touch_RoundAll_f( void ) +static void Touch_RoundAll_f( void ) { touch_button_t *button; + if( !touch_grid_enable->value ) return; + for( button = touch.list_user.first; button; button = button->next ) IN_TouchCheckCoords( &B(x1), &B(y1), &B(x2), &B(y2) ); } -void Touch_ListButtons_f( void ) +static void Touch_ListButtons_f( void ) { touch_button_t *button; Touch_InitConfig(); @@ -419,35 +434,44 @@ void Touch_ListButtons_f( void ) 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) ); + if( B(flags) & TOUCH_FL_CLIENT) continue; + UI_AddTouchButtonToList( B(name), B(texturefile), B(command),B(color), B(flags) ); } touch.configchanged = true; } -void Touch_Stroke_f( void ) +static void Touch_Stroke_f( void ) { + if( Cmd_Argc() != 6 ) + { + Con_Printf( S_USAGE "touch_set_stroke \n"); + return; + } + touch.swidth = Q_atoi( Cmd_Argv( 1 ) ); MakeRGBA( touch.scolor, Q_atoi( Cmd_Argv( 2 ) ), Q_atoi( Cmd_Argv( 3 ) ), Q_atoi( Cmd_Argv( 4 ) ), Q_atoi( Cmd_Argv( 5 ) ) ); } -touch_button_t *Touch_FindButton( touchbuttonlist_t *list, const char *name ) +static touch_button_t *Touch_FindButton( touchbuttonlist_t *list, const char *name ) { touch_button_t *button; - for ( button = list->first; button; button = button->next ) - if( !Q_strncmp( button->name, name, 32 ) ) + for( button = list->first; button; button = button->next ) + if( !Q_strncmp( button->name, name, sizeof( button->name ))) return button; + return NULL; } -touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *name ) +static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *name ) { touch_button_t *button; - for ( button = list->first; button; button = button->next ) - if( ( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name ) ) || !Q_strncmp( name, button->name, 32 ) ) + 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 ))) return button; return NULL; } @@ -476,27 +500,35 @@ void Touch_SetClientOnly( qboolean state ) #endif } -void Touch_SetClientOnly_f( void ) +static void Touch_SetClientOnly_f( void ) { - Touch_SetClientOnly( Q_atoi( Cmd_Argv( 1 ) ) ); + if( Cmd_Argc() != 2 ) + { + Con_Printf( S_USAGE "touch_setclientonly \n"); + return; + } + + Touch_SetClientOnly( Q_atoi( Cmd_Argv( 1 ))); } -void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *name ) +static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *name ) { touch_button_t *button; IN_TouchEditClear(); - while( ( button = Touch_FindFirst( &touch.list_user, name ) ) ) + while(( button = Touch_FindFirst( &touch.list_user, name ))) { if( button->prev ) button->prev->next = button->next; else list->first = button->next; + if( button->next ) button->next->prev = button->prev; else list->last = button->prev; + Mem_Free( button ); } @@ -507,60 +539,69 @@ void Touch_RemoveButton( const char *name ) Touch_RemoveButtonFromList( &touch.list_user, name ); } -void IN_TouchRemoveButton_f( void ) +static void IN_TouchRemoveButton_f( void ) { - Touch_RemoveButton( Cmd_Argv( 1 ) ); + if( Cmd_Argc() != 2 ) + { + Con_Printf( S_USAGE "touch_removebutton