;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Armor Attack ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Memory Usage: ; ;;;;;;;;;;;;;;; ; ; XTMR0(C82E): Delay before play action starts ; XTMR1(C82F): Delay before starting more tanks ; XTMR2(C830): Delay before processing helecopter ; SATUS(C867): Sound mask: ; bit 0 - slow tank sound ; bit 1 - fast tank sound ; bit 2 - helecopter?? ; bit 3 - missile fired ; bit 4 - ; bit 5 - ; bit 6 - ; bit 7 - ; FEAST(C871): Set but never referenced. ; LASRAM(C880): Indicates whether slow tanks(1) ; or fast tanks (2) are in use. ; SJOY(C881): Max # of tanks for this level ; C882 : ; ETMP1(C883): Controls when helecopter resyncs ; the player's position. ; ETMP2(C884): Controls course/fine tuning of the ; angle between a player and a tank ; or helecopter. As levels get harder ; this mask does less course tuning of ; the angle value. ; ETMP3(C885): Mask; controls how often the helecopter's ; angle of travel is updated: ; 0x03 = moderate update rate ; 0x01 = fast update rate ; 0x00 = update every pass ; ETMP4(C886): Controls when the helecopter and tanks ; will attempt to fire a missile. ; ETMP5(C887): Index into level-specific data array. ; ETMP6(C888): Tanks are slow (1) or fast (2) ; ETMP7(C889): Tank body angle delta ; ETMP8(C88A): Incrementing flag, used primarily to ; signal when level-specific data should ; be initialized. ; ETMP9(C88B): # of tanks currently visible ; ETMP10(C88C): y position of helecopter target. ; C88D : x position of helecopter target. ; TEMP3(C891): Controls which missile movement deltas ; are used: -1=large, 1=small ; Toggles on every other iteration. ; TEMP4(C892): Helecopter intensity ; TEMP5(C893): Helecopter scale ; C894-C8A6 : Helecopter data ; C8A7-C8C6 : Helecopter body vlists ; C8C7 : # of players still alive ; C8C8 : # of players ; C8C9 : Another scale factor ; C8CA : Scale factor used to move, when ; drawing ____. ; C8CB : Work variable ; C8CC-C8CD : Function pointer ; C8CD : (1) # of tanks to start up ; : (2) Angle from helecopter to player ; : (3) Helecopter's desired angle of travel ; C8CE : Proximity of helecopter to player ; C8CF : (1) Angle from tank to player ; (2) Helecopter angle delta (+-1) ; C8D0 : Proximity of tank to player ; C8D2 : Missile processing loop counter ; C8DA : Used during missile processing: ; 2 = player 1 ; 3 = player 2 ; 4 = helecopter/tank ; Used when player fires missile to ; index into missile vlist array: ; 0 = player 1 ; 2 = player 2 ; C8DE-C8DF : Helecopter processing delay ; C8E0 : Tank startup delay counter ; C8E1 : Startup delay counter ; C8E2 : # of jeeps remaining ; C8E3 : Award for 1st tank hit (BCD 0200) ; C8E4 : Award for 2nd tank hit (BCD 0300) ; C8E5 : Value to add to player 1 score. ; C8E6 : Value to add to player 2 score. ; C8E7 : Placeholder for tank/helecopter ; score updates. ; C8E8 : 1/2 target size; used during hit ; detection; size = 2nx2n ; C8E9 : Controls display of # jeeps & score ; >= 0 - Display score & # jeeps ; < 0 - Don't display ; C8EB : Mask; when tank sounds are enabled, ; indicates which sound is made: ; bit 0 = slow tanks ; bit 1 = fast tanks ; C8EC : Enable mask; used to control which, ; if any, tank sound is made: ; bit 0 = slow tanks ; bit 1 = fast tanks ; C8ED : -1 (game active) or 0 (display "END") ; C8EE : Counts # of passes thru main loop ; C8EF : Used by sound code; flags that helecopter ; is exploding (-1), so all other sounds ; are disabled. ; C8F0 : Btn mask; controls whether a button is ; continuous read (bit = 0) or ; press/release (bit = 1). ; C900-C93F : Tank 1 data ; C940-C97F : Tank 2 data ; C980-C9BF : Tank 3 data ; C9C0-C9C6 : Player 1 1st missile data ; C9C7-C9CD : Player 1 2nd missile data ; C9CE-C9D4 : Player 2 1st missile data ; C9D5-C9DB : Player 2 2nd missile data ; C9DC-C9E2 : Helecopter missile data ; C9E3-C9E9 : Tank 1 missile data ; C9EA-C9F0 : Tank 2 missile data ; C9F1-C9F7 : Tank 3 missile data ; CA00-CA26 : Player 1 data ; CA27-CA4D : Player 2 data ; CA4E-CA55 : Button & Joystick state info ; CA56-CA5F : Player 1 1st missile vlist ; CA60-CA69 : Player 1 2nd missile vlist ; CA6A-CA73 : Player 2 1st missile vlist ; CA74-CA7D : Player 2 2nd missile vlist ; CA7E-CA87 : Rotated missile vlist ; CA88-CA89 : Position for plyr 1 score str ; CA8A-CA90 : Player 1 score string ; CA91-CA92 : Position for plyr 2 score str ; CA93-CA99 : Player 2 score string ; CA9A-CAF9 : Helecopter rotor vlists; 4 sets ; of 12 vectors. ; CB00-CB1F : Array of points; used during the ; drawing of an exploding missile, ; when drawing tank flames, or when ; the helecopter is hit. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Data Structures ; ;;;;;;;;;;;;;;;;; ; ; Button/Joystick Information (CA4E-CA55) ; (The joystick left/right information is) ; (merged in with the key 0 & key 1 data) ; ; ---------------- ; 0 | Key 0 (left) | \ ; ---------------- | ; 1 | Key 1 (right)| | ; ---------------- | Player 1 ; 2 | Key 2 (move) | | ; ---------------- | ; 3 | Key 3 (fire) | / ; ---------------- ; 4 | Key 0 (left) | \ ; ---------------- | ; 5 | Key 1 (right)| | ; ---------------- | Player 2 ; 6 | Key 2 (move) | | ; ---------------- | ; 7 | Key 3 (fire) | / ; ---------------- ; ; Missile (C9C0-C9C6) ; ; ----------------------- ; 0 | State flag | -> -1 = In use ; ----------------------- 0 = Inactive ; 1 | y pos | >0 = Exploding ; ----------------------- ; 2 | x pos | ; ----------------------- ; 3 | dwell (exploding) | ; | y delta (in use) | ; ----------------------- ; 4 | scale (exploding) | ; | x delta (in use) | ; ----------------------- ; 5 | diffy dot vlist ptr | -> Exploding ; -- -or- -- ; 6 | (y,x) small deltas | -> In use ; ----------------------- ; ; Player Data (CA00-CA26) [RAMMES] ; ; ----------------------- ; 0 | State Flag | -> 0 = Inactive/dead ; ----------------------- >0 = Alive ; 1 | Address of first | <0 = Exploding ; -- -- ; 2 | missile data block | ; ----------------------- ; 3 |firing delay (alive) | ; |Expl scale (expldng) | ; ----------------------- ; 4 | y delta (alive) | ; |scale delta (expldng)| ; ----------------------- ; 5 | x delta | ; ----------------------- ; 6 | 16-bit y | ; -- -- ; 7 | position | ; ----------------------- ; 8 | 16-bit x | ; -- -- ; 9 | position | ; ----------------------- ; 10 | angle | ; ----------------------- ; 11 | Packet | ; . | jeep | ; 38 | vlist | ; ----------------------- ; ; When player is alive, the embedded vlist is drawn. ; When player is exploding, vlist at 0xCA9A is drawn. ; When player is first hit, state is set to 0x80, and ; value is then counted up until it reaches 0. ; ; Tank Data (C900-C93F) ; ; ----------------------- ; 0 | State Flag | -> 0 = Inactive/dead ; ----------------------- >0 = Alive ; 1 | # of hits | <0 = Burning ; ----------------------- ; 2 |Fire missile counter | ; ----------------------- ; 3 | | ; ----------------------- ; 4 | | ; ----------------------- ; 5 |Tank body angle delta| ; ----------------------- ; 6 | Turret angle | ; ----------------------- ; 7 | | ; ----------------------- ; 8 | | ; ----------------------- ; 9 | | ; ----------------------- ; 10 | Ptr to array of | -> Only when burning? ; -- -- ; 11 | flame locations | ; ----------------------- ; 12 | Scale factor | ; ----------------------- ; 13 | Flames array index | ; ----------------------- ; 14 | y position | ; ----------------------- ; 15 | x position | ; ----------------------- ; 16 | y delta | ; ----------------------- ; 17 | x delta | ; ----------------------- ; 18 | Tank body angle | ; ----------------------- ; 19 | Tank | ; -- -- ; . | body | ; -- -- ; 37 | vlist | ; ----------------------- ; 38 | Tank | ; -- -- ; . | turret | ; -- -- ; 62 | vlist | ; ----------------------- ; ; When tank is first hit, state is set to 0x80, and ; value is then counted up until it reaches 0. ; ; Helecopter Data (C894-C8A6) ; ; ----------------------- ; 0 | State Flag | TEMP6 ; ----------------------- ; 1 | index - controls | TEMP7 -> 0 = try to fire ; | firing -vs- tracking| 1 = update position ; ----------------------- ; 2 | counter - track | TEMP8 -> Resync when counts ; | players new position| down to 0. ; ----------------------- ; 3 | counter - update | TEMP9 -> Update when 0 ; | angle of travel | ; ----------------------- ; 4 |Update body vlist flg| TEMP10 -> -1 = update needed ; ----------------------- 0 = update not needed ; 5 | | C899 ; ----------------------- ; 6 |Fire missile counter | C89A ; ----------------------- ; 7 | Pointer to player | ACTPLY ; -- -- ; 8 | being stalked | TMR1 ; ----------------------- ; 9 | Body y position | T1FUNC ; ----------------------- ; 10 | Body x position | C89E ; ----------------------- ; 11 | Body y offset | TMR2 ; ----------------------- ; 12 | Body x offset | T2FUNC ; ----------------------- ; 13 | Heading delta (y) | C8A1 ; ----------------------- ; 14 | Heading delta (x) | TMR3 ; ----------------------- ; 15 | Movement delta (y) | T3FUNC ; ----------------------- ; 16 | Movement delta (x) | C8A4 ; ----------------------- ; 17 | Angle of fire | TMR4 ; ----------------------- ; 18 | Body rotation angle | T4FUNC ; ----------------------- ; 19 | Helecopter | ; -- -- ; . | body | ; -- -- ; 50 | vlist | ; ----------------------- ; ; When the helecopter is started, the (y,x) position ; is randomly set to one of the following: (0,7F), ; (0,81), (7F,0) or (81,0). ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; include "osmapV2.h" include "fnmapV2.h" ; Bogus jump point back into the OS ROM ; PF000 equ $F000 org 0x0000; db "g GCE 1982",0x80 dw 0xFD81; db 0xF8 ; height db 0x50 ; width db 0x20 ; rel y db 0xC0 ; rel x db "ARMOR ATTACK",0x80,0x00 P001F: ldx #LASRAM ; Clear 0xC880-0xCAFF ldd #0x0280 jsr CLRBLK ldd #0x0203 ; Get # of players (max 2) jsr SELOPT ; Get game # (3 choices) jsr DPRAM lda #0xFF ; Set line pattern used sta DASH ; when drawing buildings. ldb #0xBB ; Button state mask: ; Btns 1,2,4: press/release ; Btn 3: continous lda OPTION ; Which game was choosen? cmpa #0x01 ; Game 1? beq P0045 ; Branch if game 1 ldb #0x88 ; Button state mask: ; Btn 4: press/release ; Btns 1,2,3: continous cmpa #0x02 ; Game 2? beq P0045 ; Branch if game 2 inc DASH ; Use invisible buildings P0045: stb 0xC8F0 ; Store game specific btn mask clr EPOT1 ; Disable up/down movement clr EPOT3 ; for both console jsticks. ldd #0x7F7F std 0xC8C9 ; Init two scale factors RestartGame: lda PLAYRS sta 0xC8C8 ; Save copy of # of players clr ETMP5 ; Index into level-specific ; data; init to 0. ; Initialize some OS variables lda #0x10 sta POTRES ; Set jstick resolution limit ldd #0xFA38 std SIZRAS ; Set font cell size (-6x56) ; Initialize some game specific variables ldx #0xC8DE ; Initialize some variables, ldu #Defaults; by copying the default lda #0x07 ; values from ROM into the jsr CopyUtoX ; appropriate RAM locations. ; Initialize player 1 score string ldx #0xCA88 ; Ptr to player 1 score str ldd #0x7888 ; Position to display score std ,x++ ; Init player 1 score and jsr SCLR ; its display position. ; Initialize player 2 score string leax 7,x ; Ptr to player 2 score str ldd #0x7838 ; Position to display score std ,x++ ; Init player 2 score and jsr SCLR ; its display position. jsr INTREQ ; Initialize sound stuff lda #0xFF; sta FEAST ; Set, but never referenced! sta ETMP8 ; Init flag to -1 sta 0xC8E9 ; Disable disp of #jeeps & score sta 0xC8ED ; Disable "END" display sta TEMP3 ; Start with big missile deltas ; Create 4 sets of 12 vectors, representing ; the rotating helecopter rotors. ldx #HelecopterRotorVlist ; Src bufr ldu #0xCA9A ; dest buffer ldb #0x02 ; Vector count - 1 (3) jsr CreateHelecopterRotors; P0099: lda 0xC8E1 ; Set delay controlling when sta XTMR0 ; play action starts. lda 0xC8E0 ; Set delay controlling when sta XTMR1 ; tanks are started up. lda 0xC8DE ; Set the delay controlling sta XTMR2 ; helecopter processing. jsr InitPlayerData; P00A8: jsr DisableAllTanks; clr TEMP6 ; Disable the helecopter ldx #0xC9C0 ; Disable all 8 missiles ldd #0x0807 ; Count=8, obj size=7 bytes jsr DisableObjects; clr SATUS ; Disable all sounds lda 0xC8E2 ; Any jeeps left? bne P00DD ; Branch if some left ldx #0xCA8A ; Get ptr to player 1 score leau 9,x ; Get ptr to player 2 score jsr WINNER ; Determine which player won cmpa #0x02 ; Player 2 have hi score? bne P00CA ; Jump if player 1 hi leax ,u ; Player 2 has hi score P00CA: ldu #HISCOR jsr HISCR ; Save new high score clr 0xC8ED ; Enable display of "END" ldd #0x0BFF ; Set the counter controlling std XTMR4 ; auto-restart of a new game. lda 0xC8C8 ; Get # of players sta 0xC8E9 ; Enable score/# jeeps display bra IdleLoop; P00DD: lda 0xC8C7 ; Any players still alive? bne MainLoop ; Branch if yes lda XTMR0 ; Branch if play action timer beq P0099 ; already expired. lda 0xC8C8 ; Get # of players sta 0xC8E9 ; Enable score/# jeeps display dec XTMR0 ; Decr play action counter bne IdleLoop ; Branch if not ready to start com 0xC8E9 ; Disable score/# jeeps display MainLoop: ldb 0xC8C7 ; Any players still alive? beq P00A8 ; Branch if not lda ETMP8 ; This flag starts at -1, and bpl P010F ; the first pass thru, will nega ; signal that the level-specific sta ETMP8 ; initialization is needed. As anda #0x03 ; tanks & helecopters start, its cmpa #0x01 ; value will become 2, then 3. bne P010F ; Branch if initialization done. ldb ETMP5 ; Get level-specific index ldu #LevelSpecificData ; Get ptr to leau b,u ; level specific values. ldx #LASRAM ; Initialize level-specific lda #0x08 ; values by copying them from jsr CopyUtoX ; ROM into RAM. P010F: jsr CheckForMissileHits; jsr ProcessHelecopter; jsr ProcessTanks; jsr ProcessBtnsBothPlayers; ; Draw visuals and make sounds. If the game ; is active, then goto the mainloop, to ; continue normal processing. Otherwise, do ; a soft game restart (using current # players) ; if the user presses a button before the two ; step idle loop counter expires. IdleLoop: inc 0xC8EE ; Incr mainloop counter jsr MakeSounds ; Process active sounds jsr DrawVisuals; Draw active objects lda 0xC8ED ; Is game over? bmi MainLoop ; Branch if not ldb TRIGGR ; Get button states lbne RestartGame; Restart if btn pressed dec XTMR5 ; Decr the 2-step auto bne IdleLoop ; restart counter. Stay dec XTMR4 ; in the idle loop until bne IdleLoop ; 2-step counter expires. ; Do a hard game restart (start from the ; game intro screen) after either the user ; presses a button, or the restart counter ; counts down to 0. ldd #0x06FF ; Reset XTMR4, to control std XTMR4 ; the hard restart loop. P013A: jsr FRWAIT ; Wait for frame beginning jsr INPUT ; Read controller buttons jsr DPRAM ; Set DP ptr to RAM ldx XTMR4 ; Stay in this loop, until leax -1,x ; either a btn is pressed, stx XTMR4 ; or XTMR4 counts down to beq P0150 ; 0; then restart game. lda TRIGGR ; Get button states beq P013A ; Loop if no btns pressed. P0150: jmp PF000 ; Restart from intro screen ; FDT - May be a bug; did not ; do right thing on a multi- ; cart. ; MoveDrawDashed() ; ; Entry: a = scale factor for moving ; u = ptr to rel (y,x) position ; x = ptr to diffy vlist ; s+0 = # of iterations remaining ; s+1 = vector count ; ; Used to draw the buildings. The dashed line pattern ; is used, to allow the walls to be visible (solid line) ; or invisible (line pattern turned off). ; MoveDrawDashed: sta T1LOLC ; Set scale factor (move) ldd ,u++ ; Get pos to move to jsr POSITN ; Move to rel (y,x) pos lda #0x3F sta T1LOLC ; Set scale factor (0x3F) lda 3,s ; Retrieve vector count sta LIST ; Save vector count jsr DASHDF ; Draw dashed lines dec 2,s ; Decr vlist counter rts; ; DrawAtMultipleLocations() ; ; Entry: u = ptr to the following: ; byte 0 = iteration counter (?) ; byte 1 = vector count (?) ; byte 2,3 = rel (y,x) for pass 1 ; byte x,x+1 = rel (y,x) for pass n ; x = ptr to diffy vlist ; ; Draw a given diffy vlist multiple times, at the ; specified set of locations. ; DrawAtMultipleLocations: ldd ,u++ ; Get iteration & vector counts pshs a,b,x ; Save on stack P016D: ldx 2,s ; Get ptr to vlist lda 0xC8CA ; Load 'move' scale factor bsr MoveDrawDashed ; Draw vlist bne P016D ; More iterations? puls a,b,x,pc ; All done ; DrawMultipleVlists() ; ; Entry: u = ptr to the following: ; byte 0 = # of vlists (?) ; byte 1 = vector count (?) ; byte 2,3 = rel (y,x) for vlist 1 ; byte x,x+1 = rel (y,x) for vlist n ; x = ptr to set of diffy vlists ; ; Draw a set of diffy vlist, at the ; specified set of locations. ; DrawMultipleVlists: ldd ,u++ ; Get vlist & vector counts pshs a,b ; Save on stack P017C: lda 0xC8C9 ; Load 'move' scale factor bsr MoveDrawDashed ; Draw vlist bne P017C ; More iterations? puls a,b,pc ; All done ; DrawVisuals() ; ; Takes care of drawing all buildings and outer boundaries, ; jeeps, tanks, the helecopter and any missiles. Also ; displays the score and # of jeeps, when enabled. ; DrawVisuals: inc ZSKIP; jsr FRWAIT ; DP comes back set to IO jsr REQOUT ; Output sound chip values jsr INT3Q ; Use 3/4 intensity ; Draw the outer boundary area and the ; enclosed buildings. The attribute list ; provides details like the number of vlists ; to draw, the vector count and the (y,x) ; position for each vlist. ldx #OuterBoundaryVlists; ldu #AllVlistAttrs; bsr DrawMultipleVlists; ldx #LgSquareBuildingVlist; bsr DrawAtMultipleLocations; leax 12,x ; SmSquareBuildingVlist bsr DrawAtMultipleLocations; leax 8,x ; LBuildingVlists bsr DrawMultipleVlists; clr ZSKIP; leas -10,s ; Allocate some work space ; Draw any active tanks (upto 3) ldu #0xC900 ; Get ptr to array of tanks ldd #ProcessArrayEntry; std ,s ; Set array iterator proc ldd #DrawTank; Primary processing proc std 2,s ; Save primary proc addr lda SJOY ; Loop cntr - max # tanks ldb #0x40 ; Size of each array entry jsr CallProcMultipleTimes; ; Draw each player's jeep ; Reuses iterator set above ldu #RAMMES ; Get ptr to player 1 data ldd #DrawJeep; Primary processing proc std 2,s ; Save primary proc addr lda 0xC8C8 ; Loop cntr - # of players ldb #0x27 ; Size of each array entry jsr CallProcMultipleTimes; ; Draw any active missiles (upto 8) ; Reuses iterator set above ldu #0xC9C0 ; Get ptr to 1st missile ldd #DrawMissile; Primary processing proc std 2,s ; Save primary proc addr ldy #0xCA56 ; Ptr to 1st missile vlist ldd #0x0807 ; Loop cntr(8); entry size(7) jsr CallProcMultipleTimes; ; Draw the helecopter ; Reuses iterator set above ldu #TEMP6 ; Get ptr to helecopter data ldd #DrawHelecopter; Primary processing proc std 2,s ; Save primary proc addr lda #0x01 ; Loop counter (1) jsr CallProcMultipleTimes; ; Add any score updates (due to hits on tanks ; or helecopters) to each player's score ldd #UpdateScore std ,s ; Set array iterator proc ldx #0xCA8A ; Ptr to player 1 score ldu #0xC8E5 ; Ptr to plyr1 score additions lda 0xC8C8 ; Loop cntr - # of players jsr CallProcMultipleTimes; ; Set new intensity & scale for remaining drawing ldd #0x7E7F stb T1LOLC ; Set scale = 0x7F jsr INTENS ; Set intensity = 0x7E ; If still in the startup delay, display the score lda 0xC8E9 ; Is game play active? bmi P021A ; Branch if yes lda 0xC8C8 ; Loop cntr - # of players ldx #RSTPOS ; Proc to display score stx ,s ; Set array iterator proc ldu #0xCA88 ; Addr of player 1 score jsr CallProcMultipleTimes; ; If still in the startup delay, display the # ; of remaining jeeps, or, if none, then the ; "END" string. P021A: leas 10,s ; Free up work space lda 0xC8E9 ; Is game play active? bmi ProcessInput; Branch if yes ldx #0x78EF ; Set relative (y,x) pos ldb 0xC8E2 ; Get # of remaining jeeps lda #0x60 ; Jeep symbol char code jsr DSHIP ; Draw remaining tanks lda 0xC8ED ; Is the game over? bne ProcessInput; Branch if not ldu #EndString; jsr RSTPOS ; Display "END" string ; Load the jstick/btn storage area with the ; current button states. Then, adjust the ; values for btn 0 (left) or btn 1 (right) ; depending upon the joystick setting. ProcessInput: lda 0xC8F0 ; Load button state mask jsr DBNCE ; Read console buttons jsr JOYBIT ; Read joysticks lda 0xC8C8 ; Skip if no players beq P026F; ldx #0xCA4E ; Ptr to jstick/btn storage area ldu #KEY0 ; Ptr to current button states ldy #POT0 ; Ptr to current jstick states P024F: pshs a,x ; Save loop cntr & data ptr ldd ,u++ ; Get btn 1 & 2 states std ,x+ ; Save btn 1 & 2 states ldd ,u++ ; Get btn 3 & 4 states std 1,x ; Save btn 3 & 4 states clrb lda ,y++ ; Load L/R jstick value beq P0268 ; Do nothing if centered rola ; Get a's sign bit into b rolb beq P0264 ; Branch if 'a' was + coma ; Make 'a' positive negb ; Set 'b' to -1 P0264: ora b,x ; Adj L/R value, based on the sta b,x ; jstick position. P0268: puls a,x ; Restore loop cntr & data ptr leax 4,x ; Pt to player 2's storage area deca ; Decrement loop counter bne P024F ; Branch if more iterations P026F: jsr ZERGND; jmp DPRAM; ; ; DrawTank() ; ; Entry: u = ptr to tank data ; ; Draws a tank ; DrawTank: leax 14,u ; Get ptr to (y,x) pos jsr POSIT1 ; Move there leax 3,x ; Get ptr to tank body vlist ldb #0x30 ; Set scale factor jsr TPACK ; Draw the packet vlist leax 0x26,u ; Get ptr to turret vlist ldb #0x20 ; Set scale factor jsr TPACK ; Draw the packet vlist lda ,u ; Get tank's state flag bpl P02AF ; Branch if still alive jsr ZERGND; jsr INTMAX ; Set maximum intensity leax 14,u ; Get ptr to (y,x) pos jsr POSIT1 ; Move there ldx 10,u ; Get ptr to 'move' pos ldb 13,u ; Calc offset (b * 6) lda #0x06 mul abx ; Add offset to 'move' ptr ldb 12,u ; Load scale factor jsr POSITB ; Move to pos pointed by x lda #0x01 ; Set vector count -1 (2) ldb 12,u ; Load scale factor jsr TDIFFY ; Draw diffy vlist jsr INT3Q ; Set intensity to 75% P02AF: jmp ZERGND; ; DrawMissile() ; ; Entry: u = ptr to missile data ; y = ptr to missile vlist ; ; Draw a missile ; DrawMissile: leax 1,u ; Get ptr to (y,x) pos jsr POSIT1 ; Move there ldb ,u ; Get mode flag bmi P02CD ; Branch if flag < 0 ldd 3,u ; Extract scale & dwell sta DWELL ; Set dot dwell time stb T1LOLC ; Set scale factor lda #0x03 ; Vector count - 1 sta LIST ; Set vector count - 1 ldx 5,u ; Set diffy dot list ptr jsr DIFDOT ; Draw the dots rts; P02CD: incb ; Is flag -1? bmi P02DA ; Branch if flag < -1 lda #0x08 ; Load fixed dot dwell time sta DWELL ; Set dot dwell time jsr DOT ; Draw a single dot bra P02E2; P02DA: ldd #0x0428 ; vcount=5 & scale=0x28 leax ,y ; Get ptr to alt vlist jsr TDIFFY ; Draw diffy vlist P02E2: jsr ZERGND; rts; ; DrawJeep() ; ; Entry: u = ptr to player data ; ; Draw a player's jeep, or an explosion ; DrawJeep: leax 6,u ; Ptr to 16-bit (y,x) pos jsr POSWID ; Move to specified pos lda ,u ; Get player's state flag bpl P0301 ; Branch if alive ldb 3,u ; Load scale factor stb T1LOLC ; Set scale factor ldx #0xCA9A ; Get ptr to explosion vlist P02F6: lda #0x0B ; Load vector count - 1 (12) sta LIST ; Set vector count - 1 jsr LDIFFY ; Draw diffy vlist P02FE: jmp ZERGND; P0301: leax 11,u ; Ptr to Jeep vlist ldb #0x28 ; Set scale factor jmp DrawPacketVlist; ; DrawHelecopter() ; ; Entry: u = ptr to helecopter data ; ; Draws the helecopter ; DrawHelecopter: leax 9,u ; Get ptr to (y,x) pos ldd ,x ; Load (y,x) position adda 2,x ; Add y body offset bvs P0314 ; Branch if overflow addb 3,x ; Add x body offset bvc P0315 ; Branch if no overflow P0314: rts; P0315: jsr POSIT1 ; Move to pos pointed by x jsr POSIT1 ; Offset by x & y body offsets ldx #0xC8A7 ; Ptr to body vlists lda ,u ; Get helecopter state flag bmi P0336 ; Branch if exploding ldb #0x20 ; Load scale factor jsr TPACK ; Draw helecopter body ldb #0x20 ; Load scale factor stb T1LOLC ; Set scale factor ldx #0xCA9A ; Ptr to rotor vlist array ldb 5,u ; Calc offset into vlist lda #0x18 ; offset = b * 24 mul abx ; Add offset to vlist ptr bra P02F6 ; Draw the rotors ; Helecopter is exploding P0336: leay -2,u ; Ptr to intensity & scale ldu #0xCB00 ; Get ptr to 'move' pos lda ,y ; Load intensity value exg u,x jsr INTENS ; Set intensity ldb 1,y ; Load scale factor aslb ; Adjust scale factor jsr POSITB ; Move to pos pointed by x exg x,u ; Get vlist ptr into x ldb #0x20 ; Load scale factor jsr TPACK ; Draw 1st piece of hele body ldb 1,y ; Load scale factor exg u,x ; Get ptr to 'move' pos jsr POSITB ; Move to pos pointed by x exg x,u ; Get ptr to scale & vlist ldb ,x+ ; Load scale factor jsr TPACK ; Draw 2nd piece of hele body ldx #0xCA9A ; Ptr to rotor vlist array ldb 7,y ; Calc vlist offset lda #0x18 ; offset = b * 24 mul abx ; Add vlist offset ldb #0x04 stb -5,s ; Set loop counter (4) P036A: ldb 1,y ; Load scale factor stb T1LOLC ; Set scale factor ldd ,u++ ; Load 'move' pos jsr POSITN ; Move to pos in 'd' ldb #0x20 ; Set scale factor lda #0x02 ; Set vector count - 1 (3) jsr TDIFFY ; Draw rotors dec -5,s ; Decrement loop counter bne P036A ; Branch if more iterations jmp ZERGND; ; CallProcMultipleTimes() ; ; Entry: s,s+1 = Ptr to iterator function ; a = # of times to call function ; b = Function specific value ; ; Invokes the specified function a given number ; of times. When the specified function is ; called, the stack has been set up as follows: ; ; --------------- ; top | a (counter) | ; --------------- ; | b | ; --------------- ; | Return | ; -- -- ; | Address | ; --------------- ; | Iterator | ; -- -- ; | Function | ; --------------- ; | Processing | ; -- -- ; | Function | ; --------------- ; CallProcMultipleTimes: pshs a,b ; Save loop cntr & b(?) tsta ; Check loop counter beq P038D ; Bail if already 0 P0386: jsr [ 0x04,s ] ; Invoke function dec ,s ; Decrement loop cntr bne P0386 ; Jump if > 0 P038D: puls a,b,pc ; Clean up ; ProcessArrayEntry() ; ; Entry: s+3 = Size of each array entry ; s+6,s+7 = Ptr to processing function ; u = ptr to an array of objects to be ; processed. ; y = Function specific value; only used to ; hold a ptr to the missile vlists. ; ; Invokes the specified processing function on an ; array object, if the object is active (its ; state != 0). Afterwards, it updates the array ; pointer, so that the next time it is called, it ; will be referring to the next object to be ; processed. ; ; When the specified processing function is called, ; the stack has been set up as follows: ; ; --------------- ; top | Return | ; -- -- ; | Address | ; --------------- ; | a (counter) | ; --------------- ; | b (array sz)| ; --------------- ; | Return | ; -- -- ; | Address | ; --------------- ; | Iterator | ; -- -- ; | Function | ; --------------- ; | Processing | ; -- -- ; | Function | ; --------------- ; ; This is an iterator function. ; ProcessArrayEntry: lda ,u ; Get object's state flag beq P0396 ; Branch if inactive jsr [ 0x08,s ] ; Invoke processing function P0396: ldb 3,s ; Get array object size leau b,u ; Offset to next array object leay 10,y ; Point to next missile vlist rts; ; ProcessTanks() ; ProcessTanks: lda #0xFC ; Disable tank movement anda SATUS ; sounds. sta SATUS lda XTMR1 ; Get tank startup delay cntr lbeq P0448 ; Branch if already expired dec XTMR1 ; Decr tank delay counter bne P03E9 ; Branch if not expired com ETMP8 ; Flag tanks are being processed ldx #0xCB00 ; Init explosion endpoints ldu #SmSquareBuildingVlist ; Src info lda #0x04 ; Loop counter pshs a ; Save loop counter P03B9: ldd #0x0408 ; a=offset mask; b=byte cnt jsr CopyRandomArrayData ; Copy data dec ,s ; Decr loop counter bne P03B9 ; Branch if more iterations puls a ; Clean up stack lda LASRAM ; Load the slow/fast tank mask sta ETMP6 ; Save it cmpa #0x01 ; Are slow tank sounds enabled? bne P03D2 ; Branch if not ldd #0x01FD ; Init slow tank sound mask bra P03D5; P03D2: ldd #0x02FE ; Init fast tank sound mask P03D5: std 0xC8EB ; Save the sound masks jsr DisableAllTanks; lda 0xC882 sta ETMP7 ; Set tank body angle delta ldx #0xC900 ; Get ptr to tank 1 data ldb SJOY ; Get max # tanks allowed stb ETMP9 ; Set # of visible tanks P03E5: stb 0xC8CD ; Save # of tanks to start bne P03EA ; Branch if more to start P03E9: rts; P03EA: lda #0x09 ; Locate the default mul ; attributes associated ldu #DftTankAttrsBase ; with this tank. leau b,u; inca ; Set to '1' sta ,x+ ; Flag tank as active lda #0x08 ; Loop counter P03F7: clr ,x+ ; Clear the next 8 bytes deca ; of the tank data. bne P03F7 ; Branch if more bytes left jsr RAND3 ; Get random # -> 'a' anda #0x03 ; Force in range 0-3 sta ,x+ ; lda #0x09 ; Copy in some default attrs jsr CopyUtoX ; for this tank. P0408: leau -2,x ; Get ptr to delta x value lda ,u ; Retrieve delta x value bne P0410 ; Branch if != 0 lda ,-u ; Retrieve delta y value P0410: ldb ETMP6 ; 1=slow tanks, 2=fast tanks mul ; Calculate the real movement negb ; delta, based on whether the stb ,u ; tanks are fast or slow. ldb -10,x; beq P0427; leau -5,x ; Get ptr to tank's (y,x) pos coma; P041D: nega; leau a,u; neg ,u; neg 2,u; decb; bne P041D; P0427: clra; P0428: tfr d,y; ldd -5,x ; Get tanks's (y,x) pos jsr CalcAngle3;Calc turret angle sta -13,x ; Set turret angle lda -1,x ; Get body rotation angle leau ,x ; Set destination bufr ldx #TankBodyVlist ; Packet vlist to rotate jsr PROT ; Rotate the vlist lda 0xE0,u ; Get turret rotation angle jsr PROT ; Rotate turret vlist leax 1,u; ldb 0xC8CD ; Get # of tanks to start decb ; Decr the new tank counter bra P03E5; P0448: lda ETMP9 ; Any tanks still visible? bne P0451 ; Branch if yes lda 0xC8E0 ; Get dflt tank startup counter sta XTMR1 ; Reset tank startup counter rts; P0451: ldb 0xC900 ; Get tank 1 mode flag bgt P0464 ; Branch if active ldb 0xC940 ; Get tank 2 mode flag bgt P0464 ; Branch if active ldb 0xC980 ; Get tank 3 mode flag bgt P0464 ; Branch if active lda #0xFC ; Disable all tank sta 0xC8EC ; sounds. P0464: lda SATUS ; Make sure that the ora 0xC8EB ; appropriate tank sounds, anda 0xC8EC ; if any, are enabled (none, sta SATUS ; slow or fast). ldx #0xC8C8 ; Get base ptr for tank data ldb 0xC88E ; P0471: incb ; Generate a value in the andb #0x03 ; the range 1-3 (will be used stb 0xC88E ; to index in tank array). beq P0471 ; Try again, if value = 0 lda #0x40 ; Create offset into array; mul ; each array entry is 0x40 abx ; bytes. lda -8,x ; Load tank's state flag beq P048B ; Branch if not visible bmi TankBurning ; Branch if burning ldb -7,x ; Get # of hits on tank bne TankHit ; Branch if hits > 0 tsta ; Is tank alive? lbne TankIsAlive ; Branch if yes P048B: rts; ; Tank has been hit; from now on, draw it ; as burning. TankHit: lda #0x80 ; Flag tank as burning, by sta -8,x ; setting the state flag. ldu #0xCB00 ; Set ptr to the flames stu 2,x ; positioning array. ldb #0x10 ; Get flames scale factor lda 10,x ; Load tank body angle stb 4,x ; Set scale factor clr 5,x ; Set flames array offset=0 leau 11,x ; Set dest bufr ldx #DestroyedTankBodyVlist ; Src bufr jmp PROT ; Rotate tank body vlist ; Tank is burning. ; Once the state field (burn counter) increments ; to 0, the tank has burned up and will be ; deactivated. TankBurning: inc -8,x ; Incr burn counter bne StillBurning ; Branch if != 0 clr -7,x ; Clear # hits on tank dec ETMP9 ; Decr # of visible tanks bne P04B1 ; Branch if more tanks visible clr 0xC8EB ; Disable tank sounds P04B1: rts; ; The tank is still burning. ; As we approach the end of the burn stage, ; we need to make the flames appear to grow. ; If the tank has taken a 2nd hit, then it ; will now be completely disabled. StillBurning: cmpa #0xF8 ; Cnt up time < -8? blt P04BC ; Branch if yes lda #0x02 ; Incr scale factor used to adda 4,x ; draw flames; makes flames sta 4,x ; look larger. P04BC: jsr UpdateVlistIndex; Update flames vlist idx ldb -7,x ; Get # hits on tank decb ; Does tank only have 1 hit? beq TurretActive ; Branch if yes ldu #DestroyedTurretVlist leax 0x1E,x ; Switch to using the disabled lda #0x19 ; turret vlist jmp CopyUtoX ; Tank has 1 hit, which means the tank body is ; disabled, but the turret is still active, and ; thus, can track the user and fire. TurretActive: dec -6,x ; Decr 'attempt to fire' counter bgt TankTrackPlayer ; Branch if not time to fire ldu #0xC9DC ; Get base ptr to system missiles ldb 0xC88E ; Get ptr to the missile lda #0x07 ; associated with this tank. mul; leau b,u; ldb ,u ; Get missile state flag bne TankTrackPlayer ; Branch if already in use ldd 6,x ; Get tank's (y,x) pos std 1,u ; Save as missile's pos ldb -2,x ; Get turret angle lda ETMP4 ; Reset counter controlling sta -6,x ; when tank tries to fire. CalcMovementDelta: lda #0x07 ; Velocity = 7 jsr LROT90 ; Calc missile move deltas std 3,u ; Save delta y & delta x asra ; The next block takes asrb ; the deltas we just std 5,u ; calculated, divides them ldd 3,u ; by 2, and then saves the suba 5,u ; new values. subb 6,u std 3,u ; New values saved here dec ,u ; Set missile state = in use P0500: rts; ; TankTrackPlayer() ; ; Determine which player is closer, and head towards ; that player. ; TankTrackPlayer: lda #0x7F ; Initialize the proximity sta 0xC8D0 ; value to max distance. ldu #0xCA06 ; Get ptr to player 1 pos lda -6,u ; Get player 1 state flag ble P0517 ; Branch if not visible or dying ldd 6,x ; Get tank's (y,x) pos jsr CalcAngle2; Calc angle to player's jeep cmpb #0x04 ; Did they collide? blt TankCollidedWithPlayer; Branch if yes std 0xC8CF ; Save angle & proximity P0517: lda 0xC8C8 ; Get # of players deca ; > 1 player? beq P0530 ; Branch if not leau 0x27,u ; Get ptr to player 2 pos lda -6,u ; Get player 2 state flag ; FDT: bug - should be ble! blt P0530 ; Branch if being destroyed ldd 6,x ; Get tank's (y,x) pos jsr CalcAngle2; Calc angle to player's jeep cmpb #0x04 ; Did they collide? blt TankCollidedWithPlayer; Branch if yes cmpb 0xC8D0 ; Are we closer to player 2? blt P0532 ; Branch if yes P0530: lda 0xC8CF ; Track player 1 (closer) P0532: anda ETMP2 ; Course tune the angle cmpa -2,x ; Does turret angle need to beq P0500 ; change? Branch if not. ldb 0xC8EE ; Update only on every bitb #0x01 ; other pass. beq P0500 ; No update on this pass sta -2,x ; Save updated turret angle leau 0x1E,x ; Set destination bufr ldx #TankTurretVlist ; Src packet vlist jmp PROT ; Rotate turret vlist ; TankCollidedWithPlayer() ; ; When a tank and a player collide, both are destroyed. ; Mark the tank as having taken 2 hits (thus disabling ; it) and mark the jeep as destroyed. ; TankCollidedWithPlayer: lda #0x02 sta -7,x ; Force tank to have 2 hits lda #0x80 sta -6,u ; Flag player as hit rts; ; TankIsAlive() ; ; Entry: x = pointer to tank data (+8) ; TankIsAlive: lda ,x; beq P0568; suba ETMP7 ; sta ,x; lda 10,x ; Get current tank body angle adda -3,x ; Update it (add delta) sta 10,x ; Save updated rotation angle leau 11,x ; Set destination bufr ldx #TankBodyVlist ; Packet vlist to rotate jmp PROT ; Rotate the vlist ; Entry: x = pointer to tank data (+8) ; P0568: ldy #S0DA0; lda 5,x; lbeq P0600; leau 0x40,x ; Get ptr to next tank (secondary) cmpu #0xC9C8 ; Do we need to wrap? bne P057E ; Branch if no wrap needed ldu #0xC908 ; Wrap back to tank 1 P057E: lda -8,u ; Get secondary tank state flag ble P05DD ; Branch if inactive or burning ldd 6,u ; Get secondary tank's (y,x) pos suba 6,x ; Subtract primary tank's y pos bvs P05DD ; Branch if invalid (overflow) subb 7,x ; Subtract primary tank's x pos bvs P05DD ; Branch if invalid (overflow) jsr ABSAB ; Get abs val of the pos deltas std 0xC8CB ; Save y & x delta values tsta ; Are tanks at same y pos? beq P0597 ; Branch if yes tstb ; Are tanks at same x pos? bne P05DD ; Branch if not P0597: adda 0xC8CC ; Add deltas, to get proximity cmpa #0x0C ; Are the tanks close (w/in 12 units)? bgt P05DD ; Branch if not lda 3,x; cmpa 2,x; beq P05DD; deca; ldb #0x08; mul; leay 4,y; leay d,y; ldb 4,x; lda b,y; suba 5,x; beq P05DD; sta 5,x; addb #0x02; andb #0x03; stb 4,x ; Set scale factor leay -4,y; incb; andb #0x03; lda b,y; bne P05CF; incb; incb; andb #0x03; lda b,y; bne P05CF; incb; andb #0x03; P05CF: stb -4,x; neg 8,x ; Reverse y delta dir neg 9,x ; Reverse x delta dir clr -1,x; ldd 2,x ; Swap the 2 bytes sta 3,x; stb 2,x; P05DD: lda 5,x; suba ETMP6 ; 1=slow tanks, 2=fast tanks bpl P05F3; leay 9,x ; Get ptr to x delta ldb ,y ; Get x delta value bne P05EB; ldb ,-y ; Get y delta value P05EB: bpl P05EE; nega; P05EE: adda ,--y ; Add current x or y pos sta ,y ; Save new x or y pos clra; P05F3: sta 5,x; ldd 6,x ; Get tank's (y,x) pos adda 8,x ; Add y delta addb 9,x ; Add x delta std 6,x ; Save updated position jmp TurretActive; P0600: lda -5,x; beq P0618; ldb #0x08; stb 5,x; suba 1,x; anda #0x03; sta 1,x; lda -5,x; anda #0x02; asra; sta 4,x ; Update scale factor clr -5,x; rts; P0618: lda 2,x; deca; ldb #0x08; mul; leay d,y; ldb -4,x; bmi P0628; com -4,x; bsr P065F; P0628: ldb -2,x ; Get turret angle lsrb ; Divide it by 16 lsrb lsrb lsrb cmpb 1,x; bne P0633; negb; P0633: addb 1,x; cmpb #0x04; bne P063B; ldb #0x02; P063B: andb #0x03; tfr b,a; inca; pshs a,b; jsr RANDOM ; Get random # -> a puls a,b; bhs P064B; exg a,b; P064B: sta 0xC8CB ; bsr P065F; ldb 0xC8CB ; bsr P065F; ldb 4,x; bsr P065F; ldb #0x03; P0659: bsr P065F; decb; bpl P0659; rts; ; Entry: y = ptr to data (0x0DA0) ; b = ? ; x = ptr to data (+8) P065F: andb #0x03; lda b,y; beq P066D; cmpa 3,x; bne P066E; tst -1,x; beq P0672; P066D: rts; P066E: clr -1,x; bra P0674; P0672: inc -1,x; P0674: std ,s++; cmpa 2,x; bne P0683; rorb; blo P067F; addb #0x02; P067F: addb #0x02; stb -5,x; P0683: lda 2,x; sta 3,x; ldd -2,s; sta 2,x; leay b,y; lda 4,y; sta 5,x; tfr b,a; subb 4,x; andb #0x03; beq P06A5; sta 4,x; cmpb #0x02; bne P06A6; ldd 8,x ; Load tank's y & x deltas nega ; Reverse y direction P06A2: negb ; Reverse x direction P06A3: std 8,x; ; Update tank's y & x deltas P06A5: rts; P06A6: lda #0x10; sta ,x; lda 1,x; rora; bhs P06B3; addb #0x02; andb #0x03; P06B3: lda ETMP7 ; Get dflt tank body angle delta sta -3,x ; Save it lda 9,x ; Get tank's x delta pshs b; ldb 8,x ; Get tank's y delta dec ,s+; beq P06A2; nega ; Reverse x delta direction neg -3,x ; Reverse tank body angle delta bra P06A3; ; ProcessBtnsBothPlayers() ; ; Process the buttons and joystick for each player, ; adjusting position and angle as requested, and ; firing a missile when requested (and one is ; available). ; ProcessBtnsBothPlayers: ldx #RAMMES ; Get ptr to player 1 data clra ; Plyr 1 missile vlist offset=0 sta 0xC8DA ; Save missile vlist offset ldy #0xCA4E ; Ptr to player 1 btn state info P06D0: bsr ProcessBtnsOnePlayer; lda #0x02 ; Plyr 2 missile vlist offset=2 sta 0xC8DA ; Save missile vlist offset leay 4,y ; Ptr to player 2 btn state info leax 0x27,x ; Ptr to player 2 data cmpx #0xCA4E ; All done? bne P06D0 ; Branch if not rts ; ProcessExplodingJeep() ; ; Entry: x = ptr to player data ; a = player's state flag ; ProcessExplodingJeep: ldb 3,x ; Get explosion scale factor cmpa #0x80 ; Was jeep just hit? bne P06EF ; Branch if not ldb #0x02 ; Set the explosion scale stb 4,x ; factor delta. ldb #0x01 ; Set the initial explosion stb 3,x ; scale factor. P06EF: inca ; Incr player's state (counter sta ,x ; controlling explosion duration. bne P06FB ; Branch if not explosion done dec 0xC8C7 ; Decr # of players still alive bne P06FA ; Branch if >= 1 player still alive dec 0xC8E2 ; Decr # of jeeps remaining P06FA: rts; P06FB: cmpa #0xC2 ; State counted down to -62? bne P0701 ; Branch if not P06FF: neg 4,x ; Negate explosion scale factor delta P0701: asra ; Skip the following code every blo P06FA ; other pass. addb 4,x ; Add explosion scale factor delta stb 3,x ; to the current scale factor. rts ; UpdateVlistIndex() ; ; Entry: x = ptr to object data ; UpdateVlistIndex: lda 5,x ; Get current vlist index inca ; Increment the index anda #0x03 ; Force in range 0-3 sta 5,x ; Save update value P0710: rts ; ProcessBtnsOnePlayer() ; ; Entry: x = ptr to player data ; y = ptr to btn state info ; C8DA = 0 - player 1 ; 2 - player 2 ; ProcessBtnsOnePlayer: lda ,x ; Get player's state bmi ProcessExplodingJeep ; Exploding beq P0710 ; Branch if not active pshs x; lda 3,x ; Get firing delay beq P0721 ; Proceed if expired dec 3,x ; Decr firing delay bne ProcessBtns ; Branch if not expired P0721: lda 3,y ; Get state of firing btn beq ProcessBtns ; Branch if not pressed ldb 0xC8DA ; Get missile vlist base index ldu 1,x ; Get ptr to player's 1st missile lda ,u ; Is missile in use? beq MissileAvailable ; Branch if available incb ; Incr missile vlist index leau 7,u ; Get ptr to missile 2 lda ,u ; Is missile in use? bne ProcessBtns ; Branch if already in use MissileAvailable: stb 0xC8CB ; Save index of available missile dec ,u ; Flag missile as in use lda #0x10 ; Enable missile firing sound ora SATUS sta SATUS lda 6,x ; Get player's y pos ldb 8,x ; Get player's x pos std 1,u ; Save as initial missile pos ldb 10,x ; Get jeep's rotation angle jsr CalcMovementDelta; lda #0x08 ; Get default firing delay sta 3,x ; Reset player's firing delay ldb #0x0A ; Calculate the address of lda 0xC8CB ; of the missile vlist to use. mul ldu #0xCA56 leau b,u ; Get ptr to missile vlist lda 10,x ; Get jeep's rotation angle ldx #MissileVlist ; Src vlist to rotate ldb #0x04 ; Vector count - 1 (5) jsr DROT ; Rotate the missile vlist lda 0xC8EF ; Is helecopter exploding? bmi P076F ; Branch if yes. lda #0x80; ora SATUS; sta SATUS; lda #0x20; sta 0xC8EF ; P076F: puls x,pc; ; ProcessBtns() ; ; Entry: y = ptr to player's button/joystick info ; x = ptr to player data ; ; Process the buttons and joystick, to determine ; the jeeps position or direction of travel needs ; to change. Also checks if the player has run ; into a wall. ; ProcessBtns: lda 2,y ; Get state of 'move' btn beq P07CD ; Branch if not pressed ldb 4,x ; Get y delta sex ; Convert to 16-bits, and aslb ; multiply by 8. rola aslb rola aslb rola std 0xC8CB ; Save 16-bit y delta addd 6,x ; Add player's current y pos std 6,x ; Save new position ldb 5,x ; Get x delta sex ; Convert to 16-bits, and aslb ; multiply by 8. rola aslb rola aslb rola std 0xC8CD ; Save 16-bit x delta addd 8,x ; Add player's current x pos std 8,x ; Save new position clrb ; Used to track sign of y & x lda 6,x ; Load new y pos (hi byte) bpl P079A ; Get absolute value nega ; Make positive incb ; Flag it was negative P079A: sta 0xC8DB ; Save absolute y pos lda 8,x ; Load new x pos (hi byte) bpl P07A3 ; Get absolute value nega ; Make positive orb #0x02 ; Flag it was negative P07A3: sta 0xC8DC ; Save absolute x pos pshs b ; Save +/- sign flags ldb 0xC8DB ; Load absolute y value ldu #HorizontalWalls; Check if user is bsr CheckForWallContact; up against a bvc P07B2 ; horizontal wall. stb 0xC8DB ; Store updated abs y val P07B2: ldb 0xC8DC ; Load absolute x value ldu #VerticalWalls; Check if user is bsr CheckForWallContact; up against a bvc P07BD ; vertical wall. stb 0xC8DC ; Store updated abs x val P07BD: ldd 0xC8DB ; Get updated (y,x) values ror ,s ; Restore the original bhs P07C4 ; +/- sign for the y nega ; value. P07C4: sta 6,x ; Save updated signed y value ror ,s+ ; Restore the original bhs P07CB ; +/- sign for the x negb ; value; P07CB: stb 8,x ; Save updated signed x value P07CD: clra ; Clear the rotation adjustment ldb ,y ; Get state of 'rotate left' btn beq P07D3 ; Skip if not pressed inca ; Rotate left (add +1) P07D3: ldb 1,y ; Get state of 'rotate right' btn beq P07D8 ; Skip if not pressed deca ; Rotate right (add -1) P07D8: tsta ; Do nothing if both pressed, or beq P07FA ; neither btn pressed. adda 10,x ; Update jeep's angle of travel anda #0x3F ; Make angle 0-360 sta 10,x ; Save new angle tfr a,b ; Load rotation angle lda #0x20 ; Velocity = 32 jsr LROT90 ; Calc new movement deltas std 4,x ; Save new movement deltas lda 0xC8DA ; 0=plyr1, 2=plyr2 ldb #0x0E ; Half size of each element mul ; Calc offset into vlist set lda 10,x ; Get rotation angle leau 11,x ; Set destination bufr ldx #JeepVlists ; Set vlist to rotate abx ; Add in the offset (plyr1/plyr2) jsr PROT ; Rotate the packet vlist P07FA: puls x,pc; ; This appears to be dead code! P07FC: ldb -13,x; lda #0x02; sta -13,x; leax ,u; subb #0x02; bmi P080E; lda #0x80; sta ,x; puls x,pc; P080E: ldd 6,x; subd 0xC8CB ; std 6,x; ldd 8,x; subd 0xC8CD ; std 8,x; bra P07CD; ; CheckForWallContact() ; ; Entry: b = absolute value of x or y position ; u = ptr to horizontal (y) or vertical (x) ; wall data ; C8DB = absolute value(y pos) ; C8DC = absolute value(x pos) ; ; Exit: cc: 1 = contact occurred ; 0 = no contact ; b : if contact, updated y or x position; ; prevent jeep from passing thru wall. ; ; Uses the coordinate to generate a table offset, ; which is then used to get a list of walls within ; range of the coordinate. If the coordinate is ; within the bounds of a wall, then the cc is set, ; and an updated coordinate is returned in b (this ; prevents a jeep from passing thru a wall). ; ; The coordinate ranges for each table offset are ; as follows: ; ; 0x0A-0x19 => 0x00 ; 0x1A-0x29 => 0x02 ; 0x2A-0x39 => 0x04 ; 0x3A-0x49 => 0x06 ; 0x4A-0x59 => 0x08 ; 0x5A-0x69 => 0x0A ; 0x6A-0x79 => 0x0C ; CheckForWallContact: subb #0x0A ; Subtract 10 from the position bmi P084A ; Branch if orig value <= 9 andb #0x70 ; Get 3 most significant bits asrb ; Shift right 3 bits, to asrb ; form a table offset in the asrb ; lower nibble (0x00-0x0C). ldd b,u ; Set a=offset, b=loop cntr leau a,u ; Get ptr to wall data stb 0xC8DD ; Save loop counter P082B: ldd 0xC8DB ; Get object's (y,x) pos suba ,u ; Check if y falls within the bmi P0842 ; bounds of the current wall; cmpa 1,u ; move onto the next wall, bgt P0842 ; if not. subb 2,u ; Check if x falls within the bmi P0842 ; bounds of the current wall; cmpb 3,u ; move onto the next wall, bgt P0842 ; if not. ldb 4,u ; Return updated y or x pos orcc #0x02 ; Set overflow bit, to signal rts ; wall contact occurred. P0842: leau 5,u ; Point to next wall data block dec 0xC8DD ; More walls to process? bne P082B ; Branch if yes andcc #0xFD ; Clear overflow bit, to signal P084A: rts ; no wall contact occurred. ; InitPlayerData() ; ; Initializes the player data associated with each ; active player. ; InitPlayerData: ldu #RAMMES ; Set destination bufr ldy #0xC9C0 ; Save ptr to 1st missile ldx #JeepVlists ; Packet vlist to rotate lda 0xC8C8 ; Get # of players sta 0xC8C7 ; Save as # players still alive ldb #0x20 ; Player 1 starting y pos P085B: pshs a,b ; Save for later use sta ,u+ ; Init the state flag sty ,u++ ; Save addr of 1st missile ldb #0x08 ; Clear the next 8 bytes P0864: clr ,u+ ; of the user data. decb ; More bytes? bne P0864 ; Branch if yes ldd ,s ; Load x delta & y position std -6,u ; Save x delta & y position jsr PROT ; Rotate packet vlist leay 14,y ; Point to next player puls a,b ; Restore saved values negb ; Init player 2 starting y pos deca ; Another player? bne P085B ; Branch if yes rts; ; HelecopterExploding() ; ; Entry: x = ptr to helecopter position (C89D) ; a = Helecopter mode flag (TEMP6) ; HelecopterExploding: nega ; Check if helecopter was just bvc P088D ; hit; branch if not deca ; Decr helecopter intensity, clrb ; and clear scale; save the std TEMP4 ; updated values. asr T3FUNC ; Decrease y movement delta asr 0xC8A4 ; Decrease x movement delta decb ; Set to -1 stb 0xC8EF ; Flag helecopter exploding lda #0x80 ; Enable a sound (helecopter ora SATUS ; hit/exploding??) sta SATUS P088D: inc TEMP6 ; Increment helecopter state bne ContinueExplosion ; Branch if not done ; exploding clr 0xC8EF ; Clear helecopter exploding lda #0xF7 ; Disable a sound (helecopter anda SATUS ; exploding??) sta SATUS; rts; ; ContinueExplosion() ; ; Every few passes through this function, we will ; increase the allowed angle of fire for the next ; helecopter, and we will alter the angle used to ; draw the destroyed helecopter. We will also ; decrease the intensity used to draw the helecopter, ; and update the vector list. ; ContinueExplosion: rora bhs P08B7 ; Branch if bit 7 = 0 inc TMR4 ; Increase angle of fire ; allowed for next helecopter. dec T4FUNC ; Decr helecopter rotation angle rora bhs P08A8 ; Branch if bit 6 = 0 dec TEMP4 ; Decr helecopter intensity inc TEMP5 ; Incr helecopter scale P08A8: lda T4FUNC ; Get helecopter rotation angle leau 10,x ; Set destination bufr ldx #DestroyedHelecopterVlists ; Src vlist jsr PROT ; Rotate packet vlist lda T4FUNC ; Get helecopter rotation angle jsr PROT ; Rotate packet vlist P08B7: jmp ValidateHelePos ; ProcessHelecopter() ; ProcessHelecopter: ldx XTMR2 ; Get startup counter beq CheckHelecopter ; Skip if already processed (0) leax -1,x ; Decrement the counter and stx XTMR2 ; save updated value. bne P0910 ; Branch if not counted down to 0 lda #0xF7 ; Start a helecopter anda SATUS; sta SATUS; com ETMP8 ; Flag helecopter being processed ldx #TEMP6 ; Clear the first 25 bytes ldb #0x19 ; of the helecopter data jsr BCLR ; structure. lda #0x00; sta FEAST ; Set, but never referenced! lda #0x02; sta TEMP6 ; Set the helecopter state flag deca ; Don't have the helecopter fire sta TEMP7 ; a missile yet. ldd #RAMMES ; Config to initially stalk std ACTPLY ; player 1. lda ETMP1 ; Set counter controlling when sta TEMP8 ; to requery player's position. lda ETMP4 ; Set counter controlling when sta 0xC89A ; to fire a missile. leax 9,x; jsr RANDOM ; Load random # -> a; determines clrb ; edge helecopter enters from: rola ; bit 7: 0=top/bottom(set y pos) ; 1=left/right(set x pox) rolb ; bit 6: 0=right(x)/top(y) ; 1=left(x)/bottom(y) leax b,x ; Get ptr to y or x position stb 0xC8CB ; (0 or 1) ldb #0x7F ; Starting position rola ; If bit 6=1, then negate position bhs P08FE ; to start from left (if x) or negb ; bottom (if y). P08FE: stb ,x ; Save initial y or x position asrb ; Initialize the body offset asrb ; to be the initial position/4. stb 2,x ; Save initial body offset. lda #0x07; suba 0xC8CB ; (0 or 1) suba 0xC8CB ; (0 or 1) P090A: leax a,x; inc ,x; com TEMP10 ; Flag vlist needs updating P0910: rts; ; CheckHelecopter() ; CheckHelecopter: ldx #TEMP6 ; Get ptr to helecopter data jsr UpdateVlistIndex ; Update rotor index leax 9,x ; Get ptr to hele (y,x) pos lda TEMP6 ; Get helecopter state flag lbmi HelecopterExploding bne HelecopterActive; std ETMP10 ; Reset target position ldd 0xC8DE ; Reset helecopter processing std XTMR2 ; delay counter. rts; ; HelecopterActive() ; ; Entry: x = ptr to helecopter data (+9) HelecopterActive: lda #0x08; ora SATUS; sta SATUS; ldb TEMP10 ; Branch if helecopter body bpl TrackPlayer ; vlist doesn't need updating. leau 10,x ; Set dest bufr ldx #HelecopterBodyVlist ; Src vlist lda T4FUNC ; Get helecopter rotation angle jsr PROT ; Rotate packet vlist clr TEMP10 ; Clear 'needs update' flag bra ValidateHelePos ; TrackPlayer() ; ; Entry: x = pointer to helecopter data (+ 9) ; TrackPlayer: ldd ETMP10 ; Get pos of player to track tfr d,y ; Xfer pos to y register jsr CalcAngle1; Get angle to player anda ETMP2 ; Course tune the angle std 0xC8CD ; Store angle & proximity leax 9,x ; Get ptr to angle of travel cmpb #0x08 ; Is player close (w/in 8 units)? bls P0959 ; Branch if yes suba T4FUNC ; Sub helecopter rotation angle beq P0959 ; Branch if already heading in ; the desired direction. bsr UpdateTravelAngle ; Update angle of travel dec TEMP10 ; Flag that vlist needs updating P0959: leax -1,x; lda TEMP7 ; Based on whether the helecopter anda #0x01 ; is supposed to fire or just move, asla ; call the appropriate processing ldu #HelecopterActionTable ; function. jsr [ a,u ] ; ValidateHelePos() ; ; See if the helecopter has reached the boundary of the ; playing area, and if so, force it back in. ; ValidateHelePos: ldd #0x78FF ; Edge coordinate = 0x78; delta = -1 leax -6,x ; Get ptr to (y,x) offset cmpa ,x+ ; Is 'y' in range? blt P097E ; Branch if out of range cmpa ,x+ ; Is 'x' in range? blt P097E ; Branch if out of range nega ; Edge coordinate = -0x78 negb ; Delta = +1 leax -2,x ; Get ptr to (y,x) offset cmpa ,x+ ; Is 'y' in range? bgt P097E ; Branch if out of range cmpa ,x+ ; Is 'x' in range? blt P0980 ; Branch if in range P097E: stb 3,x ; Set the movement delta for the ; out of range coordinate. P0980: ldd TMR2 ; Get helecopter y/x pos offset adda T3FUNC ; Add y movement delta addb 0xC8A4 ; Add x movement delta std TMR2 ; Save updated y/x pos offset rts; ; UpdateTravelAngle() ; ; Entry: a = difference between the current angle of ; travel, and the desired angle of travel. ; x = pointer to helecopter's angle of travel. ; C8CD = desired angle of travel. ; ; Determines whether CW or CCW rotation is needed to ; bring the helecopter to the desired angle of travel. ; Updates the helecopter's angle of travel in the ; necessary direction. ; UpdateTravelAngle: anda #0x3F ; Make 0<=angle<360 ldb #0x01 ; Assume CCW angle delta cmpa #0x20 ; Angle delta <= 180 degrees? ble P0992 ; Branch if yes negb ; Use CW angle delta P0992: stb 0xC8CF ; Save angle delta value addb ,x ; Add current angle of travel andb #0x3F ; Make 0<=angle<360 cmpb 0xC8CD ; Match desired angle of travel? beq P09A0 ; Branch if yes addb 0xC8CF ; Add angle delta a second time andb #0x3F ; Make 0<=angle<360 P09A0: stb ,x ; Save updated angle of travel rts ; UpdateHelecopterHeading() ; ; Update the helecopter's angle of travel, as we ; track the player. ; UpdateHelecopterHeading: lda TEMP8 ; Is it time to get an update deca ; on the player's position? bne P09AA ; Branch if not bsr GetPlayerPos ; Get player's current pos P09AA: lda #0x02; sta FEAST ; Set, but never referenced! ldd T1FUNC ; Get hele's nose (y,x) offset jsr CalcAngle3; Get angle to player & proximity cmpb #0x04 ; Are they really close? ble EnableMissileFire ; Allow firing, if so tfr a,b ; Set rotation angle lda #0x01 ; Velocity = 1 jsr LROT90 ; Calc heading change deltas std 0xC8A1 ; Save heading change deltas adda T1FUNC ; Add helecopter's y position addb 0xC89E ; Add helecopter's x position std T1FUNC ; Update hele's (y,x) position rts; ; EnableMissileFire() ; ; If we an update position for the player, then enable ; missile firing. ; EnableMissileFire: lda TEMP8 ; Have we already updated the bne AdjTargetPos ; player's pos? Branch if not. sta TEMP7 ; Prepare hele to fire missile rts; ; AdjTargetPos() ; ; Rather than firing directly where the player was, add ; some random adjustments to the target location, so give ; the player a chance. ; AdjTargetPos: dec TEMP8 ; Decr 'update' counter, and beq GetPlayerPos ; Update player's pos if 0. jsr RANDOM ; 'Adjust' the perceived 'y' adda ETMP10 ; location of the player we're sta ETMP10 ; targeting. rola ; 'Adjust' the perceived 'x' rola ; location of the player we coma ; are targeting. In other words, adda 0xC88D ; allow for some randomness when sta 0xC88D ; targeting a missile. rts ; GetPlayerPos() ; ; Entry: ACTPLY = ptr to player being stalked ; ; Exit: ETMP10 = player's position ; cc = 0 (no position set) ; 1 (ETMP10 updated with pos) ; ACTPLY = ptr to player to stalk ; ; If player 1 is alive, get his position. ; Otherwise, set up to return player 2's ; position the next time we are called. ; GetPlayerPos: ldu ACTPLY ; Get ptr to player being stalked lda ,u ; Get player's state flag bgt P09F5 ; Branch if alive ldu #0xCA27 ; Get ptr to player 2 data stu ACTPLY ; Save as player being stalked lda #0x01 ; Don't have the helecopter sta TEMP7 ; fire yet. inc TEMP8 ; Force another update later orcc #0x02 ; Flag no position set rts; P09F5: lda 6,u ; Get player's y pos ldb 8,u ; Get player's x pos std ETMP10 ; Save position andcc #0xFE ; Flag that position was set P09FD: rts; ; FireHelecopterMissile() ; FireHelecopterMissile: lda #0x01; sta FEAST ; Set, but never referenced! jsr GetPlayerPos ; Get player's position bvs P09FD ; Branch if no player found std T1FUNC ; Update hele's nose offset ldd 0xC8CD ; Load angle & proximity to player suba TMR4 ; Subtract allowed angle of fire beq P0A26 ; Branch if target within allowed ; angle of fire. cmpb #0x10 ; Is player close? bls P0A26 ; Branch if yes ldb TEMP9 ; Update counter controlling incb ; when helecopter angle of andb ETMP3 ; travel should be updated. stb TEMP9 ; Save updated value bne P0A26 ; Update only when = 0 jsr UpdateTravelAngle; lda #0x02 ; Velocity = 2 jsr LROT90 ; Calc movement deltas std T3FUNC ; Save movement deltas P0A26: dec 0xC89A ; Time to fire? bgt P09FD ; Branch if not ldu #0xC9DC ; Ptr to missile data lda ,u ; Missile in use already? bne P09FD ; Branch if yes ldd T1FUNC ; Get hele's nose offset adda TMR2 ; Add y position offset bvs P09FD ; Skip if overflow addb T2FUNC ; Add x position offset bvs P09FD ; Skip if overflow std 1,u ; Save starting position lda ETMP4 ; Reset cntr for next sta 0xC89A ; attempt to fire. dec ,u ; Flag missile as active ldb T4FUNC ; Get hele rotation angle jsr CalcMovementDelta; lda T4FUNC ; Get hele rotation angle ldu #0xCA7E ; Missile vlist buffer ldx #MissileVlist ; Src vlist to rotate ldb #0x04 ; Vector count-1 (5) jmp DROT ; Rotate the vlist HelecopterActionTable: dw FireHelecopterMissile dw UpdateHelecopterHeading ; CheckForMissileHits() ; CheckForMissileHits: neg TEMP3 ; Toggle between using big & ; small missile movement deltas. ldy #0xC8E3 ; Ptr to player 1 bonus info clr 2,y ; Clear player 1 bonus clr 3,y ; Clear player 2 bonus lda #0x02 ; Flag we're processing sta 0xC8DA ; player 1's missiles. ldx #0xC9C0 ; Ptr to 1st missile ldd #CheckForHelecopterHit; std 0xC8CC ; Set processing function ldb #0x08 ; Loop cntr (8 missiles) P0A71: stb 0xC8D2 ; Save/update loop cntr lda ,x ; Get missile state bmi UpdateMissilePos ; Branch if active beq P0A92 ; Branch if not in use ldu #0xCB00 ; Ptr to expl position array deca ; Decr state counter sta ,x ; Store updated value anda #0x03 ; Every 4th pass, double bne P0A8B ; the scale factor use to ldb 4,x ; draw the explosion, and addb 4,x ; decrement the dwell (intens). stb 4,x ; Store update scale factor dec 3,x ; Decrement the dwell value P0A8B: ldb #0x08 ; Create an offset into the mul ; array of explosion locations. leau b,u ; Get ptr to explosion data stu 5,x ; Update explsn vlist ptr P0A92: leax 7,x ; Point to next missile ldb 0xC8D2 ; Get loop counter decb ; Decrement it beq P0AAC ; Branch if all processed cmpb #0x06 ; Player 2's 1st missile? bne P0A9F ; Branch if not inc 0xC8DA ; Flag plyr 2 processing P0A9F: cmpb #0x04 ; Helecopter missile? bne P0A71 ; Branch if not ldu #CheckForSystemMissileHits; stu 0xC8CC ; Set processing function inc 0xC8DA ; Flag we're processing bra P0A71 ; system missiles. P0AAC: rts; ; UpdateMissilePos() ; ; Entry: x = ptr to missile data ; UpdateMissilePos: lda TEMP3 ; Use big (-1) or small (1) adda #0x04 ; missile movement deltas. leau a,x ; Get ptr to y & x deltas ldd 1,x ; Get missile's (y,x) pos adda ,u ; Update y pos addb 1,u ; Update x pos std 1,x ; Save updated position jsr ABSAB ; Get abs val of a & b std 0xC8DB ; Save new values cmpa #0x78 ; Explode the missile if bhs ExplodeMissile ; it has reached cmpb #0x78 ; the outer bounds of the bhs ExplodeMissile ; playing area. ldu #VerticalWalls ; Check if missile jsr CheckForWallContact ; has hit a bvs ExplodeMissile ; vertical wall. ldb 0xC8DB ; Get missile's x pos ldu #HorizontalWalls ; Check if missile jsr CheckForWallContact ; has hit a bvs ExplodeMissile ; horizontal wall. ldu #0xC900 ; Ptr to tank 1 data ldb SJOY ; Get max # tanks allowed P0ADF: stb 0xC8CB ; Save/update loop cntr subb 0xC8D2 ; Sub missile loop cntr addb #0x03; subb SJOY; beq P0B0B; ldd ,u; tsta ; Check tank's state flag beq P0B0B ; Skip if tank is not active cmpb #0x02 ; Skip if the tank is disabled; bge P0B0B ; i.e. already has 2 hits. lda #0x05 ; Set the target half size sta 0xC8E8 ; for the tank (10x10). ldd 14,u ; Get tank's position bsr CheckForMissileHit bvc P0B0B ; Branch if no hit ldb 1,u ; Get # hits on tank lda b,y ; Load bonus value for hit ldb 0xC8DA ; Do a BCD add of the new adda b,y ; bonus value to the player's daa ; cumulative bonus value, and sta b,y ; save it. inc 1,u ; Register hit on the tank bra ExplodeMissile ; Explode the missile P0B0B: leau 0x40,u ; Get ptr to next tank ldb 0xC8CB ; Get loop counter decb ; Decr loop counter bne P0ADF ; Branch if more tanks jsr [ 0xC8CC ] ; Call processing proc lbvc P0A92 ; Branch if no hit ExplodeMissile: lda #0x08 ; Set missile state flag sta ,x ; to show it's exploding. ldd #0x090A ; Set dwell (0x09) and std 3,x ; scale factor (0x0A). ldd #0xCB00 ; Explosion end points std 5,x ; Set explosion vlist jmp P0A92; ; CheckForSystemMissileHits() ; CheckForSystemMissileHits: ldu #RAMMES ; Ptr to player 1 data P0B2F: lda ,u ; Get player's state flag ble P0B46 ; Branch if dead/exploding lda #0x02 ; Set the target size of sta 0xC8E8 ; the player (4x4). lda 6,u ; Get player's y pos ldb 8,u ; Get player's x pos bsr CheckForMissileHit bvc P0B46 ; Branch if no hit lda #0x80 ; Flag the player as sta ,u ; being hit. orcc #0x02 ; Signal a hit occurred. rts P0B46: leau 0x27,u ; Get ptr to next player cmpu #0xCA4E ; All done? bne P0B2F ; Branch if not done andcc #0xFD ; Signal no hit occurred. rts ; CheckForMissileHit() ; ; Entry: x = ptr to missile data ; a = target y ; b = target x ; C8E8 = target half size ; CheckForMissileHit: suba 1,x ; Get delta between missile bvs P0B6B ; and target y; branch if bpl P0B59 ; overflow. Else, get abs nega ; value of the delta. P0B59: subb 2,x ; Get delta between missile bvs P0B6B ; and target x; branch if bpl P0B60 ; overflow. Else, get abs negb ; value of the delta. P0B60: cmpa 0xC8E8 ; Is y within the target? bgt P0B6B ; Branch if not cmpb 0xC8E8 ; Is x within the target? bgt P0B6B ; Branch if not orcc #0x02 ; Signal a hit occurred rts P0B6B: andcc #0xFD ; Signal no hit occurred rts ; CheckForHelecopterHit() ; ; Entry: x = Ptr to missile data ; y = ptr to player 1 bonus info (-2) ; CheckForHelecopterHit: lda TEMP6 ; Get Helecopter state flag ble P0BCD ; Branch if inactive/exploding ldd T1FUNC ; Get hele's (y,x) offset adda TMR2 ; Add y offset position bvs P0BCD ; Branch if invalid (overflow) addb T2FUNC ; Add x offset position bvs P0BCD ; Branch if invalid (overflow) suba 1,x ; Subtract missile y bvs P0BCD ; Branch if invalid (overflow) subb 2,x ; Subtract missile x bvs P0BCD ; Branch if invalid (overflow) asra ; Divide y difference by 2 asrb ; Divide x difference by 2 std 0xC8CF ; Save y & x differences ldb T4FUNC ; Get helecopter rotation angle subb #0x40 ; Adjust angle andb #0x3F ; Force in 0-360 range jsr LNROT ; Rotate single line std 0xC8CE ; Save rotated (y,x) endpt lda 0xC8D0 ; Velocity ldb ANGLE ; Get angle of travel jsr LROT90 ; Calc movement deltas adda 0xC8CE ; Take into account the hele's ; pending y movement. bpl P0B9F ; Branch if positive nega ; Make positive P0B9F: addb 0xC8CF ; Take into account the hele's ; pending x movement. bpl P0BA4 ; Branch if positive negb ; Make positive P0BA4: cmpa #0x02 ; Is missile within 2 y units? bgt P0BCD ; Branch if not cmpb #0x04 ; Is missile within 4 x units? bgt P0BCD ; Branch if not lda #0x80 ; Set helecopter state flag sta TEMP6 ; to signal it's been hit. ldb 0xC8DA ; Based on whose missile it lda b,y ; was, add a 1000 point adda #0x0A ; bonus to the appropriate daa ; player's bonus area. sta b,y ; Save the new bonus value ldb 1,y ; Get the current bonus for incb ; the second tank hit. Incr it. cmpb #0x08 ; Has it reached 800 points? bne P0BC8 ; Branch if not inc 0xC8E2 ; Award a bonus jeep bne P0BC6 ; Are they now at 0 jeeps? dec 0xC8E2 ; If so, then remove bonus jeep; ; player must have just died also. P0BC6: ldb #0x02 ; Reset 2nd hit bonus to 200 points P0BC8: stb 1,y ; Save updated 2nd hit bonus orcc #0x02 ; Signal a hit occurred rts P0BCD: andcc #0xFD ; Signal no hit occurred rts P0BD0: jmp EXPLOD ; Make explosion noise ; MakeSounds() ; MakeSounds: ldu #ExplosionSounds ; Load ptr to sound lda 0xC8EF ; Helecopter exploding? beq P0BE5 ; Branch if not bmi P0BD0 ; Branch if yes dec 0xC8EF ; leau 4,u ; Ptr to alt explosion snd jsr EXPLOD ; Make explosion sound bra P0C33; P0BE5: lda #0x0F; sta REQ5 ; Channel A amplitude sta REQ4 ; Channel B amplitude sta REQ3 ; Channel C amplitude ldb REQ6 ; Tone/Noise enables lda SATUS ; Check if tank sounds anda #0x03 ; are enabled. beq P0C2F ; Branch if not andb #0xF9 ; Enable tone chans B&C orb #0x30 ; Disable noise chans B&C stb REQ6 ; Tone/Noise enables adda BACON; sta BACON; bita #0x08; bne P0C07; orb #0x04 ; Disable tone channel C stb REQ6 ; Tone/Noise enables P0C07: bita #0x10; bne P0C0D; eora #0x07; P0C0D: anda #0x07; adda #0x10; sta REQ9 ; Channel C fine tone period clr REQ8 ; Channel C course tone period lda #0x08; sta REQ3 ; Channel C amplitude lda SATUS; bita #0x01 ; Slow tank sounds? beq P0C24 ; Branch if not (then fast tanks) ldd #0x0FFF ; Chan B course/fine tone period bra P0C27; ; Fast moving tanks sounds P0C24: ldd #0x0BFF ; Chan B course/fine tone period P0C27: std REQA ; Channel B course tone period (a) ; Channel B fine tone period (b) lda #0x0E ; New Chan B amplitude std REQ4 ; Channel B amplitude (a) ; Channel A amplitude (b) bra P0C33; P0C2F: orb #0x36 ; Disable noise & tone chans B&C stb REQ6 ; Tone/Noise enables P0C33: ldb REQ6 ; Tone/Noise enables lda SATUS ; Is the helecopter flying sound bita #0x08 ; enabled? beq P0C59 ; Branch if not inc GAP; lda GAP; bita #0x02; beq P0C59; andb #0xF7 ; Enable noise channel A stb REQ6 ; Tone/Noise enables rora; ldb #0x20; blo P0C4D; lsrb; P0C4D: clra; std REQC ; Channel A course tone period ; Channel A fine tone period ldb #0x03; stb REQ7 ; Noise period lda #0x0D; sta REQ5 ; Channel A amplitude rts; P0C59: orb #0x09 ; Disable noise & tone chan A stb REQ6 ; Noise/Tone enables rts; ExplosionSounds: db 0x3B ; Channel enables db 0x00 ; Sweep freq (up) db 0x00 ; Sweep vol (up) db 0x01 ; Explosion duration db 0x36 ; Channel enables db 0x78 ; Sweep freq (down) db 0x00 ; Sweep vol (up) db 0x04 ; Explosion duration ; CalcAngle1() ; ; Entry: x = ptr to tracker's (y,x) position ; y = target (player) position ; ; Exit: a = angle from tracker to target ; b = sum of abs(delta y + delta x) ; (for proximity testing). ; ; Calculates the angle from the tracker to the ; target. ; CalcAngle1: ldd ,x ; Get tracker's (y,x) pos asra ; Divide y by 2 asrb ; Divide x by 2 std -2,s ; Save results on stack ldd 2,x ; Get tracker's movement deltas asra ; Divide y delta by 2 asrb ; Divide x delta by 2 adda -2,s ; Add adjusted y delta to y pos addb -1,s ; Add adjusted x delta to x pos bra P0C82 ; CalcAngle2() ; ; Entry: u = ptr to player's (y,x) position ; d = trackers (y,x) position ; ; Exit: a = angle from tracker to target ; b = sum of abs(delta y + delta x) ; (for proximity testing). ; ; Calculates the angle from the tracker to the ; target. ; CalcAngle2: pshs a,b ; Save tank's (y,x) pos lda ,u ; Get player's y pos ldb 2,u ; Get player's x pos tfr d,y ; Xfer position to y register puls a,b ; Restore tank's (y,x) pos ; CalcAngle3() ; ; Entry: d = Tracker's (y,x) position ; y = target (player) position ; ; Exit: a = angle from tracker to target ; b = sum of abs(delta y + delta x) ; (for proximity testing). ; ; Calculates the angle from the tracker to the ; target. This appears to be used to do a gradual ; angle adjustment, since it halves the tracker's ; angle, before doing the calculation. ; CalcAngle3: asra ; Divide y by 2 asrb ; Divide x by 2 P0C82: pshs a,b ; Save tracker's updated pos tfr y,d ; Get target's position asra ; Divide y by 2 asrb ; Divide x by 2 suba ,s+ ; Get delta between the y's subb ,s+ ; Get delta between the x's pshs a,b ; Save the delta values jsr CMPASS ; Use the result to calc the ; angle from the tracker to ; the target. puls a,b ; Restore the delta values jsr ABSAB ; Get abs val of the deltas pshs a ; Sum the abs value of the 2 orb ,s+ ; deltas, to get proximity val lda ANGLE ; Load calculated angle rts; ; DrawPacketVlist() ; ; Entry: b = scale factor ; x = packet vlist pointer ; DrawPacketVlist: jsr TPACK ; Draw packet vlist jmp ZERGND; ; UpdateScore() ; ; This is an iterator function. ; UpdateScore: lda ,u+ ; Get upper BCD score byte clrb ; Lower BCD score byte = "00" jsr SCRADD ; Add "xx00" to score str leax 9,x ; Pt to next score str rts; ; CreateHelecopterRotors() ; ; Entry: x = ptr to diffy rotor vlist ; u = ptr to destination buffer ; b = vector count - 1 ; ; Takes the source rotor vlist (3 vectors) and ; creates four copies, each rotated at 90 degrees ; from the each other, to produce a set of rotors. ; It does this four times, to produce 4 complete ; sets of rotors, each at a slightly different ; rotation angle. These will be used to produce ; the effect of rotating helecopter rotors. ; The 4 sets of 12 vectors are stored into the ; destination buffer. ; CreateHelecopterRotors: leay ,x ; Save ptr to rotor diffy vlist lda #0x04 ; Outer loop counter pshs a,b ; Save loop cntr & # vectors ldb #0x04 ; b = angle (22.5 degrees) pshs a,b ; a = inner loop counter P0CB6: lda 1,s ; Get rotation angle P0CB8: adda #0x10 ; Adjust: add 90 degrees sta 1,s ; Save updated value ldb 3,s ; Set vector count -1 jsr DROT ; Rotate rotor diffy vlist leax ,y ; Restore ptr to rotor vlist dec ,s ; Decr inner loop counter bne P0CB6 ; Branch if more iterations lda #0x04 ; Reset inner sta ,s ; loop counter. adda 1,s ; Adj angle (add 22.5 degrees) dec 2,s ; Decr outer loop counter bne P0CB8 ; Branch if more iterations leas 4,s ; Clean up stack rts ; DisableAllTanks() ; ; Disables all tanks, by setting their state flag ; to 0. ; DisableAllTanks: ldx #0xC900 ; Ptr to 1st tank bufr ldd #0x0340 ; a=loop cnt; b=bufr size ; DisableObjects() ; ; Entry: x = ptr to first object to be disabled ; a = # of objects to disable ; b = size of each object ; DisableObjects: clr ,x ; Disable this object abx ; Point to next object deca ; Decrement loop counter bne DisableObjects ; More interations? rts ; CopyRandomArrayData() ; ; Entry: a = offset mask ; u = ptr to source array ; x = ptr to destination ; b = # of bytes to copy ; ; Generates a random number, which is then masked ; using the specified offset mask. The result is ; used to index into the specified array. Each ; byte in the source array is divided by 4, and ; then copied into the destination buffer. The ; specified number of bytes are copied. ; CopyRandomArrayData: pshs a,b; jsr RANDOM ; Load random # -> a anda ,s+ ; Mask with offset mask leau a,u ; Offset into src array puls a ; Get # bytes to copy P0CEC: ldb ,u+ ; Get next byte asrb ; Divide the value asrb ; by 4. stb ,x+ ; Store in dest buffer deca ; Decr loop counter bne P0CEC ; Branch if more bytes rts ; CopyUtoX() ; ; Entry: u = ptr to source buffer ; x = ptr to destination buffer ; a = # bytes to copy ; CopyUtoX: ldb ,u+ ; Get next byte stb ,x+ ; Save in dest buffer deca ; Decr loop counter bne CopyUtoX ; Branch if more bytes rts db 0x12; ; Values used to initialize C880-C887 LevelSpecificData: db 0x01 ; Use slow tank sounds db 0x01 ; Max # of tanks db 0x02 ; Tank body angle delta db 0x06 ; Resync plyr's pos counter db 0xFC ; Course tuning angle mask db 0x03 ; Hele angle update mask db 0x20 ; Delay before firing missile db 0x08 ; Index to level-specific data db 0x01 ; Use slow tank sounds db 0x02 ; Max # of tanks db 0x02 ; Tank body angle delta db 0x04 ; Resync plyr's pos counter db 0xFD ; Course tuning angle mask db 0x01 ; Hele angle update mask db 0x20 ; Delay before firing missile db 0x10 ; Index to level-specific data db 0x01 ; Use slow tank sounds db 0x02 ; Max # of tanks db 0x02 ; Tank body angle delta db 0x02 ; Resync plyr's pos counter db 0xFD ; Course tuning angle mask db 0x01 ; Hele angle update mask db 0x20 ; Delay before firing missile db 0x18 ; Index to level-specific data db 0x01 ; Use slow tank sounds db 0x03 ; Max # of tanks db 0x02 ; Tank body angle delta db 0x02 ; Resync plyr's pos counter db 0xFD ; Course tuning angle mask db 0x01 ; Hele angle update mask db 0x1C ; Delay before firing missile db 0x20 ; Index to level-specific data db 0x01 ; Use slow tank sounds db 0x03 ; Max # of tanks db 0x02 ; Tank body angle delta db 0x02 ; Resync plyr's pos counter db 0xFE ; Course tuning angle mask db 0x01 ; Hele angle update mask db 0x1C ; Delay before firing missile db 0x28 ; Index to level-specific data db 0x02 ; Use fast tank sounds db 0x03 ; Max # of tanks db 0x02 ; Tank body angle delta db 0x01 ; Resync plyr's pos counter db 0xFE ; Course tuning angle mask db 0x01 ; Hele angle update mask db 0x1C ; Delay before firing missile db 0x30 ; Index to level-specific data db 0x02 ; Use fast tank sounds db 0x03 ; Max # of tanks db 0x02 ; Tank body angle delta db 0x01 ; Resync plyr's pos counter db 0xFF ; Course tuning angle mask db 0x00 ; Hele angle update mask db 0x1C ; Delay before firing missile db 0x38 ; Index to level-specific data db 0x02 ; Use fast tank sounds db 0x03 ; Max # of tanks db 0x04 ; Tank body angle delta db 0x01 ; Resync plyr's pos counter db 0xFF ; Course tuning angle mask db 0x00 ; Hele angle update mask db 0x14 ; Delay before firing missile db 0x38 ; Index to level-specific data Defaults: db 0x02 ; Counter - delay before db 0x00 ; processing helecopter. db 0x30 ; Counter - tank startup delay db 0xFF ; Counter - startup delay db 0x05 ; Starting jeep count db 0x02 ; Value for 1st tank hit (0200) db 0x03 ; Value for 2nd tank hit (0300) JeepVlists: Jeep1: db 0x00, 0x08, 0x0C db 0xFF, 0xF0, 0x00 db 0xFF, 0x00, 0xE8 db 0xFF, 0x10, 0x00 db 0xFF, 0x00, 0x18 db 0x00, 0xF4, 0x00 db 0xFF, 0xFC, 0xF6 db 0xFF, 0x10, 0x00 db 0xFF, 0xFC, 0x0A db 0x01 Jeep2: db 0x00, 0x08, 0x0C db 0xFF, 0xF0, 0x00 db 0xFF, 0x00, 0xE8 db 0xFF, 0x10, 0x00 db 0xFF, 0x00, 0x18 db 0xFF, 0xF0, 0xF6 db 0xFF, 0x10, 0x00 db 0xFF, 0xF0, 0x0A db 0x01 MissileVlist: db 0x00 DftTankAttrsBase: db 0x1B db 0x00 db 0xEE db 0x03 db 0xFD db 0xFA db 0x00 db 0x03 db 0x03 DftTankAttrs: Tank1: db 0x0F ; db 0x0F ; db 0x02 ; scale db 0x08 ; index db 0x18 ; y db 0x78 ; x db 0x00 ; delta y db 0x01 ; delta x db 0x30 ; angle Tank2: db 0x0A ; db 0x0A ; db 0x02 ; scale db 0x08 ; index db 0x38 ; y db 0x78 ; x db 0x00 ; delta y db 0x01 ; delta x db 0x30 ; angle Tank3: db 0x06 ; db 0x06 ; db 0x03 ; scale db 0x08 ; index db 0x78 ; y db 0x38 ; x db 0x01 ; delta y db 0x00 ; delta x db 0x00 ; angle S0DA0: db 0x00 db 0x02 db 0x01 db 0x01 db 0x00 db 0x20 db 0x08 db 0x08 db 0x0B db 0x03 db 0x02 db 0x01 db 0x30 db 0x30 db 0x08 db 0x20 db 0x04 db 0x00 db 0x03 db 0x02 db 0x10 db 0x00 db 0x08 db 0x30 db 0x00 db 0x05 db 0x03 db 0x00 db 0x00 db 0x18 db 0x10 db 0x00 db 0x06 db 0x00 db 0x00 db 0x04 db 0x20 db 0x00 db 0x00 db 0x18 db 0x00 db 0x00 db 0x05 db 0x07 db 0x00 db 0x00 db 0x20 db 0x18 db 0x08 db 0x06 db 0x00 db 0x0B db 0x20 db 0x18 db 0x00 db 0x30 db 0x00 db 0x00 db 0x07 db 0x09 db 0x00 db 0x00 db 0x20 db 0x20 db 0x0A db 0x08 db 0x00 db 0x0C db 0x18 db 0x20 db 0x00 db 0x10 db 0x00 db 0x00 db 0x09 db 0x0F db 0x00 db 0x00 db 0x18 db 0x20 db 0x0C db 0x07 db 0x02 db 0x00 db 0x20 db 0x30 db 0x30 db 0x00 db 0x00 db 0x09 db 0x0B db 0x0D db 0x00 db 0x10 db 0x20 db 0x10 db 0x0F db 0x0C db 0x00 db 0x0E db 0x18 db 0x10 db 0x00 db 0x10 db 0x00 db 0x0D db 0x00 db 0x0E db 0x00 db 0x10 db 0x00 db 0x08 db 0x00 db 0x0A db 0x0D db 0x00 db 0x00 db 0x20 db 0x18 db 0x00 ; Pairs of (y,x) values OuterBoundaryVlists: db 0x30, 0x00 db 0x00, 0x60 db 0xD0, 0x00 db 0x00, 0x40 db 0xC0, 0x00 db 0x00, 0x30 db 0xA0, 0x00 db 0x00, 0xD0 db 0xC0, 0x00 db 0x00, 0x30 db 0xA0, 0x00 db 0x00, 0xD0 db 0xC0, 0x00 db 0x00, 0xC0 db 0xD0, 0x00 db 0x00, 0xA0 db 0x30, 0x00 db 0x00, 0xC0 db 0xD0, 0x00 db 0x00, 0xA0 db 0x30, 0x00 db 0x00, 0xC0 db 0x40, 0x00 db 0x00, 0xD0 db 0x60, 0x00 db 0x00, 0x30 db 0x40, 0x00 db 0x00, 0xD0 db 0x60, 0x00 db 0x00, 0x30 db 0x40, 0x00 db 0x00, 0x40 db 0x30, 0x00 db 0x00, 0x60 db 0xD0, 0x00 db 0x00, 0x40 ; Pairs of (y,x) values LgSquareBuildingVlist: db 0x00, 0x40 db 0xC0, 0x00 db 0xC0, 0x00 db 0x00, 0xC0 db 0x40, 0x00 db 0x40, 0x00 ; Pairs of (y,x) values SmSquareBuildingVlist: db 0x00, 0x20 db 0x40, 0x00 db 0x00, 0xE0 db 0xC0, 0x00 ; Pairs of (y,x) values LBuildingVlists: db 0x00, 0x40 db 0x48, 0x00 db 0x00, 0xE0 db 0xD8, 0x00 db 0x00, 0xE0 db 0xE0, 0x00 db 0x20, 0x00 db 0x00, 0xE0 db 0x28, 0x00 db 0x00, 0xE0 db 0xB8, 0x00 db 0x00, 0x40 db 0xE0, 0x00 db 0x00, 0xE0 db 0xD8, 0x00 db 0x00, 0xE0 db 0x48, 0x00 db 0x00, 0x40 db 0x00, 0x40 db 0xB8, 0x00 db 0x00, 0xE0 db 0x28, 0x00 db 0x00, 0xE0 db 0x20, 0x00 AllVlistAttrs: db 0x04 ; # of vlists db 0x08 ; Vector count - 1 db 0x60 ; relative y1 db 0x10 ; relative x1 db 0xF0 ; relative y2 db 0x60 ; relative x2 db 0xA0 ; relative y3 db 0xF0 ; relative x3 db 0x10 ; relative y4 db 0xA0 ; relative x4 ; Attributes for LgSquareBuildingVlist db 0x02 ; # of iterations db 0x05 ; vector count - 1 db 0x20 ; relative y1 db 0x20 ; relative x1 db 0x20 ; relative y2 db 0xC0 ; relative x2 ; Attributes for SmSquareBuildingVlist db 0x04 ; # of iterations db 0x03 ; vector count - 1 db 0x30 ; relative y1 db 0x40 ; relative x1 db 0x30 ; relative y2 db 0xB0 ; relative x2 db 0xB0 ; relative y3 db 0xB0 ; relative x3 db 0xB0 ; relative y4 db 0x40 ; relative x4 ; Attributes for LBuildingVlists db 0x04 ; # of vlists db 0x05 ; vector count - 1 db 0x40 ; relative y1 db 0x10 ; relative x1 db 0x40 ; relative y2 db 0xF0 ; relative x2 db 0xC0 ; relative y3 db 0xF0 ; relative x3 db 0xC0 ; relative y4 db 0x10 ; relative x4 TankBodyVlist: db 0x00, 0x0C, 0x08 db 0xFF, 0x00, 0xF0 db 0xFF, 0xE8, 0x00 db 0xFF, 0x00, 0x10 db 0xFF, 0x18, 0x00 db 0x00, 0xF4, 0xF8 db 0x01 TankTurretVlist: db 0xFF, 0x04, 0x00 db 0xFF, 0x04, 0xFC db 0xFF, 0xFC, 0xF0 db 0xFF, 0xF8, 0x00 db 0xFF, 0xFC, 0x10 db 0xFF, 0x04, 0x04 db 0xFF, 0x04, 0x00 db 0xFF, 0x00, 0x28 db 0x01 DestroyedTankBodyVlist: db 0x00, 0x0A, 0x05 db 0xFF, 0x04, 0xF0 db 0xFF, 0xEF, 0x06 db 0xFF, 0xF7, 0xFD db 0xFF, 0xFD, 0x11 db 0xFF, 0x0F, 0xF7 db 0x01 DestroyedTurretVlist: db 0xFF, 0x06, 0xFA db 0xFF, 0xFE, 0xFC db 0xFF, 0x02, 0xF8 db 0xFF, 0xFA, 0xFE db 0xFF, 0xFC, 0x06 db 0xFF, 0x08, 0x10 db 0xFF, 0xFE, 0x14 db 0xFF, 0x02, 0x14 db 0x01 ; Vertical wall boundaries ; ; | * * ; | * * ;70 + * * ; | * * ; | * * ; | * * ;60 + * * * * * ; | * * * ; | * * * ; | * * * ;50 + * * * ; | * * * * * * ; | * * * * * ; | * * * * * ;40 + * * * * * ; | * * * ; | * * * ; | * * * ;30 + * * * ; | * ; | * ; | * ;20 + * ; | * * * ; | * * * ; | * * * ;10 + * * * ; | * * * * ; | * * * ; | * * * ;00 +---+---*---+--*+---+---*---+-- ; 00 10 20 30 40 50 60 70 ; VerticalWalls: db 0x0E ; offset (0x0A-0x19) db 0x02 ; # of walls db 0x18 ; offset (0x1A-0x29) db 0x02 ; # of walls db 0x22 ; offset (0x2A-0x39) db 0x01 ; # of walls db 0x27 ; offset (0x3A-0x49) db 0x03 ; # of walls db 0x36 ; offset (0x4A-0x59) db 0x01 ; # of walls db 0x3B ; offset (0x5A-0x69) db 0x02 ; # of walls db 0x45 ; offset (0x6A-0x79) db 0x01 ; # of walls db 0x60 ; min y db 0x1C ; max y delta db 0x0C ; min x db 0x04 ; max x delta db 0x10 ; updated x pos db 0x40 ; min y db 0x10 ; max y delta db 0x10 ; min x db 0x04 ; max x delta db 0x10 ; updated x pos db 0x4C ; min y db 0x18 ; max y delta db 0x20 ; min x db 0x04 ; max x delta db 0x20 ; updated x pos db 0x00 ; min y db 0x20 ; max y delta db 0x20 ; min x db 0x04 ; max x delta db 0x20 ; updated x pos db 0x40 ; min y db 0x24 ; max y delta db 0x2C ; min x db 0x04 ; max x delta db 0x30 ; updated x pos db 0x60 ; min y db 0x1C ; max y delta db 0x40 ; min x db 0x04 ; max x delta db 0x40 ; updated x pos db 0x30 ; min y db 0x20 ; max y delta db 0x40 ; min x db 0x04 ; max x delta db 0x40 ; updated x pos db 0x00 ; min y db 0x20 ; max y delta db 0x3C ; min x db 0x04 ; max x delta db 0x40 ; updated x pos db 0x30 ; min y db 0x20 ; max y delta db 0x4C ; min x db 0x04 ; max x delta db 0x50 ; updated x pos db 0x40 ; min y db 0x24 ; max y delta db 0x60 ; min x db 0x04 ; max x delta db 0x60 ; updated x pos db 0x00 ; min y db 0x10 ; max y delta db 0x60 ; min x db 0x04 ; max x delta db 0x60 ; updated x pos db 0x0C ; min y db 0x34 ; max y delta db 0x78 ; min x db 0x04 ; max x delta db 0x78 ; updated x pos ; Horizontal wall boundaries ; FDT - Note bug, marked by 'xx'; this ; wall invisibly extends 8 units ; beyond where the physical wall ; really is! ; ; | ************** ; | ;70 + ; | ; | ; | ;60 **** **** ********** ; | ; | ; | ;50 + ; | ****** **** ; | ; | ;40 + ********xx ******* ; | ; | ; | ;30 + **** ; | ; | ; | ;20 + ; | ******** ; | ; | ;10 + ; | ******* ; | ; | ;00 +---+---+---+---+---+---+---+-- ; 00 10 20 30 40 50 60 70 ; HorizontalWalls: db 0x0E ; offset (0x0A-0x19) db 0x01 ; # of walls db 0x13 ; offset (0x1A-0x29) db 0x01 ; # of walls db 0x18 ; offset (0x2A-0x39) db 0x01 ; # of walls db 0x1D ; offset (0x3A-0x49) db 0x02 ; # of walls db 0x27 ; offset (0x4A-0x59) db 0x02 ; # of walls db 0x31 ; offset (0x5A-0x69) db 0x03 ; # of walls db 0x40 ; offset (0x6A-0x79) db 0x01 ; # of walls db 0x0C ; min y db 0x04 ; max y delta db 0x60 ; min x db 0x1C ; max x delta db 0x10 ; updated y pos db 0x1C ; min y db 0x04 ; max y delta db 0x20 ; min x db 0x20 ; max x delta db 0x20 ; updated y pos db 0x30 ; min y db 0x04 ; max y delta db 0x40 ; min x db 0x10 ; max x delta db 0x30 ; updated y pos db 0x40 ; min y db 0x04 ; max y delta db 0x10 ; min x db 0x28 ; max x delta db 0x40 ; updated y pos db 0x40 ; min y db 0x03 ; max y delta db 0x60 ; min x db 0x1C ; max x delta db 0x40 ; updated y pos db 0x4C ; min y db 0x04 ; max y delta db 0x10 ; min x db 0x14 ; max x delta db 0x50 ; updated y pos db 0x4C ; min y db 0x04 ; max y delta db 0x40 ; min x db 0x10 ; max x delta db 0x50 ; updated y pos db 0x60 ; min y db 0x04 ; max y delta db 0x00 ; min x db 0x10 ; max x delta db 0x60 ; updated y pos db 0x60 ; min y db 0x04 ; max y delta db 0x20 ; min x db 0x10 ; max x delta db 0x64 ; updated y pos db 0x60 ; min y db 0x04 ; max y delta db 0x40 ; min x db 0x24 ; max x delta db 0x60 ; updated y pos db 0x78 ; min y db 0x04 ; max y delta db 0x0C ; min x db 0x38 ; max x delta db 0x78 ; updated y pos HelecopterBodyVlist: db 0x00, 0x00, 0x1C db 0xFF, 0x0C, 0xF4 db 0xFF, 0x00, 0xE0 db 0xFF, 0xF8, 0xF4 db 0xFF, 0xFC, 0xCC db 0xFF, 0xFC, 0x34 db 0xFF, 0xF8, 0x0C db 0xFF, 0x00, 0x20 db 0xFF, 0x0C, 0x0C db 0x00, 0x00, 0xE4 db 0x01 DestroyedHelecopterVlists: db 0x00, 0x0C, 0x10 db 0xFF, 0xF4, 0x0C db 0xFF, 0xF4, 0xF4 db 0xFF, 0x00, 0xD0 db 0x20 db 0x00, 0xE8, 0xE4 db 0xFF, 0x08, 0x0C db 0xFF, 0x04, 0xCC db 0xFF, 0x04, 0x34 db 0xFF, 0x08, 0x0C db 0xFF, 0x00, 0x30 db 0x01 ; Pairs of (y,x) points HelecopterRotorVlist: db 0x30, 0x00 db 0x00, 0xF8 db 0xD0, 0x08 EndString: db 0x00 db 0xF0 db "END",0x80 db 0x03 db 0x97 db 0x68 db 0x0F db 0x67 S0FFF: db 0x39