+
+ case '\b':
+ start_time = glutGet(GLUT_ELAPSED_TIME);
+ prev_tmsec = 0;
+ anim_stop_time = 0;
+ beam_angle = 0;
+ break;
+
+ case ' ':
+ if(anim_stop_time > 0) {
+ long msec = glutGet(GLUT_ELAPSED_TIME);
+ start_time += msec - anim_stop_time;
+ prev_tmsec = msec - start_time;
+ anim_stop_time = 0;
+ } else {
+ anim_stop_time = glutGet(GLUT_ELAPSED_TIME);
+ }
+ break;
+
+ case '=':
+ beam_speed = get_seq_value("beam-speed", anim_time);
+ set_seq_value("beam-speed", anim_time, beam_speed + 0.1);
+ break;
+
+ case '-':
+ beam_speed = get_seq_value("beam-speed", anim_time) - 0.1;
+ if(beam_speed < 0) beam_speed = 0;
+ set_seq_value("beam-speed", anim_time, beam_speed);
+ break;
+
+ case '0':
+ clear_seq_track("beam-speed");
+ break;
+
+ case '[':
+ beam_len = get_seq_value("beam-len", anim_time) - 0.5;
+ if(beam_len < 0) beam_len = 0;
+ set_seq_value("beam-len", anim_time, beam_len);
+ break;
+
+ case ']':
+ beam_len = get_seq_value("beam-len", anim_time);
+ set_seq_value("beam-len", anim_time, beam_len + 0.5);
+ break;
+
+ case '\\':
+ clear_seq_track("beam-len");
+ break;
+
+ case '\r':
+ case '\n':
+ idx = find_seq_track("beam-speed");
+ assert(idx >= 0);
+ if(get_seq_value(idx, anim_time) > 0.0) {
+ clear_seq_track(idx);
+ set_seq_value(idx, anim_time, beam_speed);
+ set_seq_value(idx, anim_time + 3000, 0);
+ orig_beam_speed = beam_speed;
+ } else {
+ clear_seq_track(idx);
+ set_seq_value(idx, anim_time, 0);
+ set_seq_value(idx, anim_time + 3000, orig_beam_speed);
+ }
+ break;
+
+ case 'c':
+ freecam = !freecam;
+ printf("camera mode: %s\n", freecam ? "free" : "animated");
+ if(!freecam) {
+ orig_cam = cam;
+ } else {
+ cam = orig_cam;
+ }
+ break;
+
+ case 'v':
+ printf("current view\n");
+ printf(" pos: %f %f %f\n", cam.x, cam.y, cam.z);
+ printf(" theta: %f, phi: %f\n", cam.theta, cam.phi);
+ printf(" dist: %f\n", cam.dist);
+ break;
+
+ case 'L':
+ printf("clearing camera keyframes\n");
+ clear_seq_track("cam-x");
+ clear_seq_track("cam-y");
+ clear_seq_track("cam-z");
+ clear_seq_track("cam-theta");
+ clear_seq_track("cam-phi");
+ clear_seq_track("cam-dist");
+ break;
+
+ case 'k':
+ printf("setting camera keyframe for time: %ld\n", anim_time);
+ set_seq_value("cam-x", anim_time, cam.x);
+ set_seq_value("cam-y", anim_time, cam.y);
+ set_seq_value("cam-z", anim_time, cam.z);
+ set_seq_value("cam-theta", anim_time, cam.theta);
+ set_seq_value("cam-phi", anim_time, cam.phi);
+ set_seq_value("cam-dist", anim_time, cam.dist);
+ break;
+
+ case 'x':
+ set_seq_value("xlogo", anim_time, xlogo_alpha < 0.5 ? 1.0 : 0.0);
+ break;
+
+ case 'X':
+ printf("clearing logo keyframes\n");
+ clear_seq_track("xlogo");
+ break;
+
+ case '`':
+ printf("dumping animation data to: seq_dump\n");
+ if(!dump_seq("seq_dump")) {
+ fprintf(stderr, "dump failed\n");
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void keyb_special(int key, int x, int y)
+{
+ switch(key) {
+ case GLUT_KEY_F1:
+ show_help = !show_help;
+ break;
+