Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Issue?] Two tilesets, one palette?
#21
(11-03-2022, 04:44 PM)megamarc Wrote: Hi!

Glad you like this new feature :-)

Unfortunately Tiled editor doesn't allow setting custom properties on individual tilemap cells, only on tileset tiles. The only way to set palette bits on a tilemap cell at runtime is using combination of TLN_GetTilemapTile() / TLN_SetTilemapTile(), or the new TLN_GetTilemapTiles() that is more efficient but more dangerous too.
Only specific tilemap editors for consoles allow setting attribute flags directly on tilemap cells, but they're tightly tied to the features and limitations of each console. Tiled is more versatile and open-ended, but lacks this feature.

There is a workaround in Tilengine that is already implemented for "priority" attribute, and could be done for palette index too. The idea is to set the property to specific tiles in the .tsx (tileset) editor. When you set up a tilemap layer with TLN_SetLayerTilemap(), the engine "transfers" priority attribute of tiles on the tileset to tilemap cells. Same could be done with a "palette" attribute. However, this is a hack: priority and palette flags should be applied individually to selected tilemap cells, but with this method they're mass-applied to all tilemap cells with the same graphic (tile id). So you can't have the same graphic used on different parts of the map with different priority or palette on each place.

What do you think about implementing a "palette"property in tileset?

Just for curiosity I'll research a bit about file formats of specific console editors, peraphs I may write loaders for Tilengine in the future

I have an idea : Why not using a custom layer where tile ID defines the palette? Tilengine while loading the TMX can also load this specific layer that contains the ID of palette to use.
Edit : I use this technique for defining collisions with the tilemap.
Reply
#22
Hi,

This kind of proposed functionality should be implemented in the application -game- domain, not inside the engine. It's not a bad idea, but it's kind of a "hack" too, to overcome a limitation of the editor.

However implementing this is easy, this function does the trick. It requires that both layers -the palette indexes and the target layer- have the same size:


Code:
void apply_palette(TLN_Tilemap palette_layer, TLN_Tilemap target_layer)
{
    const int numtiles = TLN_GetTilemapCols(palette_layer) * TLN_GetTilemapRows(palette_layer);
    TLN_Tile srctile = TLN_GetTilemapTiles(palette_layer, 0, 0);
    TLN_Tile dsttile = TLN_GetTilemapTiles(target_layer, 0, 0);
    int c;
    for (c = 0; c < numtiles; c += 1)
    {
        if (srctile->index != 0)
            dsttile->palette = srctile->index - 1;
        srctile += 1;
        dsttile += 1;
    }
}


Take a look at this Sega Megadrive/Genesis editor:

https://allone-works.itch.io/16tile

This one allows to easily set priority and palette to selected tilemap cells. This is what Tiled lacks. It may be cool to load its maps into Tilengine to take advantage of its "console features"
Reply
#23
(11-03-2022, 10:22 PM)megamarc Wrote: Hi,

This kind of proposed functionality should be implemented in the application -game- domain, not inside the engine. It's not a bad idea, but it's kind of a "hack" too, to overcome a limitation of the editor.

However implementing this is easy, this function does the trick. It requires that both layers -the palette indexes and the target layer- have the same size:


Code:
void apply_palette(TLN_Tilemap palette_layer, TLN_Tilemap target_layer)
{
    const int numtiles = TLN_GetTilemapCols(palette_layer) * TLN_GetTilemapRows(palette_layer);
    TLN_Tile srctile = TLN_GetTilemapTiles(palette_layer, 0, 0);
    TLN_Tile dsttile = TLN_GetTilemapTiles(target_layer, 0, 0);
    int c;
    for (c = 0; c < numtiles; c += 1)
    {
        if (srctile->index != 0)
            dsttile->palette = srctile->index - 1;
        srctile += 1;
        dsttile += 1;
    }
}


Take a look at this Sega Megadrive/Genesis editor:

https://allone-works.itch.io/16tile

This one allows to easily set priority and palette to selected tilemap cells. This is what Tiled lacks. It may be cool to load its maps into Tilengine to take advantage of its "console features"

Oh, 16Tile is a pretty nice tool, I already gave it a try in the past! Sadly, it seems this tool isn't open source, but I have good news : the format used by this tool is plain text (it looks like JSON), so you can easily implement a loader into Tilengine since JSON is a standard format.
About your code, wouldn't it hurt the performances with big tilemaps? The loader already does a first loop to load tiles, and you are doing a second loop to set the palettes. But maybe I got something wrong. But in any case, you set up palette data during map loading.

Edit : You also should take a look to LDtk https://ldtk.io/
It is less easy to use than 16Tile, but it's open source, and is also free and also uses JSON. It is also very powerful.
Reply
#24
Hi again!


Having a tool that isn't open source isn't a problem per se -at least for me- as long as it does what is expected to do. The problem is that the 16t format is undocumented. Yes it's a standard json, but several fields have obscure data sources:
  • Layer TYPE can be 0 or 2, but I don't know their meanings,
  • Tilesets have BUFFER and BUFFER_STREAMED keys with base64 encoded data. This data seems to be pixel data as there isn't any reference to external .png. But the actual format and meaning of the encoded data is unknown.
  • There isn't any trace of tilemap layout. Maybe it's mixed inside the encoded base64 buffers.

According to documentation, this tool is designed to be used alongside SGDK devkit, so the author doesn't bother to document its own file format. The tool is cool, but without file format documentation I can't write a proper importer. I'll contact the author to ask for it.

Don't worry for the performance of applying palette flags at runtime, traversing a few thousands of tiles sequentially will take only a few milliseconds even on humble systems.

I already knew ldtk too, it looks cool, but reading its well documented file format, there isn't support for per-tile priority or palette -or custom property-. In this regard it's even more limited than Tiled, only h/v flip flags can be set. This is all you can put in a tile cell in ldtk:

   
Reply
#25
(11-04-2022, 12:32 AM)megamarc Wrote: Hi again!


Having a tool that isn't open source isn't a problem per se -at least for me- as long as it does what is expected to do. The problem is that the 16t format is undocumented. Yes it's a standard json, but several fields have obscure data sources:
  • Layer TYPE can be 0 or 2, but I don't know their meanings,
  • Tilesets have BUFFER and BUFFER_STREAMED keys with base64 encoded data. This data seems to be pixel data as there isn't any reference to external .png. But the actual format and meaning of the encoded data is unknown.
  • There isn't any trace of tilemap layout. Maybe it's mixed inside the encoded base64 buffers.

According to documentation, this tool is designed to be used alongside SGDK devkit, so the author doesn't bother to document its own file format. The tool is cool, but without file format documentation I can't write a proper importer. I'll contact the author to ask for it.

Don't worry for the performance of applying palette flags at runtime, traversing a few thousands of tiles sequentially will take only a few milliseconds even on humble systems.

I already knew ldtk too, it looks cool, but reading its well documented file format, there isn't support for per-tile priority or palette -or custom property-. In this regard it's even more limited than Tiled, only h/v flip flags can be set. This is all you can put in a tile cell in ldtk:

Hi again!
Thanks for the code, it works very well. I can use the same technique for priority, mask and so on. I can store everything in one TMX. It would be even simpler to do it this way.
By the way, I hope you will have an answer from Tile16's author.
Reply
#26
Hi!

I'm glad this is already working for you. At's a good idea indeed: having non-standard attributes in separate layers using tile indexes, and mass-transfer them to the destination tilemap at runtime. I like the approach!

I've searched contact addres for the author of 16Tile, but I can't find any... Just posted a comment in its youtube video release
Reply
#27
(11-04-2022, 03:44 AM)megamarc Wrote: Hi!

I'm glad this is already working for you. At's a good idea indeed: having non-standard attributes in separate layers using tile indexes, and mass-transfer them to the destination tilemap at runtime. I like the approach!

I've searched contact addres for the author of 16Tile, but I can't find any... Just posted a comment in its youtube video release

I'm glad you like my approach! The author of 16Tile is also on the SGDK Discord community, I will contact him too.
Reply
#28
Okay so I'm currently talking with the devlopper of 16Tile. Is there some fields in the JSON you are interested in?
Also, note this tool can only have one tileset per layer.
Reply
#29
Hi!
Glad to know you're in contact with the developer.
The fields I'm interested on are those encoded in base64:
  • Tilemap.Grid
  • Tileset.Buffer
  • Tileset.Buffer_Streamed
Yes this editor only supports one tileset per layer, because the Sega Genesis doesn't have concept of different tilesets, just one region of VRAM where graphic tiles are stored
Reply
#30
(11-07-2022, 07:57 AM)megamarc Wrote: Hi!
Glad to know you're in contact with the developer.
The fields I'm interested on are those encoded in base64:
  • Tilemap.Grid
  • Tileset.Buffer
  • Tileset.Buffer_Streamed
Yes this editor only supports one tileset per layer, because the Sega Genesis doesn't have concept of different tilesets, just one region of VRAM where graphic tiles are stored

Hi
According to the dev, here are some informations :
GRID = contains the grid information:
--- GRID_SIZE = the size of each tile in the grid (8, 16, 32 or 64);
--- GRID_WIDTH = the WIDTH of the grid (in tiles);
--- GRID_HEIGHT = the HEIGHT of the grid (in tiles);
--- WIDTH = the WIDTH of the grid (in pixels);
--- HEIGHT = the HEIGHT of the grid (in pixels);
BUFFER = contains the graphical data for the tileset (stores each LINE sequentialy);
--- Each data in the buffer represents the color index for that pixel (ranges from 0 to 15). This BUFFER field stores all the pixels from each line in order.
BUFFER_STREAMED = contains the graphical data for the tileset (stores each TILE sequentialy);
--- Each data in the buffer represents the color index for that pixel (ranges from 0 to 15). This BUFFER_STREAMED field stores all the pixels from each tile in order.

you will have to convert base64 strings into a regular string / array of bytes and then decompress them with zlib. the GRID base64 contains data about tile indexes, palette, flipping etc
Here is a reference he sent to me :
https://forum.nhl94.com/index.php?/topic...-sega-gene
[Image: image.png]sis/

Here is another link I found :
https://segaretro.org/Plane
Reply


Forum Jump:


Users browsing this thread: 9 Guest(s)