Apple II "Lo-res Escape" Demo


A 32k demo using the Apple II lo-res graphics modes in some interesting ways.

See the story of a woman who just wants to be left alone to read her books, but an entire spacefaring civilization is trying to stop her.
This Demo won 3rd place in the Retro Demo category at Demosplash 2019 on 9 November 2019.

Video Capture



I apologize for the sound, it sounds great in AppleWin and MAME but it drops out on actual Mockingboard hardware and I haven't been able to sort out why.

Disk Image


System Requirements


Source Code

Source code can be found as part of the dos33fsutils project http://github.com/deater/dos33fsutils in the demos/lores_escape/ directory

Screenshots and Dev Notes

Opening Screen. This uses cycle counting to get a 40x96 display.
Portrait. This is 40x48 interlaced (40x192 but colors have to happen in groups of two). Racing the beam for 40x192 on the static rasterbars.
Book opening. This is plain lores (nothing fancy) but is rotoscoped.
Starbase. This uses the engine from my implementation of Another World. Note the intentional use of both grey colors to create intentional thin NTSC artifact lines in the columns.

Star wipe. The star wipe is a tribute to @a2_4am who is making a million wipes for his Total Replay project.
Escape. This is doing cycle counting and some advanced racing-the-beam effects. The ship sprite and lasers are in 40x192 mode (look at that smooth scrolling). Also note the text mode at the top of the screen (not something you usually see on Apple II). This is part of a playable game.
Book reading. Cycle counted 40x96 mode
Rasterbar Credits. Cycle counting and racing the beam for partial 40x192 15-color mode. Also double height multicolor fonts.

How it's Done

Graphics

The original Apple II has an 40x24 text mode, a 40x48 15 color lo-res mode, and a 280x192 6-color (with extreme limitations) hi-res mode. Later models extend these a bit, but we aren't using any of those advanced (double lo-res or double hi-res) modes. This entire demo is in 40x48 lo-res.

How do we get 40x96 and 40x48 interlaced modes? The Apple II has two pages of lo-res memory, and we can page-flip between them. If we page flip every two scan lines (40x96) or every scan line (40x48) we can get these higher resolutions.

The problem is each scan line is 65 cycles, and that Apple II has no official way of knowing when HBLANK or VBLANK start. For more info on how we use "vapor lock" and the "floating bus" see this article.

In addition to those mode, some of the scenes have parts of the screen in 40x192 resolution. This is done by racing the beam. Usually if you switch each line, you are limited to having two colors in the 4 pixel high block as there's only 2 pages to choose from. However, in the 65 cycles before you have to switch back you can write up to 13 pixels (to the same color, for rasterbars) or 7 pixels (arbitrary color, for sprites).

To do this you have to unroll a big bunch of code that's roughly 49 instructionsx192 lines long, so roughly 10k. This is big, and in this demo we have multiple different tables like this. So we generate them on the fly to save space. This table can then be modified in the VBLANK to allow sprites and rasterbars.

Sound

Sound was the trickiest part of this demo, and the part that didn't go well during the live showing at Demosplash.

The music is a pt3 file by DYA. It has been scaled a bit to be 1MHz/60Hz. The sound quality suffers on actual Mockingboard hardware for unknown reasons, the music sounds great in the AppleWin and MAME emulators.

The starbase sequence is using the interrupt-driven pt3_lib as normal. This cannot be used in cycle-counted situations, so for that I have to decode to memory and play that. However it takes roughly 2.75k for each 3s of audio, so space is a constraint. For the beginning music it decodes to the language card (top 12k of memory). At the end we need much more of that, so we decode the music and completely over-write the first half of the demo as we don't need that code anymore.

There are some handoff issues that are really tricky to address when switching from interrupt-driven to cycle driven. Another issue happens as we have to decode to disk while still playing the music. The last tricky part is playing music during the picture loading and graphics-lookup parts which take a long time and are not cycle-accurate so we have to estimate and schedule calls to the music player while we can.

Vote for this at Pouet
Back to my Apple II pages
Back to my Demo pages