;******************************************************************************
;            (C) Copyright 1992-1995, Radius, Inc. and Atari Corp.
; Secret and confidential                                   All rights reserved
;******************************************************************************
; This source code and any compilation or derivative thereof is the joint
; property of Radius, Inc. and Atari Corp.  This code is provided pursuant
; to a Software License Agreement and/or Software Development Contract.  This
; code is the proprietary information of Radius, Inc. and Atari Corp. and is
; confidential in nature.  Its use and dissemination by any party other than
; Atari Corp. are strictly limited by the confidential information provisions
; of the Agreement or Contract referenced above.
;******************************************************************************
; 100 11 Dec 95 JPE     Initial revision.
;******************************************************************************

        .include    'params.inc'

;==============================================================================
;                              VolumeCtrl
;==============================================================================
;   Performs real-time control of playback volume, using UP and DOWN keys
;   on joypad.  Dynamic range is ~70 dB, in 32 steps.  Pressing and holding
;   either key caused the volume to be changed at five steps per second in
;   the specified direction.  When the volume has reached either extreme, it
;   is pegged at that limit.
;
;   Output: None.
;==============================================================================

VolumeCtrl:
        movem.l d0,-(sp)                ; Save registers

        btst.b  #bVOLUME,joySemaphore   ; Semaphore set?
        beq     CheckTimer              ; No, just check timer

        bclr.b  #bVOLUME,joySemaphore   ; Yes, clear it
        move.l  joyRise,d0              ; Keys that went active
        or.l    joyFall,d0              ; Keys that went inactive
        btst.l  #bUP,d0                 ; Change on UP key?
        beq.s   CheckDown               ; No, check DOWN key

        move.l  joyRise,d0              ; Keys that went active
        btst.l  #bUP,d0                 ; Is UP key pressed?
        beq.s   UpInactive              ; Skip if not

        move    #MAX_VOL,volLimit       ; Limit at maximum
        move    #1,volDelta             ; Use positive steps
        move.l  time,volTimer           ; Arm for immediate action
        bra.s   CheckTimer

UpInactive:
        clr.l   volTimer                ; Disable timer
        bra     ExitVolume

CheckDown:
        btst.l  #bDOWN,d0               ; Change on DOWN key?
        beq.s   CheckTimer              ; No, check timer key

        move.l  joyRise,d0              ; Keys that went active
        btst.l  #bDOWN,d0               ; Is DOWN key pressed?
        beq.s   DownInactive            ; Skip if not

        move    #MIN_VOL,volLimit       ; Limit at minimum
        move    #-1,volDelta            ; Use negative steps
        move.l  time,volTimer           ; Arm for immediate action
        bra.s   CheckTimer

DownInactive:
        clr.l   volTimer                ; Disable timer
        bra.s   ExitVolume

CheckTimer:
        tst.l   volTimer                ; Is timer set?
        beq.s   ExitVolume              ; Exit if not

        move.l  time,d0                 ; Get current time
        cmp.l   volTimer,d0             ; Time to adjust volume?
        blt.s   ExitVolume              ; No, exit

        addi.l  #120,d0                 ; Yes, add 0.2 seconds
        move.l  d0,volTimer             ; Reset timer
        move    volIndex,d0             ; Get current index
        cmp     volLimit,d0             ; Reached limit?
        beq.s   ExitVolume              ; Yes, don't adjust

        add     volDelta,d0             ; No, add increment
        move    d0,volIndex             ; Save updated index
        lsl     #1,d0                   ; Word entries in table
        move    volTbl(pc,d0),d0        ; New audio gain
        andi.l  #$ffff,d0               ; Clear out high word
        move.l  d0,audioGain            ; Write back updated value

.if 0   ;----------------------------------------------------------------------
        movem.l     d2-d3,-(sp)         ; Save
        move.l      #'VOLU',d0          ; Tag
        move.l      joySamp,d1          ; d1 = joySamp
        clr.l       d2                  ; Clear high word
        move        volIndex,d2         ; d2 = volIndex
        bsr         RecordEvent         ; Leave crumb
        movem.l     (sp)+,d2-d3         ; Restore
.endif  ;----------------------------------------------------------------------

ExitVolume:
        movem.l (sp)+,d0                ; Restore registers
        rts

;------------------------------------------------------------------------------

        dc.w      512,   583,   664,   756,   861,   980,  1117,  1272
        dc.w     1448,  1649,  1878,  2139,  2435,  2773,  3158,  3596
volTbl: dc.w     4096
        dc.w     4664,  5312,  6049,  6888,  7844,  8933, 10173, 11585
        dc.w    13193, 15024, 17109, 19483, 22188, 25267, 28774, 32767

;------------------------------------------------------------------------------
;   Declare storage.
;------------------------------------------------------------------------------

volIndex:       dc.w    0
volTimer:       dc.l    0

        .bss

volDelta:       ds.w    1
volLimit:       ds.w    1

;------------------------------------------------------------------------------
;   Delare externals and globals.
;------------------------------------------------------------------------------

        .extern audioGain
        .extern joyFall
        .extern joyRise
        .extern joySamp
        .extern joySemaphore
        .extern RecordEvent
        .extern time

        .globl  VolumeCtrl
