Genlock transparency emulation.

This commit is contained in:
Toni Wilen 2015-06-18 20:29:05 +03:00
parent 5e80df2c32
commit 4d65ec3b06
8 changed files with 2499 additions and 89 deletions

View File

@ -158,8 +158,8 @@ static uae_u32 sprite_ab_merge[256];
/* Tables for collision detection. */ /* Tables for collision detection. */
static uae_u32 sprclx[16], clxmask[16]; static uae_u32 sprclx[16], clxmask[16];
/* AGA T genlock bit in color registers */ /* T genlock bit in ECS Denise and AGA color registers */
static uae_u8 color_regs_aga_genlock[256]; static uae_u8 color_regs_genlock[256];
/* /*
* Hardware registers of all sorts. * Hardware registers of all sorts.
@ -2909,15 +2909,18 @@ static void record_color_change (int hpos, int regno, unsigned long value)
static bool isbrdblank (int hpos, uae_u16 bplcon0, uae_u16 bplcon3) static bool isbrdblank (int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
{ {
bool brdblank; bool brdblank, brdntrans;
#ifdef ECS_DENISE #ifdef ECS_DENISE
brdblank = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && (bplcon0 & 1) && (bplcon3 & 0x20); brdblank = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && (bplcon0 & 1) && (bplcon3 & 0x20);
brdntrans = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && (bplcon0 & 1) && (bplcon3 & 0x10);
#else #else
brdblank = false; brdblank = false;
brdntrans = false;
#endif #endif
if (hpos >= 0 && current_colors.borderblank != brdblank) { if (hpos >= 0 && (current_colors.borderblank != brdblank || current_colors.borderntrans != brdntrans)) {
record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (current_colors.bordersprite ? 2 : 0)); record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (current_colors.bordersprite ? 2 : 0) | (brdntrans ? 4 : 0));
current_colors.borderblank = brdblank; current_colors.borderblank = brdblank;
current_colors.borderblank = brdntrans;
remembered_color_entry = -1; remembered_color_entry = -1;
} }
return brdblank; return brdblank;
@ -2933,7 +2936,7 @@ static bool issprbrd (int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
brdsprt = false; brdsprt = false;
#endif #endif
if (hpos >= 0 && current_colors.bordersprite != brdsprt) { if (hpos >= 0 && current_colors.bordersprite != brdsprt) {
record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (current_colors.borderblank ? 1 : 0) | (brdsprt ? 2 : 0)); record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (current_colors.borderblank ? 1 : 0) | (current_colors.borderntrans ? 4 : 0) | (brdsprt ? 2 : 0));
current_colors.bordersprite = brdsprt; current_colors.bordersprite = brdsprt;
remembered_color_entry = -1; remembered_color_entry = -1;
if (brdsprt && !current_colors.borderblank) if (brdsprt && !current_colors.borderblank)
@ -3363,7 +3366,7 @@ static void decide_sprites (int hpos, bool usepointx)
{ {
int nrs[MAX_SPRITES * 2], posns[MAX_SPRITES * 2]; int nrs[MAX_SPRITES * 2], posns[MAX_SPRITES * 2];
int count, i; int count, i;
int point = hpos * 2 + 0; int point;
int width = sprite_width; int width = sprite_width;
int sscanmask = 0x100 << sprite_buffer_res; int sscanmask = 0x100 << sprite_buffer_res;
int gotdata = 0; int gotdata = 0;
@ -3371,6 +3374,12 @@ static void decide_sprites (int hpos, bool usepointx)
if (thisline_decision.plfleft < 0 && !(bplcon3 & 2)) if (thisline_decision.plfleft < 0 && !(bplcon3 & 2))
return; return;
// let sprite shift register empty completely
// if sprite is at the very edge of right border
point = hpos * 2;
if (hpos >= maxhpos)
point += ((9 - 2) * 2) * sprite_buffer_res;
if (nodraw () || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point) if (nodraw () || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point)
return; return;
@ -3393,6 +3402,9 @@ static void decide_sprites (int hpos, bool usepointx)
if (! spr[i].armed) if (! spr[i].armed)
continue; continue;
// if (sprxp > ((maxhpos * 2) << sprite_buffer_res))
// write_log(_T("*"));
if (hw_xp > last_sprite_point && hw_xp <= point + pointx) { if (hw_xp > last_sprite_point && hw_xp <= point + pointx) {
add_sprite (&count, i, sprxp, posns, nrs); add_sprite (&count, i, sprxp, posns, nrs);
} }
@ -5652,6 +5664,10 @@ static void SPRxCTLPOS(int num)
sprstartstop (s); sprstartstop (s);
sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1); sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1);
if (!(fmode & 0x80) && sprxp >= 2 && sprxp <= 9) {
// right border wrap around
sprxp += maxhpos * 2;
}
sprxp <<= sprite_buffer_res; sprxp <<= sprite_buffer_res;
/* Quite a bit salad in this register... */ /* Quite a bit salad in this register... */
if (0) { if (0) {
@ -5873,10 +5889,10 @@ void dump_aga_custom (void)
c2 = c1 + 64; c2 = c1 + 64;
c3 = c2 + 64; c3 = c2 + 64;
c4 = c3 + 64; c4 = c3 + 64;
rgb1 = current_colors.color_regs_aga[c1] | (color_regs_aga_genlock[c1] << 31); rgb1 = current_colors.color_regs_aga[c1];
rgb2 = current_colors.color_regs_aga[c2] | (color_regs_aga_genlock[c2] << 31); rgb2 = current_colors.color_regs_aga[c2];
rgb3 = current_colors.color_regs_aga[c3] | (color_regs_aga_genlock[c3] << 31); rgb3 = current_colors.color_regs_aga[c3];
rgb4 = current_colors.color_regs_aga[c4] | (color_regs_aga_genlock[c4] << 31); rgb4 = current_colors.color_regs_aga[c4];
console_out_f (_T("%3d %08X %3d %08X %3d %08X %3d %08X\n"), console_out_f (_T("%3d %08X %3d %08X %3d %08X %3d %08X\n"),
c1, rgb1, c2, rgb2, c3, rgb3, c4, rgb4); c1, rgb1, c2, rgb2, c3, rgb3, c4, rgb4);
} }
@ -5891,14 +5907,14 @@ static uae_u16 COLOR_READ (int num)
return 0xffff; return 0xffff;
colreg = ((bplcon3 >> 13) & 7) * 32 + num; colreg = ((bplcon3 >> 13) & 7) * 32 + num;
cr = current_colors.color_regs_aga[colreg] >> 16; cr = (current_colors.color_regs_aga[colreg] >> 16) & 0xFF;
cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF; cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF;
cb = current_colors.color_regs_aga[colreg] & 0xFF; cb = current_colors.color_regs_aga[colreg] & 0xFF;
if (bplcon3 & 0x200) { if (bplcon3 & 0x200) {
cval = ((cr & 15) << 8) | ((cg & 15) << 4) | ((cb & 15) << 0); cval = ((cr & 15) << 8) | ((cg & 15) << 4) | ((cb & 15) << 0);
} else { } else {
cval = ((cr >> 4) << 8) | ((cg >> 4) << 4) | ((cb >> 4) << 0); cval = ((cr >> 4) << 8) | ((cg >> 4) << 4) | ((cb >> 4) << 0);
if (color_regs_aga_genlock[num]) if (color_regs_genlock[num])
cval |= 0x8000; cval |= 0x8000;
} }
return cval; return cval;
@ -5931,7 +5947,6 @@ static void checkautoscalecol0 (void)
static void COLOR_WRITE (int hpos, uae_u16 v, int num) static void COLOR_WRITE (int hpos, uae_u16 v, int num)
{ {
bool colzero = false; bool colzero = false;
v &= 0xFFF;
#ifdef AGA #ifdef AGA
if (currprefs.chipset_mask & CSMASK_AGA) { if (currprefs.chipset_mask & CSMASK_AGA) {
int r,g,b; int r,g,b;
@ -5947,7 +5962,7 @@ static void COLOR_WRITE (int hpos, uae_u16 v, int num)
r = (v & 0xF00) >> 8; r = (v & 0xF00) >> 8;
g = (v & 0xF0) >> 4; g = (v & 0xF0) >> 4;
b = (v & 0xF) >> 0; b = (v & 0xF) >> 0;
cr = current_colors.color_regs_aga[colreg] >> 16; cr = (current_colors.color_regs_aga[colreg] >> 16) & 0xFF;
cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF; cg = (current_colors.color_regs_aga[colreg] >> 8) & 0xFF;
cb = current_colors.color_regs_aga[colreg] & 0xFF; cb = current_colors.color_regs_aga[colreg] & 0xFF;
@ -5959,9 +5974,9 @@ static void COLOR_WRITE (int hpos, uae_u16 v, int num)
cr = r + (r << 4); cr = r + (r << 4);
cg = g + (g << 4); cg = g + (g << 4);
cb = b + (b << 4); cb = b + (b << 4);
color_regs_aga_genlock[colreg] = v >> 15; color_regs_genlock[colreg] = v >> 15;
} }
cval = (cr << 16) | (cg << 8) | cb; cval = (cr << 16) | (cg << 8) | cb | (color_regs_genlock[colreg] ? 0x80000000 : 0);
if (cval && colreg == 0) if (cval && colreg == 0)
colzero = true; colzero = true;
@ -5979,6 +5994,10 @@ static void COLOR_WRITE (int hpos, uae_u16 v, int num)
} else { } else {
#endif #endif
v &= 0x8fff;
if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE))
v &= 0xfff;
color_regs_genlock[num] = v >> 15;
if (num && v == 0) if (num && v == 0)
colzero = true; colzero = true;
if (current_colors.color_regs_ecs[num] == v) if (current_colors.color_regs_ecs[num] == v)
@ -9111,8 +9130,11 @@ uae_u8 *restore_custom (uae_u8 *src)
clxcon2 = RW; /* 10E CLXCON2* */ clxcon2 = RW; /* 10E CLXCON2* */
for(i = 0; i < 8; i++) for(i = 0; i < 8; i++)
fetched[i] = RW; /* BPLXDAT */ fetched[i] = RW; /* BPLXDAT */
for(i = 0; i < 32; i++) for(i = 0; i < 32; i++) {
current_colors.color_regs_ecs[i] = RW; /* 180 COLORxx */ uae_u16 v = RW;
color_regs_genlock[i] = (v & 0x8000) != 0;
current_colors.color_regs_ecs[i] = v & 0xfff; /* 180 COLORxx */
}
htotal = RW; /* 1C0 HTOTAL */ htotal = RW; /* 1C0 HTOTAL */
hsstop = RW; /* 1C2 HSTOP ? */ hsstop = RW; /* 1C2 HSTOP ? */
hbstrt = RW; /* 1C4 HBSTRT ? */ hbstrt = RW; /* 1C4 HBSTRT ? */
@ -9288,7 +9310,10 @@ uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full)
v2 |= ((v >> 20) & 15) << 8; v2 |= ((v >> 20) & 15) << 8;
SW (v2); SW (v2);
} else { } else {
SW (current_colors.color_regs_ecs[i]); /* 180-1BE COLORxx */ uae_u16 v = current_colors.color_regs_ecs[i];
if (color_regs_genlock[i])
v |= 0x8000;
SW (v); /* 180-1BE COLORxx */
} }
} }
SW (htotal); /* 1C0 HTOTAL */ SW (htotal); /* 1C0 HTOTAL */
@ -9339,10 +9364,10 @@ uae_u8 *restore_custom_agacolors (uae_u8 *src)
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
#ifdef AGA #ifdef AGA
uae_u32 v = RL; uae_u32 v = RL;
color_regs_aga_genlock[i] = 0; color_regs_genlock[i] = 0;
if (v & 0x80000000) if (v & 0x80000000)
color_regs_aga_genlock[i] = 1; color_regs_genlock[i] = 1;
v &= 0x00ffffff; v &= 0x80ffffff;
current_colors.color_regs_aga[i] = v; current_colors.color_regs_aga[i] = v;
#else #else
RL; RL;
@ -9362,7 +9387,7 @@ uae_u8 *save_custom_agacolors (int *len, uae_u8 *dstptr)
dstbak = dst = xmalloc (uae_u8, 256 * 4); dstbak = dst = xmalloc (uae_u8, 256 * 4);
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
#ifdef AGA #ifdef AGA
SL (current_colors.color_regs_aga[i] | (color_regs_aga_genlock[i] ? 0x80000000 : 0)); SL (current_colors.color_regs_aga[i] | (color_regs_genlock[i] ? 0x80000000 : 0));
#else #else
SL (0); SL (0);
#endif #endif

View File

@ -230,6 +230,9 @@ static uae_u32 plf_sprite_mask;
static int sbasecol[2] = { 16, 16 }; static int sbasecol[2] = { 16, 16 };
static int hposblank; static int hposblank;
static bool specialmonitoron; static bool specialmonitoron;
static bool ecs_genlock_features_active;
static uae_u8 ecs_genlock_features_mask;
static bool ecs_genlock_features_colorkey;
bool picasso_requested_on; bool picasso_requested_on;
bool picasso_on; bool picasso_on;
@ -1219,6 +1222,38 @@ static uae_u8 render_sprites (int pos, int dualpf, uae_u8 apixel, int aga)
return 0; return 0;
} }
static bool get_genlock_very_rare_and_complex_case(uae_u8 v)
{
// border color without BRDNTRAN bit set = transparent
if (v == 0 && !colors_for_drawing.borderntrans)
return false;
if (ecs_genlock_features_colorkey) {
// color key match?
if (currprefs.chipset_mask & CSMASK_AGA) {
if (colors_for_drawing.color_regs_aga[v] & 0x80000000)
return false;
} else {
if (colors_for_drawing.color_regs_ecs[v] & 0x8000)
return false;
}
}
// plane mask match?
if (v & ecs_genlock_features_mask)
return false;
return true;
}
// false = transparent
STATIC_INLINE bool get_genlock_transparency(uae_u8 v)
{
if (!ecs_genlock_features_active) {
if (v == 0)
return false;
return true;
} else {
return get_genlock_very_rare_and_complex_case(v);
}
}
#include "linetoscr.cpp" #include "linetoscr.cpp"
#define LTPARMS src_pixel, start, stop #define LTPARMS src_pixel, start, stop
@ -1882,10 +1917,10 @@ static void init_ham_decoding (void)
int pv = pixdata.apixels[ham_decode_pixel + unpainted_amiga - 1]; int pv = pixdata.apixels[ham_decode_pixel + unpainted_amiga - 1];
#ifdef AGA #ifdef AGA
if (currprefs.chipset_mask & CSMASK_AGA) if (currprefs.chipset_mask & CSMASK_AGA)
ham_lastcolor = colors_for_drawing.color_regs_aga[pv ^ bplxor]; ham_lastcolor = colors_for_drawing.color_regs_aga[pv ^ bplxor] & 0xffffff;
else else
#endif #endif
ham_lastcolor = colors_for_drawing.color_regs_ecs[pv]; ham_lastcolor = colors_for_drawing.color_regs_ecs[pv] & 0xfff;
} }
#ifdef AGA #ifdef AGA
} else if (currprefs.chipset_mask & CSMASK_AGA) { } else if (currprefs.chipset_mask & CSMASK_AGA) {
@ -1894,7 +1929,7 @@ static void init_ham_decoding (void)
int pv = pixdata.apixels[ham_decode_pixel++] ^ bplxor; int pv = pixdata.apixels[ham_decode_pixel++] ^ bplxor;
switch (pv & 0x3) switch (pv & 0x3)
{ {
case 0x0: ham_lastcolor = colors_for_drawing.color_regs_aga[pv >> 2]; break; case 0x0: ham_lastcolor = colors_for_drawing.color_regs_aga[pv >> 2] & 0xffffff; break;
case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pv & 0xFC); break; case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pv & 0xFC); break;
case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pv & 0xFC) << 16; break; case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pv & 0xFC) << 16; break;
case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pv & 0xFC) << 8; break; case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pv & 0xFC) << 8; break;
@ -1905,7 +1940,7 @@ static void init_ham_decoding (void)
int pv = pixdata.apixels[ham_decode_pixel++] ^ bplxor; int pv = pixdata.apixels[ham_decode_pixel++] ^ bplxor;
switch (pv & 0x30) switch (pv & 0x30)
{ {
case 0x00: ham_lastcolor = colors_for_drawing.color_regs_aga[pv]; break; case 0x00: ham_lastcolor = colors_for_drawing.color_regs_aga[pv] & 0xffffff; break;
case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= (pv & 0xF) << 4; break; case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= (pv & 0xF) << 4; break;
case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= (pv & 0xF) << 20; break; case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= (pv & 0xF) << 20; break;
case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= (pv & 0xF) << 12; break; case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= (pv & 0xF) << 12; break;
@ -1919,7 +1954,7 @@ static void init_ham_decoding (void)
int pv = pixdata.apixels[ham_decode_pixel++]; int pv = pixdata.apixels[ham_decode_pixel++];
switch (pv & 0x30) switch (pv & 0x30)
{ {
case 0x00: ham_lastcolor = colors_for_drawing.color_regs_ecs[pv]; break; case 0x00: ham_lastcolor = colors_for_drawing.color_regs_ecs[pv] & 0xfff; break;
case 0x10: ham_lastcolor &= 0xFF0; ham_lastcolor |= (pv & 0xF); break; case 0x10: ham_lastcolor &= 0xFF0; ham_lastcolor |= (pv & 0xF); break;
case 0x20: ham_lastcolor &= 0x0FF; ham_lastcolor |= (pv & 0xF) << 8; break; case 0x20: ham_lastcolor &= 0x0FF; ham_lastcolor |= (pv & 0xF) << 8; break;
case 0x30: ham_lastcolor &= 0xF0F; ham_lastcolor |= (pv & 0xF) << 4; break; case 0x30: ham_lastcolor &= 0xF0F; ham_lastcolor |= (pv & 0xF) << 4; break;
@ -1937,10 +1972,10 @@ static void decode_ham (int pix, int stoppos, bool blank)
int pv = pixdata.apixels[ham_decode_pixel]; int pv = pixdata.apixels[ham_decode_pixel];
#ifdef AGA #ifdef AGA
if (currprefs.chipset_mask & CSMASK_AGA) if (currprefs.chipset_mask & CSMASK_AGA)
ham_lastcolor = colors_for_drawing.color_regs_aga[pv ^ bplxor]; ham_lastcolor = colors_for_drawing.color_regs_aga[pv ^ bplxor] & 0xffffff;
else else
#endif #endif
ham_lastcolor = colors_for_drawing.color_regs_ecs[pv]; ham_lastcolor = colors_for_drawing.color_regs_ecs[pv] & 0xfff;
ham_linebuf[ham_decode_pixel++] = ham_lastcolor; ham_linebuf[ham_decode_pixel++] = ham_lastcolor;
} }
@ -1951,7 +1986,7 @@ static void decode_ham (int pix, int stoppos, bool blank)
int pv = pixdata.apixels[ham_decode_pixel] ^ bplxor; int pv = pixdata.apixels[ham_decode_pixel] ^ bplxor;
switch (pv & 0x3) switch (pv & 0x3)
{ {
case 0x0: ham_lastcolor = colors_for_drawing.color_regs_aga[pv >> 2]; break; case 0x0: ham_lastcolor = colors_for_drawing.color_regs_aga[pv >> 2] & 0xffffff; break;
case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pv & 0xFC); break; case 0x1: ham_lastcolor &= 0xFFFF03; ham_lastcolor |= (pv & 0xFC); break;
case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pv & 0xFC) << 16; break; case 0x2: ham_lastcolor &= 0x03FFFF; ham_lastcolor |= (pv & 0xFC) << 16; break;
case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pv & 0xFC) << 8; break; case 0x3: ham_lastcolor &= 0xFF03FF; ham_lastcolor |= (pv & 0xFC) << 8; break;
@ -1963,7 +1998,7 @@ static void decode_ham (int pix, int stoppos, bool blank)
int pv = pixdata.apixels[ham_decode_pixel] ^ bplxor; int pv = pixdata.apixels[ham_decode_pixel] ^ bplxor;
switch (pv & 0x30) switch (pv & 0x30)
{ {
case 0x00: ham_lastcolor = colors_for_drawing.color_regs_aga[pv]; break; case 0x00: ham_lastcolor = colors_for_drawing.color_regs_aga[pv] & 0xffffff; break;
case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= (pv & 0xF) << 4; break; case 0x10: ham_lastcolor &= 0xFFFF00; ham_lastcolor |= (pv & 0xF) << 4; break;
case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= (pv & 0xF) << 20; break; case 0x20: ham_lastcolor &= 0x00FFFF; ham_lastcolor |= (pv & 0xF) << 20; break;
case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= (pv & 0xF) << 12; break; case 0x30: ham_lastcolor &= 0xFF00FF; ham_lastcolor |= (pv & 0xF) << 12; break;
@ -1978,7 +2013,7 @@ static void decode_ham (int pix, int stoppos, bool blank)
int pv = pixdata.apixels[ham_decode_pixel]; int pv = pixdata.apixels[ham_decode_pixel];
switch (pv & 0x30) switch (pv & 0x30)
{ {
case 0x00: ham_lastcolor = colors_for_drawing.color_regs_ecs[pv]; break; case 0x00: ham_lastcolor = colors_for_drawing.color_regs_ecs[pv] & 0xfff; break;
case 0x10: ham_lastcolor &= 0xFF0; ham_lastcolor |= (pv & 0xF); break; case 0x10: ham_lastcolor &= 0xFF0; ham_lastcolor |= (pv & 0xF); break;
case 0x20: ham_lastcolor &= 0x0FF; ham_lastcolor |= (pv & 0xF) << 8; break; case 0x20: ham_lastcolor &= 0x0FF; ham_lastcolor |= (pv & 0xF) << 8; break;
case 0x30: ham_lastcolor &= 0xF0F; ham_lastcolor |= (pv & 0xF) << 4; break; case 0x30: ham_lastcolor &= 0xF0F; ham_lastcolor |= (pv & 0xF) << 4; break;
@ -2464,6 +2499,17 @@ static void pfield_expand_dp_bplcon (void)
sbasecol[1] = ((dp_for_drawing->bplcon4 >> 0) & 15) << 4; sbasecol[1] = ((dp_for_drawing->bplcon4 >> 0) & 15) << 4;
bplxor = dp_for_drawing->bplcon4 >> 8; bplxor = dp_for_drawing->bplcon4 >> 8;
#endif #endif
ecs_genlock_features_active = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && ((dp_for_drawing->bplcon2 & 0x0c00) || colors_for_drawing.borderntrans) ? 1 : 0;
if (ecs_genlock_features_active) {
ecs_genlock_features_colorkey = false;
ecs_genlock_features_mask = 0;
if (dp_for_drawing->bplcon3 & 0x0800) {
ecs_genlock_features_mask = 1 << ((dp_for_drawing->bplcon2 >> 12) & 7);
}
if (dp_for_drawing->bplcon3 & 0x0400) {
ecs_genlock_features_colorkey = true;
}
}
} }
static bool isham (uae_u16 bplcon0) static bool isham (uae_u16 bplcon0)
@ -2626,6 +2672,7 @@ static void do_color_changes (line_draw_func worker_border, line_draw_func worke
if (regno == 0 && (value & COLOR_CHANGE_BRDBLANK)) { if (regno == 0 && (value & COLOR_CHANGE_BRDBLANK)) {
colors_for_drawing.borderblank = (value & 1) != 0; colors_for_drawing.borderblank = (value & 1) != 0;
colors_for_drawing.bordersprite = (value & 3) == 2; colors_for_drawing.bordersprite = (value & 3) == 2;
colors_for_drawing.borderntrans = (value & 5) == 4;
} else { } else {
color_reg_set (&colors_for_drawing, regno, value); color_reg_set (&colors_for_drawing, regno, value);
colors_for_drawing.acolors[regno] = getxcolor (value); colors_for_drawing.acolors[regno] = getxcolor (value);
@ -3495,6 +3542,21 @@ static void finish_drawing_frame (void)
} }
} }
if (currprefs.genlock_image && !currprefs.monitoremu && gfxvidinfo.tempbuffer.bufmem_allocated && currprefs.genlock) {
setspecialmonitorpos(&gfxvidinfo.tempbuffer);
if (init_genlock_data != specialmonitor_need_genlock()) {
need_genlock_data = init_genlock_data = specialmonitor_need_genlock();
init_row_map();
}
emulate_genlock(vb, &gfxvidinfo.tempbuffer);
vb = gfxvidinfo.outbuffer = &gfxvidinfo.tempbuffer;
if (vb->nativepositioning)
setnativeposition(vb);
gfxvidinfo.drawbuffer.tempbufferinuse = true;
do_flush_screen(vb, 0, vb->outheight);
didflush = true;
}
if (!currprefs.monitoremu && gfxvidinfo.tempbuffer.bufmem_allocated && currprefs.cs_cd32fmv) { if (!currprefs.monitoremu && gfxvidinfo.tempbuffer.bufmem_allocated && currprefs.cs_cd32fmv) {
if (cd32_fmv_active) { if (cd32_fmv_active) {
cd32_fmv_genlock(vb, &gfxvidinfo.tempbuffer); cd32_fmv_genlock(vb, &gfxvidinfo.tempbuffer);

View File

@ -98,20 +98,30 @@ int set_indent (int indent)
return old_indent; return old_indent;
} }
void outln (const char *s) void outindent(void)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < outfile_indent; i++) for (i = 0; i < outfile_indent; i++)
fputc (' ', outfile); fputc(' ', outfile);
}
void outf(const char *s, ...)
{
va_list ap;
va_start(ap, s);
vfprintf(outfile, s, ap);
}
void outln (const char *s)
{
outindent();
fprintf (outfile, "%s\n", s); fprintf (outfile, "%s\n", s);
} }
void outlnf (const char *s, ...) void outlnf (const char *s, ...)
{ {
va_list ap; va_list ap;
unsigned int i; outindent();
for (i = 0; i < outfile_indent; i++)
fputc (' ', outfile);
va_start (ap, s); va_start (ap, s);
vfprintf (outfile, s, ap); vfprintf (outfile, s, ap);
fputc ('\n', outfile); fputc ('\n', outfile);
@ -221,12 +231,50 @@ static void out_linetoscr_do_incspix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE
} }
} }
static void put_dpixsprgenlock(int offset, int genlock)
static void put_dpix (const char *var, int genlock, const char *var2)
{ {
if (genlock!)
return;
if (offset)
outlnf(" genlock_buf[dpix + %d] = get_genlock_transparency(sprcol);", offset);
else
outlnf(" genlock_buf[dpix] = get_genlock_transparency(sprcol);");
}
static void put_dpixgenlock(int offset, CMODE_T cmode, int aga, int genlock, const char *var2)
{
if (!genlock)
return;
outindent();
if (offset)
outf(" genlock_buf[dpix + %d] = get_genlock_transparency(", offset);
else
outf(" genlock_buf[dpix] = get_genlock_transparency(");
if (genlock) { if (genlock) {
outlnf(" genlock_buf[dpix] = %s;", var2 ? var2 : "spix_val"); if (cmode == CMODE_EXTRAHB) {
outf("%s", var2 ? var2 : "spix_val & 31");
}
else if (cmode == CMODE_DUALPF) {
outf("%s", var2 ? var2 : "lookup[spix_val]");
}
else if (cmode == CMODE_HAM) {
if (aga) {
outf("%s", var2 ? var2 : "(spix_val >> 2) & 63");
}
else {
outf("%s", var2 ? var2 : "spix_val & 15");
}
}
else {
outf("%s", var2 ? var2 : "spix_val");
}
} }
outf(");\n");
}
static void put_dpix (const char *var)
{
outlnf(" buf[dpix++] = %s;", var); outlnf(" buf[dpix++] = %s;", var);
} }
@ -238,37 +286,30 @@ static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int
outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf(" if (sprcol) {"); outlnf(" if (sprcol) {");
outlnf ( " out_val = colors_for_drawing.acolors[sprcol];"); outlnf ( " out_val = colors_for_drawing.acolors[sprcol];");
if (genlock) put_dpixsprgenlock(0, genlock);
outlnf(" spix_val = sprcol;");
outlnf(" }"); outlnf(" }");
outlnf(" }"); outlnf(" }");
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
} else if (cnt == 2) { } else if (cnt == 2) {
outlnf ( " {"); outlnf ( " {");
outlnf ( " uae_u32 out_val1 = out_val;"); outlnf ( " uae_u32 out_val1 = out_val;");
outlnf ( " uae_u32 out_val2 = out_val;"); outlnf ( " uae_u32 out_val2 = out_val;");
if (genlock) {
outlnf(" uae_u32 spix_val1 = spix_val;");
outlnf(" uae_u32 spix_val2 = spix_val;");
}
outlnf(" if (spritepixels[dpix + 0].data) {"); outlnf(" if (spritepixels[dpix + 0].data) {");
outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {"); outlnf ( " if (sprcol) {");
outlnf ( " out_val1 = colors_for_drawing.acolors[sprcol];"); outlnf ( " out_val1 = colors_for_drawing.acolors[sprcol];");
if (genlock) put_dpixsprgenlock(0, genlock);
outlnf(" spix_val1 = sprcol;");
outlnf(" }"); outlnf(" }");
outlnf(" }"); outlnf(" }");
outlnf ( " if (spritepixels[dpix + 1].data) {"); outlnf ( " if (spritepixels[dpix + 1].data) {");
outlnf ( " sprcol = render_sprites (dpix + 1, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); outlnf ( " sprcol = render_sprites (dpix + 1, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {"); outlnf ( " if (sprcol) {");
outlnf ( " out_val2 = colors_for_drawing.acolors[sprcol];"); outlnf ( " out_val2 = colors_for_drawing.acolors[sprcol];");
if (genlock) put_dpixsprgenlock(1, genlock);
outlnf(" spix_val2 = sprcol;");
outlnf(" }"); outlnf(" }");
outlnf(" }"); outlnf(" }");
put_dpix("out_val1", genlock, "spix_val1"); put_dpix("out_val1");
put_dpix("out_val2", genlock, "spix_val2"); put_dpix("out_val2");
outlnf ( " }"); outlnf ( " }");
} else if (cnt == 4) { } else if (cnt == 4) {
outlnf ( " {"); outlnf ( " {");
@ -276,62 +317,51 @@ static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int
outlnf ( " uae_u32 out_val2 = out_val;"); outlnf ( " uae_u32 out_val2 = out_val;");
outlnf ( " uae_u32 out_val3 = out_val;"); outlnf ( " uae_u32 out_val3 = out_val;");
outlnf ( " uae_u32 out_val4 = out_val;"); outlnf ( " uae_u32 out_val4 = out_val;");
if (genlock) {
outlnf(" uae_u32 spix_val1 = spix_val;");
outlnf(" uae_u32 spix_val2 = spix_val;");
outlnf(" uae_u32 spix_val3 = spix_val;");
outlnf(" uae_u32 spix_val4 = spix_val;");
}
outlnf(" if (spritepixels[dpix + 0].data) {"); outlnf(" if (spritepixels[dpix + 0].data) {");
outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); outlnf ( " sprcol = render_sprites (dpix + 0, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {"); outlnf ( " if (sprcol) {");
outlnf ( " out_val1 = colors_for_drawing.acolors[sprcol];"); outlnf ( " out_val1 = colors_for_drawing.acolors[sprcol];");
if (genlock) put_dpixsprgenlock(0, genlock);
outlnf(" spix_val1 = sprcol;");
outlnf(" }"); outlnf(" }");
outlnf(" }"); outlnf(" }");
outlnf ( " if (spritepixels[dpix + 1].data) {"); outlnf ( " if (spritepixels[dpix + 1].data) {");
outlnf ( " sprcol = render_sprites (dpix + 1, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); outlnf ( " sprcol = render_sprites (dpix + 1, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {"); outlnf ( " if (sprcol) {");
outlnf ( " out_val2 = colors_for_drawing.acolors[sprcol];"); outlnf ( " out_val2 = colors_for_drawing.acolors[sprcol];");
if (genlock) put_dpixsprgenlock(1, genlock);
outlnf(" spix_val2 = sprcol;");
outlnf(" }"); outlnf(" }");
outlnf(" }"); outlnf(" }");
outlnf ( " if (spritepixels[dpix + 2].data) {"); outlnf ( " if (spritepixels[dpix + 2].data) {");
outlnf ( " sprcol = render_sprites (dpix + 2, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); outlnf ( " sprcol = render_sprites (dpix + 2, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {"); outlnf ( " if (sprcol) {");
outlnf ( " out_val3 = colors_for_drawing.acolors[sprcol];"); outlnf ( " out_val3 = colors_for_drawing.acolors[sprcol];");
if (genlock) put_dpixsprgenlock(2, genlock);
outlnf(" spix_val3 = sprcol;");
outlnf(" }"); outlnf(" }");
outlnf(" }"); outlnf(" }");
outlnf ( " if (spritepixels[dpix + 3].data) {"); outlnf ( " if (spritepixels[dpix + 3].data) {");
outlnf ( " sprcol = render_sprites (dpix + 3, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); outlnf ( " sprcol = render_sprites (dpix + 3, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {"); outlnf ( " if (sprcol) {");
outlnf ( " out_val4 = colors_for_drawing.acolors[sprcol];"); outlnf ( " out_val4 = colors_for_drawing.acolors[sprcol];");
if (genlock) put_dpixsprgenlock(3, genlock);
outlnf(" spix_val4 = sprcol;");
outlnf(" }"); outlnf(" }");
outlnf(" }"); outlnf(" }");
put_dpix("out_val1", genlock, "spix_val1"); put_dpix("out_val1");
put_dpix("out_val2", genlock, "spix_val2"); put_dpix("out_val2");
put_dpix("out_val3", genlock, "spix_val3"); put_dpix("out_val3");
put_dpix("out_val4", genlock, "spix_val4"); put_dpix("out_val4");
outlnf ( " }"); outlnf ( " }");
} }
} else { } else {
outlnf ( " if (spritepixels[dpix].data) {"); outlnf ( " if (spritepixels[dpix].data) {");
outlnf ( " sprcol = render_sprites (dpix, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga); outlnf ( " sprcol = render_sprites (dpix, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
if (genlock) put_dpixsprgenlock(0, genlock);
outlnf(" spix_val = sprcol;");
outlnf(" if (sprcol) {"); outlnf(" if (sprcol) {");
outlnf ( " uae_u32 spcol = colors_for_drawing.acolors[sprcol];"); outlnf ( " uae_u32 spcol = colors_for_drawing.acolors[sprcol];");
outlnf ( " out_val = spcol;"); outlnf ( " out_val = spcol;");
outlnf ( " }"); outlnf ( " }");
outlnf ( " }"); outlnf ( " }");
while (cnt-- > 0) while (cnt-- > 0)
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
} }
} }
@ -356,7 +386,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr);
out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr); out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr);
put_dpix("dpix_val", genlock, NULL); put_dpix("dpix_val");
outln ( "}"); outln ( "}");
outln ( "if (dpix >= dpix_end)"); outln ( "if (dpix >= dpix_end)");
outln ( " return spix;"); outln ( " return spix;");
@ -384,6 +414,18 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
else else
outln ( " out_val = colors_for_drawing.acolors[0];"); outln ( " out_val = colors_for_drawing.acolors[0];");
if (hmode == HMODE_DOUBLE) {
put_dpixgenlock(0, cmode, aga, genlock, NULL);
put_dpixgenlock(1, cmode, aga, genlock, NULL);
} else if (hmode == HMODE_DOUBLE2X) {
put_dpixgenlock(0, cmode, aga, genlock, NULL);
put_dpixgenlock(1, cmode, aga, genlock, NULL);
put_dpixgenlock(2, cmode, aga, genlock, NULL);
put_dpixgenlock(3, cmode, aga, genlock, NULL);
} else {
put_dpixgenlock(0, cmode, aga, genlock, NULL);
}
if (hmode != HMODE_DOUBLE && hmode != HMODE_DOUBLE2X && bpp == DEPTH_16BPP && spr == 0) { if (hmode != HMODE_DOUBLE && hmode != HMODE_DOUBLE2X && bpp == DEPTH_16BPP && spr == 0) {
out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr); out_linetoscr_do_srcpix (bpp, hmode, aga, cmode, spr);
out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr);
@ -410,8 +452,8 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
if (spr) { if (spr) {
out_sprite(bpp, hmode, cmode, aga, 2, spr, genlock); out_sprite(bpp, hmode, cmode, aga, 2, spr, genlock);
} else { } else {
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
} }
} }
} else if (hmode == HMODE_DOUBLE2X) { } else if (hmode == HMODE_DOUBLE2X) {
@ -431,10 +473,10 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
if (spr) { if (spr) {
out_sprite(bpp, hmode, cmode, aga, 4, spr, genlock); out_sprite(bpp, hmode, cmode, aga, 4, spr, genlock);
} else { } else {
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
} }
} }
} else { } else {
@ -449,7 +491,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
if (spr) { if (spr) {
out_sprite(bpp, hmode, cmode, aga, 1, spr, genlock); out_sprite(bpp, hmode, cmode, aga, 1, spr, genlock);
} else { } else {
put_dpix("out_val", genlock, NULL); put_dpix("out_val");
} }
} }
} }
@ -466,7 +508,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM
out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr);
out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr); out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr);
put_dpix("dpix_val", genlock, NULL); put_dpix("dpix_val");
outln ( "}"); outln ( "}");
} }

View File

@ -86,7 +86,7 @@ struct color_entry {
xcolnr acolors[256]; xcolnr acolors[256];
uae_u32 color_regs_aga[256]; uae_u32 color_regs_aga[256];
#endif #endif
bool borderblank, bordersprite; bool borderblank, borderntrans, bordersprite;
}; };
#ifdef AGA #ifdef AGA

View File

@ -4,3 +4,4 @@ void specialmonitor_store_fmode(int vpos, int hpos, uae_u16 fmode);
void specialmonitor_reset(void); void specialmonitor_reset(void);
bool specialmonitor_need_genlock(void); bool specialmonitor_need_genlock(void);
addrbank *specialmonitor_autoconfig_init(int devnum); addrbank *specialmonitor_autoconfig_init(int devnum);
bool emulate_genlock(struct vidbuffer*, struct vidbuffer*);

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -11,6 +11,7 @@
#include "memory.h" #include "memory.h"
#include "specialmonitors.h" #include "specialmonitors.h"
#include "debug.h" #include "debug.h"
#include "zfile.h"
static bool automatic; static bool automatic;
static int monitor; static int monitor;
@ -20,6 +21,11 @@ extern uae_u8 **row_map_genlock;
static uae_u8 graffiti_palette[256 * 4]; static uae_u8 graffiti_palette[256 * 4];
STATIC_INLINE bool is_transparent(uae_u8 v)
{
return v == 0;
}
STATIC_INLINE uae_u8 FVR(struct vidbuffer *src, uae_u8 *dataline) STATIC_INLINE uae_u8 FVR(struct vidbuffer *src, uae_u8 *dataline)
{ {
if (src->pixbytes == 4) if (src->pixbytes == 4)
@ -382,7 +388,7 @@ static bool firecracker24(struct vidbuffer *src, struct vidbuffer *dst, bool dou
b = vramptr[3]; b = vramptr[3];
} }
} }
if (!(fc24_cr0 & 1) && (!(fc24_cr1 & 1) || (s_genlock[0] != 0))) { if (!(fc24_cr0 & 1) && (!(fc24_cr1 & 1) || (!is_transparent(s_genlock[0])))) {
uae_u8 *s2 = s + src->rowbytes; uae_u8 *s2 = s + src->rowbytes;
uae_u8 *d2 = d + dst->rowbytes; uae_u8 *d2 = d + dst->rowbytes;
PUT_AMIGARGB(d, s, d2, s2, dst, xadd, doublelines, false); PUT_AMIGARGB(d, s, d2, s2, dst, xadd, doublelines, false);
@ -598,7 +604,7 @@ static void REGPARAM2 sm_bput(uaecptr addr, uae_u32 b)
if (!sm_configured) { if (!sm_configured) {
switch (addr) { switch (addr) {
case 0x48: case 0x48:
map_banks(&specialmonitors_bank, expamem_z2_pointer >> 16, 65536 >> 16, 0); map_banks_z2(&specialmonitors_bank, expamem_z2_pointer >> 16, 65536 >> 16);
sm_configured = 1; sm_configured = 1;
expamem_next(&specialmonitors_bank, NULL); expamem_next(&specialmonitors_bank, NULL);
break; break;
@ -1821,5 +1827,264 @@ bool specialmonitor_need_genlock(void)
case MONITOREMU_HAM_E_PLUS: case MONITOREMU_HAM_E_PLUS:
return true; return true;
} }
if (currprefs.genlock_image && currprefs.genlock)
return true;
return false; return false;
} }
static uae_u8 *genlock_image;
static int genlock_image_width, genlock_image_height, genlock_image_pitch;
static uae_u8 noise_buffer[1024];
static uae_u32 noise_seed, noise_add, noise_index;
static uae_u32 quickrand(void)
{
noise_seed = (noise_seed >> 1) ^ (0 - (noise_seed & 1) & 0xd0000001);
return noise_seed;
}
static void init_noise(void)
{
noise_seed++;
for (int i = 0; i < sizeof noise_buffer; i++) {
noise_buffer[i] = quickrand();
}
}
static uae_u8 get_noise(void)
{
noise_index += noise_add;
noise_index &= 1023;
return noise_buffer[noise_index];
}
#include "png.h"
struct png_cb
{
uae_u8 *ptr;
int size;
};
static void __cdecl readcallback(png_structp png_ptr, png_bytep out, png_size_t count)
{
png_voidp io_ptr = png_get_io_ptr(png_ptr);
if (!io_ptr)
return;
struct png_cb *cb = (struct png_cb*)io_ptr;
if (count > cb->size)
count = cb->size;
memcpy(out, cb->ptr, count);
cb->ptr += count;
cb->size -= count;
}
static void load_genlock_image(void)
{
extern unsigned char test_card_png[];
extern unsigned int test_card_png_len;
uae_u8 *b = test_card_png;
uae_u8 *bfree = NULL;
int file_size = test_card_png_len;
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 width, height;
int depth, color_type;
struct png_cb cb;
xfree(genlock_image);
genlock_image = NULL;
if (currprefs.genlock_image == 3) {
int size;
uae_u8 *bb = zfile_load_file(currprefs.genlock_image_file, &size);
if (bb) {
file_size = size;
b = bb;
bfree = bb;
}
}
if (!png_check_sig(b, 8))
goto end;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr)
goto end;
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, 0, 0);
goto end;
}
cb.ptr = b;
cb.size = file_size;
png_set_read_fn(png_ptr, &cb, readcallback);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &depth, &color_type, 0, 0, 0);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8)
png_set_expand(png_ptr);
if (depth > 8)
png_set_strip_16(png_ptr);
if (depth < 8)
png_set_packing(png_ptr);
if (!(color_type & PNG_COLOR_MASK_ALPHA))
png_set_add_alpha(png_ptr, 0, PNG_FILLER_AFTER);
png_size_t cols = png_get_rowbytes(png_ptr, info_ptr);
genlock_image_pitch = width * 4;
genlock_image_width = width;
genlock_image_height = height;
png_bytepp row_pp = new png_bytep[height];
genlock_image = xcalloc(uae_u8, width * height * 4);
for (int i = 0; i < height; i++) {
row_pp[i] = (png_bytep) &genlock_image[i * genlock_image_pitch];
}
png_read_image(png_ptr, row_pp);
png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
delete[] row_pp;
end:
xfree(bfree);
}
static bool do_genlock(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines)
{
int y, x, vdbl, hdbl;
int ystart, yend, isntsc;
int gl_vdbl_l, gl_vdbl_r;
int gl_hdbl_l, gl_hdbl_r, gl_hdbl;
int gl_hcenter, gl_vcenter;
isntsc = (beamcon0 & 0x20) ? 0 : 1;
if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
isntsc = currprefs.ntscmode ? 1 : 0;
if (!genlock_image && currprefs.genlock_image == 2) {
load_genlock_image();
}
if (genlock_image && currprefs.genlock_image != 2) {
xfree(genlock_image);
genlock_image = NULL;
}
if (gfxvidinfo.xchange == 1)
hdbl = 0;
else if (gfxvidinfo.xchange == 2)
hdbl = 1;
else
hdbl = 2;
gl_hdbl_l = gl_hdbl_r = 0;
if (genlock_image_width < 600) {
gl_hdbl = 0;
} else if (genlock_image_width < 1000) {
gl_hdbl = 1;
} else {
gl_hdbl = 2;
}
if (hdbl >= gl_hdbl) {
gl_hdbl_l = hdbl - gl_hdbl;
} else {
gl_hdbl_r = gl_hdbl - hdbl;
}
if (gfxvidinfo.ychange == 1)
vdbl = 0;
else
vdbl = 1;
gl_vdbl_l = gl_vdbl_r = 0;
gl_hcenter = (genlock_image_width - ((src->inwidth << hdbl) >> gl_hdbl)) / 2;
ystart = isntsc ? VBLANK_ENDLINE_NTSC : VBLANK_ENDLINE_PAL;
yend = isntsc ? MAXVPOS_NTSC : MAXVPOS_PAL;
gl_vcenter = (((genlock_image_height << gl_vdbl_l) >> gl_vdbl_r) - (((yend - ystart) * 2))) / 2;
init_noise();
uae_u8 r = 0, g = 0, b = 0;
for (y = ystart; y < yend; y++) {
int yoff = (((y * 2 + oddlines) - src->yoffset) >> vdbl);
if (yoff < 0)
continue;
if (yoff >= src->inheight)
continue;
uae_u8 *line = src->bufmem + yoff * src->rowbytes;
uae_u8 *dstline = dst->bufmem + (((y * 2 + oddlines) - dst->yoffset) >> vdbl) * dst->rowbytes;
uae_u8 *line_genlock = row_map_genlock[yoff];
int gy = ((((y * 2 + oddlines) - dst->yoffset) << gl_vdbl_l) >> gl_vdbl_r) + gl_vcenter;
uae_u8 *image_genlock = genlock_image + gy * genlock_image_pitch;
r = g = b = 0;
noise_add = (quickrand() & 15) | 1;
for (x = 0; x < src->inwidth; x++) {
uae_u8 *s = line + x * src->pixbytes;
uae_u8 *d = dstline + x * dst->pixbytes;
uae_u8 *s_genlock = line_genlock + x;
uae_u8 *s2 = s + src->rowbytes;
uae_u8 *d2 = d + dst->rowbytes;
if (is_transparent(*s_genlock)) {
if (genlock_image) {
int gx = (((x + gl_hcenter) << gl_hdbl_l) >> gl_hdbl_r);
if (gx >= 0 && gx < genlock_image_width && gy >= 0 && gy < genlock_image_height) {
uae_u8 *s_genlock_image = image_genlock + gx * 4;
r = s_genlock_image[0];
g = s_genlock_image[1];
b = s_genlock_image[2];
} else {
r = g = b = 0;
}
} else {
r = g = b = get_noise();
}
PUT_PRGB(d, d2, dst, r, g, b, 0, doublelines, false);
} else {
PUT_AMIGARGB(d, s, d2, s2, dst, 0, doublelines, false);
}
}
}
dst->nativepositioning = true;
return true;
}
bool emulate_genlock(struct vidbuffer *src, struct vidbuffer *dst)
{
bool v;
if (interlace_seen) {
if (currprefs.gfx_iscanlines) {
v = do_genlock(src, dst, false, lof_store ? 0 : 1);
if (v && currprefs.gfx_iscanlines > 1)
blank_generic(src, dst, lof_store ? 1 : 0);
} else {
v = do_genlock(src, dst, false, 0);
v |= do_genlock(src, dst, false, 1);
}
} else {
if (currprefs.gfx_pscanlines) {
v = do_genlock(src, dst, false, lof_store ? 0 : 1);
if (v && currprefs.gfx_pscanlines > 1)
blank_generic(src, dst, lof_store ? 1 : 0);
} else {
v = do_genlock(src, dst, true, 0);
}
}
return v;
}

2015
test_card.cpp Normal file

File diff suppressed because it is too large Load Diff