⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_edgea.s

📁 Quake 2 Source code for students by Theerthan You can also download from idsoftwares.com
💻 S
📖 第 1 页 / 共 2 页
字号:
// 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -