Advertisement
Romano338

Stationnary magikoopa

Jul 30th, 2018
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.82 KB | None | 0 0
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ; Stationary Magikoopa, by yoshicookiezeus
  3. ;
  4. ; Description: This Magikoopa sits in one place repeatedly firing magic,
  5. ; disappearing whenever Mario gets near and reappearing when he goes away.
  6. ; Unlike the normal Magikoopa, several of these can be active at once,
  7. ; and after getting killed (by a thrown sprite, for instance) it does
  8. ; not respawn.
  9. ; Note that wherever you place the sprite in Lunar Magic is where its head
  10. ; appears, so it should be placed one tile above the floor you want it to
  11. ; stand on.
  12. ;
  13. ; Uses the extra bit: No
  14. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  15.  
  16. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  17. ; sprite constants - feel free to change these
  18. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  19.  
  20. !MagicNumber = $20 ; The normal sprite number to generate (Magikoopa magic)
  21. !WandTile = $99 ; The sprite tile to use for the wand
  22.  
  23. !ShootSFX = $10 ; The sound effect to play when shooting magic
  24. !ShootBank = $1DF9
  25.  
  26. Tilemap:
  27. db $A0,$C0,$A0,$C0,$A4,$C4,$A4,$C4,$A0,$C0,$A0,$C0
  28. Y_Disp:
  29. db $10,$00
  30.  
  31. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  32. ; ROM and RAM defines - don't mess with these
  33. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  34. !RAM_FrameCounter = $13
  35. !RAM_FrameCounterB = $14
  36. !RAM_ScreenBndryXLo = $1A
  37. !RAM_ScreenBndryXHi = $1B
  38. !RAM_ScreenBndryYLo = $1C
  39. !RAM_ScreenBndryYHi = $1D
  40. !RAM_MarioSpeedX = $7B
  41. !RAM_MarioXPos = $94
  42. !RAM_MarioXPosHi = $95
  43. !RAM_SpritesLocked = $9D
  44. !RAM_SpriteNum = !9E
  45. !RAM_SpriteSpeedY = !AA
  46. !RAM_SpriteSpeedX = !B6
  47. !RAM_SpriteState = !C2
  48. !RAM_SpriteYLo = !D8
  49. !RAM_SpriteXLo = !E4
  50. !OAM_DispX = $0300|!Base2
  51. !OAM_DispY = $0301|!Base2
  52. !OAM_Tile = $0302|!Base2
  53. !OAM_Prop = $0303|!Base2
  54. !OAM_Tile2DispX = $0304|!Base2
  55. !OAM_Tile2DispY = $0305|!Base2
  56. !OAM_Tile2 = $0306|!Base2
  57. !OAM_Tile2Prop = $0307|!Base2
  58. !OAM_Tile3DispX = $0308|!Base2
  59. !OAM_Tile3DispY = $0309|!Base2
  60. !OAM_Tile3 = $030A|!Base2
  61. !OAM_Tile3Prop = $030B|!Base2
  62. !OAM_TileSize = $0460|!Base2
  63. !RAM_SpriteStatus = !14C8
  64. !RAM_SpriteYHi = !14D4
  65. !RAM_SpriteXHi = !14E0
  66. !RAM_SpriteDir = !157C
  67. !RAM_SprObjStatus = !1588
  68. !RAM_OffscreenHorz = !15A0
  69. !RAM_CurrentSprIndex = $15E9|!Base2
  70. !RAM_SprOAMIndex = !15EA
  71. !RAM_SpritePal = !15F6
  72. !RAM_SmokeNum = $17C0|!Base2
  73. !RAM_SmokeYLo = $17C4|!Base2
  74. !RAM_SmokeXLo = $17C8|!Base2
  75. !RAM_SmokeTimer = $17CC|!Base2
  76. !RAM_OffscreenVert = !186C
  77.  
  78. !FinishOAMWrite = $01B7B3|!BankB
  79. !InitSpriteTables = $07F7D2|!BankB
  80.  
  81. print "INIT ",pc
  82. RTL
  83.  
  84. print "MAIN ",pc
  85. PHB : PHK : PLB
  86. JSR SpriteCode
  87. PLB
  88. RTL
  89.  
  90. SpriteCode:
  91. LDA #$00
  92. %SubOffScreen()
  93. LDA #$01
  94. STA !15D0,x
  95. LDA !RAM_SpriteState,x
  96. JSL $0086DF|!BankB
  97.  
  98. MagiKoopaPtrs:
  99. dw Gone
  100. dw Attacking
  101.  
  102. Gone:
  103. LDA !RAM_SpritesLocked ;\ if sprites locked,
  104. BNE Gone_Return ;/ return
  105. JSR CheckProximityMario
  106. BNE Gone_Return
  107.  
  108. INC !RAM_SpriteState,x ; go to next sprite state
  109. STZ !1570,x
  110. %SubHorzPos() ;\ make sprite face Mario
  111. TYA ; |
  112. STA !RAM_SpriteDir,x ;/
  113. JSR SpawnSmoke
  114. LDA #$70
  115. STA !1540,x
  116. Gone_Return:
  117. RTS
  118.  
  119. DATA_01BE69:
  120. db $04,$02,$00
  121.  
  122. DATA_01BE6C:
  123. db $10,$F8
  124.  
  125. Attacking:
  126. STZ !15D0,x
  127. JSL $01803A|!BankB ; interact with Mario and with other sprites
  128. %SubHorzPos() ;\ make sprite face Mario
  129. TYA ; |
  130. STA !RAM_SpriteDir,x ;/
  131. LDA !1540,x ;\ if attack cycle not complete,
  132. BNE .DontReset ;/ branch
  133. LDA #$70 ;\ reset cycle
  134. STA !1540,x ;/
  135. .DontReset
  136. JSR CheckProximityMario
  137. BEQ .DontDisappear
  138. STZ !RAM_SpriteState,x ; go to next sprite state
  139. JSR SpawnSmoke
  140. BRA .SetGraphics
  141.  
  142. .DontDisappear
  143. LDA !1540,x
  144. CMP #$40 ;\ if not time to generate magic,
  145. BNE .SetGraphics ;/ branch
  146. PHA ; preserve sprite state timer
  147. LDA !RAM_SpritesLocked ;\ if sprites locked
  148. ORA !RAM_OffscreenHorz,x ; | or sprite is offscreen,
  149. BNE .DontSpawn ;/ branch
  150. JSR SpawnMagic
  151. .DontSpawn
  152. PLA ; retrieve sprite state timer
  153. .SetGraphics
  154. LSR #6 ;\ use sprite state timer to determine graphics frame to use
  155. ; | in some very complicated manner
  156. TAY ; | get two highest bits of sprite state timer into y register
  157. PHY ; | and preserve them
  158. LDA !1540,x ; |
  159. LSR #3 ; |
  160. AND #$01 ; | get fourth bit of sprite state timer
  161. ORA DATA_01BE69,y ; | add in something determined by two highest bits
  162. STA !1602,x ;/ and use it to determine sprite graphics frame to use
  163.  
  164. JSR Graphics
  165.  
  166. LDA !1602,x ;\ if sprite graphics frame less than 4,
  167. SEC : SBC #$02 ; |
  168. CMP #$02 ; |
  169. BCC .Label1 ;/ branch
  170. LSR ;\ if it's less than
  171. BCC .Label1 ;/ branch
  172. LDA !RAM_SprOAMIndex,x ;\ place head tile one pixel lower
  173. TAX ; |
  174. INC !OAM_DispY,x ;/
  175.  
  176. LDX !RAM_CurrentSprIndex ; load sprite index
  177.  
  178. .Label1
  179. PLY ;\ retrieve seventh bit of sprite state timer
  180. CPY #$01 ; | if it's clear,
  181. BNE DisplayWand ;/ branch
  182. JSR CODE_01B14E ; sparkle effect
  183.  
  184. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  185.  
  186. DisplayWand:
  187. LDA !1602,x ;\ if sprite graphics frame less than 4,
  188. CMP #$04 ; |
  189. BCC .Return ;/ return
  190. LDY !RAM_SpriteDir,x ;\ use sprite direction to determine x position of wand tile
  191. LDA !RAM_SpriteXLo,x ; |
  192. CLC : ADC DATA_01BE6C,y ; |
  193. SEC : SBC !RAM_ScreenBndryXLo ; |
  194. LDY !RAM_SprOAMIndex,x ; |
  195. STA !OAM_Tile3DispX,y ;/
  196. LDA !RAM_SpriteYLo,x ;\ set y position of wand tile
  197. SEC : SBC !RAM_ScreenBndryYLo ; |
  198. CLC : ADC #$10 ; |
  199. STA !OAM_Tile3DispY,y ;/
  200. LDA !RAM_SpriteDir,x ;\ set properties of wand tile
  201. LSR ; |
  202. LDA #$00 ; |
  203. BCS + ; |
  204. ORA #$40 ; |
  205. + ORA $64 ; |
  206. ORA !RAM_SpritePal,x ; |
  207. STA !OAM_Tile3Prop,y ;/
  208. LDA.b #!WandTile ;\ set wand tile number
  209. STA !OAM_Tile3,y ;/
  210. TYA ;\ set wand tile size
  211. LSR #2 ; |
  212. TAY ; |
  213. LDA #$00 ; |
  214. ORA !RAM_OffscreenHorz,x ; |
  215. STA $0462|!Base2,y ;/
  216. .Return
  217. RTS
  218.  
  219. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  220.  
  221. CheckProximityMario:
  222. %SubHorzPos() ;\ if sprite not closer to Mario than 0x20 pixels horizontally,
  223. LDA $0E ; |
  224. CLC : ADC #$30 ; |
  225. CMP #$60 ; |
  226. BCS + ;/ branch
  227. %SubVertPos() ;\ if sprite not closer to Mario than 0x20 pixels horizontally,
  228. LDA $0F ; |
  229. CLC : ADC #$30 ; |
  230. CMP #$60 ; |
  231. BCS + ;/ branch
  232. LDA #$01
  233. RTS
  234.  
  235. + LDA #$00
  236. RTS
  237.  
  238. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  239.  
  240. SpawnMagic:
  241. LDY.b #!SprSize-3 ; setup loop
  242. - LDA !14C8,y ;\ check if sprite slot is free
  243. BEQ + ;/ if so, branch
  244. DEY ;\ if not, check next slot
  245. BPL - ;/
  246. RTS ; if no slots left, return
  247.  
  248. + LDA.b #!ShootSFX ;\ sound effect
  249. STA.w !ShootBank|!Base2 ;/
  250. LDA #$08 ;\ set sprite status
  251. STA !14C8,y ;/
  252. LDA.b #!MagicNumber ;\ set sprite number
  253. STA.w !9E,y ;/
  254. LDA !sprite_x_low,x ;\ set sprite x position
  255. STA.w !sprite_x_low,y ; |
  256. LDA !sprite_x_high,x ; |
  257. STA.w !sprite_x_high,y ;/
  258. LDA !sprite_y_low,x ;\ set sprite y position
  259. CLC : ADC #$0A ; |
  260. STA.w !sprite_y_low,y ; |
  261. LDA !sprite_y_high,x ; |
  262. ADC #$00 ; |
  263. STA !sprite_y_high,y ;/
  264. TYX
  265. JSL !InitSpriteTables ; clear out old sprite values
  266. LDA #$20
  267. JSR CODE_01BF6A ; aiming routine
  268. LDX !RAM_CurrentSprIndex
  269. LDA $00 ;\ set sprite speeds
  270. STA.w !sprite_speed_y|!Base1,y ; |
  271. LDA $01 ; |
  272. STA.w !sprite_speed_x|!Base1,y ;/
  273. RTS
  274.  
  275. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  276. ; Graphics routine
  277. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  278.  
  279. Graphics:
  280. %GetDrawInfo()
  281. LDA !1602,x ;\ use graphics frame to determine initial tile table offset
  282. ASL ; |
  283. STA $03 ;/
  284. LDA !RAM_SpriteDir,x
  285. STA $02
  286. PHX ; preserve sprite index
  287. LDX #$01 ; setup loop counter
  288. - LDA $01 ;\ set y position of tile
  289. CLC : ADC Y_Disp,x ; |
  290. STA !OAM_DispY,y ;/
  291. LDA $00 ;\ set x position of tile
  292. STA !OAM_DispX,y ;/
  293. PHX ; preserve loop counter
  294. LDX $03 ; get tilemap index
  295. LDA Tilemap,x ;\ set tile number
  296. STA !OAM_Tile,y ;/
  297. LDX !RAM_CurrentSprIndex ; load sprite index
  298. LDA !RAM_SpritePal,x ; load sprite graphics properties
  299. PLX ; retrieve loop counter
  300. PHY ; preserve OAM index
  301. LDY $02 ;\ if sprite facing right,
  302. BNE + ; |
  303. EOR #$40 ;/ flip tile
  304. + PLY ; retrieve OAM index
  305. ORA $64 ; add in level properties
  306. STA !OAM_Prop,Y ; set tile properties
  307. INY #4 ; increase OAM index so that the next tile can be written
  308. INC $03
  309. DEX ; decrease loop counter
  310. BPL - ; if still tiles left to draw, go to start of loop
  311. PLX ; retrieve sprite index
  312. LDY #$02 ; the tiles written were 16x16
  313. LDA #$01 ; we wrote two tiles
  314. JSL !FinishOAMWrite
  315. RTS
  316.  
  317. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  318. ; aiming routine
  319. ; input: accumulator should be set to total speed (x+y)
  320. ; output: $00 = y speed, $01 = x speed
  321. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  322.  
  323. CODE_01BF6A:
  324. STA $01
  325. PHX ;\ preserve sprite indexes of Magikoopa and magic
  326. PHY ;/
  327. JSR CODE_01AD42 ; $0E = vertical distance to Mario
  328. STY $02 ; $02 = vertical direction to Mario
  329. LDA $0E ;\ $0C = vertical distance to Mario, positive
  330. BPL + ; |
  331. EOR #$FF ; |
  332. CLC : ADC #$01 ; |
  333. + STA $0C ;/
  334. %SubHorzPos() ; $0F = horizontal distance to Mario
  335. STY $03 ; $03 = horizontal direction to Mario
  336. LDA $0E ;\ $0D = horizontal distance to Mario, positive
  337. BPL + ; |
  338. EOR #$FF ; |
  339. CLC : ADC #$01 ; |
  340. + STA $0D
  341. LDY #$00
  342. LDA $0D ;\ if vertical distance less than horizontal distance,
  343. CMP $0C ; |
  344. BCS + ;/ branch
  345. INY ; set y register
  346. PHA ;\ switch $0C and $0D
  347. LDA $0C ; |
  348. STA $0D ; |
  349. PLA ; |
  350. STA $0C ;/
  351. + LDA #$00 ;\ zero out $00 and $0B
  352. STA $0B ; | ...what's wrong with STZ?
  353. STA $00 ;/
  354. LDX $01 ;\ divide $0C by $0D?
  355. - LDA $0B ; |\ if $0C + loop counter is less than $0D,
  356. CLC : ADC $0C ; | |
  357. CMP $0D ; | |
  358. BCC + ; |/ branch
  359. SBC $0D ; | else, subtract $0D
  360. INC $00 ; | and increase $00
  361. + STA $0B ; |
  362. DEX ; |\ if still cycles left to run,
  363. BNE - ;/ / go to start of loop
  364. TYA ;\ if $0C and $0D was not switched,
  365. BEQ + ;/ branch
  366. LDA $00 ;\ else, switch $00 and $01
  367. PHA ; |
  368. LDA $01 ; |
  369. STA $00 ; |
  370. PLA ; |
  371. STA $01 ;/
  372. + LDA $00 ;\ if horizontal distance was inverted,
  373. LDY $02 ; | invert $00
  374. BEQ + ; |
  375. EOR #$FF ; |
  376. CLC : ADC #$01 ; |
  377. STA $00 ;/
  378. + LDA $01 ;\ if vertical distance was inverted,
  379. LDY $03 ; | invert $01
  380. BEQ + ; |
  381. EOR #$FF ; |
  382. CLC : ADC #$01 ; |
  383. STA $01 ;/
  384. + PLY ;\ retrieve Magikoopa and magic sprite indexes
  385. PLX ;/
  386. RTS
  387.  
  388. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  389. ; display smoke effect
  390. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  391.  
  392. SpawnSmoke:
  393. LDA !RAM_OffscreenVert,x
  394. ORA !RAM_OffscreenHorz,x
  395. BNE .Return
  396.  
  397. LDY #$03 ; find a free slot to display effect
  398. - LDA !RAM_SmokeNum,y
  399. BEQ +
  400. DEY
  401. BPL -
  402. .Return
  403. RTS ; return if no slots open
  404.  
  405. + LDA #$01 ;\ set effect graphic to smoke graphic
  406. STA !RAM_SmokeNum,y ;/
  407. LDA !RAM_SpriteYLo,x ;\ set smoke y position
  408. CLC : ADC #$08 ; |
  409. STA !RAM_SmokeYLo,y ;/
  410. LDA !RAM_SpriteXLo,x ;\ smoke x position = shooter x position
  411. STA !RAM_SmokeXLo,y ;/
  412. LDA #$1B ;\ set time to show smoke
  413. STA !RAM_SmokeTimer,y ;/
  414. RTS
  415.  
  416. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  417.  
  418. CODE_01B14E:
  419. LDA !RAM_FrameCounter ;\ only run code every fourth frame
  420. AND #$03 ; |
  421. ORA !RAM_OffscreenVert,x ; | if sprite offscreen vertically
  422. ORA !RAM_SpritesLocked ; | or sprites locked,
  423. BNE Return01B191 ;/ return
  424. JSL $01ACF9|!BankB ;\ #$02 = sprite xpos low byte + random number between 0x-5 and 0xB
  425. AND #$0F ; |
  426. CLC ; |
  427. LDY #$00 ; |
  428. ADC #$FC ; |
  429. BPL + ; |
  430. DEY ; |
  431. + ; |
  432. CLC : ADC !RAM_SpriteXLo,x ; |
  433. STA $02 ;/
  434. TYA ;\ if $02 means an offscreen location?
  435. ADC !RAM_SpriteXHi,x ; |
  436. PHA ; |
  437. LDA $02 ; |
  438. CMP !RAM_ScreenBndryXLo ; |
  439. PLA ; |
  440. SBC !RAM_ScreenBndryXHi ; |
  441. BNE Return01B191 ;/ return
  442. LDA $148E ;\ #$00 = sprite ypos low byte + random number between 0x-2 and 0xD
  443. AND #$0F ; |
  444. CLC : ADC #$FE ; |
  445. ADC !RAM_SpriteYLo,x ; |
  446. STA $00 ;/
  447. LDA !RAM_SpriteYHi,x ;\ #$01 = sprite ypos high byte with changes for earlier random number
  448. ADC #$00 ; |
  449. STA $01 ;/
  450. JSL $0285BA|!BankB ; sparkle effect
  451. Return01B191:
  452. RTS
  453.  
  454. CODE_01AD42:
  455. LDY #$00
  456. LDA $D3
  457. CLC ;\ make subroutine use position of Mario's lower half instead of the upper one
  458. ADC #$08 ;/ this wasn't in the original routine
  459. SEC : SBC !RAM_SpriteYLo,x
  460. STA $0E
  461. LDA $D4
  462. SBC !RAM_SpriteYHi,x
  463. BPL +
  464. INY
  465. + RTS
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement