#include <stdio.h>
#include <stdint.h>
+#include "../libsdl/print.h"
#include "video.h"
#include "../libcpu/m68kcpu.h"
static void planar2chunky(uint8_t *rgb, uint8_t *bitplanes[], uint16_t palette[], int planes, int width, int y_start, int y_end)
{
+ uint8_t red, green, blue;
int x, y, p, b, i;
uint8_t word[planes], chunk;
uint16_t rgb4;
word[p] <<= 1;
}
rgb4 = palette[chunk];
- *rgb++ = (rgb4 >> 4) & 0xf0;
- *rgb++ = rgb4 & 0xf0;
- *rgb++ = rgb4 << 4;
+ red = (rgb4 >> 4) & 0xf0;
+ green = rgb4 & 0xf0;
+ blue = rgb4 << 4;
+ red = red | (red >> 4);
+ green = green | (green >> 4);
+ blue = blue | (blue >> 4);
+ *rgb++ = red;
+ *rgb++ = green;
+ *rgb++ = blue;
}
i++;
}
}
}
+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;
+ red = red | (red >> 4);
+ green = green | (green >> 4);
+ blue = blue | (blue >> 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
#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 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];
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;
}
/* get copper list start pointer */
copperlist = (io[COP1LCH] << 16) | io[COP1LCL];
if (!copperlist) {
- fprintf(stderr, "Copper list pointer not initialized, please fix!\n");
- return;
+ print_error("Copper list pointer not initialized, please fix!\n");
+ return all_white;
}
#ifdef DEBUG_COPPERLIST
last_line = 0;
while (42) {
if (++count == 100) {
- fprintf(stderr, "Copper list does not seem to terminate, please fix!\n");
- return;
+ print_error("Copper list does not seem to terminate, please fix!\n");
+ return all_white;
}
c1 = m68k_read_memory_16(copperlist);
c2 = m68k_read_memory_16(copperlist + 2);
}
} else {
if ((c2 & 1)) {
- fprintf(stderr, "We suppport no SKIP command in copper list, please fix!\n");
+ print_error("We suppport no SKIP command in copper list, please fix!\n");
continue;
}
/* WAIT */
printf(" %06x", bitplane[i]);
#endif
if (bitplane[i] == 0 || bitplane[i] + width * height / 8 >= 0x80000) {
+#ifdef DEBUG_COPPERLIST
printf("\n");
- fprintf(stderr, "Bitplane %d in copper list not set or out of range, please fix!\n", i);
- return;
+#endif
+ print_error("Bitplane %d in copper list not set or out of range, please fix!\n", i);
+ return all_white;
}
bitmem[i] = memory + bitplane[i];
}
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;
}
}
+ return all_white;
}