// File: FreeSlave[P]vhlt/hlvis/flow.cpp
// Function: ClipToSeperators(winding_t const*, winding_t const*, winding_t*, bool, pstack_s*)
inline static winding_t* ClipToSeperators(
    const winding_t* const source,
    const winding_t* const pass, 
    winding_t* const a_target,
    const bool flipclip, 
    pstack_t* const stack)
{
    int             i, j, k, l;
    plane_t         plane;
    vec3_t          v1, v2;
    float           d;
    int             counts[3];
    bool            fliptest;
    winding_t*      target = a_target;

    const unsigned int numpoints = source->numpoints;

    // check all combinations       
    for (i=0, l=1; i < numpoints; i++, l++)
    {
        if (l == numpoints)
        {
            l = 0;
        }

        VectorSubtract(source->points[l], source->points[i], v1);

        // fing a vertex of pass that makes a plane that puts all of the
        // vertexes of pass on the front side and all of the vertexes of
        // source on the back side
        for (j = 0; j < pass->numpoints; j++)
        {
            VectorSubtract(pass->points[j], source->points[i], v2);
            CrossProduct(v1, v2, plane.normal);
            if (VectorNormalize(plane.normal) < ON_EPSILON)
            {
                continue;
            }
            plane.dist = DotProduct(pass->points[j], plane.normal);

            // find out which side of the generated seperating plane has the
            // source portal
            fliptest = false;
            for (k = 0; k < numpoints; k++)
            {
                if ((k == i) | (k == l)) // | instead of || for branch optimization
                {
                    continue;
                }
                d = DotProduct(source->points[k], plane.normal) - plane.dist;
                if (d < -ON_EPSILON)
                {                                          // source is on the negative side, so we want all
                    // pass and target on the positive side
                    fliptest = false;
                    break;
                }
                else if (d > ON_EPSILON)
                {                                          // source is on the positive side, so we want all
                    // pass and target on the negative side
                    fliptest = true;
                    break;
                }
            }
            if (k == numpoints)
            {
                continue;                                  // planar with source portal
            }

            // flip the normal if the source portal is backwards
            if (fliptest)
            {
                VectorSubtract(vec3_origin, plane.normal, plane.normal);
                plane.dist = -plane.dist;
            }

            // if all of the pass portal points are now on the positive side,
            // this is the seperating plane
            counts[0] = counts[1] = counts[2] = 0;
            for (k = 0; k < pass->numpoints; k++)
            {
                if (k == j)
                {
                    continue;
                }
                d = DotProduct(pass->points[k], plane.normal) - plane.dist;
                if (d < -ON_EPSILON)
                {
                    break;
                }
                else if (d > ON_EPSILON)
                {
                    counts[0]++;
                }
                else
                {
                    counts[2]++;
                }
            }
            if (k != pass->numpoints)
            {
                continue;                                  // points on negative side, not a seperating plane
            }

            if (!counts[0])
            {
                continue;                                  // planar with seperating plane
            }

            // flip the normal if we want the back side
            if (flipclip)
            {
                VectorSubtract(vec3_origin, plane.normal, plane.normal);
                plane.dist = -plane.dist;
            }

	    if (target != NULL)
	    {
            // clip target by the seperating plane
            target = ChopWinding(target, stack, &plane);
            if (!target)
            {
                return NULL;                               // target is not visible
            }
	    }
	    else
	    {
        	AddPlane(stack, &plane);
	    }

#ifdef RVIS_LEVEL_1
            break; /* Antony was here */
#endif
        }
    }

    return target;
}

// Assembly:
subq $0x98, %rsp
movb %cl, %al
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movq %rdx, 0x78(%rsp)
andb $0x1, %al
movb %al, 0x77(%rsp)
movq %r8, 0x68(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x88(%rsp), %rax
movl 0x4(%rax), %eax
movl %eax, 0xc(%rsp)
movl $0x0, 0x64(%rsp)
movl $0x1, 0x58(%rsp)
movl 0x64(%rsp), %eax
cmpl 0xc(%rsp), %eax
jae 0x14a2d
movl 0x58(%rsp), %eax
cmpl 0xc(%rsp), %eax
jne 0x143a2
movl $0x0, 0x58(%rsp)
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x58(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss (%rax), %xmm0
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x64(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
subss (%rax), %xmm0
movss %xmm0, 0x3c(%rsp)
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x58(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x4(%rax), %xmm0
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x64(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
subss 0x4(%rax), %xmm0
movss %xmm0, 0x40(%rsp)
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x58(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x8(%rax), %xmm0
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x64(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
subss 0x8(%rax), %xmm0
movss %xmm0, 0x44(%rsp)
movl $0x0, 0x60(%rsp)
movl 0x60(%rsp), %eax
movq 0x80(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0x14a10
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x60(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss (%rax), %xmm0
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x64(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
subss (%rax), %xmm0
movss %xmm0, 0x30(%rsp)
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x60(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x4(%rax), %xmm0
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x64(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
subss 0x4(%rax), %xmm0
movss %xmm0, 0x34(%rsp)
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x60(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x8(%rax), %xmm0
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x64(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
subss 0x8(%rax), %xmm0
movss %xmm0, 0x38(%rsp)
movss 0x40(%rsp), %xmm0
movss 0x38(%rsp), %xmm2
movss 0x44(%rsp), %xmm1
mulss 0x34(%rsp), %xmm1
movd %xmm1, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0x48(%rsp)
movss 0x44(%rsp), %xmm0
movss 0x30(%rsp), %xmm2
movss 0x3c(%rsp), %xmm1
mulss 0x38(%rsp), %xmm1
movd %xmm1, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0x4c(%rsp)
movss 0x3c(%rsp), %xmm0
movss 0x34(%rsp), %xmm2
movss 0x40(%rsp), %xmm1
mulss 0x30(%rsp), %xmm1
movd %xmm1, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0x50(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x10780
cvtss2sd %xmm0, %xmm1
movsd 0x8046(%rip), %xmm0     # 0x1c630
ucomisd %xmm1, %xmm0
jbe 0x145f5
jmp 0x14a00
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x60(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss (%rax), %xmm1
movss 0x48(%rsp), %xmm2
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x60(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x4(%rax), %xmm0
mulss 0x4c(%rsp), %xmm0
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x60(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x8(%rax), %xmm0
movss 0x50(%rsp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0x54(%rsp)
movb $0x0, 0x1f(%rsp)
movl $0x0, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
cmpl 0xc(%rsp), %eax
jae 0x14791
movl 0x5c(%rsp), %eax
cmpl 0x64(%rsp), %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl 0x5c(%rsp), %ecx
cmpl 0x58(%rsp), %ecx
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
cmpl $0x0, %eax
je 0x146bb
jmp 0x14781
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x5c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss (%rax), %xmm1
movss 0x48(%rsp), %xmm2
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x5c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x4(%rax), %xmm0
mulss 0x4c(%rsp), %xmm0
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movq 0x88(%rsp), %rax
addq $0x8, %rax
movslq 0x5c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x8(%rax), %xmm0
movss 0x50(%rsp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
subss 0x54(%rsp), %xmm0
movss %xmm0, 0x2c(%rsp)
movss 0x2c(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x7ee7(%rip), %xmm0     # 0x1c638
ucomisd %xmm1, %xmm0
jbe 0x1475e
movb $0x0, 0x1f(%rsp)
jmp 0x14791
movss 0x2c(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x7ec0(%rip), %xmm1     # 0x1c630
ucomisd %xmm1, %xmm0
jbe 0x1477d
movb $0x1, 0x1f(%rsp)
jmp 0x14791
jmp 0x1477f
jmp 0x14781
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x14680
movl 0x5c(%rsp), %eax
cmpl 0xc(%rsp), %eax
jne 0x147a0
jmp 0x14a00
testb $0x1, 0x1f(%rsp)
je 0x14807
leaq 0x66d2(%rip), %rax      # 0x1ae80
movss (%rax), %xmm0
subss 0x48(%rsp), %xmm0
movss %xmm0, 0x48(%rsp)
leaq 0x66bb(%rip), %rax      # 0x1ae80
movss 0x4(%rax), %xmm0
subss 0x4c(%rsp), %xmm0
movss %xmm0, 0x4c(%rsp)
leaq 0x66a3(%rip), %rax      # 0x1ae80
movss 0x8(%rax), %xmm0
subss 0x50(%rsp), %xmm0
movss %xmm0, 0x50(%rsp)
movss 0x54(%rsp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss %xmm0, 0x54(%rsp)
movl $0x0, 0x28(%rsp)
movl $0x0, 0x24(%rsp)
movl $0x0, 0x20(%rsp)
movl $0x0, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
movq 0x80(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0x1492d
movl 0x5c(%rsp), %eax
cmpl 0x60(%rsp), %eax
jne 0x1484b
jmp 0x1491d
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x5c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss (%rax), %xmm1
movss 0x48(%rsp), %xmm2
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x5c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x4(%rax), %xmm0
mulss 0x4c(%rsp), %xmm0
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movq 0x80(%rsp), %rax
addq $0x8, %rax
movslq 0x5c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x8(%rax), %xmm0
movss 0x50(%rsp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
subss 0x54(%rsp), %xmm0
movss %xmm0, 0x2c(%rsp)
movss 0x2c(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x7d57(%rip), %xmm0     # 0x1c638
ucomisd %xmm1, %xmm0
jbe 0x148e9
jmp 0x1492d
movss 0x2c(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x7d35(%rip), %xmm1     # 0x1c630
ucomisd %xmm1, %xmm0
jbe 0x1490e
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x14919
movl 0x28(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
jmp 0x1491b
jmp 0x1491d
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x14827
movl 0x5c(%rsp), %eax
movq 0x80(%rsp), %rcx
cmpl 0x4(%rcx), %eax
je 0x14943
jmp 0x14a00
cmpl $0x0, 0x20(%rsp)
jne 0x1494f
jmp 0x14a00
testb $0x1, 0x77(%rsp)
je 0x149b6
leaq 0x6523(%rip), %rax      # 0x1ae80
movss (%rax), %xmm0
subss 0x48(%rsp), %xmm0
movss %xmm0, 0x48(%rsp)
leaq 0x650c(%rip), %rax      # 0x1ae80
movss 0x4(%rax), %xmm0
subss 0x4c(%rsp), %xmm0
movss %xmm0, 0x4c(%rsp)
leaq 0x64f4(%rip), %rax      # 0x1ae80
movss 0x8(%rax), %xmm0
subss 0x50(%rsp), %xmm0
movss %xmm0, 0x50(%rsp)
movss 0x54(%rsp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss %xmm0, 0x54(%rsp)
cmpq $0x0, 0x10(%rsp)
je 0x149ef
movq 0x10(%rsp), %rdi
movq 0x68(%rsp), %rsi
leaq 0x48(%rsp), %rdx
callq 0x14ce0
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x10(%rsp)
jne 0x149ed
movq $0x0, 0x90(%rsp)
jmp 0x14a3a
jmp 0x149fe
movq 0x68(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x14b60
jmp 0x14a10
movl 0x60(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x60(%rsp)
jmp 0x14468
jmp 0x14a12
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0x14382
movq 0x10(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
addq $0x98, %rsp
retq
nopw (%rax,%rax)