Test Sprite Collision Flag

SGDK only sub forum

Moderator: Stef

Post Reply
User avatar
kubilus1
Very interested
Posts: 221
Joined: Thu Aug 16, 2012 2:25 am
Contact:

Test Sprite Collision Flag

Post by kubilus1 » Mon May 30, 2016 11:14 pm

So when, am I supposed to test the Sprite collision flag. I can't seem to get this to work reliably without adding a crazy amount of "delay". For instance, if I take the old basic sprite example and test for collision, this does not work unless I loop over the test about 1000 times.

For example, I would expect this to show me a collision, but it will not:

Code: Select all

#include <genesis.h>

#define TILE1	1
#define SPR_NBTILES	4	//tiles needed for our sprite

//const is used to keep tile in ROM, not in RAM
const u32 spriteTiles[SPR_NBTILES*8]=
{
		0x00001111, //Tile Top Left
		0x00001111,
		0x00111144,
		0x00111144,
		0x11112244,
		0x11112244,
		0x11112244,
		0x11112244,

		0x11112222, //Tile Bottom Left
		0x11112222,
		0x11112222,
		0x11112222,
		0x00111122,
		0x00111122,
		0x00001111,
		0x00001111,

		0x11110000, //Tile Top Right
		0x11110000,
		0x44111100,
		0x44111100,
		0x44221111,
		0x44221111,
		0x44221111,
		0x44221111,

		0x22221111, //Tile Bottom Right
		0x22221111,
		0x22221111,
		0x22221111,
		0x22111100,
		0x22111100,
		0x11110000,
		0x11110000
};

int main( )
{
	SpriteDef mySprite;
	SpriteDef mySprite2;
	SpriteDef mySprite3;

	//load the tile in VRAM (check it using GensKMod CPU>Debug>Genesis>VDP)
	VDP_loadTileData( (const u32 *)spriteTiles, TILE1, 4, 0);

	//optional, but take the use to
	VDP_resetSprites();

	// Try 1 : define sprite using setSprite
	// arg0 : sprite idx (from 0 to 79)
	// arg1 : x
	// arg2 : y
	// arg3 : size (from 1x1 to 4x4 tiles)
	// arg4 : tiles properties
	// arg5 : link property (more on this later)
	//VDP_setSprite(0, 0, 0, SPRITE_SIZE(2,2), TILE_ATTR_FULL(PAL0,1,0,0,TILE1), 0);


	// Try 2 : define sprite using setSpriteP
	mySprite.posx = 0;
	mySprite.posy = 0;
	mySprite.size = SPRITE_SIZE(2,2);
	mySprite.tile_attr = TILE_ATTR_FULL(PAL0,1,0,128,TILE1);
	mySprite.link  = 2; //1; //0;
	VDP_setSpriteP(0, &mySprite);

	//the sprite(s) won't be drawn until this call
	//VDP_updateSprites();

	// Try 3 : define multi sprite
	mySprite2.posx = 0;
	mySprite2.posy = 0;
	mySprite2.size = SPRITE_SIZE(1,1); //a sprite 1x1 using 1 tile
	mySprite2.tile_attr = TILE_ATTR_FULL(PAL0,1,0,64,TILE1);
	mySprite2.link  = 2;
	VDP_setSpriteP(1, &mySprite2);
	//VDP_updateSprites();

	// Try 4 : skip mySprite2
	mySprite3.posx = 0;
	mySprite3.posy = 0;
	mySprite3.size = SPRITE_SIZE(2,2);
	mySprite3.tile_attr = TILE_ATTR_FULL(PAL1,1,0,0,TILE1);
	mySprite3.link  = 0;
	VDP_setSpriteP(2, &mySprite3);

	VDP_updateSprites();


    VDP_drawText("no coll ", 2, 2);
	while(1)
	{
		VDP_waitVSync();

		VDP_resetSprites();

		//mySprite.posx++;
		mySprite.posy++;
		VDP_setSpriteP(0, &mySprite);

		//mySprite2.posx+=2;
		mySprite2.posy++;
		VDP_setSpriteP(1, &mySprite2);

		//mySprite3.posx++;
		mySprite3.posy+=2;
		VDP_setSpriteP(2, &mySprite3);

		VDP_updateSprites();
        if(GET_VDPSTATUS(VDP_SPRCOLLISION_FLAG)) {
            VDP_drawText("  COLL  ", 2, 2);
        }

	}
	return 0;
}
If I loop over GET_VDPSTATUS 1024 times, I will show the collision. Obviously that approach is no good, what am I doing wrong here?

User avatar
Stef
Very interested
Posts: 2775
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Test Sprite Collision Flag

Post by Stef » Tue May 31, 2016 11:16 am

Honestly trying to use the collision flag is, i believe, a waste of time :p
It only tells you a collision between 2 non transparent pixel sprite happened but it doesn't tell you which sprites...
It was useful back in time when you had only very few sprites but on Megadrive you never rely on this flag. In fact maybe 3 or 4 games uses it and only 1 really uses it to check collision between players versus objects and it's probably the worst game ever released on Megadrive (Barbie Super Model) :p

User avatar
kubilus1
Very interested
Posts: 221
Joined: Thu Aug 16, 2012 2:25 am
Contact:

Re: Test Sprite Collision Flag

Post by kubilus1 » Tue May 31, 2016 4:58 pm

Yeah, alone I realize that it is far from enough. But aside from being annoyed that it is not actually working correctly, I figure I may be able to take some kind of advantage of it.

For instance, let's say I use the collision detection method where I indicate which column each sprite is in. Then assume I move my spites one at a time and check collision between movement. If I detect the collision flag after moving the sprite, and lookup which sprite is in a matching column I should be able to have fairly cheap pixel-perfect collision.

Of course, there are probably a dozen details that will complicate such a method. At the very least the flags not working correctly really bugs me, is something being done in SGDK with horizontal interrupts or something that is causing the register to be read and therefore wiping out the flag?

User avatar
Stef
Very interested
Posts: 2775
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Test Sprite Collision Flag

Post by Stef » Tue May 31, 2016 5:47 pm

Normally no, by default SGDK does not read the status flag during active period as H int is not enabled by default, but you need to know that many SGDK method does read it (timer related methods, DMA...) so you have to take care of that.

User avatar
kubilus1
Very interested
Posts: 221
Joined: Thu Aug 16, 2012 2:25 am
Contact:

Re: Test Sprite Collision Flag

Post by kubilus1 » Tue May 31, 2016 11:30 pm

What I don't understand is that in this simple example, very little is going on. Basically, move sprite, VDP_setSprite, VDP_updateSprites, check collision.

No other methods are being called.

User avatar
kubilus1
Very interested
Posts: 221
Joined: Thu Aug 16, 2012 2:25 am
Contact:

Re: Test Sprite Collision Flag

Post by kubilus1 » Wed Jun 01, 2016 2:41 am

Okay figured it out. I have to check this during hblank. I setup an interrupt and that seems to work.

So I figure I can grab the vcounter when a collision is detected and know where vertically a collision is happened, more or less for free.

User avatar
Sik
Very interested
Posts: 709
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Test Sprite Collision Flag

Post by Sik » Wed Jun 01, 2016 4:35 am

Stef wrote:It only tells you a collision between 2 non transparent pixel sprite happened but it doesn't tell you which sprites...
The TMS9918A would tell you :/ But yeah it's a complete waste of time on the Mega Drive, especially since more often than not you don't want pixel perfect collision (you want there to be some leeway by not having collision against insignificant parts of the sprite, usually hitboxes are a bit smaller than the sprite in use).
Sik is pronounced as "seek", not as "sick".

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests