/*
* This work was originally done by Fred Taft (fred_taft@hp.com).
* Please forward any comments, corrections or additions back to Fred.
*
* Note that the work here is incomplete. If you have the time to work
* further on this, please repost your results, so that the rest of us
* can benefit from your knowledge.
*
* Dark Tower
*
******************************************************************************
******************************************************************************
*
* The following is the memory map for Dark Tower RAM usage:
*
* C880 The console button mask.
*
* C881-C882 Joystick enable flags.
*
* C883 Work memory, when player is in forest.
*
* C884 Work memory, when player is in forest.
*
* C883-C884 Has many uses:
*
* 1) During brigand drawing, C883 holds a copy of the
* drawing intensity, while C884 holds a copy of the
* scale factor.
*
* C884-C885 Has many uses:
*
* 1) Used during fog and plague drawing, to indicate
* where to draw the fog/plague lines.
*
* C883-C886 Used as work memory, during the generation of the solution
* to the puzzle; keeps track of which keys have already been
* used, so that the key will not be used again. See Note 1.
*
* C885-C886 Has many uses:
*
* 1) During brigand drawing, holds a pointer to the
* 16-bit y and 16-bit x location where the brigand
* is to be drawn.
*
* 2) Appears to hold some (y,x) info during normal use.
* Possibly the player's position.
*
* C889 Has many uses:
*
* 1) Used during generation of forest data.
*
* 2) Used during drawing of dot lists; contains a value
* used during the calculation of the scale factor
* and intensity values.
*
* C88A Has man uses:
*
* 1) Used during generation of forest data.
*
* 2) Used to index into the array of dot lists [CB71];
* controls which set of dots is drawn. Also used
* when calculating the scale factor and intensity
* value used to draw the dots.
*
* C88B Used as a loop counter by InvokeRandomFunctionFromTable().
*
* C88F
*
* C890 Has many uses:
*
* 1) During brigand scenes, used to temporarily hold
* the brigand animation index.
*
* 2) During inventory request, holds index into player's
* array of possessions.
*
* 3) At various times, used as a loop counter.
*
* C89C Startup delay counter. Controls the length of time the
* "REPLACEMENT WARRIOR" or "YOUR FIRST WARRIOR" message
* stays up, each time you start up. This is used to control the
* invocation of the function whose pointer has been placed into
* C89D.
*
* C89D-C89E Function pointer; invoked only when delay timer C89C
* decrements from 1 to 0.
*
* C89F Delay counter; filled with random number, and decremented
* until it reaches 0. This is used to control the invocation
* of the function whose pointer has been placed into C8A0.
*
* C8A0-C8A1 Function pointer; invoked only when delay timer C89F
* decrements from 1 to 0.
*
* C8A2 Delay counter; filled with random number, and decremented
* until it reaches 0. This is used to control the invocation
* of the function whose pointer has been placed into C8A3.
*
* C8A3-C8A4 Function pointer; invoked only when delay timer C8A2
* decrements from 1 to 0.
*
* C8A8 Filled with random number in range 0-7; certain processing
* is disabled if this value is not 0.
*
* C8A9 Filled with random number in range 0-3; certain processing
* is disabled if this value is not 0.
*
* C8AA Filled with random number in range 0-1; certain processing
* is disabled if this value is not 0.
*
* C8AB-C8AC Stores intensity and scale values used by Draw2VectorLists().
*
* C8AD-C8AE Stores pointer to an alternate vector list, used by
* Draw2VectorLists() and Draw2VectorLists_16bit().
*
* C8AF-C8B0 Stores pointer to an alternate vector list, used by
* Draw2VectorLists() and Draw2VectorLists_16bit().
*
* C8B1 Boolean: indicates if this is the first warrior being
* used (0x00) or a replacement warrior (0xFF).
*
* C8B2 Players direction of travel; manipulated bases on how the
* joystick is moved. Values are:
*
* 0-7 = North
* 8-15 = NorthWest
* 16-23 = West
* 24-31 = SouthWest
* 32-39 = South
* 40-47 = SouthEast
* 48-55 = East
* 56-63 = NorthEast
*
* C8B3 Related to C8B2; set, but never referenced.
*
* C8B4-C8B5 Player's 16-bit y position (in forest coordinates).
*
* C8B6-C8B7 Player's 16-bit x position (in forest coordinates).
*
* C8B8 8-bit y position (in forest coordinates) last used
* to generate the forest information.
*
* C8B9 8-bit x position (in forest coordinates) last used
* to generate the forest information.
*
* C8BA-C8BB 16-bit rise (y delta) added or subtracted from player's
* current position (in forest coordinates), when player is
* moved; is calculated based on the direction the player is
8 moving.
*
* C8BC-C8BD 16-bit run (x delta) added or subtracted from player's
* current position (in forest coordinates), when player is
* moved; is calculated based on the direction the player is
* moving.
*
* C8BE Boolean: 0 when player is just starting to walk; 1 if
* player is already walking.
*
* C8BF Boolean: 0 if player is in the forest, non-zero if the
* player is in a treasure chest.
*
* C8C0
*
* C8C1
*
* C8C4-C8C5 Sin based on player's direction of travel.
*
* C8C6-C8C7 Cosine based on player's direction of travel.
*
* C8C8 X scalar value tranformed by TransformPoint();
*
* C8C9
*
* C8CA Y scalar value transformed by TransformPoint().
*
* C8CB
*
* C8D2 When the player is in the forest, indicates the number of
* visible objects.
*
* C8D3 Boolean: set to 1 when player runs out of warriors, and
* game is over.
*
* C8D4 Game restart counter; automatically restarts new game when
* it decrements to 0.
*
* C8D6-C8DF Array used to track which objects the player has in his
* possession. This is used when the magician attempts to
* award the player something new, and also when the player's
* inventory is displayed. An entry will be non-zero if the
* player has it in his possession. See Note 4.
*
* C8E0 Intensity adjustment value for special object currently
* in view.
*
* C8E1-C8E2 Stores a pointer to one of the entries in the 'forest
* data' array (C9A6-CA47). This is the entry representing
* the special object currently in view.
*
* C8E3-C8E4 Stores a pointer to one of the entries in the 'visible
* object' array (CA48-CB07). This is the entry representing
* the special object currently in view.
*
* C8E5-C8E6 Pointer to the byte in the array stored at 0xC8F8, which
* is associated with the special object currently in sight.
*
* C8E7 Holds a bitmask (with only a single bit set), which
* represents the special object in view. When the object
* is consumed, this mask is OR'ed with the byte pointed to
* by 0xC8E5-0xC8E6.
*
* C8E8 Holds a flag which indicates whether the special object
* in view has already been consumed, and thus, should not
* again be drawn (i.e. bags of gold). 0 => not consumed,
* while non-zero => already consumed.
*
* C8E9 When the player is entering a treasure chest, used to hold
* a random number in the range 6-9.
*
* C8EA When the player encounters a special object in the forest,
* this is used as a decrement counter, to allow the enlarging
* string to continue to display for a while, after it has
* finished enlarging.
*
* C8EB Indicates if the player is alive (0xFF) or has just died (0x00).
*
* C8EC-C8ED Player's 16-bit y position (in screen coordinates: 0x80-0x7F).
*
* C8EE-C8EF Player's 16-bit x position (in screen coordinates: 0x80-0x7F).
*
* C8F0 Scale adjustment factor.
*
* C8F1 Line drawing pattern used when drawing the player; usually
* set to 0xFF (solid lines), but is assigned a random value
* when the player is hit by a plague.
*
* C8F3-C8F4 Pointer to the label representing the object just awarded
* to the player. Used by the function which draws an
* enlarging string.
*
* C8F5-C8F6 (y,x) position to display the label of the awarded object.
*
* C8F7 During string enlargement, this indexes into the array
* of height/width values, used to successively draw the
* string larger.
*
* C8F8-???? Has multiple uses:
*
* 1) Byte array, containing information about which
* consumable objects have already been picked up
* by the player. When a bit is turned on, it
* indicates that the object has already been
* consumed.
*
* 2) Used as a work buffer, after player solves the
* riddle of the keys.
*
* C978-C99C Array of 18 entries, each 2 bytes long. Used to store
* important forest information (bytes 8 and 9 of the forest
* array at C9A6-CA47), when the player temporarily leaves the
* forest to enter a treasure chest, or attempts to solve the
* riddle of the keys. When the player returns to the forest,
* this information is copied back into the forest array.
* These two bytes represent the dynamic (versus the static)
* forest data; that is why they must be saved off.
*
* C99C-C99F 4 byte array, holding the official solution to the puzzle.
* See Note 2 for an explanation of the values.
*
* C9A0 Has many uses:
*
* 1) Boolean: when player is in the forest, signals
* whether a fog is starting up (0x01),
* finishing (0x80) or not in effect (0x00).
*
* 2) Boolean: when player is fighting brigands in a
* chest, indicates whether any brigands were
* processed during this pass (0xFF).
*
* 3) When player is in a chest and meets a magician,
* holds the animation index used to index into an
* array of vector lists, while drawing the magician.
*
* C9A1 Has many uses:
*
* 1) Controls duration of fog effect.
*
* 2) Used during brigand sequence, to indicate whether
* the current brigand has been hit (0xFF).
*
* C9A2 Has many uses:
*
* 1) Boolean: when player is in the forest, signals
* whether a plague is starting up (0x01),
* finishing (0x80) or not in effect (0x00).
*
* 2) Used to store the angle of fire, when player
* throws a flamoid, while in a chest.
*
* C9A3 Has many uses:
*
* 1) Controls duration of plague effect.
*
* 2) Used during brigand sequence.
*
* C9A0-C9A3 Used to hold the player's guess at the solution to the
* puzzle. See Note 3.
*
* C9A4 During player's attempt to solve the puzzle, this contains
* the index into the player's solution array (C9A0-C9A3); it
* indicates the current key position the player is working on.
*
* C9A4-C9B6 When the player is fighting a brigand, this buffer is used
* to hold the transformed flamoid vector list.
*
* C9A4-C9A5 When the player is in the forest, this is used as a
* decrement counter; when it decrements to zero, a plague
* occurs.
*
* C9A6-CA47 Array of 18 entries, each 9 bytes long. When the player is
* in the forest, this array contains the data describing the
* visible trees in the forest. See Note 10.
*
* C9A4-C9B6 When player is in a chest, fighting a brigand, this is used
* to hold the transformed flamoid vector list.
*
* C9E0-C9F7 Array of 6 entries, each 4 bytes long. There are 6 possible
* brigands which can appear; each entry in this array represents
* one of the possible brigands. This structure is initialized
* by copying the original structure, which is encoded in the
* game ROM at 2DAD. See Note 7 for details of this structure.
*
* C9F8-CA4F Array of 8 entries, each 11 bytes long. These are the
* flamoid entries; holds information about flamoids thrown
* both by the player and the brigands. Only in use when the
* player is in a chest fightin a brigand. See Note 6 for
* details about this structure.
*
* CA48-CB07 Array of 32 entries, each 6 bytes long. When the player is
* in the forest, each entry in this array contains information
* about what is visible to the player (trees, gold, keys,
* dark tower, treasure chest, etc). See Note 9.
*
* CA50-CB21 Array of 14 entries, each 15 bytes long. These are the
* explosion buffers. When the player is fighting a brigand,
* if the player hits the brigand, or the brigand hits the
* player, that person will explode into pieces, which fly
* off spinning into different directions. Each individual
* piece is placed into its own explosion buffer entry.
* See Note 5 for details of this structure.
*
* CB2C-CB40 Buffer for holding the player's score string; it has the
* following format: "YOUR SCORE IS 0",0x80.
*
* CB41-CB49 Buffer for holding the player's direction of travel, and
* the number of steps taken since the last change of
* direction. It has the following format:
* " NE 0",0x80 (for forward movement) or
* " NE - 1",0x80 (for backward movement).
*
* CB4A Boolean: Indicates if the current step counter (i.e. the
* number of steps the player has taken in the current
* direction) is 0 (1) or non-zero (0).
*
* CB4B-CB5C Buffer for holding the string indicating the number of
* bags of gold the player has. It has the following format:
* " 2 BAGS OF GOLD",0x80.
*
* CB5D-CB6B Buffer used for displaying string indicating the number
* of warriors awarded to the player, or the number of bags
* of gold awarded to the player. It has the following format:
* "1 NEW WARRIOR",0x80 or "2 BAGS OF GOLD",0x80.
*
* CB6C
*
* CB6D
*
* CB6E
*
* CB6F
*
* CB70
*
* CB71-CB80 Array of 16-bit pointers; each pointer points to a list
* of dot verticies. This array is initialized by a call
* into the MineStorm code in the ExecOS ROM.
*
* CB81-CB88 This is an array of 8 scale factors. The scale factors
* are used when the corresponding set of motion dots (see
* above entry) are drawn.
*
* CB89 Boolean: indicates whether dot drawing sequence is active.
* DrawDotList() clears this when it has finished drawing
* the animated dot sequence:
*
* 0x00 => Dot sequence complete/inactive
* > 0 => Scale adjustment factor will be increased
* over time.
* < 0 => Scale adjustment factor will be decreased
* over time.
*
* CB8A Scale adjustment value, used during dot drawing.
*
* CB8C-CB9F Buffer for holding the string indicating the number of
* reserve troops the player has. It has the following
* format: " 6 RESERVE TROOPS",0x80.
*
******************************************************************************
*
* NOTES:
* ------
*
* Note 1: Keys Already Used Array
*
* -------------------
* C883 | Gold key used |
* -------------------
* C884 | Silver key used |
* -------------------
* C885 | Bronze key used |
* -------------------
* C886 | Brass key used |
* -------------------
*
* Note 2: Official Solution To The Puzzle
*
* ---------
* C99C | Key 1 |
* ---------
* C99D | Key 2 |
* ---------
* C99E | Key 3 |
* ---------
* C99F | Key 4 |
* ---------
*
* The value for each key is one of the following:
*
* 1 = Gold key
*
* 2 = Silver key
*
* 3 = Bronze key
*
* 4 = Brass key
*
* Note 3: Player's Guess At Solution
*
* ----------------
* C9A0 | Key 1 guess |
* ----------------
* C9A1 | Key 2 guess |
* ----------------
* C9A2 | Key 3 guess |
* ----------------
* C9A3 | Key 4 guess |
* ----------------
*
* The value for each guess is one of the following:
*
* 0 = No guess (initial state)
*
* 1 = Gold key
*
* 2 = Silver key
*
* 3 = Bronze key
*
* 4 = Brass key
*
* Note 4: Items In Player's Possession
*
* --------------------------
* C8D6 | Gold Key |
* --------------------------
* C8D7 | Silver Key |
* --------------------------
* C8D8 | Bronze Key |
* --------------------------
* C8D9 | Brass Key |
* --------------------------
* C8DA | Crystal Crown |
* --------------------------
* C8DB | Scout |
* --------------------------
* C8DC | Healer |
* --------------------------
* C8DD | # of bags of Gold |
* -- --
* C8DE | |
* --------------------------
* C8DF | # Replacement warriors |
* --------------------------
*
* Note 5: Explosion Buffer
*
* --------------------------
* 0 | In use Flag 0/1 |
* --------------------------
* 1 | Rise (y) Delta |
* -- --
* 2 | |
* --------------------------
* 3 | Run (x) Delta |
* -- --
* 4 | |
* --------------------------
* 5 | 16-bit Y position |
* -- --
* 6 | |
* --------------------------
* 7 | 16-bit X position |
* -- --
* 8 | |
* --------------------------
* 9 | Scale Factor |
* --------------------------
* A | Angle of travel |
* --------------------------
* B | Angle delta (spin rate)|
* --------------------------
* C | Vector list pointer |
* -- --
* D | |
* --------------------------
* E | Lifespan |
* --------------------------
*
* The lifespan field controls how long the object gets drawn.
* When it decrements to 0, the entry gets marked as no longer
* in use.
*
* Note 6: Flamoid Buffer
*
* --------------------------
* 0 | In use Flag 0/1 |
* --------------------------
* 1 | Rise (y) Delta |
* -- --
* 2 | |
* --------------------------
* 3 | Run (x) Delta |
* -- --
* 4 | |
* --------------------------
* 5 | 16-bit Y position |
* -- --
* 6 | |
* --------------------------
* 7 | 16-bit X position |
* -- --
* 8 | |
* --------------------------
* 9 | ?????? |
* --------------------------
* A | Lifespan |
* --------------------------
*
* The lifespan field controls how long the object gets drawn.
* When it decrements to 0, the entry gets marked as no longer
* in use.
*
* Note 7: Soft Brigand Data
*
* --------------------------
* 0 | Current state |
* --------------------------
* 1 | Animation index |
* --------------------------
* 2 | Pointer to Hard Brigand|
* -- --
* 3 | Data (See Note 8) |
* --------------------------
*
* This structure contains the 'soft' data associated with a
* brigand. It is soft because it can change over the course
* of the game.
* The current state can assume one of the following values:
*
* 0x80 = In use
* 0x40 = Flamoid has been thrown
* 0x01 = Inactive
*
* The Animation index starts at 0, and increments upto 0x15.
* It is used to index into the array of brigand images, and
* controls which image is drawn, when a flamoid is thrown, and
* when the brigand is vulnerable to being hit by the player's
* flamoids.
*
* Note 8: Hard Brigand Data
*
* --------------------------
* 0 | Brigand's 16-bit Y |
* -- --
* 1 | Position |
* --------------------------
* 2 | Brigand's 16-bit X |
* -- --
* 3 | Position |
* --------------------------
* 4 | Flamoid's 16-bit Y |
* -- --
* 5 | Position |
* --------------------------
* 6 | Flamoid's 16-bit X |
* -- --
* 7 | Position |
* --------------------------
* 8 | ???? |
* --------------------------
* 9 | ???? |
* --------------------------
* 0A | ???? |
* --------------------------
* 0B | ???? |
* --------------------------
* 0C | ???? |
* --------------------------
* 0D | Image Flip Flag |
* --------------------------
* 0E | Scale Factor |
* --------------------------
* 0F | Target Size (height/2) |
* -- --
* 10 | Target Size (width/2) |
* --------------------------
*
* This structure contains the brigand data which is fixed, and
* the only copy is stored in the game ROM. There is one entry
* for each of the 6 possible brigands. The 'Image Flip Flag'
* indicates whether the associated brigand vector list should
* be flipped around the y axis; this allows a single vector
* list to be used for a brigand coming from either the left
* or right side of a wall.
*
* Note 9: Visible Objects In The Forest
*
* ------------------------------
* 0 | Visible Object Id |
* ------------------------------
* 1 | 8-bit y position |
* ------------------------------
* 2 | 8-bit x position |
* ------------------------------
* 3 | Intensity adj value |
* ------------------------------
* 4 | Pointer to entry in |
* -- --
* 5 | the forest array (Note 10) |
* ------------------------------
*
* This structure contains the information describing a visible
* object in the forest (tree, treasure chest, gold, key, etc).
*
* The Visible Object Id not only identifies the object, but
* also, in some cases, the lower 4 bits are used as an index
* into the a jump table, whose entries represent the function
* used to award the given object. The Visible Object Id can
* assume the following values:
*
* 0x00 => nothing
* 0x01 => a tree
* 0x8x =>
* 0x9x =>
* 0xF4 => Dark Tower
* 0xF2 => Gold
* 0xF0 => Key
* ?????
*
*
* Note 10: Forest Information
*
* ----------------------------------
* 0 | Id or vector list pointer |
* -- --
* 1 | |
* ----------------------------------
* 2 | 16-bit Y Information |
* -- --
* 3 | |
* ----------------------------------
* 4 | 16-bit X Information |
* -- --
* 5 | |
* ----------------------------------
* 6 | Image flip flag |
* ----------------------------------
* 7 | Object state |
* ----------------------------------
* 8 | Treasure chest animation index |
* ----------------------------------
*
* The 'Object state' field starts at 0, and basically acts
* like the 'controller' for a mini state machine. When the
* player encounters an object in the forest, this is used
* to control the object as it transitions through a series
* of animations as the user is taking procession of the object.
*
* If byte 0 is 0x00, then byte 1 contains the Id of a special
* object; otherwise, bytes 0 & 1 are a pointer to a tree
* vector list.
*
******************************************************************************
*/
include "osmapV3.h"
include "fnmapV3.h"
org 0x0000
S0000: db "g GCE 1983",0x80
dw DT_IntroMusic
db 0xF8
db 0x50
db 0x40
db 0xE0
db "DARK",0x80
db 0xF8
db 0x50
db 0x20
db 0xD8
db "TOWER",0x80,0x00
StartNewGame:
jsr DPRAM
direct $C8
inc $C824
ldd #0x0004 ; Support 1 player & 4 games
jsr SELOPT
jsr DPRAM
direct $C8
lda #0xEE ; Save console button mask
sta $C880
ldx #0x0103
stx $C881 ; Save joystick enable flags
ldx #0xC883 ; Clear all game controlled
P003B: clr ,x+ ; RAM; C883 - CBE9.
cmpx #0xCBEA
bne P003B
jsr MS_INIT_MOTION_DOTS
ldd #0x1000 ; Set restart counter, for when
std $C8D4 ; after the game ends.
dec $C87A ; Force game # in range 0 - 3
ble P005F ; Jump if game 1 selected
jsr AwardSilverKey
dec $C87A
ble P005F ; Jump if game 2 selected
jsr AwardBronzeKey
dec $C87A
ble P005F ; Jump if game 3 selected
jsr AwardBrassKey
P005F: ldx #YourScoreIsLabel ; Make copy of string
ldu #0xCB2C
jsr CopyStringToBuffer
ldd #0x0500
std $C9A4 ; Set plague delay counter
ldd #CheckForDeadPlayer
std $C89D ; Set indirect jump pointer
lda #0x1F
sta $C89C ; Set startup delay counter
ldd #ActivateABrigand
std $C8A0 ; Set indirect jump pointer
lda #0x06
sta $C8DF ; Start player with 6 warriors
ldx #ReserveTroopsLabel
ldu #0xCB8C
jsr CopyStringToBuffer
ldd #0x0002 ; Start player with 2 bags of
std $C8DD ; gold.
ldx #BagsOfGoldLabel_2
ldu #0xCB4B
jsr CopyStringToBuffer
; Calculate where to place the player
P0097: jsr PlacePlayerRandomlyInForest
lda $C8B6 ; If the random position doesn't
asla ; fall into an acceptable
anda #0x40 ; range, then discard these
ora $C8B4 ; values, and try again.
anda #0x60 ; This may be preventing the
beq P0097 ; player from starting in a
; non-forested area.
; Calculate solution to 'Riddle Of The Keys'
ldx #0xC882 ; This array is used to keep
ldd #0x0000 ; track of which keys have
std $C883 ; already been used; can't use
; FDT: BUG should be 0x85!!
std $C884 ; keys more than once.
jsr RANDOM
anda #0x03 ; Generate random number (1-4)
inca ; representing index of first
sta $C99C ; key.
sta $C88F
inc a,x ; Tag key as now in use
P00BC: jsr RANDOM
anda #0x03 ; Generate random number (1-4)
inca ; representing index of second
sta $C99D ; key.
ldb a,x
bne P00BC ; Redo, if already in use.
inc a,x ; Tag key as now in use
adda $C88F
sta $C88F
P00CF: jsr RANDOM
anda #0x03 ; Generate random number (1-4)
inca ; representing index of third
sta $C99E ; key.
ldb a,x
bne P00CF ; Redo, if already in use
inc a,x ; Tag key as now in use
adda $C88F
sta $C88F ; Since the sum of all of the
lda #0x0A ; key indices is '10', the last
suba $C88F ; key index is easy to calculate.
sta $C99F ; Set index of last key
; This is the game's main loop
MainLoop:
jsr CheckForInventoryRequest
pshs dp
lda #0xC8
tfr a,dp
direct $C8
lda $C89C ; When the startup delay counter
bne P00F9 ; hits 0, set C8B1, so next time
coma ; we use 'Replacement Warrior',
sta $C8B1 ; instead of 'Initial Warrior'.
P00F9: jsr ProcessMovementAndDrawPlayer
clr $C8BF ; Flag that player's in forest
jsr ProcessForestObjects
ldx $C9A4 ; If not already 0, then
beq P010B ; decrement the plague delay
leax -1,x ; counter
stx $C9A4
P010B: puls dp
direct $D0
lda $C89C ; Keep showing 'Warrior' string
beq P012F ; until startup delay elapses.
lda $C8B1 ; Is this the 'Initial' or a
bne P011C ; 'Replacement' warrior?
ldu #YourFirstWarriorLabel
bra P0129
P011C: lda $C9A3
bne P012F ; Skip, if plague is in effect
lda $C8DF ; If no replacement warriors left,
beq P012F ; then the game is over.
ldu #ReplacementWarriorLabel
P0129: jsr INTMAX
jsr PrintMultiPartString
P012F: jsr CheckIfFogActive
jsr CheckIfPlagueIsActive
jsr CheckForGameOver
bra MainLoop
; ProcessForestObjects()
;
; If there is currently a special object in view, then it
; it query information about whether or not the object has
; already been consumed. It will then check to see if
; the player is close to a treasure chest, and whether or
; not the player is asking to enter the treasure chest.
ProcessForestObjects:
pshs dp
direct $C8
ldy $C8E1 ; Is a special item in view?
beq DrawForestScene ; Nope
jsr CheckIfObjectConsumed ; Yep; see if consumed
sta $C8E8 ; Save 'been consumed flag
ldd $C883 ; Get ptr to 'consumed' byte
std $C8E5 ; Save ptr to 'consumed' byte
lda $C885 ; Get obj's 'consumed' bitmask
sta $C8E7 ; Save the 'consumed' bitmask
lda $C815 ; Get btn4 state; does player
beq DrawForestScene ; want 2 grab special item?
lda [ $C8E3 ] ; Yep; get object's Id
anda #0xE0 ; Skip, if this is not a
P0158: cmpa #0x80 ; treasure chest object.
bne DrawForestScene
lda $C8EB ; Is player dead?
beq DrawForestScene ; Skip, if player is dead
lda $C9A0 ; If the player is in the
ora $C9A2 ; middle of fog or plague,
ora $C856 ; or if some sound is active,
bne DrawForestScene ; then jump elsewhere.
lda 7,y ; Determine whether what
bita #0x02 ; state this object is
bne P0183 ; currently in.
bita #0xFE
bne DrawForestScene
lda #0x03 ; Init treasure chest state
sta 7,y ; Set initial state for object
lda #0x01
sta 8,y ; Init animation index
lda #0x30
sta $CB6D
bra P0187
P0183: lda #0x05 ; Force treasure chest to
sta 7,y ; next state.
P0187: clr $C815 ; Clear console 1, btn4 state
; DrawForestScene()
;
; Displays the direction/step information, along with
; drawing each currently visible object.
DrawForestScene:
lda #0xD0
tfr a,dp
direct $D0
jsr INTMAX
ldd #0xFB38
std $C82A ; Set string height & width
ldd #0x7F10 ; Set (y,x) position
jsr POSITD
ldu #0xCB41 ; Display direction of travel
jsr RASTER
ldu #0xCA48 ; Get ptr to tree position data
lda #0x20
sta $C8CF ; Set loop counter
lda #0xFF
sta $C829 ; Set line drawing pattern
P01AF: ldy 4,u
lda 0,u
beq P01DE ; Skip, if entry is inactive
bmi ObjectIsSpecial
lda 6,y
sta $CBA0 ; Control flipping of image
lda #0x7F ; Calculate the intensity to
suba 3,u ; be used; if it comes out
sta $C883 ; < 0x20, then don't draw.
adda #0x30 ; int=0x7F-(3,u)+0x30-$C9A1
bvc P01CA ; Check for calculation overflow
lda #0x7F ; Max intensity is 0x7F
P01CA: suba $C9A1
cmpa #0x20 ; Draw tree only if close
ble P01DE ; enough to be visible.
ldb $C883 ; Calculate scale factor:
lsrb ; ((0x7F-(3,u))/2)+8
addb #0x08
ldx 0,y ; Get ptr to vector list
leay 1,u ; Get ptr to 8-bit position
jsr DT_MoveThenDraw
P01DE: leau 6,u ; Get ptr to next tree pos entry
dec $C8CF ; Decrement loop counter
bne P01AF ; Process next entry
puls dp,pc ; All done
; Object is a treasure chest, gold, key, Dark Tower, etc
ObjectIsSpecial:
lda 0,u ; Determine which object this is
cmpa #0xF2 ; Is it a bag of gold?
lbeq ProcessBagsOfGoldInForest
cmpa #0xF0 ; Is it a key?
lbeq ProcessKeysInForest
cmpa #0xF4 ; Is it the Dark Tower?
lbeq ProcessDarkTowerInForest
anda #0xF0
cmpa #0xE0
beq P01DE
lda $C8EC ; Get player's y position
ldb $C8EE ; Get player's x position
jsr DrawDotsIfActive
sta $C8F0
lda 7,y
anda #0x3E
ora $C8BF
sta $C8BF
lda 7,y ; Check the state of the object
bita #0x30 ; Are we in the handler?
bne InvokeChestAction ; Yep
bita #0x08 ; Are we delaying?
bne CheckDelay ; Yep
bita #0xFE ; Are we drawing static chest?
beq DrawTreasureChest ; Yep
ldb $C8A8 ; 'Slow down' flag disabled?
bne DrawTreasureChest ; Nope, so don't update.
bita #0x04 ; Is the chest closing?
bne ChestClosing ; Yep
lda 8,y ; Use the treasure chest
inca ; animation index to get the
asla ; correct treasure chest base.
ldx #TreasureChestBase_Table
ldx a,x ; If the vector list is 0x0000,
beq InitDelayCounter ; then animation is complete
lsra ; Update the treasure chest
sta 8,y ; animation index.
bra DrawTreasureChest
ChestClosing:
dec 8,y ; Decrement animation index
bne DrawTreasureChest
lda #0x01 ; Set state to show that the
sta 7,y ; chest has finished closing.
bra DrawTreasureChest
InitDelayCounter:
lda #0x09 ; Set object state to show we're
sta 7,y ; waiting on the delay counter.
lda #0x08 ; Set delay counter; controls
sta $C8EA ; when chest action is invoked.
CheckDelay:
dec $C8EA ; Wait for delay counter to
bne DrawTreasureChest ; decrement to 0.
InvokeChestAction:
ldx #ObjectTbl ; Invoke the action corresponding
lda 0,u ; to the object encountered.
anda #0x0E
jsr [ a,x ] ; (INDIRECT JUMP)
DrawTreasureChest:
lda 6,y
sta $CBA0 ; Control flipping of image
lda #0x7F ; Calculate intensity
suba 3,u ; Adjust value, based on some
tfr a,b ; object information.
adda #0x20 ; Further adjust value
bvc P0270 ; Check for overflow
lda #0x7F ; Use max intensity value
P0270: suba $C9A1 ; More adjustments
cmpa #0x20 ; If the object is too far away
lble P01DE ; to be seen, then skip it.
sta $C8AB ; Save intensity value
lsrb ; Calculate scale factor
subb #0x0C ; Adjust the value
lble P01DE ; Skip object if scale <= 0
stb $C8AC ; Save scale factor
ldx #TreasureChestBase_Table
lda 8,y ; Use the treasure chest
asla ; animation index to draw the
ldx a,x ; correct treasure chest base.
stx $C8AD ; Set alternate vector list 1
ldx #TreasureChestLid_Table
ldx a,x ; Get correct treasure chest lid
stx $C8AF ; Set alternate vector list 2
ldd #0x0000 ; Force drawing of alt vector list
leay 1,u ; Set addr of drawing position
jsr Draw2VectorLists
jmp P01DE
; When a special object is encountered in the forest, this
; table indicates the function to process the object. The
; first byte of the 'visible objects in forest' structure
; is used to index into this array.
ObjectTbl:
dw NoObject
dw GoldOrNewWarriorObject
dw BrigandChestObject
dw MagicianObject
dw FogObject
dw PlagueObject
dw NoObject
dw NoObject
; GoldOrNewWarriorObject()
;
; Entry: y = ptr to Forest Info structure
;
; This is a mini state machine, where the state is controlled
; by the 8th byte in the structure pointed to by 'y'.
; The state transition is as follows:
;
; 0x0x => Just starting determine award, start drawing
; the enlarged string, and set state = 0x11.
;
; 0x1x => Keep drawing enlarging string representing
; the prize. When the scale index (C8F7)
; used by the enlarging string function reaches
; 0x60, set state = 0x21.
;
; 0x2x => Finish drawing the enlarging string, and
; once it is completely enlarged, leave it
; displaying, until C8EA decrements to 0, at
; which point set state = 0x05.
;
; 0x05 => All done.
GoldOrNewWarriorObject:
lda 7,y
bita #0x20
bne P02F5 ; Goto state 3 processing
bita #0x10
bne P02E2 ; Goto state 2 processing
lda $C8E8 ; Get 'been consumed' flag
bne P0308 ; Skip, if already consumed
lda #0x11 ; State 1: initialize, and
sta 7,y ; set to state 2.
pshs dp,x,y,u
lda #0xC8
tfr a,dp ; Select random prize to award
direct $C8
ldu #RandomAwardsTable1
jsr InvokeRandomFunctionFromTable
jsr SetLabelOfFoundObject
lda [ $C8E5 ] ; Get 'consumed' byte
ora $C8E7 ; Flag object as 'consumed'
sta [ $C8E5 ] ; Save updated 'consumed' byte
direct $D0
puls dp,x,y,u
P02E2: jsr DrawEnlargingString ; State 2
lda $C8F7 ; When the enlargement factor
cmpa #0x60 ; reaches 0x60, change to
blt P0307 ; state 3.
lda #0x21 ; Entering state 3
sta 7,y
lda #0x1F
sta $C8EA ; Set delay counter
P02F5: jsr DrawEnlargingString ; State 3
dec $C8EA ; Has delay counter expired?
bne P0307 ; Nope
lda #0x05 ; Yep; All done
sta 7,y ; Enter state 4
ldd #0x0000
std $C8F3 ; Clear out string pointer
P0307: rts
P0308: lda #0x84
P030A: sta 0,u
; BrigandChestObject()
;
; Entry: y = ptr to Forest Info structure
;
; This is a mini state machine, where the state is controlled
; by the 8th byte in the structure pointed to by 'y'.
; The state transition is as follows:
;
; 0x0x => Just starting initiate the dot sequence used
; transition the player into the treasure chest,
; and set state = 0x11.
;
; 0x1x => Wait for the dot sequence to complete. Also,
; generate a random number in the range 6-9,
; and store it in C8E9. When the dot sequence
; completes, have the player enter the chest,
; and wait for that to finish. If the player
; is still alive, then initiate another dot
; sequence, to transition him back to the
; forest. At that point, set state = 0x21.
;
; 0x2x => When the delay counter (C8EA) decrements
; to 0, then we're done, so set state = 0x05.
;
; 0x05 => All done.
BrigandChestObject:
lda 7,y
bita #0x20
lbne P03C6 ; Goto state 3 processing
bita #0x10
bne P0324 ; Goto state 2 processing
lda #0x01 ; State 1
sta $CB89 ; Flag start of dot sequence
clr $CB8A ; Clear scale adj factor
lda #0x11
sta 7,y ; Change to state 2
P0324: lda $CB89 ; State 2: wait for dot
bne P0357 ; sequence to complete.
lda $C8E9 ; If we have not already
bne P0338 ; done so, then generate
jsr RANDOM ; a random number in the
anda #0x03 ; range 6-9.
adda #0x06
sta $C8E9 ; Save this number
P0338: pshs dp,y,u ; Process the player in
jsr PlayerEnteringChest ; the treasure chest;
puls dp,y,u ; wait for him to finish.
lda #0x21
sta 7,y ; Change to state 3
lda #0x1F ; If the player is still alive,
sta $C8EA ; then transition him back into
lda $C8EB ; the forest.
beq P0357 ; Skip, if player is dead
lda #0x80
sta $CB89 ; Flag start of dot sequence
lda #0x3F
sta $CB8A ; Set scale adj value
P0357: rts
; MagicianObject()
;
; Entry: y = ptr to Forest Info structure
;
; This is a mini state machine, where the state is controlled
; by the 8th byte in the structure pointed to by 'y'.
; The state transition is as follows:
;
; 0x0x => Just starting initiate the dot sequence used
; transition the player into the treasure chest,
; and set state = 0x11.
;
; 0x1x => Wait for the dot sequence to complete.
; When the dot sequence completes, have the
; player enter the chest, to receive an award
; from the magician. Then initiate another dot
; sequence, to transition him back to the
; forest. At that point, set state = 0x21.
;
; 0x2x => When the delay counter (C8EA) decrements
; to 0, then we're done, so set state = 0x05.
;
; 0x05 => All done.
MagicianObject:
lda $C8E8 ; Get 'been consumed' flag
bne P0308 ; Skip, if already consumed
lda 7,y
bita #0x20
bne P03C6 ; Goto state 3 processing
bita #0x10
bne P0373 ; Goto state 2 processing
lda #0x01 ; State 1
sta $CB89 ; Flag start of dot sequence
clr $CB8A ; Clear scale adj factor
lda #0x11
sta 7,y ; Change to state 2
P0373: lda $CB89 ; Jump if the dot sequence
bne P039D ; has not completed.
lda [ $C8E5 ] ; Get 'consumed' byte
ora $C8E7 ; Flag obj as 'consumed'
sta [ $C8E5 ] ; Save updated 'consumed' byte
pshs dp,y,u ; Move player into the chest,
jsr InsideMagicianChest ; and attempt to award
puls dp,y,u ; him something.
lda #0x21
sta 7,y ; Change to state 3
lda #0x1F ; Start another dot sequence,
sta $C8EA ; as we transition the player
lda #0x80 ; back to the forest.
sta $CB89 ; Flag start of dot sequence
lda #0x3F
sta $CB8A ; Set scale adj value
P039D: rts
; FogObject()
;
; Entry: y = ptr to Forest Info structure
;
; This is a mini state machine, where the state is controlled
; by the 8th byte in the structure pointed to by 'y'.
; The state transition is as follows:
;
; 0x0x => Just starting attempt to force a fog to
; occur, and then set state = 0x11.
;
; 0x1x => When the delay counter (C8EA) decrements
; to 0, then we're done, so set state = 0x05.
;
; 0x05 => All done.
FogObject:
lda 7,y
bita #0x10
bne P03C6 ; Goto state 2 processing
jsr TryToStartFog ; State 1
lda #0xFF
sta $C8EA ; Set duration counter
bra P03C2
; PlagueObject()
;
; Entry: y = ptr to Forest Info structure
;
; This is a mini state machine, where the state is controlled
; by the 8th byte in the structure pointed to by 'y'.
; The state transition is as follows:
;
; 0x0x => Just starting attempt to force a plague to
; occur, and then set state = 0x11.
;
; 0x1x => When the delay counter (C8EA) decrements
; to 0, then we're done, so set state = 0x05.
;
; 0x05 => All done.
PlagueObject:
lda 7,y
bita #0x10
bne P03C6 ; Goto state 2 processing
ldd #0x0000 ; State 1
std $C9A4 ; Force plague delay to 0
jsr TryToStartPlague
lda #0x4F
sta $C8EA ; Set duration counter
P03C2: lda #0x11
sta 7,y ; Change to state 2/3
P03C6: dec $C8EA ; State 2/3: When the duration
bne P03CF ; counter has decremented to 0,
lda #0x05 ; change to the 'done' state.
sta 7,y
P03CF: rts
; NoObject()
;
; Entry: y = ptr to Forest Info structure
;
; This is a mini state machine, where the state is controlled
; by the 8th byte in the structure pointed to by 'y'.
; The state transition is as follows:
;
; 0x0x => Simply initialize the duration counter, and
; then set state = 0x11.
;
; 0x1x => When the delay counter (C8EA) decrements
; to 0, then we're done, so set state = 0x05.
;
; 0x05 => All done.
NoObject:
lda 7,y
bita #0x10
bne P03C6 ; Goto state 2 processing
lda #0x10 ; State 1
sta $C8EA ; Set duration counter
bra P03C2
; ProcessDarkTowerInForest()
;
; If the player has all of the keys, and is not currently
; in a fog, then this function gives the player the
; chance to try to solve the riddle of the keys. If the
; player fails to solve the puzzle, then he will be
; placed randomly back into the forest, unless he has a
; scout in his possession, at which point he will simply
; be placed back outside the dark tower.
ProcessDarkTowerInForest:
pshs dp
lda #0xC8
direct $C8
tfr a,dp
jsr CheckIfAllKeysAwarded
bhs P0437 ; Branch if not all keys found
lda $C9A0 ; Don't let player solve riddle
bne P040D ; if he's currently in the fog.
lda [ $C8E3 ] ; Get special object's Id
cmpa #0xF4
bne P040D
lda $C8E0 ; Get obj's intensity adj value
cmpa #0x3C ; Don't interact, if player is
bge P040D ; too far away from Dark Tower.
; Attempt to solve riddle if player moving forward
lda $C81C ; Get joystick u/d position
ble P040D
lda $C81B ; Get joystick l/r position
bne P040D
pshs x,y,u
jsr TryToSolveRiddleOfKeys
jsr TryToStartFog ; Force player to random spot
puls x,y,u
P040D: clr $CBA0 ; Don't flip image
lda #0x7F
suba 3,u
tfr a,b
adda #0x30
bvc P041C
lda #0x7F
P041C: suba $C9A1
cmpa #0x20
ble P0437
aslb
addb #0x68
bhs P042A
ldb #0xFF
P042A: std $C8AB ; Set intensity & scale values
ldd #DarkTowerRightHalf ; Set vector list 1
ldx #DarkTowerLeftHalf ; Set vector list 2
leay 1,u ; Set addr of drawing position
jsr Draw2VectorLists
P0437: puls dp
jmp P01DE
; ProcessKeysInForest()
;
; This function does nothing, if the player already has
; all of the keys. Otherwise, it determines if the player
; has moved close enough to pick up the key movement to
; the left, right or backwards will not result in the
; player picking up the key.
ProcessKeysInForest:
pshs dp
lda #0xC8
tfr a,dp
direct $C8
jsr CheckIfAllKeysAwarded
blo P044C ; Jump if all keys found
jsr CheckIfObjectConsumed
beq P0451 ; Branch if obj not yet consumed
P044C: puls dp
jmp P01DE
P0451: lda [ $C8E3 ] ; Get special objects Id
cmpa #0xF0
bne DrawKeyInForest
lda $C8E8 ; Has key already been consumed?
bne P044C ; Yep, so skip it
lda $C8E0 ; Get obj's intensity adj value
cmpa #0x3C ; Don't pick it up, if player is
bge DrawKeyInForest ; too far away.
lda $C81C ; Get joystick u/d position
ble DrawKeyInForest ; Player moved backwards
lda $C81B ; Get joystick l/r position
bne DrawKeyInForest ; Player moved left or right
; Upward (forward) movement
;
; Attempt to reward the player with one of the keys
; make sure it's one he doesn't already have.
jsr AwardGoldKey
bne P047F
jsr AwardBronzeKey
bne P047F
jsr AwardSilverKey
bne P047F
jsr AwardBrassKey
beq P044C
P047F: lda [ $C8E5 ] ; Get 'consumed' byte
ora $C8E7 ; Flag object as 'consumed'
sta [ $C8E5 ] ; Save updated 'consumed' byte
sta $C8E8 ; Save 'been consumed' flag
pshs u
ldu #AwardSound
jsr SPLAY
puls u
bra P044C
; DrawKeyInForest()
;
; This function attempts to draw a visible key in the
; forest. It will determine if the key is visible (by
; calculating the scale and intensity values), and if
; it is not, will not draw the key.
DrawKeyInForest:
clr $CBA0 ; Don't flip image
lda #0x7F
suba 3,u ; Calculate intensity value
tfr a,b
adda #0x30
bvc P04A6
lda #0x7F
P04A6: suba $C9A1 ; Include fog factor
cmpa #0x20 ; Skip if intensity <= 0x20
ble P044C
lsrb ; Calculate scale value
lsrb
addb #0x08
cmpb #0x10
ble P044C ; Skip if scale <= 0x10
puls dp
ldx #Key ; Get vector list
leay 1,u ; Get ptr to drawing position
jsr DT_MoveThenDraw
jmp P01DE
; ProcessBagsOfGoldInForest()
;
; Checks to see if the bag of gold has already been picked
; up by the player, and if not, checks to see if the player
; is close enough to pick it up, and is moving towards the
; bag. If all criteria is met, then the bag is consumed.
ProcessBagsOfGoldInForest:
pshs dp
lda #0xC8
direct $C8
tfr a,dp
jsr CheckIfObjectConsumed
beq P04D2 ; Keep going, if not consumed yet
P04CD: puls dp ; Object already consumed; exit
jmp P01DE
P04D2: lda [ $C8E3 ] ; Get special object's Id
cmpa #0xF2
bne DrawBagOfGold
lda $C8E8 ; Has gold already been consumed?
bne P04CD ; Yep, so skip it
lda $C8E0 ; Get obj's intensity adj value
cmpa #0x3C ; Don't pick up, if player is
bge DrawBagOfGold ; too far away.
lda $C81C ; Get joystick u/d position
ble DrawBagOfGold
lda $C81B ; Get joystick l/r position
bne DrawBagOfGold
; Upward (forward) movement
pshs u
ldd $C8DD ; Award 1 bag of gold, unless
addd #0x0001 ; the player already has the
blo P04FF ; maximum number of bags.
std $C8DD ; Save new gold count
lda #0x01 ; # of bags awarded
ldx #0xCB4B ; Ptr to 'Bags of gold' buffer
jsr UpdateAwardsStringBuffer
P04FF: ldx #0xCB3A ; Add 100 to player's score
ldd #0x0100
jsr SCRADD
ldu #AwardSound
jsr SPLAY ; Make a sound
puls u
lda [ $C8E5 ] ; Get 'consumed' byte
ora $C8E7 ; Flag object as 'consumed'
sta [ $C8E5 ] ; Save updated 'consumed' byte
sta $C8E8 ; Save 'been consumed' flag
bra P04CD
; DrawBagOfGold()
;
; Entry: u => ptr to visible object
;
; This function determines if the bag of gold is really
; visible (based on its calculated scale and intensity
; values). If it is visible, then it is drawn.
;
DrawBagOfGold:
clr $CBA0 ; Don't flip image
lda #0x7F ; Calculate intensity value
suba 3,u
tfr a,b
adda #0x30
bvc P052D
lda #0x7F
P052D: suba $C9A1 ; Include fog factor
cmpa #0x20
ble P04CD ; Skip if intensity <= 0x20
lsrb ; Calculate scale value
lsrb
addb #0x08
cmpb #0x10
ble P04CD ; Skip if scale <= 0x10
puls dp
ldx #BagOfGold ; Get vector list
leay 1,u ; Get ptr to drawing position
jsr DT_MoveThenDraw
jmp P01DE
; ProcessMovementAndDrawPlayer()
;
; This function checks to see if the player is trying to
; move, and if so, whether or not the forest information
; must be regenerated. It then draws the player, either
; walking, or standing still, depending upon what the
; player is currently doing.
ProcessMovementAndDrawPlayer:
lda $C8EB
lbeq P0655 ; Skip, if player is dead
lda #0x70 ; Calculate player's intensity
suba $C9A1 ; Include fog factor
suba $C8F0 ; Include plague factor
cmpa #0x20 ; Skip if calculated intensity
lble P0655 ; is <= 0x20.
ldb #0x30
std $C8AB
lda $C8BF ; Jump, if player's in a chest
lbne PlayerStandingStill
lda $C81B ; Get joystick l/r position
ora $C81C ; Get joystick u/d position
lbeq PlayerStandingStill ; Skip if in neutral
lda $C8A8 ; 'Slow down' flag disabled?
bne CheckForMovement ; Nope; don't update l/r pos
lda $C81B ; Get joystick l/r position
beq CheckForMovement ; Skip if not left or right
bmi TurnLeft ; Is joystick 'left'?
; TurnRight()
;
; Decrement the players angle of travel.
TurnRight:
dec $C8B2 ; Nope; joystick is 'right'
bra UpdateDirection
; TurnLeft()
;
; Increment the players angle of travel.
TurnLeft:
inc $C8B2 ; Joystick is 'left'
; UpdateDirection()
;
; Update all values associated with the players direction
; of travel.
UpdateDirection:
jsr PlayerChangedDirection
; CheckForMovement()
;
; Check to see if the player is asking to move forward
; or backward. If so, then update the step count, and
; the player's position within the forest. If the player's
; forest position has changed, then update the forest
; information.
CheckForMovement:
lda $C8A9 ; Is 'slow down' flag disabled?
bne NoUpdate ; Nope, so don't update
lda $C81C ; Get joystick u/d position
beq UpdateForestInfo ; Skip if not up or down
bmi MoveDown ; Jump if joystick is 'down'
; Joystick is in 'up' position go forward
MoveUp:
ldd $C8BA ; Add 'rise' to 'y' position
addd $C8B4 ; Add in player's 16-bit 'y' pos
std $C88F ; Save in temporary storage
bita #0xC0 ; Skip if player is out of bounds
bne NoUpdate ; I.e. don't update forest info
ldd $C8BC ; Add 'run' to 'x' position
addd $C8B6 ; Add in player's 16-bit 'x' pos
std $C891 ; Save in temporary storage
bita #0xC0 ; Skip if player is out of bounds
bne NoUpdate ; I.e. don't update forest info
ldx #0xCB45 ; Increment the number of steps
lda $CB4A ; taken by player.
jsr IncrementSignedString
sta $CB4A ; Save 'step count = 0' indicator
bra CheckIfUpdateNecessary
; Joystick is in 'down' position back up
MoveDown:
ldd $C8BA ; Subtract 'rise' from 'y' pos
coma ; Negate the 'rise' value, to
comb ; move the player down.
addd #0x0001 ; Make into 2's compliment
addd $C8B4 ; Add in player's 16-bit 'y' pos
std $C88F ; Save in temporary storage
bita #0xC0 ; Skip if player is out of bounds
bne NoUpdate ; I.e. don't update forest info
ldd $C8BC ; Subtract 'run' from 'x' pos
coma ; Negate the 'run' value, to
comb ; move the player down.
addd #0x0001 ; Make into 2's compliment
addd $C8B6 ; Add in player's 16-bit 'x' pos
std $C891 ; Save in temporary storage
bita #0xC0 ; Skip if player is out of bounds
bne NoUpdate ; I.e. don't update forest info
ldx #0xCB45 ; Decrement the number of steps
lda $CB4A ; taken by player.
jsr DecrementSignedString
sta $CB4A ; Save 'step count = 0' indicator
; CheckIfUpdateNecessary()
;
; If the player's position within the forest has changed
; significantly from the position last used to generate
; the forest data, then regenerate the forest data, based
; on the player's new position.
CheckIfUpdateNecessary:
ldd $C88F ; Load updated 'y' position
std $C8B4 ; Update player's 'y' position
ldd $C891 ; Load updated 'x' position
std $C8B6 ; Update player's 'x' position
cmpa $C8B9 ; If the top byte of the player's
bne UpdateForestInfo ; x and y positions have not
ldb $C8B4 ; changed, then don't bother
cmpb $C8B8 ; updating the forest info, since
beq NoUpdate ; the view will not have changed.
; Player's position has changed, so update viewing info
UpdateForestInfo:
ldb $C8B4 ; Save off the new x and y values
stb $C8B8 ; since they are the ones now
lda $C8B6 ; being used to generate the
sta $C8B9 ; forest view information.
jsr FillInVisibleForestInfo
jsr CheckForPlagueOrFog
bra ProcessPlayerWalking
; Existing forest data still valid no need to update
NoUpdate:
jsr P06AE
; ProcessPlayerWalking()
;
; If the player is not already walking, then it generates
; a random animation index, to use to start the player
; walking.
ProcessPlayerWalking:
lda $C8BE ; Is player already walking?
bne DrawPlayerWalking ; Yes; so draw him walking
jsr RANDOM ; No, so decide what animation
anda #0x03 ; index to start with.
bne DrawPlayerWalking
ora #0x01 ; Player starting to walk; set
sta $C8F2 ; initial player animation index.
; DrawPlayerWalking()
;
; This function draws the player actively walking.
DrawPlayerWalking:
lda $C8A9 ; Is 'slow down' flag disabled?
bne P0616 ; Nope, so don't update
inc $C8F2 ; Increment player animation index
lda #0x04
sta $CB6C
P0616: lda #0x01
sta $C8BE ; Flag that player is walking
bra DrawPlayer
; PlayerStandingStill()
;
; This forces the player to a standstill.
PlayerStandingStill:
lda #0x00
sta $C8BE ; Flag player as standing still
clr $C8F2 ; Clear animation index
; DrawPlayer()
;
; Draw the player, either walking, or standing still.
; If the player is walking, then it uses the player's
; animation index to draw the appropriate set of vectors,
; to give the effect that the player is first moving the
; left leg, then the right, etc.
DrawPlayer:
lda $C8EB ; Is player dead?
beq P0655 ; Skip, if player is dead
P0626: lda $C8F2 ; Load player animation index
ldx #PlayerWalkingImageControlTable
ldb a,x
stb $CBA0 ; Control flipping of image
asla
ldx #PlayerWalking_LeftSide_Table
ldx a,x
stx $C8AF ; Set alternate vector list 2
ldx #PlayerWalking_RightSide_Table
ldx a,x
stx $C8AD ; Set alternate vector list 1
bne P0647
lda #0x01 ; When the last vector list is
sta $C8F2 ; reached, reset the player's
bra P0626 ; animation index back to 1.
P0647: ldb $C8F1 ; Retrieve player drawing pattern
stb $C829 ; Set line drawing pattern
ldd #0x0000 ; Force drawing of alt vector lists
ldy #0xC8EC ; Set addr of drawing position
jsr Draw2VectorLists_16bit
P0655: rts
; FillInVisibleForestInfo()
;
; This function is responsible for filling in both the
; array of forest data and the array of visible objects.
FillInVisibleForestInfo:
ldu #0xC9A6
ldb #0x12
stb $C88F ; Set loop counter 1
stb $C890 ; Set loop counter 2
ldd #0x0000
P0662: std 0,u ; Clear out all forest entries
leau 9,u
dec $C890
bne P0662 ; Process next array entry
ldu #0xC9A6 ; Prepare to fill forest array
clr $C8D2 ; Initially, no object are visible
ldy #DirectionalForestData
lda $C8B2 ; Get angle of travel
lsra ; Convert to compass direction
lsra
anda #0x1E ; Get forest information, based on
ldy a,y ; player's direction of travel.
lda $C8B4 ; Get player's y position
suba #0x06 ; Decrement it by 6
sta $C883 ; Save for later use
lda $C8B6 ; Get player's x position
suba #0x06 ; Decrement it by 6
sta $C884 ; Save for later use
P0688: jsr GenerateForestData
blo P06AE ; If 'carry' set, then all done
bvs P0688 ; Branch if 'overflow' bit set
stb 6,u ; Save 'image flip' control bit
ldx #ObjectVectorTable
asla ; Use return info to index into
ldd a,x ; object vector table.
std 0,u ; Save object id
clrb
lda $C885 ; Save player's y position?
std 2,u
lda $C886 ; Save player's x position?
std 4,u
clr 7,u ; Clear object state machine index
clr 8,u ; Clear chest animation index
inc $C8D2 ; Increment # of visible trees
leau 9,u ; Point to next tree array entry
dec $C88F ; Decrement loop counter
bne P0688 ; Process next entry
P06AE: ldu #0xCA48 ; Get ptr to tree position data
ldb #0x20 ; Set loop counter
P06B3: clr 0,u ; Flag entry as 'inactive'
leau 6,u ; Point to next array entry
decb ; Decrement loop counter
bne P06B3 ; Process next array entry
ldd #0x0000
std $C8E1 ; Clear 'special object' pointer
sta $C8E9
coma
sta $C8E0 ; Set initial intensity adj value
lda #0xFC
sta $C8C9
lda #0xE0
sta $C8CB
ldd $C8C4
std $C837 ; Init rotation routine cosine value
ldd $C8C6
std $C839 ; Init rotation routine sin value
ldx #0xC9A6 ; Get ptr to Visible Tree array
lda $C8D2 ; Were any trees visible? If not,
beq P074A ; then branch elsewhere.
sta $C88F ; Set loop counter
P06DD: ldd 0,x ; Jump elsewhere if this entry
beq P0744 ; does not point to a tree.
ldd $C8B6 ; Get player's 16-bit x position
subd 4,x
asra
rorb
asra
rorb
asra
rorb
stb $C8C8
ldd $C8B4 ; Get player's 16-bit y position
subd 2,x
asra
rorb
asra
rorb
asra
rorb
stb $C8CA
jsr TransformPoint
bvs P0744
ldb $C8CE ; Generate an index, in the
addb #0x80 ; range of 0-31.
lsrb
lsrb
lsrb
ldu #0xCA48 ; Generate pointer to the
lda #0x06 ; indicated 'visible object'
mul ; array entry.
leau d,u
lda 0,u
beq P0717 ; Branch if no visible object
lda $C8CC
cmpa 3,u
bhi P0744
P0717: ldd 0,x ; Is this a tree, or some other
tsta ; special object?
beq P071E ; It's a special object
ldb #0x01 ; It's a tree
P071E: stb 0,u ; Set flag in visible obj entry
stx 4,u ; Save pointer to forest entry
ldb $C8CC
stb 3,u
lda $C8CD
sta 1,u
lda $C8CE
sta 2,u
cmpa #0xE0
ble P0744
cmpa #0x30
bge P0744
cmpb #0x80
bhi P0744
cmpb $C8E0 ; Skip this object, if its farther
bhi P0744 ; away than another special object.
stb $C8E0 ; Save obj's intensity adj value
stx $C8E1 ; Save ptr to associated forest obj
stu $C8E3 ; Save ptr to visible object
P0744: leax 9,x ; Point to next array entry
dec $C88F ; Decrement loop counter
bne P06DD ; Process next entry
P074A: rts
; CheckIfFogActive()
;
; Controls the processing of the fog. If C9A0 = 0,
; then a fog is not in effect. If C9A0 = 1, then the
; fog is starting, and will get thicker over time. If
; C9A0 = 0x80, then the fog is receding, and will get
; thinner over time.
direct $D0
CheckIfFogActive:
lda $C9A0 ; Check if fog is active,
lbeq P07EC ; increasing, or decreasing.
bmi DecreaseFog
inc $C9A1 ; Increment fog duration counter
lda $C9A1
cmpa #0x60 ; Is it done getting thick?
blo DrawFog ; Nope
lda #0x80 ; Yep; time to decrease fog
sta $C9A0 ; Set flag = 'decrease fog'
lda $C8C1
bne P0775
lda $C8DB ; Does player have a scout?
beq P0775 ; Nope; do random placement
dec $C8C2 ; Decrement # of scout uses left
bpl DecreaseFog ; Has scout been used up?
clr $C8DB ; Yep, so remove from inventory
P0775: pshs dp ; and randomly reposition the
lda #0xC8 ; player elsewhere in the forest.
direct $C8
tfr a,dp
jsr PlacePlayerRandomlyInForest
direct $D0
puls dp
DecreaseFog:
dec $C9A1 ; See if fog duration has passed
ble FogDone
DrawFog:
clr $C887 ; Clear loop counter
lda $C9A1 ; Calculate the intensity to use
adda #0x20 ; Do some adjustments
bvc P0791 ; Check for overflow
lda #0x7F ; Use the maximum intensity value
P0791: jsr INTENS
jsr RANDOM
anda #0x1F ; Calculate a pseudo-random
adda #0x90 ; position on the screen; this is
ldb #0x00 ; where the fog line will be drawn.
jsr POSITD
ldd #0x0158
std $C884 ; Endpoint for 'Fog' lines
jsr RANDOM
anda #0x7F ; Calculate a random scale factor,
ora #0x60 ; in the range 0x60 - 0x7F.
sta $D004 ; Set the drawing scale factor
RedrawFogLine:
inc $C887 ; Increment loop counter
lda $C887 ; Stop drawing, when C887 > C9A1
cmpa $C9A1
bhi P07EC
ldd $C884 ; Retrieve 'Fog' starting point
negb ; Draw from (y,x) to (y,-x)
stb $C885 ; Modify last x coordinate
sta $D001 ; Set 'y' position
clr $D000
tst $FF00 ; Just a 'nop'
inc $D000
stb $D001 ; Set 'x' position
ldd #0xFF00
sta $D00A ; Set drawing pattern
stb $D005
ldd #0x0040
P07D6: bitb $D00D ; Wait for drawing to finish
beq P07D6
nop
sta $D00A ; Clear drawing pattern
jsr RANDOM
ora #0xC0
sta $D004 ; Set random drawing scale factor
bra RedrawFogLine
FogDone:
clr $C9A0 ; Flag that 'Fog' sequence is over
clr $C9A1
P07EC: jmp ZERGND
; CheckForPlagueOrFog()
;
; This function appears to see if the current forest
; location has a plague or fog associated with it, and
; if so, attempts to activate it.
direct $C8
CheckForPlagueOrFog:
ldy #0x0824
lda $C8B4 ; Get player's y position
suba #0x06 ; Decrement it by 6
sta $C883 ; Save for later use
lda $C8B6 ; Get player's x position
suba #0x06 ; Decrement it by 6
sta $C884 ; Save for later use
P07FF: jsr GenerateForestData
blo P0823 ; If 'carry' set, then all done
bvs P0814 ; Branch if 'overflow' bit set
tfr a,b ; Save copy of 'object type' info
andb #0x0E
eorb #0x0E
bne P07FF
anda #0x01
beq P0820
bra P081C
P0814: jsr TryToStartFog
lda #0x01
sta $C8C1
rts
P081C: jsr TryToStartFog
rts
P0820: jsr TryToStartPlague
P0823: rts
S0824: db 0x05
db 0x05
db 0x05
db 0x06
db 0x05
db 0x07
db 0x06
db 0x05
db 0x06
db 0x06
db 0x06
db 0x07
db 0x07
db 0x05
db 0x07
db 0x06
db 0x07
db 0x07
db 0x00
db 0x00
; CheckIfPlagueIsActive()
;
; Controls the processing of the plague. If C9A2 = 0,
; then the plague is not in effect. If C9A2 = 1, then the
; plague is starting, and will get thicker over time. If
; C9A2 = 0x80, then the plague is receding, and will get
; thinner over time.
direct $D0
CheckIfPlagueIsActive:
lda $C9A2 ; Is 'plague in progress'?
lbeq P08EA ; Skip if plague not active
bmi DrawPlagueLines ; Jump if already in progress
inc $C9A3 ; Increment duration counter
lda $C9A3
tfr a,b
lsrb
stb $C8F0
cmpa #0x60 ; Is plague done increasing?
blo P0870 ; Nope
lda #0x80 ; Yep; so start it decreasing
sta $C9A2
lda $C8DC ; Check to see if the player
beq P0863 ; has a healer; skip if not
dec $C8C3 ; Decrement Healer uses left
bpl DrawPlagueLines ; Has Healer been used up?
clr $C8DC ; Yep; clear from inventory
P0863: clr $C8EB ; Flag that player is dead
lda #0x90
sta $C89C ; Reset startup delay timer
DrawPlagueLines:
dec $C9A3 ; Decrement duration counter
ble PlagueDone
P0870: clr $C883 ; Clear loop counter
lda $C9A3 ; Calculate intensity value
adda #0x20 ; Make some adjustments
bvc P087C ; Check for overflow
lda #0x7F ; If overflow, use max value
P087C: jsr INTENS
jsr RANDOM ; Calculate a random line
sta $C8F1 ; pattern for drawing player.
anda #0x0F ; Calculate random position, in
adda #0x90 ; range (0x81,0) to (0x90,0)
ldb #0x00
jsr POSITD
ldd #0x0158
std $C884 ; Save initial drawing position
jsr RANDOM
anda #0x1C
sta $D004 ; Generate random scale factor
RedrawPlagueLine:
inc $C883 ; Increment loop counter
lda $C883
cmpa $C9A3 ; Are we done yet?
bhi P08EA ; Jump, if done
ldd $C884 ; Load drawing position
negb ; Set endpoint = (y, -x)
bmi P08AD ; Adjust, if necessary
decb
P08AD: stb $C885 ; Modify saved x coordinate
sta $D001 ; Set y drawing position
clr $D000
tst $FF00 ; Just a nop
inc $D000
stb $D001 ; Set x drawing position
lda $C829 ; Get current drawing pattern
ldb #0x40 ; Set up interrupt check flag
sta $D00A ; Set drawing pattern
clr $D005
P08C4: lda $C829 ; Get current drawing pattern
sta $D00A ; Set drawing pattern
nop ; Until the drawing timer
bitb $D00D ; elapses, keep resetting the
beq P08C4 ; line drawing pattern.
clr $D00A ; Clear line drawing pattern
jsr RANDOM
sta $C829 ; Get random drawing pattern
jsr RANDOM
anda #0x3F ; Calculate random scale factor
adda $C9A3
sta $D004 ; Set scale factor
bra RedrawPlagueLine
PlagueDone:
clr $C9A2 ; Clear 'In Progress' flag
lda #0xFF
sta $C8F1 ; Set player drawing pattern
P08EA: jmp ZERGND
; PlayerEnteringChest()
;
; This function is activated when the user enters a
; brigand chest. It is responsible for saving off the
; current state of any visible objects in the forest,
; and initializing the brigand data. It then transitions
; the player into the chest, and processes the fighting
; between the player and the brigand, until either the
; player defeats the random number of brigands, or the
; player is killed. If the player defeats the brigands,
; then he is awarded a random prize, and then placed back
; into the forest. If the player dies, then he is placed
; back into the forest.
direct $C8
PlayerEnteringChest:
jsr PreserveVisibleObjectData
jsr ClearAllGameStorageArrays
ldx #BrigandDefaults
ldu #0xC9E0 ; Get ptr to brigand array
ldb #0x18 ; Set byte/loop counter
P08FB: lda ,x+ ; Init the brigand array, using
sta ,u+ ; the default values stored in
decb ; ROM.
P0900: bne P08FB
pshs dp
jsr SetPlayersPositionInChest
jsr RANDOM
anda #0x7F
ora #0x80
sta $C89F ; Set up action delay timer
lda #0x80
sta $CB89 ; Flag start of dot sequence
lda #0x3F
sta $CB8A
lda #0x1F
sta $CB8B
lda #0x01
sta $C8BF ; Flag that player's in a chest
ldu #EnteringChestSound
jsr SPLAY
direct $D0
P0929: jsr CheckForInventoryRequest
lda $CB8B
ble P0936
dec $CB8B
bra P093F
P0936: ldd #0xCD00 ; Force a specific (y,x) location
jsr DrawDotsIfActive
sta $C8F0
P093F: jsr CheckForFiringOrMovement
jsr ProcessBrigand
lda $CB89 ; Jump if the dot sequence
bne P0929 ; has not completed.
clr $C8BF
P094D: jsr CheckForInventoryRequest
jsr CheckForFiringOrMovement
jsr ProcessBrigand
jsr UpdateFlamoids
jsr ProcessExplodingObjects
jsr CheckFlamoidsForHits
lda $C9A3
bne P094D
lda $C8EB
beq P09DB ; Skip, if player is dead
lda $C8E9
bpl P094D
lda $C9A0 ; Were any brigands processed?
bne P094D ; Keep looping, if so
lda $C9A1
beq P094D
lda #0xC8
tfr a,dp
direct $C8
clr $C89F ; Disable C8A0 invocation
lda #0x01
sta $C8BF ; Flag that player's in a chest
direct $D0
ldu #RandomAwardsTable2
jsr InvokeRandomFunctionFromTable
jsr SetLabelOfFoundObject
P098B: jsr CheckForInventoryRequest
jsr DrawEnlargingString
jsr CheckForFiringOrMovement
jsr ProcessBrigand
jsr UpdateFlamoids
jsr ProcessExplodingObjects
lda $C8F7 ; Keep looping until the award
cmpa #0x60 ; string has enlarged enough.
blt P098B
lda #0x01
sta $CB89 ; Flag start of dot sequence
clr $CB8A
lda #0x0F
sta $CB8B
P09B1: jsr CheckForInventoryRequest
lda $CB8B
ble P09BE
dec $CB8B
bra P09C7
P09BE: ldd $C8D0 ; Load some (y,x) value
jsr DrawDotsIfActive
sta $C8F0
P09C7: jsr DrawEnlargingString
jsr CheckForFiringOrMovement
jsr ProcessBrigand
jsr UpdateFlamoids
jsr ProcessExplodingObjects
lda $CB89 ; Jump if the dot sequence
bne P09B1 ; has not completed.
P09DB: lda #0xC8
tfr a,dp
direct $C8
clr $C89F ; Disable C8A0 invocation
clr $C8A2 ; Disable C8A3 invocation
jsr SetPlayersPositionInForest
lda $C8EB
bne P09F0 ; Skip, if player is alive
ldu #PlayerDeadSound
jsr SPLAY
P09F0: lda #0x7F
sta $C8F0
jsr ClearAllGameStorageArrays
jsr FillInVisibleForestInfo
jsr RestoreVisibleObjectData
puls dp,pc
; ProcessBrigand()
;
; Exit: C9A0 = 0, if no brigands to process, else
; != 0, if at least 1 brigand was processed.
;
; This function is responsible for processing all of the
; active brigands. It will update the animation for each
; brigand, and decide if the animation is complete, so the
; corresponding brigand can be deactivated. Otherwise, if
; the brigand has not already thrown a flamoid, it decides
; if it is time for it to do so. It will randomly decide
; whether to throw it directly at the player, or in a
; random direction.
direct $D0
ProcessBrigand:
ldu #0xC9E0 ; Get ptr to brigand array
lda #0x06
sta $C88F ; Set loop counter
clr $C9A0 ; Clear return value
P0A0A: ldb 0,u ; Only process visible brigands
lbpl P0AAE
lda $C9A0 ; Set return value to show that
ora #0x01 ; at least 1 brigand was processed
sta $C9A0
ldy 2,u ; Get ptr to brigand position info
pshs dp,y,u
lda #0xC8
tfr a,dp
direct $C8
lda $C8A9 ; Is 'slow down' flag disabled?
bne P0A60 ; Nope, so don't update
inc 1,u ; Increment animation index
bitb #0x40 ; Has this brigand already thrown
bne P0A60 ; a flamoid? Branch if yes
ldx #FlamoidControlTable ; Determine if the
lda 1,u ; animation has reached the point
lda a,x ; where the flamoid can be thrown.
beq P0A60 ; Branch if not ready to throw
orb #0x40
stb 0,u ; Flag that flamoid's been thrown
jsr RANDOM
bita #0x70 ; Use a random # to determine
bne P0A49 ; whether to throw directly at
anda #0x87 ; player, or randomly.
bpl P0A45
ora #0xF9
P0A45: adda #0x20
bra P0A56
P0A49: lda 4,y ; Load brigand's y position
suba $C8EC ; Subtract off player's y position
ldb 6,y ; Load brigand's x position
subb $C8EE ; Subtract off player's x position
jsr CMPASS
adda #0x10 ; Calculate angle to player
P0A56: ldx 6,y ; Get flamoids initial x pos
ldb 8,y
ldy 4,y ; Get flamoids initial y pos
jsr TryToFireNewFlamoid
direct $D0
P0A60: puls dp,y,u
lda 1,u ; Get the animation index
asla
sta $C890 ; Save the animation index
lda 13,y
sta $CBA0 ; Control flipping of image
ldx #BrigandArmAndBodyTable
lda $C890
ldx a,x ; Skip drawing, if vector table
cmpx #0xFFFF ; entry is 0xFFFF.
beq P0AAE
cmpx #0x0000 ; See if animation has completed
beq P0AA8 ; Branch if complete
lda #0x60 ; Set drawing intensity
ldb 14,y ; Get scale factor
std $C883 ; Save them away
leay 0,y ; Get location to move to
sty $C885 ; Save them away
jsr DT_16bitMoveThenDraw
ldx #BrigandHeadTable
lda $C890 ; Use animation index to index
ldx a,x ; into the vector list table.
cmpx #0xFFFF ; Skip drawing, if vector table
beq P0AAE ; entry is 0xFFFF.
ldd $C883 ; Retrieve intensity & scale info
ldy $C885 ; Retrieve ptr to (y,x) position
jsr DT_16bitMoveThenDraw
bra P0AAE
P0AA8: lda #0x01 ; Flag that the brigand animation
sta 0,u ; sequence has completed.
clr 1,u ; Reset animation index
P0AAE: leau 4,u ; Process next array entry, if
dec $C88F ; any are left.
lbne P0A0A
rts
; CheckForFiringOrMovement()
;
; This function first checks to see if the player is
; attempting to fire a flamoid, and if so, then it
; fires one in the indicated direction. If not, then
; it checks to see if the player is trying to move left
; or right. This function is called when the player is
; in a treasure chest.
CheckForFiringOrMovement:
pshs dp
lda $C8EB
lbeq P0BB5 ; Skip, if player is dead
lda #0xC8
tfr a,dp
direct $C8
clr $C88F
clr $CBA0 ; Don't flip image
lda $C8C0
bne P0AF1
lda $C8BF
lbne P0B77
lda $C814 ; Get console 1, btn 3 state
beq P0ADC
lda #0x00 ; Fire straight (angle = 0 deg)
bra P0AEA
P0ADC: lda $C815 ; Get console 1, btn 4 state
beq P0AE4
lda #0x3D ; Fire right (angle = 15 deg right)
bra P0AEA
P0AE4: lda $C813 ; Get console 1, btn 2 state
beq CheckForLRMovement
lda #0x03 ; Fire left (angle = 15 deg left)
P0AEA: inc $C8C0
clr $C8F2 ; Set image index = 0
sta $C9A2 ; Save angle of fire
P0AF1: lda $C8AA
bne P0B1A
ldx #PlayerFireSynchronization
inc $C8F2 ; Increment animation index
lda $C8F2 ; See if the animation is now
lda a,x ; synched for flamoid to appear.
beq P0B1A ; Jump if not yet synched
lda $C8EC ; Get player's y position
clrb
tfr d,y ; Flamoids initial y position
lda $C8EE ; Get player's x position
adda #0x02
clrb
tfr d,x ; Flamoids initial x position
ldb #0xF8
lda $C9A2 ; Angle to fire flamoid
jsr TryToFireNewFlamoid
lda 0,u
ora #0x40
sta 0,u
P0B1A: jsr P1BF4
ldx #PlayerStandingStillLeftSide
stx $C8AF ; Set alternate vector list 2
lda $C8F2 ; Use player's animation index to
asla ; get the correct vector list.
ldx #PlayerThrowing_RightSide_Table
ldx a,x
stx $C8AD ; Set alternate vector list 1
bne P0B34
clr $C8C0
clr $C8F2 ; When last vector list is reached
bra P0B7C ; reset player's animation index.
P0B34: ldb #0x7F ; Calculate intensity
subb $C8CC
subb #0x10
lda #0x70 ; Get scale value
std $C8AB ; Set intensity & scale values
ldd #0x0000 ; Force drawing of alt vector lists
ldy #0xC8CD ; Set addr of drawing position
jsr Draw2VectorLists
jmp P0BB5
; CheckForLRMovement()
;
; This function handles moving the player to the left or
; right, while fighting brigands. It also takes care of
; drawing the 6 walls in the brigand area.
CheckForLRMovement:
lda $C81B ; Get joystick l/r position
beq P0B77 ; Do nothing, if in neutral
bmi GoLeft ; Branch if joystick is left
GoRight:
ldd $C8EE ; Get player's 16-bit x pos
cmpa #0x0C ; If not at upper bounds, then
bge P0B6B ; move player to the right.
addd #0x0060
std $C8EE ; Update player's 16-bit x pos
bra P0B69
GoLeft:
ldd $C8EE ; Get player's 16-bit x pos
cmpa #0xF4 ; If not at lower bounds, then
ble P0B6B ; move player to the left
subd #0x0060
std $C8EE ; Update player's 16-bit x pos
P0B69: inc $C88F
P0B6B: lda $C88F
beq P0B77
lda $C8A9 ; Is 'slow down' flag disabled?
bne P0B79 ; Nope, so don't update
inc $C8F2 ; Increment players animation index
bra P0B79
P0B77: clr $C8F2 ; Reset player's animation index
P0B79: jsr P1BF4
P0B7C: lda $C8F2 ; Load player's animation index
ldx #ImageFlip_Table
ldb a,x
stb $CBA0 ; Control flipping of image
asla
ldx #PlyrSideStepping_LeftSide_Tbl
ldx a,x
stx $C8AF ; Set alternate vector list 2
ldx #PlyrSideStepping_RightSide_Tbl
ldx a,x
stx $C8AD ; Set alternate vector list 1
bne P0B9B
clr $C8F2 ; Reset player's animation index
bra P0B7C
P0B9B: lda #0x70 ; Calculate intensity
suba $C8F0
cmpa #0x20
ble P0BB5
ldb #0x7F ; Calculate scale value
subb $C8CC
subb #0x10
std $C8AB ; Set intensity & scale values
ldd #0x0000 ; Force drawing of alt vector lists
ldy #0xC8CD ; Set addr of drawing position
jsr Draw2VectorLists
P0BB5: lda #0xD0
tfr a,dp
direct $D0
ldd #0x0000
std $C88F
clr $CBA0 ; Don't flip image
ldd #0x50FF
ldx #BrigandWalls
ldy #0xC88F
jsr DT_MoveThenDraw
dec $CBA0 ; Flip image
ldd #0x50FF
ldx #BrigandWalls
jsr DT_MoveThenDraw
puls dp,pc
; UpdateFlamoids()
;
; This function processes all active flamoids. Each active
; flamoid is checked to see if it has gone off the display,
; and if so, is deactivated. The lifespan value is
; decremented, to see if the flamoid should be deactivated.
; Otherwise, a random angle is used to transform the flamoid
; vector list (to give the impression it is spinning), and
; the flamoid is drawn.
UpdateFlamoids:
pshs dp
lda #0xC8
tfr a,dp
direct $C8
ldx #Flamoid
ldu #0xC9A4 ; Transform buffer
lda $C826 ; Calculate random angle
asla
asla
ldb ,x+ ; Get # of endpoints
stb ,u+ ; Also save in xform buffer
jsr DROT
ldd #0x0080
std $C837 ; Force 'run' index pair
ldd #0xFF81
std $C839 ; Force 'rise' index pair
ldu #0xC9F8 ; Get ptr to flamoid array
lda #0x08
sta $C88F ; Process 8 entries
P0C05: lda 0,u ; Skip, if entry not active
beq P0C41
jsr UpdatePosition
bvs P0C3F ; Disable flamoid, if it went
blo P0C3F ; off the display.
lda 5,u ; Load hi-byte of y position
ldb 7,u ; Load hi-byte of x position
sta $C8CA
stb $C8C8
lda 9,u
sta $C8C9
jsr TransformPoint
bvs P0C41
dec 10,u ; Decrement flamoid's lifespan
beq P0C3F
pshs dp
lda #0xD0
tfr a,dp
direct $D0
ldx #0xC9A4 ; Xformed flamoid vector list
ldd #0x7F7F ; Calculate intensity & scale
subb $C8CC
ldy #0xC8CD ; Address of drawing position
jsr DT_MoveThenDraw
puls dp
direct $C8
bra P0C41
P0C3F: clr 0,u ; Mark entry as now inactive
P0C41: leau 11,u ; Keep processing the entries,
dec $C88F ; until there are no more.
bne P0C05
puls dp,pc
; ProcessExplodingObjects()
;
; This function processes any active explosions (i.e. the
; player or a brigand exploding into pieces). Each
; exploding component has its angle of rotation updated
; (pieces appear to spin off during an explosion), along
; with its intensity (components get dimmer over time).
ProcessExplodingObjects:
pshs dp
lda #0xC8
tfr a,dp
direct $C8
clr $CBA0 ; Don't flip image
clr $C9A3
ldu #0xCA50 ; Get ptr to explosion bfr array
lda #0x0E
sta $C88F ; Set loop counter
P0C5C: lda 0,u
beq P0CA7 ; Skip if entry is inactive
dec 14,u ; Decrement lifespan; skip if
beq P0CA5 ; lifespan decrements to 0.
lda $C9A3
ora 14,u
sta $C9A3
jsr UpdatePosition
bvs P0CA5 ; Disable, if it went off the
blo P0CA5 ; display.
pshs u
lda 10,u ; Update angle value
adda 11,u
anda #0x3F ; Force in range 0-359 degrees
sta 10,u
ldx 12,u ; Get the vector list
ldu #0xC9A4 ; Transform buffer
ldb ,x+ ; Get number of endpoints
stb ,u+ ; Also save into xform buffer
andb #0x3F
jsr DROT
puls u
pshs dp
lda #0xD0
tfr a,dp
direct $D0
ldx #0xC9A4 ; Transform buffer
lda 14,u ; Calculate decreasing intensity
adda #0x30
ldb 9,u ; Set drawing scale factor
leay 5,u ; Set drawing position
jsr DT_16bitMoveThenDraw
puls dp
direct $C8
bra P0CA7
P0CA5: clr 0,u ; Disable this entry
P0CA7: leau 15,u ; Point to next entry
dec $C88F ; Process next entry, if any
bne P0C5C
puls dp,pc
; CheckFlamoidsForHits()
;
; This processes each active flamoid, to see if it has
; come in contact with the player, a brigand or a wall.
CheckFlamoidsForHits:
pshs dp
lda #0xC8
tfr a,dp
direct $C8
ldu #0xC9F8 ; Get ptr to flamoid array
lda #0x08
sta $C88F ; Set loop counter
P0CBC: lda 0,u ; Skip this flamoid, if it is
lbeq P0DF5 ; not active.
lda 5,u ; Get y position
ldb 7,u ; Get x position
std $C883 ; Save position for later use
lda 0,u
bita #0x40
bne CheckForHitOnWall
lda $C8EB ; Skip, if player is dead
beq CheckForHitOnWall
; CheckForHitOnPlayer()
;
; Tests to see if a flamoid thrown by a brigand has hit
; the players. If so, then the player is added to the
; explosion buffer, and he is flagged as dead.
CheckForHitOnPlayer:
ldx $C883 ; Get bullet position
lda $C8EC ; Get player's y position
ldb $C8EE ; Get player's x position
tfr d,y ; Set player as the target
ldd #0x0202 ; Size of target area / 2
jsr BXTEST
bhs CheckForHitOnWall ; Branch if no hit occurred
pshs x,y,u
clrb
lda $C8D0
tfr d,y
lda $C8D1
tfr d,x
lda #0x3F
ldu #PlayerExploding_Head
jsr RegisterNewExplosionEntry
ldu #PlayerExploding_LeftArm
jsr RegisterNewExplosionEntry
ldu #PlayerExploding_RightArm
jsr RegisterNewExplosionEntry
ldu #PlayerExploding_Body
jsr RegisterNewExplosionEntry
clr $C8EB ; Flag that player is dead
lda #0x7F
sta $C89C ; Reset startup delay counter
inc $C9A3
lda #0x80
sta $CB70
puls x,y,u
jmp P0DF3
; CheckForHitOnWall()
;
; This function tests to see if the flamoid has come
; in contact with any of the 6 walls in the brigand
; area. If it has, then the flamoid is marked as
; inactive.
CheckForHitOnWall:
ldx $C883 ; Get bullet position
ldy #0x52E0 ; Set target position
ldd #0x030A ; Get target size / 2
jsr BXTEST
lblo P0DF3
ldx $C883 ; Get bullet position
ldy #0x5EE8 ; Set target position
ldd #0x0306 ; Get target size / 2
jsr BXTEST
lblo P0DF3
ldx $C883 ; Get bullet position
ldy #0x66E8 ; Get target position
ldd #0x0309 ; Get target size / 2
jsr BXTEST
lblo P0DF3
ldx $C883 ; Get bullet position
ldy #0x5218 ; Get target position
ldd #0x0302 ; Get target size / 2
jsr BXTEST
lblo P0DF3
ldx $C883 ; Get bullet position
ldy #0x5E18 ; Get target position
ldd #0x0306 ; Get target size / 2
jsr BXTEST
lblo P0DF3
ldx $C883 ; Get bullet position
ldy #0x6618 ; Get target position
ldd #0x0308 ; Get target size
jsr BXTEST
blo P0DF3
; CheckForHitOnBrigand()
;
; This function loops through each of the flamoids, to
; see if a brigand has been hit. A brigand is only
; vulnerable when he is fully exposed. If a brigand is
; hit, then he will be added to the explosion buffer,
; the flamoid will be made inactive, and the player will
; be awarded 125 points.
CheckForHitOnBrigand:
ldy #0xC9E0 ; Get ptr to brigand array
lda #0x06
sta $C890 ; Set loop counter
P0D80: lda 0,y
bpl P0DEB
ldx #BrigandIsVulnerable ; It is only possible to
lda 1,y ; hit the brigand when he is fully
lda a,x ; exposed; check if he is.
beq P0DEB ; Nope; so don't check for a hit
lda 0,u ; Get flamoid state information
bita #0x40
beq P0DEB
pshs y,u
ldx 2,y ; Get ptr to brigand position info
lda 9,x
ldb 11,x
ldx 15,x ; Get target size information
pshs x
tfr d,y ; Save target position
lda 5,u ; Get flamoid y position
ldb 7,u ; Get flamoid x position
tfr d,x ; Save bullet position
puls a,b
jsr BXTEST
puls y,u
bhs P0DEB ; Branch if no hit occurred
pshs y,u
ldx 2,y ; Get ptr to brigand position info
ldy 0,x ; Load brigand's y position
lda 14,x
ldx 2,x ; Load brigand's x position
ldu #BrigandExploding_RightArm
jsr RegisterNewExplosionEntry
ldu #BrigandExploding_LeftArm
jsr RegisterNewExplosionEntry
ldu #BrigandExploding_Head
jsr RegisterNewExplosionEntry
puls y,u
clr 0,u ; Flag flamoid as inactive
ldx #0xCB3A ; Add 125 to player's score
ldd #0x0125
jsr SCRADD
inc $C9A3
lda #0x80
sta $CB6F
clr 0,y
dec $C8E9
lda #0x01
sta $C9A1
P0DEB: leay 4,y ; Point to next brigand entry
dec $C890 ; Decrement loop counter
bne P0D80 ; Process next brigand entry
bra P0DF5
P0DF3: clr 0,u ; Tag flamoid as inactive
P0DF5: leau 11,u ; Point to next flamoid entry
dec $C88F ; Decrement loop counter
lbne P0CBC ; Process next flamoid entry
puls dp,pc
; InsideMagicianChest()
;
; This functions controls the game, while the player is
; inside of a treasure chest containing a magician.
; It moves the player into the chest, animates the magician
; and then determines whether or not anything will be
; awarded to the player.
direct $D0
InsideMagicianChest:
jsr PreserveVisibleObjectData
jsr ClearAllGameStorageArrays
pshs dp
jsr SetPlayersPositionInChest
lda #0x80
sta $CB89 ; Flag start of dot sequence
lda #0x3F
sta $CB8A
lda #0x1F
sta $CB8B
P0E19: jsr CheckForInventoryRequest
lda $CB8B
beq P0E26
dec $CB8B
bra P0E2F
P0E26: ldd #0xCD00 ; Use fixed (y,x) position
jsr DrawDotsIfActive
sta $C8F0
P0E2F: jsr CheckForFiringOrMovement
lda $CB89 ; Jump if the dot sequence
bne P0E19 ; has not completed.
lda #0xC8
tfr a,dp
direct $C8
lda #0x80
sta $CB89 ; Flag start of dot sequence
lda #0x3F
sta $CB8A
lda #0x68
sta $CB8B
lda #0x7F
sta $C9A1
ldu #0xFF26
jsr SPLAY
P0E55: jsr CheckForInventoryRequest
lda $CB8B
beq P0E62
dec $CB8B
bra P0E6B
P0E62: ldd #0x1000 ; Use fixed (y,x) position
jsr DrawDotsIfActive
sta $C9A1
P0E6B: clr $C9A0 ; Clear magician animation index
jsr DrawMagician
jsr CheckForFiringOrMovement
lda $CB89 ; Jump if the dot sequence
bne P0E55 ; has not completed.
clr $C9A0
clr $C9A2
P0E7F: jsr CheckForInventoryRequest
jsr DrawAnimatedMagician
jsr CheckForFiringOrMovement
lda $C9A2
bne P0E8F
bra P0E7F
P0E8F: lda #0xC8
tfr a,dp
direct $C8
jsr RANDOM ; Random # decides if player
cmpa #0x80 ; has chance for award, or goes
bls AttemptMagicianAward ; away empty handed.
cmpa #0x90
lbls NoMagicianAward
; AttemptMagicianAward()
;
; This function attempts to award the player something
; useful, like a key, a scout, a healer or a warrior. The
; award given is dependent upon how much gold the player has.
; The more gold available, the better the award. Also,
; if the player already has a certain item, then the
; next best item will be awarded. After an award is
; made, the player is left with only a few bags of gold.
AttemptMagicianAward:
ldd $C8DD ; Player must have at least
cmpd #0x0060 ; 60 bags of gold to get the
blt P0EAF ; Gold Key.
jsr AwardGoldKey
lbne ChargePlayerForAward
P0EAF: ldd $C8DD ; Player must have at least
cmpd #0x0060 ; 60 bags of gold to get the
blt P0EBC ; Crystal Crown.
jsr AwardCrystalCrown
bne ChargePlayerForAward
P0EBC: ldd $C8DD ; Player must have at least
cmpd #0x0050 ; 50 bags of gold to get the
blt P0EC9 ; Silver Key.
jsr AwardSilverKey
bne ChargePlayerForAward
P0EC9: ldd $C8DD ; Player must have at least
cmpd #0x0040 ; 40 bags of gold to get the
blt P0ED6 ; Bronze Key.
jsr AwardBronzeKey
bne ChargePlayerForAward
P0ED6: ldd $C8DD ; Player must have at least
cmpd #0x0030 ; 30 bags of gold to get the
blt P0EE3 ; Brass Key.
jsr AwardBrassKey
bne ChargePlayerForAward
P0EE3: ldd $C8DD ; Player must have at least
cmpd #0x0020 ; 20 bags of gold to get the
blt P0F02 ; Scout.
lda $C8DB ; Skip, if already has a Scout
bne P0F02
inc $C8DB ; Flag that Scout was awarded
lda #0x04 ; Allow upto 4 uses of the scout
sta $C8C2 ; before he is used up.
ldx #0xCB3A ; Add 300 to player's score
ldd #0x0300
jsr SCRADD
lda #0x0C ; Show that bonus was awarded
bra ChargePlayerForAward
P0F02: ldd $C8DD ; Player must have at least
cmpd #0x0015 ; 15 bags of gold to get the
blt P0F21 ; Healer.
lda $C8DC ; Skip, if already has a healer
bne P0F21
inc $C8DC ; Flag that Healer was awarded
lda #0x04 ; Allow upto 4 uses of healer
sta $C8C3 ; before he is used up.
ldx #0xCB3A ; Add 300 to player's score
ldd #0x0300
jsr SCRADD
lda #0x0E ; Show that bonus was awarded
bra ChargePlayerForAward
P0F21: ldd $C8DD
cmpd #0x0010 ; Player must have at least
blt NoMagicianAward ; 10 bags of gold to get an
jsr AwardNewWarrior ; extra warrior.
bne ChargePlayerForAward
; NoMagicianAward()
;
; When the player enters a magician chest, he has a random
; chance of coming away empty handed. He will also come
; away empty handed if he does not have at least 10 bags
; of gold. This function displays the 'Be Gone' label,
; which tells the player he got nothing.
NoMagicianAward:
clra ; No award made; 'Be Gone'
jsr SetLabelOfFoundObject
bra DisplayMagicianAward
; ChargePlayerForAward()
;
; When the magician awards something to the player, he
; takes most of the player's gold, leaving him with only
; 2-9 bags of gold.
ChargePlayerForAward:
jsr SetLabelOfFoundObject
ldx #BagsOfGoldLabel_2
ldu #0xCB4B
jsr CopyStringToBuffer
jsr RANDOM
anda #0x07 ; When an award occurs, the
adda #0x02 ; player is 'charged' for it.
sta $C8DE ; The player is then left with
clr $C8DD ; only 2-9 bags of gold.
ora #0x30 ; Need to update the player's
sta $CB4E ; gold count in inventory list.
; DisplayMagicianAward()
;
direct $D0
DisplayMagicianAward:
lda #0x01
sta $CB89 ; Flag start of dot sequence
clr $CB8A
lda #0x0F
sta $CB8B
P0F5D: jsr CheckForInventoryRequest
lda $CB8B
beq P0F6A
dec $CB8B
bra P0F73
P0F6A: ldd #0x1000 ; Load fixed (y,x) location
jsr DrawDotsIfActive
sta $C9A1
P0F73: jsr DrawEnlargingString
jsr DrawMagician
jsr CheckForFiringOrMovement
lda $CB89 ; Jump if the dot sequence
bne P0F5D ; has not completed.
lda #0xC8
tfr a,dp
direct $C8
lda #0x01
sta $CB89 ; Flag start of dot sequence
clr $CB8A
lda #0x0F
sta $CB8B
P0F92: jsr CheckForInventoryRequest
lda $CB8B
beq P0F9F
dec $CB8B
bra P0FA8
P0F9F: ldd #0xCD00 ; Load fixed (y,x) location
jsr DrawDotsIfActive
direct $D0
sta $C8F0
P0FA8: jsr DrawEnlargingString
jsr CheckForFiringOrMovement
lda $CB89 ; Jump if the dot sequence
bne P0F92 ; has not completed.
jmp P09DB
; DrawAnimatedMagician()
; DrawMagician()
;
; DrawAnimatedMagician() draws the magician in an animated
; fashion, using C9A0 as the animation index, and incrementing
; it before drawing.
;
; DrawMagician() draws the magician using C9A0 as the
; animation index, but does not modify the index value.
direct $D0
DrawAnimatedMagician:
lda $C8A8 ; Is 'slow down' flag disabled?
bne DrawMagician ; Nope, so don't update
inc $C9A0 ; Increment animation index
DrawMagician:
lda $C9A0 ; Use animation index to get the
asla ; correct vector lists.
ldx #MagicianLeftSide_Table
ldx a,x
stx $C8AF ; Set alternate vector list 1
ldx #MagicianRightSide_Table
ldx a,x
stx $C8AD ; Set alternate vector list 1
bne P0FDE ; When last vector list reached,
dec $C9A0 ; repeat previous 1 again.
lda #0x01
sta $C9A2
bra DrawMagician
P0FDE: lda #0x70 ; Calculate intensity value
suba $C9A1 ; Make some adjustments
cmpa #0x20
ble P0FFC ; Skip if intensity < 0x20
ldb #0x50 ; Calculate scale factor
std $C8AB ; Set intensity & scale values
ldd #0x1000
std $C88F ; Set drawing position
ldd #0x0000 ; Force drawing of alt vector lists
ldy #0xC88F ; Set addr of drawing position
jsr Draw2VectorLists
P0FFC: rts
; TryToSolveRiddleOfKeys()
;
; Give the player the opportunity to order the keys, to
; solve the solution of the puzzle. Once the player
; signals that the solution should be checked, check the
; solution and either let them know it is solved, or
; move them back out of the tower, and allow them to
; try again.
TryToSolveRiddleOfKeys:
pshs dp,y,u
jsr PreserveVisibleObjectData
jsr ClearAllGameStorageArrays
lda #0xC8
tfr a,dp
direct $C8
clr $CBA0 ; Don't flip image
P100C: jsr CheckForInventoryRequest
direct $D0
lda $C813 ; Get console 1, btn 2 state
beq P101D
ldb $C9A4 ; Move selection arrow
incb
andb #0x03 ; Force in range 0-3
stb $C9A4 ; Update arrow position
P101D: lda $C814 ; Get console 1, btn 3 state
P1020: beq P1037
ldu #0xC9A0 ; Cycle to the next key choice.
lda #0x03 ; Get the index of the current
suba $C9A4 ; choice for this position in ;
leau a,u ; the solution, and increment
ldb ,u ; increment it, thus selecting
incb ; the next key. If wrapping
cmpb #0x04 ; needs to take place, then
bls P1035 ; wrap to key 1 (gold).
ldb #0x01
P1035: stb ,u ; Save the new value
P1037: lda $C815 ; Get console 1, btn 4 state
lbne TestRiddleSolution
P103E: jsr INTMAX
ldu #RiddleOfTheKeysLabel
jsr PrintMultiPartString
ldd #0xC0C4 ; Get drawing position
jsr POSITD
ldb #0xE0 ; Scale factor
ldx #TowerDoor
jsr DT_Draw ; Draw tower door
jsr INT3Q
ldd #0x1020 ; Get drawing position
jsr POSITD
ldb #0xA0 ; Scale factor
ldx #KeyHole
jsr DT_Draw ; Draw tower door keyhole
ldd #0xB290
; This block displays the player's choices (names of keys)
; for each of the 4 positions making up the solution to
; the riddle of the keys. It loops, once for each of the
; solution positions.
std $C88F ; Set initial icon drawing pos
ldd #0xA880
std $C891 ; Set initial text drawing pos
lda #0x03
sta $C893 ; Set loop counter for 4 passes
P1077: jsr INT3Q
ldd $C88F
addb #0x2E ; Update icon drawing position
std $C88F ; Get drawing position
jsr POSITD
ldb #0x38 ; Set scale factor
ldx #Key
jsr DT_Draw ; Draw the key icon
ldd #0xFC30
std $C82A ; Set text height & width
jsr INTMAX
ldd $C891
addb #0x2E ; Update text drawing position
std $C891 ; Get drawing position
jsr POSITD
ldu #0xC9A0 ; Get the index of the next
lda $C893 ; key in player's solution.
lda a,u
ldu #KeyNameLabelTable
asla ; Get the label for the key
ldu a,u ; Print name of this key
jsr RASTER
dec $C893 ; Decrement loop counter
bpl P1077
ldu #ArrowXpositions
lda $C9A4 ; Get location of arrow
ldb a,u ; Set x position
lda #0x98 ; Set y position
jsr POSITD
ldb #0x14 ; Set scale factor
ldx #Arrow
jsr DT_Draw ; Draw selection arrow
jmp P100C
; TestRiddleSolution()
;
; Compare the player's guess against the predetermined
; solution. If they match, then the game is over.
; Otherwise, show them which keys are correct, then
; place the player back outside the tower, or randomly
; in the forest (if he does not have a scout).
TestRiddleSolution:
ldx #0xC99C ; Ptr to real solution
ldu #0xC9A0 ; Ptr to player's guess
ldb #0x03 ; First, verify that each
lda ,u ; key was used only once;
adda 1,u ; the sum of the key indices
adda 2,u ; should be 10 (1+2+3+4).
adda 3,u
cmpa #0x0A ; All 4 keys in place?
lbne P103E ; Nope
P10E5: lda b,x ; Compare the order against
cmpa b,u ; the solution.
bne IncorrectAnswer ; Bail if a mismatch occurs
decb ; Decrement loop counter
bpl P10E5 ; Check remaining keys
jmp SolutionMatches ; The solutions match!!
; IncorrectAnswer()
;
; The player's guess was wrong. Briefly show them which
; keys were correct, and then drop them back into the
; forest.
IncorrectAnswer:
lda #0xC8 ; Incorrect solution
tfr a,dp
direct $C8
clr $CBA0 ; Don't flip image
lda #0x50
sta $C8EA ; Set duration counter
P10FC: jsr CheckForInventoryRequest
direct $D0
jsr INTMAX
ldd #0xC0C4 ; Set drawing position
jsr POSITD
ldb #0xE0 ; Set scale factor
ldx #TowerDoor
jsr DT_Draw ; Draw tower door
jsr INT3Q
ldd #0x1020 ; Set drawing position
jsr POSITD
ldb #0xA0 ; Set scale factor
ldx #KeyHole
jsr DT_Draw ; Draw the keyhole
ldd #0xB290
std $C88F ; Set initial drawing position
ldd #0xA880
std $C891 ; Set initial text position
lda #0x03
sta $C893 ; Set loop counter; 4 passes
ldd #0xFC30
std $C82A ; Set string height & width
P1138: ldd $C88F ; Retrieve saved drawing pos
addb #0x2E ; Adjust 'x' for next icon
std $C88F ; Save modified drawing position
ldd $C891 ; Retrieve saved text position
addb #0x2E ; Adjust 'x' for next string
std $C891 ; Increment text position
jsr INT3Q
ldd $C88F ; Set drawing position
jsr POSITD
ldb #0x38 ; Set scale factor
ldx #Key
jsr DT_Draw ; Draw the key icon
ldx #0xC99C ; Sequence thru each key; if
lda $C893 ; it was positioned correctly,
ldb a,x ; then keep displaying the key
ldx #0xC9A0 ; label, so player will know it.
cmpb a,x
bne P1182 ; This key was in wrong order
jsr INTMAX ; Key in correct order
ldu #0xC99C ; Get the label for the key
lda $C893 ; which was in the correct
lda a,u ; order.
ldu #KeyNameLabelTable
asla
ldu a,u
ldd $C891 ; Set drawing position
jsr POSITD
jsr RASTER ; Display key name
P1182: dec $C893 ; Decrement loop counter
bpl P1138 ; Anymore keys to process?
dec $C8EA ; Decrement duration counter
lbne P10FC ; Keep looping for awhile
lda #0xC8
tfr a,dp
direct $C8
jsr ClearAllGameStorageArrays
jsr FillInVisibleForestInfo
jsr RestoreVisibleObjectData
direct $D0
puls dp,y,u,pc
; SolutionMatches()
;
; The solution matches! Draw the player walking into the
; dark tower, followed by the 'Game Over' string.
SolutionMatches:
lda #0xC8 ; The block copy done below do
tfr a,dp ; nothing more than use up time.
direct $C8
ldu #0xC8F8 ; Work buffer
lda #0x10
sta $C890 ; Set loop counter
P11A8: ldx #0xC8D6 ; Table of player's possessions
ldd #0xFF00
std ,u++
clr $C88F ; Clear the checksum
P11B2: lda ,x+ ; Copy the player's possessions
sta ,u+ ; into a backup buffer.
adda $C88F
sta $C88F ; Update checksum
cmpx #0xC8DF ; Everything copied?
ble P11B2 ; Nope ... keep going
ldb #0x03 ; Set loop counter
ldy #0xCB4B ; " x Bags Of Gold" buffer
P11C5: lda ,y+ ; Copy first 4 bytes into the
sta ,u+ ; buffer also.
adda $C88F
sta $C88F ; Update the checksum
decb ; All bytes copied?
bpl P11C5 ; Nope ... keep going
ldb #0x03 ; Set loop counter
ldy #0xCB8C ; " x Reserve Troops" buffer
P11D6: lda ,y+ ; Copy first 4 bytes into the
sta ,u+ ; buffer also.
adda $C88F
sta $C88F ; Update the checksum
decb ; All bytes copied?
bpl P11D6 ; Nope ... keep going
ldb #0x06 ; Set loop counter
ldy #0xCB3A ; "Your Score Is x" string
P11E7: lda ,y+ ; Copy the 7 bytes of score
sta ,u+ ; into the buffer also.
adda $C88F
sta $C88F ; Update the checksum
decb ; All bytes copied?
bpl P11E7 ; Nope ... keep going
lda $C88F
sta ,u+ ; Save the checksum
dec $C890 ; Repeat, until loop counter
bne P11A8 ; decrements to 0.
ldu #DT_IntroMusic
jsr SPLAY ; Play intro music
ldx #0xCB3A ; Add 3000 to player's score
ldd #0x3000
jsr SCRADD
lda #0xFF
ldb #0x30
std $C896 ; Set player's intensity & scale
clr $C898 ; Use 16-bits of scale
ldd #0xE000
std $C8EC ; Set player's 16-bit y pos
P1216: jsr CheckForInventoryRequest
direct $D0
ldu #EnterVictoriousWarriorLabel
jsr PrintMultiPartString
ldd #0x48FF
std $C8AB ; Set tower intensity & scale
ldd #0xF000
std $C88F ; Set tower drawing position
clr $CBA0 ; Don't flip tower image
ldd #DarkTowerRightHalf ; Set vector list 1
ldx #DarkTowerLeftHalf ; Set vector list 2
ldy #0xC88F ; Set addr of drawing position
jsr Draw2VectorLists
lda #0xC8
tfr a,dp
direct $C8
dec $C896 ; Decrement player's intensity
lda $C896 ; As the player's intensity
bmi P1259 ; decreases, draw the player
cmpa #0x20 ; differently.
ble P1264
; Draw player walking into the Dark Tower
sta $C8AB ; Update player's intensity value
ldd $C897
subd #0x0020
std $C897 ; Decrement player's 16-bit scale
sta $C8AC ; Update player's scale value
jsr DrawPlayerWalking
bra P1216
; Draw player apprehensively approaching the Dark Tower
P1259: lda #0x7F
ldb #0x30
std $C8AB ; Set intensity & scale values
jsr PlayerStandingStill
bra P1216
; Stop drawing the player, and show 'Game Over'
P1264: jsr CheckForInventoryRequest
direct $D0
ldd #0x48FF
std $C8AB ; Set intensity & scale values
ldd #0xF000
std $C88F ; Set tower drawing position
clr $CBA0 ; Don't flip image
ldd #DarkTowerRightHalf ; Set vector list 1
ldx #DarkTowerLeftHalf ; Set vector list 2
ldy #0xC88F ; Set addr of drawing position
jsr Draw2VectorLists
jsr DisplayGameOverInfo
bra P1264
; CheckForInventoryRequest()
;
; As long as button 1 on console 1 is pressed, display
; the player's inventory information.
CheckForInventoryRequest:
lda #0xD0
tfr a,dp
direct $D0
jsr INTMAX
lda $C812 ; Get console 1, btn 1 state
lbeq DoMainProcessing ; Skip if btn 1 not pressed
lda $C856
ora $CB6C
ora $CB6D
ora $CB6E
ora $CB6F
ora $CB70
lbne DoMainProcessing
pshs dp
lda #0xC8
tfr a,dp
direct $C8
lda #0x80
jsr P14E5
puls dp
direct $D0
ldd #0x64A0 ; Set drawing position
jsr POSITD
ldd #0xF638 ; Set text drawing H & W values
std $C82A
ldu #0xCB2C ; Print "Your score is ..."
jsr RASTER
ldd #0x4CA0 ; Set drawing position
jsr POSITD
ldd #0xF638
std $C82A ; Set text drawing H & W values
ldu #InventoryLabel
jsr RASTER ; Display "Player Inventory"
ldd #0x38B8
std $C891 ; Set initial text position
lda $C8DF ; Display # of reserve troops, if
beq P130E ; there are any.
ldd $C891 ; Set drawing position
jsr POSITD
ldd #0xF838 ; Set text drawing H & W values
std $C82A
ldu #0xCB8C
P12F7: lda ,u ; Strip off leading spaces and
ora #0x10 ; zeros from the number of
cmpa #0x30 ; reserve troops; display the
bne P1303 ; modified value
leau 1,u
bra P12F7
P1303: jsr RASTER ; Display # of reserve troops
ldd $C891
suba #0x10
std $C891 ; Update text drawing position
P130E: ldd $C891 ; Set drawing position
jsr POSITD
ldd #0xF838
std $C82A ; Set text drawing H & W values
ldu #0xCB4B ; Strip off leading spaces and
P131D: lda ,u ; zeros from the number of bags
ora #0x10 ; of gold the player has; display
cmpa #0x30 ; the modified value.
bne P1329
leau 1,u
bra P131D
P1329: jsr RASTER ; Display # of bags of gold
ldd $C891
suba #0x10
std $C891 ; Update text drawing position
ldd #0xFA38
std $C82A ; Set text drawing H & W values
lda #0x07
sta $C88F ; Set loop counter
ldy #0xC8D6 ; Array of player's possessions
clr $C890 ; Index into player's possessions
P1346: lda $C890
lda a,y ; See if player has this object?
beq P1369 ; Skip, if answer is 'no'
ldd $C891 ; Set drawing position
jsr POSITD
ldu #TableOfObjectsToFind
lda $C890
asla
adda #0x02
ldu a,u ; Get label for this object
jsr RASTER
lda $C891
suba #0x10
sta $C891 ; Update text drawing position
P1369: inc $C890
dec $C88F ; Decrement loop counter
bne P1346 ; Keep processing?
jsr FRWAIT
jsr DEFLOK
jsr DEFLOK
jsr DEFLOK
jsr RANDOM
lda $C880 ; Load console button mask
jsr DBNCE ; Keep displaying inventory
jmp CheckForInventoryRequest ; until button 1
; is released.
direct $D0
DoMainProcessing:
jsr FRWAIT
pshs dp
jsr DEFLOK
lda $C880 ; Load console button mask
jsr DBNCE
ldd $C881 ; Configure the joystick:
std $C81F ; console 1 l/r => C81B
std $C821 ; console 1 u/d => C81C
jsr JOYBIT
lda #0xC8
tfr a,dp
direct $C8
lda $C826 ; Grab a random number
anda #0x07 ; Set 'slow down' counter; allows
sta $C8A8 ; updates only every 7th pass.
anda #0x03 ; Set 'slow down' counter; allows
sta $C8A9 ; updates only every 4th pass.
anda #0x01
sta $C8AA
lda $C89C ; The following block causes the
beq P13C1 ; function pointed to by C89D to
dec $C89C ; be called only once, when C89C
bne P13C1 ; decrements to zero.
jsr [ $C89D ]; (INDIRECT JUMP)
P13C1: lda $C89F ; The following block causes the
beq P13CD ; function pointed to by C8A0 to
dec $C89F ; be called only once, when C89F
bne P13CD ; decrements to zero.
jsr [ $C8A0 ]; (INDIRECT JUMP)
P13CD: lda $C8A2 ; The following block causes the
beq P13D9 ; function pointed to by C8A3 to
dec $C8A2 ; be called only once, when C8A2
bne P13D9 ; decrements to zero.
jsr [ $C8A3 ]; (INDIRECT JUMP)
P13D9: lda $C856
beq P13F2
clr $CB6D
clr $CB6C
clr $CB6E
clr $CB6F
clr $CB70
jsr REPLAY
jmp P14DF
P13F2: lda #0x80
jsr P14E5
lda $CB6C
bne P1421
lda $CB6D
bne P144C
lda $CB70
lbmi P14B5
lbne P14CA
lda $CB6F
lbmi P149D
lda $CB6E
lbmi P1483
lbne P1498
jmp P14CD
P1421: lda #0x03
jsr P14E5
dec $CB6C
ldb $CB6C
cmpb #0x04
bge P1433
aslb
bra P1438
P1433: ldb #0x0C
subb $CB6C
P1438: addb #0x02
andb #0x0F
stb $C844
stb $C843
ldd #0xE708
anda $C845
subb $C844
std $C845
jmp P14DF
P144C: lda #0x01
jsr P14E5
dec $CB6D
ldb $CB6D
cmpb #0x0F
bls P145D
ldb #0x0F
P145D: stb $C844
ldx #0x0700
ldb $C826
lsrb
ldb $CB6D
bhs P146E
ldx #0x0000
negb
P146E: sex
aslb
rola
aslb
rola
aslb
rola
aslb
rola
leax d,x
stx $C84B
lda #0xFE
anda $C845
sta $C845
bra P14DF
P1483: lda #0xFF
bsr P14E5
lda #0x01
sta $CB6E
clr $C877
lda #0x80
sta $C867
ldu #ExplosionSound3
jsr EXPLOD
P1498: clr $CB6F
bra P14CD
P149D: lda #0xFF
jsr P14E5
lda #0x01
sta $CB6F
clr $C877
lda #0x80
sta $C867
ldu #ExplosionSound1
jsr EXPLOD
bra P14CD
P14B5: lda #0xFF
bsr P14E5
lda #0x01
sta $CB70
clr $C877
lda #0x80
sta $C867
ldu #ExplosionSound2
jsr EXPLOD
P14CA: clr $CB6F
P14CD: jsr EXPLOD
lda $C877
bne P14DF
clr $CB6F
clr $CB70
clr $CB6E
clr $C867
P14DF: puls dp
jsr REQOUT
rts
P14E5: tsta
bmi P14FB
bne P14FF
clr $C856
clr $CB6C
clr $CB6D
clr $CB6E
clr $CB6F
clr $CB70
P14FB: jsr INTREQ
rts
P14FF: anda #0x07
tfr a,b
pshs a,b
asla
asla
asla
ora ,s+
ora $C845
sta $C845
ldx #0xC83F
clr ,x+
clr ,x+
clr ,x+
clr $C846
ldu #0xC847
puls a
ldb #0x02
P1520: lsra
bhs P152D
clr b,x
aslb
clr b,u
incb
clr b,u
decb
lsrb
P152D: decb
bpl P1520
rts
ExplosionSound1:
db 0x08
db 0xFF
db 0x00
db 0x02
ExplosionSound2:
db 0x3F
db 0x00
db 0x00
db 0x01
ExplosionSound3:
db 0x33
db 0x11
db 0x7F
db 0x08
DT_IntroMusic:
dw DT_MusicHeader
dw MSCHDR7
db 0x9A
db 0x95
db 0x1E
db 0x10
db 0x99
db 0x95
db 0x1E
db 0x05
db 0x99
db 0x95
db 0x1E
db 0x05
db 0x99
db 0x95
db 0x1E
db 0x05
db 0x97
db 0x9A
db 0x1E
db 0x10
db 0x95
db 0x9A
db 0x1C
db 0x10
db 0x9A
db 0x95
db 0x1E
db 0x10
db 0x9A
db 0x95
db 0x1E
db 0x10
db 0x9A
db 0x8E
db 0x21
db 0x18
db 0x99
db 0x90
db 0x1F
db 0x08
db 0x9A
db 0x95
db 0x1E
db 0x10
db 0x99
db 0x95
db 0x1E
db 0x05
db 0x99
db 0x95
db 0x1E
db 0x05
db 0x99
db 0x95
db 0x1E
db 0x05
db 0x97
db 0x9A
db 0x1E
db 0x10
db 0x95
db 0x9A
db 0x1C
db 0x10
db 0x9A
db 0x95
db 0x1E
db 0x10
db 0x9A
db 0x95
db 0x1E
db 0x10
db 0x9A
db 0x95
db 0x1E
db 0x08
db 0x9A
db 0x95
db 0x1C
db 0x08
db 0x9A
db 0x95
db 0x1A
db 0x08
db 0x9A
db 0x95
db 0x1C
db 0x08
db 0x8E
db 0x89
db 0x1E
db 0x7F
db 0x00
db 0x80
DT_MusicHeader:
db 0x0F
db 0xFF
db 0xFE
db 0xED
db 0xDC
db 0xCB
db 0xBA
db 0xA9
db 0x98
db 0x88
db 0x88
db 0x88
db 0x87
db 0x76
db 0x65
db 0x54
EnteringChestSound:
dw MSCHDR5
dw MSCHDR7
db 0x9C
db 0x90
db 0x04
db 0x0C
db 0x9C
db 0x90
db 0x04
db 0x0C
db 0x9C
db 0x90
db 0x04
db 0x06
db 0x9C
db 0x90
db 0x04
db 0x06
db 0x9C
db 0x90
db 0x04
db 0x0C
db 0x9F
db 0x93
db 0x07
db 0x0C
db 0x9E
db 0x92
db 0x06
db 0x06
db 0x9E
db 0x92
db 0x06
db 0x06
db 0x9C
db 0x90
db 0x04
db 0x06
db 0x9C
db 0x90
db 0x04
db 0x06
db 0x9A
db 0x8E
db 0x02
db 0x06
db 0x9C
db 0x90
db 0x04
db 0x0C
db 0x04
db 0x80
FogSound:
dw MSCHDR6
dw MSCHDR2
db 0x1E
db 0x14
db 0x1D
db 0x14
db 0x13
db 0x14
db 0x1D
db 0x14
db 0x1C
db 0x14
db 0x17
db 0x14
db 0x1C
db 0x14
db 0x1B
db 0x14
db 0x16
db 0x14
db 0x1B
db 0x14
db 0x1A
db 0x14
db 0x15
db 0x7F
db 0x00
db 0x80
AwardSound:
dw DT_MusicHeader
dw MSCHDR7
db 0xA6
db 0xA1
db 0x2A
db 0x10
db 0xA5
db 0xA1
db 0x2A
db 0x05
db 0xA5
db 0xA1
db 0x2A
db 0x05
db 0xA5
db 0xA1
db 0x2A
db 0x05
db 0xA3
db 0xA6
db 0x2A
db 0x10
db 0xA1
db 0xA6
db 0x28
db 0x10
db 0x9A
db 0x95
db 0x12
db 0x7F
db 0x00
db 0x80
PlayerDeadSound:
dw MSCHDR6
dw MSCHDR7
db 0x80
db 0x87
db 0x15
db 0x11
db 0x80
db 0x91
db 0x15
db 0x0C
db 0x80
db 0x91
db 0x15
db 0x04
db 0x80
db 0x90
db 0x15
db 0x11
db 0x80
db 0x91
db 0x18
db 0x0C
db 0x82
db 0x8E
db 0x17
db 0x04
db 0x84
db 0x8C
db 0x17
db 0x08
db 0x84
db 0x8C
db 0x15
db 0x08
db 0x84
db 0x8B
db 0x15
db 0x08
db 0x84
db 0x8B
db 0x14
db 0x08
db 0x84
db 0x8C
db 0x15
db 0x70
db 0x00
db 0x80
; CheckForDeadPlayer()
;
; This function checks to see if the player has died, and
; if so, attempts to restart him, using one of the
; replacement warriors. If no replacement warriors are
; left, then the game is over else, the player restarts
; from where they last were.
CheckForDeadPlayer:
lda $C8EB
bne P167D ; Skip, if player is alive
lda $C8DF ; Any replacement warriors left?
ble P167B ; Jump if none left
lda #0x01
sta $C8EB ; Flag that player is alive
ldx #0xCB8C ; Subtract one warrior from the
clra ; player's reserve troops.
jsr DecrementSignedString
dec $C8DF ; Decrement reserve troop counter
lda #0x01
sta $C8F2 ; Reset player's animation index
lda #0x1F
sta $C89C ; Reset startup delay counter
clr $C8F0
lda #0xFF
sta $C8F1 ; Set player line drawing pattern
rts
P167B: inc $C8D3 ; Flag that game is over
P167D: rts
; ActivateABrigand()
;
; Randomly choose one of the six brigands to activate.
; Add to the array of active brigands. Set a random
; delay, which must expire before the brigand appears.
ActivateABrigand:
lda $C8E9
bpl P1687
lda $C9A0 ; Were any brigands processed in
bne P16B2 ; last pass thru mainloop?
P1687: jsr RANDOM ; Nope, so start one up
anda #0x07 ; Randomly determine which of the
cmpa #0x05 ; 6 brigands to start up.
bgt ActivateABrigand ; Bad random #; try again
pshs a
ldb #0x04 ; Use the randomly generated index
mul ; to get a pointer to the
addd #0xC9E0 ; associated brigand data.
tfr d,u
ldb #0x06
subb ,s+
P169E: lda 0,u ; Is brigand entry in use?
bpl P16A9 ; Nope, so use it
leau 4,u ; Yep, so try again, by checking
decb ; the next available brigand; stop
bne P169E ; when we reach the end of the
bra P16B2 ; brigand array.
P16A9: lda #0x80 ; Flag that entry is in use
sta 0,u
clr 1,u ; Reset animation index
clr $C9A1 ; Clear 'brigand hit' flag
P16B2: jsr RANDOM
anda #0x3F ; Generate a random number, which
ora #0x20 ; specifies the delay before the
adda #0x1C ; newly activated brigand starts
sta $C89F ; to appear.
rts
; CheckIfAllKeysAwarded()
;
; Exit: Carry bit set if all keys have been found.
;
; This function checks to see if the player has already
; found all of the keys.
direct $D0
CheckIfAllKeysAwarded:
lda $C8D6 ; Gold key awarded yet?
beq P16D5
lda $C8D7 ; Silver key awarded yet?
beq P16D5
lda $C8D8 ; Bronze key awarded yet?
beq P16D5
lda $C8D9 ; Brass key awarded yet?
beq P16D5
orcc #0x01 ; All keys have been awarded
rts
P16D5: clra ; Not all keys awarded yet
rts
; SetLabelOfFoundObject()
;
; Entry: a = index into awards table, of the label for the
; awarded object.
;
; This function saves the label and the drawing position
; for the object indicated by the passed-in table index.
direct $C8
SetLabelOfFoundObject:
pshs u
ldu #TableOfObjectsToFind
ldu a,u
stu $C8F3 ; Save ptr to string to print
ldu #ObjectPositionTable
ldu a,u
stu $C8F5 ; Set drawing position
clr $C8F7 ; Init index into H/W table
ldu #AwardSound
jsr SPLAY
puls u,pc
; DrawEnlargingString()
;
; Displays an object found by the player. Each pass thru,
; the string gets bigger.
direct $D0
DrawEnlargingString:
pshs x,u
ldu $C8F3 ; String to draw
beq P1723 ; Skip, if ptr is NULL
lda $C8F7 ; Index into H/W table
adda #0x08
cmpa #0x70
bge P1704
sta $C8F7
P1704: ldx #StringHeightWidthTable
lsra
lsra
anda #0x1E
ldd a,x
std $C82A ; Set the desired H & W values
jsr INTMAX
lda $C8F7
adda #0x04
sta $D004 ; Set the scale factor
ldd $C8F5 ; Set drawing position
jsr POSITN
jsr RASTER
P1723: puls x,u,pc
; InvokeRandomFunctionFromTable()
;
; Enter: u = pointer to array of award functions.
;
; Exit: a = index of award, or 0 if no award.
;
; This function attempts to randomly choose an award for
; the player, from the array of possible awards passed in.
; It will attempt to award the player with something he
; can use, making a maximum of 7 attempts. However, if
; any one attempt selects an empty entry in the array,
; then no further attempts are made.
direct $C8
InvokeRandomFunctionFromTable:
pshs b,x,u ; Try upto 7 times to pick an
lda #0x07 ; award which the player can
sta $C88B ; use.
P172B: jsr RANDOM ; Randomly select one of the
anda #0x0E ; awards.
ldx a,u ; Award nothing, if the table
beq P173C ; entry is NULL.
jsr ,x ; Attempt to give the award
bne P173D ; Jump, if we succeeded
dec $C88B ; Try again, unless we've
bne P172B ; already tried 7 times.
P173C: clra ; Signal no award occurred
P173D: puls b,x,u,pc
; PreserveVisibleObjectData()
;
; Anytime the player leaves the forest (i.e. entering a
; treasure chest or attempting to solve the riddle of the
; keys), we must save the current state and animation
; information for each visible object. This function
; takes care of doing that.
direct $D0
PreserveVisibleObjectData:
pshs x,y
ldx #0xC978
ldy #0xC9A6
lda #0x12
sta $C883 ; Set loop counter
P174C: lda 7,y
sta 0,x ; Save state machine index
lda 8,y
sta 1,x ; Save animation index
leax 2,x ; Point to next array entry
leay 9,y ; Point to next array entry
dec $C883 ; Decrement loop counter
bne P174C ; Process next entry
puls x,y,pc
direct $C8
; RestoreVisibleObjectData()
;
; Anytime the player returns to the forest (i.e. leaving a
; treasure chest), we must restore the current state and
; animation information for each visible object. This
; function takes care of doing that.
RestoreVisibleObjectData:
pshs x,y
ldx #0xC978
ldy #0xC9A6
lda #0x12
sta $C883 ; Set loop counter
P176B: lda 0,x
sta 7,y ; Restore state machine index
lda 1,x
sta 8,y ; Restore animation index
leax 2,x ; Point to next array entry
leay 9,y ; Point to next array entry
dec $C883 ; Decrement loop counter
bne P176B ; Process next entry
puls x,y,pc
; Entry: y = ptr to forest info, based on direction of travel
;
; Exit: b = 'image flip' control bit setting.
; a = type of tree at specified location.
GenerateForestData:
ldd ,y++
lbeq P17EE ; Jump, if at end of data array
adda $C883 ; Add modified player y position
sta $C885
clr $C889
asla
blo P17EA ; Branch if 'carry' bit set
asla
blo P17EA ; Branch if 'carry' bit set
asla
rol $C889
addb $C884 ; Add modified player x position
stb $C886
aslb
blo P17EA ; Branch if 'carry' bit set
aslb
blo P17EA ; Branch if 'carry' bit set
aslb
rol $C889
ldx #0x1E72
clr $C88A
ldb $C885
lsrb
rol $C88A
stb $C88C
lda #0x40
mul
std $C887
ldb $C886
andb #0x3F
sex
addd $C887
std $C887
clr $C88B
lsra
rorb
rol $C88A
lsra
rorb
rol $C88B
leax d,x
lda ,x
inca
beq GenerateForestData ; Branch if value = 0xFF
inca
beq P17F1 ; Branch if value = 0xFE
ldb $C88A
bne P17DF
lda ,x
ldb $C88B
beq P17DB
lsra
lsra
lsra
lsra
P17DB: anda #0x0F
bne P17E1
P17DF: lda $C889
P17E1: ldb $C88B
eorb $C88C
andb #0x01 ; Set 'image flip' return value
andcc #0xFC ; Clear 'carry' & 'overflow' bits
rts
P17EA: clra ; Tree type = dead tree
orcc #0x02 ; Set the 'overflow' bit
rts
P17EE: orcc #0x01 ; All done; set the 'carry' bit
rts
P17F1: ldb $C88A
bne GenerateForestData
ldb $C88B
bitb #0x01
lbeq GenerateForestData
lda #0x07 ; Object is the Dark Tower
bra P17E1
; CheckIfObjectConsumed
;
; Entry: y = ptr to entry in 'visible forest' array
; (C9A6-CA47) entry, which represents some
; non-tree object.
;
; Exit: $C883 = ptr to 'consumed' byte for this object.
; $C885 = bitmask for object's 'consumed' flag.
; a = 0 if object not consumed, else non-zero.
;
; Checks to see if a consumable object (i.e. bags of gold)
; has already been picked up by the user.
CheckIfObjectConsumed:
ldb 2,y
andb #0x3E
lda #0x20
mul
std $C883
ldb 4,y
andb #0x3F
sex
addd $C883
clr $C885
lsra
rorb
lsra
rorb
ror $C885
lsra
rorb
ror $C885
lsra
rorb
ror $C885
rol $C885
rol $C885
rol $C885
rol $C885
addd #0xC8F8
std $C883
lda $C885 ; Convert bit number (0-7) into
jsr DECBIT ; bit mask
sta $C885 ; Save the generated bitmask
anda [ $C883 ]
rts
; AwardNewWarrior()
;
; Award the player with a random number (1-4) of reserve
; warriors, unless he has already maxed out.
AwardNewWarrior:
pshs x
jsr RANDOM
anda #0x03 ; Randomly determine how many
adda #0x01 ; new warriors to award (1-4)
sta $C883
lda $C8DF ; Increment # of reserve warriors
adda $C883 ; the player has, unless he is
blo P1872 ; max'ed out.
sta $C8DF
ldx #NewWarriorLabel
ldu #0xCB5D
jsr CopyStringToBuffer
lda $C883 ; Create string telling player
ora #0x30 ; how many warriors were awarded
sta $CB5D
ldx #0xCB8C ; Ptr to 'Reserve Troops' buffer
lda $C883 ; # of new troops awarded
jsr UpdateAwardsStringBuffer
ldx #0xCB3A ; Update player's score, by
lda $C883 ; adding (newWarriorCount ; 100)
clrb
jsr SCRADD
lda #0x12 ; Flag that award occurred
puls x,pc
P1872: clra ; Flag that no award occurred
puls x,pc
; AwardBagsOfGold()
;
; Award the player a random number (2-9) of bags of gold,
; unless already maxed out.
AwardBagsOfGold:
pshs x
jsr RANDOM
anda #0x07 ; Generate a random number (2-9)
adda #0x02 ; representing the number of
sta $C884 ; bags of gold to award.
clr $C883 ; Make into 16-bit number
ldd $C8DD ; Add to player's gold bag count,
addd $C883 ; unless already max'ed out.
blo P1872
std $C8DD ; Save updated gold count
ldx #BagsOfGoldLabel
ldu #0xCB5D
jsr CopyStringToBuffer
lda $C884 ; Insert the number of bags into
ora #0x30 ; the string buffer.
sta $CB5D
ldx #0xCB4B ; Ptr to 'Bags of gold' buffer
lda $C884 ; # of bags awarded
jsr UpdateAwardsStringBuffer
ldx #0xCB3A ; Update player's score, by
lda $C884 ; adding (# bags gold ; 100)
clrb
jsr SCRADD
lda #0x10
puls x,pc
; AwardGoldKey()
;
; Award the player the gold key.
AwardGoldKey:
pshs x
lda $C8D6 ; Only do this once; skip if
bne P1872 ; already done.
lda #0x01
sta $C8D6 ; Flag that Gold key was found
ldx #0xCB3A
ldd #0x1000 ; Add 1000 to player's score
jsr SCRADD
lda #0x02 ; Show that bonus was awarded
puls x,pc
; AwardSilverKey()
;
; Award the player the silver key.
AwardSilverKey:
pshs x
lda $C8D7 ; Only do this once; skip if
bne P1872 ; already done.
lda #0x01
sta $C8D7 ; Flag that Silver key was found
ldx #0xCB3A
ldd #0x0900 ; Add 900 to player's score
jsr SCRADD
lda #0x04 ; Show that bonus was awarded
puls x,pc
; AwardBronzeKey()
;
; Award the player the bronze key.
AwardBronzeKey:
pshs x
lda $C8D8 ; Only do this once; skip if
bne NoAward ; already done.
lda #0x01
sta $C8D8 ; Flag that Bronze key was found
ldx #0xCB3A
ldd #0x0800 ; Add 800 to player's score
jsr SCRADD
lda #0x06 ; Show that bonus was awarded
puls x,pc
; AwardBrassKey()
;
; Award the player the brass key.
AwardBrassKey:
pshs x
lda $C8D9 ; Only do this once; skip if
bne NoAward ; already done.
lda #0x01
sta $C8D9 ; Flag that Brass key was found
ldx #0xCB3A
ldd #0x0700 ; Add 700 to player's score
jsr SCRADD
lda #0x08 ; Show that bonus was awarded
puls x,pc
; AwardCrystalCrown()
;
; Award the player the crystal crown.
AwardCrystalCrown:
pshs x
lda $C8DA ; Only do this once; skip if
bne NoAward ; already done.
lda #0x01
sta $C8DA ; Flag that Crystal Crown found
ldx #0xCB3A
ldd #0x1500 ; Add 1500 to player's score
jsr SCRADD
lda #0x0A ; Show that bonus was awarded
puls x,pc
; NoAward()
;
; Since what was going to be awarded the player is alread
; in the player's possession, no award will occur.
NoAward:
clra ; Show that no bonus was awarded
puls x,pc
; TryToFireNewFlamoid()
;
; Entry: x = initial 16-bit x position
; y = initial 16-bit y position
; a = angle
; b =
;
; If the flamoid buffer is not full, then fire another
; flamoid.
TryToFireNewFlamoid:
pshs a,b,x,y
ldu #0xC9F8 ; Ptr to flamoid array
ldb #0x08 ; # of entries in the array
P192C: lda 0,u ; If this entry is not active,
beq FireNewFlamoid ; go ahead and use it.
leau 11,u ; Else, try next entry.
decb
bne P192C
orcc #0x01 ; Signal that the flamoid array
puls a,b,x,y,pc ; was full; couldn't do new one.
; FireNewFlamoid()
;
; Add a new flamoid to the list of active flamoids.
FireNewFlamoid:
lda #0x01
sta 0,u ; Mark entry as active
lda #0x90
sta 10,u ; Set lifespan counter
ldd 2,s
std 7,u ; Set initial x position
ldd 4,s
std 5,u ; Set initial y position
lda 1,s
sta 9,u
lda #0x40
ldb ,s ; Get firing angle
jsr LNROT
sta $C883 ; Calculate 16-bit x delta
sex
aslb
rola
aslb
rola
aslb
rola
std 3,u ; Set 16-bit x delta
ldb $C883 ; Calculate 16-bit y delta
sex
aslb
rola
aslb
rola
aslb
rola
std 1,u ; Set 16-bit y delta
lda #0x80
sta $CB6E
clra ; Flag that flamoid was fired
puls a,b,x,y,pc
; RegisterNewExplosionEntry()
;
; Entry: a = Scale factor
; u = Vector list pointer
; x = 16-bit x position
; y = 16-bit y position
;
; If the explosion buffer is not full, then add a new
; explosion to the list of active explosions.
RegisterNewExplosionEntry:
pshs a,x,y,u
ldu #0xCA50 ; Ptr to explosion buffer array
ldb #0x0E ; Loop counter
P1979: lda 0,u ; Look for an unused entry
beq FillExplosionEntry
leau 15,u ; Try next entry
decb
bne P1979
orcc #0x01 ; Flag no open entry found
puls a,x,y,u,pc
; FillExplosionEntry()
;
; Entry: u = ptr to explosion buffer entry to be filled
; a = Scale factor
; u = Vector list pointer
; x = 16-bit x position
; y = 16-bit y position
;
; Fill in the indicated explosion buffer entry, with
; details about the new explosion.
FillExplosionEntry:
lda #0x01
sta 0,u ; Flag entry as in use
sty 5,u ; Save initial y position
stx 7,u ; Save initial x position
clr 10,u ; Set initial angle = 0
jsr CONE
sta 11,u ; Save spin rate
lda #0x30
sta 14,u ; Set lifespan counter
lda ,s
sta 9,u ; Save scale factor
ldd 5,s
std 12,u ; Save vector list ptr
jsr CONE
lda #0x20 ; Set velocity
jsr MLTY16
sty 1,u ; Save 16-bit rise value
stx 3,u ; Save 16-bit run value
clra ; Flag that open entry was found
puls a,x,y,u,pc
; UpdatePosition()
;
; Entry: u = Ptr to flamoid or explosion buffer entry
;
; Exit: Sets 'Carry' bit if 'y' value overflowed.
; Sets 'Overflow' bit if 'x' value overflowed.
;
; Update the (y,x) information for this entry, using the
; rise and run information contained in the entry.
UpdatePosition:
ldd 5,u ; Load 16-bit y position
addd 1,u ; Add 16-bit y delta
pshs a
tfr ccr,a ; Check for y overflow
anda #0x02
lsra
sta -1,s ; Save overflow flag
puls a
std 5,u ; Save updated 16-bit y position
ldd 7,u ; Load 16-bit x position
addd 3,u ; Add 16-bit x delta
pshs a
tfr ccr,a ; Check for x overflow
anda #0xF2
ora -1,s
sta -1,s ; Update overflow flags
puls a
std 7,u ; Save updated 16-bit x position
lda -2,s
tfr a,ccr ; Set condition codes to saved
rts ; value.
; TryToStartFog()
;
; If a fog is not already active, start one, and make
; the appropriate sound.
TryToStartFog:
pshs dp,x,y,u
lda #0xC8
tfr a,dp
direct $C8
lda $C9A0
bne P19F9 ; Skip, if a fog is active
lda #0x01
sta $C9A0 ; Set 'increase fog' mode
clr $C9A1 ; Init fog loop counter
ldd #0x0500
std $C9A4 ; Reset plague delay counter
ldu #FogSound
jsr SPLAY
P19F9: puls dp,x,y,u,pc
; TryToStartPlague()
;
; If a fog is not already active, start one, and make
; the appropriate sound.
TryToStartPlague:
pshs dp,x,y,u
lda #0xC8
tfr a,dp
direct $C8
lda $C9A2 ; Only start plague if not
ora $C9A4 ; already active, and if plague
ora $C9A5 ; delay counter has reached 0.
bne P1A20 ; Skip if plague already active
lda #0x01
sta $C9A2 ; Signal plague is starting
ldu #PlayerDeadSound
jsr SPLAY
clr $C9A3 ; Clear plague duration counter
ldd #0x0500
std $C9A4 ; Reset plague delay counter
P1A20: puls dp,x,y,u,pc
; ClearAllGameStorageArrays()
;
; This function clears out all of the 'area' specific
; game memory. This is necessary anythime the player
; leaves a particular area (i.e. the forest, or a chest).
ClearAllGameStorageArrays:
ldx #0xC9A0 ; Clear C9A0-CB2B
P1A25: clr ,x+
cmpx #0xCB2C
bne P1A25
clr $CB6C
clr $CB6D
clr $CB6E
clr $CB6F
clr $CB70
rts
; UpdateAwardsStringBuffer()
;
; Entry: x = ptr to string buffer
; a = # of objects be awarded
UpdateAwardsStringBuffer:
pshs a,x
leax 1,x
lda 2,x ; If this position is a space char,
ora #0x10 ; then convert it to an ascii '0'
adda ,s ; Add in the # of awarded objects
sta 2,x ; Store back into the string
cmpa #0x39 ; Check for digit overflow
ble P1AA3 ; No overflow occurred, so jump
suba #0x0A ; Subtract 10 from this digit
sta 2,x
ldb #0x01 ; Jump elsewhere, to take care of
bra P1A60 ; carry, and stripping leading 0's
; IncrementSignedString()
; DecrementSignedString()
;
; Entry: a = 0 => string value is not at 0
; 1 => string value is currently at 0
; x = pointer to signed string buffer
;
; Exit: a = 0 => string value is not at 0
; 1 => string value is now at 0
;
; This code triggers off of the leading character in the
; string, to determine if the current value is negative
; (if so, then the leading character will be '-'). After
; updating the string value, any leading zeros will be
; stripped off, and the string will be reset to " 0", if
; necessary.
IncrementSignedString:
pshs a,x
lda ,x ; Skip elsewhere, if the first digit
cmpa #0x2D ; is "-" (negative number).
beq P1A86
P1A5C: leax 1,x ; Process the least significant
ldb #0x02 ; digit first.
P1A60: lda b,x ; Add 1 to digit; if its a " ",
ora #0x10 ; then or with 0x10, to first
inca ; convert it to a '0' .
sta b,x ; Save updated digit.
cmpa #0x39 ; Check for digit wrapping past '9'
bls P1AA3
lda #0x30 ; Wrap occurred; convert this digit
sta b,x ; to '0', and increment the next
decb ; digit.
bpl P1A60
bra P1AA3 ; All done
DecrementSignedString:
pshs a,x
lda ,x ; If first digit is '-' (negative
cmpa #0x2D ; number), then jump elsewhere.
beq P1A5C
lda ,s ; If the # of steps is currently
beq P1A86 ; '0', then we need to force the
lda #0x2D ; step count to be negative, by
sta ,x ; adding a '-' to the front.
bra P1A5C
P1A86: leax 1,x ; Process least significant digit
ldb #0x02 ; first.
lda b,x
cmpa #0x30 ; If the digit is '0', then we will
bgt P1AA1 ; need to force a 'borrow' operation
P1A90: lda #0x39 ; Need to do a borrow
sta b,x ; Force this digit to '9' first
decb ; Point to the next digit
bmi P1AA3
dec b,x ; Perform the borrow
lda b,x
cmpa #0x30 ; See if this forces us to then
bge P1AA3 ; need to borrow from the next
bra P1A90 ; digit.
P1AA1: dec b,x ; Decrement digit, then all done
; Strip off leading zeros
P1AA3: clrb ; Reset index into steps string
clr ,s ; Set return value
P1AA6: lda b,x
bmi P1AB5 ; Did we reach end of string?
cmpa #0x30 ; Strip off leading '0's, by
bgt P1AC2 ; replacing them with ' ' characters
lda #0x20
sta b,x
incb ; Process next digit
bra P1AA6
; All digits were stripped, so reset string to " 0"
P1AB5: lda #0x30
decb
sta b,x ; Set last digit to '0'
lda #0x20
sta -1,x ; Set next to last digit to ' '
lda #0x01
sta ,s ; Set return value
P1AC2: puls a,x,pc
; CheckForGameOver()
;
; If the player has run out of lives, then display the
; "Game Over' string, along with the score. Set a timer
; for automatically restarting a new game, and check for
; Btn 4, to see if a new game should be started immediately.
direct $D0
CheckForGameOver:
lda $C8D3 ; Has player run out of lives?
beq P1B09 ; Nope
DisplayGameOverInfo:
pshs dp
jsr INTMAX
ldu #GameOverLabel ; Display 'Game Over'
jsr PrintMultiPartString
ldd #0x78DC ; Move the pen
jsr POSITD
ldd #0xF638
std $C82A ; Set string H & W values
ldu #0xCB39 ; Display player's score
jsr RASTER
lda #0xC8
tfr a,dp
direct $C8
ldx #0xCB3A ; Did player set new hi score?
ldu #0xCBEB
jsr HISCR
clr $C89C ; Clear startup delay counter
clr $C89F ; Disable C8A0 invocation
clr $C8A2 ; Disable C8A3 invocation
clr $C8A5
ldx $C8D4 ; Decrement restart timer;
beq P1B0A ; restart new game when = 0.
leax -1,x
stx $C8D4
lda $C815 ; Start new game if btn 4 on
bne P1B0A ; console 1 is pressed.
puls dp
P1B09: rts
P1B0A: leas 3,s ; Fix the stack, then restart
jmp StartNewGame
; SetPlayersPositionInForest()
;
; Set the player's screen position to the location (y,x)
; (0xC0,0x00), and reset other attributes.
SetPlayersPositionInForest:
lda #0xC8
tfr a,dp
direct $C8
ldd #0xC000
std $C8EC ; Set player's 16-bit y position
ldd #0x0000
std $C8EE ; Set player's 16-bit x position
clr $C8F0
lda #0xFF
sta $C8F1 ; Set player line drawing pattern
lda #0x01
sta $C8F2 ; Reset player's animation index
clr $C8BF ; Flag that player's in the forest
clr $C8C0
rts
; SetPlayersPositionInChest()
;
; Set the player's screen position to the location (y,x)
; (0x28,0x00), and reset other attributes.
SetPlayersPositionInChest:
lda #0xC8
tfr a,dp
direct $C8
ldd #0x2800
std $C8EC ; Set player's 16-bit y position
ldd #0x0000
std $C8EE ; Set player's 16-bit x position
lda #0x7F
sta $C8F0
lda #0xFF
sta $C8F1 ; Set player line drawing pattern
clr $C8F2 ; Reset player's animation index
clr $C8C0
lda #0x01
sta $C8BF ; Flag that player's in a chest
lda #0x88
sta $C8CB
rts
; PlacePlayerRandomlyInForest()
;
; This function generates a new random forest location
; and angle of travel for the player. It also updates
; the visible forest information.
PlacePlayerRandomlyInForest:
jsr RANDOM
anda #0x3F ; Set random direction, in range
sta $C8B2 ; 0-359 degrees.
bsr PlayerChangedDirection
bsr SetPlayersPositionInForest
jsr RANDOM
lsra ; The following block generates
rorb ; a 16-bit number, in the range
lsra ; 0x0401-0x39FF. The value
rorb ; represents the player's new
cmpd #0x3A00 ; 16-bit 'y' position, within
blt P1B6A ; the forest.
subd #0x0800
P1B6A: cmpd #0x0400
bgt P1B73
addd #0x0800
P1B73: std $C8B4 ; Save player's new 16-bit 'y' pos
sta $C8B8 ; Save pos where forest was inited
jsr RANDOM
lsra ; The following block generates
rorb ; a 16-bit number, in the range
lsra ; 0x0401-0x39FF. The value
rorb ; represents the player's new
cmpd #0x3A00 ; 16-bit 'x' position, within
blt P1B87 ; the forest.
subd #0x0800
P1B87: cmpd #0x0400
bgt P1B90
addd #0x0800
P1B90: std $C8B6 ; Save player's new 16-bit 'x' pos
sta $C8B9 ; Save pos where forest was inited
clr $C8C1
jmp FillInVisibleForestInfo
; PlayerChangedDirection()
;
; When the player turns left or right, or is randomly
; placed back into the forest, this function is called.
; It initializes some of the variables holding information
; about the angle of travel, and it also resets the step
; count (and the associated string) to '0 steps'.
PlayerChangedDirection:
lda $C8B2 ; Get player's angle of travel
suba #0x08 ; The following saves the angle
anda #0x3F ; minus 45 degrees; however, C8B3
sta $C8B3 ; is never referenced anywhere !!
lda $C8B2 ; Force direction in the range of
anda #0x3F ; 0-359 degrees.
sta $C8B2
adda #0x20
sta $C836 ; Use angle + 180 degrees
jsr SINCOS ; Get sin & cos
ldd $C837
std $C8C4 ; Save the sin value
ldd $C839
std $C8C6 ; Save the cos value
lda #0x20 ; Get velocity
ldb $C8B2 ; Get angle (direction)
addb #0x20 ; Use angle + 180 degrees
jsr LNROT
sta $C883 ; Temporarily save the rise value
sex ; Convert run to 16 bits
std $C8BC ; Save 16-bit run value
ldb $C883 ; Retrieve saved rise value
sex ; Convert to 16 bits
std $C8BA ; Save 16-bit rise value
ldd #0x2020
std $CB44 ; Set CB44-CB49 = " 0",0x80
std $CB46 ; This will track # of steps taken
ldd #0x3080 ; since the last change in
std $CB48 ; direction of travel.
lda #0x01
sta $CB4A ; Force step count to 0
ldx #CompassPointLabels
lda $C8B2 ; Map angle of travel into a
lsra ; compass direction.
lsra
anda #0x0E
ldx a,x
ldu #0xCB41 ; Fill buffer with string
P1BEB: lda ,x+ ; indicating the direction of
bmi P1BF3 ; travel.
sta ,u+
bra P1BEB
P1BF3: rts
P1BF4: ldd #0x0080
std $C837 ; Force sin = 180 degrees
ldd #0xFF81
std $C839 ; Force cos = 180 degrees
lda $C8EC ; Get player's y position
sta $C8CA
lda $C8EE ; Get player's x position
sta $C8C8
lda #0xF8
sta $C8C9
bsr TransformPoint
lda $C8CD
sta $C8D0
lda $C8CE
sta $C8D1
rts
; TransformPoint()
;
; Entry: C8CA = y coordinate to be rotated.
; C8C8 = x coordinate to be rotated.
;
; Exit:
;
; This function rotates a translated point about the
; virtual origin, using the standard rotation transformation:
;
; y = -(y*cos() - x*sin())
; x = -(x*cos() + y*sin())
;
; Note that the above transformations both are negated I'm
; not sure why this is, other than maybe it's due to the
; fact that these transformations assume a clockwise angle,
; and the vectrex uses a counter-clockwise angle.
TransformPoint:
lda $C8CA ; Get y scalar value
jsr MCSINE ; y ; cos()
sta $C883 ; Save the result
lda $C8C8 ; Get x scalar value
jsr MSINE ; x ; sin()
suba $C883 ; -((y;cos()) - (x*sin()))
ble P1C4B
sta $C8CC ; Save rotated y endpoint
lda $C8C9
bsr P1C4E
bvs P1C4B
cmpb $C8CB
ble P1C4B
stb $C8CD
lda $C8C8 ; Get x scalar value
jsr MCSINE ; x ; cos()
sta $C883 ; Save the result
lda $C8CA ; Get y scalar value
jsr MSINE ; y ; sin()
adda $C883 ; ((x;cos()) + (y*sin()))
nega ; -((x;cos()) + (y*sin()))
bsr P1C4E
bvs P1C4B
stb $C8CE
andcc #0xFD
rts
P1C4B: orcc #0x02
rts
P1C4E: tfr ccr,b
bpl P1C53
nega
P1C53: stb $C884
clr $C885
cmpa $C8CC
bge P1C87
ldb $C8CC
subb #0x02
blo P1C87
cmpb #0x0E
bhi P1C67
dec $C885
P1C67: ldy #0x2172
ldb b,y
mul
tst $C885
bne P1C7A
asra
rorb
asra
rorb
asra
rorb
asra
rorb
P1C7A: tstb
bmi P1C87
lda $C884
tfr a,ccr
bpl P1C84
negb
P1C84: andcc #0xFD
rts
P1C87: orcc #0x02
rts
; CopyStringToBuffer()
;
; Entry: x = string to be copied.
; u = buffer into which string will be copied.
CopyStringToBuffer:
lda ,x+
sta ,u+
bpl CopyStringToBuffer
rts
; PrintMultiPartString()
;
; Entry: u = ptr to multi-part string.
;
; Displays a multi-part (or multi-line) string. The
; string has the following format:
;
; h,w,y,x,string,0x80,h,w,y,x,string,0x80,0x00
direct $D0
PrintMultiPartString:
pshs u
P1C93: ldd ,u++
std $C82A
ldd ,u++
jsr POSITD
jsr RASTER
lda ,u
bne P1C93
puls u,pc
; DrawDotsIfActive()
;
; Entry: d = (y,x) position to draw dots at
;
; The work performed by this function is controlled by
; the value of CB89, which can take on the following values:
;
; 0 => Dot sequence is inactive.
; >0 => Scale adjustment factor (CB8A) will be
; increased over time.
; <0 => Scale adjustment factor (CB8A) will be
; decreased over time.
DrawDotsIfActive:
std $C885 ; Save location
lda $CB89 ; Do nothing if dot sequence is
beq P1CE6 ; not active.
bmi P1CBE ; Use decreasing scale adj factor
lda $CB8A ; Use increasing scale adj factor
adda #0x02 ; Increase scale adjustment factor
sta $CB8A ; by 2. We're done when it goes
cmpa #0x20 ; >= 0x20.
bge P1D1D ; All done
bra P1CC8 ; Keep it active
P1CBE: lda $CB8A ; Use decreasing scale adj factor
suba #0x02 ; Decrease scale adj factor by 2.
sta $CB8A ; We're done when it goes <= 0
ble P1D1D ; All done
P1CC8: lda $CB8A
sta $C889 ; Set scale adjustment factor
lda #0x09 ; Initialize the index used to
sta $C88A ; index into the dot list table
P1CD3: jsr ZERGND
dec $C88A ; Decrement dot table index
bne DrawDotList
lda $C889 ; When the dot index goes to 0,
adda #0x08 ; then update the scale and
sta $C889 ; intensity adjuster value, and
jsr ZERGND ; then return.
P1CE6: lda $CB8A
asla
rts ; Return (adj factor ; 2)
; DrawDotList()
;
; Entry: C885 = (y,x) drawing position
; C889 = Scale/Intensity adjustment
; C88A = Index into dot array
;
; Exit: a = Scale adjustment factor
;
; Draws a set of dots, whose intensity and scale are
; calculated using the current index into the dot array,
; adjusted by the value in C889.
DrawDotList:
lda #0x03 ; Number of dots to draw - 1
sta $C823
ldd $C885 ; Load drawing position
suba #0x08 ; Subtract 8 from y position
jsr POSITD
ldb $C88A ; Calculate scale factor
aslb ; Multiply index by 4
aslb
addb $C889 ; Factor in scale adjustment
ble P1CD3 ; Skip if scale <= 0
andb #0x7F ; Force scale in range 0 - 0x7F
stb $D004 ; Set scale factor
ldx #0xCB71 ; Get ptr to array of dot lists
lda $C88A ; Get the dot table index, and
deca ; use it to generate the offset
asla ; into the dot list table.
ldx a,x ; Get next dot list from array
lda #0x7F ; Calculate the intensity
suba $C889 ; Factor in intensity adjustment
jsr INTENS
jsr DIFDOT
bra P1CD3
P1D1D: jsr ZERGND
clr $CB89 ; Flag dot sequence is complete
lda $CB8A
asla
rts ; Return (adj factor ; 2)
; Draw2VectorLists()
;
; Entry: y = addr of drawing position
; x = vector list 2
; d = vector list 1
; C8AB - C8AC = intensity & scale
; C8AD = alternate vector list 1
; C8AF = alternate vector list 2
;
; If 'd' is not 0x0000, then the two primary vector lists
; are drawn otherwise, the alternate vector lists are
; drawn. In either case, before drawing, the pen is moved
; to the position specified by the 2 8-bit values pointed
; to by the 'y' register.
Draw2VectorLists:
pshs a,b,dp,x,y
lda #0xD0
tfr a,dp
direct $D0
ldd $C8AB ; Get intensity & scale values
ldy 5,s ; Get addr of drawing position
ldx 0,s ; Get vector list
beq P1D46
bsr DT_MoveThenDraw
ldd $C8AB ; Get intensity & scale values
ldx 3,s ; Get vector list
ldy 5,s ; Get addr of drawing position
bsr DT_MoveThenDraw
puls a,b,dp,x,y,pc
P1D46: ldx $C8AD ; Get vector list
bsr DT_MoveThenDraw
ldd $C8AB ; Get intensity & scale values
ldx $C8AF ; Get vector list
ldy 5,s ; Get addr of drawing position
bsr DT_MoveThenDraw
puls a,b,dp,x,y,pc
; Draw2VectorLists_16bit()
;
; Entry: y = addr of 16-bit drawing position
; x = vector list 2
; d = vector list 1
; C8AB - C8AC = intensity & scale
; C8AD = alternate vector list 1
; C8AF = alternate vector list 2
;
; If 'd' is not 0x0000, then the two primary vector lists
; are drawn otherwise, the alternate vector lists are
; drawn. In either case, before drawing, the pen is moved
; to the position specified by the 2 16-bit values pointed
; to by the 'y' register.
Draw2VectorLists_16bit:
pshs a,b,dp,x,y
lda #0xD0
tfr a,dp
direct $D0
ldd $C8AB ; Get intensity & scale values
ldy 5,s ; Get drawing position
ldx 0,s ; Get vector list
beq P1D76
bsr DT_16bitMoveThenDraw
ldd $C8AB ; Get intensity & scale values
ldx 3,s ; Get vector list
ldy 5,s ; Get drawing position
bsr DT_16bitMoveThenDraw
puls a,b,dp,x,y,pc
P1D76: ldx $C8AD ; Get vector list
bsr DT_16bitMoveThenDraw
ldd $C8AB ; Get intensity & scale values
ldx $C8AF ; Get vector list
ldy 5,s ; Get drawing position
bsr DT_16bitMoveThenDraw
puls a,b,dp,x,y,pc
; DT_MoveThenDraw()
;
; Entry: a = intensity
; b = scale
; y = ptr to 8-bit (y,x) position to move to
; x = ptr to mode and vector list, where mode is:
;
; 0 => <0 or 0xFF> y x
; <0 => (count-1) y x y x ... (move to 1st point)
; >0 => (count-1) y x y x ... (draw to 1st point)
;
DT_MoveThenDraw:
pshs b,x,y
jsr INTENS
ldd ,y
jsr POSITD
puls b,x,y
bra DT_Draw
; DT_16bitMoveThenDraw()
;
; Entry: a = intensity
; b = scale
; y = ptr to 16-bit (yHiyLo,xHixLo) position to move to
; x = ptr to mode and vector list, where mode is:
;
; 0 => <0 or 0xFF> y x
; <0 => (count-1) y x y x ... (move to 1st point)
; >0 => (count-1) y x y x ... (draw to 1st point)
;
DT_16bitMoveThenDraw:
pshs b,x,y
jsr INTENS
tfr y,x
jsr POSWID
puls b,x,y
; DT_Draw()
;
; Entry: b = scale
; x = ptr to mode and vector list, where mode is:
;
; 0 => <0 or 0xFF> y x
; <0 => (count-1) y x y x ... (move to 1st point)
; >0 => (count-1) y x y x ... (draw to 1st point)
;
; CBA0 is used to control whether the 'x' coordinate is
; negated before drawing is done this will 'flip' the
; image. Useful when drawing something walking, since
; you only need to store the images for 1 side moving
; to get the other side to move, you simply flip the image.
DT_Draw:
stb $D004 ; Set scale factor
lda ,x+
beq P1E21
bmi P1DB0
bra P1DDD
P1DAC: stb $D004
lda ,x+
P1DB0: anda #0x3F ; Move to first point in list
sta $C823 ; Save number of points
ldd ,x ; Load y,x pair
sta $D001 ; Write y value
clr $D000
leax 2,x
nop
inc $D000
tst $CBA0 ; Flip the image?
beq P1DC6
negb
P1DC6: stb $D001 ; Write x value
ldd #0x0000
sta $D00A ; Force line pattern to 0
stb $D005
ldd #0x0040
P1DD2: bitb $D00D ; Wait for timer interrupt
beq P1DD2
nop
sta $D00A
lda $C823
P1DDC: deca ; Decrement point counter
P1DDD: sta $C823 ; Save number of points
ldd ,x ; Load next y,x pair
sta $D001 ; Write y value
clr $D000
leax 2,x
nop
inc $D000
tst $CBA0 ; Flip the image?
beq P1DF1
negb
P1DF1: stb $D001 ; Write x value
lda $C829
ldb #0x40
sta $D00A ; Set line pattern
clr $D005
bitb $D00D ; Timer interrupt happened yet?
beq P1E0D
clr $D00A ; Yes; clear line pattern
lda $C823
bne P1DDC ; Anymore points to draw?
jmp ZERGND ; Nope; all done
P1E0A: lda $C829
P1E0D: sta $D00A ; Set line pattern again
nop
bitb $D00D ; Timer interrupt happened yet?
beq P1E0A
lda $C823 ; Yes
clr $D00A
tsta ; Anymore points to draw?
bne P1DDC
jmp ZERGND ; Nope; all done
; These vector lists have 3 bytes per entry
P1E1F: stb $D004 ; Set scale factor
P1E21: ldd 1,x ; Load next y,x pair
sta $D001 ; Write y value
clr $D000
lda ,x ; Get line pattern
leax 3,x
tst $CBA0 ; Flip the image?
beq P1E31
negb
P1E31: inc $D000
stb $D001 ; Write x value
sta $D00A ; Set line pattern
clr $D005
ldd #0x0040
P1E3C: bitb $D00D ; Wait for timer interrupt
beq P1E3C
nop
sta $D00A ; Clear drawing pattern
lda ,x
ble P1E21 ; Anymore points to draw?
jmp ZERGND ; Nope; all done.
; This space appears to be unused
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
S1E72: db 0x00
db 0xFF
db 0xFF
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x61
db 0x06
db 0xFF
db 0xFF
db 0x00
db 0xFF
db 0x00
db 0x00
db 0xE0
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x15
db 0x19
db 0x11
db 0xFF
db 0xFF
db 0xFF
db 0x08
db 0x00
db 0x00
db 0x00
db 0x00
db 0x18
db 0x11
db 0x1A
db 0x11
db 0x1B
db 0x11
db 0x11
db 0x11
db 0x00
db 0xE0
db 0x0D
db 0x00
db 0xC0
db 0x00
db 0x0B
db 0x00
db 0x11
db 0x61
db 0x11
db 0x11
db 0x11
db 0x61
db 0x11
db 0x11
db 0x00
db 0x00
db 0x60
db 0x05
db 0x00
db 0x0E
db 0x00
db 0x00
db 0x19
db 0x18
db 0x1A
db 0x11
db 0x18
db 0x11
db 0x1B
db 0x11
db 0x00
db 0x00
db 0x09
db 0x00
db 0x08
db 0x00
db 0x0A
db 0x00
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x61
db 0x11
db 0x11
db 0x60
db 0x00
db 0x00
db 0x06
db 0x00
db 0x60
db 0x00
db 0xE0
db 0x1F
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x1B
db 0x11
db 0x00
db 0x00
db 0x0B
db 0x00
db 0x0C
db 0x00
db 0x0D
db 0x00
db 0x11
db 0x11
db 0x11
db 0x61
db 0x11
db 0x1A
db 0x16
db 0x11
db 0x00
db 0x00
db 0x60
db 0x0E
db 0x00
db 0x60
db 0x00
db 0x00
db 0x18
db 0x11
db 0x1A
db 0x11
db 0x1A
db 0x11
db 0x19
db 0x11
db 0x00
db 0xE0
db 0x0B
db 0x00
db 0x0A
db 0x00
db 0x08
db 0x00
db 0x11
db 0x61
db 0x11
db 0x18
db 0x11
db 0x11
db 0x11
db 0x11
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x0E
db 0x1A
db 0x11
db 0x1B
db 0x11
db 0x18
db 0x11
db 0x1F
db 0x11
db 0x06
db 0x00
db 0x00
db 0x06
db 0x00
db 0x0E
db 0x00
db 0x00
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x11
db 0x00
db 0xB0
db 0x00
db 0xA0
db 0x44
db 0x44
db 0x44
db 0x44
db 0x46
db 0x44
db 0x44
db 0x48
db 0x1A
db 0x11
db 0x1B
db 0x11
db 0x00
db 0x08
db 0x00
db 0x00
db 0x44
db 0x84
db 0x46
db 0x44
db 0x44
db 0x44
db 0x4B
db 0x44
db 0x11
db 0x16
db 0x11
db 0x11
db 0x00
db 0xA0
db 0x00
db 0xB0
db 0x44
db 0x44
db 0xFF
db 0xFF
db 0x44
db 0x4F
db 0x44
db 0x44
db 0x18
db 0x11
db 0x19
db 0x11
db 0x00
db 0x00
db 0x08
db 0x00
db 0x4E
db 0xFF
db 0xFF
db 0xFF
db 0xFF
db 0xFF
db 0x44
db 0xE4
db 0x11
db 0x11
db 0x11
db 0x11
db 0x62
db 0x22
db 0x62
db 0x22
db 0x44
db 0xFF
db 0xFF
db 0xFE
db 0xFF
db 0xFF
db 0x44
db 0x44
db 0x33
db 0x63
db 0x33
db 0x63
db 0x22
db 0x92
db 0x22
db 0xA2
db 0x44
db 0xFF
db 0xFF
db 0xFF
db 0xFF
db 0xFF
db 0x44
db 0x44
db 0x3A
db 0x33
db 0x3A
db 0x33
db 0x22
db 0x22
db 0x22
db 0x22
db 0x44
db 0x94
db 0xFF
db 0xFF
db 0x44
db 0x4F
db 0x4B
db 0x44
db 0x33
db 0x38
db 0x33
db 0x33
db 0x2A
db 0x22
db 0x2A
db 0x22
db 0x44
db 0x44
db 0x44
db 0x44
db 0x44
db 0x44
db 0x44
db 0x44
db 0x3B
db 0x33
db 0x3A
db 0x33
db 0x22
db 0x22
db 0x22
db 0x62
db 0x22
db 0x22
db 0x22
db 0x62
db 0x33
db 0x36
db 0x33
db 0x33
db 0x36
db 0x33
db 0x33
db 0x33
db 0x28
db 0x22
db 0x28
db 0x22
db 0x2A
db 0x22
db 0x2B
db 0x22
db 0x3C
db 0x33
db 0x3D
db 0x33
db 0x3E
db 0x33
db 0x3F
db 0x33
db 0x22
db 0x22
db 0x22
db 0x28
db 0x22
db 0x22
db 0x22
db 0x22
db 0x63
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x2F
db 0x22
db 0x2E
db 0x22
db 0x2D
db 0x26
db 0x2C
db 0x22
db 0x3B
db 0x33
db 0x3A
db 0x33
db 0x39
db 0x33
db 0x38
db 0x33
db 0x22
db 0x26
db 0x22
db 0x28
db 0x62
db 0x22
db 0x22
db 0x22
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x36
db 0x2A
db 0x22
db 0xA2
db 0x22
db 0x2B
db 0x22
db 0x2A
db 0x22
db 0x38
db 0x33
db 0x38
db 0x36
db 0x3A
db 0x33
db 0x3A
db 0x33
db 0x22
db 0x26
db 0x22
db 0x26
db 0x22
db 0x22
db 0x22
db 0x22
db 0x33
db 0x38
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x2B
db 0x22
db 0x2B
db 0x22
db 0x2A
db 0x22
db 0x2A
db 0x22
db 0x3A
db 0x33
db 0x39
db 0x33
db 0x38
db 0x33
db 0x3A
db 0x33
db 0x22
db 0x22
db 0x22
db 0x22
db 0x22
db 0x22
db 0x22
db 0x22
db 0x33
db 0x33
db 0x33
db 0x36
db 0x33
db 0x33
db 0x36
db 0x33
db 0xFF
db 0xFF
db 0xFF
db 0x22
db 0x2B
db 0x22
db 0x2C
db 0x22
db 0x3D
db 0x33
db 0x3E
db 0x33
db 0x3F
db 0x33
db 0x38
db 0x33
db 0xFF
db 0xFF
db 0xFF
db 0x22
db 0x22
db 0x22
db 0x22
db 0x22
db 0x33
db 0x33
db 0x33
db 0x33
db 0x33
db 0x35
db 0x33
db 0x36
db 0x25
db 0xFF
db 0xFF
db 0x26
db 0x22
db 0x62
db 0x22
db 0x29
db 0x33
db 0x63
db 0x33
db 0x36
db 0x33
db 0x33
db 0x33
db 0x36
; The entry used from this array is determined by the
; player's direction of travel.
DirectionalForestData:
dw NorthForestData ; Direction = North
dw NorthWestForestData ; Direction = NorthWest
dw WestForestData ; Direction = West
dw SouthWestForestData ; Direction = SouthWest
dw SouthForestData ; Direction = South
dw SouthEastForestData ; Direction = SouthEast
dw EastForestData ; Direction = East
dw NorthEastForestData ; Direction = NorthEast
NorthForestData:
db 0x05
db 0x06
db 0x05
db 0x07
db 0x05
db 0x08
db 0x05
db 0x09
db 0x04
db 0x05
db 0x04
db 0x06
db 0x04
db 0x07
db 0x04
db 0x08
db 0x04
db 0x09
db 0x03
db 0x05
db 0x03
db 0x06
db 0x03
db 0x07
db 0x03
db 0x08
db 0x03
db 0x09
db 0x00
db 0x00
NorthWestForestData:
db 0x03
db 0x07
db 0x03
db 0x08
db 0x03
db 0x09
db 0x04
db 0x07
db 0x04
db 0x08
db 0x04
db 0x09
db 0x05
db 0x07
db 0x05
db 0x08
db 0x05
db 0x09
db 0x06
db 0x07
db 0x06
db 0x08
db 0x06
db 0x09
db 0x07
db 0x08
db 0x07
db 0x09
db 0x08
db 0x09
db 0x00
db 0x00
WestForestData:
db 0x05
db 0x09
db 0x06
db 0x07
db 0x06
db 0x08
db 0x06
db 0x09
db 0x07
db 0x07
db 0x07
db 0x08
db 0x07
db 0x09
db 0x08
db 0x07
db 0x08
db 0x08
db 0x08
db 0x09
db 0x09
db 0x08
db 0x09
db 0x09
db 0x00
db 0x00
SouthWestForestData:
db 0x07
db 0x06
db 0x07
db 0x07
db 0x07
db 0x08
db 0x07
db 0x09
db 0x08
db 0x06
db 0x08
db 0x07
db 0x08
db 0x08
db 0x08
db 0x09
db 0x09
db 0x06
db 0x09
db 0x07
db 0x09
db 0x08
db 0x09
db 0x09
db 0x00
db 0x00
SouthForestData:
db 0x07
db 0x03
db 0x07
db 0x04
db 0x07
db 0x05
db 0x07
db 0x06
db 0x07
db 0x07
db 0x08
db 0x03
db 0x08
db 0x04
db 0x08
db 0x05
db 0x08
db 0x06
db 0x08
db 0x07
db 0x09
db 0x03
db 0x09
db 0x04
db 0x09
db 0x05
db 0x09
db 0x06
db 0x09
db 0x07
db 0x00
db 0x00
SouthEastForestData:
db 0x05
db 0x03
db 0x05
db 0x04
db 0x06
db 0x03
db 0x06
db 0x04
db 0x06
db 0x05
db 0x07
db 0x03
db 0x07
db 0x04
db 0x07
db 0x05
db 0x08
db 0x03
db 0x08
db 0x04
db 0x08
db 0x05
db 0x09
db 0x03
db 0x09
db 0x04
db 0x09
db 0x05
db 0x00
db 0x00
EastForestData:
db 0x03
db 0x03
db 0x03
db 0x04
db 0x03
db 0x05
db 0x04
db 0x03
db 0x04
db 0x04
db 0x04
db 0x05
db 0x05
db 0x03
db 0x05
db 0x04
db 0x05
db 0x05
db 0x06
db 0x03
db 0x06
db 0x04
db 0x06
db 0x05
db 0x07
db 0x03
db 0x07
db 0x04
db 0x07
db 0x05
db 0x00
db 0x00
NorthEastForestData:
db 0x03
db 0x03
db 0x03
db 0x04
db 0x03
db 0x05
db 0x03
db 0x06
db 0x03
db 0x07
db 0x04
db 0x03
db 0x04
db 0x04
db 0x04
db 0x05
db 0x04
db 0x06
db 0x04
db 0x07
db 0x05
db 0x03
db 0x05
db 0x04
db 0x05
db 0x05
db 0x05
db 0x06
db 0x05
db 0x07
db 0x00
db 0x00
S2172: db 0x80
db 0x55
db 0x40
db 0x33
db 0x2C
db 0x25
db 0x20
db 0x1C
db 0x1A
db 0x17
db 0x15
db 0x14
db 0x12
db 0x11
db 0x10
db 0xF1
db 0xE4
db 0xD8
db 0xCD
db 0xC3
db 0xBA
db 0xB2
db 0xAB
db 0xA4
db 0x9E
db 0x98
db 0x92
db 0x8D
db 0x89
db 0x84
db 0x80
db 0x7C
db 0x78
db 0x75
db 0x72
db 0x6F
db 0x6C
db 0x69
db 0x66
db 0x64
db 0x62
db 0x5F
db 0x5D
db 0x5B
db 0x59
db 0x57
db 0x55
db 0x54
db 0x52
db 0x50
db 0x4F
db 0x4D
db 0x4C
db 0x4A
db 0x49
db 0x48
db 0x47
db 0x45
db 0x44
db 0x43
db 0x42
db 0x41
db 0x40
db 0x3F
db 0x3E
db 0x3D
db 0x3C
db 0x3B
db 0x3B
db 0x3A
db 0x39
db 0x38
db 0x37
db 0x37
db 0x36
db 0x35
db 0x35
db 0x34
db 0x33
db 0x33
db 0x32
db 0x31
db 0x31
db 0x30
db 0x30
db 0x2F
db 0x2F
db 0x2E
db 0x2E
db 0x2D
db 0x2D
db 0x2C
db 0x2C
db 0x2B
db 0x2B
db 0x2A
db 0x2A
db 0x29
db 0x29
db 0x29
db 0x28
db 0x28
db 0x27
db 0x27
db 0x27
db 0x26
db 0x26
db 0x26
db 0x25
db 0x25
db 0x25
db 0x24
db 0x24
db 0x24
db 0x23
db 0x23
db 0x23
db 0x22
db 0x22
db 0x22
db 0x22
db 0x21
db 0x21
db 0x21
db 0x21
db 0x20
; Animation table
TreasureChestBase_Table:
dw TreasureChestBaseClosed
dw TreasureChestBaseOpen
dw TreasureChestBaseOpen
dw TreasureChestBaseOpen
dw TreasureChestBaseOpen
dw TreasureChestBaseOpen
dw 0x0000
; Animation table
TreasureChestLid_Table:
dw TreasureChestLidClosed
dw TreasureChestLidOpening_1
dw TreasureChestLidOpening_2
dw TreasureChestLidOpening_3
dw TreasureChestLidOpening_4
dw TreasureChestLidOpening_5
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TreasureChestBaseClosed:
db 0x07
db 0xE8
db 0x00
db 0xF8
db 0xE0
db 0x18
db 0x00
db 0x00
db 0xC0
db 0xE8
db 0x00
db 0x00
db 0x40
db 0x18
db 0x00
db 0x08
db 0x20
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TreasureChestLidClosed:
db 0x0A
db 0x08
db 0x00
db 0x00
db 0xC0
db 0xF8
db 0xE0
db 0x00
db 0x40
db 0xF8
db 0x00
db 0x08
db 0x1F
db 0x07
db 0x00
db 0xF8
db 0xE0
db 0xF8
db 0x00
db 0x00
db 0xC1
db 0x08
db 0x00
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TreasureChestBaseOpen:
db 0x09
db 0xE8
db 0x00
db 0xF8
db 0xE0
db 0x18
db 0x00
db 0x00
db 0xC0
db 0xE8
db 0x00
db 0x00
db 0x40
db 0x18
db 0x00
db 0x08
db 0x20
db 0x00
db 0xC0
db 0xF8
db 0xE0
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TreasureChestLidOpening_1:
db 0x0B
db 0x09
db 0x02
db 0x08
db 0xE0
db 0xF7
db 0xFE
db 0x00
db 0xC0
db 0xF8
db 0x20
db 0x07
db 0x02
db 0xF9
db 0xFE
db 0x00
db 0x40
db 0x07
db 0xE0
db 0x09
db 0x02
db 0x00
db 0xC0
db 0xF7
db 0xFE
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TreasureChestLidOpening_2:
db 0x0E
db 0x09
db 0x04
db 0x10
db 0xE0
db 0xF8
db 0xFC
db 0x00
db 0xC0
db 0x07
db 0x04
db 0x00
db 0x40
db 0xF8
db 0xFC
db 0xF0
db 0x21
db 0x00
db 0xC0
db 0x10
db 0xDF
db 0x00
db 0x12
db 0xF8
db 0x12
db 0xF8
db 0xFD
db 0x08
db 0x03
db 0x00
db 0x29
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TreasureChestLidOpening_3:
db 0x0D
db 0x06
db 0x06
db 0x1A
db 0xE4
db 0xFA
db 0xFA
db 0x00
db 0xC0
db 0x06
db 0x06
db 0x00
db 0x40
db 0xFA
db 0xFA
db 0xE6
db 0x1C
db 0x07
db 0xF8
db 0x00
db 0xCF
db 0x12
db 0xEA
db 0x00
db 0xF4
db 0xE7
db 0x1C
db 0x06
db 0x06
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TreasureChestLidOpening_4:
db 0x0E
db 0x02
db 0x08
db 0x24
db 0xF6
db 0xFE
db 0xF8
db 0x00
db 0xC0
db 0x02
db 0x08
db 0x00
db 0x40
db 0xFE
db 0xF8
db 0xDC
db 0x0A
db 0x03
db 0xFF
db 0x00
db 0xCA
db 0xFE
db 0xF8
db 0x02
db 0x08
db 0x22
db 0xF5
db 0xFE
db 0xF8
db 0xDD
db 0x0B
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TreasureChestLidOpening_5:
db 0x0B
db 0xFE
db 0x08
db 0x24
db 0x08
db 0x02
db 0xF8
db 0x00
db 0xC0
db 0xDD
db 0xF8
db 0x00
db 0x08
db 0x20
db 0x08
db 0x02
db 0xF8
db 0xFE
db 0x08
db 0x00
db 0x38
db 0x02
db 0x00
db 0xDC
db 0xF7
; Animation table
PlayerWalking_RightSide_Table:
dw PlayerStandingStillRightSide
dw PlayerWalkingRightSide2
dw PlayerWalkingRightSide3
dw PlayerWalkingRightSide2
dw PlayerWalkingRightSide3
dw 0x0000
; Animation table
PlayerWalking_LeftSide_Table:
dw PlayerStandingStillLeftSide
dw PlayerWalkingLeftSide2
dw PlayerWalkingLeftSide3
dw PlayerWalkingLeftSide2
dw PlayerWalkingLeftSide3
; Table controlling whether the image is flipped or not.
;
; 0x00 => don't flip
; 0xFF => flip
PlayerWalkingImageControlTable:
db 0x00
db 0x00
db 0x00
db 0xFF
db 0xFF
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerStandingStillRightSide:
db 0x14
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0xFE
db 0x0C
db 0xD4
db 0xFE
db 0xFE
db 0xFC
db 0x06
db 0x02
db 0xFE
db 0xFC
db 0x02
db 0x00
db 0x04
db 0x04
db 0x1E
db 0xFC
db 0xF4
db 0xFC
db 0xF0
db 0x04
db 0xD0
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0x04
db 0xF8
db 0xFC
db 0x00
db 0xFC
db 0x32
db 0xFA
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerStandingStillLeftSide:
db 0x1A
db 0x14
db 0x01
db 0x00
db 0xFE
db 0xE6
db 0x00
db 0x04
db 0xF5
db 0x0C
db 0x00
db 0x08
db 0x0C
db 0xF8
db 0x0C
db 0xF4
db 0x00
db 0xFB
db 0xF4
db 0x02
db 0xFA
db 0xF8
db 0xFE
db 0xFE
db 0xF4
db 0xD4
db 0x02
db 0xFE
db 0x04
db 0x06
db 0xFE
db 0xFE
db 0x04
db 0x02
db 0x00
db 0x04
db 0xFC
db 0x1E
db 0x04
db 0xF4
db 0x04
db 0xF0
db 0xFC
db 0xD0
db 0x02
db 0x04
db 0x00
db 0xFE
db 0xFC
db 0xF8
db 0x04
db 0x00
db 0x04
db 0x33
db 0x05
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerWalkingRightSide2:
db 0x1A
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0xFE
db 0x0C
db 0xD4
db 0xFE
db 0xFE
db 0xFC
db 0x06
db 0x02
db 0xFE
db 0xFC
db 0x02
db 0x00
db 0x04
db 0x04
db 0x1E
db 0xFC
db 0xF4
db 0xFC
db 0xDC
db 0x08
db 0xF4
db 0xFA
db 0x02
db 0xFE
db 0x00
db 0xFE
db 0xFE
db 0xFE
db 0xF6
db 0x02
db 0x00
db 0x06
db 0x0A
db 0xFE
db 0x02
db 0xFE
db 0x00
db 0xFE
db 0xFE
db 0xFE
db 0x0C
db 0x04
db 0x0F
db 0xF9
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerWalkingLeftSide2:
db 0x1C
db 0x14
db 0x01
db 0x00
db 0xFE
db 0xE6
db 0x00
db 0x04
db 0xF5
db 0x0C
db 0x00
db 0x08
db 0x0C
db 0xF8
db 0x0C
db 0xF4
db 0x00
db 0xFB
db 0xF4
db 0x02
db 0xFA
db 0xF8
db 0xFE
db 0xFC
db 0xF4
db 0xE6
db 0x00
db 0xF6
db 0x04
db 0xF8
db 0x02
db 0x06
db 0x00
db 0xFE
db 0x02
db 0x02
db 0x00
db 0x02
db 0xFE
db 0x0C
db 0xFE
db 0x14
db 0x04
db 0xF4
db 0x04
db 0xF0
db 0xFC
db 0xD0
db 0x02
db 0x04
db 0x00
db 0xFE
db 0xFC
db 0xF8
db 0x04
db 0x00
db 0x04
db 0x32
db 0x05
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerWalkingRightSide3:
db 0x17
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0xFE
db 0x0C
db 0xD4
db 0xFE
db 0xFE
db 0xFC
db 0x06
db 0x02
db 0xFE
db 0xFC
db 0x02
db 0x00
db 0x04
db 0x04
db 0x1E
db 0xFC
db 0xF4
db 0xFC
db 0xF0
db 0x04
db 0xEC
db 0x00
db 0xF2
db 0xFE
db 0x02
db 0x00
db 0x02
db 0x06
db 0xFC
db 0x00
db 0xFC
db 0xFA
db 0x00
db 0xFC
db 0x14
db 0x00
db 0x0E
db 0xFA
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerWalkingLeftSide3:
db 0x18
db 0x14
db 0x01
db 0x00
db 0xFE
db 0xE6
db 0x00
db 0x04
db 0xF5
db 0x0C
db 0x00
db 0x08
db 0x0C
db 0xF8
db 0x0C
db 0xF4
db 0x00
db 0xFB
db 0xF4
db 0x02
db 0xFA
db 0xF8
db 0xFE
db 0xFC
db 0xF4
db 0xE4
db 0x02
db 0x02
db 0x08
db 0x03
db 0x01
db 0x00
db 0xFC
db 0x12
db 0x01
db 0xF4
db 0x04
db 0xF0
db 0xFC
db 0xD0
db 0x02
db 0x04
db 0x00
db 0xFE
db 0xFC
db 0xF8
db 0x04
db 0x00
db 0x04
db 0x33
db 0x05
; Vector list:
;
; 0 => each point has its own drawing mode flag
; list of (mode,y,x) triplets, where mode is:
;
; 0x00 => move to next point
; 0xFF => draw to next point
; 0x01 => end of list
BrigandWalls:
db 0x00
db 0x00
db 0x38
db 0xC4
db 0xFF
db 0x00
db 0x10
db 0xFF
db 0xA0
db 0x00
db 0xFF
db 0x00
db 0xF0
db 0x00
db 0x08
db 0x10
db 0xFF
db 0x00
db 0x0C
db 0xFF
db 0x50
db 0x00
db 0xFF
db 0x00
db 0xF4
db 0x00
db 0xFA
db 0x0C
db 0xFF
db 0x00
db 0x08
db 0xFF
db 0xBC
db 0x00
db 0xFF
db 0x00
db 0xF8
db 0x00
db 0x04
db 0x08
db 0xFF
db 0x00
db 0x06
db 0xFF
db 0x3A
db 0x00
db 0xFF
db 0x00
db 0xFA
db 0x01
; Animation table
PlyrSideStepping_RightSide_Tbl:
dw PlayerStandingStillRightSide
dw PlayerWalkingRightSide3
dw PlayerWalkingRightSide3
dw 0x0000
; Animation table
PlyrSideStepping_LeftSide_Tbl:
dw PlayerStandingStillLeftSide
dw PlayerWalkingLeftSide3
dw PlayerWalkingLeftSide3
; When the player is side-stepping, this table controls
; when the image is flipped during drawing.
ImageFlip_Table:
db 0x00
db 0x00
db 0xFF
; Animation table
PlayerThrowing_RightSide_Table:
dw PlayerStandingStillRightSide
dw PlayerThrowing_RightSide1
dw PlayerThrowing_RightSide2
dw PlayerThrowing_RightSide3
dw PlayerThrowing_RightSide2
dw PlayerThrowing_RightSide4
dw PlayerThrowing_RightSide5
dw PlayerThrowing_RightSide5
dw PlayerThrowing_RightSide5
dw PlayerThrowing_RightSide5
dw PlayerThrowing_RightSide6
dw 0x0000
; The player's animation index is used to index into this
; table. If the value is '1', then the player is ready
; to thrown the flamoid.
PlayerFireSynchronization:
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x01
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerThrowing_RightSide1:
db 0x18
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0xFE
db 0x0C
db 0xEE
db 0x08
db 0xFA
db 0x05
db 0x00
db 0x04
db 0xFE
db 0x01
db 0x00
db 0xFD
db 0xFC
db 0x04
db 0xFC
db 0x00
db 0x00
db 0xFA
db 0x06
db 0xFE
db 0x08
db 0xF4
db 0x0D
db 0xFA
db 0xF4
db 0xFC
db 0xF0
db 0x04
db 0xD0
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0x04
db 0xF8
db 0xFC
db 0x00
db 0xFC
db 0x32
db 0xFA
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerThrowing_RightSide3:
db 0x18
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0xFC
db 0x0C
db 0x06
db 0xFE
db 0xFC
db 0xFC
db 0x02
db 0xFF
db 0x04
db 0x02
db 0x02
db 0xFA
db 0x06
db 0x02
db 0x00
db 0x06
db 0xFE
db 0x04
db 0xF0
db 0x06
db 0xFA
db 0x00
db 0x04
db 0xF2
db 0xF4
db 0xFC
db 0xF0
db 0x04
db 0xD0
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0x04
db 0xF8
db 0xFC
db 0x00
db 0xFC
db 0x32
db 0xFA
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerThrowing_RightSide2:
db 0x18
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0xFE
db 0x08
db 0xFC
db 0x08
db 0x0A
db 0x08
db 0x02
db 0xFE
db 0x02
db 0x02
db 0xFF
db 0x01
db 0x03
db 0x01
db 0xFE
db 0x04
db 0xFC
db 0x00
db 0xFE
db 0xFC
db 0xF0
db 0xFC
db 0x04
db 0xF0
db 0xF6
db 0xFA
db 0xF0
db 0x04
db 0xD0
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0x04
db 0xF8
db 0xFC
db 0x00
db 0xFC
db 0x32
db 0xFA
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerThrowing_RightSide4:
db 0x17
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0xFE
db 0x08
db 0xFA
db 0x06
db 0x04
db 0x0A
db 0x02
db 0x01
db 0x00
db 0x01
db 0xFF
db 0x00
db 0x03
db 0x03
db 0xFC
db 0x00
db 0xFE
db 0xFC
db 0xF8
db 0xF8
db 0x02
db 0xF4
db 0xF8
db 0xFB
db 0xF0
db 0x04
db 0xD0
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0x04
db 0xF8
db 0xFC
db 0x00
db 0xFC
db 0x32
db 0xFA
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerThrowing_RightSide5:
db 0x15
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0x00
db 0x06
db 0xFE
db 0x04
db 0x02
db 0x04
db 0x02
db 0xFE
db 0x00
db 0x01
db 0x04
db 0xFF
db 0xFE
db 0x04
db 0xF8
db 0x00
db 0xFA
db 0xF2
db 0xF6
db 0xFF
db 0xF0
db 0x04
db 0xD0
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0x04
db 0xF8
db 0xFC
db 0x00
db 0xFC
db 0x32
db 0xFA
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PlayerThrowing_RightSide6:
db 0x17
db 0x14
db 0xFF
db 0x00
db 0x02
db 0xE6
db 0x00
db 0x02
db 0x05
db 0xF8
db 0x01
db 0xFE
db 0x0C
db 0xEC
db 0x04
db 0xF8
db 0xFE
db 0xFA
db 0x00
db 0xFE
db 0xFC
db 0x06
db 0xFE
db 0xFE
db 0xFE
db 0x01
db 0xFF
db 0x03
db 0x03
db 0x08
db 0x02
db 0x0E
db 0xFB
db 0xF4
db 0xFC
db 0xF0
db 0x04
db 0xD0
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0x04
db 0xF8
db 0xFC
db 0x00
db 0xFC
db 0x32
db 0xFA
; Vector list:
;
; ((count - 1) | 0x80) => Move to first point
; list of (y,x) pairs.
PlayerExploding_Head:
db 0x8F
db 0x18
db 0x00
db 0x14
db 0x01
db 0x00
db 0xFE
db 0xE6
db 0x00
db 0x04
db 0xF5
db 0x0C
db 0x00
db 0x08
db 0x0C
db 0xF8
db 0x0C
db 0xF4
db 0x00
db 0xFB
db 0xF4
db 0x02
db 0xFA
db 0xF8
db 0xFE
db 0x08
db 0x02
db 0xFE
db 0x06
db 0x02
db 0x06
db 0xF8
db 0x02
; Vector list:
;
; ((count - 1) | 0x80) => Move to first point
; list of (y,x) pairs.
PlayerExploding_LeftArm:
db 0x89
db 0x0C
db 0xF8
db 0xFE
db 0xF4
db 0xD4
db 0x02
db 0xFE
db 0x04
db 0x06
db 0xFE
db 0xFE
db 0x04
db 0x02
db 0x00
db 0x04
db 0xFC
db 0x1E
db 0x04
db 0xF4
db 0x04
; Vector list:
;
; ((count - 1) | 0x80) => Move to first point
; list of (y,x) pairs.
PlayerExploding_RightArm:
db 0x8D
db 0x0C
db 0x08
db 0xFE
db 0x08
db 0xFC
db 0x08
db 0x0A
db 0x08
db 0x02
db 0xFE
db 0x02
db 0x02
db 0xFF
db 0x01
db 0x03
db 0x01
db 0xFE
db 0x04
db 0xFC
db 0x00
db 0xFE
db 0xFC
db 0xF0
db 0xFC
db 0x04
db 0xF0
db 0xF6
db 0xFA
; Vector list:
;
; ((count - 1) | 0x80) => Move to first point
; list of (y,x) pairs.
PlayerExploding_Body:
db 0x8E
db 0xF8
db 0xFA
db 0xF0
db 0xFC
db 0xD0
db 0x02
db 0x04
db 0x00
db 0xFE
db 0xFC
db 0xF8
db 0x04
db 0x00
db 0x04
db 0x33
db 0x05
db 0xCD
db 0x05
db 0x00
db 0x04
db 0x08
db 0x04
db 0x02
db 0xFC
db 0xFC
db 0x00
db 0x30
db 0x02
db 0x10
db 0xFC
; Animation table
BrigandArmAndBodyTable:
dw 0xFFFF
dw BrigandArmAndBody_1
dw BrigandArmAndBody_1
dw BrigandArmAndBody_2
dw BrigandArmAndBody_2
dw BrigandArmAndBody_2
dw BrigandArmAndBody_1
dw BrigandArmAndBody_1
dw BrigandArmAndBody_2
dw BrigandArmAndBody_3
dw BrigandArmAndBody_3
dw BrigandArmAndBody_3
dw BrigandArmAndBody_3
dw BrigandArmAndBody_3
dw BrigandArmAndBody_3
dw BrigandArmAndBody_3
dw BrigandArmAndBody_4
dw BrigandArmAndBody_5
dw BrigandArmAndBody_6
dw BrigandArmAndBody_6
dw BrigandArmAndBody_5
dw 0x0000
; Animation table
BrigandHeadTable:
dw 0xFFFF
dw 0xFFFF
dw 0xFFFF
dw BrigandHead_1
dw BrigandHead_1
dw BrigandHead_1
dw 0xFFFF
dw 0xFFFF
dw BrigandHead_1
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw BrigandHead_2
dw 0xFFFF
; As the brigand is animating, there reaches a point where
; it it time to throw a flamoid. The animation index is
; used to index into this table when a non-zero value is
; obtained, a flamoid will be thrown.
FlamoidControlTable:
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x01
db 0x00
db 0x00
db 0x00
db 0x00
; The brigand is only vulnerable to a hit from the player's
; flamoid when he (the brigand) is fully exposed. The
; table below indicates at what point during the animation
; the brigand is exposed. The brigand's animation index
; is used to index into this array. If the array value
; is '1', then the brigand is vulnerable.
BrigandIsVulnerable:
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x00
db 0x01
db 0x01
db 0x01
db 0x01
db 0x01
db 0x01
db 0x01
db 0x01
db 0x01
db 0x01
db 0x01
db 0x01
db 0x00
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BrigandArmAndBody_1:
db 0x11
db 0x4D
db 0x00
db 0x05
db 0xE6
db 0x2C
db 0x00
db 0x04
db 0x08
db 0xFC
db 0x04
db 0xFB
db 0xFF
db 0xFC
db 0xFD
db 0xEC
db 0x06
db 0x00
db 0x0C
db 0x1F
db 0x00
db 0x04
db 0xF1
db 0x10
db 0x0F
db 0x02
db 0x00
db 0x02
db 0xF8
db 0x06
db 0x08
db 0xEF
db 0x00
db 0xFA
db 0xFC
db 0x00
db 0x04
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BrigandArmAndBody_2:
db 0x0D
db 0x37
db 0x00
db 0x12
db 0xE8
db 0xFD
db 0xDD
db 0x1A
db 0x01
db 0x06
db 0x04
db 0xFE
db 0x04
db 0xFC
db 0x01
db 0xFC
db 0xFD
db 0xFB
db 0x02
db 0x0F
db 0x1C
db 0xFC
db 0x0F
db 0xF0
db 0xFB
db 0xFA
db 0x0A
db 0x01
db 0x02
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BrigandHead_1:
db 0x16
db 0x54
db 0x00
db 0x04
db 0xFC
db 0xF8
db 0x01
db 0x04
db 0xFB
db 0x0C
db 0x04
db 0xFC
db 0x04
db 0x2D
db 0x00
db 0xFC
db 0xFB
db 0x02
db 0xF7
db 0xF0
db 0xE6
db 0x13
db 0x03
db 0xFB
db 0xF2
db 0x0C
db 0x06
db 0xF4
db 0xFA
db 0x02
db 0x0A
db 0xE9
db 0xF9
db 0x06
db 0x1F
db 0xF7
db 0xFE
db 0xFD
db 0x0A
db 0x06
db 0x03
db 0x04
db 0xFA
db 0xF9
db 0xF9
db 0xF5
db 0x0B
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BrigandArmAndBody_3:
db 0x1B
db 0x15
db 0x00
db 0x0F
db 0xF2
db 0x1E
db 0xD9
db 0xF6
db 0xDD
db 0x20
db 0xF1
db 0x07
db 0x05
db 0xFE
db 0x06
db 0xFC
db 0x01
db 0xFB
db 0xFF
db 0xF8
db 0x0A
db 0x12
db 0x19
db 0x00
db 0x0F
db 0xEF
db 0x00
db 0xFC
db 0x08
db 0x04
db 0x08
db 0x0D
db 0x01
db 0xFA
db 0x03
db 0x06
db 0x04
db 0x07
db 0xF4
db 0xF6
db 0xFF
db 0x05
db 0xF7
db 0xF3
db 0xFF
db 0xFE
db 0x06
db 0x07
db 0xFD
db 0xF9
db 0x0C
db 0x03
db 0x07
db 0x0B
db 0x03
db 0x0A
db 0xF5
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BrigandHead_2:
db 0x20
db 0x70
db 0x00
db 0x00
db 0xF8
db 0xF6
db 0xEF
db 0x0F
db 0x01
db 0x01
db 0xF5
db 0xF9
db 0xFE
db 0xFD
db 0x07
db 0x09
db 0x06
db 0x06
db 0xF8
db 0x0E
db 0x1D
db 0x0E
db 0xEC
db 0x05
db 0x0A
db 0x06
db 0xF2
db 0xFA
db 0x0E
db 0xFB
db 0xF1
db 0xF3
db 0x0E
db 0xFD
db 0xE2
db 0xF9
db 0xFB
db 0x00
db 0xF7
db 0xEA
db 0xEC
db 0x13
db 0xFE
db 0xF8
db 0xF3
db 0x0D
db 0x04
db 0xF3
db 0xFC
db 0x04
db 0x09
db 0xE8
db 0x00
db 0x0E
db 0x1D
db 0xF7
db 0xFF
db 0xFF
db 0x0B
db 0x07
db 0x02
db 0x02
db 0xF9
db 0xF8
db 0xFA
db 0xF8
db 0x0E
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BrigandArmAndBody_4:
db 0x1B
db 0x15
db 0x00
db 0x0F
db 0xF3
db 0x1B
db 0xD5
db 0xF1
db 0xEC
db 0x13
db 0xE7
db 0xFE
db 0xF4
db 0x07
db 0xFA
db 0x0B
db 0x08
db 0xFB
db 0x07
db 0xF5
db 0x1B
db 0x14
db 0x0F
db 0x07
db 0x15
db 0xEF
db 0x00
db 0xFC
db 0x08
db 0x04
db 0x08
db 0x0D
db 0x01
db 0xFA
db 0x03
db 0x06
db 0x04
db 0x07
db 0xF4
db 0xF6
db 0xFF
db 0x05
db 0xF7
db 0xF3
db 0xFF
db 0xFE
db 0x06
db 0x07
db 0xFD
db 0xF9
db 0x0C
db 0x03
db 0x07
db 0x0B
db 0x03
db 0x0A
db 0xF5
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BrigandArmAndBody_5:
db 0x1D
db 0x15
db 0x00
db 0x0F
db 0xF3
db 0x1A
db 0xE4
db 0x06
db 0xF1
db 0xFB
db 0xF0
db 0xF1
db 0x09
db 0xFC
db 0xFD
db 0x07
db 0xFA
db 0xEF
db 0xF8
db 0xFC
db 0xF7
db 0x11
db 0xFB
db 0x12
db 0x0B
db 0x10
db 0x0E
db 0x0D
db 0x1C
db 0xEF
db 0x00
db 0xFC
db 0x08
db 0x04
db 0x08
db 0x0D
db 0x01
db 0xFA
db 0x03
db 0x06
db 0x04
db 0x07
db 0xF4
db 0xF6
db 0xFF
db 0x05
db 0xF7
db 0xF3
db 0xFF
db 0xFE
db 0x06
db 0x07
db 0xFD
db 0xF9
db 0x0C
db 0x03
db 0x07
db 0x0B
db 0x03
db 0x0A
db 0xF5
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BrigandArmAndBody_6:
db 0x1E
db 0x15
db 0x00
db 0x0F
db 0xF3
db 0x17
db 0xDF
db 0xF8
db 0xF0
db 0xED
db 0x02
db 0xFC
db 0x09
db 0xFD
db 0x00
db 0xFF
db 0xFD
db 0xFB
db 0x06
db 0xF8
db 0xFF
db 0xFF
db 0xF5
db 0x0F
db 0xF7
db 0x19
db 0xF5
db 0x19
db 0x0E
db 0x13
db 0x19
db 0xEF
db 0x00
db 0xFC
db 0x08
db 0x04
db 0x08
db 0x0D
db 0x01
db 0xFA
db 0x03
db 0x06
db 0x04
db 0x07
db 0xF4
db 0xF6
db 0xFF
db 0x05
db 0xF7
db 0xF3
db 0xFF
db 0xFE
db 0x06
db 0x07
db 0xFD
db 0xF9
db 0x0C
db 0x03
db 0x07
db 0x0B
db 0x03
db 0x0A
db 0xF5
; Vector list:
;
; ((count - 1) | 0x80) => Move to first point
; list of (y,x) pairs.
BrigandExploding_RightArm:
db 0x8B
db 0xE4
db 0x00
db 0x0F
db 0xF2
db 0x1E
db 0xD9
db 0xF6
db 0xDD
db 0x20
db 0xF1
db 0x07
db 0x05
db 0xFE
db 0x06
db 0xFC
db 0x01
db 0xFB
db 0xFF
db 0xF8
db 0x0A
db 0x12
db 0x19
db 0x00
db 0x0F
; Vector list:
;
; ((count - 1) | 0x80) => Move to first point
; list of (y,x) pairs.
BrigandExploding_LeftArm:
db 0x8D
db 0xE4
db 0x00
db 0x0F
db 0x0D
db 0x1A
db 0x1C
db 0x06
db 0x0F
db 0xFB
db 0x10
db 0xF1
db 0xF7
db 0xFC
db 0x03
db 0x07
db 0x06
db 0xEF
db 0x08
db 0xFC
db 0x09
db 0x11
db 0x05
db 0x12
db 0xF5
db 0x10
db 0xF2
db 0x0D
db 0xE4
; Vector list:
;
; ((count - 1) | 0x80) => Move to first point
; list of (y,x) pairs.
BrigandExploding_Head:
db 0x9B
db 0x36
db 0xE6
db 0x0F
db 0x01
db 0x06
db 0xF8
db 0x0E
db 0x1D
db 0x0E
db 0xEC
db 0x05
db 0x0A
db 0x06
db 0xF2
db 0xFA
db 0x0E
db 0xFB
db 0xF1
db 0xF3
db 0x0E
db 0xFD
db 0xE2
db 0xF9
db 0xFB
db 0x00
db 0xF7
db 0xEA
db 0xEC
db 0x13
db 0xFE
db 0xF8
db 0xF3
db 0x0D
db 0x04
db 0xF3
db 0xFC
db 0x04
db 0x09
db 0xE8
db 0x00
db 0x0E
db 0x1D
db 0xF7
db 0xFF
db 0xF8
db 0x0E
db 0xEF
db 0x00
db 0xFC
db 0x08
db 0x07
db 0x0E
db 0x0B
db 0x03
db 0x0A
db 0xF5
; Animation table
MagicianRightSide_Table:
dw MagicianRightSide1
dw MagicianRightSide1
dw MagicianRightSide1
dw MagicianRightSide2
dw MagicianRightSide3
dw MagicianRightSide4
dw MagicianRightSide3
dw MagicianRightSide4
dw MagicianRightSide5
dw MagicianRightSide4
dw MagicianRightSide4
dw 0x0000
; Animation table
MagicianLeftSide_Table:
dw MagicianLeftSide1
dw MagicianLeftSide1
dw MagicianLeftSide1
dw MagicianLeftSide2
dw MagicianLeftSide3
dw MagicianLeftSide4
dw MagicianLeftSide3
dw MagicianLeftSide4
dw MagicianLeftSide5
dw MagicianLeftSide4
dw MagicianLeftSide4
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianRightSide1:
db 0x21
db 0xFF
db 0x02
db 0x04
db 0x02
db 0xFE
db 0xFC
db 0x02
db 0xFC
db 0xFC
db 0x02
db 0x08
db 0xF8
db 0x06
db 0x04
db 0xFC
db 0x02
db 0x02
db 0x02
db 0x02
db 0xFC
db 0x00
db 0xFA
db 0xFC
db 0xFF
db 0x06
db 0xFF
db 0x02
db 0x08
db 0x02
db 0x02
db 0x00
db 0x08
db 0xFE
db 0x02
db 0xFE
db 0x08
db 0xFA
db 0xFF
db 0x04
db 0xFF
db 0x00
db 0xFA
db 0xFA
db 0x04
db 0xFE
db 0xFE
db 0xFC
db 0x08
db 0xE8
db 0x04
db 0xF2
db 0xFA
db 0x18
db 0xFC
db 0xDA
db 0x06
db 0xF8
db 0xF6
db 0x06
db 0xFC
db 0xF6
db 0xF8
db 0x04
db 0x04
db 0xFC
db 0x0E
db 0x0A
db 0x02
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianLeftSide1:
db 0x17
db 0xFF
db 0xFE
db 0x08
db 0xF8
db 0x06
db 0x04
db 0x02
db 0x04
db 0xFC
db 0x02
db 0x04
db 0x02
db 0xFE
db 0x04
db 0xFC
db 0xFE
db 0x02
db 0xFE
db 0x02
db 0x04
db 0xFA
db 0x04
db 0xF8
db 0xF8
db 0x01
db 0xFE
db 0xFF
db 0xFE
db 0x06
db 0xFA
db 0xFC
db 0xF8
db 0xE8
db 0xFC
db 0xF2
db 0x06
db 0x18
db 0x04
db 0xDA
db 0xFA
db 0xF4
db 0x0A
db 0x04
db 0xFC
db 0xFC
db 0xFC
db 0x09
db 0xFF
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianRightSide2:
db 0x26
db 0xFF
db 0x02
db 0x04
db 0x02
db 0xFE
db 0xFC
db 0x02
db 0xFC
db 0xFC
db 0x02
db 0x08
db 0xF8
db 0x06
db 0x04
db 0xFC
db 0x02
db 0x02
db 0x02
db 0x02
db 0xFC
db 0x00
db 0xFA
db 0xFC
db 0xFF
db 0x06
db 0xFF
db 0x02
db 0x08
db 0x02
db 0x02
db 0x00
db 0x08
db 0xFE
db 0x02
db 0xFE
db 0x08
db 0xFA
db 0xFF
db 0x04
db 0xFF
db 0x00
db 0xFA
db 0xFA
db 0x04
db 0xFE
db 0xFE
db 0xFC
db 0x08
db 0xEE
db 0x10
db 0xFA
db 0x04
db 0x04
db 0xFA
db 0xFE
db 0x00
db 0x02
db 0xFE
db 0x02
db 0x04
db 0xF4
db 0xF2
db 0x10
db 0xF8
db 0xDA
db 0x06
db 0xF8
db 0xF6
db 0x06
db 0xFC
db 0xF6
db 0xF8
db 0x04
db 0x04
db 0xFC
db 0x0E
db 0x0A
db 0x02
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianLeftSide2:
db 0x1C
db 0xFF
db 0xFE
db 0x08
db 0xF8
db 0x06
db 0x04
db 0x02
db 0x04
db 0xFC
db 0x02
db 0x04
db 0x02
db 0xFE
db 0x04
db 0xFC
db 0xFE
db 0x02
db 0xFE
db 0x02
db 0x04
db 0xFA
db 0x04
db 0xF8
db 0xF8
db 0x01
db 0xFE
db 0xFF
db 0xFE
db 0x06
db 0xFA
db 0xFC
db 0xF8
db 0xEE
db 0xF0
db 0xFA
db 0xFC
db 0x04
db 0x06
db 0xFE
db 0x00
db 0x02
db 0x02
db 0x02
db 0xFC
db 0xF4
db 0x0E
db 0x10
db 0x08
db 0xDA
db 0xFA
db 0xF4
db 0x0A
db 0x04
db 0xFC
db 0xFC
db 0xFC
db 0x09
db 0xFF
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianRightSide3:
db 0x2A
db 0xFF
db 0x02
db 0x04
db 0x02
db 0xFE
db 0xFC
db 0x02
db 0xFC
db 0xFC
db 0x02
db 0x08
db 0xF8
db 0x06
db 0x04
db 0xFC
db 0x02
db 0x02
db 0x02
db 0x02
db 0xFC
db 0x00
db 0xFA
db 0xFC
db 0xFF
db 0x06
db 0xFF
db 0x02
db 0x08
db 0x02
db 0x02
db 0x00
db 0x08
db 0xFE
db 0x02
db 0xFE
db 0x08
db 0xFA
db 0xFF
db 0x04
db 0xFF
db 0x00
db 0xFA
db 0xFA
db 0x04
db 0xFE
db 0xFE
db 0xFC
db 0x08
db 0xFA
db 0x02
db 0x04
db 0x0C
db 0xFC
db 0x02
db 0xFA
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0xFE
db 0x04
db 0x00
db 0xFE
db 0xFE
db 0x04
db 0x00
db 0xF4
db 0x00
db 0xF6
db 0xF8
db 0x0C
db 0xF6
db 0xDA
db 0x06
db 0xF8
db 0xF6
db 0x06
db 0xFC
db 0xF6
db 0xF8
db 0x04
db 0x04
db 0xFC
db 0x0E
db 0x0A
db 0x02
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianLeftSide3:
db 0x20
db 0xFF
db 0xFE
db 0x08
db 0xF8
db 0x06
db 0x04
db 0x02
db 0x04
db 0xFC
db 0x02
db 0x04
db 0x02
db 0xFE
db 0x04
db 0xFC
db 0xFE
db 0x02
db 0xFE
db 0x02
db 0x04
db 0xFA
db 0x04
db 0xF8
db 0xF8
db 0x01
db 0xFE
db 0xFF
db 0xFE
db 0x06
db 0xFA
db 0xFC
db 0xF8
db 0xFA
db 0xFE
db 0x04
db 0xF4
db 0xFC
db 0xFE
db 0xFA
db 0x02
db 0x04
db 0x00
db 0xFE
db 0x02
db 0x04
db 0x00
db 0xFE
db 0x02
db 0x04
db 0x00
db 0xF4
db 0x00
db 0xF6
db 0x08
db 0x0C
db 0x09
db 0xDA
db 0xFA
db 0xF4
db 0x0A
db 0x04
db 0xFC
db 0xFC
db 0xFC
db 0x09
db 0xFF
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianRightSide4:
db 0x2A
db 0xFF
db 0x02
db 0x04
db 0x02
db 0xFE
db 0xFC
db 0x02
db 0xFC
db 0xFC
db 0x02
db 0x08
db 0xF8
db 0x06
db 0x04
db 0xFC
db 0x02
db 0x02
db 0x02
db 0x02
db 0xFC
db 0x00
db 0xFA
db 0xFC
db 0xFF
db 0x06
db 0xFF
db 0x02
db 0x08
db 0x02
db 0x02
db 0x00
db 0x08
db 0xFE
db 0x02
db 0xFE
db 0x08
db 0xFA
db 0xFF
db 0x04
db 0xFF
db 0x00
db 0xFA
db 0xFA
db 0x04
db 0xFE
db 0xFE
db 0xFC
db 0x08
db 0xFA
db 0x02
db 0x0E
db 0x0E
db 0xFE
db 0x04
db 0xF8
db 0x02
db 0x06
db 0xFE
db 0xFC
db 0x00
db 0x04
db 0xFE
db 0xFA
db 0xFC
db 0x06
db 0x00
db 0xF4
db 0x00
db 0xEE
db 0xF6
db 0x0C
db 0xF7
db 0xDA
db 0x06
db 0xF8
db 0xF6
db 0x06
db 0xFC
db 0xF6
db 0xF8
db 0x04
db 0x04
db 0xFC
db 0x0E
db 0x0A
db 0x02
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianLeftSide4:
db 0x20
db 0xFF
db 0xFE
db 0x08
db 0xF8
db 0x06
db 0x04
db 0x02
db 0x04
db 0xFC
db 0x02
db 0x04
db 0x02
db 0xFE
db 0x04
db 0xFC
db 0xFE
db 0x02
db 0xFE
db 0x02
db 0x04
db 0xFA
db 0x04
db 0xF8
db 0xF8
db 0x01
db 0xFE
db 0xFF
db 0xFE
db 0x06
db 0xFA
db 0xFC
db 0xF8
db 0xFA
db 0xFE
db 0x0E
db 0xF2
db 0xFE
db 0xFC
db 0xF8
db 0xFE
db 0x06
db 0x02
db 0xFC
db 0x00
db 0x04
db 0x02
db 0xFA
db 0x04
db 0x06
db 0x00
db 0xF4
db 0x00
db 0xEE
db 0x0A
db 0x0C
db 0x09
db 0xDA
db 0xFA
db 0xF4
db 0x0A
db 0x04
db 0xFC
db 0xFC
db 0xFC
db 0x09
db 0xFF
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianRightSide5:
db 0x29
db 0xFF
db 0x02
db 0x04
db 0x02
db 0xFE
db 0xFC
db 0x02
db 0xFC
db 0xFC
db 0x02
db 0x08
db 0xF8
db 0x06
db 0x04
db 0xFC
db 0x02
db 0x02
db 0x02
db 0x02
db 0xFC
db 0x00
db 0xFA
db 0xFC
db 0xFF
db 0x06
db 0xFF
db 0x02
db 0x08
db 0x02
db 0x02
db 0x00
db 0x08
db 0xFE
db 0x02
db 0xFE
db 0x08
db 0xFA
db 0xFF
db 0x04
db 0xFF
db 0x00
db 0xFA
db 0xFA
db 0x04
db 0xFE
db 0xFE
db 0xFC
db 0x08
db 0xFA
db 0x02
db 0x0E
db 0x0E
db 0x04
db 0x00
db 0xFE
db 0x02
db 0x04
db 0x06
db 0xFA
db 0x00
db 0xF8
db 0xF4
db 0x04
db 0x00
db 0xF4
db 0x00
db 0xEE
db 0xF6
db 0x0C
db 0xF7
db 0xDA
db 0x06
db 0xF8
db 0xF6
db 0x06
db 0xFC
db 0xF6
db 0xF8
db 0x04
db 0x04
db 0xFC
db 0x0E
db 0x0A
db 0x02
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MagicianLeftSide5:
db 0x1F
db 0xFF
db 0xFE
db 0x08
db 0xF8
db 0x06
db 0x04
db 0x02
db 0x04
db 0xFC
db 0x02
db 0x04
db 0x02
db 0xFE
db 0x04
db 0xFC
db 0xFE
db 0x02
db 0xFE
db 0x02
db 0x04
db 0xFA
db 0x04
db 0xF8
db 0xF8
db 0x01
db 0xFE
db 0xFF
db 0xFE
db 0x06
db 0xFA
db 0xFC
db 0xF8
db 0xFA
db 0xFE
db 0x0E
db 0xF2
db 0x04
db 0x00
db 0xFE
db 0xFE
db 0x04
db 0xFA
db 0xFA
db 0x00
db 0xF8
db 0x0C
db 0x04
db 0x00
db 0xF4
db 0x00
db 0xEE
db 0x0A
db 0x0C
db 0x09
db 0xDA
db 0xFA
db 0xF4
db 0x0A
db 0x04
db 0xFC
db 0xFC
db 0xFC
db 0x09
db 0xFF
ObjectVectorTable:
dw DeadTree
dw PineTree
dw MapleTree
dw ElmTree
dw DeadTree
dw 0x00F0
dw 0x00F2
dw 0x00F4
dw 0x0080
dw 0x0082
dw 0x0084
dw 0x0086
dw 0x0088
dw 0x008A
dw 0x00E0
dw 0x00E2
; Vector list:
;
; count - 1
; list of (y,x) pairs.
DeadTree:
db 0x1C
db 0xF8
db 0x10
db 0x0C
db 0xFA
db 0x38
db 0x0C
db 0x18
db 0x20
db 0x18
db 0xF4
db 0x10
db 0x20
db 0xF8
db 0x10
db 0x08
db 0xF0
db 0x08
db 0x08
db 0xFC
db 0x08
db 0x04
db 0xF8
db 0xF8
db 0xF8
db 0xF2
db 0xD4
db 0xE8
db 0x08
db 0xF0
db 0xE0
db 0x20
db 0xE0
db 0x18
db 0x10
db 0x10
db 0xF0
db 0xF0
db 0x0C
db 0xE6
db 0xEC
db 0xF0
db 0x0C
db 0xF0
db 0xF0
db 0x08
db 0xF8
db 0xF8
db 0x08
db 0x0A
db 0x14
db 0xF0
db 0x0E
db 0xD0
db 0xF0
db 0xE0
db 0xE0
db 0x18
db 0x34
; Vector list:
;
; count - 1
; list of (y,x) pairs.
PineTree:
db 0x0A
db 0x23
db 0x00
db 0x00
db 0xDD
db 0x2D
db 0x0F
db 0x00
db 0xFB
db 0x37
db 0x0A
db 0x00
db 0xFB
db 0x64
db 0x14
db 0x83
db 0x19
db 0x00
db 0xF6
db 0xA6
db 0x14
db 0x00
db 0xDD
; Vector list:
;
; count - 1
; list of (y,x) pairs.
MapleTree:
db 0x15
db 0xF8
db 0x10
db 0x0C
db 0xFA
db 0x38
db 0x0C
db 0x10
db 0x16
db 0xE0
db 0x20
db 0x40
db 0x30
db 0x30
db 0x00
db 0x30
db 0xA0
db 0x00
db 0xC0
db 0xC0
db 0xD0
db 0xD0
db 0xF8
db 0xD0
db 0x30
db 0x2C
db 0x30
db 0xF4
db 0x26
db 0x05
db 0xF0
db 0xF4
db 0xEC
db 0x0A
db 0xF4
db 0xF8
db 0xF8
db 0xF8
db 0x0A
db 0xD0
db 0xF0
db 0xE0
db 0xE0
db 0x18
db 0x34
; Vector list:
;
; 0 => each point has its own drawing mode flag
; list of (mode,y,x) triplets, where mode is:
;
; 0x00 => move to next point
; 0xFF => draw to next point
; 0x01 => end of list
ElmTree:
db 0x00
db 0xFF
db 0x50
db 0x00
db 0xFF
db 0x4A
db 0x28
db 0x00
db 0xD8
db 0xE2
db 0xFF
db 0x1E
db 0xE2
db 0x00
db 0xBF
db 0x14
db 0xFF
db 0x00
db 0xDD
db 0x00
db 0x0F
db 0xF1
db 0xFF
db 0x50
db 0x0F
db 0x00
db 0x18
db 0xEC
db 0xFF
db 0x30
db 0x28
db 0xFF
db 0xF6
db 0x20
db 0x00
db 0xEA
db 0x20
db 0xFF
db 0xE8
db 0x1E
db 0xFF
db 0xE0
db 0xF6
db 0x00
db 0xE8
db 0xF1
db 0xFF
db 0xC8
db 0xC8
db 0x01
; Vector list:
;
; count - 1
; list of (y,x) pairs.
Flamoid:
db 0x08
db 0x02
db 0x00
db 0x03
db 0xFB
db 0xFB
db 0x03
db 0xFB
db 0xFD
db 0x03
db 0x05
db 0xFD
db 0x05
db 0x05
db 0xFD
db 0x05
db 0x03
db 0xFC
db 0xFA
; Vector list:
;
; count - 1
; list of (y,x) pairs.
DarkTowerRightHalf:
db 0x11
db 0xFC
db 0x06
db 0xEE
db 0x02
db 0x02
db 0x08
db 0x04
db 0x00
db 0x02
db 0x08
db 0xF8
db 0x10
db 0x08
db 0xF0
db 0xFF
db 0xFC
db 0x37
db 0xFA
db 0x06
db 0xF2
db 0xFA
db 0xF2
db 0x06
db 0xFE
db 0x0A
db 0x12
db 0xF6
db 0xFE
db 0xD2
db 0x00
db 0xFC
db 0x05
db 0xF0
db 0x01
db 0x00
db 0xF2
; Vector list:
;
; count - 1
; list of (y,x) pairs.
DarkTowerLeftHalf:
db 0x10
db 0xFC
db 0xFA
db 0xEE
db 0xFE
db 0x02
db 0xFA
db 0x0A
db 0xFC
db 0x04
db 0x02
db 0x02
db 0xFE
db 0xFC
db 0xFC
db 0xF8
db 0xFC
db 0xFC
db 0xF0
db 0x04
db 0x10
db 0x08
db 0x04
db 0x03
db 0x03
db 0x2D
db 0x05
db 0x06
db 0xFE
db 0x0A
db 0x12
db 0xF6
db 0x0E
db 0xFA
db 0xFE
; Vector list:
;
; count - 1
; list of (y,x) pairs.
TowerDoor:
db 0x08
db 0x4C
db 0x06
db 0x10
db 0x1C
db 0xF0
db 0x1E
db 0xB4
db 0x08
db 0x4C
db 0xF8
db 0x10
db 0xE2
db 0xF0
db 0x1A
db 0xB8
db 0x06
db 0x00
db 0xBE
; Vector list:
;
; 0 => each point has its own drawing mode flag
; list of (mode,y,x) triplets, where mode is:
;
; 0x00 => move to next point
; 0xFF => draw to next point
; 0x01 => end of list
KeyHole:
db 0x00
db 0xFF
db 0xFE
db 0xFE
db 0xFF
db 0xFE
db 0x01
db 0xFF
db 0xFC
db 0xFF
db 0xFF
db 0x00
db 0x04
db 0xFF
db 0x04
db 0xFF
db 0xFF
db 0x02
db 0x01
db 0xFF
db 0x02
db 0xFE
db 0x00
db 0x02
db 0xFE
db 0xFF
db 0xFE
db 0xFE
db 0xFF
db 0xF8
db 0x00
db 0xFF
db 0xFE
db 0x02
db 0xFF
db 0x00
db 0x04
db 0xFF
db 0x02
db 0x02
db 0xFF
db 0x08
db 0x00
db 0xFF
db 0x02
db 0xFE
db 0xFF
db 0x00
db 0xFC
db 0x01
; Vector list:
;
; count - 1
; list of (y,x) pairs.
Key:
db 0x12
db 0x00
db 0x14
db 0xFA
db 0x02
db 0x00
db 0x0C
db 0x08
db 0x04
db 0x08
db 0xFC
db 0x00
db 0xF4
db 0xFA
db 0xFE
db 0x00
db 0xDE
db 0xF8
db 0x00
db 0x00
db 0x02
db 0x04
db 0x00
db 0x00
db 0x04
db 0xFC
db 0x00
db 0x00
db 0x02
db 0x02
db 0x00
db 0x00
db 0x04
db 0xFE
db 0x00
db 0x00
db 0x02
db 0x04
db 0x00
; Vector list:
;
; count - 1
; list of (y,x) pairs.
Arrow:
db 0x06
db 0xD0
db 0x20
db 0x00
db 0xF0
db 0xE0
db 0x00
db 0x00
db 0xE0
db 0x20
db 0x00
db 0x00
db 0xF0
db 0x30
db 0x20
ArrowXpositions:
db 0xC1
db 0xEF
db 0x1C
db 0x4C
; Vector list:
;
; count - 1
; list of (y,x) pairs.
BagOfGold:
db 0x0E
db 0x0A
db 0xF6
db 0x0C
db 0x00
db 0x0E
db 0x0E
db 0x0A
db 0xF2
db 0xFE
db 0x0A
db 0x06
db 0x04
db 0xFC
db 0x06
db 0x06
db 0x0A
db 0xF0
db 0xFC
db 0x00
db 0xF4
db 0x00
db 0x0C
db 0xF2
db 0x12
db 0xF8
db 0x00
db 0xF2
db 0xF4
db 0x00
db 0xEA
CompassPointLabels:
dw NorthLabel
dw NorthWestLabel
dw WestLabel
dw SouthWestLabel
dw SouthLabel
dw SouthEastLabel
dw EastLabel
dw NorthEastLabel
NorthLabel:
db " N",0x80
NorthWestLabel:
db " NW",0x80
WestLabel:
db " W",0x80
SouthWestLabel:
db " SW",0x80
SouthLabel:
db " S",0x80
SouthEastLabel:
db " SE",0x80
EastLabel:
db " E",0x80
NorthEastLabel:
db " NE",0x80
; These are the default values for the brigand array, which
; occupies C9E0-C9F7 (6 entries, of 4 bytes each). The
; entries have the following meaning:
;
; ------------------------------
; byte 0 | 1 => animation complete |
; ------------------------------
; byte 1 | animation index |
; ------------------------------
; byte 2 | |
; -- Ptr to brigand specifics --
; byte 3 | |
; ------------------------------
;
BrigandDefaults:
db 0x01
db 0x00
dw Brigand1Data
db 0x01
db 0x00
dw Brigand2Data
db 0x01
db 0x00
dw Brigand3Data
db 0x01
db 0x00
dw Brigand4Data
db 0x01
db 0x00
dw Brigand5Data
db 0x01
db 0x00
dw Brigand6Data
; The following 6 data blocks represent the hard (fixed)
; data associated with the 6 possible brigands (3 on the
; left side, and 3 on the right side). Each entry is 17
; bytes long, and has the following meaning:
;
; ------------------------------
; byte 0 | Brigand's 16-bit Y |
; -- --
; byte 1 | Position |
; ------------------------------
; byte 2 | Brigand's 16-bit X |
; -- --
; byte 3 | Position |
; ------------------------------
; byte 4 | Flamoid's 16-bit Y |
; -- --
; byte 5 | Position |
; ------------------------------
; byte 6 | Flamoid's 16-bit X |
; -- --
; byte 7 | Position |
; ------------------------------
; byte 8 | ???? |
; ------------------------------
; byte 9 | ???? |
; ------------------------------
; byte A | ???? |
; ------------------------------
; byte B | ???? |
; ------------------------------
; byte C | ???? |
; ------------------------------
; byte D | Image Flip Flag |
; ------------------------------
; byte E | Scale factor |
; ------------------------------
; byte F | Target Size (height/2) |
; -- --
; byte 10 | Target Size (width/2) |
; ------------------------------
;
Brigand1Data:
db 0xD0
db 0x00
db 0x40
db 0x00
db 0x52
db 0x00
db 0x0C
db 0x00
db 0xF3
db 0x52
db 0x00
db 0x15
db 0x00
db 0x00
db 0x28
db 0x03
db 0x06
Brigand2Data:
db 0xDC
db 0x00
db 0x30
db 0x00
db 0x5E
db 0x00
db 0x08
db 0x00
db 0xF8
db 0x5E
db 0x00
db 0x12
db 0x00
db 0x00
db 0x20
db 0x03
db 0x06
Brigand3Data:
db 0xE2
db 0x00
db 0x26
db 0x00
db 0x66
db 0x00
db 0x05
db 0x00
db 0xF8
db 0x66
db 0x00
db 0x0E
db 0x00
db 0x00
db 0x18
db 0x03
db 0x06
Brigand4Data:
db 0xD0
db 0x00
db 0xC0
db 0x00
db 0x52
db 0x00
db 0xF5
db 0x00
db 0xF3
db 0x52
db 0x00
db 0xEC
db 0x00
db 0x01
db 0x28
db 0x03
db 0x06
Brigand5Data:
db 0xDC
db 0x00
db 0xD0
db 0x00
db 0x5E
db 0x00
db 0xF8
db 0x00
db 0xF8
db 0x5E
db 0x00
db 0xEE
db 0x00
db 0x01
db 0x20
db 0x03
db 0x06
Brigand6Data:
db 0xE2
db 0x00
db 0xDD
db 0x00
db 0x66
db 0x00
db 0xFB
db 0x00
db 0xF8
db 0x66
db 0x00
db 0xF1
db 0x00
db 0x01
db 0x18
db 0x03
db 0x06
StringHeightWidthTable:
db 0xFC
db 0x04
db 0xFC
db 0x06
db 0xFC
db 0x08
db 0xFB
db 0x0C
db 0xFB
db 0x0D
db 0xFA
db 0x0D
db 0xFA
db 0x10
db 0xF9
db 0x14
db 0xF8
db 0x15
db 0xF7
db 0x17
db 0xF6
db 0x18
db 0xF6
db 0x19
db 0xF6
db 0x1B
db 0xF5
db 0x1D
db 0xF5
db 0x1F
db 0xF4
db 0x21
db 0xF4
db 0x21
; Table of function pointers
dw AwardGoldKey
dw AwardSilverKey
dw AwardBronzeKey
dw AwardBrassKey
dw AwardBrassKey
dw AwardBronzeKey
dw AwardSilverKey
dw AwardGoldKey
; Table of function pointers
RandomAwardsTable1:
dw AwardBagsOfGold
dw AwardBagsOfGold
dw AwardBagsOfGold
dw AwardBagsOfGold
dw AwardNewWarrior
dw AwardBagsOfGold
dw AwardBagsOfGold
dw AwardNewWarrior
; Table of function pointers
RandomAwardsTable2:
dw AwardBagsOfGold
dw AwardBagsOfGold
dw AwardBagsOfGold
dw AwardNewWarrior
dw 0x0000
dw AwardBagsOfGold
dw AwardBagsOfGold
dw AwardBagsOfGold
InventoryLabel:
db "PLAYER INVENTORY",0x80
TableOfObjectsToFind:
dw BeGoneLabel
dw GoldKeyLabel
dw SilverKeyLabel
dw BronzeKeyLabel
dw BrassKeyLabel
dw CrystalCrownLabel
dw ScoutLabel
dw HealerLabel
dw 0xCB5D
dw 0xCB5D
; Pairs of (y,x) positions, used when displaying the
; above labels
ObjectPositionTable:
db 0x7F
db 0xF4
db 0x7F
db 0xF0
db 0x7F
db 0xEC
db 0x7F
db 0xEC
db 0x7F
db 0xEC
db 0x7F
db 0xE4
db 0x7F
db 0xF4
db 0x7F
db 0xF4
db 0x7F
db 0xE4
db 0x7F
db 0xE4
GoldKeyLabel:
db "GOLD KEY",0x80
SilverKeyLabel:
db "SILVER KEY",0x80
BronzeKeyLabel:
db "BRONZE KEY",0x80
BrassKeyLabel:
db "BRASS KEY",0x80
CrystalCrownLabel:
db "CRYSTAL CROWN",0x80
ScoutLabel:
db "SCOUT",0x80
HealerLabel:
db "HEALER",0x80
YourScoreIsLabel:
db "YOUR SCORE IS 0",0x80
BagsOfGoldLabel_2:
db " "
BagsOfGoldLabel:
db "2 BAGS OF GOLD",0x80
ReserveTroopsLabel:
db " 6 RESERVE TROOPS",0x80
NewWarriorLabel:
db "0 NEW WARRIOR",0x80
BeGoneLabel:
db "BE GONE",0x80
RiddleOfTheKeysLabel:
db 0xF8
db 0x34
db 0x78
db 0xC0
db "RIDDLE OF THE KEYS",0x80,0x00;
KeyNameLabelTable:
dw KeyLabel
dw GoldLabel
dw SilverLabel
dw BronzeLabel
dw BrassLabel
KeyLabel:
db "KEY ? ",0x80
GoldLabel:
db "GOLD ",0x80
SilverLabel:
db "SILVER",0x80
BronzeLabel:
db "BRONZE",0x80
BrassLabel:
db "BRASS ",0x80
EnterVictoriousWarriorLabel:
db 0xF8
db 0x40
db 0x38
db 0xE4
db "ENTER,",0x80
db 0xFA
db 0x40
db 0x18
db 0xD2
db "VICTORIOUS",0x80
db 0xFA
db 0x40
db 0x04
db 0xDE
db "WARRIOR",0x80,0x00
GameOverLabel:
db 0xFA
db 0x38
db 0xB0
db 0xD8
db "GAME OVER",0x80,0x00
YourFirstWarriorLabel:
db 0xFA
db 0x38
db 0x50
db 0xD8
db "YOUR FIRST",0x80
db 0xFA
db 0x38
db 0x40
db 0xE8
db "WARRIOR",0x80,0x00
ReplacementWarriorLabel:
db 0xFA
db 0x38
db 0x50
db 0xD8
db "REPLACEMENT",0x80
db 0xFA
db 0x38
db 0x40
db 0xE8
db "WARRIOR",0x80,0x00
db 0xBD
               (
geocities.com/fredtaft)