]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Genlock emulation fixes and genlock_effects genlock manual feature enable.
authorToni Wilen <twilen@winuae.net>
Sat, 24 Sep 2022 17:22:28 +0000 (20:22 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 24 Sep 2022 17:22:28 +0000 (20:22 +0300)
cfgfile.cpp
custom.cpp
drawing.cpp
genlinetoscr.cpp
include/options.h
od-win32/win32gfx.cpp
specialmonitors.cpp

index a4600c35e2c586cd5581abe002818fab05cf5aed..97a3a27bfc894bb273236167a7767df888967b0d 100644 (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;
 
index 104490255263107214ecfe6fef13d06b90d7ea27..15e4e10ec540b80ecbda6044184eb6ec71a1872f 100644 (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
index 92a9ea6c6fab84d5c807e53779f2a245deae6766..771385947f111ffdc1d5be072dff9c3c78d37452 100644 (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();
index 28923be589436ed8ef520806b97d07051a6c9121..cfbf3fa20f8d58329b15379166a0bd79d0f28340 100644 (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");
+               }
        }
 }
 
index 95bf1c1b0f80db1a90999fa38fe058bd14d91c66..2704cbb5fa7940143ed623ee3f02774741cc2790 100644 (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];
index b58026ea97170c1d6fc2edb9cf688111455acf91..5753925fd8e0b04c254388b02fd53bbccc1f4f43 100644 (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,
index 3ed0c85dca77773a16e3ff6abfe2f9e01eb20656..2feba598c5b5aead1b496a1d0e292427ed80db99 100755 (executable)
@@ -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;
 }