Genlock emulation fixes and genlock_effects genlock manual feature enable.

This commit is contained in:
Toni Wilen 2022-09-24 20:22:28 +03:00
parent 44f1045bd9
commit 1a7afe84e1
7 changed files with 177 additions and 69 deletions

View File

@ -2429,6 +2429,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
cfgfile_dwrite_str (f, _T("waiting_blits"), waitblits[p->waiting_blits]);
cfgfile_dwrite (f, _T("blitter_throttle"), _T("%.8f"), p->blitter_speed_throttle);
cfgfile_write_bool (f, _T("ntsc"), p->ntscmode);
cfgfile_write_bool(f, _T("genlock"), p->genlock);
cfgfile_dwrite_bool(f, _T("genlock_alpha"), p->genlock_alpha);
cfgfile_dwrite_bool(f, _T("genlock_aspect"), p->genlock_aspect);
@ -2437,6 +2438,38 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
cfgfile_dwrite_str(f, _T("genlock_video"), p->genlock_video_file);
cfgfile_dwrite(f, _T("genlock_mix"), _T("%d"), p->genlock_mix);
cfgfile_dwrite(f, _T("genlock_scale"), _T("%d"), p->genlock_scale);
if (p->genlock_effects) {
tmp[0] = 0;
if (p->genlock_effects & (1 << 4)) {
_tcscat(tmp, _T("brdntran"));
}
if (p->genlock_effects & (1 << 5)) {
if (tmp[0]) {
_tcscat(tmp, _T(","));
}
_tcscat(tmp, _T("brdrblnk"));
}
for (int i = 0; i < 256; i++) {
uae_u64 v = p->ecs_genlock_features_colorkey_mask[i / 64];
if (v & (1LL << (i & 63))) {
if (tmp[0]) {
_tcscat(tmp, _T(","));
}
_stprintf(tmp + _tcslen(tmp), _T("%d"), i);
}
}
for (int i = 0; i < 8; i++) {
if (p->ecs_genlock_features_plane_mask & (1 << i)) {
if (tmp[0]) {
_tcscat(tmp, _T(","));
}
_stprintf(tmp + _tcslen(tmp), _T("p%d"), i);
}
}
cfgfile_dwrite_str(f, _T("genlock_effects"), tmp);
}
cfgfile_dwrite_str(f, _T("monitoremu"), specialmonitorconfignames[p->monitoremu]);
cfgfile_dwrite(f, _T("monitoremu_monitor"), _T("%d"), p->monitoremu_mon);
cfgfile_dwrite_coords(f, _T("lightpen_offset"), p->lightpen_offset[0], p->lightpen_offset[1]);
@ -6159,6 +6192,44 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
return 1;
}
if (cfgfile_string(option, value, _T("genlock_effects"), tmpbuf, sizeof(tmpbuf) / sizeof(TCHAR))) {
TCHAR *s = tmpbuf;
TCHAR *endptr;
if (cfgfile_option_get(value, _T("brdntran"))) {
p->genlock_effects |= 1 << 4;
}
if (cfgfile_option_get(value, _T("brdrblnk"))) {
p->genlock_effects |= 1 << 5;
}
while (s && s[0]) {
TCHAR *tmpp = _tcschr (s, ',');
if (tmpp) {
*tmpp++ = 0;
}
int plane = 0;
if (s[0] == 'p' || s[0] == 'P') {
s++;
plane = 1;
}
int val = _tcstol(s, &endptr, 10);
if (val > 0 || (val == 0 && s[0] == '0')) {
if (plane == 1) {
p->ecs_genlock_features_plane_mask |= 1 << val;
p->genlock_effects |= 2;
} else {
for (int i = 0; i < 4 && val >= 0; i++, val -= 64) {
if (val < 64) {
p->ecs_genlock_features_colorkey_mask[i] |= 1LL << val;
p->genlock_effects |= 1;
}
}
}
}
s = tmpp;
}
return 1;
}
if (cfgfile_parse_filesys (p, option, value))
return 1;

View File

@ -4586,8 +4586,8 @@ static bool isbrdblank(int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
{
bool brdblank, brdntrans, extblank;
#ifdef ECS_DENISE
brdblank = ecs_denise && (bplcon0 & 1) && (bplcon3 & 0x20);
brdntrans = ecs_denise && (bplcon0 & 1) && (bplcon3 & 0x10);
brdblank = (ecs_denise && (bplcon0 & 1) && (bplcon3 & 0x20)) || (currprefs.genlock_effects & (1 << 5));
brdntrans = (ecs_denise && (bplcon0 & 1) && (bplcon3 & 0x10)) || (currprefs.genlock_effects & (1 << 4));
// ECSENA=0: hardwired horizontal, strobe vertical
// ECSENA=1: EXTBLKEN=0: hardwired blanking, strobe vertical
// ECSENA=1: EXTBLKEN=1: blanking equals HSYNC if VARCSYEN=1, blanking equals HBSTRT-HBSTOP if VARCSYEN=0, no vertical, AGA: programmed horizontal, strobe vertical
@ -6948,7 +6948,7 @@ STATIC_INLINE int islightpentriggered(void)
}
STATIC_INLINE int issyncstopped(void)
{
return (bplcon0 & 2) && !currprefs.genlock;
return (bplcon0 & 2) && (!currprefs.genlock || currprefs.genlock_effects);
}
STATIC_INLINE int GETVPOS(void)
@ -6963,7 +6963,7 @@ STATIC_INLINE int GETHPOS(void)
// fake changing hpos when rom genlock test runs and genlock is connected
static bool hsyncdelay(void)
{
if (!currprefs.genlock) {
if (!currprefs.genlock || currprefs.genlock_effects) {
return false;
}
if (currprefs.cpu_memory_cycle_exact || currprefs.m68k_speed >= 0) {
@ -11098,7 +11098,7 @@ static void vsync_handler_post(void)
genlockvtoggle = lof_store ? 1 : 0;
}
if ((bplcon0 & 2) && !currprefs.genlock) {
if ((bplcon0 & 2) && (!currprefs.genlock || currprefs.genlock_effects)) {
nosignal_trigger = true;
}
// Inverted CSYNC

View File

@ -1429,6 +1429,67 @@ STATIC_INLINE uae_u32 merge_2pixel32 (uae_u32 p1, uae_u32 p2)
return v;
}
static bool get_genlock_very_rare_and_complex_case(uae_u8 v)
{
if (ecs_genlock_features_colorkey) {
if (currprefs.genlock_effects) {
if (v < 64 && (currprefs.ecs_genlock_features_colorkey_mask[0] & (1LL << v))) {
return false;
}
if (v >= 64 && v < 128 && (currprefs.ecs_genlock_features_colorkey_mask[1] & (1LL << (v - 64)))) {
return false;
}
if (v >= 128 && v < 192 && (currprefs.ecs_genlock_features_colorkey_mask[2] & (1LL << (v - 128)))) {
return false;
}
if (v >= 192 && v < 256 && (currprefs.ecs_genlock_features_colorkey_mask[3] & (1LL << (v - 192)))) {
return false;
}
} else {
// color key match?
if (aga_mode) {
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 (currprefs.genlock_effects) {
if (v & currprefs.ecs_genlock_features_plane_mask)
return false;
} else {
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);
}
}
STATIC_INLINE bool get_genlock_transparency_border(void)
{
if (!ecs_genlock_features_active) {
return false;
} else {
// border color with BRDNTRAN bit set = not transparent
if (ce_is_borderntrans(colors_for_drawing.extra))
return true;
return get_genlock_very_rare_and_complex_case(0);
}
}
STATIC_INLINE void fill_line_16 (uae_u8 *buf, int start, int stop, int blank)
{
uae_u16 *b = (uae_u16 *)buf;
@ -1470,7 +1531,7 @@ static void pfield_do_fill_line (int start, int stop, int blank)
case 4: fill_line_32 (xlinebuffer, start, stop, blank); break;
}
if (need_genlock_data) {
memset(xlinebuffer_genlock + start, 0, stop - start);
memset(xlinebuffer_genlock + start, get_genlock_transparency_border(), stop - start);
}
}
@ -1537,7 +1598,7 @@ static void fill_line_border(int lineno)
hposblank = 3;
fill_line2(lastpos, w);
if (need_genlock_data) {
memset(xlinebuffer_genlock + lastpos, 0, w);
memset(xlinebuffer_genlock + lastpos, get_genlock_transparency_border(), w);
}
hposblank = b;
return;
@ -1548,7 +1609,7 @@ static void fill_line_border(int lineno)
hposblank = 3;
fill_line2(lastpos, w);
if (need_genlock_data) {
memset(xlinebuffer_genlock + lastpos, 0, w);
memset(xlinebuffer_genlock + lastpos, get_genlock_transparency_border(), w);
}
return;
}
@ -1556,7 +1617,7 @@ static void fill_line_border(int lineno)
if (hblank_left <= lastpos && hblank_right >= endpos) {
fill_line2(lastpos, w);
if (need_genlock_data) {
memset(xlinebuffer_genlock + lastpos, 0, w);
memset(xlinebuffer_genlock + lastpos, get_genlock_transparency_border(), w);
}
return;
}
@ -1670,38 +1731,6 @@ static uae_u8 render_sprites(int pos, int dualpf, uae_u8 apixel, int aga)
return 0;
}
static bool get_genlock_very_rare_and_complex_case(uae_u8 v)
{
// border color without BRDNTRAN bit set = transparent
if (v == 0 && !ce_is_borderntrans(colors_for_drawing.extra))
return false;
if (ecs_genlock_features_colorkey) {
// color key match?
if (aga_mode) {
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"
#define LTPARMS src_pixel, start, stop
@ -3282,14 +3311,16 @@ static void pfield_expand_dp_bplcon(void)
sprite_smaller_than_64_inuse = true;
sprite_smaller_than_64 = (dp_for_drawing->fmode & 0x0c) != 0x0c;
#endif
ecs_genlock_features_active = ecs_denise && ((dp_for_drawing->bplcon2 & 0x0c00) || ce_is_borderntrans(colors_for_drawing.extra)) ? 1 : 0;
ecs_genlock_features_active = (ecs_denise && ((dp_for_drawing->bplcon2 & 0x0c00) || ce_is_borderntrans(colors_for_drawing.extra))) || (currprefs.genlock_effects ? 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) {
uae_u16 bc2 = dp_for_drawing->bplcon2;
ecs_genlock_features_colorkey = currprefs.ecs_genlock_features_colorkey_mask[0] || currprefs.ecs_genlock_features_colorkey_mask[1] ||
currprefs.ecs_genlock_features_colorkey_mask[2] || currprefs.ecs_genlock_features_colorkey_mask[3];
ecs_genlock_features_mask = currprefs.ecs_genlock_features_plane_mask;
if (bc2 & 0x0800) {
ecs_genlock_features_mask = 1 << ((bc2 >> 12) & 7);
}
if (bc2 & 0x0400) {
ecs_genlock_features_colorkey = true;
}
}
@ -4741,7 +4772,7 @@ static void finish_drawing_frame(bool drawlines)
}
// genlock
if (currprefs.genlock_image && currprefs.genlock && !currprefs.monitoremu && vidinfo->tempbuffer.bufmem_allocated) {
if (currprefs.genlock_image && (currprefs.genlock || currprefs.genlock_effects) && !currprefs.monitoremu && vidinfo->tempbuffer.bufmem_allocated) {
setspecialmonitorpos(&vidinfo->tempbuffer);
if (init_genlock_data != specialmonitor_need_genlock()) {
need_genlock_data = init_genlock_data = specialmonitor_need_genlock();

View File

@ -243,12 +243,14 @@ 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_dpixsprgenlock(int offset, int genlock, bool subpixel)
{
if (!genlock)
return;
if (offset)
outlnf(" genlock_buf[dpix + %d] = get_genlock_transparency(sprcol);", offset);
if (offset && subpixel)
outlnf(" genlock_buf[dpix + %d] = get_genlock_transparency(sprcol);\n", offset);
else if (offset && !subpixel)
outlnf(" genlock_buf[dpix + %d] = genlock_buf[dpix];\n", offset);
else
outlnf(" genlock_buf[dpix] = get_genlock_transparency(sprcol);");
}
@ -258,12 +260,10 @@ static void put_dpixgenlock(int offset, CMODE_T cmode, int aga, int genlock, con
if (!genlock)
return;
outindent();
if (offset)
outf(" genlock_buf[dpix + %d] = get_genlock_transparency(", offset);
else
if (offset) {
outf(" genlock_buf[dpix + %d] = genlock_buf[dpix];\n", offset);
} else {
outf(" genlock_buf[dpix] = get_genlock_transparency(");
if (genlock) {
if (cmode == CMODE_EXTRAHB) {
outf("%s", var2 ? var2 : "spix_val & 31");
}
@ -281,8 +281,8 @@ static void put_dpixgenlock(int offset, CMODE_T cmode, int aga, int genlock, con
else {
outf("%s", var2 ? var2 : "spix_val");
}
outf(");\n");
}
outf(");\n");
}
static void put_dpix (const char *var)
@ -298,7 +298,7 @@ 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(" if (sprcol) {");
outlnf ( " out_val = p_acolors[sprcol];");
put_dpixsprgenlock(0, genlock);
put_dpixsprgenlock(0, genlock, true);
outlnf(" }");
outlnf(" }");
put_dpix("out_val");
@ -310,14 +310,14 @@ 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 ( " if (sprcol) {");
outlnf ( " out_val1 = p_acolors[sprcol];");
put_dpixsprgenlock(0, genlock);
put_dpixsprgenlock(0, genlock, true);
outlnf(" }");
outlnf(" }");
outlnf ( " if (spritepixels[dpix + 1].data) {");
outlnf ( " sprcol = render_sprites (dpix + 1, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {");
outlnf ( " out_val2 = p_acolors[sprcol];");
put_dpixsprgenlock(1, genlock);
put_dpixsprgenlock(1, genlock, true);
outlnf(" }");
outlnf(" }");
put_dpix("out_val1");
@ -333,28 +333,28 @@ 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 ( " if (sprcol) {");
outlnf ( " out_val1 = p_acolors[sprcol];");
put_dpixsprgenlock(0, genlock);
put_dpixsprgenlock(0, genlock, true);
outlnf(" }");
outlnf(" }");
outlnf ( " if (spritepixels[dpix + 1].data) {");
outlnf ( " sprcol = render_sprites (dpix + 1, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {");
outlnf ( " out_val2 = p_acolors[sprcol];");
put_dpixsprgenlock(1, genlock);
put_dpixsprgenlock(1, genlock, true);
outlnf(" }");
outlnf(" }");
outlnf ( " if (spritepixels[dpix + 2].data) {");
outlnf ( " sprcol = render_sprites (dpix + 2, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {");
outlnf ( " out_val3 = p_acolors[sprcol];");
put_dpixsprgenlock(2, genlock);
put_dpixsprgenlock(2, genlock, true);
outlnf(" }");
outlnf(" }");
outlnf ( " if (spritepixels[dpix + 3].data) {");
outlnf ( " sprcol = render_sprites (dpix + 3, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
outlnf ( " if (sprcol) {");
outlnf ( " out_val4 = p_acolors[sprcol];");
put_dpixsprgenlock(3, genlock);
put_dpixsprgenlock(3, genlock, true);
outlnf(" }");
outlnf(" }");
put_dpix("out_val1");
@ -366,14 +366,17 @@ static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int
} else {
outlnf ( " if (spritepixels[dpix].data) {");
outlnf ( " sprcol = render_sprites (dpix, %d, sprpix_val, %d);", cmode == CMODE_DUALPF ? 1 : 0, aga);
put_dpixsprgenlock(0, genlock);
outlnf(" if (sprcol) {");
outlnf ( " uae_u32 spcol = p_acolors[sprcol];");
outlnf ( " out_val = spcol;");
for (int i = 0; i < cnt; i++) {
put_dpixsprgenlock(i, genlock, false);
}
outlnf ( " }");
outlnf ( " }");
while (cnt-- > 0)
for (int i = 0; i < cnt; i++) {
put_dpix("out_val");
}
}
}

View File

@ -601,6 +601,9 @@ struct uae_prefs {
int genlock_mix;
int genlock_scale;
int genlock_aspect;
int genlock_effects;
uae_u64 ecs_genlock_features_colorkey_mask[4];
uae_u8 ecs_genlock_features_plane_mask;
bool genlock_alpha;
TCHAR genlock_image_file[MAX_DPATH];
TCHAR genlock_video_file[MAX_DPATH];

View File

@ -3954,7 +3954,7 @@ retry:
allocsoftbuffer(mon->monitor_id, _T("draw"), &avidinfo->drawbuffer, mon->currentmode.flags,
1920, 1280, mon->currentmode.current_depth);
if (currprefs.monitoremu || currprefs.cs_cd32fmv || (currprefs.genlock && currprefs.genlock_image) || currprefs.cs_color_burst || currprefs.gfx_grayscale) {
if (currprefs.monitoremu || currprefs.cs_cd32fmv || ((currprefs.genlock || currprefs.genlock_effects) && currprefs.genlock_image) || currprefs.cs_color_burst || currprefs.gfx_grayscale) {
allocsoftbuffer(mon->monitor_id, _T("monemu"), &avidinfo->tempbuffer, mon->currentmode.flags,
mon->currentmode.amiga_width > 1024 ? mon->currentmode.amiga_width : 1024,
mon->currentmode.amiga_height > 1024 ? mon->currentmode.amiga_height : 1024,

View File

@ -3626,7 +3626,7 @@ bool specialmonitor_need_genlock(void)
case MONITOREMU_COLORBURST:
return true;
}
if (currprefs.genlock_image && currprefs.genlock)
if (currprefs.genlock_image && (currprefs.genlock || currprefs.genlock_effects))
return true;
return false;
}