decompiled_code:
__int64 __fastcall system_init(_QWORD *a1)
{
_DWORD *v1; // rax
_DWORD *v2; // rbx
_QWORD *v3; // rax

v1 = malloc(0x10uLL);
a1[1] = v1;
if ( v1 )
{
v2 = v1;
v3 = malloc(0x30uLL);
*(_QWORD *)v2 = 0LL;
*a1 = v3;
*v3 = 0LL;
v2[2] = 0;
}
else
{
perror("Error: Memory allocation failed! Exiting...\n");
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(_QWORD *a1)
{
_DWORD *v1; // rax
_DWORD *v2; // rbx
_QWORD *v3; // rax

v1 = malloc(0x10uLL);
a1[1] = v1;
if ( v1 )
{
v2 = v1;
v3 = malloc(0x30uLL);
*(_QWORD *)v2 = 0LL;
*a1 = v3;
*v3 = 0LL;
v2[2] = 0;
}
else
{
perror("Error: Memory allocation failed! Exiting...\n");
}
return 1LL;
}

original_code:
BOOLEAN system_init(tm_type * tm)
{
 tm->stock = (struct stock_list *)malloc(sizeof(struct stock_list));
 if (!tm->stock){
  perror("Error: Memory allocation failed! Exiting...\n");
  return 1;
 }
 tm->coins = (struct coin *)malloc((6) * sizeof(struct coin));
 tm->coins->denomination = 0;
 tm->coins->count = 0;
 if (!tm->coins){
  perror("Error: Memory allocation failed! Exiting...\n");
  return 1;
 }
 tm->stock->head_stock = ((void *)0);
 tm->stock->num_stock_items = 0;
    return TRUE;
}

canonical_original_code:
enum truefalse system_init(struct tm *tm)
{
 tm->stock = (struct stock_list *)malloc(sizeof(struct stock_list));
 if (!tm->stock){
  perror("Error: Memory allocation failed! Exiting...\n");
  return 1;
 }
 tm->coins = (struct coin *)malloc((6) * sizeof(struct coin));
 tm->coins->denomination = 0;
 tm->coins->count = 0;
 if (!tm->coins){
  perror("Error: Memory allocation failed! Exiting...\n");
  return 1;
 }
 tm->stock->head_stock = ((void *)0);
 tm->stock->num_stock_items = 0;
    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; } *

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


original_code:
void system_free(tm_type_ptr tm)
{
 stock_node *currentItem = ((void *)0), *nextItem = ((void *)0);
 currentItem = tm->stock->head_stock;
 while (currentItem != ((void *)0)){
  nextItem = currentItem->next_node;
  free(currentItem->data);
  free(currentItem);
  currentItem = nextItem;
 }
 free(tm->stock);
 free(tm->coins);
}

canonical_original_code:
void system_free(struct tm *tm)
{
 struct stock_node *currentItem = ((void *)0); struct stock_node *nextItem = ((void *)0);
 currentItem = tm->stock->head_stock;
 while (currentItem != ((void *)0)){
  nextItem = currentItem->next_node;
  free(currentItem->data);
  free(currentItem);
  currentItem = nextItem;
 }
 free(tm->stock);
 free(tm->coins);
}

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

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

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


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s[3]; // [rsp+Dh] [rbp-1Bh] BYREF
char v5[24]; // [rsp+10h] [rbp-18h] BYREF

if ( argc == 3 )
{
if ( !strcmp(argv[1], "stock.csv") || !strcmp(argv[2], "coins.csv") )
{
system_init(v5);
load_data(v5, 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(v5);
break;
case 2:
display_tickets(v5);
break;
case 3:
save_data(v5, 0LL, 0LL);
system_free(v5);
exit(0);
case 4:
add_ticket(v5);
break;
case 5:
delete_ticket(v5);
break;
case 6:
display_coins(v5);
break;
case 7:
restock_tickets(v5);
break;
case 8:
restock_coins(v5);
break;
case 9:
system_free(v5);
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: input int

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 }

return_type: int


decompiled_code:
int __fastcall purchase_ticket(__int64 a1)
{
_DWORD *v1; // r14
__int64 v2; // rbx
__int64 v3; // rax
char v4; // r13
const char *v5; // rbp
bool v6; // zf
const char *v7; // r13
int v8; // ebp
const char *v9; // rsi
__int64 v10; // rax
char v12[3]; // [rsp+2h] [rbp-66h] BYREF
char v13[11]; // [rsp+5h] [rbp-63h] BYREF
char s2[88]; // [rsp+10h] [rbp-58h] BYREF

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

canonical_decompiled_code:
int __fastcall func0(__int64 a1)
{
_DWORD *v1; // r14
__int64 v2; // rbx
__int64 v3; // rax
char v4; // r13
const char *v5; // rbp
bool v6; // zf
const char *v7; // r13
int v8; // ebp
const char *v9; // rsi
__int64 v10; // rax
char v12[3]; // [rsp+2h] [rbp-66h] BYREF
char v13[11]; // [rsp+5h] [rbp-63h] BYREF
char s2[88]; // [rsp+10h] [rbp-58h] BYREF

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

variable_types:
print
char *

variable_types: returnedprice int

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


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


decompiled_code:
int __fastcall add_ticket(__int64 a1)
{
size_t v1; // rax
int v2; // ebx
char *v3; // rax
char *v4; // r12
char v6[3]; // [rsp+8h] [rbp-60h] BYREF
char s[10]; // [rsp+Bh] [rbp-5Dh] BYREF
char v8[11]; // [rsp+15h] [rbp-53h] 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): ", v6, 3LL);
if ( v1 )
{
v1 = zoneinput("Ticket zone (1-3 characters): ", v8, 5LL);
if ( v1 )
{
while ( 1 )
{
printf("Price (in cents): ");
fgets(s, 10, stdin);
v1 = strlen(s);
if ( v6[v1 + 2] == 10 )
break;
puts("Error: Input was too long! Try again.");
read_rest_of_line();
}
if ( s[0] != 10 || s[1] )
{
s[v1 - 1] = 0;
v2 = atoi(s);
v3 = (char *)malloc(0x40uLL);
v4 = v3;
if ( !v3 )
{
perror("Error: Memory allocation failed! Exiting...\n");
exit(1);
}
strcpy(v3, src);
v4[41] = v6[0];
strcpy(v4 + 42, v8);
*((_DWORD *)v4 + 14) = v2;
*((_DWORD *)v4 + 15) = 10;
add_stock_to_node(a1, v4);
LODWORD(v1) = puts("Ticket successfully added to system.");
}
}
}
}
return v1;
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1)
{
size_t v1; // rax
int v2; // ebx
char *v3; // rax
char *v4; // r12
char v6[3]; // [rsp+8h] [rbp-60h] BYREF
char s[10]; // [rsp+Bh] [rbp-5Dh] BYREF
char v8[11]; // [rsp+15h] [rbp-53h] 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): ", v6, 3LL);
if ( v1 )
{
v1 = zoneinput("Ticket zone (1-3 characters): ", v8, 5LL);
if ( v1 )
{
while ( 1 )
{
printf("Price (in cents): ");
fgets(s, 10, stdin);
v1 = strlen(s);
if ( v6[v1 + 2] == 10 )
break;
puts("Error: Input was too long! Try again.");
read_rest_of_line();
}
if ( s[0] != 10 || s[1] )
{
s[v1 - 1] = 0;
v2 = atoi(s);
v3 = (char *)malloc(0x40uLL);
v4 = v3;
if ( !v3 )
{
perror("Error: Memory allocation failed! Exiting...\n");
exit(1);
}
strcpy(v3, src);
v4[41] = v6[0];
strcpy(v4 + 42, v8);
*((_DWORD *)v4 + 14) = v2;
*((_DWORD *)v4 + 15) = 10;
add_stock_to_node(a1, v4);
LODWORD(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; // rbp
__int64 v2; // rax
char v3; // r14
__int64 v4; // r12
const char *v5; // rbx
__int64 v6; // rax
bool v7; // zf
const char *v8; // r14
const char *v9; // rdx
__int64 v10; // rcx
char v12[3]; // [rsp+2h] [rbp-66h] BYREF
char v13[11]; // [rsp+5h] [rbp-63h] BYREF
char s2[88]; // [rsp+10h] [rbp-58h] 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): ", v13, 5LL);
if ( v2 )
{
if ( v1 )
{
v3 = v12[0];
v4 = 0LL;
while ( 1 )
{
v5 = *(const char **)v1;
if ( !strcmp(*(const char **)v1, s2) && v5[41] == v3 && !strcmp(v5 + 42, v13) )
break;
v4 = v1;
if ( !*(_QWORD *)(v1 + 8) )
goto LABEL_16;
v1 = *(_QWORD *)(v1 + 8);
}
v6 = *(_QWORD *)(a1 + 8);
if ( v1 == *(_QWORD *)v6 )
{
v9 = "full fare";
if ( v3 != 70 )
v9 = "concession";
v10 = *(_QWORD *)(v1 + 8);
--*(_DWORD *)(v6 + 8);
*(_QWORD *)v6 = v10;
LODWORD(v2) = printf("\nTicket '%s %s zone %s' has been removed from ticketing machine.\n", s2, v9, v13);
}
else
{
v7 = v3 == 70;
v8 = "full fare";
if ( !v7 )
v8 = "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, v8, v13);
}
}
else
{
LABEL_16:
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; // rbp
__int64 v2; // rax
char v3; // r14
__int64 v4; // r12
const char *v5; // rbx
__int64 v6; // rax
bool v7; // zf
const char *v8; // r14
const char *v9; // rdx
__int64 v10; // rcx
char v12[3]; // [rsp+2h] [rbp-66h] BYREF
char v13[11]; // [rsp+5h] [rbp-63h] BYREF
char s2[88]; // [rsp+10h] [rbp-58h] 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): ", v13, 5LL);
if ( v2 )
{
if ( v1 )
{
v3 = v12[0];
v4 = 0LL;
while ( 1 )
{
v5 = *(const char **)v1;
if ( !strcmp(*(const char **)v1, s2) && v5[41] == v3 && !strcmp(v5 + 42, v13) )
break;
v4 = v1;
if ( !*(_QWORD *)(v1 + 8) )
goto LABEL_16;
v1 = *(_QWORD *)(v1 + 8);
}
v6 = *(_QWORD *)(a1 + 8);
if ( v1 == *(_QWORD *)v6 )
{
v9 = "full fare";
if ( v3 != 70 )
v9 = "concession";
v10 = *(_QWORD *)(v1 + 8);
--*(_DWORD *)(v6 + 8);
*(_QWORD *)v6 = v10;
LODWORD(v2) = printf("\nTicket '%s %s zone %s' has been removed from ticketing machine.\n", s2, v9, v13);
}
else
{
v7 = v3 == 70;
v8 = "full fare";
if ( !v7 )
v8 = "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, v8, v13);
}
}
else
{
LABEL_16:
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;
}


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


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

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

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

v1 = **(__int64 ***)(a1 + 8);
puts("\nRestock Tickets");
puts("---------------");
for ( ; v1; *(_DWORD *)(v2 + 60) = 10 )
{
v2 = *v1;
v1 = (__int64 *)v1[1];
}
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");
}

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


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:
// attributes: thunk
int stock_cmp(const char *s1, const char *s2)
{
return strcmp(s1, s2);
}

canonical_decompiled_code:
int func0(const char *s1, const char *s2)
{
return strcmp(s1, s2);
}

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


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 *

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


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

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

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

v2 = (char *)malloc(0x40uLL);
v3 = strtok(a2, ",");
if ( v3 )
{
v4 = v3;
v5 = 1;
do
{
v6 = v5++;
switch ( v6 )
{
case 1:
strcpy(v11, v4);
strcpy(v2, v11);
break;
case 2:
v8 = *v4;
if ( *v4 != 70 )
v8 = 67;
v2[41] = v8;
break;
case 3:
strcpy(src, v4);
strcpy(v2 + 42, src);
break;
case 4:
strcpy(nptr, v4);
*((_DWORD *)v2 + 14) = atoi(nptr);
goto LABEL_8;
case 5:
strcpy(dest, v4);
*((_DWORD *)v2 + 15) = atoi(dest);
break;
default:
if ( v5 == 5 )
LABEL_8:
func1(a1, v2);
break;
}
v4 = strtok(0LL, ",");
}
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
__int64 result; // rax

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

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

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

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:
data
struct coin *


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

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

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

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

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


ChannelsInit

repo: jameswalmsley/chuckie

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

result = &channels;
do
{
*((_BYTE *)result + 1) = 0;
result = (__int64 *)((char *)result + 28);
*((_DWORD *)result - 6) = 0;
*((_BYTE *)result - 26) = 0;
*((_DWORD *)result - 4) = 0;
*((_DWORD *)result - 5) = 0;
*((_BYTE *)result - 28) = 0;
*((_DWORD *)result - 3) = 0;
*((_DWORD *)result - 2) = 0;
*((_DWORD *)result - 1) = 0;
}
while ( result != &channels + 14 );
return result;
}

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

result = &channels;
do
{
*((_BYTE *)result + 1) = 0;
result = (__int64 *)((char *)result + 28);
*((_DWORD *)result - 6) = 0;
*((_BYTE *)result - 26) = 0;
*((_DWORD *)result - 4) = 0;
*((_DWORD *)result - 5) = 0;
*((_BYTE *)result - 28) = 0;
*((_DWORD *)result - 3) = 0;
*((_DWORD *)result - 2) = 0;
*((_DWORD *)result - 1) = 0;
}
while ( result != &channels + 14 );
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:
void QueueInit()
{
queueBegin = 0LL;
queueEnd = 0LL;
queueSize = 0LL;
}

canonical_decompiled_code:
void func1()
{
queueBegin = 0LL;
queueEnd = 0LL;
queueSize = 0LL;
}

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(unsigned int a1, char a2, char a3, char a4)
{
__int64 v7; // rdx
__int64 result; // rax
int v9; // er10
__int64 v10; // rcx
__int64 v11; // rcx

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

canonical_decompiled_code:
__int64 __fastcall func3(unsigned int a1, char a2, char a3, char a4)
{
__int64 v7; // rdx
__int64 result; // rax
int v9; // er10
__int64 v10; // rcx
__int64 v11; // rcx

v7 = a1 & 3;
result = (a1 >> 4) & 1;
if ( ((a1 >> 4) & 1) != 0 )
{
*((_DWORD *)&queueBegin + v7) = 0;
v9 = (a1 >> 4) & 1;
v10 = 0LL;
LABEL_3:
v11 = v7 + 4 * v10;
*((_DWORD *)&queueEnd + v7) = v9;
soundQueue[2 * v11] = a1;
LOBYTE(soundQueue[2 * v11 + 1]) = a2;
BYTE1(soundQueue[2 * v11 + 1]) = a3;
BYTE2(soundQueue[2 * v11 + 1]) = a4;
*((_DWORD *)&queueSize + v7) = result;
return result;
}
result = *((unsigned int *)&queueSize + v7);
if ( (_DWORD)result != 64 )
{
v10 = *((unsigned int *)&queueEnd + v7);
result = (unsigned int)(result + 1);
v9 = ((_BYTE)v10 + 1) & 0x3F;
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 v1; // rax
char v2; // dl
char v3; // si
unsigned __int8 v4; // di
char *v5; // r9
int v6; // ecx
__int64 result; // rax
char *v8; // r8
__int64 v9; // rax
char *v10; // rcx
float v11; // xmm0_4
unsigned int v12; // edx

v1 = *(_DWORD *)a1 & 3;
if ( (*(_DWORD *)a1 & 0x1000) != 0 )
{
v9 = 28 * v1;
v10 = (char *)&channels + v9;
v11 = 16000.0 / pitchLookup[(unsigned __int8)(*((_BYTE *)&channels + v9 + 16) + *((_BYTE *)&channels + v9))];
v12 = *(_DWORD *)((char *)&channels + v9 + 12) % (unsigned int)(int)v11;
result = *(_DWORD *)((char *)&channels + v9 + 12) / (unsigned int)(int)v11;
*((_DWORD *)v10 + 3) = v12;
}
else
{
v2 = *(_BYTE *)(a1 + 4);
v3 = *(_BYTE *)(a1 + 5);
v4 = *(_BYTE *)(a1 + 6);
if ( v2 <= 0 )
{
v8 = (char *)&channels + 28 * v1;
v8[2] = 0;
v8[1] = -8 * v2;
}
else
{
v5 = (char *)&channels + 28 * v1;
v5[1] = 0;
v5[2] = v2 % 17;
}
v6 = -1;
if ( v4 != 0xFF )
v6 = 50 * v4;
result = 28 * v1;
*(_DWORD *)((char *)&channels + result + 4) = v6;
*((_BYTE *)&channels + result) = v3;
*(__int64 *)((char *)&channels + result + 8) = 0LL;
*(__int64 *)((char *)&channels + result + 16) = 0LL;
*(_DWORD *)((char *)&channels + result + 24) = 0;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 v1; // rax
char v2; // dl
char v3; // si
unsigned __int8 v4; // di
char *v5; // r9
int v6; // ecx
__int64 result; // rax
char *v8; // r8
__int64 v9; // rax
char *v10; // rcx
float v11; // xmm0_4
unsigned int v12; // edx

v1 = *(_DWORD *)a1 & 3;
if ( (*(_DWORD *)a1 & 0x1000) != 0 )
{
v9 = 28 * v1;
v10 = (char *)&channels + v9;
v11 = 16000.0 / pitchLookup[(unsigned __int8)(*((_BYTE *)&channels + v9 + 16) + *((_BYTE *)&channels + v9))];
v12 = *(_DWORD *)((char *)&channels + v9 + 12) % (unsigned int)(int)v11;
result = *(_DWORD *)((char *)&channels + v9 + 12) / (unsigned int)(int)v11;
*((_DWORD *)v10 + 3) = v12;
}
else
{
v2 = *(_BYTE *)(a1 + 4);
v3 = *(_BYTE *)(a1 + 5);
v4 = *(_BYTE *)(a1 + 6);
if ( v2 <= 0 )
{
v8 = (char *)&channels + 28 * v1;
v8[2] = 0;
v8[1] = -8 * v2;
}
else
{
v5 = (char *)&channels + 28 * v1;
v5[1] = 0;
v5[2] = v2 % 17;
}
v6 = -1;
if ( v4 != 0xFF )
v6 = 50 * v4;
result = 28 * v1;
*(_DWORD *)((char *)&channels + result + 4) = v6;
*((_BYTE *)&channels + result) = v3;
*(__int64 *)((char *)&channels + result + 8) = 0LL;
*(__int64 *)((char *)&channels + result + 16) = 0LL;
*(_DWORD *)((char *)&channels + result + 24) = 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:
void __fastcall issueSound(unsigned __int8 a1)
{
__int64 v1; // rsi
int v2; // er9
__int64 v4; // r8
int *v5; // rdi
int v6; // edx
__int64 v7; // rax
int v8; // er11

v1 = a1;
v2 = *((_DWORD *)&queueSize + a1);
if ( v2 )
{
v4 = *((unsigned int *)&queueBegin + a1);
v5 = &soundQueue[8 * v4 + 2 * a1];
v6 = ((unsigned int)*v5 >> 8) & 3;
if ( !v6 )
goto LABEL_8;
v7 = 0LL;
v8 = (unsigned __int8)v6;
do
{
if ( a1 != (_BYTE)v7 )
LOBYTE(v6) = v6
- ((((unsigned int)soundQueue[8 * *((unsigned int *)&queueBegin + v7) + 2 * (int)v7] >> 8) & 3) == v8);
++v7;
}
while ( v7 != 4 );
if ( !(_BYTE)v6 )
{
LABEL_8:
*((_DWORD *)&queueSize + v1) = v2 - 1;
*((_DWORD *)&queueBegin + v1) = ((_BYTE)v4 + 1) & 0x3F;
playSound((__int64)v5);
}
}
}

canonical_decompiled_code:
void __fastcall func6(unsigned __int8 a1)
{
__int64 v1; // rsi
int v2; // er9
__int64 v4; // r8
int *v5; // rdi
int v6; // edx
__int64 v7; // rax
int v8; // er11

v1 = a1;
v2 = *((_DWORD *)&queueSize + a1);
if ( v2 )
{
v4 = *((unsigned int *)&queueBegin + a1);
v5 = &soundQueue[8 * v4 + 2 * a1];
v6 = ((unsigned int)*v5 >> 8) & 3;
if ( !v6 )
goto LABEL_8;
v7 = 0LL;
v8 = (unsigned __int8)v6;
do
{
if ( a1 != (_BYTE)v7 )
LOBYTE(v6) = v6
- ((((unsigned int)soundQueue[8 * *((unsigned int *)&queueBegin + v7) + 2 * (int)v7] >> 8) & 3) == v8);
++v7;
}
while ( v7 != 4 );
if ( !(_BYTE)v6 )
{
LABEL_8:
*((_DWORD *)&queueSize + v1) = v2 - 1;
*((_DWORD *)&queueBegin + v1) = ((_BYTE)v4 + 1) & 0x3F;
func5((__int64)v5);
}
}
}

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, char a14)
{
__int64 result; // rax

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

canonical_decompiled_code:
__int64 __fastcall func7(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, char a14)
{
__int64 result; // rax

result = 14LL * (a1 - 1);
*((_BYTE *)&envelopes + result + 6) = a7;
*((_BYTE *)&envelopes + result) = a1;
*((_BYTE *)&envelopes + result + 7) = a8;
*((_BYTE *)&envelopes + result + 1) = a2;
*((_BYTE *)&envelopes + result + 8) = a9;
*((_BYTE *)&envelopes + result + 2) = a3;
*((_BYTE *)&envelopes + result + 9) = a10;
*((_BYTE *)&envelopes + result + 3) = a4;
*((_BYTE *)&envelopes + result + 10) = a11;
*((_BYTE *)&envelopes + result + 4) = a5;
*((_BYTE *)&envelopes + result + 11) = a12;
*((_BYTE *)&envelopes + result + 5) = a6;
*((_BYTE *)&envelopes + result + 12) = a13;
*((_BYTE *)&envelopes + result + 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)
{
__int64 v1; // rax
char *v2; // rdx
__int64 result; // rax

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

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

v1 = 14LL * (*a1 - 1);
*(__int64 *)((char *)&envelopes + v1) = *(_QWORD *)a1;
v2 = (char *)&envelopes + v1;
*((_DWORD *)v2 + 2) = *((_DWORD *)a1 + 2);
result = *((unsigned __int16 *)a1 + 6);
*((_WORD *)v2 + 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, __int64 a2)
{
unsigned int v2; // er8
unsigned int v3; // er9
__int64 result; // rax
unsigned int v5; // ecx
unsigned int v6; // edx
int v7; // ecx

v2 = *(unsigned __int8 *)(a2 + 5);
v3 = *(unsigned __int8 *)(a2 + 6);
result = v2 + v3;
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;
}
v7 = *(_DWORD *)(a1 + 16);
if ( v2 <= v6 )
{
if ( v3 > v6 )
{
result = (unsigned int)(v7 + *(char *)(a2 + 3));
*(_DWORD *)(a1 + 16) = result;
}
else
{
result = (unsigned int)(v7 + *(char *)(a2 + 4));
*(_DWORD *)(a1 + 16) = result;
}
}
else
{
result = (unsigned int)(v7 + *(char *)(a2 + 2));
*(_DWORD *)(a1 + 16) = result;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, __int64 a2)
{
unsigned int v2; // er8
unsigned int v3; // er9
__int64 result; // rax
unsigned int v5; // ecx
unsigned int v6; // edx
int v7; // ecx

v2 = *(unsigned __int8 *)(a2 + 5);
v3 = *(unsigned __int8 *)(a2 + 6);
result = v2 + v3;
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;
}
v7 = *(_DWORD *)(a1 + 16);
if ( v2 <= v6 )
{
if ( v3 > v6 )
{
result = (unsigned int)(v7 + *(char *)(a2 + 3));
*(_DWORD *)(a1 + 16) = result;
}
else
{
result = (unsigned int)(v7 + *(char *)(a2 + 4));
*(_DWORD *)(a1 + 16) = result;
}
}
else
{
result = (unsigned int)(v7 + *(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

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)
{
char *v3; // rsi
int v4; // ecx
char *v5; // r11
int v6; // edx
_BYTE *v7; // rsi
unsigned __int8 v8; // r10

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

canonical_decompiled_code:
char __fastcall func11(unsigned __int8 a1, unsigned int a2)
{
char *v3; // rsi
int v4; // ecx
char *v5; // r11
int v6; // edx
_BYTE *v7; // rsi
unsigned __int8 v8; // r10

v3 = (char *)channels + 28 * a1;
v4 = (unsigned __int8)v3[2];
if ( !(_BYTE)v4 )
_assert_fail("channel->envelope > 0", "/usr/src/repo/bbcb/sound.c", 0x2BDu, "processEnvelope");
v5 = (char *)&envelopes + 14 * v4 - 14;
if ( (v5[1] & 0x7F) != 0 )
{
a2 /= v5[1] & 0x7Fu;
v6 = *((_DWORD *)v3 + 5);
*((_DWORD *)v3 + 5) = a2;
if ( v6 != a2 )
{
v7 = (char *)&envelopes + 14 * v4 - 14;
func9((__int64)channels + 28 * a1, (__int64)v5);
LOBYTE(a2) = func10(v8, v7);
}
}
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)
{
return (channels[7 * a1 + 1] + 1000 * channels[7 * a1 + 3] / -16000 <= 0) & (unsigned __int8)(channels[7 * a1 + 1] >= 0);
}

canonical_decompiled_code:
__int64 __fastcall func12(unsigned __int8 a1)
{
return (channels[7 * a1 + 1] + 1000 * channels[7 * a1 + 3] / -16000 <= 0) & (unsigned __int8)(channels[7 * a1 + 1] >= 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)
{
__int64 v3; // r14
_BYTE *v4; // r13
int v5; // er15
int v6; // ebp
_DWORD *v7; // rbx
char v8; // r12
unsigned int v9; // ecx
float v10; // xmm0_4
int v11; // eax
int v12; // eax

if ( a3 > 0 )
{
v3 = (__int64)&a2[a3 - 1 + 1];
v4 = a2;
LABEL_3:
v5 = 0;
v6 = 0;
v7 = channels;
v8 = 1;
if ( (unsigned int)finishedPlaying(0) )
{
LABEL_10:
v7[6] = 3;
issueSound(v5);
if ( v8 == 4 )
goto LABEL_11;
goto LABEL_9;
}
while ( 1 )
{
v9 = v7[3] + 1;
v7[3] = v9;
if ( v5 )
{
v10 = 16000.0 / pitchLookup[(unsigned __int8)(*((_BYTE *)v7 + 16) + *(_BYTE *)v7)];
v11 = *((unsigned __int8 *)v7 + 1);
if ( v9 % (int)v10 <= (unsigned int)(int)v10 >> 1 )
v6 += v11;
else
v6 -= v11;
LABEL_7:
if ( !*((_BYTE *)v7 + 2) )
goto LABEL_8;
goto LABEL_25;
}
if ( LOBYTE(channels[0]) == 6 )
{
if ( __ROR4__(-1431655765 * v9, 1) <= 0x2AAAAAAAu )
goto LABEL_28;
}
else if ( LOBYTE(channels[0]) > 6u )
{
if ( LOBYTE(channels[0]) != 7 )
goto LABEL_7;
if ( !(v9 % (int)(float)(16000.0 / pitchLookup[(unsigned __int8)(LOBYTE(channels[11]) + LOBYTE(channels[7]))])) )
{
LABEL_28:
v12 = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
channels[2] = v12;
goto LABEL_23;
}
}
else
{
if ( LOBYTE(channels[0]) == 4 )
goto LABEL_28;
if ( LOBYTE(channels[0]) != 5 )
goto LABEL_7;
if ( -1431655765 * v9 <= 0x55555555 )
goto LABEL_28;
}
v12 = channels[2];
LABEL_23:
v6 -= v12;
if ( !*((_BYTE *)v7 + 2) )
goto LABEL_9;
v9 = v7[3];
LABEL_25:
processEnvelope(v5, 100 * v9 / 0x3E80);
LABEL_8:
if ( v8 == 4 )
{
LABEL_11:
if ( v6 < -127 )
v6 = -127;
if ( v6 > 127 )
v6 = 127;
*v4++ = v6 / 2;
if ( (_BYTE *)v3 == v4 )
return;
goto LABEL_3;
}
LABEL_9:
++v5;
++v8;
v7 += 7;
if ( (unsigned int)finishedPlaying(v5) )
goto LABEL_10;
}
}
}

canonical_decompiled_code:
void __fastcall func13(__int64 a1, _BYTE *a2, int a3)
{
__int64 v3; // r14
_BYTE *v4; // r13
int v5; // er15
int v6; // ebp
_DWORD *v7; // rbx
char v8; // r12
unsigned int v9; // ecx
float v10; // xmm0_4
int v11; // eax
int v12; // eax

if ( a3 > 0 )
{
v3 = (__int64)&a2[a3 - 1 + 1];
v4 = a2;
LABEL_3:
v5 = 0;
v6 = 0;
v7 = channels;
v8 = 1;
if ( (unsigned int)func12(0) )
{
LABEL_10:
v7[6] = 3;
func6(v5);
if ( v8 == 4 )
goto LABEL_11;
goto LABEL_9;
}
while ( 1 )
{
v9 = v7[3] + 1;
v7[3] = v9;
if ( v5 )
{
v10 = 16000.0 / pitchLookup[(unsigned __int8)(*((_BYTE *)v7 + 16) + *(_BYTE *)v7)];
v11 = *((unsigned __int8 *)v7 + 1);
if ( v9 % (int)v10 <= (unsigned int)(int)v10 >> 1 )
v6 += v11;
else
v6 -= v11;
LABEL_7:
if ( !*((_BYTE *)v7 + 2) )
goto LABEL_8;
goto LABEL_25;
}
if ( LOBYTE(channels[0]) == 6 )
{
if ( __ROR4__(-1431655765 * v9, 1) <= 0x2AAAAAAAu )
goto LABEL_28;
}
else if ( LOBYTE(channels[0]) > 6u )
{
if ( LOBYTE(channels[0]) != 7 )
goto LABEL_7;
if ( !(v9 % (int)(float)(16000.0 / pitchLookup[(unsigned __int8)(LOBYTE(channels[11]) + LOBYTE(channels[7]))])) )
{
LABEL_28:
v12 = BYTE1(channels[0]) * (2 * (rand() & 1) - 1);
channels[2] = v12;
goto LABEL_23;
}
}
else
{
if ( LOBYTE(channels[0]) == 4 )
goto LABEL_28;
if ( LOBYTE(channels[0]) != 5 )
goto LABEL_7;
if ( -1431655765 * v9 <= 0x55555555 )
goto LABEL_28;
}
v12 = channels[2];
LABEL_23:
v6 -= v12;
if ( !*((_BYTE *)v7 + 2) )
goto LABEL_9;
v9 = v7[3];
LABEL_25:
func11(v5, 100 * v9 / 0x3E80);
LABEL_8:
if ( v8 == 4 )
{
LABEL_11:
if ( v6 < -127 )
v6 = -127;
if ( v6 > 127 )
v6 = 127;
*v4++ = v6 / 2;
if ( (_BYTE *)v3 == v4 )
return;
goto LABEL_3;
}
LABEL_9:
++v5;
++v8;
v7 += 7;
if ( (unsigned int)func12(v5) )
goto LABEL_10;
}
}
}

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()
{
__int16 v0; // ax
__int16 v1; // dx

if ( (unsigned int)SDL_InitSubSystem(16LL) == -1 )
return 0LL;
ChannelsInit();
PitchInit();
QueueInit();
wanted = 16000;
*((_WORD *)&wanted + 2) = v0;
*((_BYTE *)&wanted + 6) = 1;
*((_WORD *)&wanted + 4) = v1;
*((_QWORD *)&wanted + 2) = fill_audio;
*((_QWORD *)&wanted + 3) = 0LL;
if ( (int)SDL_OpenAudio(&wanted, 0LL) < 0 )
return 0LL;
SDL_PauseAudio(0LL);
return 1LL;
}

canonical_decompiled_code:
__int64 func14()
{
__int16 v0; // ax
__int16 v1; // dx

if ( (unsigned int)SDL_InitSubSystem(16LL) == -1 )
return 0LL;
func0();
func2();
func1();
wanted = 16000;
*((_WORD *)&wanted + 2) = v0;
*((_BYTE *)&wanted + 6) = 1;
*((_WORD *)&wanted + 4) = v1;
*((_QWORD *)&wanted + 2) = fill_audio;
*((_QWORD *)&wanted + 3) = 0LL;
if ( (int)SDL_OpenAudio(&wanted, 0LL) < 0 )
return 0LL;
SDL_PauseAudio(0LL);
return 1LL;
}

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