Commented function

- Named and commented Func_4c70.
- Removed gfx/diagonal_lines.png, which is not actually graphics.
This commit is contained in:
YamaArashi 2014-07-28 02:09:14 -07:00
parent fb11ff7e55
commit c9946975d4
3 changed files with 186 additions and 103 deletions

View file

@ -17,7 +17,7 @@ UpdatePlayerSprite: ; 4e31 (1:4e31)
ld [wSpriteStateData1 + 2], a ld [wSpriteStateData1 + 2], a
ret ret
.asm_4e50 .asm_4e50
call Func_4c70 call DetectCollisionBetweenSprites
ld h, $c1 ld h, $c1
ld a, [wWalkCounter] ; wcfc5 ld a, [wWalkCounter] ; wcfc5
and a and a
@ -604,16 +604,16 @@ CanWalkOntoTile: ; 516e (1:516e)
jr nc, .impassable ; don't walk off screen jr nc, .impassable ; don't walk off screen
push de push de
push bc push bc
call Func_4c70 call DetectCollisionBetweenSprites
pop bc pop bc
pop de pop de
ld h, $c1 ld h, $c1
ld a, [H_CURRENTSPRITEOFFSET] ld a, [H_CURRENTSPRITEOFFSET]
add $c add $c
ld l, a ld l, a
ld a, [hl] ; c1xc (forbidden directions flags(?)) ld a, [hl] ; c1xc (directions in which sprite collision would occur)
and b ; check against chosen direction (1,2,4 or 8) and b ; check against chosen direction (1,2,4 or 8)
jr nz, .impassable ; direction forbidden, don't go there jr nz, .impassable ; collision between sprites, don't go there
ld h, $c2 ld h, $c2
ld a, [H_CURRENTSPRITEOFFSET] ld a, [H_CURRENTSPRITEOFFSET]
add $2 add $2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

281
main.asm
View file

@ -222,8 +222,16 @@ UpdateNonPlayerSprite:
.unequal .unequal
jp Func_4ed1 jp Func_4ed1
; This detects if the current sprite (whose offset is at H_CURRENTSPRITEOFFSET)
Func_4c70: ; is going to collide with another sprite by looping over the other sprites.
; The current sprite's offset will be labelled with i (e.g. $c1i0).
; The loop sprite's offset will labelled with j (e.g. $c1j0).
;
; Note that the Y coordinate of the sprite (in [$c1k4]) is one of the following
; 9 values when the sprite is aligned with the grid: $fc, $0c, $1c, $2c, ..., $7c.
; The reason that 4 is added below to the coordinate is to make it align with a
; multiple of $10 to make comparisons easier.
DetectCollisionBetweenSprites:
nop nop
ld h, wSpriteStateData1 / $100 ld h, wSpriteStateData1 / $100
@ -231,195 +239,250 @@ Func_4c70:
add wSpriteStateData1 % $100 add wSpriteStateData1 % $100
ld l, a ld l, a
ld a, [hl] ld a, [hl] ; a = [$c1i0] (picture) (0 if slot is unused)
and a and a ; is this sprite slot slot used?
ret z ret z ; return if not used
ld a, l ld a, l
add 3 add 3
ld l, a ld l, a
ld a, [hli] ld a, [hli] ; a = [$c1i3] (delta Y) (-1, 0, or 1)
call Func_4d72 call SetSpriteCollisionValues
ld a, [hli] ld a, [hli] ; a = [$C1i4] (Y screen coordinate)
add 4 add 4 ; align with multiple of $10
; The effect of the following 3 lines is to
; add 7 to a if moving south or
; subtract 7 from a if moving north.
add b add b
and $f0 and $f0
or c or c
ld [$ff90], a
ld a, [hli] ld [$ff90], a ; store Y coordinate adjusted for direction of movement
call Func_4d72
ld a, [hl] ld a, [hli] ; a = [$c1i5] (delta X) (-1, 0, or 1)
call SetSpriteCollisionValues
ld a, [hl] ; a = [$C1i6] (X screen coordinate)
; The effect of the following 3 lines is to
; add 7 to a if moving east or
; subtract 7 from a if moving west.
add b add b
and $f0 and $f0
or c or c
ld [$ff91], a
ld [$ff91], a ; store X coordinate adjusted for direction of movement
ld a, l ld a, l
add 7 add 7
ld l, a ld l, a
xor a xor a
ld [hld], a ld [hld], a ; zero [$c1id] XXX what's [$c1id] for?
ld [hld], a ld [hld], a ; zero [$c1ic] (directions in which collisions occurred)
ld a, [$ff91] ld a, [$ff91]
ld [hld], a ld [hld], a ; [$c1ib] = adjusted X coordiate
ld a, [$ff90] ld a, [$ff90]
ld [hl], a ld [hl], a ; [$c1ia] = adjusted Y coordinate
xor a
xor a ; zero the loop counter
.loop .loop
ld [$ff8f], a ld [$ff8f], a ; store loop counter
swap a swap a
ld e, a ld e, a
ld a, [H_CURRENTSPRITEOFFSET] ld a, [H_CURRENTSPRITEOFFSET]
cp e cp e ; does the loop sprite match the current sprite?
jp z, .next jp z, .next ; go to the next sprite if they match
ld d, h ld d, h
ld a, [de] ld a, [de] ; a = [$c1j0] (picture) (0 if slot is unused)
and a and a ; is this sprite slot slot used?
jp z, .next jp z, .next ; go the next sprite if not used
inc e inc e
inc e inc e
ld a, [de] ld a, [de] ; a = [$c1j2] ($ff means the sprite is offscreen)
inc a inc a
jp z, .next jp z, .next ; go the next sprite if offscreen
ld a, [H_CURRENTSPRITEOFFSET] ld a, [H_CURRENTSPRITEOFFSET]
add 10 add 10
ld l, a ld l, a
inc e
ld a, [de]
call Func_4d72
inc e inc e
ld a, [de] ; a = [$c1j3] (delta Y)
call SetSpriteCollisionValues
ld a, [de] inc e
add 4 ld a, [de] ; a = [$C1j4] (Y screen coordinate)
add 4 ; align with multiple of $10
; The effect of the following 3 lines is to
; add 7 to a if moving south or
; subtract 7 from a if moving north.
add b add b
and $f0 and $f0
or c or c
sub [hl]
jr nc, .asm_4cd4 sub [hl] ; subtract the adjusted Y coordinate of sprite i ([$c1ia]) from that of sprite j
; calculate the absolute value of the difference to get the distance
jr nc, .noCarry1
cpl cpl
inc a inc a
.asm_4cd4 .noCarry1
ld [$ff90], a ld [$ff90], a ; store the distance between the two sprites' adjusted Y values
; Use the carry flag set by the above subtraction to determine which sprite's
; Y coordinate is larger. This information is used later to set [$c1ic],
; which stores which direction the collision occurred in.
; The following 5 lines set the lowest 2 bits of c, which are later shifted left by 2.
; If sprite i's Y is larger, set lowest 2 bits of c to 10.
; If sprite j's Y is larger or both are equal, set lowest 2 bits of c to 01.
push af push af
rl c rl c
pop af pop af
ccf ccf
rl c rl c
ld b, 7
ld a, [hl]
and $f
jr z, .asm_4ce6
ld b, 9
.asm_4ce6
ld a, [$ff90]
sub b
ld [$ff92], a
ld a, b
ld [$ff90], a
jr c, .asm_4d01
; If sprite i's delta Y is 0, then b = 7, else b = 9.
ld b, 7
ld a, [hl] ; a = [$c1ia] (adjusted Y coordinate)
and $f
jr z, .next1
ld b, 9
.next1
ld a, [$ff90] ; a = distance between adjusted Y coordinates
sub b
ld [$ff92], a ; store distance adjusted using sprite i's direction
ld a, b
ld [$ff90], a ; store 7 or 9 depending on sprite i's delta Y
jr c, .checkXDistance
; If sprite j's delta Y is 0, then b = 7, else b = 9.
ld b, 7 ld b, 7
dec e dec e
ld a, [de] ld a, [de] ; a = [$c1j3] (delta Y)
inc e inc e
and a and a
jr z, .asm_4cfa jr z, .next2
ld b, 9 ld b, 9
.asm_4cfa
ld a, [$ff92]
sub b
jr z, .asm_4d01
jr nc, .next
.asm_4d01 .next2
ld a, [$ff92] ; a = distance adjusted using sprite i's direction
sub b ; adjust distance using sprite j's direction
jr z, .checkXDistance
jr nc, .next ; go to next sprite if distance is still positive after both adjustments
.checkXDistance
inc e inc e
inc l inc l
ld a, [de] ld a, [de] ; a = [$c1j5] (delta X)
push bc push bc
call Func_4d72
call SetSpriteCollisionValues
inc e inc e
ld a, [de] ld a, [de] ; a = [$c1j6] (X screen coordinate)
; The effect of the following 3 lines is to
; add 7 to a if moving east or
; subtract 7 from a if moving west.
add b add b
and $f0 and $f0
or c or c
pop bc pop bc
sub [hl] sub [hl] ; subtract the adjusted X coordinate of sprite i ([$c1ib]) from that of sprite j
jr nc, .asm_4d14
; calculate the absolute value of the difference to get the distance
jr nc, .noCarry2
cpl cpl
inc a inc a
.asm_4d14 .noCarry2
ld [$ff91], a ld [$ff91], a ; store the distance between the two sprites' adjusted X values
; Use the carry flag set by the above subtraction to determine which sprite's
; X coordinate is larger. This information is used later to set [$c1ic],
; which stores which direction the collision occurred in.
; The following 5 lines set the lowest 2 bits of c.
; If sprite i's X is larger, set lowest 2 bits of c to 10.
; If sprite j's X is larger or both are equal, set lowest 2 bits of c to 01.
push af push af
rl c rl c
pop af pop af
ccf ccf
rl c rl c
; If sprite i's delta X is 0, then b = 7, else b = 9.
ld b, 7 ld b, 7
ld a, [hl] ld a, [hl] ; a = [$c1ib] (adjusted X coordinate)
and $f and $f
jr z, .asm_4d26 jr z, .next3
ld b, 9 ld b, 9
.asm_4d26
ld a, [$ff91] .next3
ld a, [$ff91] ; a = distance between adjusted X coordinates
sub b sub b
ld [$ff92], a ld [$ff92], a ; store distance adjusted using sprite i's direction
ld a, b ld a, b
ld [$ff91], a ld [$ff91], a ; store 7 or 9 depending on sprite i's delta X
jr c, .asm_4d41 jr c, .collision
; If sprite j's delta X is 0, then b = 7, else b = 9.
ld b, 7 ld b, 7
dec e dec e
ld a, [de] ld a, [de] ; a = [$c1j5] (delta X)
inc e inc e
and a and a
jr z, .asm_4d3a jr z, .next4
ld b, 9 ld b, 9
.asm_4d3a
ld a, [$ff92]
sub b
jr z, .asm_4d41
jr nc, .next
.asm_4d41 .next4
ld a, [$ff91] ld a, [$ff92] ; a = distance adjusted using sprite i's direction
sub b ; adjust distance using sprite j's direction
jr z, .collision
jr nc, .next ; go to next sprite if distance is still positive after both adjustments
.collision
ld a, [$ff91] ; a = 7 or 9 depending on sprite i's delta X
ld b, a ld b, a
ld a, [$ff90] ld a, [$ff90] ; a = 7 or 9 depending on sprite i's delta Y
inc l inc l
; If delta X isn't 0 and delta Y is 0, then b = %0011, else b = %1100.
; (note that normally if delta X isn't 0, then delta Y must be 0 and vice versa)
cp b cp b
jr c, .asm_4d4e jr c, .next5
ld b, 12 ld b, %1100
jr .asm_4d50 jr .next6
.asm_4d4e .next5
ld b, 3 ld b, %0011
.asm_4d50
ld a, c .next6
and b ld a, c ; c has 2 bits set (one of bits 0-1 is set for the X axis and one of bits 2-3 for the Y axis)
or [hl] and b ; we select either the bit in bits 0-1 or bits 2-3 based on the calculation immediately above
ld [hl], a or [hl] ; or with existing collision direction bits in [$c1ic]
ld a, c ld [hl], a ; store new value
ld a, c ; useless code because a is overwritten before being used again
; set bit in [$c1ie] or [$c1if] to indicate which sprite the collision occurred with
inc l inc l
inc l inc l
ld a, [$ff8f] ld a, [$ff8f] ; a = loop counter
ld de, DiagonalLines ld de, SpriteCollisionBitTable
add a add a
add e add e
ld e, a ld e, a
jr nc, .asm_4d62 jr nc, .noCarry3
inc d inc d
.asm_4d62 .noCarry3
ld a, [de] ld a, [de]
or [hl] or [hl]
ld [hli], a ld [hli], a
@ -429,13 +492,18 @@ Func_4c70:
ld [hl], a ld [hl], a
.next .next
ld a, [$ff8f] ld a, [$ff8f] ; a = loop counter
inc a inc a
cp $10 cp $10
jp nz, .loop jp nz, .loop
ret ret
Func_4d72: ; takes delta X or delta Y in a
; b = delta X/Y
; c = 0 if delta X/Y is 0
; c = 7 if delta X/Y is 1
; c = 9 if delta X/Y is -1
SetSpriteCollisionValues:
and a and a
ld b, 0 ld b, 0
ld c, 0 ld c, 0
@ -450,8 +518,23 @@ Func_4d72:
.done .done
ret ret
DiagonalLines: INCBIN "gfx/diagonal_lines.2bpp" SpriteCollisionBitTable:
db %00000000,%00000001
db %00000000,%00000010
db %00000000,%00000100
db %00000000,%00001000
db %00000000,%00010000
db %00000000,%00100000
db %00000000,%01000000
db %00000000,%10000000
db %00000001,%00000000
db %00000010,%00000000
db %00000100,%00000000
db %00001000,%00000000
db %00010000,%00000000
db %00100000,%00000000
db %01000000,%00000000
db %10000000,%00000000
TestBattle: TestBattle:
ret ret