	TITLE	gl_amd.asm
DIRECT_API_CALLS	equ	1
;*******************************************************************************
;
; Copyright (c)	1996-1998 ADVANCED MICRO DEVICES, INC. All Rights reserved.
;
; This software	is unpublished and contains the	trade secrets and
; confidential proprietary information of AMD. Unless otherwise
; provided in the Software Agreement associated	herewith, it is
; licensed in confidence "AS IS" and is	not to be reproduced in
; whole	or part	by any means except for	backup.	Use, duplication,
; or disclosure	by the Government is subject to	the restrictions
; in paragraph(b)(3)(B)of the Rights in	Technical Data and
; Computer Software clause in DFAR 52.227-7013(a)(Oct 1988).
; Software owned by Advanced Micro Devices Inc., One AMD Place
; P.O. Box 3453, Sunnyvale, CA 94088-3453.
;
; The following Revision History applies to the Quake2 version of this 
; file. These changes don't really apply to the SIN version except that 
; it was the original starting point for it.
;
;	Revision History:
;
;	$Log:   V:/k6plus/3dx/quake2/code/ref_gl/gl_amd.asv  $
;  
;     Rev 1.31   31 Jul 1998 17:48:42   steiger
;  Modified indirect calls to _qglVertex3fv so they
;  use DICK when 3dfxglam is the gl_driver.
;  
;     Rev 1.30   21 Jul 1998 12:52:10   steiger
;  Added Dynamic Indirect Call Kludge (DICK)
;  to GL_DrawAliasFrameLerp gl_vertex_array
;  code.
;  
;     Rev 1.29   21 Jul 1998 12:08:14   steiger
;  Fixed gl_vertex_array support. The array s_lerped
;  was changed in the id source v3.17 to a vec4_t array
;  from a vec3_t array. All accesses to the array in GL_DrawAliasFrameLerp 
;  and GL_LerpVerts had to reflect this..
;  
;     Rev 1.28   16 Jul 1998 09:35:10   steiger
;  Bypassed gl_vertex_array code in
;  GL_DrawAliasFrameLerp because it is broken.
;  
;     Rev 1.27   10 Jul 1998 17:40:48   steiger
;  Fixed crashing with gl_vertex_arrays set to 1, however,
;  gl_vertex_arrays itself is broken.
;  
;     Rev 1.26   08 Jul 1998 16:22:54   steiger
;  Build 980708 -- First 3.17 build with 3DNow!
;  
;     Rev 1.25   19 May 1998 12:16:46   steiger
;  Fixed GL_DrawAliasFrameLerp. GL_Shadows was not working --
;   moved lerped[] struc to gl_amd.asm as global var so it can be accessed 
;   by GL_DrawShadows. 
;  
;  
;     Rev 1.24   08 May 1998 13:56:24   steiger
;  Implemented Dynamic Indirect Call Kludge (DICK) in 
;   -EmitWaterPolys
;   -GL_DrawParticles
;  Completed full DICK support in:
;   -GL_RenderLightMappedPoly
;   -GL_DrawAliasFrameLerp
;  
;     Rev 1.23   07 May 1998 15:13:58   steiger
;  Added R_MarkLeaves to GL_AMD.ASM
;  Made R_MarkLeaves in GL_RSURF.C conditional
;  Added init code to DrawAliasFrameLerp and 
;  RenderLightMappedPoly to seek indirect jumps,
;  determine the final target address, and write it to
;  the code to eliminate indirection.
;  
;     Rev 1.22   04 May 1998 13:56:52   steiger
;  Combined loops in R_RecursiveWorldNode so it is 
;  like the C code in the 3.14 release.
;  
;     Rev 1.21   01 May 1998 14:16:44   steiger
;  Completed integration of all AMD3D asm routines 
;  in GL_AMD.ASM.
;  
;     Rev 1.19.1.7   29 Apr 1998 09:29:38   steiger
;  Added inclusion of amdcpu.inc, which contains
;  the proc GetCpuId.
;  
;     Rev 1.19.1.6   29 Apr 1998 07:14:00   steiger
;  Norbert did further optimization of DrawAliasFrameLerp &
;  GL_DrawParticle
;  
;     Rev 1.19.1.5   27 Apr 1998 07:48:54   steiger
;  Norbert added femms bracketing of external
;  API functions. We lose ~1/2 frame for this.
;  
;     Rev 1.19.1.4   24 Apr 1998 08:12:22   steiger
;  Inserted new RecursiveWorldNode from Norbert
;  with the Lava fixed. The UTP cable anomaly
;  noted in the last revision that was checked in is present in
;  all 3dfxgl versions of quake II, therefore, it will not be persued
;  any further.
;  
;     Rev 1.19.1.3   23 Apr 1998 14:08:42   steiger
;  Added femms at the end of _GL_DrawParticles.
;  It was masking yet another bug in EmitWaterPolys,
;  which is also now fixed. There may still be a problem
;  with a depiction of what appears to be a UTP cable
;  near a wall receptacle in the uppermost left quadrant
;  of the screen. It appears intermittently sometimes when
;  looking at walls. Maybe Quake world is wired for Ethernet ;-)
;
;     Rev 1.19.1.2   23 Apr 1998 09:22:02   steiger
;  Fixed a couple of bugs in EmitWaterPolys, but the water
;  is still not looking like water. Bug that is causing this is elsewhere.
;  
;     Rev 1.19.1.1   22 Apr 1998 15:24:38   steiger
;  Added/removed femms's where desired and/or required.
;  
;     Rev 1.19   22 Apr 1998 10:33:18   steiger
;  Completed ClipSkyPolygon, restored conditional nature
;  of said routine in GL_WARP.C so the asm version in GL_AMD.ASM
;  is built when AMD3D is defined.
;  
;  
;     Rev 1.18   22 Apr 1998 07:41:44   steiger
;  Added Norbert's RecursiveWorldNode (scheduled & aligned).
;
;  
;     Rev 1.17   21 Apr 1998 16:25:10   steiger
;  Finished asm version of R_AddSkySurface.
;  Started work on R_ClipSkyPolygon, but it is
;  removed with 'if 0...endif' until work is complete.
;  
;  
;     Rev 1.16   20 Apr 1998 14:14:34   steiger
;  Rewrote/scheduled code between $frames_different
;   & $comp_bounding_box. PFCMPs were replaced by
;   pfmins/pfmaxs.
;  
;     Rev 1.15   17 Apr 1998 19:27:58   steiger
;  Added asm function R_MarkLights to gl_amd.asm
;  Made R_MarkLights conditional in gl_light.c so the
;   asm version is built when AMD3D is defined.
;  
;     Rev 1.14   17 Apr 1998 14:34:32   steiger
;  Fixed bug in EmitWaterPolys that caused
;  ebp to be corrupted.
;  
;     Rev 1.13   17 Apr 1998 09:23:38   steiger
;  Moved some of the qgl function pointer storage from
;  qgl_win.c to here to enhance cache locality. 
;  
;     Rev 1.12   17 Apr 1998 08:32:54   steiger
;  Added scheduled GL_LerpVerts & R_CullAliasModel from Norbert.
;  
;  
;     Rev 1.11   15 Apr 1998 17:48:26   steiger
;  Removed calls to _VectorScale in GL_DrawParticles,
;   replaced with inline AMD3D code
;  
;     Rev 1.10   15 Apr 1998 15:44:04   steiger
;  Added asm version of GL_RenderLightmappedPoly with x87 code replaced with amd-3d
;  Cleaned up indents & removed spaces
;  Added Norbert's latest _GL_LerpVerts (scheduled)
;  
;  
;     Rev 1.9   14 Apr 1998 07:37:50   steiger
;  Added __chkstk routine that prevents page
;  re-probing. It can be removed by commenting out
;  "AMD_CHKSTK equ 1" near the top of the source file.
;  
;  
;     Rev 1.8   13 Apr 1998 12:32:14   steiger
;  Added EmitWaterPolys function to gl_amd.asm
;  Made EmitWaterPolys in GL_WARP.C conditional
;  
;     Rev 1.7   10 Apr 1998 18:18:48   steiger
;  Added asm version of R_CullBox
;  Finished RecursiveLightPoint, did scheduling
;  Did scheduling in GL_DrawAliasFrameLerp
;  
;	
;	Rev 1.6	07 Apr 1998 19:32:58	steiger
;	Fixed AmdAngleVectors, monsters no longer caffienated.
;	Replaced the	following routines with	Norbert's latest:
;	-GL_LerpVerts
;	-GL_DrawAliasFrameLerp
;	-R_CullAliasModel
;	Started working on RecursiveLightPoint.
;	The public declaration is commented out and
;	the C equivalent in GL_LIGHT.C is always enabled
;	to prevent use of unfinished code DOH!
;	
;	
;	
;	Rev 1.5	06 Apr 1998 15:17:26	steiger
;	Removed unneeded femms instructions
;	Added alignment to several code areas
;	Removed tables and placed them in include files
;	
;	
;	Rev 1.4	06 Apr 1998 10:18:30	RANDY_V
;	1) Changed the segmentation model from flat
;	to explicit to allow alignment to work.
;	2) Updated _GL_LerpVerts.
;	3) Updated _R_CullAliasModel.
;	
;	Rev 1.3	05 Apr 1998 16:43:44	RANDY_V
;	Added _R_BuildLightMap from Mike.	I	think
;	I was getting about 45.0 fps	in Quake II version
;	3.14	with this change.
;	
;	Rev 1.2	03 Apr 1998 16:05:56	RANDY_V
;	Added procedure _R_AddDynamicLights
;	from	Metabyte.	Now getting 45.2 fps	with
;	3.14	Quake2 running Timedemo.
;	
;	Rev 1.1	03 Apr 1998 11:52:16	RANDY_V
;	Deleted R_DrawAliasModel as Norbert said
;	this	routine	wasn't fully converted to AMD3D.
;	I'm seeing about 44.1fps with quake 3.14
;	running timedemo.
;	
;	Rev 1.0	03 Apr 1998 09:41:52	RANDY_V
;	Initial check-in.
;
;*******************************************************************************
AMD_CHKSTK	equ	1	; Use __chkstk function in this file rather
				; than BillyGates' (Microsoft's)

;*******************************************************************************

PUBLIC	_AmdAngleVectors
PUBLIC	_AMD3D_sin
PUBLIC	_AMD3D_cos
PUBLIC	_AMD3D_sincos
PUBLIC	_AmdBoxOnPlaneSide

ifdef AMD3D
ifndef AMD_PROGRESSION_GUARD
PUBLIC	_SINMDL_LerpVerts
PUBLIC	_RecursiveLightPoint

PUBLIC	_GL_DrawAliasFrameLerp
PUBLIC	_R_CullAliasModel
PUBLIC	_ClipSkyPolygon
PUBLIC	_R_AddSkySurface

PUBLIC	_R_CullBox
PUBLIC	_R_MarkLeaves
;PUBLIC	_GL_DrawParticles

PUBLIC	_R_MarkLights
PUBLIC	_SINMDL_DrawFrameLerp

ifndef SIN
_R_AuxMarkLights textequ <_R_MarkLights>
endif

;PUBLIC	_R_RecursiveWorldNode
PUBLIC	_GL_RenderLightmappedPoly
endif
endif

ifdef	AMD_CHKSTK
 PUBLIC	__chkstk
endif

	.586
	.MMX
	.K3D
include	listing.inc
include ref.inc
include gl_local.inc

_TEXT	SEGMENT	PAGE USE32 PUBLIC 'CODE'
_TEXT	ENDS
_DATA	SEGMENT	PAGE PUBLIC USE32 'DATA'
_DATA	ENDS
CONST	SEGMENT	PARA USE32 PUBLIC 'CONST'
CONST	ENDS
_BSS	SEGMENT	PARA USE32 PUBLIC 'BSS'
_BSS	ENDS
_TLS	SEGMENT	DWORD USE32 PUBLIC 'TLS'
_TLS	ENDS
ASSUME	CS: FLAT, DS: FLAT, SS:	FLAT

;*******************************************************************************
; MASM preprocessor macros (will not work with other assemblers such as 
; NASM, A386 or WASM; may work with TASM.)
;*******************************************************************************

FCALL	MACRO	arg3, arg2, arg1, arg0
	femms
	call	arg3 arg2 arg1 arg0
	femms
ENDM

ifdef	DIRECT_API_CALLS
 DCALL	MACRO	_targ_,_instance_
	  db	0E8h	; Opcode for call relative
 ; offset from next instruction that the function resides
 ifnb <&_instance_>
  D&_targ_&_instance_&:
 else
  D&_targ_&:
 endif
        dd DWORD PTR &_targ_&
 ENDM
else
 DCALL	MACRO	_targ_,_instance_
     call      DWORD PTR _targ_
 ENDM
endif

ifdef SIN
 EXCEPT_SIN macro exp
 endm

 ONLY_SIN macro exp
	&exp
 endm
else
 EXCEPT_SIN macro exp
	&exp
 endm

 ONLY_SIN macro exp
 endm
endif

ifdef	AMD3D

ifndef SIN
PUBLIC _qglBegin
PUBLIC _qglEnable
PUBLIC _qglDisable
PUBLIC _qglEnd
PUBLIC _qglTexCoord2f
PUBLIC _qglVertex2f
PUBLIC _qglColor4f
PUBLIC _qglVertex3fv
PUBLIC _qglVertex3f
PUBLIC _qglColor3f
PUBLIC _qglMultiTexCoord2fARB

_DATA	SEGMENT
align	64
_qglBegin		dd	0
_qglEnable		dd	0
_qglDisable		dd	0
_qglEnd			dd	0
_qglTexCoord2f		dd	0
_qglVertex2f		dd	0
_qglColor4f		dd	0
_qglVertex3fv		dd	0
_qglVertex3f		dd	0
_qglColor3f		dd	0
_qglMultiTexCoord2fARB	dd	0
_DATA   ends

else

extrn _qglBegin:                dword
extrn _qglEnable:               dword
extrn _qglDisable:              dword
extrn _qglEnd:                  dword
extrn _qglTexCoord2f:           dword
extrn _qglVertex2f:             dword
extrn _qglColor4f:              dword
extrn _qglVertex3fv:            dword
extrn _qglVertex3f:             dword
extrn _qglColor3f:              dword
extrn _qglMultiTexCoord2fARB:   dword

endif

AMD_CHKSTK	equ	1	; Use __chkstk function in this file rather than
				; microsoft's
;***************************************
;* Externals
;*
_modelorg$S25757	TEXTEQU	<_modelorg>
_DATA	SEGMENT
;; External Data:
;;;;; dword vars
extrn	_r_avertexnormals:	dword
extrn	_shadedots:		dword
extrn	_skyclip:		dword
extrn	_r_turbsin:		dword
extrn	_c_alias_polys:		dword
extrn	_currententity:		entity_t
extrn	_game2015:              dword
extrn	_r_gogglesmap:          dword
extrn	_currentmodel:		dword
extrn	_gldepthmin:		dword
extrn	_gldepthmax:		dword
extrn	_gl_modulate:		dword
extrn	_gl_monolightmap:	dword
extrn	_modelorg:	       	dword
;extrn	_qglBegin:	       	dword
extrn   _qglBlendFunc:          dword
;extrn	_qglColor4f:	       	dword
extrn	_qglColor4ubv:	       	dword
extrn	_qglColor4fv:		dword
extrn	_qglCullFace:	       	dword
extrn	_qglDepthMask:	       	dword
extrn	_qglDepthRange:	       	dword
;extrn	_qglDisable:	       	dword
;extrn	_qglEnable:	       	dword
;extrn	_qglEnd:	       	dword
extrn	_qglLoadIdentity:      	dword
extrn	_qglMatrixMode:	       	dword
;extrn	_qglMultiTexCoord2fARB:	dword
extrn	_qglPopMatrix:	       	dword
extrn	_qglPushMatrix:	       	dword
extrn	_qglScalef:	       	dword
extrn	_qglShadeModel:	       	dword
;extrn	_qglTexCoord2f:	       	dword
;extrn	_qglVertex3f:	       	dword
;extrn	_qglVertex3fv:	       	dword
extrn	_r_alpha_surfaces:     	dword
extrn	_r_framecount:	       	dword
extrn	_r_lefthand:	       	dword
extrn	_r_lerpmodels:	       	dword
extrn	_r_lightlevel:	       	dword
extrn	_r_notexture:	       	dword
extrn	_r_origin:	       	dword
extrn	_r_particletexture:    	dword
extrn	_r_worldmodel:	       	dword
extrn	_vpn:		       	dword
extrn	_vright:	       	dword
extrn	_vup:		       	dword
extrn	_r_visframecount:	dword
extrn	_gl_vertex_arrays:	dword
extrn	_qglEnableClientState:	dword
extrn	_qglVertexPointer:	dword
extrn	_qglLockArraysEXT:	dword
extrn	_qglUnlockArraysEXT:	dword
extrn	_qglColorPointer:	dword
extrn	_qglArrayElement:	dword


;;;;; word vars

;;;;; byte vars
ifdef SIN
extrn	_blocklights:		byte
_s_blocklights TEXTEQU <_blocklights>
else
extrn	_s_blocklights:		byte
endif
extrn	_frustum:		byte
extrn	_ri:		       	byte
extrn	_r_newrefdef:	       	byte
extrn	_vec3_origin:		byte
_DATA	ENDS

_TEXT	SEGMENT

ifdef SIN
EXTRN	_R_AddDynamicLights:NEAR

EXTRN	_EmitWaterPolys:NEAR
EXTRN	_R_BuildLightMap:NEAR
endif

;; External Code:
extrn   _sqrt:          near
extrn	_gl_dynamic:		near
extrn	_R_SetCacheState:	near
extrn	_gl_state:		near
extrn	_gl_state:		near
extrn	_qglTexSubImage2D:	near
extrn	_c_brush_polys:		near
extrn	_c_brush_polys:		near
extrn	_gl_state:		near
extrn	_c_brush_polys:		near
extrn	_c_brush_polys:		near
extrn	_gl_state:		near
extrn	_AngleVectors:		near
extrn	_GL_Bind:		near
extrn	_GL_BindImage:		near
extrn	_GL_TexEnv:		near
extrn	_MYgluPerspective:     	near
extrn	_R_LightPoint:	       	near
extrn	_R_RotateForEntity:    	near
extrn	_R_TextureAnimation:   	near
extrn	_VectorNormalize:      	near
extrn   _VectorLength:near
extrn	_GL_MBind:		near
extrn	_rand: near

;extrn	_R_AddSkySurface:	near
;extrn	_ClipSkyPolygon:	near
extrn	_DrawSkyPolygon:	near
ifndef	AMD_CHKSTK
 extrn	__chkstk:		near
endif
ifdef	DIRECT_API_CALLS
 extrn	_Sys_MakeCodeWriteable:	near
endif
_TEXT	ENDS
;************************************
;************************************
;* Constants

CONST	SEGMENT
$T25982	DD	03f800000r			; 1
$T26233	DD	000000000r			; 0

; These	are needed by _AmdBoxOnPlaneSide

BoxOnPlaneSideResultMask	dq	00000000FFFFFFFFh
BoxOnPlaneSideIsolateMask	dq	0000000100000002h
fqZero				dq	0000000000000000h

	ALIGN 8
$ChsHigh 			DQ	8000000000000000h
$ChsLow  			DQ	0000000080000000h
$ChsBoth 			DQ	8000000080000000h

CONST	ENDS

;include	anorms.inc
;include	anormtab.inc

_DATA	SEGMENT
	align	16

COMM	_shadevector:		DWORD:03h
COMM	_shadelight: 		DWORD:03h
COMM	_r_dlightframecount:	DWORD

_DATA	ENDS

_DATA	SEGMENT
align	16
aav_angles	dq	0

;; Do not change the order of these... _AmdAngleVectors	will break!!!
;; See the "assert" below.

aav_sp		dd	0	; sin(angles[PITCH]
aav_sy		dd	0	; sin(angles[YAW]
aav_sr		dd	0	; sin(angles[ROLL]
aav_cp		dd	0	; cos(angles[PITCH]
aav_cy		dd	0	; cos(angles[YAW]
aav_cr		dd	0	; cos(angles[ROLL]
		dd	0	; Padding to allow qword access	of last	variable.
TimeStampEntry	dq	0
TimeStampDelta	dq	0

if (((aav_cr-aav_sp-5*(size DWORD)) or (aav_cr+2*(size DWORD) GT TimeStampEntry)))
.err <The aav_?? ordering and padding must be maintained for _AmdAngleVectors>
endif

_DATA	ENDS

AAV_ANGLES 	equ	8
AAV_FORWARD	equ	12
AAV_RIGHT	equ	16
AAV_UP		equ	20


CONST	SEGMENT

TwoPiDiv360x2	dq	3C8EFA353C8EFA35h	; (M_PI*2 / 360) | (M_PI*2 / 360)
MinusOnex2	dq	0BF800000BF800000h	; -1.0 | -1.0
FloatOne	dd		3F800000h	; (float) 1.0
ToggleSignLo	dq	0000000080000000h	; lo dword
ToggleSignHi	dq	8000000000000000h	; hi dword
OnePtFivex2	dq	3FC000003FC00000h	; 1.5    | 1.5
TwoPtFivex2	dq	4020000040200000h	; 2.5    | 2.5
Halfx2          dq      3f0000003f000000H       ; 0.5    | 0.5
Quarter     dd   03E800000h         ; 0.25
Float3      dd   040400000h         ; 3.0
Float3x2    dq   04040000040400000h ; 3.0 | 3.0
Float2 	 dd	040000000h			; 2.0

CONST	ENDS

_TEXT	SEGMENT

align	32
_AmdAngleVectors PROC

;{
;	float		angle;
;	static float		sr, sp, sy, cr, cp, cy;
;	// static to help MS compiler fp bugs
;
;	angle =	angles[YAW] * (M_PI*2 /	360);
;	sy = sin(angle);
;	cy = cos(angle);
;	angle =	angles[PITCH] *	(M_PI*2	/ 360);
;	sp = sin(angle);
;	cp = cos(angle);
;
;}
;	femms					; [1]
	push		ebp			; [2]

	mov		ebp, esp		; [3]
	push		ebx			; [4]

	push		esi			; [5]
	mov		eax, [ebp+AAV_ANGLES]	; [6]

	movq		mm0, [eax]		; [7]; mm0 = angles[YAW] | angles[PITCH]

	pfmul		mm0, [TwoPiDiv360x2]	; [8]

	movq		[aav_angles], mm0	; [9]

; mm0 =	angles[YAW] * ((2*PI) /	360) | angles[PITCH] * ((2*PI) / 360)

;;; Get	sine & cosine of angles[PITCH]...
	call		_AMD3D_sincos		; [10]	; Wipes	out all	mmx regs
;;; mm0	= sine | cosine

	movd		[aav_cp], mm0		; [11]

	punpckhdq	mm0, mm0		; [12]

	movd		[aav_sp], mm0		; [13]

;;; Get	sine & cosine of angles[YAW]...
	movd		mm0, dword ptr [aav_angles+4]	; [x]; mm0 = 0 | angles[YAW] * ((2*PI) / 360)

	call		_AMD3D_sincos		; [14]	; Wipes	out all	mmx regs
;;; mm0	= sine | cosine

	movd		[aav_cy], mm0		; [15]

	punpckhdq	mm0, mm0		; [16]

	movd		[aav_sy], mm0		; [17]

;	if (right || up)
;	{
;		angle =	angles[ROLL] * (M_PI*2 / 360);
;		sr = sin(angle);
;		cr = cos(angle);
;	}
	mov		eax, [ebp+AAV_UP]	; [18]

	or		eax, [ebp+AAV_RIGHT]	; [19]
	jz		RollNotRequired		; [20]

	mov		eax, [ebp+AAV_ANGLES]	; [21]

	movd		mm0, [eax+8]		; [22];	mm0 = 0| angles[ROLL]

	pfmul		mm0, [TwoPiDiv360x2]	; [23]

	call		_AMD3D_sincos		; [24]	; Wipes	out all	mmx regs
;;; mm0	= sine | cosine

	movd		[aav_cr], mm0		; [25]

	punpckhdq	mm0, mm0		; [26]

	movd		[aav_sr], mm0		; [27]

RollNotRequired:
;	if (forward)
;	{
;		forward[0] = cp*cy;
;		forward[1] = cp*sy;
;		forward[2] = -sp;
;	}
	mov		ebx, [ebp+AAV_FORWARD]	; [28]

	or		ebx, ebx		; [29]

	jz		AavCheckRight		; [30]

	movd		mm0, [aav_cp]		; [31]

	punpckldq	mm0, mm0		; [32]

	movd		mm1, [aav_cy]		; [33]

	punpckldq	mm1, qword ptr [aav_sy]	; [34]

	pfmul		mm1, mm0		; [35]
	mov		eax, [aav_sp]		; [37]

	movq		[ebx], mm1		; [36]
	xor		eax, 80000000h		; [38];	Toggle the sign	bit. 

	mov		[ebx+8], eax		; [39]

;	if (right)
;	{
;		right[0] = (-1*sr*sp*cy+-1*cr*-sy);
;		right[1] = (-1*sr*sp*sy+-1*cr*cy);
;		right[2] = -1*sr*cp;
;	}
AavCheckRight:
	mov		ebx, [ebp+AAV_RIGHT]	; [40]

	or		ebx, ebx		; [41]

	jz		AavCheckUp		; [42]

	movq		mm0, [MinusOnex2]	; [43]	mm0 = -1 | -1
	movd		mm7, [aav_sr]		; [44]	mm7 = 0	| sr

	punpckldq	mm7, qword ptr [aav_cr]	; [45]	mm7 = cr | sr
	movd		mm1, [aav_sp]		; [47]	mm1 = 0	| sp

	pfmul		mm7, mm0		; [46];	mm7 = -1*cr | -1*sr
; Do initial products, then calculate &	write right[0]
	punpckldq	mm1, mm1		; [48];	mm1 = sp | sp

	movd		mm6, [aav_cy]		; [49]	mm6 = 0	| cy

	punpckldq	mm6, qword ptr [aav_sy]	; [50]	mm6 = sy | cy

	pfmul		mm6, mm1		; [51];	mm6 = sp*sy | sp*cy

	movq		mm5, mm6		; [52]	mm5 = sp*sy | sp*cy

	punpckldq	mm5, qword ptr [aav_sy]	; [53]	mm5 = sy | sp*cy
	movq		mm4, mm6		; [58];	mm4 = mm6 = sp*sy | sp*cy

	pxor		mm5, [ToggleSignHi]	; [54];	mm5 = -sy | sp*cy
	punpckhdq	mm4, mm4		; [59];	mm4 = sp*sy | sp*sy

	pfmul		mm5, mm7		; [55]	mm5 = -1*cr*-sy	| -1*sr*sp*cy
	punpckldq	mm4, qword ptr [aav_cy]	; [60];	mm4 = cy | sp*sy

	pfacc		mm5, mm5		; [56]	mm5 = -1*cr*-sy	+ -1*sr*sp*cy |	-1*cr*-sy + -1*sr*sp*cy
	pfmul		mm4, mm7		; [61];	mm4 = -1*cr*cy | -1*sr*sp*sy

	movd		[ebx], mm5		; [57];	write right[0]
	pfacc		mm4, mm4		; [62];	mm4 = -1*cr*cy + -1*sr*sp*sy | -1*cr*cy	+ -1*sr*sp*sy

	movd		mm1, [aav_cp]		; [64];	mm1 = 0	| cp
	movd		[ebx+4], mm4		; [63]

; Calculate & write right[2]
	pfmul		mm1, mm7		; [65];	mm1 = 0	| -1*sr*cp
	movd		[ebx+8], mm1		; [66]

;	if (up)
;	{
;		up[0] =	(cr*sp*cy+-sr*-sy);
;
;			=	(cr*sp*cy+sr*sy);
;		up[1] =	(cr*sp*sy+-sr*cy);
;		up[2] =	cr*cp;
;	}
;
AavCheckUp:
	mov		ebx, [ebp+AAV_UP]	; [67]
	or		ebx, ebx		; [68]
	jz		AmdAngleVectorsExit	; [69]


	movd		mm7, [aav_sp]		; [70]
	punpckldq	mm7, qword ptr [aav_sy]	; [71]	; mm7 =	sy | sp

; Do initial products, then calculate &	write up[0]
	movd		mm1, [aav_cr]		; [72]	mm1 = 0	| cr
; Calculate & write up[0]
	movd		mm5, [aav_cr]		; [89];	mm5 = 0	| cr

	punpckldq	mm1, qword ptr [aav_sr]	; [73]	; mm1 =	sr | cr
	pfmul		mm7, mm1		; [74];	mm7 =	sr*sy | cr*sp

	movd		mm4, [aav_cp]		; [90];	mm4 = 0	| cp
	movq		mm6, mm7		; [75]	mm6 =	sr*sy | cr*sp

	movd		mm2, [aav_cy]		; [76]	mm2 = 0	| cy
	pfmul		mm4, mm5		; [91];	mm4 = 0	| cr*cp

	movd		mm0, [aav_sy]		; [82];	mm0 = 0	| sy
	punpckldq	mm2, qword ptr [FloatOne]; [77, 78]		; mm2 =	 1.0 | cy

	punpckhdq	mm1, mm1		; [82.5] mm1 = sr | sr
	punpckldq	mm7, mm1		; [83];	mm7 = sr | cr*sp

	pfmul		mm6, mm2		; [79];	mm2 =	sr*sy | cr*sp*cy
	movd		[ebx+8], mm4		; [92]

	pxor		mm7, ToggleSignHi	; [84];	mm7 = -sr | cr*sp
	pfacc		mm6, mm6		; [80]

	punpckldq	mm0, mm2		; [85];	mm0 = cy	| sy
	movd		[ebx], mm6		; [81]

; Calculate & write up[1]

	pfmul		mm0, mm7		; [86];	mm0 = -sr*cy	|	cr*sp*sy
	pfacc		mm0, mm0		; [87];	mm0 = -sr*cy + cr*sp*sy	| -sr*cy + cr*sp*sy

	movd		[ebx+4], mm0		; [88]

AmdAngleVectorsExit:
;	femms					; [93]
	pop		esi			; [94]
 	pop		ebx			; [95]

	pop		ebp			; [96]
 	ret					; [97]
_AmdAngleVectors ENDP

_TEXT	ENDS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;	AMDSIN.ASM
;
;	AMD3D sine, cosine and sin/cosine math functions:
;
;	Abstract:
;
;		Reduces	arg to [0; pi/4) using two-step	algorithm
;		(from "Software	Manual for the Elementary Functions" by	Cody,
;		Waite);	for higher precision.
;
;		Let abs(arg) ==	N * pi/4 + x; 0	<= x < pi/4
;		Result := sign(arg) * (N & 4 ? -1 : 1)
;			case N mod 4 of
;				0: sin(x);
;				1: cos(pi/4 - x);
;				2: cos(x);
;				3: sin(pi/4 - x);
;			endcase
;
;		sin(x) is approximated with x -	x^3/3! + x^5/5!	- x^7/7! ==
;		 x * (1	- x^2 /	6 * (1 - x^2 / 20 * (1 - x^2 / 42) ) )
;
;
;		cos(x) is approximated with 1 -	x^2/2! + x^4/4!	- x^6/6! + x^8/8! ==
;		 1 - x^2 / 2 * (1 - x^2	/ 12 * (1 - x^2	* 30 * (1 - x^2	/ 56) )	)
;
;
;		The cosine is computed similarly.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CONST	SEGMENT
FOUROPI		dd	03fa2f983r		; 1.27324
XMAX		=	046c90fdbH		; 25735.9
XMIN		=	039e8977eH		; 0.0004436336
MASKP		dd	07fffffffh
		dd	0


HEADTAIL	equ	$
PIO4HEAD	dd	0bf490000r		; -0.785156
PIO4TAIL	dd	0b97daa22r		; -0.000241913
PIO4		dd	03f490fdbr		; 0.785398
		dd	03f490fdbr
MO5642		equ	$
MO56		dd	0bc924925r		; -0.0178571
MO42		dd	0bcc30c31r		; -0.0238095
ONE		dd	03f800000r		; 1
		dd	03f800000r
MO3020		equ	$
MO30		dd	0bd088889r		; -0.0333333
MO20		dd	0bd4ccccdr		; -0.05
MO1206		equ	$
MO12		dd	0bdaaaaabr		; -0.0833333
MO6		dd	0be2aaaabr		; -0.166667
MO2		dd	0bf000000r		; -0.5
		dd	0			; filler
CONST	ENDS

_TEXT	SEGMENT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;	Function:
;		mmx_single AMD3D_sin(mmx_single	arg);
;
;	Arguments:
; 		Arg in LH of mm0
;
;	Returns:
;		Result in LH of	mm0, HH	of mm0 undefined:
;	 		0.0 if the abs(arg) is greater than 8192 * pi
;			arg if abs(arg)	< 0.0004436336:	precise	enough
;
;	
;	Regs not preserved:
;		mm0 thru mm7
;		eax, ebx, ecx, edx
;		
;	Notes:
;		The average execution time, assuming one mispredict out	of
;		two, is	41 + 6 = 47 cycles. Precision within [0, 2*pi] range
;		is about 22 bits.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

align	32
_AMD3D_sin	PROC

	movd		eax, mm0	; 1
	pand		mm0, qword ptr MASKP


	mov		ebx, eax	; 2
	and		ebx, 80000000h


	xor		eax, ebx	; 3
	cmp		eax, XMAX


	movd		mm2, FOUROPI	; 4
	jl		AmdSineX2


	pxor		mm0, mm0	; 5
	ret
AmdSineX2:
	cmp		eax, XMIN	; 5
	movq		mm1, mm0

	jg		AmdSineX3	; 6

	ret 				; 7
AmdSineX3:
	pfmul		mm0, mm2	; 7	; y = x	* ( 4 /	pi)
	movq 		mm3, qword ptr HEADTAIL


	movq 		mm5, qword ptr ONE ; 8


	pf2id		mm0, mm0	; 9	y = int(y)
	movq 		mm7, qword ptr MO5642


	movq 		mm6, qword ptr MO3020	; 10


	movd		ecx, mm0	; 11
	pi2fd		mm0, mm0		; y = float(y)


	mov		edx, ecx	; 12


	punpckldq	mm0, mm0	; 13
	and		edx, 4


	shl		edx, 29		; 14
	pfmul		mm0, mm3	; 	; y = headtail * y


	xor		ebx, edx	; 15
	movq		mm3, qword ptr PIO4		;


	pfadd		mm1, mm0	; 16	; x = x	- head(y)


	punpckhdq	mm0, mm0	; 17
	test		ecx, 1		;


	pfadd		mm1, mm0	; 18		; x = x	- tail(y)


;	stall


	punpckldq	mm1, mm1	; 20
	jz		AmdSineX5	;	assume predicted non-taken


	pfsubr		mm1, mm3	; 21	; x = pi/4 - x
AmdSineX5:
	mov		edx, ecx	; 22
	shr		edx, 1


	movq		mm2, mm1	; 23	; x; x
	pfmul		mm1, mm1	;		; y = x	* x


	xor		ecx, edx	; 24
	movq		mm4, qword ptr MO1206


	pfmul		mm7, mm1	; 25	mm7 = -y / 56,42


	pfmul		mm6, mm1	; 26		mm6 = -y / 30,20


	pfadd		mm7, mm5	; 27	mm7 = z1 = 1 - y / 56,42
	pfmul		mm4, mm1		;		mm4 = -y / 12,6


; stall


	pfmul		mm7, mm6	; 29		mm7 = -y * z1 /	30,20
	movq		mm6, qword ptr MO2


; stall


	pfadd		mm7, mm5	; 30	mm7 = z2 = 1 - y * z1 /	30,20
	pfmul		mm6, mm1	;	mm6 = -y / 2

; stall


	pfmul		mm4, mm7	; 32	mm4 = -y * z2 /	12,6


; stall


	pfadd		mm4, mm5	; 34	mm4 = z3 = 1 - y * z2 /	12,6
	test		ecx, 1		;


	jz		AmdSineX7		; 35


	pfmul		mm4, mm6	; 36	mm4 = -y * z3 /	2


; stall


	pfadd		mm4, mm5	; 39	mm4 = z4 = 1 - y * z3 /	2
AmdSineX8:

	movd		mm0, ebx	; 40


	pxor		mm0, mm4	; 41
	ret

AmdSineX7:
	punpckhdq	mm4, mm4	; 37


	pfmul		mm4, mm2	; 38
	jmp		AmdSineX8	;


_AMD3D_sin	ENDP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;	Function:
;		mmx_single AMD3D_cos(mmx_single	arg);
;
;	Arguments:
; 		Arg in LH of mm0
;
;	Returns:
;		Result in LH of	mm0, HH	of mm0 undefined
;		Returns	1.0 if abs(arg)	>= 8192	* pi
;
;	
;	Regs not preserved:
;		mm0 thru mm7
;		eax, ebx, ecx, edx
;		
;	Notes:
;		The average execution time is 41 + 6 = 47 cycles
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

align	32
_AMD3D_cos	PROC NEAR

	movd		eax, mm0	; 1
	pand		mm0, qword ptr MASKP


	and		eax, 7fffffffh	; 2
	cmp		eax, XMAX


	movd		mm2, FOUROPI	; 3
	jl		AmdCoSineX2


	movd		mm0, dword ptr ONE	; 4
	ret

AmdCoSineX2:
	movq		mm1, mm0	; 4
	pfmul		mm0, mm2	; 	; y = x	* ( 4 /	pi)


	movq 		mm3, qword ptr HEADTAIL	; 5


	pf2id		mm0, mm0	; 6	; y = int(y)


	movq 		mm7, qword ptr MO5642	; 7


	movd		ecx, mm0	; 8


	movq 		mm6, qword ptr MO3020	; 9
	pi2fd		mm0, mm0		; y = float(y)


	mov		ebx, ecx	; 10


	punpckldq	mm0, mm0	; 11
	and		ebx, 4		;


	pfmul		mm0, mm3	; 12	; y = headtail * y
	shl		ebx, 29


	movq		mm3, qword ptr PIO4	; 13


	pfadd		mm1, mm0	; 14	; x = x	- head(y)
	movq		mm5, qword ptr ONE	;


	punpckhdq	mm0, mm0	; 15
	test		ecx, 1		;


	pfadd		mm1, mm0	; 16	; x = x	- tail(y)


; stall


	punpckldq	mm1, mm1	;	18
	jz		AmdCoSineX5	;


	pfsubr		mm1, mm3	; 19	; x = pi/4 - x

AmdCoSineX5:
	movq		mm2, mm1	; 20	; x
	mov		edx, ecx	;


	pfmul		mm1, mm1	; 21 	; y = x	* x
	shr		edx, 1


	xor		ecx, edx	; 22
	shl		edx, 31


	xor		ebx, edx	; 23
	movq		mm4, qword ptr MO1206	;


	pfmul		mm7, mm1	; 25	mm7 = -y / 56,42


	pfmul		mm6, mm1	; 26mm6	= -y / 30,20


	pfadd		mm7, mm5	; 27	mm7 = z1 = 1 - y / 56,42
	pfmul		mm4, mm1	;		mm4 = -y / 12,6


; stall


	pfmul		mm7, mm6	; 29		mm7 = -y * z1 /	30,20
	movq		mm6, qword ptr MO2


; stall


	pfadd		mm7, mm5	; 31	mm7 = z2 = 1 - y * z1 /	30,20


; stall


	pfmul		mm4, mm7	; 33	mm4 = -y * z2 /	12,6
	test		ecx, 1		;


; stall


	pfadd		mm4, mm5	; 35	mm4 = z3 = 1 - y * z2 /	12,6
	pfmul		mm6, mm1	;	mm6 = -y / 2


	jnz		AmdCoSineX7		 ; 36


	pfmul		mm4, mm6	; 37	mm4 = -y * z3 /	2


; stall


	pfadd		mm4, mm5	; 39	mm4 = z4 = 1 - y * z3 /	2


AmdCoSineX8:
	movd		mm0, ebx	; 40


	pxor		mm0, mm4	; 41
	ret
AmdCoSineX7:
	punpckhdq 	mm4, mm4	; 37
	pfmul		mm4, mm2	; 38
	jmp		AmdCoSineX8

_AMD3D_cos	ENDP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;	Function:
;		mmx_double AMD3D_sincos(mmx_single arg);
;
;	Arguments:
; 		Arg in LH of mm0
;
;	Returns:
;		Cosine in LH of	mm0, sine in HH	of mm0.
;		Returns	cos = 1.0, sin = 0.0 if	abs(arg) >= 8192 * pi
;
;	
;	Regs not preserved:
;		mm0 thru mm7
;		eax, ebx, ecx, edx, esi
;		
;	Notes:
;		The average execution time = 43	+ 6 = 49 clocks
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

align	32
_AMD3D_sincos	PROC NEAR

	movd		eax, mm0	; 1
	pand		mm0, qword ptr MASKP


	mov		ebx, eax	; 2	cos sign - in sign bit
	mov		edx, eax	; 	both sign - flag


	and		ebx, 80000000h	; 3
	shr		edx, 31


	xor		eax, ebx	; 4
	cmp		eax, XMAX	;


	movd		mm2, FOUROPI	; 5
	jl		AmdSinCosX2		 ;


	movd		mm0, dword ptr ONE	; 6
	ret
AmdSinCosX2:
	movq		mm1, mm0
	pfmul		mm0, mm2	; 6	; y = x	* ( 4 /	pi)


	movq		mm3, qword ptr HEADTAIL	; 7


	pf2id		mm0, mm0	; 8	; y = int(y)


	movq		mm7, qword ptr MO5642	; 9


	movd		ecx, mm0	; 10
	pi2fd		mm0, mm0		; y = float(y)


	mov		esi, ecx	; 11
	movq		mm6, qword ptr MO3020	;


	punpckldq 	mm0, mm0	; 12
	movq		mm5, qword ptr ONE	;


	pfmul		mm0, mm3	; 13	; y = headtail * y
	movq		mm3, qword ptr PIO4
;	stall
	pfadd		mm1, mm0	; 15	; x = x	- head(y)
	shr		esi, 2


	punpckhdq 	mm0, mm0	; 16
	xor		edx, esi


	pfadd		mm1, mm0	; 17	; x = x	- tail(y)
	test		ecx, 1		;


	punpckldq	mm1, mm1 ; 19	 ; dup mm1
	jz		AmdSinCosX5		 ;


	pfsubr		mm1, mm3	; 20	; x = pi/4 - x
AmdSinCosX5:
	movq		mm2, mm5	; 20
	shl		edx, 31


	punpckldq 	mm2, mm1	; 21	; mm2 =	1; x
	pfmul		mm1, mm1	 	; y = x	* x


	mov		esi, ecx	; 22
	movq		mm4, qword ptr MO1206	;


	shr		esi, 1		; 23
	pfmul		mm7, mm1	;		mm7 = -y / 56,42


	xor		ecx, esi	; 24
	pfmul		mm6, mm1	;		mm6 = -y / 30,20


	shl		esi, 31		; 25
	pfadd		mm7, mm5	; 	mm7 = z1 = 1 - y / 56,42


	xor		ebx, esi	; 26
	pfmul		mm4, mm1		;		mm4 = -y / 12,6


	pfmul		mm7, mm6	; 27		mm7 = -y * z1 /	30,20
	movq		mm6, qword ptr MO2


	pfadd		mm7, mm5	; 28	mm7 = z2 = 1 - y * z1 /	30,20
	pfmul		mm6, mm1	; 	mm6 = -y / 2; 0
;	stall


	pfmul		mm4, mm7	; 30	mm4 = -y * z2 /	12,6


	movd		mm0, edx	; 31


	pfadd		mm4, mm5	; 32	mm4 = z3 = 1 - y * z2 /	12,6
	punpckldq 	mm6, mm5	; 	mm6 = -y/2; 1


	psrlq		mm5, 32		; 33	mm5 = 1; 0


	pfmul		mm4, mm6	; 34	mm4 = -y * z3 /	2; z3


	punpckldq 	mm0, mm0	;	35
	movd		mm1, ebx


	pfadd		mm4, mm5	; 36	mm4 = z4 = 1 - y * z3 /	2; z3
	test		ecx, 1		;
;	stall


	pfmul		mm4, mm2	; 38	mm4 = cos; sin
	jz		AmdSinCosX7
;	stall


	punpckldq 	mm5, mm4	; 40


	punpckhdq 	mm4, mm5	;	41
AmdSinCosX7:
	pxor		mm4, mm1	; 42	mm4 = cos, sin


	pxor		mm0, mm4	; 43
	ret

_AMD3D_sincos	ENDP

_TEXT	ENDS

;	COMDAT _BoxOnPlaneSide
_TEXT	SEGMENT
_emins$	= 8
_emaxs$	= 12
_p$ = 16
align	32
_AmdBoxOnPlaneSide PROC	NEAR				; COMDAT

; 334	: // fast axial cases
; 335	: 	if (p->type < 3)

;	femms
	push		ebp

	mov		ebp, esp
	mov		ecx, DWORD PTR _p$[ebp]

	push		ebx
	mov		al, BYTE PTR [ecx+16]

	cmp		al, 3
	jae		GeneralCase

;;; This code executes infrequently, so	scheduling has
;;; not	been done.

; if (p->dist <= emins[p->type]) or, in	this case...
; if !(p->dist > emins[p->type])

	movd		mm0, [ecx+12]	; mm0 =	0 | p->dist
	and		eax, 0FFh
	shl		eax, 2
	mov		edx, eax
	mov		eax, DWORD PTR _emins$[ebp]
	pfcmpgt		mm0, [eax+edx]
	movd		eax, mm0
	or		eax, eax
	jz		CheckEmax
	mov		eax, 1
	jmp		BoxOnPlaneSideExit

CheckEmax:
; if (p->dist >= emaxs[p->type])

	movd		mm0, [ecx+12]	; mm0 =	0 | p->dist
	mov		ecx, DWORD PTR _emaxs$[ebp]
	pfcmpge		mm0, [ecx+edx]
	movd		eax, mm0
	or		eax, eax
	je		short $L799
	mov		eax, 2
	jmp		BoxOnPlaneSideExit

$L799:
	mov		eax, 3
	jmp		BoxOnPlaneSideExit

GeneralCase:

; general case
; switch (p->signbits)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ORIGINAL ORDER INDICATED BY THE NUMBER IN	SQUARE BRACKETS, e.g. [3]
	movzx		ebx, BYTE PTR [ecx+17]		; [0]
	mov		eax, DWORD PTR _emaxs$[ebp]	; [3]

	cmp		ebx, 7				; [1]
	mov		edx, DWORD PTR _emins$[ebp]	; [4]

	ja		DefaultCase			; [2]

; case 0:
; dist1	= p->normal[0]*emaxs[0]	+ p->normal[1]*emaxs[1]	+ p->normal[2]*emaxs[2];
; dist2	= p->normal[0]*emins[0]	+ p->normal[1]*emins[1]	+ p->normal[2]*emins[2];

	movd		mm0, [ecx]			; [5]

; eax =	&emaxs[0]
; ecx =	&p = &p->normal[0]
; edx =	&emins[0]

	movd		mm3, [edx]		; [11]

	punpckldq	mm0, mm0		; [5.1]
	movd		mm1, [ecx+4]		; [6]

	movd		mm2, [ecx+8]		; [8]
	punpckldq	mm1, mm1		; [7]

	punpckldq	mm2, mm2		; [9]
	movd		mm7, [eax]		; [10]

; mm0 =	p->normal[0] | p->normal[0]
; mm1 =	p->normal[1] | p->normal[1]
; mm2 =	p->normal[2] | p->normal[2]

	punpckldq	mm3, mm7		; [12] mm3 = emaxs[0] |	emins[0]
	or		ebx, ebx		; [22]

	movd		mm7, [eax+4]		; [13]
	pfmul		mm3, mm0		; [14]
; mm3 =	p->normal[0]*emaxs[0] |	p->normal[0]*emins[0]

	movd		mm4, [edx+4]		; [15]
	movd		mm5, [edx+8]		; [18]

	punpckldq	mm4, mm7		; [16] mm4 = emaxs[1] |	emins[1]
	movq		mm0, mm3		; [26] Swap mm3	hi-lo

	movd		mm7, [eax+8]		; [17]
	pfmul		mm4, mm1		; [19] mm4 = p->normal[1]*emaxs[1] | p->normal[1]*emins[1]

	punpckldq	mm5, mm7		; [20] mm5 = emaxs[2] |	emins[2]
	pfmul		mm5, mm2		; [21] mm5 = p->normal[2]*emaxs[2] | p->normal[2]*emins[2]

	jz		AddEmUp			; [23] ; Flags set in [22] above (or ebx, ebx)
	test		ebx, 1			; [24]

	jz		CheckTwo		; [25]
	punpckhdq	mm3, mm3		; [27]

	punpckldq	mm3, mm0		; [28]
CheckTwo:
	test		ebx, 2			; [29]
	movq		mm0, mm4		; [31] Swap mm4	hi-lo

	jz		CheckFour		; [30]
	punpckhdq	mm4, mm4		; [32]

	punpckldq	mm4, mm0		; [33]

CheckFour:
	test		ebx, 4			; [34]
	movq		mm0, mm5		; [36] Swap mm5	hi-lo

	jz		AddEmUp			; [35]
	punpckhdq	mm5, mm5		; [37]

	punpckldq	mm5, mm0		; [38]

AddEmUp:
	pfadd		mm3, mm4		; [39]

	pfadd		mm3, mm5		; [40]

DetermineRetVal:
	movd		mm0, [ecx+12]		; [41]
	punpckldq	mm0, mm0		; [42]
; mm0 =	p->dist	| p->dist
; mm3 =	dist1 |	dist2

;	if (dist1 >= p->dist)
;		sides =	1;
;	if !(dist2 >= p->dist)
;		sides |= 2;

	pfcmpge		mm3, mm0			; [43]
	pxor		mm3, [BoxOnPlaneSideResultMask]	; [44] Logically invert	the result for dist2
	pand		mm3, [BoxOnPlaneSideIsolateMask]; [45] Isolate relevant	bits
	movd		eax, mm3			; [46] Get the low dword in eax
	punpckhdq	mm3, mm3			; [47]
	movd		ebx, mm3			; [48] Get the hi dword	in ebx
	or		eax, ebx			; [49] Glue 'em	together

BoxOnPlaneSideExit:
;	femms						; [50]
	pop		ebx				; [51]
	pop		ebp				; [52]
	ret		0				; [53] Exit stage left...

DefaultCase:
; default:
; dist1	= dist2	= 0;
	movq		mm3, [fqZero]
	jmp		DetermineRetVal

_AmdBoxOnPlaneSide ENDP
_TEXT	ENDS
_DATA SEGMENT
align 8
Q_Scale	DQ	0
_DATA	ENDS

CONST	SEGMENT
align 8
Float_004       DQ	0000000003b83126fr	; 0.004
Float_004x2     DQ      03b83126f3b83126fr      ; 0.004 | 0.004
Float_1         DQ      0000000003f800000r      ; 1
Float_1x2       DQ      03f8000003f800000r      ; 1.000 | 1.000
Float_255       DQ	000000000437f0000r	; 255
Float_20        dd   041a00000h         ; 20.0 
Float_0         dd   000000000h         ; 0.0
Float_40   		dd   042200000h         ; 40.0 
CONST	ENDS
;
;ifdef	DIRECT_API_CALLS
;_DATA	SEGMENT
;_GL_DP_FirstTimeFlag	dd	0
;_DATA	ENDS
;endif

ifdef 0
;	COMDAT _GL_DrawParticles
_TEXT	SEGMENT
_num_particles$ = 8
_particles$ = 12
_up$ = -24
_right$ = -12
_scale$ = 8
_tmpup$ = -48
_tmpright$ = -36

align 32
_GL_DrawParticles PROC NEAR				; COMDAT

; 1516 :    const particle_t *p;
; 1517 :    int            i;
; 1518 :    vec3_t         up, right;
; 1519 :    float       scale;
; 1520 :    vec3_t         tmpup, tmpright;
; 1521 : 
; 1522 :    GL_BindImage( r_particletexture );
	
	femms
    
	sub		esp, 56					; 00000038H
	push		ebx
	push		ebp
	push		esi
	push		edi
    	mov		eax, DWORD PTR _r_particletexture
	push		eax
	call		_GL_BindImage
	add		esp, 4

; 1523 :    qglDepthMask( GL_FALSE );     // no z buffering

	push		0
	call		DWORD PTR _qglDepthMask

; 1524 :    qglEnable( GL_BLEND );  

	push		3042					; 00000be2H
	call		DWORD PTR _qglEnable

; 1525 :    GL_TexEnv( GL_MODULATE );

	push		8448					; 00002100H
	call		_GL_TexEnv
	add		esp, 4

; 1526 :    
; 1527 :    // Do the overbright particles first
; 1528 :    
; 1529 :    qglBlendFunc( GL_ONE, GL_ONE );

	push		1
	push		1
	call		DWORD PTR _qglBlendFunc

; 1530 :    qglBegin( GL_TRIANGLES );

	push		4
	call		DWORD PTR _qglBegin

; 1531 : 
; 1532 :    VectorScale (vup, 2.5, up);

	lea		ecx, DWORD PTR _up$[esp+72]
	push		ecx
	push		1075838976				; 40200000H
	push		OFFSET FLAT:_vup
	call		_VectorScale
	add		esp, 12					; 0000000cH

; 1533 :    VectorScale (vright, 2.5, right);

	lea		edx, DWORD PTR _right$[esp+72]
	push		edx
	push		1075838976				; 40200000H
	push		OFFSET FLAT:_vright
	call		_VectorScale
	add		esp, 12					; 0000000cH

; 1534 : 
; 1535 :    for ( p = particles, i=0 ; i < num_particles ; i++,p++)

	mov		ebx, DWORD PTR _num_particles$[esp+80]
	test		ebx, ebx
	jle		$L44012
	mov		eax, DWORD PTR _particles$[esp+68]
	mov		DWORD PTR -52+[esp+72], ebx
	lea		esi, DWORD PTR [eax+8]
$L44010:

; 1536 :       {
; 1537 :       if(!(p->flags & (PARTICLE_OVERBRIGHT|PARTICLE_FIRE|PARTICLE_ADDITIVE)))

	mov		al, BYTE PTR [esi+20]
	test		al, 14					; 0000000eH
	je		$L44011

; 1538 :          continue;
; 1539 : 
; 1540 :       // don't render flame particles that are closer than 32 units
; 1541 :       if(p->flags & PARTICLE_FIRE)

	test		al, 8
	je		SHORT $L44015

; 1542 :       {
; 1543 :          VectorSubtract(p->origin, r_origin, tmpup);

; IGX - Implemented Vector Subtract in 3DNow!
	femms
	movq		mm0, QWORD PTR [esi-8]			; p->origin[1] | p->origin[0] 
	movq		mm2, QWORD PTR _r_origin		; r_origin[1] | r_origin[0]
	    
	movd		mm1, DWORD PTR [esi]			; 0 | p->origin[2]
	movd		mm3, DWORD PTR _r_origin+8		; 0 | r_origin[2]
	  
	pfsub		mm0, mm2					; mm0 = p->o[1] - r_o[1] | p->o[0] - r_o[0]
	pfsub		mm1, mm3					; mm1 = 0 | p->o[2] - r_o[2]
	    
	movd		DWORD PTR _tmpup$[esp+72], mm0	; tmpup[0] = p->o[0] - r_o[0] 
	psrlq		mm0, 32					; mm0 = 0 | p->o[1] - r_o[1]
	movd		DWORD PTR _tmpup$[esp+80], mm1	; tmpup[2] = p->o[2] - r_o[2]
	movd		DWORD PTR _tmpup$[esp+76], mm0	; tmpup[1] = mm0
    
; 1544 :          length = VectorLength(tmpup);
	
	movq		mm0, QWORD PTR _tmpup$[esp+72]	;mm0 = tmpup[1 | 0]
	movd		mm1, DWORD PTR _tmpup$[esp+80]	;mm1 = tmpup[2]
	
	pfmul		mm0, mm0					;mm0 = tmpup[1 | 0]^2
	pfmul		mm1, mm1					;mm1 =  - | tmpup[2]^2
	pfacc		mm0, mm0					;mm0 = - | tmpup[1]^2 + tmpup[0]^2
	pfadd		mm0, mm1					;mm0 = - | tmpup[2]^2 + tmpup[1]^2 + tmpup[0]^2
	pfrsqrt	mm0, mm0					;mm0 = (1/mm0)^.5
	pfrcp		mm0, mm0					;mm0 = (mm0)^0.5

; 1545 :          if(length < 40)

	movd		mm1,DWORD PTR [Float_40]
	pfcmpge	mm0, mm1					;mm0=(mm0 >= mm1)?ffffffff:0
	movd		eax, mm0					;eax <- mm0
	cmp		eax, 0
	jne		$L44011					;jmp if length >= 40
    	femms
$L44015:

; 1546 :             continue;
; 1547 :       }
; 1548 :      
; 1549 :       // hack a scale up to keep particles from disapearing
; 1550 :       scale = ( p->origin[0] - r_origin[0] ) * vpn[0] +
; 1551 :              ( p->origin[1] - r_origin[1] ) * vpn[1] +
; 1552 :              ( p->origin[2] - r_origin[2] ) * vpn[2];

; IGX - Changed scale calculation to 3DNow!	
	femms
	movq		mm0, QWORD PTR [esi-8]			; mm0 = p->o[1] | p->o[0]
	movq		mm1, QWORD PTR _r_origin		; mm1 = r_o[1] | r_o[0]
	movq		mm2, QWORD PTR vpn			; mm2 = vpn[1] | vpn[0]
	    
	movd		mm3, DWORD PTR [esi]			; mm3 = 0 | p->o[2]
	pfsub		mm0, mm1					; mm0 = p->o[1] - r_o[1] | p->o[0] - r_o[0]
	movd		mm4, DWORD PTR _r_origin+8		; mm4 = 0 | r_o[2]
	pfmul		mm0, mm2					; mm0 = mm0 * mm2
	movd		mm5, DWORD PTR _vpn+8			; mm4 = 0 | vpn[2]
	pfsub		mm3, mm4					; mm3 = mm3 - mm4
	pfacc		mm0, mm0					; mm0 = vpn[1] *(p->o[1] - r_o[1]) + vpn[0]*(p->o[0] - r_o[0]) | ibid 
	pfmul		mm3, mm5					; mm3 = mm3 * mm5
	pfadd		mm0, mm3					; mm0 = scale as above
	    
	movq		mm1 ,mm0					; mm1 = mm0 save a copy of scale
	    
	movd		DWORD PTR _scale$[esp+68], mm0	; scale = mm0[31:0]
    
; 1553 : 
; 1554 :       // added variable sizes
; 1555 :       if(!p->size) // partizle size 0 indicated a regular particle
    
    mov		eax, DWORD PTR [esi+24]
    cmp		eax, 0
    jne		$L44016

; 1556 :       {
; 1557 :          if (scale < 20)

; IGX - Branch with 3DNow! compare.
	movd		mm2, DWORD PTR [Float_20]		; mm2 = 0 | 20.0
	pfcmpge	mm1, mm2    				; mm1 = 0 | scale >= 20.0 ? ffffffff : 0
	movd		eax, mm1					; eax <- mm1[31:0]
	cmp		eax, 0
	jne		$L44017					; jmp if scale < 20.0
    
; 1558 :             scale = 1;

	mov		DWORD PTR _scale$[esp+68], 1065353216	; 3f800000H

; 1559 :          else

	jmp		SHORT $L44018
$L44017:

; 1560 :             scale = 1 + scale * 0.004;

; IGX - 3DNow! scale calculation
	movd		mm1, DWORD PTR [Float_004]		; mm1 = 0 | .004
	movd		mm2, DWORD PTR [FloatOne]		; mm2 = 0 | 1.0
	    
	pfmul		mm0, mm1					; mm0 = 0 | scale * .004
	pfadd		mm0, mm2					; mm0 = 0 | 1 + scale *.004
	movd		DWORD PTR _scale$[esp+68], mm0	; scale = mm0[31:0]
    
$L44018:
	lea		edx, DWORD PTR [esi+4]

; 1561 : 
; 1562 :          qglColor4fv( p->color );

	push		edx
	call		DWORD PTR _qglColor4fv

; 1563 : 
; 1564 :          qglTexCoord2f( 0.0625, 0.0625 );

	push		1031798784				; 3d800000H
	push		1031798784				; 3d800000H
	call		DWORD PTR _qglTexCoord2f

; 1565 :          qglVertex3fv( p->origin );

	push		edi
	call		DWORD PTR _qglVertex3fv

; 1566 :          
; 1567 :          qglTexCoord2f( 1.0625, 0.0625 );

	push		1031798784				; 3d800000H
	push		1065877504				; 3f880000H
	call		DWORD PTR _qglTexCoord2f

; 1568 :          qglVertex3f( p->origin[0] + up[0]*scale,
; 1569 :             p->origin[1] + up[1]*scale,
; 1570 :             p->origin[2] + up[2]*scale);

; IGX - Compute qglVertex3f parameters with 3DNow!
	femms
	movd		mm7, _scale$[esp+68]			; mm7 = 0 | scale
	movq		mm0, QWORD PTR _up$[esp+72]		; mm0 = up[1] | up[0]
	movq		mm1, QWORD PTR [esi-8]			; mm1 = p->o[1] | p->o[0]
	    
	punpckldq	mm7, mm7					; mm7 = scale | scale
	    
	movd		mm2, DWORD PTR _up$[esp+80]		; mm2 = 0 | up[2]
	movd		mm3, DWORD PTR [esi]			; mm3 = 0 | p->o[2]
	    
	pfmul		mm0, mm7					; mm0 = up[1] * scale | up[0] * scale
	pfmul		mm2, mm7					; mm2 = 0 | up[2] * scale
	    
	pfadd		mm0, mm1					; mm0 = p->o[1] + up[1]*scale | p->o[0] + up[0] * scale
	pfadd		mm2, mm3					; mm2 = p->o[2] + up[2]*scale
	push		ecx						; make space on stack
	    
	movd		DWORD PTR [esp], mm2			; top of stack = p->o[2] + up[2] * scale
	movq		mm1, mm0					; save a copy of mm0
	push		ecx						; make room on stack
	psrlq		mm1, 32					; mm1 = 0 | p->o[1] + up[1]*scale
	movd		DWORD PTR [esp], mm1			; stop of stack = mm1[31:0]
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm0			; top of stack = mm0[31:0]

	femms
	call		DWORD PTR _qglVertex3f
	femms
	
; 1571 :          
; 1572 :          qglTexCoord2f( 0.0625, 1.0625 );

	push		1065877504				; 3f880000H
	push		1031798784				; 3d800000H
	call		DWORD PTR _qglTexCoord2f

; 1573 :          qglVertex3f( p->origin[0] + right[0]*scale,
; 1574 :             p->origin[1] + right[1]*scale,
; 1575 :             p->origin[2] + right[2]*scale);

; Compute qglVertex3f parameters using 3DNow!
	femms
	movd		mm7, _scale$[esp+68]			; mm7 = 0 | scale
	movq		mm0, QWORD PTR _right$[esp+72]	; mm0 = r[1] | r[0]
	movq		mm1, QWORD PTR [esi-8]			; mm1 = p->o[1] | p->o[0]
	    
	punpckldq	mm7, mm7					; mm7 = scale | scale
	    
	movd		mm2, DWORD PTR _right$[esp+80]	; mm2 = 0 | r[2]
	movd		mm3, DWORD PTR [esi]			; mm3 = 0 | p->o[2]
	    
	pfmul		mm0, mm7					; mm0 = r[1] * scale | r[0] * scale
	pfmul		mm2, mm7					; mm2 = 0 | r[2] * scale
	    
	pfadd		mm0, mm1					; mm0 = p->o[1] + r[1]*scale | p->o[0] + r[0] * scale
	pfadd		mm2, mm3					; mm2 = p->o[2] + r[2]*scale
	push		ecx						; make space on stack
	    
	movd		DWORD PTR [esp], mm2			; top of stack = p->o[2] + r[2] * scale
	movq		mm1, mm0					; save a copy of mm0
	push		ecx						; make room on stack
	psrlq		mm1, 32					; mm1 = 0 | p->o[1] + r[1]*scale
	movd		DWORD PTR [esp], mm1			; stop of stack = mm1[31:0]
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm0			; top of stack = mm0[31:0]
	    
	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1576 : 
; 1577 :          continue;

    jmp		$L44010
    
$L44016:

; 1578 :       }
; 1579 : 
; 1580 :       // particles using the added effects are handled below
; 1581 :       if(p->size > 1)

; IGX Changed comparison to 3DNow!
	movd		mm1, DWORD PTR [FloatOne]		; mm1 = 0 | 1.0
	movd		mm0, DWORD PTR [esi+24]			; mm0 = 0 | p->size
	pfcmpgt	mm0, mm1					; mm0 = 0 | p->size > 1.0 ? ffffffff : 0
	movd		eax, mm0					; eax <- mm0[31:0]
	cmp		eax, 0
	je		SHORT $L44019				; jmp if p->size > 1
    
; 1582 :          scale /= p->size;

; IGX - Changed scale calculation to 3DNow!
	movd		mm0, DWORD PTR [esi+24]			; mm0 = 0 | p->size
	movd		mm7, _scale$[esp+68]			; mm7 = 0 | scale
	pfrcp		mm0, mm0					; mm0 = 0 | 1/p->size
	pfmul		mm0, mm7					; mm0 = 0 | scale/p->size
    
$L44019:

; 1583 : 
; 1584 :       if (scale < 20)

; IGX - Changed fp comparison to 3DNow!
	movd		mm0, DWORD PTR _scale$[esp+68]	; mm0 = 0 | scale 
	movd		mm2, DWORD PTR [Float_20]		; mm2 = 0 | 20.0
	pfcmpge	mm0, mm2					; mm0 = scale >= 20.0 ? ffffffff : 0
	movd		eax, mm0					; eax <- mm0[31:0]
	cmp		eax, 0
	jne		SHORT $L44020				; jmp if scale >= 20.0
    
; 1585 :          scale = p->size;

	mov		eax, DWORD PTR [esi+24]
	mov		DWORD PTR _scale$[esp+68], eax

; 1586 :       else

	jmp		SHORT $L44021
$L44020:

; 1587 :          scale = p->size + scale * 0.004;

;IGX - changed fp scale calculation to 3DNow!
	movd		mm0, DWORD PTR [Float_004]		; mm0 = 0 | .004
	movd        mm1, DWORD PTR _scale$[esp+68]      ; mm1 = 0 | scale
	movd		mm2, DWORD PTR [esi+24]			; mm2 = 0 | p->size
	
	pfmul		mm0, mm1                            ; mm0 = 0 | scale * .004
	pfadd		mm0, mm2					; mm0 = 0 | p->size + scale * .004
	movd		DWORD PTR _scale$[esp+68], mm0	; scale = mm0[31:0]

$L44021:
	lea		ecx, DWORD PTR [esi+4]

; 1588 : 
; 1589 :       qglColor4fv( p->color );

	push		ecx
	femms
	call		DWORD PTR _qglColor4fv
	femms

; 1590 : 
; 1591 :       //calc new up and right vectors based on 1/4 the particle's scale
; 1592 :       // this is to reduce the number of multiplies later
; 1593 :       VectorScale(up, (scale*0.25), tmpup);

; IGX - Do VectorScale parameter calculations with 3DNow!    
	movd		mm0, DWORD PTR _scale$[esp+68]	; mm0 = 0 | scale
	movd		mm1, DWORD PTR [Quarter]		; mm1 = 0 | 0.25
	lea		edx, DWORD PTR _tmpup$[esp+72]	
	lea		eax, DWORD PTR _up$[esp+72]
	pfmul		mm0, mm1					; mm0 = scale * 0.25
	push		edx						; push tmpup
	movd		DWORD PTR -56+[esp+76], mm0		; save scale * 0.25
	mov		ebp, DWORD PTR -56+[esp+76]		; ebp = (scale * 0.25)
	push		ebp						; push (scale * 0.25)
	push		eax						; push up
	femms
	call		_VectorScale
	add		esp, 12					; 0000000cH

; 1594 :       VectorScale(right, (scale*0.25), tmpright);

	lea		ecx, DWORD PTR _tmpright$[esp+72]
	lea		edx, DWORD PTR _right$[esp+72]
	push		ecx						; push tmpright
	push		ebp						; push (scale * 0.25)
	push		edx						; push right
	call		_VectorScale

; 1595 : 
; 1596 :       // added flame type particles & changed the particle's
; 1597 :       // vertex positions to center around the origin
; 1598 :       if(p->flags & PARTICLE_FIRE)

	mov		al, BYTE PTR [esi+20]
	add		esp, 12					; 0000000cH
	test		al, 8
	je		$L44022

; 1599 :       {
; 1600 :          // randomly flip the particles back and forth a bit
; 1601 :          // to break up their regularity
; 1602 :          if((int)rand()%5)

	call		_rand
	cdq
	mov		ecx, 5

; 1603 :          {
; 1604 :             qglTexCoord2f(1.03125, 1.03125);

	push		1065615360				; 3f840000H
	idiv		ecx
	push		1065615360				; 3f840000H
	test		edx, edx
	je		$L44023
	call		DWORD PTR _qglTexCoord2f

; 1605 :             qglVertex3f( p->origin[0] - tmpup[0] + tmpright[0],
; 1606 :                         p->origin[1] - tmpup[1] + tmpright[1],
; 1607 :                       p->origin[2] - tmpup[2] + tmpright[2]);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	   
	movq		mm0, QWORD PTR _tmpright$[esp+72]	; mm0 = tr[1] | tr[0]
	movq		mm1, QWORD PTR _tmpup$[esp+72]	; mm1 = tu[1] | tu[0]
	movq		mm2, QWORD PTR [edi]			; mm2 = p->o[1] | p->o[0]
	    
	movd		mm3, DWORD PTR _tmpright$[esp+80]	; mm3 = 0 | tr[2]
	movd		mm4, DWORD PTR _tmpup$[esp+80]	; mm4 = 0 | tu[2]
	movd		mm5, DWORD PTR [esi]			; mm5 = 0 | p->o[2]
	    
	pfadd		mm2, mm1					; mm0 = p->o[1] + tr[1] | p->o[0] + tr[0]
	pfadd		mm5, mm4					; mm3 = 0 | p->o[2] + tr[2]
	    
	pfsub		mm2, mm0					; mm2 = p->o[1] - tu[1] + tr[1] | p->o[0] - tu[0] + tr[0]
	pfsub		mm5, mm3					; mm5 = 0 | p->o[2] - tu[2] + tr[2]
	    
	movq		mm1, mm2					; mm1 <- mm2
	    
	push		ecx						; make space on the stack
	    
	psrlq		mm1, 32					; mm1 = 0 | p->o[1] - tu[1] + tr[1]
	movd		DWORD PTR [esp], mm5   			; move mm5 onto the stack

	push		ecx						; make room on the stack
	movd		DWORD PTR [esp], mm1			; stack <- mm1[31:0]
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm2			; stack <- mm2[31:0]

	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1608 : 
; 1609 :             qglTexCoord2f(0.03125, 1.03125);

	push		1065615360				; 3f840000H
	push		1023410176				; 3d000000H
	call		DWORD PTR _qglTexCoord2f

; 1610 :             qglVertex3f( p->origin[0] - tmpup[0] - tmpright[0]*3,
; 1611 :                         p->origin[1] - tmpup[1] - tmpright[1]*3,
; 1612 :                       p->origin[2] - tmpup[2] - tmpright[2]*3);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpright$[esp+72]	; mm0 = tr[1] | tr[0]
	movq		mm1, QWORD PTR [Float3x2]		; mm1 = 3.0 | 3.0
	movq		mm2, QWORD PTR _tmpup$[esp+72]	; mm2 = tu[1] | tu[0]
	movq		mm3, QWORD PTR [edi]			; mm3 = p->o[1] | p->o[0]
	    
	movd		mm4, DWORD PTR _tmpright$[esp+80]	; mm4 = 0 | tr[2]
	movd		mm5, DWORD PTR [Float3]			; mm5 = 0 | 3.0
	movd		mm6, DWORD PTR _tmpup$[esp+80]	; mm6 = 0 | tu[2]
	movd		mm7, DWORD PTR [esi]			; mm7 = 0 | p->o[2]
	    
	pfmul		mm0, mm1					; mm0 = tr[1]*3 | tr[0] * 3
	pfmul		mm4, mm5					; mm4 = 0 | tr[2] * 3
	    
	pfadd		mm2, mm0					; mm2 = tu[1] + tr[1]*3 | tu[0] + tr[0]*3
	pfadd		mm6, mm4					; mm6 = 0 | tu[2] + tr[2]*3
	    
	pfsub		mm3, mm2					; mm3 = p->o[1] - mm2[63:32] | p->o[0] - mm2[31:0]
	pfsub		mm7, mm6					; mm7 = p->o[2] - mm6[31:0]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm3					; mm1 <- mm3
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm7   			; mm7[31:0] on stack

	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm1			; mm1[31:0] onto stack
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm3			; mm3[31:0] onto stack
	    
	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1613 : 
; 1614 :             qglTexCoord2f(1.03125, 0.03125);

	push		1023410176				; 3d000000H
	push		1065615360				; 3f840000H
	call		DWORD PTR _qglTexCoord2f

; 1615 :             qglVertex3f( p->origin[0] + tmpup[0]*3 + tmpright[0],
; 1616 :                         p->origin[1] + tmpup[1]*3 + tmpright[1],
; 1617 :                       p->origin[2] + tmpup[2]*3 + tmpright[2]);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpup$[esp+72]	; mm0 = tu[1] | tu[0]
	movq		mm1, QWORD PTR [Float3x2]		; mm1 = 3.0 | 3.0
	movq		mm2, QWORD PTR _tmpright$[esp+72]	; mm2 = tr[1] | tr[0]
	movq		mm3, QWORD PTR [edi]			; mm3 = p->o[1] | p->o[0]
	    
	movd		mm4, DWORD PTR _tmpup$[esp+80]	; mm4 = 0 | tu[2]
	movd		mm5, DWORD PTR [Float3]			; mm5 = 0 | 3.0
	movd		mm6, DWORD PTR _tmpright$[esp+80]	; mm6 = 0 | tr[2]
	movd		mm7, DWORD PTR [esi]			; mm7 = 0 | p->o[2]
	    
	pfmul		mm0, mm1					; mm0 = tu[1]*3 | tu[0] * 3
	pfmul		mm4, mm5					; mm4 = 0 | tu[2] * 3
	    
	pfadd		mm2, mm0					; mm2 = tr[1] + tu[1]*3 | tr[0] + tu[0]*3
	pfadd		mm6, mm4					; mm6 = 0 | tr[2] + tu[2]*3
	    
	pfadd		mm3, mm2					; mm3 = p->o[1] + mm2[63:32] | p->o[0] +  mm2[31:0]
	pfadd		mm7, mm6					; mm7 = p->o[2] + mm6[31:0]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm3					; mm1 <- mm3
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm7   			; mm7[31:0] on stack

	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm1			; mm1[31:0] onto stack
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm3			; mm3[31:0] onto stack

	femms
	call		DWORD PTR _qglVertex3f
	femms

    jmp		$L44011

; 1618 :          }
; 1619 :          else

$L44023:

; 1620 :          {
; 1621 :             qglTexCoord2f(1.03125, 1.03125);

	call		DWORD PTR _qglTexCoord2f

; 1622 :             qglVertex3f( p->origin[0] - tmpup[0] - tmpright[0],
; 1623 :                         p->origin[1] - tmpup[1] - tmpright[1],
; 1624 :                       p->origin[2] - tmpup[2] - tmpright[2]);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpright$[esp+72]	; mm0 = tr[1] | tr[0]
	movq		mm1, QWORD PTR _tmpup$[esp+72]	; mm1 = tu[1] | tu[0]
	movq		mm2, QWORD PTR [edi]			; mm2 = p->o[1] | p->o[0]
	    
	movd		mm3, DWORD PTR _tmpright$[esp+80]	; mm3 = 0 | tr[2]
	movd		mm4, DWORD PTR _tmpup$[esp+80]	; mm4 = 0 | tu[2]
	movd		mm5, DWORD PTR [esi]			; mm5 = 0 | p->o[2]
	    
	pfadd		mm1, mm0					; mm1 = tu[1] + tr[1] | tu[0] + tr[0]
	pfadd		mm4, mm3					; mm4 = 0 | tu[2] + tr[2]
	    
	pfsub		mm2, mm1					; mm2 = p->o[1] - mm1[63:32] | p->o[0] - mm1[31:0]
	pfsub		mm5, mm4					; mm5 = 0 | p->o[2] - mm4[31:0]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm2					; mm1 <- mm2
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm5   			; move mm5[31:0] onto stack

	push		ecx						; make space on stack
	movd		DWORD PTR [esp], mm1			; move mm1[41:0] onto the stack
	push		ecx						; make room on the stack
	movd		DWORD PTR [esp], mm2			; move mm2[31:0] onto the stack
	    
	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1625 : 
; 1626 :             qglTexCoord2f(1.03125, 0.03125);

	push		1023410176				; 3d000000H
	push		1065615360				; 3f840000H
	call		DWORD PTR _qglTexCoord2f

; 1627 :             qglVertex3f( p->origin[0] + tmpup[0]*3 - tmpright[0],
; 1628 :                         p->origin[1] + tmpup[1]*3 - tmpright[1],
; 1629 :                       p->origin[2] + tmpup[2]*3 - tmpright[2]);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpup$[esp+72]	; mm0 = tu[1] | tu[0]
	movq		mm1, QWORD PTR [Float3x2]		; mm1 = 3.0 | 3.0
	movq		mm2, QWORD PTR _tmpright$[esp+72]	; mm2 = tr[1] | tr[0]
	movq		mm3, QWORD PTR [edi]			; mm3 = p->o[1] | p->o[0]
	    
	movd		mm4, DWORD PTR _tmpup$[esp+80]	; mm4 = 0 | tu[2]
	movd		mm5, DWORD PTR [Float3]			; mm5 = 0 | 3.0
	movd		mm6, DWORD PTR _tmpright$[esp+80]	; mm6 = 0 | tr[2]
	movd		mm7, DWORD PTR [esi]			; mm7 = 0 | p->o[2]
	    
	pfmul		mm0, mm1					; mm0 = tu[1]*3 | tu[0] * 3
	pfmul		mm4, mm5					; mm4 = 0 | tu[2] * 3
	    
	pfsub		mm0, mm2					; mm0 = tu[1]*3 - tr[1] | tu[0]*3 - tr[0]
	pfsub		mm4, mm6					; mm4 = 0 | tu[2]*3 - tr[2]
	    
	pfadd		mm3, mm0					; mm3 = p->o[1] + mm0[63:32] | p->o[0] +  mm0[31:0]
	pfadd		mm7, mm4					; mm7 = p->o[2] + mm4[31:0]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm3					; mm1 <- mm3
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm7   			; mm7[31:0] on stack

	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm1			; mm1[31:0] onto stack
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm3			; mm3[31:0] onto stack

	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1630 : 
; 1631 :             qglTexCoord2f(0.03125, 1.03125);

	push		1065615360				; 3f840000H
	push		1023410176				; 3d000000H

; 1632 :             qglVertex3f( p->origin[0] - tmpup[0] + tmpright[0]*3,
; 1633 :                         p->origin[1] - tmpup[1] + tmpright[1]*3,
; 1634 :                       p->origin[2] - tmpup[2] + tmpright[2]*3);
; 1635 :          }
; 1636 :       }
; 1637 :       else

	jmp		$L44827
$L44022:

; 1638 :       {
; 1639 :          qglTexCoord2f( 0.0625, 0.0625 );

	push		1031798784				; 3d800000H
	push		1031798784				; 3d800000H
	call		DWORD PTR _qglTexCoord2f

; 1640 :          qglVertex3f( p->origin[0] - tmpup[0] - tmpright[0],
; 1641 :                      p->origin[1] - tmpup[1] - tmpright[1],
; 1642 :                    p->origin[2] - tmpup[2] - tmpright[2]);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpright$[esp+72]	; mm0 = tr[1] | tr[0]
	movq		mm1, QWORD PTR _tmpup$[esp+72]	; mm1 = tu[1] | tu[0]
	movq		mm2, QWORD PTR [edi]			; mm2 = p->o[1] | p->o[0]
	    
	movd		mm3, DWORD PTR _tmpright$[esp+80]	; mm3 = 0 | tr[2]
	movd		mm4, DWORD PTR _tmpup$[esp+80]	; mm4 = 0 | tu[2]
	movd		mm5, DWORD PTR [esi]			; mm5 = 0 | p->o[2]
	    
	pfadd		mm1, mm0					; mm1 = tu[1] + tr[1] | tu[0] + tr[0]
	pfadd		mm4, mm3					; mm4 = 0 | tu[2] + tr[2]
	    
	pfsub		mm2, mm1					; mm2 = p->o[1] - mm1[63:32] | p->o[0] - mm1[31:0]
	pfsub		mm5, mm4					; mm5 = 0 | p->o[2] - mm4[31:0]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm2					; mm1 <- mm2
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm5   			; move mm5[31:0] onto stack

	push		ecx						; make space on stack
	movd		DWORD PTR [esp], mm1			; move mm1[41:0] onto the stack
	push		ecx						; make room on the stack
	movd		DWORD PTR [esp], mm2			; move mm2[31:0] onto the stack
	    
	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1643 : 
; 1644 :          qglTexCoord2f( 1.0625, 0.0625 );

	push		1031798784				; 3d800000H
	push		1065877504				; 3f880000H
	call		DWORD PTR _qglTexCoord2f

; 1645 :          qglVertex3f( p->origin[0] + tmpup[0]*3 - tmpright[0],
; 1646 :                      p->origin[1] + tmpup[1]*3 - tmpright[1],
; 1647 :                    p->origin[2] + tmpup[2]*3 - tmpright[2]);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpup$[esp+72]	; mm0 = tu[1] | tu[0]
	movq		mm1, QWORD PTR [Float3x2]		; mm1 = 3.0 | 3.0
	movq		mm2, QWORD PTR _tmpright$[esp+72]	; mm2 = tr[1] | tr[0]
	movq		mm3, QWORD PTR [edi]			; mm3 = p->o[1] | p->o[0]
	    
	movd		mm4, DWORD PTR _tmpup$[esp+80]	; mm4 = 0 | tu[2]
	movd		mm5, DWORD PTR [Float3]			; mm5 = 0 | 3.0
	movd		mm6, DWORD PTR _tmpright$[esp+80]	; mm6 = 0 | tr[2]
	movd		mm7, DWORD PTR [esi]			; mm7 = 0 | p->o[2]
	    
	pfmul		mm0, mm1					; mm0 = tu[1]*3 | tu[0] * 3
	pfmul		mm4, mm5					; mm4 = 0 | tu[2] * 3
	    
	pfsub		mm0, mm2					; mm0 = tu[1]*3 - tr[1] | tu[0]*3 - tr[0]
	pfsub		mm4, mm6					; mm4 = 0 | tu[2]*3 - tr[2]
	    
	pfadd		mm3, mm0					; mm3 = p->o[1] + mm0[63:32] | p->o[0] +  mm0[31:0]
	pfadd		mm7, mm4					; mm7 = p->o[2] + mm4[31:0]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm3					; mm1 <- mm3
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm7   			; mm7[31:0] on stack

	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm1			; mm1[31:0] onto stack
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm3			; mm3[31:0] onto stack

	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1648 : 
; 1649 :          qglTexCoord2f( 0.0625, 1.0625 );

	push		1065877504				; 3f880000H
	push		1031798784				; 3d800000H
$L44827:
	call		DWORD PTR _qglTexCoord2f

; 1650 :          qglVertex3f( p->origin[0] - tmpup[0] + tmpright[0]*3,
; 1651 :                      p->origin[1] - tmpup[1] + tmpright[1]*3,
; 1652 :                    p->origin[2] - tmpup[2] + tmpright[2]*3);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpright$[esp+72]	; mm0 = tr[1] | tr[0]
	movq		mm1, QWORD PTR [Float3x2]		; mm1 = 3.0 | 3.0
	movq		mm2, QWORD PTR _tmpup$[esp+72]	; mm2 = tu[1] | tu[0]
	movq		mm3, QWORD PTR [edi]			; mm3 = p->o[1] | p->o[0]
	    
	movd		mm4, DWORD PTR _tmpright$[esp+80]	; mm4 = 0 | tr[2]
	movd		mm5, DWORD PTR [Float3]			; mm5 = 0 | 3.0
	movd		mm6, DWORD PTR _tmpup$[esp+80]	; mm6 = 0 | tu[2]
	movd		mm7, DWORD PTR [esi]			; mm7 = 0 | p->o[2]
	   
	pfmul		mm0, mm1					; mm0 = tr[1]*3 | tr[0] * 3
	pfmul		mm4, mm5					; mm4 = 0 | tr[2] * 3
	    
	pfadd		mm3, mm0					; mm3 = p->o[1] +  tr[1]*3 | p->o[0] + tr[0]*3
	pfadd		mm7, mm4					; mm6 = 0 | p->o[2] + tr[2]*3
	    
	pfsub		mm3, mm2					; mm3 = mm3[63:32] - tu[1] | mm3[31:0] - tu[0]
	pfsub		mm7, mm6					; mm7 = mm7[31:0] - tu[2]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm3					; mm1 <- mm3
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm7   			; mm7[31:0] on stack

	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm1			; mm1[31:0] onto stack
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm3			; mm3[31:0] onto stack
	    
	femms
	call		DWORD PTR _qglVertex3f
	femms

$L44011:
	mov		eax, DWORD PTR -52+[esp+72]
	add		esi, 36					; 00000024H
	dec		eax
	mov		DWORD PTR -52+[esp+72], eax
	jne		$L44010
$L44012:

; 1653 :       }
; 1654 :       }
; 1655 :    qglEnd ();

	call		DWORD PTR _qglEnd

; 1656 : 
; 1657 :    // Now do the regular particles
; 1658 :    
; 1659 :    qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

	push		771					; 00000303H
	push		770					; 00000302H
	call		DWORD PTR _qglBlendFunc

; 1660 :    qglBegin( GL_TRIANGLES );

	push		4
	call		DWORD PTR _qglBegin

; 1661 : 
; 1662 :    VectorScale (vup, 2.5, up);

	lea		edx, DWORD PTR _up$[esp+72]
	push		edx
	push		1075838976				; 40200000H
	push		OFFSET FLAT:_vup
	call		_VectorScale
	add		esp, 12					; 0000000cH

; 1663 :    VectorScale (vright, 2.5, right);

	lea		eax, DWORD PTR _right$[esp+72]
	push		eax
	push		1075838976				; 40200000H
	push		OFFSET FLAT:_vright
	call		_VectorScale
	add		esp, 12					; 0000000cH

; 1664 : 
; 1665 :    for ( p = particles, i=0 ; i < num_particles ; i++,p++)

	test		ebx, ebx
	jle		$L44028
	mov		ecx, DWORD PTR _particles$[esp+68]
	lea		esi, DWORD PTR [ecx+32]
$L44026:

; 1666 :       {  
; 1667 :       // had to add this to not draw fire particles twice
; 1668 :       if(p->flags & (PARTICLE_OVERBRIGHT|PARTICLE_FIRE|PARTICLE_ADDITIVE))

	test		BYTE PTR [esi-4], 14			; 0000000eH
	jne		$L44027

; 1669 :          continue;
; 1670 : 
; 1671 :       // hack a scale up to keep particles from disapearing
; 1672 :       scale = ( p->origin[0] - r_origin[0] ) * vpn[0] +
; 1673 :              ( p->origin[1] - r_origin[1] ) * vpn[1] +
; 1674 :              ( p->origin[2] - r_origin[2] ) * vpn[2];

; IGX compute scale using 3DNow!
	femms
	movq		mm0, QWORD PTR [esi-32]			; mm0 = p->o[1] | p->o[0]
	movq		mm1, QWORD PTR _r_origin		; mm1 = r_o[1] | r_o[0]
	movq		mm2, QWORD PTR vpn			; mm2 = vpn[1] | vpn[0]
	    
	movd		mm3, DWORD PTR [esi-24]			; mm3 = 0 | p->o[2]
	pfsub		mm0, mm1					; mm0 = p->o[1] - r_o[1] | p->o[0] - r_o[0]
	movd		mm4, DWORD PTR _r_origin+8		; mm4 = 0 | r_o[2]
	pfmul		mm0, mm2					; mm0 = mm0 * mm2
	movd		mm5, DWORD PTR _vpn+8			; mm4 = 0 | vpn[2]
	pfsub		mm3, mm4					; mm3 = mm3 - mm4
	pfacc		mm0, mm0					; mm0 = vpn[1] *(p->o[1] - r_o[1]) + vpn[0]*(p->o[0] - r_o[0]) | ibid 
	pfmul		mm3, mm5					; mm3 = mm3 * mm5
	pfadd		mm0, mm3					; mm0 = scale as above
	    
	movd		DWORD PTR _scale$[esp+68], mm0	; scale = mm0[31:0]

; 1675 : 
; 1676 :       // added variable sizes
; 1677 :       if(!p->size) // partizle size 0 indicated a regular particle

	mov		eax, DWORD PTR [esi]
	cmp		eax, 0
	jne		$L44030


; 1678 :       {
; 1679 :          if (scale < 20)

; IGX Comparison using 3DNow!
	movd		mm2, DWORD PTR [Float_20]		; mm2 = 0.0 | 20.0
	movd        mm1, DWORD PTR _scale$[esp+68]	; mm1 = 0.0 | scale
	pfcmpge	mm1, mm2    				; mm1 = dc  | scale >= 20.0 ? ffffffff : 0
	movd		eax, mm1					; eax	<- mm1[31:0]
	cmp		eax, 0
	jne		$L44031					; jmp if scale is !< 20.0

; 1680 :             scale = 1;

	mov		DWORD PTR _scale$[esp+68], 1065353216	; 3f800000H

; 1681 :          else

	jmp		SHORT $L44032
$L44031:

; 1682 :             scale = 1 + scale * 0.004;
	
; IGX. Compute scale using 3DNow!
	movd		mm0, DWORD PTR [Float_004]		; mm0 = 0 | .004
	movd		mm1, DWORD PTR _scale$[esp+68]	; mm1 = 0 | scale
	movd		mm2, DWORD PTR [FloatOne]		; mm2 = 0 | p->size
	    								
	pfmul		mm0, mm1					; mm0 = 0 | scale * .004
	pfadd		mm0, mm2					; mm0 = 0 | 1.0 + scale * .004
	movd		DWORD PTR _scale$[esp+68], mm0	; scale = mm0[31:0]
	femms								
									
$L44032:
	lea		edx, DWORD PTR [esi-20]

; 1683 : 
; 1684 :          qglColor4fv( p->color );

	push		edx
	call		DWORD PTR _qglColor4fv

; 1685 : 
; 1686 :          qglTexCoord2f( 0.0625, 0.0625 );

	push		1031798784				; 3d800000H
	push		1031798784				; 3d800000H
	call		DWORD PTR _qglTexCoord2f

; 1687 :          qglVertex3fv( p->origin );

	push		edi
	call		DWORD PTR _qglVertex3fv

; 1688 :          
; 1689 :          qglTexCoord2f( 1.0625, 0.0625 );

	push		1031798784				; 3d800000H
	push		1065877504				; 3f880000H
	call		DWORD PTR _qglTexCoord2f

; 1690 :          qglVertex3f( p->origin[0] + up[0]*scale,
; 1691 :             p->origin[1] + up[1]*scale,
; 1692 :             p->origin[2] + up[2]*scale);
	 
; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movd		mm7, _scale$[esp+68]			; mm7 = 0 | scale
	movq		mm0, QWORD PTR _up$[esp+72]		; mm0 = up[1] | up[0]
	movq		mm1, QWORD PTR [edi]			; mm1 = p->o[1] | p->o[0]
	    
	punpckldq	mm7, mm7					; mm7 = scale | scale
	    
	movd		mm2, DWORD PTR _up$[esp+80]		; mm2 = 0 | up[2]
	movd		mm3, DWORD PTR [esi-24]			; mm3 = 0 | p->o[2]
	    
	pfmul		mm0, mm7					; mm0 = up[1] * scale | up[0] * scale
	pfmul		mm2, mm7					; mm2 = 0 | up[2] * scale
	    
	pfadd		mm0, mm1					; mm0 = p->o[1] + up[1]*scale | p->o[0] + up[0] * scale
	pfadd		mm2, mm3					; mm2 = p->o[2] + up[2]*scale
	push		ecx						; make space on stack
	    
	movd		DWORD PTR [esp], mm2			; top of stack = p->o[2] + up[2] * scale
	movq		mm1, mm0					; save a copy of mm0
	push		ecx						; make room on stack
	psrlq		mm1, 32					; mm1 = 0 | p->o[1] + up[1]*scale
	movd		DWORD PTR [esp], mm1			; stop of stack = mm1[31:0]
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm0			; top of stack = mm0[31:0]
	femms
	call		DWORD PTR _qglVertex3f
	femms 
     
; 1693 :          
; 1694 :          qglTexCoord2f( 0.0625, 1.0625 );

	push		1065877504				; 3f880000H
	push		1031798784				; 3d800000H
	call		DWORD PTR _qglTexCoord2f

; 1695 :          qglVertex3f( p->origin[0] + right[0]*scale,
; 1696 :             p->origin[1] + right[1]*scale,
; 1697 :             p->origin[2] + right[2]*scale);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movd		mm7, _scale$[esp+68]			; mm7 = 0 | scale
	movq		mm0, QWORD PTR _right$[esp+72]	; mm0 = r[1] | r[0]
	movq		mm1, QWORD PTR [edi]			; mm1 = p->o[1] | p->o[0]
	    
	punpckldq	mm7, mm7					; mm7 = scale | scale
	   
	movd		mm2, DWORD PTR _right$[esp+80]	; mm2 = 0 | r[2]
	movd		mm3, DWORD PTR [esi-24]			; mm3 = 0 | p->o[2]
	    
	pfmul		mm0, mm7					; mm0 = r[1] * scale | r[0] * scale
	pfmul		mm2, mm7					; mm2 = 0 | r[2] * scale
	    
	pfadd		mm0, mm1					; mm0 = p->o[1] + r[1]*scale | p->o[0] + r[0] * scale
	pfadd		mm2, mm3					; mm2 = p->o[2] + r[2]*scale
	push		ecx						; make space on stack
	    
	movd		DWORD PTR [esp], mm2			; top of stack = p->o[2] + r[2] * scale
	movq		mm1, mm0					; save a copy of mm0
	push		ecx						; make room on stack
	psrlq		mm1, 32					; mm1 = 0 | p->o[1] + r[1]*scale
	movd		DWORD PTR [esp], mm1			; stop of stack = mm1[31:0]
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm0			; top of stack = mm0[31:0]
	femms
	call		DWORD PTR _qglVertex3f
	femms    

	jmp		$L44027

; 1698 : 
; 1699 : 
; 1700 :          continue;

$L44030:

; 1701 :       }
; 1702 : 
; 1703 :       // particles using the added effects are handled below
; 1704 :       if(p->size > 0)

;IGX.  Do comparison with 3DNow!
	movd		mm1, DWORD PTR [Float_0]		; mm1 = 0 | 0.0
	movd		mm0, DWORD PTR [esi]			; mm0 = 0 | p->size
	pfcmpgt	mm0, mm1					; mm0 = 0 | p->size > 0.0 ? ffffffff : 0
	movd		eax, mm0					; eax <- mm0[31:0]
	cmp		eax, 0
	je		SHORT $L44033				; jmp if p->size > 0.0

; 1705 :          scale /= p->size;

;IGX.  Compute scale using 3DNow!
	movd		mm0, DWORD PTR [esi]			; mm0 = 0 | p->size
	movd		mm7, _scale$[esp+68]			; mm7 = 0 | scale
	pfrcp		mm0 ,mm0					; mm0 = 0 | 1/p->size
	pfmul		mm0,mm7					; mm0 = 0 | scale/p->size

$L44033:

; 1706 : 
; 1707 :       if (scale < 20)

;IGX.  Do comparison using 3DNow!
	movd		mm0, DWORD PTR _scale$[esp+68]	; mm0 = 0 | scale 
	movd		mm2, DWORD PTR [Float_20]		; mm2 = 0 | 20.0
	pfcmpge	mm0, mm2					; mm0 = scale >= 20.0 ? ffffffff : 0
	movd		eax, mm0					; eax <- mm0[31:0]
	cmp		eax, 0
	jne		SHORT $L44034				; jmp if scale >= 20.0

; 1708 :          scale = p->size;

	mov		eax, DWORD PTR [esi]
	mov		DWORD PTR _scale$[esp+68], eax

; 1709 :       else

	jmp		SHORT $L44035
$L44034:

; 1710 :          scale = p->size + scale * 0.004;

;IGX.  Calculate scale using 3DNow!   
	movd		mm0, DWORD PTR [Float_004]		; mm0 = 0 | .004
	movd		mm1, DWORD PTR _scale$[esp+68]	; mm1 = 0 | scale
	movd		mm2, DWORD PTR [esi]			; mm2 = 0 | p->size
	
	pfmul		mm0, mm1					; mm0 = 0 | scale * .004
	pfadd		mm0, mm2					; mm0 = 0 | p->size + scale * .004
	movd		DWORD PTR _scale$[esp+68], mm0	; scale = mm0[31:0]
									
$L44035:
	lea		ecx, DWORD PTR [esi-20]

; 1711 : 
; 1712 :       qglColor4fv( p->color );

	push		ecx
	call		DWORD PTR _qglColor4fv

; 1713 : 
; 1714 :       //calc new up and right vectors based on 1/4 the particle's scale
; 1715 :       // this is to reduce the number of multiplies later
; 1716 :       VectorScale(up, (scale*0.25), tmpup);

;IGX.  Compute VectorScale parameters using 3DNow!
	movd		mm0, DWORD PTR _scale$[esp+68]	; mm0 = 0 | scale
	movd		mm1, DWORD PTR [Quarter]		; mm1 = 0 | 0.25
	lea		edx, DWORD PTR _tmpup$[esp+72]
	lea		eax, DWORD PTR _up$[esp+72]
	pfmul		mm0, mm1					; mm0 = scale * 0.25
	push		edx						; push tmpup
	movd		DWORD PTR -56+[esp+76], mm0		; save scale * 0.25
	mov		ebp, DWORD PTR -56+[esp+76]		; ebp = (scale * 0.25)
	push		ebp						; push (scale * 0.25)
	push		eax						; push up
	femms
	call		_VectorScale
	add		esp, 12					; 0000000cH

; 1717 :       VectorScale(right, (scale*0.25), tmpright);

	lea		ecx, DWORD PTR _tmpright$[esp+72]
	lea		edx, DWORD PTR _right$[esp+72]
	push		ecx						; push tmpright
	push		ebp						; push (scale * 0.25)
	push		edx						; push right
	call		_VectorScale
	add		esp, 12					; 0000000cH

; 1718 : 
; 1719 :       // added flame type particles & changed the particle's
; 1720 :       // vertex positions to center around the origin
; 1721 :       qglTexCoord2f( 0.0625, 0.0625 );

	push		1031798784				; 3d800000H
	push		1031798784				; 3d800000H
	call		DWORD PTR _qglTexCoord2f

; 1722 :       qglVertex3f( p->origin[0] - tmpup[0] - tmpright[0],
; 1723 :                   p->origin[1] - tmpup[1] - tmpright[1],
; 1724 :                 p->origin[2] - tmpup[2] - tmpright[2]);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpright$[esp+72]	; mm0 = tr[1] | tr[0]
	movq		mm1, QWORD PTR _tmpup$[esp+72]	; mm1 = tu[1] | tu[0]
	movq		mm2, QWORD PTR [edi]			; mm2 = p->o[1] | p->o[0]
	   
	movd		mm3, DWORD PTR _tmpright$[esp+80]	; mm3 = 0 | tr[2]
	movd		mm4, DWORD PTR _tmpup$[esp+80]	; mm4 = 0 | tu[2]
	movd		mm5, DWORD PTR [esi-24]			; mm5 = 0 | p->o[2]
	    
	pfadd		mm1, mm0					; mm1 = tu[1] + tr[1] | tu[0] + tr[0]
	pfadd		mm4, mm3					; mm4 = 0 | tu[2] + tr[2]
	    
	pfsub		mm2, mm1					; mm2 = p->o[1] - mm1[63:32] | p->o[0] - mm1[31:0]
	pfsub		mm5, mm4					; mm5 = 0 | p->o[2] - mm4[31:0]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm2					; mm1 <- mm2
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm5   			; move mm5[31:0] onto stack

	push		ecx						; make space on stack
	movd		DWORD PTR [esp], mm1			; move mm1[41:0] onto the stack
	push		ecx						; make room on the stack
	movd		DWORD PTR [esp], mm2			; move mm2[31:0] onto the stack
	    
	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1725 : 
; 1726 :       qglTexCoord2f( 1.0625, 0.0625 );

	push		1031798784				; 3d800000H
	push		1065877504				; 3f880000H
	call		DWORD PTR _qglTexCoord2f

; 1727 :       qglVertex3f( p->origin[0] + tmpup[0]*3 - tmpright[0],
; 1728 :                   p->origin[1] + tmpup[1]*3 - tmpright[1],
; 1729 :                 p->origin[2] + tmpup[2]*3 - tmpright[2]);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpup$[esp+72]	; mm0 = tu[1] | tu[0]
	movq		mm1, QWORD PTR [Float3x2]		; mm1 = 3.0 | 3.0
	movq		mm2, QWORD PTR _tmpright$[esp+72]	; mm2 = tr[1] | tr[0]
	movq		mm3, QWORD PTR [edi]			; mm3 = p->o[1] | p->o[0]
	    
	movd		mm4, DWORD PTR _tmpup$[esp+80]	; mm4 = 0 | tu[2]
	movd		mm5, DWORD PTR [Float3]			; mm5 = 0 | 3.0
	movd		mm6, DWORD PTR _tmpright$[esp+80]	; mm6 = 0 | tr[2]
	movd		mm7, DWORD PTR [esi-24]			; mm7 = 0 | p->o[2]
	    
	pfmul		mm0, mm1					; mm0 = tu[1]*3 | tu[0] * 3
	pfmul		mm4, mm5					; mm4 = 0 | tu[2] * 3
	    
	pfsub		mm0, mm2					; mm0 = tu[1]*3 - tr[1] | tu[0]*3 - tr[0]
	pfsub		mm4, mm6					; mm4 = 0 | tu[2]*3 - tr[2]
	    
	pfadd		mm3, mm0					; mm3 = p->o[1] + mm2[63:32] | p->o[0] +  mm2[31:0]
	pfadd		mm7, mm4					; mm7 = p->o[2] + mm6[31:0]
	    
	push		ecx						; make space on the stack
	movq		mm1, mm3					; mm1 <- mm3
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm7   			; mm7[31:0] on stack

	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm1			; mm1[31:0] onto stack
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm3			; mm3[31:0] onto stack

	femms
	call		DWORD PTR _qglVertex3f
	femms

; 1730 : 
; 1731 :       qglTexCoord2f( 0.0625, 1.0625 );

	push		1065877504				; 3f880000H
	push		1031798784				; 3d800000H
	call		DWORD PTR _qglTexCoord2f

; 1732 :       qglVertex3f( p->origin[0] - tmpup[0] + tmpright[0]*3,
; 1733 :                   p->origin[1] - tmpup[1] + tmpright[1]*3,
; 1734 :                 p->origin[2] - tmpup[2] + tmpright[2]*3);

; IGX - Compute qglVertex parameters using 3DNow!
	femms
	movq		mm0, QWORD PTR _tmpright$[esp+72]	; mm0 = tr[1] | tr[0]
	movq		mm1, QWORD PTR [Float3x2]		; mm1 = 3.0 | 3.0
	movq		mm2, QWORD PTR _tmpup$[esp+72]	; mm2 = tu[1] | tu[0]
	movq		mm3, QWORD PTR [edi]			; mm3 = p->o[1] | p->o[0]
	    
	movd		mm4, DWORD PTR _tmpright$[esp+80]	; mm4 = 0 | tr[2]
	movd		mm5, DWORD PTR [Float3]			; mm5 = 0 | 3.0
	movd		mm6, DWORD PTR _tmpup$[esp+80]	; mm6 = 0 | tu[2]
	movd		mm7, DWORD PTR [esi-24]			; mm7 = 0 | p->o[2]
	    
	pfmul		mm0, mm1					; mm0 = tr[1]*3 | tr[0] * 3
	pfmul		mm4, mm5					; mm4 = 0 | tr[2] * 3
	    
	pfadd		mm3, mm0					; mm3 = p->o[1] + tr[1]*3 | p->o[0] + tr[0]*3
	pfadd		mm7, mm4					; mm7 = 0 | p->o[2] + tr[2]*3
	    
	pfsub		mm3, mm2					; mm3 = mm3[63:32] - tu[1] | mm3[31:0] - tu[0]
	pfsub		mm7, mm6					; mm7 = mm7[31:0] - tu[2]
	   
	push		ecx						; make space on the stack
	movq		mm1, mm3					; mm1 <- mm3
	    
	psrlq		mm1, 32					; mm1 = 0 | mm1[63:32]
	movd		DWORD PTR [esp], mm7   			; mm7[31:0] on stack

	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm1			; mm1[31:0] onto stack
	push		ecx						; make room on stack
	movd		DWORD PTR [esp], mm3			; mm3[31:0] onto stack
	    
	femms
	call		DWORD PTR _qglVertex3f
	femms
    
$L44027:
	add		esi, 36					; 00000024H
	dec		ebx
	jne		$L44026
$L44028:

; 1735 :       }
; 1736 :    qglEnd ();

	call		DWORD PTR _qglEnd
			
; 1737 : 
; 1738 :    qglDisable( GL_BLEND );

	push		3042					; 00000be2H
	call		DWORD PTR _qglDisable

; 1739 :    qglColor4f( 1,1,1,1 );

	push		1065353216				; 3f800000H
	push		1065353216				; 3f800000H
	push		1065353216				; 3f800000H
	push		1065353216				; 3f800000H
	call		DWORD PTR _qglColor4f

; 1740 :    qglDepthMask( 1 );      // back to normal Z buffering

	push		1
	call		DWORD PTR _qglDepthMask

; 1741 :    GL_TexEnv( GL_REPLACE );

	push		7681					; 00001e01H
	call		_GL_TexEnv
	add		esp, 4

; 1742 :    }

	pop		edi
	pop		esi
	pop		ebp
	pop		ebx
	add		esp, 56					; 00000038H
	ret		0
_GL_DrawParticles ENDP
_TEXT	ENDS

endif

;	COMDAT _GL_LerpVerts
_TEXT	SEGMENT

_nverts$ =  8
_v$	 = 12
_ov$	 = 16
_verts$	 = 20
_lerp$	 = 24
_move$	 = 28
_frontv$ = 32
_backv$	 = 36

align	32
_GL_LerpVerts PROC NEAR				;	COMDAT

; 34	: 	if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )

     push      ebx                             ; save caller's register variable
     mov       ebx, DWORD PTR _currententity   ; currententity
assume ebx:ptr entity_t

     push      ebp                             ; save caller's frame pointer
     mov       eax, DWORD PTR _nverts$[esp+4]  ; nverts

     push      esi                             ; save caller's register variable
     mov       ecx, DWORD PTR [ebx].flags      ; currententity->flags
assume ebx:nothing

     push      edi                             ; save caller's register variable
     test      eax, eax                        ; nverts <= 0?

     mov       ebp, DWORD PTR _frontv$[esp+12] ; frontv
     jle       $LerpVertsDone                  ; yup, nverts <= 0, nothing to do

     mov       edi, DWORD PTR _backv$[esp+12]  ; backv
     test      ch, 1Ch                         ; currententity->flags & ( RF_SHELL_RED ..)

     femms                                     ; will use MMX/AMD3D, clear FPU/MMX registers

     movq      mm0, [ebp]                      ; frontv[1] | frontv[0]
     jz        $LerpVert                       ; do lerp without scaling                                ; do lerpvert   w/o scale

; 35	: 	{
; 36	: 		for (i=0 ; i < nverts; i++, v++, ov++, lerp+=3)
; 37	: 		{
; 38	: 			float *normal =	r_avertexnormals[verts[i].lightnormalindex];
; 39	: 
; 40	: 			lerp[0]	= move[0] + ov->v[0]*backv[0] +	v->v[0]*frontv[0] + normal[0] *	POWERSUIT_SCALE;
; 41	: 			lerp[1]	= move[1] + ov->v[1]*backv[1] +	v->v[1]*frontv[1] + normal[1] *	POWERSUIT_SCALE;
; 42	: 			lerp[2]	= move[2] + ov->v[2]*backv[2] +	v->v[2]*frontv[2] + normal[2] *	POWERSUIT_SCALE; 
; 43	: 		}
; 44	: 	}

     mov       ebx, DWORD PTR _verts$[esp+12]  ; verts
     movq      mm1, [edi]                      ; backv[1] | backv[0]

     movd      mm6, [ebp+8]                    ; 0 | frontv[2]
     movd      mm7, [edi+8]                    ; 0 | backv[2]

     nop                                       ; filler
     mov       edi, DWORD PTR _lerp$[esp+12]   ; lerp

     add       ebx, 3                          ; &(verts[i].lightnormalindex)
     mov       edx, DWORD PTR _move$[esp+12]   ; move

     movzx     esi, BYTE PTR [ebx]             ; verts[i].lightnormalindex
     mov       ecx, DWORD PTR _ov$[esp+12]     ; ov

     punpckldq mm6, mm7                        ; backv[2] | frontv[2]
     pxor      mm7, mm7                        ; 00000000 | 00000000

     mov       ebp, DWORD PTR _v$[esp+12]      ; v
     lea       esi, [esi*4]                    ; *4 

     lea       esi, [esi+esi*2]                ; *12 (r_avertexnormals has 3 columns)
     movq      mm5, QWORD PTR [edx]            ; move[1] | move[0]

     ;; here: eax=nvertex, ebx=verts, ecx=ov, edx=move, edi=lerp, ebp=v
     ;;       mm0= frontv[1]|frontv[0], mm1=backv[1]|backv[0], mm6=, mm7= , mm5=

$LerpVertScaleLoop:

     movq      mm4, [ebp]                      ; 0 |  v->v[3]v[2]v[1]v[0]
     add       ebp, 4                          ; v++

     movq      mm2, [ecx]                      ; 0 | ov->v[3]v[2]v[1]v[0]
     add       ecx, 4                          ; ov++

     punpcklbw mm4, mm7                        ;  v-> 0 v[3] 0 v[2] |  v-> 0 v[1] 0 v[0]
;     add       edi, 12                         ; lerp+=3
     add       edi, 16                         ; lerp+=4

     punpcklbw mm2, mm7                        ; ov-> 0 v[3] 0 v[2] | ov-> 0 v[1] 0 v[0]
     nop                                       ; filler

     movq      mm3, mm4                        ;  v-> 0 v[3] 0 v[2] |  v-> 0 v[1] 0 v[0]
     punpcklwd mm4, mm7                        ;  v-> 0 0 0 v[1]    |  v-> 0 0 0 v[0]

     punpckhwd mm3, mm2                        ; ov->0v[3] v->0v[3] | ov->0v[2] v->0v[2]
     punpcklwd mm2, mm7                        ; ov-> 0 0 0 v[1]    | ov-> 0 0 0 v[0]

     pi2fd     mm4, mm4                        ; float(v->v[1])     | float(v->v[0])
     punpcklwd mm3, mm7                        ; ov-> 0 0 0 v[2]    |  v-> 0 0 0 v[2]    

     pi2fd     mm2, mm2                        ; float(ov->v[1])    | float(ov->v[0])
     pfmul     mm4, mm0                        ; v->v[1]*frontv[1]  |  v->v[0]*frontv[1]

     pi2fd     mm3, mm3                        ; float(ov->v[2])    | float(v->v[2])
     nop                                       ; filler

     pfmul     mm2, mm1                        ; ov->v[1]*backv[1]  | ov->v[0]*backv[0]
     pfadd     mm4, mm5                        ; move[1] + ov->v[1]*backv[1] | move[0] + ov->v[0]*backv[0]

     pfmul     mm3, mm6                        ; ov->v[2]*backv[2]  |  v->v[2]*frontv[2]
     movq      mm5, QWORD PTR [$PowerSuitScale]; POWERSUIT_SCALE | POWERSUIT_SCALE

     pfadd     mm2, mm4                        ; move[1] + ov->v[1]*backv[1]   + v->v[1]*frontv[1]
     movq      mm4, QWORD PTR _r_avertexnormals[esi] ; normal[1] | normal[0]

     add       ebx, 4                          ; &(verts[i].lightnormalindex)
     pfacc     mm3, mm3                        ; ov->v[2]*backv[2] + v->v[2]*frontv[2] | ov->v[2]*backv[2] + v->v[2]*frontv[2]

     movq      mm7, QWORD PTR [edx+8]          ; move[2]
     pfmul     mm4, mm5                        ; normal[1]*POWERSUIT_SCALE | normal[0]*POWERSUIT_SCALE

     pfadd     mm3, mm7                        ; move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2]
     movq      mm7, QWORD PTR _r_avertexnormals[esi+8] ; normal[2]

     pfadd     mm2, mm4                        ; move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1] + normal[1]*POWERSUIT_SCALE 
     movzx     esi, BYTE PTR [ebx]             ; verts[i].lightnormalindex

     dec       eax                             ; nverts--
     pfmul     mm7, mm5                        ; normal[2]*POWERSUIT_SCALE

     movq      mm5, QWORD PTR [edx]            ; move [1] | move [0], for next iteration
     lea       esi, [esi+esi*2]                ; *3

;     movq      QWORD PTR [edi-12], mm2         ; lerp[1] | lerp[0]
     movq      QWORD PTR [edi-16], mm2         ; lerp[1] | lerp[0]
     pfadd     mm3, mm7                        ; move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2] + normal[2]*POWERSUIT_SCALE

     lea       esi, [esi*4]                    ; *12, normal
     pxor      mm7, mm7                        ; 00000000 | 00000000, for next iteration

;     movd      DWORD PTR [edi-4], mm3          ; lerp[2]
     movd      DWORD PTR [edi-8], mm3          ; lerp[2]
     jnz       $LerpVertScaleLoop              ; until nverts == 0

     femms                                     ; done with AMD3D, empty FPU/MMX registers

     pop       edi                             ; restore caller's register variable
     pop       esi                             ; restore caller's register variable

     pop       ebp                             ; restore frame pointer
     pop       ebx                             ; restore caller's register variable

     ret                                       ; done

     ALIGN 32
     npad 6

$LerpVert:

; 45	: 	else
; 46	: 	{
; 47	: 		for (i=0 ; i < nverts; i++, v++, ov++, lerp+=3)
; 48	: 		{
; 49	: 			lerp[0]	= move[0] + ov->v[0]*backv[0] +	v->v[0]*frontv[0];
; 50	: 			lerp[1]	= move[1] + ov->v[1]*backv[1] +	v->v[1]*frontv[1];
; 51	: 			lerp[2]	= move[2] + ov->v[2]*backv[2] +	v->v[2]*frontv[2];
; 52	: 		}
; 53	: 	}

     movq      mm1, [edi]                      ; backv[1] | backv[0]
     movd      mm6, [ebp+8]                    ; 0 | frontv[2]

     movd      mm7, [edi+8]                    ; 0 | backv[2]
     mov       edx, DWORD PTR _move$[esp+12]   ; move

     mov       edi, DWORD PTR _lerp$[esp+12]   ; lerp
     mov       ecx, DWORD PTR _ov$[esp+12]     ; ov

     mov       ebp, DWORD PTR _v$[esp+12]      ; v
     movq      mm5, QWORD PTR [edx]            ; move[1] | move[0]

     punpckldq mm6, mm7                        ; backv[2] | frontv[2]
     pxor      mm7, mm7                        ; 00000000 | 0000000

$LerpVertLoop:

     movq      mm4, [ebp]                      ; 0 |  v->v[3]v[2]v[1]v[0]
     add       ebp, 4                          ; v++

     movq      mm2, [ecx]                      ; 0 | ov->v[3]v[2]v[1]v[0]
     add       ecx, 4                          ; ov++

     punpcklbw mm4, mm7                        ;  v-> 0 v[3] 0 v[2] |  v-> 0 v[1] 0 v[0]
;     add       edi, 12                         ; lerp+=3
     add       edi, 16                         ; lerp+=4

     punpcklbw mm2, mm7                        ; ov-> 0 v[3] 0 v[2] | ov-> 0 v[1] 0 v[0]
     movq      mm3, mm4                        ;  v-> 0 v[3] 0 v[2] |  v-> 0 v[1] 0 v[0]

     punpcklwd mm4, mm7                        ;  v-> 0 0 0 v[1]    |  v-> 0 0 0 v[0]
     punpckhwd mm3, mm2                        ; ov->0v[3] v->0v[3] | ov->0v[2] v->0v[2]

     punpcklwd mm2, mm7                        ; ov-> 0 0 0 v[1]    | ov-> 0 0 0 v[0]
     pi2fd     mm4, mm4                        ; float(v->v[1])     | float(v->v[0])

     punpcklwd mm3, mm7                        ; ov-> 0 0 0 v[2]    |  v-> 0 0 0 v[2]    
     pi2fd     mm2, mm2                        ; float(ov->v[1])    | float(ov->v[0])

     pfmul     mm4, mm0                        ; v->v[1]*frontv[1]  |  v->v[0]*frontv[1]
     pi2fd     mm3, mm3                        ; float(ov->v[2])    | float(v->v[2])

     dec       eax                             ; nverts--
     pfmul     mm2, mm1                        ; ov->v[1]*backv[1]  | ov->v[0]*backv[0]

     pfmul     mm3, mm6                        ; ov->v[2]*backv[2]  |  v->v[2]*frontv[2]
     pfadd     mm4, mm5                        ; move[1] + ov->v[1]*backv[1] | move[0] + ov->v[0]*backv[0]

     pfadd     mm2, mm4                        ; move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1] | ...
     pfacc     mm3, mm3                        ; ov->v[2]*backv[2] + v->v[2]*frontv[2] | ...

     movd      mm4, DWORD PTR [edx+8]          ; move[2]
;     movq      QWORD PTR [edi-12], mm2         ; lerp[1] | lerp[0]
     movq      QWORD PTR [edi-16], mm2         ; lerp[1] | lerp[0]

     pfadd     mm3, mm4                        ; move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2]
     nop                                       ; filler

;     movd      DWORD PTR [edi-4], mm3          ; lerp[2]
     movd      DWORD PTR [edi-8], mm3          ; lerp[2]
     jnz       $LerpVertLoop                   ; until nverts == 0

     femms                                     ; done with AMD3D, empty FPU/MMX registers

$LerpVertsDone:

     pop       edi                             ; restore caller's register variable
     pop       esi                             ; restore caller's register variable

     pop       ebp                             ; restore frame pointer
     pop       ebx                             ; restore caller's register variable

     ret                                       ; done
_GL_LerpVerts ENDP
_TEXT	ENDS

CONST	SEGMENT
$T25993	DD	0c0800000r			; -4
ALIGN 8
$LowByteMask	DQ 000000FF000000FFh
$PowerSuitScale	DQ 4080000040800000h	;	4 | 4
CONST	ENDS

CONST	SEGMENT
	align 8
Abs_mask	DQ			07fffffff7fffffffr
Const_DLIGHT_CUTOFF	DQ	04280000042800000r	; this const correspond	to'DLIGHT_CUTOFF' define in gl_light.c file
CONST	ENDS

_BSS	SEGMENT

ifndef SIN
_s_lerped textequ <lerped>
endif

PUBLIC  _s_lerped
align 8

Texture_0_1	DQ	01H DUP	(?)
;_s_lerped 	DD 	02000H DUP (?)
_s_lerped 	DD 	(4*MAX_VERTS) DUP (?)

_BSS	ENDS


;	COMDAT _R_AddDynamicLights
_TEXT	SEGMENT
_surf$ = 8
_lnum$ = -44
_rad$ =	-72
_minlight$ = -36
_impact$ = -24
_local$	= -12
_smax$ = -40
_tmax$ = -28

align	32
x_R_AddDynamicLights PROC NEAR				; COMDAT
; 341	: {
	sub	esp, 72					; 00000048H

; 342	: 	int			lnum;
; 343	: 	int			sd, td;
; 344	: 	float		dist, rad, minlight;
; 345	: 	vec3_t		impact, local;
; 346	: 	int			s, t;
; 347	: //	int			i;
; 348	: 	int			smax, tmax;
; 349	: 	mtexinfo_t	*tex;
; 350	: 	dlight_t	*dl;
; 351	: 	float		*bl;
; 352	: 
; 353	: 	smax = (surf->extents[0]>>4)+1;

	mov		edx, dword ptr _surf$[esp+68]
	push		ebx

	push		ebp

; 354	: 		tmax = (surf->extents[1]>>4)+1;
; 355	: 		tex = surf->texinfo;
; 356	: 
; 357	: 		for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)

	xor		ecx, ecx
	movsx		eax, WORD ptr [edx+24]

	movsx		ebp, WORD ptr [edx+26]
	sar		eax, 4

	mov		ebx, dword ptr [edx+56]
	inc		eax

	sar		ebp, 4
	mov		dword ptr _smax$[esp+80], eax

	inc		ebp
	mov		eax, dword ptr _r_newrefdef+88

	cmp		eax, ecx
	mov		dword ptr _tmax$[esp+80], ebp

	mov		dword ptr _lnum$[esp+80], ecx
	jle		_R_ADL_Exit

	push		edi
	push		esi

	mov		dword ptr -56+[esp+88], ecx
	femms

align	32
$L25885:

; 358	: 		{
; 359	: 			if ( !(surf->dlightbits	& (1<<lnum) ) )

	mov		eax, 1
	shl		eax, cl

	test		eax, dword ptr [edx+64]
	je		$L25886

; 360	: 				continue;		// not lit by this light
; 361	: 
; 362	: 			dl = &r_newrefdef.dlights[lnum];
; 363	: 			rad = dl->intensity;
; 364	: 			dist = DotProduct (dl->origin, surf->plane->normal) -
; 365	: 					surf->plane->dist;
	mov		ecx, dword ptr _r_newrefdef+92
	mov		eax, dword ptr -56+[esp+88]		;lnum	in eax

	lea		edi, dword ptr [ecx+eax]	;dl->origin				in edi
	mov		ecx, dword ptr [edx+4]		;surf->plane->normal	in ecx

	movq		mm0, [edi]		;dl->origin[1],dl->origin[0]
	movq		mm1, [ecx]		;surf->plane->normal[1],surf->plane->normal[0]	in mm1

	movq		mm2, [edi+8]		;0,dl->origin[2]							in mm2
	pfmul		mm0, mm1			;dl->origin[1]*surf->plane->normal[1],dl->origin[0]*surf->plane->normal[0]	in mm0	

	movq		mm3, [ecx+8]		;0,surf->plane->normal[2]					in mm3
	pfacc		mm0, mm0

 	pfmul		mm2, mm3			;0,dl->origin[2]*surf->plane->normal[2]		in mm2
	movq		mm4, [ecx+12]	;surf->plane->dist		in mm4

	pfadd		mm0, mm2			;undef,DotProduct		in mm0
	movq		mm1, [edi+24]	;0,dl->intensity		in mm1

	pfsub		mm0, mm4			;undef,dist				in mm0
	movd		mm3, dword ptr Const_DLIGHT_CUTOFF	

	movq		mm7, mm0			;undef, dist in	mm7	
	pand		mm0, Abs_mask	;undef, fabs(dist)		in mm0

	pfsub		mm1, mm0			;undef,rad -= fabs(dist)	in mm1
	punpckldq	mm7, mm7		;dist,dist	in mm7

	pcmpgtd		mm3, mm1			;undef, (rad < minlight)	in mm3
	movd		_rad$[esp+88], mm1

	movd		eax, mm3			
	test		eax, eax

	jnz		$L26097

; 371	: 			continue;
; 372	: 		minlight = rad - minlight;
; 373	: 		/*
; 374	: 		for (i=0 ; i<3 ; i++)
; 375	: 		{
; 376	: 			impact[i] = dl->origin[i] - surf->plane->normal[i]*dist;
; 377	: 		}
; 378	: 		*/
; 379	: 		impact[0] = dl->origin[0] - surf->plane->normal[0]*dist;
; 380	: 		impact[1] = dl->origin[1] - surf->plane->normal[1]*dist;
; 381	: 		impact[2] = dl->origin[2] - surf->plane->normal[2]*dist;
align	32
	movq		mm1, [ecx]		;surf->plane->normal[1],surf->plane->normal[0]	in mm1
	movq		mm0, [edi]		;dl->origin[1],dl->origin[0]
	;
	movd		mm3, [ecx+8]		;0,surf->plane->normal[2]		in mm3
	pfmul		mm1, mm7		;surf->plane->normal[1]*dist,surf->plane->normal[0]*dist	in mm1
	;
	movd		mm2, [edi+8]		;0,dl->origin[2]				in mm2
	pfsub		mm0, mm1		;impact[1],impact[0]			in mm0
	;
	movd		mm1, _rad$[esp+88]
	pfmul		mm3, mm7		;surf->plane->normal[2]*dist	in mm3	
	;
	movq		mm4, [ebx]		;tex->vecs[0][1],tex->vecs[0][0]
	;
	pfsub		mm2, mm3		;undef,impact[2]				in mm2
	movq		mm5, [ebx+8]		;tex->vecs[0][3],tex->vecs[0][2]	in mm5
	;
	pfsub		mm1, Const_DLIGHT_CUTOFF
	pfmul		mm4, mm0		;impact[1]*tex->vecs[0][1],impact[0]*tex->vecs[0][0]	in mm4
	;
	punpckldq	mm2, mm2		;impact[2],impact[2]			in mm2
	pfmul		mm0, [ebx+16]		;impact[1]*tex->vecs[1][1],impact[0]*tex->vecs[1][0]	in mm0
	;
	movd		_minlight$[esp+88], mm1
	movq		mm6, [ebx+24]	;tex->vecs[1][3],tex->vecs[1][2]	in mm6

; 383	: 		local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3] - surf->texturemins[0];
; 384	: 		local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3] - surf->texturemins[1];
	;
	pfacc		mm4, mm0
	movq		mm7, mm5
	;
	movsx		ecx, WORD ptr [edx+20]		;surf->texturemins[0]	in ecx
	punpckhdq	mm7, mm6	;tex->vecs[1][3],tex->vecs[0][3]	in mm7
	;
	movsx		eax, WORD ptr [edx+22]		;surf->texturemins[1]	in eax
	punpckldq	mm5, mm6	;tex->vecs[1][2],tex->vecs[0][2]	in mm5
	;
	pfadd		mm4, mm7	;DotProduct(impact,tex->vecs[1])+tex->vecs[1][3],DotProduct(impact,tex->vecs[0])+tex->vecs[0][3]	in mm4
	pfmul		mm5, mm2	;impact[2]*tex->vecs[1][2],impact[2]*tex->vecs[0][2]	in mm5	
	;
	mov		dword ptr Texture_0_1, ecx
	pfadd		mm4, mm5	;DotProduct(impact,tex->vecs[1]),DotProduct(impact,tex->vecs[0])	in mm4
	;
	mov		dword ptr Texture_0_1+4, eax
	pi2fd		mm3, Texture_0_1				;(float)surf->texturemins[1],(float)surf->texturemins[0] in mm3

	pfsub		mm4, mm3						;local[1],local[0]	in mm4
	test		ebp, ebp

	mov		esi, offset FLAT:_s_blocklights
	jle		$L25886

	mov		dword ptr -60+[esp+88], 0
	movq		mm3, mm4

	mov		dword ptr -48+[esp+88], ebp
	punpckhdq	mm3, mm3		;local[1],local[1]	in mm3

align	32
$L25890:

; 391	: 		{
; 392	: 			td = Q_ftol( local[1] -	t*16 );
; 393	: 			if (td < 0)
; 394	: 				td = -td;
	movd		mm0, dword ptr -60+[esp+88]	;0,t*16	in mm0
	pi2fd		mm0, mm0						;undef,(float)t*16		in mm0

	mov		eax, dword ptr _smax$[esp+88]
	pfsubr		mm0, mm3						;undef,local[1]-t*16	in mm0							

	pand		mm0, Abs_mask				;undef,if(td < 0)td=-td	in mm0
	test		eax, eax

	pf2id		mm0, mm0						;undef, td				in mm0
	movd		ebp, mm0

; 395	: 			for (s=0 ; s<smax ; s++, bl+=3)

	jle		$L25891
	mov		dword ptr -64+[esp+88], 0

	mov		dword ptr -52+[esp+88], eax
align	32
$L25894:

; 396	: 			{
; 397	: 				sd = Q_ftol( local[0] -	s*16 );

	movd		mm0, dword ptr -64+[esp+88]	;0,t*16	in mm0
	pi2fd		mm0, mm0						;undef,(float)t*16		in mm0

	pfsubr		mm0, mm4						;undef,local[1]-t*16	in mm0							
	pand		mm0, Abs_mask				;undef,if(td < 0)td=-td	in mm0

	pf2id		mm0, mm0						;undef, td				in mm0
	movd		eax, mm0

; 400	: 				if (sd > td)

	cmp		eax, ebp
	jle		short $L25898

; 401	: 					dist = sd + (td>>1);
	mov		ecx, ebp
	sar		ecx, 1

	add		ecx, eax
	mov		dword ptr -68+[esp+88], ecx

; 402	: 					else
	jmp		short $L25899
$L25898:
; 403	: 						dist = td + (sd>>1);
	sar		eax, 1

	add		eax, ebp
	mov		dword ptr -68+[esp+88], eax
$L25899:

; 404	: 				if (dist < minlight)
	pi2fd		mm0, qword ptr -68+[esp+88]			;undef,(float)dist		in mm0
	movd		mm1, dword ptr _minlight$[esp+88]	;0,minlight				in mm1

	movd		mm2, dword ptr _rad$[esp+88]		;0,rad	in mm2
	pcmpgtd		mm1, mm0								;undef,(dist<minlight)	in mm1

	movd		eax, mm1
	pfsub		mm2, mm0							;undef,rad-dist			in mm2

	test		eax, eax
	jz		$L26096

; 405	: 				{
; 406	: 					bl[0] += Q_ftol( (rad -	dist)*dl->color[0] );
; 407	: 					bl[1] += Q_ftol( (rad -	dist)*dl->color[1] );
; 408	: 					bl[2] += Q_ftol( (rad -	dist)*dl->color[2] );


;	mov		eax, esi		; Use EAX instead of esi to avoid [esi] addressing mode
	movq		mm1, [edi+12]           ;dl->color[1],dl->color[0] in mm1

	punpckldq	mm2, mm2                ;rad-dist,rad-dist in mm2
	movd		mm5, [edi+20]           ;0,dl->color[2] in mm5

	pfmul		mm1, mm2                ;(rad-dist)*dl->color[1],(rad-dist)*dl->color[1] in mm1
	movd		mm6, [esi+8]            ;0,bl[2] in mm6

	pfmul		mm5, mm2                ;0,(rad-dist)*dl->color[2] in mm5
	pf2id		mm1, mm1

	pf2id		mm5, mm5
	pi2fd		mm1, mm1

	pi2fd		mm5, mm5
	pfadd		mm1, [esi+0]            ;bl[1],bl[0] in mm1

	pfadd		mm5, mm6		;0,bl[2] in mm5
	movq		[esi+0], mm1

	movd		[esi+8],mm5	

align	32
$L26096:

; 404	: 				if (dist < minlight)

	mov		edx, dword ptr -64+[esp+88]
	mov		eax, dword ptr -52+[esp+88]

	add		edx, 16                 ; 00000010H
	add		esi, 12                 ; 0000000cH

	dec		eax
	mov		dword ptr -64+[esp+88], edx

	mov		dword ptr -52+[esp+88], eax
	jne		$L25894
$L25891:

; 385	: 
; 386	: 		//local[0] -= surf->texturemins[0];
; 387	: 		//local[1] -= surf->texturemins[1];
; 388	: 
; 389	: 		bl = blocklights;
; 390	: 		for (t = 0 ; t<tmax ; t++)

	mov		ecx, dword ptr -60+[esp+88]
	mov		eax, dword ptr -48+[esp+88]

	add		ecx, 16                 ; 00000010H
	dec		eax

	mov		dword ptr -60+[esp+88], ecx
	mov		dword ptr -48+[esp+88], eax

	jne		$L25890
	mov		ebp, dword ptr _tmax$[esp+88]

	mov		edx, dword ptr _surf$[esp+84]
	jmp		short $L25886
$L26097:

; 367	: 		// rad is now the highest intensity on the plane
; 368	: 
; 369	: 		minlight = DLIGHT_CUTOFF;	// FIXME: make configurable?
; 370	: 		if (rad	< minlight)

$L25886:

; 354	: 	tmax = (surf->extents[1]>>4)+1;
; 355	: 	tex = surf->texinfo;
; 356	: 
; 357	: 	for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)

	mov		ecx, dword ptr _lnum$[esp+88]
	mov		esi, dword ptr -56+[esp+88]

	mov		eax, dword ptr _r_newrefdef+88
	inc		ecx

	add		esi, 28					; 0000001cH
	cmp		ecx, eax

	mov		dword ptr _lnum$[esp+88], ecx
	mov		dword ptr -56+[esp+88], esi

	jl		$L25885
	pop		esi

	pop		edi
_R_ADL_Exit:
	femms
;$L25887:

; 409	: 				}
; 410	: 			}
; 411	: 		}
; 412	: 	}
; 413	: }
	pop		ebp
	pop		ebx

	add		esp, 72					; 00000048H
	ret
x_R_AddDynamicLights ENDP
_TEXT	ENDS
_DATA	SEGMENT
StrNonLitSurface	DB 'R_BuildLightMap called for non-lit surface', 0
StrBadBlocklightsSize	DB 'Bad	blocklights size', 0
_DATA	ENDS
CONST	SEGMENT
FloatOnex2	dq	3f8000003f800000h
FloatInv255x2	dq	3B8080813B808081h	; 1/255	| 1/255
Float255x2	dq	437f0000437f0000h 	; 255.0	| 255.0
MaskLowDword	dq	0FFFFFFFF00000000h
MaskHiDword	dq	00000000FFFFFFFFh
FloatInvThree	dq	000000003EAAAAABh	; 0 | 1/3

;$T26132		DD		3f800000r			; 1
$T26133		DD		437f0000r			; 255
$T26134		DQ	03f70101010101010r		; 0.00392157
CONST	ENDS
;	COMDAT _R_BuildLightMap
_TEXT	SEGMENT
_surf$ = 8
_dest$ = 12
_stride$ = 16
_smax$ = -36
_tmax$ = -44
;_r$ = -48
;_g$ = 8
;_b$ = -44
;_a$ = -40
;_max$ = -40
_scale$	= -16
_bl$ = -32
_monolightmap$ = -20
align	32

x_R_BuildLightMap PROC NEAR

    sub 		esp, 48
    push		ebx
    push		ebp
    push		esi

    femms

; #ifdef SIN
;     if ( (surf->texinfo->flags & (SURF_SKY|SURF_WARP|SURF_WAVY)) ||
;          (surf->texinfo->s->surfinfo->translucence > 0))
; #else
;     if ( surf->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP) )
; #endif

    mov 		esi, DWORD PTR _surf$[esp+56]
ifdef SIN
if 1
    push		edi

    mov 		eax, DWORD PTR [esi+56]
    mov 	 	ecx, 1036 				; 0000040cH

    mov	 		edi, DWORD PTR [eax+44]
    pxor                mm0, mm0

    mov	 		edi, DWORD PTR [edi]

    movd 		mm1, DWORD PTR [edi+100]

    pfcmpgt             mm1, mm0                                ; "-0" case
    and			ecx, DWORD PTR [eax+32]

    movd                ebp, mm1

    or			ebp, ecx
endif

else
    push		edi
    mov 		eax, DWORD PTR [esi+56]
    test		BYTE PTR [eax+32], 60			; 0000003cH
endif
    je  		SHORT $L25934

; ri.Sys_Error (ERR_DROP, "R_BuildLightMap called for non-lit surface");
    push		OFFSET FLAT:StrNonLitSurface
    push		1
    FCALL		DWORD PTR _ri
    add 		esp, 8
$L25934:

; smax = (surf->extents[0]>>4)+1;

	movsx		eax, WORD PTR [esi+24]

; tmax = (surf->extents[1]>>4)+1;

	movsx		ebp, WORD PTR [esi+26]
	sar		eax, 4
	sar		ebp, 4
	inc		eax
	inc		ebp
	mov		DWORD PTR _tmax$[esp+64], ebp

; size = smax*tmax;

	imul		ebp, eax

; if (size > (sizeof(blocklights)>>4) )

	cmp		ebp, 867				; 00000363H
	mov		DWORD PTR _smax$[esp+64], eax
	jbe		SHORT $L25936

; ri.Sys_Error (ERR_DROP, "Bad blocklights size");

	push		OFFSET FLAT:StrBadBlocklightsSize
	push		1
	FCALL		DWORD PTR _ri
	add		esp, 8
$L25936:
; set to full bright if	no light data
; if (!surf->samples)

	mov		ecx, DWORD PTR [esi+92]
	test		ecx, ecx
	jne		SHORT $L25938

; for (i=0 ; i<size*3 ;	i++)

	lea		ebp, DWORD PTR [ebp+ebp*2]
	test		ebp, ebp
	jle		SHORT $L25940

	mov		ecx, ebp
	mov		eax, 1132396544				; 437f0000H
	mov		edi, OFFSET FLAT:_s_blocklights
	rep		stosd
$L25940:

; blocklights[i] = 255;
; for (maps = 0	; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; maps++)

	xor		eax, eax
$L25943:
	cmp		BYTE PTR [eax+esi+72], 255		; 000000ffH
	je		$store$25946
	inc		eax
	cmp		eax, 4
	jl		SHORT $L25943

; style	= &r_newrefdef.lightstyles[surf->styles[maps]];
; goto store;
	jmp		$store$25946

$L25938:
; count	the # of maps
; for (	nummaps	= 0 ; nummaps <	MAXLIGHTMAPS &&	surf->styles[nummaps] != 255; nummaps++)

	xor		eax, eax
	lea		edx, DWORD PTR [esi+72]

$L25947:
	cmp		BYTE PTR [eax+edx], 255			; 000000ffH
	je		SHORT $L25949
	inc		eax
	cmp		eax, 4
	jl		SHORT $L25947
$L25949:

; lightmap = surf->samples;
; add all the lightmaps
; if ( nummaps == 1 )

	cmp		eax, 1
	mov		ebx, ecx
	jne		$L25950

	mov		eax, -72
	mov		edi, edx
	sub		eax, esi
	mov		DWORD PTR -40+[esp+64], eax
$L26137:
	mov		al, BYTE PTR [edi]
	cmp		al, 255
	je		$L25970
	mov		edx, DWORD PTR _r_newrefdef+76
	mov		esi, DWORD PTR _gl_modulate
	and		eax, 255
;	lea		ecx, DWORD PTR _scale$[esp+64]
	shl		eax, 4
	add		eax, edx
	movd		mm0, [esi+20]
	punpckldq	mm0, mm0
	movq		mm1, [eax]
	movd		mm2, [eax+8]
	pfmul		mm1, mm0
;	movq		[ecx], mm1
	movq		mm7, mm1
	pfmul		mm2, mm0
	movq		mm3, [FloatOnex2]
;	movd		[ecx+8], mm2
	movq		mm6, mm2
;	movq		mm0, qword ptr _scale$[esp+64]
;	movd		mm1, dword ptr _scale$[esp+72]
	movq		mm0, mm7
	movq		mm1, mm6
	pfcmpeq		mm0, mm3
	pfcmpeq		mm1, mm3
	pand		mm1, mm0
	punpckhdq	mm0, mm0
	pand		mm0, mm1
	movd		eax, mm0
	test		eax, eax
	jz		$L25958
; 
; bl = blocklights;
; 
; for (i=0 ; i<3 ; i++)
; 	scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
; 
; if ( scale[0]	== 1.0F	&& scale[1] == 1.0F && scale[2]	== 1.0F	)
;	for (i=0 ; i<size ; i++, bl+=3)

	test		ebp, ebp
	jle		$L25965

	mov		ecx, OFFSET FLAT:_s_blocklights+8
	lea		eax, DWORD PTR [ebx+2]
	mov		esi, ebp
	jmp		short $L25959
align	32
$L25959:
	movzx		edx, byte ptr [eax-2]
	add		ecx, 12

	movd		mm0, edx
	add		eax, 3

	movzx		edx, byte ptr [eax-4]
	movd		mm1, edx

	movzx		edx, byte ptr [eax-3]
	movd		mm2, edx

	punpckldq	mm0, mm1
	pi2fd		mm2, mm2

	pi2fd		mm0, mm0
	movq		[ecx-20], mm0

	dec		esi
	movd		[ecx-12], mm2

	jnz		$L25959

; bl[0]	= lightmap[i*3+0];
; bl[1]	= lightmap[i*3+1];
; bl[2]	= lightmap[i*3+2];

	jmp		SHORT $L25965
align	32
$L25958:
; for (i=0 ; i<size ; i++, bl+=3)

	test		ebp, ebp
	jle		SHORT $L25965
	mov		ecx, OFFSET FLAT:_s_blocklights+8
	lea		eax, DWORD PTR [ebx+2]
	mov		esi, ebp
	jmp		short $L25963

align	32
$L25963:
	movzx		edx, byte ptr [eax-2]
	add		ecx, 12
	movd		mm0, edx

	add		eax, 3
	movzx		edx, byte ptr [eax-4]

	movd		mm1, edx
	movzx		edx, byte ptr [eax-3]

	movd		mm2, edx
	punpckldq	mm0, mm1

	pi2fd		mm0, mm0
	dec		esi

	pfmul		mm0, mm7
	pi2fd		mm2, mm2

	movq		[ecx-20], mm0

	pfmul		mm2, mm6
	movd		[ecx-12], mm2

	jnz		$L25963

$L25965:
; for (maps = 0	; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;

	mov		ecx, DWORD PTR -40+[esp+64]

; lightmap += size*3	skip to	next lightmap

	mov		eax, ebp
; else

	mov		esi, DWORD PTR _surf$[esp+60]
	add		eax, ebx
	inc		edi
	add		ecx, edi
	lea		ebx, DWORD PTR [eax+ebp*2]
	cmp		ecx, 4
	jl		$L26137
	jmp		$L25970
align	32
$L25950:
; memset( blocklights, 0, sizeof( blocklights[0] ) * size * 3 );

	lea		ecx, DWORD PTR [ebp+ebp*2]
	xor		eax, eax

	shl		ecx, 2
	mov		esi, ecx

	mov		edi, OFFSET FLAT:_s_blocklights
	shr		ecx, 2

	rep		stosd

	mov		ecx, esi
	mov		esi, DWORD PTR _surf$[esp+60]

	and		ecx, 3
	rep 		stosb

	mov		eax, -72
	mov		edi, edx

	sub		eax, esi
	mov		DWORD PTR -40+[esp+64], eax
	jmp		$L26138
align	32
$L26138:
	mov		al, BYTE PTR [edi]
	cmp		al, 255

	je		$L25970
	mov		edx, DWORD PTR _r_newrefdef+76

	mov		esi, DWORD PTR _gl_modulate
	and		eax, 255

;	lea		ecx, DWORD PTR _scale$[esp+64]
	shl		eax, 4

	add		eax, edx
	movd		mm2, [esi+20]

	punpckldq	mm2, mm2
	movq		mm0, [eax]

	movd		mm1, [eax+8]
	pfmul		mm0, mm2

	pfmul		mm1, mm2
;	movq		[ecx], mm0
	movq		mm7, mm0

	movq		mm2, [FloatOnex2]
;	movd		[ecx+8], mm1
	movq		mm6, mm1

;	movq		mm0, _scale$[esp+64]
;	movd		mm1, _scale$[esp+72]

	pfcmpeq		mm0, mm2
	pfcmpeq		mm1, mm2

	pand		mm1, mm0
	punpckhdq	mm0, mm0

	pand		mm0, mm1
	movd		eax, mm0

	test		eax, eax
	lea		ecx, DWORD PTR [ebx+2]

	mov		eax, OFFSET FLAT:_s_blocklights+8
	jz		short $L25974

; bl = blocklights;
; 
; for (i=0 ; i<3 ; i++)
; 	scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
; 
; if ( scale[0]	== 1.0F	&& scale[1] == 1.0F && scale[2]	== 1.0F	)
; 	for (i=0 ; i<size ; i++, bl+=3 )

	test		ebp, ebp
	jle		$L25981

	mov		esi, ebp
	jmp		short $L25975
align	32
$L25975:
	movzx		edx, byte ptr [ecx-2]
	add		eax, 12

	movq		mm3, [eax-20]
	movd		mm0, edx

	add		ecx, 3
	movzx		edx, byte ptr [ecx-4]

	movd		mm1, edx
	movzx		edx, byte ptr [ecx-3]

	movd		mm2, edx
	punpckldq	mm0, mm1

	pi2fd		mm0, mm0
	dec		esi

	pfadd		mm0, mm3
	pi2fd		mm2, mm2

	movd		mm3, [eax-12]
	movq		[eax-20], mm0

	pfadd		mm2, mm3
	movd		[eax-12], mm2

	jnz		$L25975

; bl[0]	+= lightmap[i*3+0];
; bl[1]	+= lightmap[i*3+1];
; bl[2]	+= lightmap[i*3+2];

	jmp		$L25981
align	32
$L25974:

; for (i=0 ; i<size ; i++, bl+=3)

	test		ebp, ebp
	jle		SHORT $L25981
	mov		eax, OFFSET FLAT:_s_blocklights+8
	lea		ecx, DWORD PTR [ebx+2]
	mov		esi, ebp
	jmp		short $L25979
align	32
$L25979:
	movzx		edx, byte ptr [ecx-2]
	add		eax, 12

	movd		mm0, edx
	add		ecx, 3

	movzx		edx, byte ptr [ecx-4]
	movd		mm1, edx

	movq		mm5, [eax-20]
	movzx		edx, byte ptr [ecx-3]

	punpckldq	mm0, mm1
	movd		mm2, edx

	pi2fd		mm0, mm0
	pi2fd		mm2, mm2

	pfmul		mm0, mm7
	movd		mm4, [eax-12]

	pfadd		mm0, mm5
	pfmul		mm2, mm6

	dec		esi
	pfadd		mm2, mm4

	movq		[eax-20], mm0
	movd		[eax-12], mm2

	jnz		$L25979

$L25981:
; for (maps = 0	; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;

	mov		ecx, DWORD PTR -40+[esp+64]

; lightmap += size*3	skip to	next lightmap

	mov		eax, ebp
	mov		esi, DWORD PTR _surf$[esp+60]
	add		eax, ebx
	inc		edi
	lea		ebx, DWORD PTR [eax+ebp*2]
	lea		edx, DWORD PTR [edi+ecx]
	cmp		edx, 4
	jl		$L26138
$L25970:

; add all the dynamic lights
; if (surf->dlightframe	== r_framecount)

	mov		eax, DWORD PTR [esi+60]
	mov		ecx, DWORD PTR _r_framecount
	cmp		eax, ecx
	jne		SHORT $store$25946

; _R_AddDynamicLights (surf);

	push		esi
	call		x_R_AddDynamicLights
	add		esp, 4

$store$25946:	; stride -= (smax<<2);

	mov		ecx, DWORD PTR _smax$[esp+64]

; bl = blocklights;
; monolightmap = gl_monolightmap->string[0];

	mov		eax, DWORD PTR _gl_monolightmap
	mov		esi, DWORD PTR _stride$[esp+60]
	mov		edi, OFFSET FLAT:_s_blocklights
	lea		edx, DWORD PTR [ecx*4]
	mov		ecx, DWORD PTR [eax+4]
	sub		esi, edx
	mov		DWORD PTR _bl$[esp+64], edi
	movsx		eax, BYTE PTR [ecx]
	mov		DWORD PTR _monolightmap$[esp+64], eax

; if ( monolightmap == '0' )

	cmp		eax, 48

; for (i=0 ; i<tmax ; i++, dest	+= stride)

	mov		eax, DWORD PTR _tmax$[esp+64]
	mov		DWORD PTR _stride$[esp+60], esi
	jne		$L25983
	test		eax, eax
	jle		$L26001		; All Done

	mov		esi, DWORD PTR _dest$[esp+60]
	mov		DWORD PTR -32+[esp+64], eax
$L26135:
	mov		eax, DWORD PTR _smax$[esp+64]
	test		eax, eax
	jle		$L25985

; for (j=0 ; j<smax ; j++)

	mov	ebp, eax
$L25987:

	pxor		mm2, mm2	; mm2 =	0 | 0
	movq		mm0, [edi]

	movd		mm1, [edi+8]
	pfmax		mm0, mm2

	pfmax		mm1, mm2
	movq		mm2, mm0

	punpckhdq	mm2, mm2

;;; mm0	= g | r
;;; mm1	= X | b
;;; mm2	= g | g

	movq		mm3, mm0

	pfmax		mm3, mm1
	pfmax		mm3, mm2

	pf2id		mm4, mm3

	movd		eax, mm4

; 
; 
;	alpha is ONLY used for the mono lightmap case.	For this reason
;	we set it to	the brightest of the color components so that 
;	things don't	get too	dim.
; 
;	a = max;
; 
;	rescale all the color components if the intensity of	the greatest
;	channel exceeds 1.0
; 
; if (max > 255)

	cmp		eax, 255				; 000000ffH
	jle		ConvertFloatsToInts

;;; mm0	= g | r
;;; mm1	= X | b
;;; mm2	= g | g
;;; eax	= a

	punpckhdq	mm3, mm3		; mm4 =	(float)	max | (float) max
	pfmul		mm3, [FloatInv255x2]	; mm4 =	t | t
	pfmul		mm0, mm3		; mm0 =	g*t | r*t
	pfmul		mm1, mm3		; mm1 =	 X	| b*t

ConvertFloatsToInts:
	pf2id		mm0, mm0
	pf2id		mm1, mm1	

$L25996:
	movd		mm2, eax		; mm2 =	0 | a
	punpckldq	mm1, mm2		; mm0 =	g | r
						; mm1 =	a | b
	packssdw	mm0, mm1		; mm0 =	a	b | g	r
	packuswb	mm0, mm0		; mm0 =	a b g r	| a b g	r
	movd		[esi], mm0

; bl +=	3;

	add		edi, 12

; dest += 4;

	add		esi, 4
	dec		ebp
	jne		$L25987
$L25985:

; for (i=0 ; i<tmax ; i++, dest	+= stride)

	mov		ecx, DWORD PTR _stride$[esp+60]
	mov		eax, DWORD PTR -32+[esp+64]
	add		esi, ecx
	dec		eax
	mov		DWORD PTR -32+[esp+64], eax
	jne		$L26135

	pop		edi
	pop		esi
	pop		ebp
	pop		ebx
	add		esp, 48					; 00000030H
	femms
	ret		0
$L25983:

; else
; {
;	for (i=0 ; i<tmax ; i++, dest += stride)

	test		eax, eax
	jle		$L26001		; All Done


	mov		DWORD PTR -24+[esp+64], eax
	jmp		short $L25999
align	32
$L25999:

; for (j=0 ; j<smax ; j++)

	mov		eax, DWORD PTR _smax$[esp+64]
	test		eax, eax

	jle		$L26000
	mov		edx, eax

	mov		DWORD PTR -28+[esp+64], edx
	jmp		short $L26002

align	32
$L26002:
	mov		ebx, DWORD PTR _bl$[esp+64]

	pxor		mm2, mm2	; mm2 =	0 | 0
	movq		mm0, [ebx]	; mm0 =	bl[1] |	bl [0]

	movd		mm1, [ebx+8]	; mm1 =	 0	|	bl[2]
	pfmax		mm0, mm2	; mm0 =	(float)g | (float)r

	pfmax		mm1, mm2	; mm1 =	X | (float)b
	movq		mm2, mm0	; mm2 =	(float)g | (float)r

	movq		mm3, mm1	; mm3 =	X | (float)b
	pfmax		mm3, mm2	; mm3 =	X | (float) max	(r, b)

	punpckhdq	mm2, mm2	; mm2 =	g | g
	pfmax		mm2, mm3	; mm2 =	X | a (a = (float) max (g, max (r,b)))

	punpckldq	mm1, mm2	; mm1 =	(float)a | (float)b
	pf2id		mm2, mm2

	movd		ebx, mm2
;;; ebx	= (int)a
;;; mm0	= (float)g | (float)r
;;; mm1	= (float)a | (float)b

;
;
; alpha	is ONLY	used for the mono lightmap case.	For this reason
; we set it to the brightest of	the color components so	that 
; things don't get too dim.
;
;	a = max;
;
; rescale all the color	components if the intensity of the greatest
; channel exceeds 1.0
;
; if (max > 255)

	cmp	ebx, 255
	jle	SHORT $L26011

;;; mm0	= (float)g | (float)r
;;; mm1	= (float)a | (float)b

	movq		mm2, mm1

	punpckhdq	mm2, mm2
	pfmul		mm2, [FloatInv255x2]	; mm2 =	t | t

	pfmul		mm0, mm2
	pfmul		mm1, mm2

$L26011:

	mov	eax, DWORD PTR _monolightmap$[esp+64]
	cmp	eax, 'C'		;67
	je	SHORT $L26018
	cmp	eax, 'I'		;73
	je	SHORT $L26017
	cmp	eax, 'L'		;76
	je	SHORT $L26017
;;; mm0	= (float)g | (float)r
;;; mm1	= (float)a | (float)b
; r = g	= b = 0
; a = 255 - a
	pxor		mm0, mm0
	movq		mm2, mm1
	punpckldq	mm2, [Float255x2]	; mm2 =	(float)255 | b
	pfsubr		mm1, mm2

	jmp	SHORT $L26014
align	32
$L26017:

;;; mm0	= (float)g | (float)r
;;; mm1	= (float)a | (float)b
;r = a;
;g = b = 0;


	movq		mm0, mm1
	psrlq		mm0, 32

	pand		mm1, [MaskLowDword]
	jmp		SHORT $L26014
align	32
$L26018:
;;; mm0	= (float)g | (float)r
;;; mm1	= (float)a | (float)b
; a = 255 - ((r+g+b)/3);
; r *= a/255.0;
; g *= a/255.0;
; b *= a/255.0;

	movq		mm2, mm0
	pfacc		mm2, mm2		; mm2 =	r+g | r+g

	pfadd		mm2, mm1		; mm2 =	X | r+g+b
	punpckldq	mm2, mm2		; mm2 =	r+g+b |	r+g+b

	pfmul		mm2, [FloatInvThree]	; mm2 =	(r+g+b)/3 | (r+g+b)/3
	pfsubr		mm2, [Float255x2]	; mm2 =	255-((r+g+b)/3)	| 255-((r+g+b)/3)
						;	=	a | a
	movq		mm3, mm2		; mm3 =	a | a
	pfmul		mm2, [FloatInv255x2]	; mm2 =	a/255.0	| a/255.0

	pfmul		mm0, mm2
	pfmul		mm1, mm2

	punpckldq	mm1, mm3

$L26014:
;;; mm0	= (float)g | (float)r
;;; mm1	= (float)a | (float)b

	mov		esi, DWORD PTR _dest$[esp+60]

	pf2id		mm0, mm0		; mm0 =	g | r
	pf2id		mm1, mm1		; mm1 =	a | b

	packssdw	mm0, mm1		; mm0 =	a	b | g	r
	packuswb	mm0, mm0		; mm0 =	a b g r	| a b g	r

	movd		[esi], mm0
	mov		edx, DWORD PTR _bl$[esp+64]

	mov		eax, DWORD PTR -28+[esp+64]
	add		edx, 12

	add		esi, 4
	dec		eax

	mov		DWORD PTR _bl$[esp+64], edx
	mov		DWORD PTR _dest$[esp+60], esi

	mov		DWORD PTR -28+[esp+64], eax
	jne		$L26002

;;; mm0	= (float)g | (float)r
;;; mm1	= (float)a | (float)b

$L26000:

	mov		eax, DWORD PTR _stride$[esp+60]
	mov		ecx, DWORD PTR _dest$[esp+60]
	add		ecx, eax
	mov		eax, DWORD PTR -24+[esp+64]
	dec		eax
	mov		DWORD PTR _dest$[esp+60], ecx
	mov		DWORD PTR -24+[esp+64], eax
	jne		$L25999
$L26001:

	femms
	pop		edi
	pop		esi
	pop		ebp
	pop		ebx
	add		esp, 48
	ret		0
x_R_BuildLightMap ENDP

_TEXT	ENDS


EXTRN	_frustum:BYTE
;	COMDAT ??_C@_0CE@CJCD@R_CullAliasModel?3?5no?5such?5frame?5@
; File C:\Quake2\code\ref_gl\gl_mesh.c
_DATA	SEGMENT
??_C@_0CE@CJCD@R_CullAliasModel?3?5no?5such?5frame?5@ DB 'R_CullAliasMode'
	DB	'l: no such frame %d', 0aH, 00H		; `string'
_DATA	ENDS
;	COMDAT ??_C@_0CH@BKBK@R_CullAliasModel?3?5no?5such?5oldfra@
_DATA	SEGMENT
??_C@_0CH@BKBK@R_CullAliasModel?3?5no?5such?5oldfra@ DB	'R_CullAliasModel'
	DB	': no such oldframe %d', 0aH, 00H		; `string'
_DATA	ENDS


CONST	SEGMENT
	ALIGN 8
$twofiftyfive DQ 437f0000437f0000h	; 255 | 255
CONST	ENDS


;	COMDAT _R_CullAliasModel
_TEXT	SEGMENT

_bbox$     = 8-4
_e$        = 12-4
_mins$     = -148
_maxs$     = -108
_vectors$  = -96
_thismins$ = -12
_oldmins$  = -24
_thismaxs$ = -48
_oldmaxs$  = -36
_angles$   = -60
_tmp$25879 = -148

align	32
_R_CullAliasModel PROC NEAR				; COMDAT

; 254	: 	int i;
; 255	: 	vec3_t		mins, maxs;
; 256	: 	dmdl_t		*paliashdr;
; 257	: 	vec3_t		vectors[3];
; 258	: 	vec3_t		thismins, oldmins, thismaxs, oldmaxs;
; 259	: 	daliasframe_t *pframe, *poldframe;
; 260	: 	vec3_t angles;
; 261	: 
; 262	: 	paliashdr = (dmdl_t *)currentmodel->extradata;

ESP_currofs = 148

     mov       eax, DWORD PTR _currentmodel    ; currentmodel
assume eax:ptr model_t
     sub       esp, ESP_currofs                ; make room for local variables

; 263	: 
; 264	: 	if ( ( e->frame	>= paliashdr->num_frames ) || (	e->frame < 0 ) )
; 265	: 	{
; 266	: 		ri.Con_Printf (PRINT_ALL, "R_CullAliasModel: no	such frame %d\n", e->frame);
; 267	: 		e->frame = 0;
; 268	: 	}

     push      ebx                             ; save caller's register variable
ESP_currofs = ESP_currofs + 4
     mov       ebx, _e$[esp+ESP_currofs]       ; e
assume ebx:ptr entity_t

     push      esi                             ; save caller's register variable
ESP_currofs = ESP_currofs + 4
     mov       esi, [eax].extradata            ; +372(H) paliashdr = currentmodel->extradata
assume esi:ptr dmdl_t

     push      ebp                             ; save frame pointer
ESP_currofs = ESP_currofs + 4
     mov       eax, DWORD PTR [ebx].frame      ; +28(1CH) e->frame
assume eax:nothing

     mov       ecx, DWORD PTR [esi].num_frames ; +40(28H) paliashdr->num_frames 
     push      edi                             ; save caller's register variable
ESP_currofs = ESP_currofs + 4

     mov       edi, DWORD PTR [ebx].oldframe   ; +44(2CH) e->oldframe
     nop                                       ; filler

     cmp       eax, ecx                        ; e->frame >= paliashdr->num_frames ?
     jge       SHORT $print_frm_msg            ; yup, print message

     test      eax, eax                        ; e->frame < 0 ?
     jge       SHORT $print_frm_done           ; nope, don't print message

$print_frm_msg:
     push      eax                             ; e->frame
     push      OFFSET FLAT:??_C@_0CE@CJCD@R_CullAliasModel?3?5no?5such?5frame?5@ ; `string'

     push      0                               ; PRINT_ALL
     call      DWORD PTR _ri+24                ; ri.Con_Printf (..)

     mov       ecx, DWORD PTR [esi].num_frames ; +40(28H) paliashdr->num_frames (reload)
     nop                                       ; filler

     add       esp, 12                         ; pop 3 DWORD arguments off stack
     mov       DWORD PTR [ebx].frame, 0        ; +28(1CH) e->frame = 0
$print_frm_done:

; 269	: 	if ( ( e->oldframe >= paliashdr->num_frames ) || ( e->oldframe < 0 ) )
; 270	: 	{
; 271	: 		ri.Con_Printf (PRINT_ALL, "R_CullAliasModel: no	such oldframe %d\n", e->oldframe);
; 272	: 		e->oldframe = 0;
; 273	: 	}
; 274	: 

     mov       eax, DWORD PTR [esi].framesize  ; +16(10H) paliashdr->framesize
     cmp       edi, ecx                        ; e->oldframe >= paliashdr->num_frames ?

     mov       edx, DWORD PTR [esi].ofs_frames ; +56(38H) paliashdr->ofs_frames
     jge       SHORT $print_ofrm_msg           ; yup, print message

     test      edi, edi                        ; e->oldframe < 0 ?
     jge       SHORT $print_ofrm_done          ; nope, don't print message
$print_ofrm_msg:
     push      edi                             ; e->oldframe
     push      OFFSET FLAT:??_C@_0CH@BKBK@R_CullAliasModel?3?5no?5such?5oldfra@ ; `string'

     push      0                               ; PRINT_ALL
     call      DWORD PTR _ri+24                ; ri.Con_Printf (..)

     mov       eax, DWORD PTR [esi].framesize  ; +16(10H) paliashdr->framesize (reload)
     mov       edx, DWORD PTR [esi].ofs_frames ; +56(38H) paliashdr->ofs_frames (reload)

     add       esp, 12                         ; pop 3 DWORD arguments off stack
     mov       DWORD PTR [ebx].oldframe, 0     ; +44(2CH) e->oldframe = 0
$print_ofrm_done:

; 275	: 	pframe = ( daliasframe_t * ) ( ( byte *	) paliashdr + 
; 276	: 						paliashdr->ofs_frames +
; 277	: 										e->frame * paliashdr->framesize);
; 278	: 
; 279	: 	poldframe = ( daliasframe_t * )	( ( byte * ) paliashdr + 
; 280	: 						paliashdr->ofs_frames +
; 281	: 										e->oldframe *	paliashdr->framesize);

; stack offset = 164
     mov       ecx, eax                        ; paliashdr->framesize
     lea       edi, DWORD PTR _maxs$[esp+ESP_currofs]  ; maxs

     imul      eax, DWORD PTR [ebx].oldframe   ; +44(2CH) e->oldframe * paliashdr->framesize

     imul      ecx, DWORD PTR [ebx].frame      ; +28(1CH) e->frame * paliashdr->framesize

     femms                                     ; will use AMD3D, empty FPU/MMX registers

     add       eax, esi                        ; ( byte * ) paliashdr + e->oldframe * paliashdr->framesize
     add       ecx, esi                        ; ( byte * ) paliashdr + e->frame * paliashdr->framesize

     add       eax, edx                        ; ( byte * ) paliashdr + paliashdr->ofs_frames + e->oldframe * paliashdr->framesize
     add       ecx, edx                        ; ( byte * ) paliashdr + paliashdr->ofs_frames + e->frame * paliashdr->framesize


; 282	: 
; 283	: 	/*
; 284	: 	** compute axially aligned mins	and maxs
; 285	: 	*/
; 286	: 	if ( pframe == poldframe )
; 287	: 	{
; 288	: 		for ( i	= 0; i < 3; i++	)
; 289	: 		{
; 290	: 			mins[i]	= pframe->translate[i];
; 291	: 			maxs[i]	= mins[i] + pframe->scale[i]*255;
; 292	: 		}
; 293	: 	}

     movq      mm0, QWORD PTR [ecx+12]         ; pframe->translate[1] | pframe->translate[0]
     lea       edx, DWORD PTR _mins$[esp+ESP_currofs] ; mins

     movq      mm2, $twofiftyfive              ; 255 | 255
     movq      mm1, QWORD PTR [ecx]            ; pframe->scale[1] | pframe->scale[0]

     cmp       ecx, eax                        ; pframe == poldframe ? 
     jne       SHORT $frames_different         ; nope, frames are not the same

     movd      mm4, DWORD PTR [ecx+8]          ; 0 | pframe->scale[2]
     mov       esp, esp                        ; filler

     pfmul     mm1, mm2                        ; pframe->scale[1]*255 | pframe->scale[0]*255
     movd      mm3, DWORD PTR [ecx+20]         ; 0 | mins[2]=pframe->translate[2]

     pfmul     mm4, mm2                        ; 0 | pframe->scale[2]*255
     movq      mm2, mm0                        ; mins[1] | mins[0]

     pfadd     mm1, mm0                        ; pframe->translate[1]+pframe->scale[1]*255 | ...
     movq      mm5, mm3                        ; 0 | mins[2]

     pfadd     mm4, mm3                        ; 0 | pframe->translate[2]+pframe->scale[2]*255
     punpckldq mm5, mm5                        ; mins[2] | mins[2]

     punpckhdq mm2, mm5                        ; mins[2] | mins[1]
     jmp       $comp_bounding_box              ; go compute bounding box

assume esi:nothing

     ;; on exit: mm0=mins[1] | mins[0]
     ;;          mm1=maxs[1] | maxs[0]
     ;;          mm2=mins[2] | mins[1]
     ;;          mm4=    0   | maxs[2]
     ;;          mm5=mins[2] | mins[2]

; 294	: 	else
; 295	: 	{
; 296	: 		for ( i	= 0; i < 3; i++	)
; 297	: 		{
; 298	: 			thismins[i] = pframe->translate[i];
; 299	: 			thismaxs[i] = thismins[i] + pframe->scale[i]*255;
; 300	: 
; 301	: 			oldmins[i]	= poldframe->translate[i];
; 302	: 			oldmaxs[i]	= oldmins[i] + poldframe->scale[i]*255;
; 303	: 
; 304	: 			if ( thismins[i] < oldmins[i] )
; 305	: 				mins[i]	= thismins[i];
; 306	: 			else
; 307	: 				mins[i]	= oldmins[i];
; 308	: 
; 309	: 			if ( thismaxs[i] > oldmaxs[i] )
; 310	: 				maxs[i]	= thismaxs[i];
; 311	: 			else
; 312	: 				maxs[i]	= oldmaxs[i];
; 313	: 		}
; 314	: 	}

	    npad 2

$frames_different:
;; here: eax=poldframe, ecx=pframe, edx=mins, edi=maxs, ebx=e,
;;       mm0= thismins[1]=pframe->translate[1] | thismins[0]=pframe->translate[0]
;;       mm1= pframe->scale[1] | pframe->scale[0]
;;       mm2= 255 | 255

        movq            mm6, mm0                ; thismins[1] | thismins[0]  
        movq            mm7, [eax]              ; poldframe->scale[1] | poldframe->scale[0]

        pfmul           mm1, mm2                ; pframe->scale[1]*255 | pframe->scale[0]*255
        movq            mm3, [eax+12]           ; oldmins[1]=poldframe->translate[1] | oldmins[0]=poldframe->translate[0]

        pfadd           mm1, mm6                ; thismaxs[1] | thismaxs[0]
        movd            mm5, [ecx+20]           ; 0 | thismins[2]=pframe->translate[2]

        pfmul           mm7, mm2                ; poldframe->scale[1]*255 | poldframe->scale[0]*255
        movd            mm4, [ecx+8]            ; 0 | pframe->scale[2]

        pfmin           mm0, mm3                ; mins[1]=min(oldmins[1],thismins[1]) | mins[0]=min(oldmins[0],thismins[0])
        movd            mm6, [eax+20]           ; 0 | oldmins[2]=poldframe->translate[2]

        pfadd           mm3, mm7                ; oldmaxs[1]=oldmins[1]+poldframe->scale[1]*25 | oldmaxs[0]=oldmins[0]+...
        movq            mm7, [eax+8]            ; 0 | poldframe->scale[2]

        pfmul           mm4, mm2                ; 0 | pframe->scale[2]*255
        pfmax           mm1, mm3                ; maxs[1]=max(thismaxs[1],oldmaxs[1]) | maxs[0]=maxs(thismaxs[0],oldmaxs[0])  

        pfmul           mm7, mm2                ; 0 | poldframe->scale[2]*255
        movq            mm2, mm5                ; 0 | thismins[2]

        pfmin           mm5, mm6                ; 0 | mins[2]=min(thismins[2],oldmins[2])
        pfadd           mm4, mm2                ; 0 | thismaxs[2]=thismins[2]+pframe->scale[2]*255

        movq            mm2, mm0                ; mins[1] | mins[0]
        pfadd           mm7, mm6                ; 0 | oldmaxs[2]=oldmins[2]+poldframe->scale[2]*255

        punpckldq       mm5, mm5                ; mins[2] | mins[2]
        punpckhdq       mm2, mm5                ; mins[2] | mins[1]

        pfmax           mm4, mm7                ; 0 | maxs[2]=max(thismaxs[2],oldmaxs[2])
        mov             esp, esp                ; filler

        ;; here: mm0=mins[1] | mins[0]
        ;;       mm1=maxs[1] | maxs[0]
        ;;       mm2=mins[2] | mins[1]
        ;;       mm4=    0   | maxs[2]
        ;;       mm5=mins[2] | mins[2]
        ;; here: ebx=e

; 315	: 
; 316	: 	/*
; 317	: 	** compute a full bounding box
; 318	: 	*/
; 319	: 	for ( i	= 0; i < 8; i++	)
; 320	: 	{
; 321	: 		vec3_t	 tmp;
; 322	: 
; 323	: 		if ( i & 1 )
; 324	: 			tmp[0] = mins[0];
; 325	: 		else
; 326	: 			tmp[0] = maxs[0];
; 327	: 
; 328	: 		if ( i & 2 )
; 329	: 			tmp[1] = mins[1];
; 330	: 		else
; 331	: 			tmp[1] = maxs[1];
; 332	: 
; 333	: 		if ( i & 4 )
; 334	: 			tmp[2] = mins[2];
; 335	: 		else
; 336	: 			tmp[2] = maxs[2];
; 337	: 
; 338	: 		VectorCopy( tmp, bbox[i] );
; 339	: 	}
; 340	: 
; 339	: 	}
; 340	: 

$comp_bounding_box:

     mov       edi, DWORD PTR _bbox$[esp+ESP_currofs] ; bbox
     movq      mm3, mm1                        ; maxs[1] | maxs[0]

     punpckldq mm4, mm4                        ; maxs[2] | maxs[2]
     movq      mm6, mm1                        ; maxs[1] | maxs[0]

     movq      QWORD PTR [edi], mm1            ; bbox[0][1]=maxs[1] | bbox[0][0]=maxs[0]
     punpckhdq mm3, mm4                        ; maxs[2] | maxs[1]

     movq      QWORD PTR [edi+88], mm2         ; bbox[7][2]=mins[2] | bbox[7][1]=mins[1]
     punpckldq mm4, mm0                        ; mins[0] | maxs[2]

     movq      QWORD PTR [edi+8], mm4          ; bbox[1][0]=mins[0] | bbox[0][2]=maxs[2]
     punpckldq mm5, mm0                        ; mins[0] | mins[2]

     movq      QWORD PTR [edi+16], mm3         ; bbox[1][2]=maxs[2] | bbox[1][1]=maxs[1]
     punpckldq mm6, mm2                        ; mins[1] | maxs[0]

     movq      QWORD PTR [edi+80], mm5         ; bbox[7][0]=mins[0] | bbox[6][2]=mins[2]
     movq      mm7, mm0                        ; mins[1] | mins[0]

     movq      QWORD PTR [edi+24], mm6         ; bbox[2][1]=mins[1] | bbox[2][0]=maxs[0]
     movq      QWORD PTR [edi+32], mm4         ; bbox[3][0]=mins[0] | bbox[2][2]=maxs[2]

     punpckhdq mm7, mm3                        ; maxs[2] | mins[1]
     movq      mm3, QWORD PTR [ebx+4]          ; e->angles[1] | e->angles[0]

     movq      QWORD PTR [edi+40], mm7         ; bbox[3][2]=maxs[2] | bbox[3][1]=mins[1]
     movq      mm4, $ChsHigh                   ; 80000000 | 00000000

     movq      QWORD PTR [edi+48], mm1         ; bbox[4][1]=maxs[1] | bbox[4][0]=maxs[0]
     punpckhdq mm1, mm2                        ; mins[2] | maxs[1]

     movq      QWORD PTR [edi+56], mm5         ; bbox[5][0]=mins[0] | bbox[4][2]=mins[2]
     pxor      mm3, mm4                        ; - (e->angles[1]) | e->angles[0] ; YAW=1

     movq      QWORD PTR [edi+64], mm1         ; bbox[5][2]=mins[2] | bbox[5][1]=maxs[1]
     movd      mm5, DWORD PTR [ebx+12]         ; 0 | e->angles[2]

     movq      QWORD PTR [edi+72], mm6         ; bbox[6][1]=mins[1] | bbox[6][0]=maxs[0]
ifndef SIN
     mov       eax, esp                        ; stack pointer

 ; 341	: 	/*
 ; 342	: 	** rotate the bounding box
 ; 343	: 	*/
 ; 344	: 	VectorCopy( e->angles, angles );
 ; 345	: 	angles[YAW] = -angles[YAW];
 ; 346	: 	AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
 ; 347	: 

     movq      QWORD PTR _angles$[esp+164], mm3; angles[1] | angles[0]
     add       eax, _vectors$+188              ; vectors[2]

     movd      DWORD PTR _angles$[esp+172], mm5; angles[2]
     mov       esi, esp                        ; stack pointer

     add       esi, _angles$+ESP_currofs       ; angles
     sub       esp, 16                         ; push 4 DWORD arguments
 ESP_currofs = ESP_currofs + 16

     mov       DWORD PTR [esp+12], eax         ; vectors[2]
     sub       eax, 12                         ; vectors[1]

     mov       DWORD PTR [esp+8], eax          ; vectors[1]
     sub       eax, 12                         ; vectors[0]

     mov       DWORD PTR [esp+4], eax          ; vectors[0]
     nop                                       ; filler

     mov       DWORD PTR [esp], esi            ; angles
     call      _AmdAngleVectors                ; AngleVectors (angles, ...)

     add       esp, 16                         ; pop 4 DWORDS arguments off stack
 ESP_currofs = ESP_currofs - 16
endif
     mov       eax, 8                          ; initialize loop counter

; 348	: 	for ( i	= 0; i < 8; i++	)
; 349	: 	{
; 350	: 		vec3_t tmp;
; 351	: 
; 352	: 		VectorCopy( bbox[i], tmp );
; 353	: 
; 354	: 		bbox[i][0] = DotProduct( vectors[0], tmp );
; 355	: 		bbox[i][1] = -DotProduct( vectors[1], tmp );
; 356	: 		bbox[i][2] = DotProduct( vectors[2], tmp );
; 357	: 
; 358	: 		VectorAdd( e->origin, bbox[i], bbox[i] );
; 359	: 	}
; 360	: 

;; here: edi=bbox[0], ebx=e

ifdef SIN
_CurMat textequ <edx>
     mov       edx, DWORD PTR _currententity    ; currententity
assume edx:ptr entity_t
     mov       _CurMat,entity_t[edx].mat        ; vectors = currententity->mat
else
_CurMat textequ <esp+_vectors$+ESP_currofs>     ; vec3_t vectors[3]
endif

; stack offset = 164

     movq      mm0, [edi]                       ; bbox[i][1] | bbox[i][0]
     mov       ecx, edi                         ; save pointer to bbox

     movq      mm2, QWORD PTR [_CurMat+12]      ; vectors[1][1] | vectors[1][0]
     mov       esi, (NOT 0)                     ; aggregatemask = ~0

     movq      mm1, QWORD PTR [_CurMat]         ; vectors[0][1] | vectors[0][0]
     mov       ebp, eax                         ; p = 8 (eax happens to be 8, see above)

$ProductLoop:
     pfmul     mm2, mm0                         ; bbox[i][1]*vectors[1][1] | bbox[i][0]*vectors[1][0]
     movq      mm3, QWORD PTR [_CurMat+24]      ; vectors[2][1] | vectors[2][0]

     pfmul     mm1, mm0                         ; bbox[i][1]*vectors[0][1] | bbox[i][0]*vectors[0][0]
     movd      mm4, DWORD PTR [edi+8]           ; bbox[i][2]

     pfmul     mm3, mm0                         ; bbox[i][1]*vectors[2][1] | bbox[i][0]*vectors[2][0]
     pfacc     mm2, mm2                         ; bbox[i][1]*vectors[1][1]      + bbox[i][0]*vectors[1][0]

     punpckldq mm4, mm4                         ; bbox[i][2] | bbox[i][2]
     movd      mm7, DWORD PTR [_CurMat+32]      ; 0 | vectors[2][2]

     pfacc     mm1, mm1                         ; bbox[i][1]*vectors[0][1] + bbox[i][0]*vectors[0][0]
     movd      mm5, DWORD PTR [_CurMat+8]       ; 0 | vectors[0][2]

     pfacc     mm3, mm3                         ; bbox[i][1]*vectors[2][1]      + bbox[i][0]*vectors[2][0]
     movd      mm6, DWORD PTR [_CurMat+20]      ; 0 | vectors[1][2]

     punpckldq mm1, mm2                         ; bbox[i][1]*vectors[1][1] + bbox[i][0]*vectors[1][0] | bbox[i][1]*vectors[0][1] + bbox[i][0]*vectors[0][0]
     pfmul     mm7, mm4                         ; 0 | bbox[i][2]*vectors[2][2]

     punpckldq mm5, mm6                         ; vectors[1][2] | vectors[0][2]
    EXCEPT_SIN <movq mm6, $ChsHigh>             ; 80000000 | 00000000

     pfadd     mm3, mm7                         ; DotProduct(bbox[i],vectors[2])
     add       edi, 3*(size REAL4)              ; bbox++

     pfmul     mm5, mm4                         ; bbox[i][2]*vectors[1][2] | bbox[i][2]*vectors[0][2]
     movq      mm4, QWORD PTR [ebx].origin      ; e->origin[1] | e->origin[0]

     movq      mm2, QWORD PTR [_CurMat+12]      ; vectors[1][1] | vectors[1][0]
     dec       eax                              ; i--

     pfadd     mm1, mm5                         ; bbox[i][2]*vectors[1][2] + bbox[i][1]*vectors[1][1] + bbox[i][0]*vectors[1][0]
     movd      mm5, DWORD PTR [ebx].origin[2*(size REAL4)] ; 0 | e->origin[2]

     movq      mm0, [edi]                       ; bbox[i][1] | bbox[i][0] (for next iteration)
    EXCEPT_SIN <pxor mm6, mm1>                  ; -DotProduct(bbox[i],vectors[1]) | DotProduct(bbox[i],vectors[0])

     pfadd     mm3, mm5                         ; bbox[i][2]+e->origin[2]
     movq      mm1, QWORD PTR [_CurMat]         ; vectors[0][1] | vectors[0][0]

     pfadd     mm6, mm4                         ; bbox[i][1]+e->origin[1] | bbox[i][0]+e->origin[0]
     movd      [edi-(size REAL4)], mm3          ; bbox[i][2]

     movq      [edi-3*(size REAL4)], mm6        ; bbox[i][1] | bbox[i][0]
     jnz       $ProductLoop                     ; until 8 loops done

; 361	: 	{
; 362	: 		int p, f, aggregatemask	= ~0;
; 363	: 
; 364	: 		for ( p	= 0; p < 8; p++	)
; 365	: 		{
; 366	: 			int mask = 0;
; 367	: 
; 368	: 			for ( f	= 0; f < 4; f++	)
; 369	: 			{
; 370	: 				float dp = DotProduct( frustum[f].normal, bbox[p] );
; 371	: 
; 372	: 				if ( ( dp - frustum[f].dist ) <	0 )
; 373	: 				{
; 374	: 					mask |=	( 1 << f );
; 375	: 				}
; 376	: 			}
; 377	: 
; 378	: 			aggregatemask &= mask;
; 379	: 		}
; 380	: 
; 381	: 		if ( aggregatemask )
; 382	: 		{
; 383	: 			return true;
; 384	: 		}
; 385	: 
; 386	: 		return false;
; 387	: 	}
; 388	: }

;; here: ecx = bbox[0]

     movq      mm1, [ecx]                      ; bbox[p][1] | bbox[p][0]
     mov       edx, OFFSET FLAT:_frustum       ; frustum[0]
assume edx:nothing

     movq      mm0, [edx]                      ; frustum[0].normal[1] | frustum[0].normal[0]
     nop                                       ; filler

     movd      mm3, [ecx+8]                    ; 0 | bbox[p][2]
     movd      mm2, [edx+8]                    ; 0 | frustum[0].normal[2]

$OuterLoop:
     xor       edi, edi                        ; mask = 0
     pfmul     mm0, mm1                        ; bbox[p][1]*frustum[0].normal[1] | bbox[p][0]*frustum[0].normal[0]

     pfmul     mm2, mm3                        ; 0 | bbox[p][2]*frustum[f].normal[2]
     movd      mm4, [edx+12]                   ; frustum[0].dist

     pfacc     mm0, mm0                        ; bbox[p][1]*frustum[0].normal[1] + bbox[p][0]*frustum[0].normal[0]
     movq      mm5, [edx+20]                   ; frustum[1].normal[1] | frustum[1].normal[0]

     movd      mm6, [edx+28]                   ; 0 | frustum[1].normal[2]
     nop

     pfadd     mm0, mm2                        ; dp = DotProduct (frustum[0].normal, bbox[p])
     pfmul     mm5, mm1                        ; bbox[p][1]*frustum[1].normal[1] | bbox[p][0]*frustum[1].normal[0]

     pfmul     mm6, mm3                        ; 0 | bbox[p][2]*frustum[f].normal[2]
     movd      mm7, [edx+32]                   ; frustum[1].dist

     pfcmpgt   mm4, mm0                        ; frustum[0].dist > dp ? ffffffff : 0
     movq      mm0, [edx+40]                   ; frustum[2].normal[1] | frustum[2].normal[0]

     pfacc     mm5, mm5                        ; bbox[p][1]*frustum[1].normal[1] + bbox[p][0]*frustum[1].normal[0]
     movd      mm2, [edx+48]                   ; 0 | frustum[2].normal[2]

     movd      DWORD PTR _mins$[esp+ESP_currofs], mm4  ; frustum[0].dist > dp ? ffffffff : 0
     pfmul     mm0, mm1                        ; bbox[p][1]*frustum[2].normal[1] | bbox[p][0]*frustum[2].normal[0]

     mov       eax, DWORD PTR _mins$[esp+ESP_currofs]  ; frustum[0].dist > dp ? ffffffff : 0
     pfadd     mm5, mm6                        ; dp = DotProduct (frustum[1].normal, bbox[p])

     pfacc     mm0, mm0                        ; bbox[p][1]*frustum[2].normal[1] + bbox[p][0]*frustum[2].normal[0]
     and       eax, 1                          ; frustum[0].dist > dp ? (1 << 0) : 0

     pfmul     mm2, mm3                        ; 0 | bbox[p][2]*frustum[f].normal[2]
     movd      mm4, [edx+52]                   ; frustum[2].dist

     pfcmpgt   mm7, mm5                        ; frustum[1].dist > dp ? ffffffff : 0
     or        edi, eax                        ; mask |= ((frustum[0].dist > dp) ? (1 << 0) : 0)

     pfadd     mm0, mm2                        ; dp = DotProduct (frustum[2].normal, bbox[p])
     movq      mm5, [edx+60]                   ; frustum[3].normal[1] | frustum[3].normal[0]

     movd      DWORD PTR _mins$[esp+ESP_currofs][4], mm7  ; frustum[1].dist > dp ? ffffffff : 0
     mov       eax, DWORD PTR _mins$[esp+ESP_currofs][4]  ; frustum[1].dist > dp ? ffffffff : 0

     movd      mm6, [edx+68]                   ; 0 | frustum[3].normal[2]
     pfcmpgt   mm4, mm0                        ; frustum[2].dist > dp ? ffffffff : 0

     pfmul     mm5, mm1                        ; bbox[p][1]*frustum[3].normal[1] | bbox[p][0]*frustum[3].normal[0]
     and       eax, 2                          ; frustum[1].dist > dp ? (1 << 1) : 0

     pfmul     mm6, mm3                        ; 0 | bbox[p][2]*frustum[3].normal[2]
     movd      DWORD PTR _mins$[esp+ESP_currofs][8], mm4  ; frustum[2].dist > dp ? ffffffff : 0 

     pfacc     mm5, mm5                        ; bbox[p][1]*frustum[3].normal[1] + bbox[p][0]*frustum[3].normal[0]
     mov       ebx, DWORD PTR _mins$[esp+ESP_currofs][8]  ; frustum[2].dist > dp ? ffffffff : 0

     or        edi, eax                        ; mask |= ((frustum[1].dist > dp) ? (1 << 1) : 0)
     and       ebx, 4                          ; frustum[2].dist > dp ? (1 << 2) : 0

     movd      mm7, [edx+72]                   ; frustum[3].dist
     pfadd     mm5, mm6                        ; dp = DotProduct (frustum[3].normal, bbox[p])

     add       ecx, 12                         ; bbox++
     or        edi, ebx                        ; mask |= ((frustum[2].dist > dp) ? (1 << 2) : 0)

     pfcmpgt   mm7, mm5                        ; frustum[3].dist > dp ? ffffffff : 0
     movq      mm1, [ecx]                      ; bbox[p][1] | bbox[p][0]

     movd      DWORD PTR _mins$[esp+ESP_currofs][8], mm7  ; frustum[3].dist > dp ? ffffffff : 0
     mov       eax, DWORD PTR _mins$[esp+ESP_currofs][8]  ; frustum[2].dist > dp ? ffffffff : 0

     and       eax, 8                          ; frustum[3].dist > dp ? (1 << 3) : 0
     movq      mm0, [edx]                      ; frustum[0].normal[1] | frustum[0].normal[0]

     or        edi, eax                        ; mask |= ((frustum[3].dist > dp) ? (1 << 3) : 0)
     movd      mm3, [ecx+8]                    ; 0 | bbox[p][2]

     and       esi, edi                        ; aggregatemask &= mask
     movd      mm2, [edx+8]                    ; 0 | frustum[0].normal[2]

     dec       ebp                             ; p--
     jnz       $OuterLoop                      ; while p > 0 

     neg       esi                             ; CF = aggregatemask ? 1 : 0
     pop       edi                             ; restore caller's register variable

     femms

     sbb       eax, eax                        ; aggregatemask ? ffffffff      : 0

     pop       ebp                             ; restore caller's register variable
     and       eax, 1                          ; aggregatemask ? true : false

     pop       esi                             ; restore caller's register variable
     pop       ebx                             ; restore caller's register variable
ESP_currofs = ESP_currofs - 16

; stack offset = 148

     add       esp, ESP_currofs                ; remove local variables from stack
     ret 
_R_CullAliasModel ENDP

assume ebx:nothing

	ALIGN	32
_TEXT	ENDS

CONST	SEGMENT
	ALIGN	8
$One    DQ      3f8000003f800000h              ; 1 | 1
CONST	ENDS

_DATA	SEGMENT
PUBLIC	_GL_DAFL_InitFlag
	_GL_DAFL_InitFlag		dd	0
_DATA	ENDS


;; Args

_backlerp$  = 12-4
_paliashdr$ = 8-4

_colorArray$ = 	-32768	; float colorArray[MAX_VERTS*4]
_backv$	=       -32780	; vec3_t backv
_vectors$ =     -32816  ; vec3_t vectors[3]
_frontv$ =      -32828	; vec3_t frontv
_ov$ =          -32832	; *
_v$ =           -32836	; *
_frontlerp$ =   -32840	; float	frontlerp
_alpha$	=       -32844	; float alpha
_move$ =        -32856	; vec3_t move
_delta$	=       -32868	; vec3_t delta

; These stack offsets were obtained through direct examination of the 
; generated .COD file for the original source.  I haven't figured out why they 
; are different between SIN and Quake II, but it shouldn't matter so long as 
; proper stack management procedures are taken.

_TEXT	SEGMENT

align	64
_GL_DrawAliasFrameLerp PROC NEAR			; COMDAT

ESP_currofs = 32868

ifdef	DIRECT_API_CALLS
	test	_GL_DAFL_InitFlag, -1
	jz	ConvertIndirectCalls
endif
; 66	: {
; 67	: 	float 	l;
; 68	: 	daliasframe_t	*frame, *oldframe;
; 69	: 	dtrivertx_t	*v, *ov, *verts;
; 70	: 	int		*order;
; 71	: 	int		count;
; 72	: 	float	frontlerp;
; 73	: 	float	alpha;
; 74	: 	vec3_t	move, delta, vectors[3];
; 75	: 	vec3_t	frontv, backv;
; 76	: 	int		i;
; 77	: 	int		index_xyz;
; 78	: 	vec3_t	lerped[MAX_VERTS];
; 79	: 	float	*lerp;
; 80	: 
; 81	: 	frame =	(daliasframe_t *)((byte	*)paliashdr + paliashdr->ofs_frames 
; 82	: 		+ currententity->frame * paliashdr->framesize);
; 83	: 	verts =	v = frame->verts;
; 84	: 
; 85	: 	oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames 
; 86	: 		+ currententity->oldframe * paliashdr->framesize);
; 87	: 	ov = oldframe->verts;
; 88	: 
; 89	: 	order =	(int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
; 90	: 
; 91	: //	glTranslatef (frame->translate[0], frame->translate[1], frame->translate[2]);
; 92	: //	glScalef (frame->scale[0], frame->scale[1], frame->scale[2]);
; 93	: 
; 		float colorArray[MAX_VERTS*4];

     mov       eax, ESP_currofs
     call      __chkstk

     mov       eax, DWORD PTR _currententity      ; currententity
assume eax:ptr entity_t

     push      ebp                                ; save caller's register variable
ESP_currofs = ESP_currofs + 4
; stack offset is 32872
     mov       ebp, DWORD PTR _paliashdr$[esp+ESP_currofs]; paliashdr
assume ebp:ptr dmdl_t

     push      ebx                                ; save caller's register variable
     mov       ebx, [eax].frame                   ; +28(1Ch)

ESP_currofs = ESP_currofs + 4
; stack offset is 32876

     push      esi                                ; save caller's register variable
     mov       ecx, DWORD PTR [ebp].framesize     ; +16(10h)
ESP_currofs = ESP_currofs + 4
; stack offset is 32880

     push      edi                                ; save caller's register variable
     mov       edi, [eax].oldframe                ; +44(2Ch)
ESP_currofs = ESP_currofs + 4
; stack offset is 32884
     imul      ebx, ecx                           ; currententity->frame * paliashdr->framesize

     imul      edi, ecx                           ; currententity->oldframe * paliashdr->framesize

     mov       edx, DWORD PTR [ebp].ofs_frames    ; +56(38h)
     add       ebx, ebp                           ; ((byte *)paliashdr + currententity->frame * paliashdr->framesize

     add       edi, ebp                           ; ((byte *)paliashdr + currententity->oldframe * paliashdr->framesize
     add       ebx, edx                           ; frame=((byte *)paliashdr + paliashdr->ofs_frames + currententity->frame * paliashdr->framesize

     add       edi, edx                           ; oldframe=((byte *)paliashdr + paliashdr->ofs_frames + currententity->oldframe * paliashdr->framesize
     lea       esi, DWORD PTR [ebx+40]            ; verts=frame->verts

     lea       ecx, DWORD PTR [edi+40]            ; oldframe->verts
     mov       _v$[esp+ESP_currofs], esi          ; v = frame->verts

     mov       esi, DWORD PTR [ebp].ofs_glcmds    ; +60(3Ch)
     mov       _ov$[esp+ESP_currofs], ecx         ; ov = oldframe->verts

; 94	: 	if (currententity->flags & RF_TRANSLUCENT)
; 95	: 		alpha =	currententity->alpha;
; 96	: 	else
; 97	: 		alpha =	1.0;
; 98	: 

     mov       edx, [eax].alpha                   ; +60(3Ch)
     add       esi, ebp                           ; order=((byte *)paliashdr + paliashdr->ofs_glcmds)

     mov       ecx, [eax].flags                   ; +68(44h)
     mov       eax, 3f800000h                     ; alpha = 1 (in case non-transparent)

     test      cl, 32                             ; (currententity->flags & RF_TRANSLUCENT)
     jnz       SHORT $StoreAlpha                  ; translucent, keep alpha

     mov       _alpha$[esp+ESP_currofs], eax      ; alpha = 1
     jmp       SHORT $AlphaStored                 ; merge back

$StoreAlpha:
     nop                                          ; filler
     mov       _alpha$[esp+ESP_currofs], edx      ; alpha = currententity->alpha

$AlphaStored:
; This piece of logic has been removed out of the SIN code.
ifndef SIN
 ; 99	: 	if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
 ; 100	: 		qglDisable( GL_TEXTURE_2D );

     test      ch, 28                             ; currententity->flags & ( RF_SHELL_RED ...)
     je        SHORT $DontDisableTex              ; no need to disable texture

     push      3553                               ; GL_TEXTURE_2D = 00000de1H
 ; Indirect Call
     DCALL	_qglDisable,1                     ; qglDisable( GL_TEXTURE_2D )
endif
$DontDisableTex:

; stack offset is 32884
; 101	:
; 102	: 	frontlerp = 1.0	- backlerp;
; 103	: 
; 104	: 	// move	should be the delta back to the	previous frame * backlerp
; 105	: 	VectorSubtract (currententity->oldorigin, currententity->origin, delta);
; 106	: 	AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);

; In the SIN code, there is no need to call AngleVectors(), thus the stack is 
; left alone.

ifdef SIN
_CurMat textequ <edi>
     mov       [esp+_vectors$+ESP_currofs],edi    ; Store off edi.
else
_CurMat textequ <esp+_vectors$+ESP_currofs>       ; vec3_t vectors[3]
endif

     lea       ecx, [_CurMat+24]                  ; vectors[2]
     mov       eax, DWORD PTR _currententity      ; &currententity 
    ONLY_SIN  <mov _CurMat,[eax].mat>             ; vectors = currententity->mat

     lea       edx, [_CurMat+12]                  ; vectors[1]
     sub       esp, 16                            ; make room for 4 DWORD arguments
ESP_currofs = ESP_currofs+16
; stack offset is 32884+16 = 32900
     femms                                        ; AMD3D code ahead, empty FPU/MMX registers

    EXCEPT_SIN <mov DWORD PTR [esp+12], ecx>      ; "push" vectors[2]
     movq      mm0, QWORD PTR [eax].oldorigin     ; +32(20h) oldorigin[1] | oldorigin[0]

     lea       ecx, DWORD PTR [_CurMat]           ; vectors[0]
     movq      mm2, QWORD PTR [eax].origin        ; +16(10h) origin[1] | origin[0]

    EXCEPT_SIN <mov DWORD PTR [esp+8], edx>       ; "push" vectors[1]
     movd      mm1, DWORD PTR [eax].oldorigin[(size REAL4)*2]	; +40(28h) 0 | oldorigin[2]

     pfsub     mm0, mm2                           ; currententity->oldorigin[1] - currententity->origin[1] |      ...
     movd      mm3, DWORD PTR [eax].origin[(size REAL4)*2]      ; +24(18h) 0 | origin[2]

    EXCEPT_SIN <mov DWORD PTR [esp+4], ecx>       ; "push" vectors[0]
     movq      mm4, QWORD PTR $One                ; 1.0f | 1.0f

     pfsub     mm1, mm3                           ; 0 | currententity->oldorigin[2] - currententity->origin[2]
     lea       edx, _backlerp$[esp+ESP_currofs]   ; &backlerp

     movd      mm5, DWORD PTR [edx]               ; backlerp
     movq      _delta$[esp+32900], mm0            ; delta[1] | delta[0]
assume eax:nothing
     add       eax, 4                             ; currententity->angles
     movd      _delta$[esp+ESP_currofs+8], mm1    ; delta[2]

     pfsub     mm4, mm5                           ; 1.0f - backlerp
    EXCEPT_SIN <mov DWORD PTR [esp], eax>         ; "push" currententity->angles

     movd      _frontlerp$[esp+ESP_currofs], mm4  ; frontlerp
    EXCEPT_SIN <call _AmdAngleVectors>            ; AngleVectors (currententity->angles, ve...

; 107	: 
; 108	: 	move[0]	= DotProduct (delta, vectors[0]);	// forward
; 109	: 	move[1]	= -DotProduct (delta, vectors[1]);	// left
; 110	: 	move[2]	= DotProduct (delta, vectors[2]);	// up
; 111	: 
; 112	: 	VectorAdd (move, oldframe->translate, move);

     movq      mm0, QWORD PTR _delta$[esp+ESP_currofs]  ; delta[1]      | delta[0]
    EXCEPT_SIN <nop>                              ; filler

     lea       edx, DWORD PTR _backv$[esp+ESP_currofs]  ; backv
     movq      mm1, QWORD PTR [_CurMat]           ; vectors[0][1] | vectors[0][0]

     lea       ecx, DWORD PTR [ebx+12]            ; frame->translate[]
     movq      mm2, QWORD PTR [_CurMat+12]        ; vectors[1][1] | vectors[1][0]

     pfmul     mm1, mm0                           ; delta[1]*vectors[0][1] | delta[0]*vectors[0][0]
     movq      mm3, QWORD PTR [_CurMat+24]        ; vectors[2][1] | vectors[2][0]

     pfmul     mm2, mm0                           ; delta[1]*vectors[1][1] | delta[0]*vectors[1][0]
     movd      mm4, DWORD PTR _delta$[esp+ESP_currofs+8]  ; delta[2]

     pfacc     mm1, mm1                           ; delta[1]*vectors[0][1] + delta[0]*vectors[0][0]
     movd      mm5, DWORD PTR [_CurMat+8]         ; vectors[0][2]

     pfmul     mm3, mm0                           ; delta[1]*vectors[2][1] | delta[0]*vectors[2][0]
     movd      mm6, DWORD PTR [_CurMat+20]        ; vectors[1][2]

     pfacc     mm2, mm2                           ; delta[1]*vectors[1][1] + delta[0]*vectors[1][0]
     punpckldq mm4, mm4                           ; delta[2]      | delta[2]

     punpckldq mm5, mm6                           ; vectors[1][2] | vectors[0][2]
     movd      mm7, DWORD PTR [_CurMat+32]        ; vectors[2][2]

     pfacc     mm3, mm3                           ; delta[1]*vectors[2][1] + delta[0]*vectors[2][0]
    ONLY_SIN <mov edi,[esp+_vectors$+ESP_currofs]>; recover edi.
    EXCEPT_SIN <nop>                              ; filler
     pfmul     mm5, mm4                           ; delta[2]*vectors[1][2] | delta[2]*vectors[0][2]
     punpckldq mm1, mm2                           ; delta[1]*vectors[1][1] + delta[0]*vectors[1][0] | delta[1]*vectors[0][1] + delta[0]*vectors[0][0]

    EXCEPT_SIN <movq mm6, $ChsHigh>               ; 80000000 | 00000000
     pfmul     mm7, mm4                           ; 0 | delta[2]*vectors[2][2]

     movq      mm4, QWORD PTR [edi+12]            ; oldframe->translate[1] | oldframe->translate[0]
     pfadd     mm1, mm5                           ; delta[2]*vectors[1][2] + delta[1]*vectors[1][1] + delta[0]*vectors[1][0]

     movd      mm5, DWORD PTR [edi+20]            ; oldframe->translate[2]
     pfadd     mm3, mm7                           ; DotProduct(delta,vectors[2])

    EXCEPT_SIN <pxor mm1, mm6>                    ; (-)DotProduct(delta,vectors[1]) | DotProduct(delta,vectors[0])
     lea       eax, DWORD PTR _backlerp$[esp+ESP_currofs]; &backlerp

     pfadd     mm3, mm5                           ; move[2]+oldframe->translate[2]
     movd      mm0, DWORD PTR [eax]               ; backlerp

     pfadd     mm4, mm1                           ; move[1]+oldframe->translate[1] | move[0]+oldframe->translate[0]
     lea       eax, DWORD PTR _move$[esp+ESP_currofs]   ; move

     movd      mm1, DWORD PTR _frontlerp$[esp+ESP_currofs]; frontlerp
     movd      DWORD PTR [eax+8], mm3             ; move[2]

     movq      mm2, QWORD PTR [ecx]               ; frame->translate[1] | frame->translate[0]
     movq      QWORD PTR [eax], mm4               ; move[1] | move[0]


; 113	: 
; 114	: 	for (i=0 ; i<3 ; i++)
; 115	: 	{
; 116	: 		move[i]	= backlerp*move[i] + frontlerp*frame->translate[i];
; 117	: //		move[i]	+= backlerp*oldframe->translate[i];
; 118	: 
; 119	: //		move[i]	/= oldframe->scale[i];
; 120	: //		move[i]	*= backlerp;
; 121	: 	}
; 122	: 
; 123	: 	for (i=0 ; i<3 ; i++)
; 124	: 	{
; 125	: 		frontv[i] = frontlerp*frame->scale[i];
; 126	: 		backv[i] = backlerp*oldframe->scale[i];
; 127	: 	}
; 128	: 
; 129	: 	lerp = lerped[0];
; 130	: 
; 131	: 	GL_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv );
; stack offset is 32900

     punpckldq mm0, mm0                           ; backlerp | backlerp
     movq      mm3, QWORD PTR [eax]               ; move[1] | move[0]

     punpckldq mm1, mm1                           ; frontlerp | frontlerp
     movd      mm4, DWORD PTR [ecx+8]             ; 0 | frame->translate[2]

     pfmul     mm2, mm1                           ; frontlerp*frame->translate[1] | frontlerp*frame->translate[0] 
     movd      mm5, DWORD PTR [eax+8]             ; 0 | move[2]

     pfmul     mm3, mm0                           ; backlerp*move[1] | backlerp*move[0] 
     db        081h,0ECh                          ; sub esp ...
     dd        16                                 ;    ... , 16; make room for 4 more DWORD args (4 still allocated from previous call, re-use)
ESP_currofs = ESP_currofs + 16
; stack offset is 32900+16=32916
     movq      mm6, mm1                           ; frontlerp
     lea       ecx, DWORD PTR _frontv$[esp+ESP_currofs] ; frontv

     punpckldq mm4, mm5                           ; move[2] | frame->translate[2]
     pfadd     mm2, mm3                           ; backlerp*move[1] + frontlerp*frame->translate[1]

     mov       DWORD PTR [esp+28], edx            ; "push" backv
     punpckldq mm6, mm0                           ; backlerp | frontlerp

     mov       DWORD PTR [esp+24], ecx            ; "push" frontv
     pfmul     mm4, mm6                           ; backlerp*move[2] | frontlerp*frame->translate[2]

     movq      QWORD PTR [eax], mm2               ; move[1] | move[0]
     movq      mm2, QWORD PTR [ebx]               ; frame->scale[1] | frame->scale[0]

     movq      mm3, QWORD PTR [edi]               ; oldframe->scale[1] | oldframe->scale[0]
     pfacc     mm4, mm4                           ; backlerp*move[2] + frontlerp*frame->translate[2]

     pfmul     mm2, mm1                           ; frontlerp*frame->scale[1] | frontlerp*frame->scale[0]
     mov       DWORD PTR [esp+20], eax            ; "push" move

     movd      DWORD PTR [eax+8], mm4             ; move[2]
     pfmul     mm3, mm0                           ; backlerp*oldframe->scale[1] | backlerp*oldframe->scale[0]

     movd      mm5, DWORD PTR [edi+8]             ; 0 | oldframe->scale[2]
     db        00Fh,07Fh,051h,000h                ; movq QWORD PTR [ecx+0], mm2 ; frontv[1] | frontv[0]

     movd      mm4, DWORD PTR [ebx+8]             ; 0 | frame->scale[2]
     lea       eax, _s_lerped			  ; lerp = lerped[0]

     mov       DWORD PTR [esp+16], eax            ; "push" lerp
     mov       eax, DWORD PTR _v$[esp+ESP_currofs]; v/verts

     punpckldq mm4, mm5                           ; oldframe->scale[2] | frame->scale[2]
     lea       edx, _backv$[esp+ESP_currofs]      ; backv

     movq      QWORD PTR [edx], mm3               ; backv[1] | backv[0]
     mov       DWORD PTR [esp+12], eax            ; "push" verts

     pfmul     mm4, mm6                           ; backlerp*oldframe->scale[2] | frontlerp*frame->scale[2]
     mov       DWORD PTR [esp+4], eax             ; "push" v

     mov       eax, DWORD PTR [ebp].num_xyz       ; +24(18h)
     movd      DWORD PTR [ecx+8], mm4             ; frontv[2]

     punpckhdq mm4, mm4                           ; backlerp*oldframe->scale[2]
     mov       ecx, _ov$[esp+ESP_currofs]         ; ov

     movd      DWORD PTR [edx+8], mm4             ; backv[2]
     db        089h,044h,024h,000h                ; mov [esp], eax ; "push" paliashdr->num_xyz

     mov       DWORD PTR [esp+8], ecx             ; "push" ov
     call     _GL_LerpVerts                       ; GL_LerpVerts( paliashdr->num_xyz, v, ...)

     add       esp, 32                            ; remove 8 DWORD arguments from stack
; stack offset is 32916-32 = 32884
ESP_currofs = ESP_currofs - 32
     add       esi, 4                             ; order++
; stack offset is 32884
;; 3.17 code
;	if ( gl_vertex_arrays->value )
assume ebp:nothing
	mov       	ebp, DWORD PTR _alpha$[esp+ESP_currofs]  ; alpha
	mov		eax, DWORD PTR _gl_vertex_arrays
	cmp		DWORD PTR [eax+20], 0
	je		$L25818
; 	{
	femms
; 		qglEnableClientState( GL_VERTEX_ARRAY );
	mov	ebp, DWORD PTR _paliashdr$[esp+ESP_currofs]

	push		ESP_currofs		  ; 00008074H
	DCALL		_qglEnableClientState,1

; 		qglVertexPointer( 3, GL_FLOAT, 16, s_lerped );	// padded for SIMD

	push	OFFSET FLAT:_s_lerped
	push	16				  ; 00000010H
	push	5126				  ; 00001406H
	push	3
	DCALL	_qglVertexPointer,1

; This piece of logic has been removed out of the SIN code.

ifndef SIN

 ; 148  : 		if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )

	mov	ecx, DWORD PTR _currententity
assume ecx:ptr entity_t

	mov	eax, DWORD PTR [ecx].flags
assume ecx:nothing
	test	ah, 28					; 0000001cH
	je	SHORT $L25888

 ; 		{

	mov	edx, DWORD PTR _alpha$[esp+ESP_currofs]
	mov	eax, DWORD PTR _shadelight+8
	mov	ecx, DWORD PTR _shadelight+4
	push	edx
	mov	edx, DWORD PTR _shadelight
	push	eax
	push	ecx
	push	edx
	DCALL	_qglColor4f,4                     ; qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha );

 ; 151  : 		}
 ; 152  : 		else

	jmp	$L25892
endif

$L25888:
;; stack offset is 32884
	mov	ebx, DWORD PTR _v$[esp+ESP_currofs]

; 		{

	push	32886                             ; GL_COLOR_ARRAY = 00008076H
	DCALL	_qglEnableClientState,2           ; qglEnableClientState( GL_COLOR_ARRAY );

	lea	eax, DWORD PTR _colorArray$[esp+ESP_currofs]
	push	eax
	push	0
	push	5126				  ; GL_FLOAT = 00001406H
	push	3
	DCALL	_qglColorPointer,1                ; qglColorPointer( 3, GL_FLOAT, 0, colorArray );
; 
; 			//
; 			// pre light everything
; 			//
; 			for ( i = 0; i < paliashdr->num_xyz; i++ )

	mov	edi, DWORD PTR [ebp+24]
	test	edi, edi
	jle	$L25892

; 277  : }

	mov	ebp, DWORD PTR _shadedots
	lea	eax, DWORD PTR _colorArray$[esp+ESP_currofs]
	lea	ecx, DWORD PTR [ebx+3]

; 			{
; 				float l = shadedots[verts[i].lightnormalindex];
; 
; 				colorArray[i*3+0] = l * shadelight[0];
; 				colorArray[i*3+1] = l * shadelight[1];
; 				colorArray[i*3+2] = l * shadelight[2];
	femms
	jmp		short $L25890_1
align 64
$L25890_1:
	movzx		edx, BYTE PTR [ecx]		; verts[i].lightnormalindex
	add		eax, 12				; i*3

	movd		mm0, [ebp+edx*4]		; 0 | l
	add		ecx, 4				; &(verts[i].lightnormalindex)

	punpckldq	mm0, mm0			; l | l
	movq		mm2, qword ptr _shadelight	; shadelight[1] | shadelight[0]

	movd		mm3, _shadelight+8		; 0 | shadelight[2]
	dec		edi

	movq		mm1, mm0			; l | l
	pfmul		mm0, mm2			; l*shadelight[1] | l*shadelight[0]

	pfmul		mm1, mm3			; 0 | l*shadelight[2]
	nop

	movq		[eax-12], mm0			; colorArray[i*3+1] | colorArray[i*3+0]
	nop

	movd		[eax-4], mm1			; colorArray[i*3+2]
	jne		SHORT $L25890_1		; flags set from dec edi above...

	mov		ebp, DWORD PTR _paliashdr$[esp+ESP_currofs]
	femms
$L25892:
;; stack offset is 32884

; 			}
; 		}
; 
; 		if ( qglLockArraysEXT != 0 )
	mov		eax, DWORD PTR _qglLockArraysEXT
	test		eax, eax
	je		SHORT $L26133

; 			qglLockArraysEXT( 0, paliashdr->num_xyz );

	mov		ecx, DWORD PTR [ebp+24]
	push		ecx
	push		0
	call		eax
$L26133:

; There is some similar code to the following in _SINMDL_DrawFrameLerp
; functions below.  In _SINMDL_DrawFrameLerp is has been optimized a lot
; better, and you may consider copying those changes over here.

; 173  :                while (1)
; 174  : 		{
; 175  : 			// get the vertex count and primitive type
; 176  : 			count = *order++;

	mov		edi, DWORD PTR [esi-4]
;	add		esi, 4

; 177  : 			if (!count)

	test		edi, edi
	je		SHORT $L26105_1

; 178  : 				break;		// done
; 179  : 			if (count < 0)

	jge	SHORT $L25899_1

; 180  : 			{
; 181  : 				count = -count;

	neg	edi

; 182  : 				qglBegin (GL_TRIANGLE_FAN);

	push	6

; 183  : 			}
; 184  : 			else

	jmp	SHORT $L26142
$L25899_1:

; 185  : 			{
; 186  : 				qglBegin (GL_TRIANGLE_STRIP);

	push	5
$L26142:
	DCALL	_qglBegin,5

ifndef SIN

 ; 187  : 			}
 ; 188  : 
 ; 189  : 			if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )

	mov	edx, DWORD PTR _currententity
	mov	eax, DWORD PTR [edx+68]
	test	ah, 28					; 0000001cH
	je	SHORT $L26135_1
 $L25902:

 ; 190  : 			{
 ; 191  : 				do
 ; 192  : 				{
 ; 193  : 					index_xyz = order[2];

	mov	eax, DWORD PTR [esi+8]

 ; 194  : 					order += 3;

	add	esi, 12					; 0000000cH

 ; 195  : 
 ; 196  : 					qglVertex3fv( s_lerped[index_xyz] );

	shl	eax, 4
	add	eax, OFFSET FLAT:_s_lerped
	push	eax
	call	DWORD PTR _qglVertex3fv		; Don't DCALL any _qglVertex??v calls

 ; 197  : 
 ; 198  : 				} while (--count);

	dec	edi
	jne	SHORT $L25902

 ; 217  : 			}
 ; 218  : 			qglEnd ();

	DCALL	_qglEnd,5

 ; 172  : 
 ; 173  : 		while (1)

	add		esi, 4
	jmp		SHORT $L26133
 $L26135_1:
 ; 				}
 ; 				else
 ; 				{
 ; 					do
 ; 					{
 ; 						// texture coordinates come from the draw list
 ; 						qglTexCoord2f (((float *)order)[0], ((float *)order)[1]);

	mov	eax, DWORD PTR [esi+4]
	mov	ecx, DWORD PTR [esi]
	push	eax
	push	ecx
	DCALL   _qglTexCoord2f,6
 ; index_xyz = order[2];
	mov	eax, DWORD PTR [esi+8]

 ; order += 3;
	add	esi, 12					; 0000000cH

 ; normals and vertexes come from the frame list
 ; qglArrayElement( index_xyz );
	push		eax
	DCALL	_qglArrayElement,1
 ; } while (--count);
	dec	edi
	jne	SHORT $L26135_1

 ; 217  : 			}
 ; 218  : 			qglEnd ();

	DCALL	_qglEnd,6

 ; 172  : 
 ; 173  : 		while (1)
	add		esi, 4
	jmp	SHORT $L26133
endif

$L26105_1:
;		}
;
;		if ( qglUnlockArraysEXT != 0 )

	mov	eax, DWORD PTR _qglUnlockArraysEXT
	test	eax, eax
	je	SHORT $L26106_1

;	qglUnlockArraysEXT();

	call	eax
$L26106_1:

; This piece of logic has been removed out of the SIN code.

ifndef SIN
 ; 		}
 ; 	}
 ; 
 ; 	if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )

	mov	edx, DWORD PTR _currententity
	mov	eax, DWORD PTR [edx+68]
	test	ah, 28					; 0000001cH
	je	SHORT $L25925

 ; 		qglEnable( GL_TEXTURE_2D );

	push	3553					; 00000de1H
	DCALL	_qglEnable,3
 $L25925:

 ; }
 ;	jump to exit
endif
	jmp		$L25831

align 64
$L25818:
; stack offset is 32884

; 132	: 
; 133	: 	while (1)
; 134	: 	{
; 135	: 		// get the vertex count	and primitive type
; 136	: 		count =	*order++;
; 137	: 		if (!count)
; 138	: 			break;		// done
; 139	: 		if (count < 0)
; 140	: 		{
; 141	: 			count =	-count;
; 142	: 			qglBegin (GL_TRIANGLE_FAN);
; 143	: 		}
; 144	: 		else
; 145	: 			qglBegin (GL_TRIANGLE_STRIP);

     mov       ebx, DWORD PTR [esi-4]             ; count = *order
     mov       ecx, 5                             ; GL_TRIANGLE_STRIP 

     mov       edi, DWORD PTR _currententity      ; currententity
     mov       edx, ebx                           ; count

     sar       edx, 31                            ; count < 0 ? FFFFFFFF : 0
     cmp       ebx, 0                             ; count == 0 ?

     jz        $DrawDone                          ; yup, we are done
     xor       ebx, edx                           ; count < 0 ? ~count : count

     sub       ecx, edx                           ; count < 0 ? GL_TRIANGLE_FAN : GL_TRIANGLE_STRIP
     sub       ebx, edx                           ; count < 0 ? -count : count

     push      ecx                                ; count < 0 ? GL_TRIANGLE_FAN : GL_TRIANGLE_STRIP
     mov       edi, DWORD PTR [edi+68]            ; currententity->flags

     femms
; Indirect Call
     DCALL	_qglBegin,1                      ; qglBegin (...)
     femms

; 146	: 
; 147	: 		if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
; 148	: 		{
; 149	: 			do
; 150	: 			{
; 151	: 				index_xyz = order[2];
; 152	: 				order += 3;
; 153	: 
; 154	: 				qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha);
; 155	: 				qglVertex3fv (lerped[index_xyz]);
; 156	: 
; 157	: 			} while	(--count);
; 174	: 		}
; 175	: 
; 176	: 		qglEnd ();

     test      edi, 1C00h                         ; currententity->flags & (RF_SHELL_RED ...)
     je        $L25984                      ; 

     femms                                        ; protect OpenGL calls in loop in case FPU

align 64
$L25824:
     mov       edi, DWORD PTR [esi+8]             ; index_xyz = order[2]
     sub       esp, 16                            ; make room for 4 DWORD arguments
ESP_currofs = ESP_currofs + 16
; stack offset is 32900

; Some funny things happen to the stack offset after this point that I am not 
; clear on.  Its jumping around a lot, but I don't see how it adds up in the 
; end.  Perhaps it just relies on maintaining ebp, which in theory is 
; sufficient for retaining the stack frame.

     mov       eax, DWORD PTR _shadelight         ; shadelight[0]
     mov       DWORD PTR [esp+12], ebp            ; "push" alpha

     mov       ecx, DWORD PTR _shadelight+4       ; shadelight[1]
     shl       edi, 2				  ; 4 array elements

     mov       edx, DWORD PTR _shadelight+8       ; shadelight[2]
     cmp       ebp, ebp                           ; filler

     mov       DWORD PTR [esp], eax               ; "push" shadelight[0]
     lea       edi, DWORD PTR _s_lerped[edi*4]; lerped[index_xyz]

     mov       DWORD PTR [esp+4], ecx             ; "push" shadelight[1]
     mov       DWORD PTR [esp+8], edx             ; "push" shadelight[2]

; Indirect Call
     DCALL	_qglColor4f,2                     ; qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha)
     add       esi, 12                            ; order+=3
     push      edi                                ; lerped[index_xyz]

; Indirect Call
ifdef	DIRECT_API_CALLS
	test	 __Amd3Dfx, -1			  ; Set flags.
	jz	UseIndirectCall3
	DCALL	_qglVertex3fv,6
UseIndirectCallRet3:
else
     call      DWORD PTR _qglVertex3fv            ; qglVertex3fv (lerped[index_xyz])
endif
     dec       ebx                                ; --count
     jne       SHORT $L25824                      ; until count == 0

; Indirect Call
     DCALL	_qglEnd,1                         ; qglEnd ()
     femms                                        ; potentially more AMD3D code ahead

     add       esi, 4                             ; order++
     jmp       $L25818                            ; rejoin outer loop
UseIndirectCall3:
	call	DWORD PTR _qglVertex3fv            ; qglVertex3fv( p->origin )
	jmp	UseIndirectCallRet3

     nop                                          ; filler

; 158	: 		}
; 159	: 		else
; 160	: 		{
; 161	: 			do
; 162	: 			{
; 163	: 				// texture coordinates come from the draw list
; 164	: 				qglTexCoord2f (((float *)order)[0], ((float *)order)[1]);
; 165	: 				index_xyz = order[2];
; 166	: 				order += 3;
; 167	: 
; 168	: 				// normals and vertexes	come from the frame list
; 169	: 				l = shadedots[verts[index_xyz].lightnormalindex];
; 170	: 				
; 171	: 				qglColor4f (l* shadelight[0], l*shadelight[1], l*shadelight[2], alpha);
; 172	: 				qglVertex3fv (lerped[index_xyz]);
; 173	: 			} while	(--count);
; 174	: 		}
; 175	: 
; 176	: 		qglEnd ();

align 64
$L25984:
     add       esi, 12                            ; order+=3
     movq      mm2, QWORD PTR _shadelight         ; shadelight[1] | shadelight[0]

     mov       ecx, DWORD PTR _v$[esp+32884]      ; verts
     mov       edi, DWORD PTR [esi-4]             ; index_xyz = order[2]

     sub       esp, 24                            ; make room for arguments to qglTexCoord2f and qglColor4f
     shl       edi, 2				  ; 4 array elements

     mov       edx, DWORD PTR _shadedots          ; shadedots
     movzx     eax, BYTE PTR [ecx+edi+3]        ; verts[index_xyz].lightnormalindex

     mov       [esp+20], ebp                      ; "push" alpha
     movd      mm0, DWORD PTR [edx+eax*4]         ; l=shadedots[verts[index_xyz].lightnormalindex]

     movd      mm1, DWORD PTR _shadelight+8       ; shadelight[2]
     lea       edi, DWORD PTR _s_lerped[edi*4]; lerped[index_xyz]

     pfmul     mm1, mm0                           ; l*shadelight[2]
     punpckldq mm0, mm0                           ; l | l

     pfmul     mm2, mm0                           ; l*shadelight[1] | l*shadelight[0]
     movq      mm7, QWORD PTR [esi-12]            ; order[1] | order[0]

     movd      DWORD PTR [esp+16], mm1            ; l*shadelight[2]
     nop                                          ; filler

     movq      QWORD PTR [esp], mm7               ; order[1] | order[0]
     movq      QWORD PTR [esp+8], mm2             ; l*shadelight[1] | l*shadelight[0]

     femms                                        ; protect OpenGL calls in case FPU

     DCALL	_qglTexCoord2f,1                  ; qglTexCoord2f (((float *)order)[0], ((float *)order)[1])

     DCALL	_qglColor4f,1                     ; qglColor4f (l*shadelight[0], l*shadelight[1], l*shadelight[2], alpha)

ifdef DIRECT_API_CALLS
     test      __Amd3Dfx, -1			  ; Set flags.
endif
     push      edi                                ; lerped[index_xyz]

ifdef DIRECT_API_CALLS
; Calling D_qglVertex3fv1 doesn't necessarlily work in OpenGL because 
; OpenGL32.dll dynamically changes the function address. 

     jz	UseIndirectCall1
;;;; 3Dfx specific path
endif
     DCALL	_qglVertex3fv,1                   ; qglVertex3fv (lerped[index_xyz])
     dec       ebx                                ; --count
     femms                                        ; back to AMD3D code
     jne       SHORT $L25984                      ; until count==0
     call      DWORD PTR _qglEnd                  ; qglEnd ()
     add       esi, 4                             ; order++
     femms
     jmp       $L25818                            ; rejoin outer loop
;;;;;; End 3Dfx specific path

;;;;;; OpenGL specific path
UseIndirectCall1:
     call      DWORD PTR _qglVertex3fv            ; qglVertex3fv (lerped[index_xyz])
     dec       ebx                                ; --count
     femms
     jne       $L25984                            ; until count==0
     call      DWORD PTR _qglEnd                  ; qglEnd ()
     add       esi, 4                             ; order++
     femms
     jmp       $L25818                            ; rejoin outer loop
;;;;;; End OpenGL/3Dfx special code

$DrawDone:

; 177	: 	}
; 178	: 
; 179	: 	if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
; 180	: 		qglEnable( GL_TEXTURE_2D );
; 181	: }

     mov       edx, DWORD PTR _currententity      ; currententity

     femms                                        ; done with AMD3D code, empty FPU/MMX regs

     mov       eax, DWORD PTR [edx+68]            ; currententity->flags
     test      ah, 28                             ; RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE

     jz        SHORT $L25831                      ;
     push      3553                               ; GL_TEXTURE_2D = 00000de1H

;;; Indirect Call
     DCALL	_qglEnable,2                      ; qglEnable( GL_TEXTURE_2D )
$L25831:
     pop       edi                                ; restore caller's register variable
     pop       esi                                ; restore caller's register variable

     pop       ebx                                ; restore caller's register variable
     pop       ebp                                ; restore frame pointer

     add       esp, 32868                         ; remove local variables from stack
     ret                                          ; done, return to caller

ifdef	DIRECT_API_CALLS

ConvertIndirectCalls:

	lea	eax, _GL_DrawAliasFrameLerpEnd
	lea	edx, _GL_DrawAliasFrameLerp
	sub	eax, edx
	push	eax
	push	edx

	call	_Sys_MakeCodeWriteable
	add	esp, 8

	lea	eax, _qglEnable
	lea	edx, D_qglEnable2
	call	ProcAddrWorm

ifdef D_qglEnable3	
	lea	eax, _qglEnable
	lea	edx, D_qglEnable3
	call	ProcAddrWorm
endif

	lea	eax, _qglTexCoord2f
	lea	edx, D_qglTexCoord2f1
	call	ProcAddrWorm

	lea	eax, _qglColor4f
	lea	edx, D_qglColor4f1
	call	ProcAddrWorm

	lea	eax, _qglVertex3fv
	lea	edx, D_qglVertex3fv1
	call	ProcAddrWorm

	lea	eax, _qglBegin
	lea	edx, D_qglBegin1
	call	ProcAddrWorm

	lea	eax, _qglEnd
	lea	edx, D_qglEnd1
	call	ProcAddrWorm

ifdef D_qglEnd5	
        lea	eax, _qglEnd
	lea	edx, D_qglEnd5
	call	ProcAddrWorm
endif

ifdef D_qglEnd6	
        lea	eax, _qglEnd
	lea	edx, D_qglEnd6
	call	ProcAddrWorm
endif

	lea	eax, _qglColor4f
	lea	edx, D_qglColor4f2
	call	ProcAddrWorm

	lea	eax, _qglVertex3fv
	lea	edx, D_qglVertex3fv6
	call	ProcAddrWorm

; This bypass does not apply to the SIN code.

ifdef D_qglDisable1
	lea	eax, _qglDisable
	lea	edx, D_qglDisable1
	call	ProcAddrWorm
endif

	lea	eax, _qglEnableClientState
	lea	edx, D_qglEnableClientState1
	call	ProcAddrWorm

	lea	eax, _qglEnableClientState
	lea	edx, D_qglEnableClientState2
	call	ProcAddrWorm

	lea	eax, _qglColorPointer
	lea	edx, D_qglColorPointer1
	call	ProcAddrWorm

	lea	eax, _qglVertexPointer
	lea	edx, D_qglVertexPointer1
	call	ProcAddrWorm

ifdef D_qglColor4f4	
        lea	eax, _qglColor4f
	lea	edx, D_qglColor4f4
	call	ProcAddrWorm
endif

	lea	eax, _qglBegin
	lea	edx, D_qglBegin5
	call	ProcAddrWorm

ifdef D_qglTexCoord2f6	
        lea	eax, _qglTexCoord2f
	lea	edx, D_qglTexCoord2f6
	call	ProcAddrWorm
endif

ifdef D_qglArrayElement1	
        lea	eax, _qglArrayElement
	lea	edx, D_qglArrayElement1
	call	ProcAddrWorm
endif

;;; Test code
;	int	3
;	lea	eax, pTestProc
;	lea	edx, D_pTestProc
;	call	ProcAddrWorm
;	DCALL	_pTestProc
;;; END test code

	mov	_GL_DAFL_InitFlag, -1
	jmp	_GL_DrawAliasFrameLerp
endif
_GL_DrawAliasFrameLerpEnd	label	byte
_GL_DrawAliasFrameLerp ENDP
_TEXT	ENDS

CONST	SEGMENT
;$T26075	DQ	0bf70101010101010r		; -0.00392157
$T26047	DD	000000000r			; 0
CONST	ENDS
_DATA	SEGMENT
align	16
COMM	_pointcolor:DWORD:03H
COMM	_lightspot:DWORD:03H
COMM	_lightplane:DWORD
_DATA	ENDS

;	COMDAT _RecursiveLightPoint

CONST	SEGMENT
	ORG $+4
$T51428	DQ	0bf70101010101010r		; -0.00392157
CONST	ENDS

;	COMDAT _RecursiveLightPoint
_TEXT	SEGMENT
_node$ = 8
_start$ = 12
_end$ = 16
_front$ = 12
_back$ = -28
_side$ = -32
_mid$ = -24
_i$ = 12
_scale$51071 = -12
_RecursiveLightPoint PROC NEAR				; COMDAT

; 297  : {

	sub	esp, 32					; 00000020H
	push	ebx
	push	ebp

; 298  : 	float		front, back, frac;
; 299  : 	int			side;
; 300  : 	cplane_t	*plane;
; 301  : 	vec3_t		mid;
; 302  : 	msurface_t	*surf;
; 303  : 	int			s, t, ds, dt;
; 304  : 	int			i;
; 305  : 	mtexinfo_t	*tex;
; 306  : 	byte		*lightmap;
; 307  : 	int			maps;
; 308  : 	int			r;
; 309  : 
; 310  : RLP_TailRecurseRestart:
; 311  : 
; 312  : 	if (node->contents != -1)

	mov	ebp, DWORD PTR _node$[esp+36]
	push	esi
	push	edi
	cmp	DWORD PTR [ebp], -1
	jne	$L51421

; 320  : 	back = DotProduct (end, plane->normal) - plane->dist;

	mov	ecx, DWORD PTR _start$[esp+44]
	jmp	SHORT $RLP_TailRecurseRestart$51055
$L51429:
	mov	ebp, DWORD PTR _node$[esp+44]
$RLP_TailRecurseRestart$51055:

; 314  : 
; 315  : // calculate mid point
; 316  : 
; 317  : // FIXME: optimize for axial
; 318  : 	plane = node->plane;
; 319  : 	front = DotProduct (start, plane->normal) - plane->dist;

     mov	 esi, DWORD PTR [ebp+36]
     mov	 edx, DWORD PTR _end$[esp+44]

     femms

     movq        mm6, qword ptr [esi]

     movq        mm2, qword ptr [ecx]

     movq        mm3, qword ptr [edx]
     pfmul       mm2, mm6

     movq        mm7, qword ptr [esi+8]
     pfmul       mm3, mm6

     movd        mm4, dword ptr [ecx+8]
     pfacc       mm2, mm2

     movd        mm5, dword ptr [edx+8]
     pfacc       mm3, mm3

     pfmul       mm4, mm7

     pfmul       mm5, mm7

     punpckhdq   mm7, mm7

     pfsub       mm4, mm7

     pfsub       mm5, mm7

     pfadd       mm2, mm4
     movd        DWORD PTR _front$[esp+44], mm2

     pfadd       mm3, mm5
     movd        DWORD PTR _back$[esp+48], mm3

; 345  : 	if ( (back < 0) == (front < 0) ) {

     pxor        mm4, mm4
     punpckldq   mm3, mm2

     pfcmpgt     mm4, mm3

     psrld       mm4, 31

     movd        edi, mm4
     punpckhdq   mm4, mm4

     movd        eax, mm4
     mov	 DWORD PTR _side$[esp+48], eax

     femms

     cmp	 edi, eax
     jne 	 SHORT $L51057

; 327  : 		return RecursiveLightPoint (node->children[side], start, end);

     mov	eax, DWORD PTR [ebp+eax*4+40]
     mov	DWORD PTR _node$[esp+44], eax
     jmp	$L51424
$L51057:

; 331  : #endif
; 332  : 	}
; 333  : 
; 334  : 	frac = front / (front-back);

     pfsubr      mm3, mm2
     punpckldq   mm2, mm2

     movq        mm0, qword ptr [ecx]
     lea	 edi, DWORD PTR _mid$[esp+48]

     pfrcp       mm4, mm3
     movq        mm1, qword ptr [edx]

     pfsub       mm1, mm0
     movd        mm5, dword ptr [ecx+8]

     pfrcpit1    mm3, mm4
     movd        mm6, dword ptr [edx+8]

     pfsub       mm6, mm5
     push	 edi

     pfrcpit2    mm3, mm4
     push	 ecx

     mov	 eax, DWORD PTR [ebp+eax*4+40]
     nop

     push	 eax
     pfmul       mm2, mm3                       ; frac = front / (front-back);

     pfmul       mm1, mm2

     pfmul       mm6, mm2

     pfadd       mm1, mm0
     movq        qword ptr [edi], mm1

     pfadd       mm6, mm5
     movd        dword ptr [edi+8], mm6

     call	 _RecursiveLightPoint

     add	 esp, 12			; 0000000cH

     femms

; 341  : 	if (r >= 0)

     test	eax, eax
     jge	$L51038

; 342  : 		return r;		// hit something
; 346  : 
; 347  : 	if ( (back < 0) == side )
; 348  : 		return -1;		// didn't hit anuthing
; 350  : 
; 351  : // check for impact on this node
; 352  : 	VectorCopy (mid, lightspot);

	mov	ecx, DWORD PTR _mid$[esp+56]
	mov	edx, DWORD PTR _mid$[esp+48]
	mov	eax, DWORD PTR _mid$[esp+52]
	mov	DWORD PTR _lightspot+8, ecx

; 353  : 	lightplane = plane;
; 354  : 
; 355  : 	surf = r_worldmodel->surfaces + node->firstsurface;

	xor	ecx, ecx
	mov	DWORD PTR _lightspot, edx
	mov	DWORD PTR _lightspot+4, eax
	mov	DWORD PTR _lightplane, esi
	mov	cx, WORD PTR [ebp+48]

; 356  : 	for (i=0 ; i<node->numsurfaces ; i++, surf++)

	xor	ebx, ebx
	mov	eax, ecx
	mov	bx, WORD PTR [ebp+50]
	shl	eax, 3
	sub	eax, ecx
	mov	DWORD PTR _i$[esp+44], 0
	test	ebx, ebx
	lea	edx, DWORD PTR [eax+eax*2]
	mov	eax, DWORD PTR _r_worldmodel
	mov	ecx, DWORD PTR [eax+212]
	lea	edi, DWORD PTR [ecx+edx*8]
	jle	$L51061
$L51059:

; 357  : 	{
; 358  : 		if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY))

	test	BYTE PTR [edi+8], 20			; 00000014H
	jne	$L51060

; 359  : 			continue;	// no lightmaps
; 360  : 
; 361  : 		tex = surf->texinfo;

	mov	esi, DWORD PTR [edi+56]

; 362  : 
; 363  : 		s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];

     femms

     movq        mm2, qword ptr [esi]

     movq        mm0, qword ptr _mid$[esp+48]

     pfmul       mm2, mm0
     movq        mm5, qword ptr [esi+16]

     movq        mm4, qword ptr Float_1x2

     pfmul       mm5, mm0
     movd        mm1, dword ptr _mid$[esp+48+8]

     movq        mm3, qword ptr [esi+8]
     punpckldq   mm1, mm4

     pfmul       mm3, mm1
     movq        mm6, qword ptr [esi+24]

     pfacc       mm2, mm3
     pfacc       mm2, mm2

     pf2id       mm2, mm2
     pfmul       mm6, mm1

     pfacc       mm5, mm6
     pfacc       mm5, mm5

     pf2id       mm5, mm5

     movd        ebp, mm2
     movd        eax, mm5

     femms

; output in eax

; 386  : 		if (s < surf->texturemins[0] || t < surf->texturemins[1])
; 387  : 			continue;
; 388  : 
; 389  : 		ds = s - surf->texturemins[0];
; 390  : 		dt = t - surf->texturemins[1];

     movsx	ecx, WORD PTR [edi+20]
     cmp	ebp, ecx
     jl		SHORT $L51383
     movsx	edx, WORD PTR [edi+22]
     cmp	eax, edx
     jl		SHORT $L51383

; 367  : 			continue;
; 368  : 
; 369  : 		ds = s - surf->texturemins[0];
; 370  : 		dt = t - surf->texturemins[1];

    sub		eax, edx
    sub		ebp, ecx

; 371  : 
; 372  : 		if ( ds > surf->extents[0] || dt > surf->extents[1] )

    movsx	edx, WORD PTR [edi+24]
    cmp		ebp, edx
    jg		SHORT $L51383
    movsx	ecx, WORD PTR [edi+26]
    cmp		eax, ecx
    jle		SHORT $L51065
$L51383:
    mov		ebp, DWORD PTR _node$[esp+44]
$L51060:

; 356  : 	for (i=0 ; i<node->numsurfaces ; i++, surf++)

     mov	eax, DWORD PTR _i$[esp+44]
     add	edi, 168				; 000000a8H
     inc	eax
     cmp	eax, ebx
     mov	DWORD PTR _i$[esp+44], eax
     jl		$L51059
$L51061:

; 422  : 	}
; 423  : 
; 424  : // go down back side
; 425  : #if 0
; 426  : 	return RecursiveLightPoint (node->children[!side], mid, end);
; 427  : #else
; 428  :     node = node->children[!side];

	mov	eax, DWORD PTR _side$[esp+48]
	xor	edx, edx
	test	eax, eax
	sete	dl

; 429  :     start = mid;

	lea	ecx, DWORD PTR _mid$[esp+48]
	mov	eax, DWORD PTR [ebp+edx*4+40]
	mov	DWORD PTR _node$[esp+44], eax
$L51424:
	mov	edx, DWORD PTR _node$[esp+44]
	cmp	DWORD PTR [edx], -1
	je	$L51429
$L51421:

; 313  : 		return -1;		// didn't hit anything

	or	eax, -1

; 430  :     goto RLP_TailRecurseRestart;
; 431  : #endif
; 432  : }

	pop	edi
	pop	esi
	pop	ebp
	pop	ebx
	add	esp, 32					; 00000020H
	ret	0
$L51065:

; 393  : 			continue;
; 394  : 
; 395  : #ifdef SIN
; 396  :       if (surf->flags&SURF_DRAWNONLIT) {

     mov	 ecx, DWORD PTR [edi+8]
     test	 ch, 1
     je 	 $L51067

; 397  :          pointcolor[0] = tex->s->surfinfo->nonlit;
; 398  :          pointcolor[1] = tex->s->surfinfo->nonlit;
; 399  :          pointcolor[2] = tex->s->surfinfo->nonlit;

     mov	 eax, DWORD PTR [esi+44]
     mov	 edx, DWORD PTR [eax+120]
     mov	 DWORD PTR _pointcolor, edx
     mov	 DWORD PTR _pointcolor+4, edx
     mov	 DWORD PTR _pointcolor+8, edx

; 400  : 
; 401  :          if (surf->texinfo->flags & SURF_USECOLOR) {

     mov	 eax, DWORD PTR [edi+56]
     mov	 ecx, DWORD PTR [eax+32]
     test	 ch, -128		; ffffff80H
     je 	 $L51074

; 402  :             pointcolor[0] *= tex->s->surfinfo->color[0];
; 403  :             pointcolor[1] *= tex->s->surfinfo->color[1];
; 404  :             pointcolor[2] *= tex->s->surfinfo->color[2];

     mov	 edx, DWORD PTR [esi+44]

     movq        mm0, QWORD PTR _pointcolor
     movq        mm1, QWORD PTR [edx+156]
     pfmul       mm0, mm1

     movd        mm2, DWORD PTR _pointcolor+8
     movd        mm3, DWORD PTR [edx+156+8]
     pfmul       mm2, mm3

     movq        QWORD PTR _pointcolor, mm0
     movd        DWORD PTR _pointcolor+8, mm2

     mov	 eax, 1

     femms

; 441  : 		return 1;
; 450  :     goto RLP_TailRecurseRestart;
; 451  : #endif
; 452  : }

     pop	edi
     pop	esi
     pop	ebp
     pop	ebx
     add	esp, 32					; 00000020H
     ret	0
$L51067:

; 385  :          }
; 386  :          return 1;
; 387  :       }
; 388  : #endif
; 389  : 		if (!surf->samples)

     mov	edx, DWORD PTR [edi+152]
     test	edx, edx
     jne	SHORT $L51069

; 390  : 			return 0;

     xor	eax, eax

; 430  :     goto RLP_TailRecurseRestart;
; 431  : #endif
; 432  : }

     pop	edi
     pop	esi
     pop	ebp
     pop	ebx
     add	esp, 32					; 00000020H
     ret	0
$L51069:

; 391  : 
; 392  : 		ds >>= 4;
; 393  : 		dt >>= 4;
; 394  : 
; 395  : 		lightmap = surf->samples;
; 396  : 		VectorCopy (vec3_origin, pointcolor);

     mov	ecx, DWORD PTR _vec3_origin
     mov	DWORD PTR _pointcolor, ecx
     mov	ecx, DWORD PTR _vec3_origin+4
     mov	DWORD PTR _pointcolor+4, ecx
     mov	ecx, DWORD PTR _vec3_origin+8
     mov	DWORD PTR _pointcolor+8, ecx

; 397  : #ifdef SIN
; 398  :       if (/*lightmap &&*/ r_newrefdef.lightstyles)

     mov	ecx, DWORD PTR _r_newrefdef+76
     sar	ebp, 4
     sar	eax, 4
     test	ecx, ecx
     je		$L51074

; 399  : #else
; 400  :       if (lightmap)
; 401  : #endif
; 402  : 		{
; 403  : 			vec3_t scale;
; 404  : 
; 405  : 			lightmap += 3*(dt * ((surf->extents[0]>>4)+1) + ds);

	movsx	ecx, WORD PTR [edi+24]
	sar	ecx, 4
	inc	ecx

; 430  :     goto RLP_TailRecurseRestart;
; 431  : #endif
; 432  : }

	mov	ebx, DWORD PTR _gl_modulate
	imul	ecx, eax
	add	ecx, ebp
	lea	ebp, DWORD PTR [edi+72]
	mov	eax, ecx
	add	eax, edx
	lea	edx, DWORD PTR [eax+ecx*2]
	mov	eax, -72				; ffffffb8H
	sub	eax, edi
	mov	DWORD PTR 12+[esp+44], eax
$L51072:
	mov	al, BYTE PTR [ebp]
	cmp	al, 255					; 000000ffH
	je	$L51074
	mov	esi, DWORD PTR _r_newrefdef+76
	and	eax, 255				; 000000ffH
	lea	ecx, DWORD PTR _scale$51071[esp+48]
	lea	eax, DWORD PTR [eax+eax*2]
	lea	eax, DWORD PTR [esi+eax*8]
	mov	esi, 3
$L51075:
	fld	DWORD PTR [ebx+20]
	fmul	DWORD PTR [eax]
	add	eax, 4
	add	ecx, 4
	dec	esi
	fstp	DWORD PTR [ecx-4]
	jne	SHORT $L51075
	fld	DWORD PTR _pointcolor
	xor	ecx, ecx
	xor	eax, eax
	mov	cl, BYTE PTR [edx]
	mov	DWORD PTR 8+[esp+44], ecx
	xor	ecx, ecx
	fild	DWORD PTR 8+[esp+44]
	fmul	DWORD PTR _scale$51071[esp+48]
	fmul	QWORD PTR $T51428
	fsubp	ST(1), ST(0)
	fstp	DWORD PTR _pointcolor
	mov	al, BYTE PTR [edx+1]
	fld	DWORD PTR _pointcolor+4
	mov	DWORD PTR 8+[esp+44], eax
	fild	DWORD PTR 8+[esp+44]
	fmul	DWORD PTR _scale$51071[esp+52]
	fmul	QWORD PTR $T51428
	fsubp	ST(1), ST(0)
	fstp	DWORD PTR _pointcolor+4
	mov	cl, BYTE PTR [edx+2]
	fld	DWORD PTR _pointcolor+8
	mov	DWORD PTR 8+[esp+44], ecx
	fild	DWORD PTR 8+[esp+44]
	fmul	DWORD PTR _scale$51071[esp+56]
	fmul	QWORD PTR $T51428
	fsubp	ST(1), ST(0)
	fstp	DWORD PTR _pointcolor+8
	movsx	eax, WORD PTR [edi+26]
	movsx	ecx, WORD PTR [edi+24]
	sar	eax, 4
	sar	ecx, 4
	inc	eax
	inc	ecx
	imul	eax, ecx
	mov	ecx, eax
	add	ecx, edx
	inc	ebp
	lea	edx, DWORD PTR [ecx+eax*2]
	mov	eax, DWORD PTR 12+[esp+44]
	add	eax, ebp
	cmp	eax, 16					; 00000010H
	jl	$L51072
$L51074:

; 406  : 
; 407  : 			for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
; 408  : 					maps++)
; 409  : 			{
; 410  : 				for (i=0 ; i<3 ; i++)
; 411  : 					scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
; 412  : 
; 413  : 				pointcolor[0] += lightmap[0] * scale[0] * (1.0/255);
; 414  : 				pointcolor[1] += lightmap[1] * scale[1] * (1.0/255);
; 415  : 				pointcolor[2] += lightmap[2] * scale[2] * (1.0/255);
; 416  : 				lightmap += 3*((surf->extents[0]>>4)+1) *
; 417  : 						((surf->extents[1]>>4)+1);
; 418  : 			}
; 419  : 		}
; 420  : 
; 421  : 		return 1;

	mov	eax, 1
$L51038:

; 430  :     goto RLP_TailRecurseRestart;
; 431  : #endif
; 432  : }

	pop	edi
	pop	esi
	pop	ebp
	pop	ebx
	add	esp, 32					; 00000020H
	ret	0
_RecursiveLightPoint ENDP
_TEXT	ENDS


_DATA	SEGMENT
align	16
COMM	_r_nocull:DWORD
_DATA	ENDS

CONST	SEGMENT
$T26379	DD	000000000r			; 0
CONST	ENDS
;	COMDAT _R_CullBox
_TEXT	SEGMENT
_mins$ = 8
_maxs$ = 12
_R_CullBox PROC	NEAR					; COMDAT

; 114	: 		int		i;
; 115	: 
; 116	: 		if (r_nocull->value)

	mov		eax, DWORD PTR _r_nocull
	femms
	push		ebx
	push		esi
	push		edi

	mov		eax, [eax+20]
	or		eax, eax
	jnz		$L25771

	mov		esi, OFFSET FLAT:_frustum
	mov		edi, DWORD PTR _maxs$[esp+8]
	mov		ebx, DWORD PTR _mins$[esp+8]

$L25769:
	push		esi
	push		edi
	push		ebx
	call		_AmdBoxOnPlaneSide
	add		esp, 12
	cmp		eax, 2
	je		SHORT $L26377
	add		esi, 14h
	cmp		esi, OFFSET FLAT:_frustum+80
	jl		SHORT $L25769

	xor		eax, eax

	pop		edi
	pop		esi
	pop		ebx
	femms
	ret		0
$L26377:

	mov		eax, 1

	pop		edi
	pop		esi
	pop		ebx
	femms
	ret		0
$L25771:
	pop		edi
	pop		esi
	xor		eax, eax
	pop		ebx
	femms
	ret		0

_R_CullBox ENDP
_TEXT	ENDS
CONST	SEGMENT
FloatPtFivex2	dq	3F0000003F000000h
FloatMinus64x2	dq     0C2800000C2800000h	
SignBitLow	dq	0000000080000000h
FloatPt125x2	dq	3E0000003E000000h
TurbScalex2	dq	4222F9834222F983h 	; (256/(2*PI)) | (256/(2*PI))
Int255x2	dq	000000FF000000FFh	; 255 | 255
FloatInv64x2	dq	3C8000003C800000h	; 1/64 | 1/64
CONST	ENDS
;	COMDAT _EmitWaterPolys

_DATA	SEGMENT
PUBLIC	_EWP_InitFlag
 _EWP_InitFlag	dd	0
_DATA	ENDS

_TEXT	SEGMENT
; arg offset(s) relative to ebp:
_fa$ = 8
; local var offsets relative to ebp:
_p$ = -4
_bp$ = -8
_v$ = -12
_i$ = -16
; _s & _t must be paired with _s at the low address
_t$ = -20
_s$ = -24
; _os & _ot must be paired with _os at the low address
_ot$ = -28
_os$ = -32
;;;
_scroll$ = -36
_rdt$ = -40
align	32
x_EmitWaterPolys PROC NEAR				; COMDAT
; 193  : {
;void EmitWaterPolys (msurface_t *fa)
ifdef	DIRECT_API_CALLS
	test	_EWP_InitFlag, -1
	jz	EWP_CvtIndCalls
endif
	push		ebp
	mov		ebp, esp

	sub		esp, 40

; 194  : 	glpoly_t	*p, *bp;
; 195  : 	float		*v;
; 196  : 	int			i;
; 197  : 	float		s, t, os, ot;
; 198  : 	float		scroll;
; 199  : 	float		rdt = r_newrefdef.time;

	mov		eax, DWORD PTR _r_newrefdef+64
	femms

	push		ebx
	push		esi

; 200  : 
; 201  : 	if (fa->texinfo->flags & SURF_FLOWING)

	mov		esi, DWORD PTR _fa$[ebp]
	mov		DWORD PTR _rdt$[ebp], eax

	push		edi
	mov		ecx, DWORD PTR [esi+56]

	test		BYTE PTR [ecx+32], 64			; 00000040H
	pxor		mm0, mm0

	je		SHORT $L25853

; 202  : 		scroll = -64 * ( (r_newrefdef.time*0.5) - (int)(r_newrefdef.time*0.5) );

	movd		mm0, dword ptr _r_newrefdef+64
	movq		mm2, [FloatPtFivex2]

	movq		mm1, mm0
	movq		mm4, [FloatMinus64x2]

	pf2id		mm0, mm0
	movq		mm3, [SignBitLow]

	pi2fd		mm0, mm0

	punpckldq	mm0, mm1	; mm0 = r_newrefdef.time | (float)(int)r_newrefdef.time

	pfmul		mm0, mm2	; mm0 = r_newrefdef.time*0.5 | (float)(int)r_newrefdef.time*0.5

	pxor		mm0, mm3	; mm0 = r_newrefdef.time*0.5 | -1 (float)(int)r_newrefdef.time*0.5

	pfacc		mm0, mm0	; mm0 = X | (r_newrefdef.time*0.5) - (int)(r_newrefdef.time*0.5)

	pfmul		mm0, mm4	; mm0 = X | -64 * ( (r_newrefdef.time*0.5) - (int)(r_newrefdef.time*0.5) )

$L25853:
	movd		_scroll$[ebp], mm0

; 205  : 	for (bp=fa->polys ; bp ; bp=bp->next)

	mov		edi, DWORD PTR [esi+44]

	test		edi, edi
	je		$L25857

	jmp		short $L25855
align	32
$L25855:

; 206  : 	{
; 207  : 		p = bp;
; 208  : 
; 209  : 		qglBegin (GL_TRIANGLE_FAN);

	push		6
	FCALL		_qglBegin

; 210  : 		for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)

	mov		eax, [edi+8]
	xor		ebx, ebx

	test		eax, eax
	lea		esi, [edi+16]

	jle		$L25860
	jmp		short $L25858
align	64
$L25858:
; 212  : 			os = v[3];
; 213  : 			ot = v[4];
; 218  : 			s = os + r_turbsin[Q_ftol( ((ot*0.125+rdt) * TURBSCALE) ) & 255];
; 226  : 			t = ot + r_turbsin[Q_ftol( ((os*0.125+rdt) * TURBSCALE) ) & 255];

	movq		mm0, qword ptr [esi+12]		; mm0 = v[4] | v[3]
	movd		mm3, _rdt$[ebp]			; mm3 = 0 | rdt

	movq		mm2, [FloatPt125x2]		; mm2 = 0.125 | 0.125
	movq		mm4, mm0

	punpckldq	mm3, mm3			; mm3 = rdt | rdt
	pfmul		mm0, mm2			; mm0 =   ot*0.125 |   os*0.125

	movq		mm5, [TurbScalex2]
	pfadd		mm0, mm3			; mm0 =   ot*0.125+rdt |   os*0.125+rdt

	lea		eax, _r_turbsin
	pfmul		mm0, mm5			; mm0 = TURBSCALE*(ot*0.125+rdt) | TURBSCALE*(os*0.125+rdt)

	movq		mm2, [Int255x2]			;
	movd		mm1, eax

	pf2id		mm0, mm0			;
	punpckldq	mm1, mm1			; mm1 = &r_turbsin[0] | &r_turbsin[0]

	pand		mm0, mm2			; mm0 = (TURBSCALE*(ot*0.125+rdt)) & 0xFF | (TURBSCALE*(os*0.125+rdt)) & 0xFF
	movq		mm7, [FloatInv64x2]		; mm7 = 1/16 | 1/16

	psllq		mm0, 2
	paddd		mm0, mm1			; mm0 = &r_turbsin[Q_ftol( ((ot*0.125+rdt) * TURBSCALE) ) & 255] | 
							;	&r_turbsin[Q_ftol( ((os*0.125+rdt) * TURBSCALE) ) & 255]
	movd		eax, mm0			; eax = &r_turbsin[Q_ftol( ((os*0.125+rdt) * TURBSCALE) ) & 255]

	punpckhdq	mm0, mm0
	movd		mm6, _scroll$[ebp]

	movd		edx, mm0			; edx = &r_turbsin[Q_ftol( ((ot*0.125+rdt) * TURBSCALE) ) & 255]
	movd		mm1, [eax]			; mm1 = 0 | r_turbsin[Q_ftol( ((os*0.125+rdt) * TURBSCALE) ) & 255]

	movd		mm2, [edx]			; mm2 = 0 | r_turbsin[Q_ftol( ((ot*0.125+rdt) * TURBSCALE) ) & 255]
	punpckldq	mm1, mm2			; mm1 = r_turbsin[Q_ftol( ((ot*0.125+rdt) * TURBSCALE) ) & 255] |
							;	r_turbsin[Q_ftol( ((os*0.125+rdt) * TURBSCALE) ) & 255]
	pfadd		mm1, mm4			; mm1 = t | s
	sub		esp, 8

	pfadd		mm1, mm6			; mm1 = t | s+scroll
	pfmul		mm1, mm7			; mm1 = (1/64)*t | (1/64)*(s+scroll)

	movq		[esp], mm1
	femms
	DCALL	_qglTexCoord2f,2

	push		esi
ifdef	DIRECT_API_CALLS                          
	test	__Amd3Dfx, -1			  ; Set flags.
	jz	UseIndirectCall4
	DCALL	_qglVertex3fv,3
UseIndirectCallRet4:
else
	call		DWORD PTR _qglVertex3fv
endif
	femms

	mov		eax, DWORD PTR [edi+8]
	inc		ebx

	add		esi, 28
	cmp		ebx, eax

	jl		$L25858

$L25860:
	FCALL	DWORD PTR _qglEnd

	mov		edi, DWORD PTR [edi]
	test		edi, edi

	jne		$L25855

$L25857:
	femms
	pop		edi
	pop		esi
	pop		ebx
	add		esp, 40
	pop		ebp
	ret		0
ifdef	DIRECT_API_CALLS

UseIndirectCall4:
	call	DWORD PTR _qglVertex3fv            ; qglVertex3fv( p->origin )
	jmp	UseIndirectCallRet4

EWP_CvtIndCalls:
	lea	eax, x_EmitWaterPolysEnd
	lea	edx, x_EmitWaterPolys
	sub	eax, edx
	push	eax
	push	edx

	call	_Sys_MakeCodeWriteable
	add	esp, 8

	lea	eax, _qglTexCoord2f
	lea	edx, D_qglTexCoord2f2
	call	ProcAddrWorm

	lea	eax, _qglVertex3fv
	lea	edx, D_qglVertex3fv3
	call	ProcAddrWorm

	mov	_EWP_InitFlag, -1
	jmp	x_EmitWaterPolys
endif
x_EmitWaterPolysEnd	label	byte
x_EmitWaterPolys ENDP

ifdef	AMD_CHKSTK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;	__chkstk
;		Replaces Microsoft's __chkstk. Prevents re-probing of
;		memory pages. Keeps track of the lowest probed memory
;		address and only probes when the current stack minus
;		the requested size is lower than the last saved
;		lowest address. The lowest address variable is
;		initialized to -1 so the first time __chkstk is
;		called, probing occurs. Probing is done in 4k increments.
;		It is not known what the side effects of this routine might
;		be, particulary in low physical memory configurations.
;
;	Arguments:
;		EAX	= Requested stack allocation (must be +'ve)
;		
;	Returns:
;		EAX	= Undefined
;		ESP	= New stack pointer (ESP - Requested stack allocation)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align	32
__chkstk	PROC
	push		ecx		; Save	ecx
	push		edx
	cmp		eax,00001000h	; Is requested stack size greater than 4k?
	lea		ecx,[esp+12]	; Get a copy of the stack pointer
	jb		JumpTheWall
	mov		edx, ecx
	sub		edx, eax
	cmp		edx, [LowestAddr]
	jae		JumpTheWall
	mov		[LowestAddr], edx
	jmp		short WalkTheLine

align	32
WalkTheLine:
	sub		ecx,00001000h
	sub		eax,00001000h
	test		[ecx],eax
	cmp		eax,00001000h
	jae		WalkTheLine		; Touch (read) each 4k block

JumpTheWall:
	sub		ecx,eax		; Subtract any remainder < 4k
	mov		eax,esp		; Save the old stack pointer in eax
	test		[ecx],eax	; Touch (read) the last 4k page
	mov		esp,ecx		; Init the "new" stack pointer
	mov		edx,[eax]	; Restore edx
	mov		ecx,[eax+04]	; Restore ecx
	mov		eax,[eax+08]	; Get the return address
	push		eax		; ...and push it on the "new" stack.
	ret				; return to the caller

__chkstk	ENDP

_TEXT	ENDS

_DATA	SEGMENT
align	16
PUBLIC	_GL_RLP_InitFlag
_GL_RLP_InitFlag	dd	0
LowestAddr	dd	0FFFFFFFFh		; Init to -1 so first call will
_DATA	ENDS					; cause probe to occur.

else

_TEXT	ENDS

endif	; AMD_CHKSTK


ifndef SIN

;	COMDAT _GL_RenderLightmappedPoly
_TEXT	SEGMENT
_surf$ = 8
_nv$ = -65548
_image$ = -65540
_is_dynamic$ = -65544
_temp$25953 = -65536

align	32
_GL_RenderLightmappedPoly PROC NEAR			; COMDAT

ifdef	DIRECT_API_CALLS
     test	_GL_RLP_InitFlag, -1
     jz	GL_RLP_CvtIndCalls
endif


; 600  : {

; 601  : 		int		i, nv = surf->polys->numverts;
; 602  : 		int		map;
; 603  : 		float	*v;
; 604  : 		image_t *image = R_TextureAnimation( surf->texinfo );
; 605  : 		qboolean is_dynamic = false;
; 606  : 		unsigned lmtex = surf->lightmaptexturenum;

     mov		eax, 65548				; 0001000cH
     call		__chkstk
     push		ebx
     push		ebp
     push		esi
     mov		esi, dword ptr _surf$[esp+65556]
     push		edi
     mov		eax, dword ptr [esi+44]
     mov		edx, dword ptr [esi+56]
     push		edx
     mov		ecx, dword ptr [eax+8]
     mov		dword ptr _nv$[esp+65568], ecx
     femms
     call	_R_TextureAnimation
     femms
     mov		ebx, dword ptr [esi+68]

; 607  : 		glpoly_t *p;
; 608  : 
; 609  : 		for ( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )

     mov		edi, dword ptr _r_newrefdef+76
     add		esp, 4
     mov		ebp, eax
     xor		ecx, ecx
     mov		dword ptr _image$[esp+65564], ebp
     mov		dword ptr _is_dynamic$[esp+65564], ecx
     lea		edx, dword ptr [esi+76]
;	jmp		short $L25944

align	32
$L25944:
     mov		al, byte ptr [ecx+esi+72]
     cmp		al, 255					; 000000ffH
     je		short $L25946

; 610  : 		{
; 611  : 			if ( r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map] )

     and		eax, 255				; 000000ffH
     shl		eax, 4

     movd		mm1, [edx]
     movd		mm0, [eax+edi+12]
     pfcmpeq		mm1, mm0
     movd		eax, mm1
     or		eax, eax
;	fld		dword ptr [eax+edi+12]
;	fcomp		dword ptr [edx]
;	fnstsw		ax
;	test		ah, 64					; 00000040H
     jz		short $dynamic$25948	; jump when NOT equal
     inc		ecx
     add		edx, 4
     cmp		ecx, 4
     jl		short $L25944
$L25946:

; 612  : 				goto dynamic;
; 613  : 		}
; 614  : 
; 615  : 		// dynamic this frame or dynamic previously
; 616  : 		if ( ( surf->dlightframe == r_framecount ) )

     mov		eax, dword ptr [esi+60]
     mov		edx, dword ptr _r_framecount
     cmp		eax, edx
     jne		short $L26304
$dynamic$25948:

; 617  : 		{
; 618  : dynamic	:
; 619  : 			if ( gl_dynamic->value )

     mov		edx, dword ptr _gl_dynamic
     or		edx, edx
;	fld		dword ptr [edx+20]
;	fcomp		dword ptr $T26233
;	fnstsw		ax
;	test		ah, 64					; 00000040H
;	jne		short $L26304
     jz		short $L26304

; 620  : 			{
; 621  : 				if ( !(surf->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP ) ) )

     mov		eax, dword ptr [esi+56]
     mov		dl, byte ptr [eax+32]

; 622  : 				{
; 623  : 					is_dynamic = true;

     mov		eax, 1
     test		dl, 60					; 0000003cH
     je		short $L25951
$L26304:
     mov		eax, dword ptr _is_dynamic$[esp+65564]
$L25951:

; 624  : 				}
; 625  : 			}
; 626  : 		}
; 627  : 
; 628  : 		if ( is_dynamic )

     test		eax, eax
     je		$L25952

; 629  : 		{
; 630  : 			unsigned	temp[128*128];
; 631  : 			int			smax, tmax;
; 632  : 
; 633  : 			if ( ( surf->styles[map] >= 32 || surf->styles[map] == 0 ) && ( surf->dlightframe != r_framecount ) )

     mov		cl, byte ptr [ecx+esi+72]
     cmp		cl, 32					; 00000020H
     jae		short $L25957
     test		cl, cl
     jne		short $L25956
$L25957:
     mov		ecx, dword ptr _r_framecount
     mov		eax, dword ptr [esi+60]
     cmp		eax, ecx
     je		short $L25956

; 634  : 			{
; 635  : 				smax = (surf->extents[0]>>4)+1;

     movsx		edi, WORD ptr [esi+24]

; 636  : 				tmax = (surf->extents[1]>>4)+1;

     movsx		ebx, WORD ptr [esi+26]
     sar		edi, 4
     inc		edi

; 637  : 
; 638  : 				R_BuildLightMap( surf, (void *)temp, smax*4 );

     lea		eax, dword ptr _temp$25953[esp+65564]
     sar		ebx, 4
     lea		edx, dword ptr [edi*4]
     inc		ebx
     push		edx
     push		eax
     push		esi
     call		_R_BuildLightMap
     add		esp, 12					; 0000000cH

; 639  : 				R_SetCacheState( surf );

     push		esi
     FCALL		_R_SetCacheState

; 640  : 
; 641  : 				GL_MBind( GL_TEXTURE1_ARB, gl_state.lightmap_textures + surf->lightmaptexturenum );

     mov		ecx, dword ptr _gl_state+16
     mov		eax, dword ptr [esi+68]
     add		esp, 4
     add		ecx, eax
     push		ecx
     push		33985					; 000084c1H
     FCALL		_GL_MBind

; 642  : 
; 643  : 				lmtex = surf->lightmaptexturenum;

     mov		ebp, dword ptr [esi+68]
     add		esp, 8

; 644  : 
; 645  : 				qglTexSubImage2D( GL_TEXTURE_2D, 0,
; 646  : 								  surf->light_s, surf->light_t, 
; 647  : 								  smax, tmax, 
; 648  : 								  GL_LIGHTMAP_FORMAT, 
; 649  : 								  GL_UNSIGNED_BYTE, temp );
; 650  : 
; 651  : 			}
; 652  : 			else

     jmp		short $L26306
$L25956:

; 653  : 			{
; 654  : 				smax = (surf->extents[0]>>4)+1;

     movsx		edi, WORD ptr [esi+24]

; 655  : 				tmax = (surf->extents[1]>>4)+1;

     movsx		ebx, WORD ptr [esi+26]
     sar		edi, 4
     inc		edi

; 656  : 
; 657  : 				R_BuildLightMap( surf, (void *)temp, smax*4 );

     lea		eax, dword ptr _temp$25953[esp+65564]
     sar		ebx, 4
     lea		edx, dword ptr [edi*4]
     inc		ebx
     push		edx
     push		eax
     push		esi
    call		_R_BuildLightMap

; 658  : 
; 659  : 				GL_MBind( GL_TEXTURE1_ARB, gl_state.lightmap_textures + 0 );

     mov		ecx, dword ptr _gl_state+16
     add		esp, 12					; 0000000cH
     push		ecx
     push		33985					; 000084c1H
     FCALL		_GL_MBind
     add		esp, 8

; 660  : 
; 661  : 				lmtex = 0;

     xor		ebp, ebp
$L26306:

; 662  : 
; 663  : 				qglTexSubImage2D( GL_TEXTURE_2D, 0,
; 664  : 								  surf->light_s, surf->light_t, 
; 665  : 								  smax, tmax, 
; 666  : 								  GL_LIGHTMAP_FORMAT, 
; 667  : 								  GL_UNSIGNED_BYTE, temp );

     mov		eax, dword ptr [esi+32]
     mov		ecx, dword ptr [esi+28]
     lea		edx, dword ptr _temp$25953[esp+65564]
     push		edx
     push		5121					; 00001401H
     push		6408					; 00001908H
     push		ebx
     push		edi
     push		eax
     push		ecx
     push		0
     push		3553					; 00000de1H
     femms
     DCALL	_qglTexSubImage2D,?
     femms

; 668  : 
; 669  : 			}
; 670  : 
; 671  : 			c_brush_polys++;

     mov		edx, dword ptr _c_brush_polys
     inc		edx
     mov		dword ptr _c_brush_polys, edx

; 672  : 
; 673  : 			GL_MBind( GL_TEXTURE0_ARB, image->texnum );

     mov		edx, dword ptr _image$[esp+65564]
     mov		eax, dword ptr [edx+92]
     push		eax
     push		33984					; 000084c0H
     call		_GL_MBind

; 674  : 			GL_MBind( GL_TEXTURE1_ARB, gl_state.lightmap_textures + lmtex );

     mov		ecx, dword ptr _gl_state+16
     add		esp, 8
     add		ebp, ecx
     push		ebp
     push		33985					; 000084c1H
     call		_GL_MBind
     femms
; 675  : 
; 676  : 			for ( p = surf->polys; p; p = p->chain )

     mov		ebx, dword ptr [esi+44]
     add		esp, 8
     test		ebx, ebx
     je		$L25968
$l25959_:

; 677  : 			{
; 678  : 				v = p->verts[0];
; 679  : 				qglBegin (GL_POLYGON);

     push		9
     lea		esi, dword ptr [ebx+16]
     femms
     DCALL	_qglBegin,3
     femms
; 680  : 				for (i=0 ; i< nv; i++, v+= VERTEXSIZE)

     mov		edi, dword ptr _nv$[esp+65564]
     test		edi, edi
     jle		short $L25964
$L25962:
    femms
align	64
$L25962a:

; 681  : 				{
; 682  : 					qglMultiTexCoord2fARB( GL_TEXTURE0_ARB, v[3], v[4]);
; 683  : 					qglMultiTexCoord2fARB( GL_TEXTURE1_ARB, v[5], v[6]);
; 684  : 					qglVertex3fv (v);
; 685  : 				}

     mov		edx, dword ptr [esi+16]
     mov		eax, dword ptr [esi+12]
     push		edx
     push		eax
     push		33984					; 000084c0H

     DCALL	_qglMultiTexCoord2fARB,1
     mov		ecx, dword ptr [esi+24]
     mov		edx, dword ptr [esi+20]
     push		ecx
     push		edx
     push		33985					; 000084c1H

     DCALL	_qglMultiTexCoord2fARB,2
     push		esi

ifdef	DIRECT_API_CALLS


     test	__Amd3Dfx, -1			  ; Set flags.
     jz	UseIndirectCall5
     DCALL	_qglVertex3fv,2
UseIndirectCallRet5:

else
     call		dword ptr _qglVertex3fv
endif
     add		esi, 28					; 0000001cH
     dec		edi
     jne		short $L25962a
$L25964:

; 686  : 				qglEnd ();
     femms
     DCALL	_qglEnd,3
     femms
     mov		ebx, dword ptr [ebx+4]
     test		ebx, ebx
     jne		$l25959_

; 707  : 			}
; 708  : 		}
; 709  : }

     pop		edi
     pop		esi
     pop		ebp
     pop		ebx
     add		esp, 65548				; 0001000cH
     ret		0

UseIndirectCall5:
     call	DWORD PTR _qglVertex3fv            ; qglVertex3fv( p->origin )
     jmp	UseIndirectCallRet5


$L25952:

; 687  : 		}
; 688  : 	}
; 689  : 	else
; 690  : 	{
; 691  : 		c_brush_polys++;

     mov		edx, dword ptr _c_brush_polys
     inc		edx
     mov		dword ptr _c_brush_polys, edx

; 692  : 
; 693  : 			GL_MBind( GL_TEXTURE0_ARB, image->texnum );
; 694  : 			GL_MBind( GL_TEXTURE1_ARB, gl_state.lightmap_textures + lmtex );


     femms
     mov		eax, dword ptr [ebp+92]
     push		eax
     push		33984					; 000084c0H
     call		_GL_MBind
     mov		ecx, dword ptr _gl_state+16
     add		esp, 8
     add		ebx, ecx
     push		ebx
     push		33985					; 000084c1H
     call		_GL_MBind
    femms

; 695  : 
; 696  : 			for ( p = surf->polys; p; p = p->chain )

     mov		ebx, dword ptr [esi+44]
     add		esp, 8
     test		ebx, ebx
     je		short $L25968
$L25966:

; 697  : 			{
; 698  : 				v = p->verts[0];
; 699  : 				qglBegin (GL_POLYGON);

     push		9
     lea		esi, dword ptr [ebx+16]
     femms
     DCALL	_qglBegin,4
     femms

; 700  : 				for (i=0 ; i< nv; i++, v+= VERTEXSIZE)

     mov		edi, dword ptr _nv$[esp+65564]
     test		edi, edi
     jle		short $L25971
align	32
$L25969:
    femms
$L25969a:

; 701  : 				{
; 702  : 					qglMultiTexCoord2fARB( GL_TEXTURE0_ARB, v[3], v[4]);
; 703  : 					qglMultiTexCoord2fARB( GL_TEXTURE1_ARB, v[5], v[6]);
; 704  : 					qglVertex3fv (v);
     mov		edx, dword ptr [esi+16]
     mov		eax, dword ptr [esi+12]
     push		edx
     push		eax
     push		33984					; 000084c0H
     DCALL	_qglMultiTexCoord2fARB,3
     mov		ecx, dword ptr [esi+24]
     mov		edx, dword ptr [esi+20]
     push		ecx
     push		edx
     push		33985					; 000084c1H
     DCALL	_qglMultiTexCoord2fARB,4
     push		esi
ifdef	DIRECT_API_CALLS
     test	__Amd3Dfx, -1			  ; Set flags.
     jz	UseIndirectCall6
     DCALL	_qglVertex3fv,5
UseIndirectCallRet6:
else
     call		dword ptr _qglVertex3fv
endif
     add		esi, 28					; 0000001cH
     dec		edi
     jne		short $L25969
     femms
$L25971:
; 705  : 				}
; 706  : 				qglEnd ();

     femms
     DCALL	_qglEnd,4
     femms
     mov		ebx, dword ptr [ebx+4]
     test		ebx, ebx
     jne		short $L25966
$L25968:

; 707  : 			}
; 708  : 		}
; 709  : }

     pop		edi
     pop		esi
     pop		ebp
     pop		ebx
     add		esp, 65548				; 0001000cH
     ret		0
ifdef	DIRECT_API_CALLS

UseIndirectCall6:
     call	DWORD PTR _qglVertex3fv            ; qglVertex3fv( p->origin )
     jmp	UseIndirectCallRet6


GL_RLP_CvtIndCalls:

     lea	eax, _GL_RenderLightmappedPolyEnd
     lea	edx, _GL_RenderLightmappedPoly
     sub	eax, edx
     push	eax
     push	edx

     call	_Sys_MakeCodeWriteable
     add	esp, 8

     lea	eax, _qglBegin
     lea	edx, D_qglBegin3
     call	ProcAddrWorm

     lea	eax, _qglTexSubImage2D
     lea	edx, D_qglTexSubImage2D?
     call	ProcAddrWorm

     lea	eax, _qglEnd
     lea	edx, D_qglEnd3
     call	ProcAddrWorm

     lea	eax, _qglBegin
     lea	edx, D_qglBegin4
     call	ProcAddrWorm

     lea	eax, _qglEnd
     lea	edx, D_qglEnd4
     call	ProcAddrWorm


     lea	eax, _qglMultiTexCoord2fARB
     lea	edx, D_qglMultiTexCoord2fARB1
     call	ProcAddrWorm

     lea	eax, _qglMultiTexCoord2fARB
     lea	edx, D_qglMultiTexCoord2fARB2
     call	ProcAddrWorm

     lea	eax, _qglVertex3fv
     lea	edx, D_qglVertex3fv2
     call	ProcAddrWorm

     lea	eax, _qglMultiTexCoord2fARB
     lea	edx, D_qglMultiTexCoord2fARB3
     call	ProcAddrWorm

     lea	eax, _qglMultiTexCoord2fARB
     lea	edx, D_qglMultiTexCoord2fARB4
     call	ProcAddrWorm

     lea	eax, _qglVertex3fv
     lea	edx, D_qglVertex3fv5
     call	ProcAddrWorm

     mov	_GL_RLP_InitFlag, -1
     jmp	_GL_RenderLightmappedPoly
endif
_GL_RenderLightmappedPolyEnd	label	byte
_GL_RenderLightmappedPoly ENDP
_TEXT	ENDS

else

PUBLIC	_GL_RenderLightmappedPoly

EXTRN	_GL_MBindImage:NEAR

CONST	SEGMENT
$T51509	DD	040000000r			; 2
$T51510	DD	0bf800000r			; -1
	ORG $+4
$T51512	DD	0bf000000r			; -0.5
CONST	ENDS

;	COMDAT _GL_RenderLightmappedPoly
_TEXT	SEGMENT

_GL_RenderLightmappedPoly PROC NEAR			; COMDAT

; 1198 : {

ifdef	DIRECT_API_CALLS
     test	_GL_RLP_InitFlag, -1
     jz		GL_RLP_CvtIndCalls
endif

	mov	eax, 65612				; 0001004cH
	call	__chkstk
	push	ebx
	push	ebp
	push	esi
	push	edi

; 1199 : 	int		i, nv;
; 1200 : 	int		map;
; 1201 : 	float	*v;
; 1202 :	image_t *image;
; 1203 : 	qboolean is_dynamic = false;
; 1204 : 	unsigned lmtex;
; 1205 : 	glpoly_t *p;

_nv$ = -65600
_image$ = -65544
_is_dynamic$ = -65540
_lmtex$ = -65548
_temp$51220 = -65536
_eye_normal$51228 = -65560
_eye_vert$51229 = -65612
_normal$51230 = -65612
_transform$51231 = -65596
_surf$ = 8

; 1207 :    if (surf->texinfo->flags & SURF_NODRAW)

	mov	edi, DWORD PTR _surf$[esp+65624]
	mov	DWORD PTR _is_dynamic$[esp+65628], 0
	mov	eax, DWORD PTR [edi+56]
	test	BYTE PTR [eax+32], -128			; ffffff80H
	jne	$L51263

; 1208 :       {
; 1209 :       return;
; 1210 :       }
; 1211 : 
; 1212 :    image = R_TextureAnimation( surf->texinfo );

	push	eax
	call	_R_TextureAnimation

; 1213 : 	lmtex = surf->lightmaptexturenum;
; 1214 : 	nv = surf->polys->numverts;

	mov	ecx, DWORD PTR [edi+44]

; 1215 : 
; 1216 : 	for ( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )

	mov	esi, DWORD PTR _r_newrefdef+76
	mov	ebp, eax
	mov	eax, DWORD PTR [edi+68]
	mov	ebx, DWORD PTR [ecx+8]
	add	esp, 4
	mov	DWORD PTR _image$[esp+65628], ebp
	mov	DWORD PTR _lmtex$[esp+65628], eax
	mov	DWORD PTR _nv$[esp+65628], ebx
	xor	ecx, ecx

; 1381 :          }
; 1382 :       }
; 1383 :    //
; 1384 :    // render the splatter map
; 1385 :    //
; 1438 : }

	lea	edx, DWORD PTR [edi+88]
$L51210:
	movzx	eax, BYTE PTR [ecx+edi+72]
	cmp	al, 255					; 000000ffH

	lea	eax, DWORD PTR [eax+eax*2]
	je	SHORT $L51212

	mov	eax, DWORD PTR [esi+eax*8+20]
	cmp	eax, DWORD PTR [edx + ecx*4]
        lea     ecx, [ecx+1]
	jne	SHORT $dynamic$51214

	cmp	ecx, 16					; 00000010H
	jl	SHORT $L51210
$L51212:

; 1217 : 	{
; 1218 : 		if ( r_newrefdef.lightstyles[surf->styles[map]].rgbvalue != surf->cached_light[map] )
; 1219 : 			goto dynamic;
; 1220 : 	}
; 1221 : 
; 1222 : 	// dynamic this frame or dynamic previously
; 1223 : 	if ( ( surf->dlightframe == r_framecount ) )

	mov	edx, DWORD PTR [edi+60]
	mov	eax, DWORD PTR _r_framecount
	cmp	edx, eax
	jne	SHORT $L51514
$dynamic$51214:

; 1224 : 	{
; 1225 : dynamic:
; 1226 : 		if ( gl_dynamic->value )

	mov	eax, DWORD PTR _gl_dynamic
        mov     eax, DWORD PTR [eax+20]
        add     eax, eax
	jz	SHORT $L51514

; 1227 : 		{
; 1228 :        		if ( !(surf->texinfo->flags & (SURF_SKY|SURF_WARP|SURF_WAVY)))

	mov	eax, DWORD PTR [edi+56]
	test	DWORD PTR [eax+32], 1036		; 0000040cH
	jne	SHORT $L51514

; 1229 : 			{
; 1230 :             if (surf->texinfo->surf->translucence == 0)

	mov	edx, DWORD PTR [eax+44]
        mov     eax, DWORD PTR [edx+88]
        add     eax, eax
; 1231 : 				is_dynamic = true;
	mov	eax, 1
	jz	SHORT $L51218

$L51514:
	mov	eax, DWORD PTR _is_dynamic$[esp+65628]
$L51218:

; 1232 : 			}
; 1233 : 		}
; 1234 : 	}
; 1235 : 
; 1236 : 	if ( is_dynamic )

	test	eax, eax
	je	$L51219

; 1237 : 	{
; 1238 : 		unsigned	temp[128*128];
; 1239 : 		int			smax, tmax;
; 1240 : 
; 1241 : 		if ( ( surf->styles[map] >= 32 || surf->styles[map] == 0 ) && ( surf->dlightframe != r_framecount ) )

	mov	cl, BYTE PTR [ecx+edi+72]
	cmp	cl, 32					; 00000020H
	jae	SHORT $L51224
	test	cl, cl
	jne	SHORT $L51223
$L51224:
	mov	eax, DWORD PTR _r_framecount
	mov	ecx, DWORD PTR [edi+60]
	cmp	ecx, eax
	je	SHORT $L51223

; 1242 : 		{
; 1243 : 			smax = (surf->extents[0]>>4)+1;

	movsx	esi, WORD PTR [edi+24]

; 1244 : 			tmax = (surf->extents[1]>>4)+1;

	movsx	ebx, WORD PTR [edi+26]
	sar	esi, 4
	inc	esi

; 1245 : 
; 1246 : 			R_BuildLightMap( surf, (void *)temp, smax*4 );

	lea	edx, DWORD PTR _temp$51220[esp+65628]
	sar	ebx, 4
	lea	ecx, DWORD PTR [esi*4]
	inc	ebx
	push	ecx
	push	edx
	push	edi
	call	_R_BuildLightMap
	add	esp, 12					; 0000000cH

; 1247 : 			R_SetCacheState( surf );

	push	edi
	call	_R_SetCacheState

; 1248 : 
; 1249 : 			GL_MBind( GL_TEXTURE1_ARB, gl_state.lightmap_textures + surf->lightmaptexturenum );

	mov	eax, DWORD PTR _gl_state+16
	mov	ecx, DWORD PTR [edi+68]
	add	esp, 4
	add	eax, ecx
	push	eax
	push	33985					; 000084c1H
	call	_GL_MBind

; 1250 : 
; 1251 : 			lmtex = surf->lightmaptexturenum;

	mov	ebp, DWORD PTR [edi+68]
	add	esp, 8

; 1252 : 
; 1253 : 			qglTexSubImage2D( GL_TEXTURE_2D, 0,
; 1254 : 							  surf->light_s, surf->light_t,
; 1255 : 							  smax, tmax,
; 1256 : 							  GL_LIGHTMAP_FORMAT,
; 1257 : 							  GL_UNSIGNED_BYTE, temp );
; 1258 : 
; 1259 : 		}
; 1260 : 		else

	jmp	SHORT $L51516
$L51223:

; 1261 : 		{
; 1262 : 			smax = (surf->extents[0]>>4)+1;

	movsx	esi, WORD PTR [edi+24]

; 1263 : 			tmax = (surf->extents[1]>>4)+1;

	movsx	ebx, WORD PTR [edi+26]
	sar	esi, 4
	inc	esi

; 1264 : 
; 1265 : 			R_BuildLightMap( surf, (void *)temp, smax*4 );

	lea	edx, DWORD PTR _temp$51220[esp+65628]
	sar	ebx, 4
	lea	ecx, DWORD PTR [esi*4]
	inc	ebx

	push	ecx
	push	edx
	push	edi
	call	_R_BuildLightMap

; 1266 : 
; 1267 : 			GL_MBind( GL_TEXTURE1_ARB, gl_state.lightmap_textures + 0 );

	mov	eax, DWORD PTR _gl_state+16
	add	esp, 12					; 0000000cH
	push	eax
	push	33985					; 000084c1H

	call	_GL_MBind
	add	esp, 8

; 1268 : 
; 1269 : 			lmtex = 0;

	xor	ebp, ebp
$L51516:

; 1270 : 
; 1271 : 			qglTexSubImage2D( GL_TEXTURE_2D, 0,
; 1272 : 							  surf->light_s, surf->light_t,
; 1273 : 							  smax, tmax,
; 1274 : 							  GL_LIGHTMAP_FORMAT,
; 1275 : 							  GL_UNSIGNED_BYTE, temp );

	mov	edx, DWORD PTR [edi+32]
	mov	eax, DWORD PTR [edi+28]
	lea	ecx, DWORD PTR _temp$51220[esp+65628]
	push	ecx
	push	5121					; 00001401H
	push	6408					; 00001908H
	push	ebx
	push	esi
	push	edx
	push	eax
	push	0
	push	3553					; 00000de1H
	call	DWORD PTR _qglTexSubImage2D

; 1276 : 
; 1277 : 		}
; 1278 : 
; 1279 : 		c_brush_polys++;

	mov	ecx, DWORD PTR _c_brush_polys
	inc	ecx
	mov	DWORD PTR _c_brush_polys, ecx

; 1280 : 
; 1281 : 		GL_MBindImage( GL_TEXTURE0_ARB, image );

	mov	ecx, DWORD PTR _image$[esp+65628]
	push	ecx
	push	33984					; 000084c0H
	call	_GL_MBindImage

; 1282 : 		GL_MBind( GL_TEXTURE1_ARB, gl_state.lightmap_textures + lmtex );

	mov	edx, DWORD PTR _gl_state+16
	add	esp, 8
	add	ebp, edx
	push	ebp
	push	33985					; 000084c1H
	call	_GL_MBind

; 1283 : 	}
; 1284 : 	else

	mov	ebx, DWORD PTR _nv$[esp+65636]
	add	esp, 8
	jmp	SHORT $L51226
$L51219:

; 1285 : 	{
; 1286 : 		c_brush_polys++;

	mov	ecx, DWORD PTR _c_brush_polys

; 1287 : 
; 1288 : 		GL_MBindImage( GL_TEXTURE0_ARB, image );

	push	ebp
	inc	ecx
	push	33984					; 000084c0H
	mov	DWORD PTR _c_brush_polys, ecx
	call	_GL_MBindImage

; 1289 : 		GL_MBind( GL_TEXTURE1_ARB, gl_state.lightmap_textures + lmtex );

	mov	eax, DWORD PTR _gl_state+16
	mov	ecx, DWORD PTR _lmtex$[esp+65636]
	add	esp, 8
	add	ecx, eax
	push	ecx
	push	33985					; 000084c1H
	call	_GL_MBind
	add	esp, 8
$L51226:

; 1290 : 	}
; 1291 :    if (surf->texinfo->flags & SURF_ENVMAPPED)

	mov	edx, DWORD PTR [edi+56]
	mov	eax, DWORD PTR [edx+32]
	test	eax, 2097152				; 00200000H
	je	$L51227

; 1292 :       {
; 1293 :       vec3_t eye_normal;
; 1294 :       vec3_t eye_vert;
; 1295 :       vec3_t normal;
; 1296 :       vec3_t transform[3];
; 1297 :       float two_nu, m, fx, fy, fz;
; 1298 : 
; 1299 :       if ( surf->flags & SURF_PLANEBACK )

	test	BYTE PTR [edi+8], 2

; 1300 :          VectorNegate(surf->plane->normal, normal);

	mov	eax, DWORD PTR [edi+4]
	je	SHORT $L51237

        mov     ecx, [eax]
        nop

        xor     ecx, 80000000h
        mov     edx, [eax+4]

        mov     DWORD PTR _normal$51230[esp+65628], ecx
        mov     ecx, [eax+8]

        xor     edx, 80000000h
        mov     DWORD PTR _normal$51230[esp+65632], edx

        xor     ecx, 80000000h
        mov     DWORD PTR _normal$51230[esp+65636], ecx

; 1301 :       else

	jmp	SHORT $L51238
$L51237:

; 1302 :          VectorCopy(surf->plane->normal, normal);

	mov	ecx, DWORD PTR [eax]
	mov	DWORD PTR _normal$51230[esp+65628], ecx
	mov	edx, DWORD PTR [eax+4]
	mov	DWORD PTR _normal$51230[esp+65632], edx
	mov	ecx, DWORD PTR [eax+8]
	mov	DWORD PTR _normal$51230[esp+65636], ecx
$L51238:

; 1303 : 
; 1304 : 	   VectorCopy (vright, transform[0]);
; 1305 : 	   VectorNegate (vup, transform[1]);

	fld	DWORD PTR _vup
	fld	DWORD PTR _vup+4

; 1306 : 	   VectorCopy (vpn, transform[2]);

	fld	DWORD PTR _vup+8

; 1379 :          {
; 1380 :          qglDisable( GL_BLEND );

	fxch	ST(2)
	fchs
	fxch	ST(1)
	fchs
	mov	ecx, DWORD PTR _vright
	mov	edx, DWORD PTR _vright+4
	mov	DWORD PTR _transform$51231[esp+65628], ecx
	mov	eax, DWORD PTR _vpn
	fld	DWORD PTR _transform$51231[esp+65628]
	fxch	ST(2)
	fstp	DWORD PTR _transform$51231[esp+65640]
	mov	DWORD PTR _transform$51231[esp+65632], edx
	mov	DWORD PTR _transform$51231[esp+65652], eax
	fld	DWORD PTR _transform$51231[esp+65632]
	fxch	ST(1)
	fstp	DWORD PTR _transform$51231[esp+65644]
	fld	DWORD PTR _transform$51231[esp+65640]
	fld	DWORD PTR _transform$51231[esp+65644]
	fld	DWORD PTR _transform$51231[esp+65652]
	fxch	ST(4)
	fmul	DWORD PTR _normal$51230[esp+65628]
	fxch	ST(5)
	fchs
	fxch	ST(3)
	fmul	DWORD PTR _normal$51230[esp+65632]
	mov	ecx, DWORD PTR _vpn+4
	mov	edx, DWORD PTR _vright+8
	mov	DWORD PTR _transform$51231[esp+65656], ecx
	mov	DWORD PTR _transform$51231[esp+65636], edx
	fld	DWORD PTR _transform$51231[esp+65656]
	fxch	ST(3)
	fmul	DWORD PTR _normal$51230[esp+65628]
	fxch	ST(4)
	fstp	DWORD PTR _transform$51231[esp+65648]
	fxch	ST(1)
	fmul	DWORD PTR _normal$51230[esp+65632]
	fld	DWORD PTR _transform$51231[esp+65636]
	fxch	ST(5)
	fmul	DWORD PTR _normal$51230[esp+65628]
	fxch	ST(3)
	fmul	DWORD PTR _normal$51230[esp+65632]
	fld	DWORD PTR _transform$51231[esp+65648]
	fxch	ST(6)
	fmul	DWORD PTR _normal$51230[esp+65636]
	fxch	ST(3)
	faddp	ST(7), ST(0)
	mov	eax, DWORD PTR _vpn+8
	mov	edi, DWORD PTR [edi+44]
	mov	DWORD PTR _transform$51231[esp+65660], eax
	fld	DWORD PTR _transform$51231[esp+65660]
	fxch	ST(6)
	fmul	DWORD PTR _normal$51230[esp+65636]
	fxch	ST(2)
	faddp	ST(5), ST(0)
	fxch	ST(5)
	fmul	DWORD PTR _normal$51230[esp+65636]
	fxch	ST(5)
	faddp	ST(3), ST(0)
	fxch	ST(1)
	faddp	ST(5), ST(0)
	test	edi, edi
	faddp	ST(2), ST(0)
	fxch	ST(2)
	faddp	ST(2), ST(0)
	fxch	ST(2)
	fstp	DWORD PTR _eye_normal$51228[esp+65628]
	fxch	ST(1)
	fstp	DWORD PTR _eye_normal$51228[esp+65632]
	fstp	DWORD PTR _eye_normal$51228[esp+65636]
	je	$L51263
$L51239:

; 1307 : 
; 1308 : 		eye_normal[0] = DotProduct(normal, transform[0]);
; 1309 : 		eye_normal[1] = DotProduct(normal, transform[1]);
; 1310 : 		eye_normal[2] = DotProduct(normal, transform[2]);
; 1311 : 
; 1312 : 	   for ( p = surf->polys; p; p = p->chain )
; 1313 : 	      {
; 1314 :          qglBegin (GL_POLYGON);

	push	9
	call	DWORD PTR _qglBegin

; 1315 :          v = p->verts[0];
; 1316 :          for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)

	mov	eax, DWORD PTR [edi+8]
	xor	ebx, ebx
	test	eax, eax
	lea	esi, DWORD PTR [edi+16]
	jle	$L51244
$L51242:

; 1317 :             {
; 1318 : 		      eye_vert[0] = DotProduct(v, transform[0]) - r_origin[0];

	fld	DWORD PTR _transform$51231[esp+65636]
	fld	DWORD PTR _transform$51231[esp+65632]
	fmul	DWORD PTR [esi+4]
	fld	DWORD PTR [esi]

; 1379 :          {
; 1380 :          qglDisable( GL_BLEND );

	fxch	ST(2)
	fmul	DWORD PTR [esi+8]
	fld	DWORD PTR _transform$51231[esp+65644]
	fxch	ST(3)
	fmul	DWORD PTR _transform$51231[esp+65628]
	fxch	ST(1)
	faddp	ST(2), ST(0)
	fld	DWORD PTR _transform$51231[esp+65648]
	fld	DWORD PTR _transform$51231[esp+65656]
	fxch	ST(2)
	faddp	ST(3), ST(0)
	fld	DWORD PTR _transform$51231[esp+65660]
	fxch	ST(3)
	fsub	DWORD PTR _r_origin
	lea	ecx, DWORD PTR _eye_vert$51229[esp+65628]
	push	ecx
	fstp	DWORD PTR _eye_vert$51229[esp+65632]
	fxch	ST(3)
	fmul	DWORD PTR [esi+4]
	fld	DWORD PTR [esi]
	fxch	ST(4)
	fmul	DWORD PTR [esi+8]
	fxch	ST(4)
	fmul	DWORD PTR _transform$51231[esp+65644]
	fxch	ST(4)
	faddp	ST(1), ST(0)
	fxch	ST(3)
	faddp	ST(3), ST(0)
	fxch	ST(2)
	fsub	DWORD PTR _r_origin+4
	fstp	DWORD PTR _eye_vert$51229[esp+65636]
	fxch	ST(1)
	fmul	DWORD PTR [esi+4]
	fld	DWORD PTR [esi]
	fxch	ST(2)
	fmul	DWORD PTR [esi+8]
	fxch	ST(2)
	fmul	DWORD PTR _transform$51231[esp+65656]
	fxch	ST(2)
	faddp	ST(1), ST(0)
	fxch	ST(1)
	faddp	ST(1), ST(0)
	fsub	DWORD PTR _r_origin+8
	fstp	DWORD PTR _eye_vert$51229[esp+65640]
	call	_VectorNormalize
	fld	DWORD PTR _eye_vert$51229[esp+65636]
	fld	DWORD PTR _eye_vert$51229[esp+65632]
	fmul	DWORD PTR _eye_normal$51228[esp+65632]
	fld	DWORD PTR _eye_vert$51229[esp+65640]
	fxch	ST(2)
	fmul	DWORD PTR _eye_normal$51228[esp+65636]
	fxch	ST(3)
	fstp	ST(0)
	fxch	ST(1)
	fmul	DWORD PTR _eye_normal$51228[esp+65640]
	fxch	ST(2)
	faddp	ST(1), ST(0)
	fxch	ST(1)
	add	esp, 4
	faddp	ST(1), ST(0)
	fadd	ST(0), ST(0)
	fld	ST(0)
	fmul	DWORD PTR _eye_normal$51228[esp+65636]
	fld	ST(1)
	fmul	DWORD PTR _eye_normal$51228[esp+65628]
	fxch	ST(1)
	fsubr	DWORD PTR _eye_vert$51229[esp+65636]
	fxch	ST(1)
	fsubr	DWORD PTR _eye_vert$51229[esp+65628]
	fxch	ST(1)
	fxch	ST(2)
	fxch	ST(1)
	fxch	ST(2)
	fsub	DWORD PTR $T51510
	fxch	ST(1)
	fmul	DWORD PTR _eye_normal$51228[esp+65632]
	fld	ST(2)
	fxch	ST(1)
	fsubr	DWORD PTR _eye_vert$51229[esp+65632]
	fxch	ST(2)
	fst	DWORD PTR -65600+[esp+65628]
	fmul	DWORD PTR -65600+[esp+65628]
	fxch	ST(1)
	fmul	ST(0), ST(3)
	fld	ST(2)
	fmul	ST(0), ST(3)
	fxch	ST(1)
	faddp	ST(2), ST(0)
	faddp	ST(1), ST(0)
	fsqrt
	fadd	ST(0), ST(0)
	fcom	DWORD PTR $T26233
	fnstsw	ax
	test	ah, 64					; 00000040H
	je	SHORT $L51245
	fstp	ST(0)
	push	1056964608				; 3f000000H
	push	1056964608				; 3f000000H
	fstp	ST(0)
	push	33984					; 000084c0H
	fstp	ST(0)
	call	DWORD PTR _qglMultiTexCoord2fARB
	mov	edx, DWORD PTR [esi+24]
	mov	eax, DWORD PTR [esi+20]
	push	edx
	push	eax
	jmp	SHORT $L51517
$L51245:

; 1319 : 		      eye_vert[1] = DotProduct(v, transform[1]) - r_origin[1];
; 1320 : 		      eye_vert[2] = DotProduct(v, transform[2]) - r_origin[2];
; 1321 :             VectorNormalize( eye_vert );
; 1322 :             two_nu = 2.0f * DotProduct( eye_normal, eye_vert );
; 1323 :             fx = eye_vert[0] - eye_normal[0] * two_nu;
; 1324 :             fy = eye_vert[1] - eye_normal[1] * two_nu;
; 1325 :             fz = eye_vert[2] - eye_normal[2] * two_nu;
; 1326 :             m = 2.0F * sqrt( fx*fx + fy*fy + (fz+1.0F)*(fz+1.0F) );
; 1327 :             if (m==0.0F)
; 1328 :                {
; 1329 : 		         qglMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.5f, 0.5f);
; 1330 :                qglMultiTexCoord2fARB( GL_TEXTURE1_ARB, v[5], v[6]);
; 1331 :                }
; 1332 :             else
; 1333 :                {
; 1334 :                float mInv = 1.0F / m;

	fdivr	DWORD PTR FloatOne

; 1335 : 		         qglMultiTexCoord2fARB( GL_TEXTURE0_ARB, fx * mInv + 0.5f, fy * mInv + 0.5F);

	push	ecx
	fld	ST(0)
	fmul	ST(0), ST(2)
	fxch	ST(1)
	fmul	ST(0), ST(3)
	fxch	ST(1)
	fsub	DWORD PTR $T51512
	fxch	ST(1)
	fsub	DWORD PTR $T51512
	fxch	ST(1)
	fstp	DWORD PTR [esp]
	push	ecx
	fstp	DWORD PTR [esp]
	push	33984					; 000084c0H
	fstp	ST(0)
	fstp	ST(0)
	call	DWORD PTR _qglMultiTexCoord2fARB

; 1336 :                qglMultiTexCoord2fARB( GL_TEXTURE1_ARB, v[5], v[6]);

	mov	ecx, DWORD PTR [esi+24]
	mov	edx, DWORD PTR [esi+20]
	push	ecx
	push	edx
$L51517:
	push	33985					; 000084c1H
	call	DWORD PTR _qglMultiTexCoord2fARB

; 1337 :                }
; 1338 :             qglVertex3fv (v);

	push	esi
	call	DWORD PTR _qglVertex3fv
	mov	eax, DWORD PTR [edi+8]
	inc	ebx
	add	esi, 28					; 0000001cH
	cmp	ebx, eax
	jl	$L51242
$L51244:

; 1339 :             }
; 1340 :          qglEnd ();

	call	DWORD PTR _qglEnd
	mov	edi, DWORD PTR [edi+4]
	test	edi, edi
	jne	$L51239

; 1381 :          }
; 1382 :       }
; 1383 :    //
; 1384 :    // render the splatter map
; 1385 :    //
; 1386 : /*
; 1387 :    if ( surf->splatter_surface )
; 1388 :       {
; 1389 :       splatter_t * splatter;
; 1390 :       glpoly_t * p;
; 1391 : 
; 1392 :    	GL_EnableMultitexture( false );
; 1393 :    	// don't bother writing Z
; 1394 : 	   qglDepthMask( 0 );
; 1395 :    	qglDepthFunc (GL_EQUAL);
; 1396 : 		qglEnable (GL_BLEND);
; 1397 : 	   qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
; 1398 : 
; 1399 :       splatter = surf->splatter_surface;
; 1400 : 		GL_Bind( gl_state.splatter_textures + splatter->texture_num );
; 1401 :       p = surf->polys;
; 1402 : 		for ( ; p != 0; p = p->chain )
; 1403 : 		   {
; 1404 : 			float *v;
; 1405 : 			int j;
; 1406 : 
; 1407 : 			qglBegin (GL_POLYGON);
; 1408 : 			v = p->verts[0];
; 1409 : 			for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
; 1410 : 			   {
; 1411 : 				qglTexCoord2f( v[7] * splatter->s_mult, v[8] * splatter->t_mult );
; 1412 : 				qglVertex3fv (v);
; 1413 : 			   }
; 1414 : 			qglEnd ();
; 1415 :          }
; 1416 : 	   qglDisable (GL_BLEND);
; 1417 : 	   if (gl_ztrick->value)
; 1418 :    	   {
; 1419 : 		   if (ztrickframe & 1)
; 1420 :    		   {
; 1421 : 			   qglDepthFunc (GL_LEQUAL);
; 1422 :    		   }
; 1423 : 		   else
; 1424 : 	   	   {
; 1425 : 			   qglDepthFunc (GL_GEQUAL);
; 1426 : 		      }
; 1427 :          }
; 1428 :       else
; 1429 :          qglDepthFunc (GL_LEQUAL);
; 1430 :    	qglDepthMask( 1 );
; 1431 :    	GL_EnableMultitexture( true );
; 1432 : 	   GL_SelectTexture( GL_TEXTURE0_ARB );
; 1433 : 	   GL_TexEnv( GL_REPLACE );
; 1434 : 	   GL_SelectTexture( GL_TEXTURE1_ARB );
; 1435 : 	   GL_TexEnv( GL_MODULATE );
; 1436 :       }
; 1437 : */
; 1438 : }

	pop	edi
	pop	esi
	pop	ebp
	pop	ebx
	add	esp, 65612				; 0001004cH
	ret	0
$L51227:

; 1341 :          }
; 1342 :       }
; 1343 :    else if (surf->texinfo->flags & SURF_MASKED)

	test	al, 2
	je	$L51249

; 1344 :       {
; 1345 :       //
; 1346 :       // masked but lit
; 1347 :       // non-lit goes to RenderBrushPoly
; 1348 :       //
; 1349 :       qglEnable(GL_ALPHA_TEST);

	push	3008					; 00000bc0H
	call	DWORD PTR _qglEnable

; 1350 : 	   for ( p = surf->polys; p; p = p->chain )

	mov	ebp, DWORD PTR [edi+44]
	test	ebp, ebp
	je	SHORT $L51252
$L51250:

; 1351 : 	      {
; 1352 : 		   v = p->verts[0];
; 1353 : 		   qglBegin (GL_POLYGON);

	push	9
	lea	esi, DWORD PTR [ebp+16]
	call	DWORD PTR _qglBegin

; 1354 : 		   for (i=0 ; i< nv; i++, v+= VERTEXSIZE)

	mov	ebx, DWORD PTR _nv$[esp+65628]
	test	ebx, ebx
	jle	SHORT $L51255
$L51253:

; 1355 : 		      {
; 1356 : 		      qglMultiTexCoord2fARB( GL_TEXTURE0_ARB, v[3] + surf->texinfo->surf->delta_s, v[4] + surf->texinfo->surf->delta_t);

        femms

	mov	eax, DWORD PTR [edi+56]

        movq    mm0, qword ptr [esi+12]

        movq    mm1, qword ptr [eax+144]

        sub     esp, 8
        pfadd   mm1, mm0

        movq    qword ptr [esp], mm1

        femms

	push	33984					; 000084c0H
;	call	DWORD PTR _qglMultiTexCoord2fARB
	DCALL	 _qglMultiTexCoord2fARB,c3


; 1357 :             qglMultiTexCoord2fARB( GL_TEXTURE1_ARB, v[5], v[6]);

	mov	ecx, DWORD PTR [esi+24]
	mov	edx, DWORD PTR [esi+20]
	push	ecx
	push	edx
	push	33985					; 000084c1H
;	call	DWORD PTR _qglMultiTexCoord2fARB
	DCALL	 _qglMultiTexCoord2fARB,c4

; 1358 : 		      qglVertex3fv (v);

	push	esi
	call	DWORD PTR _qglVertex3fv
	add	esi, 28					; 0000001cH
	dec	ebx
	jne	SHORT $L51253
$L51255:

; 1359 : 		      }
; 1360 :          qglEnd ();

	call	DWORD PTR _qglEnd
	mov	ebp, DWORD PTR [ebp+4]
	test	ebp, ebp
	jne	SHORT $L51250
$L51252:

; 1361 : 	      }
; 1362 :       qglDisable (GL_ALPHA_TEST);

	push	3008					; 00000bc0H

; 1379 :          {
; 1380 :          qglDisable( GL_BLEND );

	call	DWORD PTR _qglDisable

; 1381 :          }
; 1382 :       }
; 1383 :    //
; 1384 :    // render the splatter map
; 1385 :    //
; 1386 : /*
; 1387 :    if ( surf->splatter_surface )
; 1388 :       {
; 1389 :       splatter_t * splatter;
; 1390 :       glpoly_t * p;
; 1391 : 
; 1392 :    	GL_EnableMultitexture( false );
; 1393 :    	// don't bother writing Z
; 1394 : 	   qglDepthMask( 0 );
; 1395 :    	qglDepthFunc (GL_EQUAL);
; 1396 : 		qglEnable (GL_BLEND);
; 1397 : 	   qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
; 1398 : 
; 1399 :       splatter = surf->splatter_surface;
; 1400 : 		GL_Bind( gl_state.splatter_textures + splatter->texture_num );
; 1401 :       p = surf->polys;
; 1402 : 		for ( ; p != 0; p = p->chain )
; 1403 : 		   {
; 1404 : 			float *v;
; 1405 : 			int j;
; 1406 : 
; 1407 : 			qglBegin (GL_POLYGON);
; 1408 : 			v = p->verts[0];
; 1409 : 			for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
; 1410 : 			   {
; 1411 : 				qglTexCoord2f( v[7] * splatter->s_mult, v[8] * splatter->t_mult );
; 1412 : 				qglVertex3fv (v);
; 1413 : 			   }
; 1414 : 			qglEnd ();
; 1415 :          }
; 1416 : 	   qglDisable (GL_BLEND);
; 1417 : 	   if (gl_ztrick->value)
; 1418 :    	   {
; 1419 : 		   if (ztrickframe & 1)
; 1420 :    		   {
; 1421 : 			   qglDepthFunc (GL_LEQUAL);
; 1422 :    		   }
; 1423 : 		   else
; 1424 : 	   	   {
; 1425 : 			   qglDepthFunc (GL_GEQUAL);
; 1426 : 		      }
; 1427 :          }
; 1428 :       else
; 1429 :          qglDepthFunc (GL_LEQUAL);
; 1430 :    	qglDepthMask( 1 );
; 1431 :    	GL_EnableMultitexture( true );
; 1432 : 	   GL_SelectTexture( GL_TEXTURE0_ARB );
; 1433 : 	   GL_TexEnv( GL_REPLACE );
; 1434 : 	   GL_SelectTexture( GL_TEXTURE1_ARB );
; 1435 : 	   GL_TexEnv( GL_MODULATE );
; 1436 :       }
; 1437 : */
; 1438 : }

	pop	edi
	pop	esi
	pop	ebp
	pop	ebx
	add	esp, 65612				; 0001004cH
	ret	0
$L51249:

; 1363 :       }
; 1364 :    else
; 1365 :       {     
; 1366 :       for ( p = surf->polys; p; p = p->chain )

	mov	ebp, DWORD PTR [edi+44]
	test	ebp, ebp
	je	SHORT $L51259
$L51257:

; 1367 : 	      {
; 1368 : 		   v = p->verts[0];
; 1369 : 		   qglBegin (GL_POLYGON);

	push	9
	lea	esi, DWORD PTR [ebp+16]
	call	DWORD PTR _qglBegin

; 1370 : 		   for (i=0 ; i< nv; i++, v+= VERTEXSIZE)

	test	ebx, ebx
	jle	SHORT $L51262
$L51260:

; 1371 : 		      {
; 1372 :             qglMultiTexCoord2fARB( GL_TEXTURE0_ARB, v[3] + surf->texinfo->surf->delta_s, v[4] + surf->texinfo->surf->delta_t);

        femms

	mov	eax, DWORD PTR [edi+56]

        movq    mm0, qword ptr [esi+12]

        movq    mm1, qword ptr [eax+144]

        sub     esp, 8
        pfadd   mm1, mm0

        movq    qword ptr [esp], mm1

        femms

	push	33984					; 000084c0H
;	call	DWORD PTR _qglMultiTexCoord2fARB
	DCALL	 _qglMultiTexCoord2fARB,c1

; 1373 :             qglMultiTexCoord2fARB( GL_TEXTURE1_ARB, v[5], v[6]);

	mov	ecx, DWORD PTR [esi+24]
	mov	edx, DWORD PTR [esi+20]
	push	ecx
	push	edx
	push	33985					; 000084c1H
;	call	DWORD PTR _qglMultiTexCoord2fARB
	DCALL	_qglMultiTexCoord2fARB,c2

; 1374 : 		      qglVertex3fv (v);

	push	esi
	call	DWORD PTR _qglVertex3fv
	add	esi, 28					; 0000001cH
	dec	ebx
	jne	SHORT $L51260

; 1370 : 		   for (i=0 ; i< nv; i++, v+= VERTEXSIZE)

	mov	ebx, DWORD PTR _nv$[esp+65628]
$L51262:

; 1375 : 		      }
; 1376 :          qglEnd ();

	call	DWORD PTR _qglEnd
	mov	ebp, DWORD PTR [ebp+4]
	test	ebp, ebp
	jne	SHORT $L51257
$L51259:

; 1377 : 	      }
; 1378 :       if ( ( surf->texinfo->flags & SURF_USECOLOR ) && ( surf->texinfo->flags & SURF_HARDWAREONLY ) )

	mov	eax, DWORD PTR [edi+56]
	mov	eax, DWORD PTR [eax+32]
	test	ah, -128				; ffffff80H
	je	SHORT $L51263
	test	eax, 65536				; 00010000H
	je	SHORT $L51263

; 1379 :          {
; 1380 :          qglDisable( GL_BLEND );

	push	3042					; 00000be2H
	call	DWORD PTR _qglDisable
$L51263:

; 1381 :          }
; 1382 :       }
; 1383 :    //
; 1384 :    // render the splatter map
; 1385 :    //
; 1386 : /*
; 1387 :    if ( surf->splatter_surface )
; 1388 :       {
; 1389 :       splatter_t * splatter;
; 1390 :       glpoly_t * p;
; 1391 : 
; 1392 :    	GL_EnableMultitexture( false );
; 1393 :    	// don't bother writing Z
; 1394 : 	   qglDepthMask( 0 );
; 1395 :    	qglDepthFunc (GL_EQUAL);
; 1396 : 		qglEnable (GL_BLEND);
; 1397 : 	   qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
; 1398 : 
; 1399 :       splatter = surf->splatter_surface;
; 1400 : 		GL_Bind( gl_state.splatter_textures + splatter->texture_num );
; 1401 :       p = surf->polys;
; 1402 : 		for ( ; p != 0; p = p->chain )
; 1403 : 		   {
; 1404 : 			float *v;
; 1405 : 			int j;
; 1406 : 
; 1407 : 			qglBegin (GL_POLYGON);
; 1408 : 			v = p->verts[0];
; 1409 : 			for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
; 1410 : 			   {
; 1411 : 				qglTexCoord2f( v[7] * splatter->s_mult, v[8] * splatter->t_mult );
; 1412 : 				qglVertex3fv (v);
; 1413 : 			   }
; 1414 : 			qglEnd ();
; 1415 :          }
; 1416 : 	   qglDisable (GL_BLEND);
; 1417 : 	   if (gl_ztrick->value)
; 1418 :    	   {
; 1419 : 		   if (ztrickframe & 1)
; 1420 :    		   {
; 1421 : 			   qglDepthFunc (GL_LEQUAL);
; 1422 :    		   }
; 1423 : 		   else
; 1424 : 	   	   {
; 1425 : 			   qglDepthFunc (GL_GEQUAL);
; 1426 : 		      }
; 1427 :          }
; 1428 :       else
; 1429 :          qglDepthFunc (GL_LEQUAL);
; 1430 :    	qglDepthMask( 1 );
; 1431 :    	GL_EnableMultitexture( true );
; 1432 : 	   GL_SelectTexture( GL_TEXTURE0_ARB );
; 1433 : 	   GL_TexEnv( GL_REPLACE );
; 1434 : 	   GL_SelectTexture( GL_TEXTURE1_ARB );
; 1435 : 	   GL_TexEnv( GL_MODULATE );
; 1436 :       }
; 1437 : */
; 1438 : }

	pop	edi
	pop	esi
	pop	ebp
	pop	ebx
	add	esp, 65612				; 0001004cH
	ret	0


ifdef	DIRECT_API_CALLS

GL_RLP_CvtIndCalls:

     lea	eax, _GL_RenderLightmappedPolyEnd
     lea	edx, _GL_RenderLightmappedPoly
     sub	eax, edx
     push	eax
     push	edx

     call	_Sys_MakeCodeWriteable
     add	esp, 8

     lea	eax, _qglMultiTexCoord2fARB
     lea	edx, D_qglMultiTexCoord2fARBc1
     call	ProcAddrWorm

     lea	eax, _qglMultiTexCoord2fARB
     lea	edx, D_qglMultiTexCoord2fARBc2
     call	ProcAddrWorm

     lea	eax, _qglMultiTexCoord2fARB
     lea	edx, D_qglMultiTexCoord2fARBc3
     call	ProcAddrWorm

     lea	eax, _qglMultiTexCoord2fARB
     lea	edx, D_qglMultiTexCoord2fARBc4
     call	ProcAddrWorm

     mov	_GL_RLP_InitFlag, -1
     jmp	_GL_RenderLightmappedPoly

endif
_GL_RenderLightmappedPolyEnd	label	byte
_GL_RenderLightmappedPoly ENDP
_TEXT	ENDS

endif

_TEXT	SEGMENT
_in$ = 8
_scale$ = 12
_out$ = 16
align	32
; void VectorScale ( in, scale, out );
_VectorScale PROC NEAR					; COMDAT

; 531  : 	out[0] = in[0]*scale;
; 532  : 	out[1] = in[1]*scale;
; 533  : 	out[2] = in[2]*scale;

     mov		eax, _in$[esp-4] 
     movd		mm2, _scale$[esp-4]

     movd		mm1, [eax+8]
     movq		mm0, [eax]

     pfmul		mm1, mm2
     mov		ecx, _out$[esp-4]

     punpckldq	mm2, mm2
     movd		[ecx+8], mm1

     pfmul		mm0, mm2
     movq		[ecx], mm0

     ret	0

_VectorScale ENDP
_TEXT	ENDS

EXTRN	_r_worldmodel:DWORD

CONST	SEGMENT
$T26056		dd	042800000r			; 64
DlightCutoff	dq      42800000C2800000h		; -64 | 64
SignBitHigh	dq	8000000000000000h
CONST	ENDS

_TEXT	SEGMENT
_light$ = 8
_bit$ = 12
_node$ = 16

align 32
_R_AuxMarkLights PROC NEAR				; COMDAT
; void R_MarkLights (dlight_t *light, int bit, mnode_t *node)

; 100  : {
     push	esi

; 101  : 	cplane_t	*splitplane;
; 102  : 	float		dist;
; 103  : 	msurface_t	*surf;
; 104  : 	int			i;
; 105  : 	
; 106  : 	if (node->contents != -1)

     mov	esi, DWORD PTR _node$[esp]
     femms
     cmp	DWORD PTR [esi], -1
     jne	$L26053
     push	edi

; 107  : 		return;
; 108  : 
; 109  : 	splitplane = node->plane;
; 111  : 	

     mov	edi, DWORD PTR _bit$[esp+4]
     push	ebp
     push	ebx
     mov	ebx, DWORD PTR _light$[esp+12]
;typedef struct cplane_s
;{
;	vec3_t	normal;
;	float	dist;
;	byte	type;			// for fast side tests
;	byte	signbits;		// signx + (signy<<1) + (signz<<1)
;	byte	pad[2];
;} cplane_t;
;typedef struct
;{
;	vec3_t	origin;
;	vec3_t	color;
;	float	intensity;
;} dlight_t;
; dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>
align	32
$L26049:
     mov	eax, DWORD PTR [esi+36]		; eax = splitplane
; ebx 	 = light->origin[0]
; eax 	 = splitplane->normal[0]
; eax+12 = splitplane->dist
     movq		mm0, [ebx]		; mm0 = origin[1] | origin[0]
     movd		mm1, [ebx+8]		; mm1 = 0 | origin [2]

     movq		mm2, [eax]		; mm2 = normal[1] | normal[0]
     movd		mm3, [eax+8]		; mm3 = 0 | normal[2]

     movd		mm4, [eax+12]		; mm4 = 0 | splitplane->dist
     movd		mm5, [ebx+24]		; mm5 = 0 | intensity

     pfmul		mm0, mm2		; mm0 = normal[1]*origin[1] | normal[0]*origin[0]
     pfmul		mm1, mm3		; mm1 = 0 | normal[2]*origin[2]

     punpckldq	mm5, mm5		; mm5 = intensity | intensity
     movq		mm6, [DlightCutoff]

     pfacc		mm0, mm0		; mm0 = X | normal[1]*origin[1]+normal[0]*origin[0]
     pxor		mm5, [SignBitHigh]	; mm5 = -light->intensity | light->intensity

     pfadd		mm0, mm1		; mm0 = X | normal[1]*origin[1]+normal[0]*origin[0]+normal[2]*origin[2]
     pfsub		mm0, mm4		; mm0 = X | dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;

     pfadd		mm5, mm6		; mm5 = -light->intensity+DLIGHT_CUTOFF | light->intensity-DLIGHT_CUTOFF
     punpckldq	mm0, mm5		; mm0 = light->intensity-DLIGHT_CUTOFF | dist

     punpckhdq	mm5, mm5		; mm5 = -light->intensity+DLIGHT_CUTOFF | -light->intensity+DLIGHT_CUTOFF
     punpckldq	mm5, mm0		; mm5 = dist | -light->intensity+DLIGHT_CUTOFF

     pfcmpge		mm5, mm0
     movd		eax, mm5

     punpckhdq	mm5, mm5
     movd		ecx, mm5

     test		ecx, ecx
     jz		CheckDistLow

     mov		eax, DWORD PTR [esi+40]

CallR_MarkLightsAndBail:
     push		eax
     push		edi
     push		ebx
     FCALL		_R_AuxMarkLights
     add		esp, 12					; 0000000cH
     pop		ebx
     pop		ebp
     pop		edi
     pop		esi
     ret		0

;;;;	if (dist > light->intensity-DLIGHT_CUTOFF)
;	if !(light->intensity-DLIGHT_CUTOFF >= dist)
;	 	R_MarkLights (light, bit, node->children[0]);
;		return;

CheckDistLow:
     or		eax, eax
     mov		eax, DWORD PTR [esi+44]
     jnz		short CallR_MarkLightsAndBail

;;;;	if (dist < -light->intensity+DLIGHT_CUTOFF)
; 	if !(dist >= -light->intensity+DLIGHT_CUTOFF) 
; 		R_MarkLights (light, bit, node->children[1]);
;		return;
;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>
;$L26049:
;	mov	eax, DWORD PTR [esi+36]		; eax = splitplane
;	fld	DWORD PTR [eax+4]		; normal[1]
;	fld	DWORD PTR [eax+8]		; normal[2] | normal[1]
;	fmul	DWORD PTR [ebx+8]		; origin[2]*normal[2] | normal[1]
;	fld	DWORD PTR [eax]			; normal[0] | origin[2]*normal[2] | normal[1]
;	fxch	ST(2)				; normal[1] | origin[2]*normal[2] | normal[0]
;	fmul	DWORD PTR [ebx+4]		; origin[1]*normal[1] | origin[2]*normal[2] | normal[0]
;	fld	DWORD PTR [ebx+24]		; intensity | origin[1]*normal[1] | origin[2]*normal[2] | normal[0]
;	fxch	ST(3)				; normal[0] | origin[1]*normal[1] | origin[2]*normal[2] | intensity
;	fmul	DWORD PTR [ebx]			; origin[0]*normal[0] | origin[1]*normal[1] | origin[2]*normal[2] | intensity
;	fxch	ST(1)				; origin[1]*normal[1] | origin[0]*normal[0] | origin[2]*normal[2] | intensity
;	faddp	ST(2), ST(0)			; origin[0]*normal[0] | origin[1]*normal[1]+origin[2]*normal[2] | intensity
;	fxch	ST(2)				; intensity | origin[1]*normal[1]+origin[2]*normal[2] | origin[0]*normal[0]
;	fsub	DWORD PTR $T26056		; intensity-64 | origin[1]*normal[1]+origin[2]*normal[2] | origin[0]*normal[0]
;	fxch	ST(2)				; origin[0]*normal[0] | origin[1]*normal[1]+origin[2]*normal[2] | intensity-64
;	faddp	ST(1), ST(0)			; origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2] | intensity-64
;	fsub	DWORD PTR [eax+12]		; origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]-spl->dist | intensity-64
;; 112  : 	if (dist > light->intensity-DLIGHT_CUTOFF)
;	fxch	ST(1)				; intensity-64 | origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	fld	ST(1)				; origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2] | intensity-64 | origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	fcompp					; intensity-64 | origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	fnstsw	ax
;	test	ah, 41h
;	jne	SHORT $L25792		; Is greater than or equal to.
;
;; 113  : 	{
;; 114  : 		R_MarkLights (light, bit, node->children[0]);
;
;	mov	esi, DWORD PTR [esi+40]
;	fstp	ST(0)				; origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	jmp	SHORT $L26055
;$L25792:
;
;; 115  : 		return;
;; 116  : 	}
;; 117  : 	if (dist < -light->intensity+DLIGHT_CUTOFF)
;
;	fld	DWORD PTR $T26056		; 64 | intensity-64 | origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	fsub	DWORD PTR [ebx+24]		; 64-intensity | intensity-64 | origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	fxch	ST(1)				; intensity-64 | 64-intensity | origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	fcompp					; intensity-64 | 64-intensity | origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	fnstsw	ax				; 64-intensity | origin[0]*normal[0]+origin[1]*normal[1]+origin[2]*normal[2]
;	test	ah, 1
;
;; 118  : 	{
;; 119  : 		R_MarkLights (light, bit, node->children[1]);
;
;	jne	SHORT $L26057	; Bail
;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>;;;;;;;;<AMD-3D>

; 120  : 		return;
; 121  : 	}
; 122  : 		
; 123  : // mark the polygons
; 124  : 	surf = r_worldmodel->surfaces + node->firstsurface;

     mov	ecx, DWORD PTR _r_worldmodel
     xor	eax, eax
     mov	ax, WORD PTR [esi+48]
     mov	edx, DWORD PTR [ecx+212]

; 125  : 	for (i=0 ; i<node->numsurfaces ; i++, surf++)

     xor	ecx, ecx
     lea	eax, DWORD PTR [eax+eax*2]
     shl	eax, 5
     add	eax, edx
     cmp	WORD PTR [esi+50], cx
     jbe	SHORT $L25796	; Call R_MarkLights and then bail.

; 137  : }

     add	eax, 64					; 00000040H
$L25794:

; 126  : 	{
; 127  : 		if (surf->dlightframe != r_dlightframecount)

     mov	edx, DWORD PTR [eax-4]
     mov	ebp, DWORD PTR _r_dlightframecount
     cmp	edx, ebp
     je	SHORT $L25797

; 128  : 		{
; 129  : 			surf->dlightbits = 0;

     mov	DWORD PTR [eax], 0

; 130  : 			surf->dlightframe = r_dlightframecount;

     mov	edx, DWORD PTR _r_dlightframecount
     mov	DWORD PTR [eax-4], edx
$L25797:

; 131  : 		}
; 132  : 		surf->dlightbits |= bit;

     mov	edx, DWORD PTR [eax]
     add	eax, 96					; 00000060H
     or	edx, edi
     inc	ecx
     mov	DWORD PTR [eax-96], edx
     xor	edx, edx
     mov	dx, WORD PTR [esi+50]
     cmp	ecx, edx
     jl	SHORT $L25794
$L25796:

; 133  : 	}
; 134  : 
; 135  : 	R_MarkLights (light, bit, node->children[0]);

     mov	eax, DWORD PTR [esi+40]
     push	eax
     push	edi
     push	ebx
     FCALL	_R_AuxMarkLights
     add	esp, 12					; 0000000cH
$L26057:

; 136  : 	R_MarkLights (light, bit, node->children[1]);

     mov	esi, DWORD PTR [esi+44]
$L26055:

; 101  : 	cplane_t	*splitplane;
; 102  : 	float		dist;
; 103  : 	msurface_t	*surf;
; 104  : 	int			i;
; 105  : 	
; 106  : 	if (node->contents != -1)

     cmp	DWORD PTR [esi], -1
     je	$L26049
     pop	ebx
     pop	ebp
     pop	edi
$L26053:

; 137  : }

     pop	esi
     femms
     ret	0
_R_AuxMarkLights ENDP
_TEXT	ENDS

ifdef SIN

EXTRN	_TransposeMatrix:NEAR
EXTRN	_MatrixTransformVector:NEAR

_TEXT	SEGMENT

align 32
_R_MarkLights PROC NEAR					; COMDAT

; 249  : {

     sub	 esp, 76			; 0000004cH
     push	 esi

; 250  :     dlight_t        s_light;
; 251  : 	cplane_t		*splitplane;
; 252  : 	vec3_t		    ofs;
; 253  : 	float			mat[3][3];

_light$ = 8
_bit$ = 12
_node$ = 16
_s_light$ = -64
_ofs$ = -76
_mat$ = -36

; 255  : 	if (node->contents != -1)

     mov	 esi, DWORD PTR _node$[esp+76]
     cmp	 DWORD PTR [esi], -1
     jne	 $LEXIT50985

; 256  : 		return;
; 257  : 
; 258  : 	splitplane = node->plane;
; 259  : 	if ( currententity->angles[0] || currententity->angles[1] || currententity->angles[2])

; 264  : 		}
; 265  : 	else
; 266  : 		{
; 267  : 		VectorSubtract( light->origin, currententity->origin, s_light.origin );

    femms

    movq         mm2, fqZero
    mov	         ecx, DWORD PTR _currententity

    movd         mm1, [ecx+12]          ; angles                        [- | 2]
    mov 	 eax, DWORD PTR _light$[esp+76]

    movq         mm0, qword ptr [ecx+4] ; angles                        [1 | 0]
    pslld        mm1, 1                 ; Remove sign bits (0 == -0)

    pslld        mm0, 1                 ; Remove sign bits (0 == -0)
    pcmpeqd      mm1, mm2               ; -Ind(angles==0)               [- | 2]

    pcmpeqd      mm0, mm2               ; -Ind(angles==0)               [1 | 0]
    punpckldq    mm1, mm1               ; -Ind(angles==0)               [2 | 2]

    por          mm1, mm0               ; -Ind(angles==0)     [1 or 2 | 0 or 2]
    movq         mm4, QWORD PTR [ecx+4]

    pfacc        mm1, mm1               ; -Ind(...)     [- | (1 or 2)+(0 or 2)]
    movq         mm0, [eax]

    movd         mm2, [eax+8]
    pfsub        mm0, mm4

    movd         edx, mm1               ;  [(1 or 2)+(0 or 2)] == (0 or 1 or 2)
    movd         mm3, [ecx+12]

    test         edx, edx
    pfsub        mm2, mm3

    movq         _s_light$[esp+80], mm0
    jne          $LIF50992

    movd         _s_light$[esp+88], mm2
    mov 	 ecx, DWORD PTR _bit$[esp+76]

$L50993:

; 268  : 		}
; 269  : 
; 270  : 	R_AuxMarkLights (&s_light, bit, node);

     push	 esi
     lea	 edx, DWORD PTR _s_light$[esp+84]
     push	 ecx
     push	 edx
     call	 _R_AuxMarkLights
     add	 esp, 12			; 0000000cH
$LEXIT50985:

; 271  : }

     pop	 esi
     add	 esp, 76			; 0000004cH
     ret	 0

$LIF50992:

; 260  : 		{
; 261  : 		TransposeMatrix( currententity->mat, mat );

    movq        mm0, [ecx+76]                   ; [1 0]
    lea         eax, DWORD PTR _mat$[esp+80]

    movq        mm1, [ecx+76+8]                 ; [3 2]
    movd        [eax], mm0                      ; (0)

    movd        mm3, [ecx+76+16]                ; [- 4]
    psrlq       mm0, 32                         ; [- 1]

    movq        mm2, [ecx+76+20]                ; [6 5]
    punpckldq   mm0, mm3                        ; [4 1]

    movq        mm3, [ecx+76+28]                ; [8 7]
    movq        [eax+12], mm0                   ; (4 1)

    movd        [eax+20], mm3                   ; (7)
    movq        mm0, mm1                        ; [3 2]

    punpckldq   mm0, mm2                        ; [5 2]
    punpckhdq   mm1, mm2                        ; [6 3]

    psrlq       mm3, 32                         ; [- 8]
    movq        [eax+4], mm1                    ; (6 3)

    movq        [eax+24], mm0                   ; (5 2)
    movd        [eax+8], mm3                    ; (8)

    lea 	edx, DWORD PTR _mat$[esp+80]
    mov 	eax, DWORD PTR _light$[esp+76]

    movq        mm1, QWORD PTR [ecx+4]

    movq        mm0, [eax]

    movd        mm2, [eax+8]
    pfsub       mm0, mm1

    movd        mm3, [ecx+12]
    movq        _ofs$[esp+80], mm0

    pfsub       mm2, mm3

    movd        _ofs$[esp+88], mm2

    femms

; 263  : 		MatrixTransformVector( ofs, mat, s_light.origin );

    lea 	ecx, DWORD PTR _s_light$[esp+80]
    lea 	eax, DWORD PTR _ofs$[esp+80]
    push 	ecx
    push	edx
    push	eax
    call	_MatrixTransformVector
    add 	esp, 12				; 0000000cH

    mov 	 ecx, DWORD PTR _bit$[esp+76]

    femms

    jmp 	 $L50993

_R_MarkLights ENDP
_TEXT	ENDS

endif

;EXTRN	_r_origin:BYTE
;	COMDAT _R_AddSkySurface
_TEXT	SEGMENT
_fa$ = 8
_verts$ = -768
_R_AddSkySurface PROC NEAR				; COMDAT

; 468  : 	int			i;
; 469  : 	vec3_t		verts[MAX_CLIP_VERTS];
; 470  : 	glpoly_t	*p;
; 471  : 
; 472  : 	// calculate vertex values for sky box
; 473  : 	for (p=fa->polys ; p ; p=p->next)

     mov	eax, DWORD PTR _fa$[esp-4]
     sub	esp, 768				; 00000300H
     push	esi
     push	edi
     mov	esi, DWORD PTR [eax+44]
     test	esi, esi
     jne	SHORT $L25958_
     jmp	$L25960
align	64
$L25958_:

; 474  : 	{
; 475  : 		for (i=0 ; i<p->numverts ; i++)

     mov	eax, DWORD PTR [esi+8]
     xor	edx, edx
     test	eax, eax
     jle	SHORT $L25963_
     lea	edi, DWORD PTR _verts$[esp+780]
     lea	eax, DWORD PTR [esi+20]
     femms
     mov	ecx, DWORD PTR [esi+8]
     jmp	short $L25961
align	64
$L25961:

; 476  : 		{
; 477  : 			VectorSubtract (p->verts[i], r_origin, verts[i]);

     movq		mm0, [eax-4]
     movq		mm2, qword ptr [_r_origin]

     movd		mm3, dword ptr [_r_origin+8]
     add		eax, 28

     pfsub		mm0, mm2
     movd		mm1, [eax-24]

     add		edi, 12
     inc		edx

     pfsub		mm1, mm3
     movq		[edi-16], mm0

     movd		[edi-8], mm1
     loop		short $L25961

$L25963_:

; 478  : 		}
; 479  : 		ClipSkyPolygon (p->numverts, verts[0], 0);

     mov	edx, DWORD PTR [esi+8]
     lea	edi, DWORD PTR _verts$[esp+776]
     push	0
     push	edi
     push	edx
     call	_ClipSkyPolygon
     mov	esi, DWORD PTR [esi]
     add	esp, 12					; 0000000cH
     test	esi, esi
     je	short $L25960
     jmp	$L25958_

$L25960:

; 480  : 	}
; 481  : }

     pop	edi
     pop	esi
     add	esp, 768				; 00000300H
     ret	0
_R_AddSkySurface ENDP
_TEXT	ENDS
;if 0

;??	PUBLIC_C@_0BP@NDMM@ClipSkyPolygon?3?5MAX_CLIP_VERTS?$AA@ ; `string'
;	COMDAT ??_C@_0BP@NDMM@ClipSkyPolygon?3?5MAX_CLIP_VERTS?$AA@
; File C:\Quake2\code\ref_gl\gl_warp.c
_DATA	SEGMENT
??_C@_0BP@NDMM@ClipSkyPolygon?3?5MAX_CLIP_VERTS?$AA@ DB 'ClipSkyPolygon: '
     DB	'MAX_CLIP_VERTS', 00H			; `string'
_DATA	ENDS
CONST	SEGMENT
FloatPointOne	dd	3DCCCCCDh
FloatMinusPtOne	dd     0BDCCCCCDh

CONST	ENDS
;	COMDAT _ClipSkyPolygon
_TEXT	SEGMENT
_nump$ = 8
_vecs$ = 12
_stage$ = 16
_back$ = -2076
_dists$ = -1792
_sides$ = -2048
_newv$ = -1536
_newc$ = -2064
_i$ = -2056
_ClipSkyPolygon PROC NEAR				; COMDAT

; 371  : {
     sub	esp, 2076				; 0000081cH
     push	ebx
     push	ebp
     push	esi
     push	edi

; 372  : 	float	*norm;
; 373  : 	float	*v;
; 374  : 	qboolean	front, back;
; 375  : 	float	d, e;
; 376  : 	float	dists[MAX_CLIP_VERTS];
; 377  : 	int		sides[MAX_CLIP_VERTS];
; 378  : 	vec3_t	newv[2][MAX_CLIP_VERTS];
; 379  : 	int		newc[2];
; 380  : 	int		i, j;
; 381  : 
; 382  : 	if (nump > MAX_CLIP_VERTS-2)

     mov	edi, DWORD PTR _nump$[esp+2088]
     cmp	edi, 62					; 0000003eH
     jle	SHORT $L25926

; 383  : 		ri.Sys_Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS");

     push	OFFSET FLAT:??_C@_0BP@NDMM@ClipSkyPolygon?3?5MAX_CLIP_VERTS?$AA@ ; `string'
     push	1
     call	DWORD PTR _ri
     add	esp, 8
$L25926:

; 384  : 	if (stage == 6)

     mov	eax, DWORD PTR _stage$[esp+2088]
     cmp	eax, 6
     jne	SHORT $L25928

; 385  : 	{	// fully clipped, so draw it
; 386  : 		DrawSkyPolygon (nump, vecs);

     mov	eax, DWORD PTR _vecs$[esp+2088]
     femms
     push	eax
     push	edi
     FCALL	_DrawSkyPolygon
     add	esp, 8

; 459  : }

     pop	edi
     pop	esi
     pop	ebp
     pop	ebx
     add	esp, 2076				; 0000081cH
     ret	0
$L25928:

; 387  : 		return;
; 388  : 	}
; 389  : 
; 390  : 	front = back = false;
; 391  : 	norm = skyclip[stage];
; 392  : 	for (i=0, v = vecs ; i<nump ; i++, v+=3)

     mov	ebx, DWORD PTR _vecs$[esp+2088]
     xor	ecx, ecx
     lea	edx, DWORD PTR [eax+eax*2]
     xor	esi, esi
     cmp	edi, ecx
     mov	DWORD PTR _back$[esp+2092], ecx
     lea	ebp, DWORD PTR _skyclip[edx*4]
     jle	$L25931

; 459  : }

     lea	edx, DWORD PTR [ebx+8]
$L25929:

; 393  : 	{
; 394  : 		d = DotProduct (v, norm);
; 394  : 		d = DotProduct (v, norm);
     movd		mm4, [FloatPointOne]	; EPSILON
     movd		mm5, [FloatMinusPtOne]	; -EPSILON
     movq		mm0, [edx-8]
     movq		mm2, [ebp]
     movd		mm1, [edx]
     movd		mm3, [ebp+8]
     pfmul		mm0, mm2
     pfmul		mm1, mm3
     pfacc		mm0, mm0
     pfadd		mm0, mm1	; mm0 = X | d
; if (d > ON_EPSILON)
; if !(ON_EPSILON >= d)
     pfcmpge		mm4, mm0
     movd		eax, mm4
     test		eax, eax
     jnz		short $L25932
; 396  : 		{
; 397  : 			front = true;

     mov	esi, 1

; 398  : 			sides[i] = SIDE_FRONT;

     mov	DWORD PTR _sides$[esp+ecx*4+2092], 0

; 399  : 		}
; 400  : 		else if (d < -ON_EPSILON)

     jmp	SHORT $L25935
$L25932:
; else if (d < -ON_EPSILON)
; else if !(-ON_EPSILON >= d)
     pfcmpge		mm5, mm0
     movd		eax, mm5
     test		eax, eax
     jz		short $L25934_

; 401  : 		{
; 402  : 			back = true;

     mov	DWORD PTR _back$[esp+2092], 1

; 403  : 			sides[i] = SIDE_BACK;

     mov	DWORD PTR _sides$[esp+ecx*4+2092], 1

; 404  : 		}
; 405  : 		else

     jmp	SHORT $L25935
$L25934_:

; 406  : 			sides[i] = SIDE_ON;

     mov	DWORD PTR _sides$[esp+ecx*4+2092], 2
$L25935:

; 407  : 		dists[i] = d;

     movd	dword ptr _dists$[esp+ecx*4+2092], mm0
     inc	ecx
     add	edx, 12					; 0000000cH
     cmp	ecx, edi
     jl	SHORT $L25929
; 387  : 		return;
; 388  : 	}
; 389  : 
; 390  : 	front = back = false;
; 391  : 	norm = skyclip[stage];
; 392  : 	for (i=0, v = vecs ; i<nump ; i++, v+=3)

     mov	eax, DWORD PTR _stage$[esp+2088]
$L25931:

; 408  : 	}
; 409  : 
; 410  : 	if (!front || !back)

     test	esi, esi
     je	$L25937
     mov	edx, DWORD PTR _back$[esp+2092]
     test	edx, edx
     je	$L25937

; 413  : 		return;
; 414  : 	}
; 415  : 
; 416  : 	// clip it
; 417  : 	sides[i] = sides[0];
; 418  : 	dists[i] = dists[0];

     movd		mm0, dword ptr _dists$[esp+2092]
     mov	eax, DWORD PTR _sides$[esp+2092]

; 419  : 	VectorCopy (vecs, (vecs+(i*3)) );

     mov	edx, DWORD PTR [ebx]
     movd	DWORD PTR _dists$[esp+ecx*4+2092], mm0
     mov	DWORD PTR _sides$[esp+ecx*4+2092], eax
     lea	ecx, DWORD PTR [ecx+ecx*2]

; 420  : 	newc[0] = newc[1] = 0;

     xor	esi, esi
     lea	ecx, DWORD PTR [ebx+ecx*4]

; 421  : 
; 422  : 	for (i=0, v = vecs ; i<nump ; i++, v+=3)

     cmp	edi, esi
     mov	DWORD PTR _newc$[esp+2092], esi
     mov	DWORD PTR _i$[esp+2092], esi
     mov	DWORD PTR [ecx], edx
     mov	eax, DWORD PTR [ebx+4]
     mov	DWORD PTR [ecx+4], eax
     mov	edx, DWORD PTR [ebx+8]
     lea	eax, DWORD PTR [ebx+8]
     mov	DWORD PTR [ecx+8], edx
     jle	$L25940_

; 459  : }

     lea	ecx, DWORD PTR _dists$[esp+2096]
     lea	edi, DWORD PTR _newv$[esp+2100]
     lea	edx, DWORD PTR _newv$[esp+2096]
     lea	ebx, DWORD PTR _newv$[esp+2092]
     mov	DWORD PTR -2076+[esp+2092], ecx
     mov	DWORD PTR -2068+[esp+2092], edi
     mov	DWORD PTR -2072+[esp+2092], edx
$L25938_:
     mov	ecx, DWORD PTR _i$[esp+2092]
     lea	ebp, DWORD PTR [ecx*4]
     mov	DWORD PTR -2052+[esp+2092], ebp
     mov	ecx, DWORD PTR _sides$[esp+ebp+2092]
     sub	ecx, 0
     je	SHORT $L25945

; 423  : 	{
; 424  : 		switch (sides[i])

     dec	ecx
     je	SHORT $L25946_
     dec	ecx
     jne	SHORT $L25942

; 429  : 			break;
; 430  : 		case SIDE_BACK:
; 431  : 			VectorCopy (v, newv[1][newc[1]]);
; 432  : 			newc[1]++;
; 433  : 			break;
; 434  : 		case SIDE_ON:
; 435  : 			VectorCopy (v, newv[0][newc[0]]);

     mov	ecx, DWORD PTR [eax-8]

; 436  : 			newc[0]++;

     mov	ebp, DWORD PTR _newc$[esp+2092]
     mov	DWORD PTR [ebx], ecx
     mov	ecx, DWORD PTR [eax-4]
     mov	DWORD PTR [edx], ecx
     mov	ecx, DWORD PTR [eax]
     mov	DWORD PTR [edi], ecx
     inc	ebp
     add	edx, 12					; 0000000cH
     add	edi, 12					; 0000000cH
     mov	DWORD PTR _newc$[esp+2092], ebp
     mov	DWORD PTR -2072+[esp+2092], edx
     mov	DWORD PTR -2068+[esp+2092], edi
     add	ebx, 12					; 0000000cH
$L25946_:
     mov	ebp, DWORD PTR [eax-8]
     lea	ecx, DWORD PTR [esi+esi*2]
     shl	ecx, 2
     inc	esi
     mov	DWORD PTR _newv$[esp+ecx+2860], ebp
     mov	ebp, DWORD PTR [eax-4]
     mov	DWORD PTR _newv$[esp+ecx+2864], ebp
     mov	ebp, DWORD PTR [eax]
     mov	DWORD PTR _newv$[esp+ecx+2868], ebp
     mov	ebp, DWORD PTR -2052+[esp+2092]
     jmp	SHORT $L25942
$L25945:

; 425  : 		{
; 426  : 		case SIDE_FRONT:
; 427  : 			VectorCopy (v, newv[0][newc[0]]);

     mov	ecx, DWORD PTR [eax-8]

; 428  : 			newc[0]++;

     add	edx, 12					; 0000000cH
     mov	DWORD PTR [ebx], ecx
     mov	ecx, DWORD PTR [eax-4]
     mov	DWORD PTR [edx-12], ecx
     mov	ecx, DWORD PTR [eax]
     mov	DWORD PTR [edi], ecx
     mov	ecx, DWORD PTR _newc$[esp+2092]
     inc	ecx
     add	edi, 12					; 0000000cH
     mov	DWORD PTR _newc$[esp+2092], ecx
     mov	DWORD PTR -2072+[esp+2092], edx
     mov	DWORD PTR -2068+[esp+2092], edi
     add	ebx, 12					; 0000000cH
$L25942:

; 437  : 			VectorCopy (v, newv[1][newc[1]]);
; 438  : 			newc[1]++;
; 439  : 			break;
; 440  : 		}
; 441  : 
; 442  : 		if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])

     mov	ecx, DWORD PTR _sides$[esp+ebp+2092]
     cmp	ecx, 2
     je	$L25939
     mov	ebp, DWORD PTR _sides$[esp+ebp+2096]
     cmp	ebp, 2
     je	$L25939
     cmp	ebp, ecx
     je	$L25939
     mov	edx, DWORD PTR -2052+[esp+2092]

; 459  : }

     mov	ebp, 3
     movd		mm0, DWORD PTR _dists$[esp+edx+2092]

     lea	ecx, DWORD PTR _dists$[esp+edx+2092]
     mov	edx, DWORD PTR -2076+[esp+2092]

     movd		mm1, [edx]
     movd		mm2, [ecx]

     pfsub		mm0, mm1
     lea	edx, DWORD PTR [esi+esi*2]
     pfrcp		mm0, mm0
     pfmul		mm0, mm2
     lea	edi, DWORD PTR _newv$[esp+edx*4+2860]
     lea	ecx, DWORD PTR [eax-8]
     mov	edx, ebx
$L25950_:
     movd	mm1, [ecx+12]
     movd	mm2, [ecx]
     pfsub	mm1, mm2
     add	ecx, 4
     add	edx, 4
     add	edi, 4
     dec	ebp

     pfmul		mm1, mm0
     pfadd		mm1, mm2
     movd		[edx-4], mm1
     movd		[edi-4], mm1
     jne	SHORT $L25950_
     mov	ebp, DWORD PTR _newc$[esp+2092]
     mov	edx, DWORD PTR -2072+[esp+2092]
     mov	edi, DWORD PTR -2068+[esp+2092]
     inc	ebp
     add	edx, 12					; 0000000cH
     add	edi, 12					; 0000000cH
     add	ebx, 12					; 0000000cH
     mov	DWORD PTR _newc$[esp+2092], ebp
     mov	DWORD PTR -2072+[esp+2092], edx
     mov	DWORD PTR -2068+[esp+2092], edi
     inc	esi
$L25939:
     mov	ebp, DWORD PTR -2076+[esp+2092]
     mov	ecx, DWORD PTR _i$[esp+2092]
     add	ebp, 4
     inc	ecx
     mov	DWORD PTR -2076+[esp+2092], ebp
     mov	ebp, DWORD PTR _nump$[esp+2088]
     add	eax, 12					; 0000000cH
     cmp	ecx, ebp
     mov	DWORD PTR _i$[esp+2092], ecx
     jl	$L25938_
$L25940_:

; 443  : 			continue;
; 444  : 
; 445  : 		d = dists[i] / (dists[i] - dists[i+1]);
; 446  : 		for (j=0 ; j<3 ; j++)
; 447  : 		{
; 448  : 			e = v[j] + d*(v[j+3] - v[j]);
; 449  : 			newv[0][newc[0]][j] = e;
; 450  : 			newv[1][newc[1]][j] = e;
; 451  : 		}
; 452  : 		newc[0]++;
; 453  : 		newc[1]++;
; 454  : 	}
; 455  : 
; 456  : 	// continue
; 457  : 	ClipSkyPolygon (newc[0], newv[0][0], stage+1);
; 458  : 	ClipSkyPolygon (newc[1], newv[1][0], stage+1);
; 459  : }

     femms
     mov	eax, DWORD PTR _stage$[esp+2088]
     mov	edx, DWORD PTR _newc$[esp+2092]
     lea	ecx, DWORD PTR _newv$[esp+2092]
     lea	edi, DWORD PTR [eax+1]
     push	edi
     push	ecx
     push	edx
     call	_ClipSkyPolygon
     add	esp, 12					; 0000000cH
     lea	eax, DWORD PTR _newv$[esp+2860]
     push	edi
     push	eax
     push	esi
     call	_ClipSkyPolygon
     add	esp, 12					; 0000000cH
     pop	edi
     pop	esi
     pop	ebp
     pop	ebx
     add	esp, 2076				; 0000081cH
     ret	0
$L25937:

; 411  : 	{	// not clipped
; 412  : 		ClipSkyPolygon (nump, vecs, stage+1);

     femms
     inc	eax
     push	eax
     push	ebx
     push	edi
     call	_ClipSkyPolygon
     add	esp, 12					; 0000000cH

; 459  : }

     pop	edi
     pop	esi
     pop	ebp
     pop	ebx
     add	esp, 2076				; 0000081cH
     ret	0
_ClipSkyPolygon ENDP
_TEXT	ENDS
CONST	SEGMENT
$T26252	DD	000000000r			; 0
CONST	ENDS
EXTRN	_r_viewcluster:DWORD
EXTRN	_r_viewcluster2:DWORD
EXTRN	_r_oldviewcluster:DWORD
EXTRN	_r_oldviewcluster2:DWORD
EXTRN	_r_novis:DWORD
EXTRN	_gl_lockpvs:DWORD
EXTRN	_Mod_ClusterPVS:NEAR
EXTRN	_r_visframecount:DWORD
;	COMDAT _R_MarkLeaves
_TEXT	SEGMENT
_vis$ = -8196
_fatvis$ = -8192
_R_MarkLeaves PROC NEAR					; COMDAT

; 1153 : {

     mov	eax, 8196				; 00002004H
     call	__chkstk

; 1154 : 	byte	*vis;
; 1155 : 	byte	fatvis[MAX_MAP_LEAFS/8];
; 1156 : 	mnode_t	*node;
; 1157 : 	int		i, c;
; 1158 : 	mleaf_t	*leaf;
; 1159 : 	int		cluster;
; 1160 : 
; 1161 : 	if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && !r_novis->value && r_viewcluster != -1)

     mov	ecx, DWORD PTR _r_viewcluster
     mov	eax, DWORD PTR _r_oldviewcluster
     mov	edx, DWORD PTR _r_viewcluster2
     push	ebx
     push	ebp
     push	esi
     mov	esi, DWORD PTR _r_novis
     cmp	eax, ecx
     push	edi
     jne	SHORT $L26102
     cmp	DWORD PTR _r_oldviewcluster2, edx
     jne	SHORT $L26102
;	fld	DWORD PTR [esi+20]
;	fcomp	DWORD PTR $T26252
;	fnstsw	ax
;	test	ah, 64					; 00000040H
;	je	SHORT $L26102
     cmp	dword ptr [esi+20], 0
     jne	SHORT $L26102
     cmp	ecx, -1
     jne	$L26111
$L26102:

; 1162 : 		return;
; 1163 : 
; 1164 : 	// development aid to let you run around and see exactly where
; 1165 : 	// the pvs ends
; 1166 : 	if (gl_lockpvs->value)

     mov	eax, DWORD PTR _gl_lockpvs
;	fld	DWORD PTR [eax+20]
;	fcomp	DWORD PTR $T26252
;	fnstsw	ax
;	test	ah, 64					; 00000040H
;	je	$L26111
     cmp	DWORD PTR [eax+20], 0
     jne	$L26111

; 1167 : 		return;
; 1168 : 
; 1169 : 	r_visframecount++;

     mov	eax, DWORD PTR _r_visframecount

; 1170 : 	r_oldviewcluster = r_viewcluster;

     mov	DWORD PTR _r_oldviewcluster, ecx
     inc	eax

; 1171 : 	r_oldviewcluster2 = r_viewcluster2;

     mov	DWORD PTR _r_oldviewcluster2, edx
     mov	DWORD PTR _r_visframecount, eax

; 1172 : 
; 1173 : 	if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)

;	fld	DWORD PTR [esi+20]
;	fcomp	DWORD PTR $T26252
;	fnstsw	ax
;	test	ah, 64					; 00000040H
     mov	eax, DWORD PTR _r_worldmodel
;	je	$L26105
     cmp	DWORD PTR [esi+20], 0
     jne	$L26105
     cmp	ecx, -1
     je	$L26105
     mov	edx, DWORD PTR [eax+232]
     test	edx, edx
     je	$L26105

; 1180 : 		return;
; 1181 : 	}
; 1182 : 
; 1183 : 	vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);

     push	eax
     push	ecx
     call	_Mod_ClusterPVS

; 1184 : 	// may have to combine two clusters because of solid water boundaries
; 1185 : 	if (r_viewcluster2 != r_viewcluster)

     mov	ebp, DWORD PTR _r_viewcluster2
     mov	esi, eax
     mov	eax, DWORD PTR _r_viewcluster
     add	esp, 8
     cmp	ebp, eax
     mov	DWORD PTR _vis$[esp+8212], esi
     je	SHORT $L26112

; 1186 : 	{
; 1187 : 		memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8);

     mov	ebx, DWORD PTR _r_worldmodel
     lea	edi, DWORD PTR _fatvis$[esp+8212]

; 1188 : 		vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel);

     push	ebx
     push	ebp
     mov	eax, DWORD PTR [ebx+164]
     add	eax, 7
     cdq
     and	edx, 7
     add	eax, edx
     mov	ecx, eax
     sar	ecx, 3
     mov	edx, ecx
     shr	ecx, 2
     rep movsd
     mov	ecx, edx
     and	ecx, 3
     rep movsb
     call	_Mod_ClusterPVS
     mov	esi, eax

; 1189 : 		c = (r_worldmodel->numleafs+31)/32;

     mov	eax, DWORD PTR _r_worldmodel
     add	esp, 8
     mov	eax, DWORD PTR [eax+164]
     add	eax, 31					; 0000001fH
     cdq
     and	edx, 31					; 0000001fH
     add	eax, edx
     sar	eax, 5

; 1190 : 		for (i=0 ; i<c ; i++)

     test	eax, eax
     jle	SHORT $L26115
     mov	edx, esi
     lea	esi, DWORD PTR _fatvis$[esp+8212]
     lea	ecx, DWORD PTR _fatvis$[esp+8212]
     sub	edx, esi
$L26113:

; 1191 : 			((int *)fatvis)[i] |= ((int *)vis)[i];

     mov	esi, DWORD PTR [edx+ecx]
     mov	ebx, DWORD PTR [ecx]
     or	ebx, esi
     mov	DWORD PTR [ecx], ebx
     add	ecx, 4
     dec	eax
     jne	SHORT $L26113
$L26115:

; 1192 : 		vis = fatvis;

     lea	ecx, DWORD PTR _fatvis$[esp+8212]
     mov	DWORD PTR _vis$[esp+8212], ecx
$L26112:

; 1193 : 	}
; 1194 : 	
; 1195 : 	for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)

     mov	ecx, DWORD PTR _r_worldmodel
     xor	esi, esi
     mov	eax, DWORD PTR [ecx+164]
     mov	ebp, DWORD PTR [ecx+168]
     test	eax, eax
     jle	$L26111
     mov	edi, DWORD PTR _r_visframecount
$L26116:

; 1196 : 	{
; 1197 : 		cluster = leaf->cluster;

     mov	eax, DWORD PTR [ebp+36]

; 1198 : 		if (cluster == -1)

     cmp	eax, -1
     je	SHORT $L26117

; 1199 : 			continue;
; 1200 : 		if (vis[cluster>>3] & (1<<(cluster&7)))

     mov	ecx, eax
     mov	edx, 1
     and	ecx, 7
     shl	edx, cl
     mov	ecx, DWORD PTR _vis$[esp+8212]
     sar	eax, 3
     mov	al, BYTE PTR [eax+ecx]
     test	dl, al
     je	SHORT $L26123

; 1201 : 		{
; 1202 : 			node = (mnode_t *)leaf;
; 1203 : 			do
; 1204 : 			{
; 1205 : 				if (node->visframe == r_visframecount)

     mov	edx, DWORD PTR [ebp+4]
     lea	ecx, DWORD PTR [ebp+4]
     cmp	edx, edi
     mov	eax, ebp
     je	SHORT $L26123
$L26121:

; 1206 : 					break;
; 1207 : 				node->visframe = r_visframecount;
; 1208 : 				node = node->parent;

     mov	eax, DWORD PTR [eax+32]
     mov	DWORD PTR [ecx], edi

; 1209 : 			} while (node);

     test	eax, eax
     je	SHORT $L26344
     mov	edi, DWORD PTR _r_visframecount
     mov	edx, DWORD PTR [eax+4]
     lea	ecx, DWORD PTR [eax+4]
     cmp	edx, edi
     jne	SHORT $L26121

; 1201 : 		{
; 1202 : 			node = (mnode_t *)leaf;
; 1203 : 			do
; 1204 : 			{
; 1205 : 				if (node->visframe == r_visframecount)

     jmp	SHORT $L26123
$L26344:
     mov	edi, DWORD PTR _r_visframecount
$L26123:
     mov	ecx, DWORD PTR _r_worldmodel
$L26117:

; 1193 : 	}
; 1194 : 	
; 1195 : 	for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)

     mov	eax, DWORD PTR [ecx+164]
     inc	esi
     add	ebp, 52					; 00000034H
     cmp	esi, eax
     jl	SHORT $L26116

; 1210 : 		}
; 1211 : 	}
; 1212 : 
; 1213 : #if 0
; 1214 : 	for (i=0 ; i<r_worldmodel->vis->numclusters ; i++)
; 1215 : 	{
; 1216 : 		if (vis[i>>3] & (1<<(i&7)))
; 1217 : 		{
; 1218 : 			node = (mnode_t *)&r_worldmodel->leafs[i];	// FIXME: cluster
; 1219 : 			do
; 1220 : 			{
; 1221 : 				if (node->visframe == r_visframecount)
; 1222 : 					break;
; 1223 : 				node->visframe = r_visframecount;
; 1224 : 				node = node->parent;
; 1225 : 			} while (node);
; 1226 : 		}
; 1227 : 	}
; 1228 : #endif
; 1229 : }

     pop	edi
     pop	esi
     pop	ebp
     pop	ebx
     add	esp, 8196				; 00002004H
     ret	0
$L26105:

; 1174 : 	{
; 1175 : 		// mark everything
; 1176 : 		for (i=0 ; i<r_worldmodel->numleafs ; i++)

     mov	edx, DWORD PTR [eax+164]
     xor	ecx, ecx
     test	edx, edx
     jle	SHORT $L26108
     xor	edx, edx
$L26106:

; 1177 : 			r_worldmodel->leafs[i].visframe = r_visframecount;

     mov	eax, DWORD PTR [eax+168]
     mov	esi, DWORD PTR _r_visframecount
     inc	ecx
     mov	DWORD PTR [eax+edx+4], esi
     mov	eax, DWORD PTR _r_worldmodel
     add	edx, 52					; 00000034H
     cmp	ecx, DWORD PTR [eax+164]
     jl	SHORT $L26106
$L26108:

; 1178 : 		for (i=0 ; i<r_worldmodel->numnodes ; i++)

     mov	edx, DWORD PTR [eax+188]
     xor	ecx, ecx
     test	edx, edx
     jle	SHORT $L26111
     xor	edx, edx
$L26109:

; 1179 : 			r_worldmodel->nodes[i].visframe = r_visframecount;

     mov	eax, DWORD PTR [eax+196]
     mov	esi, DWORD PTR _r_visframecount
     inc	ecx
     mov	DWORD PTR [eax+edx+4], esi
     mov	eax, DWORD PTR _r_worldmodel
     add	edx, 52					; 00000034H
     cmp	ecx, DWORD PTR [eax+188]
     jl	SHORT $L26109
$L26111:

; 1210 : 		}
; 1211 : 	}
; 1229 : }

     pop	edi
     pop	esi
     pop	ebp
     pop	ebx
     add	esp, 8196				; 00002004H
     ret	0
_R_MarkLeaves ENDP
_TEXT	ENDS

;  --------------------------------------------------------------------------

EXTRN	_r_fullbright:DWORD
EXTRN	_fullbright:DWORD
EXTRN	_r_envmap:DWORD
EXTRN	_r_goldenvmap:DWORD
EXTRN	_gl_drawflat:DWORD
EXTRN	_r_solidcolors:BYTE
EXTRN	_gl_showtris:DWORD

_DATA	SEGMENT
extrn	_currentbase:DWORD
extrn	_currentverts:DWORD
extrn	_oldverts:DWORD
extrn	_currentanim:DWORD
extrn	_oldanim:DWORD
extrn	_currentframe:DWORD
extrn	_oldframe:DWORD
extrn	_currentscale:DWORD
extrn	_weapon_lefthanded:DWORD
extrn	_sinmdl_transform:DWORD ;; 0cH
extrn	_rendergroups:DWORD     ;; 020H
_DATA	ENDS

;	COMDAT _SINMDL_LerpVerts
_TEXT	SEGMENT
_nverts$ = 8
_v$ = 12
_ov$ = 16
_lerp$ = 24
_move$ = 28
_frontv$ = 32
_backv$ = 36
align	32	; 01-07-99 M. Steiger -- Aligned Procedure
_SINMDL_LerpVerts PROC NEAR				; COMDAT

; 355  : 	int i;
; 356  : 
; 357  :    for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4)

     mov	 eax, DWORD PTR _nverts$[esp-4]
     test	 eax, eax
     jle	 $L51013

     femms

; 358  : 		{
; 359  : 		lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0];
; 360  : 		lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1];
; 361  : 		lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2];

     push      edi
     push      esi
     push      ebp
     push      ebx
     
     mov       ecx, eax
     mov       edx, DWORD PTR _move$[esp+16-4]
     mov       eax, DWORD PTR _ov$[esp+16-4]
     mov       edi, DWORD PTR _backv$[esp+16-4]
     mov       esi, DWORD PTR _lerp$[esp+16-4]
     mov       ebp, DWORD PTR _frontv$[esp+16-4]
     mov       ebx, DWORD PTR _v$[esp+16-4]

     movq      mm6, qword ptr [edx]
     movd      mm5, dword ptr [edx+8]
     movq      mm0, qword ptr [ebp]            ; frontv                 [1 | 0]

     pxor      mm7, mm7                        ; 00000000 | 00000000

align 32	; 01-07-99 M. Steiger -- Aligned Loop Target
$L51011:

     movd      mm4, dword ptr [ebx]            ; 0 |  v->v[3]v[2]v[1]v[0]
     add       ebx, 4                          ; v++

     punpcklbw mm4, mm7                        ;  v-> 0 v[3] 0 v[2] |  v-> 0 v[1] 0 v[0]
     add       esi, 16                         ; lerp+=4

     movq      mm3, mm4                        ;  v-> 0 v[3] 0 v[2] |  v-> 0 v[1] 0 v[0]
     punpcklwd mm4, mm7                        ;  v-> 0 0 0 v[1]    |  v-> 0 0 0 v[0]

     punpckhbw mm3, mm7                        ;  v-> 0 0 0 v[3]    |  v-> 0 0 0 v[2]
     pi2fd     mm4, mm4                        ;  float(v->v[1])    | float(v->v[0])

; 01-07-99 M. Steiger -- Change to movd; Otherwise occasionally reads past end of page...
;     movq      mm2, [eax]                      ; 0 | ov->v[3]v[2]v[1]v[0]
     movd      mm2, [eax]                      ; 0 | ov->v[3]v[2]v[1]v[0]
     pi2fd     mm3, mm3                        ;  float(v->v[3])    | float(v->v[2])

     pfmul     mm4, mm0                        ; v->v * frontv          [1 | 0]
     movd      mm0, dword ptr [ebp+8]          ; frontv                 [- | 2]

     pfmul     mm3, mm0                        ; v->v * frontv          [- | 2]
     movq      mm0, qword ptr [edi]            ; backv                  [1 | 0]

     punpcklbw mm2, mm7                        ; ov-> 0 v[3] 0 v[2] | ov-> 0 v[1] 0 v[0]
     add       eax, 4                          ; ov++

     movq      mm1, mm2                        ; ov-> 0 v[3] 0 v[2] | ov-> 0 v[1] 0 v[0]
     punpcklwd mm2, mm7                        ; ov-> 0 0 0 v[1]    |  v-> 0 0 0 v[0]

     punpckhbw mm1, mm7                        ; ov-> 0 0 0 0       | ov-> 0 v[3] 0 v[2]
     pi2fd     mm2, mm2                        ;  float(ov->v[1])   | float(ov->v[0])

     nop
     pi2fd     mm1, mm1                        ;  float(ov->v[3])   | float(ov->v[2])

     pfmul     mm2, mm0                        ; ov->v * backv          [1 | 0]
     movd      mm0, dword ptr [edi+8]          ; backv                  [- | 2]

     pfmul     mm1, mm0                        ; ov->v * backv          [- | 2]
     movq      mm0, qword ptr [ebp]            ; frontv                 [1 | 0]

     pfadd     mm2, mm4
     nop

     pfadd     mm1, mm3
     mov       eax, eax

     pfadd     mm2, mm6
     movq      [esi-16], mm2

     pfadd     mm1, mm5
     movd      [esi-8], mm1

     loop      $L51011

     pop	 ebx
     pop	 ebp
     pop	 esi
     pop	 edi

     femms

$L51013:

; 362  : 	   }
; 363  :    }

     ret	 0
_SINMDL_LerpVerts ENDP
_TEXT	ENDS

_DATA SEGMENT
_SINMDL_DFL_InitFlag dd 0
_LAE_locked dd 0
_DATA ENDS

_TEXT	SEGMENT
_S_qglLockArraysEXT PROC NEAR				; COMDAT

; 409  : 	 LAE_locked = false;
; 410  :      if ( qglLockArraysEXT != 0 ) {

      mov	 eax, DWORD PTR _qglLockArraysEXT
      mov	 DWORD PTR _LAE_locked, 0
      test	 eax, eax
      je	 SHORT $L51082

; 411  :          LAE_locked = true;
; 412  :          qglLockArraysEXT( 0, currentbase->num_xyz );

      mov	 ecx, DWORD PTR _currentbase
      mov	 DWORD PTR _LAE_locked, 1
      mov	 edx, DWORD PTR [ecx+8]
      push	 edx
      push	 0
      call	 eax
$L51082:

; 413  :      }
; 414  : }

      ret	 0
_S_qglLockArraysEXT ENDP

_S_qglUnlockArraysEXT PROC NEAR				; COMDAT

; 417  :    if ( LAE_locked && qglUnlockArraysEXT != 0 ) {

      mov	 eax, DWORD PTR _LAE_locked
      test	 eax, eax
      je	 SHORT $L51085
      mov	 eax, DWORD PTR _qglUnlockArraysEXT
      test	 eax, eax
      je	 SHORT $L51085

; 418  :       qglUnlockArraysEXT();

      call	 eax
$L51085:

; 419  :    }
; 420  :    LAE_locked = false;

      mov	 DWORD PTR _LAE_locked, 0

; 421  : }

      ret	 0
_S_qglUnlockArraysEXT ENDP
_TEXT	ENDS

_BSS	SEGMENT
_?playerskins@?3??SINMDL_DrawFrameLerp@@9@9$S43846 DD 02H DUP (?)
_BSS	ENDS
CONST	SEGMENT
$T44249	DQ	03ff0000000000000r		; 1
$T44250	DD	000000000r			; 0
$T44251	DD	03f28f5c3r			; 0.66
$T44252	DD	03ea8f5c3r			; 0.33
$T44253	DD	03f800000r			; 1
$T44254	DD	040000000r			; 2
$T44255	DD	0bf800000r			; -1
$T44256	DQ	04000000000000000r		; 2
$T44257	DD	0bf000000r			; -0.5
CONST	ENDS
;	COMDAT _SINMDL_DrawFrameLerp
_TEXT	SEGMENT
_pmdl$ = 8
_backlerp$ = 12
_framebacklerp$ = 16
_count$ = -108
_frontlerp$ = -92
_framefrontlerp$ = 8
_alpha$ = 16
_move$ = -36
_delta$ = -84
_frontv$ = -12
_backv$ = -24
_i$ = 8
_skins$ = -104
_plight$ = -96
_pgroup$43853 = -88
_eye_normal$43902 = -48
_eye_vert$43903 = -60
_normal$43904 = -72

align 32
_SINMDL_DrawFrameLerp PROC NEAR				; COMDAT

; 416  :    {
	cmp		_SINMDL_DFL_InitFlag,0
	je		SINMDL_DFL_CvtIndCalls
   
	sub		esp, 108				; 0000006cH
			 
; 417  : 	float 	l;
; 418  : 	int		*order;
; 419  : 	int		count;
; 420  : 	float	   frontlerp;
; 421  : 	float	   framefrontlerp;
; 422  : 	float	   alpha;
; 423  : 	vec3_t	move, delta;
; 424  : 	vec3_t	frontv, backv;
; 425  : 	int		i,j;
; 426  : 	int		index_xyz;
; 427  : 	float	   *lerp;
; 428  : 	image_t	**skins;
; 429  : 	image_t	*skin;
; 430  :    float    *plight;
; 431  :    qboolean locked = false;
; 432  : 
; 433  : 
; 434  : 	frontlerp = 1.0 - backlerp;
; 435  : 	framefrontlerp = 1.0 - framebacklerp;
; 436  : 

;IGX. Copied from original optimization
	femms

	mov		eax, DWORD PTR _currententity
	movq		mm0, Float_1x2				;mm0 = 1.0 | 1.0 

	push		ebx
	movq		mm2, QWORD PTR [eax+16]			;mm2 = ce->orig[1] | ce->orig[0]

	push		ebp
	movq		mm1, QWORD PTR [eax+32]			;mm1 = ce->oldorig[1] | ce->oldorig[0]

	push		esi
	movd		mm3, DWORD PTR [eax+40]			;mm3 = 0 | ce->oldorig[2]

	movq		mm7, QWORD PTR _backlerp$[esp+120-4];mm7 = framebacklerp | backlerp
	push		edi

	movd		mm4, DWORD PTR [eax+24]			;mm4 = 0 | ce->orig[2]
	pfsub		mm0, mm7					;mm0 = 1-framebacklerp | 1-backlerp
																
	movd		DWORD PTR _frontlerp$[esp+124], mm0	;frontlerp = 1-backlerp.
	psrlq		mm0, 32					;shift 1-framebacklerp down

	movd		DWORD PTR _framefrontlerp$[esp+124], mm0 ; framefrontlerp = 1-framebacklerp
	
; 437  : 	// move should be the delta back to the previous frame * backlerp
; 438  :    VectorSubtract (currententity->oldorigin, currententity->origin, delta);

; IGX. Copied from original Sin Optimization	
	pfsub		mm1, mm2                           	;mm1 = delta[1] (d1)| delta[0] (d0)
	pfsub		mm3, mm4					;mm3 = 0 | delta[2] (d2)
	
	movq		mm0, mm1                            ;mm0 <- mm1

	punpckldq	mm3, mm1                            ; d2 | d0
	mov		esi, DWORD PTR _pmdl$[esp+124-4]    ; *(pmdl)
	
assume esi:ptr dsinmdl_t
;; 439  : 
;; 440  : 	move[0] =  DotProduct(delta, currententity->mat[ 0 ]);	// forward
;; 441  : 	move[1] =  DotProduct(delta, currententity->mat[ 1 ]);	// left
;; 442  : 	move[2] =  DotProduct(delta, currententity->mat[ 2 ]);	// up
;; 443  : 

; offset(->mat) = +76
; IGX.  Copied from original Sin Optimization
	psrlq		mm0, 32                             ; d1 | --
	movq		mm2, QWORD PTR [eax+76]             ; currententity->mat[0,1]

	punpckldq	mm0, mm3                            ; d1 | d2
	movq		mm4, QWORD PTR [eax+76+8]           ; currententity->mat[2,3]

	pfmul		mm2, mm1                            ; M0*d0 | M1*d1
	movq		mm5, QWORD PTR [eax+76+16]          ; currententity->mat[4,5]

	pfmul		mm4, mm3                            ; M2*d2 | M3*d0
	movq		mm6, QWORD PTR [eax+76+24]          ; currententity->mat[6,7]

	pfmul		mm5, mm0                            ; M4*d1 | M5*d2
	movd		mm7, DWORD PTR [eax+76+32]          ; currententity->mat[8]

	pfmul		mm6, mm1                            ; M6*d0 | M7*d1
	pfacc		mm2, mm5                            ; (M0*d0+M1*d1) | (M4*d1+M5*d2)

	pfmul 	mm7, mm3                            ; M8*d2 | ---
	pfacc 	mm6, mm6                            ; (M6*d0+M7*d1)

	movd	   	mm5, DWORD PTR [esi].load_scale     ; pmdl->load_scale
	pfadd   	mm4, mm2                            ; (M0*d0+M1*d1+M2*d2) | (M4*d1+M5*d2+M3*d0)

	mov	   	edx, DWORD PTR _oldframe            ; *(oldframe)
	pfadd		mm6, mm7                            ; (M6*d0+M7*d1+M8*d2)
     
;; 444  :    VectorScale( oldframe->translate, currentscale*pmdl->load_scale, delta );

	movq		QWORD PTR _move$[esp+124], mm4    ; store move[0] & move[1]
	movd		mm4, DWORD PTR _currentscale      ; currentscale

	movd		DWORD PTR _move$[esp+124+8], mm6  ; store move[2]
	movq		mm6, QWORD PTR [edx+28]           ; oldframe->translate[1 | 0]


	punpckldq	mm5, mm5                          ; pmdl->load_scale | pmdl->load_scale
	xor		ebp, ebp

	punpckldq	mm4, mm4                          ; currentscale | currentscale
	movd		mm7, DWORD PTR [edx+28+8]         ; oldframe->translate[- | 2]

	pfmul		mm5, mm4                          ; pmdl->load_scale*currentscale | pmdl->load_scale*currentscale
	mov		eax, DWORD PTR _currentframe

	pfmul		mm6, mm5
	movq		QWORD PTR _delta$[esp+124], mm6   ; d0 | d1 

	pfmul		mm7, mm5
	movd		DWORD PTR _delta$[esp+124+8], mm7 ; d2 | ??

	mov		ecx, DWORD PTR _currentframe
	lea		edx, DWORD PTR [esi].load_origin  ; pmdl->load_origin

; 457  : 
; 458  : 	for (i=0 ; i<3 ; i++)

	mov		edi, DWORD PTR _oldframe
	lea		ecx, DWORD PTR [ecx+16]	; currentframe->scale[*]

$L51109:

; 459  : 	   {
; 460  : 		move[i] = framebacklerp*delta[i] +
; 461  :                 backlerp*move[i] +
; 462  :                 ((framefrontlerp*currentframe->translate[i])+pmdl->load_origin[i])*currentscale*pmdl->load_scale;
; 464  : 		backv[i] = framebacklerp*oldframe->scale[i]*currentscale*pmdl->load_scale;
; 463  : 		frontv[i] = framefrontlerp*currentframe->scale[i]*currentscale*pmdl->load_scale;

; IGX.  Compute move[i], backv[i], and frontv[i] using 3DNow!
	movd		mm0, DWORD PTR _framebacklerp$[esp+124-4]	;mm0 = 0 | framebacklerp
	punpckldq	mm0, mm0					;mm0 = framebacklerp | framebacklerp

	movq		mm6, QWORD PTR [edi+16]     		;mm6=oldframe->scale[1|0]
	movq		mm2, mm0					;mm2 <- mm0

	pfmul		mm2, mm5					;mm2=framebacklerp*currentscale*loadscale | same as top
	movd		mm7, DWORD PTR [edi+16+8]           ;mm7 = 0 | oldframe->scale[2]

	movq		mm1, mm0					;mm1 <- mm0
	movq		mm3, mm2					;mm3 <- mm2

	pfmul		mm2, mm6					;finish computation of backv[1|0]
	movq		QWORD PTR _backv$[esp+124],mm2	;backv[1|0] <- mm2

	pfmul		mm3, mm7					;finish computation of backv[2]
	movq		mm2, QWORD PTR [ecx]			;mm2 = currentframe->scale[1|0]

	movd		DWORD PTR _backv$[esp+124+8],mm3	;backv[2]<-mm3[31:0]
	movd		mm3, DWORD PTR [ecx+8]			;mm3=0|currentframe->scale[2]

	pfmul		mm2, mm5					;mm2 = oldframe->scale[1|0]*loadscale*curscale
	movd		mm6, DWORD PTR _framefrontlerp$[esp+124]	;mm6=0|ffl

	pfmul		mm3, mm5					;mm3 = 0|currentframe->scale[2]*loadscale*curscale
	punpckldq	mm6, mm6					;mm6 = ffl | ffl

	pfmul		mm2, mm6					;mm2 = finish computation of frontv[1|0]
	movq		QWORD PTR _frontv$[esp+124], mm2	;frontv[1|0] <- mm2
	 
	pfmul		mm3, mm6					;mm3 = finish computation of frontv[2]
	movq		mm2, QWORD PTR _delta$[esp+124]	;mm2 = delta[1|0]

	movd		DWORD PTR _frontv$[esp+124+8], mm3	;frontv[2]<-mm3[31:0]
	movd		mm3, DWORD PTR _delta$[esp+124+8]	;mm3 = 0|delta[2]

	pfmul		mm0, mm2					;mm0 = fbl*delta[1|0]
	movq		mm2, QWORD PTR [ecx+12]			;mm2 = cf->xlate[1|0]

	pfmul		mm1, mm3					;mm1 = 0 | fbl * delta[2]
	movd		mm3, DWORD PTR [ecx+12+8]		;mm3 = 0|cf->xlate[2]

	pfmul		mm2, mm6					;mm2 = ffl*cf->xlate[1|0]
	movd		mm7, DWORD PTR [edx+8]			;mm7 = 0 | pmdl->lo[2]

	pfmul		mm3, mm6					;mm3 = 0|ffl*cf->xlate[2]
	movq		mm6, QWORD PTR [edx]			;mm6 = pmdl->lo[1|0]

	pfadd		mm2, mm6					;mm2 = (ffl*cf->xlate[1|0])+pmdl->lo[1|0]
	movd		mm6, DWORD PTR _backlerp$[esp+124]	;mm6 = 0 | backlerp

	pfadd		mm3, mm7					;mm3 = 0 | (ffl*cf->xlate[2])+pmdl->lo[2]
	punpckldq	mm6, mm6					;mm6 = backlerp | backlerp

	pfmul		mm2, mm5					;mm2 = ((ffl*cf->xlate[1|0])+pmdl->lo[1|0]) *curscale*loadscale
	movq		mm4, QWORD PTR _move$[esp+124]	;mm4 = move[1|0]

	pfmul		mm3, mm5					;mm3 = 0 | ((ffl*cf->xlate[2])+pmdl->lo[2]) *curscale*loadscale
	movd		mm5, DWORD PTR _move$[esp+124+8]	;mm5 = 0 | move[2]

	pfmul		mm4, mm6					;mm4 = move[1|0]*backlerp
	pfadd		mm0, mm2					;mm0 = fbl*delta[1|0]+ ((ffl*cf->xlate[1|0])+pmdl->lo[1|0]) *curscale*loadscale

	pfmul		mm5, mm6					;mm5 = 0 | move[2]*backlerp
	pfadd		mm1, mm3					;mm1 = fbl*delta[2]+ ((ffl*cf->xlate[2])+pmdl->lo[2]) *curscale*loadscale

	pfadd		mm0, mm4					;mm0 = move[1|0]
	movq		QWORD PTR _move$[esp+124], mm0	;move[1|0] <- mm0

	pfadd		mm1, mm5					;mm1 = 0 | move[2]
	movd		DWORD PTR _move$[esp+124+8], mm1	;move[2]<-mm1[31:0]

	femms

; 453  : 	   }
; 454  : 
; 455  :    lerp = s_lerped[0];
; 456  : 
; 457  : 	SINMDL_LerpVerts( currentbase->num_xyz, currentverts, oldverts, currentverts, lerp, move, frontv, backv );

	lea		eax, DWORD PTR _backv$[esp+124]
	lea		ecx, DWORD PTR _frontv$[esp+124]
	push		eax
	mov		eax, DWORD PTR _currentverts
	lea		edx, DWORD PTR _move$[esp+128]
	push		ecx
	mov		ecx, DWORD PTR _oldverts
	push		edx
	mov		edx, DWORD PTR _currentbase
	push		OFFSET FLAT:_s_lerped
	push		eax
	push		ecx
	push		eax
	mov		eax, DWORD PTR [edx+8]
	push		eax
	call		_SINMDL_LerpVerts
	femms
    
; 657  : 
; 658  : 
; 659  :    // bind the right skin for this group
; 660  : 	// select skin
; 661  : 	if (currententity->skin)

	mov		edi, DWORD PTR _currententity
	add		esp, 32					; 00000020H
	mov		eax, DWORD PTR [edi+64]
	test		eax, eax
	je		SHORT $L43844

; 662  :       {
; 663  :       static image_t  *playerskins[ 2 ];
; 664  : 
; 665  :       skins = playerskins;
; 666  :       playerskins[ 0 ] = currententity->skin;

	mov		DWORD PTR _?playerskins@?3??SINMDL_DrawFrameLerp@@9@9$S43846, eax

; 667  :       playerskins[ 1 ] = currententity->damageskin;

	mov		ecx, DWORD PTR [edi+68]
	mov		DWORD PTR _skins$[esp+124], OFFSET FLAT:_?playerskins@?3??SINMDL_DrawFrameLerp@@9@9$S43846
	mov		DWORD PTR _?playerskins@?3??SINMDL_DrawFrameLerp@@9@9$S43846+4, ecx

; 668  :       }
; 669  : 	else

	jmp		SHORT $L43849
$L43844:		

; 670  : 	   {
; 671  :       if ( currententity->skinnum < MAX_MD2SKINS )

	mov		eax, DWORD PTR [edi+52]
	cmp		eax, 32					; 00000020H
	jge		SHORT $L43848

; 672  :          skins = &currentmodel->skins[ currententity->skinnum ];

	mov		edx, DWORD PTR _currentmodel
	lea		eax, DWORD PTR [edx+eax*4+240]
	mov		DWORD PTR _skins$[esp+124], eax

; 673  :       else

	jmp		SHORT $L43849
$L43848:

; 674  :          skins = &currentmodel->skins[ 0 ];

	mov		ecx, DWORD PTR _currentmodel
	add		ecx, 240				; 000000f0H
	mov		DWORD PTR _skins$[esp+124], ecx
$L43849:

; 675  :       }
; 676  : 
; 677  :    for (i=0;i<currentbase->num_groups;i++)

	mov		edx, DWORD PTR _currentbase
	mov		DWORD PTR _i$[esp+120], 0
	mov		eax, DWORD PTR [edx+16]
	test		eax, eax
	jle		$L43852
	jmp		SHORT $L43850
$L44269:
	mov		edi, DWORD PTR _currententity
$L43850:

; 678  :       {
; 679  :       dsintrigroup_t * pgroup;
; 680  : 
; 681  :       if (rendergroups[i] & MDL_GROUP_NODRAW)

	mov		eax, DWORD PTR _i$[esp+120]
	mov		ecx, DWORD PTR _rendergroups[eax*4]
	test		cl, -128				; ffffff80H
	jne		$L43851

; 682  :          continue;
; 683  : 
; 684  :       pgroup = &currentbase->groups[i];

	mov		ebp, eax

; 685  : 
; 686  :       c_alias_polys += pgroup->num_tris;

	mov		esi, DWORD PTR _c_alias_polys
	lea		eax, DWORD PTR [ebp+ebp*2]
	lea		eax, DWORD PTR [edx+eax*8+28]
	mov		DWORD PTR _pgroup$43853[esp+124], eax
	mov		edx, DWORD PTR [eax+4]
	add		esi, edx
	mov		DWORD PTR _c_alias_polys, esi

; 687  : 
; 688  :    	order = (int *)((byte *)pgroup + pgroup->ofs_glcmds);

	mov		esi, DWORD PTR [eax+12]
	add		esi, eax

; 689  : 
; 690  :       if ( gl_drawflat->value )

	mov		eax, DWORD PTR _gl_drawflat
	cmp		DWORD PTR [eax+20], 0
	je		$L43855
    
; 691  :          {
; 692  :          qglDisable (GL_TEXTURE_2D);

	push		3553					; 00000de1H
	call		DWORD PTR _qglDisable

; 693  :          // check for twosidedness
; 694  :          if (rendergroups[i] & MDL_GROUP_TWOSIDED)

	mov		eax, DWORD PTR _rendergroups[ebp*4]
	test		ah, -128				; ffffff80H
	je		SHORT $L44258

; 695  : 		      qglDisable(GL_CULL_FACE);

	push		2884					; 00000b44H
	call		DWORD PTR _qglDisable
$L44258:

; 697  :    	      {
; 698  : 		      // get the vertex count and primitive type
; 699  : 		      count = *order++;

	mov		ebx, DWORD PTR [esi]
	add		esi, 4

; 700  : 		      if (!count)

	test		ebx, ebx
	je		SHORT $L44215

; 701  : 			      break;		// done
; 702  : 		      if (count < 0)

	jge		SHORT $L43861

; 703  : 	   	      {
; 704  : 			      count = -count;

	neg		ebx

; 705  : 			      qglBegin (GL_TRIANGLE_FAN);

	push		6

; 706  : 		         }
; 707  : 		      else

	jmp		SHORT $L44272
$L43861:

; 708  :                {
; 709  : 			      qglBegin (GL_TRIANGLE_STRIP);

	push		5
$L44272:
	call		DWORD PTR _qglBegin
$L44259:

; 710  :                }
; 711  : 
; 712  : 			   do
; 713  : 			      {
; 714  :                int index;
; 715  :                float *c;
; 716  : 
; 717  : 				   index_xyz = order[2];
; 718  : 
; 719  :                if ( gl_drawflat->value == 1.0f )
			
	mov		ecx, DWORD PTR _gl_drawflat
	mov		edi, DWORD PTR [esi+8]
	cmp		DWORD PTR [ecx+20], 1065353216		; 3f800000H
	jne		SHORT $L43868

; 720  :                   {
; 721  :                   index = (((int)s_lerped[index_xyz])>>3)&0xff;

	mov		eax, edi
	shl		eax, 4
	add		eax, OFFSET FLAT:_s_lerped
	sar		eax, 3

; 722  :                   }
; 723  :                else

	jmp		SHORT $L44273
$L43868:

; 724  :                   {
; 725  :                   index = i & 0xff;

	mov		eax, ebp
$L44273:
	and		eax, 255				; 000000ffH

; 726  :                   }
; 727  :                c = &r_solidcolors[index*3];

	lea		edx, DWORD PTR [eax+eax*2]

; 728  : 
; 729  :                qglColor3f ( c[0],c[1],c[2] );

	mov		ecx, DWORD PTR _r_solidcolors[edx*4+8]
	lea		eax, DWORD PTR _r_solidcolors[edx*4]
	push		ecx
	mov		edx, DWORD PTR [eax+4]
	mov		eax, DWORD PTR [eax]
	push		edx
	push		eax
	call		DWORD PTR _qglColor3f

; 730  :                qglVertex3fv (s_lerped[index_xyz]);

	shl		edi, 4
	add		edi, OFFSET FLAT:_s_lerped
	push		edi
	call		DWORD PTR _qglVertex3fv

; 731  :                order += 3;

	add		esi, 12					; 0000000cH

; 732  : 			      } while (--count);

	dec		ebx
	jne		SHORT $L44259

; 733  : 		      qglEnd ();

;	call	DWORD PTR _qglEnd
	DCALL		_qglEnd, a1
; 696  : 	      while (1)

	jmp		SHORT $L44258
$L44215:

; 734  : 	         }
; 735  :          qglEnable (GL_TEXTURE_2D);

	push		3553					; 00000de1H
	call		DWORD PTR _qglEnable
$L44217:

; 956  : 	         }
; 957  :          }
; 958  :       if (gl_showtris->value)

;IGX.  Removed fp comparison.
	mov		eax, DWORD PTR _gl_showtris
	cmp		DWORD PTR [eax+20], 0
	je		$L43944
    
; 959  :          {
; 960  :          dsintriangle_t * ptri;
; 961  : 
; 962  :          ptri = (dsintriangle_t *)((byte *)pgroup + pgroup->ofs_tris);

	mov		ebx, DWORD PTR _pgroup$43853[esp+124]

; 963  : 
; 964  : 		   for (j=0 ; j<pgroup->num_tris ; j++, ptri++)

	xor		edi, edi
	mov		esi, DWORD PTR [ebx+16]
	mov		eax, DWORD PTR [ebx+4]
	add		esi, ebx
	test		eax, eax
	jle		$L43944
$L43942:

; 965  : 		      {
; 966  : 		      qglBegin (GL_LINE_STRIP);

	push		3
	call		DWORD PTR _qglBegin

; 967  :             qglColor4f (1,1,1,1);

	push		1065353216				; 3f800000H
	push		1065353216				; 3f800000H
	push		1065353216				; 3f800000H
	push		1065353216				; 3f800000H
	call		DWORD PTR _qglColor4f

; 968  :             qglVertex3fv (s_lerped[ptri->index_xyz[0]]);

	movsx		edx, WORD PTR [esi]
	shl		edx, 4
	add		edx, OFFSET FLAT:_s_lerped
	push		edx
	call		DWORD PTR _qglVertex3fv

; 969  :             qglVertex3fv (s_lerped[ptri->index_xyz[1]]);

	movsx		eax, WORD PTR [esi+2]
	shl		eax, 4
	add		eax, OFFSET FLAT:_s_lerped
	push		eax
	call		DWORD PTR _qglVertex3fv

; 970  :             qglVertex3fv (s_lerped[ptri->index_xyz[2]]);

	movsx		ecx, WORD PTR [esi+4]
	shl		ecx, 4
	add		ecx, OFFSET FLAT:_s_lerped
	push		ecx
	call		DWORD PTR _qglVertex3fv

; 971  :             qglVertex3fv (s_lerped[ptri->index_xyz[0]]);

	movsx		edx, WORD PTR [esi]
	shl		edx, 4
	add		edx, OFFSET FLAT:_s_lerped
	push		edx
	call		DWORD PTR _qglVertex3fv

; 972  : 		      qglEnd ();

	call		DWORD PTR _qglEnd
	mov		eax, DWORD PTR [ebx+4]
	inc		edi
	add		esi, 16					; 00000010H
	cmp		edi, eax
	jl		SHORT $L43942
$L43944:

; 973  : 	         }
; 974  :          }
; 975  :       if (rendergroups[i] & MDL_GROUP_TWOSIDED)

	mov		esi, DWORD PTR _i$[esp+120]
	mov		eax, DWORD PTR _rendergroups[esi*4]
	test		ah, -128				; ffffff80H
	je		SHORT $L43945

; 976  :          qglEnable(GL_CULL_FACE);

	push		2884					; 00000b44H
	call		DWORD PTR _qglEnable
$L43945:

; 977  :       if (rendergroups[i] & MDL_GROUP_MASKED)

	mov		eax, DWORD PTR _rendergroups[esi*4]
	test		ah, 64					; 00000040H
	je		SHORT $L43946

; 978  :          {
; 979  :          qglDisable (GL_ALPHA_TEST);

	push		3008					; 00000bc0H
	call		DWORD PTR _qglDisable

; 980  : 	      qglDepthMask (1);

	push		1	
	call		DWORD PTR _qglDepthMask

; 981  : 	      qglDisable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglDisable

; 982  :   	      GL_TexEnv( GL_REPLACE );

	push		7681					; 00001e01H
	call		_GL_TexEnv
	add		esp, 4
$L43946:

; 983  :          }
; 984  : 	   if (
; 985  :             ( !( currententity->flags & RF_TRANSLUCENT ) ) &&
; 986  :             (
; 987  :                (rendergroups[i] & MDL_GROUP_TRANSLUCENT_33) ||
; 988  :                (rendergroups[i] & MDL_GROUP_TRANSLUCENT_66)
; 989  :             )
; 990  :          )

	mov		eax, DWORD PTR _currententity
	test		BYTE PTR [eax+72], 32			; 00000020H
	jne		SHORT $L43851
	test		BYTE PTR _rendergroups[esi*4], 96	; 00000060H
	je		SHORT $L43851

; 991  :          {
; 992  : 	      qglDepthMask (1);

	push		1
	call		DWORD PTR _qglDepthMask

; 993  :      		qglDisable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglDisable
$L43851:
	mov		edx, DWORD PTR _currentbase
	mov		eax, DWORD PTR _i$[esp+120]
	inc		eax
	mov		ecx, DWORD PTR [edx+16]
	mov		DWORD PTR _i$[esp+120], eax
	cmp		eax, ecx
	jl		$L44269
$L43852:

; 994  :          }
; 995  :       }
; 996  : //   if ( locked && qglUnlockArraysEXT != 0 )
; 997  : //      qglUnlockArraysEXT();
; 998  :    }
	pop		edi
	pop		esi
	pop		ebp
	pop		ebx
	add		esp, 108				; 0000006cH
	ret		0
$L43855:

; 736  :          }
; 737  :       else if ( rendergroups[i] & (MDL_GROUP_ENVMAPPED_SILVER|MDL_GROUP_ENVMAPPED_GOLD) )

	test		cl, 24					; 00000018H
	je		$L43871

; 738  :          {
; 739  :          if (rendergroups[i] & MDL_GROUP_ENVMAPPED_SILVER)

	test		cl, 16					; 00000010H
	je		SHORT $L43872

; 740  :             {
; 741  :             // 2015 code
; 742  :             if(game2015->value)

;IGX removed fp comparison
	mov		eax, DWORD PTR _game2015
	cmp		DWORD PTR [eax+20], 0
	je		SHORT $L43873
    
; 743  :                {
; 744  :                // use the therm-optic goggles env map
; 745  :                if(currententity->lightofs && !(currententity->flags & RF_LIGHTOFFSET))

	mov		eax, DWORD PTR [edi+192]
	test		eax, eax
	je		SHORT $L43874
	mov		eax, DWORD PTR [edi+72]
	test		ah, 64					; 00000040H
	jne		SHORT $L43874

; 746  :                   GL_BindImage(r_gogglesmap);

	mov		edx, DWORD PTR _r_gogglesmap

; 747  :                else // use regular crome map

	jmp		SHORT $L44274
$L43874:

; 748  :                   GL_BindImage( r_envmap );

	mov		eax, DWORD PTR _r_envmap
	push		eax

; 749  :                }
; 750  :             else

	jmp		SHORT $L44275
$L43873:

; 751  :                {
; 752  :                GL_BindImage( r_envmap );

	mov		ecx, DWORD PTR _r_envmap
	push		ecx

; 753  :                }
; 754  :             }
; 755  :          else 

	jmp		SHORT $L44275
$L43872:

; 756  :             {
; 757  :  	         GL_BindImage( r_goldenvmap );

	mov		edx, DWORD PTR _r_goldenvmap
$L44274:
	push		edx
$L44275:
	call		_GL_BindImage

; 758  :             }
; 759  :          // check for twosidedness
; 760  :          if (rendergroups[i] & MDL_GROUP_TWOSIDED)

	mov		eax, DWORD PTR _rendergroups[ebp*4]
	add		esp, 4
	test		ah, -128				; ffffff80H
	je		SHORT $L43878

; 761  : 		      qglDisable(GL_CULL_FACE);

	push		2884					; 00000b44H
	call		DWORD PTR _qglDisable
$L43878:

; 762  : 	      if (currententity->flags & RF_TRANSLUCENT)

	mov		eax, DWORD PTR _currententity
	test		BYTE PTR [eax+72], 32			; 00000020H
	je		SHORT $L43879

; 763  :             {
; 764  : 		      alpha = currententity->alpha;

	mov		eax, DWORD PTR [eax+60]
	mov		DWORD PTR _alpha$[esp+120], eax

; 765  :             }
; 766  : 	      else

	jmp		$L43886
$L43879:

; 767  :             {
; 768  :             if (rendergroups[i] & MDL_GROUP_TRANSLUCENT_33)

	mov		eax, DWORD PTR _rendergroups[ebp*4]
	test		al, 32					; 00000020H
	je		SHORT $L43881

; 769  :                {
; 770  :                // 2015 code
; 771  :                if(rendergroups[i] & MDL_GROUP_TRANSLUCENT_66)

	test		al, 64					; 00000040H

; 772  :                   {
; 773  :                   qglDepthMask (0);

	push		0
	je		SHORT $L43882
	call		DWORD PTR _qglDepthMask

; 774  :                   qglEnable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglEnable

; 775  :                   alpha = currententity->alpha;

	mov		ecx, DWORD PTR _currententity
	mov		edx, DWORD PTR [ecx+60]
	mov		DWORD PTR _alpha$[esp+120], edx

; 776  :                   }
; 777  :                else

	jmp		SHORT $L43886
$L43882:

; 778  :                   {
; 779  :    	            qglDepthMask (0);

	call		DWORD PTR _qglDepthMask

; 780  :       		      qglEnable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglEnable

; 781  :                   alpha = 0.66f;

	mov		DWORD PTR _alpha$[esp+120], 1059648963	; 3f28f5c3H

; 782  :                   }
; 783  :                }
; 784  :             else if (rendergroups[i] & MDL_GROUP_TRANSLUCENT_66)

	jmp		SHORT $L43886
$L43881:
	test		al, 64					; 00000040H
	je		SHORT $L43885

; 785  :                {
; 786  :    	         qglDepthMask (0);

	push		0
	call		DWORD PTR _qglDepthMask

; 787  :       		   qglEnable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglEnable

; 788  :                alpha = 0.33f;

	mov		DWORD PTR _alpha$[esp+120], 1051260355	; 3ea8f5c3H

; 789  :                }
; 790  :             else

	jmp		SHORT $L43886
$L43885:

; 791  : 		         alpha = 1.0;

	mov		DWORD PTR _alpha$[esp+120], 1065353216	; 3f800000H
$L43886:

; 792  :             }
; 793  :          if (rendergroups[i] & MDL_GROUP_FULLBRIGHT || r_fullbright->value)

	test		BYTE PTR _rendergroups[ebp*4], 4
	jne		SHORT $L43888
	mov		eax, DWORD PTR _r_fullbright

; 795  :          else
; 796  :             plight = shadelight;

;IGX. Removed fp comparison.
	mov		DWORD PTR _plight$[esp+124], OFFSET FLAT:_shadelight
	cmp		DWORD PTR [eax+20], 0
	je		$L44260
    
$L43888:

; 794  :             plight = fullbright;

	mov		DWORD PTR _plight$[esp+124], OFFSET FLAT:_fullbright
$L44260:

; 799  :    	      {
; 800  : 		      // get the vertex count and primitive type
; 801  : 		      count = *order++;

	mov		eax, DWORD PTR [esi]
	add		esi, 4

; 802  : 		      if (!count)

	test		eax, eax
	mov		DWORD PTR _count$[esp+124], eax
	je		$L44217

; 803  : 			      break;		// done
; 804  : 		      if (count < 0)

	jge		SHORT $L43894

; 805  : 	   	      {
; 806  : 			      count = -count;

	neg		eax
	mov		DWORD PTR _count$[esp+124], eax

; 807  : 			      qglBegin (GL_TRIANGLE_FAN);

	push		6

; 808  : 		         }
; 809  : 		      else

	jmp		SHORT $L44276
$L43894:

; 810  :                {
; 811  : 			      qglBegin (GL_TRIANGLE_STRIP);

	push		5
$L44276:
	call		DWORD PTR _qglBegin
$L44261:

; 812  :                }
; 813  : 
; 814  : 			   do
; 815  : 			      {
; 816  :                int lightindex;
; 817  :                int oldlightindex;
; 818  :                int k;
; 819  :                vec3_t eye_normal;
; 820  :                vec3_t eye_vert;
; 821  :                vec3_t normal;
; 822  :                float two_nu, m, fx, fy, fz;
; 823  : 
; 824  : 
; 825  : 				   index_xyz = order[2];
	femms
	mov		ebp, DWORD PTR [esi+8]

; 826  : 				   lightindex = currentverts[index_xyz].lightnormalindex;

	mov		edx, DWORD PTR _currentverts
	xor		ecx, ecx

; 827  : 				   oldlightindex = oldverts[index_xyz].lightnormalindex;

	xor		eax, eax
	mov		cl, BYTE PTR [edx+ebp*4+3]
	lea		edx, DWORD PTR _normal$43904[esp+124]
	mov		edi, ecx
	mov		ecx, DWORD PTR _oldverts
	mov		ebx, 3
	mov		al, BYTE PTR [ecx+ebp*4+3]
	lea		ecx, DWORD PTR [edi+edi*2]
	lea		eax, DWORD PTR [eax+eax*2]
	lea		ecx, DWORD PTR _r_avertexnormals[ecx*4]
	lea		eax, DWORD PTR _r_avertexnormals[eax*4]
$L43910:

; 828  : 
; 829  :                for ( k=0; k<3; k++ )
; 830  :                   normal[k] = (r_avertexnormals[lightindex][k]*frontlerp)+(r_avertexnormals[oldlightindex][k]*backlerp);

;IGX. Perform normal calculations using 3DNow!
	movd		mm6, DWORD PTR _frontlerp$[esp+124]
	movd		mm0, DWORD PTR [ecx]
	    
	movd		mm7, DWORD PTR _backlerp$[esp+120]
	movd		mm1, DWORD PTR [eax]

	pfmul		mm0, mm6
	pfmul		mm1, mm7
	    
	add		eax, 4
	add		ecx, 4
	    
	pfadd		mm0, mm1
	   
	add		edx, 4
	dec		ebx
	movd		DWORD PTR [edx], mm0
	jne		SHORT $L43910
    
; 831  : 
; 832  : 		         eye_normal[0] = DotProduct(normal, sinmdl_transform[0]);
; 833  : 		         eye_normal[1] = DotProduct(normal, sinmdl_transform[1]);
; 834  : 		         eye_normal[2] = DotProduct(normal, sinmdl_transform[2]);
; 835  : 

;IGX.  Compute eye_normal[i], eye_vert[i] and normalize using 3DNow!

	movq		mm7, QWORD PTR _normal$43904[esp+124]	;mm7 = normal[1|0]
	  
	movq		mm0, QWORD PTR _sinmdl_transform+4	;mm0 = sinmdl_xform[0][1|0]
	movq		mm1, QWORD PTR _sinmdl_transform+20	;mm1 = sinmdl_xform[1][1|0]
	movq		mm2, QWORD PTR _sinmdl_transform+36	;mm2 = sinmdl_xform[2][1|0]
	    
	movd		mm6, DWORD PTR _normal$43904[esp+132]	;mm6 = 0 | normal[2]
	    
	pfmul		mm0, mm7					;mm0 = sinmdl_xform[0][1|0]*normal[1|0]
	movd		mm3, DWORD PTR _sinmdl_transform+12	;mm3 = 0 | sinmdl_xform[0][2]
	pfmul		mm1, mm7					;mm1 = sinmdl_xform[1][1|0]*normal[1|0]
	movd		mm4, DWORD PTR _sinmdl_transform+28	;mm4 = 0 | sinmdl_xform[1][2]
	pfmul		mm2, mm7					;mm2 = sinmdl_xform[2][1|0]*normal[1|0]
	movd		mm5, DWORD PTR _sinmdl_transform+44	;mm5 = sinmdl_xform[2][2]
	    
	pfacc		mm0,mm0					;mm0 = xform[0][0]*normal[0]+xform[0][1]*normal[1]| same
	pfmul		mm3, mm6					;mm3 = xform[0][2]*normal[2]
	pfacc		mm1,mm1					;mm1 = xform[1][0]*normal[0]+xform[1][1]*normal[1]| same
	pfmul		mm4, mm6					;mm4 = xform[1][2]*normal[2]
	pfacc		mm2,mm2					;mm2 = xform[2][0]*normal[0]+xform[2][1]*normal[1]| same
	pfmul		mm5, mm6					;mm5 = xform[2][2]*normal[2]
	    
	pfadd		mm0, mm3  					;mm0 = dc | dotproduct(normal,xform[0])
	pfadd		mm1, mm4					;mm1 = dc | dotproduct(normal,xform[1])
	pfadd		mm2, mm5					;mm2 = dc | dotproduct(normal,xform[2])
	    
	movd		DWORD PTR _eye_normal$43902[esp+124], mm0	;eyenormal[0] <-mm0[31:0]
	movd		DWORD PTR _eye_normal$43902[esp+128], mm1	;eyenormal[1] <-mm1[31:0]
	movd		DWORD PTR _eye_normal$43902[esp+132], mm2	;eyenormal[2] <-mm2[31:0]
	
; 836  :                eye_vert[0] = DotProduct(s_lerped[index_xyz], sinmdl_transform[0]) + sinmdl_transform[0][3];
; 837  :                eye_vert[1] = DotProduct(s_lerped[index_xyz], sinmdl_transform[1]) + sinmdl_transform[1][3];
; 838  :                eye_vert[2] = DotProduct(s_lerped[index_xyz], sinmdl_transform[2]) + sinmdl_transform[2][3];
; 839  : 
	    
	shl		ebp, 4
	mov		eax, ebp
	lea		ecx, DWORD PTR _eye_vert$43903[esp+124]
	lea		ebx, DWORD PTR _s_lerped[eax]
	    
	movq		mm7, QWORD PTR [ebx]			;mm7 = s_lerped[idx][1 | 0]
	movd		mm6, DWORD PTR _s_lerped[eax+8]	;mm6 = 0 | s_lerped[idx][2]
	    
	movq		mm0, QWORD PTR _sinmdl_transform+4	;mm0 = sinmdl_xform[0][1|0]
	movq		mm1, QWORD PTR _sinmdl_transform+20	;mm1 = sinmdl_xform[1][1|0]
	movq		mm2, QWORD PTR _sinmdl_transform+36	;mm2 = sinmdl_xform[2][1|0]
	
	pfmul		mm0, mm7					;mm0 = sinmdl_xform[0][1|0]*s_l[idx][1|0]
	movd		mm3, DWORD PTR _sinmdl_transform+12	;mm3 = 0 | sinmdl_xform[0][2]
	pfmul		mm1, mm7					;mm1 = sinmdl_xform[1][1|0]*s_l[idx][1|0]
	movd		mm4, DWORD PTR _sinmdl_transform+28	;mm4 = 0 | sinmdl_xform[1][2]
	pfmul		mm2, mm7					;mm2 = sinmdl_xform[2][1|0]*s_l[idx][1|0]
	movd		mm5, DWORD PTR _sinmdl_transform+44	;mm5 = sinmdl_xform[2][2]
	    
	pfacc		mm0,mm0	 				;mm0 = xform[0][0]*s_l[idx][0]+xform[0][1]*s_l[idx][1]| same
	pfmul		mm3, mm6					;mm3 = xform[0][2]*s_l[idx][2]
	pfacc		mm1,mm1					;mm1 = xform[1][0]*s_l[idx][0]+xform[1][1]*s_l[idx][1]| same
	pfmul		mm4, mm6					;mm4 = xform[1][2]*s_l[idx][2]
	pfacc		mm2,mm2					;mm2 = xform[2][0]*s_l[idx][0]+xform[2][1]*s_l[idx][1]| same
	pfmul		mm5, mm6					;mm5 = xform[2][2]*s_l[idx][2]
	    
	pfadd		mm0, mm3	 				;mm0 = dc | dotproduct(s_l[idx],xform[0])
	pfadd		mm1, mm4					;mm1 = dc | dotproduct(s_l[idx],xform[1])
	pfadd		mm2, mm5					;mm2 = dc | dotproduct(s_l[idx],xform[2])
	
	movd        mm3, DWORD PTR _sinmdl_transform+16	;mm3 = 0 | sinmdl_transform[0][3]
	movd        mm4, DWORD PTR _sinmdl_transform+32	;mm4 = 0 | sinmdl_transform[1][3]
	movd        mm5, DWORD PTR _sinmdl_transform+48	;mm5 = 0 | sinmdl_transform[2][3]
	
	pfadd		mm0, mm3	 				;mm0 = dc | dotproduct(s_l[idx],xform[0])+xform[0][3]
	pfadd		mm1, mm4					;mm1 = dc | dotproduct(s_l[idx],xform[1])+xform[1][3]
	pfadd		mm2, mm5					;mm2 = dc | dotproduct(s_l[idx],xform[2])+xform[2][3]
	
; 840  :                VectorNormalize( eye_vert );
	    
	; save eye_vert[0,1,2] for later
	movq		mm3, mm0	 				;mm3 <-mm0
	movq		mm4, mm1	 				;mm4 <-mm1
	movq		mm5, mm2	 				;mm5 <-mm2
	    
	pfmul		mm0, mm0	 				;mm0 = dc | eye_vert[0]^2
	pfmul		mm1, mm1	 				;mm1 = dc | eye_vert[1]^2 
	pfmul		mm2, mm2	 				;mm2 = dc | eye_vert[2]^2
	    
	pfadd		mm0, mm1	 				;mm0 = e_v[0]^2 + e_v[1]^2
	pfadd		mm0, mm2					;mm0 = e_v[0]^2 + e_v[1]^2 + e_v[2]^2
	    
	pfrsqrt	mm0, mm0					;mm0 = length of e_v = 1/(e_v[0]^2 + e_v[1]^2 + e_v[2]^2)^.5
	    
	pfmul		mm3, mm0					;mm3 = eye_vert[0]/(lenght of e_v)
	pfmul		mm4, mm0					;mm4 = eye_vert[1]/(lenght of e_v)
	pfmul		mm5, mm0					;mm5 = eye_vert[2]/(lenght of e_v)
	     
	movd		DWORD PTR _eye_vert$43903[esp+124], mm3	;e_v[0] = mm3[31:0]
	movd		DWORD PTR _eye_vert$43903[esp+128], mm4	;e_v[1] = mm4[31:0]
	movd		DWORD PTR _eye_vert$43903[esp+132], mm5	;e_v[2] = mm5[31:0]
     
; 841  :                two_nu = 2.0f * DotProduct( eye_normal, eye_vert );


;IGX.  Compute dot product and multiply using 3DNow!
	movq		mm2, QWORD PTR _eye_normal$43902[esp+124]	;mm2 = e_n[1 | 0]
	movd		mm3, DWORD PTR _eye_normal$43902[esp+132]	;mm3 = 0 | e_n[2]

	movq		mm0, QWORD PTR _eye_vert$43903[esp+124]	;mm0 = e_v[1 | 0]
	movd		mm1, DWORD PTR _eye_vert$43903[esp+132]	;mm1 = 0 | e_v[2]
	    
	movd		mm7, DWORD PTR [Float2]			;mm7 = 0.0 | 2.0
	    
	pfmul		mm0, mm2					;mm0 = e_v[1 | 0] * e_n[1 | 0]
	pfmul		mm1, mm3					;mm1 = e_v[2] * e_n[2]
	    
	pfacc		mm0, mm0					;mm0 = e_v[1] * e_n[1] + e_v[0] * e_n[0]
	pfadd		mm0, mm1					;mm0 = e_v[2] * e_n[2] + e_v[1] * e_n[1] + e_v[0] * e_n[0]
	    
	pfmul		mm0, mm7					;mm0 = dotproduct(e_n, e_v)*2.0
	    
	punpckldq	mm7, mm0					;mm7=two_nu | two_nu
    
; 842  :                fx = eye_vert[0] - eye_normal[0] * two_nu;
; 843  :                fy = eye_vert[1] - eye_normal[1] * two_nu;
; 844  :                fz = eye_vert[2] - eye_normal[2] * two_nu;


;IGX.  Compute fx,fy,and fz using 3DNow!
	movq		mm0, QWORD PTR _eye_vert$43903[esp+124]	;mm0 = e_v[1 | 0]
	movd		mm1, DWORD PTR _eye_vert$43903[esp+132]	;mm1 = 0 | e_v[2]

	pfmul		mm2, mm7					;mm2 = e_n[1 | 0]*two_nu
	pfmul		mm3, mm7					;mm3 = 0 | e_n[2] *two_nu
	    
	pfsub		mm0, mm2					;mm0 = fy | fx
	movd		mm6, DWORD PTR [FloatOne]		;mm6 = 0.0 | 1.0
	pfsub		mm1, mm3					;mm1 = 0 | fz
	    
	movq		mm2, mm0             			; save fy | fx
	movq		mm3, mm1		   			; save  - | fz
    
; 845  :                m = 2.0F * sqrt( fx*fx + fy*fy + (fz+1.0F)*(fz+1.0F) );
    
;IGX.  Compute m with 3DNow! instructions
    
	pfadd		mm1, mm6					;mm1 = - | fz+1.0
	    
	pfmul		mm0,mm0					;mm0 = fy^2 | fx^2
	movd		mm5, DWORD PTR [Float2]			;mm5 = 0 | 2.0
	pfmul		mm1, mm1					;mm1 = - |(fz+1.0)^2
	    
	pfacc		mm0, mm0					;mm0 = fx^2 + fy^2
	pfadd		mm0, mm1					;mm0 = fx^2 + fy^2 + (fz+1.0)^2
	    
	pfrsqrt	mm0, mm0					;mm0 = 1/(fx^2 + fy^2 + (fz+1.0)^2)^.5
	pfrcp		mm0, mm0					;mm0 = (fx^2 + fy^2 + (fz+1.0)^2)^.5
	pfmul		mm0, mm5	  				;mm0 = 2*(fx^2 + fy^2 + (fz+1.0)^2)^.5
    
    
; 846  :                if (m==0.0F)


;IGX.  Do comparison with 3DNow! instructions
	movd		DWORD PTR -100+[esp+124], mm0
	mov		eax, -100+[esp+124]
	cmp		eax, $T44250
	je		SHORT $L43913
      
; 847  :                   {
; 848  :       				qglTexCoord2f ( 0.5f, 0.5f );

	push		1056964608				; 3f000000H
	push		1056964608				; 3f000000H

; 849  :                   }
; 850  :                else

	jmp		SHORT $L44277
$L43913:

; 851  :                   {
; 852  :                   float mInv = 1.0F / m;

;IGX.  Compute mInv and call params for qglTexCoord2f with 3DNow!

	pfrcp		mm0, mm0     				;mm0 = - | mInv
	movq		mm1, QWORD PTR [Halfx2]			;mm1 =  0.5 | 0.5
	punpckldq	mm0, mm0					;mm0 = mInv | mInv 
	
	push		ecx						;make room on the stack
	
	pfmul		mm2, mm0					;mm2 = mInv*fy | mInv*fx
	pfadd		mm2, mm1					;mm2 = mInv * fy + 0.5 | mInv * fx + 0.5
	    
	movq		mm3, mm2					;mm3 <- mm2
	    
	psrlq		mm3, 32					;mm3 = 0 | mInv * fy + 0.5
	    
	movd		DWORD PTR [esp], mm3			;copy first argument onto stack
	
	push		ecx						;make room on the stack
	movd		DWORD PTR [esp], mm2			;copy the second argument onto the stack
	femms
; 853  :       				qglTexCoord2f ( fx * mInv + 0.5f, fy * mInv + 0.5F );

$L44277:
	DCALL		_qglTexCoord2f,a1

; 854  :                   }
; 855  :                // normals and vertexes come from the frame list
; 856  :                l = shadedots[lightindex];

	mov		edx, DWORD PTR _shadedots

; 857  :                qglColor4f (l* plight[0], l*plight[1], l*plight[2], alpha);

;IGX.  Compute qglColor4f parameters using 3DNow!
	femms
	movd		mm7, DWORD PTR [edx+edi*4]		;mm7 = 0 | l
	    
	mov		eax, DWORD PTR _plight$[esp+124]	;eax = &plight
	mov		ecx, DWORD PTR _alpha$[esp+120]	;ecx = alpha
	punpckldq	mm7, mm7					;mm7 = l | l		

	movd		mm0, DWORD PTR [eax +8]			;mm0 = 0 | plight[2]
	    
	push		ecx						;push alpha
	push		ecx						;make room on the stack
	   
	pfmul		mm0, mm7					;mm0 = - | l*plight[2]
	movq		mm1, QWORD PTR [eax]			;mm1 = plight[1] | plight[0]
	movd		DWORD PTR [esp], mm0			;put l*plight[2] on the stack
	    
	pfmul		mm1, mm7					;mm1 = l*plight[1] | l*plight[0]
	push		ecx						;make room on the stack for two entries
	movq		mm0, mm1					;mm0 <-mm1
	psrlq		mm0, 32					;mm0 = 0 | l*plight[1]    
	movd		DWORD PTR [esp], mm1			;move l*plight[1] onto the stack
	push		ecx						;make room on the stack
	movd		DWORD PTR [esp], mm0			;move l*plight[0] onto the stack

	femms
	DCALL		_qglColor4f, a1
	femms
; 858  : 
; 859  :                qglVertex3fv (s_lerped[index_xyz]);

	push		ebx
	call		DWORD PTR _qglVertex3fv

; 860  :                order += 3;
; 861  : 			      } while (--count);

	mov		eax, DWORD PTR _count$[esp+124]
	add		esi, 12					; 0000000cH
	dec		eax
	mov		DWORD PTR _count$[esp+124], eax
	jne		$L44261

; 862  : 
; 863  : 		      qglEnd ();

	call		DWORD PTR _qglEnd

; 797  : 
; 798  : 	      while (1)

	jmp		$L44260
$L43871:

; 864  : 	         }
; 865  : 
; 866  :          }
; 867  :       else
; 868  :          {
; 869  :          //
; 870  :          // get the skin
; 871  :          //
; 872  :          skin = skins[ ( rendergroups[ i ] & 0x3 ) ];

	mov		edx, DWORD PTR _skins$[esp+124]
	and		ecx, 3
	mov		ecx, DWORD PTR [edx+ecx*4]

; 873  : 	      if (!skin)

	test		ecx, ecx
	jne		SHORT $L43917

; 874  : 		      skin = r_notexture;	// fallback...

	mov		ecx, DWORD PTR _r_notexture
$L43917:

; 875  : 
; 876  : 	      GL_BindImage( skin );

	push		ecx
	call		_GL_BindImage

; 877  :          // check for twosidedness
; 878  :          if (rendergroups[i] & MDL_GROUP_TWOSIDED)

	mov		eax, DWORD PTR _rendergroups[ebp*4]
	add		esp, 4
	test		ah, -128				; ffffff80H
	je		SHORT $L43918

; 879  : 		      qglDisable(GL_CULL_FACE);

	push		2884					; 00000b44H
	call		DWORD PTR _qglDisable
$L43918:

; 880  :          // check for masked
; 881  :          if (rendergroups[i] & MDL_GROUP_MASKED)

	mov		eax, DWORD PTR _rendergroups[ebp*4]
	test		ah, 64					; 00000040H
	je		SHORT $L43919

; 882  :             {
; 883  : 	         qglDepthMask (0);

	push		0
	call		DWORD PTR _qglDepthMask

; 884  : 	         qglEnable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglEnable

; 885  :  	         GL_TexEnv( GL_MODULATE );

	push		8448					; 00002100H
	call		_GL_TexEnv
	add		esp, 4

; 886  : 	         qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	push		771					; 00000303H
	push		770					; 00000302H
	call		DWORD PTR _qglBlendFunc
$L43919:

; 887  :             }
; 888  : 	      if (currententity->flags & RF_TRANSLUCENT)

	mov		eax, DWORD PTR _currententity
	test		BYTE PTR [eax+72], 32			; 00000020H
	je		SHORT $L43920

; 889  :             {
; 890  : 		      alpha = currententity->alpha;

	mov		eax, DWORD PTR [eax+60]
	mov		DWORD PTR _alpha$[esp+120], eax

; 891  :             }
; 892  : 	      else

	jmp		$L43927
$L43920:

; 893  :             {
; 894  :             if (rendergroups[i] & MDL_GROUP_TRANSLUCENT_33)

	mov		eax, DWORD PTR _rendergroups[ebp*4]
	test		al, 32					; 00000020H
	je		SHORT $L43922

; 895  :                {
; 896  :                // 2015 code
; 897  :                if(rendergroups[i] & MDL_GROUP_TRANSLUCENT_66)

	test		al, 64					; 00000040H

; 898  :                   {
; 899  :                   qglDepthMask (0);

	push		0
	je		SHORT $L43923
	call		DWORD PTR _qglDepthMask

; 900  :                   qglEnable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglEnable

; 901  :                   alpha = currententity->alpha;

	mov		ecx, DWORD PTR _currententity
	mov		edx, DWORD PTR [ecx+60]
	mov		DWORD PTR _alpha$[esp+120], edx

; 902  :                   }  
; 903  :                else

	jmp		SHORT $L43927
$L43923:

; 904  :                   {
; 905  :    	            qglDepthMask (0);

	call		DWORD PTR _qglDepthMask

; 906  :       		      qglEnable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglEnable

; 907  :                   alpha = 0.66f;

	mov		DWORD PTR _alpha$[esp+120], 1059648963	; 3f28f5c3H

; 908  :                   }
; 909  :                }
; 910  :             else if (rendergroups[i] & MDL_GROUP_TRANSLUCENT_66)

	jmp		SHORT $L43927
$L43922:
	test		al, 64					; 00000040H
	je		SHORT $L43926

; 911  :                {
; 912  :    	         qglDepthMask (0);

	push		0
	call		DWORD PTR _qglDepthMask

; 913  :       		   qglEnable (GL_BLEND);

	push		3042					; 00000be2H
	call		DWORD PTR _qglEnable

; 914  :                alpha = 0.33f;

	mov		DWORD PTR _alpha$[esp+120], 1051260355	; 3ea8f5c3H

; 915  :                }
; 916  :             else

	jmp		SHORT $L43927
$L43926:

; 917  : 		         alpha = 1.0;

	mov		DWORD PTR _alpha$[esp+120], 1065353216	; 3f800000H
$L43927:

; 918  :             }
; 919  :          if (rendergroups[i] & MDL_GROUP_FULLBRIGHT || r_fullbright->value)

	test		BYTE PTR _rendergroups[ebp*4], 4
	jne		SHORT $L43929
	mov		eax, DWORD PTR _r_fullbright

; 921  :          else
; 922  :             plight = shadelight;

;IGX.  Get rid of fp comparison.
	mov		ebp, OFFSET FLAT:_shadelight
	cmp		DWORD PTR [eax+20], 0
	je		SHORT $L44263
	
$L43929:

; 920  :             plight = fullbright;

	mov		ebp, OFFSET FLAT:_fullbright
$L44263:

; 925  :    	      {
; 926  : 		      // get the vertex count and primitive type
; 927  : 		      count = *order++;

	mov		ebx, DWORD PTR [esi]
	add		esi, 4

; 928  : 		      if (!count)

	test		ebx, ebx
	je		$L44217

; 929  : 			      break;		// done
; 930  : 		      if (count < 0)

	jge		SHORT $L43935

; 931  : 	   	      {
; 932  : 			      count = -count;

	neg		ebx

; 933  : 			      qglBegin (GL_TRIANGLE_FAN);

	push		6

; 934  : 		         }
; 935  : 		      else

	jmp		SHORT $L44278
$L43935:

; 936  :                {
; 937  : 			      qglBegin (GL_TRIANGLE_STRIP);

	push		5
$L44278:
	call		DWORD PTR _qglBegin
$L44239:

; 938  :                }
; 939  : 
; 940  : 			   do
; 941  : 			      {
; 942  : 				   index_xyz = order[2];
; 943  : 
; 944  : 				   // texture coordinates come from the draw list
; 945  : 				   qglTexCoord2f (((float *)order)[0], ((float *)order)[1]);

	mov		ecx, DWORD PTR [esi+4]
	mov		edx, DWORD PTR [esi]
	mov		edi, DWORD PTR [esi+8]
	push		ecx
	push		edx
	call		DWORD PTR _qglTexCoord2f

; 946  : 
; 947  :                // normals and vertexes come from the frame list
; 948  :                l = shadedots[ currentverts[ index_xyz ].lightnormalindex ];

	mov		ecx, DWORD PTR _currentverts
	mov		edx, DWORD PTR _shadedots
	xor		eax, eax
	mov		al, BYTE PTR [ecx+edi*4+3]
    
    
    

; 949  :                qglColor4f (l* plight[0], l*plight[1], l*plight[2], alpha);
	
	
;IGX.  Compute qglColor4f parameters using 3DNow!	
	femms
	movd		mm7, DWORD PTR [edx+eax*4]		;mm7 = 0 | l
	    
	mov		ecx, DWORD PTR _alpha$[esp+120]	;ecx = alpha
	punpckldq	mm7, mm7					;mm7 = l | l		

	movd		mm0, DWORD PTR [ebp +8]			;mm0 = 0 | plight[2]
	    
	push		ecx						;push alpha
	push		ecx						;make room on the stack
	   
	pfmul		mm0, mm7					;mm0 = - | l*plight[2]
	movq		mm1, QWORD PTR [ebp]			;mm1 = plight[1] | plight[0]
	movd		DWORD PTR [esp], mm0			;put l*plight[2] on the stack
	    
	pfmul		mm1, mm7					;mm1 = l*plight[1] | l*plight[0]
	push		ecx						;make room on the stack for two entries
	movq		mm0, mm1					;mm0 <-mm1
	psrlq		mm0, 32					;mm0 = 0 | l*plight[1]    
	movd		DWORD PTR [esp], mm1			;move l*plight[1] onto the stack
	push		ecx						;make room on the stack
	movd		DWORD PTR [esp], mm0			;move l*plight[0] onto the stack

	femms
	call		DWORD PTR _qglColor4f
	femms
; 950  : 
; 951  :                qglVertex3fv (s_lerped[index_xyz]);

	shl		edi, 4
	add		edi, OFFSET FLAT:_s_lerped
	push		edi
	call		DWORD PTR _qglVertex3fv

; 952  :                order += 3;

	add		esi, 12					; 0000000cH

; 953  : 			      } while (--count);

	dec		ebx
	jne		SHORT $L44239

; 954  : 
; 955  : 		      qglEnd ();

	call		DWORD PTR _qglEnd

; 923  : 
; 924  : 	      while (1)

	jmp		$L44263

ifdef	DIRECT_API_CALLS

SINMDL_DFL_CvtIndCalls:
	lea		eax, _SINMDL_DrawFrameLerpEnd
	lea		edx, _SINMDL_DrawFrameLerp
	sub		eax, edx
	push		eax
	push		edx

	call		_Sys_MakeCodeWriteable
	add		esp, 8

	lea		eax, _qglTexCoord2f
	lea		edx, D_qglTexCoord2fa1
	call		ProcAddrWorm

	lea		eax, _qglColor4f
	lea		edx, D_qglColor4fa1
	call		ProcAddrWorm

	lea		eax, _qglEnd
	lea		edx, D_qglEnda1
	call		ProcAddrWorm

	mov		_SINMDL_DFL_InitFlag, -1
	jmp		_SINMDL_DrawFrameLerp
endif
_SINMDL_DrawFrameLerpEnd	label	byte
_SINMDL_DrawFrameLerp ENDP
_TEXT	ENDS

ifdef SIN

PUBLIC	_DrawGLPoly
EXTRN	__fltused:NEAR

CONST	SEGMENT
$T51472	DD	000000000r			; 0
$T51473	DD	040000000r			; 2
$T51474	DD	0bf800000r			; -1
     ORG $+4
$T51475	DQ	04000000000000000r		; 2
$T51476	DD	03f800000r			; 1
$T51477	DD	0bf000000r			; -0.5
CONST	ENDS

_DATA	SEGMENT
_DrawGLPoly_InitFlag dd 0
_DATA	ENDS

;	COMDAT _DrawGLPoly
_TEXT	SEGMENT

align  32

_DrawGLPoly PROC NEAR					; COMDAT

        cmp     _DrawGLPoly_InitFlag, -1
        jne     _DrawGLPoly_CvtIndCalls

; 352  : 	int		i;
; 353  : 	float  	*v;

_s$ = 8
_eye_normal$50984 = -48
_eye_vert$50985 = -60
_normal$50986 = -60
_transform$50987 = -36

; 354  : #ifdef SIN
; 355  :    glpoly_t *p = s->polys;
; 356  : 
; 357  :    if (gl_drawflat->value)

     mov	 eax, DWORD PTR _gl_drawflat
     sub	 esp, 60			; 0000003cH
     mov         eax, [eax+20]
     push	 ebx
     mov	 ebx, DWORD PTR _s$[esp+60]
     push	 ebp
     push	 esi
     push	 edi
     mov	 edi, DWORD PTR [ebx+44]
     add         eax, eax
     jz 	 $L50976

; 358  :      {
; 359  :      int    index = (((int)s>>3)&0xff);
; 360  :      float  *c = &r_solidcolors[index*3];

     sar	 ebx, 3
     and	 ebx, 255		; 000000ffH

; 361  :      //
; 362  :      // solid poly
; 363  :      //
; 364  :      qglDisable (GL_TEXTURE_2D);

     push	 3553			; 00000de1H
     lea	 ecx, DWORD PTR [ebx+ebx*2]
     lea	 esi, DWORD PTR _r_solidcolors[ecx*4]
     call	 DWORD PTR _qglDisable

; 365  : 
; 366  :      qglBegin (GL_POLYGON);

     push	 9
     call	 DWORD PTR _qglBegin

; 367  :      v = p->verts[0];
; 368  :      for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)

     mov	 eax, DWORD PTR [edi+8]
     xor	 ebx, ebx
     test	 eax, eax
     lea	 ebp, DWORD PTR [edi+16]
     jle	 SHORT $L50981

$L50979:

; 369  :         {
; 370  :         qglColor3f ( c[0],c[1],c[2] );

     mov	 edx, DWORD PTR [esi+8]
     mov	 eax, DWORD PTR [esi+4]
     mov	 ecx, DWORD PTR [esi+0]
     push	 edx
     push	 eax
     push	 ecx
     call	 DWORD PTR _qglColor3f

; 371  :         qglVertex3fv (v);

     push	 ebp
     call	 DWORD PTR _qglVertex3fv
     mov	 eax, DWORD PTR [edi+8]
     inc	 ebx
     add	 ebp, 28			; 0000001cH
     cmp	 ebx, eax
     jl	 SHORT $L50979
$L50981:

; 372  :         }
; 373  :      qglEnd ();

     call	 DWORD PTR _qglEnd

     push	 3553			; 00000de1H

; 374  :      qglColor3f ( 1.0,1.0,1.0 );

     push	 1065353216		; 3f800000H
     push	 1065353216		; 3f800000H
     push	 1065353216		; 3f800000H
     call	 DWORD PTR _qglColor3f

; 375  :      qglEnable (GL_TEXTURE_2D);

     call	 DWORD PTR _qglEnable

; 434  :       }
; 435  : #else
; 436  :   	qglBegin (GL_POLYGON);
; 437  : 	v = p->verts[0];
; 438  : 	for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
; 439  : 	{
; 440  : 		qglTexCoord2f (v[3], v[4]);
; 441  : 		qglVertex3fv (v);
; 442  : 	}
; 443  : 	qglEnd ();
; 444  : #endif
; 445  :    }
	 femms
     pop	 edi
     pop	 esi
     pop	 ebp
     pop	 ebx
     add	 esp, 60			; 0000003cH
     ret	 0
$L50976:

; 376  :       }
; 377  :    else if (s->texinfo->flags & SURF_ENVMAPPED)

     mov	 edx, DWORD PTR [ebx+56]
     test	 DWORD PTR [edx+32], 2097152 ; 00200000H
     je 	 $L50983

; 378  :       {
; 379  :       vec3_t eye_normal;
; 380  :       vec3_t eye_vert;
; 381  :       vec3_t normal;
; 382  :       vec3_t transform[3];
; 383  :       float two_nu, m, fx, fy, fz;
; 384  : 
; 385  :       if ( s->flags & SURF_PLANEBACK )

     femms

     mov	 al, BYTE PTR [ebx+8]
     mov	 ebx, DWORD PTR [ebx+4]

     movq	 mm5, qword ptr [ebx]
     test	 al, 2

     movd	 mm6, dword ptr [ebx+8]
     nop

     movq        mm4, $ChsBoth
     je 	 SHORT $LLL50993

; 386  :          VectorNegate(s->plane->normal, normal);

     pxor        mm5, mm4
     pxor        mm6, mm4

$LLL50993:

; 388  :          VectorCopy(s->plane->normal, normal);

     movq        qword ptr _normal$50986[esp+76], mm5
     movd        dword ptr _normal$50986[esp+84], mm6

; 389  : 
; 390  : 	   VectorCopy (vright, transform[0]);
; 391  : 	   VectorNegate (vup, transform[1]);
; 392  : 	   VectorCopy (vpn, transform[2]);

     movq        mm0, qword ptr [_vright]
     punpckldq   mm6, mm5

     movd        mm1, dword ptr [_vright+8]
     movq        qword ptr _transform$50987[esp+76], mm0

     movd        mm7, dword ptr [_vup]

     movq        mm2, qword ptr [_vup+4]
     pxor        mm7, mm4

     movq        mm3, qword ptr [_vpn]
     pxor        mm2, mm4

     movd        mm4, dword ptr [_vpn+8]
     punpckldq   mm1, mm7

     movq        qword ptr _transform$50987[esp+76+8], mm1
     movq        mm7, mm5

; 394  : 		eye_normal[0] = DotProduct(normal, transform[0]);
; 395  : 		eye_normal[1] = DotProduct(normal, transform[1]);
; 396  : 		eye_normal[2] = DotProduct(normal, transform[2]);

; Superfast 3x3 x 3x1 matrix-vector multiply.

     pfmul       mm0, mm5
     punpckhdq   mm7, mm7

     pfmul       mm1, mm6
     punpckldq   mm7, mm6

     movq        qword ptr _transform$50987[esp+76+16], mm2
     pfmul       mm2, mm7

     movq        qword ptr _transform$50987[esp+76+24], mm3
     pfmul       mm3, mm5

     movd        dword ptr _transform$50987[esp+76+32], mm4
     pfacc       mm0, mm2

     pfmul       mm4, mm6
     pfacc       mm3, mm3

     pfadd       mm0, mm1
     movq        qword ptr _eye_normal$50984[esp+76], mm0

     pfadd       mm3,  mm4
     movq        qword ptr _eye_normal$50984[esp+84], mm3

     femms

     push	 9
     call	 DWORD PTR _qglBegin

     mov	 eax, DWORD PTR [edi+8]
     lea	 esi, DWORD PTR [edi+16]		; esi == v
     test	 eax, eax
     mov	 ebx, 0
     jle	 $L51004

$L50995:

; 398  :       qglBegin (GL_POLYGON);
; 399  :       v = p->verts[0];
; 400  :       for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
; 401  :          {
; 402  : 		   eye_vert[0] = DotProduct(v, transform[0]) - r_origin[0];
; 403  : 		   eye_vert[1] = DotProduct(v, transform[1]) - r_origin[1];
; 404  : 		   eye_vert[2] = DotProduct(v, transform[2]) - r_origin[2];

     femms

     movq        mm5, qword ptr [esi+0]
     nop

     movd        mm6, dword ptr [esi+8]
     movq        mm7, mm5

     punpckldq   mm6, mm5
     punpckhdq   mm7, mm7

     movq	 mm0, QWORD PTR _transform$50987[esp+76]
     punpckldq   mm7, mm6

     pfmul       mm0, mm5
     movq	 mm2, QWORD PTR _transform$50987[esp+76+16]

     pfmul       mm2, mm7
     movq	 mm1, QWORD PTR _transform$50987[esp+76+8]

     pfmul       mm1, mm6
     movq	 mm3, QWORD PTR _transform$50987[esp+76+24]

     pfmul       mm3, mm5
     movd	 mm4, DWORD PTR _transform$50987[esp+76+32]

     pfacc       mm0, mm2
     pfmul       mm4, mm6

     pfacc       mm3, mm3
     nop

     pfadd       mm0, mm1
     movq        mm1, qword ptr [_r_origin]

     pfadd       mm3, mm4
     movd        mm2, dword ptr [_r_origin+8]

     pfsub       mm0, mm1
     movq        qword ptr _eye_vert$50985[esp+76], mm0

     pfsub       mm3, mm2
     movd        dword ptr _eye_vert$50985[esp+76+8], mm3

     movq        mm1, mm0
     pfmul       mm0, mm0

     movq        mm2, mm3
     pfmul       mm3, mm3

     pfacc       mm0, mm0
     movq        mm4, qword ptr _eye_normal$50984[esp+76]

     pfadd       mm0, mm3
     movd        mm5, dword ptr _eye_normal$50984[esp+84]

     movq        mm3, mm4
     pfmul       mm4, mm1

     pfmul       mm5, mm2                               ; 
     pfrsqrt     mm6, mm0                               ; 1/|ev| 15 bits

     movq        mm7, mm6
     movd        mm4, dword ptr _eye_normal$50984[esp+84]

     pfadd       mm5, mm4
     pfmul       mm6, mm6

     sub         esp, 8
     nop

     pfrsqit1    mm6, mm0
     pfadd       mm5, mm5

     nop
     nop

     pfrcpit2    mm6, mm7                               ; 1/|ev|         = | =
     movq        mm7, Float_1                           ; 1.0

     nop
     nop

     pfmul       mm5, mm6                               ; two_nu
     nop

     pfmul       mm2, mm6                               ; ev[2]
     nop

     pfmul       mm4, mm5                               ; en*tn
     nop

     pfmul       mm1, mm6                               ; ev[0] ev[1]
     pfadd       mm2, mm7                               ; ev[2] + 1.0

     pfmul       mm3, mm5                               ; en*tn
     movq        mm7, qword ptr fqZero                  ; 0 | 0

     pfsub       mm2, mm4                               ; fz + 1.0
     movq        mm5, qword ptr Halfx2                  ; 0.5 | 0.5

     pfsub       mm1, mm3                               ; fxy
     nop

     pfmul       mm2, mm2                               ; (fz + 1.0)^2
     movq        mm4, mm1                               ; fxy

     pfmul       mm1, mm1                               ; fx^2 fy^2
     nop

     nop
     nop

     pfacc       mm1, mm1
     nop

     nop
     nop

     pfadd       mm1, mm2                               ; fx^2+fy^2+(fz+1)^2
     nop

     nop
     nop

     pfcmpeq     mm0, mm1                               ; 0 == |f+(0,0,1)|^2 ?
     pfrsqrt     mm2, mm1                               ; m = 1/sqrt_15( " )

     nop
     nop

     movq        mm3, mm2
     pfmul       mm2, mm2

; Further iterations of the square root calculator may be unecessary.  I leave
; this to ritual to decide whether or not they want to remove them.

     pfrsqit1    mm2, mm1
     movd        eax, mm0

     test        eax, eax
     jnz         short $LCoordOutput

     pfrcpit1    mm2, mm3
     nop

     nop
     nop

     pfmul       mm2, mm5
     nop

     nop
     nop

     pfmul       mm2, mm4
     nop

     nop
     nop

     pfadd       mm5, mm2

$LCoordOutput:

     movq        qword ptr [esp], mm5

     femms
     call	 DWORD PTR _qglTexCoord2f
     femms

; 419  :             }
; 420  :          qglVertex3fv (v);

     push	 esi
     call	 DWORD PTR _qglVertex3fv
     mov	 eax, DWORD PTR [edi+8]
     inc	 ebx
     add	 esi, 28			; 0000001cH
     cmp	 ebx, eax
     jl 	 $L50995

; 432  :          }
; 433  :       qglEnd ();

     call	 DWORD PTR _qglEnd

     pop	 edi
     pop	 esi
     pop	 ebp
     pop	 ebx
     add	 esp, 60			; 0000003cH
     ret	 0
$L50983:

; 421  :          }
; 422  :       qglEnd ();
; 423  :       }
; 424  :    else
; 425  :       {
; 426  :       qglBegin (GL_POLYGON);

     push	 9
     call	 DWORD PTR _qglBegin

; 427  :       v = p->verts[0];
; 428  :       for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)

     mov         ebp, DWORD PTR [edi+8]
     lea	 esi, DWORD PTR [edi+16]

     test	 ebp, ebp
     jle	 SHORT $L51004

     mov	 ecx, DWORD PTR [ebx+56]
     mov	 edi, DWORD PTR [ecx+44]

     femms

$L51002:

; 429  :          {
; 430  :          qglTexCoord2f (v[3] + s->texinfo->s->surfinfo->delta_s, v[4] + s->texinfo->s->surfinfo->delta_t);

     push	 esi                                    ; v
     movq        mm0, qword ptr [esi+12]                ; v[3],[4]

     sub         esp, 8
     movq        mm1, qword ptr [edi+144]               ; s->...->delta_s,delta_t

     add	 esi, 28				; VERTEXSIZE == 0000001cH
     pfadd       mm0, mm1

     movq        qword ptr [esp], mm0

     femms

     DCALL	 _qglTexCoord2f,b1

; 431  :          qglVertex3fv (v);

;     DCALL	 _qglVertex3fv,b1
     call 	 dword ptr _qglVertex3fv

     sub         ebp, 1                                 ; i++;
     jg 	 SHORT $L51002                          ; i < p->numberts ?
$L51004:

; 432  :          }
; 433  :       qglEnd ();

     femms

     call	 DWORD PTR _qglEnd

     pop	 edi
     pop	 esi
     pop	 ebp
     pop	 ebx
     add	 esp, 60			; 0000003cH
     ret	 0

ifdef	DIRECT_API_CALLS

_DrawGLPoly_CvtIndCalls:
     lea	eax, _DrawGLPolyEnd
     lea	edx, _DrawGLPoly
     sub	eax, edx
     push	eax
     push	edx

     call	_Sys_MakeCodeWriteable
     add	esp, 8

ifdef NEVER
     lea	eax, _qglVertex3fv
     lea	edx, D_qglVertex3fvb1
     call	ProcAddrWorm
endif

     lea	eax, _qglTexCoord2f
     lea	edx, D_qglTexCoord2fb1
     call	ProcAddrWorm

     mov	_DrawGLPoly_InitFlag, -1
     jmp	_DrawGLPoly

endif

_DrawGLPolyEnd	label	byte
_DrawGLPoly ENDP
_TEXT	ENDS

endif

PUBLIC	_DrawGLPolyChain
;	COMDAT _DrawGLPolyChain
_TEXT	SEGMENT
_p$ = 8
_soffset$ = 12
_toffset$ = 16

align  32

_DrawGLPolyChain PROC NEAR				; COMDAT

; 513  : 	if ( soffset == 0 && toffset == 0 )

     mov         eax, DWORD PTR _soffset$[esp-12+8]
     push	 ebx

     or          eax, DWORD PTR _toffset$[esp-8+8]
     push	 esi

     push	 edi

     add	 eax, eax
     jne         SHORT $LDGLPC51062
     
; 514  : 	{
; 515  : 		for ( ; p != 0; p = p->chain )

     mov	 edi, DWORD PTR _p$[esp+8]
     test	 edi, edi
     je 	 $LDGLPC51074
$LDGLPC51063:

; 516  : 		{
; 517  : 			float *v;
; 518  : 			int j;
; 519  : 
; 520  : 			qglBegin (GL_POLYGON);

     push	 9
     call	 DWORD PTR _qglBegin

; 521  : 			v = p->verts[0];
; 522  : 			for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)

     mov	 eax, DWORD PTR [edi+8]
     xor	 ebx, ebx
     test	 eax, eax
     lea	 esi, DWORD PTR [edi+16]
     jle	 SHORT $LDGLPC51070
$LDGLPC51068:

; 523  : 			{
; 524  : 				qglTexCoord2f (v[5], v[6] );

     push	 esi
     mov	 eax, DWORD PTR [esi+24]

     mov	 ecx, DWORD PTR [esi+20]
     push	 eax

     push	 ecx
     call	 DWORD PTR _qglTexCoord2f

; 525  : 				qglVertex3fv (v);

     call	 DWORD PTR _qglVertex3fv

     mov	 eax, DWORD PTR [edi+8]
     inc	 ebx

     add	 esi, 28			; 0000001cH
     cmp	 ebx, eax
     jl 	 SHORT $LDGLPC51068
$LDGLPC51070:

; 526  : 			}
; 527  : 			qglEnd ();

     call	 DWORD PTR _qglEnd
     mov	 edi, DWORD PTR [edi+4]
     test	 edi, edi
     jne	 SHORT $LDGLPC51063

; 545  : 		}
; 546  : 	}
; 547  : }

     pop	 edi
     pop	 esi
     pop	 ebx
     ret	 0
$LDGLPC51062:

; 528  : 		}
; 529  : 	}
; 530  : 	else
; 531  : 	{
; 532  : 		for ( ; p != 0; p = p->chain )

     mov	 edi, DWORD PTR _p$[esp+8]
     test	 edi, edi
     je 	 SHORT $LDGLPC51074
$LDGLPC51072:

; 533  : 		{
; 534  : 			float *v;
; 535  : 			int j;
; 536  : 
; 537  : 			qglBegin (GL_POLYGON);

     push	 9
     call	 DWORD PTR _qglBegin

     femms

; 538  : 			v = p->verts[0];
; 539  : 			for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)

     mov	 eax, DWORD PTR [edi+8]
     xor	 ebx, ebx
     test	 eax, eax
     lea	 esi, DWORD PTR [edi+16]
     jle	 SHORT $LDGLPC51079

if (_soffset$+4-_toffset$)
.err <_soffset$ and _toffset$ must be adjacent DWORDs>
endif

$LDGLPC51077:

; 540  : 			{
; 541  : 				qglTexCoord2f (v[5] - soffset, v[6] - toffset );

     movq        mm0, qword ptr [esi+20]

     movq        mm1, qword ptr _soffset$[esp+8]

     pfsub       mm0, mm1
     push        esi

     sub         esp, 8
     movq        qword ptr [esp], mm0

     call	 DWORD PTR _qglTexCoord2f

     call	 DWORD PTR _qglVertex3fv

     mov	 eax, DWORD PTR [edi+8]
     inc	 ebx
     add	 esi, 28			; 0000001cH
     cmp	 ebx, eax
     jl 	 SHORT $LDGLPC51077
$LDGLPC51079:

; 543  : 			}
; 544  : 			qglEnd ();

     call	 DWORD PTR _qglEnd
     mov	 edi, DWORD PTR [edi+4]
     test	 edi, edi
     jne	 SHORT $LDGLPC51072
$LDGLPC51074:

; 545  : 		}
; 546  : 	}
; 547  : }

     pop	 edi
     pop	 esi
     pop	 ebx
     ret	 0
_DrawGLPolyChain ENDP
_TEXT	ENDS

;  --------------------------------------------------------------------------

_TEXT	SEGMENT

ifdef	DIRECT_API_CALLS

ProcAddrWorm	proc	near
     mov	eax, [eax]

KeepWormin:
     cmp	word ptr [eax], 25FFh	; jmp indirect
     jne	CheckJumpDirect
     mov	eax, [eax+2]		; Address of address of code
     mov	eax, [eax]		; address of code
     jmp	KeepWormin

CheckJumpDirect:
     cmp	byte ptr [eax], 0E9h	; jmp direct 32 bit relative 
     jne	CheckJmpShort
     mov	ecx, [eax+1]
     add	eax, ecx
     add	eax, 5
     jmp	KeepWormin

CheckJmpShort:
     cmp	byte ptr [eax], 0EBh	; jmp direct 8 bit relative
     jne	WriteActualAddress
     movsx	ecx, byte ptr [eax+1]
     add	eax, ecx
     add	eax, 2
     jmp	KeepWormin

WriteActualAddress:
     sub	eax, edx
     sub	eax, 4
     mov	[edx], eax				;start with no conversion
     ret

ProcAddrWorm	endp
endif

;;; TEST CODE
;RetCode:
;	ret
;
;TestFunction	proc	near
;	jmp	FarOffset
;RetFarOffset:
;	jmp	RetCode
;TestFunction	endp
;junk	db	256 dup (90h)
;FarOffset:
;	jmp	RetFarOffset
;;; End Test code

_TEXT	ENDS
include	amdcpu.inc

_DATA	SEGMENT
PUBLIC	__Amd3Dfx
__Amd3Dfx		dd	0
;;; Test Code
;pTestProc		dd	TestFunction
;;; END test code
_DATA   ends
endif   ; AMD3D
END
