;-----------------------------------------------------------;
;                                                           ;
; Invaded                                                   ;
; Version 1.0                                               ;
; Bullet Routines for enemies                               ;
;                                                           ;
;-----------------------------------------------------------;

;------------------------------------------------
; clearEBulletArray - Clear eBulletArray
;
; Input:    None
; Output:   None
;------------------------------------------------
clearEBulletArray:
        ld      hl,eBulletArray
        ld      de,eBulletArray+1
        ld      bc,MAX_EBULLETS*4-1
        ld      (hl),0
        ldir
        ret

;------------------------------------------------
; newEBullet - Add a new enemy bullet
;
; Input:    IX => Enemy entry in enemyArray
;           B = Type
;           C = 255 to calculate angle, other equals direction to set bullet to
; Output:   None
;------------------------------------------------
newEBullet:
        push    bc
        ld      hl,eBulletArray
        ld      de,4
        ld      b,MAX_EBULLETS
findEmptyEBulletEntry:
        ld      a,(hl)
        or      a
        jr      z,eBulletEntryFound
        add     hl,de
        djnz    findEmptyEBulletEntry
        pop     bc
        ret
eBulletEntryFound:
        pop     bc
        inc     c
        jp      nz,newEBulletSpecifyAngle
        push    bc
        push    hl
        ld      bc,0                            ; B = Offset to direction, we need C to be 0 for after
        ld      a,(y)                           ; A = PY
        sub     (ix+E_Y)                        ; A = PY - EY
        jr      z,eBulletHorizontal             ; If PY = EY, bullet will be moving horizontal
        jr      nc,pyeyPos
        neg
        ld      c,6
pyeyPos:
        ld      l,a
        ld      h,b                             ; HL = Abs(PY - EY)
        ld      a,b
        add     a,c
        ld      b,a                             ; B = Offset to direction
        push    hl
        ld      a,(pScreenX)                    ; A = PX
        pop     hl
        sub     (ix+E_X)                        ; A = PX - EX
        jr      z,eBulletVertical               ; If PX = EX, bullet will be moving vertical
        ld      c,0
        jr      nc,pxexPos
        neg
        ld      c,3
pxexPos:
        ld      d,a
        ld      a,b
        add     a,c
        ld      b,a                             ; B = Offset to direction
        ld      a,d                             ; A = Abs(PX - EX)
        bcall(_divhlbya)                        ; HL = Abs(PY - EY) / Abs(PX - EX)
        ld      a,l
        cp      3
        jr      c,eBulletNoSet2
        ld      a,2
eBulletNoSet2:
        ld      c,a                             ; C = 0, 1 or 2
        ld      a,b
        or      a
        jr      z,eBulletModGradient
        cp      9
        jr      nz,eBulletAfterModGradient
eBulletModGradient:
        bit     0,c                             ; Does C = 1?
        jr      nz,eBulletAfterModGradient      ; If so, don't toggle bit 1
        ld      b,a
        ld      a,c
        xor     $02
        ld      c,a
        ld      a,b
eBulletAfterModGradient:
        add     a,c
makeEBullet:
        pop     hl                              ; HL => Entry to use
        pop     bc                              ; B = Type
makeEBullet2:
        push    af
        ld      (hl),b
        inc     hl
        ex      de,hl                           ; DE => Where to store X Coord
        ld      c,b
        dec     c
        ld      b,0
        ld      hl,newEBulletXOffsetTable
        add     hl,bc
        ld      a,(hl)
        add     a,(ix+E_X)
        ld      (de),a
        inc     de                              ; DE => Where to store Y Coord
        ld      hl,newEBulletYOffsetTable
        add     hl,bc
        ld      a,(hl)
        add     a,(ix+E_Y)
        ld      (de),a
        inc     de
        pop     af
        ld      (de),a
        ret
eBulletHorizontal:
        ld      a,(pScreenX)
        sub     (ix+E_X)
        ld      a,14
        jr      c,makeEBullet
        inc     a
        jr      makeEBullet
eBulletVertical:
        ld      a,(y)
        sub     (ix+E_Y)
        ld      a,12
        jr      c,makeEBullet
        inc     a
        jr      makeEBullet
newEBulletSpecifyAngle:
        dec     c
        ld      a,c
        jr      makeEBullet2

;------------------------------------------------
; drawEBullets - Draw/Erase enemy bullets
;
; Input:    None
; Output:   None
;------------------------------------------------
drawEBullets:
        ld      hl,eBulletArray                 ; HL => Start of eBulletArray
        ld      b,MAX_EBULLETS                  ; B = Number of entries
drawEBulletsLoop:
        push    bc
        push    hl
        ld      a,(hl)
        or      a                               ; Is there a bullet in this entry?
        jr      z,endDrawEBulletsLoop           ; If not, try next entry
        ex      de,hl                           ; DE => Entry in eBulletArray
        ld      l,a
        dec     l
        ld      h,0                             ; HL = Type-1
        add     hl,hl
        add     hl,hl
        add     hl,hl                           ; HL = Offset to sprite
        ex      de,hl                           ; DE = Offset to sprite, HL => Entry in eBulletArray
        inc     hl
        ld      a,(hl)                          ; A = XCoord
        inc     hl
        ld      l,(hl)                          ; L = YCoord
        ld      ix,sprEBullets                  ; IX => Start of enemy bullet sprites
        add     ix,de                           ; IX => Sprite to show
#ifndef MIRAGE
        ld      b,8                             ; B = 8 rows of sprite to show
        call    ionPutSprite                    ; Draw bullet
#else
        call    putSprite8                      ; Draw bullet
#endif
endDrawEBulletsLoop:
        pop     hl                              ; HL => Start of current entry
        pop     bc                              ; B = Counter
        ld      de,4
        add     hl,de                           ; HL => Next entry
        djnz    drawEBulletsLoop                ; Repeat until finished
        ret

;------------------------------------------------
; moveEBullets - Move enemy bullets
;
; Input:    None
; Output:   None
;------------------------------------------------
moveEBullets:
        ld      a,(frame)
        and     $01
        ret     nz                              ; Only update every 2nd frame
        ld      hl,eBulletArray
        ld      b,MAX_EBULLETS
        jp      doMoveBullets

;------------------------------------------------
; checkEBulletsOnScreen - Check to make sure all enemy bullets are still on screen
;
; Input:    None
; Output:   None
;------------------------------------------------
checkEBulletsOnScreen:
        ld      hl,eBulletArray
        ld      b,MAX_EBULLETS
        jp      doCheckBulletsOnScreen

;------------------------------------------------
; checkEBulletsHitSolid - Check to see if any enemy bullets are hitting a solid tile
;
; Input:    None
; Output:   None
;------------------------------------------------
checkEBulletsHitSolid:
        ld      hl,eBulletArray
        ld      bc,MAX_EBULLETS*256+1
        ld      de,eBulletCenterX
        ld      ix,eBulletCenterY
        jp      doCheckBulletsHitSolid

;------------------------------------------------
; Enemy Bullet Types
;------------------------------------------------
; 1.  Normal bullet
; 2.  Large beam power bullet
; 3.  Powerball bullet
; 4.  Bullet that goes through walls
; 5.  Twin Laser bullet
;------------------------------------------------

.end
