decompiled_code:
__int64 __fastcall line_width(_QWORD *a1)
{
return ttf_line_width(*a1);
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1)
{
return ttf_line_width(*a1);
}

original_code:
float line_width(font_t* font, const char* str)
{
 return ttf_line_width(font->ttf, str);
}

canonical_original_code:
float line_width(struct font *font, char *str)
{
 return ttf_line_width(font->ttf, str);
}

return_type: float

user_defined_types: struct ttf_glyph_data { short *px; short *py; unsigned short *endpoints; int *state; unsigned short npoints; unsigned char ncontours; unsigned short aw; short lsb; unsigned short maxwidth; }

user_defined_types: struct ttf_long_hmetrics { unsigned short aw; short lsb; }

user_defined_types: struct ttf_horizontal_header { unsigned int version; short ascender; short descender; short linegap; unsigned short advanceWidthMax; short minLeftSideBearing; short minRightSideBearing; short xMaxExtent; short caretSlopeRise; short caretSlopeRun; short reserved01; short reserved02; short reserved03; short reserved04; short reserved05; short metricDataFormat; unsigned short num_h_metrics; }

user_defined_types: struct ttf_font_header { unsigned int version; unsigned int font_revision; unsigned int checksumAdjust; unsigned int magic; unsigned short flags; unsigned short upem; unsigned char created[8]; unsigned char modified[8]; short xmin; short ymin; short xmax; short ymax; unsigned short mac_style; unsigned short lowest_rec_ppm; short direction_hint; short index_to_loc_format; short glyph_data_format; }

user_defined_types: struct ttf_table_header { unsigned int tag; unsigned int checksum; unsigned int offset; unsigned int length; }

user_defined_types: struct binary_search_tree { struct binary_search_tree *parent; void *value; void *rvalue; void *min; void *max; struct binary_search_tree *left; struct binary_search_tree *right; }

user_defined_types: enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 }

user_defined_types: struct list { struct list *succ; struct list *pred; void *data; }


repo: llbit/cttf

decompiled_code:
float __fastcall line_height(__int64 a1)
{
if ( !a1 )
_assert_fail("font != NULL", "text.c", 0x81u, "line_height");
return (float)(*(__int16 *)(*(_QWORD *)a1 + 62LL) - *(__int16 *)(*(_QWORD *)a1 + 58LL))
/ (float)*(unsigned __int16 *)(*(_QWORD *)a1 + 18LL);
}

canonical_decompiled_code:
float __fastcall func3(__int64 a1)
{
if ( !a1 )
_assert_fail("font != NULL", "text.c", 0x81u, "line_height");
return (float)(*(__int16 *)(*(_QWORD *)a1 + 62LL) - *(__int16 *)(*(_QWORD *)a1 + 58LL))
/ (float)*(unsigned __int16 *)(*(_QWORD *)a1 + 18LL);
}

original_code:
float line_height(font_t* font)
{
 ((font != ((void *)0)) ? (void) (0) : __assert_fail ("font != NULL", "text.c", 129, __extension__ __PRETTY_FUNCTION__));
 return (font->ttf->ymax - font->ttf->ymin) /
  (float) font->ttf->upem;
}

canonical_original_code:
float line_height(struct font *font)
{
 ((font != ((void *)0)) ? (void) (0) : __assert_fail ("font != NULL", "text.c", 129, __extension__ __PRETTY_FUNCTION__));
 return (font->ttf->ymax - font->ttf->ymin) /
  (float) font->ttf->upem;
}

variable_types: struct font { struct ttf { unsigned int *glyph_table; struct ttf_glyph_data { short *px; short *py; unsigned short *endpoints; int *state; unsigned short npoints; unsigned char ncontours; unsigned short aw; short lsb; unsigned short maxwidth; } *glyph_data; unsigned short nglyphs; unsigned short upem; unsigned short ppem; unsigned short resolution; unsigned char interpolation_level; int zerobase; int zerolsb; unsigned int nhmtx; struct ttf_long_hmetrics { unsigned short aw; short lsb; } *plhmtx; short *plsb; short xmin; short ymin; short xmax; short ymax; unsigned int *idx2loc; struct ttf_horizontal_header { unsigned int version; short ascender; short descender; short linegap; unsigned short advanceWidthMax; short minLeftSideBearing; short minRightSideBearing; short xMaxExtent; short caretSlopeRise; short caretSlopeRun; short reserved01; short reserved02; short reserved03; short reserved04; short reserved05; short metricDataFormat; unsigned short num_h_metrics; } *hh; struct ttf_font_header { unsigned int version; unsigned int font_revision; unsigned int checksumAdjust; unsigned int magic; unsigned short flags; unsigned short upem; unsigned char created[8]; unsigned char modified[8]; short xmin; short ymin; short xmax; short ymax; unsigned short mac_style; unsigned short lowest_rec_ppm; short direction_hint; short index_to_loc_format; short glyph_data_format; } *fh; struct ttf_table_header { unsigned int tag; unsigned int checksum; unsigned int offset; unsigned int length; } *cmap; struct ttf_table_header *glyf; struct ttf_table_header *head; struct ttf_table_header *hhea; struct ttf_table_header *hmtx; struct ttf_table_header *loca; struct ttf_table_header *maxp; } *ttf; struct shape { struct vector { float x; float y; } *vec; int nvec; int maxvec; int *seg; int nseg; int maxseg; } **cshape; struct edge_list { int nvert; struct vertex { enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 } vtype; struct vector vec; struct edge { struct vertex *origin; struct face { struct list { struct list *succ; struct list *pred; void *data; } *inner_components; struct edge *outer_component; int is_inside; } *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; } *incident_edge; int flags; int id; } **vertices; struct list *faces; struct list *cycles; struct binary_search_tree { struct binary_search_tree *parent; void *value; void *rvalue; void *min; void *max; struct binary_search_tree *left; struct binary_search_tree *right; } *etree; struct list *edges; } **cedges; } *

user_defined_types: struct font { struct ttf *ttf; struct shape **cshape; struct edge_list **cedges; }

user_defined_types: struct ttf { unsigned int *glyph_table; struct ttf_glyph_data *glyph_data; unsigned short nglyphs; unsigned short upem; unsigned short ppem; unsigned short resolution; unsigned char interpolation_level; int zerobase; int zerolsb; unsigned int nhmtx; struct ttf_long_hmetrics *plhmtx; short *plsb; short xmin; short ymin; short xmax; short ymax; unsigned int *idx2loc; struct ttf_horizontal_header *hh; struct ttf_font_header *fh; struct ttf_table_header *cmap; struct ttf_table_header *glyf; struct ttf_table_header *head; struct ttf_table_header *hhea; struct ttf_table_header *hmtx; struct ttf_table_header *loca; struct ttf_table_header *maxp; }

user_defined_types: struct shape { struct vector *vec; int nvec; int maxvec; int *seg; int nseg; int maxseg; }

user_defined_types: struct edge_list { int nvert; struct vertex **vertices; struct list *faces; struct list *cycles; struct binary_search_tree *etree; struct list *edges; }

user_defined_types: struct vertex { enum vtype vtype; struct vector vec; struct edge *incident_edge; int flags; int id; }

user_defined_types: struct edge { struct vertex *origin; struct face *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; }

user_defined_types: struct face { struct list *inner_components; struct edge *outer_component; int is_inside; }


decompiled_code:
void __fastcall draw_hollow_word(_QWORD *a1, const char *a2)
{
const char *v2; // r12
size_t v3; // rax
int v4; // eax
__int64 v5; // rbp
__int64 v6; // rbx
__int64 v7; // rcx
__int64 v8; // rax
__int64 v9; // rcx
float *v10; // rdx
double v11; // xmm0_8
float v12; // [rsp+8h] [rbp-40h]
float v13; // [rsp+Ch] [rbp-3Ch]
wchar_t pwc[11]; // [rsp+1Ch] [rbp-2Ch] BYREF

if ( !a1 )
_assert_fail("font != NULL", "text.c", 0x8Au, "draw_hollow_word");
v2 = a2;
if ( *a2 )
{
while ( 1 )
{
v3 = _ctype_get_mb_cur_max();
v4 = mbtowc(pwc, v2, v3);
if ( v4 == -1 )
break;
v2 += v4;
font_prepare_chr(a1, pwc[0], 0);
v5 = *(_QWORD *)(a1[1] + 8LL * pwc[0]);
if ( v5 )
{
glBegin(1LL);
if ( *(int *)(v5 + 24) > 0 )
{
v6 = 0LL;
do
{
v7 = *(_QWORD *)(v5 + 16);
v8 = *(int *)(v7 + 8 * v6);
v9 = *(int *)(v7 + 8 * v6++ + 4);
v10 = (float *)(*(_QWORD *)v5 + 8 * v9);
v13 = *v10;
v12 = v10[1];
glVertex3f(*(float *)(*(_QWORD *)v5 + 8 * v8), *(float *)(*(_QWORD *)v5 + 8 * v8 + 4), 0.0);
glVertex3f(v13, v12, 0.0);
}
while ( *(_DWORD *)(v5 + 24) > (int)v6 );
}
glEnd();
v11 = ttf_char_width(*a1, LOWORD(pwc[0]));
glTranslatef(v11, 0.0);
if ( !*v2 )
return;
}
else if ( !*v2 )
{
return;
}
}
}
}

canonical_decompiled_code:
void __fastcall func4(_QWORD *a1, const char *a2)
{
const char *v2; // r12
size_t v3; // rax
int v4; // eax
__int64 v5; // rbp
__int64 v6; // rbx
__int64 v7; // rcx
__int64 v8; // rax
__int64 v9; // rcx
float *v10; // rdx
double v11; // xmm0_8
float v12; // [rsp+8h] [rbp-40h]
float v13; // [rsp+Ch] [rbp-3Ch]
wchar_t pwc[11]; // [rsp+1Ch] [rbp-2Ch] BYREF

if ( !a1 )
_assert_fail("font != NULL", "text.c", 0x8Au, "draw_hollow_word");
v2 = a2;
if ( *a2 )
{
while ( 1 )
{
v3 = _ctype_get_mb_cur_max();
v4 = mbtowc(pwc, v2, v3);
if ( v4 == -1 )
break;
v2 += v4;
func1(a1, pwc[0], 0);
v5 = *(_QWORD *)(a1[1] + 8LL * pwc[0]);
if ( v5 )
{
glBegin(1LL);
if ( *(int *)(v5 + 24) > 0 )
{
v6 = 0LL;
do
{
v7 = *(_QWORD *)(v5 + 16);
v8 = *(int *)(v7 + 8 * v6);
v9 = *(int *)(v7 + 8 * v6++ + 4);
v10 = (float *)(*(_QWORD *)v5 + 8 * v9);
v13 = *v10;
v12 = v10[1];
glVertex3f(*(float *)(*(_QWORD *)v5 + 8 * v8), *(float *)(*(_QWORD *)v5 + 8 * v8 + 4), 0.0);
glVertex3f(v13, v12, 0.0);
}
while ( *(_DWORD *)(v5 + 24) > (int)v6 );
}
glEnd();
v11 = ttf_char_width(*a1, LOWORD(pwc[0]));
glTranslatef(v11, 0.0);
if ( !*v2 )
return;
}
else if ( !*v2 )
{
return;
}
}
}
}

original_code:
void draw_hollow_word(font_t* font, const char* str)
{
 const char* p;
 ((font != ((void *)0)) ? (void) (0) : __assert_fail ("font != NULL", "text.c", 138, __extension__ __PRETTY_FUNCTION__));
 p = str;
 while (*p != '\0') {
  wchar_t wc;
  int n;
  int i;
  shape_t* shape;
  n = mbtowc(&wc, p, (__ctype_get_mb_cur_max ()));
  if (n == -1) break;
  else p += n;
  font_prepare_chr(font, wc, 0);
  shape = font->cshape[wc];
  if (!shape) continue;
  glBegin(0x0001);
  for (i = 0; i < shape->nseg; ++i) {
   float x1 = shape->vec[shape->seg[i*2]].x;
   float y1 = shape->vec[shape->seg[i*2]].y;
   float x2 = shape->vec[shape->seg[i*2+1]].x;
   float y2 = shape->vec[shape->seg[i*2+1]].y;
   glVertex3f(x1, y1, 0);
   glVertex3f(x2, y2, 0);
  }
  glEnd();
  glTranslatef(ttf_char_width(font->ttf, wc), 0, 0);
 }
}

canonical_original_code:
void draw_hollow_word(struct font *font, char *str)
{
 char *p;
 ((font != ((void *)0)) ? (void) (0) : __assert_fail ("font != NULL", "text.c", 138, __extension__ __PRETTY_FUNCTION__));
 p = str;
 while (*p != '\0') {
  int wc;
  int n;
  int i;
  struct shape *shape;
  n = mbtowc(&wc, p, (__ctype_get_mb_cur_max ()));
  if (n == -1) break;
  else p += n;
  font_prepare_chr(font, wc, 0);
  shape = font->cshape[wc];
  if (!shape) continue;
  glBegin(0x0001);
  for (i = 0; i < shape->nseg; ++i) {
   float x1 = shape->vec[shape->seg[i*2]].x;
   float y1 = shape->vec[shape->seg[i*2]].y;
   float x2 = shape->vec[shape->seg[i*2+1]].x;
   float y2 = shape->vec[shape->seg[i*2+1]].y;
   glVertex3f(x1, y1, 0);
   glVertex3f(x2, y2, 0);
  }
  glEnd();
  glTranslatef(ttf_char_width(font->ttf, wc), 0, 0);
 }
}

variable_types:
str
char *

variable_types:
p
char *

variable_types: wc int

variable_types: n int

variable_types: i int

variable_types: struct shape { struct vector { float x; float y; } *vec; int nvec; int maxvec; int *seg; int nseg; int maxseg; } *

return_type: void


decompiled_code:
void __fastcall draw_filled_word(_QWORD *a1, const char *a2)
{
const char *v2; // r12
double v3; // xmm0_8
size_t v4; // rax
int v5; // eax
__int64 v6; // rbx
_QWORD *v7; // r14
_QWORD *v8; // rbx
__int64 v9; // rax
_QWORD *v10; // rbp
_QWORD *v11; // r15
wchar_t pwc[15]; // [rsp+Ch] [rbp-3Ch] BYREF

if ( !a1 )
_assert_fail("font != NULL", "text.c", 0xAEu, "draw_filled_word");
v2 = a2;
while ( *v2 )
{
v4 = _ctype_get_mb_cur_max();
v5 = mbtowc(pwc, v2, v4);
if ( v5 == -1 )
break;
v2 += v5;
font_prepare_chr(a1, pwc[0], 1);
v6 = *(_QWORD *)(a1[2] + 8LL * pwc[0]);
if ( v6 )
{
glBegin(4LL);
v7 = *(_QWORD **)(v6 + 16);
if ( v7 )
{
v8 = *(_QWORD **)(v6 + 16);
do
{
v9 = v8[2];
v8 = (_QWORD *)*v8;
v10 = *(_QWORD **)(v9 + 8);
if ( *(_DWORD *)(v9 + 16) && v10 && *(_QWORD **)(*(_QWORD *)(v10[3] + 24LL) + 24LL) == v10 )
{
v11 = *(_QWORD **)(v9 + 8);
glNormal3d(0.0, 0.0, 1.0);
do
{
glVertex3f(*(float *)(*v11 + 4LL), *(float *)(*v11 + 8LL), 0.0);
v11 = (_QWORD *)v11[3];
}
while ( v10 != v11 );
}
}
while ( v7 != v8 );
}
glEnd();
v3 = ttf_char_width(*a1, LOWORD(pwc[0]));
glTranslatef(v3, 0.0);
}
}
}

original_code:
void draw_filled_word(font_t* font, const char* str)
{
 const char* s;
 ((font != ((void *)0)) ? (void) (0) : __assert_fail ("font != NULL", "text.c", 174, __extension__ __PRETTY_FUNCTION__));
 s = str;
 while (*s != '\0') {
  wchar_t wc;
  int n;
  edge_list_t* edge_list;
  list_t* p;
  list_t* h;
  n = mbtowc(&wc, s, (__ctype_get_mb_cur_max ()));
  if (n == -1) break;
  else s += n;
  font_prepare_chr(font, wc, 1);
  edge_list = font->cedges[wc];
  if (!edge_list) continue;
  glBegin(0x0004);
  p = h = edge_list->faces;
  if (p)
  do {
   face_t* face = p->data;
   edge_t* edge = face->outer_component;
   p = p->succ;
   if (!face->is_inside || edge == ((void *)0))
    continue;
   if (edge->succ->succ->succ == edge) {
    edge_t* e = edge;
    glNormal3d(0, 0, 1);
    do {
     glVertex3f(e->origin->vec.x,
       e->origin->vec.y, 0);
     e = e->succ;
    } while (e != edge);
   }
  } while (p != h);
  glEnd();
  glTranslatef(ttf_char_width(font->ttf, wc), 0, 0);
 }
}

canonical_original_code:
void draw_filled_word(struct font *font, char *str)
{
 char *s;
 ((font != ((void *)0)) ? (void) (0) : __assert_fail ("font != NULL", "text.c", 174, __extension__ __PRETTY_FUNCTION__));
 s = str;
 while (*s != '\0') {
  int wc;
  int n;
  struct edge_list *edge_list;
  struct list *p;
  struct list *h;
  n = mbtowc(&wc, s, (__ctype_get_mb_cur_max ()));
  if (n == -1) break;
  else s += n;
  font_prepare_chr(font, wc, 1);
  edge_list = font->cedges[wc];
  if (!edge_list) continue;
  glBegin(0x0004);
  p = h = edge_list->faces;
  if (p)
  do {
   struct face *face = p->data;
   struct edge *edge = face->outer_component;
   p = p->succ;
   if (!face->is_inside || edge == ((void *)0))
    continue;
   if (edge->succ->succ->succ == edge) {
    struct edge *e = edge;
    glNormal3d(0, 0, 1);
    do {
     glVertex3f(e->origin->vec.x,
       e->origin->vec.y, 0);
     e = e->succ;
    } while (e != edge);
   }
  } while (p != h);
  glEnd();
  glTranslatef(ttf_char_width(font->ttf, wc), 0, 0);
 }
}

variable_types:
s
char *

variable_types: struct edge_list { int nvert; struct vertex { enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 } vtype; struct vector { float x; float y; } vec; struct edge { struct vertex *origin; struct face { struct list { struct list *succ; struct list *pred; void *data; } *inner_components; struct edge *outer_component; int is_inside; } *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; } *incident_edge; int flags; int id; } **vertices; struct list *faces; struct list *cycles; struct binary_search_tree { struct binary_search_tree *parent; void *value; void *rvalue; void *min; void *max; struct binary_search_tree *left; struct binary_search_tree *right; } *etree; struct list *edges; } *

variable_types: struct face { struct list { struct list *succ; struct list *pred; void *data; } *inner_components; struct edge { struct vertex { enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 } vtype; struct vector { float x; float y; } vec; struct edge *incident_edge; int flags; int id; } *origin; struct face *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; } *outer_component; int is_inside; } *

variable_types: struct edge { struct vertex { enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 } vtype; struct vector { float x; float y; } vec; struct edge *incident_edge; int flags; int id; } *origin; struct face { struct list { struct list *succ; struct list *pred; void *data; } *inner_components; struct edge *outer_component; int is_inside; } *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; } *


original_code:
void draw_3d_word(font_t* font, const char* str, float depth)
{
 const char* s;
 ((font != ((void *)0)) ? (void) (0) : __assert_fail ("font != NULL", "text.c", 227, __extension__ __PRETTY_FUNCTION__));
 s = str;
 while (*s != '\0') {
  wchar_t wc;
  int n;
  list_t* p;
  list_t* h;
  edge_list_t* edge_list;
  shape_t* shape;
  int i;
  n = mbtowc(&wc, s, (__ctype_get_mb_cur_max ()));
  if (n == -1) break;
  else s += n;
  font_prepare_chr(font, wc, 1);
  edge_list = font->cedges[wc];
  shape = font->cshape[wc];
  if (!edge_list) continue;
  glBegin(0x0004);
  p = h = edge_list->faces;
  if (p)
  do {
   face_t* face = p->data;
   edge_t* edge = face->outer_component;
   edge_t* e;
   p = p->succ;
   if (!face->is_inside || edge == ((void *)0))
    continue;
   glNormal3d(0, 0, 1);
   e = edge;
   do {
    glVertex3f(e->origin->vec.x,
      e->origin->vec.y, 0);
    e = e->succ;
   } while (e != edge);
  } while (p != h);
  glEnd();
  glBegin(0x0007);
  for (i = 0; i < shape->nseg; ++i) {
   float x1 = shape->vec[shape->seg[i*2]].x;
   float y1 = shape->vec[shape->seg[i*2]].y;
   float x2 = shape->vec[shape->seg[i*2+1]].x;
   float y2 = shape->vec[shape->seg[i*2+1]].y;
   glNormal3d(-depth*(y2-y1), depth*(x2-x1), 0);
   glVertex3f(x1, y1, 0);
   glVertex3f(x2, y2, 0);
   glVertex3f(x2, y2, -depth);
   glVertex3f(x1, y1, -depth);
  }
  glEnd();
  glTranslatef(ttf_char_width(font->ttf, wc), 0, 0);
 }
}

canonical_original_code:
void draw_3d_word(struct font *font, char *str, float depth)
{
 char *s;
 ((font != ((void *)0)) ? (void) (0) : __assert_fail ("font != NULL", "text.c", 227, __extension__ __PRETTY_FUNCTION__));
 s = str;
 while (*s != '\0') {
  int wc;
  int n;
  struct list *p;
  struct list *h;
  struct edge_list *edge_list;
  struct shape *shape;
  int i;
  n = mbtowc(&wc, s, (__ctype_get_mb_cur_max ()));
  if (n == -1) break;
  else s += n;
  font_prepare_chr(font, wc, 1);
  edge_list = font->cedges[wc];
  shape = font->cshape[wc];
  if (!edge_list) continue;
  glBegin(0x0004);
  p = h = edge_list->faces;
  if (p)
  do {
   struct face *face = p->data;
   struct edge *edge = face->outer_component;
   struct edge *e;
   p = p->succ;
   if (!face->is_inside || edge == ((void *)0))
    continue;
   glNormal3d(0, 0, 1);
   e = edge;
   do {
    glVertex3f(e->origin->vec.x,
      e->origin->vec.y, 0);
    e = e->succ;
   } while (e != edge);
  } while (p != h);
  glEnd();
  glBegin(0x0007);
  for (i = 0; i < shape->nseg; ++i) {
   float x1 = shape->vec[shape->seg[i*2]].x;
   float y1 = shape->vec[shape->seg[i*2]].y;
   float x2 = shape->vec[shape->seg[i*2+1]].x;
   float y2 = shape->vec[shape->seg[i*2+1]].y;
   glNormal3d(-depth*(y2-y1), depth*(x2-x1), 0);
   glVertex3f(x1, y1, 0);
   glVertex3f(x2, y2, 0);
   glVertex3f(x2, y2, -depth);
   glVertex3f(x1, y1, -depth);
  }
  glEnd();
  glTranslatef(ttf_char_width(font->ttf, wc), 0, 0);
 }
}

variable_types: depth float

variable_types: struct list { struct list *succ; struct list *pred; void *data; } *


decompiled_code:
__int64 __fastcall draw_hollow_str(_QWORD *a1, const char *a2)
{
glMatrixMode(5888LL);
glPushMatrix();
draw_hollow_word(a1, a2);
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func7(_QWORD *a1, const char *a2)
{
glMatrixMode(5888LL);
glPushMatrix();
func4(a1, a2);
return glPopMatrix();
}

original_code:
void draw_hollow_str(font_t* font, const char* str)
{
 glMatrixMode(0x1700);
 glPushMatrix();
 draw_hollow_word(font, str);
 glPopMatrix();
}

canonical_original_code:
void draw_hollow_str(struct font *font, char *str)
{
 glMatrixMode(0x1700);
 glPushMatrix();
 draw_hollow_word(font, str);
 glPopMatrix();
}


decompiled_code:
__int64 __fastcall draw_filled_str(_QWORD *a1, const char *a2)
{
glMatrixMode(5888LL);
glPushMatrix();
draw_filled_word(a1, a2);
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func8(_QWORD *a1, const char *a2)
{
glMatrixMode(5888LL);
glPushMatrix();
func5(a1, a2);
return glPopMatrix();
}

original_code:
void draw_filled_str(font_t* font, const char* str)
{
 glMatrixMode(0x1700);
 glPushMatrix();
 draw_filled_word(font, str);
 glPopMatrix();
}

canonical_original_code:
void draw_filled_str(struct font *font, char *str)
{
 glMatrixMode(0x1700);
 glPushMatrix();
 draw_filled_word(font, str);
 glPopMatrix();
}


decompiled_code:
__int64 __fastcall draw_3d_str(_QWORD *a1, const char *a2, float a3)
{
glMatrixMode(5888LL);
glPushMatrix();
draw_3d_word(a1, a2, a3);
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func9(_QWORD *a1, const char *a2, float a3)
{
glMatrixMode(5888LL);
glPushMatrix();
func6(a1, a2, a3);
return glPopMatrix();
}

original_code:
void draw_3d_str(font_t* font, const char* str, float depth)
{
 glMatrixMode(0x1700);
 glPushMatrix();
 draw_3d_word(font, str, depth);
 glPopMatrix();
}

canonical_original_code:
void draw_3d_str(struct font *font, char *str, float depth)
{
 glMatrixMode(0x1700);
 glPushMatrix();
 draw_3d_word(font, str, depth);
 glPopMatrix();
}


decompiled_code:
__int64 __fastcall draw_hollow_text(_QWORD *a1, __int64 a2, double a3)
{
int v4; // er13
int v5; // ebp
__int64 v6; // r14
__int64 v7; // r15
__int64 v8; // rbp
const char *v9; // rsi
double v10; // xmm1_8
__int64 v12; // [rsp+8h] [rbp-40h]

glMatrixMode(5888LL);
glPushMatrix();
if ( *(_DWORD *)(a2 + 32) )
{
v4 = 1;
do
{
v5 = v4;
v12 = v4;
v6 = 4LL * v4;
v4 += *(_DWORD *)(*(_QWORD *)(a2 + 16) + v6);
glPushMatrix();
if ( v5 < v4 )
{
v7 = 8 * v12 - 8;
v8 = 8 * (v12 + (unsigned int)(v4 + ~v5));
while ( 1 )
{
v9 = *(const char **)(*(_QWORD *)(a2 + 8) + v7);
v7 += 8LL;
draw_hollow_word(a1, v9);
if ( v7 == v8 )
break;
*(_QWORD *)&a3 = *(unsigned int *)(*(_QWORD *)(a2 + 24) + v6);
glTranslatef(a3, 0.0);
}
}
glPopMatrix();
*(float *)&a3 = line_height((__int64)a1);
*(_QWORD *)&v10 = *(_QWORD *)&a3 ^ LC9;
HIDWORD(a3) = 0;
glTranslatef(0.0, v10);
}
while ( *(_DWORD *)(a2 + 32) >= (unsigned int)v4 );
}
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func10(_QWORD *a1, __int64 a2, double a3)
{
int v4; // er13
int v5; // ebp
__int64 v6; // r14
__int64 v7; // r15
__int64 v8; // rbp
const char *v9; // rsi
double v10; // xmm1_8
__int64 v12; // [rsp+8h] [rbp-40h]

glMatrixMode(5888LL);
glPushMatrix();
if ( *(_DWORD *)(a2 + 32) )
{
v4 = 1;
do
{
v5 = v4;
v12 = v4;
v6 = 4LL * v4;
v4 += *(_DWORD *)(*(_QWORD *)(a2 + 16) + v6);
glPushMatrix();
if ( v5 < v4 )
{
v7 = 8 * v12 - 8;
v8 = 8 * (v12 + (unsigned int)(v4 + ~v5));
while ( 1 )
{
v9 = *(const char **)(*(_QWORD *)(a2 + 8) + v7);
v7 += 8LL;
func4(a1, v9);
if ( v7 == v8 )
break;
*(_QWORD *)&a3 = *(unsigned int *)(*(_QWORD *)(a2 + 24) + v6);
glTranslatef(a3, 0.0);
}
}
glPopMatrix();
*(float *)&a3 = func3((__int64)a1);
*(_QWORD *)&v10 = *(_QWORD *)&a3 ^ LC9;
HIDWORD(a3) = 0;
glTranslatef(0.0, v10);
}
while ( *(_DWORD *)(a2 + 32) >= (unsigned int)v4 );
}
return glPopMatrix();
}

original_code:
void draw_hollow_text(font_t* font, paragraph_t* text)
{
 int i;
 glMatrixMode(0x1700);
 glPushMatrix();
 for (i = 1; i <= text->nwords; ) {
  int first = 1;
  int j = i;
  int next = i+text->wc[i];
  glPushMatrix();
  while (j < next) {
   if (!first)
    glTranslatef(text->spw[i], 0, 0);
   draw_hollow_word(font, text->words[j-1]);
   first = 0;
   j = j+1;
  }
  i = next;
  glPopMatrix();
  glTranslatef(0, -line_height(font), 0);
 }
 glPopMatrix();
}

canonical_original_code:
void draw_hollow_text(struct font *font, struct paragraph_t *text)
{
 int i;
 glMatrixMode(0x1700);
 glPushMatrix();
 for (i = 1; i <= text->nwords; ) {
  int first = 1;
  int j = i;
  int next = i+text->wc[i];
  glPushMatrix();
  while (j < next) {
   if (!first)
    glTranslatef(text->spw[i], 0, 0);
   draw_hollow_word(font, text->words[j-1]);
   first = 0;
   j = j+1;
  }
  i = next;
  glPopMatrix();
  glTranslatef(0, -line_height(font), 0);
 }
 glPopMatrix();
}

variable_types: struct paragraph_t { struct ttf *typeface; char **words; int *wc; float *spw; unsigned int nwords; unsigned int max; float mincwidth; float spacewidth; } *

variable_types: first int

variable_types: j int

variable_types: next int


decompiled_code:
__int64 __fastcall draw_filled_text(_QWORD *a1, __int64 a2, double a3)
{
int v4; // er13
int v5; // ebp
__int64 v6; // r14
__int64 v7; // r15
__int64 v8; // rbp
const char *v9; // rsi
double v10; // xmm1_8
__int64 v12; // [rsp+8h] [rbp-40h]

glMatrixMode(5888LL);
glPushMatrix();
if ( *(_DWORD *)(a2 + 32) )
{
v4 = 1;
do
{
v5 = v4;
v12 = v4;
v6 = 4LL * v4;
v4 += *(_DWORD *)(*(_QWORD *)(a2 + 16) + v6);
glPushMatrix();
if ( v5 < v4 )
{
v7 = 8 * v12 - 8;
v8 = 8 * (v12 + (unsigned int)(v4 + ~v5));
while ( 1 )
{
v9 = *(const char **)(*(_QWORD *)(a2 + 8) + v7);
v7 += 8LL;
draw_filled_word(a1, v9);
if ( v7 == v8 )
break;
*(_QWORD *)&a3 = *(unsigned int *)(*(_QWORD *)(a2 + 24) + v6);
glTranslatef(a3, 0.0);
}
}
glPopMatrix();
*(float *)&a3 = line_height((__int64)a1);
*(_QWORD *)&v10 = *(_QWORD *)&a3 ^ LC9;
HIDWORD(a3) = 0;
glTranslatef(0.0, v10);
}
while ( *(_DWORD *)(a2 + 32) >= (unsigned int)v4 );
}
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func11(_QWORD *a1, __int64 a2, double a3)
{
int v4; // er13
int v5; // ebp
__int64 v6; // r14
__int64 v7; // r15
__int64 v8; // rbp
const char *v9; // rsi
double v10; // xmm1_8
__int64 v12; // [rsp+8h] [rbp-40h]

glMatrixMode(5888LL);
glPushMatrix();
if ( *(_DWORD *)(a2 + 32) )
{
v4 = 1;
do
{
v5 = v4;
v12 = v4;
v6 = 4LL * v4;
v4 += *(_DWORD *)(*(_QWORD *)(a2 + 16) + v6);
glPushMatrix();
if ( v5 < v4 )
{
v7 = 8 * v12 - 8;
v8 = 8 * (v12 + (unsigned int)(v4 + ~v5));
while ( 1 )
{
v9 = *(const char **)(*(_QWORD *)(a2 + 8) + v7);
v7 += 8LL;
func5(a1, v9);
if ( v7 == v8 )
break;
*(_QWORD *)&a3 = *(unsigned int *)(*(_QWORD *)(a2 + 24) + v6);
glTranslatef(a3, 0.0);
}
}
glPopMatrix();
*(float *)&a3 = func3((__int64)a1);
*(_QWORD *)&v10 = *(_QWORD *)&a3 ^ LC9;
HIDWORD(a3) = 0;
glTranslatef(0.0, v10);
}
while ( *(_DWORD *)(a2 + 32) >= (unsigned int)v4 );
}
return glPopMatrix();
}

original_code:
void draw_filled_text(font_t* font, paragraph_t* text)
{
 int i;
 glMatrixMode(0x1700);
 glPushMatrix();
 for (i = 1; i <= text->nwords; ) {
  int first = 1;
  int j = i;
  int next = i+text->wc[i];
  glPushMatrix();
  while (j < next) {
   if (!first)
    glTranslatef(text->spw[i], 0, 0);
   draw_filled_word(font, text->words[j-1]);
   first = 0;
   j = j+1;
  }
  i = next;
  glPopMatrix();
  glTranslatef(0, -line_height(font), 0);
 }
 glPopMatrix();
}

canonical_original_code:
void draw_filled_text(struct font *font, struct paragraph_t *text)
{
 int i;
 glMatrixMode(0x1700);
 glPushMatrix();
 for (i = 1; i <= text->nwords; ) {
  int first = 1;
  int j = i;
  int next = i+text->wc[i];
  glPushMatrix();
  while (j < next) {
   if (!first)
    glTranslatef(text->spw[i], 0, 0);
   draw_filled_word(font, text->words[j-1]);
   first = 0;
   j = j+1;
  }
  i = next;
  glPopMatrix();
  glTranslatef(0, -line_height(font), 0);
 }
 glPopMatrix();
}

variable_types: struct font { struct ttf { unsigned int *glyph_table; struct ttf_glyph_data { short *px; short *py; unsigned short *endpoints; int *state; unsigned short npoints; unsigned char ncontours; unsigned short aw; short lsb; unsigned short maxwidth; } *glyph_data; unsigned short nglyphs; unsigned short upem; unsigned short ppem; unsigned short resolution; unsigned char interpolation_level; int zerobase; int zerolsb; unsigned int nhmtx; struct ttf_long_hmetrics { unsigned short aw; short lsb; } *plhmtx; short *plsb; short xmin; short ymin; short xmax; short ymax; unsigned int *idx2loc; struct ttf_horizontal_header { unsigned int version; short ascender; short descender; short linegap; unsigned short advanceWidthMax; short minLeftSideBearing; short minRightSideBearing; short xMaxExtent; short caretSlopeRise; short caretSlopeRun; short reserved01; short reserved02; short reserved03; short reserved04; short reserved05; short metricDataFormat; unsigned short num_h_metrics; } *hh; struct ttf_font_header { unsigned int version; unsigned int font_revision; unsigned int checksumAdjust; unsigned int magic; unsigned short flags; unsigned short upem; unsigned char created[8]; unsigned char modified[8]; short xmin; short ymin; short xmax; short ymax; unsigned short mac_style; unsigned short lowest_rec_ppm; short direction_hint; short index_to_loc_format; short glyph_data_format; } *fh; struct ttf_table_header { unsigned int tag; unsigned int checksum; unsigned int offset; unsigned int length; } *cmap; struct ttf_table_header *glyf; struct ttf_table_header *head; struct ttf_table_header *hhea; struct ttf_table_header *hmtx; struct ttf_table_header *loca; struct ttf_table_header *maxp; } *ttf; struct shape { struct vector { float x; float y; } *vec; int nvec; int maxvec; int *seg; int nseg; int maxseg; } **cshape; struct edge_list { int nvert; struct vertex { enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 } vtype; struct vector vec; struct edge { struct vertex *origin; struct face { struct list { struct list *succ; struct list *pred; void *data; } *inner_components; struct edge *outer_component; int is_inside; } *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; } *incident_edge; int flags; int id; } **vertices; struct list *faces; struct list *cycles; struct binary_search_tree { struct binary_search_tree *parent; void *value; void *rvalue; void *min; void *max; struct binary_search_tree *left; struct binary_search_tree *right; } *etree; struct list *edges; } **cedges; } *

user_defined_types: struct paragraph_t { struct ttf *typeface; char **words; int *wc; float *spw; unsigned int nwords; unsigned int max; float mincwidth; float spacewidth; }


decompiled_code:
__int64 __fastcall draw_3d_text(_QWORD *a1, __int64 a2, double a3)
{
int v4; // er13
int v5; // ebp
__int64 v6; // r14
__int64 v7; // r15
__int64 v8; // rbp
const char *v9; // rsi
double v10; // xmm1_8
float v12; // [rsp+0h] [rbp-48h]
__int64 v13; // [rsp+8h] [rbp-40h]

v12 = *(float *)&a3;
glMatrixMode(5888LL);
glPushMatrix();
if ( *(_DWORD *)(a2 + 32) )
{
v4 = 1;
do
{
v5 = v4;
v13 = v4;
v6 = 4LL * v4;
v4 += *(_DWORD *)(*(_QWORD *)(a2 + 16) + v6);
glPushMatrix();
if ( v5 < v4 )
{
v7 = 8 * v13 - 8;
v8 = 8 * (v13 + (unsigned int)(v4 + ~v5));
while ( 1 )
{
*(_QWORD *)&a3 = LODWORD(v12);
v9 = *(const char **)(*(_QWORD *)(a2 + 8) + v7);
v7 += 8LL;
draw_3d_word(a1, v9, v12);
if ( v7 == v8 )
break;
glTranslatef(COERCE_DOUBLE((unsigned __int64)*(_DWORD *)(*(_QWORD *)(a2 + 24) + v6)), 0.0);
}
}
glPopMatrix();
*(float *)&a3 = line_height((__int64)a1);
*(_QWORD *)&v10 = *(_QWORD *)&a3 ^ LC9;
HIDWORD(a3) = 0;
glTranslatef(0.0, v10);
}
while ( *(_DWORD *)(a2 + 32) >= (unsigned int)v4 );
}
return glPopMatrix();
}

canonical_decompiled_code:
__int64 __fastcall func12(_QWORD *a1, __int64 a2, double a3)
{
int v4; // er13
int v5; // ebp
__int64 v6; // r14
__int64 v7; // r15
__int64 v8; // rbp
const char *v9; // rsi
double v10; // xmm1_8
float v12; // [rsp+0h] [rbp-48h]
__int64 v13; // [rsp+8h] [rbp-40h]

v12 = *(float *)&a3;
glMatrixMode(5888LL);
glPushMatrix();
if ( *(_DWORD *)(a2 + 32) )
{
v4 = 1;
do
{
v5 = v4;
v13 = v4;
v6 = 4LL * v4;
v4 += *(_DWORD *)(*(_QWORD *)(a2 + 16) + v6);
glPushMatrix();
if ( v5 < v4 )
{
v7 = 8 * v13 - 8;
v8 = 8 * (v13 + (unsigned int)(v4 + ~v5));
while ( 1 )
{
*(_QWORD *)&a3 = LODWORD(v12);
v9 = *(const char **)(*(_QWORD *)(a2 + 8) + v7);
v7 += 8LL;
func6(a1, v9, v12);
if ( v7 == v8 )
break;
glTranslatef(COERCE_DOUBLE((unsigned __int64)*(_DWORD *)(*(_QWORD *)(a2 + 24) + v6)), 0.0);
}
}
glPopMatrix();
*(float *)&a3 = func3((__int64)a1);
*(_QWORD *)&v10 = *(_QWORD *)&a3 ^ LC9;
HIDWORD(a3) = 0;
glTranslatef(0.0, v10);
}
while ( *(_DWORD *)(a2 + 32) >= (unsigned int)v4 );
}
return glPopMatrix();
}

original_code:
void draw_3d_text(font_t* font, paragraph_t* text, float depth)
{
 int i;
 glMatrixMode(0x1700);
 glPushMatrix();
 for (i = 1; i <= text->nwords; ) {
  int first = 1;
  int j = i;
  int next = i+text->wc[i];
  glPushMatrix();
  while (j < next) {
   if (!first)
    glTranslatef(text->spw[i], 0, 0);
   draw_3d_word(font, text->words[j-1], depth);
   first = 0;
   j = j+1;
  }
  i = next;
  glPopMatrix();
  glTranslatef(0, -line_height(font), 0);
 }
 glPopMatrix();
}

canonical_original_code:
void draw_3d_text(struct font *font, struct paragraph_t *text, float depth)
{
 int i;
 glMatrixMode(0x1700);
 glPushMatrix();
 for (i = 1; i <= text->nwords; ) {
  int first = 1;
  int j = i;
  int next = i+text->wc[i];
  glPushMatrix();
  while (j < next) {
   if (!first)
    glTranslatef(text->spw[i], 0, 0);
   draw_3d_word(font, text->words[j-1], depth);
   first = 0;
   j = j+1;
  }
  i = next;
  glPopMatrix();
  glTranslatef(0, -line_height(font), 0);
 }
 glPopMatrix();
}


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

result = 0LL;
if ( !*(_QWORD *)(a1 + 40) )
result = *(_QWORD *)(a1 + 48) == 0LL;
return result;
}

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

result = 0LL;
if ( !*(_QWORD *)(a1 + 40) )
result = *(_QWORD *)(a1 + 48) == 0LL;
return result;
}

original_code:
static int is_leaf(bstree_t* tree)
{
 return tree->left == ((void *)0) && tree->right == ((void *)0);
}

canonical_original_code:
static int is_leaf(struct binary_search_tree *tree)
{
 return tree->left == ((void *)0) && tree->right == ((void *)0);
}

variable_types: struct binary_search_tree { struct binary_search_tree *parent; void *value; void *rvalue; void *min; void *max; struct binary_search_tree *left; struct binary_search_tree *right; } *

return_type: int


decompiled_code:
__int64 __fastcall bstree_size(__int64 a1)
{
__int64 v1; // rbx
unsigned int v2; // er12
int v3; // eax

if ( !a1 )
return 0LL;
v1 = a1;
v2 = 0;
while ( !is_leaf(v1) )
{
v3 = bstree_size(*(_QWORD *)(v1 + 40));
v1 = *(_QWORD *)(v1 + 48);
v2 += v3;
if ( !v1 )
return v2;
}
return v2 + 1;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
__int64 v1; // rbx
unsigned int v2; // er12
int v3; // eax

if ( !a1 )
return 0LL;
v1 = a1;
v2 = 0;
while ( !func0(v1) )
{
v3 = func3(*(_QWORD *)(v1 + 40));
v1 = *(_QWORD *)(v1 + 48);
v2 += v3;
if ( !v1 )
return v2;
}
return v2 + 1;
}

original_code:
unsigned bstree_size(bstree_t* tree)
{
 if (tree == ((void *)0))
  return 0;
 else if (is_leaf(tree))
  return 1;
 else
  return bstree_size(tree->left) + bstree_size(tree->right);
}

canonical_original_code:
unsigned int bstree_size(struct binary_search_tree *tree)
{
 if (tree == ((void *)0))
  return 0;
 else if (is_leaf(tree))
  return 1;
 else
  return bstree_size(tree->left) + bstree_size(tree->right);
}

return_type: unsigned int


decompiled_code:
__int64 __fastcall bstree_find_left(_QWORD *a1, __int64 a2, unsigned int (__fastcall *a3)(__int64, _QWORD))
{
_QWORD *v4; // rbx
__int64 v5; // rax

v4 = a1;
if ( !a1 )
return 0LL;
while ( !is_leaf((__int64)v4) )
{
while ( 1 )
{
v5 = v4[6];
if ( !v5 )
{
v4 = (_QWORD *)v4[5];
goto LABEL_8;
}
if ( v4[5] )
break;
v4 = (_QWORD *)v4[6];
if ( is_leaf(v5) )
return v4[1];
}
if ( a3(a2, v4[1]) || a3(a2, v4[2]) )
v4 = (_QWORD *)v4[5];
else
v4 = (_QWORD *)v4[6];
LABEL_8:
if ( !v4 )
return 0LL;
}
return v4[1];
}

canonical_decompiled_code:
__int64 __fastcall func6(_QWORD *a1, __int64 a2, unsigned int (__fastcall *a3)(__int64, _QWORD))
{
_QWORD *v4; // rbx
__int64 v5; // rax

v4 = a1;
if ( !a1 )
return 0LL;
while ( !func0((__int64)v4) )
{
while ( 1 )
{
v5 = v4[6];
if ( !v5 )
{
v4 = (_QWORD *)v4[5];
goto LABEL_8;
}
if ( v4[5] )
break;
v4 = (_QWORD *)v4[6];
if ( func0(v5) )
return v4[1];
}
if ( a3(a2, v4[1]) || a3(a2, v4[2]) )
v4 = (_QWORD *)v4[5];
else
v4 = (_QWORD *)v4[6];
LABEL_8:
if ( !v4 )
return 0LL;
}
return v4[1];
}

original_code:
void* bstree_find_left(bstree_t* tree, void* v, comparator_t cmp)
{
 if (tree == ((void *)0)) return ((void *)0);
 if (is_leaf(tree))
  return tree->value;
 else if (tree->right == ((void *)0))
  return bstree_find_left(tree->left, v, cmp);
 else if (tree->left == ((void *)0))
  return bstree_find_left(tree->right, v, cmp);
 else if (cmp(v, tree->value) || cmp(v, tree->rvalue))
  return bstree_find_left(tree->left, v, cmp);
 else
  return bstree_find_left(tree->right, v, cmp);
}

canonical_original_code:
void *bstree_find_left(struct binary_search_tree *tree, void *v, int (*cmp)(void *, void *))
{
 if (tree == ((void *)0)) return ((void *)0);
 if (is_leaf(tree))
  return tree->value;
 else if (tree->right == ((void *)0))
  return bstree_find_left(tree->left, v, cmp);
 else if (tree->left == ((void *)0))
  return bstree_find_left(tree->right, v, cmp);
 else if (cmp(v, tree->value) || cmp(v, tree->rvalue))
  return bstree_find_left(tree->left, v, cmp);
 else
  return bstree_find_left(tree->right, v, cmp);
}

variable_types:
v
void *

variable_types:
cmp
int (*)(void *, void *)

return_type: void *


decompiled_code:
__int64 __fastcall bstree_find_right(_QWORD *a1, __int64 a2, unsigned int (__fastcall *a3)(__int64, _QWORD))
{
_QWORD *v4; // rbx
__int64 v5; // rax

v4 = a1;
if ( !a1 )
return 0LL;
while ( !is_leaf((__int64)v4) )
{
while ( 1 )
{
v5 = v4[6];
if ( !v5 )
{
v4 = (_QWORD *)v4[5];
goto LABEL_8;
}
if ( v4[5] )
break;
v4 = (_QWORD *)v4[6];
if ( is_leaf(v5) )
return v4[1];
}
if ( a3(a2, v4[1]) || a3(a2, v4[2]) )
v4 = (_QWORD *)v4[6];
else
v4 = (_QWORD *)v4[5];
LABEL_8:
if ( !v4 )
return 0LL;
}
return v4[1];
}

canonical_decompiled_code:
__int64 __fastcall func7(_QWORD *a1, __int64 a2, unsigned int (__fastcall *a3)(__int64, _QWORD))
{
_QWORD *v4; // rbx
__int64 v5; // rax

v4 = a1;
if ( !a1 )
return 0LL;
while ( !func0((__int64)v4) )
{
while ( 1 )
{
v5 = v4[6];
if ( !v5 )
{
v4 = (_QWORD *)v4[5];
goto LABEL_8;
}
if ( v4[5] )
break;
v4 = (_QWORD *)v4[6];
if ( func0(v5) )
return v4[1];
}
if ( a3(a2, v4[1]) || a3(a2, v4[2]) )
v4 = (_QWORD *)v4[6];
else
v4 = (_QWORD *)v4[5];
LABEL_8:
if ( !v4 )
return 0LL;
}
return v4[1];
}

original_code:
void* bstree_find_right(bstree_t* tree, void* v, comparator_t cmp)
{
 if (tree == ((void *)0)) return ((void *)0);
 if (is_leaf(tree))
  return tree->value;
 else if (tree->right == ((void *)0))
  return bstree_find_right(tree->left, v, cmp);
 else if (tree->left == ((void *)0))
  return bstree_find_right(tree->right, v, cmp);
 else if (cmp(v, tree->value) || cmp(v, tree->rvalue))
  return bstree_find_right(tree->right, v, cmp);
 else
  return bstree_find_right(tree->left, v, cmp);
}

canonical_original_code:
void *bstree_find_right(struct binary_search_tree *tree, void *v, int (*cmp)(void *, void *))
{
 if (tree == ((void *)0)) return ((void *)0);
 if (is_leaf(tree))
  return tree->value;
 else if (tree->right == ((void *)0))
  return bstree_find_right(tree->left, v, cmp);
 else if (tree->left == ((void *)0))
  return bstree_find_right(tree->right, v, cmp);
 else if (cmp(v, tree->value) || cmp(v, tree->rvalue))
  return bstree_find_right(tree->right, v, cmp);
 else
  return bstree_find_right(tree->left, v, cmp);
}


decompiled_code:
void __fastcall bstree_find_all(_QWORD *a1, __int64 a2, unsigned int (__fastcall *a3)(__int64, _QWORD), __int64 a4)
{
_QWORD *v6; // rbx
__int64 v7; // rdi

if ( a1 )
{
v6 = a1;
while ( !is_leaf((__int64)v6) )
{
v7 = v6[5];
if ( v7 )
bstree_find_all(v7, a2, a3, a4);
v6 = (_QWORD *)v6[6];
if ( !v6 )
return;
}
if ( a3(a2, v6[1]) )
list_add(a4, v6[1]);
}
}

canonical_decompiled_code:
void __fastcall func8(_QWORD *a1, __int64 a2, unsigned int (__fastcall *a3)(__int64, _QWORD), __int64 a4)
{
_QWORD *v6; // rbx
__int64 v7; // rdi

if ( a1 )
{
v6 = a1;
while ( !func0((__int64)v6) )
{
v7 = v6[5];
if ( v7 )
func8(v7, a2, a3, a4);
v6 = (_QWORD *)v6[6];
if ( !v6 )
return;
}
if ( a3(a2, v6[1]) )
list_add(a4, v6[1]);
}
}

original_code:
void bstree_find_all(bstree_t* tree, void* v, comparator_t cmp, list_t** list)
{
 if (tree == ((void *)0)) return;
 if (is_leaf(tree)) {
  if (cmp(v, tree->value))
   list_add(list, tree->value);
 } else {
  if (tree->left != ((void *)0))
   bstree_find_all(tree->left, v, cmp, list);
  if (tree->right != ((void *)0))
   bstree_find_all(tree->right, v, cmp, list);
 }
}

canonical_original_code:
void bstree_find_all(struct binary_search_tree *tree, void *v, int (*cmp)(void *, void *), struct list **list)
{
 if (tree == ((void *)0)) return;
 if (is_leaf(tree)) {
  if (cmp(v, tree->value))
   list_add(list, tree->value);
 } else {
  if (tree->left != ((void *)0))
   bstree_find_all(tree->left, v, cmp, list);
  if (tree->right != ((void *)0))
   bstree_find_all(tree->right, v, cmp, list);
 }
}

variable_types: struct list { struct list *succ; struct list *pred; void *data; } **


decompiled_code:
void __fastcall free_bstree(void **a1)
{
char *v2; // rdi

if ( !a1 )
_assert_fail("tree != NULL", "bstree.c", 0x112u, "free_bstree");
v2 = (char *)*a1;
if ( v2 )
{
free_bstree(v2 + 40);
free_bstree((char *)*a1 + 48);
free(*a1);
*a1 = 0LL;
}
}

canonical_decompiled_code:
void __fastcall func9(void **a1)
{
char *v2; // rdi

if ( !a1 )
_assert_fail("tree != NULL", "bstree.c", 0x112u, "free_bstree");
v2 = (char *)*a1;
if ( v2 )
{
func9(v2 + 40);
func9((char *)*a1 + 48);
free(*a1);
*a1 = 0LL;
}
}

original_code:
void free_bstree(bstree_t** tree)
{
 ((tree != ((void *)0)) ? (void) (0) : __assert_fail ("tree != NULL", "bstree.c", 274, __extension__ __PRETTY_FUNCTION__));
 if (*tree == ((void *)0)) return;
 free_bstree(&(*tree)->left);
 free_bstree(&(*tree)->right);
 free(*tree);
 *tree = ((void *)0);
}

canonical_original_code:
void free_bstree(struct binary_search_tree **tree)
{
 ((tree != ((void *)0)) ? (void) (0) : __assert_fail ("tree != NULL", "bstree.c", 274, __extension__ __PRETTY_FUNCTION__));
 if (*tree == ((void *)0)) return;
 free_bstree(&(*tree)->left);
 free_bstree(&(*tree)->right);
 free(*tree);
 *tree = ((void *)0);
}

variable_types: struct binary_search_tree { struct binary_search_tree *parent; void *value; void *rvalue; void *min; void *max; struct binary_search_tree *left; struct binary_search_tree *right; } **


decompiled_code:
__int64 __fastcall set_remove(void **a1)
{
_QWORD *v2; // rdi
__int64 v3; // r12
_QWORD *v4; // rax
_QWORD *v5; // rbp

if ( !a1 )
_assert_fail("set != NULL", "treeset.c", 0x4Bu, "set_remove");
v2 = *a1;
if ( !v2 )
return 0LL;
v3 = v2[2];
if ( *v2 )
{
v4 = set_rem_rightmost((_QWORD **)v2);
LABEL_5:
v5 = v4;
*v4 = *(_QWORD *)*a1;
v4[1] = *((_QWORD *)*a1 + 1);
free(*a1);
*a1 = v5;
return v3;
}
if ( v2[1] )
{
v4 = set_rem_leftmost(v2 + 1);
goto LABEL_5;
}
free(v2);
*a1 = 0LL;
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func0(void **a1)
{
_QWORD *v2; // rdi
__int64 v3; // r12
_QWORD *v4; // rax
_QWORD *v5; // rbp

if ( !a1 )
_assert_fail("set != NULL", "treeset.c", 0x4Bu, "set_remove");
v2 = *a1;
if ( !v2 )
return 0LL;
v3 = v2[2];
if ( *v2 )
{
v4 = set_rem_rightmost((_QWORD **)v2);
LABEL_5:
v5 = v4;
*v4 = *(_QWORD *)*a1;
v4[1] = *((_QWORD *)*a1 + 1);
free(*a1);
*a1 = v5;
return v3;
}
if ( v2[1] )
{
v4 = set_rem_leftmost(v2 + 1);
goto LABEL_5;
}
free(v2);
*a1 = 0LL;
return v3;
}

original_code:
void* set_remove(set_t** set)
{
 void* data;
 ((set != ((void *)0)) ? (void) (0) : __assert_fail ("set != NULL", "treeset.c", 75, __extension__ __PRETTY_FUNCTION__));
 if (*set == ((void *)0)) return ((void *)0);
 data = (*set)->data;
 if ((*set)->left != ((void *)0)) {
  set_t* s = set_rem_rightmost(&(*set)->left);
  s->left = (*set)->left;
  s->right = (*set)->right;
  free(*set);
  *set = s;
 } else if ((*set)->right != ((void *)0)) {
  set_t* s = set_rem_leftmost(&(*set)->right);
  s->left = (*set)->left;
  s->right = (*set)->right;
  free(*set);
  *set = s;
 } else {
  free(*set);
  *set = ((void *)0);
 }
 return data;
}

canonical_original_code:
void *set_remove(struct set **set)
{
 void *data;
 ((set != ((void *)0)) ? (void) (0) : __assert_fail ("set != NULL", "treeset.c", 75, __extension__ __PRETTY_FUNCTION__));
 if (*set == ((void *)0)) return ((void *)0);
 data = (*set)->data;
 if ((*set)->left != ((void *)0)) {
  struct set *s = set_rem_rightmost(&(*set)->left);
  s->left = (*set)->left;
  s->right = (*set)->right;
  free(*set);
  *set = s;
 } else if ((*set)->right != ((void *)0)) {
  struct set *s = set_rem_leftmost(&(*set)->right);
  s->left = (*set)->left;
  s->right = (*set)->right;
  free(*set);
  *set = s;
 } else {
  free(*set);
  *set = ((void *)0);
 }
 return data;
}

variable_types: struct set { struct set *left; struct set *right; void *data; } **

variable_types:
data
void *


decompiled_code:
__int64 __fastcall free_set(__int64 **a1)
{
__int64 *v2; // rdi
__int64 result; // rax
int v4; // ebx
__int64 v5; // [rsp+0h] [rbp-18h] BYREF
__int64 v6; // [rsp+8h] [rbp-10h] BYREF

if ( !a1 )
_assert_fail("set != NULL", "treeset.c", 0x73u, "free_set");
v2 = *a1;
result = 0LL;
if ( v2 )
{
v5 = *v2;
v6 = v2[1];
free(v2);
*a1 = 0LL;
v4 = free_set(&v5) + 1;
result = v4 + (unsigned int)free_set(&v6);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 **a1)
{
__int64 *v2; // rdi
__int64 result; // rax
int v4; // ebx
__int64 v5; // [rsp+0h] [rbp-18h] BYREF
__int64 v6; // [rsp+8h] [rbp-10h] BYREF

if ( !a1 )
_assert_fail("set != NULL", "treeset.c", 0x73u, "free_set");
v2 = *a1;
result = 0LL;
if ( v2 )
{
v5 = *v2;
v6 = v2[1];
free(v2);
*a1 = 0LL;
v4 = func2(&v5) + 1;
result = v4 + (unsigned int)func2(&v6);
}
return result;
}

original_code:
int free_set(set_t** set)
{
 set_t* left;
 set_t* right;
 int n;
 ((set != ((void *)0)) ? (void) (0) : __assert_fail ("set != NULL", "treeset.c", 115, __extension__ __PRETTY_FUNCTION__));
 if (*set == ((void *)0)) return 0;
 n = 1;
 left = (*set)->left;
 right = (*set)->right;
 free(*set);
 *set = ((void *)0);
 n += free_set(&left);
 n += free_set(&right);
 return n;
}

canonical_original_code:
int free_set(struct set **set)
{
 struct set *left;
 struct set *right;
 int n;
 ((set != ((void *)0)) ? (void) (0) : __assert_fail ("set != NULL", "treeset.c", 115, __extension__ __PRETTY_FUNCTION__));
 if (*set == ((void *)0)) return 0;
 n = 1;
 left = (*set)->left;
 right = (*set)->right;
 free(*set);
 *set = ((void *)0);
 n += free_set(&left);
 n += free_set(&right);
 return n;
}

variable_types: struct set { struct set *left; struct set *right; void *data; } *

variable_types: n int


decompiled_code:
__int64 __fastcall set_contains(_QWORD *a1, unsigned __int64 a2)
{
_QWORD *v2; // rax

while ( 1 )
{
if ( !a1 )
return 0LL;
if ( a1[2] == a2 )
break;
v2 = (_QWORD *)*a1;
if ( a1[2] <= a2 )
v2 = (_QWORD *)a1[1];
a1 = v2;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(_QWORD *a1, unsigned __int64 a2)
{
_QWORD *v2; // rax

while ( 1 )
{
if ( !a1 )
return 0LL;
if ( a1[2] == a2 )
break;
v2 = (_QWORD *)*a1;
if ( a1[2] <= a2 )
v2 = (_QWORD *)a1[1];
a1 = v2;
}
return 1LL;
}

original_code:
int set_contains(set_t* set, void* data)
{
 if (set == ((void *)0))
  return 0;
 else if (set->data == data)
  return 1;
 else if (set->data > data)
  return set_contains(set->left, data);
 else
  return set_contains(set->right, data);
}

canonical_original_code:
int set_contains(struct set *set, void *data)
{
 if (set == ((void *)0))
  return 0;
 else if (set->data == data)
  return 1;
 else if (set->data > data)
  return set_contains(set->left, data);
 else
  return set_contains(set->right, data);
}

user_defined_types: struct set { struct set *left; struct set *right; void *data; }


decompiled_code:
__int64 __fastcall stack_pop(__int64 **a1)
{
__int64 *v2; // rdi
__int64 v3; // r12
__int64 *v4; // rbp

if ( !a1 )
_assert_fail("stack != NULL", "stack.c", 0x2Cu, "stack_pop");
v2 = *a1;
if ( !v2 )
_assert_fail("*stack != NULL", "stack.c", 0x2Du, "stack_pop");
v3 = *v2;
v4 = (__int64 *)v2[1];
free(v2);
*a1 = v4;
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 **a1)
{
__int64 *v2; // rdi
__int64 v3; // r12
__int64 *v4; // rbp

if ( !a1 )
_assert_fail("stack != NULL", "stack.c", 0x2Cu, "stack_pop");
v2 = *a1;
if ( !v2 )
_assert_fail("*stack != NULL", "stack.c", 0x2Du, "stack_pop");
v3 = *v2;
v4 = (__int64 *)v2[1];
free(v2);
*a1 = v4;
return v3;
}

original_code:
void* stack_pop(stack_t** stack)
{
 void* data;
 stack_t* next;
 ((stack != ((void *)0)) ? (void) (0) : __assert_fail ("stack != NULL", "stack.c", 44, __extension__ __PRETTY_FUNCTION__));
 ((*stack != ((void *)0)) ? (void) (0) : __assert_fail ("*stack != NULL", "stack.c", 45, __extension__ __PRETTY_FUNCTION__));
 data = (*stack)->data;
 next = (*stack)->next;
 free(*stack);
 *stack = next;
 return data;
}

canonical_original_code:
void *stack_pop(struct stack **stack)
{
 void *data;
 struct stack *next;
 ((stack != ((void *)0)) ? (void) (0) : __assert_fail ("stack != NULL", "stack.c", 44, __extension__ __PRETTY_FUNCTION__));
 ((*stack != ((void *)0)) ? (void) (0) : __assert_fail ("*stack != NULL", "stack.c", 45, __extension__ __PRETTY_FUNCTION__));
 data = (*stack)->data;
 next = (*stack)->next;
 free(*stack);
 *stack = next;
 return data;
}

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


decompiled_code:
__int64 __fastcall stack_peek(__int64 a1)
{
if ( !a1 )
_assert_fail("stack != NULL", "stack.c", 0x38u, "stack_peek");
return *(_QWORD *)a1;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
if ( !a1 )
_assert_fail("stack != NULL", "stack.c", 0x38u, "stack_peek");
return *(_QWORD *)a1;
}

original_code:
void* stack_peek(stack_t* stack)
{
 ((stack != ((void *)0)) ? (void) (0) : __assert_fail ("stack != NULL", "stack.c", 56, __extension__ __PRETTY_FUNCTION__));
 return stack->data;
}

canonical_original_code:
void *stack_peek(struct stack *stack)
{
 ((stack != ((void *)0)) ? (void) (0) : __assert_fail ("stack != NULL", "stack.c", 56, __extension__ __PRETTY_FUNCTION__));
 return stack->data;
}

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


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

if ( !a1 )
_assert_fail("stack != NULL", "stack.c", 0x3Fu, "free_stack");
v2 = *a1;
if ( v2 )
{
do
{
*a1 = (_QWORD *)v2[1];
free(v2);
v2 = *a1;
}
while ( *a1 );
}
}

canonical_decompiled_code:
void __fastcall func2(_QWORD **a1)
{
_QWORD *v2; // rdi

if ( !a1 )
_assert_fail("stack != NULL", "stack.c", 0x3Fu, "free_stack");
v2 = *a1;
if ( v2 )
{
do
{
*a1 = (_QWORD *)v2[1];
free(v2);
v2 = *a1;
}
while ( *a1 );
}
}

original_code:
void free_stack(stack_t** stack)
{
 ((stack != ((void *)0)) ? (void) (0) : __assert_fail ("stack != NULL", "stack.c", 63, __extension__ __PRETTY_FUNCTION__));
 while (*stack != ((void *)0)) {
  stack_t* p = *stack;
  *stack = p->next;
  free(p);
 }
}

canonical_original_code:
void free_stack(struct stack **stack)
{
 ((stack != ((void *)0)) ? (void) (0) : __assert_fail ("stack != NULL", "stack.c", 63, __extension__ __PRETTY_FUNCTION__));
 while (*stack != ((void *)0)) {
  struct stack *p = *stack;
  *stack = p->next;
  free(p);
 }
}

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


original_code:
void render_shape(shape_t* shape)
{
 int i;
 glBegin(0x0001);
 for (i = 0; i < shape->nseg; ++i) {
  int n;
  int m;
  n = shape->seg[i*2];
  m = shape->seg[i*2+1];
  glVertex3f(shape->vec[n].x, shape->vec[n].y, 0.f);
  glVertex3f(shape->vec[m].x, shape->vec[m].y, 0.f);
 }
 glEnd();
}

canonical_original_code:
void render_shape(struct shape *shape)
{
 int i;
 glBegin(0x0001);
 for (i = 0; i < shape->nseg; ++i) {
  int n;
  int m;
  n = shape->seg[i*2];
  m = shape->seg[i*2+1];
  glVertex3f(shape->vec[n].x, shape->vec[n].y, 0.f);
  glVertex3f(shape->vec[m].x, shape->vec[m].y, 0.f);
 }
 glEnd();
}

variable_types: struct shape { struct vector { float x; float y; } *vec; int nvec; int maxvec; int *seg; int nseg; int maxseg; } *

variable_types: i int

variable_types: m int


decompiled_code:
void __fastcall qsort_work(__int64 a1, unsigned int a2, unsigned int a3)
{
unsigned int v3; // er15
unsigned int v4; // er14
unsigned int v6; // er13
unsigned int v7; // ebx
double v8; // xmm1_8
double v9; // xmm0_8
unsigned int v10; // esi

if ( a3 > a2 )
{
v3 = a3 - 1;
v4 = a2;
if ( a3 - 1 == a2 )
{
LABEL_12:
if ( !(unsigned int)vec_above(*(double *)(*(_QWORD *)(a1 + 8LL * v3) + 4LL)) )
qsort_swap(a1, v3, a3);
}
else
{
while ( 1 )
{
v6 = v4;
v7 = v4;
v8 = *(double *)(*(_QWORD *)(a1 + 8LL * ((v4 + a3) >> 1)) + 4LL);
qsort_swap(a1, (v4 + a3) >> 1, a3);
do
{
while ( 1 )
{
v9 = *(double *)(*(_QWORD *)(a1 + 8LL * v7) + 4LL);
if ( (unsigned int)vec_above(v9) )
break;
if ( a3 <= ++v7 )
goto LABEL_7;
}
v10 = v7++;
qsort_swap(a1, v10, v6++);
}
while ( a3 > v7 );
LABEL_7:
qsort_swap(a1, v6, a3);
if ( v6 > v4 )
qsort_work(a1, v4, v6 - 1, v9, v8);
if ( v6 >= a3 )
break;
v4 = v6 + 1;
if ( v6 + 1 >= a3 )
break;
if ( v4 == v3 )
goto LABEL_12;
}
}
}
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1, unsigned int a2, unsigned int a3)
{
unsigned int v3; // er15
unsigned int v4; // er14
unsigned int v6; // er13
unsigned int v7; // ebx
double v8; // xmm1_8
double v9; // xmm0_8
unsigned int v10; // esi

if ( a3 > a2 )
{
v3 = a3 - 1;
v4 = a2;
if ( a3 - 1 == a2 )
{
LABEL_12:
if ( !(unsigned int)vec_above(*(double *)(*(_QWORD *)(a1 + 8LL * v3) + 4LL)) )
qsort_swap(a1, v3, a3);
}
else
{
while ( 1 )
{
v6 = v4;
v7 = v4;
v8 = *(double *)(*(_QWORD *)(a1 + 8LL * ((v4 + a3) >> 1)) + 4LL);
qsort_swap(a1, (v4 + a3) >> 1, a3);
do
{
while ( 1 )
{
v9 = *(double *)(*(_QWORD *)(a1 + 8LL * v7) + 4LL);
if ( (unsigned int)vec_above(v9) )
break;
if ( a3 <= ++v7 )
goto LABEL_7;
}
v10 = v7++;
qsort_swap(a1, v10, v6++);
}
while ( a3 > v7 );
LABEL_7:
qsort_swap(a1, v6, a3);
if ( v6 > v4 )
func0(a1, v4, v6 - 1, v9, v8);
if ( v6 >= a3 )
break;
v4 = v6 + 1;
if ( v6 + 1 >= a3 )
break;
if ( v4 == v3 )
goto LABEL_12;
}
}
}
}

original_code:
static void qsort_work(vertex_t** a, unsigned start, unsigned end)
{
 unsigned pivot;
 unsigned i;
 vector_t pv;
 unsigned store;
 if (start >= end)
  return;
 else if (start == end - 1) {
  if (!vec_above(a[start]->vec, a[end]->vec))
   qsort_swap(a, start, end);
  return;
 }
 pivot = (start + end) / 2;
 pv = a[pivot]->vec;
 qsort_swap(a, pivot, end);
 store = start;
 for (i = start; i < end; ++i) {
  if (vec_above(a[i]->vec, pv)) {
   qsort_swap(a, i, store);
   store++;
  }
 }
 qsort_swap(a, store, end);
 if (start < store)
  qsort_work(a, start, store-1);
 if (store < end)
  qsort_work(a, store+1, end);
}

canonical_original_code:
static void qsort_work(struct vertex **a, unsigned int start, unsigned int end)
{
 unsigned int pivot;
 unsigned int i;
 struct vector pv;
 unsigned int store;
 if (start >= end)
  return;
 else if (start == end - 1) {
  if (!vec_above(a[start]->vec, a[end]->vec))
   qsort_swap(a, start, end);
  return;
 }
 pivot = (start + end) / 2;
 pv = a[pivot]->vec;
 qsort_swap(a, pivot, end);
 store = start;
 for (i = start; i < end; ++i) {
  if (vec_above(a[i]->vec, pv)) {
   qsort_swap(a, i, store);
   store++;
  }
 }
 qsort_swap(a, store, end);
 if (start < store)
  qsort_work(a, start, store-1);
 if (store < end)
  qsort_work(a, store+1, end);
}

variable_types: struct vertex { enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 } vtype; struct vector { float x; float y; } vec; struct edge { struct vertex *origin; struct face { struct list { struct list *succ; struct list *pred; void *data; } *inner_components; struct edge *outer_component; int is_inside; } *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; } *incident_edge; int flags; int id; } **

variable_types:
start
unsigned int

variable_types:
end
unsigned int

variable_types:
pivot
unsigned int

variable_types:
i
unsigned int

variable_types:
pv
struct vector { float x; float y; }

variable_types:
store
unsigned int


decompiled_code:
void __fastcall qsort_verts(__int64 a1, int a2)
{
qsort_work(a1, 0, a2 - 1);
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1, int a2)
{
func0(a1, 0, a2 - 1);
}

original_code:
void qsort_verts(vertex_t** verts, unsigned n)
{
 qsort_work(verts, 0, n-1);
}

canonical_original_code:
void qsort_verts(struct vertex **verts, unsigned int n)
{
 qsort_work(verts, 0, n-1);
}

variable_types:
n
unsigned int


decompiled_code:
__int64 __fastcall list_remove(void **a1)
{
_QWORD *v2; // rdi
_QWORD *v3; // rbp
__int64 v4; // r12
_QWORD *v5; // rax

if ( !a1 )
_assert_fail("list != NULL", "list.c", 0x34u, "list_remove");
v2 = *a1;
if ( !v2 )
return 0LL;
v3 = (_QWORD *)*v2;
v4 = v2[2];
if ( v2 != (_QWORD *)*v2 )
{
v5 = (_QWORD *)v2[1];
*v5 = v3;
v3[1] = v5;
free(*a1);
*a1 = v3;
return v4;
}
free(v2);
*a1 = 0LL;
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func0(void **a1)
{
_QWORD *v2; // rdi
_QWORD *v3; // rbp
__int64 v4; // r12
_QWORD *v5; // rax

if ( !a1 )
_assert_fail("list != NULL", "list.c", 0x34u, "list_remove");
v2 = *a1;
if ( !v2 )
return 0LL;
v3 = (_QWORD *)*v2;
v4 = v2[2];
if ( v2 != (_QWORD *)*v2 )
{
v5 = (_QWORD *)v2[1];
*v5 = v3;
v3[1] = v5;
free(*a1);
*a1 = v3;
return v4;
}
free(v2);
*a1 = 0LL;
return v4;
}

original_code:
void* list_remove(list_t** list)
{
 void* data;
 ((list != ((void *)0)) ? (void) (0) : __assert_fail ("list != NULL", "list.c", 52, __extension__ __PRETTY_FUNCTION__));
 if (*list == ((void *)0)) return ((void *)0);
 data = (*list)->data;
 if ((*list)->succ == *list) {
  free(*list);
  *list = ((void *)0);
 } else {
  list_t* pred = (*list)->pred;
  list_t* succ = (*list)->succ;
  pred->succ = succ;
  succ->pred = pred;
  free(*list);
  *list = succ;
 }
 return data;
}

canonical_original_code:
void *list_remove(struct list **list)
{
 void *data;
 ((list != ((void *)0)) ? (void) (0) : __assert_fail ("list != NULL", "list.c", 52, __extension__ __PRETTY_FUNCTION__));
 if (*list == ((void *)0)) return ((void *)0);
 data = (*list)->data;
 if ((*list)->succ == *list) {
  free(*list);
  *list = ((void *)0);
 } else {
  struct list *pred = (*list)->pred;
  struct list *succ = (*list)->succ;
  pred->succ = succ;
  succ->pred = pred;
  free(*list);
  *list = succ;
 }
 return data;
}

variable_types: struct list { struct list *succ; struct list *pred; void *data; } **


decompiled_code:
__int64 __fastcall list_remove_item(_QWORD **a1, __int64 a2)
{
__int64 result; // rax
_QWORD *v3; // rbp
__int64 v4; // rax
_QWORD *v5; // rbx
_QWORD *v6; // rax

if ( !a1 )
_assert_fail("list != NULL", "list.c", 0x59u, "list_remove_item");
result = 0LL;
if ( *a1 )
{
v3 = *a1;
while ( 1 )
{
v4 = v3[2];
v5 = v3;
v3 = (_QWORD *)*v3;
if ( v4 == a2 )
break;
if ( v3 == *a1 )
return 0LL;
}
if ( v5 == v3 )
{
free(v3);
*a1 = 0LL;
result = 1LL;
}
else
{
v6 = (_QWORD *)v5[1];
*v6 = v3;
v3[1] = v6;
free(v5);
result = 1LL;
if ( *a1 == v5 )
*a1 = v3;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD **a1, __int64 a2)
{
__int64 result; // rax
_QWORD *v3; // rbp
__int64 v4; // rax
_QWORD *v5; // rbx
_QWORD *v6; // rax

if ( !a1 )
_assert_fail("list != NULL", "list.c", 0x59u, "list_remove_item");
result = 0LL;
if ( *a1 )
{
v3 = *a1;
while ( 1 )
{
v4 = v3[2];
v5 = v3;
v3 = (_QWORD *)*v3;
if ( v4 == a2 )
break;
if ( v3 == *a1 )
return 0LL;
}
if ( v5 == v3 )
{
free(v3);
*a1 = 0LL;
result = 1LL;
}
else
{
v6 = (_QWORD *)v5[1];
*v6 = v3;
v3[1] = v6;
free(v5);
result = 1LL;
if ( *a1 == v5 )
*a1 = v3;
}
}
return result;
}

original_code:
int list_remove_item(list_t** list, void* data)
{
 list_t* p;
 ((list != ((void *)0)) ? (void) (0) : __assert_fail ("list != NULL", "list.c", 89, __extension__ __PRETTY_FUNCTION__));
 p = *list;
 if (p)
 do {
  if (p->data == data) {
   if (p->succ == p) {
    free(p);
    *list = ((void *)0);
    return 1;
   } else {
    list_t* pred = p->pred;
    list_t* succ = p->succ;
    pred->succ = succ;
    succ->pred = pred;
    free(p);
    if (p == *list) {
     *list = succ;
    }
    return 1;
   }
  }
  p = p->succ;
 } while (p != *list);
 return 0;
}

canonical_original_code:
int list_remove_item(struct list **list, void *data)
{
 struct list *p;
 ((list != ((void *)0)) ? (void) (0) : __assert_fail ("list != NULL", "list.c", 89, __extension__ __PRETTY_FUNCTION__));
 p = *list;
 if (p)
 do {
  if (p->data == data) {
   if (p->succ == p) {
    free(p);
    *list = ((void *)0);
    return 1;
   } else {
    struct list *pred = p->pred;
    struct list *succ = p->succ;
    pred->succ = succ;
    succ->pred = pred;
    free(p);
    if (p == *list) {
     *list = succ;
    }
    return 1;
   }
  }
  p = p->succ;
 } while (p != *list);
 return 0;
}

variable_types:
data
void *

variable_types: struct list { struct list *succ; struct list *pred; void *data; } *


decompiled_code:
__int64 __fastcall free_list(_QWORD *a1)
{
_QWORD *v1; // rbp
_QWORD *v3; // rbx
unsigned int v4; // er12
void *v5; // rdi

if ( !a1 )
return 0LL;
v1 = (_QWORD *)*a1;
if ( !*a1 )
return 0LL;
v3 = (_QWORD *)*a1;
v4 = 0;
do
{
v5 = v3;
v3 = (_QWORD *)*v3;
++v4;
free(v5);
}
while ( v1 != v3 );
*a1 = 0LL;
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1)
{
_QWORD *v1; // rbp
_QWORD *v3; // rbx
unsigned int v4; // er12
void *v5; // rdi

if ( !a1 )
return 0LL;
v1 = (_QWORD *)*a1;
if ( !*a1 )
return 0LL;
v3 = (_QWORD *)*a1;
v4 = 0;
do
{
v5 = v3;
v3 = (_QWORD *)*v3;
++v4;
free(v5);
}
while ( v1 != v3 );
*a1 = 0LL;
return v4;
}

original_code:
int free_list(list_t** list)
{
 int count = 0;
 list_t* p;
 list_t* h;
 if (list == ((void *)0)) return 0;
 if (*list == ((void *)0)) return 0;
 p = h = *list;
 do {
  list_t* t = p;
  p = p->succ;
  free(t);
  count++;
 } while (p != h);
 *list = ((void *)0);
 return count;
}

canonical_original_code:
int free_list(struct list **list)
{
 int count = 0;
 struct list *p;
 struct list *h;
 if (list == ((void *)0)) return 0;
 if (*list == ((void *)0)) return 0;
 p = h = *list;
 do {
  struct list *t = p;
  p = p->succ;
  free(t);
  count++;
 } while (p != h);
 *list = ((void *)0);
 return count;
}

variable_types: count int


decompiled_code:
__int64 __fastcall list_length(_QWORD *a1)
{
unsigned int v1; // er8
_QWORD *v2; // rax

v1 = 0;
if ( a1 )
{
v2 = a1;
do
{
v2 = (_QWORD *)*v2;
++v1;
}
while ( a1 != v2 );
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func3(_QWORD *a1)
{
unsigned int v1; // er8
_QWORD *v2; // rax

v1 = 0;
if ( a1 )
{
v2 = a1;
do
{
v2 = (_QWORD *)*v2;
++v1;
}
while ( a1 != v2 );
}
return v1;
}

original_code:
int list_length(list_t* list)
{
 list_t* p = list;
 int len = 0;
 if (p)
 do {
  p = p->succ;
  len += 1;
 } while (p != list);
 return len;
}

canonical_original_code:
int list_length(struct list *list)
{
 struct list *p = list;
 int len = 0;
 if (p)
 do {
  p = p->succ;
  len += 1;
 } while (p != list);
 return len;
}

variable_types: len int


decompiled_code:
__int64 __fastcall list_contains(_QWORD *a1, __int64 a2)
{
__int64 result; // rax
_QWORD *v3; // rax

result = 0LL;
if ( a1 )
{
v3 = a1;
do
{
if ( v3[2] == a2 )
return 1LL;
v3 = (_QWORD *)*v3;
}
while ( a1 != v3 );
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(_QWORD *a1, __int64 a2)
{
__int64 result; // rax
_QWORD *v3; // rax

result = 0LL;
if ( a1 )
{
v3 = a1;
do
{
if ( v3[2] == a2 )
return 1LL;
v3 = (_QWORD *)*v3;
}
while ( a1 != v3 );
result = 0LL;
}
return result;
}

original_code:
int list_contains(list_t* list, void* data)
{
 list_t* p = list;
 if (p)
 do {
  if (p->data == data)
   return 1;
  p = p->succ;
 } while (p != list);
 return 0;
}

canonical_original_code:
int list_contains(struct list *list, void *data)
{
 struct list *p = list;
 if (p)
 do {
  if (p->data == data)
   return 1;
  p = p->succ;
 } while (p != list);
 return 0;
}


original_code:
shape_t* new_shape()
{
 shape_t* obj;
 obj = malloc(sizeof(*obj));
 obj->vec = malloc(sizeof(vector_t)*(12));
 obj->nvec = 0;
 obj->maxvec = (12);
 obj->seg = malloc(sizeof(int)*(12)*2);
 obj->nseg = 0;
 obj->maxseg = (12);
 return obj;
}

canonical_original_code:
struct shape *new_shape()
{
 struct shape *obj;
 obj = malloc(sizeof(*obj));
 obj->vec = malloc(sizeof(vector_t)*(12));
 obj->nvec = 0;
 obj->maxvec = (12);
 obj->seg = malloc(sizeof(int)*(12)*2);
 obj->nseg = 0;
 obj->maxseg = (12);
 return obj;
}

return_type: struct shape { struct vector { float x; float y; } *vec; int nvec; int maxvec; int *seg; int nseg; int maxseg; } *


decompiled_code:
void __fastcall free_shape(__int64 *a1)
{
__int64 v1; // rbp
void *v3; // rdi

if ( !a1 )
_assert_fail("shape != NULL", "shape.c", 0x30u, "free_shape");
v1 = *a1;
if ( *a1 )
{
if ( *(_QWORD *)v1 )
free(*(void **)v1);
v3 = *(void **)(v1 + 16);
if ( v3 )
free(v3);
free((void *)v1);
*a1 = 0LL;
}
}

canonical_decompiled_code:
void __fastcall func1(__int64 *a1)
{
__int64 v1; // rbp
void *v3; // rdi

if ( !a1 )
_assert_fail("shape != NULL", "shape.c", 0x30u, "free_shape");
v1 = *a1;
if ( *a1 )
{
if ( *(_QWORD *)v1 )
free(*(void **)v1);
v3 = *(void **)(v1 + 16);
if ( v3 )
free(v3);
free((void *)v1);
*a1 = 0LL;
}
}

original_code:
void free_shape(shape_t** shape)
{
 shape_t* p;
 ((shape != ((void *)0)) ? (void) (0) : __assert_fail ("shape != NULL", "shape.c", 48, __extension__ __PRETTY_FUNCTION__));
 p = *shape;
 if (!p) return;
 if (p->vec)
  free(p->vec);
 p->vec = ((void *)0);
 if (p->seg)
  free(p->seg);
 p->seg = ((void *)0);
 free(p);
 *shape = ((void *)0);
}

canonical_original_code:
void free_shape(struct shape **shape)
{
 struct shape *p;
 ((shape != ((void *)0)) ? (void) (0) : __assert_fail ("shape != NULL", "shape.c", 48, __extension__ __PRETTY_FUNCTION__));
 p = *shape;
 if (!p) return;
 if (p->vec)
  free(p->vec);
 p->vec = ((void *)0);
 if (p->seg)
  free(p->seg);
 p->seg = ((void *)0);
 free(p);
 *shape = ((void *)0);
}

variable_types: struct shape { struct vector { float x; float y; } *vec; int nvec; int maxvec; int *seg; int nseg; int maxseg; } **


decompiled_code:
__int64 __fastcall shape_add_vec(char **a1, float a2, float a3)
{
int v3; // eax
bool v4; // zf
char *v6; // rdi
__int64 v7; // rdx
__int64 result; // rax
float *v9; // rdx
int v10; // eax
char *v11; // rax

v3 = *((_DWORD *)a1 + 2);
v4 = v3 == *((_DWORD *)a1 + 3);
if ( v3 > *((_DWORD *)a1 + 3) )
_assert_fail("shape->nvec <= shape->maxvec", "shape.c", 0x44u, "shape_add_vec");
v6 = *a1;
if ( v4 )
{
v10 = 2 * v3;
*((_DWORD *)a1 + 3) = v10;
v11 = (char *)realloc(v6, 8LL * v10);
*a1 = v11;
v6 = v11;
v3 = *((_DWORD *)a1 + 2);
}
v7 = v3;
result = (unsigned int)(v3 + 1);
v9 = (float *)&v6[8 * v7];
*v9 = a2;
v9[1] = a3;
*((_DWORD *)a1 + 2) = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(char **a1, float a2, float a3)
{
int v3; // eax
bool v4; // zf
char *v6; // rdi
__int64 v7; // rdx
__int64 result; // rax
float *v9; // rdx
int v10; // eax
char *v11; // rax

v3 = *((_DWORD *)a1 + 2);
v4 = v3 == *((_DWORD *)a1 + 3);
if ( v3 > *((_DWORD *)a1 + 3) )
_assert_fail("shape->nvec <= shape->maxvec", "shape.c", 0x44u, "shape_add_vec");
v6 = *a1;
if ( v4 )
{
v10 = 2 * v3;
*((_DWORD *)a1 + 3) = v10;
v11 = (char *)realloc(v6, 8LL * v10);
*a1 = v11;
v6 = v11;
v3 = *((_DWORD *)a1 + 2);
}
v7 = v3;
result = (unsigned int)(v3 + 1);
v9 = (float *)&v6[8 * v7];
*v9 = a2;
v9[1] = a3;
*((_DWORD *)a1 + 2) = result;
return result;
}

original_code:
void shape_add_vec(shape_t* shape, float x, float y)
{
 ((shape->nvec <= shape->maxvec) ? (void) (0) : __assert_fail ("shape->nvec <= shape->maxvec", "shape.c", 68, __extension__ __PRETTY_FUNCTION__));
 if (shape->nvec == shape->maxvec) {
  shape->maxvec *= 2;
  shape->vec = realloc(shape->vec,
    sizeof(vector_t)*shape->maxvec);
 }
 shape->vec[shape->nvec].x = x;
 shape->vec[shape->nvec].y = y;
 shape->nvec += 1;
}

canonical_original_code:
void shape_add_vec(struct shape *shape, float x, float y)
{
 ((shape->nvec <= shape->maxvec) ? (void) (0) : __assert_fail ("shape->nvec <= shape->maxvec", "shape.c", 68, __extension__ __PRETTY_FUNCTION__));
 if (shape->nvec == shape->maxvec) {
  shape->maxvec *= 2;
  shape->vec = realloc(shape->vec,
    sizeof(vector_t)*shape->maxvec);
 }
 shape->vec[shape->nvec].x = x;
 shape->vec[shape->nvec].y = y;
 shape->nvec += 1;
}

variable_types: struct shape { struct vector { float x; float y; } *vec; int nvec; int maxvec; int *seg; int nseg; int maxseg; } *

variable_types: x float

variable_types: y float


original_code:
void shape_add_seg(shape_t* shape, int n, int m)
{
 ((shape->nseg <= shape->maxseg) ? (void) (0) : __assert_fail ("shape->nseg <= shape->maxseg", "shape.c", 83, __extension__ __PRETTY_FUNCTION__));
 if (shape->nseg == shape->maxseg) {
  shape->maxseg *= 2;
  shape->seg = realloc(shape->seg,
    sizeof(int)*shape->maxseg*2);
 }
 shape->seg[shape->nseg*2] = n;
 shape->seg[shape->nseg*2 + 1] = m;
 shape->nseg += 1;
}

canonical_original_code:
void shape_add_seg(struct shape *shape, int n, int m)
{
 ((shape->nseg <= shape->maxseg) ? (void) (0) : __assert_fail ("shape->nseg <= shape->maxseg", "shape.c", 83, __extension__ __PRETTY_FUNCTION__));
 if (shape->nseg == shape->maxseg) {
  shape->maxseg *= 2;
  shape->seg = realloc(shape->seg,
    sizeof(int)*shape->maxseg*2);
 }
 shape->seg[shape->nseg*2] = n;
 shape->seg[shape->nseg*2 + 1] = m;
 shape->nseg += 1;
}

variable_types: n int

variable_types: m int


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

result = *(unsigned int *)(a1 + 16);
if ( (_DWORD)result )
{
if ( *(_QWORD *)(a1 + 8) )
result = render_component(a1, *(_QWORD **)(a1 + 8));
}
return result;
}

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

result = *(unsigned int *)(a1 + 16);
if ( (_DWORD)result )
{
if ( *(_QWORD *)(a1 + 8) )
result = func6(a1, *(_QWORD **)(a1 + 8));
}
return result;
}

original_code:
void render_face(face_t* face, int color)
{
 if (face->is_inside && face->outer_component)
  render_component(face, face->outer_component, color);
}

canonical_original_code:
void render_face(struct face *face, int color)
{
 if (face->is_inside && face->outer_component)
  render_component(face, face->outer_component, color);
}

variable_types: struct face { struct list { struct list *succ; struct list *pred; void *data; } *inner_components; struct edge { struct vertex { enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 } vtype; struct vector { float x; float y; } vec; struct edge *incident_edge; int flags; int id; } *origin; struct face *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; } *outer_component; int is_inside; } *

variable_types: color int


decompiled_code:
int print_help()
{
puts("usage: 3dtext FONT TEXT [OPTIONS]");
puts(" where FONT is either the filename of a TrueTypeFont or SHAPE file");
puts(" and TEXT is the text to render (if no shape is specified)");
puts(" and OPTIONS is one of");
return puts(" -h show help");
}

canonical_decompiled_code:
int func0()
{
puts("usage: 3dtext FONT TEXT [OPTIONS]");
puts(" where FONT is either the filename of a TrueTypeFont or SHAPE file");
puts(" and TEXT is the text to render (if no shape is specified)");
puts(" and OPTIONS is one of");
return puts(" -h show help");
}

original_code:
void print_help()
{
 printf("usage: 3dtext FONT TEXT [OPTIONS]\n");
 printf("  where FONT is either the filename of a TrueTypeFont or SHAPE file\n");
 printf("  and TEXT is the text to render (if no shape is specified)\n");
 printf("  and OPTIONS is one of\n");
 printf("    -h    show help\n");
}


decompiled_code:
__int64 setup_video()
{
__int64 v1[3]; // [rsp+0h] [rbp-18h] BYREF

screen = SDL_SetVideoMode(700LL, 700LL, 0LL, 1073741827LL);
if ( !screen )
{
fwrite("Failed to set video mode", 1uLL, 0x18uLL, stderr);
exit(1);
}
SDL_ShowCursor(1LL);
glViewport(0LL, 0LL, *(unsigned int *)(screen + 16), *(unsigned int *)(screen + 20));
glMatrixMode(5889LL);
glLoadIdentity();
gluPerspective(60.0, 1.0, 1.0, 7.0);
glEnable(2929LL);
glDisable(2896LL);
glDisable(2912LL);
glDisable(3553LL);
glDisable(3042LL);
glEnable(2884LL);
glBlendFunc(770LL, 771LL);
glPolygonMode(1032LL, 6914LL);
glClearColor(1.0, 1.0, 1.0);
glEnable(2896LL);
glEnable(0x4000LL);
v1[0] = 0LL;
v1[1] = 1065353216LL;
glLightfv(0x4000LL, 4611LL, v1);
return glEnable(2977LL);
}

canonical_decompiled_code:
__int64 func2()
{
__int64 v1[3]; // [rsp+0h] [rbp-18h] BYREF

screen = SDL_SetVideoMode(700LL, 700LL, 0LL, 1073741827LL);
if ( !screen )
{
fwrite("Failed to set video mode", 1uLL, 0x18uLL, stderr);
exit(1);
}
SDL_ShowCursor(1LL);
glViewport(0LL, 0LL, *(unsigned int *)(screen + 16), *(unsigned int *)(screen + 20));
glMatrixMode(5889LL);
glLoadIdentity();
gluPerspective(60.0, 1.0, 1.0, 7.0);
glEnable(2929LL);
glDisable(2896LL);
glDisable(2912LL);
glDisable(3553LL);
glDisable(3042LL);
glEnable(2884LL);
glBlendFunc(770LL, 771LL);
glPolygonMode(1032LL, 6914LL);
glClearColor(1.0, 1.0, 1.0);
glEnable(2896LL);
glEnable(0x4000LL);
v1[0] = 0LL;
v1[1] = 1065353216LL;
glLightfv(0x4000LL, 4611LL, v1);
return glEnable(2977LL);
}

original_code:
void setup_video()
{
 uint32_t flags = 0x00000001 | 0x40000000 | 0x00000002;
 screen = SDL_SetVideoMode((700), (700), 0, flags);
 if (!screen) {
  fprintf(stderr, "Failed to set video mode");
  exit(1);
 }
 SDL_ShowCursor(1);
 glViewport(0, 0, screen->w, screen->h);
 glMatrixMode(0x1701);
 glLoadIdentity();
 gluPerspective(60, 1, 1, 7);
 glEnable(0x0B71);
 glDisable(0x0B50);
 glDisable(0x0B60);
 glDisable(0x0DE1);
 glDisable(0x0BE2);
 glEnable(0x0B44);
 glBlendFunc(0x0302, 0x0303);
 glPolygonMode(0x0408, 0x1B02);
 glClearColor(1, 1, 1, 1);
 GLfloat light[4];
 glEnable(0x0B50);
 glEnable(0x4000);
 light[0] = 0;
 light[1] = 0;
 light[2] = 1;
 light[3] = 0;
 glLightfv(0x4000, 0x1203, light);
 glEnable(0x0BA1);
}

canonical_original_code:
void setup_video()
{
 unsigned int flags = 0x00000001 | 0x40000000 | 0x00000002;
 screen = SDL_SetVideoMode((700), (700), 0, flags);
 if (!screen) {
  fprintf(stderr, "Failed to set video mode");
  exit(1);
 }
 SDL_ShowCursor(1);
 glViewport(0, 0, screen->w, screen->h);
 glMatrixMode(0x1701);
 glLoadIdentity();
 gluPerspective(60, 1, 1, 7);
 glEnable(0x0B71);
 glDisable(0x0B50);
 glDisable(0x0B60);
 glDisable(0x0DE1);
 glDisable(0x0BE2);
 glEnable(0x0B44);
 glBlendFunc(0x0302, 0x0303);
 glPolygonMode(0x0408, 0x1B02);
 glClearColor(1, 1, 1, 1);
 float light[4];
 glEnable(0x0B50);
 glEnable(0x4000);
 light[0] = 0;
 light[1] = 0;
 light[2] = 1;
 light[3] = 0;
 glLightfv(0x4000, 0x1203, light);
 glEnable(0x0BA1);
}

variable_types:
flags
unsigned int

variable_types:
light
float [4]


decompiled_code:
__int64 free_resources()
{
return free_font(&font);
}

canonical_decompiled_code:
__int64 func3()
{
return free_font(&font);
}

original_code:
void free_resources()
{
 free_font(&font);
}


decompiled_code:
__int64 __fastcall render_component(__int64 a1, _QWORD *a2)
{
_QWORD *v2; // rbx

if ( !a2 )
_assert_fail("edge != NULL", "3dtest.c", 0xD0u, "render_component");
glBegin(4LL);
v2 = a2;
glNormal3d(0.0, 0.0, 1.0);
do
{
glVertex3f(*(float *)(*v2 + 4LL), *(float *)(*v2 + 8LL), 0.0);
v2 = (_QWORD *)v2[3];
}
while ( a2 != v2 );
return glEnd();
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, _QWORD *a2)
{
_QWORD *v2; // rbx

if ( !a2 )
_assert_fail("edge != NULL", "3dtest.c", 0xD0u, "render_component");
glBegin(4LL);
v2 = a2;
glNormal3d(0.0, 0.0, 1.0);
do
{
glVertex3f(*(float *)(*v2 + 4LL), *(float *)(*v2 + 8LL), 0.0);
v2 = (_QWORD *)v2[3];
}
while ( a2 != v2 );
return glEnd();
}

original_code:
void render_component(face_t* face, edge_t* edge, int color)
{
 ((edge != ((void *)0)) ? (void) (0) : __assert_fail ("edge != NULL", "3dtest.c", 208, __extension__ __PRETTY_FUNCTION__));
 glBegin(0x0004);
 glNormal3d(0, 0, 1);
 edge_t* p;
 p = edge;
 do {
  edge_t* e = p;
  glVertex3f(e->origin->vec.x,
    e->origin->vec.y, 0);
  p = p->succ;
 } while (p != edge);
 glEnd();
}

canonical_original_code:
void render_component(struct face *face, struct edge *edge, int color)
{
 ((edge != ((void *)0)) ? (void) (0) : __assert_fail ("edge != NULL", "3dtest.c", 208, __extension__ __PRETTY_FUNCTION__));
 glBegin(0x0004);
 glNormal3d(0, 0, 1);
 struct edge *p;
 p = edge;
 do {
  struct edge *e = p;
  glVertex3f(e->origin->vec.x,
    e->origin->vec.y, 0);
  p = p->succ;
 } while (p != edge);
 glEnd();
}

variable_types:
edge
struct edge *

variable_types: struct edge { struct vertex { enum vtype { START_VERTEX=0, END_VERTEX=1, SPLIT_VERTEX=2, MERGE_VERTEX=3, REGULAR_VERTEX=4, UNCLASSIFIED_VERTEX=5 } vtype; struct vector { float x; float y; } vec; struct edge *incident_edge; int flags; int id; } *origin; struct face { struct list { struct list *succ; struct list *pred; void *data; } *inner_components; struct edge *outer_component; int is_inside; } *left_face; struct edge *twin; struct edge *succ; struct edge *pred; struct vertex *helper; int cycle; } *


nextsample

repo: llbit/gravazoid

original_code:
static s16 nextsample() {
 int c;
 int acc;
 if(!player.divtimer) {
  if(!player.ttimer) {
   player.ttimer = 6;
   for(c = 0; c < 4; c++) {
    struct channel *ch = &channel[c];
    u8 note, cmd, trk, hi, lo, ivol = 0xf;
    trk = (song[(c) * 25 + (player.songpos)]);
    note = (song[8 * 25 + (trk) * 32 + (player.trackpos)]);
    cmd = (song[8 * 25 + 42 * 32 + (trk) * 32 + (player.trackpos)]);
    if(note) note += (song[4 * 25 + (c) * 25 + (player.songpos)]);
    *((u32 *) &ch->echonotes[1]) = *((u32 *) &ch->echonotes[0]);
    ch->echonotes[0] = note;
    if(!note && ch->param[CHP_ECHO]) {
     note = ch->echonotes[3];
     ivol = ch->param[CHP_ECHO];
    }
    if(note) {
     ch->freq = pow(1.059463094, note + 60);
     ch->param[CHP_FREQDUP] = 0;
     ch->param[CHP_FREQDDN] = 0;
     ch->param[CHP_VOLDDN] = 0;
     ch->param[CHP_VIBRDEPTH] = 0;
     ch->param[CHP_VOL] = ivol << 4;
     ch->sustaintimer = (shiftm1[(ch->param[CHP_SUSTAIN])]);
    }
    hi = cmd >> 4;
    lo = cmd & 15;
    ch->param[hi] = lo;
    if(0) {
    }
    else if(hi == CHP_VOLDDN) {
     ch->sustaintimer = 0;
    }
    else if(hi == CHP_VIBRDEPTH) {
     ch->vibrphase = 0;
    }
    else if(hi == CHP_VOL) {
     ch->param[CHP_VOL] = lo << 4;
    }
    else if(hi == 0xd) {
     player.drumptr = drums[lo >> 1];
     player.drumvol = lo & 1;
    }
   }
   player.trackpos++;
   player.trackpos %= 32;
   if(!player.trackpos && allow_advance) {
    player.songpos++;
    if(player.songpos == 25) {
     player.songpos = 1;
    }
   }
  }
  player.ttimer--;
  for(c = 0; c < 4; c++) {
   struct channel *ch = &channel[c];
   s16 vol = ch->param[CHP_VOL];
   ch->freq += ch->param[CHP_FREQDUP];
   ch->freq -= ch->param[CHP_FREQDDN];
   vol -= (shiftm1[(ch->param[CHP_VOLDDN])]);
   if(vol < 0) vol = 0;
   ch->param[CHP_VOL] = (u8) vol;
   ch->vibrphase += ch->param[CHP_VIBRRATE];
   if(ch->sustaintimer) {
    ch->sustaintimer--;
    if(!ch->sustaintimer) {
     ch->param[CHP_VOLDDN] = ch->param[CHP_RELEASE];
    }
   }
  }
  player.divtimer = 44100/100;
 }
 player.divtimer--;
 if(player.drumptr) {
  switch(*player.drumptr++) {
   case 0:
    if(player.drumlevel > -16) player.drumlevel--;
    break;
   case 1:
    if(player.drumlevel < 15) player.drumlevel++;
    break;
   default:
    player.drumptr = 0;
    break;
  }
 }
 acc = player.drumlevel << (9 - player.drumvol);
 for(c = 0; c < 4; c++) {
  struct channel *ch = &channel[c];
  s8 sound;
  switch(ch->param[CHP_WAVEFORM]) {
   case 0x8:
    sound = ch->phase >> 10;
    if(sound & 0x20) {
     sound ^= 0x3f;
    }
    sound -= 16;
    break;
   case 0xF:
    sound = (player.noise & 15) >> (ch->freq >> 8);
    player.noise <<= 1;
    if(player.noise & 0x8000) player.noise ^= 1;
    if(player.noise & 0x4000) player.noise ^= 1;
    sound -= 8;
    break;
   default:
    sound = -8;
    if((ch->phase >> 12) > ch->param[CHP_WAVEFORM]) sound = 8;
    break;
  }
  acc += sound * ch->param[CHP_VOL];
  ch->phase +=
   ch->freq
   + (shiftm1[(ch->param[CHP_VIBRDEPTH])]) * sin((3.14159265358979323846 * 2 / 256) * ch->vibrphase)
   ;
 }
 if(bleepvolume) {
  bleepphase += bleepfreq;
  acc += bleepvolume * 2 * ((bleepphase & 0x8000)? 1 : -1);
  bleepvolume--;
 }
 return acc;
}

canonical_original_code:
static short nextsample() {
 int c;
 int acc;
 if(!player.divtimer) {
  if(!player.ttimer) {
   player.ttimer = 6;
   for(c = 0; c < 4; c++) {
    struct channel *ch = &channel[c];
    unsigned char note; unsigned char cmd; unsigned char trk; unsigned char hi; unsigned char lo; unsigned char ivol = 0xf;
    trk = (song[(c) * 25 + (player.songpos)]);
    note = (song[8 * 25 + (trk) * 32 + (player.trackpos)]);
    cmd = (song[8 * 25 + 42 * 32 + (trk) * 32 + (player.trackpos)]);
    if(note) note += (song[4 * 25 + (c) * 25 + (player.songpos)]);
    *((unsigned int *) &ch->echonotes[1]) = *((unsigned int *) &ch->echonotes[0]);
    ch->echonotes[0] = note;
    if(!note && ch->param[CHP_ECHO]) {
     note = ch->echonotes[3];
     ivol = ch->param[CHP_ECHO];
    }
    if(note) {
     ch->freq = pow(1.059463094, note + 60);
     ch->param[CHP_FREQDUP] = 0;
     ch->param[CHP_FREQDDN] = 0;
     ch->param[CHP_VOLDDN] = 0;
     ch->param[CHP_VIBRDEPTH] = 0;
     ch->param[CHP_VOL] = ivol << 4;
     ch->sustaintimer = (shiftm1[(ch->param[CHP_SUSTAIN])]);
    }
    hi = cmd >> 4;
    lo = cmd & 15;
    ch->param[hi] = lo;
    if(0) {
    }
    else if(hi == CHP_VOLDDN) {
     ch->sustaintimer = 0;
    }
    else if(hi == CHP_VIBRDEPTH) {
     ch->vibrphase = 0;
    }
    else if(hi == CHP_VOL) {
     ch->param[CHP_VOL] = lo << 4;
    }
    else if(hi == 0xd) {
     player.drumptr = drums[lo >> 1];
     player.drumvol = lo & 1;
    }
   }
   player.trackpos++;
   player.trackpos %= 32;
   if(!player.trackpos && allow_advance) {
    player.songpos++;
    if(player.songpos == 25) {
     player.songpos = 1;
    }
   }
  }
  player.ttimer--;
  for(c = 0; c < 4; c++) {
   struct channel *ch = &channel[c];
   short vol = ch->param[CHP_VOL];
   ch->freq += ch->param[CHP_FREQDUP];
   ch->freq -= ch->param[CHP_FREQDDN];
   vol -= (shiftm1[(ch->param[CHP_VOLDDN])]);
   if(vol < 0) vol = 0;
   ch->param[CHP_VOL] = (unsigned char) vol;
   ch->vibrphase += ch->param[CHP_VIBRRATE];
   if(ch->sustaintimer) {
    ch->sustaintimer--;
    if(!ch->sustaintimer) {
     ch->param[CHP_VOLDDN] = ch->param[CHP_RELEASE];
    }
   }
  }
  player.divtimer = 44100/100;
 }
 player.divtimer--;
 if(player.drumptr) {
  switch(*player.drumptr++) {
   case 0:
    if(player.drumlevel > -16) player.drumlevel--;
    break;
   case 1:
    if(player.drumlevel < 15) player.drumlevel++;
    break;
   default:
    player.drumptr = 0;
    break;
  }
 }
 acc = player.drumlevel << (9 - player.drumvol);
 for(c = 0; c < 4; c++) {
  struct channel *ch = &channel[c];
  char sound;
  switch(ch->param[CHP_WAVEFORM]) {
   case 0x8:
    sound = ch->phase >> 10;
    if(sound & 0x20) {
     sound ^= 0x3f;
    }
    sound -= 16;
    break;
   case 0xF:
    sound = (player.noise & 15) >> (ch->freq >> 8);
    player.noise <<= 1;
    if(player.noise & 0x8000) player.noise ^= 1;
    if(player.noise & 0x4000) player.noise ^= 1;
    sound -= 8;
    break;
   default:
    sound = -8;
    if((ch->phase >> 12) > ch->param[CHP_WAVEFORM]) sound = 8;
    break;
  }
  acc += sound * ch->param[CHP_VOL];
  ch->phase +=
   ch->freq
   + (shiftm1[(ch->param[CHP_VIBRDEPTH])]) * sin((3.14159265358979323846 * 2 / 256) * ch->vibrphase)
   ;
 }
 if(bleepvolume) {
  bleepphase += bleepfreq;
  acc += bleepvolume * 2 * ((bleepphase & 0x8000)? 1 : -1);
  bleepvolume--;
 }
 return acc;
}

variable_types: c int

variable_types: acc int

variable_types: struct channel { unsigned char param[16]; unsigned short phase; unsigned short freq; unsigned short vibrphase; unsigned short sustaintimer; unsigned char echonotes[5]; unsigned char pad[3]; } *

variable_types:
note
unsigned char

variable_types:
cmd
unsigned char

variable_types:
trk
unsigned char

variable_types:
hi
unsigned char

variable_types:
lo
unsigned char

variable_types:
ivol
unsigned char

variable_types: vol short

variable_types: sound char

return_type: short


playroutine

original_code:
static void playroutine(void *_dummy, uint8_t *_soundbuf, int _buflen) {
 int i;
 s16 *soundbuf = (s16 *) _soundbuf;
 int buflen = _buflen / 4;
 s16 dry;
 static s16 reverb[1024];
 static int reverbpos;
 for(i = 0; i < buflen; i++) {
  dry = nextsample();
  soundbuf[i * 2 + 0] = dry + reverb[reverbpos];
  soundbuf[i * 2 + 1] = dry + reverb[(reverbpos + 1024 - 100) % 1024];
  reverb[reverbpos] = dry >> 2;
  reverbpos = (reverbpos + 1) % 1024;
 }
}

canonical_original_code:
static void playroutine(void *_dummy, unsigned char *_soundbuf, int _buflen) {
 int i;
 short *soundbuf = (s16 *) _soundbuf;
 int buflen = _buflen / 4;
 short dry;
 static short reverb[1024];
 static int reverbpos;
 for(i = 0; i < buflen; i++) {
  dry = nextsample();
  soundbuf[i * 2 + 0] = dry + reverb[reverbpos];
  soundbuf[i * 2 + 1] = dry + reverb[(reverbpos + 1024 - 100) % 1024];
  reverb[reverbpos] = dry >> 2;
  reverbpos = (reverbpos + 1) % 1024;
 }
}

variable_types: i int

variable_types:
soundbuf
short *

variable_types: buflen int

variable_types: dry short

variable_types:
reverb
short [1024]

variable_types: reverbpos int


decompiled_code:
__int64 sfx_init()
{
return SDL_OpenAudio(&audiospec, 0LL);
}

canonical_decompiled_code:
__int64 func2()
{
return SDL_OpenAudio(&audiospec, 0LL);
}

original_code:
void sfx_init() {
 SDL_OpenAudio(&audiospec, 0);
}


decompiled_code:
__int64 sfx_startsong()
{
SDL_PauseAudio(1LL);
allow_advance = 0;
channel[0] = (__int128)_mm_load_si128((const __m128i *)&initchannel);
xmmword_2510 = (__int128)_mm_load_si128((const __m128i *)&xmmword_25D0);
xmmword_2520 = (__int128)_mm_load_si128((const __m128i *)&xmmword_25E0);
xmmword_2530 = (__int128)_mm_load_si128((const __m128i *)&xmmword_25F0);
qword_24E0 = 0LL;
xmmword_2540 = (__int128)_mm_load_si128((const __m128i *)&xmmword_2600);
xmmword_2550 = (__int128)_mm_load_si128((const __m128i *)&xmmword_2610);
xmmword_2560 = (__int128)_mm_load_si128((const __m128i *)&xmmword_2620);
xmmword_2570 = (__int128)_mm_load_si128((const __m128i *)&xmmword_2630);
player = (__int128)_mm_load_si128((const __m128i *)&initplayer);
return SDL_PauseAudio(0LL);
}

canonical_decompiled_code:
__int64 func3()
{
SDL_PauseAudio(1LL);
allow_advance = 0;
channel[0] = (__int128)_mm_load_si128((const __m128i *)&initchannel);
xmmword_2510 = (__int128)_mm_load_si128((const __m128i *)&xmmword_25D0);
xmmword_2520 = (__int128)_mm_load_si128((const __m128i *)&xmmword_25E0);
xmmword_2530 = (__int128)_mm_load_si128((const __m128i *)&xmmword_25F0);
qword_24E0 = 0LL;
xmmword_2540 = (__int128)_mm_load_si128((const __m128i *)&xmmword_2600);
xmmword_2550 = (__int128)_mm_load_si128((const __m128i *)&xmmword_2610);
xmmword_2560 = (__int128)_mm_load_si128((const __m128i *)&xmmword_2620);
xmmword_2570 = (__int128)_mm_load_si128((const __m128i *)&xmmword_2630);
player = (__int128)_mm_load_si128((const __m128i *)&initplayer);
return SDL_PauseAudio(0LL);
}

original_code:
void sfx_startsong(int num) {
 SDL_PauseAudio(1);
 memcpy(channel, initchannel, sizeof(channel));
 memcpy(&player, &initplayer, sizeof(player));
 allow_advance = 0;
 SDL_PauseAudio(0);
}

variable_types: num int


decompiled_code:
void sfx_advance()
{
allow_advance = 1;
}

canonical_decompiled_code:
void func4()
{
allow_advance = 1;
}


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

result = 823LL;
bleepfreq = 823;
bleepvolume = 3000;
return result;
}

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

result = 823LL;
bleepfreq = 823;
bleepvolume = 3000;
return result;
}

original_code:
void sfx_hitbase() {
 bleepfreq = 554 * 0x10000 / 44100;
 bleepvolume = 3000;
}


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

result = 1646LL;
bleepfreq = 1646;
bleepvolume = 3000;
return result;
}

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

result = 1646LL;
bleepfreq = 1646;
bleepvolume = 3000;
return result;
}

original_code:
void sfx_hitbrick() {
 bleepfreq = 1108 * 0x10000 / 44100;
 bleepvolume = 3000;
}


decompiled_code:
void sfx_gameover()
{
;
}

canonical_decompiled_code:
void func7()
{
;
}

original_code:
void sfx_gameover() {
}

canonical_original_code:
void sfx_gameover() {
}


decompiled_code:
__int64 __fastcall draw_membrane_part(int a1, int a2, int a3, int a4)
{
double v6; // [rsp+8h] [rbp-40h]
double v7; // [rsp+28h] [rbp-20h]

v6 = (double)a3;
v7 = 0.12 * (double)a3;
glTexCoord2d(0.12 * (double)a1, v7);
glVertex3d((double)a1, 0.0, v6);
glTexCoord2d(0.12 * (double)a1, 0.12 * (double)a4);
glVertex3d((double)a1, 0.0, (double)a4);
glTexCoord2d(0.12 * (double)a2, 0.12 * (double)a4);
glVertex3d((double)a2, 0.0, (double)a4);
glTexCoord2d(0.12 * (double)a2, v7);
return glVertex3d((double)a2, 0.0, v6);
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, int a2, int a3, int a4)
{
double v6; // [rsp+8h] [rbp-40h]
double v7; // [rsp+28h] [rbp-20h]

v6 = (double)a3;
v7 = 0.12 * (double)a3;
glTexCoord2d(0.12 * (double)a1, v7);
glVertex3d((double)a1, 0.0, v6);
glTexCoord2d(0.12 * (double)a1, 0.12 * (double)a4);
glVertex3d((double)a1, 0.0, (double)a4);
glTexCoord2d(0.12 * (double)a2, 0.12 * (double)a4);
glVertex3d((double)a2, 0.0, (double)a4);
glTexCoord2d(0.12 * (double)a2, v7);
return glVertex3d((double)a2, 0.0, v6);
}

original_code:
void draw_membrane_part(int x0, int x1, int z0, int z1)
{
 glTexCoord2d(x0 * .12, z0 * .12);
 glVertex3d(x0, 0, z0);
 glTexCoord2d(x0 * .12, z1 * .12);
 glVertex3d(x0, 0, z1);
 glTexCoord2d(x1 * .12, z1 * .12);
 glVertex3d(x1, 0, z1);
 glTexCoord2d(x1 * .12, z0 * .12);
 glVertex3d(x1, 0, z0);
}


original_code:
void draw_membrane(int softglow)
{
 int x, y;
 int ox, oz;
 glBindTexture(0x0DE1, TEX_GRID);
 glTexParameteri(0x0DE1, 0x2801, 0x2703);
 glTexParameteri(0x0DE1, 0x2800, 0x2703);
 glDepthMask(1);
 glDisable(0x0B44);
 if(softglow) {
  glColor3ub(0x62, 0xBC, 0xE8);
 } else {
  glColor3ub(0x82, 0xdc, 0xff);
 }
 glBegin(0x0007);
 ox = -240 / 2;
 oz = -240 / 2;
 draw_membrane_part(ox, ox + 240, oz, oz - (200));
 ox = -240 / 2;
 oz = 240 / 2;
 draw_membrane_part(ox, ox + 240, oz, oz + (200));
 ox = -(200) - 240 / 2;
 oz = -(200) - 240 / 2;
 draw_membrane_part(ox, ox + (200), oz, oz + 2*(200) + 240);
 ox = (200) + 240 / 2;
 oz = -(200) - 240 / 2;
 draw_membrane_part(ox, ox - (200), oz, oz + 2*(200) + 240);
 glEnd();
 glEnable(0x0B44);
 for(y = 0; y < 240; y += 5) {
  int z0 = y - 240/2;
  int z1 = y + 5 - 240/2;
  int xmax = 240/2;
  glBegin(0x0008);
  for(x = 0; x < 240; x += 5) {
   int x0 = x - 240/2;
   glTexCoord2d(x0 * .12, z0 * .12);
   glVertex3d(x0, -.1 * worldmap[y][x].sinkage, z0);
   glTexCoord2d(x0 * .12, z1 * .12);
   if(y + 5 >= 240) {
    glVertex3d(x0, 0, z1);
   } else {
    glVertex3d(x0, -.1 * worldmap[y + 5][x].sinkage, z1);
   }
  }
  glTexCoord2d(xmax * .12, z0 * .12);
  glVertex3d(xmax, 0, z0);
  glTexCoord2d(xmax * .12, z1 * .12);
  glVertex3d(xmax, 0, z1);
  glEnd();
 }
 glBindTexture(0x0DE1, TEX_VIGNETTE);
 glTexParameteri(0x0DE1, 0x2801, 0x2703);
 glTexParameteri(0x0DE1, 0x2800, 0x2703);
 glEnable(0x0BE2);
 glBlendFunc(0, 0x0300);
 glColor3d(1, 1, 1);
 glDisable(0x0B71);
 glDepthMask(0);
 glBegin(0x0007);
 glTexCoord2d(0, 0);
 glVertex3d(-(200) - 240 / 2, 0, -(200) - 240 / 2);
 glTexCoord2d(0, 1);
 glVertex3d(-(200) - 240 / 2, 0, +(200) + 240 / 2);
 glTexCoord2d(1, 1);
 glVertex3d(+(200) + 240 / 2, 0, +(200) + 240 / 2);
 glTexCoord2d(1, 0);
 glVertex3d(+(200) + 240 / 2, 0, -(200) - 240 / 2);
 glEnd();
 glDisable(0x0BE2);
 glEnable(0x0B71);
 glDepthMask(1);
}

canonical_original_code:
void draw_membrane(int softglow)
{
 int x; int y;
 int ox; int oz;
 glBindTexture(0x0DE1, TEX_GRID);
 glTexParameteri(0x0DE1, 0x2801, 0x2703);
 glTexParameteri(0x0DE1, 0x2800, 0x2703);
 glDepthMask(1);
 glDisable(0x0B44);
 if(softglow) {
  glColor3ub(0x62, 0xBC, 0xE8);
 } else {
  glColor3ub(0x82, 0xdc, 0xff);
 }
 glBegin(0x0007);
 ox = -240 / 2;
 oz = -240 / 2;
 draw_membrane_part(ox, ox + 240, oz, oz - (200));
 ox = -240 / 2;
 oz = 240 / 2;
 draw_membrane_part(ox, ox + 240, oz, oz + (200));
 ox = -(200) - 240 / 2;
 oz = -(200) - 240 / 2;
 draw_membrane_part(ox, ox + (200), oz, oz + 2*(200) + 240);
 ox = (200) + 240 / 2;
 oz = -(200) - 240 / 2;
 draw_membrane_part(ox, ox - (200), oz, oz + 2*(200) + 240);
 glEnd();
 glEnable(0x0B44);
 for(y = 0; y < 240; y += 5) {
  int z0 = y - 240/2;
  int z1 = y + 5 - 240/2;
  int xmax = 240/2;
  glBegin(0x0008);
  for(x = 0; x < 240; x += 5) {
   int x0 = x - 240/2;
   glTexCoord2d(x0 * .12, z0 * .12);
   glVertex3d(x0, -.1 * worldmap[y][x].sinkage, z0);
   glTexCoord2d(x0 * .12, z1 * .12);
   if(y + 5 >= 240) {
    glVertex3d(x0, 0, z1);
   } else {
    glVertex3d(x0, -.1 * worldmap[y + 5][x].sinkage, z1);
   }
  }
  glTexCoord2d(xmax * .12, z0 * .12);
  glVertex3d(xmax, 0, z0);
  glTexCoord2d(xmax * .12, z1 * .12);
  glVertex3d(xmax, 0, z1);
  glEnd();
 }
 glBindTexture(0x0DE1, TEX_VIGNETTE);
 glTexParameteri(0x0DE1, 0x2801, 0x2703);
 glTexParameteri(0x0DE1, 0x2800, 0x2703);
 glEnable(0x0BE2);
 glBlendFunc(0, 0x0300);
 glColor3d(1, 1, 1);
 glDisable(0x0B71);
 glDepthMask(0);
 glBegin(0x0007);
 glTexCoord2d(0, 0);
 glVertex3d(-(200) - 240 / 2, 0, -(200) - 240 / 2);
 glTexCoord2d(0, 1);
 glVertex3d(-(200) - 240 / 2, 0, +(200) + 240 / 2);
 glTexCoord2d(1, 1);
 glVertex3d(+(200) + 240 / 2, 0, +(200) + 240 / 2);
 glTexCoord2d(1, 0);
 glVertex3d(+(200) + 240 / 2, 0, -(200) - 240 / 2);
 glEnd();
 glDisable(0x0BE2);
 glEnable(0x0B71);
 glDepthMask(1);
}

variable_types: softglow int

variable_types: x int

variable_types: y int

variable_types: ox int

variable_types: oz int

variable_types: xmax int


decompiled_code:
void **__fastcall free_bigint(void ***a1)
{
void **result; // rax

if ( !a1 )
_assert_fail("obj != NULL", "bigint.c", 0x24u, "free_bigint");
result = *a1;
if ( *a1 )
{
if ( *result )
{
free(*result);
result = *a1;
}
*result = 0LL;
*a1 = 0LL;
}
return result;
}

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

if ( !a1 )
_assert_fail("obj != NULL", "bigint.c", 0x24u, "free_bigint");
result = *a1;
if ( *a1 )
{
if ( *result )
{
free(*result);
result = *a1;
}
*result = 0LL;
*a1 = 0LL;
}
return result;
}

original_code:
void free_bigint(bigint_t** obj)
{
 ((obj != ((void *)0)) ? (void) (0) : __assert_fail ("obj != NULL", "bigint.c", 36, __extension__ __PRETTY_FUNCTION__));
 if (*obj == ((void *)0)) return;
 if ((*obj)->d != ((void *)0))
  free((*obj)->d);
 (*obj)->d = ((void *)0);
 *obj = ((void *)0);
}

canonical_original_code:
void free_bigint(struct bigint **obj)
{
 ((obj != ((void *)0)) ? (void) (0) : __assert_fail ("obj != NULL", "bigint.c", 36, __extension__ __PRETTY_FUNCTION__));
 if (*obj == ((void *)0)) return;
 if ((*obj)->d != ((void *)0))
  free((*obj)->d);
 (*obj)->d = ((void *)0);
 *obj = ((void *)0);
}

variable_types: struct bigint { int *d; int n; int lim; } **


decompiled_code:
void __fastcall bigint_widen(__int64 a1, int a2)
{
_DWORD *v2; // rdx
void *v3; // rax

if ( !a1 )
_assert_fail("obj != NULL", "bigint.c", 0x31u, "bigint_widen");
if ( *(_DWORD *)(a1 + 12) < a2 )
{
v3 = realloc(*(void **)a1, 4LL * a2);
*(_DWORD *)(a1 + 12) = a2;
*(_QWORD *)a1 = v3;
v2 = v3;
LODWORD(v3) = *(_DWORD *)(a1 + 8) + 1;
if ( a2 > (int)v3 )
{
v3 = (void *)(int)v3;
do
{
v2[(_QWORD)v3] = 0;
v3 = (char *)v3 + 1;
}
while ( *(_DWORD *)(a1 + 12) > (int)v3 );
}
}
}

original_code:
void bigint_widen(bigint_t* obj, int n)
{
 ((obj != ((void *)0)) ? (void) (0) : __assert_fail ("obj != NULL", "bigint.c", 49, __extension__ __PRETTY_FUNCTION__));
 if (obj->lim >= n)
  return;
 obj->d = realloc(obj->d, sizeof(int)*n);
 obj->lim = n;
 for (int i = obj->n+1; i < obj->lim; ++i)
  obj->d[i] = 0;
}

canonical_original_code:
void bigint_widen(struct bigint *obj, int n)
{
 ((obj != ((void *)0)) ? (void) (0) : __assert_fail ("obj != NULL", "bigint.c", 49, __extension__ __PRETTY_FUNCTION__));
 if (obj->lim >= n)
  return;
 obj->d = realloc(obj->d, sizeof(int)*n);
 obj->lim = n;
 for (int i = obj->n+1; i < obj->lim; ++i)
  obj->d[i] = 0;
}

variable_types: struct bigint { int *d; int n; int lim; } *

variable_types: n int


decompiled_code:
unsigned __int64 __fastcall bigint_set(__int64 *a1, unsigned int a2)
{
unsigned __int64 result; // rax
__int64 v3; // rdx
__int64 v4; // r10
__int64 v5; // rdx
unsigned int v6; // ecx

result = *((unsigned int *)a1 + 2);
if ( (result & 0x80000000) == 0LL )
{
v3 = *a1;
result = 0LL;
do
*(_DWORD *)(v3 + 4 * result++) = 0;
while ( *((_DWORD *)a1 + 2) >= (int)result );
}
*((_DWORD *)a1 + 2) = 0;
if ( a2 )
{
v4 = *a1;
v5 = 0LL;
do
{
result = a2 / 0x2710uLL;
*(_DWORD *)(v4 + 4 * v5) = a2 % 0x2710;
v6 = a2;
a2 /= 0x2710u;
*((_DWORD *)a1 + 2) = v5++;
}
while ( v6 > 0x270F );
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func2(__int64 *a1, unsigned int a2)
{
unsigned __int64 result; // rax
__int64 v3; // rdx
__int64 v4; // r10
__int64 v5; // rdx
unsigned int v6; // ecx

result = *((unsigned int *)a1 + 2);
if ( (result & 0x80000000) == 0LL )
{
v3 = *a1;
result = 0LL;
do
*(_DWORD *)(v3 + 4 * result++) = 0;
while ( *((_DWORD *)a1 + 2) >= (int)result );
}
*((_DWORD *)a1 + 2) = 0;
if ( a2 )
{
v4 = *a1;
v5 = 0LL;
do
{
result = a2 / 0x2710uLL;
*(_DWORD *)(v4 + 4 * v5) = a2 % 0x2710;
v6 = a2;
a2 /= 0x2710u;
*((_DWORD *)a1 + 2) = v5++;
}
while ( v6 > 0x270F );
}
return result;
}

canonical_original_code:
void bigint_set(struct bigint *a, unsigned int v)
{
 int i;
 for (i = 0; i < a->n+1; ++i)
  a->d[i] = 0;
 a->n = 0;
 for (i = 0; v > 0; ++i) {
  int rem = v % (10000);
  a->d[i] = rem;
  v = v / (10000);
  a->n = i;
 }
}

variable_types:
v
unsigned int

variable_types: rem int

user_defined_types: struct bigint { int *d; int n; int lim; }


original_code:
void bigint_add(bigint_t* a, bigint_t* b, bigint_t* c)
{
 if (a->n < b->n) {
  bigint_add(b, a, c);
  return;
 }
 bigint_widen(c, a->n+2);
 int i;
 for (i = 0; i < b->n+1; ++i)
  c->d[i] = a->d[i] + b->d[i];
 for (; i < a->n+1; ++i)
  c->d[i] = a->d[i];
 for (i = a->n+1; i < c->lim; ++i)
  c->d[i] = 0;
 int rem = 0;
 int carry = 0;
 int n = a->n+1;
 for (i = 0; i < n || carry; ++i) {
  c->d[i] += carry;
  rem = c->d[i] % (10000);
  carry = c->d[i] / (10000);
  c->d[i] = rem;
  c->n = i;
 }
}

canonical_original_code:
void bigint_add(struct bigint *a, struct bigint *b, struct bigint *c)
{
 if (a->n < b->n) {
  bigint_add(b, a, c);
  return;
 }
 bigint_widen(c, a->n+2);
 int i;
 for (i = 0; i < b->n+1; ++i)
  c->d[i] = a->d[i] + b->d[i];
 for (; i < a->n+1; ++i)
  c->d[i] = a->d[i];
 for (i = a->n+1; i < c->lim; ++i)
  c->d[i] = 0;
 int rem = 0;
 int carry = 0;
 int n = a->n+1;
 for (i = 0; i < n || carry; ++i) {
  c->d[i] += carry;
  rem = c->d[i] % (10000);
  carry = c->d[i] / (10000);
  c->d[i] = rem;
  c->n = i;
 }
}

variable_types:
b
struct bigint *

variable_types:
c
struct bigint *

variable_types: i int

variable_types: carry int