decompiled_code:
void __fastcall process_cheat_gs1(__int64 a1)
{
__int64 *v1; // r12
__int64 v2; // r14
__int64 v3; // r13
__int64 v4; // rbp
__int64 *v5; // rbx
unsigned __int64 v6; // r15
__int64 v7; // rdi
__int64 v8; // r13
__int64 v9; // r15
__int64 v11; // [rsp+10h] [rbp-48h]
__int64 v12; // [rsp+18h] [rbp-40h]

if ( *(_QWORD *)(a1 + 2080) )
{
v1 = (__int64 *)(a1 + 32);
v2 = 0LL;
while ( 1 )
{
v3 = *v1;
v4 = v1[1];
v5 = v1 + 2;
v6 = *v1 & 0xFFFFFFF;
switch ( (unsigned __int64)*v1 >> 28 )
{
case 0uLL:
write_memory8(*v1 & 0xFFFFFFF, (unsigned __int8)v4);
break;
case 1uLL:
write_memory16(*v1 & 0xFFFFFFF, (unsigned __int16)v4);
break;
case 2uLL:
write_memory32(*v1 & 0xFFFFFFF, v1[1]);
break;
case 3uLL:
v11 = (unsigned __int16)v3;
if ( (_WORD)v3 )
{
v12 = 2 * ((unsigned __int16)v3 + 1LL);
do
{
v7 = *v5;
v8 = v5[1];
v5 += 2;
write_memory32(v7, v4);
if ( v8 )
write_memory32(v8, v4);
}
while ( &v1[v12] != v5 );
v5 = &v1[v12];
v2 += v11;
}
break;
case 0xDuLL:
if ( read_memory16(*v1 & 0xFFFFFFF) != (unsigned __int16)v4 )
{
v5 = v1 + 4;
++v2;
}
break;
case 0xEuLL:
if ( read_memory16(v1[1] & 0xFFFFFFF) != (unsigned __int16)v3 )
{
v9 = (v6 >> 16) & 3;
v5 += 2 * v9;
v2 += v9;
}
break;
default:
break;
}
if ( *(_QWORD *)(a1 + 2080) <= (unsigned __int64)++v2 )
break;
v1 = v5;
}
}
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1)
{
__int64 *v1; // r12
__int64 v2; // r14
__int64 v3; // r13
__int64 v4; // rbp
__int64 *v5; // rbx
unsigned __int64 v6; // r15
__int64 v7; // rdi
__int64 v8; // r13
__int64 v9; // r15
__int64 v11; // [rsp+10h] [rbp-48h]
__int64 v12; // [rsp+18h] [rbp-40h]

if ( *(_QWORD *)(a1 + 2080) )
{
v1 = (__int64 *)(a1 + 32);
v2 = 0LL;
while ( 1 )
{
v3 = *v1;
v4 = v1[1];
v5 = v1 + 2;
v6 = *v1 & 0xFFFFFFF;
switch ( (unsigned __int64)*v1 >> 28 )
{
case 0uLL:
write_memory8(*v1 & 0xFFFFFFF, (unsigned __int8)v4);
break;
case 1uLL:
write_memory16(*v1 & 0xFFFFFFF, (unsigned __int16)v4);
break;
case 2uLL:
write_memory32(*v1 & 0xFFFFFFF, v1[1]);
break;
case 3uLL:
v11 = (unsigned __int16)v3;
if ( (_WORD)v3 )
{
v12 = 2 * ((unsigned __int16)v3 + 1LL);
do
{
v7 = *v5;
v8 = v5[1];
v5 += 2;
write_memory32(v7, v4);
if ( v8 )
write_memory32(v8, v4);
}
while ( &v1[v12] != v5 );
v5 = &v1[v12];
v2 += v11;
}
break;
case 0xDuLL:
if ( read_memory16(*v1 & 0xFFFFFFF) != (unsigned __int16)v4 )
{
v5 = v1 + 4;
++v2;
}
break;
case 0xEuLL:
if ( read_memory16(v1[1] & 0xFFFFFFF) != (unsigned __int16)v3 )
{
v9 = (v6 >> 16) & 3;
v5 += 2 * v9;
v2 += v9;
}
break;
default:
break;
}
if ( *(_QWORD *)(a1 + 2080) <= (unsigned __int64)++v2 )
break;
v1 = v5;
}
}
}

original_code:
void process_cheat_gs1(cheat_type *cheat)
{
  u32 cheat_opcode;
  u32 *code_ptr = cheat->cheat_codes;
  u32 address, value;
  u32 i;
  for(i = 0; i < cheat->num_cheat_lines; i++)
  {
    address = code_ptr[0];
    value = code_ptr[1];
    code_ptr += 2;
    cheat_opcode = address >> 28;
    address &= 0xFFFFFFF;
    switch(cheat_opcode)
    {
      case 0x0:
        write_memory8(address, value);
        break;
      case 0x1:
        write_memory16(address, value);
        break;
      case 0x2:
        write_memory32(address, value);
        break;
      case 0x3:
      {
        u32 num_addresses = address & 0xFFFF;
        u32 address1, address2;
        u32 i2;
        for(i2 = 0; i2 < num_addresses; i2++)
        {
          address1 = code_ptr[0];
          address2 = code_ptr[1];
          code_ptr += 2;
          i++;
          write_memory32(address1, value);
          if(address2 != 0)
            write_memory32(address2, value);
        }
        break;
      }
      case 0x6:
        break;
      case 0x8:
        break;
      case 0xD:
        if(read_memory16(address) != (value & 0xFFFF))
        {
          code_ptr += 2;
          i++;
        }
        break;
      case 0xE:
        if(read_memory16(value & 0xFFFFFFF) != (address & 0xFFFF))
        {
          u32 skip = ((address >> 16) & 0x03);
          code_ptr += skip * 2;
          i += skip;
        }
        break;
      case 0x0F:
        break;
    }
  }
}

canonical_original_code:
void process_cheat_gs1(struct cheat_type *cheat)
{
  unsigned long cheat_opcode;
  unsigned long *code_ptr = cheat->cheat_codes;
  unsigned long address; unsigned long value;
  unsigned long i;
  for(i = 0; i < cheat->num_cheat_lines; i++)
  {
    address = code_ptr[0];
    value = code_ptr[1];
    code_ptr += 2;
    cheat_opcode = address >> 28;
    address &= 0xFFFFFFF;
    switch(cheat_opcode)
    {
      case 0x0:
        write_memory8(address, value);
        break;
      case 0x1:
        write_memory16(address, value);
        break;
      case 0x2:
        write_memory32(address, value);
        break;
      case 0x3:
      {
        unsigned long num_addresses = address & 0xFFFF;
        unsigned long address1; unsigned long address2;
        unsigned long i2;
        for(i2 = 0; i2 < num_addresses; i2++)
        {
          address1 = code_ptr[0];
          address2 = code_ptr[1];
          code_ptr += 2;
          i++;
          write_memory32(address1, value);
          if(address2 != 0)
            write_memory32(address2, value);
        }
        break;
      }
      case 0x6:
        break;
      case 0x8:
        break;
      case 0xD:
        if(read_memory16(address) != (value & 0xFFFF))
        {
          code_ptr += 2;
          i++;
        }
        break;
      case 0xE:
        if(read_memory16(value & 0xFFFFFFF) != (address & 0xFFFF))
        {
          unsigned long skip = ((address >> 16) & 0x03);
          code_ptr += skip * 2;
          i += skip;
        }
        break;
      case 0x0F:
        break;
    }
  }
}

variable_types: struct cheat_type { unsigned char cheat_name[17]; unsigned long cheat_active; unsigned long cheat_codes[256]; unsigned long num_cheat_lines; enum cheat_variant_enum { CHEAT_TYPE_GAMESHARK_V1=0, CHEAT_TYPE_GAMESHARK_V3=1, CHEAT_TYPE_INVALID=2 } cheat_variant; } *

variable_types:
address
unsigned long

variable_types:
value
unsigned long

variable_types:
skip
unsigned long

user_defined_types: struct cheat_type { unsigned char cheat_name[17]; unsigned long cheat_active; unsigned long cheat_codes[256]; unsigned long num_cheat_lines; enum cheat_variant_enum cheat_variant; }


original_code:
void process_cheat_gs3(cheat_type *cheat)
{
  u32 cheat_opcode;
  u32 *code_ptr = cheat->cheat_codes;
  u32 address, value;
  u32 i;
  for(i = 0; i < cheat->num_cheat_lines; i++)
  {
    address = code_ptr[0];
    value = code_ptr[1];
    code_ptr += 2;
    cheat_opcode = address >> 28;
    address &= 0xFFFFFFF;
    switch(cheat_opcode)
    {
      case 0x0:
        cheat_opcode = address >> 24;
        address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
        switch(cheat_opcode)
        {
          case 0x0:
          {
            u32 iterations = value >> 24;
            u32 i2;
            value &= 0xFF;
            for(i2 = 0; i2 <= iterations; i2++, address++)
            {
              write_memory8(address, value);
            }
            break;
          }
          case 0x2:
          {
            u32 iterations = value >> 16;
            u32 i2;
            value &= 0xFFFF;
            for(i2 = 0; i2 <= iterations; i2++, address += 2)
            {
              write_memory16(address, value);
            }
            break;
          }
          case 0x4:
            write_memory32(address, value);
            break;
        }
        break;
      case 0x4:
        cheat_opcode = address >> 24;
        address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
        switch(cheat_opcode)
        {
          case 0x0:
            address = read_memory32(address) + (value >> 24);
            write_memory8(address, value & 0xFF);
            break;
          case 0x2:
            address = read_memory32(address) + ((value >> 16) * 2);
            write_memory16(address, value & 0xFFFF);
            break;
          case 0x4:
            address = read_memory32(address);
            write_memory32(address, value);
            break;
        }
        break;
      case 0x8:
        cheat_opcode = address >> 24;
        address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
        switch(cheat_opcode)
        {
          case 0x0:
            value = (value & 0xFF) + read_memory8(address);
            write_memory8(address, value);
            break;
          case 0x2:
            value = (value & 0xFFFF) + read_memory16(address);
            write_memory16(address, value);
            break;
          case 0x4:
            value = value + read_memory32(address);
            write_memory32(address, value);
            break;
        }
        break;
      case 0xC:
        cheat_opcode = address >> 24;
        address = (address & 0xFFFFFF) + 0x4000000;
        switch(cheat_opcode)
        {
          case 0x6:
            write_memory16(address, value);
            break;
          case 0x7:
            write_memory32(address, value);
            break;
        }
        break;
    }
  }
}

canonical_original_code:
void process_cheat_gs3(struct cheat_type *cheat)
{
  unsigned long cheat_opcode;
  unsigned long *code_ptr = cheat->cheat_codes;
  unsigned long address; unsigned long value;
  unsigned long i;
  for(i = 0; i < cheat->num_cheat_lines; i++)
  {
    address = code_ptr[0];
    value = code_ptr[1];
    code_ptr += 2;
    cheat_opcode = address >> 28;
    address &= 0xFFFFFFF;
    switch(cheat_opcode)
    {
      case 0x0:
        cheat_opcode = address >> 24;
        address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
        switch(cheat_opcode)
        {
          case 0x0:
          {
            unsigned long iterations = value >> 24;
            unsigned long i2;
            value &= 0xFF;
            for(i2 = 0; i2 <= iterations; i2++, address++)
            {
              write_memory8(address, value);
            }
            break;
          }
          case 0x2:
          {
            unsigned long iterations = value >> 16;
            unsigned long i2;
            value &= 0xFFFF;
            for(i2 = 0; i2 <= iterations; i2++, address += 2)
            {
              write_memory16(address, value);
            }
            break;
          }
          case 0x4:
            write_memory32(address, value);
            break;
        }
        break;
      case 0x4:
        cheat_opcode = address >> 24;
        address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
        switch(cheat_opcode)
        {
          case 0x0:
            address = read_memory32(address) + (value >> 24);
            write_memory8(address, value & 0xFF);
            break;
          case 0x2:
            address = read_memory32(address) + ((value >> 16) * 2);
            write_memory16(address, value & 0xFFFF);
            break;
          case 0x4:
            address = read_memory32(address);
            write_memory32(address, value);
            break;
        }
        break;
      case 0x8:
        cheat_opcode = address >> 24;
        address = (address & 0xFFFFF) + ((address << 4) & 0xF000000);
        switch(cheat_opcode)
        {
          case 0x0:
            value = (value & 0xFF) + read_memory8(address);
            write_memory8(address, value);
            break;
          case 0x2:
            value = (value & 0xFFFF) + read_memory16(address);
            write_memory16(address, value);
            break;
          case 0x4:
            value = value + read_memory32(address);
            write_memory32(address, value);
            break;
        }
        break;
      case 0xC:
        cheat_opcode = address >> 24;
        address = (address & 0xFFFFFF) + 0x4000000;
        switch(cheat_opcode)
        {
          case 0x6:
            write_memory16(address, value);
            break;
          case 0x7:
            write_memory32(address, value);
            break;
        }
        break;
    }
  }
}

variable_types:
i
unsigned long

variable_types:
iterations
unsigned long

return_type: void

user_defined_types: enum cheat_variant_enum { CHEAT_TYPE_GAMESHARK_V1=0, CHEAT_TYPE_GAMESHARK_V3=1, CHEAT_TYPE_INVALID=2 }


decompiled_code:
void process_cheats()
{
__int64 *v0; // rbx
unsigned __int64 v1; // rbp
int v2; // eax

if ( num_cheats )
{
v0 = cheats;
v1 = 0LL;
do
{
if ( v0[3] )
{
v2 = *((_DWORD *)v0 + 522);
if ( v2 )
{
if ( v2 == 1 )
process_cheat_gs3((__int64)v0);
}
else
{
process_cheat_gs1((__int64)v0);
}
}
++v1;
v0 += 262;
}
while ( num_cheats > v1 );
}
}

original_code:
void process_cheats()
{
  u32 i;
  for(i = 0; i < num_cheats; i++)
  {
    if(cheats[i].cheat_active)
    {
      switch(cheats[i].cheat_variant)
      {
        case CHEAT_TYPE_GAMESHARK_V1:
          process_cheat_gs1(cheats + i);
          break;
        case CHEAT_TYPE_GAMESHARK_V3:
          process_cheat_gs3(cheats + i);
          break;
      }
    }
  }
}

canonical_original_code:
void process_cheats()
{
  unsigned long i;
  for(i = 0; i < num_cheats; i++)
  {
    if(cheats[i].cheat_active)
    {
      switch(cheats[i].cheat_variant)
      {
        case CHEAT_TYPE_GAMESHARK_V1:
          process_cheat_gs1(cheats + i);
          break;
        case CHEAT_TYPE_GAMESHARK_V3:
          process_cheat_gs3(cheats + i);
          break;
      }
    }
  }
}


decompiled_code:
__int64 __fastcall trigger_key(unsigned __int16 a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdi
unsigned __int64 v4; // rdx

result = io_registers[153];
if ( (result & 0x4000) != 0 )
{
v3 = (unsigned __int16)result & a1 & 0x3FF;
v4 = (unsigned __int64)(unsigned __int16)result >> 15;
if ( v4 )
{
result &= 0x3FFu;
if ( result != v3 )
return result;
return raise_interrupt(4096LL, a2, v4);
}
if ( v3 )
return raise_interrupt(4096LL, a2, v4);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned __int16 a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdi
unsigned __int64 v4; // rdx

result = io_registers[153];
if ( (result & 0x4000) != 0 )
{
v3 = (unsigned __int16)result & a1 & 0x3FF;
v4 = (unsigned __int64)(unsigned __int16)result >> 15;
if ( v4 )
{
result &= 0x3FFu;
if ( result != v3 )
return result;
return raise_interrupt(4096LL, a2, v4);
}
if ( v3 )
return raise_interrupt(4096LL, a2, v4);
}
return result;
}

original_code:
void trigger_key(u32 key)
{
  u32 p1_cnt = io_registers[REG_P1CNT];
  u32 p1;
  if((p1_cnt >> 14) & 0x01)
  {
    u32 key_intersection = (p1_cnt & key) & 0x3FF;
    if(p1_cnt >> 15)
    {
      if(key_intersection == (p1_cnt & 0x3FF))
        raise_interrupt(IRQ_KEYPAD);
    }
    else
    {
      if(key_intersection)
        raise_interrupt(IRQ_KEYPAD);
    }
  }
}

canonical_original_code:
void trigger_key(unsigned long key)
{
  unsigned long p1_cnt = io_registers[REG_P1CNT];
  unsigned long p1;
  if((p1_cnt >> 14) & 0x01)
  {
    unsigned long key_intersection = (p1_cnt & key) & 0x3FF;
    if(p1_cnt >> 15)
    {
      if(key_intersection == (p1_cnt & 0x3FF))
        raise_interrupt(IRQ_KEYPAD);
    }
    else
    {
      if(key_intersection)
        raise_interrupt(IRQ_KEYPAD);
    }
  }
}

variable_types:
key
unsigned long


decompiled_code:
__int64 __fastcall key_map(unsigned int a1)
{
__int64 result; // rax

if ( a1 > 0x134 )
return 0LL;
if ( a1 <= 0x110 )
{
result = 8LL;
if ( a1 != 13 )
{
result = 0LL;
if ( a1 == 120 )
result = 256LL;
}
}
else
{
switch ( a1 )
{
case 0x111u:
result = 64LL;
break;
case 0x112u:
result = 128LL;
break;
case 0x113u:
result = 16LL;
break;
case 0x114u:
result = 32LL;
break;
case 0x12Fu:
result = 4LL;
break;
case 0x130u:
result = 512LL;
break;
case 0x132u:
result = 2LL;
break;
case 0x134u:
result = 1LL;
break;
default:
result = 0LL;
break;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1)
{
__int64 result; // rax

if ( a1 > 0x134 )
return 0LL;
if ( a1 <= 0x110 )
{
result = 8LL;
if ( a1 != 13 )
{
result = 0LL;
if ( a1 == 120 )
result = 256LL;
}
}
else
{
switch ( a1 )
{
case 0x111u:
result = 64LL;
break;
case 0x112u:
result = 128LL;
break;
case 0x113u:
result = 16LL;
break;
case 0x114u:
result = 32LL;
break;
case 0x12Fu:
result = 4LL;
break;
case 0x130u:
result = 512LL;
break;
case 0x132u:
result = 2LL;
break;
case 0x134u:
result = 1LL;
break;
default:
result = 0LL;
break;
}
}
return result;
}

original_code:
u32 key_map(SDLKey key_sym)
{
  switch(key_sym)
  {
    case SDLK_LSHIFT:
      return BUTTON_L;
    case SDLK_x:
      return BUTTON_R;
    case SDLK_DOWN:
      return BUTTON_DOWN;
    case SDLK_UP:
      return BUTTON_UP;
    case SDLK_LEFT:
      return BUTTON_LEFT;
    case SDLK_RIGHT:
      return BUTTON_RIGHT;
    case SDLK_RETURN:
      return BUTTON_START;
    case SDLK_RSHIFT:
      return BUTTON_SELECT;
    case SDLK_LCTRL:
      return BUTTON_B;
    case SDLK_LALT:
      return BUTTON_A;
    default:
      return BUTTON_NONE;
  }
}

canonical_original_code:
unsigned long key_map(enum SDLKey key_sym)
{
  switch(key_sym)
  {
    case SDLK_LSHIFT:
      return BUTTON_L;
    case SDLK_x:
      return BUTTON_R;
    case SDLK_DOWN:
      return BUTTON_DOWN;
    case SDLK_UP:
      return BUTTON_UP;
    case SDLK_LEFT:
      return BUTTON_LEFT;
    case SDLK_RIGHT:
      return BUTTON_RIGHT;
    case SDLK_RETURN:
      return BUTTON_START;
    case SDLK_RSHIFT:
      return BUTTON_SELECT;
    case SDLK_LCTRL:
      return BUTTON_B;
    case SDLK_LALT:
      return BUTTON_A;
    default:
      return BUTTON_NONE;
  }
}

variable_types: enum SDLKey { SDLK_UNKNOWN=0, SDLK_FIRST=0, SDLK_BACKSPACE=8, SDLK_TAB=9, SDLK_CLEAR=12, SDLK_RETURN=13, SDLK_PAUSE=19, SDLK_ESCAPE=27, SDLK_SPACE=32, SDLK_EXCLAIM=33, SDLK_QUOTEDBL=34, SDLK_HASH=35, SDLK_DOLLAR=36, SDLK_AMPERSAND=38, SDLK_QUOTE=39, SDLK_LEFTPAREN=40, SDLK_RIGHTPAREN=41, SDLK_ASTERISK=42, SDLK_PLUS=43, SDLK_COMMA=44, SDLK_MINUS=45, SDLK_PERIOD=46, SDLK_SLASH=47, SDLK_0=48, SDLK_1=49, SDLK_2=50, SDLK_3=51, SDLK_4=52, SDLK_5=53, SDLK_6=54, SDLK_7=55, SDLK_8=56, SDLK_9=57, SDLK_COLON=58, SDLK_SEMICOLON=59, SDLK_LESS=60, SDLK_EQUALS=61, SDLK_GREATER=62, SDLK_QUESTION=63, SDLK_AT=64, SDLK_LEFTBRACKET=91, SDLK_BACKSLASH=92, SDLK_RIGHTBRACKET=93, SDLK_CARET=94, SDLK_UNDERSCORE=95, SDLK_BACKQUOTE=96, SDLK_a=97, SDLK_b=98, SDLK_c=99, SDLK_d=100, SDLK_e=101, SDLK_f=102, SDLK_g=103, SDLK_h=104, SDLK_i=105, SDLK_j=106, SDLK_k=107, SDLK_l=108, SDLK_m=109, SDLK_n=110, SDLK_o=111, SDLK_p=112, SDLK_q=113, SDLK_r=114, SDLK_s=115, SDLK_t=116, SDLK_u=117, SDLK_v=118, SDLK_w=119, SDLK_x=120, SDLK_y=121, SDLK_z=122, SDLK_DELETE=127, SDLK_WORLD_0=160, SDLK_WORLD_1=161, SDLK_WORLD_2=162, SDLK_WORLD_3=163, SDLK_WORLD_4=164, SDLK_WORLD_5=165, SDLK_WORLD_6=166, SDLK_WORLD_7=167, SDLK_WORLD_8=168, SDLK_WORLD_9=169, SDLK_WORLD_10=170, SDLK_WORLD_11=171, SDLK_WORLD_12=172, SDLK_WORLD_13=173, SDLK_WORLD_14=174, SDLK_WORLD_15=175, SDLK_WORLD_16=176, SDLK_WORLD_17=177, SDLK_WORLD_18=178, SDLK_WORLD_19=179, SDLK_WORLD_20=180, SDLK_WORLD_21=181, SDLK_WORLD_22=182, SDLK_WORLD_23=183, SDLK_WORLD_24=184, SDLK_WORLD_25=185, SDLK_WORLD_26=186, SDLK_WORLD_27=187, SDLK_WORLD_28=188, SDLK_WORLD_29=189, SDLK_WORLD_30=190, SDLK_WORLD_31=191, SDLK_WORLD_32=192, SDLK_WORLD_33=193, SDLK_WORLD_34=194, SDLK_WORLD_35=195, SDLK_WORLD_36=196, SDLK_WORLD_37=197, SDLK_WORLD_38=198, SDLK_WORLD_39=199, SDLK_WORLD_40=200, SDLK_WORLD_41=201, SDLK_WORLD_42=202, SDLK_WORLD_43=203, SDLK_WORLD_44=204, SDLK_WORLD_45=205, SDLK_WORLD_46=206, SDLK_WORLD_47=207, SDLK_WORLD_48=208, SDLK_WORLD_49=209, SDLK_WORLD_50=210, SDLK_WORLD_51=211, SDLK_WORLD_52=212, SDLK_WORLD_53=213, SDLK_WORLD_54=214, SDLK_WORLD_55=215, SDLK_WORLD_56=216, SDLK_WORLD_57=217, SDLK_WORLD_58=218, SDLK_WORLD_59=219, SDLK_WORLD_60=220, SDLK_WORLD_61=221, SDLK_WORLD_62=222, SDLK_WORLD_63=223, SDLK_WORLD_64=224, SDLK_WORLD_65=225, SDLK_WORLD_66=226, SDLK_WORLD_67=227, SDLK_WORLD_68=228, SDLK_WORLD_69=229, SDLK_WORLD_70=230, SDLK_WORLD_71=231, SDLK_WORLD_72=232, SDLK_WORLD_73=233, SDLK_WORLD_74=234, SDLK_WORLD_75=235, SDLK_WORLD_76=236, SDLK_WORLD_77=237, SDLK_WORLD_78=238, SDLK_WORLD_79=239, SDLK_WORLD_80=240, SDLK_WORLD_81=241, SDLK_WORLD_82=242, SDLK_WORLD_83=243, SDLK_WORLD_84=244, SDLK_WORLD_85=245, SDLK_WORLD_86=246, SDLK_WORLD_87=247, SDLK_WORLD_88=248, SDLK_WORLD_89=249, SDLK_WORLD_90=250, SDLK_WORLD_91=251, SDLK_WORLD_92=252, SDLK_WORLD_93=253, SDLK_WORLD_94=254, SDLK_WORLD_95=255, SDLK_KP0=256, SDLK_KP1=257, SDLK_KP2=258, SDLK_KP3=259, SDLK_KP4=260, SDLK_KP5=261, SDLK_KP6=262, SDLK_KP7=263, SDLK_KP8=264, SDLK_KP9=265, SDLK_KP_PERIOD=266, SDLK_KP_DIVIDE=267, SDLK_KP_MULTIPLY=268, SDLK_KP_MINUS=269, SDLK_KP_PLUS=270, SDLK_KP_ENTER=271, SDLK_KP_EQUALS=272, SDLK_UP=273, SDLK_DOWN=274, SDLK_RIGHT=275, SDLK_LEFT=276, SDLK_INSERT=277, SDLK_HOME=278, SDLK_END=279, SDLK_PAGEUP=280, SDLK_PAGEDOWN=281, SDLK_F1=282, SDLK_F2=283, SDLK_F3=284, SDLK_F4=285, SDLK_F5=286, SDLK_F6=287, SDLK_F7=288, SDLK_F8=289, SDLK_F9=290, SDLK_F10=291, SDLK_F11=292, SDLK_F12=293, SDLK_F13=294, SDLK_F14=295, SDLK_F15=296, SDLK_NUMLOCK=300, SDLK_CAPSLOCK=301, SDLK_SCROLLOCK=302, SDLK_RSHIFT=303, SDLK_LSHIFT=304, SDLK_RCTRL=305, SDLK_LCTRL=306, SDLK_RALT=307, SDLK_LALT=308, SDLK_RMETA=309, SDLK_LMETA=310, SDLK_LSUPER=311, SDLK_RSUPER=312, SDLK_MODE=313, SDLK_COMPOSE=314, SDLK_HELP=315, SDLK_PRINT=316, SDLK_SYSREQ=317, SDLK_BREAK=318, SDLK_MENU=319, SDLK_POWER=320, SDLK_EURO=321, SDLK_UNDO=322, SDLK_LAST=323 }

return_type: unsigned long


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

switch ( a1 )
{
case 0LL:
result = 2LL;
break;
case 1LL:
result = a1;
break;
case 4LL:
result = 512LL;
break;
case 5LL:
result = 256LL;
break;
case 8LL:
result = 4LL;
break;
case 9LL:
result = 8LL;
break;
default:
result = 0LL;
break;
}
return result;
}

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

switch ( a1 )
{
case 0LL:
result = 2LL;
break;
case 1LL:
result = a1;
break;
case 4LL:
result = 512LL;
break;
case 5LL:
result = 256LL;
break;
case 8LL:
result = 4LL;
break;
case 9LL:
result = 8LL;
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
u32 joy_map(u32 button)
{
  switch(button)
  {
    case 4:
      return BUTTON_L;
    case 5:
      return BUTTON_R;
    case 9:
      return BUTTON_START;
    case 8:
      return BUTTON_SELECT;
    case 0:
      return BUTTON_B;
    case 1:
      return BUTTON_A;
    default:
      return BUTTON_NONE;
  }
}

canonical_original_code:
unsigned long joy_map(unsigned long button)
{
  switch(button)
  {
    case 4:
      return BUTTON_L;
    case 5:
      return BUTTON_R;
    case 9:
      return BUTTON_START;
    case 8:
      return BUTTON_SELECT;
    case 0:
      return BUTTON_B;
    case 1:
      return BUTTON_A;
    default:
      return BUTTON_NONE;
  }
}

variable_types:
button
unsigned long


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

result = SDL_NumJoysticks();
if ( (_DWORD)result )
{
SDL_JoystickOpen(0LL);
result = SDL_JoystickEventState(1LL);
}
return result;
}

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

result = SDL_NumJoysticks();
if ( (_DWORD)result )
{
SDL_JoystickOpen(0LL);
result = SDL_JoystickEventState(1LL);
}
return result;
}

original_code:
void init_input()
{
  u32 joystick_count = SDL_NumJoysticks();
  if(joystick_count > 0)
  {
    SDL_JoystickOpen(0);
    SDL_JoystickEventState(1);
  }
}

canonical_original_code:
void init_input()
{
  unsigned long joystick_count = SDL_NumJoysticks();
  if(joystick_count > 0)
  {
    SDL_JoystickOpen(0);
    SDL_JoystickEventState(1);
  }
}


main

canonical_name: main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
__pid_t v3; // eax
char *v4; // rax
char *v5; // rdi
__int64 i; // rcx
char *file; // [rsp+0h] [rbp-68h] BYREF
int pipedes[2]; // [rsp+8h] [rbp-60h] BYREF
__int64 buf[2]; // [rsp+10h] [rbp-58h] BYREF
char v10[56]; // [rsp+20h] [rbp-48h] BYREF
unsigned __int64 v11; // [rsp+58h] [rbp-10h]

v11 = __readfsqword(0x28u);
if ( pipe(pipedes) != -1 )
{
v3 = fork();
if ( v3 != -1 )
{
if ( v3 )
{
close(pipedes[1]);
wait((__WAIT_STATUS)&file);
if ( (unsigned __int8)file & 0x7F | BYTE1(file) )
exit(1);
buf[0] = 0LL;
buf[1] = 0LL;
v5 = v10;
for ( i = 12LL; i; --i )
{
*(_DWORD *)v5 = 0;
v5 += 4;
}
if ( read(pipedes[0], buf, 0x40uLL) > 0 )
{
v10[47] = 0;
close(pipedes[0]);
execlp((const char *)buf, (const char *)buf, 0LL);
exit(1);
}
exit(1);
}
close(pipedes[0]);
if ( dup2(pipedes[1], 1) != -1 )
{
v4 = getenv("USER");
asprintf(&file, "%s%s%s%s", "/home/", v4, "/.cabal/bin/", "yeganesh");
execlp(file, "yeganesh", "-x", 0LL);
close(pipedes[1]);
exit(1);
}
exit(1);
}
exit(1);
}
exit(1);
}

original_code:
int main()
{
 int pipefd[2];
 if (pipe(pipefd) == -1)
  exit(1);
 switch (fork()) {
 case -1:
  exit(1);
 case 0:
  close(pipefd[0]);
  if (dup2(pipefd[1], 1) == -1)
   exit(1);
  execlp(({ char *yg_path; asprintf(&yg_path, "%s%s%s%s", "/home/", getenv("USER"), "/.cabal/bin/", "yeganesh"); yg_path; }), "yeganesh", "-x", ((void *)0));
  close(pipefd[1]);
  exit(1);
 default:
  close(pipefd[1]);
  int status;
  wait(&status);
  if (!((((status) & 0x7f) == 0) && ((((status) & 0xff00) >> 8) == 0)))
   exit(1);
  char buf[64] = "";
  if (read(pipefd[0], buf, 64) < 1)
   exit(1);
  buf[64 -1] = '\0';
  close(pipefd[0]);
  execlp(buf, buf, ((void *)0));
  exit(1);
 }
}

variable_types:
pipefd
int [2]

variable_types: status int

variable_types:
buf
char [64]

return_type: int


setlevel

repo: nissafors/lwrace

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

result = _isoc99_sscanf(a1, &unk_5D4, &level);
if ( (_DWORD)result != 1 || level > 9u )
level = -1;
return result;
}

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

result = _isoc99_sscanf(a1, &unk_5D4, &level);
if ( (_DWORD)result != 1 || level > 9u )
level = -1;
return result;
}

original_code:
static void setlevel(char *optarg) {
    extern int level;
    int scanfargc;
    scanfargc = sscanf(optarg, "%d", &level);
    if (scanfargc != 1 || level < 0 || level > 9) {
        level = -1;
    }
}

variable_types:
optarg
char *

variable_types: level int

variable_types: scanfargc int


showhelp

decompiled_code:
int __fastcall showhelp(const char *a1)
{
if ( !a1 )
return puts(
"Usage: lwrace [-l <0-9>] [-f <file>] [-k <file>]\n"
" lwrace [-h[=keyword] | -p | -s [-f <file>] [-l <level>] | -v ]\n"
"Run terminal mode game Lawyer Race, an enhanced clone of an old QBasic game.\n"
"Default game control: use arrow keys to move, space to stop, p to pause and\n"
"escape to abort game.\n"
"\n"
" -f <file>, or Read and store high scores to and from <file>.\n"
" --scorefile <file> Type \"lwrace --help=scorefile\" for details.\n"
" -h, --help Display this help and exit.\n"
" -k <file>, or Use keys defined in <file> for game control.\n"
" --keyfile <file> Type \"lwrace --help=keyfile\" for details.\n"
" -l <0-9>, or Set difficulty of the game. 0-2 = easy, 3 = default,\n"
" --level <0-9> 4-9 = medium to hard. High scores are level dependent.\n"
" -p, --plot Display the original game plot and exit.\n"
" -s, --scores Display high scores and exit.\n"
" -v, --version Output version information and exit.\n"
"\n"
"Report bugs to aa@mensa.se\n"
"Github project page: <https://github.com/nissafors/lwrace>");
if ( !strcmp(a1, "keyfile") )
return puts(
"There are seven possible actions in a lawyer race game: Move up, move down,\n"
"move left, move right, stop, pause and give up. By default these actions are\n"
"mapped to arrow keys, space, p and esc respectively. To remap keys, you can\n"
"use a keyfile. This is a textfile containing key map commands with syntax:\n"
"\n"
" action (whitespace) key\n"
"\n"
"\"Action\" is one of the following: up, down, left, right, stop, pause or exit\n"
"\"Whitespace\" is tabs or spaces.\n"
"\"Key\" is either a typable character surrounded by single quotes, a raw\n"
"number that curses getch() can handle or any of <return>, <tab>, <esc>,\n"
"<space>, <enter>, <down>, <up>, <left>, <right>, <home>, <backspace>, <del>,\n"
" <ins>, <pgdn>, <pgup> or <end>. Note that you can't use ' '; Use <space>.\n"
"Here's a sample keyfile to make things clearer:\n"
"\n"
" # Lines that begin with \"#\" are comments\n"
" pause 27\n"
" up 'w'\n"
" down 's'\n"
" left 'a'\n"
" right 'd'\n"
" exit <end>\n"
"\n"
"\"lwrace --keyfile /path/to/keyfile\" tells the program to use your keyfile.\n"
"You can also rename you file \"keys\" and put it in ~/.lwrace/, where lwrace\n"
"will look by default.");
if ( strcmp(a1, "scorefile") )
return puts(
"Usage: lwrace [-l <0-9>] [-f <file>] [-k <file>]\n"
" lwrace [-h[=keyword] | -p | -s [-f <file>] [-l <level>] | -v ]\n"
"Run terminal mode game Lawyer Race, an enhanced clone of an old QBasic game.\n"
"Default game control: use arrow keys to move, space to stop, p to pause and\n"
"escape to abort game.\n"
"\n"
" -f <file>, or Read and store high scores to and from <file>.\n"
" --scorefile <file> Type \"lwrace --help=scorefile\" for details.\n"
" -h, --help Display this help and exit.\n"
" -k <file>, or Use keys defined in <file> for game control.\n"
" --keyfile <file> Type \"lwrace --help=keyfile\" for details.\n"
" -l <0-9>, or Set difficulty of the game. 0-2 = easy, 3 = default,\n"
" --level <0-9> 4-9 = medium to hard. High scores are level dependent.\n"
" -p, --plot Display the original game plot and exit.\n"
" -s, --scores Display high scores and exit.\n"
" -v, --version Output version information and exit.\n"
"\n"
"Report bugs to aa@mensa.se\n"
"Github project page: <https://github.com/nissafors/lwrace>");
return puts(
"By default lawyer race writes high scores to files in ~/.lwrace/ directory.\n"
"Filenames are prepended with .<number>, where <number> is the level chosen\n"
"with the --level option. A player who has played on default level plus level\n"
"two and level six will have these files in his/her ~/.lwrace/ directory:\n"
"\n"
" highscores.2 highscores.3 highscores.6\n"
"\n"
"You can tell the program to store scores in a high score file of your choice\n"
"by issuing \"lwrace --scorefile /path/to/scorefile\".\n"
"Note that the level extension will always be added to the filename, thus the\n"
"command \"lwrace -l 5 -f myfile \" will produce the file \"myfile.5\"");
}

canonical_decompiled_code:
int __fastcall func1(const char *a1)
{
if ( !a1 )
return puts(
"Usage: lwrace [-l <0-9>] [-f <file>] [-k <file>]\n"
" lwrace [-h[=keyword] | -p | -s [-f <file>] [-l <level>] | -v ]\n"
"Run terminal mode game Lawyer Race, an enhanced clone of an old QBasic game.\n"
"Default game control: use arrow keys to move, space to stop, p to pause and\n"
"escape to abort game.\n"
"\n"
" -f <file>, or Read and store high scores to and from <file>.\n"
" --scorefile <file> Type \"lwrace --help=scorefile\" for details.\n"
" -h, --help Display this help and exit.\n"
" -k <file>, or Use keys defined in <file> for game control.\n"
" --keyfile <file> Type \"lwrace --help=keyfile\" for details.\n"
" -l <0-9>, or Set difficulty of the game. 0-2 = easy, 3 = default,\n"
" --level <0-9> 4-9 = medium to hard. High scores are level dependent.\n"
" -p, --plot Display the original game plot and exit.\n"
" -s, --scores Display high scores and exit.\n"
" -v, --version Output version information and exit.\n"
"\n"
"Report bugs to aa@mensa.se\n"
"Github project page: <https://github.com/nissafors/lwrace>");
if ( !strcmp(a1, "keyfile") )
return puts(
"There are seven possible actions in a lawyer race game: Move up, move down,\n"
"move left, move right, stop, pause and give up. By default these actions are\n"
"mapped to arrow keys, space, p and esc respectively. To remap keys, you can\n"
"use a keyfile. This is a textfile containing key map commands with syntax:\n"
"\n"
" action (whitespace) key\n"
"\n"
"\"Action\" is one of the following: up, down, left, right, stop, pause or exit\n"
"\"Whitespace\" is tabs or spaces.\n"
"\"Key\" is either a typable character surrounded by single quotes, a raw\n"
"number that curses getch() can handle or any of <return>, <tab>, <esc>,\n"
"<space>, <enter>, <down>, <up>, <left>, <right>, <home>, <backspace>, <del>,\n"
" <ins>, <pgdn>, <pgup> or <end>. Note that you can't use ' '; Use <space>.\n"
"Here's a sample keyfile to make things clearer:\n"
"\n"
" # Lines that begin with \"#\" are comments\n"
" pause 27\n"
" up 'w'\n"
" down 's'\n"
" left 'a'\n"
" right 'd'\n"
" exit <end>\n"
"\n"
"\"lwrace --keyfile /path/to/keyfile\" tells the program to use your keyfile.\n"
"You can also rename you file \"keys\" and put it in ~/.lwrace/, where lwrace\n"
"will look by default.");
if ( strcmp(a1, "scorefile") )
return puts(
"Usage: lwrace [-l <0-9>] [-f <file>] [-k <file>]\n"
" lwrace [-h[=keyword] | -p | -s [-f <file>] [-l <level>] | -v ]\n"
"Run terminal mode game Lawyer Race, an enhanced clone of an old QBasic game.\n"
"Default game control: use arrow keys to move, space to stop, p to pause and\n"
"escape to abort game.\n"
"\n"
" -f <file>, or Read and store high scores to and from <file>.\n"
" --scorefile <file> Type \"lwrace --help=scorefile\" for details.\n"
" -h, --help Display this help and exit.\n"
" -k <file>, or Use keys defined in <file> for game control.\n"
" --keyfile <file> Type \"lwrace --help=keyfile\" for details.\n"
" -l <0-9>, or Set difficulty of the game. 0-2 = easy, 3 = default,\n"
" --level <0-9> 4-9 = medium to hard. High scores are level dependent.\n"
" -p, --plot Display the original game plot and exit.\n"
" -s, --scores Display high scores and exit.\n"
" -v, --version Output version information and exit.\n"
"\n"
"Report bugs to aa@mensa.se\n"
"Github project page: <https://github.com/nissafors/lwrace>");
return puts(
"By default lawyer race writes high scores to files in ~/.lwrace/ directory.\n"
"Filenames are prepended with .<number>, where <number> is the level chosen\n"
"with the --level option. A player who has played on default level plus level\n"
"two and level six will have these files in his/her ~/.lwrace/ directory:\n"
"\n"
" highscores.2 highscores.3 highscores.6\n"
"\n"
"You can tell the program to store scores in a high score file of your choice\n"
"by issuing \"lwrace --scorefile /path/to/scorefile\".\n"
"Note that the level extension will always be added to the filename, thus the\n"
"command \"lwrace -l 5 -f myfile \" will produce the file \"myfile.5\"");
}

original_code:
static void showhelp(char *optarg) {
    if (optarg) {
        if (strcmp(optarg, "keyfile") == 0) {
            puts(keyfilehelp);
            return;
        } else if (strcmp(optarg, "scorefile") == 0) {
            puts(scorefilehelp);
            return;
        }
    }
    puts(usage);
}


incompatibleopts

decompiled_code:
_BOOL8 __fastcall incompatibleopts(char *s)
{
_BOOL4 v1; // ebp
size_t v2; // rax

if ( strchr(s, 112) || (v1 = 0, strchr(s, 118)) )
v1 = strlen(s) > 1;
if ( strchr(s, 115) )
{
v2 = strlen(s);
if ( v2 > 3 )
{
v1 = 1;
}
else if ( v2 == 3 )
{
if ( !strchr(s, 102) )
return 1;
if ( !strchr(s, 108) )
v1 = 1;
return v1;
}
if ( v2 == 2 && !strchr(s, 102) && !strchr(s, 108) )
v1 = 1;
}
return v1;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(char *s)
{
_BOOL4 v1; // ebp
size_t v2; // rax

if ( strchr(s, 112) || (v1 = 0, strchr(s, 118)) )
v1 = strlen(s) > 1;
if ( strchr(s, 115) )
{
v2 = strlen(s);
if ( v2 > 3 )
{
v1 = 1;
}
else if ( v2 == 3 )
{
if ( !strchr(s, 102) )
return 1;
if ( !strchr(s, 108) )
v1 = 1;
return v1;
}
if ( v2 == 2 && !strchr(s, 102) && !strchr(s, 108) )
v1 = 1;
}
return v1;
}

original_code:
int incompatibleopts(char *argstring) {
    int errbool = 0;
    if ( (strchr(argstring, 'p') || strchr(argstring, 'v')) &&
          strlen(argstring) > 1 )
    {
        errbool = 1;
    }
    if (strchr(argstring, 's')) {
        if (strlen(argstring) > 3)
            errbool = 1;
        if (strlen(argstring) == 3)
            if ( !(strchr(argstring, 'f') && strchr(argstring, 'l')) )
                errbool = 1;
        if (strlen(argstring) == 2)
            if ( !(strchr(argstring, 'f') || strchr(argstring, 'l')) )
                errbool = 1;
    }
    return errbool;
}

variable_types:
argstring
char *

variable_types: errbool int


parseargs

original_code:
int parseargs(int argc, char *argv[])
{
    extern int level;
    extern char *key_file_path;
    extern char *hiscore_file_path;
    int return_bits = 0;
    char *heap_area_for_scorefile_path;
    char *heap_area_for_keyfile_path;
    int c, i;
    char argstring[7 + 1];
    argstring[0] = '\0';
    char *optstring = "l:f:h::k:psv";
    struct option longopts[] = {
        {"level", 1, ((void *)0), 'l'},
        {"scorefile", 1, ((void *)0), 'f'},
        {"help", 2, ((void *)0), 'h'},
        {"keyfile", 1, ((void *)0), 'k'},
        {"plot", 0, ((void *)0), 'p'},
        {"scores", 0, ((void *)0), 's'},
        {"version", 0, ((void *)0), 'v'},
        {0, 0, 0, 0}
    };
    i = 0;
    while ((c = getopt_long(argc, argv, optstring, longopts, ((void *)0))) != -1) {
        if (c == '?' || c == ':')
            exit(1);
        if ( (strchr(argstring, c)) ) {
            fprintf(stderr, "%s: option may be given only once -- %c\n",
                    argv[0], c);
            exit(1);
        }
        if(optarg && *optarg == '=')
            optarg++;
        switch (c) {
            case 'l':
                setlevel(optarg);
                return_bits = return_bits | 1;
                break;
            case 'f':
                if( (heap_area_for_scorefile_path = expandpath(optarg, 1)) )
                {
                    free(hiscore_file_path);
                    hiscore_file_path = heap_area_for_scorefile_path;
                    return_bits = return_bits | 2;
                }
                break;
            case 'h':
                showhelp(optarg);
                exit(0);
            case 'k':
                if( (heap_area_for_keyfile_path = expandpath(optarg, 1)) )
                {
                    free(key_file_path);
                    key_file_path = heap_area_for_keyfile_path;
                    return_bits = return_bits | 4;
                }
                break;
        }
        argstring[i++] = (char)c;
        argstring[i] = '\0';
    }
    if (incompatibleopts(argstring))
        error(1, 0, "illegal combination of arguments -- %s", argstring);
    if (level == -1) {
        fprintf(stderr, "%s: level out of range\n", argv[0]);
        exit(1);
    }
    if ( (strchr(argstring, 'f') && !hiscore_file_path) ||
         (strchr(argstring, 'k') && !key_file_path) )
    {
        fprintf(stderr, "%s: could not expand path\n", argv[0]);
        exit(1);
    }
    if (strchr(argstring, 's')) {
        if (!strchr(argstring, 'l')) {
            level = -1;
        }
        printscores(hiscore_file_path, level);
        exit(0);
    }
    if (*argstring == 'p') {
        puts(plot);
        exit(0);
    }
    if (*argstring == 'v') {
        printf(version, "1.0 RC1");
        exit(0);
    }
    return return_bits;
}

canonical_original_code:
int parseargs(int argc, char *argv[])
{
    extern int level;
    extern char *key_file_path;
    extern char *hiscore_file_path;
    int return_bits = 0;
    char *heap_area_for_scorefile_path;
    char *heap_area_for_keyfile_path;
    int c; int i;
    char argstring[-1];
    argstring[0] = '\0';
    char *optstring = "l:f:h::k:psv";
    struct option longopts[] = {
        {"level", 1, ((void *)0), 'l'},
        {"scorefile", 1, ((void *)0), 'f'},
        {"help", 2, ((void *)0), 'h'},
        {"keyfile", 1, ((void *)0), 'k'},
        {"plot", 0, ((void *)0), 'p'},
        {"scores", 0, ((void *)0), 's'},
        {"version", 0, ((void *)0), 'v'},
        {0, 0, 0, 0}
    };
    i = 0;
    while ((c = getopt_long(argc, argv, optstring, longopts, ((void *)0))) != -1) {
        if (c == '?' || c == ':')
            exit(1);
        if ( (strchr(argstring, c)) ) {
            fprintf(stderr, "%s: option may be given only once -- %c\n",
                    argv[0], c);
            exit(1);
        }
        if(optarg && *optarg == '=')
            optarg++;
        switch (c) {
            case 'l':
                setlevel(optarg);
                return_bits = return_bits | 1;
                break;
            case 'f':
                if( (heap_area_for_scorefile_path = expandpath(optarg, 1)) )
                {
                    free(hiscore_file_path);
                    hiscore_file_path = heap_area_for_scorefile_path;
                    return_bits = return_bits | 2;
                }
                break;
            case 'h':
                showhelp(optarg);
                exit(0);
            case 'k':
                if( (heap_area_for_keyfile_path = expandpath(optarg, 1)) )
                {
                    free(key_file_path);
                    key_file_path = heap_area_for_keyfile_path;
                    return_bits = return_bits | 4;
                }
                break;
        }
        argstring[i++] = (char)c;
        argstring[i] = '\0';
    }
    if (incompatibleopts(argstring))
        error(1, 0, "illegal combination of arguments -- %s", argstring);
    if (level == -1) {
        fprintf(stderr, "%s: level out of range\n", argv[0]);
        exit(1);
    }
    if ( (strchr(argstring, 'f') && !hiscore_file_path) ||
         (strchr(argstring, 'k') && !key_file_path) )
    {
        fprintf(stderr, "%s: could not expand path\n", argv[0]);
        exit(1);
    }
    if (strchr(argstring, 's')) {
        if (!strchr(argstring, 'l')) {
            level = -1;
        }
        printscores(hiscore_file_path, level);
        exit(0);
    }
    if (*argstring == 'p') {
        puts(plot);
        exit(0);
    }
    if (*argstring == 'v') {
        printf(version, "1.0 RC1");
        exit(0);
    }
    return return_bits;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: c int

variable_types: i int

variable_types:
argstring
char [-1]

variable_types:
optstring
char *

variable_types: struct option { char *name; int has_arg; int *flag; int val; } []


initglobals

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

level = 3;
enemy_nokill_time = LC0;
row_to_col_delay_ratio = LC1;
fobj_init_delay_min = 24;
fobj_init_delay_max = 48;
fobj_hang_delay_min = 0;
fobj_hang_delay_max = 24;
fobj_fall_delay_start = LC2;
fobj_fall_delay_end = LC3;
fobj_base = LC4;
fobj_acc = LC5;
key_esc = 27;
key_pause = 112;
key_stop = 32;
key_enter = 10;
key_up = 259;
key_down = 258;
key_left = 260;
key_right = 261;
key_file_path = expandpath("~/.lwrace/keys", 1LL);
result = expandpath("~/.lwrace/highscores", 1LL);
hiscore_file_path = result;
return result;
}

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

level = 3;
enemy_nokill_time = LC0;
row_to_col_delay_ratio = LC1;
fobj_init_delay_min = 24;
fobj_init_delay_max = 48;
fobj_hang_delay_min = 0;
fobj_hang_delay_max = 24;
fobj_fall_delay_start = LC2;
fobj_fall_delay_end = LC3;
fobj_base = LC4;
fobj_acc = LC5;
key_esc = 27;
key_pause = 112;
key_stop = 32;
key_enter = 10;
key_up = 259;
key_down = 258;
key_left = 260;
key_right = 261;
key_file_path = expandpath("~/.lwrace/keys", 1LL);
result = expandpath("~/.lwrace/highscores", 1LL);
hiscore_file_path = result;
return result;
}

original_code:
static void initglobals() {
    level = 3;
    enemy_nokill_time = 3;
    row_to_col_delay_ratio = 23.0 / 80.0;
    fobj_init_delay_min = 24;
    fobj_init_delay_max = 48;
    fobj_hang_delay_min = 0;
    fobj_hang_delay_max = 24;
    fobj_fall_delay_start = 4.8;
    fobj_fall_delay_end = 0.72;
    fobj_base = 2;
    fobj_acc = 16;
    key_esc = 27;
    key_pause = 'p';
    key_stop = ' ';
    key_enter = '\n';
    key_up = 0403;
    key_down = 0402;
    key_left = 0404;
    key_right = 0405;
    key_file_path = expandpath("~/.lwrace/keys", 1);
    hiscore_file_path = expandpath("~/.lwrace/highscores", 1);
}


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // er14
char v4; // bp
void *v5; // rbx
int v6; // er15
int v7; // esi
int v8; // eax
unsigned int v9; // ebp
__int64 v10; // rsi
unsigned __int64 v11; // r13
unsigned int v12; // er12
__int64 i; // rdi
int v14; // eax
int v15; // edx
unsigned __int64 v16; // rbx
unsigned int v17; // eax
__int64 v19; // rbx

initglobals(argc, argv, envp);
v4 = parseargs((unsigned int)argc, argv);
setspeed();
if ( (unsigned int)setkeys(key_file_path) != 2 )
{
v5 = (void *)expandpath("~/.lwrace", 0LL);
v6 = mk_default_dir(v5);
free(v5);
if ( v6 && (v4 & 2) != 0 )
v6 = 0;
seedgenrand();
initscr();
cbreak();
keypad(stdscr, 1);
noecho();
curs_set(0);
nodelay(stdscr, 1);
if ( stdscr )
{
v7 = stdscr->_maxy + 1;
v8 = stdscr->_maxx + 1;
}
else
{
v7 = -1;
v8 = -1;
}
cols = v8;
rows = v7 - 1;
v9 = genrand(0LL);
v10 = (unsigned int)cols;
v11 = (unsigned int)genrand(0LL);
v12 = 0;
for ( i = 0xFFFFFFFFLL; ; i = v3 )
{
v17 = getdir(i, v10);
if ( v17 == -2 )
goto LABEL_22;
if ( v17 == 9 )
idle("Game paused");
else
v3 = v17;
if ( stdscr )
{
v14 = stdscr->_maxy + 1;
v15 = stdscr->_maxx + 1;
}
else
{
v14 = -1;
v15 = -1;
}
cols = v15;
rows = v14 - 1;
v16 = drawplayer(v3, (v11 << 32) | v9);
v9 = v16;
v11 = HIDWORD(v16);
v12 += treasures(v16);
printstatus(v12);
if ( (unsigned int)drawenemies(v16, v12) )
break;
v10 = v12;
if ( (unsigned int)fobjects(v16, v12) )
break;
}
if ( wmove(stdscr, v16, SHIDWORD(v16)) != -1 )
waddch(stdscr, 0x58uLL);
wrefresh(stdscr);
idle("GAME OVER!");
if ( v6 || !(unsigned int)is_high_score(v12, (unsigned int)level, hiscore_file_path) )
{
LABEL_22:
endwin();
return 0;
}
v19 = getname();
endwin();
if ( !(unsigned int)writescores(hiscore_file_path, v19, v12, (unsigned int)level) )
{
printscores(hiscore_file_path, (unsigned int)level);
exit(0);
}
error(1, 0, "Can't open high score file -- %s", (const char *)hiscore_file_path);
}
return 1;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // er14
char v4; // bp
void *v5; // rbx
int v6; // er15
int v7; // esi
int v8; // eax
unsigned int v9; // ebp
__int64 v10; // rsi
unsigned __int64 v11; // r13
unsigned int v12; // er12
__int64 i; // rdi
int v14; // eax
int v15; // edx
unsigned __int64 v16; // rbx
unsigned int v17; // eax
__int64 v19; // rbx

func0(argc, argv, envp);
v4 = parseargs((unsigned int)argc, argv);
setspeed();
if ( (unsigned int)setkeys(key_file_path) != 2 )
{
v5 = (void *)expandpath("~/.lwrace", 0LL);
v6 = mk_default_dir(v5);
free(v5);
if ( v6 && (v4 & 2) != 0 )
v6 = 0;
seedgenrand();
initscr();
cbreak();
keypad(stdscr, 1);
noecho();
curs_set(0);
nodelay(stdscr, 1);
if ( stdscr )
{
v7 = stdscr->_maxy + 1;
v8 = stdscr->_maxx + 1;
}
else
{
v7 = -1;
v8 = -1;
}
cols = v8;
rows = v7 - 1;
v9 = genrand(0LL);
v10 = (unsigned int)cols;
v11 = (unsigned int)genrand(0LL);
v12 = 0;
for ( i = 0xFFFFFFFFLL; ; i = v3 )
{
v17 = getdir(i, v10);
if ( v17 == -2 )
goto LABEL_22;
if ( v17 == 9 )
func1("Game paused");
else
v3 = v17;
if ( stdscr )
{
v14 = stdscr->_maxy + 1;
v15 = stdscr->_maxx + 1;
}
else
{
v14 = -1;
v15 = -1;
}
cols = v15;
rows = v14 - 1;
v16 = drawplayer(v3, (v11 << 32) | v9);
v9 = v16;
v11 = HIDWORD(v16);
v12 += treasures(v16);
printstatus(v12);
if ( (unsigned int)drawenemies(v16, v12) )
break;
v10 = v12;
if ( (unsigned int)fobjects(v16, v12) )
break;
}
if ( wmove(stdscr, v16, SHIDWORD(v16)) != -1 )
waddch(stdscr, 0x58uLL);
wrefresh(stdscr);
func1("GAME OVER!");
if ( v6 || !(unsigned int)is_high_score(v12, (unsigned int)level, hiscore_file_path) )
{
LABEL_22:
endwin();
return 0;
}
v19 = getname();
endwin();
if ( !(unsigned int)writescores(hiscore_file_path, v19, v12, (unsigned int)level) )
{
printscores(hiscore_file_path, (unsigned int)level);
exit(0);
}
error(1, 0, "Can't open high score file -- %s", (const char *)hiscore_file_path);
}
return 1;
}

original_code:
int main(int argc, char *argv[])
{
    struct pos plpos;
    dir_t pldir;
    dir_t lastdir;
    int score;
    char *name;
    char *default_dir;
    int parseargs_bitmask;
    bool_t scores_off;
    initglobals();
    parseargs_bitmask = parseargs(argc, argv);
    setspeed();
    if (setkeys(key_file_path) == 2) {
        return 1;
    }
    default_dir = expandpath("~/.lwrace", 0);
    scores_off = mk_default_dir(default_dir);
    free(default_dir);
    if (scores_off && (parseargs_bitmask & 2)) {
        scores_off = 0;
    }
    seedgenrand();
    initscr();
    cbreak();
    keypad(stdscr, 1);
    noecho();
    curs_set(0);
    nodelay(stdscr, 1);
    pldir = -1;
    ((rows) = ((0 != (const void *)((stdscr))) ? ((stdscr)->_maxy + 1) : (-1)), (cols) = ((0 != (const void *)((stdscr))) ? ((stdscr)->_maxx + 1) : (-1))), rows--;
    plpos.row = genrand(0, rows);
    plpos.col = genrand(0, cols);
    score = 0;
    while ((pldir = getdir(pldir)) != -2) {
        if (pldir == 9) {
            idle("Game paused");
            pldir = lastdir;
        }
        lastdir = pldir;
        ((rows) = ((0 != (const void *)((stdscr))) ? ((stdscr)->_maxy + 1) : (-1)), (cols) = ((0 != (const void *)((stdscr))) ? ((stdscr)->_maxx + 1) : (-1))), rows--;
        plpos = drawplayer(pldir, plpos);
        score += treasures(plpos);
        printstatus(score);
        if(drawenemies(plpos, score) || fobjects(plpos, score)) {
            (wmove((stdscr),((plpos.row)),((plpos.col))) == (-1) ? (-1) : waddch((stdscr),(('X'))));
            wrefresh(stdscr);
            idle("GAME OVER!");
            if (!scores_off) {
                if (is_high_score(score, level, hiscore_file_path)) {
                    name = getname();
                    endwin();
                    scores_off = writescores(hiscore_file_path, name, score, level);
                    if (scores_off) {
                        error(1, 0, "Can't open high score file -- %s", hiscore_file_path);
                    }
                    printscores(hiscore_file_path, level);
                    exit(0);
                }
            }
            break;
        }
    }
    endwin();
    return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
    struct pos plpos;
    int pldir;
    int lastdir;
    int score;
    char *name;
    char *default_dir;
    int parseargs_bitmask;
    int scores_off;
    initglobals();
    parseargs_bitmask = parseargs(argc, argv);
    setspeed();
    if (setkeys(key_file_path) == 2) {
        return 1;
    }
    default_dir = expandpath("~/.lwrace", 0);
    scores_off = mk_default_dir(default_dir);
    free(default_dir);
    if (scores_off && (parseargs_bitmask & 2)) {
        scores_off = 0;
    }
    seedgenrand();
    initscr();
    cbreak();
    keypad(stdscr, 1);
    noecho();
    curs_set(0);
    nodelay(stdscr, 1);
    pldir = -1;
    ((rows) = ((0 != (void *)((stdscr))) ? ((stdscr)->_maxy + 1) : (-1)), (cols) = ((0 != (void *)((stdscr))) ? ((stdscr)->_maxx + 1) : (-1))), rows--;
    plpos.row = genrand(0, rows);
    plpos.col = genrand(0, cols);
    score = 0;
    while ((pldir = getdir(pldir)) != -2) {
        if (pldir == 9) {
            idle("Game paused");
            pldir = lastdir;
        }
        lastdir = pldir;
        ((rows) = ((0 != (void *)((stdscr))) ? ((stdscr)->_maxy + 1) : (-1)), (cols) = ((0 != (void *)((stdscr))) ? ((stdscr)->_maxx + 1) : (-1))), rows--;
        plpos = drawplayer(pldir, plpos);
        score += treasures(plpos);
        printstatus(score);
        if(drawenemies(plpos, score) || fobjects(plpos, score)) {
            (wmove((stdscr),((plpos.row)),((plpos.col))) == (-1) ? (-1) : waddch((stdscr),(('X'))));
            wrefresh(stdscr);
            idle("GAME OVER!");
            if (!scores_off) {
                if (is_high_score(score, level, hiscore_file_path)) {
                    name = getname();
                    endwin();
                    scores_off = writescores(hiscore_file_path, name, score, level);
                    if (scores_off) {
                        error(1, 0, "Can't open high score file -- %s", hiscore_file_path);
                    }
                    printscores(hiscore_file_path, level);
                    exit(0);
                }
            }
            break;
        }
    }
    endwin();
    return 0;
}

variable_types:
plpos
struct pos { int row; int col; }

variable_types: pldir int

variable_types: lastdir int

variable_types: score int

variable_types:
name
char *


genrand

decompiled_code:
__int64 __fastcall genrand(int a1, int a2)
{
return (unsigned int)(rand() % (a2 - a1) + a1);
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, int a2)
{
return (unsigned int)(rand() % (a2 - a1) + a1);
}

original_code:
int genrand(int min, int max) {
    return rand() % (max-min) + min;
}

variable_types: min int

variable_types: max int


seedgenrand

decompiled_code:
void seedgenrand()
{
struct timeval v0; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v0, 0LL);
srand(LODWORD(v0.tv_usec) * LODWORD(v0.tv_sec));
}

canonical_decompiled_code:
void func1()
{
struct timeval v0; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v0, 0LL);
srand(LODWORD(v0.tv_usec) * LODWORD(v0.tv_sec));
}

original_code:
void seedgenrand() {
    long seed;
    struct timeval now;
    gettimeofday(&now, ((void *)0));
    seed = now.tv_sec * now.tv_usec;
    srand(seed);
}

variable_types: seed long

variable_types: struct timeval { long tv_sec; long tv_usec; }


getnow

decompiled_code:
double getnow()
{
struct timeval v1; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v1, 0LL);
return (double)SLODWORD(v1.tv_usec) / 1000000.0 + (double)SLODWORD(v1.tv_sec);
}

canonical_decompiled_code:
double func2()
{
struct timeval v1; // [rsp+0h] [rbp-18h] BYREF

gettimeofday(&v1, 0LL);
return (double)SLODWORD(v1.tv_usec) / 1000000.0 + (double)SLODWORD(v1.tv_sec);
}

original_code:
double getnow() {
    struct timeval now;
    gettimeofday(&now, ((void *)0));
    return now.tv_sec+(now.tv_usec/1000000.0);
}

return_type: double

user_defined_types: struct timeval { long tv_sec; long tv_usec; }


decompiled_code:
int __fastcall mk_default_dir(char *path)
{
char v1; // al
int result; // eax
struct stat v3; // [rsp+0h] [rbp-98h] BYREF

if ( stat(path, &v3) == -1 )
{
result = mkdir(path, 0x1FDu);
if ( !result )
return result;
error(0, 0, "Error creating %s", path);
}
else
{
if ( (v3.st_mode & 0xF000) == 0x4000 )
return 0;
error(0, 0, "%s exists but is not a directory.\n", path);
}
do
{
puts("Can't write high scores to default target\nfile or read default keyfile.\nPlay anyway? [y/n]");
v1 = getchar();
if ( v1 == 110 )
exit(0);
}
while ( v1 != 121 );
return 1;
}

canonical_decompiled_code:
int __fastcall func3(char *path)
{
char v1; // al
int result; // eax
struct stat v3; // [rsp+0h] [rbp-98h] BYREF

if ( stat(path, &v3) == -1 )
{
result = mkdir(path, 0x1FDu);
if ( !result )
return result;
error(0, 0, "Error creating %s", path);
}
else
{
if ( (v3.st_mode & 0xF000) == 0x4000 )
return 0;
error(0, 0, "%s exists but is not a directory.\n", path);
}
do
{
puts("Can't write high scores to default target\nfile or read default keyfile.\nPlay anyway? [y/n]");
v1 = getchar();
if ( v1 == 110 )
exit(0);
}
while ( v1 != 121 );
return 1;
}

original_code:
int mk_default_dir(char *path) {
    char *notdirerr = "%s exists but is not a directory.\n";
    char *othererr = "Error creating %s";
    char *play_anyway =
"Can't write high scores to default target\nfile or read default keyfile.\n"
"Play anyway? [y/n]";
    char reply;
    struct stat buf;
    int statret;
    int mkdirret;
    statret = stat(path, &buf);
    if (statret == -1) {
        mkdirret = mkdir(path, (0400|0200|0100) | ((0400|0200|0100) >> 3) | ((0400 >> 3) >> 3) | ((0100 >> 3) >> 3));
        if (mkdirret == 0) {
            return 0;
        }
        error(0, 0, othererr, path);
    } else if (((((buf.st_mode)) & 0170000) == (0040000))) {
        return 0;
    } else {
        error(0, 0, notdirerr, path);
    }
    while (1) {
        puts(play_anyway);
        reply = getchar();
        if (reply == 'n')
            exit(0);
        if (reply == 'y')
            break;
    }
    return 1;
}

variable_types:
path
char *

variable_types:
notdirerr
char *

variable_types:
othererr
char *

variable_types: reply char

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }

variable_types: statret int

variable_types: mkdirret int

user_defined_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


decompiled_code:
char *__fastcall extend_str_space(char *src, int a2)
{
int v3; // ebp
int v4; // er12
char *v5; // rdi
char *v6; // rcx
char *v7; // rax

v3 = strlen(src);
v4 = a2 + v3 + 1;
v5 = (char *)malloc(v4);
if ( v5 )
{
v6 = strcpy(v5, src);
v5 = v6;
if ( v3 < a2 + v3 )
{
v7 = &v6[v3];
do
*v7++ = 32;
while ( v7 != &v6[v3 + 1 + (unsigned __int64)(unsigned int)(a2 - 1)] );
}
v6[v4 - 1] = 0;
}
return v5;
}

canonical_decompiled_code:
char *__fastcall func0(char *src, int a2)
{
int v3; // ebp
int v4; // er12
char *v5; // rdi
char *v6; // rcx
char *v7; // rax

v3 = strlen(src);
v4 = a2 + v3 + 1;
v5 = (char *)malloc(v4);
if ( v5 )
{
v6 = strcpy(v5, src);
v5 = v6;
if ( v3 < a2 + v3 )
{
v7 = &v6[v3];
do
*v7++ = 32;
while ( v7 != &v6[v3 + 1 + (unsigned __int64)(unsigned int)(a2 - 1)] );
}
v6[v4 - 1] = 0;
}
return v5;
}

original_code:
char *extend_str_space(char *string, int extend_by) {
    char *ext;
    int len, i;
    len = strlen(string) + 1;
    ext = malloc((len + extend_by) * sizeof(char));
    if(!ext)
        return ((void *)0);
    ext = strcpy(ext, string);
    for (i = len - 1; i < len + extend_by - 1; i++) {
        ext[i] = ' ';
    }
    ext[len + extend_by - 1] = '\0';
    return ext;
}

canonical_original_code:
char *extend_str_space(char *string, int extend_by) {
    char *ext;
    int len; int i;
    len = strlen(string) + 1;
    ext = malloc((len + extend_by) * sizeof(char));
    if(!ext)
        return ((void *)0);
    ext = strcpy(ext, string);
    for (i = len - 1; i < len + extend_by - 1; i++) {
        ext[i] = ' ';
    }
    ext[len + extend_by - 1] = '\0';
    return ext;
}

variable_types:
string
char *

variable_types:
ext
char *

variable_types: len int

variable_types: i int

return_type: char *


decompiled_code:
const char *__fastcall append_dotnr_to_path(const char *a1, char a2)
{
int v2; // eax

v2 = strlen(a1);
a1[v2 - 2] = 46;
*(_WORD *)&a1[v2 - 1] = (unsigned __int8)(a2 + 48);
return a1;
}

canonical_decompiled_code:
const char *__fastcall func1(const char *a1, char a2)
{
int v2; // eax

v2 = strlen(a1);
a1[v2 - 2] = 46;
*(_WORD *)&a1[v2 - 1] = (unsigned __int8)(a2 + 48);
return a1;
}

original_code:
char *append_dotnr_to_path(char *path, int number) {
    int len;
    len = strlen(path);
    path[len - 2] = '.';
    path[len - 1] = '0' + number;
    path[len] = '\0';
    return path;
}

variable_types: number int


decompiled_code:
_BOOL8 __fastcall is_high_score(int a1, char a2, char *a3)
{
char *v3; // rax
const char *v4; // rax
FILE *v5; // rax
void **v6; // rdx
int v7; // ecx

v3 = extend_str_space(a3, 2);
v4 = append_dotnr_to_path(v3, a2);
v5 = readscores(v4);
if ( !v5 )
return 1LL;
v6 = &v5->__pad2;
while ( *(_QWORD *)&v5->_flags )
{
v7 = (int)v5->_IO_read_ptr;
v5 = (FILE *)((char *)v5 + 16);
if ( v5 == (FILE *)v6 )
return a1 > v7;
}
return 1LL;
}

canonical_decompiled_code:
_BOOL8 __fastcall func3(int a1, char a2, char *a3)
{
char *v3; // rax
const char *v4; // rax
FILE *v5; // rax
void **v6; // rdx
int v7; // ecx

v3 = func0(a3, 2);
v4 = func1(v3, a2);
v5 = readscores(v4);
if ( !v5 )
return 1LL;
v6 = &v5->__pad2;
while ( *(_QWORD *)&v5->_flags )
{
v7 = (int)v5->_IO_read_ptr;
v5 = (FILE *)((char *)v5 + 16);
if ( v5 == (FILE *)v6 )
return a1 > v7;
}
return 1LL;
}

original_code:
int is_high_score(int score, int level, char *path) {
    struct hiscore *scores;
    char *extpath;
    int i, lastscore = -1;
    extpath = extend_str_space(path, 2);
    extpath = append_dotnr_to_path(extpath, level);
    scores = readscores(extpath);
    if (!scores) {
        return 1;
    }
    for (i = 0; i < 10; i++) {
        if (!(scores+i)->name) {
            return 1;
        }
        lastscore = (scores+i)->score;
    }
    if (score > lastscore)
        return 1;
    return 0;
}

canonical_original_code:
int is_high_score(int score, int level, char *path) {
    struct hiscore *scores;
    char *extpath;
    int i; int lastscore = -1;
    extpath = extend_str_space(path, 2);
    extpath = append_dotnr_to_path(extpath, level);
    scores = readscores(extpath);
    if (!scores) {
        return 1;
    }
    for (i = 0; i < 10; i++) {
        if (!(scores+i)->name) {
            return 1;
        }
        lastscore = (scores+i)->score;
    }
    if (score > lastscore)
        return 1;
    return 0;
}

variable_types: score int

variable_types: level int

variable_types: struct hiscore { char *name; int score; } *

variable_types:
extpath
char *

variable_types: lastscore int


printscores

decompiled_code:
void __fastcall printscores(char *a1, unsigned int a2)
{
char v2; // bl
char v3; // r15
const char *v4; // r12
unsigned int v5; // er13
int v6; // er14
FILE *v7; // rbx
int v8; // ebp

v2 = 0;
if ( a2 <= 9 )
v2 = a2;
v3 = 9;
if ( a2 <= 9 )
v3 = a2;
v4 = extend_str_space(a1, 2);
v5 = v2;
v6 = 0;
while ( 1 )
{
v4 = append_dotnr_to_path(v4, v5);
v7 = readscores(v4);
if ( v7 )
{
dashes(27);
printf(" High Scores - level %d\n", v5);
dashes(27);
v8 = 0;
while ( *(_QWORD *)&v7->_flags )
{
printf("%3d: %5d :: %s\n", (unsigned int)++v8, LODWORD(v7->_IO_read_ptr), *(const char **)&v7->_flags);
++v6;
v7 = (FILE *)((char *)v7 + 16);
if ( v8 == 10 )
goto LABEL_7;
}
if ( !v8 )
break;
}
LABEL_7:
if ( (char)++v5 > v3 )
goto LABEL_14;
}
error(1, 0, "file empty -- %s", v4);
LABEL_14:
if ( !v6 )
{
error(1, 0, "error reading high score file");
JUMPOUT(0x68FLL);
}
}

canonical_decompiled_code:
void __fastcall func6(char *a1, unsigned int a2)
{
char v2; // bl
char v3; // r15
const char *v4; // r12
unsigned int v5; // er13
int v6; // er14
FILE *v7; // rbx
int v8; // ebp

v2 = 0;
if ( a2 <= 9 )
v2 = a2;
v3 = 9;
if ( a2 <= 9 )
v3 = a2;
v4 = func0(a1, 2);
v5 = v2;
v6 = 0;
while ( 1 )
{
v4 = func1(v4, v5);
v7 = readscores(v4);
if ( v7 )
{
func5(27);
printf(" High Scores - level %d\n", v5);
func5(27);
v8 = 0;
while ( *(_QWORD *)&v7->_flags )
{
printf("%3d: %5d :: %s\n", (unsigned int)++v8, LODWORD(v7->_IO_read_ptr), *(const char **)&v7->_flags);
++v6;
v7 = (FILE *)((char *)v7 + 16);
if ( v8 == 10 )
goto LABEL_7;
}
if ( !v8 )
break;
}
LABEL_7:
if ( (char)++v5 > v3 )
goto LABEL_14;
}
error(1, 0, "file empty -- %s", v4);
LABEL_14:
if ( !v6 )
{
error(1, 0, "error reading high score file");
JUMPOUT(0x68FLL);
}
}

original_code:
void printscores(char *path, int level) {
    struct hiscore *scores;
    char *extpath = ((void *)0);
    int printed_count = 0;
    char *heading = "  High Scores - level %d\n";
    char *fstr = "%3d: %5d :: %s\n";
    char fromlevel, tolevel;
    int i;
    if (level >= 0 && level <= 9) {
        fromlevel = tolevel = level;
    } else {
        fromlevel = 0;
        tolevel = 9;
    }
    extpath = extend_str_space(path, 2);
    for ( ; fromlevel <= tolevel; fromlevel++) {
        extpath = append_dotnr_to_path(extpath, fromlevel);
        if ( (scores = readscores(extpath)) ) {
            dashes(strlen(heading) + 2);
            printf(heading, fromlevel);
            dashes(strlen(heading) + 2);
        }
        if (!scores)
            continue;
        for (i = 0; i < 10; i++) {
            if ((scores + i)->name) {
                printf(fstr, i + 1, (scores + i)->score,
                        (scores + i)->name);
                printed_count++;
            }
            else {
                if(i == 0)
                    error(1, 0, "file empty -- %s", extpath);
                else
                    break;
            }
        }
    }
    if (printed_count == 0)
        error(1, 0, "error reading high score file");
}

canonical_original_code:
void printscores(char *path, int level) {
    struct hiscore *scores;
    char *extpath = ((void *)0);
    int printed_count = 0;
    char *heading = "  High Scores - level %d\n";
    char *fstr = "%3d: %5d :: %s\n";
    char fromlevel; char tolevel;
    int i;
    if (level >= 0 && level <= 9) {
        fromlevel = tolevel = level;
    } else {
        fromlevel = 0;
        tolevel = 9;
    }
    extpath = extend_str_space(path, 2);
    for ( ; fromlevel <= tolevel; fromlevel++) {
        extpath = append_dotnr_to_path(extpath, fromlevel);
        if ( (scores = readscores(extpath)) ) {
            dashes(strlen(heading) + 2);
            printf(heading, fromlevel);
            dashes(strlen(heading) + 2);
        }
        if (!scores)
            continue;
        for (i = 0; i < 10; i++) {
            if ((scores + i)->name) {
                printf(fstr, i + 1, (scores + i)->score,
                        (scores + i)->name);
                printed_count++;
            }
            else {
                if(i == 0)
                    error(1, 0, "file empty -- %s", extpath);
                else
                    break;
            }
        }
    }
    if (printed_count == 0)
        error(1, 0, "error reading high score file");
}

variable_types:
path
char *

variable_types:
heading
char *

variable_types:
fstr
char *

variable_types: fromlevel char

variable_types: tolevel char

user_defined_types: struct hiscore { char *name; int score; }


getdir

decompiled_code:
__int64 __fastcall getdir(unsigned int a1)
{
int v1; // eax
unsigned int v2; // edx

v1 = wgetch(stdscr);
v2 = 1;
if ( key_up != v1 )
{
if ( key_down == v1 )
{
v2 = 2;
}
else if ( key_left == v1 )
{
v2 = 3;
}
else if ( key_right == v1 )
{
v2 = 4;
}
else
{
v2 = 0;
if ( key_stop != v1 )
{
if ( key_pause == v1 )
{
v2 = 9;
}
else
{
v2 = -2;
if ( key_esc != v1 )
v2 = a1;
}
}
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1)
{
int v1; // eax
unsigned int v2; // edx

v1 = wgetch(stdscr);
v2 = 1;
if ( key_up != v1 )
{
if ( key_down == v1 )
{
v2 = 2;
}
else if ( key_left == v1 )
{
v2 = 3;
}
else if ( key_right == v1 )
{
v2 = 4;
}
else
{
v2 = 0;
if ( key_stop != v1 )
{
if ( key_pause == v1 )
{
v2 = 9;
}
else
{
v2 = -2;
if ( key_esc != v1 )
v2 = a1;
}
}
}
}
return v2;
}

original_code:
dir_t getdir(dir_t curdir) {
    extern int key_up, key_down, key_left, key_right;
    extern int key_stop, key_pause, key_esc;
    int key = wgetch(stdscr);
    if (key == key_up)
        return 1;
    if (key == key_down)
        return 2;
    if (key == key_left)
        return 3;
    if (key == key_right)
        return 4;
    if (key == key_stop)
        return 0;
    if (key == key_pause)
        return 9;
    if (key == key_esc)
        return -2;
    return curdir;
}

canonical_original_code:
int getdir(int curdir) {
    extern int key_up; extern int key_down; extern int key_left; extern int key_right;
    extern int key_stop; extern int key_pause; extern int key_esc;
    int key = wgetch(stdscr);
    if (key == key_up)
        return 1;
    if (key == key_down)
        return 2;
    if (key == key_left)
        return 3;
    if (key == key_right)
        return 4;
    if (key == key_stop)
        return 0;
    if (key == key_pause)
        return 9;
    if (key == key_esc)
        return -2;
    return curdir;
}

variable_types: curdir int

variable_types: key int


drawplayer

decompiled_code:
__int64 __fastcall drawplayer(__int64 a1, __int64 a2)
{
int v2; // eax
__int64 v4; // [rsp+8h] [rbp-30h] BYREF
double v5; // [rsp+10h] [rbp-28h] BYREF
double v6[4]; // [rsp+18h] [rbp-20h] BYREF

v4 = a2;
v6[0] = player_row_delay / (double)rows;
v5 = player_col_delay / (double)cols;
v2 = setpos(a1, &v4, v6, &v5, &lasttime_3);
if ( (_DWORD)a1 == -1 || v2 )
{
v4 = drawfigure(v4, 79LL, a2, 32LL, (unsigned int)lastrows_1, (unsigned int)lastcols_2);
lastrows_1 = rows;
lastcols_2 = cols;
}
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2)
{
int v2; // eax
__int64 v4; // [rsp+8h] [rbp-30h] BYREF
double v5; // [rsp+10h] [rbp-28h] BYREF
double v6[4]; // [rsp+18h] [rbp-20h] BYREF

v4 = a2;
v6[0] = player_row_delay / (double)rows;
v5 = player_col_delay / (double)cols;
v2 = setpos(a1, &v4, v6, &v5, &lasttime_3);
if ( (_DWORD)a1 == -1 || v2 )
{
v4 = drawfigure(v4, 79LL, a2, 32LL, (unsigned int)lastrows_1, (unsigned int)lastcols_2);
lastrows_1 = rows;
lastcols_2 = cols;
}
return v4;
}

original_code:
struct pos drawplayer(dir_t dir, struct pos curpos) {
    extern int rows, cols;
    extern double player_row_delay;
    extern double player_col_delay;
    static double lasttime;
    static int lastrows, lastcols;
    struct pos oldpos;
    double rdelay = player_row_delay / rows;
    double cdelay = player_col_delay / cols;
    oldpos = curpos;
    if (setpos(dir, &curpos, &rdelay, &cdelay, &lasttime) || dir == -1) {
        curpos = drawfigure(curpos, 'O', oldpos, ' ',
                            lastrows, lastcols);
        lastrows = rows, lastcols = cols;
    }
    return curpos;
}

canonical_original_code:
struct pos drawplayer(int dir, struct pos curpos) {
    extern int rows; extern int cols;
    extern double player_row_delay;
    extern double player_col_delay;
    static double lasttime;
    static int lastrows; static int lastcols;
    struct pos oldpos;
    double rdelay = player_row_delay / rows;
    double cdelay = player_col_delay / cols;
    oldpos = curpos;
    if (setpos(dir, &curpos, &rdelay, &cdelay, &lasttime) || dir == -1) {
        curpos = drawfigure(curpos, 'O', oldpos, ' ',
                            lastrows, lastcols);
        lastrows = rows, lastcols = cols;
    }
    return curpos;
}

variable_types: dir int

variable_types:
curpos
struct pos

variable_types: rows int

variable_types: cols int

variable_types: lasttime double

variable_types: lastrows int

variable_types: lastcols int

variable_types:
oldpos
struct pos { int row; int col; }

variable_types: rdelay double

variable_types: cdelay double

return_type: struct pos { int row; int col; }


printstatus

decompiled_code:
__int64 __fastcall printstatus(unsigned int a1)
{
int v1; // ebx
__int64 result; // rax

if ( oldscrrow_0 != rows && cols > 0 )
{
v1 = 0;
do
{
if ( wmove(stdscr, oldscrrow_0, v1) != -1 )
waddch(stdscr, 0x20uLL);
++v1;
}
while ( cols > v1 );
}
mvprintw(rows, 0, "Score: %d", a1);
mvprintw(rows, cols - 9, "Level: %d", level);
result = (unsigned int)rows;
oldscrrow_0 = rows;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int a1)
{
int v1; // ebx
__int64 result; // rax

if ( oldscrrow_0 != rows && cols > 0 )
{
v1 = 0;
do
{
if ( wmove(stdscr, oldscrrow_0, v1) != -1 )
waddch(stdscr, 0x20uLL);
++v1;
}
while ( cols > v1 );
}
mvprintw(rows, 0, "Score: %d", a1);
mvprintw(rows, cols - 9, "Level: %d", level);
result = (unsigned int)rows;
oldscrrow_0 = rows;
return result;
}

original_code:
void printstatus (int score) {
    extern int rows;
    extern int cols;
    extern int level;
    static int oldscrrow;
    int clrcol;
    char *scoref = "Score: %d";
    char *levelf = "Level: %d";
    if (oldscrrow != rows)
        for (clrcol = 0; clrcol < cols; clrcol++)
            (wmove((stdscr),((oldscrrow)),((clrcol))) == (-1) ? (-1) : waddch((stdscr),((' '))));
    mvprintw(rows, 0, scoref, score);
    mvprintw(rows, cols - strlen(levelf), levelf, level);
    oldscrrow = rows;
}

canonical_original_code:
void printstatus(int score) {
    extern int rows;
    extern int cols;
    extern int level;
    static int oldscrrow;
    int clrcol;
    char *scoref = "Score: %d";
    char *levelf = "Level: %d";
    if (oldscrrow != rows)
        for (clrcol = 0; clrcol < cols; clrcol++)
            (wmove((stdscr),((oldscrrow)),((clrcol))) == (-1) ? (-1) : waddch((stdscr),((' '))));
    mvprintw(rows, 0, scoref, score);
    mvprintw(rows, cols - strlen(levelf), levelf, level);
    oldscrrow = rows;
}

variable_types: score int

variable_types: level int

variable_types: oldscrrow int

variable_types: clrcol int

variable_types:
scoref
char *

variable_types:
levelf
char *


fobjects

decompiled_code:
__int64 __fastcall fobjects(__int64 a1, int a2)
{
__int64 *v2; // rbp
__int64 v3; // rbx
__int64 v4; // rbx
int v5; // ecx
int v6; // eax
int v7; // eax
__int64 v9[11]; // [rsp+0h] [rbp-58h] BYREF

if ( (float)((float)a2 / 5.0) == (float)(objcount_5 + 3) && objcount_5 <= 4 )
{
v4 = objcount_5;
LODWORD(lastpos_4[objcount_5]) = 0;
HIDWORD(lastpos_4[v4]) = genrand(0LL, cols);
v5 = genrand((unsigned int)(100 * fobj_init_delay_min), (unsigned int)(100 * fobj_init_delay_max));
v6 = objcount_5;
delay_3[objcount_5] = (float)v5 / 100.0 / (double)rows;
objcount_5 = v6 + 1;
}
if ( objcount_5 <= 0 )
return 0LL;
v2 = v9;
v3 = 0LL;
do
{
*v2 = lastpos_4[v3];
if ( (unsigned int)setpos(2LL, v2, &delay_3[v3], &delay_3[v3], (char *)&lasttime_2 + 8 * v3) )
{
delay_3[v3] = pow(
fobj_base,
COERCE_DOUBLE(COERCE_UNSIGNED_INT64((double)*(int *)v2 / (double)rows) ^ LC2) * fobj_acc)
* fobj_fall_delay_start
+ fobj_fall_delay_end;
if ( rows - 1 <= SLODWORD(lastpos_4[v3]) )
{
*(_DWORD *)v2 = 0;
*((_DWORD *)v2 + 1) = genrand(0LL, cols);
delay_3[v3] = (float)(int)genrand(
(unsigned int)(100 * fobj_hang_delay_min),
(unsigned int)(100 * fobj_hang_delay_max))
/ 100.0;
}
lastpos_4[(int)v3] = drawfigure(
v9[(int)v3],
111LL,
lastpos_4[(int)v3],
32LL,
(unsigned int)lastrows_0[v3],
(unsigned int)lastcols_1[v3]);
v7 = rows;
delay_3[v3] = delay_3[v3] / (double)rows;
lastrows_0[v3] = v7;
lastcols_1[v3] = cols;
}
if ( *v2 == a1 )
return 1LL;
++v3;
++v2;
}
while ( objcount_5 > (int)v3 );
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, int a2)
{
__int64 *v2; // rbp
__int64 v3; // rbx
__int64 v4; // rbx
int v5; // ecx
int v6; // eax
int v7; // eax
__int64 v9[11]; // [rsp+0h] [rbp-58h] BYREF

if ( (float)((float)a2 / 5.0) == (float)(objcount_5 + 3) && objcount_5 <= 4 )
{
v4 = objcount_5;
LODWORD(lastpos_4[objcount_5]) = 0;
HIDWORD(lastpos_4[v4]) = genrand(0LL, cols);
v5 = genrand((unsigned int)(100 * fobj_init_delay_min), (unsigned int)(100 * fobj_init_delay_max));
v6 = objcount_5;
delay_3[objcount_5] = (float)v5 / 100.0 / (double)rows;
objcount_5 = v6 + 1;
}
if ( objcount_5 <= 0 )
return 0LL;
v2 = v9;
v3 = 0LL;
do
{
*v2 = lastpos_4[v3];
if ( (unsigned int)setpos(2LL, v2, &delay_3[v3], &delay_3[v3], (char *)&lasttime_2 + 8 * v3) )
{
delay_3[v3] = pow(
fobj_base,
COERCE_DOUBLE(COERCE_UNSIGNED_INT64((double)*(int *)v2 / (double)rows) ^ LC2) * fobj_acc)
* fobj_fall_delay_start
+ fobj_fall_delay_end;
if ( rows - 1 <= SLODWORD(lastpos_4[v3]) )
{
*(_DWORD *)v2 = 0;
*((_DWORD *)v2 + 1) = genrand(0LL, cols);
delay_3[v3] = (float)(int)genrand(
(unsigned int)(100 * fobj_hang_delay_min),
(unsigned int)(100 * fobj_hang_delay_max))
/ 100.0;
}
lastpos_4[(int)v3] = drawfigure(
v9[(int)v3],
111LL,
lastpos_4[(int)v3],
32LL,
(unsigned int)lastrows_0[v3],
(unsigned int)lastcols_1[v3]);
v7 = rows;
delay_3[v3] = delay_3[v3] / (double)rows;
lastrows_0[v3] = v7;
lastcols_1[v3] = cols;
}
if ( *v2 == a1 )
return 1LL;
++v3;
++v2;
}
while ( objcount_5 > (int)v3 );
return 0LL;
}

original_code:
bool_t fobjects(struct pos plpos, int score) {
    extern int rows, cols;
    extern int fobj_init_delay_min, fobj_init_delay_max;
    extern int fobj_hang_delay_min, fobj_hang_delay_max;
    extern double fobj_fall_delay_start, fobj_fall_delay_end;
    extern double fobj_base, fobj_acc;
    static struct pos lastpos[5];
    static double lasttime[5];
    static int lastrows[5], lastcols[5];
    static int objcount;
    struct pos objpos[5];
    static double delay[5];
    int i;
    if ((float)score / (float)5 == objcount +
       3 && objcount < 5) {
        lastpos[objcount].row = 0;
        lastpos[objcount].col = genrand(0,cols);
        delay[objcount] = (float)genrand(fobj_init_delay_min * 100,
                           fobj_init_delay_max * 100) / 100.0;;
        delay[objcount] /= rows;
        objcount++;
    }
    for (i = 0; i < objcount; i++) {
        objpos[i] = lastpos[i];
        if (setpos(2, objpos+i, delay+i, delay+i, lasttime+i)) {
            delay[i] = fobj_fall_delay_end + fobj_fall_delay_start *
                       pow(fobj_base, -((double)objpos[i].row / (double)rows) *
                       fobj_acc);
            if (lastpos[i].row > rows - 2) {
                objpos[i].row = 0;
                objpos[i].col = genrand(0, cols);
                delay[i] = (float)genrand(fobj_hang_delay_min * 100,
                             fobj_hang_delay_max * 100) / 100.0;
            }
            lastpos[i] = drawfigure(objpos[i], 'o', lastpos[i], ' ',
                                    lastrows[i], lastcols[i]);
            delay[i] /= rows;
            lastrows[i] = rows, lastcols[i] = cols;
        }
        if (objpos[i].row == plpos.row && objpos[i].col == plpos.col)
            return 1;
    }
    return 0;
}

canonical_original_code:
int fobjects(struct pos plpos, int score) {
    extern int rows; extern int cols;
    extern int fobj_init_delay_min; extern int fobj_init_delay_max;
    extern int fobj_hang_delay_min; extern int fobj_hang_delay_max;
    extern double fobj_fall_delay_start; extern double fobj_fall_delay_end;
    extern double fobj_base; extern double fobj_acc;
    static struct pos lastpos[5];
    static double lasttime[5];
    static int lastrows[5]; static int lastcols[5];
    static int objcount;
    struct pos objpos[5];
    static double delay[5];
    int i;
    if ((float)score / (float)5 == objcount +
       3 && objcount < 5) {
        lastpos[objcount].row = 0;
        lastpos[objcount].col = genrand(0,cols);
        delay[objcount] = (float)genrand(fobj_init_delay_min * 100,
                           fobj_init_delay_max * 100) / 100.0;;
        delay[objcount] /= rows;
        objcount++;
    }
    for (i = 0; i < objcount; i++) {
        objpos[i] = lastpos[i];
        if (setpos(2, objpos+i, delay+i, delay+i, lasttime+i)) {
            delay[i] = fobj_fall_delay_end + fobj_fall_delay_start *
                       pow(fobj_base, -((double)objpos[i].row / (double)rows) *
                       fobj_acc);
            if (lastpos[i].row > rows - 2) {
                objpos[i].row = 0;
                objpos[i].col = genrand(0, cols);
                delay[i] = (float)genrand(fobj_hang_delay_min * 100,
                             fobj_hang_delay_max * 100) / 100.0;
            }
            lastpos[i] = drawfigure(objpos[i], 'o', lastpos[i], ' ',
                                    lastrows[i], lastcols[i]);
            delay[i] /= rows;
            lastrows[i] = rows, lastcols[i] = cols;
        }
        if (objpos[i].row == plpos.row && objpos[i].col == plpos.col)
            return 1;
    }
    return 0;
}

variable_types:
plpos
struct pos { int row; int col; }

variable_types:
lastpos
struct pos { int row; int col; } [5]

variable_types:
lasttime
double [5]

variable_types:
lastrows
int [5]

variable_types:
lastcols
int [5]

variable_types: objcount int

variable_types:
objpos
struct pos { int row; int col; } [5]

variable_types:
delay
double [5]

variable_types: i int


hunt

original_code:
dir_t hunt(struct pos *target, struct pos *hunter, int logic) {
    extern int rows, cols;
    int up, down, left, right;
    up = down = left = right = 0;
    logic = logic % 3;
    if (
            (
                (double)abs(hunter->row - target->row)
                < 0.22 * (double)rows
                && (double)abs(hunter->col - target->col)
                < 0.0625 * (double)cols
            )
            || (double)abs(hunter->row - target->row)
                > 0.44 * (double)rows
            || (double)abs(hunter->col - target->col)
                > 0.375 * (double)cols
        )
        logic = 0;
    if (logic == 1) {
        if (hunter->row < target->row)
            down = 1;
        else if (hunter->row > target->row)
            up = 1;
        else if (hunter->col < target->col)
            right = 1;
        else if (hunter->col > target->col)
            left = 1;
    }
    if (logic == 2) {
        if (hunter->col < target->col)
            right = 1;
        else if (hunter->col > target->col)
            left = 1;
        else if (hunter->row < target->row)
            down = 1;
        else if (hunter->row > target->row)
            up = 1;
    }
    if (logic == 0) {
        if (hunter->row < target->row)
            down = 1;
        else if (hunter->row > target->row)
            up = 1;
        if (hunter->col < target->col)
            right = 1;
        else if (hunter->col > target->col)
            left = 1;
    }
    if (up && right)
        return 5;
    else if (up && left)
        return 6;
    else if (down && right)
        return 7;
    else if (down && left)
        return 8;
    else if (up)
        return 1;
    else if (down)
        return 2;
    else if (right)
        return 4;
    else if (left)
        return 3;
    else
        return 0;
}

canonical_original_code:
int hunt(struct pos *target, struct pos *hunter, int logic) {
    extern int rows; extern int cols;
    int up; int down; int left; int right;
    up = down = left = right = 0;
    logic = logic % 3;
    if (
            (
                (double)abs(hunter->row - target->row)
                < 0.22 * (double)rows
                && (double)abs(hunter->col - target->col)
                < 0.0625 * (double)cols
            )
            || (double)abs(hunter->row - target->row)
                > 0.44 * (double)rows
            || (double)abs(hunter->col - target->col)
                > 0.375 * (double)cols
        )
        logic = 0;
    if (logic == 1) {
        if (hunter->row < target->row)
            down = 1;
        else if (hunter->row > target->row)
            up = 1;
        else if (hunter->col < target->col)
            right = 1;
        else if (hunter->col > target->col)
            left = 1;
    }
    if (logic == 2) {
        if (hunter->col < target->col)
            right = 1;
        else if (hunter->col > target->col)
            left = 1;
        else if (hunter->row < target->row)
            down = 1;
        else if (hunter->row > target->row)
            up = 1;
    }
    if (logic == 0) {
        if (hunter->row < target->row)
            down = 1;
        else if (hunter->row > target->row)
            up = 1;
        if (hunter->col < target->col)
            right = 1;
        else if (hunter->col > target->col)
            left = 1;
    }
    if (up && right)
        return 5;
    else if (up && left)
        return 6;
    else if (down && right)
        return 7;
    else if (down && left)
        return 8;
    else if (up)
        return 1;
    else if (down)
        return 2;
    else if (right)
        return 4;
    else if (left)
        return 3;
    else
        return 0;
}

variable_types:
target
struct pos { int row; int col; } *

variable_types:
hunter
struct pos *

variable_types: logic int

variable_types: rows int

variable_types: cols int

variable_types: up int

variable_types: down int

variable_types: left int

variable_types: right int


drawenemies

decompiled_code:
__int64 __fastcall drawenemies(__int64 a1, int a2)
{
int v2; // ebx
__int64 v3; // rbx
__int64 v4; // rbp
int v5; // ebx
int v6; // eax
int i; // er12
unsigned int v8; // eax
double v9; // xmm2_8
double v10; // r12
double v11; // xmm0_8
__int64 v13[16]; // [rsp+8h] [rbp-80h] BYREF

v13[0] = a1;
v2 = encount_7;
if ( (float)((float)a2 / 5.0) == (float)encount_7 && encount_7 <= 2 )
{
LODWORD(lastpos_6[v2]) = genrand(0LL, (unsigned int)rows);
v5 = encount_7;
HIDWORD(lastpos_6[v5]) = genrand(0LL, cols);
v6 = encount_7;
delaydiff_5[encount_7] = 0LL;
encount_7 = v6 + 1;
immortaltimer_4 = getnow();
displaytimer_3 = 1;
}
if ( encount_7 <= 0 )
return 0LL;
v3 = 0LL;
v4 = 0LL;
do
{
v13[v3 + 9] = lastpos_6[v3];
v8 = hunt((int *)v13, (int *)&v13[v3 + 9], v4);
v9 = *(double *)&delaydiff_5[v3];
*(double *)&v13[v3 + 5] = enemy_row_delay / (double)rows + v9 / (double)rows;
*(double *)&v13[v3 + 1] = enemy_col_delay / (double)cols + v9 / (double)cols;
if ( (unsigned int)setpos(v8, &v13[v3 + 9], &v13[v3 + 5], &v13[v3 + 1], (char *)&lasttime_2 + v3 * 8) )
{
lastpos_6[(int)v4] = drawfigure(
v13[(int)v4 + 9],
35LL,
lastpos_6[(int)v4],
32LL,
(unsigned int)lastrows_0[v4],
(unsigned int)lastcols_1[v4]);
v10 = *(double *)&immortaltimer_4 + enemy_nokill_time;
v11 = v10 - getnow();
if ( v11 >= 0.0 )
{
mvprintw(rows, cols / 2 - 14, "* Untouchable for %d seconds!", (unsigned int)((int)v11 + 1));
}
else
{
if ( displaytimer_3 == 1 )
{
for ( i = 0; i != 29; ++i )
{
if ( wmove(stdscr, rows, i + cols / 2 - 14) != -1 )
waddch(stdscr, 0x20uLL);
}
displaytimer_3 = 0;
}
if ( __PAIR64__(HIDWORD(v13[v3 + 9]), v13[v3 + 9]) == v13[0] )
return 1LL;
}
lastrows_0[v4] = rows;
lastcols_1[v4] = cols;
}
++v4;
++v3;
}
while ( encount_7 > (int)v4 );
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, int a2)
{
int v2; // ebx
__int64 v3; // rbx
__int64 v4; // rbp
int v5; // ebx
int v6; // eax
int i; // er12
unsigned int v8; // eax
double v9; // xmm2_8
double v10; // r12
double v11; // xmm0_8
__int64 v13[16]; // [rsp+8h] [rbp-80h] BYREF

v13[0] = a1;
v2 = encount_7;
if ( (float)((float)a2 / 5.0) == (float)encount_7 && encount_7 <= 2 )
{
LODWORD(lastpos_6[v2]) = genrand(0LL, (unsigned int)rows);
v5 = encount_7;
HIDWORD(lastpos_6[v5]) = genrand(0LL, cols);
v6 = encount_7;
delaydiff_5[encount_7] = 0LL;
encount_7 = v6 + 1;
immortaltimer_4 = getnow();
displaytimer_3 = 1;
}
if ( encount_7 <= 0 )
return 0LL;
v3 = 0LL;
v4 = 0LL;
do
{
v13[v3 + 9] = lastpos_6[v3];
v8 = func0((int *)v13, (int *)&v13[v3 + 9], v4);
v9 = *(double *)&delaydiff_5[v3];
*(double *)&v13[v3 + 5] = enemy_row_delay / (double)rows + v9 / (double)rows;
*(double *)&v13[v3 + 1] = enemy_col_delay / (double)cols + v9 / (double)cols;
if ( (unsigned int)setpos(v8, &v13[v3 + 9], &v13[v3 + 5], &v13[v3 + 1], (char *)&lasttime_2 + v3 * 8) )
{
lastpos_6[(int)v4] = drawfigure(
v13[(int)v4 + 9],
35LL,
lastpos_6[(int)v4],
32LL,
(unsigned int)lastrows_0[v4],
(unsigned int)lastcols_1[v4]);
v10 = *(double *)&immortaltimer_4 + enemy_nokill_time;
v11 = v10 - getnow();
if ( v11 >= 0.0 )
{
mvprintw(rows, cols / 2 - 14, "* Untouchable for %d seconds!", (unsigned int)((int)v11 + 1));
}
else
{
if ( displaytimer_3 == 1 )
{
for ( i = 0; i != 29; ++i )
{
if ( wmove(stdscr, rows, i + cols / 2 - 14) != -1 )
waddch(stdscr, 0x20uLL);
}
displaytimer_3 = 0;
}
if ( __PAIR64__(HIDWORD(v13[v3 + 9]), v13[v3 + 9]) == v13[0] )
return 1LL;
}
lastrows_0[v4] = rows;
lastcols_1[v4] = cols;
}
++v4;
++v3;
}
while ( encount_7 > (int)v4 );
return 0LL;
}

original_code:
bool_t drawenemies(struct pos plpos, int score) {
    extern int rows, cols;
    extern double enemy_row_delay, enemy_col_delay, enemy_nokill_time;
    static struct pos lastpos[3];
    static double lasttime[3];
    static int lastrows[3], lastcols[3];
    static double delaydiff[3];
    static int encount;
    static double immortaltimer;
    static bool_t displaytimer;
    struct pos enpos[3];
    double rdelay[3], cdelay[3];
    double timeleft;
    int i, j;
    dir_t dir = 0;
    char *immortaltext = "* Untouchable for %d seconds!";
    if ((float)score / (float)5 == encount
      && encount < 3) {
        lastpos[encount].row = genrand(0,rows);
        lastpos[encount].col = genrand(0,cols);
        delaydiff[encount] = 0 * encount;
        encount++;
        immortaltimer = getnow();
        displaytimer = 1;
    }
    for (i = 0; i < encount; i++) {
        enpos[i] = lastpos[i];
        dir = hunt(&plpos, enpos+i, i);
        rdelay[i] = enemy_row_delay / rows + delaydiff[i] / rows;
        cdelay[i] = enemy_col_delay / cols + delaydiff[i] / cols;
        if (setpos(dir, enpos+i, rdelay+i, cdelay+i, lasttime+i)) {
            lastpos[i] = drawfigure(enpos[i], '#', lastpos[i], ' ',
                                    lastrows[i], lastcols[i]);
            timeleft = immortaltimer + enemy_nokill_time - getnow();
            if (timeleft < 0) {
                if (displaytimer == 1) {
                    for (j = 0; j < strlen(immortaltext); j++) {
                        (wmove((stdscr),((rows)),((cols / 2 - strlen(immortaltext) / 2 + j))) == (-1) ? (-1) : waddch((stdscr),((' '))));
                    }
                    displaytimer = 0;
                }
                if (enpos[i].row == plpos.row && enpos[i].col == plpos.col)
                    return 1;
            } else {
                mvprintw(rows, cols/2-strlen(immortaltext)/2, immortaltext,
                    (int)timeleft + 1);
            }
            lastrows[i] = rows, lastcols[i] = cols;
        }
    }
    return 0;
}

canonical_original_code:
int drawenemies(struct pos plpos, int score) {
    extern int rows; extern int cols;
    extern double enemy_row_delay; extern double enemy_col_delay; extern double enemy_nokill_time;
    static struct pos lastpos[3];
    static double lasttime[3];
    static int lastrows[3]; static int lastcols[3];
    static double delaydiff[3];
    static int encount;
    static double immortaltimer;
    static int displaytimer;
    struct pos enpos[3];
    double rdelay[3]; double cdelay[3];
    double timeleft;
    int i; int j;
    int dir = 0;
    char *immortaltext = "* Untouchable for %d seconds!";
    if ((float)score / (float)5 == encount
      && encount < 3) {
        lastpos[encount].row = genrand(0,rows);
        lastpos[encount].col = genrand(0,cols);
        delaydiff[encount] = 0 * encount;
        encount++;
        immortaltimer = getnow();
        displaytimer = 1;
    }
    for (i = 0; i < encount; i++) {
        enpos[i] = lastpos[i];
        dir = hunt(&plpos, enpos+i, i);
        rdelay[i] = enemy_row_delay / rows + delaydiff[i] / rows;
        cdelay[i] = enemy_col_delay / cols + delaydiff[i] / cols;
        if (setpos(dir, enpos+i, rdelay+i, cdelay+i, lasttime+i)) {
            lastpos[i] = drawfigure(enpos[i], '#', lastpos[i], ' ',
                                    lastrows[i], lastcols[i]);
            timeleft = immortaltimer + enemy_nokill_time - getnow();
            if (timeleft < 0) {
                if (displaytimer == 1) {
                    for (j = 0; j < strlen(immortaltext); j++) {
                        (wmove((stdscr),((rows)),((cols / 2 - strlen(immortaltext) / 2 + j))) == (-1) ? (-1) : waddch((stdscr),((' '))));
                    }
                    displaytimer = 0;
                }
                if (enpos[i].row == plpos.row && enpos[i].col == plpos.col)
                    return 1;
            } else {
                mvprintw(rows, cols/2-strlen(immortaltext)/2, immortaltext,
                    (int)timeleft + 1);
            }
            lastrows[i] = rows, lastcols[i] = cols;
        }
    }
    return 0;
}

variable_types:
plpos
struct pos { int row; int col; }

variable_types: score int

variable_types:
lastpos
struct pos { int row; int col; } [3]

variable_types:
lasttime
double [3]

variable_types:
lastrows
int [3]

variable_types:
lastcols
int [3]

variable_types:
delaydiff
double [3]

variable_types: encount int

variable_types: immortaltimer double

variable_types: displaytimer int

variable_types:
enpos
struct pos { int row; int col; } [3]

variable_types:
rdelay
double [3]

variable_types:
cdelay
double [3]

variable_types: timeleft double

variable_types: j int

variable_types: dir int

variable_types:
immortaltext
char *


getudir

decompiled_code:
struct passwd *getudir()
{
__uid_t v0; // ebp
struct passwd *v1; // rbx

v0 = getuid();
v1 = getpwent();
if ( v1 )
{
while ( v1->pw_uid != v0 )
{
v1 = getpwent();
if ( !v1 )
return v1;
}
endpwent();
v1 = (struct passwd *)v1->pw_dir;
}
else
{
endpwent();
}
return v1;
}

canonical_decompiled_code:
struct passwd *func0()
{
__uid_t v0; // ebp
struct passwd *v1; // rbx

v0 = getuid();
v1 = getpwent();
if ( v1 )
{
while ( v1->pw_uid != v0 )
{
v1 = getpwent();
if ( !v1 )
return v1;
}
endpwent();
v1 = (struct passwd *)v1->pw_dir;
}
else
{
endpwent();
}
return v1;
}

original_code:
static char *getudir() {
    struct passwd *upwent;
    uid_t uid;
    uid = getuid();
    if ( (upwent = getpwent()) ) {
        while (upwent->pw_uid != uid) {
            if ( !(upwent = getpwent()) ) {
                return ((void *)0);
            }
        }
        endpwent();
        return upwent->pw_dir;
    }
    endpwent();
    return ((void *)0);
}

canonical_original_code:
static char *getudir() {
    struct passwd *upwent;
    unsigned int uid;
    uid = getuid();
    if ( (upwent = getpwent()) ) {
        while (upwent->pw_uid != uid) {
            if ( !(upwent = getpwent()) ) {
                return ((void *)0);
            }
        }
        endpwent();
        return upwent->pw_dir;
    }
    endpwent();
    return ((void *)0);
}

variable_types: struct passwd { char *pw_name; char *pw_passwd; unsigned int pw_uid; unsigned int pw_gid; char *pw_gecos; char *pw_dir; char *pw_shell; } *

variable_types:
uid
unsigned int


expandpath

decompiled_code:
char *__fastcall expandpath(char *src, int a2)
{
char v2; // r12
char v3; // r14
char *v4; // rbp
const char *v5; // r13
size_t v6; // r12
int v7; // eax
char *v8; // rax
int v10; // er13
int v11; // eax
char *v12; // rax
char *v13; // r13
size_t v14; // rax
char v15[4136]; // [rsp+0h] [rbp-1028h] BYREF

v2 = *src;
v3 = src[1];
if ( src[strlen(src) - 1] == 47 )
{
v4 = 0LL;
if ( a2 )
return v4;
}
if ( v2 == 126 || v2 == 47 )
{
if ( (v2 == 46 || v2 == 126) && v3 == 47 )
{
if ( v2 == 126 )
{
v5 = (const char *)getudir();
LABEL_8:
if ( !v5 )
return 0LL;
v6 = strlen(v5);
v4 = 0LL;
if ( v6 <= 0x1000 )
{
v7 = strlen(src);
v8 = (char *)malloc((int)v6 + v7);
v4 = v8;
if ( v8 )
sprintf(v8, "%s%s", v5, src + 1);
}
return v4;
}
goto LABEL_7;
}
v4 = 0LL;
if ( v2 == 47 )
{
v14 = strlen(src);
v4 = (char *)malloc(v14 + 1);
if ( v4 )
{
if ( strlen(src) <= 0x1000 )
strcpy(v4, src);
else
v4 = 0LL;
}
}
}
else
{
if ( v2 == 46 && v3 == 47 )
goto LABEL_7;
v4 = strchr(src, 47);
if ( v4 )
{
if ( v2 != 46 || v3 != 47 )
return 0LL;
goto LABEL_7;
}
if ( getcwd(v15, 0x1000uLL) )
{
v10 = strlen(v15);
v11 = strlen(src);
v12 = (char *)malloc(v10 + v11 + 2);
v13 = v12;
if ( v12 )
{
sprintf(v12, "%s/%s", v15, src);
return v13;
}
}
if ( v2 == 46 && v3 == 47 )
{
LABEL_7:
v5 = getcwd(v15, 0x1000uLL);
goto LABEL_8;
}
}
return v4;
}

canonical_decompiled_code:
char *__fastcall func1(char *src, int a2)
{
char v2; // r12
char v3; // r14
char *v4; // rbp
const char *v5; // r13
size_t v6; // r12
int v7; // eax
char *v8; // rax
int v10; // er13
int v11; // eax
char *v12; // rax
char *v13; // r13
size_t v14; // rax
char v15[4136]; // [rsp+0h] [rbp-1028h] BYREF

v2 = *src;
v3 = src[1];
if ( src[strlen(src) - 1] == 47 )
{
v4 = 0LL;
if ( a2 )
return v4;
}
if ( v2 == 126 || v2 == 47 )
{
if ( (v2 == 46 || v2 == 126) && v3 == 47 )
{
if ( v2 == 126 )
{
v5 = (const char *)func0();
LABEL_8:
if ( !v5 )
return 0LL;
v6 = strlen(v5);
v4 = 0LL;
if ( v6 <= 0x1000 )
{
v7 = strlen(src);
v8 = (char *)malloc((int)v6 + v7);
v4 = v8;
if ( v8 )
sprintf(v8, "%s%s", v5, src + 1);
}
return v4;
}
goto LABEL_7;
}
v4 = 0LL;
if ( v2 == 47 )
{
v14 = strlen(src);
v4 = (char *)malloc(v14 + 1);
if ( v4 )
{
if ( strlen(src) <= 0x1000 )
strcpy(v4, src);
else
v4 = 0LL;
}
}
}
else
{
if ( v2 == 46 && v3 == 47 )
goto LABEL_7;
v4 = strchr(src, 47);
if ( v4 )
{
if ( v2 != 46 || v3 != 47 )
return 0LL;
goto LABEL_7;
}
if ( getcwd(v15, 0x1000uLL) )
{
v10 = strlen(v15);
v11 = strlen(src);
v12 = (char *)malloc(v10 + v11 + 2);
v13 = v12;
if ( v12 )
{
sprintf(v12, "%s/%s", v15, src);
return v13;
}
}
if ( v2 == 46 && v3 == 47 )
{
LABEL_7:
v5 = getcwd(v15, 0x1000uLL);
goto LABEL_8;
}
}
return v4;
}

original_code:
char *expandpath(char *path, int isfile) {
    char firstchar, secondchar, lastchar;
    char cwd[4096];
    char *dir = ((void *)0);
    char *heap = ((void *)0);
    int len = 0;
    firstchar = *path;
    secondchar = *(path + 1);
    lastchar = *(path + strlen(path) - 1);
    if (lastchar == '/' && isfile)
        return ((void *)0);
    if (firstchar != '~' && firstchar != '/') {
        if ( !(firstchar == '.' && secondchar == '/') ) {
            if (!strchr(path, '/')) {
                if (getcwd(cwd, 4096)) {
                    len = strlen(cwd) + strlen(path) + 2;
                    if ( (heap = malloc(len * sizeof(char))) ) {
                        sprintf(heap, "%s/%s", cwd, path);
                        return heap;
                    }
                }
            }
        }
    }
    if ( (firstchar == '~' || firstchar == '.') && secondchar == '/') {
        if (firstchar == '~') {
            dir = getudir();
        } else {
            dir = getcwd(cwd, 4096);
        }
        if (dir) {
            if (strlen(dir) > 4096)
                return ((void *)0);
            len = strlen(dir) + strlen(path);
            if ( (heap = malloc(len * sizeof(char))) ) {
                sprintf(heap, "%s%s", dir, path + 1);
                return heap;
            }
        }
    } else if (firstchar == '/') {
        heap = malloc((strlen(path) + 1) * sizeof(char));
        if (heap)
            if (strlen(path) <= 4096)
                return strcpy(heap, path);
    }
    return ((void *)0);
}

canonical_original_code:
char *expandpath(char *path, int isfile) {
    char firstchar; char secondchar; char lastchar;
    char cwd[4096];
    char *dir = ((void *)0);
    char *heap = ((void *)0);
    int len = 0;
    firstchar = *path;
    secondchar = *(path + 1);
    lastchar = *(path + strlen(path) - 1);
    if (lastchar == '/' && isfile)
        return ((void *)0);
    if (firstchar != '~' && firstchar != '/') {
        if ( !(firstchar == '.' && secondchar == '/') ) {
            if (!strchr(path, '/')) {
                if (getcwd(cwd, 4096)) {
                    len = strlen(cwd) + strlen(path) + 2;
                    if ( (heap = malloc(len * sizeof(char))) ) {
                        sprintf(heap, "%s/%s", cwd, path);
                        return heap;
                    }
                }
            }
        }
    }
    if ( (firstchar == '~' || firstchar == '.') && secondchar == '/') {
        if (firstchar == '~') {
            dir = getudir();
        } else {
            dir = getcwd(cwd, 4096);
        }
        if (dir) {
            if (strlen(dir) > 4096)
                return ((void *)0);
            len = strlen(dir) + strlen(path);
            if ( (heap = malloc(len * sizeof(char))) ) {
                sprintf(heap, "%s%s", dir, path + 1);
                return heap;
            }
        }
    } else if (firstchar == '/') {
        heap = malloc((strlen(path) + 1) * sizeof(char));
        if (heap)
            if (strlen(path) <= 4096)
                return strcpy(heap, path);
    }
    return ((void *)0);
}

variable_types:
path
char *

variable_types: isfile int

variable_types: firstchar char

variable_types: secondchar char

variable_types: lastchar char

variable_types:
cwd
char [4096]

variable_types:
dir
char *

variable_types:
heap
char *

variable_types: len int