*-------------------------------
*
* 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       
         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       
         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       
         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       
         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
