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

📄 r_edgea.s

📁 Quake 2 Source code for students by Theerthan You can also download from idsoftwares.com
💻 S
📖 第 1 页 / 共 2 页
字号:
//
// r_edgea.s
// x86 assembly-language edge-processing code.
//

#include "qasm.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

⌨️ 快捷键说明

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