ref: db569956efab02d4199a584b2916a188bce6b566
parent: f6038a3d52a2d26271fdcba9639284301305d751
author: yenatch <yenatch@gmail.com>
date: Sun May 25 15:45:59 EDT 2014
Split out overworld object movement.
--- /dev/null
+++ b/engine/overworld/movement.asm
@@ -1,0 +1,858 @@
+UpdatePlayerSprite: ; 4e31 (1:4e31)
+ ld a, [wSpriteStateData2]
+ and a
+ jr z, .asm_4e41
+ cp $ff
+ jr z, .asm_4e4a
+ dec a
+ ld [wSpriteStateData2], a
+ jr .asm_4e4a
+.asm_4e41
+ FuncCoord 8, 9 ; $c45c
+ ld a, [Coord]
+ ld [$ff93], a
+ cp $60
+ jr c, .asm_4e50
+.asm_4e4a
+ ld a, $ff
+ ld [$c102], a
+ ret
+.asm_4e50
+ call Func_4c70
+ ld h, $c1
+ ld a, [wWalkCounter] ; $cfc5
+ and a
+ jr nz, .asm_4e90
+ ld a, [$d528]
+ bit 2, a
+ jr z, .asm_4e65
+ xor a
+ jr .asm_4e86
+.asm_4e65
+ bit 3, a
+ jr z, .asm_4e6d
+ ld a, $4
+ jr .asm_4e86
+.asm_4e6d
+ bit 1, a
+ jr z, .asm_4e75
+ ld a, $8
+ jr .asm_4e86
+.asm_4e75
+ bit 0, a
+ jr z, .asm_4e7d
+ ld a, $c
+ jr .asm_4e86
+.asm_4e7d
+ xor a
+ ld [$c107], a
+ ld [$c108], a
+ jr .asm_4eab
+.asm_4e86
+ ld [$c109], a
+ ld a, [$cfc4]
+ bit 0, a
+ jr nz, .asm_4e7d
+.asm_4e90
+ ld a, [$d736]
+ bit 7, a
+ jr nz, .asm_4eb6
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $7
+ ld l, a
+ ld a, [hl]
+ inc a
+ ld [hl], a
+ cp $4
+ jr nz, .asm_4eab
+ xor a
+ ld [hl], a
+ inc hl
+ ld a, [hl]
+ inc a
+ and $3
+ ld [hl], a
+.asm_4eab
+ ld a, [$c108]
+ ld b, a
+ ld a, [$c109]
+ add b
+ ld [$c102], a
+.asm_4eb6
+ ld a, [$ff93]
+ ld c, a
+ ld a, [W_GRASSTILE]
+ cp c
+ ld a, $0
+ jr nz, .asm_4ec3
+ ld a, $80
+.asm_4ec3
+ ld [$c207], a
+ ret
+
+Func_4ec7: ; 4ec7 (1:4ec7)
+ push bc
+ push af
+ ld a, [$ffda]
+ ld c, a
+ pop af
+ add c
+ ld l, a
+ pop bc
+ ret
+
+Func_4ed1: ; 4ed1 (1:4ed1)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ swap a
+ dec a
+ add a
+ ld hl, W_MAPSPRITEDATA ; $d4e4
+ add l
+ ld l, a
+ ld a, [hl] ; read movement byte 2
+ ld [wCurSpriteMovement2], a
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld l, a
+ inc l
+ ld a, [hl] ; c1x1
+ and a
+ jp z, InitializeSpriteStatus
+ call CheckSpriteAvailability
+ ret c ; if sprite is invisible, on tile >=$60, in grass or player is currently walking
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld l, a
+ inc l
+ ld a, [hl] ; c1x1
+ bit 7, a
+ jp nz, InitializeSpriteFacingDirection ; c1x1 >= $80
+ ld b, a
+ ld a, [$cfc4]
+ bit 0, a
+ jp nz, notYetMoving
+ ld a, b
+ cp $2
+ jp z, UpdateSpriteMovementDelay ; c1x1 == 2
+ cp $3
+ jp z, UpdateSpriteInWalkingAnimation ; c1x1 == 3
+ ld a, [wWalkCounter] ; $cfc5
+ and a
+ ret nz ; don't do anything yet if player is currently moving (redundant, already tested in CheckSpriteAvailability)
+ call InitializeSpriteScreenPosition
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; c2x6: movement byte 1
+ inc a
+ jr z, .asm_4f59 ; value $FF
+ inc a
+ jr z, .asm_4f59 ; value $FE
+ dec a
+ ld [hl], a ; (temporarily) increment movement byte 1
+ dec a
+ push hl
+ ld hl, $cf0f
+ dec [hl] ; decrement $cf0f
+ pop hl
+ ld de, $cc5b
+ call LoadDEPlusA ; a = [$cc5b + movement byte 1]
+ cp $e0
+ jp z, ChangeFacingDirection
+ cp $ff
+ jr nz, .asm_4f4b
+ ld [hl], a ; reset movement byte 1 to initial value
+ ld hl, $d730
+ res 0, [hl]
+ xor a
+ ld [$cd38], a
+ ld [$cd3a], a
+ ret
+.asm_4f4b
+ cp $fe
+ jr nz, .asm_4f5f
+ ld [hl], $1 ; set movement byte 1 to $1
+ ld de, $cc5b
+ call LoadDEPlusA ; a = [$cc5b + $fe] (?)
+ jr .asm_4f5f
+.asm_4f59
+ call getTileSpriteStandsOn
+ call Random
+.asm_4f5f
+ ld b, a
+ ld a, [wCurSpriteMovement2]
+ cp $d0
+ jr z, .moveDown ; movement byte 2 = $d0 forces down
+ cp $d1
+ jr z, .moveUp ; movement byte 2 = $d1 forces up
+ cp $d2
+ jr z, .moveLeft ; movement byte 2 = $d2 forces left
+ cp $d3
+ jr z, .moveRight ; movement byte 2 = $d3 forces right
+ ld a, b
+ cp $40 ; a < $40: down (or left)
+ jr nc, .notDown
+ ld a, [wCurSpriteMovement2]
+ cp $2
+ jr z, .moveLeft ; movement byte 2 = $2 only allows left or right
+.moveDown
+ ld de, 2*20
+ add hl, de ; move tile pointer two rows down
+ ld de, $100
+
+ ld bc, $400
+ jr TryWalking
+.notDown
+ cp $80 ; $40 <= a < $80: up (or right)
+ jr nc, .notUp
+ ld a, [wCurSpriteMovement2]
+ cp $2
+ jr z, .moveRight ; movement byte 2 = $2 only allows left or right
+.moveUp
+ ld de, -2*20 ; $ffd8
+ add hl, de ; move tile pointer two rows up
+ ld de, $ff00
+ ld bc, $804
+ jr TryWalking
+.notUp
+ cp $c0 ; $80 <= a < $c0: left (or up)
+ jr nc, .notLeft
+ ld a, [wCurSpriteMovement2]
+ cp $1
+ jr z, .moveUp ; movement byte 2 = $1 only allows up or down
+.moveLeft
+ dec hl
+ dec hl ; move tile pointer two columns left
+ ld de, $ff
+ ld bc, $208
+ jr TryWalking
+.notLeft ; $c0 <= a: right (or down)
+ ld a, [wCurSpriteMovement2]
+ cp $1
+ jr z, .moveDown ; movement byte 2 = $1 only allows up or down
+.moveRight
+ inc hl
+ inc hl ; move tile pointer two columns right
+ ld de, $1
+ ld bc, $10c
+ jr TryWalking
+
+; changes facing direction by zeroing the movement delta and calling TryWalking
+ChangeFacingDirection: ; 4fc8 (1:4fc8)
+ ld de, $0
+ ; fall through
+
+; b: direction (1,2,4 or 8)
+; c: new facing direction (0,4,8 or $c)
+; d: Y movement delta (-1, 0 or 1)
+; e: X movement delta (-1, 0 or 1)
+; hl: pointer to tile the sprite would wlak onto
+; set carry on failure, clears carry on success
+TryWalking: ; 4fcb (1:4fcb)
+ push hl
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $9
+ ld l, a
+ ld [hl], c ; c1x9 (update facing direction)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $3
+ ld l, a
+ ld [hl], d ; c1x3 (update Y movement delta)
+ inc l
+ inc l
+ ld [hl], e ; c1x5 (update X movement delta)
+ pop hl
+ push de
+ ld c, [hl] ; read tile to walk onto
+ call CanWalkOntoTile
+ pop de
+ ret c ; cannot walk there (reinitialization of delay values already done)
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld a, [hl] ; c2x4: Y position
+ add d
+ ld [hli], a ; update Y position
+ ld a, [hl] ; c2x5: X position
+ add e
+ ld [hl], a ; update X position
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld l, a
+ ld [hl], $10 ; c2x0=16: walk animation counter
+ dec h
+ inc l
+ ld [hl], $3 ; c1x1: set movement status to walking
+ jp UpdateSpriteImage
+
+; update the walking animation parameters for a sprite that is currently walking
+UpdateSpriteInWalkingAnimation: ; 4ffe (1:4ffe)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $7
+ ld l, a
+ ld a, [hl] ; c1x7 (counter until next walk animation frame)
+ inc a
+ ld [hl], a ; c1x7 += 1
+ cp $4
+ jr nz, .noNextAnimationFrame
+ xor a
+ ld [hl], a ; c1x7 = 0
+ inc l
+ ld a, [hl] ; c1x8 (walk animation frame)
+ inc a
+ and $3
+ ld [hl], a ; advance to next animation frame every 4 ticks (16 ticks total for one step)
+.noNextAnimationFrame
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $3
+ ld l, a
+ ld a, [hli] ; c1x3 (movement Y delta)
+ ld b, a
+ ld a, [hl] ; c1x4 (screen Y position)
+ add b
+ ld [hli], a ; update screen Y position
+ ld a, [hli] ; c1x5 (movement X delta)
+ ld b, a
+ ld a, [hl] ; c1x6 (screen X position)
+ add b
+ ld [hl], a ; update screen X position
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld l, a
+ inc h
+ ld a, [hl] ; c2x0 (walk animantion counter)
+ dec a
+ ld [hl], a ; update walk animantion counter
+ ret nz
+ ld a, $6 ; walking finished, update state
+ add l
+ ld l, a
+ ld a, [hl] ; c2x6 (movement byte 1)
+ cp $fe
+ jr nc, .initNextMovementCounter ; values $fe and $ff
+ ld a, [H_CURRENTSPRITEOFFSET]
+ inc a
+ ld l, a
+ dec h
+ ld [hl], $1 ; c1x1 = 1 (movement status ready)
+ ret
+.initNextMovementCounter
+ call Random
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $8
+ ld l, a
+ ld a, [hRandomAdd]
+ and $7f
+ ld [hl], a ; c2x8: set next movement delay to a random value in [0,$7f]
+ dec h ; note that value 0 actually makes the delay $100 (bug?)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ inc a
+ ld l, a
+ ld [hl], $2 ; c1x1 = 2 (movement status)
+ inc l
+ inc l
+ xor a
+ ld b, [hl] ; c1x3 (movement Y delta)
+ ld [hli], a ; reset movement Y delta
+ inc l
+ ld c, [hl] ; c1x5 (movement X delta)
+ ld [hl], a ; reset movement X delta
+ ret
+
+; update delay value (c2x8) for sprites in the delayed state (c1x1)
+UpdateSpriteMovementDelay: ; 5057 (1:5057)
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; c2x6: movement byte 1
+ inc l
+ inc l
+ cp $fe
+ jr nc, .tickMoveCounter ; values $fe or $ff
+ ld [hl], $0
+ jr .moving
+.tickMoveCounter
+ dec [hl] ; c2x8: frame counter until next movement
+ jr nz, notYetMoving
+.moving
+ dec h
+ ld a, [H_CURRENTSPRITEOFFSET]
+ inc a
+ ld l, a
+ ld [hl], $1 ; c1x1 = 1 (mark as ready to move)
+notYetMoving: ; 5073 (1:5073)
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $8
+ ld l, a
+ ld [hl], $0 ; c1x8 = 0 (walk animation frame)
+ jp UpdateSpriteImage
+
+InitializeSpriteFacingDirection: ; 507f (1:507f)
+ ld a, [$d72d]
+ bit 5, a
+ jr nz, notYetMoving
+ res 7, [hl]
+ ld a, [$d52a]
+ bit 3, a
+ jr z, .notFacingDown
+ ld c, $0 ; make sprite face down
+ jr .facingDirectionDetermined
+.notFacingDown
+ bit 2, a
+ jr z, .notFacingUp
+ ld c, $4 ; make sprite face up
+ jr .facingDirectionDetermined
+.notFacingUp
+ bit 1, a
+ jr z, .notFacingRight
+ ld c, $c ; make sprite face right
+ jr .facingDirectionDetermined
+.notFacingRight
+ ld c, $8 ; make sprite face left
+.facingDirectionDetermined
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $9
+ ld l, a
+ ld [hl], c ; c1x9: set facing direction
+ jr notYetMoving
+
+InitializeSpriteStatus: ; 50ad (1:50ad)
+ ld [hl], $1 ; $c1x1: set movement status to ready
+ inc l
+ ld [hl], $ff ; $c1x2: set sprite image to $ff (invisible/off screen)
+ inc h
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld a, $8
+ ld [hli], a ; $c2x2: set Y displacement to 8
+ ld [hl], a ; $c2x3: set X displacement to 8
+ ret
+
+; calculates the spprite's scrren position form its map position and the player position
+InitializeSpriteScreenPosition: ; 50bd (1:50bd)
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld a, [W_YCOORD] ; $d361
+ ld b, a
+ ld a, [hl] ; c2x4 (Y position + 4)
+ sub b ; relative to player position
+ swap a ; * 16
+ sub $4 ; - 4
+ dec h
+ ld [hli], a ; c1x4 (screen Y position)
+ inc h
+ ld a, [W_XCOORD] ; $d362
+ ld b, a
+ ld a, [hli] ; c2x6 (X position + 4)
+ sub b ; relative to player position
+ swap a ; * 16
+ dec h
+ ld [hl], a ; c1x6 (screen X position)
+ ret
+
+; tests if sprite is off screen or otherwise unable to do anything
+CheckSpriteAvailability: ; 50dc (1:50dc)
+ ld a, $12
+ call Predef ; indirect jump to IsMissableObjectHidden (f1a6 (3:71a6))
+ ld a, [$ffe5]
+ and a
+ jp nz, .spriteInvisible
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; c2x6: movement byte 1
+ cp $fe
+ jr c, .skipXVisibilityTest ; movement byte 1 < $fe
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld b, [hl] ; c2x4: Y pos (+4)
+ ld a, [W_YCOORD] ; $d361
+ cp b
+ jr z, .skipYVisibilityTest
+ jr nc, .spriteInvisible ; above screen region
+ add $8 ; screen is 9 tiles high
+ cp b
+ jr c, .spriteInvisible ; below screen region
+.skipYVisibilityTest
+ inc l
+ ld b, [hl] ; c2x5: X pos (+4)
+ ld a, [W_XCOORD] ; $d362
+ cp b
+ jr z, .skipXVisibilityTest
+ jr nc, .spriteInvisible ; left of screen region
+ add $9 ; screen is 10 tiles wide
+ cp b
+ jr c, .spriteInvisible ; right of screen region
+.skipXVisibilityTest
+ call getTileSpriteStandsOn
+ ld d, $60
+ ld a, [hli]
+ cp d
+ jr nc, .spriteInvisible ; standing on tile with ID >=$60 (bottom left tile)
+ ld a, [hld]
+ cp d
+ jr nc, .spriteInvisible ; standing on tile with ID >=$60 (bottom right tile)
+ ld bc, -20 ; $ffec
+ add hl, bc ; go back one row of tiles
+ ld a, [hli]
+ cp d
+ jr nc, .spriteInvisible ; standing on tile with ID >=$60 (top left tile)
+ ld a, [hl]
+ cp d
+ jr c, .spriteVisible ; standing on tile with ID >=$60 (top right tile)
+.spriteInvisible
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld [hl], $ff ; c1x2
+ scf
+ jr .done
+.spriteVisible
+ ld c, a
+ ld a, [wWalkCounter] ; $cfc5
+ and a
+ jr nz, .done ; if player is currently walking, we're done
+ call UpdateSpriteImage
+ inc h
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $7
+ ld l, a
+ ld a, [W_GRASSTILE]
+ cp c
+ ld a, $0
+ jr nz, .notInGrass
+ ld a, $80
+.notInGrass
+ ld [hl], a ; c2x7
+ and a
+.done
+ ret
+
+UpdateSpriteImage: ; 5157 (1:5157)
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $8
+ ld l, a
+ ld a, [hli] ; c1x8: walk animation frame
+ ld b, a
+ ld a, [hl] ; c1x9: facing direction
+ add b
+ ld b, a
+ ld a, [$ff93] ; current sprite offset
+ add b
+ ld b, a
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld [hl], b ; c1x2: sprite to display
+ ret
+
+; tests if sprite can walk the specified direction
+; b: direction (1,2,4 or 8)
+; c: ID of tile the sprite would walk onto
+; d: Y movement delta (-1, 0 or 1)
+; e: X movement delta (-1, 0 or 1)
+; set carry on failure, clears carry on success
+CanWalkOntoTile: ; 516e (1:516e)
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; c2x6 (movement byte 1)
+ cp $fe
+ jr nc, .canMove ; values $fe and $ff
+ and a
+ ret
+.canMove
+ ld a, [W_TILESETCOLLISIONPTR]
+ ld l, a
+ ld a, [W_TILESETCOLLISIONPTR+1]
+ ld h, a
+.tilePassableLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .impassable
+ cp c
+ jr nz, .tilePassableLoop
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; $c2x6 (movement byte 1)
+ inc a
+ jr z, .impassable ; if $ff, no movement allowed (however, changing direction is)
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld a, [hli] ; c1x4 (screen Y pos)
+ add $4 ; align to blocks (Y pos is always 4 pixels off)
+ add d ; add Y delta
+ cp $80 ; if value is >$80, the destination is off screen (either $81 or $FF underflow)
+ jr nc, .impassable ; don't walk off screen
+ inc l
+ ld a, [hl] ; c1x6 (screen X pos)
+ add e ; add X delta
+ cp $90 ; if value is >$90, the destination is off screen (either $91 or $FF underflow)
+ jr nc, .impassable ; don't walk off screen
+ push de
+ push bc
+ call Func_4c70
+ pop bc
+ pop de
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $c
+ ld l, a
+ ld a, [hl] ; c1xc (forbidden directions flags(?))
+ and b ; check against chosen direction (1,2,4 or 8)
+ jr nz, .impassable ; direction forbidden, don't go there
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld a, [hli] ; c2x2 (sprite Y displacement, initialized at $8, keep track of where a sprite did go)
+ bit 7, d ; check if going upwards (d=$ff)
+ jr nz, .upwards
+ add d
+ cp $5
+ jr c, .impassable ; if c2x2+d < 5, don't go ;bug: this tests probably were supposed to prevent sprites
+ jr .checkHorizontal ; from walking out too far, but this line makes sprites get stuck
+.upwards ; whenever they walked upwards 5 steps
+ sub $1 ; on the other hand, the amount a sprite can walk out to the
+ jr c, .impassable ; if d2x2 == 0, don't go ; right of bottom is not limited (until the counter overflows)
+.checkHorizontal
+ ld d, a
+ ld a, [hl] ; c2x3 (sprite X displacement, initialized at $8, keep track of where a sprite did go)
+ bit 7, e ; check if going left (e=$ff)
+ jr nz, .left
+ add e
+ cp $5 ; compare, but no conditional jump like in the vertical check above (bug?)
+ jr .passable
+.left
+ sub $1
+ jr c, .impassable ; if d2x3 == 0, don't go
+.passable
+ ld [hld], a ; update c2x3
+ ld [hl], d ; update c2x2
+ and a ; clear carry (marking success)
+ ret
+.impassable
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ inc a
+ ld l, a
+ ld [hl], $2 ; c1x1 = 2 (set movement status to delayed)
+ inc l
+ inc l
+ xor a
+ ld [hli], a ; c1x3 = 0 (clear Y movement delta)
+ inc l
+ ld [hl], a ; c1x5 = 0 (clear X movement delta)
+ inc h
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $8
+ ld l, a
+ call Random
+ ld a, [hRandomAdd]
+ and $7f
+ ld [hl], a ; c2x8: set next movement delay to a random value in [0,$7f] (again with delay $100 if value is 0)
+ scf ; set carry (marking failure to walk)
+ ret
+
+; calculates the tile pointer pointing to the tile the current sprite stancs on
+; this is always the lower left tile of the 2x2 tile blocks all sprites are snapped to
+; hl: output pointer
+getTileSpriteStandsOn: ; 5207 (1:5207)
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld a, [hli] ; c1x4: screen Y position
+ add $4 ; align to 2*2 tile blocks (Y position is always off 4 pixels to the top)
+ and $f0 ; in case object is currently moving
+ srl a ; screen Y tile * 4
+ ld c, a
+ ld b, $0
+ inc l
+ ld a, [hl] ; c1x6: screen Y position
+ srl a
+ srl a
+ srl a ; screen X tile
+ add $14 ; screen X tile + 20
+ ld d, $0
+ ld e, a
+ ld hl, wTileMap
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, de ; wTileMap + 20*(screen Y tile + 1) + screen X tile
+ ret
+
+; loads [de+a] into a
+LoadDEPlusA: ; 522f (1:522f)
+ add e
+ ld e, a
+ jr nc, .noCarry
+ inc d
+.noCarry
+ ld a, [de]
+ ret
+
+Func_5236: ; 5236 (1:5236)
+ ld a, [$d730]
+ bit 7, a
+ ret z
+ ld hl, $d72e
+ bit 7, [hl]
+ set 7, [hl]
+ jp z, Func_52a6
+ ld hl, $cc97
+ ld a, [$cd37]
+ add l
+ ld l, a
+ jr nc, .asm_5251
+ inc h
+.asm_5251
+ ld a, [hl]
+ cp $40
+ jr nz, .asm_525f
+ call Func_52b2
+ ld c, $4
+ ld a, $fe
+ jr .asm_5289
+.asm_525f
+ cp $0
+ jr nz, .asm_526c
+ call Func_52b2
+ ld c, $0
+ ld a, $2
+ jr .asm_5289
+.asm_526c
+ cp $80
+ jr nz, .asm_5279
+ call Func_52b7
+ ld c, $8
+ ld a, $fe
+ jr .asm_5289
+.asm_5279
+ cp $c0
+ jr nz, .asm_5286
+ call Func_52b7
+ ld c, $c
+ ld a, $2
+ jr .asm_5289
+.asm_5286
+ cp $ff
+ ret
+.asm_5289
+ ld b, a
+ ld a, [hl]
+ add b
+ ld [hl], a
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $9
+ ld l, a
+ ld a, c
+ ld [hl], a
+ call Func_52c3
+ ld hl, $cf18
+ dec [hl]
+ ret nz
+ ld a, $8
+ ld [$cf18], a
+ ld hl, $cd37
+ inc [hl]
+ ret
+
+Func_52a6: ; 52a6 (1:52a6)
+ xor a
+ ld [$cd37], a
+ ld a, $8
+ ld [$cf18], a
+ jp Func_52c3
+
+Func_52b2: ; 52b2 (1:52b2)
+ ld a, $4
+ ld b, a
+ jr asm_52ba
+
+Func_52b7: ; 52b7 (1:52b7)
+ ld a, $6
+ ld b, a
+asm_52ba: ; 52ba (1:52ba)
+ ld hl, wSpriteStateData1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add l
+ add b
+ ld l, a
+ ret
+
+Func_52c3: ; 52c3 (1:52c3)
+ ld hl, wSpriteStateData2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $e
+ ld l, a
+ ld a, [hl]
+ dec a
+ swap a
+ ld b, a
+ ld hl, wSpriteStateData1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $9
+ ld l, a
+ ld a, [hl]
+ cp $0
+ jr z, .asm_52ea
+ cp $4
+ jr z, .asm_52ea
+ cp $8
+ jr z, .asm_52ea
+ cp $c
+ jr z, .asm_52ea
+ ret
+.asm_52ea
+ add b
+ ld b, a
+ ld [$ffe9], a
+ call Func_5301
+ ld hl, wSpriteStateData1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld a, [$ffe9]
+ ld b, a
+ ld a, [$ffea]
+ add b
+ ld [hl], a
+ ret
+
+Func_5301: ; 5301 (1:5301)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $7
+ ld l, a
+ ld a, [hl]
+ inc a
+ ld [hl], a
+ cp $4
+ ret nz
+ xor a
+ ld [hl], a
+ inc l
+ ld a, [hl]
+ inc a
+ and $3
+ ld [hl], a
+ ld [$ffea], a
+ ret
--- a/main.asm
+++ b/main.asm
@@ -544,865 +544,7 @@
TX_FAR _NoMoreRoomForItemText
db "@"
-
-UpdatePlayerSprite: ; 4e31 (1:4e31)
- ld a, [wSpriteStateData2]
- and a
- jr z, .asm_4e41
- cp $ff
- jr z, .asm_4e4a
- dec a
- ld [wSpriteStateData2], a
- jr .asm_4e4a
-.asm_4e41
- FuncCoord 8, 9 ; $c45c
- ld a, [Coord]
- ld [$ff93], a
- cp $60
- jr c, .asm_4e50
-.asm_4e4a
- ld a, $ff
- ld [$c102], a
- ret
-.asm_4e50
- call Func_4c70
- ld h, $c1
- ld a, [wWalkCounter] ; $cfc5
- and a
- jr nz, .asm_4e90
- ld a, [$d528]
- bit 2, a
- jr z, .asm_4e65
- xor a
- jr .asm_4e86
-.asm_4e65
- bit 3, a
- jr z, .asm_4e6d
- ld a, $4
- jr .asm_4e86
-.asm_4e6d
- bit 1, a
- jr z, .asm_4e75
- ld a, $8
- jr .asm_4e86
-.asm_4e75
- bit 0, a
- jr z, .asm_4e7d
- ld a, $c
- jr .asm_4e86
-.asm_4e7d
- xor a
- ld [$c107], a
- ld [$c108], a
- jr .asm_4eab
-.asm_4e86
- ld [$c109], a
- ld a, [$cfc4]
- bit 0, a
- jr nz, .asm_4e7d
-.asm_4e90
- ld a, [$d736]
- bit 7, a
- jr nz, .asm_4eb6
- ld a, [H_CURRENTSPRITEOFFSET]
- add $7
- ld l, a
- ld a, [hl]
- inc a
- ld [hl], a
- cp $4
- jr nz, .asm_4eab
- xor a
- ld [hl], a
- inc hl
- ld a, [hl]
- inc a
- and $3
- ld [hl], a
-.asm_4eab
- ld a, [$c108]
- ld b, a
- ld a, [$c109]
- add b
- ld [$c102], a
-.asm_4eb6
- ld a, [$ff93]
- ld c, a
- ld a, [W_GRASSTILE]
- cp c
- ld a, $0
- jr nz, .asm_4ec3
- ld a, $80
-.asm_4ec3
- ld [$c207], a
- ret
-
-Func_4ec7: ; 4ec7 (1:4ec7)
- push bc
- push af
- ld a, [$ffda]
- ld c, a
- pop af
- add c
- ld l, a
- pop bc
- ret
-
-Func_4ed1: ; 4ed1 (1:4ed1)
- ld a, [H_CURRENTSPRITEOFFSET]
- swap a
- dec a
- add a
- ld hl, W_MAPSPRITEDATA ; $d4e4
- add l
- ld l, a
- ld a, [hl] ; read movement byte 2
- ld [wCurSpriteMovement2], a
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- ld l, a
- inc l
- ld a, [hl] ; c1x1
- and a
- jp z, InitializeSpriteStatus
- call CheckSpriteAvailability
- ret c ; if sprite is invisible, on tile >=$60, in grass or player is currently walking
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- ld l, a
- inc l
- ld a, [hl] ; c1x1
- bit 7, a
- jp nz, InitializeSpriteFacingDirection ; c1x1 >= $80
- ld b, a
- ld a, [$cfc4]
- bit 0, a
- jp nz, notYetMoving
- ld a, b
- cp $2
- jp z, UpdateSpriteMovementDelay ; c1x1 == 2
- cp $3
- jp z, UpdateSpriteInWalkingAnimation ; c1x1 == 3
- ld a, [wWalkCounter] ; $cfc5
- and a
- ret nz ; don't do anything yet if player is currently moving (redundant, already tested in CheckSpriteAvailability)
- call InitializeSpriteScreenPosition
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $6
- ld l, a
- ld a, [hl] ; c2x6: movement byte 1
- inc a
- jr z, .asm_4f59 ; value $FF
- inc a
- jr z, .asm_4f59 ; value $FE
- dec a
- ld [hl], a ; (temporarily) increment movement byte 1
- dec a
- push hl
- ld hl, $cf0f
- dec [hl] ; decrement $cf0f
- pop hl
- ld de, $cc5b
- call LoadDEPlusA ; a = [$cc5b + movement byte 1]
- cp $e0
- jp z, ChangeFacingDirection
- cp $ff
- jr nz, .asm_4f4b
- ld [hl], a ; reset movement byte 1 to initial value
- ld hl, $d730
- res 0, [hl]
- xor a
- ld [$cd38], a
- ld [$cd3a], a
- ret
-.asm_4f4b
- cp $fe
- jr nz, .asm_4f5f
- ld [hl], $1 ; set movement byte 1 to $1
- ld de, $cc5b
- call LoadDEPlusA ; a = [$cc5b + $fe] (?)
- jr .asm_4f5f
-.asm_4f59
- call getTileSpriteStandsOn
- call Random
-.asm_4f5f
- ld b, a
- ld a, [wCurSpriteMovement2]
- cp $d0
- jr z, .moveDown ; movement byte 2 = $d0 forces down
- cp $d1
- jr z, .moveUp ; movement byte 2 = $d1 forces up
- cp $d2
- jr z, .moveLeft ; movement byte 2 = $d2 forces left
- cp $d3
- jr z, .moveRight ; movement byte 2 = $d3 forces right
- ld a, b
- cp $40 ; a < $40: down (or left)
- jr nc, .notDown
- ld a, [wCurSpriteMovement2]
- cp $2
- jr z, .moveLeft ; movement byte 2 = $2 only allows left or right
-.moveDown
- ld de, 2*20
- add hl, de ; move tile pointer two rows down
- ld de, $100
-
- ld bc, $400
- jr TryWalking
-.notDown
- cp $80 ; $40 <= a < $80: up (or right)
- jr nc, .notUp
- ld a, [wCurSpriteMovement2]
- cp $2
- jr z, .moveRight ; movement byte 2 = $2 only allows left or right
-.moveUp
- ld de, -2*20 ; $ffd8
- add hl, de ; move tile pointer two rows up
- ld de, $ff00
- ld bc, $804
- jr TryWalking
-.notUp
- cp $c0 ; $80 <= a < $c0: left (or up)
- jr nc, .notLeft
- ld a, [wCurSpriteMovement2]
- cp $1
- jr z, .moveUp ; movement byte 2 = $1 only allows up or down
-.moveLeft
- dec hl
- dec hl ; move tile pointer two columns left
- ld de, $ff
- ld bc, $208
- jr TryWalking
-.notLeft ; $c0 <= a: right (or down)
- ld a, [wCurSpriteMovement2]
- cp $1
- jr z, .moveDown ; movement byte 2 = $1 only allows up or down
-.moveRight
- inc hl
- inc hl ; move tile pointer two columns right
- ld de, $1
- ld bc, $10c
- jr TryWalking
-
-; changes facing direction by zeroing the movement delta and calling TryWalking
-ChangeFacingDirection: ; 4fc8 (1:4fc8)
- ld de, $0
- ; fall through
-
-; b: direction (1,2,4 or 8)
-; c: new facing direction (0,4,8 or $c)
-; d: Y movement delta (-1, 0 or 1)
-; e: X movement delta (-1, 0 or 1)
-; hl: pointer to tile the sprite would wlak onto
-; set carry on failure, clears carry on success
-TryWalking: ; 4fcb (1:4fcb)
- push hl
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $9
- ld l, a
- ld [hl], c ; c1x9 (update facing direction)
- ld a, [H_CURRENTSPRITEOFFSET]
- add $3
- ld l, a
- ld [hl], d ; c1x3 (update Y movement delta)
- inc l
- inc l
- ld [hl], e ; c1x5 (update X movement delta)
- pop hl
- push de
- ld c, [hl] ; read tile to walk onto
- call CanWalkOntoTile
- pop de
- ret c ; cannot walk there (reinitialization of delay values already done)
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $4
- ld l, a
- ld a, [hl] ; c2x4: Y position
- add d
- ld [hli], a ; update Y position
- ld a, [hl] ; c2x5: X position
- add e
- ld [hl], a ; update X position
- ld a, [H_CURRENTSPRITEOFFSET]
- ld l, a
- ld [hl], $10 ; c2x0=16: walk animation counter
- dec h
- inc l
- ld [hl], $3 ; c1x1: set movement status to walking
- jp UpdateSpriteImage
-
-; update the walking animation parameters for a sprite that is currently walking
-UpdateSpriteInWalkingAnimation: ; 4ffe (1:4ffe)
- ld a, [H_CURRENTSPRITEOFFSET]
- add $7
- ld l, a
- ld a, [hl] ; c1x7 (counter until next walk animation frame)
- inc a
- ld [hl], a ; c1x7 += 1
- cp $4
- jr nz, .noNextAnimationFrame
- xor a
- ld [hl], a ; c1x7 = 0
- inc l
- ld a, [hl] ; c1x8 (walk animation frame)
- inc a
- and $3
- ld [hl], a ; advance to next animation frame every 4 ticks (16 ticks total for one step)
-.noNextAnimationFrame
- ld a, [H_CURRENTSPRITEOFFSET]
- add $3
- ld l, a
- ld a, [hli] ; c1x3 (movement Y delta)
- ld b, a
- ld a, [hl] ; c1x4 (screen Y position)
- add b
- ld [hli], a ; update screen Y position
- ld a, [hli] ; c1x5 (movement X delta)
- ld b, a
- ld a, [hl] ; c1x6 (screen X position)
- add b
- ld [hl], a ; update screen X position
- ld a, [H_CURRENTSPRITEOFFSET]
- ld l, a
- inc h
- ld a, [hl] ; c2x0 (walk animantion counter)
- dec a
- ld [hl], a ; update walk animantion counter
- ret nz
- ld a, $6 ; walking finished, update state
- add l
- ld l, a
- ld a, [hl] ; c2x6 (movement byte 1)
- cp $fe
- jr nc, .initNextMovementCounter ; values $fe and $ff
- ld a, [H_CURRENTSPRITEOFFSET]
- inc a
- ld l, a
- dec h
- ld [hl], $1 ; c1x1 = 1 (movement status ready)
- ret
-.initNextMovementCounter
- call Random
- ld a, [H_CURRENTSPRITEOFFSET]
- add $8
- ld l, a
- ld a, [hRandomAdd]
- and $7f
- ld [hl], a ; c2x8: set next movement delay to a random value in [0,$7f]
- dec h ; note that value 0 actually makes the delay $100 (bug?)
- ld a, [H_CURRENTSPRITEOFFSET]
- inc a
- ld l, a
- ld [hl], $2 ; c1x1 = 2 (movement status)
- inc l
- inc l
- xor a
- ld b, [hl] ; c1x3 (movement Y delta)
- ld [hli], a ; reset movement Y delta
- inc l
- ld c, [hl] ; c1x5 (movement X delta)
- ld [hl], a ; reset movement X delta
- ret
-
-; update delay value (c2x8) for sprites in the delayed state (c1x1)
-UpdateSpriteMovementDelay: ; 5057 (1:5057)
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $6
- ld l, a
- ld a, [hl] ; c2x6: movement byte 1
- inc l
- inc l
- cp $fe
- jr nc, .tickMoveCounter ; values $fe or $ff
- ld [hl], $0
- jr .moving
-.tickMoveCounter
- dec [hl] ; c2x8: frame counter until next movement
- jr nz, notYetMoving
-.moving
- dec h
- ld a, [H_CURRENTSPRITEOFFSET]
- inc a
- ld l, a
- ld [hl], $1 ; c1x1 = 1 (mark as ready to move)
-notYetMoving: ; 5073 (1:5073)
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $8
- ld l, a
- ld [hl], $0 ; c1x8 = 0 (walk animation frame)
- jp UpdateSpriteImage
-
-InitializeSpriteFacingDirection: ; 507f (1:507f)
- ld a, [$d72d]
- bit 5, a
- jr nz, notYetMoving
- res 7, [hl]
- ld a, [$d52a]
- bit 3, a
- jr z, .notFacingDown
- ld c, $0 ; make sprite face down
- jr .facingDirectionDetermined
-.notFacingDown
- bit 2, a
- jr z, .notFacingUp
- ld c, $4 ; make sprite face up
- jr .facingDirectionDetermined
-.notFacingUp
- bit 1, a
- jr z, .notFacingRight
- ld c, $c ; make sprite face right
- jr .facingDirectionDetermined
-.notFacingRight
- ld c, $8 ; make sprite face left
-.facingDirectionDetermined
- ld a, [H_CURRENTSPRITEOFFSET]
- add $9
- ld l, a
- ld [hl], c ; c1x9: set facing direction
- jr notYetMoving
-
-InitializeSpriteStatus: ; 50ad (1:50ad)
- ld [hl], $1 ; $c1x1: set movement status to ready
- inc l
- ld [hl], $ff ; $c1x2: set sprite image to $ff (invisible/off screen)
- inc h
- ld a, [H_CURRENTSPRITEOFFSET]
- add $2
- ld l, a
- ld a, $8
- ld [hli], a ; $c2x2: set Y displacement to 8
- ld [hl], a ; $c2x3: set X displacement to 8
- ret
-
-; calculates the spprite's scrren position form its map position and the player position
-InitializeSpriteScreenPosition: ; 50bd (1:50bd)
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $4
- ld l, a
- ld a, [W_YCOORD] ; $d361
- ld b, a
- ld a, [hl] ; c2x4 (Y position + 4)
- sub b ; relative to player position
- swap a ; * 16
- sub $4 ; - 4
- dec h
- ld [hli], a ; c1x4 (screen Y position)
- inc h
- ld a, [W_XCOORD] ; $d362
- ld b, a
- ld a, [hli] ; c2x6 (X position + 4)
- sub b ; relative to player position
- swap a ; * 16
- dec h
- ld [hl], a ; c1x6 (screen X position)
- ret
-
-; tests if sprite is off screen or otherwise unable to do anything
-CheckSpriteAvailability: ; 50dc (1:50dc)
- ld a, $12
- call Predef ; indirect jump to IsMissableObjectHidden (f1a6 (3:71a6))
- ld a, [$ffe5]
- and a
- jp nz, .spriteInvisible
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $6
- ld l, a
- ld a, [hl] ; c2x6: movement byte 1
- cp $fe
- jr c, .skipXVisibilityTest ; movement byte 1 < $fe
- ld a, [H_CURRENTSPRITEOFFSET]
- add $4
- ld l, a
- ld b, [hl] ; c2x4: Y pos (+4)
- ld a, [W_YCOORD] ; $d361
- cp b
- jr z, .skipYVisibilityTest
- jr nc, .spriteInvisible ; above screen region
- add $8 ; screen is 9 tiles high
- cp b
- jr c, .spriteInvisible ; below screen region
-.skipYVisibilityTest
- inc l
- ld b, [hl] ; c2x5: X pos (+4)
- ld a, [W_XCOORD] ; $d362
- cp b
- jr z, .skipXVisibilityTest
- jr nc, .spriteInvisible ; left of screen region
- add $9 ; screen is 10 tiles wide
- cp b
- jr c, .spriteInvisible ; right of screen region
-.skipXVisibilityTest
- call getTileSpriteStandsOn
- ld d, $60
- ld a, [hli]
- cp d
- jr nc, .spriteInvisible ; standing on tile with ID >=$60 (bottom left tile)
- ld a, [hld]
- cp d
- jr nc, .spriteInvisible ; standing on tile with ID >=$60 (bottom right tile)
- ld bc, -20 ; $ffec
- add hl, bc ; go back one row of tiles
- ld a, [hli]
- cp d
- jr nc, .spriteInvisible ; standing on tile with ID >=$60 (top left tile)
- ld a, [hl]
- cp d
- jr c, .spriteVisible ; standing on tile with ID >=$60 (top right tile)
-.spriteInvisible
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $2
- ld l, a
- ld [hl], $ff ; c1x2
- scf
- jr .done
-.spriteVisible
- ld c, a
- ld a, [wWalkCounter] ; $cfc5
- and a
- jr nz, .done ; if player is currently walking, we're done
- call UpdateSpriteImage
- inc h
- ld a, [H_CURRENTSPRITEOFFSET]
- add $7
- ld l, a
- ld a, [W_GRASSTILE]
- cp c
- ld a, $0
- jr nz, .notInGrass
- ld a, $80
-.notInGrass
- ld [hl], a ; c2x7
- and a
-.done
- ret
-
-UpdateSpriteImage: ; 5157 (1:5157)
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $8
- ld l, a
- ld a, [hli] ; c1x8: walk animation frame
- ld b, a
- ld a, [hl] ; c1x9: facing direction
- add b
- ld b, a
- ld a, [$ff93] ; current sprite offset
- add b
- ld b, a
- ld a, [H_CURRENTSPRITEOFFSET]
- add $2
- ld l, a
- ld [hl], b ; c1x2: sprite to display
- ret
-
-; tests if sprite can walk the specified direction
-; b: direction (1,2,4 or 8)
-; c: ID of tile the sprite would walk onto
-; d: Y movement delta (-1, 0 or 1)
-; e: X movement delta (-1, 0 or 1)
-; set carry on failure, clears carry on success
-CanWalkOntoTile: ; 516e (1:516e)
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $6
- ld l, a
- ld a, [hl] ; c2x6 (movement byte 1)
- cp $fe
- jr nc, .canMove ; values $fe and $ff
- and a
- ret
-.canMove
- ld a, [W_TILESETCOLLISIONPTR]
- ld l, a
- ld a, [W_TILESETCOLLISIONPTR+1]
- ld h, a
-.tilePassableLoop
- ld a, [hli]
- cp $ff
- jr z, .impassable
- cp c
- jr nz, .tilePassableLoop
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $6
- ld l, a
- ld a, [hl] ; $c2x6 (movement byte 1)
- inc a
- jr z, .impassable ; if $ff, no movement allowed (however, changing direction is)
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $4
- ld l, a
- ld a, [hli] ; c1x4 (screen Y pos)
- add $4 ; align to blocks (Y pos is always 4 pixels off)
- add d ; add Y delta
- cp $80 ; if value is >$80, the destination is off screen (either $81 or $FF underflow)
- jr nc, .impassable ; don't walk off screen
- inc l
- ld a, [hl] ; c1x6 (screen X pos)
- add e ; add X delta
- cp $90 ; if value is >$90, the destination is off screen (either $91 or $FF underflow)
- jr nc, .impassable ; don't walk off screen
- push de
- push bc
- call Func_4c70
- pop bc
- pop de
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $c
- ld l, a
- ld a, [hl] ; c1xc (forbidden directions flags(?))
- and b ; check against chosen direction (1,2,4 or 8)
- jr nz, .impassable ; direction forbidden, don't go there
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $2
- ld l, a
- ld a, [hli] ; c2x2 (sprite Y displacement, initialized at $8, keep track of where a sprite did go)
- bit 7, d ; check if going upwards (d=$ff)
- jr nz, .upwards
- add d
- cp $5
- jr c, .impassable ; if c2x2+d < 5, don't go ;bug: this tests probably were supposed to prevent sprites
- jr .checkHorizontal ; from walking out too far, but this line makes sprites get stuck
-.upwards ; whenever they walked upwards 5 steps
- sub $1 ; on the other hand, the amount a sprite can walk out to the
- jr c, .impassable ; if d2x2 == 0, don't go ; right of bottom is not limited (until the counter overflows)
-.checkHorizontal
- ld d, a
- ld a, [hl] ; c2x3 (sprite X displacement, initialized at $8, keep track of where a sprite did go)
- bit 7, e ; check if going left (e=$ff)
- jr nz, .left
- add e
- cp $5 ; compare, but no conditional jump like in the vertical check above (bug?)
- jr .passable
-.left
- sub $1
- jr c, .impassable ; if d2x3 == 0, don't go
-.passable
- ld [hld], a ; update c2x3
- ld [hl], d ; update c2x2
- and a ; clear carry (marking success)
- ret
-.impassable
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- inc a
- ld l, a
- ld [hl], $2 ; c1x1 = 2 (set movement status to delayed)
- inc l
- inc l
- xor a
- ld [hli], a ; c1x3 = 0 (clear Y movement delta)
- inc l
- ld [hl], a ; c1x5 = 0 (clear X movement delta)
- inc h
- ld a, [H_CURRENTSPRITEOFFSET]
- add $8
- ld l, a
- call Random
- ld a, [hRandomAdd]
- and $7f
- ld [hl], a ; c2x8: set next movement delay to a random value in [0,$7f] (again with delay $100 if value is 0)
- scf ; set carry (marking failure to walk)
- ret
-
-; calculates the tile pointer pointing to the tile the current sprite stancs on
-; this is always the lower left tile of the 2x2 tile blocks all sprites are snapped to
-; hl: output pointer
-getTileSpriteStandsOn: ; 5207 (1:5207)
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $4
- ld l, a
- ld a, [hli] ; c1x4: screen Y position
- add $4 ; align to 2*2 tile blocks (Y position is always off 4 pixels to the top)
- and $f0 ; in case object is currently moving
- srl a ; screen Y tile * 4
- ld c, a
- ld b, $0
- inc l
- ld a, [hl] ; c1x6: screen Y position
- srl a
- srl a
- srl a ; screen X tile
- add $14 ; screen X tile + 20
- ld d, $0
- ld e, a
- ld hl, wTileMap
- add hl, bc
- add hl, bc
- add hl, bc
- add hl, bc
- add hl, bc
- add hl, de ; wTileMap + 20*(screen Y tile + 1) + screen X tile
- ret
-
-; loads [de+a] into a
-LoadDEPlusA: ; 522f (1:522f)
- add e
- ld e, a
- jr nc, .noCarry
- inc d
-.noCarry
- ld a, [de]
- ret
-
-Func_5236: ; 5236 (1:5236)
- ld a, [$d730]
- bit 7, a
- ret z
- ld hl, $d72e
- bit 7, [hl]
- set 7, [hl]
- jp z, Func_52a6
- ld hl, $cc97
- ld a, [$cd37]
- add l
- ld l, a
- jr nc, .asm_5251
- inc h
-.asm_5251
- ld a, [hl]
- cp $40
- jr nz, .asm_525f
- call Func_52b2
- ld c, $4
- ld a, $fe
- jr .asm_5289
-.asm_525f
- cp $0
- jr nz, .asm_526c
- call Func_52b2
- ld c, $0
- ld a, $2
- jr .asm_5289
-.asm_526c
- cp $80
- jr nz, .asm_5279
- call Func_52b7
- ld c, $8
- ld a, $fe
- jr .asm_5289
-.asm_5279
- cp $c0
- jr nz, .asm_5286
- call Func_52b7
- ld c, $c
- ld a, $2
- jr .asm_5289
-.asm_5286
- cp $ff
- ret
-.asm_5289
- ld b, a
- ld a, [hl]
- add b
- ld [hl], a
- ld a, [H_CURRENTSPRITEOFFSET]
- add $9
- ld l, a
- ld a, c
- ld [hl], a
- call Func_52c3
- ld hl, $cf18
- dec [hl]
- ret nz
- ld a, $8
- ld [$cf18], a
- ld hl, $cd37
- inc [hl]
- ret
-
-Func_52a6: ; 52a6 (1:52a6)
- xor a
- ld [$cd37], a
- ld a, $8
- ld [$cf18], a
- jp Func_52c3
-
-Func_52b2: ; 52b2 (1:52b2)
- ld a, $4
- ld b, a
- jr asm_52ba
-
-Func_52b7: ; 52b7 (1:52b7)
- ld a, $6
- ld b, a
-asm_52ba: ; 52ba (1:52ba)
- ld hl, wSpriteStateData1
- ld a, [H_CURRENTSPRITEOFFSET]
- add l
- add b
- ld l, a
- ret
-
-Func_52c3: ; 52c3 (1:52c3)
- ld hl, wSpriteStateData2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $e
- ld l, a
- ld a, [hl]
- dec a
- swap a
- ld b, a
- ld hl, wSpriteStateData1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $9
- ld l, a
- ld a, [hl]
- cp $0
- jr z, .asm_52ea
- cp $4
- jr z, .asm_52ea
- cp $8
- jr z, .asm_52ea
- cp $c
- jr z, .asm_52ea
- ret
-.asm_52ea
- add b
- ld b, a
- ld [$ffe9], a
- call Func_5301
- ld hl, wSpriteStateData1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $2
- ld l, a
- ld a, [$ffe9]
- ld b, a
- ld a, [$ffea]
- add b
- ld [hl], a
- ret
-
-Func_5301: ; 5301 (1:5301)
- ld a, [H_CURRENTSPRITEOFFSET]
- add $7
- ld l, a
- ld a, [hl]
- inc a
- ld [hl], a
- cp $4
- ret nz
- xor a
- ld [hl], a
- inc l
- ld a, [hl]
- inc a
- and $3
- ld [hl], a
- ld [$ffea], a
- ret
+INCLUDE "engine/overworld/movement.asm"
INCLUDE "engine/cable_club.asm"