Multisprites ?

SGDK only sub forum

Moderator: Stef

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

Post by Stef » Mon Dec 22, 2014 11:52 pm

A 1:1 port is not possible due to palettes limitations (I don't have System-16 specs, but Shinobi display quite a few more than 61 colors). I'll try to adapt MD Shadow Dancer constraints (12 colors for Musashi, one palette for the background, and clever use of the rest). Except for that, I'll try to stick the most closely possible to the arcade.
Oh yeah of course, i said 1:1 but indeed with the color limitation in mind, also the sound may be a bit different but i believe it can be as good as the arcade version at least.

Shadow Dancer updates up to 256 tiles, from what I saw.
I also think I'll use fixed address in VRAM.
The sprite engine is aim to do almost every thing for you (as the VRAM tile allocation) but you still have the possibility to fix the sprite tile position in VRAM by using the sprite->fixedIndex field (-1 mean auto, else it is the index of the tiles in VRAM).

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Post by tryphon » Sun Dec 28, 2014 11:23 am

From sprite_eng.h :

Code: Select all

/**
 *  \struct Sprite
 *      Sprite structure.<br/>
 *      Used to manage an active sprite in game condition.
 *
 *  \param spriteDef
 *      Sprite definition pointer
 *  \param animation
 *      Animation pointer cache
 *  \param frame
 *      AnimationFrame pointer cache
 *  \param x
 *      current sprite X position
 *  \param y
 *      current sprite Y position
 *  \param animInd
 *      current animation index
 *  \param frameInd
 *      current frame animation index
 *  \param seqInd
 *      current frame animation sequence index
 *  \param timer
 *      timer for current frame
 *  \param attribut
 *      sprite extra attribut (see TILE_ATTR() macro)
 *  \param fixedIndex
 *      fixed VRAM tile index for this sprite, by default it is set to -1 for dynamic allocation
 *  \param data
 *      misc data to handle sprite (free use for user)
 *  \param visibility
 *      visibility flag for each VDP sprite of current frame
 */
How do I get the "Animation pointer cache" and the 'AnimationFrame pointer cache" ?

How does the visibility flag work ?

(also, there's a probable copy/paste mistake at line 135 - 136 of the same file, with no consequence : there's no timer field in Animation struct).

Edit : correct me if I'm wrong but it seems that I don't need to define the Sprite, just create a blank one and give it to SPR_initSprite() ?

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

Post by Stef » Mon Dec 29, 2014 12:04 pm

Exactly, you don't need to feed yourself the Sprite structure and so don't mess with the animation or frame cache ;)
Just use the SPR_xxx methods to manipulate your Sprite structure, you should not directly modify Sprites fields values.
Thanks for the typo about the doc !

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Post by tryphon » Sat Jan 03, 2015 1:41 pm

Seems like I forgot to thank you : thanks :)

Another other question : what's the use of the 'palette' field in the SpriteDef struct ?

I looked into spr_engine.c and didn't see what it was used for. Can it be Null ?

To be fair, since most of the palettes are shared between different sprites, and most sprite use only a portion of an entire palette, I'd prefer handling the palettes myself...

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Post by tryphon » Mon Jan 19, 2015 11:54 pm

This question is just for a C user.
Sorry, my C is really rusty.

In the sample given by Stef :

Code: Select all

u32 _tiledata1[4] =
{
  0x00022334,
  0x01113455,
  0x01234553,
  0x00113430
};

TileSet _tset1 =
{
    COMPRESSION_NONE,    // compression
    4*4,    // number of tile
    _tiledata1   // tiledata
};

FrameSprite _fspr1 =
{
  // VDPSprite
  {
    0,    // y pos
    SPRITE_SIZE(2, 2),    // size_link (2x2 tiles here)
    TILE_ATTR_FULL(FALSE, PAL0, FALSE, FALSE, 0),    // tile attributs
    0     // x pos
  },
  // TileSet*
  _tset1
}
so in the before-the-last line, _tset is a TileSet type object. But the doc says :

Code: Select all

typedef struct
{
    VDPSprite vdpSprite;
        TileSet *tileset;
}  FrameSprite;
So it expects a pointer to a TileSet.

So shouldn't the line in the sample be :

Code: Select all

  // TileSet*
  &_tset1 // ptr to _tset1
}
?

Is this a typo by Stef or a misunderstanding by me ?
There are other things of the same kind during the whole sample. I got my own sample compiled, but it crashes as soon as I run it :)

I'm really sorry for the triviality of this question, be sure I wouldn't have hesitated some years ago but it's a really long time since I last coded in C.

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

Post by Stef » Tue Jan 20, 2015 9:43 am

Indeed i should have used &_tset1, sorry for the typo, and i probably made it multiple time.
The palette field is just to allow a bit more of flexibility in the sprite definition but indeed almost time you will share the same palette so if you define the structures manually you can always point to the same one ;)

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Post by tryphon » Tue Jan 20, 2015 10:14 am

Thanks a lot and you don't have to be sorry for my stupidity.

I'll try to debug my code alone but be ready for some stupid questions :)

That's crazy, I became fluent with CaML (which must concern 0.000001 % of coders) and forgot my C. How I hate switching languages !

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Post by tryphon » Tue Jan 20, 2015 10:27 pm

Not yet victory, but likely not too far.

My sprite is displayed, I can move it but... only the first tile appears (whereas it's a 2x2 tiles sprite). I checked, and the 4 tiles are loaded in VRAM.

Here's where my sprite is defined (sorry for the weird names, it's software generated) :

Code: Select all

#include <genesis.h>

u16 const pal_sprites[16] = {
	0xDB9, 0x000, 0xEEE, 0x8D4, 0x38D, 0x000, 0x000, 0x000,
	0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
};

Palette palette_sprites = {
	0, 	// index
	16,	// size
	pal_sprites	// color data
};

u32 const down_0_tiledata_00[32] = {
	0x44444333,
	0x44443333,
	0x44443223,
	0x44433222,
	0x44432212,
	0x44432212,
	0x44432244,
	0x44334444,

	0x44333444,
	0x43333222,
	0x43333222,
	0x33343222,
	0x44442222,
	0x44442222,
	0x44444442,
	0x44444444,

	0x33444444,
	0x33344444,
	0x22344444,
	0x22234444,
	0x12234444,
	0x12234444,
	0x42333344,
	0x44433334,

	0x44333333,
	0x22233444,
	0x22223444,
	0x22222444,
	0x22222444,
	0x22244444,
	0x24444444,
	0x44444444
};

TileSet down_0_tileset_00 = {
    	COMPRESSION_NONE,	// compression
    	4,	// number of tiles
    	down_0_tiledata_00	// tiledata
};

FrameSprite down_0_fsprite_00 = {
	// VDPSprite
	{
		0,	// y pos
		SPRITE_SIZE(2, 2),	// size_link (2x2 tiles here)
		TILE_ATTR_FULL(FALSE, PAL0, FALSE, FALSE, 0),	// tile attributs 
		0	// x pos
	},
	// TileSet*
	&down_0_tileset_00
} ;

FrameSprite* down_0_sprites[] = {
	&down_0_fsprite_00
};

AnimationFrame down_0 = {
	1,	// number of sprites
	&down_0_sprites,	// sprite array
	0,	// number of collision
	NULL,	// collision array
	16,	// width of current animation frame in pixel
	16,	// height of current animation frame in pixel
	COLLISION_TYPE_NONE,	// collision type
	1,	// time to keep this frame in number of frame
};

AnimationFrame* down_frames[] = {
	&down_0
};

u8*	down_seqframes[] = {0} ;

Animation down = {
	1,	// number of frames
	&down_frames,	// frames composing the animation
	1,	// animation sequence length
	&down_seqframes,	// animation sequence,
	-1,	// loop (-1 if no loop)
};

Animation* gurin_animations[] = {
	&down
};

SpriteDefinition gurin_sprite = {
	&palette_sprites,	// palette (NULL because manually handled)
	1,	// number of animations
	&gurin_animations,	// animations
};
The main code (just a copy/paste/delete from sample/sprite to simplify) :

Code: Select all

#include <genesis.h>

#include "gurin.h"

#define ANIM_STAND      0
#define ANIM_UP	        1
#define ANIM_DOWN       2
#define ANIM_LEFT       3
#define ANIM_RIGHT      4

// forward
static void updatePhysic();
static void updateAnim();

// sprites structure
Sprite sprites[1];

u16   posx;
u16   posy;
u16   movx;
u16   movy;

int main()
{
    // disable interrupt when accessing VDP
    SYS_disableInts();
    // initialization
    VDP_setScreenWidth320();

    // init sprites engine
    SPR_init(256);

    // VDP process done, we can re enable interrupts
    SYS_enableInts();

    posx = 160;
    posy = 160;
    movx = 1;
    movy = 0;

    // init sprite
    SPR_initSprite(&sprites[0], 
                   &gurin_sprite, 
	   posx, 
	   posy, 
	   TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
    SPR_update(sprites, 1);

    // prepare palettes
    //memcpy(&palette[0], palette_sprites, 16 * 2);
    VDP_setPaletteColors(0, pal_sprites, 16);


    while(TRUE)
    {
        updatePhysic();
        updateAnim();

        // update sprites (only one to update here)
        SPR_update(sprites, 1);

        VDP_waitVSync();
    }

    return 0;
}

static void updatePhysic()
{
    // set sprite position
    posx++ ;
    SPR_setPosition(&sprites[0], 
                    posx, 
	    posy);
}

static void updateAnim()
{
    SPR_setAttribut(&sprites[0], TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
}
Note : yes, I know it's kinda stupid to use the sprite engine for a Sprite that is made of only one FrameSprite, but that's only a test.

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

Post by Stef » Wed Jan 21, 2015 9:46 am

Everything seems to be correct in the sprite definition part, maybe i made a mistake about the sprite size information. Can you try to replace it this way ? :

Code: Select all

FrameSprite down_0_fsprite_00 = {
   // VDPSprite
   {
      0,   // y pos
      (SPRITE_SIZE(2, 2) << 8),   // size_link (2x2 tiles here)
      TILE_ATTR_FULL(FALSE, PAL0, FALSE, FALSE, 0),   // tile attributs
      0   // x pos
   },
   // TileSet*
   &down_0_tileset_00
} ; 

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Post by tryphon » Wed Jan 21, 2015 9:13 pm

That fixed it, thanks :)

Still not won though, I have a crash as soon as I add a second frame in my animation. I investigate :)

EDIT : in fact it works. It crashes if I set 'loop' in Animation to -1. I supposed that a loop of -1 would cause the animation to stay on the last frame forever, but this is not the case. What is it supposed to do ?

Now, some more testing, then a true multisprite...

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

Post by Stef » Thu Jan 22, 2015 9:42 am

Indeed there is an error in my code with loop set to -1, it looks like i do not handle that case and actually i don't even need it, if you want to avoid loop you can just set it to the last frame index =)

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Post by tryphon » Fri Jan 23, 2015 7:27 pm

Thanks, that's what I ended to do :)

POLYGAMe
Very interested
Posts: 151
Joined: Sun Apr 14, 2013 1:19 am
Location: Auckland, New Zealand
Contact:

Re: Multisprites ?

Post by POLYGAMe » Sun Jan 03, 2016 8:09 pm

Any updates on the Shinobi port? I've wanted Shinobi on SMD for decades! :D

tryphon
Very interested
Posts: 316
Joined: Sat Aug 17, 2013 9:38 pm
Location: France

Re: Multisprites ?

Post by tryphon » Tue Jan 05, 2016 9:49 pm

It goes its way, slowly but surely. I've not as much time to devote to it as I'd like, and I have other projects to handle with so few time, both Sega related : a translation of Phantasy Star Generation 1&2 (see here, here and there) on PS2 and a translation of The Hybrid Front on Megadrive (I may have found a translator).

Concerning Shinobi, you can see my progress on sega-16 board.

I'm in a rewrite of some part of the code, it broke everything :P
Now fixing bit by bit :mrgreen:

POLYGAMe
Very interested
Posts: 151
Joined: Sun Apr 14, 2013 1:19 am
Location: Auckland, New Zealand
Contact:

Re: Multisprites ?

Post by POLYGAMe » Wed Jan 06, 2016 1:20 am

Cool, will check out the thread! I'm making an SMD game myself. I hurt my back a couple of weeks ago and decided to rest up with my Atari Lynx. Chip's Challenge inspired me to make a puzzle game. So far I have made some flashing text. Hahaha.

Post Reply