home *** CD-ROM | disk | FTP | other *** search
/ Fujiology Archive / fujiology_archive_v1_0.iso / !FALCON / LINEOUT / DELTA.ZIP / DELTASRC.ZIP / DELTA.SRC / SFLY_DSP.S < prev    next >
Text File  |  2003-01-04  |  89KB  |  4,445 lines

  1. ; CPU+DSP implementation of the Human Fly engine 2.1.
  2. ; Special one-off 'shadow' version!! Beware!!
  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.     dbra    d7,.yloop
  705.     rts
  706.  
  707. ;======= PrimitiveMesh
  708.  
  709. ; Marks the PrimitiveMesh as ready to roll.
  710. PrimitiveMesh.new:
  711. ; Inform the dsp.
  712.     moveq    #RPC_NEW_PRIMITIVEMESH,d0
  713.     sendLongToDsp    d0
  714.  
  715. ; Disable shadow handling.
  716.     clr.l    d0
  717.     move.w    d0,PrimitiveMesh.shadowsOn
  718.     sendLongToDsp    d0
  719.     rts
  720.  
  721. ; Marks the PrimitiveMesh as ready to roll.
  722. ; INPUT:
  723. ; a0: shadow polygon buffer
  724. PrimitiveMesh.newShadowed:
  725.     moveq    #RPC_NEW_PRIMITIVEMESH,d0
  726.     sendLongToDsp    d0
  727.  
  728. ; Enable shadow handling.
  729.     moveq    #1,d0
  730.     move.w    d0,PrimitiveMesh.shadowsOn
  731.     sendLongToDsp    d0
  732.     move.l    a0,PrimitiveMesh.shadowStartAdr
  733.     clr.w    (a0)+                    ; Clear counter.
  734.     move.l    a0,PrimitiveMesh.shadowAdr
  735.     rts
  736.  
  737. ; Sort the elements.
  738. PrimitiveMesh.sortZ:
  739.     moveq    #RPC_SORT_PRIMITIVEMESH,d0
  740.     sendLongToDsp    d0
  741.     rts
  742.  
  743. ; Indicate the mesh is ready for painting.
  744. PrimitiveMesh.complete:
  745. ; Give the command..
  746.     moveq    #RPC_PAINT_PRIMITIVES,d0
  747.     sendLongToDsp    d0
  748.     rts
  749.  
  750. ; INPUT:
  751. ; a0: storage for bounding rectangles
  752. PrimitiveMesh.paint:
  753.     move.l    a0,-(sp)
  754.  
  755. ; Now wait for a reply and paint them primitives.
  756. .loop:    receiveWordFromDsp    d0        ; d0=shadetype
  757.     bmi.s    .end_paint            ; d0<0 ? terminate!
  758.     jsr    .jumpTable(pc,d0.w*4)
  759.     bra.s    .loop
  760. .end_paint:
  761.  
  762. ; Killer! Now we receive all bounding rectangles in the scene.
  763.     movea.l    (sp)+,a0
  764.     receiveWordFromDsp    d7
  765.     move.w    d7,(a0)+
  766.     beq.s    .end
  767.     lsl.w    #2,d7                ; rectanglecount*words/rectangle = total words
  768.     subq.w    #1,d7
  769. .rect_loop:
  770.     receiveWordFromDsp    (a0)+
  771.     dbra    d7,.rect_loop
  772.  
  773. .end:    rts
  774.  
  775. .jumpTable:
  776.     bra.w    Polygon.paintDspFlatshaded
  777.     bra.w    Polygon.paintFastGouraudshaded
  778.     bra.w    Polygon.paintDspTexturemapped
  779.     bra.w    Polygon.paintDspAlphatextured
  780.     bra.w    Polygon.paintDspBumpmapped
  781.     bra.w    Sprite.paintReceived
  782.     bra.w    Line.paintReceived
  783.  
  784. ;======= Polygon
  785.  
  786. Polygon.MAX_TEXTURES:        =    32
  787.  
  788. Polygon.OFFSET_TEXTURING:    =    0
  789. Polygon.PIXEL_TEXTURING:    =    1
  790. Polygon.ALPHA_TEXTURING:    =    2
  791. Polygon.BUMP_TEXTURING:        =    3
  792. Polygon.FLAT_SHADING:        =    4
  793. Polygon.GOURAUD_SHADING:    =    5
  794.  
  795. ; Initializes polygonpainter lookup tables.
  796. ; INPUT:
  797. ; a0: texture-address-table
  798. ; a1: gouraud-tables
  799. ; OUTPUT:
  800. ; d0.l: 0=ok, -1=error
  801. Polygon.init:
  802.     move.l    a1,Polygon.coloradr
  803.  
  804.     bsr.w    Polygon.copyTextureTable
  805.  
  806.     tst.w    .mix_initialized(pc)
  807.     bne.s    .done_mixing
  808.     bsr.w    Primitive.initMsbMixTable
  809.     bsr.w    Primitive.initLsbMixTable
  810.     move.w    #1,.mix_initialized
  811. .done_mixing:
  812.  
  813.     bsr.w    Polygon.deregisterBumpmaps
  814.  
  815.     bsr.w    Polygon.parseTextureTable
  816.  
  817.     move.w    d0,-(sp)
  818.     bsr.w    Polygon.calcInvTable
  819.     move.w    (sp)+,d0
  820.  
  821.     bsr.s    Polygon.setTextureMode
  822.  
  823. .success:
  824.     moveq    #0,d0
  825.     rts
  826. .error:    moveq    #-1,d0
  827.     rts
  828.  
  829. .mix_initialized:
  830.     DC.W    0
  831.  
  832. ; Copies specified texturetable to internal table.
  833. Polygon.copyTextureTable:
  834.     lea    Polygon.textureTable,a1
  835.     moveq    #Polygon.MAX_TEXTURES-1,d7
  836. .loop:    move.l    (a0)+,(a1)+
  837.     dbeq    d7,.loop
  838.     rts
  839.  
  840. ; INPUT:
  841. ; d0.w=texturemode
  842. Polygon.setTextureMode:
  843.     move.w    d0,Polygon.texturemode
  844.  
  845.     cmpi.w    #Polygon.PIXEL_TEXTURING,d0
  846.     beq.s    .end
  847.  
  848. .offset:cmpi.w    #Polygon.OFFSET_TEXTURING,d0
  849.     bne.s    .end
  850. ; Set the dsp to sending back offsets.
  851.     moveq    #RPC_SET_OFFSETPIXEL,d0
  852.     sendLongToDsp    d0
  853.  
  854. .end:    rts
  855.  
  856. ; Parses a table containing APX block textures and resets all addresses
  857. ; to point to the start of the pixeldata. Also installs all texturebuffers.
  858. ; PRECONDITIONS:
  859. ; The texturetable points to APX blocks.
  860. ; The texturetable is null-terminated.
  861. ; The texturetable does not contain over 16 highcolor and 8bpp textures.
  862. ; OUTPUT:
  863. ; d0.w=(Polygon.PIXEL_TEXTURING, Polygon.OFFSET_TEXTURING)
  864. Polygon.parseTextureTable:
  865.     lea    Polygon.textureTable,a0
  866.  
  867. ; Get all textureaddresses and split them in the 8bpp and highcolor
  868. ; catagories.
  869. .catagorization:
  870.     clr.l    d1
  871.     clr.l    d2
  872.     clr.l    d3                ; d3.l= #pixels (8bit)
  873.     clr.l    d4                ; d4.l= #pixels (16bit)
  874.     lea    .wordTextureTable,a4
  875.     lea    .byteTextureTable,a5
  876.  
  877. .storeloop:
  878.     movea.l    (a0)+,a1
  879.     tst.l    a1
  880.     beq.s    .end_catagorization
  881.     movem.w    12(a1),d6/d7            ; d6.w=width, d7.w=height
  882.     mulu.w    d6,d7                ; d7.l=#pixels
  883.     move.l    (a1),d0
  884. .test_byte_per_pixel:
  885.     cmpi.l    #"Byte",d0
  886.     bne.s    .end_test_byte_per_pixel
  887.     add.l    d7,d3
  888.     addq.w    #1,d2
  889.     move.l    a1,(a5)+            ; Store 8bpp texture.
  890.     lea    788(a1),a1
  891. .end_test_byte_per_pixel:
  892. .test_word_per_pixel:
  893.     cmpi.l    #"Word",d0
  894.     bne.s    .end_test_word_per_pixel
  895.     add.l    d7,d4
  896.     addq.w    #1,d1
  897.     move.l    a1,(a4)+            ; Store highcolor texture.
  898.     lea    20(a1),a1
  899. .end_test_word_per_pixel:
  900.     move.l    a1,-4(a0)
  901. .dont_send:
  902.     bra.s    .storeloop
  903. .end_catagorization:
  904.  
  905. ; d1.w= number of highcolor textures
  906. ; d2.w= number of 8bpp textures
  907. ; d3.l= total 16bit pixels
  908. ; d4.l= total 8bit pixels
  909. ; If either the amount of 16bit or 8bit textures exceeds 2, use offsetmode.
  910.     cmpi.w    #2,d1
  911.     bgt    .init_offset_mode
  912.     cmpi.w    #2,d2
  913.     bgt    .init_offset_mode
  914. ; If either the amount of 16bit or 8bit pixels exceeds 8192, use offsetmode.
  915.     cmpi.l    #8192,d3
  916.     bgt    .init_offset_mode
  917.     cmpi.l    #8192,d4
  918.     bgt    .init_offset_mode
  919.  
  920. ; Put all the textures toghether in a piece of texturecache.
  921. ; First the 16bit ones....
  922. .cache_16bit:
  923.     lea    Polygon.textureCache,a0
  924.     lea    .wordTextureTable,a4
  925.     subq.w    #1,d1
  926.     bmi.s    .end_cache_16bit
  927. .cache16bit_loop:
  928.     movea.l    (a4)+,a1
  929.     movem.w    12(a1),d6/d7
  930.     lea    20(a1),a1
  931.     mulu.w    d6,d7
  932.     subq.w    #1,d7
  933.  
  934. .pixel16bitloop:
  935.     addq    #1,a0
  936.     move.w    (a1)+,(a0)+
  937.     dbra    d7,.pixel16bitloop
  938.  
  939.     dbra    d1,.cache16bit_loop
  940. .end_cache_16bit:
  941.  
  942. ; Then the 8bit ones....
  943. .cache_8bit:
  944.     lea    Polygon.textureCache,a0
  945.     lea    .byteTextureTable,a4
  946.     subq.w    #1,d2
  947.     bmi.s    .end_cache_8bit
  948. .cache8bit_loop:
  949.     movea.l    (a4)+,a1
  950.     movem.w    12(a1),d6/d7
  951.     lea    788(a1),a1
  952.     mulu.w    d6,d7
  953.     subq.w    #1,d7
  954.  
  955. .pixel8bitloop:
  956.     move.b    (a1)+,(a0)+
  957.     addq    #2,a0
  958.     dbra    d7,.pixel8bitloop
  959.  
  960.     dbra    d2,.cache8bit_loop
  961. .end_cache_8bit:
  962.  
  963. ; Pump the texturecache over to the dsp.
  964.     moveq    #RPC_STORE_TEXTURE,d7
  965.     sendLongToDsp    d7
  966.     lea    Polygon.textureCache,a1
  967.     move.w    #8192-1,d7
  968. .sendloop:
  969.     move.b    (a1)+,d0
  970.     swap    d0
  971.     move.w    (a1)+,d0
  972.     sendLongToDsp    d0
  973.     dbra    d7,.sendloop
  974.  
  975.     move.w    #Polygon.PIXEL_TEXTURING,d0
  976. .end:    rts
  977.  
  978. .init_offset_mode:
  979.     move.w    #Polygon.OFFSET_TEXTURING,d0
  980.     rts
  981.  
  982. ; These store all textureaddresses found.
  983. .wordTextureTable:
  984.     DS.L    16
  985. .byteTextureTable:
  986.     DS.L    16
  987.  
  988. Polygon.calcInvTable:
  989.     lea    Polygon.invTable,a0
  990.     move.l    #$80000000,d1
  991.     moveq    #2,d0
  992.     move.l    d1,d2
  993.     swap    d2
  994.     move.w    #$7fff,(a0)+
  995.     move.w    #$7fff,(a0)+
  996.  
  997. .posloop:
  998.     move.l    d1,d2
  999.     divu.l    d0,d2
  1000.     swap    d2
  1001.     move.w    d2,(a0)+
  1002.     addq.w    #1,d0
  1003.     cmpi.w    #Viewport.MAX_Y+1,d0
  1004.     blt.s    .posloop
  1005.  
  1006.     rts
  1007.  
  1008. ; Calculates a 64K highcolor-word lookup table from two 256 truecolor
  1009. ; palettes.
  1010. ; INPUT: d7.w: start intensity of palette1
  1011. ;        a0: highcolor lookuptable
  1012. ;        a1: truecolor palette1
  1013. ;        a2: truecolor palette2 (256 entries)
  1014. ;        a5: number of entries in palette1
  1015. Polygon.calcMixtable:
  1016.     movea.l    #$0000ffff,a6
  1017.  
  1018. .palloop:
  1019.     moveq    #0,d0
  1020.     moveq    #0,d1
  1021.     moveq    #0,d2
  1022.     move.b    (a1)+,d0
  1023.     move.b    (a1)+,d1
  1024.     move.b    (a1)+,d2
  1025.     muls.w    d7,d0
  1026.     muls.w    d7,d1
  1027.     muls.w    d7,d2
  1028.     lsl.l    #1,d0
  1029.     lsl.l    #1,d1
  1030.     lsl.l    #1,d2
  1031.     moveq    #0,d6
  1032.  
  1033. .colorloop:
  1034.     moveq    #0,d3
  1035.     moveq    #0,d4
  1036.     moveq    #0,d5
  1037.     move.b    (a2)+,d3
  1038.     move.b    (a2)+,d4
  1039.     move.b    (a2)+,d5
  1040.     mulu.w    d6,d3
  1041.     mulu.w    d6,d4
  1042.     mulu.w    d6,d5
  1043.     add.l    d0,d3
  1044.     bpl.s    .red1_ok
  1045.     moveq    #0,d3
  1046.     bra.s    .red_ok
  1047. .red1_ok:
  1048.     cmp.l    a6,d3
  1049.     blt.s    .red_ok
  1050.     move.w    a6,d3
  1051. .red_ok:
  1052.     add.l    d1,d4
  1053.     bpl.s    .green1_ok
  1054.     moveq    #0,d4
  1055.     bra.s    .green_ok
  1056. .green1_ok:
  1057.     cmp.l    a6,d4
  1058.     blt.s    .green_ok
  1059.     move.w    a6,d4
  1060. .green_ok:
  1061.     add.l    d2,d5
  1062.     bpl.s    .blue1_ok
  1063.     moveq    #0,d5
  1064.     bra.s    .blue_ok
  1065. .blue1_ok:
  1066.     cmp.l    a6,d5
  1067.     blt.s    .blue_ok
  1068.     move.w    a6,d5
  1069. .blue_ok:
  1070.     andi.w    #%1111100000000000,d3
  1071.     lsr.w    #5,d4
  1072.     andi.w    #%0000011111100000,d4
  1073.     lsr.w    #8,d5
  1074.     lsr.w    #3,d5
  1075.     or.w    d4,d3
  1076.     or.w    d5,d3
  1077.     move.w    d3,(a0)+
  1078.     addq.b    #1,d6
  1079.     bne.s    .colorloop
  1080.  
  1081.     lea    -256*3(a2),a2
  1082.     addq.w    #1,d7
  1083.     cmp.w    a5,d7
  1084.     blt.s    .palloop
  1085.  
  1086.     rts
  1087.  
  1088. ; Cuts bumpoffsets down to 12bits (0yyyyy0xxxxx).
  1089. ; Converts a heightfield (8bpp) into a bumpmap (16bit).
  1090. ; INPUT:
  1091. ; a0: source APX heightmap (words)
  1092. Polygon.registerBumpmap:
  1093.     bsr    Polygon.addBumpmap
  1094.     movem.w    12(a0),d4/d7
  1095.     lea    20(a0),a0
  1096.     subq.w    #1,d7
  1097.  
  1098. .yloop:    move.w    d4,d6
  1099.     subq.w    #1,d6
  1100.  
  1101. .xloop:    moveq    #0,d0
  1102.     move.b    (a0),d0
  1103.     move.b    1(a0),d1
  1104.     lsr.b    #3,d0
  1105.     lsr.b    #3,d1
  1106.     lsl.w    #6,d0
  1107.     or.w    d1,d0
  1108.     move.w    d0,(a0)+
  1109.     dbra    d6,.xloop
  1110.  
  1111.     dbra    d7,.yloop
  1112.     rts
  1113.  
  1114. Polygon.deregisterBumpmaps:
  1115.     clr.w    Polygon.bumpmapTable
  1116.     rts
  1117.  
  1118. ; INPUT:
  1119. ; a0: bumpmap to add
  1120. Polygon.addBumpmap:
  1121.     lea    Polygon.bumpmapTable,a1
  1122.     move.w    (a1)+,d7
  1123.     move.l    a0,(a1,d7.w*4)
  1124.     addq.w    #1,-(a1)
  1125.     rts
  1126.  
  1127. ; INPUT:
  1128. ; a0: address of potential bumpmap (APX)
  1129. ; OUTPUT:
  1130. ; d0.l= 1: yes, 0: no
  1131. Polygon.isBumpmap:
  1132.     lea    Polygon.bumpmapTable,a1
  1133.     move.w    (a1)+,d7
  1134.     subq.w    #1,d7
  1135.     bmi.s    .no_match
  1136.  
  1137. .loop:    cmpa.l    (a1)+,a0
  1138.     beq.s    .match
  1139.     dbra    d7,.loop
  1140. .no_match:
  1141.     moveq    #0,d0
  1142.     rts
  1143. .match:    moveq    #1,d0                ; You've been elected bumpmap of the day!
  1144.     rts
  1145.  
  1146. Polygon.flatRoutTable:
  1147.     DC.L    Polygon.pixelFlatMoved,2
  1148.     DC.L    Polygon.pixelFlatOrred,2
  1149.     DC.L    Polygon.pixelFlatAdded,2
  1150.     DC.L    Polygon.pixelFlatceilAdded,10
  1151. Polygon.gouraudRoutTable:
  1152.     DC.L    Polygon.pixelGouraudMoved,4
  1153.     DC.L    Polygon.pixelGouraudOrred,6
  1154.     DC.L    Polygon.pixelGouraudAdded,6
  1155.     DC.L    Polygon.pixelGouraudceilAdded,12
  1156. Polygon.offsetRoutTable:
  1157.     DC.L    Polygon.pixelOffsetMoved,4
  1158.     DC.L    Polygon.pixelOffsetOrred,6
  1159.     DC.L    Polygon.pixelOffsetAdded,6
  1160.     DC.L    Polygon.pixelOffsetceilAdded,2
  1161. Polygon.textureRoutTable:
  1162.     DC.L    Polygon.pixelTextureMoved,2
  1163.     DC.L    Polygon.pixelTextureOrred,4
  1164.     DC.L    Polygon.pixelTextureAdded,4
  1165.     DC.L    Polygon.pixelTextureceilAdded,2
  1166.     IFNE    0
  1167. Polygon.bumpRoutTable:
  1168.     DC.L    Polygon.pixelBumpMoved
  1169.     DC.L    Polygon.pixelBumpOrred
  1170.     DC.L    Polygon.pixelBumpAdded
  1171.     DC.L    Polygon.pixelBumpceilAdded
  1172. Polygon.alphaRoutTable:
  1173.     DC.L    Polygon.pixelAlphaMoved
  1174.     DC.L    Polygon.pixelAlphaOrred
  1175.     DC.L    Polygon.pixelAlphaAdded
  1176.     DC.L    Polygon.pixelAlphaceilAdded
  1177.     ENDC
  1178.  
  1179. Polygon.pixelFlatMoved:
  1180.     move.b    d4,(a1)+
  1181.     move.w    d4,(a1)+
  1182.  
  1183. Polygon.pixelFlatOrred:
  1184.     or.b    d4,(a1)+
  1185.     or.w    d4,(a1)+
  1186.  
  1187. Polygon.pixelFlatAdded:
  1188.     add.b    d4,(a1)+
  1189.     add.w    d4,(a1)+
  1190.  
  1191. Polygon.pixelFlatceilAdded:
  1192.     move.b    (a1),d3
  1193.     add.b    d4,d3
  1194.     scs    d2
  1195.     or.b    d2,d4
  1196.     move.b    d4,(a1)+
  1197.     move.w    d4,(a1)+
  1198.  
  1199. Polygon.flatTail:
  1200.     dbra    d6,*-2
  1201.  
  1202.     adda.l    a5,a0
  1203.     add.l    d2,d0
  1204.     add.l    d3,d1
  1205.     DC.W    $51CF,$FFD4            ; dbra    d7,.yloop
  1206.     rts
  1207. Polygon.flatTailEnd:
  1208.  
  1209. Polygon.FLAT_TAILSIZE:    =    Polygon.flatTailEnd-Polygon.flatTail
  1210.  
  1211. Polygon.pixelGouraudMoved:
  1212.     move.b    (a2,d0.w*2),(a0)+
  1213.     move.w    (a2,d0.w*2),(a0)+
  1214.  
  1215. Polygon.pixelGouraudOrred:
  1216.     move.b    (a2,d0.w*2),d2
  1217.     or.b    d2,(a0)+
  1218.     move.w    (a2,d0.w*2),d2
  1219.     or.w    d2,(a0)+
  1220.  
  1221. Polygon.pixelGouraudAdded:
  1222.     move.b    (a2,d0.w*2),d2
  1223.     add.b    d2,(a0)+
  1224.     move.w    (a2,d0.w*2),d2
  1225.     add.w    d2,(a0)+
  1226.  
  1227. Polygon.pixelGouraudceilAdded:
  1228.     move.b    (a2,d0.w*2),d2
  1229.     add.b    (a0),d2
  1230.     scs    d3
  1231.     or.b    d3,d2
  1232.     move.b    d2,(a0)+
  1233.     move.w    (a2,d0.w*2),(a0)+
  1234.  
  1235. Polygon.gouraudTail:
  1236.     addx.l    d1,d0
  1237.     dbra    d6,*-2
  1238.  
  1239.     adda.l    d5,a6
  1240.     DC.W    $51CF,$FFC4            ; dbra    d7,.yloop
  1241.     rts
  1242. Polygon.gouraudTailEnd:
  1243.  
  1244. Polygon.GOURAUD_TAILSIZE:=    Polygon.gouraudTailEnd-Polygon.gouraudTail
  1245.  
  1246. Polygon.pixelOffsetMoved:
  1247.     move.b    (a2,d1.l*2),(a0)+
  1248.     move.w    (a2,d1.l*2),(a0)+
  1249.  
  1250. Polygon.pixelOffsetOrred:
  1251.     move.b    (a2,d1.l*2),d0
  1252.     or.b    d0,(a0)+
  1253.     move.w    (a2,d1.l*2),d0
  1254.     or.w    d0,(a0)+
  1255.  
  1256. Polygon.pixelOffsetAdded:
  1257.     move.b    (a2,d1.l*2),d0
  1258.     add.b    d0,(a0)+
  1259.     move.w    (a2,d1.l*2),d0
  1260.     add.w    d0,(a0)+
  1261.  
  1262. Polygon.pixelOffsetceilAdded:
  1263.     nop
  1264.     nop
  1265.  
  1266. Polygon.offsetTail:
  1267.     dbra    d6,*
  1268.  
  1269.     adda.l    d5,a6
  1270.     dbra    d7,*
  1271.     rts
  1272. Polygon.offsetTailEnd:
  1273.  
  1274. Polygon.OFFSET_TAILSIZE:=    Polygon.offsetTailEnd-Polygon.offsetTail
  1275.  
  1276. Polygon.pixelTextureMoved:
  1277.     move.w    (a1),(a0)+
  1278.  
  1279. Polygon.pixelTextureOrred:
  1280.     move.w    (a1),d0
  1281.     or.w    d0,(a0)+
  1282.  
  1283. Polygon.pixelTextureAdded:
  1284.     move.w    (a1),d0
  1285.     add.w    d0,(a0)+
  1286.  
  1287. Polygon.pixelTextureceilAdded:
  1288.     move.w    (a1),(a0)+        ; simple move replacement!
  1289.  
  1290. Polygon.textureTail:
  1291.     dbra    d6,*
  1292.  
  1293.     adda.l    d5,a6
  1294.     dbra    d7,*
  1295.     rts
  1296. Polygon.textureTailEnd:
  1297.  
  1298. Polygon.TEXTURE_TAILSIZE:=    Polygon.textureTailEnd-Polygon.textureTail
  1299.  
  1300. ; INPUT:
  1301. ; d0.l= color
  1302. ; a1: shadow polygon table
  1303. Polygon.clearShadows:
  1304.     clr.l    PrimitiveMesh.background
  1305.     move.w    (a1)+,d7
  1306.     beq.s    .end
  1307.     subq.w    #1,d7
  1308.     move.l    d0,Polygon.color
  1309.  
  1310. .loop:    move.w    d7,-(sp)
  1311.     bsr.s    Polygon.paintFlatshadedC
  1312.     move.w    (sp)+,d7
  1313.     dbf    d7,.loop
  1314.  
  1315. .end:    rts
  1316.  
  1317. ; INPUT:
  1318. ; a0: background picture (same dimensions as viewport!)
  1319. ; a1: shadow polygon table
  1320. Polygon.restoreShadows:
  1321.     move.l    a0,PrimitiveMesh.background
  1322.     move.w    (a1)+,d7
  1323.     beq.s    .end
  1324.     subq.w    #1,d7
  1325.  
  1326. .loop:    move.w    d7,-(sp)
  1327.     bsr.s    Polygon.paintFlatshadedC
  1328.     move.w    (sp)+,d7
  1329.     dbf    d7,.loop
  1330.  
  1331. .end:    rts
  1332.  
  1333. ; Splits a flatshaded polygon up into triangles and paints them.
  1334. ; INPUT:
  1335. ; a1: polygon (col.w, #points.w, (x,y), (x,y), ...)
  1336. ; OUTPUT:
  1337. ; a1: end of poly
  1338. Polygon.paintFlatshaded:
  1339.     moveq    #0,d0
  1340.     move.w    (a1)+,d0
  1341.     movea.l    Polygon.coloradr,a0
  1342.     lea    Primitive.GRADIENTSIZE/2(a0),a0
  1343.     lsl.l    #Primitive.GRADIENTBITS+1,d0
  1344.     move.w    (a0,d0.l),d0
  1345.     move.w    d0,d1
  1346.     swap    d0
  1347.     move.w    d1,d0
  1348.     move.l    d0,Polygon.color
  1349.  
  1350. ; Splits a flatshaded polygon up into triangles and paints them.
  1351. ; INPUT:
  1352. ; a1: polygon (#points.w, (x,y), (x,y), ...)
  1353. ; OUTPUT:
  1354. ; a1: end of poly
  1355. Polygon.paintFlatshadedC:
  1356.     move.w    (a1)+,d7
  1357.     movem.w    (a1)+,d0-d1
  1358.     subq.w    #3,d7
  1359.     movem.w    d0-d1,-(sp)            ; Push first pair on stack.
  1360.  
  1361. .loop:    movem.w    (a1)+,d2-d3
  1362.     movem.w    (a1),d4-d5
  1363.     move.w    d7,-(sp)
  1364.     move.l    a1,-(sp)
  1365.     bsr    PAINT_UNCLIPFLATTRIANGLE
  1366.     movea.l    (sp)+,a1
  1367.     move.w    (sp)+,d7
  1368.     movem.w    (sp),d0-d1
  1369.     dbf    d7,.loop
  1370.     addq    #4,sp                ; Pop first pair off.
  1371.     addq    #4,a1                ; a1: end of poly
  1372.     rts
  1373.  
  1374. Polygon.FLATUNROLL:    =    0
  1375.  
  1376. ; Splits a flatshaded polygon up into triangles and paints them.
  1377. ; Receives the crap from the hostport.
  1378. Polygon.paintDspFlatshaded:
  1379.     clr.l    d0
  1380.     receiveWordFromDsp    d0
  1381.     movea.l    Polygon.coloradr,a0
  1382.     lea    Primitive.GRADIENTSIZE/2(a0),a0
  1383.     lsl.l    #Primitive.GRADIENTBITS+1,d0
  1384.     move.w    (a0,d0.l),d2
  1385.     move.w    d2,d1
  1386.     swap    d2
  1387.     move.w    d1,d2
  1388.     bra.s    Polygon.paintDspFlatshaded3
  1389.  
  1390. Polygon.paintDspFlatshaded2:
  1391.     move.l    Polygon.color,d2
  1392. Polygon.paintDspFlatshaded3:
  1393.     movea.l    Primitive.screenadr,a0
  1394.     receiveWordFromDsp    d0        ; d0.w=top y
  1395.     clr.l    d5
  1396.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  1397.     add.l    d5,d5
  1398.     mulu.w    d5,d0
  1399.     adda.l    d0,a0
  1400.     receiveWordFromDsp    d7        ; d7.w=#scans
  1401.     clr.l    d0
  1402.     clr.l    d1
  1403.     lea    $FFFFA206.w,a3
  1404.     subq.w    #1,d7
  1405.     bmi.s    .end
  1406.  
  1407.     IFNE    Polygon.FLATUNROLL
  1408.     moveq    #1<<5-1,d4
  1409.     lea    .pixeljumpend(pc),a2
  1410.     ENDC
  1411.  
  1412. .yloop:    move.w    (a3),d0                ; d0.w=lx
  1413.     move.w    (a3),d1                ; d1.w=rx
  1414.     sub.w    d0,d1                ; d1.w=length=rx-lx
  1415.     ble.s    .next
  1416.     lea    (a0,d0.l*2),a1
  1417.  
  1418.     IFNE    0
  1419.  
  1420.     lsr.w    d0
  1421.     bcc.s    .end_1st
  1422.     move.w    d2,(a1)+
  1423.     subq.w    #1,d1
  1424.     ble.s    .next
  1425. .end_1st:
  1426.     move.w    d1,d0
  1427.     lsr.w    d1
  1428.     beq.s    .last
  1429.     subq.w    #1,d1
  1430. .pixloop:
  1431.     move.l    d2,(a1)+
  1432.     dbf    d1,.pixloop
  1433. .last:    lsr.w    d0
  1434.     bcc.s    .end_last
  1435.     move.w    d2,(a1)+
  1436. .end_last:
  1437.  
  1438.     ELSE
  1439.  
  1440.     IFNE    Polygon.FLATUNROLL
  1441.  
  1442.     move.l    d1,d3
  1443.     lsr.l    #5,d1
  1444.     and.w    d4,d3
  1445.     neg.l    d3
  1446.     jmp    (a2,d3.l*2)
  1447.  
  1448.     IFNE    *&2                    ; Put it longeven!
  1449.     nop
  1450.     ENDC
  1451. .chunkloop:
  1452.     REPT    1<<5
  1453.     move.w    d2,(a1)+
  1454.     ENDR
  1455. .pixeljumpend:
  1456.     dbf    d1,.chunkloop
  1457.  
  1458.     ELSE
  1459.  
  1460.     subq.w    #1,d1
  1461.  
  1462. .xloop:    move.w    d2,(a1)+
  1463.     dbf    d1,.xloop
  1464.  
  1465.     ENDC
  1466.  
  1467.     ENDC
  1468.  
  1469. .next:    adda.l    d5,a0
  1470.     dbf    d7,.yloop
  1471. .end:    rts
  1472.  
  1473. ; Paints a gouraudshaded polygon.
  1474. ; INPUT: a1: polygon
  1475. Polygon.paintGouraudshaded:
  1476.     move.w    (a1)+,Polygon.curtexture
  1477.     move.w    #Polygon.GOURAUD_SHADING,d0
  1478.     moveq    #2,d6
  1479.     bra    Polygon.paintDsp
  1480.  
  1481. ; Paints a gouraudshaded polygon directly (slope recalc per scan included!).
  1482. ; Receives tha crap from the hostport.
  1483. Polygon.paintFastGouraudshaded:
  1484.     move.w    #Polygon.GOURAUD_SHADING,d0
  1485.     moveq    #2,d6
  1486.     bra    Polygon.paintReceived
  1487.  
  1488. ; Splits a texturemapped polygon up into triangles and paints them.
  1489. ; INPUT: a1: polygon
  1490. Polygon.paintTextured:
  1491.     move.w    (a1)+,Polygon.curtexture
  1492.     move.w    Polygon.texturemode,d0
  1493.     moveq    #3,d6
  1494.     bra.s    Polygon.paintDsp
  1495.  
  1496. ; Splits an alpha-texturemapped polygon up into triangles and paints them.
  1497. ; INPUT: a1: polygon
  1498. Polygon.paintAlphatextured:
  1499.     move.w    (a1)+,Polygon.curtexture
  1500.     moveq    #RPC_SET_V4ALPHA,d0
  1501.     sendLongToDsp    d0
  1502.     move.w    #Polygon.ALPHA_TEXTURING,d0
  1503.     moveq    #5,d6
  1504.     bra.s    Polygon.paintDsp
  1505.  
  1506. ; Splits an alpha-texturemapped polygon up into triangles and paints them.
  1507. ; INPUT: a1: polygon
  1508. Polygon.paintBumpmapped:
  1509.     move.w    (a1)+,Polygon.curtexture
  1510.     moveq    #RPC_SET_V4BUMP,d0
  1511.     sendLongToDsp    d0
  1512.     move.w    #Polygon.BUMP_TEXTURING,d0
  1513.     moveq    #5,d6
  1514.  
  1515. ; Sends polygon data to the dsp, receives incoming scanline data and paints
  1516. ; it to the screen.
  1517. ; This works for all shadetypes.
  1518. ; INPUT:
  1519. ; d0.w:    DSP texturing mode
  1520. ; d6.w:    number of coordinates in point
  1521. ;       (1=flat, 2=gouraud, 3=texture, 4=gouraudtexture, 5=alpha/bumpmap)
  1522. ; a1: polygon table
  1523. Polygon.paintDsp:
  1524.     sendLongToDsp    #RPC_PAINT_POLYGON        ; Call the DSP.
  1525.  
  1526.     clr.l    d1
  1527.     move.w    Polygon.curtexture,d1
  1528.     sendLongToDsp    d1                ; Send texturenumber.
  1529.     clr.l    d7
  1530.     move.w    (a1)+,d7
  1531.     sendLongToDsp    d7                ; Send number of points.
  1532.     move.l    d6,$ffffa204.w
  1533.     subq.w    #2,d6
  1534.     subq.w    #1,d7
  1535.  
  1536. .pointloop:
  1537.     movem.w    (a1)+,d1-d2
  1538.     ;sendLongToDsp    d2                ; Send Y.
  1539.     move.l    d2,$ffffa204.w
  1540.     ;sendLongToDsp    d1                ; Send X.
  1541.     move.l    d1,$ffffa204.w
  1542.     move.w    d6,d5
  1543.     bmi.s    .skip_coords
  1544.  
  1545. ; Send u0,v0,u1,v1
  1546. .coordloop:
  1547.     moveq    #0,d1
  1548.     move.w    (a1)+,d1
  1549.     swap    d1
  1550.     lsr.l    #1,d1
  1551.     ;sendLongToDsp    d1
  1552.     move.l    d1,$ffffa204.w
  1553.     dbra    d5,.coordloop
  1554. .skip_coords:
  1555.  
  1556.     dbra    d7,.pointloop
  1557.  
  1558.     lea    $FFFFA206.w,a1
  1559.     clr.l    d2
  1560.     receiveWordFromDsp    d2            ; Get texture number.
  1561.     movea.l    Primitive.screenadr,a0
  1562.     moveq    #0,d5
  1563.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  1564.     add.l    d5,d5
  1565.     ;receiveWordFromDsp    d1            ; Get top y.
  1566.     move.w    (a1),d1
  1567.     mulu.w    d5,d1
  1568.     adda.l    d1,a0
  1569.     movea.l    a0,a6
  1570.     ;receiveWordFromDsp    d7            ; Get height.
  1571.     move.w    (a1),d7
  1572.     subq.w    #1,d7
  1573.     bpl.s    .go_on
  1574.     rts
  1575. .go_on:    clr.l    d1
  1576.     cmpi.w    #Polygon.GOURAUD_SHADING,d0
  1577.     beq    PAINT_GOURAUDPOLY
  1578.     cmpi.w    #Polygon.PIXEL_TEXTURING,d0
  1579.     beq    PAINT_PIXELDSPPOLY
  1580.     cmpi.w    #Polygon.OFFSET_TEXTURING,d0
  1581.     beq    PAINT_OFFSETDSPPOLY
  1582.     cmpi.w    #Polygon.ALPHA_TEXTURING,d0
  1583.     beq    PAINT_ALPHADSPPOLY
  1584.     cmpi.w    #Polygon.BUMP_TEXTURING,d0
  1585.     beq    PAINT_BUMPDSPPOLY
  1586.     rts
  1587.  
  1588. ; INPUT:
  1589. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1590. Polygon.paintClippedFlatshaded:
  1591.     moveq    #0,d0
  1592.     move.w    (a1)+,d0
  1593.     movea.l    Polygon.coloradr,a0
  1594.     lea    Primitive.GRADIENTSIZE/2(a0),a0
  1595.     lsl.l    #Primitive.GRADIENTBITS+1,d0
  1596.     move.w    (a0,d0.l),d0
  1597.     move.w    d0,d1
  1598.     swap    d0
  1599.     move.w    d1,d0
  1600.     move.l    d0,Polygon.color
  1601.     move.w    #Polygon.FLAT_SHADING,d0
  1602.     moveq    #1,d6
  1603.     bra.s    Polygon.paintClipped
  1604.  
  1605. ; INPUT:
  1606. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1607. Polygon.paintClippedGouraudshaded:
  1608.     clr.l    d0
  1609.     move.w    (a1)+,d0
  1610.     movea.l    Polygon.coloradr,a0
  1611.     lsl.l    #Primitive.GRADIENTBITS+1,d0                ; d0*(64*2)
  1612.     adda.l    d0,a0
  1613.     move.l    a0,Polygon.gradadr
  1614.     move.w    #Polygon.GOURAUD_SHADING,d0
  1615.     moveq    #2,d6
  1616.     bra.s    Polygon.paintClipped
  1617.  
  1618. ; INPUT:
  1619. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1620. Polygon.paintClippedTextured:
  1621.     move.w    (a1)+,Polygon.curtexture
  1622.     move.w    Polygon.texturemode,d0
  1623.     moveq    #3,d6
  1624.     bra.s    Polygon.paintClipped
  1625.  
  1626. ; INPUT:
  1627. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1628. Polygon.paintClippedAlphatextured:
  1629.     move.w    (a1)+,Polygon.curtexture
  1630.     moveq    #RPC_SET_V4ALPHA,d0
  1631.     sendLongToDsp    d0
  1632.     move.w    #Polygon.ALPHA_TEXTURING,d0
  1633.     moveq    #5,d6
  1634.     bra.s    Polygon.paintClipped
  1635.  
  1636. ; INPUT:
  1637. ; a1: polygon table (texturenum.w, numofpoints.w, points)
  1638. Polygon.paintClippedBumpmapped:
  1639.     move.w    (a1)+,Polygon.curtexture
  1640.     moveq    #RPC_SET_V4BUMP,d0
  1641.     sendLongToDsp    d0
  1642.     move.w    #Polygon.BUMP_TEXTURING,d0
  1643.     moveq    #5,d6
  1644.  
  1645. ; Sends polygon data to the dsp, receives incoming scanline data and paints
  1646. ; it to the screen. Ofcourse this clips as well! This is a HumanFly
  1647. ; interface implementation!
  1648. ; INPUT:
  1649. ; d0.w:    DSP texturing mode
  1650. ; d6.l:    number of coordinates in point
  1651. ;       (1=flat, 2=gouraud, 3=texture, 4=gouraudtexture, 5=alpha/bumpmap)
  1652. ; a1: polygon table (numofpoints.w, points)
  1653. Polygon.paintClipped:
  1654.     sendLongToDsp    #RPC_CLIPPAINT_POLYGON        ; Call the DSP.
  1655.  
  1656.     clr.l    d1
  1657.     move.w    Polygon.curtexture,d1
  1658.     sendLongToDsp    d1                ; Send texturenumber.
  1659.     move.w    (a1)+,d7
  1660.     ext.l    d7
  1661.     sendLongToDsp    d7                ; Send number of points.
  1662.     ;sendLongToDsp    d6                ; Send pointsize.
  1663.     move.l    d6,$FFFFA204.w
  1664.     subq.w    #2,d6
  1665.     subq.w    #1,d7
  1666.  
  1667. .pointloop:
  1668.     movem.w    (a1)+,d1-d2
  1669.     ;sendLongToDsp    d2                ; Send Y.
  1670.     move.l    d2,$ffffa204.w
  1671.     ;sendLongToDsp    d1                ; Send X.
  1672.     move.l    d1,$ffffa204.w
  1673.     move.w    d6,d5
  1674.     bmi.s    .skip_coords
  1675.  
  1676. ; Send u0,v0,u1,v1
  1677. .coordloop:
  1678.     moveq    #0,d1
  1679.     move.w    (a1)+,d1
  1680.     swap    d1
  1681.     lsr.l    #1,d1
  1682.     ;sendLongToDsp    d1
  1683.     move.l    d1,$ffffa204.w
  1684.     dbf    d5,.coordloop
  1685. .skip_coords:
  1686.  
  1687.     dbf    d7,.pointloop
  1688.  
  1689.     receiveWordFromDsp    d7            ; d7=cullstatus
  1690.     bmi.s    .end                    ; Culled off?
  1691.     clr.l    d2
  1692.     receiveWordFromDsp    d2            ; Get texture number.
  1693.  
  1694.     cmpi.w    #Polygon.FLAT_SHADING,d0
  1695.     beq    Polygon.paintDspFlatshaded2
  1696.  
  1697.     lea    $ffffa206.w,a1
  1698.     movea.l    Primitive.screenadr,a0
  1699.     moveq    #0,d5
  1700.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  1701.     add.l    d5,d5
  1702.  
  1703.     receiveWordFromDsp    d1            ; Get top y.
  1704.     ;move.w    (a1),d1
  1705.  
  1706.     mulu.w    d5,d1
  1707.     adda.l    d1,a0
  1708.     movea.l    a0,a6
  1709.     ;receiveWordFromDsp    d7            ; Get height.
  1710.     move.w    (a1),d7
  1711.     subq.w    #1,d7
  1712.     bpl.s    .go_on
  1713. .end:    rts
  1714. .go_on:    clr.l    d1
  1715.     cmpi.w    #Polygon.GOURAUD_SHADING,d0
  1716.     beq    PAINT_GOURAUDPOLY
  1717.     cmpi.w    #Polygon.PIXEL_TEXTURING,d0
  1718.     beq    PAINT_PIXELDSPPOLY
  1719.     cmpi.w    #Polygon.OFFSET_TEXTURING,d0
  1720.     beq    PAINT_OFFSETDSPPOLY
  1721.     cmpi.w    #Polygon.ALPHA_TEXTURING,d0
  1722.     beq    PAINT_ALPHADSPPOLY
  1723.     cmpi.w    #Polygon.BUMP_TEXTURING,d0
  1724.     beq    PAINT_BUMPDSPPOLY
  1725.     rts
  1726.  
  1727. ; Splits a texturemapped polygon up into triangles and paints them.
  1728. ; Receives shit over hostport.
  1729. Polygon.paintDspTexturemapped:
  1730.     move.w    Polygon.texturemode,d0
  1731.     moveq    #3,d6
  1732.     bra.s    Polygon.paintReceived
  1733.  
  1734. ; Splits an alpha-texturemapped polygon up into triangles and paints them.
  1735. ; Receives trash over hostport.
  1736. Polygon.paintDspAlphatextured:
  1737.     moveq    #RPC_SET_V4ALPHA,d0
  1738.     move.w    #Polygon.ALPHA_TEXTURING,d0
  1739.     moveq    #5,d6
  1740.     bra.s    Polygon.paintReceived
  1741.  
  1742. ; Splits an alpha-texturemapped polygon up into triangles and paints them.
  1743. ; Receives rotteness over hostport.
  1744. Polygon.paintDspBumpmapped:
  1745.     moveq    #RPC_SET_V4BUMP,d0
  1746.     move.w    #Polygon.BUMP_TEXTURING,d0
  1747.     moveq    #5,d6
  1748.  
  1749. ; Receives incoming scanline data and paints it to the screen.
  1750. ; This works for all shadetypes.
  1751. ; INPUT:
  1752. ; d0.w=    DSP texturing mode (shadetype)
  1753. ; d6.w=    number of coordinates in point
  1754. ;       (1=flat, 2=gouraud, 3=texture, 4=gouraudtexture, 5=alpha/bumpmap)
  1755. Polygon.paintReceived:
  1756.     lea    $FFFFA206.w,a1
  1757.  
  1758. ; 1: Receive and store polygon outline...
  1759.     tst.w    PrimitiveMesh.shadowsOn
  1760.     beq.s    .outline_end
  1761.  
  1762.     movea.l    PrimitiveMesh.shadowStartAdr,a2
  1763.     addq.w    #1,(a2)                    ; Increase shadow poly count.
  1764.     movea.l    PrimitiveMesh.shadowAdr,a2
  1765.  
  1766.     receiveWordFromDsp    d5            ; d5.w=#vertices
  1767.     ;move.w    (a1),d5
  1768.  
  1769.     move.w    d5,(a2)+                ; Store #vertices.
  1770.     subq.w    #1,d5
  1771. .outline_loop:
  1772. ; Receive x.
  1773.     ;receiveWordFromDsp    (a2)+
  1774.     move.w    (a1),(a2)+
  1775. ; Receive y.
  1776.     ;receiveWordFromDsp    (a2)+
  1777.     move.w    (a1),(a2)+
  1778.     dbf    d5,.outline_loop
  1779.  
  1780.     move.l    a2,PrimitiveMesh.shadowAdr
  1781. .outline_end:
  1782.  
  1783. ; 2: Receive and handle painting info..
  1784.     clr.l    d2
  1785.  
  1786.     receiveWordFromDsp    d2            ; Get shadetype.
  1787.     ;move.w    (a1),d2
  1788.     ;receiveWordFromDsp    d1            ; Get top y.
  1789.     move.w    (a1),d1
  1790.     ;receiveWordFromDsp    d7            ; Get height.
  1791.     move.w    (a1),d7
  1792.  
  1793.     subq.w    #1,d7
  1794.     bpl.s    .go_on
  1795.     rts
  1796.  
  1797. ; d1.w=top y
  1798. ; d2.w=shadetype
  1799. ; d7.w=height-1
  1800. .go_on:    movea.l    Primitive.screenadr,a0
  1801.     clr.l    d5
  1802.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  1803.     add.l    d5,d5
  1804.     mulu.w    d5,d1
  1805.     adda.l    d1,a0
  1806.     movea.l    a0,a6
  1807. ; a0=a6=screen pos
  1808. ; d7.w=height-1
  1809.  
  1810. ; 3: and paint..
  1811.     clr.l    d1
  1812.     cmpi.w    #Polygon.GOURAUD_SHADING,d0
  1813.     beq    PAINT_GOURAUDPOLY
  1814.     cmpi.w    #Polygon.PIXEL_TEXTURING,d0
  1815.     beq    PAINT_PIXELDSPPOLY
  1816.     cmpi.w    #Polygon.OFFSET_TEXTURING,d0
  1817.     beq    PAINT_OFFSETDSPPOLY
  1818.     cmpi.w    #Polygon.ALPHA_TEXTURING,d0
  1819.     beq    PAINT_ALPHADSPPOLY
  1820.     cmpi.w    #Polygon.BUMP_TEXTURING,d0
  1821.     beq    PAINT_BUMPDSPPOLY
  1822.     rts
  1823.  
  1824. ; This should be both fast as well as accurate. At least.. faster than
  1825. ; texturemapping. Prolly something like 1.500.000 pixels/s on standard
  1826. ; Falcon.
  1827. PAINT_GOURAUDPOLY:
  1828.     movea.w    Primitive.skipBytes,a3
  1829.     movea.l    Polygon.coloradr,a2
  1830.     lsl.l    #Primitive.GRADIENTBITS+1,d2                ; d0*(64*2)
  1831.     adda.l    d2,a2
  1832.  
  1833. Polygon.gouraudYloop:
  1834. .wait:    btst.b    #0,$ffffa202.w
  1835.     beq.s    .wait
  1836.  
  1837.     move.w    (a1),d1                    ; Get left x.
  1838.     lea    (a6,d1.w*2),a0
  1839.     move.w    (a1),d6                    ; Get width.
  1840.     clr.l    d0
  1841.     clr.l    d1
  1842.     receiveLongFromDsp    d0            ; d0.l = left u
  1843.     swap    d0
  1844.     ext.w    d0
  1845.     receiveLongFromDsp    d1            ; d1.l = u_step
  1846.     swap    d1
  1847.     ext.w    d1
  1848.     subq.w    #1,d6
  1849.     bpl.s    .go_on
  1850.     adda.l    d5,a6
  1851.     dbra    d7,Polygon.gouraudYloop    
  1852.     rts
  1853. .go_on:
  1854.  
  1855. Polygon.gouraudPixelInstr:
  1856. .xloop:    move.w    (a2,d0.w*2),(a0)+
  1857.     addx.l    d1,d0
  1858.     dbra    d6,.xloop
  1859.  
  1860.     adda.l    d5,a6
  1861.     dbra    d7,Polygon.gouraudYloop
  1862.     rts
  1863.  
  1864.     nop                        ; for code gen crap
  1865.     nop
  1866.     nop
  1867.     nop
  1868.  
  1869. CHUNKLOG:    =    4
  1870.  
  1871. ; This is slow. But since it can do a polygon instead of only a triangle,
  1872. ; I'm content. Speed on a plain falcon is 500.000 texels/s _including_
  1873. ; overhead.
  1874. ; INPUT:
  1875. ; d2.w= texturenumber
  1876. PAINT_OFFSETDSPPOLY:
  1877.     clr.l    d1
  1878.     movea.w    Primitive.skipBytes,a3
  1879.     lea    Polygon.textureTable,a2
  1880.     movea.l    (a2,d2.w*4),a2
  1881.  
  1882. Polygon.offsetYloop:
  1883.     move.w    (a1),d1                    ; d1.w=lx
  1884.     lea    (a6,d1.l*2),a0
  1885.     receiveWordFromDsp    d6            ; d6.w=width
  1886.     bgt.s    .go_on
  1887.     adda.l    d5,a6
  1888.     dbra    d7,Polygon.offsetYloop
  1889.     rts
  1890. .go_on:    subq.w    #1,d6
  1891.  
  1892.     move.w    (a1),d1
  1893. Polygon.offsetPixelInstr:
  1894.     move.w    (a2,d1.l*2),(a0)+
  1895.     dbra    d6,Polygon.offsetPixelInstr-2
  1896.  
  1897.     adda.l    d5,a6
  1898.     dbra    d7,Polygon.offsetYloop
  1899.     rts
  1900.  
  1901.     nop
  1902.     nop
  1903.  
  1904. DSP_SYNC:    =    1
  1905.  
  1906. ; This is fast on a plain falcon. In fact, it kicks every other rout
  1907. ; I've seen square in the nuts!!! =)) Speeds of 1.100.000 texels/s
  1908. ; _including_ overhead are no exception!
  1909. ; Though this unrolled jumptree sucks on ct2.
  1910. PAINT_PIXELDSPPOLY:
  1911.     moveq    #1<<CHUNKLOG-1,d4
  1912. Polygon.textureLoadInstr:
  1913.     lea    Polygon.pixeljumpend,a2
  1914.     clr.l    d6
  1915.  
  1916. Polygon.textureYloop:
  1917. .yloop:    move.w    (a1),d1                    ; Get left x.
  1918.     lea    (a6,d1.l*2),a0
  1919.     move.w    (a1),d6                    ; Get width.
  1920.     bgt.s    .go_on
  1921.     adda.l    d5,a6
  1922.     dbra    d7,.yloop
  1923.     rts
  1924. .go_on:    move.l    d6,d3
  1925.     lsr.l    #CHUNKLOG,d6
  1926.     and.l    d4,d3
  1927.     neg.l    d3
  1928. Polygon.textureJmpInstr:
  1929.     jmp    (a2,d3.l*2)
  1930.  
  1931.     IFNE    *&2                    ; Put it longeven!
  1932.     nop
  1933.     ENDC
  1934.  
  1935. Polygon.texturePixelInstr:
  1936.     REPT    1<<CHUNKLOG
  1937.     move.w    (a1),(a0)+
  1938.     ENDR
  1939. Polygon.pixeljumpend:
  1940.     dbf    d6,Polygon.texturePixelInstr
  1941.  
  1942.     adda.l    d5,a6
  1943.     dbf    d7,Polygon.textureYloop
  1944.     rts
  1945.  
  1946.     DS.W    1<<CHUNKLOG
  1947.  
  1948. ; Speed of >500.000 texels/s _including_ overhead.
  1949. PAINT_ALPHADSPPOLY:
  1950.     movea.l    Polygon.alphatableadr,a2
  1951.  
  1952. .yloop:    move.w    (a1),d1                    ; Get left x.
  1953.     lea    (a6,d1.l*2),a0
  1954.     move.w    (a1),d6                    ; Get width.
  1955.     subq.w    #1,d6
  1956.     bmi.s    .end_xloop
  1957.  
  1958. .wait:    btst.b    #0,$FFFFA202.w
  1959.     beq.s    .wait
  1960.  
  1961. .xloop:    move.w    (a1),d1
  1962.     move.w    (a2,d1.l*2),(a0)+
  1963. ; Shit! takes 14 cycles to sync on CT2.
  1964.     IFNE    DSP_SYNC
  1965.     rol.l    d0,d0
  1966.     rol.l    #4,d0
  1967.     ENDC
  1968.     dbra    d6,.xloop
  1969. .end_xloop:
  1970.  
  1971.     adda.l    d5,a6
  1972.     dbra    d7,.yloop
  1973.  
  1974. .end:    rts
  1975.  
  1976. ; Speed of 800.000 texels/s _including_ overhead.
  1977. PAINT_BUMPDSPPOLY:
  1978. .yloop:    move.w    (a1),d1                    ; Get left x.
  1979.     lea    (a6,d1.l*2),a0
  1980.     move.w    (a1),d6                    ; Get width.
  1981.     subq.w    #1,d6
  1982.     bmi.s    .end_xloop
  1983.  
  1984. .wait:    btst.b    #0,$ffffa202.w
  1985.     beq.s    .wait
  1986.  
  1987. .xloop:    move.w    (a1),(a0)+
  1988. ; Shit! takes 16 cycles to sync on CT2.
  1989.     IFNE    DSP_SYNC
  1990.     rol.l    d0,d0
  1991.     rol.l    d0,d0
  1992.     nop
  1993.     nop
  1994.     ELSE
  1995.     nop                        ; needed even on plain falcon!!
  1996.     nop
  1997.     ENDC
  1998.     dbra    d6,.xloop
  1999. .end_xloop:
  2000.  
  2001.     adda.l    d5,a6
  2002.     dbra    d7,.yloop
  2003.  
  2004. .end:    rts
  2005.  
  2006. ;======= Fragment
  2007.  
  2008.             RSRESET
  2009. Fragment.LSLOPE:    RS.L    1        ; 16:16 fixed point
  2010. Fragment.RSLOPE:    RS.L    1        ; 16:16 fixed point
  2011. Fragment.LX:        RS.W    1        ; left X
  2012. Fragment.RX:        RS.W    1        ; right X
  2013. Fragment.LUSTART:    RS.W    1        ; 8:8 index
  2014. Fragment.LVSTART:    RS.W    1        ; 8:8 index
  2015. Fragment.RUSTART:    RS.W    1        ; 8:8 index
  2016. Fragment.RVSTART:    RS.W    1        ; 8:8 index
  2017. Fragment.LUSLOPE:    RS.W    1        ; 8:8 slope
  2018. Fragment.LVSLOPE:    RS.W    1        ; 8:8 slope
  2019. Fragment.RUSLOPE:    RS.W    1        ; 8:8 slope
  2020. Fragment.RVSLOPE:    RS.W    1        ; 8:8 slope
  2021. Fragment.START:        RS.W    1        ; start scanline of fragment
  2022. Fragment.HEIGHT:    RS.W    1        ; height of fragment
  2023. Fragment.SIZE:        RS.B    0
  2024.  
  2025. Fragment.shadeMask:    =    %00000111
  2026. Fragment.shadeFlat:    =    %000
  2027. Fragment.shadeGradient:    =    %001
  2028. Fragment.shadeTexture:    =    %010
  2029. Fragment.shadeAlpha:    =    %011
  2030. Fragment.shadeBump:    =    %100
  2031. Fragment.maskMode:    =    %00001000
  2032. Fragment.clipMode:    =    %00010000
  2033.  
  2034. ; Paints an unclipped triangle. No in-/off-screen check whatsoever!
  2035. ; Make sure triangle is 100% IN SCREEN!
  2036. ; INPUT:
  2037. ; d0.l: X0
  2038. ; d1.l: Y0
  2039. ; d2.l: X1
  2040. ; d3.l: Y1
  2041. ; d4.l: X2
  2042. ; d5.l: X2
  2043. PAINT_UNCLIPFLATTRIANGLE:
  2044. ; Sort points in Y-order.
  2045. .sort_y:
  2046.     cmp.l    d1,d3
  2047.     bgt.s    .first_y_ok
  2048.     exg    d0,d2
  2049.     exg    d1,d3
  2050. .first_y_ok:
  2051.     cmp.l    d1,d5
  2052.     bgt.s    .first_y_ok2
  2053.     exg    d0,d4
  2054.     exg    d1,d5
  2055. .first_y_ok2:
  2056.     cmp.l    d3,d5
  2057.     bgt.s    .second_y_ok
  2058.     exg    d2,d4
  2059.     exg    d3,d5
  2060. .second_y_ok:
  2061.     movea.l    d0,a0
  2062.     movea.l    d1,a1
  2063.     movea.l    d2,a2
  2064.     movea.l    d3,a3
  2065.     movea.l    d4,a4
  2066.     movea.l    d5,a5
  2067. .end_sort_y:
  2068.  
  2069. .calc_slopes_height:
  2070. ; X2-X1 X3-X1 X3-X2
  2071. ; Y2-Y1 Y3-Y1 Y3-Y2
  2072.     sub.l    d2,d4                ; X3-X2
  2073.     sub.l    d0,d2                ; X2-X1
  2074.     suba.l    d0,a4                ; X3-X1
  2075.     move.l    d2,d0
  2076.     move.l    a4,d2
  2077.     sub.l    d3,d5                ; Y3-Y2
  2078.     sub.l    d1,d3                ; Y2-Y1
  2079.     suba.l    d1,a5                ; Y3-Y1
  2080.     move.l    d3,d1
  2081.     move.l    a5,d3
  2082.     lea    Polygon.invTable,a6
  2083.     muls.w    (a6,d1.l*2),d0
  2084.     muls.w    (a6,d3.l*2),d2
  2085.     muls.w    (a6,d5.l*2),d4
  2086.     add.l    d0,d0
  2087.     add.l    d2,d2
  2088.     add.l    d4,d4
  2089. .end_calcslopes:
  2090.  
  2091. ; side 1: upper point <-> middle point
  2092. ; d0.l: 16:16 slope of side 1
  2093. ; d1.l: height of side 1
  2094. ; side 2: upper point <-> lower point
  2095. ; d2.l: 16:16 slope of side 2
  2096. ; d3.l: height of side 2
  2097. ; side 3: middle point <-> lower point
  2098. ; d4.l: 16:16 slope of side 3
  2099. ; d5.l: heigth of side 3
  2100.  
  2101. ; Special case for triangles that have a horizontal edge.
  2102.     move.w    a3,.a3
  2103.     tst.l    PrimitiveMesh.background
  2104.     beq.s    .clear_it
  2105.     lea    RESTORE_UNCLIPFLATFRAG(pc),a4
  2106.     bra.s    .rout_set
  2107. .clear_it:
  2108.     lea    PAINT_UNCLIPFLATFRAGMENT(pc),a4
  2109. .rout_set:
  2110.     tst.w    d1
  2111.     bne.s    .make_fragments
  2112.     move.w    d3,d7
  2113.     subq.w    #1,d7
  2114.     bmi    .end_paint_triangle
  2115.     move.l    d4,d3
  2116.     move.l    Polygon.color,d4
  2117.     moveq    #0,d0
  2118.     move.w    a0,d0
  2119.     swap    d0
  2120.     moveq    #0,d1
  2121.     move.w    a2,d1
  2122.     swap    d1
  2123.     cmp.l    d0,d1
  2124.     bgt.s    .start_x_okay
  2125.     exg    d0,d1
  2126.     exg    d2,d3
  2127. .start_x_okay:
  2128.     movea.l    Primitive.screenadr,a0
  2129.     movea.l    PrimitiveMesh.background,a3
  2130.     move.l    a1,d6
  2131.     mulu.w    Viewport.settingsTable+Viewport.XSCREEN,d6
  2132.     add.l    d6,d6
  2133.     adda.l    d6,a0
  2134.     adda.l    d6,a3
  2135.  
  2136.     jmp    (a4)
  2137.  
  2138. .make_fragments:
  2139.     lea    Polygon.fragmentTable,a6
  2140.     cmp.l    d0,d2
  2141.     blt.s    .make_fragments_rl
  2142.  
  2143. .make_fragments_lr:
  2144.     move.l    d4,(a6)+            ; Store left slope.
  2145.     move.l    d2,(a6)+            ; Store right slope.
  2146.     move.w    a2,(a6)+            ; Store left x.
  2147.     move.w    #$8000,(a6)+            ; Store right x.
  2148.     move.w    .a3(pc),(a6)+            ; Store y.
  2149.     move.w    d5,(a6)+            ; Store height.
  2150.  
  2151.     move.w    d1,d7
  2152.     move.l    Polygon.color,d4
  2153.     move.l    d2,d3
  2154.     move.l    d0,d2
  2155.     moveq    #0,d0
  2156.     move.w    a0,d0
  2157.     swap    d0
  2158.     move.l    d0,d1
  2159.     subq.w    #1,d7
  2160.     bmi.s    .end_paint_upper_lr
  2161.     movea.l    Primitive.screenadr,a0
  2162.     movea.l    PrimitiveMesh.background,a3
  2163.     move.w    a1,d6
  2164.     mulu.w    Viewport.settingsTable+Viewport.XSCREEN,d6
  2165.     add.l    d6,d6
  2166.     adda.l    d6,a0
  2167.     adda.l    d6,a3
  2168.  
  2169.     jsr    (a4)
  2170.  
  2171. .end_paint_upper_lr:
  2172.  
  2173.      bra.s    .end_make_fragments
  2174.  
  2175. .make_fragments_rl:
  2176.     move.l    d2,(a6)+            ; Store left slope.
  2177.     move.l    d4,(a6)+            ; Store right slope.
  2178.     move.w    #$8000,(a6)+            ; Store left x.
  2179.     move.w    a2,(a6)+            ; Store right x.
  2180.     move.w    .a3(pc),(a6)+            ; Store y.
  2181.     move.w    d5,(a6)+            ; Store height.
  2182.  
  2183.     move.w    d1,d7
  2184.     move.l    Polygon.color,d4
  2185.     move.l    d0,d3
  2186.     moveq    #0,d0
  2187.     move.w    a0,d0
  2188.     swap    d0
  2189.     move.l    d0,d1
  2190.     subq.w    #1,d7
  2191.     bmi.s    .end_paint_upper_rl
  2192.     movea.l    Primitive.screenadr,a0
  2193.     movea.l    PrimitiveMesh.background,a3
  2194.     move.w    a1,d6
  2195.     mulu.w    Viewport.settingsTable+Viewport.XSCREEN,d6
  2196.     add.l    d6,d6
  2197.     adda.l    d6,a0
  2198.     adda.l    d6,a3
  2199.  
  2200.     jsr    (a4)
  2201.  
  2202. .end_paint_upper_rl:
  2203.  
  2204. .end_make_fragments:
  2205.  
  2206. .paint_lower_fragment:
  2207. ;    bra    .end_paint_fragments
  2208.     lea    -16(a6),a6
  2209.     move.l    (a6)+,d2            ; Get left slope.
  2210.     move.l    (a6)+,d3            ; Get right slope.
  2211.  
  2212. .get_new_lx:
  2213.     moveq    #0,d7
  2214.     move.w    (a6)+,d7            ; Get left x.
  2215.     cmpi.w    #$8000,d7
  2216.     beq.s    .end_get_new_lx
  2217.     move.l    d7,d0
  2218.     swap    d0
  2219. .end_get_new_lx:
  2220.  
  2221. .get_new_rx:
  2222.     move.w    (a6)+,d7            ; Get right x.
  2223.     cmpi.w    #$8000,d7
  2224.     beq.s    .end_get_new_rx
  2225.     move.l    d7,d1
  2226.     swap    d1
  2227. .end_get_new_rx:
  2228.  
  2229.     movea.l    Primitive.screenadr,a0
  2230.     movea.l    PrimitiveMesh.background,a3
  2231.     move.w    (a6)+,d7            ; Get y.
  2232.     mulu.w    Viewport.settingsTable+Viewport.XSCREEN,d7
  2233.     add.l    d7,d7
  2234.     adda.l    d7,a0
  2235.     adda.l    d7,a3
  2236.     move.w    (a6)+,d7            ; Get height.
  2237.     subq.w    #1,d7
  2238.     bmi.s    .end_paint_fragments
  2239.  
  2240.     jmp    (a4)
  2241.  
  2242. .skip_lower_fragment:
  2243. .end_paint_fragments:
  2244.  
  2245. .end_paint_triangle:
  2246.     rts
  2247.  
  2248. .a3:    DC.W    0
  2249.  
  2250. ; Subroutine that paints a flatshaded fragment. NO clipping!
  2251. ; INPUT:
  2252. ; d0.l: 16:16 left X-start
  2253. ; d1.l: 16:16 right X-start
  2254. ; d2.l: 16:16 left stepvalue
  2255. ; d3.l: 16:16 right stepvalue
  2256. ; d4.l: 16:16 color (double highcolor)
  2257. ; d7.w: number of scanlines to paint - 1
  2258. ; a0: start of begin screenline
  2259. ; OUTPUT: a0: start of next screenline
  2260. PAINT_UNCLIPFLATFRAGMENT:
  2261.     movea.w    Viewport.settingsTable+Viewport.XSCREEN,a5
  2262.     adda.l    a5,a5
  2263.     movea.w    Primitive.skipBytes,a2
  2264.  
  2265. Polygon.flatFragmentYloop:
  2266. .yloop:    move.l    d0,d5
  2267.     move.l    d1,d6
  2268.     swap    d5
  2269.     swap    d6
  2270.  
  2271.     sub.w    d5,d6
  2272.     bgt.s    .go_on
  2273.  
  2274.     adda.l    a5,a0
  2275.     add.l    d2,d0
  2276.     add.l    d3,d1
  2277.     dbra    d7,.yloop
  2278.     rts
  2279.  
  2280. .go_on:    subq.w    #1,d6
  2281.     lea    (a0,d5.w*2),a1
  2282.  
  2283. Polygon.flatPixelInstr:
  2284. .xloop:    move.w    d4,(a1)+
  2285.     dbf    d6,.xloop
  2286.  
  2287.     adda.l    a5,a0
  2288.     add.l    d2,d0
  2289.     add.l    d3,d1
  2290.     dbf    d7,Polygon.flatFragmentYloop
  2291.     rts
  2292.  
  2293.     nop                        ; crap for code-gen
  2294.     nop
  2295.     nop
  2296.     nop
  2297.  
  2298. ; TODO: prepare this for different paintmodes! (byte, skip)
  2299. ; Subroutine that restores a fragment. NO clipping!
  2300. ; INPUT:
  2301. ; d0.l: 16:16 left X-start
  2302. ; d1.l: 16:16 right X-start
  2303. ; d2.l: 16:16 left stepvalue
  2304. ; d3.l: 16:16 right stepvalue
  2305. ; d4.l: 16:16 color (double highcolor)
  2306. ; d7.w: number of scanlines to paint - 1
  2307. ; a0: dst screenline
  2308. ; a3: src screenline
  2309. ; OUTPUT:
  2310. ; a0: next dst screenline
  2311. ; a3: next src screenline
  2312. RESTORE_UNCLIPFLATFRAG:
  2313.     movea.w    Viewport.settingsTable+Viewport.XSCREEN,a5
  2314.     adda.l    a5,a5
  2315.     movea.w    Primitive.skipBytes,a2
  2316.  
  2317. Polygon.restoreFragmentYloop:
  2318. .yloop:    move.l    d0,d5
  2319.     move.l    d1,d6
  2320.     swap    d5
  2321.     swap    d6
  2322.  
  2323.     sub.w    d5,d6
  2324.     bgt.s    .go_on
  2325.  
  2326.     adda.l    a5,a0
  2327.     adda.l    a5,a3
  2328.     add.l    d2,d0
  2329.     add.l    d3,d1
  2330.     dbra    d7,.yloop
  2331.     rts
  2332.  
  2333. .go_on:    lea    (a0,d5.w*2),a1
  2334.     lea    (a3,d5.w*2),a3
  2335.     add.w    d6,d5
  2336.     subq.w    #1,d6
  2337.  
  2338. Polygon.restorePixelInstr:
  2339. .xloop:    move.w    (a3)+,(a1)+
  2340.     dbf    d6,.xloop
  2341.  
  2342.     adda.l    a5,a0
  2343.     adda.l    a5,a3
  2344.     suba.w    d5,a3
  2345.     suba.w    d5,a3
  2346.     add.l    d2,d0
  2347.     add.l    d3,d1
  2348.     dbf    d7,Polygon.restoreFragmentYloop
  2349.  
  2350.     rts
  2351.  
  2352.     nop                        ; crap for code-gen
  2353.     nop
  2354.     nop
  2355.     nop
  2356.  
  2357.  
  2358.     IFNE    0
  2359.  
  2360.         RSRESET
  2361. v4EdgeXSlope:    RS.L    1
  2362. v4EdgeU0Slope:    RS.W    1
  2363. v4EdgeV0Slope:    RS.W    1
  2364. v4EdgeU1Slope:    RS.W    1
  2365. v4EdgeV1Slope:    RS.W    1
  2366. v4EdgeXStart:    RS.W    1
  2367. v4EdgeYStart:    RS.W    1
  2368. v4EdgeU0Start:    RS.W    1
  2369. v4EdgeV0Start:    RS.W    1
  2370. v4EdgeU1Start:    RS.W    1
  2371. v4EdgeV1Start:    RS.W    1
  2372. v4EdgeDY:    RS.W    1
  2373. v4EdgeSize:    RS.B    0
  2374.  
  2375. ; Subroutine that draws a v4-textured fragment to a table.
  2376. ; Vertical and horizontal clipping are NOT this routine's responsibility.
  2377. ; INPUT:
  2378. ; d0.l: 8:8:8:8 (000V) left V0-start
  2379. ; d1.l: 8:8:8:8 (000V) left V1-start
  2380. ; a5.l: 8:8:8:8 (v0Uu) left U0-step, left V0-step
  2381. ; d3.l: 8:8:8:8 (000V) left V0-step
  2382. ; a6.l: 8:8:8:8 (v0Uu) left U1-step, left V1-step
  2383. ; d5.l: 8:8:8:8 (000V) left V1-step
  2384. ; d7.w: number of scanlines to paint - 1
  2385. ; a0: startentry of scanline table
  2386. ; a1.l: 16:16 (XXxx) left X-start
  2387. ; a2.l: 16:16 (XXxx) right X-start
  2388. ; a3.l: 16:16 (XXxx) left X-step
  2389. ; a4.l: 16:16 (XXxx) right X-step
  2390. ; d2.l: 8:8:8:8 (v0Uu) left U0-start, left V0-start
  2391. ; d4.l: 8:8:8:8 (v0Uu) left U1-start, left V1-start
  2392. ; OUTPUT:
  2393. ; a0: start of next scanline entry
  2394. DRAW_V4FRAGMENT:
  2395. .scanline_loop:
  2396.     move.l    a1,d6                ;  2
  2397.     swap    d6                ;  4
  2398.     move.w    d6,(a0)+            ; ?8
  2399.     move.l    a2,d6                ;  2
  2400.     swap    d6                ;  4
  2401.     move.w    d6,(a0)+            ; ?8
  2402.     move.w    d2,(a0)+            ; ?8
  2403.     move.w    d0,(a0)+            ; ?8
  2404.     move.w    d4,(a0)+            ; ?8
  2405.     move.w    d1,(a0)+            ; ?8
  2406.     adda.l    a3,a1                ;  2
  2407.     adda.l    a4,a2                ;  2
  2408.     add.w    a5,d2                ;  2
  2409.     add.w    d3,d0                ;  2
  2410.     add.w    a6,d4                ;  2
  2411.     add.w    d5,d1                ;  2
  2412.     dbra    d7,.scanline_loop        ;  6
  2413.                         ; 74
  2414.     rts
  2415.  
  2416. ; INPUT:
  2417. ; d0.l: x0
  2418. ; d1.l: y0
  2419. ; d2.l: x1
  2420. ; d3.l: y1
  2421. ; d4.l: x2
  2422. ; d5.l: y2
  2423. ; a0: address of 1st uv-table (u0,v0,u1,v1)
  2424. ; a1: address of uv-table (u0,v0,u1,v1)
  2425. ; a2: address of uv-table (u0,v0,u1,v1)
  2426. PAINT_UNCLIPV4TRIANGLE:
  2427.     movea.l    a0,a3
  2428.     movea.l    a1,a4
  2429.     movea.l    a2,a5
  2430.  
  2431. ; d0.l: X1
  2432. ; d1.l: Y1
  2433. ; d2.l: X2
  2434. ; d3.l: Y2
  2435. ; d4.l: X3
  2436. ; d5.l: Y3
  2437. ; a3.l: address of 1st uv-table
  2438. ; a4.l: address of 2nd uv-table
  2439. ; a5.l: address of 3rd uv-table
  2440.  
  2441. ; Sort points in Y-order.
  2442. .sort_y:
  2443.     cmp.l    d1,d3
  2444.     bgt.s    .first_y_ok
  2445.     exg    d0,d2
  2446.     exg    d1,d3
  2447.     exg    a3,a4
  2448. .first_y_ok:
  2449.     cmp.l    d1,d5
  2450.     bgt.s    .first_y_ok2
  2451.     exg    d0,d4
  2452.     exg    d1,d5
  2453.     exg    a3,a5
  2454. .first_y_ok2:
  2455.     cmp.l    d3,d5
  2456.     bgt.s    .second_y_ok
  2457.     exg    d2,d4
  2458.     exg    d3,d5
  2459.     exg    a4,a5
  2460. .second_y_ok:
  2461. .end_sort_y:
  2462.  
  2463. .calc_edges:
  2464. ; X2-X1 X3-X1 X3-X2
  2465. ; Y2-Y1 Y3-Y1 Y3-Y2
  2466. ; I2-I1 I3-I1 I3-I2
  2467.  
  2468.     lea    Polygon.invTable,a6
  2469.     lea    .edges_tbl,a0
  2470.     lea    v4EdgeSize(a0),a1
  2471.     lea    v4EdgeSize(a1),a2
  2472.     move.w    d0,v4EdgeXStart(a0)
  2473.     move.w    d1,v4EdgeYStart(a0)
  2474.     move.l    d2,d6
  2475.     move.l    d3,d7
  2476.     sub.l    d0,d6
  2477.     sub.l    d1,d7
  2478.     muls.w    (a6,d7.l*2),d6
  2479.     add.l    d6,d6
  2480.     move.l    d6,v4EdgeXSlope(a0)
  2481.     move.l    (a3),v4EdgeU0Start(a0)        ; u0,v0
  2482.     move.l    4(a3),v4EdgeU1Start(a0)        ; u1,v1
  2483.     move.w    (a4)+,d6
  2484.     sub.w    (a3)+,d6
  2485.     muls.w    (a6,d7.l*2),d6
  2486.     asr.l    #7,d6
  2487.     move.w    d6,v4EdgeU0Slope(a0)
  2488.     move.w    (a4)+,d6
  2489.     sub.w    (a3)+,d6
  2490.     muls.w    (a6,d7.l*2),d6
  2491.     asr.l    #7,d6
  2492.     move.w    d6,v4EdgeV0Slope(a0)
  2493.     move.w    (a4)+,d6
  2494.     sub.w    (a3)+,d6
  2495.     muls.w    (a6,d7.l*2),d6
  2496.     asr.l    #7,d6
  2497.     move.w    d6,v4EdgeU1Slope(a0)
  2498.     move.w    (a4)+,d6
  2499.     sub.w    (a3)+,d6
  2500.     muls.w    (a6,d7.l*2),d6
  2501.     asr.l    #7,d6
  2502.     move.w    d6,v4EdgeV1Slope(a0)
  2503.     subq    #8,a3
  2504.     subq    #8,a4
  2505.     move.w    d7,v4EdgeDY(a0)
  2506.  
  2507. ;    move.w    d0,v4EdgeXStart(a1)
  2508. ;    move.w    d1,v4EdgeYStart(a1)
  2509.     move.l    d4,d6
  2510.     move.l    d5,d7
  2511.     sub.l    d0,d6
  2512.     sub.l    d1,d7
  2513.     muls.w    (a6,d7.l*2),d6
  2514.     add.l    d6,d6
  2515.     move.l    d6,v4EdgeXSlope(a1)
  2516. ;    move.l    a3,v4EdgeUStart(a1)        ; u,v
  2517.     move.w    (a5)+,d6
  2518.     sub.w    (a3)+,d6
  2519.     muls.w    (a6,d7.l*2),d6
  2520.     asr.l    #7,d6
  2521.     move.w    d6,v4EdgeU0Slope(a1)
  2522.     move.w    (a5)+,d6
  2523.     sub.w    (a3)+,d6
  2524.     muls.w    (a6,d7.l*2),d6
  2525.     asr.l    #7,d6
  2526.     move.w    d6,v4EdgeV0Slope(a1)
  2527.     move.w    (a5)+,d6
  2528.     sub.w    (a3)+,d6
  2529.     muls.w    (a6,d7.l*2),d6
  2530.     asr.l    #7,d6
  2531.     move.w    d6,v4EdgeU1Slope(a1)
  2532.     move.w    (a5)+,d6
  2533.     sub.w    (a3)+,d6
  2534.     muls.w    (a6,d7.l*2),d6
  2535.     asr.l    #7,d6
  2536.     move.w    d6,v4EdgeV1Slope(a1)
  2537.     subq    #8,a3
  2538.     subq    #8,a5
  2539. ;    move.w    d7,v4EdgeDY(a1)
  2540.  
  2541.     move.w    d2,v4EdgeXStart(a2)
  2542.     move.w    d3,v4EdgeYStart(a2)
  2543.     move.l    d4,d6
  2544.     move.l    d5,d7
  2545.     sub.l    d2,d6
  2546.     sub.l    d3,d7
  2547.     muls.w    (a6,d7.l*2),d6
  2548.     add.l    d6,d6
  2549.     move.l    d6,v4EdgeXSlope(a2)
  2550.     move.l    (a4),v4EdgeU0Start(a2)        ; u0,v0
  2551.     move.l    4(a4),v4EdgeU1Start(a2)        ; u1,v1
  2552.     move.w    (a5)+,d6
  2553.     sub.w    (a4)+,d6
  2554.     muls.w    (a6,d7.l*2),d6
  2555.     asr.l    #7,d6
  2556.     move.w    d6,v4EdgeU0Slope(a2)
  2557.     move.w    (a5)+,d6
  2558.     sub.w    (a4)+,d6
  2559.     muls.w    (a6,d7.l*2),d6
  2560.     asr.l    #7,d6
  2561.     move.w    d6,v4EdgeV0Slope(a2)
  2562.     move.w    (a5)+,d6
  2563.     sub.w    (a4)+,d6
  2564.     muls.w    (a6,d7.l*2),d6
  2565.     asr.l    #7,d6
  2566.     move.w    d6,v4EdgeU1Slope(a2)
  2567.     move.w    (a5)+,d6
  2568.     sub.w    (a4)+,d6
  2569.     muls.w    (a6,d7.l*2),d6
  2570.     asr.l    #7,d6
  2571.     move.w    d6,v4EdgeV1Slope(a2)
  2572.     subq    #8,a4
  2573.     subq    #8,a5
  2574.     move.w    d7,v4EdgeDY(a2)
  2575. .end_calc_edges:
  2576.  
  2577. ; Calculate horizontal intensity slope.
  2578. .calcslope:
  2579.     cmp.l    d1,d3
  2580.     bne.s    .not_edge1
  2581.     move.l    d2,d7
  2582.     sub.l    d0,d7
  2583.     addq.w    #1,d7
  2584.     move.w    (a4)+,d0
  2585.     sub.w    (a3)+,d0
  2586.     ext.l    d0
  2587.     lsl.l    #8,d0
  2588.     divs.w    d7,d0
  2589.     move.w    (a4)+,d1
  2590.     sub.w    (a3)+,d1
  2591.     ext.l    d1
  2592.     lsl.l    #8,d1
  2593.     divs.w    d7,d1
  2594.     move.w    (a4)+,d2
  2595.     sub.w    (a3)+,d2
  2596.     ext.l    d2
  2597.     lsl.l    #8,d2
  2598.     divs.w    d7,d2
  2599.     move.w    (a4)+,d3
  2600.     sub.w    (a3)+,d3
  2601.     ext.l    d3
  2602.     lsl.l    #8,d3
  2603.     divs.w    d7,d3
  2604.     bra    .end_calcslope
  2605. .not_edge1:
  2606.     cmp.l    d3,d5
  2607.     bne.s    .not_edge3
  2608.     move.l    d4,d7
  2609.     sub.l    d2,d7
  2610.     addq.w    #1,d7
  2611.     move.w    (a5)+,d0
  2612.     sub.w    (a4)+,d0
  2613.     ext.l    d0
  2614.     lsl.l    #8,d0
  2615.     divs.w    d7,d0
  2616.     move.w    (a5)+,d1
  2617.     sub.w    (a4)+,d1
  2618.     ext.l    d1
  2619.     lsl.l    #8,d1
  2620.     divs.w    d7,d1
  2621.     move.w    (a5)+,d2
  2622.     sub.w    (a4)+,d2
  2623.     ext.l    d2
  2624.     lsl.l    #8,d2
  2625.     divs.w    d7,d2
  2626.     move.w    (a5)+,d3
  2627.     sub.w    (a4)+,d3
  2628.     ext.l    d3
  2629.     lsl.l    #8,d3
  2630.     divs.w    d7,d3
  2631.     bra    .end_calcslope
  2632. .not_edge3:
  2633.  
  2634. ; x_intersect := Edge1Slope ; Edge0length + Edge1XStart
  2635.     move.l    v4EdgeXSlope(a1),d7
  2636.     moveq    #0,d4
  2637.     move.w    v4EdgeDY(a0),d4
  2638.     muls.l    d4,d7
  2639.     swap    d7
  2640.     add.w    v4EdgeXStart(a0),d7        a1; x_intersect
  2641. ; i_intersect := Edge1ISlope ; Edge0length + Edge1IStart
  2642.     move.w    v4EdgeU0Slope(a1),d0
  2643.     move.w    v4EdgeV0Slope(a1),d1
  2644.     move.w    v4EdgeU1Slope(a1),d2
  2645.     move.w    v4EdgeV1Slope(a1),d3
  2646.     muls.w    d4,d0
  2647.     muls.w    d4,d1
  2648.     muls.w    d4,d2
  2649.     muls.w    d4,d3
  2650.     asr.l    #8,d0
  2651.     asr.l    #8,d1
  2652.     asr.l    #8,d2
  2653.     asr.l    #8,d3
  2654.     add.w    v4EdgeU0Start(a0),d0        a1; i_intersect
  2655.     add.w    v4EdgeV0Start(a0),d1        a1
  2656.     add.w    v4EdgeU1Start(a0),d2        a1; i_intersect
  2657.     add.w    v4EdgeV1Start(a0),d3        a1
  2658. ; i_horizontalslope := (x_intersect - I2) / (x_intersect - X2)
  2659.     sub.w    v4EdgeXStart(a2),d7
  2660.     bmi.s    .fuk
  2661.     addq.w    #1,d7
  2662.     bra.s    .end_fuk
  2663. .fuk:    subq.w    #1,d7
  2664. .end_fuk:
  2665.     sub.w    v4EdgeU0Start(a2),d0
  2666.     sub.w    v4EdgeV0Start(a2),d1
  2667.     sub.w    v4EdgeU1Start(a2),d2
  2668.     sub.w    v4EdgeV1Start(a2),d3
  2669.     ext.l    d0
  2670.     ext.l    d1
  2671.     ext.l    d2
  2672.     ext.l    d3
  2673.     lsl.l    #8,d0
  2674.     lsl.l    #8,d1
  2675.     lsl.l    #8,d2
  2676.     lsl.l    #8,d3
  2677.     ext.l    d7
  2678.     beq.s    .slope0
  2679.     divs.w    d7,d0
  2680.     divs.w    d7,d1
  2681.     divs.w    d7,d2
  2682.     divs.w    d7,d3
  2683. .slope0:
  2684. .end_calcslope:
  2685.  
  2686. ; d0.w: Uu (0)
  2687. ; d1.w: Vv (0)
  2688. ; d2.w: Uu (1)
  2689. ; d3.w: Vv (1)
  2690. ; d7.l: dx
  2691.  
  2692.     movem.w    d0-d3,Polygon.uvslopes
  2693.  
  2694. ; Special case for triangles that have a horizontal edge.
  2695.     lea    .edges_tbl,a0
  2696.     tst.w    v4EdgeDY(a0)
  2697.     bne    .make_fragments
  2698.     subq    #8,a3
  2699.     move.w    v4EdgeDY(a2),d7
  2700.     subq.w    #1,d7
  2701.     bmi    .end_paint_triangle
  2702.     move.w    d7,-(sp)
  2703.     moveq    #0,d0
  2704.     move.w    v4EdgeXStart(a0),d0
  2705.     swap    d0
  2706.     moveq    #0,d1
  2707.     move.w    v4EdgeXStart(a2),d1
  2708.     swap    d1
  2709.     move.l    v4EdgeXSlope(a1),d2
  2710.     move.l    v4EdgeXSlope(a2),d3
  2711.     cmp.l    d0,d1
  2712.     bgt.s    .left_right
  2713. .right_left:
  2714.     move.l    d2,-(sp)
  2715.     move.l    d3,-(sp)
  2716.     move.l    d0,-(sp)
  2717.     move.l    d1,-(sp)
  2718.     move.w    v4EdgeU0Start(a2),d2
  2719.     lsl.w    #8,d2
  2720.     move.w    v4EdgeV0Start(a2),d0
  2721.     lsl.w    #8,d0
  2722.     move.w    v4EdgeU1Start(a2),d4
  2723.     lsl.w    #8,d4
  2724.     move.w    v4EdgeV1Start(a2),d1
  2725.     lsl.w    #8,d1
  2726.     move.w    v4EdgeU0Slope(a2),a5
  2727.     move.w    v4EdgeV0Slope(a2),d3
  2728.     move.w    v4EdgeU1Slope(a2),a6
  2729.     move.w    v4EdgeV1Slope(a2),d5
  2730.     bra.s    .start_x_okay
  2731. .left_right:
  2732.     move.l    d3,-(sp)
  2733.     move.l    d2,-(sp)
  2734.     move.l    d1,-(sp)
  2735.     move.l    d0,-(sp)
  2736.     move.w    v4EdgeU0Slope(a1),a5
  2737.     move.w    v4EdgeV0Slope(a1),d3
  2738.     move.w    v4EdgeU1Slope(a1),a6
  2739.     move.w    v4EdgeV1Slope(a1),d5
  2740.     move.w    (a3)+,d2    v4EdgeU0Start(a1),d2
  2741.     lsl.l    #8,d2
  2742.     move.w    (a3)+,d0    v4EdgeV0Start(a1),d3
  2743.     lsl.w    #8,d0
  2744.     move.w    (a3)+,d4    v4EdgeU1Start(a1),d2
  2745.     lsl.w    #8,d4
  2746.     move.w    (a3)+,d1    v4EdgeV1Start(a1),d3
  2747.     lsl.w    #8,d1
  2748. .start_x_okay:
  2749.     movem.l    (sp)+,a1-a4
  2750.     move.w    v4EdgeYStart(a0),-(sp)
  2751.     lea    Polygon.scanlineTable,a0
  2752.     bsr    DRAW_V4FRAGMENT
  2753.      bra    .end_draw_fragments
  2754.  
  2755. .make_fragments:
  2756.     move.l    v4EdgeXSlope(a0),d0
  2757.     move.l    v4EdgeXSlope(a1),d1
  2758.     cmp.l    d0,d1
  2759.     blt    .make_fragments_rl
  2760.  
  2761. ; a0 /\ a1
  2762. ;      \
  2763. .make_fragments_lr:
  2764. ; Create upper fragment..
  2765.     movea.l    a2,a6
  2766.     move.w    v4EdgeDY(a0),d7
  2767.     subq.w    #1,d7
  2768.     move.w    d7,-(sp)
  2769.     move.w    v4EdgeYStart(a0),-(sp)
  2770.     tst.w    d7
  2771.     bmi.s    .lr_skip_upper
  2772.     move.l    a6,-(sp)
  2773.     move.l    d0,a3
  2774.     move.l    d1,a4
  2775.     moveq    #0,d0
  2776.     move.w    v4EdgeXStart(a0),d0
  2777.     swap    d0
  2778.     movea.l    d0,a1
  2779.     movea.l    d0,a2
  2780.     move.w    v4EdgeU0Start(a0),d2
  2781.     lsl.w    #8,d2
  2782.     move.w    v4EdgeV0Start(a0),d0
  2783.     lsl.w    #8,d0
  2784.     move.w    v4EdgeU1Start(a0),d4
  2785.     lsl.w    #8,d4
  2786.     move.w    v4EdgeV1Start(a0),d1
  2787.     lsl.w    #8,d1
  2788.     move.w    v4EdgeU0Slope(a0),a5
  2789.     move.w    v4EdgeV0Slope(a0),d3
  2790.     move.w    v4EdgeU1Slope(a0),a6
  2791.     move.w    v4EdgeV1Slope(a0),d5
  2792.     lea    Polygon.scanlineTable,a0
  2793.     bsr    DRAW_V4FRAGMENT
  2794.     movea.l    (sp)+,a6
  2795. .lr_skip_upper:
  2796.  
  2797. ; Create lower fragment..
  2798.     move.w    v4EdgeDY(a6),d7
  2799.     add.w    d7,2(sp)
  2800.     moveq    #0,d0
  2801.     move.w    v4EdgeXStart(a6),d0
  2802.     swap    d0
  2803.     movea.l    d0,a1
  2804.     movea.l    v4EdgeXSlope(a6),a3
  2805.     move.w    v4EdgeU0Start(a6),d2
  2806.     lsl.w    #8,d2
  2807.     move.w    v4EdgeV0Start(a6),d0
  2808.     lsl.w    #8,d0
  2809.     move.w    v4EdgeU1Start(a6),d4
  2810.     lsl.w    #8,d4
  2811.     move.w    v4EdgeV1Start(a6),d1
  2812.     lsl.w    #8,d1
  2813.     move.w    v4EdgeU0Slope(a6),a5
  2814.     move.w    v4EdgeV0Slope(a6),d3
  2815.     move.w    v4EdgeV1Slope(a6),d5
  2816.     move.w    v4EdgeU1Slope(a6),a6
  2817.     subq.w    #1,d7
  2818.     bmi.s    .lr_skip_lower
  2819.     bsr    DRAW_V4FRAGMENT
  2820. .lr_skip_lower:
  2821.      bra    .end_draw_fragments
  2822.  
  2823. .make_fragments_rl:
  2824. ; Create upper fragment..
  2825.     movea.l    d0,a4
  2826.     movea.l    d1,a3
  2827.     move.w    v4EdgeDY(a0),d7
  2828.     subq.w    #1,d7
  2829.     move.w    d7,-(sp)
  2830.     move.w    v4EdgeYStart(a0),-(sp)
  2831.     tst.w    d7
  2832.     bmi.s    .rl_skip_upper
  2833.     move.l    a2,-(sp)
  2834.     moveq    #0,d6
  2835.     move.w    v4EdgeXStart(a0),d6
  2836.     swap    d6
  2837.     movea.l    d6,a2
  2838.     move.w    v4EdgeU0Start(a0),d2
  2839.     lsl.w    #8,d2
  2840.     move.w    v4EdgeV0Start(a0),d0
  2841.     lsl.w    #8,d0
  2842.     move.w    v4EdgeU1Start(a0),d4
  2843.     lsl.w    #8,d4
  2844.     move.w    v4EdgeV1Start(a0),d1
  2845.     lsl.w    #8,d1
  2846.     move.w    v4EdgeU0Slope(a1),a5
  2847.     move.w    v4EdgeV0Slope(a1),d3
  2848.     move.w    v4EdgeU1Slope(a1),a6
  2849.     move.w    v4EdgeV1Slope(a1),d5
  2850.     movea.l    a2,a1
  2851.     lea    Polygon.scanlineTable,a0
  2852.     bsr    DRAW_V4FRAGMENT
  2853.     movea.l    (sp)+,a2
  2854. .rl_skip_upper:
  2855.  
  2856. ; Create lower fragment..
  2857.     move.w    v4EdgeDY(a2),d7
  2858.     add.w    d7,2(sp)
  2859.     moveq    #0,d6
  2860.     move.w    v4EdgeXStart(a2),d6
  2861.     swap    d6
  2862.     movea.l    v4EdgeXSlope(a2),a4
  2863.     movea.l    d6,a2
  2864.     subq.w    #1,d7
  2865.     bmi.s    .rl_skip_lower
  2866.     bsr    DRAW_V4FRAGMENT
  2867. .rl_skip_lower:
  2868. .end_draw_fragments:
  2869.  
  2870.     movea.l    Primitive.screenadr,a0
  2871.     move.w    (sp)+,d0                ; Get Y start of triangle.
  2872.     mulu.w    Viewport.settingsTable+Viewport.XSCREEN,d0
  2873.     add.l    d0,d0
  2874.     adda.l    d0,a0
  2875.     lea    Polygon.scanlineTable,a1
  2876.     move.w    (sp)+,d7
  2877.     bmi.s    .end_paint_triangle
  2878.     movea.l    Polygon.v4routadr,a3
  2879.     movem.w    Polygon.uvslopes,d0-d3
  2880.     ror.l    #8,d1
  2881.     move.l    d1,d4
  2882.     move.w    d0,d4
  2883.     movea.l    d4,a2
  2884.     ror.l    #8,d3
  2885.     move.l    d3,d4
  2886.     move.w    d2,d4
  2887.     movea.l    d4,a5
  2888.     move.w    d3,d6
  2889.     swap    d6
  2890.     move.w    d1,d6
  2891.     jmp    (a3)
  2892.  
  2893. .end_paint_triangle:
  2894.     rts
  2895.  
  2896.     BSS
  2897.  
  2898. .edges_tbl:
  2899.     DS.B    v4EdgeSize*3
  2900.  
  2901.     TEXT
  2902.     
  2903. ; Draws a mixed-texture triangle to the screen.
  2904. ; Horizontal clipping is implemented.
  2905. ; INPUT: a0: start screenline
  2906. ;        a1: start entry in scanline table
  2907. ;        d7.w: number of scanlines to paint - 1
  2908. PAINT_UNCLIPALPHASCANS:
  2909.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d0
  2910.     add.w    d0,d0
  2911.     move.w    d0,-(sp)
  2912.     movem.l    Polygon.curtexture,a3/a4
  2913.     movea.l    Polygon.alphatableadr,a6
  2914.  
  2915. .paint_yloop:
  2916.     swap    d7
  2917.     move.l    a0,-(sp)
  2918.     movem.w    (a1)+,d0/d1
  2919.     lea    (a0,d0.l*2),a0
  2920.     sub.w    d0,d1
  2921.     moveq    #0,d2
  2922.     move.w    (a1)+,d0
  2923.     move.w    (a1)+,d2
  2924.     ror.l    #8,d2
  2925.     move.l    d2,d4
  2926.     move.w    d0,d4
  2927.     move.w    (a1)+,d0
  2928.     move.w    (a1)+,d3
  2929.     ror.l    #8,d3
  2930.     move.l    d3,d5
  2931.     move.w    d0,d5
  2932.     subq.w    #1,d1
  2933.     bmi.s    .end_paint_yloop
  2934.  
  2935. .paint_xloop:
  2936.     move.w    d4,d0
  2937.     add.l    a2,d4
  2938.     move.b    d2,d0
  2939.     addx.b    d6,d2
  2940.     move.w    (a3,d0.l),d7
  2941.     move.w    d5,d0
  2942.     add.l    a5,d5
  2943.     move.b    d3,d0
  2944.     swap    d6
  2945.     addx.b    d6,d3
  2946.     swap    d6
  2947.     move.b    (a4,d0.l),d7
  2948.     move.w    (a6,d7.w*2),(a0)+
  2949.     dbra    d1,.paint_xloop
  2950.  
  2951. .end_paint_yloop:
  2952.     movea.l    (sp)+,a0
  2953.     adda.w    (sp),a0
  2954.     swap    d7
  2955.     dbra    d7,.paint_yloop
  2956.     addq    #2,sp
  2957.     rts
  2958.  
  2959. ; Draws a bump-textured triangle to the screen.
  2960. ; Horizontal clipping is implemented.
  2961. ; INPUT: a0: start screenline
  2962. ;        a1: start entry in scanline table
  2963. ;        d7.w: number of scanlines to paint - 1
  2964. PAINT_UNCLIPBUMPSCANS:
  2965.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d0
  2966.     add.w    d0,d0
  2967.     move.w    d0,-(sp)
  2968.     movem.l    Polygon.curtexture,a3/a4
  2969.  
  2970. .paint_yloop:
  2971.     swap    d7
  2972.     move.l    a0,-(sp)
  2973.     movem.w    (a1)+,d0/d1
  2974.     lea    (a0,d0.l*2),a0
  2975.     sub.w    d0,d1
  2976.     moveq    #0,d2
  2977.     move.w    (a1)+,d0
  2978.     move.w    (a1)+,d2
  2979.     ror.l    #8,d2
  2980.     move.l    d2,d4
  2981.     move.w    d0,d4
  2982.     move.w    (a1)+,d0
  2983.     move.w    (a1)+,d3
  2984.     ror.l    #8,d3
  2985.     move.l    d3,d5
  2986.     move.w    d0,d5
  2987.     subq.w    #1,d1
  2988.     bmi.s    .end_paint_yloop
  2989.  
  2990. .paint_xloop:
  2991.     move.w    d4,d0
  2992.     add.l    a2,d4
  2993.     move.b    d2,d0
  2994.     addx.b    d6,d2
  2995.     move.w    (a4,d0.l*2),d7
  2996.     move.w    d5,d0
  2997.     add.l    a5,d5
  2998.     move.b    d3,d0
  2999.     swap    d6
  3000.     addx.b    d6,d3
  3001.     swap    d6
  3002.     add.w    d7,d0
  3003.     move.w    (a3,d0.l*2),(a0)+
  3004.     dbra    d1,.paint_xloop
  3005.  
  3006. .end_paint_yloop:
  3007.     movea.l    (sp)+,a0
  3008.     adda.w    (sp),a0
  3009.     swap    d7
  3010.     dbra    d7,.paint_yloop
  3011.     addq    #2,sp
  3012.     rts
  3013.  
  3014.     ENDC
  3015.  
  3016. ;======= Sprite
  3017.  
  3018. Sprite.routTable:
  3019.     DC.L    Sprite.paintMoved
  3020.     DC.L    Sprite.paintOrred
  3021.     DC.L    Sprite.paintAdded
  3022.     DC.L    Sprite.paintceilAdded
  3023.  
  3024. ; INPUT:
  3025. ; a1: sprite structure
  3026. ; a2: vertex table
  3027. Sprite.paint:
  3028.     lea    Polygon.textureTable,a0
  3029.     move.w    Primitive.SPRITETYPE(a1),d0
  3030.     andi.w    #Primitive.TEXTUREMASK,d0
  3031.     movea.l    (a0,d0.w*4),a0
  3032. ; a0: address of sprite-data.
  3033.     move.w    Sprite.VERTEX(a1),d0
  3034.     mulu.w    #Vertex.SIZE,d0
  3035.     movem.w    4(a2,d0.l),d0-d2
  3036. ; d0.l: X
  3037. ; d1.l: Y
  3038. ; d2.l: Z
  3039.     movea.l    a0,a1
  3040.     bra.w    Sprite.clipAndPaint
  3041.  
  3042. Sprite.paintReceived:
  3043.     lea    Polygon.textureTable,a0
  3044.     receiveWordFromDsp    d0
  3045.     andi.w    #Primitive.TEXTUREMASK,d0
  3046.     movea.l    (a0,d0.w*4),a0
  3047. ; a0: address of sprite-data.
  3048.     receiveWordFromDsp    d1
  3049.     receiveWordFromDsp    d0
  3050.     receiveWordFromDsp    d2
  3051.     ext.l    d0
  3052.     ext.l    d1
  3053.     ext.l    d2
  3054. ; d0.l: X
  3055. ; d1.l: Y
  3056. ; d2.l: Z
  3057.     movea.l    a0,a1
  3058.     bra.w    Sprite.clipAndPaint
  3059.  
  3060. ; Paints a highcolor rle sprite to the screen.
  3061. ; This handles horizontal and vertical clipping as well.
  3062. ; INPUT:
  3063. ; d0.w: x position (mid)
  3064. ; d1.w: y position (mid)
  3065. ; a1: sprite
  3066. Sprite.clipAndPaint:
  3067.     movea.l    Primitive.screenadr,a0
  3068.     movea.w    Viewport.settingsTable+Viewport.XSCREEN,a6
  3069.     adda.l    a6,a6
  3070.     move.w    (a1)+,d6            ; width of sprite
  3071.     move.w    (a1)+,d7            ; height of sprite
  3072.     move.w    d6,d4
  3073.     lsr.w    #1,d4
  3074.     sub.w    d4,d0
  3075.     move.w    d7,d4
  3076.     lsr.w    #1,d4
  3077.     sub.w    d4,d1
  3078.     movem.w    Viewport.settingsTable+Viewport.XSTART,d4/d5/a4/a5
  3079.     movea.l    a1,a3
  3080.     lea    (a1,d7.w*2),a1
  3081.  
  3082. ; d0.w: left x coordinate of sprite
  3083. ; d1.w: top y coordinate of sprite
  3084. ; d6.w: width of sprite
  3085. ; d7.w: height of sprite
  3086.  
  3087. .clip_bottom:
  3088.     cmp.w    a5,d1                ; YEnd
  3089.     bge    .end                ; Beneath bottom?
  3090.     move.w    d1,d2
  3091.     add.w    d7,d2                ; d2 := bottom line of sprite
  3092.     cmp.w    a5,d2
  3093.     blt.s    .end_clip_bottom
  3094.     move.w    d2,d3
  3095.     sub.w    a5,d3
  3096.     sub.w    d3,d7
  3097. .end_clip_bottom:
  3098.  
  3099. .clip_top:
  3100.     cmp.w    a4,d1                ; YStart
  3101.     bge.s    .end_clip_top    
  3102.     cmp.w    a4,d2
  3103.     ble    .end                ; Above top?
  3104.     move.w    d2,d7
  3105.     sub.w    a4,d7
  3106.     sub.w    a4,d1
  3107.     neg.w    d1
  3108.     lea    (a3,d1.w*2),a3
  3109.     move.w    a4,d1
  3110. .end_clip_top:
  3111.  
  3112. ; d1.w: top y coordinate of sprite
  3113. ; d7.w: height of sprite
  3114.  
  3115. .clip_left:
  3116.     moveq    #0,d3
  3117.     move.w    d0,d2
  3118.     add.w    d6,d2                ; d2 := left x of sprite
  3119.     cmp.w    d4,d0                ; XStart
  3120.     bgt.s    .end_clip_left
  3121.     cmp.w    d4,d2                ; XStart
  3122.     ble    .end                ; Left of viewport?
  3123.     move.w    d0,d3
  3124.     sub.w    d4,d3
  3125.     neg.w    d3
  3126.     move.w    d4,d0
  3127. .end_clip_left:
  3128.  
  3129. .clip_right:
  3130.     cmp.w    d5,d0                ; XEnd
  3131.     bge    .end                ; Right of viewport?
  3132.     cmp.w    d5,d2
  3133.     ble.s    .end_clip_right
  3134.     sub.w    d5,d2
  3135.     sub.w    d2,d6
  3136. .end_clip_right:
  3137.  
  3138.     movea.l    Sprite.rout,a5
  3139.     jsr    (a5)
  3140.  
  3141. .end:    rts
  3142.  
  3143. ; d0.w= left x coordinate of sprite
  3144. ; d3.w= #left pixels to skip
  3145. ; d6.w= #pixels in spriteline
  3146. Sprite.paintMoved:
  3147.     move.w    d3,d2
  3148.     move.l    a6,d5
  3149.     mulu.w    d1,d5
  3150.     adda.l    d5,a0
  3151.     lea    (a0,d0.w*2),a0
  3152.     subq.w    #1,d7
  3153.     move.w    #$7fff,d0
  3154.     clr.l    d1
  3155.     clr.l    d3
  3156.  
  3157. .yloop:    move.w    (a3)+,d1
  3158.     lea    (a1,d1.l),a4
  3159.     movea.l    a0,a2
  3160.     moveq    #0,d5                ; linesize := 0
  3161.  
  3162. .skip_blocks:
  3163.     tst.w    d2
  3164.     beq.s    .end_handle_leftover
  3165.  
  3166. .skip_block_loop:
  3167.     move.w    (a4)+,d4
  3168.     move.w    d4,d3
  3169.     and.w    d0,d3
  3170.     add.w    d3,d5                ; linesize := linesize + blocksize
  3171.     cmp.w    d5,d2
  3172.     ble.s    .end_skip_blocks
  3173.     cmp.w    d0,d4
  3174.     blo.s    .skip_unmasked
  3175. .skip_masked:
  3176.     lea    (a4,d3.l*2),a4            ; Skip <d3> pixels.
  3177. .skip_unmasked:
  3178.     bra.s    .skip_block_loop
  3179. .end_skip_blocks:
  3180.  
  3181. .handle_leftover:
  3182.     move.w    d5,d1
  3183.     sub.w    d2,d1
  3184.     cmp.w    d0,d4
  3185.     blo.s    .leftover_unmasked
  3186. .leftover_masked:
  3187.     sub.w    d1,d3
  3188.     lea    (a4,d3.l*2),a4            ; Skip <d3> pixels.
  3189.     ble.s    .end_handle_leftover
  3190.     subq.w    #1,d1
  3191. .leftover_loop:
  3192.     move.w    (a4)+,(a2)+
  3193.     dbf    d1,.leftover_loop
  3194.     bra.s    .end_handle_leftover
  3195. .leftover_unmasked:
  3196.     lea    (a2,d1.l*2),a2            ; Skip <d1> pixels.
  3197. .end_handle_leftover:
  3198.  
  3199. .block_loop:
  3200.     move.w    (a4)+,d4
  3201.     move.w    d4,d3
  3202.     and.w    d0,d3
  3203.     add.w    d3,d5                ; linesize := linesize + blocksize
  3204.     cmp.w    d5,d6
  3205.     ble.s    .end_block_loop
  3206.     cmp.w    d0,d4
  3207.     blo.s    .unmasked
  3208. .masked:
  3209.     subq.w    #1,d3
  3210. .masked_loop:
  3211.     move.w    (a4)+,(a2)+
  3212.     dbf    d3,.masked_loop
  3213.     bra.s    .next_block
  3214. .unmasked:
  3215.     lea    (a2,d3.l*2),a2            ; Skip <d3> pixels.
  3216. .next_block:
  3217.     bra.s    .block_loop
  3218. .end_block_loop:
  3219.  
  3220. ; Not left-over, but "right-over", get it? RIght-Over?!? Ghweheheheh.
  3221. .handle_rightover:
  3222.     sub.w    d6,d5
  3223.     beq.s    .rightover_ok
  3224.     sub.w    d5,d3
  3225.     beq.s    .end_handle_rightover
  3226. .rightover_ok:
  3227.     cmp.w    d0,d4
  3228.     blo.s    .rightover_unmasked
  3229. .rightover_masked:
  3230.     subq.w    #1,d3
  3231. .rightover_masked_loop:
  3232.     move.w    (a4)+,(a2)+
  3233.     dbf    d3,.rightover_masked_loop
  3234. .rightover_unmasked:
  3235. .end_handle_rightover:
  3236.  
  3237. .next_line:
  3238.     adda.l    a6,a0
  3239.     dbra    d7,.yloop
  3240.  
  3241. .end:    rts
  3242.  
  3243. ; d0.w: left x coordinate of sprite
  3244. ; d3.w: number of left pixels to skip
  3245. ; d6.w: number of pixels in spriteline
  3246. Sprite.paintAdded:
  3247.     move.w    d3,d2
  3248.     move.l    a6,d5
  3249.     mulu.w    d1,d5
  3250.     adda.l    d5,a0
  3251.     lea    (a0,d0.w*2),a0
  3252.     subq.w    #1,d7
  3253.     move.w    #$7fff,d0
  3254.     move.w    #%0111101111101111,d4
  3255.  
  3256. .yloop:    moveq    #0,d1
  3257.     move.w    (a3)+,d1
  3258.     lea    (a1,d1.w),a4
  3259.     movea.l    a0,a2
  3260.     moveq    #0,d5                ; linesize := 0
  3261.  
  3262. .skip_blocks:
  3263.     tst.w    d2
  3264.     beq.s    .end_handle_leftover
  3265.  
  3266. .skip_block_loop:
  3267.     move.w    (a4)+,a5
  3268.     move.w    a5,d3
  3269.     and.w    d0,d3
  3270.     add.w    d3,d5                ; linesize := linesize + blocksize
  3271.     cmp.w    d5,d2
  3272.     ble.s    .end_skip_blocks
  3273.     cmp.w    d0,a5
  3274.     blo.s    .skip_unmasked
  3275. .skip_masked:
  3276.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3277. .skip_unmasked:
  3278.     bra.s    .skip_block_loop
  3279. .end_skip_blocks:
  3280.  
  3281. .handle_leftover:
  3282.     move.w    d5,d1
  3283.     sub.w    d2,d1
  3284.     cmp.w    d0,a5
  3285.     blo.s    .leftover_unmasked
  3286. .leftover_masked:
  3287.     sub.w    d1,d3
  3288.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3289.     subq.w    #1,d1
  3290.     bmi.s    .end_handle_leftover
  3291. .leftover_loop:
  3292.     move.w    (a2),d3
  3293.     lsr.w    #1,d3
  3294.     and.w    d4,d3
  3295.     add.w    (a4)+,d3
  3296.     move.w    d3,(a2)+
  3297.     dbra    d1,.leftover_loop
  3298.     bra.s    .end_handle_leftover
  3299. .leftover_unmasked:
  3300.     lea    (a2,d1.w*2),a2            ; Skip <d1> pixels.
  3301. .end_handle_leftover:
  3302.  
  3303. .block_loop:
  3304.     move.w    (a4)+,a5
  3305.     move.w    a5,d3
  3306.     and.w    d0,d3
  3307.     add.w    d3,d5                ; linesize := linesize + blocksize
  3308.     cmp.w    d5,d6
  3309.     ble.s    .end_block_loop
  3310.     cmp.w    d0,a5
  3311.     blo.s    .unmasked
  3312. .masked:
  3313.     subq.w    #1,d3
  3314. .masked_loop:
  3315.     move.w    (a2),d1
  3316.     lsr.w    #1,d1
  3317.     and.w    d4,d1
  3318.     add.w    (a4)+,d1
  3319.     move.w    d1,(a2)+
  3320.     dbra    d3,.masked_loop
  3321.     bra.s    .next_block
  3322. .unmasked:
  3323.     lea    (a2,d3.w*2),a2            ; Skip <d3> pixels.
  3324. .next_block:
  3325.     bra.s    .block_loop
  3326. .end_block_loop:
  3327.  
  3328. ; Not left-over, but "right-over", get it? RIght-Over?!? Ghweheheheh.
  3329. .handle_rightover:
  3330.     sub.w    d6,d5
  3331.     beq.s    .rightover_ok
  3332.     sub.w    d5,d3
  3333.     beq.s    .end_handle_rightover
  3334. .rightover_ok:
  3335.     cmp.w    d0,a5
  3336.     blo.s    .rightover_unmasked
  3337. .rightover_masked:
  3338.     subq.w    #1,d3
  3339. .rightover_masked_loop:
  3340.     move.w    (a2),d1
  3341.     lsr.w    #1,d1
  3342.     and.w    d4,d1
  3343.     add.w    (a4)+,d1
  3344.     move.w    d1,(a2)+
  3345.     dbra    d3,.rightover_masked_loop
  3346. .rightover_unmasked:
  3347. .end_handle_rightover:
  3348.  
  3349. .next_line:
  3350.     adda.l    a6,a0
  3351.     dbra    d7,.yloop
  3352.  
  3353. .end:    rts
  3354.  
  3355. ; d0.w: left x coordinate of sprite
  3356. ; d3.w: number of left pixels to skip
  3357. ; d6.w: number of pixels in spriteline
  3358. Sprite.paintOrred:
  3359.     move.w    d3,d2
  3360.     move.l    a6,d5
  3361.     mulu.w    d1,d5
  3362.     adda.l    d5,a0
  3363.     lea    (a0,d0.w*2),a0
  3364.     subq.w    #1,d7
  3365.     move.w    #$7fff,d0
  3366.  
  3367. .yloop:    moveq    #0,d1
  3368.     move.w    (a3)+,d1
  3369.     lea    (a1,d1.w),a4
  3370.     movea.l    a0,a2
  3371.     moveq    #0,d5                ; linesize := 0
  3372.  
  3373. .skip_blocks:
  3374.     tst.w    d2
  3375.     beq.s    .end_handle_leftover
  3376.  
  3377. .skip_block_loop:
  3378.     move.w    (a4)+,a5
  3379.     move.w    a5,d3
  3380.     and.w    d0,d3
  3381.     add.w    d3,d5                ; linesize := linesize + blocksize
  3382.     cmp.w    d5,d2
  3383.     ble.s    .end_skip_blocks
  3384.     cmp.w    d0,a5
  3385.     blo.s    .skip_unmasked
  3386. .skip_masked:
  3387.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3388. .skip_unmasked:
  3389.     bra.s    .skip_block_loop
  3390. .end_skip_blocks:
  3391.  
  3392. .handle_leftover:
  3393.     move.w    d5,d1
  3394.     sub.w    d2,d1
  3395.     cmp.w    d0,a5
  3396.     blo.s    .leftover_unmasked
  3397. .leftover_masked:
  3398.     sub.w    d1,d3
  3399.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3400.     subq.w    #1,d1
  3401.     bmi.s    .end_handle_leftover
  3402. .leftover_loop:
  3403.     move.w    (a4)+,d3
  3404.     or.w    d3,(a2)+
  3405.     dbf    d1,.leftover_loop
  3406.     bra.s    .end_handle_leftover
  3407. .leftover_unmasked:
  3408.     lea    (a2,d1.w*2),a2            ; Skip <d1> pixels.
  3409. .end_handle_leftover:
  3410.  
  3411. .block_loop:
  3412.     move.w    (a4)+,a5
  3413.     move.w    a5,d3
  3414.     and.w    d0,d3
  3415.     add.w    d3,d5                ; linesize := linesize + blocksize
  3416.     cmp.w    d5,d6
  3417.     ble.s    .end_block_loop
  3418.     cmp.w    d0,a5
  3419.     blo.s    .unmasked
  3420. .masked:
  3421.     subq.w    #1,d3
  3422. .masked_loop:
  3423.     move.w    (a4)+,d1
  3424.     or.w    d1,(a2)+
  3425.     dbf    d3,.masked_loop
  3426.     bra.s    .next_block
  3427. .unmasked:
  3428.     lea    (a2,d3.w*2),a2            ; Skip <d3> pixels.
  3429. .next_block:
  3430.     bra.s    .block_loop
  3431. .end_block_loop:
  3432.  
  3433. ; Not left-over, but "right-over", get it? RIght-Over?!? Ghweheheheh.
  3434. .handle_rightover:
  3435.     sub.w    d6,d5
  3436.     beq.s    .rightover_ok
  3437.     sub.w    d5,d3
  3438.     beq.s    .end_handle_rightover
  3439. .rightover_ok:
  3440.     cmp.w    d0,a5
  3441.     blo.s    .rightover_unmasked
  3442. .rightover_masked:
  3443.     subq.w    #1,d3
  3444. .rightover_masked_loop:
  3445.     move.w    (a4)+,d1
  3446.     or.w    d1,(a2)+
  3447.     dbf    d3,.rightover_masked_loop
  3448. .rightover_unmasked:
  3449. .end_handle_rightover:
  3450.  
  3451. .next_line:
  3452.     adda.l    a6,a0
  3453.     dbra    d7,.yloop
  3454.  
  3455. .end:    rts
  3456.  
  3457. ; d0.w: left x coordinate of sprite
  3458. ; d3.w: number of left pixels to skip
  3459. ; d6.w: number of pixels in spriteline
  3460. Sprite.paintceilAdded:
  3461.     clr.l    d2
  3462.     move.w    d3,d2
  3463.     move.l    a6,d5
  3464.     mulu.w    d1,d5
  3465.     adda.l    d5,a0
  3466.     lea    (a0,d0.w*2),a0
  3467.     subq.w    #1,d7
  3468.     move.w    #$7fff,d0
  3469.  
  3470. .yloop:    move.w    d7,-(sp)
  3471.     move.w    (a3)+,d1
  3472.     lea    (a1,d1.w),a4
  3473.     movea.l    a0,a2
  3474.     clr.l    d5                ; linesize := 0
  3475.     movem.l    a1/a3,-(sp)
  3476.     move.w    d2,-(sp)
  3477.     lea    Primitive.msbMixTable,a3
  3478.     lea    Primitive.lsbMixTable,a1
  3479.  
  3480. .skip_blocks:
  3481.     tst.w    d2
  3482.     beq.s    .end_handle_leftover
  3483.  
  3484. .skip_block_loop:
  3485.     move.w    (a4)+,a5
  3486.     move.w    a5,d3
  3487.     and.w    d0,d3
  3488.     add.w    d3,d5                ; linesize := linesize + blocksize
  3489.     cmp.w    d5,d2
  3490.     ble.s    .end_skip_blocks
  3491.     cmp.w    d0,a5
  3492.     blo.s    .skip_unmasked
  3493. .skip_masked:
  3494.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3495. .skip_unmasked:
  3496.     bra.s    .skip_block_loop
  3497. .end_skip_blocks:
  3498.  
  3499. .handle_leftover:
  3500.     move.w    d5,d1
  3501.     sub.w    d2,d1
  3502.     cmp.w    d0,a5
  3503.     blo.s    .leftover_unmasked
  3504. .leftover_masked:
  3505.     sub.w    d1,d3
  3506.     lea    (a4,d3.w*2),a4            ; Skip <d3> pixels.
  3507.     subq.w    #1,d1
  3508.     bmi.s    .end_handle_leftover
  3509. .leftover_loop:
  3510.  
  3511.     IFNE    1
  3512. ; rgb
  3513.     move.w    (a4)+,d2
  3514.     move.l    d2,d7
  3515.     move.w    (a2),d3
  3516.     move.b    (a2),d2                ; d2.w=src_msb<<8+dest_msb
  3517.     move.b    (a3,d2.l),(a2)+            ; Store res_msb.
  3518.     lsl.w    #8,d7
  3519.     move.b    d3,d7                ; d7.w=src_lsb<<8+dest_lsb
  3520.     move.b    (a1,d7.l),(a2)+
  3521.  
  3522.     ELSE
  3523.  
  3524.     move.w    (a2),d3
  3525.     add.w    (a4)+,d3
  3526.     scs.b    d4
  3527.     ext.w    d4
  3528.     or.w    d4,d3
  3529.     move.w    d3,(a2)+
  3530.  
  3531.     ENDC
  3532.  
  3533.     dbf    d1,.leftover_loop
  3534.     bra.s    .end_handle_leftover
  3535. .leftover_unmasked:
  3536.     lea    (a2,d1.w*2),a2            ; Skip <d1> pixels.
  3537. .end_handle_leftover:
  3538.  
  3539. .block_loop:
  3540.     move.w    (a4)+,a5
  3541.     move.w    a5,d3
  3542.     and.w    d0,d3
  3543.     add.w    d3,d5                ; linesize := linesize + blocksize
  3544.     cmp.w    d5,d6
  3545.     ble.s    .end_block_loop
  3546.     cmp.w    d0,a5
  3547.     blo.s    .unmasked
  3548. .masked:
  3549.     subq.w    #1,d3
  3550. .masked_loop:
  3551. ; in use: d0,d3,d5,d6,d7,a0,a1,a2,a4,a6
  3552.  
  3553.     IFNE    0
  3554.  
  3555. ; linear
  3556.     move.w    (a2),d1
  3557.     add.w    (a4)+,d1
  3558.     scs.b    d4
  3559.     ext.w    d4
  3560.     or.w    d4,d1
  3561.     move.w    d1,(a2)+
  3562.  
  3563.     ELSE
  3564.  
  3565. ; rgb
  3566.     move.w    (a4)+,d2
  3567.     move.l    d2,d7
  3568.     move.w    (a2),d1
  3569.     move.b    (a2),d2                ; d2.w=src_msb<<8+dest_msb
  3570.     move.b    (a3,d2.l),(a2)+            ; Store res_msb.
  3571.     lsl.w    #8,d7
  3572.     move.b    d1,d7                ; d7.w=src_lsb<<8+dest_lsb
  3573.     move.b    (a1,d7.l),(a2)+
  3574.  
  3575.     ENDC
  3576.     dbf    d3,.masked_loop
  3577.     bra.s    .next_block
  3578. .unmasked:
  3579.     lea    (a2,d3.w*2),a2            ; Skip <d3> pixels.
  3580. .next_block:
  3581.     bra.s    .block_loop
  3582. .end_block_loop:
  3583.  
  3584. ; Not left-over, but "right-over", get it? RIght-Over?!? Ghweheheheh.
  3585. .handle_rightover:
  3586.     sub.w    d6,d5
  3587.     beq.s    .rightover_ok
  3588.     sub.w    d5,d3
  3589.     beq.s    .end_handle_rightover
  3590. .rightover_ok:
  3591.     cmp.w    d0,a5
  3592.     blo.s    .rightover_unmasked
  3593. .rightover_masked:
  3594.     subq.w    #1,d3
  3595. .rightover_masked_loop:
  3596.  
  3597.     IFNE    1
  3598.  
  3599. ; rgb ceiladd!
  3600.     move.w    (a4)+,d2
  3601.     move.l    d2,d7
  3602.     move.w    (a2),d1
  3603.     move.b    (a2),d2                ; d2.w=src_msb<<8+dest_msb
  3604.     move.b    (a3,d2.l),(a2)+            ; Store res_msb.
  3605.     lsl.w    #8,d7
  3606.     move.b    d1,d7                ; d7.w=src_lsb<<8+dest_lsb
  3607.     move.b    (a1,d7.l),(a2)+
  3608.  
  3609.     ELSE
  3610.  
  3611. ; linear ceiladd!
  3612.     move.w    (a2),d1
  3613.     add.w    (a4)+,d1
  3614.     scs.b    d4
  3615.     ext.w    d4
  3616.     or.w    d4,d1
  3617.     move.w    d1,(a2)+
  3618.  
  3619.     ENDC
  3620.  
  3621.     dbf    d3,.rightover_masked_loop
  3622. .rightover_unmasked:
  3623. .end_handle_rightover:
  3624.  
  3625. .next_line:
  3626.     move.w    (sp)+,d2
  3627.     movem.l    (sp)+,a1/a3
  3628.     adda.l    a6,a0
  3629.     move.w    (sp)+,d7
  3630.     dbra    d7,.yloop
  3631.  
  3632. .end:    rts
  3633.  
  3634. ; TODO: implement this!
  3635.  
  3636.     IFNE    0
  3637.     move.w    #%0000000000011111,d7
  3638.     move.w    #%0000011111100000,d6
  3639.     move.w    #%1111100000000000,d5
  3640.  
  3641. ; Looks like almost 80 cycles :(
  3642. ; Maybe try table?
  3643.     move.w    (a1)+,d0
  3644.     move.w    (a0),d1
  3645.     move.w    d0,d2
  3646.     move.w    d1,d3
  3647.     and.w    d7,d2
  3648.     and.w    d7,d3
  3649.     add.w    d2,d3
  3650.     cmp.w    d7,d3
  3651.     ble.s    .b_ok
  3652.     move.w    d7,d3
  3653. .b_ok:    move.w    d0,d2
  3654.     move.w    d1,d4
  3655.     and.w    d6,d2
  3656.     and.w    d6,d4
  3657.     sub.w    d2,d0
  3658.     sub.w    d4,d1
  3659.     add.w    d2,d4
  3660.     cmp.w    d6,d4
  3661.     ble.s    .g_ok
  3662.     move.w    d6,d4
  3663. .g_ok:    or.w    d4,d3
  3664.     add.w    d0,d1
  3665.     bcc.s    .r_ok
  3666.     move.w    d5,d1
  3667. .r_ok:    or.w    d1,d3
  3668.     move.w    d3,(a0)+
  3669.     ENDC
  3670.  
  3671. Primitive.initMsbMixTable:
  3672.     move.b    #%00000111,d6
  3673.     move.b    #%11111000,d5
  3674.     lea    Primitive.msbMixTable,a0
  3675.     clr.w    d7
  3676.  
  3677. .loop:    move.w    d7,d0
  3678.     lsr.w    #8,d0
  3679.     move.b    d7,d1
  3680.     move.b    d0,d2
  3681.     move.b    d1,d3
  3682.     and.b    d6,d0
  3683.     and.b    d6,d1
  3684.     sub.b    d0,d2
  3685.     sub.b    d1,d3
  3686.     add.b    d0,d1
  3687.     cmp.b    d6,d1
  3688.     blo.s    .g_ok
  3689.     move.b    d6,d1
  3690. .g_ok:    add.b    d2,d3
  3691.     bcc.s    .r_ok
  3692.     move.b    d5,d3
  3693. .r_ok:    or.b    d3,d1
  3694.     move.b    d1,(a0)+
  3695.     addq.w    #1,d7
  3696.     bne.s    .loop
  3697.     rts
  3698.  
  3699. Primitive.initLsbMixTable:
  3700.     move.b    #%00011111,d6
  3701.     move.b    #%11100000,d5
  3702.     lea    Primitive.lsbMixTable,a0
  3703.     clr.w    d7
  3704.  
  3705. .loop:    move.w    d7,d0
  3706.     lsr.w    #8,d0
  3707.     move.b    d7,d1
  3708.     move.b    d0,d2
  3709.     move.b    d1,d3
  3710.     and.b    d6,d0
  3711.     and.b    d6,d1
  3712.     sub.b    d0,d2
  3713.     sub.b    d1,d3
  3714.     add.b    d0,d1
  3715.     cmp.b    d6,d1
  3716.     blo.s    .b_ok
  3717.     move.b    d6,d1
  3718. .b_ok:    add.b    d2,d3
  3719.     bcc.s    .g_ok
  3720.     move.b    d5,d3
  3721. .g_ok:    or.b    d3,d1
  3722.     move.b    d1,(a0)+
  3723.     addq.w    #1,d7
  3724.     bne.s    .loop
  3725.     rts
  3726.  
  3727.     IFNE    0
  3728. ; r,g,b hicolor word saturated add code.
  3729.     lea    Primitive.msbMixTable,a2
  3730.     lea    Primitive.lsbMixTable,a3
  3731.     clr.l    d2
  3732.     clr.b    d3
  3733.  
  3734.     move.w    (a1)+,d2
  3735.     move.w    d2,d0
  3736.     move.w    (a0),d1
  3737.     move.b    (a0),d2                ; d2.w=src_msb<<8+dest_msb
  3738.     move.b    (a2,d2.l),d4            ; d4.b=res_msb
  3739.     move.b    d1,d2
  3740.     lsl.w    #8,d2
  3741.     move.b    d0,d2                ; d2.w=src_lsb<<8+dest_lsb
  3742.     move.b    d4,(a0)+
  3743.     move.b    (a3,d2.l),(a0)+
  3744.  
  3745. ; 6+2+6+4+8+2+4+2+6+10=50 cycles (well..)
  3746.     ENDC
  3747.  
  3748. ;======= Line
  3749.  
  3750. Line.paintReceived:
  3751.     receiveWordFromDsp    d4
  3752.     receiveWordFromDsp    d1
  3753.     receiveWordFromDsp    d0
  3754.     receiveWordFromDsp    d3
  3755.     receiveWordFromDsp    d2
  3756.     ext.l    d0
  3757.     ext.l    d1
  3758.     ext.l    d2
  3759.     ext.l    d3
  3760.     move.w    d4,d5
  3761.     andi.w    #Primitive.TEXTUREMASK,d5
  3762.     move.w    d5,Line.colorNum
  3763.     andi.w    #Primitive.SHADEMASK,d4
  3764.     cmpi.w    #Line.FLATSHADED,d4
  3765.     beq.s    Line.paintFlatshaded
  3766.     cmpi.w    #Line.GOURAUDSHADED,d4
  3767.     beq    Line.paintGouraudshaded
  3768.     cmpi.w    #Line.PHONGSHADED,d4
  3769.     beq    Line.paintPhongshaded
  3770.     rts
  3771.  
  3772. ; INPUT:
  3773. ; \1: flagnum
  3774. ; \2: flagreg
  3775. ; \3: edgereg
  3776. ; \4: xreg
  3777. ; \5: yreg
  3778. Line_clipEdgeX:    MACRO
  3779.     btst    \1,\2
  3780.     beq.s    \@end_clip
  3781.     move.l    d2,d4
  3782.     sub.l    d0,d4
  3783.     move.l    d3,d7
  3784.     sub.l    d1,d7
  3785.     swap    d7
  3786.     clr.w    d7
  3787.     tst.w    d4
  3788.     beq.s    \@skip_div
  3789.     divs.l    d4,d7
  3790. \@skip_div:
  3791.     move.l    d0,d4
  3792.     sub.l    \3,d4
  3793.     muls.l    d4,d7
  3794.     swap    d7
  3795.     move.w    d1,d4
  3796.     sub.w    d7,d4
  3797.     cmp.w    a5,d4
  3798.     blt.s    \@out_of_range
  3799.     cmp.w    a6,d4
  3800.     bgt.s    \@out_of_range
  3801.     move.w    d4,\5
  3802.     move.l    \3,\4
  3803.     ext.l    \5
  3804.     moveq    #0,\2
  3805.     bra.s    \@end_clip
  3806. \@out_of_range:
  3807.     bset    #4,\2
  3808. \@end_clip:
  3809.     ENDM
  3810.  
  3811. ; INPUT:
  3812. ; \1: flagnum
  3813. ; \2: flagreg
  3814. ; \3: edgereg
  3815. ; \4: xreg
  3816. ; \5: yreg
  3817. Line_clipEdgeY:    MACRO
  3818.     btst    \1,\2
  3819.     beq.s    \@end_clip
  3820.     move.l    d3,d4
  3821.     sub.l    d1,d4
  3822.     move.l    d2,d7
  3823.     sub.l    d0,d7
  3824.     swap    d7
  3825.     clr.w    d7
  3826.     tst.w    d4
  3827.     beq.s    \@skip_div
  3828.     divs.l    d4,d7
  3829. \@skip_div:
  3830.     move.l    d1,d4
  3831.     sub.l    \3,d4
  3832.     muls.l    d4,d7
  3833.     swap    d7
  3834.     move.w    d0,d4
  3835.     sub.w    d7,d4
  3836.     cmp.w    a3,d4
  3837.     blt.s    \@out_of_range
  3838.     cmp.w    a4,d4
  3839.     bgt.s    \@out_of_range
  3840.     move.w    d4,\4
  3841.     ext.l    \4
  3842.     move.l    \3,\5
  3843.     moveq    #0,\2
  3844.     bra.s    \@end_clip
  3845. \@out_of_range:
  3846.     bset    #4,\2
  3847. \@end_clip:
  3848.     ENDM
  3849.  
  3850. ; INPUT:
  3851. ; \1: flagnum
  3852. ; \2: flagreg
  3853. ; \3: edgereg
  3854. ; \4: xreg
  3855. ; \5: yreg
  3856. ; \6: ireg
  3857. Line_clipGEdgeX:    MACRO
  3858.     btst    \1,\2
  3859.     beq.s    \@end_clip
  3860.     move.l    d2,d4
  3861.     sub.l    d0,d4
  3862.     move.l    d3,d7
  3863.     sub.l    d1,d7
  3864.     swap    d7
  3865.     clr.w    d7
  3866.     tst.w    d4
  3867.     beq.s    \@skip_div
  3868.     divs.l    d4,d7
  3869. \@skip_div:
  3870.     move.l    d0,d4
  3871.     sub.l    \3,d4                ; d4.l: dx
  3872.     muls.l    d4,d7
  3873.     swap    d7
  3874.     move.w    d1,d4
  3875.     sub.w    d7,d4
  3876.     cmp.w    a5,d4
  3877.     blt.s    \@out_of_range
  3878.     cmp.w    a6,d4
  3879.     bgt.s    \@out_of_range
  3880.     move.w    d4,\5
  3881.  
  3882.     move.l    d2,d4
  3883.     sub.l    d0,d4
  3884.     move.l    a2,d7
  3885.     sub.l    a0,d7
  3886.     lsl.l    #8,d7
  3887.     tst.w    d4
  3888.     beq.s    \@skip_div2
  3889.     divs.w    d4,d7                ; (di<<8)/x
  3890. \@skip_div2:
  3891.     move.l    d0,d4
  3892.     sub.l    \3,d4                ; d4.l: dx
  3893.     muls.w    d4,d7
  3894.     asr.l    #8,d7    
  3895.     move.w    a0,d4
  3896.     sub.w    d7,d4
  3897.     move.w    d4,\6
  3898.  
  3899.     move.l    \3,\4
  3900.     ext.l    \5
  3901.     moveq    #0,\2
  3902.     bra.s    \@end_clip
  3903. \@out_of_range:
  3904.     bset    #4,\2
  3905. \@end_clip:
  3906.     ENDM
  3907.  
  3908. ; INPUT:
  3909. ; \1: flagnum
  3910. ; \2: flagreg
  3911. ; \3: edgereg
  3912. ; \4: xreg
  3913. ; \5: yreg
  3914. ; \6: ireg
  3915. Line_clipGEdgeY:    MACRO
  3916.     btst    \1,\2
  3917.     beq.s    \@end_clip
  3918.     move.l    d3,d4
  3919.     sub.l    d1,d4
  3920.     move.l    d2,d7
  3921.     sub.l    d0,d7
  3922.     swap    d7
  3923.     clr.w    d7
  3924.     tst.w    d4
  3925.     beq.s    \@skip_div
  3926.     divs.l    d4,d7
  3927. \@skip_div:
  3928.     move.l    d1,d4
  3929.     sub.l    \3,d4
  3930.     muls.l    d4,d7
  3931.     swap    d7
  3932.     move.w    d0,d4
  3933.     sub.w    d7,d4
  3934.     cmp.w    a3,d4
  3935.     blt.s    \@out_of_range
  3936.     cmp.w    a4,d4
  3937.     bgt.s    \@out_of_range
  3938.     move.w    d4,\4
  3939.  
  3940.     move.l    d3,d4
  3941.     sub.l    d1,d4
  3942.     move.l    a2,d7
  3943.     sub.l    a0,d7
  3944.     lsl.l    #8,d7
  3945.     tst.w    d4
  3946.     beq.s    \@skip_div2
  3947.     divs.w    d4,d7                ; (di<<8)/y
  3948. \@skip_div2:
  3949.     move.l    d1,d4
  3950.     sub.l    \3,d4                ; d4.l: dy
  3951.     muls.w    d4,d7
  3952.     asr.l    #8,d7    
  3953.     move.w    a0,d4
  3954.     sub.w    d7,d4
  3955.     move.w    d4,\6
  3956.  
  3957.     ext.l    \4
  3958.     move.l    \3,\5
  3959.     moveq    #0,\2
  3960.     bra.s    \@end_clip
  3961. \@out_of_range:
  3962.     bset    #4,\2
  3963. \@end_clip:
  3964.     ENDM
  3965.  
  3966. ; Paints a one-colour line to the screen. The line can be clipped in
  3967. ; any way.
  3968. ; INPUT:
  3969. ; d0.l: x1
  3970. ; d1.l: y1
  3971. ; d2.l: x2
  3972. ; d3.l: y2
  3973. Line.paintFlatshaded:
  3974. ; Clip this baby first...
  3975. .clip:    movem.w    Viewport.settingsTable+Viewport.XSTART,a3-a6
  3976.  
  3977.     moveq    #0,d5                ; Set point clipflags to 0.
  3978. .check_first_left:
  3979.     cmp.w    a3,d0                ; XSTART
  3980.     bge.s    .check_first_right
  3981.     addq.w    #%0010,d5
  3982. .check_first_right:
  3983.     cmp.w    a4,d0                ; XEND
  3984.     blt.s    .end_check_first_right
  3985.     addq.w    #%0001,d5
  3986. .end_check_first_right:
  3987. .check_first_above:
  3988.     cmp.w    a5,d1                ; YSTART
  3989.     bge.s    .check_first_under
  3990.     ori.w    #%1000,d5
  3991. .check_first_under:
  3992.     cmp.w    a6,d1                ; YEND
  3993.     blt.s    .end_first_check
  3994.     addq.w    #%0100,d5
  3995. .end_first_check:
  3996.  
  3997.     moveq    #0,d6                ; Set point clipflags to 0.
  3998. .check_second_left:
  3999.     cmp.w    a3,d2                ; XSTART
  4000.     bge.s    .check_second_right
  4001.     addq.w    #%0010,d6
  4002. .check_second_right:
  4003.     cmp.w    a4,d2                ; XEND
  4004.     blt.s    .end_check_second_right
  4005.     addq.w    #%0001,d6
  4006. .end_check_second_right:
  4007. .check_second_above:
  4008.     cmp.w    a5,d3                ; YSTART
  4009.     bge.s    .check_second_under
  4010.     ori.w    #%1000,d6
  4011. .check_second_under:
  4012.     cmp.w    a6,d3                ; YEND
  4013.     blt.s    .end_second_check
  4014.     addq.w    #%0100,d6
  4015. .end_second_check:
  4016.  
  4017.     subq    #1,a4
  4018.     subq    #1,a6
  4019.  
  4020.     move.w    d5,d7
  4021.     and.w    d6,d7
  4022.     beq    .go_on
  4023.     rts
  4024. .go_on:    move.w    d5,d7
  4025.     or.w    d6,d7
  4026.     beq    Line.paintFlatshaded.end_clip
  4027.  
  4028. .clip_first_left:
  4029.     Line_clipEdgeX    #1,d5,a3,d0,d1
  4030. .end_clip_first_left:
  4031. .clip_first_right:
  4032.     Line_clipEdgeX    #0,d5,a4,d0,d1
  4033. .end_clip_first_right:
  4034. .clip_first_top:
  4035.     Line_clipEdgeY    #3,d5,a5,d0,d1
  4036. .end_clip_first_top:
  4037. .clip_first_bottom:
  4038.     Line_clipEdgeY    #2,d5,a6,d0,d1
  4039. .end_clip_first_bottom:
  4040.  
  4041. .clip_second_left:
  4042.     Line_clipEdgeX    #1,d6,a3,d2,d3
  4043. .end_clip_second_left:
  4044. .clip_second_right:
  4045.     Line_clipEdgeX    #0,d6,a4,d2,d3
  4046. .end_clip_second_right:
  4047. .clip_second_top:
  4048.     Line_clipEdgeY    #3,d6,a5,d2,d3
  4049. .end_clip_second_top:
  4050. .clip_second_bottom:
  4051.     Line_clipEdgeY    #2,d6,a6,d2,d3
  4052. .end_clip_second_bottom:
  4053.  
  4054.     or.w    d5,d6
  4055.     btst    #4,d6
  4056.     beq.s    .go_on
  4057.     rts
  4058. .go_on:
  4059.  
  4060. Line.paintFlatshaded.end_clip:
  4061.  
  4062. ; The lineroutine has NO CLIPPING!!!
  4063.     moveq    #0,d6
  4064.     move.w    Line.colorNum,d6
  4065.     movea.l    Polygon.coloradr,a1
  4066.     lea    Primitive.GRADIENTSIZE/2(a1),a1
  4067.     lsl.l    #Primitive.GRADIENTBITS+1,d6
  4068.     move.w    (a1,d6.l),d6
  4069.     movea.l    Primitive.screenadr,a0
  4070.     clr.l    d5
  4071.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  4072.     add.l    d5,d5
  4073. ; d0.w=x0, d1.w=y0, d2.w=x1, d3.w=y1, d5.l=scrwidth, d6.w=color, a0: screen
  4074.  
  4075. ; Calculate |dx|, |dy| and calculate x step, y step.
  4076.     moveq    #2,d4
  4077.     sub.w    d0,d2            ; d2.w = dx
  4078.     bpl.s    .dx_positive
  4079.     neg.l    d4
  4080.     neg.w    d2
  4081. .dx_positive:
  4082.     movea.l    d4,a1            ; a1 = x step
  4083.     move.l    d5,d4
  4084.     sub.w    d1,d3            ; d3.w = dy
  4085.     bpl.s    .dy_positive
  4086.     neg.l    d4
  4087.     neg.w    d3
  4088. .dy_positive:
  4089.     movea.l    d4,a2            ; a2 = y step
  4090. ; d2.w = |dx|, d3.w = |dy|
  4091.  
  4092. ; Calculate the startaddress on screen.
  4093.     ext.l    d0
  4094.     add.w    d0,d0
  4095.     mulu.w    d5,d1
  4096.     add.l    d0,d1
  4097.     adda.l    d1,a0
  4098.  
  4099. ; Branch to appropriate routine, depending on |dx| < |dy|.
  4100.     cmp.w    d2,d3
  4101.     blt.s    Line.paintDy
  4102.  
  4103. ; Paints a line with |dy| >= |dx|.
  4104. Line.paintDx:
  4105.     move.w    d3,d5
  4106.     beq.s    .end
  4107.     ;subq.w    #1,d5
  4108.     move.w    d3,d0
  4109.  
  4110. .loop:    move.w    d6,(a0)
  4111.     sub.w    d2,d0
  4112.     bgt.s    .end_inc_x
  4113.     add.w    d3,d0
  4114.     adda.l    a1,a0
  4115. .end_inc_x:
  4116.     adda.l    a2,a0
  4117.     dbra    d5,.loop
  4118.  
  4119. .end:    rts
  4120.  
  4121. ; Paints a line with |dx| < |dy|.
  4122. Line.paintDy:
  4123.     move.w    d2,d5
  4124.     beq.s    .end
  4125.     ;subq.w    #1,d5
  4126.     move.w    d2,d0
  4127.  
  4128. .loop:    move.w    d6,(a0)
  4129.     sub.w    d3,d0
  4130.     bgt.s    .end_inc_y
  4131.     add.w    d2,d0
  4132.     adda.l    a2,a0
  4133. .end_inc_y:
  4134.     adda.l    a1,a0
  4135.     dbra    d5,.loop
  4136.  
  4137. .end:    rts
  4138.  
  4139. ; Paints a gouraudshaded line to the screen. The line can be clipped in any
  4140. ; way.
  4141. ; INPUT:
  4142. ; d0.l: x1
  4143. ; d1.l: y1
  4144. ; d2.l: x2
  4145. ; d3.l: y2
  4146. Line.paintGouraudshaded:
  4147.     receiveWordFromDsp    a0
  4148.     receiveWordFromDsp    a2
  4149.  
  4150. Line.paintGradiented:
  4151. ; Clip this baby first...
  4152. .clip:    movem.w    Viewport.settingsTable+Viewport.XSTART,a3-a6
  4153.  
  4154.     moveq    #0,d5                ; Set point clipflags to 0.
  4155. .check_first_left:
  4156.     cmp.w    a3,d0                ; XSTART
  4157.     bge.s    .check_first_right
  4158.     addq.w    #%0010,d5
  4159. .check_first_right:
  4160.     cmp.w    a4,d0                ; XEND
  4161.     blt.s    .end_check_first_right
  4162.     addq.w    #%0001,d5
  4163. .end_check_first_right:
  4164. .check_first_above:
  4165.     cmp.w    a5,d1                ; YSTART
  4166.     bge.s    .check_first_under
  4167.     ori.w    #%1000,d5
  4168. .check_first_under:
  4169.     cmp.w    a6,d1                ; YEND
  4170.     blt.s    .end_first_check
  4171.     addq.w    #%0100,d5
  4172. .end_first_check:
  4173.  
  4174.     moveq    #0,d6                ; Set point clipflags to 0.
  4175. .check_second_left:
  4176.     cmp.w    a3,d2                ; XSTART
  4177.     bge.s    .check_second_right
  4178.     addq.w    #%0010,d6
  4179. .check_second_right:
  4180.     cmp.w    a4,d2                ; XEND
  4181.     blt.s    .end_check_second_right
  4182.     addq.w    #%0001,d6
  4183. .end_check_second_right:
  4184. .check_second_above:
  4185.     cmp.w    a5,d3                ; YSTART
  4186.     bge.s    .check_second_under
  4187.     ori.w    #%1000,d6
  4188. .check_second_under:
  4189.     cmp.w    a6,d3                ; YEND
  4190.     blt.s    .end_second_check
  4191.     addq.w    #%0100,d6
  4192. .end_second_check:
  4193.  
  4194.     subq    #1,a4
  4195.     subq    #1,a6
  4196.  
  4197.     move.w    d5,d7
  4198.     and.w    d6,d7
  4199.     beq    .go_on
  4200.     rts
  4201. .go_on:    move.w    d5,d7
  4202.     or.w    d6,d7
  4203.     beq    Line.paintGouraudshaded.end_clip
  4204.  
  4205. .clip_first_left:
  4206.     Line_clipGEdgeX    #1,d5,a3,d0,d1,a0
  4207. .end_clip_first_left:
  4208. .clip_first_right:
  4209.     Line_clipGEdgeX    #0,d5,a4,d0,d1,a0
  4210. .end_clip_first_right:
  4211. .clip_first_top:
  4212.     Line_clipGEdgeY    #3,d5,a5,d0,d1,a0
  4213. .end_clip_first_top:
  4214. .clip_first_bottom:
  4215.     Line_clipGEdgeY    #2,d5,a6,d0,d1,a0
  4216. .end_clip_first_bottom:
  4217.  
  4218. .clip_second_left:
  4219.     Line_clipGEdgeX    #1,d6,a3,d2,d3,a2
  4220. .end_clip_second_left:
  4221. .clip_second_right:
  4222.     Line_clipGEdgeX    #0,d6,a4,d2,d3,a2
  4223. .end_clip_second_right:
  4224. .clip_second_top:
  4225.     Line_clipGEdgeY    #3,d6,a5,d2,d3,a2
  4226. .end_clip_second_top:
  4227. .clip_second_bottom:
  4228.     Line_clipGEdgeY    #2,d6,a6,d2,d3,a2
  4229. .end_clip_second_bottom:
  4230.  
  4231.     or.w    d5,d6
  4232.     btst    #4,d6
  4233.     beq.s    .go_on
  4234.     rts
  4235. .go_on:
  4236.  
  4237. Line.paintGouraudshaded.end_clip:
  4238.  
  4239. ; The lineroutine has NO CLIPPING!!!
  4240.     move.l    a0,d6
  4241.     move.l    a2,d7
  4242.     clr.l    d4
  4243.     move.w    Line.colorNum,d4
  4244.     movea.l    Polygon.coloradr,a1
  4245.     lsl.l    #Primitive.GRADIENTBITS+1,d4
  4246.     adda.l    d4,a1
  4247.     movea.l    Primitive.screenadr,a0
  4248. ; d0.w=x0, d1.w=y0, d2.w=x1, d3.w=y1, d6.w=g0 d7.w=g1, a0: screen, a1: pal
  4249.  
  4250.     clr.l    d5
  4251.     move.w    Viewport.settingsTable+Viewport.XSCREEN,d5
  4252.     add.l    d5,d5
  4253.  
  4254. ; Calculate |dx|, |dy| and calculate x step, y step.
  4255.     moveq    #2,d4
  4256.     sub.w    d0,d2            ; d2.w=dx
  4257.     bpl.s    .dx_positive
  4258.     neg.l    d4
  4259.     neg.w    d2
  4260. .dx_positive:
  4261.     movea.l    d4,a2            ; a1= x step
  4262.     move.l    d5,d4
  4263.     sub.w    d1,d3            ; d3.w=dy
  4264.     bpl.s    .dy_positive
  4265.     neg.l    d4
  4266.     neg.w    d3
  4267. .dy_positive:
  4268.     movea.l    d4,a3            ; a2= y step
  4269. ; d2.w = |dx|, d3.w = |dy|
  4270.  
  4271. ; Calc dg.
  4272.     ext.l    d7
  4273.     ext.l    d6
  4274.     sub.l    d6,d7
  4275.     lsl.l    #8,d6
  4276.     move.l    d6,d4
  4277.     lsl.l    #8,d7
  4278.  
  4279. ; Calculate the startaddress on screen.
  4280.     ext.l    d0
  4281.     add.l    d0,d0
  4282.     mulu.w    d5,d1
  4283.     add.l    d0,d1
  4284.     adda.l    d1,a0
  4285.  
  4286. ; Branch to appropriate routine, depending on |dx| < |dy|.
  4287.     cmp.w    d2,d3
  4288.     blt.s    Line.paintGradDy
  4289.  
  4290. ; Paints a line with |dy| >= |dx|.
  4291. Line.paintGradDx:
  4292.     move.w    d3,d5
  4293.     beq.s    .end
  4294.     divs.w    d5,d7
  4295.     ;subq.w    #1,d5
  4296.     move.w    d3,d0
  4297.  
  4298. .loop:    move.l    d4,d1
  4299.     lsr.l    #8,d1
  4300.     move.w    (a1,d1.l*2),(a0)
  4301.     sub.w    d2,d0
  4302.     bgt.s    .end_inc_x
  4303.     add.w    d3,d0
  4304.     adda.l    a2,a0
  4305. .end_inc_x:
  4306.     add.w    d7,d4
  4307.     adda.l    a3,a0
  4308.     dbra    d5,.loop
  4309.  
  4310. .end:    rts
  4311.  
  4312. ; Paints a line with |dx| < |dy|.
  4313. Line.paintGradDy:
  4314.     move.w    d2,d5
  4315.     beq.s    .end
  4316.     divs.w    d5,d7
  4317.     ;subq.w    #1,d5
  4318.     move.w    d2,d0
  4319.  
  4320. .loop:    move.l    d4,d1
  4321.     lsr.l    #8,d1
  4322.     move.w    (a1,d1.l*2),(a0)
  4323.     sub.w    d3,d0
  4324.     bgt.s    .end_inc_y
  4325.     add.w    d2,d0
  4326.     adda.l    a3,a0
  4327. .end_inc_y:
  4328.     add.w    d7,d4
  4329.     adda.l    a2,a0
  4330.     dbra    d5,.loop
  4331.  
  4332. .end:    rts
  4333.  
  4334. ; Paints a gouraudshaded line to the screen. The line can be clipped in any
  4335. ; way.
  4336. ; INPUT:
  4337. ; d0.l: x1
  4338. ; d1.l: y1
  4339. ; d2.l: x2
  4340. ; d3.l: y2
  4341. ; a1: Line structure
  4342. ; a2: vertex table
  4343. Line.paintPhongshaded:
  4344.     receiveWordFromDsp    a0
  4345.     receiveWordFromDsp    a2
  4346.     bra    Line.paintGradiented
  4347.  
  4348.     DATA
  4349.  
  4350. ;======= HumanFly
  4351.  
  4352. HumanFly.p56:
  4353.     INCBIN    S_FLY.P56
  4354. HumanFly.endP56:
  4355.     EVEN
  4356.  
  4357. ;======= Sprite
  4358.  
  4359. Sprite.rout:
  4360.     DC.L    Sprite.paintMoved
  4361.  
  4362.     BSS
  4363.  
  4364. ;======= ObjectRegistry
  4365.  
  4366. ObjectRegistry.numberOfHandles:
  4367.     DS.W    1
  4368. ObjectRegistry.table:
  4369.     DS.L    ObjectRegistry.CAPACITY
  4370. ObjectRegistry.size:
  4371.     DS.L    1                ; #words in dsp buffer already
  4372.  
  4373. ;======= PrimitiveMesh
  4374.  
  4375. PrimitiveMesh.shadowAdr:            ; points to actual shadow
  4376.     DS.L    1
  4377. PrimitiveMesh.shadowStartAdr:            ; points to 1st shadow
  4378.     DS.L    1
  4379. PrimitiveMesh.background:            ; backgroundaddress
  4380.     DS.L    1
  4381. PrimitiveMesh.shadowsOn:
  4382.     DS.W    1
  4383.  
  4384. ;======= Primitive
  4385.  
  4386. Primitive.skipBytes:
  4387.     DS.W    1
  4388. Primitive.bytesPerPixel:
  4389.     DS.W    1
  4390. Primitive.screenadr:
  4391.     DS.L    1
  4392. Primitive.msbMixTable:
  4393.     DS.B    256*256
  4394. Primitive.lsbMixTable:
  4395.     DS.B    256*256
  4396.  
  4397. ;======= Polygon
  4398.  
  4399. Polygon.gradadr:                ; address of current gradient table
  4400.     DS.L    1
  4401. Polygon.textureTable:                ; contains texturepointers (nullterminated)
  4402.     DS.L    Polygon.MAX_TEXTURES+1
  4403. Polygon.textureroutadr:
  4404.     DS.L    1
  4405. Polygon.v4routadr:
  4406.     DS.L    1
  4407. Polygon.alphatableadr:
  4408.     DS.L    1
  4409. Polygon.texturemode:
  4410.     DS.W    1
  4411. Polygon.v4texturemode:
  4412.     DS.W    1
  4413. Polygon.color:                    ; current color
  4414.     DS.L    1
  4415. Polygon.coloradr:                ; base address of gradient tables
  4416.     DS.L    1
  4417. Polygon.curtexture:                ; first current textureaddress
  4418.     DS.L    1
  4419. Polygon.curtexture2:                ; second current textureaddress
  4420.     DS.L    1
  4421.  
  4422. Polygon.uvslopes:
  4423.     DS.W    4                ; u0,v0,u1,v1
  4424. Polygon.invTable:
  4425.     DS.W    Viewport.MAX_Y+1
  4426. Polygon.fragmentTable:
  4427.     DS.W    1                ; active fragment flags
  4428.     DS.B    Fragment.SIZE*4            ; max 3 for quad, max 2 for triangle
  4429. Polygon.scanlineTable:
  4430.     DS.W    1
  4431.     DS.W    3*Viewport.MAX_Y        ; table for tmap and envmap scanlines
  4432. Polygon.shadeTable:
  4433.     DS.W    Vertex2d.SIZE*8            ; (u,v) for each vertex
  4434. Polygon.extvertexTable:
  4435.     DS.W    4*3                ; for each trianglevertex: u0,v0,u1,v1
  4436. Polygon.bumpmapTable:
  4437.     DS.W    1
  4438.     DS.L    16
  4439. Polygon.textureCache:
  4440.     DS.B    3*8192
  4441.  
  4442. ;======= Line
  4443.  
  4444. Line.colorNum:
  4445.     DS.W    1