// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/apps/gapsview/gapsview.cpp
// Function: GLUTKeyboard(unsigned char, int, int)
static void
GLUTKeyboard(unsigned char key, int x, int y)
{
  // Initialize redraw
  RNBoolean redraw = TRUE;

  // Determine modifiers
  int modifiers = glutGetModifiers();
  int ctrl = (modifiers & GLUT_ACTIVE_CTRL);
  int alt = (modifiers & GLUT_ACTIVE_ALT);

  // Process keyboard button event
  if (ctrl) {
    // Control which data sources are drawn
    switch(key) {
    case 7: // ctrl-G
      show_grids = !show_grids;
      break;

    case 12: // ctrl-L
      show_gsvs = !show_gsvs;
      break;

    case 13: // ctrl-M
      show_meshes = !show_meshes;
      break;

    case 15: // ctrl-O
      show_scenes = !show_scenes;
      break;

    case 16: // ctrl-P
      show_pointsets = !show_pointsets;
      break;

    case 19: // ctrl-S
      show_sfls = !show_sfls;
      break;

    default:
      redraw = FALSE;
      break;
    }
  }
  else if (alt) {
    // Control how things are drawn
    switch (key) {
    case 'C':
    case 'c':
      color_scheme = RGB_COLOR_SCHEME;
      break;

    case 'E':
    case 'e':
      color_scheme = NULL_COLOR_SCHEME;
      break;

    case 'I':
    case 'i':
      color_scheme = INSTANCE_COLOR_SCHEME;
      break;

    case 'L':
    case 'l':
      color_scheme = CATEGORY_COLOR_SCHEME;
      break;

    case 'S':
    case 's':
      color_scheme = SHADING_COLOR_SCHEME;
      break;

    case 'X':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_X]++;
        if (grid_slice_coords[RN_X] >= grids[selected_model_index]->XResolution()) 
          grid_slice_coords[RN_X] = grids[selected_model_index]->XResolution() - 1;
      }
      break;

    case 'x':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_X]--;
        if (grid_slice_coords[RN_X] < 0)
          grid_slice_coords[RN_X] = 0;
      }
      break;

    case 'Y':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_Y]++;
        if (grid_slice_coords[RN_Y] >= grids[selected_model_index]->YResolution()) 
          grid_slice_coords[RN_Y] = grids[selected_model_index]->YResolution() - 1;
      }
      break;

    case 'y':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_Y]--;
        if (grid_slice_coords[RN_Y] < 0)
          grid_slice_coords[RN_Y] = 0;
      }
      break;

    case 'Z':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_Z]++;
        if (grid_slice_coords[RN_Z] >= grids[selected_model_index]->ZResolution()) 
          grid_slice_coords[RN_Z] = grids[selected_model_index]->ZResolution() - 1;
      }
      break;

    case 'z':
      if (selected_model_index < grids.NEntries()) {
        grid_slice_coords[RN_Z]--;
        if (grid_slice_coords[RN_Z] < 0)
          grid_slice_coords[RN_Z] = 0;
      }
      break;

    default:
      redraw = FALSE;
      break;
    }
  }
  else {
    // Control which data elements are drawn
    switch (key) {
    case '1':
    case '2':
    case '3':
    case '4':
      selected_model_index = key - '1';
      if (selected_model_index > nmodels - 1) {
        selected_model_index = nmodels - 1;
      }
      break;

    case 'A':
    case 'a':
      show_axes = !show_axes;
      break;

    case 'B':
    case 'b':
      show_bbox = !show_bbox;
      break;

    case 'C':
    case 'c':
      show_cameras = !show_cameras;
      break;

    case 'D':
    case 'd':
      show_image_depths = !show_image_depths;
      break;
      
    case 'E':
    case 'e':
      show_edges = !show_edges;
      break;

    case 'F':
    case 'f':
      show_surfaces = !show_surfaces;
      break;

    case 'G':
    case 'g':
      show_slices = !show_slices;
      break;

    case 'I':
      show_image_billboards = !show_image_billboards;
      break;

    case 'i':
      show_image_insets = !show_image_insets;
      break;

    case 'L':
    case 'l':
      show_text_labels = !show_text_labels;
      break;

    case 'N':
    case 'n':
      show_normals = !show_normals;
      break;

    case 'P':
    case 'p':
      show_points = !show_points;
      break;

    case 'R':
    case 'r':
      show_image_rays = !show_image_rays;
      break;

    case 'T':
    case 't':
      show_grid_threshold = !show_grid_threshold;
      break;

    case ' ': {
      // Print camera
      const R3Camera& camera = viewer->Camera();
      printf("#camera  %g %g %g  %g %g %g  %g %g %g  %g \n",
             camera.Origin().X(), camera.Origin().Y(), camera.Origin().Z(),
             camera.Towards().X(), camera.Towards().Y(), camera.Towards().Z(),
             camera.Up().X(), camera.Up().Y(), camera.Up().Z(),
             camera.YFOV());
      break; }
      
    case 27: // ESCAPE
      GLUTStop();
      break;

    default:
      redraw = FALSE;
      break;
    }
  }
  
  // Remember mouse position 
  GLUTmouse[0] = x;
  GLUTmouse[1] = GLUTwindow_height - y;

  // Remember modifiers 
  GLUTmodifiers = modifiers;

  // Redraw
  if (redraw) glutPostRedisplay();  
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x80, %rsp
movl %edx, %ebx
movl %esi, %ebp
movl %edi, %r14d
callq 0x113de1
testb $0x2, %al
jne 0x2dade
testb $0x4, %al
jne 0x2db15
movzbl %r14b, %ecx
leal -0x31(%rcx), %eax
cmpl $0x43, %eax
ja 0x2dec5
leaq 0x11e750(%rip), %rcx    # 0x14c204
movslq (%rcx,%rax,4), %rdx
addq %rcx, %rdx
jmpq *%rdx
movl %eax, 0x1ad6c1(%rip)    # 0x1db184
movl 0x1ad8fb(%rip), %ecx    # 0x1db3c4
cmpl %ecx, %eax
jl 0x2dfed
decl %ecx
movl %ecx, 0x1ad6ab(%rip)    # 0x1db184
jmp 0x2dfed
movzbl %r14b, %eax
addl $-0x7, %eax
cmpl $0xc, %eax
ja 0x2ded3
leaq 0x11e64b(%rip), %rcx    # 0x14c140
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %eax, %eax
cmpl $0x0, 0x1a7f8d(%rip)    # 0x1d5a94
sete %al
movl %eax, 0x1a7f84(%rip)    # 0x1d5a94
jmp 0x2dfed
movzbl %r14b, %eax
cmpl $0x62, %eax
jg 0x2db8d
leal -0x43(%rax), %ecx
cmpl $0x9, %ecx
jbe 0x2dc37
addl $-0x53, %eax
cmpl $0x7, %eax
ja 0x2ded3
leaq 0x11e65f(%rip), %rcx    # 0x14c19c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movslq 0x1ad637(%rip), %rax    # 0x1db184
cmpl 0x1ad181(%rip), %eax    # 0x1dacd4
jge 0x2dfed
movl 0x1ad601(%rip), %ecx    # 0x1db160
incl %ecx
movl %ecx, 0x1ad5f9(%rip)    # 0x1db160
movq 0x1ad15a(%rip), %rdx    # 0x1dacc8
movq (%rdx,%rax,8), %rax
movl 0x238(%rax), %eax
cmpl %eax, %ecx
jl 0x2dfed
decl %eax
movl %eax, 0x1ad5d8(%rip)    # 0x1db160
jmp 0x2dfed
leal -0x63(%rax), %ecx
cmpl $0x9, %ecx
jbe 0x2dc47
addl $-0x73, %eax
cmpl $0x7, %eax
ja 0x2ded3
leaq 0x11e638(%rip), %rcx    # 0x14c1e4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x2, 0x1a7ec1(%rip)    # 0x1d5a80
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1a7ec3(%rip)    # 0x1d5a90
sete %al
movl %eax, 0x1a7eba(%rip)    # 0x1d5a90
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1a7eb4(%rip)    # 0x1d5a98
sete %al
movl %eax, 0x1a7eab(%rip)    # 0x1d5a98
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1a7ea5(%rip)    # 0x1d5aa0
sete %al
movl %eax, 0x1a7e9c(%rip)    # 0x1d5aa0
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1a7e7a(%rip)    # 0x1d5a8c
sete %al
movl %eax, 0x1a7e71(%rip)    # 0x1d5a8c
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1a7e5b(%rip)    # 0x1d5a84
sete %al
movl %eax, 0x1a7e52(%rip)    # 0x1d5a84
jmp 0x2dfed
leaq 0x11e536(%rip), %rax    # 0x14c174
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
leaq 0x11e56e(%rip), %rax    # 0x14c1bc
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movl $0x1, 0x1a7e1f(%rip)    # 0x1d5a80
jmp 0x2dfed
movl $0x4, 0x1a7e10(%rip)    # 0x1d5a80
jmp 0x2dfed
movl $0x0, 0x1a7e01(%rip)    # 0x1d5a80
jmp 0x2dfed
movl $0x3, 0x1a7df2(%rip)    # 0x1d5a80
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad71c(%rip)    # 0x1db3b8
sete %al
movl %eax, 0x1ad713(%rip)    # 0x1db3b8
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad4d9(%rip)    # 0x1db18c
sete %al
movl %eax, 0x1ad4d0(%rip)    # 0x1db18c
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad4be(%rip)    # 0x1db188
sete %al
movl %eax, 0x1ad4b5(%rip)    # 0x1db188
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad6df(%rip)    # 0x1db3c0
sete %al
movl %eax, 0x1ad6d6(%rip)    # 0x1db3c0
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad6bc(%rip)    # 0x1db3b4
sete %al
movl %eax, 0x1ad6b3(%rip)    # 0x1db3b4
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad691(%rip)    # 0x1db3a0
sete %al
movl %eax, 0x1ad688(%rip)    # 0x1db3a0
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1a7d76(%rip)    # 0x1d5a9c
sete %al
movl %eax, 0x1a7d6d(%rip)    # 0x1d5a9c
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad67f(%rip)    # 0x1db3bc
sete %al
movl %eax, 0x1ad676(%rip)    # 0x1db3bc
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad43c(%rip)    # 0x1db190
sete %al
movl %eax, 0x1ad433(%rip)    # 0x1db190
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad63d(%rip)    # 0x1db3a8
sete %al
movl %eax, 0x1ad634(%rip)    # 0x1db3a8
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1a7d06(%rip)    # 0x1d5a88
sete %al
movl %eax, 0x1a7cfd(%rip)    # 0x1d5a88
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad60b(%rip)    # 0x1db3a4
sete %al
movl %eax, 0x1ad602(%rip)    # 0x1db3a4
jmp 0x2dfed
movslq 0x1ad3d6(%rip), %rax    # 0x1db184
cmpl 0x1acf20(%rip), %eax    # 0x1dacd4
jge 0x2dfed
movl 0x1ad3a4(%rip), %ecx    # 0x1db164
incl %ecx
movl %ecx, 0x1ad39c(%rip)    # 0x1db164
movq 0x1acef9(%rip), %rdx    # 0x1dacc8
movq (%rdx,%rax,8), %rax
movl 0x23c(%rax), %eax
cmpl %eax, %ecx
jl 0x2dfed
decl %eax
movl %eax, 0x1ad37b(%rip)    # 0x1db164
jmp 0x2dfed
movl 0x1ad390(%rip), %eax    # 0x1db184
cmpl 0x1aceda(%rip), %eax    # 0x1dacd4
jge 0x2dfed
movl 0x1ad35e(%rip), %eax    # 0x1db164
cmpl $0x2, %eax
movl $0x1, %ecx
cmovgel %eax, %ecx
decl %ecx
movl %ecx, 0x1ad34b(%rip)    # 0x1db164
jmp 0x2dfed
movl 0x1ad360(%rip), %eax    # 0x1db184
cmpl 0x1aceaa(%rip), %eax    # 0x1dacd4
jge 0x2dfed
movl 0x1ad32a(%rip), %eax    # 0x1db160
cmpl $0x2, %eax
movl $0x1, %ecx
cmovgel %eax, %ecx
decl %ecx
movl %ecx, 0x1ad317(%rip)    # 0x1db160
jmp 0x2dfed
movslq 0x1ad32f(%rip), %rax    # 0x1db184
cmpl 0x1ace79(%rip), %eax    # 0x1dacd4
jge 0x2dfed
movl 0x1ad301(%rip), %ecx    # 0x1db168
incl %ecx
movl %ecx, 0x1ad2f9(%rip)    # 0x1db168
movq 0x1ace52(%rip), %rdx    # 0x1dacc8
movq (%rdx,%rax,8), %rax
movl 0x240(%rax), %eax
cmpl %eax, %ecx
jl 0x2dfed
decl %eax
movl %eax, 0x1ad2d8(%rip)    # 0x1db168
jmp 0x2dfed
movl 0x1ad2e9(%rip), %eax    # 0x1db184
cmpl 0x1ace33(%rip), %eax    # 0x1dacd4
jge 0x2dfed
movl 0x1ad2bb(%rip), %eax    # 0x1db168
cmpl $0x2, %eax
movl $0x1, %ecx
cmovgel %eax, %ecx
decl %ecx
movl %ecx, 0x1ad2a8(%rip)    # 0x1db168
jmp 0x2dfed
cmpl $0x20, %ecx
je 0x2df1a
cmpl $0x1b, %ecx
je 0x2e016
movl %ebp, 0x1ad4ef(%rip)    # 0x1db3c8
movl 0x1a7b15(%rip), %eax    # 0x1d59f4
subl %ebx, %eax
movl %eax, 0x1ad4e5(%rip)    # 0x1db3cc
jmp 0x2e006
xorl %eax, %eax
cmpl $0x0, 0x1ad4bb(%rip)    # 0x1db3b0
sete %al
movl %eax, 0x1ad4b2(%rip)    # 0x1db3b0
jmp 0x2dfed
xorl %eax, %eax
cmpl $0x0, 0x1ad4a0(%rip)    # 0x1db3ac
sete %al
movl %eax, 0x1ad497(%rip)    # 0x1db3ac
jmp 0x2dfed
movq 0x1ad24f(%rip), %r12    # 0x1db170
movsd 0x8(%r12), %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x10(%r12), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x18(%r12), %xmm0
movsd %xmm0, 0x20(%rsp)
leaq 0x50(%r12), %r14
leaq 0x68(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0xd5aac
movsd (%r15), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x50(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0xd5aac
movsd 0x8(%r15), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x38(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0xd5aac
movsd 0x10(%r15), %xmm5
movsd 0x38(%r12), %xmm6
movsd 0x40(%r12), %xmm7
movsd 0x48(%r12), %xmm0
movsd 0x70(%r12), %xmm1
movsd %xmm1, 0x8(%rsp)
movsd %xmm0, (%rsp)
leaq 0x11e454(%rip), %rdi    # 0x14c41c
movsd 0x30(%rsp), %xmm0
movsd 0x28(%rsp), %xmm1
movsd 0x20(%rsp), %xmm2
movsd 0x18(%rsp), %xmm3
movsd 0x10(%rsp), %xmm4
movb $0x8, %al
callq 0x27080
movl %ebp, 0x1ad3d5(%rip)    # 0x1db3c8
movl 0x1a79fb(%rip), %eax    # 0x1d59f4
subl %ebx, %eax
movl %eax, 0x1ad3cb(%rip)    # 0x1db3cc
callq 0x10ef28
addq $0x80, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
callq 0x322d4