// File: FreeSlave[P]vhlt/hlcsg/brushunion.cpp
// Function: AddPlaneToUnion(brushhull_t*, int)
static void     AddPlaneToUnion(brushhull_t* hull, const int planenum)
{
    bool            need_new_face = false;

    bface_t*        new_face_list;

    bface_t*        face;
    bface_t*        next;

    plane_t*        split;
    Winding*        front;
    Winding*        back;

    new_face_list = NULL;

    next = NULL;

    hlassert(hull);

    if (!hull->faces)
    {
        return;
    }
    hlassert(hull->faces->w);

    for (face = hull->faces; face; face = next)
    {
        hlassert(face->w);
        next = face->next;

        // Duplicate plane, ignore
        if (face->planenum == planenum)
        {
            AddFaceToList(&new_face_list, CopyFace(face));
            continue;
        }

        split = &g_mapplanes[planenum];
        face->w->Clip(split->normal, split->dist, &front, &back);

        if (front)
        {
            delete front;
            need_new_face = true;

            if (back)
            {                                              // Intersected the face
                delete face->w;
                face->w = back;
                AddFaceToList(&new_face_list, CopyFace(face));
            }
        }
        else
        {
            // Completely missed it, back is identical to face->w so it is destroyed
            if (back)
            {
                delete back;
                AddFaceToList(&new_face_list, CopyFace(face));
            }
        }
        hlassert(face->w);
    }

    FreeFaceList(hull->faces);
    hull->faces = new_face_list;

    if (need_new_face && (NumberOfHullFaces(hull) > 2))
    {
        Winding*        new_winding = NewWindingFromPlane(hull, planenum);

        if (new_winding)
        {
            bface_t*        new_face = (bface_t*)Alloc(sizeof(bface_t));

            new_face->planenum = planenum;
            new_face->w = new_winding;

            new_face->next = hull->faces;
            hull->faces = new_face;
        }
    }
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movl %esi, 0x5c(%rsp)
movb $0x0, 0x5b(%rsp)
movq $0x0, 0x50(%rsp)
movq $0x0, 0x40(%rsp)
movq 0x60(%rsp), %rax
cmpq $0x0, 0x30(%rax)
jne 0x19465
jmp 0x19655
movq 0x60(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x48(%rsp)
cmpq $0x0, 0x48(%rsp)
je 0x195be
movq 0x48(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rax
movl 0x8(%rax), %eax
cmpl 0x5c(%rsp), %eax
jne 0x194b6
movq 0x48(%rsp), %rdi
callq 0x20330
movq %rax, %rsi
leaq 0x50(%rsp), %rdi
callq 0x19ca0
jmp 0x195af
movslq 0x5c(%rsp), %rcx
leaq 0x20c14de(%rip), %rax   # 0x20da9a0
shlq $0x6, %rcx
addq %rcx, %rax
movq %rax, 0x38(%rsp)
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x38(%rsp), %rsi
movq 0x38(%rsp), %rax
movsd 0x30(%rax), %xmm0
leaq 0x30(%rsp), %rdx
leaq 0x28(%rsp), %rcx
movsd 0x14160(%rip), %xmm1    # 0x2d658
callq 0xfe00
cmpq $0x0, 0x30(%rsp)
je 0x19573
movq 0x30(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x19520
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movb $0x1, 0x5b(%rsp)
cmpq $0x0, 0x28(%rsp)
je 0x19571
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x1954c
movq 0x8(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq 0x28(%rsp), %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x48(%rsp), %rdi
callq 0x20330
movq %rax, %rsi
leaq 0x50(%rsp), %rdi
callq 0x19ca0
jmp 0x195ad
cmpq $0x0, 0x28(%rsp)
je 0x195ab
movq 0x28(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x19594
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq 0x48(%rsp), %rdi
callq 0x20330
movq %rax, %rsi
leaq 0x50(%rsp), %rdi
callq 0x19ca0
jmp 0x195ad
jmp 0x195af
movq 0x40(%rsp), %rax
movq %rax, 0x48(%rsp)
jmp 0x19473
movq 0x60(%rsp), %rax
movq 0x30(%rax), %rdi
callq 0x20420
movq 0x50(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x30(%rax)
testb $0x1, 0x5b(%rsp)
je 0x19655
movq 0x60(%rsp), %rdi
callq 0x19d10
cmpl $0x2, %eax
jle 0x19655
movq 0x60(%rsp), %rdi
movl 0x5c(%rsp), %esi
callq 0x19d80
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x20(%rsp)
je 0x19653
movl $0x68, %edi
callq 0x4aa0
movq %rax, 0x18(%rsp)
movl 0x5c(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x20(%rsp), %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x60(%rsp), %rax
movq 0x30(%rax), %rcx
movq 0x18(%rsp), %rax
movq %rcx, (%rax)
movq 0x18(%rsp), %rcx
movq 0x60(%rsp), %rax
movq %rcx, 0x30(%rax)
jmp 0x19655
addq $0x68, %rsp
retq
nopw (%rax,%rax)