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.