home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / OUT.ZIP / SOURCE.ZIP / SFLY_DSP.S < prev    next >
Text File  |  2004-01-14  |  93KB  |  4,619 lines

  1. ; CPU+DSP implementation of the Human Fly engine 2.1.
  2. ; New attempt at a more optimised shadow version.. succeeded.
  3. ;
  4. ; Ofcourse limited in terms of scene complexity, but handles this with
  5. ; various errorcodes.
  6. ;
  7. ; This is meant for >=68020 CPU and 56x01 DSP
  8.  
  9. ; TODO: repair bumpmap init you numbskull!
  10.  
  11.     INCLUDE    HFLYCORE.S            ; Include core routines.
  12.     TEXT
  13.     INCLUDE    H_FLYRPC.I
  14.  
  15. ;======= MACROS
  16.  
  17. sendLongToDsp:    MACRO
  18.     btst.b    #1,$ffffa202.w
  19.     beq.s    *-6
  20.     move.l    \1,$ffffa204.w
  21.     ENDM
  22.  
  23. receiveLongFromDsp:    MACRO
  24.     btst.b    #0,$ffffa202.w
  25.     beq.s    *-6
  26.     move.l    $ffffa204.w,\1
  27.     ENDM
  28.  
  29. sendWordToDsp:    MACRO
  30.     btst.b    #1,$ffffa202.w
  31.     beq.s    *-6
  32.     move.w    \1,$ffffa206.w
  33.     ENDM
  34.  
  35. receiveWordFromDsp:    MACRO
  36.     btst.b    #0,$ffffa202.w
  37.     beq.s    *-6
  38.     move.w    $ffffa206.w,\1
  39.     ENDM
  40.  
  41. ;======= HumanFly
  42.  
  43. ; Initialises global parts of the pipeline.
  44. ; PRE:
  45. ; Dsp must have bootstrap code installed!
  46. HumanFly.init:
  47. ; Requires Dsp.loadProgram function!
  48.     move.l    #(HumanFly.endP56-HumanFly.p56)/3,d0
  49.     lea    HumanFly.p56,a0
  50.     bra    Dsp.loadProgram
  51.  
  52. ;======= ObjectRegistry
  53.  
  54. ObjectRegistry.CAPACITY:    =    32
  55.  
  56. ; Adds a 3d-object to the registry and returns a handle.
  57. ; INPUT:
  58. ; d0.l=size of object (bytes)
  59. ; a0: address of 3d object
  60. ; OUTPUT:
  61. ; d0.w: >= 0: objecthandle, -1: error, not added!
  62. ObjectRegistry.set:
  63. ; Store handle->address stuff.
  64.     move.w    ObjectRegistry.numberOfHandles,d1
  65.     move.l    a0,(ObjectRegistry.table,d1.w*4)
  66.  
  67.     moveq    #RPC_REGISTER_OBJECT,d1
  68.     sendLongToDsp    d1
  69.  
  70. ; Now transfer our object to the dsp.
  71.     lsr.l    #1,d0
  72.     move.l    d0,d1
  73.     add.l    ObjectRegistry.size,d1
  74.     sendLongToDsp    d1            ; Send total size of reg..
  75.     tst.l    d0
  76.     ble.s    .error
  77.     receiveWordFromDsp    d3
  78.     tst.w    d3                ; Did the dsp accept?
  79.     bmi.s    .error
  80.     sendLongToDsp    d0            ; Send objectsize.
  81.     move.l    d1,ObjectRegistry.size
  82.     lea    $FFFFA202.w,a1
  83.     lea    $FFFFA204.w,a2
  84.     subq.w    #1,d0
  85.  
  86. .loop:    move.w    (a0)+,d1
  87.     ext.l    d1
  88.  
  89. .wait:    btst.b    #1,(a1)
  90.     beq.s    .wait
  91.     move.l    d1,(a2)
  92.     dbra    d0,.loop
  93.  
  94. .success:
  95.     addq.w    #1,ObjectRegistry.numberOfHandles
  96.     move.w    d3,d0
  97.     rts
  98. .error:    moveq    #-1,d0
  99.     rts
  100.  
  101. ; Clears the registry. All handles become invalid.
  102. ObjectRegistry.clear:
  103.     clr.l    ObjectRegistry.size
  104.     clr.w    ObjectRegistry.numberOfHandles
  105.     moveq    #RPC_CLEAR_REGISTRY,d0
  106.     sendLongToDsp    d0
  107.     rts
  108.  
  109. ; TODO: bugs out with replacement of texels.. why!?!?!?
  110. ; Replaces specified object's primitives/vertices/normals/texels.
  111. ; INPUT:
  112. ; d0.w=objecthandle
  113. ; d1.w=replacemode (%ptnv)
  114. ; d2.l=objectsize
  115. ; OUTPUT:
  116. ; d0.w =0:success, <0:error
  117. ObjectRegistry.replace:
  118. ; Check if handle is valid...
  119.     cmp.w    ObjectRegistry.numberOfHandles,d0
  120.     bge    .error
  121.  
  122.     andi.w    #%1111,d1
  123.     beq    .success
  124.  
  125.     move.l    d2,.size
  126.  
  127.     move.l    (ObjectRegistry.table,d0.w*4),a0    ; a0: object
  128.     movea.l    a0,a5
  129.  
  130.     move.w    (a0)+,d2                ; d2.w=#vertices+#normals
  131.     move.w    d2,d3
  132.     mulu.w    #Vertex.SIZE,d3
  133.     move.w    (a0)+,d4                ; d4.w=#normals
  134.     sub.w    d4,d2                    ; d2.w=#vertices
  135.     move.w    d2,d5
  136.     mulu.w    #Vertex.SIZE,d5
  137.     lea    (a0,d5.l),a1
  138.     lea    (a0,d3.l),a2
  139.     move.w    (a2)+,d5                ; d5.w=#texels
  140.     lea    (a2,d5.w*Vertex2d.SIZE),a3
  141. ; a0: vertextable
  142. ; a1: normaltable
  143. ; a2: texeltable
  144. ; a3: primitivelist
  145. ; a6: object
  146.  
  147. ; Call remote procedure on dsp.
  148.     moveq    #RPC_REPLACE_OBJECT,d3
  149.     sendLongToDsp    d3
  150.  
  151. ; Send objecthandle to dsp.
  152.     clr.l    d3
  153.     move.w    d0,d3
  154.     sendLongToDsp    d3
  155.  
  156. ; Send replacemode to dsp.
  157.     move.w    d1,d3
  158.     sendLongToDsp    d3
  159.  
  160.     lea    $FFFFA204.w,a6
  161.  
  162.     lsr.w    d1
  163.     bcc.s    .end_vertices
  164.     mulu.w    #Vertex.SIZE/2,d2
  165.     sendLongToDsp    d2
  166.     subq.w    #1,d2
  167.     bmi.s    .end_vertices
  168. .vertex_loop:
  169.     move.w    (a0)+,d0
  170.     ext.l    d0
  171.     move.l    d0,(a6)
  172.     dbra    d2,.vertex_loop
  173. .end_vertices:
  174.  
  175.     lsr.w    d1
  176.     bcc.s    .end_normals
  177.     mulu.w    #Vertex.SIZE/2,d4
  178.     sendLongToDsp    d4
  179.     subq.w    #1,d4
  180.     bmi.s    .end_normals
  181. .normal_loop:
  182.     move.w    (a1)+,d0
  183.     ext.l    d0
  184.     move.l    d0,(a6)
  185.     dbra    d4,.normal_loop
  186. .end_normals:
  187.  
  188.     lsr.w    d1
  189.     bcc.s    .end_texels
  190.     mulu.w    #Vertex2d.SIZE/2,d5
  191.     sendLongToDsp    d5
  192.     subq.w    #1,d5
  193.     bmi.s    .end_texels
  194. .texel_loop:
  195.     move.w    (a2)+,d0
  196.     ext.l    d0
  197.     move.l    d0,(a6)
  198.     dbra    d5,.texel_loop
  199. .end_texels:
  200.  
  201.     lsr.w    d1
  202.     bcc.s    .end_primitives
  203.     move.l    .size(pc),d2
  204.     sub.l    a3,d2
  205.     add.l    a5,d2
  206.     lsr.l    #1,d2
  207.     sendLongToDsp    d2
  208.     subq.w    #1,d2
  209.     bmi.s    .end_primitives
  210. .primitive_loop:
  211.     move.w    (a3)+,d0
  212.     ext.l    d0
  213.     move.l    d0,(a6)
  214.     dbra    d2,.primitive_loop
  215. .end_primitives:
  216.  
  217. .success:
  218.     moveq    #0,d0
  219.     rts
  220. .error:    moveq    #-1,d0
  221.     rts
  222.  
  223. .size:    DC.L    0
  224.  
  225. ;======= Matrix
  226.  
  227. ; Wiser to convert here, instead of dsp..
  228. ; INPUT:
  229. ; a0: quaternion
  230. Matrix.convertQuaternion:
  231.     moveq    #RPC_GENERATE_QUATMATRIX,d0
  232.     sendLongToDsp    d0
  233.  
  234.     moveq    #Quaternion.SIZE/2,d7
  235. .loop    move.w    (a0)+,d0
  236.     ext.l    d0
  237.     sendLongToDsp    d0
  238.     dbra    d7,.loop
  239.     rts
  240.  
  241. ; INPUT:
  242. ; d0.w: X rotation (a)
  243. ; d1.w: Y rotation (b)
  244. ; d2.w: Z rotation (c)
  245. Matrix.generate:
  246.     lea    $FFFFA204.w,a4
  247.     moveq    #RPC_GENERATE_ROTMATRIX,d7
  248.  
  249.     sendLongToDsp    d7
  250. ;    move.l    d7,(a4)
  251.  
  252.     move.w    #sintbllen-1,d3
  253.     and.w    d3,d0
  254.     and.w    d3,d1
  255.     and.w    d3,d2
  256.     lea    Matrix.sineTable,a2
  257.     Get_SinCos    a2,d2,d4,d5
  258.     Get_SinCos    a2,d1,d2,d3
  259.     Get_SinCos    a2,d0,d0,d1
  260.     lsl.l    #8,d0
  261.     lsl.l    #8,d1
  262.     lsl.l    #8,d2
  263.     lsl.l    #8,d3
  264.     lsl.l    #8,d4
  265.     lsl.l    #8,d5
  266.     sendLongToDsp    d0
  267.     sendLongToDsp    d1
  268.     IFNE    0
  269.     move.l    d2,(a4)
  270.     move.l    d3,(a4)
  271.     move.l    d4,(a4)
  272.     move.l    d5,(a4)
  273.     ELSE
  274.     sendLongToDsp    d2
  275.     sendLongToDsp    d3
  276.     sendLongToDsp    d4
  277.     sendLongToDsp    d5
  278.     ENDC
  279.     rts
  280.  
  281. ; Translate the matrix translation vector.
  282. ; INPUT:
  283. ; d0.w: X translation
  284. ; d1.w: Y translation
  285. ; d2.w: Z translation
  286. Matrix.translate:
  287.     lea    $FFFFA204.w,a4
  288.     moveq    #RPC_TRANSLATE_MATRIX,d7
  289.  
  290.     sendLongToDsp    d7
  291. ;    move.l    d7,(a4)
  292.  
  293.     ext.l    d0
  294.     ext.l    d1
  295.     ext.l    d2
  296.     IFNE    0
  297.     move.l    d0,(a4)
  298.     move.l    d1,(a4)
  299.     move.l    d2,(a4)
  300.     ELSE
  301.     sendLongToDsp    d0
  302.     sendLongToDsp    d1
  303.     sendLongToDsp    d2
  304.     ENDC
  305.     rts
  306.  
  307. ; Pushes a previously generated matrix on the stack.
  308. Matrix.push:
  309.     moveq    #RPC_PUSH_MATRIX,d0
  310.  
  311.     sendLongToDsp    d0
  312. ;    move.l    d0,$FFFFA204.w
  313.     rts
  314.  
  315. ; Pops the top matrix off the stack.
  316. Matrix.pop:
  317.     moveq    #RPC_POP_MATRIX,d0
  318.  
  319.     sendLongToDsp    d0
  320. ;    move.l    d0,$FFFFA204.w
  321.     rts
  322.  
  323. ;======= TransformObject
  324.  
  325. ; INPUT:
  326. ; d0.l: flags
  327. ; d1.w: original objecthandle
  328. ; Rotates & scales & translates object by it's matrix.
  329. TransformObject.transform:
  330.     lea    $FFFFA204.w,a4
  331.     moveq    #RPC_TRANSFORM_OBJECT,d7
  332.  
  333. ; Send transformation command to the dsp.
  334.     sendLongToDsp    d7
  335. ;    move.l    d7,(a4)
  336.  
  337.     ext.l    d1
  338.  
  339.     sendLongToDsp    d1
  340. ;    move.l    d1,(a4)
  341.     rts
  342.  
  343. ;======= Primitive
  344.  
  345. Primitive.PAINTMODE_ENABLED:    =    1
  346.  
  347. ; INPUT:
  348. ; a0: address of screenbuffer
  349. Primitive.setScreenbuffer:
  350.     move.l    a0,Primitive.screenadr
  351.     rts
  352.  
  353. ; Sets paintmode. This involves pixeltype, logic op, pixelskip. For
  354. ; discription of these, see paintmode equates.
  355. ; All primitives use the settings taken by this call.
  356. ; WARNING: this is dirty rotten and festering! Code generation city!
  357. ; Well, first problems arise with 040 prolly.
  358. ; todo: if all fails, fuck up 040 caches. A shitty job really, doesn't
  359. ; belong in a user-mode engine.
  360. ; Unfortunately a more tidy way would drasticly increase the amount of
  361. ; routines (about 120 more routs needed!!!!)
  362. ; INPUT:
  363. ; d0.w=pixeltype and logic op
  364. ; d1.w=pixelskip (number of bytes to progress each pixel)
  365. ; OUTPUT:
  366. ; d0.w: =0: success, <0: error
  367. Primitive.setPaintMode:
  368.     IFNE    Primitive.PAINTMODE_ENABLED
  369.     move.w    d0,d2
  370.     andi.w    #Primitive.LOGICMASK,d0
  371.     lsr.w    #Primitive.LOGICSHIFT,d0
  372.     andi.w    #Primitive.SIZEMASK,d2
  373. ; d0.w=logic, d1.w=pixelskip, d2.w=pixelsize
  374.  
  375.     move.w    d1,Primitive.skipBytes
  376.     move.w    d2,d3
  377.     addq.w    #1,d3
  378.     move.w    d3,Primitive.bytesPerPixel
  379.  
  380.     move.l    (Sprite.routTable,d0.w*4),Sprite.rout
  381.  
  382.     bsr    Polygon.setFlatShader
  383.     bsr    Polygon.setGouraudShader
  384.     bsr    Polygon.setOffsetMapper
  385.     bsr    Polygon.setPixelMapper
  386.  
  387. ; Lines still todo, but they're not of much practical use..
  388.     ENDC
  389.  
  390.     clr.l    d0                    ; return 'success'
  391.     rts
  392.  
  393. Polygon.setFlatShader:
  394. ; Move in pixel instruction for the flatshader.
  395.     lea    Polygon.flatPixelInstr,a0
  396.     move.l    (Polygon.flatRoutTable,d0.w*8),a2
  397.     move.l    (Polygon.flatRoutTable+4,d0.w*8),d3
  398.     move.w    d3,d4
  399.     mulu.w    d2,d4
  400.     adda.l    d4,a2
  401.     lsr.w    #1,d3
  402.     subq.w    #1,d3
  403.     cmpi.w    #1,d2
  404.     bne.s    .no_word
  405.     clr.w    d3                    ; word loop always small!
  406. .no_word:
  407. .pixinstr_loop:
  408.     move.w    (a2)+,(a0)+                ; pump move, or, add, whatever
  409.     dbra    d3,.pixinstr_loop
  410.     tst.w    d1
  411.     beq.s    .add_done
  412.     move.w    #$D3CA,(a0)+                ; Concatenate 'adda.l a2,a1'.
  413. .add_done:
  414.     lea    Polygon.flatTail,a1
  415.     move.w    (a1)+,(a0)+
  416.     addq    #2,a1
  417.     move.l    #Polygon.flatPixelInstr,d3
  418.     sub.l    a0,d3
  419.     move.w    d3,(a0)+                ; Kick in dbf offset.
  420.  
  421.     moveq    #Polygon.FLAT_TAILSIZE/2-3,d7
  422. .concat_tail_loop:
  423.     move.w    (a1)+,(a0)+
  424.     dbra    d7,.concat_tail_loop
  425.  
  426.     tst.w    d1
  427.     beq.s    .end_outer_dbf_adjust
  428.     subq.w    #2,-4(a0)                ; Adjust outer dbf for concatenated 'adda'!
  429. .end_outer_dbf_adjust:
  430.     rts
  431.  
  432. Polygon.setGouraudShader:
  433. ; Move in pixel instruction for the gouraudshader.
  434.     lea    Polygon.gouraudPixelInstr,a0
  435.     move.l    (Polygon.gouraudRoutTable,d0.w*8),a2
  436.     move.l    (Polygon.gouraudRoutTable+4,d0.w*8),d3
  437.     move.w    d3,d7
  438.     move.w    d3,d4
  439.     lsr.w    #1,d7
  440.     subq.w    #1,d7
  441.     mulu.w    d2,d3
  442.     adda.l    d3,a2
  443.     cmpi.w    #1,d2
  444.     bne.s    .no_word
  445.     moveq    #2,d7                    ; word loop always small!
  446.     tst.w    d0
  447.     bne.s    .no_move
  448.     subq.w    #1,d7
  449. .no_move:
  450. .no_word:
  451. ; Pump move, or, add, whatever.
  452. .pump_loop:
  453.     move.w    (a2)+,(a0)+
  454.     dbf    d7,.pump_loop
  455.  
  456.     tst.w    d1
  457.     beq.s    .add_done
  458.     move.w    #$D1CB,(a0)+                ; Concatenate 'adda.l a3,a0'.
  459. .add_done:
  460.     lea    Polygon.gouraudTail,a1
  461.     move.w    (a1)+,(a0)+                ; Kick 'addx.l'.
  462.     move.w    (a1)+,(a0)+                ; Kick 1st 'dbf d6,' word.
  463.     addq    #2,a1
  464.     move.w    d4,d3
  465.     neg.w    d3
  466.     subq.w    #4,d3
  467.     tst.w    d1
  468.     beq.s    .put_dbf_addy
  469.     subq.w    #2,d3
  470. .put_dbf_addy:
  471.     move.w    d3,(a0)+                ; Kick in dbf offset.
  472.  
  473.     moveq    #Polygon.GOURAUD_TAILSIZE/2-4,d7
  474. .concat_tail_loop:
  475.     move.w    (a1)+,(a0)+
  476.     dbra    d7,.concat_tail_loop
  477.  
  478. ; Store offsetdata for outer dbf.
  479.     subq    #4,a0                    ; a0: addy of dbf-data
  480.     move.l    #Polygon.gouraudYloop,d3
  481.     sub.l    a0,d3
  482.     move.w    d3,(a0)                    ; Store offset.
  483.     rts
  484.  
  485. Polygon.setOffsetMapper:
  486. ; Move in pixel instruction for the texturemapper.
  487.     lea    Polygon.offsetPixelInstr,a0
  488.     move.l    (Polygon.offsetRoutTable,d0.w*8),a2
  489.     move.l    (Polygon.offsetRoutTable+4,d0.w*8),d3
  490.     move.w    d3,d7
  491.     move.w    d3,d4
  492.     lsr.w    #1,d7
  493.     subq.w    #1,d7
  494.     mulu.w    d2,d3
  495.     adda.l    d3,a2
  496. ; Pump move, or, add, whatever.
  497. .pump_loop:
  498.     move.w    (a2)+,(a0)+
  499.     dbf    d7,.pump_loop
  500.  
  501.     tst.w    d1
  502.     beq.s    .add_done
  503.     move.w    #$D1CB,(a0)+                ; Concatenate 'adda.l a2,a1'.
  504. .add_done:
  505.     lea    Polygon.offsetTail,a1
  506.     move.w    (a1)+,(a0)+                ; Kick 2st word of 'dbf d6,'.
  507.     addq    #2,a1
  508.     move.w    d4,d3
  509.     neg.w    d3
  510.     subq.w    #4,d3
  511.     tst.w    d1
  512.     beq.s    .put_dbf_addy
  513.     subq.w    #2,d3
  514. .put_dbf_addy:
  515.     move.w    d3,(a0)+                ; Kick in dbf offset.
  516.  
  517.     moveq    #Polygon.OFFSET_TAILSIZE/2-3,d7
  518. .concat_tail_loop:
  519.     move.w    (a1)+,(a0)+
  520.     dbra    d7,.concat_tail_loop
  521.  
  522. ; Store offsetdata for outer dbf.
  523.     subq    #4,a0                    ; a0: addy of dbf-data
  524.     move.l    a0,d3
  525.     move.l    #Polygon.offsetYloop,d3
  526.     sub.l    a0,d3
  527.     move.w    d3,(a0)                    ; Store offset.
  528.     rts
  529.  
  530. ; Note: this bitch only makes word-based pixelloops, due to optimisations.
  531. ; Also no pixelskipping is implemented. For a more complete but slower
  532. ; texturemapper, try the offset version.
  533. Polygon.setPixelMapper:
  534. ; Move in pixel instruction for the texturemapper.
  535.     lea    Polygon.texturePixelInstr,a0
  536.     move.l    (Polygon.textureRoutTable,d0.w*8),a2
  537.     movea.l    a2,a3
  538.     move.l    (Polygon.textureRoutTable+4,d0.w*8),d3
  539.     move.w    d3,d6
  540.     move.w    d3,d4
  541.     lsr.w    #1,d6
  542.     subq.w    #1,d6
  543.     move.w    d6,d5
  544.     moveq    #1<<CHUNKLOG-1,d7
  545.  
  546. ; Unroll pixeloop 2^CHUNKLOG times. This is nice and fast.
  547. .instr_loop:
  548. ; Pump move, or, add, whatever.
  549. .pump_loop:
  550.     move.w    (a2)+,(a0)+
  551.     dbf    d6,.pump_loop
  552.  
  553.     move.w    d5,d6
  554.     movea.l    a3,a2
  555.     dbf    d7,.instr_loop
  556.  
  557. ; Create load jumptree instruction. Store the address data.
  558.     move.l    a0,Polygon.textureLoadInstr+2        ; 'lea jumptree,a2'
  559.  
  560. ; Calc and store size for jump instruction {*1,*2,*4,*8}.
  561.     move.w    Polygon.textureJmpInstr+2,d5
  562.     andi.w    #%1111100111111111,d5
  563.     lsl.w    #8,d3
  564.     or.w    d3,d5
  565.     move.w    d5,Polygon.textureJmpInstr+2
  566.  
  567. ; Now kick in the dbf toghether with calculated offset data.
  568.     lea    Polygon.textureTail,a1
  569.     move.w    (a1)+,(a0)+                ; Kick 2st word of 'dbf d6,'.
  570.     addq    #2,a1
  571.     move.l    #Polygon.texturePixelInstr,d3
  572.     sub.l    a0,d3
  573.     move.w    d3,(a0)+                ; Kick in dbf offset.
  574.  
  575.     moveq    #Polygon.TEXTURE_TAILSIZE/2-3,d7
  576. .concat_tail_loop:
  577.     move.w    (a1)+,(a0)+
  578.     dbra    d7,.concat_tail_loop
  579.  
  580. ; Store offsetdata for outer dbf.
  581.     subq    #4,a0                    ; a0: addy of dbf-data
  582.     move.l    a0,d3
  583.     move.l    #Polygon.textureYloop,d3
  584.     sub.l    a0,d3
  585.     move.w    d3,(a0)                    ; Store offset.
  586.     rts
  587.  
  588. ;======= Viewport
  589.  
  590. Viewport.MAX_X:        =    320        ; maximum x dimension
  591. Viewport.MAX_Y:        =    200        ; maximum y dimension
  592.  
  593. ; Updates the viewport settings to the dsp.
  594. ; USES: Viewport.settingsTable
  595. Viewport.update:
  596.     lea    Viewport.settingsTable,a0
  597.     moveq    #RPC_UPDATE_VIEWPORT,d0
  598.     sendLongToDsp    d0
  599.     moveq    #Viewport.SIZE/2-1,d7
  600.  
  601. .loop:    move.w    (a0)+,d0
  602.     ext.l    d0
  603.     sendLongToDsp    d0
  604.     dbra    d7,.loop
  605.     rts
  606.  
  607. ; INPUT: d0.w: left x
  608. ;        d1.w: upper y
  609. ;        d6.w: right x
  610. ;        d7.w: lower y
  611. ;        d4.l: color (2 words)
  612. Viewport.paintRectangle:
  613.     movea.l    Primitive.screenadr,a0
  614.     lea    Viewport.settingsTable,a1
  615.     move.w    d6,d2
  616.  
  617.     cmp.w    Viewport.XSTART(a1),d0
  618.     bpl.s    .testx0
  619.     move.w    Viewport.XSTART(a1),d0
  620. .testx0:
  621.     cmp.w    Viewport.XEND(a1),d0
  622.     blt.s    .endtestx0
  623.     move.w    Viewport.XEND(a1),d0
  624.     subq.w    #1,d0
  625. .endtestx0:
  626.  
  627.     cmp.w    Viewport.YSTART(a1),d1
  628.     bpl.s    .testy0
  629.     move.w    Viewport.YSTART(a1),d1
  630. .testy0:
  631.     cmp.w    Viewport.YEND(a1),d1
  632.     blt.s    .endtesty0
  633.     move.w    Viewport.YEND(a1),d1
  634.     subq.w    #1,d1
  635. .endtesty0:
  636.  
  637.     cmp.w    Viewport.XSTART(a1),d6
  638.     bpl.s    .testx1
  639.     move.w    Viewport.XSTART(a1),d6
  640. .testx1:
  641.     cmp.w    Viewport.XEND(a1),d6
  642.     blt.s    .endtestx1
  643.     move.w    Viewport.XEND(a1),d6
  644.     move.w    d6,d2
  645.     subq.w    #1,d6
  646. .endtestx1:
  647.  
  648.     cmp.w    Viewport.YSTART(a1),d7
  649.     bpl.s    .testy1
  650.     move.w    Viewport.YSTART(a1),d7
  651. .testy1:
  652.     cmp.w    Viewport.YEND(a1),d7
  653.     blt.s    .endtesty1
  654.     move.w    Viewport.YEND(a1),d7
  655.     subq.w    #1,d7
  656. .endtesty1:
  657.  
  658.     move.w    d7,d3
  659. ;    andi.w    #$FFFE,d2            ; longeven startaddy! todo: make correct.
  660.     adda.w    d2,a0
  661.     adda.w    d2,a0
  662.     move.w    Viewport.XSCREEN(a1),d5
  663.     add.w    d5,d5
  664.     movea.w    d5,a4
  665.     mulu.w    d5,d3
  666.     adda.l    d3,a0
  667. ; w=r-l+1, ceil(w/2)=(w+1)/2=(r-l+2)/2
  668.     sub.w    d0,d6                ; d6.w=r-l
  669.     addq.w    #2,d6                ; d6.w=r-l+2
  670.     lsr.w    d6                ; d6.w=(r-l+2)/2=ceil(w/2)
  671.     sub.w    d1,d7
  672.     move.l    d4,d0
  673.     move.l    d4,d1
  674.     move.l    d4,d2
  675.     move.l    d4,d3
  676.     movea.l    d4,a1
  677.     movea.l    d4,a2
  678.     movea.l    d4,a3
  679.     move.w    d6,d5
  680.     add.w    d6,d5
  681.     add.w    d5,d5
  682.     suba.w    d5,a4
  683.     ext.l    d6
  684.     move.l    d6,d5
  685.     andi.w    #$0007,d6
  686.     lsr.w    #3,d5
  687.     neg.l    d5
  688.     neg.l    d6
  689.     lea    (.endchunks.w,pc,d5.l*4),a5
  690.     lea    (.endpix.w,pc,d6.l*2),a6
  691.  
  692. .yloop:    jmp    (a5)
  693.     REPT    Viewport.MAX_X/16
  694.     movem.l    d0-d4/a1-a3,-(a0)
  695.     ENDR
  696. .endchunks:
  697.     jmp    (a6)
  698.     REPT    7
  699.     move.l    d0,-(a0)
  700.     ENDR
  701. .endpix:
  702.  
  703.     suba.l    a4,a0
  704.     dbf    d7,.yloop
  705.     rts
  706.  
  707. ; todo: optimise!
  708. ; INPUT:
  709. ; d0.w: left x
  710. ; d1.w: upper y
  711. ; d6.w: right x
  712. ; d7.w: lower y
  713. ; a1: background (same dimensions as screen)
  714. Viewport.copyRectangle:
  715.     movea.l    Primitive.screenadr,a0
  716.     lea    Viewport.settingsTable,a2
  717.     move.w    d6,d2
  718.  
  719.     cmp.w    Viewport.XSTART(a2),d0
  720.     bpl.s    .testx0
  721.     move.w    Viewport.XSTART(a2),d0
  722. .testx0:
  723.     cmp.w    Viewport.XEND(a2),d0
  724.     blt.s    .endtestx0
  725.     move.w    Viewport.XEND(a2),d0
  726.     subq.w    #1,d0
  727. .endtestx0:
  728.  
  729.     cmp.w    Viewport.YSTART(a2),d1
  730.     bpl.s    .testy0
  731.     move.w    Viewport.YSTART(a2),d1
  732. .testy0:
  733.     cmp.w    Viewport.YEND(a2),d1
  734.     blt.s    .endtesty0
  735.     move.w    Viewport.YEND(a2),d1
  736.     subq.w    #1,d1
  737. .endtesty0:
  738.  
  739.     cmp.w    Viewport.XSTART(a2),d6
  740.     bpl.s    .testx1
  741.     move.w    Viewport.XSTART(a2),d6
  742. .testx1:
  743.     cmp.w    Viewport.XEND(a2),d6
  744.     blt.s    .endtestx1
  745.     move.w    Viewport.XEND(a2),d6
  746.     move.w    d6,d2
  747.     subq.w    #1,d6
  748. .endtestx1:
  749.  
  750.     cmp.w    Viewport.YSTART(a2),d7
  751.     bpl.s    .testy1
  752.     move.w    Viewport.YSTART(a2),d7
  753. .testy1:
  754.     cmp.w    Viewport.YEND(a2),d7
  755.     blt.s    .endtesty1
  756.     move.w    Viewport.YEND(a2),d7
  757.     subq.w    #1,d7
  758. .endtesty1:
  759.  
  760.     move.w    d7,d3
  761. ;    andi.w    #$FFFE,d2            ; longeven startaddy! todo: make correct.
  762.     adda.w    d2,a0
  763.     adda.w    d2,a0
  764.     adda.w    d2,a1
  765.     adda.w    d2,a1
  766.     move.w    Viewport.XSCREEN(a2),d5
  767.     add.w    d5,d5
  768.     movea.w    d5,a4
  769.     mulu.w    d5,d3
  770.     adda.l    d3,a0
  771.     adda.l    d3,a1
  772. ; w=r-l+1, ceil(w/2)=(w+1)/2=(r-l+2)/2
  773.     sub.w    d0,d6                ; d6.w=r-l
  774.     addq.w    #2,d6                ; d6.w=r-l+2
  775.     lsr.w    d6                ; d6.w=(r-l+2)/2=ceil(w/2)
  776.     move.w    d6,d5
  777.     add.w    d6,d5
  778.     add.w    d5,d5
  779.     suba.w    d5,a4
  780.     sub.w    d1,d7
  781.     subq.w    #1,d6
  782.     bmi.s    .end
  783.     move.w    d6,d5
  784.  
  785. .yloop:
  786.  
  787. .xloop:    move.l    -(a1),-(a0)
  788.     dbf    d6,.xloop
  789.  
  790.     move.w    d5,d6
  791.     suba.l    a4,a0
  792.     suba.l    a4,a1
  793.     dbf    d7,.yloop
  794. .end:    rts
  795.  
  796. ;======= PrimitiveMesh
  797.  
  798. ; Marks the PrimitiveMesh as ready to roll.
  799. PrimitiveMesh.new:
  800. ; Inform the dsp.
  801.     moveq    #RPC_NEW_PRIMITIVEMESH,d0
  802.     sendLongToDsp    d0
  803.  
  804. ; Disable shadow handling.
  805.     clr.l    d0
  806.     move.w    d0,PrimitiveMesh.shadowsOn
  807.     sendLongToDsp    d0
  808.     rts
  809.  
  810. ; Marks the PrimitiveMesh as ready to roll.
  811. ; INPUT:
  812. ; a0: shadow polygon buffer
  813. PrimitiveMesh.newShadowed:
  814.     moveq    #RPC_NEW_PRIMITIVEMESH,d0
  815.     sendLongToDsp    d0
  816.  
  817. ; Enable shadow handling.
  818.     moveq    #1,d0
  819.     move.w    d0,PrimitiveMesh.shadowsOn
  820.     sendLongToDsp    d0
  821.     move.l    a0,PrimitiveMesh.shadowStartAdr
  822.     clr.w    (a0)+                    ; Clear counter.
  823.     move.l    a0,PrimitiveMesh.shadowAdr
  824.     rts
  825.  
  826. ; Sort the elements.
  827. PrimitiveMesh.sortZ:
  828.     moveq    #RPC_SORT_PRIMITIVEMESH,d0
  829.     sendLongToDsp    d0
  830.     rts
  831.  
  832. ; Indicate the mesh is ready for painting.
  833. PrimitiveMesh.complete:
  834. ; Give the command..
  835.     moveq    #RPC_PAINT_PRIMITIVES,d0
  836.     sendLongToDsp    d0
  837.     rts
  838.  
  839. ; INPUT:
  840. ; a0: storage for bounding rectangles
  841. PrimitiveMesh.paint:
  842.     move.l    a0,-(sp)
  843.  
  844. ; Now wait for a reply and paint them primitives.
  845. .loop:    receiveWordFromDsp    d0        ; d0=shadetype
  846.     bmi.s    .end_paint            ; d0<0 ? terminate!
  847.     jsr    .jumpTable(pc,d0.w*4)
  848.     bra.s    .loop
  849. .end_paint:
  850.  
  851. ; Killer! Now we receive all bounding rectangles in the scene.
  852.     movea.l    (sp)+,a0
  853.     receiveWordFromDsp    d7
  854.     move.w    d7,(a0)+
  855.     beq.s    .end
  856.     lsl.w    #2,d7                ; rectanglecount*words/rectangle = total words
  857.     subq.w    #1,d7
  858. .rect_loop:
  859.     receiveWordFromDsp    (a0)+
  860.     dbra    d7,.rect_loop
  861.  
  862. .end:    rts
  863.  
  864. .jumpTable:
  865.     bra.w    Polygon.paintDspFlatshaded
  866.     bra.w    Polygon.paintFastGouraudshaded
  867.     bra.w    Polygon.paintDspTexturemapped
  868.     bra.w    Polygon.paintDspAlphatextured
  869.     bra.w    Polygon.paintDspBumpmapped
  870.     bra.w    Sprite.paintReceived
  871.     bra.w    Line.paintReceived
  872.  
  873. ;======= Polygon
  874.  
  875. Polygon.MAX_TEXTURES:        =    32
  876.  
  877. Polygon.OFFSET_TEXTURING:    =    0
  878. Polygon.PIXEL_TEXTURING:    =    1
  879. Polygon.ALPHA_TEXTURING:    =    2
  880. Polygon.BUMP_TEXTURING:        =    3
  881. Polygon.FLAT_SHADING:        =    4
  882. Polygon.GOURAUD_SHADING:    =    5
  883.  
  884. ; Initializes polygonpainter lookup tables.
  885. ; INPUT:
  886. ; a0: texture-address-table
  887. ; a1: gouraud-tables
  888. ; OUTPUT:
  889. ; d0.l: 0=ok, -1=error
  890. Polygon.init:
  891.     move.l    a1,Polygon.coloradr
  892.  
  893.     bsr.w    Polygon.copyTextureTable
  894.  
  895.     tst.w    .mix_initialized(pc)
  896.     bne.s    .done_mixing
  897.     bsr.w    Primitive.initMsbMixTable
  898.     bsr.w    Primitive.initLsbMixTable
  899.     move.w    #1,.mix_initialized
  900. .done_mixing:
  901.  
  902.     bsr.w    Polygon.deregisterBumpmaps
  903.  
  904.     bsr.w    Polygon.parseTextureTable
  905.  
  906.     move.w    d0,-(sp)
  907.     bsr.w    Polygon.calcInvTable
  908.     move.w    (sp)+,d0
  909.  
  910.     bsr.s    Polygon.setTextureMode
  911.  
  912. .success:
  913.     moveq    #0,d0
  914.     rts
  915. .error:    moveq    #-1,d0
  916.     rts
  917.  
  918. .mix_initialized:
  919.     DC.W    0
  920.  
  921. ; Copies specified texturetable to internal table.
  922. Polygon.copyTextureTable:
  923.     lea    Polygon.textureTable,a1
  924.     moveq    #Polygon.MAX_TEXTURES-1,d7
  925. .loop:    move.l    (a0)+,(a1)+
  926.     dbeq    d7,.loop
  927.     rts
  928.  
  929. ; INPUT:
  930. ; d0.w=texturemode
  931. Polygon.setTextureMode:
  932.     move.w    d0,Polygon.texturemode
  933.  
  934.     cmpi.w    #Polygon.PIXEL_TEXTURING,d0
  935.     beq.s    .end
  936.  
  937. .offset:cmpi.w    #Polygon.OFFSET_TEXTURING,d0
  938.     bne.s    .end
  939. ; Set the dsp to sending back offsets.
  940.     moveq    #RPC_SET_OFFSETPIXEL,d0
  941.     sendLongToDsp    d0
  942.  
  943. .end:    rts
  944.  
  945. ; Parses a table containing APX block textures and resets all addresses
  946. ; to point to the start of the pixeldata. Also installs all texturebuffers.
  947. ; PRECONDITIONS:
  948. ; The texturetable points to APX blocks.
  949. ; The texturetable is null-terminated.
  950. ; The texturetable does not contain over 16 highcolor and 8bpp textures.
  951. ; OUTPUT:
  952. ; d0.w=(Polygon.PIXEL_TEXTURING, Polygon.OFFSET_TEXTURING)
  953. Polygon.parseTextureTable:
  954.     lea    Polygon.textureTable,a0
  955.  
  956. ; Get all textureaddresses and split them in the 8bpp and highcolor
  957. ; catagories.
  958. .catagorization:
  959.     clr.l    d1
  960.     clr.l    d2
  961.     clr.l    d3                ; d3.l= #pixels (8bit)
  962.     clr.l    d4                ; d4.l= #pixels (16bit)
  963.     lea    .wordTextureTable,a4
  964.     lea    .byteTextureTable,a5
  965.  
  966. .storeloop:
  967.     movea.l    (a0)+,a1
  968.     tst.l    a1
  969.     beq.s    .end_catagorization
  970.     movem.w    12(a1),d6/d7            ; d6.w=width, d7.w=height
  971.     mulu.w    d6,d7                ; d7.l=#pixels
  972.     move.l    (a1),d0
  973. .test_byte_per_pixel:
  974.     cmpi.l    #"Byte",d0
  975.     bne.s    .end_test_byte_per_pixel
  976.     add.l    d7,d3
  977.     addq.w    #1,d2
  978.     move.l    a1,(a5)+            ; Store 8bpp texture.
  979.     lea    788(a1),a1
  980. .end_test_byte_per_pixel:
  981. .test_word_per_pixel:
  982.     cmpi.l    #"Word",d0
  983.     bne.s    .end_test_word_per_pixel
  984.     add.l    d7,d4
  985.     addq.w    #1,d1
  986.     move.l    a1,(a4)+            ; Store highcolor texture.
  987.     lea    20(a1),a1
  988. .end_test_word_per_pixel:
  989.     move.l    a1,-4(a0)
  990. .dont_send:
  991.     bra.s    .storeloop
  992. .end_catagorization:
  993.  
  994. ; d1.w= number of highcolor textures
  995. ; d2.w= number of 8bpp textures
  996. ; d3.l= total 16bit pixels
  997. ; d4.l= total 8bit pixels
  998. ; If either the amount of 16bit or 8bit textures exceeds 2, use offsetmode.
  999.     cmpi.w    #2,d1
  1000.     bgt    .init_offset_mode
  1001.     cmpi.w    #2,d2
  1002.     bgt    .init_offset_mode
  1003. ; If either the amount of 16bit or 8bit pixels exceeds 8192, use offsetmode.
  1004.     cmpi.l    #8192,d3
  1005.     bgt    .init_offset_mode
  1006.     cmpi.l    #8192,d4
  1007.     bgt    .init_offset_mode
  1008.  
  1009. ; Put all the textures toghether in a piece of texturecache.
  1010. ; First the 16bit ones....
  1011. .cache_16bit:
  1012.     lea    Polygon.textureCache,a0
  1013.     lea    .wordTextureTable,a4
  1014.     subq.w    #1,d1
  1015.     bmi.s    .end_cache_16bit
  1016. .cache16bit_loop:
  1017.     movea.l    (a4)+,a1
  1018.     movem.w    12(a1),d6/d7
  1019.     lea    20(a1),a1
  1020.     mulu.w    d6,d7
  1021.     subq.w    #1,d7
  1022.  
  1023. .pixel16bitloop:
  1024.     addq    #1,a0
  1025.     move.w    (a1)+,(a0)+
  1026.     dbra    d7,.pixel16bitloop
  1027.  
  1028.     dbra    d1,.cache16bit_loop
  1029. .end_cache_16bit:
  1030.  
  1031. ; Then the 8bit ones....
  1032. .cache_8bit:
  1033.     lea    Polygon.textureCache,a0
  1034.     lea    .byteTextureTable,a4
  1035.     subq.w    #1,d2
  1036.     bmi.s    .end_cache_8bit
  1037. .cache8bit_loop:
  1038.     movea.l    (a4)+,a1
  1039.     movem.w    12(a1),d6/d7
  1040.     lea    788(a1),a1
  1041.     mulu.w    d6,d7
  1042.     subq.w    #1,d7
  1043.  
  1044. .pixel8bitloop:
  1045.     move.b    (a1)+,(a0)+
  1046.     addq    #2,a0
  1047.     dbra    d7,.pixel8bitloop
  1048.  
  1049.     dbra    d2,.cache8bit_loop
  1050. .end_cache_8bit:
  1051.  
  1052. ; Pump the texturecache over to the dsp.
  1053.     moveq    #RPC_STORE_TEXTURE,d7
  1054.     sendLongToDsp    d7
  1055.     lea    Polygon.textureCache,a1
  1056.     move.w    #8192-1,d7
  1057. .sendloop:
  1058.     move.b    (a1)+,d0
  1059.     swap    d0
  1060.     move.w    (a1)+,d0
  1061.     sendLongToDsp    d0
  1062.     dbra    d7,.sendloop
  1063.  
  1064.     move.w    #Polygon.PIXEL_TEXTURING,d0
  1065. .end:    rts
  1066.  
  1067. .init_offset_mode:
  1068.     move.w    #Polygon.OFFSET_TEXTURING,d0
  1069.     rts
  1070.  
  1071. ; These store all textureaddresses found.
  1072. .wordTextureTable:
  1073.     DS.L    16
  1074. .byteTextureTable:
  1075.     DS.L    16
  1076.  
  1077. Polygon.calcInvTable:
  1078.     lea    Polygon.invTable,a0
  1079.     move.l    #$80000000,d1
  1080.     moveq    #2,d0
  1081.     move.l    d1,d2
  1082.     swap    d2
  1083.     move.w    #$7fff,(a0)+
  1084.     move.w    #$7fff,(a0)+
  1085.  
  1086. .posloop:
  1087.     move.l    d1,d2
  1088.     divu.l    d0,d2
  1089.     swap    d2
  1090.     move.w    d2,(a0)+
  1091.     addq.w    #1,d0
  1092.     cmpi.w    #Viewport.MAX_Y+1,d0
  1093.     blt.s    .posloop
  1094.  
  1095.     rts
  1096.  
  1097. ; Calculates a 64K highcolor-word lookup table from two 256 truecolor
  1098. ; palettes.
  1099. ; INPUT: d7.w: start intensity of palette1
  1100. ;        a0: highcolor lookuptable
  1101. ;        a1: truecolor palette1
  1102. ;        a2: truecolor palette2 (256 entries)
  1103. ;        a5: number of entries in palette1
  1104. Polygon.calcMixtable:
  1105.     movea.l    #$0000ffff,a6
  1106.  
  1107. .palloop:
  1108.     moveq    #0,d0
  1109.     moveq    #0,d1
  1110.     moveq    #0,d2
  1111.     move.b    (a1)+,d0
  1112.     move.b    (a1)+,d1
  1113.     move.b    (a1)+,d2
  1114.     muls.w    d7,d0
  1115.     muls.w    d7,d1
  1116.     muls.w    d7,d2
  1117.     lsl.l    #1,d0
  1118.     lsl.l    #1,d1
  1119.     lsl.l    #1,d2
  1120.     moveq    #0,d6
  1121.  
  1122. .colorloop:
  1123.     moveq    #0,d3
  1124.     moveq    #0,d4
  1125.     moveq    #0,d5
  1126.     move.b    (a2)+,d3
  1127.     move.b    (a2)+,d4
  1128.     move.b    (a2)+,d5
  1129.     mulu.w    d6,d3
  1130.     mulu.w    d6,d4
  1131.     mulu.w    d6,d5
  1132.     add.l    d0,d3
  1133.     bpl.s    .red1_ok
  1134.     moveq    #0,d3
  1135.     bra.s    .red_ok
  1136. .red1_ok:
  1137.     cmp.l    a6,d3
  1138.     blt.s    .red_ok
  1139.     move.w    a6,d3
  1140. .red_ok:
  1141.     add.l    d1,d4
  1142.     bpl.s    .green1_ok
  1143.     moveq    #0,d4
  1144.     bra.s    .green_ok
  1145. .green1_ok:
  1146.     cmp.l    a6,d4
  1147.     blt.s    .green_ok
  1148.     move.w    a6,d4
  1149. .green_ok:
  1150.     add.l    d2,d5
  1151.     bpl.s    .blue1_ok
  1152.     moveq    #0,d5
  1153.     bra.s    .blue_ok
  1154. .blue1_ok:
  1155.     cmp.l    a6,d5
  1156.     blt.s    .blue_ok
  1157.     move.w    a6,d5
  1158. .blue_ok:
  1159.     andi.w    #%1111100000000000,d3
  1160.     lsr.w    #5,d4
  1161.     andi.w    #%0000011111100000,d4
  1162.     lsr.w    #8,d5
  1163.     lsr.w    #3,d5
  1164.     or.w    d4,d3
  1165.     or.w    d5,d3
  1166.     move.w    d3,(a0)+
  1167.     addq.b    #1,d6
  1168.     bne.s    .colorloop
  1169.  
  1170.     lea    -256*3(a2),a2
  1171.     addq.w    #1,d7
  1172.     cmp.w    a5,d7
  1173.     blt.s    .palloop
  1174.  
  1175.     rts
  1176.  
  1177. ; Cuts bumpoffsets down to 12bits (0yyyyy0xxxxx).
  1178. ; Converts a heightfield (8bpp) into a bumpmap (16bit).
  1179. ; INPUT:
  1180. ; a0: source APX heightmap (words)
  1181. Polygon.registerBumpmap:
  1182.     bsr    Polygon.addBumpmap
  1183.     movem.w    12(a0),d4/d7
  1184.     lea    20(a0),a0
  1185.     subq.w    #1,d7
  1186.  
  1187. .yloop:    move.w    d4,d6
  1188.     subq.w    #1,d6
  1189.  
  1190. .xloop:    moveq    #0,d0
  1191.     move.b    (a0),d0
  1192.     move.b    1(a0),d1
  1193.     lsr.b    #3,d0
  1194.     lsr.b    #3,d1
  1195.     lsl.w    #6,d0
  1196.     or.w    d1,d0
  1197.     move.w    d0,(a0)+
  1198.     dbra    d6,.xloop
  1199.  
  1200.     dbra    d7,.yloop
  1201.     rts
  1202.  
  1203. Polygon.deregisterBumpmaps:
  1204.     clr.w    Polygon.bumpmapTable
  1205.     rts
  1206.  
  1207. ; INPUT:
  1208. ; a0: bumpmap to add
  1209. Polygon.addBumpmap:
  1210.     lea    Polygon.bumpmapTable,a1
  1211.     move.w    (a1)+,d7
  1212.     move.l    a0,(a1,d7.w*4)
  1213.     addq.w    #1,-(a1)
  1214.     rts
  1215.  
  1216. ; INPUT:
  1217. ; a0: address of potential bumpmap (APX)
  1218. ; OUTPUT:
  1219. ; d0.l= 1: yes, 0: no
  1220. Polygon.isBumpmap:
  1221.     lea    Polygon.bumpmapTable,a1
  1222.     move.w    (a1)+,d7
  1223.     subq.w    #1,d7
  1224.     bmi.s    .no_match
  1225.  
  1226. .loop:    cmpa.l    (a1)+,a0
  1227.     beq.s    .match
  1228.     dbra    d7,.loop
  1229. .no_match:
  1230.     moveq    #0,d0
  1231.     rts
  1232. .match:    moveq    #1,d0                ; You've been elected bumpmap of the day!
  1233.     rts
  1234.  
  1235. Polygon.flatRoutTable:
  1236.     DC.L    Polygon.pixelFlatMoved,2
  1237.     DC.L    Polygon.pixelFlatOrred,2
  1238.     DC.L    Polygon.pixelFlatAdded,2
  1239.     DC.L    Polygon.pixelFlatceilAdded,10
  1240. Polygon.gouraudRoutTable:
  1241.     DC.L    Polygon.pixelGouraudMoved,4
  1242.     DC.L    Polygon.pixelGouraudOrred,6
  1243.     DC.L    Polygon.pixelGouraudAdded,6
  1244.     DC.L    Polygon.pixelGouraudceilAdded,12
  1245. Polygon.offsetRoutTable:
  1246.     DC.L    Polygon.pixelOffsetMoved,4
  1247.     DC.L    Polygon.pixelOffsetOrred,6
  1248.     DC.L    Polygon.pixelOffsetAdded,6
  1249.     DC.L    Polygon.pixelOffsetceilAdded,2
  1250. Polygon.textureRoutTable:
  1251.     DC.L    Polygon.pixelTextureMoved,2
  1252.     DC.L    Polygon.pixelTextureOrred,4
  1253.     DC.L    Polygon.pixelTextureAdded,4
  1254.     DC.L    Polygon.pixelTextureceilAdded,2
  1255.     IFNE    0
  1256. Polygon.bumpRoutTable:
  1257.     DC.L    Polygon.pixelBumpMoved
  1258.     DC.L    Polygon.pixelBumpOrred
  1259.     DC.L    Polygon.pixelBumpAdded
  1260.     DC.L    Polygon.pixelBumpceilAdded
  1261. Polygon.alphaRoutTable:
  1262.     DC.L    Polygon.pixelAlphaMoved
  1263.     DC.L    Polygon.pixelAlphaOrred
  1264.     DC.L    Polygon.pixelAlphaAdded
  1265.     DC.L    Polygon.pixelAlphaceilAdded
  1266.     ENDC
  1267.  
  1268. Polygon.pixelFlatMoved:
  1269.     move.b    d4,(a1)+
  1270.     move.w    d4,(a1)+
  1271.  
  1272. Polygon.pixelFlatOrred:
  1273.     or.b    d4,(a1)+
  1274.     or.w    d4,(a1)+
  1275.  
  1276. Polygon.pixelFlatAdded:
  1277.     add.b    d4,(a1)+
  1278.     add.w    d4,(a1)+
  1279.  
  1280. Polygon.pixelFlatceilAdded:
  1281.     move.b    (a1),d3
  1282.     add.b    d4,d3
  1283.     scs    d2
  1284.     or.b    d2,d4
  1285.     move.b    d4,(a1)+
  1286.     move.w    d4,(a1)+
  1287.  
  1288. Polygon.flatTail:
  1289.     dbra    d6,*-2
  1290.  
  1291.     adda.l    a5,a0
  1292.     add.l    d2,d0
  1293.     add.l    d3,d1
  1294.     DC.W    $51CF,$FFD4            ; dbra    d7,.yloop
  1295.     rts
  1296. Polygon.flatTailEnd:
  1297.  
  1298. Polygon.FLAT_TAILSIZE:    =    Polygon.flatTailEnd-Polygon.flatTail
  1299.  
  1300. Polygon.pixelGouraudMoved:
  1301.     move.b    (a2,d0.w*2),(a0)+
  1302.     move.w    (a2,d0.w*2),(a0)+
  1303.  
  1304. Polygon.pixelGouraudOrred:
  1305.     move.b    (a2,d0.w*2),d2
  1306.     or.b    d2,(a0)+
  1307.     move.w    (a2,d0.w*2),d2
  1308.     or.w    d2,(a0)+
  1309.  
  1310. Polygon.pixelGouraudAdded:
  1311.     move.b    (a2,d0.w*2),d2
  1312.     add.b    d2,(a0)+
  1313.     move.w    (a2,d0.w*2),d2
  1314.     add.w    d2,(a0)+
  1315.  
  1316. Polygon.pixelGouraudceilAdded:
  1317.     move.b    (a2,d0.w*2),d2
  1318.     add.b    (a0),d2
  1319.     scs    d3
  1320.     or.b    d3,d2
  1321.     move.b    d2,(a0)+
  1322.     move.w    (a2,d0.w*2),(a0)+
  1323.  
  1324. Polygon.gouraudTail:
  1325.     addx.l    d1,d0
  1326.     dbra    d6,*-2
  1327.  
  1328.     adda.l    d5,a6
  1329.     DC.W    $51CF,$FFC4            ; dbra    d7,.yloop
  1330.     rts
  1331. Polygon.gouraudTailEnd:
  1332.  
  1333. Polygon.GOURAUD_TAILSIZE:=    Polygon.gouraudTailEnd-Polygon.gouraudTail
  1334.  
  1335. Polygon.pixelOffsetMoved:
  1336.     move.b    (a2,d1.l*2),(a0)+
  1337.     move.w    (a2,d1.l*2),(a0)+
  1338.  
  1339. Polygon.pixelOffsetOrred:
  1340.     move.b    (a2,d1.l*2),d0
  1341.     or.b    d0,(a0)+
  1342.     move.w    (a2,d1.l*2),d0
  1343.     or.w    d0,(a0)+
  1344.  
  1345. Polygon.pixelOffsetAdded:
  1346.     move.b    (a2,d1.l*2),d0
  1347.     add.b    d0,(a0)+
  1348.     move.w    (a2,d1.l*2),d0
  1349.     add.w    d0,(a0)+
  1350.  
  1351. Polygon.pixelOffsetceilAdded:
  1352.     nop
  1353.     nop
  1354.  
  1355. Polygon.offsetTail:
  1356.     dbra    d6,*
  1357.  
  1358.     adda.l    d5,a6
  1359.     dbra    d7,*
  1360.     rts
  1361. Polygon.offsetTailEnd:
  1362.  
  1363. Polygon.OFFSET_TAILSIZE:=    Polygon.offsetTailEnd-Polygon.offsetTail
  1364.  
  1365. Polygon.pixelTextureMoved:
  1366.     move.w    (a1),(a0)+
  1367.  
  1368. Polygon.pixelTextureOrred:
  1369.     move.w    (a1),d0
  1370.     or.w    d0,(a0)+
  1371.  
  1372. Polygon.pixelTextureAdded:
  1373.     move.w    (a1),d0
  1374.     add.w    d0,(a0)+
  1375.  
  1376. Polygon.pixelTextureceilAdded:
  1377.     move.w    (a1),(a0)+        ; simple move replacement!
  1378.  
  1379. Polygon.textureTail:
  1380.     dbra    d6,*
  1381.  
  1382.     adda.l    d5,a6
  1383.     dbra    d7,*
  1384.     rts
  1385. Polygon.textureTailEnd:
  1386.  
  1387. Polygon.TEXTURE_TAILSIZE:=    Polygon.textureTailEnd-Polygon.textureTail
  1388.  
  1389. ; INPUT:
  1390. ; d0.l= color
  1391. ; a1: shadow polygon table
  1392. Polygon.clearShadows:
  1393.     move.w    (a1)+,d7
  1394.     beq.s    .end
  1395.     subq.w    #1,d7
  1396.     move.l    d0,d4                ;d0,Polygon.color
  1397.     lea    PAINT_UNCLIPFLATFRAGMENT(pc),a4
  1398.  
  1399. .loop:    move.w    d7,-(sp)
  1400.     move.w    (a1)+,-(sp)
  1401.     pea    (a1)
  1402.     bsr    prest_paint_poly
  1403.     movea.l    (sp)+,a1
  1404.     move.w    (sp)+,d7
  1405.     lea    (a1,d7.w*4),a1            ; a1: next poly
  1406.     move.w    (sp)+,d7
  1407.     dbf    d7,.loop
  1408.  
  1409. .end:    rts
  1410.  
  1411. ; INPUT:
  1412. ; a0: background picture (same dimensions as viewport!)
  1413. ; a1: shadow polygon table
  1414. Polygon.restoreShadows:
  1415.     move.l    a0,PrimitiveMesh.background
  1416.     move.w    (a1)+,d7
  1417.     beq.s    .end
  1418.     subq.w    #1,d7
  1419.     lea    RESTORE_UNCLIPFLATFRAG(pc),a4
  1420.  
  1421. .loop:    move.w    d7,-(sp)
  1422.     IFNE    1
  1423.     move.w    (a1)+,-(sp)
  1424.     pea    (a1)
  1425.     bsr.s    prest_paint_poly
  1426.     movea.l    (sp)+,a1
  1427.     move.w    (sp)+,d7
  1428.     lea    (a1,d7.w*4),a1            ; a1: next poly
  1429.     ELSE
  1430.     bsr.s    Polygon.paintFlatshadedC
  1431.     ENDC
  1432.     move.w    (sp)+,d7
  1433.     dbf    d7,.loop
  1434.  
  1435. .end:    rts
  1436.  
  1437. Polygon.FLATUNROLL:    =    0
  1438.  
  1439. ; INPUT:
  1440. ; d4.l=color (optional)
  1441. ; a4: trapezoid paintrout
  1442. ; 4(sp): polyadr
  1443. ; 8(sp)=#points.w
  1444. prest_paint_poly:
  1445. ; Can you tell your head from your ass?
  1446.     move.w    8(sp),d7
  1447.     movea.l    4(sp),a0
  1448.     bsr    prest_reorder
  1449.  
  1450. ; if not anti-clockwise, you can make it..
  1451. ; todo: do the test when required..
  1452. .anti_clockwise:
  1453.     lea    prest_left_table,a6
  1454.     lea    prest_right_table,a2
  1455.     bra.s    .dir_done
  1456. .clockwise:
  1457.     lea    prest_left_table,a2
  1458.     lea    prest_right_table,a6
  1459. .dir_done:
  1460.  
  1461.     lea    Polygon.invTable,a5
  1462.  
  1463.     lea    prest_poly2,a1
  1464.     movea.l    a6,a0
  1465.     move.w    prest_max(pc),d6
  1466.     bsr    prest_calc_left_points
  1467.  
  1468.     lea    prest_poly2,a1
  1469.     movea.l    a2,a0
  1470.     move.w    prest_max(pc),d6
  1471.     move.w    8(sp),d7
  1472.     bsr    prest_calc_right_points
  1473.  
  1474. ; Now paint trapezoids..
  1475. ; d4.l=color (optional)
  1476. ; a4: trapezoid paintrout
  1477. ; a6: left
  1478. ; a2: right
  1479.     movem.w    prest_poly2,d0-d1
  1480.     move.w    d1,d6                ; d1.w=d6.w=top
  1481.  
  1482. ; Set screenstart
  1483.     movea.l    PrimitiveMesh.background,a3
  1484.     movea.l    Primitive.screenadr,a0
  1485.     move.w    d1,d2
  1486.     mulu.w    Viewport.settingsTable+Viewport.XSCREEN,d2
  1487.     add.l    d2,d2
  1488.     adda.l    d2,a0
  1489.     adda.l    d2,a3
  1490.     movea.w    Viewport.settingsTable+Viewport.XSCREEN,a5
  1491.     adda.l    a5,a5
  1492.  
  1493. ; Head..
  1494.     cmp.w    (a6),d6
  1495.     beq    .horizontal_head_l
  1496.     cmp.w    (a2),d6
  1497.     beq.s    .horizontal_head_r
  1498. ; Normal triangular head..
  1499.     swap    d0
  1500.     move.w    #$8000,d0            ; d0.l=lx start (16:16)
  1501.     move.l    d0,d1                ; d1.l=rx start (16:16)
  1502.     move.l    4(a6),d2            ; d2.l=l slope (16:16)
  1503.     move.l    4(a2),d3            ; d3.l=r slope (16:16)
  1504.  
  1505. .loop:
  1506. ; d6.w=y start
  1507. ; a0: start of next screenline
  1508.     cmp.w    prest_max(pc),d6
  1509.     beq.s    .end
  1510.     move.w    (a6),d7
  1511.     cmp.w    (a2),d7
  1512.     bgt.s    .left_bigger
  1513.     blt.s    .right_bigger
  1514.  
  1515. ; Both sides equal..
  1516. ;  / \
  1517. ; /   \
  1518.     sub.w    d6,d7
  1519.     subq.w    #1,d7                ; d7.w=h-1
  1520.     bmi.s    .skip_b
  1521.     jsr    (a4)
  1522. .skip_b:move.w    (a6)+,d6            ; d6.w=y
  1523.     move.w    (a6)+,d0            ; d0.w=lx start
  1524.     swap    d0
  1525.     move.w    #$8000,d0            ; d0.l=lx start (16:16)
  1526.     move.w    2(a2),d1
  1527.     swap    d1
  1528.     move.w    d0,d1                ; d1.l=rx start (16:16)
  1529.     addq    #4,a6                ; a6: next left
  1530.     addq    #8,a2                ; a2: next right
  1531.     move.l    4(a6),d2            ; d2.l=l slope (16:16)
  1532.     move.l    4(a2),d3            ; d3.l=r slope (16:16)
  1533.     bra.s    .loop
  1534.  
  1535. .right_bigger:
  1536. ; Right bigger, proceed to next left..
  1537. ; / \
  1538. ;    \
  1539.     sub.w    d6,d7
  1540.     subq.w    #1,d7                ; d7.w=h-1
  1541.     bmi.s    .skip_r
  1542.     jsr    (a4)
  1543. .skip_r:move.w    (a6)+,d6
  1544.     move.w    (a6)+,d0
  1545.     swap    d0
  1546.     move.w    #$8000,d0            ; d0.l=lx start (16:16)
  1547.     addq    #4,a6                ; a6: next left
  1548.     move.l    4(a6),d2            ; d2.l=l slope (16:16)
  1549.     bra.s    .loop
  1550.  
  1551. .left_bigger:
  1552. ; Left bigger, proceed to next right..
  1553. ;  / \
  1554. ; /
  1555.     move.w    (a2),d7
  1556.     sub.w    d6,d7
  1557.     subq.w    #1,d7                ; d7.w=h-1
  1558.     bmi.s    .skip_l
  1559.     jsr    (a4)
  1560. .skip_l:move.w    (a2)+,d6
  1561.     move.w    (a2)+,d1
  1562.     swap    d1
  1563.     move.w    #$8000,d1            ; d1.l=rx start (16:16)
  1564.     addq    #4,a2                ; a2: next right
  1565.     move.l    4(a2),d3            ; d3.l=r slope (16:16)
  1566.     bra.s    .loop
  1567.  
  1568. .end:    rts
  1569.  
  1570. ; Special fucking cases..
  1571.  
  1572. ;   o---r
  1573. ;  /    :
  1574. ; l
  1575. .horizontal_head_r:
  1576.     move.w    2(a2),d1
  1577.     swap    d1
  1578.     move.w    #$8000,d1            ; d1.l=right x (16:16)
  1579.     swap    d0
  1580.     move.w    d1,d0                ; d0.l=left x (16:16)
  1581.     addq    #8,a2                ; a2: next right
  1582.     move.l    4(a6),d2            ; d2.l=l slope (16:16)
  1583.     move.l    4(a2),d3            ; d3.l=l slope (16:16)
  1584.     bra    .loop
  1585.  
  1586. .horizontal_head_l:
  1587.     cmp.w    (a2),d1
  1588.     beq.s    .horizontal_head
  1589. ; l---o
  1590. ; :    \
  1591. ;       r
  1592.     swap    d0
  1593.     move.w    #$8000,d0
  1594.     move.l    d0,d1                ; d1.l=right x (16:16)
  1595.     move.w    2(a6),d0
  1596.     swap    d0
  1597.     move.w    d1,d0                ; d0.l=left x (16:16)
  1598.     addq    #8,a6                ; a6: next left
  1599.     move.l    4(a6),d2            ; d2.l=l slope (16:16)
  1600.     move.l    4(a2),d3            ; d3.l=l slope (16:16)
  1601.     bra    .loop
  1602.  
  1603. ; l---o---r
  1604. ; :       :
  1605. .horizontal_head:
  1606.     move.w    2(a6),d0
  1607.     swap    d0
  1608.     move.w    #$8000,d0            ; d0.l=left x (16:16)
  1609.     move.w    2(a2),d1
  1610.     swap    d1
  1611.     move.w    d0,d1                ; d1.l=right x (16:16)
  1612.     addq    #8,a6                ; a6: next left
  1613.     addq    #8,a2                ; a6: next right
  1614.     move.l    4(a6),d2            ; d2.l=l slope (16:16)
  1615.     move.l    4(a2),d3            ; d3.l=l slope (16:16)
  1616.     bra    .loop
  1617.  
  1618. ; d7.w=pointcount >=3
  1619. ; a0: point table count*(x.w,y.w)
  1620. prest_reorder:
  1621. ; Find min y and max y.
  1622.     movea.l    a0,a1                ; a1: backup src poly
  1623.     addq    #2,a0                ; a0: y coords
  1624.     move.w    d7,d6
  1625.     move.w    d7,d1                ; d1.w=count-index_min[0]
  1626.     move.w    d7,d3                ; d3.w=count-index_max[0]
  1627.     subq.w    #1,d6
  1628.     moveq    #$FFFFFFFF,d0            ; d0.w=min[0]
  1629.     moveq    #$00000000,d2            ; d2.w=max[0]
  1630. .loop:    cmp.w    (a0),d0                ; y[n]<min[n-1] ?
  1631.     blo.s    .try_max            ; nope -> check next
  1632.     move.w    (a0),d0                ; Set new min.
  1633.     move.w    d6,d1                ; Set new minindex.
  1634. .try_max:
  1635.     cmp.w    (a0),d2
  1636.     bhi.s    .next
  1637.     move.w    (a0),d2                ; Set new max.
  1638.     move.w    d6,d3                ; Set new maxindex.
  1639. .next:    addq    #4,a0                ; a0: next point
  1640.     dbf    d6,.loop
  1641.     move.w    d0,prest_min
  1642.     move.w    d2,prest_max
  1643.  
  1644. ; Head up!
  1645.     lea    prest_poly2,a0
  1646.  
  1647. ; Rotate the point table using a barrel shift.
  1648. ; The 
  1649. ; a0: dst point table
  1650. ; a1: src point table
  1651. ; d1.w=count - split index
  1652. ; d7.w=pointcount
  1653.     subq.w    #1,d7                ; d7.w=#points-1
  1654.     move.w    d7,d6
  1655.     sub.w    d1,d6                ; d6.w=count-(count-split)=split
  1656.     lea    (a1,d6.w*4),a2            ; a2: src tail
  1657.     move.w    d1,d5                ; d5.w=headsize
  1658. .headloop:
  1659.     move.l    (a2)+,(a0)+
  1660.     dbf    d5,.headloop
  1661.  
  1662.     subq.w    #1,d6
  1663.     bmi.s    .tail_done
  1664. .tailloop:
  1665.     move.l    (a1)+,(a0)+
  1666.     dbf    d6,.tailloop
  1667. .tail_done:
  1668.     rts
  1669.  
  1670. ; d6.w=btm
  1671. ; a0: left table [(y.w,x.w,slope.l),(),...]
  1672. ; a1: pointtable
  1673. ; a5: invtable
  1674. prest_calc_left_points:
  1675.     clr.l    d2
  1676.     move.w    (a1)+,d1                ; d0.w=y[0]
  1677.     move.w    (a1)+,d0                ; d1.w=x[0]
  1678. .loop:
  1679. ; a1: next point
  1680.     move.w    2(a1),d2                ; d2.w=y[n]
  1681.     move.w    d2,(a0)+                ; Store y.
  1682.     sub.w    d0,d2                    ; d2.w=dy
  1683.     move.w    (a1),d3                    ; d3.w=x[n]
  1684.     move.w    d3,(a0)+                ; Store x.
  1685.     sub.w    d1,d3                    ; d1.w=dx
  1686.     muls.w    (a5,d2.l*2),d3                ; d3.l=dx<<16/dy
  1687.     add.l    d3,d3
  1688.     move.l    d3,(a0)+                ; Store slope.
  1689.     move.w    (a1)+,d1                ; d0.w=y[n]
  1690.     move.w    (a1)+,d0                ; d1.w=x[n]
  1691.     cmp.w    d0,d6
  1692.     bne.s    .loop
  1693. .end:    rts
  1694.  
  1695. ; d6.w=btm
  1696. ; d7.w=#points
  1697. ; a0: right table [(y.w,x.w,slope.l),(),...]
  1698. ; a1: pointtable
  1699. ; a5: invtable
  1700. prest_calc_right_points:
  1701.     clr.l    d2
  1702.     move.w    (a1)+,d1                ; d0.w=y[0]
  1703.     move.w    (a1)+,d0                ; d1.w=x[0]
  1704.     lea    -8(a1,d7.w*4),a1
  1705. .loop:
  1706. ; a1: next point
  1707.     move.w    2(a1),d2                ; d2.w=y[n]
  1708.     move.w    d2,(a0)+                ; Store y.
  1709.     sub.w    d0,d2                    ; d2.w=dy
  1710.     move.w    (a1),d3                    ; d3.w=x[n]
  1711.     move.w    d3,(a0)+                ; Store x.
  1712.     sub.w    d1,d3                    ; d1.w=dx
  1713.     muls.w    (a5,d2.l*2),d3                ; d3.l=dx<<16/dy
  1714.     add.l    d3,d3
  1715.     move.l    d3,(a0)+                ; Store slope.
  1716.     move.w    (a1)+,d1                ; d0.w=y[n]
  1717.     move.w    (a1)+,d0                ; d1.w=x[n]
  1718.     subq    #8,a1
  1719.     cmp.w    d0,d6
  1720.     bne.s    .loop
  1721. .end:    rts
  1722.  
  1723. prest_max:
  1724.     ds.w    1
  1725.  
  1726. ;.................................
  1727.  
  1728. ; Splits a flatshaded polygon up into triangles and paints them.
  1729. ; Receives the crap from the hostport.
  1730. Polygon.paintDspFlatshaded:
  1731.     clr.l    d0
  1732.     receiveWordFromDsp    d0
  1733.     movea.l    Polygon.coloradr,a0
  1734.     lea    Primitive.GRADIENTSIZE/2(a0),a0
  1735.     lsl.l    #Primitive.GRADIENTBITS+1,d0
  1736.     move.w    (a0,d0.l),d2
  1737.     move.w    d2,d1
  1738.     swap    d2
  1739.     move.w    d1,d2
  1740.     bra.s    Polygon.paintDspFlatshaded3
  1741.  
  1742. Polygon.paintDspFlatshaded2:
  1743.     move.l    Polygon.color,d2
  1744. Polygon.paintDspFlatshaded3:
  1745.     movea.l    Primitive.screenadr,a0
  1746.     receiveWordFromDsp    d0        ; d0.w=top y
  1747.     clr.l    d5
  1748.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  1749.     add.l    d5,d5
  1750.     mulu.w    d5,d0
  1751.     adda.l    d0,a0
  1752.     receiveWordFromDsp    d7        ; d7.w=#scans
  1753.     clr.l    d0
  1754.     clr.l    d1
  1755.     lea    $FFFFA206.w,a3
  1756.     subq.w    #1,d7
  1757.     bmi.s    .end
  1758.  
  1759.     IFNE    Polygon.FLATUNROLL
  1760.     moveq    #1<<5-1,d4
  1761.     lea    .pixeljumpend(pc),a2
  1762.     ENDC
  1763.  
  1764. .yloop:    move.w    (a3),d0                ; d0.w=lx
  1765.     move.w    (a3),d1                ; d1.w=rx
  1766.     sub.w    d0,d1                ; d1.w=length=rx-lx
  1767.     ble.s    .next
  1768.     lea    (a0,d0.l*2),a1
  1769.  
  1770.     IFNE    0
  1771.  
  1772.     lsr.w    d0
  1773.     bcc.s    .end_1st
  1774.     move.w    d2,(a1)+
  1775.     subq.w    #1,d1
  1776.     ble.s    .next
  1777. .end_1st:
  1778.     move.w    d1,d0
  1779.     lsr.w    d1
  1780.     beq.s    .last
  1781.     subq.w    #1,d1
  1782. .pixloop:
  1783.     move.l    d2,(a1)+
  1784.     dbf    d1,.pixloop
  1785. .last:    lsr.w    d0
  1786.     bcc.s    .end_last
  1787.     move.w    d2,(a1)+
  1788. .end_last:
  1789.  
  1790.     ELSE
  1791.  
  1792.     IFNE    Polygon.FLATUNROLL
  1793.  
  1794.     move.l    d1,d3
  1795.     lsr.l    #5,d1
  1796.     and.w    d4,d3
  1797.     neg.l    d3
  1798.     jmp    (a2,d3.l*2)
  1799.  
  1800.     IFNE    *&2                    ; Put it longeven!
  1801.     nop
  1802.     ENDC
  1803. .chunkloop:
  1804.     REPT    1<<5
  1805.     move.w    d2,(a1)+
  1806.     ENDR
  1807. .pixeljumpend:
  1808.     dbf    d1,.chunkloop
  1809.  
  1810.     ELSE
  1811.  
  1812.     subq.w    #1,d1
  1813.  
  1814. .xloop:    move.w    d2,(a1)+
  1815.     dbf    d1,.xloop
  1816.  
  1817.     ENDC
  1818.  
  1819.     ENDC
  1820.  
  1821. .next:    adda.l    d5,a0
  1822.     dbf    d7,.yloop
  1823. .end:    rts
  1824.  
  1825. ; Paints a gouraudshaded polygon.
  1826. ; INPUT: a1: polygon
  1827. Polygon.paintGouraudshaded:
  1828.     move.w    (a1)+,Polygon.curtexture
  1829.     move.w    #Polygon.GOURAUD_SHADING,d0
  1830.     moveq    #2,d6
  1831.     bra    Polygon.paintDsp
  1832.  
  1833. ; Paints a gouraudshaded polygon directly (slope recalc per scan included!).
  1834. ; Receives tha crap from the hostport.
  1835. Polygon.paintFastGouraudshaded:
  1836.     move.w    #Polygon.GOURAUD_SHADING,d0
  1837.     moveq    #2,d6
  1838.     bra    Polygon.paintReceived
  1839.  
  1840. ; Splits a texturemapped polygon up into triangles and paints them.
  1841. ; INPUT: a1: polygon
  1842. Polygon.paintTextured:
  1843.     move.w    (a1)+,Polygon.curtexture
  1844.     move.w    Polygon.texturemode,d0
  1845.     moveq    #3,d6
  1846.     bra.s    Polygon.paintDsp
  1847.  
  1848. ; Splits an alpha-texturemapped polygon up into triangles and paints them.
  1849. ; INPUT: a1: polygon
  1850. Polygon.paintAlphatextured:
  1851.     move.w    (a1)+,Polygon.curtexture
  1852.     moveq    #RPC_SET_V4ALPHA,d0
  1853.     sendLongToDsp    d0
  1854.     move.w    #Polygon.ALPHA_TEXTURING,d0
  1855.     moveq    #5,d6
  1856.     bra.s    Polygon.paintDsp
  1857.  
  1858. ; Splits an alpha-texturemapped polygon up into triangles and paints them.
  1859. ; INPUT: a1: polygon
  1860. Polygon.paintBumpmapped:
  1861.     move.w    (a1)+,Polygon.curtexture
  1862.     moveq    #RPC_SET_V4BUMP,d0
  1863.     sendLongToDsp    d0
  1864.     move.w    #Polygon.BUMP_TEXTURING,d0
  1865.     moveq    #5,d6
  1866.  
  1867. ; Sends polygon data to the dsp, receives incoming scanline data and paints
  1868. ; it to the screen.
  1869. ; This works for all shadetypes.
  1870. ; INPUT:
  1871. ; d0.w:    DSP texturing mode
  1872. ; d6.w:    number of coordinates in point
  1873. ;       (1=flat, 2=gouraud, 3=texture, 4=gouraudtexture, 5=alpha/bumpmap)
  1874. ; a1: polygon table
  1875. Polygon.paintDsp:
  1876.     sendLongToDsp    #RPC_PAINT_POLYGON        ; Call the DSP.
  1877.  
  1878.     clr.l    d1
  1879.     move.w    Polygon.curtexture,d1
  1880.     sendLongToDsp    d1                ; Send texturenumber.
  1881.     clr.l    d7
  1882.     move.w    (a1)+,d7
  1883.     sendLongToDsp    d7                ; Send number of points.
  1884.     move.l    d6,$ffffa204.w
  1885.     subq.w    #2,d6
  1886.     subq.w    #1,d7
  1887.  
  1888. .pointloop:
  1889.     movem.w    (a1)+,d1-d2
  1890.     ;sendLongToDsp    d2                ; Send Y.
  1891.     move.l    d2,$ffffa204.w
  1892.     ;sendLongToDsp    d1                ; Send X.
  1893.     move.l    d1,$ffffa204.w
  1894.     move.w    d6,d5
  1895.     bmi.s    .skip_coords
  1896.  
  1897. ; Send u0,v0,u1,v1
  1898. .coordloop:
  1899.     moveq    #0,d1
  1900.     move.w    (a1)+,d1
  1901.     swap    d1
  1902.     lsr.l    #1,d1
  1903.     ;sendLongToDsp    d1
  1904.     move.l    d1,$ffffa204.w
  1905.     dbra    d5,.coordloop
  1906. .skip_coords:
  1907.  
  1908.     dbra    d7,.pointloop
  1909.  
  1910.     lea    $FFFFA206.w,a1
  1911.     clr.l    d2
  1912.     receiveWordFromDsp    d2            ; Get texture number.
  1913.     movea.l    Primitive.screenadr,a0
  1914.     moveq    #0,d5
  1915.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  1916.     add.l    d5,d5
  1917.     ;receiveWordFromDsp    d1            ; Get top y.
  1918.     move.w    (a1),d1
  1919.     mulu.w    d5,d1
  1920.     adda.l    d1,a0
  1921.     movea.l    a0,a6
  1922.     ;receiveWordFromDsp    d7            ; Get height.
  1923.     move.w    (a1),d7
  1924.     subq.w    #1,d7
  1925.     bpl.s    .go_on
  1926.     rts
  1927. .go_on:    clr.l    d1
  1928.     cmpi.w    #Polygon.GOURAUD_SHADING,d0
  1929.     beq    PAINT_GOURAUDPOLY
  1930.     cmpi.w    #Polygon.PIXEL_TEXTURING,d0
  1931.     beq    PAINT_PIXELDSPPOLY
  1932.     cmpi.w    #Polygon.OFFSET_TEXTURING,d0
  1933.     beq    PAINT_OFFSETDSPPOLY
  1934.     cmpi.w    #Polygon.ALPHA_TEXTURING,d0
  1935.     beq    PAINT_ALPHADSPPOLY
  1936.     cmpi.w    #Polygon.BUMP_TEXTURING,d0
  1937.     beq    PAINT_BUMPDSPPOLY
  1938.     rts
  1939.  
  1940. ; INPUT:
  1941. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1942. Polygon.paintClippedFlatshaded:
  1943.     moveq    #0,d0
  1944.     move.w    (a1)+,d0
  1945.     movea.l    Polygon.coloradr,a0
  1946.     lea    Primitive.GRADIENTSIZE/2(a0),a0
  1947.     lsl.l    #Primitive.GRADIENTBITS+1,d0
  1948.     move.w    (a0,d0.l),d0
  1949.     move.w    d0,d1
  1950.     swap    d0
  1951.     move.w    d1,d0
  1952.     move.l    d0,Polygon.color
  1953.     move.w    #Polygon.FLAT_SHADING,d0
  1954.     moveq    #1,d6
  1955.     bra.s    Polygon.paintClipped
  1956.  
  1957. ; INPUT:
  1958. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1959. Polygon.paintClippedGouraudshaded:
  1960.     clr.l    d0
  1961.     move.w    (a1)+,d0
  1962.     movea.l    Polygon.coloradr,a0
  1963.     lsl.l    #Primitive.GRADIENTBITS+1,d0                ; d0*(64*2)
  1964.     adda.l    d0,a0
  1965.     move.l    a0,Polygon.gradadr
  1966.     move.w    #Polygon.GOURAUD_SHADING,d0
  1967.     moveq    #2,d6
  1968.     bra.s    Polygon.paintClipped
  1969.  
  1970. ; INPUT:
  1971. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1972. Polygon.paintClippedTextured:
  1973.     move.w    (a1)+,Polygon.curtexture
  1974.     move.w    Polygon.texturemode,d0
  1975.     moveq    #3,d6
  1976.     bra.s    Polygon.paintClipped
  1977.  
  1978. ; INPUT:
  1979. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1980. Polygon.paintClippedAlphatextured:
  1981.     move.w    (a1)+,Polygon.curtexture
  1982.     moveq    #RPC_SET_V4ALPHA,d0
  1983.     sendLongToDsp    d0
  1984.     move.w    #Polygon.ALPHA_TEXTURING,d0
  1985.     moveq    #5,d6
  1986.     bra.s    Polygon.paintClipped
  1987.  
  1988. ; INPUT:
  1989. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1990. Polygon.paintClippedBumpmapped:
  1991.     move.w    (a1)+,Polygon.curtexture
  1992.     moveq    #RPC_SET_V4BUMP,d0
  1993.     sendLongToDsp    d0
  1994.     move.w    #Polygon.BUMP_TEXTURING,d0
  1995.     moveq    #5,d6
  1996.  
  1997. ; Sends polygon data to the dsp, receives incoming scanline data and paints
  1998. ; it to the screen. Ofcourse this clips as well! This is a HumanFly
  1999. ; interface implementation!
  2000. ; INPUT:
  2001. ; d0.w:    DSP texturing mode
  2002. ; d6.l:    number of coordinates in point
  2003. ;       (1=flat, 2=gouraud, 3=texture, 4=gouraudtexture, 5=alpha/bumpmap)
  2004. ; a1: polygon table (numofpoints.w, points)
  2005. Polygon.paintClipped:
  2006.     sendLongToDsp    #RPC_CLIPPAINT_POLYGON        ; Call the DSP.
  2007.  
  2008.     clr.l    d1
  2009.     move.w    Polygon.curtexture,d1
  2010.     sendLongToDsp    d1                ; Send texturenumber.
  2011.     move.w    (a1)+,d7
  2012.     ext.l    d7
  2013.     sendLongToDsp    d7                ; Send number of points.
  2014.     ;sendLongToDsp    d6                ; Send pointsize.
  2015.     move.l    d6,$FFFFA204.w
  2016.     subq.w    #2,d6
  2017.     subq.w    #1,d7
  2018.  
  2019. .pointloop:
  2020.     movem.w    (a1)+,d1-d2
  2021.     ;sendLongToDsp    d2                ; Send Y.
  2022.     move.l    d2,$ffffa204.w
  2023.     ;sendLongToDsp    d1                ; Send X.
  2024.     move.l    d1,$ffffa204.w
  2025.     move.w    d6,d5
  2026.     bmi.s    .skip_coords
  2027.  
  2028. ; Send u0,v0,u1,v1
  2029. .coordloop:
  2030.     moveq    #0,d1
  2031.     move.w    (a1)+,d1
  2032.     swap    d1
  2033.     lsr.l    #1,d1
  2034.     ;sendLongToDsp    d1
  2035.     move.l    d1,$ffffa204.w
  2036.     dbf    d5,.coordloop
  2037. .skip_coords:
  2038.  
  2039.     dbf    d7,.pointloop
  2040.  
  2041.     receiveWordFromDsp    d7            ; d7=cullstatus
  2042.     bmi.s    .end                    ; Culled off?
  2043.     clr.l    d2
  2044.     receiveWordFromDsp    d2            ; Get texture number.
  2045.  
  2046.     cmpi.w    #Polygon.FLAT_SHADING,d0
  2047.     beq    Polygon.paintDspFlatshaded2
  2048.  
  2049.     lea    $ffffa206.w,a1
  2050.     movea.l    Primitive.screenadr,a0
  2051.     moveq    #0,d5
  2052.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  2053.     add.l    d5,d5
  2054.  
  2055.     receiveWordFromDsp    d1            ; Get top y.
  2056.     ;move.w    (a1),d1
  2057.  
  2058.     mulu.w    d5,d1
  2059.     adda.l    d1,a0
  2060.     movea.l    a0,a6
  2061.     ;receiveWordFromDsp    d7            ; Get height.
  2062.     move.w    (a1),d7
  2063.     subq.w    #1,d7
  2064.     bpl.s    .go_on
  2065. .end:    rts
  2066. .go_on:    clr.l    d1
  2067.     cmpi.w    #Polygon.GOURAUD_SHADING,d0
  2068.     beq    PAINT_GOURAUDPOLY
  2069.     cmpi.w    #Polygon.PIXEL_TEXTURING,d0
  2070.     beq    PAINT_PIXELDSPPOLY
  2071.     cmpi.w    #Polygon.OFFSET_TEXTURING,d0
  2072.     beq    PAINT_OFFSETDSPPOLY
  2073.     cmpi.w    #Polygon.ALPHA_TEXTURING,d0
  2074.     beq    PAINT_ALPHADSPPOLY
  2075.     cmpi.w    #Polygon.BUMP_TEXTURING,d0
  2076.     beq    PAINT_BUMPDSPPOLY
  2077.     rts
  2078.  
  2079. ; Splits a texturemapped polygon up into triangles and paints them.
  2080. ; Receives shit over hostport.
  2081. Polygon.paintDspTexturemapped:
  2082.     move.w    Polygon.texturemode,d0
  2083.     moveq    #3,d6
  2084.     bra.s    Polygon.paintReceived
  2085.  
  2086. ; Splits an alpha-texturemapped polygon up into triangles and paints them.
  2087. ; Receives trash over hostport.
  2088. Polygon.paintDspAlphatextured:
  2089.     moveq    #RPC_SET_V4ALPHA,d0
  2090.     move.w    #Polygon.ALPHA_TEXTURING,d0
  2091.     moveq    #5,d6
  2092.     bra.s    Polygon.paintReceived
  2093.  
  2094. ; Splits an alpha-texturemapped polygon up into triangles and paints them.
  2095. ; Receives rotteness over hostport.
  2096. Polygon.paintDspBumpmapped:
  2097.     moveq    #RPC_SET_V4BUMP,d0
  2098.     move.w    #Polygon.BUMP_TEXTURING,d0
  2099.     moveq    #5,d6
  2100.  
  2101. ; Receives incoming scanline data and paints it to the screen.
  2102. ; This works for all shadetypes.
  2103. ; INPUT:
  2104. ; d0.w=    DSP texturing mode (shadetype)
  2105. ; d6.w=    number of coordinates in point
  2106. ;       (1=flat, 2=gouraud, 3=texture, 4=gouraudtexture, 5=alpha/bumpmap)
  2107. Polygon.paintReceived:
  2108.     lea    $FFFFA206.w,a1
  2109.  
  2110. ; 1: Receive and store polygon outline...
  2111.     tst.w    PrimitiveMesh.shadowsOn
  2112.     beq.s    .outline_end
  2113.  
  2114.     movea.l    PrimitiveMesh.shadowStartAdr,a2
  2115.     addq.w    #1,(a2)                    ; Increase shadow poly count.
  2116.     movea.l    PrimitiveMesh.shadowAdr,a2
  2117.  
  2118.     receiveWordFromDsp    d5            ; d5.w=#vertices
  2119.     ;move.w    (a1),d5
  2120.  
  2121.     move.w    d5,(a2)+                ; Store #vertices.
  2122.     subq.w    #1,d5
  2123. .outline_loop:
  2124. ; Receive x.
  2125.     ;receiveWordFromDsp    (a2)+
  2126.     move.w    (a1),(a2)+
  2127. ; Receive y.
  2128.     ;receiveWordFromDsp    (a2)+
  2129.     move.w    (a1),(a2)+
  2130.     dbf    d5,.outline_loop
  2131.  
  2132.     move.l    a2,PrimitiveMesh.shadowAdr
  2133. .outline_end:
  2134.  
  2135. ; 2: Receive and handle painting info..
  2136.     clr.l    d2
  2137.  
  2138.     receiveWordFromDsp    d2            ; Get shadetype.
  2139.     ;move.w    (a1),d2
  2140.     ;receiveWordFromDsp    d1            ; Get top y.
  2141.     move.w    (a1),d1
  2142.     ;receiveWordFromDsp    d7            ; Get height.
  2143.     move.w    (a1),d7
  2144.  
  2145.     subq.w    #1,d7
  2146.     bpl.s    .go_on
  2147.     rts
  2148.  
  2149. ; d1.w=top y
  2150. ; d2.w=shadetype
  2151. ; d7.w=height-1
  2152. .go_on:    movea.l    Primitive.screenadr,a0
  2153.     clr.l    d5
  2154.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  2155.     add.l    d5,d5
  2156.     mulu.w    d5,d1
  2157.     adda.l    d1,a0
  2158.     movea.l    a0,a6
  2159. ; a0=a6=screen pos
  2160. ; d7.w=height-1
  2161.  
  2162. ; 3: and paint..
  2163.     clr.l    d1
  2164.     cmpi.w    #Polygon.GOURAUD_SHADING,d0
  2165.     beq    PAINT_GOURAUDPOLY
  2166.     cmpi.w    #Polygon.PIXEL_TEXTURING,d0
  2167.     beq    PAINT_PIXELDSPPOLY
  2168.     cmpi.w    #Polygon.OFFSET_TEXTURING,d0
  2169.     beq    PAINT_OFFSETDSPPOLY
  2170.     cmpi.w    #Polygon.ALPHA_TEXTURING,d0
  2171.     beq    PAINT_ALPHADSPPOLY
  2172.     cmpi.w    #Polygon.BUMP_TEXTURING,d0
  2173.     beq    PAINT_BUMPDSPPOLY
  2174.     rts
  2175.  
  2176. ; This should be both fast as well as accurate. At least.. faster than
  2177. ; texturemapping. Prolly something like 1.500.000 pixels/s on standard
  2178. ; Falcon.
  2179. PAINT_GOURAUDPOLY:
  2180.     movea.w    Primitive.skipBytes,a3
  2181.     movea.l    Polygon.coloradr,a2
  2182.     lsl.l    #Primitive.GRADIENTBITS+1,d2                ; d0*(64*2)
  2183.     adda.l    d2,a2
  2184.  
  2185. Polygon.gouraudYloop:
  2186. .wait:    btst.b    #0,$ffffa202.w
  2187.     beq.s    .wait
  2188.  
  2189.     move.w    (a1),d1                    ; Get left x.
  2190.     lea    (a6,d1.w*2),a0
  2191.     move.w    (a1),d6                    ; Get width.
  2192.     clr.l    d0
  2193.     clr.l    d1
  2194.     receiveLongFromDsp    d0            ; d0.l = left u
  2195.     swap    d0
  2196.     ext.w    d0
  2197.     receiveLongFromDsp    d1            ; d1.l = u_step
  2198.     swap    d1
  2199.     ext.w    d1
  2200.     subq.w    #1,d6
  2201.     bpl.s    .go_on
  2202.     adda.l    d5,a6
  2203.     dbra    d7,Polygon.gouraudYloop    
  2204.     rts
  2205. .go_on:
  2206.  
  2207. Polygon.gouraudPixelInstr:
  2208. .xloop:    move.w    (a2,d0.w*2),(a0)+
  2209.     addx.l    d1,d0
  2210.     dbra    d6,.xloop
  2211.  
  2212.     adda.l    d5,a6
  2213.     dbra    d7,Polygon.gouraudYloop
  2214.     rts
  2215.  
  2216.     nop                        ; for code gen crap
  2217.     nop
  2218.     nop
  2219.     nop
  2220.  
  2221. CHUNKLOG:    =    4
  2222.  
  2223. ; This is slow. But since it can do a polygon instead of only a triangle,
  2224. ; I'm content. Speed on a plain falcon is 500.000 texels/s _including_
  2225. ; overhead.
  2226. ; INPUT:
  2227. ; d2.w= texturenumber
  2228. PAINT_OFFSETDSPPOLY:
  2229.     clr.l    d1
  2230.     movea.w    Primitive.skipBytes,a3
  2231.     lea    Polygon.textureTable,a2
  2232.     movea.l    (a2,d2.w*4),a2
  2233.  
  2234. Polygon.offsetYloop:
  2235.     move.w    (a1),d1                    ; d1.w=lx
  2236.     lea    (a6,d1.l*2),a0
  2237.     receiveWordFromDsp    d6            ; d6.w=width
  2238.     bgt.s    .go_on
  2239.     adda.l    d5,a6
  2240.     dbra    d7,Polygon.offsetYloop
  2241.     rts
  2242. .go_on:    subq.w    #1,d6
  2243.  
  2244.     move.w    (a1),d1
  2245. Polygon.offsetPixelInstr:
  2246.     move.w    (a2,d1.l*2),(a0)+
  2247.     dbra    d6,Polygon.offsetPixelInstr-2
  2248.  
  2249.     adda.l    d5,a6
  2250.     dbra    d7,Polygon.offsetYloop
  2251.     rts
  2252.  
  2253.     nop
  2254.     nop
  2255.  
  2256. DSP_SYNC:    =    1
  2257.  
  2258. ; This is fast on a plain falcon. In fact, it kicks every other rout
  2259. ; I've seen square in the nuts!!! =)) Speeds of 1.100.000 texels/s
  2260. ; _including_ overhead are no exception!
  2261. ; Though this unrolled jumptree sucks on ct2.
  2262. PAINT_PIXELDSPPOLY:
  2263.     moveq    #1<<CHUNKLOG-1,d4
  2264. Polygon.textureLoadInstr:
  2265.     lea    Polygon.pixeljumpend,a2
  2266.     clr.l    d6
  2267.  
  2268. Polygon.textureYloop:
  2269. .yloop:    move.w    (a1),d1                    ; Get left x.
  2270.     lea    (a6,d1.l*2),a0
  2271.     move.w    (a1),d6                    ; Get width.
  2272.     bgt.s    .go_on
  2273.     adda.l    d5,a6
  2274.     dbra    d7,.yloop
  2275.     rts
  2276. .go_on:    move.l    d6,d3
  2277.     lsr.l    #CHUNKLOG,d6
  2278.     and.l    d4,d3
  2279.     neg.l    d3
  2280. Polygon.textureJmpInstr:
  2281.     jmp    (a2,d3.l*2)
  2282.  
  2283. Polygon.texturePixelInstr:
  2284.     REPT    1<<CHUNKLOG
  2285.     move.w    (a1),(a0)+
  2286.     ENDR
  2287. Polygon.pixeljumpend:
  2288.     dbf    d6,Polygon.texturePixelInstr
  2289.  
  2290.     adda.l    d5,a6
  2291.     dbf    d7,Polygon.textureYloop
  2292.     rts
  2293.  
  2294.     DS.W    1<<CHUNKLOG
  2295.  
  2296. ; Speed of >500.000 texels/s _including_ overhead.
  2297. PAINT_ALPHADSPPOLY:
  2298.     movea.l    Polygon.alphatableadr,a2
  2299.  
  2300. .yloop:    move.w    (a1),d1                    ; Get left x.
  2301.     lea    (a6,d1.l*2),a0
  2302.     move.w    (a1),d6                    ; Get width.
  2303.     subq.w    #1,d6
  2304.     bmi.s    .end_xloop
  2305.  
  2306. .wait:    btst.b    #0,$FFFFA202.w
  2307.     beq.s    .wait
  2308.  
  2309. .xloop:    move.w    (a1),d1
  2310.     move.w    (a2,d1.l*2),(a0)+
  2311. ; Shit! takes 14 cycles to sync on CT2.
  2312.     IFNE    DSP_SYNC
  2313.     rol.l    d0,d0
  2314.     rol.l    #4,d0
  2315.     ENDC
  2316.     dbra    d6,.xloop
  2317. .end_xloop:
  2318.  
  2319.     adda.l    d5,a6
  2320.     dbra    d7,.yloop
  2321.  
  2322. .end:    rts
  2323.  
  2324. ; Speed of 800.000 texels/s _including_ overhead.
  2325. PAINT_BUMPDSPPOLY:
  2326. .yloop:    move.w    (a1),d1                    ; Get left x.
  2327.     lea    (a6,d1.l*2),a0
  2328.     move.w    (a1),d6                    ; Get width.
  2329.     subq.w    #1,d6
  2330.     bmi.s    .end_xloop
  2331.  
  2332. .wait:    btst.b    #0,$ffffa202.w
  2333.     beq.s    .wait
  2334.  
  2335. .xloop:    move.w    (a1),(a0)+
  2336. ; Shit! takes 16 cycles to sync on CT2.
  2337.     IFNE    DSP_SYNC
  2338.     rol.l    d0,d0
  2339.     rol.l    d0,d0
  2340.     nop
  2341.     nop
  2342.     ELSE
  2343.     nop                        ; needed even on plain falcon!!
  2344.     nop
  2345.     ENDC
  2346.     dbra    d6,.xloop
  2347. .end_xloop:
  2348.  
  2349.     adda.l    d5,a6
  2350.     dbra    d7,.yloop
  2351.  
  2352. .end:    rts
  2353.  
  2354. ;======= Fragment
  2355.  
  2356.             RSRESET
  2357. Fragment.LSLOPE:    RS.L    1        ; 16:16 fixed point
  2358. Fragment.RSLOPE:    RS.L    1        ; 16:16 fixed point
  2359. Fragment.LX:        RS.W    1        ; left X
  2360. Fragment.RX:        RS.W    1        ; right X
  2361. Fragment.LUSTART:    RS.W    1        ; 8:8 index
  2362. Fragment.LVSTART:    RS.W    1        ; 8:8 index
  2363. Fragment.RUSTART:    RS.W    1        ; 8:8 index
  2364. Fragment.RVSTART:    RS.W    1        ; 8:8 index
  2365. Fragment.LUSLOPE:    RS.W    1        ; 8:8 slope
  2366. Fragment.LVSLOPE:    RS.W    1        ; 8:8 slope
  2367. Fragment.RUSLOPE:    RS.W    1        ; 8:8 slope
  2368. Fragment.RVSLOPE:    RS.W    1        ; 8:8 slope
  2369. Fragment.START:        RS.W    1        ; start scanline of fragment
  2370. Fragment.HEIGHT:    RS.W    1        ; height of fragment
  2371. Fragment.SIZE:        RS.B    0
  2372.  
  2373. Fragment.shadeMask:    =    %00000111
  2374. Fragment.shadeFlat:    =    %000
  2375. Fragment.shadeGradient:    =    %001
  2376. Fragment.shadeTexture:    =    %010
  2377. Fragment.shadeAlpha:    =    %011
  2378. Fragment.shadeBump:    =    %100
  2379. Fragment.maskMode:    =    %00001000
  2380. Fragment.clipMode:    =    %00010000
  2381.  
  2382. ; Subroutine that paints a flatshaded fragment. NO clipping!
  2383. ; INPUT:
  2384. ; d0.l: 16:16 left X-start
  2385. ; d1.l: 16:16 right X-start
  2386. ; d2.l: 16:16 left stepvalue
  2387. ; d3.l: 16:16 right stepvalue
  2388. ; d4.l: 16:16 color (double highcolor)
  2389. ; d7.w: number of scanlines to paint - 1
  2390. ; a0: start of begin screenline
  2391. ; a5: width (bytes)
  2392. ; OUTPUT: a0: start of next screenline
  2393. PAINT_UNCLIPFLATFRAGMENT:
  2394.  
  2395. Polygon.flatFragmentYloop:
  2396. .yloop:    move.l    d0,d5
  2397.     move.l    d1,d6
  2398.     swap    d5
  2399.     swap    d6
  2400.  
  2401.     sub.w    d5,d6
  2402.     bgt.s    .go_on
  2403.  
  2404.     adda.l    a5,a0
  2405.     add.l    d2,d0
  2406.     add.l    d3,d1
  2407.     dbf    d7,.yloop
  2408.     rts
  2409.  
  2410.     IFNE    1
  2411. ; warning! this will _not_ work with code generation!!
  2412.  
  2413. .go_on:    lea    (a0,d5.w*2),a1
  2414. ; seems to be fastest at the moment.
  2415.     lsr.w    d6
  2416.     bcc.s    .even
  2417.     move.w    d4,(a1)+
  2418. .even:    subq.w    #1,d6
  2419.     bmi.s    .end
  2420. .loop:    move.l    d4,(a1)+
  2421.     dbf    d6,.loop
  2422. .end:
  2423.  
  2424. Polygon.flatPixelInstr:                ; dummy, don't use!
  2425.  
  2426.     ELSE
  2427.  
  2428. .go_on:    subq.w    #1,d6
  2429.     lea    (a0,d5.w*2),a1
  2430.  
  2431. Polygon.flatPixelInstr:
  2432. .xloop:    move.w    d4,(a1)+
  2433.     dbf    d6,.xloop
  2434.  
  2435.     ENDC
  2436.  
  2437.     adda.l    a5,a0
  2438.     add.l    d2,d0
  2439.     add.l    d3,d1
  2440.     dbf    d7,Polygon.flatFragmentYloop
  2441.     rts
  2442.  
  2443.     nop                        ; crap for code-gen
  2444.     nop
  2445.     nop
  2446.     nop
  2447.  
  2448. ; TODO: prepare this for different paintmodes! (byte, skip)
  2449. ; Subroutine that restores a fragment. NO clipping!
  2450. ; INPUT:
  2451. ; d0.l: 16:16 left X-start
  2452. ; d1.l: 16:16 right X-start
  2453. ; d2.l: 16:16 left stepvalue
  2454. ; d3.l: 16:16 right stepvalue
  2455. ; d7.w: number of scanlines to paint - 1
  2456. ; a0: dst screenline
  2457. ; a3: src screenline
  2458. ; a5: width (bytes)
  2459. ; OUTPUT:
  2460. ; a0: next dst screenline
  2461. ; a3: next src screenline
  2462. RESTORE_UNCLIPFLATFRAG:
  2463. Polygon.restoreFragmentYloop:
  2464. .yloop:    move.l    d0,d5
  2465.     move.l    d1,d6
  2466.     swap    d5
  2467.     swap    d6
  2468.  
  2469.     sub.w    d5,d6
  2470.     bgt.s    .go_on
  2471.  
  2472.     adda.l    a5,a0
  2473.     adda.l    a5,a3
  2474.     add.l    d2,d0
  2475.     add.l    d3,d1
  2476.     dbra    d7,.yloop
  2477.     rts
  2478.  
  2479. .go_on:    lea    (a0,d5.w*2),a1
  2480.     lea    (a3,d5.w*2),a3
  2481.     add.w    d6,d5
  2482.  
  2483.     IFNE    1
  2484. ; warning! this will _not_ work with code generation!!
  2485. ; seems to be fastest at the moment.
  2486.     lsr.w    d6
  2487.     bcc.s    .even
  2488.     move.w    (a3)+,(a1)+
  2489. .even:    subq.w    #1,d6
  2490.     bmi.s    .end
  2491. .loop:    move.l    (a3)+,(a1)+
  2492.     dbf    d6,.loop
  2493. .end:
  2494.  
  2495. Polygon.restorePixelInstr:            ; dummy, don't use!
  2496.     ELSE
  2497.  
  2498.     subq.w    #1,d6
  2499. Polygon.restorePixelInstr:
  2500. .xloop:    move.w    (a3)+,(a1)+
  2501.     dbf    d6,.xloop
  2502.  
  2503.     ENDC
  2504.  
  2505.     adda.l    a5,a0
  2506.     adda.l    a5,a3
  2507.     suba.w    d5,a3
  2508.     suba.w    d5,a3
  2509.     add.l    d2,d0
  2510.     add.l    d3,d1
  2511.     dbf    d7,Polygon.restoreFragmentYloop
  2512.  
  2513.     rts
  2514.  
  2515.     nop                        ; crap for code-gen
  2516.     nop
  2517.     nop
  2518.     nop
  2519.  
  2520.  
  2521.     IFNE    0
  2522.  
  2523.         RSRESET
  2524. v4EdgeXSlope:    RS.L    1
  2525. v4EdgeU0Slope:    RS.W    1
  2526. v4EdgeV0Slope:    RS.W    1
  2527. v4EdgeU1Slope:    RS.W    1
  2528. v4EdgeV1Slope:    RS.W    1
  2529. v4EdgeXStart:    RS.W    1
  2530. v4EdgeYStart:    RS.W    1
  2531. v4EdgeU0Start:    RS.W    1
  2532. v4EdgeV0Start:    RS.W    1
  2533. v4EdgeU1Start:    RS.W    1
  2534. v4EdgeV1Start:    RS.W    1
  2535. v4EdgeDY:    RS.W    1
  2536. v4EdgeSize:    RS.B    0
  2537.  
  2538. ; Subroutine that draws a v4-textured fragment to a table.
  2539. ; Vertical and horizontal clipping are NOT this routine's responsibility.
  2540. ; INPUT:
  2541. ; d0.l: 8:8:8:8 (000V) left V0-start
  2542. ; d1.l: 8:8:8:8 (000V) left V1-start
  2543. ; a5.l: 8:8:8:8 (v0Uu) left U0-step, left V0-step
  2544. ; d3.l: 8:8:8:8 (000V) left V0-step
  2545. ; a6.l: 8:8:8:8 (v0Uu) left U1-step, left V1-step
  2546. ; d5.l: 8:8:8:8 (000V) left V1-step
  2547. ; d7.w: number of scanlines to paint - 1
  2548. ; a0: startentry of scanline table
  2549. ; a1.l: 16:16 (XXxx) left X-start
  2550. ; a2.l: 16:16 (XXxx) right X-start
  2551. ; a3.l: 16:16 (XXxx) left X-step
  2552. ; a4.l: 16:16 (XXxx) right X-step
  2553. ; d2.l: 8:8:8:8 (v0Uu) left U0-start, left V0-start
  2554. ; d4.l: 8:8:8:8 (v0Uu) left U1-start, left V1-start
  2555. ; OUTPUT:
  2556. ; a0: start of next scanline entry
  2557. DRAW_V4FRAGMENT:
  2558. .scanline_loop:
  2559.     move.l    a1,d6                ;  2
  2560.     swap    d6                ;  4
  2561.     move.w    d6,(a0)+            ; ?8
  2562.     move.l    a2,d6                ;  2
  2563.     swap    d6                ;  4
  2564.     move.w    d6,(a0)+            ; ?8
  2565.     move.w    d2,(a0)+            ; ?8
  2566.     move.w    d0,(a0)+            ; ?8
  2567.     move.w    d4,(a0)+            ; ?8
  2568.     move.w    d1,(a0)+            ; ?8
  2569.     adda.l    a3,a1                ;  2
  2570.     adda.l    a4,a2                ;  2
  2571.     add.w    a5,d2                ;  2
  2572.     add.w    d3,d0                ;  2
  2573.     add.w    a6,d4                ;  2
  2574.     add.w    d5,d1                ;  2
  2575.     dbra    d7,.scanline_loop        ;  6
  2576.                         ; 74
  2577.     rts
  2578.  
  2579. ; INPUT:
  2580. ; d0.l: x0
  2581. ; d1.l: y0
  2582. ; d2.l: x1
  2583. ; d3.l: y1
  2584. ; d4.l: x2
  2585. ; d5.l: y2
  2586. ; a0: address of 1st uv-table (u0,v0,u1,v1)
  2587. ; a1: address of uv-table (u0,v0,u1,v1)
  2588. ; a2: address of uv-table (u0,v0,u1,v1)
  2589. PAINT_UNCLIPV4TRIANGLE:
  2590.     movea.l    a0,a3
  2591.     movea.l    a1,a4
  2592.     movea.l    a2,a5
  2593.  
  2594. ; d0.l: X1
  2595. ; d1.l: Y1
  2596. ; d2.l: X2
  2597. ; d3.l: Y2
  2598. ; d4.l: X3
  2599. ; d5.l: Y3
  2600. ; a3.l: address of 1st uv-table
  2601. ; a4.l: address of 2nd uv-table
  2602. ; a5.l: address of 3rd uv-table
  2603.  
  2604. ; Sort points in Y-order.
  2605. .sort_y:
  2606.     cmp.l    d1,d3
  2607.     bgt.s    .first_y_ok
  2608.     exg    d0,d2
  2609.     exg    d1,d3
  2610.     exg    a3,a4
  2611. .first_y_ok:
  2612.     cmp.l    d1,d5
  2613.     bgt.s    .first_y_ok2
  2614.     exg    d0,d4
  2615.     exg    d1,d5
  2616.     exg    a3,a5
  2617. .first_y_ok2:
  2618.     cmp.l    d3,d5
  2619.     bgt.s    .second_y_ok
  2620.     exg    d2,d4
  2621.     exg    d3,d5
  2622.     exg    a4,a5
  2623. .second_y_ok:
  2624. .end_sort_y:
  2625.  
  2626. .calc_edges:
  2627. ; X2-X1 X3-X1 X3-X2
  2628. ; Y2-Y1 Y3-Y1 Y3-Y2
  2629. ; I2-I1 I3-I1 I3-I2
  2630.  
  2631.     lea    Polygon.invTable,a6
  2632.     lea    .edges_tbl,a0
  2633.     lea    v4EdgeSize(a0),a1
  2634.     lea    v4EdgeSize(a1),a2
  2635.     move.w    d0,v4EdgeXStart(a0)
  2636.     move.w    d1,v4EdgeYStart(a0)
  2637.     move.l    d2,d6
  2638.     move.l    d3,d7
  2639.     sub.l    d0,d6
  2640.     sub.l    d1,d7
  2641.     muls.w    (a6,d7.l*2),d6
  2642.     add.l    d6,d6
  2643.     move.l    d6,v4EdgeXSlope(a0)
  2644.     move.l    (a3),v4EdgeU0Start(a0)        ; u0,v0
  2645.     move.l    4(a3),v4EdgeU1Start(a0)        ; u1,v1
  2646.     move.w    (a4)+,d6
  2647.     sub.w    (a3)+,d6
  2648.     muls.w    (a6,d7.l*2),d6
  2649.     asr.l    #7,d6
  2650.     move.w    d6,v4EdgeU0Slope(a0)
  2651.     move.w    (a4)+,d6
  2652.     sub.w    (a3)+,d6
  2653.     muls.w    (a6,d7.l*2),d6
  2654.     asr.l    #7,d6
  2655.     move.w    d6,v4EdgeV0Slope(a0)
  2656.     move.w    (a4)+,d6
  2657.     sub.w    (a3)+,d6
  2658.     muls.w    (a6,d7.l*2),d6
  2659.     asr.l    #7,d6
  2660.     move.w    d6,v4EdgeU1Slope(a0)
  2661.     move.w    (a4)+,d6
  2662.     sub.w    (a3)+,d6
  2663.     muls.w    (a6,d7.l*2),d6
  2664.     asr.l    #7,d6
  2665.     move.w    d6,v4EdgeV1Slope(a0)
  2666.     subq    #8,a3
  2667.     subq    #8,a4
  2668.     move.w    d7,v4EdgeDY(a0)
  2669.  
  2670. ;    move.w    d0,v4EdgeXStart(a1)
  2671. ;    move.w    d1,v4EdgeYStart(a1)
  2672.     move.l    d4,d6
  2673.     move.l    d5,d7
  2674.     sub.l    d0,d6
  2675.     sub.l    d1,d7
  2676.     muls.w    (a6,d7.l*2),d6
  2677.     add.l    d6,d6
  2678.     move.l    d6,v4EdgeXSlope(a1)
  2679. ;    move.l    a3,v4EdgeUStart(a1)        ; u,v
  2680.     move.w    (a5)+,d6
  2681.     sub.w    (a3)+,d6
  2682.     muls.w    (a6,d7.l*2),d6
  2683.     asr.l    #7,d6
  2684.     move.w    d6,v4EdgeU0Slope(a1)
  2685.     move.w    (a5)+,d6
  2686.     sub.w    (a3)+,d6
  2687.     muls.w    (a6,d7.l*2),d6
  2688.     asr.l    #7,d6
  2689.     move.w    d6,v4EdgeV0Slope(a1)
  2690.     move.w    (a5)+,d6
  2691.     sub.w    (a3)+,d6
  2692.     muls.w    (a6,d7.l*2),d6
  2693.     asr.l    #7,d6
  2694.     move.w    d6,v4EdgeU1Slope(a1)
  2695.     move.w    (a5)+,d6
  2696.     sub.w    (a3)+,d6
  2697.     muls.w    (a6,d7.l*2),d6
  2698.     asr.l    #7,d6
  2699.     move.w    d6,v4EdgeV1Slope(a1)
  2700.     subq    #8,a3
  2701.     subq    #8,a5
  2702. ;    move.w    d7,v4EdgeDY(a1)
  2703.  
  2704.     move.w    d2,v4EdgeXStart(a2)
  2705.     move.w    d3,v4EdgeYStart(a2)
  2706.     move.l    d4,d6
  2707.     move.l    d5,d7
  2708.     sub.l    d2,d6
  2709.     sub.l    d3,d7
  2710.     muls.w    (a6,d7.l*2),d6
  2711.     add.l    d6,d6
  2712.     move.l    d6,v4EdgeXSlope(a2)
  2713.     move.l    (a4),v4EdgeU0Start(a2)        ; u0,v0
  2714.     move.l    4(a4),v4EdgeU1Start(a2)        ; u1,v1
  2715.     move.w    (a5)+,d6
  2716.     sub.w    (a4)+,d6
  2717.     muls.w    (a6,d7.l*2),d6
  2718.     asr.l    #7,d6
  2719.     move.w    d6,v4EdgeU0Slope(a2)
  2720.     move.w    (a5)+,d6
  2721.     sub.w    (a4)+,d6
  2722.     muls.w    (a6,d7.l*2),d6
  2723.     asr.l    #7,d6
  2724.     move.w    d6,v4EdgeV0Slope(a2)
  2725.     move.w    (a5)+,d6
  2726.     sub.w    (a4)+,d6
  2727.     muls.w    (a6,d7.l*2),d6
  2728.     asr.l    #7,d6
  2729.     move.w    d6,v4EdgeU1Slope(a2)
  2730.     move.w    (a5)+,d6
  2731.     sub.w    (a4)+,d6
  2732.     muls.w    (a6,d7.l*2),d6
  2733.     asr.l    #7,d6
  2734.     move.w    d6,v4EdgeV1Slope(a2)
  2735.     subq    #8,a4
  2736.     subq    #8,a5
  2737.     move.w    d7,v4EdgeDY(a2)
  2738. .end_calc_edges:
  2739.  
  2740. ; Calculate horizontal intensity slope.
  2741. .calcslope:
  2742.     cmp.l    d1,d3
  2743.     bne.s    .not_edge1
  2744.     move.l    d2,d7
  2745.     sub.l    d0,d7
  2746.     addq.w    #1,d7
  2747.     move.w    (a4)+,d0
  2748.     sub.w    (a3)+,d0
  2749.     ext.l    d0
  2750.     lsl.l    #8,d0
  2751.     divs.w    d7,d0
  2752.     move.w    (a4)+,d1
  2753.     sub.w    (a3)+,d1
  2754.     ext.l    d1
  2755.     lsl.l    #8,d1
  2756.     divs.w    d7,d1
  2757.     move.w    (a4)+,d2
  2758.     sub.w    (a3)+,d2
  2759.     ext.l    d2
  2760.     lsl.l    #8,d2
  2761.     divs.w    d7,d2
  2762.     move.w    (a4)+,d3
  2763.     sub.w    (a3)+,d3
  2764.     ext.l    d3
  2765.     lsl.l    #8,d3
  2766.     divs.w    d7,d3
  2767.     bra    .end_calcslope
  2768. .not_edge1:
  2769.     cmp.l    d3,d5
  2770.     bne.s    .not_edge3
  2771.     move.l    d4,d7
  2772.     sub.l    d2,d7
  2773.     addq.w    #1,d7
  2774.     move.w    (a5)+,d0
  2775.     sub.w    (a4)+,d0
  2776.     ext.l    d0
  2777.     lsl.l    #8,d0
  2778.     divs.w    d7,d0
  2779.     move.w    (a5)+,d1
  2780.     sub.w    (a4)+,d1
  2781.     ext.l    d1
  2782.     lsl.l    #8,d1
  2783.     divs.w    d7,d1
  2784.     move.w    (a5)+,d2
  2785.     sub.w    (a4)+,d2
  2786.     ext.l    d2
  2787.     lsl.l    #8,d2
  2788.     divs.w    d7,d2
  2789.     move.w    (a5)+,d3
  2790.     sub.w    (a4)+,d3
  2791.     ext.l    d3
  2792.     lsl.l    #8,d3
  2793.     divs.w    d7,d3
  2794.     bra    .end_calcslope
  2795. .not_edge3:
  2796.  
  2797. ; x_intersect := Edge1Slope ; Edge0length + Edge1XStart
  2798.     move.l    v4EdgeXSlope(a1),d7
  2799.     moveq    #0,d4
  2800.     move.w    v4EdgeDY(a0),d4
  2801.     muls.l    d4,d7
  2802.     swap    d7
  2803.     add.w    v4EdgeXStart(a0),d7        a1; x_intersect
  2804. ; i_intersect := Edge1ISlope ; Edge0length + Edge1IStart
  2805.     move.w    v4EdgeU0Slope(a1),d0
  2806.     move.w    v4EdgeV0Slope(a1),d1
  2807.     move.w    v4EdgeU1Slope(a1),d2
  2808.     move.w    v4EdgeV1Slope(a1),d3
  2809.     muls.w    d4,d0
  2810.     muls.w    d4,d1
  2811.     muls.w    d4,d2
  2812.     muls.w    d4,d3
  2813.     asr.l    #8,d0
  2814.     asr.l    #8,d1
  2815.     asr.l    #8,d2
  2816.     asr.l    #8,d3
  2817.     add.w    v4EdgeU0Start(a0),d0        a1; i_intersect
  2818.     add.w    v4EdgeV0Start(a0),d1        a1
  2819.     add.w    v4EdgeU1Start(a0),d2        a1; i_intersect
  2820.     add.w    v4EdgeV1Start(a0),d3        a1
  2821. ; i_horizontalslope := (x_intersect - I2) / (x_intersect - X2)
  2822.     sub.w    v4EdgeXStart(a2),d7
  2823.     bmi.s    .fuk
  2824.     addq.w    #1,d7
  2825.     bra.s    .end_fuk
  2826. .fuk:    subq.w    #1,d7
  2827. .end_fuk:
  2828.     sub.w    v4EdgeU0Start(a2),d0
  2829.     sub.w    v4EdgeV0Start(a2),d1
  2830.     sub.w    v4EdgeU1Start(a2),d2
  2831.     sub.w    v4EdgeV1Start(a2),d3
  2832.     ext.l    d0
  2833.     ext.l    d1
  2834.     ext.l    d2
  2835.     ext.l    d3
  2836.     lsl.l    #8,d0
  2837.     lsl.l    #8,d1
  2838.     lsl.l    #8,d2
  2839.     lsl.l    #8,d3
  2840.     ext.l    d7
  2841.     beq.s    .slope0
  2842.     divs.w    d7,d0
  2843.     divs.w    d7,d1
  2844.     divs.w    d7,d2
  2845.     divs.w    d7,d3
  2846. .slope0:
  2847. .end_calcslope:
  2848.  
  2849. ; d0.w: Uu (0)
  2850. ; d1.w: Vv (0)
  2851. ; d2.w: Uu (1)
  2852. ; d3.w: Vv (1)
  2853. ; d7.l: dx
  2854.  
  2855.     movem.w    d0-d3,Polygon.uvslopes
  2856.  
  2857. ; Special case for triangles that have a horizontal edge.
  2858.     lea    .edges_tbl,a0
  2859.     tst.w    v4EdgeDY(a0)
  2860.     bne    .make_fragments
  2861.     subq    #8,a3
  2862.     move.w    v4EdgeDY(a2),d7
  2863.     subq.w    #1,d7
  2864.     bmi    .end_paint_triangle
  2865.     move.w    d7,-(sp)
  2866.     moveq    #0,d0
  2867.     move.w    v4EdgeXStart(a0),d0
  2868.     swap    d0
  2869.     moveq    #0,d1
  2870.     move.w    v4EdgeXStart(a2),d1
  2871.     swap    d1
  2872.     move.l    v4EdgeXSlope(a1),d2
  2873.     move.l    v4EdgeXSlope(a2),d3
  2874.     cmp.l    d0,d1
  2875.     bgt.s    .left_right
  2876. .right_left:
  2877.     move.l    d2,-(sp)
  2878.     move.l    d3,-(sp)
  2879.     move.l    d0,-(sp)
  2880.     move.l    d1,-(sp)
  2881.     move.w    v4EdgeU0Start(a2),d2
  2882.     lsl.w    #8,d2
  2883.     move.w    v4EdgeV0Start(a2),d0
  2884.     lsl.w    #8,d0
  2885.     move.w    v4EdgeU1Start(a2),d4
  2886.     lsl.w    #8,d4
  2887.     move.w    v4EdgeV1Start(a2),d1
  2888.     lsl.w    #8,d1
  2889.     move.w    v4EdgeU0Slope(a2),a5
  2890.     move.w    v4EdgeV0Slope(a2),d3
  2891.     move.w    v4EdgeU1Slope(a2),a6
  2892.     move.w    v4EdgeV1Slope(a2),d5
  2893.     bra.s    .start_x_okay
  2894. .left_right:
  2895.     move.l    d3,-(sp)
  2896.     move.l    d2,-(sp)
  2897.     move.l    d1,-(sp)
  2898.     move.l    d0,-(sp)
  2899.     move.w    v4EdgeU0Slope(a1),a5
  2900.     move.w    v4EdgeV0Slope(a1),d3
  2901.     move.w    v4EdgeU1Slope(a1),a6
  2902.     move.w    v4EdgeV1Slope(a1),d5
  2903.     move.w    (a3)+,d2    v4EdgeU0Start(a1),d2
  2904.     lsl.l    #8,d2
  2905.     move.w    (a3)+,d0    v4EdgeV0Start(a1),d3
  2906.     lsl.w    #8,d0
  2907.     move.w    (a3)+,d4    v4EdgeU1Start(a1),d2
  2908.     lsl.w    #8,d4
  2909.     move.w    (a3)+,d1    v4EdgeV1Start(a1),d3
  2910.     lsl.w    #8,d1
  2911. .start_x_okay:
  2912.     movem.l    (sp)+,a1-a4
  2913.     move.w    v4EdgeYStart(a0),-(sp)
  2914.     lea    Polygon.scanlineTable,a0
  2915.     bsr    DRAW_V4FRAGMENT
  2916.      bra    .end_draw_fragments
  2917.  
  2918. .make_fragments:
  2919.     move.l    v4EdgeXSlope(a0),d0
  2920.     move.l    v4EdgeXSlope(a1),d1
  2921.     cmp.l    d0,d1
  2922.     blt    .make_fragments_rl
  2923.  
  2924. ; a0 /\ a1
  2925. ;      \
  2926. .make_fragments_lr:
  2927. ; Create upper fragment..
  2928.     movea.l    a2,a6
  2929.     move.w    v4EdgeDY(a0),d7
  2930.     subq.w    #1,d7
  2931.     move.w    d7,-(sp)
  2932.     move.w    v4EdgeYStart(a0),-(sp)
  2933.     tst.w    d7
  2934.     bmi.s    .lr_skip_upper
  2935.     move.l    a6,-(sp)
  2936.     move.l    d0,a3
  2937.     move.l    d1,a4
  2938.     moveq    #0,d0
  2939.     move.w    v4EdgeXStart(a0),d0
  2940.     swap    d0
  2941.     movea.l    d0,a1
  2942.     movea.l    d0,a2
  2943.     move.w    v4EdgeU0Start(a0),d2
  2944.     lsl.w    #8,d2
  2945.     move.w    v4EdgeV0Start(a0),d0
  2946.     lsl.w    #8,d0
  2947.     move.w    v4EdgeU1Start(a0),d4
  2948.     lsl.w    #8,d4
  2949.     move.w    v4EdgeV1Start(a0),d1
  2950.     lsl.w    #8,d1
  2951.     move.w    v4EdgeU0Slope(a0),a5
  2952.     move.w    v4EdgeV0Slope(a0),d3
  2953.     move.w    v4EdgeU1Slope(a0),a6
  2954.     move.w    v4EdgeV1Slope(a0),d5
  2955.     lea    Polygon.scanlineTable,a0
  2956.     bsr    DRAW_V4FRAGMENT
  2957.     movea.l    (sp)+,a6
  2958. .lr_skip_upper:
  2959.  
  2960. ; Create lower fragment..
  2961.     move.w    v4EdgeDY(a6),d7
  2962.     add.w    d7,2(sp)
  2963.     moveq    #0,d0
  2964.     move.w    v4EdgeXStart(a6),d0
  2965.     swap    d0
  2966.     movea.l    d0,a1
  2967.     movea.l    v4EdgeXSlope(a6),a3
  2968.     move.w    v4EdgeU0Start(a6),d2
  2969.     lsl.w    #8,d2
  2970.     move.w    v4EdgeV0Start(a6),d0
  2971.     lsl.w    #8,d0
  2972.     move.w    v4EdgeU1Start(a6),d4
  2973.     lsl.w    #8,d4
  2974.     move.w    v4EdgeV1Start(a6),d1
  2975.     lsl.w    #8,d1
  2976.     move.w    v4EdgeU0Slope(a6),a5
  2977.     move.w    v4EdgeV0Slope(a6),d3
  2978.     move.w    v4EdgeV1Slope(a6),d5
  2979.     move.w    v4EdgeU1Slope(a6),a6
  2980.     subq.w    #1,d7
  2981.     bmi.s    .lr_skip_lower
  2982.     bsr    DRAW_V4FRAGMENT
  2983. .lr_skip_lower:
  2984.      bra    .end_draw_fragments
  2985.  
  2986. .make_fragments_rl:
  2987. ; Create upper fragment..
  2988.     movea.l    d0,a4
  2989.     movea.l    d1,a3
  2990.     move.w    v4EdgeDY(a0),d7
  2991.     subq.w    #1,d7
  2992.     move.w    d7,-(sp)
  2993.     move.w    v4EdgeYStart(a0),-(sp)
  2994.     tst.w    d7
  2995.     bmi.s    .rl_skip_upper
  2996.     move.l    a2,-(sp)
  2997.     moveq    #0,d6
  2998.     move.w    v4EdgeXStart(a0),d6
  2999.     swap    d6
  3000.     movea.l    d6,a2
  3001.     move.w    v4EdgeU0Start(a0),d2
  3002.     lsl.w    #8,d2
  3003.     move.w    v4EdgeV0Start(a0),d0
  3004.     lsl.w    #8,d0
  3005.     move.w    v4EdgeU1Start(a0),d4
  3006.     lsl.w    #8,d4
  3007.     move.w    v4EdgeV1Start(a0),d1
  3008.     lsl.w    #8,d1
  3009.     move.w    v4EdgeU0Slope(a1),a5
  3010.     move.w    v4EdgeV0Slope(a1),d3
  3011.     move.w    v4EdgeU1Slope(a1),a6
  3012.     move.w    v4EdgeV1Slope(a1),d5
  3013.     movea.l    a2,a1
  3014.     lea    Polygon.scanlineTable,a0
  3015.     bsr    DRAW_V4FRAGMENT
  3016.     movea.l    (sp)+,a2
  3017. .rl_skip_upper:
  3018.  
  3019. ; Create lower fragment..
  3020.     move.w    v4EdgeDY(a2),d7
  3021.     add.w    d7,2(sp)
  3022.     moveq    #0,d6
  3023.     move.w    v4EdgeXStart(a2),d6
  3024.     swap    d6
  3025.     movea.l    v4EdgeXSlope(a2),a4
  3026.     movea.l    d6,a2
  3027.     subq.w    #1,d7
  3028.     bmi.s    .rl_skip_lower
  3029.     bsr    DRAW_V4FRAGMENT
  3030. .rl_skip_lower:
  3031. .end_draw_fragments:
  3032.  
  3033.     movea.l    Primitive.screenadr,a0
  3034.     move.w    (sp)+,d0                ; Get Y start of triangle.
  3035.     mulu.w    Viewport.settingsTable+Viewport.XSCREEN,d0
  3036.     add.l    d0,d0
  3037.     adda.l    d0,a0
  3038.     lea    Polygon.scanlineTable,a1
  3039.     move.w    (sp)+,d7
  3040.     bmi.s    .end_paint_triangle
  3041.     movea.l    Polygon.v4routadr,a3
  3042.     movem.w    Polygon.uvslopes,d0-d3
  3043.     ror.l    #8,d1
  3044.     move.l    d1,d4
  3045.     move.w    d0,d4
  3046.     movea.l    d4,a2
  3047.     ror.l    #8,d3
  3048.     move.l    d3,d4
  3049.     move.w    d2,d4
  3050.     movea.l    d4,a5
  3051.     move.w    d3,d6
  3052.     swap    d6
  3053.     move.w    d1,d6
  3054.     jmp    (a3)
  3055.  
  3056. .end_paint_triangle:
  3057.     rts
  3058.  
  3059.     BSS
  3060.  
  3061. .edges_tbl:
  3062.     DS.B    v4EdgeSize*3
  3063.  
  3064.     TEXT
  3065.     
  3066. ; Draws a mixed-texture triangle to the screen.
  3067. ; Horizontal clipping is implemented.
  3068. ; INPUT: a0: start screenline
  3069. ;        a1: start entry in scanline table
  3070. ;        d7.w: number of scanlines to paint - 1
  3071. PAINT_UNCLIPALPHASCANS:
  3072.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d0
  3073.     add.w    d0,d0
  3074.     move.w    d0,-(sp)
  3075.     movem.l    Polygon.curtexture,a3/a4
  3076.     movea.l    Polygon.alphatableadr,a6
  3077.  
  3078. .paint_yloop:
  3079.     swap    d7
  3080.     move.l    a0,-(sp)
  3081.     movem.w    (a1)+,d0/d1
  3082.     lea    (a0,d0.l*2),a0
  3083.     sub.w    d0,d1
  3084.     moveq    #0,d2
  3085.     move.w    (a1)+,d0
  3086.     move.w    (a1)+,d2
  3087.     ror.l    #8,d2
  3088.     move.l    d2,d4
  3089.     move.w    d0,d4
  3090.     move.w    (a1)+,d0
  3091.     move.w    (a1)+,d3
  3092.     ror.l    #8,d3
  3093.     move.l    d3,d5
  3094.     move.w    d0,d5
  3095.     subq.w    #1,d1
  3096.     bmi.s    .end_paint_yloop
  3097.  
  3098. .paint_xloop:
  3099.     move.w    d4,d0
  3100.     add.l    a2,d4
  3101.     move.b    d2,d0
  3102.     addx.b    d6,d2
  3103.     move.w    (a3,d0.l),d7
  3104.     move.w    d5,d0
  3105.     add.l    a5,d5
  3106.     move.b    d3,d0
  3107.     swap    d6
  3108.     addx.b    d6,d3
  3109.     swap    d6
  3110.     move.b    (a4,d0.l),d7
  3111.     move.w    (a6,d7.w*2),(a0)+
  3112.     dbra    d1,.paint_xloop
  3113.  
  3114. .end_paint_yloop:
  3115.     movea.l    (sp)+,a0
  3116.     adda.w    (sp),a0
  3117.     swap    d7
  3118.     dbra    d7,.paint_yloop
  3119.     addq    #2,sp
  3120.     rts
  3121.  
  3122. ; Draws a bump-textured triangle to the screen.
  3123. ; Horizontal clipping is implemented.
  3124. ; INPUT: a0: start screenline
  3125. ;        a1: start entry in scanline table
  3126. ;        d7.w: number of scanlines to paint - 1
  3127. PAINT_UNCLIPBUMPSCANS:
  3128.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d0
  3129.     add.w    d0,d0
  3130.     move.w    d0,-(sp)
  3131.     movem.l    Polygon.curtexture,a3/a4
  3132.  
  3133. .paint_yloop:
  3134.     swap    d7
  3135.     move.l    a0,-(sp)
  3136.     movem.w    (a1)+,d0/d1
  3137.     lea    (a0,d0.l*2),a0
  3138.     sub.w    d0,d1
  3139.     moveq    #0,d2
  3140.     move.w    (a1)+,d0
  3141.     move.w    (a1)+,d2
  3142.     ror.l    #8,d2
  3143.     move.l    d2,d4
  3144.     move.w    d0,d4
  3145.     move.w    (a1)+,d0
  3146.     move.w    (a1)+,d3
  3147.     ror.l    #8,d3
  3148.     move.l    d3,d5
  3149.     move.w    d0,d5
  3150.     subq.w    #1,d1
  3151.     bmi.s    .end_paint_yloop
  3152.  
  3153. .paint_xloop:
  3154.     move.w    d4,d0
  3155.     add.l    a2,d4
  3156.     move.b    d2,d0
  3157.     addx.b    d6,d2
  3158.     move.w    (a4,d0.l*2),d7
  3159.     move.w    d5,d0
  3160.     add.l    a5,d5
  3161.     move.b    d3,d0
  3162.     swap    d6
  3163.     addx.b    d6,d3
  3164.     swap    d6
  3165.     add.w    d7,d0
  3166.     move.w    (a3,d0.l*2),(a0)+
  3167.     dbra    d1,.paint_xloop
  3168.  
  3169. .end_paint_yloop:
  3170.     movea.l    (sp)+,a0
  3171.     adda.w    (sp),a0
  3172.     swap    d7
  3173.     dbra    d7,.paint_yloop
  3174.     addq    #2,sp
  3175.     rts
  3176.  
  3177.     ENDC
  3178.  
  3179. ;======= Sprite
  3180.  
  3181. Sprite.routTable:
  3182.     DC.L    Sprite.paintMoved
  3183.     DC.L    Sprite.paintOrred
  3184.     DC.L    Sprite.paintAdded
  3185.     DC.L    Sprite.paintceilAdded
  3186.  
  3187. ; INPUT:
  3188. ; a1: sprite structure
  3189. ; a2: vertex table
  3190. Sprite.paint:
  3191.     lea    Polygon.textureTable,a0
  3192.     move.w    Primitive.SPRITETYPE(a1),d0
  3193.     andi.w    #Primitive.TEXTUREMASK,d0
  3194.     movea.l    (a0,d0.w*4),a0
  3195. ; a0: address of sprite-data.
  3196.     move.w    Sprite.VERTEX(a1),d0
  3197.     mulu.w    #Vertex.SIZE,d0
  3198.     movem.w    4(a2,d0.l),d0-d2
  3199. ; d0.l: X
  3200. ; d1.l: Y
  3201. ; d2.l: Z
  3202.     movea.l    a0,a1
  3203.     bra.w    Sprite.clipAndPaint
  3204.  
  3205. Sprite.paintReceived:
  3206.     lea    Polygon.textureTable,a0
  3207.     receiveWordFromDsp    d0
  3208.     andi.w    #Primitive.TEXTUREMASK,d0
  3209.     movea.l    (a0,d0.w*4),a0
  3210. ; a0: address of sprite-data.
  3211.     receiveWordFromDsp    d1
  3212.     receiveWordFromDsp    d0
  3213.     receiveWordFromDsp    d2
  3214.     ext.l    d0
  3215.     ext.l    d1
  3216.     ext.l    d2
  3217. ; d0.l: X
  3218. ; d1.l: Y
  3219. ; d2.l: Z
  3220.     movea.l    a0,a1
  3221.     bra.w    Sprite.clipAndPaint
  3222.  
  3223. ; Paints a highcolor rle sprite to the screen.
  3224. ; This handles horizontal and vertical clipping as well.
  3225. ; INPUT:
  3226. ; d0.w: x position (mid)
  3227. ; d1.w: y position (mid)
  3228. ; a1: sprite
  3229. Sprite.clipAndPaint:
  3230.     movea.l    Primitive.screenadr,a0
  3231.     movea.w    Viewport.settingsTable+Viewport.XSCREEN,a6
  3232.     adda.l    a6,a6
  3233.     move.w    (a1)+,d6            ; width of sprite
  3234.     move.w    (a1)+,d7            ; height of sprite
  3235.     move.w    d6,d4
  3236.     lsr.w    #1,d4
  3237.     sub.w    d4,d0
  3238.     move.w    d7,d4
  3239.     lsr.w    #1,d4
  3240.     sub.w    d4,d1
  3241.     movem.w    Viewport.settingsTable+Viewport.XSTART,d4/d5/a4/a5
  3242.     movea.l    a1,a3
  3243.     lea    (a1,d7.w*2),a1
  3244.  
  3245. ; d0.w: left x coordinate of sprite
  3246. ; d1.w: top y coordinate of sprite
  3247. ; d6.w: width of sprite
  3248. ; d7.w: height of sprite
  3249.  
  3250. .clip_bottom:
  3251.     cmp.w    a5,d1                ; YEnd
  3252.     bge    .end                ; Beneath bottom?
  3253.     move.w    d1,d2
  3254.     add.w    d7,d2                ; d2 := bottom line of sprite
  3255.     cmp.w    a5,d2
  3256.     blt.s    .end_clip_bottom
  3257.     move.w    d2,d3
  3258.     sub.w    a5,d3
  3259.     sub.w    d3,d7
  3260. .end_clip_bottom:
  3261.  
  3262. .clip_top:
  3263.     cmp.w    a4,d1                ; YStart
  3264.     bge.s    .end_clip_top    
  3265.     cmp.w    a4,d2
  3266.     ble    .end                ; Above top?
  3267.     move.w    d2,d7
  3268.     sub.w    a4,d7
  3269.     sub.w    a4,d1
  3270.     neg.w    d1
  3271.     lea    (a3,d1.w*2),a3
  3272.     move.w    a4,d1
  3273. .end_clip_top:
  3274.  
  3275. ; d1.w: top y coordinate of sprite
  3276. ; d7.w: height of sprite
  3277.  
  3278. .clip_left:
  3279.     moveq    #0,d3
  3280.     move.w    d0,d2
  3281.     add.w    d6,d2                ; d2 := left x of sprite
  3282.     cmp.w    d4,d0                ; XStart
  3283.     bgt.s    .end_clip_left
  3284.     cmp.w    d4,d2                ; XStart
  3285.     ble    .end                ; Left of viewport?
  3286.     move.w    d0,d3
  3287.     sub.w    d4,d3
  3288.     neg.w    d3
  3289.     move.w    d4,d0
  3290. .end_clip_left:
  3291.  
  3292. .clip_right:
  3293.     cmp.w    d5,d0                ; XEnd
  3294.     bge    .end                ; Right of viewport?
  3295.     cmp.w    d5,d2
  3296.     ble.s    .end_clip_right
  3297.     sub.w    d5,d2
  3298.     sub.w    d2,d6
  3299. .end_clip_right:
  3300.  
  3301.     movea.l    Sprite.rout,a5
  3302.     jsr    (a5)
  3303.  
  3304. .end:    rts
  3305.  
  3306. ; d0.w= left x coordinate of sprite
  3307. ; d3.w= #left pixels to skip
  3308. ; d6.w= #pixels in spriteline
  3309. Sprite.paintMoved:
  3310.     move.w    d3,d2                ; d2.w=left skip pixels
  3311.     move.l    a6,d5
  3312.     mulu.w    d1,d5
  3313.     adda.l    d5,a0
  3314.     lea    (a0,d0.w*2),a0
  3315.     subq.w    #1,d7
  3316.     move.w    #$7fff,d0
  3317.     clr.l    d1
  3318.     clr.l    d3
  3319.  
  3320. .yloop:    move.w    (a3)+,d1
  3321.     lea    (a1,d1.l),a4
  3322.     movea.l    a0,a2
  3323.     moveq    #0,d5                ; d5.l=linesize=0
  3324.  
  3325. .skip_blocks:
  3326.     tst.w    d2
  3327.     beq.s    .end_handle_leftover
  3328.  
  3329. .skip_block_loop:
  3330.     move.w    (a4)+,d4
  3331.     move.w    d4,d3
  3332.     and.w    d0,d3                ; d3.w=blocksize
  3333.     add.w    d3,d5                ; linesize := linesize + blocksize
  3334.     cmp.w    d5,d2                ; linesize > left skip pixels? (=> on screen?)
  3335.     ble.s    .end_skip_blocks
  3336.     cmp.w    d0,d4
  3337.     blo.s    .skip_unmasked
  3338. .skip_masked:
  3339.     lea    (a4,d3.l*2),a4            ; Skip <d3> pixels.
  3340. .skip_unmasked:
  3341.     bra.s    .skip_block_loop
  3342. .end_skip_blocks:
  3343.  
  3344. .handle_leftover:
  3345.     move.w    d5,d1
  3346.     sub.w    d2,d1                ; d1.w=linesize-left_skip_pixels=leftover
  3347.     cmp.w    d0,d4
  3348.     blo.s    .leftover_unmasked
  3349. .leftover_masked:
  3350.     sub.w    d1,d3                ; d3.w=blocksize-block_leftover=block_skip
  3351.     lea    (a4,d3.l*2),a4            ; Skip block_skip pixels in data.
  3352.     ble.s    .end_handle_leftover
  3353.     subq.w    #1,d1
  3354.     bmi.s    .block_loop
  3355. .leftover_loop:
  3356.     move.w    (a4)+,(a2)+
  3357.     dbf    d1,.leftover_loop
  3358.     bra.s    .end_handle_leftover
  3359. .leftover_unmasked:
  3360.     lea    (a2,d1.l*2),a2            ; Skip leftover pixels on screen.
  3361. .end_handle_leftover:
  3362.  
  3363. .block_loop:
  3364.     move.w    (a4)+,d4
  3365.     move.w    d4,d3
  3366.     and.w    d0,d3
  3367.     add.w    d3,d5                ; linesize := linesize + blocksize
  3368.     cmp.w    d5,d6
  3369.     ble.s    .end_block_loop
  3370.     cmp.w    d0,d4
  3371.     blo.s    .unmasked
  3372. .masked:subq.w    #1,d3
  3373. .masked_loop:
  3374.     move.w    (a4)+,(a2)+
  3375.     dbf    d3,.masked_loop
  3376.     bra.s    .next_block
  3377. .unmasked:
  3378.     lea    (a2,d3.l*2),a2            ; Skip <d3> pixels.
  3379. .next_block:
  3380.     bra.s    .block_loop
  3381. .end_block_loop:
  3382.  
  3383. ; Not left-over, but "right-over", get it? RIght-Over?!? Ghweheheheh.
  3384. .handle_rightover:
  3385.     sub.w    d6,d5
  3386.     beq.s    .rightover_ok
  3387.     sub.w    d5,d3
  3388.     beq.s    .end_handle_rightover
  3389. .rightover_ok:
  3390.     cmp.w    d0,d4
  3391.     blo.s    .rightover_unmasked
  3392. .rightover_masked:
  3393.     subq.w    #1,d3
  3394. .rightover_masked_loop:
  3395.     move.w    (a4)+,(a2)+
  3396.     dbf    d3,.rightover_masked_loop
  3397. .rightover_unmasked:
  3398. .end_handle_rightover:
  3399.  
  3400. .next_line:
  3401.     adda.l    a6,a0
  3402.     dbf    d7,.yloop
  3403.  
  3404. .end:    rts
  3405.  
  3406. ; d0.w: left x coordinate of sprite
  3407. ; d3.w: number of left pixels to skip
  3408. ; d6.w: number of pixels in spriteline
  3409. Sprite.paintAdded:
  3410.     move.w    d3,d2
  3411.     move.l    a6,d5
  3412.     mulu.w    d1,d5
  3413.     adda.l    d5,a0
  3414.     lea    (a0,d0.w*2),a0
  3415.     subq.w    #1,d7
  3416.     move.w    #$7fff,d0
  3417.     move.w    #%0111101111101111,d4
  3418.  
  3419. .yloop:    moveq    #0,d1
  3420.     move.w    (a3)+,d1
  3421.     lea    (a1,d1.w),a4
  3422.     movea.l    a0,a2
  3423.     moveq    #0,d5                ; linesize := 0
  3424.  
  3425. .skip_blocks:
  3426.     tst.w    d2
  3427.     beq.s    .end_handle_leftover
  3428.  
  3429. .skip_block_loop:
  3430.     move.w    (a4)+,a5
  3431.     move.w    a5,d3
  3432.     and.w    d0,d3
  3433.     add.w    d3,d5                ; linesize := linesize + blocksize
  3434.     cmp.w    d5,d2
  3435.     ble.s    .end_skip_blocks
  3436.     cmp.w    d0,a5
  3437.     blo.s    .skip_unmasked
  3438. .skip_masked:
  3439.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3440. .skip_unmasked:
  3441.     bra.s    .skip_block_loop
  3442. .end_skip_blocks:
  3443.  
  3444. .handle_leftover:
  3445.     move.w    d5,d1
  3446.     sub.w    d2,d1
  3447.     cmp.w    d0,a5
  3448.     blo.s    .leftover_unmasked
  3449. .leftover_masked:
  3450.     sub.w    d1,d3
  3451.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3452.     subq.w    #1,d1
  3453.     bmi.s    .end_handle_leftover
  3454. .leftover_loop:
  3455.     move.w    (a2),d3
  3456.     lsr.w    #1,d3
  3457.     and.w    d4,d3
  3458.     add.w    (a4)+,d3
  3459.     move.w    d3,(a2)+
  3460.     dbra    d1,.leftover_loop
  3461.     bra.s    .end_handle_leftover
  3462. .leftover_unmasked:
  3463.     lea    (a2,d1.w*2),a2            ; Skip <d1> pixels.
  3464. .end_handle_leftover:
  3465.  
  3466. .block_loop:
  3467.     move.w    (a4)+,a5
  3468.     move.w    a5,d3
  3469.     and.w    d0,d3
  3470.     add.w    d3,d5                ; linesize := linesize + blocksize
  3471.     cmp.w    d5,d6
  3472.     ble.s    .end_block_loop
  3473.     cmp.w    d0,a5
  3474.     blo.s    .unmasked
  3475. .masked:
  3476.     subq.w    #1,d3
  3477. .masked_loop:
  3478.     move.w    (a2),d1
  3479.     lsr.w    #1,d1
  3480.     and.w    d4,d1
  3481.     add.w    (a4)+,d1
  3482.     move.w    d1,(a2)+
  3483.     dbra    d3,.masked_loop
  3484.     bra.s    .next_block
  3485. .unmasked:
  3486.     lea    (a2,d3.w*2),a2            ; Skip <d3> pixels.
  3487. .next_block:
  3488.     bra.s    .block_loop
  3489. .end_block_loop:
  3490.  
  3491. ; Not left-over, but "right-over", get it? RIght-Over?!? Ghweheheheh.
  3492. .handle_rightover:
  3493.     sub.w    d6,d5
  3494.     beq.s    .rightover_ok
  3495.     sub.w    d5,d3
  3496.     beq.s    .end_handle_rightover
  3497. .rightover_ok:
  3498.     cmp.w    d0,a5
  3499.     blo.s    .rightover_unmasked
  3500. .rightover_masked:
  3501.     subq.w    #1,d3
  3502. .rightover_masked_loop:
  3503.     move.w    (a2),d1
  3504.     lsr.w    #1,d1
  3505.     and.w    d4,d1
  3506.     add.w    (a4)+,d1
  3507.     move.w    d1,(a2)+
  3508.     dbra    d3,.rightover_masked_loop
  3509. .rightover_unmasked:
  3510. .end_handle_rightover:
  3511.  
  3512. .next_line:
  3513.     adda.l    a6,a0
  3514.     dbra    d7,.yloop
  3515.  
  3516. .end:    rts
  3517.  
  3518. ; d0.w: left x coordinate of sprite
  3519. ; d3.w: number of left pixels to skip
  3520. ; d6.w: number of pixels in spriteline
  3521. Sprite.paintOrred:
  3522.     move.w    d3,d2
  3523.     move.l    a6,d5
  3524.     mulu.w    d1,d5
  3525.     adda.l    d5,a0
  3526.     lea    (a0,d0.w*2),a0
  3527.     subq.w    #1,d7
  3528.     move.w    #$7fff,d0
  3529.  
  3530. .yloop:    moveq    #0,d1
  3531.     move.w    (a3)+,d1
  3532.     lea    (a1,d1.w),a4
  3533.     movea.l    a0,a2
  3534.     moveq    #0,d5                ; linesize := 0
  3535.  
  3536. .skip_blocks:
  3537.     tst.w    d2
  3538.     beq.s    .end_handle_leftover
  3539.  
  3540. .skip_block_loop:
  3541.     move.w    (a4)+,a5
  3542.     move.w    a5,d3
  3543.     and.w    d0,d3
  3544.     add.w    d3,d5                ; linesize := linesize + blocksize
  3545.     cmp.w    d5,d2
  3546.     ble.s    .end_skip_blocks
  3547.     cmp.w    d0,a5
  3548.     blo.s    .skip_unmasked
  3549. .skip_masked:
  3550.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3551. .skip_unmasked:
  3552.     bra.s    .skip_block_loop
  3553. .end_skip_blocks:
  3554.  
  3555. .handle_leftover:
  3556.     move.w    d5,d1
  3557.     sub.w    d2,d1
  3558.     cmp.w    d0,a5
  3559.     blo.s    .leftover_unmasked
  3560. .leftover_masked:
  3561.     sub.w    d1,d3
  3562.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3563.     subq.w    #1,d1
  3564.     bmi.s    .end_handle_leftover
  3565. .leftover_loop:
  3566.     move.w    (a4)+,d3
  3567.     or.w    d3,(a2)+
  3568.     dbf    d1,.leftover_loop
  3569.     bra.s    .end_handle_leftover
  3570. .leftover_unmasked:
  3571.     lea    (a2,d1.w*2),a2            ; Skip <d1> pixels.
  3572. .end_handle_leftover:
  3573.  
  3574. .block_loop:
  3575.     move.w    (a4)+,a5
  3576.     move.w    a5,d3
  3577.     and.w    d0,d3
  3578.     add.w    d3,d5                ; linesize := linesize + blocksize
  3579.     cmp.w    d5,d6
  3580.     ble.s    .end_block_loop
  3581.     cmp.w    d0,a5
  3582.     blo.s    .unmasked
  3583. .masked:
  3584.     subq.w    #1,d3
  3585. .masked_loop:
  3586.     move.w    (a4)+,d1
  3587.     or.w    d1,(a2)+
  3588.     dbf    d3,.masked_loop
  3589.     bra.s    .next_block
  3590. .unmasked:
  3591.     lea    (a2,d3.w*2),a2            ; Skip <d3> pixels.
  3592. .next_block:
  3593.     bra.s    .block_loop
  3594. .end_block_loop:
  3595.  
  3596. ; Not left-over, but "right-over", get it? RIght-Over?!? Ghweheheheh.
  3597. .handle_rightover:
  3598.     sub.w    d6,d5
  3599.     beq.s    .rightover_ok
  3600.     sub.w    d5,d3
  3601.     beq.s    .end_handle_rightover
  3602. .rightover_ok:
  3603.     cmp.w    d0,a5
  3604.     blo.s    .rightover_unmasked
  3605. .rightover_masked:
  3606.     subq.w    #1,d3
  3607. .rightover_masked_loop:
  3608.     move.w    (a4)+,d1
  3609.     or.w    d1,(a2)+
  3610.     dbf    d3,.rightover_masked_loop
  3611. .rightover_unmasked:
  3612. .end_handle_rightover:
  3613.  
  3614. .next_line:
  3615.     adda.l    a6,a0
  3616.     dbra    d7,.yloop
  3617.  
  3618. .end:    rts
  3619.  
  3620. ; d0.w: left x coordinate of sprite
  3621. ; d3.w: number of left pixels to skip
  3622. ; d6.w: number of pixels in spriteline
  3623. Sprite.paintceilAdded:
  3624.     clr.l    d2
  3625.     move.w    d3,d2
  3626.     move.l    a6,d5
  3627.     mulu.w    d1,d5
  3628.     adda.l    d5,a0
  3629.     lea    (a0,d0.w*2),a0
  3630.     subq.w    #1,d7
  3631.     move.w    #$7fff,d0
  3632.  
  3633. .yloop:    move.w    d7,-(sp)
  3634.     move.w    (a3)+,d1
  3635.     lea    (a1,d1.w),a4
  3636.     movea.l    a0,a2
  3637.     clr.l    d5                ; linesize := 0
  3638.     movem.l    a1/a3,-(sp)
  3639.     move.w    d2,-(sp)
  3640.     lea    Primitive.msbMixTable,a3
  3641.     lea    Primitive.lsbMixTable,a1
  3642.  
  3643. .skip_blocks:
  3644.     tst.w    d2
  3645.     beq.s    .end_handle_leftover
  3646.  
  3647. .skip_block_loop:
  3648.     move.w    (a4)+,a5
  3649.     move.w    a5,d3
  3650.     and.w    d0,d3
  3651.     add.w    d3,d5                ; linesize := linesize + blocksize
  3652.     cmp.w    d5,d2
  3653.     ble.s    .end_skip_blocks
  3654.     cmp.w    d0,a5
  3655.     blo.s    .skip_unmasked
  3656. .skip_masked:
  3657.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3658. .skip_unmasked:
  3659.     bra.s    .skip_block_loop
  3660. .end_skip_blocks:
  3661.  
  3662. .handle_leftover:
  3663.     move.w    d5,d1
  3664.     sub.w    d2,d1
  3665.     cmp.w    d0,a5
  3666.     blo.s    .leftover_unmasked
  3667. .leftover_masked:
  3668.     sub.w    d1,d3
  3669.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3670.     subq.w    #1,d1
  3671.     bmi.s    .end_handle_leftover
  3672. .leftover_loop:
  3673.  
  3674.     IFNE    1
  3675. ; rgb
  3676.     move.w    (a4)+,d2
  3677.     move.l    d2,d7
  3678.     move.w    (a2),d3
  3679.     move.b    (a2),d2                ; d2.w=src_msb<<8+dest_msb
  3680.     move.b    (a3,d2.l),(a2)+            ; Store res_msb.
  3681.     lsl.w    #8,d7
  3682.     move.b    d3,d7                ; d7.w=src_lsb<<8+dest_lsb
  3683.     move.b    (a1,d7.l),(a2)+
  3684.  
  3685.     ELSE
  3686.  
  3687.     move.w    (a2),d3
  3688.     add.w    (a4)+,d3
  3689.     scs.b    d4
  3690.     ext.w    d4
  3691.     or.w    d4,d3
  3692.     move.w    d3,(a2)+
  3693.  
  3694.     ENDC
  3695.  
  3696.     dbf    d1,.leftover_loop
  3697.     bra.s    .end_handle_leftover
  3698. .leftover_unmasked:
  3699.     lea    (a2,d1.w*2),a2            ; Skip <d1> pixels.
  3700. .end_handle_leftover:
  3701.  
  3702. .block_loop:
  3703.     move.w    (a4)+,a5
  3704.     move.w    a5,d3
  3705.     and.w    d0,d3
  3706.     add.w    d3,d5                ; linesize := linesize + blocksize
  3707.     cmp.w    d5,d6
  3708.     ble.s    .end_block_loop
  3709.     cmp.w    d0,a5
  3710.     blo.s    .unmasked
  3711. .masked:
  3712.     subq.w    #1,d3
  3713. .masked_loop:
  3714. ; in use: d0,d3,d5,d6,d7,a0,a1,a2,a4,a6
  3715.  
  3716.     IFNE    0
  3717.  
  3718. ; linear
  3719.     move.w    (a2),d1
  3720.     add.w    (a4)+,d1
  3721.     scs.b    d4
  3722.     ext.w    d4
  3723.     or.w    d4,d1
  3724.     move.w    d1,(a2)+
  3725.  
  3726.     ELSE
  3727.  
  3728. ; rgb
  3729.     move.w    (a4)+,d2
  3730.     move.l    d2,d7
  3731.     move.w    (a2),d1
  3732.     move.b    (a2),d2                ; d2.w=src_msb<<8+dest_msb
  3733.     move.b    (a3,d2.l),(a2)+            ; Store res_msb.
  3734.     lsl.w    #8,d7
  3735.     move.b    d1,d7                ; d7.w=src_lsb<<8+dest_lsb
  3736.     move.b    (a1,d7.l),(a2)+
  3737.  
  3738.     ENDC
  3739.     dbf    d3,.masked_loop
  3740.     bra.s    .next_block
  3741. .unmasked:
  3742.     lea    (a2,d3.w*2),a2            ; Skip <d3> pixels.
  3743. .next_block:
  3744.     bra.s    .block_loop
  3745. .end_block_loop:
  3746.  
  3747. ; Not left-over, but "right-over", get it? RIght-Over?!? Ghweheheheh.
  3748. .handle_rightover:
  3749.     sub.w    d6,d5
  3750.     beq.s    .rightover_ok
  3751.     sub.w    d5,d3
  3752.     beq.s    .end_handle_rightover
  3753. .rightover_ok:
  3754.     cmp.w    d0,a5
  3755.     blo.s    .rightover_unmasked
  3756. .rightover_masked:
  3757.     subq.w    #1,d3
  3758. .rightover_masked_loop:
  3759.  
  3760.     IFNE    1
  3761.  
  3762. ; rgb ceiladd!
  3763.     move.w    (a4)+,d2
  3764.     move.l    d2,d7
  3765.     move.w    (a2),d1
  3766.     move.b    (a2),d2                ; d2.w=src_msb<<8+dest_msb
  3767.     move.b    (a3,d2.l),(a2)+            ; Store res_msb.
  3768.     lsl.w    #8,d7
  3769.     move.b    d1,d7                ; d7.w=src_lsb<<8+dest_lsb
  3770.     move.b    (a1,d7.l),(a2)+
  3771.  
  3772.     ELSE
  3773.  
  3774. ; linear ceiladd!
  3775.     move.w    (a2),d1
  3776.     add.w    (a4)+,d1
  3777.     scs.b    d4
  3778.     ext.w    d4
  3779.     or.w    d4,d1
  3780.     move.w    d1,(a2)+
  3781.  
  3782.     ENDC
  3783.  
  3784.     dbf    d3,.rightover_masked_loop
  3785. .rightover_unmasked:
  3786. .end_handle_rightover:
  3787.  
  3788. .next_line:
  3789.     move.w    (sp)+,d2
  3790.     movem.l    (sp)+,a1/a3
  3791.     adda.l    a6,a0
  3792.     move.w    (sp)+,d7
  3793.     dbra    d7,.yloop
  3794.  
  3795. .end:    rts
  3796.  
  3797. ; TODO: implement this!
  3798.  
  3799.     IFNE    0
  3800.     move.w    #%0000000000011111,d7
  3801.     move.w    #%0000011111100000,d6
  3802.     move.w    #%1111100000000000,d5
  3803.  
  3804. ; Looks like almost 80 cycles :(
  3805. ; Maybe try table?
  3806.     move.w    (a1)+,d0
  3807.     move.w    (a0),d1
  3808.     move.w    d0,d2
  3809.     move.w    d1,d3
  3810.     and.w    d7,d2
  3811.     and.w    d7,d3
  3812.     add.w    d2,d3
  3813.     cmp.w    d7,d3
  3814.     ble.s    .b_ok
  3815.     move.w    d7,d3
  3816. .b_ok:    move.w    d0,d2
  3817.     move.w    d1,d4
  3818.     and.w    d6,d2
  3819.     and.w    d6,d4
  3820.     sub.w    d2,d0
  3821.     sub.w    d4,d1
  3822.     add.w    d2,d4
  3823.     cmp.w    d6,d4
  3824.     ble.s    .g_ok
  3825.     move.w    d6,d4
  3826. .g_ok:    or.w    d4,d3
  3827.     add.w    d0,d1
  3828.     bcc.s    .r_ok
  3829.     move.w    d5,d1
  3830. .r_ok:    or.w    d1,d3
  3831.     move.w    d3,(a0)+
  3832.     ENDC
  3833.  
  3834. Primitive.initMsbMixTable:
  3835.     move.b    #%00000111,d6
  3836.     move.b    #%11111000,d5
  3837.     lea    Primitive.msbMixTable,a0
  3838.     clr.w    d7
  3839.  
  3840. .loop:    move.w    d7,d0
  3841.     lsr.w    #8,d0
  3842.     move.b    d7,d1
  3843.     move.b    d0,d2
  3844.     move.b    d1,d3
  3845.     and.b    d6,d0
  3846.     and.b    d6,d1
  3847.     sub.b    d0,d2
  3848.     sub.b    d1,d3
  3849.     add.b    d0,d1
  3850.     cmp.b    d6,d1
  3851.     blo.s    .g_ok
  3852.     move.b    d6,d1
  3853. .g_ok:    add.b    d2,d3
  3854.     bcc.s    .r_ok
  3855.     move.b    d5,d3
  3856. .r_ok:    or.b    d3,d1
  3857.     move.b    d1,(a0)+
  3858.     addq.w    #1,d7
  3859.     bne.s    .loop
  3860.     rts
  3861.  
  3862. Primitive.initLsbMixTable:
  3863.     move.b    #%00011111,d6
  3864.     move.b    #%11100000,d5
  3865.     lea    Primitive.lsbMixTable,a0
  3866.     clr.w    d7
  3867.  
  3868. .loop:    move.w    d7,d0
  3869.     lsr.w    #8,d0
  3870.     move.b    d7,d1
  3871.     move.b    d0,d2
  3872.     move.b    d1,d3
  3873.     and.b    d6,d0
  3874.     and.b    d6,d1
  3875.     sub.b    d0,d2
  3876.     sub.b    d1,d3
  3877.     add.b    d0,d1
  3878.     cmp.b    d6,d1
  3879.     blo.s    .b_ok
  3880.     move.b    d6,d1
  3881. .b_ok:    add.b    d2,d3
  3882.     bcc.s    .g_ok
  3883.     move.b    d5,d3
  3884. .g_ok:    or.b    d3,d1
  3885.     move.b    d1,(a0)+
  3886.     addq.w    #1,d7
  3887.     bne.s    .loop
  3888.     rts
  3889.  
  3890.     IFNE    0
  3891. ; r,g,b hicolor word saturated add code.
  3892.     lea    Primitive.msbMixTable,a2
  3893.     lea    Primitive.lsbMixTable,a3
  3894.     clr.l    d2
  3895.     clr.b    d3
  3896.  
  3897.     move.w    (a1)+,d2
  3898.     move.w    d2,d0
  3899.     move.w    (a0),d1
  3900.     move.b    (a0),d2                ; d2.w=src_msb<<8+dest_msb
  3901.     move.b    (a2,d2.l),d4            ; d4.b=res_msb
  3902.     move.b    d1,d2
  3903.     lsl.w    #8,d2
  3904.     move.b    d0,d2                ; d2.w=src_lsb<<8+dest_lsb
  3905.     move.b    d4,(a0)+
  3906.     move.b    (a3,d2.l),(a0)+
  3907.  
  3908. ; 6+2+6+4+8+2+4+2+6+10=50 cycles (well..)
  3909.     ENDC
  3910.  
  3911. ;======= Line
  3912.  
  3913. Line.paintReceived:
  3914.     receiveWordFromDsp    d4
  3915.     receiveWordFromDsp    d1
  3916.     receiveWordFromDsp    d0
  3917.     receiveWordFromDsp    d3
  3918.     receiveWordFromDsp    d2
  3919.     ext.l    d0
  3920.     ext.l    d1
  3921.     ext.l    d2
  3922.     ext.l    d3
  3923.     move.w    d4,d5
  3924.     andi.w    #Primitive.TEXTUREMASK,d5
  3925.     move.w    d5,Line.colorNum
  3926.     andi.w    #Primitive.SHADEMASK,d4
  3927.     cmpi.w    #Line.FLATSHADED,d4
  3928.     beq.s    Line.paintFlatshaded
  3929.     cmpi.w    #Line.GOURAUDSHADED,d4
  3930.     beq    Line.paintGouraudshaded
  3931.     cmpi.w    #Line.PHONGSHADED,d4
  3932.     beq    Line.paintPhongshaded
  3933.     rts
  3934.  
  3935. ; INPUT:
  3936. ; \1: flagnum
  3937. ; \2: flagreg
  3938. ; \3: edgereg
  3939. ; \4: xreg
  3940. ; \5: yreg
  3941. Line_clipEdgeX:    MACRO
  3942.     btst    \1,\2
  3943.     beq.s    \@end_clip
  3944.     move.l    d2,d4
  3945.     sub.l    d0,d4
  3946.     move.l    d3,d7
  3947.     sub.l    d1,d7
  3948.     swap    d7
  3949.     clr.w    d7
  3950.     tst.w    d4
  3951.     beq.s    \@skip_div
  3952.     divs.l    d4,d7
  3953. \@skip_div:
  3954.     move.l    d0,d4
  3955.     sub.l    \3,d4
  3956.     muls.l    d4,d7
  3957.     swap    d7
  3958.     move.w    d1,d4
  3959.     sub.w    d7,d4
  3960.     cmp.w    a5,d4
  3961.     blt.s    \@out_of_range
  3962.     cmp.w    a6,d4
  3963.     bgt.s    \@out_of_range
  3964.     move.w    d4,\5
  3965.     move.l    \3,\4
  3966.     ext.l    \5
  3967.     moveq    #0,\2
  3968.     bra.s    \@end_clip
  3969. \@out_of_range:
  3970.     bset    #4,\2
  3971. \@end_clip:
  3972.     ENDM
  3973.  
  3974. ; INPUT:
  3975. ; \1: flagnum
  3976. ; \2: flagreg
  3977. ; \3: edgereg
  3978. ; \4: xreg
  3979. ; \5: yreg
  3980. Line_clipEdgeY:    MACRO
  3981.     btst    \1,\2
  3982.     beq.s    \@end_clip
  3983.     move.l    d3,d4
  3984.     sub.l    d1,d4
  3985.     move.l    d2,d7
  3986.     sub.l    d0,d7
  3987.     swap    d7
  3988.     clr.w    d7
  3989.     tst.w    d4
  3990.     beq.s    \@skip_div
  3991.     divs.l    d4,d7
  3992. \@skip_div:
  3993.     move.l    d1,d4
  3994.     sub.l    \3,d4
  3995.     muls.l    d4,d7
  3996.     swap    d7
  3997.     move.w    d0,d4
  3998.     sub.w    d7,d4
  3999.     cmp.w    a3,d4
  4000.     blt.s    \@out_of_range
  4001.     cmp.w    a4,d4
  4002.     bgt.s    \@out_of_range
  4003.     move.w    d4,\4
  4004.     ext.l    \4
  4005.     move.l    \3,\5
  4006.     moveq    #0,\2
  4007.     bra.s    \@end_clip
  4008. \@out_of_range:
  4009.     bset    #4,\2
  4010. \@end_clip:
  4011.     ENDM
  4012.  
  4013. ; INPUT:
  4014. ; \1: flagnum
  4015. ; \2: flagreg
  4016. ; \3: edgereg
  4017. ; \4: xreg
  4018. ; \5: yreg
  4019. ; \6: ireg
  4020. Line_clipGEdgeX:    MACRO
  4021.     btst    \1,\2
  4022.     beq.s    \@end_clip
  4023.     move.l    d2,d4
  4024.     sub.l    d0,d4
  4025.     move.l    d3,d7
  4026.     sub.l    d1,d7
  4027.     swap    d7
  4028.     clr.w    d7
  4029.     tst.w    d4
  4030.     beq.s    \@skip_div
  4031.     divs.l    d4,d7
  4032. \@skip_div:
  4033.     move.l    d0,d4
  4034.     sub.l    \3,d4                ; d4.l: dx
  4035.     muls.l    d4,d7
  4036.     swap    d7
  4037.     move.w    d1,d4
  4038.     sub.w    d7,d4
  4039.     cmp.w    a5,d4
  4040.     blt.s    \@out_of_range
  4041.     cmp.w    a6,d4
  4042.     bgt.s    \@out_of_range
  4043.     move.w    d4,\5
  4044.  
  4045.     move.l    d2,d4
  4046.     sub.l    d0,d4
  4047.     move.l    a2,d7
  4048.     sub.l    a0,d7
  4049.     lsl.l    #8,d7
  4050.     tst.w    d4
  4051.     beq.s    \@skip_div2
  4052.     divs.w    d4,d7                ; (di<<8)/x
  4053. \@skip_div2:
  4054.     move.l    d0,d4
  4055.     sub.l    \3,d4                ; d4.l: dx
  4056.     muls.w    d4,d7
  4057.     asr.l    #8,d7    
  4058.     move.w    a0,d4
  4059.     sub.w    d7,d4
  4060.     move.w    d4,\6
  4061.  
  4062.     move.l    \3,\4
  4063.     ext.l    \5
  4064.     moveq    #0,\2
  4065.     bra.s    \@end_clip
  4066. \@out_of_range:
  4067.     bset    #4,\2
  4068. \@end_clip:
  4069.     ENDM
  4070.  
  4071. ; INPUT:
  4072. ; \1: flagnum
  4073. ; \2: flagreg
  4074. ; \3: edgereg
  4075. ; \4: xreg
  4076. ; \5: yreg
  4077. ; \6: ireg
  4078. Line_clipGEdgeY:    MACRO
  4079.     btst    \1,\2
  4080.     beq.s    \@end_clip
  4081.     move.l    d3,d4
  4082.     sub.l    d1,d4
  4083.     move.l    d2,d7
  4084.     sub.l    d0,d7
  4085.     swap    d7
  4086.     clr.w    d7
  4087.     tst.w    d4
  4088.     beq.s    \@skip_div
  4089.     divs.l    d4,d7
  4090. \@skip_div:
  4091.     move.l    d1,d4
  4092.     sub.l    \3,d4
  4093.     muls.l    d4,d7
  4094.     swap    d7
  4095.     move.w    d0,d4
  4096.     sub.w    d7,d4
  4097.     cmp.w    a3,d4
  4098.     blt.s    \@out_of_range
  4099.     cmp.w    a4,d4
  4100.     bgt.s    \@out_of_range
  4101.     move.w    d4,\4
  4102.  
  4103.     move.l    d3,d4
  4104.     sub.l    d1,d4
  4105.     move.l    a2,d7
  4106.     sub.l    a0,d7
  4107.     lsl.l    #8,d7
  4108.     tst.w    d4
  4109.     beq.s    \@skip_div2
  4110.     divs.w    d4,d7                ; (di<<8)/y
  4111. \@skip_div2:
  4112.     move.l    d1,d4
  4113.     sub.l    \3,d4                ; d4.l: dy
  4114.     muls.w    d4,d7
  4115.     asr.l    #8,d7    
  4116.     move.w    a0,d4
  4117.     sub.w    d7,d4
  4118.     move.w    d4,\6
  4119.  
  4120.     ext.l    \4
  4121.     move.l    \3,\5
  4122.     moveq    #0,\2
  4123.     bra.s    \@end_clip
  4124. \@out_of_range:
  4125.     bset    #4,\2
  4126. \@end_clip:
  4127.     ENDM
  4128.  
  4129. ; Paints a one-colour line to the screen. The line can be clipped in
  4130. ; any way.
  4131. ; INPUT:
  4132. ; d0.l: x1
  4133. ; d1.l: y1
  4134. ; d2.l: x2
  4135. ; d3.l: y2
  4136. Line.paintFlatshaded:
  4137. ; Clip this baby first...
  4138. .clip:    movem.w    Viewport.settingsTable+Viewport.XSTART,a3-a6
  4139.  
  4140.     moveq    #0,d5                ; Set point clipflags to 0.
  4141. .check_first_left:
  4142.     cmp.w    a3,d0                ; XSTART
  4143.     bge.s    .check_first_right
  4144.     addq.w    #%0010,d5
  4145. .check_first_right:
  4146.     cmp.w    a4,d0                ; XEND
  4147.     blt.s    .end_check_first_right
  4148.     addq.w    #%0001,d5
  4149. .end_check_first_right:
  4150. .check_first_above:
  4151.     cmp.w    a5,d1                ; YSTART
  4152.     bge.s    .check_first_under
  4153.     ori.w    #%1000,d5
  4154. .check_first_under:
  4155.     cmp.w    a6,d1                ; YEND
  4156.     blt.s    .end_first_check
  4157.     addq.w    #%0100,d5
  4158. .end_first_check:
  4159.  
  4160.     moveq    #0,d6                ; Set point clipflags to 0.
  4161. .check_second_left:
  4162.     cmp.w    a3,d2                ; XSTART
  4163.     bge.s    .check_second_right
  4164.     addq.w    #%0010,d6
  4165. .check_second_right:
  4166.     cmp.w    a4,d2                ; XEND
  4167.     blt.s    .end_check_second_right
  4168.     addq.w    #%0001,d6
  4169. .end_check_second_right:
  4170. .check_second_above:
  4171.     cmp.w    a5,d3                ; YSTART
  4172.     bge.s    .check_second_under
  4173.     ori.w    #%1000,d6
  4174. .check_second_under:
  4175.     cmp.w    a6,d3                ; YEND
  4176.     blt.s    .end_second_check
  4177.     addq.w    #%0100,d6
  4178. .end_second_check:
  4179.  
  4180.     subq    #1,a4
  4181.     subq    #1,a6
  4182.  
  4183.     move.w    d5,d7
  4184.     and.w    d6,d7
  4185.     beq    .go_on
  4186.     rts
  4187. .go_on:    move.w    d5,d7
  4188.     or.w    d6,d7
  4189.     beq    Line.paintFlatshaded.end_clip
  4190.  
  4191. .clip_first_left:
  4192.     Line_clipEdgeX    #1,d5,a3,d0,d1
  4193. .end_clip_first_left:
  4194. .clip_first_right:
  4195.     Line_clipEdgeX    #0,d5,a4,d0,d1
  4196. .end_clip_first_right:
  4197. .clip_first_top:
  4198.     Line_clipEdgeY    #3,d5,a5,d0,d1
  4199. .end_clip_first_top:
  4200. .clip_first_bottom:
  4201.     Line_clipEdgeY    #2,d5,a6,d0,d1
  4202. .end_clip_first_bottom:
  4203.  
  4204. .clip_second_left:
  4205.     Line_clipEdgeX    #1,d6,a3,d2,d3
  4206. .end_clip_second_left:
  4207. .clip_second_right:
  4208.     Line_clipEdgeX    #0,d6,a4,d2,d3
  4209. .end_clip_second_right:
  4210. .clip_second_top:
  4211.     Line_clipEdgeY    #3,d6,a5,d2,d3
  4212. .end_clip_second_top:
  4213. .clip_second_bottom:
  4214.     Line_clipEdgeY    #2,d6,a6,d2,d3
  4215. .end_clip_second_bottom:
  4216.  
  4217.     or.w    d5,d6
  4218.     btst    #4,d6
  4219.     beq.s    .go_on
  4220.     rts
  4221. .go_on:
  4222.  
  4223. Line.paintFlatshaded.end_clip:
  4224.  
  4225. ; The lineroutine has NO CLIPPING!!!
  4226.     moveq    #0,d6
  4227.     move.w    Line.colorNum,d6
  4228.     movea.l    Polygon.coloradr,a1
  4229.     lea    Primitive.GRADIENTSIZE/2(a1),a1
  4230.     lsl.l    #Primitive.GRADIENTBITS+1,d6
  4231.     move.w    (a1,d6.l),d6
  4232.     movea.l    Primitive.screenadr,a0
  4233.     clr.l    d5
  4234.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  4235.     add.l    d5,d5
  4236. ; d0.w=x0, d1.w=y0, d2.w=x1, d3.w=y1, d5.l=scrwidth, d6.w=color, a0: screen
  4237.  
  4238. ; Calculate |dx|, |dy| and calculate x step, y step.
  4239.     moveq    #2,d4
  4240.     sub.w    d0,d2            ; d2.w = dx
  4241.     bpl.s    .dx_positive
  4242.     neg.l    d4
  4243.     neg.w    d2
  4244. .dx_positive:
  4245.     movea.l    d4,a1            ; a1 = x step
  4246.     move.l    d5,d4
  4247.     sub.w    d1,d3            ; d3.w = dy
  4248.     bpl.s    .dy_positive
  4249.     neg.l    d4
  4250.     neg.w    d3
  4251. .dy_positive:
  4252.     movea.l    d4,a2            ; a2 = y step
  4253. ; d2.w = |dx|, d3.w = |dy|
  4254.  
  4255. ; Calculate the startaddress on screen.
  4256.     ext.l    d0
  4257.     add.w    d0,d0
  4258.     mulu.w    d5,d1
  4259.     add.l    d0,d1
  4260.     adda.l    d1,a0
  4261.  
  4262. ; Branch to appropriate routine, depending on |dx| < |dy|.
  4263.     cmp.w    d2,d3
  4264.     blt.s    Line.paintDy
  4265.  
  4266. ; Paints a line with |dy| >= |dx|.
  4267. Line.paintDx:
  4268.     move.w    d3,d5
  4269.     beq.s    .end
  4270.     ;subq.w    #1,d5
  4271.     move.w    d3,d0
  4272.  
  4273. .loop:    move.w    d6,(a0)
  4274.     sub.w    d2,d0
  4275.     bgt.s    .end_inc_x
  4276.     add.w    d3,d0
  4277.     adda.l    a1,a0
  4278. .end_inc_x:
  4279.     adda.l    a2,a0
  4280.     dbra    d5,.loop
  4281.  
  4282. .end:    rts
  4283.  
  4284. ; Paints a line with |dx| < |dy|.
  4285. Line.paintDy:
  4286.     move.w    d2,d5
  4287.     beq.s    .end
  4288.     ;subq.w    #1,d5
  4289.     move.w    d2,d0
  4290.  
  4291. .loop:    move.w    d6,(a0)
  4292.     sub.w    d3,d0
  4293.     bgt.s    .end_inc_y
  4294.     add.w    d2,d0
  4295.     adda.l    a2,a0
  4296. .end_inc_y:
  4297.     adda.l    a1,a0
  4298.     dbra    d5,.loop
  4299.  
  4300. .end:    rts
  4301.  
  4302. ; Paints a gouraudshaded line to the screen. The line can be clipped in any
  4303. ; way.
  4304. ; INPUT:
  4305. ; d0.l: x1
  4306. ; d1.l: y1
  4307. ; d2.l: x2
  4308. ; d3.l: y2
  4309. Line.paintGouraudshaded:
  4310.     receiveWordFromDsp    a0
  4311.     receiveWordFromDsp    a2
  4312.  
  4313. Line.paintGradiented:
  4314. ; Clip this baby first...
  4315. .clip:    movem.w    Viewport.settingsTable+Viewport.XSTART,a3-a6
  4316.  
  4317.     moveq    #0,d5                ; Set point clipflags to 0.
  4318. .check_first_left:
  4319.     cmp.w    a3,d0                ; XSTART
  4320.     bge.s    .check_first_right
  4321.     addq.w    #%0010,d5
  4322. .check_first_right:
  4323.     cmp.w    a4,d0                ; XEND
  4324.     blt.s    .end_check_first_right
  4325.     addq.w    #%0001,d5
  4326. .end_check_first_right:
  4327. .check_first_above:
  4328.     cmp.w    a5,d1                ; YSTART
  4329.     bge.s    .check_first_under
  4330.     ori.w    #%1000,d5
  4331. .check_first_under:
  4332.     cmp.w    a6,d1                ; YEND
  4333.     blt.s    .end_first_check
  4334.     addq.w    #%0100,d5
  4335. .end_first_check:
  4336.  
  4337.     moveq    #0,d6                ; Set point clipflags to 0.
  4338. .check_second_left:
  4339.     cmp.w    a3,d2                ; XSTART
  4340.     bge.s    .check_second_right
  4341.     addq.w    #%0010,d6
  4342. .check_second_right:
  4343.     cmp.w    a4,d2                ; XEND
  4344.     blt.s    .end_check_second_right
  4345.     addq.w    #%0001,d6
  4346. .end_check_second_right:
  4347. .check_second_above:
  4348.     cmp.w    a5,d3                ; YSTART
  4349.     bge.s    .check_second_under
  4350.     ori.w    #%1000,d6
  4351. .check_second_under:
  4352.     cmp.w    a6,d3                ; YEND
  4353.     blt.s    .end_second_check
  4354.     addq.w    #%0100,d6
  4355. .end_second_check:
  4356.  
  4357.     subq    #1,a4
  4358.     subq    #1,a6
  4359.  
  4360.     move.w    d5,d7
  4361.     and.w    d6,d7
  4362.     beq    .go_on
  4363.     rts
  4364. .go_on:    move.w    d5,d7
  4365.     or.w    d6,d7
  4366.     beq    Line.paintGouraudshaded.end_clip
  4367.  
  4368. .clip_first_left:
  4369.     Line_clipGEdgeX    #1,d5,a3,d0,d1,a0
  4370. .end_clip_first_left:
  4371. .clip_first_right:
  4372.     Line_clipGEdgeX    #0,d5,a4,d0,d1,a0
  4373. .end_clip_first_right:
  4374. .clip_first_top:
  4375.     Line_clipGEdgeY    #3,d5,a5,d0,d1,a0
  4376. .end_clip_first_top:
  4377. .clip_first_bottom:
  4378.     Line_clipGEdgeY    #2,d5,a6,d0,d1,a0
  4379. .end_clip_first_bottom:
  4380.  
  4381. .clip_second_left:
  4382.     Line_clipGEdgeX    #1,d6,a3,d2,d3,a2
  4383. .end_clip_second_left:
  4384. .clip_second_right:
  4385.     Line_clipGEdgeX    #0,d6,a4,d2,d3,a2
  4386. .end_clip_second_right:
  4387. .clip_second_top:
  4388.     Line_clipGEdgeY    #3,d6,a5,d2,d3,a2
  4389. .end_clip_second_top:
  4390. .clip_second_bottom:
  4391.     Line_clipGEdgeY    #2,d6,a6,d2,d3,a2
  4392. .end_clip_second_bottom:
  4393.  
  4394.     or.w    d5,d6
  4395.     btst    #4,d6
  4396.     beq.s    .go_on
  4397.     rts
  4398. .go_on:
  4399.  
  4400. Line.paintGouraudshaded.end_clip:
  4401.  
  4402. ; The lineroutine has NO CLIPPING!!!
  4403.     move.l    a0,d6
  4404.     move.l    a2,d7
  4405.     clr.l    d4
  4406.     move.w    Line.colorNum,d4
  4407.     movea.l    Polygon.coloradr,a1
  4408.     lsl.l    #Primitive.GRADIENTBITS+1,d4
  4409.     adda.l    d4,a1
  4410.     movea.l    Primitive.screenadr,a0
  4411. ; d0.w=x0, d1.w=y0, d2.w=x1, d3.w=y1, d6.w=g0 d7.w=g1, a0: screen, a1: pal
  4412.  
  4413.     clr.l    d5
  4414.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  4415.     add.l    d5,d5
  4416.  
  4417. ; Calculate |dx|, |dy| and calculate x step, y step.
  4418.     moveq    #2,d4
  4419.     sub.w    d0,d2            ; d2.w=dx
  4420.     bpl.s    .dx_positive
  4421.     neg.l    d4
  4422.     neg.w    d2
  4423. .dx_positive:
  4424.     movea.l    d4,a2            ; a1= x step
  4425.     move.l    d5,d4
  4426.     sub.w    d1,d3            ; d3.w=dy
  4427.     bpl.s    .dy_positive
  4428.     neg.l    d4
  4429.     neg.w    d3
  4430. .dy_positive:
  4431.     movea.l    d4,a3            ; a2= y step
  4432. ; d2.w = |dx|, d3.w = |dy|
  4433.  
  4434. ; Calc dg.
  4435.     ext.l    d7
  4436.     ext.l    d6
  4437.     sub.l    d6,d7
  4438.     lsl.l    #8,d6
  4439.     move.l    d6,d4
  4440.     lsl.l    #8,d7
  4441.  
  4442. ; Calculate the startaddress on screen.
  4443.     ext.l    d0
  4444.     add.l    d0,d0
  4445.     mulu.w    d5,d1
  4446.     add.l    d0,d1
  4447.     adda.l    d1,a0
  4448.  
  4449. ; Branch to appropriate routine, depending on |dx| < |dy|.
  4450.     cmp.w    d2,d3
  4451.     blt.s    Line.paintGradDy
  4452.  
  4453. ; Paints a line with |dy| >= |dx|.
  4454. Line.paintGradDx:
  4455.     move.w    d3,d5
  4456.     beq.s    .end
  4457.     divs.w    d5,d7
  4458.     ;subq.w    #1,d5
  4459.     move.w    d3,d0
  4460.  
  4461. .loop:    move.l    d4,d1
  4462.     lsr.l    #8,d1
  4463.     move.w    (a1,d1.l*2),(a0)
  4464.     sub.w    d2,d0
  4465.     bgt.s    .end_inc_x
  4466.     add.w    d3,d0
  4467.     adda.l    a2,a0
  4468. .end_inc_x:
  4469.     add.w    d7,d4
  4470.     adda.l    a3,a0
  4471.     dbra    d5,.loop
  4472.  
  4473. .end:    rts
  4474.  
  4475. ; Paints a line with |dx| < |dy|.
  4476. Line.paintGradDy:
  4477.     move.w    d2,d5
  4478.     beq.s    .end
  4479.     divs.w    d5,d7
  4480.     ;subq.w    #1,d5
  4481.     move.w    d2,d0
  4482.  
  4483. .loop:    move.l    d4,d1
  4484.     lsr.l    #8,d1
  4485.     move.w    (a1,d1.l*2),(a0)
  4486.     sub.w    d3,d0
  4487.     bgt.s    .end_inc_y
  4488.     add.w    d2,d0
  4489.     adda.l    a3,a0
  4490. .end_inc_y:
  4491.     add.w    d7,d4
  4492.     adda.l    a2,a0
  4493.     dbra    d5,.loop
  4494.  
  4495. .end:    rts
  4496.  
  4497. ; Paints a gouraudshaded line to the screen. The line can be clipped in any
  4498. ; way.
  4499. ; INPUT:
  4500. ; d0.l: x1
  4501. ; d1.l: y1
  4502. ; d2.l: x2
  4503. ; d3.l: y2
  4504. ; a1: Line structure
  4505. ; a2: vertex table
  4506. Line.paintPhongshaded:
  4507.     receiveWordFromDsp    a0
  4508.     receiveWordFromDsp    a2
  4509.     bra    Line.paintGradiented
  4510.  
  4511.     DATA
  4512.  
  4513. ;======= HumanFly
  4514.  
  4515. HumanFly.p56:
  4516.     INCBIN    S_FLY.P56
  4517. HumanFly.endP56:
  4518.     EVEN
  4519.  
  4520. ;======= Sprite
  4521.  
  4522. Sprite.rout:
  4523.     DC.L    Sprite.paintMoved
  4524.  
  4525.     BSS
  4526.  
  4527. ;======= ObjectRegistry
  4528.  
  4529. ObjectRegistry.numberOfHandles:
  4530.     DS.W    1
  4531. ObjectRegistry.table:
  4532.     DS.L    ObjectRegistry.CAPACITY
  4533. ObjectRegistry.size:
  4534.     DS.L    1                ; #words in dsp buffer already
  4535.  
  4536. ;======= PrimitiveMesh
  4537.  
  4538. PrimitiveMesh.shadowAdr:            ; points to actual shadow
  4539.     DS.L    1
  4540. PrimitiveMesh.shadowStartAdr:            ; points to 1st shadow
  4541.     DS.L    1
  4542. PrimitiveMesh.background:            ; backgroundaddress
  4543.     DS.L    1
  4544. PrimitiveMesh.shadowsOn:
  4545.     DS.W    1
  4546.  
  4547. ;======= Primitive
  4548.  
  4549. Primitive.skipBytes:
  4550.     DS.W    1
  4551. Primitive.bytesPerPixel:
  4552.     DS.W    1
  4553. Primitive.screenadr:
  4554.     DS.L    1
  4555. Primitive.msbMixTable:
  4556.     DS.B    256*256
  4557. Primitive.lsbMixTable:
  4558.     DS.B    256*256
  4559.  
  4560. ;======= Polygon
  4561.  
  4562. Polygon.gradadr:                ; address of current gradient table
  4563.     DS.L    1
  4564. Polygon.textureTable:                ; contains texturepointers (nullterminated)
  4565.     DS.L    Polygon.MAX_TEXTURES+1
  4566. Polygon.textureroutadr:
  4567.     DS.L    1
  4568. Polygon.v4routadr:
  4569.     DS.L    1
  4570. Polygon.alphatableadr:
  4571.     DS.L    1
  4572. Polygon.texturemode:
  4573.     DS.W    1
  4574. Polygon.v4texturemode:
  4575.     DS.W    1
  4576. Polygon.color:                    ; current color
  4577.     DS.L    1
  4578. Polygon.coloradr:                ; base address of gradient tables
  4579.     DS.L    1
  4580. Polygon.curtexture:                ; first current textureaddress
  4581.     DS.L    1
  4582. Polygon.curtexture2:                ; second current textureaddress
  4583.     DS.L    1
  4584.  
  4585. Polygon.uvslopes:
  4586.     DS.W    4                ; u0,v0,u1,v1
  4587. Polygon.invTable:
  4588.     DS.W    Viewport.MAX_Y+1
  4589. Polygon.fragmentTable:
  4590.     DS.W    1                ; active fragment flags
  4591.     DS.B    Fragment.SIZE*4            ; max 3 for quad, max 2 for triangle
  4592. Polygon.scanlineTable:
  4593.     DS.W    1
  4594.     DS.W    3*Viewport.MAX_Y        ; table for tmap and envmap scanlines
  4595. Polygon.shadeTable:
  4596.     DS.W    Vertex2d.SIZE*8            ; (u,v) for each vertex
  4597. Polygon.extvertexTable:
  4598.     DS.W    4*3                ; for each trianglevertex: u0,v0,u1,v1
  4599. Polygon.bumpmapTable:
  4600.     DS.W    1
  4601.     DS.L    16
  4602. Polygon.textureCache:
  4603.     DS.B    3*8192
  4604.  
  4605. prest_min:
  4606.     ds.w    1
  4607. prest_poly2:
  4608.     ds.l    16
  4609. prest_left_table:
  4610.     ds.l    2*16
  4611. prest_right_table:
  4612.     ds.l    2*16
  4613.  
  4614. ;======= Line
  4615.  
  4616. Line.colorNum:
  4617.     DS.W    1
  4618.  
  4619.