int screenshot_clipmode = 0;
int screenshot_multi = 0;
+extern bool need_genlock_data;
+extern uae_u8 **row_map_genlock;
+
+static bool usealpha(void)
+{
+ return need_genlock_data != 0 && row_map_genlock && currprefs.genlock_image && currprefs.genlock_alpha;
+}
+
static void namesplit (TCHAR *s)
{
int l;
screenshot_prepared = FALSE;
}
-static int rgb_rb, rgb_gb, rgb_bb, rgb_rs, rgb_gs, rgb_bs;
+static int rgb_rb, rgb_gb, rgb_bb, rgb_rs, rgb_gs, rgb_bs, rgb_ab, rgb_as;
static int screenshot_prepare (int imagemode, struct vidbuffer *vb)
{
int width, height;
HGDIOBJ hgdiobj;
int bits;
+ int depth = usealpha() ? 32 : 24;
screenshot_free ();
uae_u8 *src, *dst, *mem;
bool needfree = false;
uae_u8 *palette = NULL;
- int rgb_bb2, rgb_gb2, rgb_rb2;
- int rgb_bs2, rgb_gs2, rgb_rs2;
+ int rgb_bb2, rgb_gb2, rgb_rb2, rgb_ab2;
+ int rgb_bs2, rgb_gs2, rgb_rs2, rgb_as2;
uae_u8 pal[256 * 3];
int screenshot_width = 0, screenshot_height = 0;
int screenshot_xoffset = -1, screenshot_yoffset = -1;
rgb_bb2 = 8;
rgb_gb2 = 8;
rgb_rb2 = 8;
+ rgb_ab2 = 8;
rgb_bs2 = 0;
rgb_gs2 = 8;
rgb_rs2 = 16;
+ rgb_as2 = 24;
} else if (vb) {
width = vb->outwidth;
height = vb->outheight;
rgb_bb2 = rgb_bb;
rgb_gb2 = rgb_gb;
rgb_rb2 = rgb_rb;
+ rgb_ab2 = rgb_ab;
rgb_bs2 = rgb_bs;
rgb_gs2 = rgb_gs;
rgb_rs2 = rgb_rs;
+ rgb_as2 = rgb_as;
} else {
src = mem = getfilterbuffer (&width, &height, &spitch, &bits);
needfree = true;
rgb_bb2 = rgb_bb;
rgb_gb2 = rgb_gb;
rgb_rb2 = rgb_rb;
+ rgb_ab2 = rgb_ab;
rgb_bs2 = rgb_bs;
rgb_gs2 = rgb_gs;
rgb_rs2 = rgb_rs;
+ rgb_as2 = rgb_as;
}
if (src == NULL)
goto donormal;
bi->bmiHeader.biWidth = screenshot_width * screenshot_xmult;
bi->bmiHeader.biHeight = screenshot_height * screenshot_ymult;
bi->bmiHeader.biPlanes = 1;
- bi->bmiHeader.biBitCount = bits <= 8 ? 8 : 24;
+ bi->bmiHeader.biBitCount = bits <= 8 ? 8 : depth;
bi->bmiHeader.biCompression = BI_RGB;
dpitch = ((bi->bmiHeader.biWidth * bi->bmiHeader.biBitCount + 31) & ~31) / 8;
bi->bmiHeader.biSizeImage = dpitch * bi->bmiHeader.biHeight;
} else {
int shift;
uae_u32 v = 0;
- uae_u32 v2, v2a, v2b, v2c;
+ uae_u32 v2, v2a, v2b, v2c, v2d;
if (bits == 16)
v = ((uae_u16*)s)[x];
v2 |= (v2 >> shift) & ((1 < shift) - 1);
v2c = v2;
+ if (depth == 32) {
+ shift = 8 - rgb_ab2;
+ v2 = (v >> rgb_as2) & ((1 << rgb_ab2) - 1);
+ v2 <<= (8 - rgb_ab2);
+ if (rgb_ab < 8)
+ v2 |= (v2 >> shift) & ((1 < shift) - 1);
+ v2d = v2;
+ }
+
uae_u8 *d2 = d;
for (int y2 = 0; y2 < ymult; y2++) {
for (int x2 = 0; x2 < xmult; x2++) {
- d2[(xx + x2) * 3 + 0] = v2a;
- d2[(xx + x2) * 3 + 1] = v2b;
- d2[(xx + x2) * 3 + 2] = v2c;
+ if (depth == 32) {
+ d2[(xx + x2) * 4 + 0] = v2a;
+ d2[(xx + x2) * 4 + 1] = v2b;
+ d2[(xx + x2) * 4 + 2] = v2c;
+ d2[(xx + x2) * 4 + 3] = v2d;
+ } else {
+ d2[(xx + x2) * 3 + 0] = v2a;
+ d2[(xx + x2) * 3 + 1] = v2b;
+ d2[(xx + x2) * 3 + 2] = v2c;
+ }
}
d2 += dpitch2;
}
if (s) {
hr = s->LockRect(&l, NULL, D3DLOCK_READONLY);
if (SUCCEEDED(hr)) {
- int dpitch = (((w * 24 + 31) & ~31) / 8);
+ int dpitch = (((w * depth + 31) & ~31) / 8);
lpvBits = xmalloc(uae_u8, dpitch * h);
ZeroMemory(bi, sizeof(bi));
bi->bmiHeader.biWidth = w;
bi->bmiHeader.biHeight = h;
bi->bmiHeader.biPlanes = 1;
- bi->bmiHeader.biBitCount = 24;
+ bi->bmiHeader.biBitCount = depth;
bi->bmiHeader.biCompression = BI_RGB;
bi->bmiHeader.biSizeImage = dpitch * bi->bmiHeader.biHeight;
bi->bmiHeader.biXPelsPerMeter = 0;
d[0] = v >> 0;
d[1] = v >> 8;
d[2] = v >> 16;
- d += 3;
+ if (depth == 32) {
+ d[3] = v >> 24;
+ d += 4;
+ } else {
+ d += 3;
+ }
}
}
} else if (bits == 16 || bits == 15) {
return screenshot_prepare (-1);
}
-void Screenshot_RGBinfo (int rb, int gb, int bb, int rs, int gs, int bs)
+void Screenshot_RGBinfo (int rb, int gb, int bb, int ab, int rs, int gs, int bs, int as)
{
if (!bi)
bi = xcalloc (BITMAPINFO, sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD));
rgb_rb = rb;
rgb_gb = gb;
rgb_bb = rb;
+ rgb_ab = ab;
rgb_rs = rs;
rgb_gs = gs;
rgb_bs = bs;
+ rgb_as = as;
}
#if PNG_SCREENSHOTS > 0
#endif
}
-static int savepng (FILE *fp)
+static int savepng(FILE *fp, bool alpha)
{
png_structp png_ptr;
png_infop info_ptr;
png_init_io (png_ptr, fp);
png_set_filter (png_ptr, 0, PNG_FILTER_NONE);
png_set_IHDR (png_ptr, info_ptr,
- w, h, 8, d <= 8 ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_RGB,
+ w, h, 8, d <= 8 ? PNG_COLOR_TYPE_PALETTE : (alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB),
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
if (d <= 8) {
for (i = 0; i < (1 << d); i++) {
row_pointers = xmalloc (png_bytep, h);
for (i = 0; i < h; i++) {
int j = h - i - 1;
- row_pointers[i] = (uae_u8*)lpvBits + j * (((w * (d <= 8 ? 8 : 24) + 31) & ~31) / 8);
+ row_pointers[i] = (uae_u8*)lpvBits + j * (((w * (d <= 8 ? 8 : (alpha ? 32 : 24)) + 31) & ~31) / 8);
}
png_set_rows (png_ptr, info_ptr, row_pointers);
png_write_png (png_ptr,info_ptr, PNG_TRANSFORM_BGR, NULL);
}
#endif
-static int savebmp (FILE *fp)
+static int savebmp (FILE *fp, bool alpha)
{
BITMAPFILEHEADER bfh;
// write the file header, bitmap information and pixel data
int failed = 0;
int screenshot_max = 1000; // limit 999 iterations / screenshots
TCHAR *format = _T("%s%s%s%03d.%s");
+ bool alpha = usealpha();
HBITMAP offscreen_bitmap = NULL; // bitmap that is converted to a DIB
HDC offscreen_dc = NULL; // offscreen DC that we can select offscreen bitmap into
if (fp) {
#if PNG_SCREENSHOTS > 0
if (screenshotmode)
- failed = savepng (fp);
+ failed = savepng (fp, alpha);
else
#endif
- failed = savebmp (fp);
+ failed = savebmp (fp, alpha);
fclose(fp);
fp = NULL;
if (failed)
}
#if PNG_SCREENSHOTS > 0
if (screenshotmode)
- nok = savepng (fp);
+ nok = savepng (fp, alpha);
else
#endif
- nok = savebmp (fp);
+ nok = savebmp (fp, alpha);
fclose(fp);
if (nok && fp) {
_tunlink(filename);
screenshotf (_T("c:\\temp\\1.bmp"), 1, 1, 1, &vb);
freevidbuffer (&vb);
#endif
-}
\ No newline at end of file
+}
}
}
+STATIC_INLINE void PRGBA(struct vidbuffer *dst, uae_u8 *dataline, uae_u8 r, uae_u8 g, uae_u8 b, uae_u8 a)
+{
+ if (dst->pixbytes == 4) {
+ dataline[0] = b;
+ dataline[1] = g;
+ dataline[2] = r;
+ dataline[3] = a;
+ } else {
+ r >>= 3;
+ g >>= 2;
+ b >>= 3;
+ ((uae_u16*)dataline)[0] = (r << 11) | (g << 5) | b;
+ }
+}
+
+
STATIC_INLINE void PUT_PRGB(uae_u8 *d, uae_u8 *d2, struct vidbuffer *dst, uae_u8 r, uae_u8 g, uae_u8 b, int xadd, int doublelines, bool hdouble)
{
if (hdouble)
}
}
+STATIC_INLINE void PUT_PRGBA(uae_u8 *d, uae_u8 *d2, struct vidbuffer *dst, uae_u8 r, uae_u8 g, uae_u8 b, uae_u8 a, int xadd, int doublelines, bool hdouble)
+{
+ if (hdouble)
+ PRGBA(dst, d - dst->pixbytes, r, g, b, a);
+ PRGBA(dst, d, r, g, b, a);
+ if (xadd >= 2) {
+ PRGBA(dst, d + 1 * dst->pixbytes, r, g, b, a);
+ if (hdouble)
+ PRGBA(dst, d + 2 * dst->pixbytes, r, g, b, a);
+ }
+ if (doublelines) {
+ if (hdouble)
+ PRGBA(dst, d2 - dst->pixbytes, r, g, b, a);
+ PRGBA(dst, d2, r, g, b, a);
+ if (xadd >= 2) {
+ PRGBA(dst, d2 + 1 * dst->pixbytes, r, g, b, a);
+ if (hdouble)
+ PRGBA(dst, d2 + 2 * dst->pixbytes, r, g, b, a);
+ }
+ }
+}
+
STATIC_INLINE void PUT_AMIGARGB(uae_u8 *d, uae_u8 *s, uae_u8 *d2, uae_u8 *s2, struct vidbuffer *dst, int xadd, int doublelines, bool hdouble)
{
if (dst->pixbytes == 4) {
}
}
+STATIC_INLINE void PUT_AMIGARGBA(uae_u8 *d, uae_u8 *s, uae_u8 *d2, uae_u8 *s2, struct vidbuffer *dst, int xadd, int doublelines, bool hdouble)
+{
+ if (dst->pixbytes == 4) {
+ if (hdouble)
+ ((uae_u32*)d)[-1] = (((uae_u32*)s)[-1]) | 0xff000000;
+ ((uae_u32*)d)[0] = (((uae_u32*)s)[0]) | 0xff000000;
+ } else {
+ if (hdouble)
+ ((uae_u16*)d)[-1] = (((uae_u16*)s)[-1]) | 0xff000000;
+ ((uae_u16*)d)[0] = (((uae_u16*)s)[0]) | 0xff000000;
+ }
+ if (doublelines) {
+ if (dst->pixbytes == 4) {
+ if (hdouble)
+ ((uae_u32*)d2)[-1] = (((uae_u32*)s2)[-1]) | 0xff000000;
+ ((uae_u32*)d2)[0] = (((uae_u32*)s2)[0]) | 0xff000000;
+ } else {
+ if (hdouble)
+ ((uae_u16*)d2)[-1] = (((uae_u16*)s2)[-1]) | 0xff000000;
+ ((uae_u16*)d2)[0] = (((uae_u16*)s2)[0]) | 0xff000000;
+ }
+ }
+}
+
static void clearmonitor(struct vidbuffer *dst)
{
uae_u8 *p = dst->bufmem;
mix1 = 256 - currprefs.genlock_mix;
mix2 = currprefs.genlock_mix;
}
+ uae_u8 amix1 = 255 - (currprefs.genlock_mix > 255 ? 255 : 0);
+ uae_u8 amix2 = 255 - amix1;
- uae_u8 r = 0, g = 0, b = 0;
+ uae_u8 r = 0, g = 0, b = 0, a = 0;
for (y = ystart; y < yend; y++) {
int yoff = (((y * 2 + oddlines) - src->yoffset) >> vdbl);
if (yoff < 0)
if (genlock_image_upsidedown)
gy = (genlock_image_height - 1) - gy;
uae_u8 *image_genlock = genlock_image + gy * genlock_image_pitch;
- r = g = b = 0;
+ r = g = b;
+ a = amix1;
noise_add = (quickrand() & 15) | 1;
for (x = 0; x < src->inwidth; x++) {
uae_u8 *s = line + x * src->pixbytes;
uae_u8 *d2 = d + dst->rowbytes;
if (is_transparent(*s_genlock)) {
+ a = amix2;
if (genlock_error) {
r = 0x00;
g = 0x00;
g = (mix1 * g + mix2 * FVG(src, s)) / 256;
b = (mix1 * b + mix2 * FVB(src, s)) / 256;
}
- PUT_PRGB(d, d2, dst, r, g, b, 0, doublelines, false);
+ PUT_PRGBA(d, d2, dst, r, g, b, a, 0, doublelines, false);
} else {
- PUT_AMIGARGB(d, s, d2, s2, dst, 0, doublelines, false);
+ PUT_AMIGARGBA(d, s, d2, s2, dst, 0, doublelines, false);
}
}
}
int address_load;
int rowbytes;
uae_u8 control_line[OPAL_CONTROL_LINE_LENGTH];
+
+ int palcoprocnt;
+ bool copro_hires;
+ int copro_bank_offset[2];
+ int copro_vdm;
+ bool copro_prior_mode;
+ bool copro_priority;
+ bool copro_dual_disp;
+ int address_load_sync;
+ int vram_write_offset;
+ int vram_read_offset;
+ int control_y;
+ bool detected;
};
static struct opals *opal;
}
}
-#define OPAL_SWAP_BANK (opal->dual_play && pf && !copro_hires) || (opal->v2 && opal->opal && opal->dual_play && copro_hires && s_genlock && is_transparent(*s_genlock))
+#define OPAL_SWAP_BANK (opal->dual_play && pf && !opal->copro_hires) || (opal->v2 && opal->opal && opal->dual_play && opal->copro_hires && s_genlock && is_transparent(*s_genlock))
-static bool opalvision(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines, bool isopal)
+static bool opalvision(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines, int yline, bool isopal)
{
int y, x, vdbl, hdbl;
int isntsc;
int yimgstart = ystart + 6;
int yend = (isntsc ? MAXVPOS_NTSC : MAXVPOS_PAL) + 1;
- int palcoprocnt = 0;
-
- bool copro_hires = false;
- int copro_bank_offset[2] = { 0, 0 };
- int copro_vdm = 0;
- bool copro_prior_mode = false;
- bool copro_priority = false;
- bool copro_dual_disp = false;
- int address_load_sync = -1;
- int vram_write_offset = 0;
- int vram_read_offset = 0;
- int control_y = 0;
+ if (yline < 0 || yline == ystart) {
+ opal->address_load_sync = -1;
+ opal->vram_write_offset = 0;
+ opal->vram_read_offset = 0;
+ opal->control_y = 0;
+ opal->copro_prior_mode = false;
+ opal->copro_priority = false;
+ opal->copro_dual_disp = false;
+ opal->copro_vdm = 0;
+ opal->copro_hires = 0;
+ opal->palcoprocnt = 0;
+ opal->detected = opal->latched;
+ }
+
+ if (yline < 0) {
+ y = ystart;
+ } else {
+ y = yline;
+ }
- for (y = ystart; y < yend; y++) {
+ for (; y < yend; y++) {
uae_u8 *line = NULL;
uae_u8 *line_genlock = NULL;
uae_u8 copro = opal->copro[y - ystart];
if (opal->opal) {
- copro_prior_mode = (copro & 0x40) != 0;
- copro_priority = (copro & 0x20) != 0;
- copro_dual_disp = (copro & 0x10) != 0;
- copro_hires = (copro & 8) != 0;
- copro_bank_offset[0] = (copro & 4) ? 6 * OPAL_SEGMENT_SIZE : 0;
- copro_bank_offset[1] = (copro & 4) ? 0 : 6 * OPAL_SEGMENT_SIZE;
- copro_vdm = copro & 3;
+ opal->copro_prior_mode = (copro & 0x40) != 0;
+ opal->copro_priority = (copro & 0x20) != 0;
+ opal->copro_dual_disp = (copro & 0x10) != 0;
+ opal->copro_hires = (copro & 8) != 0;
+ opal->copro_bank_offset[0] = (copro & 4) ? 6 * OPAL_SEGMENT_SIZE : 0;
+ opal->copro_bank_offset[1] = (copro & 4) ? 0 : 6 * OPAL_SEGMENT_SIZE;
+ opal->copro_vdm = copro & 3;
} else {
- copro_vdm = (((copro >> 6) & 1) << 1) | opal->control_line[7];
- copro_hires = (copro & 0x20) != 0;
- copro_prior_mode = (copro & 0x10) != 0;
- copro_priority = (copro & 8) != 0;
- copro_dual_disp = (copro & 4) != 0;
+ opal->copro_vdm = (((copro >> 6) & 1) << 1) | opal->control_line[7];
+ opal->copro_hires = (copro & 0x20) != 0;
+ opal->copro_prior_mode = (copro & 0x10) != 0;
+ opal->copro_priority = (copro & 8) != 0;
+ opal->copro_dual_disp = (copro & 4) != 0;
opal->dual_play = (copro & 2) != 0;
- copro_bank_offset[0] = (copro & 1) ? 6 * OPAL_SEGMENT_SIZE : 0;
- copro_bank_offset[1] = (copro & 1) ? 0 : 6 * OPAL_SEGMENT_SIZE;
+ opal->copro_bank_offset[0] = (copro & 1) ? 6 * OPAL_SEGMENT_SIZE : 0;
+ opal->copro_bank_offset[1] = (copro & 1) ? 0 : 6 * OPAL_SEGMENT_SIZE;
}
- opal->priority_stencil_mode = (copro_prior_mode ? 2 : 0) | (copro_priority ? 4 : 0) | (copro_dual_disp ? 8 : 0);
+ opal->priority_stencil_mode = (opal->copro_prior_mode ? 2 : 0) | (opal->copro_priority ? 4 : 0) | (opal->copro_dual_disp ? 8 : 0);
if (!(copro & 0x80)) {
// Add_Load
- vram_read_offset = opal->address_load;
+ opal->vram_read_offset = opal->address_load;
}
if (!line)
continue;
- int vram_write_pixel_offset = vram_write_offset;
- int vram_read_pixel_offset = vram_read_offset;
+ int vram_write_pixel_offset = opal->vram_write_offset;
+ int vram_read_pixel_offset = opal->vram_read_offset;
// behavior not fully known
if ((!opal->auto_field && opal->bank_field) || (opal->auto_field && oddlines)) {
uae_u8 pf, pr;
int bidx;
- if (copro_vdm == 0) {
+ if (opal->copro_vdm == 0) {
// 24-bit truecolor (palette)
uae_u8 m = opal->pixel_read_mask;
- r = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 0 * OPAL_SEGMENT_SIZE] & m) + 0];
- g = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE] & m) + 1];
- b = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE] & m) + 2];
+ r = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 0 * OPAL_SEGMENT_SIZE] & m) + 0];
+ g = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE] & m) + 1];
+ b = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE] & m) + 2];
pf = g & 1;
pr = b & 1;
if (OPAL_SWAP_BANK) {
- r = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + 0 * OPAL_SEGMENT_SIZE] & m) + 0];
- g = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + 1 * OPAL_SEGMENT_SIZE] & m) + 1];
- b = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + 2 * OPAL_SEGMENT_SIZE] & m) + 2];
+ r = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + 0 * OPAL_SEGMENT_SIZE] & m) + 0];
+ g = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + 1 * OPAL_SEGMENT_SIZE] & m) + 1];
+ b = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + 2 * OPAL_SEGMENT_SIZE] & m) + 2];
bidx = 0;
} else {
bidx = 1;
}
- opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !copro_hires, false);
+ opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !opal->copro_hires, false);
- if (copro_hires) {
- r = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 0 * OPAL_SEGMENT_SIZE] & m) + 0];
- g = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 1 * OPAL_SEGMENT_SIZE] & m) + 1];
- b = opal->palette[4 * (opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 2 * OPAL_SEGMENT_SIZE] & m) + 2];
+ if (opal->copro_hires) {
+ r = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 0 * OPAL_SEGMENT_SIZE] & m) + 0];
+ g = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 1 * OPAL_SEGMENT_SIZE] & m) + 1];
+ b = opal->palette[4 * (opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 2 * OPAL_SEGMENT_SIZE] & m) + 2];
pr = b & 1;
opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, false, true);
}
- } else if (copro_vdm == 1) {
+ } else if (opal->copro_vdm == 1) {
// 24-bit truecolor (bypass palette)
- r = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 0 * OPAL_SEGMENT_SIZE];
- g = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE];
- b = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE];
+ r = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 0 * OPAL_SEGMENT_SIZE];
+ g = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE];
+ b = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE];
pf = g & 1;
pr = b & 1;
if (OPAL_SWAP_BANK) {
- r = opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + 0 * OPAL_SEGMENT_SIZE];
- g = opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + 1 * OPAL_SEGMENT_SIZE];
- b = opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + 2 * OPAL_SEGMENT_SIZE];
+ r = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + 0 * OPAL_SEGMENT_SIZE];
+ g = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + 1 * OPAL_SEGMENT_SIZE];
+ b = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + 2 * OPAL_SEGMENT_SIZE];
bidx = 0;
} else {
bidx = 1;
}
- opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !copro_hires, false);
+ opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !opal->copro_hires, false);
- if (copro_hires) {
- r = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 0 * OPAL_SEGMENT_SIZE];
- g = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 1 * OPAL_SEGMENT_SIZE];
- b = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 2 * OPAL_SEGMENT_SIZE];
+ if (opal->copro_hires) {
+ r = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 0 * OPAL_SEGMENT_SIZE];
+ g = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 1 * OPAL_SEGMENT_SIZE];
+ b = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 2 * OPAL_SEGMENT_SIZE];
pr = b & 1;
opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, false, true);
}
- } else if (copro_vdm == 2) {
+ } else if (opal->copro_vdm == 2) {
// 8-bit palette
- uae_u8 v0 = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + opal->color_offset] & opal->pixel_read_mask;
- pf = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE] & 1;
- pr = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE] & 1;
+ uae_u8 v0 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + opal->color_offset] & opal->pixel_read_mask;
+ pf = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE] & 1;
+ pr = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE] & 1;
if (OPAL_SWAP_BANK) {
- v0 = opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + opal->color_offset] & opal->pixel_read_mask;
+ v0 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + opal->color_offset] & opal->pixel_read_mask;
bidx = 0;
} else {
bidx = 1;
r = opal->palette[v0 * 4 + 0];
g = opal->palette[v0 * 4 + 1];
b = opal->palette[v0 * 4 + 2];
- opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !copro_hires, false);
+ opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !opal->copro_hires, false);
- if (copro_hires) {
- uae_u8 v1 = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + opal->color_offset] & opal->pixel_read_mask;
+ if (opal->copro_hires) {
+ uae_u8 v1 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + opal->color_offset] & opal->pixel_read_mask;
r = opal->palette[v1 * 4 + 0];
g = opal->palette[v1 * 4 + 1];
b = opal->palette[v1 * 4 + 2];
opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, false, true);
}
- } else if (copro_vdm == 3) {
+ } else if (opal->copro_vdm == 3) {
if (((opal->video_command >> 6) & 3) == 3) {
// 15 bit true color
- uae_u8 v0 = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 0 * OPAL_SEGMENT_SIZE];
- uae_u8 v1 = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE];
+ uae_u8 v0 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 0 * OPAL_SEGMENT_SIZE];
+ uae_u8 v1 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE];
r = ((v0 >> 2) & 31) << (8 - 5);
g = (((v0 & 3) << 3) | ((v1 >> 5) &7)) << (8 - 5);
b = ((v1 & 31)) << (8 - 5);
pf = v1 & 1;
- pr = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE] & 1;
+ pr = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE] & 1;
if (OPAL_SWAP_BANK) {
- v0 = opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + 0 * OPAL_SEGMENT_SIZE];
- v1 = opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + 1 * OPAL_SEGMENT_SIZE];
+ v0 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + 0 * OPAL_SEGMENT_SIZE];
+ v1 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + 1 * OPAL_SEGMENT_SIZE];
bidx = 0;
} else {
bidx = 1;
}
- opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !copro_hires, false);
+ opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !opal->copro_hires, false);
- if (copro_hires) {
- v0 = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 0 * OPAL_SEGMENT_SIZE];
- v1 = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 1 * OPAL_SEGMENT_SIZE];
- pr = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 2 * OPAL_SEGMENT_SIZE] & 1;
+ if (opal->copro_hires) {
+ v0 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 0 * OPAL_SEGMENT_SIZE];
+ v1 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 1 * OPAL_SEGMENT_SIZE];
+ pr = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 2 * OPAL_SEGMENT_SIZE] & 1;
r = ((v0 >> 2) & 31) << (8 - 5);
g = (((v0 & 3) << 3) | ((v1 >> 5) & 7)) << (8 - 5);
b = ((v1 & 31)) << (8 - 5);
} else {
// 8-bit true color
- uae_u8 v0 = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + opal->color_offset];
+ uae_u8 v0 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + opal->color_offset];
r = ((v0 >> 5) & 7) << (8 - 3);
g = ((v0 >> 2) & 7) << (8 - 3);
b = ((v0 >> 0) & 3) << (8 - 2);
- pf = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE] & 1;
- pr = opal->vram[vram_read_pixel_offset + copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE] & 1;
+ pf = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 1 * OPAL_SEGMENT_SIZE] & 1;
+ pr = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[0] + 2 * OPAL_SEGMENT_SIZE] & 1;
if (OPAL_SWAP_BANK) {
- v0 = opal->vram[vram_read_pixel_offset + copro_bank_offset[1] + opal->color_offset];
+ v0 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[1] + opal->color_offset];
bidx = 0;
} else {
bidx = 1;
}
- opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !copro_hires, false);
+ opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, !opal->copro_hires, false);
- if (copro_hires) {
- uae_u8 v1 = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + opal->color_offset] & opal->pixel_read_mask;
+ if (opal->copro_hires) {
+ uae_u8 v1 = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + opal->color_offset] & opal->pixel_read_mask;
r = ((v0 >> 5) & 7) << (8 - 3);
g = ((v0 >> 2) & 7) << (8 - 3);
b = ((v0 >> 0) & 3) << (8 - 2);
- pr = opal->vram[vram_read_pixel_offset + copro_bank_offset[bidx] + 2 * OPAL_SEGMENT_SIZE] & 1;
+ pr = opal->vram[vram_read_pixel_offset + opal->copro_bank_offset[bidx] + 2 * OPAL_SEGMENT_SIZE] & 1;
opal_pixel(opal, d, d2, s, s2, s_genlock, src, dst, r, g, b, pr, doublelines, false, true);
}
}
}
}
- if (control_y && y >= control_y) {
+ if (opal->control_y && y >= opal->control_y) {
if (opal_debug & 2)
write_log(_T("%02x."), val);
if (pixcnt >= 1 && pixcnt < 4) {
if (val != 0x00)
- control_y = 0;
+ opal->control_y = 0;
} else if (pixcnt > 0) {
} else if (opal->colcopro) {
if ((pixcnt & 3) != 0) {
- if (palcoprocnt < OPAL_MAXLINES) {
+ if (opal->palcoprocnt < OPAL_MAXLINES) {
if (opal->wren)
- opal->copro[palcoprocnt] = val;
- } else if (palcoprocnt == OPAL_MAXLINES + 7) {
+ opal->copro[opal->palcoprocnt] = val;
+ } else if (opal->palcoprocnt == OPAL_MAXLINES + 7) {
opal->video_command = val;
command_update = true;
} else if (val != 0x00) {
- write_log(_T("COPRO %d = %02x\n"), palcoprocnt, val);
+ write_log(_T("COPRO %d = %02x\n"), opal->palcoprocnt, val);
}
- palcoprocnt++;
+ opal->palcoprocnt++;
}
} else {
- if (y == control_y) {
+ if (y == opal->control_y) {
if (pixcnt == 5) {
opal->palette_load = val;
command_update = true;
}
}
- if ((((y == control_y && pixcnt > 8) || (y > control_y)) && palcoprocnt < 4 * 256) && opal->wren) {
+ if ((((y == opal->control_y && pixcnt > 8) || (y > opal->control_y)) && opal->palcoprocnt < 4 * 256) && opal->wren) {
if (!(opal->video_command & 0x10)) {
// 6-bit palette (2 low bits are simply cleared)
val <<= 2;
}
- opal->palette[(palcoprocnt + (opal->palette_load * 4)) & 1023] = val;
- palcoprocnt++;
+ opal->palette[(opal->palcoprocnt + (opal->palette_load * 4)) & 1023] = val;
+ opal->palcoprocnt++;
}
}
- } else if (pixcnt < 0 && y == control_y + 2) {
+ } else if (pixcnt < 0 && y == opal->control_y + 2) {
- if (address_load_sync < 0 && val == 0xff)
- address_load_sync = 0;
- if (address_load_sync > 0 && address_load_sync < 4) {
- if (address_load_sync == 1 && (val & 0xfe))
+ if (opal->address_load_sync < 0 && val == 0xff)
+ opal->address_load_sync = 0;
+ if (opal->address_load_sync > 0 && opal->address_load_sync < 4) {
+ if (opal->address_load_sync == 1 && (val & 0xfe))
write_log(_T("Address load %02x\n"), val);
opal->address_load <<= 8;
opal->address_load |= val;
opal->address_load &= (OPAL_SEGMENT_SIZE - 1);
}
- if (address_load_sync >= 0)
- address_load_sync++;
+ if (opal->address_load_sync >= 0)
+ opal->address_load_sync++;
}
if (pixcnt >= 0)
pixcnt++;
opal->color_offset = ((opal->video_command >> 6) & 3) * OPAL_SEGMENT_SIZE;
}
- vram_write_offset += opal->rowbytes;
- vram_write_offset &= (OPAL_SEGMENT_SIZE - 1);
+ opal->vram_write_offset += opal->rowbytes;
+ opal->vram_write_offset &= (OPAL_SEGMENT_SIZE - 1);
- vram_read_offset += opal->rowbytes;
- vram_read_offset &= (OPAL_SEGMENT_SIZE - 1);
+ opal->vram_read_offset += opal->rowbytes;
+ opal->vram_read_offset &= (OPAL_SEGMENT_SIZE - 1);
- if (control_y && y >= control_y && (opal_debug & 2)) {
+ if (opal->control_y && y >= opal->control_y && (opal_debug & 2)) {
write_log(_T("\n"));
}
write_log(_T("\n"));
}
- if (y == control_y + 3) {
- control_y = 0;
+ if (y == opal->control_y + 3) {
+ opal->control_y = 0;
}
if (opal->opal && controlcnt >= OPAL_CONTROL_LINE_LENGTH) {
memcpy(opal->control_line, control_line_tmp, OPAL_CONTROL_LINE_LENGTH);
detected = opal->control_line[0] && opal->control_line[2] && !opal->control_line[1] && !opal->control_line[3];
+ opal->detected |= detected;
if (detected) {
- palcoprocnt = 0;
- control_y = y + 1;
+ opal->palcoprocnt = 0;
+ opal->control_y = y + 1;
uae_u8 *c = opal->control_line;
if (opal_debug & 1) {
write_log(_T("WREN=%d COPRO=%d AUTO=%d DP=%d FIELD=%d FM=%d Latch=%d FGrab=%d\n"),
} else if (!opal->opal && controlcnt >= COLORBURST_CONTROL_LINE_LENGTH) {
memcpy(opal->control_line, control_line_tmp, COLORBURST_CONTROL_LINE_LENGTH);
detected = !opal->control_line[0] && !opal->control_line[2] && opal->control_line[1] && opal->control_line[3];
+ opal->detected |= detected;
if (detected) {
- palcoprocnt = 0;
- control_y = y + 1;
+ opal->palcoprocnt = 0;
+ opal->control_y = y + 1;
uae_u8 *c = opal->control_line;
if (opal_debug & 1) {
write_log(_T("WREN=%d COPRO=%d AUTO=%d S0=%d\n"),
}
}
+ if (yline >= 0)
+ break;
+
if (y >= yimgstart && !detected)
return false;
}
+ if (!opal->detected && y == yend)
+ return false;
+
if (opal->opal && monitor != MONITOREMU_OPALVISION) {
monitor = MONITOREMU_OPALVISION;
write_log(_T("Opalvision control line detected\n"));
return true;
}
-static bool do_opalvision(struct vidbuffer *src, struct vidbuffer *dst, bool opal)
+static bool do_opalvision(struct vidbuffer *src, struct vidbuffer *dst, int line, bool opal)
{
bool v;
if (interlace_seen) {
if (currprefs.gfx_iscanlines) {
- v = opalvision(src, dst, false, lof_store ? 0 : 1, opal);
+ v = opalvision(src, dst, false, lof_store ? 0 : 1, line, opal);
if (v && currprefs.gfx_iscanlines > 1)
blank_generic(src, dst, lof_store ? 1 : 0);
} else {
- v = opalvision(src, dst, false, 0, opal);
- v |= opalvision(src, dst, false, 1, opal);
+ v = opalvision(src, dst, false, 0, line, opal);
+ v |= opalvision(src, dst, false, 1, line, opal);
}
} else {
- v = opalvision(src, dst, true, 0, opal);
+ v = opalvision(src, dst, true, 0, line, opal);
}
return v;
}
-static bool emulate_specialmonitors2(struct vidbuffer *src, struct vidbuffer *dst)
+static bool emulate_specialmonitors2(struct vidbuffer *src, struct vidbuffer *dst, int line)
{
automatic = false;
if (currprefs.monitoremu == MONITOREMU_AUTO) {
v = do_avideo(src, dst);
}
if (!v)
- v = do_opalvision(src, dst, true);
+ v = do_opalvision(src, dst, line, true);
if (!v)
- v = do_opalvision(src, dst, false);
+ v = do_opalvision(src, dst, line, false);
return v;
} else if (currprefs.monitoremu == MONITOREMU_A2024) {
return a2024(src, dst);
} else if (currprefs.monitoremu == MONITOREMU_FIRECRACKER24) {
return do_firecracker24(src, dst);
} else if (currprefs.monitoremu == MONITOREMU_OPALVISION) {
- return do_opalvision(src, dst, true);
+ return do_opalvision(src, dst, line, true);
} else if (currprefs.monitoremu == MONITOREMU_COLORBURST) {
- return do_opalvision(src, dst, false);
+ return do_opalvision(src, dst, line, false);
}
return false;
}
bool emulate_specialmonitors(struct vidbuffer *src, struct vidbuffer *dst)
{
- if (!emulate_specialmonitors2(src, dst)) {
+ if (!emulate_specialmonitors2(src, dst, -1)) {
if (monitor) {
clearmonitor(dst);
monitor = 0;
return true;
}
+bool emulate_specialmonitors_line(struct vidbuffer *src, struct vidbuffer *dst, int line)
+{
+ return emulate_specialmonitors2(src, dst, line);
+}
+
void specialmonitor_reset(void)
{
if (!currprefs.monitoremu)
return true;
return false;
}
+
+bool specialmonitor_uses_control_lines(void)
+{
+ switch (currprefs.monitoremu) {
+ case MONITOREMU_GRAFFITI:
+ case MONITOREMU_HAM_E:
+ case MONITOREMU_HAM_E_PLUS:
+ case MONITOREMU_OPALVISION:
+ case MONITOREMU_COLORBURST:
+ return true;
+ }
+ return false;
+}
+
+bool specialmonitor_linebased(void)
+{
+ switch (currprefs.monitoremu) {
+ case MONITOREMU_OPALVISION:
+ case MONITOREMU_COLORBURST:
+ return true;
+ }
+ return false;
+}