diff options
| author | 2026-04-23 13:09:28 +0200 | |
|---|---|---|
| committer | 2026-04-23 13:09:34 +0200 | |
| commit | 56ea076a1fd8b308a4aad3865ec13f2f5fb01c94 (patch) | |
| tree | aaaf4510e5d98e92476bbbf428dd77bd9ba2a59f /src/emu | |
| parent | 0e4c3900755d14e3ad112eda023a784fe2590fdf (diff) | |
screen: add support for update_partial(vpos,hpos)
Diffstat (limited to 'src/emu')
| -rw-r--r-- | src/emu/screen.cpp | 64 | ||||
| -rw-r--r-- | src/emu/screen.h | 5 | ||||
| -rw-r--r-- | src/emu/video.cpp | 2 |
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)) |
