Guest User

Mothra Boss

a guest
Nov 19th, 2017
13
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;; Mothra Boss
  4. ;; By Flabort
  5. ;; Originally for use in Super Mallow World by
  6. ;; The Catbus Comunity for Glitchcat7
  7. ;; (As such, instead of Mario, the player character will be refered to as Mallow)
  8. ;; Credit to SMWC and Nesquick Bunny for Sprite Tutorial
  9. ;; Credit to Katrina and Biob of SMWC for Debugging.
  10. ;; Graphics included provided by FerpyMcFrosting
  11. ;;
  12. ;;
  13. ;; Uses Extra Bit
  14. ;; When set, has 2HP per phase instead of 1
  15. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  16. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  17.  
  18.  
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20. ;Constants
  21. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22.  
  23. YDISP: db $F0,$00,$F0,$00 ;\There are lines in each constant because there are two directions
  24. db $F0,$00,$F0,$00 ;|to be facing and two frames per animation state
  25. db $F0,$00,$F0,$00 ;|There are 4 values per line because the sprite is made of
  26. db $F0,$00,$F0,$00 ;/four 16x16 tiles to make one 32x32 sprite
  27. XDISP: db $00,$00,$F0,$F0 ;\
  28. db $00,$00,$F0,$F0 ;| X and Y DISP is the displacement for each tile
  29. db $F0,$F0,$00,$00 ;|So they aren't all drawn in the same place
  30. db $F0,$F0,$00,$00 ;/
  31. TILEMAPPASSIVE: db $80,$A0,$82,$A2 ;\
  32. db $C8,$E8,$CA,$EA ;|Tiles to use in phase 1&2 when Mothra is flying back and forth in the sky
  33. db $80,$A0,$82,$A2 ;|
  34. db $C8,$E8,$CA,$EA ;/
  35. TILEMAPSWOOPDOWN: db $84,$A4,$86,$A6 ;\
  36. db $84,$A4,$86,$A6 ;|Tiles to use in phase 1&3 when Mothra dives towards Mallow
  37. db $84,$A4,$86,$A6 ;|
  38. db $84,$A4,$86,$A6 ;/
  39. TILEMAPSWOOPUP: db $88,$A8,$8A,$AA ;\
  40. db $88,$A8,$8A,$AA ;|Tiles to use in phase 1&3 when mothra returns upwards
  41. db $88,$A8,$8A,$AA ;|
  42. db $88,$A8,$8A,$AA ;/
  43. TILEMAPDIVE: db $8C,$AC,$8E,$AE ;\
  44. db $8C,$AC,$8E,$AE ;|Tiles to use in phase 2 when mothra dives at Mallow
  45. db $8C,$AC,$8E,$AE ;|
  46. db $8C,$AC,$8E,$AE ;/
  47. TILEMAPBOTTOM: db $C0,$E0,$C2,$E2 ;\
  48. db $C0,$E0,$C2,$E2 ;|Tiles to use in phase 2 when mothra pauses at the bottom of flight
  49. db $C0,$E0,$C2,$E2 ;|
  50. db $C0,$E0,$C2,$E2 ;/
  51. TILEMAPPULLUP: db $C4,$E4,$C6,$E6 ;\
  52. db $CC,$EC,$CE,$EE ;|Tiles to use in phase 2 when mothra returns to passive
  53. db $C4,$E4,$C6,$E6 ;|
  54. db $CC,$EC,$CE,$EE ;/
  55. XSPEED: db $12,$EE ;\
  56. db $0A,$F6 ;|
  57. db $0A,$F6 ;|X and Y speeds for different movement patterns
  58. db $00,$00 ;|Left is moving right, right is moving left
  59. db $00,$00 ;|each row is for a different Dive State (see HITP)
  60. db $00,$00 ;|
  61. db $1B,$E5 ;|Last two rows are double speed versions of
  62. db $1B,$E5 ;|diving at angle and rising back up, for
  63. YSPEED: db $00,$00 ;|
  64. db $0A,$0A ;|
  65. db $F6,$F6 ;|
  66. db $12,$12 ;|
  67. db $00,$00 ;|
  68. db $EE,$EE ;|
  69. db $1B,$1B ;|
  70. db $E5,$E5 ;/
  71.  
  72.  
  73. ;Shortcut Lables (addresses that will be called over and over)
  74. !FACE = $157C ;Facing left?
  75. !HITP = $1528 ;Format: xxEDDDHH
  76. ;D: Dive state. 0(0) idle/back+forth, 1(4) diving at angle,
  77. ;2(8)rising back up, 3(C) diving straight, 4(10) bottom,
  78. ;5(14) rising straight, 6(18) and 7(1C) double speed versions
  79. ;of diving at angle and rising back up respectively.
  80. ;
  81. ;H: Health. 3 max, 2 and 1 damaged, 0 dead/dying
  82. ;AND 03 = Hit points
  83. ;AND 1C = Dive State
  84. ;AND 20 = Extra Hit with Extra Bit
  85. ;AND C0 = should be null
  86.  
  87. !SPAWNH = $1534 ;The height/Y level at which Mothra is spawned.
  88. ;This is as high as Mothra should rise when flying
  89. !MALLOWH = $96 ;The height/Y level of Mallow.
  90. ;This is as low as Mothra should dive when flying
  91. !INVINCE = $163E ;Invincibility timer after Mothra is damaged
  92. !ATTACK = $1510 ;Timer used for different attacks in different phases
  93.  
  94.  
  95. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  96. ; Main and Init
  97. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  98. print "INIT ",pc
  99. LDX $15E9
  100. LDA #$2B
  101. STA !HITP,x
  102. STZ !FACE,x
  103. LDA $D8,x
  104. STA !SPAWNH,x
  105. LDA $F0
  106. STA !ATTACK,x
  107. RTL
  108.  
  109.  
  110. print "MAIN ",pc
  111. PHB
  112. PHK
  113. PLB
  114. JSR Graphics
  115. JSR SpriteCode
  116. PLB
  117. RTL
  118.  
  119.  
  120.  
  121. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  122. ; Phase controls
  123. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  124. SpriteCode:
  125. LDA $14C8,x ;\
  126. CMP #$08 ;| If sprite is dead or not in a normal state, return
  127. BNE RETURN1 ;/
  128. LDA $9D ;\
  129. BNE RETURN1 ;/ If sprites are locked, return
  130. JMP NoReturn
  131. RETURN1:
  132. RTS
  133. NoReturn:
  134. ;\ If Mothra is touching mallow...
  135. JSL $01A7DC ;|
  136. BCC NoContact ;|
  137. LDA !HITP,x ;|\Check if Mothra is alive,
  138. AND #$03 ;||
  139. CMP #$01 ;||And if he is,
  140. BMI Death ;||
  141. JSL $00F5B7 ;|/Hurt Mallow!
  142. JMP NoContact ;|
  143. Death: ;|-\Solve a Branch Out of Range error
  144. JMP DeathAnim ;|_/
  145. NoContact: ;/
  146.  
  147.  
  148. PHX ;\
  149. LDX #$0B ;|Set up the start of a loop to check if a sprite
  150. ClipLoop: ;/is clipping with Mothra, to see if it damages him
  151. TXA ;\
  152. CMP $15E9 ;|If the register is Mothra, don't check clipping
  153. BEQ NotSelf ;/
  154. PHX ;\
  155. LDX $15E9 ;|
  156. JSL $03B69F ;|Get bounding box for Mothra
  157. PLX ;/
  158. JSL $03B6E5 ;\
  159. JSL $03B72B ;|Is the sprite in X registry touching?
  160. BCS SprContact ;/
  161. NotSelf:
  162. DEX ;\If not, continue loop
  163. BMI NoSprContact ;| or branch away if all possible sprites have been checked
  164. JMP ClipLoop ;/
  165. SprContact:
  166. LDA $14C8,x ;\If the sprite was kicked at mothra
  167. CMP #$0A ;|or being carried, keep going
  168. BMI NoSprContact ;/else, ignore the sprite
  169. PHX ;\
  170. LDX $15E9 ;|
  171. LDA !HITP,x ;|
  172. AND #$03 ;|Deal Damage to Mothra, as long as Mothra can
  173. CMP #$01 ;|be damaged.
  174. BMI NoDamage ;|
  175. LDA !INVINCE,x ;|
  176. BNE NoDamage ;|
  177. ;|
  178. LDA $7FAB10,x ;|\
  179. AND #$04 ;||If extra bit is in use...
  180. BEQ BitClear ;|/
  181. LDA !HITP,x ;|\
  182. EOR #$20 ;||
  183. STA !HITP,x ;||...then double the HP per phase
  184. AND #$20 ;||
  185. BNE BitClear ;||
  186. INC !HITP,x ;|/
  187. BitClear: ;|
  188. ;|
  189. DEC !HITP,x ;|
  190. LDA #$60 ;|
  191. STA !INVINCE,x ;|
  192. LDA #$28 ;|\Play "Boss/Chuck Hurt/Stunned" sound
  193. STA $1DFC ;|/
  194. NoDamage: ;|
  195. PLX ;/
  196. LDA #$04 ;\Kill the sprite
  197. STA $14C8,x ;/so it doesn't continue to damage Mothra
  198.  
  199.  
  200. NoSprContact: ;\After doing sprite contact stuff or if there was no contact
  201. PLX ;/Return Mothra's sprite registry value to X
  202.  
  203. LDA !ATTACK,x ;\
  204. BEQ NoDec ;|Decrement the timer for attack patterns
  205. DEC !ATTACK,x ;|
  206. NoDec: ;/
  207.  
  208. LDA !HITP,x ;\
  209. AND #$1C ;|Get movement state
  210. LSR ;|(divestate+facing)
  211. EOR !FACE,x ;|and put into Y registry
  212. TAY ;/
  213. LDA XSPEED,y ;\
  214. STA $B6,x ;|Use Y registry to get X and Y speeds, store them.
  215. LDA YSPEED,y ;|
  216. STA $AA,x ;/
  217. JSL $018022 ;\Update sprite's position now that we have speed,
  218. JSL $01801A ;/Without gravity
  219.  
  220. LDA $E4,x ;\
  221. CMP #$0A ;|
  222. BCS NotNearLeft ;|
  223. STZ !FACE,x ;|
  224. JMP NotNearRight ;|If Mothra is near a screen boundary, turn around
  225. NotNearLeft: ;|
  226. LDA $E4,x ;|
  227. CMP #$F6 ;|
  228. BCC NotNearRight ;|
  229. LDA #$01 ;|
  230. STA !FACE,x ;|
  231. NotNearRight: ;/
  232.  
  233. LDA !HITP,x ;\
  234. AND #$03 ;|Branch to the appropriate phase depending on
  235. CMP #$03 ;|Mothra's HP
  236. BEQ Phase1JMP ;|
  237. CMP #$02 ;|
  238. BEQ Phase2JMP ;|
  239. CMP #$01 ;|
  240. BNE DeathJMP ;/
  241. JMP Phase3 ;\
  242. DeathJMP: ;|
  243. JMP DeathAnim ;|
  244. Phase1JMP: ;|Because the branches to Phase1, Phase2, and DeathAnim
  245. JMP Phase1 ;|were too far away from here.
  246. Phase2JMP: ;|
  247. JMP Phase2 ;/
  248. Phase3:
  249. LDA !HITP,x ;\
  250. AND #$1C ;|Unlike phase2, phase3 only has 2 states, so no need to check
  251. CMP #$1C ;|if it's in a state that phase3 doesn't use, only need to
  252. BEQ Phase3_2 ;/check if it's in one or any other.
  253. Phase3_1:
  254. LDA $D8,x ;\
  255. CMP !MALLOWH ;|If reached mallow's height, turn around
  256. BPL Phase3_2 ;/
  257. LDA !HITP,x ;\
  258. AND #$E3 ;|Set high speed dive down
  259. ORA #$18 ;|
  260. STA !HITP,x ;/
  261. JMP RETURN2
  262. Phase3_2:
  263. LDA $D8,x ;\
  264. CMP !SPAWNH,x ;|If reached spawn height, turn around
  265. BMI Phase3_1 ;/
  266. LDA !HITP,x ;\
  267. AND #$E3 ;|Set high speed rise up
  268. ORA #$1C ;|
  269. STA !HITP,x ;/
  270. JMP RETURN2
  271. Phase2:
  272. LDA !HITP,x ;\
  273. AND #$1C ;/Get dive state
  274. CMP #$04 ;\If diving at an angle,
  275. BEQ Phase2_Return ;|it's because it was damaged in Phase1,
  276. CMP #$08 ;|so go to a special subphase
  277. BEQ Phase2_Return ;/
  278. CMP #$0C ;\
  279. BEQ Phase2_2 ;|If going one way, keep doing that
  280. CMP #$10 ;|
  281. BEQ Phase2_3 ;|
  282. CMP #$14 ;|
  283. BEQ Phase2_4 ;/
  284. JMP Phase2_1
  285.  
  286. Phase2_Return:
  287. LDA $D8,x ;\
  288. CMP !SPAWNH,x ;|If Mothra has reached it's spawn height, branch.
  289. BMI Phase2_Return2 ;/
  290. LDA !HITP,x ;\
  291. AND #$E3 ;|Set Dive State to rising
  292. ORA #$08 ;|
  293. STA !HITP,x ;/
  294. JMP RETURN2
  295. Phase2_Return2:
  296. LDA #$F0 ;\Set timer until next dive
  297. STA !ATTACK,x ;/
  298. Phase2_1:
  299. LDA !ATTACK,x ;\If the timer has run out, start next subphase
  300. BEQ Phase2_2 ;/
  301. LDA !HITP,x ;\
  302. AND #$E3 ;|Fly Horizontally
  303. STA !HITP,x ;/
  304. JMP RETURN2
  305. Phase2_2:
  306. LDA #$64 ;\
  307. STA !ATTACK,x ;|Set timer for next phase and
  308. LDA $D8,x ;|check if at Mallow's height. If so,
  309. CMP !MALLOWH ;|start next subphase
  310. BPL Phase2_3 ;/
  311. LDA !HITP,x ;\
  312. AND #$E3 ;|Set Dive State properly
  313. ORA #$0C ;|
  314. STA !HITP,x ;/
  315. JMP RETURN2
  316. Phase2_3:
  317. LDA !ATTACK,x ;\If the timer runs out,
  318. BEQ Phase2_4 ;/start next subphase
  319. LDA !HITP,x ;\
  320. AND #$E3 ;|Set Dive State properly
  321. ORA #$10 ;|
  322. STA !HITP,x ;/
  323. JMP RETURN2
  324. Phase2_4:
  325. LDA #$F0 ;\
  326. STA !ATTACK,x ;|Set timer for first phase and
  327. LDA $D8,x ;|check if at spawn height.
  328. CMP !SPAWNH,x ;|If so, start first subphase
  329. BMI Phase1_1 ;/
  330. LDA !HITP,x ;\
  331. AND #$E3 ;|Set Dive State properly
  332. ORA #$14 ;|
  333. STA !HITP,x ;/
  334. JMP RETURN2
  335.  
  336.  
  337. Phase1:
  338. LDA !HITP,x ;\
  339. AND #$1C ;|If Mothra is not idle, branch.
  340. CMP #$01 ;|
  341. BPL Phase1_1 ;/
  342. LDA !ATTACK,x ;\If the attack timer has reached the end, start a dive
  343. BEQ Phase1_2 ;/
  344. JMP RETURN2 ;Else, just keep going back and forth in the sky
  345. Phase1_1:
  346. LDA !HITP,x ;\
  347. AND #$1C ;|
  348. CMP #$08 ;|
  349. BEQ Phase1_3 ;/If the dive is up, branch.
  350. Phase1_2:
  351. LDA $D8,x ;\
  352. CMP !MALLOWH ;|If down to Mallow's Y pos or lower, change subphases.
  353. BPL Phase1_3 ;/
  354. LDA !HITP,x ;\
  355. AND #$E3 ;|Set the proper
  356. ORA #$04 ;|dive state
  357. STA !HITP,x ;/
  358. JMP RETURN2
  359. Phase1_3:
  360. LDA $D8,x ;\
  361. CMP !SPAWNH,x ;|If Mothra has reached it's spawn height, branch.
  362. BMI Phase1_4 ;/
  363. LDA !HITP,x ;\
  364. AND #$E3 ;|Set Dive State to rising
  365. ORA #$08 ;|
  366. STA !HITP,x ;/
  367. JMP RETURN2
  368. Phase1_4:
  369. LDA !HITP,x ;\
  370. AND #$E3 ;|Set Dive State to regular flying
  371. STA !HITP,x ;/
  372. LDA #$F0 ;\
  373. STA !ATTACK,x ;/Set timer for next dive
  374. JMP RETURN2
  375.  
  376. DeathAnim: ;\While falling off screen,
  377. LDA !HITP,x ;|
  378. AND #$E3 ;|Make sure the diving down animation is used,
  379. ORA #$0C ;|
  380. STA !HITP,x ;/
  381.  
  382. ;\and spawn fireballs/explosions off of wings
  383. ;TBD ;|every so often
  384. ;/
  385.  
  386. LDA $D8,x ;\Once off screen, set state to dead.
  387.  
  388. CLC ;|Also, set level clear flag?
  389. ADC #$50 ;|
  390. LDA $14D4,x ;|
  391. ADC #$00 ;|
  392. CMP #$02 ;|
  393. BMI RETURN2 ;|
  394. LDA #$FF ;|
  395. STA $1493 ;|
  396. LDA #$0B ;|<-Song# to load when level is passed
  397. STA $1DBF ;|
  398. STZ $14C8,x ;/
  399.  
  400. RETURN2:
  401. RTS
  402.  
  403.  
  404. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  405. ; Graphics
  406. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  407. Graphics:
  408. JSR GET_DRAW_INFO ;Get the sprite's location so we can set up OAM
  409. LDA !FACE,x ;\
  410. CLC ;|
  411. STA $03 ;/ Get facing and store it for later
  412. PHX ;Push the sprite's index onto the stack so we don't mess it up while we loop
  413. LDX #$03 ;The number of times to loop - 1
  414. Loop:
  415. PHX ;Store the loop value into Stack so we don't mess it up either.
  416. LDA $14 ;\
  417. AND #$10 ;|If digit of a global timer is an odd number (every n frames for n/2 frames)
  418. BNE No_Anim ;|then add 4 to X
  419. TXA ;|causing line 2 or 4 in the tile tables
  420. ADC #$04 ;|to be used instead of 1 or 3.
  421. TAX ;|
  422. No_Anim: ;/
  423.  
  424. LDA $03 ;\
  425. BNE No_Right ;|If facing left,
  426. TXA ;|then add 8 to X
  427. ADC #$08 ;|causing line 3 or 4 in the tile tables
  428. TAX ;|to be used instead of 1 or 2.
  429. No_Right: ;/
  430.  
  431. LDA $00 ;\
  432. CLC ;|Store sprite's X location to OAM so it can be drawn,
  433. ADC XDISP,x ;|with displacement for extra tiles
  434. STA $0300,y ;/
  435.  
  436. LDA $01 ;\
  437. CLC ;|Store sprite's Y location to OAM so it can be drawn,
  438. ADC YDISP,x ;|with displacement for extra tiles
  439. STA $0301,y ;/
  440.  
  441. PHX ;\
  442. LDX $15E9 ;|Get the state of Mothra so we can draw the right tiles.
  443. LDA !HITP,x ;|
  444. AND #$1C ;|
  445. PLX ;/
  446. CMP #$1C ;\
  447. BEQ Graphics_Dive_Up ;|
  448. CMP #$18 ;|
  449. BEQ Graphics_Dive_Down ;|
  450. CMP #$14 ;|
  451. BEQ Graphics_Vert_Up ;|
  452. CMP #$10 ;|Basically a Switch-Case system; since CMP does not
  453. BEQ Graphics_Vert_Pause ;|Affect A, we can use multiple CMP commands
  454. CMP #$0C ;|in a row. So for each of these cases we have
  455. BEQ Graphics_Vert_Down ;|a different branch we go to.
  456. CMP #$08 ;|If none of them are true, we go to the default
  457. BEQ Graphics_Dive_Up ;|case which is Graphics_Passive
  458. CMP #$04 ;|
  459. BEQ Graphics_Dive_Down ;/
  460. Graphics_Passive:
  461. LDA TILEMAPPASSIVE,x
  462. STA $0302,y
  463. JMP Graphics_Finish
  464. Graphics_Dive_Down:
  465. LDA TILEMAPSWOOPDOWN,x
  466. STA $0302,y
  467. JMP Graphics_Finish
  468. Graphics_Dive_Up:
  469. LDA TILEMAPSWOOPUP,x
  470. STA $0302,y
  471. JMP Graphics_Finish
  472. Graphics_Vert_Down:
  473. LDA TILEMAPDIVE,x
  474. STA $0302,y
  475. JMP Graphics_Finish
  476. Graphics_Vert_Pause:
  477. LDA TILEMAPBOTTOM,x
  478. STA $0302,y
  479. JMP Graphics_Finish
  480. Graphics_Vert_Up:
  481. LDA TILEMAPPULLUP,x
  482. STA $0302,y
  483.  
  484. Graphics_Finish:
  485. PHX ;Put X onto the stack (useful for temporary variables)
  486. LDX $15E9 ;Get a new value for X,
  487. LDA $15F6,x ;and use that value to get the location of the YXPPCCCT from CFG and load it
  488. PHA ;Store A in stack
  489. LDA $03 ;\Get facing, if facing left skip next step,
  490. BEQ Skip_Step ;|Which is to flip the X facing
  491. PLA ;|\
  492. EOR #$40 ;||Said step
  493. PHA ;|/
  494. Skip_Step: ;/
  495.  
  496. LDA !HITP,x ;\
  497. CMP #$01 ;|If HP is one,
  498. BNE Skip_Other ;|increase the palette
  499. PLA ;|(use a palette from 8 to E, so
  500. ADC #$02 ;|the maximum palette this increases to is
  501. PHA ;|F or lower)
  502. Skip_Other: ;/
  503. LDA !INVINCE,x ;\
  504. BEQ Skip_Final ;|
  505. LDA $14 ;|
  506. AND #$02 ;|If Mothra was recently damaged and the invincibility
  507. BEQ Skip_Final ;|timer is running, switch palettes rapidly.
  508. PLA ;|
  509. EOR #$02 ;|
  510. PHA ;/
  511.  
  512. Skip_Final:
  513.  
  514. PLA ;Get A back
  515. STA $0303,y ;Store into OAM with the rest of the draw information
  516. PLX ;Now that we are done with X, put the value from the stack back in it
  517. INY ;\
  518. INY ;|
  519. INY ;|Increase the value of Y so on the next pass of the loop we don't overwrite what we did
  520. INY ;/
  521. PLX ;Get back the value of the loop
  522. DEX ;\
  523. BMI NoLoop ;/ End of loop, decrement counter and if it's still positive go back to start.
  524. JMP Loop
  525. NoLoop:
  526. PLX ;Now that we are done inside the loop, return the value to X that we stored just before the loop
  527.  
  528. LDY #$02 ;Mothra is 32x32, so we'll be drawing 4 16x16 tiles, which means a value of 02.
  529. LDA #$03 ;Number of tiles written in loop- 1
  530. JSL $01B7B3 ; Now that everything's loaded into OAM, call a routine to draw the sprite
  531. RTS
  532.  
  533. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  534. ; GET_DRAW_INFO
  535. ; This is a helper for the graphics routine. It sets off screen flags, and sets up
  536. ; variables. It will return with the following:
  537. ;
  538. ; Y = index to sprite OAM ($300)
  539. ; $00 = sprite x position relative to screen boarder
  540. ; $01 = sprite y position relative to screen boarder
  541. ;
  542. ; It is adapted from the subroutine at $03B760
  543. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  544.  
  545. SPR_T1: db $0C,$1C
  546. SPR_T2: db $01,$02
  547.  
  548. GET_DRAW_INFO: STZ $186C,x ; reset sprite offscreen flag, vertical
  549. STZ $15A0,x ; reset sprite offscreen flag, horizontal
  550. LDA $E4,x ; \
  551. CMP $1A ; | set horizontal offscreen if necessary
  552. LDA $14E0,x ; |
  553. SBC $1B ; |
  554. BEQ ON_SCREEN_X ; |
  555. INC $15A0,x ; /
  556.  
  557. ON_SCREEN_X: LDA $14E0,x ; \
  558. XBA ; |
  559. LDA $E4,x ; |
  560. REP #$20 ; |
  561. SEC ; |
  562. SBC $1A ; | mark sprite invalid if far enough off screen
  563. CLC ; |
  564. ADC.W #$0040 ; |
  565. CMP.W #$0180 ; |
  566. SEP #$20 ; |
  567. ROL A ; |
  568. AND #$01 ; |
  569. STA $15C4,x ; /
  570. BNE INVALID ;
  571.  
  572. LDY #$00 ; \ set up loop:
  573. LDA $1662,x ; |
  574. AND #$20 ; | if not smushed (1662 & 0x20), go through loop twice
  575. BEQ ON_SCREEN_LOOP ; | else, go through loop once
  576. INY ; /
  577. ON_SCREEN_LOOP: LDA $D8,x ; \
  578. CLC ; | set vertical offscreen if necessary
  579. ADC SPR_T1,y ; |
  580. PHP ; |
  581. CMP $1C ; | (vert screen boundry)
  582. ROL $00 ; |
  583. PLP ; |
  584. LDA $14D4,x ; |
  585. ADC #$00 ; |
  586. LSR $00 ; |
  587. SBC $1D ; |
  588. BEQ ON_SCREEN_Y ; |
  589. LDA $186C,x ; | (vert offscreen)
  590. ORA SPR_T2,y ; |
  591. STA $186C,x ; |
  592. ON_SCREEN_Y: DEY ; |
  593. BPL ON_SCREEN_LOOP ; /
  594.  
  595. LDY $15EA,x ; get offset to sprite OAM
  596. LDA $E4,x ; \
  597. SEC ; |
  598. SBC $1A ; | $00 = sprite x position relative to screen boarder
  599. STA $00 ; /
  600. LDA $D8,x ; \
  601. SEC ; |
  602. SBC $1C ; | $01 = sprite y position relative to screen boarder
  603. STA $01 ; /
  604. RTS ; return
  605.  
  606. INVALID: PLA ; \ return from *main gfx routine* subroutine...
  607. PLA ; | ...(not just this subroutine)
  608. RTS ; /
RAW Paste Data