magazine logo
Welcome to the official Attitude website - Europe's #1 C64 scene disk magazine
Proportional Scrollers
by Puterman/Fairlight

I guess my articles in "Attitude" are turning into a series of coding articles for newbies. This time we'll again do something pretty simple, which you can use to spice up your intros or demo parts, if you're the kind of coder who doesn't consider scrollers to be the most boring invention since sliced bread: proportional scrollers.

So what's a proportional scroller? A scroller with a proportional charset, like the text in "Attitude". Coding a scroller (or e.g. the text displayer in this mag) takes a bit more work than a fixed width charset, because if you're using a fixed width charset (assuming the chars are a multiple of 8 pixels wide) all you have to do is to define a charset and poke the right character values into screen memory.

So what do you have to do to display text in a proportional charset? You have to plot the character for each letter in the text into a bitmap (which doesn't have to be a bitmap in the C-64 sense of the word, it might as well be a charset or a bunch of sprites).

If you think about that for about 3.7 seconds, you'll come to the conclusion that you need to know the width of each character in the charset (as they're different, that's the point of proportional charsets). So you'll need a table with one value corresponding to each char in the charset, with the value being the width in pixels of the char. The 'A', including the empty column at the end, is 6 pixels wide, the 'I' is 2 pixels wide and the 'L' is 5 pixels wide. So, in the table we create to go with the charset, position 1 (the value you'll probably use for 'A') will have the value 6, position 9 ('I') will have the value 2 and position B ('L') will have the value 5.

I think there's a tool by Cactus to compute the width of all the chars in a charset, but you might find it interesting to write your own tool too. I'm a lazy bastard, so I always write these kinds of tools in C. Or if you're even too lazy for that, you could just load your charset into an editor and count the pixels of each char (it's not that much work).

Okay, so now we have a charset and a table that tells us the width of each char in that charset. As this article is supposed to be about proportional scrollers, I'll just give you some info particular to that problem, and then you'll have to figure out how to do a normal text displayer (plotter) yourself.

If you don't know how to write a normal text scroller, go hide in a corner and be ashamed of yourself, or just find out how to do it and then keep reading. I'll assume that you'll want to use a charset to plot the chars into, but it's equally simple to do it with sprites, a bitmap or whatever.

If you use a charset, you can either use $D016 to do the smooth scrolling (just like you'd do with a normal scroller), or you could shift all the plotted data with ROL each frame. We'll use the latter method, although it's slower, because in my opinion it's conceptually simplier, and once you've managed to code a scroller using that technique, you shouldn't have any problems with the other technique either.

So, if you're going to make a normal text scroller, using ROL instead of $D016, you'll plot the data for one char in the rightmost position of the charset each 8th frame, and each frame you shift the whole text area one step to the left, using ROL (if you're feeling really wild, or if you're just inspired by Kaktus and Mahoney, you could use ROR instead, and make it more difficult to read).

Let's assume that the charset you use is located at $2000, and you're scrolling a 40 chars wide area (i.e. the whole width of the screen). The actual portion of the charset you're using is the first 40 chars, i.e. the memory you use is $2000-$2140. The characters will be laid out from left to right on the screen, of course, starting with characters 0. As you want to shift the whole area one step to the left, you'll have to start at the right (with an offscreen buffer, into which you plot the new char each 8th frame) and ROL the data to the left.

So the code for ROLing one character line will look something like tis:

ldy #$00
rol offscreenbuffer,y
rol $2138,y
rol $2130,y
rol $2128,y
rol $2010,y
rol $2008,y
rol $2000,y

Now, the Y indexed addressing is really unnecessary, isn't it? No, I'm just being lazy, and it won't waste too much raster time to use the same code for the whole char row, so if you modify it slightly, you'll have the whole character row shifted instead:

ldy #$07
loop clc
rol offscreenbuffer,y
rol $2138,y
rol $2130,y
rol $2128,y
rol $2010,y
rol $2008,y
rol $2000,y
bpl loop

Nice, huh? Right. So, anyway, now all you have to do is to plot character data into offscreenbuffer, just ike you'd plot it into a regular character.

And well, you already know how to do that: check in the actual text buffer which character you should plot, find the data corresponding to that char in the charset, and plot that data into offscreenbuffer.

Finding the data for a character might be a bit tricky if you're not very good at coding yet, so I'll give you some hints. The easiest way is, as always, to have the data laid out in a clever way. Let's say you'd rearrange the charset (you'd have to write a tool for it, of course) so that the first $100 bytes contain the first byte of each char, the next $100 bytes contain the second byte of each char etc.

With a charset like that, plotting would be this simple (assuming the charset is located at $3000):

ldy character
lda $3000,y
sta offscreenbuffer
lda $3100,y
sta offscreenbuffer+1
lda $3200,y
sta offscreenbuffer+2
lda $3300,y
sta offscreenbuffer+3
lda $3400,y
sta offscreenbuffer+4
lda $3500,y
sta offscreenbuffer+5
lda $3600,y
sta offscreenbuffer+6
lda $3700,y
sta offscreenbuffer+7

This isn't just simple, it's also pretty fast, and it's always a good thing to think in terms of optimizations, even if you don't actually need it in this instance.

Now we've done almost everything, except for one little detail: the stuff described above won't give you a proportional scroller, only a normal one, with a fixed width charset. But the change you need to make is really simple, and you should have realized that yourself, so I won't tell you.

Er... Okay, I'll tell you anyway: each time you plot a char from your proportional charset into offscreenbuffer, you also look up the width of that char in the table you created earlier, and then you know for how many frames you should do the ROL loop before you plot a new char. For example, when you plot the 'I' in the example above, you'll find in the width table that that char is 2 pixels wide. So you'll wait 2 frames before you plot the next character.

And then there are some small details you need to check, of course, like the chars in the charset have to be left justified and so on, but you'll probably realize that on your own sooner or later.

I guess that means it's time to finish this article. If you want to see an example of a proportional scroller, check out the end part of "Clown" by Civitas. It's a bit hard to see that it's proportional, because of the charset, but if you don't believe me, use your monitor. :)


   Add/view comments on this article (comments: 0)



publication date:
Official Webpage
of Attitude diskmag
Copyright 2004-2024