Sprite detection routine (calling Artrag)

By Metalion

Paragon (1625)

Metalion's picture

10-08-2021, 22:40

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 or register to post comments

By Grauw

Ascended (10768)

Grauw's picture

10-08-2021, 22:45

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 Smile.

By Metalion

Paragon (1625)

Metalion's picture

11-08-2021, 09:17

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
	add	(ix+6)		; add y offset within the sprite 1 (yoffset1)
	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
	add	(ix+10)		; add y offset within the sprite 2 (yoffset2)
	ld	l,a
;	ld	h,0		; hl = y2 + yoffset2 + 32
	ld	h,d		<=== optimization

By turbor

Hero (520)

turbor's picture

11-08-2021, 11:36

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..

By Metalion

Paragon (1625)

Metalion's picture

11-08-2021, 23:37

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.

By Huey

Prophet (2694)

Huey's picture

12-08-2021, 17:45

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.

By Metalion

Paragon (1625)

Metalion's picture

12-08-2021, 20:09

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.

By Metalion

Paragon (1625)

Metalion's picture

12-08-2021, 21:55

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) ?

By ARTRAG

Enlighted (6935)

ARTRAG's picture

12-08-2021, 22:03

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

By Metalion

Paragon (1625)

Metalion's picture

13-08-2021, 00:20

Hi Artrag,

Thanks for your answer.
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.

By ARTRAG

Enlighted (6935)

ARTRAG's picture

13-08-2021, 08:32

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