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

📄 r_drawa.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//100%
{$ALIGN 8}{$MINENUMSIZE 4}
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): r_drawa.asm                                                       }
{                                                                            }
{ Initial conversion by : Carl Kenner (carl_kenner@hotmail.com)              }
{ Initial conversion on : 25-Feb-2002                                        }
{                                                                            }
{ This File contains part of convertion of Quake2 source to ObjectPascal.    }
{ More information about this project can be found at:                       }
{ http://www.sulaco.co.za/quake2/                                            }
{                                                                            }
{ Copyright (C) 1997-2001 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.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ Updated on :                                                               }
{ Updated by :                                                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{ none                                                                       }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{ Test it!!!!                                                                }
{----------------------------------------------------------------------------}
unit r_drawa;

{$DEFINE NODEPEND}

interface

procedure R_ClipEdge;

implementation
uses Windows,
  r_rast,
  r_local,
{$IFNDEF NODEPEND}rw_Imp,
{$ENDIF}qasm_inc,
  d_if_inc,
  r_varsa;
{$DEFINE id386}
{$IFDEF id386}

{$IFDEF NODEPEND}
var
  fpu_ceil_cw, fpu_chop_cw, fpu_full_cw, fpu_cw, fpu_pushed_cw: Word;
  fpu_sp24_cw, fpu_sp24_ceil_cw: Word;

// CAK - This function calculates the floating point control words
// CAK - needed for various floating point modes (rounding, truncating, etc.)
// CAK - and stores them in the variables.
// CAK - This function doesn't actually change the floating point control word
// CAK - in the Maths coprocessor, or do anything harmful.

procedure Sys_SetFPCW; assembler;
asm
  xor eax, eax                  // CAK   eax = 0
  fnstcw  word ptr fpu_cw       // CAK   fpu_cw = Maths Coprocessor's Floating Point Control Word
  mov ax, word ptr fpu_cw       // CAK   ax = fpu_cw

  and ah, 0f0h
  or  ah, 003h          // round to nearest mode, extended precision
  mov fpu_full_cw, ax

  and ah, 0f0h
  or  ah, 00fh          // RTZ/truncate/chop mode, extended precision
  mov fpu_chop_cw, ax

  and ah, 0f0h
  or  ah, 00bh          // ceil mode, extended precision
  mov fpu_ceil_cw, ax

  and ah, 0f0h          // round to nearest, 24-bit single precision
  mov fpu_sp24_cw, ax

  and ah, 0f0h          // ceil mode, 24-bit single precision
  or  ah, 008h          //
  mov fpu_sp24_ceil_cw, ax
end;

{$ENDIF}

// !!! if these are changed, they must be changed in r_draw.c too !!!
const
  FULLY_CLIPPED_CACHED = $80000000;
  FRAMECOUNT_MASK = $7FFFFFFF;

var
  Ld0: Single = 0.0;
  Ld1: Single = 0.0;
  Lstack: LongInt = 0;
  Lfp_near_clip: Single = NEAR_CLIP;
  Lceilv0: LongInt = 0;
  Lv: LongInt = 0;
  Lu0: LongInt = 0;
  Lv0: LongInt = 0;
  Lzi0: LongInt = 0;

//----------------------------------------------------------------------
// edge clipping code
//----------------------------------------------------------------------

const
  pv0 = 4 + 12;
  pv1 = 8 + 12;
  clip = 12 + 12;

// align 4

procedure R_ClipEdge; assembler;
label
  Lemit, Lcliploop, Lcontinue, LCalcFirst, LCalcSecond;
label
  LTransformAndProject, LPop5AndDone, LDoPop, Ldone;
label
  LSide0, LSide1, LSideDone, LNotFirst, LDoFirst;
label
  LSetRemove, LFindInsertLoop, LInsertFound;
label
  LP0, LP1, LP2, LP4, LP5;
label
  Lp1_, Lp2_, Lp3_;
label
  Ltestright, Ltestright2, LNoClip;
label
  LClampP0, LClampP1, LClampP2, LClampP3;
asm
  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 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 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]    // CAK - the var not the type
  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

⌨️ 快捷键说明

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