// File: /workspace/github_cpp_makefile_star2_O1/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xcd8, %rsp            # imm = 0xCD8
movsd %xmm1, 0x70(%rsp)
movsd %xmm0, 0x50(%rsp)
testq %rsi, %rsi
je 0x4352e
movq %rsi, %r13
movl $0x1, %eax
cmpl $0x0, 0x34(%rsi)
je 0x43d99
movq %rdi, (%rsp)
movq %r13, %rdi
callq 0x405e6
movq %r13, %rdi
callq 0x3fbf6
movl %eax, 0x5c(%rsp)
movq 0x28(%r13), %rax
movq (%rax), %rsi
addq $0x40, %rsi
leaq 0xe8(%rsp), %rdi
callq 0xd5e3e
cmpl $0x0, 0x34(%r13)
jle 0x43535
xorpd %xmm0, %xmm0
xorl %r15d, %r15d
leaq 0xe8(%rsp), %rbx
xorl %ebp, %ebp
movsd %xmm0, 0x10(%rsp)
movq 0x28(%r13), %rax
movq (%rax,%r15,8), %r12
leaq 0x40(%r12), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x9d528
movapd %xmm0, %xmm1
movsd 0x50(%rsp), %xmm0
ucomisd %xmm1, %xmm0
ja 0x43516
movq %rbx, %rdi
movq %r14, %rsi
movsd %xmm1, 0x48(%rsp)
callq 0xd619c
movsd 0x48(%rsp), %xmm1
addl 0x30(%r12), %ebp
movsd 0x10(%rsp), %xmm0
addsd %xmm1, %xmm0
incq %r15
movslq 0x34(%r13), %rax
cmpq %rax, %r15
jl 0x434cc
jmp 0x4353b
xorl %eax, %eax
jmp 0x43d99
xorl %ebp, %ebp
xorpd %xmm0, %xmm0
ucomisd 0x10aafd(%rip), %xmm0   # 0x14e040
jne 0x4354f
jp 0x4354f
movq %r13, %rdi
jmp 0x43d8f
divsd 0x50(%rsp), %xmm0
addsd 0x10aab3(%rip), %xmm0   # 0x14e010
cvttsd2si %xmm0, %eax
testl %eax, %eax
je 0x43547
movq %r13, 0x28(%rsp)
movslq %ebp, %r14
movl $0xa8, %ecx
movq %r14, %rax
mulq %rcx
movq %rax, %rbx
seto %al
addq $0x8, %rbx
movq $-0x1, %rcx
cmovbq %rcx, %rbx
testb %al, %al
cmovneq %rcx, %rbx
movq %rbx, %rdi
callq 0x27040
movq %r14, (%rax)
movq %rax, 0x10(%rsp)
leaq 0x8(%rax), %r13
testl %r14d, %r14d
je 0x435f1
imulq $0xa8, %r14, %r14
xorl %r12d, %r12d
leaq 0x18b8b3(%rip), %rbp    # 0x1cee70
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
leaq (%r12,%r13), %rdi
callq 0xb487c
movq %rbp, (%r13,%r12)
movq $0x0, 0x98(%r13,%r12)
movq %r15, 0xa0(%r13,%r12)
addq $0xa8, %r12
cmpq %r12, %r14
jne 0x435c3
movq (%rsp), %rax
movq %r13, 0x138(%rax)
leaq 0x190(%rsp), %rdi
movq $0x0, 0x30(%rsp)
movl $0xb40, %edx            # imm = 0xB40
xorl %esi, %esi
callq 0x274b0
movq 0x28(%rsp), %rbx
movq 0x28(%rbx), %rax
movq (%rax), %rsi
addq $0x40, %rsi
leaq 0xe8(%rsp), %rdi
callq 0xd619c
cmpl $0x0, 0x34(%rbx)
jle 0x43d8c
leaq 0x116c81(%rip), %rax    # 0x15a2c8
movsd (%rax), %xmm0
movsd %xmm0, 0x48(%rsp)
leaq 0x116c60(%rip), %rax    # 0x15a2b8
movsd (%rax), %xmm0
movsd %xmm0, 0x98(%rsp)
leaq 0xe8(%rsp), %r12
xorl %r13d, %r13d
xorl %ebp, %ebp
movl $0x0, 0xc(%rsp)
movq 0x28(%rbx), %rax
movq (%rax,%r13,8), %r14
leaq 0x40(%r14), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x9d528
movsd 0x50(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x43d7c
movq %r13, 0x60(%rsp)
leaq 0x38(%r14), %rbx
movq %r12, %rdi
movq %r15, %rsi
callq 0xd619c
leaq 0x178(%rsp), %rdi
movq %rbx, %rsi
callq 0x455c6
leaq 0x160(%rsp), %rdi
movq %rbx, %rsi
callq 0x4560c
movl %ebp, 0x8(%rsp)
movl %ebp, %ebx
imulq $0x5a0, %rbx, %rax      # imm = 0x5A0
leaq (%rsp,%rax), %rdi
addq $0x190, %rdi            # imm = 0x190
movl $0x5a0, %edx            # imm = 0x5A0
xorl %esi, %esi
callq 0x274b0
cmpl $0x0, 0x30(%r14)
movq %rbx, 0x38(%rsp)
jle 0x438ec
imulq $0x5a0, %rbx, %rax      # imm = 0x5A0
addq %rsp, %rax
addq $0x190, %rax            # imm = 0x190
movq %rax, 0x40(%rsp)
xorl %r13d, %r13d
xorl %ebp, %ebp
movq 0x28(%r14), %rax
movsd (%rax,%r13), %xmm0
movsd 0x8(%rax,%r13), %xmm1
movsd 0x10(%rax,%r13), %xmm2
leaq 0x118(%rsp), %r12
movq %r12, %rdi
callq 0xd5e2e
leaq 0x100(%rsp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0xd6090
movq %rbx, %rdi
callq 0xd69cc
leaq 0x194cf8(%rip), %rax    # 0x1d8468
movsd (%rax), %xmm1
movapd %xmm1, %xmm2
xorpd 0x10b530(%rip), %xmm2   # 0x14ecb0
ucomisd %xmm2, %xmm0
jb 0x43790
ucomisd %xmm0, %xmm1
jae 0x438d8
leaq 0x100(%rsp), %rbx
movq %rbx, %rdi
callq 0xd74f4
movq %rbx, %rdi
leaq 0x178(%rsp), %rsi
callq 0xd6b5e
callq 0x278b0
movapd %xmm0, 0x10(%rsp)
movq %rbx, %rdi
leaq 0x160(%rsp), %rsi
callq 0xd6b5e
xorpd %xmm1, %xmm1
cmpltsd %xmm0, %xmm1
movapd %xmm1, %xmm0
movapd 0x10(%rsp), %xmm2
andpd %xmm2, %xmm0
xorpd 0x10b4c6(%rip), %xmm2   # 0x14ecb0
andnpd %xmm2, %xmm1
orpd %xmm0, %xmm1
addsd 0x48(%rsp), %xmm1
mulsd 0x10b4a0(%rip), %xmm1   # 0x14eca0
divsd 0x98(%rsp), %xmm1
addsd 0x10a7ff(%rip), %xmm1   # 0x14e010
cvttsd2si %xmm1, %eax
cmpl $0xb3, %eax
ja 0x438d8
movl %eax, %eax
movq 0x40(%rsp), %rcx
cmpq $0x0, (%rcx,%rax,8)
jne 0x438d8
leaq (%rcx,%rax,8), %rax
movq (%rsp), %rdi
movq 0x138(%rdi), %rbx
movslq 0xc(%rsp), %rcx
imulq $0xa8, %rcx, %r12
leaq (%rbx,%r12), %rdx
movq %rdx, (%rax)
movq (%rdi), %rax
leaq 0x118(%rsp), %rsi
movq %rdx, 0x10(%rsp)
callq *0x20(%rax)
movq %r14, 0x98(%rbx,%r12)
movl %ebp, 0xa0(%rbx,%r12)
movl $0x0, 0xa4(%rbx,%r12)
testq %rbp, %rbp
je 0x438ae
movq 0x60(%rsp), %rsi
testq %rsi, %rsi
sete %dl
movl 0x30(%r14), %ecx
decl %ecx
xorl %eax, %eax
cmpq %rcx, %rbp
sete %cl
orb %cl, %dl
je 0x438b5
movb %cl, %al
leal (%rax,%rax,2), %eax
incl %eax
jmp 0x438c9
movl $0x3, %eax
jmp 0x438c9
movq 0x28(%rsp), %rax
movl 0x34(%rax), %ecx
decl %ecx
movl $0x2, %eax
cmpq %rcx, %rsi
jne 0x438d4
movq 0x10(%rsp), %rcx
movl %eax, 0xa4(%rcx)
incl 0xc(%rsp)
incq %rbp
movslq 0x30(%r14), %rax
addq $0x50, %r13
cmpq %rax, %rbp
jl 0x43723
cmpl $0x0, 0x30(%rsp)
jle 0x43d53
movl $0x1, %eax
subl 0x8(%rsp), %eax
movq %rax, 0x68(%rsp)
imulq $0x5a0, %rax, %rdx      # imm = 0x5A0
movb $0x1, %al
xorl %r14d, %r14d
cmpq $0x0, 0x190(%rsp,%rdx)
movl $0x0, %ebx
movb $0x1, %cl
jne 0x4395f
leaq 0x198(%rsp), %rcx
addq %rcx, %rdx
xorl %ecx, %ecx
cmpq $0xb3, %rcx
je 0x43957
leaq 0x1(%rcx), %rbx
cmpq $0x0, (%rdx,%rcx,8)
movq %rbx, %rcx
je 0x43930
leaq -0x1(%rbx), %rcx
cmpq $0xb3, %rcx
setb %cl
jmp 0x4395f
setb %cl
movl $0xb4, %ebx
imulq $0x5a0, 0x38(%rsp), %rdx # imm = 0x5A0
cmpq $0x0, 0x190(%rsp,%rdx)
jne 0x439ae
leaq 0x198(%rsp), %rax
addq %rax, %rdx
xorl %eax, %eax
cmpq $0xb3, %rax
je 0x439a5
leaq 0x1(%rax), %r14
cmpq $0x0, (%rdx,%rax,8)
movq %r14, %rax
je 0x43980
leaq -0x1(%r14), %rax
cmpq $0xb3, %rax
setb %al
jmp 0x439ae
setb %al
movl $0xb4, %r14d
andb %al, %cl
cmpb $0x1, %cl
jne 0x43d53
movl $0xb3, %ecx
cmpl %ecx, %ebx
setl %al
cmpl %ecx, %r14d
setl %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x43d53
movl %r14d, %eax
imulq $0x5a0, 0x38(%rsp), %rcx # imm = 0x5A0
addq %rsp, %rcx
addq $0x190, %rcx            # imm = 0x190
movq (%rcx,%rax,8), %rax
movl %ebx, %ecx
imulq $0x5a0, 0x68(%rsp), %rdx # imm = 0x5A0
addq %rsp, %rdx
addq $0x190, %rdx            # imm = 0x190
movq (%rdx,%rcx,8), %rcx
movl %r14d, %ebp
movq %rcx, %r12
movq %rax, %r13
cmpl %r14d, %ebx
movq %rbx, 0x10(%rsp)
jge 0x43a29
leal 0x1(%rbx), %eax
movq 0x68(%rsp), %rcx
movl %eax, %ebx
movl %ebp, %r14d
jmp 0x43a34
leal 0x1(%rbp), %eax
movq 0x38(%rsp), %rcx
movl %eax, %r14d
cltq
imulq $0x5a0, %rcx, %rcx      # imm = 0x5A0
addq %rsp, %rcx
addq $0x190, %rcx            # imm = 0x190
movq (%rcx,%rax,8), %r15
testq %r15, %r15
je 0x43d1a
testq %r12, %r12
je 0x43d1a
testq %r13, %r13
je 0x43d1a
movq %r15, %rsi
callq 0x4331a
movsd %xmm0, 0x40(%rsp)
movq %r12, %rsi
callq 0x4331a
movsd %xmm0, 0x90(%rsp)
movq %r13, %rsi
callq 0x4331a
movapd %xmm0, %xmm1
movsd 0x70(%rsp), %xmm0
ucomisd 0x10a5a1(%rip), %xmm0   # 0x14e040
jbe 0x43ce0
movsd %xmm1, 0x88(%rsp)
testb $0x2, 0x78(%r12)
jne 0x43ac6
movq (%rsp), %rdi
movq (%rdi), %rax
movq %r12, %rsi
callq *0x2b0(%rax)
leaq 0x30(%r12), %rsi
leaq 0x118(%rsp), %rdi
callq 0xd68d6
testb $0x2, 0x78(%r13)
jne 0x43aef
movq (%rsp), %rdi
movq (%rdi), %rax
movq %r13, %rsi
callq *0x2b0(%rax)
leaq 0x18(%r12), %rax
movq %rax, 0x78(%rsp)
leaq 0x18(%r13), %rax
movq %rax, 0x80(%rsp)
leaq 0x30(%r13), %rsi
leaq 0x100(%rsp), %rdi
callq 0xd68d6
leaq 0xd0(%rsp), %rdi
leaq 0x118(%rsp), %rsi
leaq 0x100(%rsp), %rdx
callq 0xd757c
leaq 0x130(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
movsd 0x10a4c5(%rip), %xmm0   # 0x14e010
callq 0xd7296
leaq 0x130(%rsp), %rdi
callq 0xd6be8
leaq 0xb8(%rsp), %rdi
movq %r12, %rdx
callq 0x433a8
leaq 0xd0(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
movq 0x78(%rsp), %rdx
callq 0xd6090
leaq 0xd0(%rsp), %rdi
callq 0xd6be8
leaq 0xa0(%rsp), %rdi
movq %r13, %rdx
callq 0x433a8
leaq 0xb8(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
movq 0x80(%rsp), %rdx
callq 0xd6090
leaq 0xb8(%rsp), %rdi
callq 0xd6be8
leaq 0x148(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
leaq 0xb8(%rsp), %rdx
callq 0xd757c
leaq 0xa0(%rsp), %rdi
leaq 0x148(%rsp), %rsi
movsd 0x10a40d(%rip), %xmm0   # 0x14e010
callq 0xd7296
leaq 0xa0(%rsp), %rdi
callq 0xd6be8
leaq 0xa0(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0xd6b5e
andpd 0x10b28e(%rip), %xmm0   # 0x14eec0
movsd 0x10a3d6(%rip), %xmm1   # 0x14e010
maxsd %xmm0, %xmm1
movsd 0x70(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd 0x40(%rsp), %xmm2
movapd %xmm2, %xmm1
movsd 0x90(%rsp), %xmm3
subsd %xmm3, %xmm1
ucomisd %xmm0, %xmm1
movq %r12, %rcx
movq %r15, %rdx
ja 0x43c7d
subsd %xmm2, %xmm3
xorl %eax, %eax
ucomisd %xmm0, %xmm3
movq %r15, %rcx
movq %r12, %rdx
jbe 0x43c96
movl $0x6, 0xa4(%rcx)
movl $0x5, 0xa4(%rdx)
movl $0x1, %eax
movapd %xmm2, %xmm1
movsd 0x88(%rsp), %xmm3
subsd %xmm3, %xmm1
ucomisd %xmm0, %xmm1
movq %r13, %rcx
movq %r15, %rdx
ja 0x43cc3
subsd %xmm2, %xmm3
ucomisd %xmm0, %xmm3
movq %r15, %rcx
movq %r13, %rdx
jbe 0x43cdc
movl $0x6, 0xa4(%rcx)
movl $0x5, 0xa4(%rdx)
movl $0x1, %eax
testl %eax, %eax
jne 0x43d1a
movq (%rsp), %rdi
movq (%rdi), %rax
movq 0x48(%rax), %rax
cmpl $0x2, 0x5c(%rsp)
jne 0x43cfd
movq %r12, %rsi
movq %r15, %rdx
movq %r13, %rcx
jmp 0x43d06
movq %r12, %rsi
movq %r13, %rdx
movq %r15, %rcx
xorl %r8d, %r8d
callq *%rax
testq %rax, %rax
je 0x43d1a
movl $0x1, 0x9c(%rax)
testq %r15, %r15
movq %r12, %rcx
cmovneq %r15, %rcx
cmpl %ebp, 0x10(%rsp)
movq %r15, %rax
cmovlq %r13, %rax
cmovgeq %r12, %rcx
testq %r15, %r15
cmoveq %r13, %rax
cmpl $0xb3, %ebx
jl 0x43a07
cmpl $0xb3, %r14d
jl 0x43a07
movl $0x1, %eax
subl 0x8(%rsp), %eax
movq 0x30(%rsp), %rcx
incl %ecx
movq %rcx, 0x30(%rsp)
movl %eax, %ebp
movq 0x28(%rsp), %rbx
leaq 0xe8(%rsp), %r12
movq 0x60(%rsp), %r13
incq %r13
movslq 0x34(%rbx), %rax
cmpq %rax, %r13
jl 0x4367a
movq %rbx, %rdi
callq 0x406c0
movl $0x1, %eax
addq $0xcd8, %rsp            # imm = 0xCD8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
testq %r12, %r12
je 0x43dd1
movq 0x10(%rsp), %r15
addq $-0xa0, %r15
leaq (%r15,%r12), %rdi
callq 0xb491c
addq $-0xa8, %r12
jne 0x43dbf
movq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x28340
movq %r14, %rdi
callq 0x28160