Tileset's?

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Post Reply
AnthonyPython
Interested
Posts: 10
Joined: Wed Oct 26, 2016 1:27 am

Tileset's?

Post by AnthonyPython » Tue Nov 08, 2016 4:05 am

Heya, guys, I understand how to load tiles and such, and this seems like a dumb question, but how do I use Tileset map's in sgdk? :?

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

Re: Tileset's?

Post by Stef » Tue Nov 08, 2016 4:43 pm

Do you want to know Tileset use or Map use ??

In fact an Image internally contains a TileSet and a Map structure.
You can directly load Image in SGDK without worrying about TileSet or Map with these methods :

Code: Select all

u16 VDP_drawImage(VDPPlan plan, const Image *image, u16 x, u16 y);
u16 VDP_drawImageEx(VDPPlan plan, const Image *image, u16 basetile, u16 x, u16 y, u16 loadpal, u16 use_dma);
But you can also just the TileSet in VRAM using :

Code: Select all

VDP_loadTileSet(const TileSet *tileset, u16 index, u8 use_dma);
As you can set tilemap manually from a Map (or part of Map) with :

Code: Select all

u16 VDP_setMap(VDPPlan plan, const Map *map, u16 basetile, u16 x, u16 y);
u16 VDP_setMapEx(VDPPlan plan, const Map *map, u16 basetile, u16 x, u16 y, u16 xm, u16 ym, u16 wm, u16 hm);

AnthonyPython
Interested
Posts: 10
Joined: Wed Oct 26, 2016 1:27 am

Re: Tileset's?

Post by AnthonyPython » Wed Nov 09, 2016 3:41 am

Stef wrote:Do you want to know Tileset use or Map use ??

In fact an Image internally contains a TileSet and a Map structure.
You can directly load Image in SGDK without worrying about TileSet or Map with these methods :

Code: Select all

u16 VDP_drawImage(VDPPlan plan, const Image *image, u16 x, u16 y);
u16 VDP_drawImageEx(VDPPlan plan, const Image *image, u16 basetile, u16 x, u16 y, u16 loadpal, u16 use_dma);
did this to fix the moon example, I couldn't get it working the other way.
Stef wrote:But you can also just the TileSet in VRAM using :

Code: Select all

VDP_loadTileSet(const TileSet *tileset, u16 index, u8 use_dma);
yep pretty familiar with this
Stef wrote:As you can set tilemap manually from a Map (or part of Map) with :

Code: Select all

u16 VDP_setMap(VDPPlan plan, const Map *map, u16 basetile, u16 x, u16 y);
u16 VDP_setMapEx(VDPPlan plan, const Map *map, u16 basetile, u16 x, u16 y, u16 xm, u16 ym, u16 wm, u16 hm);
uh, just to clarify does VDP_setMap assume the width and height of each tile is 8 x8 on the Tilemap?

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

Re: Tileset's?

Post by Stef » Wed Nov 09, 2016 10:06 am

The moon example is really outdated.
If you want to display a simple image, just does an IMAGE resource and use the VDP_drawImage(..) or VDP_drawImageEx(..) methods.
You can also have a very large image then use VDP_loadTileSet(..) and VDP_VDP_setMapEx(..) methods to update the plan with part of your image map :)
Map does work on tile basis (8x8 pixel block) as does the internal hardware.

AnthonyPython
Interested
Posts: 10
Joined: Wed Oct 26, 2016 1:27 am

Re: Tileset's?

Post by AnthonyPython » Wed Nov 09, 2016 6:11 pm

Alright, Thanks a bunch stef!

Hik
Very interested
Posts: 68
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Tileset's?

Post by Hik » Sun Nov 13, 2016 4:48 pm

I was playing around with tilesets the other day because I thought it might be better if I could have more control over the tiles.
The tileset worked a bit different than the image in the res file. For one thing it didn't have any palette. Which meant I had to
add in a palette from an image (I didn't have to load in the image itself) but this arrangement worked.

Anyway ,I made this code and thought it was relevant to this thread so I commented on it to make it a bit more understandable;

main.c

Code: Select all

#include <genesis.h>
#include "gfx.h"

#define TILE1	1
#define TILE2	2
#define TILE3	3
#define TILE4	4
#define TILE5	5
#define TILE6	6
#define TILE7	7
#define TILE8	8
#define TILE9	9
#define TILEA	10
#define TILEB	11
#define TILEC	12
#define TILED	13
#define TILEE	14
#define TILEF	15
#define TILE10	16

u16 palette[64];

void drawBlock();
void drawSand();

int main( )
{
	SYS_disableInts(); //Disables interrupts to work with the VDP properly
	VDP_loadTileSet( &ts_1, TILE1, 0); //ts_1 is a tileset
    //we're loading it from TILE1 and onwards (includes all 16 tiles in this tileset)
	
    // Prepare palettes
    memcpy(&palette[0], tile_image.palette->data, 16 * 2);
    VDP_setPalette(0, tile_image.palette->data);
	
	//This for loop draws a row of blocks from the tileset
	unsigned int i=0; //initialize i as an unsigned int
	for(;i<42;i+=2) // when i reaches 42 tiles it stops drawing. it skips 2 tiles (block width)
	{
		drawBlock(i,20); //Function drawBlock draws block at position horizontal i and vertical 20
	}
	
	//This for loop draws a row of sand blocks from the tileset to fill a rectangle
	unsigned int lg=0; //initialize lg as an unsigned int
	for(;lg<8;lg+=2) // when i reaches 8 tiles vertically it stops drawing. it skips 2 tiles
	{
		unsigned int j=0; //This is the same as the previous for loop with the 40 tiles max
		for(;j<42;j+=2) //Draws horizontally. Less than 42 makes it stop at 40 tiles.
		{
			drawSand(j,22+lg); // j is horizontal but we need to add lg to the vertical value
		}
	}
	SYS_enableInts(); //Enables interrupts again since we're done working with the VDP

	while(1) //When done with the VDP commands the game keeps running until quit
	{
		VDP_waitVSync(); 
	}

	return 0;
}

void drawBlock(unsigned int px,unsigned int py) //Function to draw block at px,py
{ //16x16 pixel block = four 8x8 tiles = 2 tile wide and 2 tile high
	VDP_setTileMapXY(PLAN_A, TILE2, px, py); //Tile 2 is upper left corner (8x8 tile)
	VDP_setTileMapXY(PLAN_A, TILE3, px+1, py); //Tile 3 is upper right corner (8x8 tile)
	VDP_setTileMapXY(PLAN_A, TILE4, px, py+1); //Tile 4 is lower left corner
	VDP_setTileMapXY(PLAN_A, TILE5, px+1, py+1); //Tile 5 is lower right corner
}

void drawSand(unsigned int sx,unsigned int sy) //Function to draw sandblock at sx,sy
{
	VDP_setTileMapXY(PLAN_A, TILEF, sx, sy); //These all use the same tile but other than that 
	VDP_setTileMapXY(PLAN_A, TILEF, sx+1, sy); //it works the same as draw block
	VDP_setTileMapXY(PLAN_A, TILEF, sx, sy+1);
	VDP_setTileMapXY(PLAN_A, TILEF, sx+1, sy+1);
}
gfx.res

Code: Select all

TILESET ts_1 "tileset1.png" -1
IMAGE tile_image "imgtile.png" -1
gfx.h

Code: Select all

#ifndef _RES_GFX_H_
#define _RES_GFX_H_

extern const TileSet ts_1;
extern const Image tile_image;

#endif // _RES_GFX_H_
I'm also including the files I used so you can see what they look like;
https://www.dropbox.com/s/4jdxia7u7ccj0 ... e.png?dl=1
https://www.dropbox.com/s/ugzw817jp1511 ... 1.png?dl=1

I used this for the first forground tiles on the Catgirl demo so you can see what the output looked like there.
There were some issues with it in my demo code because of the way I coded the Catgirl demo ,
so I switched to drawImageEx (for the time being).

But this tileset code works fine if you wish to draw the tiles manually and have more control over your tiles in code.

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

Re: Tileset's?

Post by Stef » Mon Nov 14, 2016 9:55 am

It seems to be a very complex way to execute that, but if you want more control about how to handle your tilemap you can indeed cut processing like that.
Still you can read these topics to understand how SGDK handle resources so you might have better control over your tilemap, even using the Iamge resource (just use a large image as base image, rescomp will optimize it) :

viewtopic.php?f=19&t=2005

Then you can read these topics as well :
viewtopic.php?f=19&t=2145
viewtopic.php?f=19&t=1949
viewtopic.php?f=19&t=1753
viewtopic.php?f=19&t=2028

They all discuss about how handling level map in general :)

Post Reply