Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ;
- ; Multi-Midway Points 1.1, by imamelia
- ;
- ; Have you ever been disappointed that despite so many advancements,
- ; Super Mario World still allows only one midway point per overworld level
- ; (and it has to be in the same sublevel to boot)? Well, with this patch, those
- ; restrictions are removed. You can have up to 255 checkpoints in each overworld
- ; level, and you can set them to any sublevel number, X position, and Y position
- ; you want. The patch also has an option for changing the level data pointer
- ; on the fly if you want, so you could do things like make levels take you to
- ; different places depending on a given factor (as in Chocolate Island 2). It is,
- ; however, highly recommended to read the readme before use.
- ;
- ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ;header
- lorom
- !OWLevelNum = $13BF ; RAM address for the overworld level number (the reason this is a define is because of the Extra Overworld Level RAM patch)
- !CheckpointRAM = $7FA040 ; 96 bytes of free RAM that will be used for the checkpoints, 1 byte per overworld level
- !AltPtrIndex = $7FA110 ; you can use this to change the level data pointer in sublevels
- ; set bit 15 to enable it, and set bits 0-8 to the level number
- !AltPtrXPos = $7FA112 ; same here, but with the player's X position instead
- !AltPtrYPos = $7FA114 ; same here, but with the player's Y position instead
- org $00802A ; initialize the checkpoint table at game load
- autoclean JSL ClearAllCheckpoints ;
- org $05D8BC ; part of the routine that sets the level number
- autoclean JML MultiMidway1 ;
- org $05DAD7 ; part of the routine that sets the player's XY position (and action)
- autoclean JML MultiMidway2 ;
- org $00976C ;
- autoclean JML GameOverClear ; clear all checkpoints on "Game Over"
- NOP #2 ;
- org $05CBFF ; part of the level end scorecard routine
- autoclean JML LevelEndClear ; clear the checkpoint flags for the current level at level end
- NOP #4 ;
- ; nullify Lunar Magic 2.20's extra midway point hijacks
- if read1($05D979) == $22
- org read3($05D97A)
- AND #$38
- LSR
- LSR
- RTL
- endif
- if read1($05D9E3) == $22
- org read3($05D9E4)
- LSR : LSR : LSR : LSR
- RTL
- endif
- freecode
- ;------------------------------------------------
- ; clear all checkpoints at game load/reset
- ;------------------------------------------------
- ClearAllCheckpoints:
- STA $7F8000 ;
- InitCheckpoints: ;
- PHP ; preserve processor flags
- REP #$20 ; 16-bit A
- SEP #$10 ;
- LDA.w #$0000 ;
- STA !AltPtrIndex ; clear all
- STA !AltPtrXPos ; alternate
- STA !AltPtrYPos ; pointers
- LDX #$5E ; $60 bytes to clear, so load 5E
- .Loop ;
- STA !CheckpointRAM,x ; clear 2 bytes at a time
- DEX ; decrement our index twice,
- DEX ; since we're in 16-bit mode
- BPL .Loop ; if our index is still positive, loop
- PLP ; pull back processor flags
- RTL ;
- ;------------------------------------------------
- ; part of the code that sets the level number to load
- ;------------------------------------------------
- MultiMidway1:
- PHB
- PHK
- PLB
- PHP
- SEP #$30
- JSR MultiMidwayMainRt1
- PLP
- PLB
- REP #$30
- LDA $0E
- STA $010B ; mirror the level number change for levelnum.asm (can easily cause bugs otherwise)
- ASL
- CLC
- ADC $0E
- TAY
- JML $05D8C0
- ;------------------------------------------------
- ; part of the code that sets the player's XY position and action on level load
- ;------------------------------------------------
- MultiMidway2:
- PHB
- PHK
- PLB
- PHP
- SEP #$30
- JSR MultiMidwayMainRt2
- PLP
- PLB
- LDA $141A ; restoring hijacked code...
- BEQ .JumpBack2 ;
- JML $85DADC ;
- .JumpBack2 ;
- JML $85DAEB ;
- ;------------------------------------------------
- ; most of the main code for the multi-midway routines (much of it is shared)
- ;------------------------------------------------
- NoCheckpoints:
- REP #$20 ; 16-bit A
- LDA !AltPtrIndex ; check the alternate level pointer
- BPL ReturnMM ;
- LDA !AltPtrIndex ; load it again...
- AND #$01FF ; we need only the lower 9 bits
- BRA SetLevelNum ; use an alternate pointer index for the level number
- NoCheckpoints2: ;
- REP #$20 ; 16-bit A
- LDA !AltPtrIndex ; check the alternate level pointer
- BMI AltPosition ;
- ReturnMM: ;
- RTS
- AltPosition: ;
- LDA !AltPtrXPos ; set the player's X position
- STA $94 ;
- LDA !AltPtrYPos ; set the player's Y position
- STA $96 ;
- RTS
- MultiMidwayMainRt1:
- LDA $0100 ; check the game mode
- CMP #$11 ; if we are not in a level fade-in sequence...
- BNE ReturnMM ; return
- LDA $141A ; if we are in a sublevel...
- BNE NoCheckpoints ; skip the checkpoint pointer switch
- PHX ;
- LDX !OWLevelNum ; get the overworld level number into X
- LDA !CheckpointRAM,x ; load a byte from the checkpoint table
- PLX ;
- CMP #$00 ;
- BEQ NoCheckpoints ;
- JSR GetIndex ; get the level number index
- LDA ($06),y ; load the level number
- SetLevelNum: ;
- STA $0E ; set the new level number and return
- RTS ; no need to REP #$30, since m and x are already clear
- MultiMidwayMainRt2:
- LDA $141A ; if we are in a sublevel...
- BNE NoCheckpoints2 ; skip the checkpoint pointer switch
- PHX ;
- LDX !OWLevelNum ; get the overworld level number into X
- LDA !CheckpointRAM,x ; load a byte from the checkpoint table
- PLX ;
- CMP #$00 ;
- BEQ NoCheckpoints2 ;
- JSR GetIndex ;
- INY #2 ;
- LDA ($06),y ; get the extra flags
- STA $00 ;
- SEP #$20 ;
- AND #$07 ; bits 0-2 = player action
- STA $192A ;
- LDA $00 ;
- AND #$08 ; bit 3 = slippery level flag
- BEQ .NoSlip ;
- LDA #$80 ;
- TSB $192A ;
- .NoSlip ;
- LDA $00 ;
- AND #$10 ; bit 4 = water level flag
- BEQ .NoWater ;
- LDA #$40 ;
- TSB $192A ;
- .NoWater ;
- REP #$20 ;
- INY #2 ;
- LDA ($06),y ; get the player's X position
- STA $94 ; set the player's X position
- INY #2 ;
- LDA ($06),y ; get the player's Y position
- STA $96 ; set the player's Y position
- INY #2 ;
- LDA ($06),y ; get the Layer 1 X position
- STA $1A ; set the Layer 1 X position
- INY #2 ;
- LDA ($06),y ; get the Layer 1 Y position
- STA $1C ; set the Layer 1 Y position
- INY #2 ;
- LDA ($06),y ; get the Layer 2 X position
- STA $1E ; set the Layer 2 X position
- INY #2 ;
- LDA ($06),y ; get the Layer 2 Y position
- STA $20 ; set the Layer 2 Y position
- RTS ;
- ;------------------------------------------------
- ; clear all checkpoints on Game Over
- ;------------------------------------------------
- GameOverClear:
- JSL InitCheckpoints ; no duh
- STZ $0DC1 ;
- LDA $0DB4 ; hijacked code
- JML $809772 ;
- ;------------------------------------------------
- ; clear the current level's checkpoints at level end
- ;------------------------------------------------
- LevelEndClear: ; clear the current level's checkpoint flags at level end
- PHX ;
- LDX !OWLevelNum ;
- LDA #$00 ;
- STA !CheckpointRAM,x ;
- PLX ;
- PHB ; restore hijacked code:
- LDA #$05 ; preserve data bank
- PHA ; and set the data bank to 05
- PLB ;
- PEA $B298 ; "PLB : RTL" in bank 05
- JML $05CC07|$800000 ; jump to the original routine (we can't just JSL, since it ends in RTS)
- ;------------------------------------------------
- ; subroutine for getting an index to a particular checkpoint table
- ;------------------------------------------------
- GetIndex: ; when this subroutine returns, ($06),y will point to the table of bytes associated with a particular checkpoint
- REP #$20 ; 16-bit A
- LDA !OWLevelNum ; load the overworld level number
- AND.w #$00FF ; wipe the high byte and multiply by 2
- ASL ; since the pointers are 16-bit
- TAY ;
- LDA CheckPtrs,y ; get a pointer for a particular level
- STA $06 ; store this to scratch RAM
- SEP #$20 ; set A back to 8-bit
- PHX ;
- LDX !OWLevelNum ; get the overworld level number into X
- LDA !CheckpointRAM,x ; load a byte from the checkpoint table
- PLX ;
- REP #$30 ; 16-bit AXY
- AND.w #$00FF ; wipe the high byte again
- BEQ .Return ; if no checkpoints have been reached, return
- DEC ; decrement once
- ASL #4 ; there are 16 bytes of data per checkpoint
- TAY ;
- RTS ;
- .Return ;
- PLA ;
- RTS ;
- ;------------------------------------------------
- ; pointers and data tables for the checkpoints
- ;------------------------------------------------
- ;print "Location of multi-midway tables: $",pc
- incsrc multimidwaytables.asm
- ;print "Freespace used: ",bytes," bytes."
- ;print "Next address: $",pc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement