switching output audio devices
[vg.git] / vg_settings_menu.h
index 96fc6ea4725ff4bf0e433175ffcd456dc0b25655..68b2171a5c6f2b995a90f84afcc8911ae2429c4c 100644 (file)
@@ -37,7 +37,8 @@ struct {
       u32 option_count;
       const char *label;
    }
-   vsync, quality, screenmode;
+   vsync, quality, screenmode, audio_devices;
+   i32 temp_audio_choice;
 
    int windowed_before[4];
 }
@@ -52,8 +53,10 @@ static vg_settings = {
                      .options = vg_settings_quality_enum, .option_count = 3 },
    .screenmode =  { .label = "Type",
                      .actual_value = &vg.screen_mode,
-                     .options = vg_settings_screen_mode_enum, .option_count=3 }
-
+                     .options = vg_settings_screen_mode_enum, .option_count=3 },
+   .audio_devices = { .label = "Audio Device",
+                      .actual_value = &vg_settings.temp_audio_choice,
+                      .options = NULL, .option_count = 0 }
 };
 
 static void vg_settings_ui_draw_diff( ui_rect orig ){
@@ -251,6 +254,118 @@ static void vg_settings_video_gui( ui_rect panel ){
    }
 }
 
+static void vg_settings_audio_apply(void){
+   if( vg_settings_enum_diff( &vg_settings.audio_devices ) ){
+      if( vg_audio.sdl_output_device ){
+         vg_info( "Closing audio device %d\n", vg_audio.sdl_output_device );
+         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;
+      }
+
+      if( vg_settings.audio_devices.new_value == -1 ){ }
+      else if( vg_settings.audio_devices.new_value == -2 ){
+         vg_fatal_error( "Programming error\n" );
+      }
+      else {
+         struct ui_enum_opt *selected = NULL, *oi;
+
+         for( int i=0; i<vg_settings.audio_devices.option_count; i ++ ){
+            oi = &vg_settings.audio_devices.options[i];
+
+            if( oi->value == vg_settings.audio_devices.new_value ){
+               selected = oi;
+               break;
+            }
+         }
+
+         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_audio_device_init();
+      *vg_settings.audio_devices.actual_value = 
+         vg_settings.audio_devices.new_value;
+   }
+}
+
+static void vg_settings_audio_gui( ui_rect panel ){
+   ui_rect rq;
+   ui_standard_widget( panel, rq, 1 );
+   vg_settings_enum( &vg_settings.audio_devices, rq );
+
+   const char *string = "Apply";
+
+   ui_rect last_row;
+   ui_px height = (vg_ui.font->glyph_height + 18) * k_ui_scale;
+   ui_split( panel, k_ui_axis_h, -height, k_ui_padding, 
+             panel, last_row );
+
+   if( ui_button( last_row, string ) == 1 )
+      vg_settings_audio_apply();
+}
+
+static void vg_settings_open(void){
+   vg.settings_open = 1;
+
+   ui_settings_ranged_i32_init( &vg_settings.fps_limit );
+   ui_settings_enum_init( &vg_settings.vsync );
+   ui_settings_enum_init( &vg_settings.quality );
+   ui_settings_enum_init( &vg_settings.screenmode );
+   
+   /* Create audio options */
+   int count = SDL_GetNumAudioDevices( 0 );
+
+   struct ui_enum_opt *options = malloc( sizeof(struct ui_enum_opt)*(count+1) );
+   vg_settings.audio_devices.options = options;
+   vg_settings.audio_devices.option_count = count+1;
+
+   struct ui_enum_opt *o0 = &options[0];
+   o0->alias = "OS Default";
+   o0->value = -1;
+
+   for( int i=0; i<count; i ++ ){
+      struct ui_enum_opt *oi = &options[i+1];
+
+      const char *device_name = SDL_GetAudioDeviceName( i, 0 );
+      int len = strlen(device_name);
+
+      oi->alias = malloc( len+1 );
+      memcpy( (void *)oi->alias, device_name, len+1 );
+      oi->value = i;
+   }
+
+   if( vg_audio.force_device_name ){
+      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 ) ){
+            vg_settings.temp_audio_choice = oi->value;
+            break;
+         }
+      }
+   }
+   else {
+      vg_settings.temp_audio_choice = -1;
+   }
+
+   ui_settings_enum_init( &vg_settings.audio_devices );
+}
+
+static void vg_settings_close(void){
+   vg.settings_open = 0;
+
+   struct ui_enum_opt *options = vg_settings.audio_devices.options;
+   for( int i=1; i < vg_settings.audio_devices.option_count; i ++ )
+      free( (void *)options[i].alias );
+   free( vg_settings.audio_devices.options );
+}
+
 static void vg_settings_gui(void){
    ui_rect null;
    ui_rect screen = { 0, 0, vg.window_x, vg.window_y };
@@ -271,7 +386,7 @@ static void vg_settings_gui(void){
    ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, quit_button );
 
    if( ui_button_text( quit_button, "X", 1 ) == 1 ){
-      vg.settings_open = 0;
+      vg_settings_close();
       return;
    }
 
@@ -284,17 +399,12 @@ static void vg_settings_gui(void){
    if( page == 0 ){
       vg_settings_video_gui( panel );
    }
+   else if( page == 1 )
+      vg_settings_audio_gui( panel );
 }
 
 static int cmd_vg_settings_toggle( int argc, const char *argv[] ){
-   vg.settings_open = !vg.settings_open;
-
-   if( vg.settings_open ){
-      ui_settings_ranged_i32_init( &vg_settings.fps_limit );
-      ui_settings_enum_init( &vg_settings.vsync );
-      ui_settings_enum_init( &vg_settings.quality );
-      ui_settings_enum_init( &vg_settings.screenmode );
-   }
+   vg_settings_open();
    return 0;
 }