Use double pixel size to render amiga video (2x2)
authorAndreas Eversberg <jolly@eversberg.eu>
Tue, 6 Mar 2018 17:56:38 +0000 (18:56 +0100)
committerAndreas Eversberg <jolly@eversberg.eu>
Wed, 7 Mar 2018 17:22:54 +0000 (18:22 +0100)
src/libvideo/video.c
src/libvideo/video.h
src/mercenary/main.c

index 32b4566..516122b 100644 (file)
@@ -54,6 +54,54 @@ static void planar2chunky(uint8_t *rgb, uint8_t *bitplanes[], uint16_t palette[]
        }
 }
 
+static void planar2chunky2(uint8_t *rgb1, uint8_t *bitplanes[], uint16_t palette[], int planes, int width, int y_start, int y_end)
+{
+       uint8_t *rgb2, red, green, blue;
+       int x, y, p, b, i;
+       uint8_t word[planes], chunk;
+       uint16_t rgb4;
+
+       rgb2 = rgb1 + width * 6;
+
+       /* we start memory read from the following calulated bitplane offset: */
+       i = y_start * (width / 8);
+       rgb1 += 2 * y_start * width * 6;
+       rgb2 += 2 * y_start * width * 6;
+       for (y = y_start; y < y_end; y++) {
+               for (x = 0; x < width; x += 8) {
+                       for (p = 0; p < planes; p++)
+                               word[p] = bitplanes[p][i];
+                       for (b = 0; b < 8; b++) {
+                               chunk = (word[planes - 1] >> 7);
+                               word[planes - 1] <<= 1;
+                               for (p = planes - 2; p >= 0; p--) {
+                                       chunk = (chunk << 1) | (word[p] >> 7);
+                                       word[p] <<= 1;
+                               }
+                               rgb4 = palette[chunk];
+                               red = (rgb4 >> 4) & 0xf0;
+                               green = rgb4 & 0xf0;
+                               blue = rgb4 << 4;
+                               *rgb1++ = red;
+                               *rgb1++ = green;
+                               *rgb1++ = blue;
+                               *rgb1++ = red;
+                               *rgb1++ = green;
+                               *rgb1++ = blue;
+                               *rgb2++ = red;
+                               *rgb2++ = green;
+                               *rgb2++ = blue;
+                               *rgb2++ = red;
+                               *rgb2++ = green;
+                               *rgb2++ = blue;
+                       }
+                       i++;
+               }
+               rgb1 += width * 6;
+               rgb2 += width * 6;
+       }
+}
+
 #define COP1LCH                0x080
 #define COP1LCL                0x082
 #define COP2LCH                0x084
@@ -61,7 +109,7 @@ static void planar2chunky(uint8_t *rgb, 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)
+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)
 {
        uint32_t bitplane[8] = {0, 0, 0, 0, 0, 0, 0, 0};
        uint8_t *bitmem[8];
@@ -213,8 +261,12 @@ void emul_video(uint8_t *rgb, uint8_t *memory, uint16_t render_palette[], int wi
                                from = start;
                        if (stop < to)
                                to = stop;
-                       if (to > from)
-                               planar2chunky(rgb, bitmem, palette, 4, width, from, to);
+                       if (to > from) {
+                               if (double_size)
+                                       planar2chunky2(rgb, bitmem, palette, 4, width, from, to);
+                               else
+                                       planar2chunky(rgb, bitmem, palette, 4, width, from, to);
+                       }
                        /* done if we rendered up to height */
                        if (line == height)
                                break;
index 4d17734..b6681a1 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);
+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);
 
index 6e1af1c..0d8d582 100644 (file)
@@ -36,7 +36,7 @@
 
 static int config_amiga_speed = 1;
 static const char *config_gamesave_dir = ".mercenary";
-static int config_video_filter = 0;
+static int config_video_filter = 1;
 static int config_audio_filter = 1;
 
 #define CPU_SPEED      7093790.0;
@@ -72,6 +72,7 @@ static float *sound_buffer = NULL; /* sound buffer memory */
 static int sound_buffer_size; /* buffer sample size */
 static int sound_buffer_writep; /* write pointer at buffer */
 static int sound_buffer_readp; /* read pointer at buffer */
+static int double_size = 1; /* render in double size, so each pixle is 2*2 pixles wide */
 
 static const char *home_dir;
 
@@ -187,7 +188,7 @@ static void main_loop(void)
                        /* render game view without benson
                         * because benson is not updated before VBL IRQ, we don't want old image from double buffer
                         */
-                       emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, 0, BENSON_AT_LINE);
+                       emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, 0, BENSON_AT_LINE, double_size);
                }
                rc = event_sdl();
                if (rc)
@@ -210,7 +211,7 @@ static void main_loop(void)
                        /* render 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);
+                       emul_video(image, memory, palette, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_DIWSTART, chipreg, BENSON_AT_LINE, IMAGE_HEIGHT, double_size);
                        /* render sound to sound buffer
                         * buffer pointer read and write is atomic, so no locking required!
                         */
@@ -264,7 +265,7 @@ int main(int argc, char *argv[])
                return 0;
 
        /* allocate image */
-       image = calloc(IMAGE_WIDTH * IMAGE_HEIGHT, 3);
+       image = calloc(IMAGE_WIDTH * IMAGE_HEIGHT * ((double_size) ? 4 : 1), 3);
        if (!image) {
                fprintf(stderr, "Failed to allocate image buffer\n");
                goto done;
@@ -320,7 +321,7 @@ int main(int argc, char *argv[])
        rc = init_sdl(argv[0], SCREEN_WIDTH, SCREEN_HEIGHT, SOUND_SAMPLERATE, sdl_sound_chunk);
        if (rc < 0)
                goto done;
-       rc = init_opengl(IMAGE_WIDTH, IMAGE_HEIGHT);
+       rc = init_opengl((double_size) ? IMAGE_WIDTH * 2 : IMAGE_WIDTH, (double_size) ? IMAGE_HEIGHT * 2 : IMAGE_HEIGHT);
        if (rc < 0)
                goto done;
        resize_opengl(SCREEN_WIDTH, SCREEN_HEIGHT);