Page 1 of 2

RESCOMP and individual nametable entries?

Posted: Sun Dec 23, 2018 1:02 pm
by realbrucest
Hi everyone.

I've trying (no luck atm) to figure out any way or method for dealing with individual nametable patterns using SGDK (when converting through Rescomp).

I need a few tiles to be hight-priority, some others low-priority. But I don't know if there is some possiblilty of setting that kind of values to the map before Rescomp gets me the obj file.

Palette and priority for individual tiles/patters has been for me always a big issue when coding megadrive. It is a powerful feature when used propperly to enhance backgrounds, long ago a few fellas and I made a tool for that but it was for a own-use project away from SGDK.

So the question is (sorry for the messy introduction-text :mrgreen: ) ... are there (somewhere) any SGDK-Image compatible tools or any way to make use of Rescomp to set priority and palette attributes individually?, not a global value to the whole map.

Re: RESCOMP and individual nametable entries?

Posted: Wed Dec 26, 2018 4:58 pm
by Stef
No unfortunately you can't encode priority inside the image so rescomp can decode it.
The way to do is to have 2 images, one for low priority and one for high priority then you combine both images map. You generate a new map out of it by using :

Code: Select all

if (*mapHigh)
 *map = *mapHigh | TILE_ATTR_PRIORITY_MASK;
else
 *map = *mapLow;
mapHigh++;
mapLow++;
map++;
For the palettes, Rescomp is able to handle multi palette images but you should carefully prepare your palettes inside the image.

Re: RESCOMP and individual nametable entries?

Posted: Mon Dec 31, 2018 5:21 pm
by realbrucest
Wow :shock: :mrgreen:

I'd never though of that method... That's a very cool and handy trick.

Thanks a lot Stef, i'll give it a try asap and I guess I'll use it plenty in advance.

Re: RESCOMP and individual nametable entries?

Posted: Mon Dec 31, 2018 8:37 pm
by Stef
To be honest that is not a really straightforward way of doing it :p Another trick is to have a software allowing to encode priority in palette bit (bit 6 or bit 7 as MDTiler is doing) but i think that is not really easy for users to understand how it works.

Re: RESCOMP and individual nametable entries?

Posted: Tue Mar 05, 2019 5:35 pm
by realbrucest
It's been a while but I couldn't attempt a few tests til now...

I wanted to use plane A to bring a normal-color/shadow layer on top of plane B (so I can overlap sprites "Vectorman-like" as well).

For testing purpouses I'm using these three images:

Image
  • bgb: image to dump into plane B
  • bga: "empty" image to dump into plane A
  • bga_priority: image from where the priority map array will be generated/taken.
EDIT: SOLVED a couple of posts down.

Re: RESCOMP and individual nametable entries?

Posted: Wed Mar 06, 2019 11:06 am
by Stef
This trash the priority flag because your image (and so its tilemap) is stored in ROM.
So when you're doing that :

Code: Select all

 u16 *aplan_tilemap = bga_image.map->tilemap;
    u16 *shadowmap_tilemap = bga_priority_image.map->tilemap;

    ....
           *aplan_tilemap &= TILE_ATTR_PRIORITY_MASK;
    ....
    }
you're trying to write to ROM, which obviously won't work :p
Also i don't understand your ' while(shadowmap_tilemap)' statement, there is something wrong there.

What you need to do is to copy your image to RAM before trying to modify its tilemap.
Better would be to only unpack the 'map' information (with unpackMap(..) method) to RAM then only modify the map part.
Then you can use VDP_loadTileSet(..) and VDP_setMap(..) methods to draw your image.

Re: RESCOMP and individual nametable entries?

Posted: Wed Mar 06, 2019 11:28 am
by realbrucest
you're trying to write to ROM, which obviously won't work :p
Ouch! :cry: :mrgreen: :roll:

Ok, so ... dumping into RAM and then VDP_loadTileSet(..) and VDP_setMap(..) methods ... I'll give it a try like that. Thanks again Stef.

EDIT:

Mmmmmm ... :? :?:

Setmap also relies on "basetile" ...

Code: Select all

u16 VDP_setMap(VDPPlan plan, const Map *map, u16 basetile, u16 x, u16 y)
It will smash once again priorities, isn't it?

EDIT 2:

DONE! :mrgreen:

Code: Select all

// SGDK LIBS //////////////////////////////////////////////
#include <genesis.h>

// ASSETS /////////////////////////////////////////////////
#include "gfx.h"
#include "sprite.h"

// CONSTANT VALUES ////////////////////////////////////////
#define SCREEN_WIDTH_TILES     40
#define SCREEEN_HEIGHT_TILES   28

#define SCENARIO_POS_X          0
#define SCENARIO_POS_Y          0

#define SCENARIO_WIDTH_TILES    SCREEN_WIDTH_TILES
#define SCENARIO_HEIGHT_TILES   SCREEEN_HEIGHT_TILES

#define SCENARIO_NUM_TILES      SCENARIO_WIDTH_TILES * SCENARIO_HEIGHT_TILES


///////////////////////////////////////////////////////////
// MAIN
///////////////////////////////////////////////////////////
int main()
{

    // Local data _________________________________________

    // Scenario (planes)
    u16 tilemap_buffer[SCENARIO_NUM_TILES];
    u16 *aplan_tilemap = &tilemap_buffer[0];

    Map *prioritymap = unpackMap(bga_priority_image.map, NULL);
    u16 *shadowmap_tilemap = prioritymap->tilemap;

    u16 numtiles = SCENARIO_NUM_TILES;

    // Sprite stuff
    u16 sprite_x, sprite_y, sprite_movx, sprite_movy;
    Sprite* sprite;

    // Process ____________________________________________

    // Dump BGA tilemap into RAM
    memcpyU16(aplan_tilemap, bga_image.map->tilemap, SCENARIO_NUM_TILES);

    while(numtiles--)
    {
        if(*shadowmap_tilemap)
            *aplan_tilemap |= TILE_ATTR_PRIORITY_MASK;

        aplan_tilemap++;
        shadowmap_tilemap++;
    }

    // Load tileset and tilemap for APLAN
    VDP_loadTileSet(bga_image.tileset, bgb_image.tileset->numTile, DMA);
    VDP_setTileMapDataRectEx(PLAN_A, &tilemap_buffer[0], 0/*u16 basetile*/,
        SCENARIO_POS_X, SCENARIO_POS_Y,
        SCENARIO_WIDTH_TILES, SCENARIO_HEIGHT_TILES, SCENARIO_WIDTH_TILES);

    // Free RAM buffers
    MEM_free(prioritymap);
    MEM_free(aplan_tilemap);

    // Load scenario for BPLAN "as it is"
    VDP_drawImage(PLAN_B, &bgb_image, SCENARIO_POS_X, SCENARIO_POS_Y);

    // Init and load the sprite
    SPR_init(16, 256, 256);
    sprite_x = 0; sprite_y = 0; sprite_movx = 1; sprite_movy = 1;
    sprite = SPR_addSprite(&star_sprite, sprite_x, sprite_y, TILE_ATTR(PAL3, TRUE, FALSE, FALSE));

    // Set the palette taken from the scenario (BLAN image)
    VDP_setPalette(PAL0, (u16*) bgb_image.palette->data);

    // Set the palette from the sprite
    VDP_setPalette(PAL3, (u16*) star_sprite.palette->data);

    // Enable HL/S mode
    VDP_setHilightShadow(1);

   // LOOP
   while(TRUE)
    {

        // Check border collisions (reverse mov)
        if(sprite_x < 0 || sprite_x > 304) sprite_movx *= -1;
        if(sprite_y < 0 || sprite_y > 196) sprite_movy *= -1;

        sprite_x += sprite_movx; sprite_y += sprite_movy;

        SPR_setPosition(sprite, sprite_x, sprite_y);

        SPR_update();

        VDP_waitVSync();
    }

    return 0;
}
Image

CodeBlocks project

Re: RESCOMP and individual nametable entries?

Posted: Wed Mar 06, 2019 4:04 pm
by Chilly Willy
This is one of the hardest things for new devs on old consoles - moving from everything being in ram to (nearly) everything being in rom. The other hard things are the lack of (nearly) infinite processor power and (nearly) infinite ram. I even run into that on Dreamcast programming.

Re: RESCOMP and individual nametable entries?

Posted: Wed Mar 06, 2019 4:51 pm
by realbrucest
Actually I'm more of an "old coder" than a "modern one" :mrgreen: Concerning games and graphic dev I've started doing things for the good and old 13h MSDOS VGA mode. 'Been developing thingies for the genesis for more than five years already, since the first version of SGDK was released, but adding custom routines I needed to it.

I forgot about SGDK because of its limitations (back then) and now (appart from rushig a bit too much before asking :roll: :oops: ) I am trying to make a few things I'm used to make easily ... in the easiest way SGDK can offer. I'm "migrating back" to SGDK trying to keep everything as it is (and it is not being too straigh forward for me).

EDIT: OK, done at last :mrgreen:

Re: RESCOMP and individual nametable entries?

Posted: Thu Mar 07, 2019 10:30 am
by Stef
The VDP_setMap(..) VDP_setMapEx(..) method does use a "basetile" argument, still the map data can "override" it (and internally the VDP_setMapEx(..) method uses VDP_setTileMapDataRectEx(..) :wink: )

Re: RESCOMP and individual nametable entries?

Posted: Thu Mar 07, 2019 10:46 am
by realbrucest
Taking note :wink:

I've just updated the demo including a hl/s coloured sprite.

Edit: new tiny update to the code using compressed maps for BPLAN and the priority map image.

Re: RESCOMP and individual nametable entries?

Posted: Wed Mar 25, 2020 5:03 am
by diegzumillo
Stef wrote:
Wed Dec 26, 2018 4:58 pm
No unfortunately you can't encode priority inside the image so rescomp can decode it.
The way to do is to have 2 images, one for low priority and one for high priority then you combine both images map. You generate a new map out of it by using :

Code: Select all

if (*mapHigh)
 *map = *mapHigh | TILE_ATTR_PRIORITY_MASK;
else
 *map = *mapLow;
mapHigh++;
mapLow++;
map++;
For the palettes, Rescomp is able to handle multi palette images but you should carefully prepare your palettes inside the image.
I am going to have to revive this topic. This is relevant to my latest struggle!

Any chance we can get a dumbed down version of what you're saying here? maybe an extended example? I get the gist but I'm not savy enough to implement it. I don't understand the meaning of some of these variables and those tiledata functions.

mapHigh/Low are tilesets (members of Map, that pointer u16* tileset), right? and each member of these arrays is a set of bits and flags containing things like tile index and priority. The pointer itself is being increased to point to the next member, so we are effectively going through map and stitching maphigh/low.

But, as I said, my blind attempts at implementing this yielded only frustration.

Re: RESCOMP and individual nametable entries?

Posted: Wed Mar 25, 2020 9:17 am
by Stef
Well in fact you have a way to encode priority information into the image but you need to arrange the palette properly.
So you need a 8 bit image (indexed so) where :

Code: Select all

// b0-b3 = pixel data
// b4-b5 = palette index (4 palette max)
// b7 = priority bit
So you can see that bit 7 can be used to store priority information, so basically you need to have your palette arrange like this :
Color 0-15: your low priority colors
Color 128-143: your high priority colors
I admit that it's not an easy to do it, but at least it's possible :oops:
And obviously colors has to be the same, it's just a way to store priority information ;)

Re: RESCOMP and individual nametable entries?

Posted: Wed Mar 25, 2020 3:22 pm
by diegzumillo
In retro dev "not an easy way of doing it" is the norm. SGDK is the one spoiling us with convenience :lol:

Anyway, my first instinct was to immediately try to index the colors in aseprite (pixel editor). But rescomp did not appreciate that "pixel at [56,0] reference a different priority."

EDIT: oops! turns out I had a tile with mixed palette! (I forgot about the transparency part) so this worked! =D maybe it's not super convenient but I can totally work with this.

Thanks for the help!

Re: RESCOMP and individual nametable entries?

Posted: Thu Mar 26, 2020 8:13 am
by vnsbr
diegzumillo wrote:
Wed Mar 25, 2020 3:22 pm
In retro dev "not an easy way of doing it" is the norm. SGDK is the one spoiling us with convenience :lol:

Anyway, my first instinct was to immediately try to index the colors in aseprite (pixel editor). But rescomp did not appreciate that "pixel at [56,0] reference a different priority."

EDIT: oops! turns out I had a tile with mixed palette! (I forgot about the transparency part) so this worked! =D maybe it's not super convenient but I can totally work with this.

Thanks for the help!
Do you have more details how to set priority bit with aseprite?