00001. ; Super Mario Bros. 3 Full Disassembly by Southbird 2012 00002. ; For more info, see http://www.sonicepoch.com/sm3mix/ 00003. ; 00004. ; PLEASE INCLUDE A CREDIT TO THE SOUTHBIRD DISASSEMBLY 00005. ; AND THE ABOVE LINK SOMEWHERE IN YOUR WORKS :) 00006. ; 00007. ; Original disassembler source generated by DCC6502 version v1.4 00008. ; (With labels, comments, and some syntax corrections for nesasm by Southbird) 00009. ; For more info about DCC6502, e-mail veilleux@ameth.org 00010. ; 00011. ; This source file last updated: 2012-01-29 13:49:44.499306754 -0600 00012. ; Distribution package date: Fri Apr 6 23:46:16 UTC 2012 00013. ;---------------------------------------------------------------------------  00014.    ; Indexed per top 2 bits of tile ($00, $40, $80, $C0)  00015.    ; Defines the shape of a slope tile for slope levels (Hills style and underground)  00016.    ; Values used for Player_Slopes:  00017.    ; 1) A tile is retrieved in Player_GetTileAndAttr  00018.    ; 2) Pick the proper table start by tile "quadrant" ($00, $40, $80, $C0)  00019.    ; 3) The relevant value from Tile_AttrTable (a series of values-per-quad  00020.    ; loaded by tileset) is grabbed; the tile retrieved in #1 is used as  00021.    ; a base value. Hills/Underground style attr table: $25, $5F, $99, $E2  00022.    ; 4) If the tile is beneath the base this data is not used  00023.    ; (e.g. using the above Hills example, if we got tile $16 -- this is  00024.    ; quad $00, and the quad $00 base tile is $25, so this is not valid)  00025.    ; 5) If tile is in range, it is subtracted, so using the Hills example:  00026.    ; Tile $25 -- first table, index 0. Tile $26 -- first table, index 1.  00027.    ; Tile $5F -- second table, index 0. Etc...  00028. Level_SlopeSetByQuad:  00029.    .word Level_SlopeQuad00 ; Tile quad $00  00030.    .word Level_SlopeQuad40 ; Tile quad $40  00031.    .word Level_SlopeQuad80 ; Tile quad $80  00032.    .word Level_SlopeQuadC0 ; Tile quad $C0  00033.   00034.    ; These tables are rooted by the base value for each tile quad by the only two  00035.    ; tilesets to support slopes, 3 (Hills) and 14 (Underground)  00036.    ; For reference, that attribute set is: $25, $5F, $99, $E2  00037.    ;  00038.    ; The value in the next four LUTs reference a "slope shape" as defined in the  00039.    ; Slope_LUT table that follows...  00040.   00041. Level_SlopeQuad00:  00042.    ; Tile $25+  00043.    .byte $01, $07, $02, $0C, $0D, $0E, $0F, $07, $03, $03, $03, $03, $03, $03, $07, $04  00044.    .byte $07, $04, $04, $03, $03, $03, $03, $03, $07, $04, $07, $04, $04, $04, $04, $04  00045.   00046. Level_SlopeQuad40:  00047.    ; Tile $5F+  00048.    .byte $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03  00049.    .byte $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03  00050.   00051. Level_SlopeQuad80:  00052.    ; Tile $99+  00053.    .byte $01, $07, $02, $0C, $0D, $0E, $0F, $05, $06, $11, $12, $13, $14, $08, $07, $04  00054.    .byte $07, $04, $04, $08, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03  00055.    .byte $03, $03, $03, $03, $03, $03, $08  00056.   00057. Level_SlopeQuadC0:  00058.    ; Tile $E2+  00059.    .byte $01, $07, $02, $0C, $0D, $0E, $0F, $05, $06, $11, $12, $13, $14, $07, $03, $03  00060.    .byte $03, $03, $08, $07, $04, $07, $04, $04, $08, $08, $04  00061.   00062. Slope_LUT:  00063.    ; Lower 4 bits are the ground slope height  00064.    ; Upper 4 bits are the ceiling slope height  00065.   00066.    ; 16 entries for each pixel across the 16x16 tile  00067.    ; <--- --- X --- -->  00068.    .byte $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10, $10 ; $00 (used as "no slope", i.e. BG tile)  00069.    .byte $0F, $0E, $0D, $0C, $0B, $0A, $09, $08, $07, $06, $05, $04, $03, $02, $01, $00 ; $01  00070.    .byte $00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $0B, $0C, $0D, $0E, $0F ; $02  00071.    .byte $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; $03 (all solid square tiles)  00072.    .byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $04 (wall, see PRG008_B9F4)  00073.    .byte $00, $10, $20, $30, $40, $50, $60, $70, $80, $90, $A0, $B0, $C0, $D0, $E0, $F0 ; $05  00074.    .byte $F0, $E0, $D0, $C0, $B0, $A0, $90, $80, $70, $60, $50, $40, $30, $20, $10, $00 ; $06  00075.    .byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $07 (unsloped ground, see PRG008_B9F4)  00076.    .byte $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; $08 (unsloped ceiling, see PRG008_B9F4)  00077.    .byte $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; $09  00078.    .byte $02, $02, $02, $02, $03, $03, $03, $03, $04, $04, $04, $04, $03, $03, $03, $02 ; $0A  00079.    .byte $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0, $F0 ; $0B  00080.    .byte $0F, $0E, $0E, $0D, $0D, $0D, $0C, $0C, $0B, $0B, $0A, $0A, $09, $09, $08, $08 ; $0C  00081.    .byte $07, $06, $06, $05, $05, $05, $04, $04, $03, $03, $02, $02, $01, $01, $00, $00 ; $0D  00082.    .byte $00, $00, $01, $01, $02, $02, $03, $03, $04, $04, $05, $05, $05, $06, $06, $07 ; $0E  00083.    .byte $08, $08, $09, $09, $0A, $0A, $0B, $0B, $0C, $0C, $0D, $0D, $0D, $0E, $0E, $0F ; $0F  00084.    .byte $0E, $0D, $0B, $0A, $09, $09, $08, $08, $08, $08, $08, $09, $09, $0A, $0B, $0D ; $10  00085.    .byte $00, $00, $10, $10, $20, $20, $30, $30, $40, $40, $50, $50, $50, $60, $60, $70 ; $11  00086.    .byte $80, $80, $90, $90, $A0, $A0, $B0, $B0, $C0, $C0, $D0, $D0, $D0, $E0, $E0, $F0 ; $12  00087.    .byte $F0, $E0, $E0, $D0, $D0, $D0, $C0, $C0, $B0, $B0, $A0, $A0, $90, $90, $80, $80 ; $13  00088.    .byte $70, $60, $60, $50, $50, $50, $40, $40, $30, $30, $20, $20, $10, $10, $00, $00 ; $14  00089.   00090.    ; Effect on Player's velocity per slope "shape" index (Slope_LUT above)  00091. Slope_PlayerVel_Effect:  00092.    .byte $00, -$03, $03, $00, $00, $00, $00, $00 ; $00-$07  00093.    .byte $00, $00, $00, $00, -$02, -$02, $02, $02 ; $08-$0F  00094.    .byte $00, $00, $00, $00, $00 ; $10-$14  00095.   00096.    ; Effect on Object's velocity per slope "shape" index (Slope_LUT above)  00097.    ; NOTE: Incomplete -- probably avoids concering with certain ceiling slopes  00098. Slope_ObjectVel_Effect:  00099.    ; $80 disables response to this slope  00100.    .byte $00, -$02, $02, $00, $00, $80, $80, $00 ; $00-$07  00101.    .byte $00, $80, $00, $80, -$01, -$01, $01, $01 ; $08-$0F  00102.    ; Incomplete, missing $10-$14  00103.    ; RAS: Slopes $10-$14 are ceiling slopes, which enemies have pretty much  00104.    ; no proper involvement with in native SMB3. Also due to a "lazy" calculation  00105.    ; found after the label PRG000_C5EC, these would be inaccessible anyway!  00106.   00107.   00108.    ; Default address for Level_GndLUT_L/H in a non-slope level; note that this  00109.    ; doesn't make sense (the address for Level_LayPtrOrig_AddrH would just give  00110.    ; you the original layout pointer, not slope data) so this is probably dead  00111.    ; code. Level_GndLUT_L/H isn't used in non-slope levels anyway...  00112. NonSlope_LUT_Addr: .word Level_LayPtrOrig_AddrH  00113.   00114.    ; Default address for Level_GndLUT_L/H in a sloped level  00115. Slope_LUT_Addr: .word Slope_LUT  00116.   00117.    ; This defines 4 values per Level_Tileset, with each of those values  00118.    ; belonging to a tile "quadrant" (i.e. tiles beginning at $00, $40,  00119.    ; $80, and $C0), and defines the beginning tile which should be  00120.    ; classified as "underwater" (Minimum Tile Under Water By Quad)  00121.    ; A value of $FF is used to indicate that no tile in that quadrant  00122.    ; is underwater (and for the first three quads is unreachable!)  00123. Level_MinTileUWByQuad:  00124.    ; 4 values per Level_TilesetIdx, which is basically (Level_Tileset - 1)  00125.    ; Listing by valid Level_Tileset values for consistency...  00126.    .byte $FF, $FF, $FF, $DA ; 1 Plains style  00127.    .byte $FF, $FF, $FF, $DA ; 2 Mini Fortress style  00128.    .byte $FF, $FF, $FF, $C1 ; 3 Hills style  00129.    .byte $FF, $FF, $FF, $DA ; 4 High-Up style  00130.    .byte $FF, $FF, $FF, $DA ; 5 pipe world plant infestation  00131.    .byte $02, $3F, $8A, $C0 ; 6 water world  00132.    .byte $FF, $FF, $FF, $DA ; 7 Toad House  00133.    .byte $FF, $FF, $8A, $DA ; 8 Vertical pipe maze  00134.    .byte $FF, $FF, $FF, $DA ; 9 desert levels  00135.    .byte $FF, $FF, $FF, $DA ; 10 Airship  00136.    .byte $FF, $FF, $FF, $DA ; 11 Giant World  00137.    .byte $FF, $FF, $FF, $DA ; 12 Ice level  00138.    .byte $FF, $FF, $FF, $DA ; 13 Sky level  00139.    .byte $FF, $FF, $FF, $C1 ; 14 Underground  00140.   00141.      00142. ToadItem_PalPerItem:  00143.    .byte $30 ; 0: INVALID  00144.    .byte $16 ; 1: Mushroom  00145.    .byte $2A ; 2: Fire flower  00146.    .byte $2A ; 3: Leaf  00147.    .byte $2A ; 4: Frog  00148.    .byte $17 ; 5: Tanooki  00149.    .byte $27 ; 6: Hammer  00150.    .byte $36 ; 7: Judgems  00151.    .byte $27 ; 8: P-Wing  00152.    .byte $30 ; 9: Star  00153.    .byte $07 ; A: Anchor  00154.    .byte $36 ; B: Hammer  00155.    .byte $27 ; C: Whistle  00156.    .byte $27 ; D: Music Box  00157.   00158.    ; Objects detect using a specific offset from this list  00159.    ; Which "group" they use is specified by the respective value in ObjectGroup_Attributes2  00160. Object_TileDetectOffsets:  00161.   00162.    ; Y/X offset pairs  00163.   00164.    ; For groups:  00165.    ; Row 1: Object Y Velocity >= 0 (on ground or moving downward)  00166.    ; Row 2: Object Y Velocity < 0 (moving upward)  00167.    ; Row 3: Object X velocity < 0 (moving leftward)  00168.    ; Row 4: Object X velocity >= 0 (moving rightward)  00169.   00170.    ; Group 0  00171.    ; Y X  00172.    .byte $10, $03 ; At feet  00173.    .byte $00, $03 ; At head  00174.    .byte $0A, $01 ; Wall to left  00175.    .byte $0A, $07 ; Wall to right  00176.   00177.    ; Group 1  00178.    ; NOTE! See "ONLY HAPPENS WITH GROUP 1 ROW 1 AND SLOPES ENABLED"  00179.    ; In a sloped level using this group, alternate offsets (below  00180.    ; Group 12) are used for left/right wall detection!  00181.    ; Y X  00182. OTDO_G1R1: .byte $10, $08 ; At feet  00183.    .byte $00, $08 ; At head  00184.    .byte $09, $00 ; Wall to left  00185.    .byte $09, $0F ; Wall to right  00186.   00187.    ; Group 2  00188.    ; Y X  00189.    .byte $20, $08 ; At feet  00190.    .byte $0C, $08 ; At head  00191.    .byte $15, $00 ; Wall to left  00192.    .byte $15, $0F ; Wall to right  00193.   00194.    ; Group 3  00195.    ; Y X  00196.    .byte $00, $00 ; At feet  00197.    .byte $00, $00 ; At head  00198.    .byte $00, $00 ; Wall to left  00199.    .byte $00, $00 ; Wall to right  00200.   00201.    ; Group 4  00202.    ; Y X  00203.    .byte $10, $08 ; At feet  00204.    .byte $00, $08 ; At head  00205.    .byte $08, $01 ; Wall to left  00206.    .byte $08, $0E ; Wall to right  00207.   00208.    ; Group 5  00209.    ; Y X  00210.    .byte $10, $0C ; At feet  00211.    .byte $00, $0C ; At head  00212.    .byte $0A, $01 ; Wall to left  00213.    .byte $0A, $17 ; Wall to right  00214.   00215.    ; Group 6  00216.    ; Y X  00217.    .byte $20, $0C ; At feet  00218.    .byte $00, $0C ; At head  00219.    .byte $11, $01 ; Wall to left  00220.    .byte $11, $17 ; Wall to right  00221.   00222.    ; Group 7  00223.    ; Y X  00224.    .byte $10, $08 ; At feet  00225.    .byte $00, $08 ; At head  00226.    .byte $08, $08 ; Wall to left  00227.    .byte $08, $08 ; Wall to right  00228.   00229.    ; Group 8  00230.    ; Y X  00231.    .byte $20, $08 ; At feet  00232.    .byte $10, $08 ; At head  00233.    .byte $18, $01 ; Wall to left  00234.    .byte $18, $0E ; Wall to right  00235.   00236.    ; Group 9  00237.    ; Y X  00238.    .byte $04, $14 ; At feet  00239.    .byte $04, $1C ; At head  00240.    .byte $0C, $14 ; Wall to left  00241.    .byte $0C, $1C ; Wall to right  00242.   00243.    ; Group 10  00244.    ; Y X  00245.    .byte $10, $08 ; At feet  00246.    .byte $00, $08 ; At head  00247.    .byte $0A, $00 ; Wall to left  00248.    .byte $0A, $1F ; Wall to right  00249.   00250.    ; Group 11  00251.    ; Y X  00252.    .byte $30, $08 ; At feet  00253.    .byte $00, $08 ; At head  00254.    .byte $10, $01 ; Wall to left  00255.    .byte $10, $0E ; Wall to right  00256.   00257.    ; Group 12  00258.    ; Y X  00259.    .byte $30, $08 ; At feet  00260.    .byte $00, $08 ; At head  00261.    .byte $23, $01 ; Wall to left  00262.    .byte $23, $0E ; Wall to right  00263.   00264.    ; Alternate offsets used when object utilizes "Group 1" in sloped levels  00265.    ; See "ONLY HAPPENS WITH GROUP 1 ROW 1 AND SLOPES ENABLED"  00266.    ; Y X  00267. OTDO_G1Alt: .byte $02, $01 ; Wall to left  00268.    .byte $02, $0E ; Wall to right  00269.   00270.    ; Offsets used for detection of water tiles  00271.    ; Y X  00272. OTDO_Water: .byte $04, $08  00273.   00274.   00275.    ; Defines the "bounding box"  00276.    ; Selected by Object_AttrFlags lower 4 bits  00277. Object_BoundBox:  00278.    ; Left Right Bot Top - offsets applied to sprite X/Y  00279.    .byte 2, 4, 2, 8 ; 0  00280.    .byte 1, 13, 2, 8 ; 1  00281.    .byte 2, 12, 2, 24 ; 2  00282.    .byte 10, 27, -2, 18 ; 3  00283.    .byte 1, 14, 2, 26 ; 4 (UNUSED)  00284.    .byte 5, 14, 10, 18 ; 5 (UNUSED)  00285.    .byte 2, 27, -2, 34 ; 6  00286.    .byte 2, 20, 2, 12 ; 7  00287.    .byte 2, 43, -2, 18 ; 8  00288.    .byte 2, 20, 2, 28 ; 9  00289.    .byte 2, 12, 2, 20 ; A  00290.    .byte 0, 31, -1, 14 ; B  00291.    .byte 1, 14, -2, 13 ; C  00292.    .byte 4, 17, 10, 19 ; D  00293.    .byte 4, 8, 5, 40 ; E  00294.    .byte 2, 43, 2, 12 ; F  00295.   00296. Object_AttrFlags:  00297.    ; Defines flags which set attributes of objects  00298.    .byte OAT_BOUNDBOX00 ; Object $00  00299.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $01  00300.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $02  00301.    .byte OAT_BOUNDBOX00 ; Object $03  00302.    .byte OAT_BOUNDBOX02 ; Object $04  00303.    .byte OAT_BOUNDBOX01 ; Object $05  00304.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $06 - OBJ_BOUNCEDOWNUP  00305.    .byte OAT_BOUNDBOX02 | OAT_WEAPONIMMUNITY | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $07 - OBJ_WARPHIDE  00306.    .byte OAT_BOUNDBOX00 | OAT_WEAPONIMMUNITY | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $08 - OBJ_PSWITCHDOOR  00307.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $09 - OBJ_AIRSHIPANCHOR  00308.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $0A  00309.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $0B - OBJ_POWERUP_1UP  00310.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $0C - OBJ_POWERUP_STARMAN  00311.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $0D - OBJ_POWERUP_MUSHROOM  00312.    .byte OAT_BOUNDBOX09 | OAT_HITNOTKILL ; Object $0E - OBJ_BOSS_KOOPALING  00313.    .byte OAT_BOUNDBOX00 ; Object $0F  00314.    .byte OAT_BOUNDBOX00 ; Object $10  00315.    .byte OAT_BOUNDBOX00 ; Object $11  00316.    .byte OAT_BOUNDBOX00 ; Object $12  00317.    .byte OAT_BOUNDBOX00 ; Object $13  00318.    .byte OAT_BOUNDBOX00 ; Object $14  00319.    .byte OAT_BOUNDBOX00 ; Object $15  00320.    .byte OAT_BOUNDBOX00 ; Object $16  00321.    .byte OAT_BOUNDBOX01 ; Object $17 - OBJ_SPINYCHEEP  00322.    .byte OAT_BOUNDBOX13 ; Object $18 - OBJ_BOSS_BOWSER  00323.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $19 - OBJ_POWERUP_FIREFLOWER  00324.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $1A  00325.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $1B - OBJ_BOUNCELEFTRIGHT  00326.    .byte OAT_BOUNDBOX01 ; Object $1C  00327.    .byte OAT_BOUNDBOX00 ; Object $1D  00328.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $1E - OBJ_POWERUP_SUPERLEAF  00329.    .byte OAT_BOUNDBOX00 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $1F - OBJ_GROWINGVINE  00330.    .byte OAT_BOUNDBOX00 ; Object $20  00331.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $21 - OBJ_POWERUP_MUSHCARD  00332.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $22 - OBJ_POWERUP_FIRECARD  00333.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $23 - OBJ_POWERUP_STARCARD  00334.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $24 - OBJ_CLOUDPLATFORM_FAST  00335.    .byte OAT_BOUNDBOX00 | OAT_WEAPONIMMUNITY | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $25  00336.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $26 - OBJ_WOODENPLAT_RIDER  00337.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $27 - OBJ_OSCILLATING_H  00338.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $28 - OBJ_OSCILLATING_V  00339.    .byte OAT_BOUNDBOX01 ; Object $29 - OBJ_SPIKE  00340.    .byte OAT_BOUNDBOX02 ; Object $2A - OBJ_PATOOIE  00341.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $2B - OBJ_GOOMBAINSHOE  00342.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $2C - OBJ_CLOUDPLATFORM  00343.    .byte OAT_BOUNDBOX07 ; Object $2D - OBJ_BIGBERTHA  00344.    .byte OAT_BOUNDBOX11 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $2E - OBJ_INVISIBLELIFT  00345.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $2F - OBJ_BOO  00346.    .byte OAT_BOUNDBOX00 | OAT_FIREIMMUNITY ; Object $30 - OBJ_HOTFOOT_SHY  00347.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $31 - OBJ_BOOSTRETCH  00348.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $32 - OBJ_BOOSTRETCH_FLIP  00349.    .byte OAT_BOUNDBOX01 ; Object $33 - OBJ_NIPPER  00350.    .byte OAT_BOUNDBOX02 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $34 - OBJ_TOAD  00351.    .byte OAT_BOUNDBOX00 ; Object $35 - OBJ_TOADHOUSEITEM  00352.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $36 - OBJ_WOODENPLATFORM  00353.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $37 - OBJ_OSCILLATING_HS  00354.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $38 - OBJ_OSCILLATING_VS  00355.    .byte OAT_BOUNDBOX01 ; Object $39 - OBJ_NIPPERHOPPING  00356.    .byte OAT_BOUNDBOX03 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $3A - OBJ_FALLINGPLATFORM  00357.    .byte OAT_BOUNDBOX01 ; Object $3B - OBJ_CHARGINGCHEEPCHEEP  00358.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $3C - OBJ_WOODENPLATFORMFALL  00359.    .byte OAT_BOUNDBOX01 ; Object $3D - OBJ_NIPPERFIREBREATHER  00360.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $3E - OBJ_WOODENPLATFORMFLOAT  00361.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS | OAT_FIREIMMUNITY ; Object $3F - OBJ_DRYBONES  00362.    .byte OAT_BOUNDBOX01 ; Object $40 - OBJ_BUSTERBEATLE  00363.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $41 - OBJ_ENDLEVELCARD  00364.    .byte OAT_BOUNDBOX01 ; Object $42 - OBJ_CHEEPCHEEPPOOL2POOL  00365.    .byte OAT_BOUNDBOX01 ; Object $43 - OBJ_CHEEPCHEEPPOOL2POOL2  00366.    .byte OAT_BOUNDBOX08 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $44 - OBJ_WOODENPLATUNSTABLE  00367.    .byte OAT_BOUNDBOX00 | OAT_FIREIMMUNITY ; Object $45 - OBJ_HOTFOOT  00368.    .byte OAT_BOUNDBOX02 ; Object $46 - OBJ_PIRANHASPIKEBALL  00369.    .byte OAT_BOUNDBOX06 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $47 - OBJ_GIANTBLOCKCTL  00370.    .byte OAT_BOUNDBOX01 ; Object $48 - OBJ_TINYCHEEPCHEEP  00371.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $49 - OBJ_FLOATINGBGCLOUD  00372.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $4A - OBJ_BOOMBOOMQBALL  00373.    .byte OAT_BOUNDBOX13 ; Object $4B - OBJ_BOOMBOOMJUMP  00374.    .byte OAT_BOUNDBOX13 ; Object $4C - OBJ_BOOMBOOMFLY  00375.    .byte OAT_BOUNDBOX00 ; Object $4D  00376.    .byte OAT_BOUNDBOX00 ; Object $4E  00377.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $4F - OBJ_CHAINCHOMPFREE  00378.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $50 - OBJ_BOBOMBEXPLODE  00379.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $51 - OBJ_ROTODISCDUAL  00380.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $52 - OBJ_TREASUREBOX  00381.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $53 - OBJ_PODOBOOCEILING  00382.    .byte OAT_BOUNDBOX12 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $54  00383.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $55 - OBJ_BOBOMB  00384.    .byte OAT_BOUNDBOX07 ; Object $56 - OBJ_PIRANHASIDEWAYSLEFT  00385.    .byte OAT_BOUNDBOX07 ; Object $57 - OBJ_PIRANHASIDEWAYSRIGHT  00386.    .byte OAT_BOUNDBOX01 ; Object $58 - OBJ_FIRECHOMP  00387.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $59 - OBJ_FIRESNAKE  00388.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $5A - OBJ_ROTODISCCLOCKWISE  00389.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $5B - OBJ_ROTODISCCCLOCKWISE  00390.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $5C - OBJ_ICEBLOCK  00391.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $5D - OBJ_TORNADO  00392.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $5E - OBJ_ROTODISCDUALOPPOSE  00393.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $5F - OBJ_ROTODISCDUALOPPOSE2  00394.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $60 - OBJ_ROTODISCDUALCCLOCK  00395.    .byte OAT_BOUNDBOX01 ; Object $61 - OBJ_BLOOPERWITHKIDS  00396.    .byte OAT_BOUNDBOX01 ; Object $62 - OBJ_BLOOPER  00397.    .byte OAT_BOUNDBOX13 ; Object $63 - OBJ_BIGBERTHABIRTHER  00398.    .byte OAT_BOUNDBOX01 ; Object $64 - OBJ_CHEEPCHEEPHOPPER  00399.    .byte OAT_BOUNDBOX00 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $65 - OBJ_WATERCURRENTUPWARD  00400.    .byte OAT_BOUNDBOX00 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $66 - OBJ_WATERCURRENTDOWNARD  00401.    .byte OAT_BOUNDBOX13 | OAT_FIREIMMUNITY ; Object $67 - OBJ_LAVALOTUS  00402.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $68 - OBJ_TWIRLINGBUZZY  00403.    .byte OAT_BOUNDBOX01 ; Object $69 - OBJ_TWIRLINGSPINY  00404.    .byte OAT_BOUNDBOX01 ; Object $6A - OBJ_BLOOPERCHILDSHOOT  00405.    .byte OAT_BOUNDBOX12 | OAT_FIREIMMUNITY ; Object $6B - OBJ_PILEDRIVER  00406.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS ; Object $6C - OBJ_GREENTROOPA  00407.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS ; Object $6D - OBJ_REDTROOPA  00408.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS ; Object $6E - OBJ_PARATROOPAGREENHOP  00409.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS ; Object $6F - OBJ_FLYINGREDPARATROOPA  00410.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS | OAT_FIREIMMUNITY ; Object $70 - OBJ_BUZZYBEATLE  00411.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS ; Object $71 - OBJ_SPINY  00412.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS ; Object $72 - OBJ_GOOMBA  00413.    .byte OAT_BOUNDBOX01 ; Object $73 - OBJ_PARAGOOMBA  00414.    .byte OAT_BOUNDBOX01 ; Object $74 - OBJ_PARAGOOMBAWITHMICROS  00415.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $75 - OBJ_BOSSATTACK  00416.    .byte OAT_BOUNDBOX01 ; Object $76 - OBJ_JUMPINGCHEEPCHEEP  00417.    .byte OAT_BOUNDBOX01 ; Object $77 - OBJ_GREENCHEEP  00418.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $78 - OBJ_BULLETBILL  00419.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $79 - OBJ_BULLETBILLHOMING  00420.    .byte OAT_BOUNDBOX13 | OAT_BOUNCEOFFOTHERS ; Object $7A - OBJ_BIGGREENTROOPA  00421.    .byte OAT_BOUNDBOX13 | OAT_BOUNCEOFFOTHERS ; Object $7B - OBJ_BIGREDTROOPA  00422.    .byte OAT_BOUNDBOX13 | OAT_BOUNCEOFFOTHERS ; Object $7C - OBJ_BIGGOOMBA  00423.    .byte OAT_BOUNDBOX13 ; Object $7D - OBJ_BIGGREENPIRANHA  00424.    .byte OAT_BOUNDBOX13 | OAT_BOUNCEOFFOTHERS ; Object $7E - OBJ_BIGGREENHOPPER  00425.    .byte OAT_BOUNDBOX13 ; Object $7F - OBJ_BIGREDPIRANHA  00426.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS ; Object $80 - OBJ_FLYINGGREENPARATROOPA  00427.    .byte OAT_BOUNDBOX02 ; Object $81 - OBJ_HAMMERBRO  00428.    .byte OAT_BOUNDBOX02 ; Object $82 - OBJ_BOOMERANGBRO  00429.    .byte OAT_BOUNDBOX01 ; Object $83 - OBJ_LAKITU  00430.    .byte OAT_BOUNDBOX01 ; Object $84 - OBJ_SPINYEGG  00431.    .byte OAT_BOUNDBOX01 | OAT_BOUNCEOFFOTHERS ; Object $85 - OBJ_SPINYEGGDUD  00432.    .byte OAT_BOUNDBOX13 ; Object $86 - OBJ_HEAVYBRO  00433.    .byte OAT_BOUNDBOX02 ; Object $87 - OBJ_FIREBRO  00434.    .byte OAT_BOUNDBOX01 ; Object $88 - OBJ_ORANGECHEEP  00435.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $89 - OBJ_CHAINCHOMP  00436.    .byte OAT_BOUNDBOX13 | OAT_FIREIMMUNITY ; Object $8A - OBJ_THWOMP  00437.    .byte OAT_BOUNDBOX13 | OAT_FIREIMMUNITY ; Object $8B - OBJ_THWOMPLEFTSLIDE  00438.    .byte OAT_BOUNDBOX13 | OAT_FIREIMMUNITY ; Object $8C - OBJ_THWOMPRIGHTSLIDE  00439.    .byte OAT_BOUNDBOX13 | OAT_FIREIMMUNITY ; Object $8D - OBJ_THWOMPUPDOWN  00440.    .byte OAT_BOUNDBOX13 | OAT_FIREIMMUNITY ; Object $8E - OBJ_THWOMPDIAGONALUL  00441.    .byte OAT_BOUNDBOX13 | OAT_FIREIMMUNITY ; Object $8F - OBJ_THWOMPDIAGONALDL  00442.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $90 - OBJ_TILTINGPLATFORM  00443.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $91 - OBJ_TWIRLINGPLATCWNS  00444.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $92 - OBJ_TWIRLINGPLATCW  00445.    .byte OAT_BOUNDBOX01 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $93 - OBJ_TWIRLINGPERIODIC  00446.    .byte OAT_BOUNDBOX06 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $94 - OBJ_BIGQBLOCK_3UP  00447.    .byte OAT_BOUNDBOX06 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $95 - OBJ_BIGQBLOCK_MUSHROOM  00448.    .byte OAT_BOUNDBOX06 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $96 - OBJ_BIGQBLOCK_FIREFLOWER  00449.    .byte OAT_BOUNDBOX06 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $97 - OBJ_BIGQBLOCK_SUPERLEAF  00450.    .byte OAT_BOUNDBOX06 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $98 - OBJ_BIGQBLOCK_TANOOKI  00451.    .byte OAT_BOUNDBOX06 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $99 - OBJ_BIGQBLOCK_FROG  00452.    .byte OAT_BOUNDBOX06 | OAT_FIREIMMUNITY | OAT_HITNOTKILL ; Object $9A - OBJ_BIGQBLOCK_HAMMER  00453.    .byte OAT_BOUNDBOX00 ; Object $9B  00454.    .byte OAT_BOUNDBOX00 ; Object $9C  00455.    .byte OAT_BOUNDBOX14 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $9D - OBJ_FIREJET_UPWARD  00456.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $9E - OBJ_PODOBOO  00457.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $9F - OBJ_PARABEETLE  00458.    .byte OAT_BOUNDBOX02 ; Object $A0 - OBJ_GREENPIRANHA  00459.    .byte OAT_BOUNDBOX02 ; Object $A1 - OBJ_GREENPIRANHA_FLIPPED  00460.    .byte OAT_BOUNDBOX10 ; Object $A2 - OBJ_REDPIRANHA  00461.    .byte OAT_BOUNDBOX10 ; Object $A3 - OBJ_REDPIRANHA_FLIPPED  00462.    .byte OAT_BOUNDBOX02 ; Object $A4 - OBJ_GREENPIRANHA_FIRE  00463.    .byte OAT_BOUNDBOX02 ; Object $A5 - OBJ_GREENPIRANHA_FIREC  00464.    .byte OAT_BOUNDBOX10 ; Object $A6 - OBJ_VENUSFIRETRAP  00465.    .byte OAT_BOUNDBOX10 ; Object $A7 - OBJ_VENUSFIRETRAP_CEIL  00466.    .byte OAT_BOUNDBOX11 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $A8 - OBJ_UPARROW  00467.    .byte OAT_BOUNDBOX11 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $A9 - OBJ_MANYARROW  00468.    .byte OAT_BOUNDBOX00 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $AA - OBJ_AIRSHIPPROP  00469.    .byte OAT_BOUNDBOX00 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $AB  00470.    .byte OAT_BOUNDBOX15 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $AC - OBJ_FIREJET_LEFT  00471.    .byte OAT_BOUNDBOX12 ; Object $AD - OBJ_ROCKYWRENCH  00472.    .byte OAT_BOUNDBOX11 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $AE - OBJ_BOLTLIFT  00473.    .byte OAT_BOUNDBOX01 | OAT_FIREIMMUNITY ; Object $AF - OBJ_ENEMYSUN  00474.    .byte OAT_BOUNDBOX13 | OAT_FIREIMMUNITY ; Object $B0 - OBJ_BIGCANNONBALL  00475.    .byte OAT_BOUNDBOX15 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $B1 - OBJ_FIREJET_RIGHT  00476.    .byte OAT_BOUNDBOX14 | OAT_WEAPONIMMUNITY | OAT_HITNOTKILL ; Object $B2 - OBJ_FIREJET_UPSIDEDOWN  00477.    .byte OAT_BOUNDBOX01 ; Object $B3  00478.   00479. ; Brick by tileset; anyone use this?  00480. ; $C3A8  00481.    .byte TILEA_BRICK ; 0 Plains style  00482.    .byte TILEA_BRICK ; 1 Mini Fortress style  00483.    .byte TILEA_BRICK ; 2 Hills style  00484.    .byte TILEA_BRICK ; 3 High-Up style  00485.    .byte TILEA_BRICK ; 4 pipe world plant infestation  00486.    .byte TILEA_BRICK ; 5 water world  00487.    .byte TILEA_BRICK ; 6 Toad House  00488.    .byte TILEA_BRICK ; 7 Vertical pipe maze  00489.    .byte TILEA_BRICK ; 8 desert levels  00490.    .byte TILEA_BRICK ; 9 Airship  00491.    .byte TILEA_BRICK ; 10 Giant World  00492.    .byte TILEA_BRICK ; 11 Ice level  00493.    .byte TILEA_BRICK ; 12 Sky level  00494.    .byte TILEA_BRICK ; 13 Underground  00495.   00496.    ; Index by Level_TilesetIdx  00497.    ; Enables spike tiles where available (this tile and tile before it)  00498. SpikesEnable:  00499.    .byte $FF ; 0 Plains style  00500.    .byte TILE2_SPIKEDOWN ; 1 Mini Fortress style  00501.    .byte $FF ; 2 Hills style  00502.    .byte $FF ; 3 High-Up style  00503.    .byte $FF ; 4 pipe world plant infestation  00504.    .byte $FF ; 5 water world  00505.    .byte $FF ; 6 Toad House  00506.    .byte TILE8_SPIKE_UP ; 7 Vertical pipe maze  00507.    .byte TILE9_SPIKEUP ; 8 desert levels  00508.    .byte $FF ; 9 Airship  00509.    .byte $FF ; 10 Giant World  00510.    .byte $FF ; 11 Ice level  00511.    .byte $FF ; 12 Sky level  00512.    .byte $FF ; 13 Underground  00513.   00514.    ; Index by Level_TilesetIdx  00515.    ; Enables conveyor tiles where available (this tile and tile before it)  00516. ConveyorEnable:  00517.    .byte $00 ; 0 Plains style  00518.    .byte TILE2_CONVEYORR ; 1 Mini Fortress style  00519.    .byte $00 ; 2 Hills style  00520.    .byte TILE2_CONVEYORR ; 3 High-Up style  00521.    .byte TILE2_CONVEYORR ; 4 pipe world plant infestation  00522.    .byte $00 ; 5 water world  00523.    .byte $00 ; 6 Toad House  00524.    .byte $00 ; 7 Vertical pipe maze  00525.    .byte $00 ; 8 desert levels  00526.    .byte $00 ; 9 Airship  00527.    .byte $00 ; 10 Giant World  00528.    .byte $00 ; 11 Ice level  00529.    .byte $00 ; 12 Sky level  00530.    .byte $00 ; 13 Underground  00531.   00532.    ; Index by Level_TilesetIdx  00533.    ; Sets the tile which is a pain in the ass (typically muncher, sometimes jelectro)  00534.    ; Although TILEA_MUNCHER is always considered anyway for Kuribo's shoe...  00535.    ; (see after PRG008_BD96) which is probably a bug/mistake! (Although to their  00536.    ; credit, you can never normally have Kuribo's shoe in a Jelectro level)  00537. MuncherJelectroSet:  00538.    .byte TILEA_MUNCHER ; 0 Plains style  00539.    .byte TILEA_MUNCHER ; 1 Mini Fortress style  00540.    .byte TILEA_MUNCHER ; 2 Hills style  00541.    .byte TILEA_MUNCHER ; 3 High-Up style  00542.    .byte TILEA_MUNCHER ; 4 pipe world plant infestation  00543.    .byte TILE4_JELECTRO ; 5 water world  00544.    .byte TILEA_MUNCHER ; 6 Toad House  00545.    .byte TILEA_MUNCHER ; 7 Vertical pipe maze  00546.    .byte TILEA_MUNCHER ; 8 desert levels  00547.    .byte TILEA_MUNCHER ; 9 Airship  00548.    .byte TILEA_MUNCHER ; 10 Giant World  00549.    .byte TILE4_JELECTRO ; 11 Ice level  00550.    .byte TILEA_MUNCHER ; 12 Sky level  00551.    .byte TILEA_MUNCHER ; 13 Underground  00552.   00553.   00554.    ; This table grants a couple (dis)abilities to certain  00555.    ; power-ups; specifically:  00556.    ; Bit 0 (1) = Able to fly and flutter (Raccoon tail wagging)  00557.    ; Bit 1 (2) = NOT able to slide on slopes  00558. PowerUp_Ability:  00559.    ; Small, Big, Fire, Leaf, Frog, Tanooki, Hammer  00560.    .byte $00, $00, $00, $01, $02, $01, $02  00561.   00562.    ; Velocities set to X/Y directly to Player for what might be a now-unused debug routine of sorts  00563. PRG000_C3E7:  00564.    .byte $00, $30, -$30  00565.   00566. ; FIXME: Anybody want to claim this?  00567. ; Looks like maybe a leftover debug routine for some kind of "float around" mode maybe!!  00568. ; $C3EA  00569.    LDA <Pad_Holding  00570.    AND #(PAD_LEFT | PAD_RIGHT)  00571.    TAY ; Y = 1 or 2  00572.   00573.    ; Set Player X velocity directly??  00574.    LDA PRG000_C3E7,Y  00575.    STA <Player_XVel  00576.   00577.    LDA <Pad_Holding  00578.    LSR A  00579.    LSR A  00580.    AND #((PAD_UP | PAD_DOWN) >> 2)  00581.    TAY ; Y = 1 or 2  00582.   00583.    ; Set Player Y velocity directly??  00584.    LDA PRG000_C3E7,Y  00585.    STA <Player_YVel  00586.   00587.    RTS ; Return  00588.   00589.    ; Offsets into Sprite_RAM used by objects  00590. SprRamOffsets:  00591.    ; The specified Sprite_RAM offset is calculated by object's index  00592.    ; added to Counter_7to0 (i.e. a value 0 to 7) so as to evenly  00593.    ; distribute the drawing of objects over available sprites and  00594.    ; help cope with the sprites-per-scanline drawing limits.  00595.    ;  00596.    ; Basically, on different frames, different objects will have  00597.    ; different sprite priority, so while there may be flicker, at  00598.    ; least everything is somewhat visible  00599.    .byte $40, $E8, $58, $D0, $70, $B8, $88, $A0, $40, $E8, $58, $D0, $70, $B8, $88  00600.   00601.   00602. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  00603. ; DoTimeBonus  00604. ;  00605. ; Converts your time remaining to score bonus, but only if there  00606. ; is no BGM playing! Also resets 'X' to object slot index.  00607. ; "BEQ" branches after this function if the clock is at 000.  00608. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  00609. TimeBonus_Score:  00610.    .byte 50, 5 ; 500 and 50  00611.   00612. ; $C412  00613. DoTimeBonus:  00614.    LDA SndCur_Music1  00615.    BNE PRG000_C446 ; If any music playing, jump to PRG000_C446 (RTS)  00616.   00617.    LDY #$01 ; Y = 1 (most significant or middle digit of time is non-zero)  00618.   00619.    LDA Level_TimerMSD  00620.    ORA Level_TimerMid  00621.    BNE PRG000_C422 ; If most significant or middle digit of time is non-zero, jump to PRG000_C422  00622.   00623.    INY ; Y = 2 (most significant and middle digit of time are zero)  00624.   00625. PRG000_C422:  00626.    ORA Level_TimerLSD  00627.    BEQ PRG000_C446 ; If all time digits are zero, jump to PRG000_C446 (RTS)  00628.   00629.    TYA ; A = Y  00630.    TAX ; X = A = 1 or 2  00631.   00632.    LDA (TimeBonus_Score - 1),X ; Get appropriate score bonus  00633.    STA Score_Earned ; Push into score buffer  00634.   00635. PRG000_C42F:  00636.    DEC Level_TimerMSD,X ; Decrement off middle or least significant digit  00637.    BPL PRG000_C43C ; If digit is >= 0, jump to PRG000_C43C  00638.   00639.    LDA #$09  00640.    STA Level_TimerMSD,X ; Otherwise, reload it with 9  00641.   00642.    DEX ; X--  00643.    BPL PRG000_C42F ; While X >= 0, loop!  00644.   00645. PRG000_C43C:  00646.    LDX <SlotIndexBackup ; Restore 'X' as object slot index  00647.   00648.    ; Play tick sound  00649.    LDA Sound_QLevel1  00650.    ORA #SND_LEVELBLIP  00651.    STA Sound_QLevel1  00652.   00653. PRG000_C446:  00654.    RTS ; Return  00655.   00656.   00657. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  00658. ; SpecialObj_FindEmptyAbort  00659. ; SpecialObj_FindEmptyAbortY  00660. ;  00661. ; Finds an empty special object slot (returned in 'Y') or "aborts"  00662. ; if no slot is open OR if the object has any horizontal sprite visibility  00663. ; "abort" = will not return to caller...  00664. ;  00665. ; SpecialObj_FindEmptyAbortY just allows a specified range  00666. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  00667. ; $C447  00668. SpecialObj_FindEmptyAbort:  00669.    LDY #$05  00670. SpecialObj_FindEmptyAbortY:  00671.    LDA SpecialObj_ID,Y  00672.    BEQ PRG000_C454 ; If object slot is dead/empty, jump to PRG000_C454  00673.    DEY ; Y--  00674.    BPL SpecialObj_FindEmptyAbortY ; While Y >= 0, loop!  00675.   00676. PRG000_C451:  00677.    ; Do not return to caller!!  00678.    PLA  00679.    PLA  00680.    RTS  00681.   00682. PRG000_C454:  00683.    JSR Object_AnySprOffscreen  00684.   00685.    BNE PRG000_C451 ; If any sprites are off-screen, jump to PRG000_C451  00686.   00687.    RTS ; Return  00688.   00689.   00690.    ; Goes into Score_Get100PlusPts, but object index is stored in 'Y'  00691.    ; NOTE: Overwrites 'X' anyway, so be careful!  00692. Score_Get100PlusPtsY:  00693.    PHA ; Save 'A'  00694.    TYA  00695.    TAX ; 'X' = 'Y'  00696.    PLA ; Restore 'A'  00697.   00698.    ; Get at least 100 pts based on value in 'A'  00699. Score_Get100PlusPts:  00700.    ADD #$05 ; Base at 100 points  00701.    JSR Score_PopUp  00702.    LDX <SlotIndexBackup ; X = object slot index  00703.    RTS ; Return  00704.   00705.   00706. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  00707. ; Score_PopUp  00708. ;  00709. ; Pops up a score value (e.g. from a killed enemy)  00710. ;  00711. ; A = score value  00712. ; X = index of on-screen object  00713. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  00714. Score_PopUp:  00715. ; $C467  00716.    PHA ; Save input value  00717.    STY <Temp_Var15 ; Backup 'Y' -> Temp_Var15  00718.   00719.    JSR Score_FindFreeSlot ; Get free Scores_Value slot  00720.    PLA ; Restore input value  00721.    STA Scores_Value,Y ; Store input value  00722.   00723.    LDA Objects_SpriteY,X  00724.    SUB #16  00725.    CMP #192  00726.    BLT PRG000_C47D ; If (sprite's Y - 16) < 192, jump to PRG000_C47D  00727.   00728.    LDA #$05 ; A = 5  00729.   00730. PRG000_C47D:  00731.    STA Scores_Y,Y ; Set score Y  00732.   00733.    ; Set score X to spawning object  00734.    LDA Objects_SpriteX,X  00735.    STA Scores_X,Y  00736.   00737.    ; Set score counter to $30  00738.    LDA #$30  00739.    STA Scores_Counter,Y  00740.   00741.    LDY <Temp_Var15 ; Restore 'Y'  00742.   00743.    RTS ; Return  00744.   00745.   00746.    ; Find a free slot to display the score in  00747. Score_FindFreeSlot:  00748.    LDY #$04 ; Y = 4  00749. PRG000_C490:  00750.    LDA Scores_Value,Y  00751.    BEQ PRG000_C49A ; If Scores_Value[Y] = 0, jump to PRG000_C49A (RTS)  00752.   00753.    DEY ; Y--  00754.    BPL PRG000_C490 ; While Y >= 0, loop  00755.   00756.    LDY #$04 ; Y = 4  00757.   00758. PRG000_C49A:  00759.    RTS ; Return  00760.   00761. PRG000_C49B:  00762.   00763.    ; Common init point for "power up" coins (coins that emerge from bricks and blocks)  00764.   00765.    ; Temp_Var1 = Y Lo  00766.    ; Temp_Var2 = X lo  00767.   00768.    LDY #$03 ; Y = 3  00769.   00770. PRG000_C49D:  00771.    LDA CoinPUp_State,Y  00772.    BEQ PRG000_C4A7 ; If this coin slot state = 0, it's free, go use it!  00773.    DEY ; Y--  00774.    BPL PRG000_C49D ; While Y >= 0, loop!  00775.   00776.    ; If all else fails, just overwrite the oldest slot!  00777.    LDY #$03 ; Y = 3  00778.   00779. PRG000_C4A7:  00780.   00781.    ; Play coin sound  00782.    LDA Sound_QLevel1  00783.    ORA #SND_LEVELCOIN  00784.    STA Sound_QLevel1  00785.   00786.    LDA #$01  00787.    STA CoinPUp_State,Y ; Set coin state to 1  00788.   00789.    LDA <Temp_Var1 ; Get input Y  00790.    SUB Level_VertScroll ; Make relative to vertical scroll  00791.    SBC #24 ; Subtract 24  00792.    STA CoinPUp_Y,Y ; Store as coin's Y  00793.   00794.    LDA <Temp_Var2 ; Get input X  00795.    SUB <Horz_Scroll ; Make relative to horizontal scroll  00796.    STA CoinPUp_X,Y ; Store as coin's X  00797.   00798.    LDA #-5  00799.    STA CoinPUp_YVel,Y ; Set Y Vel = -5  00800.   00801.    LDA #$01  00802.    STA CoinPUp_Counter,Y ; Set counter to 1  00803.   00804.    RTS ; Return  00805.   00806.   00807. Conveyor_CarryX: .byte -$01, $01 ; Left, Right  00808. Conveyor_CarryXHi: .byte $FF, $00 ; 16-bit sign extension  00809.   00810.    ; Checks for and handles object touching conveyor belt by carrying object  00811. ; $C4D6  00812. Object_HandleConveyorCarry:  00813.    LDA <Objects_DetStat,X  00814.    AND #$03  00815.    BNE PRG000_C4F5 ; If object has hit a wall, jump to PRG000_C4F5 (RTS)  00816.   00817.    LDA Object_TileFeet2  00818.    SUB #TILE2_CONVEYORL  00819.    CMP #$02  00820.    BGE PRG000_C4F5 ; If object is not standing on a conveyor belt, jump to PRG000_C4F5 (RTS)  00821.   00822.    TAY ; Conveyor tile relative index -> 'Y'  00823.   00824.    LDA <Objects_X,X  00825.    ADC Conveyor_CarryX,Y  00826.    STA <Objects_X,X  00827.   00828.    LDA <Objects_XHi,X  00829.    ADC Conveyor_CarryXHi,Y  00830.    STA <Objects_XHi,X  00831.   00832. PRG000_C4F5:  00833.    RTS ; Return  00834.   00835.   00836.    ; Checks for and handles object touching conveyor belt, storing result into LRBounce_Vel  00837. ; $CF46  00838. Object_HandleConveyorBounceVel:  00839.    LDA Level_PSwitchCnt  00840.    BNE PRG000_C4F5 ; If P-Switch is active, jump to PRG000_C4F5  00841.   00842.    LDA Object_TileFeet2  00843.    SUB #TILE2_CONVEYORL  00844.    CMP #$02  00845.    BGE PRG000_C4F5 ; If object is not standing on a conveyor belt, jump to PRG000_C4F5 (RTS)  00846.   00847.    TAY ; Conveyor tile relative index -> 'Y'  00848.   00849.    LDA Conveyor_CarryX,Y  00850.   00851.    LDY #-$01 ; Y = -$01  00852.   00853.    EOR <Objects_XVel,X ; Check if object is not going with conveyor  00854.    BMI PRG000_C511 ; If the signs differ (going against conveyor), jump to PRG000_C511  00855.   00856.    LDY #$01 ; Y = $01  00857.   00858. PRG000_C511:  00859.    STY LRBounce_Vel ; -> LRBounce_Vel  00860.   00861.    RTS ; Return  00862.   00863.   00864. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  00865. ; Object_HitGround  00866. ;  00867. ; When object hits the ground, this aligns it properly to a tile  00868. ;  00869. ; X = index of on-screen object  00870. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  00871. ; $C515  00872. Object_HitGround:  00873.    LDA <Objects_DetStat,X  00874.    BPL PRG000_C533 ; If object is NOT touching the "32 pixel partition" floor, jump to PRG000_C533  00875.   00876.    ; Object is touching the "32 pixel partition" floor...  00877.   00878.    LDA <Objects_Y,X  00879.    SUB Level_VertScroll  00880.    AND #$f0  00881.    ADD #$01  00882.    ADD Level_VertScroll  00883.    STA <Objects_Y,X ; Aligns to grid and adds 1  00884.   00885.    LDA #$00  00886.    ADC #$00  00887.    STA <Objects_YHi,X ; Apply carry  00888.   00889.    JMP PRG000_C53D ; Jump to PRG000_C53D  00890.   00891. PRG000_C533:  00892.    LDA <Objects_Y,X  00893.    AND #$f0  00894.    ADD Object_SlopeHeight  00895.    STA <Objects_Y,X ; Align to tile and apply slope  00896.   00897. PRG000_C53D:  00898.    LDA #$00  00899.    STA <Objects_YVel,X ; Halt vertical movement  00900.   00901.    RTS ; Return  00902.   00903.   00904.    ; The only difference amongst the Object_WorldDetect[x] entries  00905.    ; are the input value, which specifies the limit that an object  00906.    ; should acknowledge a floor tile. E.g., Object_WorldDetect4  00907.    ; means the object will not detect a floor if it is more than  00908.    ; 4 pixels vertically down in to it. "N1" (Negative one) is  00909.    ; thus basically to never use that limit because the object  00910.    ; can't be at a depth of "-1 pixels into the tile"  00911.   00912. ; $C542  00913. Object_WorldDetectN1:  00914.    LDA #$ff ; Use A = $FF  00915.    BNE PRG000_C54C ; Jump (technically always) to PRG000_C54C  00916.   00917. ; $C546  00918. Object_WorldDetect8:  00919.    LDA #$08 ; Use A = 8  00920.    BNE PRG000_C54C ; Jump (technically always) to PRG000_C54C  00921.   00922. ; $C54A  00923. Object_WorldDetect4:  00924.    LDA #$04 ; Use A = 4  00925.   00926. PRG000_C54C:  00927.    PHA ; Save input value (not used until PRG000_C649)  00928.   00929.    CPX #$05  00930.    BNE PRG000_C559 ; If object slot is NOT 5, jump to PRG000_C559  00931.   00932.    LDA ObjSplash_DisTimer,X  00933.    BEQ PRG000_C559 ; If ObjSplash_DisTimer = 0, jump to PRG000_C559  00934.   00935.    DEC ObjSplash_DisTimer,X ; ObjSplash_DisTimer --  00936.   00937. PRG000_C559:  00938.    LDA <Objects_DetStat,X  00939.    STA Temp_VarNP0 ; Object's detection status -> Temp_VarNP0  00940.   00941.    LDA #$00  00942.    STA <Objects_DetStat,X ; Clear Object's detection status  00943.    STA Object_SlopeHeight ; Clear Object's slope height  00944.    STA LRBounce_Vel ; Clear left/right bounce power  00945.   00946.    JSR Object_GetAttrAndMoveTiles ; Fill in values for Object_TileFeet/Quad and Object_TileWall/Quad  00947.   00948.    PLA ; Restore input value  00949.    STA <Temp_Var1 ; Store into Temp_Var1  00950.   00951.    LDY Object_AttrWall ; Y = detected quadrant of potential wall tile  00952.    LDA Object_TileWall ; A = detected tile index  00953.    CMP Tile_AttrTable+4,Y  00954.    BLT PRG000_C584 ; If the tile's index < the beginning wall/ceiling solid tile for this quad, jump to PRG000_C584  00955.   00956.    ; Object is touching solid wall tile  00957.   00958.    LDA #$01 ; A = 1  00959.   00960.    LDY <Objects_XVel,X  00961.    BPL PRG000_C580 ; If object's X velocity >= 0 (still or moving rightward), jump to PRG000_C580  00962.   00963.    ; Negative X vel...  00964.    ASL A ; A = 2  00965.   00966. PRG000_C580:  00967.    ORA <Objects_DetStat,X ; Set bit 0 or 1  00968.    STA <Objects_DetStat,X ; Update Objects_DetStat  00969.   00970. PRG000_C584:  00971.    LDY Object_AttrFeet ; Y = detected quadrant of tile  00972.   00973.    LDA <Objects_YVel,X  00974.    BPL PRG000_C5A9 ; If object's Y velocity >= 0 (still or moving downward), jump to PRG000_C5A9  00975.   00976.    ; Object moving upwards... (ceiling detection)  00977.   00978.    LDA Level_SlopeEn  00979.    BEQ PRG000_C59A ; If slopes are not enabled here, jump to PRG000_C59A  00980.   00981.    ; Slope detection (not specific)  00982.      00983.    LDA Object_TileFeet  00984.    CMP Tile_AttrTable,Y  00985.    BLT PRG000_C5A8 ; If tile is not within range of tiles solid at ceiling, jump to PRG000_C5A8 (RTS)  00986.    BGE PRG000_C5A2 ; Otherwise, jump to PRG000_C5A2  00987.   00988. PRG000_C59A:  00989.   00990.    ; Non-slope detection  00991.   00992.    LDA Object_TileFeet  00993.    CMP Tile_AttrTable+4,Y  00994.    BLT PRG000_C5A8 ; If tile is not within range of tiles solid at ceiling, jump to PRG000_C5A8 (RTS)  00995.   00996. PRG000_C5A2:  00997.    ; Flag ceiling impact  00998.    LDA <Objects_DetStat,X  00999.    ORA #$08  01000.    STA <Objects_DetStat,X  01001.   01002. PRG000_C5A8:  01003.    RTS ; Return  01004.   01005. PRG000_C5A9:  01006.   01007.    ; Object moving downwards (floor detection)  01008.   01009.    LDA Object_TileFeet  01010.    CMP Tile_AttrTable,Y  01011.    BGE PRG000_C5B4 ; If tile is within range of the starting solid tile, jump to PRG000_C5B4  01012.    JMP PRG000_C65D ; Otherwise, jump to PRG000_C65D  01013.   01014. PRG000_C5B4:  01015.    LDY Level_SlopeEn  01016.    BNE PRG000_C5BC ; If slopes are enabled, jump to PRG000_C5BC  01017.    JMP PRG000_C649 ; Jump to PRG000_C649  01018.   01019. PRG000_C5BC:  01020.   01021.    ; Slopes...  01022.   01023.    ; Any of the following tiles, jump to PRG000_C67F  01024.    CMP #TILE3_VERTGROUNDL  01025.    BEQ PRG000_C5D0  01026.   01027.    CMP #TILE3_VERTGROUNDR  01028.    BEQ PRG000_C5D0  01029.   01030.    CMP #TILE14_ABOVE_MIDGROUND  01031.    BEQ PRG000_C5D0  01032.   01033.    CMP #TILE3_MIDGROUND  01034.    BEQ PRG000_C5D0  01035.   01036.    CMP #TILE3_WMIDGROUND  01037.    BNE PRG000_C5D3  01038.   01039. PRG000_C5D0:  01040.    JMP PRG000_C67F ; Jump to PRG000_C67F  01041.   01042. PRG000_C5D3:  01043.   01044.    ; Slopes enabled, not touching one of the flat solids  01045.   01046.    LDA <Objects_Y,X  01047.    AND #$0f  01048.    STA <Temp_Var1 ; Temp_Var1 = object's tile-relative vertical position  01049.   01050.    LDA <Temp_Var16 ; Temp_Var16 right now is ObjTile_DetXLo  01051.    AND #$0f  01052.    STA <Temp_Var16 ; Temp_Var16 = object's tile-relative horizontal position  01053.   01054.    LDY Level_Tile_Slope ; Y = object's detected slope  01055.    LDA Slope_ObjectVel_Effect,Y ; Get value by slope  01056.    CMP #$80  01057.    BNE PRG000_C5EC ; If value <> $80, jump to PRG000_C5EC  01058.    JMP PRG000_C65D ; Otherwise, jump to PRG000_C65D  01059.   01060. PRG000_C5EC:  01061.    ; Slope response  01062.   01063.    ; Calculate the offset into Slope_LUT  01064.    ; NOTE: This fails to accomodate slope shape index values of $10+...  01065.    ; The most significant bit will be lost due to the 8-bit register!  01066.    ; But those are ceiling slopes which enemies generally don't care about  01067.    ; (Not even the upside-down Buzzy / Spiny enemies have proper ceiling slope coding!!)  01068.    TYA  01069.    ASL A  01070.    ASL A  01071.    ASL A  01072.    ASL A ; A = slope value << 4 (16 bytes per slope "shape" index)  01073.    ADD <Temp_Var16 ; Add the tile-relative horizontal position (offset to pixel specific height on this slope)  01074.    TAY ; -> 'Y'  01075.   01076.    LDA Slope_LUT,Y  01077.    AND #$0f  01078.    STA <Temp_Var2 ; Lower 4 bits of slope (the "floor" slope height) -> Temp_Var2  01079.   01080.    LDA <Temp_Var1  01081.    CMP #12  01082.    BGE PRG000_C606 ; If object's tile-relative Y position >= 12, jump to PRG000_C606  01083.   01084.   01085.    CMP <Temp_Var2  01086.    BLT PRG000_C65D ; If object's tile-relative Y position < calculated slope height, jump to PRG000_C65D  01087.   01088. PRG000_C606:  01089.    LDA <Temp_Var2  01090.    STA Object_SlopeHeight ; Store Object_SlopeHeight  01091.   01092.    ; Set "hit ground" flag  01093.    LDA <Objects_DetStat,X  01094.    ORA #$04  01095.    STA <Objects_DetStat,X  01096.   01097.    LDY Level_Tile_Slope ; Y = object's detected slope  01098.   01099.    LDA <Objects_XVel,X  01100.    LSR A  01101.    LSR A  01102.    LSR A  01103.    LSR A ; A = "whole" part of Object's X Velocity  01104.    BNE PRG000_C61E ; If not zero, jump to PRG000_C61E  01105.   01106.    LDA #$01 ; Otherwise, use A = 1  01107.   01108. PRG000_C61E:  01109.    CMP #$08  01110.    BLT PRG000_C624 ; If object's X velocity < 8, jump to PRG000_C624  01111.   01112.    ORA #$f0 ; Sign extend  01113.   01114. PRG000_C624:  01115.    LDX Slope_ObjectVel_Effect,Y ; X = value from Slope_ObjectVel_Effect  01116.    CPX #$00  01117.    BNE PRG000_C62E ; If value <> 0, jump to PRG000_C62E  01118.   01119.    ; Otherwise...  01120.    LDX #$00 ; X = 0  01121.    TXA ; A = 0  01122.   01123. PRG000_C62E:  01124.    CPX #$00  01125.    BPL PRG000_C635 ; If X is not negative, jump to PRG000_C635  01126.   01127.    JSR Negate ; Otherwise, negate (absolute value)  01128.   01129. PRG000_C635:  01130.    STX <Temp_Var1 ; -> Temp_Var1  01131.   01132.    LDX <SlotIndexBackup ; X = object slot index  01133.    STA Objects_Slope,X ; Absolute value slope  01134.   01135.    LDA <Temp_Var1 ; A = value from Slope_ObjectVel_Effect  01136.   01137.    LDY <Objects_XVel,X  01138.    BPL PRG000_C645 ; If X Velocity >= 0, jump to PRG000_C645  01139.   01140.    ; X velocity < 0 ...  01141.    JSR Negate ; Negate value  01142.   01143. PRG000_C645:  01144.    STA LRBounce_Vel ; Store the "power" of the left/right bouncer  01145.   01146.    RTS ; Return  01147.   01148.   01149. PRG000_C649:  01150.    LDA Player_PartDetEn  01151.    BNE PRG000_C656 ; If Player_PartDetEn is set (the object hit the visual ground), jump to PRG000_C656  01152.   01153.    ; The original input value finally winds up here. This limits when an object will actually  01154.    ; acknowledge "hitting ground." Basically, if the object is more than [input value] pixels  01155.    ; down in to the tile, it will not count as having hit the floor.  01156.   01157.    LDA <Objects_Y,X  01158.    AND #$0f ; Object's tile-relative vertical position  01159.    CMP <Temp_Var1  01160.    BGE PRG000_C65C ; If object is too far down in to the tile, jump to PRG000_C65C (RTS)  01161.   01162. PRG000_C656:  01163.   01164.    ; Flag object as "hit ground"  01165.    LDA <Objects_DetStat,X  01166.    ORA #$04  01167.    STA <Objects_DetStat,X  01168.   01169. PRG000_C65C:  01170.    RTS ; Return  01171.   01172.   01173. PRG000_C65D:  01174.    LDA Level_SlopeEn  01175.    BEQ PRG000_C67E ; If slopes are not enabled in this level, jump to PRG000_C67E  01176.   01177.    ; This is a correction applied for when an enemy steps over the edge of a slope:  01178.    ; ___  01179.    ; / \ <-- like when he walks across the top, down the side  01180.    ; Helps keep the enemy following the curve downward, especially enemies like red  01181.    ; shell koopa troopas that otherwise turn away at an edge...  01182.   01183.    LDY #$00 ; Y = 0  01184.   01185.    LDA Objects_Slope,X  01186.    BEQ PRG000_C67E ; If slope value = 0, jump to PRG000_C67E  01187.    BPL PRG000_C66C ; If slope is positive, jump to PRG000_C66C  01188.   01189.    DEY ; Otherwise, Y = $FF  01190.   01191. PRG000_C66C:  01192.    ADD <Objects_Y,X  01193.    STA <Objects_Y,X ; Update Y  01194.   01195.    TYA ; A = $00/$FF, sign extension  01196.   01197.    ADC <Objects_YHi,X  01198.    STA <Objects_YHi,X ; Apply to Y Hi  01199.   01200.    LDA #$00  01201.    STA Objects_Slope,X ; Clear slope value  01202.   01203.    JMP Object_WorldDetectN1 ; Jump to Object_WorldDetectN1  01204.   01205. PRG000_C67E:  01206.    RTS ; Return  01207.   01208. PRG000_C67F:  01209.   01210.    ; Flat ground tiles in a sloped world  01211.   01212.    LDA Objects_State,X  01213.    CMP #OBJSTATE_KILLED  01214.    BEQ PRG000_C69C ; If object is killed, jump to PRG000_C69C (RTS)  01215.   01216.    CMP #OBJSTATE_HELD  01217.    BEQ PRG000_C69C ; If object is being held, jump to PRG000_C69C (RTS)  01218.   01219.    LDA <Objects_Y,X  01220.    AND #$f0  01221.    SUB #$01  01222.    STA <Objects_Y,X ; Align object to one pixel above the tile  01223.   01224.    LDA <Objects_YHi,X  01225.    SBC #$00  01226.    STA <Objects_YHi,X ; Set the Y Hi  01227.   01228.    JMP Object_WorldDetectN1 ; Jump to Object_WorldDetectN1  01229.   01230. PRG000_C69C:  01231.    RTS ; Return  01232.   01233.   01234. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  01235. ; Object_GetAttrAndMoveTiles  01236. ;  01237. ; Gets tiles for an object based on its attribute settings and  01238. ; current state of movement. Handles entering/leaving water.  01239. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  01240. Object_GetAttrAndMoveTiles:  01241.    LDY #(OTDO_Water - Object_TileDetectOffsets) ; Special offsets used for checking for water tiles  01242.    JSR Object_DetectTile ; Get tile here  01243.   01244.    ASL A  01245.    ROL A  01246.    ROL A ; Upper 2 bits shift right 6, effectively  01247.    AND #%00000011 ; Keep these bits, i.e. "tile quadrant"  01248.    STA <Temp_Var1 ; -> Temp_Var1  01249.    TAY ; -> 'Y'  01250.   01251.    LDA <Level_Tile  01252.    CMP Tile_AttrTable,Y  01253.    BGE PRG000_C6FD ; If this tile >= this attribute tile, jump to PRG000_C6FD (may be solid)  01254.   01255.    LDX #$00 ; X = 0 (object is NOT underwater)  01256.   01257.    ; If this tile is TILEA_PSWITCH_PRESSED, TILE1_WFALLTOP, or PRG000_C6D0, jump to PRG000_C6D0  01258.    ; Object's apparently aren't in-water in a waterfall?  01259.    CMP #TILEA_PSWITCH_PRESSED  01260.    BEQ PRG000_C6D0  01261.    CMP #TILE1_WFALLTOP  01262.    BEQ PRG000_C6D0  01263.    CMP #TILE1_WFALLMID  01264.    BEQ PRG000_C6D0  01265.   01266.    LDA Level_TilesetIdx  01267.    ASL A  01268.    ASL A ; Offset to beginning of underwater-by-quad table  01269.    ADD <Temp_Var1 ; Add quadrant offset  01270.    TAY ; -> 'Y'  01271.    LDA Level_MinTileUWByQuad,Y ; Get the starting underwater tile  01272.    CMP <Level_Tile  01273.    BGE PRG000_C6D0 ; If starting underwater tile is >= the detected tile, jump to PRG000_C6D0  01274.   01275.    INX ; X = 1 (object is underwater)  01276.   01277. PRG000_C6D0:  01278.    TXA ; X -> A  01279.   01280.    LDX <SlotIndexBackup ; Restore 'X' as object slot index  01281.   01282.    CMP Objects_InWater,X  01283.    BEQ PRG000_C6FA ; If object is either still in water / out of water (hasn't changed), jump to PRG000_C6FA  01284.   01285.    PHA ; Save underwater flag  01286.   01287.    LDA <Level_Tile ; A = tile index  01288.    LDY <Temp_Var1 ; Y = tile quadrant  01289.    CMP Tile_AttrTable,Y  01290.   01291.    PLA ; Restore underwater flag  01292.   01293.    BGE PRG000_C6FA ; If tile index >= the attribute tile, solid tile, jump to PRG000_C6FA  01294.   01295.    PHA ; Save underwater flag  01296.   01297.    LDA Objects_LastTile,X  01298.    PHA ; Save Objects_LastTile  01299.   01300.    ASL A  01301.    ROL A  01302.    ROL A ; Upper 2 bits shift right 6, effectively  01303.    AND #%00000011 ; Keep these bits, i.e. "tile quadrant"  01304.    TAY ; Y = quadrant of last detected tile  01305.   01306.    PLA ; Restore the last detected tile  01307.   01308.    CMP Tile_AttrTable,Y  01309.   01310.    PLA ; Restore the underwater flag  01311.   01312.    BGE PRG000_C6FA ; If last detected tile >= the starting underwater tile, jump to PRG000_C6FA  01313.   01314.    PHA ; Save underwater flag  01315.   01316.    JSR Object_WaterSplash ; Hit water; splash!  01317.   01318.    PLA ; Restore underwater flag  01319.   01320. PRG000_C6FA:  01321.    STA Objects_InWater,X ; Set object's in-water flag  01322.   01323. PRG000_C6FD:  01324.    LDA <Level_Tile  01325.    STA Objects_LastTile,X ; Set last tile this object detected  01326.   01327.    LDY ObjGroupRel_Idx ; Y = object's group-relative index  01328.   01329.    LDA ObjectGroup_Attributes2,Y ; Get attributes set 2 for this object  01330.    AND #OA2_TDOGRPMASK  01331.    LSR A ; Upper 4 bits of attributes set 2 shifted right 1 (value * 8)  01332.    PHA ; Save it  01333.    TAY ; -> 'Y' (use respective Object_TileDetectOffsets group Row 1)  01334.   01335.    LDA <Objects_YVel,X  01336.    BPL PRG000_C713 ; If object Y velocity is >= 0 (stopped or moving downward), jump to PRG000_C713  01337.   01338.    INY  01339.    INY ; If object moving upward, Y += 2 (use respective Object_TileDetectOffsets group Row 2)  01340.   01341. PRG000_C713:  01342.    JSR Object_DetectTile ; Get tile  01343.   01344.    ; Store into tile index holders  01345.    STA Object_TileFeet2  01346.    STA Object_TileFeet  01347.   01348.    PHA ; Save tile  01349.   01350.    LDA Level_TilesetIdx  01351.    CMP #$02  01352.    BNE PRG000_C736 ; If Level_TilesetIdx <> 2 (not a Hills style level), jump to PRG000_C736  01353.   01354.    ; If enemy is touching quicksand, jump to PRG000_C72E; otherwise, jump to PRG000_C736  01355.    LDA <Level_Tile  01356.    CMP #TILE3_QUICKSAND_TOP  01357.    BEQ PRG000_C72E  01358.    CMP #TILE3_QUICKSAND_MID  01359.    BNE PRG000_C736  01360.   01361. PRG000_C72E:  01362.    INC Objects_QSandCtr,X ; Increment the quicksand counter  01363.   01364.    LDA #OBJSTATE_KILLED  01365.    STA Objects_State,X ; killed by quicksand  01366.   01367. PRG000_C736:  01368.    PLA ; Restore tile  01369.   01370.    ASL A  01371.    ROL A  01372.    ROL A ; Upper 2 bits shift right 6, effectively  01373.    AND #%00000011 ; Keep these bits, i.e. "tile quadrant"  01374.    STA Object_AttrFeet ; Store quadrant value  01375.    TAY ; -> 'Y'  01376.   01377.    LDA ObjTile_DetXLo  01378.    STA <Temp_Var16 ; Temp_Var16 = ObjTile_DetXLo  01379.   01380.    LDA Level_SlopeEn  01381.    BEQ PRG000_C76C ; If slopes are not enabled here, jump to PRG000_C76C  01382.   01383.    LDA <Level_Tile  01384.    CMP Tile_AttrTable,Y  01385.    BLT PRG000_C76C ; If detected tile < starting solidity tile, jump to PRG000_C76C  01386.   01387.    PHA ; Save tile  01388.   01389.    TYA ; Quadrant value -> 'A'  01390.    ASL A ; Shifted left 1 (2 byte index)  01391.    TAX ; -> 'X'  01392.   01393.    ; Temp_Var3/4 point to array of slope values for this quadrant  01394.    LDA Level_SlopeSetByQuad,X  01395.    STA <Temp_Var3  01396.    LDA Level_SlopeSetByQuad+1,X  01397.    STA <Temp_Var4  01398.   01399.    PLA ; Restore tile  01400.   01401.    SUB Tile_AttrTable,Y ; Subtract the root tile value  01402.    TAY ; -> 'Y'  01403.    LDA [Temp_Var3],Y ; Get slope value  01404.    STA Level_Tile_Slope ; -> Level_Tile_Slope  01405.   01406.    LDX <SlotIndexBackup ; Restore X as object slot index  01407.   01408. PRG000_C76C:  01409.    LDA #$00  01410.    STA Object_TileWall2 ; Object_TileWall2 = 0  01411.   01412.    PLA ; Restore Object_TileDetectOffsets index  01413.   01414.    CMP #(OTDO_G1R1 - Object_TileDetectOffsets)  01415.    BNE PRG000_C78C ; If not using Group 1 Row 1, jump to PRG000_C78C  01416.   01417.    LDY Level_SlopeEn  01418.    BEQ PRG000_C78C ; If slopes are not enabled, jump to PRG000_C78C  01419.   01420.    ;;;;;;;;;;;;;;;;;; ONLY HAPPENS WITH GROUP 1 ROW 1 AND SLOPES ENABLED  01421.   01422.    PHA ; Save Object_TileDetectOffsets index  01423.   01424.    LDA Temp_VarNP0 ; Retrieve object's in-air status  01425.    AND #$04 ; Bit 2 is set to indicate object is "on solid ground"  01426.    TAY ; -> 'Y' (0 or 4)  01427.   01428.    PLA ; Restore Object_TileDetectOffsets index  01429.   01430.    CPY #$00  01431.    BEQ PRG000_C78C ; If Y = 0 (object not on solid ground), jump to PRG000_C78C  01432.   01433.    LDY #(OTDO_G1Alt - Object_TileDetectOffsets) ; Otherwise, use alternate wall detection offsets  01434.    JMP PRG000_C791 ; Jump to PRG000_C791  01435.   01436.    ;;;;;;;;;;;;;;;;;; END  01437.   01438. PRG000_C78C:  01439.    TAY ; Object_TileDetectOffsets index -> 'Y'  01440.   01441.    INY  01442.    INY  01443.    INY  01444.    INY ; Y += 4 (move down two Rows in Object_TileDetectOffsets)  01445.   01446. PRG000_C791:  01447.    LDA <Objects_XVel,X  01448.    BMI PRG000_C797 ; If object's X velocity < 0 (moving leftward), jump to PRG000_C797  01449.   01450.    INY  01451.    INY ; Y += 2 (move down one Rows in Object_TileDetectOffsets)  01452.   01453. PRG000_C797:  01454.    JSR Object_DetectTile ; Get tile here  01455.   01456.    ; Store into tile index holders  01457.    STA Object_TileWall2  01458.    STA Object_TileWall  01459.   01460.    ASL A  01461.    ROL A  01462.    ROL A ; Upper 2 bits shift right 6, effectively  01463.    AND #%00000011 ; Keep these bits, i.e. "tile quadrant"  01464.    STA Object_AttrWall ; Store quadrant value  01465.   01466.    RTS ; Return  01467.   01468.   01469.   01470.   01471. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  01472. ; Object_DetectTile  01473. ;  01474. ; Gets tile based on offset of object; the offset is set by the  01475. ; 'Y' register which indexes Object_TileDetectOffsets for the  01476. ; Y/X offset pair. Seems kind of a limited way to go, but hey..  01477. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  01478. ; $C7A9  01479. Object_DetectTile:  01480.    LDA Level_7Vertical  01481.    BEQ PRG000_C7B1 ; If level is NOT vertical, jump to PRG000_C7B1  01482.   01483.    JMP PRG000_C85C ; Jump to PRG000_C85C  01484.   01485. PRG000_C7B1:  01486.    LDA Player_PartDetEn  01487.    BEQ PRG000_C7D9 ; If Player_PartDetEn is not set, jump to PRG000_C7D9  01488.   01489.    ; The 32 pixel partition floor is enabled  01490.    ; Any object Y >= 160 must detect the bottom two tile rows instead!  01491.   01492.    LDA <Objects_Y,X  01493.    ADD Object_TileDetectOffsets,Y ; Adding tile detection offset to Object's Y  01494.    SUB Level_VertScroll ; Make relative to scroll  01495.    CMP #160  01496.    BLT PRG000_C7D9 ; If Y < 160, jump to PRG000_C7D9  01497.   01498.    ; Object is low enough to the visual floor...  01499.   01500.    SBC #16 ; Subtract 16  01501.    AND #$f0 ; Align to grid  01502.    STA ObjTile_DetYLo ; -> ObjTile_DetYLo  01503.   01504.    ; Flag object as touching "32 pixel partition" floor  01505.    LDA <Objects_DetStat,X  01506.    ORA #$80  01507.    STA <Objects_DetStat,X  01508.   01509.    LDA #$01  01510.    STA ObjTile_DetYHi ; ObjTile_DetYHi = 1  01511.   01512.    JMP PRG000_C7F1 ; Jump to PRG000_C7F1  01513.   01514. PRG000_C7D9:  01515.    LDA <Objects_Y,X  01516.    ADD Object_TileDetectOffsets,Y ; Adding tile detection Y offset to Object's Y  01517.    AND #$f0 ; Align to grid  01518.    STA ObjTile_DetYLo ; -> ObjTile_DetYLo (low)  01519.   01520.    LDA <Objects_YHi,X  01521.    ADC #$00 ; Apply carry  01522.    STA ObjTile_DetYHi ; -> ObjTile_DetYHi (high)  01523.   01524.    BEQ PRG000_C7FA ; If no carry, jump to PRG000_C7FA  01525.   01526.    ; In a non-vertical level, a high value of 2 or greater is way beyond the bottom  01527.    CMP #$02  01528.    BGE PRG000_C832 ; If the Y Hi >= 2, jump to PRG000_C832  01529.   01530. PRG000_C7F1:  01531.    PHA ; Save high part  01532.   01533.    LDA ObjTile_DetYLo  01534.    CMP #$b0  01535.   01536.    PLA ; Restore high part  01537.   01538.    BGE PRG000_C832 ; If the Y lo part is greater than $B0 (the bottom of the screen), jump to PRG000_C832  01539.   01540. PRG000_C7FA:  01541.    AND #$01  01542.    STA <Temp_Var3 ; Temp_Var3 = 0 or 1, depending if Y lo is on odd line or not  01543.   01544.    LDA <Objects_X,X  01545.    ADC Object_TileDetectOffsets+1,Y ; Adding tile detection X offset to Object's X  01546.    STA ObjTile_DetXLo ; -> ObjTile_DetXLo (low)  01547.   01548.    LDA <Objects_XHi,X  01549.    ADC #$00 ; Apply carry  01550.    STA ObjTile_DetXHi ; -> ObjTile_DetXHi (high)  01551.   01552.    CMP #$10  01553.    BGE PRG000_C832 ; If the high part is more than $10 (biggest possible within other limits), jump to PRG000_C832  01554.   01555.    ASL A ; Change high part into 2 byte index to select the screen  01556.    TAY ; -> 'Y'  01557.   01558.    ; Calculate Temp_Var2/1 (tile address)  01559.    LDA Tile_Mem_Addr,Y  01560.    STA <Temp_Var1  01561.    LDA Tile_Mem_Addr+1,Y  01562.    ADC <Temp_Var3  01563.    STA <Temp_Var2  01564.   01565.    ; Calculate tile offset within screen  01566.    LDA ObjTile_DetXLo  01567.    LSR A  01568.    LSR A  01569.    LSR A  01570.    LSR A  01571.    ORA ObjTile_DetYLo  01572.   01573.    TAY ; -> 'Y'  01574.   01575. PRG000_C82A:  01576.    LDA [Temp_Var1],Y ; Get tile  01577.   01578.    JSR PSwitch_SubstTileAndAttr ; Substitute tile if P-Switch is active  01579.   01580.    JMP PRG000_C834 ; Jump to PRG000_C834  01581.   01582. PRG000_C832:  01583.    LDA #$00 ; No tile detected  01584.   01585. PRG000_C834:  01586.    STA <Level_Tile ; Store tile index detected  01587.   01588.    RTS ; Return  01589.   01590.   01591. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  01592. ; PSwitch_SubstTileAndAttr  01593. ;  01594. ; P-Switch substitution function for tiles which it effects  01595. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  01596.    ; Parallel arrays which for a given tile in the accumulator,  01597.    ; if it matches one of the ones in PrePSwitchTile is replaced  01598.    ; with the attribute and tile from the other arrays...  01599. PrePSwitchTile: .byte $40, $67, $66, $05  01600. PostPSwitchTile: .byte $67, $40, $40, $40  01601. PostPSwitchAttr: .byte $03, $00, $00, $00  01602.   01603. PSwitch_SubstTileAndAttr:  01604.    LDY Level_PSwitchCnt ; Y = Level_PSwitchCnt  01605.    BEQ PRG000_C85B ; If P-Switch not active, jump to PRG000_C85B (RTS)  01606.   01607.    LDY #(PostPSwitchTile - PrePSwitchTile - 1)  01608. PRG000_C84A:  01609.    CMP PrePSwitchTile,Y  01610.    BNE PRG000_C858 ; If this is not a match, jump to PRG000_C858  01611.   01612.    LDA PostPSwitchAttr,Y ; Get replacement attribute  01613.    STA <Player_Slopes ; Store into Player_Slopes  01614.   01615.    LDA PostPSwitchTile,Y ; Get replacement tile  01616.    RTS ; Return  01617.   01618. PRG000_C858:  01619.    DEY ; Y--  01620.    BPL PRG000_C84A ; While Y >= 0, loop!  01621.   01622. PRG000_C85B:  01623.    RTS ; Return  01624.   01625.   01626. PRG000_C85C:  01627.   01628.    ; Vertical level object detect tile  01629.   01630.    LDA <Objects_Y,X  01631.    ADD Object_TileDetectOffsets,Y ; Adding tile detection Y offset to Object's Y  01632.    AND #$f0 ; Align to grid  01633.    STA ObjTile_DetYLo ; -> ObjTile_DetYLo (low)  01634.    STA <Temp_Var3 ; -> Temp_Var3  01635.   01636.    LDA <Objects_YHi,X  01637.    ADC #$00 ; Apply carry  01638.    STA ObjTile_DetYHi ; -> ObjTile_DetYHi (high)  01639.   01640.    CMP #$10  01641.    BGE PRG000_C832 ; If object is detecting way too low (out of range), jump to PRG000_C832 (no tile detected)  01642.   01643.    ADC #$60 ; +$60  01644.    STA <Temp_Var2 ; -> Temp_Var2  01645.   01646.    ; ObjTile_DetXHi = Objects_XHi (should be zero)  01647.    LDA <Objects_XHi,X  01648.    STA ObjTile_DetXHi  01649.   01650.    LDA <Objects_X,X  01651.    ADD Object_TileDetectOffsets+1,Y ; Adding tile detection X offset to Object's X  01652.    STA ObjTile_DetXLo ; -> ObjTile_DetXLo (low)  01653.   01654.    ; Calculate tile offset within screen  01655.    LSR A  01656.    LSR A  01657.    LSR A  01658.    LSR A  01659.    ORA <Temp_Var3  01660.    STA <Temp_Var1 ; -> Temp_Var1  01661.   01662.    LDY #$00 ; Y = 0 (additional offset not used)  01663.   01664.    JMP PRG000_C82A ; Jump to PRG000_C82A  01665.   01666. ; FIXME: Anybody want to claim this?  01667. ; $C893  01668.    .byte $FC, $04, $01, $02  01669.   01670.   01671.    ; When Object hits water, splash!  01672. Object_WaterSplash:  01673.    LDA #$02  01674.   01675. Podoboo_Splash:  01676.    STA <Temp_Var1 ; Temp_Var1 = 2  01677.   01678.    LDA ObjSplash_DisTimer,X  01679.    BNE PRG000_C914 ; If splashes are disabled, jump to PRG000_C914 (RTS)  01680.   01681.    LDA Level_ObjectID,X  01682.    CMP #OBJ_GROWINGVINE  01683.    BEQ PRG000_C914 ; If object is a growing vine, jump to PRG000_C914 (RTS)  01684.   01685.    LDA <Objects_YVel,X  01686.    BMI PRG000_C8BE ; If Object's Y velocity is negative (moving upward), jump to PRG000_C8BE  01687.   01688.    ; If object is some kind of blooper, jump to PRG000_C914 (RTS)  01689.    LDA Level_ObjectID,X  01690.    CMP #OBJ_BLOOPER  01691.    BEQ PRG000_C914  01692.    CMP #OBJ_BLOOPERCHILDSHOOT  01693.    BEQ PRG000_C914  01694.    CMP #OBJ_BLOOPERWITHKIDS  01695.    BEQ PRG000_C914  01696.   01697.    LDA #$00  01698.    STA <Objects_YVel,X ; Object's Y velocity is zeroed at impact of water  01699.   01700. PRG000_C8BE:  01701.   01702.    ; Basically looking not to do a splash effect if object is falling off-screen  01703.   01704.    JSR Object_AnySprOffscreen  01705.    BNE PRG000_C914 ; If any sprites are off-screen, jump to PRG000_C914 (RTS)  01706.   01707.    LDY #$02 ; Y = 2 (this is immediately overwritten and thus not used)  01708.   01709.    ; Alternate between splash slot 1 and 2  01710.    INC Object_SplashAlt ; Object_SplashAlt++  01711.    LDA Object_SplashAlt  01712.    AND #$01 ; Keep just bit 0  01713.    TAY ; -> 'Y'  01714.   01715.    INY ; Y = 1 or 2  01716.   01717.    LDA #$01  01718.    STA Splash_Counter,Y ; Splash counter = 1 (begin splash)  01719.   01720.    LSR A  01721.    STA Splash_NoScrollY,Y ; Splash_NoScrollY = 0 (splash is relative to vertical scroll)  01722.   01723.    ; Set appropriate splash Y  01724.    LDA <Objects_Y,X  01725.    SUB #$04  01726.    AND #$f0  01727.    ADD <Temp_Var1  01728.    STA Splash_Y,Y  01729.   01730.    ; Set appropriate splash X  01731.    LDA <Objects_X,X  01732.    STA Splash_X,Y  01733.   01734.    LDA <Objects_YVel,X  01735.    BMI PRG000_C914 ; If object's Y velocity is negative (moving upwards), jump to PRG000_C914 (RTS)  01736.   01737.    ; NOTE: The following is probably old debug code; it basically catches the coordinates  01738.    ; of the very first splash any object makes... and then will never update again because  01739.    ; nothing clears the WatrHit_IsSetFlag value... may also be an unused feature where an  01740.    ; object could respond somehow to having splashed down?  01741.   01742.    LDA WatrHit_IsSetFlag  01743.    BNE PRG000_C914 ; If WatrHit_IsSetFlag is set, jump to PRG000_C914 (RTS)  01744.   01745.    LDA #$80  01746.    STA WatrHit_IsSetFlag ; WatrHit_IsSetFlag = $80  01747.   01748.    ; Store Object_WatrHit vars  01749.    LDA <Objects_Y,X  01750.    ADC #$06  01751.    STA Object_WatrHitY  01752.   01753.    LDA <Objects_YHi,X  01754.    ADC #$00  01755.    STA Object_WatrHitYHi  01756.   01757.    LDA <Objects_X,X  01758.    ADC #$04  01759.    STA Object_WatrHitX  01760.   01761.    LDA <Objects_XHi,X  01762.    ADC #$00  01763.    STA Object_WatrHitXHi  01764.   01765. PRG000_C914:  01766.    RTS ; Return  01767.   01768. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  01769. ; Objects_HandleScrollAndUpdate  01770. ;  01771. ; THE function which spawns objects as they appear on screen and  01772. ; calls updates on all objects based on their state etc. Also  01773. ; updates the timers.  01774. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  01775. Objects_HandleScrollAndUpdate:  01776.    JMP PRG000_C927 ; Jump to PRG000_C927  01777.   01778. PRG000_C918:  01779.    .byte $35, $F0, $0C  01780.   01781. ; FIXME: Anybody want to claim this?  01782. ; Appears to be a debug routine that would toggle the Player to be invincible by pressing SELECT  01783. ; $C91B  01784.    LDA <Pad_Input  01785.    AND #PAD_SELECT  01786.    BEQ PRG000_C927 ; If Player is NOT pressing SELECT, jump to PRG000_C927  01787.   01788.    ; Toggle invincibility flag  01789.    EOR Player_DebugNoHitFlag  01790.    STA Player_DebugNoHitFlag  01791.   01792. PRG000_C927:  01793.    LDA Splash_DisTimer  01794.    BEQ PRG000_C92F ; If Splash_DisTimer > 0, jump to PRG000_C92F  01795.   01796.    DEC Splash_DisTimer ; Splash_DisTimer--  01797.   01798. PRG000_C92F:  01799.    LDA <Player_Suit  01800.    CMP #PLAYERSUIT_HAMMER  01801.    BNE PRG000_C93A ; If Player suit is NOT hammer suit, jump to PRG000_C93A  01802.   01803.    ; Otherwise...  01804.    LDA #$4f  01805.    STA PatTable_BankSel+5 ; Sixth pattern table bank = $4F  01806.   01807. PRG000_C93A:  01808.    LDA <Player_IsDying  01809.    CMP #$03  01810.    BNE PRG000_C948 ; If Player is NOT dying due to TIME UP, jump to PRG000_C948  01811.   01812.    ; Otherwise...  01813.    LDA PatTable_BankSel+2  01814.    CMP #$52  01815.    BNE PRG000_C948 ; If third pattern table bank has not been set to $52, jump to PRG000_C948  01816.    RTS ; Return  01817.   01818. PRG000_C948:  01819.    LDA Player_IsHolding  01820.    STA Player_ISHolding_OLD ; Player_ISHolding_OLD = Player_ISHolding  01821.   01822.    LDA #$00  01823.    STA Player_IsHolding ; Clear Player_IsHolding  01824.    STA ArrowPlat_IsActive ; Clear ArrowPlat_IsActive  01825.   01826.    LDA #$ff  01827.    STA LRBounce_Y ; LRBounce_Y = $FF  01828.   01829.    ; Set page @ A000 to 5  01830.    LDA #$05  01831.    STA PAGE_A000  01832.    JSR PRGROM_Change_A000  01833.   01834.    JSR LevelEvent_Do ; Perform event as set by Level_Event  01835.    JSR Level_SpawnObjsAndBounce ; Handle if Player bounced off block and spawn new objects as screen scrolls  01836.   01837.    DEC Counter_7to0 ; Counter_7to0--  01838.    BPL PRG000_C973 ; If Counter_7to0 >= 0, jump to PRG000_C973  01839.   01840.    LDA #$07  01841.    STA Counter_7to0 ; Otherwise, reset Counter_7to0 to 7  01842.   01843. PRG000_C973:  01844.    LDX #$07  01845.   01846. PRG000_C975:  01847.    STX <SlotIndexBackup ; Backup current object index -> SlotIndexBackup  01848.   01849.    LDA <Player_HaltGame  01850.    BNE PRG000_C9B6 ; If gameplay is halted, jump to PRG000_C9B6  01851.   01852.    LDA Objects_Timer,X  01853.    BEQ PRG000_C983 ; If this timer is already at zero, jump to PRG000_C983  01854.   01855.    DEC Objects_Timer,X ; Otherwise, decrement it  01856.   01857. PRG000_C983:  01858.   01859.    LDA Objects_Timer2,X  01860.    BEQ PRG000_C98B ; If this timer is already at zero, jump to PRG000_C98B  01861.   01862.    DEC Objects_Timer2,X ; Otherwise, decrement it  01863.   01864. PRG000_C98B:  01865.   01866.    CPX #$05  01867.    BGE PRG000_C9B6 ; If object slot index >= 5, jump to PRG000_C9B6  01868.   01869.    ; Non-special objects in slots 0 to 4...  01870.   01871.    LDA Objects_Timer4,X  01872.    BEQ PRG000_C997 ; If this timer is already at zero, jump to PRG000_C997  01873.   01874.    DEC Objects_Timer4,X ; Otherwise, decrement it  01875.   01876. PRG000_C997:  01877.    LDA Objects_Timer3,X  01878.    BEQ PRG000_C9B6 ; If timer is zero, jump to PRG000_C9B6  01879.   01880.    CMP #$60  01881.    BLT PRG000_C9B3 ; If timer value is < $60, jump to PRG000_C9B3  01882.   01883.    LDA #$01 ; A = 1  01884.   01885.    LDY Objects_State,X  01886.    CPY #OBJSTATE_NORMAL  01887.    BEQ PRG000_C9B3 ; If object's state is Normal, jump to PRG000_C9B3  01888.   01889.    CPY #$04  01890.    BNE PRG000_C9AF ; If object's state is NOT 4 (being held), jump to PRG000_C9AF  01891.   01892.    ; Object being held...  01893.   01894.    LDA #$03 ; A = 3  01895. PRG000_C9AF:  01896.    AND <Counter_1  01897.    BNE PRG000_C9B6 ; Every A:A+1 ticks, jump to PRG000_C9B6  01898.   01899. PRG000_C9B3:  01900.    DEC Objects_Timer3,X ; Every 4 ticks, decrement Objects_Timer3  01901.   01902. PRG000_C9B6:  01903.    TXA ; Object index -> 'A'  01904.    ADD Counter_7to0 ; Add current value of Counter_7to0  01905.    TAY ; -> 'Y' (anywhere from 0 to 14)  01906.   01907.    LDA SprRamOffsets,Y  01908.    STA Object_SprRAM,X ; Store this object's Sprite_RAM offset  01909.   01910.    JSR Object_DoStateAction ; Do whatever's required by this object by its current state  01911.    JSR Object_HitByTailOrBouncer ; Test and respond if object was hit by Player tail attack or left/right bouncer  01912.   01913.    LDA Objects_State,X  01914.    BNE PRG000_C9D2 ; If object's state is not 0 (dead/empty), jump to PRG000_C9D2  01915.   01916.    ; Remove object's associated spawn index  01917.    LDA #$ff  01918.    STA Objects_SpawnIdx,X  01919.   01920. PRG000_C9D2:  01921.    DEX ; X--  01922.    BPL PRG000_C975 ; While X >= 0, loop!  01923.   01924.    LDA Cine_ToadKing  01925.    BEQ PRG000_C9E5 ; If Toad & King Cinematic is NOT going on, jump to PRG000_C9E5  01926.   01927.    ; Set page @ A000 to 24  01928.    LDA #24  01929.    STA PAGE_A000  01930.    JSR PRGROM_Change_A000  01931.   01932.    JSR Cinematic_ToadAndKing ; Do the Toad & King Cinematic logic  01933.   01934. PRG000_C9E5:  01935.    LDA Player_Flip  01936.    BEQ PRG000_C9FB ; If Player is NOT somersaulting, jump to PRG000_C9FB  01937.   01938.    LDA Player_InWater  01939.    ORA Player_SandSink  01940.    BNE PRG000_C9F6 ; If Player is in water or sinking in sand, jump to PRG000_C9F6  01941.   01942.    LDA <Player_InAir  01943.    BNE PRG000_C9FB ; If Player is mid-air, jump to PRG000_C9FB  01944.   01945. PRG000_C9F6:  01946.    ; A would-be somersaulting Player is either in water or sand,  01947.    ; or is not mid-air; disable it!  01948.    LDA #$00  01949.    STA Player_Flip  01950.   01951. PRG000_C9FB:  01952.    LDA Level_ChgTileEvent  01953.    BNE PRG000_CA33 ; If a change tile event is called for, jump to PRG000_CA33  01954.   01955.    ; Check each block bump slot to see if it needs to occur  01956.    LDY #$00  01957.    LDA Level_BlkBump,Y  01958.    BNE PRG000_CA13  01959.   01960.    INY  01961.    LDA Level_BlkBump,Y  01962.    BNE PRG000_CA13  01963.   01964.    INY  01965.    LDA Level_BlkBump,Y  01966.    BEQ PRG000_CA33  01967.   01968. PRG000_CA13:  01969.    STA Level_ChgTileEvent ; Set the block bump change event  01970.   01971.    ; Set relevant parameters  01972.    LDA Level_BlkBump_XHi,Y  01973.    STA Level_BlockChgXHi  01974.   01975.    LDA Level_BlkBump_XLo,Y  01976.    STA Level_BlockChgXLo  01977.   01978.    LDA Level_BlkBump_YHi,Y  01979.    STA Level_BlockChgYHi  01980.   01981.    LDA Level_BlkBump_YLo,Y  01982.    STA Level_BlockChgYLo  01983.   01984.    ; Clear this block bump!  01985.    LDA #$00  01986.    STA Level_BlkBump,Y  01987.   01988. PRG000_CA33:  01989.    LDA Level_JctCtl  01990.    BEQ PRG000_CA40 ; If no level junction is occurring, jump to PRG000_CA40  01991.   01992.    STA LevelPartialInit ; Flag that we need a level partial initialization  01993.   01994.    ; Clear the "Get Wand" cinematic state  01995.    LDA #$00  01996.    STA Level_GetWandState  01997.   01998. PRG000_CA40:  01999.    RTS ; Return  02000.   02001.    ; Breaks up every 36 object IDs to make smaller jump tables  02002. ObjectID_BaseVals:  02003.    .byte $00, $24, $48, $6C, $90  02004.   02005.   02006. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  02007. ; Object_DoStateAction  02008. ;  02009. ; Do whatever is required by the current Objects_State value  02010. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  02011. Object_DoStateAction:  02012.    LDA Objects_State,X  02013.    BEQ PRG000_CA40 ; If this object is "dead/empty", jump to PRG000_CA40  02014.   02015.    CMP #$08  02016.    BEQ PRG000_CA81 ; If this object's state = 8 ("Poof" Dying), jump to PRG000_CA81  02017.   02018.    LDY #$04 ; Y = 4  02019.   02020.    ; Try to locate the group that this object ID belongs to  02021.    ; Groups are defined by ObjectID_BaseVals, every 36 values.  02022. PRG000_CA51:  02023.    LDA Level_ObjectID,X ; Get object ID  02024.    CMP ObjectID_BaseVals,Y ; Compare to this base value  02025.    BGE PRG000_CA5C ; If this object ID >= the base value, jump to PRG000_CA5C  02026.   02027.    ; Object ID is smaller, thus not this group...  02028.   02029.    DEY ; Y--  02030.    BNE PRG000_CA51 ; If Y > 0, loop!  02031.   02032. PRG000_CA5C:  02033.   02034.    ; Y contains index to the base value for this group of object IDs  02035.    ; A contains the object's ID  02036.   02037.    INY ; Y++  02038.    SUB ObjectID_BaseVals-1,Y ; Subtract next group's ID to make this object's ID relative to group  02039.   02040.    STA ObjGroupRel_Idx ; Set ObjGroupRel_Idx to this group-relative index value  02041.   02042.    ; Y is now a value of 1 to 5, and that value dictates the page  02043.    ; where this object's code can be found...  02044.    STY PAGE_A000 ; Set new page  02045.    TAY ; Object group-relative index -> 'Y'  02046.      02047.    JSR PRGROM_Change_A000 ; Set page @ A000 to appropriate object page...  02048.   02049.    LDA Objects_DisPatChng,X  02050.    BNE PRG000_CA81 ; If pattern bank enforcement is disabled, jump to PRG000_CA81  02051.   02052.    ; Object's can request a particular pattern set to be available to them.  02053.    ; They may set either the fifth or sixth bank of CHRROM, which is specified  02054.    ; by bit 7.  02055.   02056.    LDX #$00 ; X = 0 (fifth CHRROM bank)  02057.    LDA ObjectGroup_PatTableSel,Y ; Load CHRROM bank request for this object, if any  02058.    BEQ PRG000_CA7F ; If CHRROM bank request is zero, no change, jump to PRG000_CA7F  02059.    BPL PRG000_CA7A ; If CHRROM bank request does not have bit 7 set, jump to PRG000_CA7A  02060.    INX ; Otherwise, X = 1 (sixth CHRROM bank)  02061.   02062. PRG000_CA7A:  02063.    AND #$7f ; Bit 7 is used to specify which bank, so filter it here  02064.    STA PatTable_BankSel+4,X ; Store pattern bank  02065.   02066. PRG000_CA7F:  02067.    LDX <SlotIndexBackup ; Restore X as the object slot index  02068.   02069. PRG000_CA81:  02070.    JSR AScrlURDiag_CheckWrapping ; Handle diagonal autoscroll's scroll wrappping  02071.    JSR Object_DetermineVertVis ; Set flags based on which sprites of this object are vertically visible  02072.    JSR Object_DetermineHorzVis ; Set flags based on which sprites of this object are horizontally visible  02073.   02074.    LDA Objects_State,X ; Get object state...  02075.   02076.    JSR DynJump  02077.   02078.    ; THESE MUST FOLLOW DynJump FOR THE DYNAMIC JUMP TO WORK!!  02079.    .word ObjState_DeadEmpty ; 0 - Dead/Empty  02080.    .word ObjState_Initializing ; 1 - Initializing  02081.    .word ObjState_Normal ; 2 - Normal operation  02082.    .word ObjState_Shelled ; 3 - Shelled  02083.    .word ObjState_Held ; 4 - Held by Player  02084.    .word ObjState_Kicked ; 5 - Kicked  02085.    .word ObjState_Killed ; 6 - Killed  02086.    .word ObjState_Squashed ; 7 - Object was squashed (NOTE: Really only intended for Goomba/Giant Goomba)  02087.    .word ObjState_PoofDying ; 8 - "Poof" Dying  02088.   02089.    ; Patterns selected by "poof" death frame  02090. PoofDeath_Pats:  02091.    .byte $47, $45, $41, $43  02092.   02093. ObjState_PoofDying:  02094.    LDA Objects_Timer,X  02095.    BNE PRG000_CAAE ; If object timer is not expired, jump to PRG000_CAAE  02096.   02097.    JMP PRG000_D068 ; Jump to PRG000_D068 (Object_SetDeadEmpty)  02098.   02099. PRG000_CAAE:  02100.    JSR Object_AnySprOffscreen  02101.    BNE PRG000_CAF0 ; If any sprite is off-screen, jump to PRG000_CAF0 (RTS)  02102.   02103.    ; Set the "poof" pixel positions  02104.    JSR Object_CalcSpriteXY_NoHi  02105.    LDY Object_SprRAM,X  02106.    LDA <Objects_SpriteY,X  02107.    STA Sprite_RAM+$00,Y  02108.    STA Sprite_RAM+$04,Y  02109.    LDA <Objects_SpriteX,X  02110.    STA Sprite_RAM+$03,Y  02111.    ADD #$08  02112.    STA Sprite_RAM+$07,Y  02113.   02114.    LDA Objects_Timer,X  02115.    LSR A  02116.    LSR A  02117.    LSR A  02118.    TAX ; X = "poof" frame  02119.   02120.    ; Set "poof" death patterns  02121.    LDA PoofDeath_Pats,X  02122.    STA Sprite_RAM+$01,Y  02123.    STA Sprite_RAM+$05,Y  02124.   02125.    ; Set the attributes  02126.    LDA Level_NoStopCnt  02127.    LSR A  02128.    LSR A  02129.    ROR A  02130.    AND #$80  02131.    ORA #$01  02132.    STA Sprite_RAM+$02,Y  02133.   02134.    EOR #$c0  02135.    STA Sprite_RAM+$06,Y  02136.   02137.    LDX <SlotIndexBackup ; X = object slot index  02138.   02139. PRG000_CAF0:  02140.    RTS ; Return  02141.   02142.    ; In units of $10 ticks by timer 3...  02143. PRG000_CAF1:  02144.    .byte %00000010, %00000010, %00000100, %00001000, %00010000, %00010000  02145.   02146.    ; Some objects have "feet" when they are waking up,  02147.    ; this offsets their Y depending on whether v-flipped  02148. ObjWakeUp_FeetYOff: .byte 10, -10  02149.   02150.    ; Called for an object in state 3 to do its "shelled" routine  02151. ObjState_Shelled:  02152.    LDY ObjGroupRel_Idx ; Y = object's group-relative index  02153.   02154.    LDA ObjectGroup_Attributes3,Y  02155.    AND #OA3_SQUASH  02156.    BEQ PRG000_CB10 ; If OA3_SQUASH is NOT set (stomp does not "shell" this object), jump to PRG000_CB10  02157.   02158.    ; Attribute set 3 bit 4 is set...  02159.   02160.    ; Go to "stomped" state  02161.   02162.    ; Timer 3 = $10  02163.    LDA #$10  02164.    STA Objects_Timer3,X  02165.   02166.    ; Set object state to Squashed  02167.    LDA #OBJSTATE_SQUASHED  02168.    STA Objects_State,X  02169.   02170.    JMP Object_ShakeAndDraw ; Draw object and don't come back...  02171.   02172. PRG000_CB10:  02173.   02174.    ; Attribute set 3 bit 4 is NOT set... (object is "shelled" when stomped)  02175.   02176.    LDA <Player_HaltGame  02177.    BNE PRG000_CB5B ; If gameplay is halted, jump to PRG000_CB5B  02178.   02179.    JSR Object_ShellDoWakeUp ; Handle waking up (MAY not return here, if object "wakes up"!)  02180.    JSR Object_Move ; Perform standard object movements  02181.   02182.    LDA <Objects_DetStat,X  02183.    AND #$04  02184.    BEQ PRG000_CB45 ; If object hit floor, jump to PRG000_CB45  02185.   02186.    LDA <Objects_YVel,X  02187.    BMI PRG000_CB45 ; If object is moving upward, jump to PRG000_CB45  02188.   02189.    ; Object has NOT hit floor and is NOT moving upward...  02190.   02191.    PHA ; Save Y velocity  02192.   02193.    JSR Object_HitGround ; Align with ground  02194.   02195.    LDA <Objects_XVel,X ; Get X velocity  02196.   02197.    PHP ; Save CPU state  02198.   02199.    ; Get absolute value of X velocity  02200.    BPL PRG000_CB30  02201.    JSR Negate  02202. PRG000_CB30:  02203.   02204.    LSR A ; Divide by 2  02205.    PLP ; Restore CPU state  02206.   02207.    ; If needed to negate before, negate again  02208.    BPL PRG000_CB37  02209.    JSR Negate  02210. PRG000_CB37:  02211.    STA <Objects_XVel,X ; Set as X velocity  02212.   02213.    PLA ; Restore Y velocity  02214.   02215.    ; Divide by 4  02216.    LSR A  02217.    LSR A  02218.    JSR Negate ; Negate it  02219.    CMP #-$02  02220.    BGE PRG000_CB45 ; If object only lightly moving upward, jump to PRG000_CB45  02221.   02222.    STA <Objects_YVel,X ; Set object Y velocity  02223.   02224. PRG000_CB45:  02225.    LDA <Objects_DetStat,X  02226.    AND #$08  02227.    BEQ PRG000_CB4F ; If object has NOT hit ceiling, jump to PRG000_CB4F  02228.   02229.    ; Set object Y velocity to $10 (rebound off ceiling)  02230.    LDA #$10  02231.    STA <Objects_YVel,X  02232.   02233. PRG000_CB4F:  02234.    LDA <Objects_DetStat,X  02235.    AND #$03  02236.    BEQ PRG000_CB58 ; If object has NOT hit wall, jump to PRG000_CB58  02237.   02238.    JSR Object_AboutFace ; Turn around...  02239.   02240. PRG000_CB58:  02241.    JSR Object_HandleBumpUnderneath ; Handle object getting hit from underside  02242.   02243. PRG000_CB5B:  02244.    JSR Object_BumpOffOthers ; Bump off and turn away from other objects  02245.   02246. PRG000_CB5E:  02247.    JSR Object_DeleteOffScreen ; Delete object if it goes off-screen  02248.   02249.   02250. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  02251. ; Object_DrawShelled  02252. ;  02253. ; Draw object in "shelled" state  02254. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  02255. ; $CB61  02256. Object_DrawShelled:  02257.    ; Set object frame to 2  02258.    LDA #$02  02259.    STA Objects_Frame,X  02260.   02261.    LDA Objects_IsGiant,X  02262.    BEQ PRG000_CB7B ; If object is NOT giant, jump to PRG000_CB7B  02263.   02264.    ; Call special "giant" object draw routine (giant objects assume a JMP instruction @ ObjectGroup_PatternSets)  02265.    JSR ObjectGroup_PatternSets  02266.   02267. Object_SetShakeAwakeTimer:  02268.   02269.    ; Set timer for object to wake up from  02270.   02271.    LDA Objects_Timer3,X  02272.    CMP #$60  02273.    BGE PRG000_CB7A ; If timer 3 >= $60, jump to PRG000_CB7A  02274.   02275.    AND #$07  02276.    STA Objects_Timer4,X ; Timer 4 = 0-7, based on timer3  02277.   02278. PRG000_CB7A:  02279.    RTS ; Return  02280.   02281.   02282. PRG000_CB7B:  02283.   02284.    LDA Level_ObjectID,X  02285.   02286.    CMP #OBJ_BOBOMBEXPLODE  02287.    BEQ PRG000_CB86 ; If this is a Bob-omb exploding, jump to PRG000_CB86  02288.   02289.    CMP #OBJ_BOBOMB  02290.    BNE PRG000_CB8E ; If this is not a Bob-omb of any sort, jump to PRG000_CB8E  02291.   02292. PRG000_CB86:  02293.   02294.    ; Have object flip same way as Player  02295.    LDA <Player_FlipBits  02296.    STA Objects_FlipBits,X  02297.   02298.    JMP Object_ShakeAndDraw ; Draw object and never come back!  02299.   02300. PRG000_CB8E:  02301.    JSR Object_ShakeAndDrawMirrored ; Draw mirrored sprite  02302.   02303.    LDY Level_ObjectID,X  02304.    CPY #OBJ_ICEBLOCK  02305.    BEQ PRG000_CBB3 ; If object is an Iceblock, jump to PRG000_CBB3 (RTS)  02306.   02307.    JSR Object_SetShakeAwakeTimer ; Set the "shake awake" timers  02308.   02309.    CPY #OBJ_BUZZYBEATLE  02310.    BNE PRG000_CBB4 ; If object is NOT a Buzzy Beatle, jump to PRG000_CBB4  02311.   02312.    ; Buzzy Beatle  02313.   02314.    LDY Objects_FlipBits,X  02315.    BMI PRG000_CBB3 ; If Buzzy is vertically flipped, jump to PRG000_CBB3 (RTS)  02316.   02317.    LDY Object_SprRAM,X ; Y = object's Sprite_RAM offset  02318.   02319.    ; +1 to Y to sprite if not flipped  02320.    LDA Sprite_RAM+$00,Y  02321.    ADD #$01  02322.    STA Sprite_RAM+$00,Y  02323.    STA Sprite_RAM+$04,Y  02324.   02325. PRG000_CBB3:  02326.    RTS ; Return  02327.   02328. PRG000_CBB4:  02329.   02330.    ; NOT a Buzzy Beatle  02331.   02332.    CPY #OBJ_SPINY  02333.    BEQ PRG000_CBB3 ; If Object is a Spiny, jump to PRG000_CBB3  02334.   02335.    ; "Shake awake" speed  02336.   02337.    LDA Objects_Timer3,X  02338.    CMP #$50  02339.    BGE PRG000_CC23 ; If timer 3 >= $50, jump to PRG000_CC23  02340.   02341.    LSR A  02342.    LSR A  02343.    LSR A  02344.    LSR A  02345.    TAY ; Y = index into PRG000_CAF1 (proper bit mask for shaking speed)  02346.   02347.    ; Various speed shake by timer 3  02348.    LDA Objects_Timer3,X  02349.    AND PRG000_CAF1,Y  02350.    BEQ PRG000_CC23 ; If not shaking on this bit, jump to PRG000_CC23  02351.   02352.    LDA #$01 ; A = 1 (object not vertically flipped)  02353.   02354.    LDY Objects_FlipBits,X  02355.    BMI PRG000_CBD4 ; If object is vertically flipped, jump to PRG000_CBD4  02356.   02357.    LSR A ; A = 0 (object vertically flipped)  02358.   02359. PRG000_CBD4:  02360.    LDY Object_SprRAM,X ; Y = object's Sprite_RAM offset  02361.   02362.    TAX ; X = 0 or 1 (proper Y offset for foot)  02363.   02364.    ; One foot  02365.    LDA Sprite_RAM+$00,Y  02366.    CMP #$f8  02367.    BEQ PRG000_CBEA ; If sprite Y = $F8, jump to PRG000_CBEA  02368.   02369.    ADD ObjWakeUp_FeetYOff,X ; Add the foot offset  02370.    CMP #$c5  02371.    BGE PRG000_CBF8 ; If the offset >= $C5, jump to PRG000_CBF8  02372.   02373.    STA Sprite_RAM+$08,Y ; Foot Y  02374.   02375. PRG000_CBEA:  02376.   02377.    ; Other foot  02378.    LDA Sprite_RAM+$04,Y  02379.    CMP #$f8  02380.    BEQ PRG000_CBF8 ; If sprite Y = $F8, jump to PRG000_CBF8  02381.   02382.    ADD ObjWakeUp_FeetYOff,X ; Add the foot offset  02383.    STA Sprite_RAM+$0C,Y ; Other foot Y  02384.   02385. PRG000_CBF8:  02386.   02387.    ; Foot Xs  02388.    LDA Sprite_RAM+$03,Y  02389.    SUB #$03  02390.    STA Sprite_RAM+$0B,Y  02391.   02392.    LDA Sprite_RAM+$07,Y  02393.    ADD #$03  02394.    STA Sprite_RAM+$0F,Y  02395.   02396.    ; Foot attributes  02397.    LDA Sprite_RAM+$02,Y  02398.    AND #$80  02399.    ORA #$03  02400.    STA Sprite_RAM+$0A,Y  02401.   02402.    ; Flip the other foot  02403.    ORA #$40  02404.    STA Sprite_RAM+$0E,Y  02405.   02406.    ; Feet pattern  02407.    LDA #$f9  02408.    STA Sprite_RAM+$09,Y  02409.    STA Sprite_RAM+$0D,Y  02410.   02411.    LDX <SlotIndexBackup ; Restore 'X' as object index  02412.   02413. PRG000_CC23:  02414.    RTS ; Return  02415.   02416.   02417. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  02418. ; Object_BumpOffOthers  02419. ;  02420. ; Detects all objects "prior" to this one and determines if the  02421. ; objects have collided, at which point they "bump off eachother"  02422. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  02423. Object_BumpOffOthers:  02424.    TXA ; A = object slot index  02425.    ADD <Counter_1  02426.    LSR A  02427.    BCS PRG000_CC6B ; Semi-randomly jump to PRG000_CC6B (RTS)  02428.   02429.    JSR Object_AnySprOffscreen  02430.    BNE PRG000_CC6B ; If any sprite is off-screen, jump to PRG000_CC6B (RTS)  02431.   02432.    JSR Object_CalcBoundBox2  02433.    TXA  02434.    BEQ PRG000_CC6B ; If object slot is zero, jump to PRG000_CC6B (RTS)  02435.   02436.    DEX ; X-- (consider the previous object)  02437.   02438. PRG000_CC37:  02439.    LDY Level_ObjectID,X ; Y = Object ID  02440.   02441.    LDA Object_AttrFlags,Y  02442.    AND #OAT_BOUNCEOFFOTHERS  02443.    BEQ PRG000_CC66 ; If OAT_BOUNCEOFFOTHERS is NOT set, jump to PRG000_CC66  02444.   02445.    LDA Objects_State,X  02446.    CMP #OBJSTATE_NORMAL  02447.    BNE PRG000_CC66 ; If Object state is NOT Normal, jump to PRG000_CC66  02448.   02449.    JSR Object_AnySprOffscreen  02450.    BNE PRG000_CC66 ; If any sprite of object is off-screen, jump to PRG000_CC66  02451.   02452.    JSR Object_CalcBoundBox  02453.    JSR ObjectObject_Intersect  02454.    BCC PRG000_CC66 ; If object did not intersect with prior object, jump to PRG000_CC66  02455.   02456.    LDY <SlotIndexBackup ; Y = object slot index  02457.   02458.    LDA <Objects_SpriteX,X  02459.    CMP Objects_SpriteX,Y  02460.    LDY #$00 ; Y = 0  02461.    BLT PRG000_CC62 ; If this object's sprite X < the OTHER object's sprite X, jump to PRG000_CC62  02462.    LDY #$40 ; Otherwise, Y = $40  02463.   02464. PRG000_CC62:  02465.    TYA  02466.    STA Objects_FlipBits,X ; Object turns around if it hit another object  02467.   02468. PRG000_CC66:  02469.    DEX ; X--  02470.    BPL PRG000_CC37 ; While X >= 0, loop!  02471.   02472.    LDX <SlotIndexBackup ; X = object slot index  02473.   02474. PRG000_CC6B:  02475.    RTS ; Return  02476.   02477.   02478. ObjKickXvel: .byte $18, -$18  02479.   02480. ObjState_Kicked:  02481.    LDA <Player_HaltGame  02482.    BEQ PRG000_CC75 ; If gameplay is NOT halted, jump to PRG000_CC75  02483.   02484.    JMP PRG000_CD46 ; Jump to PRG000_CD46  02485.   02486. PRG000_CC75:  02487.    JSR Object_Move ; Perform standard object movements  02488.    JSR Object_DetermineHorzVis ; Determine horizontally visible sprites  02489.   02490.    LDA <Objects_DetStat,X  02491.    AND #$04  02492.    BEQ PRG000_CC94 ; If object has hit ground, jump to PRG000_CC94  02493.   02494.    LDA <Objects_XVel,X  02495.    BNE PRG000_CC8D ; If object is moving horizontally, jump to PRG000_CC8D  02496.   02497.    ; Object not moving horizontally...  02498.    JSR Level_ObjCalcXDiffs  02499.    LDA ObjKickXvel,Y  02500.    STA <Objects_XVel,X ; Set X velocity based on which side of Player the object is on  02501.   02502. PRG000_CC8D:  02503.    JSR Object_HitGround ; Align to floor  02504.   02505.    ; Y Velocity = $0C (begin drop)  02506.    LDA #$0c  02507.    STA <Objects_YVel,X  02508.   02509. PRG000_CC94:  02510.    LDA <Objects_DetStat,X  02511.    AND #$03  02512.    BNE PRG000_CC9D ; If object has hit a wall, jump to PRG000_CC9D  02513.   02514.    JMP PRG000_CCF7 ; Otherwise, jump to PRG000_CCF7  02515.   02516. PRG000_CC9D:  02517.    LDA Objects_SpriteX,X  02518.   02519.    LDY <Objects_XVel,X  02520.    BPL PRG000_CCAA ; If object is not moving to the left, jump to PRG000_CCAA  02521.   02522.    CMP #$06  02523.    BLT PRG000_CCE2 ; If object's sprite X < 6, jump to PRG000_CCAA  02524.    BGE PRG000_CCAE ; Otherwise, jump to PRG000_CCAE  02525.   02526. PRG000_CCAA:  02527.    CMP #228  02528.    BGE PRG000_CCE2 ; If object's sprite X < 228, jump to PRG000_CCE2  02529.   02530. PRG000_CCAE:  02531.    JSR Object_AnySprOffscreen  02532.    BNE PRG000_CCE2 ; If any sprite is off-screen, jump to PRG000_CCE2  02533.   02534.    LDA PAGE_A000  02535.    PHA ; Save current PAGE_A000 page  02536.   02537.    ; Set page @ A000 to 8  02538.    LDA #$08  02539.    STA PAGE_A000  02540.    JSR PRGROM_Change_A000  02541.   02542.    ; Temp_Var13 = Object tile detect Y Hi  02543.    LDA ObjTile_DetYHi  02544.    STA <Temp_Var13  02545.   02546.    ; Temp_Var13 = Object tile detect Y Hi  02547.    LDA ObjTile_DetYLo  02548.    STA <Temp_Var14  02549.   02550.    ; Temp_Var15 = Object tile detect X Hi  02551.    LDA ObjTile_DetXHi  02552.    STA <Temp_Var15  02553.   02554.    ; Temp_Var16 = Object tile detect X Lo  02555.    LDA ObjTile_DetXLo  02556.    STA <Temp_Var16  02557.   02558.    ; Handle object bouncing off blocks  02559.    LDA Object_TileWall2  02560.    JSR Object_BumpOffBlocks  02561.   02562.    LDX <SlotIndexBackup ; X = object slot index  02563.   02564.    ; Restore page @ A000 to previous value  02565.    PLA  02566.    STA PAGE_A000  02567.    JSR PRGROM_Change_A000  02568.   02569. PRG000_CCE2:  02570.   02571.    ; Play bump sound  02572.    LDA Sound_QPlayer  02573.    ORA #SND_PLAYERBUMP  02574.    STA Sound_QPlayer  02575.   02576.    LDA Level_ObjectID,X  02577.    CMP #OBJ_ICEBLOCK  02578.    BNE PRG000_CCF4 ; If this object is NOT an Ice Block, jump to PRG000_CCF4  02579.   02580.    JMP PRG000_D295 ; Jump to PRG000_D295 (set Ice Block to "killed" state)  02581.   02582. PRG000_CCF4:  02583.    JSR Object_AboutFace ; Bounced off block, turn around  02584.   02585. PRG000_CCF7:  02586.    JSR Object_HandleBumpUnderneath ; Handle the kicked shelled object getting hit from underneath  02587.   02588.    TXA  02589.    ADD <Counter_1  02590.    LSR A  02591.    BCC PRG000_CD46 ; Semi-randomly jump to PRG000_CD46  02592.   02593.    JSR ObjectToObject_HitTest  02594.    BCC PRG000_CD46 ; If object has not hit another object, jump to PRG000_CD46  02595.   02596.    ; Play object-to-object collision sound  02597.    LDA Sound_QPlayer  02598.    ORA #SND_PLAYERKICK  02599.    STA Sound_QPlayer  02600.   02601.    ; Knock object in same general direction as the kicked shell object  02602.    LDA <Objects_XVel,X  02603.    ASL A  02604.    LDA #$10 ; A = $10  02605.    BCC PRG000_CD17  02606.    LDA #-$10 ; A = -$10  02607. PRG000_CD17:  02608.    STA Objects_XVel,Y  02609.   02610.    LDA Objects_State,Y  02611.    CMP #OBJSTATE_KICKED  02612.    BNE PRG000_CD36 ; If the impacted object's state is not Kicked, jump to PRG000_CD36  02613.   02614.    ; Another kicked object on the way... (slam and kill eachother)  02615.   02616.    LDA Objects_KillTally,Y  02617.  JSR Score_Get100PlusPts ; Get the total score this OTHER kicked shell object earned  02618.    JSR ObjectKill_SetShellKillVars ; Kill our kicked object and set ShellKill variables  02619.   02620.    ; Set X Velocity of our kicked object in the direction of the impacted object  02621.    LDA Objects_XVel,Y  02622.    ASL A  02623.    LDA #$10  02624.    BCS PRG000_CD34  02625.    LDA #-$10  02626. PRG000_CD34:  02627.    STA <Objects_XVel,X  02628.   02629. PRG000_CD36:  02630.    TYA  02631.    TAX ; X = the other object we just hit  02632.    JSR ObjectKill_SetShellKillVars ; Kill the impacted object and set ShellKill variables  02633.   02634.    LDX <SlotIndexBackup ; X = object slot index (our kicked object)  02635.    LDA Objects_KillTally,X  02636.    INC Objects_KillTally,X ; Increase our kicked object's kill tally...  02637.    JSR Score_Get100PlusPtsY ; Get points by the kill tally! (Incidentally, Score_Get100PlusPts would work too)  02638.   02639. PRG000_CD46:  02640.    JSR Object_DeleteOffScreen ; Delete the kicked shell object if it goes off-screen  02641.   02642.    LDA Level_ObjectID,X  02643.    CMP #OBJ_ICEBLOCK  02644.    BEQ PRG000_CD77 ; If the kicked object is an ice block, jump to PRG000_CD77  02645.   02646.    ; Object is NOT an ice block...  02647.   02648.    ; NOTE: I really, really wish Nintendo used a consistent check here!  02649.    ; Other code checks Objects_IsGiant before taking this route...  02650.    CMP #OBJ_BIGGREENTROOPA  02651.    BGE PRG000_CD80 ; If the object ID >= OBJ_BIGGREENTROOPA (why not use Objects_IsGiant?!), jump to PRG000_CD80  02652.   02653.    LDA Level_NoStopCnt  02654.    LSR A  02655.    AND #$03  02656.    TAY ; Y = 0 to 3, by counter  02657.   02658.    LDA Objects_FlipBits,X  02659.    AND #~SPR_HFLIP ; Keep all FlipBits except horizontal flips  02660.    ORA ObjShell_AnimFlipBits,Y  02661.    STA Objects_FlipBits,X ; Apply flip as appropriate  02662.   02663.    ; Set animation frame as appropriate  02664.    LDA ObjShell_AnimFrame,Y  02665.    STA Objects_Frame,X  02666.   02667.    TYA  02668.    AND #$01  02669.    BNE PRG000_CD74 ; Every other tick, jump to PRG000_CD74  02670.   02671.    JMP Object_ShakeAndDrawMirrored ; Draw sprite and don't come back  02672.   02673. PRG000_CD74:  02674.    JMP Object_ShakeAndDraw ; Update sprite data, draw sprite, and don't come back  02675.   02676. PRG000_CD77:  02677.   02678.    ; Ice block only...  02679.   02680.    LDA <Counter_1  02681.    LSR A  02682.    STA Objects_ColorCycle,X ; Cycle colors  02683.    JMP Object_ShakeAndDrawMirrored ; Draw sprite and don't come back!  02684.   02685. PRG000_CD80:  02686.    JMP ObjectGroup_PatternSets ; Jump to ObjectGroup_PatternSets (giant object special shelled draw routine)  02687.   02688.   02689. ObjectKill_SetShellKillVars:  02690.    ; Set object state to Killed  02691.    LDA #OBJSTATE_KILLED  02692.    STA Objects_State,X  02693.   02694.    ; Bounce up a bit  02695.    LDA #-$30  02696.    STA <Objects_YVel,X  02697.   02698.    ; Set ShellKillFlash vars  02699.    LDA <Objects_Y,X  02700.    STA ShellKillFlash_Y  02701.    LDA <Objects_X,X  02702.    STA ShellKillFlash_X  02703.    LDA #$0a  02704.    STA ShellKillFlash_Cnt  02705.   02706.    RTS ; Return  02707.      02708.    ; Kicked shell object animation frames and flips  02709. ObjShell_AnimFlipBits: .byte $00, $00, $00, $40  02710. ObjShell_AnimFrame: .byte $04, $06, $05, $06  02711.   02712.    ; Copies all brick bust data over to the second bust slots  02713.    ; (So up to 2 bricks may be scattering debris at once)  02714. BrickBust_MoveOver:  02715.    LDA BrickBust_En  02716.    STA BrickBust_En+1  02717.   02718.    LDA BrickBust_YUpr  02719.    STA BrickBust_YUpr+1  02720.   02721.    LDA BrickBust_YLwr  02722.    STA BrickBust_YLwr+1  02723.   02724.    LDA BrickBust_X  02725.    STA BrickBust_X+1  02726.   02727.    LDA BrickBust_YVel  02728.    STA BrickBust_YVel+1  02729.   02730.    LDA BrickBust_XDist  02731.    STA BrickBust_XDist+1  02732.   02733.    LDA BrickBust_HEn  02734.    STA BrickBust_HEn+1  02735.   02736.    RTS ; Return  02737.   02738.   02739. ; FIXME: Anybody want to claim this?  02740. ; Appears to override what goes in to Object_BumpBlocks  02741. ; $CDCF  02742.    LDA Object_TileWall2  02743.   02744. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  02745. ; Object_BumpBlocks  02746. ;  02747. ; Provides an arbitrary object with the ability to hit objects  02748. ; with its "head"; used by Boom Boom, though Boom Boom never  02749. ; gets a chance to employ that in the game...  02750. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  02751. ; $CDD2  02752. Object_BumpBlocks:  02753.    STA <Temp_Var8 ; Store detected tile -> Temp_Var8  02754.   02755.    ; Backup current PAGE_A000 bank  02756.    LDA PAGE_A000  02757.    PHA  02758.   02759.    ; Change page @ A000 to 8  02760.    LDA #$08  02761.    STA PAGE_A000  02762.    JSR PRGROM_Change_A000  02763.   02764.    ; Transfer tile detection  02765.   02766.    LDA ObjTile_DetYHi  02767.    STA <Temp_Var13  02768.   02769.    LDA ObjTile_DetYLo  02770.    STA <Temp_Var14  02771.   02772.    LDA ObjTile_DetXHi  02773.    STA <Temp_Var15  02774.   02775.    LDA ObjTile_DetXLo  02776.    STA <Temp_Var16  02777.   02778.    ; Send detected tile over to check if object has hit any blocks  02779.    ; that respond to being hit with head  02780.    LDA <Temp_Var8  02781.    JSR Object_BumpOffBlocks  02782.   02783.    LDX <SlotIndexBackup ; X = object slot index  02784.   02785.    ; Restore page @ A000 to previous page  02786.    PLA  02787.    STA PAGE_A000  02788.    JSR PRGROM_Change_A000  02789.   02790.    RTS ; Return  02791.   02792.   02793.    ; X velocities depending on kick direction, added to by half of Player's X velocity  02794. ObjectKickXVelMoving: .byte -$30, $30  02795.   02796.    ; Set appropriate flip bits based on object's relative position to Player  02797. PlayerKickFlipBits: .byte $00, $40  02798.   02799.    ; X velocities depending on kick direction  02800. BobombKickXVel: .byte -$28, $28  02801.   02802.    ; Different X and X Hi offsets applied to object being held by Player  02803.    ; Changes whether not doing anything special, in pipe, etc.  02804. ObjectHoldXOff: .byte $0B, -$0B, $04, -$04, $04, $0B, -$13, $04, -$08, $04, $00  02805. ObjectHoldXHiOff: .byte $00, $FF, $00, $FF, $00, $00, $FF, $00, $FF, $00, $00  02806.   02807.    ; Object-to-object hit resultant X velocity  02808. ObjectToObject_HitXVel: .byte -$08, $08  02809.   02810. ObjState_Held:  02811.    LDA <Player_IsDying  02812.    BEQ PRG000_CE28 ; If Player is NOT dying, jump to PRG000_CE28  02813.   02814.    JMP PRG000_CF98 ; Jump to PRG000_CF98 (just draw held object)  02815.   02816. PRG000_CE28:  02817.    JSR Object_ShellDoWakeUp ; Wake up while Player is holding object...  02818.    BIT <Pad_Holding  02819.    BVC Player_KickObject ; If Player is NOT holding B button, jump to Player_KickObject  02820.   02821. PRG000_CE2F:  02822.    JMP PRG000_CEEF ; Jump to PRG000_CEEF  02823.   02824.   02825. Player_KickObject:  02826.    LDA Level_PipeMove  02827.    BNE PRG000_CE2F ; If Player is moving through pipes, jump to PRG000_CE2F (PRG000_CEEF)  02828.   02829.    ; Play kick sound  02830.    LDA Sound_QPlayer  02831.    ORA #SND_PLAYERKICK  02832.    STA Sound_QPlayer  02833.   02834.    ; Have Player do kick frame  02835.    LDA #$0c  02836.    STA Player_Kick  02837.   02838.    ; Set object timer 2 to $10  02839.    LDA #$10  02840.    STA Objects_Timer2,X  02841.   02842.    LDA Level_ObjectID,X  02843.   02844.    CMP #OBJ_BOBOMBEXPLODE  02845.    BEQ PRG000_CE54 ; If this is a Bob-omb ready to explode, jump to PRG000_CE54  02846.   02847.    CMP #OBJ_BOBOMB  02848.    BNE PRG000_CE79 ; If this is NOT a Bob-omb, jump to PRG000_CE79  02849.   02850. PRG000_CE54:  02851.   02852.    ; Bob-ombs only...  02853.   02854.    ; State remains "normal"  02855.    LDA #OBJSTATE_NORMAL  02856.    STA Objects_State,X  02857.   02858.    ; Set Y vel to -$20 (bounce up)  02859.    LDA #-$20  02860.    STA <Objects_YVel,X  02861.   02862.    ; Set X Velocity appropriately based on kick direction  02863.    JSR Level_ObjCalcXDiffs  02864.    LDA BobombKickXVel,Y  02865.    STA <Objects_XVel,X  02866.   02867.    EOR <Player_XVel  02868.    BMI PRG000_CE76 ; If the Bob-omb's X velocity is the opposite sign of the Player's, jump to PRG000_CE76  02869.   02870.    LDA <Player_XVel  02871.    STA <Temp_Var1 ; -> Temp_Var1 (yyyy xxxx)  02872.    ASL <Temp_Var1 ; Shift 1 bit left (bit 7 into carry) (y yyyx xxx0)  02873.    ROR A ; A is now arithmatically shifted to the right (yyyyy xxx) (signed division by 2)  02874.    ADD ObjectKickXVelMoving,Y ; Add base "moving" X velocity of Bob-omb  02875.    STA <Objects_XVel,X ; Set this as Bob-omb's X Velocity  02876.   02877. PRG000_CE76:  02878.    JMP Object_ShakeAndDraw ; Draw Bob-omb and don't come back!  02879.   02880. PRG000_CE79:  02881.   02882.    ; Anything besides a Bob-omb...  02883.   02884.    ; Clear Objects_KillTally  02885.    LDA #$00  02886.    STA Objects_KillTally,X  02887.   02888.    LDA Objects_State,X  02889.    CMP #OBJSTATE_HELD  02890.    BNE PRG000_CEBE ; If object's state is not Held, jump to PRG000_CEBE  02891.   02892.    ; This object is being held by Player...  02893.   02894.    LDA Level_ObjectID,X  02895.    CMP #OBJ_ICEBLOCK  02896.    BEQ PRG000_CEB4 ; If this is an ice block, jump to PRG000_CEB4  02897.   02898.    LDY #1 ; Y = 1  02899.   02900.    LDA <Player_FlipBits  02901.    BNE PRG000_CE94 ; If Player is not turned around, jump to PRG000_CE94  02902.   02903.    LDY #-1 ; Y = -1  02904.   02905. PRG000_CE94:  02906.    STY <Objects_XVel,X ; Set minimum X velocity on object (to enable wall hit detection)  02907.   02908.    JSR Object_WorldDetectN1 ; Detect against world  02909.   02910.    LDA <Objects_DetStat,X  02911.    AND #$03  02912.    BEQ PRG000_CEB4 ; If object has not hit a wall, jump to PRG000_CEB4  02913.   02914.    ; KICK OBJECT INTO WALL LOGIC  02915.   02916.    ; Flat 100 points  02917.    LDA #$05  02918.    JSR Score_PopUp  02919.   02920.    ; Object state is Killed  02921.    LDA #OBJSTATE_KILLED  02922.    STA Objects_State,X  02923.   02924.    ; Set object Y velocity to -$40 (fly up a bit)  02925.    LDA #-$40  02926.    STA <Objects_YVel,X  02927.   02928.    ; Remove that minimum X velocity  02929.    LDA #$00  02930.    STA <Objects_XVel,X  02931.   02932.    JMP PRG000_CF98 ; Jump to PRG000_CF98  02933.   02934. PRG000_CEB4:  02935.   02936.    ; Object kicked not against wall...  02937.   02938.    LDY #0 ; Y = 0  02939.   02940.    LDA <Player_FlipBits  02941.    BEQ PRG000_CEBB ; If Player has not turned around, jump to PRG000_CEBB  02942.   02943.    INY ; Y = 1  02944.   02945. PRG000_CEBB:  02946.    JMP PRG000_CEC6 ; Jump to PRG000_CEC6  02947.   02948. PRG000_CEBE:  02949.   02950.    ; Object kicked, was not held  02951.   02952.    ; Make sure Player is facing object he's kicking  02953.    JSR Level_ObjCalcXDiffs  02954.    LDA PlayerKickFlipBits,Y  02955.    STA <Player_FlipBits  02956.   02957. PRG000_CEC6:  02958.    LDA ObjectKickXVelMoving,Y ; Get appropriate base X velocity for kick  02959.    STA <Objects_XVel,X ; -> Object's X velocity  02960.   02961.    EOR <Player_XVel  02962.    BMI PRG000_CEDC ; If the object's X velocity is the opposite sign of the Player's, jump to PRG000_CEDC  02963.   02964.    LDA <Player_XVel ; Get the Player's X velocity  02965.    STA <Temp_Var1 ; -> Temp_Var1 (yyyy xxxx)  02966.    ASL <Temp_Var1 ; Shift 1 bit left (bit 7 into carry) (y yyyx xxx0)  02967.    ROR A ; A is now arithmatically shifted to the right (yyyyy xxx) (signed division by 2)  02968.    ADD ObjectKickXVelMoving,Y ; Add base "moving" X velocity of object  02969.    STA <Objects_XVel,X ; Set as object's X velocity  02970.   02971. PRG000_CEDC:  02972.    ; If object's state is not Killed, jump to PRG000_CEE8  02973.    LDA Objects_State,X  02974.    CMP #OBJSTATE_KILLED  02975.    BEQ PRG000_CEE8  02976.   02977.    ; Set object state to 5 (Kicked)  02978.    LDA #OBJSTATE_KICKED  02979.    STA Objects_State,X  02980.   02981. PRG000_CEE8:  02982.   02983.    ; Set object's Y velocity to zero  02984.    LDA #$00  02985.    STA <Objects_YVel,X  02986.   02987.    JMP PRG000_CF98 ; Jump to PRG000_CF98  02988.   02989. PRG000_CEEF:  02990.   02991.    ; Player moving through pipes...  02992.   02993.    ; Player keeps on holding through the pipes!!  02994.    LDA #$01  02995.    STA Player_IsHolding  02996.   02997.    LDA Level_PipeMove  02998.    BEQ PRG000_CEFD ; If Player is NOT moving through pipes, jump to PRG000_CEFD  02999.   03000.    LDY #$0a ; Y = 10  03001.    BNE PRG000_CF1A ; Jump (technically always) to PRG000_CF1A  03002.   03003. PRG000_CEFD:  03004.    LDY #$00 ; Y = 0  03005.   03006.    LDA <Player_FlipBits  03007.    BNE PRG000_CF04 ; If Player is turned around, jump to PRG000_CF04  03008.   03009.    INY ; Y = 1  03010.   03011. PRG000_CF04:  03012.    LDA Objects_IsGiant,X  03013.    BEQ PRG000_CF0E ; If object is not giant, jump to PRG000_CF0E  03014.   03015.    ; Y += 5  03016.    INY  03017.    INY  03018.    INY  03019.    INY  03020.    INY  03021.   03022. PRG000_CF0E:  03023.    LDA Player_PipeFace  03024.    BEQ PRG000_CF1F ; If Player is NOT "pipe facing" (facing forward in pipe), jump to PRG000_CF1F  03025.   03026.    ; Y += 2  03027.    INY  03028.    INY  03029.   03030.    CMP #$05  03031.    BLT PRG000_CF1A ; If less than 5 ticks remaining on the "pipe face", jump to PRG000_CF1A  03032.   03033.    INY ; Otherwise, Y++  03034.   03035. PRG000_CF1A:  03036.   03037.    ; Set object to occupy Sprite_RAM offset $10  03038.    LDA #$10  03039.    STA Object_SprRAM,X  03040.   03041. PRG000_CF1F:  03042.   03043.    ; Set held object's proper X position  03044.    LDA <Player_X  03045.    ADD ObjectHoldXOff,Y  03046.    STA <Objects_X,X  03047.   03048.    LDA <Player_XHi  03049.    ADC ObjectHoldXHiOff,Y  03050.    STA <Objects_XHi,X  03051.   03052.    LDA #-$02 ; A = -$02  03053.   03054.    LDY Objects_IsGiant,X  03055.    BNE PRG000_CF3D ; If object is giant, jump to PRG000_CF3D  03056.   03057.    LDA #$0d ; A = $0D  03058.   03059.    LDY <Player_Suit  03060.    BNE PRG000_CF3D ; If Player is not small, jump to PRG000_CF3D  03061.   03062.    LDA #$0f ; Otherwise, A = $0F  03063.   03064. PRG000_CF3D:  03065.    PHA ; Save 'A'  03066.   03067.    ; Set Y offset to object being held  03068.    ADD <Player_Y  03069.    STA <Objects_Y,X  03070.   03071.    LDY #$00 ; Y = 0  03072.   03073.    PLA ; Restore 'A'  03074.   03075.    BPL PRG000_CF49 ; If A >= 0 (negative when object was giant), jump to PRG000_CF49  03076.   03077.    DEY ; Y = -1  03078.   03079. PRG000_CF49:  03080.    TYA ; A = 0 or -1  03081.   03082.    ; Apply carry  03083.    ADC <Player_YHi  03084.    STA <Objects_YHi,X  03085.   03086.    ; While held, object's velocities match Player's  03087.    LDA <Player_XVel  03088.    STA <Objects_XVel,X  03089.    LDA <Player_YVel  03090.    STA <Objects_YVel,X  03091.   03092.    JSR Object_WorldDetectN1 ; Detect against world  03093.    JSR Object_CalcSpriteXY_NoHi ; Calculate low parts of sprite X/Y (never off-screen when held by Player!)  03094.    JSR ObjectToObject_HitTest ; Test if this object has collided with another object  03095.    BCC PRG000_CF98 ; If this object did not collide with any other objects, jump to PRG000_CF98  03096.   03097.    LDA Objects_Timer2,X  03098.    ORA Level_PipeMove  03099.    BNE PRG000_CF98 ; If timer 2 is not expired or Player is moving through pipes, jump to PRG000_CF98  03100.   03101.    ; Object colliding sound!  03102.    LDA Sound_QPlayer  03103.    ORA #SND_PLAYERKICK  03104.    STA Sound_QPlayer  03105.   03106.    ; Object which was held is dead!  03107.    LDA #OBJSTATE_KILLED  03108.    STA Objects_State,X  03109.   03110.    ; Y velocity = -$30 (fly up a bit)  03111.    LDA #-$30  03112.    STA <Objects_YVel,X  03113.   03114.    ; Object that got hit is dead!  03115.    LDA #OBJSTATE_KILLED  03116.    STA Objects_State,Y  03117.   03118.    ; Y velocity = -$30 (fly up a bit)  03119.    LDA #-$30  03120.    STA Objects_YVel,Y  03121.   03122.    ; Get 100 pts for the hit!  03123.    LDA #$00  03124.    JSR Score_Get100PlusPts  03125.   03126.    ; Object will not collide again for 16 ticks (dampener I guess)  03127.    LDA #16  03128.    STA Objects_Timer2,X  03129.   03130.    TYA  03131.    TAX  03132.    JSR Level_ObjCalcXDiffs ; Determine which side the OTHER object is on  03133.   03134.    ; Set the OTHER object's X velocity appropriately  03135.    LDA ObjectToObject_HitXVel,Y  03136.    STA <Objects_XVel,X  03137.   03138. PRG000_CF98:  03139.    LDX <SlotIndexBackup ; Restore 'X' to the object slot index  03140.   03141.    LDA <Player_IsDying  03142.    BNE PRG000_CFA5 ; If Player is dying, jump to PRG000_CFA5  03143.   03144.    ; Player is NOT dying...  03145.   03146.    LDA Sprite_RAM+$28  03147.    CMP #$f8  03148.    BEQ PRG000_CFA8 ; ?? If Sprite_RAM+$28 (10th sprite) Y coordinate = $F8 (unused), jump to PRG000_CFA8 ??  03149.   03150. PRG000_CFA5:  03151.    JSR Object_DrawShelled ; Draw shelled object  03152.   03153. PRG000_CFA8:  03154.    RTS ; Return  03155.   03156.   03157.    ; Unused space... deleted code?  03158.    NOP  03159.    NOP  03160.    NOP  03161.    NOP  03162.    NOP  03163.    NOP  03164.    NOP  03165.    NOP  03166.   03167. ObjState_Killed:  03168.    JSR Object_FallAndDelete ; Have object fall and delete if it gets too low (at which point we don't return)  03169.   03170.    LDY ObjGroupRel_Idx ; Y = object's group relative index  03171.   03172.    LDA ObjectGroup_KillAction,Y  03173.    AND #%00001111  03174.    BEQ Object_DoKillAction ; If kill action is zero, jump to Object_DoKillAction (i.e. do NOT set frame 2)  03175.   03176.    CPX #$05  03177.    BGE Object_DoKillAction ; If object slot >= 5 (i.e. not a "general" objects), jump to Object_DoKillAction (i.e. do NOT set frame 2)  03178.   03179.    PHA ; Save kill action  03180.   03181.    LDA #$02  03182.    STA Objects_Frame,X ; Set frame to 2  03183.   03184.    PLA ; Restore kill action  03185.   03186.    ; Do the kill action  03187. Object_DoKillAction:  03188.    JSR DynJump  03189.   03190.    ; THESE MUST FOLLOW DynJump FOR THE DYNAMIC JUMP TO WORK!!  03191.    .word Object_StandardKill ; 0: Standard kill (does not set frame 2)  03192.    .word Object_CalcAndDrawKilled ; 1: Standard sprite draw and kill  03193.    .word Object_DrawMirroredKilled ; 2: Draw mirrored sprite  03194.    .word Object_Draw16x32Killed ; 3: Draw tall sprite  03195.    .word Object_DrawTallHFlipped ; 4: Draw tall object horizontally flipped  03196.    .word Object_NormalAndKilled ; 5: Do "Normal" state and killed action (sinking/vert flip)  03197.    .word Object_GiantKilled ; 6: Giant enemy death  03198.    .word Object_PoofDie ; 7: Do "poof" dying state while killed  03199.    .word Object_DrawAndMoveNotHalt ; 8: Draw and do movements unless gameplay halted  03200.    .word Object_NormalWhileKilled ; 9: Just do "Normal" state while killed  03201.   03202. Object_StandardKill:  03203.    JSR Object_DoHaltedAction  03204.    JMP Object_DoKilledAction  03205.   03206. Object_NormalAndKilled:  03207.    JSR Object_DoNormal  03208.    JMP Object_DoKilledAction  03209.   03210. Object_NormalWhileKilled:  03211.    JMP Object_DoNormal  03212.   03213. Object_GiantKilled:  03214.    JSR ObjectGroup_PatternSets ; Do special draw routine used by "giant" enemies  03215.    JMP Object_DoKilledAction  03216.   03217. Object_PoofDie:  03218.    ; Set object state to 8 ("Poof" Dying)  03219.    LDA #OBJSTATE_POOFDEATH  03220.    STA Objects_State,X  03221.   03222.    ; Set timer to $1F  03223.    LDA #$1f  03224.    STA Objects_Timer,X  03225.   03226.    RTS ; Return  03227.   03228. Object_DrawAndMoveNotHalt:  03229.    JSR Object_ShakeAndDraw  03230.    JMP Object_MoveNotHalted  03231.   03232. Object_DrawTallHFlipped:  03233.    JSR Object_DrawTallAndHFlip  03234.    JMP Object_DoKilledAction  03235.   03236. Object_Draw16x32Killed:  03237.    JSR Object_Draw16x32Sprite  03238.    JMP Object_DoKilledAction  03239.   03240. Object_DrawMirroredKilled:  03241.    JSR Object_ShakeAndDrawMirrored  03242.    JMP Object_DoKilledAction  03243.   03244. Object_CalcAndDrawKilled:  03245.    JSR Object_ShakeAndDraw  03246.   03247.    ; If object was killed by sinking in quicksand or just killed, do this...  03248. Object_DoKilledAction:  03249.    LDA <Player_HaltGame  03250.    BNE PRG000_D054 ; If gameplay is halted, jump to PRG000_D054  03251.   03252.    LDA Objects_QSandCtr,X  03253.    BEQ PRG000_D045 ; If object is not sinking in quicksand, jump to PRG000_D045  03254.   03255.    INC Objects_QSandCtr,X ; Objects_QSandCtr++  03256.   03257.    CMP #$90  03258.    BNE PRG000_D02E ; If Objects_QSandCtr <> $90, jump to PRG000_D02E  03259.   03260.    ; Otherwise, object has sunk long enough; delete it...  03261.    JMP Object_Delete ; Jump to Object_Delete  03262.   03263. PRG000_D02E:  03264.   03265.    ; Slow object descent  03266.    LDA #$04  03267.    STA <Objects_YVel,X  03268.   03269.    JSR Object_ApplyYVel_NoLimit ; Apply Y velocity  03270.   03271.    ; Set sprite priority  03272.    LDA Objects_FlipBits,X  03273.    ORA #SPR_BEHINDBG  03274.    STA Objects_FlipBits,X  03275.   03276.    CPX #$05  03277.    BLT PRG000_D044 ; If object index < 5 (object is a "general" object), jump to PRG000_D044 (RTS)  03278.   03279.    JMP Object_HitTestRespond ; Special object, do hit test/respond  03280.   03281. PRG000_D044:  03282.    RTS ; Return  03283.   03284. PRG000_D045:  03285.   03286.    ; Dead object, not sinking in quicksand  03287.   03288.    ; Vertically flip  03289.    LDA Objects_FlipBits,X  03290.    ORA #SPR_VFLIP  03291.    STA Objects_FlipBits,X  03292.   03293. Object_MoveNotHalted:  03294.    LDA <Player_HaltGame  03295.    BNE PRG000_D054 ; If gameplay halted, jump to PRG000_D054 (RTS)  03296.   03297.    JSR Object_Move ; Perform standard object movements  03298.   03299. PRG000_D054:  03300.    RTS ; Return  03301.   03302.   03303.    ; If killed object falls too low, delete it  03304. Object_FallAndDelete:  03305.    LDA Level_7Vertical  03306.    BEQ PRG000_D060 ; If level is NOT vertical, jump to PRG000_D060  03307.   03308.    ; In vertical level...  03309.   03310.    LDA <Objects_SpriteY,X  03311.    CMP #200  03312.    BLT PRG000_D054 ; If object Y < 200, jump to PRG000_D054 (RTS)  03313.   03314. PRG000_D060:  03315.    LDA <Objects_YHi,X  03316.    CMP #$02  03317.    BLS PRG000_D054 ; If object Y Hi < 2 (way low), jump to PRG000_D054  03318.   03319.    ; Do NOT return to caller!  03320.    PLA  03321.    PLA  03322.   03323. PRG000_D068:  03324.    JMP Object_SetDeadEmpty ; Jump to Object_SetDeadEmpty  03325.   03326. ObjState_Squashed:  03327.    LDA Objects_Timer3,X  03328.    BEQ PRG000_D090 ; If timer 3 is expired, jump to PRG000_D090  03329.   03330.    JSR Object_Move ; Perform standard object movements  03331.   03332.    LDA <Objects_DetStat,X  03333.    AND #$04  03334.    BEQ PRG000_D07E ; If object did NOT hit ground, jump to PRG000_D07E  03335.   03336.    JSR Object_HitGround ; Align to ground  03337.    STA <Objects_XVel,X ; Clear X velocity  03338.   03339. PRG000_D07E:  03340.   03341.    ; Set object frame to 3  03342.    LDA #$03  03343.    STA Objects_Frame,X  03344.   03345.    LDA Level_ObjectID,X  03346.    CMP #OBJ_GOOMBA  03347.    BNE PRG000_D08D ; If object is not a goomba, jump to PRG000_D08D (ObjectGroup_PatternSets, i.e. the "giant" enemy alternative)  03348.   03349.    JMP Object_ShakeAndDrawMirrored ; Draw goomba as mirrored sprite and don't come back  03350.   03351. PRG000_D08D:  03352.    JMP ObjectGroup_PatternSets ; Do the giant enemy draw routine and don't come back  03353.   03354. PRG000_D090:  03355.    JMP Object_SetDeadEmpty ; Jump to Object_SetDeadEmpty (mark object as dead/empty)  03356.   03357. Object_MaxFalls:  03358.    .byte OBJECT_MAXFALL, OBJECT_MAXFALLINWATER  03359.   03360.    ; Gravity of object  03361. Object_Gravity:  03362.    .byte OBJECT_FALLRATE, OBJECT_FALLRATEINWATER  03363.   03364. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03365. ; Object_Move  03366. ;  03367. ; Links all code together to move an object with velocity  03368. ; including intersecting with the world etc.  03369. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03370. ; $D097  03371. Object_Move:  03372.    LDA <Objects_XVel,X ; Get Object's X velocity  03373.    PHA ; Save it  03374.   03375.    LDY Objects_InWater,X  03376.    BEQ PRG000_D0A9 ; If object is not in water, jump to PRG000_D0A9  03377.   03378.    LDY Objects_State,X  03379.    CPY #OBJSTATE_NORMAL  03380.    BEQ PRG000_D0A9 ; If object's state is Normal, jump to PRG000_D0A9  03381.   03382.    ; This is basically an pseudo-ASR, a right shift preserving the sign  03383.    ASL A ; Bit 7 pushed into carry  03384.    ROR <Objects_XVel,X ; X velocity rotated right (divided by 2) and proper sign of bit 7 in place  03385.   03386. PRG000_D0A9:  03387.    JSR Object_ApplyXVel ; Applies object's X velocity  03388.   03389.    PLA ; Restore Object's X velocity  03390.   03391.    STA <Objects_XVel,X ; Undoes Object_ApplyXVel  03392.   03393.    JSR Object_ApplyYVel_NoLimit ; Apply Y velocity without limit  03394.   03395.    JSR Object_WorldDetect4 ; Detect against the world  03396.   03397.    LDY Objects_InWater,X ; Y = whether in-water  03398.   03399.    LDA <Objects_YVel,X  03400.    BPL PRG000_D0CA ; If object is object is still or moving downward, jump to PRG000_D0CA  03401.   03402.    ; Object is moving upward...  03403.   03404.    CPY #$00  03405.    BEQ PRG000_D0CA ; If object is NOT in water, jump to PRG000_D0CA  03406.   03407.    CMP #OBJECT_MAXWATERUPWARD  03408.    BGE PRG000_D0CA ; If object's Y velocity is between OBJECT_MAXWATERUPWARD and 0, jump to PRG000_D0CA  03409.   03410.    LDA #OBJECT_MAXWATERUPWARD  03411.    STA <Objects_YVel,X ; Otherwise, cut off velocity at OBJECT_MAXWATERUPWARD  03412.   03413.    BNE PRG000_D0CA ; Jump (technically always) to PRG000_D0CA (uhh... pointless, heh)  03414.   03415. PRG000_D0CA:  03416.    LDA <Objects_YVel,X  03417.    ADD Object_Gravity,Y  03418.    STA <Objects_YVel,X ; Apply gravity to object  03419.   03420.    BMI PRG000_D0DE ; If Y velocity is negative, jump to PRG000_D0DE (RTS)  03421.   03422.    CMP Object_MaxFalls,Y  03423.    BLT PRG000_D0DE ; If object is not falling at the max rate, jump to PRG000_D0DE (RTS)  03424.   03425.    LDA Object_MaxFalls,Y  03426.    STA <Objects_YVel,X ; Cap fall at max rate  03427.   03428. PRG000_D0DE:  03429.    RTS ; Return  03430.   03431. ObjectHeld_WakeUpDir: .byte $40, $00  03432.   03433.    ; Handle shelled object "waking up" from a shelled state, if timer 3 expired...  03434. Object_ShellDoWakeUp:  03435.   03436.    ; If object is a Bob-omb, jump to PRG000_D0EC, otherwise jump to PRG000_D101  03437.    LDA Level_ObjectID,X  03438.    CMP #OBJ_BOBOMBEXPLODE  03439.    BEQ PRG000_D0EC  03440.    CMP #OBJ_BOBOMB  03441.    BNE PRG000_D101  03442.   03443. PRG000_D0EC:  03444.   03445.    ; A Bob-omb only...  03446.   03447.    LDA Objects_Timer,X  03448.    BNE PRG000_D0F9 ; If timer is not expired, jump to PRG000_D0F9  03449.   03450.    ; Timer expired, change to state 2 (Normal)  03451.    LDA #OBJSTATE_NORMAL  03452.    STA Objects_State,X  03453.    JMP BobOmb_Explode ; Jump to BobOmb_Explode and don't come back!  03454.   03455. PRG000_D0F9:  03456.    CMP #$40  03457.    BGE PRG000_D100 ; If timer ticks >= $40, jump to PRG000_D100 (RTS)  03458.   03459.    STA Objects_ColorCycle,X ; In the last timer ticks, flash colors!  03460.   03461. PRG000_D100:  03462.    RTS ; Return  03463.   03464. PRG000_D101:  03465.   03466.    ; Anything besides a Bob-omb...  03467.   03468.    CMP #OBJ_ICEBLOCK  03469.    BNE PRG000_D120 ; If object is NOT an Ice Block, jump to PRG000_D120  03470.   03471.    ; Object is an ice block...  03472.   03473.    LDA Objects_Timer3,X  03474.    BNE PRG000_D10D ; If timer 3 is not expired, jump to PRG000_D10D  03475.   03476.    ; Timer 3 expired...  03477.   03478.    JMP Object_PoofDie ; Jump to Object_PoofDie (Set state to 8 ["Poof" Dying] and set timer)  03479.   03480.   03481.    ; Basically from here to the RTS, color cycle the ice block as it begins to "melt"  03482.    ; at different rates depending on where the timer is exactly...  03483. PRG000_D10D:  03484.    CMP #$60  03485.    BGE PRG000_D11C ; If timer 3 ticks >= $60, jump to PRG000_D11C  03486.   03487.    CMP #$30  03488.    BGE PRG000_D11B ; If timer 3 ticks >= $30, jump to PRG000_D11B  03489.   03490.    CMP #$10  03491.    BGE PRG000_D11A ; If timer 3 ticks >= $10, jump to PRG000_D11A  03492.   03493.    LSR A  03494.   03495. PRG000_D11A:  03496.    LSR A  03497.   03498. PRG000_D11B:  03499.    LSR A  03500.   03501. PRG000_D11C:  03502.    STA Objects_ColorCycle,X ; Set color cycle value  03503.   03504.    RTS ; Return  03505.   03506.   03507. PRG000_D120:  03508.   03509.    ; Object is not a Bob-omb and not an Ice Block...  03510.   03511.    LDA Objects_Timer3,X  03512.    BNE PRG000_D15A ; If timer 3 is not expired, jump to PRG000_D15A (RTS)  03513.   03514.    LDA Objects_State,X  03515.    CMP #OBJSTATE_HELD  03516.    BNE PRG000_D147 ; If object is not currently being held, jump to PRG000_D147  03517.   03518.    ; Object is being held...  03519.   03520.    JSR Object_WorldDetectN1  03521.    LDA <Objects_DetStat,X  03522.    BEQ PRG000_D147 ; If held object did not impact anything, jump to PRG000_D147  03523.   03524.    ; Held object impacted...  03525.   03526.    ; Get 100 points  03527.    LDA #$05  03528.    JSR Score_PopUp  03529.   03530.    ; Set object state to Killed  03531.    LDA #OBJSTATE_KILLED  03532.    STA Objects_State,X  03533.   03534.    ; Set object Y velocity to -$40 (fly up after death)  03535.    LDA #-$40  03536.    STA <Objects_YVel,X  03537.   03538.    ; Halt horizontal movement  03539.    LDA #$00  03540.    STA <Objects_XVel,X  03541.   03542.    BEQ PRG000_D155 ; Jump (technically always) to PRG000_D155  03543.   03544. PRG000_D147:  03545.   03546.    ; Held object did NOT impact... (time to wake up!)  03547.   03548.    ; Set object state to Normal  03549.    LDA #OBJSTATE_NORMAL  03550.    STA Objects_State,X  03551.   03552.    ; Have object "wake up" towards Player!  03553.    JSR Level_ObjCalcXDiffs  03554.    LDA ObjectHeld_WakeUpDir,Y  03555.    STA Objects_FlipBits,X  03556.   03557. PRG000_D155:  03558.   03559.    ; Do NOT return to caller!  03560.    PLA  03561.    PLA  03562.   03563.    JMP PRG000_CB5E ; Jump to PRG000_CB5E (essentially JSR Object_DeleteOffScreen)  03564.   03565. PRG000_D15A:  03566.    RTS ; Return  03567.   03568.   03569. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03570. ; Object_AboutFace  03571. ;  03572. ; Object reverses travel and facing direction  03573. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03574. ; $D15B  03575. Object_AboutFace:  03576.    LDA <Objects_XVel,X  03577.    JSR Negate  03578.    STA <Objects_XVel,X ; Negate object's X velocity  03579.   03580. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03581. ; Object_FlipFace  03582. ;  03583. ; Object reverses facing direction  03584. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03585. ; $D162  03586. Object_FlipFace:  03587.    LDA Objects_FlipBits,X  03588.    EOR #SPR_HFLIP  03589.    STA Objects_FlipBits,X ; Flip left/right flag  03590.   03591.    RTS ; Return  03592.   03593. PRG000_D16B: .byte -$08, $08  03594.   03595.   03596. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03597. ; Object_HandleBumpUnderneath  03598. ;  03599. ; Handles an object getting killed or shelled when hit from under  03600. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03601. ; $D16D  03602. Object_HandleBumpUnderneath:  03603.    JSR Object_AnySprOffscreen  03604.    BNE PRG000_D1C4 ; If any sprite is off-screen, jump to PRG000_D1C4 (RTS)  03605.   03606.    LDA Object_TileFeet2  03607.    CMP #TILEA_BLOCKBUMP_CLEAR  03608.    BNE Player_HitEnemy ; If object did not detect a block bump clear tile, jump to Player_HitEnemy  03609.   03610.    ; Object detected a block bump tile (object got bumped)  03611.   03612.    ; Set Y Vel to -$30 (bounce dead)  03613.    LDA #-$30  03614.    STA <Objects_YVel,X  03615.   03616.    JSR Level_ObjCalcXDiffs ; Detect which side object is on versus Player  03617.   03618.    ; Store proper X velocity  03619.    LDA PRG000_D16B,Y  03620.    STA <Objects_XVel,X  03621.   03622.    ; Vertically flip object  03623.    LDA #SPR_VFLIP  03624.    STA Objects_FlipBits,X  03625.   03626.    LDY ObjGroupRel_Idx  03627.    LDA ObjectGroup_Attributes3,Y  03628.    AND #OA3_DIESHELLED  03629.    BNE PRG000_D19E ; If OA3_DIESHELLED is SET (object may use special routine), jump to PRG000_D19E  03630.   03631.    ; Object killed, get 100 pts  03632.   03633.    LDA #OBJSTATE_KILLED  03634.    STA Objects_State,X  03635.   03636.    LDA #$00  03637.    JMP Score_Get100PlusPts ; Jump to Score_Get100PlusPts and don't come back!  03638.   03639. PRG000_D19E:  03640.    LDA ObjGroupRel_Idx  03641.    ASL A  03642.    TAY ; Y = 2-byte index into CollideJumpTable  03643.   03644.   03645.    LDA ObjectGroup_CollideJumpTable+1,Y ; Get the CollideJumpTable upper byte  03646.    AND #%11111000  03647.    CMP #%00001000  03648.    BNE PRG000_D1B7 ; If the upper byte is not ($08xx - $0Fxx), jump to PRG000_D1B7  03649.   03650.    ; SPECIAL JUMP TABLE VALUE ($08xx - $0Fxx): Change to alternate object  03651.   03652.    ; Change to alternate ObjectID in low byte  03653.    LDA ObjectGroup_CollideJumpTable,Y  03654.    STA Level_ObjectID,X  03655.   03656.    ; Get 100 pts  03657.    LDA #$00  03658.    JSR Score_Get100PlusPts  03659.   03660. PRG000_D1B7:  03661.    JMP Object_SetShellState ; Jump to Object_SetShellState ("dies" into shelled state)  03662.   03663. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03664. ; Player_HitEnemy  03665. ;  03666. ; General routine for how the object responds to a Player  03667. ; colliding with it (good and bad)  03668. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  03669. ; $D1BA  03670. Player_HitEnemy:  03671.    JSR Object_HitTest ; Check for collision  03672.   03673.    ; Clear hit status bits  03674.    LDA #$00  03675.    STA Objects_PlayerHitStat,X  03676.   03677.    BCS PRG000_D1C5 ; If collision occurred, jump to PRG000_D1C5  03678.   03679. PRG000_D1C4:  03680.    RTS ; Return  03681.   03682. PRG000_D1C5:  03683.    LDA Objects_Timer2,X  03684.    BNE PRG000_D1C4 ; If timer 2 hasn't expired, jump to PRG000_D1C4 (RTS)  03685.   03686.    ; Timer 2 has expired...  03687.   03688.    LDA Player_Slide  03689.    BNE PRG000_D1DB ; If Player is sliding, jump to PRG000_D1DB  03690.   03691.    ; Player is not sliding...  03692.   03693.    LDY ObjGroupRel_Idx ; Y = object group relative index  03694.    LDA ObjectGroup_Attributes2,Y ; Get attributes set 2  03695.    AND #OA2_GNDPLAYERMOD  03696.    BEQ PRG000_D218 ; If OA2_GNDPLAYERMOD not set, jump to PRG000_D218  03697.    BNE PRG000_D205 ; Otherwise, jump to PRG000_D205  03698.   03699. PRG000_D1DB:  03700.   03701.    ; Player is sliding...  03702.   03703.    JSR PRG000_D218 ; Also include code like attribute set 2 bit 1 is set  03704.   03705.    LDA Objects_State,X  03706.    CMP #OBJSTATE_NORMAL  03707.    BEQ PRG000_D204 ; If object state is Normal, jump to PRG000_D204 (RTS)  03708.   03709.    STA <Temp_Var4 ; Otherwise, store current state into Temp_Var4  03710.   03711.    JSR Enemy_Kill ; Kill enemy  03712.   03713.    LDA RandomN,X  03714.    AND #$1f ; Cap 0-31  03715.    ADC #-$4C  03716.    STA <Objects_YVel,X ; Object Y Vel = -$2D to -$4C  03717.   03718.    ; Set object state to Killed  03719.    LDA #OBJSTATE_KILLED  03720.    STA Objects_State,X  03721.   03722.    LDA <Player_XVel ; Get Player X velocity  03723.    STA <Temp_Var1 ; -> Temp_Var1 (yyyy xxxx)  03724.    ASL <Temp_Var1 ; Shift 1 bit left (bit 7 into carry) (y yyyx xxx0)  03725.    ROR A ; A is now arithmatically shifted to the right (yyyyy xxx) (signed division by 2)  03726.    ADD <Objects_XVel,X ; Add the existing velocity to this (so object velocity is influenced by half Player velocity)  03727.    STA <Objects_XVel,X ; -> Object's X velocity  03728.   03729. PRG000_D204:  03730.    RTS ; Return  03731.   03732.   03733. PRG000_D205:  03734.   03735.    ; Object attribute set 2 bit 1 is set...  03736.   03737.    ; What does this do?  03738.    ; First off, Player must be on solid ground  03739.    ; Then, either the object is falling faster than $0A OR the object is on the ground  03740.    ; In those cases, we jump to Object_HoldKickOrHurtPlayer  03741.   03742.    ; The only real apparent function here is that a fast-falling or grounded object  03743.    ; will force into the "Hold, Kick, or Hurt Player" routine without doing the  03744.    ; the other checks, but with the Player being on the ground, it's hard for him  03745.    ; not to get hit anyway. As such, I can't really for sure tell what the  03746.    ; intention of this code was really supposed to be??  03747.   03748.    ; Otherwise it is PRG000_D218  03749.   03750.    LDA <Player_InAir  03751.    BNE PRG000_D218 ; If Player is mid air, jump to PRG000_D218  03752.   03753.    ; Player is on solid ground...  03754.   03755.    LDA <Objects_YVel,X  03756.    CMP #$0a  03757.    BLS PRG000_D212 ; If Object's Y velocity < $0A, jump to PRG000_D212  03758. PRG000_D20F:  03759.    JMP Object_HoldKickOrHurtPlayer ; Otherwise, jump to Object_HoldKickOrHurtPlayer  03760.   03761. PRG000_D212:  03762.   03763.    ; Object's Y velocity < $0A ...  03764.   03765.    LDA <Objects_DetStat,X  03766.    AND #$04  03767.    BNE PRG000_D20F ; If object has hit ground, jump to PRG000_D20F (to Object_HoldKickOrHurtPlayer)  03768.   03769. PRG000_D218:  03770.   03771.    ; Object attribute set 2 bit 1 not set...  03772.    ; OR Player is mid-air...  03773.    ; OR Player is sliding...  03774.   03775.    ; Remember, this is after the bounding boxes have already been used  03776.    ; to determine there's some kind of collision; we're just find tuning  03777.    ; if this is a successful "stomp" or not...  03778.    ;  03779.    ; 'Y' represents the "height" of the object for collision detection  03780.    ; The way to think about this is we're going to reference Objects_Y  03781.    ; which in SMB3 is generally the "top" of the enemy, or in any case  03782.    ; point at which "stomp" should occur. (Of note, Koopa Troopa's  03783.    ; "top" is their shell; the head is drawn as a negative coordinate  03784.    ; from that point.) The judgement is based on Player_Y, which is the  03785.    ; "top" of the Player (note for "Super" Mario, that's near the hat,  03786.    ; but for "small" Mario, that's roughly 16 pixels above.)  03787.    ;  03788.    ; G = Goomba (for example)  03789.    ;  03790.    ; . <-- This would be 19 (for this example) pixels above  03791.    ; |  03792.    ; G <-- top of 'Goomba' is Objects_Y  03793.    ;  03794.    ; . m <-- Top of Player must be beneath the 19 pixel offset  03795.    ; | M  03796.    ; G  03797.    ;  03798.    ; ... if the above is true, that's considered "stompable" range.  03799.   03800.    LDY #17 ; Y = 17 (the following two objects)  03801.   03802.    LDA Level_ObjectID,X  03803.    CMP #OBJ_PILEDRIVER  03804.    BEQ PRG000_D22E ; If object is a pile driver microgoomba, jump to PRG000_D22E  03805.   03806.    CMP #OBJ_CHEEPCHEEPHOPPER  03807.    BEQ PRG000_D22E ; If object is a hopping Cheep Cheep jump to PRG000_D22E  03808.   03809.    LDY #19 ; Y = 19 (anything else, unless object is giant)  03810.   03811.    LDA Objects_IsGiant,X  03812.    BEQ PRG000_D22E ; If object is not giant, jump to PRG000_D22E  03813.   03814.    LDY #8 ; Y = 8 (not the first two, if object is giant set)  03815.   03816. PRG000_D22E:  03817.    STY <Temp_Var2 ; -> Temp_Var2 (height above object considered "stompable" range)  03818.   03819.    LDA <Objects_Y,X ; Get object's Y  03820.    SUB <Temp_Var2 ; Subtract Temp_Var2 (height above object considered "stompable" range)  03821.    ROL <Temp_Var1 ; Stores the carry bit into Temp_Var1 bit 0  03822.    CMP <Player_Y  03823.   03824.    PHP ; Save CPU state (the comparison)  03825.   03826.    LSR <Temp_Var1 ; Restore the carry bit  03827.    LDA <Objects_YHi,X  03828.    SBC #$00 ; Apply the carry bit to the Objects_YHi as needed for the height subtraction  03829.   03830.    PLP ; Restore CPU state (the comparison)  03831.   03832.    SBC <Player_YHi ; Get the difference against the Player_YHi  03833.    BMI PRG000_D20F ; If negative (Player_YHi > Objects_YHi, Player is lower), jump to PRG000_D20F (Object_HoldKickOrHurtPlayer)  03834.   03835.    LDA <Player_YVel  03836.    BPL PRG000_D253 ; If Player's Y Velocity >= 0 (stationary or moving downward), jump to PRG000_D253  03837.   03838.    ; Player is moving upward...  03839.   03840.    LDA Player_FlyTime  03841.    BNE PRG000_D253 ; If Player is flying, jump to PRG000_D253  03842.   03843.    ; Player moving upward, not flying...  03844.   03845.    LDA Kill_Tally  03846.    BEQ PRG000_D20F ; If Player hasn't killed anything yet, jump to PRG000_D20F (Object_HoldKickOrHurtPlayer)  03847.   03848. PRG000_D253:  03849.   03850.    ; Player hit from top bit  03851.    LDA #$01  03852.    STA Objects_PlayerHitStat,X  03853.   03854.    LDA Player_InWater  03855.    BNE PRG000_D267 ; If Player is in water, jump to PRG000_D267  03856.   03857.    LDY ObjGroupRel_Idx ; Y = group relative index  03858.    LDA ObjectGroup_Attributes3,Y ; Get object's attribute 3 setting  03859.    AND #OA3_NOTSTOMPABLE  03860.    BEQ PRG000_D272 ; If OA3_NOTSTOMPABLE NOT set (Object is stompable), jump to PRG000_D272  03861.   03862. PRG000_D267:  03863.   03864.    ; Player is in water (can't stomp in water) OR attribute 3 bit 5 is set (can't stomp anyway)...  03865.   03866.    LDA Player_Kuribo  03867.    ORA Player_Statue  03868.    BNE PRG000_D272 ; If in Kuribo's shoe or transformed into statue, ignore this and jump to PRG000_D272  03869.   03870.    JMP PRG000_D355 ; Jump to PRG000_D355 (hurt Player!)  03871.   03872. PRG000_D272:  03873.   03874.    ; Enemy got stomped!  03875.   03876.    LDY ObjGroupRel_Idx ; Y = group relative index  03877.    LDA ObjectGroup_Attributes2,Y ; Get object attribute set 2  03878.    AND #OA2_STOMPDONTCARE  03879.    BNE PRG000_D2B3 ; If OA2_STOMPDONTCARE is set (object is indifferent about stomping), jump to PRG000_D2B3 (RTS)  03880.   03881.    ; Attribute set 2 bit 2 NOT set... (object cares about being stomped)  03882.   03883.    LDA Player_Statue  03884.    ORA Player_Kuribo  03885.    BEQ PRG000_D29B ; If Player is NOT a statue and NOT in a Kuribo's shoe, jump to PRG000_D29B  03886.   03887.    ; Player is a statue or in a Kuribo's shoe...  03888.   03889.    JSR PRG000_D2B4 ; Handle stomp!  03890.   03891.    LDY ObjGroupRel_Idx ; Y = object group relative index  03892.    LDA ObjectGroup_Attributes3,Y ; Get attribute set 3  03893.    AND #OA3_SQUASH  03894.    BEQ PRG000_D295 ; If OA3_SQUASH NOT set, jump to PRG000_D295 (kill it)  03895.   03896.    ; When stomped by statue/Kuribo, if the enemy was going to get squashed anyway  03897.    ; then go ahead into "shelled" state which redirects to "stomped" state.  03898.   03899.    LDA #OBJSTATE_SHELLED ; Otherwise, state is Shelled  03900.    BNE PRG000_D297 ; Jump (technically always) to PRG000_D297  03901.   03902. PRG000_D295:  03903.   03904.    ; When stomped by statue/Kuribo, if the enemy was going to actually going to  03905.    ; become shelled, kill it instead...  03906.   03907.    LDA #OBJSTATE_KILLED ; State is Killed  03908.   03909. PRG000_D297:  03910.    STA Objects_State,X ; Set appropriate object state  03911.   03912.    RTS ; Return  03913.   03914.   03915. PRG000_D29B:  03916.   03917.    ; Player NOT a statue and NOT in a Kuribo's shoe stomp code  03918.   03919.    LDA Objects_State,X  03920.    CMP #OBJSTATE_SHELLED  03921.    BNE PRG000_D2B4 ; If object state is not shelled, jump to PRG000_D2B4 (typical stomp)  03922.   03923. PRG000_D2A2:  03924.   03925.    ; Enemy is in a shell...  03926.   03927.    LDA Kill_Tally  03928.    INC Kill_Tally ; Use Kill_Tally +1  03929.    JSR Score_Get100PlusPts ; Get points for the kick  03930.    JSR Player_KickObject ; Player kicks the enemy!  03931.   03932.    ; Clear Player kick  03933.    LDA #$00  03934.    STA Player_Kick  03935.   03936. PRG000_D2B3:  03937.    RTS ; Return  03938.   03939.   03940. PRG000_D2B4:  03941.   03942.    ; Set timer 2 to 8  03943.    LDA #$08  03944.    STA Objects_Timer2,X  03945.   03946.    ; Set Player's Y velocity to -$40 (bounce!)  03947.    LDA #-$40  03948.    STA <Player_YVel  03949.   03950.    ; Play squish sound  03951.    LDA Sound_QPlayer  03952.    ORA #SND_PLAYERSWIM  03953.    STA Sound_QPlayer  03954.   03955.    DEC Objects_HitCount,X ; HitCount--  03956.    BPL PRG000_D2B3 ; If hits remain, jump to PRG000_D2B3 (RTS)  03957.   03958.    LDA ObjGroupRel_Idx ; A = object group relative index  03959.    ASL A ; Shift left 1 (2 byte index)  03960.    PHA ; Save this  03961.   03962.    TAY ; -> 'Y'  03963.    LDA ObjectGroup_CollideJumpTable+1,Y ; Get the CollideJumpTable upper byte  03964.   03965.    AND #%11110100  03966.    CMP #%00000100  03967.    BNE PRG000_D2E1 ; If the upper byte is not ($04xx - $07xx), jump to PRG000_D2E1  03968.   03969.    ; SPECIAL JUMP TABLE VALUE ($04xx - $07xx): High scoring  03970.   03971.    ; In this case, Kill_Tally will be boosted by 4 (+1) instead of just +1  03972.    LDA Kill_Tally  03973.    ADD #$04  03974.    BNE PRG000_D2E4  03975.   03976. PRG000_D2E1:  03977.    LDA Kill_Tally ; Otherwise, just get Kill_Tally  03978.   03979. PRG000_D2E4:  03980.    INC Kill_Tally ; Kill_Tally++  03981.    JSR Score_Get100PlusPts ; Get proper score award  03982.   03983.    PLA ; Restore index into CollideJumpTable  03984.    TAY ; -> 'Y'  03985.   03986.    LDA ObjectGroup_CollideJumpTable+1,Y ; Get the CollideJumpTable upper byte  03987.    AND #%11111000  03988.    CMP #%00001000  03989.    BNE PRG000_D301 ; If the upper byte is not ($08xx - $0Fxx), jump to PRG000_D301  03990.   03991.    ; SPECIAL JUMP TABLE VALUE ($08xx - $0Fxx): Change to alternate object  03992.   03993.    ; Change to alternate ObjectID in low byte  03994.    LDA ObjectGroup_CollideJumpTable,Y  03995.    STA Level_ObjectID,X  03996.   03997.    INC Objects_HitCount,X ; Give hit back (restore to zero)  03998.    JMP PRG000_D31E ; Jump to PRG000_D31E  03999.   04000. PRG000_D301:  04001.    LDY ObjGroupRel_Idx ; Y = object group relative index  04002.    LDA ObjectGroup_Attributes2,Y ; Get object attributes set 2  04003.    AND #OA2_NOSHELLORSQUASH  04004.    BEQ PRG000_D323 ; If OA2_NOSHELLORSQUASH is NOT set (shelled enemy), jump to PRG000_D323  04005.   04006.    ; Cancel the "Squish" sound, use the "kick" sound instead!  04007.    LDA Sound_QPlayer  04008.    AND #~SND_PLAYERSWIM  04009.    ORA #SND_PLAYERKICK  04010.    STA Sound_QPlayer  04011.   04012.    ; Set object state to 6 (killed)  04013.    LDA #OBJSTATE_KILLED  04014.    STA Objects_State,X  04015.   04016.    ; Halt horizontal movement  04017.    LDA #$00  04018.    STA <Objects_XVel,X  04019.   04020. PRG000_D31E:  04021.    ; Halt vertical movement  04022.    LDA #$00  04023.    STA <Objects_YVel,X  04024.   04025.    RTS ; Return  04026.   04027. PRG000_D323:  04028.    INC Objects_HitCount,X ; Give hit back (restore to zero)  04029.   04030. Object_SetShellState:  04031.    ; Set Objects_State to Shelled  04032.    LDA #OBJSTATE_SHELLED  04033.    STA Objects_State,X  04034.   04035.    ; Set timer 3 = $FF (wake up timer)  04036.    LDA #$ff  04037.    STA Objects_Timer3,X  04038.   04039.    RTS ; Return  04040.   04041.   04042. Object_HoldKickOrHurtPlayer:  04043.   04044.    LDA Objects_State,X  04045.    CMP #OBJSTATE_SHELLED  04046.    BNE PRG000_D355 ; If object state is not Shelled, jump to PRG000_D355 (hurt Player!)  04047.   04048.    LDA Player_Kuribo  04049.    ORA Player_Statue  04050.    BEQ PRG000_D343 ; If Player is NOT in Kuribo's shoe and NOT in a statue, jump to PRG000_D343  04051.    JMP PRG000_D2A2 ; Otherwise, jump to PRG000_D2A2  04052.   04053. PRG000_D343:  04054.    LDA Player_ISHolding_OLD  04055.    BNE PRG000_D39F ; If Player WAS holding something, jump to PRG000_D39F (RTS)  04056.   04057.    BIT <Pad_Holding  04058.    BVS PRG000_D34F ; If Player is holding B, jump to PRG000_D34F  04059.    JMP Player_KickObject ; Kick away the object and don't come back!  04060.   04061. PRG000_D34F:  04062.   04063.    ; Keep held object in state 4 (Held)  04064.    LDA #OBJSTATE_HELD  04065.    STA Objects_State,X  04066.   04067.    RTS ; Return  04068.   04069.   04070. PRG000_D355:  04071.   04072.    ; Player potentially gonna get hurt!  04073.   04074.    LDA Player_FlashInv ; If Player is flashing from getting hit recently...  04075.    ORA Player_Statue ; ... or Player is a statue ...  04076.    ORA Objects_Timer2,X ; ... or this object's timer2 is not expired ...  04077.    ORA Player_StarInv ; ... or Player is invincible by Star Man ...  04078.    BNE PRG000_D39F ; ... then jump to PRG000_D39F (RTS)  04079.   04080.    LDA Objects_State,X  04081.    CMP #OBJSTATE_KICKED  04082.    BNE PRG000_D382 ; If object's state is not Kicked, jump to PRG000_D382  04083.   04084.    LDY #$00 ; Y = 0  04085.   04086.    LDA <Player_XVel  04087.    BEQ PRG000_D382 ; If Player is not moving horizontally, jump to PRG000_D382  04088.    BPL PRG000_D373 ; If Player is moving to the right, jump to PRG000_D373  04089.   04090.    INY ; Otherwise, Y = 1  04091.   04092. PRG000_D373:  04093.    STY <Temp_Var1 ; Temp_Var1 = 0 (Player moving left) or 1 (Player moving right)  04094.   04095.    EOR <Objects_XVel,X ; Check for X velocity sign difference between Player and object  04096.    BMI PRG000_D382 ; If there's a difference in sign, jump to PRG000_D382  04097.   04098.    ; Object and Player are moving in the same horizontal direction...  04099.   04100.    JSR Level_ObjCalcXDiffs  04101.    CPY <Temp_Var1  04102.    BNE PRG000_D39F ; If Player is moving away from object, jump to PRG000_D39F  04103.    BEQ PRG000_D39C ; Otherwise, jump to PRG000_D39C  04104.   04105. PRG000_D382:  04106.    LDY Level_ObjectID,X ; Y = object's ID  04107.   04108.    LDA Object_AttrFlags,Y  04109.    AND #OAT_BOUNCEOFFOTHERS  04110.    BEQ PRG000_D39C ; If OAT_BOUNCEOFFOTHERS is NOT set (turn around when hit), jump to PRG000_D39C  04111.   04112.    JSR Level_ObjCalcXDiffs  04113.   04114.    LDA Objects_FlipBits,X  04115.    AND #~SPR_HFLIP ; Clear horizontal flip  04116.    DEY  04117.    BEQ PRG000_D399  04118.    ORA #SPR_HFLIP ; Set horizontal flip  04119. PRG000_D399:  04120.    STA Objects_FlipBits,X ; Update object flip bits as necessary  04121.   04122. PRG000_D39C:  04123.    JMP Player_GetHurt ; Hurt Player and don't come back!  04124.   04125. PRG000_D39F:  04126.    RTS ; Return  04127.   04128.    ; A very popular RTS @ $D3A0  04129. ObjState_DeadEmpty:  04130. ObjInit_DoNothing:  04131. ObjNorm_DoNothing:  04132. ObjHit_DoNothing:  04133. ObjHalt_DoNothing:  04134. LevelEvent_DoNothing:  04135.    RTS ; Return  04136.   04137.    ; Called for an object in state 1 to perform initialization logic  04138. ObjState_Initializing:  04139.    JSR Level_PrepareNewObject ; Prepare the object  04140.   04141.    INC Objects_State,X ; Set object state to 2 (Normal run)  04142.    JSR Object_SetPaletteFromAttr ; Set object's palette  04143.   04144.    LDA ObjGroupRel_Idx ; Get object's group relative index  04145.    ASL A ; Shift left 1 (2 byte index)  04146.    TAY ; -> Y  04147.   04148.    ; Get jump address specific to this object  04149.    LDA ObjectGroup_InitJumpTable,Y  04150.    STA <Temp_Var1  04151.    LDA ObjectGroup_InitJumpTable+1,Y  04152.    STA <Temp_Var2  04153.    JMP [Temp_Var1] ; Dynamically jump to object's init routine  04154.   04155.    ; Set object's palette value  04156. ; $D3BC  04157. Object_SetPaletteFromAttr:  04158.    LDY ObjGroupRel_Idx ; Y = object's relative group index  04159.    LDA ObjectGroup_Attributes,Y ; Get attributes  04160.    AND #OA1_PALMASK ; Keep only bits 0 and 1 (palette)  04161.    STA Objects_SprAttr,X ; Set this object's palette  04162.    RTS ; Return  04163.   04164.   04165. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04166. ; Object_DeleteOffScreen  04167. ;  04168. ; The routine that removes objects if they go off-screen  04169. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04170.    ; Vertical level  04171. PRG000_D3C8: .byte $40, $B0 ; Lo  04172. PRG000_D3CA: .byte $01, $FF ; Hi  04173.   04174.    ; Non-vertical level -- selectable remove sizes  04175. PRG000_D3CC: .byte $20, $D0, $80, $80, $40, $B0 ; Lo  04176. PRG000_D3D2: .byte $01, $FF, $01, $FF, $01, $FF ; Hi  04177.   04178.    ; The different "N" varieties specify how wide before the deletion occurs  04179.   04180.    ; $D3D8  04181. Object_DeleteOffScreen_N4:  04182.    LDA #$04 ; A = 4  04183.    BNE PRG000_D3EF ; Jump (technically always) to PRG000_D3EF  04184.   04185.    ; $D3DC  04186. Object_DeleteOffScreen_N2:  04187.    LDA #$02 ; A = 2  04188.    BNE PRG000_D3EF ; Jump (technically always) to PRG000_D3EF  04189.   04190.    ; $D3E0  04191. Object_DeleteOffScreen:  04192.    LDA Objects_UseShortHTest,X  04193.    BEQ PRG000_D3ED ; If object wants to use "short" horizontal test, jump to PRG000_D3ED  04194.   04195.    LDA Objects_SprHVis,X  04196.    BNE Object_DeleteOffScreen_N2 ; If any sprites are horizontally off-screen, jump to Object_DeleteOffScreen_N2  04197.   04198.    STA Objects_UseShortHTest,X ; Clear Objects_UseShortHTest  04199.   04200. PRG000_D3ED:  04201.    LDA #$00 ; A = 0  04202.   04203. PRG000_D3EF:  04204.    STA <Temp_Var1 ; Temp_Var1 = 0, 2, or 4  04205.   04206.    JSR Object_AnySprOffscreen  04207.    BEQ PRG000_D463 ; If any sprites are off-screen, jump to PRG000_D463  04208.   04209.    LDA Level_7Vertical  04210.    BNE PRG000_D464 ; If level is vertical, jump to PRG000_D464  04211.   04212.   04213.    ; LEVEL NOT VERTICAL  04214.   04215.    LDA <Objects_YHi,X  04216.    CMP #$02  04217.    BPL Object_Delete ; If object Y Hi >= 2 (way off screen), jump to Object_Delete  04218.   04219.    ; Semi-randomly jump to PRG000_D463 (RTS)  04220.    ; That is, only occasionally actually do the off-screen check  04221.    ; Keeps down on CPU cycles spent wondering about the object  04222.    TXA  04223.    ADD <Counter_1  04224.    LSR A ; A = (object index + Counter_1) >> 1  04225.    BCS PRG000_D463 ; If carry set, jump to PRG000_D463 (RTS)  04226.   04227.    AND #$01  04228.    STA <Temp_Var2 ; Temp_Var2 stores bit 0 from above; thus 0 or 1  04229.   04230.    ADC <Temp_Var1 ; So value is now 0-5  04231.    TAY ; -> 'Y'  04232.   04233.    LDA <Horz_Scroll  04234.    ADD PRG000_D3CC,Y ; Horizontal scroll plus offset  04235.   04236.    ROL <Temp_Var1 ; Temp_Var1 is 0/1, 4/5  04237.   04238.    CMP <Objects_X,X ; Compare to object X  04239.    PHP ; Save CPU state  04240.   04241.    LDA <Horz_Scroll_Hi  04242.    LSR <Temp_Var1  04243.    ADC PRG000_D3D2,Y ; Add high part of offset  04244.   04245.    PLP ; Restore CPU state  04246.   04247.    SBC <Objects_XHi,X  04248.    STA <Temp_Var1 ; Temp_Var1 is X Hi difference  04249.   04250.    LDY <Temp_Var2 ; Y = Temp_Var2  04251.    BEQ PRG000_D42E ; If zero, jump to PRG000_D42E  04252.   04253.    EOR #$80  04254.    STA <Temp_Var1 ; Temp_Var1 ^= $80  04255.   04256. PRG000_D42E:  04257.    LDA <Temp_Var1  04258.    BPL PRG000_D463 ; If positive, jump to PRG000_D463 (RTS)  04259.   04260.    ; Deletes object, marks it so it will reappear next time it comes on-screen  04261. Object_Delete:  04262.    LDA Level_ObjectID,X  04263.   04264.    ; If object ID is OBJ_FIRECHOMP, OBJ_CHAINCHOMPFREE, OBJ_BLOOPERCHILDSHOOT,  04265.    ; OBJ_BLOOPERWITHKIDS, or OBJ_FIRESNAKE, jump to PRG000_D449  04266.    ; These objects are hardcoded to release their X/Y Buffer allocations!  04267.    CMP #OBJ_FIRECHOMP  04268.    BEQ PRG000_D449  04269.   04270.    CMP #OBJ_CHAINCHOMPFREE  04271.    BEQ PRG000_D449  04272.   04273.    CMP #OBJ_BLOOPERCHILDSHOOT  04274.    BEQ PRG000_D449  04275.   04276.    CMP #OBJ_BLOOPERWITHKIDS  04277.    BEQ PRG000_D449  04278.   04279.    CMP #OBJ_FIRESNAKE  04280.    BNE Object_SetDeadAndNotSpawned  04281.   04282. PRG000_D449:  04283.   04284.    ; One of the above five objects ONLY!  04285.   04286.    LDY Objects_Var6,X ; Y = Var6 (should be 0 or 1, the buffer slot the object occupies)  04287.   04288.    ; Clear the occupation of the X/Y Buffer  04289.    LDA #$00  04290.    STA Buffer_Occupied,Y  04291.   04292. Object_SetDeadAndNotSpawned:  04293.    LDY Objects_SpawnIdx,X ; Get the spawn index of this object  04294.    BMI Object_SetDeadEmpty ; If object is spawned, jump to Object_SetDeadEmpty  04295.   04296.    ; Clear object spawn flag  04297.    LDA Level_ObjectsSpawned,Y  04298.    AND #$7f  04299.    STA Level_ObjectsSpawned,Y  04300.   04301. Object_SetDeadEmpty:  04302.    ; Mark object as dead/empty  04303.    LDA #OBJSTATE_DEADEMPTY  04304.    STA Objects_State,X  04305.   04306. PRG000_D463:  04307.    RTS ; Return  04308.   04309.   04310. PRG000_D464:  04311.    ; LEVEL IS VERTICAL  04312.   04313.    LDA <Counter_1  04314.    LSR A  04315.    BCS PRG000_D463 ; Every other tick, jump to PRG000_D463 (RTS)  04316.   04317.    AND #$01  04318.    STA <Temp_Var2 ; Temp_Var2 = 0 or 1  04319.    TAY ; -> 'Y'  04320.   04321.    LDA Level_VertScroll  04322.    ADD PRG000_D3C8,Y  04323.    ROL <Temp_Var1 ; 0/1 or 4/5  04324.   04325.    CMP <Objects_Y,X ; Compare to object Y  04326.   04327. PRG000_D479:  04328.    PHP ; Save CPU state  04329.   04330.    LDA Level_VertScrollH  04331.    LSR <Temp_Var1  04332.    ADC PRG000_D3CA,Y  04333.   04334.    PLP ; Restore CPU state  04335.   04336.    SBC <Objects_YHi,X  04337.    STA <Temp_Var1  04338.    LDY <Temp_Var2  04339.    BEQ PRG000_D48F  04340.   04341.    EOR #$80  04342.    STA <Temp_Var1  04343.   04344. PRG000_D48F:  04345.    LDA <Temp_Var1  04346.    BPL PRG000_D463  04347.    BMI Object_Delete  04348.    BPL PRG000_D497  04349.   04350. PRG000_D497:  04351.    BEQ PRG000_D479  04352.   04353.   04354. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04355. ; Level_PrepareNewObject  04356. ;  04357. ; Prepares a new object by initializing all of the many object  04358. ; variables to zero...  04359. ;  04360. ; X = index of on-screen object  04361. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04362. ; $D499  04363. Level_PrepareNewObject:  04364.   04365.    ; Clear various object variables  04366.    LDA #$00  04367.    STA Objects_Var1,X  04368.    STA Objects_Var2,X  04369.    STA <Objects_SpriteX,X  04370.    STA Objects_Timer,X  04371.    STA Objects_Timer2,X  04372.    STA <Objects_XVel,X  04373.    STA <Objects_YVel,X  04374.    STA Objects_FlipBits,X  04375.    STA Objects_Frame,X  04376.    STA Objects_ColorCycle,X  04377.    STA <Objects_DetStat,X  04378.   04379.    CPX #$06  04380.    BGE PRG000_D4C8 ; If using slot index >= 6, jump to PRG000_D4C8 (skip variables available only to slots 0 to 5)  04381.   04382.    ; Clear some more variables (object slots 0 to 5 ONLY)  04383.    STA Objects_DisPatChng,X  04384.    STA ObjSplash_DisTimer,X  04385.    STA Objects_QSandCtr,X  04386.    STA Objects_InWater,X  04387.   04388. PRG000_D4C8:  04389.    CPX #$05  04390.    BGE PRG000_D506 ; If using slot index >= 5, jump to PRG000_D506 (skip variables available only to slots 0 to 4)  04391.   04392.    ; Clear even more variables (object slots 0 to 4 [major objects] ONLY!!)  04393.    STA Objects_PlayerHitStat,X  04394.    STA Objects_Timer4,X  04395.    STA Objects_Timer3,X  04396.    STA Objects_Slope,X  04397.    STA Objects_Var7,X  04398.    STA <Objects_Var5,X  04399.    STA <Objects_Var4,X  04400.    STA Objects_Var3,X  04401.    STA Objects_Var6,X  04402.    STA Objects_TargetingXVal,X  04403.    STA Objects_TargetingYVal,X  04404.    STA Objects_IsGiant,X  04405.    STA Objects_UseShortHTest,X  04406.    STA Objects_HitCount,X  04407.    STA Objects_DisPatChng,X  04408.    STA Objects_Var10,X  04409.    STA Objects_Var11,X  04410.    STA Objects_Var12,X  04411.    STA Objects_Var13,X  04412.    STA Objects_Var14,X  04413.   04414. PRG000_D506:  04415.    RTS ; Return  04416.   04417.   04418.    ; Called for an object in state 2 to do its "normal" routine  04419. ObjState_Normal:  04420.    LDA <Player_HaltGame  04421.    BEQ Object_DoNormal ; If gameplay is NOT halted by the Player, jump to Object_DoNormal  04422.   04423.    JMP Object_DoHaltedAction ; Jump to Object_DoHaltedAction  04424.   04425. Object_DoNormal:  04426.    LDA ObjGroupRel_Idx  04427.    ASL A  04428.    TAY ; Y = object's group relative index * 2 (2 byte index for jump table)  04429.   04430.    ; Get jump address specific to this object  04431.    LDA ObjectGroup_NormalJumpTable,Y  04432.    STA <Temp_Var1  04433.    LDA ObjectGroup_NormalJumpTable+1,Y  04434.    STA <Temp_Var2  04435.    JMP [Temp_Var1] ; Dynamically jump to object's "normal" routine  04436.   04437.   04438. Object_DoHaltedAction:  04439.   04440.    ; Gameplay is halted, determine what needs to happen with this object...  04441.   04442.    LDY ObjGroupRel_Idx ; Y = group relative index  04443.   04444.    LDA ObjectGroup_Attributes3,Y ; Get attribute set 3 bits  04445.    AND #OA3_HALT_MASK ; Keep only the lowest 4  04446.    JSR DynJump  04447.   04448.    ; WARNING: Read comment; some of these are specific to object banks!  04449.   04450.    ; THESE MUST FOLLOW DynJump FOR THE DYNAMIC JUMP TO WORK!!  04451.    .word Bank2_HotFootHaltAction ; 0: Bank2/Hotfoot ONLY  04452.    .word Object_ShakeAndDraw ; 1: Standard draw  04453.    .word Object_Draw16x32Sprite ; 2: Draw tall sprite  04454.    .word Bank2_SpikeHaltAction ; 3: Bank2/Spike ONLY  04455.    .word ObjHalt_DoNothing ; 4: Do nothing  04456.    .word ObjHalt_DoNothingNotNormal ; 5: If object is in "normal" state, do its normal routine, otherwise do nothing (COMMON)  04457.    .word Object_DrawWide ; 6: Draw wide sprite  04458.    .word ObjHalt_DoNothing ; 7: Do nothing  04459.    .word Shoe_DrawGoomba ; 8: Bank2/Kuribo's Shoe ONLY  04460.    .word ObjHalt_DoNothing ; 9: Do nothing  04461.    .word Object_ShakeAndDrawMirrored ; 10: Draw mirrored sprite  04462.    .word EndLevelCard_Draw ; 11: Bank2/End Level Card ONLY  04463.    .word ObjHalt_DoNothing ; 12: Do nothing  04464.    .word Buster_DrawHoldingIceBrick ; 13: Bank2/Buster Beatle ONLY  04465.    .word Bank2_PiranhaSpikeHaltAction ; 14: Bank2/Piranha Spike Ball ONLY  04466.   04467. ObjHalt_DoNothingNotNormal:  04468.    LDA Objects_State,X  04469.    CMP #OBJSTATE_NORMAL  04470.    BNE PRG000_D553 ; If object's state is not Normal, jump to PRG000_D553  04471.   04472.    JMP Object_DoNormal ; Otherwise, jump to Object_DoNormal (jump into object's "Normal" routine)  04473.   04474. PRG000_D553:  04475.    RTS ; Return  04476.   04477.   04478. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04479. ; Object_CalcSpriteXY_NoHi  04480. ;  04481. ; Calculate SpriteX/Y without considering the "High" parts  04482. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04483. ; $D554  04484. Object_CalcSpriteXY_NoHi:  04485.    LDA <Objects_Y,X  04486.    SUB Level_VertScroll  04487.    STA <Objects_SpriteY,X  04488.   04489.    LDA <Objects_X,X  04490.    SUB <Horz_Scroll  04491.    STA <Objects_SpriteX,X  04492.   04493.    RTS ; Return  04494.   04495.   04496. ; $D564  04497. Fish_FixedY_ExceptHitFloor:  04498.    LDA <Objects_DetStat,X  04499.    AND #$04  04500.    BNE PRG000_D588 ; If object has hit floor, jump to PRG000_D588  04501.   04502. ; $D56A  04503. Fish_FixedYIfAppro:  04504.    LDA Level_AScrlConfig  04505.    BEQ PRG000_D588 ; If no auto scroll effect active (assuming fixed height water level), jump to PRG000_D588 (RTS)  04506.   04507.    LDA Level_FreeVertScroll  04508.    CMP #$01  04509.    BEQ PRG000_D588 ; If this level has free vertical scrolling, jump to PRG000_D588  04510.   04511.    LDY #$00 ; Y = 0 (16-bit carry)  04512.   04513.    LDA Level_ScrollDiffV  04514.    BPL PRG000_D57E ; If desired vertical scroll is not negative, jump to PRG000_D57E  04515.   04516.    DEY ; Y = $FF (16-bit carry)  04517.   04518. PRG000_D57E:  04519.   04520.    ; In fixed-height, locked scrolling water levels, Big Bertha's  04521.    ; Object_Y position offsets from the scroll position  04522.    ADD <Objects_Y,X  04523.    STA <Objects_Y,X  04524.    TYA  04525.    ADC <Objects_YHi,X  04526.    STA <Objects_YHi,X  04527.   04528. PRG000_D588:  04529.    RTS ; Return  04530.   04531.   04532. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04533. ; Object_ShakeAndCalcSprite  04534. ;  04535. ; The routine for a held object to "shake awake" (shelled enemies)  04536. ; and calculates sprite related info  04537. ;  04538. ; X = index of on-screen object  04539. ;  04540. ; Returns lots of stuff:  04541. ; Temp_Var1 = Object sprite Y  04542. ; Temp_Var2 = Object sprite X  04543. ; Temp_Var3 = Object's LR flag  04544. ; Temp_Var4 = Object's attributes  04545. ; Temp_Var5 = Objects_SprVVis  04546. ; Temp_Var6 = Object's starting tiles index (and -> 'X')  04547. ; Temp_Var7 = Object's Sprite_RAM offset (and -> 'Y')  04548. ; Temp_Var8 = Objects_SprHVis  04549. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04550. ; $D589  04551. Object_ShakeAndCalcSprite:  04552.    LDA <Objects_Y,X ; Get object's Y  04553.    SUB Level_VertScroll ; Make relative  04554.    STA <Objects_SpriteY,X ; Store as sprite Y  04555.    STA <Temp_Var1 ; Also -> Temp_Var1  04556.   04557.    ; This is the object "shakin' awake" routine! (Enemies in shell etc.)  04558.   04559.    SEC ; Set carry (remember, this is the default for not applying carry to subtraction)  04560.   04561.    LDA Objects_Timer4,X  04562.    BEQ PRG000_D5A0 ; If Timer4 = 0, jump to PRG000_D5A0  04563.   04564.    CMP #$40  04565.    BLT PRG000_D59F ; If Timer4 < $40, jump to PRG000_D59F  04566.   04567.    LSR A  04568.    LSR A  04569.   04570. PRG000_D59F:  04571.    LSR A ; Shift right 1 (if Timer4 < $40) or 3 (basically applies a carry sort of sporadically for "shakin' awake")  04572.   04573. PRG000_D5A0:  04574.    LDA <Objects_X,X ; Get object's X  04575.    SBC <Horz_Scroll ; Make relative  04576.    STA <Objects_SpriteX,X ; Store as sprite X  04577.    STA <Temp_Var2 ; Also -> Temp_Var2  04578.   04579.    LDA Objects_FlipBits,X  04580.    STA <Temp_Var3 ; Temp_Var3 = object's LR flag  04581.   04582.    LDY ObjGroupRel_Idx ; Y = object's group relative index  04583.   04584.    LDA Objects_ColorCycle,X  04585.    BEQ PRG000_D5BC ; If Objects_ColorCycle = 0, jump to PRG000_D5BC  04586.   04587.    DEC Objects_ColorCycle,X ; Objects_ColorCycle--  04588.    AND #$03  04589.    BPL PRG000_D5BF ; Jump (technically always) to PRG000_D5BF  04590.   04591. PRG000_D5BC:  04592.    LDA Objects_SprAttr,X ; Otherwise, just get the normal attributes  04593.   04594. PRG000_D5BF:  04595.    STA <Temp_Var4 ; Decided attributes -> Temp_Var4  04596.   04597.    LDA Objects_SprVVis,X  04598.    STA <Temp_Var5 ; Temp_Var5 = Objects_SprVVis  04599.   04600.    LDA Objects_SprHVis,X  04601.    STA <Temp_Var8 ; Temp_Var8 = Objects_SprVVis  04602.   04603.    ; Each "frame" value moves up two bytes to the next pair  04604.    LDA Objects_Frame,X  04605.    ASL A  04606.    STA <Temp_Var6 ; Temp_Var6 = Objects_Frame << 1  04607.   04608.    LDA ObjectGroup_PatternStarts,Y  04609.    ADD <Temp_Var6  04610.    STA <Temp_Var6 ; Temp_Var6 += ObjectGroup_PatternStarts[Y] (set base tile index)  04611.   04612.    TAX ; -> 'X'  04613.   04614.    LDY <SlotIndexBackup ; Y = object slot index  04615.   04616.    LDA Object_SprRAM,Y  04617.    STA <Temp_Var7 ; Temp_Var7 = Object_SprRAM[Y]  04618.   04619.    TAY ; -> 'Y'  04620.   04621.    RTS ; Return  04622.   04623. PRG000_D5E3:  04624.    .byte $08, $04, $02, $01  04625.   04626.    ; Object "shaking awake" and draw its sprite  04627. ; $D5E7  04628. Object_ShakeAndDraw:  04629.    JSR Object_ShakeAndCalcSprite  04630.    JSR Object_Draw16x16Sprite  04631.   04632.    LDX <SlotIndexBackup  04633.    RTS ; Return  04634.   04635. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04636. ; Object_ShakeAndDrawMirrored  04637. ;  04638. ; Used to draw 16x16 mirrored object sprites.  04639. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04640. ; $D5F0  04641. Object_ShakeAndDrawMirrored:  04642.    JSR Object_ShakeAndDraw ; Draw object and "shake awake"  04643.   04644.    ; Keep all attributes except horizontal flip  04645.    LDA Sprite_RAM+$02,Y  04646.    AND #%10111111  04647.    STA Sprite_RAM+$02,Y  04648.   04649.    ; Flip opposite sprite  04650.    ORA #$40  04651.    STA Sprite_RAM+$06,Y  04652.   04653.    RTS ; Return  04654.   04655. ; $D601  04656. Object_DrawTallAndHFlip:  04657.    JSR Object_Draw16x32Sprite ; Draw tall sprite  04658.   04659.    ; Reverse sprites  04660.    LDA Sprite_RAM-$06,Y  04661.    AND #%10111111  04662.    STA Sprite_RAM-$06,Y  04663.   04664.    STA Sprite_RAM+$02,Y  04665.    ORA #$40  04666.    STA Sprite_RAM-$02,Y  04667.   04668.    STA Sprite_RAM+$06,Y  04669.   04670.    RTS ; Return  04671.   04672.   04673. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04674. ; Object_Draw16x32Sprite  04675. ;  04676. ; Used to draw 16x32 object sprites.  04677. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04678. ; $D618  04679. Object_Draw16x32Sprite:  04680.    JSR Object_ShakeAndCalcSprite  04681.   04682.    LDX <SlotIndexBackup ; X = object slot index  04683.   04684.    LDA Objects_Frame,X  04685.    ASL A  04686.    ADD <Temp_Var6  04687.    STA <Temp_Var6 ; Temp_Var6 += object's frame  04688.    TAX ; -> 'X'  04689.   04690.    LDA <Temp_Var3 ; Objects_FlipBits  04691.    BPL PRG000_D62D ; If Objects_FlipBits bit 7 is NOT set, jump to PRG000_D62D  04692.   04693.    ; Otherwise...  04694.    INX  04695.    INX ; X += 2  04696.   04697. PRG000_D62D:  04698.    JSR Object_Draw16x16Sprite ; Draw sprite  04699.   04700.    LSR <Temp_Var5 ; Objects_SprVVis  04701.   04702.    ; 'Y' += 8 (Sprite RAM 2 sprites over)  04703.    TYA  04704.    ADD #$08  04705.    TAY  04706.   04707.    LDX <Temp_Var6 ; X = Temp_Var6 (starting tile)  04708.   04709.    LDA <Temp_Var3 ; Objects_FlipBits  04710.    BMI PRG000_D63F ; If Objects_FlipBits bit 7 set, jump to PRG000_D63F  04711.   04712.    ; Otherwise...  04713.    INX  04714.    INX ; X += 2  04715.   04716. PRG000_D63F:  04717.    LDA #16  04718.    ADD <Temp_Var1 ; Sprite Y  04719.    STA <Temp_Var1 ; Temp_Var1 += 16  04720.   04721.    JSR Object_Draw16x16Sprite ; Draw sprite  04722.   04723.    LDX <SlotIndexBackup ; X = object slot index  04724.   04725.    RTS ; Return  04726.   04727.   04728. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04729. ; Object_DrawWide  04730. ;  04731. ; Draws a wide 48x16 object  04732. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04733. Object_DrawWide:  04734.    JSR Object_ShakeAndCalcSprite  04735.   04736.    LDX <SlotIndexBackup ; X = object's slot index  04737.   04738.    ; Calculate offset into the ObjectGroup_PatternSets table  04739.    LDA Objects_Frame,X  04740.    ADD <Temp_Var6  04741.    STA <Temp_Var6 ; Temp_Var6 += object's frame  04742.    TAX ; -> 'X'  04743.    JSR Object_Draw48x16Sprite ; Draw wide sprite  04744.   04745.    LDX <SlotIndexBackup ; X = object's slot index  04746.    RTS ; Return  04747.   04748. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04749. ; Object_ToggleFrameBySpd  04750. ;  04751. ; Sets object's frame alternating 0 or 1 at a rate which  04752. ; increases in speed (X velocity)  04753. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04754. ; $D660  04755. Object_ToggleFrameBySpd:  04756.    LDA <Objects_XVel,X  04757.    BNE PRG000_D665 ; If object is moving horizontally, jump to PRG000_D665  04758.   04759.    ; Otherwise, do nothing  04760.    RTS ; Return  04761.   04762. PRG000_D665:  04763.   04764.    ; Absolute value of X Velocity  04765.    BPL PRG000_D66A  04766.    JSR Negate  04767. PRG000_D66A:  04768.   04769.    AND #$f0  04770.    LSR A  04771.    LSR A  04772.    LSR A  04773.    LSR A  04774.    TAY ; Y = "whole" part of X Velocity only  04775.   04776.    LDA PRG000_D5E3,Y ; Get masking value  04777.   04778.    LDY #$00 ; Y = 0  04779.   04780.    AND <Counter_1  04781.    BEQ PRG000_D67B ; If Counter_1 masked by value is zero, jump to PRG000_D67B  04782.   04783.    INY ; Otherwise, Y = 1  04784.   04785. PRG000_D67B:  04786.    TYA  04787.    STA Objects_Frame,X ; Set as frame 0 or 1  04788.    RTS ; Return  04789.   04790.   04791. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04792. ; Object_Draw16x16Sprite  04793. ;  04794. ; Used to draw 16x16 object sprites.  04795. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04796. ; $D680  04797. Object_Draw16x16Sprite:  04798. ; Temp_Var1 = Object sprite Y  04799. ; Temp_Var2 = Object sprite X  04800. ; Temp_Var3 = Object's LR flag  04801. ; Temp_Var4 = Object's attributes  04802. ; Temp_Var5 = Objects_SprVVis  04803. ; Temp_Var6 = Object's starting tiles index (and -> 'X')  04804. ; Temp_Var7 = Object's Sprite_RAM offset (and -> 'Y')  04805. ; Temp_Var8 = Objects_SprHVis  04806.   04807.    LDA <Temp_Var5 ; Check sprite vertical visibility  04808.    LSR A ; Shift right (checking lowest bit)  04809.    BCS PRG000_D6C6 ; If this bit is set, this sprite piece is invisible, jump to PRG000_D6C6 (RTS)  04810.   04811.    LDA <Temp_Var1 ; Get sprite Y  04812.   04813.    BIT <Temp_Var8 ; Testing bit 7 of horizontal sprite visibility  04814.    BMI PRG000_D68E ; If bit 7 is set (this sprite is horizontally off-screen), jump to PRG000_D68E  04815.   04816.    STA Sprite_RAM+$00,Y ; Otherwise, OK to set sprite Y  04817.   04818. PRG000_D68E:  04819.    BVS PRG000_D693 ; If bit 6 is set, jump to PRG000_D693  04820.   04821.    STA Sprite_RAM+$04,Y ; Otherwise, OK set second sprite Y  04822.   04823. PRG000_D693:  04824.    LDA <Temp_Var2 ; Get sprite X  04825.    STA Sprite_RAM+$03,Y ; Store into Sprite RAM  04826.   04827.    ADD #$08 ; +8 for next sprite over  04828.    STA Sprite_RAM+$07,Y ; Store into second sprite  04829.   04830.    LDA ObjectGroup_PatternSets,X ; Get first sprite pattern index  04831.    STA Sprite_RAM+$01,Y ; -> Sprite RAM  04832.   04833.    LDA ObjectGroup_PatternSets+1,X ; Get second sprite pattern index  04834.    STA Sprite_RAM+$05,Y ; -> Sprite RAM  04835.   04836.    LDA <Temp_Var3  04837.    ORA <Temp_Var4 ; Joins base attributes to H-flip flag  04838.    STA Sprite_RAM+$02,Y ; Store into both sprite's attributes  04839.    STA Sprite_RAM+$06,Y ; Store into both sprite's attributes  04840.   04841.    BIT <Temp_Var3  04842.    BVC PRG000_D6C6 ; If sprite is not horizontally flipped, jump to PRG000_D6C6 (RTS)  04843.   04844.    ; If flipped, swap sprite attributes  04845.    LDA Sprite_RAM+$01,Y  04846.    PHA  04847.    LDA Sprite_RAM+$05,Y  04848.    STA Sprite_RAM+$01,Y  04849.    PLA  04850.    STA Sprite_RAM+$05,Y  04851.   04852. PRG000_D6C6:  04853.    RTS ; Return  04854.   04855.   04856. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04857. ; Object_Draw48x16Sprite  04858. ;  04859. ; Used to draw 48x16 object sprites.  04860. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04861. ; $D6C7  04862. Object_Draw48x16Sprite:  04863.    LDA <Temp_Var5 ; Check sprite vertical visibility  04864.    LSR A  04865.    BCS PRG000_D726 ; If this sprite is off-screen, jump to PRG000_D726 (RTS)  04866.   04867.    LDA <Temp_Var8 ; Checking horizontal sprite visibility  04868.    ASL A ; Left shift flags value  04869.    STA <Temp_Var10 ; -> Temp_Var10  04870.   04871.    LDA <Temp_Var1 ; Sprite Y  04872.    BCS PRG000_D6D8 ; If sprite is horizontally off-screen, jump to PRG000_D6D8  04873.   04874.    STA Sprite_RAM+$00,Y ; Set sprite Y in RAM  04875.   04876. PRG000_D6D8:  04877.    BIT <Temp_Var10  04878.    BMI PRG000_D6DF ; If this sprite is off-screen, jump to PRG000_D6DF  04879.   04880.    STA Sprite_RAM+$04,Y ; Set sprite Y in RAM  04881.   04882. PRG000_D6DF:  04883.    BVS PRG000_D6E4 ; If this sprite is off-screen, jump to PRG000_D6E4  04884.   04885.    STA Sprite_RAM+$08,Y ; Set sprite Y in RAM  04886.   04887. PRG000_D6E4:  04888.    LDA <Temp_Var2  04889.    STA Sprite_RAM+$03,Y ; Set sprite X in RAM  04890.    ADD #$08  04891.    STA Sprite_RAM+$07,Y ; Set sprite X in RAM (+8)  04892.    ADD #$08  04893.    STA Sprite_RAM+$0B,Y ; Set sprite X in RAM (+16)  04894.   04895.    ; Set each of the sprite's patterns  04896.    LDA ObjectGroup_PatternSets,X  04897.    STA Sprite_RAM+$01,Y  04898.    LDA ObjectGroup_PatternSets+1,X  04899.    STA Sprite_RAM+$05,Y  04900.    LDA ObjectGroup_PatternSets+2,X  04901.    STA Sprite_RAM+$09,Y  04902.   04903.    ; Set each sprite's attributes  04904.    LDA <Temp_Var3  04905.    ORA <Temp_Var4 ; Combine attributes  04906.    STA Sprite_RAM+$02,Y  04907.    STA Sprite_RAM+$06,Y  04908.    STA Sprite_RAM+$0A,Y  04909.   04910.    BIT <Temp_Var3  04911.    BVC PRG000_D6C6 ; If sprite is not horizontally flipped, jump to PRG000_D6C6 (RTS)  04912.   04913.    ; Swap end sprites patterns  04914.    LDA Sprite_RAM+$01,Y  04915.    PHA  04916.    LDA Sprite_RAM+$09,Y  04917.    STA Sprite_RAM+$01,Y  04918.    PLA  04919.    STA Sprite_RAM+$09,Y  04920.   04921. PRG000_D726:  04922.    RTS ; Return  04923.      04924.   04925. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04926. ; Object_GetRandNearUnusedSpr  04927. ;  04928. ; Gets a semi-random "near by" sprite as appropriate for an  04929. ; object; it's a "friendly" way of getting an additional sprite  04930. ; for an object that's going over the normal limit.  04931. ;  04932. ; X = index of on-screen object  04933. ;  04934. ; Returns:  04935. ; Temp_Var7 = offset to the blank sprite (also in 'Y')  04936. ; Temp_Var8 = 5 or 1  04937. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  04938.   04939.    ; Selection table for the 5/1... doesn't seem like the  04940.    ; values actually mean anything, it just checks > 5?  04941.    ; Kept in Temp_Var9 anyway...  04942. PRG000_D727:  04943.    .byte $00, $01, $02, $03, $04, $05, $03, $07, $00, $01, $02, $03, $04, $05, $02  04944.   04945. ; $D736  04946. Object_GetRandNearUnusedSpr:  04947.    TXA  04948.    PHA ; Save object index  04949.   04950.    LDY #$07 ; Y = 7  04951. PRG000_D73A:  04952.    STY <Temp_Var7 ; Update Temp_Var7  04953.   04954.    LDX <SlotIndexBackup ; X = object slot index  04955.   04956.    LDA RandomN,X  04957.    AND #$07  04958.    ADD <Temp_Var7  04959.    TAY ; Y = (Random 0-7) + Temp_Var7  04960.   04961.    LDA PRG000_D727,Y  04962.    TAY  04963.    STY <Temp_Var9 ; Temp_Var9 = PRG000_D727[Y]  04964.   04965.    LDA Objects_State,Y  04966.    BEQ PRG000_D763 ; If object state = 0 (dead/empty), jump to PRG000_D763  04967.   04968. PRG000_D752:  04969.    LDY <Temp_Var7 ; Y = Temp_Var7  04970.    DEY ; Y--  04971.    BPL PRG000_D73A ; While Y > 0, loop!  04972.   04973.    LDX #$20 ; X = $20  04974.   04975.    LDA RandomN  04976.    BPL PRG000_D760 ; 50/50, jump to PRG000_D760  04977.   04978.    LDX #$24 ; Otherwise, X = $24  04979.   04980. PRG000_D760:  04981.    JMP PRG000_D789 ; Jump to PRG000_D789  04982.   04983. PRG000_D763:  04984.   04985.    ; Object slot is dead/empty...  04986.   04987.    TYA  04988.    ADD Counter_7to0  04989.    TAY ; Y = object slot + (0-7)  04990.   04991.    LDX SprRamOffsets,Y ; X = Sprite_RAM offset  04992.   04993.    LDY #$05 ; Y = 5  04994.   04995.    LDA <Temp_Var9  04996.    CMP #$05  04997.    BLT PRG000_D776 ; If Temp_Var9 < 5, jump to PRG000_D776  04998.   04999.    LDY #$01 ; Y = 1  05000.   05001. PRG000_D776:  05002.    STY <Temp_Var8 ; Temp_Var8 = 5 or 1  05003.   05004.    LDA Sprite_RAM+$00,X  05005.    CMP #$f8  05006.    BEQ PRG000_D789 ; If this sprite Y is impossibly low (blank sprite), jump to PRG000_D789  05007.   05008.    INX  05009.    INX  05010.    INX  05011.    INX ; X += 4 (next sprite)  05012.   05013.    DEY ; Y--  05014.    BPL PRG000_D776 ; While Y >= 0, loop!  05015.   05016.    JMP PRG000_D752 ; Jump to PRG000_D752  05017.   05018. PRG000_D789:  05019.    STX <Temp_Var7 ; Temp_Var7 = offset to blank sprite  05020.   05021.    TXA  05022.    TAY ; Y = same offset  05023.   05024.    PLA  05025.    TAX ; Restore 'X'  05026.   05027.    LDA <Temp_Var8 ; A = 5 or 1  05028.   05029.    RTS ; Return  05030.   05031.   05032. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05033. ; Object_DetermineHorzVis  05034. ; Object_DetermineHorzVisY  05035. ;  05036. ; Determines how many of each horizontal sprite of an object are  05037. ; invisible (off-screen), based on size of object  05038. ;  05039. ; X = index of on-screen object  05040. ; Y = width of object; 0-5 or 8, 16, 24, 32, 40, 48 respectively (Object_DetermineHorzVisY only)  05041. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05042.    ; Pixel width minus 8 of objects  05043. Object_Widths:  05044.    .byte 0 ; 0  05045.    .byte 8 ; 1  05046.    .byte 16 ; 2  05047.    .byte 24 ; 3  05048.    .byte 32 ; 4  05049.    .byte 40 ; 5  05050.   05051.    ; Respective bit to set per width checked  05052. Object_WidthFlags:  05053.    .byte %10000000 ; 0  05054.    .byte %01000000 ; 1  05055.    .byte %00100000 ; 2  05056.    .byte %00010000 ; 3  05057.    .byte %00001000 ; 4  05058.    .byte %00000100 ; 5  05059.   05060. ; $D79E  05061. Object_DetermineHorzVis:  05062.    LDY ObjGroupRel_Idx ; Y = object group relative index  05063.    LDA ObjectGroup_Attributes,Y ; Get object's attributes  05064.    AND #OA1_WIDTHMASK ; Keep only bits 4-6  05065.    LSR A  05066.    LSR A  05067.    LSR A  05068.    LSR A ; shift right 4  05069.    TAY ; Y = Width of object (0-5 or 0, 8, 16, 24, 32, or 40, -8)  05070.   05071. Object_DetermineHorzVisY:  05072.    LDA Objects_State,X  05073.    CMP #OBJSTATE_NORMAL  05074.    BGS PRG000_D7B8 ; If this object's state >= OBJSTATE_NORMAL (not dead or initializing), jump to PRG000_D7B8  05075.   05076.    ; If object is dead/empty or initializing, mark all sprites as invisible  05077.    LDA #%11111100  05078.    STA Objects_SprHVis,X  05079.   05080.    RTS ; Return  05081.   05082. PRG000_D7B8:  05083.    LDA #$00  05084.    STA Objects_SprHVis,X ; Clear until determined  05085.   05086. PRG000_D7BD:  05087.    LDA <Objects_X,X  05088.    ADD Object_Widths,Y  05089.    STA <Temp_Var15 ; Temp_Var15 = object's X + ??  05090.   05091.    LDA <Objects_XHi,X  05092.    ADC #$00  05093.    STA <Temp_Var16 ; Temp_Var16 = Object's X Hi with carry applied  05094.   05095.    LDA <Temp_Var15  05096.    CMP <Horz_Scroll  05097.    LDA <Temp_Var16  05098.    SBC <Horz_Scroll_Hi  05099.    BEQ PRG000_D7DE ; If sprite is not horizontally off-screen, jump to PRG000_D7DE  05100.   05101.    ; This sprite is off left/right of screen...  05102.    LDA Objects_SprHVis,X ; Get appropriate invisibility bit  05103.    ORA Object_WidthFlags,Y ; OR it  05104.    STA Objects_SprHVis,X ; Store it  05105.   05106. PRG000_D7DE:  05107.    DEY ; Y--  05108.    BPL PRG000_D7BD ; While Y >= 0, loop  05109.   05110.    RTS ; Return  05111.   05112.   05113. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05114. ; Object_DetermineVertVis  05115. ; Object_DetermineVertVisY  05116. ;  05117. ; Determines how many of each vertical sprite of an object are  05118. ; invisible (off-screen), based on size of object  05119. ;  05120. ; X = index of on-screen object  05121. ; Y = height of object; 0-3 or 16, 32, 48, 64 respectively (Object_DetermineVertVisY only)  05122. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05123. ; $D7E2  05124. Object_DetermineVertVis:  05125.    LDY ObjGroupRel_Idx ; Y = object group relative index  05126.    LDA ObjectGroup_Attributes,Y ; Get object's attributes  05127.    AND #OA1_HEIGHTMASK ; keep only bits 2 and 3  05128.    LSR A  05129.    LSR A ; shift right 2  05130.    TAY ; Y = size of object (0-3 or 16, 32, 48, 64)  05131.   05132. Object_DetermineVertVisY:  05133.    LDA #$01  05134.    STA <Temp_Var3 ; Temp_Var3 = 1  05135.   05136.    LDA #$00  05137.    STA Objects_SprVVis,X ; Clear until determined  05138.   05139.    ; Copy object's Y Hi/Lo -> Temp_Var1/2  05140.    LDA <Objects_YHi,X  05141.    STA <Temp_Var1  05142.    LDA <Objects_Y,X  05143.    STA <Temp_Var2  05144.   05145. PRG000_D7FE:  05146.   05147.    ; Add 16 to copy of object's Y (bottom of this sprite)  05148.    LDA <Temp_Var2  05149.    ADD #16  05150.    STA <Temp_Var2  05151.   05152.    BCC PRG000_D809 ; If no carry, jump to Objects_SprVVis  05153.   05154.    INC <Temp_Var1 ; Otherwise, apply carry  05155.   05156. PRG000_D809:  05157.    LDA <Temp_Var2  05158.    SUB Level_VertScroll  05159.    STA <Temp_Var4 ; Temp_Var4 = screen-relative Y  05160.   05161.    LDA <Temp_Var1  05162.    SBC Level_VertScrollH  05163.    BNE PRG000_D81E ; If relative position is off-screen, jump to PRG000_D81E  05164.   05165.    ; Otherwise...  05166.    LDA <Temp_Var4  05167.    CMP #240  05168.    BLT PRG000_D826 ; If object sprite is higher than 240 (not off bottom of screen), jump to PRG000_D826  05169.   05170. PRG000_D81E:  05171.   05172.    ; This sprite is off top/bottom of screen...  05173.    LDA <Temp_Var3 ; Get current set bit  05174.    ORA Objects_SprVVis,X  05175.    STA Objects_SprVVis,X ; Mark this part as invisible  05176.   05177. PRG000_D826:  05178.    ASL <Temp_Var3 ; Temp_Var3 <<= 1  05179.    DEY ; Y--  05180.    BPL PRG000_D7FE ; While Y >= 0, loop!  05181.   05182. PRG000_D82B:  05183.    RTS ; Return  05184.   05185.    ; Defines the "bounding box" around the Player  05186.    ; Temp_Var1 - upper left of bounding box  05187.    ; Temp_Var2 - offset to right bounding box (width)  05188.    ; Temp_Var5 - top of bounding box  05189.    ; Temp_Var6 - offset to bottom bounding box (height)  05190. Player_BoundBox:  05191.    ; Left Right Bot Top - offsets applied to sprite X/Y  05192.    .byte 4, 8, 17, 13 ; small/ducking  05193.    .byte 3, 10, 5, 25 ; otherwise  05194.   05195.   05196. PRG000_D834:  05197.    .byte -8, 8  05198.      05199.   05200.   05201. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05202. ; Object_HitTest  05203. ; Object_HitTestRespond  05204. ;  05205. ; Tests if Player has collided with another object  05206. ; If using "Object_HitTestRespond", then if the Player has touched  05207. ; the object, it will call appropriate ObjectGroup_CollideJumpTable  05208. ; routine after a successful intersection.  05209. ;  05210. ; In any case, carry is set if there was a collision, or clear  05211. ; if the Player did not collide with the object!  05212. ;  05213. ; X is object's slot  05214. ; Y is group relative object index  05215. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05216. ; $D836  05217. Object_HitTest:  05218.    LDA #$01 ; Test only, do NOT perform "collide" routine  05219.    JMP PRG000_D83D ; Jump to PRG000_D83D  05220.   05221. ; $D83B  05222. Object_HitTestRespond:  05223.    LDA #$00 ; Test and do "collide" routine  05224.   05225. PRG000_D83D:  05226.    STA <Temp_Var16 ; Temp_Var16 = 0 or 1, depending on entry point  05227.   05228.    ; Clear the Player hit status bits  05229.    LDA Objects_PlayerHitStat,X  05230.    AND #%11111100  05231.    STA Objects_PlayerHitStat,X  05232.   05233.    CLC ; Carry flag will be used as a result  05234.   05235.    LDA <Player_IsDying ; If Player is dying...  05236.    ORA Player_OffScreen ; ... off-screen ...  05237.    ORA Player_Behind_En ; ... or behind the scenes ...  05238.    BNE PRG000_D82B ; ... jump to PRG000_D82B (RTS)  05239.   05240.    JSR Object_CalcBoundBox ; Calculate object's bounding box  05241.   05242.    LDA <Player_Suit  05243.    BEQ PRG000_D862 ; If Player is small, jump to PRG000_D862  05244.   05245.    LDA #$00 ; A = 0 when small or ducking  05246.   05247.    LDY Player_IsDucking  05248.    BNE PRG000_D862 ; If Player is ducking, jump to PRG000_D862  05249.   05250.    LDA #$01 ; A = 1 otherwise  05251.   05252. PRG000_D862:  05253.    ASL A  05254.    ASL A ; Multiply by 4  05255.    TAY ; Y = 0 (small/ducking) or 4 (otherwise)  05256.   05257.    ; Calculate upper left of bounding box and lower right offsets of Player  05258.    LDA <Player_SpriteX  05259.    ADD Player_BoundBox,Y  05260.    STA <Temp_Var3  05261.   05262.    LDA <Player_SpriteY  05263.    ADD Player_BoundBox+2,Y  05264.    STA <Temp_Var7  05265.   05266.    LDA Player_BoundBox+1,Y  05267.    STA <Temp_Var4  05268.   05269.    LDA Player_BoundBox+3,Y  05270.    STA <Temp_Var8  05271.   05272.    JSR ObjectObject_Intersect ; Returns carry SET if object and Player intersected  05273.    BCC PRG000_D82B ; If carry clear, object and Player did not intersect, jump to PRG000_D82B (RTS)  05274.   05275.    ; Intersection occurred by 8-bit values that represent "screen relative" positions,  05276.    ; but this is not a complete check as Player or object may be at different "High/Low"  05277.    ; positions (full 16-bit coordinate check)  05278.   05279.    STA <Temp_Var1 ; Store Player's bounding box top offset -> Temp_Var1  05280.   05281.    LDA Level_7Vertical  05282.    BNE PRG000_D8B1 ; If level is vertical, jump to PRG000_D8B1  05283.   05284.    ; Calculate full 16-bit X difference of object -> Temp_Var14/15  05285.    LDA <Player_X  05286.    SUB <Objects_X,X  05287.    STA <Temp_Var15  05288.   05289.    LDA <Player_XHi  05290.    SBC <Objects_XHi,X  05291.   05292.    STA <Temp_Var14  05293.   05294.    BPL PRG000_D8A9 ; If overall result is positive, jump to PRG000_D8A9  05295.   05296.    ; Otherwise, 16-bit negate Temp_Var14/15  05297.    LDA <Temp_Var15  05298.    JSR Negate  05299.    STA <Temp_Var15  05300.   05301.    LDA <Temp_Var14  05302.    EOR #$ff  05303.    ADC #$00  05304.    STA <Temp_Var14  05305.   05306. PRG000_D8A9:  05307.    LDA <Temp_Var14  05308.    BNE PRG000_D920 ; If Temp_Var14 is not zero, there's a difference in the "High" component of the Player/Object, so no intersect! Jump to PRG000_D920  05309.   05310.    LDA <Temp_Var15  05311.    BMI PRG000_D920 ; If Temp_Var15 is negative, no intersect, jump to PRG000_D920  05312.   05313. PRG000_D8B1:  05314.   05315.    ; The above check is not needed on a vertical level...  05316.    ; no chance of being on horizontally different screens!  05317.   05318.    ; Calculate full 16-bit Y difference of object -> Temp_Var14/15  05319.    LDA <Player_Y  05320.    SUB <Objects_Y,X  05321.    STA <Temp_Var15  05322.   05323.    LDA <Player_YHi  05324.    SBC <Objects_YHi,X  05325.    STA <Temp_Var14  05326.   05327.    BPL PRG000_D8CF ; If overall result is positive, jump to PRG000_D8CF  05328.   05329.    ; Otherwise, 16-bit negate Temp_Var14/15  05330.    LDA <Temp_Var15  05331.    JSR Negate  05332.    STA <Temp_Var15  05333.   05334.    LDA <Temp_Var14  05335.    EOR #$ff  05336.    ADC #$00  05337.    STA <Temp_Var14  05338.   05339. PRG000_D8CF:  05340.    LDA <Temp_Var14  05341.    BNE PRG000_D920 ; If Temp_Var14 is not zero, there's a difference in the "High" component of the Player/Object, so no intersect! Jump to PRG000_D920  05342.   05343.    LDA <Temp_Var15  05344.    BMI PRG000_D920 ; If Temp_Var15 is negative, no intersect, jump to PRG000_D920  05345.   05346.    ; Temp_Var12 holds specific info:  05347.    ; Bit 0 - Set if Player's bbox bottom is HIGHER than object's bbox bottom  05348.    ; Bit 1 - Set if Player's bbox left edge is to the LEFT of object's bbox left edge  05349.   05350.    LDA <Temp_Var12  05351.    LSR A  05352.    BCC PRG000_D8EB ; If Player's bbox bottom is NOT higher than object's, jump to PRG000_D8EB  05353.   05354.    LDA <Temp_Var1 ; Get Player's bounding box top offset  05355.    SUB <Temp_Var11 ; Get vertical difference between Player and Object's bounding box bottoms  05356.    CMP #$08  05357.    BLS PRG000_D8EB ; If the result < 8, jump to PRG000_D8EB  05358.   05359.    ; Otherwise, flip the remaining bit of Temp_Var12  05360.    LDA <Temp_Var12  05361.    EOR #$01  05362.    STA <Temp_Var12  05363.   05364. PRG000_D8EB:  05365.   05366.    ; Set into status bits for this objcet  05367.    LDA <Temp_Var12  05368.    ORA Objects_PlayerHitStat,X  05369.    STA Objects_PlayerHitStat,X  05370.   05371.    LDA Player_StarInv  05372.    BEQ PRG000_D922 ; If Player is NOT invincible, jump to PRG000_D922  05373.   05374.    ; Player is invincible...  05375.   05376.    LDY Level_ObjectID,X ; Get object's ID -> Y  05377.    LDA Object_AttrFlags,Y ; Get this object's attribute flags  05378.    AND #OAT_HITNOTKILL  05379.    BNE PRG000_D922 ; If OAT_HITNOTKILL is set, jump to PRG000_D922  05380.   05381.    ; For all objects where bit 7 is not set in their attributes...  05382.   05383.    LDA #OBJSTATE_KILLED  05384.    STA Objects_State,X ; Set object state to Killed  05385.   05386.    LDA #-$38  05387.    STA <Objects_YVel,X ; Set Y Velocity to -$38  05388.   05389.    ; "Kick" sound  05390.    LDA Sound_QPlayer  05391.    ORA #SND_PLAYERKICK  05392.    STA Sound_QPlayer  05393.   05394.    ; 100 points pop up  05395.    LDA #$05  05396.    JSR Score_PopUp  05397.   05398.    JSR Level_ObjCalcXDiffs ; 'Y' is set to 0 if Player is to the right of object, 1 if to the left  05399.   05400.    LDA PRG000_D834,Y  05401.    STA <Objects_XVel,X ; Set X velocity  05402.   05403. PRG000_D920:  05404.    CLC ; Clear carry  05405.    RTS ; Return  05406.   05407.   05408. PRG000_D922:  05409.   05410.    ; For all objects where bit 7 is set in their attributes...  05411.   05412.    LDA <Temp_Var16 ; Returns 0 or 1, depending on original entry point  05413.    BNE PRG000_D929 ; If it was 1 (do not respond to hit), jump to PRG000_D929  05414.   05415.    ; Do hit routine  05416.    JSR Object_DoCollision ; Otherwise...  05417.   05418. PRG000_D929:  05419.    SEC ; Set carry  05420.    RTS ; Return  05421.   05422.   05423. ; FIXME: Anybody want to claim this?  05424. ; $D92B  05425.    .byte $F0, $00, $10, $20  05426.   05427.   05428.    ; Calculates the upper-left and returns the lower-right offsets  05429.    ; of this object's bounding box...  05430.    ; Temp_Var1 - upper left of bounding box  05431.    ; Temp_Var2 - offset to right bounding box  05432.    ; Temp_Var5 - bottom of bounding box  05433.    ; Temp_Var6 - offset to top bounding box  05434. ; $D92F  05435. Object_CalcBoundBox:  05436.    ; X is object's slot  05437.    ; Y is group relative object index  05438.   05439.    LDY Level_ObjectID,X ; Get this object's ID -> Y  05440.    LDA Object_AttrFlags,Y ; Get this object's attribute flags  05441.    AND #OAT_BOUNDBOXMASK ; Mask off the bounding box  05442.    ASL A  05443.    ASL A ; Shift left 2  05444.    TAY ; -> Y (selected bounding box for this object)  05445.   05446.    ; Calculate upper left of bounding box and lower right offsets  05447.    LDA <Objects_SpriteX,X  05448.    ADD Object_BoundBox,Y  05449.    STA <Temp_Var1 ; Temp_Var1 object's sprite X with offset  05450.   05451.    LDA <Objects_SpriteY,X  05452.    ADD Object_BoundBox+2,Y  05453.    STA <Temp_Var5 ; Temp_Var5 object's sprite Y with offset  05454.   05455.    LDA Object_BoundBox+1,Y  05456.    STA <Temp_Var2 ; Temp_Var2 has the right offset  05457.   05458.    LDA Object_BoundBox+3,Y  05459.    STA <Temp_Var6 ; Temp_Var6 has the bottom offset  05460.   05461.    RTS ; Return  05462.   05463.   05464.    ; Calculates the upper-left and returns the lower-right offsets  05465.    ; of this object's bounding box...  05466.    ; Temp_Var3 - upper left of bounding box  05467.    ; Temp_Var4 - offset to right bounding box  05468.    ; Temp_Var7 - bottom of bounding box  05469.    ; Temp_Var8 - offset to top bounding box  05470. ; $D955  05471. Object_CalcBoundBox2: ; Same as Object_CalcBoundBox in spirit, just different outputs, used for object-to-object collision  05472.    ; X is object's slot  05473.    ; Y is group relative object index  05474.   05475.    LDY Level_ObjectID,X ; Get this object's ID -> Y  05476.    LDA Object_AttrFlags,Y ; Get this object's attribute flags  05477.    AND #OAT_BOUNDBOXMASK ; Mask off the bounding box  05478.    ASL A  05479.    ASL A ; Shift left 2  05480.    TAY ; -> Y (selected bounding box for this object)  05481.   05482.    ; Calculate upper left of bounding box and lower right offsets  05483.    LDA <Objects_SpriteX,X  05484.    ADD Object_BoundBox,Y  05485.    STA <Temp_Var3 ; Temp_Var3 object's sprite X with offset  05486.   05487.    LDA <Objects_SpriteY,X  05488.    ADD Object_BoundBox+2,Y  05489.    STA <Temp_Var7 ; Temp_Var7 object's sprite Y with offset  05490.   05491.    LDA Object_BoundBox+1,Y  05492.    STA <Temp_Var4 ; Temp_Var4 has the right offset  05493.   05494.    LDA Object_BoundBox+3,Y  05495.    STA <Temp_Var8 ; Temp_Var8 has the bottom offset  05496.   05497.    RTS ; Return  05498.   05499.   05500. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05501. ; ObjectObject_Intersect  05502. ;  05503. ; Determines if the Player/Object and the OTHER Object indexed  05504. ; by 'X' have intersected according to the bounding box data  05505. ;  05506. ; X = index of on-screen object  05507. ;  05508. ; Returns carry SET if Player/Object and Object intersected  05509. ; Temp_Var12 holds specific info:  05510. ; Bit 0 - Set if Player/Object's bbox bottom is HIGHER than  05511. ; object's bbox bottom  05512. ; Bit 1 - Set if Player/Object's bbox left edge is to the LEFT of  05513. ; object's bbox left edge  05514. ;  05515. ; Note that this is performed by the "sprite" (or screen-relative)  05516. ; positions of the Player/Object and the OTHER Object, and may not  05517. ; be accurate (because it's not a full 16-bit coordinate check) and  05518. ; more logic is needed after this to determine completely if there  05519. ; should be an actual collision. See use of ObjectObject_Intersect  05520. ; to get an idea what else needs to be done...  05521. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05522. ; $D97B  05523. ObjectObject_Intersect:  05524.    LDY #$00 ; Y = 0  05525.    STY <Temp_Var12 ; Temp_Var12 = 0 (Player's bbox is to the RIGHT of the object's left edge, until determined otherwise)  05526.   05527.   05528.    ; Right now we're considering the left edges of the Player and Object  05529.    ; we're detecting against  05530.   05531.    LDA <Temp_Var3 ; Left of Player's bounding box  05532.    SUB <Temp_Var1 ; Left of object's bound box  05533.    STA <Temp_Var11 ; Difference between the two -> Temp_Var11  05534.   05535.    ASL A ; Sets carry if it was a negative result  05536.   05537.    LDA <Temp_Var2 ; Get the object's right edge bounding box offset  05538.   05539.    BCC PRG000_D997 ; If the calculated difference was NOT negative (Player's bbox left edge is to the RIGHT of object's bbox left edge), jump to PRG000_D997  05540.   05541.    ; Player's box left edge is to the LEFT of the object's left edge  05542.   05543.    ; Negate Temp_Var11 (the difference), making it positive  05544.    LDA <Temp_Var11  05545.    EOR #$ff  05546.    STA <Temp_Var11  05547.    INC <Temp_Var11  05548.   05549.    INC <Temp_Var12 ; Temp_Var12 = 1 (Player's bbox is to the LEFT of object's left edge)  05550.   05551.    LDA <Temp_Var4 ; Get the Player's right edge bounding box offset  05552.   05553. PRG000_D997:  05554.    CMP <Temp_Var11  05555.    BLT PRG000_D9B7 ; If the left edge offset is less than the right edge offset (CARRY CLEAR), jump to PRG000_D9B7 (RTS)  05556.   05557.   05558.    ; That didn't happen...  05559.   05560.    ASL <Temp_Var12 ; Push result bit up  05561.   05562.    LDA <Temp_Var7 ; Player's bounding box bottom  05563.    SUB <Temp_Var5 ; Object's bouncing box bottom  05564.    STA <Temp_Var11 ; Store difference -> Temp_Var11  05565.   05566.    ASL A ; Sets carry if it was a negative result  05567.   05568.    LDA <Temp_Var6 ; Get object's bounding box top edge offset  05569.   05570.    BCC PRG000_D9B5 ; If the calculated difference was NOT negative (Player's bbox bottom is LOWER than object's bbox bottom), jump to PRG000_D9B5  05571.   05572.    ; Negate Temp_Var11 (the difference), making it positive  05573.    LDA <Temp_Var11  05574.    EOR #$ff  05575.    STA <Temp_Var11  05576.    INC <Temp_Var11  05577.   05578.    INC <Temp_Var12 ; Set bit 0 of Temp_Var12  05579.   05580.    LDA <Temp_Var8 ; Get Player's bounding box top edge offset  05581.   05582. PRG000_D9B5:  05583.    CMP <Temp_Var11 ; Set final carry bit to determine if we intersected or not  05584.   05585. PRG000_D9B7:  05586.   05587.    ; Most importantly, status of the carry flag is returned  05588.    ; If carry is CLEAR, we did not intersect Player to Object  05589.   05590.    ; Temp_Var12 holds specific info:  05591.    ; Bit 0 - Set if Player's bbox bottom is HIGHER than object's bbox bottom  05592.    ; Bit 1 - Set if Player's bbox left edge is to the LEFT of object's bbox left edge  05593.   05594.    RTS ; Return  05595.   05596.   05597.    ; Proper Collision routine for this object  05598. ; $D9BB  05599. Object_DoCollision:  05600.    LDX <SlotIndexBackup ; X = the current object slot  05601.   05602.   05603.    LDA ObjGroupRel_Idx ; Get the object's group relative index  05604.    ASL A ; Shift left 1 (2 byte index)  05605.    TAY ; -> Y  05606.   05607.    ; Get address from ObjectGroup_CollideJumpTable...  05608.    LDA ObjectGroup_CollideJumpTable,Y  05609.    STA <Temp_Var1  05610.    LDA ObjectGroup_CollideJumpTable+1,Y  05611.    STA <Temp_Var2  05612.    JMP [Temp_Var1] ; Jump to the acquired address!  05613.   05614.    ; RAS: Dead data: Specified frame of "suit lost" object  05615.    ; to display when the cooresponding suit was lost (not  05616.    ; used for any of the "regular" power ups)  05617. SMB3J_SuitLossFrame: .byte $00, $00, $00, $00, $01, $02, $03  05618.   05619. ; $D9D3  05620. Player_GetHurt:  05621.    ; If Player is...  05622.    LDA Player_FlashInv ; ... flashing invincible ...  05623.    ORA Player_Statue ; ... a statue ...  05624.    ORA Player_StarInv ; ... invincible by star ...  05625.    ORA Player_SuitLost ; ... just lost a power-up suit ...  05626.    ORA <Player_HaltGame ; ... gameplay halted ...  05627.    ORA Player_HaltTick ; ... Player halted ...  05628.    ORA Player_DebugNoHitFlag ; ... debug invincibility flag is set (unused) ...  05629.    BNE PRG000_D9B7 ; ... then jump to PRG000_D9B7 (RTS)  05630.   05631.    JMP PRG000_DA15 ; Jump to PRG000_DA15 (skips lost/dead Japanese version code)  05632.   05633.    ;;;;;;;;;;;;;; Begin SMB3-J Only Code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05634.   05635.    ; RAS: Lost/Dead Code -- This was the Japanese version suit loss code  05636.    ; For detail why it was removed, see PRG007 LostShoe_Pattern  05637. ; $D9EC  05638.    LDA Player_Kuribo  05639.    BNE PRG000_D9F7 ; If Player is in Kuribo's Shoe, jump to PRG000_D9F7  05640.   05641.    ; Player is NOT in Kuribo's Shoe...  05642.   05643.    LDA <Player_Suit  05644.    CMP #PLAYERSUIT_SUPERSUITBEGIN  05645.    BLS PRG000_DA4E ; If Player is not in one of the Super Suits, jump to PRG000_DA4E  05646.   05647. PRG000_D9F7:  05648.   05649.    ; Player was in a Kuribo's Shoe or one of the Super Suits  05650.   05651.    ; Play "shoe lost" sound  05652.    LDA Sound_QLevel1  05653.    ORA #SND_LEVELSHOE  05654.    STA Sound_QLevel1  05655.   05656.    LDY <Player_Suit ; Y = Player's power up  05657.    LDA SMB3J_SuitLossFrame,Y ; Get correct "loss" frame  05658.    STA <Temp_Var1 ; -> Temp_Var1  05659.    JSR Player_LoseKuribo ; Suit pops off  05660.   05661.    ; Switch back to just Big  05662.    LDA #$01  05663.    STA Player_QueueSuit  05664.   05665.    ; You no longer have the Kuribo's Shoe  05666.    LDA #$00  05667.    STA Player_Kuribo  05668.   05669.    BEQ PRG000_DA6D ; Jump (technically always) to PRG000_DA6D  05670.   05671.    ;;;;;;;;;;;;;; End SMB3-J Only Code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05672.   05673. PRG000_DA15:  05674.    LDA Player_Kuribo  05675.    BNE PRG000_DA32 ; If Player is in Kuribo's shoe, jump to PRG000_DA32  05676.   05677.    LDA <Player_Suit  05678.    CMP #PLAYERSUIT_FIRE ; RAS: Change this to "PLAYERSUIT_SUPERSUITBEGIN" and you restore Japanese version's "always shrink" code!!  05679.    BLS PRG000_DA4E ; If Player is Big or small, jump to PRG000_DA4E  05680.   05681.    ; Higher level power-up suits...  05682.    LDA #$17  05683.    STA Player_SuitLost ; Player_SuitLost = $17  05684.   05685.    ; Play Power up lost sound  05686.    LDA Sound_QLevel1  05687.    ORA #SND_LEVELPOOF  05688.    STA Sound_QLevel1  05689.   05690.    LDA #$02 ; Return to Big (RAS: Would be small in Japanese version!!)  05691.    JMP PRG000_DA44 ; Jump to PRG000_DA44  05692.   05693. PRG000_DA32:  05694.   05695.    ; Play "shoe lost" sound  05696.    LDA Sound_QLevel1  05697.    ORA #SND_LEVELSHOE  05698.    STA Sound_QLevel1  05699.   05700.    ; RAS: This lost its meaning, but it marks you to lose the Kuribo's  05701.    ; shoe specifically; see above for lost/dead SMB3-J code where  05702.    ; alternate Temp_Var1 values would be used...  05703.    ; (The other index values display as garbage now instead of the suit,  05704.    ; see details at PRG007 LostShoe_Pattern)  05705.    LDA #$00  05706.    STA <Temp_Var1 ; Temp_Var1 = 0  05707.   05708.    JSR Player_LoseKuribo ; Setup effect of Kuribo's shoe "flying off"  05709.    JMP PRG000_DA47 ; Jump to PRG000_DA47  05710.   05711. PRG000_DA44:  05712.    STA Player_QueueSuit ; Queue power-up change  05713.   05714. PRG000_DA47:  05715.    LDA #$00  05716.    STA Player_Kuribo ; Player no longer has Kuribo's shoe (if he even did a moment ago)  05717.    BEQ PRG000_DA6D ; Jump (technically always) to PRG000_DA6D  05718.   05719. PRG000_DA4E:  05720.   05721.    ; Player is only big or small...  05722.   05723.    LDA <Player_Suit  05724.    BEQ PRG000_DA7A ; If Player is small, jump to PRG000_DA7A (gonna die!!)  05725.   05726.    LDA #$02  05727.    STA Player_QueueSuit ; Return to Big  05728.   05729.    ; RAS: NOTE: Deprecated logic! We won't get here in SMB3-US at this  05730.    ; high of a power level anymore...  05731.    LDA <Player_Suit  05732.    CMP #PLAYERSUIT_SUPERSUITBEGIN  05733.    BGS PRG000_DA6D ; If Player's current power-up is a Super Suit, jump to PRG000_DA6D  05734.   05735.    ; Play shrinking sound!!  05736.    LDA Sound_QPlayer  05737.    ORA #SND_PLAYERPIPE  05738.    STA Sound_QPlayer  05739.   05740.    LDA #$2f  05741.    STA Player_Grow ; Player_Grow = $2f (shrinking!)  05742.    DEC Player_QueueSuit ; Get small!  05743.   05744. PRG000_DA6D:  05745.    LDA #$71  05746.    STA Player_FlashInv ; Player_FlashInv = $71  05747.   05748.    LDA #$00  05749.    STA Player_Flip ; Player not somersaulting  05750.   05751.    BEQ PRG000_DAAE ; Jump (technically always) to PRG000_DAAE (cosmetic bugfix?)  05752.   05753.    RTS ; Return  05754.   05755. PRG000_DA7A:  05756.    LDX <SlotIndexBackup ; X = SlotIndexBackup  05757.   05758.   05759. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05760. ; Player_Die  05761. ;  05762. ; Simple and to the point: Starts the death song,  05763. ; resets a bunch of variables that get in the way,  05764. ; changes to small, etc.  05765. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05766. Player_Die:  05767.    ; Queue death song  05768.    LDA Sound_QMusic1  05769.    ORA #MUS1_PLAYERDEATH  05770.    STA Sound_QMusic1  05771.   05772.    ; Clear a bunch of stuff at time of death  05773.    LDA #$00  05774.    STA <Player_XVel  05775.    STA <Obj01_Flag  05776.    STA Player_Flip  05777.    STA Player_FlashInv  05778.    STA Player_Kuribo  05779.    STA Player_StarInv  05780.    STA Player_Statue  05781.    STA Level_PSwitchCnt  05782.   05783.    LDA #$01  05784.    STA Player_QueueSuit ; Queue change to "small"  05785.   05786.    LDA #-64  05787.    STA <Player_YVel ; Player_YVel = -64  05788.   05789.    LDA #$30  05790.    STA Event_Countdown ; Event_Countdown = $30 (ticks until dropped back to map)  05791.   05792.    LDA #$01  05793.    STA <Player_IsDying ; Player_IsDying = 1  05794.   05795. PRG000_DAAE:  05796.    ; Ensure Player_FlipBits is correct?  05797.    ; RAS: May be a cosmetic bugfix for player coming out of a somersault  05798.    ; (see jump to PRG000_DAAE) and getting hit, but I'm not really sure...  05799.    LDA <Player_FlipBits  05800.    AND #$7f  05801.    STA <Player_FlipBits  05802.   05803.    RTS ; Return  05804.   05805.    ; Set display effect for Player losing Kuribo's shoe  05806.    ; RAS: This also USED to setup for losing other power-ups in  05807.    ; the Japanese version, but that is removed and broken in US.  05808.    ; See notes at PRG007 "LostShoe_Pattern" for details...  05809. Player_LoseKuribo:  05810.    LDY #$05 ; Y = 5  05811.   05812. PRG000_DAB7:  05813.    LDA SpecialObj_ID,Y  05814.    BEQ PRG000_DAC0 ; If this slot is open, jump to PRG000_DAC0  05815.   05816.    DEY ; Y--  05817.    BPL PRG000_DAB7 ; While Y >= 0, loop!  05818.   05819.    RTS ; Return  05820.   05821. PRG000_DAC0:  05822.    LDA #SOBJ_KURIBOSHOE  05823.    STA SpecialObj_ID,Y ; Lost Kuribo's shoe!  05824.   05825.    ; Set object at Player  05826.    LDA <Player_Y  05827.    STA SpecialObj_YLo,Y  05828.   05829.    LDA <Player_YHi  05830.    STA SpecialObj_YHi,Y  05831.   05832.    LDA <Player_X  05833.    STA SpecialObj_XLo,Y  05834.   05835.    LDA #-$30  05836.    STA SpecialObj_YVel,Y ; Y velocity = -$30  05837.   05838.    ; Decide proper X velocity based on Player's facing direction  05839.    LDA #$00  05840.    CMP <Player_FlipBits  05841.   05842.    LDA #16  05843.    BGE PRG000_DAE3  05844.   05845.    LDA #-16  05846.   05847. PRG000_DAE3:  05848.    STA SpecialObj_XVel,Y ; Set appropriate X velocity  05849.   05850.    ; RAS: This is always zero in SMB3-US, but would have  05851.    ; been set to other values in the Japanese original  05852.    LDA <Temp_Var1  05853.    STA SpecialObj_Data,Y  05854.   05855.    RTS ; Return  05856.   05857.    ; X velocities as appropriate based on which direction  05858.    ; Player was when he killed the enemy  05859. EnemyKill_XVels: .byte -$08, $08  05860.   05861.    ; Tail attack X offset, based on Player's facing direction  05862. Player_TailAttackXOff: .byte $11, -$0A  05863.   05864. PRG000_DAF0:  05865.    .byte -$0A, $11  05866.   05867.   05868. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05869. ; Object_HitByTailOrBouncer  05870. ;  05871. ; Test if object is getting hit by Player's tail attack  05872. ; or a left/right bouncing block  05873. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05874. Object_HitByTailOrBouncer:  05875.    ; Clear the "Tail Attacked" bit  05876.    LDA Objects_PlayerHitStat,X  05877.    AND #%11110111  05878.    STA Objects_PlayerHitStat,X  05879.   05880.    JSR Object_RespondToTailAttack ; Get hit by tail attack if appropriate  05881.   05882.    ; Handle a left/right bouncer if it impacts an object  05883.    LDA LRBounce_Y  05884.    CMP #$ff  05885.    BEQ PRG000_DB16 ; If LRBounce_Y = $FF, jump to PRG000_DB16 (RTS)  05886.    STA <Temp_Var7 ; Temp_Var7 = LRBounce_Y  05887.   05888.    LDA #$0f  05889.    STA <Temp_Var8 ; Temp_Var8 = $0F  05890.   05891.    LDA LRBounce_X  05892.    STA <Temp_Var3 ; Temp_Var3 = LRBounce_X  05893.   05894.    LDA #$0f  05895.    STA <Temp_Var4 ; Temp_Var4 = $0F  05896.   05897.    JSR Player_TailAttackDo ; Perform tail attack type action  05898.   05899. PRG000_DB16:  05900.    RTS ; Return  05901.   05902.   05903. PRG000_DB17: .byte $10, -$10  05904.   05905.   05906. Object_RespondToTailAttack:  05907.    LDA Player_TailAttack  05908.    BEQ PRG000_DB16 ; If Player is not tail attacking, jump to PRG000_DB16 (RTS)  05909.   05910.    ; Tail attack only kicks at counter values $09 and $0C  05911.    CMP #$0c  05912.    BEQ PRG000_DB26 ; If tail attack counter = $0C, jump to PRG000_DB26  05913.    CMP #$09  05914.    BNE PRG000_DB16 ; If tail attack counter <> $09, jump to PRG000_DB16 (RTS)  05915.   05916. PRG000_DB26:  05917.    LDA <Player_FlipBits  05918.    AND #$40  05919.    TAY ; Y = $00 or $40, whether Player is flipped  05920.    BEQ PRG000_DB2F ; If 'Y' = 0, jump to PRG000_DB2F  05921.   05922.    LDY #$01 ; Y = 1  05923.   05924. PRG000_DB2F:  05925.    LDA Player_TailAttackXOff,Y  05926.    ADD <Player_SpriteX  05927.    STA <Temp_Var3 ; Temp_Var3 = appropriate X offset for tail attack  05928.   05929.    LDA #$0a  05930.    STA <Temp_Var4 ; Temp_Var4 = $0A  05931.   05932.    LDA <Player_SpriteY  05933.    ADD #$10  05934.    STA <Temp_Var7 ; Temp_Var7 = tail attack offset  05935.   05936.    LDA #$0f  05937.    STA <Temp_Var8 ; Temp_Var8 = $0F  05938.   05939. Player_TailAttackDo:  05940.    LDY Objects_State,X ; Y = object's current state  05941.   05942.    LDA Obj2Obj_EnByState,Y  05943.    BNE PRG000_DB16 ; If object is not hit tested in this state, jump to PRG000_DB16 (RTS)  05944.   05945.    JSR Object_AnySprOffscreen  05946.    BNE PRG000_DB16 ; If any sprite of the object is off-screen, jump to PRG000_DB16 (RTS)  05947.   05948.    JSR Object_CalcBoundBox  05949.    JSR ObjectObject_Intersect  05950.    BCC PRG000_DB16 ; If Player and object are not intersecting, jump to PRG000_DB16 (RTS)  05951.   05952.    ; Set "Tail Attacked" bit  05953.    LDA Objects_PlayerHitStat,X  05954.    ORA #%00001000  05955.    STA Objects_PlayerHitStat,X  05956.   05957.    LDY ObjGroupRel_Idx ; Y = object's group-relative index  05958.   05959.    LDA ObjectGroup_Attributes3,Y  05960.    AND #OA3_TAILATKIMMUNE  05961.    BNE PRG000_DB16 ; If OA3_TAILATKIMMUNE is SET (Object cannot be tail-attacked), jump to PRG000_DB16 (RTS)  05962.   05963.    LDA <Temp_Var4  05964.    CMP #$0f  05965.    BEQ Enemy_Kill  05966.   05967.    LDY #$00 ; Y = 0  05968.   05969.    LDA <Player_FlipBits  05970.    BEQ PRG000_DB7A ; If Player is not turned around, jump to PRG000_DB7A  05971.   05972.    INY ; Y = 1  05973.   05974. PRG000_DB7A:  05975.   05976.    ; Set ShellKillFlash vars  05977.    LDA PRG000_DB17,Y  05978.    ADD <Player_X  05979.    STA ShellKillFlash_X  05980.   05981.    LDA <Player_Y  05982.    ADD #$10  05983.    STA ShellKillFlash_Y  05984.   05985.    LDA #$0a  05986.    STA ShellKillFlash_Cnt  05987.   05988.   05989. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05990. ; Enemy_Kill  05991. ;  05992. ; Kills an enemy; flips them over, plays the "kick" sound  05993. ; If attribute 3, bit 6 is SET, there's some special  05994. ; behavior described below (using CollideJumpTable as a  05995. ; value rather than address, alternate dead state 3, etc.)  05996. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  05997. Enemy_Kill:  05998.   05999.    ; Set timer 2 to 12  06000.    LDA #12  06001.    STA Objects_Timer2,X  06002.   06003.    ; "Kick" sound  06004.    LDA Sound_QPlayer  06005.    ORA #SND_PLAYERKICK  06006.    STA Sound_QPlayer  06007.   06008.    LDY ObjGroupRel_Idx ; Y = object group relative index  06009.    LDA ObjectGroup_Attributes3,Y ; Get this object's attribute set 3  06010.    AND #OA3_DIESHELLED  06011.    BNE PRG000_DBB6 ; If OA3_DIESHELLED is set, jump to PRG000_DBB6  06012.   06013.    ; OA3_DIESHELLED is not set...  06014.   06015.    LDA Player_Slide  06016.    BNE PRG000_DBB2 ; If Player is sliding, jump to PRG000_DBB2  06017.   06018.    LDA Kill_Tally ; Get current kill tally  06019.    JSR Score_Get100PlusPts ; Get appropriate score based on kill tally  06020.   06021. PRG000_DBB2:  06022.    LDA #$06 ; A = 6 (object state 6, killed)  06023.    BNE PRG000_DBCF ; Jump (technically always) to PRG000_DBCF  06024.   06025.   06026. PRG000_DBB6:  06027.   06028.    ; Attribute set 3 bit 6 is set...  06029.   06030.    ; Y *= 2 (2 byte index)  06031.    TYA  06032.    ASL A  06033.    TAY  06034.   06035.    LDA ObjectGroup_CollideJumpTable+1,Y ; Get upper byte of collision jump entry  06036.    AND #%11111000  06037.    CMP #%00001000 ; If only bit 3 is set and 4-7 are clear, this is a new object ID to change to  06038.    BNE PRG000_DBC8 ; If the above is not the case, jump to PRG000_DBC8  06039.   06040.    ; SPECIAL CASE: Collide Jump table lower byte specifies a new object ID  06041.   06042.    LDA ObjectGroup_CollideJumpTable,Y ; Get the new ID  06043.    STA Level_ObjectID,X ; Set the new ID  06044.   06045. PRG000_DBC8:  06046.    ; Timer 3 set to $FF  06047.    LDA #$ff  06048.    STA Objects_Timer3,X  06049.   06050.    LDA #OBJSTATE_SHELLED ; A = Shelled  06051.   06052. PRG000_DBCF:  06053.    STA Objects_State,X ; Set new object state  06054.   06055.    LDA #-$30 ; A = -$30  06056.   06057.    LDY <Temp_Var4  06058.   06059.    CPY #$0f  06060.    BEQ PRG000_DBDC ; If Temp_Var4 = $0F, jump to PRG000_DBDC  06061.   06062.    LDA #-$50 ; A = -$50  06063.   06064. PRG000_DBDC:  06065.    STA <Objects_YVel,X ; Set Y velocity appropriately  06066.   06067.    ; Set appropriate X Velocity based on facing direction of  06068.    ; Player when he killed the enemy  06069.    JSR Level_ObjCalcXDiffs  06070.    LDA EnemyKill_XVels,Y  06071.    STA <Objects_XVel,X  06072.   06073.    ; Set vertical flip on the object  06074.    LDA Objects_FlipBits,X  06075.    ORA #SPR_VFLIP  06076.    STA Objects_FlipBits,X  06077.   06078.    RTS ; Return  06079.   06080.   06081. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06082. ; ObjectToObject_HitTest  06083. ;  06084. ; Determines if the object specified in 'X' has collided  06085. ; with any of the other active objects not including  06086. ; Player (see Object_HitTest/Object_HitTestRespond)  06087. ;  06088. ; If the object has collided with another object:  06089. ; Carry flag is SET  06090. ; 'Y' = index of the collided-with object  06091. ; 'A' = ObjectID of the collided-with object  06092. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06093.    ; Enable object-to-object by state (0 = Enabled, 1 = Disabled)  06094. Obj2Obj_EnByState:  06095.    .byte $01 ; State 0: Dead/Empty  06096.    .byte $01 ; State 1: Initializing  06097.    .byte $00 ; State 2: Normal  06098.    .byte $00 ; State 3: Shelled  06099.    .byte $00 ; State 4: Held  06100.    .byte $00 ; State 5: Kicked  06101.    .byte $01 ; State 6: Killed  06102.    .byte $01 ; State 7: Squashed  06103.    .byte $01 ; State 8: Dying  06104.   06105.    ; $DBF8  06106. ObjectToObject_HitTest:  06107.    LDA Objects_SprVVis,X  06108.    BNE PRG000_DC54 ; If any sprites are vertically off-screen, jump to PRG000_DC54  06109.   06110.    ; No sprites are vertically off-screen...  06111.   06112.    LDA Objects_SprHVis,X  06113.    AND #%11000000  06114.    CMP #%11000000  06115.    BEQ PRG000_DC54 ; If both of the end sprite are horizontally off-screen, jump to PRG000_DC54  06116.   06117.    JSR Object_CalcBoundBox2 ; Calculate THIS object's bounding box  06118.   06119. PRG000_DC09:  06120.    LDX #$04 ; X = 4  06121. PRG000_DC0B:  06122.    CPX <SlotIndexBackup  06123.    BEQ PRG000_DC51 ; If this object slot is the current object, jump to PRG000_DC51 (don't do anything to self)  06124.   06125.    LDY Objects_State,X  06126.    LDA Obj2Obj_EnByState,Y  06127.    BNE PRG000_DC51 ; If the state this object is in does not do object-to-object detection, jump to PRG000_DC51 (do nothing)  06128.   06129.    LDA Objects_SprVVis,X  06130.    BNE PRG000_DC51 ; If sprites are vertically off-screen, jump to PRG000_DC51 (do nothing)  06131.   06132.    LDA Objects_SprHVis,X  06133.    AND #%11000000  06134.    CMP #%11000000  06135.    BEQ PRG000_DC51 ; If two sprites are horizontally off-screen, jump to PRG000_DC51 (do nothing)  06136.   06137.    JSR Object_CalcBoundBox ; Calculate OTHER object's bounding box  06138.    JSR ObjectObject_Intersect ; Returns carry SET if object and OTHER object intersected  06139.    BCC PRG000_DC51 ; If object did NOT intersect the OTHER object, jump to PRG000_DC51 (do nothing)  06140.   06141.    ; These two objects have collided...!  06142.   06143.    LDY <SlotIndexBackup ; Y = object slot index  06144.   06145.    LDA <Objects_X,X  06146.    SUB Objects_X,Y ; Difference between the object and the OTHER object's X  06147.    PHA ; Save the difference  06148.   06149.    LDA <Objects_XHi,X  06150.    SBC Objects_XHi,Y ; Difference between the object and the OTHER object's X Hi  06151.    STA <Temp_Var1 ; -> Temp_Var1  06152.   06153.    PLA ; Restore the lower X difference  06154.   06155.    ; Don't quite understand the logic, but this determines if the  06156.    ; objects are actually on the same screen instead of just  06157.    ; seeming to due to the low accuracy of sprite coordinates  06158.    ADC #$80  06159.    LDA <Temp_Var1  06160.    ADC #$00  06161.    BNE PRG000_DC51 ; If the objects did not actually collide, jump to PRG000_DC51 (do nothing)  06162.   06163.    SEC ; Object's collided! Set carry!  06164.   06165.    LDY Level_ObjectID,X ; Y = OTHER object's ID  06166.   06167.    LDA Object_AttrFlags,Y  06168.    AND #OAT_HITNOTKILL  06169.    BEQ PRG000_DC57 ; If this object is NOT a "Hit-Not-Kill" type, jump to PRG000_DC57  06170.   06171. PRG000_DC51:  06172.    DEX ; X--  06173.    BPL PRG000_DC0B ; While X >= 0, loop!  06174.   06175. PRG000_DC54:  06176.    CLC ; Clear carry (collided with no other object)  06177.    BCC PRG000_DC5C ; Jump (technically always) to PRG000_DC5C  06178.   06179. PRG000_DC57:  06180.    TXA  06181.    TAY ; Index of the OTHER object that this object collided with -> 'Y'  06182.    LDA Level_ObjectID,Y ; A = the ID of the OTHER object  06183.   06184. PRG000_DC5C:  06185.    LDX <SlotIndexBackup ; Restore 'X' as the object slot index  06186.    RTS ; Return  06187.   06188.   06189.    ; This changes a tile based on Temp_Var13-16 coordinates:  06190.    ; Temp_Var13 / Temp_Var14 -- Y Hi and Lo  06191.    ; Temp_Var15 / Temp_Var16 -- X Hi and Lo  06192. Level_ChangeTile_ByTempVars:  06193.   06194.    PHA ; Save 'A'  06195.    LDA Level_7Vertical  06196.    BEQ PRG000_DC7B ; If level is NOT vertical, jump to PRG000_DC7B  06197.   06198.    LDY <Temp_Var13  06199.    LDA <Temp_Var14  06200.    JSR LevelJct_GetVScreenH ; Adjust coordinates for vertical  06201.   06202.    PHA ; Save 'A' (Y Lo)  06203.   06204.    ; Set tile grid modify address  06205.    LDA Tile_Mem_AddrVL,Y  06206.    STA <Temp_Var1  06207.    LDA Tile_Mem_AddrVH,Y  06208.    STA <Temp_Var2  06209.   06210.    PLA ; Restore 'A' (Y Lo)  06211.   06212.    JMP PRG000_DC91 ; Jump to PRG000_DC91  06213.   06214. PRG000_DC7B:  06215.    LDA <Temp_Var15  06216.    ASL A  06217.    TAY ; Y = Temp_Var15 (X Hi) shifted left 1 (2 bytes index per screen for Tile_Mem_Addr)  06218.   06219.    ; Set tile grid modify address  06220.    LDA Tile_Mem_Addr,Y  06221.    STA <Temp_Var1  06222.    LDA Tile_Mem_Addr+1,Y  06223.    STA <Temp_Var2  06224.   06225.    LDA <Temp_Var13  06226.    BEQ PRG000_DC8F ; If Y Hi = 0, jump to PRG000_DC8F  06227.   06228.    INC <Temp_Var2 ; Otherwise, offset to lower screen area  06229.   06230. PRG000_DC8F:  06231.    LDA <Temp_Var14 ; A = Y lo  06232.   06233. PRG000_DC91:  06234.    AND #$f0  06235.    STA <Temp_Var3 ; Tile aligned "low" (makes row)  06236.   06237.    LDA <Temp_Var16  06238.    LSR A  06239.    LSR A  06240.    LSR A  06241.    LSR A  06242.    ORA <Temp_Var3 ; Makes column  06243.   06244.    TAY ; Y = offset to specific tile  06245.   06246.    PLA ; Restore 'A' (tile index)  06247.   06248.    STA [Temp_Var1],Y ; Change tile as appropriate  06249.   06250.    RTS ; Return  06251.   06252.   06253. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06254. ; Object_CalcCoarseXDiff  06255. ;  06256. ; Calculates a "coarse" X difference with the Player,  06257. ; returning a one byte value that determines the  06258. ; difference in X/XHi coordinates in units of 4 pixels  06259. ; in Temp_Var15. Temp_Var16 is set to $40 and the  06260. ; carry flag is set if the difference was negative.  06261. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06262. ; $DCA2  06263. Object_CalcCoarseXDiff:  06264.    LDA <Objects_X,X  06265.    SUB <Player_X  06266.    STA <Temp_Var15 ; Temp_Var15 = difference between Object and Player X  06267.   06268.    LDA <Objects_XHi,X  06269.    SBC <Player_XHi ; Calc diff between X His  06270.   06271.    LSR A ; Push low bit of "hi" difference -> carry  06272.    ROR <Temp_Var15 ; Cycle carry into Temp_Var15 at high bit; will be discarding low bit  06273.    LSR A ; Push low bit of "hi" difference -> carry  06274.    ROR <Temp_Var15 ; Cycle carry into Temp_Var15 at high bit; will be discarding low bit  06275.   06276.    ; Temp_Var15 now holds a difference between the Object and Player  06277.    ; X coordinates in units of 4 pixels (works up to two screen  06278.    ; widths; anything greater and object was probably removed anyway)  06279.   06280.    ; Note the following only works because there is no way that bit 5 and 7  06281.    ; could be a part of the actual difference, just the sign factor, since  06282.    ; a level cannot be more than 10 screens in width.  06283.    ASL A ; Shift remaining difference left 1; carry set means negative difference  06284.    AND #$40  06285.    STA <Temp_Var16 ; Temp_Var16 being $40 also means negative difference  06286.   06287.    RTS ; Return  06288.   06289.   06290. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06291. ; Object_CalcCoarseYDiff  06292. ;  06293. ; Calculates a "coarse" Y difference with the Player,  06294. ; returning a one byte value that determines the  06295. ; difference in Y/YHi coordinates in units of 8 pixels.  06296. ; Returns Temp_Var15 in the format of a crude signed  06297. ; value for Y Hi in bit 6 and 7  06298. ; [00 -> Y Hi = 0, 01 -> Y Hi = 1, 11 -> Y Hi = negative]  06299. ; and the base Y difference in the bits 0 - 5 (so units  06300. ; of 8 pixels.)  06301. ; Temp_Var16 holds the raw difference in "Y Hi"  06302. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06303. ; $DCB9  06304. Object_CalcCoarseYDiff  06305.    LDA <Objects_Y,X  06306.    SUB <Player_Y  06307.    STA <Temp_Var15 ; Temp_Var15 = difference between object's Y and Player's Y  06308.   06309.    LDA <Objects_YHi,X  06310.    SBC <Player_YHi  06311.    STA <Temp_Var16 ; Temp_Var16 = difference between object's Y Hi and Player's Y Hi  06312.   06313.    LSR A ; least significant bit of Y Hi -> carry  06314.   06315.    ROR <Temp_Var15 ; Temp_Var15 takes on the "Hi" value in its most significant bit  06316.   06317.    LSR A ; next least significant bit of Y Hi -> carry  06318.    ROR <Temp_Var15 ; The new Temp_Var15's least significant bit is pushed into its bit 7  06319.   06320.    ; So now Temp_Var15 holds the main Y difference in its first 5 bits  06321.    ; Bit 6 and 7 form a signed portion of the "hi" value -- 00 -> Y Hi = 0, 01 -> Y Hi = 1, 11 -> Y Hi = negative  06322.   06323.    RTS ; Return  06324.   06325.   06326. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06327. ; Object_ApplyYVel  06328. ; Object_ApplyYVel_NoLimit  06329. ;  06330. ; Adds the 4.4FP Y velocity to object and prevents object  06331. ; from falling faster than OBJECT_MAXFALL (unless using  06332. ; Object_ApplyYVel_NoLimit which does not enforce this)  06333. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06334. ; $DCCD  06335. Object_ApplyYVel:  06336.    LDA <Objects_YVel,X  06337.    BMI Object_ApplyYVel_NoLimit ; If Object's Y Vel < 0 (moving upward), jump to Object_ApplyYVel_NoLimit  06338.   06339.    CMP #OBJECT_MAXFALL  06340.    BLS Object_ApplyYVel_NoLimit ; If Object's Y Vel < OBJECT_MAXFALL, jump to Object_ApplyYVel_NoLimit  06341.   06342.    LDA #OBJECT_MAXFALL  06343.    STA <Objects_YVel,X ; Cap Y Velocity to OBJECT_MAXFALL  06344.   06345. ; $DCD9  06346. Object_ApplyYVel_NoLimit:  06347.    TXA  06348.    ADD #(Objects_YVel - Objects_XVel)  06349.    TAX ; Offset to Y velocities  06350.   06351.    JSR Object_AddVelFrac ; Apply the velocity to the object's position  06352.   06353.    LDX <SlotIndexBackup ; Restore X as Object slot index  06354.   06355.    RTS ; Return  06356.   06357.   06358. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06359. ; Object_ApplyXVel  06360. ;  06361. ; Adds the 4.4FP X velocity to object and will disable  06362. ; X Hi's application if the object wants it that way..  06363. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06364. ; $DCE4  06365. Object_ApplyXVel:  06366.    JSR Object_AddVelFrac  06367.   06368.    LDY Level_7Vertical  06369.    BEQ PRG000_DCFA ; If Level is NOT vertical, jump to PRG000_DCFA  06370.   06371.    ; Non-vertical levels...  06372.   06373.    PHA ; Save rollover value  06374.   06375.    LDY ObjGroupRel_Idx ; Get object's relative index  06376.    LDA ObjectGroup_Attributes2,Y ; Get object's 2nd attribute  06377.    AND #OA2_USE16BITX  06378.    BNE PRG000_DCF9 ; If OA2_USE16BITX is set, jump to PRG000_DCF9  06379.   06380.    STA <Objects_XHi,X ; Otherwise, Object's X Hi is zeroed  06381.   06382. PRG000_DCF9:  06383.    PLA ; Restore rollover value  06384.   06385. PRG000_DCFA:  06386.    RTS ; Return  06387.   06388. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06389. ; Object_AddVelFrac  06390. ;  06391. ; Adds the 4.4FP velocity to X or Y of object  06392. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06393. Object_AddVelFrac:  06394.    LDA <Objects_XVel,X ; Get Velocity  06395.    ASL A  06396.    ASL A  06397.    ASL A  06398.    ASL A ; Fractional part shifted up  06399.    ADD Objects_XVelFrac,X  06400.    STA Objects_XVelFrac,X ; Add to object's vel fractional accumulator  06401.   06402.    PHP ; Save CPU state  06403.    PHP ; Save CPU state  06404.   06405.    LDY #$00 ; Y = 0 (positive high part)  06406.   06407.    LDA <Objects_XVel,X ; Get Velocity  06408.    LSR A  06409.    LSR A  06410.    LSR A  06411.    LSR A ; Whole part shifted down (integer)  06412.    CMP #%00001000 ; Check the sign bit  06413.    BLT PRG000_DD19 ; If the value was not negatively signed, jump to PRG000_DD19  06414.    ORA #%11110000 ; Otherwise, apply a sign extension  06415.    DEY ; Y = $FF (negative high part)  06416. PRG000_DD19:  06417.    PLP ; Restore CPU state  06418.   06419.    PHA ; Save integer of velocity  06420.   06421.    ADC <Objects_X,X  06422.    STA <Objects_X,X ; Add with carry  06423.   06424.    TYA ; A = $00 or $FF as appropriate  06425.   06426.    ADC <Objects_XHi,X  06427.    STA <Objects_XHi,X ; Add to the high part  06428.   06429.    PLA ; Restore integer of Velocity  06430.   06431.    PLP ; Restore CPU state  06432.   06433.    ADC #$00  06434.    STA Object_VelCarry ; Set to '1' if fractional part rolled over  06435.   06436.    RTS ; Return  06437.   06438.   06439. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06440. ; Level_ObjCalcXDiffs  06441. ;  06442. ; For a given object slot in 'X'...  06443. ; Returns: Temp_Var16 as pixel difference between Player and object X coordinates  06444. ; And 'Y' is set to 0 if Player is to the right of object, 1 if to the left  06445. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06446. ; $DD2C  06447. Level_ObjCalcXDiffs:  06448.    LDA <Player_X  06449.    SUB <Objects_X,X  06450.    STA <Temp_Var16 ; Temp_Var16 = difference between Player's X and object's X  06451.   06452.    LDY #$00 ; Y = 0  06453.    LDA <Player_XHi  06454.    SBC <Objects_XHi,X  06455.    BPL PRG000_DD3C ; If Player's X Hi >= Object's X Hi, jump to PRG000_DD3C (RTS)  06456.   06457.    INY ; Otherwise Y = 1  06458.   06459. PRG000_DD3C:  06460.    RTS ; Return  06461.   06462.   06463. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06464. ; Level_ObjCalcYDiffs  06465. ;  06466. ; For a given object slot in 'X'...  06467. ; Returns: Temp_Var16 as pixel difference between Player and object Y coordinates  06468. ; And 'Y' is set to 0 if Player is lower than object, 1 if higher  06469. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06470. ; $DD3D  06471. Level_ObjCalcYDiffs:  06472.    LDA <Player_Y  06473.    SUB <Objects_Y,X  06474.    STA <Temp_Var16 ; Temp_Var16 = difference between Player's Y and object's Y  06475.   06476.    LDY #$00 ; Y = 0  06477.    LDA <Player_YHi  06478.    SBC <Objects_YHi,X  06479.    BPL PRG000_DD4D ; If Player's Y Hi >= Object's Y Hi, jump to PRG000_DD4D (RTS)  06480.   06481.    INY ; Ohterwise Y = 1  06482.   06483. PRG000_DD4D:  06484.    RTS ; Return  06485.   06486.   06487. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06488. ; Negate  06489. ;  06490. ; "NEG" is not REALLY an opcode of its own  06491. ; This makes it a subroutine, though...  06492. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06493. ; $DD4E  06494. Negate:  06495.    NEG  06496.    RTS ; Return  06497.   06498.   06499. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06500. ; Object_AnySprOffscreen  06501. ;  06502. ; Returns non-zero if any flags are set on Objects_SprHVis or Objects_SprVVis  06503. ; (i.e. if any sprites are off-screen)  06504. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  06505. ; $DD54  06506. Object_AnySprOffscreen:  06507.    LDA Objects_SprHVis,X  06508.    ORA Objects_SprVVis,X  06509.    RTS ; Return  06510.   06511.   06512. ; FIXME: Anybody want to claim this?  06513. ; Appears it would return a free object slot  06514. ; $DD5B  06515.    LDY #$04 ; Y = 4  06516. PRG000_DD5D:  06517.    LDA Objects_State,Y  06518.    BEQ PRG000_DD65 ; If this object slot is dead/empty, jump to PRG000_DD65  06519.   06520.    DEY ; Y--  06521.    BPL PRG000_DD5D ; While Y >= 0, loop  06522.   06523. PRG000_DD65:  06524.    RTS ; Return  06525.   06526.   06527. ; FIXME: Anybody want to claim this?  06528. ; Appears to apply offsets to Player X/Y (Temp_Var11/Temp_Var10) and get a tile there  06529. ; $DD66  06530.   06531.    ; Temp_Var13 = Player_YHi  06532.    LDA <Player_YHi  06533.    STA <Temp_Var13  06534.   06535.    ; Temp_Var14 = Temp_Var10 (? input var?) + Player_Y  06536.    LDA <Temp_Var10  06537.    ADD <Player_Y  06538.    STA <Temp_Var14  06539.   06540.    BCC PRG000_DD75 ; If no carry, jump to PRG000_DD75  06541.   06542.    INC <Temp_Var13 ; Apply carry  06543.   06544. PRG000_DD75:  06545.    LDA <Temp_Var13  06546.    BNE PRG000_DD84 ; If Temp_Var13 <> 0 (Player is on lower screen), jump to PRG000_DD84  06547.   06548.    ; Temp_Var14 -= 16  06549.    LDA <Temp_Var14  06550.    SUB #16  06551.    STA <Temp_Var14  06552.    BCS PRG000_DD84 ; If carry set, jump to PRG000_DD84  06553.   06554.    DEC <Temp_Var13 ; Apply carry  06555.   06556. PRG000_DD84:  06557.   06558.    ; Temp_Var15 = Player_XHi  06559.    LDA <Player_XHi  06560.    STA <Temp_Var15  06561.   06562.    LDA <Temp_Var11  06563.    BPL PRG000_DD8E ; If Temp_Var11 (? input var?) >= 0, jump to PRG000_DD8E  06564.   06565.    DEC <Temp_Var15 ; Otherwise, Temp_Var15--  06566.   06567. PRG000_DD8E:  06568.   06569.    ; Temp_Var16 = Player_X + Temp_Var11 (? input var)  06570.    LDA <Player_X  06571.    ADD <Temp_Var11  06572.    STA <Temp_Var16  06573.    BCC PRG000_DD99 ; If no carry, jump to PRG000_DD99  06574.   06575.    INC <Temp_Var15 ; Apply carry  06576.   06577. PRG000_DD99:  06578.    ; Backup X/Y  06579.    STY <Temp_Var10  06580.    STX <Temp_Var11  06581.   06582.    JSR Player_GetTileAndSlope_Normal  06583.   06584.    ; Restore X/Y  06585.    LDY <Temp_Var10  06586.    LDX <Temp_Var11  06587.    RTS ; Return  06588.   06589.   06590.   06591.    ; Initializes a "block bump" effect, if one of the 2 slots is open...  06592. BlockBump_Init:  06593.    LDY #$00 ; Y = 0  06594.    LDA Level_BlkBump,Y  06595.    BEQ PRG000_DDB2 ; If block bump slot 1 is empty, jump to PRG000_DDB2  06596.   06597.    INY ; Y = 1  06598.    LDA Level_BlkBump,Y  06599.    BNE PRG000_DDCB ; If block bump slot 2 is not empty, jump to PRG000_DDCB (RTS)  06600.   06601. PRG000_DDB2:  06602.    LDA <Temp_Var12  06603.    STA Level_BlkBump,Y ; Store tile-behind effect  06604.   06605.    ; Temp_Var13 / Temp_Var14 -- Y Hi and Lo  06606.    ; Temp_Var15 / Temp_Var16 -- X Hi and Lo  06607.   06608.    LDA <Temp_Var15  06609.    STA Level_BlkBump_XHi,Y  06610.   06611.   06612.    LDA <Temp_Var16  06613.    STA Level_BlkBump_XLo,Y  06614.   06615.    LDA <Temp_Var13  06616.    STA Level_BlkBump_YHi,Y  06617.   06618.    LDA <Temp_Var14  06619.    STA Level_BlkBump_YLo,Y  06620.   06621. PRG000_DDCB:  06622.    RTS ; Return  06623.   06624. InventoryRow_BaseIndex:  06625.    ; Base index in inventory, per row  06626.    .byte $15, $0E, $07, $00  06627.   06628. Inventory_DestX:  06629.    ; Destination X coordinate per inventory slot  06630.    .byte $48, $60, $78, $90, $A8, $C0, $D8  06631.   06632.   06633.    ; This sets up the "pop out" item you get when you open a treasure box  06634. ToadHouse_GiveItem:  06635.   06636.    ; X = Inventory item index you are getting from Toad  06637.    ; A = X position of box  06638.   06639.    STX Objects_Frame ; Store item you are getting  06640.    STA <Objects_X ; X position of box that was opened  06641.   06642.    LSR A  06643.    LSR A  06644.    STA <Temp_Var1 ; Temp_Var1 = X position / 4  06645.   06646.    LDY Player_Current  06647.    BEQ PRG000_DDE7 ; If Player is Mario, jump to PRG000_DDE7  06648.   06649.    LDY #(Inventory_Items2 - Inventory_Items) ; Y = offset to Luigi's items  06650.   06651. PRG000_DDE7:  06652.    LDX #$00 ; X = 0  06653.   06654. PRG000_DDE9:  06655.    LDA Inventory_Items,Y ; Get item currently in slot  06656.    BEQ PRG000_DDF4 ; If slot is empty, jump to PRG000_DDF4  06657.   06658.    INY ; Y++ (next item slot)  06659.    INX ; X++ (counter)  06660.    CPX #(Inventory_Cards - Inventory_Items - 1)  06661.    BLT PRG000_DDE9 ; While potential item slots remain, loop!  06662.   06663. PRG000_DDF4:  06664.    STY Objects_Var1 ; Obj var 1 stores target inventory index  06665.   06666.    ; The following basically does a MOD 7 against the non-offsetted inventory index  06667.    TXA ; non-offset inventory index -> 'A'  06668.    LDY #$03 ; Y = 3 (up to four rows of inventory)  06669. PRG000_DDFA:  06670.    CMP #$07  06671.    BLT PRG000_DE03 ; If index has arrived in a inventory row-relative spot, jump to PRG000_DE03  06672.    SBC #$07 ; Otherwise subtract 7...  06673.    DEY ; Y-- (go one row higher!)  06674.    BNE PRG000_DDFA ; If not out of rows, loop!  06675. PRG000_DE03:  06676.   06677.    TAX ; Mod value -> 'X'  06678.   06679.    LDA InventoryRow_BaseIndex,Y ; Get base inventory index for this row  06680.    STA Objects_Var2 ; -> Objects_Var2  06681.   06682.    ; Configure the treasure box item to pop out!  06683.    LDA #OBJSTATE_NORMAL  06684.    STA Objects_State  06685.   06686.    LDA #OBJ_TOADHOUSEITEM  06687.    STA Level_ObjectID  06688.   06689.    LDA #$90  06690.    STA <Objects_Y  06691.   06692.    ; Calculates a good fly rate so item lands in the inventory slot  06693.    LDA Inventory_DestX,X ; Get target X coordinate for object  06694.    LSR A  06695.    LSR A  06696.    SUB <Temp_Var1 ; was object X / 4  06697.    STA <Objects_XVel ; Set as X velocity  06698.   06699.    LDA #-$30  06700.    STA <Objects_YVel ; Object's Y velocity = -$30  06701.   06702.    LDA #$00  06703.    STA Objects_XVelFrac ; Objects_XVelFrac = 0  06704.    STA THouse_UnusedFlag ; THouse_UnusedFlag = 0 (set here, never used otherwise)  06705.   06706.    LDA #$ff  06707.    STA Objects_Timer ; Objects_Timer = $FF  06708.    STA <Objects_Var4 ; Objects_Var4 = $FF  06709.   06710.    ; Play Inventory flip noise  06711.    LDA Sound_QMap  06712.    ORA #SND_MAPINVENTORYFLIP  06713.    STA Sound_QMap  06714.   06715.    RTS ; Return  06716.   06717.   06718. AScrlURDiag_HandleWrap:  06719.    LDA AScrlURDiag_WrapState  06720.    STA AScrlURDiag_WrapState_Copy ; AScrlURDiag_WrapState_Copy = AScrlURDiag_WrapState  06721.    JSR AScrlURDiag_NoWrapAbort ; Will not return here if AScrlURDiag_WrapState_Copy not set or gameplay halted!  06722.   06723.    LDY #$00 ; Y = 0  06724.   06725.    LDA Level_AScrlVVelCarry  06726.    LSR A  06727.    BCC PRG000_DE53 ; If Level_AScrlVVelCarry = 0, jump to PRG000_DE53  06728.   06729.    INY ; Y = 1  06730.    DEC Level_ScrollDiffH ; Level_ScrollDiffH--  06731.   06732. PRG000_DE53:  06733.    LDA Level_ScrollDiffH  06734.    STA AScrlURDiag_OffsetX ; AScrlURDiag_OffsetX = Level_ScrollDiffH  06735.   06736.    STY Level_ScrollDiffH ; Level_ScrollDiffH = 0 or 1  06737.   06738.    ADD <Player_X  06739.    STA <Player_X ; Player_X += Level_ScrollDiffH  06740.    BCC PRG000_DE65 ; If no carry, jump to PRG000_DE65  06741.   06742.    INC <Player_XHi ; Otherwise, apply carry  06743.   06744. PRG000_DE65:  06745.    LDY #$00 ; Y = 0  06746.   06747.    LDA Level_AScrlVVelCarry  06748.    LSR A  06749.    BCC PRG000_DE71 ; If no autoscroll vertical velocity carry, jump to PRG000_DE71  06750.   06751.    DEY ; Y = -1  06752.    INC Level_ScrollDiffV  06753.   06754. PRG000_DE71:  06755.    LDA Level_ScrollDiffV  06756.    STA AScrlURDiag_OffsetY ; AScrlURDiag_OffsetY = Level_ScrollDiffV  06757.   06758.    STY Level_ScrollDiffV ; Level_ScrollDiffV = 0 or -1  06759.   06760.    LDY <Player_InAir  06761.    BEQ PRG000_DE89 ; If Player is not mid air, jump to PRG000_DE89  06762.   06763.    LDY #$00 ; Y = 0  06764.   06765.    ADD Level_ScrollDiffV ; Level_ScrollDiffV is 0 or -1 right now  06766.    CMP #$ff  06767.    BNE PRG000_DE89  06768.    DEY ; Y = -1  06769.   06770. PRG000_DE89:  06771.    ADD <Player_Y  06772.    STA <Player_Y  06773.    TYA  06774.    ADC <Player_YHi  06775.    STA <Player_YHi  06776.   06777.    RTS ; Return  06778.   06779. AScrlURDiag_CheckWrapping:  06780.    JSR AScrlURDiag_NoWrapAbort ; Will not return here if AScrlURDiag_WrapState_Copy is not set or gameplay halted!  06781.   06782.    LDA <Objects_X,X  06783.    ADD AScrlURDiag_OffsetX  06784.    STA <Objects_X,X  06785.    BCC PRG000_DEA3 ; If no carry, jump to PRG000_DEA3  06786.    INC <Objects_XHi,X ; Otherwise, apply carry  06787. PRG000_DEA3:  06788.   06789.    LDA <Objects_Y,X  06790.    ADD AScrlURDiag_OffsetY  06791.    STA <Objects_Y,X  06792.    BCC PRG000_DEAF ; If no carry, jump to PRG000_DEAF  06793.    INC <Objects_YHi,X ; Otherwise, apply carry  06794.   06795. PRG000_DEAF:  06796.    RTS ; Return  06797.   06798.   06799. AScrlURDiag_NoWrapAbort:  06800.    LDA AScrlURDiag_WrapState_Copy  06801.    BEQ PRG000_DEB9 ; If diagonal autoscroller is not wrapping, jump to PRG000_DEB9  06802.   06803.    LDA <Player_HaltGame  06804.    BEQ PRG000_DEBB ; If gameplay is not halted, jump to PRG000_DEBB (RTS)  06805.   06806. PRG000_DEB9:  06807.    ; If NOT AScrlURDiag_WrapState_Copy or if gameplay is halted, do not return to caller!!  06808.    PLA  06809.    PLA ; Pull return address  06810.   06811. PRG000_DEBB:  06812.    RTS ; Return  06813.   06814.   06815. ASHIM .func \1-AScroll_Movement-1  06816.    ; This is the initial movement table for horizontal auto scroll levels, minus 1  06817.    ; Level_AScrlLimitSel selects which entry to use, which sets Level_AScrlVar (the actual index value)  06818. AScroll_HorizontalInitMove:  06819.    .byte ASHIM(ASM_World_36_14) ; 0 World 3-6 / 1-4  06820.    .byte ASHIM(ASM_W3_Airship) ; 1 World 3 Airship  06821.    .byte ASHIM(ASM_World_62) ; 2 World 6-2  06822.    .byte ASHIM(ASM_W5_Airship) ; 3 World 5 Airship  06823.    .byte ASHIM(ASM_UNK4) ; 4  06824.    .byte ASHIM(ASM_W4Airship) ; 5 World 4 Airship  06825.    .byte ASHIM(ASM_W6Airship) ; 6 World 6 Airship  06826.    .byte ASHIM(ASM_World_56) ; 7 World 5-6  06827.    .byte ASHIM(ASM_UNK8) ; 8  06828.    .byte ASHIM(ASM_UNK9) ; 9  06829.    .byte ASHIM(ASM_World_67) ; A World 6-7  06830.    .byte ASHIM(ASM_W1Airship) ; B World 1 Airship  06831.    .byte ASHIM(ASM_W7Airship) ; C World 7 Airship  06832.    .byte ASHIM(ASM_W8Airship) ; D World 8 Airship  06833.    .byte ASHIM(ASM_W8Battleship) ; E World 8 Battleship  06834.    .byte ASHIM(ASM_World_74) ; F World 7-4  06835.    .byte ASHIM(ASM_W1CoinHeaven) ; 10  06836.    .byte ASHIM(ASM_CoinShip) ; 11 Coin Ship  06837.    .byte ASHIM(ASM_UNK12) ; 12  06838.    .byte ASHIM(ASM_World8Tank1) ; 13 World 8 Tank 1  06839.    .byte ASHIM(ASM_World8Tank2) ; 14 World 8 Tank 2  06840.    .byte ASHIM(ASM_Terminator) ; 15 ** Terminator Only (because it seeks ahead to see the terminating movement index)  06841.   06842. Video_3CMMushTop:  06843.    vaddr $208D  06844.    .byte VU_REPEAT | $06, $A9  06845.    vaddr $20AB  06846.    .byte VU_REPEAT | $04, $A9  06847.    vaddr $20B1  06848.    .byte VU_REPEAT | $04, $A9  06849.    vaddr $20CA  06850.    .byte VU_REPEAT | $05, $A9  06851.    vaddr $20D1  06852.    .byte VU_REPEAT | $05, $A9  06853.    vaddr $214A  06854.    .byte VU_VERT | VU_REPEAT | $03, $A9  06855.    .byte $00 ; Terminator  06856.   06857. Video_3CMMushLeft:  06858.    vaddr $20E9  06859.    .byte $05, $A9, $A9, $FC, $A9, $A9  06860.    vaddr $20F2  06861.    .byte $05, $A9, $A9, $FC, $A9, $A9  06862.    vaddr $2128  06863.    .byte VU_VERT | VU_REPEAT | $07, $A9  06864.    vaddr $2109  06865.    .byte VU_VERT | VU_REPEAT | $06, $A9  06866.    vaddr $214D  06867.    .byte VU_VERT | VU_REPEAT | $03, $A9  06868.    .byte $00 ; Terminator  06869.   06870. Video_3CMMushMid:  06871.    vaddr $212E  06872.    .byte VU_VERT | VU_REPEAT | $08, $A9  06873.    vaddr $212F  06874.    .byte VU_VERT | VU_REPEAT | $05, $A9  06875.    vaddr $2130  06876.    .byte VU_VERT | VU_REPEAT | $05, $A9  06877.    vaddr $2131  06878.    .byte VU_VERT | VU_REPEAT | $08, $A9  06879.    vaddr $2152  06880.    .byte VU_VERT | VU_REPEAT | $03, $A9  06881.    .byte $00 ; Terminator  06882.   06883. Video_3CMMushRight:  06884.    vaddr $2155  06885.    .byte VU_VERT | VU_REPEAT | $03, $A9  06886.    vaddr $2116  06887.    .byte VU_VERT | VU_REPEAT | $06, $A9  06888.    vaddr $2137  06889.    .byte VU_VERT | VU_REPEAT | $07, $A9  06890.    vaddr $21CB  06891.    .byte VU_REPEAT | $0A, $A9  06892.    vaddr $21E9  06893.    .byte VU_VERT | VU_REPEAT | $02, $A9  06894.    .byte $00 ; Terminator  06895.   06896. Video_3CMMushBot:  06897.    vaddr $21EA  06898.    .byte VU_VERT | VU_REPEAT | $04, $A9  06899.    vaddr $21EB  06900.    .byte VU_VERT | $04, $A9, $FC, $FC, $A9  06901.    vaddr $21F4  06902.    .byte VU_VERT | $04, $A9, $FC, $FC, $A9  06903.    vaddr $21F5  06904.    .byte VU_VERT | VU_REPEAT | $04, $A9  06905.    vaddr $21F6  06906.    .byte VU_VERT | VU_REPEAT | $02, $A9  06907.    vaddr $226B  06908.    .byte VU_REPEAT | $0A, $A9  06909.    .byte $00 ; Terminator  06910.   06911. Video_3CMFlowTop:  06912.    vaddr $208B  06913.    .byte VU_REPEAT | $0A, $A9  06914.    vaddr $20A9  06915.    .byte VU_REPEAT | $03, $A9  06916.    vaddr $20B4  06917.    .byte VU_REPEAT | $03, $A9  06918.    vaddr $20C8  06919.    .byte VU_REPEAT | $02, $A9  06920.    vaddr $20D6  06921.    .byte VU_REPEAT | $02, $A9  06922.    vaddr $20E8  06923.    .byte VU_VERT | VU_REPEAT | $03, $A9  06924.    vaddr $20EB  06925.    .byte VU_REPEAT | $03, $A9  06926.    vaddr $210B  06927.    .byte $01, $A9  06928.    .byte $00 ; Terminator  06929.   06930. Video_3CMFlowDiag:  06931.    vaddr $2148  06932.    .byte VU_REPEAT | $02, $A9  06933.    vaddr $20CD  06934.    .byte VU_REPEAT | $06, $A9  06935.    vaddr $20F2  06936.    .byte VU_REPEAT | $03, $A9  06937.    vaddr $20F7  06938.    .byte VU_VERT | VU_REPEAT | $03, $A9  06939.    vaddr $214D  06940.    .byte VU_REPEAT | $06, $A9  06941.    vaddr $212B  06942.    .byte VU_REPEAT | $03, $A9  06943.    vaddr $2156  06944.    .byte VU_REPEAT | $02, $A9  06945.    vaddr $21A9  06946.    .byte VU_REPEAT | $02, $A9  06947.    .byte $00 ; Terminator  06948.   06949. Video_3CMFlowMid:  06950.    vaddr $2114  06951.    .byte $01, $A9  06952.    vaddr $210E  06953.    .byte VU_REPEAT | $04, $A9  06954.    vaddr $2132  06955.    .byte VU_REPEAT | $03, $A9  06956.    vaddr $2169  06957.    .byte VU_REPEAT | $03, $A9  06958.    vaddr $2174  06959.    .byte VU_REPEAT | $03, $A9  06960.    vaddr $218B  06961.    .byte VU_REPEAT | $0A, $A9  06962.    vaddr $21B5  06963.    .byte VU_REPEAT | $02, $A9  06964.    vaddr $21D7  06965.    .byte VU_VERT | VU_REPEAT | $03, $A9  06966.    .byte $00 ; Terminator  06967.   06968. Video_3CMFlowStem:  06969.    vaddr $21AE  06970.    .byte VU_VERT | VU_REPEAT | $06, $A9  06971.    vaddr $21B1  06972.    .byte VU_VERT | VU_REPEAT | $06, $A9  06973.    vaddr $21C8  06974.    .byte VU_VERT | VU_REPEAT | $03, $A9  06975.    vaddr $21CB  06976.    .byte VU_REPEAT | $02, $A9  06977.    vaddr $21D3  06978.    .byte VU_REPEAT | $02, $A9  06979.    vaddr $21EA  06980.    .byte $04, $A9, $FC, $FC, $A9  06981.    vaddr $21F2  06982.    .byte $04, $A9, $FC, $FC, $A9  06983.    .byte $00 ; Terminator  06984.   06985. Video_3CMFlowBot  06986.    vaddr $220B  06987.    .byte $01, $A9  06988.    vaddr $2214  06989.    .byte $01, $A9  06990.    vaddr $2229  06991.    .byte $04, $A9, $FC, $FC, $A9  06992.    vaddr $2233  06993.    .byte $04, $A9, $FC, $FC, $A9  06994.    vaddr $224A  06995.    .byte $04, $A9, $A9, $FC, $A9  06996.    vaddr $2252  06997.    .byte $04, $A9, $FC, $A9, $A9  06998.    vaddr $226C  06999.    .byte VU_REPEAT | $08, $A9  07000.    .byte $00 ; Terminator  07001.   07002.