LDA isPaused
BEQ +
RTS
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;new code for jump attack
LDA Object_physics_byte,x
AND #%00000001 ;; is it on the ground?
BNE try2
LDA Object_movement,x
AND #%00000111
CMP #%00000110 ;; facing left?
BNE ++
FaceDirection player1_object, FACE_UP_LEFT
JMP+
++
CMP #%00000010 ;;facing right?
BNE +
FaceDirection player1_object, FACE_UP_RIGHT
+
try2:
LDA Object_movement,x
AND #%00000111
CMP #%00000110 ;; facing left?
BNE ++
FaceDirection player1_object, FACE_LEFT
JMP+
++
CMP #%00000010 ;;facing right?
BNE +
FaceDirection player1_object, FACE_RIGHT
+
LDA gamepad
AND #%00010010
CMP #%00010010
BNE goaheads
JMP +
goaheads:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDA gameHandler
AND #%00100000
BEQ notNPCstate_attack
JMP doneAttacking
notNPCstate_attack:
LDA weaponsUnlocked
AND #%00000001
BNE canAttack
JMP doneAttacking
canAttack:
;notAlreadyAttacking:
;nowifonground:
LDX player1_object
GetCurrentActionType player1_object
CMP #$03
BNE notAlreadyAttacking1
JMP doneAttacking
;;;;;
notAlreadyAttacking1:
;;; don't attack if already attacking.
;;; do we have to check for hurt here?
;;;;; Here, we WOULD create melee
ChangeObjectState #$03, #$02
LDA Object_physics_byte,x
AND #%00000001 ;; is it on the ground?
BEQ jumporground
;;;;;;
;;;;;;;;;;;;;;;;
LDA Object_movement,x
AND #%00001111
STA Object_movement,x
LDA #$00
STA Object_h_speed_hi,x
STA Object_h_speed_lo,x
STA Object_v_speed_hi,x
STA Object_v_speed_lo,x
;JMP goherenow
jumporground:
;;;;;;;;;;;;;;;;;;;
LDA Object_x_hi,x
STA temp
LDA Object_y_hi,x
STA temp1
;goherenow:
LDA Object_movement,x
AND #%00000111
STA temp2
TAY
LDA Object_x_hi,x
SEC
SBC #$10 ;; <<--- HERE, you have to set width of melee weapon in HEX (1 tile = 8px, 8 in decimal = #$08 in hex. Use the binary <-> hex converter plugin)
STA temp
LDA Object_scroll,x
SBC #$00
STA temp3
LDA temp
;;; offset x for creation
CLC
ADC weaponOffsetTableX,y
STA temp
LDA temp3
ADC #$00
STA temp3
LDA Object_y_hi,x
CLC
ADC weaponOffsetTableY,y
SEC
SBC #$08 ;; <<--- HERE, you have to set height of melee weapon in HEX (1 tile = 8px, 8 in decimal = #$08 in hex. Use the binary <-> hex converter plugin)
STA temp1
;;;;;;;;;;;;;;;;;
LDA which_weapon
CMP #$01
BEQ ++
JMP weap2
++
;;weap1
CreateObject temp, temp1, #OBJECT_PLAYER_MELEE, #$00, temp3
JMP meleeCreated
weap2:
LDA which_weapon
CMP #$02
BEQ ++
JMP weap3
++
CreateObject temp, temp1, #OBJECT_PLAYER_MELEE, #$01, temp3
JMP meleeCreated
weap3:
LDA which_weapon
CMP #$03
BEQ ++
JMP meleeCreated
++
CreateObject temp, temp1, #OBJECT_PLAYER_MELEE, #$02, temp3
JMP meleeCreated
meleeCreated:
STX player1_weapon
;;;; x is now the newly created object's x.
LDA Object_movement,x
ORA temp2
STA Object_movement,x
;;PlaySound #SND_SLASH
+
doneAttacking:
RTS
;; temporarly put this subroutine here, but would be better into a custom script.
;; fix for the non moving ignore-gravity-objects (like projectiles) in the platform games:
;; (used by the HandleHorizontalInertia macro)
updateXPosForNonPlayerObjects:
CPX player1_object ;; check if it's the player
BEQ doneUpdatingXPosForNonPlayerObjects ;; if it IS, don't need to update
LDA Object_vulnerability,x
AND #%00100000 ;; check if "ignore gravity" is set
BEQ doneUpdatingXPosForNonPlayerObjects ;; if it is NOT, don't need to update
LDA Object_movement,x
AND #%10000000 ;; check if movement horizontal engaged
BEQ doneUpdatingXPosForNonPlayerObjects ;; if it is NOT, don't need to update
LDA xHold_lo
STA Object_x_lo,x
LDA xHold_hi
STA Object_x_hi,x
;LDA nt_hold
;STA Object_scroll,x ;; don't know what to do with this...
doneUpdatingXPosForNonPlayerObjects:
RTS
;; (used by the HandleVerticalInertia macro)
updateYPosForNonPlayerObjects:
CPX player1_object ;; check if it's the player
BEQ doneUpdatingYPosForNonPlayerObjects ;; if it IS, don't need to update
LDA Object_vulnerability,x
AND #%00100000 ;; check if "ignore gravity" is set
BEQ doneUpdatingYPosForNonPlayerObjects ;; if it is NOT, don't need to update
LDA Object_movement,x
AND #%00100000 ;; check if movement vertical engaged
BEQ doneUpdatingYPosForNonPlayerObjects ;; if it is NOT, don't need to update
LDA yHold_lo
STA Object_y_lo,x
LDA yHold_hi
STA Object_y_hi,x
doneUpdatingYPosForNonPlayerObjects:
RTS
MACRO HandleHorizontalInertia
LDA Object_movement,x
AND #%10000000 ;; check if L or R is engaged.
BNE horizontalInputEngaged
;;; there was no horizontal input, however we still need to see if deceleration needs to happen!
JMP checkForHdec
horizontalInputEngaged:
;;;===============================HANDLE HORIZONTAL ACCELERATION==================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; So, if a horizontal input is engaged, we want the acceleration to be able to swing
;;;;; from negative max speed to positive max speed.
;;;;; so the twos compliment of max speed is the negative value.
;;;;; if the left horizontal input is engaged, speed needs to go down by the acceleration value.
;;;;; if the right horizontal input is engaged, speed needs to go up by the acceleration value.
LDA Object_movement,x
AND #%01000000
BEQ LeftInputEngaged_forAccHandle
;;; here, the right input is engaged for acc handling.
LDA Object_h_speed_lo,x
CLC
ADC tempAccAmount
STA Object_h_speed_lo,x
LDA Object_h_speed_hi,x
ADC #$00
STA Object_h_speed_hi,x
;;;; we now have values pushed to horizontal speed,
;;;; but in order to make this stick, we have to check to see if they've surpassed max speed.
;;;; For this, we will need a 16 bit comparison.
LDA Object_h_speed_hi,x
BMI rightMaxSpeedNotReached
CMP temp3
BCC rightMaxSpeedNotReached
BNE rightMaxSpeedIsReached
LDA Object_h_speed_lo,x
CMP temp2
BCC rightMaxSpeedNotReached
rightMaxSpeedIsReached:
LDA temp2
STA Object_h_speed_lo,x
LDA temp3
STA Object_h_speed_hi,x
rightMaxSpeedNotReached:
JMP doneGettingInertia
LeftInputEngaged_forAccHandle:
LDA Object_h_speed_lo,x
sec
sbc tempAccAmount
STA Object_h_speed_lo,x
LDA Object_h_speed_hi,x
sbc #$00
STA Object_h_speed_hi,x
;;;; we now have values pushed to horizontal speed,
;;;; but in order to make this stick, we have to check to see if they've surpassed max speed.
;;;; For this, we will need a 16 bit comparison.
LDA Object_h_speed_lo,x
CLC
ADC temp2
LDA Object_h_speed_hi,x
ADC temp3
BPL leftMaxSpeedNotReached
;; max speed is reached;
LDA #$00
SEC
SBC temp2
STA Object_h_speed_lo,x
LDA #$00
;SEC
SBC temp3
STA Object_h_speed_hi,x
leftMaxSpeedNotReached:
;;;;;;;;;;;;;;;; GET ABSOLUTE VALUE FOR h speeds.
JMP doneGettingInertia
checkForHdec:
;; here we will be checking for hozizontal deceleration
LDA Object_h_speed_lo,x
CLC
ADC #$00
LDA Object_h_speed_hi,x
ADC #$00
;;;we need to know whether to ADD or SUBTRACT from speed.
;;; if the current speed is negative, we need to add to the speed until it passes zero, then zero it out.
;;; if the current speed is positive, we need to subtract from the speed until it passes zero, then zero it out.
BMI hSpeedIsNegative
;;;; here, hSpeed is positive.
;;;; so we need to subtract until we cross the zero threshold.
LDA Object_h_speed_lo,x
SEC
SBC tempAccAmount
STA Object_h_speed_lo,x
LDA Object_h_speed_hi,x
SBC #$00
STA Object_h_speed_hi,x
BMI setHspeedToZero
;;; we had not reached zero yet.
;;; so keep the new update to speed and
;;; continue on.
JMP doneGettingInertia
hSpeedIsNegative:
;;; here, hSpeed is negative
;;; so we need to add until we cross the zero threshold
LDA Object_h_speed_lo,x
CLC
ADC tempAccAmount
STA Object_h_speed_lo,x
LDA Object_h_speed_hi,x
ADC #$00
STA Object_h_speed_hi,x
BPL setHspeedToZero
;;; we had not reached zero yet
;;; so keep the new update to speed and
;;; continue on.
JMP doneGettingInertia
setHspeedToZero:
LDA #$00
STA Object_h_speed_hi,x
STA Object_h_speed_lo,x
JMP doneGettingInertia
doneGettingInertia:
LDA Object_h_speed_lo,x
CLC
ADC #$00
LDA Object_h_speed_hi,x
ADC #$00
BMI inertiaIsNegative
;;; intertia is positive.
LDA Object_x_lo,x
CLC
ADC Object_h_speed_lo,x
;STA Object_x_lo,x
STA xHold_lo
LDA Object_x_hi,x
ADC Object_h_speed_hi,x
;STA Object_x_hi,x
STA xHold_hi
LDA Object_scroll,x
ADC #$00
;STA Object_scroll,x
STA nt_hold
;; small fix for the ignore gravity objects (maybe issues with other objects in some another cases?)
JSR updateXPosForNonPlayerObjects
;;;; here is a macro that handles player guided right scrolling.
;;;; you can disable right scrolling by simply commenting this one macro out.
LDA screenFlags
AND #%00000100 ;; is it auto scrolling?
BNE + ;; NOT autoscrolling
;; is auto scroll, so does not deal with scrolling.
LDA screenFlags
AND #%00010000
BEQ +
DoPlayerGuidedRightScroll
+
JMP doneGettingNewPotentialHorizintalPosition
inertiaIsNegative:
LDA Object_h_speed_lo,x
EOR #$FF
;CLC
;ADC #$01
STA temp
LDA Object_h_speed_hi,x
EOR #$FF
;CLC
;ADC #$01
STA temp1
LDA Object_x_lo,x
SEC
SBC temp
;STA Object_x_lo,x
STA xHold_lo
LDA Object_x_hi,x
SBC temp1
;STA Object_x_hi,x
STA xHold_hi
LDA Object_scroll,x
SBC #$00
;STA Object_scroll,x
STA nt_hold
;; small fix for the ignore gravity objects (maybe issues with other objects in some another cases?)
JSR updateXPosForNonPlayerObjects
;;; this handles player guided left scrolling
;;; to disable left scrolling, simply comment this one macro out.
LDA screenFlags
AND #%00000100 ;; is it auto scrolling?
BNE + ;; NOT autoscrolling
;; is auto scroll, so does not deal with scrolling.
LDA screenFlags
AND #%00001000
BEQ +
DoPlayerGuidedLeftScroll
+
;JMP doneGettingNewPotentialHorizintalPosition ;; redundant if flows directly into it.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;========================================================
doneGettingNewPotentialHorizintalPosition:
ENDM
MACRO HandleVerticalInertia
;;VERTICAL MOVEMENT CHECKS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDA Object_movement,x
AND #%00100000 ;; check if L or R is engaged.
BNE verticalInputEngaged
;;; there was no horizontal input, however we still need to see if deceleration needs to happen!
JMP checkForVdec
verticalInputEngaged:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;===============================HANDLE Vertial ACCELERATION==================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; So, if a vertical input is engaged, we want the acceleration to be able to swing
;;;;; from negative max speed to positive max speed.
;;;;; so the twos compliment of max speed is the negative value.
;;;;; if the up vertical input is engaged, speed needs to go down by the acceleration value.
;;;;; if the down horizontal input is engaged, speed needs to go up by the acceleration value.
LDA Object_movement,x
AND #%00010000
BEQ UpInputEngaged_forAccHandle
;;; here, the down input is engaged for acc handling.
LDA Object_v_speed_lo,x
CLC
ADC tempAccAmount
STA Object_v_speed_lo,x
LDA Object_v_speed_hi,x
ADC #$00
STA Object_v_speed_hi,x
;;;; we now have values pushed to vertical speed,
;;;; but in order to make this stick, we have to check to see if they've surpassed max speed.
;;;; For this, we will need a 16 bit comparison.
LDA Object_v_speed_hi,x
BMI downMaxSpeedNotReached
CMP temp3
BCC downMaxSpeedNotReached
BNE downMaxSpeedIsReached
LDA Object_v_speed_lo,x
CMP temp2
BCC downMaxSpeedNotReached
downMaxSpeedIsReached:
LDA temp2
STA Object_v_speed_lo,x
LDA temp3
STA Object_v_speed_hi,x
downMaxSpeedNotReached:
JMP doneGettingVInertia
UpInputEngaged_forAccHandle:
LDA Object_v_speed_lo,x
sec
sbc tempAccAmount
STA Object_v_speed_lo,x
LDA Object_v_speed_hi,x
sbc #$00
STA Object_v_speed_hi,x
;;;; we now have values pushed to vertical speed,
;;;; but in order to make this stick, we have to check to see if they've surpassed max speed.
;;;; For this, we will need a 16 bit comparison.
LDA Object_v_speed_lo,x
CLC
ADC temp2
LDA Object_v_speed_hi,x
ADC temp3
BPL upMaxSpeedNotReached
;; max speed is reached;
upMaxSpeedIsReached:
LDA #$00
SEC
SBC temp2
STA Object_v_speed_lo,x
LDA #$00
;SEC
SBC temp3
STA Object_v_speed_hi,x
upMaxSpeedNotReached:
;;;;;;;;;;;;;;;; GET ABSOLUTE VALUE FOR v speeds.
JMP doneGettingVInertia
checkForVdec:
;; here we will be checking for hozizontal deceleration
LDA Object_v_speed_lo,x
CLC
ADC #$00
LDA Object_v_speed_hi,x
ADC #$00
;;;we need to know whether to ADD or SUBTRACT from speed.
;;; if the current speed is negative, we need to add to the speed until it passes zero, then zero it out.
;;; if the current speed is positive, we need to subtract from the speed until it passes zero, then zero it out.
BMI vSpeedIsNegative
;;;; here, hSpeed is positive.
;;;; so we need to subtract until we cross the zero threshold.
LDA Object_v_speed_lo,x
SEC
SBC tempAccAmount
STA Object_v_speed_lo,x
LDA Object_v_speed_hi,x
SBC #$00
STA Object_v_speed_hi,x
BMI setVspeedToZero
;;; we had not reached zero yet.
;;; so keep the new update to speed and
;;; continue on.
JMP doneGettingVInertia
vSpeedIsNegative:
;;; here, hSpeed is negative
;;; so we need to add until we cross the zero threshold
LDA Object_v_speed_lo,x
CLC
ADC tempAccAmount
STA Object_v_speed_lo,x
LDA Object_v_speed_hi,x
ADC #$00
STA Object_v_speed_hi,x
BPL setVspeedToZero
;;; we had not reached zero yet
;;; so keep the new update to speed and
;;; continue on.
JMP doneGettingVInertia
setVspeedToZero:
LDA #$00
STA Object_v_speed_hi,x
STA Object_v_speed_lo,x
JMP doneGettingVInertia
doneGettingVInertia:
LDA Object_v_speed_lo,x
CLC
ADC #$00
LDA Object_v_speed_hi,x
ADC #$00
BMI VinertiaIsNegative
;;; intertia is positive.
LDA Object_y_lo,x
CLC
ADC Object_v_speed_lo,x
;STA Object_y_lo,x
STA yHold_lo
LDA Object_y_hi,x
ADC Object_v_speed_hi,x
;STA Object_y_hi,x
STA yHold_hi
;; small fix for the ignore gravity objects (maybe issues with other objects in some another cases?)
JSR updateYPosForNonPlayerObjects
;;;; HERE IS WHERE WE MIGHT ADD DOWNWARD SCROLLING.
JMP doneGettingNewPotentialVerticalPosition
VinertiaIsNegative:
LDA Object_v_speed_lo,x
EOR #$FF
STA temp
LDA Object_v_speed_hi,x
EOR #$FF
STA temp1
LDA Object_y_lo,x
SEC
SBC temp
;STA Object_y_lo,x
STA yHold_lo
LDA Object_y_hi,x
SBC temp1
;STA Object_y_hi,x
STA yHold_hi
;; small fix for the ignore gravity objects (maybe issues with other objects in some another cases?)
JSR updateYPosForNonPlayerObjects
;;; this handles player guided left scrolling
;;; to disable left scrolling, simply comment this one macro out.
; DoPlayerGuidedLeftScroll
JMP doneGettingNewPotentialVerticalPosition ;; redundant if flows directly into it.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;========================================================
doneGettingNewPotentialVerticalPosition:
ENDM
HandleTileCollision:
;;;;;ASSUMES vulnerability bit 000x0000, if one, skips collision.
;;;;;Six collision points.
;;;;;All collision points checked and registered for all objects.
;;;; a solid in any of the points will result in negating all others.
;;; There are 6 ram variables, collisionPoint0 - collisionPoint5.
;;; collisionPoint0 = top left
;;; collisionPoint1 = top right
;;; collisionPoint2 = bottom right
;;; collisionPoint3 = bottom left.
;;; collisionPoint4 = mid left
;;; collisionPoint5 = mid right.
TXA
STA currentObject
TYA
STA tempy
LDA npc_collision
AND #%11111101
LDA #$00
STA npc_collision
LDA navFlag
AND #%11111110
STA navFlag
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; EXPLANATION:
;; In this basic module, both non gravity and gravity scripts are loaded.
;; Under most circumstances, a user will likely make use of one or the other,
;; as they each take up a good chunk of data. But the benefit of including both is that
;; a platforming game with gravity is just a simple bit flip in the screen flags.
LDA screenFlags
AND #%00100000
BNE useGravity
JMP dontUseGravity
useGravity:
LDA Object_vulnerability,x
AND #%00100000
BEQ useGravity2
LDA Object_physics_byte,x
AND #%00000010
BNE useGravity2
JMP dontUseGravity
useGravity2:
;;;;;;===================================================
;;;;;;***************************************************
;;;;;; TILE COLLISION FOR SCROLLING PLATFORMERS:
;;;;;; For scrolling platformers we will use three types of collision detection:
;;;;;; 1. A routine to check under our feet to determine
;;;;;; whether or not you are standing on a solid object.
;;; This function will check under neath the object's feet
;;; by arg0 pixels.
;;; it will update bit 0 of the Object_physics_byte.
;;; If that bit is 0, it means the place is free.
;;; If that bit is 1, it means the place is solid.
;**********************
CheckUnderObject #$01
;;;;;;
;;;;;; 2. A routine that checks to see if the potential position leaves you
;;;;;; with your 'bottom' or 'top' in a solid object, in which case it ejects pixel perfect
;;;;;; to that tile.
;;; This function checks the POTENTIAL vertical position.
;;; If it results in a point in a solid object, it appropriately
;;; ejects and places the object directly against the point
;;; of collision.
; **********************
CheckForVerticalEjection
;;;;;;
;;;;;; 3. A routine which checks horizontal motion to see if the potential position
;;;;;; sees a solid collision, in which case it can not move.
;;; This function checks potential horizontal position.
;;; without factoring in vertical motion. If it sees a solid,
;;; it skips motion.
; ***********************
CheckForHorizontalCollision
;;;; This is the end of scrolling platform physics. It automatically jumps to the proper place.
;;;; Otherwise, if there was no collision, we jump to updating the position.
;; we only need to update horizontal position
CheckPlayerCameraPosition
;;;; if it turns out we were outside of the camera bounds, the macro
;;;; has RTSed out of this routine, so the hoziontal position will
;;;; never be updated.
JSR updateHorizontalPosition
JMP DoneWithTileChecksAndUpdatePosition
;;;;;;;;;;;;;==============================================
dontUseGravity:
;;;;;;===================================================
;;;;;;***************************************************
;;;;;; TILE COLLISION FOR TOP DOWN GAMES:
;;;; Before we update the position, though, if this is a scrolling game, we need to see if the player
;;;; is at the edge of the camera. If he is at the edge of the camera, it
;;;; will do a bounds check.
CheckPlayerCameraPosition
;;;; if it turns out we were outside of the camera bounds, the macro
;;;; has RTSed out of this routine, so the hoziontal position will
;;;; never be updated.
;;;;; For top down type games, or games that generally have no gravity but have 4 directional movement,
;;;;; we only need to check potential position and jump to the appropriate label.
CheckPotentialPosition ;; <<-- uncomment this line (for checking vertical collisions)
CheckForHorizontalCollision ;; <<--- checking horizontal solid collisions
CheckForHorizontalCollision ;; check solid collisions now
JSR updateHorizontalPosition
; JSR updateVerticalPosition
;;;; THis is the end of top down scrolling physics. It automatically jumps to the proper place.
;;;; Otherwise, if there was no collision, we jump to updating the position.
JMP DoneWithTileChecksAndUpdatePosition
;;; NO POINTS WERE SOLID
;;;; update hold
DoneWithTileChecksAndUpdatePosition:
ldx currentObject
RTS
HandleSolidCollision:
LDA screenFlags
AND #%00000100 ;; is it autoscrolling?
BEQ + ;; not autoscrolling
;;; is auto scrolling
CPX player1_object
BNE +
JSR CheckAutoScrollLeftEdge
RTS
+ ;; not auto scrolling.
LDA xPrev
STA xHold_hi
LDA yPrev
STA yHold_hi
TYA
STA tempy
LDA Object_edge_action,x
LSR
LSR
LSR
LSR
BEQ doNothingAtSolid
TAY
LDA AI_ReactionTable_Lo,y
STA temp16
LDA AI_ReactionTable_Hi,y
STA temp16+1
JSR doReactionTrampolineSolid
JMP pastReactionTrampolineSolid
doReactionTrampolineSolid:
JMP (temp16) ;;; this now does the action
;; and when it hits the RTS in that action,
;; it will jump back to the last JSR it saw,
;; which was doNewActionTrampoline...which will immediately
;; jump to pastDoNewActionTrampoline.
pastReactionTrampolineSolid:
;LDA #$00
;STA xHold_lo
doNothingAtSolid:
;;;;;;;;;;; Do solid reaction type.
LDY tempy
LDX currentObject
RTS
ejectUp:
LDA tileY
and #%00001111;We can only be 0 to 15 pixels in any given wall
sta temp
lda Object_y_hi,x
clc;Subtract one plus that so we're a pixel out of the wall rather than one pixel in it.
SBC temp
STA Object_y_hi,x
LDA #$00
STA yHold_lo
STA Object_v_speed_hi,x
STA Object_v_speed_lo,x
RTS
ejectDown:
lda tileY
and #%00001111;we can only be 0 to 15 pixels in any given wall
eor #%00001111;If we're at position 15 in the tile, we only want to eject 0 (+1) so flip the bits
sec;Will add the extra one to the position so that we're a pixel out of the wall
adc Object_y_hi,x;rather than one pixel in it.
sta Object_y_hi,x
LDA #$00
STA yHold_lo
STA Object_v_speed_hi,x
STA Object_v_speed_lo,x
;;; check the top two collision points to see if is it a prize block.
LDA collisionPoint0
CMP #COL_INDEX_PRIZE_BLOCK
BEQ +
JMP ++
+
LDA Object_x_hi,x
CLC
ADC Object_left,x
STA tileX
JMP +++
++
LDA collisionPoint1
CMP #COL_INDEX_PRIZE_BLOCK
BEQ +
JMP ++
+
LDA Object_x_hi,x
CLC
ADC Object_right,x
STA tileX
+++
LDA gameHandler
ORA #%00010000
STA gameHandler
;;;;; check other head-hit type objects here.
;; change collision data.
;; should still have the correct coordinates in tileX and tileY
ChangeTileAtCollision #COL_INDEX_PRIZE_BLOCK_OFF, #TILE_INDEX_PRIZE_OFF
TXA
PHA
LDA Object_x_hi,x
STA temp
LDA Object_y_hi,x
SEC
SBC #$1A ;; a bit more than the height of it.
STA temp1
LDA Object_scroll,x
STA temp2
CreateObject temp, temp1, #OBJ_PRIZE, #$00, temp2
LDA #$00
SEC
SBC #$04
STA Object_v_speed_hi,x
PLA
TAX
++
RTS
CheckForCollision:
;;;; commonly, we won't want to waste cycling 6 times through this for each object when
;;;; all points are at no collision. If by chance we NEED the zero type collision to do something,
;;;; we can comment out the zero type check in this next line. But most games are going to have
;;;; at least one "blank tile" that does nothing, and most games will use zero for this.
;;;; Another conundrum is that a collision could take place in the current or new nametable.
;;;; if this collision is of type that draws from screen data (for instance, NPC data or warp data), it could
;;;; be problematic, as all variables handling these things are loaded with the current collision tables data.
;;;; tempCol ends up being 0 or 1 based on which collision table this should be referencing.
STA temp
BNE notZeroTypeCollision
JMP zeroTypeCollision
notZeroTypeCollision:
LDA #$00
STA tile_solidity
DoCheckPointsLoop:
LDA temp
TAY
LDA tileTypeBehaviorLo,y
STA temp16
LDA tileTypeBehaviorHi,y
STA temp16+1
JSR UseTileTypeTrampoline
JMP pastTileTypeTrampoline
UseTileTypeTrampoline:
JMP (temp16)
pastTileTypeTrampoline:
DontCheckTileType0:
zeroTypeCollision:
ldx currentObject
RTS
DetermineCollisionTable:
LDA tempCol
BNE colPointInDifferentTable
;;;; the collision point is in the current collision table.
LDA Object_scroll,x
AND #%00000001
BNE isInOddTable
JMP isInEvenTable
colPointInDifferentTable:
;;; the collision point to be checked is in the NEXT collision table.
LDA Object_scroll,x
AND #%00000001
BNE isInEvenTable
JMP isInOddTable
isInEvenTable:
LDA collisionTable,y
RTS
isInOddTable:
LDA collisionTable2,y
RTS
updateHorizontalPosition:
LDA xHold_lo
STA Object_x_lo,x
LDA xHold_hi
STA Object_x_hi,x
LDA nt_hold
CMP Object_scroll,x
BEQ justUpdateScroll
LDA #$01
STA update_screen_data_flag
LDA nt_hold
justUpdateScroll:
STA Object_scroll,x
RTS
updateVerticalPosition:
LDA yHold_lo
STA Object_y_lo,x
LDA yHold_hi
STA Object_y_hi,x
RTS
LDA isPaused
BEQ +
RTS
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;new code for jump attack
LDA Object_physics_byte,x
AND #%00000001 ;; is it on the ground?
BNE try1
LDA Object_movement,x
AND #%00000111
CMP #%00000110 ;; facing left?
BNE ++
FaceDirection player1_object, FACE_UP_LEFT
JMP+
++
CMP #%00000010 ;;facing right?
BNE +
FaceDirection player1_object, FACE_UP_RIGHT
+
try1:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;new code for jump attack/button combos allowed
LDA gamepad
CMP #%00010011
BEQ canShoot
CMP #%10010011
BEQ canShoot
CMP #%01010011
BEQ canShoot
LDA gamepad
CMP #%00010010
BEQ canShoot
CMP #%10010010
BEQ canShoot
CMP #%01010010
BEQ canShoot
JMP doneShooting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
canShoot:
;; We count the projectile already on screen to see if can Shoot another one :
CountObjects #%00000100, #$00 ;; count player weapon on screen
LDA monsterCounter ;; the variable used to count is monsterCounter
CLC
CMP #PROJECTILE_MAX ;; compare to 2
BCC + ;; if less than 2 on screen we can create a projectile
RTS ;; else we quit
+
LDX player1_object
;;; check if already shooting
CMP #$06
BNE notAlreadyShooting
JMP wasAlreadyShooting
notAlreadyShooting
+
++
ChangeObjectState #$03 , #$02
;;;if you wanna stop player comment out next eight lines
LDY player1_object
CPY #$FF;;;;;
BNE playerCanCreateProjectile
RTS
playerCanCreateProjectile:
LDA limitProjectile
BNE continueCreateProjectile
RTS
continueCreateProjectile:
DEC limitProjectile
LDA Object_physics_byte,x
AND #%00000001 ;; is it on the ground?
BEQ wasAlreadyShooting
LDA Object_movement,x
AND #%00001111
STA Object_movement,x
LDA #$00
STA Object_h_speed_hi,x
STA Object_h_speed_lo,x
STA Object_v_speed_hi,x
STA Object_v_speed_lo,x
; if was already shooting
wasAlreadyShooting:
LDA Object_movement,x
AND #%00000111
STA temp2
TAY
LDA Object_x_hi,x
SEC
SBC #$08 ;; width
STA temp
LDA Object_scroll,x
SBC #$00
STA temp3
LDA temp;;; offset x for creation
CLC
ADC projOffsetTableX,y
STA temp
LDA temp3
ADC #$00
STA temp3
LDA Object_y_hi,x
CLC
ADC projOffsetTableY,y
sec
sbc #$08 ;; height
STA temp1
;;test if player has weaponm 1
;LDA weaponsUnlocked
;AND #%00000001
;BEQ playerDoesNotHaveWeapon1
;else weapon 1 is now unlocked
;;test if player has weaponm 2
;LDA weaponsUnlocked
; AND #%00000010
;BEQ playerDoesNotHaveWeapon2
;else weapon 2is now unlocked
; continueCreatingTheProjectileObject:
CreateObject temp , temp1, #OBJECT_PLAYER_PROJECTILE, #$00, temp3
;;;;x is now the newly created objects x
LDA Object_movement,x
ORA temp2
STA Object_movement,x
LDY temp2
LDA directionTable,y
ORA Object_movement,x
STA Object_movement,x
;PlaySound #SND_SHOOT
++
doneShooting:
;DEC limitProjectile
RTS
STA temp2
CMP #%00000100
BCS +
LDA #FACE_RIGHT
STA temp2
JMP ++
+
LDA #FACE_LEFT
STA temp2
++
MACRO HandleVerticalInertia
;;VERTICAL MOVEMENT CHECKS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDA Object_movement,x
AND #%00100000 ;; check if L or R is engaged.
BNE verticalInputEngaged
;;; there was no horizontal input, however we still need to see if deceleration needs to happen!
JMP checkForVdec
verticalInputEngaged:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;===============================HANDLE Vertial ACCELERATION==================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; So, if a vertical input is engaged, we want the acceleration to be able to swing
;;;;; from negative max speed to positive max speed.
;;;;; so the twos compliment of max speed is the negative value.
;;;;; if the up vertical input is engaged, speed needs to go down by the acceleration value.
;;;;; if the down horizontal input is engaged, speed needs to go up by the acceleration value.
LDA Object_movement,x
AND #%00010000
BEQ UpInputEngaged_forAccHandle
;;; here, the down input is engaged for acc handling.
LDA Object_v_speed_lo,x
CLC
ADC tempAccAmount
STA Object_v_speed_lo,x
LDA Object_v_speed_hi,x
ADC #$00
STA Object_v_speed_hi,x
;;;; we now have values pushed to vertical speed,
;;;; but in order to make this stick, we have to check to see if they've surpassed max speed.
;;;; For this, we will need a 16 bit comparison.
LDA Object_v_speed_hi,x
BMI downMaxSpeedNotReached
CMP temp3
BCC downMaxSpeedNotReached
BNE downMaxSpeedIsReached
LDA Object_v_speed_lo,x
CMP temp2
BCC downMaxSpeedNotReached
downMaxSpeedIsReached:
LDA temp2
STA Object_v_speed_lo,x
LDA temp3
STA Object_v_speed_hi,x
downMaxSpeedNotReached:
JMP doneGettingVInertia
UpInputEngaged_forAccHandle:
LDA Object_v_speed_lo,x
sec
sbc tempAccAmount
STA Object_v_speed_lo,x
LDA Object_v_speed_hi,x
sbc #$00
STA Object_v_speed_hi,x
;;;; we now have values pushed to vertical speed,
;;;; but in order to make this stick, we have to check to see if they've surpassed max speed.
;;;; For this, we will need a 16 bit comparison.
LDA Object_v_speed_lo,x
CLC
ADC temp2
LDA Object_v_speed_hi,x
ADC temp3
BPL upMaxSpeedNotReached
;; max speed is reached;
upMaxSpeedIsReached:
LDA #$00
SEC
SBC temp2
STA Object_v_speed_lo,x
LDA #$00
;SEC
SBC temp3
STA Object_v_speed_hi,x
upMaxSpeedNotReached:
;;;;;;;;;;;;;;;; GET ABSOLUTE VALUE FOR v speeds.
JMP doneGettingVInertia
checkForVdec:
;; here we will be checking for hozizontal deceleration
LDA Object_v_speed_lo,x
CLC
ADC #$00
LDA Object_v_speed_hi,x
ADC #$00
;;;we need to know whether to ADD or SUBTRACT from speed.
;;; if the current speed is negative, we need to add to the speed until it passes zero, then zero it out.
;;; if the current speed is positive, we need to subtract from the speed until it passes zero, then zero it out.
BMI vSpeedIsNegative
;;;; here, hSpeed is positive.
;;;; so we need to subtract until we cross the zero threshold.
LDA Object_v_speed_lo,x
SEC
SBC tempAccAmount
STA Object_v_speed_lo,x
LDA Object_v_speed_hi,x
SBC #$00
STA Object_v_speed_hi,x
BMI setVspeedToZero
;;; we had not reached zero yet.
;;; so keep the new update to speed and
;;; continue on.
JMP doneGettingVInertia
vSpeedIsNegative:
;;; here, hSpeed is negative
;;; so we need to add until we cross the zero threshold
LDA Object_v_speed_lo,x
CLC
ADC tempAccAmount
STA Object_v_speed_lo,x
LDA Object_v_speed_hi,x
ADC #$00
STA Object_v_speed_hi,x
BPL setVspeedToZero
;;; we had not reached zero yet
;;; so keep the new update to speed and
;;; continue on.
JMP doneGettingVInertia
setVspeedToZero:
LDA #$00
STA Object_v_speed_hi,x
STA Object_v_speed_lo,x
JMP doneGettingVInertia
doneGettingVInertia:
LDA Object_v_speed_lo,x
CLC
ADC #$00
LDA Object_v_speed_hi,x
ADC #$00
BMI VinertiaIsNegative
;;; intertia is positive.
LDA Object_y_lo,x
CLC
ADC Object_v_speed_lo,x
;STA Object_y_lo,x
STA yHold_lo
LDA Object_y_hi,x
ADC Object_v_speed_hi,x
;STA Object_y_hi,x
STA yHold_hi
;; small fix for the ignore gravity objects (maybe issues with other objects in some another cases?)
JSR updateYPosForNonPlayerObjects
;;;; HERE IS WHERE WE MIGHT ADD DOWNWARD SCROLLING.
JMP doneGettingNewPotentialVerticalPosition
VinertiaIsNegative:
LDA Object_v_speed_lo,x
EOR #$FF
STA temp
LDA Object_v_speed_hi,x
EOR #$FF
STA temp1
LDA Object_y_lo,x
SEC
SBC temp
;STA Object_y_lo,x
STA yHold_lo
LDA Object_y_hi,x
SBC temp1
;STA Object_y_hi,x
STA yHold_hi
;;; this handles player guided left scrolling
;;; to disable left scrolling, simply comment this one macro out.
; DoPlayerGuidedLeftScroll
JMP doneGettingNewPotentialVerticalPosition ;; redundant if flows directly into it.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;========================================================
doneGettingNewPotentialVerticalPosition:
ENDM
ACRO HandleHorizontalInertia
LDA Object_movement,x
AND #%10000000 ;; check if L or R is engaged.
BNE horizontalInputEngaged
;;; there was no horizontal input, however we still need to see if deceleration needs to happen!
JMP checkForHdec
horizontalInputEngaged:
;;;===============================HANDLE HORIZONTAL ACCELERATION==================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; So, if a horizontal input is engaged, we want the acceleration to be able to swing
;;;;; from negative max speed to positive max speed.
;;;;; so the twos compliment of max speed is the negative value.
;;;;; if the left horizontal input is engaged, speed needs to go down by the acceleration value.
;;;;; if the right horizontal input is engaged, speed needs to go up by the acceleration value.
LDA Object_movement,x
AND #%01000000
BEQ LeftInputEngaged_forAccHandle
;;; here, the right input is engaged for acc handling.
LDA Object_h_speed_lo,x
CLC
ADC tempAccAmount
STA Object_h_speed_lo,x
LDA Object_h_speed_hi,x
ADC #$00
STA Object_h_speed_hi,x
;;;; we now have values pushed to horizontal speed,
;;;; but in order to make this stick, we have to check to see if they've surpassed max speed.
;;;; For this, we will need a 16 bit comparison.
LDA Object_h_speed_hi,x
BMI rightMaxSpeedNotReached
CMP temp3
BCC rightMaxSpeedNotReached
BNE rightMaxSpeedIsReached
LDA Object_h_speed_lo,x
CMP temp2
BCC rightMaxSpeedNotReached
rightMaxSpeedIsReached:
LDA temp2
STA Object_h_speed_lo,x
LDA temp3
STA Object_h_speed_hi,x
rightMaxSpeedNotReached:
JMP doneGettingInertia
LeftInputEngaged_forAccHandle:
LDA Object_h_speed_lo,x
sec
sbc tempAccAmount
STA Object_h_speed_lo,x
LDA Object_h_speed_hi,x
sbc #$00
STA Object_h_speed_hi,x
;;;; we now have values pushed to horizontal speed,
;;;; but in order to make this stick, we have to check to see if they've surpassed max speed.
;;;; For this, we will need a 16 bit comparison.
LDA Object_h_speed_lo,x
CLC
ADC temp2
LDA Object_h_speed_hi,x
ADC temp3
BPL leftMaxSpeedNotReached
;; max speed is reached;
LDA #$00
SEC
SBC temp2
STA Object_h_speed_lo,x
LDA #$00
;SEC
SBC temp3
STA Object_h_speed_hi,x
leftMaxSpeedNotReached:
;;;;;;;;;;;;;;;; GET ABSOLUTE VALUE FOR h speeds.
JMP doneGettingInertia
checkForHdec:
;; here we will be checking for hozizontal deceleration
LDA Object_h_speed_lo,x
CLC
ADC #$00
LDA Object_h_speed_hi,x
ADC #$00
;;;we need to know whether to ADD or SUBTRACT from speed.
;;; if the current speed is negative, we need to add to the speed until it passes zero, then zero it out.
;;; if the current speed is positive, we need to subtract from the speed until it passes zero, then zero it out.
BMI hSpeedIsNegative
;;;; here, hSpeed is positive.
;;;; so we need to subtract until we cross the zero threshold.
LDA Object_h_speed_lo,x
SEC
SBC tempAccAmount
STA Object_h_speed_lo,x
LDA Object_h_speed_hi,x
SBC #$00
STA Object_h_speed_hi,x
BMI setHspeedToZero
;;; we had not reached zero yet.
;;; so keep the new update to speed and
;;; continue on.
JMP doneGettingInertia
hSpeedIsNegative:
;;; here, hSpeed is negative
;;; so we need to add until we cross the zero threshold
LDA Object_h_speed_lo,x
CLC
ADC tempAccAmount
STA Object_h_speed_lo,x
LDA Object_h_speed_hi,x
ADC #$00
STA Object_h_speed_hi,x
BPL setHspeedToZero
;;; we had not reached zero yet
;;; so keep the new update to speed and
;;; continue on.
JMP doneGettingInertia
setHspeedToZero:
LDA #$00
STA Object_h_speed_hi,x
STA Object_h_speed_lo,x
JMP doneGettingInertia
doneGettingInertia:
LDA Object_h_speed_lo,x
CLC
ADC #$00
LDA Object_h_speed_hi,x
ADC #$00
BMI inertiaIsNegative
;;; intertia is positive.
LDA Object_x_lo,x
CLC
ADC Object_h_speed_lo,x
;STA Object_x_lo,x
STA xHold_lo
LDA Object_x_hi,x
ADC Object_h_speed_hi,x
;STA Object_x_hi,x
STA xHold_hi
LDA Object_scroll,x
ADC #$00
;STA Object_scroll,x
STA nt_hold
;; small fix for the ignore gravity objects (maybe issues with other objects in some another cases?)
JSR updateXPosForNonPlayerObjects
;;;; here is a macro that handles player guided right scrolling.
;;;; you can disable right scrolling by simply commenting this one macro out.
LDA screenFlags
AND #%00000100 ;; is it auto scrolling?
BNE + ;; NOT autoscrolling
;; is auto scroll, so does not deal with scrolling.
LDA screenFlags
AND #%00010000
BEQ +
DoPlayerGuidedRightScroll
+
JMP doneGettingNewPotentialHorizintalPosition
inertiaIsNegative:
LDA Object_h_speed_lo,x
EOR #$FF
;CLC
;ADC #$01
STA temp
LDA Object_h_speed_hi,x
EOR #$FF
;CLC
;ADC #$01
STA temp1
LDA Object_x_lo,x
SEC
SBC temp
;STA Object_x_lo,x
STA xHold_lo
LDA Object_x_hi,x
SBC temp1
;STA Object_x_hi,x
STA xHold_hi
LDA Object_scroll,x
SBC #$00
;STA Object_scroll,x
STA nt_hold
;; small fix for the ignore gravity objects (maybe issues with other objects in some another cases?)
JSR updateXPosForNonPlayerObjects
;;; this handles player guided left scrolling
;;; to disable left scrolling, simply comment this one macro out.
LDA screenFlags
AND #%00000100 ;; is it auto scrolling?
BNE + ;; NOT autoscrolling
;; is auto scroll, so does not deal with scrolling.
LDA screenFlags
AND #%00001000
BEQ +
DoPlayerGuidedLeftScroll
+
;JMP doneGettingNewPotentialHorizintalPosition ;; redundant if flows directly into it.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;========================================================
doneGettingNewPotentialHorizintalPosition:
ENDM