Advertisement
Guest User

Untitled

a guest
Jun 16th, 2014
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.70 KB | None | 0 0
  1. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. ;
  3. ; Multi-Midway Points 1.1, by imamelia
  4. ;
  5. ; Have you ever been disappointed that despite so many advancements,
  6. ; Super Mario World still allows only one midway point per overworld level
  7. ; (and it has to be in the same sublevel to boot)? Well, with this patch, those
  8. ; restrictions are removed. You can have up to 255 checkpoints in each overworld
  9. ; level, and you can set them to any sublevel number, X position, and Y position
  10. ; you want. The patch also has an option for changing the level data pointer
  11. ; on the fly if you want, so you could do things like make levels take you to
  12. ; different places depending on a given factor (as in Chocolate Island 2). It is,
  13. ; however, highly recommended to read the readme before use.
  14. ;
  15. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16.  
  17. ;header
  18. lorom
  19.  
  20. !OWLevelNum = $13BF ; RAM address for the overworld level number (the reason this is a define is because of the Extra Overworld Level RAM patch)
  21.  
  22. !CheckpointRAM = $7FA040 ; 96 bytes of free RAM that will be used for the checkpoints, 1 byte per overworld level
  23.  
  24. !AltPtrIndex = $7FA110 ; you can use this to change the level data pointer in sublevels
  25. ; set bit 15 to enable it, and set bits 0-8 to the level number
  26. !AltPtrXPos = $7FA112 ; same here, but with the player's X position instead
  27. !AltPtrYPos = $7FA114 ; same here, but with the player's Y position instead
  28.  
  29. org $00802A ; initialize the checkpoint table at game load
  30. autoclean JSL ClearAllCheckpoints ;
  31.  
  32. org $05D8BC ; part of the routine that sets the level number
  33. autoclean JML MultiMidway1 ;
  34.  
  35. org $05DAD7 ; part of the routine that sets the player's XY position (and action)
  36. autoclean JML MultiMidway2 ;
  37.  
  38. org $00976C ;
  39. autoclean JML GameOverClear ; clear all checkpoints on "Game Over"
  40. NOP #2 ;
  41.  
  42. org $05CBFF ; part of the level end scorecard routine
  43. autoclean JML LevelEndClear ; clear the checkpoint flags for the current level at level end
  44. NOP #4 ;
  45.  
  46. ; nullify Lunar Magic 2.20's extra midway point hijacks
  47. if read1($05D979) == $22
  48. org read3($05D97A)
  49. AND #$38
  50. LSR
  51. LSR
  52. RTL
  53. endif
  54.  
  55. if read1($05D9E3) == $22
  56. org read3($05D9E4)
  57. LSR : LSR : LSR : LSR
  58. RTL
  59. endif
  60.  
  61. freecode
  62.  
  63. ;------------------------------------------------
  64. ; clear all checkpoints at game load/reset
  65. ;------------------------------------------------
  66.  
  67. ClearAllCheckpoints:
  68. STA $7F8000 ;
  69. InitCheckpoints: ;
  70. PHP ; preserve processor flags
  71. REP #$20 ; 16-bit A
  72. SEP #$10 ;
  73. LDA.w #$0000 ;
  74. STA !AltPtrIndex ; clear all
  75. STA !AltPtrXPos ; alternate
  76. STA !AltPtrYPos ; pointers
  77. LDX #$5E ; $60 bytes to clear, so load 5E
  78. .Loop ;
  79. STA !CheckpointRAM,x ; clear 2 bytes at a time
  80. DEX ; decrement our index twice,
  81. DEX ; since we're in 16-bit mode
  82. BPL .Loop ; if our index is still positive, loop
  83. PLP ; pull back processor flags
  84. RTL ;
  85.  
  86. ;------------------------------------------------
  87. ; part of the code that sets the level number to load
  88. ;------------------------------------------------
  89.  
  90. MultiMidway1:
  91. PHB
  92. PHK
  93. PLB
  94. PHP
  95. SEP #$30
  96. JSR MultiMidwayMainRt1
  97. PLP
  98. PLB
  99. REP #$30
  100. LDA $0E
  101. STA $010B ; mirror the level number change for levelnum.asm (can easily cause bugs otherwise)
  102. ASL
  103. CLC
  104. ADC $0E
  105. TAY
  106. JML $05D8C0
  107.  
  108. ;------------------------------------------------
  109. ; part of the code that sets the player's XY position and action on level load
  110. ;------------------------------------------------
  111.  
  112. MultiMidway2:
  113. PHB
  114. PHK
  115. PLB
  116. PHP
  117. SEP #$30
  118. JSR MultiMidwayMainRt2
  119. PLP
  120. PLB
  121. LDA $141A ; restoring hijacked code...
  122. BEQ .JumpBack2 ;
  123. JML $85DADC ;
  124. .JumpBack2 ;
  125. JML $85DAEB ;
  126.  
  127. ;------------------------------------------------
  128. ; most of the main code for the multi-midway routines (much of it is shared)
  129. ;------------------------------------------------
  130.  
  131. NoCheckpoints:
  132. REP #$20 ; 16-bit A
  133. LDA !AltPtrIndex ; check the alternate level pointer
  134. BPL ReturnMM ;
  135. LDA !AltPtrIndex ; load it again...
  136. AND #$01FF ; we need only the lower 9 bits
  137. BRA SetLevelNum ; use an alternate pointer index for the level number
  138. NoCheckpoints2: ;
  139. REP #$20 ; 16-bit A
  140. LDA !AltPtrIndex ; check the alternate level pointer
  141. BMI AltPosition ;
  142. ReturnMM: ;
  143. RTS
  144.  
  145. AltPosition: ;
  146. LDA !AltPtrXPos ; set the player's X position
  147. STA $94 ;
  148. LDA !AltPtrYPos ; set the player's Y position
  149. STA $96 ;
  150. RTS
  151.  
  152. MultiMidwayMainRt1:
  153. LDA $0100 ; check the game mode
  154. CMP #$11 ; if we are not in a level fade-in sequence...
  155. BNE ReturnMM ; return
  156. LDA $141A ; if we are in a sublevel...
  157. BNE NoCheckpoints ; skip the checkpoint pointer switch
  158. PHX ;
  159. LDX !OWLevelNum ; get the overworld level number into X
  160. LDA !CheckpointRAM,x ; load a byte from the checkpoint table
  161. PLX ;
  162. CMP #$00 ;
  163. BEQ NoCheckpoints ;
  164. JSR GetIndex ; get the level number index
  165. LDA ($06),y ; load the level number
  166. SetLevelNum: ;
  167. STA $0E ; set the new level number and return
  168. RTS ; no need to REP #$30, since m and x are already clear
  169.  
  170. MultiMidwayMainRt2:
  171. LDA $141A ; if we are in a sublevel...
  172. BNE NoCheckpoints2 ; skip the checkpoint pointer switch
  173. PHX ;
  174. LDX !OWLevelNum ; get the overworld level number into X
  175. LDA !CheckpointRAM,x ; load a byte from the checkpoint table
  176. PLX ;
  177. CMP #$00 ;
  178. BEQ NoCheckpoints2 ;
  179. JSR GetIndex ;
  180. INY #2 ;
  181. LDA ($06),y ; get the extra flags
  182. STA $00 ;
  183. SEP #$20 ;
  184. AND #$07 ; bits 0-2 = player action
  185. STA $192A ;
  186. LDA $00 ;
  187. AND #$08 ; bit 3 = slippery level flag
  188. BEQ .NoSlip ;
  189. LDA #$80 ;
  190. TSB $192A ;
  191. .NoSlip ;
  192. LDA $00 ;
  193. AND #$10 ; bit 4 = water level flag
  194. BEQ .NoWater ;
  195. LDA #$40 ;
  196. TSB $192A ;
  197. .NoWater ;
  198. REP #$20 ;
  199. INY #2 ;
  200. LDA ($06),y ; get the player's X position
  201. STA $94 ; set the player's X position
  202. INY #2 ;
  203. LDA ($06),y ; get the player's Y position
  204. STA $96 ; set the player's Y position
  205. INY #2 ;
  206. LDA ($06),y ; get the Layer 1 X position
  207. STA $1A ; set the Layer 1 X position
  208. INY #2 ;
  209. LDA ($06),y ; get the Layer 1 Y position
  210. STA $1C ; set the Layer 1 Y position
  211. INY #2 ;
  212. LDA ($06),y ; get the Layer 2 X position
  213. STA $1E ; set the Layer 2 X position
  214. INY #2 ;
  215. LDA ($06),y ; get the Layer 2 Y position
  216. STA $20 ; set the Layer 2 Y position
  217. RTS ;
  218.  
  219. ;------------------------------------------------
  220. ; clear all checkpoints on Game Over
  221. ;------------------------------------------------
  222.  
  223. GameOverClear:
  224. JSL InitCheckpoints ; no duh
  225. STZ $0DC1 ;
  226. LDA $0DB4 ; hijacked code
  227. JML $809772 ;
  228.  
  229. ;------------------------------------------------
  230. ; clear the current level's checkpoints at level end
  231. ;------------------------------------------------
  232.  
  233. LevelEndClear: ; clear the current level's checkpoint flags at level end
  234. PHX ;
  235. LDX !OWLevelNum ;
  236. LDA #$00 ;
  237. STA !CheckpointRAM,x ;
  238. PLX ;
  239. PHB ; restore hijacked code:
  240. LDA #$05 ; preserve data bank
  241. PHA ; and set the data bank to 05
  242. PLB ;
  243. PEA $B298 ; "PLB : RTL" in bank 05
  244. JML $05CC07|$800000 ; jump to the original routine (we can't just JSL, since it ends in RTS)
  245.  
  246. ;------------------------------------------------
  247. ; subroutine for getting an index to a particular checkpoint table
  248. ;------------------------------------------------
  249.  
  250. GetIndex: ; when this subroutine returns, ($06),y will point to the table of bytes associated with a particular checkpoint
  251. REP #$20 ; 16-bit A
  252. LDA !OWLevelNum ; load the overworld level number
  253. AND.w #$00FF ; wipe the high byte and multiply by 2
  254. ASL ; since the pointers are 16-bit
  255. TAY ;
  256. LDA CheckPtrs,y ; get a pointer for a particular level
  257. STA $06 ; store this to scratch RAM
  258. SEP #$20 ; set A back to 8-bit
  259. PHX ;
  260. LDX !OWLevelNum ; get the overworld level number into X
  261. LDA !CheckpointRAM,x ; load a byte from the checkpoint table
  262. PLX ;
  263. REP #$30 ; 16-bit AXY
  264. AND.w #$00FF ; wipe the high byte again
  265. BEQ .Return ; if no checkpoints have been reached, return
  266. DEC ; decrement once
  267. ASL #4 ; there are 16 bytes of data per checkpoint
  268. TAY ;
  269. RTS ;
  270. .Return ;
  271. PLA ;
  272. RTS ;
  273.  
  274. ;------------------------------------------------
  275. ; pointers and data tables for the checkpoints
  276. ;------------------------------------------------
  277.  
  278. ;print "Location of multi-midway tables: $",pc
  279.  
  280. incsrc multimidwaytables.asm
  281.  
  282. ;print "Freespace used: ",bytes," bytes."
  283. ;print "Next address: $",pc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement