Motion interpolation
[mercenary-reloaded.git] / src / mercenary / main.c
index 11eceb1..cda13e1 100644 (file)
@@ -43,6 +43,8 @@
 
 static int config_ctrl_c = 0;
 static int config_amiga_speed = 1;
+#warning fixme: make use of 10 for intro, then be as fast as given
+static double config_fps = 16.0;
 static const char *config_gamesave_dir = ".mercenary";
 static int config_video_filter = 1;
 static int config_audio_filter = 1;
@@ -54,7 +56,7 @@ static double config_benson_size = 1.0;
 static int config_debug_transparent = 0;
 static int config_debug_opengl = 0;
 /* render improvements */
-static int config_improve_extend_roads = 0;    /* set to 1 to extend roads */
+static int config_improve_extend_roads = 1;    /* set to 1 to extend roads */
 
 #define CPU_SPEED      7093790.0;
 
@@ -107,14 +109,16 @@ int parse_args(int argc, char *argv[])
        while (argc > i) {
                if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
                        print_info("Usage: %s\n", argv[0]);
-                       print_info(" -s --amiga-speed original | full\n");
-                       print_info("        Set speed of rendering to original Amiga or full speed.\n");
+                       print_info(" -s --render-speed original | fast\n");
+                       print_info("        Set speed of rendering to original Amiga or fast speed.\n");
+                       print_info("    --fps <fps>\n");
+                       print_info("        Set frames per second for fast rate (default = %.1f).\n", config_fps);
                        print_info(" -v --video-filter on | off\n");
                        print_info("        Set video filter.\n");
                        print_info(" -a --audio-filter on | off\n");
                        print_info("        Set audio filter.\n");
-                       print_info(" -r --render original | opegl\n");
-                       print_info("        Set speed of rendering to original Amiga or full speed.\n");
+                       print_info(" -r --render original | opengl\n");
+                       print_info("        Set speed of rendering to original Amiga or OpenGL.\n");
                        print_info(" -b --benson normal | half\n");
                        print_info("        Size of 'Benson' (control panel).\n");
                        print_info(" -m --multisampling <samples>\n");
@@ -132,7 +136,7 @@ int parse_args(int argc, char *argv[])
                        print_info("        Use CTRL+C to exit game (used for development)\n");
                        return -1;
                } else
-               if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--amiga-speed")) {
+               if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--render-speed")) {
                        i++;
                        if (argc == i) {
 missing_parameter:
@@ -142,7 +146,7 @@ missing_parameter:
                        if (!strcmp(argv[i], "original"))
                                config_amiga_speed = 1;
                        else
-                       if (!strcmp(argv[i], "full"))
+                       if (!strcmp(argv[i], "fast"))
                                config_amiga_speed = 0;
                        else {
 illegal_parameter:
@@ -150,6 +154,14 @@ illegal_parameter:
                                return -1;
                        }
                } else
+               if (!strcmp(argv[i], "--fps")) {
+                       i++;
+                       if (argc == i)
+                               goto missing_parameter;
+                       config_fps = atof(argv[i]);
+                       if (config_fov <= 0.0)
+                               goto illegal_parameter;
+               } else
                if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--video-filter")) {
                        i++;
                        if (argc == i)
@@ -243,11 +255,12 @@ static void special_event(int event)
 
 static void main_loop(void)
 {
+       double frame_step, frame_time = 0.0, frame_render = 1;
        int had_first_irq = 0;
        static uint32_t current_time, last_time = 0, diff;
        int i, rc;
        int space, length;
-       int cycle_count, event;
+       int cycle_count, event = STOP_AT_END;
        double render_delay = 0.0;
        uint32_t palette_address;
        uint16_t palette[16];
@@ -256,7 +269,16 @@ static void main_loop(void)
 
        /* render result on window */
        while (!quit) {
-printf("frame rate: %.6f\n", 1.0 / vbl_duration);
+#warning oder ganz anders: bevor landung machen wir amiga-rate als interpolation
+               /* if we are in interstellar fligt, we use 50 Hz */
+               /* if we are approaching to Eris Space Port, we use 10 Hz */
+               /* else we use whatever frame rate the user wants */
+               if (render_capture_is_interstellar())
+                       frame_step = vbl_duration * 50.0;
+               else
+                       frame_step = vbl_duration * config_fps;
+               if (frame_step > 1.0)
+                       frame_step = 1.0;
                /* handle SDL events */
                rc = event_sdl();
                if (rc)
@@ -270,13 +292,22 @@ printf("frame rate: %.6f\n", 1.0 / vbl_duration);
                benson_size = config_benson_size;
                render_legacy = (!config_render) || debug_opengl;
                render_improved = config_render || debug_opengl;
+               if (!render_improved) {
+                       /* 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);
                        opengl_copy_last();
                }
                /* STEP 1: let the CPU render/process the game, also improve rendering via OpenGL, if enabled */
-               /* don't render if we still delay */
-               if (!render_delay) {
+               /* amgia speed: don't render if we still delay */
+               /* non amiga speed: render if we need a new frame */
+               /* NOTE: at input event we must render after every VBL, so we do this in every loop */
+               if ((frame_render && !config_amiga_speed)
+                || (config_amiga_speed && render_delay <= 0.0)
+                || event == STOP_AT_WAIT_INPUT) {
+                       frame_render = 0;
                        /* start capturing for improved graphics */
                        if (render_improved)
                                render_capture_start(config_fov, config_improve_extend_roads, config_debug_transparent);
@@ -286,9 +317,8 @@ printf("frame rate: %.6f\n", 1.0 / vbl_duration);
                        do {
                                cycle_count += execute_cpu(0, &event);
                                /* handle special events */
-                               if (event != STOP_AT_WAIT_VBL)
-                                       special_event(event);
-                       } while (event != STOP_AT_WAIT_VBL);
+                               special_event(event);
+                       } while (event != STOP_AT_WAIT_VBL && event != STOP_AT_WAIT_INPUT);
                        /* stop capturing for improved graphics */
                        if (render_improved)
                                render_capture_stop();
@@ -298,11 +328,18 @@ printf("frame rate: %.6f\n", 1.0 / vbl_duration);
                                palette[i] = m68k_read_memory_16(palette_address + i*2);
                        /* for amiga speed: set delay by the number of cycles */
                        if (config_amiga_speed)
-                               render_delay = (double)cycle_count / CPU_SPEED;
+                               render_delay += (double)cycle_count / CPU_SPEED;
                }
-               /* render improved graphics */
+               /* render improved graphics, interpolate, if required */
                if (render_improved)
-                       render_all_items();
+                       render_all_items((config_amiga_speed) ? 1.0 : frame_time);
+               /* advance frame time */
+printf("frame rate: %.6f, frame-step=%.5f frame-time=%.5f\n", 1.0 / vbl_duration, frame_step,frame_time);
+               frame_time += frame_step;
+               if (frame_time >= 1.0) {
+                       frame_time -= 1.0;
+                       frame_render = 1;
+               }
 
                /* STEP 2: transfer legacy image (or just benson) in memory to OpenGL texture */
                if (had_first_irq) {