Allgemeine Hex- und ASM-Fragen

geschrieben am 07.04.2012 14:08:07
( Link )
Zitat von WYE:
Versuch mal, folgendes direkt nach dem Main-Label einzufügen:

Code

PHP : REP #$20 ; \
LDA $010B ; | Wenn wir in Level 0D sind,
CMP #$000D ; | so weitermachen wie geplant
BEQ .continue ; /
PLP ; \
LDA $7B ; | Ansonsten den überschriebenen
BPL + ; | Code wiederherstellen
EOR #$FF : INC A ; | und zurück zum SMW-Code springen
+ JML $00D637 ; /
.continue
PLP


LDA $010B ; | Wenn wir in Level 0D sind,

was muss ich ändern, damit das im level 0C ist?
geschrieben am 07.04.2012 14:25:36
( Link )
Ups. Na ja, such mal nach der Zahl 000D, das ist die Level-Nummer.
geschrieben am 07.04.2012 14:37:29
( Link )
Zitat von WYE:
Ups. Na ja, such mal nach der Zahl 000D, das ist die Level-Nummer.

Code
PHP : REP #$20   ; \
LDA $010B ; | Wenn wir in Level 0D sind,
CMP #$000D ; | so weitermachen wie geplant
BEQ .continue ; /
PLP ; \
LDA $7B ; | Ansonsten den überschriebenen
BPL + ; | Code wiederherstellen
EOR #$FF : INC A ; | und zurück zum SMW-Code springen
+ JML $00D637 ; /
.continue
PLP

verstehe ich das jetzt falsch, oder muss ich anstatt LDA $010B jetzt LDA $000C hinschreiben?
geschrieben am 07.04.2012 14:39:05
( Link )
ach ich sehs

das CMP #$000D muss ich dann ja anscheinend zu CMP #$000C machen^^ (das soll ja im level C sein^^)
geschrieben am 07.04.2012 16:53:57
( Link )
YAY es funktioniert!
Danke WYE!!

Die Demo ist jetzt fast fertig^^
geschrieben am 14.04.2012 17:28:13
( Link )
Im Moment versuche ich grade ein bisschen wieder in ASM reinzukommen. Nur hab ich folgendes Problem:
Beim Autoscroll kann ich links/rechts rausfliegen und sterbe dabei.
Nun versuche ich das zu umgehen, indem ich Marios inscreen Position ändere.
Hier das Codeschnipsel:
Code

[...]
REP #$20 ;16-Bit Modus Ahoi
LDA $7E ;X-Position von Mario auf dem sichtbaren Bereich ($0000=Links;$FFFF=Rechts)
CMP #$0800 ;Vergleiche mit X-Pos (8 Pixel vom linken Rand weg)
BCS SkipBorderL ;Wenns größer ist, dann überspringe das darauffolgende
LDA #$0800 ;Lade $0800 in A
STA $7E ;Und setze die X-Position auf A
SkipBorderL:
SEP #$20 ;16-Bit Modus zum kentern bringen
[...]

Nur funktioniert das leider nicht so, wie ich das will und ich sterbe immernoch, wenn ich am linken Rand nach links drücke.
Tutorials: ExAnimation | YouTube: W4mp3 | Twitter: https://twitter.com/SMWW4mp3
geschrieben am 14.04.2012 17:46:56
( Link )
So... ich habe mich mit ASM auseinander gesetzt...
Und miserabel versagt ^^
So, ich brauche jetzt mal für 3 Codes hilfe:
Nummer 1: Ein Block, der Mario groß macht und das für 15 Münzen.
Problem: Die Münzen werden nicht abgezogen, Generell funktioniert es nur wenn Mario neben dem Block steht, egal, was ich mache.
Code:
Code
db $42

JMP MarioBelow : JMP MarioAbove : JMP MarioSide : JMP SpriteV : JMP SpriteH : JMP MarioCape : JMP MarioFireBall




MarioAbove:
LDA $0DBF ;Marios Münzen
CMP #$0F ;werden Verglichen mit 15
BCS Label1 ; Wenn 15 oder mehr, branch
RTL ; Weniger, zurück zum Spiel

Label1:
LDA #$01 ;Lädt eine Eins
STA $19 ;Macht mario groß
LDA $0DBF ;Lädt Marios Münzen Zähler
SEC ;Set Carry Flag
SBC #$0F ;Sutrahiert 15
STA $0DBF ;Zurück in den Münzen Zähler
RTL ;Ende des Codes

MarioBelow:
MarioSide:
SpriteH:
SpriteV:
MarioCape:
MarioFireBall:
RTL


Block Nummer 2: Ein Block, der Mario zu Feuer Mario macht, wenn er 80 Bonus Sterne hat, und diese dann abzieht
Problem: So ziemlich das selbe, wie beim ersten Block.
Code:
Code
db $42

JMP MarioBelow : JMP MarioAbove : JMP MarioSide : JMP SpriteV : JMP SpriteH : JMP MarioCape : JMP MarioFireBall

MarioBelow:
LDA $0F48 ;Lädt Marios Star Counter
CMP #$50 ;vergleicht ihn mit 80
BCS Label2 ;Gleich oder größer = branch
RTL ;Andernfalls, ende


Label2:
LDA #$03 ;Lädt eine 3
STA $19 ;Macht Mario zu Feuer Mario
LDA $0F48 ;Lädt marios Starcounter
SEC ;Set Carry Flag
SBC #$50 ;redzuziert ihn um 80
STA $0F48 ;Plaziert ihn dahin, wo er hinsoll
RTL ;Ende des Codes

MarioAbove:
MarioSide:
SpriteV:
SpriteH:
MarioCape:
MarioFireBall:
RTL


Block Nummer 3: Ein Block, der Mario zu Cape Mario macht, wenn er nach links schaut, und ihm ansonsten nur eine Münze gibt
Problem: Selbes wie oben, nur dass ich möchte, dass der Block danach zu einem brauen benutzt Block wird.
Code:
Code
db $42

JMP MarioBelow : JMP MarioAbove : JMP MarioSide : JMP SpriteV : JMP SpriteH : JMP MarioCape : JMP MarioFireBall

MarioBelow:
LDA $76 ;Lädt die Richtung, in die Mario guckt
CMP #$00 ;Vergleicht sie mit 00 (00 = Links)
BEQ Label1 ;Wenn es 00 ist, branch
INC $0DBF ;andernfalls: Gebe Mario eine Münze
RTL ;Ende des Codes

Label1:
LDA #$02 ;Lädt 2
STA $19 ;Plaziert sie in Marios Status
RTL ;Code Ende

MarioAbove:
MarioSide:
SpriteV:
SpriteH:
MarioCape:
MarioFireBall:
RTL

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 14.04.2012 18:20:54
( Link )
Zitat von W4mp3:
;X-Position von Mario auf dem sichtbaren Bereich ($0000=Links;$FFFF=Rechts)

Öh, da stimmt was nicht. Der Bildschirm ist nur 256 Pixel breit, also kann die X-Position von Mario auf dem Bildschirm auch nur von 0 bis FF gehen. Bei Adressen wie $94 macht der 16-Bit-Modus tatsächlich Sinn, aber auch nur bis #$1F00 oder so (das High Byte ist die Nummer des Screens, in dem Mario sich befindet, und davon gibt's nun mal keine 256).

Auroros: Sieht eigentlich alles richtig aus. Kannst du dein Problem noch mal genauer beschreiben?
geschrieben am 14.04.2012 18:32:31
( Link )
Zitat von WYE:

Auroros: Sieht eigentlich alles richtig aus. Kannst du dein Problem noch mal genauer beschreiben?


Nun, Mario muss nur den Block von der Seite Berühren, damit der Effekt des Blockes aktiviert wird.
Und beim ersten werden Marios Münzen nicht abgezogen.
Ich will aber, dass sie z.B. Turnblöcke mit Items Funktionieren. (Letztendlich muss ich diese Blöcke entweder verstecken (Wie der Block, der, wenn man nach Links guckt, einem eine Feder gibt)
Die Shop Blocks halt auch in etwa so, nur, dass sie keine "braunen" Blöcke werden.

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 14.04.2012 19:12:59
( Link )
Zitat von WYE:
Zitat von W4mp3:
;X-Position von Mario auf dem sichtbaren Bereich ($0000=Links;$FFFF=Rechts)

Öh, da stimmt was nicht. Der Bildschirm ist nur 256 Pixel breit, also kann die X-Position von Mario auf dem Bildschirm auch nur von 0 bis FF gehen. Bei Adressen wie $94 macht der 16-Bit-Modus tatsächlich Sinn, aber auch nur bis #$1F00 oder so (das High Byte ist die Nummer des Screens, in dem Mario sich befindet, und davon gibt's nun mal keine 256).
[...]


Arrr, ich meinte $0000 = Links; $00FF = Rechts, wenn ich links aus dem Bildschrirm fliege ist das $FFFF.
Theoretisch will ich das hier erzeugen:

Nur klappt das bei $7E nicht und $94 ist ganz falsch, da passiert genauso wenig.

*20 minuten Später und ein wenig rumprobiert*

Oh, war doch einfacher als gedacht, brauchte da sogar kein 16-bit Mode.
Code

[...]
LDA $15 ;Lese Contollerdaten aus
AND #$02 ;Kurz schauen, ob links gedrückt wird
BEQ SkipL ;falls nicht, überspringen
LDA $7E ;Marios X-Position auf dem Bildschirm
CMP #$09 ; \wenn X <= 9
BCC SkipL ; /dann überspringen
LDA #$E0 ;\Setze marios X-Geschwindigkeit
STA $7B ;/
SkipL:
[...]

Das einfachste fällt mir nie ein
Die restlichen Ränder sind analog dazu
Tutorials: ExAnimation | YouTube: W4mp3 | Twitter: https://twitter.com/SMWW4mp3
geschrieben am 26.04.2012 17:14:12
( Link )
Hallo!
Ich habe folgendes Problem:
Ich habe mir den "Larry Boss" von dahnamics gesaugt und etwas umgeschrieben (klappt alles super & so).
Nun möchte ich das er bei einer Kante einfach wieder umdreht, anstatt runter zu laufen .. Aber keine Ahnung wie x.x

Hier mal der Code:
Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Larry, by dahnamics
;;
;; Special thanks to: miOr, icegoom, Heisanevilgenius, Cheeseum, Newmoon, Dispari Scuro, Yoshicookiezeus, and SMTKO (the game of course)
;;
;; Based on the following sprites:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SMAS SMB2 Mouser, by Dispari Scuro
;;
;; Special thanks to: miOr, icegoom, Heisanevilgenius, Cheeseum, Newmoon
;;
;; Based on the following sprites:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Bomb Brother, by mikeyk
;;
;; Description: Similar to the Boomerang Bro, but he throws bombs instead.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shy Guy, by mikeyk
;;
;; Description: A Shy Guy with many available configurations.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

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 Larry's stun duration
Larry_Hits = $F ; This is how many hits it takes to kill Larry (default == 3)

RAM_HitCount = $1534
SPRITE_TO_GEN dcb $3,$4,$2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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

SPRITE_GRAVITY = $20

X_SPEED dcb $DF,$20,$D6,$24,$D2,$28,$CE,$2C,$CA,$32,$C6,$36,$C2,$3A,$BE,$3E,$BA,$43,$B6,$47,$B2,$4B,$B2,$4B,$B2,$4B,$B2,$4B,$B2,$4B
KILLED_X_SPEED dcb $F0,$10
TIME_TILL_THROW dcb $68,$69

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

JSR SUB_OFF_SCREEN_HB ; handle off screen situation

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 $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 EXTRA_PROP_1,x ; don't stay on ledges if bit is set
AND #$02 ;
BEQ FALLING ;

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

Walk_Normal:
LDA $151C,x ;
TAY ;
LDA $1540,x ;
BEQ X_TIME ;
LDA X_SPEED,y ; | set y speed
STA $B6,x ; /
BRA IN_AIR

X_TIME
LDA $1528,x ; \ set x speed based on total HP
ASL
CLC
ADC $157C,x ; and direction
TAY

;LDY $157C,x ; \ set x speed based on direction
LDA X_SPEED,y ; |
STA $B6,x ; /

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

LDA Invuln_Timer,x ; \
CMP #$00 ; | Ignore if Larry 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 DONE_WITH_SPEED ; |
LDA $151C,x
INC A
AND #$03
STA $151C,x

DONE_WITH_SPEED JSL $018032 ; interact with sprites
JSL $01A7DC ; check for mario/sprite contact (carry set = contact)

LDA $1490 ; \ if mario star timer > 0, goto HAS_STAR
BNE HAS_STAR ; / NOTE: branch to RETURN_24 to disable star killing

NO_CONTACT JSR KILL_BOOMERANGS
RTS ; return
KILL_BOOMERANGS
RTS

RETURN_24 RTS ; final 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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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 #$50
JSR CODE_01BF6A
LDX $15E9
LDA $00
STA $00AA,y
LDA $01
STA $00B6,y
;RETURN1 RTS
; 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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; aiming routine
; input: accumulator should be set to total speed (x+y)
; output: $00 = y speed, $01 = x speed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CODE_01BF6A: STA $01
PHX ;\ preserve sprite indexes of Magikoopa and magic
PHY ;/
JSR SUB_VERT_POS ; $0E = vertical distance to Mario
STY $02 ; $02 = vertical direction to Mario
LDA $0E ;\ $0C = vertical distance to Mario, positive
BPL CODE_01BF7C ; |
EOR #$FF ; |
CLC ; |
ADC #$01 ; |
CODE_01BF7C: STA $0C ;/
JSR SUB_HORZ_POS ; $0F = horizontal distance to Mario
STY $03 ; $03 = horizontal direction to Mario
LDA $0F ;\ $0D = horizontal distance to Mario, positive
BPL CODE_01BF8C ; |
EOR #$FF ; |
CLC ; |
ADC #$01 ; |
CODE_01BF8C: STA $0D ;/
LDY #$00
LDA $0D ;\ if vertical distance less than horizontal distance,
CMP $0C ; |
BCS CODE_01BF9F ;/ branch
INY ; set y register
PHA ;\ switch $0C and $0D
LDA $0C ; |
STA $0D ; |
PLA ; |
STA $0C ;/
CODE_01BF9F: LDA #$00 ;\ zero out $00 and $0B
STA $0B ; | ...what's wrong with STZ?
STA $00 ;/
LDX $01 ;\ divide $0C by $0D?
CODE_01BFA7: LDA $0B ; |\ if $0C + loop counter is less than $0D,
CLC ; | |
ADC $0C ; | |
CMP $0D ; | |
BCC CODE_01BFB4 ; |/ branch
SBC $0D ; | else, subtract $0D
INC $00 ; | and increase $00
CODE_01BFB4: STA $0B ; |
DEX ; |\ if still cycles left to run,
BNE CODE_01BFA7 ;/ / go to start of loop
TYA ;\ if $0C and $0D was not switched,
BEQ CODE_01BFC6 ;/ branch
LDA $00 ;\ else, switch $00 and $01
PHA ; |
LDA $01 ; |
STA $00 ; |
PLA ; |
STA $01 ;/
CODE_01BFC6: LDA $00 ;\ if horizontal distance was inverted,
LDY $02 ; | invert $00
BEQ CODE_01BFD3 ; |
EOR #$FF ; |
CLC ; |
ADC #$01 ; |
STA $00 ;/
CODE_01BFD3: LDA $01 ;\ if vertical distance was inverted,
LDY $03 ; | invert $01
BEQ CODE_01BFE0 ; |
EOR #$FF ; |
CLC ; |
ADC #$01 ; |
STA $01 ;/
CODE_01BFE0: PLY ;\ retrieve Magikoopa and magic sprite indexes
PLX ;/
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
STUNNED_X_SPEED:
dcb $20,$DF

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 #$F0 ; Set stunned timer
STA $1564,x

INC $1528,x

LDA $1528,x

cmp #Larry_Hits
bcc Return3

LDA #$02 ; Kill Larry
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

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

;TILEMAP dcb $46,$4A,$7F,$00
; dcb $46,$5A,$2F,$00
; dcb $48,$4A,$7F,$00
; dcb $48,$5A,$2F,$00

TILEMAP

dcb $00,$02,$20,$22 ; walk 1: head left, head right, bottom left, bottom right
dcb $04,$06,$24,$26 ; walk 2: head left, head right, bottom left, bottom right
dcb $08,$0A,$28,$2A ; throw1: head left, head right, bottom left, bottom right
dcb $0C,$0E,$2C,$2E ; throw2: head left, head right, bottom left, bottom right
dcb $40,$42,$60,$62 ; hurt 1: head left, head right, bottom left, bottom right
dcb $48,$4A,$68,$6A ; hurt 2: head left, head right, bottom left, bottom right
dcb $40,$42,$60,$62 ; dying : head left, head right, bottom left, bottom right
dcb $40,$42,$60,$62 ; dying2: head left, head right, bottom left, bottom right

dcb $00,$02,$20,$22 ; walk 1: head left, head right, bottom left, bottom right
dcb $04,$06,$24,$26 ; walk 2: head left, head right, bottom left, bottom right
dcb $08,$0A,$28,$2A ; throw1: head left, head right, bottom left, bottom right
dcb $0C,$0E,$2C,$2E ; throw2: head left, head right, bottom left, bottom right
dcb $40,$42,$60,$62 ; hurt 1: head left, head right, bottom left, bottom right
dcb $48,$4A,$68,$6A ; hurt 2: head left, head right, bottom left, bottom right
dcb $40,$42,$60,$62 ; dying : head left, head right, bottom left, bottom right
dcb $40,$42,$60,$62 ; dying2: head left, head right, bottom left, bottom right
dcb $40,$42,$60,$62 ; dying2: head left, head right, bottom left, bottom right

HORZ_DISP


dcb $F8,$08,$F8,$08
dcb $F8,$08,$F8,$08
dcb $F8,$08,$F8,$08
dcb $F8,$08,$F8,$08
dcb $F8,$08,$F8,$08
dcb $08,$F8,$08,$F8
dcb $F8,$08,$F8,$08
dcb $F8,$08,$F8,$08


dcb $08,$F8,$08,$F8
dcb $08,$F8,$08,$F8
dcb $08,$F8,$08,$F8
dcb $08,$F8,$08,$F8
dcb $08,$F8,$08,$F8
dcb $F8,$08,$F8,$08
dcb $08,$F8,$08,$F8
dcb $08,$F8,$08,$F8

VERT_DISP dcb $F0,$F0,$00,$00
dcb $EF,$EF,$FF,$FF
dcb $F0,$F0,$FF,$FF
dcb $F0,$F0,$FF,$FF
dcb $F0,$F0,$00,$00
dcb $F0,$F0,$00,$00
dcb $00,$00,$F0,$F0
dcb $00,$00,$F0,$F0

dcb $F0,$F0,$00,$00
dcb $EF,$EF,$FF,$FF
dcb $F0,$F0,$FF,$FF
dcb $F0,$F0,$FF,$FF
dcb $F0,$F0,$00,$00
dcb $F0,$F0,$00,$00
dcb $00,$00,$F0,$F0
dcb $00,$00,$F0,$F0

PROPERTIES dcb $3F,$3F,$3F,$3F ; 00 = no flip
dcb $3F,$3F,$3F,$3F ; 40 = horizontal flip
dcb $3F,$3F,$3F,$3F ; 80 = vertical flip
dcb $3F,$3F,$3F,$3F ; C0 = horizontal and vertical flip
dcb $3F,$3F,$3F,$3F
dcb $7F,$7F,$7F,$7F
dcb $BF,$BF,$BF,$BF
dcb $BF,$BF,$BF,$BF

dcb $7F,$7F,$7F,$7F
dcb $7F,$7F,$7F,$7F
dcb $7F,$7F,$7F,$7F
dcb $7F,$7F,$7F,$7F
dcb $7F,$7F,$7F,$7F
dcb $3F,$3F,$3F,$3F
dcb $FF,$FF,$FF,$FF
dcb $FF,$FF,$FF,$FF


SUB_GFX:
JSR GET_DRAW_INFO ; after: Y = index to sprite tile map ($300)
; $00 = sprite x position relative to screen boarder
; $01 = sprite y position relative to screen boarder

LDA $1602,x
STA $03 ; | $03 = index to frame start (0 or 4)

LDA $14 ; Frame Counter
LSR A ; \
LSR A ; | Change every 8 frames
LSR A ; |
;LSR A ; |
;LSR A ; |
LSR A ; /

AND #$01 ; 2 walking "frames"
ASL A ; x2
ASL A ; x4 (sprite is made up of 4 tiles)
STA $03

LDA $14C8,x ; If killed...
CMP #$02
BNE NOT_DEAD
LDA $03
CLC
ADC #$18 ; ...set killed frame
STA $03
;LDA $15F6,x ; \
;ORA #$80 ; | ...flip vertically
;STA $15F6,x ; /
BRA DONE_WALKING

NOT_DEAD:
LDA Invuln_Timer,x ; \ If sprite is stunned...
CMP #$00 ; |
BEQ No_Stun ; |
LDA $03 ; |
CLC ; |
ADC #$10 ; | ...use stun frames.
STA $03 ; /
BRA DONE_WALKING

No_Stun:
LDA RAM_ThrowTimer,x ; \ If throw timer...
;CMP #$60 ; | ...is 60 or more...
CMP #$50 ; | ...is 50 or more...
BCC DONE_WALKING ; |
LDA $03 ; |
CLC ; | ...use throwing frames.
ADC #$08 ; |
STA $03 ; /
;BRA DONE_WALKING

DONE_WALKING:
LDA $157C,x ; \ $02 = sprite direction
STA $02 ; /
BNE LOOP_START
LDA $03
CLC
ADC #$20 ; skip some tiles if facing the other way
STA $03

LOOP_START:
PHX ; push sprite index
LDX #$03 ; loop counter = (number of tiles per frame) - 1

LOOP_START_2:
PHX ; push current tile number
;TXA ; \ X = index to horizontal displacement
;ORA $03 ; / get index of tile (index to first tile of frame + current tile number)
;TAX

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

PHY ; \
TYA ; |
LSR A ; |
LSR A ; |
TAY ; | Set tile to be 16x16 ($02)
LDA #$02 ; |
STA $0460,y ; |
PLY ; /

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

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

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

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

PLX ; \ pull, X = current tile of the frame we're drawing
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 #$03 ; | A = number of tiles drawn - 1
JSL $01B7B3 ; / don't draw if offscreen
RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; routines below can be shared by all sprites. they are ripped from original
; SMW and poorly documented
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

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

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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_VERT_POS
; This routine determines if Mario is above or below the sprite. It sets the Y register
; to the direction such that the sprite would face Mario
; It is ripped from $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
CLC
ADC #$18
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 $0E ;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 SPR_L11 ;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
SPR_L11 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 ; 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


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



Habe in folgenden Zeilen das hier gefunden:

Code
JUMP_BIRDO                    
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 EXTRA_PROP_1,x ; don't stay on ledges if bit is set
AND #$02 ;
BEQ FALLING ;

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

Walk_Normal:
LDA $151C,x ;
TAY ;
LDA $1540,x ;
BEQ X_TIME ;
LDA X_SPEED,y ; | set y speed
STA $B6,x ; /
BRA IN_AIR


Muss ich da etwas verändern? Hoffe mir kann einer helfen!
geschrieben am 26.04.2012 18:31:18
( Link )
Ich hab keine Ahnung, aber probier mal aus was passiert wenn du diesen Teil des Codes löscht.

Code
 NO_OBJ_CONTACT      LDA EXTRA_PROP_1,x      ; don't stay on ledges if bit is set
AND #$02 ;
BEQ FALLING ;

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 ;
geschrieben am 26.04.2012 18:46:08
( Link )
Gar nichts.
geschrieben am 26.04.2012 19:31:06
( Link )
Sieht aus, als ob das "Extra Property Byte 1" in der CFG-Datei fürs Runterfallen bzw. Umdrehen zuständig ist.
geschrieben am 26.04.2012 19:46:54
( Link )
Zitat von WYE:
Sieht aus, als ob das "Extra Property Byte 1" in der CFG-Datei fürs Runterfallen bzw. Umdrehen zuständig ist.


Hmm .. ich werde es ausprobieren und das Ergebnis mit einen Edit verkünden.
Muss mir erstmal ein Programm herunterladen um CFG-Dateien zu öffnen.

Edit:

Was genau muss ich jetzt damit machen?

Code
01
36
00 0D 3F 03 19 44
00 00
larry.asm
0
geschrieben am 26.04.2012 20:54:18
( Link )
Zitat von Bladey:
Muss mir erstmal ein Programm herunterladen um CFG-Dateien zu öffnen.

Warum? Ist cfg_editor.exe nicht bei Sprite Tool dabei?
geschrieben am 26.04.2012 21:11:33
( Link )
Zitat von WYE:
Zitat von Bladey:
Muss mir erstmal ein Programm herunterladen um CFG-Dateien zu öffnen.

Warum? Ist cfg_editor.exe nicht bei Sprite Tool dabei?


Schon möglich.. Fail sag ich da nur ..
Ich habe es einfach mit ASMPad geöffnet .. Das hatte ich noch am Rechner.

Edit: Das Problem ist gelöst. Danke für die Versuche
geschrieben am 05.05.2012 0:36:54
( Link )
ich hätte mal wieder eine frage...
Ist es möglich die Statusbar zu deaktiviren? (also IRQ zu deaktiviren?)
möchte layer 3 über den ganzen Bildschirm nutzen können
WAS, WIE, WO???? Ne, Ne ich bin nicht die Signatur ...
Ich putze hier nur.

Mein Hack:
<!-- m --><a class="postlink" href="http://www.youtube.com/user/conankun88#p/a/u/0/8vdcyGylrg0">http://www.youtube.com/user/conankun88# ... vdcyGylrg0</a><!-- m -->
geschrieben am 05.05.2012 8:21:08
( Link )
Meinst du das hier?

http://www.smwcentral.net/?p=viewthread&t=25824
geschrieben am 05.05.2012 14:05:24
( Link )
Meinst du etwa so:

(Das "Statusbar" oben ist auf Layer 3 auf dem Nebeldingens)
Falls du die Statusbar nur für ein Level nicht brauchst, dann nimm den Patch:
http://www.smwcentral.net/download.php? ... pe=patches [* [Xkas] Statusbar scanline hack]
Tutorials: ExAnimation | YouTube: W4mp3 | Twitter: https://twitter.com/SMWW4mp3