decompiled_code:
void __fastcall game_free(void *ptr)
{
__int64 v1; // rax

if ( ptr )
{
ogl_free_texture(*((_QWORD *)ptr + 6));
v1 = *((_QWORD *)ptr + 2);
*(_QWORD *)(*((_QWORD *)ptr + 3) + 16LL) = v1;
*(_QWORD *)(v1 + 24) = *((_QWORD *)ptr + 3);
game_start = (void *)*((_QWORD *)ptr + 2);
if ( game_start == *((void **)game_start + 2) )
game_start = 0LL;
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func2(void *ptr)
{
__int64 v1; // rax

if ( ptr )
{
ogl_free_texture(*((_QWORD *)ptr + 6));
v1 = *((_QWORD *)ptr + 2);
*(_QWORD *)(*((_QWORD *)ptr + 3) + 16LL) = v1;
*(_QWORD *)(v1 + 24) = *((_QWORD *)ptr + 3);
game_start = (void *)*((_QWORD *)ptr + 2);
if ( game_start == *((void **)game_start + 2) )
game_start = 0LL;
free(ptr);
}
}

original_code:
void game_free( struct game* game ) {
 if( game ) {
  ogl_free_texture( game->texture );
  game->all_prev->all_next = game->all_next;
  game->all_next->all_prev = game->all_prev;
  game_start = game->all_next;
  if( game_start->all_next == game_start ) {
   game_start = ((void *)0);
  }
  free( game );
  game = ((void *)0);
 }
}

canonical_original_code:
void game_free(struct game *game) {
 if( game ) {
  ogl_free_texture( game->texture );
  game->all_prev->all_next = game->all_next;
  game->all_next->all_prev = game->all_prev;
  game_start = game->all_next;
  if( game_start->all_next == game_start ) {
   game_start = ((void *)0);
  }
  free( game );
  game = ((void *)0);
 }
}

user_defined_types: struct game_category { struct game_category *next; char *name; char *value; }

user_defined_types: struct config_param { struct config_param *next; char name[64]; char value[64]; }

user_defined_types: struct game_media { struct game_media *next; int type; char *subtype; char file_name[256]; }

user_defined_types: struct texture { unsigned int id; int width; int height; }


repo: tuxme/tuxbrio

decompiled_code:
void game_list_free()
{
void *i; // rdi

for ( i = game_start; game_start; i = game_start )
game_free(i);
}

canonical_decompiled_code:
void func3()
{
void *i; // rdi

for ( i = game_start; game_start; i = game_start )
func2(i);
}

original_code:
void game_list_free( void ) {
 while( game_start )
  game_free( game_start );
}

canonical_original_code:
void game_list_free() {
 while( game_start )
  game_free( game_start );
}

return_type: void


decompiled_code:
__int64 __fastcall game_free_texture(__int64 a1)
{
__int64 v2; // rdi
__int64 result; // rax

v2 = *(_QWORD *)(a1 + 48);
if ( v2 )
{
result = ogl_free_texture(v2);
*(_QWORD *)(a1 + 48) = 0LL;
}
return result;
}

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

v2 = *(_QWORD *)(a1 + 48);
if ( v2 )
{
result = ogl_free_texture(v2);
*(_QWORD *)(a1 + 48) = 0LL;
}
return result;
}

original_code:
void game_free_texture( struct game *game ) {
 if( game->texture ) {
  ogl_free_texture( game->texture );
  game->texture = ((void *)0);
 }
}

canonical_original_code:
void game_free_texture(struct game *game) {
 if( game->texture ) {
  ogl_free_texture( game->texture );
  game->texture = ((void *)0);
 }
}

variable_types: struct game { struct game *next; struct game *prev; struct game *all_next; struct game *all_prev; struct platform { struct platform *next; struct platform *prev; char *name; char image_file[256]; struct texture { unsigned int id; int width; int height; } *texture; } *platform; struct game_category { struct game_category *next; char *name; char *value; } *categories; struct texture *texture; struct config_param { struct config_param *next; char name[64]; char value[64]; } *params; struct game_media { struct game_media *next; int type; char *subtype; char file_name[256]; } *media; struct config_emulator { struct config_emulator *next; int id; char name[128]; char display_name[128]; char executable[256]; char directory[256]; int is_default; struct config_param *params; struct config_platform { struct config_platform *next; char name[128]; } *platform; } *emulator; char *name; char *rom_path; } *

user_defined_types: struct game { struct game *next; struct game *prev; struct game *all_next; struct game *all_prev; struct platform *platform; struct game_category *categories; struct texture *texture; struct config_param *params; struct game_media *media; struct config_emulator *emulator; char *name; char *rom_path; }

user_defined_types: struct platform { struct platform *next; struct platform *prev; char *name; char image_file[256]; struct texture *texture; }

user_defined_types: struct config_emulator { struct config_emulator *next; int id; char name[128]; char display_name[128]; char executable[256]; char directory[256]; int is_default; struct config_param *params; struct config_platform *platform; }


decompiled_code:
__int64 __fastcall game_load_texture(__int64 a1)
{
__int64 *v2; // rax
__int64 *v3; // rbp
__int64 v4; // rax
int v5; // ecx
int v6; // edx
unsigned int v7; // esi
_BYTE *v9; // rdi

v2 = game_media_get(a1, 0, (const char *)game_image_type);
v3 = v2;
if ( *(_QWORD *)(a1 + 48) )
{
game_free_texture(a1);
if ( !v3 )
goto LABEL_3;
goto LABEL_8;
}
if ( v2 )
{
LABEL_8:
*(_QWORD *)(a1 + 48) = sdl_create_texture(v3);
LABEL_3:
v4 = *(_QWORD *)(a1 + 48);
if ( v4 )
goto LABEL_4;
}
v9 = *(_BYTE **)(a1 + 80);
if ( v9 && *v9 )
*(_QWORD *)(a1 + 48) = ((__int64 (*)(void))font_create_texture)();
else
*(_QWORD *)(a1 + 48) = font_create_texture("<No Name>");
v4 = *(_QWORD *)(a1 + 48);
if ( !v4 )
return (unsigned int)-1;
LABEL_4:
v5 = *(_DWORD *)(v4 + 4);
v6 = *(_DWORD *)(v4 + 8);
if ( v5 <= v6 )
{
v7 = 0;
if ( v6 > 280 )
{
*(_DWORD *)(v4 + 4) = (int)(float)((float)(int)(float)v5 / (float)((float)v6 / 280.0));
*(_DWORD *)(*(_QWORD *)(a1 + 48) + 8LL) = 280;
}
}
else
{
v7 = 0;
if ( v5 > 360 )
{
*(_DWORD *)(v4 + 8) = (int)(float)((float)(int)(float)v6 / (float)((float)v5 / 360.0));
*(_DWORD *)(*(_QWORD *)(a1 + 48) + 4LL) = 360;
}
}
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 *v2; // rax
__int64 *v3; // rbp
__int64 v4; // rax
int v5; // ecx
int v6; // edx
unsigned int v7; // esi
_BYTE *v9; // rdi

v2 = game_media_get(a1, 0, (const char *)game_image_type);
v3 = v2;
if ( *(_QWORD *)(a1 + 48) )
{
func4(a1);
if ( !v3 )
goto LABEL_3;
goto LABEL_8;
}
if ( v2 )
{
LABEL_8:
*(_QWORD *)(a1 + 48) = sdl_create_texture(v3);
LABEL_3:
v4 = *(_QWORD *)(a1 + 48);
if ( v4 )
goto LABEL_4;
}
v9 = *(_BYTE **)(a1 + 80);
if ( v9 && *v9 )
*(_QWORD *)(a1 + 48) = ((__int64 (*)(void))font_create_texture)();
else
*(_QWORD *)(a1 + 48) = font_create_texture("<No Name>");
v4 = *(_QWORD *)(a1 + 48);
if ( !v4 )
return (unsigned int)-1;
LABEL_4:
v5 = *(_DWORD *)(v4 + 4);
v6 = *(_DWORD *)(v4 + 8);
if ( v5 <= v6 )
{
v7 = 0;
if ( v6 > 280 )
{
*(_DWORD *)(v4 + 4) = (int)(float)((float)(int)(float)v5 / (float)((float)v6 / 280.0));
*(_DWORD *)(*(_QWORD *)(a1 + 48) + 8LL) = 280;
}
}
else
{
v7 = 0;
if ( v5 > 360 )
{
*(_DWORD *)(v4 + 8) = (int)(float)((float)(int)(float)v6 / (float)((float)v5 / 360.0));
*(_DWORD *)(*(_QWORD *)(a1 + 48) + 4LL) = 360;
}
}
return v7;
}

original_code:
int game_load_texture( struct game *game ) {
 const char *filename = game_media_get( game, MEDIA_IMAGE, game_image_type );
 if( game->texture ) {
  game_free_texture( game );
 }
 if( game && filename ) {
  game->texture = sdl_create_texture( filename );
 }
 if( game->texture == ((void *)0) ) {
  if( game && game->name && *game->name ) {
   game->texture = font_create_texture( game->name );
  }
  else {
   game->texture = font_create_texture( "<No Name>" );
  }
 }
 if( game->texture == ((void *)0) ) {
  return -1;
 }
 else {
  if( game->texture->width > game->texture->height ) {
   if( game->texture->width > IMAGE_MAX_WIDTH ) {
    game->texture->height = (int)(float)game->texture->height/((float)game->texture->width/IMAGE_MAX_WIDTH);
    game->texture->width = IMAGE_MAX_WIDTH;
   }
  }
  else {
   if( game->texture->height > IMAGE_MAX_HEIGHT ) {
    game->texture->width = (int)(float)game->texture->width/((float)game->texture->height/IMAGE_MAX_HEIGHT);
    game->texture->height = IMAGE_MAX_HEIGHT;
   }
  }
 }
 return 0;
}

canonical_original_code:
int game_load_texture(struct game *game) {
 char *filename = game_media_get( game, MEDIA_IMAGE, game_image_type );
 if( game->texture ) {
  game_free_texture( game );
 }
 if( game && filename ) {
  game->texture = sdl_create_texture( filename );
 }
 if( game->texture == ((void *)0) ) {
  if( game && game->name && *game->name ) {
   game->texture = font_create_texture( game->name );
  }
  else {
   game->texture = font_create_texture( "<No Name>" );
  }
 }
 if( game->texture == ((void *)0) ) {
  return -1;
 }
 else {
  if( game->texture->width > game->texture->height ) {
   if( game->texture->width > IMAGE_MAX_WIDTH ) {
    game->texture->height = (int)(float)game->texture->height/((float)game->texture->width/IMAGE_MAX_WIDTH);
    game->texture->width = IMAGE_MAX_WIDTH;
   }
  }
  else {
   if( game->texture->height > IMAGE_MAX_HEIGHT ) {
    game->texture->width = (int)(float)game->texture->width/((float)game->texture->height/IMAGE_MAX_HEIGHT);
    game->texture->height = IMAGE_MAX_HEIGHT;
   }
  }
 }
 return 0;
}

variable_types:
filename
char *

return_type: int

user_defined_types: struct config_platform { struct config_platform *next; char name[128]; }


decompiled_code:
__int64 game_list_pause()
{
_QWORD *v0; // rbx
__int64 result; // rax

v0 = game_start;
if ( game_start )
{
do
{
result = ogl_free_texture(v0[6]);
v0[6] = 0LL;
v0 = (_QWORD *)v0[2];
}
while ( game_start != v0 );
}
return result;
}

canonical_decompiled_code:
__int64 func6()
{
_QWORD *v0; // rbx
__int64 result; // rax

v0 = game_start;
if ( game_start )
{
do
{
result = ogl_free_texture(v0[6]);
v0[6] = 0LL;
v0 = (_QWORD *)v0[2];
}
while ( game_start != v0 );
}
return result;
}

original_code:
void game_list_pause( void ) {
 struct game *g = game_start;
 if( g ) {
  do {
   ogl_free_texture( g->texture );
   g->texture = ((void *)0);
   g = g->all_next;
  } while( g != game_start );
 }
}

canonical_original_code:
void game_list_pause() {
 struct game *g = game_start;
 if( g ) {
  do {
   ogl_free_texture( g->texture );
   g->texture = ((void *)0);
   g = g->all_next;
  } while( g != game_start );
 }
}


decompiled_code:
__int64 game_list_resume()
{
_QWORD *v0; // rbx

v0 = game_start;
if ( game_start )
{
do
{
game_load_texture((__int64)v0);
v0 = (_QWORD *)v0[2];
}
while ( game_start != v0 );
}
return 0LL;
}

canonical_decompiled_code:
__int64 func7()
{
_QWORD *v0; // rbx

v0 = game_start;
if ( game_start )
{
do
{
func5((__int64)v0);
v0 = (_QWORD *)v0[2];
}
while ( game_start != v0 );
}
return 0LL;
}

original_code:
int game_list_resume( void ) {
 struct game *g = game_start;
 if( g ) {
  do {
   game_load_texture( g );
   g = g->all_next;
  } while( g != game_start );
 }
 return 0;
}

canonical_original_code:
int game_list_resume() {
 struct game *g = game_start;
 if( g ) {
  do {
   game_load_texture( g );
   g = g->all_next;
  } while( g != game_start );
 }
 return 0;
}


decompiled_code:
__int64 __fastcall game_add_category(__int64 a1, __int64 a2, __int64 a3)
{
_QWORD *v4; // rax
__int64 result; // rax

v4 = malloc(0x18uLL);
if ( v4 )
{
v4[1] = a2;
v4[2] = a3;
*v4 = *(_QWORD *)(a1 + 40);
*(_QWORD *)(a1 + 40) = v4;
result = 0LL;
}
else
{
fprintf(stderr, "Warning: Couldn't allocate category for game '%s'\n", *(const char **)(a1 + 80));
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, __int64 a2, __int64 a3)
{
_QWORD *v4; // rax
__int64 result; // rax

v4 = malloc(0x18uLL);
if ( v4 )
{
v4[1] = a2;
v4[2] = a3;
*v4 = *(_QWORD *)(a1 + 40);
*(_QWORD *)(a1 + 40) = v4;
result = 0LL;
}
else
{
fprintf(stderr, "Warning: Couldn't allocate category for game '%s'\n", *(const char **)(a1 + 80));
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int game_add_category( struct game *game, char *name, char *value ) {
 struct game_category *gc = malloc( sizeof(struct game_category) );
 if( gc ) {
  gc->name = name;
  gc->value = value;
  gc->next = game->categories;
  game->categories = gc;
 }
 else {
  fprintf( stderr, "Warning: Couldn't allocate category for game '%s'\n", game->name );
  return -1;
 }
 return 0;
}

canonical_original_code:
int game_add_category(struct game *game, char *name, char *value) {
 struct game_category *gc = malloc( sizeof(struct game_category) );
 if( gc ) {
  gc->name = name;
  gc->value = value;
  gc->next = game->categories;
  game->categories = gc;
 }
 else {
  fprintf( stderr, "Warning: Couldn't allocate category for game '%s'\n", game->name );
  return -1;
 }
 return 0;
}

variable_types:
name
char *

variable_types:
value
char *

variable_types: struct game_category { struct game_category *next; char *name; char *value; } *


decompiled_code:
__int64 __fastcall game_list_filter_category(__int128 a1)
{
__int64 *v1; // r12
unsigned int v2; // er14
const char *v3; // r13
__int64 i; // rbx
__int64 **v6; // rax
__int64 v7; // rax

v1 = (__int64 *)game_start;
game_filter_start = 0LL;
v2 = 0;
if ( game_start )
{
v3 = (const char *)a1;
if ( *((_QWORD *)game_start + 5) )
{
do
{
for ( i = v1[5]; i; i = *(_QWORD *)i )
{
if ( !strcasecmp(*(const char **)(i + 8), v3) )
{
*(_QWORD *)&a1 = *(_QWORD *)(i + 16);
if ( a1 == 0
|| *((_QWORD *)&a1 + 1) && (_QWORD)a1 && !strcasecmp((const char *)a1, *((const char **)&a1 + 1)) )
{
if ( game_filter_start )
{
v6 = *(__int64 ***)(game_filter_start + 8);
v1[1] = (__int64)v6;
*v6 = v1;
v7 = game_filter_start;
*(_QWORD *)(game_filter_start + 8) = v1;
*v1 = v7;
}
else
{
game_filter_start = (__int64)v1;
*v1 = (__int64)v1;
v1[1] = (__int64)v1;
}
++v2;
}
}
}
v1 = (__int64 *)v1[2];
}
while ( game_start != v1 );
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int128 a1)
{
__int64 *v1; // r12
unsigned int v2; // er14
const char *v3; // r13
__int64 i; // rbx
__int64 **v6; // rax
__int64 v7; // rax

v1 = (__int64 *)game_start;
game_filter_start = 0LL;
v2 = 0;
if ( game_start )
{
v3 = (const char *)a1;
if ( *((_QWORD *)game_start + 5) )
{
do
{
for ( i = v1[5]; i; i = *(_QWORD *)i )
{
if ( !strcasecmp(*(const char **)(i + 8), v3) )
{
*(_QWORD *)&a1 = *(_QWORD *)(i + 16);
if ( a1 == 0
|| *((_QWORD *)&a1 + 1) && (_QWORD)a1 && !strcasecmp((const char *)a1, *((const char **)&a1 + 1)) )
{
if ( game_filter_start )
{
v6 = *(__int64 ***)(game_filter_start + 8);
v1[1] = (__int64)v6;
*v6 = v1;
v7 = game_filter_start;
*(_QWORD *)(game_filter_start + 8) = v1;
*v1 = v7;
}
else
{
game_filter_start = (__int64)v1;
*v1 = (__int64)v1;
v1[1] = (__int64)v1;
}
++v2;
}
}
}
v1 = (__int64 *)v1[2];
}
while ( game_start != v1 );
}
}
return v2;
}

original_code:
int game_list_filter_category( char *name, char *value ) {
 int count = 0;
 struct game *game = game_start;
 struct game_category *category = ((void *)0);
 game_filter_start = ((void *)0);
 if( game && game->categories ) {
  do {
   category = game->categories;
   while( category ) {
    if( strcasecmp( category->name, name ) == 0 ) {
     if( (category->value == ((void *)0) && value == ((void *)0))
     || (category->value && value && strcasecmp( category->value, value ) == 0) ) {
      if( game_filter_start == ((void *)0) ) {
       game_filter_start = game;
       game->next = game;
       game->prev = game;
      }
      else {
       game->prev = game_filter_start->prev;
       game_filter_start->prev->next = game;
       game_filter_start->prev = game;
       game->next = game_filter_start;
      }
      count++;
     }
    }
    category = category->next;
   }
   game = game->all_next;
  } while ( game != game_start );
 }
 return count;
}

canonical_original_code:
int game_list_filter_category(char *name, char *value) {
 int count = 0;
 struct game *game = game_start;
 struct game_category *category = ((void *)0);
 game_filter_start = ((void *)0);
 if( game && game->categories ) {
  do {
   category = game->categories;
   while( category ) {
    if( strcasecmp( category->name, name ) == 0 ) {
     if( (category->value == ((void *)0) && value == ((void *)0))
     || (category->value && value && strcasecmp( category->value, value ) == 0) ) {
      if( game_filter_start == ((void *)0) ) {
       game_filter_start = game;
       game->next = game;
       game->prev = game;
      }
      else {
       game->prev = game_filter_start->prev;
       game_filter_start->prev->next = game;
       game_filter_start->prev = game;
       game->next = game_filter_start;
      }
      count++;
     }
    }
    category = category->next;
   }
   game = game->all_next;
  } while ( game != game_start );
 }
 return count;
}

variable_types: count int


decompiled_code:
__int64 __fastcall game_list_filter_platform(__int64 a1)
{
__int64 *v1; // rax
unsigned int v2; // edx
__int64 **v3; // rcx
__int64 v4; // rcx

v1 = (__int64 *)game_start;
game_filter_start = 0LL;
if ( !game_start || !a1 )
return 0;
v2 = 0;
do
{
if ( v1[4] == a1 )
{
if ( game_filter_start )
{
v3 = *(__int64 ***)(game_filter_start + 8);
v1[1] = (__int64)v3;
*v3 = v1;
v4 = game_filter_start;
*(_QWORD *)(game_filter_start + 8) = v1;
*v1 = v4;
}
else
{
game_filter_start = (__int64)v1;
*v1 = (__int64)v1;
v1[1] = (__int64)v1;
}
++v2;
}
v1 = (__int64 *)v1[2];
}
while ( game_start != v1 );
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
__int64 *v1; // rax
unsigned int v2; // edx
__int64 **v3; // rcx
__int64 v4; // rcx

v1 = (__int64 *)game_start;
game_filter_start = 0LL;
if ( !game_start || !a1 )
return 0;
v2 = 0;
do
{
if ( v1[4] == a1 )
{
if ( game_filter_start )
{
v3 = *(__int64 ***)(game_filter_start + 8);
v1[1] = (__int64)v3;
*v3 = v1;
v4 = game_filter_start;
*(_QWORD *)(game_filter_start + 8) = v1;
*v1 = v4;
}
else
{
game_filter_start = (__int64)v1;
*v1 = (__int64)v1;
v1[1] = (__int64)v1;
}
++v2;
}
v1 = (__int64 *)v1[2];
}
while ( game_start != v1 );
return v2;
}

original_code:
int game_list_filter_platform( struct platform *platform ) {
 int count = 0;
 struct game *game = game_start;
 game_filter_start = ((void *)0);
 if( game && platform ) {
  do {
   if( game->platform == platform ) {
    if( game_filter_start == ((void *)0) ) {
     game_filter_start = game;
     game->next = game;
     game->prev = game;
    }
    else {
     game->prev = game_filter_start->prev;
     game_filter_start->prev->next = game;
     game_filter_start->prev = game;
     game->next = game_filter_start;
    }
    count++;
   }
   game = game->all_next;
  } while ( game != game_start );
 }
 return count;
}

canonical_original_code:
int game_list_filter_platform(struct platform *platform) {
 int count = 0;
 struct game *game = game_start;
 game_filter_start = ((void *)0);
 if( game && platform ) {
  do {
   if( game->platform == platform ) {
    if( game_filter_start == ((void *)0) ) {
     game_filter_start = game;
     game->next = game;
     game->prev = game;
    }
    else {
     game->prev = game_filter_start->prev;
     game_filter_start->prev->next = game;
     game_filter_start->prev = game;
     game->next = game_filter_start;
    }
    count++;
   }
   game = game->all_next;
  } while ( game != game_start );
 }
 return count;
}

variable_types: struct platform { struct platform *next; struct platform *prev; char *name; char image_file[256]; struct texture { unsigned int id; int width; int height; } *texture; } *


decompiled_code:
__int64 game_list_unfilter()
{
_QWORD *v0; // rax
unsigned int v1; // ecx
_QWORD *v2; // rdx

v0 = game_start;
v1 = 0;
if ( game_start )
{
do
{
v2 = v0;
v0 = (_QWORD *)v0[2];
*v2 = v0;
v2[1] = v2[3];
++v1;
}
while ( v0 != game_start );
}
game_filter_start = (__int64)game_start;
return v1;
}

canonical_decompiled_code:
__int64 func11()
{
_QWORD *v0; // rax
unsigned int v1; // ecx
_QWORD *v2; // rdx

v0 = game_start;
v1 = 0;
if ( game_start )
{
do
{
v2 = v0;
v0 = (_QWORD *)v0[2];
*v2 = v0;
v2[1] = v2[3];
++v1;
}
while ( v0 != game_start );
}
game_filter_start = (__int64)game_start;
return v1;
}

original_code:
int game_list_unfilter( void ) {
 int count = 0;
 struct game* game = game_start;
 if( game ) {
  do {
   game->next = game->all_next;
   game->prev = game->all_prev;
   game = game->all_next;
   count++;
  } while ( game != game_start );
 }
 game_filter_start = game_start;
 return count;
}

canonical_original_code:
int game_list_unfilter() {
 int count = 0;
 struct game *game = game_start;
 if( game ) {
  do {
   game->next = game->all_next;
   game->prev = game->all_prev;
   game = game->all_next;
   count++;
  } while ( game != game_start );
 }
 game_filter_start = game_start;
 return count;
}


decompiled_code:
__int64 game_list_create()
{
__int64 v1; // rax
__int64 v2; // rax
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rax
_QWORD *v6; // rbx
__int64 v7; // rdi
__int64 v8; // rbp
__int64 v9; // rsi
unsigned int i; // er12
_QWORD *v11; // r14
_QWORD *v12; // rbx
const char *v13; // rsi
const char *v14; // rbp
__int64 v15; // rax
_DWORD *v16; // rax
_BYTE *v17; // rbx
__int64 v18; // rax
const char **v19; // rbx
_QWORD *v20; // r13
_QWORD *v21; // r15
__int64 v22; // rdi
__int64 v23; // r12
__int64 v24; // rax
_QWORD *v25; // rax
const char **v26; // rbp
const char *v27; // r12
const char *v28; // [rsp+8h] [rbp-40h]

v28 = *(const char **)(config_get() + 24);
if ( v28 )
{
game_image_type = image_type_name(0LL);
while ( 1 )
{
v20 = malloc(0x60uLL);
if ( !v20 )
return 0xFFFFFFFFLL;
v6 = (_QWORD *)*((_QWORD *)v28 + 97);
v21 = (_QWORD *)category_first();
memset(v20, 0, 0x60uLL);
v20[10] = v28 + 8;
v20[11] = v28 + 136;
v20[7] = *((_QWORD *)v28 + 98);
v22 = *((_QWORD *)v28 + 99);
if ( v22 )
{
v20[4] = platform_get(v22 + 8);
}
else
{
platform_add_unknown();
v20[4] = platform_get(0LL);
}
if ( v28[648] )
{
v1 = emulator_get_by_name(v28 + 648);
v20[9] = v1;
if ( v1 )
goto LABEL_42;
fprintf(stderr, "Warning: Emulator '%s' defined for game '%s' not found\n", v28 + 648, (const char *)v20[10]);
}
if ( v20[9]
|| (v2 = *((_QWORD *)v28 + 99)) != 0 && (v3 = emulator_get_by_platform(v2 + 8), (v20[9] = v3) != 0LL)
|| (v4 = emulator_get_default(), (v20[9] = v4) != 0LL) )
{
LABEL_42:
for ( v20[5] = 0LL; v6; v6 = (_QWORD *)*v6 )
{
v7 = v6[1];
if ( *(_DWORD *)(v7 + 8) )
{
v5 = lookup_category(v7, v6[2] + 8LL);
game_add_category((__int64)v20, v6[1] + 12LL, v5);
}
else
{
v8 = v6[2] + 8LL;
v9 = config_get() + 236;
game_add_category((__int64)v20, v9, v8);
}
}
v20[8] = 0LL;
for ( i = 0; i != 4; ++i )
{
v11 = malloc(0x118uLL);
if ( v11 )
{
v12 = (_QWORD *)*((_QWORD *)v28 + 100);
memset(v11, 0, 0x118uLL);
if ( v12 )
{
while ( 1 )
{
v13 = (const char *)image_type_name(i);
v14 = (const char *)(v12[1] + 8LL);
if ( !strcasecmp(v14, v13) )
break;
v12 = (_QWORD *)*v12;
if ( !v12 )
goto LABEL_17;
}
v11[2] = v14;
location_get_path(v14, v12 + 2, v11 + 3);
}
LABEL_17:
if ( *((_BYTE *)v11 + 24)
|| (v15 = image_type_name(i), v11[2] = v15,
location_get_match(v15, v20[11], v11 + 3),
*((_BYTE *)v11 + 24)) )
{
*v11 = v20[8];
v20[8] = v11;
}
else
{
free(v11);
}
}
else
{
fprintf(stderr, "Warning: Couldn't allocate game image object for '%s'\n", (const char *)v20[10]);
}
}
v16 = malloc(0x118uLL);
v17 = v16;
if ( v16 )
{
memset(v16, 0, 0x118uLL);
v16[2] = 1;
v18 = media_type_name(1LL);
location_get_path(v18, v28 + 392, v17 + 24);
if ( v17[24] || (v23 = v20[11], v24 = media_type_name(1LL), location_get_match(v24, v23, v17 + 24), v17[24]) )
{
*(_QWORD *)v17 = v20[8];
v20[8] = v17;
}
else
{
free(v17);
}
}
else
{
fprintf(stderr, "Warning: Couldn't allocate game video object for '%s'\n", (const char *)v20[10]);
}
if ( v21 )
{
do
{
v25 = (_QWORD *)v20[5];
if ( v25 )
{
while ( v25[1] != v21[4] )
{
v25 = (_QWORD *)*v25;
if ( !v25 )
goto LABEL_51;
}
}
else
{
LABEL_51:
category_value_add_unknown(v21);
game_add_category((__int64)v20, v21[4], 0LL);
}
v21 = (_QWORD *)*v21;
}
while ( v21 != (_QWORD *)category_first() );
}
v19 = (const char **)game_start;
if ( game_start )
{
v26 = (const char **)*((_QWORD *)game_start + 3);
v27 = (const char *)v20[10];
v19 = v26;
do
{
if ( strcasecmp(v19[10], v27) <= 0 )
break;
v19 = (const char **)v19[3];
}
while ( v26 != v19 );
}
game_add((__int64)v20, (__int64)v19);
if ( !game_start || strcasecmp((const char *)v20[10], *((const char **)game_start + 10)) < 0 )
game_start = v20;
*v20 = v20[2];
v20[1] = v20[3];
v28 = *(const char **)v28;
if ( !v28 )
goto LABEL_4;
}
else
{
fprintf(stderr, "Warning: No emulator found for game '%s'\n", (const char *)v20[10]);
free(v20);
}
}
}
platform_add_unknown();
game_image_type = image_type_name(0LL);
LABEL_4:
game_list_unfilter();
return 0LL;
}

canonical_decompiled_code:
__int64 func12()
{
__int64 v1; // rax
__int64 v2; // rax
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rax
_QWORD *v6; // rbx
__int64 v7; // rdi
__int64 v8; // rbp
__int64 v9; // rsi
unsigned int i; // er12
_QWORD *v11; // r14
_QWORD *v12; // rbx
const char *v13; // rsi
const char *v14; // rbp
__int64 v15; // rax
_DWORD *v16; // rax
_BYTE *v17; // rbx
__int64 v18; // rax
const char **v19; // rbx
_QWORD *v20; // r13
_QWORD *v21; // r15
__int64 v22; // rdi
__int64 v23; // r12
__int64 v24; // rax
_QWORD *v25; // rax
const char **v26; // rbp
const char *v27; // r12
const char *v28; // [rsp+8h] [rbp-40h]

v28 = *(const char **)(config_get() + 24);
if ( v28 )
{
game_image_type = image_type_name(0LL);
while ( 1 )
{
v20 = malloc(0x60uLL);
if ( !v20 )
return 0xFFFFFFFFLL;
v6 = (_QWORD *)*((_QWORD *)v28 + 97);
v21 = (_QWORD *)category_first();
memset(v20, 0, 0x60uLL);
v20[10] = v28 + 8;
v20[11] = v28 + 136;
v20[7] = *((_QWORD *)v28 + 98);
v22 = *((_QWORD *)v28 + 99);
if ( v22 )
{
v20[4] = platform_get(v22 + 8);
}
else
{
platform_add_unknown();
v20[4] = platform_get(0LL);
}
if ( v28[648] )
{
v1 = emulator_get_by_name(v28 + 648);
v20[9] = v1;
if ( v1 )
goto LABEL_42;
fprintf(stderr, "Warning: Emulator '%s' defined for game '%s' not found\n", v28 + 648, (const char *)v20[10]);
}
if ( v20[9]
|| (v2 = *((_QWORD *)v28 + 99)) != 0 && (v3 = emulator_get_by_platform(v2 + 8), (v20[9] = v3) != 0LL)
|| (v4 = emulator_get_default(), (v20[9] = v4) != 0LL) )
{
LABEL_42:
for ( v20[5] = 0LL; v6; v6 = (_QWORD *)*v6 )
{
v7 = v6[1];
if ( *(_DWORD *)(v7 + 8) )
{
v5 = lookup_category(v7, v6[2] + 8LL);
func8((__int64)v20, v6[1] + 12LL, v5);
}
else
{
v8 = v6[2] + 8LL;
v9 = config_get() + 236;
func8((__int64)v20, v9, v8);
}
}
v20[8] = 0LL;
for ( i = 0; i != 4; ++i )
{
v11 = malloc(0x118uLL);
if ( v11 )
{
v12 = (_QWORD *)*((_QWORD *)v28 + 100);
memset(v11, 0, 0x118uLL);
if ( v12 )
{
while ( 1 )
{
v13 = (const char *)image_type_name(i);
v14 = (const char *)(v12[1] + 8LL);
if ( !strcasecmp(v14, v13) )
break;
v12 = (_QWORD *)*v12;
if ( !v12 )
goto LABEL_17;
}
v11[2] = v14;
location_get_path(v14, v12 + 2, v11 + 3);
}
LABEL_17:
if ( *((_BYTE *)v11 + 24)
|| (v15 = image_type_name(i), v11[2] = v15,
location_get_match(v15, v20[11], v11 + 3),
*((_BYTE *)v11 + 24)) )
{
*v11 = v20[8];
v20[8] = v11;
}
else
{
free(v11);
}
}
else
{
fprintf(stderr, "Warning: Couldn't allocate game image object for '%s'\n", (const char *)v20[10]);
}
}
v16 = malloc(0x118uLL);
v17 = v16;
if ( v16 )
{
memset(v16, 0, 0x118uLL);
v16[2] = 1;
v18 = media_type_name(1LL);
location_get_path(v18, v28 + 392, v17 + 24);
if ( v17[24] || (v23 = v20[11], v24 = media_type_name(1LL), location_get_match(v24, v23, v17 + 24), v17[24]) )
{
*(_QWORD *)v17 = v20[8];
v20[8] = v17;
}
else
{
free(v17);
}
}
else
{
fprintf(stderr, "Warning: Couldn't allocate game video object for '%s'\n", (const char *)v20[10]);
}
if ( v21 )
{
do
{
v25 = (_QWORD *)v20[5];
if ( v25 )
{
while ( v25[1] != v21[4] )
{
v25 = (_QWORD *)*v25;
if ( !v25 )
goto LABEL_51;
}
}
else
{
LABEL_51:
category_value_add_unknown(v21);
func8((__int64)v20, v21[4], 0LL);
}
v21 = (_QWORD *)*v21;
}
while ( v21 != (_QWORD *)category_first() );
}
v19 = (const char **)game_start;
if ( game_start )
{
v26 = (const char **)*((_QWORD *)game_start + 3);
v27 = (const char *)v20[10];
v19 = v26;
do
{
if ( strcasecmp(v19[10], v27) <= 0 )
break;
v19 = (const char **)v19[3];
}
while ( v26 != v19 );
}
func1((__int64)v20, (__int64)v19);
if ( !game_start || strcasecmp((const char *)v20[10], *((const char **)game_start + 10)) < 0 )
game_start = v20;
*v20 = v20[2];
v20[1] = v20[3];
v28 = *(const char **)v28;
if ( !v28 )
goto LABEL_4;
}
else
{
fprintf(stderr, "Warning: No emulator found for game '%s'\n", (const char *)v20[10]);
free(v20);
}
}
}
platform_add_unknown();
game_image_type = image_type_name(0LL);
LABEL_4:
func11();
return 0LL;
}

original_code:
int game_list_create( void ) {
 struct game *game = ((void *)0);
 struct game *prev = ((void *)0);
 struct config_game *config_game = config_get()->games;
 if( !config_game )
  platform_add_unknown();
 game_image_type = (char*)image_type_name( IMAGE_LOGO );
 while( config_game ) {
  game = malloc(sizeof(struct game));
  if( game == ((void *)0) ) {
   return -1;
  }
  else {
   struct config_game_category *config_game_category = config_game->categories;
   struct category *category = category_first();
   int i = 0;
   memset( game, 0, sizeof(struct game) );
   game->name = config_game->name;
   game->texture = ((void *)0);
   game->rom_path = config_game->rom_image;
   game->params = config_game->params;
   if( config_game->platform ) {
    game->platform = platform_get( config_game->platform->name );
   }
   else {
    platform_add_unknown();
    game->platform = platform_get( ((void *)0) );
   }
   if( config_game->emulator && config_game->emulator[0] ) {
    game->emulator = emulator_get_by_name( config_game->emulator );
    if( !game->emulator )
     fprintf( stderr, "Warning: Emulator '%s' defined for game '%s' not found\n", config_game->emulator, game->name );
   }
   if( !game->emulator && config_game->platform ) {
    game->emulator = emulator_get_by_platform( config_game->platform->name );
   }
   if( !game->emulator ) {
    game->emulator = emulator_get_default();
   }
   if( !game->emulator ) {
    fprintf( stderr, "Warning: No emulator found for game '%s'\n", game->name );
    free( game );
    continue;
   }
   game->categories = ((void *)0);
   while( config_game_category ) {
    if( config_game_category->category->id == 0 )
     game_add_category( game, (char*)config_get()->iface.labels.label_lists, config_game_category->value->name );
    else
     game_add_category( game, config_game_category->category->name, (char*)lookup_category( config_game_category->category, (const char*)config_game_category->value->name ) );
    config_game_category = config_game_category->next;
   }
   game->media = ((void *)0);
   for( i = 0 ; i < NUM_IMAGE_TYPES ; i++ ) {
    struct game_media *image = malloc( sizeof(struct game_media) );
    if( image ) {
     struct config_image *config_game_image = config_game->images;
     memset( image, 0, sizeof(struct game_media) );
     image->type = MEDIA_IMAGE;
     while( config_game_image ) {
      if( strcasecmp( config_game_image->type->name, image_type_name(i) ) == 0 ) {
       image->subtype = config_game_image->type->name;
       location_get_path( image->subtype, config_game_image->file_name, image->file_name );
       break;
      }
      config_game_image = config_game_image->next;
     }
     if( image->file_name[0] == '\0' ) {
      image->subtype = (char*)image_type_name(i);
      location_get_match( image->subtype, game->rom_path, image->file_name );
     }
     if( image->file_name[0] == '\0' ) {
      free( image );
     }
     else {
      image->next = game->media;
      game->media = image;
     }
    }
    else {
     fprintf( stderr, "Warning: Couldn't allocate game image object for '%s'\n", game->name );
    }
   }
   {
    struct game_media *video = malloc( sizeof(struct game_media) );
    if( video ) {
     memset( video, 0, sizeof(struct game_media) );
     video->type = MEDIA_VIDEO;
     location_get_path( media_type_name(MEDIA_VIDEO), config_game->video, video->file_name );
     if( video->file_name[0] == '\0' ) {
      location_get_match( media_type_name(MEDIA_VIDEO), game->rom_path, video->file_name );
     }
     if( video->file_name[0] == '\0' ) {
      free( video );
     }
     else {
      video->next = game->media;
      game->media = video;
     }
    }
    else {
     fprintf( stderr, "Warning: Couldn't allocate game video object for '%s'\n", game->name );
    }
   }
   if( category ) {
    do {
     struct game_category *gc = game->categories;
     while( gc ) {
      if( gc->name == category->name ) {
       break;
      }
      gc = gc->next;
     }
     if( gc == ((void *)0) ) {
      category_value_add_unknown( category );
      game_add_category( game, category->name, ((void *)0) );
     }
     category = category->next;
    } while( category != category_first() );
   }
   prev = game_start;
   if( game_start ) {
    prev = game_start->all_prev;
    while( strcasecmp( prev->name, game->name ) > 0 ) {
     prev = prev->all_prev;
     if( prev == game_start->all_prev ) break;
    }
   }
   game_add( game, prev );
   if( !game_start || strcasecmp( game->name, game_start->name ) < 0 ) {
    game_start = game;
   }
   game->next = game->all_next;
   game->prev = game->all_prev;
  }
  config_game = config_game->next;
 }
 game_list_unfilter();
 return 0;
}

canonical_original_code:
int game_list_create() {
 struct game *game = ((void *)0);
 struct game *prev = ((void *)0);
 struct config_game *config_game = config_get()->games;
 if( !config_game )
  platform_add_unknown();
 game_image_type = (char *)image_type_name( IMAGE_LOGO );
 while( config_game ) {
  game = malloc(sizeof(struct game));
  if( game == ((void *)0) ) {
   return -1;
  }
  else {
   struct config_game_category *config_game_category = config_game->categories;
   struct category *category = category_first();
   int i = 0;
   memset( game, 0, sizeof(struct game) );
   game->name = config_game->name;
   game->texture = ((void *)0);
   game->rom_path = config_game->rom_image;
   game->params = config_game->params;
   if( config_game->platform ) {
    game->platform = platform_get( config_game->platform->name );
   }
   else {
    platform_add_unknown();
    game->platform = platform_get( ((void *)0) );
   }
   if( config_game->emulator && config_game->emulator[0] ) {
    game->emulator = emulator_get_by_name( config_game->emulator );
    if( !game->emulator )
     fprintf( stderr, "Warning: Emulator '%s' defined for game '%s' not found\n", config_game->emulator, game->name );
   }
   if( !game->emulator && config_game->platform ) {
    game->emulator = emulator_get_by_platform( config_game->platform->name );
   }
   if( !game->emulator ) {
    game->emulator = emulator_get_default();
   }
   if( !game->emulator ) {
    fprintf( stderr, "Warning: No emulator found for game '%s'\n", game->name );
    free( game );
    continue;
   }
   game->categories = ((void *)0);
   while( config_game_category ) {
    if( config_game_category->category->id == 0 )
     game_add_category( game, (char *)config_get()->iface.labels.label_lists, config_game_category->value->name );
    else
     game_add_category( game, config_game_category->category->name, (char *)lookup_category( config_game_category->category, (char *)config_game_category->value->name ) );
    config_game_category = config_game_category->next;
   }
   game->media = ((void *)0);
   for( i = 0 ; i < NUM_IMAGE_TYPES ; i++ ) {
    struct game_media *image = malloc( sizeof(struct game_media) );
    if( image ) {
     struct config_image *config_game_image = config_game->images;
     memset( image, 0, sizeof(struct game_media) );
     image->type = MEDIA_IMAGE;
     while( config_game_image ) {
      if( strcasecmp( config_game_image->type->name, image_type_name(i) ) == 0 ) {
       image->subtype = config_game_image->type->name;
       location_get_path( image->subtype, config_game_image->file_name, image->file_name );
       break;
      }
      config_game_image = config_game_image->next;
     }
     if( image->file_name[0] == '\0' ) {
      image->subtype = (char *)image_type_name(i);
      location_get_match( image->subtype, game->rom_path, image->file_name );
     }
     if( image->file_name[0] == '\0' ) {
      free( image );
     }
     else {
      image->next = game->media;
      game->media = image;
     }
    }
    else {
     fprintf( stderr, "Warning: Couldn't allocate game image object for '%s'\n", game->name );
    }
   }
   {
    struct game_media *video = malloc( sizeof(struct game_media) );
    if( video ) {
     memset( video, 0, sizeof(struct game_media) );
     video->type = MEDIA_VIDEO;
     location_get_path( media_type_name(MEDIA_VIDEO), config_game->video, video->file_name );
     if( video->file_name[0] == '\0' ) {
      location_get_match( media_type_name(MEDIA_VIDEO), game->rom_path, video->file_name );
     }
     if( video->file_name[0] == '\0' ) {
      free( video );
     }
     else {
      video->next = game->media;
      game->media = video;
     }
    }
    else {
     fprintf( stderr, "Warning: Couldn't allocate game video object for '%s'\n", game->name );
    }
   }
   if( category ) {
    do {
     struct game_category *gc = game->categories;
     while( gc ) {
      if( gc->name == category->name ) {
       break;
      }
      gc = gc->next;
     }
     if( gc == ((void *)0) ) {
      category_value_add_unknown( category );
      game_add_category( game, category->name, ((void *)0) );
     }
     category = category->next;
    } while( category != category_first() );
   }
   prev = game_start;
   if( game_start ) {
    prev = game_start->all_prev;
    while( strcasecmp( prev->name, game->name ) > 0 ) {
     prev = prev->all_prev;
     if( prev == game_start->all_prev ) break;
    }
   }
   game_add( game, prev );
   if( !game_start || strcasecmp( game->name, game_start->name ) < 0 ) {
    game_start = game;
   }
   game->next = game->all_next;
   game->prev = game->all_prev;
  }
  config_game = config_game->next;
 }
 game_list_unfilter();
 return 0;
}

variable_types: struct config_game { struct config_game *next; char name[128]; char rom_image[256]; char video[256]; char emulator[128]; struct config_game_category { struct config_game_category *next; struct config_category { struct config_category *next; int id; char name[128]; struct config_category_value { struct config_category_value *next; char name[128]; } *values; struct config_lookup { struct config_lookup *next; char match[32]; char value[32]; } *lookups; } *category; struct config_category_value *value; } *categories; struct config_param { struct config_param *next; char name[64]; char value[64]; } *params; struct config_platform { struct config_platform *next; char name[128]; } *platform; struct config_image { struct config_image *next; struct config_image_type { struct config_image_type *next; char name[128]; } *type; char file_name[256]; } *images; } *

variable_types: struct category { struct category *next; struct category *prev; struct category_value { struct category_value *next; struct category_value *prev; char *name; } *values; int id; char *name; int value_count; int has_unknowns; } *

variable_types: i int

variable_types: struct game_media { struct game_media *next; int type; char *subtype; char file_name[256]; } *

user_defined_types: struct config_game { struct config_game *next; char name[128]; char rom_image[256]; char video[256]; char emulator[128]; struct config_game_category *categories; struct config_param *params; struct config_platform *platform; struct config_image *images; }

user_defined_types: struct config_game_category { struct config_game_category *next; struct config_category *category; struct config_category_value *value; }

user_defined_types: struct category { struct category *next; struct category *prev; struct category_value *values; int id; char *name; int value_count; int has_unknowns; }

user_defined_types: struct config_image { struct config_image *next; struct config_image_type *type; char file_name[256]; }

user_defined_types: struct config_category { struct config_category *next; int id; char name[128]; struct config_category_value *values; struct config_lookup *lookups; }


decompiled_code:
char *__fastcall device_name(unsigned int a1)
{
char *result; // rax

result = 0LL;
if ( a1 <= 4 )
result = device_str[a1];
return result;
}

canonical_decompiled_code:
char *__fastcall func0(unsigned int a1)
{
char *result; // rax

result = 0LL;
if ( a1 <= 4 )
result = device_str[a1];
return result;
}

original_code:
const char *device_name( int device ) {
 if( device < 0 || device > NUM_DEVS )
  return ((void *)0);
 else
  return device_str[device];
}

canonical_original_code:
char *device_name(int device) {
 if( device < 0 || device > NUM_DEVS )
  return ((void *)0);
 else
  return device_str[device];
}

variable_types: device int

return_type: char *


decompiled_code:
__int64 __fastcall device_id(char *s1)
{
__int64 v1; // rbx
unsigned int v2; // er12

v1 = 0LL;
if ( s1 )
{
while ( 1 )
{
v2 = v1;
if ( !strcasecmp(s1, device_str[v1]) )
break;
if ( ++v1 == 4 )
{
fprintf(stderr, "Warning: Unknown device name '%s'\n", s1);
return 0;
}
}
}
else
{
fwrite("Warning: Null device name\n", 1uLL, 0x1AuLL, stderr);
v2 = 0;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func1(char *s1)
{
__int64 v1; // rbx
unsigned int v2; // er12

v1 = 0LL;
if ( s1 )
{
while ( 1 )
{
v2 = v1;
if ( !strcasecmp(s1, device_str[v1]) )
break;
if ( ++v1 == 4 )
{
fprintf(stderr, "Warning: Unknown device name '%s'\n", s1);
return 0;
}
}
}
else
{
fwrite("Warning: Null device name\n", 1uLL, 0x1AuLL, stderr);
v2 = 0;
}
return v2;
}

original_code:
int device_id( char *name ) {
 int i;
 if( name == ((void *)0) ) {
  fprintf( stderr, "Warning: Null device name\n" );
  return DEV_UNKNOWN;
 }
 for( i = 0 ; i < NUM_DEVS ; i++ ) {
  if( strcasecmp( name, device_str[i] ) == 0 ) return i;
 }
 fprintf( stderr, "Warning: Unknown device name '%s'\n", name );
 return DEV_UNKNOWN;
}

canonical_original_code:
int device_id(char *name) {
 int i;
 if( name == ((void *)0) ) {
  fprintf( stderr, "Warning: Null device name\n" );
  return DEV_UNKNOWN;
 }
 for( i = 0 ; i < NUM_DEVS ; i++ ) {
  if( strcasecmp( name, device_str[i] ) == 0 ) return i;
 }
 fprintf( stderr, "Warning: Unknown device name '%s'\n", name );
 return DEV_UNKNOWN;
}


decompiled_code:
char *__fastcall control_name(unsigned int a1)
{
char *result; // rax

result = 0LL;
if ( a1 <= 5 )
result = ctrl_str[a1];
return result;
}

canonical_decompiled_code:
char *__fastcall func2(unsigned int a1)
{
char *result; // rax

result = 0LL;
if ( a1 <= 5 )
result = ctrl_str[a1];
return result;
}

original_code:
const char *control_name( int control ) {
 if( control < 0 || control > NUM_CTRLS )
  return ((void *)0);
 else
  return ctrl_str[control];
}

canonical_original_code:
char *control_name(int control) {
 if( control < 0 || control > NUM_CTRLS )
  return ((void *)0);
 else
  return ctrl_str[control];
}

variable_types: control int


decompiled_code:
__int64 __fastcall control_id(char *s1)
{
__int64 v1; // rbx
unsigned int v2; // er12

v1 = 0LL;
if ( s1 )
{
while ( 1 )
{
v2 = v1;
if ( !strcasecmp(s1, ctrl_str[v1]) )
break;
if ( ++v1 == 5 )
{
fprintf(stderr, "Warning: Unknown control name '%s'\n", s1);
return 0;
}
}
}
else
{
fwrite("Warning: Null control name\n", 1uLL, 0x1BuLL, stderr);
v2 = 0;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s1)
{
__int64 v1; // rbx
unsigned int v2; // er12

v1 = 0LL;
if ( s1 )
{
while ( 1 )
{
v2 = v1;
if ( !strcasecmp(s1, ctrl_str[v1]) )
break;
if ( ++v1 == 5 )
{
fprintf(stderr, "Warning: Unknown control name '%s'\n", s1);
return 0;
}
}
}
else
{
fwrite("Warning: Null control name\n", 1uLL, 0x1BuLL, stderr);
v2 = 0;
}
return v2;
}

original_code:
int control_id( char *name ) {
 int i;
 if( name == ((void *)0) ) {
  fprintf( stderr, "Warning: Null control name\n" );
  return CTRL_UNKNOWN;
 }
 for( i = 0 ; i < NUM_CTRLS ; i++ ) {
  if( strcasecmp( name, ctrl_str[i] ) == 0 ) return i;
 }
 fprintf( stderr, "Warning: Unknown control name '%s'\n", name );
 return CTRL_UNKNOWN;
}

canonical_original_code:
int control_id(char *name) {
 int i;
 if( name == ((void *)0) ) {
  fprintf( stderr, "Warning: Null control name\n" );
  return CTRL_UNKNOWN;
 }
 for( i = 0 ; i < NUM_CTRLS ; i++ ) {
  if( strcasecmp( name, ctrl_str[i] ) == 0 ) return i;
 }
 fprintf( stderr, "Warning: Unknown control name '%s'\n", name );
 return CTRL_UNKNOWN;
}


decompiled_code:
char *__fastcall direction_name(unsigned int a1)
{
char *result; // rax

result = 0LL;
if ( a1 <= 5 )
result = dir_str[a1];
return result;
}

canonical_decompiled_code:
char *__fastcall func4(unsigned int a1)
{
char *result; // rax

result = 0LL;
if ( a1 <= 5 )
result = dir_str[a1];
return result;
}

original_code:
const char *direction_name( int dir ) {
 if( dir < 0 || dir > NUM_DIRS )
  return ((void *)0);
 else
  return dir_str[dir];
}

canonical_original_code:
char *direction_name(int dir) {
 if( dir < 0 || dir > NUM_DIRS )
  return ((void *)0);
 else
  return dir_str[dir];
}

variable_types: dir int


decompiled_code:
__int64 __fastcall direction_id(char *s1)
{
__int64 v1; // rbx
unsigned int v2; // er12

v1 = 0LL;
if ( s1 )
{
while ( 1 )
{
v2 = v1;
if ( !strcasecmp(s1, dir_str[v1]) )
break;
if ( ++v1 == 5 )
{
fprintf(stderr, "Warning: Unknown direction name '%s'\n", s1);
return 0;
}
}
}
else
{
fwrite("Warning: Null direction name\n", 1uLL, 0x1DuLL, stderr);
v2 = 0;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func5(char *s1)
{
__int64 v1; // rbx
unsigned int v2; // er12

v1 = 0LL;
if ( s1 )
{
while ( 1 )
{
v2 = v1;
if ( !strcasecmp(s1, dir_str[v1]) )
break;
if ( ++v1 == 5 )
{
fprintf(stderr, "Warning: Unknown direction name '%s'\n", s1);
return 0;
}
}
}
else
{
fwrite("Warning: Null direction name\n", 1uLL, 0x1DuLL, stderr);
v2 = 0;
}
return v2;
}

original_code:
int direction_id( char *name ) {
 int i;
 if( name == ((void *)0) ) {
  fprintf( stderr, "Warning: Null direction name\n" );
  return DIR_UNKNOWN;
 }
 for( i = 0 ; i < NUM_DIRS ; i++ ) {
  if( strcasecmp( name, dir_str[i] ) == 0 ) return i;
 }
 fprintf( stderr, "Warning: Unknown direction name '%s'\n", name );
 return DIR_UNKNOWN;
}

canonical_original_code:
int direction_id(char *name) {
 int i;
 if( name == ((void *)0) ) {
  fprintf( stderr, "Warning: Null direction name\n" );
  return DIR_UNKNOWN;
 }
 for( i = 0 ; i < NUM_DIRS ; i++ ) {
  if( strcasecmp( name, dir_str[i] ) == 0 ) return i;
 }
 fprintf( stderr, "Warning: Unknown direction name '%s'\n", name );
 return DIR_UNKNOWN;
}


decompiled_code:
__int64 __fastcall axis_dir_value(char *s1)
{
int v1; // edx
__int64 result; // rax
int v3; // edx
__int64 i; // rbx
int v5; // er12

if ( s1 )
{
v1 = strcasecmp(s1, "plus");
result = 1LL;
if ( v1 )
{
v3 = strcasecmp(s1, "minus");
result = 0xFFFFFFFFLL;
if ( v3 )
{
for ( i = 0LL; i != 5; ++i )
{
v5 = i;
if ( !strcasecmp(s1, dir_str[i]) )
break;
v5 = i + 1;
}
result = 0xFFFFFFFFLL;
if ( (v5 & 0xFFFFFFFD) != 1 )
{
result = 1LL;
if ( ((v5 - 2) & 0xFFFFFFFD) != 0 )
{
fprintf(stderr, "Warning: Bogus axis direction '%s'\n", s1);
result = 0LL;
}
}
}
}
}
else
{
fwrite("Warning: Null axis value\n", 1uLL, 0x19uLL, stderr);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(char *s1)
{
int v1; // edx
__int64 result; // rax
int v3; // edx
__int64 i; // rbx
int v5; // er12

if ( s1 )
{
v1 = strcasecmp(s1, "plus");
result = 1LL;
if ( v1 )
{
v3 = strcasecmp(s1, "minus");
result = 0xFFFFFFFFLL;
if ( v3 )
{
for ( i = 0LL; i != 5; ++i )
{
v5 = i;
if ( !strcasecmp(s1, dir_str[i]) )
break;
v5 = i + 1;
}
result = 0xFFFFFFFFLL;
if ( (v5 & 0xFFFFFFFD) != 1 )
{
result = 1LL;
if ( ((v5 - 2) & 0xFFFFFFFD) != 0 )
{
fprintf(stderr, "Warning: Bogus axis direction '%s'\n", s1);
result = 0LL;
}
}
}
}
}
else
{
fwrite("Warning: Null axis value\n", 1uLL, 0x19uLL, stderr);
result = 0LL;
}
return result;
}

original_code:
int axis_dir_value( char *name ) {
 int i;
 if( name == ((void *)0) ) {
  fprintf( stderr, "Warning: Null axis value\n" );
  return DIR_UNKNOWN;
 }
 if( strcasecmp( name, axis_dir_plus ) == 0 )
  return 1;
 if( strcasecmp( name, axis_dir_minus ) == 0 )
  return -1;
 for( i = 0 ; i < NUM_DIRS ; i++ ) {
  if( strcasecmp( name, dir_str[i] ) == 0 ) {
   break;
  }
 }
 if( i == DIR_LEFT || i == DIR_UP )
  return -1;
 if( i == DIR_RIGHT || i == DIR_DOWN )
  return 1;
 fprintf( stderr, "Warning: Bogus axis direction '%s'\n", name );
 return 0;
}

canonical_original_code:
int axis_dir_value(char *name) {
 int i;
 if( name == ((void *)0) ) {
  fprintf( stderr, "Warning: Null axis value\n" );
  return DIR_UNKNOWN;
 }
 if( strcasecmp( name, axis_dir_plus ) == 0 )
  return 1;
 if( strcasecmp( name, axis_dir_minus ) == 0 )
  return -1;
 for( i = 0 ; i < NUM_DIRS ; i++ ) {
  if( strcasecmp( name, dir_str[i] ) == 0 ) {
   break;
  }
 }
 if( i == DIR_LEFT || i == DIR_UP )
  return -1;
 if( i == DIR_RIGHT || i == DIR_DOWN )
  return 1;
 fprintf( stderr, "Warning: Bogus axis direction '%s'\n", name );
 return 0;
}


decompiled_code:
const char *__fastcall axis_dir_name(int a1)
{
const char *result; // rax

result = "minus";
if ( a1 >= 0 )
{
result = "plus";
if ( a1 <= 0 )
{
fprintf(stderr, "Warning: Bogus axis direction '%d'\n", 0LL);
result = (const char *)&unk_33C;
}
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func7(int a1)
{
const char *result; // rax

result = "minus";
if ( a1 >= 0 )
{
result = "plus";
if ( a1 <= 0 )
{
fprintf(stderr, "Warning: Bogus axis direction '%d'\n", 0LL);
result = (const char *)&unk_33C;
}
}
return result;
}

original_code:
const char *axis_dir_name( int axis_dir ) {
 if( axis_dir < 0 )
  return axis_dir_minus;
 else if ( axis_dir > 0 )
  return axis_dir_plus;
 fprintf( stderr, "Warning: Bogus axis direction '%d'\n", axis_dir );
 return "";
}

canonical_original_code:
char *axis_dir_name(int axis_dir) {
 if( axis_dir < 0 )
  return axis_dir_minus;
 else if ( axis_dir > 0 )
  return axis_dir_plus;
 fprintf( stderr, "Warning: Bogus axis direction '%d'\n", axis_dir );
 return "";
}


decompiled_code:
__int64 category_count()
{
return (unsigned int)count;
}

canonical_decompiled_code:
__int64 func0()
{
return (unsigned int)count;
}

original_code:
int category_count( void ) {
 return count;
}

canonical_original_code:
int category_count() {
 return count;
}


decompiled_code:
__int64 __fastcall category_add(_QWORD *a1, __int64 *a2)
{
__int64 result; // rax

if ( a2 )
{
*(_QWORD *)(*a2 + 8) = a1;
result = *a2;
*a1 = *a2;
*a2 = (__int64)a1;
a1[1] = a2;
}
else
{
a1[1] = a1;
*a1 = a1;
}
++count;
return result;
}

original_code:
void category_add( struct category *category, struct category *after ) {
 if( after == ((void *)0) ) {
  category->prev = category;
  category->next = category;
 }
 else {
  after->next->prev = category;
  category->next = after->next;
  after->next = category;
  category->prev = after;
 }
 count++;
}

canonical_original_code:
void category_add(struct category *category, struct category *after) {
 if( after == ((void *)0) ) {
  category->prev = category;
  category->next = category;
 }
 else {
  after->next->prev = category;
  category->next = after->next;
  after->next = category;
  category->prev = after;
 }
 count++;
}

variable_types:
after
struct category *

user_defined_types: struct category_value { struct category_value *next; struct category_value *prev; char *name; }


decompiled_code:
__int64 __fastcall category_value_add_unknown(__int64 a1)
{
unsigned int v1; // ebp
_QWORD *v3; // rax
__int64 v4; // rdx
_QWORD *v5; // rdx

v1 = *(_DWORD *)(a1 + 44);
if ( v1 )
return 1;
v3 = malloc(0x18uLL);
if ( v3 )
{
*v3 = 0LL;
v3[1] = 0LL;
v3[2] = 0LL;
v4 = *(_QWORD *)(a1 + 16);
if ( v4 )
{
*v3 = v4;
v5 = *(_QWORD **)(v4 + 8);
v3[1] = v5;
*v5 = v3;
*(_QWORD *)(*(_QWORD *)(a1 + 16) + 8LL) = v3;
}
else
{
v3[1] = v3;
*v3 = v3;
*(_QWORD *)(a1 + 16) = v3;
}
++*(_DWORD *)(a1 + 40);
*(_DWORD *)(a1 + 44) = 1;
}
else
{
fwrite("Warning: Couldn't allocate new category value\n", 1uLL, 0x2EuLL, stderr);
v1 = -1;
}
return v1;
}

original_code:
int category_value_add_unknown( struct category *category ) {
 if( category->has_unknowns ) {
  return 1;
 }
 else {
  struct category_value *value = malloc( sizeof(struct category_value) );
  if( value ) {
   memset( value, 0, sizeof(struct category_value) );
   value->name = ((void *)0);
   if( category->values == ((void *)0) ) {
    value->prev = value;
    value->next = value;
    category->values = value;
   }
   else {
    value->next = category->values;
    value->prev = category->values->prev;
    category->values->prev->next = value;
    category->values->prev = value;
   }
   category->value_count++;
   category->has_unknowns = 1;
   return 0;
  }
  else {
   fprintf( stderr, "Warning: Couldn't allocate new category value\n" );
   return -1;
  }
 }
}

canonical_original_code:
int category_value_add_unknown(struct category *category) {
 if( category->has_unknowns ) {
  return 1;
 }
 else {
  struct category_value *value = malloc( sizeof(struct category_value) );
  if( value ) {
   memset( value, 0, sizeof(struct category_value) );
   value->name = ((void *)0);
   if( category->values == ((void *)0) ) {
    value->prev = value;
    value->next = value;
    category->values = value;
   }
   else {
    value->next = category->values;
    value->prev = category->values->prev;
    category->values->prev->next = value;
    category->values->prev = value;
   }
   category->value_count++;
   category->has_unknowns = 1;
   return 0;
  }
  else {
   fprintf( stderr, "Warning: Couldn't allocate new category value\n" );
   return -1;
  }
 }
}

variable_types: struct category_value { struct category_value *next; struct category_value *prev; char *name; } *


original_code:
int category_value_add( struct category *category, char *name ) {
 struct category_value *search = category->values;
 struct category_value *after = category->values;
 struct category_value *category_value = malloc( sizeof(struct category_value) );
 if( search ) {
  do {
   if( strcasecmp( search->name, name ) == 0 )
    return 0;
   search = search->next;
  } while( search != category->values );
 }
 if( category_value ) {
  memset( category_value, 0, sizeof(struct category_value) );
  category_value->name = name;
  if( after ) {
   after = after->prev;
   while( strcasecmp( after->name, category_value->name ) > 0 ) {
    after = after->prev;
    if( after == category->values->prev ) break;
   }
  }
  if( after == ((void *)0) ) {
   category_value->prev = category_value;
   category_value->next = category_value;
  }
  else {
   after->next->prev = category_value;
   category_value->next = after->next;
   after->next = category_value;
   category_value->prev = after;
  }
  category->value_count++;
  if( !category->values || strcasecmp( category_value->name, category->values->name ) < 0 ) {
   category->values = category_value;
  }
 }
 else {
  fprintf( stderr, "Warning: Couldn't allocate new category value\n" );
  return -1;
 }
 return 0;
}

canonical_original_code:
int category_value_add(struct category *category, char *name) {
 struct category_value *search = category->values;
 struct category_value *after = category->values;
 struct category_value *category_value = malloc( sizeof(struct category_value) );
 if( search ) {
  do {
   if( strcasecmp( search->name, name ) == 0 )
    return 0;
   search = search->next;
  } while( search != category->values );
 }
 if( category_value ) {
  memset( category_value, 0, sizeof(struct category_value) );
  category_value->name = name;
  if( after ) {
   after = after->prev;
   while( strcasecmp( after->name, category_value->name ) > 0 ) {
    after = after->prev;
    if( after == category->values->prev ) break;
   }
  }
  if( after == ((void *)0) ) {
   category_value->prev = category_value;
   category_value->next = category_value;
  }
  else {
   after->next->prev = category_value;
   category_value->next = after->next;
   after->next = category_value;
   category_value->prev = after;
  }
  category->value_count++;
  if( !category->values || strcasecmp( category_value->name, category->values->name ) < 0 ) {
   category->values = category_value;
  }
 }
 else {
  fprintf( stderr, "Warning: Couldn't allocate new category value\n" );
  return -1;
 }
 return 0;
}


decompiled_code:
__int64 category_init()
{
__int64 *v0; // r12
__int64 v2; // r13
const char *v3; // r14
__int64 v4; // rbx
_QWORD *v5; // rbx
_QWORD *v6; // rax
__int64 v7; // rbp
int v8; // eax
const char *v9; // rsi

v0 = *(__int64 **)(config_get() + 16);
if ( !v0 )
return 0LL;
do
{
v6 = malloc(0x30uLL);
v7 = (__int64)v6;
if ( !v6 )
{
fwrite("Error: Couldn't allocate memeory for category object\n", 1uLL, 0x35uLL, stderr);
return 0xFFFFFFFFLL;
}
*v6 = 0LL;
v6[1] = 0LL;
v6[2] = 0LL;
v6[3] = 0LL;
v6[4] = 0LL;
v6[5] = 0LL;
v8 = *((_DWORD *)v0 + 2);
*(_DWORD *)(v7 + 24) = v8;
if ( v8 )
*(_QWORD *)(v7 + 32) = (char *)v0 + 12;
else
*(_QWORD *)(v7 + 32) = config_get() + 236;
v4 = category_start;
if ( category_start )
{
v2 = *(_QWORD *)(category_start + 8);
v3 = *(const char **)(v7 + 32);
v4 = v2;
do
{
if ( strcasecmp(*(const char **)(v4 + 32), v3) <= 0 )
break;
v4 = *(_QWORD *)(v4 + 8);
}
while ( v2 != v4 );
}
category_add((_QWORD *)v7, (__int64 *)v4);
if ( !category_start || strcasecmp(*(const char **)(v7 + 32), *(const char **)(category_start + 32)) < 0 )
category_start = v7;
v5 = (_QWORD *)v0[18];
if ( v5 )
{
*(_QWORD *)(v7 + 16) = 0LL;
do
{
v9 = (const char *)lookup_category(v0, v5 + 1);
category_value_add(v7, v9);
v5 = (_QWORD *)*v5;
}
while ( v5 );
}
v0 = (__int64 *)*v0;
}
while ( v0 );
return 0LL;
}

canonical_decompiled_code:
__int64 func4()
{
__int64 *v0; // r12
__int64 v2; // r13
const char *v3; // r14
__int64 v4; // rbx
_QWORD *v5; // rbx
_QWORD *v6; // rax
__int64 v7; // rbp
int v8; // eax
const char *v9; // rsi

v0 = *(__int64 **)(config_get() + 16);
if ( !v0 )
return 0LL;
do
{
v6 = malloc(0x30uLL);
v7 = (__int64)v6;
if ( !v6 )
{
fwrite("Error: Couldn't allocate memeory for category object\n", 1uLL, 0x35uLL, stderr);
return 0xFFFFFFFFLL;
}
*v6 = 0LL;
v6[1] = 0LL;
v6[2] = 0LL;
v6[3] = 0LL;
v6[4] = 0LL;
v6[5] = 0LL;
v8 = *((_DWORD *)v0 + 2);
*(_DWORD *)(v7 + 24) = v8;
if ( v8 )
*(_QWORD *)(v7 + 32) = (char *)v0 + 12;
else
*(_QWORD *)(v7 + 32) = config_get() + 236;
v4 = category_start;
if ( category_start )
{
v2 = *(_QWORD *)(category_start + 8);
v3 = *(const char **)(v7 + 32);
v4 = v2;
do
{
if ( strcasecmp(*(const char **)(v4 + 32), v3) <= 0 )
break;
v4 = *(_QWORD *)(v4 + 8);
}
while ( v2 != v4 );
}
func1((_QWORD *)v7, (__int64 *)v4);
if ( !category_start || strcasecmp(*(const char **)(v7 + 32), *(const char **)(category_start + 32)) < 0 )
category_start = v7;
v5 = (_QWORD *)v0[18];
if ( v5 )
{
*(_QWORD *)(v7 + 16) = 0LL;
do
{
v9 = (const char *)lookup_category(v0, v5 + 1);
func3(v7, v9);
v5 = (_QWORD *)*v5;
}
while ( v5 );
}
v0 = (__int64 *)*v0;
}
while ( v0 );
return 0LL;
}

original_code:
int category_init( void ) {
 struct config_category *c = config_get()->categories;
 struct category *category = ((void *)0);
 struct category *prev = ((void *)0);
 while( c ) {
  category = malloc( sizeof(struct category) );
  if( category ) {
   memset( category, 0, sizeof(struct category) );
   category->id = c->id;
   if( category->id == 0 )
    category->name = (char*)config_get()->iface.labels.label_lists;
   else
    category->name = c->name;
   prev = category_start;
   if( category_start ) {
    prev = category_start->prev;
    while( strcasecmp( prev->name, category->name ) > 0 ) {
     prev = prev->prev;
     if( prev == category_start->prev ) break;
    }
   }
   category_add( category, prev );
   if( !category_start || strcasecmp( category->name, category_start->name ) < 0 ) {
    category_start = category;
   }
   if( c->values ) {
    struct config_category_value *value = c->values;
    category->values = ((void *)0);
    while( value ) {
     category_value_add( category, (char*)lookup_category( c, value->name ) );
     value = value->next;
    }
   }
  }
  else {
   fprintf( stderr, "Error: Couldn't allocate memeory for category object\n" );
   return -1;
  }
  c = c->next;
 }
 return 0;
}

canonical_original_code:
int category_init() {
 struct config_category *c = config_get()->categories;
 struct category *category = ((void *)0);
 struct category *prev = ((void *)0);
 while( c ) {
  category = malloc( sizeof(struct category) );
  if( category ) {
   memset( category, 0, sizeof(struct category) );
   category->id = c->id;
   if( category->id == 0 )
    category->name = (char *)config_get()->iface.labels.label_lists;
   else
    category->name = c->name;
   prev = category_start;
   if( category_start ) {
    prev = category_start->prev;
    while( strcasecmp( prev->name, category->name ) > 0 ) {
     prev = prev->prev;
     if( prev == category_start->prev ) break;
    }
   }
   category_add( category, prev );
   if( !category_start || strcasecmp( category->name, category_start->name ) < 0 ) {
    category_start = category;
   }
   if( c->values ) {
    struct config_category_value *value = c->values;
    category->values = ((void *)0);
    while( value ) {
     category_value_add( category, (char *)lookup_category( c, value->name ) );
     value = value->next;
    }
   }
  }
  else {
   fprintf( stderr, "Error: Couldn't allocate memeory for category object\n" );
   return -1;
  }
  c = c->next;
 }
 return 0;
}

variable_types: struct config_category { struct config_category *next; int id; char name[128]; struct config_category_value { struct config_category_value *next; char name[128]; } *values; struct config_lookup { struct config_lookup *next; char match[32]; char value[32]; } *lookups; } *


decompiled_code:
int catgeory_dump()
{
__int64 v0; // rbp
int result; // eax
__int64 *v2; // rbx

v0 = category_start;
do
{
if ( !v0 )
break;
result = printf("Category: %s (%d)\n", *(const char **)(v0 + 32), *(unsigned int *)(v0 + 40));
v2 = *(__int64 **)(v0 + 16);
do
{
if ( !v2 )
break;
result = printf(" Value: %s\n", (const char *)v2[2]);
v2 = (__int64 *)*v2;
}
while ( *(__int64 **)(v0 + 16) != v2 );
v0 = *(_QWORD *)v0;
}
while ( category_start != v0 );
return result;
}

canonical_decompiled_code:
int func5()
{
__int64 v0; // rbp
int result; // eax
__int64 *v2; // rbx

v0 = category_start;
do
{
if ( !v0 )
break;
result = printf("Category: %s (%d)\n", *(const char **)(v0 + 32), *(unsigned int *)(v0 + 40));
v2 = *(__int64 **)(v0 + 16);
do
{
if ( !v2 )
break;
result = printf(" Value: %s\n", (const char *)v2[2]);
v2 = (__int64 *)*v2;
}
while ( *(__int64 **)(v0 + 16) != v2 );
v0 = *(_QWORD *)v0;
}
while ( category_start != v0 );
return result;
}

original_code:
void catgeory_dump( void ) {
 struct category *category = category_start;
 while( category ) {
  printf("Category: %s (%d)\n", category->name, category->value_count );
  struct category_value *value = category->values;
  while( value ) {
   printf("  Value: %s\n", value->name );
   value = value->next;
   if( value == category->values ) break;
  }
  category = category->next;
  if( category == category_start ) break;
 }
}

canonical_original_code:
void catgeory_dump() {
 struct category *category = category_start;
 while( category ) {
  printf("Category: %s (%d)\n", category->name, category->value_count );
  struct category_value *value = category->values;
  while( value ) {
   printf("  Value: %s\n", value->name );
   value = value->next;
   if( value == category->values ) break;
  }
  category = category->next;
  if( category == category_start ) break;
 }
}


decompiled_code:
__int64 category_first()
{
return category_start;
}

canonical_decompiled_code:
__int64 func6()
{
return category_start;
}

original_code:
struct category *category_first( void ) {
 return category_start;
}

canonical_original_code:
struct category *category_first() {
 return category_start;
}

return_type: struct category { struct category *next; struct category *prev; struct category_value { struct category_value *next; struct category_value *prev; char *name; } *values; int id; char *name; int value_count; int has_unknowns; } *


decompiled_code:
__int64 __fastcall category_get(char *s2)
{
__int64 v1; // rbx
__int64 v2; // r12

if ( !s2 )
return 0LL;
v1 = 0LL;
if ( *s2 )
{
v2 = category_start;
if ( category_start )
{
v1 = category_start;
while ( strcasecmp(*(const char **)(v1 + 32), s2) )
{
if ( *(_QWORD *)(v2 + 8) == v1 )
return 0LL;
v1 = *(_QWORD *)v1;
if ( !v1 )
return v1;
}
}
else
{
v1 = category_start;
}
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func7(char *s2)
{
__int64 v1; // rbx
__int64 v2; // r12

if ( !s2 )
return 0LL;
v1 = 0LL;
if ( *s2 )
{
v2 = category_start;
if ( category_start )
{
v1 = category_start;
while ( strcasecmp(*(const char **)(v1 + 32), s2) )
{
if ( *(_QWORD *)(v2 + 8) == v1 )
return 0LL;
v1 = *(_QWORD *)v1;
if ( !v1 )
return v1;
}
}
else
{
v1 = category_start;
}
}
return v1;
}

original_code:
struct category *category_get( const char *name ) {
 struct category *g = category_start;
 if( name && *name ) {
  while( g ) {
   if( strcasecmp( g->name, name ) == 0 )
    return g;
   if( g == category_start->prev ) break;
   g = g->next;
  }
 }
 return ((void *)0);
}

canonical_original_code:
struct category *category_get(char *name) {
 struct category *g = category_start;
 if( name && *name ) {
  while( g ) {
   if( strcasecmp( g->name, name ) == 0 )
    return g;
   if( g == category_start->prev ) break;
   g = g->next;
  }
 }
 return ((void *)0);
}


decompiled_code:
__int64 font_init()
{
__int64 v0; // rbx
int v1; // er12
unsigned int v2; // ebp
const char *v4; // rax
const char *v5; // rbx
const char *v6; // rax

v0 = config_get();
v1 = *(_DWORD *)(v0 + 2496);
if ( v1 <= 0 )
v1 = 50;
LOWORD(col) = *(_WORD *)(v0 + 2500);
BYTE2(col) = *(_BYTE *)(v0 + 2502);
if ( (unsigned int)TTF_Init() )
{
v4 = (const char *)SDL_GetError();
fprintf(stderr, "Error: Couldn't initialise font library: %s\n", v4);
v2 = -1;
}
else
{
v2 = 0;
if ( *(_BYTE *)(v0 + 2240) )
{
v5 = (const char *)(v0 + 2240);
font = TTF_OpenFont(v5, (unsigned int)v1);
if ( !font )
{
v6 = (const char *)SDL_GetError();
fprintf(stderr, "Error: Couldn't load font '%s': %s\n", v5, v6);
v2 = -1;
}
}
}
return v2;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 v0; // rbx
int v1; // er12
unsigned int v2; // ebp
const char *v4; // rax
const char *v5; // rbx
const char *v6; // rax

v0 = config_get();
v1 = *(_DWORD *)(v0 + 2496);
if ( v1 <= 0 )
v1 = 50;
LOWORD(col) = *(_WORD *)(v0 + 2500);
BYTE2(col) = *(_BYTE *)(v0 + 2502);
if ( (unsigned int)TTF_Init() )
{
v4 = (const char *)SDL_GetError();
fprintf(stderr, "Error: Couldn't initialise font library: %s\n", v4);
v2 = -1;
}
else
{
v2 = 0;
if ( *(_BYTE *)(v0 + 2240) )
{
v5 = (const char *)(v0 + 2240);
font = TTF_OpenFont(v5, (unsigned int)v1);
if ( !font )
{
v6 = (const char *)SDL_GetError();
fprintf(stderr, "Error: Couldn't load font '%s': %s\n", v5, v6);
v2 = -1;
}
}
}
return v2;
}

original_code:
int font_init( void ) {
 const struct config *config = config_get();
 int size;
 if( config->iface.theme.font_size > 0 )
  size = config->iface.theme.font_size;
 else
  size = DEFAULT_FONT_SIZE;
 col.r = config->iface.theme.font_rgb.red;
 col.g = config->iface.theme.font_rgb.green;
 col.b = config->iface.theme.font_rgb.blue;
 if( TTF_Init() != 0 ) {
  fprintf( stderr, "Error: Couldn't initialise font library: %s\n", SDL_GetError() );
  return -1;
 }
 if( config->iface.theme.font_file && *config->iface.theme.font_file ) {
  font = TTF_OpenFont( config->iface.theme.font_file, size );
  if( font == ((void *)0) ) {
   fprintf( stderr, "Error: Couldn't load font '%s': %s\n", config->iface.theme.font_file, SDL_GetError() );
   return -1;
  }
 }
 return 0;
}

canonical_original_code:
int font_init() {
 struct config *config = config_get();
 int size;
 if( config->iface.theme.font_size > 0 )
  size = config->iface.theme.font_size;
 else
  size = DEFAULT_FONT_SIZE;
 col.r = config->iface.theme.font_rgb.red;
 col.g = config->iface.theme.font_rgb.green;
 col.b = config->iface.theme.font_rgb.blue;
 if( TTF_Init() != 0 ) {
  fprintf( stderr, "Error: Couldn't initialise font library: %s\n", SDL_GetError() );
  return -1;
 }
 if( config->iface.theme.font_file && *config->iface.theme.font_file ) {
  font = TTF_OpenFont( config->iface.theme.font_file, size );
  if( font == ((void *)0) ) {
   fprintf( stderr, "Error: Couldn't load font '%s': %s\n", config->iface.theme.font_file, SDL_GetError() );
   return -1;
  }
 }
 return 0;
}

variable_types: struct config { struct config_emulator { struct config_emulator *next; int id; char name[128]; char display_name[128]; char executable[256]; char directory[256]; int is_default; struct config_param { struct config_param *next; char name[64]; char value[64]; } *params; struct config_platform { struct config_platform *next; char name[128]; } *platform; } *emulators; struct config_platform *platforms; struct config_category { struct config_category *next; int id; char name[128]; struct config_category_value { struct config_category_value *next; char name[128]; } *values; struct config_lookup { struct config_lookup *next; char match[32]; char value[32]; } *lookups; } *categories; struct config_game { struct config_game *next; char name[128]; char rom_image[256]; char video[256]; char emulator[128]; struct config_game_category { struct config_game_category *next; struct config_category *category; struct config_category_value *value; } *categories; struct config_param *params; struct config_platform *platform; struct config_image { struct config_image *next; struct config_image_type { struct config_image_type *next; char name[128]; } *type; char file_name[256]; } *images; } *games; struct config_theme { struct config_theme *next; char name[128]; char directory[256]; char background_image[256]; int background_rotation; int background_transparency; char sounds[-1][256]; char font_file[256]; int font_size; struct config_rgb { unsigned char red; unsigned char green; unsigned char blue; } font_rgb; struct config_menu { char texture[256]; float item_width; float item_height; float font_scale; float zoom; int transparency; float offset1; float offset2; int max_visible; float spacing; int orientation; int auto_hide; int border; } menu; struct config_submenu { char texture[256]; float item_width; float item_height; float font_scale; float offset1; float offset2; } submenu; struct config_game_sel { float offset1; float offset2; float size_x; float size_y; float tile_size; int orientation; int selected; struct config_game_sel_tile { struct config_game_sel_tile *next; int order; float pos[3]; float angle[3]; int transparency; } *tiles; } game_sel; struct config_snap { float offset1; float offset2; float angle_x; float angle_y; float angle_z; float size; int fix_aspect_ratio; int auto_hide; int platform_icons; } snap; struct config_hints { float offset1; float offset2; float size; float spacing; int pulse; char image_back[256]; char image_select[256]; char image_arrow[256]; } hints; } *themes; struct config_image_type *image_types; struct config_location { struct config_location *next; struct config_location_type { struct config_location_type *next; char name[128]; } *type; char directory[256]; } *locations; struct config_location_type *location_types; struct config_iface { int full_screen; int screen_width; int screen_height; int screen_rotation; int screen_hflip; int screen_vflip; int frame_rate; int gfx_quality; int gfx_max_width; int gfx_max_height; int prune_menus; struct config_labels { char label_all[32]; char label_platform[32]; char label_back[32]; char label_select[32]; char label_lists[32]; } labels; struct config_control { int device_type; int device_id; int control_type; int control_id; int value; } controls[-1]; char theme_name[128]; struct config_theme theme; } iface; } *

variable_types: size int

user_defined_types: struct config { struct config_emulator *emulators; struct config_platform *platforms; struct config_category *categories; struct config_game *games; struct config_theme *themes; struct config_image_type *image_types; struct config_location *locations; struct config_location_type *location_types; struct config_iface iface; }

user_defined_types: struct config_iface { int full_screen; int screen_width; int screen_height; int screen_rotation; int screen_hflip; int screen_vflip; int frame_rate; int gfx_quality; int gfx_max_width; int gfx_max_height; int prune_menus; struct config_labels labels; struct config_control controls[-1]; char theme_name[128]; struct config_theme theme; }

user_defined_types: struct config_theme { struct config_theme *next; char name[128]; char directory[256]; char background_image[256]; int background_rotation; int background_transparency; char sounds[-1][256]; char font_file[256]; int font_size; struct config_rgb font_rgb; struct config_menu menu; struct config_submenu submenu; struct config_game_sel game_sel; struct config_snap snap; struct config_hints hints; }

user_defined_types: struct config_location { struct config_location *next; struct config_location_type *type; char directory[256]; }

user_defined_types: struct config_game_sel { float offset1; float offset2; float size_x; float size_y; float tile_size; int orientation; int selected; struct config_game_sel_tile *tiles; }


decompiled_code:
__int64 font_free()
{
if ( font )
TTF_CloseFont();
return TTF_Quit();
}

canonical_decompiled_code:
__int64 func1()
{
if ( font )
TTF_CloseFont();
return TTF_Quit();
}

original_code:
void font_free( void ) {
 if( font )
  TTF_CloseFont( font );
 TTF_Quit();
}

canonical_original_code:
void font_free() {
 if( font )
  TTF_CloseFont( font );
 TTF_Quit();
}


decompiled_code:
__int64 font_pause()
{
return font_free();
}

canonical_decompiled_code:
__int64 func2()
{
return func1();
}

original_code:
void font_pause( void ) {
 font_free();
}

canonical_original_code:
void font_pause() {
 font_free();
}


decompiled_code:
__int64 font_resume()
{
return font_init();
}

canonical_decompiled_code:
__int64 func3()
{
return func0();
}

original_code:
int font_resume( void ) {
 return font_init();
}

canonical_original_code:
int font_resume() {
 return font_init();
}


supress

decompiled_code:
__int64 supress()
{
__int64 result; // rax

result = (unsigned int)(*(_DWORD *)(config_get() + 88) / 5);
supress_wait = result;
return result;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 result; // rax

result = (unsigned int)(*(_DWORD *)(config_get() + 88) / 5);
supress_wait = result;
return result;
}

original_code:
void supress( void ) {
 supress_wait = config_get()->iface.frame_rate / 5;
}

canonical_original_code:
void supress() {
 supress_wait = config_get()->iface.frame_rate / 5;
}


decompiled_code:
__int64 clean_up()
{
sound_free();
game_list_free();
submenu_free();
platform_free();
menu_free();
hint_free();
font_free();
bg_free();
location_free();
event_free();
snap_free();
video_free();
return sdl_free();
}

canonical_decompiled_code:
__int64 func1()
{
sound_free();
game_list_free();
submenu_free();
platform_free();
menu_free();
hint_free();
font_free();
bg_free();
location_free();
event_free();
snap_free();
video_free();
return sdl_free();
}

original_code:
void clean_up( void ) {
 sound_free();
 game_list_free();
 submenu_free();
 platform_free();
 menu_free();
 hint_free();
 font_free();
 bg_free();
 location_free();
 event_free();
 snap_free();
 video_free();
 sdl_free();
}

canonical_original_code:
void clean_up() {
 sound_free();
 game_list_free();
 submenu_free();
 platform_free();
 menu_free();
 hint_free();
 font_free();
 bg_free();
 location_free();
 event_free();
 snap_free();
 video_free();
 sdl_free();
}


bail

decompiled_code:
void __noreturn bail()
{
clean_up();
exit(-1);
}

canonical_decompiled_code:
void __noreturn func2()
{
func1();
exit(-1);
}

original_code:
void bail( void ) {
 clean_up();
 exit( -1 );
}

canonical_original_code:
void bail() {
 clean_up();
 exit( -1 );
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebp
unsigned int v4; // eax
unsigned int v5; // ebx

v3 = config_open(0LL, argv, envp);
if ( v3 != -1 )
{
if ( (unsigned int)sdl_init() )
bail();
if ( (unsigned int)ogl_init() )
bail();
ogl_clear();
sdl_swap();
if ( (unsigned int)event_init() )
bail();
if ( (unsigned int)font_init() )
bail();
if ( v3 != 1 )
goto LABEL_7;
if ( (unsigned int)setup() )
return -1;
config_update();
if ( !(unsigned int)config_create() )
{
LABEL_7:
location_init();
font_free();
font_init();
bg_init();
bg_clear();
bg_draw();
sdl_swap();
if ( (unsigned int)platform_init() )
bail();
if ( (unsigned int)category_init() )
bail();
if ( (unsigned int)game_sel_init() )
bail();
if ( (unsigned int)hint_init() )
bail();
if ( (unsigned int)snap_init() )
bail();
if ( (unsigned int)game_list_create() )
bail();
if ( (unsigned int)menu_init(0LL) )
bail();
if ( (unsigned int)submenu_init() )
bail();
sound_init();
video_init();
event_flush();
if ( !*(_DWORD *)(config_get() + 2800) )
menu_show();
focus_set(2LL);
while ( 1 )
{
ogl_clear();
bg_draw();
snap_draw();
hint_draw();
menu_draw();
submenu_draw();
game_sel_draw();
sdl_swap();
v4 = event_poll();
v5 = v4;
if ( v4 )
{
v3 = supress_wait;
if ( !supress_wait )
{
if ( v4 == 7 )
{
sdl_frame_delay();
clean_up();
return v3;
}
supress();
event_process(v5);
}
}
if ( supress_wait > 0 )
--supress_wait;
sdl_frame_delay();
}
}
v3 = -1;
}
return v3;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebp
unsigned int v4; // eax
unsigned int v5; // ebx

v3 = config_open(0LL, argv, envp);
if ( v3 != -1 )
{
if ( (unsigned int)sdl_init() )
func2();
if ( (unsigned int)ogl_init() )
func2();
ogl_clear();
sdl_swap();
if ( (unsigned int)event_init() )
func2();
if ( (unsigned int)font_init() )
func2();
if ( v3 != 1 )
goto LABEL_7;
if ( (unsigned int)setup() )
return -1;
config_update();
if ( !(unsigned int)config_create() )
{
LABEL_7:
location_init();
font_free();
font_init();
bg_init();
bg_clear();
bg_draw();
sdl_swap();
if ( (unsigned int)platform_init() )
func2();
if ( (unsigned int)category_init() )
func2();
if ( (unsigned int)game_sel_init() )
func2();
if ( (unsigned int)hint_init() )
func2();
if ( (unsigned int)snap_init() )
func2();
if ( (unsigned int)game_list_create() )
func2();
if ( (unsigned int)menu_init(0LL) )
func2();
if ( (unsigned int)submenu_init() )
func2();
sound_init();
video_init();
event_flush();
if ( !*(_DWORD *)(config_get() + 2800) )
menu_show();
focus_set(2LL);
while ( 1 )
{
ogl_clear();
bg_draw();
snap_draw();
hint_draw();
menu_draw();
submenu_draw();
game_sel_draw();
sdl_swap();
v4 = event_poll();
v5 = v4;
if ( v4 )
{
v3 = supress_wait;
if ( !supress_wait )
{
if ( v4 == 7 )
{
sdl_frame_delay();
func1();
return v3;
}
func0();
event_process(v5);
}
}
if ( supress_wait > 0 )
--supress_wait;
sdl_frame_delay();
}
}
v3 = -1;
}
return v3;
}

original_code:
int main( int argc, char *arvg[] ) {
 int quit = 0;
 int config_status = 0;
 int event;
 config_status = config_open( ((void *)0) );
 if( config_status == -1 )
  return -1;
 if( sdl_init() != 0 )
  bail();
 if( ogl_init() != 0 )
  bail();
 ogl_clear();
 sdl_swap();
 if( event_init() != 0 )
  bail();
 if( font_init() != 0 )
  bail();
 if( config_status == 1 ) {
  if( setup() != 0 )
   return -1;
  config_update();
  if( config_create() != 0 )
   return -1;
 }
 location_init();
 font_free();
 font_init();
 bg_init();
 bg_clear();
 bg_draw();
 sdl_swap();
 if( platform_init() != 0 )
  bail();
 if( category_init() != 0 )
  bail();
 if( game_sel_init() != 0 )
  bail();
 if( hint_init() != 0 )
  bail();
 if( snap_init() != 0 )
  bail();
 if( game_list_create() != 0 )
  bail();
 if( menu_init() != 0 )
  bail();
 if( submenu_init() != 0 )
  bail();
 sound_init();
 video_init();
 event_flush();
 if( !config_get()->iface.theme.menu.auto_hide )
  menu_show();
 focus_set( FOCUS_GAMESEL );
 while( !quit ) {
  ogl_clear();
  bg_draw();
  snap_draw();
  hint_draw();
  menu_draw();
  submenu_draw();
  game_sel_draw();
  sdl_swap();
  if (( event = event_poll() )) {
   if( supress_wait == 0 ) {
    if( event == EVENT_QUIT ) {
     quit = 1;
    }
    else {
     supress();
     event_process( event );
    }
   }
  }
  if( supress_wait > 0 )
   supress_wait--;
  sdl_frame_delay();
 }
 clean_up();
 return 0;
}

canonical_original_code:
int main(int argc, char *arvg[]) {
 int quit = 0;
 int config_status = 0;
 int event;
 config_status = config_open( ((void *)0) );
 if( config_status == -1 )
  return -1;
 if( sdl_init() != 0 )
  bail();
 if( ogl_init() != 0 )
  bail();
 ogl_clear();
 sdl_swap();
 if( event_init() != 0 )
  bail();
 if( font_init() != 0 )
  bail();
 if( config_status == 1 ) {
  if( setup() != 0 )
   return -1;
  config_update();
  if( config_create() != 0 )
   return -1;
 }
 location_init();
 font_free();
 font_init();
 bg_init();
 bg_clear();
 bg_draw();
 sdl_swap();
 if( platform_init() != 0 )
  bail();
 if( category_init() != 0 )
  bail();
 if( game_sel_init() != 0 )
  bail();
 if( hint_init() != 0 )
  bail();
 if( snap_init() != 0 )
  bail();
 if( game_list_create() != 0 )
  bail();
 if( menu_init() != 0 )
  bail();
 if( submenu_init() != 0 )
  bail();
 sound_init();
 video_init();
 event_flush();
 if( !config_get()->iface.theme.menu.auto_hide )
  menu_show();
 focus_set( FOCUS_GAMESEL );
 while( !quit ) {
  ogl_clear();
  bg_draw();
  snap_draw();
  hint_draw();
  menu_draw();
  submenu_draw();
  game_sel_draw();
  sdl_swap();
  if (( event = event_poll() )) {
   if( supress_wait == 0 ) {
    if( event == EVENT_QUIT ) {
     quit = 1;
    }
    else {
     supress();
     event_process( event );
    }
   }
  }
  if( supress_wait > 0 )
   supress_wait--;
  sdl_frame_delay();
 }
 clean_up();
 return 0;
}

variable_types: argc int

variable_types:
arvg
char *[]

variable_types: quit int

variable_types: event int


decompiled_code:
__int64 location_init()
{
_QWORD *i; // rbp
_QWORD *v2; // rbx
_QWORD *v3; // rax
_QWORD *v4; // r12

for ( i = *(_QWORD **)(config_get() + 56); i; i = (_QWORD *)*i )
{
v4 = malloc(0x18uLL);
if ( v4 )
{
v2 = *(_QWORD **)(config_get() + 48);
v4[1] = 0LL;
for ( v4[2] = i + 1; v2; v2 = (_QWORD *)*v2 )
{
if ( (_QWORD *)v2[1] == i )
{
v3 = malloc(0x10uLL);
if ( v3 )
{
v3[1] = v2 + 2;
*v3 = v4[1];
v4[1] = v3;
}
else
{
fwrite("Warning: Couldn't allocate memory for location\n", 1uLL, 0x2FuLL, stderr);
}
}
}
*v4 = type_start;
type_start = v4;
}
else
{
fwrite("Warning: Couldn't allocate memory for location type\n", 1uLL, 0x34uLL, stderr);
}
}
return 0LL;
}

canonical_decompiled_code:
__int64 func0()
{
_QWORD *i; // rbp
_QWORD *v2; // rbx
_QWORD *v3; // rax
_QWORD *v4; // r12

for ( i = *(_QWORD **)(config_get() + 56); i; i = (_QWORD *)*i )
{
v4 = malloc(0x18uLL);
if ( v4 )
{
v2 = *(_QWORD **)(config_get() + 48);
v4[1] = 0LL;
for ( v4[2] = i + 1; v2; v2 = (_QWORD *)*v2 )
{
if ( (_QWORD *)v2[1] == i )
{
v3 = malloc(0x10uLL);
if ( v3 )
{
v3[1] = v2 + 2;
*v3 = v4[1];
v4[1] = v3;
}
else
{
fwrite("Warning: Couldn't allocate memory for location\n", 1uLL, 0x2FuLL, stderr);
}
}
}
*v4 = type_start;
type_start = v4;
}
else
{
fwrite("Warning: Couldn't allocate memory for location type\n", 1uLL, 0x34uLL, stderr);
}
}
return 0LL;
}

original_code:
int location_init( void ) {
 struct config_location_type *config_type = config_get()->location_types;
 while( config_type ) {
  struct location_type *type = malloc( sizeof(struct location_type) );
  if( type ) {
   struct config_location *config_location = config_get()->locations;
   type->locations = ((void *)0);
   type->name = config_type->name;
   while( config_location ) {
    if( config_location->type == config_type ) {
     struct location *location = malloc( sizeof(struct location) );
     if( location ) {
      location->directory = config_location->directory;
      location->next = type->locations;
      type->locations = location;
     }
     else {
      fprintf( stderr, "Warning: Couldn't allocate memory for location\n" );
     }
    }
    config_location = config_location->next;
   }
   type->next = type_start;
   type_start = type;
  }
  else {
   fprintf( stderr, "Warning: Couldn't allocate memory for location type\n" );
  }
  config_type = config_type->next;
 }
 return 0;
}

canonical_original_code:
int location_init() {
 struct config_location_type *config_type = config_get()->location_types;
 while( config_type ) {
  struct location_type *type = malloc( sizeof(struct location_type) );
  if( type ) {
   struct config_location *config_location = config_get()->locations;
   type->locations = ((void *)0);
   type->name = config_type->name;
   while( config_location ) {
    if( config_location->type == config_type ) {
     struct location *location = malloc( sizeof(struct location) );
     if( location ) {
      location->directory = config_location->directory;
      location->next = type->locations;
      type->locations = location;
     }
     else {
      fprintf( stderr, "Warning: Couldn't allocate memory for location\n" );
     }
    }
    config_location = config_location->next;
   }
   type->next = type_start;
   type_start = type;
  }
  else {
   fprintf( stderr, "Warning: Couldn't allocate memory for location type\n" );
  }
  config_type = config_type->next;
 }
 return 0;
}

variable_types: struct location_type { struct location_type *next; struct location { struct location *next; char *directory; } *locations; char *name; } *

variable_types: struct config_location { struct config_location *next; struct config_location_type { struct config_location_type *next; char name[128]; } *type; char directory[256]; } *

user_defined_types: struct location_type { struct location_type *next; struct location *locations; char *name; }


decompiled_code:
void location_free()
{
_QWORD *v0; // rbp
_QWORD *v1; // r12
_QWORD *v2; // rbx
void *v3; // rdi

v0 = type_start;
if ( type_start )
{
do
{
v1 = v0;
v0 = (_QWORD *)*v0;
v2 = (_QWORD *)v1[1];
while ( v2 )
{
v3 = v2;
v2 = (_QWORD *)*v2;
free(v3);
}
free(v1);
}
while ( v0 );
}
}

canonical_decompiled_code:
void func1()
{
_QWORD *v0; // rbp
_QWORD *v1; // r12
_QWORD *v2; // rbx
void *v3; // rdi

v0 = type_start;
if ( type_start )
{
do
{
v1 = v0;
v0 = (_QWORD *)*v0;
v2 = (_QWORD *)v1[1];
while ( v2 )
{
v3 = v2;
v2 = (_QWORD *)*v2;
free(v3);
}
free(v1);
}
while ( v0 );
}
}

original_code:
void location_free( void ) {
 struct location_type *type = type_start;
 while( type ) {
  struct location_type *ttmp = type->next;
  struct location *location = type->locations;
  while( location ) {
   struct location *ltmp = location->next;
   free( location );
   location = ltmp;
  }
  free( type );
  type = ttmp;
 }
}

canonical_original_code:
void location_free() {
 struct location_type *type = type_start;
 while( type ) {
  struct location_type *ttmp = type->next;
  struct location *location = type->locations;
  while( location ) {
   struct location *ltmp = location->next;
   free( location );
   location = ltmp;
  }
  free( type );
  type = ttmp;
 }
}

variable_types: struct location { struct location *next; char *directory; } *


decompiled_code:
const char *__fastcall location_get_first(char *s2)
{
const char *v1; // rbx

v1 = (const char *)type_start;
if ( type_start )
{
while ( strcasecmp(*((const char **)v1 + 2), s2) )
{
v1 = *(const char **)v1;
if ( !v1 )
return v1;
}
v1 = (const char *)*((_QWORD *)v1 + 1);
}
return v1;
}

canonical_decompiled_code:
const char *__fastcall func2(char *s2)
{
const char *v1; // rbx

v1 = (const char *)type_start;
if ( type_start )
{
while ( strcasecmp(*((const char **)v1 + 2), s2) )
{
v1 = *(const char **)v1;
if ( !v1 )
return v1;
}
v1 = (const char *)*((_QWORD *)v1 + 1);
}
return v1;
}

original_code:
struct location *location_get_first( const char *type ) {
 struct location_type *ltype = type_start;
 while( ltype ) {
  if( strcasecmp( ltype->name, type ) == 0 )
   return ltype->locations;
  ltype = ltype->next;
 }
 return ((void *)0);
}

canonical_original_code:
struct location *location_get_first(char *type) {
 struct location_type *ltype = type_start;
 while( ltype ) {
  if( strcasecmp( ltype->name, type ) == 0 )
   return ltype->locations;
  ltype = ltype->next;
 }
 return ((void *)0);
}

variable_types:
type
char *

return_type: struct location { struct location *next; char *directory; } *


decompiled_code:
__int64 __fastcall location_absolute(_BYTE *a1)
{
return (unsigned int)-(*a1 != 47);
}

canonical_decompiled_code:
__int64 __fastcall func3(_BYTE *a1)
{
return (unsigned int)-(*a1 != 47);
}

original_code:
int location_absolute( const char *filename ) {
  if( filename[0] == '/' ) {
   return 0;
  }
  return -1;
}

canonical_original_code:
int location_absolute(char *filename) {
  if( filename[0] == '/' ) {
   return 0;
  }
  return -1;
}

variable_types:
filename
char *


decompiled_code:
__int64 __fastcall location_try_directory(const char *a1, const char *a2, char *a3)
{
unsigned int v4; // ebx
int v5; // edi
char *v7; // rax
struct stat v8; // [rsp+0h] [rbp-1A8h] BYREF
char s[280]; // [rsp+90h] [rbp-118h] BYREF

if ( !a1 || !a2 )
return (unsigned int)-1;
snprintf(s, 0x100uLL, "%s/%s", a1, a2);
v4 = stat(s, &v8);
if ( v4 == -1 )
{
v5 = *_errno_location();
if ( v5 != 2 )
{
v7 = strerror(v5);
fprintf(stderr, "Warning: Couldn't stat file '%s': %s\n", s, v7);
}
}
else
{
strncpy(a3, s, 0x100uLL);
v4 = 0;
}
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func4(const char *a1, const char *a2, char *a3)
{
unsigned int v4; // ebx
int v5; // edi
char *v7; // rax
struct stat v8; // [rsp+0h] [rbp-1A8h] BYREF
char s[280]; // [rsp+90h] [rbp-118h] BYREF

if ( !a1 || !a2 )
return (unsigned int)-1;
snprintf(s, 0x100uLL, "%s/%s", a1, a2);
v4 = stat(s, &v8);
if ( v4 == -1 )
{
v5 = *_errno_location();
if ( v5 != 2 )
{
v7 = strerror(v5);
fprintf(stderr, "Warning: Couldn't stat file '%s': %s\n", s, v7);
}
}
else
{
strncpy(a3, s, 0x100uLL);
v4 = 0;
}
return v4;
}

original_code:
int location_try_directory( const char *dir, const char *filename, char *path ) {
 char test[256];
 struct stat stmp;
 if( dir && filename ) {
  snprintf( test, 256, "%s/%s", dir, filename );
  if( stat( test, &stmp ) == -1 ) {
   if( (*__errno_location ()) != 2 ) {
    fprintf( stderr, "Warning: Couldn't stat file '%s': %s\n", test, strerror( (*__errno_location ()) ) );
    return -1;
   }
  }
  else {
   strncpy( path, test, 256 );
   return 0;
  }
 }
 return -1;
}

canonical_original_code:
int location_try_directory(char *dir, char *filename, char *path) {
 char test[256];
 struct stat stmp;
 if( dir && filename ) {
  snprintf( test, 256, "%s/%s", dir, filename );
  if( stat( test, &stmp ) == -1 ) {
   if( (*__errno_location ()) != 2 ) {
    fprintf( stderr, "Warning: Couldn't stat file '%s': %s\n", test, strerror( (*__errno_location ()) ) );
    return -1;
   }
  }
  else {
   strncpy( path, test, 256 );
   return 0;
  }
 }
 return -1;
}

variable_types:
dir
char *

variable_types:
path
char *

variable_types:
test
char [256]

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; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }

user_defined_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; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


decompiled_code:
__int64 __fastcall location_get_path(char *a1, char *a2, char *a3)
{
const char *v4; // rax
const char *v5; // rbp
unsigned int v6; // ebx

v4 = location_get_first(a1);
if ( !a1 )
return (unsigned int)-1;
v5 = v4;
if ( !a2 )
return (unsigned int)-1;
if ( !*a2 )
return (unsigned int)-1;
v6 = location_absolute(a2);
if ( v6 )
{
if ( v5 )
{
while ( 1 )
{
v6 = location_try_directory(*((const char **)v5 + 1), a2, a3);
if ( !v6 )
break;
v5 = *(const char **)v5;
if ( !v5 )
goto LABEL_8;
}
}
else
{
LABEL_8:
strncpy(a3, a2, 0x100uLL);
v6 = -1;
}
}
else
{
strncpy(a3, a2, 0x100uLL);
}
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func5(char *a1, char *a2, char *a3)
{
const char *v4; // rax
const char *v5; // rbp
unsigned int v6; // ebx

v4 = func2(a1);
if ( !a1 )
return (unsigned int)-1;
v5 = v4;
if ( !a2 )
return (unsigned int)-1;
if ( !*a2 )
return (unsigned int)-1;
v6 = func3(a2);
if ( v6 )
{
if ( v5 )
{
while ( 1 )
{
v6 = func4(*((const char **)v5 + 1), a2, a3);
if ( !v6 )
break;
v5 = *(const char **)v5;
if ( !v5 )
goto LABEL_8;
}
}
else
{
LABEL_8:
strncpy(a3, a2, 0x100uLL);
v6 = -1;
}
}
else
{
strncpy(a3, a2, 0x100uLL);
}
return v6;
}

original_code:
int location_get_path( const char *type, const char *filename, char *path ) {
 struct location *location = location_get_first( type );
 if( type && filename && filename[0]) {
  if( location_absolute( filename ) == 0 ) {
   strncpy( path, filename, 256 );
   return 0;
  }
  while( location ) {
   if( location_try_directory( location->directory, filename, path ) == 0 ) {
    return 0;
   }
   location = location->next;
  }
  strncpy( path, filename, 256 );
 }
 return -1;
}

canonical_original_code:
int location_get_path(char *type, char *filename, char *path) {
 struct location *location = location_get_first( type );
 if( type && filename && filename[0]) {
  if( location_absolute( filename ) == 0 ) {
   strncpy( path, filename, 256 );
   return 0;
  }
  while( location ) {
   if( location_try_directory( location->directory, filename, path ) == 0 ) {
    return 0;
   }
   location = location->next;
  }
  strncpy( path, filename, 256 );
 }
 return -1;
}

user_defined_types: struct location { struct location *next; char *directory; }


decompiled_code:
__int64 __fastcall location_get_theme_path(char *src, char *dest)
{
unsigned int v2; // ebx
__int64 v3; // rax

if ( !src )
return (unsigned int)-1;
v2 = location_absolute(src);
if ( v2 )
{
v3 = config_get();
v2 = location_try_directory((const char *)(v3 + 696), src, dest);
if ( v2 )
{
strncpy(dest, src, 0x100uLL);
v2 = -1;
}
}
else
{
strncpy(dest, src, 0x100uLL);
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func6(char *src, char *dest)
{
unsigned int v2; // ebx
__int64 v3; // rax

if ( !src )
return (unsigned int)-1;
v2 = func3(src);
if ( v2 )
{
v3 = config_get();
v2 = func4((const char *)(v3 + 696), src, dest);
if ( v2 )
{
strncpy(dest, src, 0x100uLL);
v2 = -1;
}
}
else
{
strncpy(dest, src, 0x100uLL);
}
return v2;
}

original_code:
int location_get_theme_path( const char *filename, char *path ) {
 if( filename ) {
  if( location_absolute( filename ) == 0 ) {
   strncpy( path, filename, 256 );
   return 0;
  }
  if( location_try_directory( config_get()->iface.theme.directory, filename, path ) == 0 ) {
   return 0;
  }
  strncpy( path, filename, 256 );
 }
 return -1;
}

canonical_original_code:
int location_get_theme_path(char *filename, char *path) {
 if( filename ) {
  if( location_absolute( filename ) == 0 ) {
   strncpy( path, filename, 256 );
   return 0;
  }
  if( location_try_directory( config_get()->iface.theme.directory, filename, path ) == 0 ) {
   return 0;
  }
  strncpy( path, filename, 256 );
 }
 return -1;
}


decompiled_code:
__int64 __fastcall setup_draw_msg(unsigned int *a1, float a2, float a3)
{
double v3; // xmm0_8

ogl_load_alterego();
glTranslatef(0.0, a2, -6.0);
glColor4f(1.0, 1.0, 1.0);
glBlendFunc(770LL, 771LL);
glEnable(3553LL);
glTexEnvf(8960LL, 8704LL, 8448.0);
glBindTexture(3553LL, *a1);
glBegin(7LL);
glTexCoord2f(0.0);
glVertex3f(
COERCE_DOUBLE(COERCE_UNSIGNED_INT((float)((float)(int)a1[1] * a3) * 0.5) ^ (unsigned __int64)LC5),
(float)((float)(int)a1[2] * a3) * 0.5,
0.0);
glTexCoord2f(0.0);
glVertex3f(
COERCE_DOUBLE(COERCE_UNSIGNED_INT((float)((float)(int)a1[1] * a3) * 0.5) ^ (unsigned __int64)LC5),
COERCE_FLOAT(COERCE_UNSIGNED_INT((float)((float)(int)a1[2] * a3) * 0.5) ^ LC5),
0.0);
glTexCoord2f(COERCE_DOUBLE((unsigned __int64)LC2));
glVertex3f(
COERCE_DOUBLE((unsigned __int64)COERCE_UNSIGNED_INT((float)((float)(int)a1[1] * a3) * 0.5)),
COERCE_FLOAT(COERCE_UNSIGNED_INT((float)((float)(int)a1[2] * a3) * 0.5) ^ LC5),
0.0);
glTexCoord2f(COERCE_DOUBLE((unsigned __int64)LC2));
HIDWORD(v3) = 0;
*(float *)&v3 = (float)((float)(int)a1[1] * a3) * 0.5;
glVertex3f(v3, (float)((float)(int)a1[2] * a3) * 0.5, 0.0);
glEnd();
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int *a1, float a2, float a3)
{
double v3; // xmm0_8

ogl_load_alterego();
glTranslatef(0.0, a2, -6.0);
glColor4f(1.0, 1.0, 1.0);
glBlendFunc(770LL, 771LL);
glEnable(3553LL);
glTexEnvf(8960LL, 8704LL, 8448.0);
glBindTexture(3553LL, *a1);
glBegin(7LL);
glTexCoord2f(0.0);
glVertex3f(
COERCE_DOUBLE(COERCE_UNSIGNED_INT((float)((float)(int)a1[1] * a3) * 0.5) ^ (unsigned __int64)LC5),
(float)((float)(int)a1[2] * a3) * 0.5,
0.0);
glTexCoord2f(0.0);
glVertex3f(
COERCE_DOUBLE(COERCE_UNSIGNED_INT((float)((float)(int)a1[1] * a3) * 0.5) ^ (unsigned __int64)LC5),
COERCE_FLOAT(COERCE_UNSIGNED_INT((float)((float)(int)a1[2] * a3) * 0.5) ^ LC5),
0.0);
glTexCoord2f(COERCE_DOUBLE((unsigned __int64)LC2));
glVertex3f(
COERCE_DOUBLE((unsigned __int64)COERCE_UNSIGNED_INT((float)((float)(int)a1[1] * a3) * 0.5)),
COERCE_FLOAT(COERCE_UNSIGNED_INT((float)((float)(int)a1[2] * a3) * 0.5) ^ LC5),
0.0);
glTexCoord2f(COERCE_DOUBLE((unsigned __int64)LC2));
HIDWORD(v3) = 0;
*(float *)&v3 = (float)((float)(int)a1[1] * a3) * 0.5;
glVertex3f(v3, (float)((float)(int)a1[2] * a3) * 0.5, 0.0);
glEnd();
return 0LL;
}

original_code:
int setup_draw_msg( struct texture *msg, GLfloat y, GLfloat scale ) {
 ogl_load_alterego();
 glTranslatef( 0, y, -6 );
 glColor4f( 1.0, 1.0, 1.0, 1.0 );
 glBlendFunc(0x0302,0x0303);
 glEnable(0x0DE1);
 glTexEnvf(0x2300, 0x2200, 0x2100 );
 glBindTexture( 0x0DE1, msg->id );
 glBegin( 0x0007 );
  glTexCoord2f(0.0, 0.0); glVertex3f(-((msg->width*scale)/2), ((msg->height*scale)/2), 0.0);
  glTexCoord2f(0.0, 1.0); glVertex3f(-((msg->width*scale)/2), -((msg->height*scale)/2), 0.0);
  glTexCoord2f(1.0, 1.0); glVertex3f( ((msg->width*scale)/2), -((msg->height*scale)/2), 0.0);
  glTexCoord2f(1.0, 0.0); glVertex3f( ((msg->width*scale)/2), ((msg->height*scale)/2), 0.0);
 glEnd();
 return 0;
}

canonical_original_code:
int setup_draw_msg(struct texture *msg, float y, float scale) {
 ogl_load_alterego();
 glTranslatef( 0, y, -6 );
 glColor4f( 1.0, 1.0, 1.0, 1.0 );
 glBlendFunc(0x0302,0x0303);
 glEnable(0x0DE1);
 glTexEnvf(0x2300, 0x2200, 0x2100 );
 glBindTexture( 0x0DE1, msg->id );
 glBegin( 0x0007 );
  glTexCoord2f(0.0, 0.0); glVertex3f(-((msg->width*scale)/2), ((msg->height*scale)/2), 0.0);
  glTexCoord2f(0.0, 1.0); glVertex3f(-((msg->width*scale)/2), -((msg->height*scale)/2), 0.0);
  glTexCoord2f(1.0, 1.0); glVertex3f( ((msg->width*scale)/2), -((msg->height*scale)/2), 0.0);
  glTexCoord2f(1.0, 0.0); glVertex3f( ((msg->width*scale)/2), ((msg->height*scale)/2), 0.0);
 glEnd();
 return 0;
}

variable_types: struct texture { unsigned int id; int width; int height; } *

variable_types: y float

variable_types: scale float