mame/src/mame/video/8080bw.cpp
janniz f31b19f9c9 Added two new unreleased Model Racing games (#5813)
* Fixed LOG_WAV_ENABLED_ONLY (m_enable has to be checked only if LOG_WAV_ENABLED_ONLY is set)
Added log data to the right channel of the wave, accordingly to the definition declared in LOG_WAV_VALUE_R

* Fixed an error with tag() returning a ':' and generating a filename not valid in Windows environment

* Added Model Racing "Cane"

* Added Model Racing "Orbite"

* Replaced the char array with a std::string in sn76477_device::open_wav_file to override possible buffer overrun.
Minor cosmetic change in a boolean expression in sn76477_device::sound_stream_update

* Refactored "Cane" related code creating an audio device to encapsulate the audio system
Refactored "Cane" and "Orbite" creating their own classes
Other minor changes in indentation of the source code
2019-10-31 22:11:45 +11:00

437 lines
12 KiB
C++

// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria, Tormod Tjaberg, Mirko Buffoni,Lee Taylor, Valerio Verrando, Zsolt Vasvari,Aaron Giles,Jonathan Gevaryahu,hap,Robbbert
// thanks-to:Michael Strutts, Marco Cassili
/***************************************************************************
video.c
Functions to emulate the video hardware of the machine.
***************************************************************************/
#include "emu.h"
#include "includes/8080bw.h"
MACHINE_START_MEMBER(_8080bw_state,extra_8080bw_vh)
{
save_item(NAME(m_flip_screen));
save_item(NAME(m_color_map));
save_item(NAME(m_screen_red));
// These two only belong to schaser, but for simplicity's sake let's waste
// two bytes in other drivers' .sta files.
save_item(NAME(m_schaser_background_disable));
save_item(NAME(m_schaser_background_select));
}
void _8080bw_state::rollingc_palette(palette_device &palette) const
{
// palette is 3bpp + intensity
for (int i = 0; i < 8; i++)
{
palette.set_pen_color(i, pal1bit(i >> 2) >> 1, pal1bit(i >> 1) >> 1, pal1bit(i >> 0) >> 1);
palette.set_pen_color(i | 8, pal1bit(i >> 2), pal1bit(i >> 1), pal1bit(i >> 0));
}
// but according to photos, pen 6 is clearly orange instead of dark-yellow, and pen 5 is less dark as well
// pens 1, 2 and 4 are good though. Maybe we're missing a color prom?
palette.set_pen_color(0x05, 0xff, 0x00, 0x80); // pink
palette.set_pen_color(0x06, 0xff, 0x80, 0x00); // orange
}
void _8080bw_state::sflush_palette(palette_device &palette) const
{
// standard 3-bit rbg palette, but background color is bright blue
palette.set_pen_color(0, 0x80, 0x80, 0xff);
for (int i = 1; i < 8; i++)
palette.set_pen_color(i, rgb_t(pal1bit(i >> 0), pal1bit(i >> 2), pal1bit(i >> 1)));
}
inline void _8080bw_state::set_pixel( bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, int color )
{
if (y >= MW8080BW_VCOUNTER_START_NO_VBLANK)
{
if (m_flip_screen)
bitmap.pix32(MW8080BW_VBSTART - 1 - (y - MW8080BW_VCOUNTER_START_NO_VBLANK), MW8080BW_HPIXCOUNT - 1 - x) = m_palette->pen_color(color);
else
bitmap.pix32(y - MW8080BW_VCOUNTER_START_NO_VBLANK, x) = m_palette->pen_color(color);
}
}
inline void _8080bw_state::set_8_pixels( bitmap_rgb32 &bitmap, uint8_t y, uint8_t x, uint8_t data, int fore_color, int back_color )
{
int i;
for (i = 0; i < 8; i++)
{
set_pixel(bitmap, y, x, (data & 0x01) ? fore_color : back_color);
x = x + 1;
data = data >> 1;
}
}
/* this is needed as this driver doesn't emulate the shift register like mw8080bw does */
void _8080bw_state::clear_extra_columns( bitmap_rgb32 &bitmap, int color )
{
uint8_t x;
for (x = 0; x < 4; x++)
{
uint8_t y;
for (y = MW8080BW_VCOUNTER_START_NO_VBLANK; y != 0; y++)
{
if (m_flip_screen)
bitmap.pix32(MW8080BW_VBSTART - 1 - (y - MW8080BW_VCOUNTER_START_NO_VBLANK), MW8080BW_HPIXCOUNT - 1 - (256 + x)) = m_palette->pen_color(color);
else
bitmap.pix32(y - MW8080BW_VCOUNTER_START_NO_VBLANK, 256 + x) = m_palette->pen_color(color);
}
}
}
uint32_t _8080bw_state::screen_update_invadpt2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t *prom = memregion("proms")->base();
uint8_t *color_map_base = m_color_map ? &prom[0x0400] : &prom[0x0000];
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
offs_t color_address = (offs >> 8 << 5) | (offs & 0x1f);
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_screen_red ? 1 : color_map_base[color_address] & 0x07;
set_8_pixels(bitmap, y, x, data, fore_color, 0);
}
clear_extra_columns(bitmap, 0);
return 0;
}
uint32_t _8080bw_state::screen_update_ballbomb(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t *prom = memregion("proms")->base();
uint8_t *color_map_base = m_color_map ? &prom[0x0400] : &prom[0x0000];
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
offs_t color_address = (offs >> 8 << 5) | (offs & 0x1f);
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_screen_red ? 1 : color_map_base[color_address] & 0x07;
/* blue background */
set_8_pixels(bitmap, y, x, data, fore_color, 2);
}
clear_extra_columns(bitmap, 2);
return 0;
}
uint32_t _8080bw_state::screen_update_schaser(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t *background_map_base = memregion("proms")->base();
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t back_color = 0;
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_scattered_colorram[(offs & 0x1f) | ((offs & 0x1f80) >> 2)] & 0x07;
if (!m_schaser_background_disable)
{
offs_t back_address = (offs >> 8 << 5) | (offs & 0x1f);
uint8_t back_data = background_map_base[back_address];
/* the equations derived from the schematics don't appear to produce
the right colors, but this one does, at least for this PROM */
back_color = (((back_data & 0x0c) == 0x0c) && m_schaser_background_select) ? 4 : 2;
}
set_8_pixels(bitmap, y, x, data, fore_color, back_color);
}
clear_extra_columns(bitmap, m_schaser_background_disable ? 0 : 2);
return 0;
}
uint32_t _8080bw_state::screen_update_schasercv(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_scattered_colorram[(offs & 0x1f) | ((offs & 0x1f80) >> 2)] & 0x07;
/* blue background */
set_8_pixels(bitmap, y, x, data, fore_color, 2);
}
clear_extra_columns(bitmap, 2);
return 0;
}
uint32_t _8080bw_state::screen_update_rollingc(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_scattered_colorram[(offs & 0x1f) | ((offs & 0x1f00) >> 3)] & 0x0f;
uint8_t back_color = m_scattered_colorram2[(offs & 0x1f) | ((offs & 0x1f00) >> 3)] & 0x0f;
set_8_pixels(bitmap, y, x, data, fore_color, back_color);
}
clear_extra_columns(bitmap, 0);
return 0;
}
uint32_t _8080bw_state::screen_update_polaris(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t *color_map_base = memregion("proms")->base();
uint8_t *cloud_gfx = memregion("user1")->base();
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t data = m_main_ram[offs];
offs_t color_address = (offs >> 8 << 5) | (offs & 0x1f);
/* for the background color, bit 0 of the map PROM is connected to green gun.
red is 0 and blue is 1, giving cyan and blue for the background. This
is different from what the schematics shows, but it's supported
by screenshots. Bit 3 is connected to cloud enable, while
bits 1 and 2 are marked 'not use' (sic) */
uint8_t back_color = (color_map_base[color_address] & 0x01) ? 6 : 2;
uint8_t fore_color = ~m_scattered_colorram[(offs & 0x1f) | ((offs & 0x1f80) >> 2)] & 0x07;
uint8_t cloud_y = y - m_polaris_cloud_pos;
if ((color_map_base[color_address] & 0x08) || (cloud_y >= 64))
{
set_8_pixels(bitmap, y, x, data, fore_color, back_color);
}
else
{
/* cloud appears in this part of the screen */
int i;
for (i = 0; i < 8; i++)
{
uint8_t color;
if (data & 0x01)
{
color = fore_color;
}
else
{
int bit = 1 << (~x & 0x03);
offs_t cloud_gfx_offs = ((x >> 2) & 0x03) | ((~cloud_y & 0x3f) << 2);
color = (cloud_gfx[cloud_gfx_offs] & bit) ? 7 : back_color;
}
set_pixel(bitmap, y, x, color);
x = x + 1;
data = data >> 1;
}
}
}
clear_extra_columns(bitmap, 6);
return 0;
}
uint32_t _8080bw_state::screen_update_lupin3(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t data = m_main_ram[offs];
uint8_t fore_color = ~m_scattered_colorram[(offs & 0x1f) | ((offs & 0x1f80) >> 2)] & 0x07;
set_8_pixels(bitmap, y, x, data, fore_color, 0);
}
clear_extra_columns(bitmap, 0);
return 0;
}
uint32_t _8080bw_state::screen_update_cosmo(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
offs_t color_address = (offs >> 8 << 5) | (offs & 0x1f);
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_colorram[color_address] & 0x07;
set_8_pixels(bitmap, y, x, data, fore_color, 0);
}
clear_extra_columns(bitmap, 0);
return 0;
}
uint32_t _8080bw_state::screen_update_indianbt(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint8_t *prom = memregion("proms")->base();
uint8_t *color_map_base = m_color_map ? &prom[0x0400] : &prom[0x0000];
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
offs_t color_address = (offs >> 8 << 5) | (offs & 0x1f);
uint8_t data = m_main_ram[offs];
uint8_t fore_color = color_map_base[color_address] & 0x07;
set_8_pixels(bitmap, y, x, data, fore_color, 0);
}
clear_extra_columns(bitmap, 0);
return 0;
}
uint32_t _8080bw_state::screen_update_sflush(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_scattered_colorram[(offs & 0x1f) | ((offs & 0x1f80) >> 2)] & 0x07;
set_8_pixels(bitmap, y, x, data, fore_color, 0);
}
clear_extra_columns(bitmap, 0);
return 0;
}
uint32_t _8080bw_state::screen_update_shuttlei(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t data = m_main_ram[offs];
for (int i = 0; i < 8; i++)
{
if (m_flip_screen)
bitmap.pix32(191-y, 255-(x|i)) = m_palette->pen_color(BIT(data, 7));
else
bitmap.pix32(y, x|i) = m_palette->pen_color(BIT(data, 7));
data <<= 1;
}
}
return 0;
}
uint32_t _8080bw_state::screen_update_spacecom(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < 0x1c00; offs++)
{
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t flipx = m_flip_screen ? 7 : 0;
uint8_t data = m_main_ram[offs+0x400];
for (int i = 0; i < 8; i++)
{
bitmap.pix32(y, x | (i^flipx)) = m_palette->pen_color(BIT(data, 0));
data >>= 1;
}
}
return 0;
}
/*******************************************************/
/* */
/* Model Racing "Orbite" */
/* */
/*******************************************************/
uint32_t orbite_state::screen_update_orbite(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
for (offs_t offs = 0; offs < m_main_ram.bytes(); offs++)
{
uint8_t back_color = 0;
uint8_t y = offs >> 5;
uint8_t x = offs << 3;
uint8_t data = m_main_ram[offs];
uint8_t fore_color = m_scattered_colorram[(offs & 0x1f) | ((offs & 0x1f80) >> 2)] & 0x07;
set_8_pixels(bitmap, y, x, data, fore_color, back_color);
}
clear_extra_columns(bitmap, 0);
return 0;
}