lib3d, version 2.0 SLJ 4/99 -- The idea of the 3d graphics library is to provide some fast routines, for doing things like rotations and drawing polygons. Version 2.0 of the library contains a number of significant changes and enhancements, in large part to support obj3d, the 3d object library. Changes include: o New memory map, in particular reorganized zero page. o Rotation accumulation routines now take a _pointer_ to the matrix to be accumulated (formerly used zp matrix) o ROTPROJ multiplies by both orientation and viewpoint matrix before projecting; also stores rotated z-coords in PLISTZLO/HI (useful for depth-sorting objects) o New routines PLOT and DRAWLINE let you, well, plot points and draw lines. o Multicolor! There is now both a hires and a multicolor version of the library. The line/plot/polyfill routines all plot in multicolor, and ROTPROJ corrects for the screen aspect ratio. o VERSION routine lets you determine which library is in use Although most people will probably use lib3d via obj3d, it is an exceptionally good idea for obj3d users to read through this document. -- As to the library, it consists of five routine groups: 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, a polygon rendering routine, and point/line drawing routines. Although the routines are based on the polygonamy routines and ideas all routines were derived and written from scratch. They are not the fastest possible routines, but I believe they the fastest routines for their size and flexibility. The library is designed to work with any VIC bank -- there is always enough room for a bitmap, and usually enough room for eight sprite definitions. -- There are ten 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 PLOT - Plot a single point DRAWLINE - Draw a line VERSION - Returns library version 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 $8800. Memory map ---------- Zero page: $41-$49 MATRIX Orientation (local rotation) matrix $4A-$52 VIEWMAT Viewpoint 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! $60-$67 X1,Y1,X2,Y2 Coordinates for PLOT and DRAWLINE routines. $8B-$8F PLISTZLO, PLISTZHI Before projecting, ROTPROJ stores the z-coordinate of each point into these lists. The obj3d library uses these to depth-arrange compound objects, for example. $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. $B1-$B8 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). $B9 BITMAP High byte of bitmap base address. $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. Library: $0200-$027F Point queue. $8400-$9FFF Routines, tables, etc. $8800 Jump table into routines Tables: $5E00-$5FFF 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 except bank 2, where lib3d is located (only enough room for a bitmap there). Library Routines ---------------- $8800 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 Cycle count: 390 cycles, worst case. $8803 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 stored. These routines are necessary to do independent 3d rotations (i.e. rotate around local axis). On entry: carry clear/set to indicate positive/negative rotations. .AY = address of matrix+remainder to be accumulated On exit: Accumulated matrix! Cycle count: Somewhere around 150, I think. $8806 ACCROTY Similar around y-axis $8809 ACCROTZ Similar around z-axis $880C GLOBROT Perform a global rotation of 16-bit signed coordinates (Rotate centers) Stuff to set up: MULTLO1 MULTLO2 MULTHI1 MULTHI2 = $B1-$B8 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. $880F 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. Points are first rotated by the orientation matrix at $41, then by the viewpoint matrix at $4A, then added to the object center. The z-coordinates are stored in PLISTZLO/HI, and the points are then projected, with the results stored in PLISTXLO/HI and PLISTYLO/HI. The _length_ of a vertex vector (sqrt(x^2 + y^2 + z^2)) must be less than 95. Stuff to set up: Orientatin and viewpoint matrix = $41-$52 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, PLISTZLO = $8B-$8E 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. $8812 POLYFILL Draw pattern-filled polygon into bitmap. Stuff to set up: MULTLO1, MULTLO2, MULTHI1, MULTHI2 = $B1-$B8 BITMAP = $B9 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. $8815 PLOT Plot a point to the bitmap To set up: BITMAP = $B9 X1,Y1 = $60,$62 = (signed) 16-bit coordinates. FILLPAT = $BB-$BC -- point is ANDED with fill pattern before plotting. On exit: Plotted point! $8818 DRAWLINE Draw a line between two points. Note that this is not the fastest routine around; it was designed more for compactness than efficiency (but is still reasonably fast!). To set up: BITMAP = $B9 X1,Y1,X2,Y2 = $60,$62,$64,$66 = (signed) 16-bit coordinates. FILLPAT = $BB-$BC -- point is ANDED with fill pattern before plotting. On exit: line drawn from X1,Y1 to X2,Y2. Note that off-screen coordinates are allowed. **NOTE** In both PLOT and DRAWLINE, the coordinates are *16-bits* -- make sure the high bytes are set correctly! $881B VERSION Returns version number of library On entry: On exit: version number returned in .A High bit set -> multicolor, so currently VERSION will either return $02 or $82.