OVR: Add Support for Oculus Rift SDK
[mercenary-reloaded.git] / src / mercenary / main.c
index a0c0040..c94708b 100644 (file)
@@ -24,6 +24,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include "../libsdl/sdl.h"
+#ifdef HAVE_OVR
+#include "../libovr/ovr.h"
+#endif
 #include "../libsdl/opengl.h"
 #include "../libsdl/print.h"
 #include "../libcpu/m68k.h"
@@ -55,6 +58,7 @@ static int config_render = 1; /* opengl render */
 static int config_skip_intro = 0;
 static int config_multisampling = 16;
 static double config_fov = FOV_NOVAGEN;
+static double config_monitor_distance = 31.5; /* inch */
 static double config_benson_size = 1.0;
 static int config_debug_transparent = 0;
 static int config_debug_opengl = 0;
@@ -88,8 +92,13 @@ static uint8_t *help_osd = NULL;
 static uint8_t *info_osd = NULL;
 static int help_view = 1;
 static int32_t osd_timer = 0;
-#define SCREEN_WIDTH   320
-#define SCREEN_HEIGHT  200
+#ifdef HAVE_OVR
+#define SCREEN_WIDTH   800
+#define SCREEN_HEIGHT  800
+#else
+#define SCREEN_WIDTH   (320*3)
+#define SCREEN_HEIGHT  (200*3)
+#endif
 #define IMAGE_WIDTH    320
 #define IMAGE_HEIGHT   200
 #define BENSON_AT_LINE 136
@@ -300,7 +309,6 @@ static void main_loop(void)
 {
        double frame_step, frame_time = 0.0, frame_render = 1;
        int had_first_irq = 0;
-       int render_improved_rc;
        static uint32_t current_time, last_time = 0, diff;
        int i, rc;
        int space, length;
@@ -308,6 +316,7 @@ static void main_loop(void)
        double render_delay = 0.0;
        uint32_t palette_address;
        uint16_t palette[16];
+       int eye;
 
        last_time = ticks_sdl();
 
@@ -329,9 +338,6 @@ static void main_loop(void)
                if (rc)
                        break;
 
-               /* clear screen */
-               opengl_clear();
-
                /* initialize rendering */
                debug_opengl = config_debug_opengl;
                benson_size = config_benson_size;
@@ -341,8 +347,6 @@ static void main_loop(void)
                        /* be sure to clean all capture history, so we don't get glichtes when turning on improved rendering again */
                        render_capture_reset();
                }
-               if (render_improved)
-                       opengl_viewport_improved(debug_opengl, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size);
                /* STEP 1: let the CPU render/process the game, also improve rendering via OpenGL, if enabled */
                /* amgia speed: don't render if we still delay */
                /* non amiga speed: render if we need a new frame */
@@ -378,11 +382,81 @@ static void main_loop(void)
                        if (config_amiga_speed)
                                render_delay += (double)cycle_count / CPU_SPEED;
                }
-               /* render improved graphics, interpolate, if required */
-               if (render_improved)
-                       render_improved_rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time);
-               else
-                       render_improved_rc = -1;
+
+               /* STEP 2: transfer legacy image (or just benson) in memory to OpenGL texture */
+#ifdef HAVE_OVR
+               begin_render_ovr();
+               for (eye = 0; eye < 2; eye++) {
+                       /* viewport and frustum is set here */
+                       begin_render_ovr_eye(eye);
+#else
+               eye = 0;
+               {
+#endif
+                       /* clear screen */
+#ifdef HAVE_OVR
+                       opengl_clear(1);
+#else
+                       opengl_clear(0);
+#endif
+                       /* render benson + osd ontop of improved opengl rendering, if enabled */
+                       if (render_improved) {
+#ifndef HAVE_OVR
+                               /* viewport and frustum is set here */
+                               opengl_viewport((debug_opengl) ? 2 : 0, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size);
+#endif
+                               /* render improved graphics, interpolate, if required,
+                                * if no item list is available, for legacy rendering
+                                */
+#ifdef HAVE_OVR
+                               rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time, 1);
+#else
+                               rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time, 0);
+#endif
+                               if (rc)
+                                       goto goto_legacy;
+                               opengl_blit_image(image, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, 1, config_fov, config_monitor_distance, benson_size);
+                               if (help_view)
+                                       opengl_blit_osd(0, help_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, config_monitor_distance, benson_size, 1.0, 1.0, 0.0, 0.0);
+                               if (osd_timer) {
+                                       opengl_blit_osd(1, info_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, config_monitor_distance, benson_size, 0.5, 0.04, 0.5, -0.95);
+                                       if (osd_timer - (int32_t)ticks_sdl() < 0)
+                                               osd_timer = 0;
+                               }
+                       }
+                       /* setup viewport for legacy image and render image, if enabled */
+                       /* also render legacy, if render_improved failed due to not (yet) available items */
+                       if (render_legacy) {
+                               goto_legacy:
+                               /* render game view without benson
+                                * because benson is not updated before VBL IRQ, we don't want old image from double buffer
+                                */
+                               if (had_first_irq)
+                                       emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, 0, BENSON_AT_LINE, double_pixel_size);
+#ifndef HAVE_OVR
+                               /* viewport and frustum is set here */
+                               opengl_viewport((debug_opengl) ? 1 : 0, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, 1.0);
+#endif
+                               opengl_blit_image(image, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, 0, config_fov, config_monitor_distance, 1.0);
+                               if (help_view)
+                                       opengl_blit_osd(0, help_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, config_monitor_distance, 1.0, 1.0, 1.0, 0.0, 0.0);
+                               if (osd_timer) {
+                                       opengl_blit_osd(1, info_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, config_monitor_distance, 1.0, 0.5, 0.04, 0.5, -0.95);
+                                       if (osd_timer - (int32_t)ticks_sdl() < 0)
+                                               osd_timer = 0;
+                               }
+                       }
+#ifdef HAVE_OVR
+                       end_render_ovr_eye(eye);
+               }
+               /* at this point we are ready with our image, so we display */
+               end_render_ovr();
+               render_mirror_ovr(SCREEN_WIDTH, SCREEN_HEIGHT);
+#else
+               }
+#endif
+               swap_sdl();
+
                /* advance frame time, if we are not in help view  */
                if (!(had_first_irq && help_view)) {
                        frame_time += frame_step;
@@ -392,41 +466,6 @@ static void main_loop(void)
                        }
                }
 
-               /* STEP 2: transfer legacy image (or just benson) in memory to OpenGL texture */
-               if (had_first_irq) {
-                       /* render game view without benson
-                        * because benson is not updated before VBL IRQ, we don't want old image from double buffer
-                        */
-                       if (render_legacy || render_improved_rc)
-                               emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, 0, BENSON_AT_LINE, double_pixel_size);
-               }
-               /* render benson + osd ontop of improved opengl rendering, if enabled */
-               if (render_improved && render_improved_rc == 0) {
-                       opengl_blit_benson(image, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size, (double_pixel_size) ? 2 : 1);
-                       if (help_view)
-                               opengl_blit_osd(0, help_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size, 1.0, 1.0, 0.0, 0.0);
-                       if (osd_timer) {
-                               opengl_blit_osd(1, info_osd, config_video_filter, (double_pixel_size) ? BENSON_AT_LINE * 2 : BENSON_AT_LINE, config_fov, benson_size, 0.5, 0.04, 0.5, -0.95);
-                               if (osd_timer - (int32_t)ticks_sdl() < 0)
-                                       osd_timer = 0;
-                       }
-               }
-               /* setup viewport for legacy image and render image, if enabled */
-               /* also render legacy, if render_improved failed due to not (yet) available items */
-               if (render_legacy || (render_improved && render_improved_rc)) {
-                       opengl_viewport_legacy(debug_opengl);
-                       opengl_blit_legacy(image, config_video_filter);
-                       if (help_view)
-                               opengl_blit_osd(0, help_osd, config_video_filter, 0, 0.0, 0, 1.0, 1.0, 0.0, 0.0);
-                       if (osd_timer) {
-                               opengl_blit_osd(1, info_osd, config_video_filter, 0, 0.0, 0, 0.5, 0.04, 0.5, -0.95);
-                               if (osd_timer - (int32_t)ticks_sdl() < 0)
-                                       osd_timer = 0;
-                       }
-               }
-
-               /* at this point we are ready with our image, so we display */
-               swap_sdl();
                /* measure frame rate */
                framerate_measure();
 
@@ -546,7 +585,7 @@ static void disk_read(int track, int __attribute__((unused)) side, uint32_t data
                fp = fopen(filename, "r");
                if (!fp) {
 fail:
-                       print_error("failed to load game from '%s'\n", filename);
+                       print_info("failed to load game from '%s'\n", filename);
                        goto copy;
                }
                got = fread(game_save, sizeof(game_save[0]), 2, fp);
@@ -663,7 +702,7 @@ static void keyboard_sdl(int down, enum keycode keycode)
                        osd_info("render mode", (config_render) ? "OpenGL" : "original");
                        break;
                case KEYCODE_b:
-                       if (!config_render) {
+                       if (!config_render && !config_debug_opengl) {
                                osd_info("", "not applicable");
                                break;
                        }
@@ -947,19 +986,29 @@ int main(int argc, char *argv[])
        mercenary_patch();
 
        /* init SDL and OpenGL */
-       rc = init_sdl(argv[0], (config_debug_opengl) ? SCREEN_WIDTH * 2 : SCREEN_WIDTH * 3, (config_debug_opengl) ? SCREEN_HEIGHT * 4 : SCREEN_HEIGHT * 3, SOUND_SAMPLERATE, sdl_sound_chunk, keyboard_sdl, audio_sdl, config_multisampling);
+#ifdef HAVE_OVR
+       int vbl_sync = 0;
+#else
+       int vbl_sync = 1;
+#endif
+       rc = init_sdl(argv[0], (config_debug_opengl) ? SCREEN_WIDTH / 3 * 2 : SCREEN_WIDTH, (config_debug_opengl) ? SCREEN_HEIGHT / 3 * 4 : SCREEN_HEIGHT, SOUND_SAMPLERATE, sdl_sound_chunk, keyboard_sdl, audio_sdl, config_multisampling, vbl_sync);
        if (rc < 0)
                goto done;
-       rc = init_opengl((double_pixel_size) ? IMAGE_WIDTH * 2 : IMAGE_WIDTH, (double_pixel_size) ? IMAGE_HEIGHT * 2 : IMAGE_HEIGHT);
+#ifdef HAVE_OVR
+       rc = init_ovr();
        if (rc < 0)
                goto done;
-       resize_opengl((config_debug_opengl) ? SCREEN_WIDTH * 2 : SCREEN_WIDTH * 3, (config_debug_opengl) ? SCREEN_HEIGHT * 4 : SCREEN_HEIGHT * 3);
+#endif
+       rc = init_opengl_image((double_pixel_size) ? IMAGE_WIDTH * 2 : IMAGE_WIDTH, (double_pixel_size) ? IMAGE_HEIGHT * 2 : IMAGE_HEIGHT);
+       if (rc < 0)
+               goto done;
+       resize_opengl((config_debug_opengl) ? SCREEN_WIDTH / 3 * 2 : SCREEN_WIDTH, (config_debug_opengl) ? SCREEN_HEIGHT / 3 * 4 : SCREEN_HEIGHT);
 
        /* init osd */
-       rc = init_osd(0, IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2);
+       rc = init_opengl_osd(0, IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2);
        if (rc < 0)
                goto done;
-       rc = init_osd(1, OSD_WIDTH, OSD_HEIGHT);
+       rc = init_opengl_osd(1, OSD_WIDTH, OSD_HEIGHT);
        if (rc < 0)
                goto done;
        help_osd = text_alloc(IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2, HELP_ALPHA);
@@ -1026,6 +1075,9 @@ int main(int argc, char *argv[])
 
 done:
        exit_opengl();
+#ifdef HAVE_OVR
+       exit_ovr();
+#endif
        exit_sdl();
 
        if (chipreg)