mirror of
https://github.com/holub/mame
synced 2025-04-26 18:23:08 +03:00
scanline partial updates checkpoint (nw)
This isn't working right yet with my test case, but I'm fairly certain the actual core part is generally correct, just the Apple II video rendering and/or floating-bus reading isn't quite right.
This commit is contained in:
parent
bd5fca7042
commit
6fb7e0f7d3
124
src/emu/screen.c
124
src/emu/screen.c
@ -63,6 +63,7 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
|
||||
m_curtexture(0),
|
||||
m_changed(true),
|
||||
m_last_partial_scan(0),
|
||||
m_partial_scan_hpos(0),
|
||||
m_color(rgb_t(0xff, 0xff, 0xff, 0xff)),
|
||||
m_brightness(0xff),
|
||||
m_frame_period(DEFAULT_FRAME_PERIOD.as_attoseconds()),
|
||||
@ -661,21 +662,121 @@ bool screen_device::update_partial(int scanline)
|
||||
|
||||
void screen_device::update_now()
|
||||
{
|
||||
// these two checks only apply if we're allowed to skip frames
|
||||
if (!(m_video_attributes & VIDEO_ALWAYS_UPDATE))
|
||||
{
|
||||
// if skipping this frame, bail
|
||||
if (machine().video().skip_this_frame())
|
||||
{
|
||||
LOG_PARTIAL_UPDATES(("skipped due to frameskipping\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// skip if this screen is not visible anywhere
|
||||
if (!machine().render().is_live(*this))
|
||||
{
|
||||
LOG_PARTIAL_UPDATES(("skipped because screen not live\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int current_vpos = vpos();
|
||||
int current_hpos = hpos();
|
||||
rectangle clip = m_visarea;
|
||||
|
||||
// since we can currently update only at the scanline
|
||||
// level, we are trying to do the right thing by
|
||||
// updating including the current scanline, only if the
|
||||
// beam is past the halfway point horizontally.
|
||||
// If the beam is in the first half of the scanline,
|
||||
// we only update up to the previous scanline.
|
||||
// This minimizes the number of pixels that might be drawn
|
||||
// incorrectly until we support a pixel level granularity
|
||||
if (current_hpos < (m_width / 2) && current_vpos > 0)
|
||||
current_vpos = current_vpos - 1;
|
||||
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.max_x, m_visarea.max_y));
|
||||
|
||||
update_partial(current_vpos);
|
||||
// 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 the line before us was incomplete, we must do it in two pieces
|
||||
if (m_partial_scan_hpos > 0)
|
||||
{
|
||||
INT32 save_scan = m_partial_scan_hpos;
|
||||
update_partial(current_vpos - 2);
|
||||
m_partial_scan_hpos = save_scan;
|
||||
|
||||
// now finish the previous partial scanline
|
||||
int scanline = current_vpos - 1;
|
||||
if (m_partial_scan_hpos > clip.min_x)
|
||||
clip.min_x = m_partial_scan_hpos;
|
||||
if (current_hpos < clip.max_x)
|
||||
clip.max_x = current_hpos;
|
||||
if (m_last_partial_scan > clip.min_y)
|
||||
clip.min_y = m_last_partial_scan;
|
||||
if (scanline < clip.max_y)
|
||||
clip.max_y = scanline;
|
||||
|
||||
// if there's something to draw, do it
|
||||
if ((clip.min_x <= clip.max_x) && (clip.min_y <= clip.max_y))
|
||||
{
|
||||
g_profiler.start(PROFILER_VIDEO);
|
||||
|
||||
screen_bitmap &curbitmap = m_bitmap[m_curbitmap];
|
||||
switch (curbitmap.format())
|
||||
{
|
||||
default:
|
||||
case BITMAP_FORMAT_IND16: m_screen_update_ind16(*this, curbitmap.as_ind16(), clip); break;
|
||||
case BITMAP_FORMAT_RGB32: m_screen_update_rgb32(*this, curbitmap.as_rgb32(), clip); break;
|
||||
}
|
||||
|
||||
m_partial_updates_this_frame++;
|
||||
g_profiler.stop();
|
||||
m_partial_scan_hpos = 0;
|
||||
m_last_partial_scan = current_vpos + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
update_partial(current_vpos - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// now draw this partial scanline
|
||||
clip = m_visarea;
|
||||
|
||||
if (m_partial_scan_hpos > clip.min_x)
|
||||
clip.min_x = m_partial_scan_hpos;
|
||||
if (current_hpos < clip.max_x)
|
||||
clip.max_x = current_hpos;
|
||||
if (current_vpos > clip.min_y)
|
||||
clip.min_y = current_vpos;
|
||||
if (current_vpos < clip.max_y)
|
||||
clip.max_y = current_vpos;
|
||||
|
||||
// and if there's something to draw, do it
|
||||
if ((clip.min_x <= clip.max_x) && (clip.min_y <= clip.max_y))
|
||||
{
|
||||
g_profiler.start(PROFILER_VIDEO);
|
||||
|
||||
LOG_PARTIAL_UPDATES(("doing scanline partial draw: Y %d X %d-%d\n", clip.max_y, clip.min_x, clip.max_x));
|
||||
|
||||
UINT32 flags = UPDATE_HAS_NOT_CHANGED;
|
||||
screen_bitmap &curbitmap = m_bitmap[m_curbitmap];
|
||||
switch (curbitmap.format())
|
||||
{
|
||||
default:
|
||||
case BITMAP_FORMAT_IND16: flags = m_screen_update_ind16(*this, curbitmap.as_ind16(), clip); break;
|
||||
case BITMAP_FORMAT_RGB32: flags = m_screen_update_rgb32(*this, curbitmap.as_rgb32(), clip); break;
|
||||
}
|
||||
|
||||
m_partial_updates_this_frame++;
|
||||
g_profiler.stop();
|
||||
|
||||
// if we modified the bitmap, we have to commit
|
||||
m_changed |= ~flags & UPDATE_HAS_NOT_CHANGED;
|
||||
|
||||
// remember where we left off
|
||||
m_partial_scan_hpos = current_hpos;
|
||||
m_last_partial_scan = current_vpos;
|
||||
|
||||
// if we completed the line, mark it so
|
||||
if (current_hpos >= m_visarea.max_x)
|
||||
{
|
||||
m_partial_scan_hpos = 0;
|
||||
m_last_partial_scan = current_vpos + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -687,6 +788,7 @@ void screen_device::update_now()
|
||||
void screen_device::reset_partial_updates()
|
||||
{
|
||||
m_last_partial_scan = 0;
|
||||
m_partial_scan_hpos = 0;
|
||||
m_partial_updates_this_frame = 0;
|
||||
m_scanline0_timer->adjust(time_until_pos(0));
|
||||
}
|
||||
|
@ -285,6 +285,7 @@ private:
|
||||
UINT8 m_curtexture; // current texture index
|
||||
bool m_changed; // has this bitmap changed?
|
||||
INT32 m_last_partial_scan; // scanline of last partial update
|
||||
INT32 m_partial_scan_hpos; // horizontal pixel last rendered on this partial scanline
|
||||
bitmap_argb32 m_screen_overlay_bitmap; // screen overlay bitmap
|
||||
UINT32 m_unique_id; // unique id for this screen_device
|
||||
rgb_t m_color; // render color
|
||||
|
@ -324,9 +324,6 @@ TIMER_DEVICE_CALLBACK_MEMBER(napple2_state::apple2_interrupt)
|
||||
{
|
||||
int scanline = param;
|
||||
|
||||
if((scanline % 8) == 0)
|
||||
machine().first_screen()->update_partial(machine().first_screen()->vpos());
|
||||
|
||||
// update the video system's shadow copy of the system config at the end of the frame
|
||||
if (scanline == 192)
|
||||
{
|
||||
@ -450,31 +447,39 @@ void napple2_state::do_io(address_space &space, int offset)
|
||||
break;
|
||||
|
||||
case 0x50: // graphics mode
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_graphics = true; break;
|
||||
|
||||
case 0x51: // text mode
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_graphics = false; break;
|
||||
|
||||
case 0x52: // no mix
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_mix = false; break;
|
||||
|
||||
case 0x53: // mixed mode
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_mix = true; break;
|
||||
|
||||
case 0x54: // set page 1
|
||||
machine().first_screen()->update_now();
|
||||
m_page2 = false;
|
||||
m_video->m_page2 = false;
|
||||
break;
|
||||
|
||||
case 0x55: // set page 2
|
||||
machine().first_screen()->update_now();
|
||||
m_page2 = true;
|
||||
m_video->m_page2 = true;
|
||||
break;
|
||||
|
||||
case 0x56: // select lo-res
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_hires = false; break;
|
||||
|
||||
case 0x57: // select hi-res
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_hires = true; break;
|
||||
|
||||
case 0x58: // AN0 off
|
||||
|
@ -779,11 +779,6 @@ TIMER_DEVICE_CALLBACK_MEMBER(apple2e_state::apple2_interrupt)
|
||||
{
|
||||
int scanline = param;
|
||||
|
||||
if((scanline % 8) == 0)
|
||||
{
|
||||
machine().first_screen()->update_partial(machine().first_screen()->vpos());
|
||||
}
|
||||
|
||||
if (m_isiic)
|
||||
{
|
||||
update_iic_mouse();
|
||||
@ -1101,10 +1096,12 @@ void apple2e_state::do_io(address_space &space, int offset, bool is_iic)
|
||||
switch (offset)
|
||||
{
|
||||
case 0x5e: // SETDHIRES
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_dhires = true;
|
||||
break;
|
||||
|
||||
case 0x5f: // CLRDHIRES
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_dhires = false;
|
||||
break;
|
||||
}
|
||||
@ -1155,35 +1152,47 @@ void apple2e_state::do_io(address_space &space, int offset, bool is_iic)
|
||||
break;
|
||||
|
||||
case 0x50: // graphics mode
|
||||
m_video->m_graphics = true; break;
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_graphics = true;
|
||||
break;
|
||||
|
||||
case 0x51: // text mode
|
||||
m_video->m_graphics = false; break;
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_graphics = false;
|
||||
break;
|
||||
|
||||
case 0x52: // no mix
|
||||
m_video->m_mix = false; break;
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_mix = false;
|
||||
break;
|
||||
|
||||
case 0x53: // mixed mode
|
||||
m_video->m_mix = true; break;
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_mix = true;
|
||||
break;
|
||||
|
||||
case 0x54: // set page 1
|
||||
machine().first_screen()->update_now();
|
||||
m_page2 = false;
|
||||
m_video->m_page2 = false;
|
||||
auxbank_update();
|
||||
break;
|
||||
|
||||
case 0x55: // set page 2
|
||||
machine().first_screen()->update_now();
|
||||
m_page2 = true;
|
||||
m_video->m_page2 = true;
|
||||
auxbank_update();
|
||||
break;
|
||||
|
||||
case 0x56: // select lo-res
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_hires = false;
|
||||
auxbank_update();
|
||||
break;
|
||||
|
||||
case 0x57: // select hi-res
|
||||
machine().first_screen()->update_now();
|
||||
m_video->m_hires = true;
|
||||
auxbank_update();
|
||||
break;
|
||||
|
@ -1236,6 +1236,7 @@ void a2_video_device::hgr_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
UINT32 w;
|
||||
UINT16 *artifact_map_ptr;
|
||||
int mon_type = m_sysconfig & 0x03;
|
||||
int begincol = 0, endcol = 40;
|
||||
|
||||
/* sanity checks */
|
||||
if (beginrow < cliprect.min_y)
|
||||
@ -1245,6 +1246,18 @@ void a2_video_device::hgr_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
if (endrow < beginrow)
|
||||
return;
|
||||
|
||||
// we generate 2 pixels per "column" so adjust
|
||||
if (begincol < (cliprect.min_x/14))
|
||||
begincol = (cliprect.min_x/14);
|
||||
if (endcol > (cliprect.max_x/14))
|
||||
endcol = (cliprect.max_x/14);
|
||||
if (cliprect.max_x > 39*14)
|
||||
endcol = 40;
|
||||
if (endcol < begincol)
|
||||
return;
|
||||
|
||||
//printf("HGR draw: page %c, rows %d-%d cols %d-%d\n", m_page2 ? '2' : '1', beginrow, endrow, begincol, endcol);
|
||||
|
||||
vram = &m_ram_ptr[(m_page2 ? 0x4000 : 0x2000)];
|
||||
|
||||
vram_row[0] = 0;
|
||||
@ -1252,7 +1265,7 @@ void a2_video_device::hgr_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
|
||||
for (row = beginrow; row <= endrow; row++)
|
||||
{
|
||||
for (col = 0; col < 40; col++)
|
||||
for (col = begincol; col < endcol; col++)
|
||||
{
|
||||
offset = ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col)) | ((row & 7) << 10);
|
||||
vram_row[1+col] = vram[offset];
|
||||
@ -1266,9 +1279,7 @@ void a2_video_device::hgr_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
| (((UINT32) vram_row[col+1] & 0x7f) << 7)
|
||||
| (((UINT32) vram_row[col+2] & 0x7f) << 14);
|
||||
|
||||
switch (mon_type)
|
||||
{
|
||||
case 0:
|
||||
|
||||
// verified on h/w: setting dhires w/o 80col emulates a rev. 0 Apple ][ with no orange/blue
|
||||
if (m_dhires)
|
||||
{
|
||||
@ -1278,6 +1289,10 @@ void a2_video_device::hgr_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
{
|
||||
artifact_map_ptr = &m_hires_artifact_map[((vram_row[col + 1] & 0x80) >> 7) * 16];
|
||||
}
|
||||
|
||||
switch (mon_type)
|
||||
{
|
||||
case 0:
|
||||
for (b = 0; b < 7; b++)
|
||||
{
|
||||
v = artifact_map_ptr[((w >> (b + 7-1)) & 0x07) | (((b ^ col) & 0x01) << 3)];
|
||||
|
Loading…
Reference in New Issue
Block a user