home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / OUT.ZIP / SOURCE.ZIP / HFLYCORE.S < prev    next >
Text File  |  2003-07-12  |  29KB  |  1,042 lines

  1. *==========================================================================*
  2. *                                                      .                   *
  3. *                       .    .   !       '       .                         *
  4. *                        \.  ' ! | | '   | !   ' |   /                     *
  5. *                         \\=|=|=|=|=|=|=|=|=|=|=|=//                      *
  6. *                          \\ >>> HUMAN - FLY <<< //                       *
  7. *                          // Falcon030 3D engine \\                       *
  8. *                         //=|=|=|=|=|=|=|=|=|=|=|=\\                      *
  9. *                        /   . | !   ! |   ' | !    '                      *
  10. *                       '    ' ! '   ' !     ! '      '                    *
  11. *                      /                                                   *
  12. *                                  <v2.1>                                  *
  13. *         3D world engine and rendering pipeline for ATARI Falcon          *
  14. *==========================================================================*
  15. *                            CPU CORE ROUTINES                             *
  16. *                                                                          *
  17. * This contains no implementation specific routines, such as primitive     *
  18. * painters, dsp comms. or fpu code.                                        *
  19. * Only the core doing all the high parts of the pipeline.                  *
  20. * In order to use Human Fly, all interfaces defined here must be           *
  21. * implemented.                                                             *
  22. *--------------------------------------------------------------------------*
  23. * All interfaces are finalized. Objects implementing these interfaces      *
  24. * should not deviate from them.                                            *
  25. * Finalized objects: (already implemented here!)                           *
  26. * - KeyFramer                                                              *
  27. * - MeshElement                                                            *
  28. * - Primitive                                                              *
  29. * - Quaternion                                                             *
  30. * - QuatKey                                                                *
  31. * - QuatKeyEntry                                                           *
  32. * - QuatKeyBuf                                                             *
  33. * - Vertex                                                                 *
  34. * - Vertex2d                                                               *
  35. * - VertexKey                                                              *
  36. * - VertexKeyEntry                                                         *
  37. * - VertexKeyBuf                                                           *
  38. * - WorldNode                                                              *
  39. * - WorldTree                                                              *
  40. * Objects/subroutines outside core, _must_ be implemented:                 *
  41. * - Line:                                                                  *
  42. *   .paint                                                                 *
  43. *   .paintFlat                                                             *
  44. *   .paintGouraud                                                          *
  45. *   .paintPhong                                                            *
  46. * - Matrix:                                                                *
  47. *   .convertQuaternion                                                     *
  48. *   .generate                                                              *
  49. *   .pop                                                                   *
  50. *   .push                                                                  *
  51. * - ObjectRegistry:                                                        *
  52. *   .set                                                                   *
  53. *   .clear                                                                 *
  54. *   .replace                                                               *
  55. * - Polygon:                                                               *
  56. *   .init                                                                  *
  57. *   .paintFlat                                                             *
  58. *   .paintGouraudshaded                                                    *
  59. *   .paintTextured                                                         *
  60. *   .paintAlphatextured                                                    *
  61. *   .paintBumpmapped                                                       *
  62. *   .paintClippedFlat                                                      *
  63. *   .paintClippedGouraudshaded                                             *
  64. *   .paintClippedTextured                                                  *
  65. *   .paintClippedAlphatextured                                             *
  66. *   .paintClippedBumpmapped                                                *
  67. *   .registerBumpmap                                                       *
  68. * - Primitive:                                                             *
  69. *   .setPaintMode                                                          *
  70. *   .setScreenbuffer                                                       *
  71. * - PrimitiveMesh:                                                         *
  72. *   .new:                                                                  *
  73. *   .sortZ:                                                                *
  74. *   .paint:                                                                *
  75. *   .paintUnclipped:                                                       *
  76. * - Sprite:                                                                *
  77. *   .clipAndPaint                                                          *
  78. * - TransformObject:                                                       *
  79. *   .transform                                                             *
  80. * - Viewport:                                                              *
  81. *   .paintRectangle                                                        *
  82. *   .update                                                                *
  83. *==========================================================================*
  84.  
  85. ******** GLOBAL MACROS ********
  86.  
  87. ******** HumanFly
  88.  
  89. HumanFly:
  90.  
  91. * Initialises global parts of the pipeline.
  92. ;HumanFly.init:
  93.  
  94. ******** Rectangle
  95.  
  96.         RSRESET
  97. Rectangle.Y0:    RS.W    1
  98. Rectangle.Y1:    RS.W    1
  99. Rectangle.X0:    RS.W    1
  100. Rectangle.X1:    RS.W    1
  101. Rectangle.SIZE:    RS.B    0
  102.  
  103. ******** WorldNode
  104.  
  105.             RSRESET
  106. WorldNode.OBJECTADR:    RS.L    1
  107. WorldNode.MATRIXADR:    RS.L    1
  108. WorldNode.ARRAYADR:    RS.L    1
  109. WorldNode.SIZE:        RS.B    0
  110.  
  111. * Creates a new node with the specified parameters.
  112. WorldNode_new:    MACRO    NodeAdr,ObjectAdr,ArrayAdr
  113.     move.l    \1,a0
  114.     move.l    \2,WorldNode.OBJECTADR(a0)
  115.     move.l    \3,WorldNode.ARRAYADR(a0)
  116.     movea.l    WorldNode.ARRAYADR(a0),a0
  117.     clr.w    (a0)
  118.     ENDM
  119.  
  120. * Returns the number of children this node has.
  121. * INPUT: NodeAdr: node
  122. * OUTPUT: d0.w: number of children
  123. WorldNode_getChildCount:    MACRO    NodeAdr
  124.     movea.l    \1,a0
  125.     movea.l    WorldNode.ARRAYADR(a0),a0
  126.     move.w    (a0),d0
  127.     ENDM
  128.  
  129. * Returns a child of node. No boundscheck is done.
  130. * INPUT: NodeAdr: node
  131. *        ChildIndex: index of child
  132. * OUTPUT: a0: child node
  133. WorldNode_getChild:    MACRO    NodeAdr,ChildIndex
  134.     movea.l    \1,a0
  135.     movea.l    WorldNode.ARRAYADR(a0),a0
  136.     move.w    ChildIndex,d0
  137.     movea.l    2(a0,d0.w*4),a0
  138.     ENDM
  139.  
  140. * Adds a child to node.
  141. * INPUT: ParentAdr: worldnode to add child to
  142. *        ChildAdr: child to add
  143. WorldNode_addChild:    MACRO    ParentAdr,ChildAdr
  144.     movea.l    WorldNode.ARRAYADR(\1),a0
  145.     move.w    (a0),d0
  146.     addq.w    #1,(a0)+
  147.     move.l    \2,(a0,d0.w*4)
  148.     ENDM    
  149.  
  150. * Removes child from node. No boundscheck is done.
  151. * INPUT: NodeAdr: node to remove child from
  152. *        ChildIndex: index of child
  153. WorldNode_removeChild:    MACRO    NodeAdr,ChildIndex
  154.     movea.l    WorldNode.ARRAYADR(\1),a0
  155.     move.w    \2,d0
  156.     move.w    (a0),d1
  157.     beq.s    @\end
  158.     subq.w    #1,(a0)+
  159.     lea    (a0,d0.w*4),a0
  160.      lea    4(a0),a1
  161.     sub.w    d0,d1
  162.     subq.w    #1,d1
  163.     bmi.s    @\end
  164. @\loop:    move.l    (a1)+,(a0)+
  165.     dbra    d1,@\loop
  166. @\end:
  167.     ENDM
  168.  
  169. ******** ObjectRegistry
  170.  
  171. ObjectRegistry.VERTICES:=    %001
  172. ObjectRegistry.NORMALS:    =    %010
  173. ObjectRegistry.TEXELS:    =    %100
  174.  
  175. ; TODO: maximum amount of objects!!
  176. ; Adds a 3d-object to the registry and returns a handle.
  177. ; INPUT:
  178. ; d0.l=size of object (bytes)
  179. ; a0: object
  180. ; OUTPUT:
  181. ; d0.w: >= 0: objecthandle, -1: error, not added!
  182. ;ObjectRegistry.set:
  183.  
  184. ; Returns the objectaddress of the specified handle.
  185. ; No checking for invalid handles!!
  186. ; INPUT:
  187. ; d0.w=ObjectHandle
  188. ; OUTPUT:
  189. ; a0: object
  190. ;ObjectRegistry.get:
  191.  
  192. ; Clears the registry. All handles become invalid.
  193. ;ObjectRegistry.clear:
  194.  
  195. ; Updates specified object's primitives/vertices/normals/texels.
  196. ; INPUT:
  197. ; d0.w=objecthandle
  198. ; d1.w=replacemode (%ptnv)
  199. ;ObjectRegistry.replace:
  200.  
  201. ******** Vertex
  202.  
  203.         RSRESET
  204. Vertex.X:    RS.W    1
  205. Vertex.Y:    RS.W    1
  206. Vertex.Z:    RS.W    1
  207. Vertex.SIZE:    RS.B    0
  208.  
  209. ******** Vertex2d
  210.  
  211.         RSRESET
  212. Vertex2d.X:    RS.W    1            * 8:8 fixed point
  213. Vertex2d.Y:    RS.W    1            * 8:8 fixed point
  214. Vertex2d.SIZE:    RS.B    0
  215.  
  216. ******** Primitive
  217.  
  218. ; Equates involving paintmodes.
  219. Primitive.SIZEMASK:    =    %00011
  220. Primitive.BYTE:        =    %00000
  221. Primitive.WORD:        =    %00001
  222. Primitive.24B:        =    %00010
  223. Primitive.LONG:        =    %00011
  224. Primitive.LOGICMASK:    =    %11100
  225. Primitive.LOGICSHIFT:    =    2
  226. Primitive.MOVE:        =    %00000
  227. Primitive.OR:        =    %00100
  228. Primitive.ADD:        =    %01000        ; plain add
  229. Primitive.CEILADD:    =    %01100        ; add with ceiling for r,g,b
  230.  
  231. ; Equates for palette handling.
  232. Primitive.GRADIENTBITS:    =    7
  233. Primitive.GRADIENTSIZE:    =    1<<(Primitive.GRADIENTBITS+1)
  234.  
  235.             RSRESET
  236. Primitive.TYPE:        RS.W    1        ; primitive/shading/extended type
  237.  
  238.             RSRESET
  239.             RS.W    1        ; primitive/shading/extended type
  240. Sprite.VERTEX:        RS.W    1        ; offset to vertex
  241. Sprite.SIZE:        RS.B    0
  242.  
  243.             RSRESET
  244.             RS.W    1        ; primitive/shading/extended type
  245. Line.VERTEX1:        RS.W    1        ; offset to vertex 1
  246. Line.VERTEX2:        RS.W    1        ; offset to vertex 2
  247. Line.SIZE:        RS.B    0
  248.  
  249. Primitive.SHADEMASK:    =    %1110000000000000
  250. Primitive.SHADESHIFT:    =    13
  251.  
  252. ; Shade types for sprites
  253. Sprite.REPLACED:    =    %0000000000000000
  254. Sprite.MIXED:        =    %0010000000000000
  255.  
  256. ; Shade types for polygons
  257. Line.FLATSHADED:    =    %0000000000000000
  258. Line.GOURAUDSHADED:    =    %0010000000000000
  259. Line.PHONGSHADED:    =    %0100000000000000
  260.  
  261. ; Shade types for polygons
  262. Polygon.FLATSHADED:    =    %0000000000000000
  263. Polygon.GOURAUDSHADED:    =    %0010000000000000
  264. Polygon.PHONGSHADED:    =    %0100000000000000
  265. Polygon.TEXTUREMAPPED:    =    %0110000000000000
  266. Polygon.ENVMAPPED:    =    %1000000000000000
  267. Polygon.ALPHATEXTURED:    =    %1010000000000000
  268. Polygon.BUMPMAPPED:    =    %1100000000000000
  269. Polygon.GOURAUDTEXTURED:=    %1110000000000000
  270.  
  271. ; Primitive types
  272. Primitive.TYPEMASK:    =    %0001110000000000
  273. Primitive.TYPESHIFT:    =    10
  274. Primitive.SPRITETYPE:    =    %0000000000000000
  275. Primitive.LINETYPE:    =    %0000010000000000
  276. ; Other types are polygons, %10 :== triangle, %11 :== quadrangle, etc.
  277.  
  278. ; TableLookup mask
  279. Primitive.TEXTUREMASK:    =    %0000001111111111
  280.  
  281. ; Standard Polygon types
  282. Polygon.TRI:        =    (3-1)<<Primitive.TYPESHIFT
  283. Polygon.QUAD:        =    (4-1)<<Primitive.TYPESHIFT
  284. Polygon.PENT:        =    (5-1)<<Primitive.TYPESHIFT
  285. Polygon.HEX:        =    (6-1)<<Primitive.TYPESHIFT
  286.  
  287. ; Sets paintmode. This involves pixeltype, logic op, pixelskip. For
  288. ; discription of these, see paintmode equates.
  289. ; All primitives use the settings taken by this call.
  290. ; INPUT:
  291. ; d0.w=pixeltype and logic op
  292. ; d1.w=pixelskip (number of bytes to progress after each pixel)
  293. ; OUTPUT:
  294. ; d0.w: =0: success, <0: error
  295. ;Primitive.setPaintMode:
  296.  
  297. ********* PolyPoint
  298.  
  299.         RSRESET
  300. PolyPoint.X:    RS.W    1
  301. PolyPoint.Y:    RS.W    1
  302. PolyPoint.U1:    RS.W    1
  303. PolyPoint.V1:    RS.W    1
  304. PolyPoint.U2:    RS.W    1
  305. PolyPoint.V2:    RS.W    1
  306. PolyPoint.SIZE:    RS.B    0
  307.  
  308. ********* MeshElement
  309.  
  310.             RSRESET
  311. MeshElement.BASE:    RS.L    1            * startaddress of vertex table
  312. MeshElement.REF:    RS.L    1            * address of primitive
  313. MeshElement.Z:        RS.W    1            * avg. Z coordinate of primitive
  314. MeshElement.SIZE:    RS.B    0
  315.  
  316. ******** KeyFramer
  317.  
  318.             RSRESET
  319. QuatKey.X:        RS.W    1
  320. QuatKey.GX:        RS.W    1
  321. QuatKey.Y:        RS.W    1
  322. QuatKey.GY:        RS.W    1
  323. QuatKey.Z:        RS.W    1
  324. QuatKey.GZ:        RS.W    1
  325. QuatKey.LOOKAT_X:    RS.W    1
  326. QuatKey.GLOOKAT_X:    RS.W    1
  327. QuatKey.LOOKAT_Y:    RS.W    1
  328. QuatKey.GLOOKAT_Y:    RS.W    1
  329. QuatKey.LOOKAT_Z:    RS.W    1
  330. QuatKey.GLOOKAT_Z:    RS.W    1
  331. QuatKey.LOOKAT_R:    RS.W    1
  332. QuatKey.GLOOKAT_R:    RS.W    1
  333. QuatKey.SIZE:        RS.B    0
  334.  
  335.             RSRESET
  336. QuatKeyEntry.POS:    RS.B    QuatKey.SIZE
  337. QuatKeyEntry.TIME:    RS.L    1
  338. QuatKeyEntry.SIZE:    RS.B    0
  339.  
  340.             RSRESET
  341. QuatKeyBuf.KEYNUM:    RS.W    1
  342. QuatKeyBuf.STEPMATRIX:    RS.B    QuatKey.SIZE*2
  343. QuatKeyBuf.BASEMATRIX:    RS.B    QuatKey.SIZE*2
  344. QuatKeyBuf.SIZE:    RS.B    0
  345.  
  346. * Calculates the objects position from the trajectory (keyframe) table.
  347. * INPUT:
  348. * a0: destination quaternion
  349. * a1: object's keyframe buffer
  350. * a2: trajectory table
  351. * a3: address of start time (long)
  352. Keyframer.InterpolateQuaternion:
  353.     move.l    a0,-(sp)
  354.     pea    QuatKeyBuf.BASEMATRIX(a1)
  355.  
  356. .get_entry:
  357.     move.w    (a2)+,d5
  358.     move.w    QuatKeyBuf.KEYNUM(a1),d0
  359.     move.l    $4ba.w,d1
  360.     move.l    (a3),d2
  361.     sub.l    d2,d1
  362.     tst.w    d0
  363.     bpl.s    .not_first_entry
  364.     addq.w    #1,d0
  365.     move.l    QuatKeyEntry.TIME(a2),d3
  366.     cmp.l    d3,d1
  367.     blt.s    .init_spline
  368.     bra.s    .get_entry_loop
  369. .not_first_entry:
  370.     move.w    d0,d4
  371.     mulu.w    #QuatKeyEntry.SIZE,d4
  372.     move.l    QuatKeyEntry.TIME(a2,d4.l),d3
  373.     cmp.l    d3,d1
  374.     blt.s    .end_get_entry
  375.  
  376. .get_entry_loop:
  377.     add.l    d3,d2
  378.     sub.l    d3,d1
  379.     ext.l    d0
  380.     addq.w    #1,d0
  381.     divu.w    d5,d0
  382.     swap    d0
  383.     move.w    d0,d4
  384.     mulu.w    #QuatKeyEntry.SIZE,d4
  385.     move.l    QuatKeyEntry.TIME(a2,d4.l),d3
  386.     cmp.l    d3,d1
  387.     bge.s    .get_entry_loop
  388.  
  389.     move.l    d2,(a3)
  390.  
  391. .init_spline:
  392.     move.l    d3,-(sp)
  393.     move.w    d1,-(sp)
  394.     move.w    d0,QuatKeyBuf.KEYNUM(a1)
  395.     move.w    d0,d4
  396.     addq.w    #1,d4
  397.     ext.l    d4
  398.     divu.w    d5,d4
  399.     swap    d4
  400.     lea    QuatKeyBuf.STEPMATRIX(a1),a0
  401.     mulu.w    #QuatKeyEntry.SIZE,d0
  402.     mulu.w    #QuatKeyEntry.SIZE,d4
  403.     lea    (a2,d4.l),a3
  404.     lea    (a2,d0.l),a2
  405.     moveq    #QuatKey.SIZE/2-1,d7
  406. .fill_matrix_loop:
  407.     move.w    (a2)+,(a0)+                * Copy start data.
  408.     move.w    (a3)+,(a0)+                * Copy end data.
  409.     dbra    d7,.fill_matrix_loop
  410.     lea    QuatKeyBuf.STEPMATRIX(a1),a0
  411.     lea    QuatKeyBuf.BASEMATRIX(a1),a1
  412.     moveq    #QuatKey.SIZE/4,d0
  413.     bsr    Spline.init
  414.     move.w    (sp)+,d1
  415.     move.l    (sp)+,d3
  416. .end_init_spline:
  417.  
  418. .end_get_entry:
  419.  
  420.     movea.l    (sp)+,a0
  421.     movea.l    (sp)+,a1
  422.  
  423. .calc_spline_position:
  424.     move.l    #$7fff,d2
  425.     divu.w    d3,d2
  426.     mulu.w    d2,d1
  427.     move.w    d1,d0
  428.     moveq    #QuatKey.SIZE/4,d1
  429.     bsr    Spline.calculate
  430. .end_calc_spline_position:
  431.     rts
  432.  
  433.             RSRESET
  434. VertexKey.X:        RS.W    1
  435. VertexKey.GX:        RS.W    1
  436. VertexKey.Y:        RS.W    1
  437. VertexKey.GY:        RS.W    1
  438. VertexKey.Z:        RS.W    1
  439. VertexKey.GZ:        RS.W    1
  440. VertexKey.RX:        RS.W    1
  441. VertexKey.GRX:        RS.W    1
  442. VertexKey.RY:        RS.W    1
  443. VertexKey.GRY:        RS.W    1
  444. VertexKey.RZ:        RS.W    1
  445. VertexKey.GRZ:        RS.W    1
  446. VertexKey.SIZE:        RS.B    0
  447.  
  448.             RSRESET
  449. VertexKeyEntry.POS:    RS.B    VertexKey.SIZE
  450. VertexKeyEntry.TIME:    RS.L    1
  451. VertexKeyEntry.SIZE:    RS.B    0
  452.  
  453.                 RSRESET
  454. VertexKeyBuf.KEYNUM:        RS.W    1
  455. VertexKeyBuf.STEPMATRIX:    RS.B    VertexKey.SIZE*2
  456. VertexKeyBuf.BASEMATRIX:    RS.B    VertexKey.SIZE*2
  457. VertexKeyBuf.SIZE:        RS.B    0
  458.  
  459. * Calculates the objects position from the trajectory (keyframe) table.
  460. * INPUT:
  461. * a0: destination vertex
  462. * a1: object's keyframe buffer
  463. * a2: trajectory table
  464. * a3: address of start time (long)
  465. Keyframer.interpolateVertex:
  466.     move.l    a0,-(sp)
  467.     pea    VertexKeyBuf.BASEMATRIX(a1)
  468.  
  469. .get_entry:
  470.     move.w    (a2)+,d5
  471.     move.w    VertexKeyBuf.KEYNUM(a1),d0
  472.     move.l    $4ba.w,d1
  473.     move.l    (a3),d2
  474.     sub.l    d2,d1
  475.     tst.w    d0
  476.     bpl.s    .not_first_entry
  477.     addq.w    #1,d0
  478.     move.l    VertexKeyEntry.TIME(a2),d3
  479.     cmp.l    d3,d1
  480.     blt.s    .init_spline
  481.     bra.s    .get_entry_loop
  482. .not_first_entry:
  483.     move.w    d0,d4
  484.     mulu.w    #VertexKeyEntry.SIZE,d4
  485.     move.l    VertexKeyEntry.TIME(a2,d4.l),d3
  486.     cmp.l    d3,d1
  487.     blt.s    .end_get_entry
  488.  
  489. .get_entry_loop:
  490.     add.l    d3,d2
  491.     sub.l    d3,d1
  492.     ext.l    d0
  493.     addq.w    #1,d0
  494.     divu.w    d5,d0
  495.     swap    d0
  496.     move.w    d0,d4
  497.     mulu.w    #VertexKeyEntry.SIZE,d4
  498.     move.l    VertexKeyEntry.TIME(a2,d4.l),d3
  499.     cmp.l    d3,d1
  500.     bge.s    .get_entry_loop
  501.  
  502.     move.l    d2,(a3)
  503.  
  504. .init_spline:
  505.     move.l    d3,-(sp)
  506.     move.w    d1,-(sp)
  507.     move.w    d0,VertexKeyBuf.KEYNUM(a1)
  508.     move.w    d0,d4
  509.     addq.w    #1,d4
  510.     ext.l    d4
  511.     divu.w    d5,d4
  512.     swap    d4
  513.     lea    VertexKeyBuf.STEPMATRIX(a1),a0
  514.     mulu.w    #VertexKeyEntry.SIZE,d0
  515.     mulu.w    #VertexKeyEntry.SIZE,d4
  516.     lea    (a2,d4.l),a3
  517.     lea    (a2,d0.l),a2
  518.     moveq    #VertexKey.SIZE/2-1,d7
  519. .fill_matrix_loop:
  520.     move.w    (a2)+,(a0)+                * Copy start data.
  521.     move.w    (a3)+,(a0)+                * Copy end data.
  522.     dbra    d7,.fill_matrix_loop
  523.     lea    VertexKeyBuf.STEPMATRIX(a1),a0
  524.     lea    VertexKeyBuf.BASEMATRIX(a1),a1
  525.     moveq    #VertexKey.SIZE/4,d0
  526.     bsr    Spline.init
  527.     move.w    (sp)+,d1
  528.     move.l    (sp)+,d3
  529. .end_init_spline:
  530.  
  531. .end_get_entry:
  532.  
  533.     movea.l    (sp)+,a0
  534.     movea.l    (sp)+,a1
  535.  
  536. .calc_spline_position:
  537.     move.l    #$7fff,d2
  538.     divu.w    d3,d2
  539.     mulu.w    d2,d1
  540.     move.w    d1,d0
  541.     moveq    #VertexKey.SIZE/4,d1
  542.     bsr    Spline.calculate
  543. .end_calc_spline_position:
  544.     rts
  545.  
  546. ********* Matrix
  547.  
  548.         RSRESET
  549. Matrix.XX:    RS.W    1
  550. Matrix.XY:    RS.W    1
  551. Matrix.XZ:    RS.W    1
  552. Matrix.YX:    RS.W    1
  553. Matrix.YY:    RS.W    1
  554. Matrix.YZ:    RS.W    1
  555. Matrix.ZX:    RS.W    1
  556. Matrix.ZY:    RS.W    1
  557. Matrix.ZZ:    RS.W    1
  558. Matrix.TX:    RS.L    1
  559. Matrix.TY:    RS.L    1
  560. Matrix.TZ:    RS.L    1
  561. Matrix.SIZE:    RS.B    0
  562.  
  563.         RSRESET
  564. Quaternion.ORG_X:    RS.W    1
  565. Quaternion.ORG_Y:    RS.W    1
  566. Quaternion.ORG_Z:    RS.W    1
  567. Quaternion.LOOK_X:    RS.W    1
  568. Quaternion.LOOK_Y:    RS.W    1
  569. Quaternion.LOOK_Z:    RS.W    1
  570. ;Quaternion.UP_X:    RS.W    1
  571. ;Quaternion.UP_Y:    RS.W    1
  572. ;Quaternion.UP_Z:    RS.W    1
  573. Quaternion.ROLL:    RS.W    1
  574. Quaternion.SIZE:    RS.B    0
  575.  
  576. * Calculates a hermite basis matrix.
  577. * Our input matrix is a set of 4 points, each with 'n' dimensions.
  578. * We therefore have a n x 4 matrix (width n, height 4).
  579. * i.e.  [ a1 b1  ... ]
  580. *       [ a2 b2      ]
  581. *       [ a3 b3      ]
  582. *       [ a4 b4      ]
  583. * This is multiplied by the matrix ( 2 -2  1  1)
  584. *                                  (-3  3 -2 -1)
  585. *                                  ( 0  0  1  0)
  586. *                                  ( 1  0  0  0) to give our ouput mtrx
  587. * i.e. the first column is multiplied by 2,-2,1,1
  588. * then -3,3,-2,-1 for the next value 
  589. *
  590. * INPUT: d0.w: number of columns
  591. *        a0: input matrix (in "downwards" format)
  592. *        a1: output matrix
  593. Spline.init:
  594.     lea    .matrix_tbl(pc),a2
  595.     move.w    d0,d7                * Save the no of rows.
  596.     subq.w    #1,d7
  597.     movea.l    a0,a4
  598. .row_loop:
  599.     moveq    #4-1,d6
  600.     movea.l    a2,a6                * a6: address of current input matrix
  601.  
  602. .column_loop:
  603.     movea.l    a4,a5                * a5: address of current input row
  604. * Now multiply this by our column:
  605.     move.w    (a5)+,d0
  606.     muls.w    (a6)+,d0
  607.     move.w    (a5)+,d1
  608.     muls.w    (a6)+,d1
  609.     add.l    d1,d0
  610.     move.w    (a5)+,d1
  611.     muls.w    (a6)+,d1
  612.     add.l    d1,d0
  613.     move.w    (a5)+,d1
  614.     muls.w    (a6)+,d1
  615.     add.l    d1,d0
  616.     move.w    d0,(a1)+            * Output the column.
  617. * Move on to the next column:
  618.     dbra    d6,.column_loop
  619.  
  620. * We have done each column, so move on to the next row of input
  621.     addq    #4*2,a0
  622.     movea.l    a0,a4
  623.     dbra    d7,.row_loop
  624.     rts
  625.  
  626. * The base matrix used
  627. .matrix_tbl:
  628.     DC.W    +2,-2,+1,+1
  629.     DC.W    -3,+3,-2,-1
  630.     DC.W    +0,+0,+1,+0
  631.     DC.W    +1,+0,+0,+0
  632.  
  633. * Calculate a single point on the curve, given the basis matrix.
  634. * INPUT: d0.w: value of "t" ($0000 t=0,  $7fff t=1)
  635. *        d1.w: no. of columns
  636. *        a0: basis matrix
  637. *        a1: output matrix
  638. Spline.calculate:
  639. * First calculate our values of "t" and store in registers.
  640.     ext.l    d0
  641.     move.w    d1,d7        * counter
  642.     move.w    d0,d1        * d0 = t
  643.     muls.w    d1,d1
  644.     add.l    d1,d1
  645.     swap    d1        * d1 = t*t
  646.     move.w    d1,d2
  647.     muls.w    d0,d2        * d2 = t*t*t
  648.     add.l    d2,d2
  649.     swap    d2
  650.  
  651. * Now calculate "d7" values.
  652.     subq.w    #1,d7
  653. .calcloop:
  654.     move.w    (a0)+,d6    * t*t*t term
  655.     muls.w    d2,d6
  656.     move.w    (a0)+,d5    * t*t term
  657.     muls.w    d1,d5
  658.     add.l    d5,d6
  659.     move.w    (a0)+,d5    * t term
  660.     muls.w    d0,d5
  661.     add.l    d5,d6
  662.     add.l    d6,d6
  663.     swap    d6
  664.     add.w    (a0)+,d6    * 1 term
  665.     move.w    d6,(a1)+
  666.     dbra    d7,.calcloop
  667.     rts
  668.  
  669. ******** Matrix
  670.  
  671. * Initializes the matrix, to enable generation of rotationmatrices,
  672. * multiplications, translations and conversion of quaternions.
  673. * INPUT: a1: address of sin/cos table
  674. Matrix.init:
  675.     lea    Matrix.sineTable,a0
  676.     move.w    #sintbllen-1,d7
  677. .loop:    move.l    (a1)+,(a0)+
  678.     dbra    d7,.loop
  679.  
  680.     lea    Matrix.sineTable,a0
  681.     move.w    #$8000,d0
  682.     move.w    #sintbllen*2-1,d7
  683. .adjustloop:
  684.     cmp.w    (a0)+,d0
  685.     bne.s    .no_adjust
  686.     addq.w    #1,-2(a0)
  687. .no_adjust:
  688.     dbra    d7,.adjustloop
  689.     rts
  690.  
  691. * Pushes a previously generated matrix on the stack.
  692. ;Matrix.push:
  693.  
  694. * Pops the top matrix off the stack.
  695. ;Matrix.pop:
  696.  
  697. * Generates a matrix out of a 3D vertex with it's X,Y,Z rotation.
  698. * INPUT:
  699. * a1: source vertex
  700. Matrix.convertRotationVertex:
  701.     move.l    a1,-(sp)
  702.     movem.w    6(a1),d0-d2
  703.     bsr    Matrix.generate
  704.     movea.l    (sp)+,a1
  705.     movem.w    (a1),d0-d2
  706.     bsr    Matrix.translate
  707.     rts
  708.  
  709. * Generates a matrix from a quaternion.
  710. * This uses the roll.
  711. *
  712. * O = observer position (camera)
  713. * A = aimpoint position (focus)
  714. * R = direction point position (up)
  715. * N = normalize (Ax - Ox, Ay - Oy, Az - Oz)
  716. * D = normalize (Rx - Ox, Ry - Oy, Rz - Oz)
  717. * V = D - (D . N) * N
  718. * U = V x N
  719. *
  720. *               | Ux Uy Uz |
  721. * View Matrix = | Vx Vy Vz |
  722. *               | Nx Ny Nz |
  723. *
  724. * a = angle for camera Z-panning (roll)
  725. * D = [sin(a), cos(a), 0]
  726. * INPUT: a0: destination matrix
  727. *        a1: source quaternion
  728. ;Matrix.convertQuaternion:
  729.  
  730. * Seems to work ok, since there has been some patching on the overflow
  731. * errors (caused by combination of finite accuracy and use of maximum range).
  732. * INPUT: d0.w: X rotation (a)
  733. *        d1.w: Y rotation (b)
  734. *        d2.w: Z rotation (c)
  735. *        a0: matrix table to output to
  736. ;Matrix.generate:
  737.  
  738. * Bad implementation.. Needs to be altered in order to work correctly
  739. * with normals.
  740. * INPUT: d0.w: X factor (-1.0 ... 1.0)
  741. *        d1.w: Y factor (-1.0 ... 1.0)
  742. *        d2.w: Z factor (-1.0 ... 1.0)
  743. ;Matrix.scaleMatrix:
  744.  
  745. ******** TransformObject
  746.  
  747. TransformObject.BACKFACE_CULLING:    =    $00000001
  748. TransformObject.PERSPECTIVATE:        =    $00000002
  749. TransformObject.ROTATE_NORMALS:        =    1            * Enable/Disable rotation of normalvectors.
  750.  
  751. * INPUT: d0.l: flags
  752. *        d1.w: original objecthandle
  753. * Rotates & scales & translates object by it's matrix.
  754. ;TransformObject.transform:
  755.  
  756. ******** Vertex
  757.  
  758. * Perform a linear morph between 3d vertices.
  759. * INPUT: d0.w: 0-32767 morph index
  760. *        a0: destination vertices
  761. *        a1: begin vertices
  762. *        a2: end vertices
  763. Vertex.morph:
  764.     move.w    #32767,d3
  765.     sub.w    d0,d3
  766.     addq    #2,a2
  767.     move.w    (a1)+,d7
  768.     move.w    d7,(a0)+
  769.     subq.w    #1,d7
  770.     bmi.s    .end
  771.  
  772. .loop:    REPT    3
  773.     move.w    (a1)+,d1
  774.     move.w    (a2)+,d2
  775.     muls.w    d3,d1
  776.     muls.w    d0,d2
  777.     add.l    d1,d2
  778.     add.l    d2,d2
  779.     swap    d2
  780.     move.w    d2,(a0)+
  781.     ENDR    
  782.     dbra    d7,.loop
  783.  
  784. .end:    rts
  785.  
  786. ******** Viewport
  787.  
  788.             RSRESET
  789. Viewport.XSCREEN:    RS.W    1        * X dimension of screenbuffer
  790. Viewport.YSCREEN:    RS.W    1        * Y dimension of screenbuffer
  791. Viewport.XSTART:    RS.W    1        * X start within screen
  792. Viewport.XEND:        RS.W    1        * X end within screen
  793. Viewport.YSTART:    RS.W    1        * Y start within screen
  794. Viewport.YEND:        RS.W    1        * Y end within screen
  795. Viewport.XCENTER:    RS.W    1        * Y start within screen
  796. Viewport.YCENTER:    RS.W    1        * Y end within screen
  797. Viewport.FOCAL:        RS.W    1        * Focal length
  798. Viewport.ASPECT:    RS.W    1        * 8:8 Y scale
  799. Viewport.SIZE:        RS.B    0
  800.  
  801. * INPUT: d0.w: left x
  802. *        d1.w: upper y
  803. *        d6.w: right x
  804. *        d7.w: lower y
  805. *        d4.l: color (2 words)
  806. ;Viewport.paintRectangle:
  807.  
  808. * Updates the viewport settings. Transfers configuration to any objects who
  809. * need to know.
  810. * USES: Viewport.settingsTable
  811. ;Viewport.update:
  812.  
  813. ******** Primitive
  814.  
  815. * INPUT:
  816. * a0: address of screenbuffer
  817. ;Primitive.setScreenbuffer:
  818.  
  819. ******** Polygon
  820.  
  821. Polygon.USE_BLITGOURAUD:    =    0
  822. Polygon.USE_BLITTER:        =    0
  823.  
  824. ******** PrimitiveMesh
  825.  
  826. PrimitiveMesh.MAX_VERTICES:    =    10000
  827. PrimitiveMesh.MAX_PRIMITIVES:    =    10000
  828.  
  829. * Marks the PrimitiveMesh as ready to roll.
  830. ;PrimitiveMesh.new:
  831.  
  832. * Sort the elements using radixsort.
  833. ;PrimitiveMesh.sortZ:
  834.  
  835. * INPUT:
  836. * a0: destination rectangle table
  837. ;PrimitiveMesh.paint:
  838.  
  839. * Beware! No clipping on Polygons!!!!!!! Use this only when absolutely sure
  840. * all polygons are within the viewport range.
  841. * INPUT:
  842. * a0: destination rectangle table
  843. ;PrimitiveMesh.paintUnclipped:
  844.  
  845. ******** Polygon
  846.  
  847. * Initializes polygonpainter lookup tables.
  848. * INPUT:
  849. * a0: texture-address-table
  850. * a1: gouraud-tables
  851. * OUTPUT:
  852. * d0.l: 0=ok, -1=error
  853. ;Polygon.init:
  854.  
  855. * Paints a flatshaded polygon. Must be within viewport!
  856. * INPUT:
  857. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, x1.w, y1.w, x2.w, y2.w....)
  858. ;Polygon.paintFlatshaded:
  859.  
  860. * Paints a gouraudshaded polygon. Must be within viewport!
  861. * INPUT:
  862. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w....)
  863. ;Polygon.paintGouraudshaded:
  864.  
  865. * Paints a textured polygon. Must be within viewport!
  866. * INPUT:
  867. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w....)
  868. ;Polygon.paintTextured:
  869.  
  870. * Paints a alphatextured polygon. Must be within viewport!
  871. * INPUT:
  872. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w, u1.w, v1.w....)
  873. ;Polygon.paintAlphatextured:
  874.  
  875. * Paints a bumpmapped polygon. Must be within viewport!
  876. * INPUT:
  877. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w, u1.w, v1.w....)
  878. ;Polygon.paintBumpmapped:
  879.  
  880. * Paints a flatshaded polygon.
  881. * INPUT:
  882. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, x1.w, y1.w, x2.w, y2.w....)
  883. ;Polygon.paintClippedFlatshaded:
  884.  
  885. * Paints a gouraudshaded polygon.
  886. * INPUT:
  887. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w....)
  888. ;Polygon.paintClippedGouraudshaded:
  889.  
  890. * Paints a textured polygon.
  891. * INPUT:
  892. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w....)
  893. ;Polygon.paintClippedTextured:
  894.  
  895. * Paints a alphatextured polygon.
  896. * INPUT:
  897. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w, u1.w, v1.w....)
  898. ;Polygon.paintClippedAlphatextured:
  899.  
  900. * Paints a bumpmapped polygon.
  901. * INPUT:
  902. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w, u1.w, v1.w....)
  903. ;Polygon.paintClippedBumpmapped:
  904.  
  905. * INPUT:
  906. * a1: sprite structure
  907. * a2: vertex table
  908. ;Sprite.paint:
  909.  
  910. * INPUT:
  911. * a1: line structure
  912. * a2: vertex table
  913. ;Line.paint:
  914.  
  915. ******** WorldTree
  916.  
  917. * OUTPUT: a0: rootnode of tree
  918. WorldTree_GetRootNode:    MACRO
  919.     movea.l    WorldTree.rootNode,a0
  920.     ENDM
  921.  
  922. * INPUT: RootNode: address of rootnode
  923. WorldTree_SetRootNode:    MACRO    RootNode
  924.     clr.l    WorldTree.matrixStack
  925.     move.l    \1,WorldTree.rootNode
  926.     ENDM
  927.  
  928. * Traverse the worldtree and execute the specified routine for every node.
  929. * INPUT: RoutineAdr: routine to execute
  930. WorldTree_TraverseTree:    MACRO
  931.     bsr    WT_TRAVERSE_TREE
  932.     ENDM
  933.  
  934. * Not working yet.. Let's do this baby in version 3 shall we?
  935. * Routine traverses through the world tree and executes a routine for every
  936. * node.
  937. WT_TRAVERSE_TREE:
  938.     WorldTree_GetRootNode
  939.     bsr.s    .push_matrix
  940.     bsr.s    .traverse_tree
  941.     rts
  942.  
  943. * Recursive subroutine.
  944. * INPUT: a0: address of node to traverse
  945. .traverse_tree:
  946.     movea.l    WorldNode.ARRAYADR(a0),a2
  947.     tst.l    a2
  948.     beq.s    .is_leaf
  949.     move.w    (a2),-(sp)            * Push number of children on stack.
  950.  
  951. .nextnodeloop
  952.     move.l    a0,-(sp)
  953.     movea.l    WorldNode.ARRAYADR(a0),a0
  954.     move.w    4(sp),d0
  955.     subq.w    #1,d0
  956.     movea.l    2(a0,d0.w*4),a0
  957.     bsr.s    .push_matrix
  958.     bsr.s    .traverse_tree
  959.     movea.l    (sp)+,a0
  960.     subq.w    #1,(sp)
  961.     bgt.s    .nextnodeloop
  962. .children_done:
  963.  
  964.     addq    #2,sp                * Pop number of children off stack.
  965.     bsr.s    .pop_matrix
  966.     rts
  967. .is_leaf:
  968. * TODO: Execute matrixstack on a new transformobject.
  969. * final matrix := 3rd outer * 2nd outer * outer
  970. * matrix := 2nd_outer * outer
  971. * matrix := 3rd_outer * matrix
  972.     move.l    WorldNode.MATRIXADR(a0),a0
  973. ;    bsr    Matrix.loadMatrix
  974.  
  975. .popstackloop:
  976. ;    bsr    Matrix.pop
  977. ;    lea    WorldTree.matrixStack,a1
  978. ;    adda.l    (a1)+,a1
  979. ;    bsr    Matrix.multiply
  980. ;    subi.l    #Matrix.SIZE,WorldTree.matrixStack
  981.     bgt.s    .popstackloop
  982.  
  983. * TODO: Transform object here??????????
  984.  
  985.     addi.l    #Matrix.SIZE,WorldTree.matrixStack
  986.     rts
  987.  
  988. * Routine that pushes the current node's matrix (rotation, scale & translation)
  989. * onto the matrixstack.
  990. * INPUT: a1: matrix
  991. .push_matrix:
  992.     movem.l    a0-a1,-(sp)
  993.  
  994.     lea    WorldTree.matrixStack,a0
  995.     move.l    (a0),d0
  996.     move.l    d0,d1
  997.     addi.l    #Matrix.SIZE,d1
  998.     move.l    d1,(a0)+
  999.     moveq    #Matrix.SIZE/2-1,d7
  1000. .copyloop:
  1001.     move.w    (a1)+,(a0)+
  1002.     dbra    d7,.copyloop
  1003.  
  1004.     movem.l    (sp)+,a0-a1
  1005.     rts
  1006.  
  1007. * Routine that pops the top matrix off the matrixstack.
  1008. .pop_matrix:
  1009.     subi.l    #Matrix.SIZE,WorldTree.matrixStack
  1010.     rts
  1011.  
  1012. ******** RESERVED SECTION ********
  1013.  
  1014.     BSS
  1015.  
  1016. ******** Viewport
  1017.  
  1018. Viewport.settingsTable:
  1019.     DS.B    Viewport.SIZE
  1020.  
  1021. ******** WorldTree
  1022.  
  1023. WorldTree.rootNode:
  1024.     DS.L    1                * address of rootnode
  1025. WorldTree.matrixStack:
  1026.     DS.L    1                * offset to top
  1027.     DS.W    1000
  1028.  
  1029. ******** Matrix
  1030.  
  1031. Matrix.sineTable:
  1032.     DS.L    sintbllen
  1033.  
  1034. ******** TransformObject 
  1035.  
  1036. TransformObject.2dvertexadr:            * address to 2d vertices array of object
  1037.     DS.L    1
  1038. TransformObject.vertexNum:            * number of vertices in object
  1039.     DS.W    1
  1040. TransformObject.primitiveNum:            * number of elements in object
  1041.     DS.W    1