// File: /workspace/github_c_makefile_star2_O0/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
subq $0x250, %rsp            # imm = 0x250
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x0, -0x4(%rbp)
setne %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
leaq 0x14abe(%rip), %rdi     # 0x469db
movl $0x14, %esi
leaq 0x14ad5(%rip), %rdx     # 0x469fe
movzbl %al, %ecx
callq 0xb210
movl $0x0, -0x50(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x4c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x48(%rbp)
leaq -0x50(%rbp), %rdi
addq $0x10, %rdi
callq 0x435d0
leaq -0x50(%rbp), %rdi
addq $0x28, %rdi
callq 0x435d0
movl -0x4(%rbp), %esi
leaq -0x68(%rbp), %rdi
callq 0x43600
movq -0x68(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x20(%rbp)
movb -0x58(%rbp), %al
movb %al, -0x18(%rbp)
movl $0x0, -0x6c(%rbp)
movl $0x0, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
cmpl -0x4(%rbp), %eax
jae 0x321e2
movq -0x10(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movl -0x74(%rbp), %eax
decl %eax
movl -0x4(%rbp), %ecx
xorl %edx, %edx
movl %edx, -0x1e4(%rbp)
divl %ecx
movq -0x1f8(%rbp), %rax
movl %edx, %ecx
movl -0x1e4(%rbp), %edx
movq (%rax,%rcx,8), %rax
movq %rax, -0x80(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movl -0x74(%rbp), %eax
movl -0x4(%rbp), %ecx
divl %ecx
movq -0x1f0(%rbp), %rax
movl %edx, %ecx
movl -0x1e4(%rbp), %edx
movq (%rax,%rcx,8), %rax
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movl -0x74(%rbp), %eax
incl %eax
movl -0x4(%rbp), %ecx
divl %ecx
movq -0x1e0(%rbp), %rax
movl %edx, %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0x90(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0xa0(%rbp)
movsd -0xa0(%rbp), %xmm0
leaq -0x88(%rbp), %rdi
callq 0x5850
movlpd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0xb0(%rbp)
movsd -0xb0(%rbp), %xmm0
leaq -0x90(%rbp), %rdi
callq 0x5850
movlpd %xmm0, -0xa8(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movsd -0xc0(%rbp), %xmm0
movsd -0xc8(%rbp), %xmm1
leaq -0xb1(%rbp), %rdi
callq 0x325b0
cmpb $0x0, %al
je 0x320c7
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x320d0
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
cmpl $0x0, -0x6c(%rbp)
je 0x321d2
cmpl $0x0, -0x70(%rbp)
je 0x321d2
movq -0x10(%rbp), %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movq -0x10(%rbp), %rax
movss 0xc(%rax), %xmm1
cvtss2sd %xmm1, %xmm1
leaq 0x1491e(%rip), %rdi     # 0x46a22
movb $0x2, %al
callq 0x102c0
movq %rax, -0xd0(%rbp)
movl $0x1, -0xd4(%rbp)
movl -0xd4(%rbp), %eax
cmpl -0x4(%rbp), %eax
jae 0x3217b
movq -0xd0(%rbp), %rsi
movq -0x10(%rbp), %rax
movl -0xd4(%rbp), %ecx
movss (%rax,%rcx,8), %xmm0
cvtss2sd %xmm0, %xmm0
movq -0x10(%rbp), %rax
movl -0xd4(%rbp), %ecx
movss 0x4(%rax,%rcx,8), %xmm1
cvtss2sd %xmm1, %xmm1
leaq 0x148c4(%rip), %rdi     # 0x46a20
movb $0x2, %al
callq 0x102c0
movq %rax, -0xd0(%rbp)
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd4(%rbp)
jmp 0x3211c
movq 0x36e5e(%rip), %rax     # 0x68fe0
movq (%rax), %rsi
movq -0xd0(%rbp), %rax
leaq 0x13adc(%rip), %rdi     # 0x45c6f
leaq 0x14841(%rip), %rdx     # 0x469db
movl $0x35, %ecx
leaq 0x14889(%rip), %r8      # 0x46a2f
leaq 0x1488c(%rip), %r9      # 0x46a39
movq %rax, (%rsp)
movb $0x0, %al
callq 0xb100
leaq 0x1481c(%rip), %rdi     # 0x469db
movl $0x36, %esi
leaq 0x148ad(%rip), %rdx     # 0x46a78
xorl %ecx, %ecx
callq 0xb210
jmp 0x321d4
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x31f99
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0xbc10
movlpd %xmm0, -0xdc(%rbp)
movl $0x0, -0xe0(%rbp)
movl -0xe0(%rbp), %eax
cmpl -0x4(%rbp), %eax
jae 0x3225a
movq -0x10(%rbp), %rax
movl -0xe0(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0xf0(%rbp)
movsd -0xf0(%rbp), %xmm0
leaq -0xdc(%rbp), %rdi
callq 0x40dc0
movlpd %xmm0, -0xe8(%rbp)
movq -0xe8(%rbp), %rax
movq %rax, -0xdc(%rbp)
movl -0xe0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe0(%rbp)
jmp 0x321ff
movl -0x4(%rbp), %eax
cvtsi2ss %rax, %xmm0
leaq -0xdc(%rbp), %rdi
callq 0x5440
movq -0xdc(%rbp), %rax
movq %rax, -0x4c(%rbp)
movl $0x0, -0xf4(%rbp)
movl -0xf4(%rbp), %eax
cmpl -0x4(%rbp), %eax
jae 0x322ed
movq -0x10(%rbp), %rax
movl -0xf4(%rbp), %ecx
leaq (%rax,%rcx,8), %rdi
movq -0xdc(%rbp), %rax
movq %rax, -0x108(%rbp)
movsd -0x108(%rbp), %xmm0
callq 0x5850
movlpd %xmm0, -0xfc(%rbp)
leaq -0x50(%rbp), %rdi
addq $0x28, %rdi
movl -0xf4(%rbp), %esi
callq 0x43650
movq -0xfc(%rbp), %rcx
movq %rcx, (%rax)
movl -0xf4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf4(%rbp)
jmp 0x32283
movl -0x4(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x4(%rbp), %esi
leaq -0x120(%rbp), %rdi
callq 0x43600
movq -0x120(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x118(%rbp), %rax
movq %rax, -0x38(%rbp)
movb -0x110(%rbp), %al
movb %al, -0x30(%rbp)
movl $0x0, -0x124(%rbp)
movl -0x124(%rbp), %eax
cmpl -0x4(%rbp), %eax
jae 0x32546
leaq -0x28(%rbp), %rdi
movq %rdi, -0x200(%rbp)
movl -0x124(%rbp), %esi
callq 0x43650
movq -0x200(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x130(%rbp)
movl -0x124(%rbp), %eax
incl %eax
movl -0x24(%rbp), %ecx
xorl %edx, %edx
divl %ecx
movl %edx, %esi
callq 0x43650
movq (%rax), %rax
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
movq %rax, -0x150(%rbp)
movsd -0x150(%rbp), %xmm0
leaq -0x130(%rbp), %rdi
callq 0x5850
movlpd %xmm0, -0x148(%rbp)
movsd -0x148(%rbp), %xmm0
callq 0xb410
movlpd %xmm0, -0x140(%rbp)
movss -0x13c(%rbp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss %xmm0, -0x158(%rbp)
movss -0x140(%rbp), %xmm0
movss %xmm0, -0x154(%rbp)
movl $0x0, -0x15c(%rbp)
movl -0x15c(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jae 0x32511
movq -0x158(%rbp), %rax
movq %rax, -0x168(%rbp)
leaq -0x40(%rbp), %rdi
movl -0x15c(%rbp), %esi
callq 0x43650
movq (%rax), %rax
movq %rax, -0x170(%rbp)
movsd -0x168(%rbp), %xmm0
movsd -0x170(%rbp), %xmm1
callq 0xb340
movaps %xmm0, %xmm1
xorps %xmm0, %xmm0
ucomiss %xmm1, %xmm0
jbe 0x324a0
movq -0x158(%rbp), %rax
movq %rax, -0x178(%rbp)
leaq -0x40(%rbp), %rdi
movl -0x15c(%rbp), %esi
callq 0x43650
movq (%rax), %rax
movq %rax, -0x180(%rbp)
movsd -0x178(%rbp), %xmm0
movsd -0x180(%rbp), %xmm1
callq 0xb340
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm0
movss %xmm0, -0x204(%rbp)
jmp 0x324e4
movq -0x158(%rbp), %rax
movq %rax, -0x188(%rbp)
leaq -0x40(%rbp), %rdi
movl -0x15c(%rbp), %esi
callq 0x43650
movq (%rax), %rax
movq %rax, -0x190(%rbp)
movsd -0x188(%rbp), %xmm0
movsd -0x190(%rbp), %xmm1
callq 0xb340
movss %xmm0, -0x204(%rbp)
movss -0x204(%rbp), %xmm0
movss 0x12d44(%rip), %xmm1    # 0x45238
ucomiss %xmm1, %xmm0
jb 0x324fb
jmp 0x32530
jmp 0x324fd
movl -0x15c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x15c(%rbp)
jmp 0x323f7
leaq -0x40(%rbp), %rdi
movq -0x158(%rbp), %rax
movq %rax, -0x198(%rbp)
movsd -0x198(%rbp), %xmm0
callq 0x436b0
jmp 0x32532
movl -0x124(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x124(%rbp)
jmp 0x3232b
leaq 0x4c433(%rip), %rax     # 0x7e980
movl 0x4(%rax), %eax
movl %eax, -0x50(%rbp)
leaq -0x1d8(%rbp), %rdi
leaq -0x50(%rbp), %rsi
movl $0x40, %edx
callq 0x2090
movups -0x1d8(%rbp), %xmm0
movups -0x1c8(%rbp), %xmm1
movups -0x1b8(%rbp), %xmm2
movups -0x1a8(%rbp), %xmm3
movq %rsp, %rax
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq 0x4c3e3(%rip), %rdi     # 0x7e980
callq 0x43730
movl -0x50(%rbp), %eax
addq $0x250, %rsp            # imm = 0x250
popq %rbp
retq
nop