/* * 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