]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Genlock positioning/scaling fixes. Manual offset config entries added.
authorToni Wilen <twilen@winuae.net>
Sat, 10 Feb 2024 16:51:49 +0000 (18:51 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 10 Feb 2024 16:51:49 +0000 (18:51 +0200)
cfgfile.cpp
custom.cpp
include/custom.h
include/options.h
include/videograb.h
od-win32/win32_videograb.cpp
od-win32/win32gfx.cpp
specialmonitors.cpp

index 8b84fc8abf9089af4f63a2dd4687b81d70530d90..d76d1e76474e0e3a5993905af15a1b11e8b1fae6 100644 (file)
@@ -2563,6 +2563,8 @@ 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);
+       cfgfile_dwrite(f, _T("genlock_offset_x"), _T("%d"), p->genlock_offset_x);
+       cfgfile_dwrite(f, _T("genlock_offset_y"), _T("%d"), p->genlock_offset_y);
        if (p->genlock_effects) {
                tmp[0] = 0;
                if (p->genlock_effects & (1 << 4)) {
@@ -5967,6 +5969,8 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_intval(option, value, _T("monitoremu_monitor"), &p->monitoremu_mon, 1)
                || cfgfile_intval(option, value, _T("genlock_scale"), &p->genlock_scale, 1)
                || cfgfile_intval(option, value, _T("genlock_mix"), &p->genlock_mix, 1)
+               || cfgfile_intval(option, value, _T("genlock_offset_x"), &p->genlock_offset_x, 1)
+               || cfgfile_intval(option, value, _T("genlock_offset_y"), &p->genlock_offset_y, 1)
                || cfgfile_intval(option, value, _T("keyboard_handshake"), &p->cs_kbhandshake, 1)
                || cfgfile_intval(option, value, _T("eclockphase"), &p->cs_eclockphase, 1)
                || cfgfile_intval(option, value, _T("chipset_rtc_adjust"), &p->cs_rtc_adjust, 1)
@@ -8579,6 +8583,8 @@ void default_prefs (struct uae_prefs *p, bool reset, int type)
        p->genlock = 0;
        p->genlock_image = 0;
        p->genlock_mix = 0;
+       p->genlock_offset_x = 0;
+       p->genlock_offset_y = 0;
        p->ntscmode = 0;
        p->filesys_limit = 0;
        p->filesys_max_name = 107;
index d9d24fa5d13df5409ff00b833e9f89bc8a242b05..c81a74c88e669121032319b74d50107d8876e85b 100644 (file)
@@ -7785,6 +7785,21 @@ static void check_line_enabled(void)
        line_disabled |= custom_disabled ? 2 : 0;
 }
 
+void get_mode_blanking_limits(int *phbstop, int *phbstrt, int *pvbstop, int *pvbstrt)
+{
+       if (new_beamcon0 & BEAMCON0_VARVBEN) {
+               *pvbstop = vbstop;
+               *pvbstrt = vbstrt;
+               *phbstop = hbstop_v;
+               *phbstrt = hbstrt_v;
+       } else {
+               *pvbstop = hardwired_vbstop;
+               *pvbstrt = hardwired_vbstrt;
+               *phbstop = (47 << CCK_SHRES_SHIFT) - 7;
+               *phbstrt = ((maxhpos_short + 8) << CCK_SHRES_SHIFT) - 3;
+       }
+}
+
 static void vb_check(void)
 {
        check_line_enabled();
index 4ba4b8064aa4caf3b7ab49d70d8731e75ec35b75..8651a6f3d982903c186c1d49e585763fcd676a48 100644 (file)
@@ -254,6 +254,7 @@ void custom_cpuchange(void);
 bool bitplane_dma_access(int hpos, int offset);
 void custom_dumpstate(int);
 bool get_ras_cas(uaecptr, int*, int*);
+void get_mode_blanking_limits(int *phbstop, int *phbstrt, int *pvbstop, int *pvbstrt);
 
 #define RGA_PIPELINE_ADJUST 4
 #define MAX_CHIPSETSLOTS 256
index 283b761b8f0679dabe9e5726b37eabcc6330fd96..06da514a0e8a3d23a558472eccba86651927285b 100644 (file)
@@ -628,6 +628,7 @@ struct uae_prefs {
        int genlock_scale;
        int genlock_aspect;
        int genlock_effects;
+       int genlock_offset_x, genlock_offset_y;
        uae_u64 ecs_genlock_features_colorkey_mask[4];
        uae_u8 ecs_genlock_features_plane_mask;
        bool genlock_alpha;
@@ -910,6 +911,7 @@ struct uae_prefs {
        bool win32_shutdown_notification;
        bool win32_warn_exit;
        bool win32_gui_control;
+       bool win32_videograb_balance;
        bool right_control_is_right_win_key;
 #ifdef WITH_SLIRP
        struct slirp_redir slirp_redirs[MAX_SLIRP_REDIRS];
index 3873664c31c956be767a22c622b0ffc6cc811fc9..1bfeb1c7333ec9bf0d4a77a90a55a1111e3b6701 100644 (file)
@@ -4,7 +4,9 @@ void uninitvideograb(void);
 bool getvideograb(long **buffer, int *width, int *height);
 void pausevideograb(int pause);
 uae_s64 getsetpositionvideograb(uae_s64 framepos);
+uae_s64 getdurationvideograb(void);
 bool isvideograb(void);
 bool getpausevideograb(void);
 void setvolumevideograb(int volume);
+void setchflagsvideograb(int chflags);
 void isvideograb_status(void);
index 16bab06d7d9d9dbea218446bdd79b0fe3d9dc358..de6692231425a27996788dcb34b8fde3edf43bcc 100644 (file)
@@ -51,17 +51,20 @@ static CComPtr<IMediaSeeking> mediaSeeking;
 static CComPtr<IMediaEvent> mediaEvent;
 static CComPtr<IBasicAudio> audio;
 static bool videoInitialized;
-static bool videoPaused;
+static int videoPaused;
 static long *frameBuffer;
 static long bufferSize;
 static int videoWidth, videoHeight;
+static int audio_chflags, audio_volume;
 
 void uninitvideograb(void)
 {
        write_log(_T("uninitvideograb\n"));
 
        videoInitialized = false;
-       videoPaused = false;
+       videoPaused = -1;
+       audio_chflags = 0;
+       audio_volume = 0;
 
        sampleGrabber.Release();
        mediaSeeking.Release();
@@ -311,6 +314,7 @@ bool initvideograb(const TCHAR *filename)
 
        hr = filterGraph->QueryInterface(IID_IBasicAudio, (void**)&audio);
        setvolumevideograb(100 - currprefs.sound_volume_genlock);
+       setchflagsvideograb(0);
 
        hr = filterGraph->QueryInterface(IID_IMediaControl, (void**)&mediaControl);
        if (FAILED(hr)) {
@@ -332,6 +336,16 @@ bool initvideograb(const TCHAR *filename)
        }
 }
 
+uae_s64 getdurationvideograb(void)
+{
+       LONGLONG dura;
+       HRESULT hr = mediaSeeking->GetDuration(&dura);
+       if (FAILED(hr)) {
+               return 0;
+       }
+       return dura;
+}
+
 uae_s64 getsetpositionvideograb(uae_s64 framepos)
 {
        if (!videoInitialized || !mediaSeeking)
@@ -351,8 +365,32 @@ uae_s64 getsetpositionvideograb(uae_s64 framepos)
                hr = mediaSeeking->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
                if (FAILED(hr)) {
                        write_log(_T("SetPositions %lld failed %08x\n"), framepos, hr);
+                       return 0;
                }
-               return 0;
+               return pos;
+       }
+}
+
+void setchflagsvideograb(int chflags)
+{
+       if (!audio)
+               return;
+       audio_chflags = chflags;
+       long bal;
+       if (chflags == 1) {
+               bal = -10000;
+       } else if (chflags == 2) {
+               bal = 10000;
+       } else {
+               bal = 0;
+       }
+       if (!currprefs.win32_videograb_balance) {
+               audio->put_Balance(bal);
+       }
+       if (chflags) {
+               setvolumevideograb(audio_volume);
+       } else if (!chflags) {
+               audio->put_Volume(0);
        }
 }
 
@@ -360,13 +398,17 @@ void setvolumevideograb(int volume)
 {
        if (!audio)
                return;
+       audio_volume = volume;
+       if (!audio_chflags) {
+               volume = 0;
+       }
        long vol = (long)(log10((float)volume / 100.0) * 4000.0);
        audio->put_Volume(vol);
 }
 
 bool getpausevideograb(void)
 {
-       return videoPaused != 0;
+       return videoPaused > 0;
 }
 
 void pausevideograb(int pause)
@@ -374,17 +416,19 @@ void pausevideograb(int pause)
        HRESULT hr;
        if (!videoInitialized)
                return;
+       if (videoPaused == pause)
+               return;
        if (pause < 0) {
                pause = videoPaused ? 0 : 1;
        }
        if (pause > 0) {
                hr = mediaControl->Pause();
                if (SUCCEEDED(hr))
-                       videoPaused = true;
+                       videoPaused = 1;
        } else if (pause == 0) {
                hr = mediaControl->Run();
                if (SUCCEEDED(hr))
-                       videoPaused = false;
+                       videoPaused = 0;
        }
 }
 
index eb258c099ce17a8067e1d32fb0351576e0fa9f7d..2d47b3b3b58b048b35387cf04bd326c65320e1df 100644 (file)
@@ -2264,6 +2264,8 @@ int check_prefs_changed_gfx(void)
        c |= currprefs.genlock_mix != changed_prefs.genlock_mix ? (1 | 256) : 0;
        c |= currprefs.genlock_aspect != changed_prefs.genlock_aspect ? (1 | 256) : 0;
        c |= currprefs.genlock_scale != changed_prefs.genlock_scale ? (1 | 256) : 0;
+       c |= currprefs.genlock_offset_x != changed_prefs.genlock_offset_x ? (1 | 256) : 0;
+       c |= currprefs.genlock_offset_y != changed_prefs.genlock_offset_y ? (1 | 256) : 0;
        c |= _tcsicmp(currprefs.genlock_image_file, changed_prefs.genlock_image_file) ? (2 | 8) : 0;
        c |= _tcsicmp(currprefs.genlock_video_file, changed_prefs.genlock_video_file) ? (2 | 8) : 0;
 
@@ -2368,6 +2370,8 @@ int check_prefs_changed_gfx(void)
                currprefs.genlock_alpha = changed_prefs.genlock_alpha;
                currprefs.genlock_aspect = changed_prefs.genlock_aspect;
                currprefs.genlock_scale = changed_prefs.genlock_scale;
+               currprefs.genlock_offset_x = changed_prefs.genlock_offset_x;
+               currprefs.genlock_offset_y = changed_prefs.genlock_offset_y;
                _tcscpy(currprefs.genlock_image_file, changed_prefs.genlock_image_file);
                _tcscpy(currprefs.genlock_video_file, changed_prefs.genlock_video_file);
 
index ea567f96c4695ae394d1951618e4ce389e949141..b20347bf93d768a170fe6889aec863fdfe92606a 100755 (executable)
@@ -2399,7 +2399,7 @@ static bool do_genlock(struct vidbuffer *src, struct vidbuffer *dst, bool double
        struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo;
 
        int y, x, vdbl, hdbl;
-       int ystart, yend;
+       int ystart, yend, xstart, xend;
        int mix1 = 0, mix2 = 0;
 
        int genlock_image_pixbytes = 4;
@@ -2536,8 +2536,7 @@ skip:
        else
                hdbl = 2; // lores
 
-       ystart = minfirstline;
-       yend = maxvpos;
+       get_mode_blanking_limits(&xstart, &xend,  &ystart, &yend);
 
        init_noise();
 
@@ -2548,11 +2547,25 @@ skip:
        uae_u8 amix1 = 255 - (currprefs.genlock_mix > 255 ? 255 : 0);
        uae_u8 amix2 = 255 - amix1;
 
-       int ah = (((yend - ystart) * 2) >> vdbl);
-       int aw = src->inwidth;
+       int ah = (((yend - ystart) * 2) >> 0);
+       int aw = ((xend - xstart) >> 1);
 
-       int deltax = genlock_image_width * 65536 / aw;
-       int deltay = genlock_image_height * 65536 / ah;
+       if (ah < 16 || aw < 16) {
+               return false;
+       }
+
+       int deltax = 65536;
+       int deltay = 65536;
+
+       if (abs(genlock_image_width - aw) > 8) {
+               deltax = genlock_image_width * 65536 / aw;
+       }
+       if (abs(genlock_image_height - ah) > 8) {
+               deltay = genlock_image_height * 65536 / ah;
+       }
+       deltay <<= vdbl;
+       deltax <<= hdbl;
+       deltax >>= 1;
 
        deltax -= currprefs.genlock_scale * 256;
        deltay -= currprefs.genlock_scale * 256;
@@ -2561,20 +2574,31 @@ skip:
        int offsety = 0;
 
        if (deltax && deltay) {
-               offsetx = (aw - genlock_image_width * 65536 / deltax) / 2;
-               offsety = (ah - genlock_image_height * 65536 / deltay) / 2;
+               offsetx = ((aw - genlock_image_width) * 65536 / deltax) / 2;
+               offsety = ((ah - genlock_image_height) * 65536 / deltay) / 2;
        
                if (currprefs.genlock_aspect) {
                        if (deltax < deltay) {
-                               offsetx = (aw - genlock_image_width * 65536 / deltay) / 2;
+                               offsetx = ((aw - genlock_image_width) * 65536 / deltay) / 2;
                                deltax = deltay;
                        } else {
-                               offsety = (ah - genlock_image_height * 65536 / deltax) / 2;
+                               offsety = ((ah - genlock_image_height) * 65536 / deltax) / 2;
                                deltay = deltax;
                        }
                }
        }
 
+       int gen_xoffset = 0;
+       int gen_yoffset = 0;
+
+       if (currprefs.gfx_overscanmode >= OVERSCANMODE_EXTREME) {
+               gen_xoffset = (xstart / 2) - hsync_end_left_border * 2;
+       }
+       gen_yoffset = (ystart - minfirstline) * 2;
+
+       gen_xoffset += currprefs.genlock_offset_x;
+       gen_yoffset += currprefs.genlock_offset_y;
+
        uae_u8 r = 0, g = 0, b = 0, a = 0;
        for (y = ystart; y < yend; y++) {
                int yoff = (y * 2 + oddlines) - src->yoffset;
@@ -2588,7 +2612,7 @@ skip:
                uae_u8 *lineprev = yoff > 0 ? src->bufmem + (yoff - 1) * src->rowbytes : NULL;
                uae_u8 *dstline = dst->bufmem + ((y * 2 + oddlines) - dst->yoffset) * dst->rowbytes;
                uae_u8 *line_genlock = row_map_genlock[yoff];
-               int gy = ((y * 2 + oddlines) - src->yoffset - offsety) * deltay / 65536;
+               int gy = ((y * 2 + oddlines) - src->yoffset + offsety - gen_yoffset) * deltay / 65536;
                if (genlock_image_upsidedown)
                        gy = (genlock_image_height - 1) - gy;
                uae_u8 *image_genlock = genlock_image + gy * genlock_image_pitch;
@@ -2611,7 +2635,7 @@ skip:
                                } else if (genlock_blank) {
                                        r = g = b = 0;
                                } else if (genlock_image) {
-                                       int gx = (x - offsetx) * deltax / 65536;
+                                       int gx = (x + offsetx - gen_xoffset) * deltax / 65536;
                                        if (gx >= 0 && gx < genlock_image_width && gy >= 0 && gy < genlock_image_height) {
                                                uae_u8 *s_genlock_image = image_genlock + gx * genlock_image_pixbytes;
                                                r = s_genlock_image[genlock_image_red_index];