decompiled_code:
char *__fastcall kl_bvh_insert(__int64 *a1, __int64 *a2, __int64 a3)
{
float *v3; // rax
char *result; // rax

v3 = (float *)leaf_new(a2, a3);
result = leaf_insert(*a1, v3);
*a1 = (__int64)result;
return result;
}

canonical_decompiled_code:
char *__fastcall func6(__int64 *a1, __int64 *a2, __int64 a3)
{
float *v3; // rax
char *result; // rax

v3 = (float *)leaf_new(a2, a3);
result = func5(*a1, v3);
*a1 = (__int64)result;
return result;
}

original_code:
void kl_bvh_insert(kl_bvh_node_t **root, kl_sphere_t *bounds, void *item) {
  kl_bvh_leaf_t *leaf = leaf_new(bounds, item);
  *root = leaf_insert(*root, leaf);
}

canonical_original_code:
void kl_bvh_insert(union kl_bvh_node **root, struct kl_sphere *bounds, void *item) {
  struct kl_bvh_leaf *leaf = leaf_new(bounds, item);
  *root = leaf_insert(*root, leaf);
}

variable_types: union kl_bvh_node { struct kl_bvh_header { int type; struct kl_sphere { struct kl_vec3f { float x; } center; float radius; } bounds; } header; struct kl_bvh_branch { struct kl_bvh_header header; union kl_bvh_node *children[2]; } branch; struct kl_bvh_leaf { struct kl_bvh_header header; void *item; } leaf; } **

variable_types:
bounds
struct kl_sphere *

variable_types:
item
void *

variable_types: struct kl_bvh_leaf { struct kl_bvh_header { int type; struct kl_sphere { struct kl_vec3f { float x; } center; float radius; } bounds; } header; void *item; } *


repo: zvxryb/kludge-engine

decompiled_code:
void __fastcall kl_bvh_search(__int64 a1, unsigned int (__fastcall *a2)(__int64, __int64), __int64 a3, __int64 a4)
{
__int64 v4; // rbx

v4 = a1;
if ( a1 )
{
while ( a2(v4 + 4, a3) )
{
if ( *(_DWORD *)v4 == 1 )
{
kl_array_push(a4, v4 + 24);
return;
}
if ( *(_DWORD *)v4 == 2 )
{
kl_bvh_search(*(_QWORD *)(v4 + 24), a2, a3, a4);
v4 = *(_QWORD *)(v4 + 32);
if ( v4 )
continue;
}
return;
}
}
}

original_code:
void kl_bvh_search(kl_bvh_node_t *root, kl_bvh_filter_cb filtercb, void *filter_data, kl_array_t *results) {
  if (root == ((void *)0)) return;
  if (!filtercb(&root->header.bounds, filter_data)) return;
  switch (root->header.type) {
    case 0x01:
      kl_array_push(results, &root->leaf.item);
      return;
    case 0x02:
      kl_bvh_search(root->branch.children[0], filtercb, filter_data, results);
      kl_bvh_search(root->branch.children[1], filtercb, filter_data, results);
      return;
  }
}

canonical_original_code:
void kl_bvh_search(union kl_bvh_node *root, int (*filtercb)(struct kl_sphere *, void *), void *filter_data, struct kl_array *results) {
  if (root == ((void *)0)) return;
  if (!filtercb(&root->header.bounds, filter_data)) return;
  switch (root->header.type) {
    case 0x01:
      kl_array_push(results, &root->leaf.item);
      return;
    case 0x02:
      kl_bvh_search(root->branch.children[0], filtercb, filter_data, results);
      kl_bvh_search(root->branch.children[1], filtercb, filter_data, results);
      return;
  }
}

variable_types: union kl_bvh_node { struct kl_bvh_header { int type; struct kl_sphere { struct kl_vec3f { float x; } center; float radius; } bounds; } header; struct kl_bvh_branch { struct kl_bvh_header header; union kl_bvh_node *children[2]; } branch; struct kl_bvh_leaf { struct kl_bvh_header header; void *item; } leaf; } *

variable_types:
filtercb
int (*)(struct kl_sphere *, void *)

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

return_type: void

user_defined_types: union kl_bvh_node { struct kl_bvh_header header; struct kl_bvh_branch branch; struct kl_bvh_leaf leaf; }

user_defined_types: struct kl_bvh_header { int type; struct kl_sphere bounds; }

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


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

v3 = a1;
if ( a1 )
{
kl_array_push(a2, &v3);
result = v3;
if ( *(_DWORD *)v3 == 2 )
{
kl_bvh_debug(*(_QWORD *)(v3 + 24), a2);
result = kl_bvh_debug(*(_QWORD *)(v3 + 32), a2);
}
}
return result;
}

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

v3 = a1;
if ( a1 )
{
kl_array_push(a2, &v3);
result = v3;
if ( *(_DWORD *)v3 == 2 )
{
func8(*(_QWORD *)(v3 + 24), a2);
result = func8(*(_QWORD *)(v3 + 32), a2);
}
}
return result;
}

original_code:
void kl_bvh_debug(kl_bvh_node_t* root, kl_array_t *results) {
  if (root == ((void *)0)) return;
  kl_array_push(results, &root);
  if (root->header.type == 0x02) {
      kl_bvh_debug(root->branch.children[0], results);
      kl_bvh_debug(root->branch.children[1], results);
  }
}

canonical_original_code:
void kl_bvh_debug(union kl_bvh_node *root, struct kl_array *results) {
  if (root == ((void *)0)) return;
  kl_array_push(results, &root);
  if (root->header.type == 0x02) {
      kl_bvh_debug(root->branch.children[0], results);
      kl_bvh_debug(root->branch.children[1], results);
  }
}

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

user_defined_types: struct kl_bvh_branch { struct kl_bvh_header header; union kl_bvh_node *children[2]; }

user_defined_types: struct kl_bvh_leaf { struct kl_bvh_header header; void *item; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v3; // r15
char v4; // r14
char v5; // r13
__int64 v6; // rax
__int64 v7; // rax
__int64 v8; // rax
int v9; // ebx
int v10; // er12
float v11; // xmm0_4
float v12; // xmm2_4
int result; // eax
char v14; // [rsp+Bh] [rbp-E5h]
float v15; // [rsp+Ch] [rbp-E4h]
int v16; // [rsp+14h] [rbp-DCh] BYREF
int v17; // [rsp+18h] [rbp-D8h] BYREF
__int64 v18; // [rsp+1Ch] [rbp-D4h] BYREF
__int64 v19; // [rsp+24h] [rbp-CCh] BYREF
int v20; // [rsp+2Ch] [rbp-C4h]
__int64 v21; // [rsp+30h] [rbp-C0h] BYREF
int v22; // [rsp+38h] [rbp-B8h]
__int64 v23; // [rsp+3Ch] [rbp-B4h] BYREF
int v24; // [rsp+44h] [rbp-ACh]
__int64 v25; // [rsp+48h] [rbp-A8h] BYREF
int v26; // [rsp+50h] [rbp-A0h]
int v27[3]; // [rsp+54h] [rbp-9Ch] BYREF
int v28[2]; // [rsp+60h] [rbp-90h] BYREF
char v29; // [rsp+68h] [rbp-88h]
int v30; // [rsp+6Ch] [rbp-84h]
int v31; // [rsp+70h] [rbp-80h]
__int64 v32[3]; // [rsp+80h] [rbp-70h] BYREF
int v33; // [rsp+98h] [rbp-58h]
float v34; // [rsp+9Ch] [rbp-54h]
__int64 v35; // [rsp+A0h] [rbp-50h]
int v36; // [rsp+A8h] [rbp-48h]
float v37; // [rsp+ACh] [rbp-44h]
float v38; // [rsp+B0h] [rbp-40h]
__int64 v39; // [rsp+B4h] [rbp-3Ch]

kl_resource_add_dir("./test_assets/", &unk_27, envp);
if ( (int)kl_vid_init() < 0 || (int)kl_input_init() < 0 || (int)kl_render_init() < 0 )
return -1;
v3 = 0;
v4 = 0;
v5 = 0;
kl_vid_size(&v16, &v17);
v32[1] = 0x3F80000000000000LL;
v39 = 0x461C40003F800000LL;
v32[0] = 0LL;
v32[2] = 0LL;
v37 = (float)v16;
v38 = (float)v17;
v33 = 0;
v35 = 1065747481LL;
v36 = 0;
v34 = (float)v16 / (float)v17;
kl_terrain_testsphere();
v6 = kl_model_load("test_assets/test.iqm");
kl_render_add_model(v6);
v7 = kl_model_load("test_assets/sponza.obj");
kl_render_add_model(v7);
v8 = kl_model_load("test_assets/colorcalibration.obj");
kl_render_add_model(v8);
v19 = 0x43C8000043FA0000LL;
v20 = 0;
kl_render_add_light(&v19, 1.0, 0.80000001, 0.60000002, 25000.0);
v21 = 0x43C80000C3FA0000LL;
v22 = 0;
kl_render_add_light(&v21, 1.0, 0.80000001, 0.60000002, 25000.0);
v23 = 0xC0000000C0000000LL;
v24 = 1065353216;
kl_render_set_envlight(&v23, 0.80000001, 0.80000001, 1.0, 0.0, 1.0, 0.89999998, 0.60000002);
v25 = 0LL;
v18 = 3212836864LL;
v26 = 0;
v14 = 0;
while ( 1 )
{
v9 = 0;
v10 = 0;
v15 = kl_timer_tick(&v18);
kl_input_tick();
LABEL_6:
if ( (unsigned __int8)kl_input_poll(v28) )
break;
LABEL_10:
*((float *)&v25 + 1) = COERCE_FLOAT(COERCE_UNSIGNED_INT((float)v10) ^ LC11) / 200.0;
*(float *)&v25 = COERCE_FLOAT(COERCE_UNSIGNED_INT((float)v9) ^ LC11) / 200.0;
kl_camera_local_rotate(v32, &v25);
v11 = *(float *)&LC0;
if ( !v3 )
v11 = 0.0;
if ( v4 )
v11 = v11 - 1.0;
v12 = *(float *)&LC0;
*(float *)v27 = v11;
v27[1] = 0;
if ( !v5 )
v12 = 0.0;
if ( v14 )
v12 = v12 - 1.0;
*(float *)&v27[2] = v12;
kl_vec3f_scale_constprop_0_isra_0((float *)v27, v11, 0.0, v12, v15 * 320.0);
kl_camera_local_move(v32, v27);
kl_render_draw(v32);
kl_vid_swap();
}
while ( v28[0] != 1 )
{
if ( v28[0] != 2 )
goto LABEL_6;
v10 += v30;
v9 += v31;
if ( !(unsigned __int8)kl_input_poll(v28) )
goto LABEL_10;
}
switch ( v28[1] )
{
case 1:
if ( !v29 )
goto LABEL_6;
result = 0;
break;
case 0x21:
kl_render_set_debug(0LL);
goto LABEL_6;
case 0x22:
kl_render_set_debug(1LL);
goto LABEL_6;
case 0x23:
kl_render_set_debug(2LL);
goto LABEL_6;
case 0x24:
kl_render_set_debug(3LL);
goto LABEL_6;
case 0x25:
kl_render_set_debug(4LL);
goto LABEL_6;
case 0x26:
kl_render_set_debug(5LL);
goto LABEL_6;
case 0x27:
kl_render_set_debug(6LL);
goto LABEL_6;
case 0x28:
kl_render_set_debug(7LL);
goto LABEL_6;
case 0x29:
kl_render_set_debug(8LL);
goto LABEL_6;
case 0x30:
v4 = v29;
goto LABEL_6;
case 0x33:
v3 = v29;
goto LABEL_6;
case 0x42:
v5 = v29;
goto LABEL_6;
case 0x46:
v14 = v29;
goto LABEL_6;
default:
goto LABEL_6;
}
return result;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v3; // r15
char v4; // r14
char v5; // r13
__int64 v6; // rax
__int64 v7; // rax
__int64 v8; // rax
int v9; // ebx
int v10; // er12
float v11; // xmm0_4
float v12; // xmm2_4
int result; // eax
char v14; // [rsp+Bh] [rbp-E5h]
float v15; // [rsp+Ch] [rbp-E4h]
int v16; // [rsp+14h] [rbp-DCh] BYREF
int v17; // [rsp+18h] [rbp-D8h] BYREF
__int64 v18; // [rsp+1Ch] [rbp-D4h] BYREF
__int64 v19; // [rsp+24h] [rbp-CCh] BYREF
int v20; // [rsp+2Ch] [rbp-C4h]
__int64 v21; // [rsp+30h] [rbp-C0h] BYREF
int v22; // [rsp+38h] [rbp-B8h]
__int64 v23; // [rsp+3Ch] [rbp-B4h] BYREF
int v24; // [rsp+44h] [rbp-ACh]
__int64 v25; // [rsp+48h] [rbp-A8h] BYREF
int v26; // [rsp+50h] [rbp-A0h]
int v27[3]; // [rsp+54h] [rbp-9Ch] BYREF
int v28[2]; // [rsp+60h] [rbp-90h] BYREF
char v29; // [rsp+68h] [rbp-88h]
int v30; // [rsp+6Ch] [rbp-84h]
int v31; // [rsp+70h] [rbp-80h]
__int64 v32[3]; // [rsp+80h] [rbp-70h] BYREF
int v33; // [rsp+98h] [rbp-58h]
float v34; // [rsp+9Ch] [rbp-54h]
__int64 v35; // [rsp+A0h] [rbp-50h]
int v36; // [rsp+A8h] [rbp-48h]
float v37; // [rsp+ACh] [rbp-44h]
float v38; // [rsp+B0h] [rbp-40h]
__int64 v39; // [rsp+B4h] [rbp-3Ch]

kl_resource_add_dir("./test_assets/", &unk_27, envp);
if ( (int)kl_vid_init() < 0 || (int)kl_input_init() < 0 || (int)kl_render_init() < 0 )
return -1;
v3 = 0;
v4 = 0;
v5 = 0;
kl_vid_size(&v16, &v17);
v32[1] = 0x3F80000000000000LL;
v39 = 0x461C40003F800000LL;
v32[0] = 0LL;
v32[2] = 0LL;
v37 = (float)v16;
v38 = (float)v17;
v33 = 0;
v35 = 1065747481LL;
v36 = 0;
v34 = (float)v16 / (float)v17;
kl_terrain_testsphere();
v6 = kl_model_load("test_assets/test.iqm");
kl_render_add_model(v6);
v7 = kl_model_load("test_assets/sponza.obj");
kl_render_add_model(v7);
v8 = kl_model_load("test_assets/colorcalibration.obj");
kl_render_add_model(v8);
v19 = 0x43C8000043FA0000LL;
v20 = 0;
kl_render_add_light(&v19, 1.0, 0.80000001, 0.60000002, 25000.0);
v21 = 0x43C80000C3FA0000LL;
v22 = 0;
kl_render_add_light(&v21, 1.0, 0.80000001, 0.60000002, 25000.0);
v23 = 0xC0000000C0000000LL;
v24 = 1065353216;
kl_render_set_envlight(&v23, 0.80000001, 0.80000001, 1.0, 0.0, 1.0, 0.89999998, 0.60000002);
v25 = 0LL;
v18 = 3212836864LL;
v26 = 0;
v14 = 0;
while ( 1 )
{
v9 = 0;
v10 = 0;
v15 = kl_timer_tick(&v18);
kl_input_tick();
LABEL_6:
if ( (unsigned __int8)kl_input_poll(v28) )
break;
LABEL_10:
*((float *)&v25 + 1) = COERCE_FLOAT(COERCE_UNSIGNED_INT((float)v10) ^ LC11) / 200.0;
*(float *)&v25 = COERCE_FLOAT(COERCE_UNSIGNED_INT((float)v9) ^ LC11) / 200.0;
kl_camera_local_rotate(v32, &v25);
v11 = *(float *)&LC0;
if ( !v3 )
v11 = 0.0;
if ( v4 )
v11 = v11 - 1.0;
v12 = *(float *)&LC0;
*(float *)v27 = v11;
v27[1] = 0;
if ( !v5 )
v12 = 0.0;
if ( v14 )
v12 = v12 - 1.0;
*(float *)&v27[2] = v12;
func0((float *)v27, v11, 0.0, v12, v15 * 320.0);
kl_camera_local_move(v32, v27);
kl_render_draw(v32);
kl_vid_swap();
}
while ( v28[0] != 1 )
{
if ( v28[0] != 2 )
goto LABEL_6;
v10 += v30;
v9 += v31;
if ( !(unsigned __int8)kl_input_poll(v28) )
goto LABEL_10;
}
switch ( v28[1] )
{
case 1:
if ( !v29 )
goto LABEL_6;
result = 0;
break;
case 0x21:
kl_render_set_debug(0LL);
goto LABEL_6;
case 0x22:
kl_render_set_debug(1LL);
goto LABEL_6;
case 0x23:
kl_render_set_debug(2LL);
goto LABEL_6;
case 0x24:
kl_render_set_debug(3LL);
goto LABEL_6;
case 0x25:
kl_render_set_debug(4LL);
goto LABEL_6;
case 0x26:
kl_render_set_debug(5LL);
goto LABEL_6;
case 0x27:
kl_render_set_debug(6LL);
goto LABEL_6;
case 0x28:
kl_render_set_debug(7LL);
goto LABEL_6;
case 0x29:
kl_render_set_debug(8LL);
goto LABEL_6;
case 0x30:
v4 = v29;
goto LABEL_6;
case 0x33:
v3 = v29;
goto LABEL_6;
case 0x42:
v5 = v29;
goto LABEL_6;
case 0x46:
v14 = v29;
goto LABEL_6;
default:
goto LABEL_6;
}
return result;
}

original_code:
int main(int argc, char **argv) {
  kl_evt_generic_t evt;
  kl_resource_add_dir("./test_assets/", "");
  if (kl_vid_init() < 0) return -1;
  if (kl_input_init() < 0) return -1;
  if (kl_render_init() < 0) return -1;
  int w, h;
  kl_vid_size(&w, &h);
  kl_camera_t cam = {
    .position = { .x = 0.0f, .y = 0.0f, .z = 0.0f },
    .orientation = { .r = 1.0f, .i = 0.0f, .j = 0.0f, .k = 0.0f },
    .aspect = (float)w/(float)h,
    .fov = 1.047f,
 .viewport = { .x = 0, .y = 0, .z = w, .w = h },
    .near = 1.0f,
    .far = 10000.0f
  };
  kl_terrain_testsphere();
  kl_model_t *model1 = kl_model_load("test_assets/test.iqm");
  kl_render_add_model(model1);
  kl_model_t *model2 = kl_model_load("test_assets/sponza.obj");
  kl_render_add_model(model2);
  kl_model_t *model3 = kl_model_load("test_assets/colorcalibration.obj");
  kl_render_add_model(model3);
  kl_vec3f_t light1_pos = { .x = 500.0f, .y = 400.0f, .z = 0.0f };
  kl_render_add_light(&light1_pos, 1.0f, 0.8f, 0.6f, 25000.0f);
  kl_vec3f_t light2_pos = { .x = -500.0f, .y = 400.0f, .z = 0.0f };
  kl_render_add_light(&light2_pos, 1.0f, 0.8f, 0.6f, 25000.0f);
  kl_vec3f_t light3_pos = { .x = 0.0f, .y = 300.0f, .z = 0.0f };
  kl_vec3f_t envlight_dir = { -2.0f, -2.0f, 1.0f };
  kl_render_set_envlight(&envlight_dir, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, 0.9f, 0.6f, 0.0f);
  kl_timer_t timer = { .time = -1.0f, .dt = 0.0f};
  _Bool move_f = 0;
  _Bool move_b = 0;
  _Bool move_l = 0;
  _Bool move_r = 0;
  kl_vec3f_t mouseangle = { .x = 0.0f, .y = 0.0f, .z = 0.0f };
  for (;;) {
    float dt = kl_timer_tick(&timer);
    kl_input_tick();
    int dx = 0; int dy = 0;
    while (kl_input_poll(&evt)) {
      switch (evt.event.type) {
        case 0x01:
          switch (evt.button.code) {
            case 0x01:
              if (evt.button.isdown) return 0;
              break;
            case 0x46:
              move_f = evt.button.isdown;
              break;
            case 0x30:
              move_l = evt.button.isdown;
              break;
            case 0x42:
              move_b = evt.button.isdown;
              break;
            case 0x33:
              move_r = evt.button.isdown;
              break;
            case 0x21:
              kl_render_set_debug(0);
              break;
            case 0x22:
              kl_render_set_debug(1);
              break;
            case 0x23:
              kl_render_set_debug(2);
              break;
            case 0x24:
              kl_render_set_debug(3);
              break;
            case 0x25:
              kl_render_set_debug(4);
              break;
            case 0x26:
              kl_render_set_debug(5);
              break;
            case 0x27:
              kl_render_set_debug(6);
              break;
            case 0x28:
              kl_render_set_debug(7);
              break;
            case 0x29:
              kl_render_set_debug(8);
              break;
          }
          break;
        case 0x02:
          dx += evt.mouse.dx;
          dy += evt.mouse.dy;
      }
    }
    mouseangle.y = -(float)dx/200.0f;
    mouseangle.x = -(float)dy/200.0f;
    kl_camera_local_rotate(&cam, &mouseangle);
    kl_vec3f_t offset = {
      .x = (move_r ? 1.0f : 0.0f) - (move_l ? 1.0f : 0.0f),
      .y = 0.0f,
      .z = (move_b ? 1.0f : 0.0f) - (move_f ? 1.0f : 0.0f)
    };
    kl_vec3f_scale(&offset, &offset, 320.0f * dt);
    kl_camera_local_move(&cam, &offset);
    kl_render_draw(&cam);
    kl_vid_swap();
  }
}

canonical_original_code:
int main(int argc, char **argv) {
  union kl_evt_generic evt;
  kl_resource_add_dir("./test_assets/", "");
  if (kl_vid_init() < 0) return -1;
  if (kl_input_init() < 0) return -1;
  if (kl_render_init() < 0) return -1;
  int w; int h;
  kl_vid_size(&w, &h);
  struct kl_camera cam = {
    .position = { .x = 0.0f, .y = 0.0f, .z = 0.0f },
    .orientation = { .r = 1.0f, .i = 0.0f, .j = 0.0f, .k = 0.0f },
    .aspect = (float)w/(float)h,
    .fov = 1.047f,
 .viewport = { .x = 0, .y = 0, .z = w, .w = h },
    .near = 1.0f,
    .far = 10000.0f
  };
  kl_terrain_testsphere();
  struct kl_model *model1 = kl_model_load("test_assets/test.iqm");
  kl_render_add_model(model1);
  struct kl_model *model2 = kl_model_load("test_assets/sponza.obj");
  kl_render_add_model(model2);
  struct kl_model *model3 = kl_model_load("test_assets/colorcalibration.obj");
  kl_render_add_model(model3);
  struct kl_vec3f light1_pos = { .x = 500.0f, .y = 400.0f, .z = 0.0f };
  kl_render_add_light(&light1_pos, 1.0f, 0.8f, 0.6f, 25000.0f);
  struct kl_vec3f light2_pos = { .x = -500.0f, .y = 400.0f, .z = 0.0f };
  kl_render_add_light(&light2_pos, 1.0f, 0.8f, 0.6f, 25000.0f);
  struct kl_vec3f light3_pos = { .x = 0.0f, .y = 300.0f, .z = 0.0f };
  struct kl_vec3f envlight_dir = { -2.0f, -2.0f, 1.0f };
  kl_render_set_envlight(&envlight_dir, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, 0.9f, 0.6f, 0.0f);
  struct kl_timer timer = { .time = -1.0f, .dt = 0.0f};
  _Bool move_f = 0;
  _Bool move_b = 0;
  _Bool move_l = 0;
  _Bool move_r = 0;
  struct kl_vec3f mouseangle = { .x = 0.0f, .y = 0.0f, .z = 0.0f };
  for (;;) {
    float dt = kl_timer_tick(&timer);
    kl_input_tick();
    int dx = 0; int dy = 0;
    while (kl_input_poll(&evt)) {
      switch (evt.event.type) {
        case 0x01:
          switch (evt.button.code) {
            case 0x01:
              if (evt.button.isdown) return 0;
              break;
            case 0x46:
              move_f = evt.button.isdown;
              break;
            case 0x30:
              move_l = evt.button.isdown;
              break;
            case 0x42:
              move_b = evt.button.isdown;
              break;
            case 0x33:
              move_r = evt.button.isdown;
              break;
            case 0x21:
              kl_render_set_debug(0);
              break;
            case 0x22:
              kl_render_set_debug(1);
              break;
            case 0x23:
              kl_render_set_debug(2);
              break;
            case 0x24:
              kl_render_set_debug(3);
              break;
            case 0x25:
              kl_render_set_debug(4);
              break;
            case 0x26:
              kl_render_set_debug(5);
              break;
            case 0x27:
              kl_render_set_debug(6);
              break;
            case 0x28:
              kl_render_set_debug(7);
              break;
            case 0x29:
              kl_render_set_debug(8);
              break;
          }
          break;
        case 0x02:
          dx += evt.mouse.dx;
          dy += evt.mouse.dy;
      }
    }
    mouseangle.y = -(float)dx/200.0f;
    mouseangle.x = -(float)dy/200.0f;
    kl_camera_local_rotate(&cam, &mouseangle);
    struct kl_vec3f offset = {
      .x = (move_r ? 1.0f : 0.0f) - (move_l ? 1.0f : 0.0f),
      .y = 0.0f,
      .z = (move_b ? 1.0f : 0.0f) - (move_f ? 1.0f : 0.0f)
    };
    kl_vec3f_scale(&offset, &offset, 320.0f * dt);
    kl_camera_local_move(&cam, &offset);
    kl_render_draw(&cam);
    kl_vid_swap();
  }
}

variable_types: argc int

variable_types:
argv
char **

variable_types: union kl_evt_generic { struct kl_evt { int type; } event; struct kl_evt_button { struct kl_evt evt; int code; _Bool isdown; } button; struct kl_evt_mouse { struct kl_evt evt; int x; int y; int dx; int dy; } mouse; }

variable_types: w int

variable_types: h int

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_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:
timer
struct kl_timer { float time; }

variable_types:
mouseangle
struct kl_vec3f { float x; }

variable_types: dt float

variable_types: dx int

variable_types: dy int

variable_types:
offset
struct kl_vec3f { float x; }

return_type: int

user_defined_types: union kl_evt_generic { struct kl_evt event; struct kl_evt_button button; struct kl_evt_mouse mouse; }

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: 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: 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_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; }


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

result = realloc(*(void **)a1, a2 * *(_DWORD *)(a1 + 12));
*(_DWORD *)(a1 + 8) = a2;
*(_QWORD *)a1 = result;
return result;
}

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

result = realloc(*(void **)a1, a2 * *(_DWORD *)(a1 + 12));
*(_DWORD *)(a1 + 8) = a2;
*(_QWORD *)a1 = result;
return result;
}

original_code:
static void array_resize(kl_array_t *array, int size) {
  array->data = realloc(array->data, size * array->item_size);
  array->size = size;
}

canonical_original_code:
static void array_resize(struct kl_array *array, int size) {
  array->data = realloc(array->data, size * array->item_size);
  array->size = size;
}

variable_types: size int


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

canonical_decompiled_code:
void *__fastcall func1(__int64 a1)
{
return func0(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);
}


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

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

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: minsize int

variable_types:
clearbyte
unsigned char

variable_types: oldsize int


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

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

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

result = malloc(a2 << 8);
*(_DWORD *)(a1 + 12) = a2;
*(_QWORD *)a1 = result;
*(_DWORD *)(a1 + 8) = 256;
*(_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;
}

variable_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));
*(_DWORD *)(a1 + 8) = 256;
*(_QWORD *)a1 = result;
*(_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));
*(_DWORD *)(a1 + 8) = 256;
*(_QWORD *)a1 = result;
*(_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;
}


decompiled_code:
void __fastcall kl_array_free(__int64 a1)
{
free(*(void **)a1);
*(_QWORD *)(a1 + 8) = 0LL;
*(_DWORD *)(a1 + 16) = 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) )
{
func1(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


decompiled_code:
void *__fastcall kl_array_set_expand(__int64 a1, int a2, const void *a3, unsigned __int8 a4)
{
int v5; // edx

v5 = *(_DWORD *)(a1 + 16);
if ( v5 > a2 )
return kl_array_set_isra_0(*(_QWORD *)a1, *(_DWORD *)(a1 + 12), v5, a2, a3);
array_growto(a1, a2 + 1, a4);
*(_DWORD *)(a1 + 16) = a2 + 1;
return kl_array_set_isra_0(*(_QWORD *)a1, *(_DWORD *)(a1 + 12), a2 + 1, 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);
}


alwaystrue

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

canonical_decompiled_code:
__int64 func0()
{
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;
}

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


checkfrustum

decompiled_code:
__int64 __fastcall checkfrustum(float *a1, float *a2)
{
unsigned int v2; // er13
float v3; // xmm0_4
float v5; // [rsp+0h] [rbp-28h]
float v6; // [rsp+4h] [rbp-24h]
float v7; // [rsp+8h] [rbp-20h]
float v8; // [rsp+Ch] [rbp-1Ch]

v2 = 0;
v5 = a1[2];
v6 = a1[1];
v7 = *a1;
v3 = kl_plane_dist_isra_0(a2, *a1, v6, v5);
v8 = a1[3];
if ( v3 <= v8
&& kl_plane_dist_isra_0(a2 + 4, v7, v6, v5) <= v8
&& kl_plane_dist_isra_0(a2 + 8, v7, v6, v5) <= v8
&& kl_plane_dist_isra_0(a2 + 12, v7, v6, v5) <= v8
&& kl_plane_dist_isra_0(a2 + 16, v7, v6, v5) <= v8 )
{
v2 = 0;
LOBYTE(v2) = kl_plane_dist_isra_0(a2 + 20, v7, v6, v5) <= v8;
}
return v2;
}

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_frustum { struct kl_plane { struct kl_vec3f norm; float dist; } near; struct kl_plane top; } *

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


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(v2, 8LL);
kl_bvh_search(bvh_models, checkfrustum, &frustum_1, v2);
kl_gl3_pass_gbuffer(v2);
kl_gl3_pass_envlight();
kl_array_init(v3, 8LL);
kl_bvh_search(bvh_lights, checkfrustum, &frustum_1, v3);
kl_gl3_pass_pointlight(v3);
kl_array_free(v3);
kl_timer_tick(&timer_0);
kl_gl3_composite();
kl_array_free(v2);
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(v2, 8LL);
kl_bvh_search(bvh_models, checkfrustum, &frustum_1, v2);
kl_gl3_pass_gbuffer(v2);
kl_gl3_pass_envlight();
kl_array_init(v3, 8LL);
kl_bvh_search(bvh_lights, checkfrustum, &frustum_1, v3);
kl_gl3_pass_pointlight(v3);
kl_array_free(v3);
kl_timer_tick(&timer_0);
kl_gl3_composite();
kl_array_free(v2);
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; }

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: 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_light { struct kl_vec3f position; float scale; unsigned int id; }

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_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; } *


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:
void __fastcall kl_quat_magnitude(float *a1)
{
float v1; // xmm0_4

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

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 a3)
{
float v3; // xmm2_4
float v4; // xmm1_4
float v5; // xmm3_4

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

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; // xmm0_4
float v3; // xmm0_4
float v4; // xmm2_4
float v5; // xmm1_4
float v6; // xmm0_4
float cosx; // [rsp+8h] [rbp-28h] BYREF
float sinx[2]; // [rsp+Ch] [rbp-24h] BYREF
int v9[7]; // [rsp+14h] [rbp-1Ch] BYREF

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

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

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

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
  };
}


decompiled_code:
__int64 __fastcall kl_quat_rotate(__int64 a1, float *a2, __int64 a3)
{
int v3; // xmm0_4
__int64 result; // rax
int v5; // xmm0_4
float v6[4]; // [rsp+0h] [rbp-50h] BYREF
float v7[4]; // [rsp+10h] [rbp-40h] BYREF
float v8; // [rsp+20h] [rbp-30h] BYREF
__int64 v9; // [rsp+24h] [rbp-2Ch]
int v10; // [rsp+2Ch] [rbp-24h]
int v11; // [rsp+30h] [rbp-20h] BYREF
__int64 v12; // [rsp+34h] [rbp-1Ch]
int v13; // [rsp+3Ch] [rbp-14h]

v3 = *(_DWORD *)(a3 + 8);
v12 = *(_QWORD *)a3;
v13 = v3;
v11 = 0;
kl_quat_conj(v6, a2);
kl_quat_mul(v7, (float *)&v11, v6);
kl_quat_mul(&v8, a2, v7);
result = v9;
v5 = v10;
*(_QWORD *)a1 = v9;
*(_DWORD *)(a1 + 8) = v5;
return result;
}

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; // er12
unsigned int v3; // ebx
size_t v4; // r15
void *v5; // rax
void *v6; // r13
__int64 v7; // rbx
int *v9; // rax
char *v10; // rax
int *v11; // rax
char *v12; // rax
int *v13; // rax
char *v14; // 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 )
{
v13 = _errno_location();
v7 = 0LL;
v14 = strerror(*v13);
fprintf(stderr, "Model: Failed to open %s!\n\tDetails: %s\n", a1, v14);
return v7;
}
if ( fstat(v1, &buf) < 0 )
{
v15 = _errno_location();
v7 = 0LL;
v16 = strerror(*v15);
fprintf(stderr, "Model: Failed to get info for %s!\n\tDetails: %s\n", a1, v16);
return v7;
}
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 )
{
v17 = _errno_location();
v7 = 0LL;
v18 = strerror(*v17);
fprintf(stderr, "Model: Failed to memory-map %s!\n\tDetails: %s\n", a1, v18);
return v7;
}
if ( (unsigned __int8)kl_model_isiqm2(v5, v3) )
{
v7 = kl_model_loadiqm2(v6, v3);
}
else
{
if ( !(unsigned __int8)kl_model_isobj(v6, v3) )
goto LABEL_6;
v7 = kl_model_loadobj(v6, v3);
}
if ( !v7 )
{
LABEL_6:
v7 = 0LL;
fprintf(stderr, "Model: Failed to load %s!\n", a1);
if ( munmap(v6, v4) >= 0 )
goto LABEL_7;
LABEL_12:
v9 = _errno_location();
v10 = strerror(*v9);
fprintf(stderr, "Model: Failed to unmap %s!\n\tDetails: %s\n", a1, v10);
if ( close(v2) >= 0 )
return v7;
LABEL_13:
v11 = _errno_location();
v12 = strerror(*v11);
fprintf(stderr, "Model: Failed to close %s!\n\tDetails: %s\n", a1, v12);
return v7;
}
if ( munmap(v6, v4) < 0 )
goto LABEL_12;
LABEL_7:
if ( close(v2) < 0 )
goto LABEL_13;
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1)
{
int v1; // eax
int v2; // er12
unsigned int v3; // ebx
size_t v4; // r15
void *v5; // rax
void *v6; // r13
__int64 v7; // rbx
int *v9; // rax
char *v10; // rax
int *v11; // rax
char *v12; // rax
int *v13; // rax
char *v14; // 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 )
{
v13 = _errno_location();
v7 = 0LL;
v14 = strerror(*v13);
fprintf(stderr, "Model: Failed to open %s!\n\tDetails: %s\n", a1, v14);
return v7;
}
if ( fstat(v1, &buf) < 0 )
{
v15 = _errno_location();
v7 = 0LL;
v16 = strerror(*v15);
fprintf(stderr, "Model: Failed to get info for %s!\n\tDetails: %s\n", a1, v16);
return v7;
}
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 )
{
v17 = _errno_location();
v7 = 0LL;
v18 = strerror(*v17);
fprintf(stderr, "Model: Failed to memory-map %s!\n\tDetails: %s\n", a1, v18);
return v7;
}
if ( (unsigned __int8)kl_model_isiqm2(v5, v3) )
{
v7 = kl_model_loadiqm2(v6, v3);
}
else
{
if ( !(unsigned __int8)kl_model_isobj(v6, v3) )
goto LABEL_6;
v7 = kl_model_loadobj(v6, v3);
}
if ( !v7 )
{
LABEL_6:
v7 = 0LL;
fprintf(stderr, "Model: Failed to load %s!\n", a1);
if ( munmap(v6, v4) >= 0 )
goto LABEL_7;
LABEL_12:
v9 = _errno_location();
v10 = strerror(*v9);
fprintf(stderr, "Model: Failed to unmap %s!\n\tDetails: %s\n", a1, v10);
if ( close(v2) >= 0 )
return v7;
LABEL_13:
v11 = _errno_location();
v12 = strerror(*v11);
fprintf(stderr, "Model: Failed to close %s!\n\tDetails: %s\n", a1, v12);
return v7;
}
if ( munmap(v6, v4) < 0 )
goto LABEL_12;
LABEL_7:
if ( close(v2) < 0 )
goto LABEL_13;
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[]; } *

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: union kl_model_bufs { struct kl_model_bufs_prop prop; struct kl_model_bufs_actor actor; struct kl_model_bufs_terrain terrain; }


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


decompiled_code:
__int64 __fastcall kl_mat4f_frustum(__int64 a1, float a2, float a3, float a4, float a5, float a6, float a7)
{
__int64 result; // rax

result = 3212836864LL;
*(_QWORD *)(a1 + 44) = 3212836864LL;
*(_QWORD *)(a1 + 4) = 0LL;
*(_QWORD *)(a1 + 12) = 0LL;
*(_QWORD *)(a1 + 24) = 0LL;
*(_DWORD *)(a1 + 52) = 0;
*(_DWORD *)(a1 + 60) = 0;
*(float *)(a1 + 32) = (float)(a3 + a2) / (float)(a3 - a2);
*(float *)a1 = (float)(a6 + a6) / (float)(a3 - a2);
*(float *)(a1 + 20) = (float)(a6 + a6) / (float)(a5 - a4);
*(float *)(a1 + 36) = (float)(a5 + a4) / (float)(a5 - a4);
*(float *)(a1 + 40) = COERCE_FLOAT(COERCE_UNSIGNED_INT(a6 + a7) ^ LC3) / (float)(a7 - a6);
*(float *)(a1 + 56) = COERCE_FLOAT(COERCE_UNSIGNED_INT((float)(a7 + a7) * a6) ^ LC3) / (float)(a7 - a6);
return result;
}

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_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: 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
{
++v1;
result = printf("[ %6.3f, %6.3f, %6.3f, %6.3f ]\n", *(v1 - 1), v1[3], v1[7], v1[11]);
}
while ( a1 + 4 != v1 );
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)
{
__int64 v1; // rax
char *v2; // rdi
__int64 v3; // r8

v1 = *a1;
if ( !(_BYTE)v1 )
return 0LL;
v2 = a1 + 1;
v3 = 0LL;
do
{
++v2;
v3 = __ROL8__(v3 ^ v1, 11);
v1 = *(v2 - 1);
}
while ( (_BYTE)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
__int64 v4; // rax

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);
v4 = resource_cache[v2 & 0xFFF];
*((_QWORD *)v3 + 64) = v2;
*((_DWORD *)v3 + 130) = 0;
*((_QWORD *)v3 + 66) = 0LL;
*((_QWORD *)v3 + 67) = 0LL;
resource_cache[v2 & 0xFFF] = (__int64)v3;
*((_QWORD *)v3 + 68) = v4;
return 0LL;
}

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

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


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
bool v2; // zf

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

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
__int64 result; // rax
bool v2; // zf

result = resource_cache[a1 & 0xFFF];
if ( result )
{
while ( *(_QWORD *)(result + 512) != a1 )
{
result = *(_QWORD *)(result + 544);
if ( !result )
return result;
}
v2 = *(_DWORD *)(result + 520) == 1;
if ( --*(_DWORD *)(result + 520) < 0 )
_assert_fail("curr->refs >= 0", "resource.c", 0xCBu, "kl_resource_decref");
if ( v2 )
{
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:
const char *__fastcall kl_resource_strip_extension(const char *a1)
{
const char *result; // rax
unsigned int v2; // ecx
__int64 v3; // rsi
const char *v4; // rsi
char v5; // dl

result = (const char *)strlen(a1);
v2 = (_DWORD)result - 1;
if ( (int)result - 1 >= 0 )
{
v3 = (__int64)&a1[(int)result - 2];
result = &a1[v2];
v4 = (const char *)(v3 - v2);
do
{
v5 = *result;
if ( (*result & 0xDF) == 92 || v5 == 47 )
break;
if ( v5 == 46 )
{
*result = 0;
return result;
}
--result;
}
while ( result != v4 );
}
return result;
}

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

result = (const char *)strlen(a1);
v2 = (_DWORD)result - 1;
if ( (int)result - 1 >= 0 )
{
v3 = (__int64)&a1[(int)result - 2];
result = &a1[v2];
v4 = (const char *)(v3 - v2);
do
{
v5 = *result;
if ( (*result & 0xDF) == 92 || v5 == 47 )
break;
if ( v5 == 46 )
{
*result = 0;
return result;
}
--result;
}
while ( result != v4 );
}
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 func0(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; } *

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; }


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

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");
v3 = *((_QWORD *)dest + 32) == 0LL;
*((_QWORD *)dest + 35) = result;
if ( v3 )
_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 func1(char *src, char *dest)
{
__int64 result; // rax
bool v3; // zf

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");
v3 = *((_QWORD *)dest + 32) == 0LL;
*((_QWORD *)dest + 35) = result;
if ( v3 )
_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:
char *__fastcall material_load_raw(char *src, char *dest)
{
__int64 v2; // r13
__int64 v3; // r15
__int64 v4; // r14
__int64 v5; // rax
__int64 v6; // rcx
char *result; // rax
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11; // [rsp+8h] [rbp-138h]
__int64 v12; // [rsp+8h] [rbp-138h]
__int64 v13; // [rsp+8h] [rbp-138h]
__int64 v14; // [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);
v5 = kl_texture_incref(s);
v6 = v5;
if ( v2 )
{
if ( v3 )
goto LABEL_3;
}
else
{
v12 = v5;
v8 = kl_texture_incref("DEFAULT_DIFFUSE");
v6 = v12;
v2 = v8;
if ( v3 )
{
LABEL_3:
if ( v4 )
goto LABEL_4;
LABEL_12:
v14 = v6;
v10 = kl_texture_incref("DEFAULT_SPECULAR");
v6 = v14;
v4 = v10;
if ( v14 )
goto LABEL_5;
goto LABEL_13;
}
}
v13 = v6;
v9 = kl_texture_incref("DEFAULT_NORMAL");
v6 = v13;
v3 = v9;
if ( !v4 )
goto LABEL_12;
LABEL_4:
if ( v6 )
goto LABEL_5;
LABEL_13:
v6 = kl_texture_incref("DEFAULT_EMISSIVE");
LABEL_5:
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");
v11 = v6;
result = strncpy(dest, src, 0x100uLL);
*((_QWORD *)dest + 32) = v2;
*((_QWORD *)dest + 33) = v3;
*((_QWORD *)dest + 34) = v4;
*((_QWORD *)dest + 35) = v11;
return result;
}

canonical_decompiled_code:
char *__fastcall func2(char *src, char *dest)
{
__int64 v2; // r13
__int64 v3; // r15
__int64 v4; // r14
__int64 v5; // rax
__int64 v6; // rcx
char *result; // rax
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11; // [rsp+8h] [rbp-138h]
__int64 v12; // [rsp+8h] [rbp-138h]
__int64 v13; // [rsp+8h] [rbp-138h]
__int64 v14; // [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);
v5 = kl_texture_incref(s);
v6 = v5;
if ( v2 )
{
if ( v3 )
goto LABEL_3;
}
else
{
v12 = v5;
v8 = kl_texture_incref("DEFAULT_DIFFUSE");
v6 = v12;
v2 = v8;
if ( v3 )
{
LABEL_3:
if ( v4 )
goto LABEL_4;
LABEL_12:
v14 = v6;
v10 = kl_texture_incref("DEFAULT_SPECULAR");
v6 = v14;
v4 = v10;
if ( v14 )
goto LABEL_5;
goto LABEL_13;
}
}
v13 = v6;
v9 = kl_texture_incref("DEFAULT_NORMAL");
v6 = v13;
v3 = v9;
if ( !v4 )
goto LABEL_12;
LABEL_4:
if ( v6 )
goto LABEL_5;
LABEL_13:
v6 = kl_texture_incref("DEFAULT_EMISSIVE");
LABEL_5:
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");
v11 = v6;
result = strncpy(dest, src, 0x100uLL);
*((_QWORD *)dest + 32) = v2;
*((_QWORD *)dest + 33) = v3;
*((_QWORD *)dest + 34) = v4;
*((_QWORD *)dest + 35) = v11;
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; // rax
char *v3; // r13
__int64 v4; // r14
char *result; // rax
char *v6; // [rsp+0h] [rbp-30h] BYREF
__int64 v7[5]; // [rsp+8h] [rbp-28h] BYREF

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

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

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

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
char *v3; // [rsp+0h] [rbp-20h] BYREF
__int64 v4; // [rsp+8h] [rbp-18h] BYREF

if ( !loader )
{
loader = kl_resource_loader_new(material_load, material_free);
kl_resource_add_entry(&unk_A49, "DEFAULT_MATERIAL");
}
strncpy(buf_4, src, 0xFFuLL);
byte_91F = 0;
if ( (unsigned __int8)path_split_constprop_0(buf_4, &v3, &v4) )
mtl_entries = kl_material_mtl_incref(v3);
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
char *v3; // [rsp+0h] [rbp-20h] BYREF
__int64 v4; // [rsp+8h] [rbp-18h] BYREF

if ( !loader )
{
loader = kl_resource_loader_new(material_load, material_free);
kl_resource_add_entry(&unk_A49, "DEFAULT_MATERIAL");
}
strncpy(buf_4, src, 0xFFuLL);
byte_91F = 0;
if ( (unsigned __int8)func3(buf_4, &v3, &v4) )
mtl_entries = kl_material_mtl_incref(v3);
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
char *v3; // [rsp+0h] [rbp-20h] BYREF
__int64 v4; // [rsp+8h] [rbp-18h] BYREF

strncpy(buf_0, src, 0xFFuLL);
byte_71F = 0;
if ( (unsigned __int8)path_split_constprop_0(buf_0, &v3, &v4) )
kl_material_mtl_decref(v3);
v1 = kl_resource_getid(src);
return kl_resource_decref(v1);
}

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

strncpy(buf_0, src, 0xFFuLL);
byte_71F = 0;
if ( (unsigned __int8)func3(buf_0, &v3, &v4) )
kl_material_mtl_decref(v3);
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

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)
{
int v2; // ebx
__int64 result; // rax
unsigned int v4; // er13
__int64 v5[5]; // [rsp+8h] [rbp-28h] BYREF

v2 = 0;
result = a1;
if ( a2 )
{
while ( 1 )
{
v4 = *(_DWORD *)(a1 + 104);
if ( (int)kl_array_size_isra_0(v4) <= v2 )
break;
kl_array_get_isra_0(*(_QWORD *)(a1 + 88), *(_DWORD *)(a1 + 100), v4, v2, v5);
result = v5[0];
if ( *(_DWORD *)(v5[0] + 8) == a2 )
return result;
++v2;
}
result = 0LL;
}
return result;
}

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

v2 = 0;
result = a1;
if ( a2 )
{
while ( 1 )
{
v4 = *(_DWORD *)(a1 + 104);
if ( (int)func6(v4) <= v2 )
break;
func7(*(_QWORD *)(a1 + 88), *(_DWORD *)(a1 + 100), v4, v2, v5);
result = v5[0];
if ( *(_DWORD *)(v5[0] + 8) == a2 )
return result;
++v2;
}
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; }