Modifizieren von Custom Sprites?

geschrieben am 07.02.2011 15:05:00
( Link )
Hey Leute, ich habe mich ja schon ASM beschäftigt und beherrsche Blöcke und Patche RELATIV gut.

Nun kommt aber ein Gebiet, was mich ernorm verwirrt, und zwar sind es die Custom Sprites! Ich will aber keine blank scratchen sondern nur modifizieren (siehe Titel)

Ich habe so einige simple Ideen, doch ich kann sie einfach nicht umsetzen, da ich nicht verstehe, wie Custom Sprites überhaupt funktionieren, hier ein Beispiel:

Der springende Goomba:

Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Classic Goomba, by mikeyk
;;
;; Description: A classic squashable goomba.
;;
;; Uses first extra bit: NO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; goomba init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "INIT"
PHY
JSR SUB_HORZ_POS
TYA
STA $157C,x
PLY
RTL


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; goomba main JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "MAIN"
PHB ; \
PHK ; | main sprite function, just calls local subroutine
PLB ; |
JSR GOOMB_CODE_START ; |
PLB ; |
RTL ; /


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; goomba main code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

X_SPEED dcb $08,$F8
KILLED_X_SPEED dcb $F0,$10

GOOMB_CODE_START JSR GOOMB_GRAPHICS ; graphics routine
LDA $14C8,x ; \
CMP #$08 ; | if status != 8, return
BNE RETURN ; /
JSR SUB_OFF_SCREEN_X0 ; handle off screen situation
LDY $157C,x ; \ set x speed based on direction
LDA X_SPEED,y ; |
STA $B6,x ; /
LDA $9D ; \ if sprites locked, return
BNE RETURN ; /
LDA $1558,x ; \ if sprite not defeated (timer to show remains > 0)...
BEQ ALIVE ; / ... goto ALIVE
STA $15D0,x ; \
DEC A ; } if sprite remains don't disappear next frame...
BNE RETURN ; / ... return
STZ $14C8,x ; this is the last frame to show remains, so set sprite status = 0 (not alive)
RETURN RTS ; return
ALIVE LDA $1588,x ;A:0100 X:0007 Y:0001 D:0000 DB:03 S:01EF P:envMXdiZCHC:0276 VC:077 00 FL:623
AND #$04 ;A:0100 X:0007 Y:0001 D:0000 DB:03 S:01EF P:envMXdiZCHC:0308 VC:077 00 FL:623
PHA ;A:0100 X:0007 Y:0001 D:0000 DB:03 S:01EF P:envMXdiZCHC:0324 VC:077 00 FL:623
JSL $01802A ; update position based on speed values
JSL $018032 ; interact with other sprites
LDA $1588,x ;A:254B X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0684 VC:085 00 FL:623
AND #$04 ;A:2504 X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0716 VC:085 00 FL:623
BEQ IN_AIR ;A:2504 X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0732 VC:085 00 FL:623
STZ $AA,x ;A:2504 X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0748 VC:085 00 FL:623
PLA ;A:2504 X:0007 Y:0007 D:0000 DB:03 S:01EE P:envMXdizcHC:0778 VC:085 00 FL:623
BRA ON_GROUND ;A:2500 X:0007 Y:0007 D:0000 DB:03 S:01EF P:envMXdiZcHC:0806 VC:085 00 FL:623
IN_AIR PLA ;A:2500 X:0007 Y:0006 D:0000 DB:03 S:01EB P:envMXdiZcHC:0316 VC:085 00 FL:4955
BEQ WAS_IN_AIR ;A:2504 X:0007 Y:0006 D:0000 DB:03 S:01EC P:envMXdizcHC:0344 VC:085 00 FL:4955
LDA #$0A ;A:2504 X:0007 Y:0006 D:0000 DB:03 S:01EC P:envMXdizcHC:0360 VC:085 00 FL:4955
STA $1540,x ;A:25FF X:0007 Y:0006 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0376 VC:085 00 FL:4955
WAS_IN_AIR LDA $1540,x ;A:25FF X:0007 Y:0006 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0408 VC:085 00 FL:4955
BEQ ON_GROUND ;A:25FF X:0007 Y:0006 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0440 VC:085 00 FL:4955
STZ $AA,x ;A:25FF X:0007 Y:0006 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0456 VC:085 00 FL:4955
ON_GROUND
LDA $1588,x ; | if sprite is in contact with an object...
AND #$03 ; |
BEQ DONT_UPDATE ; |
LDA $157C,x ; | flip the direction status
EOR #$01 ; |
STA $157C,x ; /


DONT_UPDATE JSL $01A7DC ; check for mario/sprite contact
BCC RETURN_24 ; (carry set = contact)
LDA $1490 ; \ if mario star timer > 0 ...
BNE HAS_STAR ; / ... goto HAS_STAR
LDA $7D ; \ if mario's y speed < 10 ...
CMP #$10 ; } ... sprite will hurt mario
BMI GOOB_WINS ; /

MARIO_WINS JSR SUB_STOMP_PTS ; give mario points
JSL $01AA33 ; set mario speed
JSL $01AB99 ; display contact graphic
LDA $140D ; \ if mario is spin jumping...
ORA $187A ; } ... or on yoshi ...
BNE SPIN_KILL ; / ... goto SPIN_KILL
LDA #$20 ; \ ... time to show defeated sprite = $20
STA $1558,x ; /
RETURN_24 RTS ; return

GOOB_WINS LDA $1497 ; \ if mario is invincible...
ORA $187A ; } ... or mario on yoshi...
ORA $15D0,x ; | ...or sprite being eaten...
BNE RETURN2 ; / ... return
JSR SUB_GET_DIR ; \ set new sprite direction
TYA ; }
STA $157C,x ; /
JSL $00F5B7 ; hurt mario
RETURN2 RTS ; return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; spin and star kill (still part of above routine)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

STAR_SOUNDS dcb $00,$13,$14,$15,$16,$17,$18,$19

SPIN_KILL LDA #$04 ; \ status = 4 (being killed by spin jump)
STA $14C8,x ; /
LDA #$1F ; \ set spin jump animation timer
STA $1540,x ; /
JSL $07FC3B ; show star animation
LDA #$08 ; \ play sound effect
STA $1DF9 ; /
RTS ; return
HAS_STAR LDA #$02 ; \ status = 2 (being killed by star)
STA $14C8,x ; /
LDA #$D0 ; \ set y speed
STA $AA,x ; /
JSR SUB_HORZ_POS ; get new direction
LDA KILLED_X_SPEED,y ; \ set x speed based on 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


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

;frame 1, frame 2, squashed, star killed (2 bytes each)
TILE_SIZE dcb $02,$02,$02,$02,$00,$00,$02,$02
GOOMB_HORIZ_DISP dcb $00,$00,$00,$00,$00,$08,$00,$00
GOOMB_VERT_DISP dcb $00,$00,$00,$00,$08,$08,$00,$00
GOOMB_TILEMAP dcb $88,$88,$88,$88,$38,$38,$88,$88
GOOMB_PROPERTIES dcb $00,$00,$40,$40,$00,$40,$80,$80

GOOMB_GRAPHICS JSR GET_DRAW_INFO
LDA $157C,x ; \ $02 = direction
STA $02 ; /

LDA $14 ;\
LSR A ; |
LSR A ; |
LSR A ; |
CLC ; |
ADC $15E9 ; |
AND #$01 ; |
ASL A
STA $03 ; | $03 = index to frame start (0 or 2)
PHX ; /

LDA $14C8,x
CMP #$02
BNE NO_STAR
LDA #$06
STA $03

NO_STAR LDA $1558,x ; \ if time to show sprite remains > 0...
BEQ NOT_DEAD ; |
LDA #$04 ; | $03 = 4
STA $03 ; /
STX $15E9
NOT_DEAD

LDX #$01 ; run loop 4 times, cuz 4 tiles per frame
LOOP_START_2 PHX ; push, current tile

TXA ; \ X = index of frame start + current tile
CLC ; |
ADC $03 ; |
TAX ; /

PHY ; set tile to be 8x8 or 16x16
TYA ;
LSR A ;
LSR A ;
TAY ;
LDA TILE_SIZE,x ;
STA $0460,y ;
PLY ;

LDA $00 ; \ tile x position = sprite x location ($00) + tile displacement
CLC ; |
ADC GOOMB_HORIZ_DISP,x ; |
STA $0300,y ; /

LDA $01 ; |
CLC ; | tile y position = sprite y location ($01) + tile displacement
ADC GOOMB_VERT_DISP,x ; |
STA $0301,y ; /

LDA GOOMB_TILEMAP,x ; \ store tile
STA $0302,y ; /

PHX ;
LDX $15E9 ;
LDA $15F6,x ; get palette info
PLX ;
ORA GOOMB_PROPERTIES,x ; flip tile if necessary
ORA $64 ; add in tile priority of level
STA $0303,y ; store tile properties

PLX ; \ pull, current tile
INY ; | increase index to sprite tile map ($300)...
INY ; | ...we wrote 1 16x16 tile...
INY ; | ...sprite OAM is 8x8...
INY ; | ...so increment 4 times
DEX ; | go to next tile of frame and loop
BPL LOOP_START_2 ; /

PLX ; pull, X = sprite index
LDY #$FF ; \ we've already set 460 so use FF
LDA #$01 ; | A = number of tiles drawn - 1
JSL $01B7B3 ; / don't draw if offscreen
RTS ; return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; points routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; routines below can be shared by all sprites. they are ripped from original
; SMW and poorly documented
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $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 ; /

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B817 - horizontal mario/sprite check - shared
; Y = 1 if mario left of sprite??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;org $03B817 ; Y = 1 if contact

SUB_GET_DIR 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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $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_HB 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

NOP


Der obige Code ist vom bereits existierenden Classic Goomba, auffindbar im Spritetoolordner

Wie ihr seht, will ich nur Code hinzufügen

Was der Jumpgumba macht:

Er ist ein Goomba aus SMB...nur das er halt nach 4 Schrittten(? Sowas halt, aso nicht permanent!) springt...nur weiß ich halt nicht wie ich das anstellen soll!

Ich hoffe jemand, der mir dabei helfen kann, hilft mir auch folgendes zutun:

(Hinweis: Bei Extra sind glaub ich zumindestens, komplizierte Sachen, die sind nicht so wichtig! Ich will lieber simple bearbeiten können!)

- Ein Bowserfeuerball-spuckenden Rex Extra: Extraanimation für das Spucken
- Extra: Ihr kennt doch Eating/Creating Block? Die sollen automatisch laufen und Magikoopa Magic auf euch schießen( Creating genau auf euch, Eating etwas daneben) Wie beim Orginal wenn CreatingBlock zu Ende kreiiert hat, fällt er nach unten und "stirbt" (ist im Dissassembly aber schon drinnen)

Also aufjeden Fall würde ich gerne den Rex selbst hinkriegen, nur bräuchte ich halt ein gutes Beispiel (siehe Jumpgoomba), WIE man sowas editiert!

Danke im Vorraus für Hilfe
Wie kritisch man doch gegenüber dem System wird, wenn man älter wird...
geschrieben am 07.02.2011 15:21:31
( Link )
Mit dem Sprungcode könnte ich helfen. Ihn genau nach 4 Schritten springen zu lassen, wird schwierig, aber mit einem Timer geht das auch.

Du musst dafür einen Timer verwenden ($14 funktioniert), und den Y-Speed verändern, wenn er bei einer bestimmten Zahl angelangt ist (bzw. durch eine Zahl teilbar ist). Das könnte so ausehen:

Code
LDA $14
AND #$3F ; 01, 03, 0F, 1F, 3F und 7F gehen
BNE NichtSpringen
LDA $1588,x ; Und wenn der Gumba nicht
AND #$04 ; am Boden ist,
BEQ NichtSpringen ; auch nicht springen.
LDA #$E0 ; Speed
STA $AA,x
NichtSpringen:


Füg den Code am besten am Anfang ein, also zwischen GOOMB_CODE_START und GOOMB_GRAPHICS.
geschrieben am 07.02.2011 15:26:43
( Link )
Naja... also deine Sachen sind schon etwas Komplizierter... Ich weiß nicht genau wie das Läuft, aber auf jeden fall wirst du (glaub ich) für den Fire Rex einen Generator machen müssen, der Bowser Fireballs generiert.
Dasselbe für den Eating creating Block, nur weiß ich nicht, ob es möglich ist, die Sprites neben Mario zielen zu lassen...

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 07.02.2011 16:43:17
( Link )
@WYE Ich probiere es gleich mal aus Könntest du mir auch erklären, weshalb es genau dort stehen muss

@Auroros Ich verstehe deine Antwort nicht ganz:

1) Wenn man IM ORGINAL die Eating/Creating Schlange aktiviert, bewegt die sich unabhängig weiter...was ich lediglich will, ist dass du nicht darauf stehen muss, dass sie sich automatisch dann bewegt.

2) Das mit dem Rex kann auch nciht sein, denn es gibt auch einen Generator im Spiel, dass was ich brauche ist ein Code, der Rex Fireballs "shooten" lässt, siehe "Custom Shooter". Das Problem ist, ich weiß bei Sprites einfach nie, wo ich den Code einfügen muss

Edit:WYE ich glaube es funktioniert nicht, okay es crasht nix oder so, aber Sprite springt anscheinend garnicht oder vielleicht nur einen Pixel...hast du vielleicht eine Lösung hierfür?
Wie kritisch man doch gegenüber dem System wird, wenn man älter wird...
geschrieben am 07.02.2011 19:52:31
( Link )
Ich weiß nicht ob E0 als speed ausreicht, aber du kannst ja einfach mal probieren mehr zu setzen (z.B. B0).
Ansonsten kannst du ein "INC $19" an der Stelle einfügen an der er springen soll soll, in dem Fall z.B. zwischen STA $AA,x und dem Branch, um zu sehen ob das überhaupt ausgeführ wird.
geschrieben am 07.02.2011 21:04:54
( Link )
Wow was passiert den mit Mario O.@ Der wird ja nach Feuerblume total farbgeraped

Danke RL, hbas mit einer höheren Zahl probiert, und er "springt" auch, aber bleibt abrupt in der Luft stehen Kann das evtl. mit dem Goomba selbst zurun haben? Sieht da vielleicht irgendjemand, was man ändern sollte, damit der "hoch" springt?

Edit: Zomg ich habs tatsächlich selbstgefixt haha Aber der Sprite springt andauernd...sieht lustig aus^^

(Nur eine schnelle Frage: Kann man auhc, ähnlich wie bei Custom Block, an MArios Aktionen den Sprite beeinflussen? Zum Beispiel immer wenn Mario nicht den Boden berührt springen die, oder wenn Mario eine andere Y Position hat oder sowas)
Wie kritisch man doch gegenüber dem System wird, wenn man älter wird...
geschrieben am 07.02.2011 21:28:26
( Link )
Code
LDA $77          ;Player blocked
AND #$04 ;SxxMUDLR, #$04 -> D, also Mario auf dem Boden
BNE MSpringt
"Code hier"
MSpringt:


Sollte funktionieren, das nimmst du dann anstatt des frame counter checks.
Und wenns nicht geht hab ich BEQ und BNE vertauscht. Und wenns dann nicht geht hab ich mich vertan.
geschrieben am 08.02.2011 14:48:45
( Link )
Also ich meinte das so, das man Sprites einen Generator einbauen kann, der nach einer bestimmten Zeit eine Sprite generiert
Ein Beispiel dafür ist der Custom Thwomp Boss, Der immer eine Sprite generiert, wenn er auf dem Boden landet
Das muss man dann "nur" noch mit einer Zeitangabe angeben, in welchem Takt er das macht und fertig... aber ich bin mir nicht sicher... das ist alles Theorie...

PS: ich schlage eine Verwichtigung vor, für alle, die Sprites modifizieren wollen, und sich so, hier Hilfe holen können, um nicht den ASM und HEX Thread zu zumüllen
Ich würde nämlich auch gerne ein paar Sachen modifizieren und will nicht damit den ASM und HEX thread zu müllen

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