Sehr netter Levelaufbau. Vielleicht noch zum Münzpfeil nen Koopa setzen?
Die Palette vom BG ist mir ehrlich gesagt etwas zu, ich weiß nicht, wie soll ich sagen, flächig blau?!???
Alles in allem doch sehr schön
LDA $0DBF
CMP #$05 ; diese Zahl ändern, um die Anzahl der Münzen zu ändern, welche man zahlen muss
BCC ZuWenigCoins
SEC
SBC #$05 ; diese Zahl AUCH ändern, um die Anzahl der Münzen zu ändern, welche man zahlen muss
INC $0DBE
ZuWenigCoins:
RTL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Bowser Jr., by dahnamics
;;
;; Credit: mikeyk (Shy Guy), Yoshicookiezeus (Thwomp boss v. 2.0), Schwa (sledge_ex)
;;
;; Description: This sprite is loosely based on Bowser Jr. from NSMB. He cannot be jumped on
;; until Mario throws a shell at him. Just like his form in 4-Tower, 6-Tower2, 7-Tower
;; and the towers in World 8, he throws a shell at Mario and Mario throws the shell back
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shy Guy, by mikeyk
;;
;; Description: A Shy Guy with many available configurations.
;;
;; Note: When rideable, clipping tables values should be: 03 0A FE 0E
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Uses first extra bit: NO
;;
;; Extra Property Byte 1
;; bit 0 - enable spin killing
;; bit 1 - stay on ledges
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SPRITE_Y_SPEED = $AA
SPRITE_X_SPEED = $B6
SPRITE_Y_POS = $D8
ORIG_Y_POS = $151C
H_OFFSCREEN = $15A0
V_OFFSCREEN = $186C
FREEZE_TIMER = $1540
SMASH_STATUS = $1602
STATE_TIMER = $163E
RAM_ThrowTimer = $1504
SPR_OBJ_STATUS = $1588
EXTRA_BITS = $7FAB10
EXTRA_PROP_1 = $7FAB28
GetSpriteClippingA = $03B69F
CheckForContact = $03B72B
GetSpriteClippingB = $03B6E5
ShowSprContactGfx = $01AB72
Invuln_Timer = $1564 ; The RAM address for Clawgrip's stun duration
MAX_Y_SPEED = $3E
MAX_Y_SPEED2 = $C2
; definitions of bits (don't change these)
IS_ON_GROUND = $04
IS_ON_CEILING = $08
TIME_ON_GROUND = $A0
TIME_TO_SHAKE = $40
RISE_SPEED = $C0
SOUND_EFFECT = $09
SPRITE_GRAVITY = $20
SPRITE_GRAVITY2 = $04
TIME_TO_EXPLODE = $00
X_SPEED dcb $08,$F8,$10,$F0
X_SPEED2 dcb $20,$E0
HURT_SPEED dcb $20,$E0
KILLED_X_SPEED dcb $F0,$10
SPRITE_STATE = $C2
HIT_POINTS = $05 ; being stomped by Mario
SPHERE = $6F
PROPFLASH:
dcb $04,$06,$08,$0C,$04,$06,$08,$0C
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "INIT"
LDA SPRITE_Y_POS,x
STA ORIG_Y_POS,x
LDA $E4,x
CLC
ADC #$08
STA $E4,x
TXA
AND #$03
ASL A
ASL A
ASL A
ASL A
ASL A
STA STATE_TIMER,x
CLC
ADC #$32
STA RAM_ThrowTimer,x
PHY
JSR SUB_HORZ_POS
TYA
STA $157C,x
PLY
LDA $1588,x ; if on the ground, reset the turn counter
ORA #$04
STA $1588,x ; if on the ground, reset the turn counter
RTL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite code JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "MAIN"
PHB ; \
PHK ; | main sprite function, just calls local subroutine
PLB ; |
JSR SPRITE_CODE_START ; |
PLB ; |
RTL ; /
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite main code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RETURN RTS
SPRITE_CODE_START
JSR SUB_GFX ; graphics routine
LDA $14C8,x ; return if sprite status != 8
CMP #$08 ; \ if status != 8, return
BNE RETURN ; /
LDA $9D ; \ if sprites locked, return
BNE RETURN ; /
JSR SUB_OFF_SCREEN_X3 ; handle off screen situation
DONE_WITH_SPEED
JSL $018032 ; interact with sprites
LDA $1528,x ; \ if sprite hit counter == 3
CMP #HIT_POINTS ; |
BEQ NO_CONTACT ; /
JSR HIT_ROUTINE
MARIO_INTERACT JSL $01A7DC ; interact with mario
BCC NO_CONTACT ; return if no contact
LDA $154C,x ; \ if sprite invincibility timer > 0 ...
BNE NO_CONTACT ; / ... goto NO_CONTACT
LDA #$08 ; \ sprite invincibility timer = $08
STA $154C,x ; /
LDA $7D ; \ if Mario's y speed < 10 ...
CMP #$10 ; } ... sprite will DEAD Mario
BMI SPRITE_WINS ; /
LDA SPRITE_STATE,x ; return if sprite is invulnerable
CMP #$05
BNE SPRITE_WINS
MARIO_WINS
JSR SUB_STOMP_PTS ; give Mario points
JSL $01AA33 ; set Mario speed
JSL $01AB99 ; display contact graphic
LDA #$28 ; \ sound effect
STA $1DFC ; /
LDA #$A0 ; \ Set stunned timer
STA $1564,x ; /
INC $1528,x ; increment sprite hit counter
LDA $1528,x ; \ if sprite hit counter == 3
CMP #HIT_POINTS ; |
BNE SMUSH_SPRITE ; /
SMUSH_SPRITE LDA #$0C ; \ time to show semi-squashed sprite = $0C
STA $1FE2,x ; /
LDA $1528,x ; \ if sprite hit counter == 3
CMP #HIT_POINTS ; |
BEQ SPRITE_DEAD ; /
LDA #$04
STA SPRITE_STATE,x
BRA NEW_RETURN
SPRITE_DEAD LDA #$06
STA SPRITE_STATE,x
NEW_RETURN RTS ; return
SPRITE_WINS
LDA $1497 ; \ if Mario is invincible...
ORA $187A ; } ... or Mario on yoshi...
BNE NO_CONTACT ; / ... return
JSR SUB_HORZ_POS ; \ set new sprite direction
TYA ; }
STA $157C,x ; /
JSL $00F5B7 ; hurt Mario
NO_CONTACT LDA SPRITE_STATE,x
CMP #$01
BEQ WALKING0
CMP #$02
BEQ FURIOUS0
CMP #$03
BEQ THROWING0
CMP #$04
BEQ HURT0
CMP #$05
BEQ STUNNED0
CMP #$06
BEQ DEAD0
CMP #$07
BEQ EXITING0
;-----------------------------------------------------------------------------------------
; state 0
;-----------------------------------------------------------------------------------------
WAITING
LDA V_OFFSCREEN,x ;fall if offscreen vertically
BNE SET_WALKING
LDA H_OFFSCREEN,x ;return if offscreen horizontally
BNE RETURN0
JSR SUB_HORZ_POS ;determine if mario is close and act accordingly
TYA
STA $157C,x
LDA $1588,x ; \ if sprite is in contact with an object...
AND #$03 ; |
BEQ NO_OBJ_CONTACT0 ; |
LDA $157C,x ; | flip the direction status
EOR #$01 ; |
STA $157C,x ; /
NO_OBJ_CONTACT0
LDA $1588,x ; run the subroutine if the sprite is in the air...
ORA $151C,x ; ...and not already turning
BNE ON_GROUND0 ;
JSR SUB_CHANGE_DIR ;
LDA #$01 ; set that we're already turning
STA $151C,x ;
ON_GROUND0
LDA $1588,x ; if on the ground, reset the turn counter
AND #$04
BEQ RETURN0
STZ $151C,x
STZ $AA,x
BRA X_TIME0
FALLING0
LDA $1588,x ; if on the ground, reset the turn counter
AND #$04
BEQ RETURN0
LDA #$10 ; \ y speed = 10
STA $AA,x ; /
X_TIME0 STZ $B6,x
BCS RETURN0
LDA $0F
CLC
ADC #$40
CMP #$80
BCS THWOMP_4
THWOMP_4
LDA $0F
CLC
ADC #$24
CMP #$50
BCS RETURN0
SET_WALKING
INC SPRITE_STATE,x ;chage state to falling
WALKING0 BRA WALKING
RETURN0 JSL $01802A ; update position based on speed values
RTS
THROWING0 JMP THROWING
FURIOUS0 JMP FURIOUS
HURT0 JMP HURT
STUNNED0 JMP STUNNED
DEAD0 JMP DEAD
EXITING0 JMP EXITING
;-----------------------------------------------------------------------------------------
; state 1
;-----------------------------------------------------------------------------------------
WALKING
LDA #$00 ; If timer isn't C0..
CMP $1534,x ;
JSR SUB_HORZ_POS ;determine if mario is close and act accordingly
TYA
STA $157C,x
LDA $1588,x ; \ if sprite is in contact with an object...
AND #$03 ; |
BEQ NO_OBJ_CONTACT ; |
LDA $157C,x ; | flip the direction status
EOR #$01 ; |
STA $157C,x ; /
NO_OBJ_CONTACT
LDA $1588,x ; run the subroutine if the sprite is in the air...
ORA $151C,x ; ...and not already turning
BNE ON_GROUND ;
JSR SUB_CHANGE_DIR ;
LDA #$01 ; set that we're already turning
STA $151C,x ;
ON_GROUND LDA $1588,x ; if on the ground, reset the turn counter
AND #$04
BEQ IN_AIR
STZ $151C,x
STZ $AA,x
BRA X_TIME
FALLING LDA $1588,x ; if on the ground, reset the turn counter
AND #$04
BEQ IN_AIR
LDA #$10 ; \ y speed = 10
STA $AA,x ; /
X_TIME LDA $1528,x ; \ set x speed based on total HP
ASL
CLC
ADC $157C,x ; and direction
TAY
LDA X_SPEED,y ; |
STA $B6,x ; /
CONTINUE2 LDA STATE_TIMER,x
CMP #$28 ; | just go to normal walking code
BCS RETURN0 ; /
LDA Invuln_Timer,x
CMP #$00
BNE RETURN0
LDA STATE_TIMER,x
CMP #$21
BNE NO_JUMP2
LDA $1570,x
LSR A
AND #01
BEQ NO_JUMP2
STZ STATE_TIMER,x ; x speed = 0
BRA RETURN2
NO_JUMP2 CMP #$00
BNE RETURN2
SET_FALLING STZ SPRITE_X_SPEED,x
LDA #$03
STA SPRITE_STATE,x
LDA #$00
STA SPRITE_Y_SPEED,x ;set initial speed
IN_AIR JSL $01802A ; update position based on speed values
RETURN2 RTS
;-----------------------------------------------------------------------------------------
; state 2
;-----------------------------------------------------------------------------------------
FURIOUS
LDA $1588,x ; \ if sprite is in contact with an object...
AND #$03 ; |
BEQ NO_OBJ_CONTACT2 ; |
LDA $157C,x ; | flip the direction status
EOR #$01 ; |
STA $157C,x ; /
NO_OBJ_CONTACT2
LDA $1588,x ; run the subroutine if the sprite is in the air...
ORA $151C,x ; ...and not already turning
BNE X_TIME2 ;
JSR SUB_CHANGE_DIR ;
LDA #$01 ; set that we're already turning
STA $151C,x ;
X_TIME2 LDY $157C,x ; \ set x speed based on direction
LDA X_SPEED2,y ; |
STA $B6,x ; /
JSR Hop ; Jump to custom code
IN_AIR2 JSL $01802A ; update position based on speed values
Hop:
LDA #$C0 ; If timer isn't C0..
CMP $1504,x ;
BNE IncreaseHop ; Increase it.
LDA $1588,x ; Don't jump if already on ground.
AND #$04 ;
BEQ RETURN4 ;
JSR SUB_HAMMER_THROW2
LDA #$C0 ; Set jump height.
STA $AA,x ; Store it too.
STZ $1504,x ; Reset timer.
RTS ; Return
IncreaseHop:
INC $1504,x ; Increase timer.
RETURN4 RTS
;-----------------------------------------------------------------------------------------
; state 3
;-----------------------------------------------------------------------------------------
THROWING LDA #$00
STA SPRITE_Y_SPEED,x ;set initial speed
JSL $01801A ;apply speed
LDA SPRITE_Y_SPEED,x ;increase speed if below the max
CMP #MAX_Y_SPEED
BCS DONT_INC_SPEED
ADC #SPRITE_GRAVITY2
STA SPRITE_Y_SPEED,x
DONT_INC_SPEED
JSL $019138 ;interact with objects
LDA $1564,x ; return if sprite is invulnerable
CMP #$00
BNE RETURN67
JSR SUB_HAMMER_THROW
LDA #$F0 ; set the time of flight to F0
STA STATE_TIMER,x
LDA #$01
STA SPRITE_STATE,x
STZ SMASH_STATUS,x
RETURN67 RTS
;-----------------------------------------------------------------------------------------
; state 4
;-----------------------------------------------------------------------------------------
HURT LDA $1588,x ; \ if sprite is in contact with an object...
AND #$03 ; |
BEQ NO_OBJ_CONTACT1 ; |
LDA $157C,x ; | flip the direction status
EOR #$01 ; |
STA $157C,x ; /
NO_OBJ_CONTACT1
LDY $157C,x ; \ set x speed based on direction
LDA HURT_SPEED,y ; |
STA $B6,x
LDA $1564,x ; return if sprite is invulnerable
CMP #$00
BNE RETURN68
LDA $1528,x
CMP #$02
BCC ATTACK1
LDA #$02
STA SPRITE_STATE,x
BRA RETURN68
ATTACK1
LDA #$01
STA SPRITE_STATE,x
RETURN68 JSL $01802A ;apply speed
RTS
;-----------------------------------------------------------------------------------------
; state 5
;-----------------------------------------------------------------------------------------
STUNNED LDA $1588,x ; \ if sprite is in contact with an object...
AND #$03 ; |
BEQ NO_OBJ_CONTACT3 ; |
LDA $157C,x ; | flip the direction status
EOR #$01 ; |
STA $157C,x ; /
NO_OBJ_CONTACT3
STZ $B6,x
Hop3:
LDA #$C0 ; If timer isn't C0..
CMP $1534,x ;
BNE IncreaseHop3 ; Increase it.
STZ $1534,x ; Reset timer.
LDA #$01
STA SPRITE_STATE,x
RTS ; Return
IncreaseHop3:
INC $1534,x ; Increase timer.
RETURN65 JSL $01802A ;apply speed
RTS
;-----------------------------------------------------------------------------------------
; state 6
;-----------------------------------------------------------------------------------------
DEAD LDA FREEZE_TIMER,x
BNE RETURN10
STZ SPRITE_X_SPEED,x
LDA $0F30
BNE RETURN10
LDA $0F33
AND $01
BNE RETURN10
INC SMASH_STATUS,X
LDA SMASH_STATUS,x
CMP #$02
BNE RETURN10
INC SPRITE_STATE,x ;chage state to falling
RETURN10 RTS
;-----------------------------------------------------------------------------------------
; state 7
;-----------------------------------------------------------------------------------------
EXITING
LDA V_OFFSCREEN,x ;fall if offscreen vertically
BNE GOAL
LDA H_OFFSCREEN,x ;return if offscreen horizontally
BNE RETURN1
JSL $01801A ;apply speed
LDA SPRITE_Y_SPEED,x ;increase speed if below the max
CMP #MAX_Y_SPEED2
BMI DONT_INC_SPEED2
SEC
SBC #SPRITE_GRAVITY2
STA SPRITE_Y_SPEED,x
DONT_INC_SPEED2
JSL $019138 ;interact with objects
LDA SPR_OBJ_STATUS,x ;return if not on the ceiling
AND #IS_ON_CEILING
BEQ RETURN1
JSR SUB_9A04 ; ?? speed related
LDA #TIME_TO_SHAKE ;shake ground
STA $1887
LDA #TIME_ON_GROUND ;set time to stay on ground
STA FREEZE_TIMER,x
RETURN1 RTS
GOAL STZ $14C8,x
DEC $13C6 ; prevent Mario from walking at the level end
LDA #$FF ; \ set goal
STA $1493 ; /
LDA #$0B ; \ set ending music
STA $1DFB ; /
RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; hammer routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
X_OFFSET dcb $F9,$07
X_OFFSET2 dcb $FF,$00
X_THROW_SPEED dcb $18,$E8
RETURN21 RTS
SUB_HAMMER_THROW LDA $15A0,x ; \ no egg if off screen
ORA $186C,x ; |
ORA $15D0,x
BNE RETURN21
JSL $02A9DE ; \ get an index to an unused sprite slot, return if all slots full
BMI RETURN21 ; / after: Y has index of sprite being generated
LDA #$0A ; \ set sprite status for new sprite
STA $14C8,y ; /
LDA #$04
STA $9E,y
PHY ; set x position for new sprite
LDA $157C,x
TAY
LDA $E4,x
CLC
ADC X_OFFSET,y
PLY
STA $00E4,y
PHY ; set x position for new sprite
LDA $157C,x
TAY
LDA $14E0,x
ADC X_OFFSET2,y
PLY
STA $14E0,y
LDA $D8,x ; \ set y position for new sprite
SEC ; | (y position of generator - 1)
SBC #$0E ; |
STA $00D8,y ; |
LDA $14D4,x ; |
SBC #$00 ; |
STA $14D4,y ; /
PHX ; \ before: X must have index of sprite being generated
TYX ; | routine clears *all* old sprite values...
JSL $07F7D2 ; | ...and loads in new values for the 6 main sprite tables
PLX ; /
PHY
LDA $157C,x
TAY
LDA X_THROW_SPEED,y
PLY
STA $B6,y
LDA #$C0
STA $AA,y
RETURN20 RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; hammer routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
X_OFFSET3 dcb $F9,$07
X_OFFSET4 dcb $FF,$00
X_THROW_SPEED2 dcb $30,$D0
RETURN58 RTS
SUB_HAMMER_THROW2
LDA $15A0,x ; \ no egg if off screen
ORA $186C,x ; |
ORA $15D0,x
BNE RETURN58
JSL $02A9DE ; \ get an index to an unused sprite slot, return if all slots full
BMI RETURN58 ; / after: Y has index of sprite being generated
LDA #$0A ; \ set sprite status for new sprite
STA $14C8,y ; /
LDA #$04
STA $9E,y
PHY ; set x position for new sprite
LDA $157C,x
TAY
LDA $E4,x
CLC
ADC X_OFFSET3,y
PLY
STA $00E4,y
PHY ; set x position for new sprite
LDA $157C,x
TAY
LDA $14E0,x
ADC X_OFFSET4,y
PLY
STA $14E0,y
LDA $D8,x ; \ set y position for new sprite
SEC ; | (y position of generator - 1)
SBC #$0E ; |
STA $00D8,y ; |
LDA $14D4,x ; |
SBC #$00 ; |
STA $14D4,y ; /
PHX ; \ before: X must have index of sprite being generated
TYX ; | routine clears *all* old sprite values...
JSL $07F7D2 ; | ...and loads in new values for the 6 main sprite tables
PLX ; /
PHY
LDA $157C,x
TAY
LDA X_THROW_SPEED2,y
PLY
STA $B6,y
LDA #$C0
STA $AA,y
LDA #TIME_TO_EXPLODE
STA $1540,y
RETURN57 RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Be killed by shells
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HIT_ROUTINE:
HITPOINTS:
;TXA ; \ Process every 4 frames
;EOR $13 ; |
;AND #$03 ; |
;BNE RETURN_BOB ; /
LDY #$09 ; \ Loop over sprites:
KILLED_X_SPEED:
dcb $FF,$00
SpriteInteract:
ldy #$0b
InteractLoop:
lda $14c8,y
cmp #$09
bcs ProcessSprite
NextSprite:
dey
bpl InteractLoop
rts
ProcessSprite:
PHX
TYX
JSL GetSpriteClippingB
PLX
JSL GetSpriteClippingA
JSL CheckForContact
bcc NextSprite
PHX
TYX
JSL ShowSprContactGfx
LDA #$02 ; \ Kill thrown sprite
STA $14C8,x ; /
LDA #$D0 ; \ Set killed Y speed
STA $AA,x ; /
LDY #$00 ; Set killed X speed
LDA $B6,x
BPL SET_SPEED
INY
SET_SPEED
LDA KILLED_X_SPEED,y
STA $B6,x
PLX
HandleBirdoHit:
LDA #$13 ; \ sound effect
STA $1DF9 ; /
LDA SPRITE_STATE,x ; If jumping up
CMP #$03
BCS Return3
SHELL_CONTACT
LDA #$05
STA SPRITE_STATE,x
Return3:
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PROPERTIES: dcb $7F,$3F
;The tables must now have 16 bytes.
;THE LAST 8 ARE ONLY CREATED BECAUSE OF XDISP.
;0-4 BYTE - FRAME 1 RIGHT
;4-8 BYTE - FRAME 2 RIGHT
;8-12 BYTE - FRAME 1 LEFT
;12-16 BYTE - FRAME 2 LEFT
TILEMAP:
dcb $00,$02,$20,$22 ; WALKING 1 ;\ RIGHT
dcb $04,$06,$24,$26 ; WALKING 2 ;/ RIGHT
dcb $00,$02,$20,$22 ; WAITING 1 ;\ RIGHT
dcb $84,$86,$A4,$A6 ; WAITING 2 ;/ RIGHT
dcb $40,$42,$60,$62 ; RETREAT 1 ;\ RIGHT
dcb $44,$46,$64,$66 ; RETREAT 2 ;/ RIGHT
dcb $08,$0A,$28,$2A ; THROW 1 ;\ RIGHT
dcb $0C,$0E,$2C,$2E ; THROW 2 ;/ RIGHT
dcb $80,$82,$A0,$A2 ; LEAPING 1 ;\ RIGHT
dcb $80,$82,$A0,$A2 ; LEAPING 2 ;/ RIGHT
dcb $8C,$8E,$AC,$AE ; STUNNED 1 ;\ RIGHT
dcb $C0,$C2,$E0,$E2 ; STUNNED 2 ;/ RIGHT
dcb $48,$4A,$68,$6A ; DYING 1 ;\ RIGHT
dcb $48,$4A,$68,$6A ; DYING 2 ;/ RIGHT
dcb $00,$02,$20,$22 ; WALKING 1 ;\ LEFT
dcb $04,$06,$24,$26 ; WALKING 2 ;/ LEFT
dcb $00,$02,$20,$22 ; WAITING 1 ;\ LEFT
dcb $84,$86,$A4,$A6 ; WAITING 2 ;/ LEFT
dcb $40,$42,$60,$62 ; RETREAT 1 ;\ LEFT
dcb $44,$46,$64,$66 ; RETREAT 2 ;/ LEFT
dcb $08,$0A,$28,$2A ; THROW 1 ;\ LEFT
dcb $0C,$0E,$2C,$2E ; THROW 2 ;/ LEFT
dcb $80,$82,$A0,$A2 ; LEAPING 1 ;\ LEFT
dcb $80,$82,$A0,$A2 ; LEAPING 2 ;/ LEFT
dcb $8C,$8E,$AC,$AE ; STUNNED 1 ;\ LEFT
dcb $C0,$C2,$E0,$E2 ; STUNNED 2 ;/ LEFT
dcb $48,$4A,$68,$6A ; DYING 1 ;\ LEFT
dcb $48,$4A,$68,$6A ; DYING 2 ;/ LEFT
YDISP:
dcb $F0,$F0,$00,$00 ; WALKING 1 ;\ RIGHT
dcb $F0,$F0,$00,$00 ; WALKING 2 ;/ RIGHT
dcb $F0,$F0,$00,$00 ; WAITING 1 ;\ RIGHT
dcb $F0,$F0,$00,$00 ; WAITING 2 ;/ RIGHT
dcb $F0,$F0,$00,$00 ; RETREAT 1 ;\ RIGHT
dcb $F0,$F0,$00,$00 ; RETREAT 2 ;/ RIGHT
dcb $F0,$F0,$00,$00 ; THROW 1 ;\ RIGHT
dcb $F0,$F0,$00,$00 ; THROW 2 ;/ RIGHT
dcb $F0,$F0,$00,$00 ; LEAPING 1 ;\ RIGHT
dcb $F0,$F0,$00,$00 ; LEAPING 2 ;/ RIGHT
dcb $F0,$F0,$00,$00 ; STUNNED 1 ;\ RIGHT
dcb $F0,$F0,$00,$00 ; STUNNED 2 ;/ RIGHT
dcb $F0,$F0,$00,$00 ; DYING 1 ;\ RIGHT
dcb $F0,$F0,$00,$00 ; DYING 2 ;/ RIGHT
dcb $F0,$F0,$00,$00 ; WALKING 1 ;\ LEFT
dcb $F0,$F0,$00,$00 ; WALKING 2 ;/ LEFT
dcb $F0,$F0,$00,$00 ; WAITING 1 ;\ LEFT
dcb $F0,$F0,$00,$00 ; WAITING 2 ;/ LEFT
dcb $F0,$F0,$00,$00 ; RETREAT 1 ;\ LEFT
dcb $F0,$F0,$00,$00 ; RETREAT 2 ;/ LEFT
dcb $F0,$F0,$00,$00 ; THROW 1 ;\ LEFT
dcb $F0,$F0,$00,$00 ; THROW 2 ;/ LEFT
dcb $F0,$F0,$00,$00 ; LEAPING 1 ;\ LEFT
dcb $F0,$F0,$00,$00 ; LEAPING 2 ;/ LEFT
dcb $F0,$F0,$00,$00 ; STUNNED 1 ;\ LEFT
dcb $F0,$F0,$00,$00 ; STUNNED 2 ;/ LEFT
dcb $F0,$F0,$00,$00 ; DYING 1 ;\ LEFT
dcb $F0,$F0,$00,$00 ; DYING 2 ;/ LEFT
XDISP:
dcb $00,$10,$00,$10 ; WALKING 1 ;\ RIGHT
dcb $00,$10,$00,$10 ; WALKING 2 ;/ RIGHT
dcb $00,$10,$00,$10 ; WALKING 1 ;\ RIGHT
dcb $00,$10,$00,$10 ; WALKING 2 ;/ RIGHT
dcb $00,$10,$00,$10 ; RETREAT 1 ;\ RIGHT
dcb $00,$10,$00,$10 ; RETREAT 2 ;/ RIGHT
dcb $00,$10,$00,$10 ; THROW 1 ;\ RIGHT
dcb $00,$10,$00,$10 ; THROW 2 ;/ RIGHT
dcb $00,$10,$00,$10 ; LEAPING 1 ;\ RIGHT
dcb $00,$10,$00,$10 ; LEAPING 2 ;/ RIGHT
dcb $00,$10,$00,$10 ; STUNNED 1 ;\ RIGHT
dcb $00,$10,$00,$10 ; STUNNED 2 ;/ RIGHT
dcb $00,$10,$00,$10 ; DYING 1 ;\ RIGHT
dcb $00,$10,$00,$10 ; DYING 2 ;/ RIGHT
dcb $10,$00,$10,$00 ; WALKING 1 ;\ LEFT
dcb $10,$00,$10,$00 ; WALKING 2 ;/ LEFT
dcb $10,$00,$10,$00 ; WALKING 1 ;\ LEFT
dcb $10,$00,$10,$00 ; WALKING 2 ;/ LEFT
dcb $10,$00,$10,$00 ; RETREAT 1 ;\ LEFT
dcb $10,$00,$10,$00 ; RETREAT 2 ;/ LEFT
dcb $10,$00,$10,$00 ; THROW 1 ;\ LEFT
dcb $10,$00,$10,$00 ; THROW 2 ;/ LEFT
dcb $10,$00,$10,$00 ; LEAPING 1 ;\ LEFT
dcb $10,$00,$10,$00 ; LEAPING 2 ;/ LEFT
dcb $10,$00,$10,$00 ; STUNNED 1 ;\ LEFT
dcb $10,$00,$10,$00 ; STUNNED 2 ;/ LEFT
dcb $10,$00,$10,$00 ; DYING 1 ;\ LEFT
dcb $10,$00,$10,$00 ; DYING 2 ;/ LEFT
SUB_GFX:
JSR GET_DRAW_INFO
LDA $1602,x
STA $03 ; | $03 = index to frame start (0 or 4)
LDA $14 ;\ Frame counter ..
LSR A ; |
LSR A ; | Add in frame animation rate; More LSRs for slower animation.
LSR A ; |
AND #$01 ; | 01 means we animate between 2 frames (00 and 01).
ASL A ; |
ASL A ; | ASL x2 (0-4) makes it switch between the first byte and fifth byte,
STA $03 ;/ i.e. first animation and second animation. The result is stored into $03.
LDA SPRITE_STATE,x ; If jumping up
CMP #$06
BNE NOT_DEAD
LDA $03
CLC
ADC #$30 ; ...set killed frame
STA $03
LDA $15F6,x ; \
ORA #$80 ; | ...flip vertically
STA $15F6,x ; /
BRA DONE_WALKING
NOT_DEAD:
LDA SPRITE_STATE,x ; if retreating into shell
CMP #$04
BNE KNOCKED_BACK ; |
LDA $03 ; |
CLC ; |
ADC #$10 ; | ...use stun frames.
STA $03 ; /
BRA DONE_WALKING
KNOCKED_BACK:
LDA SPRITE_STATE,x ; if retreating into shell
CMP #$05
BNE YELLING ; |
LDA $03 ; |
CLC ; |
ADC #$28 ; | ...use stun frames.
STA $03 ; /
BRA DONE_WALKING
YELLING:
LDA SPRITE_STATE,x ; if yelling at Mario
CMP #$00
BNE JUMPING ; |
LDA $03 ; |
CLC ; |
ADC #$08 ; | ...use stun frames.
STA $03 ; /
BRA DONE_WALKING
JUMPING:
LDA SPRITE_STATE,x ; if exiting the level
CMP #$07
BNE IN_THE_AIR ; |
LDA $03 ; |
CLC ; |
ADC #$20 ; | ...use stun frames.
STA $03 ; /
BRA DONE_WALKING
IN_THE_AIR:
LDA SPR_OBJ_STATUS,x ;return if on the ground
CMP #$04 ; |
BEQ THROWING_SHELL ; |
LDA $03 ; |
CLC ; |
ADC #$20 ; | ...use stun frames.
STA $03 ; /
BRA DONE_WALKING
THROWING_SHELL:
LDA SPRITE_STATE,x ; If throwing shell
CMP #$03
BNE DONE_WALKING ; |
LDA $03 ; |
CLC ; |
ADC #$18 ; | ...use stun frames.
STA $03 ; /
; BRA DONE_WALKING
DONE_WALKING:
LDA $157C,x
STA $02 ; Store direction to $02 for use with property routine later.
BNE NoAdd
LDA $03 ;\
CLC ; | If sprite faces left ..
ADC #$38 ; | Adding 16 more bytes to the table.
STA $03 ;/ So we can invert XDISP to not mess up the sprite's appearance.
NoAdd:
PHX ;\ Push sprite index ..
LDX #$03 ;/ And load X with number of tiles to loop through.
Loop:
PHX ; Push number of tiles to loop through.
TXA ;\
ORA $03 ;/ Transfer it to X and add in the "left displacement" if necessary.
TAX ;\ Get it back into X for an index.
LDA $00 ;\
CLC ; | Apply X displacement of the sprite.
ADC XDISP,x ; |
STA $0300,y ;/
LDA $01 ;\
CLC ; | Y displacement is added for the Y position, so one tile is higher than the other.
ADC YDISP,x ; | Otherwise, both tiles would have been drawn to the same position!
STA $0301,y ; | If X is 00, i.e. first tile, then load the first value from the table and apply that
;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
LDA TILEMAP,x
STA $0302,y
PHX ; Push number of times to go through loop + "left" displacement if necessary.
LDX $02 ;\
LDA PROPERTIES,x ; | Set properties based on direction.
STA $0303,y ;/
PLX ; Pull number of times to go through loop.
INY ;\
INY ; | The OAM is 8x8, but our sprite is 16x16 ..
INY ; | So increment it 4 times.
INY ;/
PLX ; Pull current tile back.
DEX ; After drawing this tile, decrease number of tiles to go through loop. If the second tile
; is drawn, then loop again to draw the first tile.
BPL Loop ; Loop until X becomes negative (FF).
PLX ; Pull back the sprite index! We pushed it at the beginning of the routine.
LDY #$02 ; Y ends with the tile size .. 02 means it's 16x16
LDA #$03 ; A -> number of tiles drawn - 1.
; I drew 2 tiles, so 2-1 = 1. A = 01.
JSL $01B7B3 ; Call the routine that draws the sprite.
RTS ; Never forget this!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_CHANGE_DIR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $019098
SUB_CHANGE_DIR ;LDA $15AC,x
;BNE LABEL41
;LDA #$08
;STA $15AC,x
LDA $B6,x
EOR #$FF
INC A
STA $B6,x
LDA $157C,x
EOR #$01
STA $157C,x
LABEL41 RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; speed related
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SUB_9A04 LDA SPR_OBJ_STATUS,x
BMI THWOMP_1
LDA #$00
LDY $15B8,x
BEQ THWOMP_2
THWOMP_1 LDA #$18
THWOMP_2 STA SPRITE_Y_SPEED,x
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; routines below can be shared by all sprites. they are ripped from original
; SMW and poorly documented
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; points routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STAR_SOUNDS dcb $00,$13,$14,$15,$16,$17,$18,$19
SUB_STOMP_PTS PHY ;
LDA $1697 ; \
CLC ; |
ADC $1626,x ; / some enemies give higher pts/1ups quicker??
INC $1697 ; increase consecutive enemies stomped
TAY ;
INY ;
CPY #$08 ; \ if consecutive enemies stomped >= 8 ...
BCS NO_SOUND ; / ... don't play sound
LDA STAR_SOUNDS,y ; \ play sound effect
STA $1DF9 ; /
NO_SOUND TYA ; \
CMP #$08 ; | if consecutive enemies stomped >= 8, reset to 8
BCC NO_RESET ; |
LDA #$08 ; /
NO_RESET JSL $02ACE5 ; give mario points
PLY ;
RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B760 - graphics routine helper - shared
; sets off screen flags and sets index to OAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B75C
TABLE1 dcb $0C,$1C
TABLE2 dcb $01,$02
GET_DRAW_INFO 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 ON_SCREEN_X ; |
INC $15A0,x ; /
ON_SCREEN_X LDA $14E0,x ; \
XBA ; |
LDA $E4,x ; |
REP #$20 ; |
SEC ; |
SBC $1A ; | mark sprite invalid if far enough off screen
CLC ; |
ADC.W #$0040 ; |
CMP.W #$0180 ; |
SEP #$20 ; |
ROL A ; |
AND #$01 ; |
STA $15C4,x ; /
BNE INVALID ;
LDY #$00 ; \ set up loop:
LDA $1662,x ; |
AND #$20 ; | if not smushed (1662 & 0x20), go through loop twice
BEQ ON_SCREEN_LOOP ; | else, go through loop once
INY ; /
ON_SCREEN_LOOP LDA $D8,x ; \
CLC ; | set vertical offscreen if necessary
ADC TABLE1,y ; |
PHP ; |
CMP $1C ; | (vert screen boundry)
ROL $00 ; |
PLP ; |
LDA $14D4,x ; |
ADC #$00 ; |
LSR $00 ; |
SBC $1D ; |
BEQ ON_SCREEN_Y ; |
LDA $186C,x ; | (vert offscreen)
ORA TABLE2,y ; |
STA $186C,x ; |
ON_SCREEN_Y DEY ; |
BPL ON_SCREEN_LOOP ; /
LDY $15EA,x ; get offset to sprite OAM
LDA $E4,x ; \
SEC ; |
SBC $1A ; | $00 = sprite x position relative to screen boarder
STA $00 ; /
LDA $D8,x ; \
SEC ; |
SBC $1C ; | $01 = sprite y position relative to screen boarder
STA $01 ; /
RTS ; return
INVALID PLA ; \ return from *main gfx routine* subroutine...
PLA ; | ...(not just this subroutine)
RTS ; /
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B829 - vertical mario/sprite position check - shared
; Y = 1 if mario below sprite??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B829
SUB_VERT_POS LDY #$00 ;A:25A1 X:0007 Y:0001 D:0000 DB:03 S:01EA P:envMXdizCHC:0130 VC:085 00 FL:924
LDA $96 ;A:25A1 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdiZCHC:0146 VC:085 00 FL:924
SEC ;A:2546 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizCHC:0170 VC:085 00 FL:924
SBC $D8,x ;A:2546 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizCHC:0184 VC:085 00 FL:924
STA $0F ;A:25D6 X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0214 VC:085 00 FL:924
LDA $97 ;A:25D6 X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0238 VC:085 00 FL:924
SBC $14D4,x ;A:2501 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizcHC:0262 VC:085 00 FL:924
BPL LABEL11 ;A:25FF X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0294 VC:085 00 FL:924
INY ;A:25FF X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0310 VC:085 00 FL:924
LABEL11 RTS ;A:25FF X:0007 Y:0001 D:0000 DB:03 S:01EA P:envMXdizcHC:0324 VC:085 00 FL:924
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B817 - horizontal mario/sprite check - shared
; Y = 1 if mario left of sprite??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B817
SUB_HORZ_POS LDY #$00 ;A:25D0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1020 VC:097 00 FL:31642
LDA $94 ;A:25D0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZCHC:1036 VC:097 00 FL:31642
SEC ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1060 VC:097 00 FL:31642
SBC $E4,x ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1074 VC:097 00 FL:31642
STA $0F ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1104 VC:097 00 FL:31642
LDA $95 ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1128 VC:097 00 FL:31642
SBC $14E0,x ;A:2500 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZcHC:1152 VC:097 00 FL:31642
BPL LABEL16 ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1184 VC:097 00 FL:31642
INY ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1200 VC:097 00 FL:31642
LABEL16 RTS ;A:25FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:1214 VC:097 00 FL:31642
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B85D - off screen processing code - shared
; sprites enter at different points
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B83B
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
SUB_OFF_SCREEN_X0 LDA #$06 ; \ entry point of routine determines value of $03
BRA STORE_03 ; |
SUB_OFF_SCREEN_X1 LDA #$04 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X2 LDA #$02 ; |
STORE_03 STA $03 ; |
BRA START_SUB ; |
SUB_OFF_SCREEN_X3 STZ $03 ; /
START_SUB 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 ; |
ORA $03 ; |
STA $01 ; |
TAY ; /
LDA $1A ;x boundry ;A:0101 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0256 VC:090 00 FL:16953
CLC ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0280 VC:090 00 FL:16953
ADC TABLE4,y ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0294 VC:090 00 FL:16953
ROL $00 ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0326 VC:090 00 FL:16953
CMP $E4,x ;x pos ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0364 VC:090 00 FL:16953
PHP ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0394 VC:090 00 FL:16953
LDA $1B ;x boundry hi ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNvMXdizCHC:0416 VC:090 00 FL:16953
LSR $00 ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdiZCHC:0440 VC:090 00 FL:16953
ADC TABLE5,y ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdizcHC:0478 VC:090 00 FL:16953
PLP ;A:01FF X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0510 VC:090 00 FL:16953
SBC $14E0,x ;x pos high ;A:01FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0538 VC:090 00 FL:16953
STA $00 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0570 VC:090 00 FL:16953
LSR $01 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0594 VC:090 00 FL:16953
BCC LABEL20 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0632 VC:090 00 FL:16953
EOR #$80 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0648 VC:090 00 FL:16953
STA $00 ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0664 VC:090 00 FL:16953
LABEL20 LDA $00 ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0688 VC:090 00 FL:16953
BPL RETURN_2 ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0712 VC:090 00 FL:16953
ERASE_SPRITE LDA $14C8,x ; \ if sprite status < 8, permanently erase sprite
CMP #$08 ; |
BCC KILL_SPRITE ; /
LDY $161A,x ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0140 VC:071 00 FL:21152
CPY #$FF ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0172 VC:071 00 FL:21152
BEQ KILL_SPRITE ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0188 VC:071 00 FL:21152
LDA #$00 ; \ mark sprite to come back A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0204 VC:071 00 FL:21152
STA $1938,y ; / A:FF00 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0220 VC:071 00 FL:21152
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 ;A:0227 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0228 VC:112 00 FL:1142
STA $01 ;A:0201 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0244 VC:112 00 FL:1142
TAY ;A:0201 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0268 VC:112 00 FL:1142
LDA $1C ;A:0201 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0282 VC:112 00 FL:1142
CLC ;A:02BD X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0306 VC:112 00 FL:1142
ADC TABLE3,y ;A:02BD X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0320 VC:112 00 FL:1142
ROL $00 ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:enVMXdizCHC:0352 VC:112 00 FL:1142
CMP $D8,x ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:enVMXdizCHC:0390 VC:112 00 FL:1142
PHP ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNVMXdizcHC:0420 VC:112 00 FL:1142
LDA.W $001D ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNVMXdizcHC:0442 VC:112 00 FL:1142
LSR $00 ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:enVMXdiZcHC:0474 VC:112 00 FL:1142
ADC TABLE6,y ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:enVMXdizCHC:0512 VC:112 00 FL:1142
PLP ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdiZCHC:0544 VC:112 00 FL:1142
SBC $14D4,x ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNVMXdizcHC:0572 VC:112 00 FL:1142
STA $00 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0604 VC:112 00 FL:1142
LDY $01 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0628 VC:112 00 FL:1142
BEQ LABEL22 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0652 VC:112 00 FL:1142
EOR #$80 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0668 VC:112 00 FL:1142
STA $00 ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0684 VC:112 00 FL:1142
LABEL22 LDA $00 ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0708 VC:112 00 FL:1142
BPL RETURN_2 ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0732 VC:112 00 FL:1142
BMI ERASE_SPRITE ;A:0280 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0170 VC:064 00 FL:1195
SUB_IS_OFF_SCREEN LDA $15A0,x ; \ if sprite is on screen, accumulator = 0
ORA $186C,x ; |
RTS ; / return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Normal Sprite Generator, based on mikeyk's code, further changed by Davros.
;;
;; Description: This sprite will generate a sprite when all the enemies on screen are
;; killed.
;;
;; Uses first extra bit: YES
;; When the first extra bit is clear, the sprite will turn into a sprite. When the first
;; extra bit is set, it will turn into another sprite.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NORM_SPRITE = $3E ; P-Switch
NORM_SPRITE2 = $3E ; P-Switch
EXTRA_BITS = $7FAB10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "INIT"
RTL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite code JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "MAIN"
LDA $1493 ; \ if the goal is set...
BNE RETURN ; /
LDY #$0B ; \ load number of times to go through loop
LOOP_START CPY $00 ; |
BEQ DONT_CHECK ; /
LDA $190F,y ; \ if the tweaker bits are set...
AND #$40 ; |
BNE DONT_CHECK ; /
LDA $14C8,y ; \ if no sprite is left alive...
BNE RETURN ; /
DONT_CHECK DEY ;
BPL LOOP_START ;
LDA EXTRA_BITS,x ; \ set other sprite if the extra bit is set...
AND #$04 ; |
BNE SET_NORM_GEN ; /
JSR NORMAL_GEN ; generate normal sprite routine
BRA RETURN
SET_NORM_GEN JSR NORMAL_GEN2 ; generate normal sprite routine
RETURN RTL ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; generate normal sprite routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NORMAL_GEN LDA #$08 ; \ set sprite status for new sprite
STA $14C8,x ; /
LDA #NORM_SPRITE ; \ set sprite number for new sprite
STA $9E,x ; /
JSL $07F7D2 ; reset sprite tables
JSR SUB_SMOKE ; smoke routine
JSR SUB_HORZ_POS ; \ always face Mario
TYA ; |
STA $157C,x ; /
LDA #$10 ; \ sound effect
STA $1DF9 ; /
RETURN67 RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; generate normal sprite routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NORMAL_GEN2 LDA #$08 ; \ set sprite status for new sprite
STA $14C8,x ; /
LDA #NORM_SPRITE2 ; \ set sprite number for new sprite
STA $9E,x ; /
JSL $07F7D2 ; reset sprite tables
JSR SUB_SMOKE ; smoke routine
JSR SUB_HORZ_POS ; \ always face Mario
TYA ; |
STA $157C,x ; /
LDA #$10 ; \ sound effect
STA $1DF9 ; /
RETURN69 RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; display smoke effect
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SUB_SMOKE LDY #$03 ; \ find a free slot to display effect
FINDFREE LDA $17C0,y ; |
BEQ FOUNDONE ; |
DEY ; |
BPL FINDFREE ; |
RTS ; / return if no slots open
FOUNDONE LDA #$01 ; \ set effect graphic to smoke graphic
STA $17C0,y ; /
LDA #$1B ; \ set time to show smoke
STA $17CC,y ; /
LDA $D8,x ; \ smoke y position = generator y position
STA $17C4,y ; /
LDA $E4,x ; \ load generator x position and store it for later
STA $17C8,y ; /
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B817 - horizontal mario/sprite check - shared
; Y = 1 if mario left of sprite??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B817
SUB_HORZ_POS LDY #$00 ;A:25D0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1020 VC:097 00 FL:31642
LDA $94 ;A:25D0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZCHC:1036 VC:097 00 FL:31642
SEC ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1060 VC:097 00 FL:31642
SBC $E4,x ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1074 VC:097 00 FL:31642
STA $0F ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1104 VC:097 00 FL:31642
LDA $95 ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1128 VC:097 00 FL:31642
SBC $14E0,x ;A:2500 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZcHC:1152 VC:097 00 FL:31642
BPL LABEL16 ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1184 VC:097 00 FL:31642
INY ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1200 VC:097 00 FL:31642
LABEL16 RTS ;A:25FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:1214 VC:097 00 FL:31642
db $42 : JMP M : JMP M : JMP M : JMP R : JMP R : JMP R: JMP R : JMP M : JMP M : JMP M
M:
LDA #$02
STA $9C
JSL $00BEB0
R:
RTL