// File: /workspace/github_cpp_makefile_star2_O1/FreeSlave[P]vhlt/hlbsp/surfaces.cpp
// Function: SubdivideFace(face_s*, face_s**)
void            SubdivideFace(face_t* f, face_t** prevptr)
{
    vec_t           mins, maxs;
    vec_t           v;
    int             axis;
    int             i;
    dplane_t        plane;
    face_t*         front;
    face_t*         back;
    face_t*         next;
    texinfo_t*      tex;
    vec3_t          temp;

    // special (non-surface cached) faces don't need subdivision

#ifdef HLCSG_HLBSP_VOIDTEXINFO
	if (f->texturenum == -1)
	{
		return;
	}
#endif
    tex = &g_texinfo[f->texturenum];

    if (tex->flags & TEX_SPECIAL) 
    {
        return;
    }

    if (f->facestyle == face_hint)
    {
        return;
    }
    if (f->facestyle == face_skip)
    {
        return;
    }

#ifdef ZHLT_NULLTEX    // AJM
    if (f->facestyle == face_null)
        return; // ideally these should have their tex_special flag set, so its here jic
#endif
#ifdef HLCSG_HLBSP_SOLIDHINT
	if (f->facestyle == face_discardable)
		return;
#endif
	
    for (axis = 0; axis < 2; axis++)
    {
        while (1)
        {
#ifdef HLBSP_SUBDIVIDE_INMID
			const int maxlightmapsize = g_subdivide_size / TEXTURE_STEP + 1;
			int lightmapmins, lightmapmaxs;
			if (f->numpoints == 0)
			{
				break;
			}
			for (i = 0; i < f->numpoints; i++)
			{
				v = DotProduct (f->pts[i], tex->vecs[axis]) + tex->vecs[axis][3];
				if (i == 0 || v < mins)
				{
					mins = v;
				}
				if (i == 0 || v > maxs)
				{
					maxs = v;
				}
			}
			lightmapmins = (int)floor (mins / TEXTURE_STEP - 0.05); // the worst case
			lightmapmaxs = (int)ceil (maxs / TEXTURE_STEP + 0.05); // the worst case
			if (lightmapmaxs - lightmapmins <= maxlightmapsize)
			{
				break;
			}
#else
#ifdef ZHLT_64BIT_FIX
			mins = 99999999;
			maxs = -99999999;
#else
            mins = 999999;
            maxs = -999999;
#endif

            for (i = 0; i < f->numpoints; i++)
            {
                v = DotProduct(f->pts[i], tex->vecs[axis]);
                if (v < mins)
                {
                    mins = v;
                }
                if (v > maxs)
                {
                    maxs = v;
                }
            }

            if ((maxs - mins) <= g_subdivide_size)
            {
                break;
            }
#endif
                
            // split it
            subdivides++;

            VectorCopy(tex->vecs[axis], temp);
            v = VectorNormalize(temp);

            VectorCopy(temp, plane.normal);
#ifdef HLBSP_SUBDIVIDE_INMID
			int splitpos;
			if ((lightmapmaxs - lightmapmins - 1) - (maxlightmapsize - 1) < (maxlightmapsize - 1) / 4) // don't create very thin face
			{
				splitpos = lightmapmins + (maxlightmapsize - 1) - (maxlightmapsize - 1) / 4;
			}
			else
			{
				splitpos = lightmapmins + (maxlightmapsize - 1);
			}
			plane.dist = ((splitpos + 0.5) * TEXTURE_STEP - tex->vecs[axis][3]) / v;
#else
            plane.dist = (mins + g_subdivide_size - TEXTURE_STEP) / v; //plane.dist = (mins + g_subdivide_size - 16) / v; //--vluzacn
#endif
            next = f->next;
            SplitFace(f, &plane, &front, &back);
            if (!front || !back)
            {
                Developer(DEVELOPER_LEVEL_SPAM, "SubdivideFace: didn't split the %d-sided polygon @(%.0f,%.0f,%.0f)",
                        f->numpoints, f->pts[0][0], f->pts[0][1], f->pts[0][2]);
#ifndef HLBSP_SubdivideFace_FIX
                break;
#endif
            }
#ifdef HLBSP_SubdivideFace_FIX
			f = next;
			if (front)
			{
				front->next = f;
				f = front;
			}
			if (back)
			{
				back->next = f;
				f = back;
			}
			*prevptr = f;
#else
            *prevptr = back;
            back->next = front;
            front->next = next;
            f = back;
#endif
        }
    }
}

// Assembly:
movslq 0xc(%rdi), %rax
cmpq $-0x1, %rax
je 0x1a538
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
leaq (%rax,%rax,4), %rax
leaq 0x117a0ea(%rip), %rcx   # 0x11943c0
testb $0x1, 0x24(%rcx,%rax,8)
jne 0x1a527
movq %rdi, %rbp
movl 0x30(%rdi), %edx
decl %edx
cmpl $0x4, %edx
jb 0x1a527
movq %rsi, %rbx
leaq (%rcx,%rax,8), %rax
movq %rax, 0x10(%rsp)
xorl %r14d, %r14d
leaq 0x120fc(%rip), %r13     # 0x2c404
movq %rsp, %r12
movq %r14, 0x18(%rsp)
shlq $0x4, %r14
addq 0x10(%rsp), %r14
movslq 0x2c(%rbp), %rax
movsd 0x9903(%rip), %xmm3     # 0x23c28
movsd 0x98f3(%rip), %xmm6     # 0x23c20
testq %rax, %rax
jle 0x1a3a9
xorps %xmm0, %xmm0
cvtss2sd (%r14), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x4(%r14), %xmm1
xorps %xmm2, %xmm2
cvtss2sd 0x8(%r14), %xmm2
shlq $0x3, %rax
leaq (%rax,%rax,2), %rax
xorl %ecx, %ecx
movsd 0x98c2(%rip), %xmm4     # 0x23c20
movsd 0x98c2(%rip), %xmm5     # 0x23c28
movsd 0x40(%rbp,%rcx), %xmm3
mulsd %xmm1, %xmm3
movsd 0x38(%rbp,%rcx), %xmm6
mulsd %xmm0, %xmm6
addsd %xmm3, %xmm6
movsd 0x48(%rbp,%rcx), %xmm3
mulsd %xmm2, %xmm3
addsd %xmm6, %xmm3
movapd %xmm3, %xmm6
minsd %xmm4, %xmm6
maxsd %xmm5, %xmm3
addq $0x18, %rcx
movapd %xmm6, %xmm4
movapd %xmm3, %xmm5
cmpq %rcx, %rax
jne 0x1a366
subsd %xmm6, %xmm3
xorps %xmm0, %xmm0
cvtsi2sdl (%r13), %xmm0
ucomisd %xmm3, %xmm0
jae 0x1a515
incl 0x32ba6aa(%rip)         # 0x32d4a70
cvtps2pd (%r14), %xmm3
xorps %xmm2, %xmm2
cvtss2sd 0x8(%r14), %xmm2
movapd %xmm3, %xmm0
mulpd %xmm3, %xmm0
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
movapd %xmm3, %xmm1
mulsd %xmm3, %xmm1
addsd %xmm0, %xmm1
movaps %xmm2, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
ucomisd 0x6e82(%rip), %xmm0     # 0x21280
jb 0x1a406
sqrtsd %xmm0, %xmm0
jmp 0x1a42f
movsd %xmm6, 0x28(%rsp)
movapd %xmm3, 0x30(%rsp)
movsd %xmm2, 0x20(%rsp)
callq 0x4240
movsd 0x20(%rsp), %xmm2
movapd 0x30(%rsp), %xmm3
movsd 0x28(%rsp), %xmm6
movsd 0x3cd9(%rip), %xmm1     # 0x1e110
ucomisd %xmm0, %xmm1
xorpd %xmm1, %xmm1
ja 0x1a449
divsd %xmm0, %xmm2
movapd %xmm2, %xmm1
xorpd %xmm2, %xmm2
ja 0x1a45f
movapd %xmm0, %xmm2
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
divpd %xmm2, %xmm3
movapd %xmm3, %xmm2
movapd %xmm0, %xmm3
cmpltsd 0x3ca4(%rip), %xmm3     # 0x1e110
andnpd %xmm0, %xmm3
movapd %xmm2, 0x40(%rsp)
movsd %xmm1, 0x50(%rsp)
xorps %xmm0, %xmm0
cvtsi2sdl (%r13), %xmm0
addsd %xmm0, %xmm6
addsd 0x979f(%rip), %xmm6     # 0x23c30
divsd %xmm3, %xmm6
movsd %xmm6, 0x70(%rsp)
movq (%rbp), %r15
movq %rbp, %rdi
leaq 0x40(%rsp), %rsi
leaq 0x8(%rsp), %rdx
movq %r12, %rcx
callq 0x149b6
cmpq $0x0, 0x8(%rsp)
je 0x1a4c3
cmpq $0x0, (%rsp)
jne 0x1a4e8
movl 0x2c(%rbp), %edx
movsd 0x38(%rbp), %xmm0
movsd 0x40(%rbp), %xmm1
movsd 0x48(%rbp), %xmm2
movl $0x5, %edi
leaq 0x977f(%rip), %rsi      # 0x23c60
movb $0x3, %al
callq 0xa496
movq 0x8(%rsp), %rax
testq %rax, %rax
je 0x1a4fa
movq %r15, (%rax)
movq 0x8(%rsp), %r15
movq (%rsp), %rax
testq %rax, %rax
je 0x1a50a
movq %r15, (%rax)
movq (%rsp), %r15
movq %r15, (%rbx)
movq %r15, %rbp
jmp 0x1a319
movq 0x18(%rsp), %rcx
leaq 0x1(%rcx), %r14
testq %rcx, %rcx
je 0x1a30b
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq