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.