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)) {
|| 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)
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;
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();
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
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;
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];
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);
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();
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)) {
}
}
+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)
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);
}
}
{
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)
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;
}
}
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;
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);
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;
else
hdbl = 2; // lores
- ystart = minfirstline;
- yend = maxvpos;
+ get_mode_blanking_limits(&xstart, &xend, &ystart, ¥d);
init_noise();
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;
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;
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;
} 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];