pouët.net

1k boing by Piru [web]

1k boing
========

The original idea was to reproduce as much of the original CES Boing Ball demo
as possible. I discussed the idea with some guys over beer and we had some
debate on how this I should approach the problem, especially the filled
polygons. My argument was that setting everything up via HW banging would
actually end up taking more code than using the OS calls.

Anyway the ball itself is 1:1 reproduction of the ball from the original Boing
Ball in the CES demo, minus the shadow. The original boing demo uses fairly
complicated code to calculate the quads required for the palette animation of
the ball. Clearly it would have been way too complicated to reproduce it in
1k. In order to have sensible targets I set my goal to incremental stages:

- draw the ball
- rotate the ball
- bounce the ball
- add boing sound
- extra stuff, room permitting

Reproducing the ball clearly proved to be the most challenging part. I started
by dumping the SetAPen/AreaMove/AreaDraw/AreaEnd calls of the original boing
demo (by patching the ReSourced binary and recompiling, heh). This gave me the
required colors and coordinates to draw the ball.

I spent considerable time trying to figure it out how to optimize the data.
The ball has 8 rows, each consisting of 55 quads (total 440 quads). I realized
that for each new quad I only needed to have 1 new coordinate, the 3 other
being available from earlier steps. When looking at data it became obvious
that each new coordinate could be encoded as deltas rather than absolute
coordinates. The coordinate deltas could be encoded to 3 bits per coordinate
pair (2 bits for x delta, 1 bit of y delta). The color of each quad could be
calculated algorithmically. I only needed to have 7+7 bit absolute coordinate
for start of each row, the rest of the row could be encoded with 2+1 bit delta
per coordinate. This reduced the ball coordinate data to (7 + 7 + 3 * 54) * 8
bits = 176 bytes.

I implemented the early prototype utilizing HTML5 canvas and JavaScript. This
way I could make sure that the optimizations were actually working in real
life. Once the algorithm was working correctly I wrote the first 68k code
rendering the ball from the data.

Rotating the ball involves a simple palette cycling. I made the palette
generation short and dynamic, allowing easy color changes if desired.

Getting the ball to bounce was rather easy. I added simple gravity with
movement direction change on bottom and side collision. The ball movement
utilizes the same method as the original boing demo, namely poking rasinfo
offsets and calling MakeScreen.

Boing sound is actually just an 8 byte sine sample, with volume reducing at
predetermined speed. The boing frequency is determined by the location of the
ball at the time of the collision.

Changing the color of the ball was realized by rotating the constant used to
generate the ball "red" color. When performed inside the main loop it results
in the ball color changing over time.

The scroller was added as an afterthought, and it reuses much of the code
already used to render and move the ball. The scroller is a separate, wide
screen located at the top of the display. The text is extracted 1 character at
a time (encoded as 6 bits per char) and rendered by using Text() calls,
enabling custom spacing. The actual scroll involves scrolling the screen
viewport in similar fashion to the ball movement. The limitations of the
AmigaOS viewport scrolling explain the somewhat glitchy appearance of the
scroller. The appearance slightly differs between KS 1.x and 2.x+, too, due to
obviously different topaz font and changes in the actual intuition/graphics
library implementations.

The code is naturally heavily optimized and pulls couple of rather neat tricks
to save space, but the main functionality of the intro is rather
straightforward.

 - Piru