home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / DELTA.ZIP / DELTASRC.ZIP / DELTA.SRC / WORM.SO < prev    next >
Text File  |  2003-01-03  |  21KB  |  1,110 lines

  1. ; Worm screen for delta. todo: possible memsaving as a last resort.
  2.  
  3. ******** OBJECT EQUATES ********
  4.  
  5. Worm.BACKGROUND:=    1
  6. Worm.DISTANCE:    =    3100                ; Maybe increase when module is playing!
  7.  
  8. Worm.SEGMENTS:    =    8                ; DO NOT CHANGE!
  9. Worm.MIN_DEPTH:    =    -(1+Worm.SEGMENTS)<<8/2
  10.  
  11. Worm.NUMSTARS:    =    250                ; number of background stars
  12. Worm.STARRADIUS:=    300                ; radius of skysphere
  13.  
  14.         RSRESET
  15. Worm.object:    RS.W    8192
  16. Worm.texture:    RS.W    10+64*64
  17. Worm.BLOCK_SIZE:RS.B    0
  18.  
  19. ******** OBJECT TABLE ********
  20.  
  21. * Must be first in object!!
  22. Worm.table:
  23.     DC.L    Worm.mainLoop
  24.     DC.L    Worm.init
  25.     DC.L    rts
  26.     DC.L    Worm.setZoomOut
  27.     DC.L    0
  28.  
  29.     IFND    DEMO_SYSTEM
  30.     INCLUDE    SFLY_DSP.S                ; Include the CPU-DSP engine.
  31.     TEXT
  32.     ENDC
  33.  
  34. ******** INIT SUBROUTINE ********
  35.  
  36. * OUTPUT: d0.l: 0   = All clear.
  37. *               neg = Error! Not initialized!
  38. Worm.init:
  39.     move.l    #Worm.BLOCK_SIZE,d0
  40.     bsr.l    Mem.register
  41.  
  42.     lea    sine_tbl,a1
  43.     bsr.l    Matrix.init
  44.  
  45. .success:
  46.     moveq    #0,d0
  47.     rts
  48. .error:    moveq    #-1,d0
  49.     rts
  50.  
  51. ******** REALTIME INIT SUBROUTINE ********
  52.  
  53. Worm.realtimeInit:
  54.     move.l    #rts,vbl_gfx
  55.  
  56.     bsr.l    Mem.getBlock
  57.     move.l    d0,d1
  58.     addi.l    #Worm.object,d1
  59.     move.l    d1,Worm.objAdr
  60.     move.l    d0,d1
  61.     addi.l    #Worm.texture,d1
  62.     move.l    d1,Worm.textureTable
  63.  
  64.     movea.l    d1,a0
  65.     clr.w    d0
  66.     move.w    #10+64*64-1,d7
  67. .clearloop:
  68.     move.w    d0,(a0)+
  69.     dbf    d7,.clearloop
  70.  
  71.     bsr.l    HumanFly.init
  72.  
  73. ; Generate nice turbulence chrome texture..
  74.     movea.l    Worm.textureTable,a0
  75.     move.l    #"Word",(a0)+
  76.     move.l    #"PerP",(a0)+
  77.     move.l    #"ixel",(a0)+
  78.     move.l    #$00400040,(a0)+
  79.     lea    FlareGen.icePal,a1
  80.     moveq    #6,d0
  81.     moveq    #3,d1
  82.     move.l    #$00010001,d2
  83.     bsr.l    Texture.createWords2
  84.  
  85.     lea    Viewport.settingsTable,a0
  86.     move.w    #320,Viewport.XSCREEN(a0)
  87.     move.w    #200,Viewport.YSCREEN(a0)
  88.     move.w    #0,Viewport.XSTART(a0)
  89.     move.w    #0,Viewport.YSTART(a0)
  90.     move.w    #320,Viewport.XEND(a0)
  91.     move.w    #200,Viewport.YEND(a0)
  92.     move.w    #160,Viewport.XCENTER(a0)
  93.     move.w    #100,Viewport.YCENTER(a0)
  94.     move.w    #256+32,Viewport.ASPECT(a0)
  95.     move.w    #$100,Viewport.FOCAL(a0)
  96.     bsr.l    Viewport.update
  97.  
  98.     lea    Worm.textureTable,a0
  99.     bsr.l    Polygon.init
  100.  
  101.     lea    Worm.starTable,a0
  102.     move.w    #Worm.NUMSTARS,d0
  103.     move.w    #Worm.STARRADIUS,d1
  104.     bsr.w    Worm.calcSphere
  105.  
  106.     bsr.l    ObjectRegistry.clear
  107.  
  108.     moveq    #1,d0
  109.     movea.l    Worm.objAdr,a0
  110.     bsr.w    Worm.generate
  111. ; d0.l=size of generated worm
  112.     movea.l    Worm.objAdr,a0
  113.     bsr.l    ObjectRegistry.set
  114.  
  115.     bsr.l    flushAndDisableICache
  116.     move.w    #Primitive.WORD|Primitive.MOVE,d0
  117.     moveq    #0,d1
  118.     bsr.l    Primitive.setPaintMode
  119.     bsr.l    restoreCache
  120.  
  121.     bsr    Worm.setZoomIn
  122.  
  123.     move.w    monitormode,d0
  124.     cmpi.w    #vga60,d0
  125.     beq.s    .vga60
  126.     cmpi.w    #vga100,d0
  127.     beq.s    .vga100
  128.     cmpi.w    #rgb50,d0
  129.     beq.s    .rgb50
  130. * Unknown monitormode..
  131.     rts
  132. .vga60:    move.l    #vga60_16bit_320_200,Worm.resRout
  133.     rts
  134. .vga100:move.l    #vga100_16bit_320_200,Worm.resRout
  135.     rts
  136. .rgb50:    move.l    #rgb50_16bit_320_200,Worm.resRout
  137.     rts
  138.  
  139. ******** SCREENINIT SUBROUTINE ********
  140.  
  141. Worm.initScreen:
  142.     lea    Viewport.settingsTable,a0
  143.     movem.w    Viewport.XSTART(a0),d0/d6
  144.     movem.w    Viewport.YSTART(a0),d1/d7
  145.     moveq    #$00000000,d4
  146.     bsr.l    Viewport.paintRectangle
  147.     rts
  148.  
  149. ******** MAINLOOP SUBROUTINE ********
  150.  
  151. Worm.mainLoop:
  152.     move.w    $0468.w,.old468
  153.  
  154.     movea.l    scr,a0
  155.     bsr.l    Primitive.setScreenbuffer
  156.  
  157.     move.l    frmcnt,d0
  158.     sub.l    lastframecount,d0
  159.     bne.s    .end_realtime_init
  160.     move.l    d0,-(sp)
  161.     bsr.w    Worm.realtimeInit
  162.     move.l    (sp)+,d0
  163. .end_realtime_init:
  164.     cmpi.l    #3,d0
  165.     bhs.s    .end_screeninit
  166.     bsr.w    Worm.initScreen
  167. .end_screeninit:
  168.  
  169. ; Control starcolor..
  170.     move.w    Worm.zoomDir,d0
  171.     bne.s    .calc_grey
  172.     moveq    #$FFFFFFFF,d1
  173.     bra.s    .store_color
  174. .calc_grey:
  175.     move.w    $04BC.w,d1
  176.     sub.w    Worm.zoomStart,d1
  177.     lsr.w    #3,d1
  178.     cmpi.w    #63,d1
  179.     blt.s    .grey_ok
  180.     moveq    #63,d1
  181. .grey_ok:
  182.     tst.w    d0
  183.     bmi.s    .grey_up
  184.     neg.w    d1
  185.     addi.w    #63,d1
  186. .grey_up:
  187.     move.w    d1,d2
  188.     move.w    d1,d3
  189.     lsr.w    d2                ; b
  190.     lsr.w    d3
  191.     lsl.w    #5,d1                ; g
  192.     lsl.w    #5,d3
  193.     lsl.w    #6,d3                ; r
  194.     or.w    d2,d1
  195.     or.w    d3,d1
  196. .store_color:
  197.     move.w    d1,Worm.starColor
  198.  
  199. ; Control rotation.
  200.     move.w    $04BC.w,d0
  201.     move.w    d0,d1
  202.     move.w    d0,d2
  203.     mulu.w    #7,d0
  204.     lsr.l    #3,d0
  205.     mulu.w    #3,d1
  206.     lsr.l    d1
  207.     mulu.w    #5,d2
  208.     lsr.l    #2,d2
  209.     movem.w    d0-d2,Worm.rotTable
  210.  
  211. ; Paint foreground (worm).
  212.     bsr.w    Worm.paint
  213.  
  214.     lea    scr,a0
  215.     move.l    (a0)+,d0
  216.     move.l    (a0)+,d1
  217.     move.l    (a0),-4(a0)
  218.     move.l    d0,(a0)
  219.     move.l    d1,-8(a0)
  220.     movea.l    Worm.resRout,a0
  221.     suba.l    a1,a1
  222.     movea.l    d0,a2
  223.     bsr.l    Screen.requestUpdate
  224.     clr.l    Worm.resRout
  225.  
  226.     move.w    .old468(pc),d0
  227. .wait:    cmp.w    $0468.w,d0
  228.     beq.s    .wait
  229.  
  230.     rts
  231.  
  232. .old468:DC.W    0
  233.  
  234. ******** OBJECT SUBROUTINES ********
  235.  
  236. Worm.setZoomOut:
  237.     move.w    #Worm.DISTANCE,Worm.startZ
  238.     move.w    $04BC.w,Worm.zoomStart
  239.     move.w    #+1,Worm.zoomDir
  240.     rts
  241.  
  242. Worm.setZoomIn:
  243.     move.w    #8000,Worm.startZ
  244.     move.w    $04BC.w,Worm.zoomStart
  245.     move.w    #-1,Worm.zoomDir
  246.     rts
  247.  
  248. ; Seems to work ok, since there has been some patching on the overflow
  249. ; errors (caused by combination of finite accuracy and use of maximum range).
  250. ; INPUT:
  251. ; d0.w= X rotation (a)
  252. ; d1.w= Y rotation (b)
  253. ; d2.w= Z rotation (c)
  254. Worm.generateMatrix:
  255.     lea    Worm.matrix,a0
  256. * 1> rotate 3 axis.
  257.     Do_SinModulo    d0
  258.     Do_SinModulo    d1
  259.     Do_SinModulo    d2
  260.     movea.w    d0,a3
  261.     movea.w    d1,a4
  262.     movea.w    d2,a5
  263.     lea    Matrix.sineTable,a2
  264.  
  265. * X := + x*cos(b)*cos(c)
  266. *      - y*cos(b)*sin(c)
  267. *      + z*sin(b)
  268.     Get_SinCos    a2,d1,d3,d4
  269.     Get_SinCos    a2,d2,d5,d6
  270.     muls.w    d4,d6                * / cos(b)*sin(c)
  271.     add.l    d6,d6                * |
  272. ;    bvc.s    .skipxd6
  273. ;    subq.l    #1,d6
  274. ;.skipxd6:
  275.     swap    d6                * \
  276.     muls.w    d4,d5                * / -cos(b)*sin(c)
  277.     add.l    d5,d5                * |
  278. ;    bvc.s    .skipxd5
  279. ;    subq.l    #1,d5
  280. ;.skipxd5:
  281.     swap    d5                * |
  282.     neg.w    d5                * \
  283.     move.w    d6,(a0)+
  284.     move.w    d5,(a0)+
  285.     move.w    d3,(a0)+
  286.     
  287. * Y := + x*(sin(a)*sin(b)*cos(c)+cos(a)*sin(c))
  288. *      + y*(cos(a)*cos(c)-sin(a)*sin(b)*sin(c))
  289. *      - z*sin(a)*cos(b)
  290.     Get_SinCos    a2,a3,d0,d1
  291.     Get_Sin        a2,a4,d2
  292.     Get_SinCos    a2,a5,d4,d5
  293.     muls.w    d0,d2
  294.     add.l    d2,d2
  295. ;    bvc.s    .skipyd2
  296. ;    subq.l    #1,d2
  297. ;.skipyd2:
  298.     swap    d2
  299.     muls.w    d2,d5
  300.     add.l    d5,d5
  301. ;    bvc.s    .skipyd5
  302. ;    subq.l    #1,d5
  303. ;.skipyd5:
  304.     swap    d5
  305.     muls.w    d1,d4
  306.     add.l    d4,d4
  307. ;    bvc.s    .skipyd4
  308. ;    subq.l    #1,d4
  309. ;.skipyd4:
  310.     swap    d4
  311.     add.w    d4,d5
  312.     bvc.s    .skipyvd5
  313.     addq.w    #1,d5
  314.     neg.w    d5
  315. .skipyvd5:
  316.     move.w    d5,d3
  317.     ;Get_SinCos    a2,a3,d0,d1
  318.     Get_Sin        a2,a4,d2
  319.     Get_SinCos    a2,a5,d4,d5
  320.     muls.w    d1,d5
  321.     add.l    d5,d5
  322. ;    bvc.s    .skipy2d5
  323. ;    subq.l    #1,d5
  324. ;.skipy2d5:
  325.     swap    d5
  326.     muls.w    d0,d2
  327.     add.l    d2,d2
  328. ;    bvc.s    .skipy2d2
  329. ;    subq.l    #1,d2
  330. ;.skipy2d2:
  331.     swap    d2
  332.     muls.w    d2,d4
  333.     add.l    d4,d4
  334.     swap    d4
  335.     sub.w    d4,d5
  336.     bvc.s    .skipyv2d5
  337.     addq.w    #1,d5
  338.     neg.w    d5
  339. .skipyv2d5:
  340.     Get_Cos        a2,a4,d4
  341.     muls.w    d0,d4
  342.     add.l    d4,d4
  343. ;    bvc.s    .skipy2d4
  344. ;    subq.l    #1,d4
  345. ;.skipy2d4:
  346.     swap    d4
  347.     neg.w    d4
  348.     move.w    d3,(a0)+
  349.     move.w    d5,(a0)+
  350.     move.w    d4,(a0)+
  351.  
  352. * Z := + x*(sin(a)*sin(c)-cos(a)*sin(b)*cos(c))
  353. *      + y*(cos(a)*sin(b)*sin(c)+sin(a)*cos(c))
  354. *      + z*cos(a)*cos(b)
  355.     Get_SinCos    a2,a3,d0,d1
  356.     Get_Sin        a2,a4,d2
  357.     Get_SinCos    a2,a5,d4,d5
  358.     muls.w    d0,d4
  359.     add.l    d4,d4
  360. ;    bvc.s    .skipzd4
  361. ;    subq.l    #1,d4
  362. ;.skipzd4:
  363.     swap    d4
  364.     muls.w    d1,d2
  365.     add.l    d2,d2
  366. ;    bvc.s    .skipzd2
  367. ;    subq.l    #1,d2
  368. ;.skipzd2:
  369.     swap    d2
  370.     muls.w    d2,d5
  371.     add.l    d5,d5
  372.     swap    d5
  373.     sub.w    d5,d4
  374.     bvc.s    .skipzvd4
  375.     addq.w    #1,d4
  376.     neg.w    d4
  377. .skipzvd4:
  378.     move.w    d4,d3
  379.     ;Get_SinCos    a2,a3,d0,d1
  380.     Get_Sin        a2,a4,d2
  381.     Get_SinCos    a2,a5,d4,d5
  382.     muls.w    d1,d2
  383.     add.l    d2,d2
  384. ;    bvc.s    .skipz2d2
  385. ;    subq.l    #1,d2
  386. ;.skipz2d2:
  387.     swap    d2
  388.     muls.w    d2,d4
  389.     add.l    d4,d4
  390.     swap    d4
  391.     muls.w    d0,d5
  392.     add.l    d5,d5
  393. ;    bvc.s    .skipzd5
  394. ;    subq.l    #1,d5
  395. ;.skipzd5:
  396.     swap    d5
  397.     add.w    d4,d5
  398.     bvc.s    .skipzvd5
  399.     addq.w    #1,d5
  400.     neg.w    d5
  401. .skipzvd5:
  402.     Get_Cos        a2,a4,d4
  403.     muls.w    d1,d4
  404.     add.l    d4,d4
  405. ;    bvc.s    .skipz2d4
  406. ;    subq.l    #1,d4
  407. ;.skipz2d4:
  408.     swap    d4
  409.     move.w    d3,(a0)+
  410.     move.w    d5,(a0)+
  411.     move.w    d4,(a0)+
  412.  
  413.     rts
  414.  
  415. Worm.rotateStars:
  416.     lea    Worm.matrix,a1
  417.     lea    Worm.starTable,a2
  418.     movea.l    Worm.starAdrTable,a4
  419.     lea    2(a4),a0
  420.     move.w    #Worm.NUMSTARS-1,d7
  421.     lea    6*2(a1),a3
  422.     suba.l    a5,a5
  423.  
  424. .loop:    movem.w    (a2)+,d0-d2            ; d0-d2.w: source vertex
  425.     move.w    d0,d3
  426.     move.w    d1,d4
  427.     move.w    d2,d5
  428.     muls.w    (a3)+,d3
  429.     muls.w    (a3)+,d4
  430.     muls.w    (a3)+,d5
  431.     subq    #6,a3
  432.     add.l    d3,d5
  433.     add.l    d4,d5
  434.     add.l    d5,d5
  435.     swap    d5
  436.     tst.w    d5                * Test z coordinate.
  437.     bmi.s    .next
  438.  
  439.     REPT    2
  440.     move.w    d0,d3
  441.     move.w    d1,d4
  442.     move.w    d2,d5
  443.     muls.w    (a1)+,d3
  444.     muls.w    (a1)+,d4
  445.     muls.w    (a1)+,d5
  446.     add.l    d3,d5
  447.     add.l    d4,d5
  448.     add.l    d5,d5
  449.     swap    d5
  450.     move.w    d5,(a0)+            * Store coordinate.
  451.     ENDR
  452.  
  453.     addq    #1,a5
  454.     lea    -2*3*2(a1),a1
  455.  
  456. .next:    dbf    d7,.loop
  457.     move.w    a5,(a4)                ; Store # of output stars.
  458.     rts
  459.  
  460. ; Paints the stars in front of the camera. Also x/y clipping implemented.
  461. Worm.paintStars:
  462.     movea.l    Worm.starAdrTable,a1
  463.     movea.l    Worm.restoreAdrTable,a2
  464.     lea    2(a2),a4
  465.     suba.l    a3,a3                ; a3: plotcount
  466.     move.w    (a1)+,d7
  467.     beq.s    .end
  468.     movea.l    scr,a0
  469.     subq.w    #1,d7
  470.     move.w    #160,d2
  471.     move.w    #100,d3
  472.     move.w    #320,d4
  473.     move.w    #200,d5
  474.     move.w    Worm.starColor,d6
  475.  
  476. .loop:    movem.w    (a1)+,d0-d1
  477.     add.w    d2,d0
  478.     cmp.w    d4,d0
  479.     bcc.s    .next
  480.     add.w    d3,d1
  481.     cmp.w    d5,d1
  482.     bcc.s    .next
  483.     mulu.w    d4,d1
  484.     ext.l    d0
  485.     add.l    d1,d0
  486.     move.w    d0,(a4)+            ; Store screenoffset.
  487.     addq    #1,a3
  488.     move.w    d6,(a0,d0.l*2)            ; Plot.
  489. .next:    dbf    d7,.loop
  490. .end:    move.w    a3,(a2)                ; Store #plots.
  491.     rts
  492.  
  493. ; Clears stars from previous frame.
  494. Worm.restoreStars:
  495.     movea.l    Worm.restoreAdrTable,a1
  496.     move.w    (a1)+,d7
  497.     beq.s    .end
  498.     subq.w    #1,d7
  499.     clr.l    d0
  500.     movea.l    scr,a0
  501.     clr.l    d1
  502. .loop:    move.w    (a1)+,d0
  503.     move.w    d1,(a0,d0.l*2)
  504.     dbf    d7,.loop
  505. .end    rts
  506.  
  507. ; Generates a sphere of 3d points.
  508. ; INPUT:
  509. ; d0.w=amount of points
  510. ; d1.w=radius [0..32767]
  511. ; a0: dest buffer
  512. Worm.calcSphere:
  513.     move.w    d0,d7            ; d7.w=points to do
  514.     move.l    random,d0
  515.  
  516. .loop:
  517. ; Calculate next random value.
  518.     move.l    d0,d2
  519.     mulu.w    d0,d0
  520.     eor.l    d2,d0
  521.     addq.l    #7,d0
  522.     move.w    d0,d3
  523.     move.l    d0,d4
  524.     swap    d4
  525.     rol.l    #8,d0
  526. ; Calculate next random value.
  527.     move.l    d0,d2
  528.     mulu.w    d0,d0
  529.     eor.l    d2,d0
  530.     addq.l    #7,d0
  531.     move.w    d0,d5
  532.     rol.l    #8,d0
  533.     movea.l    d3,a3
  534.     movea.l    d4,a4
  535.     movea.l    d5,a5
  536.     muls.w    d3,d3
  537.     muls.w    d4,d4
  538.     muls.w    d5,d5
  539.     add.l    d3,d5
  540.     add.l    d4,d5
  541.     cmpi.l    #32767*32767,d5
  542.     bhs.s    .loop
  543.  
  544.     movem.l    d0/d1,-(sp)
  545.     move.l    d5,d1
  546.     bsr.l    Math.sqrt
  547.     move.l    d0,d6
  548.     clr.w    d6
  549.     swap    d6
  550.     movem.l    (sp)+,d0/d1
  551.  
  552.     move.l    a3,d3
  553.     move.l    a4,d4
  554.     move.l    a5,d5
  555.     muls.w    d1,d3
  556.     muls.w    d1,d4
  557.     muls.w    d1,d5
  558.     divs.l    d6,d3
  559.     divs.l    d6,d4
  560.     divs.l    d6,d5
  561.  
  562.     move.w    d3,(a0)+
  563.     move.w    d4,(a0)+
  564.     move.w    d5,(a0)+
  565.     subq.w    #1,d7
  566.     bne    .loop
  567.  
  568.     move.l    d0,random
  569.     rts
  570.  
  571. Worm.paint:
  572.     bsr.l    PrimitiveMesh.new
  573.  
  574.     moveq    #0,d0
  575.     movea.l    Worm.objAdr,a0
  576.     bsr.w    Worm.generate
  577. ; d0.l=size of generated worm
  578.  
  579.     IFNE    0
  580.     move.l    d0,-(sp)
  581.     bsr    ObjectRegistry.clear
  582.     move.l    (sp)+,d0
  583. ; d0.l=size of generated worm
  584.     movea.l    Worm.objAdr,a0
  585.     bsr.l    ObjectRegistry.set
  586.     ELSE
  587. ; Damn, seems to fail with texels! But why the hell???
  588.     movea.l    Worm.objAdr,a0
  589.     moveq    #0,d0
  590.     moveq    #%0001,d1
  591.     bsr.l    ObjectRegistry.replace
  592.     ENDC
  593.  
  594.     movem.w    Worm.rotTable,d0-d2
  595.     bsr.l    Matrix.generate
  596.     clr.w    d0
  597.     clr.w    d1
  598.     move.w    Worm.startZ,d2
  599.     move.w    $04BC.w,d3
  600.     sub.w    Worm.zoomStart,d3
  601.     lsl.w    #3,d3
  602.     muls.w    Worm.zoomDir,d3
  603.     add.w    d3,d2
  604.     cmpi.w    #Worm.DISTANCE,d2
  605.     bge.s    .zoom_done                ; Zoomed in?
  606.     clr.w    Worm.zoomDir                ; then stop zooming..
  607.     move.w    #Worm.DISTANCE,d2
  608.     move.w    d2,Worm.startZ
  609. .zoom_done:
  610.     bsr.l    Matrix.translate
  611.     bsr.l    Matrix.push
  612.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  613.     moveq    #0,d1
  614.     bsr.l    TransformObject.transform
  615.     bsr.l    Matrix.pop
  616.     bsr.l    PrimitiveMesh.sortZ
  617.  
  618.     bsr.l    PrimitiveMesh.complete
  619.  
  620.     IFNE    0
  621.  
  622.     lea    Viewport.settingsTable,a0
  623.     movem.w    Viewport.XSTART(a0),d0/d6
  624.     movem.w    Viewport.YSTART(a0),d1/d7
  625.     moveq    #$00000000,d4
  626.     bsr.l    Viewport.paintRectangle
  627.  
  628.     ELSE
  629.  
  630.     movea.l    Worm.rectAddressTable,a0
  631.     tst.w    (a0)+
  632.     beq.s    .end_restore
  633.     movem.w    (a0)+,d1/d7
  634.     movem.w    (a0)+,d0/d6
  635.     move.l    a0,-(sp)
  636.     moveq    #$00000000,d4
  637.     bsr.l    Viewport.paintRectangle
  638.     movea.l    (sp)+,a0
  639. .end_restore:
  640.  
  641.     IFNE    Worm.BACKGROUND
  642.     bsr.w    Worm.restoreStars
  643.  
  644.     movem.w    Worm.rotTable,d0-d2
  645.     bsr.w    Worm.generateMatrix
  646.     bsr.w    Worm.rotateStars
  647.     bsr.w    Worm.paintStars
  648.  
  649.     lea    Worm.starAdrTable,a3
  650.     move.l    (a3)+,d0
  651.     move.l    (a3)+,d1
  652.     move.l    (a3),-4(a3)
  653.     move.l    d0,(a3)
  654.     move.l    d1,-8(a3)
  655.     lea    Worm.restoreAdrTable,a3
  656.     move.l    (a3)+,d0
  657.     move.l    (a3)+,d1
  658.     move.l    (a3),-4(a3)
  659.     move.l    d0,(a3)
  660.     move.l    d1,-8(a3)
  661.     ENDC
  662.  
  663.     ENDC
  664.  
  665.     movea.l    Worm.rectAddressTable,a0
  666.     bsr.l    PrimitiveMesh.paint
  667.  
  668.     lea    Worm.rectAddressTable,a0
  669.      move.l    (a0)+,d0
  670.     move.l    (a0)+,d1
  671.     move.l    (a0),-(a0)
  672.     move.l    d0,4(a0)
  673.     move.l    d1,-(a0)
  674.  
  675.     rts
  676.  
  677. ; INPUT:
  678. ; d0.w= 0:only vertices, 1:faces also
  679. ; a0: destination buffer
  680. ; OUTPUT:
  681. ; d0.l=size of output object
  682. Worm.generate:
  683.     move.w    d0,-(sp)
  684.     movea.l    a0,a6
  685.  
  686.     move.w    #(Worm.SEGMENTS+1)*8+2,(a0)+        ; Store total #vertices.
  687.     clr.w    (a0)+                    ; Store #normals.
  688.  
  689. ; Output worm nose.
  690.     move.w    #0,(a0)+
  691.     move.w    #0,(a0)+
  692.     move.w    #Worm.MIN_DEPTH,(a0)+
  693.     
  694. ; Output segments.
  695.     move.w    $04BC.w,d2
  696.     lsl.w    #3,d2
  697.     clr.w    d3
  698.     clr.w    d7
  699.     lea    sine_tbl,a2
  700.  
  701. .segment_loop:
  702.     Do_SinModulo    d2
  703.     Get_Sin    sine_tbl,d2,d1
  704.     move.w    d2,d0
  705.     addi.w    #sintbllen/2,d0
  706.     Do_SinModulo    d0
  707.     Get_Sin    sine_tbl,d0,d4
  708.     addi.w    #$8000,d1
  709.     lsr.w    #8,d1
  710.     addi.w    #$8000,d4
  711.     lsr.w    #8,d4
  712.     lsr.w    #2,d4
  713.     addi.w    #$40,d1
  714.     addi.w    #$80,d4
  715.     moveq    #8-1,d6
  716.     lea    Worm.segmentTable,a1
  717.     add.w    d1,d3
  718.  
  719. .corner_loop:
  720.     REPT    2
  721.     move.w    (a1)+,d0
  722.     muls.w    (a2),d0
  723.     add.l    d0,d0
  724.     swap    d0
  725.     muls.w    d4,d0
  726.     asr.l    #8,d0                ; d0.w=radius of segment
  727.     move.w    d0,(a0)+
  728.     ENDR
  729.     move.w    d3,d0
  730.     addi.w    #Worm.MIN_DEPTH,d0
  731.     add.w    (a1)+,d0
  732.     move.w    d0,(a0)+
  733.     dbra    d6,.corner_loop
  734.  
  735.     adda.w    #128*4,a2
  736.     addi.w    #$140,d2
  737.     addq.w    #1,d7
  738.     cmpi.w    #Worm.SEGMENTS+1,d7
  739.     blt    .segment_loop
  740.  
  741. ; Output worm tail.
  742.     Do_SinModulo    d2
  743.     Get_Sin    sine_tbl,d2,d1
  744.     addi.w    #$8000,d1
  745.     lsr.w    #8,d1
  746.     addi.w    #$40,d1
  747.     move.w    #0,(a0)+
  748.     move.w    #0,(a0)+
  749.     add.w    d1,d3
  750.     move.w    d3,d0
  751.     addi.w    #Worm.MIN_DEPTH,d0
  752.     move.w    d0,(a0)+
  753.  
  754. ; Textureshit..
  755.     move.w    #(Worm.SEGMENTS+1)*9+2,(a0)+    ; Store #texturevertices.
  756.     move.w    #Worm.SEGMENTS,d7
  757.  
  758. ; Head texturevertex.
  759.     move.w    #$00FF,(a0)+
  760.     move.w    #$007F,(a0)+
  761.  
  762. ; 9 texturevertices (including 1 for wrap)
  763. .texture_vertex_loop:
  764.     move.w    d7,d0
  765.     mulu.w    #$FF/(Worm.SEGMENTS+1),d0
  766.     move.w    d0,(a0)+
  767.     move.w    #$0000,(a0)+
  768.     move.w    d0,(a0)+
  769.     move.w    #$0020,(a0)+
  770.     move.w    d0,(a0)+
  771.     move.w    #$0040,(a0)+
  772.     move.w    d0,(a0)+
  773.     move.w    #$0060,(a0)+
  774.     move.w    d0,(a0)+
  775.     move.w    #$0080,(a0)+
  776.     move.w    d0,(a0)+
  777.     move.w    #$00A0,(a0)+
  778.     move.w    d0,(a0)+
  779.     move.w    #$00C0,(a0)+
  780.     move.w    d0,(a0)+
  781.     move.w    #$00E0,(a0)+
  782.     move.w    d0,(a0)+
  783.     move.w    #$00FF,(a0)+
  784.     dbra    d7,.texture_vertex_loop
  785.  
  786. ; Tail texturevertex.
  787.     move.w    #$0000,(a0)+
  788.     move.w    #$007F,(a0)+
  789.  
  790.     move.w    (sp)+,d0
  791.     beq    .end
  792.  
  793. ; Now we output the worm faces.
  794. ;    move.w    #16+Worm.SEGMENTS*16,(a0)+        ; Store #faces.
  795.     move.w    #16+Worm.SEGMENTS*8,(a0)+        ; Store #faces.
  796.  
  797. ; Do the head (8 faces).
  798.     moveq    #1,d6
  799. .head_loop:
  800.     move.w    #Polygon.TRI|Polygon.TEXTUREMAPPED,(a0)+
  801.     move.w    d6,d0
  802.     andi.w    #7,d0
  803.     addq.w    #1,d0
  804.     clr.w    (a0)+
  805.     move.w    d0,(a0)+
  806.     move.w    d6,(a0)+
  807.     clr.w    (a0)+
  808.     move.w    d6,d0
  809.     addq.w    #1,d0
  810.     move.w    d0,(a0)+
  811.     move.w    d6,(a0)+
  812.     addq.w    #1,d6
  813.     cmpi.w    #8+1,d6
  814.     blt.s    .head_loop
  815.  
  816. ; Do segment faces (16 per segment).
  817.     moveq    #Worm.SEGMENTS-1,d7
  818.     bmi    .end
  819.     moveq    #1,d6
  820.     
  821. .segment_face_loop:
  822.     clr.w    d5
  823.  
  824. .face_loop:
  825.  
  826.     IFNE    1
  827. ; Let's try a quadrangle..
  828.     move.w    #Polygon.QUAD|Polygon.TEXTUREMAPPED|0,(a0)+
  829.  
  830.     move.w    d6,d0
  831.     add.w    d5,d0
  832.     move.w    d0,(a0)+            ; d0.w=i+1
  833.     move.w    d5,d2
  834.     andi.w    #7,d2
  835.     addq.w    #8,d2
  836.     add.w    d6,d2                ; d2.w=i mod 8 +9
  837.     move.w    d2,(a0)+
  838.     move.w    d5,d1
  839.     addq.w    #1,d1
  840.     andi.w    #7,d1
  841.     addq.w    #8,d1
  842.     add.w    d6,d1                ; d1.w=(i+1) mod 8 +9
  843.     move.w    d1,(a0)+
  844.     move.w    d5,d2
  845.     addq.w    #1,d2
  846.     andi.w    #7,d2
  847.     add.w    d6,d2                ; d2.w=(i+1) mod 8 +1
  848.     move.w    d2,(a0)+
  849.  
  850. ; texture..
  851.     move.w    d6,d3
  852.     subq.w    #1,d3
  853.     lsr.w    #3,d3
  854.     mulu.w    #9,d3
  855.     add.w    d5,d3
  856.     addq.w    #1,d3
  857.     move.w    d3,(a0)+            ; 1+r*9+c
  858.     addi.w    #9,d3
  859.     move.w    d3,(a0)+            ; 1+(r+1)*9+c
  860.     addq.w    #1,d3
  861.     move.w    d3,(a0)+            ; 1+(r+1)*9+c+1
  862.     subi.w    #9,d3
  863.     move.w    d3,(a0)+            ; 1+r*9+c+1
  864.  
  865.     ELSE
  866. ; Arrogance, the first face.
  867.     move.w    #Polygon.TRI|Polygon.TEXTUREMAPPED|0,(a0)+
  868.     move.w    d6,d0
  869.     add.w    d5,d0
  870.     move.w    d0,(a0)+            ; d0.w=i+1
  871.     move.w    d5,d1
  872.     addq.w    #1,d1
  873.     andi.w    #7,d1
  874.     addq.w    #8,d1
  875.     add.w    d6,d1                ; d1.w=(i+1) mod 8 +9
  876.     move.w    d1,(a0)+
  877.     move.w    d5,d2
  878.     andi.w    #7,d2
  879.     addq.w    #8,d2
  880.     add.w    d6,d2                ; d2.w=i mod 8 +9
  881.     move.w    d2,(a0)+
  882. ; Repeat indices for texels..
  883.     move.w    d6,d3
  884.     subq.w    #1,d3
  885.     lsr.w    #3,d3
  886.     mulu.w    #9,d3
  887.     add.w    d5,d3
  888.     addq.w    #1,d3
  889.     move.w    d3,(a0)+
  890.     addi.w    #9+1,d3
  891.     move.w    d3,(a0)+
  892.     subq.w    #1,d3
  893.     move.w    d3,(a0)+
  894. ; Ignorance, the second..
  895.     move.w    #Polygon.TRI|Polygon.TEXTUREMAPPED|0,(a0)+
  896.     move.w    d0,(a0)+
  897.     move.w    d5,d2
  898.     addq.w    #1,d2
  899.     andi.w    #7,d2
  900.     add.w    d6,d2                ; d2.w=(i+1) mod 8 +1
  901.     move.w    d2,(a0)+
  902.     move.w    d1,(a0)+
  903. ; Repeat indices for texels..
  904.     move.w    d6,d3
  905.     subq.w    #1,d3
  906.     lsr.w    #3,d3
  907.     mulu.w    #9,d3
  908.     add.w    d5,d3
  909.     addq.w    #1,d3
  910.     move.w    d3,(a0)+
  911.     addq.w    #1,d3
  912.     move.w    d3,(a0)+
  913.     addi.w    #9,d3
  914.     move.w    d3,(a0)+
  915. ; Ignarrogance.
  916.     ENDC
  917.  
  918.     addq.w    #1,d5
  919.     cmpi.w    #8,d5
  920.     blt.s    .face_loop
  921.     
  922.     addq.w    #8,d6
  923.     dbra    d7,.segment_face_loop
  924.  
  925. ; Do the tail (8 faces).
  926.     clr.w    d6
  927. .tail_loop:
  928.     move.w    #Polygon.TRI|Polygon.TEXTUREMAPPED,(a0)+
  929.     move.w    d6,d0
  930.     move.w    d6,d1
  931.     addq.w    #1,d0
  932.     andi.w    #7,d0
  933.     addi.w    #1+Worm.SEGMENTS*8,d0
  934.     addi.w    #1+Worm.SEGMENTS*8,d1
  935. ; vertices
  936.     move.w    #(Worm.SEGMENTS+1)*8+1,(a0)+
  937.     move.w    d1,(a0)+
  938.     move.w    d0,(a0)+
  939. ; texels
  940.     move.w    #(Worm.SEGMENTS+1)*9+1,(a0)+
  941.     move.w    d6,d0
  942.     move.w    d6,d1
  943.     addi.w    #2+Worm.SEGMENTS*9,d0
  944.     addi.w    #1+Worm.SEGMENTS*9,d1
  945.     move.w    d1,(a0)+
  946.     move.w    d0,(a0)+
  947.  
  948.     addq.w    #1,d6
  949.     cmpi.w    #8,d6
  950.     blt.s    .tail_loop
  951.  
  952. .end:    move.l    a0,d0
  953.     sub.l    a6,d0
  954.     rts
  955.  
  956. ; meant for more flexible type of worm.. a bit shitty tho..
  957. ; Calculates the intersection point between a line and a plane in 3d space.
  958. ;
  959. ; Plane equation: ax+by+cz = 0, po = (po.x, po.y, po.z)
  960. ; Line equation:  o, v = (o.x, o.y, o.z), (v.x, v.y, v.z)
  961. ;
  962. ; Substitution of line into plane yields:
  963. ;
  964. ; a(lo.x+l*v.x)+b(lo.y+l*v.y)+c(lo.z+l*v.z) = 0, (l is a scalar)         (1)
  965. ; Where lo = o - po
  966. ;
  967. ; a*l*v.x+b*l*v.y+c*l*v.z = -a*lo.x-b*lo.y-c*lo.z
  968. ; l(a*v.x+b*v.y+c*v.z) = -a*lo.x-b*lo.y-c*lo.z
  969. ;
  970. ;      -a*lo.x-b*lo.y-c*lo.z    n
  971. ; l = ----------------------- = -                                        (2)
  972. ;       a*v.x+b*v.y+c*v.z       m
  973. ;
  974. ; Now we got (2), we use it in (1) and hey, there you have the solution:
  975. ;
  976. ; o' = (o'.x, o'.y, o'.z) = (lo.x+l*v.x, lo.y+l*v.y, lo.z+l*v.z)
  977. ;
  978. ; Ofcourse we rather output with untranslated origin:
  979. ;
  980. ; o' = (o'.x, o'.y, o'.z) = (o.x+l*v.x, o.y+l*v.y, o.z+l*v.z)
  981. ;
  982. ; INPUT:
  983. ; a0: destination vertex (o')
  984. ; a1: origin vertex (o)
  985. ; a2: vector (v)
  986. ; a3: plane coefficients (a,b,c,po.x,po.y,po.z)
  987. Worm.intersectPlane:
  988. ; 1] First calculate l...
  989.  
  990. ; 1a Calculate -a*lo.x-b*lo.y-c*lo.z
  991.     movem.w    (a1),d0-d2
  992.     sub.w    6(a3),d0
  993.     sub.w    8(a3),d1
  994.     sub.w    10(a3),d2
  995.     muls.w    (a3),d0
  996.     muls.w    2(a3),d1
  997.     muls.w    4(a3),d2
  998.     neg.l    d0
  999.     sub.l    d1,d0
  1000.     sub.l    d2,d0
  1001. ; d0.l=n=-a*lo.x-b*lo.y-c*lo.z
  1002.  
  1003. ; 1b Calculate a*v.x+b*v.y+c*v.z
  1004.     movem.w    (a2),d1-d3
  1005.     muls.w    (a3)+,d1
  1006.     muls.w    (a3)+,d2
  1007.     muls.w    (a3)+,d3
  1008.     add.l    d3,d1
  1009.     add.l    d2,d1
  1010. ; d1.l=m=a*v.x+b*v.y+c*v.z
  1011.  
  1012. ; Calculate o' = (o.x+l*v.x, o.y+l*v.y, o.z+l*v.z)
  1013.     movem.w    (a2),d2-d4
  1014.     muls.w    d0,d2
  1015.     muls.w    d0,d3
  1016.     muls.w    d0,d4
  1017.     divs.w    d1,d2
  1018.     divs.w    d1,d3
  1019.     divs.w    d1,d4
  1020.     add.w    Vertex.X(a1),d2
  1021.     add.w    Vertex.Y(a1),d3
  1022.     add.w    Vertex.Z(a1),d4
  1023.  
  1024.     movem.w    d2-d4,(a0)
  1025.     rts
  1026.  
  1027. ******** OBJECT DATA ********
  1028.  
  1029.     DATA
  1030.  
  1031. ;   a-b
  1032. ;  /   \
  1033. ; h     c
  1034. ; |     |
  1035. ; g     d
  1036. ;  \   /
  1037. ;   f-e
  1038. Worm.segmentTable:
  1039.     DC.W    -100,-200,0            ; a
  1040.     DC.W    +100,-200,0            ; b
  1041.     DC.W    +200,-100,0            ; c
  1042.     DC.W    +200,+100,0            ; d
  1043.     DC.W    +100,+200,0            ; e
  1044.     DC.W    -100,+200,0            ; f
  1045.     DC.W    -200,+100,0            ; g
  1046.     DC.W    -200,-100,0            ; h
  1047.  
  1048. Worm.rectAddressTable:
  1049.     DC.L    Worm.rectangleTable
  1050.     DC.L    Worm.rectangleTable2
  1051.     DC.L    Worm.rectangleTable3
  1052.  
  1053. Worm.starAdrTable:
  1054.     DC.L    Worm.destStarTable
  1055.     DC.L    Worm.destStarTable2
  1056.     DC.L    Worm.destStarTable3
  1057.  
  1058. Worm.restoreAdrTable:
  1059.     DC.L    Worm.restoreTable
  1060.     DC.L    Worm.restoreTable2
  1061.     DC.L    Worm.restoreTable3
  1062.  
  1063. ******** OBJECT RESERVES ********
  1064.  
  1065.     BSS
  1066.  
  1067. Worm.rectangleTable:
  1068.     DS.W    4*10
  1069. Worm.rectangleTable2:
  1070.     DS.W    4*10
  1071. Worm.rectangleTable3:
  1072.     DS.W    4*10
  1073.  
  1074. Worm.matrix:
  1075.     DS.W    9
  1076. Worm.rotTable:
  1077.     DS.W    3
  1078. Worm.zoomStart:
  1079.     DS.W    1
  1080. Worm.zoomDir:
  1081.     DS.W    1
  1082. Worm.startZ:
  1083.     DS.W    1
  1084. Worm.starColor:
  1085.     DS.W    1
  1086.  
  1087. Worm.objAdr:
  1088.     DS.L    1
  1089. Worm.textureTable:
  1090.     DS.L    2
  1091.  
  1092. Worm.starTable:
  1093.     DS.W    Worm.NUMSTARS*3
  1094. Worm.destStarTable:
  1095.     DS.W    Worm.NUMSTARS*2+1
  1096. Worm.destStarTable2:
  1097.     DS.W    Worm.NUMSTARS*2+1
  1098. Worm.destStarTable3:
  1099.     DS.W    Worm.NUMSTARS*2+1
  1100. Worm.restoreTable:
  1101.     DS.W    Worm.NUMSTARS+1
  1102. Worm.restoreTable2:
  1103.     DS.W    Worm.NUMSTARS+1
  1104. Worm.restoreTable3:
  1105.     DS.W    Worm.NUMSTARS+1
  1106.  
  1107. Worm.resRout:
  1108.     DS.L    1
  1109.  
  1110. ******** END OF DEMO-EFFECT OBJECT ********