Allgemeine Hex- und ASM-Fragen

geschrieben am 30.12.2010 19:50:20
( Link )
Zitat von WYE:
Doch, das tut man. (Sollte man zumindest, wenn man nicht gerade Bonussterne bekommt.)

...Davor war ich mir sicher das man keins bekommt...egal ^^ Trotzdem interessant ^^
geschrieben am 09.01.2011 23:07:30
( Link )
Wie muss ich den Code dieser Sprite ändern, damit iese Sprite mehr hitpoints hat?
Spoiler anzeigen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Homing Thwomp, by yoshicookiezeus and edited by dahnamics
;;
;; Description: A thwomp that follows Mario horizontally when on the ceiling, and spawns
;; Spinies, Green Koopas and Hopping Flames randomly when it hits the ground.
;; It has three hit points, and shell like items hurt it. It gets faster with
;; each hit and explodes like a Bob-Omb when killed. It also ends the level.
;;
;; NOTE: ONLY use this sprite in one-screen areas with "No vertical or horizontal scroll"
;; enabled!
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Homing Thwomp, by yoshicookiezeus
;;
;; Description: A thwomp that follows Mario horizontally when on the ceiling, and spawns
;; Bob-Ombs when it hits the ground. It has three hit points, and only gets
;; hurt by Bob-Omb explosions. It gets faster with each hit.
::
;; NOTE: ONLY use this sprite in one-screen areas with "No vertical or horizontal scroll"
;; enabled!
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; symbolic names for RAM addresses (don't change these)
GetSpriteClippingA = $03B69F
GetSpriteClippingB = $03B6E5
CheckForContact = $03B72B
ShowSprContactGfx = $01AB72
SPRITE_Y_SPEED = $AA
SPRITE_X_SPEED = $B6
SPRITE_STATE = $C2
SPRITE_X_POS = $E4
SPRITE_Y_POS = $D8
ORIG_Y_POS = $151C
EXPRESSION = $1594
FREEZE_TIMER = $1540
SPR_OBJ_STATUS = $1588
H_OFFSCREEN = $15A0
V_OFFSCREEN = $186C

; definitions of bits (don't change these)
IS_ON_GROUND = $04

; sprite data
SPRITE_GRAVITY = $04
MAX_Y_SPEED = $3E
RISE_SPEED dcb $F0,$E0,$D0
TIME_TO_SHAKE = $18
SOUND_EFFECT = $09
TIME_ON_GROUND dcb $30,$20,$10
ANGRY_TILE = $4A

X_SPEED_LEFT dcb $10,$20,$30
X_SPEED_RIGHT dcb $EF,$DF,$CF

X_OFFSET dcb $FC,$04,$FC,$04,$00
Y_OFFSET dcb $00,$00,$10,$10,$08
TILE_MAP dcb $0E,$0E,$2E,$2E,$48
PROPERTIES dcb $03,$43,$03,$43,$03

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "INIT"
LDA SPRITE_Y_POS,x
STA ORIG_Y_POS,x
LDA $E4,x
CLC
ADC #$08
STA $E4,x
RTL


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite code JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "MAIN"
PHB
PHK
PLB
JSR SPRITE_CODE_START
PLB
RTL


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite main code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

RETURN RTS

SPRITE_CODE_START JSR SUB_GFX

LDA $14C8,x ; return if sprite status != 8

ALIVE CMP #$08 ; \ if status != 8, return
BNE RETURN ; /

LDA $9D ; return if sprites locked
BNE RETURN

LDA $1564,x ; if invincibility timer isn't active,
BEQ JUMP ; go to hitpoints routine
DEC $1564,x ; else, decrease invincibility timer
BRA NO_JUMP

JUMP JSR HITPOINTS

NO_JUMP JSR SUB_OFF_SCREEN_X0 ; only process sprite while on screen

JSL $01A7DC ; interact with mario

LDA SPRITE_STATE,x
CMP #$01
BEQ FALLING
CMP #$02
BEQ RISING0

;-----------------------------------------------------------------------------------------
; state 0
;-----------------------------------------------------------------------------------------

HOVERING LDA V_OFFSCREEN,x ;fall if offscreen vertically
BNE SET_FALLING

LDA H_OFFSCREEN,x ;return if offscreen horizontally
BNE RETURN0

STZ SPRITE_Y_SPEED,x
JSR SUB_HORZ_POS ;determine if mario is close and act accordingly
TYA
STA $157C,x

LDY $1528,x ;check what side of sprite Mario is on
LDA $157C,x ;and set x speed accordingly
BEQ LEFT
LDA X_SPEED_RIGHT,y
STA SPRITE_X_SPEED,x
BRA CONTINUE

LEFT LDA X_SPEED_LEFT,y
STA SPRITE_X_SPEED,x

CONTINUE LDA SPRITE_X_POS,x
CLC
ADC #$08
SEC
SBC $94
CMP #$10
BCS RETURN0

SET_FALLING STZ SPRITE_X_SPEED,x
LDA #$02 ;set expression
STA EXPRESSION,x

INC SPRITE_STATE,x ;chage state to falling

LDA #$00
STA SPRITE_Y_SPEED,x ;set initial speed

RETURN0 JSL $01802A ;apply speed
RTS

RISING0 BRA RISING1

;-----------------------------------------------------------------------------------------
; state 1
;-----------------------------------------------------------------------------------------
SPRITE_TO_GEN dcb $30,$04,$B6,$B3

FALLING 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_GRAVITY
STA SPRITE_Y_SPEED,x
DONT_INC_SPEED
JSL $019138 ;interact with objects

LDA SPR_OBJ_STATUS,x ;return if not on the ground
AND #IS_ON_GROUND
BEQ RETURN68

JSR SUB_9A04 ; ?? speed related

LDA #TIME_TO_SHAKE ;shake ground
STA $1887

LDA #SOUND_EFFECT ;play sound effect
STA $1DFC

LDY $1528,x
LDA TIME_ON_GROUND,y ;set time to stay on ground
STA FREEZE_TIMER,x

INC SPRITE_STATE,x ;go to rising state

LDA $1528,x
CMP #$02
BNE SUB_BOMB_THROW
LDA $77
AND #$04
BEQ SUB_BOMB_THROW
LDA #TIME_TO_SHAKE
STA $18BD
BRA SUB_BOMB_THROW

RISING1 BRA RISING

RETURN68 RTS
SUB_BOMB_THROW LDA $15A0,x ; \ no bomb if off screen
ORA $186C,x ; |
ORA $15D0,x
BNE RETURN68

JSL $02A9DE ; \ get an index to an unused sprite slot, return if all slots full
BMI RETURN68 ; / after: Y has index of sprite being generated

LDA #$01 ; \ set sprite status for new sprite
STA $14C8,y ; /

PHX
LDA #$02
JSL RANDOM
TAX
LDA SPRITE_TO_GEN,x ; \ set sprite number for new sprite
PLX
STA $9E,y

LDA $E4,x ; \ set position of spawned sprite
STA $E4,y ; |
LDA $D8,x ; |
CLC ; |
ADC #$10 ; |
STA $D8,y ; |
LDA $14D4,x ; |
STA $14D4,y ; |
LDA $14E0,X ; |
STA $14E0,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 #$00
PLY
STA $B6,y

LDA #$00
STA $AA,y

RETURN67 RTS ; return

RANDOM PHX
PHP
SEP #$30
PHA
JSL $01ACF9 ; Random number generation routine
PLX
CPX #$FF ;\ Handle glitch if max is FF
BNE NORMALRT ;|
LDA $148B ;|
BRA ENDRANDOM ;/
NORMALRT INX ; Amount in plus 1
LDA $148B ;\
STA $4202 ;| Multiply with hardware regsisters
STX $4203 ;|
NOP ;|
NOP ;|
NOP ;|
NOP ;/
LDA $4217
ENDRANDOM PLP
PLX
RTL
;-----------------------------------------------------------------------------------------
; state 2
;-----------------------------------------------------------------------------------------

RISING LDA FREEZE_TIMER,x ;if we're still waiting on the ground, return
BNE RETURN2

STZ EXPRESSION,x ;reset expression

JSL $019138 ;interact with objects
LDA SPR_OBJ_STATUS,x ;check if the sprite is in original position
AND #$08
BEQ RISE

STZ SPRITE_STATE,x ;reset state to hovering
RTS

RISE LDY $1528,x
LDA RISE_SPEED,y ;set rising speed and apply it
STA SPRITE_Y_SPEED,x
JSL $01801A
RETURN2 RTS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SUB_GFX JSR GET_DRAW_INFO

LDA EXPRESSION,x
STA $02
PHX
LDX #$03
CMP #$00
BEQ LOOP_START
INX
LOOP_START LDA $00
CLC
ADC X_OFFSET,x
STA $0300,y

LDA $01
CLC
ADC Y_OFFSET,x
STA $0301,y

LDA PROPERTIES,x
ORA $64
STA $0303,y

LDA TILE_MAP,x
CPX #$04
BNE NORMAL_TILE
PHX
LDX $02
CPX #$02
BNE NOT_ANGRY
LDA #ANGRY_TILE
NOT_ANGRY PLX
NORMAL_TILE STA $0302,y

INY
INY
INY
INY
DEX
BPL LOOP_START

PLX

LDY #$02 ; \ 460 = 2 (all 16x16 tiles)
LDA #$04 ; | A = (number of tiles drawn - 1)
JSL $01B7B3 ; / don't draw if offscreen
RTS ; return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Be killed by shells
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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 $14C8,x
CMP #$0A
BEQ NoKill

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 SetSpeed
INY
SetSpeed:
LDA KILLED_X_SPEED,y
STA $B6,x
NoKill:
PLX
HandleBirdoHit:
LDA #$28 ; Play sound effect
STA $1DFC

LDA #$20 ; Set stunned timer
STA $1564,x

;JSL $019138 ;interact with objects

INC $1528,x

LDA $1528,x

cmp #$03
bcc Return3

LDA #$0D ; \ turn sprite
STA $9E,x ; / into bob-omb
JSL $07F7D2 ; reset sprite tables
LDA #$08 ; \ sprite status:
STA $14C8,x ; / normal
LDA #$01 ; \ make it
STA $1534,x ; / explode
LDA #$30 ; \ set time for
STA $1540,x ; / explosion
LDA #$09 ; \ play sound
STA $1DFC ; / effect

GOAL 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

LDA #$03
STA $1602,x ; / write frame to show
Return3:
rts


ProcessCachedHit:
LDA $1528,x

BPL Return3
AND #$7F
STA $1528,x

BRA HandleBirdoHit



;###############################################################################################
;###############################################################################################
;###############################################################################################
; ROUTINES FROM THE LIBRARY ARE PASTED BELOW
; You should never have to modify this code
;###############################################################################################
;###############################################################################################
;###############################################################################################


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_HORZ_POS
; This routine determines which side of the sprite Mario is on. It sets the Y register
; to the direction such that the sprite would face Mario
; It is ripped from $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 SPR_L16 ;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
SPR_L16 RTS ;A:25FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:1214 VC:097 00 FL:31642


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_OFF_SCREEN
; This subroutine deals with sprites that have moved off screen
; It is adapted from the subroutine at $01AC0D
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SPR_T12 dcb $40,$B0
SPR_T13 dcb $01,$FF
SPR_T14 dcb $30,$C0,$A0,$C0,$A0,$F0,$60,$90 ;bank 1 sizes
dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0 ;bank 3 sizes
SPR_T15 dcb $01,$FF,$01,$FF,$01,$FF,$01,$FF ;bank 1 sizes
dcb $01,$FF,$01,$FF,$01,$00,$01,$FF ;bank 3 sizes

SUB_OFF_SCREEN_X1 LDA #$02 ; \ entry point of routine determines value of $03
BRA STORE_03 ; | (table entry to use on horizontal levels)
SUB_OFF_SCREEN_X2 LDA #$04 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X3 LDA #$06 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X4 LDA #$08 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X5 LDA #$0A ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X6 LDA #$0C ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X7 LDA #$0E ; |
STORE_03 STA $03 ; |
BRA START_SUB ; |
SUB_OFF_SCREEN_X0 STZ $03 ; /

START_SUB JSR SUB_IS_OFF_SCREEN ; \ if sprite is not off screen, return
BEQ RETURN_35 ; /
LDA $5B ; \ goto VERTICAL_LEVEL if vertical level
AND #$01 ; |
BNE VERTICAL_LEVEL ; /
LDA SPRITE_Y_POS,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_35 ; /
LDA $13 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0756 VC:176 00 FL:205
AND #$01 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0780 VC:176 00 FL:205
ORA $03 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0796 VC:176 00 FL:205
STA $01 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0820 VC:176 00 FL:205
TAY ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0844 VC:176 00 FL:205
LDA $1A ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0858 VC:176 00 FL:205
CLC ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0882 VC:176 00 FL:205
ADC SPR_T14,y ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0896 VC:176 00 FL:205
ROL $00 ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizcHC:0928 VC:176 00 FL:205
CMP $E4,x ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:0966 VC:176 00 FL:205
PHP ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:0996 VC:176 00 FL:205
LDA $1B ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizCHC:1018 VC:176 00 FL:205
LSR $00 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdiZCHC:1042 VC:176 00 FL:205
ADC SPR_T15,y ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizcHC:1080 VC:176 00 FL:205
PLP ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F0 P:eNvMXdizcHC:1112 VC:176 00 FL:205
SBC $14E0,x ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1140 VC:176 00 FL:205
STA $00 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1172 VC:176 00 FL:205
LSR $01 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1196 VC:176 00 FL:205
BCC SPR_L31 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1234 VC:176 00 FL:205
EOR #$80 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1250 VC:176 00 FL:205
STA $00 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1266 VC:176 00 FL:205
SPR_L31 LDA $00 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1290 VC:176 00 FL:205
BPL RETURN_35 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1314 VC:176 00 FL:205
ERASE_SPRITE LDA $14C8,x ; \ if sprite status < 8, permanently erase sprite
CMP #$08 ; |
BCC KILL_SPRITE ; /
LDY $161A,x ;A:FF08 X:0007 Y:0001 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1108 VC:059 00 FL:2878
CPY #$FF ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1140 VC:059 00 FL:2878
BEQ KILL_SPRITE ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1156 VC:059 00 FL:2878
LDA #$00 ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1172 VC:059 00 FL:2878
STA $1938,y ;A:FF00 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZcHC:1188 VC:059 00 FL:2878
KILL_SPRITE STZ $14C8,x ; erase sprite
RETURN_35 RTS ; return

VERTICAL_LEVEL LDA $167A,x ; \ if "process offscreen" flag is set, return
AND #$04 ; |
BNE RETURN_35 ; /
LDA $13 ; \
LSR A ; |
BCS RETURN_35 ; /
LDA $E4,x ; \
CMP #$00 ; | if the sprite has gone off the side of the level...
LDA $14E0,x ; |
SBC #$00 ; |
CMP #$02 ; |
BCS ERASE_SPRITE ; / ...erase the sprite
LDA $13 ;A:0000 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:1218 VC:250 00 FL:5379
LSR A ;A:0016 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1242 VC:250 00 FL:5379
AND #$01 ;A:000B X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1256 VC:250 00 FL:5379
STA $01 ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1272 VC:250 00 FL:5379
TAY ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1296 VC:250 00 FL:5379
LDA $1C ;A:001A X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0052 VC:251 00 FL:5379
CLC ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0076 VC:251 00 FL:5379
ADC SPR_T12,y ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0090 VC:251 00 FL:5379
ROL $00 ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:enVMXdizCHC:0122 VC:251 00 FL:5379
CMP SPRITE_Y_POS,x ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0160 VC:251 00 FL:5379
PHP ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0190 VC:251 00 FL:5379
LDA.W $001D ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F2 P:eNVMXdizcHC:0212 VC:251 00 FL:5379
LSR $00 ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdiZcHC:0244 VC:251 00 FL:5379
ADC SPR_T13,y ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdizCHC:0282 VC:251 00 FL:5379
PLP ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:envMXdiZCHC:0314 VC:251 00 FL:5379
SBC $14D4,x ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0342 VC:251 00 FL:5379
STA $00 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0374 VC:251 00 FL:5379
LDY $01 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0398 VC:251 00 FL:5379
BEQ SPR_L38 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0422 VC:251 00 FL:5379
EOR #$80 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0438 VC:251 00 FL:5379
STA $00 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0454 VC:251 00 FL:5379
SPR_L38 LDA $00 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0478 VC:251 00 FL:5379
BPL RETURN_35 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0502 VC:251 00 FL:5379
BMI ERASE_SPRITE ;A:8AFF X:0002 Y:0000 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0704 VC:184 00 FL:5490

SUB_IS_OFF_SCREEN LDA H_OFFSCREEN,x ; \ if sprite is on screen, accumulator = 0
ORA V_OFFSCREEN,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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SPR_T1 dcb $0C,$1C
SPR_T2 dcb $01,$02

GET_DRAW_INFO STZ V_OFFSCREEN,x ; reset sprite offscreen flag, vertical
STZ H_OFFSCREEN,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 H_OFFSCREEN,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 SPRITE_Y_POS,x ; \
CLC ; | set vertical offscreen if necessary
ADC SPR_T1,y ; |
PHP ; |
CMP $1C ; | (vert screen boundry)
ROL $00 ; |
PLP ; |
LDA $14D4,x ; |
ADC #$00 ; |
LSR $00 ; |
SBC $1D ; |
BEQ ON_SCREEN_Y ; |
LDA V_OFFSCREEN,x ; | (vert offscreen)
ORA SPR_T2,y ; |
STA V_OFFSCREEN,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 SPRITE_Y_POS,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 ; /


EDIT: Wie kann ich einstellen, das es die Thwomp Grafik anzeigt?

The Lord of Monster Hunter, Auroros.


Projekt: SMWU
Status: Durchführung
News:
12.4.14: Was für ein Timing... zu Spikus Geburtstag komm ich zurück ^^ Und nebenbei beherrsche ich jetzt auch noch Ein wenig ASM
geschrieben am 10.01.2011 15:36:57
( Link )
Wenn ich mich nicht komplett irre, die rot markierte Zahl im "be killed" Teil ändern.

Spoiler anzeigen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Be killed by shells
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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 $14C8,x
CMP #$0A
BEQ NoKill

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 SetSpeed
INY
SetSpeed:
LDA KILLED_X_SPEED,y
STA $B6,x
NoKill:
PLX
HandleBirdoHit:
LDA #$28 ; Play sound effect
STA $1DFC

LDA #$20 ; Set stunned timer
STA $1564,x

;JSL $019138 ;interact with objects

INC $1528,x

LDA $1528,x

cmp #$03
bcc Return3

LDA #$0D ; \ turn sprite
STA $9E,x ; / into bob-omb
JSL $07F7D2 ; reset sprite tables
LDA #$08 ; \ sprite status:
STA $14C8,x ; / normal
LDA #$01 ; \ make it
STA $1534,x ; / explode
LDA #$30 ; \ set time for
STA $1540,x ; / explosion
LDA #$09 ; \ play sound
STA $1DFC ; / effect

GOAL 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

LDA #$03
STA $1602,x ; / write frame to show
Return3:
rts


ProcessCachedHit:
LDA $1528,x

BPL Return3
AND #$7F
STA $1528,x

BRA HandleBirdoHit


Zur anderen Frage, spontan würd ich sagen das Tileset auswählen in dem die Thwomps sind. Außer der Macher hat da was geändert.
geschrieben am 10.01.2011 16:24:54
( Link )
Ich hab mal ne Frage übers schreiben von Custom Blöcken.

Angenommen ich will jetzt nen Block schreiben der Mario zu Firemario macht dann sieht der Code ja so aus:

Mario:
LDA #$03
STA $19
Return:
RTL

Aber ich mein irgendwo auch mal gehört zu haben das man vorm Code noch so ne Art Gerüst schreiben muss.
Bei diesem Code würden ja (JMP Mario : und JMP Return : ) vorkommen,jetzt ist nur die Frage woher weiß ich wie oft ich JMP Mario und wie oft ich JMP Return schreiben muss?
Ich meine ich hab darüber noch nichts genaueres in den ganzen Tutorials gehört.
geschrieben am 10.01.2011 17:42:13
zuletzt bearbeitet von Auroros am 10.01.2011 19:04:43.
( Link )
Danke für die HP stelle

Aber das Castle Tileset funktioniert nicht... deswegen frage ich ja nach

EDIT: Funkt nicht... nachdem 3. treffer rührt sich der Boss nicht mehr... Da muss man wahrscheinlich im Code eine routine eintippen oder?
... Weiß jemand rein zufällig wie die Routine für den Boss bzw. reicht einfach Copy and paste um die Routine zu Kopieren?

The Lord of Monster Hunter, Auroros.


Projekt: SMWU
Status: Durchführung
News:
12.4.14: Was für ein Timing... zu Spikus Geburtstag komm ich zurück ^^ Und nebenbei beherrsche ich jetzt auch noch Ein wenig ASM
geschrieben am 10.01.2011 19:04:11
( Link )
Zitat von MarcelLp:
Bei diesem Code würden ja (JMP Mario : und JMP Return : ) vorkommen,jetzt ist nur die Frage woher weiß ich wie oft ich JMP Mario und wie oft ich JMP Return schreiben muss?
Ich meine ich hab darüber noch nichts genaueres in den ganzen Tutorials gehört.


Eigentlich ist's ganz einfach: Das Label, das hinter dem ersten JMP steht, ist das Label, zu dem der Code springt, wenn Mario den Block von oben berührt. Wenn da also JMP Troete steht, wird der Code nach dem Label "Troete:" ausgeführt, wenn der Block von oben berührt wird. Die Labels danach sind, in der Reihenfolge, zuständig für: Berührung von unten, Berührung von den Seiten, Berührung von Sprites oben/unten, Berührung von Sprites an den Seiten, Berührung durch Cape, Berühren durch Feuerball.

Wahrscheinlich willst du den Code für deinen Block nur ausführen, wenn er von oben, unten und den Seiten berührt wird, also solltest du folgendes nehmen:

Code
JMP Mario
JMP Mario
JMP Mario
JMP Return
JMP Return
JMP Return
JMP Return
geschrieben am 10.01.2011 19:30:51
( Link )
Ah vielen dank hab das jetzt einigermaßen Verstanden
geschrieben am 10.01.2011 20:07:56
( Link )
Zitat von Auroros:
Danke für die HP stelle

Aber das Castle Tileset funktioniert nicht... deswegen frage ich ja nach

Am anfang der Datei sind folgende Zeilen:
Code
RISE_SPEED dcb $F0,$E0,$D0
TIME_ON_GROUND dcb $30,$20,$10
X_SPEED_LEFT dcb $10,$20,$30
X_SPEED_RIGHT dcb $EF,$DF,$CF

Tausch die mal jeweils mit denen aus:
Code
RISE_SPEED dcb $F0,$E0,$D0,$D0
TIME_ON_GROUND dcb $30,$20,$10,$10
X_SPEED_LEFT dcb $10,$20,$30,$30
X_SPEED_RIGHT dcb $EF,$DF,$CF,$CF


Wegen den Grafiken, im Super GFX Bypass (roter giftpilz) muss bei SP4 3 stehen.
geschrieben am 10.01.2011 22:01:33
( Link )
Funktioniert irgend wie nicht... muss ich vielleicht nur ein bisschen verinnerlichen

Was das Castle Tileset angeht:

SP4 ist 3!
SP4 ist für die Reflecting Fireballs zuständig, und am Thwomp ändert sich nichts!
Da muss man irgend etwas mit der Tile Map machen... Bei mir zeigt er mir nur den (toten) Knochen trocken boden als Boden an, und als Kopf benutzt er nur die Obere Hälfte des riesen Feuer Ball, der am Boden Krabbelt
Und sein Gesicht zeigt bei seinen Attacken, wenn er auf den Boden geht, immer die Spitze dieses Holz Speeres...

The Lord of Monster Hunter, Auroros.


Projekt: SMWU
Status: Durchführung
News:
12.4.14: Was für ein Timing... zu Spikus Geburtstag komm ich zurück ^^ Und nebenbei beherrsche ich jetzt auch noch Ein wenig ASM
geschrieben am 10.01.2011 22:48:21
( Link )
Also gut, poste bitte nochmal alles so wie du's jetzt verändert hast. Dann kann ich es auch mal selber testen.

Damit die richtigen Grafiken gezeigt werden änderst du
Code
TILE_MAP dcb $0E,$0E,$2E,$2E,$48 

in
Code
TILE_MAP dcb $8E,$8E,$AE,$AE,$C8 
geschrieben am 10.01.2011 23:02:14
( Link )
Der Code... (Vorsicht! er speit keine Spinis und Hopping Flames! sondern Reflecting Fireballs und Bone Drys! Und natürlich Koopas)

Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Homing Thwomp, by yoshicookiezeus and edited by dahnamics
;;
;; Description: A thwomp that follows Mario horizontally when on the ceiling, and spawns
;; Spinies, Green Koopas and Hopping Flames randomly when it hits the ground.
;; It has three hit points, and shell like items hurt it. It gets faster with
;; each hit and explodes like a Bob-Omb when killed. It also ends the level.
;;
;; NOTE: ONLY use this sprite in one-screen areas with "No vertical or horizontal scroll"
;; enabled!
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Homing Thwomp, by yoshicookiezeus
;;
;; Description: A thwomp that follows Mario horizontally when on the ceiling, and spawns
;; Bob-Ombs when it hits the ground. It has three hit points, and only gets
;; hurt by Bob-Omb explosions. It gets faster with each hit.
::
;; NOTE: ONLY use this sprite in one-screen areas with "No vertical or horizontal scroll"
;; enabled!
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; symbolic names for RAM addresses (don't change these)
GetSpriteClippingA = $03B69F
GetSpriteClippingB = $03B6E5
CheckForContact = $03B72B
ShowSprContactGfx = $01AB72
SPRITE_Y_SPEED = $AA
SPRITE_X_SPEED = $B6
SPRITE_STATE = $C2
SPRITE_X_POS = $E4
SPRITE_Y_POS = $D8
ORIG_Y_POS = $151C
EXPRESSION = $1594
FREEZE_TIMER = $1540
SPR_OBJ_STATUS = $1588
H_OFFSCREEN = $15A0
V_OFFSCREEN = $186C

; definitions of bits (don't change these)
IS_ON_GROUND = $04

; sprite data
SPRITE_GRAVITY = $04
MAX_Y_SPEED = $3E
RISE_SPEED dcb $F0,$E0,$D0,$D0
TIME_TO_SHAKE = $18
SOUND_EFFECT = $09
TIME_ON_GROUND dcb $30,$20,$10,$10
ANGRY_TILE = $4A

X_SPEED_LEFT dcb $10,$20,$30,$30
X_SPEED_RIGHT dcb $EF,$DF,$CF,$CF

X_OFFSET dcb $FC,$04,$FC,$04,$00
Y_OFFSET dcb $00,$00,$10,$10,$08
TILE_MAP dcb $8E,$8E,$AE,$AE,$C8
PROPERTIES dcb $03,$43,$03,$43,$03

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "INIT"
LDA SPRITE_Y_POS,x
STA ORIG_Y_POS,x
LDA $E4,x
CLC
ADC #$08
STA $E4,x
RTL


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite code JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "MAIN"
PHB
PHK
PLB
JSR SPRITE_CODE_START
PLB
RTL


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite main code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

RETURN RTS

SPRITE_CODE_START JSR SUB_GFX

LDA $14C8,x ; return if sprite status != 8

ALIVE CMP #$08 ; \ if status != 8, return
BNE RETURN ; /

LDA $9D ; return if sprites locked
BNE RETURN

LDA $1564,x ; if invincibility timer isn't active,
BEQ JUMP ; go to hitpoints routine
DEC $1564,x ; else, decrease invincibility timer
BRA NO_JUMP

JUMP JSR HITPOINTS

NO_JUMP JSR SUB_OFF_SCREEN_X0 ; only process sprite while on screen

JSL $01A7DC ; interact with mario

LDA SPRITE_STATE,x
CMP #$01
BEQ FALLING
CMP #$02
BEQ RISING0

;-----------------------------------------------------------------------------------------
; state 0
;-----------------------------------------------------------------------------------------

HOVERING LDA V_OFFSCREEN,x ;fall if offscreen vertically
BNE SET_FALLING

LDA H_OFFSCREEN,x ;return if offscreen horizontally
BNE RETURN0

STZ SPRITE_Y_SPEED,x
JSR SUB_HORZ_POS ;determine if mario is close and act accordingly
TYA
STA $157C,x

LDY $1528,x ;check what side of sprite Mario is on
LDA $157C,x ;and set x speed accordingly
BEQ LEFT
LDA X_SPEED_RIGHT,y
STA SPRITE_X_SPEED,x
BRA CONTINUE

LEFT LDA X_SPEED_LEFT,y
STA SPRITE_X_SPEED,x

CONTINUE LDA SPRITE_X_POS,x
CLC
ADC #$08
SEC
SBC $94
CMP #$10
BCS RETURN0

SET_FALLING STZ SPRITE_X_SPEED,x
LDA #$02 ;set expression
STA EXPRESSION,x

INC SPRITE_STATE,x ;chage state to falling

LDA #$00
STA SPRITE_Y_SPEED,x ;set initial speed

RETURN0 JSL $01802A ;apply speed
RTS

RISING0 BRA RISING1

;-----------------------------------------------------------------------------------------
; state 1
;-----------------------------------------------------------------------------------------
SPRITE_TO_GEN dcb $30,$06,$B6,$B4,$1C,$10,$1F

FALLING 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_GRAVITY
STA SPRITE_Y_SPEED,x
DONT_INC_SPEED
JSL $019138 ;interact with objects

LDA SPR_OBJ_STATUS,x ;return if not on the ground
AND #IS_ON_GROUND
BEQ RETURN68

JSR SUB_9A04 ; ?? speed related

LDA #TIME_TO_SHAKE ;shake ground
STA $1887

LDA #SOUND_EFFECT ;play sound effect
STA $1DFC

LDY $1528,x
LDA TIME_ON_GROUND,y ;set time to stay on ground
STA FREEZE_TIMER,x

INC SPRITE_STATE,x ;go to rising state

LDA $1528,x
CMP #$02
BNE SUB_BOMB_THROW
LDA $77
AND #$04
BEQ SUB_BOMB_THROW
LDA #TIME_TO_SHAKE
STA $18BD
BRA SUB_BOMB_THROW

RISING1 BRA RISING

RETURN68 RTS
SUB_BOMB_THROW LDA $15A0,x ; \ no bomb if off screen
ORA $186C,x ; |
ORA $15D0,x
BNE RETURN68

JSL $02A9DE ; \ get an index to an unused sprite slot, return if all slots full
BMI RETURN68 ; / after: Y has index of sprite being generated

LDA #$01 ; \ set sprite status for new sprite
STA $14C8,y ; /

PHX
LDA #$02
JSL RANDOM
TAX
LDA SPRITE_TO_GEN,x ; \ set sprite number for new sprite
PLX
STA $9E,y

LDA $E4,x ; \ set position of spawned sprite
STA $E4,y ; |
LDA $D8,x ; |
CLC ; |
ADC #$10 ; |
STA $D8,y ; |
LDA $14D4,x ; |
STA $14D4,y ; |
LDA $14E0,X ; |
STA $14E0,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 #$00
PLY
STA $B6,y

LDA #$00
STA $AA,y

RETURN67 RTS ; return

RANDOM PHX
PHP
SEP #$30
PHA
JSL $01ACF9 ; Random number generation routine
PLX
CPX #$FF ;\ Handle glitch if max is FF
BNE NORMALRT ;|
LDA $148B ;|
BRA ENDRANDOM ;/
NORMALRT INX ; Amount in plus 1
LDA $148B ;\
STA $4202 ;| Multiply with hardware regsisters
STX $4203 ;|
NOP ;|
NOP ;|
NOP ;|
NOP ;/
LDA $4217
ENDRANDOM PLP
PLX
RTL
;-----------------------------------------------------------------------------------------
; state 2
;-----------------------------------------------------------------------------------------

RISING LDA FREEZE_TIMER,x ;if we're still waiting on the ground, return
BNE RETURN2

STZ EXPRESSION,x ;reset expression

JSL $019138 ;interact with objects
LDA SPR_OBJ_STATUS,x ;check if the sprite is in original position
AND #$08
BEQ RISE

STZ SPRITE_STATE,x ;reset state to hovering
RTS

RISE LDY $1528,x
LDA RISE_SPEED,y ;set rising speed and apply it
STA SPRITE_Y_SPEED,x
JSL $01801A
RETURN2 RTS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SUB_GFX JSR GET_DRAW_INFO

LDA EXPRESSION,x
STA $02
PHX
LDX #$03
CMP #$00
BEQ LOOP_START
INX
LOOP_START LDA $00
CLC
ADC X_OFFSET,x
STA $0300,y

LDA $01
CLC
ADC Y_OFFSET,x
STA $0301,y

LDA PROPERTIES,x
ORA $64
STA $0303,y

LDA TILE_MAP,x
CPX #$04
BNE NORMAL_TILE
PHX
LDX $02
CPX #$02
BNE NOT_ANGRY
LDA #ANGRY_TILE
NOT_ANGRY PLX
NORMAL_TILE STA $0302,y

INY
INY
INY
INY
DEX
BPL LOOP_START

PLX

LDY #$02 ; \ 460 = 2 (all 16x16 tiles)
LDA #$04 ; | A = (number of tiles drawn - 1)
JSL $01B7B3 ; / don't draw if offscreen
RTS ; return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Be killed by shells
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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 $14C8,x
CMP #$0A
BEQ NoKill

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 SetSpeed
INY
SetSpeed:
LDA KILLED_X_SPEED,y
STA $B6,x
NoKill:
PLX
HandleBirdoHit:
LDA #$28 ; Play sound effect
STA $1DFC

LDA #$20 ; Set stunned timer
STA $1564,x

;JSL $019138 ;interact with objects

INC $1528,x

LDA $1528,x

cmp #$04
bcc Return3

LDA #$0D ; \ turn sprite
STA $9E,x ; / into bob-omb
JSL $07F7D2 ; reset sprite tables
LDA #$08 ; \ sprite status:
STA $14C8,x ; / normal
LDA #$01 ; \ make it
STA $1534,x ; / explode
LDA #$30 ; \ set time for
STA $1540,x ; / explosion
LDA #$09 ; \ play sound
STA $1DFC ; / effect

GOAL 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

LDA #$03
STA $1602,x ; / write frame to show
Return3:
rts


ProcessCachedHit:
LDA $1528,x

BPL Return3
AND #$7F
STA $1528,x

BRA HandleBirdoHit



;###############################################################################################
;###############################################################################################
;###############################################################################################
; ROUTINES FROM THE LIBRARY ARE PASTED BELOW
; You should never have to modify this code
;###############################################################################################
;###############################################################################################
;###############################################################################################


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_HORZ_POS
; This routine determines which side of the sprite Mario is on. It sets the Y register
; to the direction such that the sprite would face Mario
; It is ripped from $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 SPR_L16 ;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
SPR_L16 RTS ;A:25FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:1214 VC:097 00 FL:31642


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_OFF_SCREEN
; This subroutine deals with sprites that have moved off screen
; It is adapted from the subroutine at $01AC0D
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SPR_T12 dcb $40,$B0
SPR_T13 dcb $01,$FF
SPR_T14 dcb $30,$C0,$A0,$C0,$A0,$F0,$60,$90 ;bank 1 sizes
dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0 ;bank 3 sizes
SPR_T15 dcb $01,$FF,$01,$FF,$01,$FF,$01,$FF ;bank 1 sizes
dcb $01,$FF,$01,$FF,$01,$00,$01,$FF ;bank 3 sizes

SUB_OFF_SCREEN_X1 LDA #$02 ; \ entry point of routine determines value of $03
BRA STORE_03 ; | (table entry to use on horizontal levels)
SUB_OFF_SCREEN_X2 LDA #$04 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X3 LDA #$06 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X4 LDA #$08 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X5 LDA #$0A ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X6 LDA #$0C ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X7 LDA #$0E ; |
STORE_03 STA $03 ; |
BRA START_SUB ; |
SUB_OFF_SCREEN_X0 STZ $03 ; /

START_SUB JSR SUB_IS_OFF_SCREEN ; \ if sprite is not off screen, return
BEQ RETURN_35 ; /
LDA $5B ; \ goto VERTICAL_LEVEL if vertical level
AND #$01 ; |
BNE VERTICAL_LEVEL ; /
LDA SPRITE_Y_POS,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_35 ; /
LDA $13 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0756 VC:176 00 FL:205
AND #$01 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0780 VC:176 00 FL:205
ORA $03 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0796 VC:176 00 FL:205
STA $01 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0820 VC:176 00 FL:205
TAY ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0844 VC:176 00 FL:205
LDA $1A ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0858 VC:176 00 FL:205
CLC ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0882 VC:176 00 FL:205
ADC SPR_T14,y ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0896 VC:176 00 FL:205
ROL $00 ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizcHC:0928 VC:176 00 FL:205
CMP $E4,x ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:0966 VC:176 00 FL:205
PHP ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:0996 VC:176 00 FL:205
LDA $1B ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizCHC:1018 VC:176 00 FL:205
LSR $00 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdiZCHC:1042 VC:176 00 FL:205
ADC SPR_T15,y ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizcHC:1080 VC:176 00 FL:205
PLP ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F0 P:eNvMXdizcHC:1112 VC:176 00 FL:205
SBC $14E0,x ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1140 VC:176 00 FL:205
STA $00 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1172 VC:176 00 FL:205
LSR $01 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1196 VC:176 00 FL:205
BCC SPR_L31 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1234 VC:176 00 FL:205
EOR #$80 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1250 VC:176 00 FL:205
STA $00 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1266 VC:176 00 FL:205
SPR_L31 LDA $00 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1290 VC:176 00 FL:205
BPL RETURN_35 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1314 VC:176 00 FL:205
ERASE_SPRITE LDA $14C8,x ; \ if sprite status < 8, permanently erase sprite
CMP #$08 ; |
BCC KILL_SPRITE ; /
LDY $161A,x ;A:FF08 X:0007 Y:0001 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1108 VC:059 00 FL:2878
CPY #$FF ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1140 VC:059 00 FL:2878
BEQ KILL_SPRITE ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1156 VC:059 00 FL:2878
LDA #$00 ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1172 VC:059 00 FL:2878
STA $1938,y ;A:FF00 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZcHC:1188 VC:059 00 FL:2878
KILL_SPRITE STZ $14C8,x ; erase sprite
RETURN_35 RTS ; return

VERTICAL_LEVEL LDA $167A,x ; \ if "process offscreen" flag is set, return
AND #$04 ; |
BNE RETURN_35 ; /
LDA $13 ; \
LSR A ; |
BCS RETURN_35 ; /
LDA $E4,x ; \
CMP #$00 ; | if the sprite has gone off the side of the level...
LDA $14E0,x ; |
SBC #$00 ; |
CMP #$02 ; |
BCS ERASE_SPRITE ; / ...erase the sprite
LDA $13 ;A:0000 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:1218 VC:250 00 FL:5379
LSR A ;A:0016 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1242 VC:250 00 FL:5379
AND #$01 ;A:000B X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1256 VC:250 00 FL:5379
STA $01 ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1272 VC:250 00 FL:5379
TAY ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1296 VC:250 00 FL:5379
LDA $1C ;A:001A X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0052 VC:251 00 FL:5379
CLC ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0076 VC:251 00 FL:5379
ADC SPR_T12,y ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0090 VC:251 00 FL:5379
ROL $00 ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:enVMXdizCHC:0122 VC:251 00 FL:5379
CMP SPRITE_Y_POS,x ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0160 VC:251 00 FL:5379
PHP ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0190 VC:251 00 FL:5379
LDA.W $001D ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F2 P:eNVMXdizcHC:0212 VC:251 00 FL:5379
LSR $00 ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdiZcHC:0244 VC:251 00 FL:5379
ADC SPR_T13,y ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdizCHC:0282 VC:251 00 FL:5379
PLP ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:envMXdiZCHC:0314 VC:251 00 FL:5379
SBC $14D4,x ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0342 VC:251 00 FL:5379
STA $00 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0374 VC:251 00 FL:5379
LDY $01 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0398 VC:251 00 FL:5379
BEQ SPR_L38 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0422 VC:251 00 FL:5379
EOR #$80 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0438 VC:251 00 FL:5379
STA $00 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0454 VC:251 00 FL:5379
SPR_L38 LDA $00 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0478 VC:251 00 FL:5379
BPL RETURN_35 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0502 VC:251 00 FL:5379
BMI ERASE_SPRITE ;A:8AFF X:0002 Y:0000 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0704 VC:184 00 FL:5490

SUB_IS_OFF_SCREEN LDA H_OFFSCREEN,x ; \ if sprite is on screen, accumulator = 0
ORA V_OFFSCREEN,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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SPR_T1 dcb $0C,$1C
SPR_T2 dcb $01,$02

GET_DRAW_INFO STZ V_OFFSCREEN,x ; reset sprite offscreen flag, vertical
STZ H_OFFSCREEN,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 H_OFFSCREEN,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 SPRITE_Y_POS,x ; \
CLC ; | set vertical offscreen if necessary
ADC SPR_T1,y ; |
PHP ; |
CMP $1C ; | (vert screen boundry)
ROL $00 ; |
PLP ; |
LDA $14D4,x ; |
ADC #$00 ; |
LSR $00 ; |
SBC $1D ; |
BEQ ON_SCREEN_Y ; |
LDA V_OFFSCREEN,x ; | (vert offscreen)
ORA SPR_T2,y ; |
STA V_OFFSCREEN,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 SPRITE_Y_POS,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 ; /


Testen muss ich das mit der Tilemap noch...
Heute Läuft da nichts mehr

The Lord of Monster Hunter, Auroros.


Projekt: SMWU
Status: Durchführung
News:
12.4.14: Was für ein Timing... zu Spikus Geburtstag komm ich zurück ^^ Und nebenbei beherrsche ich jetzt auch noch Ein wenig ASM
geschrieben am 11.01.2011 20:38:34
( Link )
Okay, Status

HP verändern... das funktioniert gut... Ich weiß auch wie ich die Geschwindigkeit verändern kann
Aber Tileset... das macht noch ein paar Probleme... und zwar werden immer noch bei dem zu boden fallen die Spitze des Holz speeres gezeigt...
Da brauch ich noch ein wenig hilfe... dann haben wir meinen Custom custom Thwomp boss

EDIT: kann ich ihn auch custom sprites generieren lassen? und wenn ja, wie?

The Lord of Monster Hunter, Auroros.


Projekt: SMWU
Status: Durchführung
News:
12.4.14: Was für ein Timing... zu Spikus Geburtstag komm ich zurück ^^ Und nebenbei beherrsche ich jetzt auch noch Ein wenig ASM
geschrieben am 12.01.2011 15:02:15
( Link )
Wie erstellt man eigentlich einen Patch, der Mario die ganze Zeit springen laesst?(Sowie bei Doodle Jump)
Brutal Mario ist out.Spielt mal SMW FreedoMN,1Updudes-Hacks,The Devious Four Chronicles oder Chomps Attacke!
geschrieben am 15.01.2011 13:50:29
( Link )
Ich benutze den Custom-Lemmy-Boss. Der produziert Bälle, die im Raum umherfliegen und mit denen man ihn treffen muss. Sobald 5 Bälle im Screen sind, baut er keine weiteren Bälle.
Wie kann ich bei Lemmy einstellen, dass er schon bei einer Anzahl von 3 Bällen im Screen aufhört, mit Bällen zu werfen:
Code

EXTRA_BITS = $7FAB10
NEW_SPRITE_NUM = $7FAB9E ;08 bytes custom sprite number

JUMP_TIMER = $163E
RAM_ThrowTimer = $1504

Hit_Counter = $1528 ; The hit counter for any sprite that takes lots of hits to kill
GetSpriteClippingA = $03B69F
CheckForContact = $03B72B


GetSpriteClippingB = $03B6E5
;CheckForContact = $03B72B
ShowSprContactGfx = $01AB72
HurtMario = $00F5B7
GivePoints = $02ACE5
GetRand = $01ACF9
SPRITE_STATE = $C2

Invuln_Timer = $1564 ; The RAM address for Lemmy's stun duration
Lemmy_Hits = $05 ; This is how many hits it takes to kill Lemmy (default == 3)

RAM_HitCount = $1534
SPRITE_TO_GEN dcb $4C,$4C,$4C
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


PROPERTIES dcb $40,$00 ;xyppccct format

BOOMERANG_TILE = $CA
TIME_TO_EXPLODE = $A0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "INIT"

JSR SUB_GET_DIR
TYA
STA $157C,x

TXA
AND #$03
ASL A
ASL A
ASL A
ASL A
ASL A
STA JUMP_TIMER,x
CLC
ADC #$32
STA RAM_ThrowTimer,x

RTL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main sprite JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "MAIN"
HAMMER_BRO_JSL PHB ; \
PHK ; | main sprite function, just calls local subroutine
PLB ; |
JSR DecrementTimers
JSR START_HB_CODE ; |
PLB ; |
RTL ; /
DecrementTimers:
LDA $14C8,x
CMP #$08
BNE DoneDec
LDA $9D
BNE DoneDec
LDA RAM_ThrowTimer,x
BEQ DoneDec
DEC RAM_ThrowTimer,x

DoneDec:
RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main sprite routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TIME_TO_SHOW = $10 ;time to display the boomerang before it is thrown

X_SPEED dcb $F8,$F8,$08,$08 ;rest at bottom, forward speed, rest at top, backwards speed
TIME_IN_POS dcb $37,$18,$37,$18 ;moving forward, rest, moving backwards, rest ($48,$10,$48,$10)
TIME_TILL_THROW dcb $68,$69

STAR INC RAM_ThrowTimer,x
RETURN RTS
START_HB_CODE JSR SUB_GFX ; draw hammer bro gfx
LDA $14C8,x ; \ if hammer bro status != 8...
CMP #$02 ; } ... not (killed with spin jump [4] or star[2])
BEQ STAR
CMP #$08
BNE RETURN ; / ... return
LDA $9D ; \ if sprites locked...
BNE RETURN ; / ... return

;JSR SUB_GET_DIR ; \ always face mario
;TYA ; |
;STA $157C,x ; /
JSR SUB_OFF_SCREEN_HB ; only process hammer bro while on screen

LDA Invuln_Timer,x ; \
BEQ No_Inv ; | Decrement Invuln timer if necessary
DEC Invuln_Timer,x ; /

No_Inv:
INC $1570,x ; increment number of frames hammer bro has been on screen
LDA $151C,x
AND #$01
BEQ LABEL3B
LDA $1570,x ; \ calculate which frame to show:
LSR A ; |
LSR A ; |
LSR A ; |
AND #$01 ; | update every 16 cycles if normal
BRA LABEL3

LABEL3B LDA $151C,x
BEQ LABEL3
LDA #$01
LABEL3 STA $1602,x ; / write frame to show

LDA RAM_ThrowTimer,x ; \ if time until spit >= $10
CMP #TIME_TO_SHOW ; | just go to normal walking code
BCS JUMP_BIRDO ; /
INC $1602,x
INC $1602,x

LDA Invuln_Timer,x
CMP #$00
BEQ Go_Throw
LDA TIME_TILL_THROW,y
STA RAM_ThrowTimer,x
Go_Throw:
LDA RAM_ThrowTimer,x ; \ throw hammer if it's time
BNE NO_RESET ; |
LDY $C2,x
LDA TIME_TILL_THROW,y
STA RAM_ThrowTimer,x
NO_RESET CMP #$01
BNE JUMP_BIRDO
LDA $C2,x
EOR #$01
STA $C2,x
JSR SUB_HAMMER_THROW ; /

JUMP_BIRDO LDA JUMP_TIMER,x
CMP #$28 ; | just go to normal walking code
BCS WALK_BIRDO ; /

LDA Invuln_Timer,x
CMP #$00
BNE WALK_BIRDO

LDA JUMP_TIMER,x
CMP #$21
BNE NO_JUMP2
LDA $1570,x
LSR A
AND #01
BEQ NO_JUMP2
;STZ $B6,x ; x speed = 0
LDA #$D0 ; \ y speed
STA $AA,x ; /

BRA APPLY_SPEED
NO_JUMP2 CMP #$00
BNE WALK_BIRDO
LDA #$7F
STA JUMP_TIMER,x

WALK_BIRDO LDA Invuln_Timer,x ; \ If in stunned state...
CMP #$00 ; |
BEQ Walk_Normal ; |
STZ $B6,x ; | ...halt motion...
INC $1540,x ; | ...and freeze movement timer by incrementing it.
BRA APPLY_SPEED ; /
Walk_Normal:
LDA $151C,x ;
TAY ;
LDA $1540,x ;
BEQ CHANGE_SPEED ;
LDA X_SPEED,y ; | set y speed
STA $B6,x ; /
BRA APPLY_SPEED

CHANGE_SPEED LDA TIME_IN_POS,y ;A:0001 X:0007 Y:0000 D:0000 DB:01 S:01F5 P:envMXdiZCHC:0654 VC:057 00 FL:24235
STA $1540,x ;A:0020 X:0007 Y:0000 D:0000 DB:01 S:01F5 P:envMXdizCHC:0686 VC:057 00 FL:24235
LDA $151C,x
INC A
AND #$03
STA $151C,x

APPLY_SPEED JSL $01802A ; update position based on speed values

LDA Invuln_Timer,x ; \
CMP #$00 ; | Ignore if Lemmy is still immune to bombs
BEQ Jump_to_Weapon ; |
BRA No_Jump_to ; /

Jump_to_Weapon:
JSR HIT_ROUTINE

No_Jump_to:
LDA $1588,x ; \ if hammer bro is touching the side of an object...
AND #$03 ; |
BEQ DONT_CHANGE_DIR ; |
LDA $151C,x
INC A
AND #$03
STA $151C,x

DONT_CHANGE_DIR JSL $018032 ; interact with other sprites
JSL $01A7DC ; check for mario/hammer bro contact
BCC NO_CONTACT ; No Contact
LDA $1490 ; \ if mario star timer > 0 ...
BNE HAS_STAR ; / ... goto HAS_STAR

NO_CONTACT JSR KILL_BOOMERANGS
RTS ; return
KILL_BOOMERANGS
RTS

HAS_STAR LDA #$02 ; \ sprite status = 2 (being killed by star)
STA $14C8,x ; /
STZ $B6 ; Freeze X speed
LDA #$D0 ; \ set y speed
STA $AA,x ; /
;JSR SUB_HORZ_POS ; get new sprite direction
;LDA KILLED_X_SPEED,y ; \ set x speed based on sprite direction
;STA $B6,x ; /
;INC $18D2 ; increment number consecutive enemies killed
LDA $18D2 ; \
CMP #$08 ; | if consecutive enemies stomped >= 8, reset to 8
BCC NO_RESET2 ; |
LDA #$08 ; |
STA $18D2 ; /
NO_RESET2 JSL $02ACE5 ; give mario points
LDY $18D2 ; \
CPY #$08 ; | if consecutive enemies stomped < 8 ...
BCS NO_SOUND2 ; |
LDA STAR_SOUNDS,y ; | ... play sound effect
STA $1DF9 ; /
NO_SOUND2 RTS ; final return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; hammer routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

X_OFFSET dcb $06,$FA
X_OFFSET2 dcb $00,$FF

SUB_HAMMER_THROW
JSL $02A9DE ; \ get an index to an unused sprite slot, return if all slots full
BMI RETURN67 ; / after: Y has index of sprite being generated

PHX
TYX

LDA #$20 ; \ sound effect
STA $1DF9

LDA #$08
STA $14C8,x

PHX
LDA #$02
JSL RANDOM
TAX
LDA SPRITE_TO_GEN,x ; \ set sprite number for new sprite
PLX

;LDA #$3A
STA $7FAB9E,x
JSL $07F7D2
JSL $0187A7
LDA #$08
STA $7FAB10,x
PLX

PHY
LDA $157C,x
TAY
LDA $E4,x ; \ set xlo position for new sprite
CLC
ADC X_OFFSET,y
PLY
STA $00E4,y

PHY
LDA $157C,x
TAY
LDA $14E0,x ; | set xhi position for new sprite
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
JSL $0187A7 ; get table values for custom sprite
LDA #$88
STA EXTRA_BITS,x
PLX ; /

LDA $157C,x
STA $157C,y

RETURN67 RTS ; return

RANDOM PHX
PHP
SEP #$30
PHA
JSL $01ACF9 ; Random number generation routine
PLX
CPX #$FF ;\ Handle glitch if max is FF
BNE NORMALRT ;|
LDA $148B ;|
BRA ENDRANDOM ;/
NORMALRT INX ; Amount in plus 1
LDA $148B ;\
STA $4202 ;| Multiply with hardware regsisters
STX $4203 ;|
NOP ;|
NOP ;|
NOP ;|
NOP ;/
LDA $4217
ENDRANDOM PLP
PLX
RTL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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
STUNNED_X_SPEED:
dcb $10,$EF

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 $14C8,x
CMP #$0A
BEQ NoKill

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 SetSpeed
INY
SetSpeed:
LDA KILLED_X_SPEED,y
STA $B6,x
NoKill:
PLX
HandleBirdoHit:
LDA #$28 ; Play sound effect
STA $1DFC

LDA #$30 ; Set stunned timer
STA $1564,x

INC $1528,x

LDA $1528,x

cmp #Lemmy_Hits
bcc Return3

LDA #$02 ; Kill Lemmy
STA $14C8,x
STZ $B6,x ; Set X speed
LDA #$F0 ; Set Y speed
STA $AA,x

GOAL 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

LDA #$03
STA $1602,x ; / write frame to show
Return3:
rts


ProcessCachedHit:
LDA $1528,x

BPL Return3
AND #$7F
STA $1528,x

BRA HandleBirdoHit


(Die Graphics Routine usw. hab ich mal weggelassen...)
geschrieben am 21.01.2011 18:55:14
( Link )
Ich wollt einen Block schreiben der Mario's Leben um 1 erhöht wenn man Feuermario ist.
Ich weiß absolut nicht warum der Block nicht funktioniert hier mal der Code:

Spoiler anzeigen
JMP Mario : JMP Mario : JMP Mario : JMP Return : JMP Return : JMP Return : JMP Return

Mario:
LDA $19
CMP #$03
BEQ Leben
RTL
Leben:
LDA #$01
STA $18E4
Return:
RTL


Ich hoffe, dass jemand bereit ist mir den Fehler zu erklären.
geschrieben am 21.01.2011 22:05:08
( Link )
Ich kann da nichts Falsches erkennen... Funktioniert's denn, wenn du für den "Leben geben"-Code einfach nur INC $0DBE nimmst?
geschrieben am 21.01.2011 22:17:34
( Link )
Hmm komisch funktioniert trotzdem nicht. Hat das vlt was mit der behave like tile number zu tun ? Hab da : 25 genommen ( macht man doch so weit ich weiß bei fast jeden Custom Block, zumindest klappen die andern mit der Nummer)
geschrieben am 21.01.2011 23:28:43
( Link )
Womit fügst du's denn ein? Und was genau passiert? Crasht die ROM oder passiert einfach gar nichts?

Es müsste jedenfalls zumindest "INC $18E4" heißen, da der Counter sonst genau auf 1 gesetzt wird statt um 1 erhöht zu werden.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.

geschrieben am 22.01.2011 10:47:47
( Link )
Klappt immer noch nicht .
Also ich fügs per Blocktool Super Deluxe ein ( aber am einfügen kann es nicht liegen, da sämtliche andere Custom Blocks auch funktionieren )
Und nein die Rom crasht nicht es einfach passiert gar nichts.
geschrieben am 22.01.2011 11:06:55
( Link )
Was genau hast du denn alles in BTSD und in Lunar Magic gemacht? Liste hier einfach nochmal genau jeden Schritt auf. Irgendwo musst du ja einen Fehler gemacht habe.
-Das quadratische Rad neu erfinden-
Mit das quadratische Rad neu erfinden (englisch Reinventing the square wheel) bezeichnet man die Bereitstellung einer schlechten Lösung, wenn eine gute Lösung bereits existiert.

-Slowsort-
Slowsort (von engl. slow: langsam) ist ein langsamer, rekursiver Sortieralgorithmus, der nach dem Prinzip Vervielfache und kapituliere (engl. Multiply and surrender, eine Parodie auf Teile und herrsche) arbeitet.