Log In  

Cart #jegihusofi-0 | 2023-02-07 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
4

SEIZURE WARNING - FLICKERING IMAGES!

Developer Explanation

First of all love is love! Support the human rights of human beings!

This is a flicker palette expansion demo that uses 49 colors of an available 136 "colors" to animate a randomized, circular rainbow "video wipe" style effect. This is achieved by drawing two different colors on the same pixel in quick succession to dazzle your senses into tricking your brain into thinking it's seeing more colors than Pico-8 can actually draw. It looks okay at 30 fps but really benefits from 60 fps.

Apparently there is historical evidence of arcane "Super CGA" video cards using this method to expand the color palette of old 16-color monitors from a bygone era. Cool stuff. Most of the CGA cards like the CGA board that went into the IBM PC XT back then were only displaying four colors at time so there wouldn't have been much incentive to write a piece of software that actually used this technique.

This GIF image example is 30 fps since capturing a GIF at 60 fps only shows one half of the frames so the effect is lost in the conversion. This 30 fps example is also slow enough to give an idea of how the effect is achieved: each band of colors is actually three bands wide. The code runs at 60 fps which looks 100% better than the example GIF.

My goal is mostly to remind anyone who needs to hear this that Pico-8's palette can be greatly expanded using only the official 16 colors.

Just so I know my math is right the rainbow uses 7 official colors which blends into 6 new colors between the bands. The background fills with any of the 16 official color which only add 9 new colors to the mix. The red band blends with 14 of the background fill colors in a way that it hasn't already with itself and orange as does the violet band with itself and dark blue but since red blending with violet has already been counted that's only 13 additional colors for violet.

7 + 6 + 9 + 14 + 13 = 49 colors

Controls

No controls yet. It just draws sweeping rainbows until you quit. It could use some sliders to adjust things like speed, width, delays, etc.

Developer Notes

I found cart by @dw817 called "256 Colors" with Pico-8's "Lucky Draw" feature which looks to be showing at least 136 unique colors (and 120 duplicates) which was where I got the inspiration to try something similar. I had been watching videos about legacy computers and just had to try this out. It's easy to imagine how someone might have been able to get old 16-color CGA monitors to behave in a similar fashion either in software or with special hardware.

Shout out to David Murray "The 8-Bit Guy" whose video "Meet the Super CGA Cards" discusses specialized CGA video cards like the Plantronics Colorplus and the QuadColor II. I think I just figured out how the Quadcolor II supposedly has support for 136-color on 16-color displays. @dw817's cart is a literally picture of a similar set of colors using Pico-8s official 16-color palette.

For anyone interested in the history on this stuff, here's the video I'm referring to.

I highly recommend "The 8-Bit Guy" to Pico-8 developers for some insights about what 1970's and 1980's era PC gaming was actually like. Does anyone remember when the swatches in Microsoft Paint in Windows 3.1 were dithered on some systems because the hardware didn't support the colors? Nostalgia ...

This "flickering color palette expansion" method probably has to be used somewhat sparingly in practical applications because some scenes would take too long to render at a full 60 fps.

Possible Expansions

I haven't implemented any dithering which seems to open up quite a bit more color options. There might also be a way to flicker in an extra color layer or two for broader color depth but at a considerable cost to frame rates.

There are a ton of Rainbow-themed carts that could benefit from implementations of this technique. Well worth searching around the BBS for these carts. Lots of good stuff in there.

There's lots of little variables you can play with in the code to change how this little tech demo behaves. I think of it as a piece of parametric software but I haven't yet brought out the parameters to the GUI so this cart would benefit from that work.

Minimal effort to make some sort of useful library so people can place a rainbow wipe or other gradient anywhere on the screen might be useful to someone.

Musical Notes

There's no music but this might be a good effect for any demoscene kinds of work I might do with Pico-8's amazing synthesizer capabilities which I barely know how to leverage in code at this point but after discovering @luchak 's "RP-8" cart I need to dig deeper, awesome stuff.

Free Software

Feel free to use, optimize or expand this code in any way your see fit for example to accompany music, simulate shock waves or whatever other project you're working on if you just need to slap a flickering rainbow on something. It can easily be modified to use other colors and might look amazing with some fast dithering techniques maybe using special characters or something.

P#125462 2023-02-07 12:16 ( Edited 2023-02-09 00:45)

been used with great success on Jungle Ping on very few places - the more you draw using such technique, the more it will induce visual fatigue.

your rainbow is quite nice but cannot bear more than a few seconds looking at it.

P#125475 2023-02-07 15:21

Hi @homebum:

This would be a great special effect for having found the last item in a maze or game level ! :D Gold star.

If you're curious to expansion of colors. You might be interested in this old cart I wrote that does a nice DITHER with two colors.

https://www.lexaloffle.com/bbs/?tid=35781

And my classic 256-color method by blending.

https://www.lexaloffle.com/bbs/?tid=45648

. . .

Also I had this very computer listed above. The AT&T 6300. It had great B&W graphics, 640x480. I developed a great many B&W games with it.

P#125481 2023-02-07 17:23 ( Edited 2023-02-09 04:54)

@freds72 and @dw817 y'all are doing some amazing work here so thanks for that.

@freds72 I tried to get a mix of different kinds of waves. I'm curious which are the hardest to look at and what makes them harder to look at than others. I'm assuming it's not just the flickering palettes but the motion itself could be much, much slower to alleviate some of the rainbow nausea. Thinner bands at high speeds have sort of a "detonation shockwave" feel to them. Very wide bands sweeping over the screen is kind of dizzying. I'm tempted just to code the seizure warning into the demo itself in big bold lettering and give people a few seconds or a confirmation button before it even starts just out of consideration to people who are more sensitive to that kind of stimulation. I don't want to put anyone in the hospital over a tech demo.

@dw817 I've noticed you've expanded quite a bit on these ideas. Something just occurred to me: you call this effect 256 colors in some places where I only count 136 as I mention in my post. I was thinking that if the buffer flipped three times instead of two there wouldn't be the diagonal axis of symmetry I'm seeing on the aforementioned demo duplicating colors. So for example two splashes of red with one splash of orange might be red-orange whereas two splashes of orange with one splash or red would be orange-red.

Unrelated but I keep wondering if there's a reason Pico-8 could benefit from triple buffering but I barely remember what it is or if it relates to these ideas I'm having especially about things like masking layers but it might solve certain tearing issues or even the occasional sub-60fps flickering I notice.

The ability to draw a scene in the background and then overlay sprites with even a monochrome masking layer might make dithering a whole lot easier especially if P8SCII characters or fill patterns could speed up the drawing of the dither pixels. Transparency masks of any kind would be incredibly useful and intuitive for people trying to apply ideas they'd be borrowing from graphics work using Adobe products or handwritten SVG markup which relies heavily on masking, etc. Some stuff would be brutal if not impossible without an easy way to do masking but I need to tinker with blitting very large sprites and maybe using memcopy() in interesting ways.

I need to make a note somewhere that I have no idea how big of a sprite can be blitted in a practical way to the backbuffer or how quickly that happens. Circ() and Circfill() clearly support very large sizes. Use of fill() instead of patching together sprites might perform a lot better than the latter. I hadn't thought about it but my little tech demo illustrates the large circles do pretty great if there isn't too many of them. Might be food for thought for someone.

One of the dithering techniques I was considering was lookup table "fast math" trig routines to evenly space radial lines of dither pixels but it would still be insanely recursive. Tons of calls to cos(), sin() or sqrt() would probably bog drawing down way too much. Might be practical for generating a pair of buffers and flipping between them but I can't imagine that happening in realtime even with lookup table "fast math". I'm not sure if I can improve image quality of these animations without a huge sacrifice to framerates. Although that triple-flicker palette expansion method I mentioned might be tolerable for the extra few dozen colors it might afford me.

P#125558 2023-02-09 01:41 ( Edited 2023-02-09 01:42)

Hi @homebum:

Well I'm calling it 256 cause literally the internal palette I create from the 0-15 colors (16 in all) is mulitiplied by itself, 16x16 = 256. Yet I am not considering colors that repeat, for instance 2x16 and 16x2 are really the same so, yep, while it is 256. You will clearly not be using ALL of the 256 to convert a true 24-bit picture.

As for your persistence idea, I had something similiar in mind to this sometime back. I wrote an article on the idea of blending colors mid-screen HERE:

https://www.lexaloffle.com/bbs/?tid=47549

Quite simply I wanted to set it so you could set a mode of 2-page where anything you drew had a 1-frame buffer and blended with the last thing that was drawn. So if you did this:

cls()
mrmysteryno=12345 -- adjust screen to persist last drawn images
poke(mrmysteryno,2)
rect(8,8,64,64,7)
rect(8,8,64,64,0)

You would get the perfect unflickering color of GRAY.

Another way would be to specify the page you wanted the image to appear from the 2-pages overlapping.

cls()
mrmysteryno=12345 -- adjust screen to persist last drawn images
poke(mrmysteryno,2)
rect(8,8,64,64,7,0)
rect(8,8,64,64,0,1)

There are man interpretations possible.

P#125563 2023-02-09 04:53

I am not sensitive in the medical term, just that large area blinking rapidly are difficult to the eye.

again, fine with the technique. works well for details (say, shadows or sprite outlines, antialiasing).

P#125569 2023-02-09 09:17

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 20:26:03 | 0.047s | Q:27