summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2026-04-23 13:09:28 +0200
committer hap <happppp@users.noreply.github.com>2026-04-23 13:09:34 +0200
commit56ea076a1fd8b308a4aad3865ec13f2f5fb01c94 (patch)
treeaaaf4510e5d98e92476bbbf428dd77bd9ba2a59f
parent0e4c3900755d14e3ad112eda023a784fe2590fdf (diff)
screen: add support for update_partial(vpos,hpos)
-rw-r--r--src/emu/screen.cpp64
-rw-r--r--src/emu/screen.h5
-rw-r--r--src/emu/video.cpp2
3 files changed, 37 insertions, 34 deletions
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index 849c1dff8bb..d1c7eed720d 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -1136,9 +1136,9 @@ void screen_device::set_visible_area(int min_x, int max_x, int min_y, int max_y)
//-------------------------------------------------
-// update_partial - perform a partial update from
-// the last scanline up to and including the
-// specified scanline
+// update_partial (scanline) - perform a partial
+// update from the last scanline up to and
+// including the specified scanline
//-----------------------------------------------*/
bool screen_device::update_partial(int scanline)
@@ -1192,6 +1192,10 @@ bool screen_device::update_partial(int scanline)
// otherwise, render
LOG_PARTIAL_UPDATES(("updating %d-%d\n", clip.top(), clip.bottom()));
+ // if we left off in the middle of a scanline, eg. with update_now(), finish that scanline first
+ if (m_partial_scan_hpos > 0)
+ update_partial(m_last_partial_scan, 0);
+
u32 flags = 0;
{
auto profile = g_profiler.start(PROFILER_VIDEO);
@@ -1252,11 +1256,12 @@ bool screen_device::update_partial(int scanline)
//-------------------------------------------------
-// update_now - perform an update from the last
-// beam position up to the current beam position
+// update_partial (vpos, hpos) - perform an update
+// from the last beam position up to (but not
+// including!) the newly specified beam position
//-------------------------------------------------
-void screen_device::update_now()
+bool screen_device::update_partial(int vpos, int hpos)
{
// these two checks only apply if we're allowed to skip frames
if (!(m_video_attributes & VIDEO_ALWAYS_UPDATE))
@@ -1265,47 +1270,45 @@ void screen_device::update_now()
if (machine().video().skip_this_frame())
{
LOG_PARTIAL_UPDATES(("skipped due to frameskipping\n"));
- return;
+ return false;
}
// skip if this screen is not visible anywhere
if (!machine().render().is_live(*this))
{
LOG_PARTIAL_UPDATES(("skipped because screen not live\n"));
- return;
+ return false;
}
}
- int current_vpos = vpos();
- int current_hpos = hpos();
rectangle clip = m_visarea;
// skip if we already rendered this line
- if (current_vpos < m_last_partial_scan)
+ if (vpos < m_last_partial_scan)
{
LOG_PARTIAL_UPDATES(("skipped because line was already rendered\n"));
- return;
+ return false;
}
// if beam position is the same, there's nothing to update
- if (current_vpos == m_last_partial_scan && current_hpos == m_partial_scan_hpos)
+ if (vpos == m_last_partial_scan && hpos == m_partial_scan_hpos)
{
LOG_PARTIAL_UPDATES(("skipped because beam position is unchanged\n"));
- return;
+ return false;
}
// skip if we already rendered this frame
- // this can happen if a cpu timeslice that called update_now is in the previous frame while scanline 0 already started
+ // this can happen if a cpu timeslice that called update_partial is in the previous frame while scanline 0 already started
if (m_last_partial_scan == 0 && m_partial_scan_hpos == 0 && m_last_partial_reset > machine().time())
{
LOG_PARTIAL_UPDATES(("skipped because frame was already rendered\n"));
- return;
+ return false;
}
- LOG_PARTIAL_UPDATES(("update_now(): Y=%d, X=%d, last partial %d, partial hpos %d (vis %d %d)\n", current_vpos, current_hpos, m_last_partial_scan, m_partial_scan_hpos, m_visarea.right(), m_visarea.bottom()));
+ LOG_PARTIAL_UPDATES(("update_partial(): Y=%d, X=%d, last partial %d, partial hpos %d (vis %d %d)\n", vpos, hpos, m_last_partial_scan, m_partial_scan_hpos, m_visarea.right(), m_visarea.bottom()));
// start off by doing a partial update up to the line before us, in case that was necessary
- if (current_vpos > m_last_partial_scan)
+ if (vpos > m_last_partial_scan)
{
// if the line before us was incomplete, we must do it in two pieces
if (m_partial_scan_hpos > 0)
@@ -1352,21 +1355,21 @@ void screen_device::update_now()
m_partial_scan_hpos = 0;
m_last_partial_scan++;
}
- if (current_vpos > m_last_partial_scan)
+ if (vpos > m_last_partial_scan)
{
- update_partial(current_vpos - 1);
+ update_partial(vpos - 1);
}
}
// now draw this partial scanline
- if (current_hpos > 0)
+ if (hpos > 0)
{
clip = m_visarea;
clip.set((std::max)(clip.left(), m_partial_scan_hpos),
- (std::min)(clip.right(), current_hpos - 1),
- (std::max)(clip.top(), current_vpos),
- (std::min)(clip.bottom(), current_vpos));
+ (std::min)(clip.right(), hpos - 1),
+ (std::max)(clip.top(), vpos),
+ (std::min)(clip.bottom(), vpos));
// and if there's something to draw, do it
if (!clip.empty())
@@ -1379,12 +1382,12 @@ void screen_device::update_now()
screen_bitmap &curbitmap = m_bitmap[m_curbitmap];
if (m_video_attributes & VIDEO_VARIABLE_WIDTH)
{
- pre_update_scanline(current_vpos);
+ pre_update_scanline(vpos);
switch (curbitmap.format())
{
default:
- case BITMAP_FORMAT_IND16: flags = m_screen_update_ind16(*this, *(bitmap_ind16 *)m_scan_bitmaps[m_curbitmap][current_vpos], clip); break;
- case BITMAP_FORMAT_RGB32: flags = m_screen_update_rgb32(*this, *(bitmap_rgb32 *)m_scan_bitmaps[m_curbitmap][current_vpos], clip); break;
+ case BITMAP_FORMAT_IND16: flags = m_screen_update_ind16(*this, *(bitmap_ind16 *)m_scan_bitmaps[m_curbitmap][vpos], clip); break;
+ case BITMAP_FORMAT_RGB32: flags = m_screen_update_rgb32(*this, *(bitmap_rgb32 *)m_scan_bitmaps[m_curbitmap][vpos], clip); break;
}
}
else
@@ -1405,8 +1408,9 @@ void screen_device::update_now()
}
// remember where we left off
- m_partial_scan_hpos = current_hpos;
- m_last_partial_scan = current_vpos;
+ m_partial_scan_hpos = hpos;
+ m_last_partial_scan = vpos;
+ return true;
}
@@ -1571,7 +1575,7 @@ int screen_device::hpos() const
//-------------------------------------------------
// time_until_pos - returns the amount of time
// remaining until the beam is at the given
-// hpos,vpos
+// vpos,hpos
//-------------------------------------------------
attotime screen_device::time_until_pos(int vpos, int hpos) const
diff --git a/src/emu/screen.h b/src/emu/screen.h
index 31451d9b6a4..be74838323b 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -213,7 +213,7 @@ public:
/// horizontal blanking period.
/// \param [in] hbend Index of first visible pixel after horizontal
/// blanking period ends.
- /// \param [in] hbstart Index of first pixel in horzontal blanking
+ /// \param [in] hbstart Index of first pixel in horizontal blanking
/// period after visible pixels.
/// \param [in] vtotal Total lines per frame, including vertical
/// blanking period.
@@ -407,7 +407,8 @@ public:
int partial_updates() const { return m_partial_updates_this_frame; }
int partial_scan_hpos() const { return m_partial_scan_hpos; }
bool update_partial(int scanline);
- void update_now();
+ bool update_partial(int vpos, int hpos);
+ bool update_now() { return update_partial(vpos(), hpos()); }
void reset_partial_updates();
// additional helpers
diff --git a/src/emu/video.cpp b/src/emu/video.cpp
index 75ba128df91..a8900d36cee 100644
--- a/src/emu/video.cpp
+++ b/src/emu/video.cpp
@@ -621,8 +621,6 @@ bool video_manager::finish_screen_updates()
bool has_live_screen = false;
for (screen_device &screen : iter)
{
- if (screen.partial_scan_hpos() > 0) // previous update ended mid-scanline
- screen.update_now();
screen.update_partial(screen.visible_area().max_y);
if (machine().render().is_live(screen))