################################################################################
#
# This Tcl script reads Quake's configuration file and sets the volume
# of the CD player and the sound effects using "cmix"; it's invoked by
# lxQuakeCDmusic right before x[f86]quake is started, plus whenever a
# user issues a "lx [volume|cd|sound]" command on Quake's console.
#
# (C) Copyright 1996 Michael Schumacher (mike@hightec.saarlink.de)
#
################################################################################

proc get_volumes {} {
  global env lxq_volumes

  catch {unset lxq_volumes}
  if { [catch {set desc [open "|$env(LXQCD_BINPATH)/cmix" r]}] } {
    return
  }
  if { [catch {set lines [read $desc]}] } {
    return
  }
  catch {close $desc}
  set os "\[ \t\]*"
  set ws "\[ \t\]+"
  set ls "\[\r\n\]+"
  set nr {[0-9]+}
  regexp "${ls}${ws}vol${ws}left=${os}($nr)" $lines {} lxq_volumes(volume)
  regexp "${ls}${ws}pcm${ws}left=${os}($nr)" $lines {} lxq_volumes(sound)
  regexp "${ls}${ws}cd${ws}left=${os}($nr)" $lines {} lxq_volumes(cd)
  if { [info exists lxq_volumes] && [llength [array names lxq_volumes]] != 3 } {
    unset lxq_volumes
  } else {
    set lxq_volumes(volume) [expr $lxq_volumes(volume) / 100.0]
    set lxq_volumes(sound) [expr $lxq_volumes(sound) / 100.0]
    set lxq_volumes(cd) [expr $lxq_volumes(cd) / 100.0]
  }
}

proc adjust_volume { dev how } {
  global lxq_volumes

  get_volumes
  if { ![info exists lxq_volumes] } {
    puts "setvolume: error calling \"cmix\"."
    return
  }

  if { "$how" == "+" } {
    call_cmix $dev [expr $lxq_volumes($dev) + 0.1]
  } elseif { "$how" == "-" } {
    call_cmix $dev [expr $lxq_volumes($dev) - 0.1]
  } elseif { "$how" != "" } {
    call_cmix $dev $how
  } else {
    set dev all
  }
  show_volumes $dev
}

proc show_volumes { dev } {
  global lxq_volumes

  get_volumes
  if { ![info exists lxq_volumes] } {
    puts "setvolume: error calling \"cmix\"."
    return
  }

  if { "$dev" == "volume" } {
    puts "setvolume: master volume is $lxq_volumes(volume)"
  } elseif { "$dev" == "sound" } {
    puts "setvolume: sound volume is $lxq_volumes(sound)"
  } elseif { "$dev" == "cd" } {
    puts "setvolume: CD volume is $lxq_volumes(cd)"
  } else {
    puts "setvolume: master volume is $lxq_volumes(volume)"
    puts "           sound volume is $lxq_volumes(sound)"
    puts "           CD volume is $lxq_volumes(cd)"
  }
}

proc call_cmix { dev val } {
  global env

  if { [catch {set val [expr int ($val * 100)]}] } {
    puts "setvolume: illegal value \"$val\"."
    return
  } elseif { $val < 0 } {
    set val min
  } elseif { $val > 100 } {
    set val max
  }
  if { "$dev" == "volume" } {
    set dev vol
  } elseif { "$dev" == "sound" } {
    set dev pcm
  }
  catch {exec $env(LXQCD_BINPATH)/cmix $dev $val}
}

proc set_volume {} {
  global env

  if { [catch {set desc [open $env(LXQCD_BINPATH)/../id1/config.cfg r]}] } {
    return
  }
  if { [catch {set lines [read $desc]}] } {
    catch {close $desc}
    return
  }
  close $desc
  set ws "\[ \t\]*"
  set fp {[0-9\.]+}
  set ls "\[\r\n\]+"
  call_cmix vol 1.0
  if { [regexp "${ls}bgmvolume$ws\"$ws\($fp)$ws\"" $lines {} vol] } {
    call_cmix cd $vol
  }
  if { [regexp "${ls}volume$ws\"$ws\($fp)$ws\"" $lines {} vol] } {
    call_cmix pcm $vol
  }
}

set_volume

### EOF ########################################################################
