// File: tomfunkhouser[P]gaps/apps/scnview/scnview.cpp
// Function: GLUTKeyboard(unsigned char, int, int)
void GLUTKeyboard(unsigned char key, int x, int y)
{
  // Process keyboard button event 
  switch (key) {
  case 'A':
  case 'a':
    show_axes = !show_axes;
    break;

  case 'B':
  case 'b':
    if (show_backfacing == 0) show_backfacing = 1;
    else show_backfacing = 0;
    break;

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

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

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

  case 'H':
  case 'h':
    show_bboxes = !show_bboxes;
    break;

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

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

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

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

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

  case 'V':
  case 'v':
    // Set camera
    if (cameras && (cameras->NEntries() > 0)) {
      if (key == 'v') selected_camera_index++;
      else if (key == 'V') selected_camera_index--;
      if (selected_camera_index < 0) selected_camera_index = 0;
      if (selected_camera_index >= cameras->NEntries()) selected_camera_index = cameras->NEntries()-1;
      viewer->SetCamera(*(cameras->Kth(selected_camera_index)));
    }
    else {
      viewer->SetCamera(scene->Camera());
    }

    // Set center
    if (1) {
      R3Point hit_point;
      R3Ray ray = viewer->WorldRay(GLUTwindow_width/2, GLUTwindow_height/2);
      if (scene->Intersects(ray, NULL, NULL, NULL, &hit_point)) center = hit_point;
    }
    break;

  case ' ': {
    // Print camera
    const R3Camera& camera = viewer->Camera();
    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 27: // ESCAPE
    GLUTStop();
    break;
  }

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

  // Remember modifiers 
  GLUTmodifiers = glutGetModifiers();

  // Redraw
  glutPostRedisplay();  
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movb %dil, %al
movb %al, 0x137(%rsp)
movl %esi, 0x130(%rsp)
movl %edx, 0x12c(%rsp)
movzbl 0x137(%rsp), %eax
addl $-0x1b, %eax
movl %eax, %ecx
movq %rcx, 0x88(%rsp)
subl $0x5b, %eax
ja 0x297c2
movq 0x88(%rsp), %rax
leaq 0x164d88(%rip), %rcx    # 0x18e0a4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x0, 0x1d2970(%rip)    # 0x1fbc9c
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2960(%rip)    # 0x1fbc9c
jmp 0x297c2
cmpl $0x0, 0x1d28d8(%rip)    # 0x1fbc20
jne 0x29356
movl $0x1, 0x1d28cc(%rip)    # 0x1fbc20
jmp 0x29360
movl $0x0, 0x1d28c0(%rip)    # 0x1fbc20
jmp 0x297c2
cmpl $0x0, 0x1d28c4(%rip)    # 0x1fbc30
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d28b4(%rip)    # 0x1fbc30
jmp 0x297c2
cmpl $0x0, 0x1d290c(%rip)    # 0x1fbc94
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d28fc(%rip)    # 0x1fbc94
jmp 0x297c2
cmpl $0x0, 0x1cc71c(%rip)    # 0x1f5ac0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1cc70c(%rip)    # 0x1f5ac0
jmp 0x297c2
cmpl $0x0, 0x1d28d8(%rip)    # 0x1fbc98
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d28c8(%rip)    # 0x1fbc98
jmp 0x297c2
cmpl $0x0, 0x1d2864(%rip)    # 0x1fbc40
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2854(%rip)    # 0x1fbc40
jmp 0x297c2
cmpl $0x0, 0x1d2908(%rip)    # 0x1fbd00
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d28f8(%rip)    # 0x1fbd00
jmp 0x297c2
cmpl $0x0, 0x1d2830(%rip)    # 0x1fbc44
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2820(%rip)    # 0x1fbc44
jmp 0x297c2
cmpl $0x0, 0x1d2818(%rip)    # 0x1fbc48
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2808(%rip)    # 0x1fbc48
jmp 0x297c2
cmpl $0x0, 0x1d2854(%rip)    # 0x1fbca0
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x1d2844(%rip)    # 0x1fbca0
jmp 0x297c2
cmpq $0x0, 0x1d27cf(%rip)    # 0x1fbc38
je 0x2953b
movq 0x1d27c2(%rip), %rdi    # 0x1fbc38
callq 0x2b8b0
cmpl $0x0, %eax
jle 0x2953b
movzbl 0x137(%rsp), %eax
cmpl $0x76, %eax
jne 0x294a2
movl 0x1cc635(%rip), %eax    # 0x1f5acc
addl $0x1, %eax
movl %eax, 0x1cc62c(%rip)    # 0x1f5acc
jmp 0x294c0
movzbl 0x137(%rsp), %eax
cmpl $0x56, %eax
jne 0x294be
movl 0x1cc617(%rip), %eax    # 0x1f5acc
addl $-0x1, %eax
movl %eax, 0x1cc60e(%rip)    # 0x1f5acc
jmp 0x294c0
cmpl $0x0, 0x1cc605(%rip)    # 0x1f5acc
jge 0x294d3
movl $0x0, 0x1cc5f9(%rip)    # 0x1f5acc
movl 0x1cc5f3(%rip), %eax    # 0x1f5acc
movl %eax, 0x84(%rsp)
movq 0x1d2751(%rip), %rdi    # 0x1fbc38
callq 0x2b8b0
movl %eax, %ecx
movl 0x84(%rsp), %eax
cmpl %ecx, %eax
jl 0x2950e
movq 0x1d2738(%rip), %rdi    # 0x1fbc38
callq 0x2b8b0
subl $0x1, %eax
movl %eax, 0x1cc5be(%rip)    # 0x1f5acc
movq 0x1d2713(%rip), %rax    # 0x1fbc28
movq %rax, 0x78(%rsp)
movq 0x1d2717(%rip), %rdi    # 0x1fbc38
movl 0x1cc5a5(%rip), %esi    # 0x1f5acc
callq 0x2b8c0
movq 0x78(%rsp), %rdi
movq %rax, %rsi
callq 0x5a440
jmp 0x29560
movq 0x1d26e6(%rip), %rax    # 0x1fbc28
movq %rax, 0x70(%rsp)
movq 0x1d26ca(%rip), %rdi    # 0x1fbc18
callq 0x2b8e0
movq 0x70(%rsp), %rdi
movq %rax, %rsi
callq 0x5a440
leaq 0x110(%rsp), %rdi
callq 0xcc860
movq 0x1d26b4(%rip), %rsi    # 0x1fbc28
movl 0x1cc54a(%rip), %eax    # 0x1f5ac4
movl $0x2, %ecx
cltd
idivl %ecx
cvtsi2sd %eax, %xmm0
movl 0x1cc53c(%rip), %eax    # 0x1f5ac8
movl $0x2, %ecx
cltd
idivl %ecx
cvtsi2sd %eax, %xmm1
leaq 0xe0(%rsp), %rdi
callq 0x5bca0
movq 0x1d266c(%rip), %rdi    # 0x1fbc18
leaq 0x1ccd05(%rip), %rax    # 0x1f62b8
movsd (%rax), %xmm1
leaq 0xe0(%rsp), %rsi
xorl %eax, %eax
movl %eax, %r8d
leaq 0x110(%rsp), %r9
xorps %xmm0, %xmm0
movq %r8, %rdx
movq %r8, %rcx
movq $0x0, (%rsp)
movq $0x0, 0x8(%rsp)
callq 0x2dd90
cmpl $0x0, %eax
je 0x29604
leaq 0x1d2601(%rip), %rdi    # 0x1fbbf8
leaq 0x110(%rsp), %rsi
callq 0xccf00
jmp 0x297c2
movq 0x1d2618(%rip), %rdi    # 0x1fbc28
callq 0x2b4d0
movq %rax, 0xd8(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x2b900
movq %rax, %rdi
callq 0x2b820
movsd %xmm0, 0x68(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x2b900
movq %rax, %rdi
callq 0x2b830
movsd %xmm0, 0x20(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x2b900
movq %rax, %rdi
callq 0x2b840
movsd %xmm0, 0x28(%rsp)
movq 0xd8(%rsp), %rsi
leaq 0xc0(%rsp), %rdi
callq 0x2b770
leaq 0xc0(%rsp), %rdi
callq 0x2b910
movsd %xmm0, 0x30(%rsp)
movq 0xd8(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x2b770
leaq 0xa8(%rsp), %rdi
callq 0x2b920
movsd %xmm0, 0x38(%rsp)
movq 0xd8(%rsp), %rsi
leaq 0x90(%rsp), %rdi
callq 0x2b770
leaq 0x90(%rsp), %rdi
callq 0x2b930
movsd %xmm0, 0x40(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x2b890
movq %rax, %rdi
callq 0x2b910
movsd %xmm0, 0x48(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x2b890
movq %rax, %rdi
callq 0x2b920
movsd %xmm0, 0x50(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x2b890
movq %rax, %rdi
callq 0x2b930
movsd %xmm0, 0x58(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x2b940
movsd %xmm0, 0x60(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x2b950
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 0x164aa7(%rip), %rdi    # 0x18e247
movsd %xmm10, (%rsp)
movsd %xmm9, 0x8(%rsp)
movsd %xmm8, 0x10(%rsp)
movb $0x8, %al
callq 0x22090
jmp 0x297c2
callq 0x26e00
movl 0x130(%rsp), %eax
movl %eax, 0x1d24f9(%rip)    # 0x1fbcc8
movl 0x1cc2f3(%rip), %eax    # 0x1f5ac8
subl 0x12c(%rsp), %eax
movl %eax, 0x1d24ea(%rip)    # 0x1fbccc
callq 0x1821b0
movl %eax, 0x1d24e7(%rip)    # 0x1fbcd4
callq 0x179f80
addq $0x138, %rsp            # imm = 0x138
retq
nopw (%rax,%rax)