original_code:
void get_tcp(struct TCPHeader* tcphead) {
  tcphead->src = get16();
  tcphead->dest = get16();
  tcphead->seqnum = get32();
  tcphead->acknum = get32();
  tcphead->byte0 = get8();
  tcphead->byte1 = get8();
  tcphead->winsize = get16();
  tcphead->checksum = get16();
  tcphead->urgpoint = get16();
}

canonical_original_code:
void get_tcp(struct TCPHeader *tcphead) {
  tcphead->src = get16();
  tcphead->dest = get16();
  tcphead->seqnum = get32();
  tcphead->acknum = get32();
  tcphead->byte0 = get8();
  tcphead->byte1 = get8();
  tcphead->winsize = get16();
  tcphead->checksum = get16();
  tcphead->urgpoint = get16();
}

variable_types: struct TCPHeader { unsigned short src; unsigned short dest; unsigned int seqnum; unsigned int acknum; unsigned char byte0; unsigned char byte1; unsigned short winsize; unsigned short checksum; unsigned short urgpoint; } *


decompiled_code:
int __fastcall print_tcp(unsigned __int16 *a1)
{
char v1; // al
const char *v2; // rdx
char *v3; // rsi

v1 = *((_BYTE *)a1 + 13);
v2 = "NSYN" + 1;
v3 = "ACK";
if ( (v1 & 2) == 0 )
v2 = "NSYN";
if ( (v1 & 0x10) == 0 )
v3 = "NACK";
printf("<<<TCP %s %s\n", v3, v2);
printf(" %d -> %d\n", *a1, a1[1]);
printf(" seq num: 0x%08x\n", *((unsigned int *)a1 + 1));
return printf(" ack num: 0x%08x\n", *((unsigned int *)a1 + 2));
}

canonical_decompiled_code:
int __fastcall func18(unsigned __int16 *a1)
{
char v1; // al
const char *v2; // rdx
char *v3; // rsi

v1 = *((_BYTE *)a1 + 13);
v2 = "NSYN" + 1;
v3 = "ACK";
if ( (v1 & 2) == 0 )
v2 = "NSYN";
if ( (v1 & 0x10) == 0 )
v3 = "NACK";
printf("<<<TCP %s %s\n", v3, v2);
printf(" %d -> %d\n", *a1, a1[1]);
printf(" seq num: 0x%08x\n", *((unsigned int *)a1 + 1));
return printf(" ack num: 0x%08x\n", *((unsigned int *)a1 + 2));
}

original_code:
void print_tcp(struct TCPHeader* tcphead) {
  printf("<<<TCP %s %s\n", tcphead->byte1&0x10?"ACK":"NACK", tcphead->byte1&0x02?"SYN":"NSYN");
  printf("    %d -> %d\n", tcphead->src, tcphead->dest);
  printf("    seq num: 0x%08x\n", tcphead->seqnum);
  printf("    ack num: 0x%08x\n", tcphead->acknum);
}

canonical_original_code:
void print_tcp(struct TCPHeader *tcphead) {
  printf("<<<TCP %s %s\n", tcphead->byte1&0x10?"ACK":"NACK", tcphead->byte1&0x02?"SYN":"NSYN");
  printf("    %d -> %d\n", tcphead->src, tcphead->dest);
  printf("    seq num: 0x%08x\n", tcphead->seqnum);
  printf("    ack num: 0x%08x\n", tcphead->acknum);
}

return_type: void

user_defined_types: struct TCPHeader { unsigned short src; unsigned short dest; unsigned int seqnum; unsigned int acknum; unsigned char byte0; unsigned char byte1; unsigned short winsize; unsigned short checksum; unsigned short urgpoint; }


main

canonical_name: main

decompiled_code:
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
unsigned __int16 v4; // si
const char *v5; // rdi
const char *v6; // rdi
__int64 v8; // rax
char v9[12]; // [rsp+2h] [rbp-86h] BYREF
unsigned __int16 v10; // [rsp+Eh] [rbp-7Ah]
char ptr[8]; // [rsp+10h] [rbp-78h] BYREF
unsigned int v12; // [rsp+18h] [rbp-70h]
unsigned int v13; // [rsp+1Ch] [rbp-6Ch]
char v14[2]; // [rsp+20h] [rbp-68h] BYREF
unsigned __int16 v15; // [rsp+22h] [rbp-66h]
char v16; // [rsp+29h] [rbp-5Fh]
char v17[4]; // [rsp+40h] [rbp-48h] BYREF
unsigned __int16 v18; // [rsp+44h] [rbp-44h]
int v19; // [rsp+60h] [rbp-28h] BYREF
unsigned __int16 v20; // [rsp+64h] [rbp-24h]
unsigned __int16 v21; // [rsp+66h] [rbp-22h]
unsigned int v22; // [rsp+70h] [rbp-18h]
int v23; // [rsp+74h] [rbp-14h]

if ( argc == 1 )
{
fread(&v19, 1uLL, 0x18uLL, _bss_start);
if ( v19 == -1582119980 )
{
printf("PCAP format v%d.%d, ", v20, v21);
if ( v23 == 1 )
{
v3 = 0;
puts("link layer type: Ethernet.");
goto LABEL_4;
}
puts("unsupported link layer type");
}
else
{
puts("invalid file format");
}
}
else
{
if ( argc == 2 )
{
*(_QWORD *)&argc = argv[1];
argv = (const char **)"-r";
v3 = 1;
if ( !strcmp(*(const char **)&argc, "-r") )
{
while ( 1 )
{
LABEL_4:
while ( 1 )
{
putchar(10);
if ( !v3 )
break;
get_ether(v9);
print_ether(v9);
v4 = v10;
if ( v10 > 0x5DCu )
goto LABEL_8;
printf("Old style packet, length = %d\n", v10);
puts("We don't support this packet now");
}
while ( 1 )
{
if ( fread(ptr, 1uLL, 0x10uLL, _bss_start) != 16 )
return 0;
if ( v12 > v22 )
{
v8 = ftell(_bss_start);
printf("wrong packet at 0x%08x\n", v8);
return 0;
}
puts("<<<PCAP packet");
printf(" packet size: %d\n", v12);
printf(" payload size: %d\n", v13);
get_ether(v9);
print_ether(v9);
v4 = v10;
if ( v10 <= 0x5DCu )
{
printf("Old style packet, length = %d\n", v10);
puts("We don't support this packet now");
goto LABEL_12;
}
LABEL_8:
if ( v4 == 2048 )
{
get_ipv4(v14);
print_ipv4(v14);
if ( v16 == 4 )
{
puts("IP packet");
v6 = "Wedon't support this packet now";
LABEL_21:
puts(v6);
dump((unsigned int)v15 - 20, 1LL);
goto LABEL_22;
}
if ( v16 == 6 )
{
get_tcp(v17);
print_tcp(v17);
if ( v12 < (unsigned __int64)v15 + 14 )
dump(v12 - 54, 0LL);
else
dump((unsigned int)v15 - 40, 0LL);
goto LABEL_22;
}
v6 = "Unexpected IP packet";
if ( v16 != 17 )
goto LABEL_21;
get_udp(v17);
if ( v18 != v15 - 20LL )
__assert_fail("udphead.size == ipv4head.datalen-sizeof(ipv4head)", "wireguppy.c", 0x157u, "main");
print_udp(v17);
if ( v12 < (unsigned __int64)v15 + 14 )
dump(v12 + v18 - 22 - v15, 0LL);
else
dump((unsigned int)v18 - 8, 0LL);
LABEL_22:
if ( !v3 && v12 > (unsigned __int64)v15 + 14 )
{
puts("pad:");
dump(v12 - 14 - v15, 1LL);
}
goto LABEL_4;
}
v5 = "ARP packet";
if ( v4 == 2054 )
goto LABEL_16;
if ( v4 != 0x86DD )
break;
v5 = "IPv6 packet";
LABEL_16:
puts(v5);
puts("We don't support this packet now");
if ( v3 )
goto LABEL_4;
LABEL_12:
dump(v12 - 14, 1LL);
putchar(10);
}
puts("Unexpected Ethernet packet");
if ( !v3 )
goto LABEL_12;
}
}
}
usage(*(_QWORD *)&argc, argv, envp);
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
unsigned __int16 v4; // si
const char *v5; // rdi
const char *v6; // rdi
__int64 v8; // rax
char v9[12]; // [rsp+2h] [rbp-86h] BYREF
unsigned __int16 v10; // [rsp+Eh] [rbp-7Ah]
char ptr[8]; // [rsp+10h] [rbp-78h] BYREF
unsigned int v12; // [rsp+18h] [rbp-70h]
unsigned int v13; // [rsp+1Ch] [rbp-6Ch]
char v14[2]; // [rsp+20h] [rbp-68h] BYREF
unsigned __int16 v15; // [rsp+22h] [rbp-66h]
char v16; // [rsp+29h] [rbp-5Fh]
char v17[4]; // [rsp+40h] [rbp-48h] BYREF
unsigned __int16 v18; // [rsp+44h] [rbp-44h]
int v19; // [rsp+60h] [rbp-28h] BYREF
unsigned __int16 v20; // [rsp+64h] [rbp-24h]
unsigned __int16 v21; // [rsp+66h] [rbp-22h]
unsigned int v22; // [rsp+70h] [rbp-18h]
int v23; // [rsp+74h] [rbp-14h]

if ( argc == 1 )
{
fread(&v19, 1uLL, 0x18uLL, _bss_start);
if ( v19 == -1582119980 )
{
printf("PCAP format v%d.%d, ", v20, v21);
if ( v23 == 1 )
{
v3 = 0;
puts("link layer type: Ethernet.");
goto LABEL_4;
}
puts("unsupported link layer type");
}
else
{
puts("invalid file format");
}
}
else
{
if ( argc == 2 )
{
*(_QWORD *)&argc = argv[1];
argv = (const char **)"-r";
v3 = 1;
if ( !strcmp(*(const char **)&argc, "-r") )
{
while ( 1 )
{
LABEL_4:
while ( 1 )
{
putchar(10);
if ( !v3 )
break;
func11(v9);
func12(v9);
v4 = v10;
if ( v10 > 0x5DCu )
goto LABEL_8;
printf("Old style packet, length = %d\n", v10);
puts("We don't support this packet now");
}
while ( 1 )
{
if ( fread(ptr, 1uLL, 0x10uLL, _bss_start) != 16 )
return 0;
if ( v12 > v22 )
{
v8 = ftell(_bss_start);
printf("wrong packet at 0x%08x\n", v8);
return 0;
}
puts("<<<PCAP packet");
printf(" packet size: %d\n", v12);
printf(" payload size: %d\n", v13);
func11(v9);
func12(v9);
v4 = v10;
if ( v10 <= 0x5DCu )
{
printf("Old style packet, length = %d\n", v10);
puts("We don't support this packet now");
goto LABEL_12;
}
LABEL_8:
if ( v4 == 2048 )
{
func13(v14);
func14(v14);
if ( v16 == 4 )
{
puts("IP packet");
v6 = "Wedon't support this packet now";
LABEL_21:
puts(v6);
func10((unsigned int)v15 - 20, 1LL);
goto LABEL_22;
}
if ( v16 == 6 )
{
func17(v17);
func18(v17);
if ( v12 < (unsigned __int64)v15 + 14 )
func10(v12 - 54, 0LL);
else
func10((unsigned int)v15 - 40, 0LL);
goto LABEL_22;
}
v6 = "Unexpected IP packet";
if ( v16 != 17 )
goto LABEL_21;
func15(v17);
if ( v18 != v15 - 20LL )
__assert_fail("udphead.size == ipv4head.datalen-sizeof(ipv4head)", "wireguppy.c", 0x157u, "main");
func16(v17);
if ( v12 < (unsigned __int64)v15 + 14 )
func10(v12 + v18 - 22 - v15, 0LL);
else
func10((unsigned int)v18 - 8, 0LL);
LABEL_22:
if ( !v3 && v12 > (unsigned __int64)v15 + 14 )
{
puts("pad:");
func10(v12 - 14 - v15, 1LL);
}
goto LABEL_4;
}
v5 = "ARP packet";
if ( v4 == 2054 )
goto LABEL_16;
if ( v4 != 0x86DD )
break;
v5 = "IPv6 packet";
LABEL_16:
puts(v5);
puts("We don't support this packet now");
if ( v3 )
goto LABEL_4;
LABEL_12:
func10(v12 - 14, 1LL);
putchar(10);
}
puts("Unexpected Ethernet packet");
if ( !v3 )
goto LABEL_12;
}
}
}
func19(*(_QWORD *)&argc, argv, envp);
}
return 0;
}

original_code:
int main(int argc, char **argv) {
  int raw_mode = 0;
  struct GlobalHeader ghead;
  if(argc == 1) {
    raw_mode = 0;
  } else if(argc == 2) {
    if(0 != strcmp(argv[1], "-r")) {
      usage();
      return 0;
    }
    raw_mode = 1;
  } else {
    usage();
    return 0;
  }
  if(!raw_mode) {
    fread(&ghead, sizeof(unsigned char), sizeof(struct GlobalHeader), stdin);
    if(ghead.magic != 0xA1B2C3D4) {
      printf("invalid file format\n");
      return 0;
    }
    printf("PCAP format v%d.%d, ", ghead.majorver, ghead.minorver);
    if(ghead.linklayertype != 1) {
      printf("unsupported link layer type\n");
      return 0;
    }
    printf("link layer type: Ethernet.\n");
  }
  while (1) {
    int i;
    struct PacketHeader phead;
    struct EthernetHeader ehead;
    printf("\n");
    if (!raw_mode) {
      if(sizeof(struct PacketHeader) != fread(&phead, sizeof(unsigned char), sizeof(struct PacketHeader), stdin)) break;
      if(phead.packetsize > ghead.snapshotlength) {
 printf("wrong packet at 0x%08x\n", (int)ftell(stdin));
 return 0;
      }
      printf("<<<PCAP packet\n");
      printf("    packet size: %d\n", phead.packetsize);
      printf("    payload size: %d\n", phead.payloadsize);
    }
    get_ether(&ehead);
    print_ether(&ehead);
    if (ehead.length_type <= 1500) {
      printf("Old style packet, length = %d\n", ehead.length_type);
      printf("We don't support this packet now\n");
      if (!raw_mode) {
 dump(phead.packetsize-sizeof(ehead), 1);
      }
    } else if (ehead.length_type == 0x0800) {
      struct IPv4Header ipv4head;
      get_ipv4(&ipv4head);
      print_ipv4(&ipv4head);
      if(ipv4head.protocol == 4) {
 printf("IP packet\n");
 printf("Wedon't support this packet now\n");
 dump(ipv4head.datalen-sizeof(ipv4head), 1);
      } else if(ipv4head.protocol == 6) {
 struct TCPHeader tcphead;
 get_tcp(&tcphead);
 print_tcp(&tcphead);
 if(phead.packetsize >= sizeof(ehead)+ipv4head.datalen) {
   dump(ipv4head.datalen-sizeof(ipv4head)-sizeof(tcphead), 0);
 } else {
   dump((ipv4head.datalen-sizeof(ipv4head)-sizeof(tcphead))-(sizeof(ehead)+ipv4head.datalen-phead.packetsize), 0);
 }
      } else if(ipv4head.protocol == 17) {
 struct UDPHeader udphead;
 get_udp(&udphead);
 ((void) sizeof ((udphead.size == ipv4head.datalen-sizeof(ipv4head)) ? 1 : 0), __extension__ ({ if (udphead.size == ipv4head.datalen-sizeof(ipv4head)) ; else __assert_fail ("udphead.size == ipv4head.datalen-sizeof(ipv4head)", "wireguppy.c", 343, __extension__ __PRETTY_FUNCTION__); }));
 print_udp(&udphead);
 if(phead.packetsize >= sizeof(ehead)+ipv4head.datalen) {
   dump(udphead.size-sizeof(udphead), 0);
 } else {
   dump((udphead.size-sizeof(udphead))-(sizeof(ehead)+ipv4head.datalen-phead.packetsize), 0);
 }
      } else {
 printf("Unexpected IP packet\n");
 dump(ipv4head.datalen-sizeof(ipv4head), 1);
      }
      if(!raw_mode) {
 if(phead.packetsize > sizeof(ehead)+ipv4head.datalen) {
   printf("pad:\n");
   dump(phead.packetsize-sizeof(ehead)-ipv4head.datalen, 1);
 }
      }
    } else if(ehead.length_type == 0x0806) {
      printf("ARP packet\n");
      printf("We don't support this packet now\n");
      if (!raw_mode) {
 dump(phead.packetsize-sizeof(ehead), 1);
      }
    } else if(ehead.length_type == 0x86DD) {
      printf("IPv6 packet\n");
      printf("We don't support this packet now\n");
      if (!raw_mode) {
 dump(phead.packetsize-sizeof(ehead), 1);
      }
    } else {
      printf("Unexpected Ethernet packet\n");
      if (!raw_mode) {
 dump(phead.packetsize-sizeof(ehead), 1);
      }
    }
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: struct GlobalHeader { unsigned int magic; unsigned short majorver; unsigned short minorver; unsigned int timezoneoffset; unsigned int timestamp; unsigned int snapshotlength; unsigned int linklayertype; }

variable_types: i int

variable_types: struct PacketHeader { unsigned int timestamp; unsigned int microsec; unsigned int packetsize; unsigned int payloadsize; }

variable_types: struct EthernetHeader { unsigned char dest[6]; unsigned char src[6]; unsigned short length_type; }

variable_types: struct IPv4Header { unsigned char byte0; unsigned char byte1; unsigned short datalen; unsigned short id; unsigned short word0; unsigned char TTL; unsigned char protocol; unsigned short headchecksum; unsigned char src[4]; unsigned char dest[4]; }

variable_types: struct TCPHeader { unsigned short src; unsigned short dest; unsigned int seqnum; unsigned int acknum; unsigned char byte0; unsigned char byte1; unsigned short winsize; unsigned short checksum; unsigned short urgpoint; }

variable_types: struct UDPHeader { unsigned short src; unsigned short dest; unsigned short size; unsigned short checksum; }

return_type: int


usage

decompiled_code:
int usage()
{
puts("Usage: ./wireguppy < input.pcap");
return puts(" or ./wireguppy -r < input.pcap for raw file");
}

canonical_decompiled_code:
int func19()
{
puts("Usage: ./wireguppy < input.pcap");
return puts(" or ./wireguppy -r < input.pcap for raw file");
}

original_code:
void usage() {
  printf("Usage: ./wireguppy < input.pcap\n");
  printf("    or ./wireguppy -r < input.pcap for raw file\n");
}


repo: deuill/spooky-maze

decompiled_code:
void __noreturn game_usage()
{
puts(
"Usage: spooky-maze [OPTION]...\n"
"Options:\n"
" -d, --datadir\t\tDirectory where data files reside.\n"
" -f, --fullscreen\tStart game in fullscreen.\n"
" -s, --size\t\tSize of game screen (example usage: '-s 800x600').\n"
" -h, --help\t\tDisplay this text.");
exit(1);
}

canonical_decompiled_code:
void __noreturn func0()
{
puts(
"Usage: spooky-maze [OPTION]...\n"
"Options:\n"
" -d, --datadir\t\tDirectory where data files reside.\n"
" -f, --fullscreen\tStart game in fullscreen.\n"
" -s, --size\t\tSize of game screen (example usage: '-s 800x600').\n"
" -h, --help\t\tDisplay this text.");
exit(1);
}

original_code:
static void game_usage(void)
{
 printf( "Usage: spooky-maze [OPTION]...\n"
  "Options:\n"
  " -d, --datadir\t\tDirectory where data files reside.\n"
  " -f, --fullscreen\tStart game in fullscreen.\n"
  " -s, --size\t\tSize of game screen (example usage: '-s 800x600').\n"
  " -h, --help\t\tDisplay this text.\n");
 exit(1);
}

canonical_original_code:
static void game_usage()
{
 printf( "Usage: spooky-maze [OPTION]...\n"
  "Options:\n"
  " -d, --datadir\t\tDirectory where data files reside.\n"
  " -f, --fullscreen\tStart game in fullscreen.\n"
  " -s, --size\t\tSize of game screen (example usage: '-s 800x600').\n"
  " -h, --help\t\tDisplay this text.\n");
 exit(1);
}


decompiled_code:
void __fastcall __noreturn game_terminate(int status)
{
const char *v1; // rax

if ( status )
{
v1 = (const char *)SDL_GetError();
fprintf(stderr, "Error: %s\nExiting...\n", v1);
}
SDL_Quit();
exit(status);
}

canonical_decompiled_code:
void __fastcall __noreturn func1(int status)
{
const char *v1; // rax

if ( status )
{
v1 = (const char *)SDL_GetError();
fprintf(stderr, "Error: %s\nExiting...\n", v1);
}
SDL_Quit();
exit(status);
}

original_code:
int game_terminate(int code)
{
 if (code != 0)
  fprintf(stderr, "Error: %s\nExiting...\n", SDL_GetError());
 SDL_Quit();
 exit(code);
}

variable_types: code int


repo: devanlai/derp-robot

decompiled_code:
__int64 __fastcall rgb_to_pixel(unsigned __int8 a1, unsigned __int8 a2, unsigned __int8 a3, int a4)
{
return (a4 << 24) | (a1 << 16) | a3 | (a2 << 8);
}

canonical_decompiled_code:
__int64 __fastcall func11(unsigned __int8 a1, unsigned __int8 a2, unsigned __int8 a3, int a4)
{
return (a4 << 24) | (a1 << 16) | a3 | (a2 << 8);
}

original_code:
ChumbyPixel rgb_to_pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) {
 return (alpha << 24) | (red << 16) | (green << 8) | blue;
}

canonical_original_code:
unsigned int rgb_to_pixel(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha) {
 return (alpha << 24) | (red << 16) | (green << 8) | blue;
}

variable_types:
red
unsigned char

variable_types:
green
unsigned char

variable_types:
blue
unsigned char

variable_types:
alpha
unsigned char

return_type: unsigned int


decompiled_code:
void *__fastcall map_framebuffer(unsigned int a1)
{
unsigned __int64 v1; // rdi
int v2; // er8
void *result; // rax

if ( a1 > 1 )
return 0LL;
v1 = 16LL * a1;
v2 = fb_map[v1 / 4];
if ( v2 < 0 )
return 0LL;
result = (void *)qword_4040E8[v1 / 8];
if ( !result )
{
result = mmap(0LL, 0x1D4C00uLL, 2, 16385, v2, 0LL);
if ( result != (void *)-1LL )
{
*(_QWORD *)&fb_map[v1 / 4 + 2] = result;
return result;
}
return 0LL;
}
return result;
}

canonical_decompiled_code:
void *__fastcall func12(unsigned int a1)
{
unsigned __int64 v1; // rdi
int v2; // er8
void *result; // rax

if ( a1 > 1 )
return 0LL;
v1 = 16LL * a1;
v2 = fb_map[v1 / 4];
if ( v2 < 0 )
return 0LL;
result = (void *)qword_4040E8[v1 / 8];
if ( !result )
{
result = mmap(0LL, 0x1D4C00uLL, 2, 16385, v2, 0LL);
if ( result != (void *)-1LL )
{
*(_QWORD *)&fb_map[v1 / 4 + 2] = result;
return result;
}
return 0LL;
}
return result;
}

original_code:
ChumbyPixel* map_framebuffer(FBNum fb_no) {
 if (fb_no < 0 || fb_no >= 2) {
  return ((void *)0);
 }
 int fd = _fb_map[fb_no].fd;
 if (fd < 0) {
  return ((void *)0);
 }
 if (_fb_map[fb_no].ptr == ((void *)0)) {
  ChumbyPixel* data = mmap(((void *)0), (800*600*sizeof(ChumbyPixel)), 0x2, 0x01 | 0x04000, fd, 0);
  if (data == ((void *) -1)) {
   return ((void *)0);
  }
  _fb_map[fb_no].ptr = data;
 }
 return _fb_map[fb_no].ptr;
}

canonical_original_code:
unsigned int *map_framebuffer(enum FBNum fb_no) {
 if (fb_no < 0 || fb_no >= 2) {
  return ((void *)0);
 }
 int fd = _fb_map[fb_no].fd;
 if (fd < 0) {
  return ((void *)0);
 }
 if (_fb_map[fb_no].ptr == ((void *)0)) {
  unsigned int *data = mmap(((void *)0), (800*600*sizeof(ChumbyPixel)), 0x2, 0x01 | 0x04000, fd, 0);
  if (data == ((void *) -1)) {
   return ((void *)0);
  }
  _fb_map[fb_no].ptr = data;
 }
 return _fb_map[fb_no].ptr;
}

variable_types: fd int

variable_types:
data
unsigned int *

return_type: unsigned int *


decompiled_code:
int __fastcall unmap_framebuffer(void *a1)
{
int result; // eax

if ( a1 )
result = munmap(a1, 0x1D4C00uLL);
return result;
}

canonical_decompiled_code:
int __fastcall func13(void *a1)
{
int result; // eax

if ( a1 )
result = munmap(a1, 0x1D4C00uLL);
return result;
}

original_code:
void unmap_framebuffer(ChumbyPixel* buffer) {
 if (buffer == ((void *)0)) {
  return;
 }
 munmap(buffer, (800*600*sizeof(ChumbyPixel)));
}

canonical_original_code:
void unmap_framebuffer(unsigned int *buffer) {
 if (buffer == ((void *)0)) {
  return;
 }
 munmap(buffer, (800*600*sizeof(ChumbyPixel)));
}

variable_types:
buffer
unsigned int *


decompiled_code:
int __fastcall open_framebuffer(unsigned int a1)
{
int result; // eax

if ( a1 > 1 )
return -1;
result = fb_map[4 * a1];
if ( result < 0 )
{
if ( a1 == 1 )
result = open("/dev/fb1", 2);
else
result = open("/dev/fb0", 2);
if ( result >= 0 )
fb_map[4 * a1] = result;
}
return result;
}

canonical_decompiled_code:
int __fastcall func14(unsigned int a1)
{
int result; // eax

if ( a1 > 1 )
return -1;
result = fb_map[4 * a1];
if ( result < 0 )
{
if ( a1 == 1 )
result = open("/dev/fb1", 2);
else
result = open("/dev/fb0", 2);
if ( result >= 0 )
fb_map[4 * a1] = result;
}
return result;
}

original_code:
int open_framebuffer(FBNum fb_no) {
 if (fb_no < 0 || fb_no >= 2) {
  return -1;
 }
 int fd = _fb_map[fb_no].fd;
 if (fd < 0) {
  switch (fb_no) {
  case FB0:
   fd = open("/dev/fb0", 02);
   break;
  case FB1:
   fd = open("/dev/fb1", 02);
   break;
  default:
   return -1;
  }
  if (fd < 0) {
   return fd;
  } else {
   _fb_map[fb_no].fd = fd;
   return fd;
  }
 } else {
  return fd;
 }
}

canonical_original_code:
int open_framebuffer(enum FBNum fb_no) {
 if (fb_no < 0 || fb_no >= 2) {
  return -1;
 }
 int fd = _fb_map[fb_no].fd;
 if (fd < 0) {
  switch (fb_no) {
  case FB0:
   fd = open("/dev/fb0", 02);
   break;
  case FB1:
   fd = open("/dev/fb1", 02);
   break;
  default:
   return -1;
  }
  if (fd < 0) {
   return fd;
  } else {
   _fb_map[fb_no].fd = fd;
   return fd;
  }
 } else {
  return fd;
 }
}


decompiled_code:
int __fastcall close_framebuffer(unsigned int a1)
{
__int64 v1; // rbx
int v2; // edi
int result; // eax

if ( a1 <= 1 )
{
v1 = 4LL * a1;
v2 = fb_map[v1];
if ( v2 >= 0 )
{
result = close(v2);
fb_map[v1] = -1;
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func15(unsigned int a1)
{
__int64 v1; // rbx
int v2; // edi
int result; // eax

if ( a1 <= 1 )
{
v1 = 4LL * a1;
v2 = fb_map[v1];
if ( v2 >= 0 )
{
result = close(v2);
fb_map[v1] = -1;
}
}
return result;
}

original_code:
void close_framebuffer(FBNum fb_no) {
 if (fb_no < 0 || fb_no >= 2) {
  return;
 }
 int fd = _fb_map[fb_no].fd;
 if (fd >= 0) {
  close(fd);
  _fb_map[fb_no].fd = -1;
 }
}

canonical_original_code:
void close_framebuffer(enum FBNum fb_no) {
 if (fb_no < 0 || fb_no >= 2) {
  return;
 }
 int fd = _fb_map[fb_no].fd;
 if (fd >= 0) {
  close(fd);
  _fb_map[fb_no].fd = -1;
 }
}


decompiled_code:
void *__fastcall init_framebuffer(unsigned int a1)
{
void *result; // rax

if ( open_framebuffer(a1) < 0 )
result = 0LL;
else
result = map_framebuffer(a1);
return result;
}

canonical_decompiled_code:
void *__fastcall func16(unsigned int a1)
{
void *result; // rax

if ( func14(a1) < 0 )
result = 0LL;
else
result = func12(a1);
return result;
}

original_code:
ChumbyPixel* init_framebuffer(FBNum fb_no) {
 int fd = open_framebuffer(fb_no);
 if (fd < 0) {
  return ((void *)0);
 }
 return map_framebuffer(fb_no);
}

canonical_original_code:
unsigned int *init_framebuffer(enum FBNum fb_no) {
 int fd = open_framebuffer(fb_no);
 if (fd < 0) {
  return ((void *)0);
 }
 return map_framebuffer(fb_no);
}


decompiled_code:
int __fastcall free_framebuffer(unsigned int a1)
{
int result; // eax

if ( a1 <= 1 )
{
unmap_framebuffer((void *)qword_4040E8[2 * a1]);
result = close_framebuffer(a1);
}
return result;
}

canonical_decompiled_code:
int __fastcall func17(unsigned int a1)
{
int result; // eax

if ( a1 <= 1 )
{
func13((void *)qword_4040E8[2 * a1]);
result = func15(a1);
}
return result;
}

original_code:
void free_framebuffer(FBNum fb_no) {
 if (fb_no < 0 || fb_no >= 2) {
  return;
 }
 unmap_framebuffer(_fb_map[fb_no].ptr);
 close_framebuffer(fb_no);
}

canonical_original_code:
void free_framebuffer(enum FBNum fb_no) {
 if (fb_no < 0 || fb_no >= 2) {
  return;
 }
 unmap_framebuffer(_fb_map[fb_no].ptr);
 close_framebuffer(fb_no);
}


repo: deveah/etraom

decompiled_code:
const char ***__fastcall alloc_entity(__int64 a1)
{
const char ***v1; // r12
__int64 v2; // rax
__int64 v3; // rax
const char **v4; // rbp
const char **v5; // r13
_QWORD *v6; // rax
_QWORD *v7; // r14
_QWORD *v8; // rbx
_DWORD *v9; // rax
_DWORD *v10; // rdx

v1 = (const char ***)malloc(0x68uLL);
v2 = bufcpy(a1);
*((_DWORD *)v1 + 24) = 0;
*v1 = (const char **)v2;
v1[1] = (const char **)0x8000000007ALL;
v1[6] = (const char **)malloc(0x50uLL);
v3 = alloc_list();
v4 = v1[6];
v1[2] = 0LL;
v1[7] = (const char **)v3;
v1[9] = 0LL;
v5 = v4 + 10;
v1[8] = 0LL;
v1[10] = 0LL;
v1[11] = 0LL;
do
{
v6 = malloc(0x280uLL);
*v4 = (const char *)v6;
v7 = v6;
v8 = v6 + 80;
do
{
v9 = malloc(0x54uLL);
*v7 = v9;
v10 = v9 + 21;
do
*v9++ = 0;
while ( v10 != v9 );
++v7;
}
while ( v8 != v7 );
++v4;
}
while ( v4 != v5 );
log_add("[alloc_entity] Allocated entity 0x%08x('%s').\n", v1, **v1);
return v1;
}

canonical_decompiled_code:
const char ***__fastcall func0(__int64 a1)
{
const char ***v1; // r12
__int64 v2; // rax
__int64 v3; // rax
const char **v4; // rbp
const char **v5; // r13
_QWORD *v6; // rax
_QWORD *v7; // r14
_QWORD *v8; // rbx
_DWORD *v9; // rax
_DWORD *v10; // rdx

v1 = (const char ***)malloc(0x68uLL);
v2 = bufcpy(a1);
*((_DWORD *)v1 + 24) = 0;
*v1 = (const char **)v2;
v1[1] = (const char **)0x8000000007ALL;
v1[6] = (const char **)malloc(0x50uLL);
v3 = alloc_list();
v4 = v1[6];
v1[2] = 0LL;
v1[7] = (const char **)v3;
v1[9] = 0LL;
v5 = v4 + 10;
v1[8] = 0LL;
v1[10] = 0LL;
v1[11] = 0LL;
do
{
v6 = malloc(0x280uLL);
*v4 = (const char *)v6;
v7 = v6;
v8 = v6 + 80;
do
{
v9 = malloc(0x54uLL);
*v7 = v9;
v10 = v9 + 21;
do
*v9++ = 0;
while ( v10 != v9 );
++v7;
}
while ( v8 != v7 );
++v4;
}
while ( v4 != v5 );
log_add("[alloc_entity] Allocated entity 0x%08x('%s').\n", v1, **v1);
return v1;
}

original_code:
entity_t *alloc_entity( buf_t *name )
{
 int i, j, k;
 entity_t *e = malloc( sizeof(entity_t) );
 e->name = bufcpy( name );
 e->face = 'z';
 e->color = (((chtype)(((8))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
 e->flags = 0;
 e->lightmap = (float***) malloc( sizeof(float**) * 10 );
 e->inventory = alloc_list();
 e->agility = 0;
 e->ap = 0;
 e->in_hand = ((void *)0);
 e->worn = ((void *)0);
 e->natural = ((void *)0);
 e->ai = ((void *)0);
 for( i = 0; i < 10; i++ )
 {
  e->lightmap[i] = (float**) malloc( sizeof(float*) * 80 );
  for( j = 0; j < 80; j++ )
  {
   e->lightmap[i][j] = (float*) malloc( sizeof(float) * 21 );
   for( k = 0; k < 21; k++ )
   {
    e->lightmap[i][j][k] = 0.0f;
   }
  }
 }
 log_add( "[alloc_entity] Allocated entity 0x%08x('%s').\n", e,
  e->name->data );
 return e;
}

canonical_original_code:
struct entity_t *alloc_entity(struct buf_t *name)
{
 int i; int j; int k;
 struct entity_t *e = malloc( sizeof(entity_t) );
 e->name = bufcpy( name );
 e->face = 'z';
 e->color = (((chtype)(((8))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
 e->flags = 0;
 e->lightmap = (float ***) malloc( sizeof(float **) * 10 );
 e->inventory = alloc_list();
 e->agility = 0;
 e->ap = 0;
 e->in_hand = ((void *)0);
 e->worn = ((void *)0);
 e->natural = ((void *)0);
 e->ai = ((void *)0);
 for( i = 0; i < 10; i++ )
 {
  e->lightmap[i] = (float **) malloc( sizeof(float *) * 80 );
  for( j = 0; j < 80; j++ )
  {
   e->lightmap[i][j] = (float *) malloc( sizeof(float) * 21 );
   for( k = 0; k < 21; k++ )
   {
    e->lightmap[i][j][k] = 0.0f;
   }
  }
 }
 log_add( "[alloc_entity] Allocated entity 0x%08x('%s').\n", e,
  e->name->data );
 return e;
}

variable_types:
name
struct buf_t *

variable_types: j int

variable_types: k int

variable_types: struct entity_t { struct buf_t { char *data; int length; } *name; int face; int ap; int agility; int hp; int x; float ***lightmap; struct list_t { struct _list_element { void *data; struct _list_element *next; } *head; int length; } *inventory; struct item_t { struct buf_t *name; int face; int quantity; float quality; int type; void *specific; int place; int x; int flags; } *worn; struct weapon_t { int type; int accuracy; int min_damage; struct item_t *ammo_type; int ammo_loaded; char *attack_name; } *natural; struct ai_t { int type; int lx; int flags; } *ai; int flags; } *

user_defined_types: struct entity_t { struct buf_t *name; int face; int ap; int agility; int hp; int x; float ***lightmap; struct list_t *inventory; struct item_t *worn; struct weapon_t *natural; struct ai_t *ai; int flags; }

user_defined_types: struct list_t { struct _list_element *head; int length; }


decompiled_code:
__int64 __fastcall free_entity(void *ptr)
{
char *v2; // rdi
__int64 i; // rbp
char *v4; // r8
__int64 j; // rbx
void *v6; // rdi
__int64 *v7; // rdi
__int64 v8; // rbx
ITEM *v9; // rdi
ITEM *v10; // rdi
void *v11; // rdi
__int64 result; // rax

if ( ptr )
{
v2 = (char *)*((_QWORD *)ptr + 6);
if ( v2 )
{
for ( i = 0LL; i != 80; i += 8LL )
{
while ( 1 )
{
v4 = *(char **)&v2[i];
if ( v4 )
break;
i += 8LL;
if ( i == 80 )
goto LABEL_11;
}
for ( j = 0LL; j != 640; j += 8LL )
{
v6 = *(void **)&v4[j];
if ( v6 )
{
free(v6);
v4 = *(char **)(*((_QWORD *)ptr + 6) + i);
}
}
free(v4);
v2 = (char *)*((_QWORD *)ptr + 6);
}
LABEL_11:
free(v2);
}
v7 = (__int64 *)*((_QWORD *)ptr + 7);
if ( v7 )
{
v8 = *v7;
if ( *v7 )
{
do
{
free_item(*(ITEM **)v8);
v8 = *(_QWORD *)(v8 + 8);
}
while ( v8 );
v7 = (__int64 *)*((_QWORD *)ptr + 7);
}
free_list(v7);
}
v9 = (ITEM *)*((_QWORD *)ptr + 9);
if ( v9 )
free_item(v9);
v10 = (ITEM *)*((_QWORD *)ptr + 8);
if ( v10 )
free_item(v10);
v11 = (void *)*((_QWORD *)ptr + 10);
if ( v11 )
free(v11);
if ( *((_QWORD *)ptr + 11) )
free_ai();
bufdestroy(*(_QWORD *)ptr);
free(ptr);
result = log_add("[free_entity] Freed entity 0x%08x.\n", ptr);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(void *ptr)
{
char *v2; // rdi
__int64 i; // rbp
char *v4; // r8
__int64 j; // rbx
void *v6; // rdi
__int64 *v7; // rdi
__int64 v8; // rbx
ITEM *v9; // rdi
ITEM *v10; // rdi
void *v11; // rdi
__int64 result; // rax

if ( ptr )
{
v2 = (char *)*((_QWORD *)ptr + 6);
if ( v2 )
{
for ( i = 0LL; i != 80; i += 8LL )
{
while ( 1 )
{
v4 = *(char **)&v2[i];
if ( v4 )
break;
i += 8LL;
if ( i == 80 )
goto LABEL_11;
}
for ( j = 0LL; j != 640; j += 8LL )
{
v6 = *(void **)&v4[j];
if ( v6 )
{
free(v6);
v4 = *(char **)(*((_QWORD *)ptr + 6) + i);
}
}
free(v4);
v2 = (char *)*((_QWORD *)ptr + 6);
}
LABEL_11:
free(v2);
}
v7 = (__int64 *)*((_QWORD *)ptr + 7);
if ( v7 )
{
v8 = *v7;
if ( *v7 )
{
do
{
free_item(*(ITEM **)v8);
v8 = *(_QWORD *)(v8 + 8);
}
while ( v8 );
v7 = (__int64 *)*((_QWORD *)ptr + 7);
}
free_list(v7);
}
v9 = (ITEM *)*((_QWORD *)ptr + 9);
if ( v9 )
free_item(v9);
v10 = (ITEM *)*((_QWORD *)ptr + 8);
if ( v10 )
free_item(v10);
v11 = (void *)*((_QWORD *)ptr + 10);
if ( v11 )
free(v11);
if ( *((_QWORD *)ptr + 11) )
free_ai();
bufdestroy(*(_QWORD *)ptr);
free(ptr);
result = log_add("[free_entity] Freed entity 0x%08x.\n", ptr);
}
return result;
}

original_code:
void free_entity( entity_t *e )
{
 int i, j;
 if( e )
 {
  if( e->lightmap )
  {
   for( i = 0; i < 10; i++ )
   {
    if( e->lightmap[i] )
    {
     for( j = 0; j < 80; j++ )
     {
      if( e->lightmap[i][j] )
       free( e->lightmap[i][j] );
     }
     free( e->lightmap[i] );
    }
   }
   free( e->lightmap );
  }
  if( e->inventory )
  {
   list_element *el = e->inventory->head;
   while( el )
   {
    free_item( (item_t*)el->data );
    el = el->next;
   }
   free_list( e->inventory );
  }
  if( e->in_hand )
   free_item( e->in_hand );
  if( e->worn )
   free_item( e->worn );
  if( e->natural )
   free( e->natural );
  if( e->ai )
   free_ai( e->ai );
  bufdestroy( e->name );
  free( e );
  log_add( "[free_entity] Freed entity 0x%08x.\n", e );
 }
}

canonical_original_code:
void free_entity(struct entity_t *e)
{
 int i; int j;
 if( e )
 {
  if( e->lightmap )
  {
   for( i = 0; i < 10; i++ )
   {
    if( e->lightmap[i] )
    {
     for( j = 0; j < 80; j++ )
     {
      if( e->lightmap[i][j] )
       free( e->lightmap[i][j] );
     }
     free( e->lightmap[i] );
    }
   }
   free( e->lightmap );
  }
  if( e->inventory )
  {
   struct _list_element *el = e->inventory->head;
   while( el )
   {
    free_item( (struct item_t *)el->data );
    el = el->next;
   }
   free_list( e->inventory );
  }
  if( e->in_hand )
   free_item( e->in_hand );
  if( e->worn )
   free_item( e->worn );
  if( e->natural )
   free( e->natural );
  if( e->ai )
   free_ai( e->ai );
  bufdestroy( e->name );
  free( e );
  log_add( "[free_entity] Freed entity 0x%08x.\n", e );
 }
}

variable_types: i int

variable_types: struct _list_element { void *data; struct _list_element *next; } *

user_defined_types: struct item_t { struct buf_t *name; int face; int quantity; float quality; int type; void *specific; int place; int x; int flags; }

user_defined_types: struct buf_t { char *data; int length; }

user_defined_types: struct weapon_t { int type; int accuracy; int min_damage; struct item_t *ammo_type; int ammo_loaded; char *attack_name; }

user_defined_types: struct ai_t { int type; int lx; int flags; }


original_code:
entity_t *clone_entity( entity_t *e )
{
 if( !e )
  return ((void *)0);
 entity_t *ce = alloc_entity( e->name );
 ce->face = e->face;
 ce->color = e->color;
 ce->ap = e->ap;
 ce->agility = e->agility;
 ce->hp = e->hp;
 ce->max_hp = e->max_hp;
 ce->x = e->x;
 ce->y = e->y;
 ce->z = e->z;
 ce->worn = clone_item( e->worn );
 ce->in_hand = clone_item( e->in_hand );
 ce->flags = e->flags;
 return ce;
}

canonical_original_code:
struct entity_t *clone_entity(struct entity_t *e)
{
 if( !e )
  return ((void *)0);
 struct entity_t *ce = alloc_entity( e->name );
 ce->face = e->face;
 ce->color = e->color;
 ce->ap = e->ap;
 ce->agility = e->agility;
 ce->hp = e->hp;
 ce->max_hp = e->max_hp;
 ce->x = e->x;
 ce->y = e->y;
 ce->z = e->z;
 ce->worn = clone_item( e->worn );
 ce->in_hand = clone_item( e->in_hand );
 ce->flags = e->flags;
 return ce;
}

variable_types:
e
struct entity_t *

return_type: struct entity_t { struct buf_t { char *data; int length; } *name; int face; int ap; int agility; int hp; int x; float ***lightmap; struct list_t { struct _list_element { void *data; struct _list_element *next; } *head; int length; } *inventory; struct item_t { struct buf_t *name; int face; int quantity; float quality; int type; void *specific; int place; int x; int flags; } *worn; struct weapon_t { int type; int accuracy; int min_damage; struct item_t *ammo_type; int ammo_loaded; char *attack_name; } *natural; struct ai_t { int type; int lx; int flags; } *ai; int flags; } *


decompiled_code:
__int64 free_entities()
{
__int64 result; // rax
__int64 i; // rbx

result = entity_list;
for ( i = *(_QWORD *)entity_list; i; i = *(_QWORD *)(i + 8) )
result = free_entity(*(void **)i);
return result;
}

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

result = entity_list;
for ( i = *(_QWORD *)entity_list; i; i = *(_QWORD *)(i + 8) )
result = func1(*(void **)i);
return result;
}

original_code:
void free_entities( void )
{
 list_element *e = entity_list->head;
 while( e )
 {
  free_entity( (entity_t*)e->data );
  e = e->next;
 }
}

canonical_original_code:
void free_entities()
{
 struct _list_element *e = entity_list->head;
 while( e )
 {
  free_entity( (struct entity_t *)e->data );
  e = e->next;
 }
}

user_defined_types: struct _list_element { void *data; struct _list_element *next; }


decompiled_code:
__int64 __fastcall entity_act(__int64 a1)
{
__int64 result; // rax
unsigned int v2; // eax
bool v3; // zf

result = (unsigned int)(*(_DWORD *)(a1 + 16) + *(_DWORD *)(a1 + 20));
*(_DWORD *)(a1 + 16) = result;
while ( (int)result > 0 )
{
while ( 1 )
{
log_add("[entity_act] Act: 0x%08x('%s').\n", a1, **(const char ***)a1);
log_add(
"[entity_act]\tentity has agility %i and ap %i.\n",
*(unsigned int *)(a1 + 20),
*(unsigned int *)(a1 + 16));
do_fov(a1, 5LL);
if ( (*(_BYTE *)(a1 + 96) & 1) == 0 )
break;
draw_main_screen();
v2 = wgetch(stdscr);
if ( (unsigned int)handle_key(v2) == 1 )
{
*(_DWORD *)(a1 + 16) -= 10;
++player_turns;
}
result = running;
if ( !running )
return result;
result = *(unsigned int *)(a1 + 16);
LABEL_7:
if ( (int)result <= 0 )
return result;
}
v3 = (unsigned int)run_ai(a1) == 0;
result = *(unsigned int *)(a1 + 16);
if ( v3 )
goto LABEL_7;
result = (unsigned int)(result - 10);
*(_DWORD *)(a1 + 16) = result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
__int64 result; // rax
unsigned int v2; // eax
bool v3; // zf

result = (unsigned int)(*(_DWORD *)(a1 + 16) + *(_DWORD *)(a1 + 20));
*(_DWORD *)(a1 + 16) = result;
while ( (int)result > 0 )
{
while ( 1 )
{
log_add("[entity_act] Act: 0x%08x('%s').\n", a1, **(const char ***)a1);
log_add(
"[entity_act]\tentity has agility %i and ap %i.\n",
*(unsigned int *)(a1 + 20),
*(unsigned int *)(a1 + 16));
do_fov(a1, 5LL);
if ( (*(_BYTE *)(a1 + 96) & 1) == 0 )
break;
draw_main_screen();
v2 = wgetch(stdscr);
if ( (unsigned int)handle_key(v2) == 1 )
{
*(_DWORD *)(a1 + 16) -= 10;
++player_turns;
}
result = running;
if ( !running )
return result;
result = *(unsigned int *)(a1 + 16);
LABEL_7:
if ( (int)result <= 0 )
return result;
}
v3 = (unsigned int)run_ai(a1) == 0;
result = *(unsigned int *)(a1 + 16);
if ( v3 )
goto LABEL_7;
result = (unsigned int)(result - 10);
*(_DWORD *)(a1 + 16) = result;
}
return result;
}

original_code:
void entity_act( entity_t *e )
{
 int key;
 e->ap += e->agility;
 while( e->ap > 0 )
 {
  log_add( "[entity_act] Act: 0x%08x('%s').\n", e, e->name->data );
  log_add( "[entity_act]\tentity has agility %i and ap %i.\n", e->agility, e->ap );
  do_fov( e, 5 );
  if( e->flags & (1<<0) )
  {
   draw_main_screen();
   key = wgetch(stdscr);
   if( handle_key( key ) == 1 )
   {
    e->ap -= 10;
    player_turns++;
   }
   if( !running )
    return;
  }
  else
  {
   if( run_ai( e ) )
    e->ap -= 10;
  }
 }
}

canonical_original_code:
void entity_act(struct entity_t *e)
{
 int key;
 e->ap += e->agility;
 while( e->ap > 0 )
 {
  log_add( "[entity_act] Act: 0x%08x('%s').\n", e, e->name->data );
  log_add( "[entity_act]\tentity has agility %i and ap %i.\n", e->agility, e->ap );
  do_fov( e, 5 );
  if( e->flags & (1<<0) )
  {
   draw_main_screen();
   key = wgetch(stdscr);
   if( handle_key( key ) == 1 )
   {
    e->ap -= 10;
    player_turns++;
   }
   if( !running )
    return;
  }
  else
  {
   if( run_ai( e ) )
    e->ap -= 10;
  }
 }
}

variable_types: key int


decompiled_code:
int __fastcall entity_die(void *ptr)
{
__int64 v2; // r12
__int64 v3; // r13
__int64 v4; // r12
int v5; // eax
__int64 v6; // rdi
int v7; // eax
int v8; // eax
int v9; // eax
unsigned int v10; // eax
int result; // eax

if ( (void *)player == ptr )
{
wclear(stdscr);
mvprintw(0, 0, "You die. Press any key to exit.");
running = 0;
result = wgetch(stdscr);
}
else
{
v2 = bufprintf("The %s dies!", **(const char ***)ptr);
push_message(v2);
bufdestroy(v2);
v3 = bufprintf("%s corpse", **(const char ***)ptr);
v4 = alloc_item(v3);
bufdestroy(v3);
v5 = *((_DWORD *)ptr + 3);
v6 = item_list;
*(_DWORD *)(v4 + 8) = 37;
*(_DWORD *)(v4 + 12) = v5;
*(_QWORD *)(v4 + 16) = 0x3F80000000000001LL;
v7 = *((_DWORD *)ptr + 8);
*(_DWORD *)(v4 + 24) = 4;
*(_DWORD *)(v4 + 44) = v7;
v8 = *((_DWORD *)ptr + 9);
*(_DWORD *)(v4 + 40) = 2;
*(_DWORD *)(v4 + 48) = v8;
v9 = *((_DWORD *)ptr + 10);
*(_DWORD *)(v4 + 56) = 3;
*(_DWORD *)(v4 + 52) = v9;
list_add_tail(v6, v4);
log_add("[entity_die] Entity 0x%08x (%s) has died.\n", ptr, **(const char ***)ptr);
v10 = list_find(entity_list, ptr);
list_remove_index(entity_list, v10);
result = free_entity(ptr);
}
return result;
}

canonical_decompiled_code:
int __fastcall func5(void *ptr)
{
__int64 v2; // r12
__int64 v3; // r13
__int64 v4; // r12
int v5; // eax
__int64 v6; // rdi
int v7; // eax
int v8; // eax
int v9; // eax
unsigned int v10; // eax
int result; // eax

if ( (void *)player == ptr )
{
wclear(stdscr);
mvprintw(0, 0, "You die. Press any key to exit.");
running = 0;
result = wgetch(stdscr);
}
else
{
v2 = bufprintf("The %s dies!", **(const char ***)ptr);
push_message(v2);
bufdestroy(v2);
v3 = bufprintf("%s corpse", **(const char ***)ptr);
v4 = alloc_item(v3);
bufdestroy(v3);
v5 = *((_DWORD *)ptr + 3);
v6 = item_list;
*(_DWORD *)(v4 + 8) = 37;
*(_DWORD *)(v4 + 12) = v5;
*(_QWORD *)(v4 + 16) = 0x3F80000000000001LL;
v7 = *((_DWORD *)ptr + 8);
*(_DWORD *)(v4 + 24) = 4;
*(_DWORD *)(v4 + 44) = v7;
v8 = *((_DWORD *)ptr + 9);
*(_DWORD *)(v4 + 40) = 2;
*(_DWORD *)(v4 + 48) = v8;
v9 = *((_DWORD *)ptr + 10);
*(_DWORD *)(v4 + 56) = 3;
*(_DWORD *)(v4 + 52) = v9;
list_add_tail(v6, v4);
log_add("[entity_die] Entity 0x%08x (%s) has died.\n", ptr, **(const char ***)ptr);
v10 = list_find(entity_list, ptr);
list_remove_index(entity_list, v10);
result = func1(ptr);
}
return result;
}

original_code:
void entity_die( entity_t *e )
{
 if( e == player )
 {
  wclear(stdscr);
  mvprintw( 0, 0, "You die. Press any key to exit." );
  running = 0;
  wgetch(stdscr);
  return;
 }
 buf_t *msg = bufprintf( "The %s dies!", e->name->data );
 push_message( msg );
 bufdestroy( msg );
 buf_t *b = bufprintf( "%s corpse", e->name->data );
 item_t *c = alloc_item( b );
 bufdestroy( b );
 c->face = '%';
 c->color = e->color;
 c->quantity = 1;
 c->quality = 1.0f;
 c->type = ITEMTYPE_JUNK;
 c->place = ITEMPLACE_DUNGEON;
 c->x = e->x;
 c->y = e->y;
 c->z = e->z;
 c->flags = (1<<1) | (1<<0);
 list_add_tail( item_list, (void*)c );
 log_add( "[entity_die] Entity 0x%08x (%s) has died.\n", e, e->name->data );
 int i = list_find( entity_list, (void*)e );
 list_remove_index( entity_list, i );
 free_entity( e );
}

canonical_original_code:
void entity_die(struct entity_t *e)
{
 if( e == player )
 {
  wclear(stdscr);
  mvprintw( 0, 0, "You die. Press any key to exit." );
  running = 0;
  wgetch(stdscr);
  return;
 }
 struct buf_t *msg = bufprintf( "The %s dies!", e->name->data );
 push_message( msg );
 bufdestroy( msg );
 struct buf_t *b = bufprintf( "%s corpse", e->name->data );
 struct item_t *c = alloc_item( b );
 bufdestroy( b );
 c->face = '%';
 c->color = e->color;
 c->quantity = 1;
 c->quality = 1.0f;
 c->type = ITEMTYPE_JUNK;
 c->place = ITEMPLACE_DUNGEON;
 c->x = e->x;
 c->y = e->y;
 c->z = e->z;
 c->flags = (1<<1) | (1<<0);
 list_add_tail( item_list, (void *)c );
 log_add( "[entity_die] Entity 0x%08x (%s) has died.\n", e, e->name->data );
 int i = list_find( entity_list, (void*)e );
 list_remove_index( entity_list, i );
 free_entity( e );
}

variable_types: struct item_t { struct buf_t { char *data; int length; } *name; int face; int quantity; float quality; int type; void *specific; int place; int x; int flags; } *


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
init_game(argc, argv, envp);
game_loop();
terminate_game();
return 0;
}

original_code:
int main( int argc, char **argv )
{
 init_game( argc, argv );
 game_loop();
 terminate_game();
 return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
 init_game( argc, argv );
 game_loop();
 terminate_game();
 return 0;
}

variable_types: argc int

variable_types:
argv
char **


decompiled_code:
void __fastcall free_item(_QWORD *a1)
{
_QWORD *v2; // rdi

if ( a1 )
{
bufdestroy(*a1);
v2 = (_QWORD *)a1[4];
if ( v2 )
{
if ( *((_DWORD *)a1 + 6) == 1 )
{
if ( v2[2] )
{
free_item(v2[2]);
v2 = (_QWORD *)a1[4];
}
}
free(v2);
}
free(a1);
}
}

original_code:
void free_item( item_t *i )
{
 if( i )
 {
  bufdestroy( i->name );
  if( i->specific )
  {
   if( i->type == ITEMTYPE_WEAPON )
   {
    weapon_t *w = (weapon_t*)i->specific;
    if( w->ammo_type )
     free_item( w->ammo_type );
   }
   free( i->specific );
  }
  free( i );
 }
}

canonical_original_code:
void free_item(struct item_t *i)
{
 if( i )
 {
  bufdestroy( i->name );
  if( i->specific )
  {
   if( i->type == ITEMTYPE_WEAPON )
   {
    struct weapon_t *w = (weapon_t*)i->specific;
    if( w->ammo_type )
     free_item( w->ammo_type );
   }
   free( i->specific );
  }
  free( i );
 }
}

variable_types: struct weapon_t { int type; int accuracy; int min_damage; struct item_t { struct buf_t { char *data; int length; } *name; int face; int quantity; float quality; int type; void *specific; int place; int x; int flags; } *ammo_type; int ammo_loaded; char *attack_name; } *


decompiled_code:
void free_items()
{
__int64 i; // rbx

for ( i = *(_QWORD *)item_list; i; i = *(_QWORD *)(i + 8) )
free_item(*(_QWORD **)i);
}

canonical_decompiled_code:
void func1()
{
__int64 i; // rbx

for ( i = *(_QWORD *)item_list; i; i = *(_QWORD *)(i + 8) )
func0(*(_QWORD **)i);
}

original_code:
void free_items( void )
{
 list_element *e = item_list->head;
 while( e )
 {
  free_item( (item_t*)e->data );
  e = e->next;
 }
}

canonical_original_code:
void free_items()
{
 struct _list_element *e = item_list->head;
 while( e )
 {
  free_item( (struct item_t *)e->data );
  e = e->next;
 }
}


decompiled_code:
__int64 __fastcall item_find_by_position(int a1, int a2, int a3)
{
_QWORD *v5; // rbx
__int64 result; // rax
_DWORD *v7; // rsi
__int64 v8; // [rsp+8h] [rbp-30h]

v5 = *(_QWORD **)item_list;
for ( result = alloc_list(); v5; v5 = (_QWORD *)v5[1] )
{
v7 = (_DWORD *)*v5;
if ( *(_DWORD *)(*v5 + 44LL) == a1 && v7[12] == a2 && v7[13] == a3 && v7[10] == 2 )
{
v8 = result;
list_add_head(result);
result = v8;
}
}
if ( !*(_DWORD *)(result + 16) )
{
free_list(result);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, int a2, int a3)
{
_QWORD *v5; // rbx
__int64 result; // rax
_DWORD *v7; // rsi
__int64 v8; // [rsp+8h] [rbp-30h]

v5 = *(_QWORD **)item_list;
for ( result = alloc_list(); v5; v5 = (_QWORD *)v5[1] )
{
v7 = (_DWORD *)*v5;
if ( *(_DWORD *)(*v5 + 44LL) == a1 && v7[12] == a2 && v7[13] == a3 && v7[10] == 2 )
{
v8 = result;
list_add_head(result);
result = v8;
}
}
if ( !*(_DWORD *)(result + 16) )
{
free_list(result);
result = 0LL;
}
return result;
}

original_code:
list_t *item_find_by_position( int x, int y, int z )
{
 list_element *e = item_list->head;
 list_t *li = alloc_list();
 while( e )
 {
  item_t *it = (item_t*)e->data;
  if( ( x == it->x ) && ( y == it->y ) && ( z == it->z ) &&
   ( it->place == ITEMPLACE_DUNGEON ) )
   list_add_head( li, it );
  e = e->next;
 }
 if( li->length == 0 )
 {
  free_list( li );
  return ((void *)0);
 }
 else
  return li;
}

canonical_original_code:
struct list_t *item_find_by_position(int x, int y, int z)
{
 struct _list_element *e = item_list->head;
 struct list_t *li = alloc_list();
 while( e )
 {
  struct item_t *it = (item_t*)e->data;
  if( ( x == it->x ) && ( y == it->y ) && ( z == it->z ) &&
   ( it->place == ITEMPLACE_DUNGEON ) )
   list_add_head( li, it );
  e = e->next;
 }
 if( li->length == 0 )
 {
  free_list( li );
  return ((void *)0);
 }
 else
  return li;
}

variable_types: x int

variable_types: y int

variable_types: z int

variable_types: struct list_t { struct _list_element { void *data; struct _list_element *next; } *head; int length; } *


decompiled_code:
int __fastcall items_alike(__int64 a1, __int64 a2)
{
int result; // eax

if ( !a1 )
return 0;
if ( !a2 )
return 0;
result = strcmp(**(const char ***)a1, **(const char ***)a2);
if ( result )
return 0;
if ( *(_DWORD *)(a1 + 24) == *(_DWORD *)(a2 + 24) && *(float *)(a1 + 20) == *(float *)(a2 + 20) )
result = 1;
return result;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, __int64 a2)
{
int result; // eax

if ( !a1 )
return 0;
if ( !a2 )
return 0;
result = strcmp(**(const char ***)a1, **(const char ***)a2);
if ( result )
return 0;
if ( *(_DWORD *)(a1 + 24) == *(_DWORD *)(a2 + 24) && *(float *)(a1 + 20) == *(float *)(a2 + 20) )
result = 1;
return result;
}

original_code:
int items_alike( item_t *a, item_t *b )
{
 if( !a )
  return 0;
 if( !b )
  return 0;
 return( ( strcmp( a->name->data, b->name->data ) == 0 ) &&
   ( a->type == b->type ) &&
   ( a->quality == b->quality ) );
}

canonical_original_code:
int items_alike(struct item_t *a, struct item_t *b)
{
 if( !a )
  return 0;
 if( !b )
  return 0;
 return( ( strcmp( a->name->data, b->name->data ) == 0 ) &&
   ( a->type == b->type ) &&
   ( a->quality == b->quality ) );
}

variable_types:
b
struct item_t *


decompiled_code:
__int64 __fastcall count_items(__int64 **a1, __int64 a2)
{
__int64 *v2; // rbx
unsigned int v3; // er13
__int64 v4; // rbp

v2 = *a1;
if ( !*a1 )
return 0LL;
v3 = 0;
do
{
v4 = *v2;
if ( items_alike(a2, *v2) )
v3 += *(_DWORD *)(v4 + 16);
v2 = (__int64 *)v2[1];
}
while ( v2 );
return v3;
}

original_code:
int count_items( list_t *li, item_t *i )
{
 list_element *el = li->head;
 int c = 0;
 while( el )
 {
  item_t *j = (item_t*)el->data;
  if( items_alike( i, j ) )
  {
   c += j->quantity;
  }
  el = el->next;
 }
 return c;
}

canonical_original_code:
int count_items(struct list_t *li, struct item_t *i)
{
 struct _list_element *el = li->head;
 int c = 0;
 while( el )
 {
  struct item_t *j = (item_t*)el->data;
  if( items_alike( i, j ) )
  {
   c += j->quantity;
  }
  el = el->next;
 }
 return c;
}

variable_types: c int


decompiled_code:
__int64 terminate_game()
{
unsigned int v0; // ebx
__int64 v1; // rdx

log_add("Terminating game...\n");
if ( nlevels )
{
v0 = 0;
do
{
v1 = v0++;
free_map(*((_QWORD *)dungeon + v1));
}
while ( nlevels > v0 );
}
free(dungeon);
free_entities();
free_list(entity_list);
free_messages();
free_list(message_list);
free_items();
free_list(item_list);
free_links();
free_list(link_list);
free_entity_types();
free_ammo_types();
log_add("Done terminating game.\n");
terminate_ui();
close_logfile();
return 1LL;
}

canonical_decompiled_code:
__int64 func0()
{
unsigned int v0; // ebx
__int64 v1; // rdx

log_add("Terminating game...\n");
if ( nlevels )
{
v0 = 0;
do
{
v1 = v0++;
free_map(*((_QWORD *)dungeon + v1));
}
while ( nlevels > v0 );
}
free(dungeon);
free_entities();
free_list(entity_list);
free_messages();
free_list(message_list);
free_items();
free_list(item_list);
free_links();
free_list(link_list);
free_entity_types();
free_ammo_types();
log_add("Done terminating game.\n");
terminate_ui();
close_logfile();
return 1LL;
}

original_code:
int terminate_game( void )
{
 unsigned int i;
 log_add( "Terminating game...\n" );
 for( i = 0; i < nlevels; i++ )
 {
  free_map( dungeon[i] );
 }
 free( dungeon );
 free_entities();
 free_list( entity_list );
 free_messages();
 free_list( message_list );
 free_items();
 free_list( item_list );
 free_links();
 free_list( link_list );
 free_entity_types();
 free_ammo_types();
 log_add( "Done terminating game.\n" );
 terminate_ui();
 close_logfile();
 return 1;
}

canonical_original_code:
int terminate_game()
{
 unsigned int i;
 log_add( "Terminating game...\n" );
 for( i = 0; i < nlevels; i++ )
 {
  free_map( dungeon[i] );
 }
 free( dungeon );
 free_entities();
 free_list( entity_list );
 free_messages();
 free_list( message_list );
 free_items();
 free_list( item_list );
 free_links();
 free_list( link_list );
 free_entity_types();
 free_ammo_types();
 log_add( "Done terminating game.\n" );
 terminate_ui();
 close_logfile();
 return 1;
}

variable_types:
i
unsigned int


decompiled_code:
__int64 game_loop()
{
_QWORD *v0; // rax
_QWORD *v1; // rbx

v0 = (_QWORD *)entity_list;
if ( !running )
return 1LL;
while ( 1 )
{
v1 = (_QWORD *)*v0;
if ( *v0 )
break;
LABEL_9:
++global_turns;
}
do
{
while ( 1 )
{
entity_act(*v1);
v1 = (_QWORD *)v1[1];
if ( v1 )
break;
++global_turns;
if ( !running )
return 1LL;
v0 = (_QWORD *)entity_list;
v1 = (_QWORD *)*entity_list;
if ( !*entity_list )
goto LABEL_9;
}
}
while ( running );
++global_turns;
return 1LL;
}

canonical_decompiled_code:
__int64 func1()
{
_QWORD *v0; // rax
_QWORD *v1; // rbx

v0 = (_QWORD *)entity_list;
if ( !running )
return 1LL;
while ( 1 )
{
v1 = (_QWORD *)*v0;
if ( *v0 )
break;
LABEL_9:
++global_turns;
}
do
{
while ( 1 )
{
entity_act(*v1);
v1 = (_QWORD *)v1[1];
if ( v1 )
break;
++global_turns;
if ( !running )
return 1LL;
v0 = (_QWORD *)entity_list;
v1 = (_QWORD *)*entity_list;
if ( !*entity_list )
goto LABEL_9;
}
}
while ( running );
++global_turns;
return 1LL;
}

original_code:
int game_loop( void )
{
 list_element *e;
 while( running )
 {
  e = entity_list->head;
  while( e && running )
  {
   entity_act( (entity_t*)e->data );
   e = e->next;
  }
  global_turns++;
 }
 return 1;
}

canonical_original_code:
int game_loop()
{
 struct _list_element *e;
 while( running )
 {
  e = entity_list->head;
  while( e && running )
  {
   entity_act( (struct entity_t *)e->data );
   e = e->next;
  }
  global_turns++;
 }
 return 1;
}


decompiled_code:
__int64 __fastcall handle_key(unsigned int a1)
{
__int64 result; // rax
__int64 v2; // rax
__int64 v3; // rax

log_add("[handle_key] Received key 0x%08x(%c)\n", a1, a1);
switch ( a1 )
{
case 0x2Cu:
result = draw_pick_up_screen(player);
break;
case 0x2Eu:
case 0x35u:
result = 1LL;
break;
case 0x31u:
case 0x62u:
result = move_relative(player, 0xFFFFFFFFLL, 1LL);
break;
case 0x32u:
case 0x6Au:
case 0x102u:
result = move_relative(player, 0LL, 1LL);
break;
case 0x33u:
case 0x6Eu:
result = move_relative(player, 1LL, 1LL);
break;
case 0x34u:
case 0x68u:
case 0x104u:
result = move_relative(player, 0xFFFFFFFFLL, 0LL);
break;
case 0x36u:
case 0x6Cu:
case 0x105u:
result = move_relative(player, 1LL, 0LL);
break;
case 0x37u:
case 0x79u:
result = move_relative(player, 0xFFFFFFFFLL, 0xFFFFFFFFLL);
break;
case 0x38u:
case 0x6Bu:
case 0x103u:
result = move_relative(player, 0LL, 0xFFFFFFFFLL);
break;
case 0x39u:
case 0x75u:
result = move_relative(player, 1LL, 0xFFFFFFFFLL);
break;
case 0x3Eu:
result = follow_stairs(player);
break;
case 0x4Du:
draw_message_buffer();
result = 0LL;
break;
case 0x55u:
result = unload_weapon(player);
break;
case 0x63u:
v3 = input_direction("Close where?");
result = close_door(
player,
(unsigned int)(v3 + *(_DWORD *)(player + 32LL)),
(unsigned int)(*(_DWORD *)(player + 36LL) + HIDWORD(v3)));
break;
case 0x66u:
result = fire_at();
break;
case 0x69u:
result = draw_inventory_screen(player);
break;
case 0x6Du:
result = game_flags & 1;
if ( (game_flags & 1) != 0 )
{
reveal_map(*(unsigned int *)(player + 40LL));
result = 0LL;
}
break;
case 0x6Fu:
v2 = input_direction("Open where?");
result = open_door(
player,
(unsigned int)(v2 + *(_DWORD *)(player + 32LL)),
(unsigned int)(*(_DWORD *)(player + 36LL) + HIDWORD(v2)));
break;
case 0x71u:
running = 0;
result = 0LL;
break;
case 0x72u:
result = reload_weapon(player);
break;
case 0x78u:
look_at();
goto LABEL_3;
default:
LABEL_3:
result = 0LL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int a1)
{
__int64 result; // rax
__int64 v2; // rax
__int64 v3; // rax

log_add("[handle_key] Received key 0x%08x(%c)\n", a1, a1);
switch ( a1 )
{
case 0x2Cu:
result = draw_pick_up_screen(player);
break;
case 0x2Eu:
case 0x35u:
result = 1LL;
break;
case 0x31u:
case 0x62u:
result = move_relative(player, 0xFFFFFFFFLL, 1LL);
break;
case 0x32u:
case 0x6Au:
case 0x102u:
result = move_relative(player, 0LL, 1LL);
break;
case 0x33u:
case 0x6Eu:
result = move_relative(player, 1LL, 1LL);
break;
case 0x34u:
case 0x68u:
case 0x104u:
result = move_relative(player, 0xFFFFFFFFLL, 0LL);
break;
case 0x36u:
case 0x6Cu:
case 0x105u:
result = move_relative(player, 1LL, 0LL);
break;
case 0x37u:
case 0x79u:
result = move_relative(player, 0xFFFFFFFFLL, 0xFFFFFFFFLL);
break;
case 0x38u:
case 0x6Bu:
case 0x103u:
result = move_relative(player, 0LL, 0xFFFFFFFFLL);
break;
case 0x39u:
case 0x75u:
result = move_relative(player, 1LL, 0xFFFFFFFFLL);
break;
case 0x3Eu:
result = follow_stairs(player);
break;
case 0x4Du:
draw_message_buffer();
result = 0LL;
break;
case 0x55u:
result = unload_weapon(player);
break;
case 0x63u:
v3 = input_direction("Close where?");
result = close_door(
player,
(unsigned int)(v3 + *(_DWORD *)(player + 32LL)),
(unsigned int)(*(_DWORD *)(player + 36LL) + HIDWORD(v3)));
break;
case 0x66u:
result = fire_at();
break;
case 0x69u:
result = draw_inventory_screen(player);
break;
case 0x6Du:
result = game_flags & 1;
if ( (game_flags & 1) != 0 )
{
reveal_map(*(unsigned int *)(player + 40LL));
result = 0LL;
}
break;
case 0x6Fu:
v2 = input_direction("Open where?");
result = open_door(
player,
(unsigned int)(v2 + *(_DWORD *)(player + 32LL)),
(unsigned int)(*(_DWORD *)(player + 36LL) + HIDWORD(v2)));
break;
case 0x71u:
running = 0;
result = 0LL;
break;
case 0x72u:
result = reload_weapon(player);
break;
case 0x78u:
look_at();
goto LABEL_3;
default:
LABEL_3:
result = 0LL;
break;
}
return result;
}

original_code:
int handle_key( int key )
{
 point_t p;
 log_add( "[handle_key] Received key 0x%08x(%c)\n", key, key );
 switch( key )
 {
 case 'q':
  running = 0;
  break;
 case 'm':
  if( game_flags & (1<<0) )
  {
   reveal_map( player->z );
  }
  break;
 case '4':
 case 0404:
 case 'h':
  return move_relative( player, -1, 0 );
 case '2':
 case 0402:
 case 'j':
  return move_relative( player, 0, 1 );
 case '8':
 case 0403:
 case 'k':
  return move_relative( player, 0, -1 );
 case '6':
 case 0405:
 case 'l':
  return move_relative( player, 1, 0 );
 case '7':
 case 'y':
  return move_relative( player, -1, -1 );
 case '9':
 case 'u':
  return move_relative( player, 1, -1 );
 case '1':
 case 'b':
  return move_relative( player, -1, 1 );
 case '3':
 case 'n':
  return move_relative( player, 1, 1 );
 case '5':
 case '.':
  return 1;
 case '>':
  return follow_stairs( player );
 case ',':
  return draw_pick_up_screen( player );
 case 'i':
  return draw_inventory_screen( player );
 case 'o':
  p = input_direction( "Open where?" );
  return open_door( player, player->x + p.x, player->y + p.y );
 case 'c':
  p = input_direction( "Close where?" );
  return close_door( player, player->x + p.x, player->y + p.y );
 case 'x':
  look_at();
  return 0;
 case 'f':
  return fire_at();
 case 'r':
  return reload_weapon( player );
 case 'U':
  return unload_weapon( player );
 case 'M':
  draw_message_buffer();
  return 0;
 default:
  break;
 }
 return 0;
}

canonical_original_code:
int handle_key(int key)
{
 struct point_t p;
 log_add( "[handle_key] Received key 0x%08x(%c)\n", key, key );
 switch( key )
 {
 case 'q':
  running = 0;
  break;
 case 'm':
  if( game_flags & (1<<0) )
  {
   reveal_map( player->z );
  }
  break;
 case '4':
 case 0404:
 case 'h':
  return move_relative( player, -1, 0 );
 case '2':
 case 0402:
 case 'j':
  return move_relative( player, 0, 1 );
 case '8':
 case 0403:
 case 'k':
  return move_relative( player, 0, -1 );
 case '6':
 case 0405:
 case 'l':
  return move_relative( player, 1, 0 );
 case '7':
 case 'y':
  return move_relative( player, -1, -1 );
 case '9':
 case 'u':
  return move_relative( player, 1, -1 );
 case '1':
 case 'b':
  return move_relative( player, -1, 1 );
 case '3':
 case 'n':
  return move_relative( player, 1, 1 );
 case '5':
 case '.':
  return 1;
 case '>':
  return follow_stairs( player );
 case ',':
  return draw_pick_up_screen( player );
 case 'i':
  return draw_inventory_screen( player );
 case 'o':
  p = input_direction( "Open where?" );
  return open_door( player, player->x + p.x, player->y + p.y );
 case 'c':
  p = input_direction( "Close where?" );
  return close_door( player, player->x + p.x, player->y + p.y );
 case 'x':
  look_at();
  return 0;
 case 'f':
  return fire_at();
 case 'r':
  return reload_weapon( player );
 case 'U':
  return unload_weapon( player );
 case 'M':
  draw_message_buffer();
  return 0;
 default:
  break;
 }
 return 0;
}

variable_types:
p
struct point_t { int x; }


original_code:
void make_random_entities( int n )
{
 int i;
 int r;
 entity_t *e;
 for( i = 0; i < n; i++ )
 {
  r = rand() % ( entity_type_list->length );
  e = clone_entity( (entity_t*)( list_get_index( entity_type_list, r ) ) );
  e->z = 0;
  e->natural = malloc( sizeof(weapon_t) );
  e->natural->min_damage = 1;
  e->natural->max_damage = 3;
  e->natural->clip_size = 0;
  e->natural->ammo_loaded = 0;
  e->natural->accuracy = 0.9;
  e->natural->ammo_type = ((void *)0);
  e->natural->attack_name = "bite";
  do
  {
   e->x = rand() % 80;
   e->y = rand() % 21;
  }
  while( dungeon[e->z]->terrain[e->x][e->y] != &tile_floor );
  e->ai = alloc_ai( AITYPE_BASICMELEE );
  list_add_head( entity_list, (void*)e );
 }
}

canonical_original_code:
void make_random_entities(int n)
{
 int i;
 int r;
 struct entity_t *e;
 for( i = 0; i < n; i++ )
 {
  r = rand() % ( entity_type_list->length );
  e = clone_entity( (struct entity_t *)( list_get_index( entity_type_list, r ) ) );
  e->z = 0;
  e->natural = malloc( sizeof(weapon_t) );
  e->natural->min_damage = 1;
  e->natural->max_damage = 3;
  e->natural->clip_size = 0;
  e->natural->ammo_loaded = 0;
  e->natural->accuracy = 0.9;
  e->natural->ammo_type = ((void *)0);
  e->natural->attack_name = "bite";
  do
  {
   e->x = rand() % 80;
   e->y = rand() % 21;
  }
  while( dungeon[e->z]->terrain[e->x][e->y] != &tile_floor );
  e->ai = alloc_ai( AITYPE_BASICMELEE );
  list_add_head( entity_list, (void *)e );
 }
}

variable_types: n int

variable_types: r int

variable_types: struct entity_t { struct buf_t { char *data; int length; } *name; int face; int ap; int agility; int hp; int x; float ***lightmap; struct list_t { struct _list_element { void *data; struct _list_element *next; } *head; int length; } *inventory; struct item_t { struct buf_t *name; int face; int quantity; float quality; int type; void *specific; int place; int x; int flags; } *worn; struct weapon_t { int type; int accuracy; int min_damage; struct item_t *ammo_type; int ammo_loaded; char *attack_name; } *natural; struct ai_t { int type; int lx; int flags; } *ai; int flags; } *


original_code:
void make_random_objects( int n )
{
 int i;
 buf_t *name_a = bufnew( "Red Item" );
 buf_t *name_b = bufnew( "Green Item" );
 buf_t *name_c = bufnew( "Blue Item" );
 item_t *it;
 int r = 0;
 for( i = 0; i < n; i++ )
 {
  r = rand() % 3;
  if( r == 0 )
   it = alloc_item( name_a );
  else if( r == 1 )
   it = alloc_item( name_b );
  else
   it = alloc_item( name_c );
  it->place = ITEMPLACE_DUNGEON;
  it->x = 0;
  it->y = 0;
  it->z = 0;
  it->face = '*';
  if( r == 0 )
   it->color = (((chtype)(((2))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
  else if( r == 1 )
   it->color = (((chtype)(((3))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
  else
   it->color = (((chtype)(((5))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
  it->quantity = 1;
  it->quality = 1.0f;
  do
  {
   it->x = rand() % 80;
   it->y = rand() % 21;
  }
  while( dungeon[it->z]->terrain[it->x][it->y] != &tile_floor );
  it->type = ITEMTYPE_NONE;
  it->flags = (1<<0) | (1<<1);
  list_add_head( item_list, (void*)it );
 }
 bufdestroy( name_a );
 bufdestroy( name_b );
 bufdestroy( name_c );
}

canonical_original_code:
void make_random_objects(int n)
{
 int i;
 struct buf_t *name_a = bufnew( "Red Item" );
 struct buf_t *name_b = bufnew( "Green Item" );
 struct buf_t *name_c = bufnew( "Blue Item" );
 struct item_t *it;
 int r = 0;
 for( i = 0; i < n; i++ )
 {
  r = rand() % 3;
  if( r == 0 )
   it = alloc_item( name_a );
  else if( r == 1 )
   it = alloc_item( name_b );
  else
   it = alloc_item( name_c );
  it->place = ITEMPLACE_DUNGEON;
  it->x = 0;
  it->y = 0;
  it->z = 0;
  it->face = '*';
  if( r == 0 )
   it->color = (((chtype)(((2))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
  else if( r == 1 )
   it->color = (((chtype)(((3))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
  else
   it->color = (((chtype)(((5))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
  it->quantity = 1;
  it->quality = 1.0f;
  do
  {
   it->x = rand() % 80;
   it->y = rand() % 21;
  }
  while( dungeon[it->z]->terrain[it->x][it->y] != &tile_floor );
  it->type = ITEMTYPE_NONE;
  it->flags = (1<<0) | (1<<1);
  list_add_head( item_list, (void *)it );
 }
 bufdestroy( name_a );
 bufdestroy( name_b );
 bufdestroy( name_c );
}

variable_types: i int

variable_types: struct buf_t { char *data; int length; } *


decompiled_code:
__int64 __fastcall new_game(unsigned int seed)
{
__int64 v1; // r13
unsigned int v2; // ebp
void *v3; // rax
__int64 v4; // r12
__int64 v5; // rbp
__int64 v6; // rax
__int64 v7; // rdi
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // r12
__int64 v11; // rbp
_QWORD *v12; // rax
__int64 v13; // rax
__int64 v14; // rbx
__int64 v15; // rbp
__int64 v16; // rbp
_QWORD *v17; // rax
__int64 v18; // rdi
_QWORD *v19; // rbx
__int64 v20; // rax
__int64 v21; // rax
__int64 v22; // rax
__int64 v23; // rbx
__int64 v24; // rbp
__int64 v25; // rbp
__int64 v26; // rbx
_DWORD *v27; // rax
_QWORD *v28; // rax
__int64 v29; // rdx
__int64 v30; // rcx
int v31; // eax
_QWORD *v32; // rdx
__int64 v33; // rcx
__int64 v34; // rdi

v1 = bufnew("Dungeon");
log_add("Creating new game...\n");
main_seed = seed;
v2 = 0;
srand(seed);
nlevels = 10;
v3 = malloc(0x50uLL);
for ( dungeon = v3; ; v3 = dungeon )
{
v4 = v2;
*((_QWORD *)v3 + v2) = alloc_map(v1, 80LL, 21LL);
do
clear_map(*((_QWORD *)dungeon + v2));
while ( (int)make_dla_dungeon(*((_QWORD *)dungeon + v2)) <= 149 );
++v2;
post_process_map(*((_QWORD *)dungeon + v4));
debug_dump_map(*((_QWORD *)dungeon + v4));
if ( nlevels <= v2 )
break;
}
link_dungeon_levels();
bufdestroy(v1);
v5 = bufnew("Player");
player = alloc_entity(v5);
bufdestroy(v5);
v6 = player;
v7 = ammo_type_list;
*(_DWORD *)(player + 8LL) = 64;
*(_QWORD *)(v6 + 24) = 0x500000005LL;
*(_QWORD *)(v6 + 32) = 0LL;
*(_DWORD *)(v6 + 40) = 0;
v8 = list_get_index(v7, 1LL);
v9 = clone_item(v8);
*(_DWORD *)(v9 + 16) = 10;
list_add_head(*(_QWORD *)(player + 56LL), v9);
v10 = bufnew("Sword");
v11 = alloc_item(v10);
bufdestroy(v10);
*(_QWORD *)(v11 + 16) = 0x3F80000000000001LL;
*(_DWORD *)(v11 + 40) = 1;
*(_QWORD *)(v11 + 8) = 0x20040000000029LL;
*(_DWORD *)(v11 + 24) = 1;
*(_DWORD *)(v11 + 56) = 1;
v12 = malloc(0x28uLL);
*(_QWORD *)(v11 + 32) = v12;
v12[1] = 0x400000001LL;
v12[2] = 0LL;
v12[3] = 0LL;
*(_DWORD *)v12 = 0;
v12[4] = "cut";
list_add_head(*(_QWORD *)(player + 56LL), v11);
v13 = bufnew("Pistol");
v14 = player;
v15 = v13;
*(_QWORD *)(v14 + 72) = alloc_item(v13);
bufdestroy(v15);
v16 = *(_QWORD *)(player + 72LL);
*(_DWORD *)(v16 + 40) = 1;
*(_QWORD *)(v16 + 8) = 0x20050000000029LL;
*(_QWORD *)(v16 + 16) = 0x3F80000000000001LL;
*(_DWORD *)(v16 + 24) = 1;
*(_DWORD *)(v16 + 56) = 1;
v17 = malloc(0x28uLL);
v18 = ammo_type_list;
*(_QWORD *)(v16 + 32) = v17;
v19 = v17;
v17[3] = 0x500000005LL;
*((_DWORD *)v17 + 1) = 0;
v17[1] = 0x600000002LL;
v20 = list_get_index(v18, 1LL);
v21 = clone_item(v20);
*(_DWORD *)v19 = 1;
v19[2] = v21;
v19[4] = "shoot";
v22 = bufnew("Leather jacket");
v23 = player;
v24 = v22;
*(_QWORD *)(v23 + 64) = alloc_item(v22);
bufdestroy(v24);
v25 = player;
v26 = *(_QWORD *)(player + 64LL);
*(_DWORD *)(v26 + 40) = 1;
*(_QWORD *)(v26 + 8) = 0x4000000005BLL;
*(_QWORD *)(v26 + 16) = 0x3F80000000000001LL;
*(_DWORD *)(v26 + 24) = 2;
*(_DWORD *)(v26 + 56) = 1;
v27 = malloc(4uLL);
*(_QWORD *)(v26 + 32) = v27;
*v27 = 5;
v28 = malloc(0x28uLL);
*(_QWORD *)(v25 + 80) = v28;
v28[1] = 0x400000002LL;
v28[3] = 0LL;
v29 = *(int *)(v25 + 40);
v28[2] = 0LL;
v30 = *(int *)(v25 + 32);
*((_DWORD *)v28 + 1) = 0;
v28[4] = "punch";
if ( *(_UNKNOWN **)(*(_QWORD *)(*(_QWORD *)(*((_QWORD *)dungeon + v29) + 16LL) + 8 * v30) + 8LL * *(int *)(v25 + 36)) != &tile_floor )
{
do
{
*(_DWORD *)(player + 32LL) = rand() % 80;
v31 = rand();
v25 = player;
v32 = dungeon;
v31 %= 21;
v33 = *(int *)(player + 40LL);
*(_DWORD *)(player + 36LL) = v31;
}
while ( *(_UNKNOWN **)(*(_QWORD *)(*(_QWORD *)(v32[v33] + 16LL) + 8LL * *(int *)(v25 + 32)) + 8LL * v31) != &tile_floor );
}
*(_DWORD *)(v25 + 96) = 1;
v34 = entity_list;
*(_QWORD *)(v25 + 16) = 0xF00000000LL;
list_add_head(v34, v25);
make_random_entities(10);
make_random_objects(20);
return log_add("Done creating new game.\n");
}

canonical_decompiled_code:
__int64 __fastcall func5(unsigned int seed)
{
__int64 v1; // r13
unsigned int v2; // ebp
void *v3; // rax
__int64 v4; // r12
__int64 v5; // rbp
__int64 v6; // rax
__int64 v7; // rdi
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // r12
__int64 v11; // rbp
_QWORD *v12; // rax
__int64 v13; // rax
__int64 v14; // rbx
__int64 v15; // rbp
__int64 v16; // rbp
_QWORD *v17; // rax
__int64 v18; // rdi
_QWORD *v19; // rbx
__int64 v20; // rax
__int64 v21; // rax
__int64 v22; // rax
__int64 v23; // rbx
__int64 v24; // rbp
__int64 v25; // rbp
__int64 v26; // rbx
_DWORD *v27; // rax
_QWORD *v28; // rax
__int64 v29; // rdx
__int64 v30; // rcx
int v31; // eax
_QWORD *v32; // rdx
__int64 v33; // rcx
__int64 v34; // rdi

v1 = bufnew("Dungeon");
log_add("Creating new game...\n");
main_seed = seed;
v2 = 0;
srand(seed);
nlevels = 10;
v3 = malloc(0x50uLL);
for ( dungeon = v3; ; v3 = dungeon )
{
v4 = v2;
*((_QWORD *)v3 + v2) = alloc_map(v1, 80LL, 21LL);
do
clear_map(*((_QWORD *)dungeon + v2));
while ( (int)make_dla_dungeon(*((_QWORD *)dungeon + v2)) <= 149 );
++v2;
post_process_map(*((_QWORD *)dungeon + v4));
debug_dump_map(*((_QWORD *)dungeon + v4));
if ( nlevels <= v2 )
break;
}
link_dungeon_levels();
bufdestroy(v1);
v5 = bufnew("Player");
player = alloc_entity(v5);
bufdestroy(v5);
v6 = player;
v7 = ammo_type_list;
*(_DWORD *)(player + 8LL) = 64;
*(_QWORD *)(v6 + 24) = 0x500000005LL;
*(_QWORD *)(v6 + 32) = 0LL;
*(_DWORD *)(v6 + 40) = 0;
v8 = list_get_index(v7, 1LL);
v9 = clone_item(v8);
*(_DWORD *)(v9 + 16) = 10;
list_add_head(*(_QWORD *)(player + 56LL), v9);
v10 = bufnew("Sword");
v11 = alloc_item(v10);
bufdestroy(v10);
*(_QWORD *)(v11 + 16) = 0x3F80000000000001LL;
*(_DWORD *)(v11 + 40) = 1;
*(_QWORD *)(v11 + 8) = 0x20040000000029LL;
*(_DWORD *)(v11 + 24) = 1;
*(_DWORD *)(v11 + 56) = 1;
v12 = malloc(0x28uLL);
*(_QWORD *)(v11 + 32) = v12;
v12[1] = 0x400000001LL;
v12[2] = 0LL;
v12[3] = 0LL;
*(_DWORD *)v12 = 0;
v12[4] = "cut";
list_add_head(*(_QWORD *)(player + 56LL), v11);
v13 = bufnew("Pistol");
v14 = player;
v15 = v13;
*(_QWORD *)(v14 + 72) = alloc_item(v13);
bufdestroy(v15);
v16 = *(_QWORD *)(player + 72LL);
*(_DWORD *)(v16 + 40) = 1;
*(_QWORD *)(v16 + 8) = 0x20050000000029LL;
*(_QWORD *)(v16 + 16) = 0x3F80000000000001LL;
*(_DWORD *)(v16 + 24) = 1;
*(_DWORD *)(v16 + 56) = 1;
v17 = malloc(0x28uLL);
v18 = ammo_type_list;
*(_QWORD *)(v16 + 32) = v17;
v19 = v17;
v17[3] = 0x500000005LL;
*((_DWORD *)v17 + 1) = 0;
v17[1] = 0x600000002LL;
v20 = list_get_index(v18, 1LL);
v21 = clone_item(v20);
*(_DWORD *)v19 = 1;
v19[2] = v21;
v19[4] = "shoot";
v22 = bufnew("Leather jacket");
v23 = player;
v24 = v22;
*(_QWORD *)(v23 + 64) = alloc_item(v22);
bufdestroy(v24);
v25 = player;
v26 = *(_QWORD *)(player + 64LL);
*(_DWORD *)(v26 + 40) = 1;
*(_QWORD *)(v26 + 8) = 0x4000000005BLL;
*(_QWORD *)(v26 + 16) = 0x3F80000000000001LL;
*(_DWORD *)(v26 + 24) = 2;
*(_DWORD *)(v26 + 56) = 1;
v27 = malloc(4uLL);
*(_QWORD *)(v26 + 32) = v27;
*v27 = 5;
v28 = malloc(0x28uLL);
*(_QWORD *)(v25 + 80) = v28;
v28[1] = 0x400000002LL;
v28[3] = 0LL;
v29 = *(int *)(v25 + 40);
v28[2] = 0LL;
v30 = *(int *)(v25 + 32);
*((_DWORD *)v28 + 1) = 0;
v28[4] = "punch";
if ( *(_UNKNOWN **)(*(_QWORD *)(*(_QWORD *)(*((_QWORD *)dungeon + v29) + 16LL) + 8 * v30) + 8LL * *(int *)(v25 + 36)) != &tile_floor )
{
do
{
*(_DWORD *)(player + 32LL) = rand() % 80;
v31 = rand();
v25 = player;
v32 = dungeon;
v31 %= 21;
v33 = *(int *)(player + 40LL);
*(_DWORD *)(player + 36LL) = v31;
}
while ( *(_UNKNOWN **)(*(_QWORD *)(*(_QWORD *)(v32[v33] + 16LL) + 8LL * *(int *)(v25 + 32)) + 8LL * v31) != &tile_floor );
}
*(_DWORD *)(v25 + 96) = 1;
v34 = entity_list;
*(_QWORD *)(v25 + 16) = 0xF00000000LL;
list_add_head(v34, v25);
func3(10);
func4(20);
return log_add("Done creating new game.\n");
}

original_code:
void new_game( unsigned int seed )
{
 unsigned int i;
 buf_t *map_name = bufnew( "Dungeon" );
 log_add( "Creating new game...\n" );
 main_seed = seed;
 srand( seed );
 nlevels = 10;
 dungeon = (map_t**) malloc( nlevels * sizeof(map_t*) );
 for( i = 0; i < nlevels; i++ )
 {
  dungeon[i] = alloc_map( map_name, 80, 21 );
  int r;
  do
  {
   clear_map( dungeon[i] );
   r = make_dla_dungeon( dungeon[i] );
  }
  while( r < 150 );
  post_process_map( dungeon[i] );
  debug_dump_map( dungeon[i] );
 }
 link_dungeon_levels();
 bufdestroy( map_name );
 buf_t *player_name = bufnew( "Player" );
 player = alloc_entity( player_name );
 bufdestroy( player_name );
 player->face = '@';
 player->x = 0;
 player->y = 0;
 player->z = 0;
 player->hp = 5;
 player->max_hp = 5;
 item_t *bullet = clone_item( (item_t*)list_get_index( ammo_type_list, 1 ) );
 bullet->quantity = 10;
 list_add_head( player->inventory, (void*)bullet );
 buf_t *melee_name = bufnew( "Sword" );
 item_t *melee = alloc_item( melee_name );
 bufdestroy( melee_name );
 melee->face = ')';
 melee->color = (((chtype)(((4))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8))) | ((chtype)((1U)) << ((13) + 8));
 melee->quantity = 1;
 melee->quality = 1.0f;
 melee->place = ITEMPLACE_ENTITY;
 melee->type = ITEMTYPE_WEAPON;
 melee->flags = (1<<0);
 weapon_t *mweapon = malloc( sizeof(weapon_t) );
 melee->specific = (void*)mweapon;
 mweapon->min_damage = 1;
 mweapon->max_damage = 4;
 mweapon->clip_size = 0;
 mweapon->ammo_loaded = 0;
 mweapon->ammo_type = ((void *)0);
 mweapon->type = WEAPONTYPE_MELEE;
 mweapon->attack_name = "cut";
 list_add_head( player->inventory, melee );
 buf_t *weapon_name = bufnew( "Pistol" );
 player->in_hand = alloc_item( weapon_name );
 bufdestroy( weapon_name );
 player->in_hand->face = ')';
 player->in_hand->color = (((chtype)(((5))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8))) | ((chtype)((1U)) << ((13) + 8));
 player->in_hand->quantity = 1;
 player->in_hand->quality = 1.0f;
 player->in_hand->place = ITEMPLACE_ENTITY;
 player->in_hand->type = ITEMTYPE_WEAPON;
 player->in_hand->flags = (1<<0);
 weapon_t *weapon = malloc( sizeof(weapon_t) );
 player->in_hand->specific = (void*)weapon;
 weapon->min_damage = 2;
 weapon->max_damage = 6;
 weapon->clip_size = 5;
 weapon->ammo_loaded = 5;
 weapon->accuracy = 0.9;
 weapon->ammo_type = clone_item( (item_t*)list_get_index( ammo_type_list, 1 ) );
 weapon->type = WEAPONTYPE_HANDGUN;
 weapon->attack_name = "shoot";
 buf_t *armor_name = bufnew( "Leather jacket" );
 player->worn = alloc_item( armor_name );
 bufdestroy( armor_name );
 player->worn->face = '[';
 player->worn->color = (((chtype)(((4))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
 player->worn->quantity = 1;
 player->worn->quality = 1.0f;
 player->worn->place = ITEMPLACE_ENTITY;
 player->worn->type = ITEMTYPE_ARMOR;
 player->worn->flags = (1<<0);
 armor_t *armor = malloc( sizeof(armor_t) );
 player->worn->specific = (void*)armor;
 armor->ac = 5;
 player->natural = malloc( sizeof(weapon_t) );
 player->natural->min_damage = 2;
 player->natural->max_damage = 4;
 player->natural->clip_size = 0;
 player->natural->ammo_loaded = 0;
 player->natural->accuracy = 0.9;
 player->natural->ammo_type = ((void *)0);
 player->natural->attack_name = "punch";
 while( dungeon[player->z]->terrain[player->x][player->y] != &tile_floor )
 {
  player->x = rand() % 80;
  player->y = rand() % 21;
 }
 player->flags = (1<<0);
 player->agility = 15;
 player->ap = 0;
 list_add_head( entity_list, (void*)player );
 make_random_entities( 10 );
 make_random_objects( 20 );
 log_add( "Done creating new game.\n" );
}

canonical_original_code:
void new_game(unsigned int seed)
{
 unsigned int i;
 struct buf_t *map_name = bufnew( "Dungeon" );
 log_add( "Creating new game...\n" );
 main_seed = seed;
 srand( seed );
 nlevels = 10;
 dungeon = (struct map_t **) malloc( nlevels * sizeof(struct map_t *) );
 for( i = 0; i < nlevels; i++ )
 {
  dungeon[i] = alloc_map( map_name, 80, 21 );
  int r;
  do
  {
   clear_map( dungeon[i] );
   r = make_dla_dungeon( dungeon[i] );
  }
  while( r < 150 );
  post_process_map( dungeon[i] );
  debug_dump_map( dungeon[i] );
 }
 link_dungeon_levels();
 bufdestroy( map_name );
 struct buf_t *player_name = bufnew( "Player" );
 player = alloc_entity( player_name );
 bufdestroy( player_name );
 player->face = '@';
 player->x = 0;
 player->y = 0;
 player->z = 0;
 player->hp = 5;
 player->max_hp = 5;
 struct item_t *bullet = clone_item( (item_t*)list_get_index( ammo_type_list, 1 ) );
 bullet->quantity = 10;
 list_add_head( player->inventory, (void *)bullet );
 struct buf_t *melee_name = bufnew( "Sword" );
 struct item_t *melee = alloc_item( melee_name );
 bufdestroy( melee_name );
 melee->face = ')';
 melee->color = (((chtype)(((4))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8))) | ((chtype)((1U)) << ((13) + 8));
 melee->quantity = 1;
 melee->quality = 1.0f;
 melee->place = ITEMPLACE_ENTITY;
 melee->type = ITEMTYPE_WEAPON;
 melee->flags = (1<<0);
 struct weapon_t *mweapon = malloc( sizeof(weapon_t) );
 melee->specific = (void *)mweapon;
 mweapon->min_damage = 1;
 mweapon->max_damage = 4;
 mweapon->clip_size = 0;
 mweapon->ammo_loaded = 0;
 mweapon->ammo_type = ((void *)0);
 mweapon->type = WEAPONTYPE_MELEE;
 mweapon->attack_name = "cut";
 list_add_head( player->inventory, melee );
 struct buf_t *weapon_name = bufnew( "Pistol" );
 player->in_hand = alloc_item( weapon_name );
 bufdestroy( weapon_name );
 player->in_hand->face = ')';
 player->in_hand->color = (((chtype)(((5))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8))) | ((chtype)((1U)) << ((13) + 8));
 player->in_hand->quantity = 1;
 player->in_hand->quality = 1.0f;
 player->in_hand->place = ITEMPLACE_ENTITY;
 player->in_hand->type = ITEMTYPE_WEAPON;
 player->in_hand->flags = (1<<0);
 struct weapon_t *weapon = malloc( sizeof(weapon_t) );
 player->in_hand->specific = (void *)weapon;
 weapon->min_damage = 2;
 weapon->max_damage = 6;
 weapon->clip_size = 5;
 weapon->ammo_loaded = 5;
 weapon->accuracy = 0.9;
 weapon->ammo_type = clone_item( (struct item_t *)list_get_index( ammo_type_list, 1 ) );
 weapon->type = WEAPONTYPE_HANDGUN;
 weapon->attack_name = "shoot";
 struct buf_t *armor_name = bufnew( "Leather jacket" );
 player->worn = alloc_item( armor_name );
 bufdestroy( armor_name );
 player->worn->face = '[';
 player->worn->color = (((chtype)(((4))) << ((0) + 8)) & ((chtype)((((1U) << 8) - 1U)) << ((0) + 8)));
 player->worn->quantity = 1;
 player->worn->quality = 1.0f;
 player->worn->place = ITEMPLACE_ENTITY;
 player->worn->type = ITEMTYPE_ARMOR;
 player->worn->flags = (1<<0);
 struct armor_t *armor = malloc( sizeof(armor_t) );
 player->worn->specific = (void *)armor;
 armor->ac = 5;
 player->natural = malloc( sizeof(weapon_t) );
 player->natural->min_damage = 2;
 player->natural->max_damage = 4;
 player->natural->clip_size = 0;
 player->natural->ammo_loaded = 0;
 player->natural->accuracy = 0.9;
 player->natural->ammo_type = ((void *)0);
 player->natural->attack_name = "punch";
 while( dungeon[player->z]->terrain[player->x][player->y] != &tile_floor )
 {
  player->x = rand() % 80;
  player->y = rand() % 21;
 }
 player->flags = (1<<0);
 player->agility = 15;
 player->ap = 0;
 list_add_head( entity_list, (void *)player );
 make_random_entities( 10 );
 make_random_objects( 20 );
 log_add( "Done creating new game.\n" );
}

variable_types:
seed
unsigned int

variable_types: struct item_t { struct buf_t { char *data; int length; } *name; int face; int quantity; float quality; int type; void *specific; int place; int x; int flags; } *

variable_types:
armor
struct armor_t { int ac; } *

user_defined_types: struct map_t { struct buf_t *name; int width; struct tile_t ***terrain; struct tile_t ***memory; int flags; }

user_defined_types: struct tile_t { char *name; int face; int fg; int flags; }


decompiled_code:
__int64 __fastcall init_game(int a1, __int64 a2)
{
const char **v2; // rbp
const char *v3; // rbx
unsigned int v4; // eax
__int64 result; // rax

if ( a1 > 1 )
{
v2 = (const char **)(a2 + 8);
do
{
v3 = *v2;
if ( strlen(*v2) <= 1 || *v3 != 45 || v3[1] != 100 )
{
printf("Invalid commandline arguments.");
exit(0);
}
++v2;
game_flags |= 1u;
}
while ( v2 != (const char **)(a2 + 8LL * (unsigned int)(a1 - 2) + 16) );
}
if ( !(unsigned int)init_ui() )
{
puts("Your terminal needs to be at least 80x25.");
exit(0);
}
open_logfile();
printf("Etraom version %s, by Vlad Dumitru.\n", "0.0.1");
message_list = alloc_list();
entity_list = alloc_list();
item_list = alloc_list();
link_list = alloc_list();
if ( (unsigned int)parse_entity_types("data/entities") == -1 )
{
log_add("FATAL: Couldn't open entity data file.\n");
exit(0);
}
if ( (unsigned int)parse_ammo_types("data/ammotypes") == -1 )
{
log_add("FATAL: Couldn't open ammo type data file.\n");
exit(0);
}
draw_title_screen();
v4 = time(0LL);
new_game(v4);
result = 1LL;
running = 1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(int a1, __int64 a2)
{
const char **v2; // rbp
const char *v3; // rbx
unsigned int v4; // eax
__int64 result; // rax

if ( a1 > 1 )
{
v2 = (const char **)(a2 + 8);
do
{
v3 = *v2;
if ( strlen(*v2) <= 1 || *v3 != 45 || v3[1] != 100 )
{
printf("Invalid commandline arguments.");
exit(0);
}
++v2;
game_flags |= 1u;
}
while ( v2 != (const char **)(a2 + 8LL * (unsigned int)(a1 - 2) + 16) );
}
if ( !(unsigned int)init_ui() )
{
puts("Your terminal needs to be at least 80x25.");
exit(0);
}
open_logfile();
printf("Etraom version %s, by Vlad Dumitru.\n", "0.0.1");
message_list = alloc_list();
entity_list = alloc_list();
item_list = alloc_list();
link_list = alloc_list();
if ( (unsigned int)parse_entity_types("data/entities") == -1 )
{
log_add("FATAL: Couldn't open entity data file.\n");
exit(0);
}
if ( (unsigned int)parse_ammo_types("data/ammotypes") == -1 )
{
log_add("FATAL: Couldn't open ammo type data file.\n");
exit(0);
}
draw_title_screen();
v4 = time(0LL);
func5(v4);
result = 1LL;
running = 1;
return result;
}

original_code:
int init_game( int argc, char** argv )
{
 int i;
 for( i = 1; i < argc; i++ )
 {
  if( strlen( argv[i] ) < 2 )
  {
   printf( "Invalid commandline arguments." );
   exit( 0 );
  }
  if( argv[i][0] == '-' )
  {
   if( argv[i][1] == 'd' )
   {
    game_flags |= (1<<0);
   }
   else
   {
    printf( "Invalid commandline arguments." );
    exit( 0 );
   }
  }
  else
  {
   printf( "Invalid commandline arguments." );
   exit( 0 );
  }
 }
 if( !init_ui() )
 {
  printf( "Your terminal needs to be at least 80x25.\n" );
  exit( 0 );
 }
 open_logfile();
 printf( "Etraom version %s, by Vlad Dumitru.\n", "0.0.1" );
 message_list = alloc_list();
 entity_list = alloc_list();
 item_list = alloc_list();
 link_list = alloc_list();
 if( parse_entity_types( "data/entities" ) == -1 )
 {
  log_add( "FATAL: Couldn't open entity data file.\n" );
  exit( 0 );
 }
 if( parse_ammo_types( "data/ammotypes" ) == -1 )
 {
  log_add( "FATAL: Couldn't open ammo type data file.\n" );
  exit( 0 );
 }
 draw_title_screen();
 new_game( time( 0 ) );
 running = 1;
 return 1;
}

canonical_original_code:
int init_game(int argc, char **argv)
{
 int i;
 for( i = 1; i < argc; i++ )
 {
  if( strlen( argv[i] ) < 2 )
  {
   printf( "Invalid commandline arguments." );
   exit( 0 );
  }
  if( argv[i][0] == '-' )
  {
   if( argv[i][1] == 'd' )
   {
    game_flags |= (1<<0);
   }
   else
   {
    printf( "Invalid commandline arguments." );
    exit( 0 );
   }
  }
  else
  {
   printf( "Invalid commandline arguments." );
   exit( 0 );
  }
 }
 if( !init_ui() )
 {
  printf( "Your terminal needs to be at least 80x25.\n" );
  exit( 0 );
 }
 open_logfile();
 printf( "Etraom version %s, by Vlad Dumitru.\n", "0.0.1" );
 message_list = alloc_list();
 entity_list = alloc_list();
 item_list = alloc_list();
 link_list = alloc_list();
 if( parse_entity_types( "data/entities" ) == -1 )
 {
  log_add( "FATAL: Couldn't open entity data file.\n" );
  exit( 0 );
 }
 if( parse_ammo_types( "data/ammotypes" ) == -1 )
 {
  log_add( "FATAL: Couldn't open ammo type data file.\n" );
  exit( 0 );
 }
 draw_title_screen();
 new_game( time( 0 ) );
 running = 1;
 return 1;
}

variable_types: argc int

variable_types:
argv
char **


decompiled_code:
__int64 __fastcall push_message(const char **a1)
{
_DWORD *v1; // rbp
__int64 v2; // rax
const char *v3; // rsi

v1 = malloc(0x10uLL);
v2 = bufcpy(a1);
v3 = *a1;
v1[2] = 1;
*(_QWORD *)v1 = v2;
v1[3] = player_turns;
log_add("[message] %s\n", v3);
return list_add_tail(message_list, v1);
}

canonical_decompiled_code:
__int64 __fastcall func0(const char **a1)
{
_DWORD *v1; // rbp
__int64 v2; // rax
const char *v3; // rsi

v1 = malloc(0x10uLL);
v2 = bufcpy(a1);
v3 = *a1;
v1[2] = 1;
*(_QWORD *)v1 = v2;
v1[3] = player_turns;
log_add("[message] %s\n", v3);
return list_add_tail(message_list, v1);
}

original_code:
void push_message( buf_t *b )
{
 message_t *m = malloc( sizeof(message_t) );
 m->msg = bufcpy( b );
 m->flags = (1<<0);
 m->turn = player_turns;
 log_add( "[message] %s\n", b->data );
 list_add_tail( message_list, (void*)m );
}

canonical_original_code:
void push_message(struct buf_t *b)
{
 struct message_t *m = malloc( sizeof(message_t) );
 m->msg = bufcpy( b );
 m->flags = (1<<0);
 m->turn = player_turns;
 log_add( "[message] %s\n", b->data );
 list_add_tail( message_list, (void *)m );
}

variable_types: struct message_t { struct buf_t { char *data; int length; } *msg; int flags; int turn; } *

user_defined_types: struct message_t { struct buf_t *msg; int flags; int turn; }


decompiled_code:
void __fastcall free_message(void *ptr)
{
bufdestroy(*(_QWORD *)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
bufdestroy(*(_QWORD *)ptr);
free(ptr);
}

original_code:
void free_message( message_t *m )
{
 bufdestroy( m->msg );
 free( m );
}

canonical_original_code:
void free_message(struct message_t *m)
{
 bufdestroy( m->msg );
 free( m );
}


decompiled_code:
void free_messages()
{
__int64 v0; // rbx
void **v1; // rax

v0 = *(_QWORD *)message_list;
while ( v0 )
{
v1 = (void **)v0;
v0 = *(_QWORD *)(v0 + 8);
free_message(*v1);
}
}

canonical_decompiled_code:
void func2()
{
__int64 v0; // rbx
void **v1; // rax

v0 = *(_QWORD *)message_list;
while ( v0 )
{
v1 = (void **)v0;
v0 = *(_QWORD *)(v0 + 8);
func1(*v1);
}
}

original_code:
void free_messages( void )
{
 list_element *m = message_list->head, *temp;
 while( m )
 {
  temp = m;
  m = m->next;
  free_message( (message_t*)temp->data );
 }
}

canonical_original_code:
void free_messages()
{
 struct _list_element *m = message_list->head; struct _list_element *temp;
 while( m )
 {
  temp = m;
  m = m->next;
  free_message( (struct message_t *)temp->data );
 }
}

variable_types: struct _list_element { void *data; struct _list_element *next; } *


decompiled_code:
__int64 __fastcall move_relative(__int64 a1, int a2, int a3)
{
unsigned int v6; // er12
__int64 v7; // rdx
__int64 v8; // rdi
__int64 v9; // rsi
__int64 v11; // rsi
__int64 v12; // rbp

v6 = is_legal((unsigned int)(a2 + *(_DWORD *)(a1 + 32)), (unsigned int)(a3 + *(_DWORD *)(a1 + 36)));
if ( !v6 )
return v6;
v7 = *(int *)(a1 + 40);
v8 = (unsigned int)(a2 + *(_DWORD *)(a1 + 32));
v9 = (unsigned int)(a3 + *(_DWORD *)(a1 + 36));
if ( (*(_BYTE *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(dungeon + 8LL * *(int *)(a1 + 40)) + 16LL)
+ 8LL * (int)v8)
+ 8LL * (int)v9)
+ 16LL) & 1) != 0 )
{
v6 = 0;
if ( player == a1 )
{
v12 = bufnew("Yep, it's solid alright.", v9, v7);
push_message(v12);
bufdestroy(v12);
}
return v6;
}
v11 = entity_find_by_position(v8, v9, v7);
if ( !v11 )
{
v6 = 1;
log_add(
"[entity_move_rel] Entity 0x%08x('%s') has moved to (%i, %i, %i)\n",
a1,
**(const char ***)a1,
(unsigned int)(a2 + *(_DWORD *)(a1 + 32)),
(unsigned int)(a3 + *(_DWORD *)(a1 + 36)),
*(unsigned int *)(a1 + 40));
*(_DWORD *)(a1 + 32) += a2;
*(_DWORD *)(a1 + 36) += a3;
return v6;
}
melee_attack(a1, v11);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, int a2, int a3)
{
unsigned int v6; // er12
__int64 v7; // rdx
__int64 v8; // rdi
__int64 v9; // rsi
__int64 v11; // rsi
__int64 v12; // rbp

v6 = is_legal((unsigned int)(a2 + *(_DWORD *)(a1 + 32)), (unsigned int)(a3 + *(_DWORD *)(a1 + 36)));
if ( !v6 )
return v6;
v7 = *(int *)(a1 + 40);
v8 = (unsigned int)(a2 + *(_DWORD *)(a1 + 32));
v9 = (unsigned int)(a3 + *(_DWORD *)(a1 + 36));
if ( (*(_BYTE *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(dungeon + 8LL * *(int *)(a1 + 40)) + 16LL)
+ 8LL * (int)v8)
+ 8LL * (int)v9)
+ 16LL) & 1) != 0 )
{
v6 = 0;
if ( player == a1 )
{
v12 = bufnew("Yep, it's solid alright.", v9, v7);
push_message(v12);
bufdestroy(v12);
}
return v6;
}
v11 = entity_find_by_position(v8, v9, v7);
if ( !v11 )
{
v6 = 1;
log_add(
"[entity_move_rel] Entity 0x%08x('%s') has moved to (%i, %i, %i)\n",
a1,
**(const char ***)a1,
(unsigned int)(a2 + *(_DWORD *)(a1 + 32)),
(unsigned int)(a3 + *(_DWORD *)(a1 + 36)),
*(unsigned int *)(a1 + 40));
*(_DWORD *)(a1 + 32) += a2;
*(_DWORD *)(a1 + 36) += a3;
return v6;
}
melee_attack(a1, v11);
return 1LL;
}

original_code:
int move_relative( entity_t *e, int dx, int dy )
{
 if( is_legal( e->x+dx, e->y+dy ) )
 {
  if( dungeon[e->z]->terrain[e->x+dx][e->y+dy]->flags & (1<<0) )
  {
   if( e == player )
   {
    buf_t *msg = bufnew( "Yep, it's solid alright." );
    push_message( msg );
    bufdestroy( msg );
   }
   return 0;
  }
  else
  {
   entity_t *ee = entity_find_by_position( e->x+dx, e->y+dy, e->z );
   if( ee )
   {
    melee_attack( e, ee );
    return 1;
   }
   else
   {
    log_add( "[entity_move_rel] Entity 0x%08x('%s') has moved to "
     "(%i, %i, %i)\n", e, e->name->data, e->x+dx, e->y+dy, e->z );
    e->x += dx;
    e->y += dy;
    return 1;
   }
  }
 }
 return 0;
}

canonical_original_code:
int move_relative(struct entity_t *e, int dx, int dy)
{
 if( is_legal( e->x+dx, e->y+dy ) )
 {
  if( dungeon[e->z]->terrain[e->x+dx][e->y+dy]->flags & (1<<0) )
  {
   if( e == player )
   {
    struct buf_t *msg = bufnew( "Yep, it's solid alright." );
    push_message( msg );
    bufdestroy( msg );
   }
   return 0;
  }
  else
  {
   struct entity_t *ee = entity_find_by_position( e->x+dx, e->y+dy, e->z );
   if( ee )
   {
    melee_attack( e, ee );
    return 1;
   }
   else
   {
    log_add( "[entity_move_rel] Entity 0x%08x('%s') has moved to "
     "(%i, %i, %i)\n", e, e->name->data, e->x+dx, e->y+dy, e->z );
    e->x += dx;
    e->y += dy;
    return 1;
   }
  }
 }
 return 0;
}

variable_types: dx int

variable_types: dy int


decompiled_code:
__int64 __fastcall open_door(int *a1, unsigned int a2, unsigned int a3)
{
__int64 v4; // rbp
__int64 v5; // rbx
__int64 v6; // rdi
__int64 v7; // rsi
unsigned int v8; // er12
__int64 v9; // rcx
__int64 v10; // rdx
void **v11; // rax
const char *v13; // rdi
__int64 v14; // rax
__int64 v15; // rbp
__int64 v16; // rbp

v4 = (int)a2;
v5 = (int)a3;
v6 = a2;
v7 = a3;
v8 = is_legal(v6, a3);
if ( !v8 )
return v8;
v9 = a1[10];
v10 = player;
v11 = (void **)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(dungeon + 8 * v9) + 16LL) + 8 * v4) + 8 * v5);
if ( *v11 != &tile_door_closed )
{
v8 = 0;
if ( a1 == (int *)player )
{
v16 = bufnew("There's no closed door there.", v7, player);
push_message(v16);
bufdestroy(v16);
}
return v8;
}
*v11 = &tile_door_open;
v13 = "You open the door.";
if ( a1 != (int *)v10 )
{
v14 = *(_QWORD *)(v10 + 48);
v7 = a1[8];
v13 = "You hear a door open.";
v10 = a1[9];
if ( *(float *)(*(_QWORD *)(*(_QWORD *)(v14 + 8 * v9) + 8 * v7) + 4 * v10) > 0.0 )
v13 = "A door opens.";
}
v15 = bufnew(v13, v7, v10);
push_message(v15);
bufdestroy(v15);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(int *a1, unsigned int a2, unsigned int a3)
{
__int64 v4; // rbp
__int64 v5; // rbx
__int64 v6; // rdi
__int64 v7; // rsi
unsigned int v8; // er12
__int64 v9; // rcx
__int64 v10; // rdx
void **v11; // rax
const char *v13; // rdi
__int64 v14; // rax
__int64 v15; // rbp
__int64 v16; // rbp

v4 = (int)a2;
v5 = (int)a3;
v6 = a2;
v7 = a3;
v8 = is_legal(v6, a3);
if ( !v8 )
return v8;
v9 = a1[10];
v10 = player;
v11 = (void **)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(dungeon + 8 * v9) + 16LL) + 8 * v4) + 8 * v5);
if ( *v11 != &tile_door_closed )
{
v8 = 0;
if ( a1 == (int *)player )
{
v16 = bufnew("There's no closed door there.", v7, player);
push_message(v16);
bufdestroy(v16);
}
return v8;
}
*v11 = &tile_door_open;
v13 = "You open the door.";
if ( a1 != (int *)v10 )
{
v14 = *(_QWORD *)(v10 + 48);
v7 = a1[8];
v13 = "You hear a door open.";
v10 = a1[9];
if ( *(float *)(*(_QWORD *)(*(_QWORD *)(v14 + 8 * v9) + 8 * v7) + 4 * v10) > 0.0 )
v13 = "A door opens.";
}
v15 = bufnew(v13, v7, v10);
push_message(v15);
bufdestroy(v15);
return 1LL;
}

original_code:
int open_door( entity_t *e, int x, int y )
{
 if( !is_legal( x, y ) )
  return 0;
 if( dungeon[e->z]->terrain[x][y] == &tile_door_closed )
 {
  dungeon[e->z]->terrain[x][y] = &tile_door_open;
  if( e == player )
  {
   buf_t *msg = bufnew( "You open the door." );
   push_message( msg );
   bufdestroy( msg );
  }
  else
  {
   if( player->lightmap[e->z][e->x][e->y] > 0.0f )
   {
    buf_t *msg = bufnew( "A door opens." );
    push_message( msg );
    bufdestroy( msg );
   }
   else
   {
    buf_t *msg = bufnew( "You hear a door open." );
    push_message( msg );
    bufdestroy( msg );
   }
  }
  return 1;
 }
 else
 {
  if( e == player )
  {
   buf_t *msg = bufnew( "There's no closed door there." );
   push_message( msg );
   bufdestroy( msg );
  }
  return 0;
 }
}

canonical_original_code:
int open_door(struct entity_t *e, int x, int y)
{
 if( !is_legal( x, y ) )
  return 0;
 if( dungeon[e->z]->terrain[x][y] == &tile_door_closed )
 {
  dungeon[e->z]->terrain[x][y] = &tile_door_open;
  if( e == player )
  {
   struct buf_t *msg = bufnew( "You open the door." );
   push_message( msg );
   bufdestroy( msg );
  }
  else
  {
   if( player->lightmap[e->z][e->x][e->y] > 0.0f )
   {
    struct buf_t *msg = bufnew( "A door opens." );
    push_message( msg );
    bufdestroy( msg );
   }
   else
   {
    struct buf_t *msg = bufnew( "You hear a door open." );
    push_message( msg );
    bufdestroy( msg );
   }
  }
  return 1;
 }
 else
 {
  if( e == player )
  {
   struct buf_t *msg = bufnew( "There's no closed door there." );
   push_message( msg );
   bufdestroy( msg );
  }
  return 0;
 }
}

variable_types: x int

variable_types: y int


decompiled_code:
__int64 __fastcall close_door(int *a1, unsigned int a2, unsigned int a3)
{
__int64 v4; // rbp
__int64 v5; // rbx
__int64 v6; // rdi
__int64 v7; // rsi
unsigned int v8; // er12
__int64 v9; // rcx
__int64 v10; // rdx
void **v11; // rax
const char *v13; // rdi
__int64 v14; // rax
__int64 v15; // rbp
__int64 v16; // rbp

v4 = (int)a2;
v5 = (int)a3;
v6 = a2;
v7 = a3;
v8 = is_legal(v6, a3);
if ( !v8 )
return v8;
v9 = a1[10];
v10 = player;
v11 = (void **)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(dungeon + 8 * v9) + 16LL) + 8 * v4) + 8 * v5);
if ( *v11 != &tile_door_open )
{
v8 = 0;
if ( a1 == (int *)player )
{
v16 = bufnew("There's no open door there.", v7, player);
push_message(v16);
bufdestroy(v16);
}
return v8;
}
*v11 = &tile_door_closed;
v13 = "You close the door.";
if ( a1 != (int *)v10 )
{
v14 = *(_QWORD *)(v10 + 48);
v7 = a1[8];
v13 = "You hear a door close.";
v10 = a1[9];
if ( *(float *)(*(_QWORD *)(*(_QWORD *)(v14 + 8 * v9) + 8 * v7) + 4 * v10) > 0.0 )
v13 = "A door closes.";
}
v15 = bufnew(v13, v7, v10);
push_message(v15);
bufdestroy(v15);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(int *a1, unsigned int a2, unsigned int a3)
{
__int64 v4; // rbp
__int64 v5; // rbx
__int64 v6; // rdi
__int64 v7; // rsi
unsigned int v8; // er12
__int64 v9; // rcx
__int64 v10; // rdx
void **v11; // rax
const char *v13; // rdi
__int64 v14; // rax
__int64 v15; // rbp
__int64 v16; // rbp

v4 = (int)a2;
v5 = (int)a3;
v6 = a2;
v7 = a3;
v8 = is_legal(v6, a3);
if ( !v8 )
return v8;
v9 = a1[10];
v10 = player;
v11 = (void **)(*(_QWORD *)(*(_QWORD *)(*(_QWORD *)(dungeon + 8 * v9) + 16LL) + 8 * v4) + 8 * v5);
if ( *v11 != &tile_door_open )
{
v8 = 0;
if ( a1 == (int *)player )
{
v16 = bufnew("There's no open door there.", v7, player);
push_message(v16);
bufdestroy(v16);
}
return v8;
}
*v11 = &tile_door_closed;
v13 = "You close the door.";
if ( a1 != (int *)v10 )
{
v14 = *(_QWORD *)(v10 + 48);
v7 = a1[8];
v13 = "You hear a door close.";
v10 = a1[9];
if ( *(float *)(*(_QWORD *)(*(_QWORD *)(v14 + 8 * v9) + 8 * v7) + 4 * v10) > 0.0 )
v13 = "A door closes.";
}
v15 = bufnew(v13, v7, v10);
push_message(v15);
bufdestroy(v15);
return 1LL;
}

original_code:
int close_door( entity_t *e, int x, int y )
{
 if( !is_legal( x, y ) )
  return 0;
 if( dungeon[e->z]->terrain[x][y] == &tile_door_open )
 {
  dungeon[e->z]->terrain[x][y] = &tile_door_closed;
  if( e == player )
  {
   buf_t *msg = bufnew( "You close the door." );
   push_message( msg );
   bufdestroy( msg );
  }
  else
  {
   if( player->lightmap[e->z][e->x][e->y] > 0.0f )
   {
    buf_t *msg = bufnew( "A door closes." );
    push_message( msg );
    bufdestroy( msg );
   }
   else
   {
    buf_t *msg = bufnew( "You hear a door close." );
    push_message( msg );
    bufdestroy( msg );
   }
  }
  return 1;
 }
 else
 {
  if( e == player )
  {
   buf_t *msg = bufnew( "There's no open door there." );
   push_message( msg );
   bufdestroy( msg );
  }
  return 0;
 }
}

canonical_original_code:
int close_door(struct entity_t *e, int x, int y)
{
 if( !is_legal( x, y ) )
  return 0;
 if( dungeon[e->z]->terrain[x][y] == &tile_door_open )
 {
  dungeon[e->z]->terrain[x][y] = &tile_door_closed;
  if( e == player )
  {
   struct buf_t *msg = bufnew( "You close the door." );
   push_message( msg );
   bufdestroy( msg );
  }
  else
  {
   if( player->lightmap[e->z][e->x][e->y] > 0.0f )
   {
    struct buf_t *msg = bufnew( "A door closes." );
    push_message( msg );
    bufdestroy( msg );
   }
   else
   {
    struct buf_t *msg = bufnew( "You hear a door close." );
    push_message( msg );
    bufdestroy( msg );
   }
  }
  return 1;
 }
 else
 {
  if( e == player )
  {
   struct buf_t *msg = bufnew( "There's no open door there." );
   push_message( msg );
   bufdestroy( msg );
  }
  return 0;
 }
}


decompiled_code:
__int64 __fastcall follow_stairs(unsigned int *a1)
{
__int64 v1; // rsi
_DWORD *v2; // rax
__int64 v3; // rdx
__int64 v4; // rdx
int v5; // eax
__int64 v6; // rbp

v1 = a1[9];
v2 = (_DWORD *)link_find_by_position(a1[8], v1, a1[10]);
if ( v2 )
{
v4 = player;
*(_DWORD *)(player + 32LL) = v2[3];
*(_DWORD *)(v4 + 36) = v2[4];
*(_DWORD *)(v4 + 40) = v2[5];
v2[8] &= 1u;
v5 = v2[6];
if ( v5 == 62 )
{
v6 = bufnew("You descend.", v1, v4);
}
else if ( v5 == 60 )
{
v6 = bufnew("You ascend.", v1, v4);
}
else
{
v6 = bufnew("Bug.", v1, v4);
}
}
else
{
v6 = bufnew("There are no stairs here.", v1, v3);
}
push_message(v6);
bufdestroy(v6);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(unsigned int *a1)
{
__int64 v1; // rsi
_DWORD *v2; // rax
__int64 v3; // rdx
__int64 v4; // rdx
int v5; // eax
__int64 v6; // rbp

v1 = a1[9];
v2 = (_DWORD *)link_find_by_position(a1[8], v1, a1[10]);
if ( v2 )
{
v4 = player;
*(_DWORD *)(player + 32LL) = v2[3];
*(_DWORD *)(v4 + 36) = v2[4];
*(_DWORD *)(v4 + 40) = v2[5];
v2[8] &= 1u;
v5 = v2[6];
if ( v5 == 62 )
{
v6 = bufnew("You descend.", v1, v4);
}
else if ( v5 == 60 )
{
v6 = bufnew("You ascend.", v1, v4);
}
else
{
v6 = bufnew("Bug.", v1, v4);
}
}
else
{
v6 = bufnew("There are no stairs here.", v1, v3);
}
push_message(v6);
bufdestroy(v6);
return 0LL;
}

original_code:
int follow_stairs( entity_t *e )
{
 link_t *l = link_find_by_position( e->x, e->y, e->z );
 if( l )
 {
  player->x = l->dest_x;
  player->y = l->dest_y;
  player->z = l->dest_z;
  l->flags &= (1<<0);
  buf_t *b;
  if( l->face == '>' )
  {
   b = bufnew( "You descend." );
  }
  else if( l->face == '<' )
  {
   b = bufnew( "You ascend." );
  }
  else
  {
   b = bufnew( "Bug." );
  }
  push_message( b );
  bufdestroy( b );
  return 0;
 }
 else
 {
  buf_t *b = bufnew( "There are no stairs here." );
  push_message( b );
  bufdestroy( b );
  return 0;
 }
}

canonical_original_code:
int follow_stairs(struct entity_t *e)
{
 struct link_t *l = link_find_by_position( e->x, e->y, e->z );
 if( l )
 {
  player->x = l->dest_x;
  player->y = l->dest_y;
  player->z = l->dest_z;
  l->flags &= (1<<0);
  struct buf_t *b;
  if( l->face == '>' )
  {
   b = bufnew( "You descend." );
  }
  else if( l->face == '<' )
  {
   b = bufnew( "You ascend." );
  }
  else
  {
   b = bufnew( "Bug." );
  }
  push_message( b );
  bufdestroy( b );
  return 0;
 }
 else
 {
  struct buf_t *b = bufnew( "There are no stairs here." );
  push_message( b );
  bufdestroy( b );
  return 0;
 }
}

variable_types: struct link_t { int src_x; int dest_x; int face; int flags; } *