High color bitmap on the SNES

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
93143
Posts: 1225
Joined: Fri Jul 04, 2014 9:31 pm

Re: High color bitmap on the SNES

Post by 93143 » Sun Jul 06, 2014 4:48 pm

Stef wrote:Nice done, the image looks really nice !
Thanks!
Actually you used the "classical" scanline palette reprogramming but maybe at the maximum capabilities for the SNES.
I kinda suspected something like this had been attempted before, and last night I stumbled across a discussion of the Overdrive demo in which it became evident that it was doing something similar...

But my demo wasn't at max capability. This afternoon I changed the preprocessing algorithm, from only checking the earliest scanline with a stale colour to using a two-constant quality weighting system on all scanlines with stale colours. (This boosted the execution time from 3-4 seconds to 30-40 seconds...) The result is attached - the first version had 337 colours; this one has 417. And it's still only using about 34% of the available HDMA bandwidth. I guess it's just a stubborn picture; the success of the HDMA scheduling seems to depend to a significant degree on the parameters used in the image quantizer...
tepples wrote:So it's more like the 3200-color mode of DreamGrafix for Apple IIGS.
I... guess so, yeah. I'd never seen that before.
Mode 3 gives you a 256-color BG1 and a 16-color BG2, and 256-color layers can be set to "direct color" (a constant BBGGGRRR palette). This "direct color" alone nearly equals anything that can be done with the Genesis. But then you can do color addition between a direct color layer and a 16-color layer with a BBGR palette. Or did we already rule that out pages ago?
No, it was mentioned (by you, as a matter of fact), and AFAICT it should work. The problem is that it overloads the VRAM, so you have to letterbox it a bit.
Attachments
hcolor2.smc
(128 KiB) Downloaded 203 times

Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: High color bitmap on the SNES

Post by Sik » Sun Jul 06, 2014 5:03 pm

tepples wrote:Could you do HAM (hold and modify) by DMAing to COLDATA ($2132)?
That's what the SNES counterpart of the original method would be, pretty much.

There's only one thing I'm not sure about which is why I started this thread in the first place. Writes are byte-wide, not word-wide (unlike in the Mega Drive). This means that transferring a color takes up two writes. So here's the question: does the first byte get latched until the second is written, or do bytes get written immediately? Because if the latter, the method won't work (every other column would have an invalid color).

EDIT: also that's not what HAM does (HAM basically just takes the previous pixel and replaces one of the RGB components to get the new pixel), but eh, you get the idea.

tepples
Posts: 22049
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: High color bitmap on the SNES

Post by tepples » Sun Jul 06, 2014 5:19 pm

Sik wrote:also that's not what HAM does (HAM basically just takes the previous pixel and replaces one of the RGB components to get the new pixel), but eh, you get the idea.
According to wiki.superfamicom.org, COLDATA writes transfer 3 bits of "which components to overwrite" and 5 bytes of value. That looked very HAMmy to me.

Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: High color bitmap on the SNES

Post by Sik » Sun Jul 06, 2014 6:39 pm

I don't have the SNES documents with me right now, I just assumed you meant DMAing to the CG memory register (which is literally "copy this word to CG RAM"). I'm not aware of any other method to write to it =S

93143
Posts: 1225
Joined: Fri Jul 04, 2014 9:31 pm

Re: High color bitmap on the SNES

Post by 93143 » Sun Jul 06, 2014 6:44 pm

No, COLDATA is separate from CGRAM. It's the subscreen background colour. Writing an arbitrary colour to it takes six pixels (assuming standard DMA at 8 cycles per byte), and intermediate values would be displayed - assuming writing to it during display takes immediate effect. Grayscale or monochrome could be done with two-pixel granularity...

Isn't the CPU (and by extension DMA) halted for 40 cycles in the middle of every scanline? That wouldn't look very nice...

...

I do kinda like the mosaic idea combined with colour math, if you really want full-screen direct colour and don't mind horizontally doubled pixels. It seems like it should work, though the underlying palette would only be 12-bit...

Unfortunately it still wouldn't be the functional equivalent of the MD version, since a single frame would exceed the available DMA bandwidth, whereas the MD version by definition does not. And since a full screen of this would take up more than half the VRAM, paging would be impossible without tearing...

User avatar
feos
Posts: 107
Joined: Tue Apr 19, 2011 11:26 am
Location: RU
Contact:

Re: High color bitmap on the SNES

Post by feos » Mon Aug 31, 2015 1:08 pm

Is it possible to send separate pixels to SNES screen, or one can only feed it tiles that need to be prepared beforehand? If the latter, how do you guys convert image parts to SNES tiles (and store them)? I'd be interested in seeing the source code of both hcolor demos.

93143
Posts: 1225
Joined: Fri Jul 04, 2014 9:31 pm

Re: High color bitmap on the SNES

Post by 93143 » Wed Sep 02, 2015 11:58 pm

feos wrote:Is it possible to send separate pixels to SNES screen, or one can only feed it tiles that need to be prepared beforehand?
Normally, aside from the very limited graphical capabilities afforded by the backdrop colours and main/sub screen functionality in combination with HDMA and window masking, you pretty much have to use tiles. You can render tiles on the S-CPU, but it's slow, and to the best of our knowledge you can only transfer them to VRAM during VBlank or forced blank.

It may be possible to continuously modify the subscreen backdrop colour, but it can only take one 5-bit value at a time and apply it to any combination of the three colour channels, so even DMA wouldn't be able to do arbitrary colour changes faster than two pixels per colour channel, which would look weird. Plus DMA doesn't work during DRAM refresh in the middle of every scanline, so you'd have 10 pixels of no changes at all unless you masked it with tiles (you could perhaps modify the relevant palette entries during HBlank).

Also, byuu recently informed me that he's "never once seen a CGRAM write fail", and that if the PPU is accessing it too the worst that can happen is that the colour will go to the wrong entry. This was in the context of HBlank writes like I use in my hcolor demos, but the generality of his wording suggests to me that FantomBitmap might just be possible on the SNES after all, though it would have to use quadruple-wide pixels instead of double-wide because of the 8-bit DMA. I plan to try this, but I'm under a lot of pressure right now so I can't really hobby much.
If the latter, how do you guys convert image parts to SNES tiles (and store them)?
I use custom Matlab utilities to generate tiles, tilemaps, palettes, and HDMA tables from Windows bitmap data, since I'm good at Matlab and happen to have a copy (it's not cheap). Unfortunately Octave (free Matlab) doesn't run my scripts properly...

Storage is easy. Once I have the binary data, I just include it in the ROM via the .incbin directive. Not sure what you're asking here...
I'd be interested in seeing the source code of both hcolor demos.
Do you mean the Matlab data preparation script, or just the SNES ASM? I can do both, but I'd need to happen across a bit of free time to prepare the SNES stuff as it is a very ugly hack of someone else's slideshow and thus contains a lot of superfluous code. The actual method is very simple, and all that extra infrastructure would only confuse the issue.

User avatar
feos
Posts: 107
Joined: Tue Apr 19, 2011 11:26 am
Location: RU
Contact:

Re: High color bitmap on the SNES

Post by feos » Thu Sep 03, 2015 6:26 am

Thanks for the answer, my goal is to show just anything on the screen, it can even consist of only black and white, if it'd be easy to implement. And being easy is actually critical for me, since I've never seen SNES code, only NES and Genesis.

So how much freedom does backdrop layer allow? Can it change colors every pixel? Color depth is not an issue at all, as I mentioned. If it only allows going in blocks of the one color, it's still okay for me. If only in lines, then no.

SNES ASM source is enough. Given it had some comments and other things that'd simplify understanding.

User avatar
Khaz
Posts: 311
Joined: Thu Dec 25, 2014 10:26 pm
Location: Canada

Re: High color bitmap on the SNES

Post by Khaz » Thu Sep 03, 2015 6:58 am

Oh, hiya feos! I missed this thread back in the day and I haven't fully caught up on it, but sounds kinda related to a project of mine from a while back?

I made a python script that takes a bitmap image and processes it into tiles and a tilemap for SNES. The color depth isn't fantastic since it's in mode 1 and not mode 7, therefore having to share 8 palettes of 16 colors for the whole image, but I'm still quite impressed with the results I got from it. There is definitely still room for improvement too - you could use sprites for a boost to the color depth for example. This was mostly just a proof-of-concept.

With a loooot of pre-processing (like, weeks of it), you can even use this method to render a video frame-by-frame into SNES format. As an example I did the "Sonic Boom" video from Sonic CD. You need bsnes or an SD2SNES to play it unfortunately, due to reliance on MSU1, but the same concept can still be done without it. It's just a rom size thing; a 4 MB rom can only hold a couple seconds of video like that. Also, CD-audio!

My only complaint about the video results is that some frames that are almost but not quite one solid color came out looking like crap. If I had a cleaner source video that probably wouldn't happen, and the SNES's more limited color depth amplifies the smooth gradients into ugly jagged transitions, but yeah. I should really record video of it playing on my SNES and put it on youtube or something.

Anyways, hope that was relevant to the topic at hand.

EDIT: in the interest of the "easy" factor, I even wrote a small "picture displayer" ROM that takes static images output from my program and displays them on screen, in a slideshow-like fashion. If you're interested I could throw the source on my github when I get home.

User avatar
feos
Posts: 107
Joined: Tue Apr 19, 2011 11:26 am
Location: RU
Contact:

Re: High color bitmap on the SNES

Post by feos » Thu Sep 03, 2015 9:31 am

Woah, haven't looked at those, but sounds powerful.

My plan is to write an article about arbitrary code execution, and the best explanation would be to try and execute some code that is exclusive, like displaying a logo of the 'zine I'm writing for. So it's not a ROM with inserted images, but an actual program (fed through executing contents of input registers as code) that generates them. Hence, to be fast and easy, I'd prefer some methods that are as direct and straightforward as possible, not impressive or demoscene-ish.

And yes, by all means, post your sources.

PS: I know you, Khaz, I accepted your runs! Hi.

User avatar
Khaz
Posts: 311
Joined: Thu Dec 25, 2014 10:26 pm
Location: Canada

Re: High color bitmap on the SNES

Post by Khaz » Thu Sep 03, 2015 10:27 am

feos wrote:My plan is to write an article about arbitrary code execution, and the best explanation would be to try and execute some code that is exclusive, like displaying a logo of the 'zine I'm writing for. So it's not a ROM with inserted images, but an actual program (fed through executing contents of input registers as code) that generates them. Hence, to be fast and easy, I'd prefer some methods that are as direct and straightforward as possible, not impressive or demoscene-ish.

And yes, by all means, post your sources.
I will make a note to stick the sourcecode up on github when I get home if it's not there already.

I don't know how big of a block of arbitrary code you have to work with, but I can think of a few ways that could be done. My first take on it would be something like...

- Disable interrupts, turn off screen
- Ensure in Mode 1 (for example). Disable BG1 and 2, so you just have BG3 (2bpp)
- Set up a DMA to clear BG3's tilemap in VRAM. (I think you can do that with ACE? Set the DMA source as a zero value somehow?)
- Write a blank tile and then a few tiles for your logo to BG3's CHR VRAM through $2118, and then a few corresponding tilemap entries to show them on the screen
- Write a palette to CGRAM if you have time/inclination
- Ensure BG3's scrolls, tile sizes, etc... are set right, turn on screen!
- If you don't care what happens next, a STP instruction should suffice to keep it on screen.

Anyone have opinions on my method? Shouldn't be hard to do or take too many instructions to pull off, I don't think. If it sounds viable I'd be happy to write up some sample code of what I mean when I get home.
feos wrote:PS: I know you, Khaz, I accepted your runs! Hi.
Glad to see I am so memorable. :)

User avatar
feos
Posts: 107
Joined: Tue Apr 19, 2011 11:26 am
Location: RU
Contact:

Re: High color bitmap on the SNES

Post by feos » Thu Sep 03, 2015 11:25 am

If I were to try all that, I'd keep the screen on during all the building, just for the sake of itself. Unfortunately, I'm merely unable to try writing something that complex as your suggested payload. But I can try learning from examples that are noob-simple.

However, if you feel interested, I can just collaborate with you on this and make it actually something nice with your help. Though at first I'd need to learn the very basics, to understand what's going on. Because, you know, to explain something to people, I have to be able to pull it off myself :)

User avatar
Khaz
Posts: 311
Joined: Thu Dec 25, 2014 10:26 pm
Location: Canada

Re: High color bitmap on the SNES

Post by Khaz » Thu Sep 03, 2015 11:44 am

No problem, and hey, I wouldn't mind collaborating either. Always been fascinated by ACE and would love to see the process more closely. We'll see how it goes! I'll write up what I mean by that code when I get home.

The turn off screen part is only because you can't write to VRAM while the screen is on, so you'd need to either do that or wait for a vBlank. Turning off the screen just seems easier.

tepples
Posts: 22049
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: High color bitmap on the SNES

Post by tepples » Thu Sep 03, 2015 12:07 pm

If you want to leave rendering on:
  1. Set the mode and scroll
  2. During vblank, use DMA to copy a palette to CGRAM and a few logo tiles to VRAM
  3. Prepare a tilemap in 2048 bytes of main RAM
  4. During vblank, copy this tilemap and more logo tiles to VRAM

93143
Posts: 1225
Joined: Fri Jul 04, 2014 9:31 pm

Re: High color bitmap on the SNES

Post by 93143 » Thu Sep 03, 2015 4:18 pm

I decided to just go ahead and clean up the hcolor2 code. It didn't take all that long, as it turns out - I have a much better understanding of what's going on than I did back then. It's not an ideal model even now, but it should at least be readable.
hcolor2.7z
(122.98 KiB) Downloaded 165 times
However, I would recommend taking a look at Neviksti's actual SNES Starter Kit, as well as everything on superfamicom.org (especially the Registers page) and nocash's docs. Also, I believe the SNES Starter Kit uses a very old, buggy version of WLA DX, so watch out for that. You may want to use an updated version or a different assembler entirely.
feos wrote:So how much freedom does backdrop layer allow? Can it change colors every pixel? Color depth is not an issue at all, as I mentioned. If it only allows going in blocks of the one color, it's still okay for me. If only in lines, then no.
You have two backdrops, the main screen one (which uses CGRAM colour #0) and the subscreen one (which uses the separate COLDATA setting). You can change each one during HBlank using HDMA or an IRQ, or by polling HVBJOY, and I believe it is also possible to change COLDATA and possibly CGRAM #0 mid-scanline with timed code and/or an IRQ (as I said above, I plan to try this using bulk DMA to see if I can get a picture). The main and subscreen backdrops can be combined with colour math. I'm 99% sure the colour math mode defined by CGADSUB can be changed mid-scanline (I don't know how else to explain my results), but I don't know if any artifacting occurs.

There are two masking windows available; each one has a left and right position that can be changed during HBlank (or possibly during a scanline, though this could fail or result in garbage; I haven't tried it). The windows can be set to mask individual BG layers and/or the sprite layer, and can also prevent colour math or even force masked areas to black. Effects like the keyholes in Super Mario World and the rank numbers in Super Mario Kart are done by modifying the window edge positions with HDMA, and if your logo is vertical and doesn't contain M, N, or W this should work fine.

There's actually a commercial game (Air Strike Patrol) that changes the screen brightness in INIDISP mid-scanline. It's used to draw the shadow of the player's aircraft, though it's a bit jagged due to timing issues.

Mid-scanline writes are apparently dicey when moving from a regular SNES to a SNES Jr., as the PPU was radically redesigned and doesn't work the same. HDMA and windowing are no problem, besides which they are generally much better looking and less finicky to get working.
My plan is to write an article about arbitrary code execution, and the best explanation would be to try and execute some code that is exclusive, like displaying a logo of the 'zine I'm writing for. So it's not a ROM with inserted images, but an actual program (fed through executing contents of input registers as code) that generates them.
That sounds like a pretty ambitious plan for someone who's never seen SNES code before.

I don't suppose you could load a graphics loader and then upload a bunch of tiles through the controller ports...

Post Reply