I'm working on a low level dkc editor... Does anybody know how to go from snes tile to image in c#? I already have an object mover. I am not interested in cameras, bananas, etc. Right now I have it so levels will break if you aren't careful. This doesn't properly order objects. This is essentially a glorified hex editor.
Tiles are either 2bpp, 4bpp or 8bpp (bpp = bits per plane). For 2bpp you basically have 8 pairs of bytes, so 16 bytes in all. The bits in the 1st byte would be the low bit of the resulting shade for each pixel in the top row of the resulting tile, then the 2nd byte would contain the second lowest bit. 3rd and 4th bytes would be the same for the second row, and so on. For 2bpp, you only have that one set of 16 bytes. For 4bpp, you have another 16 bytes so 32 in all, and for 8bpp you have 4x16=64.
NES does a single bit of the resulting shade in 8 bytes, then the next bit in the following 8 bytes which is a lot more natural. The SNES does it in pairs of bits and bytes because VRAM accesses are always in words. GB also does it the SNES way, but I'm not clear on the details.
Bitplanes are quite confusing and not at all easy to grasp. Some documents and explanations are exceptionally bad, which doesn't help. It finally clicked for me when I saw a diagram in a fairly old document titled "SNES Graphics Information" by a fellow called Qwertie.
Anyway, once you have the shade for a particular pixel in that 8x8 tile, you get the real colour by using the value as a lookup in the associated palette.
In some circumstances the colour isn't known, so some programs (e.g. Tile viewers) will show the shade as greyscale rather than guess a colour.
Here's a small C program that converts a few predefined tiles to greyscale images:
The relevant part is the 'snes2shade' function. It's a bit tricky to look at like most image processing functions.
The tile data is passed to the function. This will either be 2bpp (16 bytes), 4bpp (32 bytes) or 8bpp (64 bytes). The "depth" variable indicates which, either 2, 4 or 8. A 64-byte buffer called "img" to store the output is also passed. 64 = 8x8. Again, if you wanted to apply a specific palette, you would use the values here as a lookup.
The calculations... We have "i" to indicate rows and "j" for columns. These apply to both the input and the output. The "k" variable does a few things relating to depth. First we extract the relevant bit from the tile data, then shift it and place it in the image.
It's not the easiest thing to explain, but maybe some of it is helpful.
But yes that is quite confusing. At first I thought that grid was referring to rows and columns, but it's referring to planes. It was enough to make me think I had made a serious miscalculation, but no it does match up somehow.
Definitely not the worst I've seen though. There is one particularly horrible bitplane document that lurks in my memory. It's almost certainly cursed, because anyone who looks at it will instantly and completely forget how any of this works, so you would have to relearn all this from scratch. It happened to me once. The best I can do is warn you about it, but if you come across it it's already too late. Just don't blindly google bitplane documentation if you can help it.
The Qwertie document I mentioned has a nice little diagram. The SNES word pairing makes it a tiny bit trickier than it could be, but it's not too bad.
The kids these days are into YouTubes and things like that, so maybe there is a really concise explanation out there that we don't know about.
Thanks again! I'm realizing more and more I should just keep it low-level It works, somewhat, there's just a lot more features to add. Yes, it is still low-level Glorified hex editor.
Ahem, turns out there was at least one small bug in that code preventing it from working. I think I made a small change before I posted it that looked as though it wouldn't make any difference but it actually did. I could have sworn it was working at that point, but oh well. Should be fine now, maybe.
It would have made sense to test it against some known good data instead of making sure it matched my own made up data, but oh well. Guessing is more fun anyway.
I agree! Hey, if it runs fine in your head, what's the issue?
Also, I never said this yet, but a very special thank you to Simion32. I couldn't have done this without your object list! That thing has helped me SO much. Sometimes I forget that it is thanks to you I started down this path!