;******************************************************************************
;            (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 24 Oct 95 JPE     Initial revision.
; 101 08 Nov 95 JPE     Eliminated joyStart flag. Incorporated control of
;                       voiceover. Implemented parsing of auxiliary atom,
;                       control of subtitles and profile/score updates.
;                       Converted profile increments from byte to word.
;                       Subtitle highlight added.
; 102 04 Dec 95 JPE     Eliminated canned versions of atoms. Move Print()
;                       function to utils.s
; 103 10 Jan 96 JPE     Subtitle selection based on history field in playlist.
;                       Grey subtitle on restricted pass of loop.
; 104 15 Feb 96 JPE     Modifications to support new loop specification.
; 105 02 Apr 96 HMK	Moved Voice Over Variables into DSP Memory
;******************************************************************************

        .nlist
        .include    'memory.inc'
        .include    'jaguar.inc'
        .include    'player.inc'
        .include    'params.inc'
        .include    'offset.inc'
        .list

;==============================================================================
;                               AuxCtrl
;==============================================================================

AuxCtrl:
        movem.l d0/a2,-(sp)             ; Save registers

        tst.l   auxAtom                 ; Is there an auxiliary atom?
        beq     AuxCtrlExit             ; No, nothing to do

        tst     segValid                ; Is there a valid segment?
        bne.s   CheckFrame              ; Yes, check frame number

        bsr     GetAuxSegment           ; No, try to get one
        tst     segValid                ; Successful?
        beq     AuxCtrlExit             ; No, nothing more to do

CheckFrame:
        movea.l pKeyList,a2             ; Recall place in list
        move.l  frameNum,d0             ; Current frame number
        cmp.l   (a2)+,d0                ; Compare, skip frame #
        bne     AuxCtrlExit             ; Unequal, nothing to do

        move.l  a2,pKeyList             ; Update list pointer
        tst.l   (a2)                    ; End of list?
        bne.s   XorActive               ; No, toggle active flag

        clr     segValid                ; Yes, this segment is done

XorActive:
        eori    #1,segActive            ; Toggle active flag
        beq     EndSegment              ; If zero, end of segment

        bsr     SetCensor               ; Set censored flag
        bsr     VoiceAudible            ; Check flags
        tst     d0                      ; Voiceover enabled?
        beq.s   SetTitle                ; Skip if not

        bsr     GetVoiceTrack           ; Yes, get voiceover track

SetTitle:
        move    #WHITE,fontColor        ; Use white as default
        movea.l segSubtitle,a2          ; Start of subtitle atom
        lea     subtText(a2),a2         ; Pointer to text string

        tst     loopFlag                ; In a loop?
        beq.s   TitleOn                 ; No, skip

        move    #GREEN,fontColor        ; Default green for loops
        tst     censored                ; Is this branch censored?
        beq.s   TitleOn                 ; Skip if not

        move    #GREY34,fontColor       ; Otherwise, grey out

TitleOn:
        bsr     SubtVisible             ; Check flags
        move    d0,subtEnable           ; Latch until next segment
        beq.s   AuxCtrlExit             ; Exit if not enabled

        bsr     DrawSubtitle            ; No, put up subtitle
        bra.s   AuxCtrlExit             ; Exit

EndSegment:
        tst     loopFlag                ; In a loop?
        beq.s   TitleOff                ; Skip if not

        move    #1,loadDefault          ; Too late for loop option "A"

TitleOff:
        tst     subtEnable              ; Subtitle enabled?
        beq.s   AuxCtrlExit             ; Exit if not

        bsr     EraseSubtitle           ; Kill subtitle

AuxCtrlExit:
        movem.l (a7)+,d0/a2             ; Restore registers
        rts

;------------------------------------------------------------------------------
;                              SetCensor
;------------------------------------------------------------------------------
;   Sets global "censored" flag by testing a bit in the control block censor
;   mask. The inverted lsb of segCount is used to determine the target bit.
;------------------------------------------------------------------------------

SetCensor:
        movem.l d0-d1/a1,-(sp)          ; Save registers

        clr     censored                ; Clear by default
        tst     loopFlag                ; Is this a loop?
        beq.s   ExitCensor              ; Exit if not

        lea     playCtrl,a1             ; Player control block
        movea.l playBCtrl(a1),a1        ; Buffer control block
        move    censorMask(a1),d1       ; Get censor mask

        move.l  segCount,d0             ; Get segment counter
        bchg.l  #0,d0                   ; Flip bit 0
        btst.l  d0,d1                   ; This branch censored?
        beq.s   ExitCensor              ; Exit if not

        move    #1,censored             ; Otherwise, set flag

ExitCensor:
        movem.l (sp)+,d0-d1/a1          ; Restore registers
        rts

;==============================================================================
;                            EraseSubtitle
;==============================================================================

EraseSubtitle:
        movem.l a0-a1/d0-d1,-(a7)       ; Save gcc registers

        move    #BLACK,fgColor          ; Draw with black
        movea.l pString,a2              ; Use current string pointer
        bra.s   BlitSubtitle

HiLiteSubtitle:
        movem.l a0-a1/d0-d1,-(a7)       ; Save gcc registers

        move    #MAGENTA,fgColor        ; Draw with black
        movea.l pString,a2              ; Use current string pointer
        bra.s   BlitSubtitle

DrawSubtitle:
        movem.l a0-a1/d0-d1,-(a7)       ; Save gcc registers

        move    fontColor,fgColor       ; Color to draw with
        move.l  a2,pString              ; Save string for erase

BlitSubtitle:
        move    #2,blitTitle            ; Copy title twice

        pea     font                    ; FNThead
        move.l  a2,-(a7)                ; char *str
        jsr     _FNTbox                 ; Get bounding rectangle in d0
        lea     $8(a7),a7               ; Balance stack

        subi    #NPIXELS,d0             ; Subtract pixels per line
        neg     d0                      ; Make positive
        lsr     #1,d0                   ; Divide by 2

        move    #$0,-(sp)               ; bgcolor
        move    fgColor,-(sp)           ; fgcolor
        pea     font                    ; FNThead

        move.l  #PIXEL16|PITCH3|WID320,-(sp)     ; blitflags

        move.l  #SCREEN_BASE,-(sp)      ; void *dest
        move.l  a2,-(sp)                ; char *str
        move    #194,-(sp)              ; int y
        move    d0,-(sp)                ; int x
        jsr     _FNTstr                 ; do it
        lea     $18(a7),a7              ; Balance stack

exit:
        movem.l (sp)+,a0-a1/d0-d1       ; Restore gcc registers
        rts

;==============================================================================
;                             SubtVisible
;==============================================================================
;   Tests combinations of flags to determine whether or not subtitle is to
;   be displayed.
;
;   Input:  None
;
;   Output: d0.w = 1 if subtitle is displayed
;           d0.w = 0 if subtitle is inhibited
;==============================================================================

SubtVisible:
        tst     autoPilot               ; On automatic pilot?
        bne.s   SubtInhibit             ; Inhibit if not zero

        cmpi    #NEITHER,cueOption      ; Neither subtitle nor voice?
        beq.s   SubtInhibit             ; Yes, inhibit subtitle

        cmpi    #VOICEOVER,cueOption    ; Voiceover only?
        beq.s   SubtInhibit             ; Yes, inhibit subtitle

        tst     loopFlag                ; In a loop?
        beq.s   SubtEnable              ; No, enable subtitle

        cmpi    #HARD,difficulty        ; Difficulty set to hard?
        beq.s   SubtInhibit             ; Yes, inhibit subtitle

        move    loopIndex,d0            ; Current loop index
        cmp     minIndex,d0             ; First pass through loop?
        beq.s   SubtInhibit             ; Yes, inhibit subtitle

        tst     optionIndex             ; Has a decision been made?
        bge.s   SubtInhibit             ; Yes, inhibit subtitle

SubtEnable:
        move    #1,d0                   ; Set flag on
        rts                             ; Return flag to caller

SubtInhibit:
        clr     d0                      ; Set flag off
        rts                             ; Return flag to caller

;==============================================================================
;                             VoiceAudible
;==============================================================================
;   Tests combinations of flags to determine whether or not voiceover is to
;   be played.
;
;   Input:  None
;
;   Output: d0.w = 1 if voiceover is played
;           d0.w = 0 if voiceover is inhibited
;==============================================================================

VoiceAudible:
        tst     autoPilot               ; On automatic pilot?
        bne.s   VoiceInhibit            ; Inhibit if not zero

        cmpi    #NEITHER,cueOption      ; Neither subtitle nor voice?
        beq.s   VoiceInhibit            ; Yes, inhibit voiceover

        cmpi    #SUBTITLES,cueOption    ; Subtitles only?
        beq.s   VoiceInhibit            ; Yes, inhibit voiceover

        cmpi    #HARD,difficulty        ; Difficulty set to HARD?
        beq.s   VoiceInhibit            ; Yes, inhibit voiceover

        tst     loopFlag                ; In a loop?
        beq.s   VoiceEnable             ; No, enable voiceover

        move    loopIndex,d0            ; Current loop index
        cmp     minIndex,d0             ; First pass through loop?
        beq.s   VoiceInhibit            ; Yes, inhibit voiceover

        tst     optionIndex             ; Has a decision been made?
        bge.s   VoiceInhibit            ; Yes, inhibit voiceover

VoiceEnable:
        move    #1,d0                   ; Set flag on
        rts                             ; Return flag to caller

VoiceInhibit:
        clr     d0                      ; Set flag off
        rts                             ; Return flag to caller

;==============================================================================
;                            GetVoiceTrack
;==============================================================================

GetVoiceTrack:
        movem.l d0/a0,-(a7)             ; Save used registers

        move.l  segVoiceover,a0         ; Start of voice track
        lea     8(a0),a0                ; Skip tag and size
        move.l  (a0)+,d0                ; Read byte count
        beq.s   GetVoiceExit            ; If zero, exit

        add.l   d0,d0                   ; Double (repeat 11 kHz samples)

        move.l  a0,vOverData            ; Start of voicover data
        move.l  d0,vOverCount           ; Byte count

GetVoiceExit:
        movem.l (a7)+,d0/a0             ; Restore used registers
        rts

;==============================================================================
;                             SetAuxTrack
;==============================================================================

SetAuxTrack:
        movem.l d0-d1/a0-a1,-(sp)       ; Save registers

        tst.l   auxAtom                 ; Is there an auxiliary atom?
        beq     SetAuxExit              ; No, exit

        movea.l auxAtom,a0              ; Start of auxiliary atom
        cmpi.l  #'AUXL',auxlTag(a0)     ; Correct tag?
        bne     SetAuxError             ; No, trap error

        lea     trackTbl(a0),a0         ; Point to track table
        cmpi.l  #'TRTB',trtbTag(a0)     ; Correct tag?
        bne     SetAuxError             ; No, trap error

        lea     playCtrl,a1             ; Player control block
        movea.l playBCtrl(a1),a1        ; Buffer control block
        movea.l pListAddr(a1),a1        ; Address of playlist entry
        clr.l   d0                      ; Make into long operand
        move.b  history(a1),d0          ; Number of times viewed
        move.l  trtbTracks(a0),d1       ; Number of tracks
        divu    d1,d0                   ; (viewings-1) / tracks
        swap    d0                      ; (viewings-1) % tracks
        lea     0(a0),a1                ; Start of track table
        adda.l  trtbSize(a0),a1         ; End of track table
        lea     trackRec(a0),a0         ; Skip to track records
        lsl     #3,d0                   ; Record size is 8
        adda.l  tkrcOff(a0,d0),a1       ; Indexed track record

        cmpi.l  #'TRAK',trakTag(a1)     ; Correct tag?
        bne.s   SetAuxError             ; No, trap error

        lea     segmentTbl(a1),a1       ; Move to segment table
        cmpi.l  #'SGTB',sgtbTag(a1)     ; Correct tag?
        bne.s   SetAuxError             ; No, trap error

        lea     0(a1),a0                ; Start of segment table
        adda.l  sgtbSize(a1),a0         ; Base of segment data
        move.l  a0,segBase              ; Store for later
        move.l  sgtbSegs(a1),segCount   ; Store segment count
        lea     segmentRec(a1),a1       ; Skip to segment records
        move.l  a1,segRecord            ; Store for later
        clr     segValid                ; Initialize to invalid

SetAuxExit:
        movem.l (sp)+,d0-d1/a0-a1       ; Restore registers
        rts

SetAuxError:
        illegal                         ; Trap error

;==============================================================================
;                            GetAuxSegment
;==============================================================================

GetAuxSegment:
        movem.l a0-a1,-(sp)             ; Save registers

        tst.l   segCount                ; Any segments left?
        beq     GetAuxExit              ; No, exit

GetNextSegment:
        movea.l segRecord,a0            ; Current segment record
        lea     SGRC_SIZE(a0),a1        ; Next segment record
        move.l  a1,segRecord            ; Update record pointer
        subq.l  #1,segCount             ; Decrement segment count
        move    #1,segValid             ; Flag to show valid segment

        lea     segKeyList,a1           ; Start of keyframe list
        move.l  a1,pKeyList             ; Initialize list pointer
        move.l  sgrcF0(a0),(a1)+        ; Starting frame number
        move.l  sgrcF1(a0),(a1)+        ; Ending frame number
        clr.l   (a1)                    ; End of list

        movea.l segBase,a1              ; Base of segment data
        adda.l  sgrcOffset(a0),a1       ; Start of target segment

        cmpi.l  #'SGMT',sgmtTag(a1)     ; Correct tag?
        bne.s   GetAuxError             ; No, trap error

        lea     sgmtData(a1),a1         ; Skip to start of data
        cmpi.l  #'VTRK',vtrkTag(a1)     ; Correct tag?
        bne.s   GetAuxError             ; No, trap error

        move.l  a1,segVoiceover         ; Start of voiceover atom
        adda.l  vtrkSize(a1),a1         ; Skip voiceover atom

        cmpi.l  #'SUBT',subtTag(a1)     ; Correct tag?
        bne.s   GetAuxError             ; No, trap error

        move.l  a1,segSubtitle          ; Start of subtitle atom
        adda.l  subtSize(a1),a1         ; Skip subtitle atom

        cmpi.l  #'SCOR',scorTag(a1)     ; Correct tag?
        bne.s   GetAuxError             ; No, trap error

        move.l  a1,segScore             ; Start of score atom

GetAuxExit:
        movem.l (sp)+,a0-a1             ; Restore registers
        rts

GetAuxError:
        illegal                         ; Trap error

;==============================================================================
;                             UpdateScore
;==============================================================================

UpdateScore:
        movem.l d0/a0,-(sp)             ; Save registers

        cmpi    #2,optionIndex          ; Default option?
        beq.s   ScoreExit               ; Yes, no change in score

        movea.l segScore,a0             ; Start of score atom
        moveq   #0,d0                   ; Clear high word
        move    dScore(a0),d0           ; Get incremental score
        add.l   d0,score                ; Add to score

ScoreExit:
        movem.l (sp)+,d0/a0             ; Restore registers
        rts

;==============================================================================
;                            UpdateProfile
;==============================================================================

UpdateProfile:
        movem.l d0-d2/a0-a1,-(sp)       ; Save registers

        movea.l segScore,a0             ; Start of score atom
        lea     dProfile(a0),a0         ; Pointer to profile increments
        lea     profile,a1              ; Where profile is stored
        moveq   #5-1,d2                 ; Count 5 attributes

UpdateAttribute:
        move    (a0)+,d0                ; Get increment to attribute
        add     (a1),d0                 ; Add previous value
        bge.s   NoClip                  ; If positive, no clip

        moveq   #0,d0                   ; Handle underflow

NoClip:
        lsr     #1,d0                   ; Weight 50-50
.if 0   ;----------------------------------------------------------------------
        .extern RecordEvent
        movem.l d0-d2,-(sp)             ; Save registers
        clr.l   d2                      ; Clear high word
        move    d0,d2                   ; Move new value to d2
        move.l  #'PRFL',d0              ; ASCII tag
        clr.l   d1                      ; Clear high word
        move    (a1),d1                 ; Record current value
        bsr     RecordEvent             ; Leave crumb for debug
        movem.l (sp)+,d0-d2             ; Restore registers
.endif  ;----------------------------------------------------------------------
        move    d0,(a1)+                ; Write result back
        dbra    d2,UpdateAttribute      ; Do next attribute

        movem.l (sp)+,d0-d2/a0-a1       ; Restore registers
        rts

;==============================================================================

        .long
.if 0
vOverCount:     dc.l    0		; +++ 4/2/96 HMK MOVED TO DSP MEMORY (CSX)
vOverData:      dc.l    0		; +++ 4/2/96 HMK MOVED TO DSP MEMORY (CSX)
.endif
        .bss
        .long

pString:        ds.l    1
auxAtom:        ds.l    1
segBase:        ds.l    1
segCount:       ds.l    1
segRecord:      ds.l    1
pKeyList:       ds.l    1
segVoiceover:   ds.l    1
segSubtitle:    ds.l    1
segScore:       ds.l    1
segKeyList:     ds.l    3

fgColor:        ds.w    1
fontColor:      ds.w    1
segValid:       ds.w    1
subtEnable:     ds.w    1

        .extern autoPilot
        .extern segActive
        .extern playCtrl
        .extern loopIndex
        .extern voxStart
        .extern  _FNTstr
        .extern  _FNTbox
        .extern subt_begin
        .extern font
        .extern cueOption
        .extern blitTitle
        .extern difficulty
        .extern loopFlag
        .extern profile
        .extern score
        .extern optionIndex
        .extern censored
        .extern minIndex
        .extern loadDefault
	.extern vOverData
	.extern vOverCount

        .globl  DrawSubtitle
        .globl  EraseSubtitle
        .globl  frameNum
        .globl  fontColor
        .globl  AuxCtrl
        .globl  vOverCount
        .globl  vOverData
        .globl  auxAtom
        .globl  SetAuxTrack
        .globl  UpdateProfile
        .globl  UpdateScore
        .globl  HiLiteSubtitle
        .globl  subtEnable
        .globl  segCount

        .end                           ; end of file
