add strings to console variables
authorhgn <hgodden00@gmail.com>
Sun, 31 Dec 2023 11:22:13 +0000 (11:22 +0000)
committerhgn <hgodden00@gmail.com>
Sun, 31 Dec 2023 11:22:13 +0000 (11:22 +0000)
vg.h
vg_audio.h
vg_console.h
vg_platform.h
vg_settings_menu.h
vg_string.h [new file with mode: 0644]

diff --git a/vg.h b/vg.h
index 82f95fcceab3a17469a552feee97b06d4528373f..c4f55c3ce924d070fcea0d34340cbf3d1e2e56e2 100644 (file)
--- 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 );
index 2bba7ea09ec4e4ea31fa806cf3519523844a6750..5df5638b0b1660a474df3b450e27b6735e03181f 100644 (file)
@@ -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 = 
index 42f79e4f35e7c62582bad750798f19cc126b8082..029b3e69efe417011ead5965a481b7c93abd201c 100644 (file)
@@ -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; i<vg_console.var_count; i ++ ){
                struct vg_var *cv = &vg_console.vars[ i ];
-               vg_info( "%s\n", cv->name );
+               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; i<vg_console.var_count; i ++ ){
-               struct vg_var *cv = &vg_console.vars[i];
-
-      enum vg_var_dtype type = cv->data_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; i<arg_count; i ++ ){
+               vg_strcat( str, args[i] );
+               if( i!=arg_count-1 ) vg_strcatch( str, ' ' );
+            }
+         }
       }
       else{
          if( cv->data_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;
index 9366095cc702e3026a16c74efc38b8e30f9750b2..e8b288e9731afd4034d922ff010a5ed3e4054700 100644 (file)
@@ -46,6 +46,8 @@ struct vg_achievement
 #include <errno.h>
 #include <stdlib.h>
 
+#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<i; j ++ )
-         reverse[j] = temp[ i-1-j ];
-      reverse[i] = '\0';
-
-      vg_strcat( str, reverse );
-   }
-   else
-      vg_strcat( str, "0" );
-}
-
-static void vg_strcati32r( vg_str *str, i32 value, i32 n, char alt ){
-   char temp[32];
-   i32 i=0;
-   while( value ){
-      if( i>=n ) 
-         break;
-
-      temp[ n-1 - (i ++) ] = '0' + (value % 10);
-      value /= 10;
-   }
-
-   for( ;i<n; i ++ )
-      temp[ n-1 - i ] = alt;
-
-   temp[n]='\0';
-   vg_strcat( str, temp );
-}
-
-/*
- * Returns 1 if string did not overflow while building
- */
-static int vg_strgood( vg_str *str ){
-   if( str->i == -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; i<str->i; i++ ){
-      if( str->buffer[i] == c )
-         ptr = str->buffer+i;
-   }
-
-   return ptr;
-}
-
 static u32 vg_strdjb2( const char *str ){
    u32 hash = 5381, c;
 
index 68b2171a5c6f2b995a90f84afcc8911ae2429c4c..fb6a11616c3d688f642fdc16f18819fe1f4f9389 100644 (file)
@@ -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; i<count; i ++ ){
          struct ui_enum_opt *oi = &options[i+1];
-         if( !strcmp( oi->alias, 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 (file)
index 0000000..c99fc7a
--- /dev/null
@@ -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<i; j ++ )
+         reverse[j] = temp[ i-1-j ];
+      reverse[i] = '\0';
+
+      vg_strcat( str, reverse );
+   }
+   else
+      vg_strcat( str, "0" );
+}
+
+static void vg_strcati32r( vg_str *str, i32 value, i32 n, char alt ){
+   char temp[32];
+   i32 i=0;
+   while( value ){
+      if( i>=n ) 
+         break;
+
+      temp[ n-1 - (i ++) ] = '0' + (value % 10);
+      value /= 10;
+   }
+
+   for( ;i<n; i ++ )
+      temp[ n-1 - i ] = alt;
+
+   temp[n]='\0';
+   vg_strcat( str, temp );
+}
+
+/*
+ * Returns 1 if string did not overflow while building
+ */
+static int vg_strgood( vg_str *str ){
+   if( str->i == -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; i<str->i; i++ ){
+      if( str->buffer[i] == c )
+         ptr = str->buffer+i;
+   }
+
+   return ptr;
+}
+
+#endif /* VG_STRING_H */