// File: tomfunkhouser[P]gaps/pkgs/R3Utils/R3SurfelViewer.cpp
// Function: gaps::R3SurfelViewer::Keyboard(int, int, int, int, int, int)
int R3SurfelViewer::
Keyboard(int x, int y, int key, int shift, int ctrl, int alt)
{
  // Initialize redraw status
  int redraw = 1;

  // Process debugging commands
  if (alt) {
    // Process debugging commands
    switch (key) {
    case 'A':
    case 'a':
      SetAxesVisibility(-1);
      break;
      
    case 'B':
      SetNodeBBoxVisibility(-1);
      break;

    case 'b':
      SetObjectOrientedBBoxVisibility(-1);
      break;

    case 'C':
      SetSurfelColorScheme((surfel_color_scheme + 1) % R3_SURFEL_VIEWER_NUM_COLOR_SCHEMES);
      break;

    case 'c':
      if (SurfelColorScheme() == R3_SURFEL_VIEWER_COLOR_BY_RGB)
        SetSurfelColorScheme(R3_SURFEL_VIEWER_COLOR_BY_ELEVATION);
      else if (SurfelColorScheme() == R3_SURFEL_VIEWER_COLOR_BY_ELEVATION)
        SetSurfelColorScheme(R3_SURFEL_VIEWER_COLOR_BY_OBJECT);
      else if (SurfelColorScheme() == R3_SURFEL_VIEWER_COLOR_BY_OBJECT)
        SetSurfelColorScheme(R3_SURFEL_VIEWER_COLOR_BY_CURRENT_LABEL);
      else SetSurfelColorScheme(R3_SURFEL_VIEWER_COLOR_BY_RGB);
      break;
      
    case 'D':
    case 'd':
      SetImagePointsVisibility(-1);
      SelectImage(selected_image, FALSE, FALSE);
      break;
      
    case 'E':
    case 'e':
      if (shape_draw_flags != 0) shape_draw_flags = 0;
      else shape_draw_flags = R3_SURFEL_DISC_DRAW_FLAG | R3_SURFEL_NORMAL_DRAW_FLAG;
      break;
      
    case 'F':
    case 'f':
      SetBackfacingVisibility(-1);
      break;

    case 'G':
    case 'g':
      if (ElevationRange().IsEmpty()) SetElevationRange(RNInterval(-FLT_MAX, 0.25));
      else SetElevationRange(RNnull_interval);
      break;
      
    case 'I':
      SetImagePlaneVisibility(-1);
      SelectImage(selected_image, FALSE, FALSE);
      break;

    case 'i':
      SetImageInsetVisibility(-1);
      SelectImage(selected_image, FALSE, FALSE);
      break;

    case 'L': 
    case 'l':
      SetHumanLabeledObjectVisibility(-1);
      break;
      
    case 'M':
    case 'm':
      subsampling_multiplier_when_mouse_down = (subsampling_multiplier_when_mouse_down <= 1) ? 8 : 1;
      break;
      
    case 'N':
    case 'n':
      SetNormalVisibility(-1);
      break;
      
    case 'O':
    case 'o':
      SetCenterPointVisibility(-1);
      break;
      
    case 'P':
    case 'p':
      SetSurfelVisibility(-1);
      break;

    case 'R':
    case 'r':
      SetObjectRelationshipVisibility(-1);
      break;

    // case 'S': // Save for toggling "selection" in sfllabel
    // case 's':
    //   break;

    // case 'T': // Reserve for toggling object label text in sfllabel
    // case 't':
    //  break;
      
    case 'V':
    case 'v':
      SetImageViewpointVisibility(-1);
      break;
      
    case 'W':
      UpdateWorkingSet(viewer);
      break;

    case 'w': {
      R3Point pick_position;
      R3SurfelNode *node = PickNode(x, y, &pick_position);
      if (node) SetCenterPoint(pick_position);
      break; }

    case 'X':
    case 'x':
      SetObjectPrincipalAxesVisibility(-1);
      break;
      
    case 'Y':
    case 'y':
      SetScanViewpointVisibility(-1);
      break;
      
    case 'Z':
    case 'z':
      SetViewingExtentVisibility(-1);
      break;
      
    case 'Q':
      // Print info about the currently selected image
      if (selected_image) {
        printf("%s\n", selected_image->Name());
        fflush(stdout);
      }
      break;
        
    case 'q': {
      // Print info about the node clicked
      R3Point pick_position(0,0,0);
      R3SurfelNode *node = PickNode(x, y, &pick_position);
      if (node) {
        SetCenterPoint(pick_position);
        printf("%g %g %g\n", pick_position[0], pick_position[1], pick_position[2]);
        while (node) {
          const char *node_name = (node->Name()) ? node->Name() : "-";
          R3SurfelObject *object = node->Object();
          const char *object_name = (object && (object->Name())) ? object->Name() : "-";
          char object_index[128];
          if (object) sprintf(object_index, "%d", object->SceneIndex());
          else sprintf(object_index, "%s", "-");
          R3SurfelLabel *ground_truth_label = (object) ? object->GroundTruthLabel() : NULL;
          const char *ground_truth_label_name = (ground_truth_label && (ground_truth_label->Name())) ? ground_truth_label->Name() : "-";
          R3SurfelLabel *current_label = (object) ? object->CurrentLabel() : NULL;
          const char *current_label_name = (current_label && (current_label->Name())) ? current_label->Name() : "-";
          printf("  %4d %4d %-30s  :  %-6s %-30s  :  %-30s %-30s\n",  
                 node->TreeLevel(), node->NParts(), node_name, 
                 object_index, object_name, 
                 current_label_name, ground_truth_label_name);
          node = node->Parent();        
        }
      }
      break; }

    case ';':
      SetFocusRadius(0.9 * FocusRadius());
      break;
      
    case '\'':
      SetFocusRadius(1.1 * FocusRadius());
      break;

    case ':':
      SetTargetResolution(0.9 * TargetResolution());
      break;

    case '"':
      SetTargetResolution(1.1 * TargetResolution());
      break;

    case ',': 
    case '.':
      if (!ElevationRange().IsEmpty()) {
        RNInterval range = ElevationRange();
        if (key == ',') range.SetMax(0.9 * range.Max());
        else if (key == '.') range.SetMax(1.1 * range.Max());
        SetElevationRange(range);
      }
      break;
      
    case '{':
    case '}': {
      // Set billboard depth
      RNScalar factor = (key == '{') ? 0.8 : 1.2;
      SetImagePlaneDepth(factor * ImagePlaneDepth());
      break; }

    case '<':
    case '>': {
      // Select next/prev image
      int image_index = (selected_image) ? selected_image->SceneIndex() : 0;
      if (key == '>') image_index++;
      else if (key == '<') image_index--;
      if (image_index < 0) image_index = 0;
      if (image_index > scene->NImages()-1) image_index = scene->NImages()-1;
      SelectImage(scene->Image(image_index), FALSE, FALSE);
      break; }

    case '_': 
      SetSubsamplingFactor(SubsamplingFactor() / 2);
      break;

    case '+': 
      SetSubsamplingFactor(SubsamplingFactor() * 2);
      break;

    case '-': 
      SetSurfelSize(0.8 * SurfelSize());
      break;

    case '=': 
      SetSurfelSize(1.25 * SurfelSize());
      break;

    default:
      redraw = 0;
      break;
    }
  }
  else if (ctrl) {
    switch(key) {
    case 'M':
    case 'm': // Enter
      if (image_inset_size < 0.5) SetImageInsetSize(0.8);
      else SetImageInsetSize(0.2);
      break;

    case 'R':
    case 'r':
      // Reset camera
      ResetCamera();
      break;

    default:
      redraw = 0;
      break;
    }
  }
  else {
    // Process other commands
    switch (key) {
    case R3_SURFEL_VIEWER_F1_KEY:
    case R3_SURFEL_VIEWER_F2_KEY:
    case R3_SURFEL_VIEWER_F3_KEY:
    case R3_SURFEL_VIEWER_F4_KEY: {
      int scale = key - R3_SURFEL_VIEWER_F1_KEY + 1;
      ZoomCamera(0.05 + 0.25*scale*scale);
      break; }

    case R3_SURFEL_VIEWER_F7_KEY:
      if (selected_image) SelectImage(selected_image, TRUE, TRUE);
      break;

    case R3_SURFEL_VIEWER_F8_KEY:
      ResetCamera();
      break;
      
    case R3_SURFEL_VIEWER_DOWN_KEY:
      SetImageInsetSize(0.8 * ImageInsetSize());
      break;

    case R3_SURFEL_VIEWER_UP_KEY:
      SetImageInsetSize(1.25 * ImageInsetSize());
      break;

    case R3_SURFEL_VIEWER_PAGE_UP_KEY: 
      if (viewing_extent.IsEmpty()) viewing_extent = scene->BBox();
      if (shift) viewing_extent[RN_LO][RN_Z] += 0.01 * scene->BBox().ZLength();
      else viewing_extent[RN_HI][RN_Z] += 0.01 * scene->BBox().ZLength();
      if (R3Contains(viewing_extent, scene->BBox())) viewing_extent = R3null_box;
      break;

    case R3_SURFEL_VIEWER_PAGE_DOWN_KEY: 
      if (viewing_extent.IsEmpty()) viewing_extent = scene->BBox();
      if (shift) viewing_extent[RN_LO][RN_Z] -= 0.01 * scene->BBox().ZLength();
      else viewing_extent[RN_HI][RN_Z] -= 0.01 * scene->BBox().ZLength();
      if (R3Contains(viewing_extent, scene->BBox())) viewing_extent = R3null_box;
      break;

    default:
      redraw = 0;
      break;
    }
  }

  // Remember mouse position 
  mouse_position[0] = x;
  mouse_position[1] = y;

  // Remember modifiers 
  shift_down = shift;
  ctrl_down = ctrl;
  alt_down = alt;

  // Return whether need redraw
  return redraw;
}

// Assembly:
subq $0x228, %rsp            # imm = 0x228
movl 0x230(%rsp), %eax
movq %rdi, 0x220(%rsp)
movl %esi, 0x21c(%rsp)
movl %edx, 0x218(%rsp)
movl %ecx, 0x214(%rsp)
movl %r8d, 0x210(%rsp)
movl %r9d, 0x20c(%rsp)
movq 0x220(%rsp), %rax
movq %rax, 0xc8(%rsp)
movl $0x1, 0x208(%rsp)
cmpl $0x0, 0x230(%rsp)
je 0x37b20
movl 0x214(%rsp), %eax
addl $-0x22, %eax
movl %eax, %ecx
movq %rcx, 0xc0(%rsp)
subl $0x5b, %eax
ja 0x37b10
movq 0xc0(%rsp), %rax
leaq 0x20a8d8(%rip), %rcx    # 0x2417b8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0x138(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0xf0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0xd8(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movl 0x360(%rdi), %eax
addl $0x1, %eax
movl $0xf, %ecx
cltd
idivl %ecx
movl %edx, %esi
movq (%rdi), %rax
callq *0x158(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e730
cmpl $0x0, %eax
jne 0x36f8d
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xc, %esi
callq *0x158(%rax)
jmp 0x36ff8
movq 0xc8(%rsp), %rdi
callq 0x3e730
cmpl $0xc, %eax
jne 0x36fb7
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0x5, %esi
callq *0x158(%rax)
jmp 0x36ff6
movq 0xc8(%rsp), %rdi
callq 0x3e730
cmpl $0x5, %eax
jne 0x36fe1
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0x8, %esi
callq *0x158(%rax)
jmp 0x36ff4
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
xorl %esi, %esi
callq *0x158(%rax)
jmp 0x36ff6
jmp 0x36ff8
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0x120(%rax)
movq 0xc8(%rsp), %rdi
movq 0x2d0(%rdi), %rsi
movq (%rdi), %rax
xorl %ecx, %ecx
movl %ecx, %edx
callq *0x1c0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
addq $0x458, %rdi            # imm = 0x458
callq 0x3d4b0
cmpq $0x0, %rax
je 0x37078
leaq 0x200(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2f310
movq 0xc8(%rsp), %rax
movq 0x200(%rsp), %rcx
movq %rcx, 0x458(%rax)
jmp 0x370a1
leaq 0x1f8(%rsp), %rdi
movl $0x12, %esi
callq 0x2f310
movq 0xc8(%rsp), %rax
movq 0x1f8(%rsp), %rcx
movq %rcx, 0x458(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0xb0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e750
movq %rax, %rdi
callq 0x3d380
cmpl $0x0, %eax
je 0x37110
leaq 0x1e8(%rsp), %rdi
movsd 0x20a3ed(%rip), %xmm0   # 0x2414d8
movsd 0x20a47d(%rip), %xmm1   # 0x241570
callq 0x1a6050
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
leaq 0x1e8(%rsp), %rsi
callq *0x78(%rax)
jmp 0x37125
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
leaq 0x69f9d6(%rip), %rsi    # 0x6d6af8
callq *0x78(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0x110(%rax)
movq 0xc8(%rsp), %rdi
movq 0x2d0(%rdi), %rsi
movq (%rdi), %rax
xorl %ecx, %ecx
movl %ecx, %edx
callq *0x1c0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0x118(%rax)
movq 0xc8(%rsp), %rdi
movq 0x2d0(%rdi), %rsi
movq (%rdi), %rax
xorl %ecx, %ecx
movl %ecx, %edx
callq *0x1c0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0xc8(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rax
movl 0x490(%rax), %esi
movl $0x1, %ecx
movl $0x8, %edx
cmpl $0x1, %esi
cmovlel %edx, %ecx
movl %ecx, 0x490(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0xa8(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0x128(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0xa0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0xe0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0x108(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq %rdi, %rsi
addq $0x78, %rsi
movq (%rdi), %rax
callq *0x318(%rax)
jmp 0x37b1b
leaq 0x1d0(%rsp), %rdi
callq 0x1622b0
movq 0xc8(%rsp), %rdi
movl 0x21c(%rsp), %esi
movl 0x218(%rsp), %edx
movq (%rdi), %rax
leaq 0x1d0(%rsp), %rcx
xorl %r8d, %r8d
movl %r8d, %r9d
xorl %r8d, %r8d
movq %r9, %r8
movl $0x0, (%rsp)
callq *0x1f8(%rax)
movq %rax, 0x1c8(%rsp)
cmpq $0x0, 0x1c8(%rsp)
je 0x372f3
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
leaq 0x1d0(%rsp), %rsi
callq *0x80(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0xd0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0x100(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq *0x130(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rax
cmpq $0x0, 0x2d0(%rax)
je 0x3738f
movq 0xc8(%rsp), %rax
movq 0x2d0(%rax), %rdi
callq 0x3e770
movq %rax, %rsi
leaq 0x2106a2(%rip), %rdi    # 0x247a1b
movb $0x0, %al
callq 0x28090
movq 0x28bb89(%rip), %rax    # 0x2c2f10
movq (%rax), %rdi
callq 0x28c50
jmp 0x37b1b
leaq 0x1b0(%rsp), %rdi
xorps %xmm2, %xmm2
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x1622c0
movq 0xc8(%rsp), %rdi
movl 0x21c(%rsp), %esi
movl 0x218(%rsp), %edx
movq (%rdi), %rax
leaq 0x1b0(%rsp), %rcx
xorl %r8d, %r8d
movl %r8d, %r9d
xorl %r8d, %r8d
movq %r9, %r8
movl $0x0, (%rsp)
callq *0x1f8(%rax)
movq %rax, 0x1a8(%rsp)
cmpq $0x0, 0x1a8(%rsp)
je 0x3774b
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
leaq 0x1b0(%rsp), %rsi
callq *0x80(%rax)
leaq 0x1b0(%rsp), %rdi
xorl %esi, %esi
callq 0x3e410
movsd (%rax), %xmm0
movsd %xmm0, 0xb0(%rsp)
leaq 0x1b0(%rsp), %rdi
movl $0x1, %esi
callq 0x3e410
movsd (%rax), %xmm0
movsd %xmm0, 0xb8(%rsp)
leaq 0x1b0(%rsp), %rdi
movl $0x2, %esi
callq 0x3e410
movsd 0xb0(%rsp), %xmm0
movsd 0xb8(%rsp), %xmm1
movsd (%rax), %xmm2
leaq 0x20d58f(%rip), %rdi    # 0x244a0d
movb $0x3, %al
callq 0x28090
cmpq $0x0, 0x1a8(%rsp)
je 0x37749
movq 0x1a8(%rsp), %rdi
callq 0x3e790
cmpq $0x0, %rax
je 0x374be
movq 0x1a8(%rsp), %rdi
callq 0x3e790
movq %rax, 0xa8(%rsp)
jmp 0x374cf
leaq 0x20a619(%rip), %rax    # 0x241ade
movq %rax, 0xa8(%rsp)
jmp 0x374cf
movq 0xa8(%rsp), %rax
movq %rax, 0x1a0(%rsp)
movq 0x1a8(%rsp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x58f70
movq %rax, 0x198(%rsp)
cmpq $0x0, 0x198(%rsp)
je 0x3752d
movq 0x198(%rsp), %rdi
callq 0x3e7b0
cmpq $0x0, %rax
je 0x3752d
movq 0x198(%rsp), %rdi
callq 0x3e7b0
movq %rax, 0xa0(%rsp)
jmp 0x3753e
leaq 0x20a5aa(%rip), %rax    # 0x241ade
movq %rax, 0xa0(%rsp)
jmp 0x3753e
movq 0xa0(%rsp), %rax
movq %rax, 0x190(%rsp)
cmpq $0x0, 0x198(%rsp)
je 0x37590
leaq 0x110(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x198(%rsp), %rdi
callq 0x3d620
movq 0x98(%rsp), %rdi
movl %eax, %edx
leaq 0x214223(%rip), %rsi    # 0x24b7aa
movb $0x0, %al
callq 0x28160
jmp 0x375ad
leaq 0x110(%rsp), %rdi
leaq 0x22d528(%rip), %rsi    # 0x264ac7
leaq 0x20a538(%rip), %rdx    # 0x241ade
movb $0x0, %al
callq 0x28160
cmpq $0x0, 0x198(%rsp)
je 0x375cf
movq 0x198(%rsp), %rdi
callq 0x661d0
movq %rax, 0x90(%rsp)
jmp 0x375db
xorl %eax, %eax
movq %rax, 0x90(%rsp)
jmp 0x375db
movq 0x90(%rsp), %rax
movq %rax, 0x108(%rsp)
cmpq $0x0, 0x108(%rsp)
je 0x37620
movq 0x108(%rsp), %rdi
callq 0x3e7d0
cmpq $0x0, %rax
je 0x37620
movq 0x108(%rsp), %rdi
callq 0x3e7d0
movq %rax, 0x88(%rsp)
jmp 0x37631
leaq 0x20a4b7(%rip), %rax    # 0x241ade
movq %rax, 0x88(%rsp)
jmp 0x37631
movq 0x88(%rsp), %rax
movq %rax, 0x100(%rsp)
cmpq $0x0, 0x198(%rsp)
je 0x37663
movq 0x198(%rsp), %rdi
callq 0x662c0
movq %rax, 0x80(%rsp)
jmp 0x3766f
xorl %eax, %eax
movq %rax, 0x80(%rsp)
jmp 0x3766f
movq 0x80(%rsp), %rax
movq %rax, 0xf8(%rsp)
cmpq $0x0, 0xf8(%rsp)
je 0x376b1
movq 0xf8(%rsp), %rdi
callq 0x3e7d0
cmpq $0x0, %rax
je 0x376b1
movq 0xf8(%rsp), %rdi
callq 0x3e7d0
movq %rax, 0x78(%rsp)
jmp 0x376bf
leaq 0x20a426(%rip), %rax    # 0x241ade
movq %rax, 0x78(%rsp)
jmp 0x376bf
movq 0x78(%rsp), %rax
movq %rax, 0xf0(%rsp)
movq 0x1a8(%rsp), %rdi
callq 0x58f20
movl %eax, 0x74(%rsp)
movq 0x1a8(%rsp), %rdi
callq 0x2f260
movl 0x74(%rsp), %esi
movl %eax, %edx
movq 0x1a0(%rsp), %rcx
leaq 0x110(%rsp), %r8
movq 0x190(%rsp), %r9
movq 0xf0(%rsp), %r10
movq 0x100(%rsp), %rax
leaq 0x20a3c1(%rip), %rdi    # 0x241ae0
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x28090
movq 0x1a8(%rsp), %rdi
callq 0x3e7e0
movq %rax, 0x1a8(%rsp)
jmp 0x37485
jmp 0x3774b
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e7f0
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x209d80(%rip), %xmm0   # 0x2414f0
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x1d0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e7f0
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x209db6(%rip), %xmm0   # 0x241558
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x1d0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3ded0
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x209d1c(%rip), %xmm0   # 0x2414f0
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x1c8(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3ded0
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x209d52(%rip), %xmm0   # 0x241558
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x1c8(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e750
movq %rax, %rdi
callq 0x3d380
cmpl $0x0, %eax
jne 0x378d3
movq 0xc8(%rsp), %rdi
callq 0x3e750
movq %rax, %rsi
leaq 0xe0(%rsp), %rdi
callq 0x1a6080
cmpl $0x2c, 0x214(%rsp)
jne 0x37888
leaq 0xe0(%rsp), %rdi
callq 0x3e830
movaps %xmm0, %xmm1
movsd 0x209c7b(%rip), %xmm0   # 0x2414f0
mulsd %xmm1, %xmm0
leaq 0xe0(%rsp), %rdi
callq 0x3e810
jmp 0x378bd
cmpl $0x2e, 0x214(%rsp)
jne 0x378bb
leaq 0xe0(%rsp), %rdi
callq 0x3e830
movaps %xmm0, %xmm1
movsd 0x209cae(%rip), %xmm0   # 0x241558
mulsd %xmm1, %xmm0
leaq 0xe0(%rsp), %rdi
callq 0x3e810
jmp 0x378bd
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
leaq 0xe0(%rsp), %rsi
callq *0x78(%rax)
jmp 0x37b1b
movl 0x214(%rsp), %eax
movsd 0x209c79(%rip), %xmm0   # 0x241560
movsd 0x209cb9(%rip), %xmm1   # 0x2415a8
movsd %xmm1, 0x60(%rsp)
cmpl $0x7b, %eax
movsd %xmm0, 0x68(%rsp)
je 0x3790c
movsd 0x60(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
movq 0xc8(%rsp), %rdi
movsd 0x68(%rsp), %xmm0
movsd %xmm0, 0xd8(%rsp)
movsd 0xd8(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
callq 0x3e840
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x58(%rsp), %xmm0
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x90(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rax
cmpq $0x0, 0x2d0(%rax)
je 0x37986
movq 0xc8(%rsp), %rax
movq 0x2d0(%rax), %rdi
callq 0x3e860
movl %eax, 0x54(%rsp)
jmp 0x3798e
xorl %eax, %eax
movl %eax, 0x54(%rsp)
jmp 0x3798e
movl 0x54(%rsp), %eax
movl %eax, 0xd4(%rsp)
cmpl $0x3e, 0x214(%rsp)
jne 0x379b6
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x379d3
cmpl $0x3c, 0x214(%rsp)
jne 0x379d1
movl 0xd4(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x379d3
cmpl $0x0, 0xd4(%rsp)
jge 0x379e8
movl $0x0, 0xd4(%rsp)
movq 0xc8(%rsp), %rax
movl 0xd4(%rsp), %ecx
movl %ecx, 0x50(%rsp)
movq 0x8(%rax), %rdi
callq 0x2f000
movl %eax, %ecx
movl 0x50(%rsp), %eax
subl $0x1, %ecx
cmpl %ecx, %eax
jle 0x37a2c
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x2f000
subl $0x1, %eax
movl %eax, 0xd4(%rsp)
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rdi
movl 0xd4(%rsp), %esi
callq 0x2f840
movq 0xc8(%rsp), %rdi
movq %rax, %rsi
movq (%rdi), %rax
xorl %ecx, %ecx
movl %ecx, %edx
callq *0x1c0(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e870
movq 0xc8(%rsp), %rdi
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %esi
movq (%rdi), %rax
callq *0x1d8(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e870
movq 0xc8(%rsp), %rdi
movl %eax, %esi
shll %esi
movq (%rdi), %rax
callq *0x1d8(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e890
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x209a8e(%rip), %xmm0   # 0x241560
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x98(%rax)
jmp 0x37b1b
movq 0xc8(%rsp), %rdi
callq 0x3e890
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x209a97(%rip), %xmm0   # 0x241598
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x98(%rax)
jmp 0x37b1b
movl $0x0, 0x208(%rsp)
jmp 0x37fce
cmpl $0x0, 0x20c(%rsp)
je 0x37bc9
movl 0x214(%rsp), %eax
addl $-0x4d, %eax
movl %eax, %ecx
movq %rcx, 0x48(%rsp)
subl $0x25, %eax
ja 0x37bb9
movq 0x48(%rsp), %rax
leaq 0x209bd0(%rip), %rcx    # 0x241720
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xc8(%rsp), %rax
movsd 0x2094cf(%rip), %xmm0   # 0x241038
ucomisd 0x2d8(%rax), %xmm0
jbe 0x37b8e
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movsd 0x2099da(%rip), %xmm0   # 0x241560
callq *0x88(%rax)
jmp 0x37ba7
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
movsd 0x2099ff(%rip), %xmm0   # 0x2415a0
callq *0x88(%rax)
jmp 0x37bc4
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
callq *0x50(%rax)
jmp 0x37bc4
movl $0x0, 0x208(%rsp)
jmp 0x37fcc
movl 0x214(%rsp), %eax
addl $0xfffffbfe, %eax       # imm = 0xFFFFFBFE
movl %eax, %ecx
movq %rcx, 0x40(%rsp)
subl $0x2d, %eax
ja 0x37fbf
movq 0x40(%rsp), %rax
leaq 0x209a77(%rip), %rcx    # 0x241668
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xc8(%rsp), %rdi
movl 0x214(%rsp), %eax
subl $0x428, %eax            # imm = 0x428
addl $0x1, %eax
movl %eax, 0xd0(%rsp)
cvtsi2sdl 0xd0(%rsp), %xmm1
movsd 0x209947(%rip), %xmm0   # 0x241570
mulsd %xmm1, %xmm0
cvtsi2sdl 0xd0(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0x209906(%rip), %xmm1   # 0x241548
addsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x60(%rax)
jmp 0x37fca
movq 0xc8(%rsp), %rax
cmpq $0x0, 0x2d0(%rax)
je 0x37c82
movq 0xc8(%rsp), %rdi
movq 0x2d0(%rdi), %rsi
movq (%rdi), %rax
movl $0x1, %ecx
movl %ecx, %edx
callq *0x1c0(%rax)
jmp 0x37fca
movq 0xc8(%rsp), %rdi
movq (%rdi), %rax
callq *0x50(%rax)
jmp 0x37fca
movq 0xc8(%rsp), %rdi
callq 0x3e8b0
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x2098a6(%rip), %xmm0   # 0x241560
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x88(%rax)
jmp 0x37fca
movq 0xc8(%rsp), %rdi
callq 0x3e8b0
movq 0xc8(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x2098ac(%rip), %xmm0   # 0x241598
mulsd %xmm1, %xmm0
movq (%rdi), %rax
callq *0x88(%rax)
jmp 0x37fca
movq 0xc8(%rsp), %rdi
addq $0x120, %rdi            # imm = 0x120
callq 0x2f3f0
cmpl $0x0, %eax
je 0x37d3f
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x3d7d0
movq 0xc8(%rsp), %rdi
movq %rax, %rsi
addq $0x120, %rdi            # imm = 0x120
callq 0x3e8d0
cmpl $0x0, 0x210(%rsp)
je 0x37dab
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x3d7d0
movq %rax, %rdi
callq 0x3e930
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x38(%rsp)
addq $0x120, %rdi            # imm = 0x120
xorl %esi, %esi
callq 0x3e950
movq %rax, %rdi
movl $0x2, %esi
callq 0x3e410
movsd 0x38(%rsp), %xmm0
movsd (%rax), %xmm1
movsd 0x20928b(%rip), %xmm2   # 0x241028
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
jmp 0x37e0e
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x3d7d0
movq %rax, %rdi
callq 0x3e930
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x30(%rsp)
addq $0x120, %rdi            # imm = 0x120
movl $0x1, %esi
callq 0x3e950
movq %rax, %rdi
movl $0x2, %esi
callq 0x3e410
movsd 0x30(%rsp), %xmm0
movsd (%rax), %xmm1
movsd 0x209226(%rip), %xmm2   # 0x241028
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq 0xc8(%rsp), %rax
movq %rax, %rcx
addq $0x120, %rcx            # imm = 0x120
movq %rcx, 0x28(%rsp)
movq 0x8(%rax), %rdi
callq 0x3d7d0
movq 0x28(%rsp), %rdi
movq %rax, %rsi
callq 0xef350
cmpl $0x0, %eax
je 0x37e5b
movq 0xc8(%rsp), %rdi
addq $0x120, %rdi            # imm = 0x120
leaq 0x29d252(%rip), %rsi    # 0x2d50a8
callq 0x3e8d0
jmp 0x37fca
movq 0xc8(%rsp), %rdi
addq $0x120, %rdi            # imm = 0x120
callq 0x2f3f0
cmpl $0x0, %eax
je 0x37ea1
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x3d7d0
movq 0xc8(%rsp), %rdi
movq %rax, %rsi
addq $0x120, %rdi            # imm = 0x120
callq 0x3e8d0
cmpl $0x0, 0x210(%rsp)
je 0x37f0d
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x3d7d0
movq %rax, %rdi
callq 0x3e930
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x20(%rsp)
addq $0x120, %rdi            # imm = 0x120
xorl %esi, %esi
callq 0x3e950
movq %rax, %rdi
movl $0x2, %esi
callq 0x3e410
movsd 0x20(%rsp), %xmm0
movsd (%rax), %xmm1
movsd 0x209691(%rip), %xmm2   # 0x241590
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
jmp 0x37f70
movq 0xc8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x3d7d0
movq %rax, %rdi
callq 0x3e930
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x18(%rsp)
addq $0x120, %rdi            # imm = 0x120
movl $0x1, %esi
callq 0x3e950
movq %rax, %rdi
movl $0x2, %esi
callq 0x3e410
movsd 0x18(%rsp), %xmm0
movsd (%rax), %xmm1
movsd 0x20962c(%rip), %xmm2   # 0x241590
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq 0xc8(%rsp), %rax
movq %rax, %rcx
addq $0x120, %rcx            # imm = 0x120
movq %rcx, 0x10(%rsp)
movq 0x8(%rax), %rdi
callq 0x3d7d0
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0xef350
cmpl $0x0, %eax
je 0x37fbd
movq 0xc8(%rsp), %rdi
addq $0x120, %rdi            # imm = 0x120
leaq 0x29d0f0(%rip), %rsi    # 0x2d50a8
callq 0x3e8d0
jmp 0x37fca
movl $0x0, 0x208(%rsp)
jmp 0x37fcc
jmp 0x37fce
movq 0xc8(%rsp), %rax
movl 0x21c(%rsp), %ecx
movl %ecx, 0x4a8(%rax)
movl 0x218(%rsp), %ecx
movl %ecx, 0x4ac(%rax)
movl 0x210(%rsp), %ecx
movl %ecx, 0x4bc(%rax)
movl 0x20c(%rsp), %ecx
movl %ecx, 0x4c0(%rax)
movl 0x230(%rsp), %ecx
movl %ecx, 0x4c4(%rax)
movl 0x208(%rsp), %eax
addq $0x228, %rsp            # imm = 0x228
retq
nopw %cs:(%rax,%rax)