Scrolling map

SGDK only sub forum

Moderator: Stef

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

Scrolling map

Post by tryphon » Thu Dec 04, 2014 10:21 am

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).

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

Re: Scrolling map

Post by Stef » Thu Dec 04, 2014 1:23 pm

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);

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

Post by tryphon » Thu Dec 04, 2014 3:54 pm

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) ?

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

Post by Stef » Thu Dec 04, 2014 3:58 pm

Oh of course if it's not compressed in rom then you don't need to unpack it ;)

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

Post by tryphon » Thu Dec 04, 2014 4:05 pm

That seemed obvious but I'd rather ask :)
Thanks for your answers.

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

Post by Stef » Thu Dec 04, 2014 4:26 pm

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.

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch » Thu Dec 04, 2014 7:02 pm

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 :)

kubilus1
Very interested
Posts: 237
Joined: Thu Aug 16, 2012 2:25 am
Contact:

Post by kubilus1 » Sat Dec 06, 2014 4:30 pm

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.

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

Post by Stef » Sat Dec 06, 2014 8:49 pm

I'm not sure to understand the question, do you speak about tile or tilemap data ? setMapEx is only dealing with the second one.

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch » Sat Dec 06, 2014 9:05 pm

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.

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

Post by tryphon » Fri Jan 23, 2015 11:28 pm

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 ?

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

Post by Stef » Sat Jan 24, 2015 12:10 am

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.

Post Reply