;When you apply this patch, if you go above the screen till Mario becomes invisible, causes the ;game to display an 8x8 graphic showing the player's x position. Useful if your hack deals with ;being above the screen. !TileSize = $00 ;^#$00 = 8x8 tile ; #$02 = 16x16 tile !TileNumber = $1D ;^The tile number seen on the 8x8 tile editor. See bottom status bar (not SMW's!) and use the ;last two hex digits. If 16x16 tile, would be the top left of it. !TileProp = %00110000 ;^Tile properties, in binary (%). YXPPCCCT format: ;-X and Y are flips. ;-PP are priority: ;--00 = behind all except Layer 3 tiles with priority setting 0. ;--01 = behind all except Layer 3 tiles (unless they have priority setting 1 and the "force ; above everything" bit is set) ;--10 = In front of layer 3 (unless they have priority setting 1 and the "force above everything" ; bit is set) and Layer 1 and 2 tiles with priority setting 0; appear behind Layer 1 and 2 tiles ; with priority setting 0 (this is SMW's normal setting for most sprites) ;--11 = Appear in front of everything, except Layer 3 tiles with priority setting 1 if the "force ; above everything" bit is set. ;-CCC = palette to use: ;--000 = 8 ;--001 = 9 ;--010 = A ;--011 = B ;--100 = C ;--101 = D ;--110 = E ;--111 = F ;-T = Use 2nd page if set. !PositionMarker_Y_Position = $08 ;^The Y position the marker is being displayed. $00 Indicates the top of the screen, while $E0 ;is the bottom. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;SA1 detector: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; if read1($00FFD5) == $23 !SA1 = 1 sa1rom else !SA1 = 0 endif ; Example usage if !SA1 ; SA-1 base addresses ;Give thanks to absentCrowned for this: ;http://www.smwcentral.net/?p=viewthread&t=71953 !Base1 = $3000 ;>$0000-$00FF -> $3000-$30FF !Base2 = $6000 ;>$0100-$0FFF -> $6100-$6FFF and $1000-$1FFF -> $7000-$7FFF else ; Non SA-1 base addresses !Base1 = $0000 !Base2 = $0000 endif assert !TileSize == $00 || !TileSize == $02, "Invalid number." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Hijack ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org $00F71A ;>The address that is part of the scrolling routine (compatable with center scroll) autoclean JSL DisplayMarioXPos nop freecode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Main code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DisplayMarioXPos: ;>16-bit mode A PHP ;>Save processor mode into stack (no effect on it though) PHY ;>Save Y into stack LDA $71 ;\Don't display if player is dying. BNE .Done ;/ LDA $96 ;\Y position on-screen (MarioYPos - ScreenYPos) SEC ;|Not use $80 since that does not get updated until next frame SBC $1C ;/ CMP #$FFE0 ;\If player was below that point, return. (His coordinate point is 1 block above mario BEQ + ;|when small or ducking). The BEQ makes it so that you don't have to jump just to reveal BPL .Done ;/a marker. + JSR DisplayXPos .Done PLY ;>Load Y PLP ;>load processor back into 16-bit A .RestoreCode LDA $94 ;\X position on-screen (MarioXPos - ScreenXPos) (restore code) SEC ;| SBC $1A ;/ RTL DisplayXPos: JSR FindOam BCS .Done ;>If no open slots, return. .WriteTile if !TileSize == $00 REP #$20 LDA $7E ;\Tile X position on-screen ($7E is Mario's x pos on-screen, 16-bit) CLC ADC #$0004 ;>Adjust from Mario's position (so it's centered with Mario) SEP #$20 ;>Go back into 8-bit A XBA ;>Read only the high byte X position BNE .Done ;>If High byte is not zero (x pos that is not on screen), don't draw (gfx will wrap). XBA ;>Revert the value back to use low byte else LDA $7F ;\If Mario offscreen, return. BNE .Done ;/ LDA $7E ;>Use low byte of player's x pos on-screen endif STA $0200+!Base2,y ;>And set tile X position on-screen. LDA #!PositionMarker_Y_Position ;\Tile Y position on-screen STA $0201+!Base2,y ;/ LDA #!TileNumber ;\Tile to use STA $0202+!Base2,y ;/ LDA.b #!TileProp ;\Tile properties STA $0203+!Base2,y ;/ LDY.b #!TileSize ;>Y = Tile size LDA.b #$00 ;>Minus 1 (if you wanted 1 tile, put zero) JSL $01B7B3 ;>Write OAM .Done RTS FindOam: LDY #$00 ;>Start at highest priority (appearing in front of most sprites) .Loop LDA $0201,y ;>The Y tile position on-screen, #$F0 = free slot. CMP #$F0 ;\If slot used, go to next one BEQ .NextSlot ;/ .FreeSlot CLC RTS .NextSlot INY INY INY INY CPY #$6C BCC .Loop ;>If useable slot, check it. SEC ;>If Y is on an invalid index, break loop and set carry to indicate "no slots left" RTS