home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / DELTA.ZIP / DELTASRC.ZIP / DELTA.SRC / MARCHING.ASM < prev    next >
Assembly Source File  |  2002-11-27  |  23KB  |  837 lines

  1. ; Marching cubes + field generator with dsp. Balltrajects done by host.
  2. ; Host is now some sort of slave.
  3. ; 12bit precision and 64*64 texture, but it looks decent enough..
  4. ; coding by earx 2002
  5.  
  6. ; oops: inaccuracy, normalisation in some spots doesn't work causing
  7. ; intersection of normals to go wrong. the resultant shadevector will be
  8. ; too short.
  9. ; also the same approach causes many unneeded normalcalculations.
  10. ; still it's a damn amount faster than a cpu version, hahaha!
  11.  
  12. ; You can change these to your likings, but beware of allowed limits!
  13. NUM_BALLS:    =    3                    ; #balls in blob
  14. ;ISOLEVEL:    =    480                    ; Change to your liking [0..4095]
  15. WIDTH:        =    10                    ; #points in gridside, <14 !
  16. DISTANCE:    =    $A000                    ; Not too small, no clipping!
  17. ROUND:        =    1                    ; rounding on sqrt (y/n)
  18.  
  19. ; Don't touch the following equates.
  20. PLANE_SIZE:    =    WIDTH*WIDTH
  21. FIELD_SIZE:    =    WIDTH*WIDTH*WIDTH
  22. CUBES:        =    WIDTH-1                    ; #cubes in a row
  23. GWIDTH:        =    $4000                    ; width of entire grid
  24. CUBEWIDTH:    =    GWIDTH/CUBES
  25.  
  26. HSR:        =    $FFE9
  27. HTX:        =    $FFEB
  28.  
  29. get:    MACRO
  30.     jclr    #0,x:<<HSR,*
  31.     movep    x:<<HTX,\1
  32.     ENDM
  33.  
  34. send:    MACRO
  35.     jclr    #1,x:<<HSR,*
  36.     movep    \1,x:<<HTX
  37.     ENDM
  38.  
  39.     org    p:0
  40.     jmp    <main
  41.  
  42.     org    p:$40
  43.  
  44. main:    jsr    <init
  45.  
  46. _loop:    jsr    <getBallPositions
  47.     jmp    <keepstacklow                    ; yeah, laugh please!
  48.  
  49. ;- graphical routines ------------------------------------------------------
  50. ;
  51. ;
  52.  
  53. ; Polygonizes the grid and sends polygons to host.
  54. ; This works from back to front, so depthsorting is not required.
  55. ; Note: no subroutine, jumps back to mainloop!
  56. paintGrid:
  57.     move            #field,r0
  58.     move            #gradfield,r1
  59.     move            #>DISTANCE-CUBEWIDTH,x0
  60.     move            x0,x:<posz
  61.  
  62. _zloop:    move            #>-GWIDTH/2,x0
  63.     move            x0,x:<posy
  64.  
  65. _yloop:    move            #>-GWIDTH/2,x0
  66.     move            x0,x:<posx
  67.  
  68. _xloop:
  69. ; Copy cube to table, order: lower square anticlock, upper square anticlock.
  70.     move            #<WIDTH,n0
  71.     move            #<cube,r4
  72.     move            (r0)+n0
  73.     move            #>PLANE_SIZE,n0
  74.     move            x:(r0)+,b            ; width
  75.     move            x:(r0)+n0,a    b,y:(r4)+    ; 1+width
  76.     move            #>-WIDTH-PLANE_SIZE,n0
  77.     move            x:(r0)-,b    a,y:(r4)+    ; 1+width+planesize
  78.     move            x:(r0)+n0,a    b,y:(r4)+    ; width+planesize
  79.     move            #>PLANE_SIZE,n0
  80.     move            x:(r0)+,b    a,y:(r4)+    ; 0
  81.     move            x:(r0)+n0,a    b,y:(r4)+    ; 1
  82.     move            x:(r0)-,b    a,y:(r4)+    ; 1+planesize
  83.     move            x:(r0)+,a    b,y:(r4)+    ; planesize
  84.     move                    a,y:(r4)+    ; 
  85.     move            (r0)-n0                ; 1 (next cube)
  86.  
  87. ; Get inside/outside flags..
  88.     move            #<cube,r4
  89.     move            x:<isolevel,b ;#>ISOLEVEL,b
  90.     clr    a        #>$100,x1
  91.     move                    y:(r4)+,x0
  92.     do    #8,_side_loop
  93.     cmp    x0,b
  94.     jlt    <_nextside
  95.     or    x1,a
  96. _nextside:
  97.     lsr    a                y:(r4)+,x0
  98. _side_loop:
  99.  
  100. ; Only polygonize if cube contains polygons.
  101.     move            #>edgeTable,r2
  102.     move            a,n2
  103.     move            a,x:<cubeIndex
  104.     move            x:(r2+n2),a
  105.     tst    a        a,x:<edgesCut
  106.     jne    <polygonize
  107.     
  108. _next:    move            #<2,n1
  109.     move            x:<posx,a
  110.     move            #>CUBEWIDTH,x0
  111.     add    x0,a        (r1)+n1                ; Proceed to next cube.
  112.     move            #>CUBEWIDTH*CUBES-GWIDTH/2,x0    ; Compensate for steperror.
  113.     cmp    x0,a        a,x:<posx
  114.     jlt    <_xloop
  115.  
  116.     move            #<2,n1
  117.     move            x:<posy,a
  118.     move            #>CUBEWIDTH,x0
  119.     add    x0,a        (r0)+                ; Proceed to next cube in y direction.
  120.     move            (r1)+n1
  121.     move            #>CUBEWIDTH*CUBES-GWIDTH/2,x0    ; Compensate for steperror.
  122.     cmp    x0,a        a,x:<posy
  123.     jlt    <_yloop
  124.  
  125.     move            #<WIDTH,n0
  126.     move            #<WIDTH*2,n1
  127.     move            x:<posz,a
  128.     move            #>CUBEWIDTH,x0
  129.     sub    x0,a        (r0)+n0                ; Proceed to next cube in z direction.
  130.     move            (r1)+n1
  131.     move            #>DISTANCE-CUBEWIDTH*CUBES,x0
  132.     cmp    x0,a        a,x:<posz
  133.     jge    <_zloop
  134.  
  135.     send    #-1                        ; I'll be back!
  136.     jmp    <main_loop
  137.  
  138. ; Polygonizes the isosurface within a cube.
  139. ; Note: no subroutine, jumps back to paintGrid_next.
  140. ; INPUT:
  141. ; x:r0: grid (V)
  142. ; x:r1: grad (u,v)
  143. polygonize:
  144.     move            r0,x:<tempR0
  145.     move            r1,x:<tempR1
  146.  
  147. ; Store (x,y,z) vertices in cubevertices..
  148.     move            #<posx,r2
  149.     move            #<cubeSrcVertices,r5
  150.     move            #<cubeDstVertices,r4
  151.     move            #<5-2,n4
  152.  
  153.     do    #8,_vertexloop
  154.     move            x:(r2)+,x0    y:(r5)+,a    ; x0=tx, a=x
  155.     add    x0,a        x:(r2)+,x0    y:(r5)+,b    ; a=x+tx, x0=ty, b=y
  156.     add    x0,b                a,y:(r4)+    ; b=y+ty, Store x+tx.
  157.     move                    b,y:(r4)+    ; Store y+ty.
  158.     move            x:(r2)-,x0    y:(r5)+,a    ; x0=tz, a=z
  159.     add    x0,a        (r2)-                ; a=z+tz
  160.     move                    a,y:(r4)+n4    ; Store z+tz, Proceed to next dst vertex.
  161. _vertexloop:
  162.  
  163. ; Store normals (u,v) in cubevertices.
  164.     move            #<WIDTH*2,n1
  165.     move            #<cubeDstVertices+3,r4
  166.     move            #<4,n4                ; n4=vectorwidth-1
  167.     move            (r1)+n1
  168.     move            x:(r1)+,b            ; width
  169.     move            x:(r1)+,a    b,y:(r4)+
  170.     move            #>PLANE_SIZE*2-1,n1
  171.     move            x:(r1)+,b    a,y:(r4)+n4    ; 1+width
  172.     move            x:(r1)+n1,a    b,y:(r4)+
  173.     move            #>-3,n1
  174.     move            x:(r1)+,b    a,y:(r4)+n4    ; 1+width+planesize
  175.     move            x:(r1)+n1,a    b,y:(r4)+
  176.     move            #>-(WIDTH+PLANE_SIZE)*2-1,n1
  177.     move            x:(r1)+,b    a,y:(r4)+n4    ; width+planesize
  178.     move            x:(r1)+n1,a    b,y:(r4)+
  179.     move            x:(r1)+,b    a,y:(r4)+n4    ; 0
  180.     move            x:(r1)+,a    b,y:(r4)+
  181.     move            #>PLANE_SIZE*2-1,n1
  182.     move            x:(r1)+,b    a,y:(r4)+n4    ; 1
  183.     move            x:(r1)+n1,a    b,y:(r4)+
  184.     move            #>-3,n1
  185.     move            x:(r1)+,b    a,y:(r4)+n4    ; 1+planesize
  186.     move            x:(r1)+n1,a    b,y:(r4)+
  187.     move            x:(r1)+,b    a,y:(r4)+n4    ; planesize
  188.     move            x:(r1),a    b,y:(r4)+
  189.     move                    a,y:(r4)
  190.  
  191. ; Calculate intersected vertices.
  192.     move            #<edgesCut,r5
  193.     move            #<cube,r0            ; r0: cube containing field
  194.     move            #<edgeRefTable,r2
  195.     move            #<cubeDstVertices,r4
  196.     move            #<vertexTable,r6
  197.     move            #<5,n6
  198.     move            x:(r5),a
  199.  
  200. _intersectloop:
  201.     lsr    a                y:(r2)+,y0    ; Test lsb, b=v1 index
  202.     jcc    <_next_edge
  203.     move            n6,x0                ; x0=vectorsize
  204.     mpy    y0,x0,b        y0,n0                ; n0=v1 index
  205.     asr    b        a,x:(r5)    y:(r2),y0    ; b0=v1 offset, Store cutedges, y0=v2 index
  206.     mpy    y0,x0,b        b0,n4                ; n4=v1 offset
  207.     asr    b                y:(r0+n0),x1    ; b0=v2 offset, x1=value1
  208.     lua    (r4)+n4,r3                    ; r3: vector1
  209.     move            y0,n0                ; n0=v2 index
  210.     move            b0,n4                ; n4=v2 offset
  211.     move                    y:(r0+n0),a    ; a=value2
  212.     move            x:<isolevel,b ;#>ISOLEVEL,b            ; b=isolevel
  213.     lua    (r4)+n4,r1                    ; r1: vector2
  214.     jsr    <intersect                    ; Intersect the 5d line.
  215.  
  216. ; Perspectivate the intersected vertex...
  217. ; todo: we're able to only do 16 div iterations, by prescaling Z.
  218.     move            #>128,y1
  219.     move            (r6)-n6
  220.     move                    y:(r6)+,x0    ; x0=X
  221.     mpy    y1,x0,a                y:(r6)+,x1    ; x1=Y
  222.     mpy    y1,x1,a        a0,x0                ; x0=X<<8
  223.     move            a0,x1                ; x1=Y<<8
  224.     move            #>1,a                ; a=1
  225.     move                    y:(r6)-,y0    ; y0=Z [1..8192]
  226.     andi    #$FE,ccr
  227.     rep    #24
  228.     div    y0,a                        ; a0=1/Z
  229.     move            a0,y0                ; y0=1/Z
  230.     move            #>100,a                ; a=x_center
  231.     move            #>160,b                ; b=y_center
  232.     macr    y0,x0,a        (r6)-                ; a=X'
  233.     macr    y0,x1,b                a,y:(r6)+    ; b=Y', Store X'.
  234.     move                    b,y:(r6)-    ; Store Y'.
  235.     move            x:<edgesCut,a            ; a=cut edges (shifted)
  236.  
  237. _next_edge:
  238.     move            (r2)+                ; Proceed to next indexpair.
  239.     tst    a        (r6)+n6                ; Proceed to next dst vertex.
  240.     jne    <_intersectloop
  241.  
  242. ; Generate the triangles...
  243.     move            x:<cubeIndex,x0
  244.     move            #8,x1
  245.     mpy    x0,x1,a        #>triTable,r0
  246.     move            a0,n0
  247.     move            #<vertexTable,r6
  248.     move            (r0)+n0
  249.  
  250. _triloop:
  251.     move            #<triangle,r1
  252.     move            x:(r0),a
  253.     tst    a        #>5,x0                ; End of triangle list?
  254.     jmi    <_end
  255.  
  256.     do    #3,_trivertexloop
  257. ; Store (x,y) and unsign, scale and store (u,v).
  258.     move            x:(r0)+,x1
  259.     mpy    x0,x1,a        #<vertexTable,r6
  260.     asr    a        #<$80,x1            ; a0=offset to vertex, x1=signer
  261.     move            a0,n6                ; n6=offset to vertex
  262.     move            #>$000800,y1            ; y1=upscalar
  263.     move            (r6)+n6                ; r6: vertex
  264.     move                    y:(r6)+,a    ; a= X'
  265.     move            a,x:(r1)+    y:(r6)+,b    ; b= Y', Store X'.
  266.     move            b,x:(r1)+    y:(r6)+,a    ; Store Y', dummy move.
  267.     move                    y:(r6)+,y0    ; y0=u (12b)
  268.     mpy    y1,y0,a                y:(r6),y0    ; a0=u (23b), y0=v (12b)
  269.     mpy    y1,y0,b        a0,a                ; b0=v (23b)
  270.     eor    x1,a        b0,b                ; Sign u.
  271.     eor    x1,b        #<triangle,r2            ; Sign v.
  272.     lsr    a        #<3,n2                ; Adjust u range [0..$7FFFFF]
  273.     lsr    b        a1,x:(r1)+            ; Adjust v range [0..$7FFFFF], Store u (unsaturated).
  274.     move            b1,x:(r1)+            ; Store v (unsaturated).
  275. _trivertexloop:
  276.  
  277. ; Perform backface culling...
  278.     move            x:(r2)+,a            ; a=X1
  279.     move            x:(r2)+n2,b            ; b=Y1
  280.     move            x:(r2)+,x0            ; x0=X2
  281.     sub    x0,a        x:(r2)+n2,x1            ; a=X1-X2, x1=Y2
  282.     sub    x1,b        x:(r2)+,a    a,y1        ; b=Y1-Y2, a=X3, y1=X1-X2
  283.     sub    x0,a        x:(r2),b    b,y0        ; a=X3-X2, b=Y3, y0=Y1-Y2
  284.     sub    x1,b        a,x0                ; b=Y3-Y2, x0=X3-X2
  285.     mpy    +x0,y0,a    b,x1                ; a=-(X3-X2)(Y1-Y2), x1=Y3-Y2
  286.     mac    -y1,x1,a    r0,x:<saveR0            ; a=+(X1-X2)(Y3-Y2)-(X3-X2)(Y1-Y2), Save tritable pos.
  287.     jle    <_triloop                    ; n.z<=0 ? -> cull it.
  288.  
  289. ; Paint the triangle.. Note: no clipping!
  290.     move            #<triangle,r0
  291.     jsr    <Polygon.getDimensions
  292.     move            #<triangle,r0
  293.     move            #<triangle+3*4,r5
  294.     move            r0,r6
  295.     do    #4,_wraploop
  296.     move            x:(r0)+,x0
  297.     move            x0,x:(r5)+
  298. _wraploop:    
  299.     jmp    <paintTriangle
  300. _next_tri:
  301.     move            x:<saveR0,r0
  302.     jmp    <_triloop
  303.  
  304. _end:    move            x:<tempR0,r0
  305.     move            x:<tempR1,r1
  306.     jmp    <paintGrid_next
  307.  
  308. ; Intersect a 5d line. Coordinates should have 16bit signed range!
  309. ; slope = (isolevel-v1)/(v2-v1)
  310. ; timing: 75+2n+(4/2) cycles =>{n=24}=>123+(4/2)
  311. ; INPUT:
  312. ; b = isolevel
  313. ; x1= v1
  314. ; a = v2
  315. ; y:r3: vertex1
  316. ; y:r1: vertex2
  317. ; y:r6: dst vertex
  318. ; OUTPUT:
  319. ; y:r6: next dst vertex
  320. intersect:
  321.     sub    x1,b        #>256,y0            ; b=isolevel-v1, y0=upscalar
  322.     sub    x1,a                b,y1        ; a=v2-v1, y1=isolevel-v1
  323.     mpy    y0,y1,b        a,x0                ; b0=(isolevel-v1)<<(8+n), x0=v2-v1 (denominator)
  324.     abs    b                y:(r3)+,x1    ; Make numerator positive (required by div), x1=p1[0]
  325.     eor    y1,a                y:(r1)+,y0    ; Get sign (saved for jpl), y0=p2[0]
  326.     andi    #$FE,ccr                    ; Clear carrybit (required by div).
  327.     rep    #24
  328.     div    x0,b                        ; b= (isolevel-v1)<<8/(v2-v1) = slope
  329.     jpl    <_signed                    ; Sign quotient if appropriate.
  330.     neg    b
  331. _signed:tfr    y0,b        b0,y1                ; b=p2[0], y1=slope
  332.     sub    x1,b        #>1<<14,x0            ; a=p2[0]-p1[0]=d[0], x0=downscalar
  333.  
  334.     do    #5,_loop
  335.     tfr    x1,a        b,y0                ; a=p1[n], y0=d[n]
  336.     mpy    y1,y0,b                y:(r3)+,x1    ; b=slope*d[n], x1=p1[n+1]
  337.     move            b0,y0                ; y0=slope*d[n]
  338.     macr    y0,x0,a                y:(r1)+,b    ; a=p1[n]+slope*d[n]=coord, b=p2[n+1]
  339.     sub    x1,b                a,y:(r6)+    ; b=d[n+1], Store coord.
  340. _loop:
  341.     rts
  342.  
  343. ;- polygon routines --------------------------------------------------------
  344. ;
  345. ;
  346.  
  347. ; Not a subroutine, returns to polygonize_next_tri.
  348. ; Definetely the fastest scan converter around.
  349. ; USES:
  350. ; x:Polygon.vsize: 1=flat shade, 2=gouraud, 3=tmap, 4=gourtmap, 5=envtmap/bump
  351. ; INPUT:
  352. ; x:(r6): polygon table
  353. ; PRE:
  354. ; polygon must be wrapped
  355. paintTriangle:
  356.     move            #<3,n6
  357.     move            #>InverseTable,r3
  358.     move            #>Polygon.LeftEdge,r0
  359.     move            #>Polygon.RightEdge,r1
  360.     move            n6,n5
  361.     move            n6,r4
  362.     move            r6,r5
  363.     move            (r4)+
  364.     move            (r6)+n6                ; to next point
  365.     move            (r6)+
  366.     move            r4,n4                ; n4= offset to next point
  367.  
  368. ; r5: pt1, r6: next pt
  369.     do    x:<Polygon.points,_do_line
  370.     move            x:(r5)+,a            ; a=current point's y
  371.     move            r6,r4
  372.     move            x:(r6)+,b            ; b=next point's y
  373.     sub    a,b        x:<Polygon.top,y1
  374.     jlt    <_do_left_side
  375.     jeq    <_end_line
  376.     move            b,n3
  377.     move            r0,b
  378.     jmp    <_end_swap
  379. _do_left_side:
  380. ; Calculate start y offset.
  381. ; Swap left and right edges.
  382.     add    b,a        r5,x0
  383.     neg    b        r6,r5
  384.     move            b,n3
  385.     move            x0,r6
  386.     move            r1,b
  387. _end_swap:
  388.     sub    y1,a        n6,x0                 ; a=startoffset
  389.     move            a,y1
  390.     mpy    x0,y1,a                        ; a0=startoffset*vsize*2
  391.     asr    a        n6,n2                ; a0=startoffset*vsize 
  392.     move            a0,x0
  393.     add    x0,b        r0,y0
  394.     move            b,r0
  395.  
  396. ; Speedy.. but could be better when doing u and v in one go.
  397.     do    n6,_coord_loop
  398.     move            x:(r5)+,x0            ; x0= left x
  399.     tfr    x0,a        x:(r6)+,b            ; a= left x, b= right x
  400.     sub    x0,b                y:(r3+n3),y1    ; b=x1-x0=dx, y1=1/dy
  401.     move            b1,x1                ; x1=dx
  402.     mpy    x1,y1,b        r0,r2                 ; b=x1/dy, r2=edge
  403.  
  404. ; rep is shit with interrupts :(
  405. ;    rep    n3
  406.     do    n3,_bla
  407.     add    b,a                a1,y:(r2)+n2    ; a=lx:=lx+step, store lx
  408. _bla:
  409.  
  410.     move            (r0)+                ; Proceed to next coord.
  411. _coord_loop:
  412.     move            y0,r0                ; Back to x coord
  413.  
  414. _end_line:
  415.     move            r4,r5                ; r5=current point
  416.     lua    (r4)+n4,r6                    ; r6=next point
  417. _do_line:
  418.  
  419. ; Paints (sends to host) a texturemapped polygon.
  420.     send    x:<Polygon.top                    ; Send minimum y.
  421.     move            x:<Polygon.height,a        ; a=height
  422.     send    a                        ; Send height.
  423.     tst    a        a,n6                ; n6=height
  424.     jle    <polygonize_next_tri                ; Next triangle..
  425.     move            #>Polygon.LeftEdge,r0
  426.     move            #>Polygon.RightEdge,r1
  427.     move            #>InverseTable,r2
  428.     move            #>texture,r4
  429.  
  430. ; hline loop
  431.     do    n6,_yloop
  432.  
  433.     move                    y:(r0)+,x0
  434.     send    x0                        ; Send lx.
  435.     move                    y:(r1)+,a    ; a=rx.
  436.     sub    x0,a                y:(r0)+,x0    ; x0=u_start
  437.     move            a1,n2                ; n2=width
  438.     send    a1                        ; Send width.
  439.     move                    y:(r1)+,x1    ; x1=u_end
  440.     move                    y:(r0)+,y0    ; y0=v_start
  441.     move                    y:(r1)+,b    ; b=v_end
  442.     tst    a        x1,a                ; test for 0-width, a := u_end
  443.     jle    <_skip_line
  444.     sub    x0,a                y:(r2+n2),x1    ; du=u_end-u_start, x1=divisor
  445.     sub    y0,b        a1,y1                ; dv=v_end-v_start, y1=du
  446.     mpy    x1,y1,a        b1,y1                ; a=u_step=du/divisor, y1=dv
  447.     mpy    x1,y1,b        a1,x1                ; b=v_step=dv/divisor, x1=u_step
  448.     tfr    x0,a        b1,x0                ; a1=u, x0=v_step
  449.     move            y0,a0                ; a0=v
  450.     
  451. ; a1=u, a0=v, x1=u_step, x0=v_step
  452.     move            x:<texturesize,y0
  453.     move            x,l:<u0_step
  454.     move            a1,y1
  455.  
  456. ; Only nonnegative coords permitted!
  457. ; (0,0) (7FFFFF,0)
  458. ; x     x
  459. ;
  460. ;    x(3FFFFF,3FFFFF)
  461. ;
  462. ; x     x(7FFFFF,7FFFFF)
  463. ; (0,7FFFFF)
  464.  
  465. ; 5 calculation instructions = 5*2 = 10 cycles
  466. ; 1 host send >= 8 or 10 cycles
  467. ; total >= 18 or 20 cycles per pixel
  468.     do    n2,_send_pixel
  469.     mpyr    y1,y0,b        l:<texturemask,x        ; b=offset=u*texturesize, x1=width, x0=mask
  470.     and    x0,b        a0,y1                ; kill frag_u, y1=v
  471.     mac    y1,x1,b        l:<u0_step,x            ; offset:=offset+v, x1=u_step, x0=v_step
  472.     add    x,a        b1,n4                ; u:=u+u_step, v:=v+v_step
  473.     move            a1,y1                ; y1=u
  474.     jclr    #1,x:<<HSR,*                    ; Wait until host is ready.
  475.     movep    y:(r4+n4),x:<<HTX                ; Send texturepixel.
  476. _send_pixel:
  477.  
  478. _skip_line:
  479.     nop
  480. _yloop:    jmp    <polygonize_next_tri                ; Next triangle..
  481.  
  482. ; Get top and bottom of polygon.
  483. ; INPUT:
  484. ; x:(r0): polygon table
  485. Polygon.getDimensions:
  486.     move            #>$7FFFFF,a            ; top := MAX_INT
  487.     move            #<$80,b                ; bottom := MIN_INT
  488.     move            x:<Polygon.vsize,n0
  489.  
  490.     do    x:<Polygon.points,_loop
  491.     move            x:(r0)+,y0            ; Fetch Vertex.Y.
  492.     cmp    y0,a        (r0)+n0                ; Proceed to next Vertex.
  493.     tgt    y0,a                        ; If new value is lower, set new top.
  494.     cmp    y0,b
  495.     tlt    y0,b                        ; If new value is higher, set new bottom.
  496. _loop:
  497.     sub     a,b        a,x:<Polygon.top        ; Store top, height := bottom-top
  498.     move            b,x:<Polygon.height        ; Store height.
  499.     rts
  500.  
  501. ;- field routines ----------------------------------------------------------
  502. ;
  503. ;
  504.  
  505. ; Get centers of balls from host.
  506. getBallPositions:
  507.     get    x:isolevel
  508.     move            #<posTable,r0
  509.     move            #>GWIDTH*2/9,x1
  510.     do    #3*NUM_BALLS,_loop
  511.     get    x0
  512.     mpy    x1,x0,a
  513.     move            a,x:(r0)+            ; Store coordinate.
  514. _loop:    rts
  515.  
  516. ; field and paint combined, no subrout, jumps back to main_loop.
  517. keepstacklow:
  518. ;---------------------------------------------------------------------------
  519. ; Calculates a metaball field.. Pretty intense due to div and sqrt.
  520. ;
  521. ; n:  amount of balls
  522. ; bi: ball number i
  523. ; ri: radius of ball
  524. ;
  525. ;     2                2          2          2
  526. ; (ri)      =  (x-bi.x) + (y-bi.y) + (z-bi.z)
  527. ;
  528. ;              -- n
  529. ; V(x,y,z)  =  \        -2
  530. ;              /    (ri)
  531. ;              -- 1
  532. ;               
  533. ;              -- n
  534. ;              \          -4 [bi.x-x]
  535. ; grad(V)   =  /    2*(ri)  *[bi.y-y] (and then to normalise it..)
  536. ;              -- 1          [bi.z-z]
  537. ;
  538. ;---------------------------------------------------------------------------
  539. ; Preparations: calculate (squared) distances
  540.     move            #<distTable,r1
  541.     move            #distSTable,r4
  542.     move            #>GWIDTH/2,a
  543.     move            #>CUBEWIDTH,x1
  544.  
  545.     do    #WIDTH,_widthloop
  546.     tfr    a,b        #<posTable,r0
  547.  
  548.     do    #NUM_BALLS*3,_coordloop
  549.     move            x:(r0)+,x0            ; x0=coord
  550.     sub    x0,b                        ; b=distance
  551.     move            b,x:(r1)+    b,y0        ; Store distance.
  552.     mpy    y0,y0,b                        ; Square distance.
  553.     tfr    a,b        b,l:(r4)+            ; b=gridoffset, Store square.
  554. _coordloop:
  555.  
  556.     sub    x1,a                        ; a=next gridoffset
  557. _widthloop:
  558.  
  559. ; Calculate field and normals..
  560.     move            #gradfield,x0
  561.     move            #field,r0
  562.     move            x0,x:<tempR1            ; Save gradfield adr.
  563.     move            #distSTable+2,r1
  564.     move            #<distTable+2,r4
  565.     move            #<3,n3
  566.     move            #<3,n6
  567.  
  568. _zloop:    move            #distSTable+1,r2
  569.     move            #<distTable+1,r5
  570.  
  571.     do    #WIDTH,_yloop
  572.     move            #distSTable,r3
  573.     move            #<distTable,r6
  574.  
  575.     do    #WIDTH,_xloop
  576.     move            #<NUM_BALLS,n0
  577.  
  578. ; Step 1: calculate actual field
  579.     clr    a        r1,x:<zDistAdr            ; Save dz adr.
  580.     move            a,x:<val            ; Clear value.
  581.     move            #<3,n1
  582.     move            #<3,n2
  583.  
  584.     do    #NUM_BALLS,_bloop
  585.     clr    b        l:(r1)+n1,a            ; a=dz^2
  586.     move            l:(r2)+n2,x            ; x=dy^2
  587.     add    x,a        l:(r3)+n3,x            ; a=dy^2+dz^2, x=dx^2
  588.     add    x,a        #>$000800,y0            ; a=r^2=dx^2+dy^2+dz^2, y0=downscalar
  589.     move            a0,b1
  590.     lsr    b        a1,x1                ; shift b for frac dumbness
  591.     mpy    y0,x1,b        b,x0                ; b0=scaled r (int), x0=r (frac)
  592.     mpy    y0,x0,a        b0,b                ; a1=scaled r (frac), b=scaled r (int)
  593.     addl    b,a        y0,b                ; a1=scaled r, b=1<<shift
  594.     move            a1,x0                ; x0=scaled r
  595.     rep    #24
  596.     div    x0,b                        ; b0=r^-2
  597.     move            x:<val,a0            ; a0=partial value[n-1]
  598.     add    b,a        b0,x0                ; x0=r^-2, a0=partial value[n]
  599.     mpy    x0,x0,a        a0,x:<val            ; a0=r^-4, Store partial value[n].
  600.     move            a,x:(r0)+            ; Store r^-4.
  601. _bloop:    move            x:<val,a1
  602.     lsr    a        #<3,n4
  603.     move            a1,x0
  604.     mpy    y0,x0,a        #<3,n5                ; a=downscaled value
  605.     move            a1,x:<val            ; Store value.
  606.  
  607. ; Step 2: calculate gradient vector
  608.     clr    a        (r0)-n0                ; a=0, r0: first r^-4
  609.     do    #NUM_BALLS,_gloopz
  610.     move            x:(r0)+,x0            ; x0=r^-4
  611.     move            x:(r4)+n4,x1            ; x1= dz
  612.     mac    x0,x1,a                        ; a=dz/r^4+..
  613. _gloopz:move            a,y0                ; y0=dz/r^4+..
  614.     clr    a        (r0)-n0                ; a=0, r0: first r^-4
  615.     do    #NUM_BALLS,_gloopy
  616.     move            x:(r0)+,x0
  617.     move            x:(r5)+n5,x1            ; x1= dy
  618.     mac    x0,x1,a                        ; a=dy/r^4+..
  619. _gloopy:move            a,y1                ; y1=dy/r^4+..
  620.     clr    a        (r0)-n0                ; a=0, r0: first r^-4
  621.     do    #NUM_BALLS,_gloopx
  622.     move            x:(r0)+,x0
  623.     move            x:(r6)+n6,x1            ; x1= dx
  624.     mac    x0,x1,a                        ; a=dx/r^4+..
  625. _gloopx:
  626.     mpy    y0,y0,a        a,x0                ; dx^2/r^8, x0=dx/r^4
  627.     mac    x0,x0,a        y1,x1                ; dx^2/r^8+dy^2/r^8, x1=dz/r^4
  628.     mac    x1,y1,a        x0,y0                ; dx^2/r^8+dy^2/r^8+dz^2/r^8, y0=dy/r^4
  629.     asr    a        (r0)-n0                ; Adjust fracshit, Save field adr.
  630.  
  631.     move            r0,x:<tempR0
  632.     move            a0,a                ; a1= int
  633.     clr    b        #>1,x1                ; b1 will be left_part(number) - (r0/2)**2
  634.     move            b,r0                ; r0 will be sqrt(number) * 2
  635.     move            a1,b0                ; b0= number [shifts left into b1]
  636.     move            #<2,n1
  637.     do    #12+ROUND,_loop                    ; 2 bits at a time for 24 bits in total
  638.     asl    b        r0,n0
  639.     asl    b                        ; b1= left_part(number)
  640.     tfr    b,a        (r0)+n0                ; a1/a0 is copy of b1/b0, r0:=2*r0
  641.     sub    x1,a        r0,r1
  642.     move    r0,x0
  643.     sub    x0,a        (r1)+n1                ; a1=b1-r0-1, r1=r0+2
  644.     tpl    a,b        r1,r0                ; if b1>r0 then b1:=b1-r0-1, r0:=r0+2
  645. _loop:    move            r0,a                ; a1=r0
  646.     asr    a        x:<tempR0,r0            ; a1=r0/2 = sqrt(number), r0: field 
  647.     IFNE    ROUND
  648.     move            #<2,a0                ; Force round up not convergent rounding
  649.     asr    a
  650.     rnd    a                        ; Round up, a1=sqrt
  651.     ENDC
  652.  
  653.     move            x:<tempR1,r1            ; r1: gradfield
  654.     clr    a        a1,x0                ; x0=sqrt
  655.     move            #>$7FFFFF,a0            ; a=.999999
  656.     rep    #24
  657.     div    x0,a                        ; a0=1/sqrt(dx^2/r^8+dy^2/r^8+dz^2/r^8)
  658.     move            a0,x0
  659.     mpy    x0,y0,a        #>$000800,x1            ; a=dy/r^4*sqrt(dx^2/r^8+dy^2/r^8+dz^2/r^8)=n.x, x1=downscalar
  660.     mpy    x0,y1,b        a0,y0                ; b=dx/r^4*sqrt(dx^2/r^8+dy^2/r^8+dz^2/r^8)=n.y, y0=n.x
  661.     mpy    x1,y0,a        b0,y1                ; a=scaled n.x, y1=n.y
  662.     mpy    x1,y1,b        a,x:(r1)+            ; b=scaled n.y, store n.x.
  663.     move            b,x:(r1)+            ; Store n.y.
  664.     move            r1,x:<tempR1            ; Save gradfield adr.
  665.  
  666.     move            x:<val,x0            ; x0=value
  667.     move            x0,x:(r0)+            ; Store value at right place, and proceed to next.
  668.     move            #<NUM_BALLS*3,n2
  669.     move            #<NUM_BALLS*3,n4
  670.     move            #<NUM_BALLS*3,n5
  671.     move            x:<zDistAdr,r1            ; r1: dz^2
  672.     move            (r2)-n2                ; Reset dy^2.
  673.     move            (r4)-n4                ; Reset dz.
  674.     move            (r5)-n5                ; Reset dy.
  675. _xloop:
  676.  
  677.     move            #<NUM_BALLS*3,n2
  678.     move            #<NUM_BALLS*3,n5
  679.     move            (r2)+n2                ; Proceed to next dy^2.
  680.     move            (r5)+n5                ; Proceed to next dy.
  681. _yloop:
  682.  
  683.     move            #<NUM_BALLS*3,n1
  684.     move            #<NUM_BALLS*3,n4
  685.     move            (r1)+n1                ; Proceed to next dz^2.
  686.     move            (r4)+n4                ; Proceed to next dz.
  687.     move            r1,a
  688.     move            #>distSTable+2+NUM_BALLS*3*WIDTH,x0
  689.     cmp    x0,a                        ; Done all?
  690.     jlt    <_zloop                        ; no -> loop
  691.     jmp    <paintGrid                    ; yes -> end and paint
  692.  
  693. ;- various -----------------------------------------------------------------
  694. ;
  695. ;
  696.  
  697. ; Initialization routine..
  698. init:
  699. ; Initialize poly stuff..
  700.     move            #>3,x0
  701.     move            x0,x:<Polygon.vsize
  702.     move            x0,x:<Polygon.points
  703.  
  704. ; Init trajectory thru host comms.
  705.     send    #NUM_BALLS                    ; Request amount from host.
  706.  
  707. ; Receive buffers.
  708.     move            #>4096,n0
  709.     move            #>texture,r0
  710.     do    n0,_txtloop
  711.     get    y:(r0)+
  712. _txtloop:
  713.     move            #>edgeTable,r0
  714.     do    #256,_edgeloop
  715.     get    x:(r0)+
  716. _edgeloop:
  717.     move            #>triTable,r0
  718.     do    n0,_triloop
  719.     get    x:(r0)+
  720. _triloop:
  721.  
  722. ; Calculate inversetable.
  723.     move            #>InverseTable,r0
  724.     clr    a        #>1,x0
  725.     do    #200,_invloop
  726.     tfr    x0,b        a,x1
  727.     andi    #$FE,ccr
  728.     rep    #24
  729.     div    x1,b
  730.     add    x0,a                b0,y:(r0)+
  731. _invloop:
  732.  
  733.     rts
  734.  
  735. ;= x memory ================================================================
  736.  
  737.     org    x:0
  738.  
  739. ; poly paint stuff
  740. texturewidth:
  741.     dc    64                        ; texture v width
  742. u0:    ds    1
  743. u0_step:ds    1                        ; u_step storage
  744. texturesize:
  745.     dc    64*64                        ; texture size
  746.  
  747. posx:    ds    1
  748. posy:    ds    1
  749. posz:    ds    1
  750.  
  751. Polygon.top:
  752.     ds    1
  753. Polygon.height:
  754.     ds    1
  755. Polygon.points:
  756.     ds    1
  757. Polygon.vsize:
  758.     ds    1
  759. cubeIndex:
  760.     ds    1
  761. edgesCut:
  762.     ds    1
  763. tempR0:    ds    1
  764. tempR1:    ds    1
  765. saveR0:    ds    1
  766. zDistAdr:
  767.     ds    1
  768. val:    ds    1
  769. isolevel:
  770.     ds    1
  771.  
  772. triangle:
  773.     ds    4*4
  774.  
  775. posTable:
  776.     ds    NUM_BALLS*3                    ; (x,y,z)
  777. distTable:
  778.     ds    WIDTH*NUM_BALLS*3                ; a00(x,y,z),b01(x,y,z),....,
  779.  
  780. ;= external x memory =======================================================
  781.  
  782.     org    x:$300
  783.  
  784. distSTable:
  785.     ds    WIDTH*NUM_BALLS*3                ; long mem crap, must be in phase with y mem!
  786. edgeTable:
  787.     ds    256
  788. triTable:
  789.     ds    4096
  790. field:    ds    FIELD_SIZE+NUM_BALLS                ; V, overflow required for opt!
  791. gradfield:
  792.     ds    FIELD_SIZE*2                    ; (u,v)
  793. x_end:
  794.  
  795. ;= internal y memory =======================================================
  796.  
  797.     org    y:0
  798.  
  799. ; poly paint stuff
  800. texturemask:
  801.     dc    $000FC0                        ; v_frag mask
  802. v0:    ds    1
  803. v0_step:ds    1                        ; v_step storage
  804. vertexTable:
  805.     ds    12*5                        ; intersected vertices (x,y,z,u,v)
  806. cubeSrcVertices:
  807.     dc    0,CUBEWIDTH,CUBEWIDTH
  808.     dc    CUBEWIDTH,CUBEWIDTH,CUBEWIDTH
  809.     dc    CUBEWIDTH,CUBEWIDTH,0
  810.     dc    0,CUBEWIDTH,0
  811.     dc    0,0,CUBEWIDTH
  812.     dc    CUBEWIDTH,0,CUBEWIDTH
  813.     dc    CUBEWIDTH,0,0
  814.     dc    0,0,0
  815. edgeRefTable:
  816.     dc    0,1,1,2,3,2,0,3                    ; front
  817.     dc    4,5,5,6,7,6,4,7                    ; back
  818.     dc    0,4,1,5,2,6,3,7                    ; joint
  819. cube:    ds    8
  820. cubeDstVertices:
  821.     ds    8*5
  822.  
  823. ;= external y memory =======================================================
  824.  
  825.     org    y:$300
  826.  
  827. ;distSTable:
  828.     ds    WIDTH*NUM_BALLS*3                ; long mem crap, must be in phase with x mem!
  829. InverseTable:
  830.     ds    200
  831. texture:ds    4096                        ; 64*64 highcolor texture
  832. Polygon.LeftEdge:
  833.     ds    3*200                        ; (x,u,v)*scans
  834. Polygon.RightEdge:
  835.     ds    3*200
  836. y_end:
  837.