// File: /workspace/github_c_makefile_star2_O0/Nealsbo[P]C-Software-Renderer/src/objloader.c
// Function: Model_LoadOBJ
obj_model_t *Model_LoadOBJ( const char *file_name ){
    char line[MAX_NAME_LENGTH];
    FILE *fp;
    if( ( fp = fopen(file_name, "r") ) == NULL ){
        printf( "Error: Cannot open file '%s'!\n", file_name );
        return NULL;
    }
    
    obj_model_t *model = Model_Create(file_name);
    if( model == NULL ){
        printf("Error: Cannot create model for file '%s'!\n", file_name);
    }

    node_t *tmpnode = NULL;

    List *vertList  = (List *)malloc(sizeof(List));
    List *coordList = (List *)malloc(sizeof(List));
    List *normList  = (List *)malloc(sizeof(List));
    List *faceList  = (List *)malloc(sizeof(List));

    List_Init(vertList,  &vec3_printp, &free);
    List_Init(coordList, &vec2_printp, &free);
    List_Init(normList,  &vec3_printp, &free);
    List_Init(faceList,  &Face_Printp, &free);

    int fa[9] = {0};
    int i;
    int vertCount  = 0;
    int coordCount = 0;
    int normCount  = 0;
    int faceCount  = 0;

    while(!feof(fp)){
        if(fgets( line, MAX_NAME_LENGTH, fp )){
            if( line == NULL || line[0] == '#' )
                continue;

            if( line[0] == 'v' && line[1] == ' ' ){
                vertCount++;
                vec3 *tmpvec3 = (vec3 *)malloc( sizeof( vec3 ) );
                sscanf(&line[2], "%f %f %f", &tmpvec3->x, &tmpvec3->y, &tmpvec3->z);
                List_Push(vertList, tmpvec3);
            }

            if( line[0] == 'v' && line[1] == 't' ){
                coordCount++;
                vec2 *tmpvec2 = (vec2 *)malloc( sizeof( vec2 ) );
                sscanf(&line[3], "%f %f", &tmpvec2->x, &tmpvec2->y);
                List_Push(coordList, tmpvec2);
            }

            if( line[0] == 'v' && line[1] == 'n' ){
                normCount++;
                vec3 *tmpvec3 = (vec3 *)malloc( sizeof( vec3 ) );
                sscanf(&line[3], "%f %f %f", &tmpvec3->x, &tmpvec3->y, &tmpvec3->z);
                List_Push(normList, tmpvec3);
            }

            if( line[0] == 'f' && line[1] == ' ' ){
                faceCount++;
                obj_face_t *tmpface = (obj_face_t *)malloc( sizeof( obj_face_t ) );
                sscanf(&line[2], "%i/%i/%i %i/%i/%i %i/%i/%i", &fa[0], &fa[1], &fa[2], &fa[3], &fa[4], &fa[5], &fa[6], &fa[7], &fa[8]);
                //*tmpface = Face_Create( 3, vec3i_arrayToVec3ip(9, fa) );
                tmpface->vcount = 3;
                tmpface->indexes = vec3i_arrayToVec3ip(9, fa);
                List_Push(faceList, tmpface);
            }
        }
    }

    fclose(fp);

    vec3 *tmpv3 = NULL;
    vec2 *tmpv2 = NULL;
    obj_face_t *tmpf = NULL;

    model->vertCount = vertCount;
    model->vertices = (vec3 *)malloc(sizeof(vec3) * vertCount);
    tmpnode = List_Head(vertList);
    tmpv3 = (vec3 *)List_Data(tmpnode);
    for(i = 0; i < vertCount; i++){
        tmpv3 = List_Data(tmpnode);
        model->vertices[i] = *tmpv3;
        tmpnode = List_Next(tmpnode);
    } tmpv3 = NULL;

    model->coordCount = coordCount;
    model->textcoords = (vec2 *)malloc(sizeof(vec2) * coordCount);
    tmpnode = List_Head(coordList);
    tmpv2 = (vec2 *)List_Data(tmpnode);
    for(i = 0; i < coordCount; i++){
        tmpv2 = List_Data(tmpnode);
        model->textcoords[i] = *tmpv2;
        tmpnode = List_Next(tmpnode);
    } tmpv2 = NULL;

    model->normCount = normCount;
    model->normals = (vec3 *)malloc(sizeof(vec3) * normCount);
    tmpnode = List_Head(normList);
    tmpv3 = (vec3 *)List_Data(tmpnode);
    for(i = 0; i < normCount; i++){
        tmpv3 = List_Data(tmpnode);
        model->normals[i] = *tmpv3;
        tmpnode = List_Next(tmpnode);
    }

    model->trisCount = faceCount;
    model->faces = (obj_face_t *)malloc(sizeof(obj_face_t) * faceCount);
    tmpnode = List_Head(faceList);
    tmpf = (obj_face_t *)List_Data(tmpnode);
    for(i = 0; i < faceCount; i++){
        tmpf = List_Data(tmpnode);
        model->faces[i] = *tmpf;
        tmpnode = List_Next(tmpnode);
    }
    
    model->position    = vec3_create(0.0, 0.0, 0.0);
    model->rotation    = vec3_create(0.0, 0.0, 0.0);
    model->scale       = vec3_create(1.0, 1.0, 1.0);

    model->diffmap = (texture_t *)malloc(sizeof(texture_t));
    model->diffmap->bitmap = Bitmap_LoadPPM6("./assets/texture.ppm");
    
    model->normalmap = (texture_t *)malloc(sizeof(texture_t));
    model->normalmap->bitmap = Bitmap_LoadPPM6("./assets/texture_n.ppm");

    List_Destroy(vertList);
    List_Destroy(coordList);
    List_Destroy(normList);
    List_Destroy(faceList);

    return model;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x270, %rsp            # imm = 0x270
movq %rdi, -0x20(%rbp)
movq -0x20(%rbp), %rdi
leaq 0x4609(%rip), %rsi      # 0xe0a6
callq 0x1190
movq %rax, -0x128(%rbp)
cmpq $0x0, %rax
jne 0x9ace
movq -0x20(%rbp), %rsi
leaq 0x4f5c(%rip), %rdi      # 0xea16
movb $0x0, %al
callq 0x1040
movq $0x0, -0x18(%rbp)
jmp 0xa440
movq -0x20(%rbp), %rdi
callq 0x8570
movq %rax, -0x130(%rbp)
cmpq $0x0, -0x130(%rbp)
jne 0x9afa
movq -0x20(%rbp), %rsi
leaq 0x4f42(%rip), %rdi      # 0xea35
movb $0x0, %al
callq 0x1040
movq $0x0, -0x138(%rbp)
movl $0x28, %edi
callq 0x11b0
movq %rax, -0x140(%rbp)
movl $0x28, %edi
callq 0x11b0
movq %rax, -0x148(%rbp)
movl $0x28, %edi
callq 0x11b0
movq %rax, -0x150(%rbp)
movl $0x28, %edi
callq 0x11b0
movq %rax, -0x158(%rbp)
movq -0x140(%rbp), %rdi
leaq -0x4c07(%rip), %rsi     # 0x4f50
movq 0x9482(%rip), %rdx      # 0x12fe0
callq 0x2950
movq -0x148(%rbp), %rdi
leaq -0x5cd1(%rip), %rsi     # 0x3ea0
movq 0x9468(%rip), %rdx      # 0x12fe0
callq 0x2950
movq -0x150(%rbp), %rdi
leaq -0x4c3b(%rip), %rsi     # 0x4f50
movq 0x944e(%rip), %rdx      # 0x12fe0
callq 0x2950
movq -0x158(%rbp), %rdi
leaq -0x16e5(%rip), %rsi     # 0x84c0
movq 0x9434(%rip), %rdx      # 0x12fe0
callq 0x2950
leaq -0x180(%rbp), %rdi
xorl %esi, %esi
movl $0x24, %edx
callq 0x10c0
movl $0x0, -0x188(%rbp)
movl $0x0, -0x18c(%rbp)
movl $0x0, -0x190(%rbp)
movl $0x0, -0x194(%rbp)
movq -0x128(%rbp), %rdi
callq 0x11f0
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x9c09
jmp 0x9ec7
leaq -0x120(%rbp), %rdi
movq -0x128(%rbp), %rdx
movl $0x100, %esi            # imm = 0x100
callq 0x1210
cmpq $0x0, %rax
je 0x9ec2
movsbl -0x120(%rbp), %eax
cmpl $0x23, %eax
jne 0x9c39
jmp 0x9bec
movsbl -0x120(%rbp), %eax
cmpl $0x76, %eax
jne 0x9cba
movsbl -0x11f(%rbp), %eax
cmpl $0x20, %eax
jne 0x9cba
movl -0x188(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x188(%rbp)
movl $0xc, %edi
callq 0x11b0
movq %rax, -0x1a0(%rbp)
leaq -0x120(%rbp), %rdi
addq $0x2, %rdi
movq -0x1a0(%rbp), %rdx
movq -0x1a0(%rbp), %rcx
addq $0x4, %rcx
movq -0x1a0(%rbp), %r8
addq $0x8, %r8
leaq 0x4dc0(%rip), %rsi      # 0xea60
movb $0x0, %al
callq 0x1150
movq -0x140(%rbp), %rdi
movq -0x1a0(%rbp), %rsi
callq 0x2ab0
movsbl -0x120(%rbp), %eax
cmpl $0x76, %eax
jne 0x9d30
movsbl -0x11f(%rbp), %eax
cmpl $0x74, %eax
jne 0x9d30
movl -0x18c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18c(%rbp)
movl $0x8, %edi
callq 0x11b0
movq %rax, -0x1a8(%rbp)
leaq -0x120(%rbp), %rdi
addq $0x3, %rdi
movq -0x1a8(%rbp), %rdx
movq -0x1a8(%rbp), %rcx
addq $0x4, %rcx
leaq 0x4d4d(%rip), %rsi      # 0xea63
movb $0x0, %al
callq 0x1150
movq -0x148(%rbp), %rdi
movq -0x1a8(%rbp), %rsi
callq 0x2ab0
movsbl -0x120(%rbp), %eax
cmpl $0x76, %eax
jne 0x9db1
movsbl -0x11f(%rbp), %eax
cmpl $0x6e, %eax
jne 0x9db1
movl -0x190(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x190(%rbp)
movl $0xc, %edi
callq 0x11b0
movq %rax, -0x1b0(%rbp)
leaq -0x120(%rbp), %rdi
addq $0x3, %rdi
movq -0x1b0(%rbp), %rdx
movq -0x1b0(%rbp), %rcx
addq $0x4, %rcx
movq -0x1b0(%rbp), %r8
addq $0x8, %r8
leaq 0x4cc9(%rip), %rsi      # 0xea60
movb $0x0, %al
callq 0x1150
movq -0x150(%rbp), %rdi
movq -0x1b0(%rbp), %rsi
callq 0x2ab0
movsbl -0x120(%rbp), %eax
cmpl $0x66, %eax
jne 0x9ec0
movsbl -0x11f(%rbp), %eax
cmpl $0x20, %eax
jne 0x9ec0
movl -0x194(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x194(%rbp)
movl $0x10, %edi
callq 0x11b0
movq %rax, -0x1b8(%rbp)
leaq -0x120(%rbp), %rdi
addq $0x2, %rdi
leaq -0x180(%rbp), %rdx
leaq -0x180(%rbp), %rcx
addq $0x4, %rcx
leaq -0x180(%rbp), %r8
addq $0x8, %r8
leaq -0x180(%rbp), %r9
addq $0xc, %r9
leaq -0x180(%rbp), %r14
addq $0x10, %r14
leaq -0x180(%rbp), %rbx
addq $0x14, %rbx
leaq -0x180(%rbp), %r11
addq $0x18, %r11
leaq -0x180(%rbp), %r10
addq $0x1c, %r10
leaq -0x180(%rbp), %rax
addq $0x20, %rax
leaq 0x4c07(%rip), %rsi      # 0xea69
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movq %r11, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movb $0x0, %al
callq 0x1150
movq -0x1b8(%rbp), %rax
movl $0x3, (%rax)
leaq -0x180(%rbp), %rsi
movl $0x9, %edi
callq 0x3f80
movq %rax, %rcx
movq -0x1b8(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x158(%rbp), %rdi
movq -0x1b8(%rbp), %rsi
callq 0x2ab0
jmp 0x9ec2
jmp 0x9bec
movq -0x128(%rbp), %rdi
callq 0x1160
movq $0x0, -0x1c0(%rbp)
movq $0x0, -0x1c8(%rbp)
movq $0x0, -0x1d0(%rbp)
movl -0x188(%rbp), %ecx
movq -0x130(%rbp), %rax
movl %ecx, 0x120(%rax)
movslq -0x188(%rbp), %rax
imulq $0xc, %rax, %rdi
callq 0x11b0
movq %rax, %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x100(%rax)
movq -0x140(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1c0(%rbp)
movl $0x0, -0x184(%rbp)
movl -0x184(%rbp), %eax
cmpl -0x188(%rbp), %eax
jge 0x9fc6
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1c0(%rbp)
movq -0x130(%rbp), %rax
movq 0x100(%rax), %rax
movslq -0x184(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq -0x1c0(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x138(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x138(%rbp)
movl -0x184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x184(%rbp)
jmp 0x9f55
movq $0x0, -0x1c0(%rbp)
movl -0x18c(%rbp), %ecx
movq -0x130(%rbp), %rax
movl %ecx, 0x124(%rax)
movslq -0x18c(%rbp), %rdi
shlq $0x3, %rdi
callq 0x11b0
movq %rax, %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x118(%rax)
movq -0x148(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1c8(%rbp)
movl $0x0, -0x184(%rbp)
movl -0x184(%rbp), %eax
cmpl -0x18c(%rbp), %eax
jge 0xa097
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1c8(%rbp)
movq -0x130(%rbp), %rax
movq 0x118(%rax), %rax
movslq -0x184(%rbp), %rcx
movq -0x1c8(%rbp), %rdx
movq (%rdx), %rdx
movq %rdx, (%rax,%rcx,8)
movq -0x138(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x138(%rbp)
movl -0x184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x184(%rbp)
jmp 0xa032
movq $0x0, -0x1c8(%rbp)
movl -0x190(%rbp), %ecx
movq -0x130(%rbp), %rax
movl %ecx, 0x128(%rax)
movslq -0x190(%rbp), %rax
imulq $0xc, %rax, %rdi
callq 0x11b0
movq %rax, %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x110(%rax)
movq -0x150(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1c0(%rbp)
movl $0x0, -0x184(%rbp)
movl -0x184(%rbp), %eax
cmpl -0x190(%rbp), %eax
jge 0xa174
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1c0(%rbp)
movq -0x130(%rbp), %rax
movq 0x110(%rax), %rax
movslq -0x184(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq -0x1c0(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x138(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x138(%rbp)
movl -0x184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x184(%rbp)
jmp 0xa103
movl -0x194(%rbp), %ecx
movq -0x130(%rbp), %rax
movl %ecx, 0x12c(%rax)
movslq -0x194(%rbp), %rdi
shlq $0x4, %rdi
callq 0x11b0
movq %rax, %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x108(%rax)
movq -0x158(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1d0(%rbp)
movl $0x0, -0x184(%rbp)
movl -0x184(%rbp), %eax
cmpl -0x194(%rbp), %eax
jge 0xa248
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1d0(%rbp)
movq -0x130(%rbp), %rax
movq 0x108(%rax), %rax
movslq -0x184(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq -0x1d0(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x8(%rax)
movq -0x138(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x138(%rbp)
movl -0x184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x184(%rbp)
jmp 0xa1d5
movq -0x130(%rbp), %rax
movq %rax, -0x250(%rbp)
xorps %xmm2, %xmm2
movss %xmm2, -0x244(%rbp)
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x4270
movq -0x250(%rbp), %rax
movss -0x244(%rbp), %xmm2
movss %xmm1, -0x1e8(%rbp)
movlpd %xmm0, -0x1f0(%rbp)
movl -0x1e8(%rbp), %ecx
movl %ecx, -0x1d8(%rbp)
movq -0x1f0(%rbp), %rcx
movq %rcx, -0x1e0(%rbp)
movl -0x1d8(%rbp), %ecx
movl %ecx, 0x138(%rax)
movq -0x1e0(%rbp), %rcx
movq %rcx, 0x130(%rax)
movq -0x130(%rbp), %rax
movq %rax, -0x240(%rbp)
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x4270
movq -0x240(%rbp), %rax
movss %xmm1, -0x208(%rbp)
movlpd %xmm0, -0x210(%rbp)
movl -0x208(%rbp), %ecx
movl %ecx, -0x1f8(%rbp)
movq -0x210(%rbp), %rcx
movq %rcx, -0x200(%rbp)
movl -0x1f8(%rbp), %ecx
movl %ecx, 0x144(%rax)
movq -0x200(%rbp), %rcx
movq %rcx, 0x13c(%rax)
movq -0x130(%rbp), %rax
movq %rax, -0x238(%rbp)
movss 0x3ccb(%rip), %xmm2     # 0xe004
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x4270
movq -0x238(%rbp), %rax
movss %xmm1, -0x228(%rbp)
movlpd %xmm0, -0x230(%rbp)
movq -0x230(%rbp), %rcx
movq %rcx, -0x21c(%rbp)
movl -0x228(%rbp), %ecx
movl %ecx, -0x214(%rbp)
movq -0x21c(%rbp), %rcx
movq %rcx, 0x148(%rax)
movl -0x214(%rbp), %ecx
movl %ecx, 0x150(%rax)
movl $0x8, %edi
callq 0x11b0
movq %rax, %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x158(%rax)
leaq 0x4639(%rip), %rdi      # 0xe9ea
callq 0x31f0
movq %rax, %rcx
movq -0x130(%rbp), %rax
movq 0x158(%rax), %rax
movq %rcx, (%rax)
movl $0x8, %edi
callq 0x11b0
movq %rax, %rcx
movq -0x130(%rbp), %rax
movq %rcx, 0x160(%rax)
leaq 0x4613(%rip), %rdi      # 0xe9ff
callq 0x31f0
movq %rax, %rcx
movq -0x130(%rbp), %rax
movq 0x160(%rax), %rax
movq %rcx, (%rax)
movq -0x140(%rbp), %rdi
callq 0x29a0
movq -0x148(%rbp), %rdi
callq 0x29a0
movq -0x150(%rbp), %rdi
callq 0x29a0
movq -0x158(%rbp), %rdi
callq 0x29a0
movq -0x130(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
addq $0x270, %rsp            # imm = 0x270
popq %rbx
popq %r14
popq %rbp
retq