Introduction:
After Synchrony there was a little gap to the next demoparty that was accepting tiny intros, so I got to play around a little with different ideas first, before settling on trying to recreate something that made me want to create demos myself when i first saw it on my screen.
The infamous Raytraced Spheres and Fractal effect from the Enigma demo, which I loved to watch when I was still a teenager.
Around this time, my girlfriend Blossom was starting to do some x86 sizecoding of her own and I noticed see was very good at FPU coding, so I asked her if she wanted to help out on this one as it involved quite a lot of FPU code to make this effect happen.
Raytracing vs Sphere Rendering:
We started off with a version that actually raytracing the spheres and reflections, which we were able to get working due to Blossom's awesome FPU skills, but this ended up just being too slow, as well as the code getting to big for a 256 byte.
So after a few iterations (each with its own FPU code), we ended up going for just drawing Spheres with displaced lighting instead, but still calculating the center points of each sphere in 3D space.
Reflections:
So when it came to adding the reflections, we ran into a couple of problems. Since we weren't actually calculating the reflections via raytracing anymore, we needed to somehow mirror the sphere in 3D space ourselves, which we ended up doing.
Another problem is that when working with a 256 color palette in 8bit graphics mode, you can't really blend colors to represent for accurate reflections. So to still get some kind of blending working, we ended up going for a dithering pattern based on the DI screen position, which would determine to render either the top half (5 out of 6 times) or the reflection (1 in 6).
aam 6 ; is where the magic happens.
The AX register (or rather AL) now contains a modulo value of DI and can be checked halfway rendering each pixel to see if the actual sphere or its reflection needs to be rendered for that pixel.
The downside is, well... You end up with a dithering pattern, which was alright on our own setup with either analogue VGA scaling or 1:1 pixel rendering, but did not show well on the Revision stream capture, which had some scaling issues.
The Fractal:
This part of the intro also went through some phases from a real mandelbrot to something a little less sophisticated which ended up in the final version.
The fractal is an interative loop of 14 iterations which will modify DL and compare it to an animation value (used to build up the effect) and substract the al with a value of 5 if it crosses it. As our palette crossed over from light blue to dark brown, this sort of gives off a similar vibe to the mandelbrot fractal of the original, with a little more icing on top ;-)
mov cl,14 ; 14 iterations
fractalloop:
cmp dl,bl ; compare dl value with bl (our animation value)
ja nosub
sub al,5 ; subtract 5 from color
nosub:
mov ah,dh
shr ah,1
sub dh,dl
add dl,ah ; add dl with modified value roughly based on y
loop fractalloop
Well aware that our production would just be this one effect, we spent the last few bytes on a sort of starting animation for our fractal, as well as the spheres coming from afar towards the screen, so there at least would be some kind of buildup in the few bytes we had left for it.
Dosbox vs Freedos:
While our first two releases were developed first for Dosbox (and only after release updated with FreeDOS compatible versions), we ended up fully switching from Dosbox to Freedos during the development of Enigma.
We know this can be a hot topic for sizecoders, because well, honestly... there are tricks you can use for Dosbox emulation that you simply cannot do if you want real DOS compatibility that will save you at least 8-16 bytes on your final product, and you get to have MIDI sound as a bonus.
So with a our switch to FreeDOS, we were trading off convenience, size and MIDI sound for performance and compatibility. And to be honest: It was a very pleasant experience coding in FreeDos, with some benefits that you just don't have outside of a DOS environment.
One of those benefits is the usages of PentiumPro instructions like FCMOV, CMOV, FCOMI, FCOMIP, and FUCOMIP instructions which aren't emulated in Dosbox, which would made life much easier for us. But after careful consideration we decided against using these as we still want our intros to run in all environments.
We personally feel that your releases should at least also work in a real DOS environment, so we took this opportunity to also retro-actively fix our previous two releases to work in FreeDos as well as making sure all our stuff runs everywhere from the get go moving forward.
Conclusion:
In the end, we are very pleased with how Enigma turned out. It was able to match our expectations for it , both technically (Can we do this classic Amiga effect justice in 256byte?) as well as in terms of reception (We were hoping to finish Top-3 at Revision).
Furthermore, It was really fun working together on this production. We learned a lot during the development in terms of optimizing our code as well as simply putting in the hours and honing your skills, which will help us a lot moving forward.
For more information, you can down the intro complete with sourcecode at: pouet.net