home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / r_draw68k.s < prev    next >
Encoding:
Text File  |  2000-06-17  |  43.0 KB  |  1,471 lines

  1. * Copyright (C) 1996-1997 Id Software, Inc. 
  2. * This program is free software; you can redistribute it and/or 
  3. * modify it under the terms of the GNU General Public License 
  4. * as published by the Free Software Foundation; either version 2 
  5. * of the License, or (at your option) any later version. 
  6. * This program is distributed in the hope that it will be useful, 
  7. * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  8. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   
  9. * See the GNU General Public License for more details. 
  10. * You should have received a copy of the GNU General Public License 
  11. * along with this program; if not, write to the Free Software 
  12. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
  13.  
  14. **
  15. ** Quake for AMIGA
  16. ** r_draw.c assembler implementations by Frank Wille <frank@phoenix.owl.de>
  17. **
  18.  
  19.         XREF    _r_lastvertvalid
  20.         XREF    _r_u1
  21.         XREF    _r_v1
  22.         XREF    _r_lzi1
  23.         XREF    _r_ceilv1
  24.         XREF    _r_nearzi
  25.         XREF    _r_nearzionly
  26.         XREF    _r_emitted
  27.         XREF    _r_framecount
  28.         XREF    _r_pedge
  29.         XREF    _r_refdef
  30.         XREF    _r_leftclipped
  31.         XREF    _r_rightclipped
  32.         XREF    _r_leftexit
  33.         XREF    _r_rightexit
  34.         XREF    _r_leftenter
  35.         XREF    _r_rightenter
  36.         XREF    _r_edges
  37.         XREF    _r_outofsurfaces
  38.         XREF    _r_outofedges
  39.         XREF    _r_pcurrentvertbase
  40.         XREF    _r_polycount
  41.         XREF    _r_currentkey
  42.         XREF    _c_faceclip
  43.         XREF    _modelorg
  44.         XREF    _xscale
  45.         XREF    _yscale
  46.         XREF    _xscaleinv
  47.         XREF    _yscaleinv
  48.         XREF    _xcenter
  49.         XREF    _ycenter
  50.         XREF    _vright
  51.         XREF    _vup
  52.         XREF    _vpn
  53.         XREF    _cacheoffset
  54.         XREF    _edge_p
  55.         XREF    _surfaces
  56.         XREF    _surface_p
  57.         XREF    _surf_max
  58.         XREF    _edge_max
  59.         XREF    _newedges
  60.         XREF    _removeedges
  61.         XREF    _view_clipplanes
  62.         XREF    _insubmodel
  63.         XREF    _currententity
  64.         XREF    _makeleftedge
  65.         XREF    _makerightedge
  66.  
  67.         XDEF    _R_EmitEdge
  68.         XDEF    _R_ClipEdge
  69.         XDEF    _R_RenderFace
  70.  
  71. NEAR_CLIP               equ.s   0.01            ;must match the def. in r_local.h
  72. FULLY_CLIPPED_CACHED    =       $80000000
  73. FRAMECOUNT_MASK         =       $7FFFFFFF
  74.  
  75. REFDEF_FVRECTX_ADJ      =       68
  76. REFDEF_FVRECTY_ADJ      =       72
  77. REFDEF_VRECTX_ADJ_S20   =       76
  78. REFDEF_VRECTXR_ADJ_S20  =       80
  79. REFDEF_FVRECTRIGHT_ADJ  =       84
  80. REFDEF_FVRECTBOTTOM_ADJ =       88
  81.  
  82. EDGE_U                  =       0
  83. EDGE_U_STEP             =       4
  84. EDGE_PREV               =       8
  85. EDGE_NEXT               =       12
  86. EDGE_SURFS              =       16
  87. EDGE_NEXTREMOVE         =       20
  88. EDGE_NEARZI             =       24
  89. EDGE_OWNER              =       28
  90. EDGE_SIZEOF_EXP         =       5
  91. EDGE_SIZEOF             =       (1<<EDGE_SIZEOF_EXP)
  92.  
  93. CLIP_NORMAL             =       0
  94. CLIP_DIST               =       12
  95. CLIP_NEXT               =       16
  96. CLIP_LEFTEDGE           =       20
  97. CLIP_RIGHTEDGE          =       21
  98. CLIP_RESERVED           =       22
  99. CLIP_SIZEOF             =       24
  100.  
  101. MVERTEX_SIZEOF          =       12
  102.  
  103. MEDGE_V                 =       0
  104. MEDGE_CEO               =       4
  105. MEDGE_SIZEOF_EXP        =       3
  106. MEDGE_SIZEOF            =       (1<<MEDGE_SIZEOF_EXP)
  107.  
  108. MSURFACE_VISFRAME       =       0
  109. MSURFACE_DLIGHTFRAME    =       4
  110. MSURFACE_DLIGHTBITS     =       8
  111. MSURFACE_PLANE          =       12
  112. MSURFACE_FLAGS          =       16
  113. MSURFACE_FIRSTEDGE      =       20
  114. MSURFACE_NUMEDGES       =       24
  115. MSURFACE_CACHESPOTS     =       28
  116. MSURFACE_TEXTUREMINS    =       44
  117. MSURFACE_EXTENTS        =       48
  118. MSURFACE_TEXINFO        =       52
  119. MSURFACE_STYLES         =       56
  120. MSURFACE_SAMPLES        =       60
  121. MSURFACE_SIZEOF_EXP     =       6
  122. MSURFACE_SIZEOF         =       (1<<MSURFACE_SIZEOF_EXP)
  123.  
  124. MPLANE_NORMAL           =       0
  125. MPLANE_DIST             =       12
  126. MPLANE_TYPE             =       16
  127. MPLANE_SIGNBITS         =       17
  128. MPLANE_SIZEOF           =       20
  129.  
  130. SURF_NEXT               =       0
  131. SURF_PREV               =       4
  132. SURF_SPANS              =       8
  133. SURF_KEY                =       12
  134. SURF_LAST_U             =       16
  135. SURF_SPANSTATE          =       20
  136. SURF_FLAGS              =       24
  137. SURF_DATA               =       28
  138. SURF_ENTITY             =       32
  139. SURF_NEARZI             =       36
  140. SURF_INSUBMODEL         =       40
  141. SURF_D_ZIORIGIN         =       44
  142. SURF_D_ZISTEPU          =       48
  143. SURF_D_ZISTEPV          =       52
  144. SURF_SIZEOF_EXP         =       6
  145. SURF_SIZEOF             =       (1<<SURF_SIZEOF_EXP)
  146.  
  147. ENTITY_KEYNUM        =    0
  148. ENTITY_ORIGIN        =    4
  149. ENTITY_ANGLES        =    16
  150. ENTITY_MODEL        =    28
  151. ENTITY_FRAME        =    32
  152. ENTITY_COLORMAP        =    36
  153. ENTITY_SKINNUM        =    40
  154. ENTITY_SCOREBOARD    =    44
  155. ENTITY_SYNCBASE        =    48
  156. ENTITY_EFRAG        =    52
  157. ENTITY_VISFRAME        =    56
  158. ENTITY_DLIGHTFRAME    =    60
  159. ENTITY_DLIGHTBITS    =    64
  160. ENTITY_TRIVIAL_ACCEPT    =    68
  161. ENTITY_TOPNODE        =    72
  162. ENTITY_SIZEOF           =       76
  163.  
  164. MODEL_NAME              =       0
  165. MODEL_NEEDLOAD          =       64
  166. MODEL_TYPE              =       68
  167. MODEL_NUMFRAMES         =       72
  168. MODEL_SYNCTYPE          =       76
  169. MODEL_FLAGS             =       80
  170. MODEL_MINS              =       84
  171. MODEL_MAXS              =       96
  172. MODEL_RADIUS            =       108
  173. MODEL_CLIPBOX        =    112
  174. MODEL_CLIPMINS        =    116
  175. MODEL_CLIPMAXS        =    128
  176. MODEL_FIRSTMS           =       140
  177. MODEL_NUMMS             =       144
  178. MODEL_NUMSUBMODELS      =       148
  179. MODEL_SUBMODELS         =       152
  180. MODEL_NUMPLANES         =       156
  181. MODEL_PLANES            =       160
  182. MODEL_NUMLEAFS          =       164
  183. MODEL_LEAFS             =       168
  184. MODEL_NUMVERTEXES       =       172
  185. MODEL_VERTEXES          =       176
  186. MODEL_NUMEDGES          =       180
  187. MODEL_EDGES             =       184
  188. MODEL_NUMNODES          =       188
  189. MODEL_NODES             =       192
  190. MODEL_NUMTEXINFO        =       196
  191. MODEL_TEXINFO           =       200
  192. MODEL_NUMSURFACES       =       204
  193. MODEL_SURFACES          =       208
  194. MODEL_NUMSURFEDGES      =       212
  195. MODEL_SURFEDGES         =       216
  196. MODEL_NUMCLIPNODES      =       220
  197. MODEL_CLIPNODES         =       224
  198. MODEL_NUMMARKSURFACES   =       228
  199. MODEL_MARKSURFACES      =       232
  200.  
  201. ******************************************************************************
  202. *
  203. *       void _R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
  204. *
  205. ******************************************************************************
  206.  
  207.         cnop    0,4
  208. _R_EmitEdge
  209.  
  210.         rsreset
  211. .fpuregs        rs.x    6
  212. .intregs        rs.l    7
  213.         rs.l    1
  214. .pv0            rs.l    1
  215. .pv1            rs.l    1
  216.  
  217.         movem.l d2-d5/a2-a4,-(sp)
  218.         fmovem.x        fp2-fp7,-(sp)
  219.         fmove.l fpcr,d5
  220.         fmove.l #$000000b0,fpcr
  221.         move.l  .pv0(sp),a0
  222.         move.l  .pv1(sp),a1
  223.         lea     _r_refdef,a4
  224.  
  225. *        if (r_lastvertvalid)
  226. *        {
  227. *                u0 = r_u1;
  228. *                v0 = r_v1;
  229. *                lzi0 = r_lzi1;
  230. *                ceilv0 = r_ceilv1;
  231. *        }
  232.  
  233.         tst.l   _r_lastvertvalid
  234.         beq.b   .else
  235.         fmove.s _r_u1,fp0               ;u0 = r_u1
  236.         fmove.s _r_v1,fp1               ;v0 = r_v1
  237.         fmove.s _r_lzi1,fp2             ;lzi0 = r_lzi1
  238.         move.l  _r_ceilv1,d0            ;ceilv0 = r_ceilv1
  239.         bra.b   .next
  240.  
  241. *                world = &pv0->position[0];
  242. *
  243. *                VectorSubtract (world, modelorg, local);
  244. *                TransformVector (local, transformed);
  245. *
  246. *                if (transformed[2] < NEAR_CLIP)
  247. *                        transformed[2] = NEAR_CLIP;
  248. *
  249. *                lzi0 = 1.0 / transformed[2];
  250. *
  251. *                scale = xscale * lzi0;
  252. *                u0 = (xcenter + scale*transformed[0]);
  253. *                if (u0 < r_refdef.fvrectx_adj)
  254. *                        u0 = r_refdef.fvrectx_adj;
  255. *                if (u0 > r_refdef.fvrectright_adj)
  256. *                        u0 = r_refdef.fvrectright_adj;
  257. *
  258. *                scale = yscale * lzi0;
  259. *                v0 = (ycenter - scale*transformed[1]);
  260. *                if (v0 < r_refdef.fvrecty_adj)
  261. *                        v0 = r_refdef.fvrecty_adj;
  262. *                if (v0 > r_refdef.fvrectbottom_adj)
  263. *                        v0 = r_refdef.fvrectbottom_adj;
  264. *
  265. *                ceilv0 = (int) ceil(v0);
  266.  
  267. .else
  268.         lea     _modelorg,a2
  269.  
  270. ******  VectorSubtract (inlined)
  271.  
  272.         fmove.s (a0)+,fp3               ;VectorSubtract (world,
  273.         fsub.s  (a2)+,fp3               ;modelorg,local)
  274.         fmove.s (a0)+,fp4
  275.         fsub.s  (a2)+,fp4
  276.         fmove.s (a0)+,fp5
  277.         fsub.s  (a2)+,fp5
  278.  
  279. ******  TransformVector (inlined)
  280.  
  281.         lea     _vright,a3              ;TransformVector (local,
  282.         fmove.s (a3)+,fp0               ;transformed)
  283.         fmul    fp3,fp0
  284.         fmove.s (a3)+,fp1
  285.         fmul    fp4,fp1
  286.         fadd    fp1,fp0
  287.         fmove.s (a3)+,fp1
  288.         fmul    fp5,fp1
  289.         fadd    fp1,fp0                 ;fp0 = transformed[0]
  290.         lea     _vup,a3
  291.         fmove.s (a3)+,fp1
  292.         fmul    fp3,fp1
  293.         fmove.s (a3)+,fp2
  294.         fmul    fp4,fp2
  295.         fadd    fp2,fp1
  296.         fmove.s (a3)+,fp2
  297.         fmul    fp5,fp2
  298.         fadd    fp2,fp1                 ;fp1 = transformed[1]
  299.         lea     _vpn,a3
  300.         fmul.s  (a3)+,fp3
  301.         fmul.s  (a3)+,fp4
  302.         fmul.s  (a3)+,fp5
  303.         fadd    fp4,fp3
  304.         fadd    fp5,fp3                 ;fp3 = transformed[2]
  305.  
  306. ******  end of TransformVector
  307.  
  308.         fcmp.s  #NEAR_CLIP,fp3          ;if transformed[2] < NEAR_CLIP
  309.         fboge.b .cont
  310.         fmove.s #NEAR_CLIP,fp3          ;transformed[2] = NEAR_CLIP
  311. .cont
  312.         fmove.s #1,fp2
  313.         fdiv    fp3,fp2                 ;lzi0 = 1.0 / transformed[2]
  314.         fmul    fp2,fp0
  315.         fmul.s  _xscale,fp0             ;scale = scale * lzi0
  316.         fadd.s  _xcenter,fp0            ;u0 = xcenter + (scale * lzi0)
  317.         fmove.s REFDEF_FVRECTX_ADJ(a4),fp7 ;if (u0 < r_refdef.fvrectx ...
  318.         fcmp    fp7,fp0
  319.         fboge.b .cont2
  320.         fmove   fp7,fp0                 ;u0 = r_refdef.fvrectx_adj
  321. .cont2
  322.         fmove.s REFDEF_FVRECTRIGHT_ADJ(a4),fp7
  323.         fcmp    fp7,fp0                 ;if (u0 > r_refdef.fvrec...
  324.         fbole.b .cont3
  325.         fmove   fp7,fp0                 ;u0 = r_refdef.fvrectright_adj
  326. .cont3
  327.         fmul    fp2,fp1
  328.         fmul.s  _yscale,fp1
  329.         fsub.s  _ycenter,fp1
  330.         fneg    fp1                     ;scale = yscale * lzi0
  331.         fmove.s REFDEF_FVRECTY_ADJ(a4),fp7
  332.         fcmp    fp7,fp1                 ;if (v0 < refdef.fvrecty_adj)
  333.         fboge.b .cont4
  334.         fmove   fp7,fp1                 ;v0 = ycenter - scale*transformed[1]
  335. .cont4
  336.         fmove.s REFDEF_FVRECTBOTTOM_ADJ(a4),fp7
  337.         fcmp    fp7,fp1                 ;if (v0 > r_refdef.fvrectb...
  338.         fbole.b .cont5
  339.         fmove   fp7,fp1                 ;v0 = r_refdef.fvrectbottom_adj
  340. .cont5
  341.         fmove.l fp1,d0
  342. .next
  343.  
  344. *        world = &pv1->position[0];
  345. *
  346. *// transform and project
  347. *        VectorSubtract (world, modelorg, local);
  348. *        TransformVector (local, transformed);
  349. *
  350. *        if (transformed[2] < NEAR_CLIP)
  351. *                transformed[2] = NEAR_CLIP;
  352. *
  353. *        r_lzi1 = 1.0 / transformed[2];
  354. *
  355. *        scale = xscale * r_lzi1;
  356. *        r_u1 = (xcenter + scale*transformed[0]);
  357. *        if (r_u1 < r_refdef.fvrectx_adj)
  358. *                r_u1 = r_refdef.fvrectx_adj;
  359. *        if (r_u1 > r_refdef.fvrectright_adj)
  360. *                r_u1 = r_refdef.fvrectright_adj;
  361. *
  362. *        scale = yscale * r_lzi1;
  363. *        r_v1 = (ycenter - scale*transformed[1]);
  364. *        if (r_v1 < r_refdef.fvrecty_adj)
  365. *                r_v1 = r_refdef.fvrecty_adj;
  366. *        if (r_v1 > r_refdef.fvrectbottom_adj)
  367. *                r_v1 = r_refdef.fvrectbottom_adj;
  368.  
  369.         fmove.s fp0,-(sp)
  370.  
  371. ******  VectorSubtract (inlined)
  372.  
  373.         lea     _modelorg,a2
  374.         fmove.s (a1)+,fp3               ;VectorSubtract (world, modelorg
  375.         fsub.s  (a2)+,fp3               ;local)
  376.         fmove.s (a1)+,fp4
  377.         fsub.s  (a2)+,fp4
  378.         fmove.s (a1)+,fp5
  379.         fsub.s  (a2)+,fp5
  380.  
  381. ******  TransformVector (inlined)
  382.  
  383.         lea     _vright,a3              ;TransformVector (local, transformed)
  384.         fmove.s (a3)+,fp6
  385.         fmul    fp3,fp6
  386.         fmove.s (a3)+,fp7
  387.         fmul    fp4,fp7
  388.         fadd    fp7,fp6
  389.         fmove.s (a3)+,fp7
  390.         fmul    fp5,fp7
  391.         fadd    fp6,fp7                 ;fp7 = transformed[0]
  392.         lea     _vup,a3
  393.         fmove.s (a3)+,fp6
  394.         fmul    fp3,fp6
  395.         fmove.s (a3)+,fp0
  396.         fmul    fp4,fp0
  397.         fadd    fp0,fp6
  398.         fmove.s (a3)+,fp0
  399.         fmul    fp5,fp0
  400.         fadd    fp0,fp6                 ;fp6 = transformed[1]
  401.         fmove.s (sp)+,fp0
  402.         lea     _vpn,a3
  403.         fmul.s  (a3)+,fp3
  404.         fmul.s  (a3)+,fp4
  405.         fmul.s  (a3)+,fp5
  406.         fadd    fp4,fp3
  407.         fadd    fp5,fp3                 ;fp3 = transformed[2]
  408.  
  409. ******  end of TransformVector
  410.  
  411.         fcmp.s  #NEAR_CLIP,fp3          ;if transformed[2] < NEAR_CLIP
  412.         fboge.b .cont6
  413.         fmove.s #NEAR_CLIP,fp3          ;transformed[2] = NEAR_CLIP
  414. .cont6
  415.         fmove.s #1,fp5
  416.         fdiv    fp3,fp5                 ;r_lzi1 = 1.0 / transformed[2]
  417.         fmul    fp5,fp7
  418.         fmul.s  _xscale,fp7
  419.         fadd.s  _xcenter,fp7            ;scale = xscale * r_lzi
  420.         fmove.s REFDEF_FVRECTX_ADJ(a4),fp4
  421.         fcmp    fp4,fp7                 ;if (r_u1 < r_refdef...
  422.         fboge.b .cont7
  423.         fmove   fp4,fp7                 ;r_u1 = r_refdef.fvrectx_adj)
  424. .cont7
  425.         fmove.s REFDEF_FVRECTRIGHT_ADJ(a4),fp4
  426.         fcmp    fp4,fp7                 ;if (r_u1 > r_refdef...
  427.         fbole.b .cont8
  428.         fmove   fp4,fp7                 ;r_u1 = r_refdef.fvrectright_adj)
  429. .cont8
  430.         fmul    fp5,fp6
  431.         fmul.s  _yscale,fp6
  432.         fsub.s  _ycenter,fp6
  433.         fneg    fp6                     ;scale = yscale * r_lzi1
  434.         fmove.s REFDEF_FVRECTY_ADJ(a4),fp4
  435.         fcmp    fp4,fp6                 ;if (r_v1 < r_refdef...
  436.         fboge.b .cont9
  437.         fmove   fp4,fp6                 ;r_v1 = r_refdef.fvrecty_adj
  438. .cont9
  439.         fmove.s REFDEF_FVRECTBOTTOM_ADJ(a4),fp4
  440.         fcmp    fp4,fp6                 ;if (r_v1 > r_refdef...
  441.         fbole.b .cont10
  442.         fmove   fp4,fp6                 ;r_v1 = r_refdef.fvrectbottom_adj)
  443. .cont10
  444.  
  445. *        if (r_lzi1 > lzi0)
  446. *                lzi0 = r_lzi1;
  447. *
  448. *        if (lzi0 > r_nearzi)    // for mipmap finding
  449. *                r_nearzi = lzi0;
  450. *
  451. *// for right edges, all we want is the effect on 1/z
  452. *        if (r_nearzionly)
  453. *                return;
  454. *
  455. *        r_emitted = 1;
  456. *
  457. *        r_ceilv1 = (int) ceil(r_v1);
  458.  
  459.         fcmp    fp5,fp2                 ;if (r_lzi1 > lzi0)
  460.         fboge.b .cont11
  461.         fmove   fp5,fp2                 ;lzi0 = r_lzi1
  462. .cont11
  463.         fcmp.s  _r_nearzi,fp2           ;if (lzi0 > r_nearzi)
  464.         fbole.b .cont12
  465.         fmove.s fp2,_r_nearzi           ;r_nearzi = lzi0
  466. .cont12
  467.         fmove.l fp6,d1                  ;r_ceilv1 = (int) ceil(r_v1)
  468.         fmove.l d5,fpcr
  469.         tst.l   _r_nearzionly           ;if (r_nearzionly)
  470.         bne.b   .exit2                  ;return
  471.         move.l  #1,_r_emitted           ;r_emitted = 1
  472.  
  473. *        if (ceilv0 == r_ceilv1)
  474. *        {
  475. *        // we cache unclipped horizontal edges as fully clipped
  476. *                if (cacheoffset != 0x7FFFFFFF)
  477. *                {
  478. *                        cacheoffset = FULLY_CLIPPED_CACHED |
  479. *                                        (r_framecount & FRAMECOUNT_MASK);
  480. *                }
  481. *
  482. *                return;         // horizontal edge
  483. *        }
  484.  
  485.         cmp.l   d0,d1                   ;if (ceilv0 == r_ceilv1)
  486.         bne.b   .cont13
  487.         cmp.l   #$7fffffff,_cacheoffset ;if (cacheoffset != 0x7fffffff)
  488.         beq.b   .exit1
  489.         move.l  _r_framecount,d2
  490.         and.l   #FRAMECOUNT_MASK,d2
  491.         or.l    #FULLY_CLIPPED_CACHED,d2
  492.         move.l  d2,_cacheoffset         ;cacheoffset = FULLY...
  493.         bra.b   .exit1
  494.  
  495. *        side = ceilv0 > r_ceilv1;
  496. *
  497. *        edge = edge_p++;
  498. *
  499. *        edge->owner = r_pedge;
  500. *
  501. *        edge->nearzi = lzi0;
  502.  
  503. .cont13
  504.         move.l  _edge_p,a2
  505.         add.l   #EDGE_SIZEOF,_edge_p    ;edge = edge_p++
  506.         move.l  _r_pedge,EDGE_OWNER(a2) ;edge->owner = r_pedge
  507.         fmove.s fp2,EDGE_NEARZI(a2)     ;edge->nearzi = lzi0
  508.  
  509. *        if (side == 0)
  510. *        {
  511. *        // trailing edge (go from p1 to p2)
  512. *                v = ceilv0;
  513. *                v2 = r_ceilv1 - 1;
  514. *
  515. *                edge->surfs[0] = surface_p - surfaces;
  516. *                edge->surfs[1] = 0;
  517. *
  518. *                u_step = ((r_u1 - u0) / (r_v1 - v0));
  519. *                u = u0 + ((float)v - v0) * u_step;
  520. *        }
  521.  
  522.         cmp.l   d1,d0                   ;if (side == 0)
  523.         bgt.b   .else2
  524.         move.l  d0,d2                   ;v = ceilv0
  525.         move.l  d1,d3
  526.         subq.l  #1,d3                   ;v2 = r_ceilv1 - 1
  527.         move.l  _surface_p,d0           ;edge->surfs[0] = surface_p - surfaces
  528.         sub.l   _surfaces,d0
  529.         asr.l   #6,d0
  530.         swap    d0
  531.         clr     d0
  532.         move.l  d0,EDGE_SURFS(a2)       ;edge->surfs[1] = 0
  533.         fmove.l d2,fp3
  534.         fmove   fp0,fp2
  535.         fsub    fp1,fp3
  536.         fsub    fp7,fp0
  537.         fsub    fp6,fp1
  538.         fdiv    fp1,fp0                 ;u_step = ((r_u1-u0)/(r_v1-v0))
  539.         fmul    fp0,fp3
  540.         fadd    fp2,fp3                 ;u = u0 + ((float)v-v0)*u_step
  541.         bra.b   .cont14
  542.  
  543. *        {
  544. *        // leading edge (go from p2 to p1)
  545. *                v2 = ceilv0 - 1;
  546. *                v = r_ceilv1;
  547. *
  548. *                edge->surfs[0] = 0;
  549. *                edge->surfs[1] = surface_p - surfaces;
  550. *
  551. *                u_step = ((u0 - r_u1) / (v0 - r_v1));
  552. *                u = r_u1 + ((float)v - r_v1) * u_step;
  553. *        }
  554.  
  555. .else2
  556.         move.l  d1,d2                   ;v = r_ceilv1
  557.         move.l  d0,d3
  558.         subq.l  #1,d3                   ;v2 = ceilv0 - 1
  559.         move.l  _surface_p,d0           ;edge->surfs[0] = 0
  560.         sub.l   _surfaces,d0
  561.         asr.l   #6,d0
  562.         and.l   #$ffff,d0
  563.         move.l  d0,EDGE_SURFS(a2)       ;edge->surfs[1] = surface_p-surfaces
  564.         fmove.l d2,fp3
  565.         fsub    fp6,fp3
  566.         fsub    fp7,fp0
  567.         fsub    fp6,fp1
  568.         fdiv    fp1,fp0                 ;u_step = ((u0-r_u1)/(v0-r_v1))
  569.         fmul    fp0,fp3
  570.         fadd    fp7,fp3                 ;u = r_u1+((float)v-r_v1)*u_step
  571.  
  572. *        edge->u_step = u_step*0x100000;
  573. *        edge->u = u*0x100000 + 0xFFFFF;
  574.  
  575. .cont14
  576.         fmove.s #16*65536,fp4
  577.         fmul    fp4,fp0
  578.         fmove.l fp0,EDGE_U_STEP(a2)     ;edge->u_step = u_step*$100000
  579.         fmul    fp4,fp3
  580.         fadd.s  #(16*65536)-1,fp3       ;edge->u = u*$100000 + $fffff
  581.         fmove.l fp3,d0
  582.  
  583. *        if (edge->u < r_refdef.vrect_x_adj_shift20)
  584. *                edge->u = r_refdef.vrect_x_adj_shift20;
  585. *        if (edge->u > r_refdef.vrectright_adj_shift20)
  586. *                edge->u = r_refdef.vrectright_adj_shift20;
  587.  
  588.         move.l  REFDEF_VRECTX_ADJ_S20(a4),d4
  589.         cmp.l   d4,d0
  590.         bge.b   .cont15
  591.         move.l  d4,d0
  592. .cont15
  593.         move.l  REFDEF_VRECTXR_ADJ_S20(a4),d4
  594.         cmp.l   d4,d0
  595.         ble.b   .cont16
  596.         move.l  d4,d0
  597.  
  598. *        u_check = edge->u;
  599. *        if (edge->surfs[0])
  600. *                u_check++;      // sort trailers after leaders
  601. *
  602. *        if (!newedges[v] || newedges[v]->u >= u_check)
  603. *        {
  604. *                edge->next = newedges[v];
  605. *                newedges[v] = edge;
  606. *        }
  607. *        else
  608. *        {
  609. *                pcheck = newedges[v];
  610. *                while (pcheck->next && pcheck->next->u < u_check)
  611. *                        pcheck = pcheck->next;
  612. *                edge->next = pcheck->next;
  613. *                pcheck->next = edge;
  614. *        }
  615.  
  616. .cont16
  617.         move.l  d0,EDGE_U(a2)
  618.         tst     EDGE_SURFS(a2)          ;if (edge->surfs[0])
  619.         beq.b   .cont17
  620.         addq.l  #1,d0                   ;u_check++
  621. .cont17
  622.         lea     _newedges,a0            ;if (!newedges[v] || ...
  623.         move.l  0(a0,d2.l*4),d4
  624.         beq.b   .cont18
  625.         move.l  d4,a1
  626.         cmp.l   EDGE_U(a1),d0
  627.         bgt.b   .cont19
  628. .cont18
  629.         move.l  d4,EDGE_NEXT(a2)        ;edge->next = newedges[v]
  630.         move.l  a2,0(a0,d2.l*4)         ;newedges[v] = edge
  631.         bra.b   .cont21
  632. .cont19
  633.         move.l  d4,a1                   ;pcheck = newedges[v]
  634. .loop
  635.         move.l  EDGE_NEXT(a1),d4        ;while (pcheck->next &&...
  636.         beq.b   .cont20
  637.         move.l  a1,d2
  638.         move.l  d4,a1                   ;pcheck = pcheck->next
  639.         cmp.l   EDGE_U(a1),d0
  640.         bgt.b   .loop
  641.         move.l  d2,a1
  642. .cont20
  643.         move.l  d4,EDGE_NEXT(a2)        ;edge->next = pcheck->next
  644.         move.l  a2,EDGE_NEXT(a1)        ;pcheck->next = edge
  645.  
  646. *        edge->nextremove = removeedges[v2];
  647. *        removeedges[v2] = edge;
  648.  
  649. .cont21
  650.         lea     _removeedges,a0
  651.         move.l  0(a0,d3.l*4),EDGE_NEXTREMOVE(a2)
  652.         move.l  a2,0(a0,d3.l*4)
  653. .exit1
  654.         move.l  d1,_r_ceilv1
  655. .exit2
  656.         fmove.s fp5,_r_lzi1
  657.         fmove.s fp7,_r_u1
  658.         fmove.s fp6,_r_v1
  659.         fmovem.x        (sp)+,fp2-fp7
  660.         movem.l (sp)+,d2-d5/a2-a4
  661.         rts
  662.  
  663.  
  664. ******************************************************************************
  665. *
  666. *       void _R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
  667. *
  668. ******************************************************************************
  669.  
  670.         cnop    0,4
  671. _R_ClipEdge
  672.  
  673.         rsreset
  674. .fpuregs        rs.x    6
  675. .intregs        rs.l    2
  676.         rs.l    1
  677. .pv0            rs.l    1
  678. .pv1            rs.l    1
  679. .cp             rs.l    1
  680.  
  681.         movem.l a2/a3,-(sp)
  682.         fmovem.x        fp2-fp7,-(sp)
  683.         move.l  .pv0(sp),a0
  684.         move.l  .pv1(sp),a1
  685.         move.l  .cp(sp),a2
  686.         bsr     DoRecursion
  687.         fmovem.x        (sp)+,fp2-fp7
  688.         movem.l (sp)+,a2/a3
  689.         rts
  690.  
  691. DoRecursion
  692.         lea     -CLIP_SIZEOF(sp),sp
  693.         move.l  sp,a3
  694.         tst.l   a2
  695.         beq.w   .add
  696. .loop
  697.  
  698. *                        d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
  699. *                        d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
  700.  
  701.         fmove.s CLIP_NORMAL(a2),fp0
  702.         fmove.s CLIP_NORMAL+4(a2),fp1
  703.         fmove.s CLIP_NORMAL+8(a2),fp2
  704.         fmove.s (a0),fp3
  705.         fmove   fp3,fp5                 ;fp5 = pv0->position[0]
  706.         fmul    fp0,fp3
  707.         fmove.s 4(a0),fp4
  708.         fmove   fp4,fp6                 ;fp6 = pv0->position[1]
  709.         fmul    fp1,fp4
  710.         fadd    fp4,fp3
  711.         fmove.s 8(a0),fp4
  712.         fmove   fp4,fp7                 ;fp7 = pv0->position[2]
  713.         fmul    fp2,fp4
  714.         fadd    fp4,fp3
  715.         fmove.s (a1),fp4                ;fp4 = pv1->position[0]
  716.         fmul    fp4,fp0
  717.         fmul.s  4(a1),fp1
  718.         fadd    fp1,fp0
  719.         fmove.s 8(a1),fp1               ;fp1 = pv1->position[2]
  720.         fmul    fp1,fp2
  721.         fadd    fp2,fp0
  722.         fmove.s CLIP_DIST(a2),fp2
  723.         fsub    fp2,fp3                 ;fp3 = d0
  724.         fsub    fp2,fp0                 ;fp0 = d1
  725.         fmove.s 4(a1),fp2               ;fp2 = pv1->position[1]
  726.  
  727. *                        if (d0 >= 0)
  728. *                        {
  729. *                        // point 0 is unclipped
  730. *                                if (d1 >= 0)
  731. *                                {
  732. *                                // both points are unclipped
  733. *                                        continue;
  734. *                                }
  735.  
  736.         ftst    fp3
  737.         fbolt   .less
  738.         ftst    fp0
  739.         fboge   .loopend
  740.  
  741. *                                cacheoffset = 0x7FFFFFFF;
  742. *
  743. *                                f = d0 / (d0 - d1);
  744. *                                clipvert.position[0] = pv0->position[0] +
  745. *                                                f * (pv1->position[0] - pv0->position[0]);
  746. *                                clipvert.position[1] = pv0->position[1] +
  747. *                                                f * (pv1->position[1] - pv0->position[1]);
  748. *                                clipvert.position[2] = pv0->position[2] +
  749. *                                                f * (pv1->position[2] - pv0->position[2]);
  750.  
  751.         move.l  #$7fffffff,_cacheoffset
  752.         fsub    fp3,fp0
  753.         fdiv    fp0,fp3
  754.         fneg    fp3                     ;fp3 = f
  755.         fsub    fp5,fp4
  756.         fmul    fp3,fp4
  757.         fadd    fp5,fp4
  758.         fmove.s fp4,(a3)                ;clipvert.position[0]
  759.         fsub    fp6,fp2
  760.         fmul    fp3,fp2
  761.         fadd    fp6,fp2
  762.         fmove.s fp2,4(a3)               ;clipvert.position[1]
  763.         fsub    fp7,fp1
  764.         fmul    fp3,fp1
  765.         fadd    fp7,fp1
  766.         fmove.s fp1,8(a3)               ;clipvert.position[2]
  767.  
  768. *                                if (clip->leftedge)
  769. *                                {
  770. *                                        r_leftclipped = true;
  771. *                                        r_leftexit = clipvert;
  772. *                                }
  773.  
  774.         tst.b   CLIP_LEFTEDGE(a2)
  775.         beq.b   .else
  776.         move.l  #1,_r_leftclipped
  777.         lea     _r_leftexit,a1
  778.         move.l  (a3)+,(a1)+
  779.         move.l  (a3)+,(a1)+
  780.         move.l  (a3)+,(a1)+
  781.         bra.b   .cont
  782.  
  783. *                                else if (clip->rightedge)
  784. *                                {
  785. *                                        r_rightclipped = true;
  786. *                                        r_rightexit = clipvert;
  787. *                                }
  788.  
  789. .else
  790.         move.l  #1,_r_rightclipped
  791.         lea     _r_rightexit,a1
  792.         move.l  (a3)+,(a1)+
  793.         move.l  (a3)+,(a1)+
  794.         move.l  (a3)+,(a1)+
  795.  
  796. *                                R_ClipEdge (pv0, &clipvert, clip->next);
  797. *                                return;
  798.  
  799. .cont
  800.         sub     #12,a3
  801.         move.l  a3,a1
  802.         move.l  CLIP_NEXT(a2),a2
  803.         bsr     DoRecursion
  804.         bra.w   .exit
  805.  
  806. *                                if (d1 < 0)
  807. *                                {
  808. *                                // both points are clipped
  809. *                                // we do cache fully clipped edges
  810. *                                        if (!r_leftclipped)
  811. *                                                cacheoffset = FULLY_CLIPPED_CACHED |
  812. *                                                                (r_framecount & FRAMECOUNT_MASK);
  813. *                                        return;
  814. *                                }
  815.  
  816. .less
  817.         ftst    fp0
  818.         fboge.b .cont2
  819.         tst.l   _r_leftclipped
  820.         bne.w   .exit
  821.         move.l  _r_framecount,d0
  822.         and.l   #FRAMECOUNT_MASK,d0
  823.         or.l    #FULLY_CLIPPED_CACHED,d0
  824.         move.l  d0,_cacheoffset
  825.         bra.w   .exit
  826.  
  827. *                                r_lastvertvalid = false;
  828. *
  829. *                        // we don't cache partially clipped edges
  830. *                                cacheoffset = 0x7FFFFFFF;
  831. *
  832. *                                f = d0 / (d0 - d1);
  833. *                                clipvert.position[0] = pv0->position[0] +
  834. *                                                f * (pv1->position[0] - pv0->position[0]);
  835. *                                clipvert.position[1] = pv0->position[1] +
  836. *                                                f * (pv1->position[1] - pv0->position[1]);
  837. *                                clipvert.position[2] = pv0->position[2] +
  838. *                                                f * (pv1->position[2] - pv0->position[2]);
  839.  
  840. .cont2
  841.         clr.l   _r_lastvertvalid
  842.         move.l  #$7fffffff,_cacheoffset
  843.         fsub    fp3,fp0
  844.         fdiv    fp0,fp3
  845.         fneg    fp3                     ;fp3 = f
  846.         fsub    fp5,fp4
  847.         fmul    fp3,fp4
  848.         fadd    fp5,fp4
  849.         fmove.s fp4,(a3)                ;clipvert.position[0]
  850.         fsub    fp6,fp2
  851.         fmul    fp3,fp2
  852.         fadd    fp6,fp2
  853.         fmove.s fp2,4(a3)               ;clipvert.position[1]
  854.         fsub    fp7,fp1
  855.         fmul    fp3,fp1
  856.         fadd    fp7,fp1
  857.         fmove.s fp1,8(a3)               ;clipvert.position[2]
  858.  
  859. *                                if (clip->leftedge)
  860. *                                {
  861. *                                        r_leftclipped = true;
  862. *                                        r_leftenter = clipvert;
  863. *                                }
  864.  
  865.         tst.b   CLIP_LEFTEDGE(a2)
  866.         beq.b   .else2
  867.         move.l  #1,_r_leftclipped
  868.         lea     _r_leftenter,a0
  869.         move.l  (a3)+,(a0)+
  870.         move.l  (a3)+,(a0)+
  871.         move.l  (a3)+,(a0)+
  872.         bra.b   .cont3
  873.  
  874. *                                else if (clip->rightedge)
  875. *                                {
  876. *                                        r_rightclipped = true;
  877. *                                        r_rightenter = clipvert;
  878. *                                }
  879.  
  880. .else2
  881.         move.l  #1,_r_rightclipped
  882.         lea     _r_rightenter,a0
  883.         move.l  (a3)+,(a0)+
  884.         move.l  (a3)+,(a0)+
  885.         move.l  (a3)+,(a0)+
  886.  
  887. *                                R_ClipEdge (&clipvert, pv1, clip->next);
  888. *                                return;
  889.  
  890. .cont3
  891.         sub     #12,a3
  892.         move.l  a3,a0
  893.         move.l  CLIP_NEXT(a2),a2
  894.         bsr     DoRecursion
  895.         bra.w   .exit
  896.  
  897. *                } while ((clip = clip->next) != NULL);
  898.  
  899. .loopend
  900.         move.l  CLIP_NEXT(a2),d0
  901.         beq.b   .add
  902.         move.l  d0,a2
  903.         bra.w   .loop
  904.  
  905. *        R_EmitEdge (pv0, pv1);
  906.  
  907. .add
  908.         move.l  a1,-(sp)
  909.         move.l  a0,-(sp)
  910.         bsr     _R_EmitEdge
  911.         addq    #8,sp
  912. .exit
  913.         lea     CLIP_SIZEOF(sp),sp
  914.         rts
  915.  
  916.  
  917.  
  918.  
  919. ******************************************************************************
  920. *
  921. *       void _R_RenderFace (msurface_t *fa, int clipflags)
  922. *
  923. ******************************************************************************
  924.  
  925.         cnop    0,4
  926. _R_RenderFace
  927.  
  928.  
  929.         rsreset
  930. .fpuregs        rs.x    5
  931. .intregs        rs.l    11
  932.         rs.l    1
  933. .fa             rs.l    1
  934. .clipflags      rs.l    1
  935.  
  936.  
  937.         movem.l d2-d7/a2-a6,-(sp)
  938.         fmovem.x        fp2-fp6,-(sp)
  939.         move.l  .fa(sp),a3
  940.         move.l  .clipflags(sp),d0
  941.  
  942. *// skip out if no more surfs
  943. *        if ((surface_p) >= surf_max)
  944. *        {
  945. *                r_outofsurfaces++;
  946. *                return;
  947. *        }
  948.  
  949.         move.l  _surface_p,a2
  950.         cmp.l   _surf_max,a2            ;if ((surface_p) >= surf_max)
  951.         blo.b   .cont
  952.         addq.l  #1,_r_outofsurfaces     ;r_outofsurfaces++
  953.         bra.w   .end                    ;return
  954.  
  955. *        if ((edge_p + fa->numedges + 4) >= edge_max)
  956. *        {
  957. *                r_outofedges += fa->numedges;
  958. *                return;
  959. *        }
  960. *
  961. *        c_faceclip++;
  962.  
  963. .cont
  964.         move.l  MSURFACE_NUMEDGES(a3),d1
  965.         move.l  d1,d2
  966.         asl.l   #EDGE_SIZEOF_EXP,d1
  967.         add.l   #4*EDGE_SIZEOF,d1
  968.         move.l  _edge_p,d6
  969.         add.l   d6,d1                   ;edge_p + fa->numedges + 4
  970.         cmp.l   _edge_max,d1            ;if d1 >= edge_max
  971.         blo.b   .cont2
  972.         add.l   d2,_r_outofedges        ;r_outofedges += fa->numedges
  973.         bra.w   .end                    ;return
  974. .cont2
  975.         addq.l  #1,_c_faceclip          ;c_faceclip++
  976.  
  977. *        pclip = NULL;
  978. *
  979. *        for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
  980. *        {
  981. *                if (clipflags & mask)
  982. *                {
  983. *                        view_clipplanes[i].next = pclip;
  984. *                        pclip = &view_clipplanes[i];
  985. *                }
  986. *        }
  987.  
  988.         sub.l   a0,a0                   ;pclip = NULL
  989.         lea     _view_clipplanes,a1
  990.         lsl.b   #4,d0
  991.         lsl.b   #1,d0                   ;if (clipflags & mask)
  992.         bcc.b   .nocarry1
  993.         move.l  a0,CLIP_NEXT+3*CLIP_SIZEOF(a1)
  994.         lea     3*CLIP_SIZEOF(a1),a0
  995. .nocarry1
  996.         lsl.b   #1,d0
  997.         bcc.b   .nocarry2
  998.         move.l  a0,CLIP_NEXT+2*CLIP_SIZEOF(a1)
  999.         lea     2*CLIP_SIZEOF(a1),a0
  1000. .nocarry2
  1001.         lsl.b   #1,d0
  1002.         bcc.b   .nocarry3
  1003.         move.l  a0,CLIP_NEXT+1*CLIP_SIZEOF(a1)
  1004.         lea     1*CLIP_SIZEOF(a1),a0
  1005. .nocarry3
  1006.         lsl.b   #1,d0
  1007.         bcc.b   .nocarry4
  1008.         move.l  a0,CLIP_NEXT(a1)        ;view_clipplanes[0].next=pclip
  1009.         move.l  a1,a0                   ;pclip = &view_clipplanes[i]
  1010. .nocarry4
  1011.         move.l  a0,a2
  1012.  
  1013. *        r_emitted = 0;
  1014. *        r_nearzi = 0;
  1015. *        r_nearzionly = false;
  1016. *        makeleftedge = makerightedge = false;
  1017. *        pedges = currententity->model->edges;
  1018. *        r_lastvertvalid = false;
  1019.  
  1020.         clr.l   _r_emitted
  1021.         clr.l   _r_nearzi
  1022.         clr.l   _r_nearzionly
  1023.         clr.l   _makeleftedge
  1024.         clr.l   _makerightedge
  1025.         move.l  _currententity,a0
  1026.         move.l  ENTITY_MODEL(a0),a6
  1027.         move.l  MODEL_EDGES(a6),d4      ;pedges = currententity->mod...
  1028.         clr.l   _r_lastvertvalid
  1029.         move.l  _r_edges,d5
  1030.         move.l  _r_pcurrentvertbase,a4
  1031.         move.l  _surface_p,d7
  1032.         sub.l   _surfaces,d7
  1033.         asr.l   #6,d7
  1034.         subq    #1,d2
  1035.         bmi.w   .noloop
  1036.         moveq   #0,d3
  1037.  
  1038. *        for (i=0 ; i<fa->numedges ; i++)
  1039. *        {
  1040. *                lindex = currententity->model->surfedges[fa->firstedge + i];
  1041.  
  1042. .loop
  1043.         move.l  MODEL_SURFEDGES(a6),a1  ;¤tentity->model->surfedges
  1044.         move.l  MSURFACE_FIRSTEDGE(a3),d0
  1045.         add.l   d3,d0                   ;fa->firstedge + i
  1046.         move.l  0(a1,d0.l*4),d0         ;lindex = currententity->model...
  1047.  
  1048. *                if (lindex > 0)
  1049.  
  1050.         ble.b   .cont3                  ;if (lindex > 0)
  1051.  
  1052. *                        r_pedge = &pedges[lindex];
  1053. *
  1054. *                // if the edge is cached, we can just reuse the edge
  1055. *                        if (!insubmodel)
  1056.  
  1057.         asl.l   #MEDGE_SIZEOF_EXP,d0
  1058.         add.l   d4,d0
  1059.         move.l  d0,a5
  1060.         move.l  a5,_r_pedge             ;r_pedge = &pedges[lindex]
  1061.         tst.l   _insubmodel             ;if (!insubmodel)
  1062.         bne.b   .nosub
  1063.  
  1064. *                                if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
  1065. *                                {
  1066. *                                        if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
  1067. *                                                r_framecount)
  1068. *                                        {
  1069. *                                                r_lastvertvalid = false;
  1070. *                                                continue;
  1071. *                                        }
  1072. *                                }
  1073.  
  1074.         move.l  MEDGE_CEO(a5),d0        ;if (r_pedge->cache... & FULLY...)
  1075.         move.l  d0,d1
  1076.         and.l   #FULLY_CLIPPED_CACHED,d0
  1077.         beq.b   .else
  1078.         and.l   #FRAMECOUNT_MASK,d1     ;if ((r_pedge->cache... & FRA...)
  1079.         cmp.l   _r_framecount,d1
  1080.         bne.b   .nosub
  1081.         clr.l   _r_lastvertvalid        ;r_lastvertvalid = false
  1082.         bra.w   .loopend
  1083.  
  1084. *                                        if ((((unsigned long)edge_p - (unsigned long)r_edges) >
  1085. *                                                 r_pedge->cachededgeoffset) &&
  1086. *                                                (((edge_t *)((unsigned long)r_edges +
  1087. *                                                 r_pedge->cachededgeoffset))->owner == r_pedge))
  1088. *                                        {
  1089. *                                                R_EmitCachedEdge ();
  1090. *                                                r_lastvertvalid = false;
  1091. *                                                continue;
  1092. *                                        }
  1093.  
  1094. .else
  1095.         move.l  d6,d0
  1096.         sub.l   d5,d0
  1097.         cmp.l   d1,d0
  1098.         bls.b   .nosub
  1099.         move.l  d1,a0
  1100.         add.l   d5,a0
  1101.         cmp.l   EDGE_OWNER(a0),a5
  1102.         bne.b   .nosub
  1103.  
  1104.  
  1105. ******  EmitCachedEdge (inlined)
  1106.  
  1107. *        pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset);
  1108. *
  1109. *        if (!pedge_t->surfs[0])
  1110. *                pedge_t->surfs[0] = surface_p - surfaces;
  1111. *        else
  1112. *                pedge_t->surfs[1] = surface_p - surfaces;
  1113. *
  1114. *        if (pedge_t->nearzi > r_nearzi) // for mipmap finding
  1115. *                r_nearzi = pedge_t->nearzi;
  1116. *
  1117. *        r_emitted = 1;
  1118.  
  1119.         tst     EDGE_SURFS(a0)
  1120.         bne.b   .contE
  1121.         move    d7,EDGE_SURFS(a0)
  1122.         bra.b   .cont2E
  1123. .contE
  1124.         move    d7,EDGE_SURFS+1*2(a0)
  1125. .cont2E
  1126.         fmove.s EDGE_NEARZI(a0),fp0
  1127.         fcmp.s  _r_nearzi,fp0
  1128.         fbole.b .cont3E
  1129.         move.l  EDGE_NEARZI(a0),_r_nearzi
  1130. .cont3E
  1131.         move.l  #1,_r_emitted
  1132.  
  1133. ******  End of EmitCachedEdge
  1134.  
  1135.  
  1136.         clr.l   _r_lastvertvalid
  1137.         bra.w   .loopend
  1138.  
  1139. *                        cacheoffset = (byte *)edge_p - (byte *)r_edges;
  1140. *                        r_leftclipped = r_rightclipped = false;
  1141. *                        R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]],
  1142. *                                                &r_pcurrentvertbase[r_pedge->v[1]],
  1143. *                                                pclip);
  1144. *                        r_pedge->cachededgeoffset = cacheoffset;
  1145. *
  1146. *                        if (r_leftclipped)
  1147. *                                makeleftedge = true;
  1148. *                        if (r_rightclipped)
  1149. *                                makerightedge = true;
  1150. *                        r_lastvertvalid = true;
  1151.  
  1152. .nosub
  1153.         move.l  d6,d0
  1154.         sub.l   d5,d0
  1155.         move.l  d0,_cacheoffset         ;cacheoffset = (byte*)edge_p...
  1156.         clr.l   _r_leftclipped
  1157.         clr.l   _r_rightclipped
  1158.         move.l  a2,-(sp)
  1159.         move    MEDGE_V+1*2(a5),d0
  1160.         muls    #MVERTEX_SIZEOF,d0
  1161.         pea     0(a4,d0.l)
  1162.         move    MEDGE_V+0*2(a5),d0
  1163.         muls    #MVERTEX_SIZEOF,d0
  1164.         pea     0(a4,d0.l)
  1165.         jsr     _R_ClipEdge             ;R_ClipEdge (&r_pcu...
  1166.         add     #12,sp
  1167.         move.l  _edge_p,d6
  1168.         move.l  _cacheoffset,MEDGE_CEO(a5) ;r_pedge->cache... = cacheoffset
  1169.         tst.l   _r_leftclipped          ;if (r_leftclipped)
  1170.         beq.b   .noLC
  1171.         move.l  #1,_makeleftedge        ;makeleftedge = true
  1172. .noLC
  1173.         tst.l   _r_rightclipped         ;if (r_rightclipped)
  1174.         beq.b   .noRC
  1175.         move.l  #1,_makerightedge       ;makerightedge = true
  1176. .noRC
  1177.         move.l  #1,_r_lastvertvalid     ;r_lastvertvalid = true
  1178.         bra.b   .loopend
  1179. .cont3
  1180.         neg.l   d0                      ;lindex = -lindex
  1181.  
  1182. *                        r_pedge = &pedges[lindex];
  1183. *
  1184. *                // if the edge is cached, we can just reuse the edge
  1185. *                        if (!insubmodel)
  1186.  
  1187.         asl.l   #MEDGE_SIZEOF_EXP,d0
  1188.         add.l   d4,d0
  1189.         move.l  d0,a5
  1190.         move.l  a5,_r_pedge             ;r_pedge = &pedges[lindex]
  1191.         tst.l   _insubmodel             ;if (!insubmodel)
  1192.         bne.b   .nosub2
  1193.  
  1194. *                                if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
  1195. *                                {
  1196. *                                        if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
  1197. *                                                r_framecount)
  1198. *                                        {
  1199. *                                                r_lastvertvalid = false;
  1200. *                                                continue;
  1201. *                                        }
  1202. *                                }
  1203.  
  1204.         move.l  MEDGE_CEO(a5),d0        ;if (r_pedge->cache... & FULLY...)
  1205.         move.l  d0,d1
  1206.         and.l   #FULLY_CLIPPED_CACHED,d0
  1207.         beq.b   .else2
  1208.         and.l   #FRAMECOUNT_MASK,d1     ;if ((r_pedge->cache... & FRA...)
  1209.         cmp.l   _r_framecount,d1
  1210.         bne.b   .nosub2
  1211.         clr.l   _r_lastvertvalid        ;r_lastvertvalid = false
  1212.         bra.w   .loopend
  1213.  
  1214. *                                        if ((((unsigned long)edge_p - (unsigned long)r_edges) >
  1215. *                                                 r_pedge->cachededgeoffset) &&
  1216. *                                                (((edge_t *)((unsigned long)r_edges +
  1217. *                                                 r_pedge->cachededgeoffset))->owner == r_pedge))
  1218. *                                        {
  1219. *                                                R_EmitCachedEdge ();
  1220. *                                                r_lastvertvalid = false;
  1221. *                                                continue;
  1222. *                                        }
  1223.  
  1224. .else2
  1225.         move.l  d6,d0
  1226.         sub.l   d5,d0
  1227.         cmp.l   d1,d0
  1228.         bls.b   .nosub2
  1229.         move.l  d1,a0
  1230.         add.l   d5,a0
  1231.         cmp.l   EDGE_OWNER(a0),a5
  1232.         bne.b   .nosub2
  1233.  
  1234.  
  1235. ******  EmitCachedEdge (inlined)
  1236.  
  1237. *        pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset);
  1238. *
  1239. *        if (!pedge_t->surfs[0])
  1240. *                pedge_t->surfs[0] = surface_p - surfaces;
  1241. *        else
  1242. *                pedge_t->surfs[1] = surface_p - surfaces;
  1243. *
  1244. *        if (pedge_t->nearzi > r_nearzi) // for mipmap finding
  1245. *                r_nearzi = pedge_t->nearzi;
  1246. *
  1247. *        r_emitted = 1;
  1248.  
  1249.         tst     EDGE_SURFS(a0)
  1250.         bne.b   .contE2
  1251.         move    d7,EDGE_SURFS(a0)
  1252.         bra.b   .cont2E2
  1253. .contE2
  1254.         move    d7,EDGE_SURFS+1*2(a0)
  1255. .cont2E2
  1256.         fmove.s EDGE_NEARZI(a0),fp0
  1257.         fcmp.s  _r_nearzi,fp0
  1258.         fbole.b .cont3E2
  1259.         move.l  EDGE_NEARZI(a0),_r_nearzi
  1260. .cont3E2
  1261.         move.l  #1,_r_emitted
  1262.  
  1263. ******  End of EmitCachedEdge
  1264.  
  1265.         clr.l   _r_lastvertvalid
  1266.         bra.w   .loopend
  1267.  
  1268. *                        cacheoffset = (byte *)edge_p - (byte *)r_edges;
  1269. *                        r_leftclipped = r_rightclipped = false;
  1270. *                        R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]],
  1271. *                                                &r_pcurrentvertbase[r_pedge->v[1]],
  1272. *                                                pclip);
  1273. *                        r_pedge->cachededgeoffset = cacheoffset;
  1274. *
  1275. *                        if (r_leftclipped)
  1276. *                                makeleftedge = true;
  1277. *                        if (r_rightclipped)
  1278. *                                makerightedge = true;
  1279. *                        r_lastvertvalid = true;
  1280.  
  1281. .nosub2
  1282.         move.l  d6,d0
  1283.         sub.l   d5,d0
  1284.         move.l  d0,_cacheoffset         ;cacheoffset = (byte*)edge_p...
  1285.         clr.l   _r_leftclipped
  1286.         clr.l   _r_rightclipped
  1287.         move.l  a2,-(sp)
  1288.         move    MEDGE_V+0*2(a5),d0
  1289.         muls    #MVERTEX_SIZEOF,d0
  1290.         pea     0(a4,d0.l)
  1291.         move    MEDGE_V+1*2(a5),d0
  1292.         muls    #MVERTEX_SIZEOF,d0
  1293.         pea     0(a4,d0.l)
  1294.         jsr     _R_ClipEdge             ;R_ClipEdge (&r_pcu...
  1295.         add     #12,sp
  1296.         move.l  _edge_p,d6
  1297.         move.l  _cacheoffset,MEDGE_CEO(a5) ;r_pedge->cache... = cacheoffset
  1298.         tst.l   _r_leftclipped          ;if (r_leftclipped)
  1299.         beq.b   .noLC2
  1300.         move.l  #1,_makeleftedge        ;makeleftedge = true
  1301. .noLC2
  1302.         tst.l   _r_rightclipped         ;if (r_rightclipped)
  1303.         beq.b   .noRC2
  1304.         move.l  #1,_makerightedge       ;makerightedge = true
  1305. .noRC2
  1306.         move.l  #1,_r_lastvertvalid     ;r_lastvertvalid = true
  1307. .loopend
  1308.         addq    #1,d3
  1309.         dbra    d2,.loop
  1310.  
  1311. *        if (makeleftedge)
  1312. *        {
  1313. *                r_pedge = &tedge;
  1314. *                r_lastvertvalid = false;
  1315. *                R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
  1316. *        }
  1317.  
  1318. .noloop
  1319.         tst.l   _makeleftedge           ;if (makeleftedge)
  1320.         beq.b   .noLE
  1321.         clr.l   _r_lastvertvalid        ;r_lastvertvalid = false
  1322.         move.l  a2,a0
  1323.         move.l  CLIP_NEXT(a0),-(sp)
  1324.         move.l  #_r_leftenter,-(sp)
  1325.         move.l  #_r_leftexit,-(sp)
  1326.         jsr     _R_ClipEdge             ;R_ClipEdge (&r_leftexit,...)
  1327.         add     #12,sp
  1328.  
  1329. *        if (makerightedge)
  1330. *        {
  1331. *                r_pedge = &tedge;
  1332. *                r_lastvertvalid = false;
  1333. *                r_nearzionly = true;
  1334. *                R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
  1335. *        }
  1336.  
  1337. .noLE
  1338.         tst.l   _makerightedge          ;if (makerightedge)
  1339.         beq.b   .noRE
  1340.         clr.l   _r_lastvertvalid        ;r_lastvertvalid = false
  1341.         move.l  #1,_r_nearzionly        ;r_nearzionly = true
  1342.         lea     _view_clipplanes,a0
  1343.         move.l  CLIP_NEXT+1*CLIP_SIZEOF(a0),-(sp)
  1344.         move.l  #_r_rightenter,-(sp)
  1345.         move.l  #_r_rightexit,-(sp)
  1346.         jsr     _R_ClipEdge             ;R_ClipEdge (&r_rightexit...)
  1347.         add     #12,sp
  1348.  
  1349. *        if (!r_emitted)
  1350. *                return;
  1351.  
  1352. .noRE
  1353.         tst.l   _r_emitted              ;if (!r_emitted)
  1354.         beq.w   .end                    ;return
  1355.  
  1356. *        r_polycount++;
  1357. *
  1358. *        surface_p->data = (void *)fa;
  1359. *        surface_p->nearzi = r_nearzi;
  1360. *        surface_p->flags = fa->flags;
  1361. *        surface_p->insubmodel = insubmodel;
  1362. *        surface_p->spanstate = 0;
  1363. *        surface_p->entity = currententity;
  1364. *        surface_p->key = r_currentkey++;
  1365. *        surface_p->spans = NULL;
  1366.  
  1367.         move.l  _r_currentkey,d0        ;r_currentkey++
  1368.         addq.l  #1,_r_currentkey
  1369.         addq.l  #1,_r_polycount         ;r_polycount++
  1370.         move.l  _surface_p,a0
  1371.         addq.l  #8,a0
  1372.         clr.l   (a0)+                   ;surface_p->spans = NULL
  1373.         move.l  d0,(a0)+                ;surface_p->key = r_currentkey++
  1374.         addq.l  #4,a0
  1375.         clr.l   (a0)+                   ;surface_p->spanstate = 0
  1376.         move.l  MSURFACE_FLAGS(a3),(a0)+ ;surface_p->flags = fa->flags
  1377.         move.l  a3,(a0)+                ;surface_p->data = (void *)fa
  1378.         move.l  _currententity,(a0)+    ;surface_p->entity = currententity
  1379.         move.l  _r_nearzi,(a0)+         ;surface_p->nearzi = r_nearzi
  1380.         move.l  _insubmodel,(a0)+       ;surface_p->insubmodel = insubmodel
  1381.  
  1382. *        pplane = fa->plane;
  1383.  
  1384.         move.l  MSURFACE_PLANE(a3),a1   ;pplane = fa->plane
  1385.  
  1386. *        TransformVector (pplane->normal, p_normal);
  1387.  
  1388. ******  TransformVector (inlined)
  1389.  
  1390.         fmove.s (a1)+,fp3
  1391.         fmove.s (a1)+,fp4
  1392.         fmove.s (a1)+,fp5
  1393.         lea     _vright,a2
  1394.         fmove.s (a2)+,fp0
  1395.         fmul    fp3,fp0
  1396.         fmove.s (a2)+,fp1
  1397.         fmul    fp4,fp1
  1398.         fadd    fp1,fp0
  1399.         fmove.s (a2)+,fp1
  1400.         fmul    fp5,fp1
  1401.         fadd    fp1,fp0                 ;fp0 = p_normal[0]
  1402.         lea     _vup,a2
  1403.         fmove.s (a2)+,fp1
  1404.         fmul    fp3,fp1
  1405.         fmove.s (a2)+,fp2
  1406.         fmul    fp4,fp2
  1407.         fadd    fp2,fp1
  1408.         fmove.s (a2)+,fp2
  1409.         fmul    fp5,fp2
  1410.         fadd    fp2,fp1
  1411.         fneg    fp1                     ;fp1 = -p_normal[1]
  1412.         lea     _vpn,a2
  1413.         fmove.s (a2)+,fp2
  1414.         fmul    fp3,fp2
  1415.         fmove.s (a2)+,fp6
  1416.         fmul    fp4,fp6
  1417.         fadd    fp6,fp2
  1418.         fmove.s (a2)+,fp6
  1419.         fmul    fp5,fp6
  1420.         fadd    fp6,fp2                 ;fp2 = p_normal[2]
  1421.  
  1422. ******  End of TransformVector
  1423.  
  1424. *        distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
  1425. *
  1426. *        surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
  1427. *        surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
  1428. *        surface_p->d_ziorigin = p_normal[2] * distinv -
  1429. *                        xcenter * surface_p->d_zistepu -
  1430. *                        ycenter * surface_p->d_zistepv;
  1431.  
  1432.         lea     _modelorg,a2            ;DotProduct (modelorg, pp...)
  1433.         fmul.s  (a2)+,fp3
  1434.         fmul.s  (a2)+,fp4
  1435.         fadd    fp4,fp3
  1436.         fmul.s  (a2)+,fp5
  1437.         fadd    fp5,fp3
  1438.         fsub.s  (a1)+,fp3
  1439.         fneg    fp3                     ;pplane->dist - DotProduct(...)
  1440.         fmove.s #1,fp5
  1441.         fdiv    fp3,fp5                 ;distinv = 1.0 / fp3
  1442.         fmove.s _xscaleinv,fp3
  1443.         fmul    fp5,fp3                 ;xscaleinv * distinv
  1444.         fmul    fp3,fp0                 ;p_normal[0] * fp3
  1445.         addq.l  #4,a0
  1446.         fmove.s fp0,(a0)+               ;surface_p->d_zistepu = fp0
  1447.         fmove.s _yscaleinv,fp4
  1448.         fmul    fp5,fp4                 ;yscaleinv * distinv
  1449.         fmul    fp4,fp1                 ;-p_normal[1] * fp4
  1450.         fmove.s fp1,(a0)+               ;surface_p->d_zistepv * fp1
  1451.         fmul.s  _xcenter,fp0            ;xcenter * fp0
  1452.         fmul.s  _ycenter,fp1            ;ycenter * fp1
  1453.         fmul    fp5,fp2                 ;p_normal[2] * distinv
  1454.         fsub    fp0,fp2                 ;- xcenter * fp0
  1455.         fsub    fp1,fp2                 ;- ycenter * fp1
  1456.         fmove.s fp2,-12(a0)             ;surface_p->d_ziorigin = fp2
  1457.  
  1458. *        surface_p++;
  1459.  
  1460.         add.l   #SURF_SIZEOF,_surface_p ;surface_p++
  1461. .end
  1462.         fmovem.x        (sp)+,fp2-fp6
  1463.         movem.l (sp)+,d2-d7/a2-a6
  1464.         rts
  1465.