summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-08-17 20:41:36 +0200
committer couriersud <couriersud@gmx.org>2020-08-17 22:24:18 +0200
commita81e2cabc8659a7152a56db98147fbecffb2f0d0 (patch)
tree055040bb035d350b8b0019b511fec718d4af116a
parentda734ea0c916b2186ce7ec3d2eea36a1ce7f3ee2 (diff)
fixedfreq.cpp: Improve handling of interlaced video
* will now detect half lines before vsync and determine field.
-rw-r--r--src/devices/video/fixfreq.cpp35
-rw-r--r--src/devices/video/fixfreq.h6
2 files changed, 26 insertions, 15 deletions
diff --git a/src/devices/video/fixfreq.cpp b/src/devices/video/fixfreq.cpp
index 44c332c066e..3810dc76a76 100644
--- a/src/devices/video/fixfreq.cpp
+++ b/src/devices/video/fixfreq.cpp
@@ -75,30 +75,31 @@ void fixedfreq_monitor_state::update_sync_channel(const time_type &time, const d
if (!last_vsync && m_sig_vsync)
{
LOG("VSYNC UP %f %d\n", m_last_x, m_last_y);
- m_intf.vsync_end_cb(time - m_last_vsync_time);
- //auto d=time - m_last_vsync_time;
- //printf("%f\n", 1.0 / d);
- m_last_vsync_time = time;
- // FIXME: this is wrong: we need to count lines with half-scanline width
- // to determine the field.
- m_sig_field = last_comp; /* force false-progressive */
- m_sig_field = (m_sig_field ^ 1) ^ last_comp; /* if there is no field switch, auto switch */
- m_last_y = 0; //m_desc.vbackporch_width();
+ const int has_fields = (m_desc.m_fieldcount > 1) ? 1: 0;
- // discharge
- //m_vsync_filter = 0.0;
+ // FIXME: add modes: true interlaced, overlayed, false progressive (see popeye video)
+ if (has_fields)
+ {
+ const auto avg_line_dur = (time - m_last_field_time) * m_desc.m_fieldcount / (m_last_y + 1);
+ m_last_field_time = time;
+ m_sig_field = avg_line_dur * 0.75 > m_last_line_duration;
+ }
+ if (!has_fields || (m_sig_field == 0))
+ {
+ m_intf.vsync_end_cb(time - m_last_vsync_time);
+ m_last_vsync_time = time;
+ }
+ m_last_y = 0; //m_desc.vbackporch_width();
}
else if (last_vsync && !m_sig_vsync)
{
LOG("VSYNC DOWN %f %d\n", m_last_x, m_last_y);
- //LOG("Field: %d\n", m_sig_field);
}
if (!last_comp && m_sig_composite)
{
if (m_sig_vsync)
LOG("Hsync in vsync\n");
- /* TODO - time since last hsync and field detection */
//LOG("HSYNC up %d\n", m_last_x);
// FIXME: pixels > 50 filters some spurious hysnc on line 23/24 in breakout
// The hsync signal transition from high to low is 7 pixels too
@@ -110,9 +111,11 @@ void fixedfreq_monitor_state::update_sync_channel(const time_type &time, const d
m_last_y += m_desc.m_fieldcount;
m_last_x = 0;
m_line_time = time + 1.0 / m_desc.hsync_filter_timeconst();
+
+ m_last_line_duration = time - m_last_hsync_time;
+ m_last_hsync_time = time;
+
}
- //if (!m_sig_vsync && (m_last_x < m_desc.m_hscale * 100))
- // printf("HSYNC up %d %f\n", m_last_y, m_last_x);
}
else if (last_comp && !m_sig_composite)
{
@@ -244,6 +247,8 @@ void fixedfreq_device::device_start()
save_item(NAME(m_state.m_line_time));
save_item(NAME(m_state.m_last_hsync_time));
save_item(NAME(m_state.m_last_vsync_time));
+ save_item(NAME(m_state.m_last_line_duration));
+ save_item(NAME(m_state.m_last_field_time));
/* sync separator */
save_item(NAME(m_state.m_vsync_filter));
diff --git a/src/devices/video/fixfreq.h b/src/devices/video/fixfreq.h
index 6deeab2f639..8e89edab355 100644
--- a/src/devices/video/fixfreq.h
+++ b/src/devices/video/fixfreq.h
@@ -131,6 +131,8 @@ struct fixedfreq_monitor_state
m_line_time(time_type(0)),
m_last_hsync_time(time_type(0)),
m_last_vsync_time(time_type(0)),
+ m_last_line_duration(time_type(0)),
+ m_last_field_time(time_type(0)),
m_vsync_filter(0),
m_sig_vsync(0),
m_sig_composite(0),
@@ -208,6 +210,9 @@ struct fixedfreq_monitor_state
time_type m_last_hsync_time;
time_type m_last_vsync_time;
+ time_type m_last_line_duration;
+ time_type m_last_field_time;
+
/* sync separator */
double m_vsync_filter;
@@ -233,6 +238,7 @@ public:
fixedfreq_device &set_monitor_clock(uint32_t clock) { m_monitor.m_monitor_clock = clock; return *this;}
fixedfreq_device &set_fieldcount(int count) { m_monitor.m_fieldcount = count; return *this; }
fixedfreq_device &set_threshold(double threshold) { m_monitor.m_sync_threshold = threshold; return *this; }
+ fixedfreq_device &set_vsync_threshold(double threshold) { m_monitor.m_vsync_threshold = threshold; return *this; }
fixedfreq_device &set_gain(double gain) { m_monitor.m_gain = gain; return *this; }
fixedfreq_device &set_horz_params(int visible, int frontporch, int sync, int backporch)
{