// license:BSD-3-Clause
// copyright-holders:Luca Elia
/***************************************************************************
-= Blomby Car =-
driver by Luca Elia (l.elia@tin.it)
Note: if MAME_DEBUG is defined, pressing Z with:
Q shows the background
W shows the foreground
A shows the sprites
Keys can be used together!
[ 2 Scrolling Layers ]
The Tilemaps are 64 x 32 tiles in size (1024 x 512).
Tiles are 16 x 16 x 4, with 32 color codes and 2 priority
leves (wrt sprites). Each tile needs 4 bytes.
[ 1024? Sprites ]
They use the same graphics the tilemaps use (16 x 16 x 4 tiles)
with 16 color codes and 2 levels of priority
***************************************************************************/
#include "emu.h"
#include "includes/blmbycar.h"
#include "screen.h"
/***************************************************************************
Tilemaps
Offset: Bits: Value:
0.w Code
2.w fedc ba98 ---- ----
---- ---- 7--- ---- Flip Y
---- ---- -6-- ---- Flip X
---- ---- --5- ---- Priority (0 = Low)
---- ---- ---4 3210 Color
***************************************************************************/
#define DIM_NX (0x40)
#define DIM_NY (0x20)
TILE_GET_INFO_MEMBER(blmbycar_state::get_tile_info_0)
{
uint16_t code = m_vram_0[tile_index * 2 + 0];
uint16_t attr = m_vram_0[tile_index * 2 + 1];
SET_TILE_INFO_MEMBER(0,
code,
attr & 0x1f,
TILE_FLIPYX((attr >> 6) & 3));
tileinfo.category = (attr >> 5) & 1;
}
TILE_GET_INFO_MEMBER(blmbycar_state::get_tile_info_1)
{
uint16_t code = m_vram_1[tile_index * 2 + 0];
uint16_t attr = m_vram_1[tile_index * 2 + 1];
SET_TILE_INFO_MEMBER(0,
code,
attr & 0x1f,
TILE_FLIPYX((attr >> 6) & 3));
tileinfo.category = (attr >> 5) & 1;
}
WRITE16_MEMBER(blmbycar_state::vram_0_w)
{
COMBINE_DATA(&m_vram_0[offset]);
m_tilemap_0->mark_tile_dirty(offset / 2);
}
WRITE16_MEMBER(blmbycar_state::vram_1_w)
{
COMBINE_DATA(&m_vram_1[offset]);
m_tilemap_1->mark_tile_dirty(offset / 2);
}
/***************************************************************************
Video Init
***************************************************************************/
void blmbycar_state::video_start()
{
m_tilemap_0 = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(blmbycar_state::get_tile_info_0),this), TILEMAP_SCAN_ROWS, 16, 16, DIM_NX, DIM_NY );
m_tilemap_1 = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(blmbycar_state::get_tile_info_1),this), TILEMAP_SCAN_ROWS, 16, 16, DIM_NX, DIM_NY );
m_tilemap_0->set_scroll_rows(1);
m_tilemap_0->set_scroll_cols(1);
m_tilemap_1->set_scroll_rows(1);
m_tilemap_1->set_scroll_cols(1);
m_tilemap_1->set_transparent_pen(0);
}
/***************************************************************************
Sprites Drawing
Offset: Bits: Value:
0.w f--- ---- ---- ---- End Of Sprites
-edc ba9- ---- ----
---- ---8 7654 3210 Y (Signed)
2.w Code
4.w f--- ---- ---- ---- Flip Y
-e-- ---- ---- ---- Flip X
--dc ba98 7654 ----
---- ---- ---- 3210 Color (Bit 3 = Priority)
6.w f--- ---- ---- ---- ? Is this ever used ?
-e-- ---- ---- ---- ? 1 = Don't Draw ?
--dc ba9- ---- ----
---- ---8 7654 3210 X (Signed)
***************************************************************************/
void blmbycar_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
{
uint16_t *source, *finish;
source = m_spriteram + 0x6 / 2; // !
finish = m_spriteram + m_spriteram.bytes() / 2 - 8 / 2;
/* Find "the end of sprites" marker */
for ( ; source < finish; source += 8 / 2 )
if (source[0] & 0x8000) break;
/* Draw sprites in reverse order for pdrawfgfx */
source -= 8 / 2;
finish = m_spriteram;
for ( ; source >= finish; source -= 8 / 2 )
{
int y = source[0];
int code = source[1];
int attr = source[2];
int x = source[3];
int flipx = attr & 0x4000;
int flipy = attr & 0x8000;
int pri = (~attr >> 3) & 0x1; // Priority (1 = Low)
int pri_mask = ~((1 << (pri+1)) - 1); // Above the first "pri" levels
if (x & 0x4000) continue; // ? To get rid of the "shadow" blocks
x = (x & 0x1ff) - 0x10;
y = 0xf0 - ((y & 0xff) - (y & 0x100));
m_gfxdecode->gfx(0)->prio_transpen(bitmap,cliprect,
code,
0x20 + (attr & 0xf),
flipx, flipy,
x, y,
screen.priority(),
pri_mask,0);
}
}
/***************************************************************************
Screen Drawing
***************************************************************************/
uint32_t blmbycar_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int i, layers_ctrl = -1;
m_tilemap_0->set_scrolly(0, m_scroll_0[0]);
m_tilemap_0->set_scrollx(0, m_scroll_0[1]);
m_tilemap_1->set_scrolly(0, m_scroll_1[0] + 1);
m_tilemap_1->set_scrollx(0, m_scroll_1[1] + 5);
#ifdef MAME_DEBUG
if (machine().input().code_pressed(KEYCODE_Z))
{
int msk = 0;
if (machine().input().code_pressed(KEYCODE_Q)) msk |= 1;
if (machine().input().code_pressed(KEYCODE_W)) msk |= 2;
// if (machine().input().code_pressed(KEYCODE_E)) msk |= 4;
if (machine().input().code_pressed(KEYCODE_A)) msk |= 8;
if (msk != 0) layers_ctrl &= msk;
}
#endif
screen.priority().fill(0, cliprect);
if (layers_ctrl & 1)
for (i = 0; i <= 1; i++)
m_tilemap_0->draw(screen, bitmap, cliprect, i, i);
else
bitmap.fill(0, cliprect);
if (layers_ctrl & 2)
for (i = 0; i <= 1; i++)
m_tilemap_1->draw(screen, bitmap, cliprect, i, i);
if (layers_ctrl & 8)
draw_sprites(screen, bitmap, cliprect);
return 0;
}