decompiled_code:
__int64 __fastcall ask_for_session(__int64 *a1, const char *a2)
{
__int64 v4; // rbx
FILE *v5; // r15
char *v6; // rax
FILE *v7; // r15
char *v8; // rax
__int64 v9; // rdi
char *v10; // r15
__int64 v11; // rax
__int64 v12; // rdx
__int64 v13; // r14
_BOOL4 v14; // er15
const char *v15; // rsi
char *v16; // rax
FILE *v17; // r15
char *v18; // rax
unsigned int v19; // eax
const char *v20; // rsi
FILE *v21; // r15
char *v22; // rax
unsigned int v23; // er15
const char *v25; // rbp
int v26; // [rsp+Ch] [rbp-6Ch]
__int64 v27; // [rsp+10h] [rbp-68h] BYREF
char *endptr; // [rsp+18h] [rbp-60h] BYREF
char s[88]; // [rsp+20h] [rbp-58h] BYREF

v27 = 0LL;
if ( a2 )
{
if ( *a2 )
{
v26 = 0;
v4 = sess_session_find_by_path_normalized();
}
else
{
v26 = 1;
v4 = 0LL;
}
}
else
{
v26 = 0;
v4 = 0LL;
}
if ( !no_clear_screen )
goto LABEL_17;
while ( 1 )
{
v5 = stdout;
v6 = dcgettext(0LL, "Welcome, please choose a session!\n", 5);
fputs(v6, v5);
if ( !no_lastsession )
{
v17 = stdout;
v18 = dcgettext(0LL, "Append '!' to the number to prevent remembering your choice.\n\n", 5);
fputs(v18, v17);
}
v7 = stdout;
v8 = dcgettext(0LL, " (0) continue using the current shell\n", 5);
fputs(v8, v7);
v9 = *a1;
sess_num = 1;
g_ptr_array_foreach(v9, display_session, 0LL);
if ( v4 )
{
if ( *(_DWORD *)(v4 + 64) )
v10 = dcgettext(0LL, "\nYour choice [%s]: ", 5);
else
v10 = dcgettext(0LL, "\nYour choice [Text: %s]: ", 5);
v11 = sess_session_get_name_locale(v4);
g_printf(v10, v11, v12);
}
else
{
v20 = "\nYour choice [<current shell>]: ";
v21 = stdout;
if ( !v26 )
v20 = "\nYour choice: ";
v22 = dcgettext(0LL, v20, 5);
fputs(v22, v21);
}
if ( !fgets(s, 32, stdin) )
return 0;
g_strchug(s);
if ( s[0] )
break;
v13 = v4;
v14 = 0;
if ( v4 )
goto LABEL_14;
if ( v26 )
{
LABEL_28:
v23 = no_lastsession | v14;
if ( v23 )
return 0;
LABEL_33:
v25 = &s1;
goto LABEL_34;
}
v15 = "There is no default session! Please make a choice.";
LABEL_16:
v16 = dcgettext(0LL, v15, 5);
puts(v16);
sleep(1u);
if ( !no_clear_screen )
LABEL_17:
terminfo_clear_screen();
}
v19 = strtoul(s, &endptr, 10);
if ( endptr == s )
{
v15 = "Please enter a number.";
goto LABEL_16;
}
v14 = *endptr == 33;
if ( !v19 )
goto LABEL_28;
if ( *(_DWORD *)(*a1 + 8) < v19 )
{
v15 = "No such session. Please try again...";
goto LABEL_16;
}
v13 = *(_QWORD *)(*(_QWORD *)*a1 + 8LL * (v19 - 1));
LABEL_14:
if ( !(unsigned int)process_session(v13) )
{
v15 = "Could not process session! Please try again...";
goto LABEL_16;
}
v23 = no_lastsession | v14;
if ( v23 )
return v13 != 0;
if ( !v13 )
goto LABEL_33;
v23 = 1;
v25 = (const char *)sess_session_get_path_normalized(v13);
LABEL_34:
if ( (!a2 || strcmp(v25, a2)) && !(unsigned int)set_last_session(v25, &v27) )
{
g_log(0LL, 16LL, "Could not save last used session: %s", *(const char **)(v27 + 8));
g_error_free(v27);
}
return v23;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 *a1, const char *a2)
{
__int64 v4; // rbx
FILE *v5; // r15
char *v6; // rax
FILE *v7; // r15
char *v8; // rax
__int64 v9; // rdi
char *v10; // r15
__int64 v11; // rax
__int64 v12; // rdx
__int64 v13; // r14
_BOOL4 v14; // er15
const char *v15; // rsi
char *v16; // rax
FILE *v17; // r15
char *v18; // rax
unsigned int v19; // eax
const char *v20; // rsi
FILE *v21; // r15
char *v22; // rax
unsigned int v23; // er15
const char *v25; // rbp
int v26; // [rsp+Ch] [rbp-6Ch]
__int64 v27; // [rsp+10h] [rbp-68h] BYREF
char *endptr; // [rsp+18h] [rbp-60h] BYREF
char s[88]; // [rsp+20h] [rbp-58h] BYREF

v27 = 0LL;
if ( a2 )
{
if ( *a2 )
{
v26 = 0;
v4 = sess_session_find_by_path_normalized();
}
else
{
v26 = 1;
v4 = 0LL;
}
}
else
{
v26 = 0;
v4 = 0LL;
}
if ( !no_clear_screen )
goto LABEL_17;
while ( 1 )
{
v5 = stdout;
v6 = dcgettext(0LL, "Welcome, please choose a session!\n", 5);
fputs(v6, v5);
if ( !no_lastsession )
{
v17 = stdout;
v18 = dcgettext(0LL, "Append '!' to the number to prevent remembering your choice.\n\n", 5);
fputs(v18, v17);
}
v7 = stdout;
v8 = dcgettext(0LL, " (0) continue using the current shell\n", 5);
fputs(v8, v7);
v9 = *a1;
sess_num = 1;
g_ptr_array_foreach(v9, display_session, 0LL);
if ( v4 )
{
if ( *(_DWORD *)(v4 + 64) )
v10 = dcgettext(0LL, "\nYour choice [%s]: ", 5);
else
v10 = dcgettext(0LL, "\nYour choice [Text: %s]: ", 5);
v11 = sess_session_get_name_locale(v4);
g_printf(v10, v11, v12);
}
else
{
v20 = "\nYour choice [<current shell>]: ";
v21 = stdout;
if ( !v26 )
v20 = "\nYour choice: ";
v22 = dcgettext(0LL, v20, 5);
fputs(v22, v21);
}
if ( !fgets(s, 32, stdin) )
return 0;
g_strchug(s);
if ( s[0] )
break;
v13 = v4;
v14 = 0;
if ( v4 )
goto LABEL_14;
if ( v26 )
{
LABEL_28:
v23 = no_lastsession | v14;
if ( v23 )
return 0;
LABEL_33:
v25 = &s1;
goto LABEL_34;
}
v15 = "There is no default session! Please make a choice.";
LABEL_16:
v16 = dcgettext(0LL, v15, 5);
puts(v16);
sleep(1u);
if ( !no_clear_screen )
LABEL_17:
terminfo_clear_screen();
}
v19 = strtoul(s, &endptr, 10);
if ( endptr == s )
{
v15 = "Please enter a number.";
goto LABEL_16;
}
v14 = *endptr == 33;
if ( !v19 )
goto LABEL_28;
if ( *(_DWORD *)(*a1 + 8) < v19 )
{
v15 = "No such session. Please try again...";
goto LABEL_16;
}
v13 = *(_QWORD *)(*(_QWORD *)*a1 + 8LL * (v19 - 1));
LABEL_14:
if ( !(unsigned int)func3(v13) )
{
v15 = "Could not process session! Please try again...";
goto LABEL_16;
}
v23 = no_lastsession | v14;
if ( v23 )
return v13 != 0;
if ( !v13 )
goto LABEL_33;
v23 = 1;
v25 = (const char *)sess_session_get_path_normalized(v13);
LABEL_34:
if ( (!a2 || strcmp(v25, a2)) && !(unsigned int)set_last_session(v25, &v27) )
{
g_log(0LL, 16LL, "Could not save last used session: %s", *(const char **)(v27 + 8));
g_error_free(v27);
}
return v23;
}

original_code:
gboolean ask_for_session( SessList *session_list, gchar *last_session )
{
    GError *error = ((void *)0);
    unsigned int choice;
    char buf[32];
    char *endptr, *choice_text;
    gchar *session_name;
    SessSession *default_session = ((void *)0);
    SessSession *chosen_session;
    gboolean default_is_current_shell = (0);
    gboolean no_lastsession_override;
    if( last_session )
    {
        if( ! *last_session )
        {
            default_is_current_shell = (!(0));
        }
        else
        {
            default_session = sess_session_find_by_path_normalized( session_list,
                last_session );
        }
    }
    for( ;; )
    {
        if( ! no_clear_screen )
        {
            terminfo_clear_screen();
        }
        fputs( gettext ("Welcome, please choose a session!\n"), stdout );
        if( ! no_lastsession )
        {
            fputs( gettext ("Append '!' to the number to prevent remembering your choice.\n\n"),
                stdout );
        }
        fputs( gettext ("  (0) continue using the current shell\n"), stdout );
        chosen_session = ((void *)0);
        _sess_num = 1;
        no_lastsession_override = (0);
        g_ptr_array_foreach( session_list->list, _display_session, ((void *)0) );
        if( default_session )
        {
            choice_text = default_session->use_xinit
                ? gettext ("\nYour choice [%s]: ")
                : gettext ("\nYour choice [Text: %s]: ");
            g_printf( choice_text,
                sess_session_get_name_locale( default_session ) );
        }
        else if( default_is_current_shell )
        {
            fputs( gettext ("\nYour choice [<current shell>]: "), stdout );
        }
        else {
            fputs( gettext ("\nYour choice: "), stdout );
        }
        if( ! fgets( buf, 32, stdin ) )
        {
            return (0);
        }
        g_strchug( buf );
        if( ! *buf )
        {
            if( default_session )
            {
                chosen_session = default_session;
            }
            else if( ! default_is_current_shell )
            {
                puts( gettext ("There is no default session! Please make a choice.") );
                sleep( 1 );
                continue;
            }
            else
            {
                break;
            }
        }
        else
        {
            choice = strtoul( buf, & endptr, 10 );
            if( endptr == buf )
            {
                puts( gettext ("Please enter a number.") );
                sleep( 1 );
                continue;
            }
            else if( *endptr == '!' )
            {
                no_lastsession_override = (!(0));
            }
            if( ! choice )
            {
                break;
            }
            else if( choice > session_list->list->len )
            {
                puts( gettext ("No such session. Please try again...") );
                sleep( 1 );
                continue;
            }
            chosen_session = ((session_list->list)->pdata)[choice - 1];
        }
        if( process_session( chosen_session ) )
        {
            break;
        }
        puts( gettext ("Could not process session! Please try again...") );
        sleep( 1 );
    }
    if( ! no_lastsession && ! no_lastsession_override )
    {
        session_name = chosen_session
                ? sess_session_get_path_normalized( chosen_session )
                : "";
        if( ( ! last_session || strcmp( session_name, last_session ) != 0 ) &&
            ! set_last_session( session_name, & error ) )
        {
            g_log (((gchar*) 0), G_LOG_LEVEL_WARNING, "Could not save last used session: %s", error->message);
            g_error_free( error );
        }
    }
    return chosen_session ? (!(0)) : (0);
}

canonical_original_code:
int ask_for_session(struct SessList *session_list, char *last_session)
{
    struct _GError *error = ((void *)0);
    unsigned int choice;
    char buf[32];
    char *endptr; char *choice_text;
    char *session_name;
    struct SessSession *default_session = ((void *)0);
    struct SessSession *chosen_session;
    int default_is_current_shell = (0);
    int no_lastsession_override;
    if( last_session )
    {
        if( ! *last_session )
        {
            default_is_current_shell = (!(0));
        }
        else
        {
            default_session = sess_session_find_by_path_normalized( session_list,
                last_session );
        }
    }
    for( ;; )
    {
        if( ! no_clear_screen )
        {
            terminfo_clear_screen();
        }
        fputs( gettext ("Welcome, please choose a session!\n"), stdout );
        if( ! no_lastsession )
        {
            fputs( gettext ("Append '!' to the number to prevent remembering your choice.\n\n"),
                stdout );
        }
        fputs( gettext ("  (0) continue using the current shell\n"), stdout );
        chosen_session = ((void *)0);
        _sess_num = 1;
        no_lastsession_override = (0);
        g_ptr_array_foreach( session_list->list, _display_session, ((void *)0) );
        if( default_session )
        {
            choice_text = default_session->use_xinit
                ? gettext ("\nYour choice [%s]: ")
                : gettext ("\nYour choice [Text: %s]: ");
            g_printf( choice_text,
                sess_session_get_name_locale( default_session ) );
        }
        else if( default_is_current_shell )
        {
            fputs( gettext ("\nYour choice [<current shell>]: "), stdout );
        }
        else {
            fputs( gettext ("\nYour choice: "), stdout );
        }
        if( ! fgets( buf, 32, stdin ) )
        {
            return (0);
        }
        g_strchug( buf );
        if( ! *buf )
        {
            if( default_session )
            {
                chosen_session = default_session;
            }
            else if( ! default_is_current_shell )
            {
                puts( gettext ("There is no default session! Please make a choice.") );
                sleep( 1 );
                continue;
            }
            else
            {
                break;
            }
        }
        else
        {
            choice = strtoul( buf, & endptr, 10 );
            if( endptr == buf )
            {
                puts( gettext ("Please enter a number.") );
                sleep( 1 );
                continue;
            }
            else if( *endptr == '!' )
            {
                no_lastsession_override = (!(0));
            }
            if( ! choice )
            {
                break;
            }
            else if( choice > session_list->list->len )
            {
                puts( gettext ("No such session. Please try again...") );
                sleep( 1 );
                continue;
            }
            chosen_session = ((session_list->list)->pdata)[choice - 1];
        }
        if( process_session( chosen_session ) )
        {
            break;
        }
        puts( gettext ("Could not process session! Please try again...") );
        sleep( 1 );
    }
    if( ! no_lastsession && ! no_lastsession_override )
    {
        session_name = chosen_session
                ? sess_session_get_path_normalized( chosen_session )
                : "";
        if( ( ! last_session || strcmp( session_name, last_session ) != 0 ) &&
            ! set_last_session( session_name, & error ) )
        {
            g_log (((char *) 0), G_LOG_LEVEL_WARNING, "Could not save last used session: %s", error->message);
            g_error_free( error );
        }
    }
    return chosen_session ? (!(0)) : (0);
}

variable_types: struct SessList { struct _GPtrArray { void **pdata; unsigned int len; } *list; struct _GPtrArray *path_idx; } *

variable_types: struct _GError { unsigned int domain; int code; char *message; } *

variable_types:
choice
unsigned int

variable_types:
buf
char [32]

variable_types:
endptr
char *

user_defined_types: struct SessList { struct _GPtrArray *list; struct _GPtrArray *path_idx; }

user_defined_types: struct SessSession { char *name; char *name_coll_key_case; char *name_locale; char *path; char *path_normalized; char *path_coll_key; char *exec; char *exec_locale; int use_xinit; }


main

canonical_name: main

repo: Tblue/sessionchooser

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rax
__int64 v4; // rbp
char *v5; // rax
const char *v6; // rbp
__int64 v7; // r13
__int64 *v9; // r12
const char *v10; // rdi
const char *v11; // rdi
const char **v12; // [rsp+0h] [rbp-38h] BYREF
int v13[3]; // [rsp+Ch] [rbp-2Ch] BYREF
__int64 v14[4]; // [rsp+18h] [rbp-20h] BYREF

v13[0] = argc;
v12 = argv;
v14[0] = 0LL;
i18n_init(argc, argv, envp);
v3 = dcgettext(0LL, "- a text-based session chooser", 5);
v4 = g_option_context_new(v3);
opt_ctx = v4;
v5 = dcgettext(
0LL,
"Displays a list of available sessions and prints a command line for the chosen session to the\n"
"file descriptor given by the -o option.",
5);
g_option_context_set_summary(v4, v5);
g_option_context_set_translation_domain(opt_ctx, "sessionchooser");
g_option_context_set_help_enabled(opt_ctx, 0LL);
g_option_context_add_main_entries(opt_ctx, &options, "sessionchooser");
g_option_context_parse(opt_ctx, v13, &v12, v14);
g_option_context_free(opt_ctx);
v6 = (const char *)v14[0];
if ( v14[0] )
{
LODWORD(v7) = 1;
g_log(0LL, 8LL, "Could not parse options: %s", *(const char **)(v14[0] + 8));
}
else if ( isatty(0) )
{
if ( fcntl(output_fd, 1) == -1 )
{
LODWORD(v7) = 3;
g_log(0LL, 8LL, "File descriptor %d is invalid.", (unsigned int)output_fd);
}
else
{
v9 = (__int64 *)sess_list_new();
v10 = (const char *)g_getenv("SESSIONCHOOSER_XPATH");
if ( !v10 )
v10 = "/usr/share/xsessions:/etc/X11/sessions";
sess_strsplit_foreach(v10, ":", 0xFFFFFFFFLL, &parse_xsession_files_in_dir, v9);
v11 = (const char *)g_getenv("SESSIONCHOOSER_TEXTPATH");
if ( !v11 )
v11 = "/etc/sessionchooser/textsessions";
sess_strsplit_foreach(v11, ":", 0xFFFFFFFFLL, &parse_textsession_files_in_dir, v9);
if ( *(_DWORD *)(*v9 + 8) )
{
sess_list_sort(v9);
if ( no_clear_screen || (unsigned int)terminfo_init() )
{
signal(2, sighandler);
if ( !no_lastsession )
v6 = (const char *)get_last_session();
v7 = (unsigned int)ask_for_session(v9, v6) == 0;
if ( !no_clear_screen )
terminfo_clear_screen();
close(output_fd);
g_free(v6);
sess_list_free(v9);
}
else
{
LODWORD(v7) = 4;
g_log(0LL, 8LL, "Could not initialize terminfo DB.");
}
}
else
{
sess_list_free(v9);
LODWORD(v7) = 1;
}
}
}
else
{
LODWORD(v7) = 2;
}
return v7;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rax
__int64 v4; // rbp
char *v5; // rax
const char *v6; // rbp
__int64 v7; // r13
__int64 *v9; // r12
const char *v10; // rdi
const char *v11; // rdi
const char **v12; // [rsp+0h] [rbp-38h] BYREF
int v13[3]; // [rsp+Ch] [rbp-2Ch] BYREF
__int64 v14[4]; // [rsp+18h] [rbp-20h] BYREF

v13[0] = argc;
v12 = argv;
v14[0] = 0LL;
i18n_init(argc, argv, envp);
v3 = dcgettext(0LL, "- a text-based session chooser", 5);
v4 = g_option_context_new(v3);
opt_ctx = v4;
v5 = dcgettext(
0LL,
"Displays a list of available sessions and prints a command line for the chosen session to the\n"
"file descriptor given by the -o option.",
5);
g_option_context_set_summary(v4, v5);
g_option_context_set_translation_domain(opt_ctx, "sessionchooser");
g_option_context_set_help_enabled(opt_ctx, 0LL);
g_option_context_add_main_entries(opt_ctx, &options, "sessionchooser");
g_option_context_parse(opt_ctx, v13, &v12, v14);
g_option_context_free(opt_ctx);
v6 = (const char *)v14[0];
if ( v14[0] )
{
LODWORD(v7) = 1;
g_log(0LL, 8LL, "Could not parse options: %s", *(const char **)(v14[0] + 8));
}
else if ( isatty(0) )
{
if ( fcntl(output_fd, 1) == -1 )
{
LODWORD(v7) = 3;
g_log(0LL, 8LL, "File descriptor %d is invalid.", (unsigned int)output_fd);
}
else
{
v9 = (__int64 *)sess_list_new();
v10 = (const char *)g_getenv("SESSIONCHOOSER_XPATH");
if ( !v10 )
v10 = "/usr/share/xsessions:/etc/X11/sessions";
sess_strsplit_foreach(v10, ":", 0xFFFFFFFFLL, &parse_xsession_files_in_dir, v9);
v11 = (const char *)g_getenv("SESSIONCHOOSER_TEXTPATH");
if ( !v11 )
v11 = "/etc/sessionchooser/textsessions";
sess_strsplit_foreach(v11, ":", 0xFFFFFFFFLL, &parse_textsession_files_in_dir, v9);
if ( *(_DWORD *)(*v9 + 8) )
{
sess_list_sort(v9);
if ( no_clear_screen || (unsigned int)terminfo_init() )
{
signal(2, sighandler);
if ( !no_lastsession )
v6 = (const char *)get_last_session();
v7 = (unsigned int)func4(v9, v6) == 0;
if ( !no_clear_screen )
terminfo_clear_screen();
close(output_fd);
g_free(v6);
sess_list_free(v9);
}
else
{
LODWORD(v7) = 4;
g_log(0LL, 8LL, "Could not initialize terminfo DB.");
}
}
else
{
sess_list_free(v9);
LODWORD(v7) = 1;
}
}
}
else
{
LODWORD(v7) = 2;
}
return v7;
}

original_code:
int main( int argc, char **argv )
{
    GError *error = ((void *)0);
    const gchar *temp;
    gchar *last_session = ((void *)0);
    SessList *session_list;
    int ret = 0;
    i18n_init();
    opt_ctx = g_option_context_new( gettext ("- a text-based session chooser") );
    g_option_context_set_summary( opt_ctx, gettext ("Displays a list of available " "sessions and prints a command line for the chosen session to the\n" "file descriptor given by the -o option.") );
    g_option_context_set_translation_domain( opt_ctx, "sessionchooser" );
    g_option_context_set_help_enabled( opt_ctx, (0) );
    g_option_context_add_main_entries( opt_ctx, options, "sessionchooser" );
    g_option_context_parse( opt_ctx, & argc, & argv, & error );
    g_option_context_free( opt_ctx );
    if( error )
    {
        g_log (((gchar*) 0), G_LOG_LEVEL_CRITICAL, "Could not parse options: %s", error->message);
        return SESS_MAIN_ERROR_OPTPARSE;
    }
    else if( ! isatty( 0 ) )
    {
        return SESS_MAIN_ERROR_NOT_A_TTY;
    }
    else if( fcntl( output_fd, 1 ) == -1 )
    {
        g_log (((gchar*) 0), G_LOG_LEVEL_CRITICAL, "File descriptor %d is invalid.", output_fd);
        return SESS_MAIN_ERROR_INV_OUTFD;
    }
    session_list = sess_list_new();
    temp = g_getenv( "SESSIONCHOOSER_XPATH" );
    if( ! temp )
    {
        temp = "/usr/share/xsessions:/etc/X11/sessions";
    }
    sess_strsplit_foreach( temp, ":", -1,
        parse_xsession_files_in_dir, session_list );
    temp = g_getenv( "SESSIONCHOOSER_TEXTPATH" );
    if( ! temp )
    {
        temp = "/etc/sessionchooser/textsessions";
    }
    sess_strsplit_foreach( temp, ":", -1,
        parse_textsession_files_in_dir, session_list );
    if( ! session_list->list->len )
    {
        sess_list_free( session_list );
        return 1;
    }
    sess_list_sort( session_list );
    if( ! no_clear_screen && ! terminfo_init() )
    {
        g_log (((gchar*) 0), G_LOG_LEVEL_CRITICAL, "Could not initialize terminfo DB.");
        return SESS_MAIN_ERROR_TERMINFO;
    }
    signal( 2, sighandler );
    if( ! no_lastsession )
    {
        last_session = get_last_session();
    }
    if( ! ask_for_session( session_list, last_session ) )
    {
        ret = 1;
    }
    if( ! no_clear_screen )
    {
        terminfo_clear_screen();
    }
    close( output_fd );
    g_free( last_session );
    sess_list_free( session_list );
    return ret;
}

canonical_original_code:
int main(int argc, char **argv)
{
    struct _GError *error = ((void *)0);
    char *temp;
    char *last_session = ((void *)0);
    struct SessList *session_list;
    int ret = 0;
    i18n_init();
    opt_ctx = g_option_context_new( gettext ("- a text-based session chooser") );
    g_option_context_set_summary( opt_ctx, gettext ("Displays a list of available " "sessions and prints a command line for the chosen session to the\n" "file descriptor given by the -o option.") );
    g_option_context_set_translation_domain( opt_ctx, "sessionchooser" );
    g_option_context_set_help_enabled( opt_ctx, (0) );
    g_option_context_add_main_entries( opt_ctx, options, "sessionchooser" );
    g_option_context_parse( opt_ctx, & argc, & argv, & error );
    g_option_context_free( opt_ctx );
    if( error )
    {
        g_log (((char *) 0), G_LOG_LEVEL_CRITICAL, "Could not parse options: %s", error->message);
        return SESS_MAIN_ERROR_OPTPARSE;
    }
    else if( ! isatty( 0 ) )
    {
        return SESS_MAIN_ERROR_NOT_A_TTY;
    }
    else if( fcntl( output_fd, 1 ) == -1 )
    {
        g_log (((char *) 0), G_LOG_LEVEL_CRITICAL, "File descriptor %d is invalid.", output_fd);
        return SESS_MAIN_ERROR_INV_OUTFD;
    }
    session_list = sess_list_new();
    temp = g_getenv( "SESSIONCHOOSER_XPATH" );
    if( ! temp )
    {
        temp = "/usr/share/xsessions:/etc/X11/sessions";
    }
    sess_strsplit_foreach( temp, ":", -1,
        parse_xsession_files_in_dir, session_list );
    temp = g_getenv( "SESSIONCHOOSER_TEXTPATH" );
    if( ! temp )
    {
        temp = "/etc/sessionchooser/textsessions";
    }
    sess_strsplit_foreach( temp, ":", -1,
        parse_textsession_files_in_dir, session_list );
    if( ! session_list->list->len )
    {
        sess_list_free( session_list );
        return 1;
    }
    sess_list_sort( session_list );
    if( ! no_clear_screen && ! terminfo_init() )
    {
        g_log (((char *) 0), G_LOG_LEVEL_CRITICAL, "Could not initialize terminfo DB.");
        return SESS_MAIN_ERROR_TERMINFO;
    }
    signal( 2, sighandler );
    if( ! no_lastsession )
    {
        last_session = get_last_session();
    }
    if( ! ask_for_session( session_list, last_session ) )
    {
        ret = 1;
    }
    if( ! no_clear_screen )
    {
        terminfo_clear_screen();
    }
    close( output_fd );
    g_free( last_session );
    sess_list_free( session_list );
    return ret;
}

variable_types: argc int

variable_types:
argv
char **

variable_types:
temp
char *

variable_types: ret int

return_type: int

user_defined_types: struct _GError { unsigned int domain; int code; char *message; }

user_defined_types: struct _GPtrArray { void **pdata; unsigned int len; }


decompiled_code:
__int64 __fastcall sess_strsplit_foreach(__int64 a1, __int64 a2, __int64 a3, void (__fastcall *a4)(__int64, __int64), __int64 a5)
{
_QWORD *v7; // rax
__int64 v8; // rdi
_QWORD *v9; // r13
__int64 *v10; // rbx

v7 = (_QWORD *)g_strsplit();
v8 = *v7;
v9 = v7;
if ( *v7 )
{
v10 = v7;
do
{
++v10;
a4(v8, a5);
v8 = *v10;
}
while ( *v10 );
}
return g_strfreev(v9);
}

original_code:
void sess_strsplit_foreach( const gchar *string, const gchar *delimiter,
                            gint max_tokens, GFunc func, gpointer user_data )
{
    gchar **parts = g_strsplit( string, delimiter, max_tokens );
    gchar **parts_p;
    for( parts_p = parts; *parts_p; parts_p++ )
    {
        func( *parts_p, user_data );
    }
    g_strfreev( parts );
}

canonical_original_code:
void sess_strsplit_foreach(char *string, char *delimiter, int max_tokens, void (*func)(void *data, void *user_data), void *user_data)
{
    char **parts = g_strsplit( string, delimiter, max_tokens );
    char **parts_p;
    for( parts_p = parts; *parts_p; parts_p++ )
    {
        func( *parts_p, user_data );
    }
    g_strfreev( parts );
}

variable_types:
string
char *

variable_types:
delimiter
char *

variable_types:
func
void (*)(void *data, void *user_data)

variable_types:
parts
char **

return_type: void


decompiled_code:
__int64 get_next_free_XDisplay()
{
__int64 v0; // rax
const char *v1; // rbp
int v2; // er12
unsigned int v3; // er13
__int64 v5; // r12
signed int v6; // eax
const char *v7; // rbp
char *v8; // rax
glob_t v9; // [rsp+0h] [rbp-68h] BYREF

v0 = g_get_tmp_dir();
v1 = (const char *)g_build_path("/", v0, ".X[0-9]*-lock", 0LL);
v2 = glob(v1, 69, 0LL, &v9);
g_free(v1);
if ( v2 == 2 )
{
g_log(0LL, 8LL, "Could not glob() for X lock files (read error)!");
globfree(&v9);
return 0xFFFFFFFFLL;
}
if ( v2 > 2 )
{
if ( v2 != 3 )
{
LABEL_11:
g_log(0LL, 8LL, "Unhandled glob() return value: %d", (unsigned int)v2);
globfree(&v9);
return 0xFFFFFFFFLL;
}
v3 = 0;
globfree(&v9);
return v3;
}
if ( v2 )
{
if ( v2 == 1 )
{
g_log(0LL, 4LL, "Out of memory!");
while ( 1 )
;
}
goto LABEL_11;
}
v5 = 0LL;
v3 = -1;
if ( !v9.gl_pathc )
{
LABEL_13:
globfree(&v9);
return v3;
}
while ( 1 )
{
v7 = v9.gl_pathv[v5];
if ( (unsigned int)g_file_test(v7, 1LL) )
break;
LABEL_16:
if ( v9.gl_pathc <= ++v5 )
goto LABEL_13;
}
v8 = strrchr(v7, 47);
if ( v8 )
{
v6 = g_ascii_strtoull(v8 + 3, 0LL, 10LL) + 1;
if ( (int)v3 < v6 )
v3 = v6;
goto LABEL_16;
}
g_assertion_message_expr(0LL, "util.c", 106LL, "get_next_free_XDisplay", "offset != NULL");
return get_active_vt();
}

canonical_decompiled_code:
__int64 func2()
{
__int64 v0; // rax
const char *v1; // rbp
int v2; // er12
unsigned int v3; // er13
__int64 v5; // r12
signed int v6; // eax
const char *v7; // rbp
char *v8; // rax
glob_t v9; // [rsp+0h] [rbp-68h] BYREF

v0 = g_get_tmp_dir();
v1 = (const char *)g_build_path("/", v0, ".X[0-9]*-lock", 0LL);
v2 = glob(v1, 69, 0LL, &v9);
g_free(v1);
if ( v2 == 2 )
{
g_log(0LL, 8LL, "Could not glob() for X lock files (read error)!");
globfree(&v9);
return 0xFFFFFFFFLL;
}
if ( v2 > 2 )
{
if ( v2 != 3 )
{
LABEL_11:
g_log(0LL, 8LL, "Unhandled glob() return value: %d", (unsigned int)v2);
globfree(&v9);
return 0xFFFFFFFFLL;
}
v3 = 0;
globfree(&v9);
return v3;
}
if ( v2 )
{
if ( v2 == 1 )
{
g_log(0LL, 4LL, "Out of memory!");
while ( 1 )
;
}
goto LABEL_11;
}
v5 = 0LL;
v3 = -1;
if ( !v9.gl_pathc )
{
LABEL_13:
globfree(&v9);
return v3;
}
while ( 1 )
{
v7 = v9.gl_pathv[v5];
if ( (unsigned int)g_file_test(v7, 1LL) )
break;
LABEL_16:
if ( v9.gl_pathc <= ++v5 )
goto LABEL_13;
}
v8 = strrchr(v7, 47);
if ( v8 )
{
v6 = g_ascii_strtoull(v8 + 3, 0LL, 10LL) + 1;
if ( (int)v3 < v6 )
v3 = v6;
goto LABEL_16;
}
g_assertion_message_expr(0LL, "util.c", 106LL, "get_next_free_XDisplay", "offset != NULL");
return func3();
}

original_code:
gint get_next_free_XDisplay( void )
{
    char *file;
    char *offset;
    size_t i;
    gint display = -1;
    gint l_display;
    glob_t matches;
    gchar *pattern = g_build_path( "/", g_get_tmp_dir(),
        ".X[0-9]*-lock", ((void *)0) );
    int res = glob( pattern, (1 << 0) | (1 << 2) | (1 << 6), ((void *)0),
        & matches );
    g_free( pattern );
    switch( res )
    {
        case 0:
            break;
        case 3:
            globfree( & matches );
            return 0;
        case 2:
            g_log (((gchar*) 0), G_LOG_LEVEL_CRITICAL, "Could not glob() for X lock files (read error)!");
            globfree( & matches );
            return -1;
        case 1:
            do { g_log (((gchar*) 0), G_LOG_LEVEL_ERROR, "Out of memory!"); for (;;) ; } while (0);
            break;
        default:
            g_log (((gchar*) 0), G_LOG_LEVEL_CRITICAL, "Unhandled glob() return value: %d", res);
            globfree( & matches );
            return -1;
    }
    for( i = 0; i < matches.gl_pathc; i++ )
    {
        file = matches.gl_pathv[i];
        if( ! g_file_test( file, G_FILE_TEST_IS_REGULAR ) )
        {
            continue;
        }
        offset = strrchr( file, '/' );
        do { if (offset != ((void *)0)) ; else g_assertion_message_expr (((gchar*) 0), "util.c", 106, ((const char*) (__func__)), "offset != NULL"); } while (0);
        offset += 3;
        l_display = g_ascii_strtoull( offset, ((void *)0), 10 ) + 1;
        if( l_display > display )
        {
            display = l_display;
        }
    }
    globfree( & matches );
    return display;
}

canonical_original_code:
int get_next_free_XDisplay()
{
    char *file;
    char *offset;
    unsigned long i;
    int display = -1;
    int l_display;
    struct glob_t matches;
    char *pattern = g_build_path( "/", g_get_tmp_dir(),
        ".X[0-9]*-lock", ((void *)0) );
    int res = glob( pattern, (1 << 0) | (1 << 2) | (1 << 6), ((void *)0),
        & matches );
    g_free( pattern );
    switch( res )
    {
        case 0:
            break;
        case 3:
            globfree( & matches );
            return 0;
        case 2:
            g_log (((char *) 0), G_LOG_LEVEL_CRITICAL, "Could not glob() for X lock files (read error)!");
            globfree( & matches );
            return -1;
        case 1:
            do { g_log (((char *) 0), G_LOG_LEVEL_ERROR, "Out of memory!"); for (;;) ; } while (0);
            break;
        default:
            g_log (((char *) 0), G_LOG_LEVEL_CRITICAL, "Unhandled glob() return value: %d", res);
            globfree( & matches );
            return -1;
    }
    for( i = 0; i < matches.gl_pathc; i++ )
    {
        file = matches.gl_pathv[i];
        if( ! g_file_test( file, G_FILE_TEST_IS_REGULAR ) )
        {
            continue;
        }
        offset = strrchr( file, '/' );
        do { if (offset != ((void *)0)) ; else g_assertion_message_expr (((char *) 0), "util.c", 106, ((char *) (__func__)), "offset != NULL"); } while (0);
        offset += 3;
        l_display = g_ascii_strtoull( offset, ((void *)0), 10 ) + 1;
        if( l_display > display )
        {
            display = l_display;
        }
    }
    globfree( & matches );
    return display;
}

variable_types:
file
char *

variable_types:
offset
char *

variable_types:
i
unsigned long

variable_types: display int

variable_types: struct glob_t { unsigned long gl_pathc; char **gl_pathv; unsigned long gl_offs; int gl_flags; void (*gl_closedir)(void *); void *(*gl_readdir)(void *); void *(*gl_opendir)(char *); int (*gl_lstat)(char *, void *); int (*gl_stat)(char *, void *); }

variable_types:
pattern
char *

variable_types: res int


decompiled_code:
__int64 get_active_vt()
{
__int64 result; // rax
unsigned __int16 v1[7]; // [rsp+Ah] [rbp-Eh] BYREF

if ( ioctl(0, 0x5603uLL, v1) == -1 )
result = 0xFFFFFFFFLL;
else
result = v1[0];
return result;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 result; // rax
unsigned __int16 v1[7]; // [rsp+Ah] [rbp-Eh] BYREF

if ( ioctl(0, 0x5603uLL, v1) == -1 )
result = 0xFFFFFFFFLL;
else
result = v1[0];
return result;
}

original_code:
gshort get_active_vt( void )
{
    struct vt_stat vtstat;
    if( ioctl( 0, 0x5603, & vtstat ) == -1 )
    {
        return -1;
    }
    return vtstat.v_active;
}

canonical_original_code:
short get_active_vt()
{
    struct vt_stat vtstat;
    if( ioctl( 0, 0x5603, & vtstat ) == -1 )
    {
        return -1;
    }
    return vtstat.v_active;
}

variable_types: struct vt_stat { unsigned short v_active; unsigned short v_signal; unsigned short v_state; }

return_type: short


decompiled_code:
_BOOL8 terminfo_init()
{
return setupterm(0LL, 1, 0LL) != -1;
}

canonical_decompiled_code:
_BOOL8 func4()
{
return setupterm(0LL, 1, 0LL) != -1;
}

original_code:
gboolean terminfo_init( void )
{
    if( setupterm( ((void *)0), 1, ((void *)0) ) == (-1) )
    {
        return 0;
    }
    return 1;
}

canonical_original_code:
int terminfo_init()
{
    if( setupterm( ((void *)0), 1, ((void *)0) ) == (-1) )
    {
        return 0;
    }
    return 1;
}


decompiled_code:
int terminfo_clear_screen()
{
return putp(*((const char **)cur_term->type.Strings + 5));
}

canonical_decompiled_code:
int func5()
{
return putp(*((const char **)cur_term->type.Strings + 5));
}

original_code:
void terminfo_clear_screen( void )
{
    putp( ((TERMTYPE *)(cur_term))-> Strings[5] );
}

canonical_original_code:
void terminfo_clear_screen()
{
    putp( ((struct termtype *)(cur_term))-> Strings[5] );
}

user_defined_types: struct termtype { char *term_names; char *str_table; char *Booleans; short *Numbers; char **Strings; char *ext_str_table; char **ext_Names; unsigned short num_Booleans; unsigned short num_Numbers; unsigned short num_Strings; unsigned short ext_Booleans; unsigned short ext_Numbers; unsigned short ext_Strings; }


decompiled_code:
__int64 get_last_session()
{
__int64 v0; // rax
__int64 v1; // rbp
__int64 v3; // [rsp+8h] [rbp-10h] BYREF

v0 = g_get_home_dir();
v3 = 0LL;
v1 = g_build_filename(v0, ".lastsession", 0LL);
g_file_get_contents(v1, &v3, 0LL, 0LL);
g_free(v1);
return v3;
}

canonical_decompiled_code:
__int64 func6()
{
__int64 v0; // rax
__int64 v1; // rbp
__int64 v3; // [rsp+8h] [rbp-10h] BYREF

v0 = g_get_home_dir();
v3 = 0LL;
v1 = g_build_filename(v0, ".lastsession", 0LL);
g_file_get_contents(v1, &v3, 0LL, 0LL);
g_free(v1);
return v3;
}

original_code:
gchar *get_last_session( void )
{
    gchar *file = g_build_filename( g_get_home_dir(), ".lastsession",
        ((void *)0) );
    gchar *last_session = ((void *)0);
    g_file_get_contents( file, & last_session, ((void *)0), ((void *)0) );
    g_free( file );
    return last_session;
}

canonical_original_code:
char *get_last_session()
{
    char *file = g_build_filename( g_get_home_dir(), ".lastsession",
        ((void *)0) );
    char *last_session = ((void *)0);
    g_file_get_contents( file, & last_session, ((void *)0), ((void *)0) );
    g_free( file );
    return last_session;
}

return_type: char *


decompiled_code:
__int64 __fastcall set_last_session(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // rbp
__int64 result; // rax
__int64 v5[4]; // [rsp+8h] [rbp-20h] BYREF

v2 = g_get_home_dir();
v5[0] = 0LL;
v3 = g_build_filename(v2, ".lastsession", 0LL);
g_file_set_contents(v3, a1, -1LL, v5);
g_free(v3);
result = 1LL;
if ( v5[0] )
{
g_propagate_error(a2);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // rbp
__int64 result; // rax
__int64 v5[4]; // [rsp+8h] [rbp-20h] BYREF

v2 = g_get_home_dir();
v5[0] = 0LL;
v3 = g_build_filename(v2, ".lastsession", 0LL);
g_file_set_contents(v3, a1, -1LL, v5);
g_free(v3);
result = 1LL;
if ( v5[0] )
{
g_propagate_error(a2);
result = 0LL;
}
return result;
}

original_code:
gboolean set_last_session( const gchar *sess_name, GError **error )
{
    gchar *file = g_build_filename( g_get_home_dir(), ".lastsession",
        ((void *)0) );
    GError *int_error = ((void *)0);
    g_file_set_contents( file, sess_name, -1, & int_error );
    g_free( file );
    if( int_error )
    {
        g_propagate_error( error, int_error );
        return 0;
    }
    return 1;
}

canonical_original_code:
int set_last_session(char *sess_name, struct _GError **error)
{
    char *file = g_build_filename( g_get_home_dir(), ".lastsession",
        ((void *)0) );
    struct _GError *int_error = ((void *)0);
    g_file_set_contents( file, sess_name, -1, & int_error );
    g_free( file );
    if( int_error )
    {
        g_propagate_error( error, int_error );
        return 0;
    }
    return 1;
}

variable_types: struct _GError { unsigned int domain; int code; char *message; } **


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

result = g_filename_to_utf8(a1, -1LL, 0LL, 0LL, 0LL);
if ( !result )
result = g_strdup(a1);
return result;
}

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

result = g_filename_to_utf8(a1, -1LL, 0LL, 0LL, 0LL);
if ( !result )
result = g_strdup(a1);
return result;
}

original_code:
gchar *filename_to_utf8_nofail( const gchar *path )
{
    gchar *file_path_utf8;
    file_path_utf8 = g_filename_to_utf8( path, -1, ((void *)0), ((void *)0), ((void *)0) );
    if( ! file_path_utf8 )
    {
        file_path_utf8 = g_strdup( path );
    }
    return file_path_utf8;
}

canonical_original_code:
char *filename_to_utf8_nofail(char *path)
{
    char *file_path_utf8;
    file_path_utf8 = g_filename_to_utf8( path, -1, ((void *)0), ((void *)0), ((void *)0) );
    if( ! file_path_utf8 )
    {
        file_path_utf8 = g_strdup( path );
    }
    return file_path_utf8;
}

variable_types:
path
char *


decompiled_code:
__int64 __fastcall ptr_array_copy(__int64 a1)
{
__int64 v1; // r12

v1 = g_ptr_array_new_full(*(unsigned int *)(a1 + 8));
g_ptr_array_foreach(a1, ptr_array_copy_cb, v1);
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
__int64 v1; // r12

v1 = g_ptr_array_new_full(*(unsigned int *)(a1 + 8));
g_ptr_array_foreach(a1, ptr_array_copy_cb, v1);
return v1;
}

original_code:
GPtrArray *ptr_array_copy( GPtrArray *src, GDestroyNotify free_func )
{
    GPtrArray *dest = g_ptr_array_new_full( src->len, free_func );
    g_ptr_array_foreach( src, _ptr_array_copy_cb, dest );
    return dest;
}

canonical_original_code:
struct _GPtrArray *ptr_array_copy(struct _GPtrArray *src, void (*free_func)(void *data))
{
    struct _GPtrArray *dest = g_ptr_array_new_full( src->len, free_func );
    g_ptr_array_foreach( src, _ptr_array_copy_cb, dest );
    return dest;
}

variable_types:
src
struct _GPtrArray *

variable_types: struct _GPtrArray { void **pdata; unsigned int len; } *


decompiled_code:
__int64 sess_desktopentry_error_quark()
{
return g_quark_from_static_string("sess-desktopentry-error-quark");
}

canonical_decompiled_code:
__int64 func0()
{
return g_quark_from_static_string("sess-desktopentry-error-quark");
}

original_code:
GQuark sess_desktopentry_error_quark( void )
{
    return g_quark_from_static_string( "sess-desktopentry-error-quark" );
}

canonical_original_code:
unsigned int sess_desktopentry_error_quark()
{
    return g_quark_from_static_string( "sess-desktopentry-error-quark" );
}

return_type: unsigned int


decompiled_code:
__int64 sess_cmdlineoption_error_quark()
{
return g_quark_from_static_string("sess-cmdlineoption-error-quark");
}

canonical_decompiled_code:
__int64 func1()
{
return g_quark_from_static_string("sess-cmdlineoption-error-quark");
}

original_code:
GQuark sess_cmdlineoption_error_quark( void )
{
    return g_quark_from_static_string( "sess-cmdlineoption-error-quark" );
}

canonical_original_code:
unsigned int sess_cmdlineoption_error_quark()
{
    return g_quark_from_static_string( "sess-cmdlineoption-error-quark" );
}


decompiled_code:
char *i18n_init()
{
char *result; // rax

setlocale(6, &locale);
result = textdomain("sessionchooser");
if ( !result )
{
g_log(0LL, 4LL, "Out of memory!");
while ( 1 )
;
}
return result;
}

canonical_decompiled_code:
char *func0()
{
char *result; // rax

setlocale(6, &locale);
result = textdomain("sessionchooser");
if ( !result )
{
g_log(0LL, 4LL, "Out of memory!");
while ( 1 )
;
}
return result;
}

original_code:
void i18n_init( void )
{
    setlocale( 6, "" );
    if( ! textdomain( "sessionchooser" ) )
    {
        do { g_log (((gchar*) 0), G_LOG_LEVEL_ERROR, "Out of memory!"); for (;;) ; } while (0);
    }
}

canonical_original_code:
void i18n_init()
{
    setlocale( 6, "" );
    if( ! textdomain( "sessionchooser" ) )
    {
        do { g_log (((char *) 0), G_LOG_LEVEL_ERROR, "Out of memory!"); for (;;) ; } while (0);
    }
}


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

result = g_locale_from_utf8(a1, a2, 0LL, 0LL, 0LL);
if ( !result )
result = g_strdup(a1);
return result;
}

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

result = g_locale_from_utf8(a1, a2, 0LL, 0LL, 0LL);
if ( !result )
result = g_strdup(a1);
return result;
}

original_code:
gchar *sess_locale_from_utf8( const gchar *utf8string, gssize len )
{
    gchar *converted = g_locale_from_utf8( utf8string, len, ((void *)0), ((void *)0), ((void *)0) );
    if( ! converted )
    {
        return g_strdup( utf8string );
    }
    return converted;
}

canonical_original_code:
char *sess_locale_from_utf8(char *utf8string, long len)
{
    char *converted = g_locale_from_utf8( utf8string, len, ((void *)0), ((void *)0), ((void *)0) );
    if( ! converted )
    {
        return g_strdup( utf8string );
    }
    return converted;
}

variable_types: len long

variable_types:
converted
char *


decompiled_code:
__int64 __fastcall sess_session_free(_QWORD *a1)
{
g_free(*a1);
g_free(a1[1]);
g_free(a1[2]);
g_free(a1[3]);
g_free(a1[4]);
g_free(a1[5]);
g_free(a1[6]);
g_free(a1[7]);
return g_free(a1);
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1)
{
g_free(*a1);
g_free(a1[1]);
g_free(a1[2]);
g_free(a1[3]);
g_free(a1[4]);
g_free(a1[5]);
g_free(a1[6]);
g_free(a1[7]);
return g_free(a1);
}

original_code:
void sess_session_free( SessSession *sess )
{
    g_free( sess->name );
    g_free( sess->name_coll_key_case );
    g_free( sess->name_locale );
    g_free( sess->path );
    g_free( sess->path_normalized );
    g_free( sess->path_coll_key );
    g_free( sess->exec );
    g_free( sess->exec_locale );
    g_free( sess );
}

canonical_original_code:
void sess_session_free(struct SessSession *sess)
{
    g_free( sess->name );
    g_free( sess->name_coll_key_case );
    g_free( sess->name_locale );
    g_free( sess->path );
    g_free( sess->path_normalized );
    g_free( sess->path_coll_key );
    g_free( sess->exec );
    g_free( sess->exec_locale );
    g_free( sess );
}

variable_types: struct SessSession { char *name; char *name_coll_key_case; char *name_locale; char *path; char *path_normalized; char *path_coll_key; char *exec; char *exec_locale; int use_xinit; } *


decompiled_code:
__int64 sess_session_new()
{
return g_malloc0(72LL);
}

canonical_decompiled_code:
__int64 func1()
{
return g_malloc0(72LL);
}

original_code:
SessSession *sess_session_new( void )
{
    return ((SessSession *) g_malloc0_n ((1), sizeof (SessSession)));
}

canonical_original_code:
struct SessSession *sess_session_new()
{
    return ((struct SessSession *) g_malloc0_n ((1), sizeof (SessSession)));
}

return_type: struct SessSession { char *name; char *name_coll_key_case; char *name_locale; char *path; char *path_normalized; char *path_coll_key; char *exec; char *exec_locale; int use_xinit; } *


decompiled_code:
__int64 __fastcall sess_session_get_name_coll_key_case(_QWORD *a1)
{
__int64 result; // rax
__int64 v2; // rbp

result = a1[1];
if ( !result )
{
v2 = g_utf8_casefold(*a1, -1LL);
a1[1] = g_utf8_collate_key(v2, -1LL);
g_free(v2);
result = a1[1];
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1)
{
__int64 result; // rax
__int64 v2; // rbp

result = a1[1];
if ( !result )
{
v2 = g_utf8_casefold(*a1, -1LL);
a1[1] = g_utf8_collate_key(v2, -1LL);
g_free(v2);
result = a1[1];
}
return result;
}

original_code:
gchar *sess_session_get_name_coll_key_case( SessSession *sess )
{
    gchar *folded;
    if( ! sess->name_coll_key_case )
    {
        folded = g_utf8_casefold( sess->name, -1 );
        sess->name_coll_key_case = g_utf8_collate_key( folded, -1 );
        g_free( folded );
    }
    return sess->name_coll_key_case;
}

canonical_original_code:
char *sess_session_get_name_coll_key_case(struct SessSession *sess)
{
    char *folded;
    if( ! sess->name_coll_key_case )
    {
        folded = g_utf8_casefold( sess->name, -1 );
        sess->name_coll_key_case = g_utf8_collate_key( folded, -1 );
        g_free( folded );
    }
    return sess->name_coll_key_case;
}

variable_types:
folded
char *


decompiled_code:
__int64 __fastcall sess_session_get_name_locale(_QWORD *a1)
{
__int64 result; // rax

result = a1[2];
if ( !result )
{
result = sess_locale_from_utf8(*a1, -1LL);
a1[2] = result;
}
return result;
}

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

result = a1[2];
if ( !result )
{
result = sess_locale_from_utf8(*a1, -1LL);
a1[2] = result;
}
return result;
}

original_code:
gchar *sess_session_get_name_locale( SessSession *sess )
{
    if( ! sess->name_locale )
    {
        sess->name_locale = sess_locale_from_utf8( sess->name, -1 );
    }
    return sess->name_locale;
}

canonical_original_code:
char *sess_session_get_name_locale(struct SessSession *sess)
{
    if( ! sess->name_locale )
    {
        sess->name_locale = sess_locale_from_utf8( sess->name, -1 );
    }
    return sess->name_locale;
}


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

result = *(_QWORD *)(a1 + 32);
if ( !result )
{
result = g_utf8_normalize(*(_QWORD *)(a1 + 24), -1LL, 1LL);
if ( !result )
result = g_strdup(*(_QWORD *)(a1 + 24));
*(_QWORD *)(a1 + 32) = result;
}
return result;
}

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

result = *(_QWORD *)(a1 + 32);
if ( !result )
{
result = g_utf8_normalize(*(_QWORD *)(a1 + 24), -1LL, 1LL);
if ( !result )
result = g_strdup(*(_QWORD *)(a1 + 24));
*(_QWORD *)(a1 + 32) = result;
}
return result;
}

original_code:
gchar *sess_session_get_path_normalized( SessSession *sess )
{
    gchar *normalized;
    if( ! sess->path_normalized )
    {
        normalized = g_utf8_normalize( sess->path, -1, G_NORMALIZE_NFC );
        if( ! normalized )
        {
            sess->path_normalized = g_strdup( sess->path );
        }
        else
        {
            sess->path_normalized = normalized;
        }
    }
    return sess->path_normalized;
}

canonical_original_code:
char *sess_session_get_path_normalized(struct SessSession *sess)
{
    char *normalized;
    if( ! sess->path_normalized )
    {
        normalized = g_utf8_normalize( sess->path, -1, G_NORMALIZE_NFC );
        if( ! normalized )
        {
            sess->path_normalized = g_strdup( sess->path );
        }
        else
        {
            sess->path_normalized = normalized;
        }
    }
    return sess->path_normalized;
}

variable_types:
normalized
char *


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

result = *(_QWORD *)(a1 + 40);
if ( !result )
{
result = g_utf8_collate_key(*(_QWORD *)(a1 + 24), -1LL);
*(_QWORD *)(a1 + 40) = result;
}
return result;
}

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

result = *(_QWORD *)(a1 + 40);
if ( !result )
{
result = g_utf8_collate_key(*(_QWORD *)(a1 + 24), -1LL);
*(_QWORD *)(a1 + 40) = result;
}
return result;
}

original_code:
gchar *sess_session_get_path_coll_key( SessSession *sess )
{
    if( ! sess->path_coll_key )
    {
        sess->path_coll_key = g_utf8_collate_key( sess->path, -1 );
    }
    return sess->path_coll_key;
}

canonical_original_code:
char *sess_session_get_path_coll_key(struct SessSession *sess)
{
    if( ! sess->path_coll_key )
    {
        sess->path_coll_key = g_utf8_collate_key( sess->path, -1 );
    }
    return sess->path_coll_key;
}


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

result = *(_QWORD *)(a1 + 56);
if ( !result )
{
result = sess_locale_from_utf8(*(_QWORD *)(a1 + 48), -1LL);
*(_QWORD *)(a1 + 56) = result;
}
return result;
}

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

result = *(_QWORD *)(a1 + 56);
if ( !result )
{
result = sess_locale_from_utf8(*(_QWORD *)(a1 + 48), -1LL);
*(_QWORD *)(a1 + 56) = result;
}
return result;
}

original_code:
gchar *sess_session_get_exec_locale( SessSession *sess )
{
    if( ! sess->exec_locale )
    {
        sess->exec_locale = sess_locale_from_utf8( sess->exec, -1 );
    }
    return sess->exec_locale;
}

canonical_original_code:
char *sess_session_get_exec_locale(struct SessSession *sess)
{
    if( ! sess->exec_locale )
    {
        sess->exec_locale = sess_locale_from_utf8( sess->exec, -1 );
    }
    return sess->exec_locale;
}


decompiled_code:
_QWORD *sess_list_new()
{
_QWORD *v0; // r12

v0 = (_QWORD *)g_malloc0(16LL);
*v0 = g_ptr_array_new_with_free_func(sess_session_free);
return v0;
}

canonical_decompiled_code:
_QWORD *func10()
{
_QWORD *v0; // r12

v0 = (_QWORD *)g_malloc0(16LL);
*v0 = g_ptr_array_new_with_free_func(sess_session_free);
return v0;
}

original_code:
SessList *sess_list_new( void )
{
    SessList *s = ((SessList *) g_malloc0_n ((1), sizeof (SessList)));
    s->list = g_ptr_array_new_with_free_func( (GDestroyNotify)sess_session_free );
    return s;
}

canonical_original_code:
struct SessList *sess_list_new()
{
    struct SessList *s = ((SessList *) g_malloc0_n ((1), sizeof (SessList)));
    s->list = g_ptr_array_new_with_free_func( (void (*)(void *data))sess_session_free );
    return s;
}

variable_types: struct SessList { struct _GPtrArray { void **pdata; unsigned int len; } *list; struct _GPtrArray *path_idx; } *


decompiled_code:
__int64 __fastcall sess_list_free(_QWORD *a1)
{
__int64 result; // rax
__int64 v2; // rdi

if ( a1 )
{
result = g_ptr_array_free(*a1, 1LL);
v2 = a1[1];
if ( v2 )
result = g_ptr_array_free(v2, 1LL);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func11(_QWORD *a1)
{
__int64 result; // rax
__int64 v2; // rdi

if ( a1 )
{
result = g_ptr_array_free(*a1, 1LL);
v2 = a1[1];
if ( v2 )
result = g_ptr_array_free(v2, 1LL);
}
return result;
}

original_code:
void sess_list_free( SessList *s )
{
    if( ! s )
    {
        return;
    }
    g_ptr_array_free( s->list, (!(0)) );
    if( s->path_idx )
    {
        g_ptr_array_free( s->path_idx, (!(0)) );
    }
}

canonical_original_code:
void sess_list_free(struct SessList *s)
{
    if( ! s )
    {
        return;
    }
    g_ptr_array_free( s->list, (!(0)) );
    if( s->path_idx )
    {
        g_ptr_array_free( s->path_idx, (!(0)) );
    }
}


decompiled_code:
__int64 __fastcall sess_list_sort(_QWORD *a1)
{
__int64 v2; // rdi
__int64 v3; // rax

g_ptr_array_sort(*a1, session_name_sort_func);
v2 = a1[1];
if ( v2 )
g_ptr_array_free(v2, 1LL);
v3 = ptr_array_copy(*a1, 0LL);
a1[1] = v3;
return g_ptr_array_sort(v3, session_path_sort_func);
}

canonical_decompiled_code:
__int64 __fastcall func12(_QWORD *a1)
{
__int64 v2; // rdi
__int64 v3; // rax

g_ptr_array_sort(*a1, session_name_sort_func);
v2 = a1[1];
if ( v2 )
g_ptr_array_free(v2, 1LL);
v3 = ptr_array_copy(*a1, 0LL);
a1[1] = v3;
return g_ptr_array_sort(v3, session_path_sort_func);
}

original_code:
void sess_list_sort( SessList *s )
{
    g_ptr_array_sort( s->list, _session_name_sort_func );
    if( s->path_idx )
    {
        g_ptr_array_free( s->path_idx, (!(0)) );
    }
    s->path_idx = ptr_array_copy( s->list, ((void *)0) );
    g_ptr_array_sort( s->path_idx, _session_path_sort_func );
}

canonical_original_code:
void sess_list_sort(struct SessList *s)
{
    g_ptr_array_sort( s->list, _session_name_sort_func );
    if( s->path_idx )
    {
        g_ptr_array_free( s->path_idx, (!(0)) );
    }
    s->path_idx = ptr_array_copy( s->list, ((void *)0) );
    g_ptr_array_sort( s->path_idx, _session_path_sort_func );
}


repo: TermiT/sw-redux

decompiled_code:
_BOOL8 __fastcall SoundDriver_IsPCMSupported(int a1)
{
return *(&off_550 + 22 * a1) != 0LL;
}

canonical_decompiled_code:
_BOOL8 __fastcall func0(int a1)
{
return *(&off_550 + 22 * a1) != 0LL;
}

original_code:
int SoundDriver_IsPCMSupported(int driver)
{
 return (SoundDrivers[driver].PCM_Init != 0);
}

variable_types: driver int


decompiled_code:
_BOOL8 __fastcall SoundDriver_IsCDSupported(int a1)
{
return *(&off_580 + 22 * a1) != 0LL;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(int a1)
{
return *(&off_580 + 22 * a1) != 0LL;
}

original_code:
int SoundDriver_IsCDSupported(int driver)
{
 return (SoundDrivers[driver].CD_Init != 0);
}


decompiled_code:
_BOOL8 __fastcall SoundDriver_IsMIDISupported(int a1)
{
return *(&off_5B8 + 22 * a1) != 0LL;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(int a1)
{
return *(&off_5B8 + 22 * a1) != 0LL;
}

original_code:
int SoundDriver_IsMIDISupported(int driver)
{
 return (SoundDrivers[driver].MIDI_Init != 0);
}


decompiled_code:
__int64 SoundDriver_PCM_GetError()
{
int v0; // edx
__int64 result; // rax

if ( SoundDriver_IsPCMSupported(ASS_PCMSoundDriver) )
result = ((__int64 (*)(void))*(&SoundDrivers + 22 * v0))();
else
result = 0xFFFFFFFFLL;
return result;
}

canonical_decompiled_code:
__int64 func3()
{
int v0; // edx
__int64 result; // rax

if ( func0(ASS_PCMSoundDriver) )
result = ((__int64 (*)(void))*(&SoundDrivers + 22 * v0))();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int SoundDriver_PCM_GetError(void)
{
 if (!SoundDriver_IsPCMSupported(ASS_PCMSoundDriver)) {
  return -1;
 }
 return SoundDrivers[ASS_PCMSoundDriver].GetError();
}

canonical_original_code:
int SoundDriver_PCM_GetError()
{
 if (!SoundDriver_IsPCMSupported(ASS_PCMSoundDriver)) {
  return -1;
 }
 return SoundDrivers[ASS_PCMSoundDriver].GetError();
}


decompiled_code:
const char *SoundDriver_PCM_ErrorString()
{
__int64 v0; // rdx
unsigned int v1; // er8

if ( (unsigned int)ASS_PCMSoundDriver > 6 )
return "No sound driver selected.";
if ( SoundDriver_IsPCMSupported(ASS_PCMSoundDriver) )
return (const char *)((__int64 (__fastcall *)(_QWORD))*(&off_548 + 22 * v0))(v1);
return "Unsupported sound driver selected.";
}

canonical_decompiled_code:
const char *func4()
{
__int64 v0; // rdx
unsigned int v1; // er8

if ( (unsigned int)ASS_PCMSoundDriver > 6 )
return "No sound driver selected.";
if ( func0(ASS_PCMSoundDriver) )
return (const char *)((__int64 (__fastcall *)(_QWORD))*(&off_548 + 22 * v0))(v1);
return "Unsupported sound driver selected.";
}

original_code:
const char * SoundDriver_PCM_ErrorString( int ErrorNumber )
{
 if (ASS_PCMSoundDriver < 0 || ASS_PCMSoundDriver >= ASS_NumSoundCards) {
  return "No sound driver selected.";
 }
 if (!SoundDriver_IsPCMSupported(ASS_PCMSoundDriver)) {
  return "Unsupported sound driver selected.";
 }
 return SoundDrivers[ASS_PCMSoundDriver].ErrorString(ErrorNumber);
}

canonical_original_code:
char *SoundDriver_PCM_ErrorString(int ErrorNumber)
{
 if (ASS_PCMSoundDriver < 0 || ASS_PCMSoundDriver >= ASS_NumSoundCards) {
  return "No sound driver selected.";
 }
 if (!SoundDriver_IsPCMSupported(ASS_PCMSoundDriver)) {
  return "Unsupported sound driver selected.";
 }
 return SoundDrivers[ASS_PCMSoundDriver].ErrorString(ErrorNumber);
}

variable_types: ErrorNumber int


decompiled_code:
__int64 SoundDriver_CD_GetError()
{
int v0; // edx
__int64 result; // rax

if ( SoundDriver_IsCDSupported(ASS_CDSoundDriver) )
result = ((__int64 (*)(void))*(&SoundDrivers + 22 * v0))();
else
result = 0xFFFFFFFFLL;
return result;
}

canonical_decompiled_code:
__int64 func5()
{
int v0; // edx
__int64 result; // rax

if ( func1(ASS_CDSoundDriver) )
result = ((__int64 (*)(void))*(&SoundDrivers + 22 * v0))();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int SoundDriver_CD_GetError(void)
{
 if (!SoundDriver_IsCDSupported(ASS_CDSoundDriver)) {
  return -1;
 }
 return SoundDrivers[ASS_CDSoundDriver].GetError();
}

canonical_original_code:
int SoundDriver_CD_GetError()
{
 if (!SoundDriver_IsCDSupported(ASS_CDSoundDriver)) {
  return -1;
 }
 return SoundDrivers[ASS_CDSoundDriver].GetError();
}


decompiled_code:
const char *SoundDriver_CD_ErrorString()
{
__int64 v0; // rdx
unsigned int v1; // er8

if ( (unsigned int)ASS_CDSoundDriver > 6 )
return "No sound driver selected.";
if ( SoundDriver_IsCDSupported(ASS_CDSoundDriver) )
return (const char *)((__int64 (__fastcall *)(_QWORD))*(&off_548 + 22 * v0))(v1);
return "Unsupported sound driver selected.";
}

canonical_decompiled_code:
const char *func6()
{
__int64 v0; // rdx
unsigned int v1; // er8

if ( (unsigned int)ASS_CDSoundDriver > 6 )
return "No sound driver selected.";
if ( func1(ASS_CDSoundDriver) )
return (const char *)((__int64 (__fastcall *)(_QWORD))*(&off_548 + 22 * v0))(v1);
return "Unsupported sound driver selected.";
}

original_code:
const char * SoundDriver_CD_ErrorString( int ErrorNumber )
{
 if (ASS_CDSoundDriver < 0 || ASS_CDSoundDriver >= ASS_NumSoundCards) {
  return "No sound driver selected.";
 }
 if (!SoundDriver_IsCDSupported(ASS_CDSoundDriver)) {
  return "Unsupported sound driver selected.";
 }
 return SoundDrivers[ASS_CDSoundDriver].ErrorString(ErrorNumber);
}

canonical_original_code:
char *SoundDriver_CD_ErrorString(int ErrorNumber)
{
 if (ASS_CDSoundDriver < 0 || ASS_CDSoundDriver >= ASS_NumSoundCards) {
  return "No sound driver selected.";
 }
 if (!SoundDriver_IsCDSupported(ASS_CDSoundDriver)) {
  return "Unsupported sound driver selected.";
 }
 return SoundDrivers[ASS_CDSoundDriver].ErrorString(ErrorNumber);
}


decompiled_code:
__int64 SoundDriver_MIDI_GetError()
{
int v0; // edx
__int64 result; // rax

if ( SoundDriver_IsMIDISupported(ASS_MIDISoundDriver) )
result = ((__int64 (*)(void))*(&SoundDrivers + 22 * v0))();
else
result = 0xFFFFFFFFLL;
return result;
}

canonical_decompiled_code:
__int64 func7()
{
int v0; // edx
__int64 result; // rax

if ( func2(ASS_MIDISoundDriver) )
result = ((__int64 (*)(void))*(&SoundDrivers + 22 * v0))();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int SoundDriver_MIDI_GetError(void)
{
 if (!SoundDriver_IsMIDISupported(ASS_MIDISoundDriver)) {
  return -1;
 }
 return SoundDrivers[ASS_MIDISoundDriver].GetError();
}

canonical_original_code:
int SoundDriver_MIDI_GetError()
{
 if (!SoundDriver_IsMIDISupported(ASS_MIDISoundDriver)) {
  return -1;
 }
 return SoundDrivers[ASS_MIDISoundDriver].GetError();
}


decompiled_code:
const char *SoundDriver_MIDI_ErrorString()
{
__int64 v0; // rdx
unsigned int v1; // er8

if ( (unsigned int)ASS_MIDISoundDriver > 6 )
return "No sound driver selected.";
if ( SoundDriver_IsMIDISupported(ASS_MIDISoundDriver) )
return (const char *)((__int64 (__fastcall *)(_QWORD))*(&off_548 + 22 * v0))(v1);
return "Unsupported sound driver selected.";
}

canonical_decompiled_code:
const char *func8()
{
__int64 v0; // rdx
unsigned int v1; // er8

if ( (unsigned int)ASS_MIDISoundDriver > 6 )
return "No sound driver selected.";
if ( func2(ASS_MIDISoundDriver) )
return (const char *)((__int64 (__fastcall *)(_QWORD))*(&off_548 + 22 * v0))(v1);
return "Unsupported sound driver selected.";
}

original_code:
const char * SoundDriver_MIDI_ErrorString( int ErrorNumber )
{
 if (ASS_MIDISoundDriver < 0 || ASS_MIDISoundDriver >= ASS_NumSoundCards) {
  return "No sound driver selected.";
 }
 if (!SoundDriver_IsMIDISupported(ASS_MIDISoundDriver)) {
  return "Unsupported sound driver selected.";
 }
 return SoundDrivers[ASS_MIDISoundDriver].ErrorString(ErrorNumber);
}

canonical_original_code:
char *SoundDriver_MIDI_ErrorString(int ErrorNumber)
{
 if (ASS_MIDISoundDriver < 0 || ASS_MIDISoundDriver >= ASS_NumSoundCards) {
  return "No sound driver selected.";
 }
 if (!SoundDriver_IsMIDISupported(ASS_MIDISoundDriver)) {
  return "Unsupported sound driver selected.";
 }
 return SoundDrivers[ASS_MIDISoundDriver].ErrorString(ErrorNumber);
}


decompiled_code:
__int64 SoundDriver_PCM_Init()
{
return ((__int64 (*)(void))*(&off_550 + 22 * ASS_PCMSoundDriver))();
}

canonical_decompiled_code:
__int64 func9()
{
return ((__int64 (*)(void))*(&off_550 + 22 * ASS_PCMSoundDriver))();
}

original_code:
int SoundDriver_PCM_Init(int * mixrate, int * numchannels, int * samplebits, void * initdata)
{
 return SoundDrivers[ASS_PCMSoundDriver].PCM_Init(mixrate, numchannels, samplebits, initdata);
}

canonical_original_code:
int SoundDriver_PCM_Init(int *mixrate, int *numchannels, int *samplebits, void *initdata)
{
 return SoundDrivers[ASS_PCMSoundDriver].PCM_Init(mixrate, numchannels, samplebits, initdata);
}

variable_types:
mixrate
int *

variable_types:
numchannels
int *

variable_types:
samplebits
int *

variable_types:
initdata
void *


decompiled_code:
__int64 SoundDriver_PCM_Shutdown()
{
return ((__int64 (*)(void))*(&off_558 + 22 * ASS_PCMSoundDriver))();
}

canonical_decompiled_code:
__int64 func10()
{
return ((__int64 (*)(void))*(&off_558 + 22 * ASS_PCMSoundDriver))();
}

original_code:
void SoundDriver_PCM_Shutdown(void)
{
 SoundDrivers[ASS_PCMSoundDriver].PCM_Shutdown();
}

canonical_original_code:
void SoundDriver_PCM_Shutdown()
{
 SoundDrivers[ASS_PCMSoundDriver].PCM_Shutdown();
}


decompiled_code:
__int64 SoundDriver_PCM_BeginPlayback()
{
return ((__int64 (*)(void))*(&off_560 + 22 * ASS_PCMSoundDriver))();
}

canonical_decompiled_code:
__int64 func11()
{
return ((__int64 (*)(void))*(&off_560 + 22 * ASS_PCMSoundDriver))();
}

original_code:
int SoundDriver_PCM_BeginPlayback(char *BufferStart, int BufferSize,
  int NumDivisions, void ( *CallBackFunc )( void ) )
{
 return SoundDrivers[ASS_PCMSoundDriver].PCM_BeginPlayback(BufferStart,
   BufferSize, NumDivisions, CallBackFunc);
}

canonical_original_code:
int SoundDriver_PCM_BeginPlayback(char *BufferStart, int BufferSize, int NumDivisions, void (*CallBackFunc)())
{
 return SoundDrivers[ASS_PCMSoundDriver].PCM_BeginPlayback(BufferStart,
   BufferSize, NumDivisions, CallBackFunc);
}

variable_types:
BufferStart
char *

variable_types: BufferSize int

variable_types: NumDivisions int

variable_types:
CallBackFunc
void (*)()


decompiled_code:
__int64 SoundDriver_PCM_StopPlayback()
{
return ((__int64 (*)(void))*(&off_568 + 22 * ASS_PCMSoundDriver))();
}

canonical_decompiled_code:
__int64 func12()
{
return ((__int64 (*)(void))*(&off_568 + 22 * ASS_PCMSoundDriver))();
}

original_code:
void SoundDriver_PCM_StopPlayback(void)
{
 SoundDrivers[ASS_PCMSoundDriver].PCM_StopPlayback();
}

canonical_original_code:
void SoundDriver_PCM_StopPlayback()
{
 SoundDrivers[ASS_PCMSoundDriver].PCM_StopPlayback();
}


decompiled_code:
__int64 SoundDriver_PCM_Lock()
{
return ((__int64 (*)(void))*(&off_570 + 22 * ASS_PCMSoundDriver))();
}

canonical_decompiled_code:
__int64 func13()
{
return ((__int64 (*)(void))*(&off_570 + 22 * ASS_PCMSoundDriver))();
}

original_code:
void SoundDriver_PCM_Lock(void)
{
 SoundDrivers[ASS_PCMSoundDriver].PCM_Lock();
}

canonical_original_code:
void SoundDriver_PCM_Lock()
{
 SoundDrivers[ASS_PCMSoundDriver].PCM_Lock();
}


decompiled_code:
__int64 SoundDriver_PCM_Unlock()
{
return ((__int64 (*)(void))*(&off_578 + 22 * ASS_PCMSoundDriver))();
}

canonical_decompiled_code:
__int64 func14()
{
return ((__int64 (*)(void))*(&off_578 + 22 * ASS_PCMSoundDriver))();
}

original_code:
void SoundDriver_PCM_Unlock(void)
{
 SoundDrivers[ASS_PCMSoundDriver].PCM_Unlock();
}

canonical_original_code:
void SoundDriver_PCM_Unlock()
{
 SoundDrivers[ASS_PCMSoundDriver].PCM_Unlock();
}


decompiled_code:
__int64 SoundDriver_CD_Init()
{
return ((__int64 (*)(void))*(&off_580 + 22 * ASS_CDSoundDriver))();
}

canonical_decompiled_code:
__int64 func15()
{
return ((__int64 (*)(void))*(&off_580 + 22 * ASS_CDSoundDriver))();
}

original_code:
int SoundDriver_CD_Init(void)
{
    return SoundDrivers[ASS_CDSoundDriver].CD_Init();
}

canonical_original_code:
int SoundDriver_CD_Init()
{
    return SoundDrivers[ASS_CDSoundDriver].CD_Init();
}


decompiled_code:
__int64 SoundDriver_CD_Shutdown()
{
return ((__int64 (*)(void))*(&off_588 + 22 * ASS_CDSoundDriver))();
}

canonical_decompiled_code:
__int64 func16()
{
return ((__int64 (*)(void))*(&off_588 + 22 * ASS_CDSoundDriver))();
}

original_code:
void SoundDriver_CD_Shutdown(void)
{
    SoundDrivers[ASS_CDSoundDriver].CD_Shutdown();
}

canonical_original_code:
void SoundDriver_CD_Shutdown()
{
    SoundDrivers[ASS_CDSoundDriver].CD_Shutdown();
}


decompiled_code:
__int64 SoundDriver_CD_Play()
{
return ((__int64 (*)(void))*(&off_590 + 22 * ASS_CDSoundDriver))();
}

canonical_decompiled_code:
__int64 func17()
{
return ((__int64 (*)(void))*(&off_590 + 22 * ASS_CDSoundDriver))();
}

original_code:
int SoundDriver_CD_Play(int track, int loop)
{
    return SoundDrivers[ASS_CDSoundDriver].CD_Play(track, loop);
}

variable_types: track int

variable_types: loop int


decompiled_code:
__int64 SoundDriver_CD_Stop()
{
return ((__int64 (*)(void))*(&off_598 + 22 * ASS_CDSoundDriver))();
}

canonical_decompiled_code:
__int64 func18()
{
return ((__int64 (*)(void))*(&off_598 + 22 * ASS_CDSoundDriver))();
}

original_code:
void SoundDriver_CD_Stop(void)
{
    SoundDrivers[ASS_CDSoundDriver].CD_Stop();
}

canonical_original_code:
void SoundDriver_CD_Stop()
{
    SoundDrivers[ASS_CDSoundDriver].CD_Stop();
}


decompiled_code:
__int64 SoundDriver_CD_Pause()
{
return ((__int64 (*)(void))*(&off_5A0 + 22 * ASS_CDSoundDriver))();
}

canonical_decompiled_code:
__int64 func19()
{
return ((__int64 (*)(void))*(&off_5A0 + 22 * ASS_CDSoundDriver))();
}

original_code:
void SoundDriver_CD_Pause(int pauseon)
{
    SoundDrivers[ASS_CDSoundDriver].CD_Pause(pauseon);
}

variable_types: pauseon int


decompiled_code:
__int64 SoundDriver_CD_IsPlaying()
{
return ((__int64 (*)(void))*(&off_5A8 + 22 * ASS_CDSoundDriver))();
}

canonical_decompiled_code:
__int64 func20()
{
return ((__int64 (*)(void))*(&off_5A8 + 22 * ASS_CDSoundDriver))();
}

original_code:
int SoundDriver_CD_IsPlaying(void)
{
    return SoundDrivers[ASS_CDSoundDriver].CD_IsPlaying();
}

canonical_original_code:
int SoundDriver_CD_IsPlaying()
{
    return SoundDrivers[ASS_CDSoundDriver].CD_IsPlaying();
}


decompiled_code:
__int64 SoundDriver_CD_SetVolume()
{
return ((__int64 (*)(void))*(&off_5B0 + 22 * ASS_CDSoundDriver))();
}

canonical_decompiled_code:
__int64 func21()
{
return ((__int64 (*)(void))*(&off_5B0 + 22 * ASS_CDSoundDriver))();
}

original_code:
void SoundDriver_CD_SetVolume(int volume)
{
    SoundDrivers[ASS_CDSoundDriver].CD_SetVolume(volume);
}

variable_types: volume int


decompiled_code:
__int64 SoundDriver_MIDI_Init()
{
return ((__int64 (*)(void))*(&off_5B8 + 22 * ASS_MIDISoundDriver))();
}

canonical_decompiled_code:
__int64 func22()
{
return ((__int64 (*)(void))*(&off_5B8 + 22 * ASS_MIDISoundDriver))();
}

original_code:
int SoundDriver_MIDI_Init(midifuncs *funcs)
{
    return SoundDrivers[ASS_MIDISoundDriver].MIDI_Init(funcs);
}

canonical_original_code:
int SoundDriver_MIDI_Init(struct midifuncs *funcs)
{
    return SoundDrivers[ASS_MIDISoundDriver].MIDI_Init(funcs);
}

variable_types: struct midifuncs { void (*NoteOff)(int channel, int key, int velocity); void (*NoteOn)(int channel, int key, int velocity); void (*PolyAftertouch)(int channel, int key, int pressure); void (*ControlChange)(int channel, int number, int value); void (*ProgramChange)(int channel, int program); void (*ChannelAftertouch)(int channel, int pressure); void (*PitchBend)(int channel, int lsb, int msb); void (*ReleasePatches)(); void (*LoadPatch)(int number); void (*SetVolume)(int volume); int (*GetVolume)(); void (*SysEx)(unsigned char *data, int length); } *


decompiled_code:
__int64 SoundDriver_MIDI_Shutdown()
{
return ((__int64 (*)(void))*(&off_5C0 + 22 * ASS_MIDISoundDriver))();
}

canonical_decompiled_code:
__int64 func23()
{
return ((__int64 (*)(void))*(&off_5C0 + 22 * ASS_MIDISoundDriver))();
}

original_code:
void SoundDriver_MIDI_Shutdown(void)
{
    SoundDrivers[ASS_MIDISoundDriver].MIDI_Shutdown();
}

canonical_original_code:
void SoundDriver_MIDI_Shutdown()
{
    SoundDrivers[ASS_MIDISoundDriver].MIDI_Shutdown();
}


decompiled_code:
__int64 SoundDriver_MIDI_StartPlayback()
{
return ((__int64 (*)(void))*(&off_5C8 + 22 * ASS_MIDISoundDriver))();
}

canonical_decompiled_code:
__int64 func24()
{
return ((__int64 (*)(void))*(&off_5C8 + 22 * ASS_MIDISoundDriver))();
}

original_code:
int SoundDriver_MIDI_StartPlayback(void (*service)(void))
{
    return SoundDrivers[ASS_MIDISoundDriver].MIDI_StartPlayback(service);
}

canonical_original_code:
int SoundDriver_MIDI_StartPlayback(void (*service)())
{
    return SoundDrivers[ASS_MIDISoundDriver].MIDI_StartPlayback(service);
}

variable_types:
service
void (*)()


decompiled_code:
__int64 SoundDriver_MIDI_HaltPlayback()
{
return ((__int64 (*)(void))*(&off_5D0 + 22 * ASS_MIDISoundDriver))();
}

canonical_decompiled_code:
__int64 func25()
{
return ((__int64 (*)(void))*(&off_5D0 + 22 * ASS_MIDISoundDriver))();
}

original_code:
void SoundDriver_MIDI_HaltPlayback(void)
{
    SoundDrivers[ASS_MIDISoundDriver].MIDI_HaltPlayback();
}

canonical_original_code:
void SoundDriver_MIDI_HaltPlayback()
{
    SoundDrivers[ASS_MIDISoundDriver].MIDI_HaltPlayback();
}


decompiled_code:
__int64 SoundDriver_MIDI_SetTempo()
{
return ((__int64 (*)(void))*(&off_5D8 + 22 * ASS_MIDISoundDriver))();
}

canonical_decompiled_code:
__int64 func26()
{
return ((__int64 (*)(void))*(&off_5D8 + 22 * ASS_MIDISoundDriver))();
}

original_code:
void SoundDriver_MIDI_SetTempo(int tempo, int division)
{
    SoundDrivers[ASS_MIDISoundDriver].MIDI_SetTempo(tempo, division);
}

variable_types: tempo int

variable_types: division int


decompiled_code:
__int64 SoundDriver_MIDI_Lock()
{
return ((__int64 (*)(void))*(&off_5E0 + 22 * ASS_MIDISoundDriver))();
}

canonical_decompiled_code:
__int64 func27()
{
return ((__int64 (*)(void))*(&off_5E0 + 22 * ASS_MIDISoundDriver))();
}

original_code:
void SoundDriver_MIDI_Lock(void)
{
 SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock();
}

canonical_original_code:
void SoundDriver_MIDI_Lock()
{
 SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock();
}


decompiled_code:
__int64 SoundDriver_MIDI_Unlock()
{
return ((__int64 (*)(void))*(&off_5E8 + 22 * ASS_MIDISoundDriver))();
}

canonical_decompiled_code:
__int64 func28()
{
return ((__int64 (*)(void))*(&off_5E8 + 22 * ASS_MIDISoundDriver))();
}

original_code:
void SoundDriver_MIDI_Unlock(void)
{
 SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock();
}

canonical_original_code:
void SoundDriver_MIDI_Unlock()
{
 SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock();
}


decompiled_code:
__int64 SDLDrv_GetError()
{
return (unsigned int)ErrorCode;
}

canonical_decompiled_code:
__int64 func1()
{
return (unsigned int)ErrorCode;
}

original_code:
int32_t SDLDrv_GetError(void)
{
    return ErrorCode;
}

canonical_original_code:
int SDLDrv_GetError()
{
    return ErrorCode;
}


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

while ( 2 )
{
switch ( a1 )
{
case -2:
case -1:
a1 = ErrorCode;
continue;
case 0:
result = "SDL Audio ok.";
break;
case 1:
result = "SDL Audio uninitialised.";
break;
case 2:
result = "SDL Audio: error in Init or InitSubSystem.";
break;
case 3:
result = "SDL Audio: error in OpenAudio.";
break;
case 4:
result = "SDL Audio: error loading OGG file.";
break;
case 5:
result = "SDL Audio: error playing OGG file.";
break;
default:
result = "Unknown SDL Audio error code.";
break;
}
break;
}
return result;
}

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

while ( 2 )
{
switch ( a1 )
{
case -2:
case -1:
a1 = ErrorCode;
continue;
case 0:
result = "SDL Audio ok.";
break;
case 1:
result = "SDL Audio uninitialised.";
break;
case 2:
result = "SDL Audio: error in Init or InitSubSystem.";
break;
case 3:
result = "SDL Audio: error in OpenAudio.";
break;
case 4:
result = "SDL Audio: error loading OGG file.";
break;
case 5:
result = "SDL Audio: error playing OGG file.";
break;
default:
result = "Unknown SDL Audio error code.";
break;
}
break;
}
return result;
}

original_code:
const char *SDLDrv_ErrorString( int32_t ErrorNumber )
{
    const char *ErrorString;
    switch( ErrorNumber ) {
        case SDLErr_Warning :
        case SDLErr_Error :
            ErrorString = SDLDrv_ErrorString( ErrorCode );
            break;
        case SDLErr_Ok :
            ErrorString = "SDL Audio ok.";
            break;
        case SDLErr_Uninitialised:
            ErrorString = "SDL Audio uninitialised.";
            break;
        case SDLErr_InitSubSystem:
            ErrorString = "SDL Audio: error in Init or InitSubSystem.";
            break;
        case SDLErr_OpenAudio:
            ErrorString = "SDL Audio: error in OpenAudio.";
            break;
        case SDLErr_OpenOGG:
            ErrorString = "SDL Audio: error loading OGG file.";
            break;
        case SDLErr_PlayOGG:
            ErrorString = "SDL Audio: error playing OGG file.";
            break;
        default:
            ErrorString = "Unknown SDL Audio error code.";
            break;
    }
    return ErrorString;
}

canonical_original_code:
char *SDLDrv_ErrorString(int ErrorNumber)
{
    char *ErrorString;
    switch( ErrorNumber ) {
        case SDLErr_Warning :
        case SDLErr_Error :
            ErrorString = SDLDrv_ErrorString( ErrorCode );
            break;
        case SDLErr_Ok :
            ErrorString = "SDL Audio ok.";
            break;
        case SDLErr_Uninitialised:
            ErrorString = "SDL Audio uninitialised.";
            break;
        case SDLErr_InitSubSystem:
            ErrorString = "SDL Audio: error in Init or InitSubSystem.";
            break;
        case SDLErr_OpenAudio:
            ErrorString = "SDL Audio: error in OpenAudio.";
            break;
        case SDLErr_OpenOGG:
            ErrorString = "SDL Audio: error loading OGG file.";
            break;
        case SDLErr_PlayOGG:
            ErrorString = "SDL Audio: error playing OGG file.";
            break;
        default:
            ErrorString = "Unknown SDL Audio error code.";
            break;
    }
    return ErrorString;
}

variable_types: ErrorNumber int

variable_types:
ErrorString
char *


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

result = (unsigned int)Initialised;
if ( Initialised )
{
Mix_HaltChannel(0xFFFFFFFFLL);
if ( DummyChunk )
{
Mix_FreeChunk();
DummyChunk = 0LL;
}
if ( DummyBuffer )
{
free(DummyBuffer);
DummyBuffer = 0LL;
}
Mix_CloseAudio();
result = SDL_DestroyMutex(EffectFence);
Initialised = 0;
}
return result;
}

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

result = (unsigned int)Initialised;
if ( Initialised )
{
Mix_HaltChannel(0xFFFFFFFFLL);
if ( DummyChunk )
{
Mix_FreeChunk();
DummyChunk = 0LL;
}
if ( DummyBuffer )
{
free(DummyBuffer);
DummyBuffer = 0LL;
}
Mix_CloseAudio();
result = SDL_DestroyMutex(EffectFence);
Initialised = 0;
}
return result;
}

original_code:
void SDLDrv_PCM_Shutdown(void)
{
    if (!Initialised)
        return;
    else Mix_HaltChannel(-1);
    if (DummyChunk != ((void *)0))
    {
        Mix_FreeChunk(DummyChunk);
        DummyChunk = ((void *)0);
    }
    if (DummyBuffer != ((void *)0))
    {
        free(DummyBuffer);
        DummyBuffer = ((void *)0);
    }
    Mix_CloseAudio();
    SDL_DestroyMutex(EffectFence);
    Initialised = 0;
}

canonical_original_code:
void SDLDrv_PCM_Shutdown()
{
    if (!Initialised)
        return;
    else Mix_HaltChannel(-1);
    if (DummyChunk != ((void *)0))
    {
        Mix_FreeChunk(DummyChunk);
        DummyChunk = ((void *)0);
    }
    if (DummyBuffer != ((void *)0))
    {
        free(DummyBuffer);
        DummyBuffer = ((void *)0);
    }
    Mix_CloseAudio();
    SDL_DestroyMutex(EffectFence);
    Initialised = 0;
}


decompiled_code:
__int64 __fastcall SDLDrv_PCM_Init(unsigned int *a1, unsigned int *a2, _DWORD *a3)
{
__int64 v6; // rdi
unsigned int v7; // ebp
__int64 v8; // rsi
__int64 result; // rax
__int16 v10[21]; // [rsp+Eh] [rbp-2Ah] BYREF

if ( Initialised )
SDLDrv_PCM_Shutdown();
v6 = *a1;
v7 = 512;
if ( (int)v6 > 15999 )
{
v7 = 2048;
if ( (int)v6 <= 31999 )
v7 = 1024;
}
v8 = (unsigned int)*a3;
if ( (_DWORD)v8 != 8 )
v8 = 32784LL;
if ( (int)Mix_OpenAudio(v6, v8, *a2, v7) < 0 )
{
ErrorCode = 3;
result = 0xFFFFFFFFLL;
}
else
{
if ( (unsigned int)Mix_QuerySpec(a1, v10, a2) )
*a3 = 8 * ((v10[0] & 0x7FFF) != 8) + 8;
EffectFence = SDL_CreateMutex();
Mix_RegisterEffect(2LL, fillData, 0LL, 0LL);
DummyBuffer = calloc((int)v7, 1uLL);
DummyChunk = Mix_QuickLoad_RAW(DummyBuffer, v7);
Mix_PlayChannelTimed(2LL, DummyChunk, 0xFFFFFFFFLL, 0xFFFFFFFFLL);
result = 0LL;
Initialised = 1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned int *a1, unsigned int *a2, _DWORD *a3)
{
__int64 v6; // rdi
unsigned int v7; // ebp
__int64 v8; // rsi
__int64 result; // rax
__int16 v10[21]; // [rsp+Eh] [rbp-2Ah] BYREF

if ( Initialised )
func3();
v6 = *a1;
v7 = 512;
if ( (int)v6 > 15999 )
{
v7 = 2048;
if ( (int)v6 <= 31999 )
v7 = 1024;
}
v8 = (unsigned int)*a3;
if ( (_DWORD)v8 != 8 )
v8 = 32784LL;
if ( (int)Mix_OpenAudio(v6, v8, *a2, v7) < 0 )
{
ErrorCode = 3;
result = 0xFFFFFFFFLL;
}
else
{
if ( (unsigned int)Mix_QuerySpec(a1, v10, a2) )
*a3 = 8 * ((v10[0] & 0x7FFF) != 8) + 8;
EffectFence = SDL_CreateMutex();
Mix_RegisterEffect(2LL, fillData, 0LL, 0LL);
DummyBuffer = calloc((int)v7, 1uLL);
DummyChunk = Mix_QuickLoad_RAW(DummyBuffer, v7);
Mix_PlayChannelTimed(2LL, DummyChunk, 0xFFFFFFFFLL, 0xFFFFFFFFLL);
result = 0LL;
Initialised = 1;
}
return result;
}

original_code:
int32_t SDLDrv_PCM_Init(int32_t *mixrate, int32_t *numchannels, int32_t *samplebits, void * initdata)
{
    int32_t err = 0;
    int32_t chunksize;
    uint16_t fmt;
    numchannels=numchannels;
    initdata=initdata;
    if (Initialised) {
        SDLDrv_PCM_Shutdown();
    }
    chunksize = 512;
    if (*mixrate >= 16000) chunksize *= 2;
    if (*mixrate >= 32000) chunksize *= 2;
    err = Mix_OpenAudio(*mixrate, (*samplebits == 8) ? 0x0008 : 0x8010, *numchannels, chunksize);
    if (err < 0) {
        ErrorCode = SDLErr_OpenAudio;
        return SDLErr_Error;
    }
    if (Mix_QuerySpec(mixrate, &fmt, numchannels))
    {
        if (fmt == 0x0008 || fmt == 0x8008) *samplebits = 8;
        else *samplebits = 16;
    }
    EffectFence = SDL_CreateMutex();
    Mix_RegisterEffect(2, fillData, ((void *)0), ((void *)0));
    DummyBuffer = (uint8_t *) malloc(chunksize);
    memset(DummyBuffer, 0, chunksize);
    DummyChunk = Mix_QuickLoad_RAW(DummyBuffer, chunksize);
    Mix_PlayChannelTimed(2,DummyChunk,-1,-1);
    Initialised = 1;
    return SDLErr_Ok;
}

canonical_original_code:
int SDLDrv_PCM_Init(int *mixrate, int *numchannels, int *samplebits, void *initdata)
{
    int err = 0;
    int chunksize;
    unsigned short fmt;
    numchannels=numchannels;
    initdata=initdata;
    if (Initialised) {
        SDLDrv_PCM_Shutdown();
    }
    chunksize = 512;
    if (*mixrate >= 16000) chunksize *= 2;
    if (*mixrate >= 32000) chunksize *= 2;
    err = Mix_OpenAudio(*mixrate, (*samplebits == 8) ? 0x0008 : 0x8010, *numchannels, chunksize);
    if (err < 0) {
        ErrorCode = SDLErr_OpenAudio;
        return SDLErr_Error;
    }
    if (Mix_QuerySpec(mixrate, &fmt, numchannels))
    {
        if (fmt == 0x0008 || fmt == 0x8008) *samplebits = 8;
        else *samplebits = 16;
    }
    EffectFence = SDL_CreateMutex();
    Mix_RegisterEffect(2, fillData, ((void *)0), ((void *)0));
    DummyBuffer = (unsigned char *) malloc(chunksize);
    memset(DummyBuffer, 0, chunksize);
    DummyChunk = Mix_QuickLoad_RAW(DummyBuffer, chunksize);
    Mix_PlayChannelTimed(2,DummyChunk,-1,-1);
    Initialised = 1;
    return SDLErr_Ok;
}

variable_types:
mixrate
int *

variable_types:
numchannels
int *

variable_types: err int

variable_types: chunksize int

variable_types:
fmt
unsigned short


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

if ( Initialised )
{
result = (unsigned int)Playing;
if ( Playing )
{
result = Mix_Pause(0xFFFFFFFFLL);
Playing = 0;
}
}
return result;
}

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

if ( Initialised )
{
result = (unsigned int)Playing;
if ( Playing )
{
result = Mix_Pause(0xFFFFFFFFLL);
Playing = 0;
}
}
return result;
}

original_code:
void SDLDrv_PCM_StopPlayback(void)
{
    if (!Initialised || !Playing) {
        return;
    }
    Mix_Pause(-1);
    Playing = 0;
}

canonical_original_code:
void SDLDrv_PCM_StopPlayback()
{
    if (!Initialised || !Playing) {
        return;
    }
    Mix_Pause(-1);
    Playing = 0;
}


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

if ( Initialised )
{
if ( Playing )
SDLDrv_PCM_StopPlayback();
MixBuffer = a1;
MixBufferSize = a2;
MixBufferCount = a3;
MixCallBack = a4;
MixBufferCurrent = 0;
MixBufferUsed = 0;
a4();
Mix_Resume(0xFFFFFFFFLL);
result = 0LL;
Playing = 1;
}
else
{
ErrorCode = 1;
result = 0xFFFFFFFFLL;
}
return result;
}

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

if ( Initialised )
{
if ( Playing )
func5();
MixBuffer = a1;
MixBufferSize = a2;
MixBufferCount = a3;
MixCallBack = a4;
MixBufferCurrent = 0;
MixBufferUsed = 0;
a4();
Mix_Resume(0xFFFFFFFFLL);
result = 0LL;
Playing = 1;
}
else
{
ErrorCode = 1;
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int32_t SDLDrv_PCM_BeginPlayback(char *BufferStart, int32_t BufferSize,
                        int32_t NumDivisions, void ( *CallBackFunc )( void ) )
{
    if (!Initialised) {
        ErrorCode = SDLErr_Uninitialised;
        return SDLErr_Error;
    }
    if (Playing) {
        SDLDrv_PCM_StopPlayback();
    }
    MixBuffer = BufferStart;
    MixBufferSize = BufferSize;
    MixBufferCount = NumDivisions;
    MixBufferCurrent = 0;
    MixBufferUsed = 0;
    MixCallBack = CallBackFunc;
    MixCallBack();
    Mix_Resume(-1);
    Playing = 1;
    return SDLErr_Ok;
}

canonical_original_code:
int SDLDrv_PCM_BeginPlayback(char *BufferStart, int BufferSize, int NumDivisions, void (*CallBackFunc)())
{
    if (!Initialised) {
        ErrorCode = SDLErr_Uninitialised;
        return SDLErr_Error;
    }
    if (Playing) {
        SDLDrv_PCM_StopPlayback();
    }
    MixBuffer = BufferStart;
    MixBufferSize = BufferSize;
    MixBufferCount = NumDivisions;
    MixBufferCurrent = 0;
    MixBufferUsed = 0;
    MixCallBack = CallBackFunc;
    MixCallBack();
    Mix_Resume(-1);
    Playing = 1;
    return SDLErr_Ok;
}

variable_types:
BufferStart
char *

variable_types: BufferSize int

variable_types: NumDivisions int


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

result = (unsigned int)InterruptsDisabled++;
if ( !(_DWORD)result )
result = SDL_mutexP(EffectFence);
return result;
}

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

result = (unsigned int)InterruptsDisabled++;
if ( !(_DWORD)result )
result = SDL_mutexP(EffectFence);
return result;
}

original_code:
void SDLDrv_PCM_Lock(void)
{
        if (InterruptsDisabled++)
            return;
        SDL_mutexP(EffectFence);
}

canonical_original_code:
void SDLDrv_PCM_Lock()
{
        if (InterruptsDisabled++)
            return;
        SDL_mutexP(EffectFence);
}


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

if ( !--InterruptsDisabled )
result = SDL_mutexV(EffectFence);
return result;
}

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

if ( !--InterruptsDisabled )
result = SDL_mutexV(EffectFence);
return result;
}

original_code:
void SDLDrv_PCM_Unlock(void)
{
        if (--InterruptsDisabled)
            return;
        SDL_mutexV(EffectFence);
}

canonical_original_code:
void SDLDrv_PCM_Unlock()
{
        if (--InterruptsDisabled)
            return;
        SDL_mutexV(EffectFence);
}


decompiled_code:
__int64 SDLDrv_CD_Init()
{
music = 0LL;
return 0LL;
}

canonical_decompiled_code:
__int64 func9()
{
music = 0LL;
return 0LL;
}

original_code:
int SDLDrv_CD_Init(void) {
    music = ((void *)0);
    return SDLErr_Ok;
}

canonical_original_code:
int SDLDrv_CD_Init() {
    music = ((void *)0);
    return SDLErr_Ok;
}


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

result = Mix_HaltMusic();
music = 0LL;
return result;
}

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

result = Mix_HaltMusic();
music = 0LL;
return result;
}

original_code:
void SDLDrv_CD_Stop(void) {
         Mix_HaltMusic();
         music = ((void *)0);
}

canonical_original_code:
void SDLDrv_CD_Stop() {
         Mix_HaltMusic();
         music = ((void *)0);
}


decompiled_code:
// attributes: thunk
__int64 SDLDrv_CD_Shutdown()
{
return SDLDrv_CD_Stop();
}

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

original_code:
void SDLDrv_CD_Shutdown(void) {
    SDLDrv_CD_Stop();
}

canonical_original_code:
void SDLDrv_CD_Shutdown() {
    SDLDrv_CD_Stop();
}


decompiled_code:
__int64 __fastcall CD_PlayFile(__int64 a1, int a2)
{
unsigned int v2; // er12
const char *v4; // rax
const char *v5; // rax

if ( music )
SDLDrv_CD_Stop();
music = Mix_LoadMUS(a1);
if ( music )
{
v2 = Mix_PlayMusic(music, (unsigned int)-(a2 != 0));
if ( v2 == -1 )
{
v4 = (const char *)SDL_GetError();
printf("Unable to playback OGG file: %s\n", v4);
ErrorCode = 5;
}
else
{
v2 = 0;
}
}
else
{
v5 = (const char *)SDL_GetError();
v2 = -1;
printf("Unable to load OGG file: %s\n", v5);
ErrorCode = 4;
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1, int a2)
{
unsigned int v2; // er12
const char *v4; // rax
const char *v5; // rax

if ( music )
func10();
music = Mix_LoadMUS(a1);
if ( music )
{
v2 = Mix_PlayMusic(music, (unsigned int)-(a2 != 0));
if ( v2 == -1 )
{
v4 = (const char *)SDL_GetError();
printf("Unable to playback OGG file: %s\n", v4);
ErrorCode = 5;
}
else
{
v2 = 0;
}
}
else
{
v5 = (const char *)SDL_GetError();
v2 = -1;
printf("Unable to load OGG file: %s\n", v5);
ErrorCode = 4;
}
return v2;
}

original_code:
int CD_PlayFile(const char * filename, int loop) {
    if (music != ((void *)0)) {
        SDLDrv_CD_Stop();
    }
    music = Mix_LoadMUS(filename);
    if(music == ((void *)0)) {
        printf("Unable to load OGG file: %s\n", SDL_GetError());
        ErrorCode = SDLErr_OpenOGG;
        return SDLErr_Error;
    }
    if(Mix_PlayMusic(music, loop ? -1 : 0) == -1) {
        printf("Unable to playback OGG file: %s\n", SDL_GetError());
        ErrorCode = SDLErr_PlayOGG;
        return SDLErr_Error;
    }
    return SDLErr_Ok;
}

canonical_original_code:
int CD_PlayFile(char *filename, int loop) {
    if (music != ((void *)0)) {
        SDLDrv_CD_Stop();
    }
    music = Mix_LoadMUS(filename);
    if(music == ((void *)0)) {
        printf("Unable to load OGG file: %s\n", SDL_GetError());
        ErrorCode = SDLErr_OpenOGG;
        return SDLErr_Error;
    }
    if(Mix_PlayMusic(music, loop ? -1 : 0) == -1) {
        printf("Unable to playback OGG file: %s\n", SDL_GetError());
        ErrorCode = SDLErr_PlayOGG;
        return SDLErr_Error;
    }
    return SDLErr_Ok;
}

variable_types:
filename
char *

variable_types: loop int


decompiled_code:
__int64 __fastcall CD_PlayByName(const char *a1, const char *a2, int a3)
{
char v5[216]; // [rsp+0h] [rbp-D8h] BYREF

sprintf(v5, "%s/%s", a2, a1);
return CD_PlayFile((__int64)v5, a3);
}

canonical_decompiled_code:
__int64 __fastcall func13(const char *a1, const char *a2, int a3)
{
char v5[216]; // [rsp+0h] [rbp-D8h] BYREF

sprintf(v5, "%s/%s", a2, a1);
return func12((__int64)v5, a3);
}

original_code:
int CD_PlayByName(const char *songname, const char *folder, int loop) {
    char filename[200];
    sprintf(filename, "%s/%s", folder, songname);
    return CD_PlayFile(filename, loop);
}

canonical_original_code:
int CD_PlayByName(char *songname, char *folder, int loop) {
    char filename[200];
    sprintf(filename, "%s/%s", folder, songname);
    return CD_PlayFile(filename, loop);
}

variable_types:
songname
char *

variable_types:
folder
char *

variable_types:
filename
char [200]


decompiled_code:
__int64 __fastcall SDLDrv_CD_Play(unsigned int a1, int a2)
{
char v3[216]; // [rsp+0h] [rbp-D8h] BYREF

sprintf(v3, "classic/MUSIC/Track%02d.ogg", a1);
return CD_PlayFile((__int64)v3, a2);
}

canonical_decompiled_code:
__int64 __fastcall func14(unsigned int a1, int a2)
{
char v3[216]; // [rsp+0h] [rbp-D8h] BYREF

sprintf(v3, "classic/MUSIC/Track%02d.ogg", a1);
return func12((__int64)v3, a2);
}

original_code:
int SDLDrv_CD_Play(int track, int loop) {
    char filename[200];
    sprintf(filename, "classic/MUSIC/Track%02d.ogg", track);
    return CD_PlayFile(filename, loop);
}

variable_types: track int


decompiled_code:
void SDLDrv_CD_Pause()
{
;
}

canonical_decompiled_code:
void func15()
{
;
}

original_code:
void SDLDrv_CD_Pause(int pauseon) {
}

canonical_original_code:
void SDLDrv_CD_Pause(int pauseon) {
}

variable_types: pauseon int


decompiled_code:
_BOOL8 SDLDrv_CD_IsPlaying()
{
return music != 0;
}

canonical_decompiled_code:
_BOOL8 func16()
{
return music != 0;
}

original_code:
int SDLDrv_CD_IsPlaying(void) {
    return music != ((void *)0);
}

canonical_original_code:
int SDLDrv_CD_IsPlaying() {
    return music != ((void *)0);
}


decompiled_code:
__int64 __fastcall SDLDrv_CD_SetVolume(int a1)
{
return Mix_VolumeMusic((unsigned int)(a1 / 2));
}

canonical_decompiled_code:
__int64 __fastcall func17(int a1)
{
return Mix_VolumeMusic((unsigned int)(a1 / 2));
}

original_code:
void SDLDrv_CD_SetVolume(int volume){
    Mix_VolumeMusic(volume/2);
}

variable_types: volume int


decompiled_code:
unsigned __int64 __fastcall seek_vorbis(__int64 a1, __int64 a2, int a3)
{
unsigned __int64 v3; // rcx
__int64 v4; // rax
unsigned __int64 result; // rax

v3 = *(_QWORD *)(a1 + 8);
v4 = 0LL;
if ( a3 )
{
v4 = *(_QWORD *)(a1 + 8);
if ( a3 != 2 )
v4 = *(_QWORD *)(a1 + 16);
}
result = a2 + v4;
if ( result > v3 )
{
*(_QWORD *)(a1 + 16) = v3;
result = v3;
}
else
{
*(_QWORD *)(a1 + 16) = result;
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func0(__int64 a1, __int64 a2, int a3)
{
unsigned __int64 v3; // rcx
__int64 v4; // rax
unsigned __int64 result; // rax

v3 = *(_QWORD *)(a1 + 8);
v4 = 0LL;
if ( a3 )
{
v4 = *(_QWORD *)(a1 + 8);
if ( a3 != 2 )
v4 = *(_QWORD *)(a1 + 16);
}
result = a2 + v4;
if ( result > v3 )
{
*(_QWORD *)(a1 + 16) = v3;
result = v3;
}
else
{
*(_QWORD *)(a1 + 16) = result;
}
return result;
}

original_code:
static int seek_vorbis(void * datasource, ogg_int64_t offset, int whence)
{
   vorbis_data * vorb = (vorbis_data *) datasource;
   switch (whence) {
      case 0: vorb->pos = 0; break;
      case 1: break;
      case 2: vorb->pos = vorb->length; break;
   }
   vorb->pos += offset;
   if (vorb->pos < 0) {
      vorb->pos = 0;
   } else if (vorb->pos > vorb->length) {
      vorb->pos = vorb->length;
   }
   return vorb->pos;
}

canonical_original_code:
static int seek_vorbis(void *datasource, long offset, int whence)
{
   struct vorbis_data *vorb = (vorbis_data *) datasource;
   switch (whence) {
      case 0: vorb->pos = 0; break;
      case 1: break;
      case 2: vorb->pos = vorb->length; break;
   }
   vorb->pos += offset;
   if (vorb->pos < 0) {
      vorb->pos = 0;
   } else if (vorb->pos > vorb->length) {
      vorb->pos = vorb->length;
   }
   return vorb->pos;
}

variable_types:
datasource
void *

variable_types: offset long

variable_types: whence int

variable_types: struct vorbis_data { void *ptr; unsigned long length; unsigned long pos; struct OggVorbis_File { void *datasource; int seekable; long offset; long end; struct ogg_sync_state { unsigned char *data; int storage; int fill; int returned; int unsynced; int headerbytes; int bodybytes; } oy; int links; long *offsets; long *dataoffsets; long *serialnos; long *pcmlengths; struct vorbis_info { int version; int channels; long rate; long bitrate_upper; long bitrate_nominal; long bitrate_lower; long bitrate_window; void *codec_setup; } *vi; struct vorbis_comment { char **user_comments; int *comment_lengths; int comments; char *vendor; } *vc; long pcm_offset; int ready_state; long current_serialno; int current_link; double bittrack; double samptrack; struct ogg_stream_state { unsigned char *body_data; long body_storage; long body_fill; long body_returned; int *lacing_vals; long *granule_vals; long lacing_storage; long lacing_fill; long lacing_packet; long lacing_returned; unsigned char header[282]; int header_fill; int e_o_s; int b_o_s; long serialno; long pageno; long packetno; long granulepos; } os; struct vorbis_dsp_state { int analysisp; struct vorbis_info *vi; float **pcm; float **pcmret; int pcm_storage; int pcm_current; int pcm_returned; int preextrapolate; int eofflag; long lW; long W; long nW; long centerW; long granulepos; long sequence; long glue_bits; long time_bits; long floor_bits; long res_bits; void *backend_state; } vd; struct vorbis_block { float **pcm; struct oggpack_buffer { long endbyte; int endbit; unsigned char *buffer; unsigned char *ptr; long storage; } opb; long lW; long W; long nW; int pcmend; int mode; int eofflag; long granulepos; long sequence; struct vorbis_dsp_state *vd; void *localstore; long localtop; long localalloc; long totaluse; struct alloc_chain { void *ptr; struct alloc_chain *next; } *reap; long glue_bits; long time_bits; long floor_bits; long res_bits; void *internal; } vb; struct ov_callbacks { unsigned long (*read_func)(void *ptr, unsigned long size, unsigned long nmemb, void *datasource); int (*seek_func)(void *datasource, long offset, int whence); int (*close_func)(void *datasource); long (*tell_func)(void *datasource); } callbacks; } vf; char block[32768]; int lastbitstream; } *

user_defined_types: struct vorbis_data { void *ptr; unsigned long length; unsigned long pos; struct OggVorbis_File vf; char block[32768]; int lastbitstream; }

user_defined_types: struct OggVorbis_File { void *datasource; int seekable; long offset; long end; struct ogg_sync_state oy; int links; long *offsets; long *dataoffsets; long *serialnos; long *pcmlengths; struct vorbis_info *vi; struct vorbis_comment *vc; long pcm_offset; int ready_state; long current_serialno; int current_link; double bittrack; double samptrack; struct ogg_stream_state os; struct vorbis_dsp_state vd; struct vorbis_block vb; struct ov_callbacks callbacks; }

user_defined_types: struct vorbis_block { float **pcm; struct oggpack_buffer opb; long lW; long W; long nW; int pcmend; int mode; int eofflag; long granulepos; long sequence; struct vorbis_dsp_state *vd; void *localstore; long localtop; long localalloc; long totaluse; struct alloc_chain *reap; long glue_bits; long time_bits; long floor_bits; long res_bits; void *internal; }


decompiled_code:
__int64 close_vorbis()
{
return 0LL;
}

canonical_decompiled_code:
__int64 func1()
{
return 0LL;
}

original_code:
static int close_vorbis(void * datasource)
{
   return 0;
}

canonical_original_code:
static int close_vorbis(void *datasource)
{
   return 0;
}


decompiled_code:
__int64 __fastcall tell_vorbis(__int64 a1)
{
return *(_QWORD *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
return *(_QWORD *)(a1 + 16);
}

original_code:
static long tell_vorbis(void * datasource)
{
   vorbis_data * vorb = (vorbis_data *) datasource;
   return vorb->pos;
}

canonical_original_code:
static long tell_vorbis(void *datasource)
{
   struct vorbis_data *vorb = (vorbis_data *) datasource;
   return vorb->pos;
}

return_type: long

user_defined_types: struct ogg_sync_state { unsigned char *data; int storage; int fill; int returned; int unsynced; int headerbytes; int bodybytes; }

user_defined_types: struct ogg_stream_state { unsigned char *body_data; long body_storage; long body_fill; long body_returned; int *lacing_vals; long *granule_vals; long lacing_storage; long lacing_fill; long lacing_packet; long lacing_returned; unsigned char header[282]; int header_fill; int e_o_s; int b_o_s; long serialno; long pageno; long packetno; long granulepos; }

user_defined_types: struct vorbis_dsp_state { int analysisp; struct vorbis_info *vi; float **pcm; float **pcmret; int pcm_storage; int pcm_current; int pcm_returned; int preextrapolate; int eofflag; long lW; long W; long nW; long centerW; long granulepos; long sequence; long glue_bits; long time_bits; long floor_bits; long res_bits; void *backend_state; }

user_defined_types: struct ov_callbacks { unsigned long (*read_func)(void *ptr, unsigned long size, unsigned long nmemb, void *datasource); int (*seek_func)(void *datasource, long offset, int whence); int (*close_func)(void *datasource); long (*tell_func)(void *datasource); }

user_defined_types: struct vorbis_info { int version; int channels; long rate; long bitrate_upper; long bitrate_nominal; long bitrate_lower; long bitrate_window; void *codec_setup; }

user_defined_types: struct vorbis_comment { char **user_comments; int *comment_lengths; int comments; char *vendor; }

user_defined_types: struct oggpack_buffer { long endbyte; int endbit; unsigned char *buffer; unsigned char *ptr; long storage; }

user_defined_types: struct alloc_chain { void *ptr; struct alloc_chain *next; }