Advertisement
Guest User

Nipper SMB3

a guest
Aug 28th, 2013
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;
  3. ;; SMB3 Nipper, by imamelia
  4. ;;
  5. ;; This is the Nipper from SMB3.  (Duh.) It is a little plant creature that stays in
  6. ;; one place until the player approaches, at which point it jumps into the air and
  7. ;; then starts moving around.  It can be found in, for example, 5-1 and 6-5.
  8. ;;
  9. ;; Extra bytes: 1
  10. ;;
  11. ;; Extra byte 1:
  12. ;;
  13. ;; Bit 0: If this is set, the sprite will spit fireballs, like the Fire-Spitting Nipper
  14. ;; at the end of 7-8.  (There is only one of them in the game.)
  15. ;; Bits 1-7: Unused.
  16. ;;
  17. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  18.  
  19. ;incsrc subroutinedefs.asm  ; shared subroutine definition file
  20.  
  21. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22. ;;
  23. ;; defines and tables
  24. ;;
  25. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  26.  
  27. StatePointers:
  28.  
  29. dw Stationary       ; 00 - the sprite hasn't jumped yet
  30. dw Waiting      ; 01 - the sprite has jumped and is about to move
  31. dw Moving       ; 02 - the sprite is moving
  32. dw SpitFire     ; 03 - the sprite is spitting fire
  33.  
  34. !JumpRange = $20        ; how close the player has to be to the sprite before it will jump
  35. !JumpSpeed = $C0        ; what speed the sprite will use when it jumps
  36. !XSpeed = $0A       ; what speed the sprite will use when moving around
  37. !FireRange = $48        ; how close the player has to be to the sprite before it will spit fireballs
  38. !FireWaitTimer = $60    ; the Nipper won't spit fireballs when this is nonzero, even if the player is in range
  39. !FireSound = $06        ; the sound to play when the sprite is spitting a fireball
  40. !FireSoundBank = $1DFC  ; the sound bank this sound will come from
  41. !FireXSpeed = $10       ; the X speed to spit the fireball
  42. !FireYSpeed = $DD       ; the Y speed to spit the fireball
  43.  
  44. Tilemap:
  45. db $20,$22,$24,$26  ; closed mouth sideways, open, closed upright, open
  46.  
  47. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  48. ;;
  49. ;; init routine wrapper
  50. ;;
  51. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  52.  
  53. print "INIT ",pc
  54. RTL
  55.  
  56. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  57. ;;
  58. ;; main routine wrapper
  59. ;;
  60. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  61.  
  62. print "MAIN ",pc
  63. PHB
  64. PHK
  65. PLB
  66. JSR NipperMain
  67. PLB
  68. RTL
  69.  
  70. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  71. ;;
  72. ;; main routine
  73. ;;
  74. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  75.  
  76. NipperMain:
  77.  
  78. LDA $14     ;
  79. LSR #3      ;
  80. AND #$01    ;
  81. ORA $160E,x ; make the sprite animate between open and closed frames
  82. STA $1602,x ;
  83.  
  84. LDA $1540,x ; unless, of course, it is spitting fire,
  85. BEQ NotOpen ; in which case it should always have an open mouth
  86. LDA #$01        ;
  87. STA $1602,x ;
  88. NotOpen:        ;
  89.  
  90. JSR NipperGFX
  91.  
  92. LDA $14C8,x
  93. CMP #$08
  94. BNE Return0
  95. LDA $9D
  96. BNE Return0
  97.  
  98. JSR SubOffscreenX0
  99.  
  100. LDA $C2,x   ;
  101. JSR ExecutePointer  ; sprite state pointers, yay!
  102.  
  103. JSL $01802A ; update sprite position
  104. JSL $01803A ; interact with sprites and the player
  105.  
  106. LDA $1588,x ;
  107. AND #$03    ; if the sprite is touching a wall...
  108. BEQ Return0 ;
  109. LDA $157C,x ;
  110. EOR #$01        ; flip its direction
  111. STA $157C,x ;
  112. LDA $B6,x   ; and its X speed
  113. EOR #$FF        ;
  114. INC     ;
  115. STA $B6,x       ;
  116.  
  117. Return0:
  118. RTS
  119.  
  120. Stationary:
  121.  
  122. JSR SubHorzPos  ;
  123. TYA     ; make the sprite always face the player
  124. STA $157C,x ;
  125.  
  126. LDA $1588,x ;
  127. AND #$04    ; if the sprite isn't on the ground...
  128. BEQ NoJump1 ;
  129.  
  130. LDA #$10        ;
  131. STA $AA,x   ;
  132.  
  133. LDA $7FAB10,x   ;
  134. AND #$04    ; if the extra bit is set...
  135. BNE CheckForSpit    ; then make the Nipper spit fire instead of jumping
  136.  
  137. JSR Proximity1  ; or is out of range...
  138. BEQ NoJump1 ; don't make it jump
  139.  
  140. LDA #!JumpSpeed ;
  141. STA $AA,x   ; set its jumping speed
  142. LDA #$02        ; set the frame to upright
  143. STA $160E,x ;
  144. LDA #$18        ;
  145. STA $1570,x ; set the timer for it to wait before moving
  146. INC $C2,x   ; set the sprite state to waiting
  147.  
  148. NoJump1:        ;
  149.  
  150. RTS
  151.  
  152. CheckForSpit:   ;
  153.  
  154. JSR Proximity2  ;
  155. BEQ NoSpit  ;
  156.  
  157. LDA $1558,x ; if the sprite just spat already...
  158. BNE NoSpit  ; don't spit any fireballs
  159. LDA #$30        ;
  160. STA $1540,x ; fireball timer
  161. LDA #$05        ;
  162. STA $1528,x ; fireball counter: 5 fireballs to spit
  163. LDA #$03        ;
  164. STA $C2,x   ; change the sprite state to spitting
  165. NoSpit:     ;
  166. RTS     ;
  167.  
  168. Waiting:        ;
  169.  
  170. LDA $1570,x ; if the wait timer has not run out...
  171. BNE NoMove  ; don't start moving
  172. INC $C2,x   ;
  173. NoMove:     ;
  174.  
  175. LDA $1588,x ;
  176. AND #$04    ; if the sprite is in the air...
  177. BEQ InAir       ;
  178. DEC $1570,x ; don't decrement the wait timer
  179. STZ $160E,x ;
  180. InAir:      ;
  181.  
  182. JSR SubHorzPos  ;
  183. TYA     ; make the sprite always face the player
  184. STA $157C,x ;
  185.  
  186. RTS     ;
  187.  
  188. Moving:     ;
  189.  
  190. LDA $1588,x ;
  191. AND #$04    ; if the sprite is not on the ground...
  192. BEQ NoClearFrame    ; don't set its Y speed
  193.  
  194. LDA #$EE        ;
  195. STA $AA,x   ; make the sprite hop a little
  196.  
  197. LDA #!XSpeed    ; give the sprite some X speed
  198. LDY $157C,x ;
  199. BEQ $03     ; flip the X speed value if the sprite is facing left
  200. EOR #$FF        ;
  201. INC     ;
  202. STA $B6,x       ;
  203.  
  204. JSR Proximity1  ; if the sprite is out of range...
  205. BEQ NoJump2 ; don't make it jump
  206.  
  207. LDA #!JumpSpeed ;
  208. STA $AA,x   ; set its jumping speed
  209. LDA #$02        ; set the frame to upright
  210. STA $160E,x ;
  211. BRA NoClearFrame    ;
  212.  
  213. NoJump2:        ;
  214.  
  215. STZ $160E,x ;
  216.  
  217. NoClearFrame:   ;
  218.  
  219. LDA $14     ;
  220. AND #$1F    ; every few frames...
  221. BNE NoFace  ;
  222. JSR SubHorzPos  ;
  223. TYA     ; make the sprite turn to face the player
  224. STA $157C,x ;
  225. NoFace:     ;
  226.  
  227. RTS
  228.  
  229. SpitFire:       ;
  230.  
  231. LDA $1540,x ; check the spit timer
  232. AND #$07    ;
  233. BNE NoSpit2 ;
  234.  
  235. JSR SubFireSpit ; fireball-spawning routine
  236.  
  237. DEC $1528,x ; decrement the fireball counter
  238. LDA $1540,x ;
  239. BNE NoSpit2 ; if the spit timer has reached zero...
  240.  
  241. LDA #!FireWaitTimer
  242. STA $1558,x ; reset the fire-spit timer
  243. STZ $C2,x   ;
  244.  
  245. NoSpit2:
  246. RTS
  247.  
  248. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  249. ;;
  250. ;; graphics routine
  251. ;;
  252. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  253.  
  254. NipperGFX:
  255.  
  256. JSR GetDrawInfo
  257.  
  258. LDA $157C,x
  259. ROR #3
  260. AND #$40
  261. EOR #$40
  262. STA $02
  263.  
  264. LDA $00
  265. STA $0300,y
  266.  
  267. LDA $01
  268. STA $0301,y
  269.  
  270. PHY
  271. LDY $1602,x
  272. LDA Tilemap,y
  273. PLY
  274. STA $0302,y
  275.  
  276. LDA $15F6,x
  277. ORA $64
  278. ORA $02
  279. STA $0303,y
  280.  
  281. LDY #$02
  282. LDA #$01
  283. JSL $01B7B3
  284. RTS
  285.  
  286. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  287. ;;
  288. ;; fire-spitting routine
  289. ;;
  290. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  291.  
  292. FireXOffsetsLo:
  293. db $06,$FA
  294. FireXOffsetsHi:
  295. db $00,$FF
  296. !FireYOffsetLo = $03
  297. !FireYOffsetHi = $00
  298.  
  299. SubFireSpit:
  300.  
  301. LDY #$07
  302. ExSpriteLoop:
  303. LDA $170B,y
  304. BEQ FoundExSlot
  305. DEY
  306. BPL ExSpriteLoop
  307. RTS
  308.  
  309. FoundExSlot:
  310.  
  311. LDA #$0B
  312. STA $170B,y
  313.  
  314. LDA $E4,x
  315. PHY
  316. LDY $157C,x
  317. CLC
  318. ADC FireXOffsetsLo,y
  319. PLY
  320. STA $171F,y
  321. LDA $14E0,x
  322. PHY
  323. LDY $157C,x
  324. ADC FireXOffsetsHi,y
  325. PLY
  326. STA $1733,y
  327.  
  328. LDA $D8,x
  329. CLC
  330. ADC #!FireYOffsetLo
  331. STA $1715,y
  332. LDA $14D4,x
  333. ADC #!FireYOffsetHi
  334. STA $1729,y
  335.  
  336. LDA #!FireXSpeed
  337. PHY
  338. LDY $157C,x
  339. BEQ $03
  340. EOR #$FF
  341. INC
  342. PLY
  343. STA $1747,y
  344. LDA #!FireYSpeed
  345. STA $173D,y
  346.  
  347. LDA #$FF
  348. STA $176F,y
  349.  
  350. LDA #!FireSound
  351. STA !FireSoundBank
  352.  
  353. RTS
  354.  
  355. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  356. ;;
  357. ;; miscellaneous subroutines
  358. ;;
  359. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  360.  
  361. ExecutePointer: ;
  362.  
  363. PHX     ;
  364. ASL     ;
  365. TAX     ;
  366. REP #$20        ;
  367. LDA StatePointers,x ;
  368. STA $00     ;
  369. SEP #$20        ;
  370. PLX     ;
  371. JMP ($0000) ;
  372.  
  373. Proximity1:     ;
  374.  
  375. LDA #!JumpRange     ;
  376. BRA StoreRange      ;
  377.  
  378. Proximity2:     ;
  379.  
  380. LDA #!FireRange     ;
  381.  
  382. StoreRange:     ;
  383.  
  384. STA $0A
  385.  
  386. ProximityMain:      ;
  387.  
  388. LDA $14E0,x     ; sprite X position high byte
  389. XBA         ; into high byte of A
  390. LDA $E4,x       ; sprite X position low byte into low byte of A
  391. REP #$20            ; set A to 16-bit mode
  392. SEC         ; subtract the player's X position
  393. SBC $94         ; from the sprite's
  394. BPL NoInvertH       ; if the result of the subtraction was negative...
  395. EOR #$FFFF      ; then invert it
  396. INC         ;
  397. NoInvertH:      ;
  398. CMP #$0100      ; if the difference is bigger than 1 screen...
  399. SEP #$20            ;
  400. BCS RangeOut1       ; then the player is out of range anyway
  401. CMP $0A         ; if not, compare the result to the desired range
  402. BCS RangeOut1       ;
  403. RangeIn1:           ;
  404. LDA #$01            ;
  405. RTS         ;
  406. RangeOut1:      ;
  407. LDA #$00            ;
  408. RTS         ;
  409.  
  410. SubHorzPos:
  411.  
  412. LDY #$00
  413. LDA $94
  414. SEC
  415. SBC $E4,x
  416. STA $0F
  417. LDA $95
  418. SBC $14E0,x
  419. BPL $01
  420. INY
  421. RTS
  422.  
  423. Table1:              db $0C,$1C
  424. Table2:              db $01,$02
  425. Table3:              db $40,$B0
  426. Table6:              db $01,$FF
  427. Table4:              db $30,$C0,$A0,$C0,$A0,$F0,$60,$90,$30,$C0,$A0,$80,$A0,$40,$60,$B0
  428. Table5:              db $01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$FF,$01,$00,$01,$FF
  429.  
  430. SubOffscreenX0:
  431. LDA #$00
  432. ;BRA SubOffscreenMain
  433. ;SubOffscreenX1:
  434. ;LDA #$02
  435. ;BRA SubOffscreenMain
  436. ;SubOffscreenX2:
  437. ;LDA #$04
  438. ;BRA SubOffscreenMain
  439. ;SubOffscreenX3:
  440. ;LDA #$06
  441. ;BRA SubOffscreenMain
  442. ;SubOffscreenX4:
  443. ;LDA #$08
  444. ;BRA SubOffscreenMain
  445. ;SubOffscreenX5:
  446. ;LDA #$0A
  447. ;BRA SubOffscreenMain
  448. ;SubOffscreenX6:
  449. ;LDA #$0C
  450. ;BRA SubOffscreenMain
  451. ;SubOffscreenX7:
  452. ;LDA #$0E
  453.  
  454. SubOffscreenMain:
  455.  
  456. STA $03
  457.  
  458. JSR SubIsOffscreen
  459. BEQ Return2
  460.  
  461. LDA $5B
  462. LSR
  463. BCS VerticalLevel
  464. LDA $D8,x
  465. CLC
  466. ADC #$50
  467. LDA $14D4,x
  468. ADC #$00
  469. CMP #$02
  470. BPL EraseSprite
  471. LDA $167A,x
  472. AND #$04
  473. BNE Return2
  474. LDA $13
  475. AND #$01
  476. ORA $03
  477. STA $01
  478. TAY
  479. LDA $1A
  480. CLC
  481. ADC Table4,y
  482. ROL $00
  483. CMP $E4,x
  484. PHP
  485. LDA $1B
  486. LSR $00
  487. ADC Table5,y
  488. PLP
  489. SBC $14E0,x
  490. STA $00
  491. LSR $01
  492. BCC Label20
  493. EOR #$80
  494. STA $00
  495. Label20:
  496. LDA $00
  497. BPL Return2
  498.  
  499. EraseSprite:
  500. LDA $14C8,x
  501. CMP #$08
  502. BCC KillSprite
  503. LDY $161A,x
  504. CPY #$FF
  505. BEQ KillSprite
  506. LDA #$00
  507. STA $1938,y
  508. KillSprite:
  509. STZ $14C8,x
  510. Return2:
  511. RTS
  512.  
  513. VerticalLevel:
  514.  
  515. LDA $167A,x
  516. AND #$04
  517. BNE Return2
  518. LDA $13
  519. LSR
  520. BCS Return2
  521. AND #$01
  522. STA $01
  523. TAY
  524. LDA $1C
  525. CLC
  526. ADC Table3,y
  527. ROL $00
  528. CMP $D8,x
  529. PHP
  530. LDA $1D
  531. LSR $00
  532. ADC Table6,y
  533. PLP
  534. SBC $14D4,x
  535. STA $00
  536. LDY $02
  537. BEQ Label22
  538. EOR #$80
  539. STA $00
  540. Label22:
  541. LDA $00
  542. BPL Return2
  543. BMI EraseSprite
  544.  
  545. SubIsOffscreen:
  546. LDA $15A0,x
  547. ORA $186C,x
  548. RTS
  549.  
  550. GetDrawInfo:
  551.  
  552. STZ $186C,x
  553. STZ $15A0,x
  554. LDA $E4,x
  555. CMP $1A
  556. LDA $14E0,x
  557. SBC $1B
  558. BEQ OnscreenX
  559. INC $15A0,x
  560. OnscreenX:
  561. LDA $14E0,x
  562. XBA
  563. LDA $E4,x
  564. REP #$20
  565. SEC
  566. SBC $1A
  567. CLC
  568. ADC.w #$0040
  569. CMP #$0180
  570. SEP #$20
  571. ROL A
  572. AND #$01
  573. STA $15C4,x
  574. BNE Invalid
  575.  
  576. LDY #$00
  577. LDA $1662,x
  578. AND #$20
  579. BEQ OnscreenLoop
  580. INY
  581. OnscreenLoop:
  582. LDA $D8,x
  583. CLC
  584. ADC Table1,y
  585. PHP
  586. CMP $1C
  587. ROL $00
  588. PLP
  589. LDA $14D4,x
  590. ADC #$00
  591. LSR $00
  592. SBC $1D
  593. BEQ OnscreenY
  594. LDA $186C,x
  595. ORA Table2,y
  596. STA $186C,x
  597. OnscreenY:
  598. DEY
  599. BPL OnscreenLoop
  600. LDY $15EA,x
  601. LDA $E4,x
  602. SEC
  603. SBC $1A
  604. STA $00
  605. LDA $D8,x
  606. SEC
  607. SBC $1C
  608. STA $01
  609. RTS
  610.  
  611. Invalid:
  612. PLA
  613. PLA
  614. RTS
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement