;-----------------------------------------------------------;
;                                                           ;
; Invaded                                                   ;
; Version 1.0                                               ;
;                                                           ;
; Copyright (c)2000-2001 TI-Calculator Programming Alliance ;
; Written and Programmed by James Vernon <james@calc.org>   ;
; ICQ#: 71589304                                            ;
; http://tcpa.calc.org                                      ;
;                                                           ;
; You may use parts of this program as long as you give me  ;
; credit. You are not allowed to release a modified version ;
; of this program or the code without my permission!        ;
;                                                           ;
;-----------------------------------------------------------;

;------------------------------------------------
; TI-83+ Ion Header
;------------------------------------------------
#ifdef TI83P
#include "ion.inc"

.org    progstart-2
.db     $BB,$6D
tempMem                 = $9820
_enoughmem              = $42FD
enemyData               = appbackupscreen

        ret
        jr      nc,start
#endif

;------------------------------------------------
; TI-83+ MirageOS Header
;------------------------------------------------
#ifdef MIRAGE
#include "ti83plus.inc"
#include "mirage.inc"

.org    $9D93
.db     $BB,$6D
#define bcall(_htimesl) call multhl
ionDetect               = iDetect
ionFastCopy             = iFastCopy
ionGetPixel             = iGetPix
ionPutSprite            = iSprite
ionRandom               = iRandom
vat                     = progPtr
enemyData               = appbackupscreen

        ret
.db     1

.db %00000000, %00000000
.db %01111111, %11111100
.db %01000000, %00000100
.db %01000000, %00000100
.db %01000000, %00000100
.db %01001111, %10000100
.db %01011110, %01000100
.db %01011111, %11100100
.db %01001001, %10000100
.db %01000000, %00000100
.db %01000000, %00000100
.db %01000000, %00000100
.db %01000000, %00000100
.db %01111111, %11111100
.db %00000000, %00000000
#endif

;------------------------------------------------
; TI-83 Ion Header
;------------------------------------------------
#ifdef TI83
#include "ion.inc"

.org    progstart
enemyData               = saferam2

        ret
        jr      nc,start
#endif

;------------------------------------------------
; Variable Declarations, Constants, etc.
;------------------------------------------------
#include "vars.asm"

;------------------------------------------------
; GET_KEY equates
;------------------------------------------------
#include "get_key.inc"

;------------------------------------------------
; Direct Input equates
;------------------------------------------------
#include "directin.inc"

;------------------------------------------------
; Description
;------------------------------------------------
.db     "Invaded v",verMajor,".",verMinor," - TCPA",0

;------------------------------------------------
; Start of Program
;------------------------------------------------
start:
        ld      hl,gbuf+768                     ; We're going to copy the system pointers located
        ld      de,systemPointers               ; after gbuf to a safe place so we can have a 1024
        ld      bc,256                          ; byte long block to use with Huffman Decompression
        ldir
#ifndef TI83
        ld      hl,MEM_NEEDED                   ; HL = Free memory needed
        bcall(_enoughmem)                       ; Check to see if there's enough
        jr      nc,memOK                        ; If so, don't quit
#else
        bcall(_memfree)                         ; HL = Free memory available
        ld      de,MEM_NEEDED+10                ; DE = Free memory needed
        sbc     hl,de                           ; Is there enough?
        jr      nc,memOK                        ; If so, don't quit
#endif
quit:
        ld      hl,systemPointers
        ld      de,gbuf+768
        ld      bc,256
        ldir                                    ; Copy system pointers back to original location
        res     textwrite,(iy+sgrflags)         ; Write with _vputs to lcd
#ifdef TI83
        set     statsvalid,(iy+statflags)       ; Finished with statvars
checkTempFile:
        ld      hl,tempFileName                 ; HL => Name of temp program
        rst     20h                             ; Copy 9 bytes from (HL) to (Op1)
        bcall(_chkfindsym)                      ; Look up program
        bcallnc(_delvar)                        ; If it exists, delete it!
#endif
        ret
memOK:
#ifdef TI83                                     ; TI-83 needs to create a temp file
        call    checkTempFile                   ; Check to see if temp program already exists, if it does, delete it
        ld      hl,MEM_NEEDED                   ; HL = Size of temp file to create
        bcall(_createprog)                      ; Create temp program
        inc     de
        inc     de                              ; DE => Start of temp program data
        ld      (tempMem),de                    ; Save pointer
        res     statsvalid,(iy+statflags)       ; TI-83 uses here
#endif
        set     apdable,(iy+apdflags)           ; We'll be using APD
        set     textwrite,(iy+sgrflags)         ; Write with _vputs to gbuf
        xor     a                               ; Initialise vars, A = 0
        ld      (menuItem),a                    ; Reset menuItem
        inc     a                               ; A = 1
        ld      (speed),a                       ; Set speed to 1 (NORMAL)

startVAT:
        ld      hl,(vat)                        ; HL => Start of VAT
        ld      (vatPtr),hl                     ; Save pointer
        xor     a
        ld      (noLevelsets),a                 ; Reset noLevelsets
        ld      (levelsetName),a                ; Clear levelsetName

levelsetSearch:
        ld      ix,strSearch                    ; IX => Search string
        call    ionDetect                       ; Look up a valid Levelset
        jp      z,levelsetFound                 ; If one is found, go check it out
levelsetNotFound:
        ld      a,(noLevelsets)                 ; A = Number of Levelsets found
        or      a                               ; Were any found?
        jr      z,quit                          ; If not, we can't play, so quit :(
        jr      startVAT                        ; Otherwise, return to the start of the VAT

menuLoop:
        bcall(_grbufclr)                        ; Clear gbuf

        ld      a,(speed)                       ; A = Speed
        add     a,2
        ld      (_speed),a                      ; Set speed in main loop

        ld      hl,titlePic                     ; HL => Picture data
        ld      de,gbuf+(2*12)                  ; DE => Where to copy it to
        ld      bc,12*12                        ; BC = Number of bytes to copy
        ldir                                    ; Copy title picture to gbuf
        ld      de,18*256+21                    ; DE = Coords to display text
        ld      hl,strMenu                      ; HL => String to display
        call    vPuts                           ; "By James Vernon"
        ld      de,29*256+2
        call    vPuts                           ; "START GAME"
        ld      de,37*256+2
        call    vPuts                           ; "LEVELSET"
        ld      de,45*256+2
        call    vPuts                           ; "GAME SPEED"
        ld      de,53*256+2
        call    vPuts                           ; "QUIT"

        ld      hl,(speed)
        ld      h,0
        add     hl,hl                           ; HL = 2 * speed
        ld      de,speedTable
        add     hl,de                           ; HL => Pointer to string to show
        bcall(_ldhlind)                         ; HL => String to show
        ld      d,45                            ; D = Y coord of where to show string
        ld      e,(hl)                          ; E = X coord of where to show string
        inc     hl                              ; HL => Actual string
        call    vPuts                           ; Show speed

        ld      hl,levelsetName                 ; HL => Levelset name
        ld      de,37*256+75
        call    vPuts                           ; Show levelset name

        ld      hl,(menuItem)                   ; L = menuItem
        ld      h,8*12                          ; 8 rows * 12 columns to skip per menuItem
        bcall(_htimesl)                         ; HL = 96 * menuItem (offset)
        ld      de,gbuf+(29*12)                 ; DE => First menuItem on buffer
        add     hl,de                           ; HL => Where to start inverting
        ld      bc,7*12                         ; 7 rows * 12 columns to invert
        call    invertArea                      ; Invert selected option
        call    ionFastCopy                     ; Copy gbuf to lcd
        ei

        bcall(GET_KEY)
        ld      hl,menuItem
        cp      GK_UP                           ; [Up]
        jr      z,menuUp
        cp      GK_DOWN                         ; [Down]
        jr      z,menuDown
        cp      GK_2ND                          ; [2nd]
        jr      nz,menuLoop

menuDone:
        ld      a,(hl)
        or      a                               ; Was START GAME selected?
        jp      z,newGame
        dec     a                               ; Was LEVELSET selected?
        jp      z,nextLevelset
        dec     a                               ; Was GAME SPEED selected?
        jr      z,changeSpeed
        jp      quit                            ; Otherwise, QUIT was selected
changeSpeed:
        ld      hl,speed                        ; HL => Speed level
        dec     (hl)                            ; Increase the speed (by decreasing the value ;)
        ld      a,(hl)                          ; A = New speed
        cp      255                             ; Did we decrement past 0?
        jp      nz,menuLoop                     ; If not, the new speed is valid
        ld      (hl),2                          ; Otherwise, set the speed to SLOW
        jp      menuLoop

menuUp:
        ld      a,(hl)                          ; A = menuItem
        or      a                               ; Is it 0?
        jr      nz,menuUpSkip                   ; If not, don't set it to 3
        ld      a,MENU_MAX
menuUpSkip:
        dec     a                               ; Decrement menu selection
        ld      (hl),a                          ; Save it
        jp      menuLoop

menuDown:                                       ; Similar to menuUp
        ld      a,(hl)
        cp      MENU_MAX-1
        jr      nz,menuDownSkip
        ld      a,-1
menuDownSkip:
        inc     a
        ld      (hl),a
        jp      menuLoop

levelsetFound:
        ld      (vatPtr),de                     ; DE => Where we're up to in VAT
        ld      de,levelsetName                 ; DE => Where to store Levelset name
        ld      bc,5                            ; BC = 5 chars to save
        ldir                                    ; Save Levelset name
        xor     a
        ld      (de),a                          ; Save NULL terminator
        ld      (dataPtr),hl                    ; HL => Levelset data
#ifndef TI83
        ld      ix,(vatPtr)                     ; IX => Next entry in VAT
        ld      a,(ix+10)                       ; A = ROM page Levelset is located on
        or      a                               ; Is Levelset in RAM?
        jp      nz,levelsetNotFound             ; If not, invalid
#endif
        inc     hl
        inc     hl
        inc     hl
        inc     hl                              ; HL => Name of required Tileset
        ld      de,strTileSearchInsert          ; DE => Where to copy name to for search
        ld      bc,5                            ; BC = 5 chars to copy
        ldir                                    ; Copy Tileset name into search string
        ld      hl,(vat)                        ; HL => Start of VAT
        ld      ix,strTileSearch                ; IX => Search string
        call    ionDetect                       ; Look up Tileset file
        jp      nz,levelsetNotFound             ; If not found, can't play this Levelset
        inc     hl                              ; HL => Number where solid tiles begin
        ld      a,(hl)
        ld      (solidTiles),a                  ; Save this number
        inc     hl                              ; HL => Number where hurty tiles begin
        ld      a,(hl)
        ld      (hurtyTiles),a                  ; Save this number too
        inc     hl                              ; HL => Actual tile data
        ld      (tileData),hl                   ; Save pointer
#ifndef TI83
        ld      hl,10
        add     hl,de                           ; HL => ROM page Tileset is located on
        ld      a,(hl)                          ; A = ROM page Tileset is located on
        or      a                               ; Is Tileset in RAM?
        jp      nz,levelsetNotFound             ; If not, can't play this Levelset
#endif
        ld      hl,noLevelsets
        inc     (hl)                            ; Increment level counter
        jp      menuLoop

nextLevelset:
        ld      hl,(vatPtr)                     ; HL => Where we're up to in the VAT
        jp      levelsetSearch                  ; Search for another Levelset

;------------------------------------------------
; All other source files
;------------------------------------------------
#include "anim.asm"                             ; Explosion Animation Routines
#define ASCR_BOTCLIP 56                         ; Define for ASCR83
#include "ascr83.asm"                           ; Advanced Sprite Clipping Routines
#include "boss.asm"                             ; End-Of-Level Boss Routines
#include "bullets.asm"                          ; Bullet Routines for player
#include "collide.asm"                          ; Collision Detection Routine
#include "damage.asm"                           ; Damage Checking Routines
#include "ebullets.asm"                         ; Bullet Routines for enemies
#include "enemy.asm"                            ; Enemy Routines
#include "enemyai.asm"                          ; Enemy AI Scripts
#include "gbullets.asm"                         ; Generic Bullet Routines
#include "huffextr.h"                           ; Huffman Extraction Routine
#include "main.asm"                             ; Main game loop, etc.
#include "misc.asm"                             ; Miscellaneous Routines
#include "orb.asm"                              ; Orb Routines
#include "pickups.asm"                          ; Items Pickups Routines
#include "player.asm"                           ; Player Routines
#include "title.asm"                            ; Title picture
#include "screen.asm"                           ; Screen Routines
#include "sprites.asm"                          ; Sprites

#include "data.asm"                             ; Data Tables, Strings, etc.

.end
