// File: tomfunkhouser[P]gaps/pkgs/GSV/GSVMesh.cpp
// Function: gaps::GSVMesh::LoadScan(gaps::GSVScan*, double, double)
int GSVMesh::
LoadScan(GSVScan *scan, 
  RNLength min_viewpoint_movement,
  RNLength max_depth_discontinuity)
{
  // Just checking
  if (!scan) return 0;
  if (scan->NScanlines() == 0) return 1;

  // Read points
  scan->ReadPoints();

  // Compute whether faces sould be flipped (clockwise)
  RNBoolean flip = (scan->SegmentIndex() == 2) ? 1 : 0;

  // Compute total number of vertices and length of scan viewpoint path
  int total_vertex_count = 0;
  RNScalar total_travel_distance = 0;
  R3Point prev_viewpoint = scan->Scanline(0)->Pose().Viewpoint();
  for (int ie = 0; ie < scan->NScanlines(); ie++) {
    GSVScanline *scanline = scan->Scanline(ie);
    const GSVPose& pose = scanline->Pose();
    const R3Point& viewpoint = pose.Viewpoint();
    RNLength movement = R3Distance(viewpoint, prev_viewpoint);
    total_travel_distance += movement;
    if (movement < min_viewpoint_movement) continue;
    prev_viewpoint = viewpoint;
    total_vertex_count += scanline->NPoints();
  }

  // Compute number of rows and columns
  if (total_travel_distance == 0) { scan->ReleasePoints(); return 1; }
  int ncols = (int) (total_travel_distance / min_viewpoint_movement + 0.5);
  if (ncols == 0) { scan->ReleasePoints(); return 1; }
  const int nrows = 180;
  int col = 0;

  // Allocate vertex data
  gsv_vertex_block = new GSVMeshVertex [ total_vertex_count ];
  if (!gsv_vertex_block) { 
    RNFail("Unable to allocate GSV Mesh vertex array\n"); 
    scan->ReleasePoints(); 
    return 0; 
  }

  // Initialize vertex buffer
  int buffer_index = 0;
  GSVMeshVertex *vertex_buffer[2][nrows];
  for (int k = 0; k < nrows; k++) {
    vertex_buffer[0][k] = NULL;
    vertex_buffer[1][k] = NULL;
  }

  // Create mesh
  int vertex_count = 0;
  prev_viewpoint = scan->Scanline(0)->Pose().Viewpoint();
  for (int ie = 0; ie < scan->NScanlines(); ie++) {
    GSVScanline *scanline = scan->Scanline(ie);
    const GSVPose& pose = scanline->Pose();
    const R3Point& viewpoint = pose.Viewpoint();
    RNLength movement = R3Distance(viewpoint, prev_viewpoint);
    if (movement < min_viewpoint_movement) continue;
    prev_viewpoint = viewpoint;
    const R3Vector& towards = pose.Towards();
    R3Vector up = pose.Up();

    // Initialize buffer of vertices in scanline indexed by row
    for (int k = 0; k < nrows; k++) {
      vertex_buffer[buffer_index][k] = NULL;
    }

    // Create vertices for scanline
    for (int j = 0; j < scanline->NPoints(); j++) {
      R3Point position = scanline->PointPosition(j);
      R3Vector v = position - viewpoint;
      RNLength distance = v.Length();
      if (RNIsZero(distance)) continue;
      v /= distance;
      RNScalar dot = v.Dot(towards);
      RNAngle angle = acos(dot);
      if (v.Dot(up) > 0) angle = RN_PI_OVER_TWO + angle;
      else angle = RN_PI_OVER_TWO - angle;
      int row = (int) (nrows * angle / RN_PI + 0.5);
      if ((row < 0) || (row >= nrows)) continue;
      if (vertex_buffer[buffer_index][row]) continue;
      assert(vertex_count < total_vertex_count);
      GSVMeshVertex *vertex = &gsv_vertex_block[vertex_count];
      vertex_buffer[buffer_index][row] = vertex;
      CreateVertex(position, vertex);
      vertex->scanline = scanline;
      vertex->point_index = j;
      vertex->boundary_type = GSV_MESH_NO_BOUNDARY;
      if (j == 0) vertex->boundary_type = GSV_MESH_BOTTOM_BOUNDARY;
      else if (j == (scanline->NPoints()-1)) vertex->boundary_type = GSV_MESH_TOP_BOUNDARY;
      else if (ie == 0) vertex->boundary_type = GSV_MESH_LEFT_BOUNDARY;
      else if (ie == (scan->NScanlines()-1)) vertex->boundary_type = GSV_MESH_RIGHT_BOUNDARY;
      vertex_count++;
    }

    // Create faces between this and previous scanline
    if (col > 0) {
      int row0 = 0;
      int row1 = 0;
      while ((row0 < nrows) && (!vertex_buffer[1-buffer_index][row0])) row0++;
      while ((row1 < nrows) && (!vertex_buffer[buffer_index][row1])) row1++;
      if ((row0 < nrows) && (row1 < nrows)) {
        GSVMeshVertex *vertex0 = vertex_buffer[1-buffer_index][row0];
        GSVMeshVertex *vertex1 = vertex_buffer[buffer_index][row1];
        while ((row0 < nrows-1) || (row1 < nrows-1)) {
          // Get next vertex
          int row = 0;
          GSVMeshVertex *vertex = NULL;
          if (row0 < row1) {
            row0++;
            vertex = vertex_buffer[1-buffer_index][row0];
            row = 0;
          }
          else {
            row1++;
            vertex = vertex_buffer[buffer_index][row1];
            row = 1;
          }

          // Check vertex
          if (vertex && vertex0 && vertex1) {
            // Mark vertex types
            RNBoolean curtain = FALSE;
            RNLength depth = VertexLaserDepth(vertex);
            RNLength depth0 = VertexLaserDepth(vertex0);
            RNLength depth1 = VertexLaserDepth(vertex1);
            if (max_depth_discontinuity > 0) {
              const R3Point& position0 = VertexPosition(vertex0);
              const R3Point& position1 = VertexPosition(vertex1);
              R3Vector normal_vector0 = VertexNormal(vertex0);
              R3Vector normal_vector1 = VertexNormal(vertex1);
              R3Vector normal_vector = 0.5 * (normal_vector0 + normal_vector1);
              normal_vector.Normalize();
              R3Vector laser_vector0 = VertexLaserViewpoint(vertex0) - position0;
              laser_vector0.Normalize();
              R3Vector laser_vector1 = VertexLaserViewpoint(vertex1)- position1;
              laser_vector1.Normalize();
              R3Vector laser_vector = 0.5 * (laser_vector0 + laser_vector1);
              laser_vector.Normalize();
              RNScalar dot = fabs(laser_vector.Dot(normal_vector));
              if (dot < 0.5) dot = 0.5;
              RNLength max_depth_diff = max_depth_discontinuity / dot;
              if (depth - depth0 > max_depth_diff) {
                vertex0->boundary_type = GSV_MESH_SILHOUETTE_BOUNDARY;
                vertex->boundary_type = GSV_MESH_SHADOW_BOUNDARY;
                curtain = TRUE;
              }
              else if (depth0 - depth > max_depth_diff) {
                vertex->boundary_type = GSV_MESH_SILHOUETTE_BOUNDARY;
                vertex0->boundary_type = GSV_MESH_SHADOW_BOUNDARY;
                curtain = TRUE;
              }
              if (depth - depth1 > max_depth_diff) {
                vertex1->boundary_type = GSV_MESH_SILHOUETTE_BOUNDARY;
                vertex->boundary_type = GSV_MESH_SHADOW_BOUNDARY;
                curtain = TRUE;
              }
              else if (depth1 - depth > max_depth_diff) {
                vertex->boundary_type = GSV_MESH_SILHOUETTE_BOUNDARY;
                vertex1->boundary_type = GSV_MESH_SHADOW_BOUNDARY;
                curtain = TRUE;
              }
            }
            
            // Create face
            if (!curtain) {
              R3MeshFace *face = NULL;
              if (flip) face = CreateFace(vertex0, vertex, vertex1);
              else face = CreateFace(vertex0, vertex1, vertex);
              if (face) SetFaceSegment(face, 1);
            }
          }
          
          // Update stuff for next triangle
          if (vertex) {
            if (row == 0) vertex0 = vertex;
            else vertex1 = vertex;
          }
        }
      }
    }

    // Update stuff for next scanline
    buffer_index = 1 - buffer_index;
    col++;
  }

  // Release points
  scan->ReleasePoints(); 

  // Return success
  return 1;
}

// Assembly:
subq $0xe78, %rsp            # imm = 0xE78
movq %rdi, 0xe68(%rsp)
movq %rsi, 0xe60(%rsp)
movsd %xmm0, 0xe58(%rsp)
movsd %xmm1, 0xe50(%rsp)
movq 0xe68(%rsp), %rax
movq %rax, 0x70(%rsp)
cmpq $0x0, 0xe60(%rsp)
jne 0x5a6d1
movl $0x0, 0xe74(%rsp)
jmp 0x5b700
movq 0xe60(%rsp), %rdi
callq 0x3a0d0
cmpl $0x0, %eax
jne 0x5a6f3
movl $0x1, 0xe74(%rsp)
jmp 0x5b700
movq 0xe60(%rsp), %rdi
callq 0x557c0
movq 0xe60(%rsp), %rdi
callq 0x54480
movl %eax, %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x2, %edx
cmovel %ecx, %eax
movl %eax, 0xe4c(%rsp)
movl $0x0, 0xe48(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0xe40(%rsp)
movq 0xe60(%rsp), %rdi
xorl %esi, %esi
callq 0x3a0f0
movq %rax, %rdi
callq 0x44c60
movq %rax, %rdi
callq 0x3a330
movq %rax, %rsi
leaq 0xe28(%rsp), %rdi
callq 0x17fdd0
movl $0x0, 0xe24(%rsp)
movl 0xe24(%rsp), %eax
movl %eax, 0x6c(%rsp)
movq 0xe60(%rsp), %rdi
callq 0x3a0d0
movl %eax, %ecx
movl 0x6c(%rsp), %eax
cmpl %ecx, %eax
jge 0x5a879
movq 0xe60(%rsp), %rdi
movl 0xe24(%rsp), %esi
callq 0x3a0f0
movq %rax, 0xe18(%rsp)
movq 0xe18(%rsp), %rdi
callq 0x44c60
movq %rax, 0xe10(%rsp)
movq 0xe10(%rsp), %rdi
callq 0x3a330
movq %rax, 0xe08(%rsp)
movq 0xe08(%rsp), %rdi
leaq 0xe28(%rsp), %rsi
callq 0x10df80
movsd %xmm0, 0xe00(%rsp)
movsd 0xe00(%rsp), %xmm0
addsd 0xe40(%rsp), %xmm0
movsd %xmm0, 0xe40(%rsp)
movsd 0xe00(%rsp), %xmm1
movsd 0xe58(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x5a833
jmp 0x5a863
movq 0xe08(%rsp), %rsi
leaq 0xe28(%rsp), %rdi
callq 0x180420
movq 0xe18(%rsp), %rdi
callq 0x3a120
addl 0xe48(%rsp), %eax
movl %eax, 0xe48(%rsp)
movl 0xe24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe24(%rsp)
jmp 0x5a774
movsd 0xe40(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x5a8aa
jp 0x5a8aa
movq 0xe60(%rsp), %rdi
callq 0x55960
movl $0x1, 0xe74(%rsp)
jmp 0x5b700
movsd 0xe40(%rsp), %xmm0
divsd 0xe58(%rsp), %xmm0
movsd 0x20b78c(%rip), %xmm1   # 0x266050
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0xdfc(%rsp)
cmpl $0x0, 0xdfc(%rsp)
jne 0x5a8fa
movq 0xe60(%rsp), %rdi
callq 0x55960
movl $0x1, 0xe74(%rsp)
jmp 0x5b700
movl $0xb4, 0xdf8(%rsp)
movl $0x0, 0xdf4(%rsp)
movslq 0xe48(%rsp), %rax
movq %rax, 0x50(%rsp)
movl $0xa8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
addq $0x8, %rdi
setb %al
orb %al, %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, 0x48(%rsp)
callq 0x29820
movq %rax, %rcx
movq 0x50(%rsp), %rax
movq %rcx, 0x58(%rsp)
movq %rax, (%rcx)
addq $0x8, %rcx
movq %rcx, 0x60(%rsp)
cmpq $0x0, %rax
je 0x5a9b7
movq 0x60(%rsp), %rax
movq 0x50(%rsp), %rcx
imulq $0xa8, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x38(%rsp)
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x5e0a0
jmp 0x5a99d
movq 0x38(%rsp), %rcx
movq 0x30(%rsp), %rax
addq $0xa8, %rax
cmpq %rcx, %rax
movq %rax, 0x40(%rsp)
jne 0x5a98c
movq 0x70(%rsp), %rax
movq 0x60(%rsp), %rcx
movq %rcx, 0x138(%rax)
cmpq $0x0, 0x138(%rax)
jne 0x5aa65
leaq 0x20cb1b(%rip), %rdi    # 0x2674f8
movb $0x0, %al
callq 0x1cbff0
movq 0xe60(%rsp), %rdi
callq 0x55960
movl $0x0, 0xe74(%rsp)
jmp 0x5b700
movq 0x60(%rsp), %rcx
movq %rax, %rsi
movq 0x30(%rsp), %rax
movq %rsi, 0xde8(%rsp)
movl %edx, 0xde4(%rsp)
cmpq %rax, %rcx
movq %rax, 0x28(%rsp)
je 0x5aa51
movq 0x28(%rsp), %rdi
addq $-0xa8, %rdi
movq %rdi, 0x20(%rsp)
callq 0x5e0f0
movq 0x60(%rsp), %rcx
movq 0x20(%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x28(%rsp)
jne 0x5aa27
movq 0x48(%rsp), %rsi
movq 0x58(%rsp), %rdi
callq 0x29030
jmp 0x5b70f
movl $0x0, 0xde0(%rsp)
movl $0x0, 0x29c(%rsp)
cmpl $0xb4, 0x29c(%rsp)
jge 0x5aac3
movslq 0x29c(%rsp), %rax
movq $0x0, 0x2a0(%rsp,%rax,8)
movslq 0x29c(%rsp), %rax
movq $0x0, 0x840(%rsp,%rax,8)
movl 0x29c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x29c(%rsp)
jmp 0x5aa7b
movl $0x0, 0x298(%rsp)
movq 0xe60(%rsp), %rdi
xorl %esi, %esi
callq 0x3a0f0
movq %rax, %rdi
callq 0x44c60
movq %rax, %rdi
callq 0x3a330
movq %rax, %rsi
leaq 0xe28(%rsp), %rdi
callq 0x180420
movl $0x0, 0x294(%rsp)
movl 0x294(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0xe60(%rsp), %rdi
callq 0x3a0d0
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x5b6e8
movq 0xe60(%rsp), %rdi
movl 0x294(%rsp), %esi
callq 0x3a0f0
movq %rax, 0x288(%rsp)
movq 0x288(%rsp), %rdi
callq 0x44c60
movq %rax, 0x280(%rsp)
movq 0x280(%rsp), %rdi
callq 0x3a330
movq %rax, 0x278(%rsp)
movq 0x278(%rsp), %rdi
leaq 0xe28(%rsp), %rsi
callq 0x10df80
movsd %xmm0, 0x270(%rsp)
movsd 0x270(%rsp), %xmm1
movsd 0xe58(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x5abaf
jmp 0x5b6d2
movq 0x278(%rsp), %rsi
leaq 0xe28(%rsp), %rdi
callq 0x180420
movq 0x280(%rsp), %rsi
leaq 0x250(%rsp), %rdi
callq 0x5e6c0
leaq 0x250(%rsp), %rax
movq %rax, 0x268(%rsp)
movq 0x280(%rsp), %rsi
leaq 0x238(%rsp), %rdi
callq 0x5e730
movl $0x0, 0x234(%rsp)
cmpl $0xb4, 0x234(%rsp)
jge 0x5ac53
movslq 0xde0(%rsp), %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x234(%rsp), %rcx
movq $0x0, (%rax,%rcx,8)
movl 0x234(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x234(%rsp)
jmp 0x5ac09
movl $0x0, 0x230(%rsp)
movl 0x230(%rsp), %eax
movl %eax, 0x18(%rsp)
movq 0x288(%rsp), %rdi
callq 0x3a120
movl %eax, %ecx
movl 0x18(%rsp), %eax
cmpl %ecx, %eax
jge 0x5af9c
movq 0x288(%rsp), %rsi
movl 0x230(%rsp), %edx
leaq 0x218(%rsp), %rdi
callq 0x59950
movq 0x278(%rsp), %rdx
leaq 0x200(%rsp), %rdi
leaq 0x218(%rsp), %rsi
callq 0x1800f0
leaq 0x200(%rsp), %rdi
callq 0x1810d0
movsd %xmm0, 0x1f8(%rsp)
movsd 0x1f8(%rsp), %xmm0
leaq 0x29e145(%rip), %rax    # 0x2f8e28
movsd (%rax), %xmm1
callq 0x51990
cmpl $0x0, %eax
je 0x5acf6
jmp 0x5af86
movsd 0x1f8(%rsp), %xmm0
leaq 0x200(%rsp), %rdi
callq 0x182100
movq 0x268(%rsp), %rsi
leaq 0x200(%rsp), %rdi
callq 0x181500
movsd %xmm0, 0x1f0(%rsp)
movsd 0x1f0(%rsp), %xmm0
callq 0x29b90
movsd %xmm0, 0x1e8(%rsp)
leaq 0x200(%rsp), %rdi
leaq 0x238(%rsp), %rsi
callq 0x181500
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x5ad7e
leaq 0x213222(%rip), %rax    # 0x26df88
movsd (%rax), %xmm0
addsd 0x1e8(%rsp), %xmm0
movsd %xmm0, 0x1e8(%rsp)
jmp 0x5ad9b
leaq 0x213203(%rip), %rax    # 0x26df88
movsd (%rax), %xmm0
subsd 0x1e8(%rsp), %xmm0
movsd %xmm0, 0x1e8(%rsp)
movsd 0x20c005(%rip), %xmm0   # 0x266da8
mulsd 0x1e8(%rsp), %xmm0
leaq 0x2131c5(%rip), %rax    # 0x26df78
divsd (%rax), %xmm0
movsd 0x20b291(%rip), %xmm1   # 0x266050
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x1e4(%rsp)
cmpl $0x0, 0x1e4(%rsp)
jl 0x5ade5
cmpl $0xb4, 0x1e4(%rsp)
jl 0x5adea
jmp 0x5af86
movslq 0xde0(%rsp), %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x1e4(%rsp), %rcx
cmpq $0x0, (%rax,%rcx,8)
je 0x5ae18
jmp 0x5af86
movq 0x70(%rsp), %rdi
movq 0x138(%rdi), %rax
movslq 0x298(%rsp), %rcx
imulq $0xa8, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x1d8(%rsp)
movq 0x1d8(%rsp), %rdx
movslq 0xde0(%rsp), %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x1e4(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x1d8(%rsp), %rdx
movq (%rdi), %rax
leaq 0x218(%rsp), %rsi
callq *0x20(%rax)
movq 0x288(%rsp), %rcx
movq 0x1d8(%rsp), %rax
movq %rcx, 0x98(%rax)
movl 0x230(%rsp), %ecx
movq 0x1d8(%rsp), %rax
movl %ecx, 0xa0(%rax)
movq 0x1d8(%rsp), %rax
movl $0x0, 0xa4(%rax)
cmpl $0x0, 0x230(%rsp)
jne 0x5aee1
movq 0x1d8(%rsp), %rax
movl $0x3, 0xa4(%rax)
jmp 0x5af75
movl 0x230(%rsp), %eax
movl %eax, 0x14(%rsp)
movq 0x288(%rsp), %rdi
callq 0x3a120
movl %eax, %ecx
movl 0x14(%rsp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5af1a
movq 0x1d8(%rsp), %rax
movl $0x4, 0xa4(%rax)
jmp 0x5af73
cmpl $0x0, 0x294(%rsp)
jne 0x5af38
movq 0x1d8(%rsp), %rax
movl $0x1, 0xa4(%rax)
jmp 0x5af71
movl 0x294(%rsp), %eax
movl %eax, 0x10(%rsp)
movq 0xe60(%rsp), %rdi
callq 0x3a0d0
movl %eax, %ecx
movl 0x10(%rsp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5af6f
movq 0x1d8(%rsp), %rax
movl $0x2, 0xa4(%rax)
jmp 0x5af71
jmp 0x5af73
jmp 0x5af75
movl 0x298(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x298(%rsp)
movl 0x230(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x230(%rsp)
jmp 0x5ac5e
cmpl $0x0, 0xdf4(%rsp)
jle 0x5b6ae
movl $0x0, 0x1d4(%rsp)
movl $0x0, 0x1d0(%rsp)
xorl %eax, %eax
cmpl $0xb4, 0x1d4(%rsp)
movb %al, 0xf(%rsp)
jge 0x5b00a
movl $0x1, %eax
subl 0xde0(%rsp), %eax
movslq %eax, %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x1d4(%rsp), %rcx
cmpq $0x0, (%rax,%rcx,8)
setne %al
xorb $-0x1, %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x5b014
jmp 0x5b027
movl 0x1d4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1d4(%rsp)
jmp 0x5afc0
jmp 0x5b029
xorl %eax, %eax
cmpl $0xb4, 0x1d0(%rsp)
movb %al, 0xe(%rsp)
jge 0x5b06c
movslq 0xde0(%rsp), %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x1d0(%rsp), %rcx
cmpq $0x0, (%rax,%rcx,8)
setne %al
xorb $-0x1, %al
movb %al, 0xe(%rsp)
movb 0xe(%rsp), %al
testb $0x1, %al
jne 0x5b076
jmp 0x5b089
movl 0x1d0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1d0(%rsp)
jmp 0x5b029
cmpl $0xb4, 0x1d4(%rsp)
jge 0x5b6ac
cmpl $0xb4, 0x1d0(%rsp)
jge 0x5b6ac
movl $0x1, %eax
subl 0xde0(%rsp), %eax
movslq %eax, %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x1d4(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x1c8(%rsp)
movslq 0xde0(%rsp), %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x1d0(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x1c0(%rsp)
movb $0x1, %al
cmpl $0xb3, 0x1d4(%rsp)
movb %al, 0xd(%rsp)
jl 0x5b133
cmpl $0xb3, 0x1d0(%rsp)
setl %al
movb %al, 0xd(%rsp)
movb 0xd(%rsp), %al
testb $0x1, %al
jne 0x5b140
jmp 0x5b6aa
movl $0x0, 0x1bc(%rsp)
movq $0x0, 0x1b0(%rsp)
movl 0x1d4(%rsp), %eax
cmpl 0x1d0(%rsp), %eax
jge 0x5b1ba
movl 0x1d4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1d4(%rsp)
movl $0x1, %eax
subl 0xde0(%rsp), %eax
movslq %eax, %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x1d4(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x1b0(%rsp)
movl $0x0, 0x1bc(%rsp)
jmp 0x5b204
movl 0x1d0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1d0(%rsp)
movslq 0xde0(%rsp), %rcx
leaq 0x2a0(%rsp), %rax
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rcx, %rax
movslq 0x1d0(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x1b0(%rsp)
movl $0x1, 0x1bc(%rsp)
cmpq $0x0, 0x1b0(%rsp)
je 0x5b66c
cmpq $0x0, 0x1c8(%rsp)
je 0x5b66c
cmpq $0x0, 0x1c0(%rsp)
je 0x5b66c
movq 0x70(%rsp), %rdi
movl $0x0, 0x1ac(%rsp)
movq 0x1b0(%rsp), %rsi
callq 0x5a320
movq 0x70(%rsp), %rdi
movsd %xmm0, 0x1a0(%rsp)
movq 0x1c8(%rsp), %rsi
callq 0x5a320
movq 0x70(%rsp), %rdi
movsd %xmm0, 0x198(%rsp)
movq 0x1c0(%rsp), %rsi
callq 0x5a320
movsd %xmm0, 0x190(%rsp)
movsd 0xe50(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x5b5d3
movq 0x70(%rsp), %rdi
movq 0x1c8(%rsp), %rsi
callq 0x391a0
movq 0x70(%rsp), %rdi
movq %rax, 0x188(%rsp)
movq 0x1c0(%rsp), %rsi
callq 0x391a0
movq 0x70(%rsp), %rdi
movq %rax, 0x180(%rsp)
movq 0x1c8(%rsp), %rsi
callq 0x39210
movq %rax, %rsi
leaq 0x168(%rsp), %rdi
callq 0x180f30
movq 0x70(%rsp), %rdi
movq 0x1c0(%rsp), %rsi
callq 0x39210
movq %rax, %rsi
leaq 0x150(%rsp), %rdi
callq 0x180f30
leaq 0x120(%rsp), %rdi
leaq 0x168(%rsp), %rsi
leaq 0x150(%rsp), %rdx
callq 0x182270
leaq 0x138(%rsp), %rdi
movsd 0x20ad08(%rip), %xmm0   # 0x266050
leaq 0x120(%rsp), %rsi
callq 0x38f20
leaq 0x138(%rsp), %rdi
callq 0x181650
movq 0x70(%rsp), %rsi
movq 0x1c8(%rsp), %rdx
leaq 0xf0(%rsp), %rdi
callq 0x5a4a0
movq 0x188(%rsp), %rdx
leaq 0x108(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x1800f0
leaq 0x108(%rsp), %rdi
callq 0x181650
movq 0x70(%rsp), %rsi
movq 0x1c0(%rsp), %rdx
leaq 0xc0(%rsp), %rdi
callq 0x5a4a0
movq 0x180(%rsp), %rdx
leaq 0xd8(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x1800f0
leaq 0xd8(%rsp), %rdi
callq 0x181650
leaq 0x90(%rsp), %rdi
leaq 0x108(%rsp), %rsi
leaq 0xd8(%rsp), %rdx
callq 0x182270
leaq 0xa8(%rsp), %rdi
movsd 0x20ac39(%rip), %xmm0   # 0x266050
leaq 0x90(%rsp), %rsi
callq 0x38f20
leaq 0xa8(%rsp), %rdi
callq 0x181650
leaq 0xa8(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x181500
movaps 0x20bb73(%rip), %xmm1   # 0x266fc0
pand %xmm1, %xmm0
movsd %xmm0, 0x88(%rsp)
movsd 0x20abee(%rip), %xmm0   # 0x266050
ucomisd 0x88(%rsp), %xmm0
jbe 0x5b47e
movsd 0x20abdb(%rip), %xmm0   # 0x266050
movsd %xmm0, 0x88(%rsp)
movsd 0xe50(%rsp), %xmm0
divsd 0x88(%rsp), %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0x1a0(%rsp), %xmm0
subsd 0x198(%rsp), %xmm0
ucomisd 0x80(%rsp), %xmm0
jbe 0x5b4e7
movq 0x1c8(%rsp), %rax
movl $0x6, 0xa4(%rax)
movq 0x1b0(%rsp), %rax
movl $0x5, 0xa4(%rax)
movl $0x1, 0x1ac(%rsp)
jmp 0x5b535
movsd 0x198(%rsp), %xmm0
subsd 0x1a0(%rsp), %xmm0
ucomisd 0x80(%rsp), %xmm0
jbe 0x5b533
movq 0x1b0(%rsp), %rax
movl $0x6, 0xa4(%rax)
movq 0x1c8(%rsp), %rax
movl $0x5, 0xa4(%rax)
movl $0x1, 0x1ac(%rsp)
jmp 0x5b535
movsd 0x1a0(%rsp), %xmm0
subsd 0x190(%rsp), %xmm0
ucomisd 0x80(%rsp), %xmm0
jbe 0x5b583
movq 0x1c0(%rsp), %rax
movl $0x6, 0xa4(%rax)
movq 0x1b0(%rsp), %rax
movl $0x5, 0xa4(%rax)
movl $0x1, 0x1ac(%rsp)
jmp 0x5b5d1
movsd 0x190(%rsp), %xmm0
subsd 0x1a0(%rsp), %xmm0
ucomisd 0x80(%rsp), %xmm0
jbe 0x5b5cf
movq 0x1b0(%rsp), %rax
movl $0x6, 0xa4(%rax)
movq 0x1c0(%rsp), %rax
movl $0x5, 0xa4(%rax)
movl $0x1, 0x1ac(%rsp)
jmp 0x5b5d1
jmp 0x5b5d3
cmpl $0x0, 0x1ac(%rsp)
jne 0x5b66a
movq $0x0, 0x78(%rsp)
cmpl $0x0, 0xe4c(%rsp)
je 0x5b621
movq 0x70(%rsp), %rdi
movq 0x1c8(%rsp), %rsi
movq 0x1b0(%rsp), %rdx
movq 0x1c0(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movq %rax, 0x78(%rsp)
jmp 0x5b64c
movq 0x70(%rsp), %rdi
movq 0x1c8(%rsp), %rsi
movq 0x1c0(%rsp), %rdx
movq 0x1b0(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movq %rax, 0x78(%rsp)
cmpq $0x0, 0x78(%rsp)
je 0x5b668
movq 0x70(%rsp), %rdi
movq 0x78(%rsp), %rsi
movl $0x1, %edx
callq 0x5e130
jmp 0x5b66a
jmp 0x5b66c
cmpq $0x0, 0x1b0(%rsp)
je 0x5b6a5
cmpl $0x0, 0x1bc(%rsp)
jne 0x5b693
movq 0x1b0(%rsp), %rax
movq %rax, 0x1c8(%rsp)
jmp 0x5b6a3
movq 0x1b0(%rsp), %rax
movq %rax, 0x1c0(%rsp)
jmp 0x5b6a5
jmp 0x5b10e
jmp 0x5b6ac
jmp 0x5b6ae
movl $0x1, %eax
subl 0xde0(%rsp), %eax
movl %eax, 0xde0(%rsp)
movl 0xdf4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdf4(%rsp)
movl 0x294(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x294(%rsp)
jmp 0x5ab08
movq 0xe60(%rsp), %rdi
callq 0x55960
movl $0x1, 0xe74(%rsp)
movl 0xe74(%rsp), %eax
addq $0xe78, %rsp            # imm = 0xE78
retq
movq 0xde8(%rsp), %rdi
callq 0x29c10
nopl (%rax)