// File: FreeSlave[P]vhlt/common/bspfile.cpp
// Function: GetFaceExtents(int, int*, int*)
void GetFaceExtents (int facenum, int mins_out[2], int maxs_out[2])
{
	CorrectFPUPrecision ();

	dface_t *f;
	float mins[2], maxs[2], val;
	int i, j, e;
	dvertex_t *v;
	texinfo_t *tex;
	int bmins[2], bmaxs[2];

	f = &g_dfaces[facenum];

	mins[0] = mins[1] = 999999;
	maxs[0] = maxs[1] = -99999;

#ifdef ZHLT_EMBEDLIGHTMAP
	tex = &g_texinfo[ParseTexinfoForFace (f)];
#else
	tex = &g_texinfo[f->texinfo];
#endif

	for (i = 0; i < f->numedges; i++)
	{
		e = g_dsurfedges[f->firstedge + i];
		if (e >= 0)
		{
			v = &g_dvertexes[g_dedges[e].v[0]];
		}
		else
		{
			v = &g_dvertexes[g_dedges[-e].v[1]];
		}
		for (j = 0; j < 2; j++)
		{
			// The old code: val = v->point[0] * tex->vecs[j][0] + v->point[1] * tex->vecs[j][1] + v->point[2] * tex->vecs[j][2] + tex->vecs[j][3];
			//   was meant to be compiled for x86 under MSVC (prior to VS 11), so the intermediate values were stored as 64-bit double by default.
			// The new code will produce the same result as the old code, but it's portable for different platforms.
			// See this article for details: Intermediate Floating-Point Precision by Bruce-Dawson http://www.altdevblogaday.com/2012/03/22/intermediate-floating-point-precision/

			// The essential reason for having this ugly code is to get exactly the same value as the counterpart of game engine.
			// The counterpart of game engine is the function CalcFaceExtents in HLSDK.
			// So we must also know how Valve compiles HLSDK. I think Valve compiles HLSDK with VC6.0 in the past.
			val = CalculatePointVecsProduct (v->point, tex->vecs[j]);
			if (val < mins[j])
			{
				mins[j] = val;
			}
			if (val > maxs[j])
			{
				maxs[j] = val;
			}
		}
	}

	for (i = 0; i < 2; i++)
	{
		bmins[i] = (int)floor (mins[i] / TEXTURE_STEP);
		bmaxs[i] = (int)ceil (maxs[i] / TEXTURE_STEP);
	}

	for (i = 0; i < 2; i++)
	{
		mins_out[i] = bmins[i];
		maxs_out[i] = bmaxs[i];
	}
}

// Assembly:
subq $0x68, %rsp
movl %edi, 0x64(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
callq 0x6390
movslq 0x64(%rsp), %rcx
leaq 0x1b990bd(%rip), %rax   # 0x1b9f480
imulq $0x14, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x48(%rsp)
movss 0x23c69(%rip), %xmm0    # 0x2a040
movss %xmm0, 0x44(%rsp)
movss 0x23c5b(%rip), %xmm0    # 0x2a040
movss %xmm0, 0x40(%rsp)
movss 0x23c49(%rip), %xmm0    # 0x2a03c
movss %xmm0, 0x3c(%rsp)
movss 0x23c3b(%rip), %xmm0    # 0x2a03c
movss %xmm0, 0x38(%rsp)
movq 0x48(%rsp), %rdi
callq 0x6620
movslq %eax, %rcx
leaq 0x1199055(%rip), %rax   # 0x119f470
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x18(%rsp)
movl $0x0, 0x30(%rsp)
movl 0x30(%rsp), %eax
movq 0x48(%rsp), %rcx
movswl 0x8(%rcx), %ecx
cmpl %ecx, %eax
jge 0x6557
movq 0x48(%rsp), %rax
movl 0x4(%rax), %eax
addl 0x30(%rsp), %eax
movslq %eax, %rcx
leaq 0x1e33046(%rip), %rax   # 0x1e394a0
movl (%rax,%rcx,4), %eax
movl %eax, 0x28(%rsp)
cmpl $0x0, 0x28(%rsp)
jl 0x648f
movslq 0x28(%rsp), %rcx
leaq 0x1d1900c(%rip), %rax   # 0x1d1f480
movzwl (%rax,%rcx,4), %eax
movl %eax, %ecx
leaq 0x1018fff(%rip), %rax   # 0x101f480
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
jmp 0x64b9
xorl %eax, %eax
subl 0x28(%rsp), %eax
movslq %eax, %rcx
leaq 0x1d18fe1(%rip), %rax   # 0x1d1f480
movzwl 0x2(%rax,%rcx,4), %eax
movl %eax, %ecx
leaq 0x1018fd3(%rip), %rax   # 0x101f480
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
movl $0x0, 0x2c(%rsp)
cmpl $0x2, 0x2c(%rsp)
jge 0x6545
movq 0x20(%rsp), %rdi
movq 0x18(%rsp), %rsi
movslq 0x2c(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rsi
callq 0x61c0
movss %xmm0, 0x34(%rsp)
movss 0x34(%rsp), %xmm1
movslq 0x2c(%rsp), %rax
movss 0x40(%rsp,%rax,4), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x6510
movss 0x34(%rsp), %xmm0
movslq 0x2c(%rsp), %rax
movss %xmm0, 0x40(%rsp,%rax,4)
movss 0x34(%rsp), %xmm0
movslq 0x2c(%rsp), %rax
ucomiss 0x38(%rsp,%rax,4), %xmm0
jbe 0x6533
movss 0x34(%rsp), %xmm0
movslq 0x2c(%rsp), %rax
movss %xmm0, 0x38(%rsp,%rax,4)
jmp 0x6535
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x64c1
jmp 0x6547
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0x642f
movl $0x0, 0x30(%rsp)
cmpl $0x2, 0x30(%rsp)
jge 0x65c5
movslq 0x30(%rsp), %rax
movss 0x40(%rsp,%rax,4), %xmm0
movss 0x23acb(%rip), %xmm1    # 0x2a044
divss %xmm1, %xmm0
callq 0x9300
cvttss2si %xmm0, %ecx
movslq 0x30(%rsp), %rax
movl %ecx, 0x10(%rsp,%rax,4)
movslq 0x30(%rsp), %rax
movss 0x38(%rsp,%rax,4), %xmm0
movss 0x23aa2(%rip), %xmm1    # 0x2a044
divss %xmm1, %xmm0
callq 0x9320
cvttss2si %xmm0, %ecx
movslq 0x30(%rsp), %rax
movl %ecx, 0x8(%rsp,%rax,4)
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0x655f
movl $0x0, 0x30(%rsp)
cmpl $0x2, 0x30(%rsp)
jge 0x660d
movslq 0x30(%rsp), %rax
movl 0x10(%rsp,%rax,4), %edx
movq 0x58(%rsp), %rax
movslq 0x30(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movslq 0x30(%rsp), %rax
movl 0x8(%rsp,%rax,4), %edx
movq 0x50(%rsp), %rax
movslq 0x30(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0x65cd
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)