mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
-screen: Fixed out-of-bounds vector accesses on interlaced snes games, nw
This commit is contained in:
parent
620ba04ce1
commit
7791be49e4
@ -587,9 +587,61 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
|
|||||||
|
|
||||||
screen_device::~screen_device()
|
screen_device::~screen_device()
|
||||||
{
|
{
|
||||||
|
destroy_scan_bitmaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// destroy_scan_bitmaps - destroy per-scanline
|
||||||
|
// bitmaps if applicable
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void screen_device::destroy_scan_bitmaps()
|
||||||
|
{
|
||||||
|
if (m_video_attributes & VIDEO_VARIABLE_WIDTH)
|
||||||
|
{
|
||||||
|
const bool screen16 = !m_screen_update_ind16.isnull();
|
||||||
|
for (int j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
for (bitmap_t* bitmap : m_scan_bitmaps[j])
|
||||||
|
{
|
||||||
|
if (screen16)
|
||||||
|
delete (bitmap_ind16*)bitmap;
|
||||||
|
else
|
||||||
|
delete (bitmap_rgb32*)bitmap;
|
||||||
|
}
|
||||||
|
m_scan_bitmaps[j].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// allocate_scan_bitmaps - allocate per-scanline
|
||||||
|
// bitmaps if applicable
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void screen_device::allocate_scan_bitmaps()
|
||||||
|
{
|
||||||
|
if (m_video_attributes & VIDEO_VARIABLE_WIDTH)
|
||||||
|
{
|
||||||
|
const bool screen16 = !m_screen_update_ind16.isnull();
|
||||||
|
s32 effwidth = std::max(m_max_width, m_visarea.right() + 1);
|
||||||
|
s32 effheight = std::max(m_height, m_visarea.bottom() + 1);
|
||||||
|
for (int i = 0; i < effheight; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
if (screen16)
|
||||||
|
m_scan_bitmaps[j].push_back(new bitmap_ind16(effwidth, 1));
|
||||||
|
else
|
||||||
|
m_scan_bitmaps[j].push_back(new bitmap_rgb32(effwidth, 1));
|
||||||
|
}
|
||||||
|
m_scan_widths.push_back(m_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// device_validity_check - verify device
|
// device_validity_check - verify device
|
||||||
// configuration
|
// configuration
|
||||||
@ -759,25 +811,6 @@ void screen_device::device_start()
|
|||||||
m_texture[1] = machine().render().texture_alloc();
|
m_texture[1] = machine().render().texture_alloc();
|
||||||
m_texture[1]->set_id((u64(m_unique_id) << 57) | 1);
|
m_texture[1]->set_id((u64(m_unique_id) << 57) | 1);
|
||||||
|
|
||||||
if (m_video_attributes & VIDEO_VARIABLE_WIDTH)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_height; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 2; j++)
|
|
||||||
{
|
|
||||||
if (screen16)
|
|
||||||
{
|
|
||||||
m_scan_bitmaps[j].push_back(new bitmap_ind16(m_width, 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_scan_bitmaps[j].push_back(new bitmap_rgb32(m_width, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_scan_widths.push_back(m_width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure the default cliparea
|
// configure the default cliparea
|
||||||
render_container::user_settings settings;
|
render_container::user_settings settings;
|
||||||
m_container->get_user_settings(settings);
|
m_container->get_user_settings(settings);
|
||||||
@ -958,15 +991,8 @@ void screen_device::configure(int width, int height, const rectangle &visarea, a
|
|||||||
m_height = height;
|
m_height = height;
|
||||||
m_visarea = visarea;
|
m_visarea = visarea;
|
||||||
|
|
||||||
// reallocate bitmap if necessary
|
// reallocate bitmap(s) if necessary
|
||||||
if (m_video_attributes & VIDEO_VARIABLE_WIDTH)
|
realloc_screen_bitmaps();
|
||||||
{
|
|
||||||
update_scan_bitmap_size(vpos());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
realloc_screen_bitmaps();
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute timing parameters
|
// compute timing parameters
|
||||||
m_frame_period = frame_period;
|
m_frame_period = frame_period;
|
||||||
@ -1038,6 +1064,10 @@ void screen_device::reset_origin(int beamy, int beamx)
|
|||||||
|
|
||||||
void screen_device::update_scan_bitmap_size(int y)
|
void screen_device::update_scan_bitmap_size(int y)
|
||||||
{
|
{
|
||||||
|
// don't update this line if it exceeds the allocated size, which can happen on initial configuration
|
||||||
|
if (y >= m_scan_widths.size())
|
||||||
|
return;
|
||||||
|
|
||||||
// determine effective size to allocate
|
// determine effective size to allocate
|
||||||
s32 effwidth = std::max(m_max_width, m_visarea.right() + 1);
|
s32 effwidth = std::max(m_max_width, m_visarea.right() + 1);
|
||||||
|
|
||||||
@ -1077,6 +1107,9 @@ void screen_device::realloc_screen_bitmaps()
|
|||||||
}
|
}
|
||||||
m_texture[0]->set_bitmap(m_bitmap[0], m_visarea, m_bitmap[0].texformat());
|
m_texture[0]->set_bitmap(m_bitmap[0], m_visarea, m_bitmap[0].texformat());
|
||||||
m_texture[1]->set_bitmap(m_bitmap[1], m_visarea, m_bitmap[1].texformat());
|
m_texture[1]->set_bitmap(m_bitmap[1], m_visarea, m_bitmap[1].texformat());
|
||||||
|
|
||||||
|
destroy_scan_bitmaps();
|
||||||
|
allocate_scan_bitmaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -454,6 +454,8 @@ private:
|
|||||||
void update_scan_bitmap_size(int y);
|
void update_scan_bitmap_size(int y);
|
||||||
void pre_update_scanline(int y);
|
void pre_update_scanline(int y);
|
||||||
void create_composited_bitmap();
|
void create_composited_bitmap();
|
||||||
|
void destroy_scan_bitmaps();
|
||||||
|
void allocate_scan_bitmaps();
|
||||||
|
|
||||||
// inline configuration data
|
// inline configuration data
|
||||||
screen_type_enum m_type; // type of screen
|
screen_type_enum m_type; // type of screen
|
||||||
|
Loading…
Reference in New Issue
Block a user