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

  // Process keyboard button event 
  switch (key) {
  case GLUT_KEY_HOME:
  case GLUT_KEY_END:
  case GLUT_KEY_PAGE_DOWN:
  case GLUT_KEY_PAGE_UP: {
    int property_index = current_property_index;
    if (key == GLUT_KEY_PAGE_DOWN) property_index--;
    else if (key == GLUT_KEY_PAGE_UP) property_index++;
    else if (key == GLUT_KEY_HOME) property_index = 0;
    else if (key == GLUT_KEY_END) property_index = properties->NProperties() - 1;
    SelectProperty(property_index);
    break; }

  case GLUT_KEY_RIGHT:
  case GLUT_KEY_LEFT:
  case GLUT_KEY_DOWN:
  case GLUT_KEY_UP: {
    RNScalar mid = percentile_range.Mid();
    RNScalar radius = percentile_range.Radius();
    if (key == GLUT_KEY_LEFT) { if (radius >= 1) radius -= 1; }
    else if (key == GLUT_KEY_RIGHT) { if ((mid - radius >= 1) && (mid + radius <= 99)) radius += 1; }
    else if (key == GLUT_KEY_DOWN) { if (mid - radius >= 1) mid -= 1; }
    else if (key == GLUT_KEY_UP) { if (mid + radius <= 99) mid += 1; }
    percentile_range.Reset(mid - radius, mid + radius);
    RNScalar min_value = current_property->Percentile(percentile_range.Min());
    RNScalar max_value = current_property->Percentile(percentile_range.Max());
    value_range.Reset(min_value, max_value);
    break; }
  }

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

  // Remember modifiers 
  GLUTmodifiers = glutGetModifiers();

  // Redraw
  glutPostRedisplay();
}

// Assembly:
subq $0x48, %rsp
movl %edi, 0x44(%rsp)
movl %esi, 0x40(%rsp)
movl %edx, 0x3c(%rsp)
movl 0x1d5eca(%rip), %eax    # 0x1feac0
movl 0x3c(%rsp), %ecx
subl %ecx, %eax
movl %eax, 0x3c(%rsp)
movl 0x44(%rsp), %eax
movl %eax, 0x14(%rsp)
addl $-0x64, %eax
subl $0x4, %eax
jb 0x28c99
jmp 0x28c16
movl 0x14(%rsp), %eax
addl $-0x68, %eax
subl $0x3, %eax
ja 0x28e48
jmp 0x28c28
movl 0x1dc0de(%rip), %eax    # 0x204d0c
movl %eax, 0x38(%rsp)
cmpl $0x69, 0x44(%rsp)
jne 0x28c46
movl 0x38(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x28c8b
cmpl $0x68, 0x44(%rsp)
jne 0x28c5a
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x28c89
cmpl $0x6a, 0x44(%rsp)
jne 0x28c6b
movl $0x0, 0x38(%rsp)
jmp 0x28c87
cmpl $0x6b, 0x44(%rsp)
jne 0x28c85
movq 0x1dc04f(%rip), %rdi    # 0x204cc8
callq 0x2ae90
subl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x28c87
jmp 0x28c89
jmp 0x28c8b
movl 0x38(%rsp), %edi
callq 0x28e80
jmp 0x28e48
leaq 0x1dbf98(%rip), %rdi    # 0x204c38
callq 0x2aeb0
movsd %xmm0, 0x30(%rsp)
leaq 0x1dbf86(%rip), %rdi    # 0x204c38
callq 0x2aed0
movsd %xmm0, 0x28(%rsp)
cmpl $0x64, 0x44(%rsp)
jne 0x28cf5
movsd 0x28(%rsp), %xmm0
movsd 0x16d396(%rip), %xmm1   # 0x196068
ucomisd %xmm1, %xmm0
jb 0x28cf0
movsd 0x28(%rsp), %xmm0
movsd 0x16d382(%rip), %xmm1   # 0x196068
subsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
jmp 0x28dbe
cmpl $0x66, 0x44(%rsp)
jne 0x28d46
movsd 0x30(%rsp), %xmm0
subsd 0x28(%rsp), %xmm0
movsd 0x16d358(%rip), %xmm1   # 0x196068
ucomisd %xmm1, %xmm0
jb 0x28d44
movsd 0x30(%rsp), %xmm1
addsd 0x28(%rsp), %xmm1
movsd 0x16d366(%rip), %xmm0   # 0x196090
ucomisd %xmm1, %xmm0
jb 0x28d44
movsd 0x16d330(%rip), %xmm0   # 0x196068
addsd 0x28(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
jmp 0x28dbc
cmpl $0x67, 0x44(%rsp)
jne 0x28d81
movsd 0x30(%rsp), %xmm0
subsd 0x28(%rsp), %xmm0
movsd 0x16d307(%rip), %xmm1   # 0x196068
ucomisd %xmm1, %xmm0
jb 0x28d7f
movsd 0x30(%rsp), %xmm0
movsd 0x16d2f3(%rip), %xmm1   # 0x196068
subsd %xmm1, %xmm0
movsd %xmm0, 0x30(%rsp)
jmp 0x28dba
cmpl $0x65, 0x44(%rsp)
jne 0x28db8
movsd 0x30(%rsp), %xmm1
addsd 0x28(%rsp), %xmm1
movsd 0x16d2f4(%rip), %xmm0   # 0x196090
ucomisd %xmm1, %xmm0
jb 0x28db6
movsd 0x16d2be(%rip), %xmm0   # 0x196068
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
jmp 0x28db8
jmp 0x28dba
jmp 0x28dbc
jmp 0x28dbe
movsd 0x30(%rsp), %xmm0
subsd 0x28(%rsp), %xmm0
movsd 0x30(%rsp), %xmm1
addsd 0x28(%rsp), %xmm1
leaq 0x1dbe5b(%rip), %rdi    # 0x204c38
callq 0x2aef0
movq 0x1dbecf(%rip), %rax    # 0x204cb8
movq %rax, (%rsp)
leaq 0x1dbe44(%rip), %rdi    # 0x204c38
callq 0x2ae00
movq (%rsp), %rdi
callq 0x6d860
movsd %xmm0, 0x20(%rsp)
movq 0x1dbea9(%rip), %rax    # 0x204cb8
movq %rax, 0x8(%rsp)
leaq 0x1dbe1d(%rip), %rdi    # 0x204c38
callq 0x2ae10
movq 0x8(%rsp), %rdi
callq 0x6d860
movsd %xmm0, 0x18(%rsp)
movsd 0x20(%rsp), %xmm0
movsd 0x18(%rsp), %xmm1
leaq 0x1dbe05(%rip), %rdi    # 0x204c48
callq 0x2aef0
movl 0x40(%rsp), %eax
movl %eax, 0x1dbe86(%rip)    # 0x204cd8
movl 0x3c(%rsp), %eax
movl %eax, 0x1dbe80(%rip)    # 0x204cdc
callq 0x18a2e0
movl %eax, 0x1dbea1(%rip)    # 0x204d08
callq 0x1820b0
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)