// license:BSD-3-Clause
// copyright-holders:Stefan Jokisch
/***************************************************************************
Taito Super Speed Race video emulation
***************************************************************************/
#include "emu.h"
#include "includes/sspeedr.h"
WRITE8_MEMBER(sspeedr_state::sspeedr_driver_horz_w)
{
m_driver_horz = (m_driver_horz & 0x100) | data;
}
WRITE8_MEMBER(sspeedr_state::sspeedr_driver_horz_2_w)
{
m_driver_horz = (m_driver_horz & 0xff) | ((data & 1) << 8);
}
WRITE8_MEMBER(sspeedr_state::sspeedr_driver_vert_w)
{
m_driver_vert = data;
}
WRITE8_MEMBER(sspeedr_state::sspeedr_driver_pic_w)
{
m_driver_pic = data & 0x1f;
}
WRITE8_MEMBER(sspeedr_state::sspeedr_drones_horz_w)
{
m_drones_horz = (m_drones_horz & 0x100) | data;
}
WRITE8_MEMBER(sspeedr_state::sspeedr_drones_horz_2_w)
{
m_drones_horz = (m_drones_horz & 0xff) | ((data & 1) << 8);
}
WRITE8_MEMBER(sspeedr_state::sspeedr_drones_mask_w)
{
m_drones_mask = data & 0x3f;
}
WRITE8_MEMBER(sspeedr_state::sspeedr_drones_vert_w)
{
m_drones_vert[offset] = data;
}
WRITE8_MEMBER(sspeedr_state::sspeedr_track_horz_w)
{
m_track_horz = (m_track_horz & 0x100) | data;
}
WRITE8_MEMBER(sspeedr_state::sspeedr_track_horz_2_w)
{
m_track_horz = (m_track_horz & 0xff) | ((data & 1) << 8);
}
WRITE8_MEMBER(sspeedr_state::sspeedr_track_vert_w)
{
m_track_vert[offset] = data & 0x7f;
}
WRITE8_MEMBER(sspeedr_state::sspeedr_track_ice_w)
{
m_track_ice = data & 0x07;
}
void sspeedr_state::draw_track(bitmap_ind16 &bitmap)
{
const uint8_t* p = memregion("gfx3")->base();
int x;
int y;
for (x = 0; x < 376; x++)
{
unsigned counter_x = x + m_track_horz + 0x50;
int flag = 0;
if (m_track_ice & 2)
{
flag = 1;
}
else if (m_track_ice & 4)
{
if (m_track_ice & 1)
{
flag = (counter_x <= 0x1ff);
}
else
{
flag = (counter_x >= 0x200);
}
}
if (counter_x >= 0x200)
{
counter_x -= 0x1c8;
}
y = 0;
/* upper landscape */
for (; y < m_track_vert[0]; y++)
{
unsigned counter_y = y - m_track_vert[0];
int offset =
((counter_y & 0x1f) << 3) |
((counter_x & 0x1c) >> 2) |
((counter_x & 0xe0) << 3);
if (counter_x & 2)
{
bitmap.pix16(y, x) = p[offset] / 16;
}
else
{
bitmap.pix16(y, x) = p[offset] % 16;
}
}
/* street */
for (; y < 128 + m_track_vert[1]; y++)
{
bitmap.pix16(y, x) = flag ? 15 : 0;
}
/* lower landscape */
for (; y < 248; y++)
{
unsigned counter_y = y - m_track_vert[1];
int offset =
((counter_y & 0x1f) << 3) |
((counter_x & 0x1c) >> 2) |
((counter_x & 0xe0) << 3);
if (counter_x & 2)
{
bitmap.pix16(y, x) = p[offset] / 16;
}
else
{
bitmap.pix16(y, x) = p[offset] % 16;
}
}
}
}
void sspeedr_state::draw_drones(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
static const uint8_t code[6] =
{
0xf, 0x4, 0x3, 0x9, 0x7, 0xc
};
int i;
for (i = 0; i < 6; i++)
{
int x;
int y;
if ((m_drones_mask >> i) & 1)
{
continue;
}
x = (code[i] << 5) - m_drones_horz - 0x50;
if (x <= -32)
{
x += 0x1c8;
}
y = 0xf0 - m_drones_vert[i >> 1];
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
code[i] ^ m_toggle,
0,
0, 0,
x,
y, 0);
}
}
void sspeedr_state::draw_driver(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int x;
int y;
if (!(m_driver_pic & 0x10))
{
return;
}
x = 0x1e0 - m_driver_horz - 0x50;
if (x <= -32)
{
x += 0x1c8;
}
y = 0xf0 - m_driver_vert;
m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
m_driver_pic,
0,
0, 0,
x,
y, 0);
}
void sspeedr_state::video_start()
{
m_toggle = 0;
}
uint32_t sspeedr_state::screen_update_sspeedr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
draw_track(bitmap);
draw_drones(bitmap, cliprect);
draw_driver(bitmap, cliprect);
return 0;
}
WRITE_LINE_MEMBER(sspeedr_state::screen_vblank_sspeedr)
{
// rising edge
if (state)
{
m_toggle ^= 1;
}
}