loading tiles from a specific location (GenRes)

SGDK only sub forum

Moderator: Stef

Helghast
Interested
Posts: 29
Joined: Sat May 25, 2013 8:53 pm
Location: Amsterdam, Netherlands
Contact:

loading tiles from a specific location (GenRes)

Post by Helghast » Tue Jun 11, 2013 11:30 am

Hey Guys,

If I use VDP_loadTileData, and point to the .tiles of my image (created using GenRes), it always loads a certain amount of tiles starting at the first tile.

How can I specify how to load from another index number for tiles, other then the first one?

Regards,
Dennis

eteream
Very interested
Posts: 81
Joined: Tue Dec 22, 2009 2:13 pm

Post by eteream » Tue Jun 11, 2013 12:25 pm

..
Last edited by eteream on Sat Jul 20, 2013 8:29 pm, edited 1 time in total.

Helghast
Interested
Posts: 29
Joined: Sat May 25, 2013 8:53 pm
Location: Amsterdam, Netherlands
Contact:

Post by Helghast » Tue Jun 11, 2013 1:17 pm

eteream wrote: u32* g_titles[8][ NUMBER_OF_TILES ];

void my_func()
{
u16 firstTile = put_here_your_tile_number;
// ...
VDP_loadTileData( (u8*)(g_titles)+(32*firstTile), ... )
// ....
}
I am having some difficulties understanding how this works.
How does that point to another tile number in an already existing GenRes image?

I'm just trying to properly understand what I'm doing, rather then copying over someone's code :)

regards,
Dennis

eteream
Very interested
Posts: 81
Joined: Tue Dec 22, 2009 2:13 pm

Post by eteream » Mon Jun 17, 2013 11:02 pm

..
Last edited by eteream on Sat Jul 20, 2013 8:29 pm, edited 1 time in total.

Helghast
Interested
Posts: 29
Joined: Sat May 25, 2013 8:53 pm
Location: Amsterdam, Netherlands
Contact:

Post by Helghast » Tue Jun 18, 2013 9:26 am

I actually got this working slightly differently (using VDP_loadTiles), but that does seem to slow down, will have to try using the DMA mode to transfer to memory straight away, but am getting some bad corruption when doing this (means I'm loading the tiles wrong :P).

Will try around with this some more.

regards, D.

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

Post by Stef » Wed Jun 19, 2013 3:51 pm

Can you post a portion of your code ? so we might be able to understand where is your problem :)

Helghast
Interested
Posts: 29
Joined: Sat May 25, 2013 8:53 pm
Location: Amsterdam, Netherlands
Contact:

Post by Helghast » Thu Jun 20, 2013 7:57 am

Code: Select all

#define BGTilesMemory	0x0010
#define TILESWIDTH	(SCREENWIDTH + 2)
#define TILESHEIGHT	24

// load tiles that should be visible
// this should only be updated when scrolling goes above 8 (to load next/previous tiles)
void loadBGTiles(u16 offset) {
	u16 i = 0;

	for(i=0; i<TILESHEIGHT; ++i) {
		VDP_loadTileData(scrollBG.tiles + (((offset-1) * 8) + ((i * scrollBG.width) * 8)), BGTilesMemory + (i*TILESWIDTH), TILESWIDTH, 0);
	}
}
This is what I'm using to load all the tiles.
With speed I was referring to the screen tearing (from the other thread).

regards,
Dennis

eteream
Very interested
Posts: 81
Joined: Tue Dec 22, 2009 2:13 pm

Post by eteream » Thu Jun 20, 2013 11:15 pm

..
Last edited by eteream on Sat Jul 20, 2013 8:31 pm, edited 1 time in total.

Helghast
Interested
Posts: 29
Joined: Sat May 25, 2013 8:53 pm
Location: Amsterdam, Netherlands
Contact:

Post by Helghast » Fri Jun 21, 2013 8:16 am

eteream wrote:From the official documentation:
- A CELL or a PATTERN is a 8x8 pixel graphic that can be used indirectly in planes or directly in sprites. Is 32bytes in size.
- To use a tile in a plane you need what is called a PATTERN NAME. Basically is the tile number plus some bit attributes, and is 2 bytes in size.

Reviewing your code makes me the impression that you are updating PATTERN NAMEs instead of CELLs, but using the function to load CELLs.
I had no idea there was such a thing as cells and patterns.
How would you (or anyone) advice me to make this work properly then?
I am still all new to megadrive programming, therefor I still often just need help, as I dont know all the details properly (I have learned LOTS the past few weeks though, and I really enjoy learning everything related to it).

regards,
Dennis

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

Post by Stef » Fri Jun 21, 2013 11:55 am

That link may help you to understand the difference between the tiles (8x8 pixel data block) and the tilemap (virtual screen map containing tile indexes) :

http://gamedev.stackexchange.com/questi ... 9225#49225

Helghast
Interested
Posts: 29
Joined: Sat May 25, 2013 8:53 pm
Location: Amsterdam, Netherlands
Contact:

Post by Helghast » Fri Jun 21, 2013 12:34 pm

Stef wrote:That link may help you to understand the difference between the tiles (8x8 pixel data block) and the tilemap (virtual screen map containing tile indexes) :

http://gamedev.stackexchange.com/questi ... 9225#49225
I do understand that difference, I come from a professional game development background, and have been working on all sorts of games/platforms for years.

I am more puzzled yet by the technical implementation on MegaDrive/Genesis itself.
The code I am showing above, does load the tiles into memory (as I asked in this topic's first post) as tiles of 8x8 pixels.
I scroll through them without any problems as well, it's just whenever I load the new rows into memory (I reload the whole image to display with an offset, as you can see in the code above) it tears the screen, because I think it's quite slow. I dont have any clue how to optimize that though.

Here's all the functions I'm using to scroll:

Code: Select all

// load tiles that should be visible
// this should only be updated when scrolling goes above 8 (to load next/previous tiles)
void loadBGTiles(u16 offset) {
	u16 i = 0;

	for(i=0; i<TILESHEIGHT; ++i) {
		VDP_loadTileData(scrollBG.tiles + (((offset-1) * 8) + ((i * scrollBG.width) * 8)), BGTilesMemory + (i*TILESWIDTH), TILESWIDTH, 0);
	}
}

// only needs to be called once, to create the tiles on the plane
void setBGTiles() {
	// redraw tiles in memory (might only have to do this once, if I simply regenarate the VRAM with proper tiles)
	VDP_fillTileMapRectInc(VDP_PLAN_A, TILE_ATTR_FULL(PAL1, 0, 0, 0, BGTilesMemory), -1, 6, TILESWIDTH, TILESHEIGHT);
}

// this function should only be called when the next/prev tiles need to be loaded in (based on player movement)
void updateTiles(u16 scroll, u16 posX) {
	if(scrollVal != prevScrollVal) {
		loadBGTiles(scrollVal);
		
		if(scrollVal > prevScrollVal) { VDP_setHorizontalScroll(APLAN, 0); }
		if(scrollVal < prevScrollVal) { VDP_setHorizontalScroll(APLAN, -8); }
		
		prevScrollVal = scrollVal;
	} else {
		if(lastScrollPos != posX) {
			VDP_setHorizontalScroll(APLAN, -posX%8);
			lastScrollPos = posX;
		}
	}

	// function that does the actual scrolling:
	// VDP_setVerticalScroll(u16 plan, u16 value);
}

void checkTileScroll(u16 posX) {
	// no scrolling needed here
	if(posX<SCROLLMIN) { return; } 
	if(posX>SCROLLMAX) { return; } 
	
	// if anywhere in between, get tile location
	u16 screenPos = (posX-SCROLLMIN)+1;
	scrollVal = (screenPos/TILESCROLL);
	
	updateTiles(screenPos, posX);
}
I call "checkTileScroll" in my VIntCallback every frame, with the current position of the player (which is based on where in the world he is located, not on the screen itself. I only scroll the visual screen to replicate where the player should be in game [unlike 3D, where you move the character to replicate where he should be in the world]).

regards,
Dennis

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

Post by Stef » Fri Jun 21, 2013 2:15 pm

Helghast wrote: I do understand that difference, I come from a professional game development background, and have been working on all sorts of games/platforms for years.
Oh i though you did not get that from this sentence :
I had no idea there was such a thing as cells and patterns.
But good you already known about all that then.
I am more puzzled yet by the technical implementation on MegaDrive/Genesis itself.
The code I am showing above, does load the tiles into memory (as I asked in this topic's first post) as tiles of 8x8 pixels.
I scroll through them without any problems as well, it's just whenever I load the new rows into memory (I reload the whole image to display with an offset, as you can see in the code above) it tears the screen, because I think it's quite slow. I dont have any clue how to optimize that though.

Here's all the functions I'm using to scroll:
...

I call "checkTileScroll" in my VIntCallback every frame, with the current position of the player (which is based on where in the world he is located, not on the screen itself. I only scroll the visual screen to replicate where the player should be in game [unlike 3D, where you move the character to replicate where he should be in the world]).

regards,
Dennis
Actually you should only load a bunch of tile per frame.
A classic game in the ideal case will load all background tiles before the game start and only load tiles for sprites during frame time. Normally your map is built so you re-use several time the same tile so you don't need to change them at each frame. A game like sonic may use a more complex tile cache system so it can upload some new tiles for the background at each frame but that number is still low (probably about 20 to 100 tiles max per frame).

Helghast
Interested
Posts: 29
Joined: Sat May 25, 2013 8:53 pm
Location: Amsterdam, Netherlands
Contact:

Post by Helghast » Fri Jun 21, 2013 2:45 pm

Stef wrote:
Helghast wrote: I do understand that difference, I come from a professional game development background, and have been working on all sorts of games/platforms for years.
Oh i though you did not get that from this sentence :
I had no idea there was such a thing as cells and patterns.
But good you already known about all that then.
It's more that I need to get used to the naming of things, I understood the underlying structures :)
Stef wrote: Actually you should only load a bunch of tile per frame.
A classic game in the ideal case will load all background tiles before the game start and only load tiles for sprites during frame time. Normally your map is built so you re-use several time the same tile so you don't need to change them at each frame. A game like sonic may use a more complex tile cache system so it can upload some new tiles for the background at each frame but that number is still low (probably about 20 to 100 tiles max per frame).
That's where I am messing it up then ;)

I will have to rewrite my system, is it possible to move certain tiles from memory to another location (is that done using DMA?)
I could re-arrange my memory everytime to move the current used tiles, and only load/append newer tiles. If I offset current memory then, it will result in the same thing.

My background is not made out of a tileset, if so, that would have been much easier :P

regards,
Dennis

eteream
Very interested
Posts: 81
Joined: Tue Dec 22, 2009 2:13 pm

Post by eteream » Sat Jun 22, 2013 3:37 pm

..
Last edited by eteream on Sat Jul 20, 2013 8:29 pm, edited 1 time in total.

Helghast
Interested
Posts: 29
Joined: Sat May 25, 2013 8:53 pm
Location: Amsterdam, Netherlands
Contact:

Post by Helghast » Sat Jun 22, 2013 10:43 pm

eteream wrote:
Helghast wrote:I do understand that difference, I come from a professional game development background, and have been working on all sorts of games/platforms for years.
The road is full of bodies who were too sure. Anyway, let's kick some asses:

Reviewing what you have done you just need to swap load tile and load tilemap function calls. And take a loook to documentation time to time.
Thank you, and i'm sorry if I came across really cocky. Apologies to you too Stef. I really appreciate you guys helping me out!

I do read the documentation all the time actually, but the search function is kinda 'hard'. As in, I need to know the syntax beforehabd so I can read it back. It doesnt let me search for related keywords, which makes it hard to find certain functions.

Kind regards, Dennis

Post Reply