// File: 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:
subq $0x78, %rsp
movl $0x210, %edi            # imm = 0x210
callq 0x4500
movq %rax, 0x70(%rsp)
cmpq $0x0, 0x70(%rsp)
setne %al
movzbl %al, %edi
andl $0x1, %edi
movl $0x1, %esi
callq 0xc400
movq 0x70(%rsp), %rdi
xorl %esi, %esi
movl $0x210, %edx            # imm = 0x210
callq 0x4210
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0x1b98ac5(%rip), %eax   # 0x1b9f474
jge 0x6c17
movslq 0x6c(%rsp), %rcx
leaq 0x1b98abf(%rip), %rax   # 0x1b9f480
imulq $0x14, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rdi
callq 0x6620
movl %eax, %edi
callq 0x6c70
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
leaq 0x2729d(%rip), %rsi     # 0x2dc8c
movl $0x3, %edx
callq 0x41f0
cmpl $0x0, %eax
je 0x6a75
movq 0x58(%rsp), %rdi
leaq 0x2945d(%rip), %rsi     # 0x2fe67
movl $0x1, %edx
callq 0x41f0
cmpl $0x0, %eax
je 0x6a75
movq 0x58(%rsp), %rdi
leaq 0x290d2(%rip), %rsi     # 0x2faf7
movl $0x5, %edx
callq 0x44e0
cmpl $0x0, %eax
je 0x6a75
movq 0x58(%rsp), %rdi
leaq 0x23716(%rip), %rsi     # 0x2a156
movl $0x5, %edx
callq 0x44e0
cmpl $0x0, %eax
je 0x6a75
movq 0x60(%rsp), %rdi
callq 0x6620
movslq %eax, %rcx
leaq 0x1198a0d(%rip), %rax   # 0x119f470
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x24(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x6a7a
jmp 0x6c07
movl 0x6c(%rsp), %edi
leaq 0x28(%rsp), %rsi
leaq 0x20(%rsp), %rdx
callq 0x63a0
movl $0x0, 0x1c(%rsp)
cmpl $0x2, 0x1c(%rsp)
jge 0x6ac7
movslq 0x1c(%rsp), %rax
movl 0x20(%rsp,%rax,4), %ecx
movslq 0x1c(%rsp), %rax
subl 0x28(%rsp,%rax,4), %ecx
shll $0x4, %ecx
movslq 0x1c(%rsp), %rax
movl %ecx, 0x50(%rsp,%rax,4)
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x6a95
xorps %xmm0, %xmm0
movsd %xmm0, 0x40(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x60(%rsp), %rax
movswl 0x8(%rax), %eax
cmpl $0x0, %eax
jle 0x6b8f
movq 0x60(%rsp), %rax
movslq 0x4(%rax), %rcx
leaq 0x1e3299c(%rip), %rax   # 0x1e394a0
movl (%rax,%rcx,4), %eax
movl %eax, 0x18(%rsp)
movl 0x18(%rsp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movslq %eax, %rcx
leaq 0x1d18960(%rip), %rax   # 0x1d1f480
shlq $0x2, %rcx
addq %rcx, %rax
movl 0x18(%rsp), %esi
movl $0x1, %ecx
xorl %edx, %edx
cmpl $0x0, %esi
cmovgel %edx, %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
movl %eax, %ecx
leaq 0x1018938(%rip), %rax   # 0x101f480
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x10(%rsp), %rax
movss 0x4(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x10(%rsp), %rax
movss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x40(%rsp)
cmpl $0x0, 0x50(%rsp)
jl 0x6bb1
cmpl $0x0, 0x54(%rsp)
jl 0x6bb1
cmpl $0x200, 0x50(%rsp)      # imm = 0x200
jg 0x6bb1
cmpl $0x200, 0x54(%rsp)      # imm = 0x200
jle 0x6bdb
movl 0x50(%rsp), %esi
movl 0x54(%rsp), %edx
movsd 0x30(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
movsd 0x40(%rsp), %xmm2
leaq 0x2358a(%rip), %rdi     # 0x2a15c
movb $0x3, %al
callq 0xbef0
jmp 0x6c07
movq 0x70(%rsp), %rdi
movl 0x50(%rsp), %eax
movl $0x10, %ecx
cltd
idivl %ecx
movl %eax, %esi
addl $0x1, %esi
movl 0x54(%rsp), %eax
movl $0x10, %ecx
cltd
idivl %ecx
movl %eax, %edx
addl $0x1, %edx
callq 0x6760
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x69a5
movl $0x0, 0xc(%rsp)
cmpq $0x0, 0x70(%rsp)
je 0x6c5e
movq 0x70(%rsp), %rax
testb $0x1, 0x8(%rax)
je 0x6c3d
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
movq 0x70(%rsp), %rax
movq (%rax), %rax
movq %rax, (%rsp)
movq 0x70(%rsp), %rdi
callq 0x4470
movq (%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x6c1f
movl 0xc(%rsp), %eax
addq $0x78, %rsp
retq
nopw (%rax,%rax)