The idea of the 3d graphics library is to provide some fast routines, for
doing things like rotations and drawing polygons, for people like Nate
who didn't want to write their own :). What it isn't is a "3d world
construction kit"; what it is is a little toolbox of important routines
one might use for various 2D and 3D programs. You still have to understand
how all the 3d stuff works, but this ought to make it easier for people
to write 3d games and programs (especially on the SuperCPU).
--
As to the library, it consists of four routines: routines to calculate
rotation matrices, a routine to rotate centers (16-bit signed coordinates),
a routine to rotate objects (restricted signed 8-bit coords, but fast)
and project them, and a polygon rendering routine.
Although the routines are based on the polygonamy routines and ideas
every single routine was derived and written from scratch. Some of the
code isn't quite as fast as polygonamy (like the fill routine), but most
of it is a significant improvement, and the routines are much more powerful
and flexible, not to mention memory efficient.
The library is designed to work with any VIC bank -- there is always
enough room for a bitmap and eight sprite definitions. The demo
program draws into banks 1 and 2, in SuperCPU optimized mode.
One major thing the demo does differently than polygonmy is screen
clearing -- right now, it just clears the entire bitmap before
drawing into it. This can be done more efficiently.
--
Some very brief and scantily clad documentation -- sensitive viewers beware!
There are seven routines:
CALCMAT - Calculate a rotation matrix
ACCROTX - Add a rotation to rotation matrix
ACCROTY
ACCROTZ
GLOBROT - 16-bit rotation (of centers)
ROTPROJ - Rotate and project objects
POLYFILL - Draw a filled polygon
You must set some stuff up for them, and they in turn will clobber some other
stuff for you. A small jump table into the routines is at $8A00.
Memory map
----------
Zero page:
$4A-$52 ACCREM Fractional part of accumulating matrix
$53 XOFFSET Location of origin on screen (e.g. 160,100)
$54 YOFFSET
$55-$72 Intermediate variables. These locations are regularly hosed
by the routines. Feel free to use them, but keep in mind that
you will lose them!
$A3-$AE C0XLO, C0XHI, C0YLO, ...
Pointers to rotated object centers, i.e. where the objects are
relative to you. Centers are 16-bit signed (2's complement).
$AF-$B0 ROTMATH
Pointer to the multiplication table at $C200-$C3FF.
$B1-$B9 Rotation matrix.
$BB-$BC FILLPAT
Pointer to fill pattern (eight bytes, 8x8 character)
$BD-$C0 PLISTXLO, PLISTXHI
$C1-$C4 PLISTYLO, PLISTYHI
Pointers to rotated object points, e.g. used by polygon renderer.
Numbers are 16-bit 2's complement.
$F7-$FE MULTLO1, MULTLO2, MULTHI1, MULTHI2
Pointers to math tables at $C400-$C9FF
MULTLO1 -> $C500
MULTLO2 -> $C400
MULTHI1 -> $C800
MULTHI2 -> $C700
(Only the high bytes of the pointers are actually relevant).
$FF BITMAP
High byte of bitmap base address.
Library:
$0200-$027F Point queue.
$8600-$9FFF Routines, tables, etc.
$8A00 Jump table into routines
Tables:
$8400-$85FF ROTMATH, pointed to by $AF-$B0
$C000-$C2FF MULTLO, pointed to by $F7-$F8 and $F9-$FA
$C300-$C5FF MULTHI, pointed to by $FB-$FC and $FD-$FE
$C600-$C6FF CDEL, table of f(x)=x*cos(delta)
$C700-$C7FF CDELREM remainder
$C800-$C8FF SDEL x*sin(delta)
$C900-$C9FF SDELREM
$CA00-$CAFF PROJTAB, projection table, f(x)=d/x, integer part
$CB00-$CBFF PROJREM, projection table, 256*remainder
$CC00-$CCFF LOG, logarithm table
$CD00-$CDFF EXP, exponential table
$CE00-$CEFF NEGEXP, exponential table
$CF00-$CFFF TRIG, table of 32*sin(2*pi*x/128) -- 160 bytes.
The tables from $C600-$CFFF are fixed and must not be moved. The
tables ROTMATH, MULTLO, and MULTHI on the other hand are only
accessed indirectly, and thus may be relocated. Thus there is
room for a color map and eight sprite definitions in any VIC bank.
Library Routines
----------------
$8A00 CALCMAT Calculate a rotation matrix
Stuff to set up: Nothing.
On entry: .X .Y .A = theta_x theta_y theta_z
On exit: Rotation matrix is contained in $B1-$B9
Cycle count: 390 cycles, worst case.
$8A03 ACCROTX This will "accumulate" a rotation matrix by one rotation
around the x-axis by the angle delta=2*pi/128. Because
this is such a small angle the fractional parts must also
be remembered, in $4A-$52. These routines are necessary
to do full 3d rotations.
On entry: carry clear/set to indicate positive/negative rotations.
On exit: Updated matrix in $B1-$B9, $4A-$52
Cycle count: Somewhere around 150, I think.
$8A06 ACCROTY Similar around y-axis
$8A09 ACCROTZ Similar around z-axis
$8A0C GLOBROT Perform a global rotation of 16-bit signed coordinates
(Rotate centers)
Stuff to set up:
MULTLO1 MULTLO2 MULTHI1 MULTHI2 = $F7-$FE
C0XLO, C0XHI, C0YLO, C0YHI, C0ZLO, C0ZHI = $63-$6E
Pointers to points to be rotated. Note also that $63-$6E
has a habit of getting hosed by the other routines.
CXLO, CXHI, CYLO, CYHI, CZLO, CZHI = $A3-$AE
Pointers to where rotated points will be stored.
On entry: .Y = number of points to rotate (0..Y-1).
On exit: Rotated points are stored in CXLO CXHI etc.
$8A0F ROTPROJ Rotate and project object points (vertices). Points must
be in range -96..95. Upon rotation, they are added to
the object center, projected, and stored in the point
list.
The _length_ of a vertex vector (sqrt(x^2 + y^2 + z^2)) must
be less than 128.
Stuff to set up:
Rotation matrix = $B1-$B9 (Call CALCMAT)
ROTMATH = $B0
P0X P0Y P0Z = $69-$6E
Pointers to points to be rotated. As with GLOBROT, these pointers
will get clobbered by other routines. Points are 8-bit signed
numbers in range -96..95.
PLISTXLO PLISTXHI ... = $BD-$C4
Where to store the rotated+projected points.
CXLO CXHI ... = $A3-$AE
List of object centers. Center will be added to rotated point
before projection.
XOFFSET, YOFFSET = $53, $54
Location of origin on the screen. Added to projected points
before storing in PLIST. 160,100 gives center of screen.
On entry: .X = Object center index (center is at CXLO,X CXHI,X etc.).
.Y = Number of points to rotate (0..Y-1).
On exit: Rotated, projected points in PLIST.
$8A12 POLYFILL Draw pattern-filled polygon into bitmap.
Stuff to set up:
MULTLO1, MULTLO2, MULTHI1, MULTHI2 = $F7-$FE
BITMAP = $FF
FILLPAT = $BB-$BC
PLISTXLO, PLISTXHI, PLISTYLO, PLISTYHI = $BD-$C4
Point queue = $0200. Entries are _indices_ into the PLISTs,
must be ordered _counter clockwise_, and must _close_ on
itself (example: 4 1 2 4).
On entry: .X = Number of points in point queue (LDX #3 in above example)
On exit: Gorgeous looking polygon in bitmap at BITMAP.