// File: FreeSlave[P]vhlt/hlbsp/tjunc.cpp
// Function: SplitFaceForTjunc(face_s*, face_s*)
static void     SplitFaceForTjunc(face_t* f, face_t* original)
{
    int             i;
    face_t*         newface;
    face_t*         chain;
    vec3_t          dir, test;
    vec_t           v;
    int             firstcorner, lastcorner;

#ifdef _DEBUG
    static int      counter = 0;

    Log("SplitFaceForTjunc %d\n", counter++);
#endif

    chain = NULL;
    do
    {
        hlassume(f->original == NULL, assume_ValidPointer);     // "SplitFaceForTjunc: f->original"

        if (f->numpoints <= MAXPOINTS)
        {                                                  // the face is now small enough without more cutting
            // so copy it back to the original
            *original = *f;
            original->original = chain;
            original->next = newlist;
            newlist = original;
            return;
        }

        tjuncfaces++;

restart:
        // find the last corner 
        VectorSubtract(f->pts[f->numpoints - 1], f->pts[0], dir);
        VectorNormalize(dir);
        for (lastcorner = f->numpoints - 1; lastcorner > 0; lastcorner--)
        {
            VectorSubtract(f->pts[lastcorner - 1], f->pts[lastcorner], test);
            VectorNormalize(test);
            v = DotProduct(test, dir);
            if (v < 1.0 - ON_EPSILON || v > 1.0 + ON_EPSILON)
            {
                break;
            }
        }

        // find the first corner        
        VectorSubtract(f->pts[1], f->pts[0], dir);
        VectorNormalize(dir);
        for (firstcorner = 1; firstcorner < f->numpoints - 1; firstcorner++)
        {
            VectorSubtract(f->pts[firstcorner + 1], f->pts[firstcorner], test);
            VectorNormalize(test);
            v = DotProduct(test, dir);
            if (v < 1.0 - ON_EPSILON || v > 1.0 + ON_EPSILON)
            {
                break;
            }
        }

        if (firstcorner + 2 >= MAXPOINTS)
        {
            // rotate the point winding
            VectorCopy(f->pts[0], test);
            for (i = 1; i < f->numpoints; i++)
            {
                VectorCopy(f->pts[i], f->pts[i - 1]);
            }
            VectorCopy(test, f->pts[f->numpoints - 1]);
            goto restart;
        }

        // cut off as big a piece as possible, less than MAXPOINTS, and not
        // past lastcorner

        newface = NewFaceFromFace(f);

        hlassume(f->original == NULL, assume_ValidPointer);     // "SplitFaceForTjunc: f->original"

        newface->original = chain;
        chain = newface;
        newface->next = newlist;
        newlist = newface;
        if (f->numpoints - firstcorner <= MAXPOINTS)
        {
            newface->numpoints = firstcorner + 2;
        }
        else if (lastcorner + 2 < MAXPOINTS && f->numpoints - lastcorner <= MAXPOINTS)
        {
            newface->numpoints = lastcorner + 2;
        }
        else
        {
            newface->numpoints = MAXPOINTS;
        }

        for (i = 0; i < newface->numpoints; i++)
        {
            VectorCopy(f->pts[i], newface->pts[i]);
        }

        for (i = newface->numpoints - 1; i < f->numpoints; i++)
        {
            VectorCopy(f->pts[i], f->pts[i - (newface->numpoints - 2)]);
        }
        f->numpoints -= (newface->numpoints - 2);
    }
    while (1);

}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movq $0x0, 0x50(%rsp)
movq 0x70(%rsp), %rax
cmpq $0x0, 0x20(%rax)
sete %al
movzbl %al, %edi
andl $0x1, %edi
movl $0x2, %esi
callq 0xbe90
movq 0x70(%rsp), %rax
cmpl $0x1c, 0x2c(%rax)
jg 0x31d11
movq 0x70(%rsp), %rsi
movq 0x68(%rsp), %rdi
movl $0x4b8, %edx            # imm = 0x4B8
callq 0x4260
movq 0x50(%rsp), %rcx
movq 0x68(%rsp), %rax
movq %rcx, 0x20(%rax)
movq 0x4a35e38(%rip), %rcx   # 0x4a67b30
movq 0x68(%rsp), %rax
movq %rcx, (%rax)
movq 0x68(%rsp), %rax
movq %rax, 0x4a35e24(%rip)   # 0x4a67b30
jmp 0x324e3
movl 0x3a35dc1(%rip), %eax   # 0x3a67ad8
addl $0x1, %eax
movl %eax, 0x3a35db8(%rip)   # 0x3a67ad8
movq 0x70(%rsp), %rax
addq $0x38, %rax
movq 0x70(%rsp), %rcx
movl 0x2c(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movq 0x70(%rsp), %rax
subsd 0x38(%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movq 0x70(%rsp), %rcx
movl 0x2c(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movq 0x70(%rsp), %rax
subsd 0x40(%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movq 0x70(%rsp), %rcx
movl 0x2c(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movq 0x70(%rsp), %rax
subsd 0x48(%rax), %xmm0
movsd %xmm0, 0x40(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x11bc0
movq 0x70(%rsp), %rax
movl 0x2c(%rax), %eax
subl $0x1, %eax
movl %eax, (%rsp)
cmpl $0x0, (%rsp)
jle 0x31f09
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl (%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq (%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
subsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl (%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq (%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
subsd 0x8(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl (%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq (%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
subsd 0x10(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x11bc0
movsd 0x10(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
movsd 0x18(%rsp), %xmm0
mulsd 0x38(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
movsd 0x40(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x85a5(%rip), %xmm0     # 0x3a480
ucomisd 0x8(%rsp), %xmm0
ja 0x31ef7
movsd 0x8(%rsp), %xmm0
movsd 0x9f0f(%rip), %xmm1     # 0x3be00
ucomisd %xmm1, %xmm0
jbe 0x31ef9
jmp 0x31f09
jmp 0x31efb
movl (%rsp), %eax
addl $-0x1, %eax
movl %eax, (%rsp)
jmp 0x31dd0
movq 0x70(%rsp), %rax
movsd 0x50(%rax), %xmm0
movq 0x70(%rsp), %rax
subsd 0x38(%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x70(%rsp), %rax
movsd 0x58(%rax), %xmm0
movq 0x70(%rsp), %rax
subsd 0x40(%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x70(%rsp), %rax
movsd 0x60(%rax), %xmm0
movq 0x70(%rsp), %rax
subsd 0x48(%rax), %xmm0
movsd %xmm0, 0x40(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x11bc0
movl $0x1, 0x4(%rsp)
movl 0x4(%rsp), %eax
movq 0x70(%rsp), %rcx
movl 0x2c(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x320b7
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x4(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x4(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
subsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x4(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x4(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
subsd 0x8(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x4(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x4(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
subsd 0x10(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x11bc0
movsd 0x10(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
movsd 0x18(%rsp), %xmm0
mulsd 0x38(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
movsd 0x40(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x83f9(%rip), %xmm0     # 0x3a480
ucomisd 0x8(%rsp), %xmm0
ja 0x320a3
movsd 0x8(%rsp), %xmm0
movsd 0x9d63(%rip), %xmm1     # 0x3be00
ucomisd %xmm1, %xmm0
jbe 0x320a5
jmp 0x320b7
jmp 0x320a7
movl 0x4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4(%rsp)
jmp 0x31f69
movl 0x4(%rsp), %eax
addl $0x2, %eax
cmpl $0x1c, %eax
jl 0x32249
movq 0x70(%rsp), %rax
movsd 0x38(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x70(%rsp), %rax
movsd 0x40(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x70(%rsp), %rax
movsd 0x48(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movl $0x1, 0x64(%rsp)
movl 0x64(%rsp), %eax
movq 0x70(%rsp), %rcx
cmpl 0x2c(%rcx), %eax
jge 0x321ca
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x64(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, (%rax)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x64(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x8(%rax)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x64(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x10(%rax)
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x320ff
movsd 0x10(%rsp), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movq 0x70(%rsp), %rcx
movl 0x2c(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, (%rax)
movsd 0x18(%rsp), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movq 0x70(%rsp), %rcx
movl 0x2c(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x8(%rax)
movsd 0x20(%rsp), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movq 0x70(%rsp), %rcx
movl 0x2c(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x10(%rax)
jmp 0x31d20
movq 0x70(%rsp), %rdi
callq 0x23d70
movq %rax, 0x58(%rsp)
movq 0x70(%rsp), %rax
cmpq $0x0, 0x20(%rax)
sete %al
movzbl %al, %edi
andl $0x1, %edi
movl $0x2, %esi
callq 0xbe90
movq 0x50(%rsp), %rcx
movq 0x58(%rsp), %rax
movq %rcx, 0x20(%rax)
movq 0x58(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x4a3589c(%rip), %rcx   # 0x4a67b30
movq 0x58(%rsp), %rax
movq %rcx, (%rax)
movq 0x58(%rsp), %rax
movq %rax, 0x4a35888(%rip)   # 0x4a67b30
movq 0x70(%rsp), %rax
movl 0x2c(%rax), %eax
subl 0x4(%rsp), %eax
cmpl $0x1c, %eax
jg 0x322ca
movl 0x4(%rsp), %ecx
addl $0x2, %ecx
movq 0x58(%rsp), %rax
movl %ecx, 0x2c(%rax)
jmp 0x32303
movl (%rsp), %eax
addl $0x2, %eax
cmpl $0x1c, %eax
jge 0x322f5
movq 0x70(%rsp), %rax
movl 0x2c(%rax), %eax
subl (%rsp), %eax
cmpl $0x1c, %eax
jg 0x322f5
movl (%rsp), %ecx
addl $0x2, %ecx
movq 0x58(%rsp), %rax
movl %ecx, 0x2c(%rax)
jmp 0x32301
movq 0x58(%rsp), %rax
movl $0x1c, 0x2c(%rax)
jmp 0x32303
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
movq 0x58(%rsp), %rcx
cmpl 0x2c(%rcx), %eax
jge 0x323c7
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movq 0x58(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, (%rax)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movq 0x58(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x8(%rax)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movq 0x58(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x10(%rax)
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x3230b
movq 0x58(%rsp), %rax
movl 0x2c(%rax), %eax
subl $0x1, %eax
movl %eax, 0x64(%rsp)
movl 0x64(%rsp), %eax
movq 0x70(%rsp), %rcx
cmpl 0x2c(%rcx), %eax
jge 0x324bf
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x64(%rsp), %ecx
movq 0x58(%rsp), %rdx
movl 0x2c(%rdx), %edx
subl $0x2, %edx
subl %edx, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, (%rax)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x64(%rsp), %ecx
movq 0x58(%rsp), %rdx
movl 0x2c(%rdx), %edx
subl $0x2, %edx
subl %edx, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x8(%rax)
movq 0x70(%rsp), %rax
addq $0x38, %rax
movslq 0x64(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movq 0x70(%rsp), %rax
addq $0x38, %rax
movl 0x64(%rsp), %ecx
movq 0x58(%rsp), %rdx
movl 0x2c(%rdx), %edx
subl $0x2, %edx
subl %edx, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x10(%rax)
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x323d6
movq 0x58(%rsp), %rax
movl 0x2c(%rax), %edx
subl $0x2, %edx
movq 0x70(%rsp), %rax
movl 0x2c(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x2c(%rax)
movb $0x1, %al
testb $0x1, %al
jne 0x31ca7
jmp 0x324e3
addq $0x78, %rsp
retq
nopl (%rax,%rax)