+static void osd_info(const char *param, const char *value)
+{
+ char line[41] = " ";
+
+ if (param[0]) {
+ strncpy(line + 21 - strlen(param), param, strlen(param));
+ line[22] = ':';
+ }
+ if (strlen(value) > 15) {
+ print_error("string too long\n");
+ return;
+ }
+ strncpy(line + 25, value, strlen(value));
+ text_render(info_osd, OSD_WIDTH, OSD_HEIGHT, line, 0x00, 4, 0, 0, 1);
+ osd_timer = ticks_sdl() + 2500;
+}
+
+static void toggle_help(void)
+{
+ if (help_view == 0)
+ help_view = 2;
+ else
+ if (help_view == help_views)
+ help_view = 0;
+ else
+ help_view++;
+}
+
+static void resize_window(int width, int height)
+{
+ window_width = width;
+ window_height = height;
+ border_timer = ticks_sdl() + 1500;
+ osd_info("", "window resized");
+}
+
+#ifdef HAVE_OVR
+static int __attribute__((unused)) button_a_last = 0, button_b_last = 0, button_x_last = 0, button_y_last = 0, button_menu_last = 0, button_left_trigger_last = 0, button_right_trigger_last = 0, button_left_thumb_last = 0, button_right_thumb_last = 0;
+static double __attribute__((unused)) stick_left_x_last = 0.0, stick_left_y_last = 0.0, stick_right_x_last = 0.0, stick_right_y_last = 0.0;
+static int thrust_last = 0;
+static int joystick_set_x_last = 0, joystick_set_y_last = 0;
+static int keyboard_on = 0;
+static enum keycode vr_key_pressed = 0, vr_key = 0;
+static int we_walk = 0, we_rotate = 0;
+static double degrees45 = 45.0 / 180.0 * M_PI;
+
+static void handle_vr_poses(void)
+{
+ int button_a = 0, button_b = 0, button_x = 0, button_y = 0, button_menu = 0, button_left_trigger = 0, button_right_trigger = 0, button_left_thumb = 0, button_right_thumb = 0;
+ double hand_right_x = 0.0, hand_right_y = 0.0, hand_right_z = 0.0;
+ double hand_right_yaw = 0.0, hand_right_pitch = 0.0, hand_right_roll = 0.0;
+ double head_yaw = 0.0, head_pitch = 0.0, head_roll = 0.0;
+ double stick_left_x = 0.0, stick_left_y = 0.0, stick_right_x = 0.0, stick_right_y = 0.0;
+ int thrust = thrust_last;
+ int joystick_set_x = 0, joystick_set_y = 0;
+ static uint32_t current_time, last_time = 0, diff;
+ static double increment, inc_count = 0.0;
+
+ /* handle input */
+ get_poses_ovr(&button_a, &button_b, &button_x, &button_y, &button_menu, &button_left_trigger, &button_right_trigger, &button_left_thumb, &button_right_thumb, &hand_right_x, &hand_right_y, &hand_right_z, &hand_right_yaw, &hand_right_pitch, &hand_right_roll, &stick_left_x, &stick_left_y, &stick_right_x, &stick_right_y, &head_yaw, &head_pitch, &head_roll);
+ if (button_a && !button_a_last) {
+ /* menu toggle */
+ toggle_help();
+ }
+ if (button_b && !button_b_last) {
+ /* reset observer */
+ reset_observer_ovr();
+ osd_info("", "reset observer");
+ }
+ if (button_x && !button_x_last) {
+ /* menu toggle */
+ toggle_help();
+ }
+ if (button_y && !button_y_last) {
+ /* reset observer */
+ reset_observer_ovr();
+ osd_info("", "reset observer");
+ }
+ if (!help_view) {
+ if (button_right_trigger && !button_right_trigger_last) {
+ /* trigger pressed */
+ if (keyboard_on) {
+ if (vr_key) {
+ vr_key_pressed = vr_key;
+ set_amiga_key(vr_key_pressed, 1);
+ /* reset vr thrust */
+ thrust = 0;
+ }
+ } else {
+ /* fire button */
+ set_joystick(-1, -1, -1, -1, 1);
+ }
+ }
+ if (!button_right_trigger && button_right_trigger_last) {
+ /* trigger released */
+ set_joystick(-1, -1, -1, -1, 0);
+ if (vr_key_pressed) {
+ set_amiga_key(vr_key_pressed, 0);
+ vr_key_pressed = 0;
+ }
+ }
+ /* joystick */
+ /* reset moving state, so the game is not influenced before we want to */
+ mercenary_vr_move(0, NULL, NULL, 256, 256);
+ joystick_set_x = 0;
+ joystick_set_y = 0;
+ if (!mercenary_get_info_walking()) {
+ /* turn right and left when not walking */
+ if (stick_right_x > STICK_ROTATE_THRESHOLD) {
+ set_joystick(0, 1, -1, -1, -1);
+ joystick_set_x = 1;
+ } else
+ if (stick_right_x < -STICK_ROTATE_THRESHOLD) {
+ set_joystick(1, 0, -1, -1, -1);
+ joystick_set_x = 1;
+ }
+ /* pitch craft */
+ if (stick_right_y > STICK_WALK_THRESHOLD) {
+ set_joystick(-1, -1, 1, 0, -1);
+ joystick_set_y = 1;
+ } else
+ if (stick_right_y < -STICK_WALK_THRESHOLD) {
+ set_joystick(-1, -1, 0, 1, -1);
+ joystick_set_y = 1;
+ }
+ if (joystick_set_x || joystick_set_y) {
+ mercenary_vr_move(0, NULL, NULL,
+ 256,
+ (int)(256.0 * fabs(stick_right_y) - STICK_WALK_THRESHOLD / (1.0 - STICK_WALK_THRESHOLD) + 0.5));
+ }
+ } else {
+ double roll, pitch, yaw;
+ double tilt, dir, east, north;
+ int32_t move_east[4], move_north[4];
+
+ tilt = sqrt(stick_right_x * stick_right_x + stick_right_y * stick_right_y);
+
+ /* check if we rotate, walk or rest */
+ if (we_rotate == 0 && we_walk == 0) {
+ /* we rest */
+ if (fabs(stick_right_y) > fabs(stick_right_x) && tilt > STICK_WALK_THRESHOLD)
+ we_walk = 1;
+ if (fabs(stick_right_x) > fabs(stick_right_y) && tilt > STICK_ROTATE_THRESHOLD)
+ we_rotate = 1;
+ } else if (we_walk) {
+ /* we walk */
+ if (tilt < STICK_WALK_THRESHOLD) {
+ we_walk = 0;
+ /* we need to stop right here and not continue until next rendering */
+ set_joystick(-1, -1, 0, 0, -1); /* stop y */
+ reset_joystick(); /* commit stop */
+ }
+ } else {
+ /* we rotate */
+ if (tilt < STICK_ROTATE_THRESHOLD)
+ we_rotate = 0;
+ }
+
+ /* if we walk */
+ if (we_walk) {
+ /* get stick amplitude (dist) and direction (dir) */
+ if (tilt > 1.0)
+ tilt = 1.0;
+ tilt = (tilt - STICK_WALK_THRESHOLD) / (1.0 - STICK_WALK_THRESHOLD) * 40.0;
+ dir = atan2(stick_right_x, stick_right_y);
+#if 0
+ /* use hand direction to get actual stick direction */
+ dir = fmod(dir - hand_right_yaw, M_PI * 2.0);
+ if (dir < -M_PI)
+ dir += M_PI * 2.0;
+ if (dir > M_PI)
+ dir -= M_PI * 2.0;
+#endif
+ /* flip direction, if we walk backwards */
+ if (dir > M_PI / 2.0 || dir < -M_PI / 2.0) {
+ /* go backwards */
+ set_joystick(-1, -1, 0, 1, -1);
+ joystick_set_y = 1;
+ } else {
+ /* go forward */
+ set_joystick(-1, -1, 1, 0, -1);
+ joystick_set_y = 1;
+ }
+ mercenary_get_orientation(&roll, &pitch, &yaw);
+ east = sin(yaw - dir + M_PI) * tilt;
+ north = -cos(yaw - dir + M_PI) * tilt;
+ /* calculatate the integer positions of 4 steps */
+ move_east[0] = (int32_t)((east * 0.25) + 0.5);
+ move_north[0] = (int32_t)((north * 0.25) + 0.5);
+ move_east[1] = (int32_t)((east * 0.5) + 0.5);
+ move_north[1] = (int32_t)((north * 0.5) + 0.5);
+ move_east[2] = (int32_t)((east * 0.75) + 0.5);
+ move_north[2] = (int32_t)((north * 0.75) + 0.5);
+ move_east[3] = (int32_t)(east + 0.5);
+ move_north[3] = (int32_t)(north + 0.5);
+ /* calculate the delta between each of the 4 step */
+ move_east[3] -= move_east[2];
+ move_north[3] -= move_north[2];
+ move_east[2] -= move_east[1];
+ move_north[2] -= move_north[1];
+ move_east[1] -= move_east[0];
+ move_north[1] -= move_north[0];
+ /* the game takes 4 steps to move the player */
+ mercenary_vr_move(1, move_east, move_north, 256, 256);
+ }
+
+ /* snap orientation to steps of 45 degrees */
+ if (we_rotate == 1) {
+ mercenary_get_orientation(&roll, &pitch, &yaw);
+ yaw = round(yaw / degrees45) * degrees45;
+ /* if we rotate: change orientation */
+ if (stick_right_x > 0)
+ yaw -= degrees45;
+ else
+ yaw += degrees45;
+ /* rotate only once per stick movement */
+ we_rotate = 2;
+ mercenary_set_orientation(yaw);
+ }
+ }
+ if (joystick_set_x_last && !joystick_set_x)
+ set_joystick(0, 0, -1, -1, -1);
+ if (joystick_set_y_last && !joystick_set_y)
+ set_joystick(-1, -1, 0, 0, -1);
+ /* thrust */
+ /* button to toggle between stop and escape */
+ if (button_left_thumb && !button_left_thumb_last) {
+ /* 'escape' pressed */
+ if (thrust_last != -99)
+ thrust = -99;
+ else
+ thrust = 0;
+ }
+ /* button to stop */
+ if (button_left_trigger && !button_left_trigger_last) {
+ /* 'stop' pressed */
+ thrust = 0;
+ }
+ /* get stick to increment or decrement thrust */
+ if (stick_left_y > STICK_THRUST_THRESHOLD)
+ increment = (stick_left_y - STICK_THRUST_THRESHOLD) / (1.0 - STICK_THRUST_THRESHOLD);
+ else
+ if (stick_left_y < -STICK_THRUST_THRESHOLD)
+ increment = (stick_left_y + STICK_THRUST_THRESHOLD) / (1.0 - STICK_THRUST_THRESHOLD);
+ else
+ increment = 0;
+ current_time = ticks_sdl();
+ if (increment) {
+ diff = current_time - last_time;
+ inc_count += increment * diff;
+ /* if we are in 'escape' mode, we stop thrust first */
+ if (thrust == -99)
+ thrust = 0;
+ if (inc_count > 150.0 && thrust >= -10 && thrust < 10) {
+ thrust++;
+ inc_count = 0.0;
+ }
+ if (inc_count < -150.0 && thrust <= 10 && thrust > -10) {
+ thrust--;
+ inc_count = 0.0;
+ }
+ } else {
+ inc_count = 0;
+ }
+ last_time = current_time;
+ /* send thrust change as keycodes */
+ if (thrust_last != thrust) {
+ /* if we were in escape mode, we stop us first and then apply the new code */
+ if (thrust_last == -99) {
+ set_amiga_key(KEYCODE_SPACE, 1);
+ set_amiga_key(KEYCODE_SPACE, 0);
+ }
+
+ if (thrust >= 10) {
+ set_amiga_key(KEYCODE_0, 1);
+ set_amiga_key(KEYCODE_0, 0);
+ } else
+ if (thrust <= -10 && thrust > -99) {
+ set_amiga_key(KEYCODE_F10, 1);
+ set_amiga_key(KEYCODE_F10, 0);
+ } else
+ if (thrust <= -99) {
+ set_amiga_key(KEYCODE_ESCAPE, 1);
+ set_amiga_key(KEYCODE_ESCAPE, 0);
+ } else
+ if (thrust > 0) {
+ set_amiga_key(KEYCODE_1 + thrust - 1, 1);
+ set_amiga_key(KEYCODE_1 + thrust - 1, 0);
+ } else
+ if (thrust < 0) {
+ set_amiga_key(KEYCODE_F1 - thrust - 1, 1);
+ set_amiga_key(KEYCODE_F1 - thrust - 1, 0);
+ } else {
+ set_amiga_key(KEYCODE_SPACE, 1);
+ set_amiga_key(KEYCODE_SPACE, 0);
+ }
+ }
+ }
+ button_a_last = button_a;
+ button_b_last = button_b;
+ button_x_last = button_x;
+ button_y_last = button_y;
+ button_menu_last = button_menu;
+ button_left_trigger_last = button_left_trigger;
+ button_right_trigger_last = button_right_trigger;
+ button_left_thumb_last = button_left_thumb;
+ button_right_thumb_last = button_right_thumb;
+ stick_left_x_last = stick_left_x;
+ stick_left_y_last = stick_left_y;
+ stick_right_x_last = stick_right_x;
+ stick_right_y_last = stick_right_y;
+ thrust_last = thrust;
+ joystick_set_x_last = joystick_set_x;
+ joystick_set_y_last = joystick_set_y;
+
+ /* we must handle keyboard after toggeling keyboard_on,
+ * so that keyboard_on will not change until keyboard is rendered */
+ vr_key = 0;
+ keyboard_on = handle_vr_keyboard(hand_right_x, hand_right_y, hand_right_z, hand_right_yaw, hand_right_pitch, &vr_key);
+}
+#endif
+
+static void skip_intro(void)
+{
+ int event;
+ double render_delay = 0.0;
+ double cycle_count;
+
+ if (intro_skipped)
+ return;
+
+ print_info("*** Skipping intro, fast forwarding... ***\n\n");
+ do {
+ /* render, if not delayed */
+ if (render_delay <= 0.0) {
+ cycle_count = 0;
+ do {
+ cycle_count += execute_cpu(0, &event);
+ } while (event != STOP_AT_WAIT_VBL && event != STOP_AT_CLEAR_SCREEN1);
+ render_delay += (double)cycle_count / CPU_SPEED;
+ }
+ /* VBL */
+ execute_cpu(3, NULL);
+ /* count down render delay */
+ if (render_delay) {
+ render_delay -= 1.0 / (double)IRQ_RATE;
+ if (render_delay < 0.0)
+ render_delay = 0.0;
+ }
+ } while (event != STOP_AT_CLEAR_SCREEN1);
+
+ intro_skipped = 1;
+}
+