Skip to content

Commit

Permalink
i8244: fix collision detection edge case [hap, bataais]
Browse files Browse the repository at this point in the history
  • Loading branch information
happppp committed Dec 3, 2024
1 parent 969ee8b commit c13ed02
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 36 deletions.
4 changes: 2 additions & 2 deletions hash/videopac.xml
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ distinguished by the changed copyright from Magnavox to N.A.P. (North American P
</part>
</software>

<software name="volley" supported="partial">
<software name="volley">
<description>Electronic Volleyball (Europe, USA)</description>
<year>1979</year>
<publisher>Philips</publisher>
Expand All @@ -846,7 +846,7 @@ distinguished by the changed copyright from Magnavox to N.A.P. (North American P
</part>
</software>

<software name="volleyf" cloneof="volley" supported="partial">
<software name="volleyf" cloneof="volley">
<description>Volleyball (France)</description>
<year>1979</year>
<publisher>Radiola</publisher>
Expand Down
19 changes: 9 additions & 10 deletions src/devices/video/ef9340_1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down
3 changes: 1 addition & 2 deletions src/devices/video/ef9340_1.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
64 changes: 49 additions & 15 deletions src/devices/video/i8244.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{ }


Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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;
Expand Down
6 changes: 2 additions & 4 deletions src/devices/video/i8244.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions src/mame/philips/odyssey2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c13ed02

Please sign in to comment.