mirror of
https://github.com/holub/mame
synced 2025-07-03 09:06:08 +03:00
i8244: split big screen_update function into several pieces
This commit is contained in:
parent
429ab3ca12
commit
31fb8f5c51
@ -4,8 +4,16 @@
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
Intel 8244 (NTSC)/8245 (PAL) Graphics and sound chip
|
Intel 8244 (NTSC)/8245 (PAL) Graphics and sound chip
|
||||||
|
Exclusively used in Odyssey 2 series.
|
||||||
|
|
||||||
Exclusively used in Odyssey 2 series. See driver file for known problems.
|
Features summary:
|
||||||
|
- 9*8 grid
|
||||||
|
- major system (predefined 8*7 objects, 12 single + 4 quads)
|
||||||
|
- minor system (4 user-defined 8*8 sprites)
|
||||||
|
- collision detection between all layers
|
||||||
|
- 1-bit sound
|
||||||
|
|
||||||
|
See Odyssey 2 driver file for known problems.
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
@ -26,9 +34,7 @@ DEFINE_DEVICE_TYPE(I8245, i8245_device, "i8245", "Intel 8245")
|
|||||||
|
|
||||||
i8244_device::i8244_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 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(mconfig, I8244, tag, owner, clock)
|
||||||
{
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
i8244_device::i8244_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 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_t(mconfig, type, tag, owner, clock)
|
||||||
@ -36,13 +42,24 @@ i8244_device::i8244_device(const machine_config &mconfig, device_type type, cons
|
|||||||
, device_video_interface(mconfig, *this)
|
, device_video_interface(mconfig, *this)
|
||||||
, m_irq_func(*this)
|
, m_irq_func(*this)
|
||||||
, m_charset(*this, "cgrom")
|
, m_charset(*this, "cgrom")
|
||||||
{
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
i8245_device::i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
i8245_device::i8245_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
: i8244_device(mconfig, I8245, tag, owner, clock)
|
: i8244_device(mconfig, I8245, tag, owner, clock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device configuration
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void i8244_device::device_config_complete()
|
||||||
{
|
{
|
||||||
|
if (!has_screen())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!screen().refresh_attoseconds())
|
||||||
|
screen().set_raw(clock()*2, m_htotal, m_cropx, m_cropx + m_width, m_vtotal, m_cropy, m_cropy + m_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i8244_device::set_default_params()
|
void i8244_device::set_default_params()
|
||||||
@ -90,7 +107,6 @@ ROM_START( i8244 )
|
|||||||
ROM_LOAD( "charset_i8244.bin", 0x0000, 0x0200, CRC(b46a3f31) SHA1(415382715455b47b69401b3d60bd8f0036dd7fef) )
|
ROM_LOAD( "charset_i8244.bin", 0x0000, 0x0200, CRC(b46a3f31) SHA1(415382715455b47b69401b3d60bd8f0036dd7fef) )
|
||||||
ROM_END
|
ROM_END
|
||||||
|
|
||||||
|
|
||||||
const tiny_rom_entry *i8244_device::device_rom_region() const
|
const tiny_rom_entry *i8244_device::device_rom_region() const
|
||||||
{
|
{
|
||||||
return ROM_NAME( i8244 );
|
return ROM_NAME( i8244 );
|
||||||
@ -98,18 +114,33 @@ const tiny_rom_entry *i8244_device::device_rom_region() const
|
|||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// device_config_complete - perform any
|
// i8244_palette - default palette
|
||||||
// operations now that the configuration is
|
|
||||||
// complete
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void i8244_device::device_config_complete()
|
void i8244_device::i8244_palette(palette_device &palette) const
|
||||||
{
|
{
|
||||||
if (!has_screen())
|
// RGB output, before any NTSC/PAL RF encoder
|
||||||
return;
|
static constexpr rgb_t i8244_colors[16] =
|
||||||
|
{
|
||||||
|
{ 0x00, 0x00, 0x00 }, // i r g b
|
||||||
|
{ 0xb6, 0x00, 0x00 }, // i R g b
|
||||||
|
{ 0x00, 0xb6, 0x00 }, // i r G b
|
||||||
|
{ 0xb6, 0xb6, 0x00 }, // i R G b
|
||||||
|
{ 0x00, 0x00, 0xb6 }, // i r g B
|
||||||
|
{ 0xb6, 0x00, 0xb6 }, // i R g B
|
||||||
|
{ 0x00, 0xb6, 0xb6 }, // i r G B
|
||||||
|
{ 0xb6, 0xb6, 0xb6 }, // i R G B
|
||||||
|
{ 0x49, 0x49, 0x49 }, // I r g b
|
||||||
|
{ 0xff, 0x49, 0x49 }, // I R g b
|
||||||
|
{ 0x49, 0xff, 0x49 }, // I r G b
|
||||||
|
{ 0xff, 0xff, 0x49 }, // I R G b
|
||||||
|
{ 0x49, 0x49, 0xff }, // I r g B
|
||||||
|
{ 0xff, 0x49, 0xff }, // I R g B
|
||||||
|
{ 0x49, 0xff, 0xff }, // I r G B
|
||||||
|
{ 0xff, 0xff, 0xff } // I R G B
|
||||||
|
};
|
||||||
|
|
||||||
if (!screen().refresh_attoseconds())
|
palette.set_pen_colors(0, i8244_colors);
|
||||||
screen().set_raw(clock()*2, m_htotal, m_cropx, m_cropx + m_width, m_vtotal, m_cropy, m_cropy + m_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -153,32 +184,9 @@ void i8244_device::device_start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i8244_device::i8244_palette(palette_device &palette) const
|
//-------------------------------------------------
|
||||||
{
|
// device_timer - handle timer callbacks
|
||||||
// RGB output, before any NTSC/PAL RF encoder
|
//-------------------------------------------------
|
||||||
static constexpr rgb_t i8244_colors[16] =
|
|
||||||
{
|
|
||||||
{ 0x00, 0x00, 0x00 }, // i r g b
|
|
||||||
{ 0xb6, 0x00, 0x00 }, // i R g b
|
|
||||||
{ 0x00, 0xb6, 0x00 }, // i r G b
|
|
||||||
{ 0xb6, 0xb6, 0x00 }, // i R G b
|
|
||||||
{ 0x00, 0x00, 0xb6 }, // i r g B
|
|
||||||
{ 0xb6, 0x00, 0xb6 }, // i R g B
|
|
||||||
{ 0x00, 0xb6, 0xb6 }, // i r G B
|
|
||||||
{ 0xb6, 0xb6, 0xb6 }, // i R G B
|
|
||||||
{ 0x49, 0x49, 0x49 }, // I r g b
|
|
||||||
{ 0xff, 0x49, 0x49 }, // I R g b
|
|
||||||
{ 0x49, 0xff, 0x49 }, // I r G b
|
|
||||||
{ 0xff, 0xff, 0x49 }, // I R G b
|
|
||||||
{ 0x49, 0x49, 0xff }, // I r g B
|
|
||||||
{ 0xff, 0x49, 0xff }, // I R g B
|
|
||||||
{ 0x49, 0xff, 0xff }, // I r G B
|
|
||||||
{ 0xff, 0xff, 0xff } // I R G B
|
|
||||||
};
|
|
||||||
|
|
||||||
palette.set_pen_colors(0, i8244_colors);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void i8244_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
void i8244_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
{
|
{
|
||||||
@ -201,6 +209,10 @@ void i8244_device::device_timer(emu_timer &timer, device_timer_id id, int param,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
I/O
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
offs_t i8244_device::fix_register_mirrors(offs_t offset)
|
offs_t i8244_device::fix_register_mirrors(offs_t offset)
|
||||||
{
|
{
|
||||||
// quad x/y registers are mirrored for each quad
|
// quad x/y registers are mirrored for each quad
|
||||||
@ -472,58 +484,12 @@ void i8244_device::write_cx(int x, bool cx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i8244_device::draw_char(u8 index, int x, int y, u8 pixel, u16 color, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
/***************************************************************************
|
||||||
|
RENDER
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
void i8244_device::draw_grid(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||||
{
|
{
|
||||||
for (int px = x; px < x + 2; px++)
|
|
||||||
{
|
|
||||||
if (cliprect.contains(px, y))
|
|
||||||
{
|
|
||||||
u8 colx = m_collision_map[px];
|
|
||||||
|
|
||||||
// check collision with self
|
|
||||||
if (index < m_priority_map[px])
|
|
||||||
{
|
|
||||||
m_control_status |= 0x80;
|
|
||||||
|
|
||||||
// TODO: much more complex on actual console (weird glitches happen)
|
|
||||||
if (colx & 0x80)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_priority_map[px] = index;
|
|
||||||
|
|
||||||
if (pixel)
|
|
||||||
{
|
|
||||||
// check if we collide with an already drawn source object
|
|
||||||
if (m_vdc.s.collision & colx)
|
|
||||||
m_collision_status |= 0x80;
|
|
||||||
|
|
||||||
// check if an already drawn object would collide with us
|
|
||||||
if (m_vdc.s.collision & 0x80)
|
|
||||||
m_collision_status |= colx;
|
|
||||||
|
|
||||||
m_collision_map[px] |= 0x80;
|
|
||||||
bitmap.pix(y, px) = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
|
||||||
{
|
|
||||||
// draw background color
|
|
||||||
bitmap.fill(bitswap<3>(m_vdc.s.color,3,4,5), cliprect);
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
// display grid if enabled
|
|
||||||
if (m_vdc.s.control & 0x08)
|
|
||||||
{
|
|
||||||
u16 color = bitswap<4>(m_vdc.s.color,6,0,1,2);
|
u16 color = bitswap<4>(m_vdc.s.color,6,0,1,2);
|
||||||
int x_grid_offset = 13;
|
int x_grid_offset = 13;
|
||||||
int y_grid_offset = 24;
|
int y_grid_offset = 24;
|
||||||
@ -611,11 +577,49 @@ u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// display objects if enabled
|
|
||||||
if (m_vdc.s.control & 0x20 && scanline <= 242)
|
void i8244_device::char_pixel(u8 index, int x, int y, u8 pixel, u16 color, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||||
|
{
|
||||||
|
for (int px = x; px < x + 2; px++)
|
||||||
{
|
{
|
||||||
|
if (cliprect.contains(px, y))
|
||||||
|
{
|
||||||
|
u8 colx = m_collision_map[px];
|
||||||
|
|
||||||
|
// check collision with self
|
||||||
|
if (index < m_priority_map[px])
|
||||||
|
{
|
||||||
|
m_control_status |= 0x80;
|
||||||
|
|
||||||
|
// TODO: much more complex on actual console (weird glitches happen)
|
||||||
|
if (colx & 0x80)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_priority_map[px] = index;
|
||||||
|
|
||||||
|
if (pixel)
|
||||||
|
{
|
||||||
|
// check if we collide with an already drawn source object
|
||||||
|
if (m_vdc.s.collision & colx)
|
||||||
|
m_collision_status |= 0x80;
|
||||||
|
|
||||||
|
// check if an already drawn object would collide with us
|
||||||
|
if (m_vdc.s.collision & 0x80)
|
||||||
|
m_collision_status |= colx;
|
||||||
|
|
||||||
|
m_collision_map[px] |= 0x80;
|
||||||
|
bitmap.pix(y, px) = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void i8244_device::draw_major(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||||
|
{
|
||||||
// quad objects
|
// quad objects
|
||||||
for (int i = ARRAY_LENGTH(m_vdc.s.quad) - 1; i >= 0; i--)
|
for (int i = ARRAY_LENGTH(m_vdc.s.quad) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@ -637,7 +641,7 @@ u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, con
|
|||||||
|
|
||||||
u16 color = 8 + ((m_vdc.s.quad[i].single[j].color >> 1) & 0x07);
|
u16 color = 8 + ((m_vdc.s.quad[i].single[j].color >> 1) & 0x07);
|
||||||
for (int cx = 0; cx < 8; cx++, x += 2)
|
for (int cx = 0; cx < 8; cx++, x += 2)
|
||||||
draw_char(4 * j + 16 * i + 0x40, x, scanline, BIT(m_charset[offset & 0x1ff], cx ^ 7), color, bitmap, cliprect);
|
char_pixel(4 * j + 16 * i + 0x40, x, scanline, BIT(m_charset[offset & 0x1ff], cx ^ 7), color, bitmap, cliprect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -659,11 +663,15 @@ u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, con
|
|||||||
int x = (m_vdc.s.foreground[i].x + 5) * 2;
|
int x = (m_vdc.s.foreground[i].x + 5) * 2;
|
||||||
u16 color = 8 + ((m_vdc.s.foreground[i].color >> 1) & 0x07);
|
u16 color = 8 + ((m_vdc.s.foreground[i].color >> 1) & 0x07);
|
||||||
for (int cx = 0; cx < 8; cx++, x += 2)
|
for (int cx = 0; cx < 8; cx++, x += 2)
|
||||||
draw_char(4 * i + 0x10, x, scanline, BIT(m_charset[offset & 0x1ff], cx ^ 7), color, bitmap, cliprect);
|
char_pixel(4 * i + 0x10, x, scanline, BIT(m_charset[offset & 0x1ff], cx ^ 7), color, bitmap, cliprect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// sprites
|
|
||||||
|
void i8244_device::draw_minor(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||||
|
{
|
||||||
|
// minor system (sprites)
|
||||||
for (int i = ARRAY_LENGTH(m_vdc.s.sprites) - 1; i >= 0; i--)
|
for (int i = ARRAY_LENGTH(m_vdc.s.sprites) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
int y = m_vdc.s.sprites[i].y;
|
int y = m_vdc.s.sprites[i].y;
|
||||||
@ -721,6 +729,29 @@ u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||||
|
{
|
||||||
|
// draw background color
|
||||||
|
bitmap.fill(bitswap<3>(m_vdc.s.color,3,4,5), cliprect);
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
// display grid if enabled
|
||||||
|
if (m_vdc.s.control & 0x08 && scanline >= 24 && scanline <= 218)
|
||||||
|
draw_grid(scanline, bitmap, cliprect);
|
||||||
|
|
||||||
|
// display objects if enabled
|
||||||
|
if (m_vdc.s.control & 0x20 && scanline <= 242)
|
||||||
|
{
|
||||||
|
draw_major(scanline, bitmap, cliprect);
|
||||||
|
draw_minor(scanline, bitmap, cliprect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,6 +759,10 @@ u32 i8244_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
SOUND
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
void i8244_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
|
void i8244_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
|
||||||
{
|
{
|
||||||
u8 volume = m_vdc.s.sound & 0xf;
|
u8 volume = m_vdc.s.sound & 0xf;
|
||||||
|
@ -124,7 +124,10 @@ protected:
|
|||||||
offs_t fix_register_mirrors(offs_t offset);
|
offs_t fix_register_mirrors(offs_t offset);
|
||||||
bool invalid_register(offs_t offset, bool rw);
|
bool invalid_register(offs_t offset, bool rw);
|
||||||
|
|
||||||
void draw_char(u8 index, int x, int y, u8 pixel, u16 color, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
void draw_grid(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||||
|
void draw_major(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||||
|
void draw_minor(int scanline, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||||
|
void char_pixel(u8 index, int x, int y, u8 pixel, u16 color, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||||
|
|
||||||
/* timers */
|
/* timers */
|
||||||
static constexpr device_timer_id TIMER_VBLANK_START = 0;
|
static constexpr device_timer_id TIMER_VBLANK_START = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user