lorom ;TODO list: ALL enemy stuff, fix echoes appearance (maybe), prevent too-fast scroll bugs. Tests if landing needs to adjust 0AF6 ;Change grapple check to work with new grapple flags ;Allows picking up item drops, may do other (hopefully benificial) things org $90F2C5 print "Boundary: ",pc GrappleCheck: LDA $0CF4 print "Boundary: ",pc org $90F0C8 print "Boundary: ",pc DW GrappleCheck ;$844B5-$84538 print "Boundary: ",pc org $90C4B5 print "Boundary: ",pc PHP REP #$30 LDA $09D2 STA $12 LDA $8F BIT $09B8 BEQ + JSR CancelCheck BRA ++ + STZ $16 LDA $8B BIT $09B8 BEQ + INC $16 + LDA $8F BIT $09BA BEQ +++ LDA $09D2 INC A CMP #$0005 ;No more x-ray scope! BMI + -- LDA #$0000 + STA $09D2 - ASL A TAX JSR ($C539,X) ; $84539 IN ROM BCC + INC $09D2 LDA $09D2 CMP #$0005 BMI - BRA -- + LDA $16 BEQ + LDA $09D2 STA $0A04 BRA ++ + STZ $0A04 ++ LDA $09D2 CMP $12 BNE + +++ LDA $0AAA CMP #$0002 BEQ ++ INC A STA $0AAA BRA ++ + LDA #$0001 STA $0AAA ++ PLP RTS print "Boundary: ",pc org $A0C0AE print "Boundary: ",pc PHP REP #$30 PHX PHY PHB PHK PLB LDX #$0000 TXY LDA $12 BPL + LDX #$0004 EOR #$FFFF INC A STA $12 + LDA $14 BPL + INX INX EOR #$FFFF INC A STA $14 + SEP #$20 XBA LDA $12 CMP $14 BCS ++ ;Branch if $14 is not bigger than $12 XBA INX ++ STZ $4204 REP #$20 STA $4205 PHX TYX LDA #$00B8 STA $14 JSR GetAngleAdjustment PLX BIT.w AngleSign-1,X BPL + EOR #$FFFF INC + CLC ADC #$0080 ;0000 + 00C0 = 01, 0000 - 0140 = FF, 0000 + 0040 = 00, 0000 - 0040 = 00 STA $12 LDA.w AngleStart-1,X AND #$FF00 CLC ADC $12 XBA AND #$00FF PLB PLY PLX PLP RTL GetAngleAdjustment: LDA $4214 LDY #$0009 - DEY ASL BCC - - DEY BEQ + LSR INX INX BRA - + XBA AND #$00FF ASL TAY LDA.w AngleIndexes,X STA $12 LDA [$12],Y RTS AngleStart: DB $40,$80,$40,$00,$C0,$80,$C0,$00 AngleSign: DB $00,$80,$80,$00,$80,$00,$00,$80 AngleIndexes: ; DW $FFFC,$FFF4,$FFE4,$FFC4,$FF84,$FF04,$FE04,$FC04 DW $FC04,$FE04,$FF04,$FF84,$FFC4,$FFE4,$FFF4,$FFFC EndCheck: print "Boundary: ",pc org $B8FC04 print "Boundary: ",pc incbin AnglesT.bin print "Boundary: ",pc org $90DD6F print "Boundary: ",pc JSL PreGrappleMain print "Boundary: ",pc org $90DD69 print "Boundary: ",pc DW CallGrappleArmCannon print "Boundary: ",pc org $94ACFE print "Boundary: ",pc GrappleMotion: PHB PHK PLB LDA $0D26 BEQ ++ CLC ADC $0CFA XBA SEP #$21 SBC $0CFB STA $0D56 BEQ + JSR SwingCollisionCheck BCS ++ ;Carry set on collision, cleared on no collision + REP #$21 LDA $0D26 ADC $0CFA ;Carry cleared because no collision STA $0CFA LDA $0D26 CLC ADC $0D44 STA $0D44 ++ LDA $0D00 CLC ADC $0CFD XBA AND #$00FF CMP #$0008 BPL + LDA #$0008 + SEC SBC $0CFE BEQ NoCollision2b JSR LengthCollisionCheck BCS AdjustSpeed ;It'll branch if there *is* a collision. ;print "Start of Angular Momentum conservation: ", pc LDA $0CFE ADC #$0014 STA $4202 LDA $0D26 PHP BPL + EOR #$FFFF INC + STA $4203 JSR ConserveAngularMomentum ;JSR and RTS cycles waste time while waiting for hardware results. :) LDA $4214 PLP ;Also does REP #$20 for me BPL + EOR #$FFFF INC + STA $0D26 BRA AdjustSpeed NoCollision2b: LDA $0D00 CLC ADC $0CFD CMP #$0800 BPL + LDA #$0800 + STA $0CFD AdjustSpeed: LDA $0CF6 XBA SEC SBC $0CFD PHP BPL + EOR #$FFFF INC + ; PHA ;Not used atm. Might enable if I want a different fraction. LSR LSR ;Hmm... This doesn't seem right. Need to tinker with the fraction. ; PLX ;Just getting rid of trash (well, it's trash now) on the stack PLP BPL + EOR #$FFFF INC + CLC ADC $0D00 CLC BPL + SEC + ROR STA $0D00 LDA $0CF4 ;Check if in water w/o gravity LSR LDA $0D26 BEQ GrappleGravity PHP BPL + EOR #$FFFF INC + STA $16 BCS + LSR ;Bigger fraction if not in water ADC $16 LSR ADC $16 LSR ADC $16 + LSR ;Smaller fraction if in water ADC $16 LSR ADC $16 LSR CLC ADC $16 LSR ADC $16 LSR DEC PLP BPL + EOR #$FFFF INC + STA $0D26 ;Now for gravity... GrappleGravity: LDA $0D45 AND #$00FF ASL TAX LDA $A0B443,X ASL CLC ADC $A0B443,X ASL ASL ASL AND #$FF00 XBA BPL + ORA #$FF00 + CLC ADC $0D16 SEC SBC $0D08 STA $12 LDA $A0B3C3,X ASL CLC ADC $A0B3C3,X ASL ASL ASL AND #$FF00 XBA BPL + ORA #$FF00 + CLC ADC $0D18 SEC SBC $0D0C STA $14 JSL CalculateVectorLength TAY LDA #$0800 STA $4204 SEP #$20 TYA STA $4206 REP #$21 LDA $A0B3C3,X ;TODO: Currently, Gravity's effect on vertical displacement is .1 pix/frame^2. Might be tweaked later. LSR LSR LSR LSR BIT #$FE00 ;This is imprecise, but it'll work for most formulas so it's fine BEQ + ORA #$FE00 ;Ditto + CLC ADC $0D00 STA $0D00 LDY $4214 LDA $A0B443,X JSL SignedMultiplication BNE + CPX #$0100 BEQ +++ BMI ++ DEC $0D26 BRA +++ + BPL ++ ;Small increase for gravity to aid movement when near center DEC DEC ++ SEC ;INC and CLC at the same time ADC $0D26 STA $0D26 ;After gravity, I'm *done* +++ JSR SamusGrappleAngle JSL $9BBD95 ;Er. *Now* I'm done PLB RTL ConserveAngularMomentum: XBA LDY $4216 STY $12 STA $4203 CLC STZ $14 LDA $13 ADC $4216 STA $4204 LDA $0CFD CLC ADC $0D00 CMP #$0800 BPL + LDA #$0800 STZ $0D00 + STA $0CFD XBA SEP #$21 ADC #$13 STA $4206 PHA TDC LDA $12 XBA REP #$20 NOP ORA $4216 ;Guaranteed to be under 100 XBA STA $4204 SEP #$20 PLA LDY $4214 STA $4206 TDC TYA XBA NOP RTS print "Boundary: ",pc org $9094F7 ;Start of grapple-scroll code print "Boundary: ",pc LDA $0CFB AND #$00FF STA $12 LDA $0D26 BPL Skip90 LDA $12 EOR #$0080 STA $12 LDA $0D26 EOR #$FFFF INC Skip90: BIT #$F000 BEQ + LDA #$0FFF + ASL ASL ASL PHA JSL $86C272 JSR ScrollSetupNum JSR HorizontalScroll PLA ; ASL JSL $86C26C JSR ScrollSetupNum JSR VerticalScroll JSL $80A528 ; $2528 IN ROM JSL $80A731 ; $2731 IN ROM BRA Skip92 print "Boundary: ",pc org $909563 print "Boundary: ",pc Skip92: print "Boundary: ",pc org $90DD21 print "Boundary: ",pc DW TurningGrapple print "Boundary: ",pc org $90DD33 print "Boundary: ",pc DW TurningGrapple print "Boundary: ",pc org $90DD35 print "Boundary: ",pc DW TurningGrapple ;Should be DONE print "Boundary: ",pc org $90DD3D print "Boundary: ",pc PHP REP #$30 LDA $0CF4 BEQ + JSL GrappleMain + LDA $09D2 ASL A TAX JSR ($DD61, X) ; $85D61 IN ROM PLP RTS print "Boundary: ",pc org $9BC490 print "Boundary: ",pc LDA $0CF4 BPL NoConnection LDA $8B AND #$0C00 BEQ +++ BIT #$0800 BNE + LDA $0CF6 DEC DEC CMP #$0010 BPL ++ LDA #$0010 BRA ++ + LDA $0CF6 INC INC CMP #$006F BMI ++ LDA #$006E ++ STA $0CF6 +++ PLA PLB JML $90B80D ;Hooray for 'bad' coding NoConnection: BNE + STZ $0CD0 ;Works, but still need palette fix on item cancel LDA $8F ORA $0E00 ;Check if fire was pressed last frame BIT $09B2 BEQ + PHB PHK PLB JMP CreateShot + RTL ;$86B86-$86BF1 print "Boundary: ",pc org $90EB86 print "Boundary: ",pc LDA $0CF4 BNE + LDA #$0007 JSL $809049 ;Augh. Playing this disables spin jump sounds, not playing this causes too much grapple sounds. LDA #$EB52 STA $0A5C LDA #$2C0F STA $7EC6B0 STA $7EC6B2 JMP $EB52 + JSR $EEE7 JSR $87BD LDA $0CF4 BPL + LDA $0CF6 LSR STA $4204 LDA #$0A00 STA $4205 SEP #$20 JSR DrawTargetLength BEQ + JSR $BAFC BRA ++ + JSL $9BC036 ; $DC036 IN ROM ++ JSR $8A4C ; $80A4C IN ROM JSR $85E2 ; $805E2 IN ROM LDA $0AAC AND #$000F BEQ + JSR $C663 ; $84663 IN ROM + JSL $9BCC00 ; $DBFA5 IN ROM LDA $0CFE BEQ + JSL $94AFBA ; $A2FBA IN ROM + RTS ;Arm cannon graphic print "Boundary: ",pc org $90C5F7 print "Boundary: ",pc JSR ACGHook ;Prevent high speed falling through ground print "Boundary: ",pc org $909256 print "Boundary: ",pc JSR HorizontalHighSpeedCheck print "Boundary: ",pc org $90E647 print "Boundary: ",pc JSR MirrorDirection print "Boundary: ",pc org $90E626 print "Boundary: ",pc JSR MirrorDirection print "Boundary: ",pc org $90FAD0 ;Just need free space. I think this is the best spot for free space. print "Boundary: ",pc ;An alternative to 0DC6! MirrorDirection: STA $0DC6 STA $0D1E RTS DrawTargetLength: NOP NOP NOP LDA $4214 DEC BPL ++ LDA #$09 ++ STA $7EC6B0 LDA $4216 DEC BPL ++ LDA #$09 ++ STA $7EC6B2 REP #$20 LDA $0A1F AND #$00FF CMP #$0016 RTS ACGHook: CMP #$0004 BNE ACGNormal LDA $0CF4 BPL ACGSet LDA $0A1F AND #$00FF CMP #$0016 BEQ ACGSet LDA #$0000 RTS ACGSet: LDA #$0001 RTS ACGNormal: LDA $C7D9,X RTS HorizontalScroll: ADC $0AF8 SEC SBC $090F STA $14 LDA $0AF6 SBC $0911 CLC ADC $16 JSR ScrollSub ADC $090F STA $090F LDA $16 STA $0DA2 ADC $0911 STA $0911 RTS VerticalScroll: ADC $0AFC SEC SBC $0913 STA $14 LDA $0AFA SBC $0915 CLC ADC $16 JSR ScrollSub ADC $0913 STA $0913 LDA $16 STA $0DA6 ADC $0915 STA $0915 RTS ScrollSetupNum: STZ $16 STZ $14 AND #$FFFF ;It's stupid, I know. But there's no TEST A. BPL Skip93 DEC $16 Skip93: STA $15 LDA $14 CLC RTS ScrollSub: SEC SBC #$0080 BPL ScrollRight LSR ROR $14 LSR ROR $14 ORA #$C000 CMP #$FFF0 BEQ ScrollCapped BPL Skip94 LDA #$FFF0 BRA ScrollCapped ScrollRight: LSR ROR $14 LSR ROR $14 CMP #$0010 BMI Skip94 LDA #$0010 ScrollCapped: STZ $14 Skip94: STA $16 CLC LDA $14 RTS CallGrappleArmCannon: JSL $9BC490 RTS ;org $90DD TurningGrapple: LDA $0CF4 BEQ + JSL GrappleMain - RTS + LDA $0B5E BEQ - JMP $DD3D CancelCheck: LDA $0A1F CMP #$0016 BEQ + LDA $0CF4 BMI ++ + STZ $0A04 STZ $09D2 ++ STZ $0CF4 RTS HorizontalHighSpeedCheck: LDA $0DBC CMP #$000F BMI + LDA #$000E + RTS print "Boundary: ",pc org $94AFBA ;(Grapple segment and point drawing. Not sure what calls it, but don't need to call it myself. Leave where it is) print "Boundary: ",pc PHB PHK PLB LDA $0CFB AND #$00FF EOR #$0080 ASL A TAX STZ $1A STZ $1C LDA $A0B443, X ASL A ASL A ASL A BPL BRANCH_ALPHA DEC $1C ;Makes $1D = #$FF BRANCH_ALPHA: STA $1B STZ $1E STZ $20 LDA $A0B3C3, X ASL A ASL A ASL A BPL BRANCH_BETA DEC $20 BRANCH_BETA: STA $1F LDA $0CFA AND #$8000 LSR A STA $26 EOR $0CFA AND #$4000 EOR #$4000 ASL A ORA $26 STA $26 LDA $0D1A SEC SBC $0911 SEC SBC #$0004 STA $14 STZ $12 LDA $0CFE BMI BRANCH_GAMMA ;uh. How? STA $4204 SEP #$20 LDA #$08 STA $4206 REP #$20 LDA $0D1C SEC SBC $0915 SEC SBC #$0004 STA $18 STZ $16 LDA $4214 BMI BRANCH_GAMMA ;Again. How? ; AND #$000F ;Should be redundant. I'll delete it, just in case I have unusually long grapple beams. ; SEC ; SBC #$0001 ;DEC would be faster. And from the looks of it, I *don't* want this. STA $28 ; JSL $808111 ;Improve random number generation, I hope BRANCH_THETA: LDA $14 ORA $18 AND #$FF00 BNE BRANCH_ZETA ;Branch if offscreen PHX JSL $808111 AND #$0003 CLC ADC #$3A21 ;Get 1 of 4 grapple beam graphics TAY JSR $B0AA ; This routine's good enough, let's leave it alone PLX DEX DEX DEC $28 BPL BRANCH_THETA BRANCH_ZETA: JSR $B14B ; Grapple Point Display B. A was deleted, B alone is good enough. BRANCH_GAMMA: PLB RTL print "Boundary: ",pc org $9BCC00 print "Boundary: ",pc DEC $0D3E BPL ++ LDA #$0005 STA $0D3E LDA $0D40 CLC ADC #$0200 CMP #$8A00 BMI + LDA #$8200 + STA $0D40 LDX $0330 LDA #$0020 STA $D0, X LDA $0D40 STA $D2, X LDA #$009A STA $D4, X LDA #$6200 STA $D5, X TXA CLC ADC #$0007 STA $0330 ++ SEP #$21 LDA $0CFB BPL + SBC #$80 + SBC #$40 BPL + EOR #$FF INC + LDY #$8220 CMP #$10 BMI + LDY #$8A20 CMP #$2F BMI + LDY #$9220 + REP #$20 CPY $0D42 BEQ + STY $0D42 LDX $0330 LDA #$0080 STA $D0, X STY $D2, X LDA #$009A STA $D4, X LDA #$6210 STA $D5, X TXA CLC ADC #$0007 STA $0330 + LDA $0CF4 CMP #$4000 BNE + LDA $0CD0 CMP #$0078 BPL + INC $0CD0 + RTL CreateShot: LDA #$0020 STA $0CCC LDA $0A04 BEQ + STZ $0A04 STZ $09D2 + STZ $0CF8 LDA #$0001 STA $0CD0 LDA #$0005 JSL $80903F LDA $0A1C ASL ASL ASL TAX LDA $91B62D,X AND #$00FF STA $16 LDA $91B62C,X AND #$00FF BIT #$00F0 BEQ + PLB RTL + STZ $0D06 STZ $0D0A STZ $0CFE STA $0D34 ASL TAX LDA #$4000 STA $0CF4 LDA #$EB86 STA $0A5C LDA #$7F91 STA $7EC1BE LDA #$0040 STA $0CF6 SEP #$20 LDA $0DB2 ORA $0DB5 BEQ + LDA $0DB2 XBA LDA $0DB5 BRA ++ + LDA $0DB6 XBA LDA $0DB9 ++ TAY LDA $0DAA ORA $0DAD BEQ + LDA $0DAA XBA LDA $0DAD BRA ++ + LDA $0DAE XBA LDA $0DB1 ++ REP #$21 ADC $C0DB,X BMI NegativeX CMP #$0F00 BMI StoreXSpeed LDA #$0F00 BRA StoreXSpeed NegativeX: CMP #$F100 BPL StoreXSpeed LDA #$F100 StoreXSpeed: STA $0D22 TYA CLC ADC $C0EF,X BMI NegativeY CMP #$0F00 BMI StoreYSpeed LDA #$0F00 BRA StoreYSpeed NegativeY: CMP #$F100 BPL StoreYSpeed LDA #$F100 StoreYSpeed: STA $0D24 LDA $C104,X STA $0CFA LDA $C122, X ;Initial grapple point X offset from Samus CLC ADC $0AF6 STA $0D08 ;X position of grapple point STA $0D02 LSR LSR LSR LSR STA $0D0E LDA $0A1F AND #$00FF DEC BEQ WalkingRunning LDA $C14A,X CLC ADC $0AF6 STA $0D1A ;X position of grapple start LDA $0AFA SEC SBC $16 PHA CLC ADC $C136, X STA $0D0C ;Y position of grapple point STA $0D04 LSR LSR LSR LSR STA $0D10 PLA CLC ADC $C15E, X STA $0D1C ;Y position of grapple start JMP GrappleCollisionDetection WalkingRunning: LDA $C19A,X CLC ADC $0AF6 STA $0D1A ;X position of grapple start LDA $0AFA SEC SBC $16 PHA CLC ADC $C186, X STA $0D0C ;Y position of grapple point STA $0D04 LSR LSR LSR LSR STA $0D10 PLA CLC ADC $C1AE, X STA $0D1C ;Y position of grapple start JMP GrappleCollisionDetection PreGrappleMain: LDA $09B6 ORA $09B4 AND $8F BEQ + JMP JumpTransition + LDA $0CF4 BNE + JMP FallingTransition + LDA $8B AND #$0C00 BEQ + BIT #$0800 BNE ++ LDA $0CF6 DEC DEC CMP #$0010 BPL +++ LDA #$0010 BRA +++ ++ LDA $0CF6 INC INC CMP #$006F BMI +++ LDA #$006E +++ STA $0CF6 + LDA $0B3F AND #$0004 BEQ GrappleConnected LDA $0D26 BPL + EOR #$FFFF INC + BIT #$F000 BEQ + LDA #$0FFF + ASL ASL ASL ASL AND #$FF00 ORA $0CFE ADC #$0018 STA $4202 LDA #$1800 ;Todo: Find a good number for this (minimum value for blue suit) CMP $4216 BMI GrappleConnected LDA #$0004 TRB $0B3F BRA GrappleConnected GrappleMain: LDA $0CF4 BMI GrappleConnected JMP GrappleFiring GrappleConnected: JSL $A09E9A BCC + ;Branch if no effect, no branch if effect on grapple beam BVS ++ ;Branch if Caught on enemy, no branch if stop beam. ; BRA + ;This is a temporary 'fix'. Will be deleted later BRA FallingTransition + JSL $94A91F BCC FallingTransition ;Branch if no effect block, no branch if effect beam BVC FallingTransition ;Branch if stop beam, no branch if caught on block LDA $0D08 AND #$FFF0 ORA #$0008 STA $0D08 LDA $0D0C AND #$FFF0 ORA #$0008 STA $0D0C ;Move grapple point to current block. LDA #$8002 ;Set Connected and Connection: Grapple Block TSB $0CF4 ++ ; LDA #$0006 ; JSL $809049 ; Play grapple-attached sound. Not sure if this should be played or not. LDA $0A1F AND #$00FF CMP #$0016 BEQ ++ LDY $0CF4 LDA #$001E TRB $0CF4 ;Delete old connections and check again next frame TYA BIT #$0006 BNE + JSL CalculateGrappleLengthA CMP #$0088 BPL +++ STA $0CFE TXA LSR XBA STA $0CFA RTL ; BIT #$0008 ; BEQ +++ ; JMP GrapplePullEnemy ;I think I'll have the enemy code do it instead + JMP GrapplePullSamus ++ JML GrappleMotion +++ STZ $0CF4 RTL ;V = w x r, Vx = w * r * sin (r + Dir * 40), Vy = w * r * (-cos (r + Dir * 40)) ;100 u = 2pi w, w = 29 u = (20 + 8 + 1) u, 101001 - LDA, ASL, ASL, ADC, ASL, ASL, ASL, ADC ;LSR speed before starting ;w = rad/frame(0000 - 0400 * 29 = 0000 - A400), r = radius (0CFE + #14) (14 - 94) ;(w * r)/256 * sin/cos = value from 0000 to 5ED0 (or A130 - 0000 - 5ED0) ;u = 0800 --> 0400, r = 0080 --> 0094, unaltered = 5ED0, goal = 1D0F. Divide by 343/100 (835/256 in decimal) ;unaltered / D * 8 FallingTransition: ;Convert angular speed to linear, set 0A32 to 7, 0A2C to 51(right) or 52(left) ;print "Start of FallingTransition: ",pc STZ $0CF4 STZ $0CF8 LDA $0A1F AND #$00FF CMP #$0016 BNE ++ LDA #$0007 STA $0A32 LDA #$0051 STA $0A2C JSR ConvertSpeedToLinear BEQ +++ BPL + EOR #$FFFF INC INC $0A2C + SEP #$20 STA $0B45 XBA STA $0B42 LDA #$01 STA $0B3C REP #$20 JSR SetNonGrapplePosition ++ RTL +++ LDA $0A1E AND #$0004 BEQ + INC $0A2C + JSR SetNonGrapplePosition RTL SetNonGrapplePosition: print "Break Grapple: ", pc PHB PHK PLB LDA $0D45 AND #$00FF ASL TAX LDY #$0020 LDA $A0B443,X JSL SignedMultiplication CLC ADC $0D1A STA $0AF6 SEC SBC #$0009 STA $12 ADC #$0011 LSR LSR LSR LSR STA $14 LDA $12 LSR LSR LSR LSR STA $12 LDA $A0B3C3,X JSL SignedMultiplication CLC ADC $0D1C STA $0AFA CLC ADC #$000C STA $16 SBC #$0017 LSR LSR LSR LSR STA $18 LDA $07A5 STA $4202 LDA $16 LSR LSR LSR LSR STZ $16 STA $4203 LDA $14 CLC ADC $4216 ASL PHA LDA $12 CLC ADC $4216 ASL JSR BlockTest BVC + INC $16 ;Bottom Left collision + PLA JSR BlockTest LDA $18 STZ $18 BVC + INC $18 ;Bottom Right collision + STA $4203 LDA $14 CLC ADC $4216 ASL PHA LDA $12 CLC ADC $4216 STZ $12 STZ $14 ASL JSR BlockTest BVC + INC $12 ;Top Left collision + PLA JSR BlockTest BVC + INC $14 ;Top Right collision + PLB ;print "PushTests: ", pc LDA $16 AND $18 BNE PushUp LDA $16 AND $12 BNE PushRight LDA $18 AND $14 BNE PushLeft LDA $12 AND $14 BEQ NoPush ;PushDown: LDA $0AFA AND #$FFF0 ORA #$000C STA $0AFA NoPush: RTS PushUp: LDA $0AFA AND #$FFF0 ORA #$0004 STA $0AFA LDA $0B2D LDY $0B36 DEY BNE + EOR #$FFFF INC + INY INY CLC ADC #$FE40 BPL + DEY EOR #$FFFF INC + STA $0B2D RTS PushRight: LDA $0AF6 AND #$FFF0 ORA #$0007 STA $0AF6 LDA #$0180 STA $12 BRA PushSideUp PushLeft: LDA $0AF6 AND #$FFF0 ORA #$0009 STA $0AF6 LDA #$FE80 STA $12 PushSideUp: SEP #$20 LDA $0B42 XBA LDA $0B45 REP #$20 LDY $0A2C CPY #$0019 BEQ + CPY #$001A BNE PushRight-1 EOR #$FFFF INC DEY + CLC ADC $12 BPL + INY EOR #$FFFF INC + STY $0A2C SEP #$20 STA $0B45 XBA STA $0B42 REP #$20 LDA $0B2D LDY $0B36 DEY BNE + EOR #$FFFF INC INY + INY CLC ADC #$FEC0 BPL + DEY EOR #$FFFF INC + STY $0B36 STA $0B2D RTS BTVE: ;Block Test Vertically Extended ;VerticallyExtended: LDA $01,S LSR TAX SEP #$21 LDA $7F6402,X BPL + EOR #$FF INC STA $4203 REP #$20 LDA $01,S SBC $4216 SEC SBC $4216 PLX BRA BlockTest + STA $4203 REP #$21 LDA $01,S ADC $4216 CLC ADC $4216 PLX BlockTest: - PHA TAX LDA $7F0003,X AND #$00F0 LSR LSR LSR LSR TAX BIT.w GrappleBlockTest-1,X BMI + ;Branch if extended block. PLX RTS ;V Set = Solid, V Clear = Air + BVS BTVE ;Extended block. Branch if vertically extended ;HorizontallyExtended: LDA $01,S LSR TAX LDA $7F6401,X AND #$FF00 XBA BPL + ORA #$FF00 + ASL CLC ADC $01,S PLX BRA - ++ JumpTransition: STZ $0CF4 STZ $0CF8 LDY #$0019 STY $0A2C LDY #$0007 ;I'm not sure about this STY $0A32 BIT $09B6 BNE ++ JSR ConvertSpeedToLinear STA $0D26 ;Save it for later LDA $0CFB EOR #$0080 AND #$00FF ASL TAX LDA $A0B3C3,X LDY #$0380 ;TODO: Tweak this till it's reasonable. Jump speed boost out of grapple JSL SignedWordMultiplication PHA LDA $0B2D DEC $0B36 BNE + EOR #$FFFF INC + LDY #$0002 STY $0B36 CLC ADC $01,S BPL + EOR #$FFFF INC DEC $0B36 + STA $0B2D PLA LDY #$0380 LDA $A0B443,X JSL SignedWordMultiplication CLC ADC $0D26 BRA + ++ JSR ConvertSpeedToLinear + BEQ ++ BPL + EOR #$FFFF INC INC $0A2C + CMP #$0700 BPL + STZ $0B3E + LDY #$0160 SEC SBC #$0160 BPL + ADC #$0160 TAY TDC + SEP #$20 STY $0B45 STA $0B45 XBA STA $0B42 TYA STA $0B49 LDA #$01 STA $0B3C REP #$20 JSR SetNonGrapplePosition RTL ++ LDA $0A1E AND #$0004 BEQ + INC $0A2C + JSR SetNonGrapplePosition RTL ;Uses $16. Converts 0D26, 0CFE, and 0CFB into 0B2D, 0B36, and signed X-Speed in A, ready to branch on sign, adjust pose, and put speed into 0B42/0B45 ;See FallingTransition for an example of use ConvertSpeedToLinear: STZ $16 LDA $0D26 BPL + EOR #$FFFF INC DEC $16 + CMP #$147A BMI + LDA #$147A + LSR STA $0D26 ASL CLC ADC $0D26 ASL ASL ASL CLC ADC $0D26 ;($0D26 * 12.5 decimal) XBA STA $4202 LDA $0CFE CLC ADC #$0014 STA $4203 LDA $0CFB CLC ADC #$0040 AND #$00FF BIT $16 BPL + EOR #$0080 + ASL TAX LDA $4216 LSR TAY LDA $A0B3C3,X JSL SignedWordMultiplication STZ $0B36 BPL + EOR #$FFFF INC DEC $0B36 + INC $0B36 INC $0B36 STA $0B2D LDA $A0B443,X JSL SignedWordMultiplication STZ $0B43 RTS CalculateGrappleLengthA: LDA $0AF6 STA $0D1A LDA $0AFA STA $0D1C CalculateGrappleLength: LDA $0D1A SEC SBC $0D08 STA $12 LDA $0D1C SEC SBC $0D0C STA $14 CalculateVectorLength: LDA $12 BPL + EOR #$FFFF INC + PHA LDA $14 BPL + EOR #$FFFF INC + CMP $01,S ;Carry set if Y >= X BCC GrappleLengthX XBA AND #$FF00 TAY PLA JSL $A0C0AE ASL TAX LDA $A0B3C3,X BIT #$00FF BEQ Cardinal BPL Skip06 Skip07: EOR #$FFFF INC Skip06: STY $4204 SEP #$20 STA $4206 REP #$20 NOP NOP NOP NOP NOP NOP LDA $4214 RTL GrappleLengthX: PLA XBA AND #$FF00 TAY JSL $A0C0AE ASL TAX LDA $A0B443,X BIT #$00FF BEQ Cardinal BMI Skip07 BRA Skip06 Cardinal: TYA XBA RTL GrappleFiring: PHB PHK PLB LDA $8B BIT $09B2 BEQ KillShot LDA $0A1C ASL ASL ASL TAX LDA $91B62D,X AND #$00FF STA $16 LDA $91B62C,X AND #$00FF BIT #$00F0 BEQ Branch_Something KillShot: STZ $0CF4 PLB RTL Branch_Something: ASL TAX LDA $0A1F AND #$00FF DEC BEQ + LDA $C14A,X CLC ADC $0AF6 STA $0D1A LDA $0AFA SEC SBC $16 CLC ADC $C15E, X STA $0D1C BRA ++ + LDA $C19A,X CLC ADC $0AF6 STA $0D1A ;X position of grapple start LDA $0AFA SEC SBC $16 CLC ADC $C1AE, X STA $0D1C ;Y position of grapple start ++ JSL CalculateGrappleLength STA $0CFE TXA LSR XBA STA $0CFA LDA $0CFE CMP #$0060 BPL KillShot SEP #$20 LDA $0D22 CLC ADC $0D07 STA $0D07 LDA $0D23 BPL + ADC $0D08 STA $0D08 LDA #$FF BRA ++ + ADC $0D08 STA $0D08 LDA #$00 ++ ADC $0D09 STA $0D09 LDA $0D24 CLC ADC $0D0B STA $0D0B LDA $0D25 BPL + ADC $0D0C STA $0D0C LDA #$FF BRA ++ + ADC $0D0C STA $0D0C LDA #$00 ++ ADC $0D0D STA $0D0D REP #$20 LDA $0D0C LSR LSR LSR LSR STA $0D14 LDA $0D0A LSR LSR LSR LSR STA $0D12 STZ $4204 CMP $0D0E BNE + JMP SameX + BPL MovedRight MovedLeft: LDA $0D14 CMP $0D10 BNE + JMP SameY + SEP #$20 BPL DownLeft UpLeft: LDA $0D04 XBA LDA $0D02 REP #$20 AND #$0F0F STA $4205 SEP #$20 LDA $0D0C XBA LDA $0D08 REP #$20 AND #$0F0F EOR #$0F0F LDY $4214 STA $4205 JMP CompareAngles DownLeft: LDA $0D04 EOR #$0F XBA LDA $0D02 REP #$20 AND #$0F0F STA $4205 SEP #$20 LDA $0D0C XBA LDA $0D08 EOR #$0F REP #$20 AND #$0F0F LDY $4214 STA $4205 BRA CompareAngles MovedRight: LDA $0D14 CMP $0D10 BEQ SameY SEP #$20 BPL DownRight UpRight: LDA $0D04 XBA LDA $0D02 EOR #$0F REP #$20 AND #$0F0F STA $4205 SEP #$20 LDA $0D0C EOR #$0F XBA LDA $0D08 REP #$20 AND #$0F0F LDY $4214 STA $4205 BRA CompareAngles DownRight: LDA $0D04 XBA LDA $0D02 REP #$20 AND #$0F0F EOR #$0F0F STA $4205 SEP #$20 LDA $0D0C XBA LDA $0D08 REP #$20 AND #$0F0F LDY $4214 STA $4205 CompareAngles: NOP NOP NOP NOP NOP NOP CPY $4214 BCS YThenX XThenY: LDA $0D12 STA $0D0E JSL $94A91F BCC SameX BlockAffect: BVS BlockGrapple JMP KillShot YThenX: LDA $0D14 STA $0D10 JSL $94A91F BCS BlockAffect SameY: LDA $0D12 STA $0D0E BRA GrappleCollisionDetection SameX: LDA $0D14 STA $0D10 GrappleCollisionDetection: JSL $94A91F BCS BlockAffect JSL $A09E9A BCC + BVC + LDA $0CFE CLC ADC #$0010 CMP #$006F BMI ++ LDA #$006E ++ STA $0CF6 + PLB RTL BlockGrapple: LDA $0D08 AND #$FFF0 ORA #$0008 STA $0D08 LDA $0D0C AND #$FFF0 ORA #$0008 STA $0D0C ;Move grapple point to current block. LDA #$8002 ;Set Connected and Connection: Grapple Block TSB $0CF4 LDA #$0006 JSL $809049 ; Play grapple-attached sound SetGrappleDefaults: JSL CalculateGrappleLengthA STA $0CFE CLC ADC #$0008 CMP #$006F BMI + LDA #$006E + STA $0CF6 TXA LSR XBA STA $0CFA LDA #$0008 CLC ADC $0CCC STA $0CCC LDA #$0001 TSB $0A64 STZ $0CD0 PLB RTL GrapplePullSamus: JSL CalculateGrappleLengthA STA $0CFE CMP #$0088 BMI + STZ $0CF4 - RTL + TXA LSR XBA STA $0CFA ; LDA $0B2E ; ORA $0B2C LDA $0B36 ;Proper on-ground check? BNE +++ ;Vertical speed: Check for run and length LDA $0D1E ;0B36 still fails when pulling up STZ $0D1E ;don't repeatedly assume to be on ground CMP #$0001 ;FINALLY seems to work BNE ++ ;Branch if still in air ;Ground: LDA $0CFE SEC SBC $0CF6 BMI - XBA LSR LSR CMP #$0800 ;Maximum force Grapple Beam can apply. This may need finetuning. BMI + LDA #$0800 + PHA LDA $0CFB AND #$00FF STA $12 LDA $01,S JSL $86C26C EOR #$FFFF INC CLC ADC $0B57 BPL + STZ $0B58 DEC $0B58 + STA $0B57 PLA JSL $86C272 ; EOR #$FFFF ; INC CLC ADC #$0180 ;Downward force of gravity. This will most likely need finetuning CLC ADC $0B5B BPL + STZ $0B5C DEC $0B5C + STA $0B5B BPL + LDA #$00FF TSB $0B5D + - RTL +++ LDA $0A68 BNE - LDA $8F BIT $09B6 BNE + ++ LDA $0CFE CMP $0CF6 BMI - STZ $0CF6 + PHB PHK PLB LDA $0AF6 SEC SBC $0D08 STA $12 LDA $0AFA SEC SBC $0D0C STA $14 JSL CalculateVectorLength SEP #$21 SBC #$0E CMP #$08 BPL + LDA #$08 + TAY REP #$20 STZ $18 STZ $16 - JSR GrappleVectorBlockCollision TYA CLC BVC + BIT $18 BMI ++ ADC #$0010 TAY DEC $18 BRA - + ADC #$000D JSR GrappleVectorBlockCollision BVS ++ TYA CLC ADC #$001A JSR GrappleVectorBlockCollision BVS ++ TYA CLC ADC #$0028 JSR GrappleVectorBlockCollision BVC SetGrappling BIT $18 BMI ++ DEC $18 DEC $16 TYA SEC SBC #$0010 TAY CMP #$0008 BPL +++ ++ - PLB RTL +++ BIT $18 BPL SetGrappling TYA CLC ADC #$000D JSR GrappleVectorBlockCollision BVS - SetGrappling: LDA $0CFE STY $0CFE LDX $0CF6 BNE + CPY #$006F BMI ++ LDY #$006E ++ STY $0CF6 BRA ++ + CMP $0CF6 BMI + SBC #$000E BIT $18 BPL ++ TYA BIT $16 BPL + SEC SBC #$0008 CMP $0CF6 BPL ++ BRA +++ + CLC ADC #$0008 CMP $0CF6 BMI ++ +++ SBC #$000E CMP #$006F BPL + CMP #$0010 BPL ++ LDA #$0010 BRA ++ + LDA #$006E STA $0CF6 ++ LDA #$0009 STA $0A30 LDY #$00B2 LDA $0A1E BIT #$0004 BEQ + LDY #$00B3 + STY $0A2A PLB RTL GrappleVectorBlockCollision: PHY TAY LDA $A0B443,X JSL SignedMultiplication CLC ADC $0D08 STA $12 LDA $A0B3C3,X JSL SignedMultiplication CLC ADC $0D0C LSR LSR LSR LSR STA $14 SEP #$20 XBA LDA $07A5 REP #$21 STA $4202 LDA $12 LSR LSR LSR LSR CLC ADC $4216 ASL PHX JSR BlockTest PLX PLY RTS GrappleBlockTest: DB $00,$40,$00,$00,$00,$80,$00,$00,$40,$40,$40,$40,$40,$C0,$40,$40 SetGrappleVelocities: LDA $0CFA STA $0D44 XBA AND #$00FF ASL TAX LDY $0B2D LDA $A0B3C3,X JSL SignedWordMultiplication STA $14 ;-Y * cos theta LDA $A0B443,X JSL SignedWordMultiplication ;Y * sin theta STA $16 LDY $0B36 DEY BNE + ;Branch if not moving up EOR #$FFFF INC STA $16 LDA $14 EOR #$FFFF INC STA $14 + LDA $0B44 CLC ADC $0B48 SEP #$20 LDA $0B42 ADC $0B46 REP #$20 XBA TAY LDA $A0B443,X JSL SignedWordMultiplication BIT $0DAA BPL + EOR #$FFFF INC + SEC SBC $14 STA $0D00 LDA $A0B3C3,X JSL SignedWordMultiplication BIT $0DAA BMI + EOR #$FFFF INC + CLC ADC $16 PHP BPL + EOR #$FFFF INC + ASL ASL ASL STA $4204 SEP #$20 LDA $0CFE LSR ADC $0CFE ADC #$30 STA $4206 REP #$20 NOP NOP NOP NOP NOP NOP LDA $4214 ; ASL ;Too much? ASL ADC $4214 ASL ASL PLP BPL Skip71 EOR #$FFFF INC Skip71: STA $0D26 RTL CalculateSamusHead: LDA $0CFB AND #$00FF ASL TAX LDY $0CFE LDA $A0B443,X ;sin x JSL SignedMultiplication CLC ADC $0D08 STA $0D1A LDA $A0B3C3,X ;-cos x JSL SignedMultiplication CLC ADC $0D0C STA $0D1C LDY #$000C LDA $0D45 AND #$00FF ASL TAX LDA $A0B443,X JSL SignedMultiplication CLC ADC $0D1A STA $0D16 LDA $A0B3C3,X JSL SignedMultiplication CLC ADC $0D1C STA $0D18 RTS CheckWater: LDA $09A2 BIT #$0020 BNE + LDA $196E BEQ + LDA $195E BMI + SEC SBC #$0011 CMP $0AFA BPL + LDA #$0001 TSB $0CF4 RTS + LDA #$0001 TRB $0CF4 RTS print "Boundary: ",pc org $9BBD95 print "Boundary: ",pc PHB PHK PLB ; LDA $0D1A ; STA $0D16 ; LDA $0D1C ; STA $0D18 JSR CalculateSamusHead LDA $0D26 BPL + EOR #$FFFF INC A + CMP #$0010 BMI + LDA #$0001 STA $0CF8 BRA ++ + STZ $0CF8 LDA $0D44 CMP $0CFA BNE ++ AND #$FF00 CMP #$8000 BNE ++ LDA $0A96 CMP #$0040 BPL +++ LDA #$0008 STA $0A94 LDA #$0040 STA $0A96 +++ LDX #$0020 BRA + ++ LDA #$000F STA $0A94 LDA $0D45 LSR LSR INC LSR AND #$001F STA $0A96 ASL A TAX + LDA $0D26 BPL + EOR #$FFFF INC A + CMP #$0200 BMI ++ LDA $0A96 CMP #$0040 BMI + LDA #$0010 + CLC ADC #$0020 STA $0A96 ++ LDA $0A1E AND #$00FF CMP #$0004 BEQ ++ LDA $C301, X AND #$FF00 XBA BPL + ORA #$FF00 + CLC ADC $0D1A STA $0AF6 LDA $C302, X AND #$FF00 XBA BPL + ORA #$FF00 BRA + ++ LDA $C2C1, X AND #$FF00 XBA BPL ++ ORA #$FF00 ++ CLC ADC $0D1A STA $0AF6 LDA $C2C2, X AND #$FF00 XBA BPL + ORA #$FF00 + CLC ADC $0D1C STA $0AFA JSR $BE98 ; Sets previous position... prevent scroll bugs? JSR CheckWater PLB RTL print "Boundary: ",pc org $91EF4F ;'Set Samus in grappling pose' routine. Needs: Convert momentum, BD95, print "Boundary: ",pc JSL SetGrappleVelocities JSL $9BBD95 ; $DBD95 IN ROM STZ $0CD0 STZ $0CD6 STZ $0CD8 STZ $0CDA STZ $0CDC STZ $0CDE STZ $0CE0 JSL $91DEBA STZ $0B46 STZ $0B48 STZ $0B2C STZ $0B2E STZ $0B42 STZ $0B44 LDA #$0006 JSL $809049 RTS print "Boundary: ",pc org $94B260 print "Boundary: ",pc SamusGrappleAngle: LDA $8B LDX $0D44 CPX $0CFA BNE LimitedMotion BIT #$0200 BNE DecrementAngle BIT #$0100 BEQ NoChange IncrementAngle: TXA CLC ADC #$0E00 STA $0D44 TDC SEP #$20 LDA #$40 JSR ForwardCollisionCheckSetup LDA #$00FF BRA CollisionCheck LimitedMotion: BPL + BIT #$0200 BEQ IncrementAngle BRA CopyAngle + BIT #$0100 BEQ DecrementAngle CopyAngle: TXA StoreAngle: STA $0D44 NoChange: RTS DecrementAngle: TXA SEC SBC #$0E00 STA $0D44 TDC SEP #$20 LDA #$C0 JSR ForwardCollisionCheckSetup LDA #$0001 CollisionCheck: STA $12 LDX #$0006 SEP #$20 BRA + -- CLC LDA $13 ADC $12 STA $13 - + LDA $0D46,X TAY LDA $13 CLC ADC $0D4E,X REP #$20 PHX JSR GetBlockXY SEP #$20 TDC PLX BCS -- DEX DEX BPL - LDA $13 CLC ADC $0D45 STA $0D45 LDA $13 CLC ADC $0CFB STA $0CFB LDA $13 XBA REP #$20 LSR LSR BIT #$2000 BEQ + ORA #$C000 + CLC ADC $0D26 STA $0D26 RTS AND #$00FF ASL TAX LDY #$0005 LDA $A0B443,X JSL SignedMultiplication CLC ADC $0D1A STA $0D22 LDA $A0B3C3,X JSL SignedMultiplication CLC ADC $0D1C STA $0D24 LDA $12 XBA AND #$00FF ASL TAX LDY #$0028 LDA $A0B443,X JSL SignedMultiplication PHA CLC ADC $0D22 STA $14 LDA $A0B3C3,X JSL SignedMultiplication PHA CLC ADC $0D24 LSR LSR LSR LSR XBA ORA $07A5 STA $4202 LDA $14 LSR LSR LSR LSR CLC ADC $4216 STA $0DC4 STA $18 ASL TAX LDA $7F0003,X AND #$00F0 LSR LSR LSR TAX JSR (GrappleBlockCollision,X) PLA BCS ++ BPL + SEC + ROR ADC $0D24 ASL ASL ASL ASL AND #$FF00 ORA $07A5 STA $4202 PLA CLC BPL + SEC + ROR ADC $0D22 LSR LSR LSR LSR CLC ADC $4216 STA $0DC4 STA $18 ASL TAX LDA $7F0003,X AND #$00F0 LSR LSR LSR TAX JSR (GrappleBlockCollision,X) + LDA $12 RTS ++ PLA LDA $12 RTS GrappleBlockCollision: DW ClearC,SetC,ClearC,ClearC,ClearC,HorizontalExtend,ClearC,ClearC,SetC,SetC,Spike,CrumbleBlock,SetC,VerticalExtend,SetC,BombBlock BombBlock: LDX $0DC4 LDA $7F6401, X AND #$FF00 XBA SEC BMI + ASL A TAX LDA $936B, X JSL $8484E7 ; $204E7 IN ROM + RTS CrumbleBlock: LDX $0DC4 LDA $7F6401, X AND #$FF00 XBA BMI + ASL A TAX LDA $9139, X JSL $8484E7 ; $204E7 IN ROM RTS + AND #$007F ASL A TAY LDA $079F ASL A TAX LDA $92E9, X STA $22 LDA ($22), Y JSL $8484E7 ; $204E7 IN ROM RTS ClearC: CLC RTS Spike: LDX $0DC4 LDA $7F6402,X ASL AND #$01FF TAX JSR ($902B,X) SetC: SEC RTS HorizontalExtend: LDX $0DC4 LDA $7F6401,X AND #$FF00 XBA BPL + ORA #$FF00 + CLC ADC $0DC4 LookupExtension: STA $0DC4 ASL TAX LDA $7F0003,X AND #$00F0 LSR LSR LSR TAX JMP (GrappleBlockCollision,X) VerticalExtend: LDX $0DC4 SEP #$20 LDA $7F6402,X BMI + STA $4203 REP #$21 LDA $0DC4 NOP ADC $4216 BRA LookupExtension + EOR #$FF INC STA $4203 REP #$20 LDA $0DC4 SEC SBC $4216 BRA LookupExtension SixSinAngle: TAX LDA $A0B443,X ASL CLC ADC $A0B443,X ASL AND #$FF00 XBA BPL + ORA #$FF00 + RTS SixCosAngle: LDA $A0B3C3,X ASL CLC ADC $A0B3C3,X ASL AND #$FF00 XBA BPL + ORA #$FF00 + RTS TwoSixSinAngle: AND #$00FF ASL TAX LDA $A0B443,X ASL CLC ADC $A0B443,X ASL ASL CLC ADC $A0B443,X ASL AND #$FF00 XBA BPL + ORA #$FF00 + RTS TwoSixCosAngle: LDA $A0B3C3,X ASL CLC ADC $A0B3C3,X ASL ASL CLC ADC $A0B3C3,X ASL EOR #$FFFF INC AND #$FF00 XBA BPL + ORA #$FF00 + RTS ;0D60, 0D64, 0D68 SetSideChecks: BMI + INC $18 + LDA $18 ;If 0, check + side. Or not? BNE + LDA $0D48 EOR #$FFFF INC STA $0D48 LDA $0D50 EOR #$FFFF INC STA $0D50 + LDA $0D48 CLC ADC $0D46 STA $12 CLC ADC $0D4A STA $0D64 CLC LDA $0D4A BPL + SEC + ROR CLC ADC $12 STA $0D60 CLC ADC $0D4A BIT $16 BMI + LDA $12 + STA $0D68 LDA $0D50 CLC ADC $0D4E STA $12 CLC ADC $0D52 STA $0D66 CLC LDA $0D52 BPL + SEC + ROR CLC ADC $12 STA $0D62 CLC ADC $0D52 BIT $16 BMI + LDA $12 + STA $0D6A LDX #$0010 RTS LengthCollisionCheck: ;+ = extending, - = retracting. A holds new grapple beam distance. ;Cases: Extending straight, Ext CW, Ext CCW, retracting straight, retracting CW, retracting CCW. ;Checks: Foot (2), Foot and + Side (3), Foot and - Side, Head (2), Head and - Side (3), Head and + Side ;Calculate offset due to movement ;Calculate 5 pixels + side(X/Y). - side is same but negative. ;Calculate 1A pixels towards feet(X/Y) ;Add results as necessary to get spots to check. ;print "Start of LengthCollisionCheck: ", pc STZ $16 STZ $18 BPL + EOR #$FFFF INC DEC $16 ;$16 is negative if retracting DEC $18 + INC TAY LDA $0CFB AND #$00FF BIT $16 BPL + EOR #$0080 + ASL TAX LDA $A0B443,X JSL SignedMultiplication CLC ADC $0D16 STA $0D46 ;X offset due to movement + 'Origin' LDA $A0B3C3,X JSL SignedMultiplication CLC ADC $0D18 STA $0D4E ;Y offset due to movement + 'Origin' LDA $0D45 EOR #$0080 JSR TwoSixSinAngle EOR #$FFFF INC STA $0D4A ;X for 2/3 to feet JSR TwoSixCosAngle STA $0D52 ;Y for 2/3 to feet TXA CLC ADC #$0180 AND #$01FF JSR SixSinAngle STA $0D48 ;X for + side JSR SixCosAngle STA $0D50 ;Y for + side LDA $0D46 CLC ADC $0D48 STA $0D58 LDA $0D46 SEC SBC $0D48 STA $0D5C LDA $0D4E CLC ADC $0D50 STA $0D5A LDA $0D4E SEC SBC $0D50 STA $0D5E LDX #$0004 LDA $0CFA CMP $0D44 BEQ + ;Skip additional spots JSR SetSideChecks + BIT $16 BMI ++ LDA $0D4A ;Change head position to foot CLC BPL + SEC + ROR CLC ADC $0D4A PHA CLC ADC $0D58 STA $0D58 ;X of foot (1) PLA CLC ADC $0D5C STA $0D5C ;X of foot (2) LDA $0D52 CLC BPL + SEC + ROR CLC ADC $0D52 PHA CLC ADC $0D5A ;Y of foot (1) STA $0D5A PLA CLC ADC $0D5E STA $0D5E ;Y of foot (2) ++ LDA $07A5 ;At this point, X is index to first X/Y to check, and all spots are ready. STA $4202 ;Yes, it does multiply it, but it doesn't waste time so eh. - ;print "Start of extending block detection: ", pc ; JSR DebugCollisionSpots LDA $0D5A,X ;Get Y LSR LSR LSR LSR STA $4203 ;High byte (trash) goes into dividend register. Doesn't do anything so it's fine. LDA $0D58,X LSR LSR LSR LSR CLC ADC $4216 STA $0DC4 STA $18 PHX ASL TAX LDA $7F0003,X AND #$00F0 LSR LSR LSR TAX JSR (GrappleBlockCollision,X) PLX BCS + DEX DEX DEX DEX BPL - - RTS + STZ $0D00 BIT $16 BMI - CPX #$0008 ;Carry set if greater or equal BPL - LDA $0D44 CMP #$A100 BCS - ;Branches if A100 - FFFF CMP #$6000 BMI + JSR AttemptLanding + SEC RTS ;DebugCollisionSpots: ; PHX ; PHA ; LDA $0D5A,X ; PHA ; LDA $0D58,X ; LDX $0590 ; SEC ; SBC $0911 ; SBC #$0004 ; STA $0370, X ; AND #$0100 ; BEQ + ; LDA $81859F, X ; STA $22 ; LDA ($22) ; ORA $81839F, X ; STA ($22) ;+ ; PLA ; SEC ; SBC $0915 ; SBC #$0004 ; STA $0371, X ; LDA #$3A20 ; STA $0372, X ; TXA ; CLC ; ADC #$0004 ; STA $0590 ; PLA ; PLX ; RTS AttemptLandingLoop: - LDA $18 SEC SBC $07A5 BMI AttemptLandingLoop-2 ;Bad practice saves 2 bytes for free! STA $18 STA $0DC4 ASL TAX LDA $7F0003,x AND #$00F0 LSR LSR LSR TAX JSR (GrappleBlockCollision,X) BCS + DEC $16 BPL - + RTS AttemptLanding: LDA #$0002 STA $16 LDA $07A5 STA $4202 ;AttemptLandingb: JSR AttemptLandingLoop BCS AttemptLanding-1 ;Set Samus to standing. May throw some ugly stack work in right here. PLA PLA PLB ;Let's handle the stack now instead of later LDA $18 STA $4204 LDA $07A5 SEP #$20 STA $4206 REP #$20 LDY #$00A4 LDA $0A1E BIT #$0004 BEQ + INY + STY $0A28 LDA #$0005 STA $0A2E LDA $4214 ASL ASL ASL ASL CLC ADC #$001B ;will need to doublecheck STA $0AFA STZ $0CF8 STZ $0B36 LDA $4216 ASL ASL ASL ASL ADC #$000A CMP $0AF6 BMI ++ SBC #$0005 CMP $0AF6 BMI +++ + DEC $18 BRA + ++ INC $18 + PHA LDA $07A5 ASL ADC $18 STA $18 LDA #$0002 STA $16 JSR AttemptLandingLoop PLA BCC + STA $0AF6 BRA +++ + AND #$FFF0 SBC #$0003 CMP $0AF6 BPL + CLC ADC #$0018 CMP $0AF6 BPL +++ + STA $0AF6 +++ JSL CalculateGrappleLengthA ;print "GrappleLength: ",pc CLC ADC #$0008 CMP $0CF6 BMI + CMP #$006F BMI ++ CMP #$0077 BPL +++ LDA #$006E ++ STA $0CF6 + RTL +++ STZ $0CF4 RTL ForwardCollisionCheckSetup: CLC ADC $0D45 REP #$20 ASL JSR SixSinAngle CLC ADC $0D16 STA $0D4C JSR SixCosAngle CLC ADC $0D18 STA $0D54 LDA $0D45 JSR TwoSixSinAngle STA $14 CLC ADC $0D4C STA $0D4A LDA $14 CLC BPL + SEC + ROR PHA CLC ADC $0D4C STA $0D48 PLA CLC ADC $14 CLC ADC $0D4C STA $0D46 JSR TwoSixCosAngle EOR #$FFFF INC STA $14 CLC ADC $0D54 STA $0D52 LDA $14 CLC BPL + SEC + ROR PHA CLC ADC $0D54 STA $0D50 PLA CLC ADC $14 CLC ADC $0D54 STA $0D4E LDY #$0006 - LDA $0D4E,Y SEC SBC $0D0C STA $14 LDA $0D46,Y SEC SBC $0D08 STA $12 PHY JSL CalculateVectorLength PLY STA $0D46,Y TXA LSR STA $0D4E,Y DEY DEY BPL - LDA #$0028 STA $0D80 RTS SwingCollisionCheck: ;print "Start of SwingCollisionCheck: ", pc TDC LDA #$C0 BIT $0D27 BMI + LDA #$40 + JSR ForwardCollisionCheckSetup STZ $12 SEP #$20 TDC INC BIT $0D56 BPL + LDA #$FF + STA $12 -- CLC LDA $13 ADC $12 STA $13 LDX #$0006 - LDA $0D46,X TAY LDA $13 CLC ADC $0D4E,X REP #$20 PHX JSR GetBlockXY PLX BCS + SEP #$20 TDC DEX DEX BPL - LDA $13 CMP $0D56 BNE -- CLC RTS + BNE ++ ;Check from PLX, branch if X !=0 LDA $0D44 CMP #$6000 BMI ++ CMP #$A0FF BPL ++ + JSR AttemptLanding ++ ;Code for normal collision response here SEP #$21 LDA $13 SBC $12 ; SEC ; SBC $12 STA $13 ;Go to angle before collision STZ $12 REP #$20 LDA $12 ;Successful degrees moved before collision SEC SBC $0D26 ;target degrees to move LSR ;-(Degrees not moved) LSR ;Divided by 4 BIT #$2000 BEQ + ORA #$C000 + CLC ADC $12 ;Successful movement - (degrees not moved) / 4 PHA CLC ADC $0CFA STA $0CFA PLA CLC ADC $0D44 STA $0D44 LDA $0D26 EOR #$FFFF INC LSR LSR BIT #$2000 BEQ + ORA #$C000 + STA $0D26 ;Reverse and divide old speed by 4 SEC RTS ;Below this should be DONE GetBlockXY: print "GetBlock routine: ", pc ASL TAX LDA $A0B443,X JSL SignedMultiplication CLC ADC $0D08 LSR LSR LSR LSR STA $16 LDA $A0B3C3,X JSL SignedMultiplication CLC ADC $0D0C ASL ASL ASL ASL AND #$FF00 ORA $16 LDX #$0026 CPX $0D80 BMI + ;Set new block - CMP $0D58,X BNE ++ ;Skip block CLC RTS ++ DEX DEX ;This shouldn't ever reach negative. If it does... well. It'll be interesting. CPX $0D80 BPL - + STA $0D58,X STX $0D80 SEP #$20 XBA STA $4202 LDA $07A5 STA $4203 LDA #$00 XBA REP #$21 ADC $4216 STA $0DC4 STA $18 ;Well, let's hope the grapple block collision won't change this... ASL TAX LDA $7F0003,X AND #$00F0 LSR LSR LSR TAX JSR (GrappleBlockCollision,X) ++ RTS ;16-bit value in Y * signed 9-bit A value, high 16-bit result in A. Result should be signed, but large values can mess it up. ;4216(high * byte) + 4217 (low * sign) = A? SignedWordMultiplication: SEP #$20 XBA BPL ++ TYA XBA BEQ + EOR #$FF INC REP #$20 STA $4202 TYA SEP #$20 NOP LDA $4217 XBA STA $4203 XBA REP #$21 AND #$00FF ADC $4216 EOR #$FFFF INC RTL + REP #$20 TYA EOR #$FFFF INC RTL ++ BNE + TYA XBA REP #$20 STA $4202 TYA SEP #$20 NOP LDA $4217 XBA STA $4203 XBA REP #$21 AND #$00FF ADC $4216 RTL + REP #$20 TYA RTL ;8-bit value in Y * signed 9-bit A, 16-bit result in A. Result should be signed, but large values can mess it up. SignedMultiplicationExtra: STY $4202 XBA BPL ++ XBA BEQ + SEP #$20 EOR #$FF INC STA $4203 REP #$20 LDA #$FFFF EOR $4216 ;I do funny things to save cycles... INC RTL + TYA EOR #$FFFF INC XBA RTL ++ BNE + SEP #$20 XBA STA $4203 REP #$20 NOP NOP LDA $4216 RTL + TYA XBA RTL ;8-bit value in Y * signed 9-bit A, high byte of result sign-extended to 16-bits in A SignedMultiplication: STY $4202 XBA BPL ++ XBA BEQ + SEP #$20 EOR #$FF INC STA $4203 LDA #$FF NOP NOP EOR $4217 ;I do funny things to save cycles... REP #$20 INC RTL + TYA EOR #$FFFF INC RTL ++ BNE + SEP #$20 XBA STA $4203 REP #$20 LDA #$00FF NOP AND $4217 RTL + TYA RTL ChargeGraphicPosition: LDA $0A1C ASL ASL ASL TAX LDA $91B62D,X AND #$00FF STA $16 LDA $91B62C,X AND #$00FF CMP #$0010 BMI + PLA PLB RTL + ASL TAX LDA $0A1F AND #$00FF CMP #$0001 BEQ ++ LDA $C1C2, X CLC ADC $0AFA SEC SBC $16 TAY LDA $C1A8, X CLC ADC $0AF6 RTS ++ LDA $C1F0, X CLC ADC $0AFA SEC SBC $16 TAY LDA $C1DC, X CLC ADC $0AF6 RTS print "Boundary: ",pc org $90DD7D ;What to do when turning around print "Boundary: ",pc BIT $0CF4 BMI + STZ $0CF4 + RTS ;$DC036-$DC0DA print "Boundary: ",pc org $9BC036 print "Boundary: ",pc PHP REP #$30 LDA $0CD0 BNE + - PLP RTL + CMP #$0001 BNE + LDA #$0010 STA $0CD6 LDA #$0003 STA $0CDC + LDA $0CDC DEC A STA $0CDC BPL ++ LDA $0CD6 INC A STA $0CD6 TAX LDA $90C487, X AND #$00FF CMP #$00FE BNE + LDA $90C488, X ORA #$FF00 CLC ADC $0CD6 STA $0CD6 TAX LDA $90C487, X AND #$00FF + STA $0CDC ++ LDA $0D1A SEC SBC $0911 STA $14 LDA $0D1C SEC SBC $0915 STA $12 AND #$FF00 BNE + LDA $0CD6 STA $16 JSL $818A37 ; $8A37 IN ROM BRA ++ + LDA $0CD6 STA $16 JSL $818AB7 ; $8AB7 IN ROM ++ PLP RTL pad $9BC0DB ;Don't don't clear 0DC6 (all originally BRA $01 originally STZ $0DC6). print "Boundary: ",pc org $91EC10 print "Boundary: ",pc ; BRA + ; NOP ;+ STZ $0DC6 print "Boundary: ",pc org $90E5FE print "Boundary: ",pc ; BRA + ; NOP ;+ STZ $0DC6 print "Boundary: ",pc org $90A68F print "Boundary: ",pc ; BRA + ; NOP ;+ STZ $0DC6 print "Boundary: ",pc org $90A654 print "Boundary: ",pc ; BRA + ; NOP ;+ STZ $0DC6 print "Boundary: ",pc org $90DDB6 print "Boundary: ",pc LDA $0CF4 BPL + JSL GrappleMain RTS + STZ $0CF4 RTS ;DD3D, DDB6, BF9D, DD6F, DD74, DD8C, DDD8 ; 03,0A,0D,14,19,1B 04,07,08,09,11,12,13 0B,0C,16,0E,17,18 0F 1A print "Boundary: ",pc org $91EBB7 print "Boundary: ",pc JSL DisableGrapple ;Calls to movement transitions print "Boundary: ",pc org $91F41A print "Boundary: ",pc JSL MovementTransition print "Boundary: ",pc org $91F3A5 print "Boundary: ",pc JSL MovementTransition ;Transition to new movement type print "Boundary: ",pc org $B880B0 print "Boundary: ",pc MovementTransition: PHP PHB PHK PLB REP #$30 LDA $0A1F AND #$00FF ASL A TAX JSR (MovementTransitions, X) PLB PLP RTL MovementTransitions: ; 00,01, 02, 03, 04,05,06,07, 08,09,0A,0B,0C, 0D DW NT,NT,NormalJump,SpinJump,KillGrapple,NT,NT,NT,KillGrapple,NT,NT,NT,NT,UnknownTransition ; 0E,0F,10, 11, 12, 13, 14,15,16,17,18,19,1A, 1B DW NT,NT,NT,KillGrapple,SpringAir,KillGrapple,WallJump,NT,NT,NT,NT,NT,NT,KillGrapple WallJump: LDA $0A23 AND #$00FF CMP #$0014 BEQ + JSL $909949 ; $81949 IN ROM + NT: RTS SpringAir: LDA $0A1C CMP #$007F BNE + LDA $0A23 AND #$00FF CMP #$0011 BEQ ++ BRA +++ + CMP #$0080 BNE +++ LDA $0A23 AND #$00FF CMP #$0011 BNE +++ ++ JSL $9098BC ; $818BC IN ROM +++ KillGrapple: STZ $0CF4 RTS UnknownTransition: LDA $0A1C CMP #$0065 BNE + LDA $0A20 CMP #$0064 BEQ ++ BRA +++ + CMP #$0066 BNE +++ LDA $0A20 CMP #$0063 BNE +++ ++ JSL $9098BC ; $818BC IN ROM +++ RTS NormalJump: LDA $0A1C CMP #$004B BEQ + CMP #$004C BEQ + CMP #$0055 BMI +++ CMP #$005B BPL +++ + LDA $0A20 CMP #$0027 BEQ + CMP #$0028 BNE ++ + LDA $0AFA SEC SBC #$000A STA $0AFA ++ JSL $9098BC ; $818BC IN ROM +++ RTS SpinJump: LDA $0A23 AND #$00FF CMP #$0003 BEQ + CMP #$0014 BEQ + JSL $B88000 ; $818BC IN ROM + RTS DisableGrapple: PHB PHK PLB LDA $0A1F AND #$00FF TAX BIT.w DisableGrappleTransitions-1,X BPL + STZ $0CF4 + PLB JML $91FB08 DisableGrappleTransitions: DB $00,$00,$00,$00,$80,$00,$00,$00,$80,$00,$00,$00,$00,$00,$00,$00 DB $00,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$80 ;$101E9A-$101F6C, ;$101F7D-$102079 print "Boundary: ",pc org $A09E9A print "Boundary: ",pc STZ $18A6 STZ $17AA -- LDY $17AA LDA $17EC, Y CMP #$FFFF BNE + CLC RTL + STA $0E54 TAX LDA $0FA0, X BEQ + - INC $17AA INC $17AA BRA -- + LDA $0F7A, X SEC SBC $0D08 BPL + EOR #$FFFF INC A + SEC SBC $0F82, X BCC + CMP #$0008 BCS - + LDA $0F7E, X SEC SBC $0D0C BPL + EOR #$FFFF INC A + SEC SBC $0F84, X BCC + CMP #$0008 BCS - + LDA $0F78, X TAX LDA $A0001A, X BPL + LDX $0E54 LDA #$0001 STA $0F8A, X ;Set to run grapple AI LDA #$8000 BRA ++ + BEQ - DEC BNE + STZ $0CF4 SEC REP #$40 RTL + LDA #$8004 ++ TSB $0CF4 LDX $0E54 LDA $0F7A, X STA $0D08 LDA $0F7E, X STA $0D0C LDA $0A1F AND #$00FF CMP #$0016 BEQ + SEC SEP #$40 RTL + JSL CalculateGrappleLength CMP #$0088 BPL ++ STA $0CFE TXA LSR AND #$00FF SEP #$20 LDY $0CFA STA $0CFB CPY $0D44 BEQ + CLC BMI +++ ADC #$F2 BRA + +++ ADC #$0E + STA $0D45 REP #$20 SEP #$41 RTL ++ STZ $0CF4 SEC REP #$40 RTL ;GrapplePullEnemyStop: ;Will be handled by individual enemies ; LDX $0E54 ; LDA $0F9E, X ; BEQ + ; LDA #$0004 ; STA $0F8A, X ; STZ $0CF4 ; RTS ;+ ; LDA $0F78, X ; TAX ; LDA $A0000D, X ; AND #$00FF ; BNE + ; LDA #$0004 ;+ ; LDX $0E54 ; STA $0F9C, X ; STZ $0F8A, X ; LDA $0CFE ; SEC ; SBC $0CF6 ; B ; RTS ;What enemies need to do: ;Check if frozen (LDA $0F9E,X : BEQ + : LDA #$0004 : STA $0F8A,X : STZ $0CF4 : LDA $0F78,X : TAX : LDA $A0001E,X : STA $1784 : JML [$1784] : + ...) ;Enemy stun effect (LDA $0F78,X : TAX : LDA $A0000D,X : AND #$00FF : BNE + : LDA #$0004 : LDX $0E54 : STA $0F9C,X : STZ $0F8A,X) ;Compare grapple length to target length, adjust speed if necessary ;Have a main AI mode for grapple movement, use it until collision with appropriate surface ; GrapplePullSamusStop: LDX $0E54 LDA $0F9E, X BNE + LDA #$0004 STA $0F8A, X STZ $0CF4 LDA $0F78,X TAX LDA $A0001E,X STA $1784 JML [$1784] + LDA $0F78, X TAX LDA $A0000D, X AND #$00FF BNE + LDA #$0004 + LDX $0E54 STA $0F9C, X STZ $0F8A, X LDA #$0004 TSB $0CF4 RTL print "Boundary: ",pc org $A3E669 print "Boundary: ",pc LDX $0E54 LDA $0F92, X ;Get orientation AND #$0003 ASL A TAY LDA $E2CC, Y ;E25C, E278, E294, E2B0 STA $0F92, X ;Set graphic AI LDA #$804D STA $0F8E, X ;Advanced hit box pointer. Probably unused, Geemers are simple squares LDA #$0001 STA $0F94, X ;Start graphic AI immediately LDA #$E6C1 STA $0FB2, X ;Main AI pointer initialized to E6C1 LDA $0FB4, X ;'Speed' from SMILE. Intended to be 0000 - 001F or 00FF XBA LSR LSR STA $0FA8, X ;Horizontal and STA $0FAA, X ;Vertical speeds. LDA $0F86, X AND #$0003 BNE + LDA $0FA8, X ;Swap X speed if initially moving left (0) EOR #$FFFF INC A STA $0FA8, X RTL + CMP #$0002 BNE + LDA $0FAA, X ;Swap Y speed if initially moving up (2) EOR #$FFFF INC A STA $0FAA, X + RTL ;Right is probably 1, down is probably 3. ;E785: Falling print "Boundary: ",pc org $A3E785 print "Boundary: ",pc LDA $7E780A,X STA $12 LDA $7E780C,X STA $14 JSL $A0C6AB PHP LDA $7E7802, X ;Uh. Not sure when this was initialized. STA $12 LDA $7E7804, X STA $14 JSL $A0C786 ;Vertical motion BCS + PLP BCC ++ BRA +++ + PLP +++ LDA #$0000 STA $7E7802, X STA $7E7804, X STA $7E780A, X STA $7E780C, X STA $7E7808, X ;Clear speeds LDA $7E7806, X STA $0FB2, X ;Restore previous AI RTL ++ LDA $7E7804, X CMP #$0004 ;Cap speed at 4 pixels per frame BPL + LDA $7E7802, X CLC ADC #$4000 STA $7E7802, X LDA $7E7804, X ADC #$0000 STA $7E7804, X ;Accelerate due to gravity + RTL print "Must be before a3e7f2: ", pc print "Boundary: ",pc org $A0DD19 print "Boundary: ",pc DW $F650 print "Boundary: ",pc org $A0DD2F print "Boundary: ",pc DW GeemerTouch print "Boundary: ",pc org $A3F650 ;First free space available in the bank... ouch print "Boundary: ",pc ;Check if frozen (LDA $0F9E,X : BEQ + : LDA #$0004 : STA $0F8A,X : STZ $0CF4 : LDA $0F78,X : TAX : LDA $A0001E,X : STA $1784 : JML [$1784] : + ...) ;Enemy stun effect (LDA $0F78,X : TAX : LDA $A0000D,X : AND #$00FF : BNE + : LDA #$0004 : LDX $0E54 : STA $0F9C,X : STZ $0F8A,X) ;Compare grapple length to target length, adjust speed if necessary LDA $0F9E,X : BEQ + : LDA #$0004 : STA $0F8A,X : STZ $0CF4 : JML $A0957E + LDA #$0004 : STA $0F9C,X : STZ $0F8A,X : LDA $0F7A,X LDA $0CFE SEC SBC $0CF6 BPL + JMP $E785 + TAY LDA $0CFB AND #$00FF ASL TAX LDA $A0B3C3,X JSL SignedMultiplicationExtra LSR LSR LSR LSR BIT #$0800 BEQ + ORA #$F000 + PHA LDA $A0B443,X JSL SignedMultiplicationExtra PLY LSR LSR LSR LSR BIT #$0800 BEQ + ORA #$F000 + LDX $0E54 PHB PEA $7E7E PLB PLB CLC ADC $780B,X STZ $780C,X BMI + CMP #$0800 BMI ++ LDA #$0008 BRA ++ + DEC $780C,X CMP #$F800 BPL ++ LDA #$F800 ++ STA $780B,X CLC TYA ADC $7803,X STZ $7804,X BMI + CMP #$0800 BMI ++ LDA #$0008 BRA ++ + DEC $7804,X CMP #$F800 BPL ++ LDA #$F800 ++ STA $7803,X LDA $0FB2,X CMP #$E785 BEQ + STA $7806,X LDA #$E785 STA $0FB2,X + PLB JMP $E785 GeemerTouch: LDX $0E54 LDA $0F8A,X LSR BCS + JML $A0A477 + RTL macro EnemyGrapplePointers(bank) ;TODO: Implement all of these. Starting with GrapplePullSamusStop { print "Boundary: ",pc org print "Boundary: ",pc JSL $A08004 ;Dummied for now RTL JSL GrapplePullSamusStop RTL JSL $A08004 ;Dummied for now RTL JSL $A08004 ;Dummied for now RTL JSL $A08004 ;Dummied for now RTL JSL $A08004 ;Dummied for now RTL } endmacro %EnemyGrapplePointers($A08000) %EnemyGrapplePointers($A28000) %EnemyGrapplePointers($A38000) %EnemyGrapplePointers($A48000) %EnemyGrapplePointers($A58000) %EnemyGrapplePointers($A68000) %EnemyGrapplePointers($A78000) %EnemyGrapplePointers($A88000) %EnemyGrapplePointers($A98000) %EnemyGrapplePointers($AA8000) %EnemyGrapplePointers($B28000) %EnemyGrapplePointers($B38000)