decompiled_code:
__int64 __fastcall draw_baddie(double *a1, __int64 a2, double a3, double a4, double a5, double a6)
{
unsigned int v6; // er14
__int64 result; // rax
double v8; // xmm2_8
unsigned int v9; // ebx
float v10; // xmm4_4
int v11; // ebx
double v12; // xmm0_8
double v13; // xmm2_8
double v14; // xmm2_8
double v15; // xmm1_8
double v16; // xmm0_8
double v17; // xmm0_8
double v18; // xmm1_8
double v19; // xmm0_8
double v20; // xmm0_8
double v21; // xmm3_8
double v22; // xmm1_8
double v23; // xmm6_8
double v24; // xmm0_8
double v25; // xmm2_8
double v26; // xmm3_8
__int64 v27; // xmm2_8
double v28; // xmm3_8
double v29; // xmm1_8
int v30; // ebx
double v31; // xmm0_8
double v32; // xmm2_8
double v33; // xmm1_8
double v34; // xmm0_8
double v35; // xmm1_8
__m128i v36; // xmm4
__m128i v37; // xmm4
float v38; // [rsp+8h] [rbp-40h]
unsigned int v39; // [rsp+8h] [rbp-40h]
double v40; // [rsp+18h] [rbp-30h]
double cosx; // [rsp+20h] [rbp-28h] BYREF
double sinx[4]; // [rsp+28h] [rbp-20h] BYREF

result = *(unsigned int *)a1;
if ( !(_DWORD)result )
_assert_fail("baddie->kind != AZ_BAD_NOTHING", "src/milestone/view/baddie.c", 0x24u, "draw_baddie");
v8 = a1[6];
v9 = (unsigned int)a1;
if ( v8 > 0.0 )
{
result = az_clock_mod(2LL, 2LL, a2);
if ( (_DWORD)result )
return result;
result = *(unsigned int *)a1;
}
v10 = a1[7];
v38 = v10;
switch ( (int)result )
{
case 0:
az_fatal("draw_baddie", "line %d: unreachable\n", 40LL);
LABEL_23:
*(_QWORD *)&v8 = (unsigned int)LC18;
glColor4f(0.0, 0.0, 1.0, *(float *)&a6);
goto LABEL_24;
case 1:
v20 = az_vtheta(a1[3], a1[4]);
glRotated(v20 * 57.29577951308232, 0.0, 0.0, 1.0);
glBegin(6LL);
*(_QWORD *)&v21 = (unsigned int)LC7;
*(_QWORD *)&v22 = (unsigned int)LC18;
*(float *)&v21 = (float)(0.5 * v38) + 0.5;
*(float *)&v22 = 1.0 - (float)(0.5 * v38);
glColor3f(*(float *)&v21, v22);
glVertex2f(0.0, 0.0, COERCE_DOUBLE((unsigned __int64)LC6), v21);
*(_QWORD *)&v23 = (unsigned int)LC7;
*(_QWORD *)&v14 = (unsigned int)LC23;
*(float *)&v23 = 0.5 - (float)(v38 * 0.25);
glColor3f((float)(v38 * 0.25) + 0.25, v23);
glVertex2f(15.0, 0.0, COERCE_DOUBLE((unsigned __int64)LC23), v21);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LC23), v21);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LC23), v21);
*(_QWORD *)&v17 = (unsigned int)LC24;
v18 = 0.0;
glVertex2f(15.0, 0.0, COERCE_DOUBLE((unsigned __int64)LC23), v21);
goto LABEL_10;
case 2:
v24 = az_vtheta(a1[3], a1[4]);
glRotated(v24 * 57.29577951308232, 0.0, 0.0, 1.0);
glBegin(6LL);
*(_QWORD *)&v25 = (unsigned int)LC7;
*(float *)&v25 = 0.5 - (float)(v38 * 0.40000001);
glColor3f(1.0, 0.0);
glVertex2f(0.0, 0.0, v25, 1.0);
*(_QWORD *)&v14 = (unsigned int)LC6;
*(float *)&v14 = 0.25 - (float)(v38 * 0.1);
glColor3f(0.5, COERCE_DOUBLE((unsigned __int64)LC11));
glVertex2f(12.0, COERCE_DOUBLE((unsigned __int64)LC26), v14, 1.0);
glVertex2f(10.0, COERCE_DOUBLE((unsigned __int64)LC27), v14, 1.0);
glVertex2f(-10.0, COERCE_DOUBLE((unsigned __int64)LC27), v14, 1.0);
glVertex2f(-12.0, COERCE_DOUBLE((unsigned __int64)LC26), v14, 1.0);
glVertex2f(-12.0, COERCE_DOUBLE((unsigned __int64)LC28), v14, 1.0);
glVertex2f(-10.0, COERCE_DOUBLE((unsigned __int64)LC29), v14, 1.0);
glVertex2f(10.0, COERCE_DOUBLE((unsigned __int64)LC29), v14, 1.0);
glVertex2f(12.0, COERCE_DOUBLE((unsigned __int64)LC28), v14, 1.0);
*(_QWORD *)&v18 = (unsigned int)LC26;
*(_QWORD *)&v17 = (unsigned int)LC27;
glVertex2f(12.0, COERCE_DOUBLE((unsigned __int64)LC26), v14, 1.0);
goto LABEL_10;
case 3:
if ( a1[5] <= 0.0 && a1[6] <= 0.0 )
{
v35 = a1[2];
v36 = 0LL;
*(float *)v36.m128i_i32 = 21.0 - v35;
v6 = _mm_cvtsi128_si32(v36);
v37 = 0LL;
*(float *)v37.m128i_i32 = 479.0 - v35;
v9 = _mm_cvtsi128_si32(v37);
*(_QWORD *)&a6 = (unsigned int)LC6;
switch ( (unsigned int)az_clock_mod(6LL, 1LL, a2) )
{
case 0u:
v8 = 0.0;
glColor4f(1.0, 0.0, 0.0, 0.25);
break;
case 1u:
v8 = 0.0;
glColor4f(1.0, COERCE_DOUBLE((unsigned __int64)LC18), 0.0, 0.25);
break;
case 2u:
v8 = 0.0;
glColor4f(0.0, COERCE_DOUBLE((unsigned __int64)LC18), 0.0, 0.25);
break;
case 3u:
*(_QWORD *)&v8 = (unsigned int)LC18;
glColor4f(0.0, COERCE_DOUBLE((unsigned __int64)LC18), 1.0, 0.25);
break;
case 4u:
goto LABEL_23;
case 5u:
*(_QWORD *)&v8 = (unsigned int)LC18;
glColor4f(1.0, 0.0, 1.0, 0.25);
break;
default:
break;
}
LABEL_24:
glBegin(5LL);
glVertex2f(-7.0, *(double *)_mm_cvtsi32_si128(v6).m128i_i64, v8, a6);
glVertex2f(7.0, *(double *)_mm_cvtsi32_si128(v6).m128i_i64, v8, a6);
glVertex2f(-7.0, COERCE_DOUBLE((unsigned __int64)LC28), v8, a6);
glVertex2f(7.0, COERCE_DOUBLE((unsigned __int64)LC28), v8, a6);
((void (*)(void))glEnd)();
glBegin(5LL);
glVertex2f(-7.0, COERCE_DOUBLE((unsigned __int64)LC26), v8, a6);
glVertex2f(7.0, COERCE_DOUBLE((unsigned __int64)LC26), v8, a6);
glVertex2f(-7.0, *(double *)_mm_cvtsi32_si128(v9).m128i_i64, v8, a6);
glVertex2f(7.0, *(double *)_mm_cvtsi32_si128(v9).m128i_i64, v8, a6);
((void (*)(void))glEnd)();
}
glBegin(6LL);
*(_QWORD *)&v26 = LODWORD(v38);
*(float *)&v26 = v38 * 0.5;
v27 = (unsigned int)LC7;
*(float *)&v14 = 0.5 - (float)(v38 * 0.5);
glColor3f((float)(v38 * 0.5) + 0.5, v14);
glVertex2f(0.0, 0.0, v14, v26);
*(_QWORD *)&v28 = COERCE_UNSIGNED_INT(v38 * 0.5);
*(_QWORD *)&v14 = LODWORD(v14);
glColor3f(v38 * 0.5, 0.0);
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-5.0, COERCE_DOUBLE((unsigned __int64)LC34), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-8.0, COERCE_DOUBLE((unsigned __int64)LC34), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-8.0, COERCE_DOUBLE((unsigned __int64)LC9), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-5.0, COERCE_DOUBLE((unsigned __int64)LC9), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(5.0, COERCE_DOUBLE((unsigned __int64)LC9), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(8.0, COERCE_DOUBLE((unsigned __int64)LC9), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(8.0, COERCE_DOUBLE((unsigned __int64)LC34), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(5.0, COERCE_DOUBLE((unsigned __int64)LC34), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
*(_QWORD *)&v18 = (unsigned int)LC14;
*(_QWORD *)&v17 = (unsigned int)LC14;
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
goto LABEL_10;
case 4:
glBegin(6LL);
v29 = a1[4];
v30 = 0;
v31 = az_vmul(a1[3], v29, 0.07000000000000001);
v40 = az_vcaplen(v31, v29, 14.0);
*(_QWORD *)&v32 = (unsigned int)LC18;
*(float *)&v39 = 1.0 - v38;
*(float *)&v32 = *(float *)&v39;
glColor4f(1.0, v32, *(float *)&v32, 0.25);
glVertex2d(v40, v29);
*(_QWORD *)&v14 = v39;
glColor4f(1.0, COERCE_DOUBLE((unsigned __int64)v39), *(float *)&v39, 0.0);
v33 = 0.0;
v34 = *(double *)&LC0;
while ( 1 )
{
v30 += 30;
v17 = v34 * 15.0;
v18 = v33 * 15.0;
glVertex2d(v17, v18);
if ( v30 == 390 )
break;
sincos((double)v30 * 0.0174532925199433, sinx, &cosx);
v34 = cosx;
v33 = sinx[0];
}
goto LABEL_10;
case 5:
v11 = 0;
az_vsub(a3, a4, a1[1], a1[2]);
v12 = az_vtheta(a3, a4);
glRotated(v12 * 57.29577951308232, 0.0, 0.0, 1.0);
glBegin(6LL);
*(_QWORD *)&v13 = (unsigned int)LC18;
*(float *)&v13 = 1.0 - v38;
glColor3f((float)(0.75 * v38) + 0.25, COERCE_DOUBLE((unsigned __int64)LC7));
glVertex2f(0.0, 0.0, v13, COERCE_DOUBLE((unsigned __int64)LODWORD(v38)));
*(_QWORD *)&v14 = (unsigned int)LC19;
*(float *)&v14 = 0.2 - (float)(v38 * 0.2);
glColor3f((float)(v38 * 0.5) + 0.15000001, COERCE_DOUBLE((unsigned __int64)LC6));
v15 = 0.0;
v16 = *(double *)&LC0;
while ( 1 )
{
v11 += 60;
v17 = v16 * 15.0;
v18 = v15 * 15.0;
glVertex2d(v17, v18);
if ( v11 == 420 )
break;
sincos((double)v11 * 0.0174532925199433, sinx, &cosx);
v16 = cosx;
v15 = sinx[0];
}
goto LABEL_10;
case 6:
v19 = az_vtheta(a1[3], a1[4]);
glRotated(v19 * 57.29577951308232, 0.0, 0.0, 1.0);
glBegin(6LL);
glColor3f(v38, COERCE_DOUBLE((unsigned __int64)LC7));
glVertex2f(-4.0, 0.0, COERCE_DOUBLE((unsigned __int64)LC6), 1.0);
*(_QWORD *)&v14 = (unsigned int)LC11;
glColor3f(v38 * 0.75, COERCE_DOUBLE((unsigned __int64)LC6));
glVertex2f(14.0, COERCE_DOUBLE((unsigned __int64)LC12), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(-14.0, COERCE_DOUBLE((unsigned __int64)LC12), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(-14.0, COERCE_DOUBLE((unsigned __int64)LC17), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(14.0, COERCE_DOUBLE((unsigned __int64)LC17), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
*(_QWORD *)&v18 = (unsigned int)LC12;
*(_QWORD *)&v17 = (unsigned int)LC13;
glVertex2f(14.0, COERCE_DOUBLE((unsigned __int64)LC12), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
LABEL_10:
result = glEnd(v17, v18, v14);
break;
default:
return result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(double *a1, __int64 a2, double a3, double a4, double a5, double a6)
{
unsigned int v6; // er14
__int64 result; // rax
double v8; // xmm2_8
unsigned int v9; // ebx
float v10; // xmm4_4
int v11; // ebx
double v12; // xmm0_8
double v13; // xmm2_8
double v14; // xmm2_8
double v15; // xmm1_8
double v16; // xmm0_8
double v17; // xmm0_8
double v18; // xmm1_8
double v19; // xmm0_8
double v20; // xmm0_8
double v21; // xmm3_8
double v22; // xmm1_8
double v23; // xmm6_8
double v24; // xmm0_8
double v25; // xmm2_8
double v26; // xmm3_8
__int64 v27; // xmm2_8
double v28; // xmm3_8
double v29; // xmm1_8
int v30; // ebx
double v31; // xmm0_8
double v32; // xmm2_8
double v33; // xmm1_8
double v34; // xmm0_8
double v35; // xmm1_8
__m128i v36; // xmm4
__m128i v37; // xmm4
float v38; // [rsp+8h] [rbp-40h]
unsigned int v39; // [rsp+8h] [rbp-40h]
double v40; // [rsp+18h] [rbp-30h]
double cosx; // [rsp+20h] [rbp-28h] BYREF
double sinx[4]; // [rsp+28h] [rbp-20h] BYREF

result = *(unsigned int *)a1;
if ( !(_DWORD)result )
_assert_fail("baddie->kind != AZ_BAD_NOTHING", "src/milestone/view/baddie.c", 0x24u, "draw_baddie");
v8 = a1[6];
v9 = (unsigned int)a1;
if ( v8 > 0.0 )
{
result = az_clock_mod(2LL, 2LL, a2);
if ( (_DWORD)result )
return result;
result = *(unsigned int *)a1;
}
v10 = a1[7];
v38 = v10;
switch ( (int)result )
{
case 0:
az_fatal("draw_baddie", "line %d: unreachable\n", 40LL);
LABEL_23:
*(_QWORD *)&v8 = (unsigned int)LC18;
glColor4f(0.0, 0.0, 1.0, *(float *)&a6);
goto LABEL_24;
case 1:
v20 = az_vtheta(a1[3], a1[4]);
glRotated(v20 * 57.29577951308232, 0.0, 0.0, 1.0);
glBegin(6LL);
*(_QWORD *)&v21 = (unsigned int)LC7;
*(_QWORD *)&v22 = (unsigned int)LC18;
*(float *)&v21 = (float)(0.5 * v38) + 0.5;
*(float *)&v22 = 1.0 - (float)(0.5 * v38);
glColor3f(*(float *)&v21, v22);
glVertex2f(0.0, 0.0, COERCE_DOUBLE((unsigned __int64)LC6), v21);
*(_QWORD *)&v23 = (unsigned int)LC7;
*(_QWORD *)&v14 = (unsigned int)LC23;
*(float *)&v23 = 0.5 - (float)(v38 * 0.25);
glColor3f((float)(v38 * 0.25) + 0.25, v23);
glVertex2f(15.0, 0.0, COERCE_DOUBLE((unsigned __int64)LC23), v21);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LC23), v21);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LC23), v21);
*(_QWORD *)&v17 = (unsigned int)LC24;
v18 = 0.0;
glVertex2f(15.0, 0.0, COERCE_DOUBLE((unsigned __int64)LC23), v21);
goto LABEL_10;
case 2:
v24 = az_vtheta(a1[3], a1[4]);
glRotated(v24 * 57.29577951308232, 0.0, 0.0, 1.0);
glBegin(6LL);
*(_QWORD *)&v25 = (unsigned int)LC7;
*(float *)&v25 = 0.5 - (float)(v38 * 0.40000001);
glColor3f(1.0, 0.0);
glVertex2f(0.0, 0.0, v25, 1.0);
*(_QWORD *)&v14 = (unsigned int)LC6;
*(float *)&v14 = 0.25 - (float)(v38 * 0.1);
glColor3f(0.5, COERCE_DOUBLE((unsigned __int64)LC11));
glVertex2f(12.0, COERCE_DOUBLE((unsigned __int64)LC26), v14, 1.0);
glVertex2f(10.0, COERCE_DOUBLE((unsigned __int64)LC27), v14, 1.0);
glVertex2f(-10.0, COERCE_DOUBLE((unsigned __int64)LC27), v14, 1.0);
glVertex2f(-12.0, COERCE_DOUBLE((unsigned __int64)LC26), v14, 1.0);
glVertex2f(-12.0, COERCE_DOUBLE((unsigned __int64)LC28), v14, 1.0);
glVertex2f(-10.0, COERCE_DOUBLE((unsigned __int64)LC29), v14, 1.0);
glVertex2f(10.0, COERCE_DOUBLE((unsigned __int64)LC29), v14, 1.0);
glVertex2f(12.0, COERCE_DOUBLE((unsigned __int64)LC28), v14, 1.0);
*(_QWORD *)&v18 = (unsigned int)LC26;
*(_QWORD *)&v17 = (unsigned int)LC27;
glVertex2f(12.0, COERCE_DOUBLE((unsigned __int64)LC26), v14, 1.0);
goto LABEL_10;
case 3:
if ( a1[5] <= 0.0 && a1[6] <= 0.0 )
{
v35 = a1[2];
v36 = 0LL;
*(float *)v36.m128i_i32 = 21.0 - v35;
v6 = _mm_cvtsi128_si32(v36);
v37 = 0LL;
*(float *)v37.m128i_i32 = 479.0 - v35;
v9 = _mm_cvtsi128_si32(v37);
*(_QWORD *)&a6 = (unsigned int)LC6;
switch ( (unsigned int)az_clock_mod(6LL, 1LL, a2) )
{
case 0u:
v8 = 0.0;
glColor4f(1.0, 0.0, 0.0, 0.25);
break;
case 1u:
v8 = 0.0;
glColor4f(1.0, COERCE_DOUBLE((unsigned __int64)LC18), 0.0, 0.25);
break;
case 2u:
v8 = 0.0;
glColor4f(0.0, COERCE_DOUBLE((unsigned __int64)LC18), 0.0, 0.25);
break;
case 3u:
*(_QWORD *)&v8 = (unsigned int)LC18;
glColor4f(0.0, COERCE_DOUBLE((unsigned __int64)LC18), 1.0, 0.25);
break;
case 4u:
goto LABEL_23;
case 5u:
*(_QWORD *)&v8 = (unsigned int)LC18;
glColor4f(1.0, 0.0, 1.0, 0.25);
break;
default:
break;
}
LABEL_24:
glBegin(5LL);
glVertex2f(-7.0, *(double *)_mm_cvtsi32_si128(v6).m128i_i64, v8, a6);
glVertex2f(7.0, *(double *)_mm_cvtsi32_si128(v6).m128i_i64, v8, a6);
glVertex2f(-7.0, COERCE_DOUBLE((unsigned __int64)LC28), v8, a6);
glVertex2f(7.0, COERCE_DOUBLE((unsigned __int64)LC28), v8, a6);
((void (*)(void))glEnd)();
glBegin(5LL);
glVertex2f(-7.0, COERCE_DOUBLE((unsigned __int64)LC26), v8, a6);
glVertex2f(7.0, COERCE_DOUBLE((unsigned __int64)LC26), v8, a6);
glVertex2f(-7.0, *(double *)_mm_cvtsi32_si128(v9).m128i_i64, v8, a6);
glVertex2f(7.0, *(double *)_mm_cvtsi32_si128(v9).m128i_i64, v8, a6);
((void (*)(void))glEnd)();
}
glBegin(6LL);
*(_QWORD *)&v26 = LODWORD(v38);
*(float *)&v26 = v38 * 0.5;
v27 = (unsigned int)LC7;
*(float *)&v14 = 0.5 - (float)(v38 * 0.5);
glColor3f((float)(v38 * 0.5) + 0.5, v14);
glVertex2f(0.0, 0.0, v14, v26);
*(_QWORD *)&v28 = COERCE_UNSIGNED_INT(v38 * 0.5);
*(_QWORD *)&v14 = LODWORD(v14);
glColor3f(v38 * 0.5, 0.0);
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-5.0, COERCE_DOUBLE((unsigned __int64)LC34), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-8.0, COERCE_DOUBLE((unsigned __int64)LC34), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-8.0, COERCE_DOUBLE((unsigned __int64)LC9), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-5.0, COERCE_DOUBLE((unsigned __int64)LC9), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(5.0, COERCE_DOUBLE((unsigned __int64)LC9), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(8.0, COERCE_DOUBLE((unsigned __int64)LC9), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(8.0, COERCE_DOUBLE((unsigned __int64)LC34), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
glVertex2f(5.0, COERCE_DOUBLE((unsigned __int64)LC34), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
*(_QWORD *)&v18 = (unsigned int)LC14;
*(_QWORD *)&v17 = (unsigned int)LC14;
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LODWORD(v14)), v28);
goto LABEL_10;
case 4:
glBegin(6LL);
v29 = a1[4];
v30 = 0;
v31 = az_vmul(a1[3], v29, 0.07000000000000001);
v40 = az_vcaplen(v31, v29, 14.0);
*(_QWORD *)&v32 = (unsigned int)LC18;
*(float *)&v39 = 1.0 - v38;
*(float *)&v32 = *(float *)&v39;
glColor4f(1.0, v32, *(float *)&v32, 0.25);
glVertex2d(v40, v29);
*(_QWORD *)&v14 = v39;
glColor4f(1.0, COERCE_DOUBLE((unsigned __int64)v39), *(float *)&v39, 0.0);
v33 = 0.0;
v34 = *(double *)&LC0;
while ( 1 )
{
v30 += 30;
v17 = v34 * 15.0;
v18 = v33 * 15.0;
glVertex2d(v17, v18);
if ( v30 == 390 )
break;
sincos((double)v30 * 0.0174532925199433, sinx, &cosx);
v34 = cosx;
v33 = sinx[0];
}
goto LABEL_10;
case 5:
v11 = 0;
az_vsub(a3, a4, a1[1], a1[2]);
v12 = az_vtheta(a3, a4);
glRotated(v12 * 57.29577951308232, 0.0, 0.0, 1.0);
glBegin(6LL);
*(_QWORD *)&v13 = (unsigned int)LC18;
*(float *)&v13 = 1.0 - v38;
glColor3f((float)(0.75 * v38) + 0.25, COERCE_DOUBLE((unsigned __int64)LC7));
glVertex2f(0.0, 0.0, v13, COERCE_DOUBLE((unsigned __int64)LODWORD(v38)));
*(_QWORD *)&v14 = (unsigned int)LC19;
*(float *)&v14 = 0.2 - (float)(v38 * 0.2);
glColor3f((float)(v38 * 0.5) + 0.15000001, COERCE_DOUBLE((unsigned __int64)LC6));
v15 = 0.0;
v16 = *(double *)&LC0;
while ( 1 )
{
v11 += 60;
v17 = v16 * 15.0;
v18 = v15 * 15.0;
glVertex2d(v17, v18);
if ( v11 == 420 )
break;
sincos((double)v11 * 0.0174532925199433, sinx, &cosx);
v16 = cosx;
v15 = sinx[0];
}
goto LABEL_10;
case 6:
v19 = az_vtheta(a1[3], a1[4]);
glRotated(v19 * 57.29577951308232, 0.0, 0.0, 1.0);
glBegin(6LL);
glColor3f(v38, COERCE_DOUBLE((unsigned __int64)LC7));
glVertex2f(-4.0, 0.0, COERCE_DOUBLE((unsigned __int64)LC6), 1.0);
*(_QWORD *)&v14 = (unsigned int)LC11;
glColor3f(v38 * 0.75, COERCE_DOUBLE((unsigned __int64)LC6));
glVertex2f(14.0, COERCE_DOUBLE((unsigned __int64)LC12), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC14), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(-14.0, COERCE_DOUBLE((unsigned __int64)LC12), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(-14.0, COERCE_DOUBLE((unsigned __int64)LC17), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(-11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(11.0, COERCE_DOUBLE((unsigned __int64)LC15), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
glVertex2f(14.0, COERCE_DOUBLE((unsigned __int64)LC17), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
*(_QWORD *)&v18 = (unsigned int)LC12;
*(_QWORD *)&v17 = (unsigned int)LC13;
glVertex2f(14.0, COERCE_DOUBLE((unsigned __int64)LC12), COERCE_DOUBLE((unsigned __int64)LC11), 1.0);
LABEL_10:
result = glEnd(v17, v18, v14);
break;
default:
return result;
}
return result;
}

original_code:
static void draw_baddie(const az_baddie_t *baddie, az_vector_t avatar_position,
                        az_clock_t clock) {
  ((baddie->kind != AZ_BAD_NOTHING) ? (void) (0) : __assert_fail ("baddie->kind != AZ_BAD_NOTHING", "src/milestone/view/baddie.c", 36, __extension__ __PRETTY_FUNCTION__));
  if (baddie->stun > 0.0 && az_clock_mod(2, 2, clock)) return;
  const GLfloat flare = baddie->flare;
  switch (baddie->kind) {
    case AZ_BAD_NOTHING: _az_fatal(__func__, "line %d: unreachable\n", 40);
    case AZ_BAD_TANK:
      glRotated(((double)(az_vtheta(baddie->velocity)) * 57.295779513082323), 0, 0, 1);
      glBegin(0x0006); {
        glColor3f(flare, 0.5, 0.25); glVertex2f(-4, 0);
        glColor3f(0.75f * flare, 0.25, 0.1);
        glVertex2f(14, 8); glVertex2f(11, 11); glVertex2f(-11, 11);
        glVertex2f(-14, 8); glVertex2f(-14, -8); glVertex2f(-11, -11);
        glVertex2f(11, -11); glVertex2f(14, -8); glVertex2f(14, 8);
      } glEnd();
      break;
    case AZ_BAD_GUARD:
      glRotated(((double)(az_vtheta(az_vsub(avatar_position, baddie->position))) * 57.295779513082323), 0, 0, 1);
      glBegin(0x0006); {
        glColor3f(0.25f + 0.75f * flare, 0.5f, 1.0f - flare);
        glVertex2f(0, 0);
        glColor3f(0.15f + 0.5f * flare, 0.25f, 0.2f - 0.2f * flare);
        for (int i = 0; i <= 360; i += 60) {
          glVertex2d(15 * cos(((double)(i) * 0.017453292519943295)),
                     15 * sin(((double)(i) * 0.017453292519943295)));
        }
      } glEnd();
      break;
    case AZ_BAD_BASILISK:
      glRotated(((double)(az_vtheta(baddie->velocity)) * 57.295779513082323), 0, 0, 1);
      glBegin(0x0006); {
        glColor3f(0.5f + 0.5f * flare, 1.0f - 0.5f * flare, 0.25f);
        glVertex2f(0, 0);
        glColor3f(0.25f + 0.25f * flare, 0.5f - 0.25f * flare, 0.12f);
        glVertex2f(15, 0); glVertex2f(-11, 11);
        glVertex2f(-11, -11); glVertex2f(15, 0);
      } glEnd();
      break;
    case AZ_BAD_FAKER:
      glRotated(((double)(az_vtheta(baddie->velocity)) * 57.295779513082323), 0, 0, 1);
      glBegin(0x0006); {
        glColor3f(1, 0, 0.5f - 0.4f * flare); glVertex2f(0, 0);
        glColor3f(0.5f, 0.1f, 0.25f - 0.1f * flare);
        glVertex2f(12, 10); glVertex2f(10, 12); glVertex2f(-10, 12);
        glVertex2f(-12, 10); glVertex2f(-12, -10); glVertex2f(-10, -12);
        glVertex2f(10, -12); glVertex2f(12, -10); glVertex2f(12, 10);
      } glEnd();
      break;
    case AZ_BAD_FORCER:
      if (baddie->cooldown <= 0.0 && baddie->stun <= 0.0) {
        const GLfloat top = 21 - baddie->position.y;
        const GLfloat bottom = (500 - 21) - baddie->position.y;
        switch (az_clock_mod(6, 1, clock)) {
          case 0: glColor4f(1, 0, 0, 0.25); break;
          case 1: glColor4f(1, 1, 0, 0.25); break;
          case 2: glColor4f(0, 1, 0, 0.25); break;
          case 3: glColor4f(0, 1, 1, 0.25); break;
          case 4: glColor4f(0, 0, 1, 0.25); break;
          case 5: glColor4f(1, 0, 1, 0.25); break;
        }
        glBegin(0x0005); {
          glVertex2f(-7, top); glVertex2f(7, top);
          glVertex2f(-7, -10); glVertex2f(7, -10);
        } glEnd();
        glBegin(0x0005); {
          glVertex2f(-7, 10); glVertex2f(7, 10);
          glVertex2f(-7, bottom); glVertex2f(7, bottom);
        } glEnd();
      }
      glBegin(0x0006); {
        glColor3f(0.5f + 0.5f * flare, 0.5f - 0.5f * flare,
                  0.5f - 0.5f * flare);
        glVertex2f(0, 0);
        glColor3f(0.5f * flare, 0.0f, 0.5f - 0.5f * flare);
        glVertex2f(11, 11); glVertex2f(-11, 11);
        glVertex2f(-5, 4); glVertex2f(-8, 4);
        glVertex2f(-8, -4); glVertex2f(-5, -4);
        glVertex2f(-11, -11); glVertex2f(11, -11);
        glVertex2f(5, -4); glVertex2f(8, -4);
        glVertex2f(8, 4); glVertex2f(5, 4); glVertex2f(11, 11);
      } glEnd();
      break;
    case AZ_BAD_GHOST:
      glBegin(0x0006); {
        const az_vector_t center =
          az_vcaplen(az_vmul(baddie->velocity, 0.07), 15 - 1);
        glColor4f(1, 1 - flare, 1 - flare, 0.25);
        glVertex2d(center.x, center.y);
        glColor4f(1, 1 - flare, 1 - flare, 0);
        for (int i = 0; i <= 360; i += 30) {
          glVertex2d(15 * cos(((double)(i) * 0.017453292519943295)),
                     15 * sin(((double)(i) * 0.017453292519943295)));
        }
      } glEnd();
      break;
  }
}

canonical_original_code:
static void draw_baddie(struct az_baddie_t *baddie, struct az_vector_t avatar_position, unsigned long clock) {
  ((baddie->kind != AZ_BAD_NOTHING) ? (void) (0) : __assert_fail ("baddie->kind != AZ_BAD_NOTHING", "src/milestone/view/baddie.c", 36, __extension__ __PRETTY_FUNCTION__));
  if (baddie->stun > 0.0 && az_clock_mod(2, 2, clock)) return;
  float flare = baddie->flare;
  switch (baddie->kind) {
    case AZ_BAD_NOTHING: _az_fatal(__func__, "line %d: unreachable\n", 40);
    case AZ_BAD_TANK:
      glRotated(((double)(az_vtheta(baddie->velocity)) * 57.295779513082323), 0, 0, 1);
      glBegin(0x0006); {
        glColor3f(flare, 0.5, 0.25); glVertex2f(-4, 0);
        glColor3f(0.75f * flare, 0.25, 0.1);
        glVertex2f(14, 8); glVertex2f(11, 11); glVertex2f(-11, 11);
        glVertex2f(-14, 8); glVertex2f(-14, -8); glVertex2f(-11, -11);
        glVertex2f(11, -11); glVertex2f(14, -8); glVertex2f(14, 8);
      } glEnd();
      break;
    case AZ_BAD_GUARD:
      glRotated(((double)(az_vtheta(az_vsub(avatar_position, baddie->position))) * 57.295779513082323), 0, 0, 1);
      glBegin(0x0006); {
        glColor3f(0.25f + 0.75f * flare, 0.5f, 1.0f - flare);
        glVertex2f(0, 0);
        glColor3f(0.15f + 0.5f * flare, 0.25f, 0.2f - 0.2f * flare);
        for (int i = 0; i <= 360; i += 60) {
          glVertex2d(15 * cos(((double)(i) * 0.017453292519943295)),
                     15 * sin(((double)(i) * 0.017453292519943295)));
        }
      } glEnd();
      break;
    case AZ_BAD_BASILISK:
      glRotated(((double)(az_vtheta(baddie->velocity)) * 57.295779513082323), 0, 0, 1);
      glBegin(0x0006); {
        glColor3f(0.5f + 0.5f * flare, 1.0f - 0.5f * flare, 0.25f);
        glVertex2f(0, 0);
        glColor3f(0.25f + 0.25f * flare, 0.5f - 0.25f * flare, 0.12f);
        glVertex2f(15, 0); glVertex2f(-11, 11);
        glVertex2f(-11, -11); glVertex2f(15, 0);
      } glEnd();
      break;
    case AZ_BAD_FAKER:
      glRotated(((double)(az_vtheta(baddie->velocity)) * 57.295779513082323), 0, 0, 1);
      glBegin(0x0006); {
        glColor3f(1, 0, 0.5f - 0.4f * flare); glVertex2f(0, 0);
        glColor3f(0.5f, 0.1f, 0.25f - 0.1f * flare);
        glVertex2f(12, 10); glVertex2f(10, 12); glVertex2f(-10, 12);
        glVertex2f(-12, 10); glVertex2f(-12, -10); glVertex2f(-10, -12);
        glVertex2f(10, -12); glVertex2f(12, -10); glVertex2f(12, 10);
      } glEnd();
      break;
    case AZ_BAD_FORCER:
      if (baddie->cooldown <= 0.0 && baddie->stun <= 0.0) {
        float top = 21 - baddie->position.y;
        float bottom = (500 - 21) - baddie->position.y;
        switch (az_clock_mod(6, 1, clock)) {
          case 0: glColor4f(1, 0, 0, 0.25); break;
          case 1: glColor4f(1, 1, 0, 0.25); break;
          case 2: glColor4f(0, 1, 0, 0.25); break;
          case 3: glColor4f(0, 1, 1, 0.25); break;
          case 4: glColor4f(0, 0, 1, 0.25); break;
          case 5: glColor4f(1, 0, 1, 0.25); break;
        }
        glBegin(0x0005); {
          glVertex2f(-7, top); glVertex2f(7, top);
          glVertex2f(-7, -10); glVertex2f(7, -10);
        } glEnd();
        glBegin(0x0005); {
          glVertex2f(-7, 10); glVertex2f(7, 10);
          glVertex2f(-7, bottom); glVertex2f(7, bottom);
        } glEnd();
      }
      glBegin(0x0006); {
        glColor3f(0.5f + 0.5f * flare, 0.5f - 0.5f * flare,
                  0.5f - 0.5f * flare);
        glVertex2f(0, 0);
        glColor3f(0.5f * flare, 0.0f, 0.5f - 0.5f * flare);
        glVertex2f(11, 11); glVertex2f(-11, 11);
        glVertex2f(-5, 4); glVertex2f(-8, 4);
        glVertex2f(-8, -4); glVertex2f(-5, -4);
        glVertex2f(-11, -11); glVertex2f(11, -11);
        glVertex2f(5, -4); glVertex2f(8, -4);
        glVertex2f(8, 4); glVertex2f(5, 4); glVertex2f(11, 11);
      } glEnd();
      break;
    case AZ_BAD_GHOST:
      glBegin(0x0006); {
        struct az_vector_t center = az_vcaplen(az_vmul(baddie->velocity, 0.07), 15 - 1);
        glColor4f(1, 1 - flare, 1 - flare, 0.25);
        glVertex2d(center.x, center.y);
        glColor4f(1, 1 - flare, 1 - flare, 0);
        for (int i = 0; i <= 360; i += 30) {
          glVertex2d(15 * cos(((double)(i) * 0.017453292519943295)),
                     15 * sin(((double)(i) * 0.017453292519943295)));
        }
      } glEnd();
      break;
  }
}

variable_types: struct az_baddie_t { enum az_baddie_kind_t { AZ_BAD_NOTHING=0, AZ_BAD_BASILISK=1, AZ_BAD_FAKER=2, AZ_BAD_FORCER=3, AZ_BAD_GHOST=4, AZ_BAD_GUARD=5, AZ_BAD_TANK=6 } kind; struct az_vector_t { double x; } position; struct az_vector_t velocity; double cooldown; double stun; double flare; int hitpoints; } *

variable_types:
clock
unsigned long

variable_types: flare float

variable_types: i int

variable_types:
center
struct az_vector_t { double x; }


repo: mdsteele/milestone

decompiled_code:
__int64 __fastcall draw_char(signed int a1)
{
__int64 v1; // rbx
int v2; // er12
float v3; // xmm0_4
float v4; // xmm1_4
__int64 result; // rax

if ( (unsigned int)a1 <= 0x7E )
{
v1 = 18LL * a1;
v2 = dword_364[v1];
if ( v2 > 0 )
{
glBegin((unsigned int)char_specs[18 * a1]);
do
{
v3 = *(float *)&dword_368[v1];
v4 = *(float *)&dword_36C[v1];
v1 += 2LL;
glVertex2f(v3, v4);
}
while ( v1 != 2 * ((unsigned int)(v2 - 1) + 9LL * a1 + 1) );
result = glEnd();
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(signed int a1)
{
__int64 v1; // rbx
int v2; // er12
float v3; // xmm0_4
float v4; // xmm1_4
__int64 result; // rax

if ( (unsigned int)a1 <= 0x7E )
{
v1 = 18LL * a1;
v2 = dword_364[v1];
if ( v2 > 0 )
{
glBegin((unsigned int)char_specs[18 * a1]);
do
{
v3 = *(float *)&dword_368[v1];
v4 = *(float *)&dword_36C[v1];
v1 += 2LL;
glVertex2f(v3, v4);
}
while ( v1 != 2 * ((unsigned int)(v2 - 1) + 9LL * a1 + 1) );
result = glEnd();
}
}
return result;
}

original_code:
static void draw_char(int c) {
  if (c >= 0 && c < ((int)((sizeof(char_specs) / sizeof(*(char_specs))) / !(sizeof(char_specs) % sizeof(*(char_specs))))) &&
      char_specs[c].num_points > 0) {
    glBegin(char_specs[c].mode); {
      for (int i = 0; i < char_specs[c].num_points; ++i) {
        glVertex2f(char_specs[c].points[i].x, char_specs[c].points[i].y);
      }
    } glEnd();
  }
}

variable_types: c int

return_type: void


decompiled_code:
__int64 __fastcall az_draw_chars(int a1, char *a2, __int64 a3, double a4, double a5, double a6)
{
char *v8; // rbx
double v9; // xmm0_8
__int64 v10; // xmm4_8
char *v11; // rbp
signed int v12; // edi
double v14; // xmm0_8
double v15; // [rsp+18h] [rbp-20h]

v8 = a2;
if ( a1 == 1 )
{
if ( a3 < 0 )
v14 = (double)(int)(a3 & 1 | ((unsigned __int64)a3 >> 1)) + (double)(int)(a3 & 1 | ((unsigned __int64)a3 >> 1));
else
v14 = (double)(int)a3;
v10 = LC1;
a5 = a5 - (v14 * a4 - 0.25 * a4) * 0.5;
}
else
{
if ( a1 == 2 )
{
if ( a3 < 0 )
v9 = (double)(int)(a3 & 1 | ((unsigned __int64)a3 >> 1)) + (double)(int)(a3 & 1 | ((unsigned __int64)a3 >> 1));
else
v9 = (double)(int)a3;
a5 = a5 - v9 * a4;
}
v10 = LC1;
}
v15 = *(double *)&v10;
glPushMatrix();
glTranslated(a5 + v15, a6 + v15, 0.0);
glScaled(a4 * 0.125, a4 * 0.125, 1.0);
if ( a3 )
{
v11 = &a2[a3];
do
{
v12 = *v8++;
draw_char(v12);
glTranslated(8.0, 0.0, 0.0);
}
while ( v11 != v8 );
}
return glPopMatrix();
}

original_code:
void az_draw_chars(double height, az_alignment_t align, double x, double top,
                   const char* chars, size_t len) {
  double left = x;
  switch (align) {
    case AZ_ALIGN_LEFT: break;
    case AZ_ALIGN_CENTER: left -= 0.5 * (len * height - 0.25 * height); break;
    case AZ_ALIGN_RIGHT: left -= len * height; break;
  }
  glPushMatrix(); {
    glTranslated(left + 0.5, top + 0.5, 0);
    glScaled(height / 8, height / 8, 1);
    for (size_t i = 0; i < len; ++i) {
      draw_char(chars[i]);
      glTranslated(8, 0, 0);
    }
  } glPopMatrix();
}

canonical_original_code:
void az_draw_chars(double height, enum az_alignment_t align, double x, double top, char *chars, unsigned long len) {
  double left = x;
  switch (align) {
    case AZ_ALIGN_LEFT: break;
    case AZ_ALIGN_CENTER: left -= 0.5 * (len * height - 0.25 * height); break;
    case AZ_ALIGN_RIGHT: left -= len * height; break;
  }
  glPushMatrix(); {
    glTranslated(left + 0.5, top + 0.5, 0);
    glScaled(height / 8, height / 8, 1);
    for (unsigned long i = 0; i < len; ++i) {
      draw_char(chars[i]);
      glTranslated(8, 0, 0);
    }
  } glPopMatrix();
}

variable_types: height double

variable_types: enum az_alignment_t { AZ_ALIGN_LEFT=0, AZ_ALIGN_CENTER=1, AZ_ALIGN_RIGHT=2 }

variable_types: x double

variable_types: top double

variable_types:
chars
char *

variable_types:
len
unsigned long

variable_types: left double

variable_types:
i
unsigned long


decompiled_code:
__int64 __fastcall az_draw_string(int a1, char *a2, double a3, double a4, double a5)
{
__int64 v5; // rax

v5 = strlen(a2);
return az_draw_chars(a1, a2, v5, a3, a4, a5);
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, char *a2, double a3, double a4, double a5)
{
__int64 v5; // rax

v5 = strlen(a2);
return func1(a1, a2, v5, a3, a4, a5);
}

original_code:
void az_draw_string(double height, az_alignment_t align, double x, double top,
                    const char* string) {
  az_draw_chars(height, align, x, top, string, strlen(string));
}

canonical_original_code:
void az_draw_string(double height, enum az_alignment_t align, double x, double top, char *string) {
  az_draw_chars(height, align, x, top, string, strlen(string));
}

variable_types:
string
char *

user_defined_types: enum az_alignment_t { AZ_ALIGN_LEFT=0, AZ_ALIGN_CENTER=1, AZ_ALIGN_RIGHT=2 }


decompiled_code:
__int64 az_draw_printf(int a1, const char *a2, double a3, double a4, double a5, ...)
{
__int64 v5; // r12
void *v6; // rsp
char v8[8]; // [rsp+0h] [rbp-110h] BYREF
double v9; // [rsp+8h] [rbp-108h]
double v10; // [rsp+10h] [rbp-100h]
double v11; // [rsp+18h] [rbp-F8h]
gcc_va_list arg; // [rsp+28h] [rbp-E8h] BYREF

va_start(arg, a5);
v9 = a5;
v10 = a4;
v11 = a3;
v5 = vsnprintf(0LL, 0LL, a2, arg);
v6 = alloca(v5 + 1);
va_end(arg);
va_start(arg, a5);
vsprintf(v8, a2, arg);
return az_draw_chars(a1, v8, v5, v11, v10, v9);
}

canonical_decompiled_code:
__int64 func3(int a1, const char *a2, double a3, double a4, double a5, ...)
{
__int64 v5; // r12
void *v6; // rsp
char v8[8]; // [rsp+0h] [rbp-110h] BYREF
double v9; // [rsp+8h] [rbp-108h]
double v10; // [rsp+10h] [rbp-100h]
double v11; // [rsp+18h] [rbp-F8h]
gcc_va_list arg; // [rsp+28h] [rbp-E8h] BYREF

va_start(arg, a5);
v9 = a5;
v10 = a4;
v11 = a3;
v5 = vsnprintf(0LL, 0LL, a2, arg);
v6 = alloca(v5 + 1);
va_end(arg);
va_start(arg, a5);
vsprintf(v8, a2, arg);
return func1(a1, v8, v5, v11, v10, v9);
}

original_code:
void az_draw_printf(double height, az_alignment_t align, double x, double top,
                    const char *format, ...) {
  va_list args;
  __builtin_va_start(args,format);
  const size_t size = vsnprintf(((void *)0), 0, format, args);
  __builtin_va_end(args);
  char buffer[size + 1];
  __builtin_va_start(args,format);
  vsprintf(buffer, format, args);
  __builtin_va_end(args);
  az_draw_chars(height, align, x, top, buffer, size);
}

canonical_original_code:
void az_draw_printf(double height, enum az_alignment_t align, double x, double top, char *format, ...) {
  __builtin_va_list args;
  __builtin_va_start(args,format);
  unsigned long size = vsnprintf(((void *)0), 0, format, args);
  __builtin_va_end(args);
  char buffer[-1];
  __builtin_va_start(args,format);
  vsprintf(buffer, format, args);
  __builtin_va_end(args);
  az_draw_chars(height, align, x, top, buffer, size);
}

variable_types:
format
char *

variable_types:
size
unsigned long

variable_types:
buffer
char [-1]


original_code:
void az_init_play_state(az_play_state_t *state) {
  memset(state, 0, sizeof(*state));
  state->avatar_position.x = 800 / 2;
  state->avatar_position.y = 500 / 2;
  state->avatar_velocity = AZ_VZERO;
  state->num_lives = 3;
  state->num_bombs = 3;
}

canonical_original_code:
void az_init_play_state(struct az_play_state_t *state) {
  memset(state, 0, sizeof(*state));
  state->avatar_position.x = 800 / 2;
  state->avatar_position.y = 500 / 2;
  state->avatar_velocity = AZ_VZERO;
  state->num_lives = 3;
  state->num_bombs = 3;
}

variable_types: struct az_play_state_t { unsigned long clock; struct az_soundboard_t { enum { AZ_MUSA_NOTHING=0, AZ_MUSA_CHANGE=1, AZ_MUSA_STOP=2 } music_action; enum az_music_key_t { AZ_MUS_NOTHING=0, AZ_MUS_TITLE=1, AZ_MUS_PLAY=2 } next_music; int music_fade_out_millis; int num_oneshots; enum az_sound_key_t { AZ_SND_BONUS_ROUND=0, AZ_SND_BREAK_BONUS_TARGET=1, AZ_SND_BREAK_FAKE_TARGET=2, AZ_SND_BREAK_NORMAL_TARGET=3, AZ_SND_DROP_FAKE_TARGET=4, AZ_SND_FIRE_BOMB=5, AZ_SND_FIRE_BULLET=6, AZ_SND_FIRE_STOPPER=7, AZ_SND_FIRE_TANK_SHELL=8, AZ_SND_FORCEFIELD=9, AZ_SND_GAIN_BOMB=10, AZ_SND_GAIN_LIFE=11, AZ_SND_HIT_TANK_SHELL=12, AZ_SND_HURT_BADDIE=13, AZ_SND_KILL_BASILISK=14, AZ_SND_KILL_GHOST=15, AZ_SND_KILL_GUARD=16, AZ_SND_KILL_TANK=17, AZ_SND_LOSE_LIFE=18, AZ_SND_NEXT_WAVE=19, AZ_SND_STUN_BADDIE=20 } oneshots[10]; int num_persists; struct { enum az_sound_key_t { AZ_SND_BONUS_ROUND=0, AZ_SND_BREAK_BONUS_TARGET=1, AZ_SND_BREAK_FAKE_TARGET=2, AZ_SND_BREAK_NORMAL_TARGET=3, AZ_SND_DROP_FAKE_TARGET=4, AZ_SND_FIRE_BOMB=5, AZ_SND_FIRE_BULLET=6, AZ_SND_FIRE_STOPPER=7, AZ_SND_FIRE_TANK_SHELL=8, AZ_SND_FORCEFIELD=9, AZ_SND_GAIN_BOMB=10, AZ_SND_GAIN_LIFE=11, AZ_SND_HIT_TANK_SHELL=12, AZ_SND_HURT_BADDIE=13, AZ_SND_KILL_BASILISK=14, AZ_SND_KILL_GHOST=15, AZ_SND_KILL_GUARD=16, AZ_SND_KILL_TANK=17, AZ_SND_LOSE_LIFE=18, AZ_SND_NEXT_WAVE=19, AZ_SND_STUN_BADDIE=20 } sound; _Bool play; _Bool loop; _Bool reset; } persists[10]; } soundboard; int num_lives; int num_bombs; long score; int current_wave; int max_wave_on_board; _Bool bonus_round; double wave_time_remaining; int total_baddies_to_spawn; int baddies_left_to_spawn; double spawn_cooldown; double bonus_flash; double gained_life_flash; double lost_life_flash; struct az_message_t { char *text; double time_remaining; _Bool flash; } tutorial_message; struct az_message_t status_message; struct az_vector_t { double x; } avatar_position; struct az_vector_t avatar_velocity; struct az_baddie_t { enum az_baddie_kind_t { AZ_BAD_NOTHING=0, AZ_BAD_BASILISK=1, AZ_BAD_FAKER=2, AZ_BAD_FORCER=3, AZ_BAD_GHOST=4, AZ_BAD_GUARD=5, AZ_BAD_TANK=6 } kind; struct az_vector_t position; struct az_vector_t velocity; double cooldown; double stun; double flare; int hitpoints; } baddies[100]; struct az_particle_t { enum az_particle_kind_t { AZ_PAR_NOTHING=0, AZ_PAR_NORMAL=1 } kind; struct az_color_t { unsigned char r; } color; struct az_vector_t position; struct az_vector_t velocity; double age; } particles[2000]; struct az_projectile_t { enum az_proj_kind_t { AZ_PROJ_NOTHING=0, AZ_PROJ_BULLET=1, AZ_PROJ_BOMB=2, AZ_PROJ_TANK_SHELL=3, AZ_PROJ_STOPPER=4 } kind; struct az_vector_t position; struct az_vector_t velocity; double age; } projectiles[200]; struct az_target_t { enum az_target_kind_t { AZ_TARG_NOTHING=0, AZ_TARG_BONUS=1, AZ_TARG_FAKE=2, AZ_TARG_NORMAL=3, AZ_TARG_REBEL=4, AZ_TARG_UNPLANNED=5 } kind; struct az_vector_t position; struct az_vector_t velocity; int wave; double presence; _Bool is_invisible; double invisibility; } targets[200]; } *

user_defined_types: struct az_play_state_t { unsigned long clock; struct az_soundboard_t soundboard; int num_lives; int num_bombs; long score; int current_wave; int max_wave_on_board; _Bool bonus_round; double wave_time_remaining; int total_baddies_to_spawn; int baddies_left_to_spawn; double spawn_cooldown; double bonus_flash; double gained_life_flash; double lost_life_flash; struct az_message_t tutorial_message; struct az_message_t status_message; struct az_vector_t avatar_position; struct az_vector_t avatar_velocity; struct az_baddie_t baddies[100]; struct az_particle_t particles[2000]; struct az_projectile_t projectiles[200]; struct az_target_t targets[200]; }

user_defined_types: struct az_soundboard_t { enum { AZ_MUSA_NOTHING=0, AZ_MUSA_CHANGE=1, AZ_MUSA_STOP=2 } music_action; enum az_music_key_t next_music; int music_fade_out_millis; int num_oneshots; enum az_sound_key_t oneshots[10]; int num_persists; struct { enum az_sound_key_t sound; _Bool play; _Bool loop; _Bool reset; } persists[10]; }

user_defined_types: struct az_baddie_t { enum az_baddie_kind_t kind; struct az_vector_t position; struct az_vector_t velocity; double cooldown; double stun; double flare; int hitpoints; }

user_defined_types: struct az_particle_t { enum az_particle_kind_t kind; struct az_color_t color; struct az_vector_t position; struct az_vector_t velocity; double age; }

user_defined_types: struct az_projectile_t { enum az_proj_kind_t kind; struct az_vector_t position; struct az_vector_t velocity; double age; }

user_defined_types: struct az_target_t { enum az_target_kind_t kind; struct az_vector_t position; struct az_vector_t velocity; int wave; double presence; _Bool is_invisible; double invisibility; }


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

result = 4LL;
if ( a1 <= 19 )
result = (unsigned int)(a1 > 9) + 2;
return result;
}

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

result = 4LL;
if ( a1 <= 19 )
result = (unsigned int)(a1 > 9) + 2;
return result;
}

original_code:
int az_num_waves_at_once_for_wave(int wave) {
  if (wave >= 20) return 4;
  else if (wave >= 10) return 3;
  else return 2;
}

variable_types: wave int

return_type: int


decompiled_code:
void __fastcall az_set_message(__int64 a1, char a2, __int64 a3, double a4)
{
*(_BYTE *)(a1 + 16) = a2;
*(_QWORD *)a1 = a3;
*(double *)(a1 + 8) = a4;
}

canonical_decompiled_code:
void __fastcall func6(__int64 a1, char a2, __int64 a3, double a4)
{
*(_BYTE *)(a1 + 16) = a2;
*(_QWORD *)a1 = a3;
*(double *)(a1 + 8) = a4;
}

original_code:
void az_set_message(az_message_t *message, double seconds, _Bool flash,
                    const char *text) {
  message->time_remaining = seconds;
  message->flash = flash;
  message->text = text;
}

canonical_original_code:
void az_set_message(struct az_message_t *message, double seconds, _Bool flash, char *text) {
  message->time_remaining = seconds;
  message->flash = flash;
  message->text = text;
}

variable_types: struct az_message_t { char *text; double time_remaining; _Bool flash; } *

variable_types: seconds double

variable_types:
text
char *


decompiled_code:
__int64 __fastcall az_award_points(__int64 a1, __int64 a2)
{
__int64 v2; // r9
__int64 result; // rax
__int64 v4; // r8

if ( a2 < 0 )
_assert_fail("points >= 0", "src/milestone/state/play.c", 0x66u, "az_award_points");
v2 = *(_QWORD *)(a1 + 160);
*(_QWORD *)(a1 + 160) = v2 + a2;
result = 0x346DC5D63886594BLL * v2;
if ( (v2 + a2) / 20000 > v2 / 20000 )
{
++*(_DWORD *)(a1 + 152);
az_set_message(a1 + 256, 1, (__int64)"Extra bomb earned!", 2.5);
result = az_play_sound(v4 + 8, 10LL);
}
return result;
}

original_code:
void az_award_points(az_play_state_t *state, int64_t points) {
  ((points >= 0) ? (void) (0) : __assert_fail ("points >= 0", "src/milestone/state/play.c", 102, __extension__ __PRETTY_FUNCTION__));
  const int64_t old_score = state->score;
  state->score += points;
  const int64_t new_score = state->score;
  if (new_score / 20000 > old_score / 20000) {
    ++state->num_bombs;
    az_set_message(&state->status_message, 2.5, 1, "Extra bomb earned!");
    az_play_sound(&state->soundboard, AZ_SND_GAIN_BOMB);
  }
}

canonical_original_code:
void az_award_points(struct az_play_state_t *state, long points) {
  ((points >= 0) ? (void) (0) : __assert_fail ("points >= 0", "src/milestone/state/play.c", 102, __extension__ __PRETTY_FUNCTION__));
  long old_score = state->score;
  state->score += points;
  long new_score = state->score;
  if (new_score / 20000 > old_score / 20000) {
    ++state->num_bombs;
    az_set_message(&state->status_message, 2.5, 1, "Extra bomb earned!");
    az_play_sound(&state->soundboard, AZ_SND_GAIN_BOMB);
  }
}

variable_types: points long

user_defined_types: struct az_message_t { char *text; double time_remaining; _Bool flash; }

user_defined_types: enum az_music_key_t { AZ_MUS_NOTHING=0, AZ_MUS_TITLE=1, AZ_MUS_PLAY=2 }

user_defined_types: enum az_sound_key_t { AZ_SND_BONUS_ROUND=0, AZ_SND_BREAK_BONUS_TARGET=1, AZ_SND_BREAK_FAKE_TARGET=2, AZ_SND_BREAK_NORMAL_TARGET=3, AZ_SND_DROP_FAKE_TARGET=4, AZ_SND_FIRE_BOMB=5, AZ_SND_FIRE_BULLET=6, AZ_SND_FIRE_STOPPER=7, AZ_SND_FIRE_TANK_SHELL=8, AZ_SND_FORCEFIELD=9, AZ_SND_GAIN_BOMB=10, AZ_SND_GAIN_LIFE=11, AZ_SND_HIT_TANK_SHELL=12, AZ_SND_HURT_BADDIE=13, AZ_SND_KILL_BASILISK=14, AZ_SND_KILL_GHOST=15, AZ_SND_KILL_GUARD=16, AZ_SND_KILL_TANK=17, AZ_SND_LOSE_LIFE=18, AZ_SND_NEXT_WAVE=19, AZ_SND_STUN_BADDIE=20 }

user_defined_types: enum az_baddie_kind_t { AZ_BAD_NOTHING=0, AZ_BAD_BASILISK=1, AZ_BAD_FAKER=2, AZ_BAD_FORCER=3, AZ_BAD_GHOST=4, AZ_BAD_GUARD=5, AZ_BAD_TANK=6 }

user_defined_types: enum az_particle_kind_t { AZ_PAR_NOTHING=0, AZ_PAR_NORMAL=1 }

user_defined_types: enum az_proj_kind_t { AZ_PROJ_NOTHING=0, AZ_PROJ_BULLET=1, AZ_PROJ_BOMB=2, AZ_PROJ_TANK_SHELL=3, AZ_PROJ_STOPPER=4 }

user_defined_types: enum az_target_kind_t { AZ_TARG_NOTHING=0, AZ_TARG_BONUS=1, AZ_TARG_FAKE=2, AZ_TARG_NORMAL=3, AZ_TARG_REBEL=4, AZ_TARG_UNPLANNED=5 }


original_code:
void az_bounce_off_edges(az_vector_t *position, az_vector_t *velocity,
                         double radius) {
  if (position->x < 1 + radius) {
    position->x = 1 + radius;
    if (velocity->x < 0) velocity->x = -0.5 * velocity->x;
  }
  if (position->x > (800 - 1) - radius) {
    position->x = (800 - 1) - radius;
    if (velocity->x > 0) velocity->x = -0.5 * velocity->x;
  }
  if (position->y < 21 + radius) {
    position->y = 21 + radius;
    if (velocity->y < 0) velocity->y = -0.5 * velocity->y;
  }
  if (position->y > (500 - 21) - radius) {
    position->y = (500 - 21) - radius;
    if (velocity->y > 0) velocity->y = -0.5 * velocity->y;
  }
}

canonical_original_code:
void az_bounce_off_edges(struct az_vector_t *position, struct az_vector_t *velocity, double radius) {
  if (position->x < 1 + radius) {
    position->x = 1 + radius;
    if (velocity->x < 0) velocity->x = -0.5 * velocity->x;
  }
  if (position->x > (800 - 1) - radius) {
    position->x = (800 - 1) - radius;
    if (velocity->x > 0) velocity->x = -0.5 * velocity->x;
  }
  if (position->y < 21 + radius) {
    position->y = 21 + radius;
    if (velocity->y < 0) velocity->y = -0.5 * velocity->y;
  }
  if (position->y > (500 - 21) - radius) {
    position->y = (500 - 21) - radius;
    if (velocity->y > 0) velocity->y = -0.5 * velocity->y;
  }
}

variable_types:
position
struct az_vector_t { double x; } *

variable_types:
velocity
struct az_vector_t *

variable_types: radius double


decompiled_code:
unsigned __int64 __fastcall az_clock_mod(int a1, int a2, unsigned __int64 a3)
{
if ( a1 <= 0 )
_assert_fail("modulus > 0", "src/milestone/util/clock.c", 0x1Bu, "az_clock_mod");
if ( a2 <= 0 )
_assert_fail("slowdown > 0", "src/milestone/util/clock.c", 0x1Cu, "az_clock_mod");
return a3 % (a2 * a1) / a2;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func0(int a1, int a2, unsigned __int64 a3)
{
if ( a1 <= 0 )
_assert_fail("modulus > 0", "src/milestone/util/clock.c", 0x1Bu, "az_clock_mod");
if ( a2 <= 0 )
_assert_fail("slowdown > 0", "src/milestone/util/clock.c", 0x1Cu, "az_clock_mod");
return a3 % (a2 * a1) / a2;
}

original_code:
int az_clock_mod(int modulus, int slowdown, az_clock_t clock) {
  ((modulus > 0) ? (void) (0) : __assert_fail ("modulus > 0", "src/milestone/util/clock.c", 27, __extension__ __PRETTY_FUNCTION__));
  ((slowdown > 0) ? (void) (0) : __assert_fail ("slowdown > 0", "src/milestone/util/clock.c", 28, __extension__ __PRETTY_FUNCTION__));
  return (clock % (modulus * slowdown)) / slowdown;
}

canonical_original_code:
int az_clock_mod(int modulus, int slowdown, unsigned long clock) {
  ((modulus > 0) ? (void) (0) : __assert_fail ("modulus > 0", "src/milestone/util/clock.c", 27, __extension__ __PRETTY_FUNCTION__));
  ((slowdown > 0) ? (void) (0) : __assert_fail ("slowdown > 0", "src/milestone/util/clock.c", 28, __extension__ __PRETTY_FUNCTION__));
  return (clock % (modulus * slowdown)) / slowdown;
}

variable_types: modulus int

variable_types: slowdown int

variable_types:
clock
unsigned long


decompiled_code:
unsigned __int64 __fastcall az_clock_zigzag(int a1, int a2, unsigned __int64 a3)
{
unsigned __int64 result; // rax

result = az_clock_mod(2 * (a1 - 1), a2, a3);
if ( a1 - 1 < (int)result )
result = (unsigned int)(2 * (a1 - 1) - result);
return result;
}

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

result = func0(2 * (a1 - 1), a2, a3);
if ( a1 - 1 < (int)result )
result = (unsigned int)(2 * (a1 - 1) - result);
return result;
}

original_code:
int az_clock_zigzag(int modulus, int slowdown, az_clock_t clock) {
  const int m = modulus - 1;
  const int d = az_clock_mod(2 * m, slowdown, clock);
  return (d <= m ? d : 2 * m - d);
}

canonical_original_code:
int az_clock_zigzag(int modulus, int slowdown, unsigned long clock) {
  int m = modulus - 1;
  int d = az_clock_mod(2 * m, slowdown, clock);
  return (d <= m ? d : 2 * m - d);
}

variable_types: m int

variable_types: d int


original_code:
static void draw_avatar_internal(az_color_t color) {
  const double outer = 10;
  const double inner = outer - 3;
  glBegin(0x0005); {
    for (int i = 0; i <= 360; i += 30) {
      const double c = cos(((double)(i) * 0.017453292519943295)), s = sin(((double)(i) * 0.017453292519943295));
      glColor3f(0.8, 0.8, 0.8); glVertex2f(inner * c, inner * s);
      glColor3f(0.4, 0.4, 0.4); glVertex2f(outer * c, outer * s);
    }
  } glEnd();
  for (int i = 0; i < 360; i += 120) {
    glBegin(0x0005); {
      glColor3f(0.4, 0.4, 0.4); glVertex2f(3, 2); glVertex2f(inner, 1);
      glColor3f(0.8, 0.8, 0.8); glVertex2f(0, 0); glVertex2f(outer, 0);
      glColor3f(0.4, 0.4, 0.4); glVertex2f(3, -2); glVertex2f(inner, -1);
    } glEnd();
    glRotatef(120, 0, 0, 1);
  }
  glBegin(0x0006); {
    glColor4ub(color.r, color.g, color.b, color.a); glVertex2f(0, 0);
    glColor4ub(color.r / 2, color.g / 2, color.b / 2, color.a);
    for (int i = 0; i <= 360; i += 30) {
      glVertex2d(4 * cos(((double)(i) * 0.017453292519943295)), 4 * sin(((double)(i) * 0.017453292519943295)));
    }
  } glEnd();
}

canonical_original_code:
static void draw_avatar_internal(struct az_color_t color) {
  double outer = 10;
  double inner = outer - 3;
  glBegin(0x0005); {
    for (int i = 0; i <= 360; i += 30) {
      double c = cos(((double)(i) * 0.017453292519943295)); double s = sin(((double)(i) * 0.017453292519943295));
      glColor3f(0.8, 0.8, 0.8); glVertex2f(inner * c, inner * s);
      glColor3f(0.4, 0.4, 0.4); glVertex2f(outer * c, outer * s);
    }
  } glEnd();
  for (int i = 0; i < 360; i += 120) {
    glBegin(0x0005); {
      glColor3f(0.4, 0.4, 0.4); glVertex2f(3, 2); glVertex2f(inner, 1);
      glColor3f(0.8, 0.8, 0.8); glVertex2f(0, 0); glVertex2f(outer, 0);
      glColor3f(0.4, 0.4, 0.4); glVertex2f(3, -2); glVertex2f(inner, -1);
    } glEnd();
    glRotatef(120, 0, 0, 1);
  }
  glBegin(0x0006); {
    glColor4ub(color.r, color.g, color.b, color.a); glVertex2f(0, 0);
    glColor4ub(color.r / 2, color.g / 2, color.b / 2, color.a);
    for (int i = 0; i <= 360; i += 30) {
      glVertex2d(4 * cos(((double)(i) * 0.017453292519943295)), 4 * sin(((double)(i) * 0.017453292519943295)));
    }
  } glEnd();
}

variable_types:
color
struct az_color_t { unsigned char r; }

variable_types: outer double

variable_types: inner double

variable_types: i int

variable_types: c double

variable_types: s double


decompiled_code:
__int64 __fastcall az_draw_avatar(__int64 a1)
{
double v1; // xmm0_8
unsigned int v2; // eax
int v3; // eax

glPushMatrix();
glTranslated(*(double *)(a1 + 280), *(double *)(a1 + 288), 0.0);
v1 = az_vtheta(*(double *)(a1 + 296), *(double *)(a1 + 304));
glRotated(v1 * 57.29577951308232, 0.0, 0.0, 1.0);
v2 = az_clock_mod(6LL, 20LL, *(_QWORD *)a1);
v3 = az_color_for_wave(v2);
draw_avatar_internal(v3);
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
double v1; // xmm0_8
unsigned int v2; // eax
int v3; // eax

glPushMatrix();
glTranslated(*(double *)(a1 + 280), *(double *)(a1 + 288), 0.0);
v1 = az_vtheta(*(double *)(a1 + 296), *(double *)(a1 + 304));
glRotated(v1 * 57.29577951308232, 0.0, 0.0, 1.0);
v2 = az_clock_mod(6LL, 20LL, *(_QWORD *)a1);
v3 = az_color_for_wave(v2);
func0(v3);
return glPopMatrix();
}

original_code:
void az_draw_avatar(const az_play_state_t *state) {
  glPushMatrix(); {
    glTranslated(state->avatar_position.x, state->avatar_position.y, 0);
    glRotated(((double)(az_vtheta(state->avatar_velocity)) * 57.295779513082323), 0, 0, 1);
    draw_avatar_internal(az_color_for_wave(az_clock_mod(6, 20, state->clock)));
  } glPopMatrix();
}

canonical_original_code:
void az_draw_avatar(struct az_play_state_t *state) {
  glPushMatrix(); {
    glTranslated(state->avatar_position.x, state->avatar_position.y, 0);
    glRotated(((double)(az_vtheta(state->avatar_velocity)) * 57.295779513082323), 0, 0, 1);
    draw_avatar_internal(az_color_for_wave(az_clock_mod(6, 20, state->clock)));
  } glPopMatrix();
}

variable_types: struct az_play_state_t { unsigned long clock; struct az_soundboard_t { enum { AZ_MUSA_NOTHING=0, AZ_MUSA_CHANGE=1, AZ_MUSA_STOP=2 } music_action; enum az_music_key_t { AZ_MUS_NOTHING=0, AZ_MUS_TITLE=1, AZ_MUS_PLAY=2 } next_music; int music_fade_out_millis; int num_oneshots; enum az_sound_key_t { AZ_SND_BONUS_ROUND=0, AZ_SND_BREAK_BONUS_TARGET=1, AZ_SND_BREAK_FAKE_TARGET=2, AZ_SND_BREAK_NORMAL_TARGET=3, AZ_SND_DROP_FAKE_TARGET=4, AZ_SND_FIRE_BOMB=5, AZ_SND_FIRE_BULLET=6, AZ_SND_FIRE_STOPPER=7, AZ_SND_FIRE_TANK_SHELL=8, AZ_SND_FORCEFIELD=9, AZ_SND_GAIN_BOMB=10, AZ_SND_GAIN_LIFE=11, AZ_SND_HIT_TANK_SHELL=12, AZ_SND_HURT_BADDIE=13, AZ_SND_KILL_BASILISK=14, AZ_SND_KILL_GHOST=15, AZ_SND_KILL_GUARD=16, AZ_SND_KILL_TANK=17, AZ_SND_LOSE_LIFE=18, AZ_SND_NEXT_WAVE=19, AZ_SND_STUN_BADDIE=20 } oneshots[10]; int num_persists; struct { enum az_sound_key_t { AZ_SND_BONUS_ROUND=0, AZ_SND_BREAK_BONUS_TARGET=1, AZ_SND_BREAK_FAKE_TARGET=2, AZ_SND_BREAK_NORMAL_TARGET=3, AZ_SND_DROP_FAKE_TARGET=4, AZ_SND_FIRE_BOMB=5, AZ_SND_FIRE_BULLET=6, AZ_SND_FIRE_STOPPER=7, AZ_SND_FIRE_TANK_SHELL=8, AZ_SND_FORCEFIELD=9, AZ_SND_GAIN_BOMB=10, AZ_SND_GAIN_LIFE=11, AZ_SND_HIT_TANK_SHELL=12, AZ_SND_HURT_BADDIE=13, AZ_SND_KILL_BASILISK=14, AZ_SND_KILL_GHOST=15, AZ_SND_KILL_GUARD=16, AZ_SND_KILL_TANK=17, AZ_SND_LOSE_LIFE=18, AZ_SND_NEXT_WAVE=19, AZ_SND_STUN_BADDIE=20 } sound; _Bool play; _Bool loop; _Bool reset; } persists[10]; } soundboard; int num_lives; int num_bombs; long score; int current_wave; int max_wave_on_board; _Bool bonus_round; double wave_time_remaining; int total_baddies_to_spawn; int baddies_left_to_spawn; double spawn_cooldown; double bonus_flash; double gained_life_flash; double lost_life_flash; struct az_message_t { char *text; double time_remaining; _Bool flash; } tutorial_message; struct az_message_t status_message; struct az_vector_t { double x; } avatar_position; struct az_vector_t avatar_velocity; struct az_baddie_t { enum az_baddie_kind_t { AZ_BAD_NOTHING=0, AZ_BAD_BASILISK=1, AZ_BAD_FAKER=2, AZ_BAD_FORCER=3, AZ_BAD_GHOST=4, AZ_BAD_GUARD=5, AZ_BAD_TANK=6 } kind; struct az_vector_t position; struct az_vector_t velocity; double cooldown; double stun; double flare; int hitpoints; } baddies[100]; struct az_particle_t { enum az_particle_kind_t { AZ_PAR_NOTHING=0, AZ_PAR_NORMAL=1 } kind; struct az_color_t { unsigned char r; } color; struct az_vector_t position; struct az_vector_t velocity; double age; } particles[2000]; struct az_projectile_t { enum az_proj_kind_t { AZ_PROJ_NOTHING=0, AZ_PROJ_BULLET=1, AZ_PROJ_BOMB=2, AZ_PROJ_TANK_SHELL=3, AZ_PROJ_STOPPER=4 } kind; struct az_vector_t position; struct az_vector_t velocity; double age; } projectiles[200]; struct az_target_t { enum az_target_kind_t { AZ_TARG_NOTHING=0, AZ_TARG_BONUS=1, AZ_TARG_FAKE=2, AZ_TARG_NORMAL=3, AZ_TARG_REBEL=4, AZ_TARG_UNPLANNED=5 } kind; struct az_vector_t position; struct az_vector_t velocity; int wave; double presence; _Bool is_invisible; double invisibility; } targets[200]; } *


decompiled_code:
__int64 __fastcall az_draw_avatar_icon(int a1, int a2, unsigned int a3)
{
int v4; // eax

glPushMatrix();
glTranslated((double)(a1 + 8), (double)(a2 + 8), 0.0);
glScaled(0.8, 0.8, 1.0);
v4 = az_color_for_wave(a3);
draw_avatar_internal(v4);
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, int a2, unsigned int a3)
{
int v4; // eax

glPushMatrix();
glTranslated((double)(a1 + 8), (double)(a2 + 8), 0.0);
glScaled(0.8, 0.8, 1.0);
v4 = az_color_for_wave(a3);
func0(v4);
return glPopMatrix();
}

original_code:
void az_draw_avatar_icon(int left, int top, int current_wave) {
  glPushMatrix(); {
    glTranslated(left + 8, top + 8, 0);
    const double factor = 8.0 / 10;
    glScaled(factor, factor, 1);
    draw_avatar_internal(az_color_for_wave(current_wave));
  } glPopMatrix();
}

canonical_original_code:
void az_draw_avatar_icon(int left, int top, int current_wave) {
  glPushMatrix(); {
    glTranslated(left + 8, top + 8, 0);
    double factor = 8.0 / 10;
    glScaled(factor, factor, 1);
    draw_avatar_internal(az_color_for_wave(current_wave));
  } glPopMatrix();
}

variable_types: left int

variable_types: top int

variable_types: factor double


variable_types: j int


decompiled_code:
__int64 __fastcall az_init_gameover_state(_QWORD *a1)
{
int v1; // ecx
unsigned __int64 v2; // rdi
__int64 result; // rax

*a1 = 0LL;
v1 = (int)a1;
v2 = (unsigned __int64)(a1 + 1);
result = 0LL;
*(_QWORD *)(v2 + 176) = 0LL;
memset((void *)(v2 & 0xFFFFFFFFFFFFFFF8LL), 0, 8 * ((v1 - (v2 & 0xFFFFFFF8) + 192) >> 3));
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1)
{
int v1; // ecx
unsigned __int64 v2; // rdi
__int64 result; // rax

*a1 = 0LL;
v1 = (int)a1;
v2 = (unsigned __int64)(a1 + 1);
result = 0LL;
*(_QWORD *)(v2 + 176) = 0LL;
memset((void *)(v2 & 0xFFFFFFFFFFFFFFF8LL), 0, 8 * ((v1 - (v2 & 0xFFFFFFF8) + 192) >> 3));
return result;
}

original_code:
void az_init_gameover_state(az_gameover_state_t *state) {
  memset(state, 0, sizeof(*state));
}

canonical_original_code:
void az_init_gameover_state(struct az_gameover_state_t *state) {
  memset(state, 0, sizeof(*state));
}

variable_types: struct az_gameover_state_t { unsigned long clock; struct az_soundboard_t { enum { AZ_MUSA_NOTHING=0, AZ_MUSA_CHANGE=1, AZ_MUSA_STOP=2 } music_action; enum az_music_key_t { AZ_MUS_NOTHING=0, AZ_MUS_TITLE=1, AZ_MUS_PLAY=2 } next_music; int music_fade_out_millis; int num_oneshots; enum az_sound_key_t { AZ_SND_BONUS_ROUND=0, AZ_SND_BREAK_BONUS_TARGET=1, AZ_SND_BREAK_FAKE_TARGET=2, AZ_SND_BREAK_NORMAL_TARGET=3, AZ_SND_DROP_FAKE_TARGET=4, AZ_SND_FIRE_BOMB=5, AZ_SND_FIRE_BULLET=6, AZ_SND_FIRE_STOPPER=7, AZ_SND_FIRE_TANK_SHELL=8, AZ_SND_FORCEFIELD=9, AZ_SND_GAIN_BOMB=10, AZ_SND_GAIN_LIFE=11, AZ_SND_HIT_TANK_SHELL=12, AZ_SND_HURT_BADDIE=13, AZ_SND_KILL_BASILISK=14, AZ_SND_KILL_GHOST=15, AZ_SND_KILL_GUARD=16, AZ_SND_KILL_TANK=17, AZ_SND_LOSE_LIFE=18, AZ_SND_NEXT_WAVE=19, AZ_SND_STUN_BADDIE=20 } oneshots[10]; int num_persists; struct { enum az_sound_key_t { AZ_SND_BONUS_ROUND=0, AZ_SND_BREAK_BONUS_TARGET=1, AZ_SND_BREAK_FAKE_TARGET=2, AZ_SND_BREAK_NORMAL_TARGET=3, AZ_SND_DROP_FAKE_TARGET=4, AZ_SND_FIRE_BOMB=5, AZ_SND_FIRE_BULLET=6, AZ_SND_FIRE_STOPPER=7, AZ_SND_FIRE_TANK_SHELL=8, AZ_SND_FORCEFIELD=9, AZ_SND_GAIN_BOMB=10, AZ_SND_GAIN_LIFE=11, AZ_SND_HIT_TANK_SHELL=12, AZ_SND_HURT_BADDIE=13, AZ_SND_KILL_BASILISK=14, AZ_SND_KILL_GHOST=15, AZ_SND_KILL_GUARD=16, AZ_SND_KILL_TANK=17, AZ_SND_LOSE_LIFE=18, AZ_SND_NEXT_WAVE=19, AZ_SND_STUN_BADDIE=20 } sound; _Bool play; _Bool loop; _Bool reset; } persists[10]; } soundboard; int last_wave; long score; _Bool is_high_score; int cursor; char name_buffer[21]; } *

user_defined_types: struct az_gameover_state_t { unsigned long clock; struct az_soundboard_t soundboard; int last_wave; long score; _Bool is_high_score; int cursor; char name_buffer[21]; }


original_code:
static void kill_baddie(az_play_state_t *state, az_baddie_t *baddie,
                        az_vector_t bullet_velocity) {
  ((baddie->kind != AZ_BAD_NOTHING) ? (void) (0) : __assert_fail ("baddie->kind != AZ_BAD_NOTHING", "src/milestone/tick/projectile.c", 35, __extension__ __PRETTY_FUNCTION__));
  az_award_points(state, az_baddie_point_value(baddie->kind));
  for (int i = 0; i < 360; i += 15) {
    for (int j = 1; j < 15; j += 1) {
      az_color_t color;
      if (baddie->kind == AZ_BAD_GHOST) {
        color = (az_color_t){128, 128, 128, 255};
      } else color = (az_color_t){128 + az_randint(0, 127), 128, 0, 255};
      const az_vector_t position =
        az_vadd(baddie->position, az_vpolar(j, ((double)(i) * 0.017453292519943295)));
      const az_vector_t velocity =
        az_vadd(az_vadd(az_vpolar(j * 10, ((double)(i) * 0.017453292519943295)),
                        az_vmul(bullet_velocity, 0.25)),
                (az_vector_t){az_random(-30, 30), az_random(-20, 20)});
      const double lifetime = az_random(1.0, 6.0);
      az_add_particle(state, color, position, velocity, lifetime);
    }
  }
  az_sound_key_t sound = AZ_SND_KILL_TANK;
  switch (baddie->kind) {
    case AZ_BAD_NOTHING: _az_fatal(__func__, "line %d: unreachable\n", 55);
    case AZ_BAD_BASILISK: sound = AZ_SND_KILL_BASILISK; break;
    case AZ_BAD_FAKER: sound = AZ_SND_KILL_TANK; break;
    case AZ_BAD_FORCER: sound = AZ_SND_KILL_TANK; break;
    case AZ_BAD_GHOST: sound = AZ_SND_KILL_GHOST; break;
    case AZ_BAD_GUARD: sound = AZ_SND_KILL_GUARD; break;
    case AZ_BAD_TANK: sound = AZ_SND_KILL_TANK; break;
  }
  az_play_sound(&state->soundboard, sound);
  baddie->kind = AZ_BAD_NOTHING;
}

canonical_original_code:
static void kill_baddie(struct az_play_state_t *state, struct az_baddie_t *baddie, struct az_vector_t bullet_velocity) {
  ((baddie->kind != AZ_BAD_NOTHING) ? (void) (0) : __assert_fail ("baddie->kind != AZ_BAD_NOTHING", "src/milestone/tick/projectile.c", 35, __extension__ __PRETTY_FUNCTION__));
  az_award_points(state, az_baddie_point_value(baddie->kind));
  for (int i = 0; i < 360; i += 15) {
    for (int j = 1; j < 15; j += 1) {
      struct az_color_t color;
      if (baddie->kind == AZ_BAD_GHOST) {
        color = (struct az_color_t){128, 128, 128, 255};
      } else color = (struct az_color_t){128 + az_randint(0, 127), 128, 0, 255};
      struct az_vector_t position = az_vadd(baddie->position, az_vpolar(j, ((double)(i) * 0.017453292519943295)));
      struct az_vector_t velocity = az_vadd(az_vadd(az_vpolar(j * 10, ((double)(i) * 0.017453292519943295)),
                        az_vmul(bullet_velocity, 0.25)),
                (az_vector_t){az_random(-30, 30), az_random(-20, 20)});
      double lifetime = az_random(1.0, 6.0);
      az_add_particle(state, color, position, velocity, lifetime);
    }
  }
  enum az_sound_key_t sound = AZ_SND_KILL_TANK;
  switch (baddie->kind) {
    case AZ_BAD_NOTHING: _az_fatal(__func__, "line %d: unreachable\n", 55);
    case AZ_BAD_BASILISK: sound = AZ_SND_KILL_BASILISK; break;
    case AZ_BAD_FAKER: sound = AZ_SND_KILL_TANK; break;
    case AZ_BAD_FORCER: sound = AZ_SND_KILL_TANK; break;
    case AZ_BAD_GHOST: sound = AZ_SND_KILL_GHOST; break;
    case AZ_BAD_GUARD: sound = AZ_SND_KILL_GUARD; break;
    case AZ_BAD_TANK: sound = AZ_SND_KILL_TANK; break;
  }
  az_play_sound(&state->soundboard, sound);
  baddie->kind = AZ_BAD_NOTHING;
}

variable_types:
baddie
struct az_baddie_t *

variable_types:
position
struct az_vector_t { double x; }

variable_types:
velocity
struct az_vector_t { double x; }

variable_types: lifetime double

variable_types: enum az_sound_key_t { AZ_SND_BONUS_ROUND=0, AZ_SND_BREAK_BONUS_TARGET=1, AZ_SND_BREAK_FAKE_TARGET=2, AZ_SND_BREAK_NORMAL_TARGET=3, AZ_SND_DROP_FAKE_TARGET=4, AZ_SND_FIRE_BOMB=5, AZ_SND_FIRE_BULLET=6, AZ_SND_FIRE_STOPPER=7, AZ_SND_FIRE_TANK_SHELL=8, AZ_SND_FORCEFIELD=9, AZ_SND_GAIN_BOMB=10, AZ_SND_GAIN_LIFE=11, AZ_SND_HIT_TANK_SHELL=12, AZ_SND_HURT_BADDIE=13, AZ_SND_KILL_BASILISK=14, AZ_SND_KILL_GHOST=15, AZ_SND_KILL_GUARD=16, AZ_SND_KILL_TANK=17, AZ_SND_LOSE_LIFE=18, AZ_SND_NEXT_WAVE=19, AZ_SND_STUN_BADDIE=20 }


decompiled_code:
__int64 __fastcall hurt_baddie(__int64 a1, __int64 a2, double a3, double a4)
{
int v4; // eax

v4 = *(_DWORD *)(a2 + 64) - 1;
*(_DWORD *)(a2 + 64) = v4;
if ( v4 <= 0 )
return kill_baddie(a1, a2, a3, a4);
*(double *)(a2 + 56) = LC9;
return az_play_sound(a1 + 8, 13LL);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2, double a3, double a4)
{
int v4; // eax

v4 = *(_DWORD *)(a2 + 64) - 1;
*(_DWORD *)(a2 + 64) = v4;
if ( v4 <= 0 )
return func0(a1, a2, a3, a4);
*(double *)(a2 + 56) = LC9;
return az_play_sound(a1 + 8, 13LL);
}

original_code:
static void hurt_baddie(az_play_state_t *state, az_baddie_t *baddie,
                        az_vector_t bullet_velocity) {
  --baddie->hitpoints;
  if (baddie->hitpoints <= 0) kill_baddie(state, baddie, bullet_velocity);
  else {
    baddie->flare = 1.0;
    az_play_sound(&state->soundboard, AZ_SND_HURT_BADDIE);
  }
}

canonical_original_code:
static void hurt_baddie(struct az_play_state_t *state, struct az_baddie_t *baddie, struct az_vector_t bullet_velocity) {
  --baddie->hitpoints;
  if (baddie->hitpoints <= 0) kill_baddie(state, baddie, bullet_velocity);
  else {
    baddie->flare = 1.0;
    az_play_sound(&state->soundboard, AZ_SND_HURT_BADDIE);
  }
}


decompiled_code:
char *__fastcall az_strdup(char *src)
{
size_t v1; // rax
char *v2; // rax

if ( !src )
return 0LL;
v1 = strlen(src);
v2 = (char *)az_alloc("az_strdup", v1 + 1, 1uLL);
return strcpy(v2, src);
}

canonical_decompiled_code:
char *__fastcall func3(char *src)
{
size_t v1; // rax
char *v2; // rax

if ( !src )
return 0LL;
v1 = strlen(src);
v2 = (char *)func2("az_strdup", v1 + 1, 1uLL);
return strcpy(v2, src);
}

original_code:
char *az_strdup(const char *string) {
  if (string == ((void *)0)) return ((void *)0);
  char *duplicate = ((char *)_az_alloc(__func__, (strlen(string) + 1), sizeof(char)));
  return strcpy(duplicate, string);
}

canonical_original_code:
char *az_strdup(char *string) {
  if (string == ((void *)0)) return ((void *)0);
  char *duplicate = ((char *)_az_alloc(__func__, (strlen(string) + 1), sizeof(char)));
  return strcpy(duplicate, string);
}

variable_types:
string
char *

variable_types:
duplicate
char *

return_type: char *


decompiled_code:
__int64 __fastcall draw_target(__int64 a1, __int64 a2)
{
float v2; // xmm6_4
int v3; // eax
double v4; // xmm0_8
unsigned int v5; // eax
double v6; // xmm2_8
double v7; // xmm1_8
double v8; // xmm0_8
__int64 result; // rax
int v10; // eax
double v11; // xmm0_8
unsigned int v12; // eax
double v13; // xmm2_8
double v14; // xmm3_8
double v15; // xmm2_8
int v16; // eax
double v17; // xmm4_8
double v18; // xmm1_8
int v19; // ebx
double v20; // xmm3_8
__int64 v21; // xmm2_8
double v22; // [rsp+0h] [rbp-40h]
double cosx; // [rsp+18h] [rbp-28h] BYREF
double sinx[4]; // [rsp+20h] [rbp-20h] BYREF

v2 = 1.0 - *(double *)(a1 + 64);
if ( *(_DWORD *)a1 == 1 )
{
v16 = az_clock_mod(360LL, 1LL, a2);
glRotated((double)(2 * v16), 0.0, 0.0, 1.0);
glBegin(6LL);
glColor4f(1.0, 1.0, 1.0, 0.0);
glVertex2f(0.0);
switch ( (unsigned int)az_clock_mod(6LL, 1LL, a2) )
{
case 0u:
glColor4f(1.0, 0.5, 0.5, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 1u:
glColor4f(1.0, 1.0, 0.5, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 2u:
glColor4f(0.5, 1.0, 0.5, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 3u:
glColor4f(0.5, 1.0, 1.0, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 4u:
glColor4f(0.5, 0.5, 1.0, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 5u:
glColor4f(1.0, 0.5, 1.0, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
default:
break;
}
v17 = *(double *)(a1 + 48);
v18 = 0.0;
v19 = 0;
v20 = *(double *)&LC2;
v21 = LC1;
while ( 1 )
{
++v19;
glVertex2d(v20 * (*(double *)&v21 * v17), v18 * (*(double *)&v21 * v17));
if ( v19 == 11 )
break;
v21 = LC0;
if ( (v19 & 1) == 0 )
v21 = LC1;
v22 = *(double *)(a1 + 48);
sincos((double)(36 * v19) * 0.0174532925199433, sinx, &cosx);
v20 = cosx;
v18 = sinx[0];
v17 = v22;
}
result = ((__int64 (*)(void))glEnd)();
}
else
{
if ( *(_DWORD *)a1 == 2 )
{
v10 = az_clock_mod(360LL, 1LL, a2);
v11 = sin((double)(2 * v10) * 0.0174532925199433);
glRotated(v11 * 120.0, 0.0, 0.0, 1.0);
glBegin(5LL);
v12 = az_target_color(a1);
glColor4ub((unsigned __int8)v12, BYTE1(v12), BYTE2(v12), (unsigned __int8)(int)(float)((float)HIBYTE(v12) * v2));
v13 = *(double *)(a1 + 48);
v14 = 5.0 * v13;
v15 = v13 * 8.0;
*(float *)&v14 = v14;
*(float *)&v15 = v15;
glVertex2f(v15);
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v14)));
glVertex2f(COERCE_DOUBLE(LODWORD(v15) ^ (unsigned __int64)(unsigned int)LC10));
glVertex2f(COERCE_DOUBLE((unsigned int)LC10 ^ (unsigned __int64)LODWORD(v14)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)(LODWORD(v15) ^ (unsigned int)LC10)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)((unsigned int)LC10 ^ LODWORD(v14))));
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v15)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v14)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v15)));
*(_QWORD *)&v7 = LODWORD(v14);
*(_QWORD *)&v8 = LODWORD(v14);
}
else
{
v3 = az_clock_mod(360LL, 1LL, a2);
v4 = sin((double)(2 * v3) * 0.0174532925199433);
glRotated(v4 * 120.0, 0.0, 0.0, 1.0);
glBegin(6LL);
glColor4f(1.0, 1.0, 1.0, 0.0);
glVertex2f(0.0);
v5 = az_target_color(a1);
glColor4ub((unsigned __int8)v5, BYTE1(v5), BYTE2(v5), (unsigned __int8)(int)(float)((float)HIBYTE(v5) * v2));
v6 = 8.0 * *(double *)(a1 + 48);
*(float *)&v6 = v6;
glVertex2f(v6);
glVertex2f(COERCE_DOUBLE(LODWORD(v6) ^ (unsigned __int64)LC10));
glVertex2f(COERCE_DOUBLE((unsigned __int64)(LODWORD(v6) ^ (unsigned int)LC10)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v6)));
*(_QWORD *)&v7 = LODWORD(v6);
*(_QWORD *)&v8 = LODWORD(v6);
}
glVertex2f(v8);
result = glEnd(v8, v7);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2)
{
float v2; // xmm6_4
int v3; // eax
double v4; // xmm0_8
unsigned int v5; // eax
double v6; // xmm2_8
double v7; // xmm1_8
double v8; // xmm0_8
__int64 result; // rax
int v10; // eax
double v11; // xmm0_8
unsigned int v12; // eax
double v13; // xmm2_8
double v14; // xmm3_8
double v15; // xmm2_8
int v16; // eax
double v17; // xmm4_8
double v18; // xmm1_8
int v19; // ebx
double v20; // xmm3_8
__int64 v21; // xmm2_8
double v22; // [rsp+0h] [rbp-40h]
double cosx; // [rsp+18h] [rbp-28h] BYREF
double sinx[4]; // [rsp+20h] [rbp-20h] BYREF

v2 = 1.0 - *(double *)(a1 + 64);
if ( *(_DWORD *)a1 == 1 )
{
v16 = az_clock_mod(360LL, 1LL, a2);
glRotated((double)(2 * v16), 0.0, 0.0, 1.0);
glBegin(6LL);
glColor4f(1.0, 1.0, 1.0, 0.0);
glVertex2f(0.0);
switch ( (unsigned int)az_clock_mod(6LL, 1LL, a2) )
{
case 0u:
glColor4f(1.0, 0.5, 0.5, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 1u:
glColor4f(1.0, 1.0, 0.5, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 2u:
glColor4f(0.5, 1.0, 0.5, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 3u:
glColor4f(0.5, 1.0, 1.0, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 4u:
glColor4f(0.5, 0.5, 1.0, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
case 5u:
glColor4f(1.0, 0.5, 1.0, COERCE_DOUBLE((unsigned __int64)LODWORD(v2)));
break;
default:
break;
}
v17 = *(double *)(a1 + 48);
v18 = 0.0;
v19 = 0;
v20 = *(double *)&LC2;
v21 = LC1;
while ( 1 )
{
++v19;
glVertex2d(v20 * (*(double *)&v21 * v17), v18 * (*(double *)&v21 * v17));
if ( v19 == 11 )
break;
v21 = LC0;
if ( (v19 & 1) == 0 )
v21 = LC1;
v22 = *(double *)(a1 + 48);
sincos((double)(36 * v19) * 0.0174532925199433, sinx, &cosx);
v20 = cosx;
v18 = sinx[0];
v17 = v22;
}
result = ((__int64 (*)(void))glEnd)();
}
else
{
if ( *(_DWORD *)a1 == 2 )
{
v10 = az_clock_mod(360LL, 1LL, a2);
v11 = sin((double)(2 * v10) * 0.0174532925199433);
glRotated(v11 * 120.0, 0.0, 0.0, 1.0);
glBegin(5LL);
v12 = az_target_color(a1);
glColor4ub((unsigned __int8)v12, BYTE1(v12), BYTE2(v12), (unsigned __int8)(int)(float)((float)HIBYTE(v12) * v2));
v13 = *(double *)(a1 + 48);
v14 = 5.0 * v13;
v15 = v13 * 8.0;
*(float *)&v14 = v14;
*(float *)&v15 = v15;
glVertex2f(v15);
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v14)));
glVertex2f(COERCE_DOUBLE(LODWORD(v15) ^ (unsigned __int64)(unsigned int)LC10));
glVertex2f(COERCE_DOUBLE((unsigned int)LC10 ^ (unsigned __int64)LODWORD(v14)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)(LODWORD(v15) ^ (unsigned int)LC10)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)((unsigned int)LC10 ^ LODWORD(v14))));
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v15)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v14)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v15)));
*(_QWORD *)&v7 = LODWORD(v14);
*(_QWORD *)&v8 = LODWORD(v14);
}
else
{
v3 = az_clock_mod(360LL, 1LL, a2);
v4 = sin((double)(2 * v3) * 0.0174532925199433);
glRotated(v4 * 120.0, 0.0, 0.0, 1.0);
glBegin(6LL);
glColor4f(1.0, 1.0, 1.0, 0.0);
glVertex2f(0.0);
v5 = az_target_color(a1);
glColor4ub((unsigned __int8)v5, BYTE1(v5), BYTE2(v5), (unsigned __int8)(int)(float)((float)HIBYTE(v5) * v2));
v6 = 8.0 * *(double *)(a1 + 48);
*(float *)&v6 = v6;
glVertex2f(v6);
glVertex2f(COERCE_DOUBLE(LODWORD(v6) ^ (unsigned __int64)LC10));
glVertex2f(COERCE_DOUBLE((unsigned __int64)(LODWORD(v6) ^ (unsigned int)LC10)));
glVertex2f(COERCE_DOUBLE((unsigned __int64)LODWORD(v6)));
*(_QWORD *)&v7 = LODWORD(v6);
*(_QWORD *)&v8 = LODWORD(v6);
}
glVertex2f(v8);
result = glEnd(v8, v7);
}
return result;
}

original_code:
static void draw_target(const az_target_t *target, az_clock_t clock) {
  const GLfloat alpha = 1.0 - target->invisibility;
  if (target->kind == AZ_TARG_BONUS) {
    glRotated(2 * az_clock_mod(360, 1, clock), 0, 0, 1);
    glBegin(0x0006); {
      glColor4f(1, 1, 1, 0);
      glVertex2f(0, 0);
      switch (az_clock_mod(6, 1, clock)) {
        case 0: glColor4f(1.0, 0.5, 0.5, alpha); break;
        case 1: glColor4f(1.0, 1.0, 0.5, alpha); break;
        case 2: glColor4f(0.5, 1.0, 0.5, alpha); break;
        case 3: glColor4f(0.5, 1.0, 1.0, alpha); break;
        case 4: glColor4f(0.5, 0.5, 1.0, alpha); break;
        case 5: glColor4f(1.0, 0.5, 1.0, alpha); break;
      }
      for (int i = 0; i <= 10; ++i) {
        const double radius = target->presence *
          (i % 2 ? 10 + 2 : 10 - 2);
        const double theta = ((double)(i * 36) * 0.017453292519943295);
        glVertex2d(radius * cos(theta), radius * sin(theta));
      }
    } glEnd();
  } else if (target->kind == AZ_TARG_FAKE) {
    glRotated(120 * sin(((double)(2 * az_clock_mod(360, 1, clock)) * 0.017453292519943295)), 0, 0, 1);
    glBegin(0x0005); {
      const az_color_t color = az_target_color(target);
      glColor4ub(color.r, color.g, color.b, alpha * color.a);
      const GLfloat inner = 5.0 * target->presence;
      const GLfloat outer = 8.0 * target->presence;
      glVertex2f(outer, outer); glVertex2f(inner, inner);
      glVertex2f(-outer, outer); glVertex2f(-inner, inner);
      glVertex2f(-outer, -outer); glVertex2f(-inner, -inner);
      glVertex2f(outer, -outer); glVertex2f(inner, -inner);
      glVertex2f(outer, outer); glVertex2f(inner, inner);
    } glEnd();
  } else {
    glRotated(120 * sin(((double)(2 * az_clock_mod(360, 1, clock)) * 0.017453292519943295)), 0, 0, 1);
    glBegin(0x0006); {
      glColor4f(1, 1, 1, 0);
      glVertex2f(0, 0);
      const az_color_t color = az_target_color(target);
      glColor4ub(color.r, color.g, color.b, alpha * color.a);
      const GLfloat side = 8.0 * target->presence;
      glVertex2f(side, side); glVertex2f(-side, side);
      glVertex2f(-side, -side); glVertex2f(side, -side);
      glVertex2f(side, side);
    } glEnd();
  }
}

canonical_original_code:
static void draw_target(struct az_target_t *target, unsigned long clock) {
  float alpha = 1.0 - target->invisibility;
  if (target->kind == AZ_TARG_BONUS) {
    glRotated(2 * az_clock_mod(360, 1, clock), 0, 0, 1);
    glBegin(0x0006); {
      glColor4f(1, 1, 1, 0);
      glVertex2f(0, 0);
      switch (az_clock_mod(6, 1, clock)) {
        case 0: glColor4f(1.0, 0.5, 0.5, alpha); break;
        case 1: glColor4f(1.0, 1.0, 0.5, alpha); break;
        case 2: glColor4f(0.5, 1.0, 0.5, alpha); break;
        case 3: glColor4f(0.5, 1.0, 1.0, alpha); break;
        case 4: glColor4f(0.5, 0.5, 1.0, alpha); break;
        case 5: glColor4f(1.0, 0.5, 1.0, alpha); break;
      }
      for (int i = 0; i <= 10; ++i) {
        double radius = target->presence *
          (i % 2 ? 10 + 2 : 10 - 2);
        double theta = ((double)(i * 36) * 0.017453292519943295);
        glVertex2d(radius * cos(theta), radius * sin(theta));
      }
    } glEnd();
  } else if (target->kind == AZ_TARG_FAKE) {
    glRotated(120 * sin(((double)(2 * az_clock_mod(360, 1, clock)) * 0.017453292519943295)), 0, 0, 1);
    glBegin(0x0005); {
      struct az_color_t color = az_target_color(target);
      glColor4ub(color.r, color.g, color.b, alpha * color.a);
      float inner = 5.0 * target->presence;
      float outer = 8.0 * target->presence;
      glVertex2f(outer, outer); glVertex2f(inner, inner);
      glVertex2f(-outer, outer); glVertex2f(-inner, inner);
      glVertex2f(-outer, -outer); glVertex2f(-inner, -inner);
      glVertex2f(outer, -outer); glVertex2f(inner, -inner);
      glVertex2f(outer, outer); glVertex2f(inner, inner);
    } glEnd();
  } else {
    glRotated(120 * sin(((double)(2 * az_clock_mod(360, 1, clock)) * 0.017453292519943295)), 0, 0, 1);
    glBegin(0x0006); {
      glColor4f(1, 1, 1, 0);
      glVertex2f(0, 0);
      struct az_color_t color = az_target_color(target);
      glColor4ub(color.r, color.g, color.b, alpha * color.a);
      float side = 8.0 * target->presence;
      glVertex2f(side, side); glVertex2f(-side, side);
      glVertex2f(-side, -side); glVertex2f(side, -side);
      glVertex2f(side, side);
    } glEnd();
  }
}

variable_types: struct az_target_t { enum az_target_kind_t { AZ_TARG_NOTHING=0, AZ_TARG_BONUS=1, AZ_TARG_FAKE=2, AZ_TARG_NORMAL=3, AZ_TARG_REBEL=4, AZ_TARG_UNPLANNED=5 } kind; struct az_vector_t { double x; } position; struct az_vector_t velocity; int wave; double presence; _Bool is_invisible; double invisibility; } *

variable_types:
clock
unsigned long

variable_types: alpha float

variable_types: radius double

variable_types: theta double

variable_types:
color
struct az_color_t { unsigned char r; }

variable_types: inner float

variable_types: outer float

variable_types: side float


threadfunc

repo: mdturnerinoz/workcrew

decompiled_code:
void *__fastcall threadfunc(void *a1)
{
unsigned int *v2; // rbp

pthread_mutex_lock(&wq);
while ( *((_DWORD *)&wq + 22) )
{
if ( !*((_QWORD *)&wq + 12) )
{
while ( 1 )
{
pthread_cond_wait((pthread_cond_t *)(unsigned int)((_DWORD)&wq + 40), &wq);
if ( *((_QWORD *)&wq + 12) )
break;
if ( !*((_DWORD *)&wq + 22) )
goto LABEL_5;
}
if ( !*((_DWORD *)&wq + 22) )
break;
}
v2 = (unsigned int *)queue_get((unsigned int)((_DWORD)&wq + 96));
pthread_mutex_unlock(&wq);
if ( debugdetail )
printf("Thread number %d processing job %d\n", *((unsigned int *)a1 + 2), v2[2]);
free(v2);
pthread_mutex_lock(&wq);
}
LABEL_5:
pthread_mutex_unlock(&wq);
pthread_mutex_lock(&cq);
queue_put((unsigned int)((_DWORD)&cq + 96), a1);
pthread_mutex_unlock(&cq);
pthread_cond_signal((pthread_cond_t *)(unsigned int)((_DWORD)&cq + 40));
if ( debugdetail )
printf("thread %d shutting down...\n", *((unsigned int *)a1 + 2));
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func0(void *a1)
{
unsigned int *v2; // rbp

pthread_mutex_lock(&wq);
while ( *((_DWORD *)&wq + 22) )
{
if ( !*((_QWORD *)&wq + 12) )
{
while ( 1 )
{
pthread_cond_wait((pthread_cond_t *)(unsigned int)((_DWORD)&wq + 40), &wq);
if ( *((_QWORD *)&wq + 12) )
break;
if ( !*((_DWORD *)&wq + 22) )
goto LABEL_5;
}
if ( !*((_DWORD *)&wq + 22) )
break;
}
v2 = (unsigned int *)queue_get((unsigned int)((_DWORD)&wq + 96));
pthread_mutex_unlock(&wq);
if ( debugdetail )
printf("Thread number %d processing job %d\n", *((unsigned int *)a1 + 2), v2[2]);
free(v2);
pthread_mutex_lock(&wq);
}
LABEL_5:
pthread_mutex_unlock(&wq);
pthread_mutex_lock(&cq);
queue_put((unsigned int)((_DWORD)&cq + 96), a1);
pthread_mutex_unlock(&cq);
pthread_cond_signal((pthread_cond_t *)(unsigned int)((_DWORD)&cq + 40));
if ( debugdetail )
printf("thread %d shutting down...\n", *((unsigned int *)a1 + 2));
return 0LL;
}

original_code:
void *threadfunc( void *myarg )
{
   wnode *mywork;
   cnode *mynode;
   mynode = ( cnode* )myarg;
   pthread_mutex_lock( &wq.control.mutex );
   while ( wq.control.active )
   {
      while ( wq.work.head == ((void *)0) && wq.control.active )
      {
         pthread_cond_wait( &wq.control.cond, &wq.control.mutex );
      }
      if ( ! wq.control.active )
         break;
      mywork = ( wnode* )queue_get( &wq.work );
      pthread_mutex_unlock( &wq.control.mutex );
      if ( debugdetail )
      {
         printf( "Thread number %d processing job %d\n", mynode->threadnum, mywork->jobnum );
      }
      free( mywork );
      pthread_mutex_lock( &wq.control.mutex );
   }
   pthread_mutex_unlock( &wq.control.mutex );
   pthread_mutex_lock( &cq.control.mutex );
   queue_put( &cq.cleanup, ( node* )mynode );
   pthread_mutex_unlock( &cq.control.mutex );
   pthread_cond_signal( &cq.control.cond );
   if ( debugdetail )
   {
      printf( "thread %d shutting down...\n", mynode->threadnum );
   }
   return ((void *)0);
}

canonical_original_code:
void *threadfunc(void *myarg)
{
   struct work_node *mywork;
   struct cleanup_node *mynode;
   mynode = ( struct cleanup_node * )myarg;
   pthread_mutex_lock( &wq.control.mutex );
   while ( wq.control.active )
   {
      while ( wq.work.head == ((void *)0) && wq.control.active )
      {
         pthread_cond_wait( &wq.control.cond, &wq.control.mutex );
      }
      if ( ! wq.control.active )
         break;
      mywork = ( struct work_node * )queue_get( &wq.work );
      pthread_mutex_unlock( &wq.control.mutex );
      if ( debugdetail )
      {
         printf( "Thread number %d processing job %d\n", mynode->threadnum, mywork->jobnum );
      }
      free( mywork );
      pthread_mutex_lock( &wq.control.mutex );
   }
   pthread_mutex_unlock( &wq.control.mutex );
   pthread_mutex_lock( &cq.control.mutex );
   queue_put( &cq.cleanup, ( struct node * )mynode );
   pthread_mutex_unlock( &cq.control.mutex );
   pthread_cond_signal( &cq.control.cond );
   if ( debugdetail )
   {
      printf( "thread %d shutting down...\n", mynode->threadnum );
   }
   return ((void *)0);
}

variable_types:
myarg
void *

variable_types: struct work_node { struct node { struct node *next; } *next; int jobnum; } *

variable_types: struct cleanup_node { struct node { struct node *next; } *next; int threadnum; unsigned long tid; } *

return_type: void *

user_defined_types: struct work_node { struct node *next; int jobnum; }

user_defined_types: struct cleanup_node { struct node *next; int threadnum; unsigned long tid; }


getparams

decompiled_code:
__int64 __fastcall getparams(int argc, char **argv)
{
int v2; // eax
unsigned int v3; // er12
FILE *v4; // rbp
__int64 result; // rax
const char **v6; // r12
char **v7; // rbx
const char *v8; // rsi
unsigned int v9; // er12
const char *v10; // r8

opterr = 0;
while ( 1 )
{
v2 = getopt(argc, argv, "w:p:s:d");
if ( v2 == -1 )
break;
if ( v2 == 112 )
{
numpackets = atoi(optarg);
}
else if ( v2 > 112 )
{
if ( v2 == 115 )
{
sleeptime = atoi(optarg);
}
else
{
if ( v2 != 119 )
{
LABEL_28:
printf("Aborting at line %d in source file %s\n", 267LL, "workcrew.c");
abort();
}
numworkers = atoi(optarg);
}
}
else
{
if ( v2 == 63 )
{
v3 = optopt;
v4 = stderr;
if ( optopt == 119 || optopt == 112 )
{
fprintf(stderr, "Option -%c requires an argument.\n", (unsigned int)optopt);
result = 1LL;
}
else
{
if ( ((*_ctype_b_loc())[v3] & 0x4000) != 0 )
fprintf(v4, "Unknown option `-%c'.\n", v3);
else
fprintf(v4, "Unknown option character `\\x%x'.\n", v3);
result = 1LL;
}
return result;
}
if ( v2 != 100 )
goto LABEL_28;
debugdetail = 1;
}
}
if ( argc <= optind )
{
v9 = 0;
}
else
{
v6 = (const char **)&argv[optind];
v7 = &(&argv[optind])[(unsigned __int64)(unsigned int)(argc + ~optind) + 1];
do
{
v8 = *v6++;
printf("Non-option argument %s\n", v8);
}
while ( v6 != (const char **)v7 );
v9 = 1;
}
v10 = "on";
if ( !debugdetail )
v10 = "off";
printf(
"\nworkers(-w): %d, packets(-p): %d, sleeptime(-s): %d, debugdetail(-d): %s\n",
(unsigned int)numworkers,
(unsigned int)numpackets,
sleeptime,
v10);
return v9;
}

canonical_decompiled_code:
__int64 __fastcall func1(int argc, char **argv)
{
int v2; // eax
unsigned int v3; // er12
FILE *v4; // rbp
__int64 result; // rax
const char **v6; // r12
char **v7; // rbx
const char *v8; // rsi
unsigned int v9; // er12
const char *v10; // r8

opterr = 0;
while ( 1 )
{
v2 = getopt(argc, argv, "w:p:s:d");
if ( v2 == -1 )
break;
if ( v2 == 112 )
{
numpackets = atoi(optarg);
}
else if ( v2 > 112 )
{
if ( v2 == 115 )
{
sleeptime = atoi(optarg);
}
else
{
if ( v2 != 119 )
{
LABEL_28:
printf("Aborting at line %d in source file %s\n", 267LL, "workcrew.c");
abort();
}
numworkers = atoi(optarg);
}
}
else
{
if ( v2 == 63 )
{
v3 = optopt;
v4 = stderr;
if ( optopt == 119 || optopt == 112 )
{
fprintf(stderr, "Option -%c requires an argument.\n", (unsigned int)optopt);
result = 1LL;
}
else
{
if ( ((*_ctype_b_loc())[v3] & 0x4000) != 0 )
fprintf(v4, "Unknown option `-%c'.\n", v3);
else
fprintf(v4, "Unknown option character `\\x%x'.\n", v3);
result = 1LL;
}
return result;
}
if ( v2 != 100 )
goto LABEL_28;
debugdetail = 1;
}
}
if ( argc <= optind )
{
v9 = 0;
}
else
{
v6 = (const char **)&argv[optind];
v7 = &(&argv[optind])[(unsigned __int64)(unsigned int)(argc + ~optind) + 1];
do
{
v8 = *v6++;
printf("Non-option argument %s\n", v8);
}
while ( v6 != (const char **)v7 );
v9 = 1;
}
v10 = "on";
if ( !debugdetail )
v10 = "off";
printf(
"\nworkers(-w): %d, packets(-p): %d, sleeptime(-s): %d, debugdetail(-d): %s\n",
(unsigned int)numworkers,
(unsigned int)numpackets,
sleeptime,
v10);
return v9;
}

original_code:
int getparams (int argc, char **argv )
{
   int status = 0;
   char *cvalue = ((void *)0);
   int index;
   int c;
   opterr = 0;
   while ((c = getopt (argc, argv, "w:p:s:d")) != -1)
   {
      switch (c)
      {
         case 'd':
            debugdetail = 1;
            break;
         case 'p':
            numpackets = atoi( optarg );
            break;
         case 's':
            sleeptime = atoi( optarg );
            break;
         case 'w':
            numworkers = atoi( optarg );
            break;
         case '?':
            if (optopt == 'w' || optopt == 'p')
               fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (((*__ctype_b_loc ())[(int) ((optopt))] & (unsigned short int) _ISprint))
               fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            else
              fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
           return status = 1;
         default:
           { printf("Aborting at line %d in source file %s\n",267,"workcrew.c"); abort(); };
      }
   }
   for (index = optind; index < argc; index++)
   {
      status = 1;
      printf ("Non-option argument %s\n", argv[index]);
   }
   printf("\nworkers(-w): %d, packets(-p): %d, sleeptime(-s): %d, debugdetail(-d): %s\n", numworkers, numpackets,
                                                                sleeptime, debugdetail ? "on" : "off" );
   return status;
}

canonical_original_code:
int getparams(int argc, char **argv)
{
   int status = 0;
   char *cvalue = ((void *)0);
   int index;
   int c;
   opterr = 0;
   while ((c = getopt (argc, argv, "w:p:s:d")) != -1)
   {
      switch (c)
      {
         case 'd':
            debugdetail = 1;
            break;
         case 'p':
            numpackets = atoi( optarg );
            break;
         case 's':
            sleeptime = atoi( optarg );
            break;
         case 'w':
            numworkers = atoi( optarg );
            break;
         case '?':
            if (optopt == 'w' || optopt == 'p')
               fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (((*__ctype_b_loc ())[(int) ((optopt))] & (unsigned short) _ISprint))
               fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            else
              fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
           return status = 1;
         default:
           { printf("Aborting at line %d in source file %s\n",267,"workcrew.c"); abort(); };
      }
   }
   for (index = optind; index < argc; index++)
   {
      status = 1;
      printf ("Non-option argument %s\n", argv[index]);
   }
   printf("\nworkers(-w): %d, packets(-p): %d, sleeptime(-s): %d, debugdetail(-d): %s\n", numworkers, numpackets,
                                                                sleeptime, debugdetail ? "on" : "off" );
   return status;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: status int

variable_types:
cvalue
char *

variable_types: index int

variable_types: c int


decompiled_code:
int join_threads()
{
__int64 v0; // rbp

for ( ; numthreads; --numthreads )
{
pthread_mutex_lock(&cq);
while ( !*((_QWORD *)&cq + 12) )
pthread_cond_wait((pthread_cond_t *)(unsigned int)((_DWORD)&cq + 40), &cq);
v0 = queue_get((unsigned int)((_DWORD)&cq + 96));
pthread_mutex_unlock(&cq);
pthread_join(*(_QWORD *)(v0 + 16), 0LL);
if ( debugdetail )
printf("joined with thread %d\n", *(unsigned int *)(v0 + 8));
free((void *)v0);
}
return printf("joined %d worker threads...\n", (unsigned int)numworkers);
}

canonical_decompiled_code:
int func2()
{
__int64 v0; // rbp

for ( ; numthreads; --numthreads )
{
pthread_mutex_lock(&cq);
while ( !*((_QWORD *)&cq + 12) )
pthread_cond_wait((pthread_cond_t *)(unsigned int)((_DWORD)&cq + 40), &cq);
v0 = queue_get((unsigned int)((_DWORD)&cq + 96));
pthread_mutex_unlock(&cq);
pthread_join(*(_QWORD *)(v0 + 16), 0LL);
if ( debugdetail )
printf("joined with thread %d\n", *(unsigned int *)(v0 + 8));
free((void *)v0);
}
return printf("joined %d worker threads...\n", (unsigned int)numworkers);
}

original_code:
void join_threads( void )
{
   cnode *curnode;
   while ( numthreads )
   {
      pthread_mutex_lock( &cq.control.mutex );
      while ( cq.cleanup.head == ((void *)0) )
      {
         pthread_cond_wait( &cq.control.cond, &cq.control.mutex );
      }
      curnode = ( cnode* )queue_get( &cq.cleanup );
      pthread_mutex_unlock( &cq.control.mutex );
      pthread_join( curnode->tid, ((void *)0) );
      if ( debugdetail )
      {
         printf( "joined with thread %d\n", curnode->threadnum );
      }
      free( curnode );
      numthreads--;
   }
   printf( "joined %d worker threads...\n", numworkers );
}

canonical_original_code:
void join_threads()
{
   struct cleanup_node *curnode;
   while ( numthreads )
   {
      pthread_mutex_lock( &cq.control.mutex );
      while ( cq.cleanup.head == ((void *)0) )
      {
         pthread_cond_wait( &cq.control.cond, &cq.control.mutex );
      }
      curnode = ( struct cleanup_node * )queue_get( &cq.cleanup );
      pthread_mutex_unlock( &cq.control.mutex );
      pthread_join( curnode->tid, ((void *)0) );
      if ( debugdetail )
      {
         printf( "joined with thread %d\n", curnode->threadnum );
      }
      free( curnode );
      numthreads--;
   }
   printf( "joined %d worker threads...\n", numworkers );
}


decompiled_code:
__int64 create_threads()
{
__int64 v0; // rsi
int v1; // ebx
void *v2; // rax
__int64 result; // rax

v0 = (unsigned int)numworkers;
if ( numworkers <= 0 )
{
LABEL_8:
printf("created %d worker threads\n", v0);
result = 0LL;
}
else
{
v1 = 0;
while ( 1 )
{
v2 = malloc(0x18uLL);
if ( !v2 )
break;
*((_DWORD *)v2 + 2) = v1;
if ( pthread_create((pthread_t *)v2 + 2, 0LL, threadfunc, v2) )
break;
if ( debugdetail )
printf("created thread %d\n", (unsigned int)v1);
v0 = (unsigned int)numworkers;
++v1;
++numthreads;
if ( numworkers <= v1 )
goto LABEL_8;
}
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 v0; // rsi
int v1; // ebx
void *v2; // rax
__int64 result; // rax

v0 = (unsigned int)numworkers;
if ( numworkers <= 0 )
{
LABEL_8:
printf("created %d worker threads\n", v0);
result = 0LL;
}
else
{
v1 = 0;
while ( 1 )
{
v2 = malloc(0x18uLL);
if ( !v2 )
break;
*((_DWORD *)v2 + 2) = v1;
if ( pthread_create((pthread_t *)v2 + 2, 0LL, threadfunc, v2) )
break;
if ( debugdetail )
printf("created thread %d\n", (unsigned int)v1);
v0 = (unsigned int)numworkers;
++v1;
++numthreads;
if ( numworkers <= v1 )
goto LABEL_8;
}
result = 1LL;
}
return result;
}

original_code:
int create_threads( void )
{
   int x;
   cnode *curnode;
   for ( x = 0; x < numworkers; x++ )
   {
      curnode = malloc( sizeof( cnode ) );
      if ( ! curnode )
         return 1;
      curnode->threadnum = x;
      if ( pthread_create( &curnode->tid, ((void *)0), threadfunc, ( void* )curnode ) )
         return 1;
      if ( debugdetail )
      {
         printf( "created thread %d\n", x );
      }
      numthreads++;
   }
   printf("created %d worker threads\n", numworkers );
   return 0;
}

canonical_original_code:
int create_threads()
{
   int x;
   struct cleanup_node *curnode;
   for ( x = 0; x < numworkers; x++ )
   {
      curnode = malloc( sizeof( cnode ) );
      if ( ! curnode )
         return 1;
      curnode->threadnum = x;
      if ( pthread_create( &curnode->tid, ((void *)0), threadfunc, ( void * )curnode ) )
         return 1;
      if ( debugdetail )
      {
         printf( "created thread %d\n", x );
      }
      numthreads++;
   }
   printf("created %d worker threads\n", numworkers );
   return 0;
}

variable_types: x int


decompiled_code:
__int64 initialize_structs()
{
numthreads = 0;
if ( (unsigned int)control_init(&wq) )
{
printf("Aborting at line %d in source file %s\n", 399LL, "workcrew.c");
abort();
}
queue_init((unsigned int)((_DWORD)&wq + 96));
if ( (unsigned int)control_init(&cq) )
{
control_destroy(&wq);
printf("Aborting at line %d in source file %s\n", 404LL, "workcrew.c");
abort();
}
queue_init((unsigned int)((_DWORD)&wq + 96));
return control_activate(&wq);
}

canonical_decompiled_code:
__int64 func4()
{
numthreads = 0;
if ( (unsigned int)control_init(&wq) )
{
printf("Aborting at line %d in source file %s\n", 399LL, "workcrew.c");
abort();
}
queue_init((unsigned int)((_DWORD)&wq + 96));
if ( (unsigned int)control_init(&cq) )
{
control_destroy(&wq);
printf("Aborting at line %d in source file %s\n", 404LL, "workcrew.c");
abort();
}
queue_init((unsigned int)((_DWORD)&wq + 96));
return control_activate(&wq);
}

original_code:
void initialize_structs( void )
{
   numthreads = 0;
   if ( control_init( &wq.control ) )
      { printf("Aborting at line %d in source file %s\n",399,"workcrew.c"); abort(); };
   queue_init( &wq.work );
   if ( control_init( &cq.control ) )
   {
      control_destroy( &wq.control );
      { printf("Aborting at line %d in source file %s\n",404,"workcrew.c"); abort(); };
   }
   queue_init( &wq.work );
   control_activate( &wq.control );
}

canonical_original_code:
void initialize_structs()
{
   numthreads = 0;
   if ( control_init( &wq.control ) )
      { printf("Aborting at line %d in source file %s\n",399,"workcrew.c"); abort(); };
   queue_init( &wq.work );
   if ( control_init( &cq.control ) )
   {
      control_destroy( &wq.control );
      { printf("Aborting at line %d in source file %s\n",404,"workcrew.c"); abort(); };
   }
   queue_init( &wq.work );
   control_activate( &wq.control );
}


decompiled_code:
__int64 cleanup_structs()
{
control_destroy(&cq);
return control_destroy(&wq);
}

canonical_decompiled_code:
__int64 func5()
{
control_destroy(&cq);
return control_destroy(&wq);
}

original_code:
void cleanup_structs( void )
{
   control_destroy( &cq.control );
   control_destroy( &wq.control );
}

canonical_original_code:
void cleanup_structs()
{
   control_destroy( &cq.control );
   control_destroy( &wq.control );
}