home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / r_edge68k.s < prev    next >
Text File  |  2000-06-17  |  22KB  |  673 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_edge.c assembler implementations by Frank Wille <frank@phoenix.owl.de>
  17. **
  18.  
  19.         XREF    _r_bmodelactive
  20.         XREF    _surfaces
  21.         XREF    _span_p
  22.         XREF    _current_iv
  23.         XREF    _fv
  24.         XREF    _edge_head
  25.         XREF    _edge_tail
  26.         XREF    _edge_aftertail
  27.         XREF    _edge_head_u_shift20
  28.         XREF    _R_CleanupSpan
  29.  
  30.         XDEF    _R_RemoveEdges
  31.         XDEF    _R_InsertNewEdges
  32.         XDEF    _R_StepActiveU
  33.         XDEF    _R_GenerateSpans
  34.  
  35. SURF_NEXT               =       0
  36. SURF_PREV               =       4
  37. SURF_SPANS              =       8
  38. SURF_KEY                =       12
  39. SURF_LAST_U             =       16
  40. SURF_SPANSTATE          =       20
  41. SURF_INSUBMODEL         =       40
  42. SURF_D_ZIORIGIN         =       44
  43. SURF_D_ZISTEPU          =       48
  44. SURF_D_ZISTEPV          =       52
  45. SURF_SIZEOF_EXP         =       6
  46. SURF_SIZEOF             =       (1<<SURF_SIZEOF_EXP)
  47. SPAN_U                  =       0
  48. SPAN_V                  =       4
  49. SPAN_COUNT              =       8
  50. SPAN_PNEXT              =       12
  51. SPAN_SIZEOF             =       16
  52. EDGE_U                  =       0
  53. EDGE_U_STEP             =       4
  54. EDGE_PREV               =       8
  55. EDGE_NEXT               =       12
  56. EDGE_SURFS              =       16
  57. EDGE_NEXTREMOVE         =       20
  58.  
  59.         fpu
  60.  
  61. ******************************************************************************
  62. *
  63. *       void _R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist)
  64. *
  65. ******************************************************************************
  66.  
  67.         cnop    0,4
  68. _R_InsertNewEdges
  69.  
  70. *****   stackframe
  71.  
  72.         rsreset
  73. .intregs        rs.l    1
  74.         rs.l    1
  75. .edgestoadd     rs.l    1
  76. .edgelist       rs.l    1
  77.  
  78.  
  79. *        do
  80. *        {
  81. *                next_edge = edgestoadd->next;
  82. *edgesearch:
  83. *                if (edgelist->u >= edgestoadd->u)
  84. *                        goto addedge;
  85. *                edgelist=edgelist->next;
  86. *                if (edgelist->u >= edgestoadd->u)
  87. *                        goto addedge;
  88. *                edgelist=edgelist->next;
  89. *                if (edgelist->u >= edgestoadd->u)
  90. *                        goto addedge;
  91. *                edgelist=edgelist->next;
  92. *                if (edgelist->u >= edgestoadd->u)
  93. *                        goto addedge;
  94. *                edgelist=edgelist->next;
  95. *                goto edgesearch;
  96. *
  97. *        // insert edgestoadd before edgelist
  98. *addedge:
  99. *                edgestoadd->next = edgelist;
  100. *                edgestoadd->prev = edgelist->prev;
  101. *                edgelist->prev->next = edgestoadd;
  102. *                edgelist->prev = edgestoadd;
  103. *        } while ((edgestoadd = next_edge) != NULL);
  104.  
  105.         move.l  a2,-(sp)
  106.         move.l  .edgestoadd(sp),a0
  107.         move.l  .edgelist(sp),a1
  108.         move.l  EDGE_U(a0),d1
  109. .loop
  110.         cmp.l   EDGE_U(a1),d1           ;if (edgelist->u >= edgestoadd->u)
  111.         ble.b   .addedge                ;goto addedge
  112.         move.l  EDGE_NEXT(a1),a1        ;edgelist=edgelist->next
  113.         cmp.l   EDGE_U(a1),d1
  114.         ble.b   .addedge
  115.         move.l  EDGE_NEXT(a1),a1
  116.         cmp.l   EDGE_U(a1),d1
  117.         ble.b   .addedge
  118.         move.l  EDGE_NEXT(a1),a1
  119.         cmp.l   EDGE_U(a1),d1
  120.         ble.b   .addedge
  121.         move.l  EDGE_NEXT(a1),a1
  122.         bra.b   .loop
  123. .addedge
  124.         move.l  EDGE_NEXT(a0),d0        ;next_edge = edgestoadd->next
  125.         move.l  a1,EDGE_NEXT(a0)        ;edgestoadd->next = edgelist
  126.         move.l  EDGE_PREV(a1),a2
  127.         move.l  a2,EDGE_PREV(a0)        ;edgestoadd->prev = edgelist->prev
  128.         move.l  a0,EDGE_NEXT(a2)        ;edgelist->prev->next = edgestoadd
  129.         move.l  a0,EDGE_PREV(a1)        ;edgelist->prev = edgestoadd
  130.         tst.l   d0                      ;while ((edgestoadd = next_edge) != NULL)
  131.         beq.b   .end
  132.         move.l  d0,a0
  133.         move.l  EDGE_U(a0),d1
  134.         bra.b   .loop
  135. .end
  136.         move.l  (sp)+,a2
  137.         rts
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144. ******************************************************************************
  145. *
  146. *       void _R_RemoveEdges (edge_t *pedge)
  147. *
  148. ******************************************************************************
  149.  
  150.         cnop    0,4
  151. _R_RemoveEdges
  152.  
  153. *****   stackframe
  154.  
  155.         rsreset
  156. .intregs        rs.l    1
  157.         rs.l    1
  158. .pedge          rs.l    1
  159.  
  160.  
  161. *        do
  162. *        {
  163. *                pedge->next->prev = pedge->prev;
  164. *                pedge->prev->next = pedge->next;
  165. *        } while ((pedge = pedge->nextremove) != NULL);
  166.  
  167.         move.l  a2,-(sp)
  168.         move.l  .pedge(sp),a0
  169. .loop
  170.         move.l  EDGE_NEXT(a0),a1
  171.         move.l  EDGE_PREV(a0),a2
  172.         move.l  a2,EDGE_PREV(a1)        ;pedge->next->prev = pedge->prev
  173.         move.l  a1,EDGE_NEXT(a2)        ;pedge->prev->next = pedge->next
  174.         move.l  EDGE_NEXTREMOVE(a0),a0  ;while ((pedge = pedge->nextremove) != NULL)
  175.         tst.l   a0
  176.         bne.b   .loop
  177.         move.l  (sp)+,a2
  178.         rts
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187. ******************************************************************************
  188. *
  189. *       void _R_StepActiveU (edge_t *pedge)
  190. *
  191. ******************************************************************************
  192.  
  193.         cnop    0,4
  194. _R_StepActiveU
  195.  
  196. *****   stackframe
  197.  
  198.         rsreset
  199. .intregs        rs.l    5
  200.         rs.l    1
  201. .pedge          rs.l    1
  202.  
  203.  
  204. *nextedge:
  205. *                pedge->u += pedge->u_step;
  206. *                if (pedge->u < pedge->prev->u)
  207. *                        goto pushback;
  208. *                pedge = pedge->next;
  209. *
  210. *                pedge->u += pedge->u_step;
  211. *                if (pedge->u < pedge->prev->u)
  212. *                        goto pushback;
  213. *                pedge = pedge->next;
  214. *
  215. *                pedge->u += pedge->u_step;
  216. *                if (pedge->u < pedge->prev->u)
  217. *                        goto pushback;
  218. *                pedge = pedge->next;
  219. *
  220. *                pedge->u += pedge->u_step;
  221. *                if (pedge->u < pedge->prev->u)
  222. *                        goto pushback;
  223. *                pedge = pedge->next;
  224. *
  225. *                goto nextedge;
  226.  
  227.         movem.l a2-a6,-(sp)
  228.         move.l  .pedge(sp),a0
  229.         move.l  EDGE_PREV(a0),a1
  230.         move.l  EDGE_U(a1),d1
  231.         lea     _edge_aftertail,a2
  232.         lea     _edge_tail,a3
  233. .loop
  234.         move.l  EDGE_U(a0),d0
  235.         add.l   EDGE_U_STEP(a0),d0
  236.         move.l  d0,EDGE_U(a0)           ;pedge->u += pedge->u_step
  237.         cmp.l   d1,d0                   ;if (pedge->u < pedge->prev->u)
  238.         blt.b   .pushback               ;goto pushback
  239.         move.l  d0,d1
  240.         move.l  EDGE_NEXT(a0),a0        ;pedge = pedge->next
  241.         move.l  EDGE_U(a0),d0
  242.         add.l   EDGE_U_STEP(a0),d0
  243.         move.l  d0,EDGE_U(a0)
  244.         cmp.l   d1,d0
  245.         blt.b   .pushback
  246.         move.l  d0,d1
  247.         move.l  EDGE_NEXT(a0),a0
  248.         move.l  EDGE_U(a0),d0
  249.         add.l   EDGE_U_STEP(a0),d0
  250.         move.l  d0,EDGE_U(a0)
  251.         cmp.l   d1,d0
  252.         blt.b   .pushback
  253.         move.l  d0,d1
  254.         move.l  EDGE_NEXT(a0),a0
  255.         move.l  EDGE_U(a0),d0
  256.         add.l   EDGE_U_STEP(a0),d0
  257.         move.l  d0,EDGE_U(a0)
  258.         cmp.l   d1,d0
  259.         blt.b   .pushback
  260.         move.l  d0,d1
  261.         move.l  EDGE_NEXT(a0),a0
  262.         bra.b   .loop
  263.  
  264. *                if (pedge == &edge_aftertail)
  265. *                        return;
  266. *
  267. *        // push it back to keep it sorted
  268. *                pnext_edge = pedge->next;
  269. *
  270. *        // pull the edge out of the edge list
  271. *                pedge->next->prev = pedge->prev;
  272. *                pedge->prev->next = pedge->next;
  273. *
  274. *        // find out where the edge goes in the edge list
  275. *                pwedge = pedge->prev->prev;
  276. *
  277. *                while (pwedge->u > pedge->u)
  278. *                {
  279. *                        pwedge = pwedge->prev;
  280. *                }
  281. *
  282. *        // put the edge back into the edge list
  283. *                pedge->next = pwedge->next;
  284. *                pedge->prev = pwedge;
  285. *                pedge->next->prev = pedge;
  286. *                pwedge->next = pedge;
  287. *
  288. *                pedge = pnext_edge;
  289. *                if (pedge == &edge_tail)
  290. *                        return;
  291.  
  292. .pushback
  293.         cmp.l   a0,a2                   ;if (pedge == &edge_aftertail)
  294.         beq.w   .end                    ;return
  295.         move.l  EDGE_NEXT(a0),a4        ;pnext_edge = pedge->next
  296.         move.l  EDGE_PREV(a0),a5
  297.         move.l  a5,EDGE_PREV(a4)        ;pedge->next->prev = pedge->prev
  298.         move.l  a4,EDGE_NEXT(a5)        ;pedge->prev->next = pedge->next
  299.         move.l  EDGE_PREV(a5),a5        ;pwedge = pedge->prev->prev
  300. .loop2
  301.         cmp.l   EDGE_U(a5),d0           ;while (pwedge->u > pedge->u)
  302.         bgt.b   .cont
  303.         move.l  EDGE_PREV(a5),a5        ;pwedge = pwedge->prev
  304.         bra.b   .loop2
  305. .cont
  306.         move.l  EDGE_NEXT(a5),a1
  307.         move.l  a1,EDGE_NEXT(a0)        ;pedge->next = pwedge->next
  308.         move.l  a5,EDGE_PREV(a0)        ;pedge->prev = pwedge
  309.         move.l  a0,EDGE_PREV(a1)        ;pedge->next->prev = pedge
  310.         move.l  a0,EDGE_NEXT(a5)        ;pwedge->next = pedge
  311.         move.l  a4,a0                   ;pedge = pnext_edge
  312.         cmp.l   a3,a0                   ;if (pedge == &edge_tail)
  313.         bne.b   .loop
  314. .end
  315.         movem.l (sp)+,a2-a6
  316.         rts
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325. ******************************************************************************
  326. *
  327. *       void _R_GenerateSpans (void)
  328. *
  329. *       R_TrailingEdge and R_LeadingEdge are inlined
  330. *
  331. *       notes:
  332. *       Increment and Decrement of _r_bmodelactive removed, because it's
  333. *       obsolete here
  334. *
  335. ******************************************************************************
  336.  
  337.         cnop    0,4
  338. _R_GenerateSpans
  339.  
  340. ******  prologue
  341.  
  342.         movem.l d2-d7/a2-a6,-(sp)
  343.         fmovem.x        fp2-fp7,-(sp)
  344.         clr.l   _r_bmodelactive
  345.         move.l  _current_iv,d2
  346.         move.l  _surfaces,a3
  347.         lea     1*SURF_SIZEOF(a3),a4
  348.         move.l  a4,SURF_NEXT(a4)
  349.         move.l  a4,SURF_PREV(a4)
  350.         move.l  _edge_head_u_shift20,SURF_LAST_U(a4)
  351.         move.l  _edge_head+EDGE_NEXT,a5
  352.         lea     _edge_tail,a6
  353.         move.l  _span_p,a4
  354.         bra.w   .try
  355. .loop
  356.         move.l  EDGE_U(a5),d4
  357.         move.l  d4,d7
  358.         moveq   #20,d0
  359.         asr.l   d0,d4
  360.         move.l  EDGE_SURFS(a5),d1
  361.         move.l  d1,d0
  362.         swap    d0
  363.         ext.l   d0
  364.         beq.b   .cont
  365.         asl.l   #SURF_SIZEOF_EXP,d0
  366.         lea     0(a3,d0.l),a0
  367.  
  368. ******  R_TrailingEdge (inlined)
  369.  
  370. *        if (--surf->spanstate == 0)
  371. *        {
  372. *                if (surf->insubmodel)
  373. *                        r_bmodelactive--;
  374. *
  375. *                if (surf == surfaces[1].next)
  376. *                {
  377. *                // emit a span (current top going away)
  378. *                        iu = edge->u >> 20;
  379. *                        if (iu > surf->last_u)
  380. *                        {
  381. *                                span = span_p++;
  382. *                                span->u = surf->last_u;
  383. *                                span->count = iu - span->u;
  384. *                                span->v = current_iv;
  385. *                                span->pnext = surf->spans;
  386. *                                surf->spans = span;
  387. *                        }
  388. *
  389. *                // set last_u on the surface below
  390. *                        surf->next->last_u = iu;
  391. *                }
  392. *
  393. *                surf->prev->next = surf->next;
  394. *                surf->next->prev = surf->prev;
  395. *        }
  396.  
  397.         subq.l  #1,SURF_SPANSTATE(a0)   ;if (--surf->spanstate) == 0
  398.         bne.b   .cont
  399.         move.l  SURF_NEXT(a0),a1
  400.         cmp.l   1*SURF_SIZEOF+SURF_NEXT(a3),a0 ;if (surf==surfaces[1].next)
  401.         bne.b   .te_cont2
  402.         move.l  d4,d0                   ;iu = edge->u >> 20
  403.         move.l  SURF_LAST_U(a0),d5
  404.         move.l  d0,SURF_LAST_U(a1)      ;surf->next->last_u = iu
  405.         sub.l   d5,d0                   ;if (iu > surf->last_u)
  406.         ble.b   .te_cont2
  407.         move.l  SURF_SPANS(a0),d3
  408.         move.l  a4,SURF_SPANS(a0)       ;surf->spans = span
  409.         move.l  d5,(a4)+                ;span->u = surf->last_u
  410.         move.l  d2,(a4)+                ;span->v = current_iv
  411.         move.l  d0,(a4)+                ;span->count = iu - span->u
  412.         move.l  d3,(a4)+                ;span->pnext = surf->spans
  413. .te_cont2
  414.         move.l  SURF_PREV(a0),a2
  415.         move.l  a1,SURF_NEXT(a2)        ;surf->prev->next = surf->next
  416.         move.l  a2,SURF_PREV(a1)        ;surf->next->prev = surf->prev
  417.  
  418. ******  end of R_TrailingEdge
  419.  
  420. .cont
  421.  
  422. ******  R_LeadingEdge (inlined)
  423.  
  424. *        if (edge->surfs[1])
  425. *        {
  426. *        // it's adding a new surface in, so find the correct place
  427. *                surf = &surfaces[edge->surfs[1]];
  428. *
  429.         ext.l   d1
  430.         beq.w   .next
  431.         asl.l   #SURF_SIZEOF_EXP,d1
  432.         lea     0(a3,d1.l),a1           ;surf = &surfaces[edge->surfs[1]]
  433. *
  434. *        // don't start a span if this is an inverted span, with the end
  435. *        // edge preceding the start edge (that is, we've already seen the
  436. *        // end edge)
  437. *                if (++surf->spanstate == 1)
  438. *                {
  439. *                        if (surf->insubmodel)
  440. *                                r_bmodelactive++;
  441. *
  442. *                        surf2 = surfaces[1].next;
  443. *
  444. *                        if (surf->key < surf2->key)
  445. *                                goto newtop;
  446. *                // if it's two surfaces on the same plane, the one that's already
  447. *                // active is in front, so keep going unless it's a bmodel
  448. *                        if (surf->insubmodel && (surf->key == surf2->key))
  449. *                        {
  450.  
  451.  
  452.         move.l  SURF_SPANSTATE(a1),d0   ;if (++surf->spanstate == 1)
  453.         beq.b   .le_zero
  454.         addq.l  #1,SURF_SPANSTATE(a1)
  455.         bra.w   .next
  456. .le_zero
  457.         addq.l  #1,d0
  458.         move.l  d0,SURF_SPANSTATE(a1)
  459.         move.l  SURF_INSUBMODEL(a1),d5  ;if (surf->insubmodel)
  460.         move.l  1*SURF_SIZEOF+SURF_NEXT(a3),a0  ;surf2 = surfaces[1].next
  461.         move.l  SURF_KEY(a1),d6
  462.         moveq   #0,d3
  463.         cmp.l   SURF_KEY(a0),d6         ;if (surf->key < surf2->key)
  464.         blt.b   .le_newtop              ;goto newtop
  465.         bgt.b   .le_search
  466.         tst.b   d5
  467.         beq.b   .le_search
  468.  
  469.         moveq   #-1,d3
  470.         move.l  d7,d0
  471.         sub.l   #$fffff,d0              ;edge->u - 0xFFFFF
  472.         fmove.l d0,fp0                  :(float)(edge->u - 0xFFFFF)
  473.         fmul.s  #(1.0/(16*65536)),fp0   ;fu = fp0 * (1 / $100000)
  474.         fmove.s _fv,fp1                 ;fv
  475.         fmove.s SURF_D_ZIORIGIN(a1),fp2
  476.         fmove.s SURF_D_ZISTEPV(a1),fp3
  477.         fmul    fp1,fp3                 ;fp1 = fv * surf->d_zistepv
  478.         fadd    fp3,fp2
  479.         fmove.s SURF_D_ZISTEPU(a1),fp3
  480.         fmove   fp3,fp4                 ;fp4 = surf->d_zistepu
  481.         fmul    fp0,fp3                 ;fp3 = fu * surf->d_zistepu
  482.         fadd    fp3,fp2                 ;newzi = d_ziorigin + fp1 + fp3
  483.         fmove   fp2,fp3
  484.         fmul.s  #0.99,fp2               ;newzibottom = newzi * 0.99
  485.         fmul.s  #1.01,fp3               ;newzitop = newzi * 1.01
  486.  
  487.  
  488. *                        // must be two bmodels in the same leaf; sort on 1/z
  489. *                                fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
  490. *                                newzi = surf->d_ziorigin + fv*surf->d_zistepv +
  491. *                                                fu*surf->d_zistepu;
  492. *                                newzibottom = newzi * 0.99;
  493. *
  494. *                                testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
  495. *                                                fu*surf2->d_zistepu;
  496. *
  497. *                                if (newzibottom >= testzi)
  498. *                                {
  499. *                                        goto newtop;
  500. *                                }
  501. *
  502. *                                newzitop = newzi * 1.01;
  503. *                                if (newzitop >= testzi)
  504. *                                {
  505. *                                        if (surf->d_zistepu >= surf2->d_zistepu)
  506. *                                        {
  507. *                                                goto newtop;
  508. *                                        }
  509. *                                }
  510.  
  511.         fmove.s SURF_D_ZIORIGIN(a0),fp5
  512.         fmove.s SURF_D_ZISTEPV(a0),fp6
  513.         fmul    fp1,fp6                 ;fp1 = fv * surf2->d_zistepv
  514.         fadd    fp6,fp5
  515.         fmove.s SURF_D_ZISTEPU(a0),fp6
  516.         fmove   fp6,fp7
  517.         fmul    fp0,fp6                 ;fp3 = fu * surf2->d_zistepu
  518.         fadd    fp6,fp5                 ;testzi = d_ziorigin + fp1 + fp3
  519.         fcmp    fp5,fp2                 ;if (newzibottom >= testzi)
  520.         fbge.b  .le_newtop              ;goto newtop
  521.         fcmp    fp5,fp3                 ;if (newzitop >= testzi)
  522.         fblt.b  .le_search
  523.         fcmp    fp7,fp4                 ;if (surf->d_zistepu >= surf2->d_zistepu)
  524.         fbge.b  .le_newtop              ;goto newtop
  525.  
  526. *                        do
  527. *                        {
  528. *                                surf2 = surf2->next;
  529. *                        } while (surf->key > surf2->key);
  530. *
  531.  
  532.  
  533. .le_search
  534.         move.l  SURF_NEXT(a0),a0        ;surf2 = surf2->next
  535.         cmp.l   SURF_KEY(a0),d6         ;while (surf->key > surf2->key)
  536.         bgt.b   .le_search
  537.  
  538. *                        if (surf->key == surf2->key)
  539. *                        {
  540. *                        // if it's two surfaces on the same plane, the one that's already
  541. *                        // active is in front, so keep going unless it's a bmodel
  542. *                                if (!surf->insubmodel)
  543. *                                        goto continue_search;
  544.  
  545.         bne.b   .le_gotposition
  546.         tst.b   d5
  547.         beq.b   .le_search
  548.         tst     d3
  549.         bne.b   .le_precalc_done
  550.         moveq   #-1,d3
  551.         move.l  d7,d0
  552.         sub.l   #$fffff,d0              ;edge->u - 0xFFFFF
  553.         fmove.l d0,fp0                  :(float)(edge->u - 0xFFFFF)
  554.         fmul.s  #(1.0/(16*65536)),fp0   ;fu = fp0 * (1 / $100000)
  555.         fmove.s _fv,fp1                 ;fv
  556.         fmove.s SURF_D_ZIORIGIN(a1),fp2
  557.         fmove.s SURF_D_ZISTEPV(a1),fp3
  558.         fmul    fp1,fp3                 ;fp1 = fv * surf->d_zistepv
  559.         fadd    fp3,fp2
  560.         fmove.s SURF_D_ZISTEPU(a1),fp3
  561.         fmove   fp3,fp4                 ;fp4 = surf->d_zistepu
  562.         fmul    fp0,fp3                 ;fp3 = fu * surf->d_zistepu
  563.         fadd    fp3,fp2                 ;newzi = d_ziorigin + fp1 + fp3
  564.         fmove   fp2,fp3
  565.         fmul.s  #0.99,fp2               ;newzibottom = newzi * 0.99
  566.         fmul.s  #1.01,fp3               ;newzitop = newzi * 1.01
  567. .le_precalc_done
  568.  
  569. *                        // must be two bmodels in the same leaf; sort on 1/z
  570. *                                fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
  571. *                                newzi = surf->d_ziorigin + fv*surf->d_zistepv +
  572. *                                                fu*surf->d_zistepu;
  573. *                                newzibottom = newzi * 0.99;
  574. *
  575. *                                testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
  576. *                                                fu*surf2->d_zistepu;
  577. *
  578. *                                if (newzibottom >= testzi)
  579. *                                {
  580. *                                        goto gotposition;
  581. *                                }
  582. *
  583. *                                newzitop = newzi * 1.01;
  584. *                                if (newzitop >= testzi)
  585. *                                {
  586. *                                        if (surf->d_zistepu >= surf2->d_zistepu)
  587. *                                        {
  588. *                                                goto gotposition;
  589. *                                        }
  590. *                                }
  591. *
  592. *                                goto continue_search;
  593. *                        }
  594. *
  595. *                        goto gotposition;
  596.  
  597.         fmove.s SURF_D_ZIORIGIN(a0),fp5
  598.         fmove.s SURF_D_ZISTEPV(a0),fp6
  599.         fmul    fp1,fp6                 ;fp1 = fv * surf2->d_zistepv
  600.         fadd    fp6,fp5
  601.         fmove.s SURF_D_ZISTEPU(a0),fp6
  602.         fmove   fp6,fp7
  603.         fmul    fp0,fp6                 ;fp3 = fu * surf2->d_zistepu
  604.         fadd    fp6,fp5                 ;testzi = d_ziorigin + fp1 + fp3
  605.         fcmp    fp5,fp2                 ;if (newzibottom >= testzi)
  606.         fbge.b  .le_gotposition         ;goto gotposition
  607.         fcmp    fp5,fp3                 ;if (newzitop >= testzi)
  608.         fblt.b  .le_search
  609.         fcmp    fp7,fp4                 ;if (surf->d_zistepu >= surf2->d_zistepu)
  610.         fbge.b  .le_gotposition         ;goto gotposition
  611.         bra.b   .le_search
  612.  
  613. *                // emit a span (obscures current top)
  614. *                        iu = edge->u >> 20;
  615. *
  616. *                        if (iu > surf2->last_u)
  617. *                        {
  618. *                                span = span_p++;
  619. *                                span->u = surf2->last_u;
  620. *                                span->count = iu - span->u;
  621. *                                span->v = current_iv;
  622. *                                span->pnext = surf2->spans;
  623. *                                surf2->spans = span;
  624. *                        }
  625. *
  626. *                        // set last_u on the new span
  627. *                        surf->last_u = iu;
  628.  
  629. .le_newtop
  630.         move.l  SURF_LAST_U(a0),d5
  631.         move.l  d4,SURF_LAST_U(a1)      ;surf->last_u = iu
  632.         sub.l   d5,d4                   ;if (iu > surf2->last_u)
  633.         ble.b   .le_cont2
  634.         move.l  SURF_SPANS(a0),d3
  635.         move.l  a4,SURF_SPANS(a0)       ;surf2->spans = span
  636.         move.l  d5,(a4)+                ;span->u = surf2->last_u
  637.         move.l  d2,(a4)+                ;span->v = current_iv
  638.         move.l  d4,(a4)+                ;span->count = iu - span->u
  639.         move.l  d3,(a4)+                ;span->pnext = surf2->spans
  640. .le_cont2
  641.  
  642. *                // insert before surf2
  643. *                        surf->next = surf2;
  644. *                        surf->prev = surf2->prev;
  645. *                        surf2->prev->next = surf;
  646. *                        surf2->prev = surf;
  647.  
  648. .le_gotposition
  649.         move.l  SURF_PREV(a0),a2
  650.         move.l  a2,SURF_PREV(a1)        ;surf->prev = surf2->prev
  651.         move.l  a0,SURF_NEXT(a1)        ;surf->next = surf2
  652.         move.l  a1,SURF_NEXT(a2)        ;surf2->prev->next = surf
  653.         move.l  a1,SURF_PREV(a0)        ;surf2->prev = surf
  654.  
  655. ******  end of R_LeadingEdge
  656.  
  657. .next
  658.         move.l  EDGE_NEXT(a5),a5
  659. .try
  660.         cmp.l   a5,a6
  661.         bne.b   .loop
  662.         move.l  a4,_span_p
  663.         jsr     _R_CleanupSpan
  664.         fmovem.x        (sp)+,fp2-fp7
  665.         movem.l (sp)+,d2-d7/a2-a6
  666.         rts
  667.