Re: How to show graphics on the screen?
Posted: Tue Apr 30, 2019 4:23 pm
There is too much content above for me to follow at this point, sorry. So I'm going to just brain dump.
I told you there were probably typos/mistakes. Good job on finding them. I don't like copy-pasting so the mistakes make sense.
It looks like your tile map and CHR data is correct -- which is great, those tend to be the most annoying -- but the palette may be wonky. Transparency (colour #0) may be part of the problem too, hard to say.
There is no universal palette format. So something named "palette" or .pal means literally nothing. Every program seems to use its own format/model/approach. YY-CHR I believe tends to use an RGB or RGBA format for its palettes, *which are not compatible with the SNES*.
What's important to know is the format of the Super Nintendo CGRAM (palette) data, as its well-understood and well-documented. Each palette entry is 2 bytes (16-bits), with the MSB (top bit / bit 15) unused. The format is 0bbbbbgggggrrrrr, where b/g/r are the intensities of blue/green/red. I explain the format better, with examples, here (see lower half of my post). These are stored in memory/ROM in 65xxx little endian, which means the low byte comes first, followed by the high byte. SuperFamiconv's palette output file are in CGRAM format, which is why you can DMA them directly into the SNES's CGRAM. It's convenient, good, and the right way to do it.
The hex editor you're using is weird. It looks like its batching up the bytes in 4-byte chunks, almost like 32-bit numbers, which means it may be messing with the endian? I'm going to give it the benefit of the doubt and ASSUME it's not. Decoding your colours seems to imply the following, split into their separate B/G/R and MSB sections with commas:
Colour #0 = $7BDE = %0,11110,11110,11110 = almost white
Colour #1 = $0000 = %0,00000,00000,00000 = black
Colour #2 = $0C63 = %0,00011,00011,00011 = a kind of dark grey
Colour #3 = $14A5 = %0,00101,00101,00101 = another shade of dark grey (lighter than colour #2)
And so on... I can see where the differences start though.
Are you 100% certain your palette in each PNG is 100% identical? Placement of colours in the indices, and everything? It see some variance here, but this might just be SuperFamiconv optimising-out unused colours:
You need to make these use the same palette universally. Same colour values, same indices, everything. 100% identical palettes/indices/transparency colour index, everything. I believe that will relieve your problem. If it doesn't, or you're 100% certain the palettes are identical in every way between the two PNGs, then this might just be SuperFamiconv saying "I detected N colours used", in which case, read on:
You might need to use SuperFamiconv's --no-remap flag, which keeps the palette consistent/doesn't remap things. However, to use this flag, you can't just call superfamiconv.exe in one shot any more, you have to use each subcommand individually, and in a specific order. I don't know why Optiroc did it this way, but whatever. So now you have to do a lot of commands to get what was previously done in just two:
Old way:
New way (so you can use additional flags) -- I sure hope I got these arguments right:
You can see here what I said above: I'm assuming frame0 and frame1 have the exact same palette (indices, everything).
If this doesn't fix your problem, then please say so. I have a lot more to say about this, including some bugs I found in my animation routine (do not write to $212c outside of NMI!), but this post is getting stupidly long already. I've saved what I've written to a text file, however.
Other comments in passing:
I forget if I mentioned it in the thread, but YY-CHR is not a particularly "good" tool despite its history and socially proliferated belief that it is. Do not even for one second believe that just because a file is named .pal or is called "a palette" that there is some universal standard to this -- there isn't. YY-CHR gives the impression of being a good tool, but is generally "meh". IMO, it's more slated towards NES type work, but it still can't let you manage tilemaps/nametable data, which is very important (esp. in this situation). SNES graphics are likewise not generally compatible with NES graphics, including 2bpp modes. That's just how it is.
Sadly there is not a good graphics editor for SNES in 2019. We had some DOS tools back in the early 90s that did this, but they don't function today. The complication is that the SNES has multiple graphics modes that use different formats of data due to 2pp vs. 4bpp vs. 8bpp vs. mode 7 etc.. Your best bet is to stick with indexed colour PNG as described and use SuperFamiconv.
Please do not use SNES9x Geiger's debugger. This program is flaky and a mess and is unmaintained. Please use bsnes-plus or Mesen-S, both of which are actively maintained. Both emulators/debuggers can show you what the palette looks like in CGRAM, plus give you a hex editor to examine things in real-time. Geiger's debugger is from a time where it was literally all we had available, and we have much better and more user-friendly tools now.
You need to ensure that, in the PNGs, you're:
1. Using indexed PNGs, not RGBA (RGB + alpha) PNGs -- you're using indexed (I can see from the output) -- though SuperFamiconv has support for RGBA, it's apparently wonky/broken in 0.3.1 but fixed in master (see below)
2. Using colour index #0 (i.e. the very first colour in the palette) as the transparency colour -- alpha has no purpose here
3. That you have the PNG configuration set so that colour index #0 is the transparency colour. Just using colour index #0 is not enough, because in PNG (much like GIF) you can say "colour index #xxx is the transparency colour". Make sure all of this is set to use colour index #0.
4. That the pixel at coordinates 0,0 in the picture happens to be the transparency colour. There is a way to override this using --color-zero except that the usage documentation is extremely poor here; this argument takes a value (despite usage docs saying otherwise), and the value is not explained/documented. Picking something it cannot parse results in the program locking up for several seconds then crashing. I think it might be --color-zero #xxxxxx in RGB format, but I'm not sure. I haven't figured this one out yet.
I should note I have used SuperFamiconv with success very recently (2 weeks ago), so I know the program works. However, it's way overdue for a release (GitHub commits indicate it's up to 0.5.x but the last binary release is 0.3.x, and I do see transparency-related bugfixes that have been implemented since. I wish Optiroc would release new binaries already, it's been over a year.
I told you there were probably typos/mistakes. Good job on finding them. I don't like copy-pasting so the mistakes make sense.
It looks like your tile map and CHR data is correct -- which is great, those tend to be the most annoying -- but the palette may be wonky. Transparency (colour #0) may be part of the problem too, hard to say.
There is no universal palette format. So something named "palette" or .pal means literally nothing. Every program seems to use its own format/model/approach. YY-CHR I believe tends to use an RGB or RGBA format for its palettes, *which are not compatible with the SNES*.
What's important to know is the format of the Super Nintendo CGRAM (palette) data, as its well-understood and well-documented. Each palette entry is 2 bytes (16-bits), with the MSB (top bit / bit 15) unused. The format is 0bbbbbgggggrrrrr, where b/g/r are the intensities of blue/green/red. I explain the format better, with examples, here (see lower half of my post). These are stored in memory/ROM in 65xxx little endian, which means the low byte comes first, followed by the high byte. SuperFamiconv's palette output file are in CGRAM format, which is why you can DMA them directly into the SNES's CGRAM. It's convenient, good, and the right way to do it.
The hex editor you're using is weird. It looks like its batching up the bytes in 4-byte chunks, almost like 32-bit numbers, which means it may be messing with the endian? I'm going to give it the benefit of the doubt and ASSUME it's not. Decoding your colours seems to imply the following, split into their separate B/G/R and MSB sections with commas:
Colour #0 = $7BDE = %0,11110,11110,11110 = almost white
Colour #1 = $0000 = %0,00000,00000,00000 = black
Colour #2 = $0C63 = %0,00011,00011,00011 = a kind of dark grey
Colour #3 = $14A5 = %0,00101,00101,00101 = another shade of dark grey (lighter than colour #2)
And so on... I can see where the differences start though.
Are you 100% certain your palette in each PNG is 100% identical? Placement of colours in the indices, and everything? It see some variance here, but this might just be SuperFamiconv optimising-out unused colours:
Code: Select all
(base) graphics $ superfamiconv -p palette.pal -i frame0.png -t frame0.chr -m frame0.map -v
...
Generated palette with [16,6] colors, 22 total
...
(base) graphics $ superfamiconv -i frame1.png -t frame1.chr -m frame1.map -v
...
Generated palette with [16,9] colors, 25 total
...
You might need to use SuperFamiconv's --no-remap flag, which keeps the palette consistent/doesn't remap things. However, to use this flag, you can't just call superfamiconv.exe in one shot any more, you have to use each subcommand individually, and in a specific order. I don't know why Optiroc did it this way, but whatever. So now you have to do a lot of commands to get what was previously done in just two:
Old way:
Code: Select all
superfamiconv -B 4 -i frame0.png -p palette.bin -t frame0.chr -t frame0.map
superfamiconv -B 4 -i frame1.png -t frame1.chr -t frame1.map
Code: Select all
superfamiconv palette -i frame0.png -d palette.bin --no-remap
superfamiconv tiles -i frame0.png -p palette.bin -d frame0.chr -B 4 --no-remap
superfamiconv map -i frame0.png -p palette.bin -t frame0.chr -d frame0.map -B 4
superfamiconv tiles -i frame1.png -p palette.bin -d frame1.chr -B 4 --no-remap
superfamiconv map -i frame1.png -p palette.bin -t frame1.chr -d frame1.map -B 4
If this doesn't fix your problem, then please say so. I have a lot more to say about this, including some bugs I found in my animation routine (do not write to $212c outside of NMI!), but this post is getting stupidly long already. I've saved what I've written to a text file, however.
Other comments in passing:
I forget if I mentioned it in the thread, but YY-CHR is not a particularly "good" tool despite its history and socially proliferated belief that it is. Do not even for one second believe that just because a file is named .pal or is called "a palette" that there is some universal standard to this -- there isn't. YY-CHR gives the impression of being a good tool, but is generally "meh". IMO, it's more slated towards NES type work, but it still can't let you manage tilemaps/nametable data, which is very important (esp. in this situation). SNES graphics are likewise not generally compatible with NES graphics, including 2bpp modes. That's just how it is.
Sadly there is not a good graphics editor for SNES in 2019. We had some DOS tools back in the early 90s that did this, but they don't function today. The complication is that the SNES has multiple graphics modes that use different formats of data due to 2pp vs. 4bpp vs. 8bpp vs. mode 7 etc.. Your best bet is to stick with indexed colour PNG as described and use SuperFamiconv.
Please do not use SNES9x Geiger's debugger. This program is flaky and a mess and is unmaintained. Please use bsnes-plus or Mesen-S, both of which are actively maintained. Both emulators/debuggers can show you what the palette looks like in CGRAM, plus give you a hex editor to examine things in real-time. Geiger's debugger is from a time where it was literally all we had available, and we have much better and more user-friendly tools now.
You need to ensure that, in the PNGs, you're:
1. Using indexed PNGs, not RGBA (RGB + alpha) PNGs -- you're using indexed (I can see from the output) -- though SuperFamiconv has support for RGBA, it's apparently wonky/broken in 0.3.1 but fixed in master (see below)
2. Using colour index #0 (i.e. the very first colour in the palette) as the transparency colour -- alpha has no purpose here
3. That you have the PNG configuration set so that colour index #0 is the transparency colour. Just using colour index #0 is not enough, because in PNG (much like GIF) you can say "colour index #xxx is the transparency colour". Make sure all of this is set to use colour index #0.
4. That the pixel at coordinates 0,0 in the picture happens to be the transparency colour. There is a way to override this using --color-zero except that the usage documentation is extremely poor here; this argument takes a value (despite usage docs saying otherwise), and the value is not explained/documented. Picking something it cannot parse results in the program locking up for several seconds then crashing. I think it might be --color-zero #xxxxxx in RGB format, but I'm not sure. I haven't figured this one out yet.
I should note I have used SuperFamiconv with success very recently (2 weeks ago), so I know the program works. However, it's way overdue for a release (GitHub commits indicate it's up to 0.5.x but the last binary release is 0.3.x, and I do see transparency-related bugfixes that have been implemented since. I wish Optiroc would release new binaries already, it's been over a year.