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