Correctly render all-white screen (explosion flickering)
authorAndreas Eversberg <jolly@eversberg.eu>
Sun, 29 Apr 2018 07:16:05 +0000 (09:16 +0200)
committerAndreas Eversberg <jolly@eversberg.eu>
Sun, 29 Apr 2018 07:16:05 +0000 (09:16 +0200)
src/libvideo/video.c
src/libvideo/video.h
src/mercenary/main.c
src/mercenary/render.c
src/mercenary/render.h

index b0cf223..55d4059 100644 (file)
@@ -120,7 +120,7 @@ static void planar2chunky2(uint8_t *rgb1, uint8_t *bitplanes[], uint16_t palette
 #define BPL1PTH                0x0e0
 #define COLOR00                0x180
 
-void emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int width, int height, int diwstart, uint16_t *io, int start, int stop, int double_size)
+int emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int width, int height, int diwstart, uint16_t *io, int start, int stop, int double_size)
 {
        uint32_t bitplane[8] = {0, 0, 0, 0, 0, 0, 0, 0};
        uint8_t *bitmem[8];
@@ -132,9 +132,9 @@ void emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int wi
        int i;
        int all_white;
 
-       /* special case where all palette entries are white. (unknown reason, maybe due to teleporter travel) */
+       /* special case where all palette entries are white, except for color 0 that is always black. (this happens during explosion) */
        all_white = 1;
-       for (i = 0; i < 16; i++) {
+       for (i = 1; i < 16; i++) {
                if (io[i * 2 + 0x180] != 0xfff)
                        all_white = 0;
        }
@@ -159,7 +159,7 @@ void emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int wi
        copperlist = (io[COP1LCH] << 16) | io[COP1LCL];
        if (!copperlist) {
                print_error("Copper list pointer not initialized, please fix!\n");
-               return;
+               return all_white;
        }
 
 #ifdef DEBUG_COPPERLIST
@@ -173,7 +173,7 @@ void emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int wi
        while (42) {
                if (++count == 100) {
                        print_error("Copper list does not seem to terminate, please fix!\n");
-                       return;
+                       return all_white;
                }
                c1 = m68k_read_memory_16(copperlist);
                c2 = m68k_read_memory_16(copperlist + 2);
@@ -249,7 +249,7 @@ void emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int wi
                                        printf("\n");
 #endif
                                        print_error("Bitplane %d in copper list not set or out of range, please fix!\n", i);
-                                       return;
+                                       return all_white;
                                }
                                bitmem[i] = memory + bitplane[i];
                        }
@@ -289,4 +289,5 @@ void emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int wi
                }
        }
 
+       return all_white;
 }
index b6681a1..f0b2403 100644 (file)
@@ -1,3 +1,3 @@
 
-void emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int width, int height, int diwstart, uint16_t *io, int start, int stop, int double_size);
+int emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int width, int height, int diwstart, uint16_t *io, int start, int stop, int double_size);
 
index 0bd216d..ac1a81e 100644 (file)
@@ -664,6 +664,7 @@ static void main_loop(void)
        double render_delay = 0.0;
        uint32_t palette_address;
        uint16_t palette[16];
+       int all_white = 0;
 #ifdef HAVE_OVR
        int eye;
 #endif
@@ -764,9 +765,15 @@ static void main_loop(void)
                                 * if no item list is available, for legacy rendering
                                 */
 #ifdef HAVE_OVR
-                               rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time, 1);
+                               if (all_white)
+                                       rc = render_all_white(1);
+                               else
+                                       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);
+                               if (all_white)
+                                       rc = render_all_white(0);
+                               else
+                                       rc = render_all_items((config_amiga_speed) ? 1.0 : frame_time, 0);
 #endif
                                if (rc)
                                        goto goto_legacy;
@@ -859,7 +866,7 @@ static void main_loop(void)
                                /* transfer benson without game view
                                 * because we only got benson refreshed during VBL IRQ
                                 */
-                               emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, BENSON_AT_LINE, IMAGE_HEIGHT, double_pixel_size);
+                               all_white = emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, BENSON_AT_LINE, IMAGE_HEIGHT, double_pixel_size);
                                /* render sound to sound buffer
                                 * buffer pointer read and write is atomic, so no locking required!
                                 */
index 48e9432..1c845b5 100644 (file)
@@ -2816,6 +2816,23 @@ int render_all_items(double inter, int vr)
        return 0;
 }
 
+int render_all_white(int vr)
+{
+       render_item_t sky_item;
+
+       memset(&sky_item, 0, sizeof(sky_item));
+       sky_item.type = RENDER_ITEM_SKY;
+
+       /* set color */
+       sky_item.u.ground.red = 1.0;
+       sky_item.u.ground.green = 1.0;
+       sky_item.u.ground.blue = 1.0;
+
+       render_one_item(&sky_item, vr);
+
+       return 0;
+}
+
 void render_capture_reset(void)
 {
        /* flush old list, if exists */
index aa87f39..8766c35 100644 (file)
@@ -3,6 +3,7 @@ void render_capture_start(double _fov, int _extend_roads, int _smooth_planets, i
 void render_capture_stop(void);
 void render_capture_event(int event);
 int render_all_items(double inter, int vr);
+int render_all_white(int vr);
 void render_capture_reset(void);
 int render_capture_is_interstellar(void);