decompiled_code:
void *__fastcall array_grow(__int64 a1)
{
return array_resize(a1, 3 * *(_DWORD *)(a1 + 8) / 2);
}

canonical_decompiled_code:
void *__fastcall func2(__int64 a1)
{
return func1(a1, 3 * *(_DWORD *)(a1 + 8) / 2);
}

original_code:
static void array_grow(kl_array_t *array) {
  int size = array->size * array_grow_mul / array_grow_div;
  array_resize(array, size);
}

canonical_original_code:
static void array_grow(struct kl_array *array) {
  int size = array->size * array_grow_mul / array_grow_div;
  array_resize(array, size);
}


repo: zvxryb/kludge-engine

decompiled_code:
void *__fastcall array_growto(__int64 a1, int a2, unsigned __int8 a3)
{
int v5; // er14
int i; // esi

v5 = *(_DWORD *)(a1 + 16);
for ( i = *(_DWORD *)(a1 + 8); a2 > i; i = 3 * i / 2 )
;
array_resize(a1, i);
return memset((void *)(*(_QWORD *)a1 + v5 * *(_DWORD *)(a1 + 12)), a3, *(_DWORD *)(a1 + 12) * (a2 - v5));
}

original_code:
static void array_growto(kl_array_t *array, int minsize, uint8_t clearbyte) {
  int oldsize = array->num_items;
  int size = array->size;
  while (size < minsize) {
    size = size * array_grow_mul / array_grow_div;
  }
  array_resize(array, size);
  memset(array->data + oldsize * array->item_size, clearbyte, (minsize - oldsize) * array->item_size);
}

canonical_original_code:
static void array_growto(struct kl_array *array, int minsize, unsigned char clearbyte) {
  int oldsize = array->num_items;
  int size = array->size;
  while (size < minsize) {
    size = size * array_grow_mul / array_grow_div;
  }
  array_resize(array, size);
  memset(array->data + oldsize * array->item_size, clearbyte, (minsize - oldsize) * array->item_size);
}

variable_types: struct kl_array { unsigned char *data; int size; int item_size; int num_items; } *

variable_types: minsize int

variable_types:
clearbyte
unsigned char

variable_types: oldsize int

variable_types: size int

return_type: void


decompiled_code:
void *__fastcall kl_array_init(__int64 a1, int a2)
{
void *result; // rax

result = malloc(a2 << 8);
*(_QWORD *)a1 = result;
*(_DWORD *)(a1 + 8) = 256;
*(_DWORD *)(a1 + 12) = a2;
*(_DWORD *)(a1 + 16) = 0;
return result;
}

canonical_decompiled_code:
void *__fastcall func4(__int64 a1, int a2)
{
void *result; // rax

result = malloc(a2 << 8);
*(_QWORD *)a1 = result;
*(_DWORD *)(a1 + 8) = 256;
*(_DWORD *)(a1 + 12) = a2;
*(_DWORD *)(a1 + 16) = 0;
return result;
}

original_code:
void kl_array_init(kl_array_t *array, int item_size) {
  array->data = malloc(array_initial_size * item_size);
  array->size = array_initial_size;
  array->item_size = item_size;
  array->num_items = 0;
}

canonical_original_code:
void kl_array_init(struct kl_array *array, int item_size) {
  array->data = malloc(array_initial_size * item_size);
  array->size = array_initial_size;
  array->item_size = item_size;
  array->num_items = 0;
}

user_defined_types: struct kl_array { unsigned char *data; int size; int item_size; int num_items; }


decompiled_code:
void *__fastcall kl_array_clear(__int64 a1)
{
void *result; // rax

free(*(void **)a1);
result = malloc((int)(*(_DWORD *)(a1 + 12) << 8));
*(_QWORD *)a1 = result;
*(_DWORD *)(a1 + 8) = 256;
*(_DWORD *)(a1 + 16) = 0;
return result;
}

canonical_decompiled_code:
void *__fastcall func5(__int64 a1)
{
void *result; // rax

free(*(void **)a1);
result = malloc((int)(*(_DWORD *)(a1 + 12) << 8));
*(_QWORD *)a1 = result;
*(_DWORD *)(a1 + 8) = 256;
*(_DWORD *)(a1 + 16) = 0;
return result;
}

original_code:
void kl_array_clear(kl_array_t *array) {
  free(array->data);
  array->data = malloc(array_initial_size * array->item_size);
  array->size = array_initial_size;
  array->num_items = 0;
}

canonical_original_code:
void kl_array_clear(struct kl_array *array) {
  free(array->data);
  array->data = malloc(array_initial_size * array->item_size);
  array->size = array_initial_size;
  array->num_items = 0;
}


original_code:
void kl_array_free(kl_array_t *array) {
  free(array->data);
  array->size = 0;
  array->item_size = 0;
  array->num_items = 0;
}

canonical_original_code:
void kl_array_free(struct kl_array *array) {
  free(array->data);
  array->size = 0;
  array->item_size = 0;
  array->num_items = 0;
}


decompiled_code:
__int64 __fastcall kl_array_push(__int64 a1, const void *a2)
{
unsigned int v2; // er12

v2 = *(_DWORD *)(a1 + 16);
*(_DWORD *)(a1 + 16) = v2 + 1;
if ( (signed int)(v2 + 1) > *(_DWORD *)(a1 + 8) )
{
array_grow(a1);
if ( (signed int)v2 >= *(_DWORD *)(a1 + 8) )
_assert_fail("i < array->size", "array.c", 0x2Du, "kl_array_push");
}
memcpy((void *)(*(_QWORD *)a1 + (int)(*(_DWORD *)(a1 + 12) * v2)), a2, *(int *)(a1 + 12));
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, const void *a2)
{
unsigned int v2; // er12

v2 = *(_DWORD *)(a1 + 16);
*(_DWORD *)(a1 + 16) = v2 + 1;
if ( (signed int)(v2 + 1) > *(_DWORD *)(a1 + 8) )
{
func2(a1);
if ( (signed int)v2 >= *(_DWORD *)(a1 + 8) )
_assert_fail("i < array->size", "array.c", 0x2Du, "kl_array_push");
}
memcpy((void *)(*(_QWORD *)a1 + (int)(*(_DWORD *)(a1 + 12) * v2)), a2, *(int *)(a1 + 12));
return v2;
}

original_code:
int kl_array_push(kl_array_t *array, void *item) {
  int i = array->num_items++;
  if (array->num_items > array->size) {
    array_grow(array);
    ((i < array->size) ? (void) (0) : __assert_fail ("i < array->size", "array.c", 45, __extension__ __PRETTY_FUNCTION__));
  }
  int bytes = array->item_size;
  memcpy(array->data + i * bytes, item, bytes);
  return i;
}

canonical_original_code:
int kl_array_push(struct kl_array *array, void *item) {
  int i = array->num_items++;
  if (array->num_items > array->size) {
    array_grow(array);
    ((i < array->size) ? (void) (0) : __assert_fail ("i < array->size", "array.c", 45, __extension__ __PRETTY_FUNCTION__));
  }
  int bytes = array->item_size;
  memcpy(array->data + i * bytes, item, bytes);
  return i;
}

variable_types:
item
void *

variable_types: i int

variable_types: bytes int

return_type: int


decompiled_code:
void *__fastcall kl_array_set_expand(__int64 a1, int a2, const void *a3, unsigned __int8 a4)
{
if ( *(_DWORD *)(a1 + 16) > a2 )
return kl_array_set(a1, a2, a3);
array_growto(a1, a2 + 1, a4);
*(_DWORD *)(a1 + 16) = a2 + 1;
return kl_array_set(a1, a2, a3);
}

canonical_decompiled_code:
void *__fastcall func8(__int64 a1, int a2, const void *a3, unsigned __int8 a4)
{
if ( *(_DWORD *)(a1 + 16) > a2 )
return func0(a1, a2, a3);
func3(a1, a2 + 1, a4);
*(_DWORD *)(a1 + 16) = a2 + 1;
return func0(a1, a2, a3);
}

original_code:
void kl_array_set_expand(kl_array_t *array, int i, void *item, uint8_t clearbyte) {
  if (i < array->num_items) {
    kl_array_set(array, i, item);
    return;
  }
  array_growto(array, i+1, clearbyte);
  array->num_items = i + 1;
  kl_array_set(array, i, item);
}

canonical_original_code:
void kl_array_set_expand(struct kl_array *array, int i, void *item, unsigned char clearbyte) {
  if (i < array->num_items) {
    kl_array_set(array, i, item);
    return;
  }
  array_growto(array, i+1, clearbyte);
  array->num_items = i + 1;
  kl_array_set(array, i, item);
}


checkfrustum

decompiled_code:
_BOOL8 __fastcall checkfrustum(float *a1, float *a2)
{
float v2; // xmm0_4
float v3; // er13
_BOOL8 result; // rax
float v5; // xmm0_4
float v6; // xmm0_4
float v7; // xmm0_4
float v8; // xmm0_4

v2 = kl_plane_dist(a2, a1);
v3 = a1[3];
result = 0LL;
if ( v2 <= v3 )
{
v5 = kl_plane_dist(a2 + 4, a1);
result = 0LL;
if ( v5 <= v3 )
{
v6 = kl_plane_dist(a2 + 8, a1);
result = 0LL;
if ( v6 <= v3 )
{
v7 = kl_plane_dist(a2 + 12, a1);
result = 0LL;
if ( v7 <= v3 )
{
v8 = kl_plane_dist(a2 + 16, a1);
result = 0LL;
if ( v8 <= v3 )
result = kl_plane_dist(a2 + 20, a1) <= v3;
}
}
}
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(float *a1, float *a2)
{
float v2; // xmm0_4
float v3; // er13
_BOOL8 result; // rax
float v5; // xmm0_4
float v6; // xmm0_4
float v7; // xmm0_4
float v8; // xmm0_4

v2 = func1(a2, a1);
v3 = a1[3];
result = 0LL;
if ( v2 <= v3 )
{
v5 = func1(a2 + 4, a1);
result = 0LL;
if ( v5 <= v3 )
{
v6 = func1(a2 + 8, a1);
result = 0LL;
if ( v6 <= v3 )
{
v7 = func1(a2 + 12, a1);
result = 0LL;
if ( v7 <= v3 )
{
v8 = func1(a2 + 16, a1);
result = 0LL;
if ( v8 <= v3 )
result = func1(a2 + 20, a1) <= v3;
}
}
}
}
return result;
}

original_code:
static int checkfrustum(kl_sphere_t *bounds, kl_frustum_t *frustum) {
  if (kl_plane_dist(&frustum->near, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->far, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->top, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->bottom, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->left, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->right, &bounds->center) > bounds->radius)
    return 0;
  return 1;
}

canonical_original_code:
static int checkfrustum(struct kl_sphere *bounds, struct kl_frustum *frustum) {
  if (kl_plane_dist(&frustum->near, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->far, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->top, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->bottom, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->left, &bounds->center) > bounds->radius)
    return 0;
  if (kl_plane_dist(&frustum->right, &bounds->center) > bounds->radius)
    return 0;
  return 1;
}

variable_types: struct kl_sphere { struct kl_vec3f { float x; } center; float radius; } *

variable_types: struct kl_frustum { struct kl_plane { struct kl_vec3f norm; float dist; } near; struct kl_plane top; } *

user_defined_types: struct kl_sphere { struct kl_vec3f center; float radius; }

user_defined_types: struct kl_frustum { struct kl_plane near; struct kl_plane top; }


alwaystrue

decompiled_code:
__int64 alwaystrue()
{
return 1LL;
}

canonical_decompiled_code:
__int64 func3()
{
return 1LL;
}

original_code:
static int alwaystrue(kl_sphere_t *bounds, void* _) {
  return 1;
}

canonical_original_code:
static int alwaystrue(struct kl_sphere *bounds, void *_) {
  return 1;
}


decompiled_code:
__int64 kl_render_init()
{
return kl_gl3_init();
}

canonical_decompiled_code:
__int64 func4()
{
return kl_gl3_init();
}

original_code:
int kl_render_init() {
  return kl_gl3_init();
}


decompiled_code:
__int64 __fastcall kl_render_draw(__int64 a1)
{
char v2[32]; // [rsp+0h] [rbp-50h] BYREF
char v3[40]; // [rsp+20h] [rbp-30h] BYREF

kl_camera_update_scene(a1, &scene_2);
kl_camera_update_frustum(a1, &frustum_1);
kl_gl3_update_scene(&scene_2);
kl_gl3_clear();
kl_array_init(v3, 8LL);
kl_bvh_search(bvh_models, checkfrustum, &frustum_1, v3);
kl_gl3_pass_gbuffer(v3);
kl_gl3_pass_envlight();
kl_array_init(v2, 8LL);
kl_bvh_search(bvh_lights, checkfrustum, &frustum_1, v2);
kl_gl3_pass_pointlight(v2);
kl_array_free(v2);
kl_timer_tick(&timer_0);
kl_gl3_composite();
kl_array_free(v3);
return kl_gl3_debugtex((unsigned int)debugmode);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
char v2[32]; // [rsp+0h] [rbp-50h] BYREF
char v3[40]; // [rsp+20h] [rbp-30h] BYREF

kl_camera_update_scene(a1, &scene_2);
kl_camera_update_frustum(a1, &frustum_1);
kl_gl3_update_scene(&scene_2);
kl_gl3_clear();
kl_array_init(v3, 8LL);
kl_bvh_search(bvh_models, checkfrustum, &frustum_1, v3);
kl_gl3_pass_gbuffer(v3);
kl_gl3_pass_envlight();
kl_array_init(v2, 8LL);
kl_bvh_search(bvh_lights, checkfrustum, &frustum_1, v2);
kl_gl3_pass_pointlight(v2);
kl_array_free(v2);
kl_timer_tick(&timer_0);
kl_gl3_composite();
kl_array_free(v3);
return kl_gl3_debugtex((unsigned int)debugmode);
}

original_code:
void kl_render_draw(kl_camera_t *cam) {
  static kl_scene_t scene;
  static kl_frustum_t frustum;
  kl_camera_update_scene(cam, &scene);
  kl_camera_update_frustum(cam, &frustum);
  kl_gl3_update_scene(&scene);
  kl_gl3_clear();
  kl_array_t models;
  kl_array_init(&models, sizeof(kl_model_t*));
  kl_bvh_search(bvh_models, (kl_bvh_filter_cb)&checkfrustum, &frustum, &models);
  kl_gl3_pass_gbuffer(&models);
  kl_gl3_pass_envlight();
  kl_array_t lights;
  kl_array_init(&lights, sizeof(kl_light_t*));
  kl_bvh_search(bvh_lights, (kl_bvh_filter_cb)&checkfrustum, &frustum, &lights);
  kl_gl3_pass_pointlight(&lights);
  kl_array_free(&lights);
  static kl_timer_t timer = { .time = -1.0f, .dt = 0.0f};
  float dt = kl_timer_tick(&timer);
  kl_gl3_composite(dt);
  kl_array_free(&models);
  kl_gl3_debugtex(debugmode);
}

canonical_original_code:
void kl_render_draw(struct kl_camera *cam) {
  static struct kl_scene scene;
  static struct kl_frustum frustum;
  kl_camera_update_scene(cam, &scene);
  kl_camera_update_frustum(cam, &frustum);
  kl_gl3_update_scene(&scene);
  kl_gl3_clear();
  struct kl_array models;
  kl_array_init(&models, sizeof(struct kl_model *));
  kl_bvh_search(bvh_models, (kl_bvh_filter_cb)&checkfrustum, &frustum, &models);
  kl_gl3_pass_gbuffer(&models);
  kl_gl3_pass_envlight();
  struct kl_array lights;
  kl_array_init(&lights, sizeof(struct kl_light *));
  kl_bvh_search(bvh_lights, (kl_bvh_filter_cb)&checkfrustum, &frustum, &lights);
  kl_gl3_pass_pointlight(&lights);
  kl_array_free(&lights);
  static struct kl_timer timer = { .time = -1.0f, .dt = 0.0f};
  float dt = kl_timer_tick(&timer);
  kl_gl3_composite(dt);
  kl_array_free(&models);
  kl_gl3_debugtex(debugmode);
}

variable_types: struct kl_camera { struct kl_vec3f { float x; } position; struct kl_quat { float r; } orientation; float aspect; float fov; struct kl_vec4f { float x; } viewport; float near; } *

variable_types: struct kl_scene { union kl_mat4f { float cell[16]; struct kl_vec4f { float x; } column[4]; } viewmatrix; union kl_mat4f projmatrix; union kl_mat4f iprojmatrix; union kl_mat4f vpmatrix; union kl_mat3f { float cell[9]; struct kl_vec3f { float x; } column[3]; } viewrot; struct kl_vec3f viewpos; struct kl_vec3f ray_eye[4]; struct kl_vec3f ray_world[4]; struct kl_vec4f viewport; float near; float far; }

variable_types: struct kl_frustum { struct kl_plane { struct kl_vec3f { float x; } norm; float dist; } near; struct kl_plane top; }

variable_types: struct kl_array { unsigned char *data; int size; int item_size; int num_items; }

variable_types:
timer
struct kl_timer { float time; }

variable_types: dt float

user_defined_types: struct kl_scene { union kl_mat4f viewmatrix; union kl_mat4f projmatrix; union kl_mat4f iprojmatrix; union kl_mat4f vpmatrix; union kl_mat3f viewrot; struct kl_vec3f viewpos; struct kl_vec3f ray_eye[4]; struct kl_vec3f ray_world[4]; struct kl_vec4f viewport; float near; float far; }

user_defined_types: struct kl_camera { struct kl_vec3f position; struct kl_quat orientation; float aspect; float fov; struct kl_vec4f viewport; float near; }

user_defined_types: union kl_mat4f { float cell[16]; struct kl_vec4f column[4]; }

user_defined_types: union kl_mat3f { float cell[9]; struct kl_vec3f column[3]; }

user_defined_types: struct kl_plane { struct kl_vec3f norm; float dist; }

user_defined_types: struct kl_model { int type; struct kl_sphere bounds; int winding; union kl_model_bufs bufs; unsigned int tris; unsigned int attribs; unsigned int mesh_n; struct kl_mesh mesh[]; }

user_defined_types: struct kl_light { struct kl_vec3f position; float scale; unsigned int id; }

user_defined_types: union kl_model_bufs { struct kl_model_bufs_prop prop; struct kl_model_bufs_actor actor; struct kl_model_bufs_terrain terrain; }

user_defined_types: struct kl_model_bufs_prop { unsigned int position; unsigned int texcoord; unsigned int normal; unsigned int tangent; }

user_defined_types: struct kl_model_bufs_actor { unsigned int position; unsigned int texcoord; unsigned int normal; unsigned int tangent; unsigned int blendidx; unsigned int blendwt; }

user_defined_types: struct kl_model_bufs_terrain { unsigned int position; unsigned int normal; unsigned int texweight; }

user_defined_types: struct kl_mesh { struct kl_material *material; unsigned int tris_i; }

user_defined_types: struct kl_material { char path[256]; struct kl_texture_t *diffuse; struct kl_texture_t *normal; struct kl_texture_t *specular; struct kl_texture_t *emissive; }

user_defined_types: struct kl_texture_t { char path[256]; unsigned int w; unsigned int id; }


decompiled_code:
__int64 __fastcall kl_render_query_models(__int64 a1)
{
return kl_bvh_search(bvh_models, alwaystrue, 0LL, a1);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
return kl_bvh_search(bvh_models, alwaystrue, 0LL, a1);
}

original_code:
void kl_render_query_models(kl_array_t *result) {
  kl_bvh_search(bvh_models, (kl_bvh_filter_cb)&alwaystrue, ((void *)0), result);
}

canonical_original_code:
void kl_render_query_models(struct kl_array *result) {
  kl_bvh_search(bvh_models, (kl_bvh_filter_cb)&alwaystrue, ((void *)0), result);
}

user_defined_types: struct kl_array { unsigned char *data; int size; int item_size; int num_items; }


decompiled_code:
void __fastcall kl_render_set_debug(int a1)
{
debugmode = a1;
}

canonical_decompiled_code:
void __fastcall func7(int a1)
{
debugmode = a1;
}

original_code:
void kl_render_set_debug(int mode) {
  debugmode = mode;
}

variable_types: mode int


decompiled_code:
__int64 __fastcall kl_render_add_model(__int64 a1)
{
return kl_bvh_insert(&bvh_models, a1 + 4, a1);
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
return kl_bvh_insert(&bvh_models, a1 + 4, a1);
}

original_code:
void kl_render_add_model(kl_model_t* model) {
  kl_bvh_insert(&bvh_models, &model->bounds, model);
}

canonical_original_code:
void kl_render_add_model(struct kl_model *model) {
  kl_bvh_insert(&bvh_models, &model->bounds, model);
}

variable_types: struct kl_model { int type; struct kl_sphere { struct kl_vec3f { float x; } center; float radius; } bounds; int winding; union kl_model_bufs { struct kl_model_bufs_prop { unsigned int position; unsigned int texcoord; unsigned int normal; unsigned int tangent; } prop; struct kl_model_bufs_actor { unsigned int position; unsigned int texcoord; unsigned int normal; unsigned int tangent; unsigned int blendidx; unsigned int blendwt; } actor; struct kl_model_bufs_terrain { unsigned int position; unsigned int normal; unsigned int texweight; } terrain; } bufs; unsigned int tris; unsigned int attribs; unsigned int mesh_n; struct kl_mesh { struct kl_material { char path[256]; struct kl_texture_t { char path[256]; unsigned int w; unsigned int id; } *diffuse; struct kl_texture_t *normal; struct kl_texture_t *specular; struct kl_texture_t *emissive; } *material; unsigned int tris_i; } mesh[]; } *

user_defined_types: struct kl_sphere { struct kl_vec3f center; float radius; }


decompiled_code:
__int64 kl_render_set_envlight()
{
return kl_gl3_update_envlight();
}

canonical_decompiled_code:
__int64 func9()
{
return kl_gl3_update_envlight();
}

original_code:
void kl_render_set_envlight(kl_vec3f_t *direction, float amb_r, float amb_g, float amb_b, float amb_intensity, float diff_r, float diff_g, float diff_b, float diff_intensity) {
  kl_gl3_update_envlight(direction, amb_r, amb_g, amb_b, amb_intensity, diff_r, diff_g, diff_b, diff_intensity);
}

canonical_original_code:
void kl_render_set_envlight(struct kl_vec3f *direction, float amb_r, float amb_g, float amb_b, float amb_intensity, float diff_r, float diff_g, float diff_b, float diff_intensity) {
  kl_gl3_update_envlight(direction, amb_r, amb_g, amb_b, amb_intensity, diff_r, diff_g, diff_b, diff_intensity);
}

variable_types:
direction
struct kl_vec3f { float x; } *


original_code:
void kl_render_add_light(kl_vec3f_t *position, float r, float g, float b, float intensity) {
  float radius = 16.0f * sqrtf(intensity);
  kl_light_t *light = malloc(sizeof(kl_light_t));
  *light = (kl_light_t){
    .position = *position,
    .scale = radius,
    .id = kl_gl3_upload_light(position, r, g, b, intensity)
  };
  kl_sphere_t bounds = {
    .center = { .x = position->x, .y = position->y, .z = position->z },
    .radius = radius
  };
  kl_bvh_insert(&bvh_lights, &bounds, light);
}

canonical_original_code:
void kl_render_add_light(struct kl_vec3f *position, float r, float g, float b, float intensity) {
  float radius = 16.0f * sqrtf(intensity);
  struct kl_light *light = malloc(sizeof(kl_light_t));
  *light = (struct kl_light){
    .position = *position,
    .scale = radius,
    .id = kl_gl3_upload_light(position, r, g, b, intensity)
  };
  struct kl_sphere bounds = {
    .center = { .x = position->x, .y = position->y, .z = position->z },
    .radius = radius
  };
  kl_bvh_insert(&bvh_lights, &bounds, light);
}

variable_types:
position
struct kl_vec3f { float x; } *

variable_types: r float

variable_types: g float

variable_types: b float

variable_types: intensity float

variable_types: radius float

variable_types: struct kl_light { struct kl_vec3f { float x; } position; float scale; unsigned int id; } *

variable_types: struct kl_sphere { struct kl_vec3f { float x; } center; float radius; }


decompiled_code:
__int64 kl_render_upload_vertdata()
{
return kl_gl3_upload_vertdata();
}

canonical_decompiled_code:
__int64 func11()
{
return kl_gl3_upload_vertdata();
}

original_code:
unsigned int kl_render_upload_vertdata(void *data, int n) {
  return kl_gl3_upload_vertdata(data, n);
}

variable_types:
data
void *

variable_types: n int

return_type: unsigned int


decompiled_code:
__int64 kl_render_upload_tris()
{
return kl_gl3_upload_tris();
}

canonical_decompiled_code:
__int64 func12()
{
return kl_gl3_upload_tris();
}

original_code:
unsigned int kl_render_upload_tris(unsigned int *data, int n) {
  return kl_gl3_upload_tris(data, n);
}

variable_types:
data
unsigned int *


decompiled_code:
__int64 __fastcall kl_render_upload_texture(__int64 a1, __int64 a2, __int64 a3, __int64 a4, unsigned __int8 a5, unsigned __int8 a6)
{
return kl_gl3_upload_texture(a1, a2, a3, a4, a5, a6);
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1, __int64 a2, __int64 a3, __int64 a4, unsigned __int8 a5, unsigned __int8 a6)
{
return kl_gl3_upload_texture(a1, a2, a3, a4, a5, a6);
}

original_code:
unsigned int kl_render_upload_texture(void *data, int w, int h, int format, _Bool clamp, _Bool filter) {
  return kl_gl3_upload_texture(data, w, h, format, clamp, filter);
}

variable_types: w int

variable_types: h int

variable_types: format int


decompiled_code:
__int64 kl_render_free_texture()
{
return kl_gl3_free_texture();
}

canonical_decompiled_code:
__int64 func14()
{
return kl_gl3_free_texture();
}

original_code:
void kl_render_free_texture(unsigned int texture) {
  kl_gl3_free_texture(texture);
}

variable_types:
texture
unsigned int


decompiled_code:
__int64 kl_render_define_attribs()
{
return kl_gl3_define_attribs();
}

canonical_decompiled_code:
__int64 func15()
{
return kl_gl3_define_attribs();
}

original_code:
unsigned int kl_render_define_attribs(int tris, kl_render_attrib_t *cfg, int n) {
  return kl_gl3_define_attribs(tris, cfg, n);
}

canonical_original_code:
unsigned int kl_render_define_attribs(int tris, struct kl_render_attrib *cfg, int n) {
  return kl_gl3_define_attribs(tris, cfg, n);
}

variable_types: tris int

variable_types: struct kl_render_attrib { unsigned int index; unsigned int size; unsigned int type; unsigned int buffer; } *


decompiled_code:
void __fastcall kl_vec3f_norm(__int64 a1, float *a2)
{
float v2; // xmm0_4

v2 = kl_vec3f_magnitude(a2);
if ( v2 == 0.0 )
{
*(_DWORD *)a1 = 0;
*(_DWORD *)(a1 + 4) = 0;
*(_DWORD *)(a1 + 8) = 0;
}
else
{
kl_vec3f_scale((float *)a1, a2, 1.0 / v2);
}
}

original_code:
static inline void kl_vec3f_norm(kl_vec3f_t *dst, kl_vec3f_t *src) {
  float m = kl_vec3f_magnitude(src);
  if (m == 0.0f) {
    *dst = (kl_vec3f_t){ .x = 0.0f, .y = 0.0f, .z = 0.0f };
    return;
  }
  float s = 1.0f/m;
  kl_vec3f_scale(dst, src, s);
}

canonical_original_code:
static inline void kl_vec3f_norm(struct kl_vec3f *dst, struct kl_vec3f *src) {
  float m = kl_vec3f_magnitude(src);
  if (m == 0.0f) {
    *dst = (struct kl_vec3f){ .x = 0.0f, .y = 0.0f, .z = 0.0f };
    return;
  }
  float s = 1.0f/m;
  kl_vec3f_scale(dst, src, s);
}

variable_types:
dst
struct kl_vec3f { float x; } *

variable_types:
src
struct kl_vec3f *

variable_types: m float

variable_types: s float


variable_types:
dst
struct kl_quat { float r; } *


decompiled_code:
float __fastcall kl_quat_magnitude(float *a1)
{
float v1; // xmm0_4
float result; // xmm0_4

v1 = (float)(a1[3] * a1[3]) + (float)((float)((float)(a1[1] * a1[1]) + (float)(*a1 * *a1)) + (float)(a1[2] * a1[2]));
if ( v1 < 0.0 )
result = sqrtf(v1);
else
result = fsqrt(v1);
return result;
}

canonical_decompiled_code:
float __fastcall func4(float *a1)
{
float v1; // xmm0_4
float result; // xmm0_4

v1 = (float)(a1[3] * a1[3]) + (float)((float)((float)(a1[1] * a1[1]) + (float)(*a1 * *a1)) + (float)(a1[2] * a1[2]));
if ( v1 < 0.0 )
result = sqrtf(v1);
else
result = fsqrt(v1);
return result;
}

original_code:
float kl_quat_magnitude(kl_quat_t *src) {
  return sqrtf(src->r * src->r + src->i * src->i + src->j * src->j + src->k * src->k);
}

canonical_original_code:
float kl_quat_magnitude(struct kl_quat *src) {
  return sqrtf(src->r * src->r + src->i * src->i + src->j * src->j + src->k * src->k);
}

variable_types:
src
struct kl_quat { float r; } *

return_type: float


decompiled_code:
void __fastcall kl_quat_norm(float *a1, float *a2)
{
float v2; // xmm0_4
float v3; // xmm3_4
float v4; // xmm2_4
float v5; // xmm1_4

v2 = kl_quat_magnitude(a2);
v3 = a2[1] / v2;
v4 = a2[2] / v2;
v5 = a2[3] / v2;
*a1 = *a2 / v2;
a1[1] = v3;
a1[2] = v4;
a1[3] = v5;
}

original_code:
void kl_quat_norm(kl_quat_t *dst, kl_quat_t *src) {
  float m = kl_quat_magnitude(src);
  *dst = (kl_quat_t){
    .r = src->r/m,
    .i = src->i/m,
    .j = src->j/m,
    .k = src->k/m
  };
}

canonical_original_code:
void kl_quat_norm(struct kl_quat *dst, struct kl_quat *src) {
  float m = kl_quat_magnitude(src);
  *dst = (struct kl_quat){
    .r = src->r/m,
    .i = src->i/m,
    .j = src->j/m,
    .k = src->k/m
  };
}

variable_types:
src
struct kl_quat *


decompiled_code:
void __fastcall kl_quat_fromvec(float *a1, float *a2)
{
float v2; // xmm2_4
float v3; // xmm1_4
float v4; // xmm0_4
float v5; // [rsp+4h] [rbp-2Ch]
float cosx; // [rsp+8h] [rbp-28h] BYREF
float sinx[2]; // [rsp+Ch] [rbp-24h] BYREF
int v8[7]; // [rsp+14h] [rbp-1Ch] BYREF

v5 = kl_vec3f_magnitude(a2);
kl_vec3f_norm((__int64)v8, a2);
sincosf(v5 * 0.5, sinx, &cosx);
v2 = sinx[0] * *(float *)v8;
v3 = sinx[0] * *(float *)&v8[1];
v4 = sinx[0] * *(float *)&v8[2];
*a1 = cosx;
a1[1] = v2;
a1[2] = v3;
a1[3] = v4;
}

canonical_decompiled_code:
void __fastcall func6(float *a1, float *a2)
{
float v2; // xmm2_4
float v3; // xmm1_4
float v4; // xmm0_4
float v5; // [rsp+4h] [rbp-2Ch]
float cosx; // [rsp+8h] [rbp-28h] BYREF
float sinx[2]; // [rsp+Ch] [rbp-24h] BYREF
int v8[7]; // [rsp+14h] [rbp-1Ch] BYREF

v5 = func1(a2);
func2((__int64)v8, a2);
sincosf(v5 * 0.5, sinx, &cosx);
v2 = sinx[0] * *(float *)v8;
v3 = sinx[0] * *(float *)&v8[1];
v4 = sinx[0] * *(float *)&v8[2];
*a1 = cosx;
a1[1] = v2;
a1[2] = v3;
a1[3] = v4;
}

original_code:
void kl_quat_fromvec(kl_quat_t *dst, kl_vec3f_t *src) {
  float theta;
  kl_vec3f_t u;
  theta = kl_vec3f_magnitude(src);
  kl_vec3f_norm(&u, src);
  float c = cosf(theta/2.0f);
  float s = sinf(theta/2.0f);
  *dst = (kl_quat_t){
    .r = c,
    .i = u.x * s,
    .j = u.y * s,
    .k = u.z * s
  };
}

canonical_original_code:
void kl_quat_fromvec(struct kl_quat *dst, struct kl_vec3f *src) {
  float theta;
  struct kl_vec3f u;
  theta = kl_vec3f_magnitude(src);
  kl_vec3f_norm(&u, src);
  float c = cosf(theta/2.0f);
  float s = sinf(theta/2.0f);
  *dst = (struct kl_quat){
    .r = c,
    .i = u.x * s,
    .j = u.y * s,
    .k = u.z * s
  };
}

variable_types:
src
struct kl_vec3f { float x; } *

variable_types: theta float

variable_types:
u
struct kl_vec3f { float x; }

variable_types: c float

user_defined_types:
struct kl_vec3f { float x; }
struct kl_quat { float r; }


original_code:
void kl_quat_conj(kl_quat_t *dst, kl_quat_t *src) {
  *dst = (kl_quat_t){
    .r = src->r,
    .i = -src->i,
    .j = -src->j,
    .k = -src->k
  };
}

canonical_original_code:
void kl_quat_conj(struct kl_quat *dst, struct kl_quat *src) {
  *dst = (struct kl_quat){
    .r = src->r,
    .i = -src->i,
    .j = -src->j,
    .k = -src->k
  };
}


original_code:
void kl_quat_rotate(kl_vec3f_t *dst, kl_quat_t *q, kl_vec3f_t *v) {
  kl_quat_t q_, t1, t2;
  kl_quat_t v_ = { .r = 0.0f, .i = v->x, .j = v->y, .k = v->z };
  kl_quat_conj(&q_, q);
  kl_quat_mul(&t1, &v_, &q_);
  kl_quat_mul(&t2, q, &t1);
  *dst = (kl_vec3f_t){
    .x = t2.i,
    .y = t2.j,
    .z = t2.k
  };
}

canonical_original_code:
void kl_quat_rotate(struct kl_vec3f *dst, struct kl_quat *q, struct kl_vec3f *v) {
  struct kl_quat q_; struct kl_quat t1; struct kl_quat t2;
  struct kl_quat v_ = { .r = 0.0f, .i = v->x, .j = v->y, .k = v->z };
  kl_quat_conj(&q_, q);
  kl_quat_mul(&t1, &v_, &q_);
  kl_quat_mul(&t2, q, &t1);
  *dst = (struct kl_vec3f){
    .x = t2.i,
    .y = t2.j,
    .z = t2.k
  };
}

variable_types:
q
struct kl_quat { float r; } *

variable_types:
v
struct kl_vec3f *

user_defined_types:
struct kl_quat { float r; }
struct kl_vec3f { float x; }


decompiled_code:
__int64 __fastcall kl_model_load(const char *a1)
{
int v1; // eax
int v2; // ebx
unsigned int v3; // er14
size_t v4; // r15
void *v5; // rax
void *v6; // r12
__int64 v7; // r14
int *v8; // rax
char *v9; // rax
int *v10; // rax
char *v11; // rax
int *v12; // rax
char *v13; // rax
int *v15; // rax
char *v16; // rax
int *v17; // rax
char *v18; // rax
struct stat buf; // [rsp+0h] [rbp-C0h] BYREF

v1 = open(a1, 0);
v2 = v1;
if ( v1 < 0 )
{
v8 = _errno_location();
v9 = strerror(*v8);
fprintf(stderr, "Model: Failed to open %s!\n\tDetails: %s\n", a1, v9);
return 0LL;
}
if ( fstat(v1, &buf) < 0 )
{
v10 = _errno_location();
v11 = strerror(*v10);
fprintf(stderr, "Model: Failed to get info for %s!\n\tDetails: %s\n", a1, v11);
return 0LL;
}
v3 = buf.st_size;
v4 = SLODWORD(buf.st_size);
v5 = mmap(0LL, SLODWORD(buf.st_size), 1, 2, v2, 0LL);
v6 = v5;
if ( v5 == (void *)-1LL )
{
v12 = _errno_location();
v13 = strerror(*v12);
fprintf(stderr, "Model: Failed to memory-map %s!\n\tDetails: %s\n", a1, v13);
return 0LL;
}
if ( (unsigned __int8)kl_model_isiqm2(v5, v3) )
{
v7 = kl_model_loadiqm2(v6, v3);
}
else
{
if ( !(unsigned __int8)kl_model_isobj(v6, v3) )
{
LABEL_12:
fprintf(stderr, "Model: Failed to load %s!\n", a1);
v7 = 0LL;
goto LABEL_13;
}
v7 = kl_model_loadobj(v6, v3);
}
if ( !v7 )
goto LABEL_12;
LABEL_13:
if ( munmap(v6, v4) < 0 )
{
v15 = _errno_location();
v16 = strerror(*v15);
fprintf(stderr, "Model: Failed to unmap %s!\n\tDetails: %s\n", a1, v16);
}
if ( close(v2) < 0 )
{
v17 = _errno_location();
v18 = strerror(*v17);
fprintf(stderr, "Model: Failed to close %s!\n\tDetails: %s\n", a1, v18);
}
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1)
{
int v1; // eax
int v2; // ebx
unsigned int v3; // er14
size_t v4; // r15
void *v5; // rax
void *v6; // r12
__int64 v7; // r14
int *v8; // rax
char *v9; // rax
int *v10; // rax
char *v11; // rax
int *v12; // rax
char *v13; // rax
int *v15; // rax
char *v16; // rax
int *v17; // rax
char *v18; // rax
struct stat buf; // [rsp+0h] [rbp-C0h] BYREF

v1 = open(a1, 0);
v2 = v1;
if ( v1 < 0 )
{
v8 = _errno_location();
v9 = strerror(*v8);
fprintf(stderr, "Model: Failed to open %s!\n\tDetails: %s\n", a1, v9);
return 0LL;
}
if ( fstat(v1, &buf) < 0 )
{
v10 = _errno_location();
v11 = strerror(*v10);
fprintf(stderr, "Model: Failed to get info for %s!\n\tDetails: %s\n", a1, v11);
return 0LL;
}
v3 = buf.st_size;
v4 = SLODWORD(buf.st_size);
v5 = mmap(0LL, SLODWORD(buf.st_size), 1, 2, v2, 0LL);
v6 = v5;
if ( v5 == (void *)-1LL )
{
v12 = _errno_location();
v13 = strerror(*v12);
fprintf(stderr, "Model: Failed to memory-map %s!\n\tDetails: %s\n", a1, v13);
return 0LL;
}
if ( (unsigned __int8)kl_model_isiqm2(v5, v3) )
{
v7 = kl_model_loadiqm2(v6, v3);
}
else
{
if ( !(unsigned __int8)kl_model_isobj(v6, v3) )
{
LABEL_12:
fprintf(stderr, "Model: Failed to load %s!\n", a1);
v7 = 0LL;
goto LABEL_13;
}
v7 = kl_model_loadobj(v6, v3);
}
if ( !v7 )
goto LABEL_12;
LABEL_13:
if ( munmap(v6, v4) < 0 )
{
v15 = _errno_location();
v16 = strerror(*v15);
fprintf(stderr, "Model: Failed to unmap %s!\n\tDetails: %s\n", a1, v16);
}
if ( close(v2) < 0 )
{
v17 = _errno_location();
v18 = strerror(*v17);
fprintf(stderr, "Model: Failed to close %s!\n\tDetails: %s\n", a1, v18);
}
return v7;
}

original_code:
kl_model_t *kl_model_load(char *path) {
  int fd = open(path, 00);
  if (fd < 0) {
    fprintf(stderr, "Model: Failed to open %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
    return ((void *)0);
  }
  struct stat s;
  if (fstat(fd, &s) < 0) {
    fprintf(stderr, "Model: Failed to get info for %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
    return ((void *)0);
  }
  int size = s.st_size;
  void *data = mmap(((void *)0), size, 0x1, 0x02, fd, 0);
  if (data == ((void *) -1)) {
    fprintf(stderr, "Model: Failed to memory-map %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
    return ((void *)0);
  }
  kl_model_t *model = ((void *)0);
  if (kl_model_isiqm2(data, size)) {
    model = kl_model_loadiqm2(data, size);
  } else if (kl_model_isobj(data, size)) {
    model = kl_model_loadobj(data, size);
  }
  if (model == ((void *)0)) {
    fprintf(stderr, "Model: Failed to load %s!\n", path);
  }
  if (munmap(data, size) < 0) {
    fprintf(stderr, "Model: Failed to unmap %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
  }
  if (close(fd) < 0) {
    fprintf(stderr, "Model: Failed to close %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
  }
  return model;
}

canonical_original_code:
struct kl_model *kl_model_load(char *path) {
  int fd = open(path, 00);
  if (fd < 0) {
    fprintf(stderr, "Model: Failed to open %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
    return ((void *)0);
  }
  struct stat s;
  if (fstat(fd, &s) < 0) {
    fprintf(stderr, "Model: Failed to get info for %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
    return ((void *)0);
  }
  int size = s.st_size;
  void *data = mmap(((void *)0), size, 0x1, 0x02, fd, 0);
  if (data == ((void *) -1)) {
    fprintf(stderr, "Model: Failed to memory-map %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
    return ((void *)0);
  }
  struct kl_model *model = ((void *)0);
  if (kl_model_isiqm2(data, size)) {
    model = kl_model_loadiqm2(data, size);
  } else if (kl_model_isobj(data, size)) {
    model = kl_model_loadobj(data, size);
  }
  if (model == ((void *)0)) {
    fprintf(stderr, "Model: Failed to load %s!\n", path);
  }
  if (munmap(data, size) < 0) {
    fprintf(stderr, "Model: Failed to unmap %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
  }
  if (close(fd) < 0) {
    fprintf(stderr, "Model: Failed to close %s!\n\tDetails: %s\n", path, strerror((*__errno_location ())));
  }
  return model;
}

variable_types:
path
char *

variable_types: fd int

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; long st_atime; unsigned long st_atimensec; long st_mtime; unsigned long st_mtimensec; long st_ctime; unsigned long st_ctimensec; long __glibc_reserved[3]; }

variable_types: size int

variable_types:
data
void *

variable_types: struct kl_model { int type; struct kl_sphere { struct kl_vec3f { float x; } center; float radius; } bounds; int winding; union kl_model_bufs { struct kl_model_bufs_prop { unsigned int position; unsigned int texcoord; unsigned int normal; unsigned int tangent; } prop; struct kl_model_bufs_actor { unsigned int position; unsigned int texcoord; unsigned int normal; unsigned int tangent; unsigned int blendidx; unsigned int blendwt; } actor; struct kl_model_bufs_terrain { unsigned int position; unsigned int normal; unsigned int texweight; } terrain; } bufs; unsigned int tris; unsigned int attribs; unsigned int mesh_n; struct kl_mesh { struct kl_material { char path[256]; struct kl_texture_t { char path[256]; unsigned int w; unsigned int id; } *diffuse; struct kl_texture_t *normal; struct kl_texture_t *specular; struct kl_texture_t *emissive; } *material; unsigned int tris_i; } mesh[]; } *


variable_types: union kl_mat4f { float cell[16]; struct kl_vec4f { float x; } column[4]; } *

variable_types: l float

variable_types: r float

variable_types: b float

variable_types: t float

variable_types: n float

variable_types: f float


original_code:
void kl_mat4f_rotation(kl_mat4f_t *dst, kl_quat_t *src) {
  float i = src->i;
  float j = src->j;
  float k = src->k;
  float r = src->r;
  float rr = r*r;
  float ii = i*i;
  float jj = j*j;
  float kk = k*k;
  float ri = 2.0f*r*i;
  float rj = 2.0f*r*j;
  float rk = 2.0f*r*k;
  float ij = 2.0f*i*j;
  float ik = 2.0f*i*k;
  float jk = 2.0f*j*k;
  *dst = (kl_mat4f_t){
    .cell = {
      rr + ii - jj - kk, ij - rk, ik + rj, 0.0f,
      ij + rk, rr - ii + jj - kk, jk - ri, 0.0f,
      ik - rj, jk + ri, rr - ii - jj + kk, 0.0f,
      0.0f, 0.0f, 0.0f, 1.0f
    }
  };
}

canonical_original_code:
void kl_mat4f_rotation(union kl_mat4f *dst, struct kl_quat *src) {
  float i = src->i;
  float j = src->j;
  float k = src->k;
  float r = src->r;
  float rr = r*r;
  float ii = i*i;
  float jj = j*j;
  float kk = k*k;
  float ri = 2.0f*r*i;
  float rj = 2.0f*r*j;
  float rk = 2.0f*r*k;
  float ij = 2.0f*i*j;
  float ik = 2.0f*i*k;
  float jk = 2.0f*j*k;
  *dst = (union kl_mat4f){
    .cell = {
      rr + ii - jj - kk, ij - rk, ik + rj, 0.0f,
      ij + rk, rr - ii + jj - kk, jk - ri, 0.0f,
      ik - rj, jk + ri, rr - ii - jj + kk, 0.0f,
      0.0f, 0.0f, 0.0f, 1.0f
    }
  };
}

variable_types:
src
struct kl_quat { float r; } *

variable_types: i float

variable_types: j float

variable_types: k float

variable_types: rr float

variable_types: ii float

variable_types: jj float

variable_types: kk float

variable_types: ri float

variable_types: rj float

variable_types: rk float

variable_types: ij float

variable_types: ik float

variable_types: jk float


canonical_original_code:
void kl_mat4f_scale(union kl_mat4f *dst, float x, float y, float z) {
  *dst = (union kl_mat4f){
    .cell = {
      x, 0.0f, 0.0f, 0.0f,
      0.0f, y, 0.0f, 0.0f,
      0.0f, 0.0f, z, 0.0f,
      0.0f, 0.0f, 0.0f, 1.0f
    }
  };
}

variable_types: union kl_mat4f { float cell[16]; struct kl_vec4f { float x; } column[4]; } *

variable_types: x float

variable_types: y float

variable_types: z float


original_code:
void kl_mat4f_perspective(kl_mat4f_t *dst, float ratio, float fov, float n, float f) {
  float h = n * tanf(fov / 2.0f);
  float w = h * ratio;
  *dst = (kl_mat4f_t){
    .cell = {
      1.0f/w, 0.0f, 0.0f, 0.0f,
      0.0f, 1.0f/h, 0.0f, 0.0f,
      0.0f, 0.0f, (f+n)/(n-f), -1.0f,
      0.0f, 0.0f, (2.0f*f*n)/(n-f), 0.0f
    }
  };
}

canonical_original_code:
void kl_mat4f_perspective(union kl_mat4f *dst, float ratio, float fov, float n, float f) {
  float h = n * tanf(fov / 2.0f);
  float w = h * ratio;
  *dst = (union kl_mat4f){
    .cell = {
      1.0f/w, 0.0f, 0.0f, 0.0f,
      0.0f, 1.0f/h, 0.0f, 0.0f,
      0.0f, 0.0f, (f+n)/(n-f), -1.0f,
      0.0f, 0.0f, (2.0f*f*n)/(n-f), 0.0f
    }
  };
}

variable_types: ratio float

variable_types: fov float

variable_types: n float

variable_types: f float

variable_types: h float

variable_types: w float


original_code:
void kl_mat4f_invperspective(kl_mat4f_t *dst, float ratio, float fov, float n, float f) {
  float h = n * tanf(fov / 2.0f);
  float w = h * ratio;
  *dst = (kl_mat4f_t){
    .cell = {
      w, 0.0f, 0.0f, 0.0f,
      0.0f, h, 0.0f, 0.0f,
      0.0f, 0.0f, 0.0f, (n-f)/(2.0f*f*n),
      0.0f, 0.0f, -1.0f, (f+n)/(2.0f*f*n)
    }
  };
}

canonical_original_code:
void kl_mat4f_invperspective(union kl_mat4f *dst, float ratio, float fov, float n, float f) {
  float h = n * tanf(fov / 2.0f);
  float w = h * ratio;
  *dst = (union kl_mat4f){
    .cell = {
      w, 0.0f, 0.0f, 0.0f,
      0.0f, h, 0.0f, 0.0f,
      0.0f, 0.0f, 0.0f, (n-f)/(2.0f*f*n),
      0.0f, 0.0f, -1.0f, (f+n)/(2.0f*f*n)
    }
  };
}


decompiled_code:
int __fastcall kl_mat4f_print(float *a1)
{
float *v1; // rbx
int result; // eax

v1 = a1;
do
{
result = printf("[ %6.3f, %6.3f, %6.3f, %6.3f ]\n", *v1, v1[4], v1[8], v1[12]);
++v1;
}
while ( v1 != a1 + 4 );
return result;
}

canonical_decompiled_code:
int __fastcall func8(float *a1)
{
float *v1; // rbx
int result; // eax

v1 = a1;
do
{
result = printf("[ %6.3f, %6.3f, %6.3f, %6.3f ]\n", *v1, v1[4], v1[8], v1[12]);
++v1;
}
while ( v1 != a1 + 4 );
return result;
}

original_code:
void kl_mat4f_print(kl_mat4f_t *src) {
  for (int r=0; r < 4; r++) {
    printf("[ %6.3f, %6.3f, %6.3f, %6.3f ]\n",
      src->cell[ r], src->cell[4 +r],
      src->cell[8 +r], src->cell[12+r]);
  }
}

canonical_original_code:
void kl_mat4f_print(union kl_mat4f *src) {
  for (int r = 0; r < 4; r++) {
    printf("[ %6.3f, %6.3f, %6.3f, %6.3f ]\n",
      src->cell[ r], src->cell[4 +r],
      src->cell[8 +r], src->cell[12+r]);
  }
}

variable_types: r int


decompiled_code:
__int64 __fastcall kl_resource_getid(char *a1)
{
char v1; // al
char *v2; // rdi
__int64 v3; // rdx

v1 = *a1;
if ( !*a1 )
return 0LL;
v2 = a1 + 1;
v3 = 0LL;
do
{
v3 = __ROL8__(v3 ^ v1, 11);
v1 = *v2++;
}
while ( v1 );
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *a1)
{
char v1; // al
char *v2; // rdi
__int64 v3; // rdx

v1 = *a1;
if ( !*a1 )
return 0LL;
v2 = a1 + 1;
v3 = 0LL;
do
{
v3 = __ROL8__(v3 ^ v1, 11);
v1 = *v2++;
}
while ( v1 );
return v3;
}

canonical_original_code:
unsigned long kl_resource_getid(char *str) {
  unsigned long h = 0;
  char p = '\0';
  for (int i = 0; str[i] != '\0'; i++) {
    char c = str[i];
    if (c >= 'A' && c <= 'Z') {
      c |= 0x20;
    }
    if (c == '\\') {
      c = '/';
    }
    if (c == '/' && p == '/') {
      continue;
    }
    h ^= str[i];
    h = (h << 11) | (h >> 53);
  }
  return h;
}

variable_types:
str
char *

variable_types:
h
unsigned long

variable_types: p char

variable_types: i int

variable_types: c char

return_type: unsigned long


decompiled_code:
__int64 __fastcall kl_resource_exists(__int64 a1)
{
__int64 result; // rax

result = resource_cache[a1 & 0xFFF];
if ( !result )
return 0LL;
while ( *(_QWORD *)(result + 512) != a1 )
{
result = *(_QWORD *)(result + 544);
if ( !result )
return result;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
__int64 result; // rax

result = resource_cache[a1 & 0xFFF];
if ( !result )
return 0LL;
while ( *(_QWORD *)(result + 512) != a1 )
{
result = *(_QWORD *)(result + 544);
if ( !result )
return result;
}
return 1LL;
}

original_code:
_Bool kl_resource_exists(kl_resource_id_t resid) {
  kl_resource_id_t bucket = resid % 0x1000;
  kl_resource_item_t *first = resource_cache.buckets[bucket];
  kl_resource_item_t *curr;
  for (curr = first; curr != ((void *)0); curr = curr->next) {
    if (curr->resid == resid) {
      return 1;
    }
  }
  return 0;
}

canonical_original_code:
_Bool kl_resource_exists(unsigned long resid) {
  unsigned long bucket = resid % 0x1000;
  struct kl_resource_item *first = resource_cache.buckets[bucket];
  struct kl_resource_item *curr;
  for (curr = first; curr != ((void *)0); curr = curr->next) {
    if (curr->resid == resid) {
      return 1;
    }
  }
  return 0;
}

variable_types:
resid
unsigned long

variable_types:
bucket
unsigned long

variable_types: struct kl_resource_item { char path[256]; char vpath[256]; unsigned long resid; int refs; struct kl_resource_loader { int type; void *(*load)(char *path, char *vpath); void (*free)(void *item); } *loader; void *item; struct kl_resource_item *next; } *

user_defined_types: struct kl_resource_item { char path[256]; char vpath[256]; unsigned long resid; int refs; struct kl_resource_loader *loader; void *item; struct kl_resource_item *next; }


decompiled_code:
__int64 __fastcall kl_resource_add_entry(char *src, char *a2)
{
__int64 v2; // r12
char *v3; // rbx

v2 = kl_resource_getid(a2);
if ( (unsigned __int8)kl_resource_exists(v2) )
return 0xFFFFFFFFLL;
v3 = (char *)malloc(0x228uLL);
strncpy(v3, src, 0x100uLL);
strncpy(v3 + 256, a2, 0x100uLL);
*((_QWORD *)v3 + 64) = v2;
*((_DWORD *)v3 + 130) = 0;
*((_QWORD *)v3 + 66) = 0LL;
*((_QWORD *)v3 + 67) = 0LL;
*((_QWORD *)v3 + 68) = resource_cache[v2 & 0xFFF];
resource_cache[v2 & 0xFFF] = (__int64)v3;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(char *src, char *a2)
{
__int64 v2; // r12
char *v3; // rbx

v2 = func3(a2);
if ( (unsigned __int8)func4(v2) )
return 0xFFFFFFFFLL;
v3 = (char *)malloc(0x228uLL);
strncpy(v3, src, 0x100uLL);
strncpy(v3 + 256, a2, 0x100uLL);
*((_QWORD *)v3 + 64) = v2;
*((_DWORD *)v3 + 130) = 0;
*((_QWORD *)v3 + 66) = 0LL;
*((_QWORD *)v3 + 67) = 0LL;
*((_QWORD *)v3 + 68) = resource_cache[v2 & 0xFFF];
resource_cache[v2 & 0xFFF] = (__int64)v3;
return 0LL;
}

original_code:
int kl_resource_add_entry(char *path, char *vpath) {
  kl_resource_id_t resid = kl_resource_getid(vpath);
  if (kl_resource_exists(resid)) return -1;
  int bucket = resid % 0x1000;
  kl_resource_item_t *item = malloc(sizeof(kl_resource_item_t));
  strncpy(item->path, path, 0x100);
  strncpy(item->vpath, vpath, 0x100);
  item->resid = resid;
  item->refs = 0;
  item->loader = ((void *)0);
  item->item = ((void *)0);
  item->next = resource_cache.buckets[bucket];
  resource_cache.buckets[bucket] = item;
  return 0;
}

canonical_original_code:
int kl_resource_add_entry(char *path, char *vpath) {
  unsigned long resid = kl_resource_getid(vpath);
  if (kl_resource_exists(resid)) return -1;
  int bucket = resid % 0x1000;
  struct kl_resource_item *item = malloc(sizeof(kl_resource_item_t));
  strncpy(item->path, path, 0x100);
  strncpy(item->vpath, vpath, 0x100);
  item->resid = resid;
  item->refs = 0;
  item->loader = ((void *)0);
  item->item = ((void *)0);
  item->next = resource_cache.buckets[bucket];
  resource_cache.buckets[bucket] = item;
  return 0;
}

variable_types:
path
char *

variable_types:
vpath
char *

variable_types: bucket int

user_defined_types: struct kl_resource_loader { int type; void *(*load)(char *path, char *vpath); void (*free)(void *item); }


decompiled_code:
__int64 __fastcall kl_resource_add_dir(const char *a1, const char *a2)
{
char *v2; // r14
char *v3; // rbx
int v4; // er12
int v5; // er13
char *v7; // rax
char v8[272]; // [rsp+10h] [rbp-160h] BYREF
char v9[80]; // [rsp+120h] [rbp-50h] BYREF

v2 = (char *)malloc(0x100uLL);
v3 = (char *)malloc(0x100uLL);
v4 = 0;
v5 = 0;
if ( (int)listdir(a1, (__int64)v9) >= 0 )
{
while ( (int)kl_array_size((__int64)v9) > v5 )
{
kl_array_get((__int64)v9, v5, v8);
snprintf(v2, 0x100uLL, "%s/%s", a1, v8);
v2[255] = 0;
snprintf(v3, 0x100uLL, "%s/%s", a2, v8);
v3[255] = 0;
if ( v8[256] )
{
v4 = kl_resource_add_dir(v2, v3);
if ( v4 < 0 )
break;
}
else
{
v7 = v3;
do
{
if ( *v7 == 124 )
*v7 = 58;
++v7;
}
while ( v7 != v3 + 256 );
v4 = kl_resource_add_entry(v2, v3);
if ( v4 < 0 )
break;
}
++v5;
}
}
kl_array_free(v9);
free(v2);
free(v3);
return (unsigned int)v4;
}

original_code:
int kl_resource_add_dir(char *path, char *vpath) {
  char *subpath = malloc(0x100);
  char *subvpath = malloc(0x100);
  int err = 0;
  kl_array_t items;
  if (listdir(path, &items) < 0) goto cleanup;
  diritem_t item;
  for (int i = 0; i < kl_array_size(&items); i++) {
    kl_array_get(&items, i, &item);
    snprintf(subpath, 0x100, "%s/%s", path, item.name);
    subpath[0x100 -1] = '\0';
    snprintf(subvpath, 0x100, "%s/%s", vpath, item.name);
    subvpath[0x100 -1] = '\0';
    if (item.isdir) {
      err = kl_resource_add_dir(subpath, subvpath);
      if (err < 0) goto cleanup;
    } else {
      for (int i=0; i < 0x100; i++) {
        if (subvpath[i] == '|') {
          subvpath[i] = ':';
        }
      }
      err = kl_resource_add_entry(subpath, subvpath);
      if (err < 0) goto cleanup;
    }
  }
  cleanup:
  kl_array_free(&items);
  free(subpath);
  free(subvpath);
  return err;
}

canonical_original_code:
int kl_resource_add_dir(char *path, char *vpath) {
  char *subpath = malloc(0x100);
  char *subvpath = malloc(0x100);
  int err = 0;
  struct kl_array items;
  if (listdir(path, &items) < 0) goto cleanup;
  struct diritem item;
  for (int i = 0; i < kl_array_size(&items); i++) {
    kl_array_get(&items, i, &item);
    snprintf(subpath, 0x100, "%s/%s", path, item.name);
    subpath[0x100 -1] = '\0';
    snprintf(subvpath, 0x100, "%s/%s", vpath, item.name);
    subvpath[0x100 -1] = '\0';
    if (item.isdir) {
      err = kl_resource_add_dir(subpath, subvpath);
      if (err < 0) goto cleanup;
    } else {
      for (int i = 0; i < 0x100; i++) {
        if (subvpath[i] == '|') {
          subvpath[i] = ':';
        }
      }
      err = kl_resource_add_entry(subpath, subvpath);
      if (err < 0) goto cleanup;
    }
  }
  cleanup:
  kl_array_free(&items);
  free(subpath);
  free(subvpath);
  return err;
}

variable_types:
subpath
char *

variable_types:
subvpath
char *

variable_types: err int

variable_types: struct kl_array { unsigned char *data; int size; int item_size; int num_items; }

variable_types: struct diritem { char name[256]; _Bool isdir; }


decompiled_code:
__int64 __fastcall kl_resource_decref(__int64 a1)
{
__int64 result; // rax
int v2; // ecx

result = resource_cache[a1 & 0xFFF];
if ( result )
{
while ( *(_QWORD *)(result + 512) != a1 )
{
result = *(_QWORD *)(result + 544);
if ( !result )
return result;
}
v2 = *(_DWORD *)(result + 520);
*(_DWORD *)(result + 520) = v2 - 1;
if ( v2 - 1 < 0 )
_assert_fail("curr->refs >= 0", "resource.c", 0xCBu, "kl_resource_decref");
if ( v2 == 1 )
{
if ( *(_QWORD *)(result + 536) )
result = (*(__int64 (**)(void))(*(_QWORD *)(result + 528) + 16LL))();
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
__int64 result; // rax
int v2; // ecx

result = resource_cache[a1 & 0xFFF];
if ( result )
{
while ( *(_QWORD *)(result + 512) != a1 )
{
result = *(_QWORD *)(result + 544);
if ( !result )
return result;
}
v2 = *(_DWORD *)(result + 520);
*(_DWORD *)(result + 520) = v2 - 1;
if ( v2 - 1 < 0 )
_assert_fail("curr->refs >= 0", "resource.c", 0xCBu, "kl_resource_decref");
if ( v2 == 1 )
{
if ( *(_QWORD *)(result + 536) )
result = (*(__int64 (**)(void))(*(_QWORD *)(result + 528) + 16LL))();
}
}
return result;
}

original_code:
void kl_resource_decref(kl_resource_id_t resid) {
  int bucket = resid % 0x1000;
  kl_resource_item_t *first = resource_cache.buckets[bucket];
  kl_resource_item_t *curr;
  for (curr = first; curr != ((void *)0); curr = curr->next) {
    if (curr->resid == resid) {
      curr->refs--;
      ((curr->refs >= 0) ? (void) (0) : __assert_fail ("curr->refs >= 0", "resource.c", 203, __extension__ __PRETTY_FUNCTION__));
      if (curr->refs <= 0 && curr->item != ((void *)0)) {
        curr->loader->free(curr->item);
      }
      break;
    }
  }
}

canonical_original_code:
void kl_resource_decref(unsigned long resid) {
  int bucket = resid % 0x1000;
  struct kl_resource_item *first = resource_cache.buckets[bucket];
  struct kl_resource_item *curr;
  for (curr = first; curr != ((void *)0); curr = curr->next) {
    if (curr->resid == resid) {
      curr->refs--;
      ((curr->refs >= 0) ? (void) (0) : __assert_fail ("curr->refs >= 0", "resource.c", 203, __extension__ __PRETTY_FUNCTION__));
      if (curr->refs <= 0 && curr->item != ((void *)0)) {
        curr->loader->free(curr->item);
      }
      break;
    }
  }
}


decompiled_code:
__int64 kl_resource_printall()
{
const char *v0; // rdx
__int64 result; // rax

v0 = (const char *)resource_cache;
do
{
for ( result = *(_QWORD *)v0; result; result = *(_QWORD *)(result + 544) )
;
v0 += 8;
}
while ( v0 != "Resource Manager: Failed to read directory %s!\n\tDetails: %s\n" );
return result;
}

canonical_decompiled_code:
__int64 func9()
{
const char *v0; // rdx
__int64 result; // rax

v0 = (const char *)resource_cache;
do
{
for ( result = *(_QWORD *)v0; result; result = *(_QWORD *)(result + 544) )
;
v0 += 8;
}
while ( v0 != "Resource Manager: Failed to read directory %s!\n\tDetails: %s\n" );
return result;
}

original_code:
void kl_resource_printall() {
  for (int i=0; i < 0x1000; i++) {
    kl_resource_item_t *item = resource_cache.buckets[i];
    while (item != ((void *)0)) {
      item = item->next;
    }
  }
}

canonical_original_code:
void kl_resource_printall() {
  for (int i = 0; i < 0x1000; i++) {
    struct kl_resource_item *item = resource_cache.buckets[i];
    while (item != ((void *)0)) {
      item = item->next;
    }
  }
}


decompiled_code:
unsigned __int64 __fastcall kl_resource_strip_extension(const char *a1)
{
int v1; // edx
unsigned __int64 result; // rax
__int64 v3; // rsi
char v4; // dl

v1 = strlen(a1);
result = (unsigned int)(v1 - 1);
if ( (result & 0x80000000) == 0LL )
{
result = (unsigned __int64)&a1[(int)result];
v3 = (__int64)&a1[v1 - 2 - (v1 - 1)];
do
{
v4 = *(_BYTE *)result;
if ( (*(_BYTE *)result & 0xDF) == 92 || v4 == 47 )
break;
if ( v4 == 46 )
{
*(_BYTE *)result = 0;
return result;
}
--result;
}
while ( result != v3 );
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func10(const char *a1)
{
int v1; // edx
unsigned __int64 result; // rax
__int64 v3; // rsi
char v4; // dl

v1 = strlen(a1);
result = (unsigned int)(v1 - 1);
if ( (result & 0x80000000) == 0LL )
{
result = (unsigned __int64)&a1[(int)result];
v3 = (__int64)&a1[v1 - 2 - (v1 - 1)];
do
{
v4 = *(_BYTE *)result;
if ( (*(_BYTE *)result & 0xDF) == 92 || v4 == 47 )
break;
if ( v4 == 46 )
{
*(_BYTE *)result = 0;
return result;
}
--result;
}
while ( result != v3 );
}
return result;
}

original_code:
void kl_resource_strip_extension(char *path) {
  int n = strlen(path);
  for (int i = n-1; i >= 0; i--) {
    if (path[i] == '/' || path[i] == '\\' || path[i] == '|') {
      break;
    }
    if (path[i] == '.') {
      path[i] = '\0';
      break;
    }
  }
}

variable_types: n int


decompiled_code:
void __fastcall material_free(void *ptr)
{
kl_texture_decref(*((_QWORD *)ptr + 32));
kl_texture_decref(*((_QWORD *)ptr + 33));
kl_texture_decref(*((_QWORD *)ptr + 34));
kl_texture_decref(*((_QWORD *)ptr + 35));
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
kl_texture_decref(*((_QWORD *)ptr + 32));
kl_texture_decref(*((_QWORD *)ptr + 33));
kl_texture_decref(*((_QWORD *)ptr + 34));
kl_texture_decref(*((_QWORD *)ptr + 35));
free(ptr);
}

original_code:
static void material_free(kl_material_t *material) {
  kl_texture_decref(material->diffuse);
  kl_texture_decref(material->normal);
  kl_texture_decref(material->specular);
  kl_texture_decref(material->emissive);
  free(material);
}

canonical_original_code:
static void material_free(struct kl_material *material) {
  kl_texture_decref(material->diffuse);
  kl_texture_decref(material->normal);
  kl_texture_decref(material->specular);
  kl_texture_decref(material->emissive);
  free(material);
}

variable_types: struct kl_material { char path[256]; struct kl_texture_t { char path[256]; unsigned int w; unsigned int id; } *diffuse; struct kl_texture_t *normal; struct kl_texture_t *specular; struct kl_texture_t *emissive; } *


decompiled_code:
__int64 __fastcall material_load_default(char *src, char *dest)
{
__int64 result; // rax

strncpy(dest, src, 0x100uLL);
*((_QWORD *)dest + 32) = kl_texture_incref("DEFAULT_DIFFUSE");
*((_QWORD *)dest + 33) = kl_texture_incref("DEFAULT_NORMAL");
*((_QWORD *)dest + 34) = kl_texture_incref("DEFAULT_SPECULAR");
result = kl_texture_incref("DEFAULT_EMISSIVE");
*((_QWORD *)dest + 35) = result;
if ( !*((_QWORD *)dest + 32) )
_assert_fail("material->diffuse != NULL", "material.c", 0x95u, "material_load_default");
if ( !*((_QWORD *)dest + 33) )
_assert_fail("material->normal != NULL", "material.c", 0x96u, "material_load_default");
if ( !*((_QWORD *)dest + 34) )
_assert_fail("material->specular != NULL", "material.c", 0x97u, "material_load_default");
if ( !result )
_assert_fail("material->emissive != NULL", "material.c", 0x98u, "material_load_default");
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *src, char *dest)
{
__int64 result; // rax

strncpy(dest, src, 0x100uLL);
*((_QWORD *)dest + 32) = kl_texture_incref("DEFAULT_DIFFUSE");
*((_QWORD *)dest + 33) = kl_texture_incref("DEFAULT_NORMAL");
*((_QWORD *)dest + 34) = kl_texture_incref("DEFAULT_SPECULAR");
result = kl_texture_incref("DEFAULT_EMISSIVE");
*((_QWORD *)dest + 35) = result;
if ( !*((_QWORD *)dest + 32) )
_assert_fail("material->diffuse != NULL", "material.c", 0x95u, "material_load_default");
if ( !*((_QWORD *)dest + 33) )
_assert_fail("material->normal != NULL", "material.c", 0x96u, "material_load_default");
if ( !*((_QWORD *)dest + 34) )
_assert_fail("material->specular != NULL", "material.c", 0x97u, "material_load_default");
if ( !result )
_assert_fail("material->emissive != NULL", "material.c", 0x98u, "material_load_default");
return result;
}

original_code:
static void material_load_default(char *path, kl_material_t *material) {
  strncpy(material->path, path, 0x100);
  material->diffuse = kl_texture_incref("DEFAULT_DIFFUSE");
  material->normal = kl_texture_incref("DEFAULT_NORMAL");
  material->specular = kl_texture_incref("DEFAULT_SPECULAR");
  material->emissive = kl_texture_incref("DEFAULT_EMISSIVE");
  ((material->diffuse != ((void *)0)) ? (void) (0) : __assert_fail ("material->diffuse != NULL", "material.c", 149, __extension__ __PRETTY_FUNCTION__));
  ((material->normal != ((void *)0)) ? (void) (0) : __assert_fail ("material->normal != NULL", "material.c", 150, __extension__ __PRETTY_FUNCTION__));
  ((material->specular != ((void *)0)) ? (void) (0) : __assert_fail ("material->specular != NULL", "material.c", 151, __extension__ __PRETTY_FUNCTION__));
  ((material->emissive != ((void *)0)) ? (void) (0) : __assert_fail ("material->emissive != NULL", "material.c", 152, __extension__ __PRETTY_FUNCTION__));
}

canonical_original_code:
static void material_load_default(char *path, struct kl_material *material) {
  strncpy(material->path, path, 0x100);
  material->diffuse = kl_texture_incref("DEFAULT_DIFFUSE");
  material->normal = kl_texture_incref("DEFAULT_NORMAL");
  material->specular = kl_texture_incref("DEFAULT_SPECULAR");
  material->emissive = kl_texture_incref("DEFAULT_EMISSIVE");
  ((material->diffuse != ((void *)0)) ? (void) (0) : __assert_fail ("material->diffuse != NULL", "material.c", 149, __extension__ __PRETTY_FUNCTION__));
  ((material->normal != ((void *)0)) ? (void) (0) : __assert_fail ("material->normal != NULL", "material.c", 150, __extension__ __PRETTY_FUNCTION__));
  ((material->specular != ((void *)0)) ? (void) (0) : __assert_fail ("material->specular != NULL", "material.c", 151, __extension__ __PRETTY_FUNCTION__));
  ((material->emissive != ((void *)0)) ? (void) (0) : __assert_fail ("material->emissive != NULL", "material.c", 152, __extension__ __PRETTY_FUNCTION__));
}


decompiled_code:
__int64 __fastcall material_load_raw(char *src, char *dest)
{
__int64 v2; // r13
__int64 v3; // r15
__int64 v4; // r14
__int64 result; // rax
__int64 v6; // [rsp+8h] [rbp-138h]
char s[304]; // [rsp+10h] [rbp-130h] BYREF

snprintf(s, 0x100uLL, "%s", src);
v2 = kl_texture_incref(s);
snprintf(s, 0x100uLL, "%s_n", src);
v3 = kl_texture_incref(s);
snprintf(s, 0x100uLL, "%s_s", src);
v4 = kl_texture_incref(s);
snprintf(s, 0x100uLL, "%s_e", src);
v6 = kl_texture_incref(s);
if ( !v2 )
v2 = kl_texture_incref("DEFAULT_DIFFUSE");
if ( !v3 )
v3 = kl_texture_incref("DEFAULT_NORMAL");
if ( !v4 )
v4 = kl_texture_incref("DEFAULT_SPECULAR");
if ( !v6 )
v6 = kl_texture_incref("DEFAULT_EMISSIVE");
if ( !v2 )
_assert_fail("diffuse != NULL", "material.c", 0x83u, "material_load_raw");
if ( !v3 )
_assert_fail("normal != NULL", "material.c", 0x84u, "material_load_raw");
if ( !v4 )
_assert_fail("specular != NULL", "material.c", 0x85u, "material_load_raw");
if ( !v6 )
_assert_fail("emissive != NULL", "material.c", 0x86u, "material_load_raw");
strncpy(dest, src, 0x100uLL);
*((_QWORD *)dest + 32) = v2;
*((_QWORD *)dest + 33) = v3;
*((_QWORD *)dest + 34) = v4;
result = v6;
*((_QWORD *)dest + 35) = v6;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *src, char *dest)
{
__int64 v2; // r13
__int64 v3; // r15
__int64 v4; // r14
__int64 result; // rax
__int64 v6; // [rsp+8h] [rbp-138h]
char s[304]; // [rsp+10h] [rbp-130h] BYREF

snprintf(s, 0x100uLL, "%s", src);
v2 = kl_texture_incref(s);
snprintf(s, 0x100uLL, "%s_n", src);
v3 = kl_texture_incref(s);
snprintf(s, 0x100uLL, "%s_s", src);
v4 = kl_texture_incref(s);
snprintf(s, 0x100uLL, "%s_e", src);
v6 = kl_texture_incref(s);
if ( !v2 )
v2 = kl_texture_incref("DEFAULT_DIFFUSE");
if ( !v3 )
v3 = kl_texture_incref("DEFAULT_NORMAL");
if ( !v4 )
v4 = kl_texture_incref("DEFAULT_SPECULAR");
if ( !v6 )
v6 = kl_texture_incref("DEFAULT_EMISSIVE");
if ( !v2 )
_assert_fail("diffuse != NULL", "material.c", 0x83u, "material_load_raw");
if ( !v3 )
_assert_fail("normal != NULL", "material.c", 0x84u, "material_load_raw");
if ( !v4 )
_assert_fail("specular != NULL", "material.c", 0x85u, "material_load_raw");
if ( !v6 )
_assert_fail("emissive != NULL", "material.c", 0x86u, "material_load_raw");
strncpy(dest, src, 0x100uLL);
*((_QWORD *)dest + 32) = v2;
*((_QWORD *)dest + 33) = v3;
*((_QWORD *)dest + 34) = v4;
result = v6;
*((_QWORD *)dest + 35) = v6;
return result;
}

original_code:
static void material_load_raw(char *path, kl_material_t *material) {
  char buf[256];
  snprintf(buf, 256, "%s", path);
  kl_texture_t *diffuse = kl_texture_incref(buf);
  snprintf(buf, 256, "%s_n", path);
  kl_texture_t *normal = kl_texture_incref(buf);
  snprintf(buf, 256, "%s_s", path);
  kl_texture_t *specular = kl_texture_incref(buf);
  snprintf(buf, 256, "%s_e", path);
  kl_texture_t *emissive = kl_texture_incref(buf);
  if (diffuse == ((void *)0)) {
    diffuse = kl_texture_incref("DEFAULT_DIFFUSE");
  }
  if (normal == ((void *)0)) {
    normal = kl_texture_incref("DEFAULT_NORMAL");
  }
  if (specular == ((void *)0)) {
    specular = kl_texture_incref("DEFAULT_SPECULAR");
  }
  if (emissive == ((void *)0)) {
    emissive = kl_texture_incref("DEFAULT_EMISSIVE");
  }
  ((diffuse != ((void *)0)) ? (void) (0) : __assert_fail ("diffuse != NULL", "material.c", 131, __extension__ __PRETTY_FUNCTION__));
  ((normal != ((void *)0)) ? (void) (0) : __assert_fail ("normal != NULL", "material.c", 132, __extension__ __PRETTY_FUNCTION__));
  ((specular != ((void *)0)) ? (void) (0) : __assert_fail ("specular != NULL", "material.c", 133, __extension__ __PRETTY_FUNCTION__));
  ((emissive != ((void *)0)) ? (void) (0) : __assert_fail ("emissive != NULL", "material.c", 134, __extension__ __PRETTY_FUNCTION__));
  strncpy(material->path, path, 0x100);
  material->diffuse = diffuse;
  material->normal = normal;
  material->specular = specular;
  material->emissive = emissive;
}

canonical_original_code:
static void material_load_raw(char *path, struct kl_material *material) {
  char buf[256];
  snprintf(buf, 256, "%s", path);
  struct kl_texture_t *diffuse = kl_texture_incref(buf);
  snprintf(buf, 256, "%s_n", path);
  struct kl_texture_t *normal = kl_texture_incref(buf);
  snprintf(buf, 256, "%s_s", path);
  struct kl_texture_t *specular = kl_texture_incref(buf);
  snprintf(buf, 256, "%s_e", path);
  struct kl_texture_t *emissive = kl_texture_incref(buf);
  if (diffuse == ((void *)0)) {
    diffuse = kl_texture_incref("DEFAULT_DIFFUSE");
  }
  if (normal == ((void *)0)) {
    normal = kl_texture_incref("DEFAULT_NORMAL");
  }
  if (specular == ((void *)0)) {
    specular = kl_texture_incref("DEFAULT_SPECULAR");
  }
  if (emissive == ((void *)0)) {
    emissive = kl_texture_incref("DEFAULT_EMISSIVE");
  }
  ((diffuse != ((void *)0)) ? (void) (0) : __assert_fail ("diffuse != NULL", "material.c", 131, __extension__ __PRETTY_FUNCTION__));
  ((normal != ((void *)0)) ? (void) (0) : __assert_fail ("normal != NULL", "material.c", 132, __extension__ __PRETTY_FUNCTION__));
  ((specular != ((void *)0)) ? (void) (0) : __assert_fail ("specular != NULL", "material.c", 133, __extension__ __PRETTY_FUNCTION__));
  ((emissive != ((void *)0)) ? (void) (0) : __assert_fail ("emissive != NULL", "material.c", 134, __extension__ __PRETTY_FUNCTION__));
  strncpy(material->path, path, 0x100);
  material->diffuse = diffuse;
  material->normal = normal;
  material->specular = specular;
  material->emissive = emissive;
}

variable_types:
buf
char [256]

variable_types: struct kl_texture_t { char path[256]; unsigned int w; unsigned int id; } *


decompiled_code:
char *__fastcall material_load(__int64 a1, char *a2)
{
char *v2; // r12
__int64 v3; // r13
char *v5; // [rsp+0h] [rbp-30h] BYREF
__int64 v6[5]; // [rsp+8h] [rbp-28h] BYREF

v2 = (char *)malloc(0x120uLL);
if ( !strcmp(a2, "DEFAULT_MATERIAL") )
{
material_load_default(a2, v2);
}
else
{
v3 = mtl_entries;
if ( !mtl_entries
|| (strncpy(buf_3, a2, 0xFFuLL),
byte_77F = 0,
path_split(buf_3, &v5, v6),
!(unsigned __int8)kl_material_loadfrommtl(v3, a2, v6[0], v2)) )
{
material_load_raw(a2, v2);
}
}
return v2;
}

canonical_decompiled_code:
char *__fastcall func4(__int64 a1, char *a2)
{
char *v2; // r12
__int64 v3; // r13
char *v5; // [rsp+0h] [rbp-30h] BYREF
__int64 v6[5]; // [rsp+8h] [rbp-28h] BYREF

v2 = (char *)malloc(0x120uLL);
if ( !strcmp(a2, "DEFAULT_MATERIAL") )
{
func2(a2, v2);
}
else
{
v3 = mtl_entries;
if ( !mtl_entries
|| (strncpy(buf_3, a2, 0xFFuLL),
byte_77F = 0,
func0(buf_3, &v5, v6),
!(unsigned __int8)kl_material_loadfrommtl(v3, a2, v6[0], v2)) )
{
func3(a2, v2);
}
}
return v2;
}

original_code:
static kl_material_t *material_load(char *path, char *vpath) {
  kl_material_t *material = malloc(sizeof(kl_material_t));
  if (strcmp(vpath, "DEFAULT_MATERIAL") == 0) {
    material_load_default(vpath, material);
    return material;
  }
  if (mtl_entries != ((void *)0)) {
    static char buf[0x100];
    strncpy(buf, vpath, 0x100);
    buf[0x100 -1] = '\0';
    char *mtlvpath;
    char *entvpath;
    path_split(buf, &mtlvpath, &entvpath);
    if (kl_material_loadfrommtl(mtl_entries, vpath, entvpath, material)) {
      return material;
    }
  }
  material_load_raw(vpath, material);
  return material;
}

canonical_original_code:
static struct kl_material *material_load(char *path, char *vpath) {
  struct kl_material *material = malloc(sizeof(kl_material_t));
  if (strcmp(vpath, "DEFAULT_MATERIAL") == 0) {
    material_load_default(vpath, material);
    return material;
  }
  if (mtl_entries != ((void *)0)) {
    static char buf[256];
    strncpy(buf, vpath, 0x100);
    buf[0x100 -1] = '\0';
    char *mtlvpath;
    char *entvpath;
    path_split(buf, &mtlvpath, &entvpath);
    if (kl_material_loadfrommtl(mtl_entries, vpath, entvpath, material)) {
      return material;
    }
  }
  material_load_raw(vpath, material);
  return material;
}

variable_types:
mtlvpath
char *

variable_types:
entvpath
char *

return_type: struct kl_material { char path[256]; struct kl_texture_t { char path[256]; unsigned int w; unsigned int id; } *diffuse; struct kl_texture_t *normal; struct kl_texture_t *specular; struct kl_texture_t *emissive; } *


decompiled_code:
__int64 __fastcall kl_material_incref(char *src)
{
__int64 v1; // rax
__int64 v3; // [rsp+0h] [rbp-20h] BYREF
char *v4; // [rsp+8h] [rbp-18h] BYREF

if ( !loader )
{
loader = kl_resource_loader_new(material_load, material_free);
kl_resource_add_entry(&unk_9A9, "DEFAULT_MATERIAL");
}
strncpy(buf_4, src, 0xFFuLL);
byte_87F = 0;
if ( path_split(buf_4, &v4, &v3) )
mtl_entries = kl_material_mtl_incref(v4);
else
mtl_entries = 0LL;
v1 = kl_resource_getid(src);
return kl_resource_incref(loader, v1);
}

canonical_decompiled_code:
__int64 __fastcall func5(char *src)
{
__int64 v1; // rax
__int64 v3; // [rsp+0h] [rbp-20h] BYREF
char *v4; // [rsp+8h] [rbp-18h] BYREF

if ( !loader )
{
loader = kl_resource_loader_new(material_load, material_free);
kl_resource_add_entry(&unk_9A9, "DEFAULT_MATERIAL");
}
strncpy(buf_4, src, 0xFFuLL);
byte_87F = 0;
if ( func0(buf_4, &v4, &v3) )
mtl_entries = kl_material_mtl_incref(v4);
else
mtl_entries = 0LL;
v1 = kl_resource_getid(src);
return kl_resource_incref(loader, v1);
}

original_code:
kl_material_t *kl_material_incref(char *path) {
  if (loader == ((void *)0)) {
    loader = kl_resource_loader_new((kl_resources_load_cb)&material_load, (kl_resources_free_cb)&material_free);
    kl_resource_add_entry("", "DEFAULT_MATERIAL");
  }
  static char buf[0x100];
  strncpy(buf, path, 0x100);
  buf[0x100 -1] = '\0';
  char *mtlvpath;
  char *entvpath;
  if (path_split(buf, &mtlvpath, &entvpath)) {
    mtl_entries = kl_material_mtl_incref(mtlvpath);
  } else {
    mtl_entries = ((void *)0);
  }
  kl_resource_id_t resid = kl_resource_getid(path);
  kl_material_t *material = kl_resource_incref(loader, resid);
  if (mtl_entries != ((void *)0) && material == ((void *)0)) {
  }
  return material;
}

canonical_original_code:
struct kl_material *kl_material_incref(char *path) {
  if (loader == ((void *)0)) {
    loader = kl_resource_loader_new((kl_resources_load_cb)&material_load, (kl_resources_free_cb)&material_free);
    kl_resource_add_entry("", "DEFAULT_MATERIAL");
  }
  static char buf[256];
  strncpy(buf, path, 0x100);
  buf[0x100 -1] = '\0';
  char *mtlvpath;
  char *entvpath;
  if (path_split(buf, &mtlvpath, &entvpath)) {
    mtl_entries = kl_material_mtl_incref(mtlvpath);
  } else {
    mtl_entries = ((void *)0);
  }
  unsigned long resid = kl_resource_getid(path);
  struct kl_material *material = kl_resource_incref(loader, resid);
  if (mtl_entries != ((void *)0) && material == ((void *)0)) {
  }
  return material;
}

variable_types:
resid
unsigned long


decompiled_code:
__int64 __fastcall kl_material_decref(char *src)
{
__int64 v1; // rax
__int64 v3; // [rsp+0h] [rbp-20h] BYREF
char *v4; // [rsp+8h] [rbp-18h] BYREF

strncpy(buf_0, src, 0xFFuLL);
byte_67F = 0;
if ( path_split(buf_0, &v4, &v3) )
kl_material_mtl_decref(v4);
v1 = kl_resource_getid(src);
return kl_resource_decref(v1);
}

canonical_decompiled_code:
__int64 __fastcall func6(char *src)
{
__int64 v1; // rax
__int64 v3; // [rsp+0h] [rbp-20h] BYREF
char *v4; // [rsp+8h] [rbp-18h] BYREF

strncpy(buf_0, src, 0xFFuLL);
byte_67F = 0;
if ( func0(buf_0, &v4, &v3) )
kl_material_mtl_decref(v4);
v1 = kl_resource_getid(src);
return kl_resource_decref(v1);
}

original_code:
void kl_material_decref(kl_material_t *material) {
  static char buf[0x100];
  strncpy(buf, material->path, 0x100);
  buf[0x100 -1] = '\0';
  char *mtlvpath;
  char *entvpath;
  if (path_split(buf, &mtlvpath, &entvpath)) {
    kl_material_mtl_decref(mtlvpath);
  }
  kl_resource_id_t resid = kl_resource_getid(material->path);
  kl_resource_decref(resid);
}

canonical_original_code:
void kl_material_decref(struct kl_material *material) {
  static char buf[256];
  strncpy(buf, material->path, 0x100);
  buf[0x100 -1] = '\0';
  char *mtlvpath;
  char *entvpath;
  if (path_split(buf, &mtlvpath, &entvpath)) {
    kl_material_mtl_decref(mtlvpath);
  }
  unsigned long resid = kl_resource_getid(material->path);
  kl_resource_decref(resid);
}


hash

decompiled_code:
__int64 __fastcall hash(char *a1)
{
char v1; // al
_BYTE *v2; // rdi
unsigned int i; // edx

v1 = *a1;
v2 = a1 + 1;
for ( i = 0; v1; v1 = *(v2 - 1) )
{
i = __ROL4__(i ^ v1, 11);
++v2;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func4(char *a1)
{
char v1; // al
_BYTE *v2; // rdi
unsigned int i; // edx

v1 = *a1;
v2 = a1 + 1;
for ( i = 0; v1; v1 = *(v2 - 1) )
{
i = __ROL4__(i ^ v1, 11);
++v2;
}
return i;
}

original_code:
static uint32_t hash(char *str) {
  uint32_t h = 0;
  for (int i=0; ; i++) {
    char c = str[i];
    if (c == '\0') return h;
    h ^= c;
    h = (h << 11) | (h >> 21);
  }
}

canonical_original_code:
static unsigned int hash(char *str) {
  unsigned int h = 0;
  for (int i = 0; ; i++) {
    char c = str[i];
    if (c == '\0') return h;
    h ^= c;
    h = (h << 11) | (h >> 21);
  }
}

variable_types:
str
char *

variable_types:
h
unsigned int

variable_types: i int

variable_types: c char


decompiled_code:
__int64 __fastcall frame_lookup(__int64 a1, int a2)
{
__int64 result; // rax
int v3; // ebx
__int64 v4; // r12
__int64 v5[5]; // [rsp+8h] [rbp-28h] BYREF

result = a1;
if ( a2 )
{
v3 = 0;
v4 = a1 + 88;
while ( (int)kl_array_size(v4) > v3 )
{
kl_array_get(v4, v3, v5);
result = v5[0];
if ( *(_DWORD *)(v5[0] + 8) == a2 )
return result;
++v3;
}
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, int a2)
{
__int64 result; // rax
int v3; // ebx
__int64 v4; // r12
__int64 v5[5]; // [rsp+8h] [rbp-28h] BYREF

result = a1;
if ( a2 )
{
v3 = 0;
v4 = a1 + 88;
while ( (int)func0(v4) > v3 )
{
func7(v4, v3, v5);
result = v5[0];
if ( *(_DWORD *)(v5[0] + 8) == a2 )
return result;
++v3;
}
result = 0LL;
}
return result;
}

original_code:
static kl_frame_t* frame_lookup(kl_frame_t *parent, uint32_t id) {
  if (id == 0) return parent;
  kl_frame_t *child;
  for (int i=0; i < kl_array_size(&parent->header.children); i++) {
    kl_array_get(&parent->header.children, i, &child);
    if (child->header.id == id) {
      return child;
    }
  }
  return ((void *)0);
}

canonical_original_code:
static union kl_frame *frame_lookup(union kl_frame *parent, unsigned int id) {
  if (id == 0) return parent;
  union kl_frame *child;
  for (int i = 0; i < kl_array_size(&parent->header.children); i++) {
    kl_array_get(&parent->header.children, i, &child);
    if (child->header.id == id) {
      return child;
    }
  }
  return ((void *)0);
}

variable_types:
parent
union kl_frame *

variable_types:
id
unsigned int

variable_types: union kl_frame { struct kl_frame_header { int type; int hidden; unsigned int id; struct kl_frame_coord { int type; float x; } preferred_size; struct kl_frame_anchor { int point; unsigned int target_id; int target_point; struct kl_frame_coord offset; } anchor_primary; struct kl_frame_anchor anchor_secondary; struct kl_vec2f { float x; } effective_position; struct kl_vec2f effective_size; struct kl_array { unsigned char *data; int size; int item_size; int num_items; } children; } header; struct kl_frame_graphic { struct kl_frame_header header; struct kl_material { char path[256]; struct kl_texture_t { char path[256]; unsigned int w; unsigned int id; } *diffuse; struct kl_texture_t *normal; struct kl_texture_t *specular; struct kl_texture_t *emissive; } *material; } graphic; struct kl_frame_text { struct kl_frame_header header; int n; char *str; } text; } *

user_defined_types: union kl_frame { struct kl_frame_header header; struct kl_frame_graphic graphic; struct kl_frame_text text; }

user_defined_types: struct kl_frame_header { int type; int hidden; unsigned int id; struct kl_frame_coord preferred_size; struct kl_frame_anchor anchor_primary; struct kl_frame_anchor anchor_secondary; struct kl_vec2f effective_position; struct kl_vec2f effective_size; struct kl_array children; }

user_defined_types: struct kl_frame_graphic { struct kl_frame_header header; struct kl_material *material; }


decompiled_code:
void __fastcall frame_free_resources(__int64 a1)
{
void *v1; // rdi

if ( *(_DWORD *)a1 == 1 )
{
if ( *(_QWORD *)(a1 + 112) )
kl_material_decref();
}
else if ( *(_DWORD *)a1 == 2 )
{
v1 = *(void **)(a1 + 120);
if ( v1 )
free(v1);
}
}

canonical_decompiled_code:
void __fastcall func10(__int64 a1)
{
void *v1; // rdi

if ( *(_DWORD *)a1 == 1 )
{
if ( *(_QWORD *)(a1 + 112) )
kl_material_decref();
}
else if ( *(_DWORD *)a1 == 2 )
{
v1 = *(void **)(a1 + 120);
if ( v1 )
free(v1);
}
}

original_code:
void frame_free_resources(kl_frame_t *frame) {
  switch (frame->header.type) {
    case 0x01:
      if (frame->graphic.material != ((void *)0)) {
        kl_material_decref(frame->graphic.material);
      }
      break;
    case 0x02:
      if (frame->text.str != ((void *)0)) {
        free(frame->text.str);
      }
      break;
  }
}

canonical_original_code:
void frame_free_resources(union kl_frame *frame) {
  switch (frame->header.type) {
    case 0x01:
      if (frame->graphic.material != ((void *)0)) {
        kl_material_decref(frame->graphic.material);
      }
      break;
    case 0x02:
      if (frame->text.str != ((void *)0)) {
        free(frame->text.str);
      }
      break;
  }
}

user_defined_types: struct kl_frame_text { struct kl_frame_header header; int n; char *str; }

user_defined_types: struct kl_frame_coord { int type; float x; }

user_defined_types: struct kl_frame_anchor { int point; unsigned int target_id; int target_point; struct kl_frame_coord offset; }


decompiled_code:
__int64 __fastcall kl_frame_graphic(__int64 a1, __int64 a2)
{
__int64 result; // rax

frame_free_resources(a1);
*(_DWORD *)a1 = 1;
result = kl_material_incref(a2);
*(_QWORD *)(a1 + 112) = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1, __int64 a2)
{
__int64 result; // rax

func10(a1);
*(_DWORD *)a1 = 1;
result = kl_material_incref(a2);
*(_QWORD *)(a1 + 112) = result;
return result;
}

original_code:
void kl_frame_graphic(kl_frame_t *frame, char *path) {
  frame_free_resources(frame);
  frame->header.type = 0x01;
  frame->graphic.material = kl_material_incref(path);
}

canonical_original_code:
void kl_frame_graphic(union kl_frame *frame, char *path) {
  frame_free_resources(frame);
  frame->header.type = 0x01;
  frame->graphic.material = kl_material_incref(path);
}

variable_types:
path
char *


decompiled_code:
void __fastcall kl_frame_delete(void *a1)
{
int v1; // ebx
__int64 v2; // r12
void *ptr; // [rsp+8h] [rbp-28h] BYREF

v1 = 0;
v2 = (__int64)a1 + 88;
while ( (int)kl_array_size(v2) > v1 )
{
kl_array_get(v2, v1, &ptr);
kl_frame_delete(ptr);
++v1;
}
kl_array_free(v2);
frame_free_resources((__int64)a1);
free(a1);
}

canonical_decompiled_code:
void __fastcall func12(void *a1)
{
int v1; // ebx
__int64 v2; // r12
void *ptr; // [rsp+8h] [rbp-28h] BYREF

v1 = 0;
v2 = (__int64)a1 + 88;
while ( (int)func0(v2) > v1 )
{
func7(v2, v1, &ptr);
func12(ptr);
++v1;
}
kl_array_free(v2);
func10((__int64)a1);
free(a1);
}

original_code:
void kl_frame_delete(kl_frame_t *frame) {
  kl_frame_header_t *header = &frame->header;
  kl_frame_t *child;
  for (int i=0; i < kl_array_size(&header->children); i++) {
    kl_array_get(&header->children, i, &child);
    kl_frame_delete(child);
  }
  kl_array_free(&header->children);
  frame_free_resources(frame);
  free(frame);
}

canonical_original_code:
void kl_frame_delete(union kl_frame *frame) {
  struct kl_frame_header *header = &frame->header;
  union kl_frame *child;
  for (int i = 0; i < kl_array_size(&header->children); i++) {
    kl_array_get(&header->children, i, &child);
    kl_frame_delete(child);
  }
  kl_array_free(&header->children);
  frame_free_resources(frame);
  free(frame);
}

variable_types: struct kl_frame_header { int type; int hidden; unsigned int id; struct kl_frame_coord { int type; float x; } preferred_size; struct kl_frame_anchor { int point; unsigned int target_id; int target_point; struct kl_frame_coord offset; } anchor_primary; struct kl_frame_anchor anchor_secondary; struct kl_vec2f { float x; } effective_position; struct kl_vec2f effective_size; struct kl_array { unsigned char *data; int size; int item_size; int num_items; } children; } *


decompiled_code:
__int64 __fastcall kl_frame_add(__int64 a1, __int64 a2)
{
__int64 v3; // [rsp+8h] [rbp-8h] BYREF

v3 = a2;
return kl_array_push(a1 + 88, &v3);
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1, __int64 a2)
{
__int64 v3; // [rsp+8h] [rbp-8h] BYREF

v3 = a2;
return kl_array_push(a1 + 88, &v3);
}

original_code:
void kl_frame_add(kl_frame_t *frame, kl_frame_t *child) {
  kl_array_push(&frame->header.children, &child);
}

canonical_original_code:
void kl_frame_add(union kl_frame *frame, union kl_frame *child) {
  kl_array_push(&frame->header.children, &child);
}

variable_types:
child
union kl_frame *


original_code:
void kl_frame_update(kl_frame_t *frame, kl_frame_t *parent, int screen_w, int screen_h) {
  kl_frame_header_t *header = &frame->header;
  if (header->anchor_primary.point == 0xFF) return;
  if (header->hidden) return;
  kl_frame_anchor_t *anchor_primary = &header->anchor_primary;
  kl_frame_anchor_t *anchor_secondary = &header->anchor_secondary;
  kl_vec2f_t preferred_size;
  coord_normalize(&header->preferred_size, &preferred_size, screen_w, screen_h);
  kl_frame_t *primary_target = frame_lookup(parent, anchor_primary->target_id);
  kl_vec2f_t primary_target_point;
  anchor_point(anchor_primary->target_point, &primary_target_point);
  kl_vec2f_mul(&primary_target_point, &primary_target_point, &primary_target->header.effective_size);
  kl_vec2f_add(&primary_target_point, &primary_target_point, &primary_target->header.effective_position);
  kl_vec2f_t primary_offset;
  coord_normalize(&anchor_primary->offset, &primary_offset, screen_w, screen_h);
  kl_vec2f_add(&primary_target_point, &primary_target_point, &primary_offset);
  kl_vec2f_t primary_local_point;
  anchor_point(anchor_primary->point, &primary_local_point);
  kl_vec2f_t size, position;
  if (anchor_secondary->point == 0xFF) {
    size = preferred_size;
  } else {
    kl_frame_t *secondary_target = frame_lookup(parent, anchor_secondary->target_id);
    kl_vec2f_t secondary_target_point;
    anchor_point(anchor_secondary->target_point, &secondary_target_point);
    kl_vec2f_mul(&secondary_target_point, &secondary_target_point, &secondary_target->header.effective_size);
    kl_vec2f_add(&secondary_target_point, &secondary_target_point, &secondary_target->header.effective_position);
    kl_vec2f_t secondary_offset;
    coord_normalize(&anchor_secondary->offset, &secondary_offset, screen_w, screen_h);
    kl_vec2f_add(&secondary_target_point, &secondary_target_point, &secondary_offset);
    kl_vec2f_t secondary_local_point;
    anchor_point(anchor_secondary->point, &secondary_local_point);
    kl_vec2f_t target_dist;
    kl_vec2f_sub(&target_dist, &primary_target_point, &secondary_target_point);
    kl_vec2f_t local_dist;
    kl_vec2f_sub(&local_dist, &primary_local_point, &secondary_local_point);
    if ((anchor_primary->target_point & 0x0F) ==
        (anchor_secondary->target_point & 0x0F))
    {
      size.x = preferred_size.x;
    } else {
      size.x = target_dist.x / local_dist.x;
    }
    if ((anchor_primary->target_point & 0xF0) ==
        (anchor_secondary->target_point & 0xF0))
    {
      size.y = preferred_size.y;
    } else {
      size.y = target_dist.y / local_dist.y;
    }
  }
  kl_vec2f_mul(&position, &size, &primary_local_point);
  kl_vec2f_sub(&position, &primary_target_point, &position);
  kl_frame_t *child;
  for (int i=0; i < kl_array_size(&header->children); i++) {
    kl_array_get(&header->children, i, &child);
    kl_frame_update(child, frame, screen_w, screen_h);
  }
}

canonical_original_code:
void kl_frame_update(union kl_frame *frame, union kl_frame *parent, int screen_w, int screen_h) {
  struct kl_frame_header *header = &frame->header;
  if (header->anchor_primary.point == 0xFF) return;
  if (header->hidden) return;
  struct kl_frame_anchor *anchor_primary = &header->anchor_primary;
  struct kl_frame_anchor *anchor_secondary = &header->anchor_secondary;
  struct kl_vec2f preferred_size;
  coord_normalize(&header->preferred_size, &preferred_size, screen_w, screen_h);
  union kl_frame *primary_target = frame_lookup(parent, anchor_primary->target_id);
  struct kl_vec2f primary_target_point;
  anchor_point(anchor_primary->target_point, &primary_target_point);
  kl_vec2f_mul(&primary_target_point, &primary_target_point, &primary_target->header.effective_size);
  kl_vec2f_add(&primary_target_point, &primary_target_point, &primary_target->header.effective_position);
  struct kl_vec2f primary_offset;
  coord_normalize(&anchor_primary->offset, &primary_offset, screen_w, screen_h);
  kl_vec2f_add(&primary_target_point, &primary_target_point, &primary_offset);
  struct kl_vec2f primary_local_point;
  anchor_point(anchor_primary->point, &primary_local_point);
  struct kl_vec2f size; struct kl_vec2f position;
  if (anchor_secondary->point == 0xFF) {
    size = preferred_size;
  } else {
    union kl_frame *secondary_target = frame_lookup(parent, anchor_secondary->target_id);
    struct kl_vec2f secondary_target_point;
    anchor_point(anchor_secondary->target_point, &secondary_target_point);
    kl_vec2f_mul(&secondary_target_point, &secondary_target_point, &secondary_target->header.effective_size);
    kl_vec2f_add(&secondary_target_point, &secondary_target_point, &secondary_target->header.effective_position);
    struct kl_vec2f secondary_offset;
    coord_normalize(&anchor_secondary->offset, &secondary_offset, screen_w, screen_h);
    kl_vec2f_add(&secondary_target_point, &secondary_target_point, &secondary_offset);
    struct kl_vec2f secondary_local_point;
    anchor_point(anchor_secondary->point, &secondary_local_point);
    struct kl_vec2f target_dist;
    kl_vec2f_sub(&target_dist, &primary_target_point, &secondary_target_point);
    struct kl_vec2f local_dist;
    kl_vec2f_sub(&local_dist, &primary_local_point, &secondary_local_point);
    if ((anchor_primary->target_point & 0x0F) ==
        (anchor_secondary->target_point & 0x0F))
    {
      size.x = preferred_size.x;
    } else {
      size.x = target_dist.x / local_dist.x;
    }
    if ((anchor_primary->target_point & 0xF0) ==
        (anchor_secondary->target_point & 0xF0))
    {
      size.y = preferred_size.y;
    } else {
      size.y = target_dist.y / local_dist.y;
    }
  }
  kl_vec2f_mul(&position, &size, &primary_local_point);
  kl_vec2f_sub(&position, &primary_target_point, &position);
  union kl_frame *child;
  for (int i = 0; i < kl_array_size(&header->children); i++) {
    kl_array_get(&header->children, i, &child);
    kl_frame_update(child, frame, screen_w, screen_h);
  }
}

variable_types: struct kl_frame_anchor { int point; unsigned int target_id; int target_point; struct kl_frame_coord { int type; float x; } offset; } *

variable_types:
size
struct kl_vec2f { float x; }

variable_types:
position
struct kl_vec2f { float x; }


decompiled_code:
void __fastcall mtl_free(void *ptr)
{
kl_array_free();
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
kl_array_free();
free(ptr);
}

original_code:
static void mtl_free(void *item) {
  kl_array_t *entries = item;
  kl_array_free(entries);
  free(item);
}

canonical_original_code:
static void mtl_free(void *item) {
  struct kl_array *entries = item;
  kl_array_free(entries);
  free(item);
}

variable_types:
item
void *

variable_types: struct kl_array { unsigned char *data; int size; int item_size; int num_items; } *


decompiled_code:
__int64 __fastcall kl_material_mtl_incref(__int64 a1)
{
__int64 v1; // rax

if ( !loader )
loader = kl_resource_loader_new(mtl_load, mtl_free);
v1 = kl_resource_getid(a1);
return kl_resource_incref(loader, v1);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 v1; // rax

if ( !loader )
loader = kl_resource_loader_new(mtl_load, mtl_free);
v1 = kl_resource_getid(a1);
return kl_resource_incref(loader, v1);
}

original_code:
kl_array_t *kl_material_mtl_incref(char *path) {
  if (loader == ((void *)0)) {
    loader = kl_resource_loader_new((kl_resources_load_cb)&mtl_load, (kl_resources_free_cb)&mtl_free);
  }
  kl_resource_id_t resid = kl_resource_getid(path);
  kl_array_t *entries = kl_resource_incref(loader, resid);
  return entries;
}

canonical_original_code:
struct kl_array *kl_material_mtl_incref(char *path) {
  if (loader == ((void *)0)) {
    loader = kl_resource_loader_new((kl_resources_load_cb)&mtl_load, (kl_resources_free_cb)&mtl_free);
  }
  unsigned long resid = kl_resource_getid(path);
  struct kl_array *entries = kl_resource_incref(loader, resid);
  return entries;
}

return_type: struct kl_array { unsigned char *data; int size; int item_size; int num_items; } *


decompiled_code:
__int64 __fastcall kl_material_mtl_decref(__int64 a1)
{
__int64 v1; // rax

v1 = kl_resource_getid(a1);
return kl_resource_decref(v1);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
__int64 v1; // rax

v1 = kl_resource_getid(a1);
return kl_resource_decref(v1);
}

original_code:
void kl_material_mtl_decref(char *path) {
  kl_resource_id_t resid = kl_resource_getid(path);
  kl_resource_decref(resid);
}

canonical_original_code:
void kl_material_mtl_decref(char *path) {
  unsigned long resid = kl_resource_getid(path);
  kl_resource_decref(resid);
}


decompiled_code:
__int64 __fastcall kl_material_loadfrommtl(__int64 a1, const char *a2, const char *a3, __int64 a4)
{
int i; // ebx
__int64 v7; // r15
__int64 v8; // r13
__int64 v9; // r12
__int64 v10; // rbx
char s1[256]; // [rsp+0h] [rbp-530h] BYREF
char v13[256]; // [rsp+100h] [rbp-430h] BYREF
char v14[256]; // [rsp+200h] [rbp-330h] BYREF
char v15[256]; // [rsp+300h] [rbp-230h] BYREF
char v16[304]; // [rsp+400h] [rbp-130h] BYREF

for ( i = 0; ; ++i )
{
if ( (int)kl_array_size(a1) <= i )
return 0LL;
kl_array_get(a1, i, s1);
if ( !strcmp(s1, a3) )
break;
}
strncpy((char *)a4, a2, 0x100uLL);
v7 = kl_texture_incref(v13);
v8 = kl_texture_incref(v15);
v9 = kl_texture_incref(v14);
v10 = kl_texture_incref(v16);
if ( !v7 )
v7 = kl_texture_incref("DEFAULT_DIFFUSE");
if ( !v8 )
v8 = kl_texture_incref("DEFAULT_NORMAL");
if ( !v9 )
v9 = kl_texture_incref("DEFAULT_SPECULAR");
if ( !v10 )
v10 = kl_texture_incref("DEFAULT_EMISSIVE");
*(_QWORD *)(a4 + 256) = v7;
*(_QWORD *)(a4 + 264) = v8;
*(_QWORD *)(a4 + 272) = v9;
*(_QWORD *)(a4 + 280) = v10;
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, const char *a2, const char *a3, __int64 a4)
{
int i; // ebx
__int64 v7; // r15
__int64 v8; // r13
__int64 v9; // r12
__int64 v10; // rbx
char s1[256]; // [rsp+0h] [rbp-530h] BYREF
char v13[256]; // [rsp+100h] [rbp-430h] BYREF
char v14[256]; // [rsp+200h] [rbp-330h] BYREF
char v15[256]; // [rsp+300h] [rbp-230h] BYREF
char v16[304]; // [rsp+400h] [rbp-130h] BYREF

for ( i = 0; ; ++i )
{
if ( (int)func0(a1) <= i )
return 0LL;
func3(a1, i, s1);
if ( !strcmp(s1, a3) )
break;
}
strncpy((char *)a4, a2, 0x100uLL);
v7 = kl_texture_incref(v13);
v8 = kl_texture_incref(v15);
v9 = kl_texture_incref(v14);
v10 = kl_texture_incref(v16);
if ( !v7 )
v7 = kl_texture_incref("DEFAULT_DIFFUSE");
if ( !v8 )
v8 = kl_texture_incref("DEFAULT_NORMAL");
if ( !v9 )
v9 = kl_texture_incref("DEFAULT_SPECULAR");
if ( !v10 )
v10 = kl_texture_incref("DEFAULT_EMISSIVE");
*(_QWORD *)(a4 + 256) = v7;
*(_QWORD *)(a4 + 264) = v8;
*(_QWORD *)(a4 + 272) = v9;
*(_QWORD *)(a4 + 280) = v10;
return 1LL;
}

original_code:
_Bool kl_material_loadfrommtl(kl_array_t *entries, char *vpath, char *entvpath, kl_material_t *material) {
  mtl_entry_t entry;
  for (int i=0; i < kl_array_size(entries); i++) {
    kl_array_get(entries, i, &entry);
    if (strcmp(entry.path, entvpath) == 0) {
      strncpy(material->path, vpath, 0x100);
      kl_texture_t *diffuse = kl_texture_incref(entry.map_diffuse);
      kl_texture_t *normal = kl_texture_incref(entry.map_normal);
      kl_texture_t *specular = kl_texture_incref(entry.map_specular);
      kl_texture_t *emissive = kl_texture_incref(entry.map_emissive);
      if (diffuse == ((void *)0)) diffuse = kl_texture_incref("DEFAULT_DIFFUSE");
      if (normal == ((void *)0)) normal = kl_texture_incref("DEFAULT_NORMAL");
      if (specular == ((void *)0)) specular = kl_texture_incref("DEFAULT_SPECULAR");
      if (emissive == ((void *)0)) emissive = kl_texture_incref("DEFAULT_EMISSIVE");
      material->diffuse = diffuse;
      material->normal = normal;
      material->specular = specular;
      material->emissive = emissive;
      return 1;
    }
  }
  return 0;
}

canonical_original_code:
_Bool kl_material_loadfrommtl(struct kl_array *entries, char *vpath, char *entvpath, struct kl_material *material) {
  struct mtl_entry entry;
  for (int i = 0; i < kl_array_size(entries); i++) {
    kl_array_get(entries, i, &entry);
    if (strcmp(entry.path, entvpath) == 0) {
      strncpy(material->path, vpath, 0x100);
      struct kl_texture_t *diffuse = kl_texture_incref(entry.map_diffuse);
      struct kl_texture_t *normal = kl_texture_incref(entry.map_normal);
      struct kl_texture_t *specular = kl_texture_incref(entry.map_specular);
      struct kl_texture_t *emissive = kl_texture_incref(entry.map_emissive);
      if (diffuse == ((void *)0)) diffuse = kl_texture_incref("DEFAULT_DIFFUSE");
      if (normal == ((void *)0)) normal = kl_texture_incref("DEFAULT_NORMAL");
      if (specular == ((void *)0)) specular = kl_texture_incref("DEFAULT_SPECULAR");
      if (emissive == ((void *)0)) emissive = kl_texture_incref("DEFAULT_EMISSIVE");
      material->diffuse = diffuse;
      material->normal = normal;
      material->specular = specular;
      material->emissive = emissive;
      return 1;
    }
  }
  return 0;
}

variable_types:
vpath
char *

variable_types:
entvpath
char *

variable_types: struct kl_material { char path[256]; struct kl_texture_t { char path[256]; unsigned int w; unsigned int id; } *diffuse; struct kl_texture_t *normal; struct kl_texture_t *specular; struct kl_texture_t *emissive; } *

variable_types: struct mtl_entry { char path[256]; char map_diffuse[256]; char map_specular[256]; char map_normal[256]; char map_emissive[256]; }


decompiled_code:
void __fastcall kl_vec3f_norm(__int64 a1, float *a2)
{
float v2; // xmm0_4

v2 = kl_vec3f_magnitude(a2);
if ( v2 == 0.0 )
{
*(_DWORD *)a1 = 0;
*(_DWORD *)(a1 + 4) = 0;
*(_DWORD *)(a1 + 8) = 0;
}
else
{
kl_vec3f_scale((float *)a1, a2, 1.0 / v2);
}
}

original_code:
static inline void kl_vec3f_norm(kl_vec3f_t *dst, kl_vec3f_t *src) {
  float m = kl_vec3f_magnitude(src);
  if (m == 0.0f) {
    *dst = (kl_vec3f_t){ .x = 0.0f, .y = 0.0f, .z = 0.0f };
    return;
  }
  float s = 1.0f/m;
  kl_vec3f_scale(dst, src, s);
}

canonical_original_code:
static inline void kl_vec3f_norm(struct kl_vec3f *dst, struct kl_vec3f *src) {
  float m = kl_vec3f_magnitude(src);
  if (m == 0.0f) {
    *dst = (struct kl_vec3f){ .x = 0.0f, .y = 0.0f, .z = 0.0f };
    return;
  }
  float s = 1.0f/m;
  kl_vec3f_scale(dst, src, s);
}

variable_types:
dst
struct kl_vec3f { float x; } *

variable_types:
src
struct kl_vec3f *

variable_types: m float

variable_types: s float


decompiled_code:
__int64 __fastcall kl_sphere_merge(__int64 a1, float *a2, float *a3)
{
__int64 result; // rax
float v5; // xmm0_4
__int64 v6; // [rsp+4h] [rbp-5Ch] BYREF
unsigned int v7; // [rsp+Ch] [rbp-54h]
float v8[3]; // [rsp+10h] [rbp-50h] BYREF
float v9[3]; // [rsp+1Ch] [rbp-44h] BYREF
float v10[3]; // [rsp+28h] [rbp-38h] BYREF
float v11[11]; // [rsp+34h] [rbp-2Ch] BYREF

kl_vec3f_sub(v10, a3, a2);
kl_vec3f_norm((__int64)v10, v10);
kl_vec3f_scale(v11, v10, a2[3]);
kl_vec3f_sub(v9, a2, v11);
kl_vec3f_scale(v11, v10, a3[3]);
kl_vec3f_add(v8, a3, v11);
result = kl_sphere_test(a2, v8);
if ( (_DWORD)result )
{
if ( a2 != (float *)a1 )
*(__m128i *)a1 = _mm_loadu_si128((const __m128i *)a2);
}
else
{
result = kl_sphere_test(a3, v9);
if ( (_DWORD)result )
{
if ( a3 != (float *)a1 )
*(__m128i *)a1 = _mm_loadu_si128((const __m128i *)a3);
}
else
{
kl_vec3f_add((float *)&v6, v9, v8);
kl_vec3f_scale((float *)&v6, (float *)&v6, 0.5);
kl_vec3f_sub(v11, v8, v9);
v5 = kl_vec3f_magnitude(v11);
*(_QWORD *)a1 = v6;
result = v7;
*(_DWORD *)(a1 + 8) = v7;
*(float *)(a1 + 12) = v5 * 0.5;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, float *a2, float *a3)
{
__int64 result; // rax
float v5; // xmm0_4
__int64 v6; // [rsp+4h] [rbp-5Ch] BYREF
unsigned int v7; // [rsp+Ch] [rbp-54h]
float v8[3]; // [rsp+10h] [rbp-50h] BYREF
float v9[3]; // [rsp+1Ch] [rbp-44h] BYREF
float v10[3]; // [rsp+28h] [rbp-38h] BYREF
float v11[11]; // [rsp+34h] [rbp-2Ch] BYREF

func1(v10, a3, a2);
func4((__int64)v10, v10);
func2(v11, v10, a2[3]);
func1(v9, a2, v11);
func2(v11, v10, a3[3]);
func0(v8, a3, v11);
result = func6(a2, v8);
if ( (_DWORD)result )
{
if ( a2 != (float *)a1 )
*(__m128i *)a1 = _mm_loadu_si128((const __m128i *)a2);
}
else
{
result = func6(a3, v9);
if ( (_DWORD)result )
{
if ( a3 != (float *)a1 )
*(__m128i *)a1 = _mm_loadu_si128((const __m128i *)a3);
}
else
{
func0((float *)&v6, v9, v8);
func2((float *)&v6, (float *)&v6, 0.5);
func1(v11, v8, v9);
v5 = func3(v11);
*(_QWORD *)a1 = v6;
result = v7;
*(_DWORD *)(a1 + 8) = v7;
*(float *)(a1 + 12) = v5 * 0.5;
}
}
return result;
}

original_code:
void kl_sphere_merge(kl_sphere_t *dst, kl_sphere_t *s1, kl_sphere_t *s2) {
  kl_vec3f_t temp, dir, max1, max2, center;
  float radius;
  kl_vec3f_sub(&dir, &s2->center, &s1->center);
  kl_vec3f_norm(&dir, &dir);
  kl_vec3f_scale(&temp, &dir, s1->radius);
  kl_vec3f_sub(&max1, &s1->center, &temp);
  kl_vec3f_scale(&temp, &dir, s2->radius);
  kl_vec3f_add(&max2, &s2->center, &temp);
  if (kl_sphere_test(s1, &max2)) {
    if (dst != s1) {
      *dst = *s1;
    }
    return;
  }
  if (kl_sphere_test(s2, &max1)) {
    if (dst != s2) {
      *dst = *s2;
    }
    return;
  }
  kl_vec3f_add(&center, &max1, &max2);
  kl_vec3f_scale(&center, &center, 0.5f);
  kl_vec3f_sub(&temp, &max2, &max1);
  radius = kl_vec3f_magnitude(&temp) / 2.0f;
  *dst = (kl_sphere_t){
    .center = center,
    .radius = radius
  };
}

canonical_original_code:
void kl_sphere_merge(struct kl_sphere *dst, struct kl_sphere *s1, struct kl_sphere *s2) {
  struct kl_vec3f temp; struct kl_vec3f dir; struct kl_vec3f max1; struct kl_vec3f max2; struct kl_vec3f center;
  float radius;
  kl_vec3f_sub(&dir, &s2->center, &s1->center);
  kl_vec3f_norm(&dir, &dir);
  kl_vec3f_scale(&temp, &dir, s1->radius);
  kl_vec3f_sub(&max1, &s1->center, &temp);
  kl_vec3f_scale(&temp, &dir, s2->radius);
  kl_vec3f_add(&max2, &s2->center, &temp);
  if (kl_sphere_test(s1, &max2)) {
    if (dst != s1) {
      *dst = *s1;
    }
    return;
  }
  if (kl_sphere_test(s2, &max1)) {
    if (dst != s2) {
      *dst = *s2;
    }
    return;
  }
  kl_vec3f_add(&center, &max1, &max2);
  kl_vec3f_scale(&center, &center, 0.5f);
  kl_vec3f_sub(&temp, &max2, &max1);
  radius = kl_vec3f_magnitude(&temp) / 2.0f;
  *dst = (struct kl_sphere){
    .center = center,
    .radius = radius
  };
}

variable_types: struct kl_sphere { struct kl_vec3f { float x; } center; float radius; } *

variable_types:
temp
struct kl_vec3f { float x; }

variable_types:
dir
struct kl_vec3f { float x; }

variable_types:
center
struct kl_vec3f { float x; }

variable_types: radius float