;******************************************************************************
;            (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 02 Feb 96 JPE     Initial revision.
; 101 16 Feb 96 JPE     Cleaned up playlist initialization. Cleaned up path
;                       record management. Moved canned movie paths (VCR) to
;                       "playlist.s". Fixed CD hangup at end of game.
; 102 22 Feb 96 JPE     Restore from paused state forces continuation.
;******************************************************************************

        .nlist
        .include    'cd.inc'
        .include    'player.inc'
        .include    'params.inc'
        .include    'offset.inc'
        .list

;==============================================================================
;                               EndCtrl
;==============================================================================

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

        move    #1,d0                   ; Wait for completion
        jsr     CD_paus                 ; Pause the CD (Uses d1!!)

        clr     restoreFlag             ; Clear restore flag
        clr     continue                ; Clear continue flag
        clr     playback                ; Clear playback flag
        clr     gameOver                ; Clear game over flag
        clr     autoPilot               ; Clear auto pilot flag
        move.l  #pathRecord,pPath       ; Default start of path record
        move.l  playListEnt,pList       ; Default loader list pointer

        bsr     ClearOnScreen           ; Clear display

EndWait:
        bsr     GetAny                  ; Read joypad
        tst.l   d0                      ; Any keys pressed?
        beq.s   EndWait                 ; No, wait

        bsr     ClearJoy                ; Let joypad clear
        bsr     EndPath                 ; Display score, etc.

        cmpi    #NOTHING,d0             ; Timed out?
        beq.s   EndWait                 ; Yes, wait again

        cmpi    #RESTART,d0             ; Restart?
        beq.s   Restart                 ; Yes, do it

        cmpi    #CONTINUE,d0            ; Continue?
        beq.s   Continue                ; Yes, do it

        cmpi    #PLAYBACK,d0            ; Playback?
        beq.s   Playback                ; Yes, do it

        illegal                         ; Trap bogus return value

Restart:
        bsr     ResetPlaylist           ; Reset playlist
        bra.s   EndExit                 ; Exit to main control

Continue:
        bsr     SetContinue             ; Set new state parameters
        bra.s   EndExit                 ; Exit to main control

Playback:
        move    #1,playback             ; Set playback flag
        move    #1,autoPilot            ; Set auto pilot flag

EndExit:
        move    #1,d0                   ; Wait for completion
        jsr     CD_upaus                ; Unpause the CD (Uses d1!!)

        clr     vcrMode                 ; Now clear vcrMode flag
        movem.l (sp)+,d0-d1             ; Restore registers
        rts

;------------------------------------------------------------------------------
;                             SetContinue
;------------------------------------------------------------------------------

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

        move    #1,continue             ; Set continue flag
        move.l  contNode,pList          ; Initialize loader list pointer
        move.l  contPath,pPath          ; Where to pick up path record
        move.l  contScore,score         ; Reset score

        lea     contProfile,a0          ; Saved values
        lea     profile,a1              ; Values to be restored
        move    #5-1,d0                 ; Loop counter

CopyProfile:
        move    (a0)+,(a1)+             ; Copy one attribute
        dbra    d0,CopyProfile          ; Loop until done

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

;==============================================================================
;                              PauseCtrl
;==============================================================================

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

        move.l  time,pauseTime          ; Save current time
        clr     msgIndex                ; Clear messgage index
        clr     pauseClear              ; Clear flag
        clr     remind                  ; Clear remind flag
        clr     restoreFlag             ; Clear restore flag
        clr     autoPilot               ; Clear auto pilot flag

;        move    #1,d0                   ; Wait for completion
;        jsr     CD_paus                 ; Pause the CD

        lea     loadCtrl,a2             ; Loader control block
        move.l  loadBCtrl(a2),d0        ; Buffer control block
        lea     playCtrl,a2             ; Player control block
        cmp.l   playBCtrl(a2),d0        ; Are buffers the same?
        bne     LoadMsg                 ; No, proceed

        cmpi    #1,playPhase            ; Idle CD phase?
        bne.s   CheckRdWr               ; No, check read-write pointers

        bra     LoadMsg                 ; Yes, OK to pause

CheckRdWr:
        tst     rdBeforeWr              ; Read pointer before write?
        bne     LoadMsg                 ; Yes, OK to pause

.if 0   ;----------------------------------------------------------------------
        bsr     GetCDWritePtr           ; Get CD write pointer
        movem.l d0-d2,-(sp)             ; Save registers
        move.l  #'PAUS',d0              ; ASCII tag
        move.l  CDWritePtr,d1           ; Record CDWritePtr
        move.l  #$deaddead,d2           ; Dead space
        bsr     RecordEvent             ; Leave breadcrumb for debug
        movem.l (sp)+,d0-d2             ; Restore registers
.endif  ;----------------------------------------------------------------------

        lea     loadCtrl,a2             ; Loader control block
        movea.l loadBCtrl(a2),a2        ; Load buffer control block
        move.l  bufStart(a2),d0         ; Start of buffer
        subq.l  #4,d0                   ; Where CD-BIOS starts

WaitSeek:
        bsr     GetCDWritePtr           ; Get CD write pointer
        cmp.l   CDWritePtr,d0           ; Still in seek mode?
        beq.s   WaitSeek                ; Yes, wait write to become active

        jsr     CD_uread                ; Stop overwriting memory

        move.l  CDWritePtr,CDReloadPtr  ; Remember where we are
        clr.l   CDWritePtr              ; Zero until loader modifies!!
        move.l  time,pauseTime          ; Resave current time
        move    #1,waitReload           ; Set flag to delay player

        lea     loadCtrl,a2             ; Loader control block
        move    #1,loadRepeat(a2)       ; Set repeat flag

        lea     playCtrl,a2             ; Player control block
        move    #1,playPause(a2)        ; Set pause flag

LoadMsg:
        move    msgIndex,d0             ; Get message index
        lsl     #2,d0                   ; Index by longs
        lea     msgTable,a2             ; Base of table
        movea.l 0(a2,d0),a2             ; Indexed message
        move    #GREEN,fontColor        ; Draw in green
        bsr     DrawSubtitle            ; Put up subtitle
        bsr     DoBlit                  ; Copy to display 1
        bsr     DoBlit                  ; Copy to display 2

        move.l  time,d1                 ; Get current time
        addi.l  #600,d1                 ; Add 1 second

CheckTime:
        tst     pauseClear              ; Cleared initial pause?
        bne.s   GetInput                ; Yes, get input

        bsr     ClearPause              ; Check on pause key
        tst     pauseClear              ; Cleared initial press?
        beq.s   SkipInput               ; No, skip input

GetInput:
        bsr     ScanCodes               ; Scan for hidden codes
        tst     scanActive              ; Code scan in progress?
        bne.s   SkipInput               ; Yes, skip normal input

        tst     vcrMode                 ; Cheat code selected?
        bne     SetPath                 ; Yes, set up fixed path

        bsr     GetAny                  ; Look for joypad key
        btst.l  #bOPTION,d0             ; Option key?
        bne     EnterConfig             ; Yes, do configuration

        btst.l  #bPAUSE,d0              ; Pause key?
        bne     Resume                  ; Yes, resume

        btst.l  #bRIGHT,d0              ; RIGHT key?
        bne     Remind                  ; Yes, jog memory

        cmpi.l  #(1<<bB)+(1<<bC),d0     ; B and C?
        beq     Trap                    ; Yes, trap for debug

SkipInput:
        cmp.l   time,d1                 ; Time elapsed?
        bgt.s   CheckTime               ; No, wait

        bsr     EraseSubtitle           ; Erase subtitle
        bsr     DoBlit                  ; Copy to display 1
        bsr     DoBlit                  ; Copy to display 2

        addq    #1,msgIndex             ; Increment index
        cmpi    #3,msgIndex             ; Out of range?
        bne     LoadMsg                 ; No, repeat loop

        clr     msgIndex                ; Reset to zero
        bra     LoadMsg                 ; Repeat loop

PauseExit:
;        move    #1,d0                   ; Wait for completion
;        jsr     CD_upaus                ; Unpause the CD

        move.l  pauseTime,joyTime       ; Reset joypas sample time
        move.l  pauseTime,time          ; Restore time

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

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

SetPath:
        move.l  playListEnt,pList       ; Initialize loader list pointer
        move    movieSelect,d0          ; Selection index
        lsl     #2,d0                   ; Index by longs
        move.l  pathTable(pc,d0),pPath  ; Set pointer to path
        bra.s   PauseExit               ; Exit from pause

pathTable:
        dc.l    movie1Path              ; Path for movie 1
        dc.l    movie2Path              ; Path for movie 2

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

EnterConfig:
        bsr     ClearJoy                ; Let joypad clear
        bsr     EraseSubtitle           ; Erase subtitle
        bsr     DoBlit                  ; Copy to display 1
        bsr     DoBlit                  ; Copy to display 2
        bsr     ConfigSys               ; Do system configuration

        tst     restoreFlag             ; Restore pending?
        beq.s   LoopReturn              ; No, return to loop

        bsr     SetContinue             ; Force continuation
        bra.s   PauseExit               ; Exit from pause

LoopReturn:
        clr     msgIndex                ; Reset message index
        bra     LoadMsg                 ; Jump back into loop

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

Resume:
        bsr     ClearJoy                ; Let joypad clear
        bsr     EraseSubtitle           ; Erase subtitle
        bsr     DoBlit                  ; Copy to display 1
        bsr     DoBlit                  ; Copy to display 2
        clr.l   joyRise                 ; Clear active key mask
        bra     PauseExit               ; Exit from pause

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

Remind:
        bsr     ClearJoy                ; Let joypad clear

        cmpi    #JUMP,jogMode           ; Jump ahead?
        beq.s   JumpAhead               ; Yes, do set up

        move.l  playListEnt,pList       ; Initialize loader list pointer
        move.l  #pathRecord,pPath       ; Where to start path record
        bra.s   RemindExit              ; Exit

JumpAhead:
        move.l  lastNode,pList          ; Initialize loader list pointer
        move.l  lastPath,pPath          ; Where to start path record

RemindExit:
        move    currFilm,pauseFilm      ; Remember film number
        move.l  frameNum,pauseFrame     ; Remember frame number
        move    #1,remind               ; Set remind flag
        move    #1,autoPilot            ; Set auto pilot flag
        bra     PauseExit               ; Exit from pause

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

Trap:
        bsr     EraseSubtitle           ; Erase subtitle
        bsr     DoBlit                  ; Copy to display 1
        bsr     DoBlit                  ; Copy to display 2
        bra     PauseExit               ; Exit from pause

;------------------------------------------------------------------------------
;                              ScanCodes
;------------------------------------------------------------------------------

STAR_POUND  .equ    (1<<bSTAR)+(1<<bPOUND)  ; Mask for */# key
MAX_DIGITS  .equ    5                       ; Maximum digits in code
N_MOVIES    .equ    2                       ; Number of canned movies

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

        bsr     SampleJoy               ; Get joypad sample
        btst.b  #bSCAN,joySemaphore     ; Semaphore set?
        beq     ScanExit                ; No, nothing to do

        bclr.b  #bSCAN,joySemaphore     ; Clear semaphore
        move.l  #STAR_POUND,d0          ; Mask for */#
        and.l   joyRise,d0              ; Did */# key go active?
        bne.s   InitScan                ; Yes, initialize code scan

        move.l  #STAR_POUND,d0          ; Mask for */#
        and.l   joyFall,d0              ; Did */# key go inactive?
        bne.s   EndScan                 ; Yes, end code scan

        tst     scanActive              ; Is scan in progress?
        beq     ScanExit                ; No, exit

; Scan joypad and store sampled value whenever a change is detected. Only
; the maximum number of digits is stored.

        tst.l   joyRise                 ; Any keys active?
        beq     ScanExit                ; No, exit

        move    scanCount,d0            ; Get scan count
        cmpi    #MAX_DIGITS,d0          ; Reached maximum?
        beq     ScanExit                ; Yes, exit

        lea     scanData,a0             ; Start of data array
        lsl     #2,d0                   ; Index by longs
        move.l  joySamp,0(a0,d0)        ; Read in joypad sample
        addq    #1,scanCount            ; Increment counter
        bra.s   ScanExit                ; Exit

; Initialize joypad scan: clear digit counter and data entry buffer, set
; active flag.

InitScan:
        clr     scanCount               ; Clear counter
        move    #1,scanActive           ; Set active flag
        lea     scanData,a0             ; Start of array
        move    #MAX_DIGITS-1,d0        ; Loop counter

ClearScan:
        clr.l   (a0)+                   ; Zero out element
        dbra    d0,ClearScan            ; Loop until done

        bra.s   ScanExit                ; Exit

; End joypad scan: clear active flag and attempt to match entry from joypad
; with parental control unlock code, or with one of the codes to select a
; canned movie. 

EndScan:
        clr     scanActive              ; Clear active flag

        lea     unlockCode,a0           ; Code to unlock parental control
        bsr     MatchCode               ; Try to match keypad input
        tst     d0                      ; Did we get a match?
        beq.s   TryMovies               ; No, try canned movies

        clr     minSex                  ; Clear minSex flag
        clr     minViolence             ; Clear minViolence flag
        bra.s   ScanExit                ; Exit

TryMovies:
        lea     movieCodes,a0           ; Start of movie codes
        clr     movieSelect             ; Clear select index

TryNextMovie:
        bsr     MatchCode               ; Try to match keypad input
        tst     d0                      ; Did we get a match?
        bne.s   GotMovie                ; Yes, set flag

        addq    #1,movieSelect          ; Increment select index
        cmpi    #N_MOVIES,movieSelect   ; Reached limit?
        beq.s   ScanExit                ; Yes, exit

        lea     4*MAX_DIGITS(a0),a0     ; Code for next movie
        bra.s   TryNextMovie            ; Try again

GotMovie:
        move    #1,vcrMode              ; Set flag
        move    #1,autoPilot            ; Set auto pilot flag

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

;------------------------------------------------------------------------------
;                               MatchCode
;------------------------------------------------------------------------------

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

        lea     scanData,a1             ; Array of scanned data
        move    #MAX_DIGITS-1,d0        ; Loop counter

MatchLoop:
        cmpm.l  (a0)+,(a1)+             ; Compare joypad data with digit
        bne.s   MatchFail               ; If unequal, match failed

        dbra    d0,MatchLoop            ; Loop until done

        move    #1,d0                   ; Match successful
        bra.s   MatchExit               ; Exit

MatchFail:
        clr     d0                      ; Match unsuccessful

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

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

; Code to unlock parental control: #13579

unlockCode:
        dc.l    (1<<bPOUND)+(1<<bONE)   ; #-1
        dc.l    (1<<bPOUND)+(1<<bTHREE) ; #-3
        dc.l    (1<<bPOUND)+(1<<bFIVE)  ; #-5
        dc.l    (1<<bPOUND)+(1<<bSEVEN) ; #-7
        dc.l    (1<<bPOUND)+(1<<bNINE)  ; #-9

movieCodes:

; Code to view movie #1: *01234

        dc.l    (1<<bSTAR)+(1<<bZERO)   ; *-0
        dc.l    (1<<bSTAR)+(1<<bONE)    ; *-1
        dc.l    (1<<bSTAR)+(1<<bTWO)    ; *-2
        dc.l    (1<<bSTAR)+(1<<bTHREE)  ; *-3
        dc.l    (1<<bSTAR)+(1<<bFOUR)   ; *-4

; Code to view movie #2: *98765

        dc.l    (1<<bSTAR)+(1<<bNINE)   ; *-9
        dc.l    (1<<bSTAR)+(1<<bEIGHT)  ; *-8
        dc.l    (1<<bSTAR)+(1<<bSEVEN)  ; *-7
        dc.l    (1<<bSTAR)+(1<<bSIX)    ; *-6
        dc.l    (1<<bSTAR)+(1<<bFIVE)   ; *-5

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

scanActive:     dc.w    0

msgTable:       dc.l    pauseMsg0
                dc.l    pauseMsg1
                dc.l    pauseMsg2

pauseMsg0:      dc.b    'PRESS OPTION FOR SETUPS...',0
pauseMsg1:      dc.b    'OR RIGHT FOR REMINDER...',0
pauseMsg2:      dc.b    'OR PAUSE TO RESUME',0

        .even

        .bss

scanData:       ds.l    5

msgIndex:       ds.w    1
pauseClear::    ds.w    1
restoreFlag::   ds.w    1
scanCount:      ds.w    1
movieSelect:    ds.w    1

;------------------------------------------------------------------------------
;   Declare externals and globals.
;------------------------------------------------------------------------------

        .extern autoPilot
        .extern CDReloadPtr
        .extern CDWritePtr
        .extern continue
        .extern contNode
        .extern contPath
        .extern contProfile
        .extern contScore
        .extern currFilm
        .extern fontColor
        .extern frameNum
        .extern gameOver
        .extern pPath
        .extern jogMode
        .extern joyFall
        .extern joyRise
        .extern joySamp
        .extern joySemaphore
        .extern joyTime
        .extern lastNode
        .extern lastPath
        .extern loadCtrl
        .extern minSex
        .extern minViolence
        .extern movie1Path
        .extern movie2Path
        .extern pathRecord
        .extern pauseFilm
        .extern pauseFrame
        .extern pauseTime
        .extern playback
        .extern playCtrl
        .extern playListEnt
        .extern playPhase
        .extern pList
        .extern profile
        .extern rdBeforeWr
        .extern remind
        .extern score
        .extern time
        .extern waitReload
        .extern vcrMode

        .extern ClearJoy
        .extern ClearOnScreen
        .extern ClearPause
        .extern ConfigSys
        .extern DoBlit
        .extern DrawSubtitle
        .extern EndPath
        .extern EraseSubtitle
        .extern GetAny
        .extern GetCDWritePtr
        .extern RecordEvent
        .extern SampleJoy
        .extern ResetPlaylist

