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

📄 r_draw16.s

📁 Quake 2 Source code for students by Theerthan You can also download from idsoftwares.com
💻 S
📖 第 1 页 / 共 2 页
字号:
// set up advancetable
//
	movl	entryvec_table_16(,%ecx,4),%ebx
	movl	%edx,%eax
	movl	%ebx,jumptemp		// entry point into code for RET later
	movl	%ebp,%ecx
	sarl	$16,%edx			// tstep >>= 16;
	movl	C(cachewidth),%ebx
	sarl	$16,%ecx			// sstep >>= 16;
	imull	%ebx,%edx

	addl	%ecx,%edx			// add in sstep
								// (tstep >> 16) * cachewidth + (sstep >> 16);
	movl	tfracf,%ecx
	movl	%edx,advancetable+4	// advance base in t
	addl	%ebx,%edx			// ((tstep >> 16) + 1) * cachewidth +
								//  (sstep >> 16);
	shll	$16,%ebp			// left-justify sstep fractional part
	movl	sfracf,%ebx
	shll	$16,%eax			// left-justify tstep fractional part
	movl	%edx,advancetable	// advance extra in t

	movl	%eax,tstep
	movl	%ecx,%edx
	addl	%eax,%edx
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi

	jmp		*jumptemp			// jump to the number-of-pixels handler

//----------------------------------------

LNoSteps:
	movb	(%esi),%al		// load first texel in segment
	subl	$15,%edi			// adjust for hardwired offset
	jmp		LEndSpan


LOnlyOneStep:
	subl	s,%eax
	subl	t,%ebx
	movl	%eax,%ebp
	movl	%ebx,%edx
	jmp		LSetEntryvec

//----------------------------------------

.globl	Entry2_16, Entry3_16, Entry4_16, Entry5_16
.globl	Entry6_16, Entry7_16, Entry8_16, Entry9_16
.globl	Entry10_16, Entry11_16, Entry12_16, Entry13_16
.globl	Entry14_16, Entry15_16, Entry16_16

Entry2_16:
	subl	$14,%edi		// adjust for hardwired offsets
	movb	(%esi),%al
	jmp		LEntry2_16

//----------------------------------------

Entry3_16:
	subl	$13,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	jmp		LEntry3_16

//----------------------------------------

Entry4_16:
	subl	$12,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry4_16

//----------------------------------------

Entry5_16:
	subl	$11,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry5_16

//----------------------------------------

Entry6_16:
	subl	$10,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry6_16

//----------------------------------------

Entry7_16:
	subl	$9,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry7_16

//----------------------------------------

Entry8_16:
	subl	$8,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry8_16

//----------------------------------------

Entry9_16:
	subl	$7,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry9_16

//----------------------------------------

Entry10_16:
	subl	$6,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry10_16

//----------------------------------------

Entry11_16:
	subl	$5,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry11_16

//----------------------------------------

Entry12_16:
	subl	$4,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry12_16

//----------------------------------------

Entry13_16:
	subl	$3,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry13_16

//----------------------------------------

Entry14_16:
	subl	$2,%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry14_16

//----------------------------------------

Entry15_16:
	decl	%edi		// adjust for hardwired offsets
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
	jmp		LEntry15_16

//----------------------------------------

Entry16_16:
	addl	%eax,%edx
	movb	(%esi),%al
	sbbl	%ecx,%ecx
	addl	%ebp,%ebx
	adcl	advancetable+4(,%ecx,4),%esi

	addl	tstep,%edx
	sbbl	%ecx,%ecx
	movb	%al,1(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry15_16:
	sbbl	%ecx,%ecx
	movb	%al,2(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry14_16:
	sbbl	%ecx,%ecx
	movb	%al,3(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry13_16:
	sbbl	%ecx,%ecx
	movb	%al,4(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry12_16:
	sbbl	%ecx,%ecx
	movb	%al,5(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry11_16:
	sbbl	%ecx,%ecx
	movb	%al,6(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry10_16:
	sbbl	%ecx,%ecx
	movb	%al,7(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry9_16:
	sbbl	%ecx,%ecx
	movb	%al,8(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry8_16:
	sbbl	%ecx,%ecx
	movb	%al,9(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry7_16:
	sbbl	%ecx,%ecx
	movb	%al,10(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry6_16:
	sbbl	%ecx,%ecx
	movb	%al,11(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry5_16:
	sbbl	%ecx,%ecx
	movb	%al,12(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
	addl	tstep,%edx
LEntry4_16:
	sbbl	%ecx,%ecx
	movb	%al,13(%edi)
	addl	%ebp,%ebx
	movb	(%esi),%al
	adcl	advancetable+4(,%ecx,4),%esi
LEntry3_16:
	movb	%al,14(%edi)
	movb	(%esi),%al
LEntry2_16:

LEndSpan:

//
// clear s/z, t/z, 1/z from FP stack
//
	fstp %st(0)
	fstp %st(0)
	fstp %st(0)

	movl	pspantemp,%ebx				// restore spans pointer
	movl	espan_t_pnext(%ebx),%ebx	// point to next span
	testl	%ebx,%ebx			// any more spans?
	movb	%al,15(%edi)
	jnz		LSpanLoop			// more spans

	popl	%ebx				// restore register variables
	popl	%esi
	popl	%edi
	popl	%ebp				// restore the caller's stack frame
	ret

//----------------------------------------------------------------------
// 8-bpp horizontal span z drawing codefor polygons, with no transparency.
//
// Assumes there is at least one span in pzspans, and that every span
// contains at least one pixel
//----------------------------------------------------------------------

	.text

// z-clamp on a non-negative gradient span
LClamp:
	movl	$0x40000000,%edx
	xorl	%ebx,%ebx
	fstp	%st(0)
	jmp		LZDraw

// z-clamp on a negative gradient span
LClampNeg:
	movl	$0x40000000,%edx
	xorl	%ebx,%ebx
	fstp	%st(0)
	jmp		LZDrawNeg


#define pzspans	4+16

.globl C(D_DrawZSpans)
C(D_DrawZSpans):
	pushl	%ebp				// preserve caller's stack frame
	pushl	%edi
	pushl	%esi				// preserve register variables
	pushl	%ebx

	flds	C(d_zistepu)
	movl	C(d_zistepu),%eax
	movl	pzspans(%esp),%esi
	testl	%eax,%eax
	jz		LFNegSpan

	fmuls	Float2ToThe31nd
	fistpl	izistep		// note: we are relying on FP exceptions being turned
						// off here to avoid range problems
	movl	izistep,%ebx	// remains loaded for all spans

LFSpanLoop:
// set up the initial 1/z value
	fildl	espan_t_v(%esi)
	fildl	espan_t_u(%esi)
	movl	espan_t_v(%esi),%ecx
	movl	C(d_pzbuffer),%edi
	fmuls	C(d_zistepu)
	fxch	%st(1)
	fmuls	C(d_zistepv)
	fxch	%st(1)
	fadds	C(d_ziorigin)
	imull	C(d_zrowbytes),%ecx
	faddp	%st(0),%st(1)

// clamp if z is nearer than 2 (1/z > 0.5)
	fcoms	float_point5
	addl	%ecx,%edi
	movl	espan_t_u(%esi),%edx
	addl	%edx,%edx				// word count
	movl	espan_t_count(%esi),%ecx
	addl	%edx,%edi				// pdest = &pdestspan[scans->u];
	pushl	%esi		// preserve spans pointer
	fnstsw	%ax
	testb	$0x45,%ah
	jz		LClamp

	fmuls	Float2ToThe31nd
	fistpl	izi			// note: we are relying on FP exceptions being turned
						// off here to avoid problems when the span is closer
						// than 1/(2**31)
	movl	izi,%edx

// at this point:
// %ebx = izistep
// %ecx = count
// %edx = izi
// %edi = pdest

LZDraw:

// do a single pixel up front, if necessary to dword align the destination
	testl	$2,%edi
	jz		LFMiddle
	movl	%edx,%eax
	addl	%ebx,%edx
	shrl	$16,%eax
	decl	%ecx
	movw	%ax,(%edi)
	addl	$2,%edi

// do middle a pair of aligned dwords at a time
LFMiddle:
	pushl	%ecx
	shrl	$1,%ecx				// count / 2
	jz		LFLast				// no aligned dwords to do
	shrl	$1,%ecx				// (count / 2) / 2
	jnc		LFMiddleLoop		// even number of aligned dwords to do

	movl	%edx,%eax
	addl	%ebx,%edx
	shrl	$16,%eax
	movl	%edx,%esi
	addl	%ebx,%edx
	andl	$0xFFFF0000,%esi
	orl		%esi,%eax
	movl	%eax,(%edi)
	addl	$4,%edi
	andl	%ecx,%ecx
	jz		LFLast

LFMiddleLoop:
	movl	%edx,%eax
	addl	%ebx,%edx
	shrl	$16,%eax
	movl	%edx,%esi
	addl	%ebx,%edx
	andl	$0xFFFF0000,%esi
	orl		%esi,%eax
	movl	%edx,%ebp
	movl	%eax,(%edi)
	addl	%ebx,%edx
	shrl	$16,%ebp
	movl	%edx,%esi
	addl	%ebx,%edx
	andl	$0xFFFF0000,%esi
	orl		%esi,%ebp
	movl	%ebp,4(%edi)	// FIXME: eliminate register contention
	addl	$8,%edi

	decl	%ecx
	jnz		LFMiddleLoop

LFLast:
	popl	%ecx			// retrieve count
	popl	%esi			// retrieve span pointer

// do the last, unaligned pixel, if there is one
	andl	$1,%ecx			// is there an odd pixel left to do?
	jz		LFSpanDone		// no
	shrl	$16,%edx
	movw	%dx,(%edi)		// do the final pixel's z

LFSpanDone:
	movl	espan_t_pnext(%esi),%esi
	testl	%esi,%esi
	jnz		LFSpanLoop

	jmp		LFDone

LFNegSpan:
	fmuls	FloatMinus2ToThe31nd
	fistpl	izistep		// note: we are relying on FP exceptions being turned
						// off here to avoid range problems
	movl	izistep,%ebx	// remains loaded for all spans

LFNegSpanLoop:
// set up the initial 1/z value
	fildl	espan_t_v(%esi)
	fildl	espan_t_u(%esi)
	movl	espan_t_v(%esi),%ecx
	movl	C(d_pzbuffer),%edi
	fmuls	C(d_zistepu)
	fxch	%st(1)
	fmuls	C(d_zistepv)
	fxch	%st(1)
	fadds	C(d_ziorigin)
	imull	C(d_zrowbytes),%ecx
	faddp	%st(0),%st(1)

// clamp if z is nearer than 2 (1/z > 0.5)
	fcoms	float_point5
	addl	%ecx,%edi
	movl	espan_t_u(%esi),%edx
	addl	%edx,%edx				// word count
	movl	espan_t_count(%esi),%ecx
	addl	%edx,%edi				// pdest = &pdestspan[scans->u];
	pushl	%esi		// preserve spans pointer
	fnstsw	%ax
	testb	$0x45,%ah
	jz		LClampNeg

	fmuls	Float2ToThe31nd
	fistpl	izi			// note: we are relying on FP exceptions being turned
						// off here to avoid problems when the span is closer
						// than 1/(2**31)
	movl	izi,%edx

// at this point:
// %ebx = izistep
// %ecx = count
// %edx = izi
// %edi = pdest

LZDrawNeg:

// do a single pixel up front, if necessary to dword align the destination
	testl	$2,%edi
	jz		LFNegMiddle
	movl	%edx,%eax
	subl	%ebx,%edx
	shrl	$16,%eax
	decl	%ecx
	movw	%ax,(%edi)
	addl	$2,%edi

// do middle a pair of aligned dwords at a time
LFNegMiddle:
	pushl	%ecx
	shrl	$1,%ecx				// count / 2
	jz		LFNegLast			// no aligned dwords to do
	shrl	$1,%ecx				// (count / 2) / 2
	jnc		LFNegMiddleLoop		// even number of aligned dwords to do

	movl	%edx,%eax
	subl	%ebx,%edx
	shrl	$16,%eax
	movl	%edx,%esi
	subl	%ebx,%edx
	andl	$0xFFFF0000,%esi
	orl		%esi,%eax
	movl	%eax,(%edi)
	addl	$4,%edi
	andl	%ecx,%ecx
	jz		LFNegLast

LFNegMiddleLoop:
	movl	%edx,%eax
	subl	%ebx,%edx
	shrl	$16,%eax
	movl	%edx,%esi
	subl	%ebx,%edx
	andl	$0xFFFF0000,%esi
	orl		%esi,%eax
	movl	%edx,%ebp
	movl	%eax,(%edi)
	subl	%ebx,%edx
	shrl	$16,%ebp
	movl	%edx,%esi
	subl	%ebx,%edx
	andl	$0xFFFF0000,%esi
	orl		%esi,%ebp
	movl	%ebp,4(%edi)	// FIXME: eliminate register contention
	addl	$8,%edi

	decl	%ecx
	jnz		LFNegMiddleLoop

LFNegLast:
	popl	%ecx			// retrieve count
	popl	%esi			// retrieve span pointer

// do the last, unaligned pixel, if there is one
	andl	$1,%ecx			// is there an odd pixel left to do?
	jz		LFNegSpanDone	// no
	shrl	$16,%edx
	movw	%dx,(%edi)		// do the final pixel's z

LFNegSpanDone:
	movl	espan_t_pnext(%esi),%esi
	testl	%esi,%esi
	jnz		LFNegSpanLoop

LFDone:
	popl	%ebx				// restore register variables
	popl	%esi
	popl	%edi
	popl	%ebp				// restore the caller's stack frame
	ret

#endif	// id386

⌨️ 快捷键说明

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