From c13ed02291783bc370de4f56a42e73fbf55a9899 Mon Sep 17 00:00:00 2001 From: hap Date: Tue, 3 Dec 2024 21:44:04 +0100 Subject: [PATCH] i8244: fix collision detection edge case [hap, bataais] --- hash/videopac.xml | 4 +-- src/devices/video/ef9340_1.cpp | 19 +++++----- src/devices/video/ef9340_1.h | 3 +- src/devices/video/i8244.cpp | 64 ++++++++++++++++++++++++++-------- src/devices/video/i8244.h | 6 ++-- src/mame/philips/odyssey2.cpp | 3 -- 6 files changed, 63 insertions(+), 36 deletions(-) diff --git a/hash/videopac.xml b/hash/videopac.xml index 438d12d4109..a48d7f36d83 100644 --- a/hash/videopac.xml +++ b/hash/videopac.xml @@ -831,7 +831,7 @@ distinguished by the changed copyright from Magnavox to N.A.P. (North American P - + Electronic Volleyball (Europe, USA) 1979 Philips @@ -846,7 +846,7 @@ distinguished by the changed copyright from Magnavox to N.A.P. (North American P - + Volleyball (France) 1979 Radiola diff --git a/src/devices/video/ef9340_1.cpp b/src/devices/video/ef9340_1.cpp index c218645208c..7b5dbcb5d8d 100644 --- a/src/devices/video/ef9340_1.cpp +++ b/src/devices/video/ef9340_1.cpp @@ -35,16 +35,15 @@ This is implemented with a callback. The datasheet explains how to hook up DEFINE_DEVICE_TYPE(EF9340_1, ef9340_1_device, "ef9340_1", "Thomson EF9340+EF9341") -ef9340_1_device::ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, EF9340_1, tag, owner, clock) - , device_video_interface(mconfig, *this) - , m_charset(*this, "ef9340_1") - , m_write_exram(*this) - , m_read_exram(*this, 0xff) -{ - m_offset_x = 0; - m_offset_y = 0; -} +ef9340_1_device::ef9340_1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, EF9340_1, tag, owner, clock), + device_video_interface(mconfig, *this), + m_charset(*this, "ef9340_1"), + m_offset_x(0), + m_offset_y(0), + m_write_exram(*this), + m_read_exram(*this, 0xff) +{ } ROM_START( ef9340_1 ) diff --git a/src/devices/video/ef9340_1.h b/src/devices/video/ef9340_1.h index 1433a992a31..539fcb395c1 100644 --- a/src/devices/video/ef9340_1.h +++ b/src/devices/video/ef9340_1.h @@ -40,8 +40,7 @@ */ -class ef9340_1_device : public device_t, - public device_video_interface +class ef9340_1_device : public device_t, public device_video_interface { public: // construction/destruction diff --git a/src/devices/video/i8244.cpp b/src/devices/video/i8244.cpp index 1734d83677d..3689a0ec6e5 100644 --- a/src/devices/video/i8244.cpp +++ b/src/devices/video/i8244.cpp @@ -32,20 +32,20 @@ DEFINE_DEVICE_TYPE(I8245, i8245_device, "i8245", "Intel 8245") // i8244_device - constructor //------------------------------------------------- -i8244_device::i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : i8244_device(mconfig, I8244, tag, owner, clock) +i8244_device::i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + i8244_device(mconfig, I8244, tag, owner, clock) { } -i8244_device::i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, type, tag, owner, clock) - , device_sound_interface(mconfig, *this) - , device_video_interface(mconfig, *this) - , m_irq_func(*this) - , m_charset(*this, "cgrom") +i8244_device::i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, type, tag, owner, clock), + device_sound_interface(mconfig, *this), + device_video_interface(mconfig, *this), + m_irq_func(*this), + m_charset(*this, "cgrom") { } -i8245_device::i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : i8244_device(mconfig, I8245, tag, owner, clock) +i8245_device::i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + i8244_device(mconfig, I8245, tag, owner, clock) { } @@ -685,15 +685,17 @@ void i8244_device::draw_minor(int scanline, bitmap_ind16 &bitmap, const rectangl { if (cliprect.contains(px, scanline)) { - u8 mask = 1 << i; + // put zoom flag on high byte for later collision detection + u16 mask = (zoom_enable ? 0x101 : 1) << i; + u8 colx = m_collision_map[px]; // check if we collide with an already drawn source object - if (m_vdc.s.collision & m_collision_map[px]) + if (m_vdc.s.collision & colx) m_collision_status |= mask; // check if an already drawn object would collide with us if (m_vdc.s.collision & mask) - m_collision_status |= m_collision_map[px]; + m_collision_status |= colx; m_collision_map[px] |= mask; bitmap.pix(scanline, px) = color; @@ -714,8 +716,11 @@ u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, con for (int scanline = cliprect.min_y; scanline <= cliprect.max_y; scanline++) { // clear collision maps - memset(m_collision_map, 0, sizeof(m_collision_map)); - memset(m_priority_map, 0, sizeof(m_priority_map)); + if (cliprect.min_x == screen.visible_area().min_x) + { + memset(m_collision_map, 0, sizeof(m_collision_map)); + memset(m_priority_map, 0, sizeof(m_priority_map)); + } // display grid if enabled if (m_vdc.s.control & 0x08 && scanline >= 24 && scanline <= 218) @@ -727,6 +732,35 @@ u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, con draw_major(scanline, bitmap, cliprect); draw_minor(scanline, bitmap, cliprect); } + + // go over the collision map again for edge cases on this scanline + for (int x = cliprect.min_x; x <= cliprect.max_x; x++) + { + if (x > screen.visible_area().min_x) + { + u16 colx0 = m_collision_map[x - 1]; + u16 colx1 = m_collision_map[x]; + + // grid or minor to the left of major + if (colx1 & 0x80) + { + if (m_vdc.s.collision & colx0 & 0x3f) + m_collision_status |= 0x80; + + if (m_vdc.s.collision & 0x80) + m_collision_status |= colx0 & 0x3f; + } + + // grid to the left of non-zoomed minor + u8 mask = (colx1 & 0xf) & (~colx1 >> 8); + + if (m_vdc.s.collision & colx0 & 0x30) + m_collision_status |= mask; + + if (m_vdc.s.collision & mask) + m_collision_status |= colx0 & 0x30; + } + } } return 0; diff --git a/src/devices/video/i8244.h b/src/devices/video/i8244.h index ad6e25e7e94..5b631e9b2b5 100644 --- a/src/devices/video/i8244.h +++ b/src/devices/video/i8244.h @@ -39,9 +39,7 @@ DECLARE_DEVICE_TYPE(I8244, i8244_device) DECLARE_DEVICE_TYPE(I8245, i8245_device) -class i8244_device : public device_t - , public device_sound_interface - , public device_video_interface +class i8244_device : public device_t, public device_sound_interface, public device_video_interface { public: // construction/destruction @@ -156,7 +154,7 @@ class i8244_device : public device_t int m_bgate_start; vdc_t m_vdc; - u8 m_collision_map[0x200]; + u16 m_collision_map[0x200]; u8 m_priority_map[0x200]; u8 m_x_beam_pos; diff --git a/src/mame/philips/odyssey2.cpp b/src/mame/philips/odyssey2.cpp index dc4775f75f5..1b182da616b 100644 --- a/src/mame/philips/odyssey2.cpp +++ b/src/mame/philips/odyssey2.cpp @@ -56,9 +56,6 @@ XTAL notes (differs per model): and writes to the ptr/color registers, but does not increment the Y regs. Does it (ab)use an undocumented 8245 feature? - g7400 helicopt sometimes locks up at the sea level, timing or IRQ related? -- volley has a sprite-char collision detection problem, causing the team on the - right to never serve the ball. Sprite positions are correct so it's not that, - and as seen on videos of other games, transparent pixels don't cause a collision. - spaans has a keyboard debounce issue: if you push and hold a key after the game revealed the answer, it will be entered in the next input field. It's a prototype so it wouldn't be surprising there are bugs, but this issue does not happen on