summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/orca40c.cpp
blob: fab592cf092b2a1577751b424f591085cab09194 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                                            

                          


                   













                                                                                                                         

                                                                         




                                                      










































































                                                                                

                                                                                                                                                                          







































































































                                                                                    
                                                                                         


















                                                                               
                                                                                         






















                                                                      
                                                                                                                     










                                                                    
                                                  
 




                                                                                              
 
                                          
                                                                                            




                                                                                               
 
// license:BSD-3-Clause
// copyright-holders:Luca Elia
/***************************************************************************

    orca40c.cpp

    ORCA OVG-40c GFX board used by at least:
    * all games in zodiack.cpp
    * dogfightp in vastar.cpp

***************************************************************************/

#include "emu.h"
#include "video/orca40c.h"

#include "emupal.h"
#include "screen.h"

#define PIXEL_CLOCK         (XTAL(18'432'000)/3)

#define HTOTAL              (396)
#define HBEND               (0)
#define HBSTART             (256)

#define VTOTAL              (256)
#define VBEND               (16)
#define VBSTART             (240)

DEFINE_DEVICE_TYPE(ORCA_OVG_40C, orca_ovg_40c_device, "orca_ovg_40c", "Orca OVG 40c video PCB")

orca_ovg_40c_device::orca_ovg_40c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, ORCA_OVG_40C, tag, owner, clock),
		device_gfx_interface(mconfig, *this, nullptr, "palette"),
		device_video_interface(mconfig, *this),
		m_videoram(*this, "videoram"),
		m_videoram_2(*this,"videoram_2"),
		m_attributeram(*this, "attributeram"),
		m_spriteram(*this, "spriteram"),
		m_bulletsram(*this, "bulletsram"),
		m_percuss_hardware(false),
		m_flip_screen(false)
{
}


/*************************************
 *
 *  Graphics definitions
 *
 *************************************/

static const gfx_layout charlayout =
{
	8,8,    /* 8*8 chars */
	256,    /* 256 characters */
	1,      /* 1 bit per pixel */
	{ 0 } , /* single bitplane */
	{ 0, 1, 2, 3, 4, 5, 6, 7 },
	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
	8*8     /* every char takes 8 consecutive bytes */
};

static const gfx_layout charlayout_2 =
{
	8,8,    /* 8*8 chars */
	256,    /* 256 characters */
	2,      /* 2 bits per pixel */
	{ 0, 512*8*8 },  /* The bitplanes are separate */
	{ 0, 1, 2, 3, 4, 5, 6, 7 },
	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
	8*8     /* every char takes 8 consecutive bytes */
};

static const gfx_layout spritelayout =
{
	16,16,  /* 16*16 sprites */
	64,     /* 64 sprites */
	2,      /* 2 bits per pixel */
	{ 0, 128*32*8 },        /* the two bitplanes are separated */
	{     0,     1,     2,     3,     4,     5,     6,     7,
		8*8+0, 8*8+1, 8*8+2, 8*8+3, 8*8+4, 8*8+5, 8*8+6, 8*8+7 },
	{  0*8,  1*8,  2*8,  3*8,  4*8,  5*8,  6*8,  7*8,
		16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8 },
	32*8    /* every sprite takes 32 consecutive bytes */
};

static const gfx_layout bulletlayout =
{
	/* there is no gfx ROM for this one, it is generated by the hardware */
	7,1,    /* it's just 1 pixel, but we use 7*1 to position it correctly */
	1,  /* just one */
	1,  /* 1 bit per pixel */
	{ 10*8*8 }, /* point to letter "A" */
	{ 3, 7, 7, 7, 7, 7, 7 },    /* I "know" that this bit of the */
	{ 1*8 },                        /* graphics ROMs is 1 */
	0   /* no use */
};

GFXDECODE_MEMBER(orca_ovg_40c_device::gfxinfo)
	GFXDECODE_DEVICE( DEVICE_SELF, 0x0000, charlayout,   8*4    , 8 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x0800, spritelayout, 0      , 8 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x0000, bulletlayout, 8*4+8*2, 1 )
	GFXDECODE_DEVICE( DEVICE_SELF, 0x1000, charlayout_2, 0      , 8 )
GFXDECODE_END


//-------------------------------------------------
//  device_start: Start up the device
//-------------------------------------------------

void orca_ovg_40c_device::device_start()
{
	decode_gfx(gfxinfo);

	m_bg_tilemap = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(orca_ovg_40c_device::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
	m_fg_tilemap = &machine().tilemap().create(*this, tilemap_get_info_delegate(*this, FUNC(orca_ovg_40c_device::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);

	m_fg_tilemap->set_transparent_pen(0);
	m_fg_tilemap->set_scroll_cols(32);

	save_item(NAME(m_flip_screen));
}

WRITE8_MEMBER(orca_ovg_40c_device::videoram_w)
{
	m_videoram[offset] = data;
	m_fg_tilemap->mark_tile_dirty(offset);
}

WRITE8_MEMBER(orca_ovg_40c_device::videoram2_w)
{
	m_videoram_2[offset] = data;
	m_bg_tilemap->mark_tile_dirty(offset);
}

WRITE8_MEMBER(orca_ovg_40c_device::attributes_w)
{
	if ((offset & 1) && m_attributeram[offset] != data)
	{
		int i;

		for (i = offset / 2; i < m_videoram.bytes(); i += 32)
		{
			m_bg_tilemap->mark_tile_dirty(i);
			m_fg_tilemap->mark_tile_dirty(i);
		}
	}

	m_attributeram[offset] = data;
}

WRITE8_MEMBER(orca_ovg_40c_device::flipscreen_w)
{
	m_flip_screen = ~data & 1;

	m_bg_tilemap->set_flip(m_flip_screen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
	m_fg_tilemap->set_flip(m_flip_screen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
}

void orca_ovg_40c_device::palette_init(palette_device &palette)
{
	const uint8_t *color_prom = memregion("proms")->base();

	/* create a lookup table for the palette */
	for (int i = 0; i < 0x30; i++)
	{
		/* red component */
		int bit0 = (color_prom[i] >> 0) & 0x01;
		int bit1 = (color_prom[i] >> 1) & 0x01;
		int bit2 = (color_prom[i] >> 2) & 0x01;
		int r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;

		/* green component */
		bit0 = (color_prom[i] >> 3) & 0x01;
		bit1 = (color_prom[i] >> 4) & 0x01;
		bit2 = (color_prom[i] >> 5) & 0x01;
		int g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;

		/* blue component */
		bit0 = 0;
		bit1 = (color_prom[i] >> 6) & 0x01;
		bit2 = (color_prom[i] >> 7) & 0x01;
		int b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;

		palette.set_indirect_color(i, rgb_t(r, g, b));
	}

	/* white for bullets */
	palette.set_indirect_color(0x30, rgb_t::white());

	for (int i = 0; i < 0x20; i++)
		palette.set_pen_indirect(i, (i & 3) ? i : 0);

	for (int i = 0; i < 0x10; i += 2)
	{
		palette.set_pen_indirect(0x20 + i, 32 + (i / 2));
		palette.set_pen_indirect(0x21 + i, 40 + (i / 2));
	}

	/* bullet */
	palette.set_pen_indirect(0x30, 0);
	palette.set_pen_indirect(0x31, 0x30);
}

TILE_GET_INFO_MEMBER(orca_ovg_40c_device::get_bg_tile_info)
{
	int code = m_videoram_2[tile_index];
	int color = (m_attributeram[(tile_index & 0x1f) << 1 | 1] >> 4) & 0x07;

	SET_TILE_INFO_MEMBER(0, code, color, 0);
}

TILE_GET_INFO_MEMBER(orca_ovg_40c_device::get_fg_tile_info)
{
	int code = m_videoram[tile_index];
	int color = (m_attributeram[(tile_index & 0x1f) << 1 | 1] >> 0) & 0x07;

	SET_TILE_INFO_MEMBER(3, code, color, 0);
}

void orca_ovg_40c_device::draw_bullets( bitmap_rgb32 &bitmap, const rectangle &cliprect )
{
	for (int offs = 0; offs < m_bulletsram.bytes(); offs += 4)
	{
		int sx = m_bulletsram[offs + 3] + 7;
		int sy = m_bulletsram[offs + 1];

		if (!(m_flip_screen && m_percuss_hardware))
			sy = 255 - sy;

		gfx(2)->transpen(
			bitmap,
			cliprect,
			0,  /* this is just a dot, generated by the hardware */
			0,
			0, 0,
			sx, sy, 0);
	}
}

void orca_ovg_40c_device::draw_sprites( bitmap_rgb32 &bitmap, const rectangle &cliprect )
{
	for (int offs = m_spriteram.bytes() - 4; offs >= 0; offs -= 4)
	{
		int sx = 240 - m_spriteram[offs + 3];
		int sy = 240 - m_spriteram[offs];
		int flipx = !(m_spriteram[offs + 1] & 0x40);
		int flipy = m_spriteram[offs + 1] & 0x80;
		int spritecode = m_spriteram[offs + 1] & 0x3f;

		if (m_flip_screen && m_percuss_hardware)
		{
			sy = 240 - sy;
			flipy = !flipy;
		}

		gfx(1)->transpen(bitmap,cliprect,
			spritecode,
			m_spriteram[offs + 2] & 0x07,
			flipx, flipy,
			sx, sy, 0);
	}
}

uint32_t orca_ovg_40c_device::screen_update( screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect )
{
	for (int i = 0; i < 32; i++)
		m_fg_tilemap->set_scrolly(i, m_attributeram[i * 2]);

	m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
	m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
	draw_bullets(bitmap, cliprect);
	draw_sprites(bitmap, cliprect);
	return 0;
}

void orca_ovg_40c_device::device_config_complete()
{
	if (!has_screen())
		return;

	if (!screen().refresh_attoseconds())
		screen().set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART);

	if (!screen().has_screen_update())
		screen().set_screen_update(*this, FUNC(orca_ovg_40c_device::screen_update));
}

void orca_ovg_40c_device::device_add_mconfig(machine_config &config)
{
	PALETTE(config, "palette", FUNC(orca_ovg_40c_device::palette_init), 4*8+2*8+2*1, 48+1);
}