Hi again, so I wanted to share a bit of detail about my latest OCS 4K. This one uses the 320×180 widescreen setup (DIWSTRT,$5281; DIWSTOP,$06c1), which turned out OK I think. It also means one frame of one bitplane takes up 40*180=7,200 bytes, and we can have 32 frames for a bargain 230,400 bytes (and that’s key to the technical design of this intro).
So, for setup we calculate two tables, each with an 8-bit value for each pixel. Firstly distance from center, and secondly the radial angle. The angle routine uses atan2 and is inaccurate around the edges, which you can notice on the “spiral” screen where there is a distortion around some diagonal lines. But this wasn’t noticeable on the stream, so. Oh, and I also want to mention that the Cinter init routine actually calculates a huge sine table. I used that for the reverse cosine lookup.
So for each effect 32 anim frames get rendered to a back buffer in fastmem, and when it’s complete it gets copied to chipmem. Each effect follows the same pattern for better compression: Spin for a few seconds, add a bitplane, add another bitplane, reverse spin, etc. Spin is just done by increasing (or decreasing) a pointer to the framenumber and ANDing it with #$1f. Pretty efficient.
So the actual rendering routine works like a crummy shader. It has access to the angle and distance table for each pixel, and each effect is a variation on this. Mostly they use a 32bit pattern where we use the angle of the pixel to determine if it should be set or clear. This is the pattern for the one from the screenshot:
dc.l %11000000000000000000000000000011 dc.l %11000000000000000000000000000011 dc.l %11100111001110011100111001110011 dc.l %11000000000000000000000000000011 dc.l %11100111001110011100111001110011 dc.l %11000000000000000000000000000011 dc.l %11100111001110011100111001110011 dc.l %01100000000000000000000000000110 dc.l %01111111111111111111111111111100 dc.l %00111111111111111111111111111000 dc.l %00011111111111111111111111110000 dc.l %00001111111111111111111111100000 dc.l %00000111111111111111111111000000 dc.l %00000011111111111111111110000000 dc.l %00000001111111111111111100000000 dc.l %00000000111111111111111000000000 dc.l %00000000011111111111110000000000 dc.l %00000000001111111111100000000000 dc.l %00000000000111111111000000000000 dc.l %00000000000011111110000000000000 dc.l %00000000000001111100000000000000 dc.l %00000000000000111000000000000000 dc.l %00000000000000010000000000000000 dc.l %00000000000000000000000000000000
For each frame the comparator is just rol #1’ed. Good thing the angle and distance calculations are pretty crude, or we would have to spend a lot more space on these!
In the end, all the “shader” routines have to be pretty similar to maximize compression. This also means each effect takes very little space by itself (notes from sourcecode for a few of the effects):
; Lines 48 bytes ; Bubbles 68b ; Pogos 72b ; Spiral 52b
Putting in text took about 200B, including the text and all the extra code/copperlist, and of course the endpart is rather different from everything else. I considered taking these out and just shoving in more parts, making it 8 minutes long like Megademica 😊But 1) couldn’t find enough varied effects and 2) that’s too long anyway and 3) I really like the endpart! I would have liked to make some kind of horizontal sine movement on some effects though. But that’s 80 bytes I didn’t have…
Rendering speed is kinda bad. You think it’s slowly paced, but that’s just how long it takes to render the back buffer. Of course it varies from effect to effect but I kept the timings the same for all effects to help the compression. Except I had one variant where I render 2 frames in the same loop, which is used for the first screen so that it doesn’t take too long to start up.
Finally a word about the idea. At first I just wanted to make the first screen, with the radiant lines and spinning. All the other ideas came after I’d started on that, based on the same routine.
So hope that kept you entertained for a bit, keep on coding!