home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / DELTA.ZIP / DELTASRC.ZIP / DELTA.SRC / HFLYCORE.S < prev    next >
Text File  |  2002-11-09  |  29KB  |  1,041 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.  
  270. ; Primitive types
  271. Primitive.TYPEMASK:    =    %0001110000000000
  272. Primitive.TYPESHIFT:    =    10
  273. Primitive.SPRITETYPE:    =    %0000000000000000
  274. Primitive.LINETYPE:    =    %0000010000000000
  275. ; Other types are polygons, %10 :== triangle, %11 :== quadrangle, etc.
  276.  
  277. ; TableLookup mask
  278. Primitive.TEXTUREMASK:    =    %0000001111111111
  279.  
  280. ; Standard Polygon types
  281. Polygon.TRI:        =    (3-1)<<Primitive.TYPESHIFT
  282. Polygon.QUAD:        =    (4-1)<<Primitive.TYPESHIFT
  283. Polygon.PENT:        =    (5-1)<<Primitive.TYPESHIFT
  284. Polygon.HEX:        =    (6-1)<<Primitive.TYPESHIFT
  285.  
  286. ; Sets paintmode. This involves pixeltype, logic op, pixelskip. For
  287. ; discription of these, see paintmode equates.
  288. ; All primitives use the settings taken by this call.
  289. ; INPUT:
  290. ; d0.w=pixeltype and logic op
  291. ; d1.w=pixelskip (number of bytes to progress after each pixel)
  292. ; OUTPUT:
  293. ; d0.w: =0: success, <0: error
  294. ;Primitive.setPaintMode:
  295.  
  296. ********* PolyPoint
  297.  
  298.         RSRESET
  299. PolyPoint.X:    RS.W    1
  300. PolyPoint.Y:    RS.W    1
  301. PolyPoint.U1:    RS.W    1
  302. PolyPoint.V1:    RS.W    1
  303. PolyPoint.U2:    RS.W    1
  304. PolyPoint.V2:    RS.W    1
  305. PolyPoint.SIZE:    RS.B    0
  306.  
  307. ********* MeshElement
  308.  
  309.             RSRESET
  310. MeshElement.BASE:    RS.L    1            * startaddress of vertex table
  311. MeshElement.REF:    RS.L    1            * address of primitive
  312. MeshElement.Z:        RS.W    1            * avg. Z coordinate of primitive
  313. MeshElement.SIZE:    RS.B    0
  314.  
  315. ******** KeyFramer
  316.  
  317.             RSRESET
  318. QuatKey.X:        RS.W    1
  319. QuatKey.GX:        RS.W    1
  320. QuatKey.Y:        RS.W    1
  321. QuatKey.GY:        RS.W    1
  322. QuatKey.Z:        RS.W    1
  323. QuatKey.GZ:        RS.W    1
  324. QuatKey.LOOKAT_X:    RS.W    1
  325. QuatKey.GLOOKAT_X:    RS.W    1
  326. QuatKey.LOOKAT_Y:    RS.W    1
  327. QuatKey.GLOOKAT_Y:    RS.W    1
  328. QuatKey.LOOKAT_Z:    RS.W    1
  329. QuatKey.GLOOKAT_Z:    RS.W    1
  330. QuatKey.LOOKAT_R:    RS.W    1
  331. QuatKey.GLOOKAT_R:    RS.W    1
  332. QuatKey.SIZE:        RS.B    0
  333.  
  334.             RSRESET
  335. QuatKeyEntry.POS:    RS.B    QuatKey.SIZE
  336. QuatKeyEntry.TIME:    RS.L    1
  337. QuatKeyEntry.SIZE:    RS.B    0
  338.  
  339.             RSRESET
  340. QuatKeyBuf.KEYNUM:    RS.W    1
  341. QuatKeyBuf.STEPMATRIX:    RS.B    QuatKey.SIZE*2
  342. QuatKeyBuf.BASEMATRIX:    RS.B    QuatKey.SIZE*2
  343. QuatKeyBuf.SIZE:    RS.B    0
  344.  
  345. * Calculates the objects position from the trajectory (keyframe) table.
  346. * INPUT:
  347. * a0: destination quaternion
  348. * a1: object's keyframe buffer
  349. * a2: trajectory table
  350. * a3: address of start time (long)
  351. Keyframer.InterpolateQuaternion:
  352.     move.l    a0,-(sp)
  353.     pea    QuatKeyBuf.BASEMATRIX(a1)
  354.  
  355. .get_entry:
  356.     move.w    (a2)+,d5
  357.     move.w    QuatKeyBuf.KEYNUM(a1),d0
  358.     move.l    $4ba.w,d1
  359.     move.l    (a3),d2
  360.     sub.l    d2,d1
  361.     tst.w    d0
  362.     bpl.s    .not_first_entry
  363.     addq.w    #1,d0
  364.     move.l    QuatKeyEntry.TIME(a2),d3
  365.     cmp.l    d3,d1
  366.     blt.s    .init_spline
  367.     bra.s    .get_entry_loop
  368. .not_first_entry:
  369.     move.w    d0,d4
  370.     mulu.w    #QuatKeyEntry.SIZE,d4
  371.     move.l    QuatKeyEntry.TIME(a2,d4.l),d3
  372.     cmp.l    d3,d1
  373.     blt.s    .end_get_entry
  374.  
  375. .get_entry_loop:
  376.     add.l    d3,d2
  377.     sub.l    d3,d1
  378.     ext.l    d0
  379.     addq.w    #1,d0
  380.     divu.w    d5,d0
  381.     swap    d0
  382.     move.w    d0,d4
  383.     mulu.w    #QuatKeyEntry.SIZE,d4
  384.     move.l    QuatKeyEntry.TIME(a2,d4.l),d3
  385.     cmp.l    d3,d1
  386.     bge.s    .get_entry_loop
  387.  
  388.     move.l    d2,(a3)
  389.  
  390. .init_spline:
  391.     move.l    d3,-(sp)
  392.     move.w    d1,-(sp)
  393.     move.w    d0,QuatKeyBuf.KEYNUM(a1)
  394.     move.w    d0,d4
  395.     addq.w    #1,d4
  396.     ext.l    d4
  397.     divu.w    d5,d4
  398.     swap    d4
  399.     lea    QuatKeyBuf.STEPMATRIX(a1),a0
  400.     mulu.w    #QuatKeyEntry.SIZE,d0
  401.     mulu.w    #QuatKeyEntry.SIZE,d4
  402.     lea    (a2,d4.l),a3
  403.     lea    (a2,d0.l),a2
  404.     moveq    #QuatKey.SIZE/2-1,d7
  405. .fill_matrix_loop:
  406.     move.w    (a2)+,(a0)+                * Copy start data.
  407.     move.w    (a3)+,(a0)+                * Copy end data.
  408.     dbra    d7,.fill_matrix_loop
  409.     lea    QuatKeyBuf.STEPMATRIX(a1),a0
  410.     lea    QuatKeyBuf.BASEMATRIX(a1),a1
  411.     moveq    #QuatKey.SIZE/4,d0
  412.     bsr    Spline.init
  413.     move.w    (sp)+,d1
  414.     move.l    (sp)+,d3
  415. .end_init_spline:
  416.  
  417. .end_get_entry:
  418.  
  419.     movea.l    (sp)+,a0
  420.     movea.l    (sp)+,a1
  421.  
  422. .calc_spline_position:
  423.     move.l    #$7fff,d2
  424.     divu.w    d3,d2
  425.     mulu.w    d2,d1
  426.     move.w    d1,d0
  427.     moveq    #QuatKey.SIZE/4,d1
  428.     bsr    Spline.calculate
  429. .end_calc_spline_position:
  430.     rts
  431.  
  432.             RSRESET
  433. VertexKey.X:        RS.W    1
  434. VertexKey.GX:        RS.W    1
  435. VertexKey.Y:        RS.W    1
  436. VertexKey.GY:        RS.W    1
  437. VertexKey.Z:        RS.W    1
  438. VertexKey.GZ:        RS.W    1
  439. VertexKey.RX:        RS.W    1
  440. VertexKey.GRX:        RS.W    1
  441. VertexKey.RY:        RS.W    1
  442. VertexKey.GRY:        RS.W    1
  443. VertexKey.RZ:        RS.W    1
  444. VertexKey.GRZ:        RS.W    1
  445. VertexKey.SIZE:        RS.B    0
  446.  
  447.             RSRESET
  448. VertexKeyEntry.POS:    RS.B    VertexKey.SIZE
  449. VertexKeyEntry.TIME:    RS.L    1
  450. VertexKeyEntry.SIZE:    RS.B    0
  451.  
  452.                 RSRESET
  453. VertexKeyBuf.KEYNUM:        RS.W    1
  454. VertexKeyBuf.STEPMATRIX:    RS.B    VertexKey.SIZE*2
  455. VertexKeyBuf.BASEMATRIX:    RS.B    VertexKey.SIZE*2
  456. VertexKeyBuf.SIZE:        RS.B    0
  457.  
  458. * Calculates the objects position from the trajectory (keyframe) table.
  459. * INPUT:
  460. * a0: destination vertex
  461. * a1: object's keyframe buffer
  462. * a2: trajectory table
  463. * a3: address of start time (long)
  464. Keyframer.interpolateVertex:
  465.     move.l    a0,-(sp)
  466.     pea    VertexKeyBuf.BASEMATRIX(a1)
  467.  
  468. .get_entry:
  469.     move.w    (a2)+,d5
  470.     move.w    VertexKeyBuf.KEYNUM(a1),d0
  471.     move.l    $4ba.w,d1
  472.     move.l    (a3),d2
  473.     sub.l    d2,d1
  474.     tst.w    d0
  475.     bpl.s    .not_first_entry
  476.     addq.w    #1,d0
  477.     move.l    VertexKeyEntry.TIME(a2),d3
  478.     cmp.l    d3,d1
  479.     blt.s    .init_spline
  480.     bra.s    .get_entry_loop
  481. .not_first_entry:
  482.     move.w    d0,d4
  483.     mulu.w    #VertexKeyEntry.SIZE,d4
  484.     move.l    VertexKeyEntry.TIME(a2,d4.l),d3
  485.     cmp.l    d3,d1
  486.     blt.s    .end_get_entry
  487.  
  488. .get_entry_loop:
  489.     add.l    d3,d2
  490.     sub.l    d3,d1
  491.     ext.l    d0
  492.     addq.w    #1,d0
  493.     divu.w    d5,d0
  494.     swap    d0
  495.     move.w    d0,d4
  496.     mulu.w    #VertexKeyEntry.SIZE,d4
  497.     move.l    VertexKeyEntry.TIME(a2,d4.l),d3
  498.     cmp.l    d3,d1
  499.     bge.s    .get_entry_loop
  500.  
  501.     move.l    d2,(a3)
  502.  
  503. .init_spline:
  504.     move.l    d3,-(sp)
  505.     move.w    d1,-(sp)
  506.     move.w    d0,VertexKeyBuf.KEYNUM(a1)
  507.     move.w    d0,d4
  508.     addq.w    #1,d4
  509.     ext.l    d4
  510.     divu.w    d5,d4
  511.     swap    d4
  512.     lea    VertexKeyBuf.STEPMATRIX(a1),a0
  513.     mulu.w    #VertexKeyEntry.SIZE,d0
  514.     mulu.w    #VertexKeyEntry.SIZE,d4
  515.     lea    (a2,d4.l),a3
  516.     lea    (a2,d0.l),a2
  517.     moveq    #VertexKey.SIZE/2-1,d7
  518. .fill_matrix_loop:
  519.     move.w    (a2)+,(a0)+                * Copy start data.
  520.     move.w    (a3)+,(a0)+                * Copy end data.
  521.     dbra    d7,.fill_matrix_loop
  522.     lea    VertexKeyBuf.STEPMATRIX(a1),a0
  523.     lea    VertexKeyBuf.BASEMATRIX(a1),a1
  524.     moveq    #VertexKey.SIZE/4,d0
  525.     bsr    Spline.init
  526.     move.w    (sp)+,d1
  527.     move.l    (sp)+,d3
  528. .end_init_spline:
  529.  
  530. .end_get_entry:
  531.  
  532.     movea.l    (sp)+,a0
  533.     movea.l    (sp)+,a1
  534.  
  535. .calc_spline_position:
  536.     move.l    #$7fff,d2
  537.     divu.w    d3,d2
  538.     mulu.w    d2,d1
  539.     move.w    d1,d0
  540.     moveq    #VertexKey.SIZE/4,d1
  541.     bsr    Spline.calculate
  542. .end_calc_spline_position:
  543.     rts
  544.  
  545. ********* Matrix
  546.  
  547.         RSRESET
  548. Matrix.XX:    RS.W    1
  549. Matrix.XY:    RS.W    1
  550. Matrix.XZ:    RS.W    1
  551. Matrix.YX:    RS.W    1
  552. Matrix.YY:    RS.W    1
  553. Matrix.YZ:    RS.W    1
  554. Matrix.ZX:    RS.W    1
  555. Matrix.ZY:    RS.W    1
  556. Matrix.ZZ:    RS.W    1
  557. Matrix.TX:    RS.L    1
  558. Matrix.TY:    RS.L    1
  559. Matrix.TZ:    RS.L    1
  560. Matrix.SIZE:    RS.B    0
  561.  
  562.         RSRESET
  563. Quaternion.ORG_X:    RS.W    1
  564. Quaternion.ORG_Y:    RS.W    1
  565. Quaternion.ORG_Z:    RS.W    1
  566. Quaternion.LOOK_X:    RS.W    1
  567. Quaternion.LOOK_Y:    RS.W    1
  568. Quaternion.LOOK_Z:    RS.W    1
  569. ;Quaternion.UP_X:    RS.W    1
  570. ;Quaternion.UP_Y:    RS.W    1
  571. ;Quaternion.UP_Z:    RS.W    1
  572. Quaternion.ROLL:    RS.W    1
  573. Quaternion.SIZE:    RS.B    0
  574.  
  575. * Calculates a hermite basis matrix.
  576. * Our input matrix is a set of 4 points, each with 'n' dimensions.
  577. * We therefore have a n x 4 matrix (width n, height 4).
  578. * i.e.  [ a1 b1  ... ]
  579. *       [ a2 b2      ]
  580. *       [ a3 b3      ]
  581. *       [ a4 b4      ]
  582. * This is multiplied by the matrix ( 2 -2  1  1)
  583. *                                  (-3  3 -2 -1)
  584. *                                  ( 0  0  1  0)
  585. *                                  ( 1  0  0  0) to give our ouput mtrx
  586. * i.e. the first column is multiplied by 2,-2,1,1
  587. * then -3,3,-2,-1 for the next value 
  588. *
  589. * INPUT: d0.w: number of columns
  590. *        a0: input matrix (in "downwards" format)
  591. *        a1: output matrix
  592. Spline.init:
  593.     lea    .matrix_tbl(pc),a2
  594.     move.w    d0,d7                * Save the no of rows.
  595.     subq.w    #1,d7
  596.     movea.l    a0,a4
  597. .row_loop:
  598.     moveq    #4-1,d6
  599.     movea.l    a2,a6                * a6: address of current input matrix
  600.  
  601. .column_loop:
  602.     movea.l    a4,a5                * a5: address of current input row
  603. * Now multiply this by our column:
  604.     move.w    (a5)+,d0
  605.     muls.w    (a6)+,d0
  606.     move.w    (a5)+,d1
  607.     muls.w    (a6)+,d1
  608.     add.l    d1,d0
  609.     move.w    (a5)+,d1
  610.     muls.w    (a6)+,d1
  611.     add.l    d1,d0
  612.     move.w    (a5)+,d1
  613.     muls.w    (a6)+,d1
  614.     add.l    d1,d0
  615.     move.w    d0,(a1)+            * Output the column.
  616. * Move on to the next column:
  617.     dbra    d6,.column_loop
  618.  
  619. * We have done each column, so move on to the next row of input
  620.     addq    #4*2,a0
  621.     movea.l    a0,a4
  622.     dbra    d7,.row_loop
  623.     rts
  624.  
  625. * The base matrix used
  626. .matrix_tbl:
  627.     DC.W    +2,-2,+1,+1
  628.     DC.W    -3,+3,-2,-1
  629.     DC.W    +0,+0,+1,+0
  630.     DC.W    +1,+0,+0,+0
  631.  
  632. * Calculate a single point on the curve, given the basis matrix.
  633. * INPUT: d0.w: value of "t" ($0000 t=0,  $7fff t=1)
  634. *        d1.w: no. of columns
  635. *        a0: basis matrix
  636. *        a1: output matrix
  637. Spline.calculate:
  638. * First calculate our values of "t" and store in registers.
  639.     ext.l    d0
  640.     move.w    d1,d7        * counter
  641.     move.w    d0,d1        * d0 = t
  642.     muls.w    d1,d1
  643.     add.l    d1,d1
  644.     swap    d1        * d1 = t*t
  645.     move.w    d1,d2
  646.     muls.w    d0,d2        * d2 = t*t*t
  647.     add.l    d2,d2
  648.     swap    d2
  649.  
  650. * Now calculate "d7" values.
  651.     subq.w    #1,d7
  652. .calcloop:
  653.     move.w    (a0)+,d6    * t*t*t term
  654.     muls.w    d2,d6
  655.     move.w    (a0)+,d5    * t*t term
  656.     muls.w    d1,d5
  657.     add.l    d5,d6
  658.     move.w    (a0)+,d5    * t term
  659.     muls.w    d0,d5
  660.     add.l    d5,d6
  661.     add.l    d6,d6
  662.     swap    d6
  663.     add.w    (a0)+,d6    * 1 term
  664.     move.w    d6,(a1)+
  665.     dbra    d7,.calcloop
  666.     rts
  667.  
  668. ******** Matrix
  669.  
  670. * Initializes the matrix, to enable generation of rotationmatrices,
  671. * multiplications, translations and conversion of quaternions.
  672. * INPUT: a1: address of sin/cos table
  673. Matrix.init:
  674.     lea    Matrix.sineTable,a0
  675.     move.w    #sintbllen-1,d7
  676. .loop:    move.l    (a1)+,(a0)+
  677.     dbra    d7,.loop
  678.  
  679.     lea    Matrix.sineTable,a0
  680.     move.w    #$8000,d0
  681.     move.w    #sintbllen*2-1,d7
  682. .adjustloop:
  683.     cmp.w    (a0)+,d0
  684.     bne.s    .no_adjust
  685.     addq.w    #1,-2(a0)
  686. .no_adjust:
  687.     dbra    d7,.adjustloop
  688.     rts
  689.  
  690. * Pushes a previously generated matrix on the stack.
  691. ;Matrix.push:
  692.  
  693. * Pops the top matrix off the stack.
  694. ;Matrix.pop:
  695.  
  696. * Generates a matrix out of a 3D vertex with it's X,Y,Z rotation.
  697. * INPUT:
  698. * a1: source vertex
  699. Matrix.convertRotationVertex:
  700.     move.l    a1,-(sp)
  701.     movem.w    6(a1),d0-d2
  702.     bsr    Matrix.generate
  703.     movea.l    (sp)+,a1
  704.     movem.w    (a1),d0-d2
  705.     bsr    Matrix.translate
  706.     rts
  707.  
  708. * Generates a matrix from a quaternion.
  709. * This uses the roll.
  710. *
  711. * O = observer position (camera)
  712. * A = aimpoint position (focus)
  713. * R = direction point position (up)
  714. * N = normalize (Ax - Ox, Ay - Oy, Az - Oz)
  715. * D = normalize (Rx - Ox, Ry - Oy, Rz - Oz)
  716. * V = D - (D . N) * N
  717. * U = V x N
  718. *
  719. *               | Ux Uy Uz |
  720. * View Matrix = | Vx Vy Vz |
  721. *               | Nx Ny Nz |
  722. *
  723. * a = angle for camera Z-panning (roll)
  724. * D = [sin(a), cos(a), 0]
  725. * INPUT: a0: destination matrix
  726. *        a1: source quaternion
  727. ;Matrix.convertQuaternion:
  728.  
  729. * Seems to work ok, since there has been some patching on the overflow
  730. * errors (caused by combination of finite accuracy and use of maximum range).
  731. * INPUT: d0.w: X rotation (a)
  732. *        d1.w: Y rotation (b)
  733. *        d2.w: Z rotation (c)
  734. *        a0: matrix table to output to
  735. ;Matrix.generate:
  736.  
  737. * Bad implementation.. Needs to be altered in order to work correctly
  738. * with normals.
  739. * INPUT: d0.w: X factor (-1.0 ... 1.0)
  740. *        d1.w: Y factor (-1.0 ... 1.0)
  741. *        d2.w: Z factor (-1.0 ... 1.0)
  742. ;Matrix.scaleMatrix:
  743.  
  744. ******** TransformObject
  745.  
  746. TransformObject.BACKFACE_CULLING:    =    $00000001
  747. TransformObject.PERSPECTIVATE:        =    $00000002
  748. TransformObject.ROTATE_NORMALS:        =    1            * Enable/Disable rotation of normalvectors.
  749.  
  750. * INPUT: d0.l: flags
  751. *        d1.w: original objecthandle
  752. * Rotates & scales & translates object by it's matrix.
  753. ;TransformObject.transform:
  754.  
  755. ******** Vertex
  756.  
  757. * Perform a linear morph between 3d vertices.
  758. * INPUT: d0.w: 0-32767 morph index
  759. *        a0: destination vertices
  760. *        a1: begin vertices
  761. *        a2: end vertices
  762. Vertex.morph:
  763.     move.w    #32767,d3
  764.     sub.w    d0,d3
  765.     addq    #2,a2
  766.     move.w    (a1)+,d7
  767.     move.w    d7,(a0)+
  768.     subq.w    #1,d7
  769.     bmi.s    .end
  770.  
  771. .loop:    REPT    3
  772.     move.w    (a1)+,d1
  773.     move.w    (a2)+,d2
  774.     muls.w    d3,d1
  775.     muls.w    d0,d2
  776.     add.l    d1,d2
  777.     add.l    d2,d2
  778.     swap    d2
  779.     move.w    d2,(a0)+
  780.     ENDR    
  781.     dbra    d7,.loop
  782.  
  783. .end:    rts
  784.  
  785. ******** Viewport
  786.  
  787.             RSRESET
  788. Viewport.XSCREEN:    RS.W    1        * X dimension of screenbuffer
  789. Viewport.YSCREEN:    RS.W    1        * Y dimension of screenbuffer
  790. Viewport.XSTART:    RS.W    1        * X start within screen
  791. Viewport.XEND:        RS.W    1        * X end within screen
  792. Viewport.YSTART:    RS.W    1        * Y start within screen
  793. Viewport.YEND:        RS.W    1        * Y end within screen
  794. Viewport.XCENTER:    RS.W    1        * Y start within screen
  795. Viewport.YCENTER:    RS.W    1        * Y end within screen
  796. Viewport.FOCAL:        RS.W    1        * Focal length
  797. Viewport.ASPECT:    RS.W    1        * 8:8 Y scale
  798. Viewport.SIZE:        RS.B    0
  799.  
  800. * INPUT: d0.w: left x
  801. *        d1.w: upper y
  802. *        d6.w: right x
  803. *        d7.w: lower y
  804. *        d4.l: color (2 words)
  805. ;Viewport.paintRectangle:
  806.  
  807. * Updates the viewport settings. Transfers configuration to any objects who
  808. * need to know.
  809. * USES: Viewport.settingsTable
  810. ;Viewport.update:
  811.  
  812. ******** Primitive
  813.  
  814. * INPUT:
  815. * a0: address of screenbuffer
  816. ;Primitive.setScreenbuffer:
  817.  
  818. ******** Polygon
  819.  
  820. Polygon.USE_BLITGOURAUD:    =    0
  821. Polygon.USE_BLITTER:        =    0
  822.  
  823. ******** PrimitiveMesh
  824.  
  825. PrimitiveMesh.MAX_VERTICES:    =    10000
  826. PrimitiveMesh.MAX_PRIMITIVES:    =    10000
  827.  
  828. * Marks the PrimitiveMesh as ready to roll.
  829. ;PrimitiveMesh.new:
  830.  
  831. * Sort the elements using radixsort.
  832. ;PrimitiveMesh.sortZ:
  833.  
  834. * INPUT:
  835. * a0: destination rectangle table
  836. ;PrimitiveMesh.paint:
  837.  
  838. * Beware! No clipping on Polygons!!!!!!! Use this only when absolutely sure
  839. * all polygons are within the viewport range.
  840. * INPUT:
  841. * a0: destination rectangle table
  842. ;PrimitiveMesh.paintUnclipped:
  843.  
  844. ******** Polygon
  845.  
  846. * Initializes polygonpainter lookup tables.
  847. * INPUT:
  848. * a0: texture-address-table
  849. * a1: gouraud-tables
  850. * OUTPUT:
  851. * d0.l: 0=ok, -1=error
  852. ;Polygon.init:
  853.  
  854. * Paints a flatshaded polygon. Must be within viewport!
  855. * INPUT:
  856. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, x1.w, y1.w, x2.w, y2.w....)
  857. ;Polygon.paintFlatshaded:
  858.  
  859. * Paints a gouraudshaded polygon. Must be within viewport!
  860. * INPUT:
  861. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w....)
  862. ;Polygon.paintGouraudshaded:
  863.  
  864. * Paints a textured polygon. Must be within viewport!
  865. * INPUT:
  866. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w....)
  867. ;Polygon.paintTextured:
  868.  
  869. * Paints a alphatextured polygon. Must be within viewport!
  870. * INPUT:
  871. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w, u1.w, v1.w....)
  872. ;Polygon.paintAlphatextured:
  873.  
  874. * Paints a bumpmapped polygon. Must be within viewport!
  875. * INPUT:
  876. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w, u1.w, v1.w....)
  877. ;Polygon.paintBumpmapped:
  878.  
  879. * Paints a flatshaded polygon.
  880. * INPUT:
  881. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, x1.w, y1.w, x2.w, y2.w....)
  882. ;Polygon.paintClippedFlatshaded:
  883.  
  884. * Paints a gouraudshaded polygon.
  885. * INPUT:
  886. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w....)
  887. ;Polygon.paintClippedGouraudshaded:
  888.  
  889. * Paints a textured polygon.
  890. * INPUT:
  891. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w....)
  892. ;Polygon.paintClippedTextured:
  893.  
  894. * Paints a alphatextured polygon.
  895. * INPUT:
  896. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w, u1.w, v1.w....)
  897. ;Polygon.paintClippedAlphatextured:
  898.  
  899. * Paints a bumpmapped polygon.
  900. * INPUT:
  901. * a1: polygon (texture.w, numofpoints.w, x0.w, y0.w, u0.w, v0.w, u1.w, v1.w....)
  902. ;Polygon.paintClippedBumpmapped:
  903.  
  904. * INPUT:
  905. * a1: sprite structure
  906. * a2: vertex table
  907. ;Sprite.paint:
  908.  
  909. * INPUT:
  910. * a1: line structure
  911. * a2: vertex table
  912. ;Line.paint:
  913.  
  914. ******** WorldTree
  915.  
  916. * OUTPUT: a0: rootnode of tree
  917. WorldTree_GetRootNode:    MACRO
  918.     movea.l    WorldTree.rootNode,a0
  919.     ENDM
  920.  
  921. * INPUT: RootNode: address of rootnode
  922. WorldTree_SetRootNode:    MACRO    RootNode
  923.     clr.l    WorldTree.matrixStack
  924.     move.l    \1,WorldTree.rootNode
  925.     ENDM
  926.  
  927. * Traverse the worldtree and execute the specified routine for every node.
  928. * INPUT: RoutineAdr: routine to execute
  929. WorldTree_TraverseTree:    MACRO
  930.     bsr    WT_TRAVERSE_TREE
  931.     ENDM
  932.  
  933. * Not working yet.. Let's do this baby in version 3 shall we?
  934. * Routine traverses through the world tree and executes a routine for every
  935. * node.
  936. WT_TRAVERSE_TREE:
  937.     WorldTree_GetRootNode
  938.     bsr.s    .push_matrix
  939.     bsr.s    .traverse_tree
  940.     rts
  941.  
  942. * Recursive subroutine.
  943. * INPUT: a0: address of node to traverse
  944. .traverse_tree:
  945.     movea.l    WorldNode.ARRAYADR(a0),a2
  946.     tst.l    a2
  947.     beq.s    .is_leaf
  948.     move.w    (a2),-(sp)            * Push number of children on stack.
  949.  
  950. .nextnodeloop
  951.     move.l    a0,-(sp)
  952.     movea.l    WorldNode.ARRAYADR(a0),a0
  953.     move.w    4(sp),d0
  954.     subq.w    #1,d0
  955.     movea.l    2(a0,d0.w*4),a0
  956.     bsr.s    .push_matrix
  957.     bsr.s    .traverse_tree
  958.     movea.l    (sp)+,a0
  959.     subq.w    #1,(sp)
  960.     bgt.s    .nextnodeloop
  961. .children_done:
  962.  
  963.     addq    #2,sp                * Pop number of children off stack.
  964.     bsr.s    .pop_matrix
  965.     rts
  966. .is_leaf:
  967. * TODO: Execute matrixstack on a new transformobject.
  968. * final matrix := 3rd outer * 2nd outer * outer
  969. * matrix := 2nd_outer * outer
  970. * matrix := 3rd_outer * matrix
  971.     move.l    WorldNode.MATRIXADR(a0),a0
  972. ;    bsr    Matrix.loadMatrix
  973.  
  974. .popstackloop:
  975. ;    bsr    Matrix.pop
  976. ;    lea    WorldTree.matrixStack,a1
  977. ;    adda.l    (a1)+,a1
  978. ;    bsr    Matrix.multiply
  979. ;    subi.l    #Matrix.SIZE,WorldTree.matrixStack
  980.     bgt.s    .popstackloop
  981.  
  982. * TODO: Transform object here??????????
  983.  
  984.     addi.l    #Matrix.SIZE,WorldTree.matrixStack
  985.     rts
  986.  
  987. * Routine that pushes the current node's matrix (rotation, scale & translation)
  988. * onto the matrixstack.
  989. * INPUT: a1: matrix
  990. .push_matrix:
  991.     movem.l    a0-a1,-(sp)
  992.  
  993.     lea    WorldTree.matrixStack,a0
  994.     move.l    (a0),d0
  995.     move.l    d0,d1
  996.     addi.l    #Matrix.SIZE,d1
  997.     move.l    d1,(a0)+
  998.     moveq    #Matrix.SIZE/2-1,d7
  999. .copyloop:
  1000.     move.w    (a1)+,(a0)+
  1001.     dbra    d7,.copyloop
  1002.  
  1003.     movem.l    (sp)+,a0-a1
  1004.     rts
  1005.  
  1006. * Routine that pops the top matrix off the matrixstack.
  1007. .pop_matrix:
  1008.     subi.l    #Matrix.SIZE,WorldTree.matrixStack
  1009.     rts
  1010.  
  1011. ******** RESERVED SECTION ********
  1012.  
  1013.     BSS
  1014.  
  1015. ******** Viewport
  1016.  
  1017. Viewport.settingsTable:
  1018.     DS.B    Viewport.SIZE
  1019.  
  1020. ******** WorldTree
  1021.  
  1022. WorldTree.rootNode:
  1023.     DS.L    1                * address of rootnode
  1024. WorldTree.matrixStack:
  1025.     DS.L    1                * offset to top
  1026.     DS.W    1000
  1027.  
  1028. ******** Matrix
  1029.  
  1030. Matrix.sineTable:
  1031.     DS.L    sintbllen
  1032.  
  1033. ******** TransformObject 
  1034.  
  1035. TransformObject.2dvertexadr:            * address to 2d vertices array of object
  1036.     DS.L    1
  1037. TransformObject.vertexNum:            * number of vertices in object
  1038.     DS.W    1
  1039. TransformObject.primitiveNum:            * number of elements in object
  1040.     DS.W    1