#include "emu.h"
#include "includes/sf.h"
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
static TILE_GET_INFO( get_bg_tile_info )
{
UINT8 *base = machine.region("gfx5")->base() + 2 * tile_index;
int attr = base[0x10000];
int color = base[0];
int code = (base[0x10000 + 1] << 8) | base[1];
SET_TILE_INFO(
0,
code,
color,
TILE_FLIPYX(attr & 3));
}
static TILE_GET_INFO( get_fg_tile_info )
{
UINT8 *base = machine.region("gfx5")->base() + 0x20000 + 2 * tile_index;
int attr = base[0x10000];
int color = base[0];
int code = (base[0x10000 + 1] << 8) | base[1];
SET_TILE_INFO(
1,
code,
color,
TILE_FLIPYX(attr & 3));
}
static TILE_GET_INFO( get_tx_tile_info )
{
sf_state *state = machine.driver_data<sf_state>();
int code = state->m_videoram[tile_index];
SET_TILE_INFO(
3,
code & 0x3ff,
code>>12,
TILE_FLIPYX((code & 0xc00)>>10));
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
VIDEO_START( sf )
{
sf_state *state = machine.driver_data<sf_state>();
state->m_bg_tilemap = tilemap_create(machine, get_bg_tile_info, tilemap_scan_cols, 16, 16, 2048, 16);
state->m_fg_tilemap = tilemap_create(machine, get_fg_tile_info, tilemap_scan_cols, 16, 16, 2048, 16);
state->m_tx_tilemap = tilemap_create(machine, get_tx_tile_info, tilemap_scan_rows, 8, 8, 64, 32);
tilemap_set_transparent_pen(state->m_fg_tilemap, 15);
tilemap_set_transparent_pen(state->m_tx_tilemap, 3);
}
/***************************************************************************
Memory handlers
***************************************************************************/
WRITE16_HANDLER( sf_videoram_w )
{
sf_state *state = space->machine().driver_data<sf_state>();
COMBINE_DATA(&state->m_videoram[offset]);
tilemap_mark_tile_dirty(state->m_tx_tilemap, offset);
}
WRITE16_HANDLER( sf_bg_scroll_w )
{
sf_state *state = space->machine().driver_data<sf_state>();
COMBINE_DATA(&state->m_bgscroll);
tilemap_set_scrollx(state->m_bg_tilemap, 0, state->m_bgscroll);
}
WRITE16_HANDLER( sf_fg_scroll_w )
{
sf_state *state = space->machine().driver_data<sf_state>();
COMBINE_DATA(&state->m_fgscroll);
tilemap_set_scrollx(state->m_fg_tilemap, 0, state->m_fgscroll);
}
WRITE16_HANDLER( sf_gfxctrl_w )
{
/* b0 = reset, or maybe "set anyway" */
/* b1 = pulsed when control6.b6==0 until it's 1 */
/* b2 = active when dip 8 (flip) on */
/* b3 = active character plane */
/* b4 = unused */
/* b5 = active background plane */
/* b6 = active middle plane */
/* b7 = active sprites */
sf_state *state = space->machine().driver_data<sf_state>();
if (ACCESSING_BITS_0_7)
{
state->m_sf_active = data & 0xff;
flip_screen_set(space->machine(), data & 0x04);
tilemap_set_enable(state->m_tx_tilemap, data & 0x08);
tilemap_set_enable(state->m_bg_tilemap, data & 0x20);
tilemap_set_enable(state->m_fg_tilemap, data & 0x40);
}
}
/***************************************************************************
Display refresh
***************************************************************************/
INLINE int sf_invert( int nb )
{
static const int delta[4] = {0x00, 0x18, 0x18, 0x00};
return nb ^ delta[(nb >> 3) & 3];
}
static void draw_sprites( running_machine &machine, bitmap_t *bitmap,const rectangle *cliprect )
{
sf_state *state = machine.driver_data<sf_state>();
int offs;
for (offs = 0x1000 - 0x20; offs >= 0; offs -= 0x20)
{
int c = state->m_objectram[offs];
int attr = state->m_objectram[offs + 1];
int sy = state->m_objectram[offs + 2];
int sx = state->m_objectram[offs + 3];
int color = attr & 0x000f;
int flipx = attr & 0x0100;
int flipy = attr & 0x0200;
if (attr & 0x400) /* large sprite */
{
int c1, c2, c3, c4, t;
if (flip_screen_get(machine))
{
sx = 480 - sx;
sy = 224 - sy;
flipx = !flipx;
flipy = !flipy;
}
c1 = c;
c2 = c + 1;
c3 = c + 16;
c4 = c + 17;
if (flipx)
{
t = c1; c1 = c2; c2 = t;
t = c3; c3 = c4; c4 = t;
}
if (flipy)
{
t = c1; c1 = c3; c3 = t;
t = c2; c2 = c4; c4 = t;
}
drawgfx_transpen(bitmap,
cliprect, machine.gfx[2],
sf_invert(c1),
color,
flipx,flipy,
sx,sy, 15);
drawgfx_transpen(bitmap,
cliprect, machine.gfx[2],
sf_invert(c2),
color,
flipx,flipy,
sx+16,sy, 15);
drawgfx_transpen(bitmap,
cliprect, machine.gfx[2],
sf_invert(c3),
color,
flipx,flipy,
sx,sy+16, 15);
drawgfx_transpen(bitmap,
cliprect, machine.gfx[2],
sf_invert(c4),
color,
flipx,flipy,
sx+16,sy+16, 15);
}
else
{
if (flip_screen_get(machine))
{
sx = 496 - sx;
sy = 240 - sy;
flipx = !flipx;
flipy = !flipy;
}
drawgfx_transpen(bitmap,
cliprect, machine.gfx[2],
sf_invert(c),
color,
flipx,flipy,
sx,sy, 15);
}
}
}
SCREEN_UPDATE( sf )
{
sf_state *state = screen->machine().driver_data<sf_state>();
if (state->m_sf_active & 0x20)
tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 0);
else
bitmap_fill(bitmap, cliprect, 0);
tilemap_draw(bitmap, cliprect, state->m_fg_tilemap, 0, 0);
if (state->m_sf_active & 0x80)
draw_sprites(screen->machine(), bitmap, cliprect);
tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0);
return 0;
}