 |
PalmOS Warp 0.5: Technical stuff
|
 |
Below is a sketch that explains the basic techniques behind the
scrolling background.
I have two Bitmap objects, marked "1" and "2", and outlined with a green and
blue border, respectively. They are 160x144 pixels in size and get drawn onto
the visible region (outlined with a red border) every screen update. Each time
I draw them a little bit further to the left, until one is completely outside.
Then I move it back all the way to the right.
I keep track of which parts are visible and draw new building blocks on the Bitmap
object that currently holds a vertical block line which will soon be scrolled into
view (denoted by a purple arrow). This is a special technique in itself, since the
KVM Java for PalmOS doesn't allow you to draw directly onto Bitmap objects. But
you can manipulate them by treating them as arrays of 16-bit data
and simply changing the entries, one by one, to new values. This is very
processor-intense on the Palm, but I only need to change between 16 and 32 entries
per scroll step, so the workload is managable. I keep a special array of 16-bit
values corresponding to various building block objects, from which I simply
copy data to the Bitmap arrays using a FOR loop.
Here is an example of a KVM Java Bitmap
constructor call and what the image looks like:
Bitmap life = new Bitmap(new short[] { // Life indicator
15, 15, 2, 0, 0, 0, 0, 0,
4032, 4400, 8462, 16642, 16670, -31788, -31532, -31276,
-30764, -31788, 16670, 20802, 11182, 5488, 4032 });
The constructor builds the
Bitmap out of a 16-bit word array, where the first 8 entries contain
the header information (height, width, etc.) and the rest are the pixels
(rounded up to the nearest 16 bits for each row) in reading order.
What's interesting is that the system refers to this data directly,
so if you modify it the changes will be seen immediately the next time
the image is drawn. There is no need to call the constructor again.
The same approach to draw mobile objects would not have worked.
I tried it in an early, discarded version of PalmOS Iceblox, but
it was way too slow. The technique I used for drawing the flames,
however, was very handy.
In a game like Warp, pixel transparency is essential. The background is
highly complex and has to work together with non-rectangular mobile objects.
Since the KVM doesn't support transparency, the only way to achieve this
is to do two drawing operations, with different image data -- one OR operation
to set the black pixels and one AND operation to clear the "white" pixels.
The KVM can only do OR/AND when moving data between the onscreen and
offscreen image buffers. This is fine in the Warp case, since I don't need
the offscreen buffer for anything else. While the game is running, that
buffer looks like this:
If I want to draw, for example, the main spaceship, I OR the 19x20-pixel data
block starting at co-ordinates (19,0) onto its destination, on the
scrolling background drawn just before. Then I AND the 16x16-pixel
block starting at (0,73) onto the same spot. Doing it in the reverse order would
work too, but I figured that the black pixels are more important (and have to be
drawn first, so that they get to be visible the longest time before the next
screen update).

People who take a close look at the source code
will notice that I'm occasionally
using XOR operations as well. Those are for the bullets, which have to be fully
visible against all backgrounds. But I'm compromising a little. Every other
screen update I do an ordinary AND (i.e. I draw them completely white).
Unfortunately, the KVM is not fully compatible with older system versions. You
need at least PalmOS 3.5 (or possibly 3.3?) installed on your handheld device
for the "transparency" trick to work. Otherwise some objects may not show up
at all. This isn't too much of a problem for Palm owners, but some of the
cheaper clones, like the Handspring Visor, lack system upgrade capability.
|





|