# Sprite detection routine (calling Artrag)

Hello,

I found this very nice routine written by Artrag for collision detection of sprites on MSX1 here. However, as I understand it, it does tests on y collision and on x collision but only provides a return on left and right collision.

How are handled collisions from above and below ?

PS : This routine uses the stack to pass parameters and then use 'ix' to access them. Love that trick! Brilliant!

Для того, чтобы оставить комментарий, необходимо регистрация или !login
Metalion wrote:

PS : This routine uses the stack to pass parameters and then use 'ix' to access them. Love that trick! Brilliant!

It’s the C way .

Reading again the routine this morning, with a clearer mind, I think I have understood. It does deal with collision from every axis, it's just that the result contains the left/right orientation of the collision.

I'm thinking this collision, for example, would be detected as a left-side collision, whether the sprites comes from the left or from above. Artrag, can you confirm ?

```+------+
|      |
|    +-|----+
+----|-+    |
|      |
+------+```

PS : I found a small optimization :

```;-------------------------------------------------------------------------------
; test y
;-------------------------------------------------------------------------------
; de = y1 + yoffset1 + 32
ld	a,(de)		; a = y sprite 1 (y1)
add	32		; needed to deal with sprites partially under the top border
ld	e,a
ld	d,0		; de = y1 + yoffset1 + 32

; hl = y2 + yoffset2 + 32
ld	a,(bc)		; a = y sprite 2 (y2)
add	32		; needed to deal with sprites partially under the top border
ld	l,a
;	ld	h,0		; hl = y2 + yoffset2 + 32
ld	h,d		<=== optimization```
Metalion wrote:

How are handled collisions from above and below ?

I'm not sure what you are asking...

if the sprites are separated enough on the Y-axis that they do not tough the code returns HL being 0.
If a collision is possible on the Y-axis then the code checks to see if there is a collosion on the X-axis.
If they are separated enough on the X-axis that they do not tough the code returns HL being 0.

if they tough (being there enclosing rectangles overlap) you get extra info:
if x_of_sprites 2 < x_of_-sprite1 then hl becomes minus one
if x_of_sprites 2 >= x_of_-sprite1 then hl becomes one

There is nothing in the return value of hl regarding info about the vertical position of the two sprites, only that they overlap because hl is not zero.

if you want info if sprite1 is above/below sprite2 you will need to extend the code..

Yes, I came to the same conclusion (see my second message). I suppose this routine was specifically built for the needs of MOAM, and that Artrag needed to have this additional info about the collision coming from the left or from the right.

Which means that if I only need the collision detection and nothing else, it could probably be simplified.

The collision routine from Artrag is just for collision. We did not do anything regarding testing what direction of the collision is in MOAM. For jumping on rafts for example we did a separate test in the raft code when we collide with the player to see if the player is falling from above.

I beg to differ ... Otherwise, why would it have a test on x axis on both sides, and then provide a different value of hl if the collision is from the left or from the right ? There must have been a need for that result.

Metalion wrote:

I beg to differ ... Otherwise, why would it have a test on x axis on both sides, and then provide a different value of hl if the collision is from the left or from the right ? There must have been a need for that result.

It might have to do with the fact that the y axis collision is only checked from one side.
Was it the case in MOAM (for example, collision coming only from above, never from below) ?

Hi Metalion, sorry for the late answer
As far as I can remember the code for Moam tests for collisions from every axis returning 0 for no collision, >0 for collision from right and <0 for collision from left. The collision direction was used to trigger back jumps after a hit from an enemy

Hi Artrag,

OK I now understand better the need for a left/right detection.

I've rewritten you routine a little bit, because some parts are unclear to me.
Especially those 2 snippets.

1) computing delta y and comparing it to the size of sprite 2

```	ld	b,(ix+11)	; b = ysize2
ex	de,hl
or	a		; resets carry
sbc	hl,de		; hl = ypixel1 - ypixel2
jr	nc,.test_delta	; nc: ypixel1 >= ypixel2
cp	b		; is ypixel2+32 >= ysize2 ???? c: ypixel1 <  ypixel2
jr	nc,.no_collision; test on y failed ??????```

Isn't there a 'ld a,l' missing before the 'cp b' ?
It would make more sense: comparing deltay with the sprite size ...
Also I don't understand why there's only 1 test (ypixel1 - ypixel2) < ysize2.
Shouldn't there be a second test : (ypixel2 - ypixel1) < ysize1 ?

2) comparing delta x to the size of either sprite

```	ld	a,h
or	a
jr	nz,.collision	; deltax > 255, collision ???

ld	a,l
cp	b
jp	nc,.no_collision; no collision if delta >= size```

Why would there be a collision if deltax is greater than 255 ?

Thank you.

Hi Metalion
In the last post of the same page there is a link to a Rom with a demo and all sources to compile it.
Have a look at the collision.asm you can find there and to the way the rom works.
Iirc using space you can swap which sprite is controlled