Welcome again to Stupid Programming Tricks. May is programming month! Actually, every month is programming month. Apparently we can't call it coding, since we're using C rather than assembly code—which is too bad, since “coder” sounds much more sinister and intelligent than “programmer”. Regardless, lately I've been wondering, am I the only Linux user in the world who didn't come from a UNIX background? The truth is, all this networking bother strikes me as a bit dull. What about normal coding? If Linux is going to sit anywhere other than on servers, it's going to have to be a multimedia OS. You may have noticed all of our Stupid Programming Tricks episodes deal with multimedia. Well, there's a method to my general idiocy. Already we can write scrolltexts, slide graphics over backgrounds, play music, synthesize sounds, fork processes and placate gcc. We can also log in as root and ruin our console screens, but that's beside the point.
This month, in honor of programming, we're going to make something neat. Yes, it's time to do something really cool and yet somehow worthy of the title “Stupid Programming Tricks”. To justify such, we must be explicit in doing something with no practical value. Hence, the point. What better way to say “Hello world!” than with a scrolltext? Hark, someone is senile—we have already done scrolltexts. Grrrr. How about a scrolltext that warps like a slithering snake?
Sine scrollers are an epitomal form of the scrolltext, not quite the pinnacle—for that, we'd need text that wraps in three dimensions, casting shadows and twisting like threads of deoxyribonucleic data—but an epitomal form, nonetheless. We're also going to cheat. Well, not really, but instead of doing clever programming tricks to save processor resources, we'll use a simple routine, since with SVGALib, it's the only thing we can do. Sine scrolling is a trick in itself, and I haven't found any tricks to make it less processor-intensive, short of adding new functions to SVGALib or lowering the resolution. It works on the 1MHz C64, and it ran on my 60 MIPS box with digital music in the background, so I reckon your 600 MIPS box won't suffer.
In order to make a sine scroller, we start with the makings of normal scrolltext: a physical screen for the actual display, a virtual screen for drawing and a scroll board to hold a graphic of our scrolltext. In our last scrolltext episode, we just copied the scroll board to the virtual screen and the virtual screen to the physical screen, doing all the scrolling in the scroll board and drawing our text as one graphic the width of the screen. This time, every single pixel-wide vertical strip of text will have a different Y coordinate from its neighbor when it gets drawn to the virtual screen from the scroll board. The only way to do this is to copy a 1x8-pixel strip, 320 times every refresh! That's about 19,200 function calls per second, even at a 60Hz refresh rate. Well, with processors that can handle hundreds of millions of instructions per second, it's not a big deal. My old box, which ran at 60 bogomips before it died last summer, could do a sine scroller with a really big 256-color font, star fields and raster bars in 640x480x256 with digital audio in the background. Remind me to dig that code off the hard drive and cover it some time. Today, we'll just use the standard 8x8 font in one color, to get the hang of the whole sine-scrolling thing.
Sine functions are beautiful. You can use them for anything, literally. A sine function has amplitude, phase, period and shift, and you can play tricks with these. For example, you can plug a sine equation into the amplitude, phase, period or shift on your first sine equation. These techniques are useful not only for making cool patterns; audio synthesis techniques rely heavily on plugging sines into sines. For our scrolltext, we could make a sine equation with a period of, say, 320, an amplitude of 90, and shift it to the exact middle of the screen. However, this would result in an unchanging sine pattern; that is, rather than slithering like a snake, the sine pattern would hold still like a serpentine pipe while the letters contorted through. It looks cool enough this way, but there's no sense of motion. To add motion, we play games with the phase; i.e., we keep cycling the phase so that the sine appears waving, up and down, like a snake.
Now, how steep do you want the sine? Well, that's a function of amplitude and period. Generally, we already have an idea of what amplitude we want (usually either full-screen or just bouncing along the bottom), so we play with our period. If you want a scrolltext that squeezes together and then stretches out, you can use a sine function to modulate the period. Now, we could also plug a sine into the amplitude, to move between flat-lining and squiggling, although it's not so useful.
Finally, you can also plug a sine into the shift in order to give a lot more variety to the scroller as a whole. The result actually looks quite neat, it's rather complex, yet visibly based on sines. There's an aesthetic quality here to be appreciated, the interplay between simplicity and complexity. In honor of sine waves, let's also grind our processors a bit by using sines to cycle the colors of our text; it'll look cool.
Now it's time for the code. Remember, it's just the same simple procedure as in our last scrolltext episode, only now we're using some sine equations to determine the y value for where our text gets placed, and a loop to draw out the text one 1x8 strip at a time. It's simple conceptually, although if you don't get it, try typing it in rather than downloading it and you'll probably understand exactly what's going on by the time you are done. Sines are some of the most useful things in the world, so even though we're using them for something silly, they have infinite practical use, and I hope this inspires some clever ideas for you!