// File: /workspace/github_cpp_makefile_star2_O2/FreeSlave[P]vhlt/common/bspfile.cpp
// Function: CountBlocks()
int CountBlocks ()
{
#ifdef ZHLT_64BIT_FIX
#if !defined (PLATFORM_CAN_CALC_EXTENT) && !defined (HLRAD)
	return -1; // otherwise GetFaceExtents will error
#endif
#endif
	lightmapblock_t *blocks;
	blocks = (lightmapblock_t *)malloc (sizeof (lightmapblock_t));
	hlassume (blocks != NULL, assume_NoMemory);
	memset (blocks, 0, sizeof (lightmapblock_t));
	int k;
	for (k = 0; k < g_numfaces; k++)
	{
		dface_t *f = &g_dfaces[k];
#ifdef ZHLT_EMBEDLIGHTMAP
		const char *texname =  GetTextureByNumber (ParseTexinfoForFace (f));
#else
		const char *texname =  GetTextureByNumber (f->texinfo);
#endif
		if (!strncmp (texname, "sky", 3) //sky, no lightmap allocation.
			|| !strncmp (texname, "!", 1) || !strncasecmp (texname, "water", 5) || !strncasecmp (texname, "laser", 5) //water, no lightmap allocation.
#ifdef ZHLT_EMBEDLIGHTMAP
			|| (g_texinfo[ParseTexinfoForFace (f)].flags & TEX_SPECIAL) //aaatrigger, I don't know.
#else
			|| (g_texinfo[f->texinfo].flags & TEX_SPECIAL) //aaatrigger, I don't know.
#endif
			)
		{
			continue;
		}
		int extents[2];
		vec3_t point;
		{
#ifdef ZHLT_64BIT_FIX
			int bmins[2];
			int bmaxs[2];
			int i;
			GetFaceExtents (k, bmins, bmaxs);
			for (i = 0; i < 2; i++)
			{
				extents[i] = (bmaxs[i] - bmins[i]) * TEXTURE_STEP;
			}

			VectorClear (point);
			if (f->numedges > 0)
			{
				int e = g_dsurfedges[f->firstedge];
				dvertex_t *v = &g_dvertexes[g_dedges[abs (e)].v[e >= 0? 0: 1]];
				VectorCopy (v->point, point);
			}
#else
			float mins[2], maxs[2];
			int bmins[2], bmaxs[2];
			texinfo_t *tex;
			tex = &g_texinfo[f->texinfo];
			mins[0] = mins[1] = 999999;
			maxs[0] = maxs[1] = -99999;
			VectorClear (point);
			int i;
			for (i = 0; i < f->numedges; i++)
			{
				int e;
				dvertex_t *v;
				int j;
				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]];
				}
				if (i == 0)
				{
					VectorCopy (v->point, point);
				}
				for (j = 0; j < 2; j++)
				{
					float 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];
					if (val < mins[j])
					{
						mins[j] = val;
					}
					if (val > maxs[j])
					{
						maxs[j] = val;
					}
				}
			}
			for (i = 0; i < 2; i++)
			{
				bmins[i] = floor (mins[i] / TEXTURE_STEP);
				bmaxs[i] = ceil (maxs[i] / TEXTURE_STEP);
				extents[i] = (bmaxs[i] - bmins[i]) * TEXTURE_STEP;
			}
#endif
		}
		if (extents[0] < 0 || extents[1] < 0 || extents[0] > qmax (512, MAX_SURFACE_EXTENT * TEXTURE_STEP) || extents[1] > qmax (512, MAX_SURFACE_EXTENT * TEXTURE_STEP))
			// the default restriction from the engine is 512, but place 'max (512, MAX_SURFACE_EXTENT * TEXTURE_STEP)' here in case someone raise the limit
		{
			Warning ("Bad surface extents %d/%d at position (%.0f,%.0f,%.0f)", extents[0], extents[1], point[0], point[1], point[2]);
			continue;
		}
		DoAllocBlock (blocks, (extents[0] / TEXTURE_STEP) + 1, (extents[1] / TEXTURE_STEP) + 1);
	}
	int count = 0;
	lightmapblock_t *next;
	for (; blocks; blocks = next)
	{
		if (blocks->used)
		{
			count++;
		}
		next = blocks->next;
		free (blocks);
	}
	return count;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
pushq $0x1
popq %rdi
movl $0x210, %esi            # imm = 0x210
callq 0x4220
movq %rax, %rbx
xorl %edi, %edi
testq %rax, %rax
setne %dil
pushq $0x1
popq %rsi
callq 0x9517
xorl %r14d, %r14d
leaq 0x1b89943(%rip), %r15   # 0x1b8f430
leaq 0x20b796c(%rip), %r12   # 0x20bd460
movslq 0x1b89929(%rip), %rax   # 0x1b8f424
cmpq %rax, %r14
jge 0x5c7b
imulq $0x14, %r14, %rbp
addq %r15, %rbp
movq %rbp, %rdi
callq 0x5893
movq %r12, %r13
cmpl $-0x1, %eax
je 0x5b3c
cltq
movq 0x8299a4(%rip), %rcx    # 0x82f4c8
imulq $0x28, %rax, %rax
leaq 0x11898f1(%rip), %rdx   # 0x118f420
movslq 0x20(%rax,%rdx), %rax
movslq 0x4(%rcx,%rax,4), %r13
addq %rcx, %r13
movzbl (%r13), %eax
cmpl $0x21, %eax
je 0x5c73
cmpl $0x73, %eax
jne 0x5b61
cmpb $0x6b, 0x1(%r13)
jne 0x5b61
cmpb $0x79, 0x2(%r13)
je 0x5c73
movq %r13, %rdi
leaq 0x18dd9(%rip), %rsi     # 0x1e944
pushq $0x5
popq %rdx
callq 0x4420
testl %eax, %eax
je 0x5c73
movq %r13, %rdi
leaq 0x135e9(%rip), %rsi     # 0x1916e
pushq $0x5
popq %rdx
callq 0x4420
testl %eax, %eax
je 0x5c73
movq %rbp, %rdi
callq 0x5893
cltq
imulq $0x28, %rax, %rax
leaq 0x1189876(%rip), %rcx   # 0x118f420
testb $0x1, 0x24(%rax,%rcx)
jne 0x5c73
movl %r14d, %edi
leaq 0x10(%rsp), %rsi
leaq 0x8(%rsp), %rdx
callq 0x570d
xorl %eax, %eax
cmpq $0x2, %rax
je 0x5be2
movl 0x8(%rsp,%rax,4), %ecx
subl 0x10(%rsp,%rax,4), %ecx
shll $0x4, %ecx
movl %ecx, (%rsp,%rax,4)
incq %rax
jmp 0x5bc9
cmpw $0x0, 0x8(%rbp)
jle 0x5c27
movslq 0x4(%rbp), %rax
leaq 0x1e2385c(%rip), %rcx   # 0x1e29450
movl (%rcx,%rax,4), %eax
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
leaq 0x1d0982b(%rip), %rdx   # 0x1d0f430
leaq (%rdx,%rcx,4), %rcx
shrl $0x1f, %eax
movzwl (%rcx,%rax,2), %eax
imulq $0xc, %rax, %rax
leaq 0x1009815(%rip), %rcx   # 0x100f430
cvtps2pd (%rax,%rcx), %xmm0
cvtss2sd 0x8(%rax,%rcx), %xmm2
jmp 0x5c2d
xorps %xmm0, %xmm0
xorps %xmm2, %xmm2
movl (%rsp), %esi
movl 0x4(%rsp), %edx
movl $0x201, %ecx            # imm = 0x201
cmpl %ecx, %esi
setae %al
cmpl %ecx, %edx
setae %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x5c61
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
leaq 0x1351c(%rip), %rdi     # 0x19174
movb $0x3, %al
callq 0x90f1
jmp 0x5c73
shrl $0x4, %esi
incl %esi
shrl $0x4, %edx
incl %edx
movq %rbx, %rdi
callq 0x5972
incq %r14
jmp 0x5af4
xorl %ebp, %ebp
testq %rbx, %rbx
je 0x5c98
movzbl 0x8(%rbx), %eax
addl %eax, %ebp
movq (%rbx), %r14
movq %rbx, %rdi
callq 0x43b0
movq %r14, %rbx
jmp 0x5c7d
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq