*-------------------------------
*
* objects.s
*
* These are the routines which set up the objects for
* the main program. It is always assumed that the
* w-coordinate of the first point of any object
* will eventually be one (24 actually), so the calling
* routine will know when the object has been completely
* defined (and subsequently skip these routines).
*
* To "grow" an object these guys simply start a coordinate
* at zero and gradually ramp it up to 24.
*
* Stephen L. Judd
* 6/15/96
*
* History:
* 6/15 -Split into object file, cleaned up a few things
* 6/21 -Added objects and sneaky-pete definition algy
* 6/22 -Added dotted line capability. To make things
* more comprehensible, lines connecting "inner"
* and "outer" portions, e.g. points with w=1
* to points with w=-1, are drawn dotted. See
* object 3 definition list for more info.
* 6/23 -Added the remaining objects
DSK "objects"
REL
* Constants
BUFF1 EQU $3000 ;First character set
BUFF2 EQU $3800 ;Second character set
SINTAB EQU $C000 ;Table of sines
HISIN EQU $60 ;Sin table currently starts at $6000
OBLISTW EQU $C400 ;The actual object points
OBLISTX EQU $C480
OBLISTY EQU $C500
OBLISTZ EQU $C580
PLISTW EQU $C600 ;List of rotated+projected points
PLISTX EQU $C680
PLISTY EQU $C700
PLISTZ EQU $C780
BITP EQU $C800 ;Bit table for line routine
LO40 EQU $C900 ;Tables of 40*x/8
HI40 EQU $C980 ;To locate offset into buffer
LO96 EQU $CA00 ;for a given column
HI96 EQU $CA80
REVLIST EQU $CB00 ;Used by symmetry routine
CONLIST1 EQU $CC00 ;First point in connection list
CONLIST2 EQU $CD00 ;Second point in connection list
DRAWCON EQU $CE00 ;List of connection indices
CONFLAG EQU $CF00 ;Flags to keep from redrawing stuff
SCRNLOC EQU 1024 ;Where is the screen located?
* Some variables
COLSTEP = $51 ;Lines: How many bytes per col
COUNTPTS = $52
WXINC = $53
XYINC = $54
YZINC = $55
XZINC = $56
SWX = $63
SXY = $64 ;These are the angles used by
SYZ = $65 ;ROTPROJ
SXZ = $66
NUMOB1 EQU $A5 ;Number of points in object 1
NUMOB12 EQU $A6
TOTNUM EQU $A7 ;Total number of points in list
OFFSET EQU $A8 ;Offset into grid
NUMCONS EQU $A9 ;Total number of connections
IMONOB EQU $B0 ;Which object am I on?
SIN1 EQU $57 ;Pointers to sine and cosine
COS1 EQU $59 ;tables.
SIN2 EQU $5B
COS2 EQU $5D
PROJTAB EQU $5F ;Pointer to projection tables
POINT1 EQU $6A ;Some spare pointers
POINT2 EQU $6C
SCREENP EQU $6E ;Pointer used by screen plotter
COLORP EQU $70 ;pointer into color RAM
COLOR EQU $72 ;Color to store in color RAM
NUMSIDE EQU $8B ;# of chars per side of square
NUMTOROT EQU $69 ;Number of points to rotate in ROTPROJ
BUFFER EQU $A3 ;Pointer to drawing buffer
X1 EQU $FB ;Points for drawing a line
Y1 EQU $FC ;These zero page addresses
X2 EQU $FD ;don't conflict with BASIC
Y2 EQU $FE
OLDX EQU $FD
CHUNK EQU $FE
DX EQU $67
DY EQU $68
TEMP1 EQU $FB ;Of course, could conflict with x1
TEMP2 EQU $FC ;Temporary variables
ZTEMP EQU $02 ;Used for buffer swap. Don't touch.
ACC EQU $22 ;Used by math routine
AUX EQU $24
EXT EQU $26
*-------------------------------
*
* SETCONS
*
* This procedure sets up connection lists
*
* Inputs:
* NUMCONS contains total number of connections
* PLISTW contains the connection list, e.g. OB1CON
* PLISTY contains the normal-connection list e.g. NORM1
*
* It really is faster and shorter to just copy the lists.
* On exit, CONLIST1, CONLIST2, and DRAWCON are set up.
*
SETCONS
LDX #00 ;Now set up connections
LDY #00
:L3 LDA PLISTW,Y ;First point
STA CONLIST1,X
INY
LDA PLISTW,Y ;Second point
STA CONLIST2,X
INY
INX
CPX NUMCONS ;Total number of connections
BNE :L3
;Finally, set up the normal connections
LDX #00
:L4 TXA ;(Start with a list of the 4D cons)
STA DRAWCON,X
INX
CPX PLISTY ;Number of 4D connections
BNE :L4
LDY #00 ;Now finish up the list
:L5 LDA PLISTY+2,Y
STA DRAWCON,X
INX
INY
CPY PLISTY+1 ;The number of points in the list
BNE :L5
RTS
*-------------------------------
*
* GROW
*
* This subroutine "grows" the points, by ramping them
* outwards from the origin. By use of a mask it is
* possible to grow subsets of points at a time.
*
* On entry, Y contains the number of points to grow-1 (0..Y),
* POINT1 is set up as a pointer to the point list,
* and A contains a mask.
*
* The point list works as follows: there are a total of
* four coordinates for each vertex, and each coordinate is
* either 0, 1, or -1. Thus we can represent each coordinate
* by two bits, and the full vector may be represented by a
* single byte. Let 00=0, 01=1, and 11=-1, then an entry
* like
* 01100000 = $60
* would correspond to a vertex at (w,x,y,z)=(1,-1,0,0).
*
* The subroutine takes this number, ANDs it with the mask
* stored in TEMP1, and parses the resulting value. If
* a coordinate is 1, then the corresponding coordinate in
* the point list (OBLISTW, etc.) is incremented. If
* a coordinate is -1, OBLISTW is decremented. If 0, then
* it is ignored. In this way, individual points may be
* grown outwards, from 0 to 24. By using the mask it is
* possible to grow, say, only the x-coordinates, or only
* positive coordinates.
*
GROW
STA TEMP1
:LOOP TYA
TAX
LDA (POINT1),Y
AND TEMP1
:CHECKW ASL
BCC :POSW
ASL ;Just assume negative
DEC OBLISTW,X
BNE :CHECKX
:POSW ASL
BCC :CHECKX
INC OBLISTW,X
:CHECKX ASL
BCC :POSX
ASL
DEC OBLISTX,X
BNE :CHECKY
:POSX ASL
BCC :CHECKY
INC OBLISTX,X
:CHECKY ASL
BCC :POSY
ASL
DEC OBLISTY,X
BNE :CHECKZ
:POSY ASL
BCC :CHECKZ
INC OBLISTY,X
:CHECKZ ASL
BCC :POSZ
ASL
DEC OBLISTZ,X
BNE :DONE
:POSZ ASL
BCC :DONE
INC OBLISTZ,X
:DONE DEY
BPL :LOOP
RTS
*-------------------------------
*
* Define objects
*
* This next procedure is the prototypical procedure
* for setting up and defining a particular object group.
* It does so by "growing" the points and setting angles
* appropriately. When done, there is a complete point
* list to be rotated, etc.
* NUMOB1 -- Number of points in object one
* TOTNUM -- Total number of points to be rotproj'd
DEFOBS ENT
LDA IMONOB
BNE :CHECK1
JMP DEFOB0
:CHECK1 CMP #1
BNE :CHECK2
JMP DEFOB1
:CHECK2 CMP #2
BNE :CHECK3
JMP DEFOB2
:CHECK3
*
* DEFOB3 -- Set up object #3, a cube
*
DEFOB3
:INIT
LDA #30 ;Sixteen 4D, eight 3D+six normals
CMP TOTNUM
BEQ :GROW ;Only run the init routine once
STA TOTNUM
LDA #16
STA NUMOB1 ;Primary (4D)
LDA #14
STA NUMOB12 ;Secondary (3D) + normals
LDA #44
STA NUMCONS ;44 connections (0..43)
LDA #$F8 ;This keeps the 3D object from
LDX #8 ;getting too big (sneaky, eh)
:L1 STA OBLISTW+15,X
DEX
BNE :L1
* Set up the connection lists
*OB1CON -> PLISTW, 44 pts
*NORM1 -> PLISTY, 40 pts total
LDY #87 ;44*2 points per connection
:LOOP LDA OB3CON,Y
STA PLISTW,Y
LDA NORM3,Y ;Yeah, so we copy a bunch of
STA PLISTY,Y ;extra junk, big whoop.
DEY
BPL :LOOP
JSR SETCONS
*
* I assume normals have been cleared out by calling routine
*
LDA #24 ;Now set up the normals
STA OBLISTX+24 ;+/- 1,0,0 etc. for a cube
STA OBLISTY+26
STA OBLISTZ+28
LDA #256-24
STA OBLISTX+25
STA OBLISTY+27
STA OBLISTZ+29
:GROW
LDA #VERT3
STA POINT1+1
LDY #23 ;Number of points to grow 0..Y
* Grow the x-coords first.
:XCOORDS LDA OBLISTX
CMP #24
BEQ :YCOORDS
LDA #%00110000 ;Mask
JMP GROW ;GROW will RTS for us.
:YCOORDS LDA OBLISTY
CMP #24
BEQ :ZCOORDS
LDA #%00001100
JMP GROW
:ZCOORDS LDA OBLISTZ ;Have I hit 24 (max value) yet?
CMP #24
BEQ :WCOORDS
INC SXY ;Make the object a little
INC SYZ ;nicer looking.
LDA #%00000011
JMP GROW
:WCOORDS LDA OBLISTW
CMP #23
BNE :CONT
LDY #$FF
STY XYINC
LDY #01 ;Start the angles going
STY WXINC
STY YZINC
INY
STY XZINC
:CONT
LDA #%11000000
JMP GROW
*
* This is the list of vertices, as described in GROW above.
* 00 = 0, 01 = 1, 11 = -1
*
VERT3 DFB %01010101 ;1,1,1,1
DFB %01010111 ;1,1,1,-1
DFB %01011101
DFB %01011111
DFB %01110101
DFB %01110111
DFB %01111101
DFB %01111111
DFB %11010101 ;-1,1,1,1
DFB %11010111
DFB %11011101
DFB %11011111
DFB %11110101
DFB %11110111
DFB %11111101
DFB %11111111 ;-1,-1,-1,-1 end of 4D cube list
DFB %00010101 ;0,1,1,1 3D cube
DFB %00010111
DFB %00011101
DFB %00011111
DFB %00110101
DFB %00110111
DFB %00111101
DFB %00111111 ;end of 3D cube list, 24 points total
*
* These are the connections between points
*
* Remember that these are INDICES into the WHOLE point
* list, not just a local point!!!
*
* These connections are all placed into a list which may
* be accessed by the main drawing routine. Then the
* normals are placed in their own list, along with
* indices into the connection list. The normal list works
* as follows:
*
* The first set of numbers indexes directly into the
* primary object connections -- there are no normals
* to worry about, and this allows the objects to be
* transparently handled by the drawing routine. Otherwise
* each face of the secondary is handled the same:
* The first number is the index to the normal in the point
* list (PLIST). Following this index is a list of indices
* into the connection list -- these connections make up the
* face which belongs to the normal. This connection list
* is terminated by a zero, and followed by other normal
* lists. The whole thing is terminated with a second zero.
*
* Thus the drawing routine works as follows: connections
* from the connection list are successively read in and
* joined, until a zero is hit. The next point is then
* read in as a normal index. If zero, then we are done,
* otherwise this normal is checked to see if the face
* is visible. If not then it skips to the next point,
* otherwise it does the drawing thing above.
*
* As each connection is drawn a corresponding flag is
* set in a similar connection list. This way, connections
* shared between visible faces do not need to be drawn twice.
*
* New feature: now connections may be drawn using either
* solid or dotted lines. The cube does not need it, but
* it helps immensely with the others to draw lines connecting
* "inner" and "outer" objects with dotted lines, to see how
* things change when they start to turn inside-out. Since there
* are not going to be more than 127 connections, the high
* bit of the connection index serves as a dotted line flag:
* if the high bit of the index is set, then draw the connecting
* line as dotted. Hence the drawing routine only needs to
* strip off this bit and set the flag DOTTED accordingly.
OB3CON HEX 0001000200040008 ;0-1 0-2 0-4 0-8
HEX 010301050109 ;1-3 1-5 1-9
HEX 02030206020A ;2-3 2-6 2-A
HEX 0307030B ;3-7 3-B
HEX 04050406040C ;4-5 4-6 4-C
HEX 0507050D ;5-7 5-D
HEX 0607060E ;6-7 6-E
HEX 070F ;7-F
HEX 0809080A080C ;8-9 8-A 8-C
HEX 090B090D ;9-B 9-D
HEX 0A0B0A0E ;a-b a-e
HEX 0B0F ;b-f
HEX 0C0D0C0E ;c-d c-e
HEX 0D0F
HEX 0E0F
OB32CON ;3D cube
HEX 101110121014 ;16-17 16-18 16-20
HEX 11131115 ;17-19 17-21 (35)
HEX 12131216 ;18-19 18-22
HEX 1317 ;19-23 (39)
HEX 14151416 ;20-21 20-22
HEX 1517 ;21-23 (42)
HEX 1617 ;22-23
* 4D: 32 connections, 3D: 12 connections
NORM3 ;List of normals + connections
HEX 20 ;First number is number of 4D cons
DFB 38 ;Second number is number of points
;in list, below
HEX 0018 ;Normal 1 at index 24 = 1,0,0
DFB 32 ;16-17
DFB 33 ;16-18
DFB 35 ;17-19
DFB 37 ;18-19
HEX 0019 ;Normal #2 = -1,0,0
DFB 40 ;20-21
DFB 41 ;20-22
DFB 42 ;21-23
DFB 43 ;22-23
HEX 001A ;Normal #3= 0,1,0
DFB 32
DFB 36
DFB 40
DFB 34
HEX 001B ;Normal 4= 0,-1,0
DFB 37
DFB 38
DFB 39
DFB 43
HEX 001C ;Normal 5= 0,0,1
DFB 33
DFB 34
DFB 41
DFB 38
HEX 001D ;Normal 6= 0,0,-1
DFB 35
DFB 36
DFB 39
DFB 42
HEX 0000 ;End o' the list
*-------------------------------
*
* DEFOB0 -- Set up object #0, a tetrahedron
*
* This is one of the objects I derive from the cube
* vertices.
*
* Vertices are all "two away" from each other on the cube.
* Starting from a 3D cube, one such set of points is
* (1,1,1) (1,-1,-1) (-1,1,-1) and (-1,-1,1) -- to get
* from one point to the next requires traversing two
* line segments on the cube. Generalizing to 4D, I
* again use a set of points on the cube which differ
* in two coordinates and in 4 coordinates, e.g. starting
* from (1,1,1,1) the two-away points are (1,1,-1,-1) etc.
* and the four-away point is (-1,-1,-1,-1).
*
* If you want to be more specific, I think this forms a
* complete set of points equivariant under the action of
* the relevant symmetry group (acting on one point with
* a symmetry operator generates another point in the set).
*
* Another way of looking at it is that I slice off corners
* of the cube which aren't adjacent to each other.
*
* Note that normals correspond exactly to the 3D points.
* That is, of any face formed by three points, the fourth
* forms a vector normal to the face (albeit pointing
* away from it).
*
DEFOB0
:INIT
LDA #16 ;8 4D, 4 3D+4 normals
CMP TOTNUM
BEQ :GROW ;Only run the init routine once
STA TOTNUM
LSR ;I need those bytes!!!
* LDA #8
STA NUMOB1 ;Primary (4D)
* LDA #8
STA NUMOB12 ;Secondary (3D) + 4 normals
LDA #30
STA NUMCONS ;30 connections (0..29)
LDX #4
LDA #$F8 ;Make object a little smaller
:L1 STA OBLISTW+7,X
DEX
BNE :L1
* Set up the connection lists
*OB0CON -> PLISTW, 30 connections (2 pts per con)
*NORM0 -> PLISTY, 24 pts total
LDY #59 ;30*2
:LOOP LDA OB0CON,Y
STA PLISTW,Y
LDA NORM0,Y
STA PLISTY,Y
DEY
BPL :LOOP
JSR SETCONS
*
* Set which connections will use dotted lines
* Dotted cons are: 0-4 0-5 0-6 1-4 1-5 1-7 2-4 2-6 2-7
* 3-5 3-6 3-7
LDY #11
:L2 LDA DOTCON0,Y
TAX
LDA DRAWCON,X
ORA #$80
STA DRAWCON,X
DEY
BPL :L2
:GROW
LDA #VERT0
STA POINT1+1
LDY #15 ;Number of points to grow 0..Y
LDA #$FF ;Grow all coords equally
JMP GROW
*
* Next the vertex list
*
VERT0 DFB %01010101 ;1,1,1,1
DFB %01011111
DFB %01110111
DFB %01111101
DFB %11010111
DFB %11011101
DFB %11110101
DFB %11111111 ;End of 4D points
DFB %00010101
DFB %00011111
DFB %00110111
DFB %00111101 ;12 points total
DFB %00111111
DFB %00110101
DFB %00011101
DFB %00010111 ;Plus four normals
OB0CON HEX 000100020003000400050006 ;0-1 0-2 0-3 0-4 0-5 0-6
HEX 01020103010401050107 ;1-2 1-3 1-4 1-5 1-7
HEX 0203020402060207 ;2-3 2-4 2-6 2-7
HEX 030503060307 ;3-5 3-6 3-7
HEX 040504060407
HEX 05060507
HEX 0607 ;4D connections (24)
OB02CON HEX 0809080A080B ;8-9 8-10 8-11
HEX 090A090B
HEX 0A0B ;3D connections (6)
DOTCON0 HEX 030405 ;These connections will be dotted
HEX 08090A ;they connect points with w=1 to
HEX 0C0D0E ;points with w=-1
HEX 0F1011 ;12 total
NORM0 ;Normals+corresponding connections
DFB 24 ;Number of 4D connections
DFB 22 ;Number of points below
HEX 000C ;Normal at index 12 = 1,1,1
DFB 27 ;9-10
DFB 28 ;9-11
DFB 29 ;10-11
HEX 000D ;Normal 1,-1,-1
DFB 25
DFB 26
DFB 29
HEX 000E ;Normal -1,1,-1
DFB 24 ;8-19
DFB 26 ;8-11
DFB 28 ;9-11
HEX 000F ;Normal -1,-1,1
DFB 24 ;8-9
DFB 25 ;9-10
DFB 27 ;9-10
HEX 0000 ;22 points in list
*-------------------------------
*
* DEFOB2
*
* Set up object #2, an octahedron.
*
* What in the world is the 4D analong of an octahedron?
*
* There are two ways of looking at this. A 3D octahedron
* has coordinates (+/-1,0,0) (0,+/-1,0) (0,0,+/-1), so
* one possibility to extend this is an object with
* coordinates at (+/-1,0,0,0) (0,+/-1,0,0) etc.
*
* On the other hand, the octahedron is easily derived
* from the cube, by joining the centers of each face
* of the cube (cutting off the corners, if you like).
* Thus it is easy enough to extend this into 4D by joining
* the centers of each 2D face of the 4D cube, which leads
* to points like (+/-1,+/-1,0,0) (+/-1,0,+/-1,0) etc.
*
* The first method is analogous to joining the center of
* each 3D cross-section of the 4D cube, whereas the second
* method is, as was stated, joining the centers of each
* 2D cross-section -- the centers of cubes versus the centers
* of planes.
*
* Which method to use? The second method generates 24 vertices
* with 96 line segments joining them all. I can see what it
* looks like in my head, I have drawn a picture, and I have
* written down all the points and line connections. Although
* it really is pretty straightforward to visualize, it seems
* obvious to me that on the computer it will look like a real
* mess, especially on just a 96x96 grid, even with dotted lines.
* Moreover, I *do* only have 4k to work with, and the 12-sided
* object will be a doozy with 96 connections and such, so
* I just use the object from the first method.
*
* (The second method is awfully cool to think about, though,
* not to mention neat-o keen to look at!)
*
DEFOB2
:INIT
LDA #22 ;8 4D, 6 3D + 8 normals
CMP TOTNUM
BEQ :GROW ;Only run the init routine once
STA TOTNUM
LDA #8
STA NUMOB1 ;Primary (4D)
LDA #14
STA NUMOB12 ;Secondary (3D) + normals
LDA #24+12
STA NUMCONS ;36 connections
LDX #6
LDA #$F6 ;Make 3D object a little smaller
:L1 STA OBLISTW+7,X
DEX
BNE :L1
* Set up the connection lists
*OB2CON -> PLISTW, 36 connections (2 pts per con)
*NORM2 -> PLISTY, 44 pts total
LDY #71 ;36*2
:LOOP LDA OB2CON,Y
STA PLISTW,Y
LDA NORM2,Y
STA PLISTY,Y
DEY
BPL :LOOP
JSR SETCONS
*
* Set which connections will use dotted lines
* In this case, lines connecting a point to
* another point with nonzero w-coordinate.
*
LDY #11 ;I stuck them in the first
:L2 LDA DRAWCON,Y ;twelve slots
ORA #$80
STA DRAWCON,Y
DEY
BPL :L2
:GROW
LDA #VERT2
STA POINT1+1
LDY #22 ;Number of points to grow 0..Y-1
LDA #$FF ;Grow all coords equally
JSR GROW
*
* This object is a little smaller than the others,
* so I cheat a little and jump both objects out
* a little farther once they're done growing.
*
* Sproing!
*
LDA OBLISTW
CMP #24
BNE :DONE
LDX #13
:L3 ASL OBLISTW,X
ASL OBLISTX,X ;close to the edge
ASL OBLISTY,X ;(down by a river?)
ASL OBLISTZ,X
DEX
BPL :L3
:DONE RTS
*
* Next the vertex list
*
VERT2 DFB %01000000
DFB %11000000
DFB %00010000
DFB %00110000
DFB %00000100
DFB %00001100
DFB %00000001
DFB %00000011 ;4D vertices
DFB %00010000
DFB %00110000
DFB %00000100
DFB %00001100
DFB %00000001
DFB %00000011 ;3D vertices (note same as above)
DFB %00010101
DFB %00010111
DFB %00011101
DFB %00011111
DFB %00110101
DFB %00110111
DFB %00111101
DFB %00111111 ;And the normals ->22 total
*
* Connections
*
OB2CON HEX 000200030004000500060007 ;02 03 04 05 06 07
HEX 010201030104010501060107 ;These will be dotted
HEX 0204020502060207
HEX 0304030503060307
HEX 04060407
HEX 05060507 ;4D connections (24 total)
OB22CON HEX 080A080B080C080D ;8-10 8-11 8-12 8-13
HEX 090A090B090C090D
HEX 0A0C0A0D ;10-12 10-13
HEX 0B0C0B0D ;3D cons (12 total)
NORM2 ;Normals+corresponding connections
DFB 24 ;Number of 4D connections
DFB 42 ;Number of points below
HEX 000E ;Normal at index 14 = 1,1,1
DFB 24 ;8-10
DFB 32 ;10-12
DFB 26 ;12-8
HEX 000F
DFB 24
DFB 33
DFB 27
HEX 0010
DFB 25
DFB 34
DFB 26
HEX 0011
DFB 25
DFB 35
DFB 27
HEX 0012
DFB 28
DFB 32
DFB 30
HEX 0013
DFB 28
DFB 33
DFB 31
HEX 0014
DFB 29
DFB 34
DFB 30
HEX 0015
DFB 29
DFB 35
DFB 31
HEX 0000 ;42 points in list
*-------------------------------
*
* DEFOB1
*
* Set up object #1, a fourteen-sided thing
*
* This is the wild one: 32 points and 96 connections in
* the 4D object alone. Gorgeous.
*
* This object is constructed by connecting the midpoints
* of each line segment on the cube. This amounts to
* setting one of the coordinates of a cube vertex to zero,
* and of course gives four points for each face of the
* cube. Example 4D coordinates are (1,1,1,0) (1,-1,0,1)
* (-1,0,-1,1) etc.
*
* In three dimensions, this has the effect of lopping the
* corners of the cube off (of course not as drastically
* as with the tetragon), leaving diamonds where the cube
* faces used to be and triangles where the corners used
* to be.
*
* The solid lines are the "inner" and "outer" 14-gons,
* and the dotted lines are all the "middle" 14-gons
* that you get in-between the inner and outer guys.
*
* One other thing to note is that the normals are a little
* different for this one. The hidden face algorithm depends
* on the dot product of the normal vector with a point
* being a particular constant. That is, one normal vector
* is (1,0,0) and it is dotted into (1,1,0), giving 1.
* (1,0,0) is a normal vector for the ex-cube face (now
* a diamond). A normal vector to the triangles, though,
* looks like (1,1,1), i.e. where the old cube vertex used
* to be. When dotted into (1,1,0) this gives 2, a different
* constant. To fix this up, the normals need to be halved,
* that is, instead of (1,1,1) it will be (1/2, 1/2, 1/2).
* Now the dot product is 1 again, and we don't need to
* special-case the hidden face algorithm.
*
DEFOB1
:INIT
LDA #58 ;32 4D, 12 3D + 14 normals
CMP TOTNUM
BEQ :GROW ;Only run the init routine once
STA TOTNUM
LDA #32
STA NUMOB1 ;Primary (4D)
LDA #12+8+6
STA NUMOB12 ;Secondary (3D) + normals
LDA #120
STA NUMCONS ;120 connections
LDX #12
LDA #$F8 ;Make 3D object a little smaller
:L1 STA OBLISTW+31,X
DEX
BNE :L1
* Set up the connection lists
*OB1CON -> PLISTW, 120 connections (2 pts per con)
*NORM1 -> PLISTY, 80 pts total
LDY #00
:LOOP LDA OB1CON,Y
STA PLISTW,Y
LDA NORM1,Y
STA PLISTY,Y
INY
CPY #240 ;120*2
BNE :LOOP
JSR SETCONS
*
* Set which connections will use dotted lines
* In this case, lines connecting a point to
* another point with nonzero w-coordinate.
*
LDY #24 ;I stuck them in slots 24-71
:L2 LDA DRAWCON,Y
ORA #$80
STA DRAWCON,Y
INY
CPY #72
BNE :L2
*
* Set up the normals
*
* There are two sets of normals. The first set correspond
* to the vertices of a cube (divided by two) and the
* second set lie on the coordinate axes.
*
LDY #256-12 ;Saves a byte (yow!!!!!)
LDX #07 ;First set
:L4 STX TEMP1 ;Let X bit=0 correspond to +1/2
LSR TEMP1 ;and bit=1 correspond to coord -1/2
LDA #12 ;Coords max out at 24
BCC :CONT1 ;half of which is 12
TYA
:CONT1 STA OBLISTZ+44,X ;Normals start at point 44
LSR TEMP1
LDA #12
BCC :CONT2
TYA
:CONT2 STA OBLISTY+44,X
LSR TEMP1
LDA #12
BCC :CONT3
TYA
:CONT3 STA OBLISTX+44,X
DEX
BPL :L4
LDA #24 ;Now do second set
STA OBLISTX+52 ;(1,0,0)
STA OBLISTY+53 ;(0,1,0)
STA OBLISTZ+54 ;(0,0,1)
LDA #256-24
STA OBLISTX+55 ;(-1,0,0)
STA OBLISTY+56 ;(0,-1,0)
STA OBLISTZ+57 ;(0,0,-1)
:GROW
LDA #VERT1
STA POINT1+1
LDY #44 ;Number of points to grow 0..Y-1
LDA #$FF ;Grow all coords equally
JMP GROW
*
* Next the vertex list
*
VERT1 DFB %01000101 ;(1,0,1,1)
DFB %01000111 ;(1,0,1,-1)
DFB %01001111 ;(1,0,-1,-1)
DFB %01001101 ;(1,0,-1,1)
DFB %01010001 ;(1,1,0,1)
DFB %01010011 ;etc
DFB %01110011
DFB %01110001 ;7
DFB %01010100
DFB %01011100
DFB %01111100
DFB %01110100
DFB %11000101
DFB %11000111
DFB %11001111
DFB %11001101 ;15
DFB %11010001
DFB %11010011
DFB %11110011
DFB %11110001
DFB %11010100
DFB %11011100
DFB %11111100
DFB %11110100 ;23
DFB %00010101
DFB %00010111
DFB %00011111
DFB %00011101
DFB %00110101
DFB %00110111
DFB %00111111
DFB %00111101 ;31, end of 4D points
DFB %00000101
DFB %00000111
DFB %00001101
DFB %00001111
DFB %00010001
DFB %00010011
DFB %00010100
DFB %00011100 ;39
DFB %00110001
DFB %00110011
DFB %00110100
DFB %00111100 ;43, end of 3D points
;Normals set up by routine above
*
* Connections
*
OB1CON HEX 0008000B00040007 ;0-8 0-11 0-4 0-7
HEX 0108010B01050106 ;1-8 1-11 1-5 1-6
HEX 0209020A02050206
HEX 030403070309030A
HEX 04080409
HEX 05080509
HEX 060A060B
HEX 070A070B ;Outer 12-gon, 24 cons
HEX 0018001C ;0-24 0-28
HEX 0119011D ;1-25 1-29
HEX 021A021E
HEX 031B031F
HEX 0418041B ;All these middle guys are
HEX 0519051A ;dotted connections
HEX 061D061E
HEX 071C071F
HEX 08180819 ;8-24 8-25
HEX 091A091B
HEX 0A1E0A1F
HEX 0B1C0B1D ;11-28 11-29, Outer->middle, 24 cons
HEX 0C180C1C
HEX 0D190D1D
HEX 0E1A0E1E ;14-26 14-30
HEX 0F1B0F1F
HEX 1018101B
HEX 1119111A
HEX 121D121E
HEX 131C131F
HEX 14181419
HEX 151A151B
HEX 161E161F
HEX 171C171D ;23-28 23-29, middle->inner, 24 more cons
HEX 0C140C170C100C13 ;And finally, the inner cons
HEX 0D140D170D110D12
HEX 0E150E160E110E12
HEX 0F100F130F150F16
HEX 10141015
HEX 11141115
HEX 12161217
HEX 13161317 ;Inner, the last 24 connections
;For a total of 96 4D connections
OB12CON HEX 20242028 ;32-36 32-40 (3D connections)
HEX 2026202A ;32-38 32-42 (last but not least)
HEX 21252129 ;33-37 33-41
HEX 2126212A
HEX 22242228
HEX 2227222B
HEX 23252329
HEX 2327232B
HEX 24262427
HEX 25262527
HEX 282A282B
HEX 292A292B ;24 more 3D connections, for a total
;of 120 connections, just shy of the
;BMI mark!
NORM1 ;Normals+corresponding connections
DFB 96 ;Number of 4D connections
DFB 78 ;Number of points below
DFB 00
DFB 44 ;Normal at index 44 = 1/2,1/2,1/2
DFB 96 ;32-36
DFB 112 ;36-38
DFB 98 ;38-32
HEX 002D ;Index 45
DFB 100
DFB 114
DFB 102
HEX 002E ;46
DFB 104
DFB 113
DFB 106
HEX 002F ;47
DFB 108
DFB 115
DFB 110
HEX 0030 ;48
DFB 97
DFB 116
DFB 99
HEX 0031 ;49
DFB 101
DFB 118
DFB 103
HEX 0032 ;50
DFB 105
DFB 117
DFB 107
HEX 0033 ;51
DFB 109
DFB 119
DFB 111
HEX 0034 ;52, the diamonds
DFB 112
DFB 114
DFB 115
DFB 113
HEX 0035 ;53
DFB 98
DFB 102
DFB 103
DFB 99
HEX 0036 ;54
DFB 96
DFB 104
DFB 105
DFB 97
HEX 0037 ;55
DFB 116
DFB 118
DFB 119
DFB 117
HEX 0038 ;56
DFB 106
DFB 110
DFB 111
DFB 107
HEX 0039 ;57, last one!
DFB 100
DFB 108
DFB 109
DFB 101
HEX 0000 ;6*6+8*5+2=78 points in list