summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
authorGravatarGravatar MooglyGuy <therealmogminer@gmail.com>2019-11-03 15:48:39 +0100
committerGravatarGravatar MooglyGuy <therealmogminer@gmail.com>2019-11-03 15:48:54 +0100
commit7791be49e4819855d52c5037cdf976ee37c40b14 (patch)
tree19e5d1539fb67f2deab296722c8fe07542aac763 /src/emu
parent620ba04ce1522aaa645f409285a94584e02e056d (diff)
-screen: Fixed out-of-bounds vector accesses on interlaced snes games, nw
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/screen.cpp89
-rw-r--r--src/emu/screen.h2
2 files changed, 63 insertions, 28 deletions
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index 64af5b6f217..c14c2ab1aac 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -587,10 +587,62 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
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
// configuration
//-------------------------------------------------
@@ -759,25 +811,6 @@ void screen_device::device_start()
m_texture[1] = machine().render().texture_alloc();
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
render_container::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_visarea = visarea;
- // reallocate bitmap if necessary
- if (m_video_attributes & VIDEO_VARIABLE_WIDTH)
- {
- update_scan_bitmap_size(vpos());
- }
- else
- {
- realloc_screen_bitmaps();
- }
+ // reallocate bitmap(s) if necessary
+ realloc_screen_bitmaps();
// compute timing parameters
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)
{
+ // 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
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[1]->set_bitmap(m_bitmap[1], m_visarea, m_bitmap[1].texformat());
+
+ destroy_scan_bitmaps();
+ allocate_scan_bitmaps();
}
diff --git a/src/emu/screen.h b/src/emu/screen.h
index 3842a65b2e6..9ca2747fc3f 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -454,6 +454,8 @@ private:
void update_scan_bitmap_size(int y);
void pre_update_scanline(int y);
void create_composited_bitmap();
+ void destroy_scan_bitmaps();
+ void allocate_scan_bitmaps();
// inline configuration data
screen_type_enum m_type; // type of screen