Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: nemo on June 07, 2010, 12:43:03 pm

Title: Tilemapping efficiently
Post by: nemo on June 07, 2010, 12:43:03 pm
does anyone know what routine is best for tilemapping? i only need 8 or so different tiles. builderboy's method seems pretty good, but i was wondering if there's a more efficient way to manage a tilemap? also, size plays a factor. i'd rather not use
deltalist(_tilemap data_)->GDB1
as that takes up a lot of size.
Title: Re: Tilemapping efficiently
Post by: DJ Omnimaga on June 07, 2010, 01:43:40 pm
Instead of doing deltalist(1,2,8,11,12,11,255,255,1) you would do [0102080B0C0BFFFF01]
Title: Re: Tilemapping efficiently
Post by: nemo on June 07, 2010, 01:50:56 pm
thank you
Title: Re: Tilemapping efficiently
Post by: Quigibo on June 07, 2010, 01:53:23 pm
Don't forget, the executable is the same size regardless, and you can archive your source before compiling to save space.

If you're using half byte tiles though, hex is more convenient since every digit 0-F are individual tiles.
Title: Re: Tilemapping efficiently
Post by: DJ Omnimaga on June 07, 2010, 01:56:07 pm
True, you can fit about 100 12x8 maps in 4200 bytes. You need some sort of special routine for collision detection and displaying the tilemap, though (which I pretty much failed on x.x). I would keep half bytes for when you are very experienced with Axe, personally.
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 02:46:12 pm
If you wanted the compression of half byte, but still wanted the ease of use, you could store your data as half byte, and then decompress it into single byte for ease of use.  (Even i dont use half byte in portal because its so much of a hassle x.x)
Title: Re: Tilemapping efficiently
Post by: jnesselr on June 07, 2010, 02:56:19 pm
I usually store the data as half-bytes, and then decompress it as two individual bytes for use.  Not that hard to do if you understand the math involved in mod and then dividing by 16 for the two parts.

Any time I have problems with a concept in another base, I always try to think of it in base 10.  Say I had the number 98.  If I were to do 98 mod 10, it would give me 8.  If I were to do 98/10, and because Axe doesn't keep decimals, I get 9.  Those are the two parts.  If axe supported base 37, we could do up to 37 different tiles with 0-9, a-z, and theta.  You would just mod 37 and store that, then divide by 37, and store that.

Can we get axe to support base 37?
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 02:59:48 pm
How would you store the data tho? Since 37 isnt a full byte (255) you would have to either do some very tricky modular arithmatic to even get the numbers out of memory, or just store them in a byte, which kind of defeats the purpose of using 37 in the first place.
Title: Re: Tilemapping efficiently
Post by: jnesselr on June 07, 2010, 03:17:24 pm
True, I guess.  I didn't think about it all being in bytes and bits.  I guess you could do 32, and have it be 5 bits.  That would mean tiles would have to be 8 chars long for 5 bits a piece = 40 bits, or 5 bytes.  To do a row of twelve...  Yeah, that won't work.  You would have an extra 4 bits.  I guess you could use that for something interesting.  Actually, if you have another byte at the end of that, you could have twelve bits extra.  Possibly useful for collision detection.

So if all of my math adds up, thats 9 bytes.  Can anyone confirm my math?  The programming code to do this would be confusing, though.  VERY confusing.  You would basically have to have a counter location for the bits.  This could possibly be slow for RPGs though.  Still, for a game with many tiles, and not smooth scrolling, I believe it's possible.  Not insanely fast, but possible.  You would just have to figure out how to isolate a single bit, so it's possible.  It is not, however, possible for me to stop using the word 'possible'.

In the meantime, we could just convert the data by hand into bytes.
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 03:22:51 pm
Well no matter what your storage is, you can then decompress it into a matrix buffer so that you are working with simple bytes and not this weird byte thingies.  PortalX uses RLE where up to 16 tiles can be stored in a single byte, and i find that it offers much more compression that tile squeezing.  However its not random access so it has to be decompressed at the start of each level, and stored in byte form.
Title: Re: Tilemapping efficiently
Post by: nemo on June 07, 2010, 03:30:22 pm
Quote
Say I had the number 98.  If I were to do 98 mod 10, it would give me 8.  If I were to do 98/10, and because Axe doesn't keep decimals, I get 9.  Those are the two parts.
this makes an astounding amount of sense to me. NOW i get why in the tutorial for tile-mapping you had to ^16 and /16. thank you! however, in my game i think i'll work on the physics of it and then when quigibo adds tile-mapping support i'll work on the maps. i'm still messing around with this concept however. this thread has been helpful
Title: Re: Tilemapping efficiently
Post by: jnesselr on June 07, 2010, 03:31:36 pm
That could be done, but in this case, it loses the biggest advantage which is more tiles.  If you have to de-compress it, this doubly defeats your program, because instead of saving those bytes, you have to make a large enough buffer inside your program in order to contain all of the bytes.  Unless you absolutely needed those 16 extra tiles, it doesn't seem to be worth it.

Of course, has anyone thought of this?:
UDLRbyte, where:
U: Up
D: Down
L: Left
R: Right
byte: ironically, byte is 4 chars long, and nibble is 6.  anyway, this refers to the 4 bit reference for the tile.
This way of storing provides an interesting advantage.  There is no collision detection.  You simply have to look at the reference here.  If there is a 0 for up, and a 1 for down, then that mean you can jump over it heading from the top direction, but not from the bottom.  Kinda like in pokemon.  You could also store other data there if you wanted to.
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 03:41:17 pm
That could be done, but in this case, it loses the biggest advantage which is more tiles.  If you have to de-compress it, this doubly defeats your program, because instead of saving those bytes, you have to make a large enough buffer inside your program in order to contain all of the bytes.  Unless you absolutely needed those 16 extra tiles, it doesn't seem to be worth it.

True, the disadvantage to decompressing means that you have to have 2 copies of the map, one thats in your program and one that is in memory.  But say you used L1 to store your map buffer, you could have over 700 tiles in your map matrix with no detriment to your program size, it only includes the compressed data, which is significantly smaller.
Title: Re: Tilemapping efficiently
Post by: jnesselr on June 07, 2010, 03:51:00 pm
Quote
Say I had the number 98.  If I were to do 98 mod 10, it would give me 8.  If I were to do 98/10, and because Axe doesn't keep decimals, I get 9.  Those are the two parts.
this makes an astounding amount of sense to me. NOW i get why in the tutorial for tile-mapping you had to ^16 and /16. thank you! however, in my game i think i'll work on the physics of it and then when quigibo adds tile-mapping support i'll work on the maps. i'm still messing around with this concept however. this thread has been helpful
Very glad we could help.

Yes, you could decompress it into memory.  That gives you 3 bits extra for data or something.  What could be stored in there?  The first two bits could be configurations of blocked sides.  Like:
00 - You can cross from anywhere.
01 - You can cross from the top
10 - You can cross from the bottom
11 - You can't cross.

You could also do a sort of macro lookup.  There only 8 possibilities with 3 bits, though.  Maybe having the previous idea for borders, and have a 0 or 1 to tell if there is a macro for this tile.  You would have to know what tile location, or where it would end up being in memory though.

What do you think?
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 03:54:26 pm
That gives you 3 bits extra for data or something.

Hmmm? Now im confused, where are these 4 bits coming from?
Title: Re: Tilemapping efficiently
Post by: jnesselr on June 07, 2010, 03:58:53 pm
Well, if you use the 5 bit method, when you decompress it into individual bytes for easer, faster reading, you have 3 bits left over.  They would be tile specific.  For example, you can walk on ground, but not on rock.
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 04:01:47 pm
Ah i see.  That would work :) So you would have a byte per tile, and instead of having 256 different tiles, you would have 32 different tiles with 8 different characteristics.
Title: Re: Tilemapping efficiently
Post by: jnesselr on June 07, 2010, 04:05:58 pm
Yes, which saves space in your actual program.  Except, I want to write a computer compiler for axe.  Sort of like a higher level programming language to axe source code.  I'm thinking that there will be a way to know what byte your tile is in when decompressed, so you could have a subroutine, that if the tile had a macro, would call the macro from the subroutine.  Just an idea, though.
Title: Re: Tilemapping efficiently
Post by: TIfanx1999 on June 07, 2010, 04:11:16 pm
Well no matter what your storage is, you can then decompress it into a matrix buffer so that you are working with simple bytes and not this weird byte thingies.  PortalX uses RLE where up to 16 tiles can be stored in a single byte, and i find that it offers much more compression that tile squeezing.  However its not random access so it has to be decompressed at the start of each level, and stored in byte form.
I'm curious as to how you could fit 16 tiles in one byte, that sounds like some ridonkulous compression magic. Also, what size tiles are you using?
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 04:19:14 pm
Yeah that might be really cool :) I think i am going to stick with my RLE though, as it provides a lot more compression, even if it does only allow 16 tiles (plenty for what i need)

And as for RLE, its a maximum of 16 tiles, it could be as low as one.  The way it works is this, say you have a map

0000000
0-----0
0-----0
0000000


which looks like this in memory

00000000-----00---00000000

A pretty simple map with 28 tiles, but there is a lot of repetition, so lets compress it into this

805-205-80

which might look like gibberish, but here is what it means, first take the first 2 numbers, 8 and 0.  What it means is that there are 8 of the 0 character at the beginning of the tilemap.  The second part looks like 5-, which says that it is followed by 5 of the - characters.  You do this for the entire map and you end up with some good compression, depending on the map design of course.  I use 1 byte per grouping, which means i have 1 byte to say what the tile type is, and what the length is.  I use 1 half of the byte for each, so i can have a maximum length of 16 tiles, with a max of 16 different tiles.  You can push these values around a bit if you have less or more tiles you want to work with, but it gets worse and worse compression the shorter you make the length.

So at the worst, this compression gives a single byte per tile
Title: Re: Tilemapping efficiently
Post by: jsj795 on June 07, 2010, 04:56:55 pm
How fast is the decompression tho? I don't think I can use RLE for mine, since mine will be more than 16 tiles, but graphmastur's seems interesting, because I need different tile sprites for different orientation and property. Except it seems pretty hard to implement :P
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 05:00:07 pm
Decompression is very fast in Axe with the help of the Fill() command, and in Basic it can be done while drawing the map.  Decompression for Graphmastur's would also be speedy, although maybe less so since you would be doing division and modular arithmatic on every tile.  In Axe it doesn't matter that much i wouldn't think, the differences would be very small
Title: Re: Tilemapping efficiently
Post by: Quigibo on June 07, 2010, 06:01:27 pm
RLE is great for decompressing.  BUT, if you have a very large tile map, say its 60x40 for example that needs to be scrolled through, that's 2400 bytes.  You can use half byte compression to only take up 1200 bytes and maybe half-byte RLE would be 500 bytes in this example.  The fact is, the map is too large to decompress anywhere in RAM unless you tack on extra size to the program.  So you're better off reading directly from the map in the program data.  When you read off that map, it needs to be fast so RLE isn't going to be possible.
Title: Re: Tilemapping efficiently
Post by: jsj795 on June 07, 2010, 06:15:38 pm
I guess RLE is made for Portal X since it doesn't require scrolling :)
Title: Re: Tilemapping efficiently
Post by: Builderboy on June 07, 2010, 06:16:42 pm
Exactly ^^ it fits all of my needs perfectly
Title: Re: Tilemapping efficiently
Post by: DJ Omnimaga on June 08, 2010, 12:45:26 am
Yeah, personally I always felt compression is easier for when you do not need scrolling (especially smooth scrolling). It is possible to have smooth scrolling in an half-byte compressed tilemap, I am certain, but I have yet to figure out how to do it.