Advertisement
NovaYoshi

player.s

Oct 20th, 2015
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .proc RunPlayer
  2.   jsr UpdateStatus
  3.  
  4.   jsr HandlePlayer
  5.   rts
  6. .endproc
  7.  
  8. NOVA_ACCEL_SPEED = 2
  9. NOVA_DECEL_SPEED = 4
  10. NOVA_WALK_SPEED = 2
  11. NOVA_RUN_SPEED = 4
  12.  
  13. .proc UpdateStatus
  14. HealthX = 0
  15. HealthCount = 1
  16.   ldy OamPtr
  17.   lda #15
  18.   sta HealthX
  19.   sta OAM_YPOS+(4*0),y
  20.   sta OAM_YPOS+(4*1),y
  21.   sta OAM_XPOS+(4*0),y
  22.   sta OAM_XPOS+(4*2),y
  23.   lda #15+8
  24.   sta OAM_YPOS+(4*2),y
  25.   sta OAM_YPOS+(4*3),y
  26.   sta OAM_XPOS+(4*1),y
  27.   sta OAM_XPOS+(4*3),y
  28.   lda #$4c
  29.   sta OAM_TILE+(4*0),y
  30.   lda #$4d
  31.   sta OAM_TILE+(4*2),y
  32.   lda #$4e
  33.   sta OAM_TILE+(4*1),y
  34.   lda #$4f
  35.   sta OAM_TILE+(4*3),y
  36.   lda #OAM_COLOR_0
  37.   sta OAM_ATTR+(4*0),y
  38.   sta OAM_ATTR+(4*1),y
  39.   sta OAM_ATTR+(4*2),y
  40.   sta OAM_ATTR+(4*3),y
  41.   tya
  42.   add #4*4
  43.   tay
  44.  
  45. ; Draw all hearts needed
  46.   lda PlayerHealth
  47.   lsr
  48.   php
  49.   sta HealthCount
  50. Loop:
  51.   lda HealthCount
  52.   beq NoMoreHearts
  53.   lda #$4a
  54.   jsr MakeHeart
  55.   dec HealthCount
  56.   bne Loop
  57. NoMoreHearts:
  58.  
  59.   plp ; add a half heart if needed
  60.   bcc :+
  61.     lda #$4b
  62.     jsr MakeHeart
  63.   :
  64.  
  65.   sty OamPtr
  66.   rts
  67.  
  68. MakeHeart:
  69.   sta OAM_TILE,y
  70.   lda HealthX
  71.   sta OAM_XPOS,y
  72.   add #8
  73.   sta HealthX
  74.   lda #0
  75.   sta OAM_ATTR,y
  76.   lda #15+16
  77.   sta OAM_YPOS,y
  78.   iny
  79.   iny
  80.   iny
  81.   iny
  82.   rts
  83. .endproc
  84.  
  85. .proc HandlePlayer
  86. ;OldPlayerPYL = 0
  87. ;OldPlayerPYH = 1
  88. Temp = 1
  89. BlockUL = 2
  90. BlockUR = 3
  91. BlockLL = 4
  92. BlockLR = 5
  93. FourCorners = 6
  94. BottomCMP = 7
  95. SkipFourCorners = 8
  96. MaxSpeedLeft = 9
  97. MaxSpeedRight = 10
  98.   lda #0
  99.   sta PlayerOnGround
  100.   sta FourCorners
  101.   sta SkipFourCorners
  102.  
  103.   lda PlayerWasRunning ; nonzero = B button, only updated when on ground
  104.   beq :+
  105.     lda #-NOVA_RUN_SPEED*16
  106.     sta MaxSpeedLeft
  107.     lda #NOVA_RUN_SPEED*16
  108.     sta MaxSpeedRight
  109.     bne NotWalkSpeed
  110. : lda #-NOVA_WALK_SPEED*16
  111.   sta MaxSpeedLeft
  112.   lda #NOVA_WALK_SPEED*16
  113.   sta MaxSpeedRight
  114. NotWalkSpeed:
  115.  
  116. ;  lda PlayerPYL
  117. ;  sta OldPlayerPYL
  118. ;  lda PlayerPYH
  119. ;  sta OldPlayerPYH
  120.  
  121.   lda PlayerVYH
  122.   bmi GravityAddOK
  123.   lda PlayerVYL
  124.   cmp #$60
  125.   bcs SkipGravity
  126. GravityAddOK:
  127.   lda PlayerVYL
  128.   add #4
  129.   sta PlayerVYL
  130.   bcc SkipGravity
  131.     inc PlayerVYH
  132. SkipGravity:
  133.  
  134.   ; apply gravity
  135.   lda PlayerPYL
  136.   add PlayerVYL
  137.   sta PlayerPYL
  138.   lda PlayerPYH
  139.   adc PlayerVYH
  140.   and #$0f
  141.   sta PlayerPYH
  142.  
  143.   lda PlayerJumpCancelLock
  144.   beq :+
  145.     dec PlayerJumpCancelLock
  146.   :
  147.  
  148.   lda PlayerWalkLock
  149.   beq :+
  150.     dec PlayerWalkLock
  151.   :
  152.  
  153.   lda PlayerInvincible
  154.   beq :+
  155.     dec PlayerInvincible
  156.   :
  157.  
  158.   lda PlayerTailAttack
  159.   beq NoTail
  160.     inc PlayerTailAttack
  161.     lda PlayerTailAttack
  162.     cmp #6 ; launch attack
  163.     bne :+
  164.       jsr DoTailAttack
  165.     :
  166.     lda PlayerTailAttack
  167.     cmp #14
  168.     bcc :+
  169.       lda #0
  170.       sta PlayerTailAttack
  171.     :
  172.     jmp SkipTail
  173. NoTail:
  174.   lda keylast
  175.   and #KEY_B|KEY_LEFT|KEY_RIGHT
  176.   bne :+
  177.   lda keydown
  178.   and #KEY_B
  179.   beq :+
  180.     lda #SFX::TAIL_WHOOSH
  181.     jsr PlaySound
  182.     inc PlayerTailAttack
  183.   :
  184. SkipTail:
  185.  
  186.   lda PlayerVYH
  187.   bpl :+
  188.     lda keydown        ; cancel a jump
  189.     and #KEY_A
  190.     bne :+
  191.       lda PlayerJumpCancelLock
  192.       bne :+
  193.         lda #0
  194.         sta PlayerVYH
  195.         sta PlayerVYL
  196.   :
  197.  
  198.   lda PlayerWalkLock
  199.   bne NotWalk
  200.   ; handle left and right
  201.   lda keydown
  202.   and #KEY_LEFT
  203.   beq NotLeft
  204.     ldy #0
  205.     sty PlayerDownTimer
  206.     iny
  207.     sty PlayerDir
  208.     lda PlayerVXL
  209.     cmp MaxSpeedLeft ; can be either run speed or walk speed
  210.     beq NotLeft
  211.     cmp #-NOVA_RUN_SPEED*16
  212.     beq NotLeft
  213.  
  214.     lda PlayerVXL
  215.     bne :+
  216.        dec PlayerVXH
  217.   : sub #NOVA_ACCEL_SPEED
  218.     sta PlayerVXL
  219. NotLeft:
  220.  
  221.   lda keydown
  222.   and #KEY_DOWN
  223.   beq NotDown
  224.     lda PlayerDownTimer
  225.     cmp #60
  226.     bcs YesDown
  227.     inc PlayerDownTimer
  228.     bne YesDown
  229.   NotDown:
  230.    lda #0
  231.    sta PlayerDownTimer
  232.   YesDown:
  233.  
  234.   lda keydown
  235.   and #KEY_RIGHT
  236.   beq NotRight
  237.     lda #0
  238.     sta PlayerDownTimer
  239.     sta PlayerDir
  240.  
  241.     lda PlayerVXL
  242.     cmp MaxSpeedRight ; can be either run speed or walk speed
  243.     beq NotRight
  244.     cmp #NOVA_RUN_SPEED*16
  245.     beq NotRight
  246.  
  247.     lda PlayerVXL
  248.     add #NOVA_ACCEL_SPEED
  249.     sta PlayerVXL
  250.     bne NotRight
  251.       inc PlayerVXH
  252. NotRight:
  253. NotWalk:
  254.  
  255.   lda #NOVA_DECEL_SPEED ; adjust the deceleration speed if you're trying to turn around
  256.   sta Temp
  257. .if 1
  258.   lda keydown
  259.   and #KEY_LEFT
  260.   beq :+
  261.     lda PlayerVXH
  262.     bmi IsMoving
  263.     lsr Temp
  264.   :
  265.   lda keydown
  266.   and #KEY_RIGHT
  267.   beq :+
  268.     lda PlayerVXL
  269.     ora PlayerVXH
  270.     beq Stopped
  271.     lda PlayerVXH
  272.     bpl IsMoving
  273.     lsr Temp
  274.   :
  275. .endif
  276. ;  lda keydown
  277. ;  and #KEY_LEFT|KEY_RIGHT
  278. ;  bne IsMoving
  279.     lda PlayerVXL
  280.     ora PlayerVXH
  281.     beq IsMoving
  282.       lda PlayerVXH ; if negative, make positive
  283.       and #128
  284.       sta 0
  285.       beq :+
  286.         neg16 PlayerVXL, PlayerVXH
  287.       :
  288.  
  289.       lda PlayerVXL
  290.       sub Temp ;#NOVA_DECEL_SPEED
  291.       sta PlayerVXL
  292.       bcs @NotCarry
  293.         dec PlayerVXH
  294.         bpl @NotCarry
  295.           lda #0
  296.           sta PlayerVXH
  297.           sta PlayerVXL
  298.   @NotCarry:
  299.  
  300.       lda 0   ; if it was negative make negative again
  301.       beq :+
  302.         neg16 PlayerVXL, PlayerVXH
  303.       :
  304. Stopped:
  305. IsMoving:
  306.  
  307. ; fix walk speed if we just came out of a run
  308.    lda PlayerVXL
  309.    bit PlayerVXH
  310.    bpl :+
  311.      neg
  312.    :
  313.    cmp MaxSpeedRight
  314.    beq NoFixWalkSpeed
  315.    bcc NoFixWalkSpeed
  316.    sub #NOVA_DECEL_SPEED
  317.    bit PlayerVXH
  318.    bpl :+
  319.      neg
  320.    :
  321.    sta PlayerVXL
  322. NoFixWalkSpeed:
  323.  
  324.   ; apply speed without caring if it's gonna push us into a wall or not
  325.   lda PlayerPXL
  326.   add PlayerVXL
  327.   sta PlayerPXL
  328.   lda PlayerPXH
  329.   adc PlayerVXH
  330.   sta PlayerPXH
  331.  
  332.   ; ------- FOUR CORNER COLLISION DETECTION -------
  333.   ; http://pineight.com/mw/index.php?title=Four-corner_collision_detection
  334.  
  335.   lda #M_SOLID_ALL
  336.   sta BottomCMP
  337.   lda PlayerVYH
  338.   bmi :+
  339.     lda #0
  340.     sta PlayerJumping
  341.     lda #M_SOLID_TOP
  342.     sta BottomCMP
  343.   :
  344.  
  345.   ; check blocks in the middle
  346.   ; TODO: make less dumb
  347.   lda PlayerPYL
  348.   add #<(16*16)
  349.   lda PlayerPYH
  350.   adc #>(16*16)
  351.   tay
  352.   lda #$40
  353.   add PlayerPXL
  354.   lda PlayerPXH
  355.   adc #0
  356.   jsr GetLevelColumnPtr
  357.   cmp #Metatiles::COIN
  358.   bne NotCoin
  359.   lda #0
  360.   jsr ChangeBlock
  361.   lda #SFX::COIN
  362.   jsr PlaySound
  363.   jsr AddCoin
  364.   jmp DoneCheckMiddle
  365. NotCoin:
  366.   cmp #Metatiles::SPRING
  367.   bne NotSpring
  368.   lda #-1
  369.   sta PlayerVYH
  370.   lda #-$70
  371.   sta PlayerVYL
  372.   lda #30
  373.   sta PlayerJumpCancelLock
  374.   lda #SFX::SPRING
  375.   jsr PlaySoundDebounce
  376.   inc SkipFourCorners
  377. NotSpring:
  378. DoneCheckMiddle:
  379.  
  380.   ; top
  381.   lda PlayerPYL
  382.   add #<(8*16)
  383.   lda PlayerPYH
  384.   adc #>(8*16)
  385.   tay
  386.   lda #0
  387.   pha
  388.   add PlayerPXL            ; left side
  389.   lda PlayerPXH
  390.   adc #0
  391.   jsr GetLevelColumnPtr
  392.   sta BlockUL
  393.   tax
  394.   lda MetatileFlags,x
  395.   cmp #$80
  396.   rol FourCorners
  397.   pla
  398.   add #$70
  399.   add PlayerPXL            ; right side
  400.   lda PlayerPXH
  401.   adc #0
  402.   jsr GetLevelColumnPtr
  403.   sta BlockUR
  404.   tax
  405.   lda MetatileFlags,x
  406.   cmp #$80
  407.   rol FourCorners
  408.  
  409.   ;bottom
  410.   lda PlayerPYL
  411.   add #<(24*16)
  412.   lda PlayerPYH
  413.   adc #>(24*16)
  414.   tay
  415.   lda #0 ; left side
  416.   pha
  417.   add PlayerPXL            ; left side
  418.   lda PlayerPXH
  419.   adc #0
  420.   jsr GetLevelColumnPtr
  421.   sta BlockLL
  422.   tax
  423.   lda MetatileFlags,x
  424.   cmp BottomCMP
  425.   rol FourCorners
  426.   pla
  427.   add #$70
  428.   add PlayerPXL            ; right side
  429.   lda PlayerPXH
  430.   adc #0
  431.   jsr GetLevelColumnPtr
  432.   sta BlockLR
  433.   tax
  434.   lda MetatileFlags,x
  435.   cmp BottomCMP
  436.   rol FourCorners
  437.  
  438.   lda SkipFourCorners
  439.   beq :+
  440.   rts
  441. :
  442.  
  443.   ; now call the right routine
  444.   ldx FourCorners
  445.   lda FourCornersH,x
  446.   pha
  447.   lda FourCornersL,x
  448.   pha
  449.   rts
  450.  
  451. HSpeedDirectionOffset:
  452.   .byt $8f, 0
  453.  
  454. FourCornersL:
  455.   .byt <(FC_____ -1), <(FC____R -1)
  456.   .byt <(FC___L_ -1), <(FC___LR -1)
  457.   .byt <(FC__R__ -1), <(FC__R_R -1)
  458.   .byt <(FC__RL_ -1), <(FC__RLR -1)
  459.   .byt <(FC_L___ -1), <(FC_L__R -1)
  460.   .byt <(FC_L_L_ -1), <(FC_L_LR -1)
  461.   .byt <(FC_LR__ -1), <(FC_LR_R -1)
  462.   .byt <(FC_LRL_ -1), <(FC_LRLR -1)
  463. FourCornersH:
  464.   .byt >(FC_____ -1), >(FC____R -1)
  465.   .byt >(FC___L_ -1), >(FC___LR -1)
  466.   .byt >(FC__R__ -1), >(FC__R_R -1)
  467.   .byt >(FC__RL_ -1), >(FC__RLR -1)
  468.   .byt >(FC_L___ -1), >(FC_L__R -1)
  469.   .byt >(FC_L_L_ -1), >(FC_L_LR -1)
  470.   .byt >(FC_LR__ -1), >(FC_LR_R -1)
  471.   .byt >(FC_LRL_ -1), >(FC_LRLR -1)
  472.  
  473. FC_____:
  474. FC__RL_:
  475. FC_L__R:
  476. FC_LR_R:
  477. FC_LRL_:
  478.   rts
  479.  
  480. FC_LRLR:
  481.   lda PlayerPYL
  482.   sub #$a0
  483.   sta PlayerPYL
  484.   subcarry PlayerPYH
  485.   lda #0
  486.   sta PlayerVYL
  487.   sta PlayerVYH
  488.   rts
  489.  
  490. FC_L_LR:
  491.   jsr FC___LR
  492.   jmp FC_L_L_
  493. FC__RLR:
  494.   jsr FC___LR
  495.   jmp FC__R_R
  496.  
  497. FC__R_R:
  498.   lda #0
  499.   sta PlayerVXL
  500.   sta PlayerVXH
  501.   lda #$8f
  502.   sta PlayerPXL
  503.   lda BlockUR
  504.   cmp #Metatiles::GROUND_CLIMB_L
  505.   bne :+
  506. DoClimb:
  507.     lda #-1
  508.     sta PlayerVYH
  509.     lda #-$40
  510.     sta PlayerVYL
  511.     lda #10
  512.     sta PlayerJumpCancelLock
  513.     lsr
  514.     sta PlayerWalkLock
  515. : rts
  516.  
  517. FC_L_L_:
  518.   lda #0
  519.   sta PlayerVXL
  520.   sta PlayerVXH
  521.   sta PlayerPXL
  522.   inc PlayerPXH
  523.   lda BlockUL
  524.   cmp #Metatiles::GROUND_CLIMB_R
  525.   beq DoClimb
  526.   rts
  527.  
  528. FC_L___:
  529.   lda PlayerPXL
  530.   add #$40
  531.   sta PlayerPXL
  532.   addcarry PlayerPXH
  533.   rts
  534.  
  535. FC__R__:
  536.   lda PlayerPXL
  537.   sub #$40
  538.   sta PlayerPXL
  539.   subcarry PlayerPXH
  540.   rts
  541.  
  542. FC_LR__:
  543.   lda #0
  544.   sta PlayerVYH
  545.   sta PlayerVYL
  546.  
  547.   ; check the block we bumped into
  548.   lda PlayerPYH
  549.   tay
  550.   lda #$40
  551.   add PlayerPXL
  552.   lda PlayerPXH
  553.   adc #0
  554.   jsr GetLevelColumnPtr
  555.   cmp #Metatiles::BRICKS
  556.   beq BreakBricks
  557.   cmp #Metatiles::PRIZE
  558.   beq OpenPrize
  559.   lda #SFX::BUMP
  560.   jmp PlaySoundDebounce
  561.  
  562. OpenPrize: ; insert effects here
  563.   lda #Metatiles::USED_PRIZE
  564.   jsr ChangeBlock
  565.   lda #SFX::COIN
  566.   jsr PlaySoundDebounce
  567.   jsr AddCoin
  568.   rts
  569. BreakBricks: ; insert effects here
  570.   lda #Metatiles::EMPTY
  571.   jsr ChangeBlock
  572.   lda #SFX::SMASH
  573.   jsr PlaySoundDebounce
  574.   rts
  575.  
  576. FC___L_:
  577. FC____R:
  578. FC___LR:
  579.   ldx BlockLL
  580.   lda MetatileFlags,x
  581.   ldx BlockLR
  582.   cmp MetatileFlags,x
  583.   bne NotFallthrough
  584.     and #~M_POST_PROCESS
  585.     cmp #M_SOLID_TOP|M_FALLABLE_LEDGE
  586.     bne NotFallthrough
  587.       lda PlayerDownTimer
  588.       cmp #15
  589.       bcc NotFallthrough
  590.         rts
  591.   NotFallthrough:
  592.  
  593.   inc PlayerOnGround
  594.   lda keydown
  595.   and #KEY_B
  596.   sta PlayerWasRunning
  597.  
  598.   lda #0
  599.   sta PlayerVYH
  600.   sta PlayerVYL
  601.   lda #$80
  602.   sta PlayerPYL
  603.   lda keylast
  604.   and #KEY_A
  605.   bne :+
  606.   lda keydown
  607.   and #KEY_A
  608.   beq :+
  609.     lda #<(-$50)
  610.     sta PlayerVYL
  611.     lda #>(-$50)
  612.     sta PlayerVYH
  613.     inc PlayerJumping
  614.     lda #SFX::JUMP
  615.     jsr PlaySound
  616.   :
  617.   rts
  618.  
  619. .endproc
  620.  
  621. .proc DisplayPlayer
  622. DrawX = 0
  623. DrawY = 1
  624. Attrib = 2
  625. MiddleOffsetX = 3
  626. DrawX2 = 4
  627.   ; need to do this first even if we skip the drawing, because of PlayerDrawX and PlayerDrawY
  628.   RealPosToScreenPos PlayerPXL, PlayerPXH, ScrollX, DrawX
  629.   RealPosToScreenPos PlayerPYL, PlayerPYH, ScrollY, DrawY
  630.  
  631.   ; copy to PlayerDrawX and PlayerDrawY which are used for collision detection
  632.   lda DrawX
  633.   sta PlayerDrawX
  634.   lda DrawY
  635.   sta PlayerDrawY
  636.  
  637.   ; if the player's invincible, flicker their sprite
  638.   lda PlayerInvincible
  639.   and #1
  640.   beq :+
  641.     rts
  642.   :
  643.  
  644.   ; okay now we want to actually draw the player
  645.   lda #0
  646.   sta MiddleOffsetX
  647.   sta Attrib
  648.   sta PlayerTiles+6
  649.   sta PlayerAnimationFrame
  650.  
  651.   lda PlayerTailAttack
  652.   beq :+
  653.     tax
  654.     lda TailAttackFrame,x
  655.     sta PlayerAnimationFrame
  656.   :
  657.  
  658.   lda PlayerAnimationFrame
  659.   beq NormalFrame
  660.   tay
  661.   lda #$0f
  662.   sta PlayerTiles+0
  663.   lda #$01
  664.   sta PlayerTiles+1
  665.   lda AnimO,y
  666.   ldx PlayerDir
  667.   beq :+
  668.   neg
  669. : sta MiddleOffsetX
  670.   lda Anim0,y
  671.   sta PlayerTiles+2
  672.   lda Anim1,y
  673.   sta PlayerTiles+3
  674.   lda Anim2,y
  675.   sta PlayerTiles+4
  676.   lda Anim3,y
  677.   sta PlayerTiles+5
  678.   lda Anim4,y
  679.   sta PlayerTiles+6
  680.   jmp NoSpecialAnimation
  681. NormalFrame:
  682.   ldy #$00
  683.   sty PlayerTiles+0
  684.   iny
  685.   sty PlayerTiles+1
  686.   iny
  687.   sty PlayerTiles+2
  688.   iny
  689.   sty PlayerTiles+3
  690.   iny
  691.   sty PlayerTiles+4
  692.   iny
  693.   sty PlayerTiles+5
  694. EndAnimationFrame:
  695.  
  696.   lda PlayerJumping
  697.   beq :+
  698.     lda #$0c
  699.     sta PlayerTiles+3
  700.     lda #$08
  701.     sta PlayerTiles+4
  702.     lda #$09
  703.     sta PlayerTiles+5
  704.     jmp NoSpecialAnimation
  705.   :
  706.  
  707.   lda PlayerOnGround
  708.   beq :+
  709.     lda PlayerDir
  710.     sta PlayerDirForScroll
  711.   :
  712.  
  713.   lda PlayerOnGround
  714.   bne :+
  715.     lda #$0d
  716.     sta PlayerTiles+2
  717.     lda #$0e
  718.     sta PlayerTiles+3
  719.     lda #$0a
  720.     sta PlayerTiles+4
  721.     lda #$0b
  722.     sta PlayerTiles+5
  723.     jmp NoSpecialAnimation
  724.   :
  725.  
  726.   ; animate walking
  727.   lda PlayerVXL
  728.   ora PlayerVXH
  729.   beq :+
  730.     lda retraces
  731.     and #%100
  732.     beq :+
  733.       lda #$06
  734.       sta PlayerTiles+4
  735.       lda #$07
  736.       sta PlayerTiles+5
  737.   :
  738. NoSpecialAnimation:
  739.  
  740.   ; flip horizontally
  741.   lda PlayerDir
  742.   beq :+
  743.     lda #OAM_XFLIP
  744.     sta Attrib
  745.     swapy PlayerTiles+0, PlayerTiles+1
  746.     swapy PlayerTiles+2, PlayerTiles+3
  747.     swapy PlayerTiles+4, PlayerTiles+5
  748.   :
  749.   lda PlayerDir
  750.   bne :+
  751.     lda DrawX
  752.     sub #8
  753.     sta DrawX
  754.   :
  755.   lda DrawX
  756.   sta DrawX2
  757.  
  758.   ldx OamPtr
  759.   ldy #0     ; current sprite
  760. PutSprite:
  761.   lda PlayerTiles,y
  762.   sta OAM_TILE,x
  763.  
  764.   lda DrawX
  765.   add XPosList,y
  766.   sta OAM_XPOS,x
  767.  
  768.   lda DrawY
  769.   add YPosList,y
  770.   sta OAM_YPOS,x
  771.  
  772.   cpy #1
  773.   bne :+
  774.     lda DrawX
  775.     add MiddleOffsetX
  776.     sta DrawX
  777.   :
  778.  
  779.   lda Attrib
  780.   sta OAM_ATTR,x
  781.   inx
  782.   inx
  783.   inx
  784.   inx
  785.   iny
  786.   cpy #6
  787.   bne PutSprite
  788.   stx OamPtr
  789.  
  790.   lda PlayerTiles+6
  791.   beq NoExtraTile
  792.   sta OAM_TILE,x
  793.   ldy PlayerDir
  794.   lda DrawX
  795.   add ExtraTileX,y
  796.   sta OAM_XPOS,x
  797.   lda DrawY
  798.   add #16
  799.   sta OAM_YPOS,x
  800.   lda Attrib
  801.   sta OAM_ATTR,x
  802.   inx
  803.   inx
  804.   inx
  805.   inx
  806.   stx OamPtr
  807. NoExtraTile:
  808.  
  809.   lda CoinShowTimer
  810.   beq NoCoinShow
  811.     dec CoinShowTimer
  812.     lda PlayerDrawY
  813.     sub #12
  814.     sta OAM_YPOS+(4*0),x
  815.     sta OAM_YPOS+(4*1),x
  816.     sta OAM_YPOS+(4*2),x
  817.     sta OAM_YPOS+(4*3),x
  818.  
  819.     lda DrawX2
  820.     sub #8
  821.     sta OAM_XPOS+(4*0),x
  822.     add #8
  823.     sta OAM_XPOS+(4*1),x
  824.     add #8
  825.     sta OAM_XPOS+(4*2),x
  826.     add #8
  827.     sta OAM_XPOS+(4*3),x
  828.  
  829.     lda #0
  830.     sta OAM_ATTR+(4*0),x
  831.     sta OAM_ATTR+(4*1),x
  832.     sta OAM_ATTR+(4*2),x
  833.     sta OAM_ATTR+(4*3),x
  834.  
  835.     ldy Coins+0
  836.     lda BCD99,y
  837.     pha
  838.     .repeat 4
  839.       lsr
  840.     .endrep
  841.     add #$40
  842.     sta OAM_TILE+(4*2),x
  843.     pla
  844.     and #$0f
  845.     add #$40
  846.     sta OAM_TILE+(4*3),x
  847.  
  848.     ldy Coins+1
  849.     lda BCD99,y
  850.     pha
  851.     .repeat 4
  852.       lsr
  853.     .endrep
  854.     add #$40
  855.     sta OAM_TILE+(4*0),x
  856.     pla
  857.     and #$0f
  858.     add #$40
  859.     sta OAM_TILE+(4*1),x    
  860.  
  861.     txa
  862.     add #16
  863.     sta OamPtr
  864. NoCoinShow:
  865.   rts
  866.  
  867. XPosList: .byt 0, 8, 0, 8, 0,  8
  868. YPosList: .byt 0, 0, 8, 8, 16, 16
  869. ExtraTileX: .byt 16, -8
  870.  
  871. Anim0: .byt $02, $10, $13, $15, $19 ;$20
  872. Anim1: .byt $03, $11, $14, $16, $1a ;$21
  873. Anim2: .byt $04, $12, $12, $17, $1b ;$22
  874. Anim3: .byt $05, $05, $05, $18, $1c ;$23
  875. Anim4: .byt $00, $00, $00, $00, $1d ;$24
  876. AnimO: .byt   0,   0,   0,   2,   3 ;  4
  877. TailAttackFrame:
  878.   .byt 1, 1, 2, 2, 3, 3, 4, 4, 4, 3, 3, 2, 2, 1
  879.  
  880. ; 00 01 | 0f 01 | 0f 01 | 0f 01 | 0f 01     | 0f 01
  881. ; 02 03 | 10 11 | 13 14 | 15 16 | 19 1a     | 20 21
  882. ; 04 05 | 12 05 | 12 05 | 17 18 | 1b 1c 1d  | 22 23 24
  883. .endproc
  884.  
  885. .proc AdjustCamera
  886. LevelIndex = 0   ; index for (ScrollLevelPointer),y
  887. AttrIndex = 1
  888. Temp = 2
  889. ScrollOldX = 4
  890. LevelPointer2 = 6
  891. ScrollDifference = 6
  892. DrawX = Temp
  893. NewCameraX = Temp
  894.  
  895.   lda ScrollX+0
  896.   sta ScrollOldX+0
  897.   lda ScrollX+1
  898.   sta ScrollOldX+1
  899.  
  900. ; FOLLOW THE PLAYER
  901. .scope
  902. player_x = PlayerPXL
  903. player_xhi = PlayerPXH
  904. player_facing = PlayerDirForScroll
  905. camtarget_lo = Temp+0
  906. camtarget_hi = Temp+1
  907. camera_lo = ScrollX+0
  908. camera_hi = ScrollX+1
  909.  
  910.   ; Step 1: Find the position that the camera seeks.
  911.   lda player_x
  912.   sta camtarget_lo
  913.   lda player_xhi
  914.   ldy player_facing  ; 0 for right, 1 for left
  915.   sec
  916.   sbc CameraTargetByFacing,y
  917.   bcs :+
  918.     lda #0
  919.     sta camtarget_lo
  920.     sec
  921. : sta camtarget_hi
  922.  
  923.   ; Step 2: Find the distance that the camera must move
  924.   ; to reach this position.
  925.   lda camtarget_lo
  926.   sbc camera_lo
  927.   sta camtarget_lo
  928.   lda camtarget_hi
  929.   sbc camera_hi
  930.   ; and divide by 4 for smoothing
  931.   cmp #$80
  932.   ror a
  933.   ror camtarget_lo
  934.   cmp #$80
  935.   ror a
  936.   ror camtarget_lo
  937.   sta camtarget_hi
  938.  
  939.   ; Step 3: Add this to produce the camera's new position.
  940.   ; The bit shifted out of camtarget_lo into carry can be used
  941.   ; for free
  942.   lda camtarget_lo
  943.   adc camera_lo
  944.   sta camera_lo
  945.   lda camtarget_hi
  946.   adc camera_hi
  947.   sta camera_hi
  948. .endscope
  949.  
  950. .if 0
  951.   ; Step 1: Find the position that the camera seeks.
  952.   lda PlayerPXL
  953.   sta NewCameraX
  954.   lda PlayerPXH
  955.   ldy PlayerDir
  956.   sec
  957.   sbc SubtractForDirections,y
  958.   bcs :+
  959.     lda #0
  960.     sta NewCameraX
  961.     sec
  962. : sta NewCameraX+1
  963.  
  964.   ; Step 2: Find the distance that the camera must move
  965.   ; to reach this position.
  966.   lda NewCameraX+0
  967.   sbc ScrollX+0
  968.   sta NewCameraX+0
  969.   lda NewCameraX+1
  970.   sbc ScrollX+1
  971.   ; and divide by 4 for smoothing
  972.   cmp #$80
  973.   ror a
  974.   ror NewCameraX+0
  975.   cmp #$80
  976.   ror a
  977.   ror NewCameraX+0
  978.   sta NewCameraX+1
  979.  
  980.   ; Step 3: Add this to produce the camera's new position.
  981.   ; The bit shifted out of camtarget_lo into carry can be used
  982.   ; for free
  983.   lda NewCameraX+0
  984.   adc ScrollX+0
  985.   sta NewCameraX+0
  986.   lda NewCameraX+1
  987.   adc ScrollX+1
  988.   sta NewCameraX+1
  989. .endif
  990. ; ----------------------------------------
  991.  
  992.   lda ScrollX+1
  993.   eor ScrollOldX+1
  994.   and #%10 ; need updates every 32 pixels
  995.   bne :+
  996.   ldx IsScrollUpdate
  997.   beq _rts
  998.   inc ThirtyUpdateAddr+1
  999.   dex
  1000.   jeq UpdateScrollBufferRight
  1001.   dex
  1002.   jeq ScrollBuffer3
  1003.   dex
  1004.   jeq UpdateScrollBufferRight
  1005. _rts:
  1006.   rts
  1007. :
  1008.  
  1009.   lda ScrollX+1
  1010.   cmp ScrollOldX+1
  1011.   beq _rts
  1012.   bcs Right
  1013.  
  1014. Left:
  1015.   lsr
  1016.   sub #2
  1017.   jmp FillIt
  1018. Right:
  1019.   lsr
  1020.   add #10
  1021. FillIt:
  1022.   sta ScrollUpdateChunk
  1023.  
  1024.   ; make level pointer
  1025.   ldy #0
  1026.   sty ScrollLevelPointer+1
  1027.   lda ScrollUpdateChunk
  1028.   .repeat 5
  1029.     asl
  1030.     rol ScrollLevelPointer+1
  1031.   .endrep
  1032.   sta ScrollLevelPointer
  1033.  
  1034.   ; setup second pointer
  1035.   lda ScrollLevelPointer+1
  1036.   ora #$60
  1037.   sta ScrollLevelPointer+1
  1038.   sta LevelPointer2+1
  1039.   lda ScrollLevelPointer
  1040.   add #16
  1041.   sta LevelPointer2
  1042.  
  1043.   ; make ThirtyUpdate address (low part)
  1044.   lda ScrollUpdateChunk
  1045.   and #7
  1046.   asl
  1047.   asl
  1048.   and #31
  1049.   sta ThirtyUpdateAddr+1
  1050.   ; high part
  1051.   lda ScrollUpdateChunk
  1052.   and #%1000 ; becomes 0 or 4
  1053.   lsr
  1054.   ora #$20
  1055.   sta ThirtyUpdateAddr+0
  1056.  
  1057.   ; fill ThirtyUpdate buffer
  1058.   jsr UpdateScrollBufferLeft
  1059.  
  1060.   ; fill attributes buffer
  1061.   ldy #0
  1062.   sty AttrIndex
  1063. LoopAttr:
  1064.   lda (ScrollLevelPointer),y
  1065.   tax
  1066.   lda MetatilePalettes,x
  1067.   and #%00000011
  1068.   sta Temp
  1069.  
  1070.   lda (LevelPointer2),y
  1071.   tax
  1072.   lda MetatilePalettes,x
  1073.   and #%00001100
  1074.   ora Temp
  1075.   sta Temp
  1076.   iny
  1077.  
  1078.   lda (ScrollLevelPointer),y
  1079.   tax
  1080.   lda MetatilePalettes,x
  1081.   and #%00110000
  1082.   ora Temp
  1083.   sta Temp
  1084.  
  1085.   lda (LevelPointer2),y
  1086.   tax
  1087.   lda MetatilePalettes,x
  1088.   and #%11000000
  1089.   ora Temp
  1090.   iny
  1091.  
  1092.   ldx AttrIndex
  1093.   sta AttributeWriteD,x
  1094.   inx
  1095.   stx AttrIndex
  1096.   cpx #8
  1097.   bne LoopAttr
  1098.  
  1099.   ; make attribute addresses
  1100.   lda ScrollUpdateChunk
  1101.   and #7
  1102.   sta Temp
  1103.   ldx #3
  1104. : lda AttributeAddrsLo,x
  1105.   ora Temp
  1106.   sta AttributeWriteA2,x
  1107.   dex
  1108.   bpl :-
  1109.   ; make high address
  1110.   lda ThirtyUpdateAddr+0
  1111.   ora #3
  1112.   sta AttributeWriteA1
  1113.  
  1114.   lda #4
  1115.   sta IsScrollUpdate
  1116.   rts
  1117.  
  1118. AttributeAddrsLo:
  1119.   .byt $c0, $c8, $d0, $d8
  1120.  
  1121. CameraTargetByFacing: ; 3/8 and 5/8
  1122.   .byt 8, 8 ;6, 10
  1123. .endproc
  1124.  
  1125. .proc ScrollBuffer3
  1126.   ; ---- also spawn any sprites we need to spawn ----
  1127.  
  1128.   jsr SpritePointerAdjust
  1129. .if 0
  1130.   lda ScrollUpdateChunk
  1131.   asl
  1132.   sta 1                 ; 1 = destination column
  1133.   ldy CurSpriteIndex
  1134.   lda SpriteListRAM,y   ; current sprite X pos > destination?
  1135.   cmp 1
  1136.   beq No
  1137.   bcc Increase
  1138. Decrease:               ; yes, decrease it
  1139.   jsr SpritePointerDecrease
  1140.   jmp No
  1141. Increase:               ; no, increase it
  1142.   jsr SpritePointerIncrease
  1143. No:
  1144. .endif
  1145.  
  1146.   lda ScrollLevelPointer
  1147.   add #16
  1148.   sta ScrollLevelPointer
  1149.   jmp UpdateScrollBufferLeft
  1150. .endproc
  1151.  
  1152. .if 0 ; TODO: finish and make it faster than the one that iterates through the whole list
  1153. .proc SpritePointerAdjust
  1154.   lda ScrollUpdateChunk
  1155.   asl
  1156.   sta 1
  1157.   ora #1
  1158.   sta 2
  1159.  
  1160.   ldy CurSpriteIndex ; don't try to the left if at the leftmost sprite
  1161.   beq DontTryLeft    ; try going right instead
  1162.   lda SpriteListRAM-3,y
  1163.   cmp 1
  1164.   beq YesLeft
  1165.   cmp 2
  1166.   beq YesLeft
  1167. DontTryLeft:
  1168.  
  1169.   lda SpriteListRAM,y ; don't try to the right if at the rightmost sprite
  1170.   cmp #255
  1171.   beq Exit            ; exit if at the end of the list
  1172.   lda SpriteListRAM+3,y
  1173.   cmp 1
  1174.   beq YesRight
  1175.   cmp 2
  1176.   beq YesRight
  1177.  
  1178. SaveAndExit:
  1179.   sty CurSpriteIndex
  1180. Exit:
  1181.   rts
  1182.  
  1183. YesLeft:
  1184.   dey
  1185.   dey
  1186.   dey
  1187.   jsr TryMakeSprite
  1188.   sty CurSpriteIndex
  1189.   rts
  1190.  
  1191. YesRight:
  1192.   iny
  1193.   iny
  1194.   iny
  1195.   jsr TryMakeSprite
  1196.   sty CurSpriteIndex
  1197.   rts
  1198. .endproc
  1199. .endif
  1200.  
  1201. .if 1
  1202. .proc SpritePointerAdjust ; version that iterates through the ENTIRE list, but isn't buggy
  1203.   lda ScrollUpdateChunk
  1204.   asl
  1205.   sta 1
  1206.   ora #1
  1207.   sta 2
  1208.  
  1209.   ldy #0
  1210. Loop:
  1211.   lda SpriteListRAM,y
  1212.   cmp #255
  1213.   beq Exit
  1214.   cmp 1
  1215.   beq Make
  1216.   cmp 2
  1217.   beq Make  
  1218. Next:
  1219.   iny
  1220.   iny
  1221.   iny
  1222.   bne Loop
  1223.  
  1224. Make:
  1225.   jsr TryMakeSprite
  1226.   jmp Next
  1227.  
  1228. Exit:
  1229.   rts
  1230. .endproc
  1231. .endif
  1232.  
  1233. .if 0
  1234. .proc SpritePointerDecrease ; buggy
  1235. Loop:
  1236.   sty CurSpriteIndex
  1237.   jsr TryMakeSprite
  1238.   ldy CurSpriteIndex
  1239.   cpy #0
  1240.   beq Exit
  1241.   dey
  1242.   dey
  1243.   dey
  1244.   lda SpriteListRAM,y
  1245.   cmp 1
  1246.   bcs Exit
  1247.   bne Loop
  1248. Exit:
  1249.   rts
  1250. .endproc
  1251.  
  1252. .proc SpritePointerIncrease ; buggy
  1253. Loop:
  1254.   sty CurSpriteIndex
  1255.   jsr TryMakeSprite
  1256.   ldy CurSpriteIndex
  1257.   iny
  1258.   iny
  1259.   iny
  1260.   lda SpriteListRAM,y
  1261.   cmp #255
  1262.   beq Exit
  1263.   cmp 1
  1264.   bcs Exit
  1265.   bne Loop
  1266. Exit:
  1267.   rts
  1268. .endproc
  1269. .endif
  1270.  
  1271. .proc TryMakeSprite ; sprite at index Y in the sprite list
  1272.   sty 0
  1273.   ldx #0
  1274. : lda ObjectF1,x             ; if there's a sprite in that location
  1275.   beq :+
  1276.   lda ObjectIndexInLevel,x   ; and it's spawned from this entry in the sprite list
  1277.   cmp 0
  1278.   beq AlreadyMade            ; don't spawn it again
  1279. : inx                        ; try next object slot
  1280.   cpx #ObjectLen
  1281.   bne :--
  1282.   beq NotAlreadyMade
  1283. AlreadyMade:
  1284.   rts
  1285. NotAlreadyMade:              ; okay, go spawn the object
  1286.   jsr FindFreeObjectX
  1287.   bcs :+
  1288.   rts
  1289. :
  1290.  
  1291.   lda SpriteListRAM,y        ; get X
  1292.   sta ObjectPXH,x
  1293.  
  1294.   lda #0                     ; clear stuff out
  1295.   sta ObjectF3,x
  1296.   sta ObjectF4,x
  1297.   sta ObjectTimer,x
  1298.   sta ObjectVXH,x
  1299.   sta ObjectVXL,x
  1300.   sta ObjectVYH,x
  1301.   sta ObjectVYL,x
  1302.   sta ObjectPXL,x
  1303.   sta ObjectPYL,x
  1304.  
  1305.   lda #ENEMY_STATE_INIT
  1306.   sta ObjectF2,x
  1307.  
  1308.   iny
  1309.   lda SpriteListRAM,y  ; get Y and flags
  1310.   and #15
  1311.   sta ObjectPYH,x
  1312.   cmp SpriteListRAM,y  ; check if Y = the Y+Flags byte; if so, no flags
  1313.   beq NoFlags
  1314.   lda SpriteListRAM,y
  1315.   lsr
  1316.   lsr
  1317.   lsr
  1318.   lsr
  1319.   sta ObjectF3,x
  1320.   and #%1000
  1321.   beq NoFlags    ; if the high bit isn't set, not using extended flags
  1322.   tya            ; save Y since we'll need it again right after
  1323.   pha
  1324.   lda ObjectF3,x ; get the 3 bits already written
  1325.   and #%0111     ; select them only
  1326.   sec            ; add LastSpriteIndex+1 since at LastSpriteIndex it's the end of sprite list marker
  1327.   adc LastSpriteIndex
  1328.   tay
  1329.   lda SpriteListRAM,y
  1330.   sta ObjectF3,x
  1331.   pla
  1332.   tay
  1333. NoFlags:
  1334.   iny
  1335.   lda SpriteListRAM,y         ; get type and direction flag
  1336.   sta ObjectF1,x              ; store
  1337.   ldy 0                       ; restore Y to what it was
  1338.   tya
  1339.   sta ObjectIndexInLevel,x    ; no "sty absolute,x" so transfer first
  1340.   rts
  1341. .endproc
  1342.  
  1343. .proc UpdateScrollBufferLeft
  1344. LevelIndex = 0
  1345.   ldy #0
  1346. LoopLeft:
  1347.   sty LevelIndex
  1348.   lda (ScrollLevelPointer),y
  1349.   tax
  1350.   tya
  1351.   asl ; Thirty index is LevelIndex * 2
  1352.   tay
  1353.   lda MetatileUL,x
  1354.   sta ThirtyUpdateTile+0,y
  1355.   lda MetatileLL,x
  1356.   sta ThirtyUpdateTile+1,y
  1357.   ldy LevelIndex
  1358.   iny
  1359.   cpy #15
  1360.   bne LoopLeft
  1361.   rts
  1362. .endproc
  1363.  
  1364. .proc UpdateScrollBufferRight
  1365. LevelIndex = 0
  1366.   ldy #0
  1367. LoopRight:
  1368.   sty LevelIndex
  1369.   lda (ScrollLevelPointer),y
  1370.   tax
  1371.   tya
  1372.   asl ; Thirty index is LevelIndex * 2
  1373.   tay
  1374.   lda MetatileUR,x
  1375.   sta ThirtyUpdateTile+0,y
  1376.   lda MetatileLR,x
  1377.   sta ThirtyUpdateTile+1,y
  1378.   ldy LevelIndex
  1379.   iny
  1380.   cpy #15
  1381.   bne LoopRight
  1382.   rts
  1383. .endproc
  1384.  
  1385. .proc AddCoin
  1386.   lda #60
  1387.   sta CoinShowTimer
  1388.   inc Coins
  1389.   lda Coins
  1390.   cmp #100
  1391.   bne :+
  1392.     lda #0
  1393.     sta Coins
  1394.     inc Coins+1
  1395.     lda Coins+1
  1396.     cmp #100
  1397.       bne :+
  1398.       lda #99
  1399.       sta Coins+1
  1400.   :
  1401.   rts
  1402. .endproc
  1403.  
  1404. .proc DoTailAttack
  1405.   lda PlayerAbility
  1406.   asl
  1407.   tax
  1408.   lda AbilityTable+1,x
  1409.   pha
  1410.   lda AbilityTable+0,x
  1411.   pha
  1412.   rts
  1413.  
  1414. AbilityTable:
  1415.   .raddr AbilityNone
  1416.   .raddr AbilityBlaster
  1417.   .raddr AbilityGlider
  1418.   .raddr AbilityBomb
  1419.   .raddr AbilityFire
  1420.   .raddr AbilityFirework
  1421.   .raddr AbilityNice
  1422.   .raddr AbilityBoomerang
  1423.   .raddr AbilityBall
  1424.   .raddr AbilityWater
  1425.   .raddr AbilityFan
  1426.   .raddr AbilityBurger
  1427.  
  1428. LimitObjectAmount:
  1429. ; limits the number of projectiles to a given amount by aborting if it's already at the limit
  1430.   sta 0  ; 0 = limit
  1431.   ldx #0
  1432.   ldy #0 ; Y = counter for number of player projectiles
  1433. : lda ObjectF1,x
  1434.   and #~1
  1435.   cmp #Enemy::PLAYER_PROJECTILE*2
  1436.   bne :+
  1437.   iny ; yes, this is a player projectile
  1438.   cpy 0
  1439.   bne :+
  1440.   pla ; abort
  1441.   pla
  1442.   rts
  1443. : inx
  1444.   cpx #ObjectLen
  1445.   bne :--
  1446.   rts
  1447.  
  1448. AbilityNone:
  1449.   ldy #PlayerProjectileType::STUN_STAR
  1450.   lda keydown
  1451.   and #KEY_UP
  1452.   beq :+
  1453.   ldy #PlayerProjectileType::COPY_ORB
  1454. : tya
  1455.   jsr MakeShot
  1456.   bcc Exit
  1457.   lda #$20
  1458.   jsr SetXVelocity
  1459.   lda #20/4
  1460.   sta ObjectTimer,x
  1461. Exit:
  1462.   rts
  1463. AbilityBlaster:
  1464.   lda #PlayerProjectileType::BLASTER_SHOT
  1465.   jsr MakeShot
  1466.   bcc @Exit
  1467.   lda #$40
  1468.   jsr SetXVelocity
  1469.   lda #50/4
  1470.   sta ObjectTimer,x
  1471. @Exit:
  1472.   rts
  1473. AbilityGlider:
  1474.   lda #4
  1475.   jsr LimitObjectAmount
  1476.   lda #PlayerProjectileType::LIFE_GLIDER
  1477.   jsr MakeShot
  1478.   bcc @Exit
  1479.   lda keydown
  1480.   and #KEY_UP
  1481.   sta ObjectF3,x
  1482.   lda #140/4
  1483.   sta ObjectTimer,x
  1484. @Exit:
  1485.   rts
  1486. AbilityBomb:
  1487.   lda #2
  1488.   jsr LimitObjectAmount
  1489.   lda #PlayerProjectileType::BOMB
  1490.   jsr MakeShotWide
  1491.   bcc @Exit
  1492.   lda #200/4
  1493.   sta ObjectTimer,x
  1494.   lda keydown
  1495.   and #KEY_UP|KEY_DOWN
  1496.   sta ObjectF3,x
  1497.   and #KEY_UP
  1498.   beq :+
  1499.     lda #$20
  1500.     jsr SetXVelocity
  1501.     lda #-$40
  1502.     sta ObjectVYL,x
  1503.     lda #255
  1504.     sta ObjectVYH,x
  1505.     lsr ObjectTimer,x
  1506.   :
  1507. @Exit:
  1508.   rts
  1509. AbilityFire:
  1510.   lda #3
  1511.   jsr LimitObjectAmount
  1512.   lda #PlayerProjectileType::FIREBALL
  1513.   jsr MakeShotWide
  1514.   bcc @Exit
  1515.   lda #80/4
  1516.   sta ObjectTimer,x
  1517.   lda keydown
  1518.   and #KEY_UP
  1519.   beq :+
  1520.     lda #-$40
  1521.     sta ObjectVYL,x
  1522.     lda #255
  1523.     sta ObjectVYH,x
  1524. : lda keydown
  1525.   and #KEY_DOWN
  1526.   bne :+
  1527.     lda #$20
  1528.     jsr SetXVelocity
  1529. @Exit:
  1530. : rts
  1531. AbilityFirework:
  1532.   lda #1
  1533.   jsr LimitObjectAmount
  1534.   lda #PlayerProjectileType::FIREWORK_CURSOR
  1535.   jsr MakeShot
  1536.   bcc @Exit
  1537.   lda #120/4
  1538.   sta ObjectTimer,x
  1539.   lda #$10
  1540.   jsr SetXVelocity
  1541. @Exit:
  1542.   rts
  1543. AbilityNice:
  1544.   lda #1
  1545.   jsr LimitObjectAmount
  1546.   lda #PlayerProjectileType::ICE_BLOCK
  1547.   jsr MakeShotWide
  1548.   bcc @Exit
  1549.   lda #80/4
  1550.   sta ObjectTimer,x
  1551.   lda #$30
  1552.   jsr SetXVelocity
  1553. @Exit:
  1554.   rts
  1555. AbilityBoomerang:
  1556.   rts
  1557. AbilityBall:
  1558.   lda #1
  1559.   jsr LimitObjectAmount
  1560.   lda #PlayerProjectileType::BALL
  1561.   jsr MakeShotWide
  1562.   bcc @Exit
  1563.   lda #80/4
  1564.   sta ObjectTimer,x
  1565.   lda #$30
  1566.   jsr SetXVelocity
  1567. @Exit:
  1568.   rts
  1569. AbilityWater:
  1570.   lda #PlayerProjectileType::WATER_BOTTLE
  1571.   jsr MakeShotWide
  1572.   bcc @Exit
  1573.   lda #48/4
  1574.   sta ObjectTimer,x
  1575.   lda keydown
  1576.   and #KEY_UP
  1577.   bne :+
  1578.   lda #$20
  1579.   jsr SetXVelocity
  1580. : lda #-$40
  1581.   sta ObjectVYL,x
  1582.   lda #255
  1583.   sta ObjectVYH,x
  1584. @Exit:
  1585.   rts
  1586. AbilityFan:
  1587.   lda #3
  1588.   jsr LimitObjectAmount
  1589.   lda #PlayerProjectileType::TORNADO
  1590.   jsr MakeShotWide
  1591.   bcc @Exit
  1592.   lda #80/4
  1593.   sta ObjectTimer,x
  1594.   lda #$30
  1595.   jsr SetXVelocity
  1596. @Exit:
  1597.   rts
  1598. AbilityBurger:
  1599.   lda #2
  1600.   jsr LimitObjectAmount
  1601.   lda #PlayerProjectileType::BURGER
  1602.   jsr MakeShotWide
  1603.   bcc @Exit
  1604.   lda #80/4
  1605.   sta ObjectTimer,x
  1606.   lda #$30
  1607.   jsr SetXVelocity
  1608. @Exit:
  1609.   rts
  1610.  
  1611. SetXVelocity:
  1612.   sta ObjectVXL,x
  1613.   tay
  1614.   lda #0
  1615.   sta ObjectVXH,x
  1616.   tya
  1617.   ldy PlayerDir
  1618.   beq :+
  1619.   neg
  1620.   sta ObjectVXL,x
  1621.   lda #255
  1622.   sta ObjectVXH,x
  1623. : rts
  1624.  
  1625. MakeShotCommon:
  1626.   jsr ObjectClearX
  1627.   lda 0
  1628.   sta ObjectF2,x
  1629.   lda PlayerPYH
  1630.   adc #0
  1631.   sta ObjectPYH,x
  1632.   rts
  1633.  
  1634. MakeShotWide:
  1635.   sta 0
  1636.   jsr FindFreeObjectX
  1637.   bcs :+
  1638.   clc
  1639.   rts
  1640. : lda #Enemy::PLAYER_PROJECTILE*2
  1641.   sta ObjectF1,x
  1642.   jsr MakeShotCommon
  1643.   lda PlayerPYL
  1644.   add #8*16
  1645.   sta ObjectPYL,x
  1646.   ldy PlayerDir
  1647.   beq Right
  1648. Left16Wide:
  1649.   lda PlayerPXL
  1650.   sta ObjectPXL,x
  1651.   lda PlayerPXH
  1652.   sub #1
  1653.   sta ObjectPXH,x
  1654.   sec
  1655.   rts
  1656.  
  1657. MakeShot:
  1658.   sta 0
  1659.   jsr FindFreeObjectX
  1660.   bcs :+
  1661.   clc
  1662.   rts
  1663. : lda PlayerDir
  1664.   ora #Enemy::PLAYER_PROJECTILE*2
  1665.   sta ObjectF1,x
  1666.   jsr MakeShotCommon
  1667.   lda PlayerPYL
  1668.   add #13*16
  1669.   sta ObjectPYL,x
  1670.   ldy PlayerDir
  1671.   beq Left
  1672. Right:
  1673.   lda PlayerPXL
  1674.   add #$80
  1675.   sta ObjectPXL,x
  1676.   lda PlayerPXH
  1677.   adc #0
  1678.   sta ObjectPXH,x
  1679.   sec
  1680.   rts
  1681. Left:
  1682.   lda PlayerPXL
  1683.   sub #8
  1684.   sta ObjectPXL,x
  1685.   lda PlayerPXH
  1686.   sbc #0
  1687.   sta ObjectPXH,x
  1688.   sec
  1689.   rts
  1690. .endproc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement