Original Post

back in january, i asked myself if it was possible to generate more than 4 colors (counting black in) on the virtual boy with a little trick. so i wrote two simple demos, one having a seperate image for each eye, and a second one quickly exchanging two images to trick the human eye so it believes that it sees both images merged into one. you can see the two images and the wanted result in the appended image.

the first way didn’t work, the human brain won’t combine the two images. (thanks again to virtualboyfreak for testing this on hardware and getting the headache while i didn’t have my flashboy at hand. ;-))

the second seemed more promising, though, since it showed the 10 colors but flickered heavily.

so i tried to sync the image exchanging to the virtual boy screen’s refresh rate with some code jorgeche send me, but it still didn’t work. at it seems, the screen’s refresh rate is just too low compared to our eyes’.

i attached the source to the demo if anyone wants to have a look at it and might want to give multiple colors on the vb another chance.

can anyone think of other tricks to try?

  • This topic was modified 16 years, 4 months ago by KR155E.
35 Replies

I tried the very same thing a year or so ago with similar bad results (I went for 16 colors though :P)

I’ll see if I can dig up some code…

how did you get 16 colors that way? i mean red1+red2 = red2+red1. or did you show one image a bit longer than the other one?

I was messing with the BRT registers between the screen updates to make it use 3 different red shades for every odd frame. I’ll look at it again when I get my flashboy 😉

i will build yours asap. your avatar makes me drool. ;D

i replaced the above file with a qucikly updated demo version which has a menu to choose the display mode. maybe someone can add a working one. ;P

I’m sorry you all, however, I believe that you guys are killing yourselves attempting to create additional solid colors. Perhaps it would be easier if you all simply just dithered your way through all your graphics.

Very nice work, and great effort overall however.

I’ve had quite a few brightness variations in a single frame before… I don’t remember exactly how I did it, but IIRC I ran across it accidentally (maybe setting the BRT regs too high?)… I just looked through a bunch of files, but I couldn’t find it.

Assuming you know that it’d be a little bit of work to deal with it, and you know that you still can really only have 4 shades, just that the 4 shades can vary across the screen, there’s a few things you should be able to do to purposefully control it. One way would be by adjusting the values in the column table (I believe the upper 8 bits of each hword is what you’d want to change). This would increase or decrease the brightness of all shades, so it probably wouldn’t be extremely useful except for special effects IMO.

You should also be able to adjust the BRT regs while the display is active. This would take a little bit more work because you’d need to keep track of where in the display scan you are, but this would allow you to individually change the brightness for each BRT shade for each column. So you could have BRTA and BRTB constant, and just change the additional BRTC component, or if you wanted to get really complex, you could change them all. The best way would probably be to have a seperate lookup table that you create for the columns when you create whatever graphics you’re wanting, and then at every new column, set the BRT regs to the desired values.

I don’t know the best way to tell which column is being drawn though. There is SBHIT, which could tell you when SBCMP = SBCOUNT, but I think that’s for framebuffer control, not screen control. You can tell when the display starts, so if you have a good timer you could check the time to determine when to change, but that’d be pretty tough since the column lengths adjust because the mirror sweep isn’t linear (which is why the column table is there). I’d guess there’s some way to tell where in the sweep you are if you’re clever enough or look hard enough.

Anyway, I hope some of this helps… I could probably throw something together one of these days that would show this, but it shouldn’t be too complex to at least see the concept.


Here you go… quick hacked together brightness demo. The column table thing doesn’t seem to do anything, but I haven’t looked into it at all, so it could just be a stupid mistake on addressing or something, or I may not be understanding how it works (maybe needs LOCK first?).

Of course you can see the brightness change, but with it just incrementing by 1, multiple brightness changes aren’t totally apparent across a single frame. The specific part to look at is if you stop it during a BRT sweep, there’s a spot where a single BRT value has multiple levels, depending where on the screen it is. That’s what I had seen in the past. I didn’t check what the values are, but it’s not all 0xFF’s.

If you add a trigger to wait until the start of a display cycle before changing BRT values, and change the values by larger amounts, you could probably tell that there were more brightnesses across a single frame.

Anyway, the controls are:
Start: sets all BRT vals to 0xFF
Select: seta all BRT vals to default
Left Trigger: sweep BRT vals down
Right Trigger: sweep BRT vals up
A: Stop
B: mess w/ column table (doesn’t seem to do anyting)



DogP wrote:
The column table thing doesn’t seem to do anything, but I haven’t looked into it at all, so it could just be a stupid mistake on addressing or something, or I may not be understanding how it works (maybe needs LOCK first?).

This will work, but the column table is read from the start address down, not up, so you’re writing to the table in the wrong direction.

Also, make sure that (REPEAT + 1) x (BRTA + BRTB + BRTC + REST + 5) x 50 ns is less than the column period. Note that the shortest column period setting in the standard column table is 12.2 µs, and 255 + 5 x 50 ns = 13 µs.

  • This reply was modified 15 years, 8 months ago by dasi.

Okay, here’s a quick demo showing > 4 brightness levels simultaneously.

Edit: I think this needs a bit more work. Stay tuned.

  • This reply was modified 15 years, 8 months ago by dasi.

so, did you ever get this to work, derek?

So… any progress with this?

Instructions: run on hardware, press start button.



Looking good. The right screen has 16 columns of different stable shades of red, the left has the same plus some flickering dithered tiles…

So it’s possible after all, very nice. 😎
So, how did you do it? Would you mind sharing some code?

It works by setting the repeat values in the column table to change the brightness every four vertical lines. Normally these are set to 0 (1 repeat).

#define ct_mem_left    ((u16*)0x0003DC00)
#define ct_mem_right   ((u16*)0x0003DE00)

// repeat values. 96 entries, range 0 - 15 (1 to 16 repeats)
u16 rpts[96]=
{ . . . };

int ii, lcta, rcta;

// max brightness level = (2+4+2)*16 = 128

// get column table address
lcta= REG_CTA & 0xFF;
rcta= REG_CTA >> 8;

// set repeat values
for(ii=0; ii<96; ii++)
    ct_mem_left[lcta-ii] |= rpts[ii]<<8;
    ct_mem_right[rcta-ii] |= rpts[ii]<<8;

the left has the same plus some flickering dithered tiles...

Yeah, I need to check for changes to the CTA in case the screens haven't stabilised when start is pressed.

Can the method be used in a 16 shade still picture?

… on a moving object and or background?

This picture perhaps:


Can the method be used in a 16 shade still picture?

Not really, because there are still only three shades, and their brightness can only be changed every four vertical lines.

Ok I don’t want to state the obvious but it seems to me that your 10 color problem has a simple solution it is as follows. Have the artist pick between 10 solid colors. When those colors are programmed in Vide they then become 10 patterned colors the ones on KR155E’s table on his Multi-color demo (actually 4 solids and 6 patterned colors) . It doesn’t use refresh rates or anything like that just a mere recognition of colors and substitution of patterned colors. It doesn’t even use dithering just substitution ,this color that’s not on the palette for that color that is made of patterned colors on the palette. I know this whole thing could be done with color optimization and dithering but that will leave unwanted artifacts wouldn’t it be better to just substitute the colors for patterned colors? Here’s what I’m talking about.

The solution you’re talking about is just dithering. It’s ok for blocks of flat colour, or a simple and regualr gradient, but you can’t really do images with it.

Best bet is (in the case of images) to just embrace the colour limit and work wonders with it using the very limited palette.

Now, the image above reduced to 4 colours (click to illustrate) doesn’t necessarily do this well, but every gameboy game had to do this and the VB does too. What’s challenging is that the gameboy was a simple small screenm, 4 colours was excusable, but the larger resolution of the VB makes things more difficult and challenging.

It’s this that I like most about the Virtual Boy, not the 3D feature.



Write a reply

You must be logged in to reply to this topic.