TICT TUTORIAL SERIES 1 - Part VI | (c) TI-Chess Team 2001 |
Grayscale Text-Scroller with Background Image |
This tutorial will explain how to implement a Grayscale Text Scroller for the TI-89 and the TI-92p, where the text scrolls from bottom to top across a Background Image.
There are many ways to implement such a scroller. I have decided to explain the techniques behind using an oversized backbuffer (invisible screenbuffer). Of course, for plain text there exists character drawing routines in the AMS which supports clipping already, so using the oversized backbuffer is more or less useless in this case. But the explained techniques can be used for any form of scolling, too.
When you try to scroll something you have one major problem: what should I do when I'll come near the borders of the screen? To explain it in terms of the textscroller: How could I scroll the text this way that it scrolls softly in from below and scrolls softly out at the top without appearing and disappearing roughly?
Screenshot of the Text Scroller after a few seconds
The presented scroller consists of a still image in the background and the text scrolls above it. To get more contrast for the text (to make it readable) the background image uses only the dark-gray plane and the light-gray plane gets completely filled.
Now to the trick used for the scrolling: the program allocates a buffer which is capable of holding a 160*108 pixels large bitmap. As you may guess it already the trick is to allocate more lines than lines fitting on the screen. In our case we allocate 8 more lines, because the program uses a 8-pixel high font. By redirecting the graphics functions of the AMS with PortSet() to draw into the area of these not visible 8 lines, the program manages it to let the text softly appear from below.
To make the scrolling as fast as possible the allocated backbuffer will be used only for the text. This way the scrolling can be performed easily by just moving the complete content of the backbuffer line-by-line upwards. Whenever a complete line becomes completely visible a new line is drawn into the "invisible" part.
To combine now this "textplane" with the background and copy it into the the visible grayplanes the program uses a simple loop which takes one longword (4 bytes) from the textplane and one longword from the background image AND's them together and writes the result into the visible grayplanes.
Now we have scrolling. Nice isn't it ;-)
I know my above explanations are really rough and maybe not completely understandable, but I would suggest to examine the sourcecode for more details.
We have just managed to implement a grayscale scroller, but what do we see? Arr***! The result flickers extremely, or better, flickers depending on the scrolling speed.
I'm sorry to introduce you to the wide field of synchronization problems. So what causes these flickers? The first source of these flickers is that the scroller runs with a fixed speed and the screen refreshing is done also with a fixed speed. If both speeds doesn't match in a special way you can get all kinds of flickers: constant ones, pumping ones etc.
Now this source can be fixed easily on HW1 calcs. The screen refreshing and the frequency of interrupt 1 calls matches on HW1 calcs. By installing an own interrupt 1 handler we can "get in sync" with the screen refreshing. The sourcecode of this tutorial implements such a handler and shows its usage. On HW2 calcs another method have to be used, but its even more easy to synchronize with the screen refresh on HW2 calcs.
But now grayscales comes into play. For grayscales a special handler hooked on interrupt 1 is used. But grayscales are tricky: to get the imagination of grayscales 2 planes gets "flipped" fast. For a short period of time plane 0 is visible and than for a short period of time plane 1.
To get different shades of gray the time how long the planes are displayed differs from each other.
Without any knowledge about when a new plane becomes visible we cannot synchronize to it.
The flickers which you can see when you use the attached demonstration program are caused exactly by this missing synchronization.
The only solution in my opinion will be a grayscale handler which "exports" a kind of counting variable which can be used to evaluate when a new plane gets drawn and which one.
But that's not enough. There exists also a general problem which cannot be solved in any way. This problem is called "phasing" and is caused by the plane flipping mechanism itself.
The plane flipping mechanism for grayscales draws the single planes after each other to the visible screen to simulate real grayscales. Even if the content of both planes changes at the same time your eye will interpolate between one old plane and one new plane for a short period of time. In the case of our text scroller you will see the grayplane data for the light plane and the darkplane displaced by one line.
This "phasing" effect may be reduced by synchronizing to the lightgray plane, because this way the time where only one plane is updated gets minimized, but nevertheless the "phasing" effect will be notable.
Check the TICT HQ Website at http://tict.ticalc.org for more tutorials and software.More useful tips, tricks and hints can be found at our Messageboard at: http://pub26.ezboard.com/btichessteamhq.
Suggestions, bug reports and similar are VERY welcome (use our Messageboard for this!!).
Like Xavier from the Doors Team I like it to get postcards from all over the world. If you want to thank me, just send me an postcard with greetings on it. Thats enough.
My address is:Thomas Nussbaumer Heinrichstrasse 112a A-8010 Graz Austria... and please: no mail bombs if one of my programs had crashed your calculator!