123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823 |
- .386P
- .model FLAT
- ;
- ; r_drawa.s
- ; x86 assembly-language edge clipping and emission code
- ;
- include qasm.inc
- include d_if.inc
- if id386
- ; !!! if these are changed, they must be changed in r_draw.c too !!!
- FULLY_CLIPPED_CACHED equ 080000000h
- FRAMECOUNT_MASK equ 07FFFFFFFh
- _DATA SEGMENT
- Ld0 dd 0.0
- Ld1 dd 0.0
- Lstack dd 0
- Lfp_near_clip dd NEAR_CLIP
- Lceilv0 dd 0
- Lv dd 0
- Lu0 dd 0
- Lv0 dd 0
- Lzi0 dd 0
- _DATA ENDS
- _TEXT SEGMENT
- ;----------------------------------------------------------------------
- ; edge clipping code
- ;----------------------------------------------------------------------
- pv0 equ 4+12
- pv1 equ 8+12
- clip equ 12+12
- align 4
- public _R_ClipEdge
- _R_ClipEdge:
- push esi ; preserve register variables
- push edi
- push ebx
- mov ds:dword ptr[Lstack],esp ; for clearing the stack later
- ; float d0, d1, f;
- ; mvertex_t clipvert;
- mov ebx,ds:dword ptr[clip+esp]
- mov esi,ds:dword ptr[pv0+esp]
- mov edx,ds:dword ptr[pv1+esp]
- ; if (clip)
- ; {
- test ebx,ebx
- jz Lemit
- ; do
- ; {
- Lcliploop:
- ; d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
- ; d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
- fld ds:dword ptr[mv_position+0+esi]
- fmul ds:dword ptr[cp_normal+0+ebx]
- fld ds:dword ptr[mv_position+4+esi]
- fmul ds:dword ptr[cp_normal+4+ebx]
- fld ds:dword ptr[mv_position+8+esi]
- fmul ds:dword ptr[cp_normal+8+ebx]
- fxch st(1)
- faddp st(2),st(0) ; d0mul2 | d0add0
- fld ds:dword ptr[mv_position+0+edx]
- fmul ds:dword ptr[cp_normal+0+ebx]
- fld ds:dword ptr[mv_position+4+edx]
- fmul ds:dword ptr[cp_normal+4+ebx]
- fld ds:dword ptr[mv_position+8+edx]
- fmul ds:dword ptr[cp_normal+8+ebx]
- fxch st(1)
- faddp st(2),st(0) ; d1mul2 | d1add0 | d0mul2 | d0add0
- fxch st(3) ; d0add0 | d1add0 | d0mul2 | d1mul2
- faddp st(2),st(0) ; d1add0 | dot0 | d1mul2
- faddp st(2),st(0) ; dot0 | dot1
- fsub ds:dword ptr[cp_dist+ebx] ; d0 | dot1
- fxch st(1) ; dot1 | d0
- fsub ds:dword ptr[cp_dist+ebx] ; d1 | d0
- fxch st(1)
- fstp ds:dword ptr[Ld0]
- fstp ds:dword ptr[Ld1]
- ; if (d0 >= 0)
- ; {
- mov eax,ds:dword ptr[Ld0]
- mov ecx,ds:dword ptr[Ld1]
- or ecx,eax
- js Lp2
- ; both points are unclipped
- Lcontinue:
- ;
- ; R_ClipEdge (&clipvert, pv1, clip->next);
- ; return;
- ; }
- ; } while ((clip = clip->next) != NULL);
- mov ebx,ds:dword ptr[cp_next+ebx]
- test ebx,ebx
- jnz Lcliploop
- ; }
- ;// add the edge
- ; R_EmitEdge (pv0, pv1);
- Lemit:
- ;
- ; set integer rounding to ceil mode, set to single precision
- ;
- ; FIXME: do away with by manually extracting integers from floats?
- ; FIXME: set less often
- fldcw ds:word ptr[_fpu_ceil_cw]
- ; edge_t *edge, *pcheck;
- ; int u_check;
- ; float u, u_step;
- ; vec3_t local, transformed;
- ; float *world;
- ; int v, v2, ceilv0;
- ; float scale, lzi0, u0, v0;
- ; int side;
- ; if (r_lastvertvalid)
- ; {
- cmp ds:dword ptr[_r_lastvertvalid],0
- jz LCalcFirst
- ; u0 = r_u1;
- ; v0 = r_v1;
- ; lzi0 = r_lzi1;
- ; ceilv0 = r_ceilv1;
- mov eax,ds:dword ptr[_r_lzi1]
- mov ecx,ds:dword ptr[_r_u1]
- mov ds:dword ptr[Lzi0],eax
- mov ds:dword ptr[Lu0],ecx
- mov ecx,ds:dword ptr[_r_v1]
- mov eax,ds:dword ptr[_r_ceilv1]
- mov ds:dword ptr[Lv0],ecx
- mov ds:dword ptr[Lceilv0],eax
- jmp LCalcSecond
- ; }
- LCalcFirst:
- ; else
- ; {
- ; world = &pv0->position[0];
- call near ptr LTransformAndProject ; v0 | lzi0 | u0
- fst ds:dword ptr[Lv0]
- fxch st(2) ; u0 | lzi0 | v0
- fstp ds:dword ptr[Lu0] ; lzi0 | v0
- fstp ds:dword ptr[Lzi0] ; v0
- ; ceilv0 = (int)(v0 - 2000) + 2000; // ceil(v0);
- fistp ds:dword ptr[Lceilv0]
- ; }
- LCalcSecond:
- ; world = &pv1->position[0];
- mov esi,edx
- call near ptr LTransformAndProject ; v1 | lzi1 | u1
- fld ds:dword ptr[Lu0] ; u0 | v1 | lzi1 | u1
- fxch st(3) ; u1 | v1 | lzi1 | u0
- fld ds:dword ptr[Lzi0] ; lzi0 | u1 | v1 | lzi1 | u0
- fxch st(3) ; lzi1 | u1 | v1 | lzi0 | u0
- fld ds:dword ptr[Lv0] ; v0 | lzi1 | u1 | v1 | lzi0 | u0
- fxch st(3) ; v1 | lzi1 | u1 | v0 | lzi0 | u0
- ; r_ceilv1 = (int)(r_v1 - 2000) + 2000; // ceil(r_v1);
- fist ds:dword ptr[_r_ceilv1]
- fldcw ds:word ptr[_fpu_chop_cw] ; put back normal floating-point state
- fst ds:dword ptr[_r_v1]
- fxch st(4) ; lzi0 | lzi1 | u1 | v0 | v1 | u0
- ; if (r_lzi1 > lzi0)
- ; lzi0 = r_lzi1;
- fcom st(1)
- fnstsw ax
- test ah,1
- jz LP0
- fstp st(0)
- fld st(0)
- LP0:
- fxch st(1) ; lzi1 | lzi0 | u1 | v0 | v1 | u0
- fstp ds:dword ptr[_r_lzi1] ; lzi0 | u1 | v0 | v1 | u0
- fxch st(1)
- fst ds:dword ptr[_r_u1]
- fxch st(1)
- ; if (lzi0 > r_nearzi) // for mipmap finding
- ; r_nearzi = lzi0;
- fcom ds:dword ptr[_r_nearzi]
- fnstsw ax
- test ah,045h
- jnz LP1
- fst ds:dword ptr[_r_nearzi]
- LP1:
- ; // for right edges, all we want is the effect on 1/z
- ; if (r_nearzionly)
- ; return;
- mov eax,ds:dword ptr[_r_nearzionly]
- test eax,eax
- jz LP2
- LPop5AndDone:
- mov eax,ds:dword ptr[_cacheoffset]
- mov edx,ds:dword ptr[_r_framecount]
- cmp eax,07FFFFFFFh
- jz LDoPop
- and edx,offset FRAMECOUNT_MASK
- or edx,offset FULLY_CLIPPED_CACHED
- mov ds:dword ptr[_cacheoffset],edx
- LDoPop:
- fstp st(0) ; u1 | v0 | v1 | u0
- fstp st(0) ; v0 | v1 | u0
- fstp st(0) ; v1 | u0
- fstp st(0) ; u0
- fstp st(0)
- jmp Ldone
- LP2:
- ; // create the edge
- ; if (ceilv0 == r_ceilv1)
- ; return; // horizontal edge
- mov ebx,ds:dword ptr[Lceilv0]
- mov edi,ds:dword ptr[_edge_p]
- mov ecx,ds:dword ptr[_r_ceilv1]
- mov edx,edi
- mov esi,ds:dword ptr[_r_pedge]
- add edx,offset et_size
- cmp ebx,ecx
- jz LPop5AndDone
- mov eax,ds:dword ptr[_r_pedge]
- mov ds:dword ptr[et_owner+edi],eax
- ; side = ceilv0 > r_ceilv1;
- ;
- ; edge->nearzi = lzi0;
- fstp ds:dword ptr[et_nearzi+edi] ; u1 | v0 | v1 | u0
- ; if (side == 1)
- ; {
- jc LSide0
- LSide1:
- ; // leading edge (go from p2 to p1)
- ; u_step = ((u0 - r_u1) / (v0 - r_v1));
- fsubp st(3),st(0) ; v0 | v1 | u0-u1
- fsub st(0),st(1) ; v0-v1 | v1 | u0-u1
- fdivp st(2),st(0) ; v1 | ustep
- ; r_emitted = 1;
- mov ds:dword ptr[_r_emitted],1
- ; edge = edge_p++;
- mov ds:dword ptr[_edge_p],edx
- ; pretouch next edge
- mov eax,ds:dword ptr[edx]
- ; v2 = ceilv0 - 1;
- ; v = r_ceilv1;
- mov eax,ecx
- lea ecx,ds:dword ptr[-1+ebx]
- mov ebx,eax
- ; edge->surfs[0] = 0;
- ; edge->surfs[1] = surface_p - surfaces;
- mov eax,ds:dword ptr[_surface_p]
- mov esi,ds:dword ptr[_surfaces]
- sub edx,edx
- sub eax,esi
- shr eax,offset SURF_T_SHIFT
- mov ds:dword ptr[et_surfs+edi],edx
- mov ds:dword ptr[et_surfs+2+edi],eax
- sub esi,esi
- ; u = r_u1 + ((float)v - r_v1) * u_step;
- mov ds:dword ptr[Lv],ebx
- fild ds:dword ptr[Lv] ; v | v1 | ustep
- fsubrp st(1),st(0) ; v-v1 | ustep
- fmul st(0),st(1) ; (v-v1)*ustep | ustep
- fadd ds:dword ptr[_r_u1] ; u | ustep
- jmp LSideDone
- ; }
- LSide0:
- ; else
- ; {
- ; // trailing edge (go from p1 to p2)
- ; u_step = ((r_u1 - u0) / (r_v1 - v0));
- fsub st(0),st(3) ; u1-u0 | v0 | v1 | u0
- fxch st(2) ; v1 | v0 | u1-u0 | u0
- fsub st(0),st(1) ; v1-v0 | v0 | u1-u0 | u0
- fdivp st(2),st(0) ; v0 | ustep | u0
- ; r_emitted = 1;
- mov ds:dword ptr[_r_emitted],1
- ; edge = edge_p++;
- mov ds:dword ptr[_edge_p],edx
- ; pretouch next edge
- mov eax,ds:dword ptr[edx]
- ; v = ceilv0;
- ; v2 = r_ceilv1 - 1;
- dec ecx
- ; edge->surfs[0] = surface_p - surfaces;
- ; edge->surfs[1] = 0;
- mov eax,ds:dword ptr[_surface_p]
- mov esi,ds:dword ptr[_surfaces]
- sub edx,edx
- sub eax,esi
- shr eax,offset SURF_T_SHIFT
- mov ds:dword ptr[et_surfs+2+edi],edx
- mov ds:dword ptr[et_surfs+edi],eax
- mov esi,1
- ; u = u0 + ((float)v - v0) * u_step;
- mov ds:dword ptr[Lv],ebx
- fild ds:dword ptr[Lv] ; v | v0 | ustep | u0
- fsubrp st(1),st(0) ; v-v0 | ustep | u0
- fmul st(0),st(1) ; (v-v0)*ustep | ustep | u0
- faddp st(2),st(0) ; ustep | u
- fxch st(1) ; u | ustep
- ; }
- LSideDone:
- ; edge->u_step = u_step*0x100000;
- ; edge->u = u*0x100000 + 0xFFFFF;
- fmul ds:dword ptr[fp_1m] ; u*0x100000 | ustep
- fxch st(1) ; ustep | u*0x100000
- fmul ds:dword ptr[fp_1m] ; ustep*0x100000 | u*0x100000
- fxch st(1) ; u*0x100000 | ustep*0x100000
- fadd ds:dword ptr[fp_1m_minus_1] ; u*0x100000 + 0xFFFFF | ustep*0x100000
- fxch st(1) ; ustep*0x100000 | u*0x100000 + 0xFFFFF
- fistp ds:dword ptr[et_u_step+edi] ; u*0x100000 + 0xFFFFF
- fistp ds:dword ptr[et_u+edi]
- ; // we need to do this to avoid stepping off the edges if a very nearly
- ; // horizontal edge is less than epsilon above a scan, and numeric error
- ; // causes it to incorrectly extend to the scan, and the extension of the
- ; // line goes off the edge of the screen
- ; // FIXME: is this actually needed?
- ; if (edge->u < r_refdef.vrect_x_adj_shift20)
- ; edge->u = r_refdef.vrect_x_adj_shift20;
- ; if (edge->u > r_refdef.vrectright_adj_shift20)
- ; edge->u = r_refdef.vrectright_adj_shift20;
- mov eax,ds:dword ptr[et_u+edi]
- mov edx,ds:dword ptr[_r_refdef+rd_vrect_x_adj_shift20]
- cmp eax,edx
- jl LP4
- mov edx,ds:dword ptr[_r_refdef+rd_vrectright_adj_shift20]
- cmp eax,edx
- jng LP5
- LP4:
- mov ds:dword ptr[et_u+edi],edx
- mov eax,edx
- LP5:
- ; // sort the edge in normally
- ; u_check = edge->u;
- ;
- ; if (edge->surfs[0])
- ; u_check++; // sort trailers after leaders
- add eax,esi
- ; if (!newedges[v] || newedges[v]->u >= u_check)
- ; {
- mov esi,ds:dword ptr[_newedges+ebx*4]
- test esi,esi
- jz LDoFirst
- cmp ds:dword ptr[et_u+esi],eax
- jl LNotFirst
- LDoFirst:
- ; edge->next = newedges[v];
- ; newedges[v] = edge;
- mov ds:dword ptr[et_next+edi],esi
- mov ds:dword ptr[_newedges+ebx*4],edi
- jmp LSetRemove
- ; }
- LNotFirst:
- ; else
- ; {
- ; pcheck = newedges[v];
- ;
- ; while (pcheck->next && pcheck->next->u < u_check)
- ; pcheck = pcheck->next;
- LFindInsertLoop:
- mov edx,esi
- mov esi,ds:dword ptr[et_next+esi]
- test esi,esi
- jz LInsertFound
- cmp ds:dword ptr[et_u+esi],eax
- jl LFindInsertLoop
- LInsertFound:
- ; edge->next = pcheck->next;
- ; pcheck->next = edge;
- mov ds:dword ptr[et_next+edi],esi
- mov ds:dword ptr[et_next+edx],edi
- ; }
- LSetRemove:
- ; edge->nextremove = removeedges[v2];
- ; removeedges[v2] = edge;
- mov eax,ds:dword ptr[_removeedges+ecx*4]
- mov ds:dword ptr[_removeedges+ecx*4],edi
- mov ds:dword ptr[et_nextremove+edi],eax
- Ldone:
- mov esp,ds:dword ptr[Lstack] ; clear temporary variables from stack
- pop ebx ; restore register variables
- pop edi
- pop esi
- ret
- ; at least one point is clipped
- Lp2:
- test eax,eax
- jns Lp1
- ; else
- ; {
- ; // point 0 is clipped
- ; if (d1 < 0)
- ; {
- mov eax,ds:dword ptr[Ld1]
- test eax,eax
- jns Lp3
- ; // both points are clipped
- ; // we do cache fully clipped edges
- ; if (!leftclipped)
- mov eax,ds:dword ptr[_r_leftclipped]
- mov ecx,ds:dword ptr[_r_pedge]
- test eax,eax
- jnz Ldone
- ; r_pedge->framecount = r_framecount;
- mov eax,ds:dword ptr[_r_framecount]
- and eax,offset FRAMECOUNT_MASK
- or eax,offset FULLY_CLIPPED_CACHED
- mov ds:dword ptr[_cacheoffset],eax
- ; return;
- jmp Ldone
- ; }
- Lp1:
- ; // point 0 is unclipped
- ; if (d1 >= 0)
- ; {
- ; // both points are unclipped
- ; continue;
- ; // only point 1 is clipped
- ; f = d0 / (d0 - d1);
- fld ds:dword ptr[Ld0]
- fld ds:dword ptr[Ld1]
- fsubr st(0),st(1)
- ; // we don't cache partially clipped edges
- mov ds:dword ptr[_cacheoffset],07FFFFFFFh
- fdivp st(1),st(0)
- sub esp,offset mv_size ; allocate space for clipvert
- ; clipvert.position[0] = pv0->position[0] +
- ; f * (pv1->position[0] - pv0->position[0]);
- ; clipvert.position[1] = pv0->position[1] +
- ; f * (pv1->position[1] - pv0->position[1]);
- ; clipvert.position[2] = pv0->position[2] +
- ; f * (pv1->position[2] - pv0->position[2]);
- fld ds:dword ptr[mv_position+8+edx]
- fsub ds:dword ptr[mv_position+8+esi]
- fld ds:dword ptr[mv_position+4+edx]
- fsub ds:dword ptr[mv_position+4+esi]
- fld ds:dword ptr[mv_position+0+edx]
- fsub ds:dword ptr[mv_position+0+esi] ; 0 | 1 | 2
- ; replace pv1 with the clip point
- mov edx,esp
- mov eax,ds:dword ptr[cp_leftedge+ebx]
- test al,al
- fmul st(0),st(3)
- fxch st(1) ; 1 | 0 | 2
- fmul st(0),st(3)
- fxch st(2) ; 2 | 0 | 1
- fmulp st(3),st(0) ; 0 | 1 | 2
- fadd ds:dword ptr[mv_position+0+esi]
- fxch st(1) ; 1 | 0 | 2
- fadd ds:dword ptr[mv_position+4+esi]
- fxch st(2) ; 2 | 0 | 1
- fadd ds:dword ptr[mv_position+8+esi]
- fxch st(1) ; 0 | 2 | 1
- fstp ds:dword ptr[mv_position+0+esp] ; 2 | 1
- fstp ds:dword ptr[mv_position+8+esp] ; 1
- fstp ds:dword ptr[mv_position+4+esp]
- ; if (clip->leftedge)
- ; {
- jz Ltestright
- ; r_leftclipped = true;
- ; r_leftexit = clipvert;
- mov ds:dword ptr[_r_leftclipped],1
- mov eax,ds:dword ptr[mv_position+0+esp]
- mov ds:dword ptr[_r_leftexit+mv_position+0],eax
- mov eax,ds:dword ptr[mv_position+4+esp]
- mov ds:dword ptr[_r_leftexit+mv_position+4],eax
- mov eax,ds:dword ptr[mv_position+8+esp]
- mov ds:dword ptr[_r_leftexit+mv_position+8],eax
- jmp Lcontinue
- ; }
- Ltestright:
- ; else if (clip->rightedge)
- ; {
- test ah,ah
- jz Lcontinue
- ; r_rightclipped = true;
- ; r_rightexit = clipvert;
- mov ds:dword ptr[_r_rightclipped],1
- mov eax,ds:dword ptr[mv_position+0+esp]
- mov ds:dword ptr[_r_rightexit+mv_position+0],eax
- mov eax,ds:dword ptr[mv_position+4+esp]
- mov ds:dword ptr[_r_rightexit+mv_position+4],eax
- mov eax,ds:dword ptr[mv_position+8+esp]
- mov ds:dword ptr[_r_rightexit+mv_position+8],eax
- ; }
- ;
- ; R_ClipEdge (pv0, &clipvert, clip->next);
- ; return;
- ; }
- jmp Lcontinue
- ; }
- Lp3:
- ; // only point 0 is clipped
- ; r_lastvertvalid = false;
- mov ds:dword ptr[_r_lastvertvalid],0
- ; f = d0 / (d0 - d1);
- fld ds:dword ptr[Ld0]
- fld ds:dword ptr[Ld1]
- fsubr st(0),st(1)
- ; // we don't cache partially clipped edges
- mov ds:dword ptr[_cacheoffset],07FFFFFFFh
- fdivp st(1),st(0)
- sub esp,offset mv_size ; allocate space for clipvert
- ; clipvert.position[0] = pv0->position[0] +
- ; f * (pv1->position[0] - pv0->position[0]);
- ; clipvert.position[1] = pv0->position[1] +
- ; f * (pv1->position[1] - pv0->position[1]);
- ; clipvert.position[2] = pv0->position[2] +
- ; f * (pv1->position[2] - pv0->position[2]);
- fld ds:dword ptr[mv_position+8+edx]
- fsub ds:dword ptr[mv_position+8+esi]
- fld ds:dword ptr[mv_position+4+edx]
- fsub ds:dword ptr[mv_position+4+esi]
- fld ds:dword ptr[mv_position+0+edx]
- fsub ds:dword ptr[mv_position+0+esi] ; 0 | 1 | 2
- mov eax,ds:dword ptr[cp_leftedge+ebx]
- test al,al
- fmul st(0),st(3)
- fxch st(1) ; 1 | 0 | 2
- fmul st(0),st(3)
- fxch st(2) ; 2 | 0 | 1
- fmulp st(3),st(0) ; 0 | 1 | 2
- fadd ds:dword ptr[mv_position+0+esi]
- fxch st(1) ; 1 | 0 | 2
- fadd ds:dword ptr[mv_position+4+esi]
- fxch st(2) ; 2 | 0 | 1
- fadd ds:dword ptr[mv_position+8+esi]
- fxch st(1) ; 0 | 2 | 1
- fstp ds:dword ptr[mv_position+0+esp] ; 2 | 1
- fstp ds:dword ptr[mv_position+8+esp] ; 1
- fstp ds:dword ptr[mv_position+4+esp]
- ; replace pv0 with the clip point
- mov esi,esp
- ; if (clip->leftedge)
- ; {
- jz Ltestright2
- ; r_leftclipped = true;
- ; r_leftenter = clipvert;
- mov ds:dword ptr[_r_leftclipped],1
- mov eax,ds:dword ptr[mv_position+0+esp]
- mov ds:dword ptr[_r_leftenter+mv_position+0],eax
- mov eax,ds:dword ptr[mv_position+4+esp]
- mov ds:dword ptr[_r_leftenter+mv_position+4],eax
- mov eax,ds:dword ptr[mv_position+8+esp]
- mov ds:dword ptr[_r_leftenter+mv_position+8],eax
- jmp Lcontinue
- ; }
- Ltestright2:
- ; else if (clip->rightedge)
- ; {
- test ah,ah
- jz Lcontinue
- ; r_rightclipped = true;
- ; r_rightenter = clipvert;
- mov ds:dword ptr[_r_rightclipped],1
- mov eax,ds:dword ptr[mv_position+0+esp]
- mov ds:dword ptr[_r_rightenter+mv_position+0],eax
- mov eax,ds:dword ptr[mv_position+4+esp]
- mov ds:dword ptr[_r_rightenter+mv_position+4],eax
- mov eax,ds:dword ptr[mv_position+8+esp]
- mov ds:dword ptr[_r_rightenter+mv_position+8],eax
- ; }
- jmp Lcontinue
- ; %esi = vec3_t point to transform and project
- ; %edx preserved
- LTransformAndProject:
- ; // transform and project
- ; VectorSubtract (world, modelorg, local);
- fld ds:dword ptr[mv_position+0+esi]
- fsub ds:dword ptr[_modelorg+0]
- fld ds:dword ptr[mv_position+4+esi]
- fsub ds:dword ptr[_modelorg+4]
- fld ds:dword ptr[mv_position+8+esi]
- fsub ds:dword ptr[_modelorg+8]
- fxch st(2) ; local[0] | local[1] | local[2]
- ; TransformVector (local, transformed);
- ;
- ; if (transformed[2] < NEAR_CLIP)
- ; transformed[2] = NEAR_CLIP;
- ;
- ; lzi0 = 1.0 / transformed[2];
- fld st(0) ; local[0] | local[0] | local[1] | local[2]
- fmul ds:dword ptr[_vpn+0] ; zm0 | local[0] | local[1] | local[2]
- fld st(1) ; local[0] | zm0 | local[0] | local[1] |
- ; local[2]
- fmul ds:dword ptr[_vright+0] ; xm0 | zm0 | local[0] | local[1] | local[2]
- fxch st(2) ; local[0] | zm0 | xm0 | local[1] | local[2]
- fmul ds:dword ptr[_vup+0] ; ym0 | zm0 | xm0 | local[1] | local[2]
- fld st(3) ; local[1] | ym0 | zm0 | xm0 | local[1] |
- ; local[2]
- fmul ds:dword ptr[_vpn+4] ; zm1 | ym0 | zm0 | xm0 | local[1] |
- ; local[2]
- fld st(4) ; local[1] | zm1 | ym0 | zm0 | xm0 |
- ; local[1] | local[2]
- fmul ds:dword ptr[_vright+4] ; xm1 | zm1 | ym0 | zm0 | xm0 |
- ; local[1] | local[2]
- fxch st(5) ; local[1] | zm1 | ym0 | zm0 | xm0 |
- ; xm1 | local[2]
- fmul ds:dword ptr[_vup+4] ; ym1 | zm1 | ym0 | zm0 | xm0 |
- ; xm1 | local[2]
- fxch st(1) ; zm1 | ym1 | ym0 | zm0 | xm0 |
- ; xm1 | local[2]
- faddp st(3),st(0) ; ym1 | ym0 | zm2 | xm0 | xm1 | local[2]
- fxch st(3) ; xm0 | ym0 | zm2 | ym1 | xm1 | local[2]
- faddp st(4),st(0) ; ym0 | zm2 | ym1 | xm2 | local[2]
- faddp st(2),st(0) ; zm2 | ym2 | xm2 | local[2]
- fld st(3) ; local[2] | zm2 | ym2 | xm2 | local[2]
- fmul ds:dword ptr[_vpn+8] ; zm3 | zm2 | ym2 | xm2 | local[2]
- fld st(4) ; local[2] | zm3 | zm2 | ym2 | xm2 | local[2]
- fmul ds:dword ptr[_vright+8] ; xm3 | zm3 | zm2 | ym2 | xm2 | local[2]
- fxch st(5) ; local[2] | zm3 | zm2 | ym2 | xm2 | xm3
- fmul ds:dword ptr[_vup+8] ; ym3 | zm3 | zm2 | ym2 | xm2 | xm3
- fxch st(1) ; zm3 | ym3 | zm2 | ym2 | xm2 | xm3
- faddp st(2),st(0) ; ym3 | zm4 | ym2 | xm2 | xm3
- fxch st(4) ; xm3 | zm4 | ym2 | xm2 | ym3
- faddp st(3),st(0) ; zm4 | ym2 | xm4 | ym3
- fxch st(1) ; ym2 | zm4 | xm4 | ym3
- faddp st(3),st(0) ; zm4 | xm4 | ym4
- fcom ds:dword ptr[Lfp_near_clip]
- fnstsw ax
- test ah,1
- jz LNoClip
- fstp st(0)
- fld ds:dword ptr[Lfp_near_clip]
- LNoClip:
- fdivr ds:dword ptr[float_1] ; lzi0 | x | y
- fxch st(1) ; x | lzi0 | y
- ; // FIXME: build x/yscale into transform?
- ; scale = xscale * lzi0;
- ; u0 = (xcenter + scale*transformed[0]);
- fld ds:dword ptr[_xscale] ; xscale | x | lzi0 | y
- fmul st(0),st(2) ; scale | x | lzi0 | y
- fmulp st(1),st(0) ; scale*x | lzi0 | y
- fadd ds:dword ptr[_xcenter] ; u0 | lzi0 | y
- ; if (u0 < r_refdef.fvrectx_adj)
- ; u0 = r_refdef.fvrectx_adj;
- ; if (u0 > r_refdef.fvrectright_adj)
- ; u0 = r_refdef.fvrectright_adj;
- ; FIXME: use integer compares of floats?
- fcom ds:dword ptr[_r_refdef+rd_fvrectx_adj]
- fnstsw ax
- test ah,1
- jz LClampP0
- fstp st(0)
- fld ds:dword ptr[_r_refdef+rd_fvrectx_adj]
- LClampP0:
- fcom ds:dword ptr[_r_refdef+rd_fvrectright_adj]
- fnstsw ax
- test ah,045h
- jnz LClampP1
- fstp st(0)
- fld ds:dword ptr[_r_refdef+rd_fvrectright_adj]
- LClampP1:
- fld st(1) ; lzi0 | u0 | lzi0 | y
- ; scale = yscale * lzi0;
- ; v0 = (ycenter - scale*transformed[1]);
- fmul ds:dword ptr[_yscale] ; scale | u0 | lzi0 | y
- fmulp st(3),st(0) ; u0 | lzi0 | scale*y
- fxch st(2) ; scale*y | lzi0 | u0
- fsubr ds:dword ptr[_ycenter] ; v0 | lzi0 | u0
- ; if (v0 < r_refdef.fvrecty_adj)
- ; v0 = r_refdef.fvrecty_adj;
- ; if (v0 > r_refdef.fvrectbottom_adj)
- ; v0 = r_refdef.fvrectbottom_adj;
- ; FIXME: use integer compares of floats?
- fcom ds:dword ptr[_r_refdef+rd_fvrecty_adj]
- fnstsw ax
- test ah,1
- jz LClampP2
- fstp st(0)
- fld ds:dword ptr[_r_refdef+rd_fvrecty_adj]
- LClampP2:
- fcom ds:dword ptr[_r_refdef+rd_fvrectbottom_adj]
- fnstsw ax
- test ah,045h
- jnz LClampP3
- fstp st(0)
- fld ds:dword ptr[_r_refdef+rd_fvrectbottom_adj]
- LClampP3:
- ret
- _TEXT ENDS
- endif ;id386
- END
|