mirror of
https://git.code.sf.net/p/quake/quakeforge-old
synced 2024-11-29 15:12:17 +00:00
c3f5581b0a
Unchained, Ultimate, Ultra, Up Yours, Underworld, Underground, Unified, Unity, etc. You know the drill. This takes care of the "standalone" problem with the wrong name, and the recent snafu with multiple developers working on the same files simultaneously...expect me (and probably others) to start locking dirs when updates are taking place. And yes, this update is really as large as it looks. Software only at the moment, but I will have the makefile updated to build the GL builds as well.
750 lines
18 KiB
ArmAsm
750 lines
18 KiB
ArmAsm
/*
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
//
|
|
// r_edgea.s
|
|
// x86 assembly-language edge-processing code.
|
|
//
|
|
|
|
#include "asm_i386.h"
|
|
#include "quakeasm.h"
|
|
#include "asm_draw.h"
|
|
|
|
#if id386
|
|
|
|
.data
|
|
Ltemp: .long 0
|
|
float_1_div_0100000h: .long 0x35800000 // 1.0/(float)0x100000
|
|
float_point_999: .single 0.999
|
|
float_1_point_001: .single 1.001
|
|
|
|
.text
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
#define edgestoadd 4+8 // note odd stack offsets because of interleaving
|
|
#define edgelist 8+12 // with pushes
|
|
|
|
.globl C(R_EdgeCodeStart)
|
|
C(R_EdgeCodeStart):
|
|
|
|
.globl C(R_InsertNewEdges)
|
|
C(R_InsertNewEdges):
|
|
pushl %edi
|
|
pushl %esi // preserve register variables
|
|
movl edgestoadd(%esp),%edx
|
|
pushl %ebx
|
|
movl edgelist(%esp),%ecx
|
|
|
|
LDoNextEdge:
|
|
movl et_u(%edx),%eax
|
|
movl %edx,%edi
|
|
|
|
LContinueSearch:
|
|
movl et_u(%ecx),%ebx
|
|
movl et_next(%ecx),%esi
|
|
cmpl %ebx,%eax
|
|
jle LAddedge
|
|
movl et_u(%esi),%ebx
|
|
movl et_next(%esi),%ecx
|
|
cmpl %ebx,%eax
|
|
jle LAddedge2
|
|
movl et_u(%ecx),%ebx
|
|
movl et_next(%ecx),%esi
|
|
cmpl %ebx,%eax
|
|
jle LAddedge
|
|
movl et_u(%esi),%ebx
|
|
movl et_next(%esi),%ecx
|
|
cmpl %ebx,%eax
|
|
jg LContinueSearch
|
|
|
|
LAddedge2:
|
|
movl et_next(%edx),%edx
|
|
movl et_prev(%esi),%ebx
|
|
movl %esi,et_next(%edi)
|
|
movl %ebx,et_prev(%edi)
|
|
movl %edi,et_next(%ebx)
|
|
movl %edi,et_prev(%esi)
|
|
movl %esi,%ecx
|
|
|
|
cmpl $0,%edx
|
|
jnz LDoNextEdge
|
|
jmp LDone
|
|
|
|
.align 4
|
|
LAddedge:
|
|
movl et_next(%edx),%edx
|
|
movl et_prev(%ecx),%ebx
|
|
movl %ecx,et_next(%edi)
|
|
movl %ebx,et_prev(%edi)
|
|
movl %edi,et_next(%ebx)
|
|
movl %edi,et_prev(%ecx)
|
|
|
|
cmpl $0,%edx
|
|
jnz LDoNextEdge
|
|
|
|
LDone:
|
|
popl %ebx // restore register variables
|
|
popl %esi
|
|
popl %edi
|
|
|
|
ret
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
#define predge 4+4
|
|
|
|
.globl C(R_RemoveEdges)
|
|
C(R_RemoveEdges):
|
|
pushl %ebx
|
|
movl predge(%esp),%eax
|
|
|
|
Lre_loop:
|
|
movl et_next(%eax),%ecx
|
|
movl et_nextremove(%eax),%ebx
|
|
movl et_prev(%eax),%edx
|
|
testl %ebx,%ebx
|
|
movl %edx,et_prev(%ecx)
|
|
jz Lre_done
|
|
movl %ecx,et_next(%edx)
|
|
|
|
movl et_next(%ebx),%ecx
|
|
movl et_prev(%ebx),%edx
|
|
movl et_nextremove(%ebx),%eax
|
|
movl %edx,et_prev(%ecx)
|
|
testl %eax,%eax
|
|
movl %ecx,et_next(%edx)
|
|
jnz Lre_loop
|
|
|
|
popl %ebx
|
|
ret
|
|
|
|
Lre_done:
|
|
movl %ecx,et_next(%edx)
|
|
popl %ebx
|
|
|
|
ret
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
#define pedgelist 4+4 // note odd stack offset because of interleaving
|
|
// with pushes
|
|
|
|
.globl C(R_StepActiveU)
|
|
C(R_StepActiveU):
|
|
pushl %edi
|
|
movl pedgelist(%esp),%edx
|
|
pushl %esi // preserve register variables
|
|
pushl %ebx
|
|
|
|
movl et_prev(%edx),%esi
|
|
|
|
LNewEdge:
|
|
movl et_u(%esi),%edi
|
|
|
|
LNextEdge:
|
|
movl et_u(%edx),%eax
|
|
movl et_u_step(%edx),%ebx
|
|
addl %ebx,%eax
|
|
movl et_next(%edx),%esi
|
|
movl %eax,et_u(%edx)
|
|
cmpl %edi,%eax
|
|
jl LPushBack
|
|
|
|
movl et_u(%esi),%edi
|
|
movl et_u_step(%esi),%ebx
|
|
addl %ebx,%edi
|
|
movl et_next(%esi),%edx
|
|
movl %edi,et_u(%esi)
|
|
cmpl %eax,%edi
|
|
jl LPushBack2
|
|
|
|
movl et_u(%edx),%eax
|
|
movl et_u_step(%edx),%ebx
|
|
addl %ebx,%eax
|
|
movl et_next(%edx),%esi
|
|
movl %eax,et_u(%edx)
|
|
cmpl %edi,%eax
|
|
jl LPushBack
|
|
|
|
movl et_u(%esi),%edi
|
|
movl et_u_step(%esi),%ebx
|
|
addl %ebx,%edi
|
|
movl et_next(%esi),%edx
|
|
movl %edi,et_u(%esi)
|
|
cmpl %eax,%edi
|
|
jnl LNextEdge
|
|
|
|
LPushBack2:
|
|
movl %edx,%ebx
|
|
movl %edi,%eax
|
|
movl %esi,%edx
|
|
movl %ebx,%esi
|
|
|
|
LPushBack:
|
|
// push it back to keep it sorted
|
|
movl et_prev(%edx),%ecx
|
|
movl et_next(%edx),%ebx
|
|
|
|
// done if the -1 in edge_aftertail triggered this
|
|
cmpl $(C(edge_aftertail)),%edx
|
|
jz LUDone
|
|
|
|
// pull the edge out of the edge list
|
|
movl et_prev(%ecx),%edi
|
|
movl %ecx,et_prev(%esi)
|
|
movl %ebx,et_next(%ecx)
|
|
|
|
// find out where the edge goes in the edge list
|
|
LPushBackLoop:
|
|
movl et_prev(%edi),%ecx
|
|
movl et_u(%edi),%ebx
|
|
cmpl %ebx,%eax
|
|
jnl LPushBackFound
|
|
|
|
movl et_prev(%ecx),%edi
|
|
movl et_u(%ecx),%ebx
|
|
cmpl %ebx,%eax
|
|
jl LPushBackLoop
|
|
|
|
movl %ecx,%edi
|
|
|
|
// put the edge back into the edge list
|
|
LPushBackFound:
|
|
movl et_next(%edi),%ebx
|
|
movl %edi,et_prev(%edx)
|
|
movl %ebx,et_next(%edx)
|
|
movl %edx,et_next(%edi)
|
|
movl %edx,et_prev(%ebx)
|
|
|
|
movl %esi,%edx
|
|
movl et_prev(%esi),%esi
|
|
|
|
cmpl $(C(edge_tail)),%edx
|
|
jnz LNewEdge
|
|
|
|
LUDone:
|
|
popl %ebx // restore register variables
|
|
popl %esi
|
|
popl %edi
|
|
|
|
ret
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
#define surf 4 // note this is loaded before any pushes
|
|
|
|
.align 4
|
|
TrailingEdge:
|
|
movl st_spanstate(%esi),%eax // check for edge inversion
|
|
decl %eax
|
|
jnz LInverted
|
|
|
|
movl %eax,st_spanstate(%esi)
|
|
movl st_insubmodel(%esi),%ecx
|
|
movl 0x12345678,%edx // surfaces[1].st_next
|
|
LPatch0:
|
|
movl C(r_bmodelactive),%eax
|
|
subl %ecx,%eax
|
|
cmpl %esi,%edx
|
|
movl %eax,C(r_bmodelactive)
|
|
jnz LNoEmit // surface isn't on top, just remove
|
|
|
|
// emit a span (current top going away)
|
|
movl et_u(%ebx),%eax
|
|
shrl $20,%eax // iu = integral pixel u
|
|
movl st_last_u(%esi),%edx
|
|
movl st_next(%esi),%ecx
|
|
cmpl %edx,%eax
|
|
jle LNoEmit2 // iu <= surf->last_u, so nothing to emit
|
|
|
|
movl %eax,st_last_u(%ecx) // surf->next->last_u = iu;
|
|
subl %edx,%eax
|
|
movl %edx,espan_t_u(%ebp) // span->u = surf->last_u;
|
|
|
|
movl %eax,espan_t_count(%ebp) // span->count = iu - span->u;
|
|
movl C(current_iv),%eax
|
|
movl %eax,espan_t_v(%ebp) // span->v = current_iv;
|
|
movl st_spans(%esi),%eax
|
|
movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans;
|
|
movl %ebp,st_spans(%esi) // surf->spans = span;
|
|
addl $(espan_t_size),%ebp
|
|
|
|
movl st_next(%esi),%edx // remove the surface from the surface
|
|
movl st_prev(%esi),%esi // stack
|
|
|
|
movl %edx,st_next(%esi)
|
|
movl %esi,st_prev(%edx)
|
|
ret
|
|
|
|
LNoEmit2:
|
|
movl %eax,st_last_u(%ecx) // surf->next->last_u = iu;
|
|
movl st_next(%esi),%edx // remove the surface from the surface
|
|
movl st_prev(%esi),%esi // stack
|
|
|
|
movl %edx,st_next(%esi)
|
|
movl %esi,st_prev(%edx)
|
|
ret
|
|
|
|
LNoEmit:
|
|
movl st_next(%esi),%edx // remove the surface from the surface
|
|
movl st_prev(%esi),%esi // stack
|
|
|
|
movl %edx,st_next(%esi)
|
|
movl %esi,st_prev(%edx)
|
|
ret
|
|
|
|
LInverted:
|
|
movl %eax,st_spanstate(%esi)
|
|
ret
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
// trailing edge only
|
|
Lgs_trailing:
|
|
pushl $Lgs_nextedge
|
|
jmp TrailingEdge
|
|
|
|
|
|
.globl C(R_GenerateSpans)
|
|
C(R_GenerateSpans):
|
|
pushl %ebp // preserve caller's stack frame
|
|
pushl %edi
|
|
pushl %esi // preserve register variables
|
|
pushl %ebx
|
|
|
|
// clear active surfaces to just the background surface
|
|
movl C(surfaces),%eax
|
|
movl C(edge_head_u_shift20),%edx
|
|
addl $(st_size),%eax
|
|
// %ebp = span_p throughout
|
|
movl C(span_p),%ebp
|
|
|
|
movl $0,C(r_bmodelactive)
|
|
|
|
movl %eax,st_next(%eax)
|
|
movl %eax,st_prev(%eax)
|
|
movl %edx,st_last_u(%eax)
|
|
movl C(edge_head)+et_next,%ebx // edge=edge_head.next
|
|
|
|
// generate spans
|
|
cmpl $(C(edge_tail)),%ebx // done if empty list
|
|
jz Lgs_lastspan
|
|
|
|
Lgs_edgeloop:
|
|
|
|
movl et_surfs(%ebx),%edi
|
|
movl C(surfaces),%eax
|
|
movl %edi,%esi
|
|
andl $0xFFFF0000,%edi
|
|
andl $0xFFFF,%esi
|
|
jz Lgs_leading // not a trailing edge
|
|
|
|
// it has a left surface, so a surface is going away for this span
|
|
shll $(SURF_T_SHIFT),%esi
|
|
addl %eax,%esi
|
|
testl %edi,%edi
|
|
jz Lgs_trailing
|
|
|
|
// both leading and trailing
|
|
call TrailingEdge
|
|
movl C(surfaces),%eax
|
|
|
|
// ---------------------------------------------------------------
|
|
// handle a leading edge
|
|
// ---------------------------------------------------------------
|
|
|
|
Lgs_leading:
|
|
shrl $16-SURF_T_SHIFT,%edi
|
|
movl C(surfaces),%eax
|
|
addl %eax,%edi
|
|
movl 0x12345678,%esi // surf2 = surfaces[1].next;
|
|
LPatch2:
|
|
movl st_spanstate(%edi),%edx
|
|
movl st_insubmodel(%edi),%eax
|
|
testl %eax,%eax
|
|
jnz Lbmodel_leading
|
|
|
|
// handle a leading non-bmodel edge
|
|
|
|
// don't start a span if this is an inverted span, with the end edge preceding
|
|
// the start edge (that is, we've already seen the end edge)
|
|
testl %edx,%edx
|
|
jnz Lxl_done
|
|
|
|
|
|
// if (surf->key < surf2->key)
|
|
// goto newtop;
|
|
incl %edx
|
|
movl st_key(%edi),%eax
|
|
movl %edx,st_spanstate(%edi)
|
|
movl st_key(%esi),%ecx
|
|
cmpl %ecx,%eax
|
|
jl Lnewtop
|
|
|
|
// main sorting loop to search through surface stack until insertion point
|
|
// found. Always terminates because background surface is sentinel
|
|
// do
|
|
// {
|
|
// surf2 = surf2->next;
|
|
// } while (surf->key >= surf2->key);
|
|
Lsortloopnb:
|
|
movl st_next(%esi),%esi
|
|
movl st_key(%esi),%ecx
|
|
cmpl %ecx,%eax
|
|
jge Lsortloopnb
|
|
|
|
jmp LInsertAndExit
|
|
|
|
|
|
// handle a leading bmodel edge
|
|
.align 4
|
|
Lbmodel_leading:
|
|
|
|
// don't start a span if this is an inverted span, with the end edge preceding
|
|
// the start edge (that is, we've already seen the end edge)
|
|
testl %edx,%edx
|
|
jnz Lxl_done
|
|
|
|
movl C(r_bmodelactive),%ecx
|
|
incl %edx
|
|
incl %ecx
|
|
movl %edx,st_spanstate(%edi)
|
|
movl %ecx,C(r_bmodelactive)
|
|
|
|
// if (surf->key < surf2->key)
|
|
// goto newtop;
|
|
movl st_key(%edi),%eax
|
|
movl st_key(%esi),%ecx
|
|
cmpl %ecx,%eax
|
|
jl Lnewtop
|
|
|
|
// if ((surf->key == surf2->key) && surf->insubmodel)
|
|
// {
|
|
jz Lzcheck_for_newtop
|
|
|
|
// main sorting loop to search through surface stack until insertion point
|
|
// found. Always terminates because background surface is sentinel
|
|
// do
|
|
// {
|
|
// surf2 = surf2->next;
|
|
// } while (surf->key > surf2->key);
|
|
Lsortloop:
|
|
movl st_next(%esi),%esi
|
|
movl st_key(%esi),%ecx
|
|
cmpl %ecx,%eax
|
|
jg Lsortloop
|
|
|
|
jne LInsertAndExit
|
|
|
|
// Do 1/z sorting to see if we've arrived in the right position
|
|
movl et_u(%ebx),%eax
|
|
subl $0xFFFFF,%eax
|
|
movl %eax,Ltemp
|
|
fildl Ltemp
|
|
|
|
fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) *
|
|
// (1.0 / 0x100000);
|
|
|
|
fld %st(0) // fu | fu
|
|
fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu
|
|
flds C(fv) // fv | fu*surf->d_zistepu | fu
|
|
fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu
|
|
fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu
|
|
fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin |
|
|
// fv*surf->d_zistepv | fu
|
|
|
|
flds st_d_zistepu(%esi) // surf2->d_zistepu |
|
|
// fu*surf->d_zistepu + surf->d_ziorigin |
|
|
// fv*surf->d_zistepv | fu
|
|
fmul %st(3),%st(0) // fu*surf2->d_zistepu |
|
|
// fu*surf->d_zistepu + surf->d_ziorigin |
|
|
// fv*surf->d_zistepv | fu
|
|
fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin |
|
|
// fu*surf2->d_zistepu |
|
|
// fv*surf->d_zistepv | fu
|
|
faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu
|
|
|
|
flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu
|
|
fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv |
|
|
// fu*surf2->d_zistepu | newzi | fu
|
|
fld %st(2) // newzi | fv*surf2->d_zistepv |
|
|
// fu*surf2->d_zistepu | newzi | fu
|
|
fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv |
|
|
// fu*surf2->d_zistepu | newzi | fu
|
|
|
|
fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv |
|
|
// newzibottom | newzi | fu
|
|
fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin |
|
|
// fv*surf2->d_zistepv | newzibottom | newzi |
|
|
// fu
|
|
faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu
|
|
fxch %st(1) // newzibottom | testzi | newzi | fu
|
|
|
|
// if (newzibottom >= testzi)
|
|
// goto Lgotposition;
|
|
|
|
fcomp %st(1) // testzi | newzi | fu
|
|
|
|
fxch %st(1) // newzi | testzi | fu
|
|
fmuls float_1_point_001 // newzitop | testzi | fu
|
|
fxch %st(1) // testzi | newzitop | fu
|
|
|
|
fnstsw %ax
|
|
testb $0x01,%ah
|
|
jz Lgotposition_fpop3
|
|
|
|
// if (newzitop >= testzi)
|
|
// {
|
|
|
|
fcomp %st(1) // newzitop | fu
|
|
fnstsw %ax
|
|
testb $0x45,%ah
|
|
jz Lsortloop_fpop2
|
|
|
|
// if (surf->d_zistepu >= surf2->d_zistepu)
|
|
// goto newtop;
|
|
|
|
flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop| fu
|
|
fcomps st_d_zistepu(%esi) // newzitop | fu
|
|
fnstsw %ax
|
|
testb $0x01,%ah
|
|
jz Lgotposition_fpop2
|
|
|
|
fstp %st(0) // clear the FPstack
|
|
fstp %st(0)
|
|
movl st_key(%edi),%eax
|
|
jmp Lsortloop
|
|
|
|
|
|
Lgotposition_fpop3:
|
|
fstp %st(0)
|
|
Lgotposition_fpop2:
|
|
fstp %st(0)
|
|
fstp %st(0)
|
|
jmp LInsertAndExit
|
|
|
|
|
|
// emit a span (obscures current top)
|
|
|
|
Lnewtop_fpop3:
|
|
fstp %st(0)
|
|
Lnewtop_fpop2:
|
|
fstp %st(0)
|
|
fstp %st(0)
|
|
movl st_key(%edi),%eax // reload the sorting key
|
|
|
|
Lnewtop:
|
|
movl et_u(%ebx),%eax
|
|
movl st_last_u(%esi),%edx
|
|
shrl $20,%eax // iu = integral pixel u
|
|
movl %eax,st_last_u(%edi) // surf->last_u = iu;
|
|
cmpl %edx,%eax
|
|
jle LInsertAndExit // iu <= surf->last_u, so nothing to emit
|
|
|
|
subl %edx,%eax
|
|
movl %edx,espan_t_u(%ebp) // span->u = surf->last_u;
|
|
|
|
movl %eax,espan_t_count(%ebp) // span->count = iu - span->u;
|
|
movl C(current_iv),%eax
|
|
movl %eax,espan_t_v(%ebp) // span->v = current_iv;
|
|
movl st_spans(%esi),%eax
|
|
movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans;
|
|
movl %ebp,st_spans(%esi) // surf->spans = span;
|
|
addl $(espan_t_size),%ebp
|
|
|
|
LInsertAndExit:
|
|
// insert before surf2
|
|
movl %esi,st_next(%edi) // surf->next = surf2;
|
|
movl st_prev(%esi),%eax
|
|
movl %eax,st_prev(%edi) // surf->prev = surf2->prev;
|
|
movl %edi,st_prev(%esi) // surf2->prev = surf;
|
|
movl %edi,st_next(%eax) // surf2->prev->next = surf;
|
|
|
|
// ---------------------------------------------------------------
|
|
// leading edge done
|
|
// ---------------------------------------------------------------
|
|
|
|
// ---------------------------------------------------------------
|
|
// see if there are any more edges
|
|
// ---------------------------------------------------------------
|
|
|
|
Lgs_nextedge:
|
|
movl et_next(%ebx),%ebx
|
|
cmpl $(C(edge_tail)),%ebx
|
|
jnz Lgs_edgeloop
|
|
|
|
// clean up at the right edge
|
|
Lgs_lastspan:
|
|
|
|
// now that we've reached the right edge of the screen, we're done with any
|
|
// unfinished surfaces, so emit a span for whatever's on top
|
|
movl 0x12345678,%esi // surfaces[1].st_next
|
|
LPatch3:
|
|
movl C(edge_tail_u_shift20),%eax
|
|
xorl %ecx,%ecx
|
|
movl st_last_u(%esi),%edx
|
|
subl %edx,%eax
|
|
jle Lgs_resetspanstate
|
|
|
|
movl %edx,espan_t_u(%ebp)
|
|
movl %eax,espan_t_count(%ebp)
|
|
movl C(current_iv),%eax
|
|
movl %eax,espan_t_v(%ebp)
|
|
movl st_spans(%esi),%eax
|
|
movl %eax,espan_t_pnext(%ebp)
|
|
movl %ebp,st_spans(%esi)
|
|
addl $(espan_t_size),%ebp
|
|
|
|
// reset spanstate for all surfaces in the surface stack
|
|
Lgs_resetspanstate:
|
|
movl %ecx,st_spanstate(%esi)
|
|
movl st_next(%esi),%esi
|
|
cmpl $0x12345678,%esi // &surfaces[1]
|
|
LPatch4:
|
|
jnz Lgs_resetspanstate
|
|
|
|
// store the final span_p
|
|
movl %ebp,C(span_p)
|
|
|
|
popl %ebx // restore register variables
|
|
popl %esi
|
|
popl %edi
|
|
popl %ebp // restore the caller's stack frame
|
|
ret
|
|
|
|
|
|
// ---------------------------------------------------------------
|
|
// 1/z sorting for bmodels in the same leaf
|
|
// ---------------------------------------------------------------
|
|
.align 4
|
|
Lxl_done:
|
|
incl %edx
|
|
movl %edx,st_spanstate(%edi)
|
|
|
|
jmp Lgs_nextedge
|
|
|
|
|
|
.align 4
|
|
Lzcheck_for_newtop:
|
|
movl et_u(%ebx),%eax
|
|
subl $0xFFFFF,%eax
|
|
movl %eax,Ltemp
|
|
fildl Ltemp
|
|
|
|
fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) *
|
|
// (1.0 / 0x100000);
|
|
|
|
fld %st(0) // fu | fu
|
|
fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu
|
|
flds C(fv) // fv | fu*surf->d_zistepu | fu
|
|
fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu
|
|
fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu
|
|
fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin |
|
|
// fv*surf->d_zistepv | fu
|
|
|
|
flds st_d_zistepu(%esi) // surf2->d_zistepu |
|
|
// fu*surf->d_zistepu + surf->d_ziorigin |
|
|
// fv*surf->d_zistepv | fu
|
|
fmul %st(3),%st(0) // fu*surf2->d_zistepu |
|
|
// fu*surf->d_zistepu + surf->d_ziorigin |
|
|
// fv*surf->d_zistepv | fu
|
|
fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin |
|
|
// fu*surf2->d_zistepu |
|
|
// fv*surf->d_zistepv | fu
|
|
faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu
|
|
|
|
flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu
|
|
fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv |
|
|
// fu*surf2->d_zistepu | newzi | fu
|
|
fld %st(2) // newzi | fv*surf2->d_zistepv |
|
|
// fu*surf2->d_zistepu | newzi | fu
|
|
fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv |
|
|
// fu*surf2->d_zistepu | newzi | fu
|
|
|
|
fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv |
|
|
// newzibottom | newzi | fu
|
|
fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin |
|
|
// fv*surf2->d_zistepv | newzibottom | newzi |
|
|
// fu
|
|
faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu
|
|
fxch %st(1) // newzibottom | testzi | newzi | fu
|
|
|
|
// if (newzibottom >= testzi)
|
|
// goto newtop;
|
|
|
|
fcomp %st(1) // testzi | newzi | fu
|
|
|
|
fxch %st(1) // newzi | testzi | fu
|
|
fmuls float_1_point_001 // newzitop | testzi | fu
|
|
fxch %st(1) // testzi | newzitop | fu
|
|
|
|
fnstsw %ax
|
|
testb $0x01,%ah
|
|
jz Lnewtop_fpop3
|
|
|
|
// if (newzitop >= testzi)
|
|
// {
|
|
|
|
fcomp %st(1) // newzitop | fu
|
|
fnstsw %ax
|
|
testb $0x45,%ah
|
|
jz Lsortloop_fpop2
|
|
|
|
// if (surf->d_zistepu >= surf2->d_zistepu)
|
|
// goto newtop;
|
|
|
|
flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop | fu
|
|
fcomps st_d_zistepu(%esi) // newzitop | fu
|
|
fnstsw %ax
|
|
testb $0x01,%ah
|
|
jz Lnewtop_fpop2
|
|
|
|
Lsortloop_fpop2:
|
|
fstp %st(0) // clear the FP stack
|
|
fstp %st(0)
|
|
movl st_key(%edi),%eax
|
|
jmp Lsortloop
|
|
|
|
|
|
.globl C(R_EdgeCodeEnd)
|
|
C(R_EdgeCodeEnd):
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// Surface array address code patching routine
|
|
//----------------------------------------------------------------------
|
|
|
|
.align 4
|
|
.globl C(R_SurfacePatch)
|
|
C(R_SurfacePatch):
|
|
|
|
movl C(surfaces),%eax
|
|
addl $(st_size),%eax
|
|
movl %eax,LPatch4-4
|
|
|
|
addl $(st_next),%eax
|
|
movl %eax,LPatch0-4
|
|
movl %eax,LPatch2-4
|
|
movl %eax,LPatch3-4
|
|
|
|
ret
|
|
|
|
#endif // id386
|
|
|