main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
_BYTE v4[29]; // [rsp+0h] [rbp-28h] BYREF
char s[11]; // [rsp+1Dh] [rbp-Bh] BYREF

if ( argc == 3 )
{
if ( !strcmp(argv[1], "stock.csv") || !strcmp(argv[2], "coins.csv") )
{
system_init(v4);
load_data(v4, argv[1], argv[2]);
while ( 1 )
{
puts("\nMain Menu");
puts("1) Purchase Ticket");
puts("2) Display Tickets");
puts("3) Save and Exit");
puts("Administrator-Only Menu");
puts("4) Add Ticket");
puts("5) Remove Ticket");
puts("6) Display Coins");
puts("7) Restock Tickets");
puts("8) Restock Coins");
puts("9) Abort\n");
printf("Select your option (1-9): ");
fgets(s, 3, stdin);
switch ( atoi(s) )
{
case 0:
puts("Error: Not a valid option! Please try again.\n");
break;
case 1:
purchase_ticket(v4);
break;
case 2:
display_tickets(v4);
break;
case 3:
save_data(v4, 0LL, 0LL);
system_free(v4);
exit(0);
case 4:
add_ticket(v4);
break;
case 5:
delete_ticket(v4);
break;
case 6:
display_coins(v4);
break;
case 7:
restock_tickets(v4);
break;
case 8:
restock_coins(v4);
break;
case 9:
system_free(v4);
exit(0);
default:
continue;
}
}
}
puts("\nError: Cannot load stock.csv and coins.csv! Exiting...\n");
exit(1);
}
puts("Usage: tm <stock.csv> <coins.csv>");
exit(1);
}

original_code:
int main(int argc, char** argv)
{
 int input;
 char *stockfile = ((void *)0), *coinsfile = ((void *)0);
 char charInput[1 + 2];
    tm_type tm;
    BOOLEAN quit = FALSE;
 if (argc != 3){
  printf("Usage: tm <stock.csv> <coins.csv>\n");
  exit(1);
 }
 else{
        if (strcmp(argv[1], "stock.csv") && strcmp(argv[2], "coins.csv") != 0){
            printf("\nError: Cannot load stock.csv and coins.csv! Exiting...\n\n");
            exit(1);
        }
 }
 system_init(&tm);
    load_data(&tm, argv[1], argv[2]);
    while(!quit)
    {
  printf("\nMain Menu\n");
  printf("1) Purchase Ticket\n");
  printf("2) Display Tickets\n");
  printf("3) Save and Exit\n");
  printf("Administrator-Only Menu\n");
  printf("4) Add Ticket\n");
  printf("5) Remove Ticket\n");
  printf("6) Display Coins\n");
  printf("7) Restock Tickets\n");
  printf("8) Restock Coins\n");
  printf("9) Abort\n\n");
        printf("Select your option (1-9): ");
  fgets(charInput, 1 + 2, stdin);
  input = atoi(charInput);
  switch(input){
   case 0:
    printf("Error: Not a valid option! Please try again.\n\n");
    break;
   case 1:
    purchase_ticket(&tm);
    break;
   case 2:
    display_tickets(&tm);
    break;
   case 3:
    save_data(&tm, stockfile, coinsfile);
    system_free(&tm);
    exit(0);
    break;
   case 4:
    add_ticket(&tm);
    break;
   case 5:
    delete_ticket(&tm);
    break;
   case 6:
    display_coins(&tm);
    break;
   case 7:
    restock_tickets(&tm);
    break;
   case 8:
    restock_coins(&tm);
    break;
   case 9:
    quit = TRUE;
    break;
   }
    }
 system_free(&tm);
 exit(0);
}

canonical_original_code:
int main(int argc, char **argv)
{
 int input;
 char *stockfile = ((void *)0); char *coinsfile = ((void *)0);
 char charInput[-1];
    struct tm tm;
    enum truefalse quit = FALSE;
 if (argc != 3){
  printf("Usage: tm <stock.csv> <coins.csv>\n");
  exit(1);
 }
 else{
        if (strcmp(argv[1], "stock.csv") && strcmp(argv[2], "coins.csv") != 0){
            printf("\nError: Cannot load stock.csv and coins.csv! Exiting...\n\n");
            exit(1);
        }
 }
 system_init(&tm);
    load_data(&tm, argv[1], argv[2]);
    while(!quit)
    {
  printf("\nMain Menu\n");
  printf("1) Purchase Ticket\n");
  printf("2) Display Tickets\n");
  printf("3) Save and Exit\n");
  printf("Administrator-Only Menu\n");
  printf("4) Add Ticket\n");
  printf("5) Remove Ticket\n");
  printf("6) Display Coins\n");
  printf("7) Restock Tickets\n");
  printf("8) Restock Coins\n");
  printf("9) Abort\n\n");
        printf("Select your option (1-9): ");
  fgets(charInput, 1 + 2, stdin);
  input = atoi(charInput);
  switch(input){
   case 0:
    printf("Error: Not a valid option! Please try again.\n\n");
    break;
   case 1:
    purchase_ticket(&tm);
    break;
   case 2:
    display_tickets(&tm);
    break;
   case 3:
    save_data(&tm, stockfile, coinsfile);
    system_free(&tm);
    exit(0);
    break;
   case 4:
    add_ticket(&tm);
    break;
   case 5:
    delete_ticket(&tm);
    break;
   case 6:
    display_coins(&tm);
    break;
   case 7:
    restock_tickets(&tm);
    break;
   case 8:
    restock_coins(&tm);
    break;
   case 9:
    quit = TRUE;
    break;
   }
    }
 system_free(&tm);
 exit(0);
}

variable_types: argc int

variable_types:
argv
char **

variable_types:
stockfile
char *

variable_types:
coinsfile
char *

variable_types:
charInput
char [-1]

variable_types: struct tm { struct coin { enum coin_types { FIVE_CENTS=5, TEN_CENTS=10, TWENTY_CENTS=20, FIFTY_CENTS=50, ONE_DOLLAR=100, TWO_DOLLARS=200 } denomination; unsigned int count; } *coins; struct stock_list { struct stock_node { struct stock_data { char ticket_name[-1]; char ticket_type; char ticket_zone[-1]; unsigned int ticket_price; unsigned int stock_level; } *data; struct stock_node *next_node; } *head_stock; unsigned int num_stock_items; } *stock; }

variable_types:
quit
enum truefalse { FALSE=0, TRUE=1 }


decompiled_code:
int __fastcall purchase_ticket(__int64 a1)
{
const char **v1; // rbx
_DWORD *v2; // r15
__int64 v3; // rax
char v4; // r14
const char *v5; // rbp
char v6; // r13
const char *v7; // rax
int v9; // [rsp+4h] [rbp-84h]
const char *v10; // [rsp+8h] [rbp-80h]
char v11[11]; // [rsp+12h] [rbp-76h] BYREF
char v12[3]; // [rsp+1Dh] [rbp-6Bh] BYREF
char s2[104]; // [rsp+20h] [rbp-68h] BYREF

v1 = **(const char ****)(a1 + 8);
v2 = *(_DWORD **)a1;
puts("\nPurchase Ticket");
puts("---------------\n");
v3 = stringinput("Enter a ticket name (1-40 characters): ", s2, 40LL);
if ( v3 )
{
v3 = charinput("Enter a ticket type (1 character): ", v12, 3LL);
if ( v3 )
{
v3 = zoneinput("Enter a zone (1, 2, or 1+2): ", v11, 5LL);
v4 = v12[0];
if ( v3 )
{
while ( 1 )
{
if ( !v1 )
goto LABEL_13;
v5 = *v1;
if ( !strcmp(*v1, s2) )
{
v6 = v5[41];
if ( v6 == v4 && !strcmp(v5 + 42, v11) )
break;
}
v1 = (const char **)v1[1];
if ( !v1[1] )
{
LODWORD(v3) = puts("Error: Could not find ticket!");
return v3;
}
}
v7 = "Concession";
if ( v6 == 70 )
v7 = "Full Fare";
v10 = v7;
LODWORD(v3) = enter_coin(a1, *((unsigned int *)v5 + 14));
v9 = v3;
if ( (_DWORD)v3 != -1 )
{
LABEL_13:
--*((_DWORD *)*v1 + 15);
--*(_DWORD *)(*(_QWORD *)(a1 + 8) + 8LL);
printf("Thank you for purchasing a %s %s zone %s ticket.\n", *v1, v10, *v1 + 42);
printf("Your change is: $%.2f\n", (float)((float)-v9 / 100.0));
LODWORD(v3) = printf("Your change coins are: ");
if ( v9 )
{
if ( v9 >= -5 )
{
--v2[1];
LODWORD(v3) = puts("5c");
}
else if ( v9 >= -10 )
{
--v2[3];
LODWORD(v3) = puts("10c");
}
else if ( v9 >= -20 )
{
--v2[5];
LODWORD(v3) = puts("20c");
}
else if ( v9 >= -50 )
{
--v2[7];
LODWORD(v3) = puts("50c");
}
else if ( v9 >= -100 )
{
--v2[9];
LODWORD(v3) = puts("$1");
}
else if ( v9 >= -200 )
{
--v2[11];
LODWORD(v3) = puts("$2");
}
}
else
{
LODWORD(v3) = puts("None");
}
return v3;
}
}
}
}
return v3;
}

canonical_decompiled_code:
int __fastcall func0(__int64 a1)
{
const char **v1; // rbx
_DWORD *v2; // r15
__int64 v3; // rax
char v4; // r14
const char *v5; // rbp
char v6; // r13
const char *v7; // rax
int v9; // [rsp+4h] [rbp-84h]
const char *v10; // [rsp+8h] [rbp-80h]
char v11[11]; // [rsp+12h] [rbp-76h] BYREF
char v12[3]; // [rsp+1Dh] [rbp-6Bh] BYREF
char s2[104]; // [rsp+20h] [rbp-68h] BYREF

v1 = **(const char ****)(a1 + 8);
v2 = *(_DWORD **)a1;
puts("\nPurchase Ticket");
puts("---------------\n");
v3 = stringinput("Enter a ticket name (1-40 characters): ", s2, 40LL);
if ( v3 )
{
v3 = charinput("Enter a ticket type (1 character): ", v12, 3LL);
if ( v3 )
{
v3 = zoneinput("Enter a zone (1, 2, or 1+2): ", v11, 5LL);
v4 = v12[0];
if ( v3 )
{
while ( 1 )
{
if ( !v1 )
goto LABEL_13;
v5 = *v1;
if ( !strcmp(*v1, s2) )
{
v6 = v5[41];
if ( v6 == v4 && !strcmp(v5 + 42, v11) )
break;
}
v1 = (const char **)v1[1];
if ( !v1[1] )
{
LODWORD(v3) = puts("Error: Could not find ticket!");
return v3;
}
}
v7 = "Concession";
if ( v6 == 70 )
v7 = "Full Fare";
v10 = v7;
LODWORD(v3) = enter_coin(a1, *((unsigned int *)v5 + 14));
v9 = v3;
if ( (_DWORD)v3 != -1 )
{
LABEL_13:
--*((_DWORD *)*v1 + 15);
--*(_DWORD *)(*(_QWORD *)(a1 + 8) + 8LL);
printf("Thank you for purchasing a %s %s zone %s ticket.\n", *v1, v10, *v1 + 42);
printf("Your change is: $%.2f\n", (float)((float)-v9 / 100.0));
LODWORD(v3) = printf("Your change coins are: ");
if ( v9 )
{
if ( v9 >= -5 )
{
--v2[1];
LODWORD(v3) = puts("5c");
}
else if ( v9 >= -10 )
{
--v2[3];
LODWORD(v3) = puts("10c");
}
else if ( v9 >= -20 )
{
--v2[5];
LODWORD(v3) = puts("20c");
}
else if ( v9 >= -50 )
{
--v2[7];
LODWORD(v3) = puts("50c");
}
else if ( v9 >= -100 )
{
--v2[9];
LODWORD(v3) = puts("$1");
}
else if ( v9 >= -200 )
{
--v2[11];
LODWORD(v3) = puts("$2");
}
}
else
{
LODWORD(v3) = puts("None");
}
return v3;
}
}
}
}
return v3;
}

original_code:
void purchase_ticket(tm_type * tm)
{
 stock_node *current = ((void *)0);
 struct coin * coinlist = ((void *)0);
 char temp_ticket_name[40], temp_ticket_type[1 + 2], temp_ticket_zone[10 +1];
 char *prompt1 = "Enter a ticket name (1-40 characters): ";
 char *prompt2 = "Enter a ticket type (1 character): ";
 char *prompt3 = "Enter a zone (1, 2, or 1+2): ";
 char * print;
 int returnedprice;
 current = tm->stock->head_stock;
 coinlist = tm->coins;
 printf("\nPurchase Ticket\n");
 printf("---------------\n\n");
  if (stringinput(prompt1, temp_ticket_name, 40) == FALSE){
   return;
  }
  if (charinput(prompt2, temp_ticket_type, 1 + 2) == FALSE){
   return;
  }
  if (zoneinput(prompt3, temp_ticket_zone, 3 + 2) == FALSE){
   return;
  }
  while(current != ((void *)0)){
   if (strcmp(current->data->ticket_name, temp_ticket_name) == 0 && current->data->ticket_type == temp_ticket_type[0]
   && strcmp(current->data->ticket_zone, temp_ticket_zone) == 0){
    if (current->data->ticket_type == 'F'){
     print = "Full Fare";
    }
    else {
     print = "Concession";
     }
    if((returnedprice = enter_coin(tm, current->data->ticket_price)) == -1){
     return;
    }
    else{
     break;
     }
   }
   current = current->next_node;
   if (current->next_node == ((void *)0)){
    printf("Error: Could not find ticket!\n");
    return;
   }
  }
  current->data->stock_level--;
  tm->stock->num_stock_items--;
  printf("Thank you for purchasing a %s %s zone %s ticket.\n", current->data->ticket_name, print, current->data->ticket_zone);
  printf("Your change is: $%.2f\n", (float)(returnedprice * -1) / 100);
  printf("Your change coins are: ");
  if (returnedprice == 0){
   printf("None\n");
  }
  else if (returnedprice >= -5){
   coinlist[0].count--;
   printf("5c\n");
  }
  else if (returnedprice >= -10){
   coinlist[1].count--;
   printf("10c\n");
  }
  else if (returnedprice >= -20){
   coinlist[2].count--;
   printf("20c\n");
  }
  else if (returnedprice >= -50){
   coinlist[3].count--;
   printf("50c\n");
  }
  else if (returnedprice >= -100){
   coinlist[4].count--;
   printf("$1\n");
  }
  else if (returnedprice >= -200){
   coinlist[5].count--;
   printf("$2\n");
  }
}

canonical_original_code:
void purchase_ticket(struct tm *tm)
{
 struct stock_node *current = ((void *)0);
 struct coin *coinlist = ((void *)0);
 char temp_ticket_name[40]; char temp_ticket_type[-1]; char temp_ticket_zone[-1];
 char *prompt1 = "Enter a ticket name (1-40 characters): ";
 char *prompt2 = "Enter a ticket type (1 character): ";
 char *prompt3 = "Enter a zone (1, 2, or 1+2): ";
 char *print;
 int returnedprice;
 current = tm->stock->head_stock;
 coinlist = tm->coins;
 printf("\nPurchase Ticket\n");
 printf("---------------\n\n");
  if (stringinput(prompt1, temp_ticket_name, 40) == FALSE){
   return;
  }
  if (charinput(prompt2, temp_ticket_type, 1 + 2) == FALSE){
   return;
  }
  if (zoneinput(prompt3, temp_ticket_zone, 3 + 2) == FALSE){
   return;
  }
  while(current != ((void *)0)){
   if (strcmp(current->data->ticket_name, temp_ticket_name) == 0 && current->data->ticket_type == temp_ticket_type[0]
   && strcmp(current->data->ticket_zone, temp_ticket_zone) == 0){
    if (current->data->ticket_type == 'F'){
     print = "Full Fare";
    }
    else {
     print = "Concession";
     }
    if((returnedprice = enter_coin(tm, current->data->ticket_price)) == -1){
     return;
    }
    else{
     break;
     }
   }
   current = current->next_node;
   if (current->next_node == ((void *)0)){
    printf("Error: Could not find ticket!\n");
    return;
   }
  }
  current->data->stock_level--;
  tm->stock->num_stock_items--;
  printf("Thank you for purchasing a %s %s zone %s ticket.\n", current->data->ticket_name, print, current->data->ticket_zone);
  printf("Your change is: $%.2f\n", (float)(returnedprice * -1) / 100);
  printf("Your change coins are: ");
  if (returnedprice == 0){
   printf("None\n");
  }
  else if (returnedprice >= -5){
   coinlist[0].count--;
   printf("5c\n");
  }
  else if (returnedprice >= -10){
   coinlist[1].count--;
   printf("10c\n");
  }
  else if (returnedprice >= -20){
   coinlist[2].count--;
   printf("20c\n");
  }
  else if (returnedprice >= -50){
   coinlist[3].count--;
   printf("50c\n");
  }
  else if (returnedprice >= -100){
   coinlist[4].count--;
   printf("$1\n");
  }
  else if (returnedprice >= -200){
   coinlist[5].count--;
   printf("$2\n");
  }
}

variable_types: struct tm { struct coin { enum coin_types { FIVE_CENTS=5, TEN_CENTS=10, TWENTY_CENTS=20, FIFTY_CENTS=50, ONE_DOLLAR=100, TWO_DOLLARS=200 } denomination; unsigned int count; } *coins; struct stock_list { struct stock_node { struct stock_data { char ticket_name[-1]; char ticket_type; char ticket_zone[-1]; unsigned int ticket_price; unsigned int stock_level; } *data; struct stock_node *next_node; } *head_stock; unsigned int num_stock_items; } *stock; } *

variable_types:
print
char *

variable_types: returnedprice int

return_type: void

user_defined_types: struct tm { struct coin *coins; struct stock_list *stock; }

user_defined_types: struct stock_node { struct stock_data *data; struct stock_node *next_node; }

user_defined_types: struct coin { enum coin_types denomination; unsigned int count; }

user_defined_types: struct stock_list { struct stock_node *head_stock; unsigned int num_stock_items; }


original_code:
void display_tickets(tm_type * tm)
{
 char *print;
 float price;
 stock_node *current = ((void *)0);
 current = tm->stock->head_stock;
 printf("\n\nTicket\t\tType\t\tZone\t\tPrice\tQty\n");
 printf("----------\t--------\t--------\t-----   ---\n");
 while (current != ((void *)0)){
  if (current->data->ticket_type == 'F'){
   print = "Full Fare";
  }
  else {
   print = "Concession";
  }
  price = (float)current->data->ticket_price / 100;
  printf("%s\t\t%s\t%s\t\t$%4.2f\t%3i\n", current->data->ticket_name, print, current->data->ticket_zone, price, current->data->stock_level);
  current = current->next_node;
 }
 printf("\n");
}

canonical_original_code:
void display_tickets(struct tm *tm)
{
 char *print;
 float price;
 struct stock_node *current = ((void *)0);
 current = tm->stock->head_stock;
 printf("\n\nTicket\t\tType\t\tZone\t\tPrice\tQty\n");
 printf("----------\t--------\t--------\t-----   ---\n");
 while (current != ((void *)0)){
  if (current->data->ticket_type == 'F'){
   print = "Full Fare";
  }
  else {
   print = "Concession";
  }
  price = (float)current->data->ticket_price / 100;
  printf("%s\t\t%s\t%s\t\t$%4.2f\t%3i\n", current->data->ticket_name, print, current->data->ticket_zone, price, current->data->stock_level);
  current = current->next_node;
 }
 printf("\n");
}

variable_types: price float

variable_types: struct stock_node { struct stock_data { char ticket_name[-1]; char ticket_type; char ticket_zone[-1]; unsigned int ticket_price; unsigned int stock_level; } *data; struct stock_node *next_node; } *

user_defined_types: enum coin_types { FIVE_CENTS=5, TEN_CENTS=10, TWENTY_CENTS=20, FIFTY_CENTS=50, ONE_DOLLAR=100, TWO_DOLLARS=200 }


decompiled_code:
char __fastcall add_ticket(__int64 a1)
{
__int64 v1; // rax
size_t v2; // rax
size_t v3; // rdx
bool v4; // zf
int v5; // er12
char *v6; // rax
char *v7; // rbp
char v9; // [rsp+7h] [rbp-61h]
char s[10]; // [rsp+8h] [rbp-60h] BYREF
char v11[11]; // [rsp+12h] [rbp-56h] BYREF
char v12[3]; // [rsp+1Dh] [rbp-4Bh] BYREF
char src[72]; // [rsp+20h] [rbp-48h] BYREF

puts("\nAdd Ticket");
puts("-----------\n");
v1 = stringinput("Ticket name (1-40 characters): ", src, 40LL);
if ( v1 )
{
v1 = charinput("Ticket type (1 character): ", v12, 3LL);
if ( v1 )
{
v1 = zoneinput("Ticket zone (1-3 characters): ", v11, 5LL);
if ( v1 )
{
while ( 1 )
{
printf("Price (in cents): ");
fgets(s, 10, stdin);
v2 = strlen(s);
v3 = v2 - 1;
if ( *(&v9 + v2) == 10 )
break;
puts("Error: Input was too long! Try again.");
read_rest_of_line();
}
v4 = strcmp(s, "\n") == 0;
LOBYTE(v1) = !v4;
if ( !v4 )
{
s[v3] = 0;
v5 = atoi(s);
v6 = (char *)malloc(0x40uLL);
v7 = v6;
if ( !v6 )
{
perror("Error: Memory allocation failed! Exiting...\n");
exit(1);
}
strcpy(v6, src);
v7[41] = v12[0];
strcpy(v7 + 42, v11);
*((_DWORD *)v7 + 14) = v5;
*((_DWORD *)v7 + 15) = 10;
add_stock_to_node(a1, v7);
LOBYTE(v1) = puts("Ticket successfully added to system.");
}
}
}
}
return v1;
}

canonical_decompiled_code:
char __fastcall func2(__int64 a1)
{
__int64 v1; // rax
size_t v2; // rax
size_t v3; // rdx
bool v4; // zf
int v5; // er12
char *v6; // rax
char *v7; // rbp
char v9; // [rsp+7h] [rbp-61h]
char s[10]; // [rsp+8h] [rbp-60h] BYREF
char v11[11]; // [rsp+12h] [rbp-56h] BYREF
char v12[3]; // [rsp+1Dh] [rbp-4Bh] BYREF
char src[72]; // [rsp+20h] [rbp-48h] BYREF

puts("\nAdd Ticket");
puts("-----------\n");
v1 = stringinput("Ticket name (1-40 characters): ", src, 40LL);
if ( v1 )
{
v1 = charinput("Ticket type (1 character): ", v12, 3LL);
if ( v1 )
{
v1 = zoneinput("Ticket zone (1-3 characters): ", v11, 5LL);
if ( v1 )
{
while ( 1 )
{
printf("Price (in cents): ");
fgets(s, 10, stdin);
v2 = strlen(s);
v3 = v2 - 1;
if ( *(&v9 + v2) == 10 )
break;
puts("Error: Input was too long! Try again.");
read_rest_of_line();
}
v4 = strcmp(s, "\n") == 0;
LOBYTE(v1) = !v4;
if ( !v4 )
{
s[v3] = 0;
v5 = atoi(s);
v6 = (char *)malloc(0x40uLL);
v7 = v6;
if ( !v6 )
{
perror("Error: Memory allocation failed! Exiting...\n");
exit(1);
}
strcpy(v6, src);
v7[41] = v12[0];
strcpy(v7 + 42, v11);
*((_DWORD *)v7 + 14) = v5;
*((_DWORD *)v7 + 15) = 10;
add_stock_to_node(a1, v7);
LOBYTE(v1) = puts("Ticket successfully added to system.");
}
}
}
}
return v1;
}

original_code:
void add_ticket(tm_type * tm)
{
 struct stock_data *data = ((void *)0);
 char temp_ticket_name[40], temp_ticket_type[1 + 2], temp_ticket_zone[10 +1];
 char char_ticket_price[10];
 unsigned int temp_ticket_price = 0;
 BOOLEAN finished = FALSE;
 char * prompt1 = "Ticket name (1-40 characters): ";
 char * prompt2 = "Ticket type (1 character): ";
 char * prompt3 = "Ticket zone (1-3 characters): ";
 printf("\nAdd Ticket\n");
 printf("-----------\n\n");
 if (stringinput(prompt1, temp_ticket_name, 40) == FALSE){
  return;
 }
 if (charinput(prompt2, temp_ticket_type, 1 + 2) == FALSE){
  return;
 }
 if (zoneinput(prompt3, temp_ticket_zone, 3 + 2) == FALSE){
  return;
 }
 do{
  printf("Price (in cents): ");
  fgets(char_ticket_price, 10, stdin);
  if(char_ticket_price[strlen(char_ticket_price) -1] !='\n'){
                printf("Error: Input was too long! Try again.\n");
                read_rest_of_line();
            }
            else if (strcmp(char_ticket_price, "\n") == 0){
                    return;
            }
            else{
                char_ticket_price[strlen(char_ticket_price) -1] = '\0';
                temp_ticket_price = atoi(char_ticket_price);
    finished = TRUE;
            }
 } while (!finished);
  data = (struct stock_data *)malloc(sizeof(struct stock_data));
  if (!data){
   perror("Error: Memory allocation failed! Exiting...\n");
   free(data);
   exit(1);
  }
  strcpy(data -> ticket_name, temp_ticket_name);
  data ->ticket_type = *temp_ticket_type;
  strcpy(data -> ticket_zone, temp_ticket_zone);
  data -> ticket_price = temp_ticket_price;
  data -> stock_level = 10;
  add_stock_to_node(tm, data);
  printf("Ticket successfully added to system.\n");
}

canonical_original_code:
void add_ticket(struct tm *tm)
{
 struct stock_data *data = ((void *)0);
 char temp_ticket_name[40]; char temp_ticket_type[-1]; char temp_ticket_zone[-1];
 char char_ticket_price[10];
 unsigned int temp_ticket_price = 0;
 enum truefalse finished = FALSE;
 char *prompt1 = "Ticket name (1-40 characters): ";
 char *prompt2 = "Ticket type (1 character): ";
 char *prompt3 = "Ticket zone (1-3 characters): ";
 printf("\nAdd Ticket\n");
 printf("-----------\n\n");
 if (stringinput(prompt1, temp_ticket_name, 40) == FALSE){
  return;
 }
 if (charinput(prompt2, temp_ticket_type, 1 + 2) == FALSE){
  return;
 }
 if (zoneinput(prompt3, temp_ticket_zone, 3 + 2) == FALSE){
  return;
 }
 do{
  printf("Price (in cents): ");
  fgets(char_ticket_price, 10, stdin);
  if(char_ticket_price[strlen(char_ticket_price) -1] !='\n'){
                printf("Error: Input was too long! Try again.\n");
                read_rest_of_line();
            }
            else if (strcmp(char_ticket_price, "\n") == 0){
                    return;
            }
            else{
                char_ticket_price[strlen(char_ticket_price) -1] = '\0';
                temp_ticket_price = atoi(char_ticket_price);
    finished = TRUE;
            }
 } while (!finished);
  data = (struct stock_data *)malloc(sizeof(struct stock_data));
  if (!data){
   perror("Error: Memory allocation failed! Exiting...\n");
   free(data);
   exit(1);
  }
  strcpy(data -> ticket_name, temp_ticket_name);
  data ->ticket_type = *temp_ticket_type;
  strcpy(data -> ticket_zone, temp_ticket_zone);
  data -> ticket_price = temp_ticket_price;
  data -> stock_level = 10;
  add_stock_to_node(tm, data);
  printf("Ticket successfully added to system.\n");
}

variable_types: struct stock_data { char ticket_name[-1]; char ticket_type; char ticket_zone[-1]; unsigned int ticket_price; unsigned int stock_level; } *

variable_types:
finished
enum truefalse { FALSE=0, TRUE=1 }


decompiled_code:
int __fastcall delete_ticket(__int64 a1)
{
__int64 v1; // rbx
__int64 v2; // rax
char v3; // r15
__int64 v4; // r12
const char *v5; // rdx
const char *v6; // rbp
char v7; // r13
_QWORD *v8; // rax
const char *v9; // rbp
char v11[11]; // [rsp+2h] [rbp-76h] BYREF
char v12[3]; // [rsp+Dh] [rbp-6Bh] BYREF
char s2[104]; // [rsp+10h] [rbp-68h] BYREF

v1 = **(_QWORD **)(a1 + 8);
puts("\nDelete Ticket");
puts("----------------\n");
v2 = stringinput("Ticket name (1-40 characters): ", s2, 40LL);
if ( v2 )
{
v2 = charinput("Ticket type (1 character): ", v12, 3LL);
if ( v2 )
{
v2 = zoneinput("Ticket zone (1-3 characters): ", v11, 5LL);
if ( v2 )
{
if ( v1 )
{
v3 = v12[0];
v4 = 0LL;
while ( 1 )
{
v6 = *(const char **)v1;
if ( !strcmp(*(const char **)v1, s2) )
{
v7 = v6[41];
if ( v7 == v3 && !strcmp(v6 + 42, v11) )
break;
}
v4 = v1;
if ( !*(_QWORD *)(v1 + 8) )
goto LABEL_18;
v1 = *(_QWORD *)(v1 + 8);
}
v8 = *(_QWORD **)(a1 + 8);
if ( *v8 == v1 )
{
v5 = "full fare";
if ( v7 != 70 )
v5 = "concession";
*v8 = *(_QWORD *)(v1 + 8);
--*(_DWORD *)(*(_QWORD *)(a1 + 8) + 8LL);
LODWORD(v2) = printf("\nTicket '%s %s zone %s' has been removed from ticketing machine.\n", s2, v5, v11);
}
else
{
v9 = "full fare";
if ( v7 != 70 )
v9 = "concession";
*(_QWORD *)(v4 + 8) = *(_QWORD *)(v1 + 8);
free((void *)v1);
--*(_DWORD *)(*(_QWORD *)(a1 + 8) + 8LL);
LODWORD(v2) = printf("\nTicket '%s %s zone %s' has been removed from ticketing machine.\n", s2, v9, v11);
}
}
else
{
LABEL_18:
LODWORD(v2) = puts("Error: Ticket does not exist! Could not delete ticket!\n");
}
}
}
}
return v2;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
__int64 v1; // rbx
__int64 v2; // rax
char v3; // r15
__int64 v4; // r12
const char *v5; // rdx
const char *v6; // rbp
char v7; // r13
_QWORD *v8; // rax
const char *v9; // rbp
char v11[11]; // [rsp+2h] [rbp-76h] BYREF
char v12[3]; // [rsp+Dh] [rbp-6Bh] BYREF
char s2[104]; // [rsp+10h] [rbp-68h] BYREF

v1 = **(_QWORD **)(a1 + 8);
puts("\nDelete Ticket");
puts("----------------\n");
v2 = stringinput("Ticket name (1-40 characters): ", s2, 40LL);
if ( v2 )
{
v2 = charinput("Ticket type (1 character): ", v12, 3LL);
if ( v2 )
{
v2 = zoneinput("Ticket zone (1-3 characters): ", v11, 5LL);
if ( v2 )
{
if ( v1 )
{
v3 = v12[0];
v4 = 0LL;
while ( 1 )
{
v6 = *(const char **)v1;
if ( !strcmp(*(const char **)v1, s2) )
{
v7 = v6[41];
if ( v7 == v3 && !strcmp(v6 + 42, v11) )
break;
}
v4 = v1;
if ( !*(_QWORD *)(v1 + 8) )
goto LABEL_18;
v1 = *(_QWORD *)(v1 + 8);
}
v8 = *(_QWORD **)(a1 + 8);
if ( *v8 == v1 )
{
v5 = "full fare";
if ( v7 != 70 )
v5 = "concession";
*v8 = *(_QWORD *)(v1 + 8);
--*(_DWORD *)(*(_QWORD *)(a1 + 8) + 8LL);
LODWORD(v2) = printf("\nTicket '%s %s zone %s' has been removed from ticketing machine.\n", s2, v5, v11);
}
else
{
v9 = "full fare";
if ( v7 != 70 )
v9 = "concession";
*(_QWORD *)(v4 + 8) = *(_QWORD *)(v1 + 8);
free((void *)v1);
--*(_DWORD *)(*(_QWORD *)(a1 + 8) + 8LL);
LODWORD(v2) = printf("\nTicket '%s %s zone %s' has been removed from ticketing machine.\n", s2, v9, v11);
}
}
else
{
LABEL_18:
LODWORD(v2) = puts("Error: Ticket does not exist! Could not delete ticket!\n");
}
}
}
}
return v2;
}

original_code:
void delete_ticket(tm_type * tm)
{
 struct stock_node *current = ((void *)0), *previous = ((void *)0), *next = ((void *)0);
 char temp_ticket_name[40], temp_ticket_type[1 + 2], temp_ticket_zone[10 +1];
 char *print;
 char * prompt1 = "Ticket name (1-40 characters): ";
 char * prompt2 = "Ticket type (1 character): ";
 char * prompt3 = "Ticket zone (1-3 characters): ";
 current = tm->stock->head_stock;
 printf("\nDelete Ticket\n");
 printf("----------------\n\n");
 if (stringinput(prompt1, temp_ticket_name, 40) == FALSE){
  return;
 }
 if (charinput(prompt2, temp_ticket_type, 1 + 2) == FALSE){
  return;
 }
 if (zoneinput(prompt3, temp_ticket_zone, 3 + 2) == FALSE){
  return;
 }
 while (current != ((void *)0)){
  if (strcmp(current->data->ticket_name, temp_ticket_name) == 0 && current->data->ticket_type == temp_ticket_type[0]
   && strcmp(current->data->ticket_zone, temp_ticket_zone) == 0){
    if (current == tm->stock->head_stock){
     if (current->data->ticket_type == 'F'){
      print = "full fare";
     }
     else {
      print = "concession";
     }
     tm->stock->head_stock = current->next_node;
     tm->stock->num_stock_items--;
     printf("\nTicket \'%s %s zone %s\' has been removed from ticketing machine.\n", temp_ticket_name, print, temp_ticket_zone);
     return;
    }
     else{
     if (current->data->ticket_type == 'F'){
      print = "full fare";
     }
     else {
      print = "concession";
     }
     next = current->next_node;
     previous->next_node = next;
     free(current);
     tm->stock->num_stock_items--;
     printf("\nTicket \'%s %s zone %s\' has been removed from ticketing machine.\n", temp_ticket_name, print, temp_ticket_zone);
     return;
     }
  }
   previous = current;
   current = current->next_node;
  }
  printf("Error: Ticket does not exist! Could not delete ticket!\n\n");
  return;
}

canonical_original_code:
void delete_ticket(struct tm *tm)
{
 struct stock_node *current = ((void *)0); struct stock_node *previous = ((void *)0); struct stock_node *next = ((void *)0);
 char temp_ticket_name[40]; char temp_ticket_type[-1]; char temp_ticket_zone[-1];
 char *print;
 char *prompt1 = "Ticket name (1-40 characters): ";
 char *prompt2 = "Ticket type (1 character): ";
 char *prompt3 = "Ticket zone (1-3 characters): ";
 current = tm->stock->head_stock;
 printf("\nDelete Ticket\n");
 printf("----------------\n\n");
 if (stringinput(prompt1, temp_ticket_name, 40) == FALSE){
  return;
 }
 if (charinput(prompt2, temp_ticket_type, 1 + 2) == FALSE){
  return;
 }
 if (zoneinput(prompt3, temp_ticket_zone, 3 + 2) == FALSE){
  return;
 }
 while (current != ((void *)0)){
  if (strcmp(current->data->ticket_name, temp_ticket_name) == 0 && current->data->ticket_type == temp_ticket_type[0]
   && strcmp(current->data->ticket_zone, temp_ticket_zone) == 0){
    if (current == tm->stock->head_stock){
     if (current->data->ticket_type == 'F'){
      print = "full fare";
     }
     else {
      print = "concession";
     }
     tm->stock->head_stock = current->next_node;
     tm->stock->num_stock_items--;
     printf("\nTicket \'%s %s zone %s\' has been removed from ticketing machine.\n", temp_ticket_name, print, temp_ticket_zone);
     return;
    }
     else{
     if (current->data->ticket_type == 'F'){
      print = "full fare";
     }
     else {
      print = "concession";
     }
     next = current->next_node;
     previous->next_node = next;
     free(current);
     tm->stock->num_stock_items--;
     printf("\nTicket \'%s %s zone %s\' has been removed from ticketing machine.\n", temp_ticket_name, print, temp_ticket_zone);
     return;
     }
  }
   previous = current;
   current = current->next_node;
  }
  printf("Error: Ticket does not exist! Could not delete ticket!\n\n");
  return;
}

user_defined_types: struct stock_data { char ticket_name[-1]; char ticket_type; char ticket_zone[-1]; unsigned int ticket_price; unsigned int stock_level; }


decompiled_code:
int __fastcall display_coins(int **a1)
{
int *v1; // rbx
int *v2; // rbp
float v3; // xmm0_4
float v5; // [rsp+8h] [rbp-20h]
float v6; // [rsp+Ch] [rbp-1Ch]

v1 = *a1;
puts("\nCoin\tQuantity\tValue");
puts("----\t--------\t-----");
v2 = v1 + 12;
v6 = 0.0;
do
{
v3 = (float)*v1 / 100.0;
v5 = (float)v1[1] * v3;
printf("$%.2f\t%i\t\t$%.2f\n", v3, (unsigned int)v1[1], v5);
v6 = v6 + v5;
v1 += 2;
}
while ( v2 != v1 );
puts("\t\t\t-----");
return printf("Total Value: \t\t$%.2f\n", v6);
}

original_code:
void display_coins(tm_type * tm)
{
 int i = 0;
 float total = 0, grandtotal = 0;
 float amount = 0;
 struct coin *listptr = ((void *)0);
 listptr = tm->coins;
 printf("\nCoin\tQuantity\tValue\n");
 printf("----\t--------\t-----\n");
 for (i = 0; i < 6; i++){
  amount = (float)listptr->denomination / 100;
  total = amount * listptr->count;
  printf("$%.2f\t%i\t\t$%.2f\n", amount, listptr->count, total);
  grandtotal += total;
  listptr++;
 }
 printf("\t\t\t-----\n");
 printf("Total Value: \t\t$%.2f\n", grandtotal);
 listptr = ((void *)0);
}

canonical_original_code:
void display_coins(struct tm *tm)
{
 int i = 0;
 float total = 0; float grandtotal = 0;
 float amount = 0;
 struct coin *listptr = ((void *)0);
 listptr = tm->coins;
 printf("\nCoin\tQuantity\tValue\n");
 printf("----\t--------\t-----\n");
 for (i = 0; i < 6; i++){
  amount = (float)listptr->denomination / 100;
  total = amount * listptr->count;
  printf("$%.2f\t%i\t\t$%.2f\n", amount, listptr->count, total);
  grandtotal += total;
  listptr++;
 }
 printf("\t\t\t-----\n");
 printf("Total Value: \t\t$%.2f\n", grandtotal);
 listptr = ((void *)0);
}

variable_types: i int

variable_types: total float

variable_types: grandtotal float

variable_types: amount float

variable_types: struct coin { enum coin_types { FIVE_CENTS=5, TEN_CENTS=10, TWENTY_CENTS=20, FIFTY_CENTS=50, ONE_DOLLAR=100, TWO_DOLLARS=200 } denomination; unsigned int count; } *


decompiled_code:
int __fastcall restock_tickets(__int64 a1)
{
_QWORD *v1; // rbx

v1 = **(_QWORD ***)(a1 + 8);
puts("\nRestock Tickets");
puts("---------------");
for ( ; v1; v1 = (_QWORD *)v1[1] )
*(_DWORD *)(*v1 + 60LL) = 10;
return puts("All ticket products have been restocked to the default level.\n");
}

canonical_decompiled_code:
int __fastcall func5(__int64 a1)
{
_QWORD *v1; // rbx

v1 = **(_QWORD ***)(a1 + 8);
puts("\nRestock Tickets");
puts("---------------");
for ( ; v1; v1 = (_QWORD *)v1[1] )
*(_DWORD *)(*v1 + 60LL) = 10;
return puts("All ticket products have been restocked to the default level.\n");
}

original_code:
void restock_tickets(tm_type * tm)
{
 stock_node *current = ((void *)0);
 current = tm->stock->head_stock;
 printf("\nRestock Tickets\n");
 printf("---------------\n");
 while (current != ((void *)0)){
  current->data->stock_level = 10;
  current = current->next_node;
 }
 printf("All ticket products have been restocked to the default level.\n\n");
}

canonical_original_code:
void restock_tickets(struct tm *tm)
{
 struct stock_node *current = ((void *)0);
 current = tm->stock->head_stock;
 printf("\nRestock Tickets\n");
 printf("---------------\n");
 while (current != ((void *)0)){
  current->data->stock_level = 10;
  current = current->next_node;
 }
 printf("All ticket products have been restocked to the default level.\n\n");
}


decompiled_code:
int __fastcall restock_coins(__int64 *a1)
{
__int64 v1; // rbx
__int64 v2; // rax

v1 = *a1;
puts("\nRestock Coins");
puts("---------------");
v2 = v1 + 48;
do
{
*(_DWORD *)(v1 + 4) = 50;
v1 += 8LL;
}
while ( v2 != v1 );
return puts("All coins have been restocked to the default level.\n");
}

canonical_decompiled_code:
int __fastcall func6(__int64 *a1)
{
__int64 v1; // rbx
__int64 v2; // rax

v1 = *a1;
puts("\nRestock Coins");
puts("---------------");
v2 = v1 + 48;
do
{
*(_DWORD *)(v1 + 4) = 50;
v1 += 8LL;
}
while ( v2 != v1 );
return puts("All coins have been restocked to the default level.\n");
}

original_code:
void restock_coins(tm_type * tm)
{
 int i = 0;
 struct coin *listptr;
 listptr = tm->coins;
 printf("\nRestock Coins\n");
 printf("---------------\n");
 for (i = 0; i < 6; i++){
  listptr->count = 50;
  listptr++;
 }
 printf("All coins have been restocked to the default level.\n\n");
}

canonical_original_code:
void restock_coins(struct tm *tm)
{
 int i = 0;
 struct coin *listptr;
 listptr = tm->coins;
 printf("\nRestock Coins\n");
 printf("---------------\n");
 for (i = 0; i < 6; i++){
  listptr->count = 50;
  listptr++;
 }
 printf("All coins have been restocked to the default level.\n\n");
}


decompiled_code:
int __fastcall stock_cmp(const char *a1, const char *a2)
{
return strcmp(a1, a2);
}

canonical_decompiled_code:
int __fastcall func0(const char *a1, const char *a2)
{
return strcmp(a1, a2);
}

original_code:
int stock_cmp(struct stock_data *first, struct stock_data *second){
 int cmp = 0;
    cmp = strcmp(first->ticket_name, second->ticket_name);
    if(cmp != 0){
        return cmp;
 }
    return strcmp(first->ticket_name, second->ticket_name);
}

variable_types:
second
struct stock_data *

variable_types: cmp int

return_type: int


original_code:
BOOLEAN add_stock_to_node(tm_type_ptr tm, struct stock_data *data){
 stock_node *currentItem = ((void *)0), *previousItem = ((void *)0), *newItem = ((void *)0);
 newItem = (stock_node *)malloc(sizeof(stock_node));
 if (!newItem){
  perror("Error: Memory allocation failed! Exiting...\n");
  free(newItem);
  exit(1);
 }
 newItem->data = data;
 newItem->next_node = ((void *)0);
 if (tm->stock->head_stock == ((void *)0)){
  tm->stock->head_stock = newItem;
 }
 else{
  currentItem = tm->stock->head_stock;
  while(currentItem != ((void *)0) && stock_cmp(currentItem->data, data) < 0){
   previousItem = currentItem;
   currentItem = currentItem->next_node;
  }
  if (previousItem == ((void *)0)){
   newItem->next_node = tm->stock->head_stock;
   tm->stock->head_stock = newItem;
  }
  else{
   newItem->next_node = currentItem;
   previousItem->next_node = newItem;
  }
 }
 tm->stock->num_stock_items++;
 return TRUE;
}

canonical_original_code:
enum truefalse add_stock_to_node(struct tm *tm, struct stock_data *data){
 struct stock_node *currentItem = ((void *)0); struct stock_node *previousItem = ((void *)0); struct stock_node *newItem = ((void *)0);
 newItem = (struct stock_node *)malloc(sizeof(stock_node));
 if (!newItem){
  perror("Error: Memory allocation failed! Exiting...\n");
  free(newItem);
  exit(1);
 }
 newItem->data = data;
 newItem->next_node = ((void *)0);
 if (tm->stock->head_stock == ((void *)0)){
  tm->stock->head_stock = newItem;
 }
 else{
  currentItem = tm->stock->head_stock;
  while(currentItem != ((void *)0) && stock_cmp(currentItem->data, data) < 0){
   previousItem = currentItem;
   currentItem = currentItem->next_node;
  }
  if (previousItem == ((void *)0)){
   newItem->next_node = tm->stock->head_stock;
   tm->stock->head_stock = newItem;
  }
  else{
   newItem->next_node = currentItem;
   previousItem->next_node = newItem;
  }
 }
 tm->stock->num_stock_items++;
 return TRUE;
}

variable_types:
data
struct stock_data *

return_type: enum truefalse { FALSE=0, TRUE=1 }


decompiled_code:
__int64 __fastcall tokenize_stock_file(__int64 a1, char *a2)
{
char *v2; // rbp
char *v3; // rax
char *v4; // rsi
int v5; // ebx
char v6; // al
char v8[10]; // [rsp+Ch] [rbp-8Ch] BYREF
char nptr[10]; // [rsp+16h] [rbp-82h] BYREF
char src[48]; // [rsp+20h] [rbp-78h] BYREF
char dest[72]; // [rsp+50h] [rbp-48h] BYREF

v2 = (char *)malloc(0x40uLL);
v3 = strtok(a2, ",");
if ( v3 )
{
v4 = v3;
v5 = 2;
do
{
switch ( v5 )
{
case 2:
strcpy(dest, v4);
strcpy(v2, dest);
break;
case 3:
v6 = *v4;
if ( *v4 != 70 )
v6 = 67;
v2[41] = v6;
break;
case 4:
strcpy(src, v4);
strcpy(v2 + 42, src);
break;
case 5:
strcpy(nptr, v4);
*((_DWORD *)v2 + 14) = atoi(nptr);
goto LABEL_9;
case 6:
strcpy(v8, v4);
*((_DWORD *)v2 + 15) = atoi(v8);
break;
default:
if ( v5 == 5 )
LABEL_9:
add_stock_to_node(a1, v2);
break;
}
v4 = strtok(0LL, ",");
++v5;
}
while ( v4 );
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, char *a2)
{
char *v2; // rbp
char *v3; // rax
char *v4; // rsi
int v5; // ebx
char v6; // al
char v8[10]; // [rsp+Ch] [rbp-8Ch] BYREF
char nptr[10]; // [rsp+16h] [rbp-82h] BYREF
char src[48]; // [rsp+20h] [rbp-78h] BYREF
char dest[72]; // [rsp+50h] [rbp-48h] BYREF

v2 = (char *)malloc(0x40uLL);
v3 = strtok(a2, ",");
if ( v3 )
{
v4 = v3;
v5 = 2;
do
{
switch ( v5 )
{
case 2:
strcpy(dest, v4);
strcpy(v2, dest);
break;
case 3:
v6 = *v4;
if ( *v4 != 70 )
v6 = 67;
v2[41] = v6;
break;
case 4:
strcpy(src, v4);
strcpy(v2 + 42, src);
break;
case 5:
strcpy(nptr, v4);
*((_DWORD *)v2 + 14) = atoi(nptr);
goto LABEL_9;
case 6:
strcpy(v8, v4);
*((_DWORD *)v2 + 15) = atoi(v8);
break;
default:
if ( v5 == 5 )
LABEL_9:
func1(a1, v2);
break;
}
v4 = strtok(0LL, ",");
++v5;
}
while ( v4 );
}
return 1LL;
}

original_code:
BOOLEAN tokenize_stock_file(tm_type_ptr tm, char *stockfile){
 struct stock_data *data = ((void *)0);
 char *buffer;
 int count = 1;
 char temp_ticket_name[40], temp_ticket_type, temp_ticket_zone[40];
 char char_ticket_price[10], char_stock_level[10];
 unsigned int temp_ticket_price, temp_stock_level;
 data = (struct stock_data *)malloc(sizeof(struct stock_data));
 buffer = strtok(stockfile, ",");
 while(buffer != ((void *)0)){
  switch(count){
   case 1:
    strcpy(temp_ticket_name, buffer);
     if (strlen(temp_ticket_name) > 40 + 1){
      printf("Error: corrupted data when loading Ticket name! Exiting...\n");
      exit(1);
     }
    strcpy(data -> ticket_name, temp_ticket_name);
    break;
   case 2:
    if (*buffer == 'F'){
     temp_ticket_type = 'F';
    }
    else {
     temp_ticket_type = 'C';
    }
    data ->ticket_type = temp_ticket_type;
    break;
   case 3:
    strcpy(temp_ticket_zone, buffer);
     if (strlen(temp_ticket_name) > 40 + 1){
      printf("Error: corrupted data when loading Ticket zone! Exiting...\n");
      exit(1);
     }
    strcpy(data->ticket_zone, temp_ticket_zone);
    break;
   case 4:
    strcpy(char_ticket_price, buffer);
     if (strlen(char_ticket_price) > 100000){
      printf("Error: corrupted data when loading Ticket price! Exiting...\n");
      exit(1);
     }
    temp_ticket_price = atoi(char_ticket_price);
    data->ticket_price = temp_ticket_price;
    break;
   case 5:
    strcpy(char_stock_level, buffer);
     if (strlen(char_stock_level) > 10){
      printf("Error: corrupted data when loading Stock level! Exiting...\n");
      exit(1);
     }
    temp_stock_level = atoi(char_stock_level);
    data->stock_level = temp_stock_level;
    break;
  }
  count++;
  if (count == 5){
   add_stock_to_node(tm, data);
  }
  buffer = strtok(((void *)0), ",");
 }
 return TRUE;
}

canonical_original_code:
enum truefalse tokenize_stock_file(struct tm *tm, char *stockfile){
 struct stock_data *data = ((void *)0);
 char *buffer;
 int count = 1;
 char temp_ticket_name[40]; char temp_ticket_type; char temp_ticket_zone[40];
 char char_ticket_price[10]; char char_stock_level[10];
 unsigned int temp_ticket_price; unsigned int temp_stock_level;
 data = (struct stock_data *)malloc(sizeof(struct stock_data));
 buffer = strtok(stockfile, ",");
 while(buffer != ((void *)0)){
  switch(count){
   case 1:
    strcpy(temp_ticket_name, buffer);
     if (strlen(temp_ticket_name) > 40 + 1){
      printf("Error: corrupted data when loading Ticket name! Exiting...\n");
      exit(1);
     }
    strcpy(data -> ticket_name, temp_ticket_name);
    break;
   case 2:
    if (*buffer == 'F'){
     temp_ticket_type = 'F';
    }
    else {
     temp_ticket_type = 'C';
    }
    data ->ticket_type = temp_ticket_type;
    break;
   case 3:
    strcpy(temp_ticket_zone, buffer);
     if (strlen(temp_ticket_name) > 40 + 1){
      printf("Error: corrupted data when loading Ticket zone! Exiting...\n");
      exit(1);
     }
    strcpy(data->ticket_zone, temp_ticket_zone);
    break;
   case 4:
    strcpy(char_ticket_price, buffer);
     if (strlen(char_ticket_price) > 100000){
      printf("Error: corrupted data when loading Ticket price! Exiting...\n");
      exit(1);
     }
    temp_ticket_price = atoi(char_ticket_price);
    data->ticket_price = temp_ticket_price;
    break;
   case 5:
    strcpy(char_stock_level, buffer);
     if (strlen(char_stock_level) > 10){
      printf("Error: corrupted data when loading Stock level! Exiting...\n");
      exit(1);
     }
    temp_stock_level = atoi(char_stock_level);
    data->stock_level = temp_stock_level;
    break;
  }
  count++;
  if (count == 5){
   add_stock_to_node(tm, data);
  }
  buffer = strtok(((void *)0), ",");
 }
 return TRUE;
}

variable_types:
stockfile
char *

variable_types:
buffer
char *

variable_types: count int


decompiled_code:
__int64 __fastcall add_coin_to_node(__int64 a1, int *a2)
{
int v2; // eax

v2 = *a2;
if ( *a2 == 5 )
{
**(_QWORD **)a1 = *(_QWORD *)a2;
free(a2);
}
else
{
switch ( v2 )
{
case 10:
*(_QWORD *)(*(_QWORD *)a1 + 8LL) = *(_QWORD *)a2;
free(a2);
break;
case 20:
*(_QWORD *)(*(_QWORD *)a1 + 16LL) = *(_QWORD *)a2;
free(a2);
break;
case 50:
*(_QWORD *)(*(_QWORD *)a1 + 24LL) = *(_QWORD *)a2;
free(a2);
break;
case 100:
*(_QWORD *)(*(_QWORD *)a1 + 32LL) = *(_QWORD *)a2;
free(a2);
break;
case 200:
*(_QWORD *)(*(_QWORD *)a1 + 40LL) = *(_QWORD *)a2;
free(a2);
break;
default:
puts("Error: Invalid coin type in data file! Exiting...");
exit(1);
}
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, int *a2)
{
int v2; // eax

v2 = *a2;
if ( *a2 == 5 )
{
**(_QWORD **)a1 = *(_QWORD *)a2;
free(a2);
}
else
{
switch ( v2 )
{
case 10:
*(_QWORD *)(*(_QWORD *)a1 + 8LL) = *(_QWORD *)a2;
free(a2);
break;
case 20:
*(_QWORD *)(*(_QWORD *)a1 + 16LL) = *(_QWORD *)a2;
free(a2);
break;
case 50:
*(_QWORD *)(*(_QWORD *)a1 + 24LL) = *(_QWORD *)a2;
free(a2);
break;
case 100:
*(_QWORD *)(*(_QWORD *)a1 + 32LL) = *(_QWORD *)a2;
free(a2);
break;
case 200:
*(_QWORD *)(*(_QWORD *)a1 + 40LL) = *(_QWORD *)a2;
free(a2);
break;
default:
puts("Error: Invalid coin type in data file! Exiting...");
exit(1);
}
}
return 1LL;
}

original_code:
BOOLEAN add_coin_to_node(tm_type_ptr tm, struct coin *data){
  if (data->denomination == FIVE_CENTS){
   tm->coins[0] = *data;
   free(data);
  }
  else if (data->denomination == TEN_CENTS){
   tm->coins[1] = *data;
   free(data);
  }
  else if (data->denomination == TWENTY_CENTS){
   tm->coins[2] = *data;
   free(data);
  }
  else if (data->denomination == FIFTY_CENTS){
   tm->coins[3] = *data;
   free(data);
  }
  else if (data->denomination == ONE_DOLLAR){
   tm->coins[4] = *data;
   free(data);
  }
  else if (data->denomination == TWO_DOLLARS){
   tm->coins[5] = *data;
   free(data);
  }
  else {
   printf("Error: Invalid coin type in data file! Exiting...\n");
   exit(1);
  }
return TRUE;
}

canonical_original_code:
enum truefalse add_coin_to_node(struct tm *tm, struct coin *data){
  if (data->denomination == FIVE_CENTS){
   tm->coins[0] = *data;
   free(data);
  }
  else if (data->denomination == TEN_CENTS){
   tm->coins[1] = *data;
   free(data);
  }
  else if (data->denomination == TWENTY_CENTS){
   tm->coins[2] = *data;
   free(data);
  }
  else if (data->denomination == FIFTY_CENTS){
   tm->coins[3] = *data;
   free(data);
  }
  else if (data->denomination == ONE_DOLLAR){
   tm->coins[4] = *data;
   free(data);
  }
  else if (data->denomination == TWO_DOLLARS){
   tm->coins[5] = *data;
   free(data);
  }
  else {
   printf("Error: Invalid coin type in data file! Exiting...\n");
   exit(1);
  }
return TRUE;
}

variable_types: struct tm { struct coin { enum coin_types { FIVE_CENTS=5, TEN_CENTS=10, TWENTY_CENTS=20, FIFTY_CENTS=50, ONE_DOLLAR=100, TWO_DOLLARS=200 } denomination; unsigned int count; } *coins; struct stock_list { struct stock_node { struct stock_data { char ticket_name[-1]; char ticket_type; char ticket_zone[-1]; unsigned int ticket_price; unsigned int stock_level; } *data; struct stock_node *next_node; } *head_stock; unsigned int num_stock_items; } *stock; } *

variable_types:
data
struct coin *


decompiled_code:
__int64 __fastcall tokenize_coins_file(__int64 a1, char *a2)
{
int *v3; // rbp
char *v4; // rax
char *v5; // rdi
int v6; // ebx
int v7; // eax

v3 = (int *)malloc(8uLL);
*v3 = 0;
v3[1] = 0;
v4 = strtok(a2, ",");
if ( v4 )
{
v5 = v4;
v6 = 2;
do
{
if ( v6 == 2 )
{
v7 = atoi(v5);
switch ( v7 )
{
case 5:
*v3 = 5;
break;
case 10:
*v3 = 10;
break;
case 20:
*v3 = 20;
break;
case 50:
*v3 = 50;
break;
case 100:
*v3 = 100;
break;
case 200:
*v3 = 200;
break;
default:
perror("Error: Invalid coin data! Exiting...\n");
exit(1);
}
}
else if ( v6 == 3 )
{
v3[1] = atoi(v5);
add_coin_to_node(a1, v3);
}
v5 = strtok(0LL, ",");
++v6;
}
while ( v5 );
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, char *a2)
{
int *v3; // rbp
char *v4; // rax
char *v5; // rdi
int v6; // ebx
int v7; // eax

v3 = (int *)malloc(8uLL);
*v3 = 0;
v3[1] = 0;
v4 = strtok(a2, ",");
if ( v4 )
{
v5 = v4;
v6 = 2;
do
{
if ( v6 == 2 )
{
v7 = atoi(v5);
switch ( v7 )
{
case 5:
*v3 = 5;
break;
case 10:
*v3 = 10;
break;
case 20:
*v3 = 20;
break;
case 50:
*v3 = 50;
break;
case 100:
*v3 = 100;
break;
case 200:
*v3 = 200;
break;
default:
perror("Error: Invalid coin data! Exiting...\n");
exit(1);
}
}
else if ( v6 == 3 )
{
v3[1] = atoi(v5);
func0(a1, v3);
}
v5 = strtok(0LL, ",");
++v6;
}
while ( v5 );
}
return 1LL;
}

original_code:
BOOLEAN tokenize_coins_file(tm_type_ptr tm, char *coinsfile){
 char *buffer = ((void *)0);
 struct coin *data = ((void *)0);
 int temp_coin = 0;
 unsigned int temp_count = 0;
 int count = 1;
 data = (struct coin *)malloc(sizeof(struct coin));
 data->denomination = 0;
 data->count = 0;
 buffer = strtok(coinsfile, ",");
  while (buffer != ((void *)0)){
   switch(count){
    case 1:
     temp_coin = atoi(buffer);
     if (temp_coin == 5){
      data->denomination = FIVE_CENTS;
     }
     else if (temp_coin == 10){
      data->denomination = TEN_CENTS;
     }
     else if (temp_coin == 20){
      data->denomination = TWENTY_CENTS;
     }
     else if (temp_coin == 50){
      data->denomination = FIFTY_CENTS;
     }
     else if (temp_coin == 100){
      data->denomination = ONE_DOLLAR;
     }
     else if (temp_coin == 200){
      data->denomination = TWO_DOLLARS;
     }
     else{
      perror("Error: Invalid coin data! Exiting...\n");
      exit(1);
     }
     break;
    case 2:
     temp_count = atoi(buffer);
     data->count = temp_count;
     break;
    default:
     break;
   }
  count++;
 if (count == 3){
  add_coin_to_node(tm, data);
 }
 buffer = strtok(((void *)0), ",");
}
return TRUE;
}

canonical_original_code:
enum truefalse tokenize_coins_file(struct tm *tm, char *coinsfile){
 char *buffer = ((void *)0);
 struct coin *data = ((void *)0);
 int temp_coin = 0;
 unsigned int temp_count = 0;
 int count = 1;
 data = (struct coin *)malloc(sizeof(struct coin));
 data->denomination = 0;
 data->count = 0;
 buffer = strtok(coinsfile, ",");
  while (buffer != ((void *)0)){
   switch(count){
    case 1:
     temp_coin = atoi(buffer);
     if (temp_coin == 5){
      data->denomination = FIVE_CENTS;
     }
     else if (temp_coin == 10){
      data->denomination = TEN_CENTS;
     }
     else if (temp_coin == 20){
      data->denomination = TWENTY_CENTS;
     }
     else if (temp_coin == 50){
      data->denomination = FIFTY_CENTS;
     }
     else if (temp_coin == 100){
      data->denomination = ONE_DOLLAR;
     }
     else if (temp_coin == 200){
      data->denomination = TWO_DOLLARS;
     }
     else{
      perror("Error: Invalid coin data! Exiting...\n");
      exit(1);
     }
     break;
    case 2:
     temp_count = atoi(buffer);
     data->count = temp_count;
     break;
    default:
     break;
   }
  count++;
 if (count == 3){
  add_coin_to_node(tm, data);
 }
 buffer = strtok(((void *)0), ",");
}
return TRUE;
}

variable_types:
coinsfile
char *


ChannelsInit

repo: jameswalmsley/chuckie

decompiled_code:
int *ChannelsInit()
{
int *result; // rax

result = &channels;
do
{
*((_BYTE *)result + 1) = 0;
result[1] = 0;
*((_BYTE *)result + 2) = 0;
result[3] = 0;
result[2] = 0;
*(_BYTE *)result = 0;
result[4] = 0;
result[5] = 0;
result[6] = 0;
result += 7;
}
while ( result != (int *)(unsigned int)((_DWORD)&channels + 112) );
return result;
}

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

result = &channels;
do
{
*((_BYTE *)result + 1) = 0;
result[1] = 0;
*((_BYTE *)result + 2) = 0;
result[3] = 0;
result[2] = 0;
*(_BYTE *)result = 0;
result[4] = 0;
result[5] = 0;
result[6] = 0;
result += 7;
}
while ( result != (int *)(unsigned int)((_DWORD)&channels + 112) );
return result;
}

original_code:
void ChannelsInit(void)
{
    unsigned int i;
    for(i = 0; i < 4; ++i)
    {
        channels[i].amplitude = 0;
        channels[i].duration = 0;
        channels[i].envelope = 0;
        channels[i].angle = 0;
        channels[i].noise = 0;
        channels[i].pitch = 0;
        channels[i].pitchDelta = 0;
        channels[i].steps = 0;
        channels[i].adsr = ATTACK;
    }
}

canonical_original_code:
void ChannelsInit()
{
    unsigned int i;
    for(i = 0; i < 4; ++i)
    {
        channels[i].amplitude = 0;
        channels[i].duration = 0;
        channels[i].envelope = 0;
        channels[i].angle = 0;
        channels[i].noise = 0;
        channels[i].pitch = 0;
        channels[i].pitchDelta = 0;
        channels[i].steps = 0;
        channels[i].adsr = ATTACK;
    }
}

variable_types:
i
unsigned int


QueueInit

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

for ( result = 0LL; result != 4; ++result )
{
queueBegin[result] = 0;
queueEnd[result] = 0;
queueSize[result] = 0;
}
return result * 4;
}

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

for ( result = 0LL; result != 4; ++result )
{
queueBegin[result] = 0;
queueEnd[result] = 0;
queueSize[result] = 0;
}
return result * 4;
}

original_code:
void QueueInit(void)
{
    unsigned int i;
    for(i = 0; i < 4; ++i)
    {
        queueBegin[i] = 0;
        queueEnd[i] = 0;
        queueSize[i] = 0;
    }
}

canonical_original_code:
void QueueInit()
{
    unsigned int i;
    for(i = 0; i < 4; ++i)
    {
        queueBegin[i] = 0;
        queueEnd[i] = 0;
        queueSize[i] = 0;
    }
}


PitchInit

original_code:
void PitchInit(void)
{
    int middleA = 89;
    float middleAFrequency = 440.0f;
    int i;
    for(i = 0; i < sizeof(pitchLookup)/sizeof(pitchLookup[0]); ++i)
    {
        pitchLookup[i] = middleAFrequency * (float)pow(2, (i - middleA)/(4.0f*12.0f));
    }
}

canonical_original_code:
void PitchInit()
{
    int middleA = 89;
    float middleAFrequency = 440.0f;
    int i;
    for(i = 0; i < sizeof(pitchLookup)/sizeof(pitchLookup[0]); ++i)
    {
        pitchLookup[i] = middleAFrequency * (float)pow(2, (i - middleA)/(4.0f*12.0f));
    }
}

variable_types: middleA int

variable_types: middleAFrequency float


basicsound

decompiled_code:
__int64 __fastcall basicsound(int a1, char a2, char a3, char a4)
{
__int64 result; // rax
int v8; // ecx
unsigned int v9; // edx
__int64 v10; // rdx

result = a1 & 3;
if ( (a1 & 0x10) != 0 )
{
queueEnd[a1 & 3] = 0;
queueBegin[a1 & 3] = 0;
v8 = 0;
LABEL_3:
result = a1 & 3;
v9 = queueEnd[result];
queueEnd[result] = ((_BYTE)v9 + 1) & 0x3F;
v10 = result + 4LL * v9;
soundQueue[2 * v10] = a1;
LOBYTE(soundQueue[2 * v10 + 1]) = a2;
BYTE1(soundQueue[2 * v10 + 1]) = a3;
BYTE2(soundQueue[2 * v10 + 1]) = a4;
queueSize[result] = v8 + 1;
return result;
}
v8 = queueSize[a1 & 3];
if ( v8 != 64 )
goto LABEL_3;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(int a1, char a2, char a3, char a4)
{
__int64 result; // rax
int v8; // ecx
unsigned int v9; // edx
__int64 v10; // rdx

result = a1 & 3;
if ( (a1 & 0x10) != 0 )
{
queueEnd[a1 & 3] = 0;
queueBegin[a1 & 3] = 0;
v8 = 0;
LABEL_3:
result = a1 & 3;
v9 = queueEnd[result];
queueEnd[result] = ((_BYTE)v9 + 1) & 0x3F;
v10 = result + 4LL * v9;
soundQueue[2 * v10] = a1;
LOBYTE(soundQueue[2 * v10 + 1]) = a2;
BYTE1(soundQueue[2 * v10 + 1]) = a3;
BYTE2(soundQueue[2 * v10 + 1]) = a4;
queueSize[result] = v8 + 1;
return result;
}
v8 = queueSize[a1 & 3];
if ( v8 != 64 )
goto LABEL_3;
return result;
}

original_code:
void basicsound(unsigned int chan, char amplitude, unsigned char pitch, unsigned char duration)
{
    Sound* sound = 0;
    unsigned int pos;
    unsigned int flush= ((chan>>4) & 1);
    unsigned int C = chan & 3;
    if(flush)
        queueSize[C] = queueBegin[C] = queueEnd[C] = 0;
    if(queueSize[C] == 64)
        return;
    pos = queueEnd[C];
    ++queueEnd[C];
    queueEnd[C] %= 64;
    sound = &soundQueue[pos][C];
    sound->params.channel = chan;
    sound->params.amplitude = amplitude;
    sound->params.pitch = pitch;
    sound->params.duration = duration;
    ++queueSize[C];
}

canonical_original_code:
void basicsound(unsigned int chan, char amplitude, unsigned char pitch, unsigned char duration)
{
    union Sound *sound = 0;
    unsigned int pos;
    unsigned int flush = ((chan>>4) & 1);
    unsigned int C = chan & 3;
    if(flush)
        queueSize[C] = queueBegin[C] = queueEnd[C] = 0;
    if(queueSize[C] == 64)
        return;
    pos = queueEnd[C];
    ++queueEnd[C];
    queueEnd[C] %= 64;
    sound = &soundQueue[pos][C];
    sound->params.channel = chan;
    sound->params.amplitude = amplitude;
    sound->params.pitch = pitch;
    sound->params.duration = duration;
    ++queueSize[C];
}

variable_types:
chan
unsigned int

variable_types: amplitude char

variable_types:
pitch
unsigned char

variable_types:
duration
unsigned char

variable_types: union Sound { unsigned char array[8]; struct { unsigned int channel; char amplitude; unsigned char pitch; unsigned char duration; } params; } *

variable_types:
pos
unsigned int

variable_types:
flush
unsigned int

variable_types:
C
unsigned int


sound

decompiled_code:
__int64 __fastcall sound(char *a1)
{
return basicsound(*(unsigned __int16 *)a1, a1[2], a1[4], a1[6]);
}

canonical_decompiled_code:
__int64 __fastcall func4(char *a1)
{
return func3(*(unsigned __int16 *)a1, a1[2], a1[4], a1[6]);
}

original_code:
void sound(unsigned char *array)
{
    basicsound((unsigned int)(array[0]|(array[1]<<8)), (char)array[2], array[4], array[6]);
}

variable_types:
array
unsigned char *


playSound

decompiled_code:
__int64 __fastcall playSound(__int64 a1)
{
__int64 result; // rax
char v2; // dl
char v3; // r8
unsigned __int8 v4; // di
__int64 v5; // r11
int v6; // ecx
__int64 v7; // rsi
__int64 v8; // rsi
float v9; // xmm0_4
unsigned int v10; // edx
__int64 v11; // r10

LODWORD(result) = *(_DWORD *)a1 & 3;
if ( (*(_DWORD *)a1 & 0x1000) != 0 )
{
v8 = 7LL * (unsigned int)result;
v9 = 16000.0
/ pitchLookup[(unsigned __int8)(LOBYTE(channels[7 * (unsigned int)result + 4])
+ LOBYTE(channels[7 * (unsigned int)result]))];
v10 = channels[7 * (unsigned int)result + 3] % (unsigned int)(int)v9;
result = channels[7 * (unsigned int)result + 3] / (unsigned int)(int)v9;
channels[v8 + 3] = v10;
}
else
{
v2 = *(_BYTE *)(a1 + 4);
v3 = *(_BYTE *)(a1 + 5);
v4 = *(_BYTE *)(a1 + 6);
if ( v2 <= 0 )
{
v11 = 7LL * (unsigned int)result;
BYTE1(channels[v11]) = -8 * v2;
BYTE2(channels[v11]) = 0;
}
else
{
v5 = 7LL * (unsigned int)result;
BYTE2(channels[v5]) = v2 % 17;
BYTE1(channels[v5]) = 0;
}
v6 = -1;
if ( v4 != 0xFF )
v6 = 50 * v4;
result = (unsigned int)result;
v7 = 7LL * (unsigned int)result;
channels[v7 + 1] = v6;
LOBYTE(channels[v7]) = v3;
channels[v7 + 3] = 0;
channels[v7 + 2] = 0;
channels[v7 + 4] = 0;
channels[v7 + 5] = 0;
channels[v7 + 6] = 0;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 result; // rax
char v2; // dl
char v3; // r8
unsigned __int8 v4; // di
__int64 v5; // r11
int v6; // ecx
__int64 v7; // rsi
__int64 v8; // rsi
float v9; // xmm0_4
unsigned int v10; // edx
__int64 v11; // r10

LODWORD(result) = *(_DWORD *)a1 & 3;
if ( (*(_DWORD *)a1 & 0x1000) != 0 )
{
v8 = 7LL * (unsigned int)result;
v9 = 16000.0
/ pitchLookup[(unsigned __int8)(LOBYTE(channels[7 * (unsigned int)result + 4])
+ LOBYTE(channels[7 * (unsigned int)result]))];
v10 = channels[7 * (unsigned int)result + 3] % (unsigned int)(int)v9;
result = channels[7 * (unsigned int)result + 3] / (unsigned int)(int)v9;
channels[v8 + 3] = v10;
}
else
{
v2 = *(_BYTE *)(a1 + 4);
v3 = *(_BYTE *)(a1 + 5);
v4 = *(_BYTE *)(a1 + 6);
if ( v2 <= 0 )
{
v11 = 7LL * (unsigned int)result;
BYTE1(channels[v11]) = -8 * v2;
BYTE2(channels[v11]) = 0;
}
else
{
v5 = 7LL * (unsigned int)result;
BYTE2(channels[v5]) = v2 % 17;
BYTE1(channels[v5]) = 0;
}
v6 = -1;
if ( v4 != 0xFF )
v6 = 50 * v4;
result = (unsigned int)result;
v7 = 7LL * (unsigned int)result;
channels[v7 + 1] = v6;
LOBYTE(channels[v7]) = v3;
channels[v7 + 3] = 0;
channels[v7 + 2] = 0;
channels[v7 + 4] = 0;
channels[v7 + 5] = 0;
channels[v7 + 6] = 0;
}
return result;
}

original_code:
void playSound(Sound* sound)
{
    char amplitude = sound->params.amplitude;
    unsigned char pitch = sound->params.pitch;
    unsigned char duration = sound->params.duration;
    unsigned int chan = sound->params.channel;
    Channel* channel = &channels[(chan&3)];
    unsigned char H = (chan >> 12) & 1;
    if(H)
    {
        channel->angle %= (int)(16000/pitchLookup[(unsigned int)(channel->pitch + channel->pitchDelta) % 256]);
        return;
    }
    if(amplitude <= 0)
    {
        amplitude = (-amplitude) << 3;
        if(amplitude > 127)
            amplitude = 127;
        channel->amplitude = amplitude;
        channel->envelope = 0;
    }
    else
    {
        channel->envelope = amplitude % 17;
        channel->amplitude = 0;
    }
    if(duration == 255)
        channel->duration = -1;
    else
        channel->duration = duration * (1000 / 20);
    channel->pitch = pitch;
    channel->angle = 0;
    channel->noise = 0;
    channel->pitchDelta = 0;
    channel->steps = 0;
    channel->adsr = ATTACK;
}

canonical_original_code:
void playSound(union Sound *sound)
{
    char amplitude = sound->params.amplitude;
    unsigned char pitch = sound->params.pitch;
    unsigned char duration = sound->params.duration;
    unsigned int chan = sound->params.channel;
    struct Channel *channel = &channels[(chan&3)];
    unsigned char H = (chan >> 12) & 1;
    if(H)
    {
        channel->angle %= (int)(16000/pitchLookup[(unsigned int)(channel->pitch + channel->pitchDelta) % 256]);
        return;
    }
    if(amplitude <= 0)
    {
        amplitude = (-amplitude) << 3;
        if(amplitude > 127)
            amplitude = 127;
        channel->amplitude = amplitude;
        channel->envelope = 0;
    }
    else
    {
        channel->envelope = amplitude % 17;
        channel->amplitude = 0;
    }
    if(duration == 255)
        channel->duration = -1;
    else
        channel->duration = duration * (1000 / 20);
    channel->pitch = pitch;
    channel->angle = 0;
    channel->noise = 0;
    channel->pitchDelta = 0;
    channel->steps = 0;
    channel->adsr = ATTACK;
}

variable_types: struct Channel { unsigned char pitch; unsigned char amplitude; unsigned char envelope; int duration; unsigned int noise; unsigned int angle; int pitchDelta; unsigned int steps; enum Phase { ATTACK=0, DECAY=1, SUSTAIN=2, RELEASE=3 } adsr; } *

variable_types:
H
unsigned char

user_defined_types: union Sound { unsigned char array[8]; struct { unsigned int channel; char amplitude; unsigned char pitch; unsigned char duration; } params; }

user_defined_types: struct Channel { unsigned char pitch; unsigned char amplitude; unsigned char envelope; int duration; unsigned int noise; unsigned int angle; int pitchDelta; unsigned int steps; enum Phase adsr; }


issueSound

decompiled_code:
__int64 __fastcall issueSound(unsigned __int8 a1)
{
__int64 result; // rax
int v2; // er9
int v4; // er8
__int64 v5; // rdx
unsigned int v6; // esi
__int64 v7; // rax
int *v8; // rdi
unsigned int v9; // eax
char v10; // cl
char v11; // r11

result = a1;
v2 = queueSize[a1];
if ( v2 )
{
v4 = a1;
v5 = a1;
v6 = queueBegin[a1];
v7 = 4LL * v6;
v8 = &soundQueue[2 * v7 + 2 * a1];
v9 = (unsigned int)soundQueue[2 * v5 + 2 * v7] >> 8;
v10 = v9 & 3;
if ( (v9 & 3) == 0 )
goto LABEL_8;
v11 = v9 & 3;
for ( result = 0LL; result != 4; ++result )
{
if ( a1 != (_BYTE)result )
v11 -= (((unsigned int)soundQueue[8 * queueBegin[result] + 2 * (int)result] >> 8) & 3) == v10;
}
if ( !v11 )
{
LABEL_8:
queueBegin[v4] = ((_BYTE)v6 + 1) & 0x3F;
queueSize[v4] = v2 - 1;
result = playSound((__int64)v8);
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(unsigned __int8 a1)
{
__int64 result; // rax
int v2; // er9
int v4; // er8
__int64 v5; // rdx
unsigned int v6; // esi
__int64 v7; // rax
int *v8; // rdi
unsigned int v9; // eax
char v10; // cl
char v11; // r11

result = a1;
v2 = queueSize[a1];
if ( v2 )
{
v4 = a1;
v5 = a1;
v6 = queueBegin[a1];
v7 = 4LL * v6;
v8 = &soundQueue[2 * v7 + 2 * a1];
v9 = (unsigned int)soundQueue[2 * v5 + 2 * v7] >> 8;
v10 = v9 & 3;
if ( (v9 & 3) == 0 )
goto LABEL_8;
v11 = v9 & 3;
for ( result = 0LL; result != 4; ++result )
{
if ( a1 != (_BYTE)result )
v11 -= (((unsigned int)soundQueue[8 * queueBegin[result] + 2 * (int)result] >> 8) & 3) == v10;
}
if ( !v11 )
{
LABEL_8:
queueBegin[v4] = ((_BYTE)v6 + 1) & 0x3F;
queueSize[v4] = v2 - 1;
result = func5((__int64)v8);
}
}
return result;
}

original_code:
void issueSound(unsigned char chan)
{
    Sound* sound = 0;
    unsigned char playGroup, syncCtrl, i;
    if(queueSize[chan] == 0)
        return;
    sound = &soundQueue[queueBegin[chan]][chan];
    syncCtrl = (sound->params.channel >> 8) & 3;
    if(syncCtrl)
    {
        playGroup = syncCtrl;
        for(i = 0; i < 4; ++i)
        {
            if(i != chan)
            {
                if(((soundQueue[queueBegin[i]][i].params.channel >> 8) & 3) == syncCtrl)
                    --playGroup;
            }
        }
        if(playGroup)
            return;
    }
    ++queueBegin[chan];
    queueBegin[chan] %= 64;
    --queueSize[chan];
    playSound(sound);
}

canonical_original_code:
void issueSound(unsigned char chan)
{
    union Sound *sound = 0;
    unsigned char playGroup; unsigned char syncCtrl; unsigned char i;
    if(queueSize[chan] == 0)
        return;
    sound = &soundQueue[queueBegin[chan]][chan];
    syncCtrl = (sound->params.channel >> 8) & 3;
    if(syncCtrl)
    {
        playGroup = syncCtrl;
        for(i = 0; i < 4; ++i)
        {
            if(i != chan)
            {
                if(((soundQueue[queueBegin[i]][i].params.channel >> 8) & 3) == syncCtrl)
                    --playGroup;
            }
        }
        if(playGroup)
            return;
    }
    ++queueBegin[chan];
    queueBegin[chan] %= 64;
    --queueSize[chan];
    playSound(sound);
}

variable_types:
chan
unsigned char

variable_types:
playGroup
unsigned char

variable_types:
syncCtrl
unsigned char

variable_types:
i
unsigned char


basicenvelope

decompiled_code:
__int64 __fastcall basicenvelope(unsigned __int8 a1, char a2, char a3, char a4, char a5, char a6, char a7, char a8, char a9, char a10, char a11, char a12, char a13, unsigned int a14)
{
__int64 v14; // rax
__int64 v15; // rcx
__int64 result; // rax

v14 = a1 - 1;
*((_BYTE *)&envelopes + 14 * v14) = a1;
*((_BYTE *)&envelopes + 14 * v14 + 1) = a2;
*((_BYTE *)&envelopes + 14 * v14 + 2) = a3;
*((_BYTE *)&envelopes + 14 * v14 + 3) = a4;
*((_BYTE *)&envelopes + 14 * v14 + 4) = a5;
*((_BYTE *)&envelopes + 14 * v14 + 5) = a6;
*((_BYTE *)&envelopes + 14 * v14 + 6) = a7;
*((_BYTE *)&envelopes + 14 * v14 + 7) = a8;
*((_BYTE *)&envelopes + 14 * v14 + 8) = a9;
*((_BYTE *)&envelopes + 14 * v14 + 9) = a10;
*((_BYTE *)&envelopes + 14 * v14 + 10) = a11;
*((_BYTE *)&envelopes + 14 * v14 + 11) = a12;
v15 = 7 * v14;
*((_BYTE *)&envelopes + 2 * v15 + 12) = a13;
result = a14;
*((_BYTE *)&envelopes + 2 * v15 + 13) = a14;
return result;
}

original_code:
void basicenvelope(unsigned char N,
                   unsigned char T,
                   char PI1,
                   char PI2,
                   char PI3,
                   unsigned char PN1,
                   unsigned char PN2,
                   unsigned char PN3,
                   char AA,
                   char AD,
                   char AS,
                   char AR,
                   unsigned char ALA,
                   unsigned char ALD)
{
    Envelope* envelope;
    if(N < 1 && N > 16)
        return;
    envelope = &envelopes[N-1];
    envelope->params.N = N;
    envelope->params.T = T;
    envelope->params.PI1 = PI1;
    envelope->params.PI2 = PI2;
    envelope->params.PI3 = PI3;
    envelope->params.PN1 = PN1;
    envelope->params.PN2 = PN2;
    envelope->params.PN3 = PN3;
    envelope->params.AA = AA;
    envelope->params.AD = AD;
    envelope->params.AS = AS;
    envelope->params.AR = AR;
    envelope->params.ALA = ALA;
    envelope->params.ALD = ALD;
}

canonical_original_code:
void basicenvelope(unsigned char N, unsigned char T, char PI1, char PI2, char PI3, unsigned char PN1, unsigned char PN2, unsigned char PN3, char AA, char AD, char AS, char AR, unsigned char ALA, unsigned char ALD)
{
    union Envelope *envelope;
    if(N < 1 && N > 16)
        return;
    envelope = &envelopes[N-1];
    envelope->params.N = N;
    envelope->params.T = T;
    envelope->params.PI1 = PI1;
    envelope->params.PI2 = PI2;
    envelope->params.PI3 = PI3;
    envelope->params.PN1 = PN1;
    envelope->params.PN2 = PN2;
    envelope->params.PN3 = PN3;
    envelope->params.AA = AA;
    envelope->params.AD = AD;
    envelope->params.AS = AS;
    envelope->params.AR = AR;
    envelope->params.ALA = ALA;
    envelope->params.ALD = ALD;
}

variable_types:
N
unsigned char

variable_types:
T
unsigned char

variable_types: AA char

variable_types: AD char

variable_types: AS char

variable_types: AR char

variable_types:
ALA
unsigned char

variable_types:
ALD
unsigned char

variable_types: union Envelope { unsigned char array[14]; struct { unsigned char N; unsigned char T; char PI1; char PI2; char PI3; unsigned char PN1; unsigned char PN2; unsigned char PN3; char AA; char AD; char AS; char AR; unsigned char ALA; unsigned char ALD; } params; } *


envelope

decompiled_code:
__int64 __fastcall envelope(unsigned __int8 *a1)
{
char *v1; // rdx
__int64 result; // rax

v1 = (char *)&envelopes + 14 * *a1 - 14;
*(_QWORD *)v1 = *(_QWORD *)a1;
*((_DWORD *)v1 + 2) = *((_DWORD *)a1 + 2);
result = *((unsigned __int16 *)a1 + 6);
*((_WORD *)v1 + 6) = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(unsigned __int8 *a1)
{
char *v1; // rdx
__int64 result; // rax

v1 = (char *)&envelopes + 14 * *a1 - 14;
*(_QWORD *)v1 = *(_QWORD *)a1;
*((_DWORD *)v1 + 2) = *((_DWORD *)a1 + 2);
result = *((unsigned __int16 *)a1 + 6);
*((_WORD *)v1 + 6) = result;
return result;
}

original_code:
void envelope(unsigned char *array)
{
    Envelope* envelope;
    unsigned char N = array[0];
    if(N < 1 && N > 16)
        return;
    envelope = &envelopes[N-1];
    memcpy(envelope->array, array, sizeof(unsigned char)*14);
}

canonical_original_code:
void envelope(unsigned char *array)
{
    union Envelope *envelope;
    unsigned char N = array[0];
    if(N < 1 && N > 16)
        return;
    envelope = &envelopes[N-1];
    memcpy(envelope->array, array, sizeof(unsigned char)*14);
}

user_defined_types: union Envelope { unsigned char array[14]; struct { unsigned char N; unsigned char T; char PI1; char PI2; char PI3; unsigned char PN1; unsigned char PN2; unsigned char PN3; char AA; char AD; char AS; char AR; unsigned char ALA; unsigned char ALD; } params; }


processPitchEnvelope

decompiled_code:
__int64 __fastcall processPitchEnvelope(__int64 a1, _BYTE *a2)
{
unsigned __int8 v2; // r8
unsigned __int8 v3; // r9
__int64 result; // rax
unsigned int v5; // ecx
unsigned int v6; // edx

v2 = a2[5];
v3 = a2[6];
result = v3 + (unsigned int)v2;
v5 = result + (unsigned __int8)a2[7];
if ( v5 )
{
v6 = *(_DWORD *)(a1 + 20);
if ( (char)a2[1] < 0 )
{
if ( v5 < v6 )
{
*(_DWORD *)(a1 + 16) = 0;
return result;
}
}
else
{
v6 %= v5;
}
if ( v2 <= v6 )
{
if ( v3 <= v6 )
result = (unsigned int)(char)a2[4];
else
result = (unsigned int)(char)a2[3];
*(_DWORD *)(a1 + 16) += result;
}
else
{
result = (unsigned int)(char)a2[2];
*(_DWORD *)(a1 + 16) += result;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, _BYTE *a2)
{
unsigned __int8 v2; // r8
unsigned __int8 v3; // r9
__int64 result; // rax
unsigned int v5; // ecx
unsigned int v6; // edx

v2 = a2[5];
v3 = a2[6];
result = v3 + (unsigned int)v2;
v5 = result + (unsigned __int8)a2[7];
if ( v5 )
{
v6 = *(_DWORD *)(a1 + 20);
if ( (char)a2[1] < 0 )
{
if ( v5 < v6 )
{
*(_DWORD *)(a1 + 16) = 0;
return result;
}
}
else
{
v6 %= v5;
}
if ( v2 <= v6 )
{
if ( v3 <= v6 )
result = (unsigned int)(char)a2[4];
else
result = (unsigned int)(char)a2[3];
*(_DWORD *)(a1 + 16) += result;
}
else
{
result = (unsigned int)(char)a2[2];
*(_DWORD *)(a1 + 16) += result;
}
}
return result;
}

original_code:
void processPitchEnvelope(Channel* channel, Envelope* envelope)
{
    unsigned int totalEnvelopeSteps, steps;
    totalEnvelopeSteps = (envelope->params.PN1+envelope->params.PN2+envelope->params.PN3);
    if(totalEnvelopeSteps > 0)
    {
        steps = channel->steps;
        if(envelope->params.T & 0x80)
        {
            if(steps > totalEnvelopeSteps)
            {
                channel->pitchDelta = 0;
                return;
            }
        }
        else
        {
            steps %= totalEnvelopeSteps;
        }
        if(steps < envelope->params.PN1)
            channel->pitchDelta += envelope->params.PI1;
        else if(steps < envelope->params.PN2)
            channel->pitchDelta += envelope->params.PI2;
        else
            channel->pitchDelta += envelope->params.PI3;
    }
}

canonical_original_code:
void processPitchEnvelope(struct Channel *channel, union Envelope *envelope)
{
    unsigned int totalEnvelopeSteps; unsigned int steps;
    totalEnvelopeSteps = (envelope->params.PN1+envelope->params.PN2+envelope->params.PN3);
    if(totalEnvelopeSteps > 0)
    {
        steps = channel->steps;
        if(envelope->params.T & 0x80)
        {
            if(steps > totalEnvelopeSteps)
            {
                channel->pitchDelta = 0;
                return;
            }
        }
        else
        {
            steps %= totalEnvelopeSteps;
        }
        if(steps < envelope->params.PN1)
            channel->pitchDelta += envelope->params.PI1;
        else if(steps < envelope->params.PN2)
            channel->pitchDelta += envelope->params.PI2;
        else
            channel->pitchDelta += envelope->params.PI3;
    }
}

variable_types:
totalEnvelopeSteps
unsigned int

variable_types:
steps
unsigned int

user_defined_types: enum Phase { ATTACK=0, DECAY=1, SUSTAIN=2, RELEASE=3 }


processAmplitudeEnvelope

decompiled_code:
char __fastcall processAmplitudeEnvelope(unsigned __int8 a1, _BYTE *a2)
{
unsigned int v2; // eax
char v3; // al
bool v4; // zf
char v5; // al

v2 = channels[7 * a1 + 6];
if ( v2 == 2 )
{
v5 = a2[10];
v4 = BYTE1(channels[7 * a1]) + v5 == 0;
LOBYTE(v2) = BYTE1(channels[7 * a1]) + v5;
BYTE1(channels[7 * a1]) = v2;
if ( v4 )
channels[7 * a1 + 6] = 3;
}
else if ( v2 > 2 )
{
if ( v2 == 3 )
{
v3 = a2[11];
v4 = BYTE1(channels[7 * a1]) + v3 == 0;
LOBYTE(v2) = BYTE1(channels[7 * a1]) + v3;
BYTE1(channels[7 * a1]) = v2;
if ( v4 || queueSize[a1] )
{
LOBYTE(v2) = a1;
channels[7 * a1 + 1] = 0;
}
}
}
else if ( v2 )
{
LOBYTE(v2) = BYTE1(channels[7 * a1]) + a2[9];
BYTE1(channels[7 * a1]) = v2;
if ( (unsigned __int8)v2 <= a2[13] )
channels[7 * a1 + 6] = 2;
}
else
{
LOBYTE(v2) = BYTE1(channels[7 * a1]) + a2[8];
BYTE1(channels[7 * a1]) = v2;
if ( (unsigned __int8)v2 >= a2[12] )
channels[7 * a1 + 6] = 1;
}
return v2;
}

canonical_decompiled_code:
char __fastcall func10(unsigned __int8 a1, _BYTE *a2)
{
unsigned int v2; // eax
char v3; // al
bool v4; // zf
char v5; // al

v2 = channels[7 * a1 + 6];
if ( v2 == 2 )
{
v5 = a2[10];
v4 = BYTE1(channels[7 * a1]) + v5 == 0;
LOBYTE(v2) = BYTE1(channels[7 * a1]) + v5;
BYTE1(channels[7 * a1]) = v2;
if ( v4 )
channels[7 * a1 + 6] = 3;
}
else if ( v2 > 2 )
{
if ( v2 == 3 )
{
v3 = a2[11];
v4 = BYTE1(channels[7 * a1]) + v3 == 0;
LOBYTE(v2) = BYTE1(channels[7 * a1]) + v3;
BYTE1(channels[7 * a1]) = v2;
if ( v4 || queueSize[a1] )
{
LOBYTE(v2) = a1;
channels[7 * a1 + 1] = 0;
}
}
}
else if ( v2 )
{
LOBYTE(v2) = BYTE1(channels[7 * a1]) + a2[9];
BYTE1(channels[7 * a1]) = v2;
if ( (unsigned __int8)v2 <= a2[13] )
channels[7 * a1 + 6] = 2;
}
else
{
LOBYTE(v2) = BYTE1(channels[7 * a1]) + a2[8];
BYTE1(channels[7 * a1]) = v2;
if ( (unsigned __int8)v2 >= a2[12] )
channels[7 * a1 + 6] = 1;
}
return v2;
}

original_code:
void processAmplitudeEnvelope(unsigned char chan, Envelope* envelope)
{
    Channel* channel = &channels[chan];
    switch(channel->adsr)
    {
    case ATTACK:
        channel->amplitude += envelope->params.AA;
        if(channel->amplitude >= envelope->params.ALA)
            channel->adsr = DECAY;
        break;
    case DECAY:
        channel->amplitude += envelope->params.AD;
        if(channel->amplitude <= envelope->params.ALD)
            channel->adsr = SUSTAIN;
        break;
    case SUSTAIN:
        channel->amplitude += envelope->params.AS;
        if(channel->amplitude == 0)
            channel->adsr = RELEASE;
        break;
    case RELEASE:
        channel->amplitude += envelope->params.AR;
        if(channel->amplitude == 0 || (queueSize[chan]>0))
            channel->duration = 0;
        break;
    };
}

canonical_original_code:
void processAmplitudeEnvelope(unsigned char chan, union Envelope *envelope)
{
    struct Channel *channel = &channels[chan];
    switch(channel->adsr)
    {
    case ATTACK:
        channel->amplitude += envelope->params.AA;
        if(channel->amplitude >= envelope->params.ALA)
            channel->adsr = DECAY;
        break;
    case DECAY:
        channel->amplitude += envelope->params.AD;
        if(channel->amplitude <= envelope->params.ALD)
            channel->adsr = SUSTAIN;
        break;
    case SUSTAIN:
        channel->amplitude += envelope->params.AS;
        if(channel->amplitude == 0)
            channel->adsr = RELEASE;
        break;
    case RELEASE:
        channel->amplitude += envelope->params.AR;
        if(channel->amplitude == 0 || (queueSize[chan]>0))
            channel->duration = 0;
        break;
    };
}

variable_types: struct Channel { unsigned char pitch; unsigned char amplitude; unsigned char envelope; int duration; unsigned int noise; unsigned int angle; int pitchDelta; unsigned int steps; enum Phase { ATTACK=0, DECAY=1, SUSTAIN=2, RELEASE=3 } adsr; } *


processEnvelope

decompiled_code:
char __fastcall processEnvelope(unsigned __int8 a1, unsigned int a2)
{
unsigned __int8 v3; // dl
int v4; // esi
int v5; // er8

v3 = BYTE2(channels[7 * a1]);
v4 = v3 - 1;
if ( !v3 )
_assert_fail("channel->envelope > 0", "/usr/src/repo/bbcb/sound.c", 0x2BDu, "processEnvelope");
if ( (*((_BYTE *)&envelopes + 14 * v4 + 1) & 0x7F) != 0 )
{
a2 /= *((_BYTE *)&envelopes + 14 * v4 + 1) & 0x7Fu;
v5 = channels[7 * a1 + 5];
channels[7 * a1 + 5] = a2;
if ( v5 != a2 )
{
processPitchEnvelope((__int64)&channels[7 * a1], (_BYTE *)&envelopes + 14 * v4);
LOBYTE(a2) = processAmplitudeEnvelope(a1, (_BYTE *)&envelopes + 14 * v4);
}
}
return a2;
}

canonical_decompiled_code:
char __fastcall func11(unsigned __int8 a1, unsigned int a2)
{
unsigned __int8 v3; // dl
int v4; // esi
int v5; // er8

v3 = BYTE2(channels[7 * a1]);
v4 = v3 - 1;
if ( !v3 )
_assert_fail("channel->envelope > 0", "/usr/src/repo/bbcb/sound.c", 0x2BDu, "processEnvelope");
if ( (*((_BYTE *)&envelopes + 14 * v4 + 1) & 0x7F) != 0 )
{
a2 /= *((_BYTE *)&envelopes + 14 * v4 + 1) & 0x7Fu;
v5 = channels[7 * a1 + 5];
channels[7 * a1 + 5] = a2;
if ( v5 != a2 )
{
func9((__int64)&channels[7 * a1], (_BYTE *)&envelopes + 14 * v4);
LOBYTE(a2) = func10(a1, (_BYTE *)&envelopes + 14 * v4);
}
}
return a2;
}

original_code:
void processEnvelope(unsigned char chan, unsigned int tcs)
{
    unsigned char stepCentiseconds;
    unsigned int numSteps, step;
    Channel* channel = &channels[chan];
    Envelope* envelope = &envelopes[channel->envelope - 1];
    ((void) sizeof ((channel->envelope > 0) ? 1 : 0), __extension__ ({ if (channel->envelope > 0) ; else __assert_fail ("channel->envelope > 0", "/usr/src/repo/bbcb/sound.c", 701, __extension__ __PRETTY_FUNCTION__); }));
    stepCentiseconds = (envelope->params.T & 0x7f);
    if(stepCentiseconds == 0)
        return;
    numSteps = (tcs/stepCentiseconds);
    step = (numSteps != channels[chan].steps);
    channel->steps = numSteps;
    if(!step)
        return;
    processPitchEnvelope(channel, envelope);
    processAmplitudeEnvelope(chan, envelope);
}

canonical_original_code:
void processEnvelope(unsigned char chan, unsigned int tcs)
{
    unsigned char stepCentiseconds;
    unsigned int numSteps; unsigned int step;
    struct Channel *channel = &channels[chan];
    union Envelope *envelope = &envelopes[channel->envelope - 1];
    ((void) sizeof ((channel->envelope > 0) ? 1 : 0), __extension__ ({ if (channel->envelope > 0) ; else __assert_fail ("channel->envelope > 0", "/usr/src/repo/bbcb/sound.c", 701, __extension__ __PRETTY_FUNCTION__); }));
    stepCentiseconds = (envelope->params.T & 0x7f);
    if(stepCentiseconds == 0)
        return;
    numSteps = (tcs/stepCentiseconds);
    step = (numSteps != channels[chan].steps);
    channel->steps = numSteps;
    if(!step)
        return;
    processPitchEnvelope(channel, envelope);
    processAmplitudeEnvelope(chan, envelope);
}

variable_types:
tcs
unsigned int

variable_types:
stepCentiseconds
unsigned char

variable_types:
numSteps
unsigned int

variable_types:
step
unsigned int


finishedPlaying

decompiled_code:
__int64 __fastcall finishedPlaying(unsigned __int8 a1)
{
int v1; // eax

v1 = channels[7 * a1 + 1];
return (v1 + 1000 * channels[7 * a1 + 3] / -16000 <= 0) & (unsigned __int8)(v1 >= 0);
}

canonical_decompiled_code:
__int64 __fastcall func12(unsigned __int8 a1)
{
int v1; // eax

v1 = channels[7 * a1 + 1];
return (v1 + 1000 * channels[7 * a1 + 3] / -16000 <= 0) & (unsigned __int8)(v1 >= 0);
}

original_code:
int finishedPlaying(unsigned char chan)
{
    return ((channels[chan].duration - (int)(channels[chan].angle*1000)/16000) <= 0) && (channels[chan].duration>=0);
}

variable_types:
chan
unsigned char


decompiled_code:
void __fastcall fill_audio(__int64 a1, _BYTE *a2, int a3)
{
_BYTE *v3; // r15
int v4; // er14
int v5; // eax
unsigned __int8 v6; // bp
char v7; // r12
int *v8; // rbx
unsigned int v9; // eax
float v10; // xmm0_4
__int64 v11; // [rsp+4h] [rbp-40h]

if ( a3 > 0 )
{
v3 = a2;
v11 = (__int64)&a2[a3 - 1 + 1];
do
{
v8 = channels;
v7 = 1;
v6 = 0;
v4 = 0;
while ( 1 )
{
if ( (unsigned int)finishedPlaying(v6) )
{
v8[6] = 3;
issueSound(v6);
goto LABEL_23;
}
v9 = v8[3] + 1;
v8[3] = v9;
if ( v6 )
{
v10 = 16000.0 / pitchLookup[(unsigned __int8)(*((_BYTE *)v8 + 16) + *(_BYTE *)v8)];
if ( v9 % (int)v10 <= (unsigned int)(int)v10 >> 1 )
v4 += *((unsigned __int8 *)v8 + 1);
else
v4 -= *((unsigned __int8 *)v8 + 1);
}
else
{
if ( LOBYTE(channels[0]) == 6 )
{
if ( v9 == 6 * (v9 / 6) )
channels[2] = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
v4 -= channels[2];
LABEL_16:
if ( !*((_BYTE *)v8 + 2) )
goto LABEL_24;
LABEL_17:
processEnvelope(v6, 100 * v8[3] / 0x3E80u);
goto LABEL_23;
}
if ( LOBYTE(channels[0]) > 6u )
{
if ( LOBYTE(channels[0]) == 7 )
{
if ( !(v9
% (int)(float)(16000.0 / pitchLookup[(unsigned __int8)(LOBYTE(channels[11]) + LOBYTE(channels[7]))])) )
channels[2] = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
v4 -= channels[2];
goto LABEL_16;
}
}
else
{
if ( LOBYTE(channels[0]) == 4 )
{
v5 = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
channels[2] = v5;
v4 -= v5;
goto LABEL_16;
}
if ( LOBYTE(channels[0]) == 5 )
{
if ( v9 == 3 * (v9 / 3) )
channels[2] = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
v4 -= channels[2];
goto LABEL_16;
}
}
}
if ( *((_BYTE *)v8 + 2) )
goto LABEL_17;
LABEL_23:
if ( (unsigned __int8)v7 > 3u )
break;
LABEL_24:
++v6;
++v7;
v8 += 7;
}
if ( v4 < -127 )
v4 = -127;
if ( v4 > 127 )
v4 = 127;
*v3++ = v4 / 2;
}
while ( v3 != (_BYTE *)v11 );
}
}

canonical_decompiled_code:
void __fastcall func13(__int64 a1, _BYTE *a2, int a3)
{
_BYTE *v3; // r15
int v4; // er14
int v5; // eax
unsigned __int8 v6; // bp
char v7; // r12
int *v8; // rbx
unsigned int v9; // eax
float v10; // xmm0_4
__int64 v11; // [rsp+4h] [rbp-40h]

if ( a3 > 0 )
{
v3 = a2;
v11 = (__int64)&a2[a3 - 1 + 1];
do
{
v8 = channels;
v7 = 1;
v6 = 0;
v4 = 0;
while ( 1 )
{
if ( (unsigned int)func12(v6) )
{
v8[6] = 3;
func6(v6);
goto LABEL_23;
}
v9 = v8[3] + 1;
v8[3] = v9;
if ( v6 )
{
v10 = 16000.0 / pitchLookup[(unsigned __int8)(*((_BYTE *)v8 + 16) + *(_BYTE *)v8)];
if ( v9 % (int)v10 <= (unsigned int)(int)v10 >> 1 )
v4 += *((unsigned __int8 *)v8 + 1);
else
v4 -= *((unsigned __int8 *)v8 + 1);
}
else
{
if ( LOBYTE(channels[0]) == 6 )
{
if ( v9 == 6 * (v9 / 6) )
channels[2] = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
v4 -= channels[2];
LABEL_16:
if ( !*((_BYTE *)v8 + 2) )
goto LABEL_24;
LABEL_17:
func11(v6, 100 * v8[3] / 0x3E80u);
goto LABEL_23;
}
if ( LOBYTE(channels[0]) > 6u )
{
if ( LOBYTE(channels[0]) == 7 )
{
if ( !(v9
% (int)(float)(16000.0 / pitchLookup[(unsigned __int8)(LOBYTE(channels[11]) + LOBYTE(channels[7]))])) )
channels[2] = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
v4 -= channels[2];
goto LABEL_16;
}
}
else
{
if ( LOBYTE(channels[0]) == 4 )
{
v5 = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
channels[2] = v5;
v4 -= v5;
goto LABEL_16;
}
if ( LOBYTE(channels[0]) == 5 )
{
if ( v9 == 3 * (v9 / 3) )
channels[2] = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
v4 -= channels[2];
goto LABEL_16;
}
}
}
if ( *((_BYTE *)v8 + 2) )
goto LABEL_17;
LABEL_23:
if ( (unsigned __int8)v7 > 3u )
break;
LABEL_24:
++v6;
++v7;
v8 += 7;
}
if ( v4 < -127 )
v4 = -127;
if ( v4 > 127 )
v4 = 127;
*v3++ = v4 / 2;
}
while ( v3 != (_BYTE *)v11 );
}
}

original_code:
void fill_audio(void *udata, Uint8 *stream, int len)
{
    unsigned int numSamplesPerWave;
    unsigned char chan;
    int i, val;
    unsigned int pitch;
    for(i = 0; i < len; ++i)
    {
        val = 0;
        for(chan = 0; chan < 4; ++chan)
        {
            if(finishedPlaying(chan))
            {
                channels[chan].adsr = RELEASE;
                issueSound(chan);
                continue;
            }
            channels[chan].angle++;
            if(chan == 0)
            {
                switch(channels[chan].pitch)
                {
                    case 0:
                        break;
                    case 1:
                        break;
                    case 2:
                        break;
                    case 3:
                        break;
                    case 4:
                        if((channels[chan].angle%((int)(16000/10000))) == 0)
                        {
                            channels[chan].noise = (((rand()&1)*2) - 1) * channels[chan].amplitude;
                        }
                        val -= channels[chan].noise;
                        break;
                    case 5:
                        if((channels[chan].angle%((int)(16000/5000))) == 0)
                        {
                            channels[chan].noise = (((rand()&1)*2) - 1) * channels[chan].amplitude;
                        }
                        val -= channels[chan].noise;
                        break;
                    case 6:
                        if((channels[chan].angle%((int)(16000/2500))) == 0)
                        {
                            channels[chan].noise = (((rand()&1)*2) - 1) * channels[chan].amplitude;
                        }
                        val -= channels[chan].noise;
                        break;
                    case 7:
                        {
                            pitch = (unsigned int)(channels[1].pitch + channels[1].pitchDelta) % 256;
                            numSamplesPerWave = (int)(16000/pitchLookup[pitch]);
                            if((channels[chan].angle%numSamplesPerWave) == 0)
                            {
                                channels[chan].noise = (((rand()&1)*2) - 1) * channels[chan].amplitude;
                            }
                            val -= channels[chan].noise;
                        }
                        break;
                }
            }
            else
            {
                pitch = (unsigned int)(channels[chan].pitch + channels[chan].pitchDelta) % 256;
                numSamplesPerWave = (int)(16000/pitchLookup[pitch]);
                if((channels[chan].angle%numSamplesPerWave) > (numSamplesPerWave>>1))
                    val -= channels[chan].amplitude;
                else
                    val += channels[chan].amplitude;
            }
            if(channels[chan].envelope > 0)
                processEnvelope(chan, (channels[chan].angle*100)/16000);
        }
        if(val > 127)
            val = 127;
        else if(val < -127)
            val = -127;
        stream[i] = val/2;
    }
}

canonical_original_code:
void fill_audio(void *udata, unsigned char *stream, int len)
{
    unsigned int numSamplesPerWave;
    unsigned char chan;
    int i; int val;
    unsigned int pitch;
    for(i = 0; i < len; ++i)
    {
        val = 0;
        for(chan = 0; chan < 4; ++chan)
        {
            if(finishedPlaying(chan))
            {
                channels[chan].adsr = RELEASE;
                issueSound(chan);
                continue;
            }
            channels[chan].angle++;
            if(chan == 0)
            {
                switch(channels[chan].pitch)
                {
                    case 0:
                        break;
                    case 1:
                        break;
                    case 2:
                        break;
                    case 3:
                        break;
                    case 4:
                        if((channels[chan].angle%((int)(16000/10000))) == 0)
                        {
                            channels[chan].noise = (((rand()&1)*2) - 1) * channels[chan].amplitude;
                        }
                        val -= channels[chan].noise;
                        break;
                    case 5:
                        if((channels[chan].angle%((int)(16000/5000))) == 0)
                        {
                            channels[chan].noise = (((rand()&1)*2) - 1) * channels[chan].amplitude;
                        }
                        val -= channels[chan].noise;
                        break;
                    case 6:
                        if((channels[chan].angle%((int)(16000/2500))) == 0)
                        {
                            channels[chan].noise = (((rand()&1)*2) - 1) * channels[chan].amplitude;
                        }
                        val -= channels[chan].noise;
                        break;
                    case 7:
                        {
                            pitch = (unsigned int)(channels[1].pitch + channels[1].pitchDelta) % 256;
                            numSamplesPerWave = (int)(16000/pitchLookup[pitch]);
                            if((channels[chan].angle%numSamplesPerWave) == 0)
                            {
                                channels[chan].noise = (((rand()&1)*2) - 1) * channels[chan].amplitude;
                            }
                            val -= channels[chan].noise;
                        }
                        break;
                }
            }
            else
            {
                pitch = (unsigned int)(channels[chan].pitch + channels[chan].pitchDelta) % 256;
                numSamplesPerWave = (int)(16000/pitchLookup[pitch]);
                if((channels[chan].angle%numSamplesPerWave) > (numSamplesPerWave>>1))
                    val -= channels[chan].amplitude;
                else
                    val += channels[chan].amplitude;
            }
            if(channels[chan].envelope > 0)
                processEnvelope(chan, (channels[chan].angle*100)/16000);
        }
        if(val > 127)
            val = 127;
        else if(val < -127)
            val = -127;
        stream[i] = val/2;
    }
}

variable_types:
udata
void *

variable_types:
stream
unsigned char *

variable_types: len int

variable_types:
numSamplesPerWave
unsigned int

variable_types: i int

variable_types: val int

variable_types:
pitch
unsigned int


AudioInit

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

v0 = SDL_InitSubSystem(16LL);
result = 0LL;
if ( v0 != -1 )
{
ChannelsInit();
PitchInit();
QueueInit();
wanted = 16000;
*((_WORD *)&wanted + 2) = -32760;
*((_BYTE *)&wanted + 6) = 1;
*((_WORD *)&wanted + 4) = 512;
*((_QWORD *)&wanted + 2) = fill_audio;
*((_QWORD *)&wanted + 3) = 0LL;
v2 = SDL_OpenAudio(&wanted, 0LL);
result = 0LL;
if ( v2 >= 0 )
{
SDL_PauseAudio(0LL);
result = 1LL;
}
}
return result;
}

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

v0 = SDL_InitSubSystem(16LL);
result = 0LL;
if ( v0 != -1 )
{
func0();
func2();
func1();
wanted = 16000;
*((_WORD *)&wanted + 2) = -32760;
*((_BYTE *)&wanted + 6) = 1;
*((_WORD *)&wanted + 4) = 512;
*((_QWORD *)&wanted + 2) = fill_audio;
*((_QWORD *)&wanted + 3) = 0LL;
v2 = SDL_OpenAudio(&wanted, 0LL);
result = 0LL;
if ( v2 >= 0 )
{
SDL_PauseAudio(0LL);
result = 1LL;
}
}
return result;
}

original_code:
int AudioInit(void)
{
    if(SDL_InitSubSystem( 0x00000010 )==-1)
        return 0;
    ChannelsInit();
    PitchInit();
    QueueInit();
    wanted.freq = 16000;
    wanted.format = 0x8008;
    wanted.channels = 1;
    wanted.samples = 512;
    wanted.callback = fill_audio;
    wanted.userdata = ((void *)0);
    if ( SDL_OpenAudio(&wanted, ((void *)0)) < 0 ) {
        return 0;
    }
    SDL_PauseAudio(0);
    return 1;
}

canonical_original_code:
int AudioInit()
{
    if(SDL_InitSubSystem( 0x00000010 )==-1)
        return 0;
    ChannelsInit();
    PitchInit();
    QueueInit();
    wanted.freq = 16000;
    wanted.format = 0x8008;
    wanted.channels = 1;
    wanted.samples = 512;
    wanted.callback = fill_audio;
    wanted.userdata = ((void *)0);
    if ( SDL_OpenAudio(&wanted, ((void *)0)) < 0 ) {
        return 0;
    }
    SDL_PauseAudio(0);
    return 1;
}


AudioQuit

decompiled_code:
__int64 AudioQuit()
{
SDL_LockAudio();
SDL_PauseAudio(1LL);
SDL_UnlockAudio();
SDL_CloseAudio();
return SDL_QuitSubSystem(16LL);
}

canonical_decompiled_code:
__int64 func15()
{
SDL_LockAudio();
SDL_PauseAudio(1LL);
SDL_UnlockAudio();
SDL_CloseAudio();
return SDL_QuitSubSystem(16LL);
}

original_code:
void AudioQuit(void)
{
    SDL_LockAudio();
    SDL_PauseAudio(1);
    SDL_UnlockAudio();
    SDL_CloseAudio();
    SDL_QuitSubSystem(0x00000010);
}

canonical_original_code:
void AudioQuit()
{
    SDL_LockAudio();
    SDL_PauseAudio(1);
    SDL_UnlockAudio();
    SDL_CloseAudio();
    SDL_QuitSubSystem(0x00000010);
}