Disassembly of Graphics Magician Picture Painter for the Apple II
First released for the Apple II in 1982, The Graphics Magician is a collection of software tools that assist developers in creating graphics and animations. It was later released for the Atari 8-bit computers, Commodore 64, and IBM PC, and an updated version that supported double hi-res on the Apple II shipped in 1984.
Disk images and manuals for certain versions can be found on graphicsmagician.com, a site created by former employees to host historical archives of software published by Penguin Software (which later became Polarware).
One of the prominent features of The Graphics Magician was the Picture Painter tool, which was used to draw scenes for graphical adventure games. Instead of saving each screen as a bitmap, the tool recorded the drawing instructions, which could be played back with a small program. The technology was used in some multi-platform adventure games, a list of which has been collected here.
The disassembly here is of the single-hi-res picture drawing code. With it, you can draw lines in the standard hi-res colors, and select from 108 different color patterns to draw text, brush patterns, and fill white regions of the screen.
The Graphics Magician is copyright by Penguin Software.
- Disassembly listing of PICDRAWH from the 1984 release.
- Project set - project files and binaries (requires SourceGen v1.9.2 or later).
Using the Picture Painter
The best reference is the original manual. While the manual for the 1982 version is easy to find, the 1984 release is slightly more rare. It can currently be found here. The disk image can be downloaded from the graphicsmagician.com site here.
The 1984 release introduced support for double-hi-res graphics. The single-hi-res code was revamped, and the code entry points are different from what's listed in the 1982 manual.
Picture files are edited with PICEDIT. They can be listed and converted to/from "transfer files" using PICDOC.
Picture Structure
Pictures are stored as a series of commands. The high 4 bits of the first byte specify the command. The low 4 bits can be used as an argument. Depending on the command, 0-2 bytes of data follow.
| Num | Command | Data |
|---|---|---|
| $0x | End of picture | none |
| $1x | Set text cursor | X, Y |
| $2x | Set line color | color (0-7), merged with command byte |
| $3x | Reverse text | char |
| $4x | Set brush | index (0-7), merged with command byte |
| $5x | Normal text | char |
| $6x | Set brush/fill color | pattern index (0-107) |
| $7x | (unused) | |
| $8x | Set line start | X, Y |
| $9x | (unused) | |
| $Ax | Draw line to | X, Y |
| $Bx | (unused) | |
| $Cx | Draw brush at | X, Y |
| $Dx | (unused) | |
| $Ex | Fill at | X, Y |
| $Fx | (unused) |
All commands are 1-3 bytes. X,Y coordinates are stored as absolute positions on the hi-res screen (0-279, 0-191), with the high part of X merged with the command byte, followed by the low part of X, then Y.
The tool also allows for "objects", which are pictures that start with a dummy line-start command. These are drawn through an alternate API entry point that doesn't begin by erasing the hi-res screen, and takes the object's position as an argument.
When drawing a brush, the X,Y coordinate specifies the top-left corner of the 14x16 bitmap, not the center. The brush drawing code does not test for screen edge overruns.
"Reverse text" means that, instead of drawing the text in the current pattern, the glyphs will be XORed with the current contents of the screen. The default font, which is embedded in PICDRAWH, has fat vertical strokes to make hi-res color rendering feasible.
In the PICEDIT tool, line colors, brush/fill patterns, and brush shapes are selected on screen from this palette:
Brush colors are arranged in columns. Brush #0 is at the top left, #1 is below it, #10 is at the start of the next column, and so on. The last two entries, which would be #108 and #109, are unused; selecting them in PICEDIT has no effect.
Regions of the screen that are entirely white can be filled rapidly with a pattern using the flood-fill call. The algorithm is described in the manual:
- Scan directly up from the selected point until a border is found.
- Move down one line, filling to the left and right borders.
- Average the left and right borders to find the midpoint, and move down one line from there.
- Check to see if the point moved down to is a border. If not, go back to step 2.
It's important to start the fill near the highest point, so that the algorithm can find the top of the region. Shifting the midpoint to the center of the current line's fill region significantly improves the code's ability to fill convex shapes with a single operation.
Copyright 2025 by Andy McFadden