diff options
author | YamaArashi <shadow962@live.com> | 2014-07-28 02:09:14 -0700 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2014-07-28 02:22:58 -0700 |
commit | c9946975d4cd806c92c1aa1efef94eb41d8b9d36 (patch) | |
tree | cf2a4813e4822dc759bfa84e1f470628e84d43b7 | |
parent | fb11ff7e55be56cef9234c8443614f04f2157a1e (diff) |
Commented function
- Named and commented Func_4c70.
- Removed gfx/diagonal_lines.png, which is not actually graphics.
-rw-r--r-- | engine/overworld/movement.asm | 8 | ||||
-rw-r--r-- | gfx/diagonal_lines.png | bin | 100 -> 0 bytes | |||
-rwxr-xr-x | main.asm | 273 |
3 files changed, 182 insertions, 99 deletions
diff --git a/engine/overworld/movement.asm b/engine/overworld/movement.asm index f08a20cb..dbec2e4f 100644 --- a/engine/overworld/movement.asm +++ b/engine/overworld/movement.asm @@ -17,7 +17,7 @@ UpdatePlayerSprite: ; 4e31 (1:4e31) ld [wSpriteStateData1 + 2], a ret .asm_4e50 - call Func_4c70 + call DetectCollisionBetweenSprites ld h, $c1 ld a, [wWalkCounter] ; wcfc5 and a @@ -604,16 +604,16 @@ CanWalkOntoTile: ; 516e (1:516e) jr nc, .impassable ; don't walk off screen push de push bc - call Func_4c70 + call DetectCollisionBetweenSprites pop bc pop de ld h, $c1 ld a, [H_CURRENTSPRITEOFFSET] add $c 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) - jr nz, .impassable ; direction forbidden, don't go there + jr nz, .impassable ; collision between sprites, don't go there ld h, $c2 ld a, [H_CURRENTSPRITEOFFSET] add $2 diff --git a/gfx/diagonal_lines.png b/gfx/diagonal_lines.png Binary files differdeleted file mode 100644 index 400c04b5..00000000 --- a/gfx/diagonal_lines.png +++ /dev/null @@ -222,8 +222,16 @@ UpdateNonPlayerSprite: .unequal jp Func_4ed1 - -Func_4c70: +; This detects if the current sprite (whose offset is at H_CURRENTSPRITEOFFSET) +; 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 ld h, wSpriteStateData1 / $100 @@ -231,195 +239,250 @@ Func_4c70: add wSpriteStateData1 % $100 ld l, a - ld a, [hl] - and a - ret z + ld a, [hl] ; a = [$c1i0] (picture) (0 if slot is unused) + and a ; is this sprite slot slot used? + ret z ; return if not used ld a, l add 3 ld l, a - ld a, [hli] - call Func_4d72 + ld a, [hli] ; a = [$c1i3] (delta Y) (-1, 0, or 1) + call SetSpriteCollisionValues - ld a, [hli] - add 4 + ld a, [hli] ; a = [$C1i4] (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 and $f0 or c - ld [$ff90], a - ld a, [hli] - call Func_4d72 + ld [$ff90], a ; store Y coordinate adjusted for direction of movement - 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 and $f0 or c - ld [$ff91], a + + ld [$ff91], a ; store X coordinate adjusted for direction of movement ld a, l add 7 ld l, a xor a - ld [hld], a - ld [hld], a + ld [hld], a ; zero [$c1id] XXX what's [$c1id] for? + ld [hld], a ; zero [$c1ic] (directions in which collisions occurred) + ld a, [$ff91] - ld [hld], a + ld [hld], a ; [$c1ib] = adjusted X coordiate ld a, [$ff90] - ld [hl], a - xor a + ld [hl], a ; [$c1ia] = adjusted Y coordinate + + xor a ; zero the loop counter .loop - ld [$ff8f], a + ld [$ff8f], a ; store loop counter swap a ld e, a ld a, [H_CURRENTSPRITEOFFSET] - cp e - jp z, .next + cp e ; does the loop sprite match the current sprite? + jp z, .next ; go to the next sprite if they match ld d, h - ld a, [de] - and a - jp z, .next + ld a, [de] ; a = [$c1j0] (picture) (0 if slot is unused) + and a ; is this sprite slot slot used? + jp z, .next ; go the next sprite if not used inc e inc e - ld a, [de] + ld a, [de] ; a = [$c1j2] ($ff means the sprite is offscreen) inc a - jp z, .next + jp z, .next ; go the next sprite if offscreen ld a, [H_CURRENTSPRITEOFFSET] add 10 ld l, a + inc e + ld a, [de] ; a = [$c1j3] (delta Y) + call SetSpriteCollisionValues - ld a, [de] - call Func_4d72 inc e + ld a, [de] ; a = [$C1j4] (Y screen coordinate) + add 4 ; align with multiple of $10 - ld a, [de] - add 4 +; 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 and $f0 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 inc a -.asm_4cd4 - ld [$ff90], a - +.noCarry1 + 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 rl c pop af ccf rl c + +; If sprite i's delta Y is 0, then b = 7, else b = 9. ld b, 7 - ld a, [hl] + ld a, [hl] ; a = [$c1ia] (adjusted Y coordinate) and $f - jr z, .asm_4ce6 + jr z, .next1 ld b, 9 -.asm_4ce6 - ld a, [$ff90] + +.next1 + ld a, [$ff90] ; a = distance between adjusted Y coordinates sub b - ld [$ff92], a + ld [$ff92], a ; store distance adjusted using sprite i's direction ld a, b - ld [$ff90], a - jr c, .asm_4d01 + 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 dec e - ld a, [de] + ld a, [de] ; a = [$c1j3] (delta Y) inc e and a - jr z, .asm_4cfa + jr z, .next2 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 l - ld a, [de] + ld a, [de] ; a = [$c1j5] (delta X) push bc - call Func_4d72 + + call SetSpriteCollisionValues 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 and $f0 or c + pop bc - sub [hl] - jr nc, .asm_4d14 + sub [hl] ; subtract the adjusted X coordinate of sprite i ([$c1ib]) from that of sprite j + +; calculate the absolute value of the difference to get the distance + jr nc, .noCarry2 cpl inc a -.asm_4d14 - ld [$ff91], a - +.noCarry2 + 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 rl c pop af ccf rl c + +; If sprite i's delta X is 0, then b = 7, else b = 9. ld b, 7 - ld a, [hl] + ld a, [hl] ; a = [$c1ib] (adjusted X coordinate) and $f - jr z, .asm_4d26 + jr z, .next3 ld b, 9 -.asm_4d26 - ld a, [$ff91] + +.next3 + ld a, [$ff91] ; a = distance between adjusted X coordinates sub b - ld [$ff92], a + ld [$ff92], a ; store distance adjusted using sprite i's direction ld a, b - ld [$ff91], a - jr c, .asm_4d41 + ld [$ff91], a ; store 7 or 9 depending on sprite i's delta X + jr c, .collision + +; If sprite j's delta X is 0, then b = 7, else b = 9. ld b, 7 dec e - ld a, [de] + ld a, [de] ; a = [$c1j5] (delta X) inc e and a - jr z, .asm_4d3a + jr z, .next4 ld b, 9 -.asm_4d3a - ld a, [$ff92] - sub b - jr z, .asm_4d41 - jr nc, .next -.asm_4d41 - ld a, [$ff91] +.next4 + 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 a, [$ff90] + ld a, [$ff90] ; a = 7 or 9 depending on sprite i's delta Y 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 - jr c, .asm_4d4e - ld b, 12 - jr .asm_4d50 -.asm_4d4e - ld b, 3 -.asm_4d50 - ld a, c - and b - or [hl] - ld [hl], a - ld a, c + jr c, .next5 + ld b, %1100 + jr .next6 +.next5 + ld b, %0011 + +.next6 + 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) + and b ; we select either the bit in bits 0-1 or bits 2-3 based on the calculation immediately above + or [hl] ; or with existing collision direction bits in [$c1ic] + 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 - ld a, [$ff8f] - ld de, DiagonalLines + ld a, [$ff8f] ; a = loop counter + ld de, SpriteCollisionBitTable add a add e ld e, a - jr nc, .asm_4d62 + jr nc, .noCarry3 inc d -.asm_4d62 +.noCarry3 ld a, [de] or [hl] ld [hli], a @@ -429,13 +492,18 @@ Func_4c70: ld [hl], a .next - ld a, [$ff8f] + ld a, [$ff8f] ; a = loop counter inc a cp $10 jp nz, .loop 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 ld b, 0 ld c, 0 @@ -450,8 +518,23 @@ Func_4d72: .done 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: ret |