Page 1 of 1
Scrolling map
Posted: Thu Dec 04, 2014 10:21 am
by tryphon
I want to make a sample of a map, scrolling both horizontally and vertically, being wider and higher than the plane it's drawn onto.
I see there's a Map class in SGDK. I was wondering if methods to update the plane had been implemented, or if I have to code them (I know propeller does that and I'll have a look into its code if necessary).
I'm sorry if some documentation somewhere deals with that, I'm a little lost to find usable documentation on SGDK (for the moment, I mostly read the sources).
Re: Scrolling map
Posted: Thu Dec 04, 2014 1:23 pm
by Stef
tryphon wrote:I want to make a sample of a map, scrolling both horizontally and vertically, being wider and higher than the plane it's drawn onto.
I see there's a Map class in SGDK. I was wondering if methods to update the plane had been implemented, or if I have to code them (I know propeller does that and I'll have a look into its code if necessary).
I'm sorry if some documentation somewhere deals with that, I'm a little lost to find usable documentation on SGDK (for the moment, I mostly read the sources).
Here are the methods (and attached doxygen documentation) using the Map structure :
Code: Select all
/**
* \brief
* Load Map at specified position.
*
* \param plan
* Plan where we want to load Map.<br/>
* Accepted values are:<br/>
* - VDP_PLAN_A<br/>
* - VDP_PLAN_B<br/>
* \param map
* Map to load.
* \param basetile
* Base index and flags for tile attributes (see TILE_ATTR_FULL() macro).
* \param x
* Region X start position (in tile).
* \param y
* Region Y start position (in tile).
*
* Load the specified Map at specified plan position.
*
* \see VDP_setTileMapData()
* \see VDP_setTileMapDataEx()
*/
u16 VDP_setMap(u16 plan, const Map *map, u16 basetile, u16 x, u16 y);
/**
* \brief
* Load Map region at specified position.
*
* \param plan
* Plan where we want to load Map.<br/>
* Accepted values are:<br/>
* - VDP_PLAN_A<br/>
* - VDP_PLAN_B<br/>
* \param map
* Map to load.
* \param basetile
* Base index and flags for tile attributes (see TILE_ATTR_FULL() macro).
* \param x
* Plan X destination position (in tile).
* \param y
* Plan Y destination position (in tile).
* \param xm
* Map region X start position (in tile).
* \param ym
* Map region Y start position (in tile).
* \param wm
* Map region Width (in tile).
* \param hm
* Map region Heigh (in tile).
*
* Load the specified Map region at specified plan position.
*
* \see VDP_setTileMapDataRect()
* \see VDP_setTileMapDataRectEx()
*/
u16 VDP_setMapEx(u16 plan, const Map *map, u16 basetile, u16 x, u16 y, u16 xm, u16 ym, u16 wm, u16 hm);
I would say the VDP_setMapEx(..) should allow you to do what you want. Just don't forget to unpack the Map first (as it can be compressed), if you don't do it, the Map will be unpacked at each method call (very slow).
You have a method to unpack Map :
Code: Select all
/**
* \brief
* Unpack the specified Map structure.
*
* \param src
* map to unpack.
* \param dest
* Destination map where to store unpacked data, be sure to allocate enough space in tiles and tilemap buffer.<br/>
* If set to NULL then a dynamic allocated Map is returned.
* \return
* The unpacked Map.<br/>
* If <i>dest</i> was set to NULL then the returned map is allocated in a single bloc and can be released with Mem_Free(map).<br/>
* <i>NULL</i> is returned if there is not enough memory to store the unpacked map.
*/
Map *unpackMap(const Map *src, Map *dest);
Posted: Thu Dec 04, 2014 3:54 pm
by tryphon
Thanks
If the map is uncompressed in ROM, am I forced to unpack it (I suppose it transfers it to RAM, and I'd prefer avoid that) ?
Posted: Thu Dec 04, 2014 3:58 pm
by Stef
Oh of course if it's not compressed in rom then you don't need to unpack it

Posted: Thu Dec 04, 2014 4:05 pm
by tryphon
That seemed obvious but I'd rather ask

Thanks for your answers.
Posted: Thu Dec 04, 2014 4:26 pm
by Stef
The way i said it initially was not really clear i admit

And yeah if you need to unpack the map, it will be done in the main ram. If the MAP is *very* large then it may not even fit in free memory so using uncompressed map is sometime handy.
Posted: Thu Dec 04, 2014 7:02 pm
by djcouchycouch
tryphon wrote:I want to make a sample of a map, scrolling both horizontally and vertically, being wider and higher than the plane it's drawn onto.
I see there's a Map class in SGDK. I was wondering if methods to update the plane had been implemented, or if I have to code them (I know propeller does that and I'll have a look into its code if necessary).
I'm sorry if some documentation somewhere deals with that, I'm a little lost to find usable documentation on SGDK (for the moment, I mostly read the sources).
Eight-way scrolling like in Propeller/Goplanes is tricky. Unfortunately their code is not super clear so you might not get it right away. You might have a better time looking at the Violence Pingouin code. It doesn't do 8-way scrolling, just straight horizontal or vertical, but it's much simpler to understand. The code is a tad better laid out too.
Not saying that it's impossible. Just saying maybe some walking before running

Posted: Sat Dec 06, 2014 4:30 pm
by kubilus1
Stef, when using VDP_setMapEx, does this reload all visible tiles, or just the new ones? For instance if the map is scrolling to the right then just one column on the left side would need to be loaded, right?
I've got an 8 way unlimited scrolling demo that maybe I'll try to clean up and post at some point, but if there are facilities already built into SGDK, that may be more convenient.
Posted: Sat Dec 06, 2014 8:49 pm
by Stef
I'm not sure to understand the question, do you speak about tile or tilemap data ? setMapEx is only dealing with the second one.
Posted: Sat Dec 06, 2014 9:05 pm
by djcouchycouch
I think there's a bit of confusion.
The original poster was asking for a scrolling system, one that updates the borders of the screen with new rows/columns of data to simulate playing fields that are larger than the VDP planes.
The file functions Stef explained can be used to implement a scrolling system (use them to copy a strip of map from rom map data to a vdp plane) but it won't update the borders for you. You'll have to take care of that.
Posted: Fri Jan 23, 2015 11:28 pm
by tryphon
I have a question about Map struct : I found its specification :
Code: Select all
typedef struct
{
u16 compression;
u16 w;
u16 h;
u16 *tilemap;
} Map;
I guess tilemap is a sequence of w*h words with the bit-format (thanks Charles McDonald) :
Code: Select all
pccvhnnnnnnnnnnn
p = Priority flag
c = Palette select
v = Vertical flip
h = Horizontal flip
n = Pattern name
But from the header of VDP_setMap function :
Code: Select all
u16 VDP_setMap(u16 plan, const Map *map, u16 basetile, u16 x, u16 y);
What does the basetile do ? Is it added to each word of the tilemap before being sent to the VRAM ?
Posted: Sat Jan 24, 2015 12:10 am
by Stef
Exactly !
Code: Select all
/**
* \brief
* Load Map at specified position.
*
* \param plan
* Plan where we want to load Map.<br/>
* Accepted values are:<br/>
* - VDP_PLAN_A<br/>
* - VDP_PLAN_B<br/>
* \param map
* Map to load.
* \param basetile
* Base index and flags for tile attributes (see TILE_ATTR_FULL() macro).
* \param x
* Region X start position (in tile).
* \param y
* Region Y start position (in tile).
*
* Load the specified Map at specified plan position.
*
* \see VDP_setTileMapData()
* \see VDP_setTileMapDataEx()
*/
u16 VDP_setMap(u16 plan, const Map *map, u16 basetile, u16 x, u16 y);
The basetile value is added (actually ored) with the word data in the map. It allows you to add an offset for the first tile index for instance, but also to override h/v flip flag, palette number and priority.