// File: /workspace/github_c_makefile_star2_O1/FredTheDino[P]Fog/src/engine/logic/block_physics.cpp
// Function: Physics::add_shape(unsigned int, Vec2*)
ShapeID add_shape(u32 points_length, Vec2 *points) {
    // Assumes the shape is convex.
    ASSERT(points_length != 0, "Invalid list!");
    Shape shape = {};
    shape.points = create_list<Vec2>(points_length);

    // Check for non-convex polygons.
    // We can do this while looping over
    // the points checking for the center, but I don't
    // think performance will be an issue here.
    // -- Ed
    u32 positiv_cross = 0;
    u32 negative_cross = 0;
    for (u32 i = 0; i < points_length; i++) {
        Vec2 a = points[(i - 1) % points_length];
        Vec2 b = points[(i + 0) % points_length];
        Vec2 c = points[(i + 1) % points_length];
        Vec2 ab = b - a;
        Vec2 bc = c - b;
        auto winding_is_positive = [](Vec2 a, Vec2 b) -> b8 {
            return (a.x * b.y - a.y * b.x) > 0;
        };
        if (winding_is_positive(ab, bc))
            positiv_cross += 1;
        else
            negative_cross += 1;

        if (positiv_cross != 0 && negative_cross != 0) {
            char *shape_dump = Util::format_int("\t%.5f, %.5f\n",
                                            points[0].x, points[1].y);
            for (u32 a = 1; a < points_length; a++) {
                shape_dump = Util::format_int("%s\t%.5f, %.5f\n",
                                          shape_dump, points[a].x, points[a].y);
            }
            ERR("Invalid shape, a given shape is not convex. The shape was:\n %s",
                shape_dump);
            ASSERT(false, "Invalid shape.");
        }
    }


    // We need the center to lay inside the shapes
    // for the SAT algorithm to work.
    Vec2 center = V2(0, 0);
    for (u32 i = 0; i < points_length; i++) center = center + points[i];
    center /= (real) points_length;
    shape.center = center;

    for (u32 i = 0; i < points_length; i++)
        shape.points[i] = points[i] - center;
    shape.points.length = points_length;  // Change the length to match.
    // Allocate worstcase memory.
    // This is a tad wastefull but it shouldn't be much
    // since most shapes should be fairly simple in their
    // design, and they are reusable.
    shape.normals = create_list<Vec2>(points_length);
    for (u32 i = 0; i < points_length; i++) {
        Vec2 v = shape.points[i];
        Vec2 u = shape.points[(i + 1) % shape.points.length];

        Vec2 relative = normalize(v - u);
        Vec2 normal = {-relative.y, relative.x};

        // If they share the same axis with something else.
        // Sure it's slow to check now, but it does save time
        // in the long run since it can cut the checks in half
        // on a symetric shape. It's cool.
        for (u32 j = 0; j < shape.normals.length; j++) {
            if (ABS(dot(normal, shape.normals[j])) >= 0.98f) {
                goto _CONTINUE_OUTER_REG_SHAPE;
            }
        }

        shape.normals.append(normal);
    _CONTINUE_OUTER_REG_SHAPE:
        continue;
    }

    shape.id = global_shape_list.length;
    global_shape_list.append(shape);
    return shape.id;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rsi, %r14
movl %edi, %r15d
xorl %ecx, %ecx
testl %edi, %edi
setne %cl
leaq 0xd13b(%rip), %rdi      # 0x31a1b
leaq 0xd157(%rip), %rdx      # 0x31a3e
movl $0x14, %esi
callq 0x722f
xorl %ebx, %ebx
movl %ebx, -0x90(%rbp)
movq $0x0, -0x8c(%rbp)
xorps %xmm0, %xmm0
movups %xmm0, -0x80(%rbp)
movb %bl, -0x70(%rbp)
movups %xmm0, -0x68(%rbp)
movb %bl, -0x58(%rbp)
movl %r15d, %edi
callq 0x2fa2e
xorps %xmm2, %xmm2
movl %r15d, -0x68(%rbp)
movl %ebx, -0x64(%rbp)
movq %rax, -0x60(%rbp)
movb $0x1, -0x58(%rbp)
movl %r15d, %r13d
movl %r15d, -0x40(%rbp)
testl %r15d, %r15d
movq %r13, -0xa8(%rbp)
je 0x24ab7
leaq -0x1(%r13), %rbx
xorps %xmm5, %xmm5
leaq 0xd10c(%rip), %r15      # 0x31a60
xorl %r8d, %r8d
xorl %eax, %eax
xorl %r12d, %r12d
movl %r12d, %esi
movl %eax, %ecx
leal -0x1(%r8), %eax
xorl %edx, %edx
divl -0x40(%rbp)
movsd (%r14,%rdx,8), %xmm0
movsd (%r14,%r8,8), %xmm1
incq %r8
cmpq %r13, %r8
movl %r8d, %eax
movl $0x0, %edx
cmovneq %rax, %rdx
movss (%r14,%rdx,8), %xmm2
movss 0x4(%r14,%rdx,8), %xmm3
movaps %xmm1, %xmm4
subps %xmm0, %xmm4
subss %xmm1, %xmm2
shufps $0x55, %xmm1, %xmm1     # xmm1 = xmm1[1,1,1,1]
subss %xmm1, %xmm3
mulss %xmm4, %xmm3
shufps $0x55, %xmm4, %xmm4     # xmm4 = xmm4[1,1,1,1]
mulss %xmm4, %xmm2
subss %xmm2, %xmm3
xorl %eax, %eax
xorl %r12d, %r12d
ucomiss %xmm5, %xmm3
seta %al
setbe %r12b
addl %esi, %r12d
addl %ecx, %eax
je 0x24a98
testl %r12d, %r12d
je 0x24a98
movl %eax, -0xa0(%rbp)
movq %r8, -0x50(%rbp)
xorps %xmm0, %xmm0
cvtss2sd (%r14), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0xc(%r14), %xmm1
leaq 0xd066(%rip), %rdi      # 0x31a62
movb $0x2, %al
callq 0xaafe
cmpl $0x1, -0x40(%rbp)
je 0x24a35
xorl %r13d, %r13d
xorps %xmm0, %xmm0
cvtss2sd 0x8(%r14,%r13,8), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0xc(%r14,%r13,8), %xmm1
movq %r15, %rdi
movq %rax, %rsi
movb $0x2, %al
callq 0xaafe
incq %r13
cmpq %r13, %rbx
jne 0x24a0c
movq 0x2a594(%rip), %rcx     # 0x4efd0
movq (%rcx), %rsi
movq %rax, (%rsp)
leaq 0xc265(%rip), %rdi      # 0x30caf
leaq 0xcfca(%rip), %r13      # 0x31a1b
movq %r13, %rdx
movl $0x35, %ecx
leaq 0xd00f(%rip), %r8       # 0x31a6f
leaq 0xd012(%rip), %r9       # 0x31a79
xorl %eax, %eax
callq 0x711f
movq %r13, %rdi
movl $0x36, %esi
leaq 0xd03b(%rip), %rdx      # 0x31ab8
xorl %ecx, %ecx
callq 0x722f
movq -0xa8(%rbp), %r13
xorps %xmm5, %xmm5
movq -0x50(%rbp), %r8
movl -0xa0(%rbp), %eax
cmpq %r13, %r8
jne 0x2495c
xorps %xmm2, %xmm2
xorl %eax, %eax
movsd (%r14,%rax,8), %xmm0
addps %xmm0, %xmm2
incq %rax
cmpq %rax, %r13
jne 0x24aa6
xorps %xmm0, %xmm0
cvtsi2ss %r13, %xmm0
movss 0xb53d(%rip), %xmm1     # 0x30004
divss %xmm0, %xmm1
movaps %xmm1, %xmm3
mulss %xmm2, %xmm3
shufps $0x55, %xmm2, %xmm2     # xmm2 = xmm2[1,1,1,1]
mulss %xmm1, %xmm2
movaps %xmm3, %xmm0
unpcklps %xmm2, %xmm0            # xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
movlps %xmm0, -0x8c(%rbp)
cmpl $0x0, -0x40(%rbp)
je 0x24b62
xorl %ebx, %ebx
leaq 0x20ea8(%rip), %r15     # 0x4599e
leaq 0x20ebe(%rip), %r12     # 0x459bb
movaps %xmm2, -0xa0(%rbp)
movaps %xmm3, -0xc0(%rbp)
movss (%r14,%rbx,8), %xmm1
movss 0x4(%r14,%rbx,8), %xmm0
subss %xmm3, %xmm1
subss %xmm2, %xmm0
unpcklps %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
movaps %xmm1, -0x50(%rbp)
xorl %ecx, %ecx
cmpb $0x0, -0x58(%rbp)
setne %cl
movq %r15, %rdi
movl $0x21, %esi
movq %r12, %rdx
callq 0x722f
movaps -0xc0(%rbp), %xmm3
movaps -0xa0(%rbp), %xmm2
movq -0x60(%rbp), %rax
movaps -0x50(%rbp), %xmm0
movlps %xmm0, (%rax,%rbx,8)
incq %rbx
cmpq %rbx, %r13
jne 0x24b0b
movl -0x40(%rbp), %ebx
movl %ebx, -0x64(%rbp)
movl %ebx, %edi
callq 0x2fa2e
movl %ebx, -0x80(%rbp)
movl $0x0, -0x7c(%rbp)
movq %rax, -0x78(%rbp)
movb $0x1, -0x70(%rbp)
testl %ebx, %ebx
je 0x24d51
xorl %r14d, %r14d
leaq 0x20e0b(%rip), %r15     # 0x4599e
leaq 0x20e21(%rip), %r12     # 0x459bb
xorl %ecx, %ecx
cmpb $0x0, -0x58(%rbp)
setne %cl
movq %r15, %rdi
movl $0x21, %esi
movq %r12, %rdx
callq 0x722f
movq -0x60(%rbp), %rax
movss (%rax,%r14,8), %xmm0
movaps %xmm0, -0x40(%rbp)
movss 0x4(%rax,%r14,8), %xmm0
movaps %xmm0, -0x50(%rbp)
incq %r14
movl %r14d, %eax
xorl %edx, %edx
divl -0x64(%rbp)
movl %edx, %r13d
xorl %ecx, %ecx
cmpb $0x0, -0x58(%rbp)
setne %cl
movq %r15, %rdi
movl $0x21, %esi
movq %r12, %rdx
callq 0x722f
movq -0x60(%rbp), %rax
movsd (%rax,%r13,8), %xmm0
movaps -0x40(%rbp), %xmm2
subss %xmm0, %xmm2
shufps $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
movaps -0x50(%rbp), %xmm1
subss %xmm0, %xmm1
movaps %xmm1, -0x50(%rbp)
mulss %xmm1, %xmm1
movaps %xmm2, -0x40(%rbp)
movaps %xmm2, %xmm0
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
ucomiss 0xb609(%rip), %xmm0     # 0x30238
jb 0x24c37
sqrtss %xmm0, %xmm0
jmp 0x24c3c
callq 0x2480
movss 0xb3c0(%rip), %xmm1     # 0x30004
divss %xmm0, %xmm1
movaps -0x40(%rbp), %xmm0
mulss %xmm1, %xmm0
movaps %xmm0, -0x40(%rbp)
movaps -0x50(%rbp), %xmm0
xorps 0xb3e1(%rip), %xmm0     # 0x30040
mulss %xmm1, %xmm0
movaps %xmm0, -0x50(%rbp)
cmpl $0x0, -0x7c(%rbp)
setne %r13b
je 0x24d33
xorl %ebx, %ebx
xorl %ecx, %ecx
cmpb $0x0, -0x70(%rbp)
setne %cl
movq %r15, %rdi
movl $0x21, %esi
movq %r12, %rdx
callq 0x722f
movq -0x78(%rbp), %rax
movsd (%rax,%rbx,8), %xmm1
movaps %xmm1, %xmm0
shufps $0x55, %xmm1, %xmm0     # xmm0 = xmm0[1,1],xmm1[1,1]
mulss -0x40(%rbp), %xmm0
mulss -0x50(%rbp), %xmm1
addss %xmm0, %xmm1
movaps %xmm1, -0xa0(%rbp)
xorl %ecx, %ecx
cmpb $0x0, -0x70(%rbp)
setne %cl
movq %r15, %rdi
movl $0x21, %esi
movq %r12, %rdx
callq 0x722f
movq -0x78(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movaps %xmm0, %xmm1
shufps $0x55, %xmm0, %xmm1     # xmm1 = xmm1[1,1],xmm0[1,1]
mulss -0x40(%rbp), %xmm1
mulss -0x50(%rbp), %xmm0
addss %xmm1, %xmm0
movaps -0xa0(%rbp), %xmm2
cmpltss 0xb53c(%rip), %xmm2     # 0x30238
movaps %xmm2, %xmm1
andnps %xmm0, %xmm1
xorps 0xb337(%rip), %xmm0     # 0x30040
andps %xmm2, %xmm0
orps %xmm1, %xmm0
ucomiss 0xb53a(%rip), %xmm0     # 0x30250
jae 0x24d2d
incq %rbx
movl -0x7c(%rbp), %eax
cmpq %rax, %rbx
setb %r13b
jb 0x24c77
jmp 0x24d33
testb $0x1, %r13b
jne 0x24d44
movaps -0x50(%rbp), %xmm0
unpcklps -0x40(%rbp), %xmm0      # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
leaq -0x80(%rbp), %rdi
callq 0x2f316
cmpq -0xa8(%rbp), %r14
jne 0x24b9a
leaq 0x3fbf8(%rip), %rdi     # 0x64950
movl 0x4(%rdi), %eax
movl %eax, -0x90(%rbp)
movups -0x90(%rbp), %xmm0
movups -0x80(%rbp), %xmm1
movups -0x70(%rbp), %xmm2
movups -0x60(%rbp), %xmm3
movups %xmm3, 0x30(%rsp)
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
callq 0x2f378
movl -0x90(%rbp), %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq