home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / OUT.ZIP / SOURCE.ZIP / KALEIDO.SO < prev    next >
Text File  |  2004-01-15  |  47KB  |  2,287 lines

  1. ; 3d kaleidoscope involving spacecut alike stuff.
  2. ;
  3. ; The idea for the effect is as follows:
  4. ;
  5. ; 1) decode u-fly object to clipper format
  6. ; 2) clip the object, keeping track of new and old vertices
  7. ; 3) encode the clipped object to u-fly again
  8. ; 4) mirror the object using the ref-data you have efficiently
  9. ; 5) u-fly engine madness
  10. ;
  11. ; Might seem a bit dodgy, but actually it's better than doing the clipping
  12. ; with references. You see, vertices come and go with every plane-clip.
  13. ; To avoid major redundancy you would have needed very nasty routs to purge
  14. ; obsolete vertices!!
  15. ;
  16. ; TODO:
  17. ; 1) bug fucking: wrong normal intersection, (backface fuck)
  18. ; what is this hellcrap? tried to fix it for ages, but i'm losing my mind
  19. ; here. maybe it's just a thing inherent to integer precision, i don't know.
  20. ; 2) make opt version run on std falcon.
  21.  
  22. ;******* OBJECT TABLE ********
  23.  
  24.     IFND    DEMO_SYSTEM
  25. testmode:    =    0
  26.     move.l    #Kaleido.table,fxAdr
  27.     INCLUDE    TESTER.S
  28.     TEXT
  29.     INCLUDE    SFLY_DSP.S
  30.     TEXT
  31.     INCLUDE    OBJECT3D.I
  32.     TEXT
  33.     ENDC
  34.  
  35. ;******* OBJECT EQUATES ********
  36.  
  37. Kaleido.BLOCKCLEARING:        =    0        ; 'fast' clearing..
  38. Kaleido.NORMAL_CORRECTION:    =    0
  39. ; Total amount of vertices + normals is 16 times this amount, so keep low!
  40. Kaleido.MAX_VERTICES:        =    64
  41. Kaleido.MAX_CVERTICES:        =    256
  42.  
  43. ******** Matrix
  44.  
  45.         RSRESET
  46. matrixXX:    RS.W    1
  47. matrixXY:    RS.W    1
  48. matrixXZ:    RS.W    1
  49. matrixYX:    RS.W    1
  50. matrixYY:    RS.W    1
  51. matrixYZ:    RS.W    1
  52. matrixZX:    RS.W    1
  53. matrixZY:    RS.W    1
  54. matrixZZ:    RS.W    1
  55. matrixTX:    RS.L    1
  56. matrixTY:    RS.L    1
  57. matrixTZ:    RS.L    1
  58. matrixSize:    RS.B    0
  59.  
  60. Kaleido.table:
  61.     DC.L    Kaleido.mainLoop
  62.     DC.L    Kaleido.init
  63.     DC.L    Kaleido.initRT
  64.     DC.L    Kaleido.deinitRT
  65.     DC.L    Kaleido.switchRot
  66.     DC.L    0
  67.  
  68. ;******* RESOLUTION SETTING ROUTINE ********
  69.  
  70. Kaleido.initRT:
  71.     move.l    #rts,vbl_gfx
  72.  
  73.     bsr.l    HumanFly.init
  74.  
  75.     lea    Viewport.settingsTable,a0
  76.     move.w    #320,Viewport.XSCREEN(a0)
  77.     move.w    #200,Viewport.YSCREEN(a0)
  78.     move.w    #0,Viewport.XSTART(a0)
  79.     move.w    #0,Viewport.YSTART(a0)
  80.     move.w    #320,Viewport.XEND(a0)
  81.     move.w    #200,Viewport.YEND(a0)
  82.     move.w    #160,Viewport.XCENTER(a0)
  83.     move.w    #100,Viewport.YCENTER(a0)
  84.     move.w    #256+32,Viewport.ASPECT(a0)
  85.     move.w    #$100,Viewport.FOCAL(a0)
  86.     bsr.l    Viewport.update
  87.  
  88.     lea    Kaleido.textureTable,a0
  89.     bsr.l    Polygon.init
  90.  
  91.     bsr.l    ObjectRegistry.clear
  92.  
  93. ;    lea    Kaleido.object,a0
  94. ;    move.l    #Object3d.spikeyEnd-Object3d.spikey,d0
  95. ;    bsr    ObjectRegistry.set
  96.  
  97.     move.w    monitormode,d0
  98.     cmpi.w    #vga60,d0
  99.     beq.s    .vga60
  100.     cmpi.w    #vga100,d0
  101.     beq.s    .vga100
  102.     cmpi.w    #rgb50,d0
  103.     beq.s    .rgb50
  104. ; Unknown monitormode..
  105. .end:    rts
  106. .vga60:    move.l    #vga60_16bit_320_200,resRout
  107.     rts
  108. .vga100:move.l    #vga100_16bit_320_200,resRout
  109.     rts
  110. .rgb50:    move.l    #rgb50_16bit_320_200,resRout
  111.     rts
  112.  
  113. ;******* INIT SUBROUTINE ********
  114.  
  115. ; OUTPUT:
  116. ; d0.l: =0 all clear, <0 error
  117. Kaleido.init:
  118.     lea    sine_tbl,a1
  119.     bsr.l    Matrix.init
  120.  
  121.     lea    Object3d.spikey,a1
  122.     move.l    #Object3d.spikeyEnd-Object3d.spikey,d0
  123.     lea    Kaleido.spikey,a0
  124.     bsr.l    Object3d.copy
  125.  
  126.     lea    Kaleido.spikey,a0
  127.     move.w    #0,d0
  128.     move.w    #8,d1
  129.     move.w    #$200/5,d2
  130.     bsr.l    Object3d.scale
  131.     lea    Kaleido.spikey,a0
  132.     move.w    #8,d0
  133.     move.w    #6,d1
  134.     move.w    #$0080,d2
  135.     bsr.l    Object3d.scale
  136.  
  137.     lea    Kaleido.spikey,a1
  138.     move.l    #Object3d.spikeyEnd-Object3d.spikey,d0
  139.     lea    Kaleido.object,a0
  140.     bsr.l    Object3d.copy
  141.  
  142. .success:
  143.     moveq    #0,d0
  144.     rts
  145. .error:    moveq    #-1,d0
  146.     rts
  147.  
  148. Kaleido.deinitRT:
  149.     rts
  150.  
  151. ;******* SCREENINIT SUBROUTINE ********
  152.  
  153. Kaleido.initScreen:
  154.     movea.l    scr,a0
  155.     bsr.l    CLEAR_320200TSCR
  156.     rts
  157.  
  158. ;******* MAINLOOP SUBROUTINE ********
  159.  
  160. Kaleido.mainLoop:
  161.     move.w    $0468.w,.old468
  162.  
  163.     move.l    frmcnt,d0
  164.     sub.l    lastframecount,d0
  165.     cmpi.l    #3,d0
  166.     bhs.s    .end_screeninit
  167.     bsr    Kaleido.initScreen
  168. .end_screeninit:
  169.  
  170.     bsr    Kaleido.getRotPos
  171. ;    bsr    getTime
  172.  
  173.     move.w    d0,d1
  174.     move.w    d0,d2
  175.     mulu.w    #11,d0
  176.     lsr.l    #2,d0
  177.     mulu.w    #3,d1
  178.     mulu.w    #7,d2
  179.     lsr.l    d1
  180.     lsr.l    d2
  181.     bsr.l    Kaleido.generateMatrix
  182.  
  183.     bsr    Kaleido.getRotPos
  184.     move.w    d0,d1
  185.     bsr    getTime
  186.     move.w    d0,d2
  187.     move.w    d1,d0
  188.     mulu.w    #5,d1
  189.     lsr.l    #3,d1
  190.     mulu.w    #3,d2
  191.     lsr.l    #2,d2
  192.     subi.w    #sintbllen/4,d0
  193.     subi.w    #sintbllen/4,d1
  194.     subi.w    #sintbllen/4,d2
  195.     Do_SinModulo    d0
  196.     Do_SinModulo    d1
  197.     Do_SinModulo    d2
  198.     lea    sine_tbl,a1
  199.     Get_Sin    a1,d0,d0
  200.     Get_Sin    a1,d1,d1
  201.     Get_Sin    a1,d2,d2
  202.     addi.w    #$8000,d0
  203.     addi.w    #$8000,d1
  204.     addi.w    #$8000,d2
  205.     lsr.w    #6,d0
  206.     lsr.w    #6,d1
  207.     lsr.w    #6,d2
  208.     bsr.l    Kaleido.translate
  209.  
  210.     lea    Kaleido.object,a0
  211.     lea    Kaleido.spikey,a2
  212.     bsr.l    Kaleido.transform
  213.  
  214.     lea    Kaleido.clippedObject,a0
  215.     lea    Kaleido.object,a1
  216.     bsr.l    Kaleido.testClip
  217. ; d0.l=size, a0: obj
  218.  
  219. ;    bsr.l    Kaleido.paintClippedObjectOpt
  220.     bsr.l    Kaleido.paintClippedObject
  221.  
  222.     lea    scr,a0
  223.     move.l    (a0)+,d0
  224.     move.l    (a0)+,d1
  225.     move.l    (a0),-4(a0)
  226.     move.l    d0,(a0)
  227.     move.l    d1,-8(a0)
  228.     movea.l    resRout,a0
  229.     suba.l    a1,a1
  230.     movea.l    d0,a2
  231.     bsr.l    Screen.requestUpdate
  232.     clr.l    resRout
  233.  
  234.     move.w    .old468(pc),d0
  235. .wait:    cmp.w    $0468.w,d0
  236.     beq.s    .wait
  237.  
  238.     rts
  239.  
  240. .old468:DC.W    0
  241.  
  242. ;******* OBJECT SUBROUTINES ********
  243.  
  244. Kaleido.switchRot:
  245.     bsr    Kaleido.getRotPos
  246.     move.l    d0,Kaleido.oldRotPos
  247.     bsr    getTime
  248.     move.l    d0,Kaleido.rotSwitchTime
  249.     neg.w    Kaleido.rotDir
  250.     not.l    Kaleido.bgColor
  251.     rts
  252.  
  253. Kaleido.getRotPos:
  254.     bsr    getTime
  255.     sub.l    Kaleido.rotSwitchTime,d0            ; t-T (T<=t)
  256.     muls.w    Kaleido.rotDir,d0                ; d(t-T)
  257.     add.l    Kaleido.oldRotPos,d0                ; OP+d(t-T)
  258.     rts
  259.  
  260. Kaleido.bgColor:
  261.     DS.L    1
  262. Kaleido.rotSwitchTime:
  263.     DS.L    1
  264. Kaleido.oldRotPos:
  265.     DS.L    1
  266. Kaleido.rotDir:
  267.     DC.W    +1
  268.  
  269. * Seems to work ok, since there has been some patching on the overflow
  270. * errors (caused by combination of finite accuracy and use of maximum range)
  271. * INPUT: d0.w: X rotation (a)
  272. *        d1.w: Y rotation (b)
  273. *        d2.w: Z rotation (c)
  274. Kaleido.generateMatrix:
  275.     lea    Kaleido.matrix,a0
  276. * 1> rotate 3 axis.
  277.     Do_SinModulo    d0
  278.     Do_SinModulo    d1
  279.     Do_SinModulo    d2
  280.     movea.w    d0,a3
  281.     movea.w    d1,a4
  282.     movea.w    d2,a5
  283.     lea    sine_tbl,a2
  284.  
  285. * X := + x*cos(b)*cos(c)
  286. *      - y*cos(b)*sin(c)
  287. *      + z*sin(b)
  288.     Get_SinCos    a2,d1,d3,d4
  289.     Get_SinCos    a2,d2,d5,d6
  290.     muls.w    d4,d6                * / cos(b)*sin(c)
  291.     add.l    d6,d6                * |
  292. ;    bvc.s    .skipxd6
  293. ;    subq.l    #1,d6
  294. ;.skipxd6:
  295.     swap    d6                * \
  296.     muls.w    d4,d5                * / -cos(b)*sin(c)
  297.     add.l    d5,d5                * |
  298. ;    bvc.s    .skipxd5
  299. ;    subq.l    #1,d5
  300. ;.skipxd5:
  301.     swap    d5                * |
  302.     neg.w    d5                * \
  303.     move.w    d6,(a0)+
  304.     move.w    d5,(a0)+
  305.     move.w    d3,(a0)+
  306.     
  307. * Y := + x*(sin(a)*sin(b)*cos(c)+cos(a)*sin(c))
  308. *      + y*(cos(a)*cos(c)-sin(a)*sin(b)*sin(c))
  309. *      - z*sin(a)*cos(b)
  310.     Get_SinCos    a2,a3,d0,d1
  311.     Get_Sin        a2,a4,d2
  312.     Get_SinCos    a2,a5,d4,d5
  313.     muls.w    d0,d2
  314.     add.l    d2,d2
  315. ;    bvc.s    .skipyd2
  316. ;    subq.l    #1,d2
  317. ;.skipyd2:
  318.     swap    d2
  319.     muls.w    d2,d5
  320.     add.l    d5,d5
  321. ;    bvc.s    .skipyd5
  322. ;    subq.l    #1,d5
  323. ;.skipyd5:
  324.     swap    d5
  325.     muls.w    d1,d4
  326.     add.l    d4,d4
  327. ;    bvc.s    .skipyd4
  328. ;    subq.l    #1,d4
  329. ;.skipyd4:
  330.     swap    d4
  331.     add.w    d4,d5
  332.     bvc.s    .skipyvd5
  333.     addq.w    #1,d5
  334.     neg.w    d5
  335. .skipyvd5:
  336.     move.w    d5,d3
  337.     ;Get_SinCos    a2,a3,d0,d1
  338.     Get_Sin        a2,a4,d2
  339.     Get_SinCos    a2,a5,d4,d5
  340.     muls.w    d1,d5
  341.     add.l    d5,d5
  342. ;    bvc.s    .skipy2d5
  343. ;    subq.l    #1,d5
  344. ;.skipy2d5:
  345.     swap    d5
  346.     muls.w    d0,d2
  347.     add.l    d2,d2
  348. ;    bvc.s    .skipy2d2
  349. ;    subq.l    #1,d2
  350. ;.skipy2d2:
  351.     swap    d2
  352.     muls.w    d2,d4
  353.     add.l    d4,d4
  354.     swap    d4
  355.     sub.w    d4,d5
  356.     bvc.s    .skipyv2d5
  357.     addq.w    #1,d5
  358.     neg.w    d5
  359. .skipyv2d5:
  360.     Get_Cos        a2,a4,d4
  361.     muls.w    d0,d4
  362.     add.l    d4,d4
  363. ;    bvc.s    .skipy2d4
  364. ;    subq.l    #1,d4
  365. ;.skipy2d4:
  366.     swap    d4
  367.     neg.w    d4
  368.     move.w    d3,(a0)+
  369.     move.w    d5,(a0)+
  370.     move.w    d4,(a0)+
  371.  
  372. * Z := + x*(sin(a)*sin(c)-cos(a)*sin(b)*cos(c))
  373. *      + y*(cos(a)*sin(b)*sin(c)+sin(a)*cos(c))
  374. *      + z*cos(a)*cos(b)
  375.     Get_SinCos    a2,a3,d0,d1
  376.     Get_Sin        a2,a4,d2
  377.     Get_SinCos    a2,a5,d4,d5
  378.     muls.w    d0,d4
  379.     add.l    d4,d4
  380. ;    bvc.s    .skipzd4
  381. ;    subq.l    #1,d4
  382. ;.skipzd4:
  383.     swap    d4
  384.     muls.w    d1,d2
  385.     add.l    d2,d2
  386. ;    bvc.s    .skipzd2
  387. ;    subq.l    #1,d2
  388. ;.skipzd2:
  389.     swap    d2
  390.     muls.w    d2,d5
  391.     add.l    d5,d5
  392.     swap    d5
  393.     sub.w    d5,d4
  394.     bvc.s    .skipzvd4
  395.     addq.w    #1,d4
  396.     neg.w    d4
  397. .skipzvd4:
  398.     move.w    d4,d3
  399.     ;Get_SinCos    a2,a3,d0,d1
  400.     Get_Sin        a2,a4,d2
  401.     Get_SinCos    a2,a5,d4,d5
  402.     muls.w    d1,d2
  403.     add.l    d2,d2
  404. ;    bvc.s    .skipz2d2
  405. ;    subq.l    #1,d2
  406. ;.skipz2d2:
  407.     swap    d2
  408.     muls.w    d2,d4
  409.     add.l    d4,d4
  410.     swap    d4
  411.     muls.w    d0,d5
  412.     add.l    d5,d5
  413. ;    bvc.s    .skipzd5
  414. ;    subq.l    #1,d5
  415. ;.skipzd5:
  416.     swap    d5
  417.     add.w    d4,d5
  418.     bvc.s    .skipzvd5
  419.     addq.w    #1,d5
  420.     neg.w    d5
  421. .skipzvd5:
  422.     Get_Cos        a2,a4,d4
  423.     muls.w    d1,d4
  424.     add.l    d4,d4
  425. ;    bvc.s    .skipz2d4
  426. ;    subq.l    #1,d4
  427. ;.skipz2d4:
  428.     swap    d4
  429.     move.w    d3,(a0)+
  430.     move.w    d5,(a0)+
  431.     move.w    d4,(a0)+
  432.  
  433. * Translation vector := (0,0,0)
  434.     moveq    #0,d0
  435.     move.l    d0,(a0)+
  436.     move.l    d0,(a0)+
  437.     move.l    d0,(a0)+
  438.  
  439.     rts
  440.  
  441. * Translate the object's translation vector.
  442. * INPUT: d0.w: X translation
  443. *        d1.w: Y translation
  444. *        d2.w: Z translation
  445. Kaleido.translate:
  446.     lea    Kaleido.matrix,a0
  447.     add.w    d0,matrixTX(a0)
  448.     add.w    d1,matrixTY(a0)
  449.     add.w    d2,matrixTZ(a0)
  450.     rts
  451.  
  452. * Transform vertices.
  453. * INPUT: a0: destination obj
  454. *        a2: source obj
  455. Kaleido.transform:
  456.     lea    Kaleido.matrix,a1
  457.     lea    Matrix.TX(a1),a3
  458.     move.w    (a2)+,d7            * total amount of vertices
  459.     move.w    (a2)+,a6            * amount of normal vectors
  460.     movem.w    d7/a6,(a0)
  461.     sub.w    a6,d7                * amount of vertices
  462.  
  463. * Transform vertices...
  464. .transform_vertices:
  465.     subq.w    #1,d7
  466.     movea.l    d7,a5
  467.     movea.l    a0,a4
  468.     addq    #4,a0
  469.  
  470.     move.w    a6,-(sp)
  471.  
  472.     movem.l    (a3),d6/a3/a6
  473.  
  474. .vertexloop:
  475.     movem.w    (a2)+,d0-d2
  476.  
  477. * X
  478.     move.w    d0,d3
  479.     move.w    d1,d4
  480.     move.w    d2,d5
  481.     muls.w    (a1)+,d3
  482.     muls.w    (a1)+,d4
  483.     muls.w    (a1)+,d5
  484.     add.l    d3,d5
  485.     add.l    d4,d5
  486.     add.l    d5,d5
  487.     add.l    d6,d5                * Translate coordinate.
  488.     swap    d5
  489.     move.w    d5,(a0)+            * Store coordinate.
  490. * Y
  491.     move.w    d0,d3
  492.     move.w    d1,d4
  493.     move.w    d2,d5
  494.     muls.w    (a1)+,d3
  495.     muls.w    (a1)+,d4
  496.     muls.w    (a1)+,d5
  497.     add.l    d3,d5
  498.     add.l    d4,d5
  499.     add.l    d5,d5
  500.     add.l    a3,d5                * Translate coordinate.
  501.     swap    d5
  502.     move.w    d5,(a0)+            * Store coordinate.
  503. * Z
  504.     move.w    d0,d3
  505.     move.w    d1,d4
  506.     move.w    d2,d5
  507.     muls.w    (a1)+,d3
  508.     muls.w    (a1)+,d4
  509.     muls.w    (a1)+,d5
  510.     add.l    d3,d5
  511.     add.l    d4,d5
  512.     add.l    d5,d5
  513.     add.l    a6,d5                * Translate coordinate.
  514.     swap    d5
  515.     move.w    d5,(a0)+            * Store coordinate.
  516.  
  517.     lea    -3*6(a1),a1
  518.     dbf    d7,.vertexloop
  519.  
  520.     movea.w    (sp)+,a6
  521. .end_transform:
  522.  
  523. * Transform normal vectors...
  524. .transform_normals:
  525.     move.w    a6,d7
  526.     subq.w    #1,d7
  527.     bmi.s    .end_transformnormals
  528.  
  529. .normalloop:
  530.     movem.w    (a2)+,d0-d2
  531.     moveq    #3-1,d6
  532.  
  533. .normalcolumnloop:
  534.     move.w    d0,d3
  535.     move.w    d1,d4
  536.     move.w    d2,d5
  537.     muls.w    (a1)+,d3
  538.     muls.w    (a1)+,d4
  539.     muls.w    (a1)+,d5
  540.     add.l    d3,d5
  541.     add.l    d4,d5
  542.     add.l    d5,d5
  543.     swap    d5
  544.     move.w    d5,(a0)+            * Store coordinate.
  545.     dbra    d6,.normalcolumnloop
  546.  
  547.     lea    -3*6(a1),a1
  548.     dbf    d7,.normalloop
  549. .end_transformnormals:
  550.     rts
  551.  
  552. ; Decodes a u-fly envmapped object to a format suitable to the clipper.
  553. ; INPUT:
  554. ; a0: dst buffer (clipper format: head, polylist)
  555. ; a1: src u-fly2 object
  556. ; a4: reftable
  557. ; PRE:
  558. ; Object must be totally envmapped.
  559. Kaleido.decodeEnvObject:
  560.     move.w    (a1)+,d0            ; d0.w=v+n
  561.     move.w    d0,d2                ; d2.w=v+n
  562.     move.w    (a1)+,d1            ; d1.w=n, a1: vertextable
  563.     sub.w    d1,d2                ; d2.w=v
  564.  
  565.     mulu.w    #Vertex.SIZE,d0            ; d1.l=offset to 2dlist
  566.     lea    (a1,d0.l),a2            ; a2: 2d vertex table
  567.     move.w    (a2)+,d0            ; d0.w=#2d vertices
  568.     mulu.w    #Vertex2d.SIZE,d0        ; d0.l=offset to polylist
  569.     add.l    d0,a2                ; a2: polytable
  570.     move.w    (a2)+,d7            ; d7.w=#polys
  571.     move.w    d7,(a0)+            ; Store #polys.
  572.     subq.w    #1,d7
  573.  
  574. .poly_loop:
  575.     move.w    (a2)+,d0            ; d0.w=polyheader
  576.     andi.w    #Primitive.TYPEMASK,d0
  577.     moveq    #Primitive.TYPESHIFT,d1
  578.     lsr.w    d1,d0
  579.     move.w    d0,d6                ; d6.w=#vertices-1
  580.     addq.w    #1,d0
  581.     lea    (a2,d0.w*2),a3            ; a3: shadetable
  582.     move.w    d0,(a0)+            ; Store #vertices.
  583.  
  584. .decode_vertex_loop:
  585.     move.w    (a2)+,d2            ; d2.w=vertexref
  586.     move.w    d2,(a4)+            ; Store ref.
  587.     mulu.w    #Vertex.SIZE,d2
  588.     move.l    (a1,d2.l),(a0)+            ; Store x,y.
  589.     move.w    4(a1,d2.l),(a0)+        ; Store z.
  590.     move.w    (a3)+,d2            ; d3.w=normalref
  591.     mulu.w    #Vertex.SIZE,d2
  592.     move.l    (a1,d2.l),(a0)+            ; Store n.x, n.y.
  593.     move.w    4(a1,d2.l),(a0)+        ; Store n.z.
  594.     dbf    d6,.decode_vertex_loop
  595.  
  596.     movea.l    a3,a2                ; a2: next poly
  597.     dbf    d7,.poly_loop
  598.  
  599.     rts
  600.  
  601. ; Encodes a clipper object to a u-fly (envmapped) object.
  602. ; Does this the efficient way, be removing unused old vertices and normals.
  603. ; INPUT:
  604. ; a0: dest buffer (u-fly2 object)
  605. ; a1: clipped object (head, polylist)
  606. ; a2: ref table
  607. ; a3: src u-fly object
  608. ; PRE:
  609. ; Source object must be totally envmapped (6 coords per vertex).
  610. Kaleido.encodeEnvObjectEff:
  611.     move.w    (a3),d0
  612.     sub.w    2(a3),d0
  613.     move.w    d0,.srcvertices
  614.     addq    #4,a3                ; Skip src header
  615.  
  616. ; Pass 1 - Count and store used old vertices in src object.
  617.  
  618. ; 1a: Clear all marks.
  619.     lea    Kaleido.markTable,a5        ; a5: marked refs table
  620.     moveq    #Kaleido.MAX_VERTICES/4-1,d7
  621.     clr.l    d0
  622. .clearloop:
  623.     move.l    d0,(a5)+
  624.     dbf    d7,.clearloop
  625.  
  626. ; 1b: Mark it up..
  627.     lea    Kaleido.markTable,a5        ; a5: marked refs table
  628.     movea.l    a1,a6                ; a6: src object
  629.     movea.l    a2,a4                ; a4: reftable
  630.     move.w    (a1)+,d7            ; d7.w=#polys
  631.     move.w    d7,.polys
  632.     subq.w    #1,d7
  633.     moveq    #1,d0
  634.  
  635. .poly_loop0:
  636.     move.w    (a1)+,d5            ; d5.w=#vertices
  637.     subq.w    #1,d5
  638.  
  639. .poly0_v_loop:
  640.     move.w    (a2)+,d1            ; d1.w=ref
  641.     bmi.s    .next
  642.     move.b    d0,(a5,d1.w)            ; Mark reference.
  643. .next:    adda.w    #12,a1
  644.     dbf    d5,.poly0_v_loop
  645.  
  646.     dbf    d7,.poly_loop0
  647.     move.w    d6,(a0)                ; Store #old vertices.
  648.     move.w    d6,.vertices            ; Store #old vertices.
  649.  
  650.     move.l    a0,-(sp)
  651.  
  652. ; 1c: Sum up marktable, to get the relocation table..
  653.     lea    Kaleido.markTable,a5        ; a5: marked refs table
  654.     lea    Kaleido.relocTable,a2        ; a2: relocation table
  655.  
  656.     move.w    #Kaleido.MAX_VERTICES-2,d7
  657. ;    move.w    .srcvertices(pc),d7
  658. ;    subq.w    #2,d7
  659.  
  660.     moveq    #-1,d0
  661. .sum_loop:
  662.     add.b    (a5)+,d0
  663.     move.b    d0,(a2)+
  664.     dbf    d7,.sum_loop
  665.     ext.w    d0
  666.     addq.w    #1,d0
  667.     move.w    d0,.vertices            ; Store #old vertices.
  668.     move.w    d0,(a0)
  669.  
  670. ; 1d: Relocate old marked vertices to dst.
  671.     lea    Kaleido.relocTable,a5        ; a5: relocation table
  672.     movea.l    a6,a1                ; a1: polylist
  673.     movea.l    a4,a2                ; a2: reftable
  674.     move.w    (a1)+,d7            ; d7.w=#polys
  675.     subq.w    #1,d7
  676.     addq    #4,a0                ; Skip dst header
  677.  
  678. .poly_loop1d:
  679.     move.w    (a1)+,d5            ; d5.w=#vertices
  680.     subq.w    #1,d5
  681.  
  682. .poly1d_v_loop:
  683.     move.w    (a2)+,d1            ; d1.w=ref
  684.     bmi.s    .next1d
  685.     clr.w    d0
  686.     move.b    (a5,d1.w),d0            ; d0.w=npos
  687.     mulu.w    #Vertex.SIZE,d1            ; d1.l=src poly offset
  688.     mulu.w    #Vertex.SIZE,d0            ; d0.l=dst poly offset
  689.     move.l    (a3,d1.l),(a0,d0.l)
  690.     move.w    4(a3,d1.l),4(a0,d0.l)
  691. .next1d:adda.w    #12,a1                ; a1: next vertex
  692.     dbf    d5,.poly1d_v_loop
  693.  
  694.     dbf    d7,.poly_loop1d
  695.  
  696.     movea.l    (sp),a0                ; a0: dst
  697.     movea.l    a0,a5
  698.     move.w    .vertices(pc),d0
  699.     mulu.w    #Vertex.SIZE,d0
  700.     lea    4(a0,d0.l),a0            ; a0: room for new vertices
  701.  
  702.     movea.l    a6,a1
  703.     movea.l    a4,a2
  704.  
  705. ; Pass 2 - Get new vertices in table.
  706.     move.w    (a1)+,d7            ; d7.w=#polys
  707.     subq.w    #1,d7
  708.     clr.w    d6
  709.  
  710. .poly_loop1:
  711.     move.w    (a1)+,d5            ; d5.w=#vertices
  712.     subq.w    #1,d5
  713.  
  714. .poly1_v_loop:
  715.     move.w    (a2)+,d1            ; d1.w=ref
  716.     bmi.s    .new_ref1
  717.     adda.w    #12,a1
  718.     bra.s    .end_handle_ref1
  719. .new_ref1:
  720.     addq.w    #1,d6                ; Increase #new vertices.
  721. ; Store vertex.
  722.     move.l    (a1)+,(a0)+
  723.     move.w    (a1)+,(a0)+
  724.     addq    #6,a1                ; Skip normal.
  725. .end_handle_ref1:
  726.     dbf    d5,.poly1_v_loop
  727.  
  728.     dbf    d7,.poly_loop1
  729.  
  730.     add.w    d6,(a5)
  731.     movea.l    a6,a1
  732.     movea.l    a4,a2
  733. ; a0: end of vertextable in dst obj
  734.  
  735. ; Pass 3 - Store used old normals.
  736. ;          Adjust refs!
  737.     move.w    .srcvertices(pc),d2        ; d2.w=total #vertices
  738.     lea    Kaleido.relocTable,a5        ; a5: relocation table
  739.     movea.l    a6,a1                ; a1: polylist
  740.     movea.l    a4,a2                ; a2: reftable
  741.     move.w    (a1)+,d7            ; d7.w=#polys
  742.     subq.w    #1,d7
  743.  
  744. .poly_loop3:
  745.     move.w    (a1)+,d5            ; d5.w=#vertices
  746.     subq.w    #1,d5
  747.  
  748. .poly3_v_loop:
  749.     move.w    (a2),d1                ; d1.w=ref
  750.     bmi.s    .next3
  751.     clr.w    d0
  752.     move.b    (a5,d1.w),d0            ; d0.w=npos
  753.     move.w    d0,(a2)
  754.     add.w    d2,d1
  755.     mulu.w    #Vertex.SIZE,d1            ; d1.l=src poly offset
  756.     mulu.w    #Vertex.SIZE,d0            ; d0.l=dst poly offset
  757.     move.l    (a3,d1.l),(a0,d0.l)
  758.     move.w    4(a3,d1.l),4(a0,d0.l)
  759. .next3:    adda.w    #12,a1                ; a1: next vertex
  760.     addq    #2,a2                ; a2: next ref
  761.     dbf    d5,.poly3_v_loop
  762.  
  763.     dbf    d7,.poly_loop3
  764.     move.w    .vertices(pc),d0
  765.     mulu.w    #Vertex.SIZE,d0
  766.     adda.l    d0,a0
  767. ; a0: current end of normaltable in dst obj
  768.  
  769. ; Pass 4 - Get new normals in table.
  770.     movea.l    a6,a1
  771.     movea.l    a4,a2
  772.     move.w    (a1)+,d7            ; d7.w=#polys
  773.     move.w    d7,d0
  774.     subq.w    #1,d7
  775.  
  776. .poly_loop2:
  777.     move.w    (a1)+,d5            ; d5.w=#vertices
  778.     subq.w    #1,d5
  779.  
  780. .poly2_v_loop:
  781.     move.w    (a2)+,d1            ; d1.w=ref
  782.     bmi.s    .new_ref2
  783.     adda.w    #12,a1
  784.     bra.s    .end_handle_ref2
  785. .new_ref2:
  786.     addq    #6,a1                ; Skip vertex.
  787. ; Store normal.
  788.     move.l    (a1)+,(a0)+
  789.     move.w    (a1)+,(a0)+
  790. .end_handle_ref2:
  791.     dbf    d5,.poly2_v_loop
  792.     
  793.     dbf    d7,.poly_loop2
  794.  
  795.     clr.w    (a0)+                ; Store #2dvertices.
  796.  
  797. ; Pass 5 - Store all polys.
  798.     movea.l    a6,a1
  799.     movea.l    a4,a2
  800.     movea.l    (sp)+,a5            ; a5: dst
  801.     move.w    (a5),d2                ; d5.w=total #vertices
  802.     move.w    .vertices(pc),d6
  803.     move.w    (a1)+,d7
  804.     move.w    d7,(a0)+            ; Store #polys.
  805.     subq.w    #1,d7
  806.  
  807. .store_poly_loop:
  808.     move.w    (a1)+,d5            ; d5.w=#vertices
  809.     move.w    d5,d4
  810.     move.w    d5,d0
  811.     mulu.w    #3*2*2,d0
  812.     adda.l    d0,a1                ; Proceed to next src poly.
  813.     subq.w    #1,d5
  814.     move.w    d5,d0
  815.     moveq    #Primitive.TYPESHIFT,d1
  816.     lsl.w    d1,d0
  817.     ori.w    #Polygon.ENVMAPPED,d0
  818.     move.w    d0,(a0)+            ; Store polyheader.
  819.     lea    (a0,d4.w*2),a3            ; a3: shadetable.
  820.  
  821. .poly5_v_loop:
  822.     move.w    (a2)+,d1            ; d1.w=ref
  823.     bmi.s    .new_ref5
  824.     move.w    d1,(a0)+            ; Store vertexref.
  825.     move.w    d1,d0
  826.     add.w    d2,d0
  827.     move.w    d0,(a3)+            ; Store normalref.
  828.     bra.s    .end_handle_ref5
  829. .new_ref5:
  830.     move.w    d6,(a0)+            ; Store vertexref.
  831.     move.w    d6,d0
  832.     add.w    d2,d0
  833.     move.w    d0,(a3)+            ; Store normalref.
  834.     addq.w    #1,d6                ; Increase #new vertices.
  835. .end_handle_ref5:
  836.     dbf    d5,.poly5_v_loop
  837.  
  838.     movea.l    a3,a0                ; Proceed to next poly.
  839.     dbf    d7,.store_poly_loop
  840.  
  841. ; Adjust dst v,n counts..
  842.     move.w    (a5),d0
  843.     move.w    d0,2(a5)
  844.     add.w    d0,d0
  845.     move.w    d0,(a5)
  846.  
  847.     move.l    a0,d0
  848.     sub.l    a5,d0                ; d0.l=dst objectsize
  849.     rts
  850.  
  851. .srcvertices:
  852.     DC.W    0
  853. .vertices:
  854.     DC.W    0                ; #old vertices
  855. .normals:
  856.     DC.W    0
  857. .polys:    DC.W    0
  858.  
  859. ; Clips a polygon against XY, YZ, XZ planes. Vertices in (+,+,+) octant
  860. ; are seen as 'in', rest is 'out'.
  861. ; INPUT:
  862. ; d1.w= vertexwidth (words per vertex)
  863. ; a0: polygon (#v, x1, y1, z1, u1, v1, ... , x2, y2, z2, u2, v2, ....)
  864. ; a3: src reftable
  865. ; a4: dst reftable (with enough mem free!)
  866. ; OUTPUT:
  867. ; d0.w= cullstatus (0=culled, 1=visible)
  868. ; a0: clipped polygon (only if visible)
  869. ; a3: next src reftable
  870. ; a4: next dst reftable
  871. ; PRE:
  872. ; Must be a polygon (3 points minimum!), coord range [0..2047]
  873. Kaleido.clipRefPoly:
  874.     movea.l    a0,a6                ; a6:src poly
  875.     move.w    (a0)+,d0
  876.     move.w    d0,.srcvertices
  877.     move.w    d1,.width
  878.  
  879. ; First, we check which sides of the poly are clipped.
  880.     subq.w    #1,d0
  881.     subq.w    #3,d1
  882.     add.w    d1,d1
  883.     moveq    #$FFFFFFFF,d3            ; d3.w=andflags
  884.     clr.w    d4                ; d4.w=orflags
  885.  
  886. .test_clip_loop:
  887.     clr.w    d2                ; flags=0 (current point)
  888.     tst.w    (a0)+                ; Test x.
  889.     bpl.s    .x_okay
  890.     ori.w    #%001,d2            ; X clipped.
  891. .x_okay:tst.w    (a0)+                ; Test y.
  892.     bpl.s    .y_okay
  893.     ori.w    #%010,d2            ; Y clipped.
  894. .y_okay:tst.w    (a0)+                ; Test z.
  895.     bpl.s    .z_okay
  896.     ori.w    #%100,d2            ; Z clipped.
  897. .z_okay:and.w    d2,d3                ; Update andflags.
  898.     or.w    d2,d4                ; Update orflags.
  899.     adda.w    d1,a0                ; next vertex
  900.     dbf    d0,.test_clip_loop
  901.  
  902.     tst.w    d3
  903.     beq.s    .test_if_in
  904.  
  905. ; Clipped off totally.
  906. .out:    move.w    .srcvertices(pc),d0
  907.     add.w    d0,d0
  908.     add.w    d0,a3                ; Proceed to next reftable.
  909.     clr.w    d0                ; Indicate 'culled'.
  910.     rts
  911.  
  912. .test_if_in:
  913.     tst.w    d4                ; No clipflags? Then don't clip at all!
  914.     bne.s    .in
  915.     move.w    .srcvertices(pc),d0
  916.     subq.w    #1,d0
  917. .copy_s2dref_loop:
  918.     move.w    (a3)+,(a4)+
  919.     dbf    d0,.copy_s2dref_loop
  920.     movea.l    a6,a0
  921.     moveq    #1,d0                ; Indicate 'in'.
  922.     rts
  923.  
  924. .in:    move.w    d4,.clipflags
  925.  
  926. ; Scale coords up 4 bits.
  927. ; Assume we have all coords 0..2047 here, because lower 4 bits are used for
  928. ; extra precision.
  929.  
  930.     movea.l    a6,a0
  931.     lea    Kaleido.polyTable,a1
  932.     movea.l    a1,a5                    ; a5: src poly
  933.     move.w    (a0)+,d0
  934.     move.w    d0,(a1)+
  935.     mulu.w    .width(pc),d0
  936.     subq.w    #1,d0
  937.  
  938. .scale_up_loop:
  939.     move.w    (a0)+,d1
  940.     lsl.w    #4,d1
  941.     move.w    d1,(a1)+
  942.     dbf    d0,.scale_up_loop
  943.  
  944. ; scale up wrapped stuff!
  945.     lea    2(a5),a0
  946.     move.w    .width(pc),d0
  947.     subq.w    #1,d0
  948. .scale_up_loop_w:
  949.     move.w    (a0)+,(a1)+
  950.     dbf    d0,.scale_up_loop_w
  951.  
  952. ; Backup src reftable to ref dst and reserve some extra mem for clippoints.
  953. ; i.e. make double buffers.
  954.     move.l    a4,-(sp)                ; Backup dst reftable.
  955.  
  956.     move.l    a4,.refsrc
  957.     move.w    .srcvertices(pc),d0
  958.     move.w    d0,d7
  959.     subq.w    #1,d7
  960.     move.w    (a3),d1
  961. .copy_ref_loop:
  962.     move.w    (a3)+,(a4)+
  963.     dbf    d7,.copy_ref_loop
  964.     move.w    d1,(a4)+                ; wrap crap
  965.     lea    (a4,d0.w*2),a4                ; Keep a good margin for extra clippoints!
  966.     move.l    a4,.refdst
  967.  
  968.     move.l    a3,-(sp)                ; Backup src reftable.
  969.  
  970. ; Process each planeclip.
  971.     lea    Kaleido.polyTable2,a1
  972.     movea.l    a5,a0                    ; a0=a5=src poly
  973.     movea.l    a1,a6                    ; a6=a1=dst poly
  974.  
  975.     btst    #0,.clipflags+1(pc)
  976.     beq.s    .no_clip_x
  977.     bsr.l    .clip
  978.     tst.w    (a0)
  979.     beq    .culled
  980. .no_clip_x:
  981.     btst    #1,.clipflags+1(pc)
  982.     beq.s    .no_clip_y
  983.     bsr.s    .clip_y
  984.     tst.w    (a0)
  985.     beq    .culled
  986. .no_clip_y:
  987.     btst    #2,.clipflags+1(pc)
  988.     beq.s    .no_clip_z
  989.     bsr.s    .clip_z
  990.     tst.w    (a0)
  991.     beq    .culled
  992. .no_clip_z:
  993.  
  994. ; Store all references to final dst reftable.
  995.     movea.l    (sp)+,a3                ; a3: next src reftable
  996.     movea.l    (sp)+,a4                ; a4: current dst reftable
  997.     movea.l    .refsrc(pc),a1
  998.     move.w    (a0),d7                    ; d7.w=#vertices of clipped poly
  999.     subq.w    #1,d7
  1000. .store_ref_loop:
  1001.     move.w    (a1)+,(a4)+
  1002.     dbf    d7,.store_ref_loop
  1003.     movea.l    .refsrc(pc),a1
  1004.     move.w    (a1)+,(a4)                ; wrap crap
  1005.  
  1006. ; Scale coords down again..
  1007.     move.w    (a0)+,d0                ; d0.w=#vertices of clipped poly
  1008.     addq.w    #1,d0                    ; extra point for wrap
  1009.     mulu.w    .width(pc),d0
  1010.     subq.w    #1,d0
  1011.     movea.l    a5,a0                    ; a0: clipped poly
  1012.     addq    #2,a5                    ; Skip header.
  1013.  
  1014. .scale_down_loop:
  1015.     move.w    (a5),d1
  1016.     asr.w    #4,d1
  1017.     bcc.s    .rounded
  1018.     addq.w    #1,d1
  1019. .rounded:
  1020.     move.w    d1,(a5)+
  1021.     dbf    d0,.scale_down_loop
  1022.  
  1023. ; Clipping done!
  1024. .end:    moveq    #1,d0
  1025.     rts
  1026.  
  1027. .culled:
  1028. ; Set back to previous ref tables.
  1029.     movea.l    (sp)+,a3            ; a3: next src reftable
  1030.     movea.l    (sp)+,a4            ; a4: current dst reftable
  1031.     clr.w    d0                ; Indicate 'culled'.
  1032.     rts
  1033.  
  1034. .clip_y:
  1035. ; Swap y with x. The edge clipper works with x coords..
  1036.     movea.l    a0,a2
  1037.     move.w    .width(pc),d5
  1038.     move.w    (a2)+,d6
  1039. .swap_yx_loop:
  1040.     move.l    (a2),d0
  1041.     swap    d0
  1042.     move.l    d0,(a2)
  1043.     lea    (a2,d5.w*2),a2
  1044.     dbf    d6,.swap_yx_loop
  1045.  
  1046.     bsr.s    .clip
  1047.  
  1048. ; Swap x and y again..
  1049.     movea.l    a0,a2
  1050.     move.w    .width(pc),d5
  1051.     move.w    (a2)+,d6
  1052. .swap_xy_loop:
  1053.     move.l    (a2),d0
  1054.     swap    d0
  1055.     move.l    d0,(a2)
  1056.     lea    (a2,d5.w*2),a2
  1057.     dbf    d6,.swap_xy_loop
  1058.  
  1059.     rts
  1060.  
  1061. .clip_z:
  1062. ; Swap z with x. The edge clipper works with x coords..
  1063.     movea.l    a0,a2
  1064.     move.w    .width(pc),d5
  1065.     move.w    (a2)+,d6
  1066. .swap_zx_loop:
  1067.     move.w    (a2),d0
  1068.     move.w    4(a2),(a2)
  1069.     move.w    d0,4(a2)
  1070.     lea    (a2,d5.w*2),a2
  1071.     dbf    d6,.swap_zx_loop
  1072.  
  1073.     bsr.s    .clip
  1074.  
  1075. ; Swap z and x again..
  1076.     movea.l    a0,a2
  1077.     move.w    .width(pc),d5
  1078.     move.w    (a2)+,d6
  1079. .swap_xz_loop:
  1080.     move.w    (a2),d0
  1081.     move.w    4(a2),(a2)
  1082.     move.w    d0,4(a2)
  1083.     lea    (a2,d5.w*2),a2
  1084.     dbf    d6,.swap_xz_loop
  1085.  
  1086.     rts
  1087.  
  1088. ; Clips one corner.
  1089. ; INPUT:
  1090. ; a0: src poly
  1091. ; a1: dst poly
  1092. ; a5: src poly
  1093. ; a6: dst poly
  1094. ; OUTPUT:
  1095. ; a0: dst poly
  1096. ; a1: scr poly
  1097. ; a5: dst poly
  1098. ; a6: src poly
  1099. .clip:    movea.l    .refsrc(pc),a3
  1100.     movea.l    .refdst(pc),a4
  1101.  
  1102.     clr.l    d6
  1103.     move.w    .width(pc),d6
  1104.     move.w    d6,d5
  1105.     subq.w    #1,d5
  1106.     add.l    d6,d6
  1107.  
  1108. ; Clip all edges.
  1109.     move.w    (a0)+,d7        ; d7.w=#src vertices
  1110.     subq.w    #1,d7
  1111.     clr.w    .vertices        ; #output vertices
  1112.     addq    #2,a1            ; Skip dst header.
  1113. .corner_loop:
  1114.     bsr.s    .clip_edge
  1115.     dbf    d7,.corner_loop
  1116.  
  1117.     move.w    .vertices(pc),(a6)        ; Store #dst vertices.
  1118.  
  1119. ; wrap-crap
  1120.     lea    2(a6),a2
  1121.     move.w    .width(pc),d7
  1122.     subq.w    #1,d7
  1123. .width_loop:
  1124.     move.w    (a2)+,(a1)+
  1125.     dbf    d7,.width_loop
  1126.     movea.l    .refdst(pc),a2
  1127.     move.w    (a2),(a4)            ; ref wrapcrap
  1128.  
  1129. ; Swap src and dst polytables, reftables.
  1130.     exg    a5,a6
  1131.     movea.l    a5,a0
  1132.     movea.l    a6,a1
  1133.     move.l    .refsrc(pc),d0
  1134.     move.l    .refdst(pc),.refsrc
  1135.     move.l    d0,.refdst
  1136.     
  1137.     rts
  1138.  
  1139. ; Clips against YZ plane.
  1140. ; INPUT:
  1141. ; d5.w=vertexwidth-1
  1142. ; d6.l=offset to next vertex
  1143. ; a0: src poly
  1144. ; a1: dst poly
  1145. .clip_edge:
  1146.     tst.w    (a0)
  1147.     bmi.s    .check_2nd_out
  1148.     tst.w    (a0,d6.l)
  1149.     bpl.s    .inside
  1150.  
  1151. ; The source edge goes from inside to outside.
  1152. ; Write the clipped point.
  1153. .inout:    move.w    #-1,(a4)+            ; Store new ref.
  1154.     addq    #2,a3                ; Proceed to next src ref.
  1155.     move.w    (a0,d6.l),d2            ; d2.w=xend
  1156.     move.w    (a0)+,d0            ; d0.w=xstart
  1157.     ext.l    d0
  1158.     sub.w    d0,d2                ; d2.w=xend-xstart(=dx)
  1159.     ext.l    d2
  1160.     neg.l    d0
  1161.     clr.w    (a1)+                ; Store clipped x(=0).
  1162.     move.w    d5,d4
  1163.     subq.w    #1,d4
  1164. .inout_loop:
  1165.     move.w    (a0,d6.l),d3            ; d3.w=yend
  1166.     move.w    (a0)+,d1            ; d1.w=ystart
  1167.     bsr.s    .intersect
  1168.     move.w    d3,(a1)+            ; Store clipped coord.
  1169.     dbf    d4,.inout_loop
  1170.     addq.w    #1,.vertices            ; #output vertices +1.
  1171.     rts
  1172.  
  1173. .check_2nd_out:
  1174.     tst.w    (a0,d6.l)
  1175.     bpl.s    .outin
  1176.  
  1177. ; Source edge is outside. Don't write it out.
  1178. .outside:
  1179.     addq    #2,a3                ; Proceed to next ref.
  1180.     adda.l    d6,a0                ; Proceed to next vertex.
  1181.     rts
  1182.  
  1183. ; The source edge goes from outside to inside.
  1184. ; Write the clipped point and the inside point as well.
  1185. .outin:    move.w    #-1,(a4)+            ; Store new ref.
  1186.     addq    #2,a3                ; Proceed to next src ref.
  1187.     move.w    (a0,d6.l),d2            ; d2.w=xend
  1188.     move.w    (a0)+,d0            ; d0.w=xstart
  1189.     ext.l    d0
  1190.     sub.w    d0,d2                ; d2.w=xend-xstart(=dx)
  1191.     neg.w    d2
  1192.     ext.l    d2
  1193.     clr.w    (a1)+                ; Store clipped x(=0).
  1194.     move.w    d5,d4
  1195.     subq.w    #1,d4
  1196. .outin_loop:
  1197.     move.w    (a0,d6.l),d3            ; d3.w=yend
  1198.     move.w    (a0)+,d1            ; d1.w=ystart
  1199.     bsr.s    .intersect
  1200.     move.w    d3,(a1)+            ; Store clipped coord.
  1201.     dbf    d4,.outin_loop
  1202.     suba.l    d6,a0                ; Back to 1st vertex in edge.
  1203.     subq    #2,a3                ; Back 1 ref.
  1204.     addq.w    #1,.vertices            ; #output vertices +1.
  1205.  
  1206. ; Write inside point (2nd point in edge!).
  1207. .inside:addq    #2,a3
  1208.     move.w    (a3),(a4)+            ; Store old ref.
  1209.     adda.l    d6,a0                ; Proceed to next point.
  1210.     movea.l    a0,a2
  1211.     move.w    d5,d4
  1212. .copy_loop:
  1213.     move.w    (a2)+,(a1)+
  1214.     dbf    d4,.copy_loop
  1215.     addq.w    #1,.vertices            ; #output vertices +1.
  1216.     rts
  1217.  
  1218. ; Generic intersection routine. The start x coord is 'in', the end is 'out'.
  1219. ; yi = ystart + xstart*(dy/dx)
  1220. ; INPUT:
  1221. ; d0.w= xstart
  1222. ; d1.w= ystart
  1223. ; d2.l= xend - xstart (=dx)
  1224. ; d3.w= yend
  1225. ; OUTPUT:
  1226. ; d3.w=yi
  1227. .intersect:
  1228.     sub.w    d1,d3                ; d3.w=dy
  1229.     swap    d3
  1230.     clr.w    d3
  1231.     divs.l    d2,d3                ; d3.l=(dy<<16)/dx=slope
  1232.     muls.l    d0,d3                ; d3.l=slope*xstart
  1233.     addi.l    #$00008000,d3
  1234.     swap    d3
  1235.     add.w    d1,d3                ; d3.w=ystart+xstart*slope
  1236.     rts
  1237.  
  1238. .refsrc:DC.L    0
  1239. .refdst:DC.L    0
  1240. .vertices:
  1241.     DC.W    0
  1242. .srcvertices:
  1243.     DC.W    0
  1244. .width:    DC.W    0
  1245. .clipflags:
  1246.     DC.W    0
  1247.  
  1248. ; Test if an envmap object can be clipped whole?!?!
  1249. ; INPUT:
  1250. ; a0: dst u-fly object
  1251. ; a1: src u-fly object
  1252. ; OUTPUT:
  1253. ; d0.l= size of object
  1254. ; a0: dst u-fly object
  1255. Kaleido.testClip:
  1256. ; Decode the object..
  1257.     movem.l    a0/a1,-(sp)
  1258.     lea    Kaleido.polyList,a0
  1259.     lea    Kaleido.srcRefTable,a4
  1260.     bsr.l    Kaleido.decodeEnvObject
  1261.  
  1262. ; Clip all polys..
  1263.     clr.w    .polys
  1264.     lea    Kaleido.srcRefTable,a3
  1265.     lea    Kaleido.dstRefTable,a4
  1266.     lea    Kaleido.polyList,a0
  1267.     lea    Kaleido.clippedPolyList+2,a1
  1268.     move.w    (a0)+,d7
  1269.     subq.w    #1,d7
  1270.  
  1271. .clip_loop:
  1272.     move.l    a0,-(sp)
  1273.     move.l    a1,-(sp)
  1274.     move.w    d7,-(sp)
  1275.     moveq    #6,d1                ; d1.w=vertexwidth
  1276.     bsr.l    Kaleido.clipRefPoly
  1277.     move.w    (sp)+,d7
  1278.     movea.l    (sp)+,a1
  1279.     movea.l    (sp)+,a2
  1280.  
  1281. ; Store (or neglect if culled) the clipped poly...
  1282.     tst.w    d0
  1283.     bne.s    .not_culled
  1284.     bra.s    .end_store_poly
  1285. .not_culled:
  1286.     addq.w    #1,.polys
  1287.  
  1288.     move.w    (a0)+,d6
  1289.     bgt.s    .d6_okay
  1290.     illegal
  1291. .d6_okay:
  1292.     move.w    d6,(a1)+
  1293.     mulu.w    #6,d6                ; d6.w=#coords*#vertices
  1294.     subq.w    #1,d6
  1295.  
  1296. .store_poly_loop:
  1297.     move.w    (a0)+,(a1)+
  1298.     dbf    d6,.store_poly_loop
  1299. .end_store_poly:
  1300.  
  1301. ; Proceed to next unclipped poly...
  1302.     move.w    (a2)+,d0
  1303.     mulu.w    #6*2,d0
  1304.     lea    (a2,d0.l),a0
  1305.     
  1306.     dbf    d7,.clip_loop
  1307.  
  1308.     move.w    .polys(pc),Kaleido.clippedPolyList
  1309.  
  1310. ; Encode it to u-fly format again...
  1311.     movem.l    (sp),a0/a3            ; a0: dst u-fly obj, a3: src u-fly obj
  1312.     lea    Kaleido.clippedPolyList,a1
  1313.     lea    Kaleido.dstRefTable,a2
  1314.     bsr.l    Kaleido.encodeEnvObjectEff
  1315. ; d0.l=size of object
  1316.  
  1317.     movem.l    (sp)+,a0/a3            ; a0: dst u-fly obj, a3: src u-fly obj
  1318.     rts
  1319.  
  1320. .polys:    DC.W    0
  1321.  
  1322.  
  1323. ; INPUT:
  1324. ; d0.w= x,y,z negation (%000..00zyx)
  1325. ; a0: object
  1326. Kaleido.invertObject:
  1327.     move.w    (a0)+,d7
  1328.     addq    #2,a0
  1329.     subq.w    #1,d7
  1330. .loop:    btst    #0,d0
  1331.     beq.s    .end_x_neg
  1332.     neg.w    (a0)
  1333. .end_x_neg:
  1334.     addq    #2,a0
  1335.     btst    #1,d0
  1336.     beq.s    .end_y_neg
  1337.     neg.w    (a0)
  1338. .end_y_neg:
  1339.     addq    #2,a0
  1340.     btst    #2,d0
  1341.     beq.s    .end_z_neg
  1342.     neg.w    (a0)
  1343. .end_z_neg:
  1344.     addq    #2,a0
  1345.     dbf    d7,.loop
  1346.  
  1347. ; Test whether to inverse back<->front polys or not..
  1348.     clr.w    d1
  1349.     lsr.w    d0
  1350.     bcc.s    .not1
  1351.     addq.w    #1,d1
  1352. .not1:    lsr.w    d0
  1353.     bcc.s    .not2
  1354.     addq.w    #1,d1
  1355. .not2:    lsr.w    d0
  1356.     bcc.s    .not3
  1357.     addq.w    #1,d1
  1358. .not3:    btst    #0,d1
  1359.     beq.s    .end
  1360.  
  1361. ; Inverse order polys..
  1362.     move.w    (a0)+,d1
  1363.     mulu.w    #Vertex2d.SIZE,d1
  1364.     adda.l    d1,a0
  1365.  
  1366.     move.w    (a0)+,d7
  1367.     subq.w    #1,d7
  1368.     moveq    #Primitive.TYPESHIFT,d2
  1369.  
  1370. .ploop:    move.w    (a0)+,d6
  1371.     andi.w    #Primitive.TYPEMASK,d6
  1372.     lsr.w    d2,d6
  1373.  
  1374.     addq.w    #1,d6
  1375.     move.w    d6,d5
  1376.     lea    (a0,d6.w*2),a1
  1377.     movea.l    a1,a2
  1378.     lsr.w    d6
  1379.     subq.w    #1,d6
  1380.  
  1381. .vloop:    move.w    -(a1),d1
  1382.     move.w    (a0),(a1)
  1383.     move.w    d1,(a0)+
  1384.     dbf    d6,.vloop
  1385.  
  1386.     movea.l    a2,a0
  1387.     lea    (a0,d5.w*2),a1
  1388.     movea.l    a1,a2
  1389.     lsr.w    d5
  1390.     subq.w    #1,d5
  1391.  
  1392. .sloop:    move.w    -(a1),d1
  1393.     move.w    (a0),(a1)
  1394.     move.w    d1,(a0)+
  1395.     dbf    d5,.sloop
  1396.  
  1397.     movea.l    a2,a0
  1398.     dbf    d7,.ploop
  1399. .end:    rts
  1400.     
  1401. Kaleido.correctNormals:
  1402.     move.w    (a0)+,d7
  1403.     sub.w    (a0)+,d7
  1404.     move.w    d7,d0
  1405.     mulu.w    #Vertex.SIZE,d0
  1406.     lea    (a0,d0.l),a1
  1407.     subq.w    #1,d7
  1408.  
  1409. .loop:    tst.w    (a0)+
  1410.     bne.s    .end_x
  1411.     clr.w    (a1)
  1412. .end_x:    addq    #2,a1
  1413.     tst.w    (a0)+
  1414.     bne.s    .end_y
  1415.     clr.w    (a1)
  1416. .end_y:    addq    #2,a1
  1417.     tst.w    (a0)+
  1418.     bne.s    .end_z
  1419.     clr.w    (a1)
  1420. .end_z:    addq    #2,a1
  1421.     dbf    d7,.loop
  1422.  
  1423.     rts
  1424.  
  1425.     IFNE    Kaleido.BLOCKCLEARING
  1426. ; Clears the blockbuffer. Set all blocks to 'unused'.
  1427. Kaleido.clearBlockBuffer:
  1428.     movea.l    Kaleido.blockBufferTable,a0
  1429.     clr.l    d0
  1430.     moveq    #25-1,d7
  1431. .loop:    REPT    10
  1432.     move.l    d0,(a0)+
  1433.     ENDR
  1434.     dbf    d7,.loop
  1435.     rts
  1436.     ENDC
  1437.  
  1438. ; INPUT:
  1439. ; a0: rectangle table
  1440. Kaleido.clipRectangles:
  1441.     move.w    #199,d1
  1442.     move.w    #319,d2
  1443.     move.w    (a0)+,d7
  1444.     beq.s    .end
  1445.     subq.w    #1,d7
  1446. .loop:    move.w    (a0),d0
  1447.     bpl.s    .ok5
  1448.     clr.w    d0
  1449. .ok5:    cmp.w    d1,d0
  1450.     blt.s    .ok6
  1451.     move.w    d1,d0
  1452. .ok6:    move.w    d0,(a0)+
  1453.     move.w    (a0),d0
  1454.     bpl.s    .ok7
  1455.     clr.w    d0
  1456. .ok7:    cmp.w    d1,d0
  1457.     blt.s    .ok8
  1458.     move.w    d1,d0
  1459. .ok8:    move.w    d0,(a0)+
  1460.     move.w    (a0),d0
  1461.     bpl.s    .ok
  1462.     clr.w    d0
  1463. .ok:    cmp.w    d2,d0
  1464.     blt.s    .ok2
  1465.     move.w    d2,d0
  1466. .ok2:    move.w    d0,(a0)+
  1467.     move.w    (a0),d0
  1468.     bpl.s    .ok3
  1469.     clr.w    d0
  1470. .ok3:    cmp.w    d2,d0
  1471.     blt.s    .ok4
  1472.     move.w    d2,d0
  1473. .ok4:    move.w    d0,(a0)+
  1474.     dbf    d7,.loop
  1475. .end:    rts
  1476.  
  1477.     IFNE    Kaleido.BLOCKCLEARING
  1478. ; Mark Rectangle in blockbuffer.
  1479. ; INPUT:
  1480. ; d0.w=x1
  1481. ; d1.w=x2
  1482. ; d2.w=y1
  1483. ; d3.w=y2
  1484. Kaleido.putRectInBuf:
  1485.     movea.l    Kaleido.blockBufferTable,a0
  1486.     lsr.w    #3,d0
  1487.     lsr.w    #3,d1
  1488.     lsr.w    #3,d2
  1489.     lsr.w    #3,d3
  1490.     sub.w    d0,d1                ; d1.w=dx
  1491.     sub.w    d2,d3                ; d3.w=dy
  1492.     mulu.w    #40,d2
  1493.     add.w    d0,d2
  1494.     adda.w    d2,a0
  1495.     moveq    #$FFFFFFFF,d0
  1496.     moveq    #40-1,d6
  1497.     sub.w    d1,d6                ; d6.w=stride
  1498.  
  1499. .yloop:    move.w    d1,d7
  1500.  
  1501. .xloop:    move.b    d0,(a0)+            ; Mark as 'used'.
  1502.     dbf    d7,.xloop
  1503.  
  1504.     adda.l    d6,a0
  1505.     dbf    d3,.yloop    
  1506.     rts
  1507.  
  1508. ; Clear blocks on screen as specified by the blockbuffer.
  1509. ; INPUT:
  1510. ; a0: screen
  1511. Kaleido.clearBlocks:
  1512.     movea.l    Kaleido.blockBufferTable,a1
  1513.     movea.w    #8*2,a5
  1514.     movea.w    #7*320*2,a6
  1515.     moveq    #25-1,d7
  1516.     clr.l    d0
  1517.     clr.l    d1
  1518.     clr.l    d2
  1519.     clr.l    d3
  1520.  
  1521. .yloop:    moveq    #40-1,d6
  1522.  
  1523. .xloop:    tst.b    (a1)+
  1524.     beq.s    .next
  1525.     movem.l    d0-d3,(a0)
  1526.     movem.l    d0-d3,320*2(a0)
  1527.     movem.l    d0-d3,320*4(a0)
  1528.     movem.l    d0-d3,320*6(a0)
  1529.     movem.l    d0-d3,320*8(a0)
  1530.     movem.l    d0-d3,320*10(a0)
  1531.     movem.l    d0-d3,320*12(a0)
  1532.     movem.l    d0-d3,320*14(a0)
  1533. .next:    adda.l    a5,a0
  1534.     dbf    d6,.xloop
  1535.  
  1536.     adda.l    a6,a0
  1537.     dbf    d7,.yloop
  1538.     rts
  1539.     ENDC
  1540.  
  1541. ; Paints 'kaleidoscoped' object in a very lame way. No culling of doubled
  1542. ; vertices.
  1543. ; INPUT:
  1544. ; d0.l= size of object
  1545. ; a0: u-fly object
  1546. Kaleido.paintClippedObject:
  1547.     movem.l    d0/a0,-(sp)
  1548.     bsr.l    ObjectRegistry.clear
  1549.     movem.l    (sp)+,d0/a0
  1550.  
  1551.     IFNE    Kaleido.NORMAL_CORRECTION
  1552.     movem.l    d0/a0,-(sp)
  1553.     bsr.l    Kaleido.correctNormals
  1554.     movem.l    (sp)+,d0/a0
  1555.     ENDC
  1556.  
  1557.     movem.l    d0/a0,-(sp)
  1558.     bsr.l    ObjectRegistry.set
  1559.     tst.w    d0
  1560.     bmi    return2tos
  1561.     movem.l    (sp)+,d0/a0
  1562.  
  1563. ; Inverse coords here!
  1564.     movea.l    a0,a6
  1565.     move.l    d0,-(sp)
  1566.     moveq    #%011,d0
  1567.     bsr.l    Kaleido.invertObject
  1568.     move.l    (sp)+,d0
  1569.     movea.l    a6,a0
  1570.  
  1571.     movem.l    d0/a0,-(sp)
  1572.     bsr.l    ObjectRegistry.set
  1573.     tst.w    d0
  1574.     bmi    return2tos
  1575.     movem.l    (sp)+,d0/a0
  1576.  
  1577. ; Inverse coords here!
  1578.     movea.l    a0,a6
  1579.     move.l    d0,-(sp)
  1580.     moveq    #%010,d0
  1581.     bsr.l    Kaleido.invertObject
  1582.     move.l    (sp)+,d0
  1583.     movea.l    a6,a0
  1584.  
  1585.     movem.l    d0/a0,-(sp)
  1586.     bsr.l    ObjectRegistry.set
  1587.     tst.w    d0
  1588.     bmi    return2tos
  1589.     movem.l    (sp)+,d0/a0
  1590.  
  1591.     movea.l    a0,a6
  1592.     move.l    d0,-(sp)
  1593.     moveq    #%011,d0
  1594.     bsr.l    Kaleido.invertObject
  1595.     move.l    (sp)+,d0
  1596.     movea.l    a6,a0
  1597.  
  1598.     movem.l    d0/a0,-(sp)
  1599.     bsr.l    ObjectRegistry.set
  1600.     tst.w    d0
  1601.     bmi    return2tos
  1602.     movem.l    (sp)+,d0/a0
  1603.  
  1604.     movea.l    a0,a6
  1605.     move.l    d0,-(sp)
  1606.     moveq    #%100,d0
  1607.     bsr.l    Kaleido.invertObject
  1608.     move.l    (sp)+,d0
  1609.     movea.l    a6,a0
  1610.  
  1611.     movem.l    d0/a0,-(sp)
  1612.     bsr.l    ObjectRegistry.set
  1613.     tst.w    d0
  1614.     bmi    return2tos
  1615.     movem.l    (sp)+,d0/a0
  1616.  
  1617.     movea.l    a0,a6
  1618.     move.l    d0,-(sp)
  1619.     moveq    #%011,d0
  1620.     bsr.l    Kaleido.invertObject
  1621.     move.l    (sp)+,d0
  1622.     movea.l    a6,a0
  1623.  
  1624.     movem.l    d0/a0,-(sp)
  1625.     bsr.l    ObjectRegistry.set
  1626.     tst.w    d0
  1627.     bmi    return2tos
  1628.     movem.l    (sp)+,d0/a0
  1629.  
  1630.     movea.l    a0,a6
  1631.     move.l    d0,-(sp)
  1632.     moveq    #%010,d0
  1633.     bsr.l    Kaleido.invertObject
  1634.     move.l    (sp)+,d0
  1635.     movea.l    a6,a0
  1636.  
  1637.     movem.l    d0/a0,-(sp)
  1638.     bsr.l    ObjectRegistry.set
  1639.     tst.w    d0
  1640.     bmi    return2tos
  1641.     movem.l    (sp)+,d0/a0
  1642.  
  1643.     movea.l    a0,a6
  1644.     move.l    d0,-(sp)
  1645.     moveq    #%011,d0
  1646.     bsr.l    Kaleido.invertObject
  1647.     move.l    (sp)+,d0
  1648.     movea.l    a6,a0
  1649.  
  1650.     movem.l    d0/a0,-(sp)
  1651.     bsr.l    ObjectRegistry.set
  1652.     tst.w    d0
  1653.     bmi    return2tos
  1654.     movem.l    (sp)+,d0/a0
  1655.  
  1656.     movea.l    scr,a0
  1657.     bsr.l    Primitive.setScreenbuffer
  1658.  
  1659.     bsr.l    PrimitiveMesh.new
  1660.  
  1661.     move.w    #sintbllen*7/8,d0
  1662.     move.w    #sintbllen/2,d1
  1663.     move.w    #sintbllen/8,d2
  1664.     bsr    getTime
  1665.     move.w    d0,d2
  1666.     mulu.w    #3,d0
  1667.     lsr.l    d0
  1668.     bsr.l    Matrix.generate
  1669.     move.w    #0,d0
  1670.     move.w    #0,d1
  1671.     move.w    #2000,d2
  1672.     bsr.l    Matrix.translate
  1673.     bsr.l    Matrix.push
  1674.  
  1675.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1676.     moveq    #0,d1
  1677.     bsr.l    TransformObject.transform
  1678.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1679.     moveq    #1,d1
  1680.     bsr.l    TransformObject.transform
  1681.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1682.     moveq    #2,d1
  1683.     bsr.l    TransformObject.transform
  1684.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1685.     moveq    #3,d1
  1686.     bsr.l    TransformObject.transform
  1687.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1688.     moveq    #4,d1
  1689.     bsr.l    TransformObject.transform
  1690.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1691.     moveq    #5,d1
  1692.     bsr.l    TransformObject.transform
  1693.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1694.     moveq    #6,d1
  1695.     bsr.l    TransformObject.transform
  1696.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1697.     moveq    #7,d1
  1698.     bsr.l    TransformObject.transform
  1699.  
  1700.     bsr.l    Matrix.pop
  1701.  
  1702.     bsr.l    PrimitiveMesh.sortZ
  1703.  
  1704.     bsr.l    PrimitiveMesh.complete
  1705.  
  1706.     IFNE    Kaleido.BLOCKCLEARING
  1707.  
  1708.     movea.l    scr,a0
  1709.     bsr    Kaleido.clearBlocks
  1710.  
  1711.     bsr    Kaleido.clearBlockBuffer
  1712.  
  1713.     ELSE
  1714.  
  1715. ;    moveq    #68,d0
  1716. ;    move.l    #320-70,d6
  1717. ;    moveq    #0,d1
  1718. ;    move.l    #200-2,d7
  1719.     moveq    #0,d0
  1720.     move.l    #320,d6
  1721.     moveq    #0,d1
  1722.     move.l    #200,d7
  1723.     move.l    Kaleido.bgColor,d4
  1724.     bsr.l    Viewport.paintRectangle
  1725.  
  1726.     ENDC
  1727.  
  1728.     movea.l    Kaleido.rectAddressTable,a0
  1729.     bsr.l    PrimitiveMesh.paint
  1730.  
  1731.     IFNE    Kaleido.BLOCKCLEARING
  1732.  
  1733.     movea.l    Kaleido.rectAddressTable,a0
  1734.     bsr    Kaleido.clipRectangles
  1735.  
  1736.     movea.l    Kaleido.rectAddressTable,a0
  1737.     move.w    (a0)+,d7
  1738.     beq.s    .end_put
  1739.     subq.w    #1,d7
  1740. .putloop:
  1741.     movem.w    (a0)+,d2-d3
  1742.     movem.w    (a0)+,d0-d1
  1743.     move.l    a0,-(sp)
  1744.     move.w    d7,-(sp)
  1745.     bsr    Kaleido.putRectInBuf
  1746.     move.w    (sp)+,d7
  1747.     movea.l    (sp)+,a0
  1748.     dbf    d7,.putloop
  1749. .end_put:
  1750.  
  1751.     lea    Kaleido.blockBufferTable,a0
  1752.      move.l    (a0)+,d0
  1753.     move.l    (a0)+,d1
  1754.     move.l    (a0),-(a0)
  1755.     move.l    d0,4(a0)
  1756.     move.l    d1,-(a0)
  1757.  
  1758.     ENDC
  1759.  
  1760.     lea    Kaleido.rectAddressTable,a0
  1761.      move.l    (a0)+,d0
  1762.     move.l    (a0)+,d1
  1763.     move.l    (a0),-(a0)
  1764.     move.l    d0,4(a0)
  1765.     move.l    d1,-(a0)
  1766.  
  1767.     IFNE    0
  1768. ; just some area measurement..
  1769.     movea.l    Kaleido.rectAddressTable,a0
  1770.     movea.l    a0,a1
  1771.     move.w    (a0)+,d7
  1772.     beq    .end
  1773.     move.w    d7,d5
  1774.     subq.w    #1,d7
  1775. .cliploop:
  1776.     move.w    (a0),d0
  1777.     bpl.s    .ok
  1778.     clr.w    d0
  1779. .ok:    cmpi.w    #319,d0
  1780.     blt.s    .ok2
  1781.     move.w    #319,d0
  1782. .ok2:    move.w    d0,(a0)+
  1783.     move.w    (a0),d0
  1784.     bpl.s    .ok3
  1785.     clr.w    d0
  1786. .ok3:    cmpi.w    #319,d0
  1787.     blt.s    .ok4
  1788.     move.w    #319,d0
  1789. .ok4:    move.w    d0,(a0)+
  1790.     move.w    (a0),d0
  1791.     bpl.s    .ok5
  1792.     clr.w    d0
  1793. .ok5:    cmpi.w    #199,d0
  1794.     blt.s    .ok6
  1795.     move.w    #199,d0
  1796. .ok6:    move.w    d0,(a0)+
  1797.     move.w    (a0),d0
  1798.     bpl.s    .ok7
  1799.     clr.w    d0
  1800. .ok7:    cmpi.w    #199,d0
  1801.     blt.s    .ok8
  1802.     move.w    #199,d0
  1803. .ok8:    move.w    d0,(a0)+
  1804.     dbf    d7,.cliploop
  1805.  
  1806.     tst.w    d5
  1807.     beq.s    .end
  1808.     subq.w    #1,d5
  1809.     clr.l    d4
  1810. .loop:    movem.w    (a1)+,d1/d7
  1811. .bla2:    movem.w    (a1)+,d0/d6
  1812.     sub.w    d1,d7
  1813.     bpl.s    .xok
  1814.     neg.w    d7
  1815. .xok:    sub.w    d0,d6
  1816.     bpl.s    .yok
  1817.     neg.w    d6
  1818. .yok:    mulu.w    d6,d7
  1819.     add.l    d7,d4
  1820.     dbf    d5,.loop
  1821. .end_restore:
  1822.  
  1823.     divu.w    #64000/320,d4
  1824.     movea.l    scr,a0
  1825.     subq.w    #1,d4
  1826.     bmi.s    .end
  1827.     moveq    #$FFFFFFFF,d0
  1828. .clrloop:
  1829.     move.w    d0,(a0)+
  1830.     dbf    d4,.clrloop
  1831.  
  1832.     ENDC
  1833.  
  1834.     clr.l    Kaleido.bgColor
  1835.  
  1836. .end:    rts
  1837.  
  1838. ; This actually 'kaleidoscopes' a clipped object. Works on a normal object
  1839. ; (no clip), but the results would be quite ordinary.
  1840. ; INPUT:
  1841. ; d0.w=coord to mirror
  1842. ; a0: src u-fly object
  1843. ; a1: dst u-fly object
  1844. ; OUTPUT
  1845. ; d0.l= size of dst object
  1846. ; PRE: object must have #normals equal to #vertices
  1847. ; Object must have envmapped polys exclusively!
  1848. Kaleido.mirror:
  1849.     move.w    d0,d2                ; d2.w=coord offset.
  1850.     movea.l    a0,a5
  1851.     movea.l    a1,a6
  1852.  
  1853. ; Step 1 - We mirror vertices in x direction.
  1854.  
  1855. ; 1a - Clear marks..
  1856.     lea    Kaleido.clipMarkTable,a2    ; a2: marked refs table
  1857.     moveq    #Kaleido.MAX_CVERTICES/4-1,d7
  1858.     clr.l    d0
  1859. .clearloop:
  1860.     move.l    d0,(a2)+
  1861.     dbf    d7,.clearloop
  1862.  
  1863. ; 1b - Copy org vertices and mark x-clipped vertices!
  1864.     lea    Kaleido.clipMarkTable,a2    ; a2: marked refs table
  1865.     move.w    (a0)+,d7
  1866.     move.w    (a0)+,d6
  1867.     move.w    d7,(a1)+
  1868.     move.w    d6,(a1)+
  1869.     sub.w    d6,d7
  1870.     move.w    d7,.orgVertices
  1871.     subq.w    #1,d7
  1872.     moveq    #1,d0
  1873.     clr.w    d1
  1874. .copy_v_loop:
  1875.     tst.w    (a0,d2.w)
  1876.     bne.s    .next_v
  1877.     move.b    d0,(a2)                ; Mark it.
  1878.     addq.w    #1,d1                ; Increase #marked.
  1879. .next_v:addq    #1,a2    
  1880.     move.w    (a0)+,(a1)+
  1881.     move.l    (a0)+,(a1)+
  1882.     dbf    d7,.copy_v_loop
  1883.  
  1884.     move.w    d1,.culledAmount
  1885.  
  1886. ; 1c: Make mirrored vertices (not the marked ones!)..
  1887.     lea    Kaleido.clipMarkTable,a2    ; a2: marked refs table
  1888.     lea    4(a5),a3
  1889.     move.w    .orgVertices(pc),d7
  1890.     move.w    d7,d0
  1891.     sub.w    .culledAmount(pc),d0
  1892.     move.w    d0,.addedVertices
  1893.     add.w    d0,(a6)
  1894.     add.w    d0,(a6)
  1895.     add.w    d0,2(a6)
  1896.     move.w    2(a6),.dstVertices
  1897.     ble.s    .end_mirror_v
  1898.     subq.w    #1,d7
  1899. .mirror_v_loop:
  1900.     tst.b    (a2)+
  1901.     bne.s    .next_mirror_v
  1902.     move.w    (a3),(a1)
  1903.     move.l    2(a3),2(a1)
  1904.     neg.w    (a1,d2.w)            ; Negate coord.
  1905.     addq    #Vertex.SIZE,a1
  1906. .next_mirror_v:
  1907.     addq    #Vertex.SIZE,a3
  1908.     dbf    d7,.mirror_v_loop
  1909. .end_mirror_v:
  1910. ; a3: src normals
  1911.  
  1912. ; 1d: Copy org normals
  1913.     subq.w    #1,d6
  1914. .copy_n_loop:
  1915.     move.l    (a0)+,(a1)+
  1916.     move.w    (a0)+,(a1)+
  1917.     dbf    d6,.copy_n_loop
  1918.     
  1919. ; 1e: Mirror normals (not the marked ones!)..
  1920.     lea    Kaleido.clipMarkTable,a2    ; a2: marked refs table
  1921.     move.w    .orgVertices(pc),d7
  1922.     ble.s    .end_mirror_v
  1923.     subq.w    #1,d7
  1924. .mirror_n_loop:
  1925.     tst.b    (a2)+
  1926.     bne.s    .next_mirror_n
  1927.     move.w    (a3),(a1)
  1928.     move.l    2(a3),2(a1)
  1929.     neg.w    (a1,d2.w)
  1930.     addq    #Vertex.SIZE,a1
  1931. .next_mirror_n:
  1932.     addq    #Vertex.SIZE,a3
  1933.     dbf    d7,.mirror_n_loop
  1934. .end_mirror_n:
  1935.  
  1936. ; Copy texturevertices (if any)..
  1937.     move.w    (a0)+,d7
  1938.     move.w    d7,(a1)+
  1939.     subq.w    #1,d7
  1940.     bmi.s    .end_copy_t
  1941. .copy_t_loop:
  1942.     move.l    (a0)+,(a1)+
  1943.     dbf    d7,.copy_t_loop
  1944. .end_copy_t:
  1945.  
  1946. ; Intermezzo - Calculate relocation table.
  1947.     lea    Kaleido.clipMarkTable,a2    ; a2: marked refs table
  1948.     lea    Kaleido.clipRelocTable,a3    ; a3: relocation table
  1949.     move.w    .orgVertices(pc),d7
  1950.     move.w    d7,d2
  1951.     subq.w    #1,d7
  1952.     moveq    #-1,d1
  1953.     clr.w    d0
  1954. .make_reloc_loop:
  1955.     move.b    (a2)+,d0
  1956.     bchg    #0,d0                ; 1<->0
  1957.     add.w    d0,d1
  1958.     move.w    d2,d3
  1959.     add.w    d1,d3                ; Make ref point to new vertices.
  1960.     move.w    d3,(a3)+            ; Store reference.
  1961.     dbf    d7,.make_reloc_loop
  1962.  
  1963. ; 2 - Copy polys..
  1964.     movea.l    a0,a3
  1965.  
  1966. ; 2a - Copy org polys
  1967.     move.w    .addedVertices(pc),d2
  1968.     moveq    #Primitive.TYPESHIFT,d1
  1969.     move.w    (a0)+,d7
  1970.     move.w    d7,(a1)
  1971.     add.w    d7,(a1)+
  1972.     subq.w    #1,d7
  1973.  
  1974. .copy_poly_loop:
  1975.     move.w    (a0)+,d0
  1976.     move.w    d0,(a1)+
  1977.     andi.w    #Primitive.TYPEMASK,d0
  1978.     lsr.w    d1,d0
  1979.     move.w    d0,d6
  1980. .copy_poly_v_loop:
  1981.     move.w    (a0)+,(a1)+            ; Copy ref.
  1982.     dbf    d0,.copy_poly_v_loop
  1983. .copy_poly_s_loop:
  1984.     move.w    (a0)+,d0
  1985.     add.w    d2,d0
  1986.     move.w    d0,(a1)+            ; Copy sref.
  1987.     dbf    d6,.copy_poly_s_loop
  1988.     dbf    d7,.copy_poly_loop
  1989.  
  1990. ; 2b - Mirror polys.
  1991.     movea.l    a3,a0
  1992.     lea    Kaleido.clipMarkTable,a2    ; a2: marked refs table
  1993.     lea    Kaleido.clipRelocTable,a3    ; a3: relocation table
  1994.     move.w    .dstVertices(pc),d2        ; d2.w=offset to normals
  1995.     moveq    #Primitive.TYPESHIFT,d1
  1996.     move.w    (a0)+,d7
  1997.     subq.w    #1,d7
  1998.  
  1999. .mirror_poly_loop:
  2000.     move.w    (a0)+,d0
  2001.     move.w    d0,(a1)+
  2002.     andi.w    #Primitive.TYPEMASK,d0
  2003.     lsr.w    d1,d0
  2004.     move.w    d0,d6
  2005.     addq.w    #1,d6
  2006.     lea    (a1,d6.w*2),a1
  2007.     lea    (a1,d6.w*2),a4
  2008.  
  2009. .mirror_poly_v_loop:
  2010.     move.w    (a0)+,d3            ; d3.w=old ref
  2011.     tst.b    (a2,d3.w)            ; Check mark.
  2012.     beq.s    .old_vertex
  2013.     move.w    d3,-(a1)            ; Store ref.
  2014.     add.w    d2,d3
  2015.     move.w    d3,-(a4)            ; Store sref.
  2016.     bra.s    .next_mirror_r
  2017. .old_vertex:
  2018.     move.w    (a3,d3.w*2),d3            ; d3.w=relocated ref.
  2019.     move.w    d3,-(a1)            ; Store ref.
  2020.     add.w    d2,d3
  2021.     move.w    d3,-(a4)            ; Store sref.
  2022. .next_mirror_r:
  2023.     dbf    d0,.mirror_poly_v_loop
  2024.  
  2025.     lea    (a4,d6.w*2),a1            ; a1: next dst poly 
  2026.     lea    (a0,d6.w*2),a0            ; a0: next src poly
  2027.     dbf    d7,.mirror_poly_loop
  2028.     
  2029. ; Calc size of new object...
  2030.     move.l    a1,d0
  2031.     sub.l    a6,d0
  2032.     rts
  2033.  
  2034. .culledAmount:
  2035.     DC.W    0
  2036. .orgVertices:
  2037.     DC.W    0
  2038. .dstVertices:
  2039.     DC.W    0
  2040. .addedVertices:
  2041.     DC.W    0
  2042.  
  2043. ; Tries to paint 'kaleidoscoped' object in a decent way. Kaleidofucks
  2044. ; the object and removes doubled vertices at once.
  2045. ; INPUT:
  2046. ; d0.l= size of object
  2047. ; a0: u-fly object
  2048. Kaleido.paintClippedObjectOpt:
  2049.     movem.l    d0/a0,-(sp)
  2050.  
  2051.     movea.l    scr,a0
  2052.     bsr.l    Primitive.setScreenbuffer
  2053.  
  2054.     bsr.l    PrimitiveMesh.new
  2055.  
  2056.     move.w    #sintbllen*7/8,d0
  2057.     move.w    #sintbllen/2,d1
  2058.     move.w    #sintbllen/8,d2
  2059.     bsr    getTime
  2060.     move.w    d0,d2
  2061.     mulu.w    #3,d0
  2062.     lsr.l    d0
  2063.     bsr.l    Matrix.generate
  2064.     move.w    #0,d0
  2065.     move.w    #0,d1
  2066.     move.w    #2000,d2
  2067.     bsr.l    Matrix.translate
  2068.     bsr.l    Matrix.push
  2069.  
  2070.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  2071.     moveq    #0,d1
  2072.     bsr.l    TransformObject.transform
  2073.  
  2074.     bsr.l    Matrix.pop
  2075.  
  2076.     bsr.l    PrimitiveMesh.sortZ
  2077.  
  2078.     bsr.l    PrimitiveMesh.complete
  2079.  
  2080. ; Parallel shit!
  2081.     movem.l    (sp)+,d0/a0
  2082.  
  2083.     IFNE    Kaleido.NORMAL_CORRECTION
  2084.     movem.l    d0/a0,-(sp)
  2085.     bsr.l    Kaleido.correctNormals
  2086.     movem.l    (sp)+,d0/a0
  2087.     ENDC
  2088.  
  2089. ; Mirror in x-direction..
  2090.     move.l    a0,-(sp)
  2091.     lea    Kaleido.mirroredObject,a1
  2092.     moveq    #0,d0
  2093.     bsr.w    Kaleido.mirror
  2094. ; Mirror in y-direction..
  2095.     move.l    (sp),a1
  2096.     lea    Kaleido.mirroredObject,a0
  2097.     moveq    #2,d0
  2098.     bsr.w    Kaleido.mirror
  2099. ; Mirror in z-direction..
  2100.     move.l    (sp)+,a0
  2101.     lea    Kaleido.mirroredObject,a1
  2102.     moveq    #4,d0
  2103.     bsr.w    Kaleido.mirror
  2104. ; d0.l=object size
  2105.     move.l    d0,-(sp)
  2106.  
  2107.     movea.l    Kaleido.rectAddressTable,a0
  2108.     move.w    (a0)+,d7
  2109.     beq.s    .end_restore
  2110.     subq.w    #1,d7
  2111. .restore_loop:
  2112.     move.w    d7,-(sp)
  2113.     movem.w    (a0)+,d1/d7
  2114.     movem.w    (a0)+,d0/d6
  2115.     move.l    a0,-(sp)
  2116.     moveq    #$00000000,d4
  2117.     bsr.l    Viewport.paintRectangle
  2118.     movea.l    (sp)+,a0
  2119.     move.w    (sp)+,d7
  2120.     dbra    d7,.restore_loop
  2121. .end_restore:
  2122. ; End of parallel shit!
  2123.  
  2124.     movea.l    Kaleido.rectAddressTable,a0
  2125.     bsr.l    PrimitiveMesh.paint
  2126.  
  2127.     lea    Kaleido.rectAddressTable,a0
  2128.      move.l    (a0)+,d0
  2129.     move.l    (a0)+,d1
  2130.     move.l    (a0),-(a0)
  2131.     move.l    d0,4(a0)
  2132.     move.l    d1,-(a0)
  2133.  
  2134.     bsr.l    ObjectRegistry.clear
  2135.  
  2136.     movem.l    (sp)+,d0
  2137.     lea    Kaleido.mirroredObject,a0
  2138.     bsr.l    ObjectRegistry.set
  2139.     tst.w    d0
  2140.     bmi    return2tos
  2141.  
  2142.     rts
  2143.  
  2144. ;******* OBJECT DATA ********
  2145.  
  2146.     DATA
  2147.  
  2148. Kaleido.texture:
  2149.     INCBIN    ENV64.APX
  2150.  
  2151. Kaleido.textureTable:
  2152.     DC.L    Kaleido.texture
  2153.     DC.L    Kaleido.texture
  2154.     DC.L    0
  2155.  
  2156. Kaleido.pyramid:
  2157.     DC.W    (.end-.start)/Vertex.SIZE    * amount of vertices
  2158.     DC.W    (.end-.normstart)/Vertex.SIZE    * amount of normals
  2159. .start:    DC.W    +000,+300,+000
  2160.     DC.W    -300,-300,-300
  2161.     DC.W    +300,-300,-300
  2162.     DC.W    +300,-300,+300
  2163.     DC.W    -300,-300,+300
  2164. .normstart:
  2165.     DC.W    +000,+100,+000
  2166.     DC.W    -60,-60,-60
  2167.     DC.W    +60,-60,-60
  2168.     DC.W    +60,-60,+60
  2169.     DC.W    -60,-60,+60
  2170. .end:
  2171.  
  2172.     DC.W    0                ; amount of 2d vertices
  2173.  
  2174.     DC.W    5                ; amount of primitives
  2175.  
  2176.     DC.W    Polygon.TRI|Polygon.ENVMAPPED|0,+0,2,1,+5,7,6
  2177.     DC.W    Polygon.TRI|Polygon.ENVMAPPED|0,+0,3,2,+5,8,7
  2178.     DC.W    Polygon.TRI|Polygon.ENVMAPPED|0,+0,4,3,+5,9,8
  2179.     DC.W    Polygon.TRI|Polygon.ENVMAPPED|0,+0,1,4,+5,6,9
  2180.     DC.W    Polygon.QUAD|Polygon.ENVMAPPED|0,+1,2,3,4,+5,6,7,8
  2181. Kaleido.pyramidEnd:
  2182.  
  2183. Kaleido.cube:
  2184.     DC.W    (.end-.start)/Vertex.SIZE    * amount of vertices
  2185.     DC.W    (.end-.normstart)/Vertex.SIZE    * amount of normals
  2186. .start:    DC.W    -300,-300,-300
  2187.     DC.W    -300,300,-300
  2188.     DC.W    300,-300,-300
  2189.     DC.W    300,300,-300
  2190.     DC.W    -300,-300,300
  2191.     DC.W    -300,300,300
  2192.     DC.W    300,-300,300
  2193.     DC.W    300,300,300
  2194. .normstart:
  2195.     DC.W    -73,-73,-73
  2196.     DC.W    -73,73,-73
  2197.     DC.W    73,-73,-73
  2198.     DC.W    73,73,-73
  2199.     DC.W    -73,-73,73
  2200.     DC.W    -73,73,73
  2201.     DC.W    73,-73,73
  2202.     DC.W    73,73,73
  2203. .end:
  2204.  
  2205.     DC.W    0                ; amount of 2d vertices
  2206.  
  2207.     DC.W    6                ; amount of primitives
  2208.  
  2209.     DC.W    Polygon.QUAD|Polygon.ENVMAPPED|0,+0,1,3,2,+8+0,8+1,8+2,8+3
  2210.     DC.W    Polygon.QUAD|Polygon.ENVMAPPED|0,+6,7,5,4,+8+0,8+1,8+2,8+3
  2211.     DC.W    Polygon.QUAD|Polygon.ENVMAPPED|0,+4,5,1,0,+8+0,8+1,8+2,8+3
  2212.     DC.W    Polygon.QUAD|Polygon.ENVMAPPED|0,+2,3,7,6,+8+0,8+1,8+2,8+3
  2213.     DC.W    Polygon.QUAD|Polygon.ENVMAPPED|0,+5,7,3,1,+8+0,8+1,8+2,8+3
  2214.     DC.W    Polygon.QUAD|Polygon.ENVMAPPED|0,+4,0,2,6,+8+0,8+1,8+2,8+3
  2215. Kaleido.cubeEnd:
  2216.  
  2217. Kaleido.rectAddressTable:
  2218.     DC.L    Kaleido.rectangleTable
  2219.     DC.L    Kaleido.rectangleTable2
  2220.     DC.L    Kaleido.rectangleTable3
  2221.  
  2222.     IFNE    Kaleido.BLOCKCLEARING
  2223. Kaleido.blockBufferTable:
  2224.     DC.L    Kaleido.blockBuffer1
  2225.     DC.L    Kaleido.blockBuffer2
  2226.     DC.L    Kaleido.blockBuffer3
  2227.     ENDC
  2228.  
  2229. Kaleido.testPoly:
  2230.     DC.W    3
  2231.     DC.W    -256,+000,+000
  2232.     DC.W    +256,+256,+000
  2233.     DC.W    +256,-256,+000
  2234.     DC.W    -256,+000,+000                ; wrap first!
  2235.     DS.W    3*3
  2236.  
  2237. ;******* OBJECT RESERVES ********
  2238.  
  2239.     BSS
  2240.  
  2241. Kaleido.rectangleTable:
  2242.     DS.W    1+4*32
  2243. Kaleido.rectangleTable2:
  2244.     DS.W    1+4*32
  2245. Kaleido.rectangleTable3:
  2246.     DS.W    1+4*32
  2247. Kaleido.polyTable:
  2248.     DS.W    1+17*7                ; 17 * (x,y,z,u0,v0,u1,v1)
  2249. Kaleido.polyTable2:
  2250.     DS.W    1+17*7                ; 17 * (x,y,z,u0,v0,u1,v1)
  2251.  
  2252. Kaleido.object:
  2253.     DS.W    10000/2
  2254. Kaleido.polyList:
  2255.     DS.W    10000/2
  2256. Kaleido.clippedPolyList:
  2257.     DS.W    10000/2
  2258. Kaleido.srcRefTable:
  2259.     DS.W    5000
  2260. Kaleido.dstRefTable:
  2261.     DS.W    5000
  2262. Kaleido.clippedObject:
  2263.     DS.W    10000/2
  2264. Kaleido.mirroredObject:
  2265.     DS.W    10000/2
  2266. Kaleido.matrix:
  2267.     DS.B    matrixSize
  2268. Kaleido.markTable:
  2269.     DS.B    Kaleido.MAX_VERTICES
  2270. Kaleido.relocTable:
  2271.     DS.B    Kaleido.MAX_VERTICES
  2272. Kaleido.clipMarkTable:
  2273.     DS.B    Kaleido.MAX_CVERTICES
  2274. Kaleido.clipRelocTable:
  2275.     DS.W    Kaleido.MAX_CVERTICES
  2276. Kaleido.spikey:
  2277.     DS.W    1000
  2278.  
  2279.     IFNE    Kaleido.BLOCKCLEARING
  2280. Kaleido.blockBuffer1:
  2281.     DS.B    40*25
  2282. Kaleido.blockBuffer2:
  2283.     DS.B    40*25
  2284. Kaleido.blockBuffer3:
  2285.     DS.B    40*25
  2286.     ENDC
  2287.