Originally posted by my shitty codey bollocks;; My RAM addresses
RAM_ExtraBits = $7FAB10
RAM_NewSpriteNumber = $7FAB9E
RAM_HammerIndex = $7F8823
;; Original subroutines
GetSpriteClippingA = $03B69F
GetSpriteClippingB = $03B6E5
CheckForContact = $03B72B
SprContactGfx = $01AB72
GivePoints = $02ACE5
SprGfxRt1x1 = $0190B2
;; Original RAM addresses
RAM_SpriteStatus = $14C8
RAM_SpriteYLo = $D8
RAM_SpriteXLo = $E4
RAM_SpriteYHi = $14D4
RAM_SpriteXHi = $14E0
RAM_MarioXPos = $94
RAM_MarioXPosHi = $95
RAM_MarioYPos = $D3
RAM_MarioYPosHi = $D4
RAM_SprOAMIndex = $15EA
OAM_Tile = $0302
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "INIT"
RTL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite main JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "MAIN"
PHB
JSR MarioHasHammer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Mario has hammer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MarioImages:
dcb $35,$35,$35,$36,$36,$37,$37,$37
DispX:
dcb $F4,$FF,$0D,$10,$10,$10,$0D,$FF
DispXHi:
dcb $FF,$FF,$00,$00,$00,$00,$00,$FF
DispY:
dcb $00,$FC,$02,$06,$10,$06,$02,$FC
dcb $FB,$F6,$FD,$06,$10,$06,$FD,$F6
DispYHi:
dcb $00,$FF,$00,$00,$00,$00,$00,$FF
dcb $FF,$FF,$FF,$00,$00,$00,$FF,$FF
MarioHasHammer:
LDA $16
AND #$40
BNE Normal
RTS
Normal:
LDA #$02
STA $7F8824 ; Disable cape spin and fire
STA $7F8825
STA $148F ; Set carrying sprite
STZ $7D ; Stops Mario's x movement
STZ $149F ; Disable flying
LDA $14 ; Set Mario image 7B
INC A
LSR A
AND #$07
TAY
LDA MarioImages,Y
STA $13E0
LDA $14 ; Calculate which frame to show
LSR A
AND #$07
STA $03
PHX ; Y displacement is different if Mario is small
LDX $19
BEQ NotSmall
CLC
ADC #$08
NotSmall:
PLX
TAY ; Set sprite Y position relative to Mario
LDA RAM_MarioYPos
CLC
ADC DispY,y
STA RAM_SpriteYLo,x
LDA RAM_MarioYPosHi
ADC DispYHi,y
STA RAM_SpriteYHi,x
LDY $03
LDA $76
BEQ Subtract
LDA RAM_MarioXPos ; Set sprite X position relative to Mario
CLC ; (Mario facing right)
ADC DispX,y
STA RAM_SpriteXLo,x
LDA RAM_MarioXPosHi
ADC DispXHi,y
STA RAM_SpriteXHi,x
BRA DoGfx
Subtract:
LDA RAM_MarioXPos ; Set sprite X position relative to Mario
SEC ; (Mario facing left)
SBC DispX,y
STA RAM_SpriteXLo,x
LDA RAM_MarioXPosHi
SBC DispXHi,y
STA RAM_SpriteXHi,x
DoGfx:
JSR SubGfx ; Draw hammer
LDA $9D
BNE Return
JSR Interact
LDA $14 ; The timer only ticks down every fourth frame
AND #$03
BEQ Return
INC $1540,X
Return:
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Process interaction with other sprites
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Interact:
LDY.B #$0B
LoopStart:
LDA RAM_SpriteStatus,Y ; Skip dead sprites
CMP #$08
BCC NextSprite
LDA $1686,Y ; Skip sprites that don't interact with others
AND #$08
BNE NextSprite
JSR SprSprInteract
NextSprite:
DEY
BPL LoopStart
RTS
SprSprInteract:
JSL GetSpriteClippingA
PHX
TYX
JSL GetSpriteClippingB
PLX
JSL CheckForContact
BCC Return1
PHX
TYX
LDA #$02 ; Sprite status = star killed
STA $14C8,x
LDA #$D0
STA $AA,x
JSL SprContactGfx
PLX
LDA RAM_ExtraBits,x
AND #$04
BNE BounusTime
LDA #$03 ; Play sound and give 200 points
STA $1DF9
LDA #$01
JSL GivePoints
RTS
BounusTime:
PHY ; Handle sound and points/1ups
LDY $1528,x
INY
CPY #$08
BCS NoStarSound
LDA StarSounds,y
STA $1DF9
BRA SetPoints
NoStarSound:
LDY #$08
SetPoints:
TYA
STA $1528,x
JSL GivePoints
PLY
Return1:
RTS
StarSounds
dcb $00,$13,$14,$15,$16,$17,$18,$19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Draw Hammer graphics
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HammerTiles:
dcb $E6,$E4,$E6,$E8,$E6,$E8,$E6,$E4
Direction:
dcb $40,$00,$00,$00,$80,$00,$00,$00
Flip:
dcb $40,$00
SubGfx:
LDA $1540,x
CMP #$14
BNE NoSound
LDY #$24 ; \ play sound effect
STY $1DFC ; /
NoSound:
JSR GetDrawInfo
PHX
LDX $76
LDA Flip,x
STA $02
LDX $03
LDA $00
STA $0300,y
LDA $01
STA $0301,y
LDA HammerTiles,x
STA $0302,y
PHX
LDX $15E9
LDA $15F6,x ; get palette info
PLX
ORA $02
EOR Direction,x
ORA $64 ; add in tile priority of level
STA $0303,y ; store tile properties
PLX
LDY #$02
LDA #$01
JSL $01B7B3
NoDraw:
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B85D - off screen processing code - shared
; sprites enter at different points
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TABLE3 dcb $40,$B0
TABLE6 dcb $01,$FF
TABLE4 dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0
TABLE5 dcb $01,$FF,$01,$FF,$01,$00,$01,$FF
SubOffScreen: JSR SUB_IS_OFF_SCREEN ; \ if sprite is not off screen, return
BEQ RETURN_2 ; /
LDA $5B ; \ goto VERTICAL_LEVEL if vertical level
AND #$01 ; |
BNE VERTICAL_LEVEL ; /
LDA $D8,x ; \
CLC ; |
ADC #$50 ; | if the sprite has gone off the bottom of the level...
LDA $14D4,x ; | (if adding 0x50 to the sprite y position would make the high byte >= 2)
ADC #$00 ; |
CMP #$02 ; |
BPL ERASE_SPRITE ; / ...erase the sprite
LDA $167A,x ; \ if "process offscreen" flag is set, return
AND #$04 ; |
BNE RETURN_2 ; /
LDA $13 ; \
AND #$01 ; |
STA $01 ; |
TAY ; /
LDA $1A ;x boundry
CLC
ADC TABLE4,y
ROL $00
CMP $E4,x ;x pos
PHP
LDA $1B ;x boundry hi
LSR $00
ADC TABLE5,y
PLP
SBC $14E0,x ;x pos high
STA $00
LSR $01
BCC LABEL20
EOR #$80
STA $00
LABEL20 LDA $00
BPL RETURN_2
ERASE_SPRITE LDA $14C8,x ; \ if sprite status < 8, permanently erase sprite
CMP #$08 ; |
BCC KILL_SPRITE ; /
LDY $161A,x
CPY #$FF
BEQ KILL_SPRITE
LDA #$00 ; \ mark sprite to come back
STA $1938,y ; /
KILL_SPRITE STZ $14C8,x ; erase sprite
RETURN_2 RTS ; return
VERTICAL_LEVEL LDA $167A,x ; \ if "process offscreen" flag is set, return
AND #$04 ; |
BNE RETURN_2 ; /
LDA $13 ; \ only handle every other frame??
LSR A ; |
BCS RETURN_2 ; /
AND #$01
STA $01
TAY
LDA $1C
CLC
ADC TABLE3,y
ROL $00
CMP $D8,x
PHP
LDA.W $001D
LSR $00
ADC TABLE6,y
PLP
SBC $14D4,x
STA $00
LDY $01
BEQ LABEL22
EOR #$80
STA $00
LABEL22 LDA $00
BPL RETURN_2
BMI ERASE_SPRITE
SUB_IS_OFF_SCREEN LDA $15A0,x ; \ if sprite is on screen, accumulator = 0
ORA $186C,x ; |
RTS ; / return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GET_DRAW_INFO
; This is a helper for the graphics routine. It sets off screen flags, and sets up
; variables. It will return with the following:
;
; Y = index to sprite OAM ($300)
; $00 = sprite x position relative to screen boarder
; $01 = sprite y position relative to screen boarder
;
; It is adapted from the subroutine at $03B760
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DATA_03B75C: dcb $0C,$1C
DATA_03B75E: dcb $01,$02
GetDrawInfo: STZ $186C,X ; Reset sprite offscreen flag, vertical
STZ $15A0,X ; Reset sprite offscreen flag, horizontal
LDA $E4,X ; \
CMP $1A ; | Set horizontal offscreen if necessary
LDA $14E0,X ; |
SBC $1B ; |
BEQ ADDR_03B774 ; |
INC $15A0,X ; /
ADDR_03B774: LDA $14E0,X ; \
XBA ; | Mark sprite invalid if far enough off screen
LDA $E4,X ; |
REP #$20 ; Accum (16 bit)
SEC ; |
SBC $1A ; |
CLC ; |
ADC.W #$0040 ; |
CMP.W #$0180 ; |
SEP #$20 ; Accum (8 bit)
ROL ; |
AND.B #$01 ; |
STA $15C4,X ; |
BNE ADDR_03B7CF ; /
LDY.B #$00 ; \ set up loop:
LDA $1662,X ; |
AND.B #$20 ; | if not smushed (1662 & 0x20), go through loop twice
BEQ ADDR_03B79A ; | else, go through loop once
INY ; /
ADDR_03B79A: LDA $D8,X ; \
CLC ; | set vertical offscree
ADC DATA_03B75C,Y ; |
PHP ; |
CMP $1C ; | (vert screen boundry)
ROL $00 ; |
PLP ; |
LDA $14D4,X ; |
ADC.B #$00 ; |
LSR $00 ; |
SBC $1D ; |
BEQ ADDR_03B7BA ; |
LDA $186C,X ; | (vert offscreen)
ORA DATA_03B75E,Y ; |
STA $186C,X ; |
ADDR_03B7BA: DEY ; |
BPL ADDR_03B79A ; /
LDY $15EA,X ; get offset to sprite OAM
LDA $E4,X ; \
SEC ; |
SBC $1A ; |
STA $00 ; / $00 = sprite x position relative to screen boarder
LDA $D8,X ; \
SEC ; |
SBC $1C ; |
STA $01 ; / $01 = sprite y position relative to screen boarder
RTS ; Return
ADDR_03B7CF: PLA ; \ Return from *main gfx routine* subroutine...
PLA ; | ...(not just this subroutine)
RTS ; /
In case you can't tell, it's only a very mild edit of MikeyK's Hammer powerup sprite. What this is supposed to do is only work when you press Y, however it's now reverted to simply crashing the game.