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);
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]);
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;
{
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
}
STATIC_INLINE int issyncstopped(void)
{
- return (bplcon0 & 2) && !currprefs.genlock;
+ return (bplcon0 & 2) && (!currprefs.genlock || currprefs.genlock_effects);
}
STATIC_INLINE int GETVPOS(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) {
genlockvtoggle = lof_store ? 1 : 0;
}
- if ((bplcon0 & 2) && !currprefs.genlock) {
+ if ((bplcon0 & 2) && (!currprefs.genlock || currprefs.genlock_effects)) {
nosignal_trigger = true;
}
// Inverted CSYNC
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;
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);
}
}
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;
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;
}
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;
}
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
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;
}
}
}
// 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();
}
}
-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);");
}
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");
}
else {
outf("%s", var2 ? var2 : "spix_val");
}
+ outf(");\n");
}
- outf(");\n");
}
static void put_dpix (const char *var)
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");
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");
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");
} 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");
+ }
}
}
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];
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,
case MONITOREMU_COLORBURST:
return true;
}
- if (currprefs.genlock_image && currprefs.genlock)
+ if (currprefs.genlock_image && (currprefs.genlock || currprefs.genlock_effects))
return true;
return false;
}