;;-----------------------------LICENSE NOTICE------------------------------------
;;  This file is part of Dragon Attack - An entry for CPCRetroDev2016
;;  Copyright (C) 2016  Paul Kooistra
;;
;;  This program is free software: you can redistribute it and/or modify
;;  it under the terms of the GNU General Public License as published by
;;  the Free Software Foundation, either version 3 of the License, or
;;  (at your option) any later version.
;;
;;  This program is distributed in the hope that it will be useful,
;;  but WITHOUT ANY WARRANTY; without even the implied warranty of
;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;  GNU General Public License for more details.
;;
;;  You should have received a copy of the GNU General Public License
;;  along with this program.  If not, see <http://www.gnu.org/licenses/>.
;;
;;  For questions about the source you can PM me, Axelay, on the CPCWiki forums
;;-------------------------------------------------------------------------------
; v4 adds dragon type var at start of round data list for different types of dragon
; v5 adds long dragons
.GetRoundData
; called to initiate a round, sets up sprite start positions, firing mode lists & round timer
; returns with a=0 if ok for next round, a/=0 if last round of game has been completed
    ld a,(Round)
    inc a
    cp a,13 ; last round plus 1
    ret nc ; returns with a /= 0, calling code will see game completed
; have got a new round to play, set it up
    ld (Round),a
; each round starts new music, but first round does not need to set it up, so skip if round 1
    cp a,1
    jr z,GRDNoNewMusic
    ld c,a
    ld a,(Lives)
    or a
    ld a,c
; also skip music start for round if player has died just before start of new round, want game over
; music to continue
    jr z,GRDNoNewMusic
    ld (Int4Game_MusicControl+1),a ; set the music trigger for this round
.GRDNoNewMusic
    dec a ; want lookup to start at 0
    push af ; save round number 0-11
; update the displayed round number on screen
    call UpdateRoundDisplay ; see DA_Display6.asm
; set tail trailing list for new boss, all tail offsets should be y=0 so remain hidden
    ld hl,TailYList
    ld de,TailYList+1
    ld (hl),0 ; start boss offscreen
    ld bc,&3f ;&1f
    ldir ; all tail 'previous y co-ords' set to 0
    pop af ; get round rumber back
    add a,a
    ld e,a
    ld d,0
    ld hl,EnemyRoundDataLU ; base of lookup table containing round data
    add hl,de ; hl now points to entry in lookup table for round data
    ld e,(hl)
    inc hl
    ld d,(hl)
    ex de,hl ; hl now points to beginning of this rounds data
; first byte is dragon type
    ld a,(hl)
    inc hl
    ld (DragonType),a
; according to dragon type, write pointer to head sprite used by move code
    or a
    jr z,GRDSetStdDragonPtr
    dec a
    jr z,GRDSetLongDragonPtr
; must be final dragon with multiple heads
    ld de,EnemyYX+6
    jr GRDSetDragonPtrCommon
.GRDSetLongDragonPtr
    ld de,EnemyYX+16
    jr GRDSetDragonPtrCommon
.GRDSetStdDragonPtr
    ld de,EnemyYX+8
.GRDSetDragonPtrCommon
    ld (DragonHeadPtr),de ; used by collision code for destroying this dragons 'core' - head, in other words
; next part is boss tables, set of 3 18 byte tables
; first list is x co-ord offset from random base, 192 indicates this sprite remains offscreen
    ld de,EnemyYX ; set de to start of first table, format = y,x
    call cpct_getRandom_lcg_u8_asm ; get random base x in a, see CPCtelera_random_mod.asm
    and a,&1f ; random number 0-31
    add a,46 ; centre the random starting position so it is 46-77
    ld c,a ; save core start position in c
    ld b,9
    ex de,hl ; put lookup table in de, yx table in hl for this next loop
.EnemyTable1Lp
    ld (hl),0 ; y start is always 0, regardless of active sprite or not
    inc l
    ld a,(de)
    inc de ; point to next x offset
    cp a,192 ; check if this sprite active for this boss
    jr z,EnemyXOffscreen ; this sprite remains offscreen, dont add offset
    add a,c ; add core starting position to offset
.EnemyXOffscreen
    ld (hl),a ; write x for this sprite
    inc l
    djnz EnemyTable1Lp
    ex de,hl ; put source list back into hl
    ld de,EnemyYX+&20 ; de points to second boss sprite data list, contains state, hits
    ld bc,18
    ldir
    ld de,EnemyYX+&40 ; de points to third boss sprite data list, contains frame, score
    ld bc,18
    ldir
; next step is to set up fire list table, 4 lists of up to 32 bytes of firing
    ld de,FireSeqTable
    ld b,4
.FireSeqOuterLp
    ld a,(hl) ; get length of this sequence
    ld c,a ; put length for first loop in c
    inc hl
    ex af,af' ; preserve a
.FireSeqInner1Lp
    ld a,(hl)
    inc hl ; move pointer to round data
    ld (de),a
    inc e ; move pointer to fire list - is page aligned so only 8 bit inc
    dec c
    jr nz,FireSeqInner1Lp
    ex af,af' ; get back a
; have written fire data, now zero rest of list, must pad it out to 32 bytes in length
    ld c,a ; save length
    ld a,32
    sub a,c ; now have length of blank space after list
    ld c,a ; put in c for next loop
    xor a ; 0 is used by fire check code to determine when fire sequence list has come to end
.FireSeqInner2Lp
    ld (de),a
    inc e
    dec c
    jr nz,FireSeqInner2Lp
    djnz FireSeqOuterLp
; have now written all 4 fire sequence lists, padded out to 32 bytes each
; get boss x move limits, the early smaller bosses and snakes have different x limits to the standard bosses
    ld a,(hl)
    ld (BossXLimits),a ; left boss x limit
    inc hl
    ld a,(hl)
    ld (BossXLimits+1),a ; right boss x limit
    inc hl
; get boss colours
    ld de,BossColours
    ldi
    ldi ; first two colours will be set by interrupt, this is colours 2 & 3
; next 2 colours not changed under interrupt
    ld a,(hl)
    inc hl
    ld bc,&7f06
    out (c),c ; point to colour 6
    out (c),a ; set colour 6
    ld a,(hl)
    inc hl
    inc c
    out (c),c ; point to colour 7
    out (c),a ; set colour 7
; get round time and set timers
    ld a,(hl)
    ld (RoundTime),a ; set seconds
    ld a,50
    ld (Round50sec),a ; set 50ths of a second
; set initial boss move
    ld hl,BossMvY
    ld (hl),64 ; boss starts with slow move down in y
    xor a
    inc l
    ld (hl),a ; Bossysp
    inc l
    ld (hl),a ; BossMvX initially no x move
    inc l
    ld (hl),a ; Bossxsp
; clear dragon leaving trigger
    ld (DragonLeaving),a
; if long dragon type, set tailxlist to current x
    ld a,(DragonType)
    cp a,1
    jr nz,GRDNoTailXReqd
; set tail x list to match current head x for long serpent style dragons
    ld a,(EnemyYX+17) ; get head of serpent dragon x co-ord
    ld hl,TailXList
    ld de,TailXList+1
    ld (hl),a
    ld bc,&7f ; have a 128 byte previous x list for serpent dragons so tail can follow in x co-ord
    ldir
.GRDNoTailXReqd
; set a=0 for round good to go and return
    xor a ; required so calling routine knows another round is commencing
    ret

.EnemyRoundDataLU
    defw Round1
    defw Round2
    defw Round3
    defw Round4
    defw Round5
    defw Round6
    defw Round7
    defw Round8
    defw Round9
    defw Round10
    defw Round11
    defw Round12

.Round1
; dragon type
    defb 0
; first list is x offset from core, or 192 if off screen
    defb 192,192,192,-8,0,8,192,192,192
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
;    defb 128,0,128,0,128,0,0,8,0,16,0,8,128,0,128,0,128,0
    defb 128,0,128,0,128,0,0,16,0,32,0,16,128,0,128,0,128,0
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 0,1,0,1,0,1,0,1,12,2,0,1,0,1,0,1,0,1
; first fire sequence
    defb 5 ; number of bytes in list
    defb 2,&20+6,5,20,11
; second fire sequence
    defb 5 ; number of bytes in list
    defb 1,&20+8,16,-8,128
; third fire sequence
    defb 5 ; number of bytes in list
    defb 2,&20+10,15,20,11
; fourth fire sequence
    defb 1 ; number of bytes in list
    defb 0 ; dummy, is not used, but 0 length lists not checked for
; boss x limits, left, then right
    defb 33-24,89+24
; the dragon colours this round
    defb &4e,&44,&5f,&5b ; blue with orange
; finally, round time in seconds
    defb 30
.Round2
; dragon type
    defb 0
; first list is x offset from core, or 192 if off screen
    defb 192,192,-16,-8,0,8,16,192,192
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
;    defb 128,0,128,0,0,12,0,20,0,32,0,20,0,12,128,0,128,0
    defb 128,0,128,0,0,16,0,24,0,48,0,24,0,16,128,0,128,0
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 0,1,0,1,0,1,2,2,12,3,2,2,0,1,0,1,0,1
; first fire sequence
    defb 5 ; number of bytes in list
    defb 2,&20+6,6,20,11
; second fire sequence
    defb 10 ; number of bytes in list
    defb 2,&20+12,1,20,11,1,&20+8,16,-8,128
; third fire sequence
    defb 5 ; number of bytes in list
    defb 2,&20+10,16,20,11
; fourth fire sequence
    defb 5 ; number of bytes in list
    defb 2,&20+4,11,20,11
; boss x limits, left, then right
    defb 33-16,89+16
; the dragon colours this round
    defb &5f,&44,&5e,&59 ; green with blue
; finally, round time in seconds
    defb 40
.Round3
; dragon type
    defb 0
; first list is x offset from core, or 192 if off screen
    defb 192,-24,-16,-8,0,8,16,24,192
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
;    defb 128,0,0,16,0,20,0,28,0,48,0,28,0,20,0,16,128,0
    defb 128,0,0,16,0,20,0,28,0,56,0,28,0,20,0,16,128,0
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 0,1,0,1,2,1,4,2,12,4,4,2,2,1,0,1,0,1
; first fire sequence
    defb 10 ; number of bytes in list
    defb 2,&20+2,6,20,11,1,&20+6,11,8,64
; second fire sequence
    defb 10 ; number of bytes in list
    defb 2,&20+12,1,20,11,1,&20+8,16,-8,128
; third fire sequence
    defb 10 ; number of bytes in list
    defb 2,&20+14,16,20,11,1,&20+10,11,-8,192
; fourth fire sequence
    defb 5 ; number of bytes in list
    defb 2,&20+4,11,20,11
; boss x limits, left, then right
    defb 33-8,89+8
; the dragon colours this round
    defb &47,&44,&5d,&5f  ; mauve with pink
; finally, round time in seconds
    defb 50
.Round4
; dragon type
    defb 1
; first list is x offset from core, or 192 if off screen
    defb 192,192,192,0,0,0,0,0,0
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
    defb 128,0,128,0,128,0,0,40,0,28,0,28,0,36,0,36,0,64
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 0,1,0,1,0,1,8,3,4,2,0,2,4,3,0,3,18,4
; first fire sequence
    defb 10 ; number of bytes in list
    defb 2,&20+6,6,20,14,1,&20+12,11,8,64
; second fire sequence
    defb 15 ; number of bytes in list
    defb 2,&20+6,1,20,14,1,&20+16,16,-8,128,1,&20+8,11,8,0
; third fire sequence
    defb 10 ; number of bytes in list
    defb 2,&20+6,16,20,14,1,&20+14,11,-8,192
; fourth fire sequence
    defb 10 ; number of bytes in list
    defb 2,&20+6,11,20,14,1,&20+10,11,-8,0
; boss x limits, left, then right
    defb 33-32,89+32
; the dragon colours this round
    defb &5f,&44,&46,&5b ; light blue
; finally, round time in seconds
    defb 50
.Round5
; dragon type
    defb 0
; first list is x offset from core, or 192 if off screen
    defb -32,-24,-16,-8,0,8,16,24,32
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
    defb 0,24,0,32,0,40,0,48,0,80,0,48,0,40,0,32,0,24
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 8,2,2,2,4,3,0,3,14,5,0,3,4,3,2,2,8,2
; first fire sequence
    defb 15 ; number of bytes in list
    defb 2,&20+0,6,20,11,1,&20+6,11,8,64,1,&20+2,11,8,192
; second fire sequence
    defb 15 ; number of bytes in list
    defb 2,&20+0,1,20,11,1,&20+8,16,-8,128,1,&20+4,11,8,0
; third fire sequence
    defb 15 ; number of bytes in list
    defb 2,&20+16,16,20,11,1,&20+10,11,-8,192,1,&20+8,16,8,128
; fourth fire sequence
    defb 15 ; number of bytes in list
    defb 2,&20+16,11,20,11,1,&20+12,11,-8,0,1,&20+14,11,-8,64
; boss x limits, left, then right
    defb 33,89
; the dragon colours this round
    defb &5f,&44,&47,&43 ; pink with mauve
; finally, round time in seconds
    defb 60
.Round6
; dragon type
    defb 0
; first list is x offset from core, or 192 if off screen
    defb -32,-24,-16,-8,0,8,16,24,32
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
    defb 0,24,0,32,0,48,0,56,0,96,0,56,0,48,0,32,0,24
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 0,2,4,2,8,3,2,4,14,6,2,4,8,3,4,2,0,2
; first fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+0,11,8,64,1,&20+16,11,-8,192,7
; second fire sequence
    defb 15 ; number of bytes in list
    defb 1,&20+2,11,-8,128,1,&20+14,11,8,128,3,&20+8,24,24,8
; third fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+4,11,8,192,1,&20+12,11,-8,64,9
; fourth fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+6,11,-8,0,1,&20+10,11,8,0,10
; boss x limits, left, then right
    defb 33,89
; the dragon colours this round
    defb &4e,&44,&5f,&5b ; blue with orange
; finally, round time in seconds
    defb 65
.Round7
; dragon type
    defb 1
; first list is x offset from core, or 192 if off screen
    defb 192,192,0,0,0,0,0,0,0
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
    defb 128,0,128,0,0,48,0,32,0,32,0,48,0,48,0,60,0,112
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 0,1,0,1,10,3,2,2,8,2,0,3,8,3,4,4,18,7
; first fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+12,14,-8,64,1,&20+16,11,8,192,7
; second fire sequence
    defb 16 ; number of bytes in list
    defb 1,&20+8,14,8,128,1,&20+14,11,-8,128,6,&20+16,16,4,128,8
; third fire sequence
    defb 9 ; number of bytes in list
    defb 3,&20+4,20,20,3,&20+4,10,20,9
; fourth fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+6,11,8,0,1,&20+10,11,-8,0,10
; boss x limits, left, then right
    defb 33-32,89+32
; the dragon colours this round
    defb &4e,&44,&4c,&43 ; red
; finally, round time in seconds
    defb 70
.Round8
; dragon type
    defb 0
; first list is x offset from core, or 192 if off screen
    defb -32,-24,-16,-8,0,8,16,24,32
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
    defb 0,24,0,32,0,48,0,64,0,128,0,64,0,48,0,32,0,24
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 2,2,10,2,4,3,8,4,14,8,8,4,4,3,10,2,2,2
; first fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+0,11,-8,64,1,&20+16,11,8,192,7
; second fire sequence
    defb 15 ; number of bytes in list
    defb 1,&20+4,11,8,64,1,&20+12,11,-8,192,5,&20+8,3,7,8
; third fire sequence
    defb 9 ; number of bytes in list
    defb 3,&20+2,18,18,3,&20+14,9,18,9
; fourth fire sequence
    defb 11 ; number of bytes in list
    defb 6,&20+6,11,4,64,6,&20+10,11,-4,192,10
; boss x limits, left, then right
    defb 33,89
; the dragon colours this round
    defb &5f,&44,&5e,&59 ; green with blue
; finally, round time in seconds
    defb 75
.Round9
; dragon type
    defb 0
; first list is x offset from core, or 192 if off screen
    defb -32,-24,-16,-8,0,8,16,24,32
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
    defb 0,24,0,32,0,54,0,72,0,144,0,72,0,54,0,32,0,24
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 8,2,10,2,0,4,6,5,16,9,6,5,0,4,10,2,8,2
; first fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+0,14,8,64,1,&20+16,14,-8,192,7
; second fire sequence
    defb 15 ; number of bytes in list
    defb 1,&20+4,11,-8,128,1,&20+12,11,8,128,5,&20+6,3,6,8
; third fire sequence
    defb 9 ; number of bytes in list
    defb 3,&20+2,16,16,3,&20+14,8,16,9
; fourth fire sequence
    defb 15 ; number of bytes in list
    defb 1,&20+8,16,8,64,1,&20+8,16,-8,192,5,&20+10,6,6,10
; boss x limits, left, then right
    defb 33,89
; the dragon colours this round
    defb &47,&44,&5d,&5f ; mauve with pink
; finally, round time in seconds
    defb 80
.Round10
; dragon type
    defb 1
; first list is x offset from core, or 192 if off screen
    defb 192,0,0,0,0,0,0,0,0
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
    defb 128,0,0,48,0,24,0,32,0,48,0,56,0,60,0,80,0,160
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 0,1,6,3,8,2,10,2,8,3,10,4,8,4,10,5,18,10
; first fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+8,14,8,128,1,&20+10,14,-8,128,7
; second fire sequence
    defb 15 ; number of bytes in list
    defb 5,&20+2,3,6,1,&20+4,14,-8,64,1,&20+12,14,8,192,8
; third fire sequence
    defb 11 ; number of bytes in list
    defb 6,&20+6,14,4,64,6,&20+14,14,-4,192,9
; fourth fire sequence
    defb 9 ; number of bytes in list
    defb 4,&20+16,12,24,5,&20+2,6,6,10
; boss x limits, left, then right
    defb 33-32,89+32
; the dragon colours this round
    defb &5f,&44,&47,&43 ; pink with mauve
; finally, round time in seconds
    defb 85
.Round11
; dragon type
    defb 0
; first list is x offset from core, or 192 if off screen
    defb -32,-24,-16,-8,0,8,16,24,32
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
    defb 0,24,0,32,0,64,0,96,0,192,0,96,0,64,0,32,0,24
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 8,2,8,2,10,4,6,6,16,12,6,6,10,4,8,2,8,2
; first fire sequence
    defb 11 ; number of bytes in list
    defb 1,&20+0,14,8,0,1,&20+16,14,-8,0,7
; second fire sequence
    defb 13 ; number of bytes in list
    defb 4,&20+4,10,20,4,&20+12,20,20,5,&20+6,3,6,8
; third fire sequence
    defb 11 ; number of bytes in list
    defb 6,&20+2,14,4,128,6,&20+14,14,-4,128,9
; fourth fire sequence
    defb 15 ; number of bytes in list
    defb 6,&20+8,16,4,64,6,&20+8,16,-4,192,5,&20+10,6,6,10
; boss x limits, left, then right
    defb 33,89
; the dragon colours this round
    defb &5f,&44,&46,&5b ; light blue
; finally, round time in seconds
    defb 90
.Round12
; dragon type
    defb 2
; first list is x offset from core, or 128 if off screen
    defb -32,-24,-16,-8,0,8,16,24,32
; second list is state, hits - state is either 128 if offscreen, or 0 if on screen
; final boss is special, bit 7+5 of invulnerable heads set true to start with
    defb 0,48,0,72,0,128,128+32+0,255,0,255,128+32+0,255,0,128,0,72,0,48
;    defb 0,48,0,72,0,128,128+32+0,0,0,0,128+32+0,0,0,128,0,72,0,48 ; test data for final boss with 1 hit
; third list is frame, score - frame is multiple of 2, total score not to exceed 61
    defb 8,3,10,5,6,8,16,9,20,9,16,9,6,8,10,5,8,3
; first fire sequence
    defb 15 ; number of bytes in list
    defb 5,&20+4,2,5,1,&20+0,14,8,0,1,&20+16,14,-8,0,7
; second fire sequence
    defb 16 ;5 ; number of bytes in list
    defb 6,&20+2,14,4,64,6,&20+14,14,-4,192,1,&20+4,14,8,128,8 ;4,&20+8,8,16,8
; third fire sequence
    defb 15 ; number of bytes in list
.Round12Centre
    defb 5,&20+12,4,5,6,&20+8,16,8,128,6,&20+8,16,-8,128,9
; fourth fire sequence
    defb 16 ;5 ; number of bytes in list
    defb 1,&20+2,14,-8,64,1,&20+14,14,8,192,1,&20+12,14,-8,128,10 ;3,&20+8,16,16,10
; boss x limits, left, then right
    defb 33-8,89-8
; the dragon colours this round
    defb &4e,&44,&4c,&43 ; red
; finally, round time in seconds
    defb 99
.Round12Left
    defb 4,&20+6,4,8,1,&20+6,16,-8,128,9,0
.Round12Right
    defb 3,&20+10,4,8,1,&20+10,16,8,128,9,0
