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

  1. ; Dying starfish. A screen for delta. Uses the ufly engine.
  2.  
  3. ;======= OBJECT EQUATES ====================================================
  4.  
  5. ; Change these to suit your needs.
  6. Starfish.DEPTH:        =    60
  7. Starfish.TOPDEPTH:    =    3*Starfish.DEPTH/2
  8. Starfish.ARMLENGTH:    =    1200
  9. Starfish.LE:        =    Starfish.ARMLENGTH/10
  10. Starfish.MAX_BEND:    =    2500
  11. Starfish.ARMS:        =    5            ; >=3
  12. Starfish.RINGPOINTS:    =    6            ; even and >=4
  13. Starfish.RINGS:        =    5            ; >=1
  14.  
  15. ; Do not change..
  16. Starfish.ARMPOINTS:    =    Starfish.RINGS*Starfish.RINGPOINTS+1
  17. Starfish.BINDPOINT1:    =    Starfish.ARMPOINTS*Starfish.ARMS
  18. Starfish.BINDPOINT2:    =    Starfish.ARMPOINTS*Starfish.ARMS+1
  19. Starfish.POINTS:    =    2+Starfish.ARMPOINTS*Starfish.ARMS
  20. Starfish.ARMPOLYS:    =    Starfish.RINGS*Starfish.RINGPOINTS
  21. Starfish.OUTPOLYS:    =    Starfish.ARMPOLYS*Starfish.ARMS
  22. Starfish.BINDPOLYS:    =    Starfish.RINGPOINTS*Starfish.ARMS    ; tris only
  23. Starfish.POLYS:        =    Starfish.BINDPOLYS+Starfish.OUTPOLYS
  24.  
  25.             RSRESET
  26. Starfish.object:    RS.W    8192
  27. Starfish.armAngleTable:    RS.W    Starfish.ARMS*(Starfish.RINGS+1)
  28. Starfish.background:    RS.W    320*200
  29. Starfish.shadowTable:    RS.W    1+4*2*500
  30. Starfish.shadowTable2:    RS.W    1+4*2*500
  31. Starfish.shadowTable3:    RS.W    1+4*2*500
  32. Starfish.shadowTable4:    RS.W    1+4*2*500
  33. Starfish.shadowTable5:    RS.W    1+4*2*500
  34. Starfish.shadowTable6:    RS.W    1+4*2*500
  35. Starfish.BLOCK_SIZE:    RS.B    0
  36.  
  37.  
  38. ;======= OBJECT TABLE ======================================================
  39.  
  40. ; Must be first in object!!
  41. Starfish.table:
  42.     DC.L    Starfish.mainLoop
  43.     DC.L    Starfish.init
  44.     DC.L    rts
  45.     DC.L    Starfish.incField
  46.     DC.L    Starfish.decField
  47.     DC.L    Starfish.invField
  48.     DC.L    Starfish.drop
  49.     DC.L    Starfish.setZoom
  50.     DC.L    0
  51.  
  52.     IFND    DEMO_SYSTEM
  53.     INCLUDE    SFLY_DSP.S
  54.     TEXT
  55.     ENDC
  56.  
  57. ;======= INIT SUBROUTINE ===================================================
  58.  
  59. ; OUTPUT:
  60. ; d0.l: 0   = All clear, neg = Error! Not initialized!
  61. Starfish.init:
  62.     move.l    #Starfish.BLOCK_SIZE,d0
  63.     bsr.l    Mem.register
  64.  
  65.     lea    sine_tbl,a1
  66.     bsr.l    Matrix.init
  67.  
  68. .success:
  69.     moveq    #0,d0
  70.     rts
  71. .error:    moveq    #-1,d0
  72.     rts
  73.  
  74. ;======= REALTIME INIT SUBROUTINE ==========================================
  75.  
  76. Starfish.realtimeInit:
  77.     move.l    #rts,vbl_gfx
  78.  
  79.     bsr.l    Mem.getBlock
  80.  
  81.     move.l    d0,d1
  82.     addi.l    #Starfish.object,d1
  83.     move.l    d1,Starfish.objAdr
  84.     move.l    d0,d1
  85.     addi.l    #Starfish.armAngleTable,d1
  86.     move.l    d1,Starfish.angleTableAdr
  87.     move.l    d0,d1
  88.     addi.l    #Starfish.background,d1
  89.     move.l    d1,Starfish.backAdr
  90.  
  91.     lea    Starfish.shadowAdr,a0
  92.     move.l    d0,a1
  93.     adda.l    #Starfish.shadowTable,a1
  94.     clr.l    (a1)
  95.     move.l    a1,(a0)+
  96.     move.l    d0,a1
  97.     adda.l    #Starfish.shadowTable2,a1
  98.     clr.l    (a1)
  99.     move.l    a1,(a0)+
  100.     move.l    d0,a1
  101.     adda.l    #Starfish.shadowTable3,a1
  102.     clr.l    (a1)
  103.     move.l    a1,(a0)+
  104.  
  105.     lea    Starfish.shadowAdr2,a0
  106.     move.l    d0,a1
  107.     adda.l    #Starfish.shadowTable4,a1
  108.     clr.l    (a1)
  109.     move.l    a1,(a0)+
  110.     move.l    d0,a1
  111.     adda.l    #Starfish.shadowTable5,a1
  112.     clr.l    (a1)
  113.     move.l    a1,(a0)+
  114.     move.l    d0,a1
  115.     adda.l    #Starfish.shadowTable6,a1
  116.     clr.l    (a1)
  117.     move.l    a1,(a0)+
  118.  
  119.     bsr.l    HumanFly.init
  120.  
  121.     lea    Viewport.settingsTable,a0
  122.     move.w    #320,Viewport.XSCREEN(a0)
  123.     move.w    #200,Viewport.YSCREEN(a0)
  124.     move.w    #0,Viewport.XSTART(a0)
  125.     move.w    #0,Viewport.YSTART(a0)
  126.     move.w    #320,Viewport.XEND(a0)
  127.     move.w    #200,Viewport.YEND(a0)
  128.     move.w    #160,Viewport.XCENTER(a0)
  129.     move.w    #100,Viewport.YCENTER(a0)
  130.     move.w    #256+32,Viewport.ASPECT(a0)
  131.     move.w    #$100,Viewport.FOCAL(a0)
  132.     bsr.l    Viewport.update
  133.  
  134.     lea    Starfish.textureTable,a0
  135.     bsr.l    Polygon.init
  136.  
  137.     movea.l    Starfish.backAdr,a0
  138.     bsr.l    Primitive.setScreenbuffer
  139.  
  140.     move.w    #320,d6
  141.     move.w    #200,d7
  142.     movea.l    Starfish.backAdr,a0
  143.     bsr.w    Starfish.genMarble
  144.  
  145.     movea.l    Starfish.backAdr,a0
  146.     lea    Texture.sandPal,a1
  147.     move.w    #320*200-1,d7
  148.     clr.l    d0
  149. .convloop:
  150.     move.w    (a0),d0
  151.     move.w    (a1,d0.l*4),(a0)+
  152.     dbf    d7,.convloop
  153.  
  154.     bsr.l    ObjectRegistry.clear
  155.  
  156.     lea    Starfish.fixArmAngleTable,a1
  157.     movea.l    Starfish.objAdr,a0
  158.     bsr.w    Starfish.calcBendedObject
  159.  
  160. ; d0.l=size of generated object
  161.     movea.l    Starfish.objAdr,a0
  162.     bsr.l    ObjectRegistry.set
  163.  
  164.     move.w    #-1000,d0
  165.     move.w    #-0500,d1
  166.     move.w    #+3000,d2
  167.     clr.w    d3
  168.     clr.w    d4
  169.     clr.w    d5
  170.     bsr.w    Starfish.paint
  171.  
  172.     movea.l    Starfish.rectAddressTable,a0
  173.     bsr.l    PrimitiveMesh.paint
  174.  
  175.     move.w    $4BC.w,Starfish.startTime
  176.     bsr.w    Starfish.drop
  177.  
  178.     move.w    monitormode,d0
  179.     cmpi.w    #vga60,d0
  180.     beq.s    .vga60
  181.     cmpi.w    #vga100,d0
  182.     beq.s    .vga100
  183.     cmpi.w    #rgb50,d0
  184.     beq.s    .rgb50
  185. .vga60:    move.l    #vga60_16bit_320_200,Starfish.resRout
  186.     rts
  187. .vga100:move.l    #vga100_16bit_320_200,Starfish.resRout
  188.     rts
  189. .rgb50:    move.l    #rgb50_16bit_320_200,Starfish.resRout
  190.     rts
  191.  
  192. ;======= SCREENINIT SUBROUTINE =============================================
  193.  
  194. Starfish.initScreen:
  195.     movea.l    scr,a0
  196.     movea.l    Starfish.backAdr,a1
  197.     bsr.l    COPY_PIC32020016
  198.     rts
  199.  
  200. ;======= MAINLOOP SUBROUTINE ===============================================
  201.  
  202. Starfish.mainLoop:
  203.     move.l    frmcnt,d0
  204.     sub.l    lastframecount,d0
  205.     bne.s    .end_realtime_init
  206.     move.l    d0,-(sp)
  207.     bsr.w    Starfish.realtimeInit
  208.     move.l    (sp)+,d0
  209. .end_realtime_init:
  210.     cmpi.l    #3,d0
  211.     bhs.s    .end_screeninit
  212.     bsr.w    Starfish.initScreen
  213. .end_screeninit:
  214.  
  215.     tst.w    Starfish.zooming
  216.     bne.s    .zoom_it
  217.     bsr.w    Starfish.paintScene
  218.     bra.s    .end_paint
  219. .zoom_it:
  220.     bsr.w    Starfish.zoom
  221. .end_paint:
  222.  
  223.     lea    scr,a0
  224.     move.l    (a0)+,d0
  225.     move.l    (a0)+,d1
  226.     move.l    (a0),-4(a0)
  227.     move.l    d0,(a0)
  228.     move.l    d1,-8(a0)
  229.  
  230.     movea.l    Starfish.resRout,a0
  231.     suba.l    a1,a1
  232.     movea.l    d0,a2
  233. .again:    bsr.l    Screen.requestUpdate
  234.     tst.l    d0
  235.     bmi.s    .again
  236.     clr.l    Starfish.resRout
  237.  
  238.     rts
  239.  
  240. ;======= OBJECT SUBROUTINES ================================================
  241.  
  242. Starfish.incField:
  243.     addi.w    #$0020,Starfish.fieldStrength
  244.     rts
  245.  
  246. Starfish.decField:
  247.     subi.w    #$0020,Starfish.fieldStrength
  248.     rts
  249.  
  250. Starfish.invField:
  251.     neg.w    Starfish.fieldStrength
  252.     rts
  253.  
  254. Starfish.drop:
  255.     st    Starfish.falling
  256.     clr.w    Starfish.zooming
  257.     rts
  258.  
  259. Starfish.setZoom:
  260. ; Copy current screen to background-buffer.
  261.     movea.l    scr+8,a1
  262.     movea.l    Starfish.backAdr,a0
  263.     bsr.l    COPY_PIC32020016
  264.  
  265.     st    Starfish.zooming
  266.     move.w    $04BC.w,Starfish.zoomStart
  267.     rts
  268.  
  269. ; Very small and nice 'marble' texture generator.
  270. ; Ripped from lost 4ktro by lucky/inter.
  271. ; INPUT:
  272. ; d6.w=width (w)
  273. ; d7.w=height (w)
  274. ; a0: dst buffer (w*h words)
  275. Starfish.genMarble:
  276. ; Make a row of noise...
  277.     move.w      D6,D0
  278.     bra.s       .marmor_w6
  279. .marmor_l0:
  280.     move.w      D1,(A0)+
  281. .marmor_w6:
  282.     rol.l       #5,D5
  283.     eori.l      #$3551462F,D5
  284.     addq.l      #1,D5
  285.     move.w      D5,D2
  286.     and.w       #7,D2
  287.     cmp.w       #7,D2
  288.     bne.s       .marmor_w4
  289.     moveq       #6,D2
  290. .marmor_w4:
  291.     add.w       D2,D1
  292.     subq.w      #3,D1
  293.     bpl.s       .marmor_w0
  294.     moveq       #0,D1
  295. .marmor_w0:
  296.     cmp.w       #$27,D1
  297.     ble.s       .marmor_w1
  298.     moveq       #$27,D1
  299. .marmor_w1:
  300.     dbra        D0,.marmor_l0
  301.  
  302. ; Back to rowstart...
  303.     move.w      D6,D0
  304.     neg.w       D0
  305.     lsl.w       #1,D0
  306.     lea         0(A0,D0.w),A1
  307.  
  308. ; Average and add a pass of noise to the whole texture (?).
  309. ; a1,a2,a3 lag behind a0, so output hights are 'recycled' for averaging.
  310. ; Nice trick. Very fast.
  311.     lea         2(A1),A2
  312.     lea         4(A2),A3
  313.     move.w      D7,D0
  314.     subq.w      #1,D0
  315.     mulu.w      D6,D0                ; d0.w=w*(h-1)
  316.     subq.w      #1,D0
  317. .marmor_l1:
  318.     move.w      (A2)+,D1
  319.     add.w       D1,D1
  320.     add.w       (A1)+,D1
  321.     add.w       (A3)+,D1
  322.     lsr.w       #2,D1
  323.     move.l    d5,d2
  324.     rol.l       #5,D5
  325.     eori.l      #-$3A5E8A3B,D5
  326.     addq.l      #7,D5
  327.     move.w      D5,D2
  328.     and.w       #7,D2
  329.     cmp.w       #7,D2
  330.     bne.s       .marmor_w5
  331.     moveq       #6,D2
  332. .marmor_w5:
  333.     add.w       D2,D1
  334.     subq.w      #3,D1
  335.     bpl.s       .marmor_w2
  336.     moveq       #0,D1
  337. .marmor_w2:
  338.     cmp.w       #39,D1
  339.     ble.s       .marmor_w3
  340.     moveq       #39,D1
  341. .marmor_w3:
  342.     move.w      D1,(A0)+
  343.     dbf    D0,.marmor_l1
  344.  
  345.     rts         
  346.  
  347. ; Update all arms of starfish according to a stream (a simple field).
  348. ; INPUT:
  349. ; d0.w=rot-offset
  350. ; a0: armtable
  351. Starfish.update:
  352.     moveq    #Starfish.ARMS-1,d7
  353.     move.w    d0,.rot
  354.  
  355. .loop:    move.w    Starfish.fieldStrength,d1
  356.     move.w    d7,d0
  357.     mulu.w    #sintbllen/Starfish.ARMS,d0
  358.     add.w    .rot(pc),d0
  359.     Do_SinModulo    d0
  360.     move.w    d0,(a0)                ; Store baseangle.
  361.     move.w    d7,-(sp)
  362.     bsr    Starfish.updateArm
  363.     move.w    (sp)+,d7
  364. ; a0: next armtable    
  365.     dbf    d7,.loop    
  366.     rts
  367.  
  368. .rot:    DC.W    0
  369.  
  370. ; Updates bent arm. Modelled as a string of massless nodes with some
  371. ; elastic properties..
  372. ;
  373. ; Seems to work, even if it neglect mass, friction of several kinds, etc..
  374. ; Abstraction (cheating) rules! =:-)
  375. ;
  376. ; theta[k, t+1] = theta[k, t] + d_theta[k, t]
  377. ;
  378. ;                             p
  379. ; d_theta[k+1]=(1-theta[k]/pi) *cos(sumtheta[k])*F
  380. ;
  381. ; sumtheta[k]=theta[0]+theta[1]+...+theta[k] (angle from armaxis)
  382. ;
  383. ; F=applied force
  384. ; p=power term used to limit big angle changes
  385. ;
  386. ; btw. p=32 gives reasonably stable results. (quite sick i know!)
  387. ; INPUT:
  388. ; d1.w=force in pos y direction (F) (8:8)
  389. ; a0: arm angletable
  390. ; OUTPUT:
  391. ; a0: end of angletable
  392. Starfish.updateArm:
  393.     lea    sine_tbl,a1
  394.     moveq    #Starfish.RINGS-1,d7
  395.     move.w    (a0)+,d2            ; d2.w=startangle
  396.  
  397. .loop:    move.w    (a0),d0
  398.     lsr.w    #5,d0
  399.  
  400.     Do_SinModulo    d0            ; d0.w=theta[k, t]
  401.     add.w    d0,d2
  402.     Do_SinModulo    d2            ; d2.w=sumtheta[k, t]
  403.     Get_Cos    a1,d2,d3            ; d3.w=cos(sumtheta[k, t])
  404.     move.w    #sintbllen/2-1,d4
  405.     sub.w    d0,d4
  406.     Do_SinModulo    d4
  407.     mulu.w    #$10000/sintbllen,d4        ; d4.w=1-theta[k, t]/pi (sgn frac)
  408.     REPT    5
  409.     muls.w    d4,d4
  410.     add.l    d4,d4
  411.     swap    d4
  412.     ENDR
  413.     muls.w    d4,d3
  414.     add.l    d3,d3
  415.     swap    d3                ; d3.w=(1-theta[k, t]/pi)*cos(sumtheta[k, t])
  416.     muls.w    d1,d3
  417.  
  418.     tst.w    d3
  419.     swap    d3
  420.     bpl.s    .end_round
  421.     addq.w    #1,d3
  422. .end_round:
  423.  
  424. ; Neglect minute angle differences..
  425.     move.w    d3,d4
  426.     bpl.s    .pos1
  427.     neg.w    d4
  428. .pos1:    cmpi.w    #5,d4
  429.     bgt.s    .diff_ok
  430.     clr.w    d3
  431. .diff_ok:
  432.  
  433. ; Update angle..
  434. ; d3.w=F*(1-theta[k, t]/pi)*cos(sumtheta[k, t])
  435. ; d3.w=theta[k, t+1]
  436.     add.w    (a0),d3
  437.     move.w    d3,d4
  438.     bpl.s    .pos
  439.     neg.w    d3
  440. .pos:    cmpi.w    #Starfish.MAX_BEND,d3
  441.     blt.s    .value_in_range
  442.     move.w    #Starfish.MAX_BEND,d3
  443. .value_in_range:
  444.     tst.w    d4
  445.     bpl.s    .ok
  446.     neg.w    d3
  447. .ok:    move.w    d3,(a0)+            ; Store new theta[k].
  448.     dbf    d7,.loop    
  449.     rts
  450.  
  451.     IFNE    0
  452. ; Paints a wireframe respresentation of the massless string model starfish.
  453. ;               [cos(sumtheta[k])]
  454. ; p[k+1]=p[k]+L*[                ] 
  455. ;               [sin(sumtheta[k])]
  456. ;
  457. Starfish.paintWF:
  458.     movea.l    Starfish.angleTableAdr,a0
  459.     moveq    #Starfish.ARMS-1,d7
  460.  
  461. .arm_loop:
  462.     moveq    #Starfish.RINGS-1,d6
  463.     movea.w    #160,a1
  464.     movea.w    #100,a2
  465.     move.w    (a0)+,d0            ; d0.w=startangle
  466.  
  467. .point_loop:
  468.     move.w    (a0)+,d1
  469.     lsr.w    #5,d1
  470.     add.w    d1,d0
  471.     Do_SinModulo    d0
  472.     move.w    d0,-(sp)
  473.     Get_SinCos    sine_tbl,d0,d1,d2
  474.     muls.w    #20*2,d1
  475.     muls.w    #20*2,d2
  476.     swap    d1
  477.     swap    d2
  478.     move.l    a1,d0
  479.     adda.w    d1,a1
  480.     move.l    a2,d1
  481.     adda.w    d2,a2
  482.     move.l    a1,d2
  483.     move.l    a2,d3
  484.     movem.l    d6-a2,-(sp)
  485.     bsr.l    Line.paintFlatshaded
  486.     movem.l    (sp)+,d6-a2
  487.     move.w    (sp)+,d0
  488.     dbf    d6,.point_loop
  489.  
  490.     dbf    d7,.arm_loop
  491.     rts
  492.     ENDC
  493.  
  494. ; Generates a starfish that can have bended arms.
  495. ; Not the best possible model for normal-based shading. It needs patching.
  496. ; todo: skewed normals on arms.. patched normals close to binder!
  497. ;
  498. ; parametrisation:
  499. ;
  500. ; 0<=alpha<2pi,         0<=beta<2pi,    0<=t<=1, l=AL*t
  501. ; controls pos in ring, controls armnr, controls pos in arm (ringnumber)
  502. ;
  503. ; AL=*armlength*
  504. ;
  505. ;      A
  506. ;  _________
  507. ;  \b  |  c/
  508. ;   \ L|  /
  509. ;  B \ | / B
  510. ;     \|/
  511. ;      a
  512. ;
  513. ; L=AL/(#rings+1), a=2pi/#arms
  514. ;
  515. ; tan(a/2)=tan(pi/#arms)=(A/2)/C=A/2L
  516. ;
  517. ; =>
  518. ;
  519. ;                         2*AL*tan(pi/#arms)
  520. ; A = 2L*tan(pi/#arms) = -------------------- = *armwidth*
  521. ;                            (#rings+1)
  522. ;---------------------------------------------------------------------------
  523. ;
  524. ; Parametrisation of bended arms:
  525. ;
  526. ; su=cos(alpha)(1-t)A/2, sv=sin(alpha)(1-t)A/2 (scalars of u, v)
  527. ;                                                          -  -
  528. ; d is direction vector of arm, |d| = 1, d.z=0
  529. ; -                              -
  530. ; c is center vector. c[t+1]=c[t]+sd[t], c[0]=0
  531. ; -                   -      -    --     -    -
  532. ;
  533. ;                      [cos(sumtheta[t]+beta)]
  534. ; sd[t] = ll*d[t] = ll*[sin(sumtheta[t]+beta)]
  535. ; --                   [        0            ]
  536. ;
  537. ; a = c + su*u+sv*v
  538. ; -   -      -    -
  539. ;
  540. ; a.x   c.x -su*d.y
  541. ; a.y = c.y +su*d.x
  542. ; a.z   c.z +sv
  543. ;
  544. ; u . d = v . d = u . v = 0 & |d| = 1 & d.z = 0
  545. ; -   -   -   -   -   -        -
  546. ;
  547. ; =>
  548. ;
  549. ;     [-d.y]       [ 0 ]
  550. ; u = [+d.x] , v = [ 0 ]
  551. ; -   [ 0  ]   -   [ 1 ]
  552. ;
  553. ;---------------------------------------------------------------------------
  554. ;
  555. ; normals given by biasing (0,0,1),
  556. ; rotation around x-axis alpha degrees,
  557. ; rotation around z-axis beta degrees.
  558. ;
  559. ; n.x          1       [+A*cos(beta)+AL*sin(alpha)*cin(beta)]
  560. ; n.y = -------------- [-A*sin(beta)+AL*sin(alpha)*cos(beta)]
  561. ; n.z   sqrt(A^2+AL^2) [+AL*cos(alpha)                      ]
  562. ;
  563. ;       [+A'*cos(beta)+AL'*sin(alpha)*sin(beta)]
  564. ;     = [-A'*sin(beta)+AL'*sin(alpha)*cos(beta)]
  565. ;       [+AL'*cos(alpha)                       ]
  566. ;
  567. ; A' =A/sqrt(A^2+AL^2)
  568. ; AL'=AL/sqrt(A^2+AL^2)
  569. ;
  570. ;---------------------------------------------------------------------------
  571. ;
  572. ; INPUT:
  573. ; a0: dst object
  574. ; a1: arm angletables
  575. ; OUTPUT:
  576. ; d0.l=size of object
  577. Starfish.calcBendedObject:
  578.     movea.l    a0,a6                ; a6: dst object
  579.     movea.l    a1,a2                ; a2: armangle tables
  580.  
  581. ; Output vertices..
  582.     move.w    #2*Starfish.POINTS,(a0)+    ; Store #vertices+#normals.
  583.     move.w    #Starfish.POINTS,(a0)+        ; Store #normals.
  584.     lea    Starfish.POINTS*Vertex.SIZE(a0),a3
  585.     lea    sine_tbl,a1
  586.     moveq    #Starfish.ARMS-1,d7
  587.  
  588. ; Calc A/2..
  589.     move.w    #sintbllen/(2*Starfish.ARMS),d0
  590.     Get_SinCos    a1,d0,d0,d1
  591. ; 0<=bla<=pi/4  =>  0<=sin(bla)<=1
  592.     subq.w    #1,d0
  593.     swap    d0
  594.     clr.w    d0
  595.     divu.w    d1,d0
  596. ; d0.w=tan(pi/#arms) (frac)
  597.     mulu.w    #Starfish.LE,d0
  598.     move.l    d0,d1
  599.     tst.w    d0
  600.     swap    d0
  601.     bpl.s    .end_round_a
  602.     addq.w    #1,d0
  603. .end_round_a:
  604.     move.w    d0,.a_div_2
  605. ; .a_div_2.w=A/2=L*tan(pi/#arms) (int)
  606.  
  607. ; calc A', AL'
  608.     move.w    #Starfish.ARMLENGTH,d0
  609.     mulu.w    d0,d0                    ; d0.l=AL*AL
  610.     add.l    d1,d1
  611.     move.l    d1,d4
  612.     swap    d1
  613.     mulu.w    d1,d1                    ; d1.l=A*A
  614.     add.l    d0,d1                    ; d1.l=AL^2+A^2
  615.     bsr.l    Math.sqrt                ; d0.l=sqrt(A^2+AL^2) (16:16)
  616.     swap    d0                    ; d0.w=sqrt(A^2+AL^2) (int)
  617.     clr.l    d3
  618.     move.w    #Starfish.ARMLENGTH,d3
  619.     swap    d3
  620.     lsr.l    d3                    ; for signed crap
  621.     divu.w    d0,d3
  622.     move.w    d3,.al_t
  623.     lsr.l    d4
  624.     divu.w    d0,d4                    ; for signed crap
  625.     move.w    d4,.a_t
  626.  
  627. .arm_pointloop:
  628.     swap    d7
  629.     move.w    #Starfish.RINGS,d7
  630.  
  631.     move.w    (a2)+,d0
  632.     move.w    d0,.sum_theta
  633. ; d0.w=beta
  634.  
  635. ; Reset c, calc d[0].
  636. ;       -       -
  637.     Do_SinModulo    d0
  638.     Get_SinCos    a1,d0,d0,d1
  639. ; d0.w=d.x, d1.w=d.y
  640.     move.w    d0,.dx
  641.     move.w    d1,.dy
  642.     muls.w    #49*Starfish.LE*2/50,d0
  643.     muls.w    #49*Starfish.LE*2/50,d1
  644.     swap    d0
  645.     swap    d1
  646.     move.w    d0,.cx
  647.     move.w    d1,.cy
  648.  
  649. .ring_pointloop:
  650.     moveq    #Starfish.RINGPOINTS-1,d6
  651.  
  652. ; Calc 1-t.
  653.     move.w    d7,d0
  654.     mulu.w    #$7FFF/Starfish.RINGS,d0
  655.     move.w    d0,.one_min_t
  656. ; .one_min_t.w=1-t (sgn frac)
  657.  
  658. ; Calc points in ring...
  659. .pointloop:
  660.     move.w    d6,d0
  661.     mulu.w    #sintbllen/Starfish.RINGPOINTS,d0    ; d0.w=alpha
  662.     Get_SinCos    a1,d0,d0,d1
  663. ; d0.w=sin(alpha), d1.w=cos(alpha) (sgn frac)
  664.     exg.l    d0,d1
  665.     movem.w    d0-d1,.sin_alpha
  666.  
  667. ; Calc su, sv.
  668.     move.w    .a_div_2(pc),d2            ; d2.w=A/2
  669.     mulu.w    .one_min_t(pc),d2
  670.     add.l    d2,d2
  671.     tst.w    d2
  672.     swap    d2
  673.     bpl.s    .end_round_ta
  674.     addq.w    #1,d2
  675. .end_round_ta:
  676.     move.w    d2,d3
  677. ; d2.w=d3.w=(1-t)A/2 (sgn frac)
  678.     
  679.     muls.w    d0,d2
  680.     add.l    d2,d2
  681.     tst.w    d2
  682.     swap    d2
  683.     bpl.s    .end_round_su
  684.     addq.w    #1,d2
  685. .end_round_su:
  686.     move.w    d2,.su
  687.  
  688.     move.w    d0,d4                ; d4.w=cos(alpha)
  689.     move.w    d1,d5                ; d5.w=sin(alpha)
  690.  
  691. ; Todo: apply scale to this!
  692.     muls.w    d1,d3
  693.     add.l    d3,d3
  694.     tst.w    d3
  695.     swap    d3
  696.     bpl.s    .end_round_sv
  697.     addq.w    #1,d3
  698. .end_round_sv:
  699.     move.w    d3,.sv
  700.  
  701. ; a.x = c.x -su*d.y
  702.     move.w    .su(pc),d0
  703.     muls.w    .dy(pc),d0
  704.     add.l    d0,d0
  705.     swap    d0
  706.     move.w    .cx(pc),d1
  707.     sub.w    d0,d1
  708.     move.w    d1,(a0)+            ; Store x.
  709.  
  710. ; y negated for backface elend
  711. ; a.y = c.y +su*d.x
  712.     move.w    .su(pc),d0
  713.     muls.w    .dx(pc),d0
  714.     add.l    d0,d0
  715.     swap    d0
  716.     add.w    .cy(pc),d0
  717.     neg.w    d0
  718.     move.w    d0,(a0)+            ; Store y.
  719.  
  720. ; a.z = +sv
  721.     move.w    .sv(pc),(a0)+            ; Store z.
  722.  
  723. ;     [+A'*cos(beta)+AL'*sin(alpha)*sin(beta)]
  724. ; n = [-A'*sin(beta)+AL'*sin(alpha)*cos(beta)]
  725. ; -   [+AL'*cos(alpha)                       ]
  726.     IFNE    0
  727.     move.w    .dx(pc),d0            ; d0.w=cos(beta)
  728.     move.w    .dy(pc),d1            ; d1.w=sin(beta)
  729.     move.w    d0,d2                ; d2.w=cos(beta)
  730.     move.w    d1,d3                ; d3.w=sin(beta)
  731.  
  732. ; Calculate n.x.
  733.     muls.w    .a_t(pc),d0            ; d0.l=A'*cos(beta)/2
  734.     muls.w    .al_t(pc),d1            ; d1.l=AL'*sin(beta)/2
  735.     add.l    d1,d1
  736.     swap    d1
  737.     muls.w    .sin_alpha(pc),d1        ; d1.l=AL'*sin(alpha)*sin(beta)/2
  738.     add.l    d1,d0
  739.     add.l    d0,d0                ; d0.l=n.x (16:16)
  740.     swap    d0
  741.     muls.w    #$E0,d0
  742.     swap    d0
  743.     move.w    d0,Vertex.X(a3)            ; Store n.x.
  744.     
  745. ; Calculate n.y.
  746.     muls.w    .a_t(pc),d3            ; d3.l=A'*sin(beta)/2
  747.     muls.w    .al_t(pc),d2            ; d2.l=AL'*cos(beta)/2    
  748.     add.l    d2,d2
  749.     swap    d2
  750.     muls.w    .sin_alpha(pc),d2        ; d2.l=AL'*sin(alpha)*cos(beta)/2
  751.     sub.l    d3,d2
  752.     add.l    d2,d2                ; d2.l=n.y (16:16)
  753.     swap    d2
  754.     muls.w    #$E0,d2
  755.     swap    d2
  756.     move.w    d2,Vertex.Y(a3)            ; Store n.y.
  757.  
  758. ; Calculate n.z.
  759.     move.w    .al_t(pc),d0            ; d0.w=AL'
  760.     muls.w    .cos_alpha(pc),d0        ; d0.l=AL'*cos(alpha)/2
  761.     add.l    d0,d0                ; d0.l=AL'*cos(alpha)
  762.     swap    d0                ; d0.w=AL'*cos(alpha)=n.z
  763.     muls.w    #$E0,d0
  764.     swap    d0
  765.     move.w    d0,Vertex.Z(a3)            ; Store n.z.
  766.  
  767.     addq    #Vertex.SIZE,a3
  768.  
  769.     ELSE
  770. ; old, unbiased normal..
  771.     move.w    d4,d2
  772.     muls.w    .dy(pc),d2
  773.     add.l    d2,d2
  774.     swap    d2
  775.     neg.w    d2
  776.     asr.w    #8,d2
  777.     move.w    d2,(a3)+            ; Store n.x.
  778.     move.w    d4,d2
  779.     muls.w    .dx(pc),d2
  780.     add.l    d2,d2
  781.     swap    d2
  782.     neg.w    d2
  783.     asr.w    #8,d2
  784.     move.w    d2,(a3)+            ; Store n.y
  785.     asr.w    #8,d5
  786.     move.w    d5,(a3)+            ; Store n.z.
  787.     ENDC
  788.  
  789.     dbf    d6,.pointloop
  790.  
  791.  
  792.     move.w    (a2)+,d0            ; d0.w=theta[t+1]<<5
  793.     lsr.w    #5,d0                ; d0.w=theta[t+1]
  794.     add.w    d0,.sum_theta            ; d0.w=sumtheta[t+1]
  795.  
  796. ; Calc c[t+1] = c[t] + d[t]
  797. ;      -        -      -
  798.     move.w    .sum_theta(pc),d0
  799.     Do_SinModulo    d0
  800.     Get_SinCos    a1,d0,d0,d1
  801. ; d0.w=d.x, d1.w=d.y
  802.     move.w    d0,.dx
  803.     move.w    d1,.dy
  804.     muls.w    #Starfish.ARMLENGTH*2/Starfish.RINGS,d0
  805.     muls.w    #Starfish.ARMLENGTH*2/Starfish.RINGS,d1
  806.     swap    d0
  807.     swap    d1
  808. ; d0.w=sd.x, d1.w=sd.y
  809.     add.w    d0,.cx
  810.     add.w    d1,.cy
  811.  
  812.     subq.w    #1,d7
  813.     bgt    .ring_pointloop
  814.  
  815.     move.w    .cx(pc),(a0)+            ; Store x.
  816.     move.w    .cy(pc),d0
  817.     neg.w    d0
  818.     move.w    d0,(a0)+            ; Store y.
  819.     clr.w    (a0)+                ; Store z.
  820.  
  821.     move.w    .dx(pc),d0
  822.     asr.w    #8,d0
  823.     cmpi.w    #$FF80,d0
  824.     bgt.s    .ok
  825.     move.w    #$FF81,d0
  826. .ok:    move.w    d0,(a3)+            ; Store n.x.
  827.     move.w    .dy(pc),d0
  828.     asr.w    #8,d0
  829.     neg.w    d0
  830.     cmpi.w    #$FF80,d0
  831.     bgt.s    .ok2
  832.     move.w    #$FF81,d0
  833. .ok2:    move.w    d0,(a3)+            ; Store n.y.
  834.     clr.w    (a3)+                ; Store n.z.
  835.  
  836.     swap    d7
  837.     dbf    d7,.arm_pointloop
  838.  
  839. ; Store binder vertices..
  840.     clr.l    (a0)+                ; Store (x,y)
  841.     move.w    #+Starfish.TOPDEPTH,(a0)+
  842.     clr.l    (a0)+                ; Store (x,y)
  843.     move.w    #-Starfish.TOPDEPTH,(a0)+
  844.     clr.l    (a3)+
  845.     move.w    #+127,(a3)+
  846.     clr.l    (a3)+
  847.     move.w    #-127,(a3)+
  848.  
  849.     movea.l    a3,a0                ; a0: end of vertices/normals
  850.  
  851. ; texels
  852.     clr.w    (a0)+
  853.  
  854. ; polys
  855. ; arm polys
  856. ; todo: fuck this around cos of changed spikepoint position!
  857.     move.w    #Starfish.POLYS,(a0)+
  858.     clr.w    d2
  859.     moveq    #Starfish.ARMS-1,d7
  860.  
  861. .poly_armloop:
  862.  
  863. ; Output spike triangles in arm..
  864.     moveq    #Starfish.RINGPOINTS-1,d5
  865.  
  866. .spike_polyloop:
  867. ; Output polyhead.
  868.     move.w    #Polygon.TRI|Polygon.ENVMAPPED|0,(a0)+
  869.  
  870.     clr.l    d0
  871.     move.w    d5,d0
  872.     addq.w    #1,d0
  873.     divu.w    #Starfish.RINGPOINTS,d0
  874.     swap    d0
  875.     addi.w    #Starfish.ARMPOINTS-1-Starfish.RINGPOINTS,d0
  876.     add.w    d2,d0
  877.     move.w    d0,(a0)+
  878.  
  879.     move.w    #Starfish.ARMPOINTS-1,d0
  880.     add.w    d2,d0
  881.     move.w    d0,(a0)+            ; Store spikeref.
  882.  
  883.     move.w    d5,d0
  884.     addi.w    #Starfish.ARMPOINTS-1-Starfish.RINGPOINTS,d0
  885.     add.w    d2,d0
  886.     move.w    d0,(a0)+
  887.  
  888. ; Store normal-refs..
  889.     REPT    3
  890.     move.w    -6(a0),d0
  891.     addi.w    #Starfish.POINTS,d0
  892.     move.w    d0,(a0)+
  893.     ENDR
  894.  
  895.     dbf    d5,.spike_polyloop
  896.  
  897.     moveq    #Starfish.RINGS-2,d6
  898. .poly_ringloop:
  899.  
  900.     moveq    #Starfish.RINGPOINTS-1,d5
  901. .polyloop:
  902. ; Output polyhead.
  903.     move.w    #Polygon.QUAD|Polygon.ENVMAPPED|0,(a0)+
  904.  
  905.     move.w    d6,d0
  906.     mulu.w    #Starfish.RINGPOINTS,d0
  907.     add.w    d2,d0
  908. ; row*n + i
  909.     move.w    d0,d1
  910.     add.w    d5,d1
  911.     move.w    d1,(a0)+
  912. ; row*n + [(i+1) mod n]
  913.     clr.l    d1
  914.     move.w    d5,d1
  915.     addq.w    #1,d1
  916.     divu.w    #Starfish.RINGPOINTS,d1
  917.     swap    d1
  918.     add.w    d0,d1
  919.     move.w    d1,(a0)+
  920. ; row*(n+1) + [(i+1) mod n]
  921.     addi.w    #Starfish.RINGPOINTS,d1
  922.     move.w    d1,(a0)+
  923. ; row*(n+1) + i
  924.     move.w    d0,d1
  925.     add.w    d5,d1
  926.     addi.w    #Starfish.RINGPOINTS,d1
  927.     move.w    d1,(a0)+
  928.  
  929. ; Store normal-refs..
  930.     REPT    4
  931.     move.w    -8(a0),d0
  932.     addi.w    #Starfish.POINTS,d0
  933.     move.w    d0,(a0)+
  934.     ENDR
  935.     
  936.     dbf    d5,.polyloop
  937.  
  938.     dbf    d6,.poly_ringloop
  939.  
  940.     addi.w    #Starfish.ARMPOINTS,d2
  941.     dbf    d7,.poly_armloop
  942.  
  943. ; binder polys
  944.     clr.w    d2
  945.     moveq    #Starfish.ARMS-1,d7
  946.  
  947. .bindpoly_armloop:
  948.     moveq    #Starfish.RINGPOINTS-1,d6
  949.  
  950. .bindpoly_ringloop:
  951. ; Output polyhead.
  952.     move.w    #Polygon.TRI|Polygon.ENVMAPPED|0,(a0)+
  953.  
  954.     move.w    #Starfish.RINGPOINTS-2,d0
  955.     cmpi.w    #Starfish.RINGPOINTS-1,d6
  956.     bne.s    .no_adj
  957.     move.w    #Starfish.RINGPOINTS-1,d0
  958.     bra.s    .end_adj
  959. .no_adj:sub.w    d6,d0
  960. .end_adj:
  961.     add.w    d2,d0
  962.     move.w    d0,(a0)+
  963.  
  964.     cmpi.w    #Starfish.RINGPOINTS/2,d6
  965.     bhs.s    .oki
  966.     move.w    #Starfish.BINDPOINT1,(a0)+
  967.     bra.s    .end_store_bindpoint
  968. .oki:    move.w    #Starfish.BINDPOINT2,(a0)+
  969. .end_store_bindpoint:
  970.  
  971.     move.w    #Starfish.RINGPOINTS-1,d0
  972.     sub.w    d6,d0
  973.     add.w    d2,d0
  974.     move.w    d0,(a0)+
  975.  
  976. ; Store normal-refs..
  977.     REPT    3
  978.     move.w    -6(a0),d0
  979.     addi.w    #Starfish.POINTS,d0
  980.     move.w    d0,(a0)+
  981.     ENDR
  982.  
  983.     dbf    d6,.bindpoly_ringloop
  984.  
  985.     addi.w    #Starfish.ARMPOINTS,d2
  986.     dbf    d7,.bindpoly_armloop
  987.  
  988. ; Calc size of object..
  989.     move.l    a0,d0
  990.     sub.l    a6,d0
  991.     rts
  992.  
  993. .cx:    DC.W    0
  994. .cy:    DC.W    0
  995. .dx:    DC.W    0
  996. .dy:    DC.W    0
  997. .sin_alpha:
  998.     DC.W    0
  999. .cos_alpha:
  1000.     DC.W    0
  1001. .a_t:    DC.W    0
  1002. .al_t:    DC.W    0
  1003. .a_div_2:
  1004.     DC.W    0
  1005. .one_min_t:
  1006.     DC.W    0
  1007. .su:    DC.W    0
  1008. .sv:    DC.W    0
  1009. .sum_theta:
  1010.     DC.W    0
  1011.  
  1012. ; INPUT:
  1013. ; d0.w=x offset
  1014. ; d1.w=y offset
  1015. ; d2.w=z offset
  1016. ; d3.w=xrot
  1017. ; d4.w=yrot
  1018. ; d5.w=zrot
  1019. Starfish.paint:
  1020.     movem.w    d0-d2,-(sp)
  1021.     movem.w    d3-d5,-(sp)
  1022.  
  1023.     movea.l    Starfish.shadowAdrAdr,a0    ; a0: log table adrs
  1024.     movea.l    (a0),a0                ; a0: current log table
  1025.     bsr.l    PrimitiveMesh.newShadowed
  1026.  
  1027.     movem.w    (sp)+,d0-d2
  1028.     bsr.l    Matrix.generate
  1029.  
  1030.     movem.w    (sp)+,d0-d2
  1031.     bsr.l    Matrix.translate
  1032.     bsr.l    Matrix.push
  1033.     moveq    #TransformObject.BACKFACE_CULLING|TransformObject.PERSPECTIVATE,d0
  1034.     moveq    #0,d1
  1035.     bsr.l    TransformObject.transform
  1036.     bsr.l    Matrix.pop
  1037.  
  1038.     bsr.l    PrimitiveMesh.sortZ
  1039.  
  1040.     bsr.l    PrimitiveMesh.complete
  1041.  
  1042.     rts
  1043.  
  1044. Starfish.paintScene:
  1045.     movea.l    scr,a0
  1046.     bsr.l    Primitive.setScreenbuffer
  1047.  
  1048.     bsr.l    ObjectRegistry.clear
  1049.  
  1050.     movea.l    Starfish.angleTableAdr,a1
  1051.     movea.l    Starfish.objAdr,a0
  1052.     bsr.w    Starfish.calcBendedObject
  1053.  
  1054. ; d0.l=size of generated object
  1055.     movea.l    Starfish.objAdr,a0
  1056.     bsr.l    ObjectRegistry.set
  1057.  
  1058.     move.w    #+0600,d0
  1059.     move.w    #+0100,d1
  1060.     move.w    #+3000,d2
  1061.     tst.w    Starfish.falling
  1062.     beq.s    .not_falling
  1063.     move.w    $04BC.w,d2
  1064.     sub.w    Starfish.startTime,d2
  1065.     add.w    d2,d2
  1066.  
  1067. ; Use a squareroot for the movement.
  1068.     movem.w    d0-d1,-(sp)
  1069.     clr.l    d1
  1070.     move.w    d2,d1
  1071.     lsl.l    #8,d1
  1072.     lsl.l    #3,d1
  1073.     bsr.l    Math.sqrt
  1074.     move.l    d0,d2
  1075.     swap    d2
  1076.     movem.w    (sp)+,d0-d1
  1077.  
  1078.     cmpi.w    #+3000,d2
  1079.     blt.s    .depth_ok
  1080.     move.w    #+3000,d2
  1081.     clr.w    Starfish.falling
  1082. .not_falling:
  1083.     clr.w    d3
  1084.     clr.w    d4
  1085.     clr.w    d5
  1086. ;    bra.s    .paint
  1087. .depth_ok:
  1088.     clr.w    d3
  1089.     move.w    $04BC.w,d4
  1090.     sub.w    Starfish.startTime,d4
  1091.     lsl.w    #2,d4
  1092.     Do_SinModulo    d4
  1093.     Get_Sin    sine_tbl,d4,d4
  1094.  
  1095. ; Recycle the squareroot movement for the 'swing' amplitude.
  1096.     move.w    #3000,d6
  1097.     sub.w    d2,d6
  1098.     muls.w    d6,d4
  1099.     swap    d4
  1100.     asr.w    #2,d4
  1101.  
  1102.     clr.w    d5
  1103. .paint:    bsr.w    Starfish.paint
  1104.  
  1105. ;- parallel shit -----------------------------------------------------------
  1106.     movea.l    Starfish.angleTableAdr,a0
  1107.     
  1108.     move.w    Starfish.oldRot,d0
  1109.     tst.w    Starfish.falling
  1110.     beq.s    .rot_calced
  1111.     move.w    $04BC.w,d0
  1112.     sub.w    Starfish.startTime,d0
  1113.     lsr.w    #2,d0
  1114.     addi.w    #$200,d0
  1115.     move.w    d0,Starfish.oldRot
  1116. .rot_calced:
  1117.     bsr.w    Starfish.update
  1118.  
  1119.     IFNE    1
  1120. ; Restore shadow..
  1121.     movea.l    Starfish.backAdr,a0
  1122.     movea.l    Starfish.shadowAdrAdr+4,a1    ; a1: phys table adrs
  1123.     movea.l    (a1),a1                ; a1: current phys table
  1124.     bsr.l    Polygon.restoreShadows
  1125.     ELSE
  1126.     movea.l    scr,a0
  1127.     movea.l    Starfish.backAdr,a1
  1128.     bsr.l    COPY_PIC32020016
  1129.     ENDC
  1130.  
  1131. ;- end of parallel shit ----------------------------------------------------
  1132.  
  1133.     movea.l    Starfish.rectAddressTable,a0
  1134.     bsr.l    PrimitiveMesh.paint
  1135.  
  1136.     lea    Starfish.rectAddressTable,a0
  1137.      move.l    (a0)+,d0
  1138.     move.l    (a0)+,d1
  1139.     move.l    (a0),-(a0)
  1140.     move.l    d0,4(a0)
  1141.     move.l    d1,-(a0)
  1142.  
  1143. ;= shadow swapping =
  1144.  
  1145.     movea.l    Starfish.shadowAdrAdr,a0
  1146.      move.l    (a0)+,d0
  1147.     move.l    (a0)+,d1
  1148.     move.l    (a0),-(a0)
  1149.     move.l    d0,4(a0)
  1150.     move.l    d1,-(a0)
  1151.  
  1152.     movea.l    Starfish.shadowAdrAdr+4,a0
  1153.      move.l    (a0)+,d0
  1154.     move.l    (a0)+,d1
  1155.     move.l    (a0),-(a0)
  1156.     move.l    d0,4(a0)
  1157.     move.l    d1,-(a0)
  1158.  
  1159.     move.w    .swapcount(pc),d0
  1160.     addq.w    #1,d0
  1161.     cmpi.w    #3,d0
  1162.     blt.s    .end_swapcount
  1163.  
  1164. ; Clear count and swap phys/log shadow tables..
  1165.     clr.w    d0
  1166.     lea    Starfish.shadowAdrAdr,a0
  1167.     move.l    (a0),d1
  1168.     move.l    4(a0),(a0)+
  1169.     move.l    d1,(a0)
  1170.  
  1171. .end_swapcount:
  1172.     move.w    d0,.swapcount
  1173.  
  1174. ;= end shadow swapping =
  1175.  
  1176.     rts
  1177.  
  1178. .swapcount:
  1179.     DC.W    0
  1180.  
  1181. Starfish.zoom:
  1182.     movea.l    scr,a0
  1183.     move.w    $04BC.w,d0
  1184.     sub.w    Starfish.zoomStart,d0
  1185.     cmpi.w    #$0100,d0
  1186.     bcs.s    .clipped
  1187.     move.w    #$0100,d0
  1188. .clipped:
  1189.     move.w    d0,d1
  1190.     move.w    d0,d2
  1191.     mulu.w    #80,d1                ; d1.l=x_offset<<8
  1192.     mulu.w    #50,d2                ; d2.l=y_offset<<8
  1193.     lsr.l    #8,d1                ; d1.l=x_offset
  1194.     lsr.l    #8,d2                ; d2.l=y_offset
  1195.     mulu.w    #320,d2
  1196.     add.l    d1,d2
  1197.     movea.l    Starfish.backAdr,a1
  1198.     lea    (a1,d2.l*2),a1
  1199.     movea.l    a1,a2                ; a2: src backup
  1200.     lsr.w    #1,d0
  1201.     move.w    #$0100,d1
  1202.     sub.w    d0,d1                ; d1.w=step (8:8)
  1203.     ext.l    d1
  1204.     lsl.l    #8,d1                ; d1.l=step (16:16)
  1205.     move.l    d1,d2                ; d2.l=step (16:16)
  1206.     clr.l    d3                ; d3.l=y_pos (16:16)
  1207.     swap    d1                ; d1.l=ssSS (16:16)
  1208.     move.w    #200-1,d7
  1209.  
  1210. .yloop:    moveq    #320/16-1,d6
  1211.     sub.l    d0,d0                ; Clear count and clear carry.
  1212.  
  1213. .xloop:
  1214.     REPT    16
  1215.     move.w    (a1,d0.w*2),(a0)+
  1216.     addx.l    d1,d0
  1217.     ENDR
  1218.     dbf    d6,.xloop
  1219.  
  1220.     add.l    d2,d3                ; d3.l=next y_pos (16:16)
  1221.     move.l    d3,d4
  1222.     swap    d4                ; d4.w=next y_pos (int)
  1223.     mulu.w    #320,d4                ; d4.l=next y_offset (int)
  1224.     lea    (a2,d4.l*2),a1            ; a1: next src line
  1225.     dbf    d7,.yloop
  1226.     
  1227.     rts
  1228.  
  1229. ;======= OBJECT DATA =======================================================
  1230.  
  1231.     DATA
  1232.  
  1233. Starfish.textureTable:
  1234.     DC.L    FlareGen.redBuffer
  1235.     DC.L    0
  1236.  
  1237. Starfish.rectAddressTable:
  1238.     DC.L    Starfish.rectangleTable
  1239.     DC.L    Starfish.rectangleTable2
  1240.     DC.L    Starfish.rectangleTable3
  1241.  
  1242. Starfish.fieldStrength:
  1243.     DC.W    $0080
  1244.  
  1245. ; Only works with 5 arms, 5 rings..
  1246. Starfish.fixArmAngleTable:
  1247.     INCBIN    ARMS.DAT            ; idiocy, but it works
  1248.  
  1249. Starfish.shadowAdrAdr:
  1250.     DC.L    Starfish.shadowAdr
  1251.     DC.L    Starfish.shadowAdr2
  1252.  
  1253. ;======= OBJECT RESERVES ===================================================
  1254.  
  1255.     BSS
  1256.  
  1257. Starfish.resRout:
  1258.     DS.L    1
  1259.  
  1260. Starfish.rectangleTable:
  1261.     DS.W    4*10
  1262. Starfish.rectangleTable2:
  1263.     DS.W    4*10
  1264. Starfish.rectangleTable3:
  1265.     DS.W    4*10
  1266.  
  1267. Starfish.startTime:
  1268.     DS.W    1
  1269. Starfish.falling:
  1270.     DS.W    1
  1271. Starfish.oldRot:
  1272.     DS.W    1
  1273. Starfish.zooming:
  1274.     DS.W    1
  1275. Starfish.zoomStart:
  1276.     DS.W    1
  1277.  
  1278. Starfish.objAdr:
  1279.     DS.L    1
  1280. Starfish.angleTableAdr:
  1281.     DS.L    1
  1282. Starfish.backAdr:
  1283.     DS.L    1
  1284.  
  1285. Starfish.shadowAdr:
  1286.     DS.L    3
  1287. Starfish.shadowAdr2:
  1288.     DS.L    3
  1289.