// File: tomfunkhouser[P]gaps/apps/mshview/mshview.cpp
// Function: GLUTKeyboard(unsigned char, int, int)
void GLUTKeyboard(unsigned char key, int x, int y)
{
  // Invert y coordinate
  y = GLUTwindow_height - y;

  // Process keyboard button event 
  switch (key) {
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
    if (key == '0') current_mesh = -1;
    else if (key - '1' < meshes.NEntries()) current_mesh = key - '1';
    else printf("Unable to select mesh %d\n", key - '1');
    break;

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

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

  case 'C': 
  case 'c':
    show_vertex_colors = !show_vertex_colors;
    break;
    
  case 'E':
    show_edge_names = !show_edge_names;
    break;

  case 'e':
    show_edges = !show_edges;
    break;

  case 'F':
    show_face_names = !show_face_names;
    break;

  case 'f':
    show_faces = !show_faces;
    break;

  case 'L':
    show_category_names = !show_category_names;
    break;

  case 'l':
    show_categories = !show_categories;
    break;

  case 'M':
    show_material_names = !show_material_names;
    break;

  case 'm':
    show_materials = !show_materials;
    break;

  case 'N':
    show_vertex_normals = !show_vertex_normals;
    break;

  case 'n':
    show_face_normals = !show_face_normals;
    break;

  case 'O':
  case 'o':
    show_world_origin = !show_world_origin;
    break;

  case 'S':
    show_segment_names = !show_segment_names;
    break;

  case 's':
    show_segments = !show_segments;
    break;

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

  case 'V':
    show_vertex_names = !show_vertex_names;
    break;

  case 'v':
    show_vertices = !show_vertices;
    break;

  case 'X':
  case 'x':
    show_boundaries = !show_boundaries;
    break;

  case ' ': {
    // Print camera
    const R3Camera& camera = viewer->Camera();
    RNFail("%g %g %g  %g %g %g  %g %g %g  %g %g  1\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.XFOV(), camera.YFOV());
    printf("%g %g %g  %g %g %g  %g %g %g  %g %g  1\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.XFOV(), camera.YFOV());
    break; }
      
  case 16:  // ctrl-P
    image_name = "mshview.png";
    break; 

  case 27: // ESCAPE
    GLUTStop();
    break;
  }

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

  // Remember modifiers 
  GLUTmodifiers = glutGetModifiers();

  // Redraw
  glutPostRedisplay();  
}

// Assembly:
subq $0x178, %rsp            # imm = 0x178
movb %dil, %al
movb %al, 0x177(%rsp)
movl %esi, 0x170(%rsp)
movl %edx, 0x16c(%rsp)
movl 0x1cb9b7(%rip), %eax    # 0x1f4abc
movl 0x16c(%rsp), %ecx
subl %ecx, %eax
movl %eax, 0x16c(%rsp)
movzbl 0x177(%rsp), %eax
addl $-0x10, %eax
movl %eax, %ecx
movq %rcx, 0xc8(%rsp)
subl $0x68, %eax
ja 0x29789
movq 0xc8(%rsp), %rax
leaq 0x163f52(%rip), %rcx    # 0x18d094
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl 0x177(%rsp), %eax
cmpl $0x30, %eax
jne 0x29164
movl $0xffffffff, 0x1cb94e(%rip) # imm = 0xFFFFFFFF
jmp 0x291bd
movzbl 0x177(%rsp), %eax
subl $0x31, %eax
movl %eax, 0xc4(%rsp)
leaq 0x1d1a9b(%rip), %rdi    # 0x1fac18
callq 0x2a760
movl %eax, %ecx
movl 0xc4(%rsp), %eax
cmpl %ecx, %eax
jge 0x291a2
movzbl 0x177(%rsp), %eax
subl $0x31, %eax
movl %eax, 0x1cb910(%rip)    # 0x1f4ab0
jmp 0x291bb
movzbl 0x177(%rsp), %esi
subl $0x31, %esi
leaq 0x164084(%rip), %rdi    # 0x18d238
movb $0x0, %al
callq 0x22090
jmp 0x291bd
jmp 0x29789
cmpl $0x0, 0x1d218b(%rip)    # 0x1fb354
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d217b(%rip)    # 0x1fb354
jmp 0x29789
cmpl $0x0, 0x1d212b(%rip)    # 0x1fb310
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d211b(%rip)    # 0x1fb310
jmp 0x29789
cmpl $0x0, 0x1d211f(%rip)    # 0x1fb320
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d210f(%rip)    # 0x1fb320
jmp 0x29789
cmpl $0x0, 0x1d211f(%rip)    # 0x1fb33c
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d210f(%rip)    # 0x1fb33c
jmp 0x29789
cmpl $0x0, 0x1d20eb(%rip)    # 0x1fb324
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d20db(%rip)    # 0x1fb324
jmp 0x29789
cmpl $0x0, 0x1d20e3(%rip)    # 0x1fb338
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d20d3(%rip)    # 0x1fb338
jmp 0x29789
cmpl $0x0, 0x1cb843(%rip)    # 0x1f4ab4
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1cb833(%rip)    # 0x1f4ab4
jmp 0x29789
cmpl $0x0, 0x1d20bf(%rip)    # 0x1fb34c
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d20af(%rip)    # 0x1fb34c
jmp 0x29789
cmpl $0x0, 0x1d2073(%rip)    # 0x1fb31c
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2063(%rip)    # 0x1fb31c
jmp 0x29789
cmpl $0x0, 0x1d207f(%rip)    # 0x1fb344
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d206f(%rip)    # 0x1fb344
jmp 0x29789
cmpl $0x0, 0x1d2033(%rip)    # 0x1fb314
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2023(%rip)    # 0x1fb314
jmp 0x29789
cmpl $0x0, 0x1d2037(%rip)    # 0x1fb334
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2027(%rip)    # 0x1fb334
jmp 0x29789
cmpl $0x0, 0x1d2017(%rip)    # 0x1fb330
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2007(%rip)    # 0x1fb330
jmp 0x29789
cmpl $0x0, 0x1d201b(%rip)    # 0x1fb350
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d200b(%rip)    # 0x1fb350
jmp 0x29789
cmpl $0x0, 0x1d1ff7(%rip)    # 0x1fb348
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d1fe7(%rip)    # 0x1fb348
jmp 0x29789
cmpl $0x0, 0x1d1fab(%rip)    # 0x1fb318
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d1f9b(%rip)    # 0x1fb318
jmp 0x29789
cmpl $0x0, 0x1d200b(%rip)    # 0x1fb394
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d1ffb(%rip)    # 0x1fb394
jmp 0x29789
cmpl $0x0, 0x1d1f9b(%rip)    # 0x1fb340
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d1f8b(%rip)    # 0x1fb340
jmp 0x29789
cmpl $0x0, 0x1d1f6b(%rip)    # 0x1fb32c
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d1f5b(%rip)    # 0x1fb32c
jmp 0x29789
cmpl $0x0, 0x1d1f4b(%rip)    # 0x1fb328
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d1f3b(%rip)    # 0x1fb328
jmp 0x29789
movq 0x1d1f0f(%rip), %rdi    # 0x1fb308
callq 0x2a770
movq %rax, 0x160(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2ae00
movq %rax, %rdi
callq 0x2ae10
movsd %xmm0, 0x68(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2ae00
movq %rax, %rdi
callq 0x2ae20
movsd %xmm0, 0x20(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2ae00
movq %rax, %rdi
callq 0x2ae30
movsd %xmm0, 0x28(%rsp)
movq 0x160(%rsp), %rsi
leaq 0x148(%rsp), %rdi
callq 0x2ae40
leaq 0x148(%rsp), %rdi
callq 0x2ae90
movsd %xmm0, 0x30(%rsp)
movq 0x160(%rsp), %rsi
leaq 0x130(%rsp), %rdi
callq 0x2ae40
leaq 0x130(%rsp), %rdi
callq 0x2aea0
movsd %xmm0, 0x38(%rsp)
movq 0x160(%rsp), %rsi
leaq 0x118(%rsp), %rdi
callq 0x2ae40
leaq 0x118(%rsp), %rdi
callq 0x2aeb0
movsd %xmm0, 0x40(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aec0
movq %rax, %rdi
callq 0x2ae90
movsd %xmm0, 0x48(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aec0
movq %rax, %rdi
callq 0x2aea0
movsd %xmm0, 0x50(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aec0
movq %rax, %rdi
callq 0x2aeb0
movsd %xmm0, 0x58(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aee0
movsd %xmm0, 0x60(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aef0
movsd 0x20(%rsp), %xmm1
movsd 0x28(%rsp), %xmm2
movsd 0x30(%rsp), %xmm3
movsd 0x38(%rsp), %xmm4
movsd 0x40(%rsp), %xmm5
movsd 0x48(%rsp), %xmm6
movsd 0x50(%rsp), %xmm7
movsd 0x58(%rsp), %xmm10
movsd 0x60(%rsp), %xmm9
movaps %xmm0, %xmm8
movsd 0x68(%rsp), %xmm0
leaq 0x163cc9(%rip), %rdi    # 0x18d252
movsd %xmm10, (%rsp)
movsd %xmm9, 0x8(%rsp)
movsd %xmm8, 0x10(%rsp)
movb $0x8, %al
callq 0xf2d20
movq 0x160(%rsp), %rdi
callq 0x2ae00
movq %rax, %rdi
callq 0x2ae10
movsd %xmm0, 0xb8(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2ae00
movq %rax, %rdi
callq 0x2ae20
movsd %xmm0, 0x70(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2ae00
movq %rax, %rdi
callq 0x2ae30
movsd %xmm0, 0x78(%rsp)
movq 0x160(%rsp), %rsi
leaq 0x100(%rsp), %rdi
callq 0x2ae40
leaq 0x100(%rsp), %rdi
callq 0x2ae90
movsd %xmm0, 0x80(%rsp)
movq 0x160(%rsp), %rsi
leaq 0xe8(%rsp), %rdi
callq 0x2ae40
leaq 0xe8(%rsp), %rdi
callq 0x2aea0
movsd %xmm0, 0x88(%rsp)
movq 0x160(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0x2ae40
leaq 0xd0(%rsp), %rdi
callq 0x2aeb0
movsd %xmm0, 0x90(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aec0
movq %rax, %rdi
callq 0x2ae90
movsd %xmm0, 0x98(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aec0
movq %rax, %rdi
callq 0x2aea0
movsd %xmm0, 0xa0(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aec0
movq %rax, %rdi
callq 0x2aeb0
movsd %xmm0, 0xa8(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aee0
movsd %xmm0, 0xb0(%rsp)
movq 0x160(%rsp), %rdi
callq 0x2aef0
movsd 0x70(%rsp), %xmm1
movsd 0x78(%rsp), %xmm2
movsd 0x80(%rsp), %xmm3
movsd 0x88(%rsp), %xmm4
movsd 0x90(%rsp), %xmm5
movsd 0x98(%rsp), %xmm6
movsd 0xa0(%rsp), %xmm7
movsd 0xa8(%rsp), %xmm10
movsd 0xb0(%rsp), %xmm9
movaps %xmm0, %xmm8
movsd 0xb8(%rsp), %xmm0
leaq 0x163afb(%rip), %rdi    # 0x18d252
movsd %xmm10, (%rsp)
movsd %xmm9, 0x8(%rsp)
movsd %xmm8, 0x10(%rsp)
movb $0x8, %al
callq 0x22090
jmp 0x29789
leaq 0x163aff(%rip), %rax    # 0x18d27a
movq %rax, 0x1d1bd6(%rip)    # 0x1fb358
jmp 0x29789
callq 0x278b0
movl 0x170(%rsp), %eax
movl %eax, 0x1d1bca(%rip)    # 0x1fb360
movl 0x16c(%rsp), %eax
movl %eax, 0x1d1bc1(%rip)    # 0x1fb364
callq 0x1813d0
movl %eax, 0x1d1be2(%rip)    # 0x1fb390
callq 0x1791a0
addq $0x178, %rsp            # imm = 0x178
retq
nopl (%rax,%rax)