Original Metroid movement code (A3:EC11): LDX $0E54 ;Metroid's index STZ $12 STZ $14 LDA $0F7E, X ;Metroid Y position SEC SBC $0E32 ;Variable use. Probably Samus's Y position... or her head's Y position. LSR A LSR A STA $13 AND #$2000 BEQ BRANCH_ALPHA LDA $14 ORA #$FFC0 ;Set to negative if right of Samus STA $14 BRANCH_ALPHA: LDA $0FAC, X ;Y subpixel speed, I think SEC SBC $12 STA $0FAC, X LDA $0FAE, X ;Y pixel speed SBC $14 STA $0FAE, X BMI BRANCH_BETA CMP #$0003 ;Cap at 3 pixels per frame BCC BRANCH_GAMMA LDA #$0003 BRA BRANCH_DELTA BRANCH_BETA: CMP #$FFFD ;Or -3 pixels per frame BCS BRANCH_GAMMA LDA #$FFFD BRANCH_DELTA: STA $0FAE, X STZ $0FAC, X BRANCH_GAMMA: LDA $0FAC, X STA $12 LDA $0FAE, X STA $14 LDX $0E54 JSL $A0C786 ;Enemy Y Movement + collision detection BCC BRANCH_EPSILON LDX $0E54 STZ $0FAC, X ;Stop if collided with wall STZ $0FAE, X BRANCH_EPSILON: LDX $0E54 STZ $12 STZ $14 LDA $0F7A, X ;Metroid X position SEC SBC $0AF6 ;Samus's X position LSR A ;and more of the same for the X position LSR A STA $13 AND #$2000 BEQ BRANCH_ZETA LDA $14 ORA #$FFC0 STA $14 BRANCH_ZETA: LDA $0FA8, X ;Metroid X subpixel speed SEC SBC $12 STA $0FA8, X LDA $0FAA, X ;Metroid X pixel speed SBC $14 STA $0FAA, X BMI BRANCH_THETA CMP #$0003 BCC BRANCH_IOTA LDA #$0003 BRA BRANCH_KAPPA BRANCH_THETA: CMP #$FFFD BCS BRANCH_IOTA LDA #$FFFD BRANCH_KAPPA: STA $0FAA, X STZ $0FA8, X BRANCH_IOTA: LDA $0FA8, X STA $12 LDA $0FAA, X STA $14 LDX $0E54 JSL $A0C6AB ;Enemy X movement + collision detection BCC BRANCH_LAMBDA LDX $0E54 STZ $0FA8, X ;Stop if collided with wall STZ $0FAA, X BRANCH_LAMBDA: RTS Ice beam dodge: a(h) = - c1*h + c2 a(l) = - c3*l + c4 a(h,l) = (c2 - c1*h) * (c4 - c3*l) c2 = 6 blocks c1 = Max a = A a(h) = A*(h-4 blocks) a(l) = (l-8 blocks) Horizontal h = |ym - yb| l = |xm - xb| dx = 0 dy = 7F (FF if ym - yb < 0) Vertical h = |xm - xb| l = |yb - ym| dx = 7F (FF if xm - xb < 0) dy = 0 (400 - (h in pixels)) / 4 --> 4202 (800 - (l in pixels)) / 8 --> 4203 4216 / B = Acceleration --> 4202 Diagonal \ h*(sqrt(2)) = |xm - xb - ym + yb| l*(sqrt(2)) = |xm - xb + ym - yb| dx = 5A (DA if xm - xb - ym + yb < 0) dy = DA (5A if xm - xb - ym + yb < 0) Diagonal / h*(sqrt(2)) = |xm - xb + ym - yb| l*(sqrt(2)) = |xm - xb - ym + yb| dx = 5A (DA if xm - xb + ym - yb < 0) dy = 5A (DA if xm - xb + ym - yb < 0) (400*sqrt(2) - (h*sqrt(2))) / 8 --> 4202 (800*sqrt(2) - (l*sqrt(2))) / 10 --> 4203 4216 / B = Acceleration --> 4202 dx --> 4203 Old XAccel + 4216 --> New XAccel - if dx is negative dy --> 4203 Old YAccel + 4216 --> New YAccel - if dy is negative XKAS CODE START org $A3EC11 PHY LDX $0E54 ;Metroid's index LDA $0F7E, X ;Metroid Y position SEC SBC $0E32 ;Variable use. Probably Samus's Y position... or her head's Y position. SEC BMI $01 CLC ROR A PHA LDA $0F7A, X ;Metroid X position SEC SBC $0AF6 ;Samus's X position SEC BMI $01 CLC ROR A PHA JSR IceBeamDodge ;On stack: Return address ($01), X Acc ($03), Y Acc ($05) BRANCH_ZETA: STZ $14 PLA STA $13 BPL $06 XBA ORA #$FF00 STA $14 LDA $0FA8, X ;Metroid X subpixel speed SEC SBC $12 STA $0FA8, X LDA $0FAA, X ;Metroid X pixel speed SBC $14 BMI BRANCH_THETA CMP #$0005 BCC BRANCH_IOTA LDA #$0005 BRA BRANCH_KAPPA BRANCH_THETA: CMP #$FFFB BCS BRANCH_IOTA LDA #$FFFB BRANCH_KAPPA: STZ $0FA8, X BRANCH_IOTA: STA $0FAA, X STZ $14 PLA STA $13 BPL $06 XBA ORA #$FF00 STA $14 LDA $0FAC, X ;Y subpixel speed, I think SEC SBC $12 STA $0FAC, X STA $12 LDA $0FAE, X ;Y pixel speed SBC $14 BMI BRANCH_BETA CMP #$0005 ;Cap at 5 pixels per frame BCC BRANCH_GAMMA LDA #$0005 BRA BRANCH_DELTA BRANCH_BETA: CMP #$FFFB ;Or -5 pixels per frame BCS BRANCH_GAMMA LDA #$FFFB BRANCH_DELTA: STZ $0FAC, X BRANCH_GAMMA: STA $0FAE, X STA $14 JSL $A0C786 ;Enemy Y Movement + collision detection LDX $0E54 BCC BRANCH_EPSILON STZ $0FAC, X ;Stop if collided with wall STZ $0FAE, X BRANCH_EPSILON: LDA $0FA8, X STA $12 LDA $0FAA, X STA $14 JSL $A0C6AB ;Enemy X movement + collision detection BCC BRANCH_LAMBDA LDX $0E54 STZ $0FA8, X ;Stop if collided with wall STZ $0FAA, X BRANCH_LAMBDA: PLY RTS padbyte $FF : pad $A3ECDC org $A3F500 IceBeamDodge: TDC PHA ;Y placeholder PHA ;X placeholder. On stack: X temp ($01), Y temp ($03) Return address ($05), X Acc ($07), Y Acc ($09) LDY #$0008 BeamCheckLoop: LDA $0C18,Y BMI ActiveProjectile SkipBeam: DEY DEY BPL BeamCheckLoop PLA CLC ADC $05,S STA $05,S PLA CLC ADC $05,S STA $05,S RTS ActiveProjectile: BIT #$0F00 BNE SkipBeam BIT #$0002 BEQ SkipBeam ;Ok, so now I know there's a live ice beam shot somewhere LDA $0C04,Y BEQ VerticalShot CMP #$0005 BMI $04 SEC SBC #$0005 ;So now 0 = up/down, 1 = upright/downleft, 2 = right/left, 3 = downright/upleft, 4 = up/down BEQ VerticalShot DEC BEQ DiagShotURDL DEC BEQ HorizontalShot DEC BEQ DiagShotDRUL VerticalShot: LDA #$0099 STA $12 LDA $0F7E,X SEC SBC $0B78,Y PHA LDA $0F7A,X SEC SBC $0B64,Y PHA ;Stack check: h ($01), l ($03), X temp ($05), Y temp ($07) Return address ($09), X Acc ($0A), Y Acc ($0E) JSR SwapSignsIfNegative BRA CalculateAccel HorizontalShot: LDA #$9900 STA $12 LDA $0F7A,X SEC SBC $0B64,Y PHA LDA $0F7E,X SEC SBC $0B78,Y PHA JSR SwapSignsIfNegative BRA CalculateAccel DiagShotURDL: LDA #$9292 STA $12 LDA $0F7E,X SEC SBC $0B78,Y PHA LDA $0F7A,X SEC SBC $0B64,Y PHA CLC ADC $03,S STA $01,S SEC SBC $03,S SEC SBC $03,S STA $03,S LDA $01,S JSR SwapSignsIfNegative BRA CalculateAccel DiagShotDRUL: LDA #$1292 STA $12 LDA $0F7A,X SEC SBC $0B64,Y PHA LDA $0F7E,X SEC SBC $0B78,Y PHA CLC ADC $03,S STA $03,S SEC SBC $01,S SEC SBC $01,S STA $01,S JSR SwapSignsIfNegative CalculateAccel: LDA $0C04,Y BEQ AddOffset CMP #$0006 BPL AddOffset LDA $03,S SEC SBC #$0020 BRA $06 AddOffset: LDA $03,S CLC ADC #$0020 PHY BMI $04 EOR #$FFFF INC CLC ADC #$0070 BMI EndCalc SEP #$20 STA $4202 REP #$21 LDA $03,S BMI $04 EOR #$FFFF INC ADC #$0070 BMI EndCalc SEP #$20 STA $4203 NOP NOP NOP LDA $4217 LSR STA $4202 LDA $12 AND #$7F STA $4203 LDA $13 AND #$7F NOP LDY $4216 STA $4203 REP #$21 TYA BIT $11 BPL $04 EOR #$FFFF INC ADC $07,S STA $07,S LDA $4216 BIT $12 BPL $04 EOR #$FFFF INC ADC $09,S STA $09,S EndCalc: PLY PLA PLA JMP SkipBeam SwapSignsIfNegative: BPL $07 LDA $12 EOR #$8080 STA $12 RTS XKAS CODE END