From: hgn Date: Sun, 31 Dec 2023 11:22:13 +0000 (+0000) Subject: add strings to console variables X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=commitdiff_plain;h=5cc37bf42297227603b045317af94952fff07bf3 add strings to console variables --- diff --git a/vg.h b/vg.h index 82f95fc..c4f55c3 100644 --- a/vg.h +++ b/vg.h @@ -885,6 +885,7 @@ static void vg_enter( int argc, char *argv[], const char *window_name ){ k_var_dtype_i32, VG_VAR_PERSISTENT ); vg_console_reg_var( "vg_screen_mode", &vg.screen_mode, k_var_dtype_i32, VG_VAR_PERSISTENT ); + vg_audio_register(); vg_console_load_autos(); vg_console_reg_cmd( "vg_settings", cmd_vg_settings_toggle, NULL ); diff --git a/vg_audio.h b/vg_audio.h index 2bba7ea..5df5638 100644 --- a/vg_audio.h +++ b/vg_audio.h @@ -96,7 +96,7 @@ struct audio_clip{ struct vg_audio_system{ SDL_AudioDeviceID sdl_output_device; - char *force_device_name; /* NULL: using default */ + vg_str device_choice; /* buffer is null? use default from OS */ void *audio_pool, *decode_buffer; @@ -276,13 +276,13 @@ static void vg_audio_device_init(void){ spec_desired.userdata = NULL; vg_audio.sdl_output_device = - SDL_OpenAudioDevice( vg_audio.force_device_name, 0, + SDL_OpenAudioDevice( vg_audio.device_choice.buffer, 0, &spec_desired, &spec_got,0 ); vg_info( "Start audio device (%u, F32, %u) @%s\n", spec_desired.freq, AUDIO_FRAME_SIZE, - vg_audio.force_device_name ); + vg_audio.device_choice.buffer ); if( vg_audio.sdl_output_device ){ SDL_PauseAudioDevice( vg_audio.sdl_output_device, 0 ); @@ -298,15 +298,18 @@ static void vg_audio_device_init(void){ } } - -static void vg_audio_init(void){ +static void vg_audio_register(void){ vg_console_reg_var( "debug_audio", &vg_audio.debug_ui, k_var_dtype_i32, VG_VAR_CHEAT ); vg_console_reg_var( "debug_dsp", &vg_audio.debug_dsp, k_var_dtype_i32, VG_VAR_CHEAT ); vg_console_reg_var( "volume", &vg_audio.external_global_volume, k_var_dtype_f32, VG_VAR_PERSISTENT ); + vg_console_reg_var( "vg_audio_device", &vg_audio.device_choice, + k_var_dtype_str, VG_VAR_PERSISTENT ); +} +static void vg_audio_init(void){ /* allocate memory */ /* 32mb fixed */ vg_audio.audio_pool = diff --git a/vg_console.h b/vg_console.h index 42f79e4..029b3e6 100644 --- a/vg_console.h +++ b/vg_console.h @@ -1,5 +1,7 @@ /* Copyright (C) 2021-2023 Harry Godden (hgn) - All Rights Reserved */ +/* TODO: String types using dynamic, vg_str! */ + #ifndef VG_CONSOLE_H #define VG_CONSOLE_H @@ -7,8 +9,9 @@ #define VG_GAME #endif -#include "vg/vg_imgui.h" -#include "vg/vg_log.h" +#include "vg_imgui.h" +#include "vg_log.h" +#include "vg_string.h" #define VG_VAR_F32( NAME, ... ) \ { u32 flags=0x00; __VA_ARGS__ ;\ @@ -20,7 +23,6 @@ #define VG_VAR_PERSISTENT 0x1 #define VG_VAR_CHEAT 0x2 -#define VG_VAR_CHEATTOGGLE 0x4 typedef struct vg_var vg_var; typedef struct vg_cmd vg_cmd; @@ -33,12 +35,11 @@ struct vg_console{ enum vg_var_dtype{ k_var_dtype_i32, k_var_dtype_u32, - k_var_dtype_f32 + k_var_dtype_f32, + k_var_dtype_str } data_type; u32 flags; - - union{ u32 _u32; f32 _f32; i32 _i32; } defaults; } vars[ 128 ]; @@ -108,10 +109,6 @@ void vg_console_reg_var( const char *alias, void *ptr, enum vg_var_dtype type, var->data_type = type; var->flags = flags; - if ( type == k_var_dtype_f32 ) var->defaults._f32 = *((f32 *)ptr); - else if( type == k_var_dtype_i32 ) var->defaults._i32 = *((i32 *)ptr); - else if( type == k_var_dtype_u32 ) var->defaults._u32 = *((u32 *)ptr); - vg_info( "Console variable '%s' registered\n", alias ); } @@ -140,7 +137,9 @@ static int _vg_console_list( int argc, char const *argv[] ){ for( int i=0; iname ); + vg_info( "%s %s\n", + (const char *[]){ "i32","u32","f32","str" }[cv->data_type], + cv->name ); } return 0; @@ -182,26 +181,10 @@ int _vg_console_exec( int argc, const char *argv[] ){ return 0; } -int _ccmd_vg_console_defaults( int argc, const char *argv[] ){ - for( int i=0; idata_type; - void *ptr = cv->data; - - if ( type == k_var_dtype_f32 ) *((f32 *)ptr) = cv->defaults._f32; - else if( type == k_var_dtype_i32 ) *((i32 *)ptr) = cv->defaults._i32; - else if( type == k_var_dtype_u32 ) *((u32 *)ptr) = cv->defaults._u32; - } - - return 0; -} - static void _vg_console_init(void){ vg_console_reg_cmd( "list", _vg_console_list, NULL ); vg_console_reg_cmd( "crash", _test_break, NULL ); vg_console_reg_cmd( "exec", _vg_console_exec, NULL ); - vg_console_reg_cmd( "defaults", _ccmd_vg_console_defaults, NULL ); vg_console_reg_var( "cheats", &vg_console.cheats, k_var_dtype_i32, #ifdef VG_DEVWINDOW VG_VAR_PERSISTENT @@ -227,17 +210,20 @@ static void _vg_console_write_persistent(void){ struct vg_var *cv = &vg_console.vars[i]; if( cv->flags & VG_VAR_PERSISTENT ){ - switch( cv->data_type ){ - case k_var_dtype_i32: - fprintf( fp, "%s %d\n", cv->name, *(i32 *)(cv->data) ); - break; - case k_var_dtype_u32: - fprintf( fp, "%s %u\n", cv->name, *(u32 *)(cv->data) ); - break; - case k_var_dtype_f32: - fprintf( fp, "%s %.5f\n", cv->name, *(float *)(cv->data ) ); - break; - } + if( cv->data_type == k_var_dtype_i32 ){ + fprintf( fp, "%s %d\n", cv->name, *(i32 *)(cv->data) ); + } + else if( cv->data_type == k_var_dtype_u32 ){ + fprintf( fp, "%s %u\n", cv->name, *(u32 *)(cv->data) ); + } + else if( cv->data_type == k_var_dtype_f32 ){ + fprintf( fp, "%s %.5f\n", cv->name, *(float *)(cv->data ) ); + } + else if( cv->data_type == k_var_dtype_str ){ + vg_str *str = cv->data; + if( str->buffer && (str->i > 0) ) + fprintf( fp, "%s %s\n", cv->name, str->buffer ); + } } } @@ -313,8 +299,7 @@ static vg_cmd *vg_console_match_cmd( const char *kw ) return NULL; } -static void vg_execute_console_input( const char *cmd, bool silent ) -{ +static void vg_execute_console_input( const char *cmd, bool silent ){ char temp[512]; char const *args[8]; int arg_count = vg_console_tokenize( cmd, temp, args ); @@ -338,21 +323,24 @@ static void vg_execute_console_input( const char *cmd, bool silent ) } if( (cv->data_type == k_var_dtype_u32) || - (cv->data_type == k_var_dtype_i32) ) - { + (cv->data_type == k_var_dtype_i32) ){ int *ptr = cv->data; *ptr = atoi( args[1] ); - - if( cv->flags & VG_VAR_CHEATTOGGLE ){ - if( *ptr ){ - _ccmd_vg_console_defaults( 0, NULL ); - } - } } else if( cv->data_type == k_var_dtype_f32 ){ float *ptr = cv->data; *ptr = atof( args[1] ); } + else if( cv->data_type == k_var_dtype_str ){ + vg_str *str = cv->data; + vg_strfree( str ); + vg_strnull( str, NULL, -1 ); + + for( int i=1; idata_type == k_var_dtype_i32 ) @@ -361,6 +349,10 @@ static void vg_execute_console_input( const char *cmd, bool silent ) vg_info( "= %u\n", *((u32 *)cv->data) ); else if( cv->data_type == k_var_dtype_f32 ) vg_info( "= %.4f\n", *((float *)cv->data) ); + else if( cv->data_type == k_var_dtype_str ){ + vg_str *str = cv->data; + vg_info( "= '%s'\n", str->buffer ); + } } return; diff --git a/vg_platform.h b/vg_platform.h index 9366095..e8b288e 100644 --- a/vg_platform.h +++ b/vg_platform.h @@ -46,6 +46,8 @@ struct vg_achievement #include #include +#include "vg_string.h" + enum strncpy_behaviour{ k_strncpy_always_add_null = 0, k_strncpy_allow_cutoff = 1, @@ -75,181 +77,6 @@ static u32 vg_strncpy( const char *src, char *dst, u32 len, return 0; } -typedef struct vg_str vg_str; -typedef struct vg_str_dynamic vg_str_dynamic; - -struct vg_str{ - char *buffer; - i32 i, /* -1: error condition. otherwise, current cursor position */ - len; /* -1: dynamically allocated. otherwise, buffer length */ -}; - -struct vg_str_dynamic { - i32 len; -}; - -/* - * Returns the current storage size of the string - */ -static i32 vg_str_storage( vg_str *str ){ - if( str->len == -1 ){ - if( str->buffer ){ - vg_str_dynamic *arr = (vg_str_dynamic *)str->buffer; - return (arr-1)->len; - } - else return 0; - } - else return str->len; -} - -/* - * Reset string. If len is -1 (dynamically allocated), buffer must be either - * NULL or be acquired from malloc or realloc - */ -static void vg_strnull( vg_str *str, char *buffer, i32 len ){ - str->buffer = buffer; - if( buffer ) - str->buffer[0] = '\0'; - - str->i = 0; - str->len = len; - - assert(len); -} - -static void vg_strfree( vg_str *str ){ - if( str->len == -1 ){ - if( str->buffer ){ - vg_str_dynamic *arr = (vg_str_dynamic *)str->buffer; - free( arr-1 ); - - str->buffer = NULL; - str->i = 0; - } - } -} - -/* - * Double the size of the dynamically allocated string. If unallocated, alloc of - * 16 bytes minimum. - */ -static i32 vg_str_dynamic_grow( vg_str *str ){ - if( str->buffer ){ - vg_str_dynamic *hdr = ((vg_str_dynamic *)str->buffer) - 1; - i32 total = (hdr->len + sizeof(vg_str_dynamic)) * 2; - hdr = realloc( hdr, total ); - hdr->len = total - sizeof(vg_str_dynamic); - str->buffer = (char *)(hdr+1); - return hdr->len; - } - else { - vg_str_dynamic *hdr = malloc(16); - hdr->len = 16-sizeof(vg_str_dynamic); - str->buffer = (char *)(hdr+1); - str->buffer[0] = '\0'; - return hdr->len; - } -} - -/* - * Append null terminated string to vg_str - */ -static void vg_strcat( vg_str *str, const char *append ){ - if( !append || (str->i == -1) ) return; - - i32 max = vg_str_storage( str ), - i = 0; - -append: - if( str->i == max ){ - if( str->len == -1 ) - max = vg_str_dynamic_grow( str ); - else{ - str->i = -1; - str->buffer[ max-1 ] = '\0'; - return; - } - } - - char c = append[ i ++ ]; - str->buffer[ str->i ] = c; - - if( c == '\0' ) - return; - - str->i ++; - goto append; -} - -/* - * Append character to vg_str - */ -static void vg_strcatch( vg_str *str, char c ){ - vg_strcat( str, (char[]){ c, '\0' } ); -} - -/* - * FIXME: Negative numbers - */ -static void vg_strcati32( vg_str *str, i32 value ){ - if( value ){ - char temp[32]; - int i=0; - while( value && (i<31) ){ - temp[ i ++ ] = '0' + (value % 10); - value /= 10; - } - - char reverse[32]; - for( int j=0; j=n ) - break; - - temp[ n-1 - (i ++) ] = '0' + (value % 10); - value /= 10; - } - - for( ;ii == -1 ) return 0; - else return 1; -} - -/* - * Returns pointer to last instance of character - */ -static char *vg_strch( vg_str *str, char c ){ - char *ptr = NULL; - for( i32 i=0; ii; i++ ){ - if( str->buffer[i] == c ) - ptr = str->buffer+i; - } - - return ptr; -} - static u32 vg_strdjb2( const char *str ){ u32 hash = 5381, c; diff --git a/vg_settings_menu.h b/vg_settings_menu.h index 68b2171..fb6a116 100644 --- a/vg_settings_menu.h +++ b/vg_settings_menu.h @@ -261,10 +261,7 @@ static void vg_settings_audio_apply(void){ SDL_CloseAudioDevice( vg_audio.sdl_output_device ); } - if( vg_audio.force_device_name ){ - free( vg_audio.force_device_name ); - vg_audio.force_device_name = NULL; - } + vg_strfree( &vg_audio.device_choice ); if( vg_settings.audio_devices.new_value == -1 ){ } else if( vg_settings.audio_devices.new_value == -2 ){ @@ -282,9 +279,8 @@ static void vg_settings_audio_apply(void){ } } - int len = strlen(oi->alias); - vg_audio.force_device_name = malloc(len+1); - memcpy( vg_audio.force_device_name, (void *)oi->alias, len+1 ); + vg_strnull( &vg_audio.device_choice, NULL, -1 ); + vg_strcat( &vg_audio.device_choice, oi->alias ); } vg_audio_device_init(); @@ -339,12 +335,12 @@ static void vg_settings_open(void){ oi->value = i; } - if( vg_audio.force_device_name ){ + if( vg_audio.device_choice.buffer ){ vg_settings.temp_audio_choice = -2; for( int i=0; ialias, vg_audio.force_device_name ) ){ + if( !strcmp( oi->alias, vg_audio.device_choice.buffer ) ){ vg_settings.temp_audio_choice = oi->value; break; } diff --git a/vg_string.h b/vg_string.h new file mode 100644 index 0000000..c99fc7a --- /dev/null +++ b/vg_string.h @@ -0,0 +1,183 @@ +#ifndef VG_STRING_H +#define VG_STRING_H + +/* string builder with optional dynamic memory or static buffer. */ + +#include "vg_stdint.h" + +typedef struct vg_str vg_str; +typedef struct vg_str_dynamic vg_str_dynamic; + +struct vg_str{ + char *buffer; + i32 i, /* -1: error condition. otherwise, current cursor position */ + len; /* -1: dynamically allocated. otherwise, buffer length */ +}; + +struct vg_str_dynamic { + i32 len; +}; + +/* + * Returns the current storage size of the string + */ +static i32 vg_str_storage( vg_str *str ){ + if( str->len == -1 ){ + if( str->buffer ){ + vg_str_dynamic *arr = (vg_str_dynamic *)str->buffer; + return (arr-1)->len; + } + else return 0; + } + else return str->len; +} + +/* + * Reset string. If len is -1 (dynamically allocated), buffer must be either + * NULL or be acquired from malloc or realloc + */ +static void vg_strnull( vg_str *str, char *buffer, i32 len ){ + str->buffer = buffer; + if( buffer ) + str->buffer[0] = '\0'; + + str->i = 0; + str->len = len; + + assert(len); +} + +static void vg_strfree( vg_str *str ){ + if( str->len == -1 ){ + if( str->buffer ){ + vg_str_dynamic *arr = (vg_str_dynamic *)str->buffer; + free( arr-1 ); + + str->buffer = NULL; + str->i = 0; + } + } +} + +/* + * Double the size of the dynamically allocated string. If unallocated, alloc of + * 16 bytes minimum. + */ +static i32 vg_str_dynamic_grow( vg_str *str ){ + if( str->buffer ){ + vg_str_dynamic *hdr = ((vg_str_dynamic *)str->buffer) - 1; + i32 total = (hdr->len + sizeof(vg_str_dynamic)) * 2; + hdr = realloc( hdr, total ); + hdr->len = total - sizeof(vg_str_dynamic); + str->buffer = (char *)(hdr+1); + return hdr->len; + } + else { + vg_str_dynamic *hdr = malloc(16); + hdr->len = 16-sizeof(vg_str_dynamic); + str->buffer = (char *)(hdr+1); + str->buffer[0] = '\0'; + return hdr->len; + } +} + +/* + * Append null terminated string to vg_str + */ +static void vg_strcat( vg_str *str, const char *append ){ + if( !append || (str->i == -1) ) return; + + i32 max = vg_str_storage( str ), + i = 0; + +append: + if( str->i == max ){ + if( str->len == -1 ) + max = vg_str_dynamic_grow( str ); + else{ + str->i = -1; + str->buffer[ max-1 ] = '\0'; + return; + } + } + + char c = append[ i ++ ]; + str->buffer[ str->i ] = c; + + if( c == '\0' ) + return; + + str->i ++; + goto append; +} + +/* + * Append character to vg_str + */ +static void vg_strcatch( vg_str *str, char c ){ + vg_strcat( str, (char[]){ c, '\0' } ); +} + +/* + * FIXME: Negative numbers + */ +static void vg_strcati32( vg_str *str, i32 value ){ + if( value ){ + char temp[32]; + int i=0; + while( value && (i<31) ){ + temp[ i ++ ] = '0' + (value % 10); + value /= 10; + } + + char reverse[32]; + for( int j=0; j=n ) + break; + + temp[ n-1 - (i ++) ] = '0' + (value % 10); + value /= 10; + } + + for( ;ii == -1 ) return 0; + else return 1; +} + +/* + * Returns pointer to last instance of character + */ +static char *vg_strch( vg_str *str, char c ){ + char *ptr = NULL; + for( i32 i=0; ii; i++ ){ + if( str->buffer[i] == c ) + ptr = str->buffer+i; + } + + return ptr; +} + +#endif /* VG_STRING_H */