Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

r_edgea.asm (18648B)


      1  .386P
      2  .model FLAT
      3 ;
      4 ; r_edgea.s
      5 ; x86 assembly-language edge-processing code.
      6 ;
      7 
      8 include qasm.inc
      9 
     10 if	id386
     11 
     12 _DATA SEGMENT	
     13 Ltemp dd 0	
     14 float_1_div_0100000h dd 035800000h	; 1.0/(float)0x100000
     15 float_point_999 dd 0.999	
     16 float_1_point_001 dd 1.001	
     17 
     18 _DATA ENDS
     19 _TEXT SEGMENT	
     20 
     21 ;--------------------------------------------------------------------
     22 
     23 edgestoadd	equ		4+8		; note odd stack offsets because of interleaving
     24 edgelist	equ		8+12	; with pushes
     25 
     26  public _R_EdgeCodeStart	
     27 _R_EdgeCodeStart:	
     28 
     29  public _R_InsertNewEdges	
     30 _R_InsertNewEdges:	
     31  push edi	
     32  push esi	; preserve register variables
     33  mov edx,ds:dword ptr[edgestoadd+esp]	
     34  push ebx	
     35  mov ecx,ds:dword ptr[edgelist+esp]	
     36 
     37 LDoNextEdge:	
     38  mov eax,ds:dword ptr[et_u+edx]	
     39  mov edi,edx	
     40 
     41 LContinueSearch:	
     42  mov ebx,ds:dword ptr[et_u+ecx]	
     43  mov esi,ds:dword ptr[et_next+ecx]	
     44  cmp eax,ebx	
     45  jle LAddedge	
     46  mov ebx,ds:dword ptr[et_u+esi]	
     47  mov ecx,ds:dword ptr[et_next+esi]	
     48  cmp eax,ebx	
     49  jle LAddedge2	
     50  mov ebx,ds:dword ptr[et_u+ecx]	
     51  mov esi,ds:dword ptr[et_next+ecx]	
     52  cmp eax,ebx	
     53  jle LAddedge	
     54  mov ebx,ds:dword ptr[et_u+esi]	
     55  mov ecx,ds:dword ptr[et_next+esi]	
     56  cmp eax,ebx	
     57  jg LContinueSearch	
     58 
     59 LAddedge2:	
     60  mov edx,ds:dword ptr[et_next+edx]	
     61  mov ebx,ds:dword ptr[et_prev+esi]	
     62  mov ds:dword ptr[et_next+edi],esi	
     63  mov ds:dword ptr[et_prev+edi],ebx	
     64  mov ds:dword ptr[et_next+ebx],edi	
     65  mov ds:dword ptr[et_prev+esi],edi	
     66  mov ecx,esi	
     67 
     68  cmp edx,0	
     69  jnz LDoNextEdge	
     70  jmp LDone	
     71 
     72  align 4	
     73 LAddedge:	
     74  mov edx,ds:dword ptr[et_next+edx]	
     75  mov ebx,ds:dword ptr[et_prev+ecx]	
     76  mov ds:dword ptr[et_next+edi],ecx	
     77  mov ds:dword ptr[et_prev+edi],ebx	
     78  mov ds:dword ptr[et_next+ebx],edi	
     79  mov ds:dword ptr[et_prev+ecx],edi	
     80 
     81  cmp edx,0	
     82  jnz LDoNextEdge	
     83 
     84 LDone:	
     85  pop ebx	; restore register variables
     86  pop esi	
     87  pop edi	
     88 
     89  ret	
     90 
     91 ;--------------------------------------------------------------------
     92 
     93 predge	equ		4+4
     94 
     95  public _R_RemoveEdges	
     96 _R_RemoveEdges:	
     97  push ebx	
     98  mov eax,ds:dword ptr[predge+esp]	
     99 
    100 Lre_loop:	
    101  mov ecx,ds:dword ptr[et_next+eax]	
    102  mov ebx,ds:dword ptr[et_nextremove+eax]	
    103  mov edx,ds:dword ptr[et_prev+eax]	
    104  test ebx,ebx	
    105  mov ds:dword ptr[et_prev+ecx],edx	
    106  jz Lre_done	
    107  mov ds:dword ptr[et_next+edx],ecx	
    108 
    109  mov ecx,ds:dword ptr[et_next+ebx]	
    110  mov edx,ds:dword ptr[et_prev+ebx]	
    111  mov eax,ds:dword ptr[et_nextremove+ebx]	
    112  mov ds:dword ptr[et_prev+ecx],edx	
    113  test eax,eax	
    114  mov ds:dword ptr[et_next+edx],ecx	
    115  jnz Lre_loop	
    116 
    117  pop ebx	
    118  ret	
    119 
    120 Lre_done:	
    121  mov ds:dword ptr[et_next+edx],ecx	
    122  pop ebx	
    123 
    124  ret	
    125 
    126 ;--------------------------------------------------------------------
    127 
    128 pedgelist	equ		4+4		; note odd stack offset because of interleaving
    129 							; with pushes
    130 
    131  public _R_StepActiveU	
    132 _R_StepActiveU:	
    133  push edi	
    134  mov edx,ds:dword ptr[pedgelist+esp]	
    135  push esi	; preserve register variables
    136  push ebx	
    137 
    138  mov esi,ds:dword ptr[et_prev+edx]	
    139 
    140 LNewEdge:	
    141  mov edi,ds:dword ptr[et_u+esi]	
    142 
    143 LNextEdge:	
    144  mov eax,ds:dword ptr[et_u+edx]	
    145  mov ebx,ds:dword ptr[et_u_step+edx]	
    146  add eax,ebx	
    147  mov esi,ds:dword ptr[et_next+edx]	
    148  mov ds:dword ptr[et_u+edx],eax	
    149  cmp eax,edi	
    150  jl LPushBack	
    151 
    152  mov edi,ds:dword ptr[et_u+esi]	
    153  mov ebx,ds:dword ptr[et_u_step+esi]	
    154  add edi,ebx	
    155  mov edx,ds:dword ptr[et_next+esi]	
    156  mov ds:dword ptr[et_u+esi],edi	
    157  cmp edi,eax	
    158  jl LPushBack2	
    159 
    160  mov eax,ds:dword ptr[et_u+edx]	
    161  mov ebx,ds:dword ptr[et_u_step+edx]	
    162  add eax,ebx	
    163  mov esi,ds:dword ptr[et_next+edx]	
    164  mov ds:dword ptr[et_u+edx],eax	
    165  cmp eax,edi	
    166  jl LPushBack	
    167 
    168  mov edi,ds:dword ptr[et_u+esi]	
    169  mov ebx,ds:dword ptr[et_u_step+esi]	
    170  add edi,ebx	
    171  mov edx,ds:dword ptr[et_next+esi]	
    172  mov ds:dword ptr[et_u+esi],edi	
    173  cmp edi,eax	
    174  jnl LNextEdge	
    175 
    176 LPushBack2:	
    177  mov ebx,edx	
    178  mov eax,edi	
    179  mov edx,esi	
    180  mov esi,ebx	
    181 
    182 LPushBack:	
    183 ; push it back to keep it sorted
    184  mov ecx,ds:dword ptr[et_prev+edx]	
    185  mov ebx,ds:dword ptr[et_next+edx]	
    186 
    187 ; done if the -1 in edge_aftertail triggered this
    188  cmp edx,offset _edge_aftertail
    189  jz LUDone	
    190 
    191 ; pull the edge out of the edge list
    192  mov edi,ds:dword ptr[et_prev+ecx]	
    193  mov ds:dword ptr[et_prev+esi],ecx	
    194  mov ds:dword ptr[et_next+ecx],ebx	
    195 
    196 ; find out where the edge goes in the edge list
    197 LPushBackLoop:	
    198  mov ecx,ds:dword ptr[et_prev+edi]	
    199  mov ebx,ds:dword ptr[et_u+edi]	
    200  cmp eax,ebx	
    201  jnl LPushBackFound	
    202 
    203  mov edi,ds:dword ptr[et_prev+ecx]	
    204  mov ebx,ds:dword ptr[et_u+ecx]	
    205  cmp eax,ebx	
    206  jl LPushBackLoop	
    207 
    208  mov edi,ecx	
    209 
    210 ; put the edge back into the edge list
    211 LPushBackFound:	
    212  mov ebx,ds:dword ptr[et_next+edi]	
    213  mov ds:dword ptr[et_prev+edx],edi	
    214  mov ds:dword ptr[et_next+edx],ebx	
    215  mov ds:dword ptr[et_next+edi],edx	
    216  mov ds:dword ptr[et_prev+ebx],edx	
    217 
    218  mov edx,esi	
    219  mov esi,ds:dword ptr[et_prev+esi]	
    220 
    221  cmp edx,offset _edge_tail
    222  jnz LNewEdge	
    223 
    224 LUDone:	
    225  pop ebx	; restore register variables
    226  pop esi	
    227  pop edi	
    228 
    229  ret	
    230 
    231 ;--------------------------------------------------------------------
    232 
    233 surf	equ		4		; note this is loaded before any pushes
    234 
    235  align 4	
    236 TrailingEdge:	
    237  mov eax,ds:dword ptr[st_spanstate+esi]	; check for edge inversion
    238  dec eax	
    239  jnz LInverted	
    240 
    241  mov ds:dword ptr[st_spanstate+esi],eax	
    242  mov ecx,ds:dword ptr[st_insubmodel+esi]	
    243  mov edx,ds:dword ptr[12345678h]	; surfaces[1].st_next
    244 LPatch0:	
    245  mov eax,ds:dword ptr[_r_bmodelactive]	
    246  sub eax,ecx	
    247  cmp edx,esi	
    248  mov ds:dword ptr[_r_bmodelactive],eax	
    249  jnz LNoEmit	; surface isn't on top, just remove
    250 
    251 ; emit a span (current top going away)
    252  mov eax,ds:dword ptr[et_u+ebx]	
    253  shr eax,20	; iu = integral pixel u
    254  mov edx,ds:dword ptr[st_last_u+esi]	
    255  mov ecx,ds:dword ptr[st_next+esi]	
    256  cmp eax,edx	
    257  jle LNoEmit2	; iu <= surf->last_u, so nothing to emit
    258 
    259  mov ds:dword ptr[st_last_u+ecx],eax	; surf->next->last_u = iu;
    260  sub eax,edx	
    261  mov ds:dword ptr[espan_t_u+ebp],edx	; span->u = surf->last_u;
    262 
    263  mov ds:dword ptr[espan_t_count+ebp],eax	; span->count = iu - span->u;
    264  mov eax,ds:dword ptr[_current_iv]	
    265  mov ds:dword ptr[espan_t_v+ebp],eax	; span->v = current_iv;
    266  mov eax,ds:dword ptr[st_spans+esi]	
    267  mov ds:dword ptr[espan_t_pnext+ebp],eax	; span->pnext = surf->spans;
    268  mov ds:dword ptr[st_spans+esi],ebp	; surf->spans = span;
    269  add ebp,offset espan_t_size	
    270 
    271  mov edx,ds:dword ptr[st_next+esi]	; remove the surface from the surface
    272  mov esi,ds:dword ptr[st_prev+esi]	; stack
    273 
    274  mov ds:dword ptr[st_next+esi],edx	
    275  mov ds:dword ptr[st_prev+edx],esi	
    276  ret	
    277 
    278 LNoEmit2:	
    279  mov ds:dword ptr[st_last_u+ecx],eax	; surf->next->last_u = iu;
    280  mov edx,ds:dword ptr[st_next+esi]	; remove the surface from the surface
    281  mov esi,ds:dword ptr[st_prev+esi]	; stack
    282 
    283  mov ds:dword ptr[st_next+esi],edx	
    284  mov ds:dword ptr[st_prev+edx],esi	
    285  ret	
    286 
    287 LNoEmit:	
    288  mov edx,ds:dword ptr[st_next+esi]	; remove the surface from the surface
    289  mov esi,ds:dword ptr[st_prev+esi]	; stack
    290 
    291  mov ds:dword ptr[st_next+esi],edx	
    292  mov ds:dword ptr[st_prev+edx],esi	
    293  ret	
    294 
    295 LInverted:	
    296  mov ds:dword ptr[st_spanstate+esi],eax	
    297  ret	
    298 
    299 ;--------------------------------------------------------------------
    300 
    301 ; trailing edge only
    302 Lgs_trailing:	
    303  push offset Lgs_nextedge	
    304  jmp TrailingEdge	
    305 
    306 
    307  public _R_GenerateSpans	
    308 _R_GenerateSpans:	
    309  push ebp	; preserve caller's stack frame
    310  push edi	
    311  push esi	; preserve register variables
    312  push ebx	
    313 
    314 ; clear active surfaces to just the background surface
    315  mov eax,ds:dword ptr[_surfaces]	
    316  mov edx,ds:dword ptr[_edge_head_u_shift20]	
    317  add eax,offset st_size	
    318 ; %ebp = span_p throughout
    319  mov ebp,ds:dword ptr[_span_p]	
    320 
    321  mov ds:dword ptr[_r_bmodelactive],0	
    322 
    323  mov ds:dword ptr[st_next+eax],eax	
    324  mov ds:dword ptr[st_prev+eax],eax	
    325  mov ds:dword ptr[st_last_u+eax],edx	
    326  mov ebx,ds:dword ptr[_edge_head+et_next]	; edge=edge_head.next
    327 
    328 ; generate spans
    329  cmp ebx,offset _edge_tail	; done if empty list
    330  jz Lgs_lastspan	
    331 
    332 Lgs_edgeloop:	
    333 
    334  mov edi,ds:dword ptr[et_surfs+ebx]	
    335  mov eax,ds:dword ptr[_surfaces]	
    336  mov esi,edi	
    337  and edi,0FFFF0000h	
    338  and esi,0FFFFh	
    339  jz Lgs_leading	; not a trailing edge
    340 
    341 ; it has a left surface, so a surface is going away for this span
    342  shl esi,offset SURF_T_SHIFT	
    343  add esi,eax	
    344  test edi,edi	
    345  jz Lgs_trailing	
    346 
    347 ; both leading and trailing
    348  call near ptr TrailingEdge	
    349  mov eax,ds:dword ptr[_surfaces]	
    350 
    351 ; ---------------------------------------------------------------
    352 ; handle a leading edge
    353 ; ---------------------------------------------------------------
    354 
    355 Lgs_leading:	
    356  shr edi,16-SURF_T_SHIFT	
    357  mov eax,ds:dword ptr[_surfaces]	
    358  add edi,eax	
    359  mov esi,ds:dword ptr[12345678h]	; surf2 = surfaces[1].next;
    360 LPatch2:	
    361  mov edx,ds:dword ptr[st_spanstate+edi]	
    362  mov eax,ds:dword ptr[st_insubmodel+edi]	
    363  test eax,eax	
    364  jnz Lbmodel_leading	
    365 
    366 ; handle a leading non-bmodel edge
    367 
    368 ; don't start a span if this is an inverted span, with the end edge preceding
    369 ; the start edge (that is, we've already seen the end edge)
    370  test edx,edx	
    371  jnz Lxl_done	
    372 
    373 
    374 ; if (surf->key < surf2->key)
    375 ;		goto newtop;
    376  inc edx	
    377  mov eax,ds:dword ptr[st_key+edi]	
    378  mov ds:dword ptr[st_spanstate+edi],edx	
    379  mov ecx,ds:dword ptr[st_key+esi]	
    380  cmp eax,ecx	
    381  jl Lnewtop	
    382 
    383 ; main sorting loop to search through surface stack until insertion point
    384 ; found. Always terminates because background surface is sentinel
    385 ; do
    386 ; {
    387 ; 		surf2 = surf2->next;
    388 ; } while (surf->key >= surf2->key);
    389 Lsortloopnb:	
    390  mov esi,ds:dword ptr[st_next+esi]	
    391  mov ecx,ds:dword ptr[st_key+esi]	
    392  cmp eax,ecx	
    393  jge Lsortloopnb	
    394 
    395  jmp LInsertAndExit	
    396 
    397 
    398 ; handle a leading bmodel edge
    399  align 4	
    400 Lbmodel_leading:	
    401 
    402 ; don't start a span if this is an inverted span, with the end edge preceding
    403 ; the start edge (that is, we've already seen the end edge)
    404  test edx,edx	
    405  jnz Lxl_done	
    406 
    407  mov ecx,ds:dword ptr[_r_bmodelactive]	
    408  inc edx	
    409  inc ecx	
    410  mov ds:dword ptr[st_spanstate+edi],edx	
    411  mov ds:dword ptr[_r_bmodelactive],ecx	
    412 
    413 ; if (surf->key < surf2->key)
    414 ;		goto newtop;
    415  mov eax,ds:dword ptr[st_key+edi]	
    416  mov ecx,ds:dword ptr[st_key+esi]	
    417  cmp eax,ecx	
    418  jl Lnewtop	
    419 
    420 ; if ((surf->key == surf2->key) && surf->insubmodel)
    421 ; {
    422  jz Lzcheck_for_newtop	
    423 
    424 ; main sorting loop to search through surface stack until insertion point
    425 ; found. Always terminates because background surface is sentinel
    426 ; do
    427 ; {
    428 ; 		surf2 = surf2->next;
    429 ; } while (surf->key > surf2->key);
    430 Lsortloop:	
    431  mov esi,ds:dword ptr[st_next+esi]	
    432  mov ecx,ds:dword ptr[st_key+esi]	
    433  cmp eax,ecx	
    434  jg Lsortloop	
    435 
    436  jne LInsertAndExit	
    437 
    438 ; Do 1/z sorting to see if we've arrived in the right position
    439  mov eax,ds:dword ptr[et_u+ebx]	
    440  sub eax,0FFFFFh	
    441  mov ds:dword ptr[Ltemp],eax	
    442  fild ds:dword ptr[Ltemp]	
    443 
    444  fmul ds:dword ptr[float_1_div_0100000h]	; fu = (float)(edge->u - 0xFFFFF) *
    445 ;      (1.0 / 0x100000);
    446 
    447  fld st(0)	; fu | fu
    448  fmul ds:dword ptr[st_d_zistepu+edi]	; fu*surf->d_zistepu | fu
    449  fld ds:dword ptr[_fv]	; fv | fu*surf->d_zistepu | fu
    450  fmul ds:dword ptr[st_d_zistepv+edi]	; fv*surf->d_zistepv | fu*surf->d_zistepu | fu
    451  fxch st(1)	; fu*surf->d_zistepu | fv*surf->d_zistepv | fu
    452  fadd ds:dword ptr[st_d_ziorigin+edi]	; fu*surf->d_zistepu + surf->d_ziorigin |
    453 ;  fv*surf->d_zistepv | fu
    454 
    455  fld ds:dword ptr[st_d_zistepu+esi]	; surf2->d_zistepu |
    456 ;  fu*surf->d_zistepu + surf->d_ziorigin |
    457 ;  fv*surf->d_zistepv | fu
    458  fmul st(0),st(3)	; fu*surf2->d_zistepu |
    459 ;  fu*surf->d_zistepu + surf->d_ziorigin |
    460 ;  fv*surf->d_zistepv | fu
    461  fxch st(1)	; fu*surf->d_zistepu + surf->d_ziorigin |
    462 ;  fu*surf2->d_zistepu |
    463 ;  fv*surf->d_zistepv | fu
    464  faddp st(2),st(0)	; fu*surf2->d_zistepu | newzi | fu
    465 
    466  fld ds:dword ptr[_fv]	; fv | fu*surf2->d_zistepu | newzi | fu
    467  fmul ds:dword ptr[st_d_zistepv+esi]	; fv*surf2->d_zistepv |
    468 ;  fu*surf2->d_zistepu | newzi | fu
    469  fld st(2)	; newzi | fv*surf2->d_zistepv |
    470 ;  fu*surf2->d_zistepu | newzi | fu
    471  fmul ds:dword ptr[float_point_999]	; newzibottom | fv*surf2->d_zistepv |
    472 ;  fu*surf2->d_zistepu | newzi | fu
    473 
    474  fxch st(2)	; fu*surf2->d_zistepu | fv*surf2->d_zistepv |
    475 ;  newzibottom | newzi | fu
    476  fadd ds:dword ptr[st_d_ziorigin+esi]	; fu*surf2->d_zistepu + surf2->d_ziorigin |
    477 ;  fv*surf2->d_zistepv | newzibottom | newzi |
    478 ;  fu
    479  faddp st(1),st(0)	; testzi | newzibottom | newzi | fu
    480  fxch st(1)	; newzibottom | testzi | newzi | fu
    481 
    482 ; if (newzibottom >= testzi)
    483 ;     goto Lgotposition;
    484 
    485  fcomp st(1)	; testzi | newzi | fu
    486 
    487  fxch st(1)	; newzi | testzi | fu
    488  fmul ds:dword ptr[float_1_point_001]	; newzitop | testzi | fu
    489  fxch st(1)	; testzi | newzitop | fu
    490 
    491  fnstsw ax	
    492  test ah,001h	
    493  jz Lgotposition_fpop3	
    494 
    495 ; if (newzitop >= testzi)
    496 ; {
    497 
    498  fcomp st(1)	; newzitop | fu
    499  fnstsw ax	
    500  test ah,045h	
    501  jz Lsortloop_fpop2	
    502 
    503 ; if (surf->d_zistepu >= surf2->d_zistepu)
    504 ;     goto newtop;
    505 
    506  fld ds:dword ptr[st_d_zistepu+edi]	; surf->d_zistepu | newzitop| fu
    507  fcomp ds:dword ptr[st_d_zistepu+esi]	; newzitop | fu
    508  fnstsw ax	
    509  test ah,001h	
    510  jz Lgotposition_fpop2	
    511 
    512  fstp st(0)	; clear the FPstack
    513  fstp st(0)	
    514  mov eax,ds:dword ptr[st_key+edi]	
    515  jmp Lsortloop	
    516 
    517 
    518 Lgotposition_fpop3:	
    519  fstp st(0)	
    520 Lgotposition_fpop2:	
    521  fstp st(0)	
    522  fstp st(0)	
    523  jmp LInsertAndExit	
    524 
    525 
    526 ; emit a span (obscures current top)
    527 
    528 Lnewtop_fpop3:	
    529  fstp st(0)	
    530 Lnewtop_fpop2:	
    531  fstp st(0)	
    532  fstp st(0)	
    533  mov eax,ds:dword ptr[st_key+edi]	; reload the sorting key
    534 
    535 Lnewtop:	
    536  mov eax,ds:dword ptr[et_u+ebx]	
    537  mov edx,ds:dword ptr[st_last_u+esi]	
    538  shr eax,20	; iu = integral pixel u
    539  mov ds:dword ptr[st_last_u+edi],eax	; surf->last_u = iu;
    540  cmp eax,edx	
    541  jle LInsertAndExit	; iu <= surf->last_u, so nothing to emit
    542 
    543  sub eax,edx	
    544  mov ds:dword ptr[espan_t_u+ebp],edx	; span->u = surf->last_u;
    545 
    546  mov ds:dword ptr[espan_t_count+ebp],eax	; span->count = iu - span->u;
    547  mov eax,ds:dword ptr[_current_iv]	
    548  mov ds:dword ptr[espan_t_v+ebp],eax	; span->v = current_iv;
    549  mov eax,ds:dword ptr[st_spans+esi]	
    550  mov ds:dword ptr[espan_t_pnext+ebp],eax	; span->pnext = surf->spans;
    551  mov ds:dword ptr[st_spans+esi],ebp	; surf->spans = span;
    552  add ebp,offset espan_t_size	
    553 
    554 LInsertAndExit:	
    555 ; insert before surf2
    556  mov ds:dword ptr[st_next+edi],esi	; surf->next = surf2;
    557  mov eax,ds:dword ptr[st_prev+esi]	
    558  mov ds:dword ptr[st_prev+edi],eax	; surf->prev = surf2->prev;
    559  mov ds:dword ptr[st_prev+esi],edi	; surf2->prev = surf;
    560  mov ds:dword ptr[st_next+eax],edi	; surf2->prev->next = surf;
    561 
    562 ; ---------------------------------------------------------------
    563 ; leading edge done
    564 ; ---------------------------------------------------------------
    565 
    566 ; ---------------------------------------------------------------
    567 ; see if there are any more edges
    568 ; ---------------------------------------------------------------
    569 
    570 Lgs_nextedge:	
    571  mov ebx,ds:dword ptr[et_next+ebx]	
    572  cmp ebx,offset _edge_tail
    573  jnz Lgs_edgeloop	
    574 
    575 ; clean up at the right edge
    576 Lgs_lastspan:	
    577 
    578 ; now that we've reached the right edge of the screen, we're done with any
    579 ; unfinished surfaces, so emit a span for whatever's on top
    580  mov esi,ds:dword ptr[12345678h]	; surfaces[1].st_next
    581 LPatch3:	
    582  mov eax,ds:dword ptr[_edge_tail_u_shift20]	
    583  xor ecx,ecx	
    584  mov edx,ds:dword ptr[st_last_u+esi]	
    585  sub eax,edx	
    586  jle Lgs_resetspanstate	
    587 
    588  mov ds:dword ptr[espan_t_u+ebp],edx	
    589  mov ds:dword ptr[espan_t_count+ebp],eax	
    590  mov eax,ds:dword ptr[_current_iv]	
    591  mov ds:dword ptr[espan_t_v+ebp],eax	
    592  mov eax,ds:dword ptr[st_spans+esi]	
    593  mov ds:dword ptr[espan_t_pnext+ebp],eax	
    594  mov ds:dword ptr[st_spans+esi],ebp	
    595  add ebp,offset espan_t_size	
    596 
    597 ; reset spanstate for all surfaces in the surface stack
    598 Lgs_resetspanstate:	
    599  mov ds:dword ptr[st_spanstate+esi],ecx	
    600  mov esi,ds:dword ptr[st_next+esi]	
    601  cmp esi,012345678h	; &surfaces[1]
    602 LPatch4:	
    603  jnz Lgs_resetspanstate	
    604 
    605 ; store the final span_p
    606  mov ds:dword ptr[_span_p],ebp	
    607 
    608  pop ebx	; restore register variables
    609  pop esi	
    610  pop edi	
    611  pop ebp	; restore the caller's stack frame
    612  ret	
    613 
    614 
    615 ; ---------------------------------------------------------------
    616 ; 1/z sorting for bmodels in the same leaf
    617 ; ---------------------------------------------------------------
    618  align 4	
    619 Lxl_done:	
    620  inc edx	
    621  mov ds:dword ptr[st_spanstate+edi],edx	
    622 
    623  jmp Lgs_nextedge	
    624 
    625 
    626  align 4	
    627 Lzcheck_for_newtop:	
    628  mov eax,ds:dword ptr[et_u+ebx]	
    629  sub eax,0FFFFFh	
    630  mov ds:dword ptr[Ltemp],eax	
    631  fild ds:dword ptr[Ltemp]	
    632 
    633  fmul ds:dword ptr[float_1_div_0100000h]	; fu = (float)(edge->u - 0xFFFFF) *
    634 ;      (1.0 / 0x100000);
    635 
    636  fld st(0)	; fu | fu
    637  fmul ds:dword ptr[st_d_zistepu+edi]	; fu*surf->d_zistepu | fu
    638  fld ds:dword ptr[_fv]	; fv | fu*surf->d_zistepu | fu
    639  fmul ds:dword ptr[st_d_zistepv+edi]	; fv*surf->d_zistepv | fu*surf->d_zistepu | fu
    640  fxch st(1)	; fu*surf->d_zistepu | fv*surf->d_zistepv | fu
    641  fadd ds:dword ptr[st_d_ziorigin+edi]	; fu*surf->d_zistepu + surf->d_ziorigin |
    642 ;  fv*surf->d_zistepv | fu
    643 
    644  fld ds:dword ptr[st_d_zistepu+esi]	; surf2->d_zistepu |
    645 ;  fu*surf->d_zistepu + surf->d_ziorigin |
    646 ;  fv*surf->d_zistepv | fu
    647  fmul st(0),st(3)	; fu*surf2->d_zistepu |
    648 ;  fu*surf->d_zistepu + surf->d_ziorigin |
    649 ;  fv*surf->d_zistepv | fu
    650  fxch st(1)	; fu*surf->d_zistepu + surf->d_ziorigin |
    651 ;  fu*surf2->d_zistepu |
    652 ;  fv*surf->d_zistepv | fu
    653  faddp st(2),st(0)	; fu*surf2->d_zistepu | newzi | fu
    654 
    655  fld ds:dword ptr[_fv]	; fv | fu*surf2->d_zistepu | newzi | fu
    656  fmul ds:dword ptr[st_d_zistepv+esi]	; fv*surf2->d_zistepv |
    657 ;  fu*surf2->d_zistepu | newzi | fu
    658  fld st(2)	; newzi | fv*surf2->d_zistepv |
    659 ;  fu*surf2->d_zistepu | newzi | fu
    660  fmul ds:dword ptr[float_point_999]	; newzibottom | fv*surf2->d_zistepv |
    661 ;  fu*surf2->d_zistepu | newzi | fu
    662 
    663  fxch st(2)	; fu*surf2->d_zistepu | fv*surf2->d_zistepv |
    664 ;  newzibottom | newzi | fu
    665  fadd ds:dword ptr[st_d_ziorigin+esi]	; fu*surf2->d_zistepu + surf2->d_ziorigin |
    666 ;  fv*surf2->d_zistepv | newzibottom | newzi |
    667 ;  fu
    668  faddp st(1),st(0)	; testzi | newzibottom | newzi | fu
    669  fxch st(1)	; newzibottom | testzi | newzi | fu
    670 
    671 ; if (newzibottom >= testzi)
    672 ;     goto newtop;
    673 
    674  fcomp st(1)	; testzi | newzi | fu
    675 
    676  fxch st(1)	; newzi | testzi | fu
    677  fmul ds:dword ptr[float_1_point_001]	; newzitop | testzi | fu
    678  fxch st(1)	; testzi | newzitop | fu
    679 
    680  fnstsw ax	
    681  test ah,001h	
    682  jz Lnewtop_fpop3	
    683 
    684 ; if (newzitop >= testzi)
    685 ; {
    686 
    687  fcomp st(1)	; newzitop | fu
    688  fnstsw ax	
    689  test ah,045h	
    690  jz Lsortloop_fpop2	
    691 
    692 ; if (surf->d_zistepu >= surf2->d_zistepu)
    693 ;     goto newtop;
    694 
    695  fld ds:dword ptr[st_d_zistepu+edi]	; surf->d_zistepu | newzitop | fu
    696  fcomp ds:dword ptr[st_d_zistepu+esi]	; newzitop | fu
    697  fnstsw ax	
    698  test ah,001h	
    699  jz Lnewtop_fpop2	
    700 
    701 Lsortloop_fpop2:	
    702  fstp st(0)	; clear the FP stack
    703  fstp st(0)	
    704  mov eax,ds:dword ptr[st_key+edi]	
    705  jmp Lsortloop	
    706 
    707 
    708  public _R_EdgeCodeEnd	
    709 _R_EdgeCodeEnd:	
    710 
    711 
    712 ;----------------------------------------------------------------------
    713 ; Surface array address code patching routine
    714 ;----------------------------------------------------------------------
    715 
    716  align 4	
    717  public _R_SurfacePatch	
    718 _R_SurfacePatch:	
    719 
    720  mov eax,ds:dword ptr[_surfaces]	
    721  add eax,offset st_size	
    722  mov ds:dword ptr[LPatch4-4],eax	
    723 
    724  add eax,offset st_next	
    725  mov ds:dword ptr[LPatch0-4],eax	
    726  mov ds:dword ptr[LPatch2-4],eax	
    727  mov ds:dword ptr[LPatch3-4],eax	
    728 
    729  ret	
    730 
    731 _TEXT ENDS
    732 endif	;id386
    733  END