#include "emu.h"
#include "includes/playmark.h"
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
static TILE_GET_INFO( bigtwin_get_tx_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
UINT16 code = state->m_videoram1[2 * tile_index];
UINT16 color = state->m_videoram1[2 * tile_index + 1];
SET_TILE_INFO(
2,
code,
color,
0);
}
static TILE_GET_INFO( bigtwin_get_fg_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
UINT16 code = state->m_videoram2[2 * tile_index];
UINT16 color = state->m_videoram2[2 * tile_index + 1];
SET_TILE_INFO(
1,
code,
color,
0);
}
static TILE_GET_INFO( wbeachvl_get_tx_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
UINT16 code = state->m_videoram1[2 * tile_index];
UINT16 color = state->m_videoram1[2 * tile_index + 1];
SET_TILE_INFO(
2,
code,
color / 4,
0);
}
static TILE_GET_INFO( wbeachvl_get_fg_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
UINT16 code = state->m_videoram2[2 * tile_index];
UINT16 color = state->m_videoram2[2 * tile_index + 1];
SET_TILE_INFO(
1,
code & 0x7fff,
color / 4 + 8,
(code & 0x8000) ? TILE_FLIPX : 0);
}
static TILE_GET_INFO( wbeachvl_get_bg_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
UINT16 code = state->m_videoram3[2 * tile_index];
UINT16 color = state->m_videoram3[2 * tile_index + 1];
SET_TILE_INFO(
1,
code & 0x7fff,
color / 4,
(code & 0x8000) ? TILE_FLIPX : 0);
}
static TILE_GET_INFO( hrdtimes_get_tx_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
int code = state->m_videoram1[tile_index] & 0x03ff;
int colr = state->m_videoram1[tile_index] & 0xe000;
SET_TILE_INFO(2,code + state->m_txt_tile_offset, colr >> 13, 0);
}
static TILE_GET_INFO( bigtwinb_get_tx_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
int code = state->m_videoram1[tile_index] & 0x0fff;
int colr = state->m_videoram1[tile_index] & 0xf000;
SET_TILE_INFO(2,code + state->m_txt_tile_offset, colr >> 12, 0);
}
static TILE_GET_INFO( hrdtimes_get_fg_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
int code = state->m_videoram2[tile_index] & 0x1fff;
int colr = state->m_videoram2[tile_index] & 0xe000;
SET_TILE_INFO(1,code + 0x2000,(colr >> 13) + 8,0);
}
static TILE_GET_INFO( hrdtimes_get_bg_tile_info )
{
playmark_state *state = machine.driver_data<playmark_state>();
int code = state->m_videoram3[tile_index] & 0x1fff;
int colr = state->m_videoram3[tile_index] & 0xe000;
SET_TILE_INFO(1, code, colr >> 13, 0);
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
VIDEO_START( bigtwin )
{
playmark_state *state = machine.driver_data<playmark_state>();
state->m_tx_tilemap = tilemap_create(machine, bigtwin_get_tx_tile_info, tilemap_scan_rows, 8, 8, 64, 32);
state->m_fg_tilemap = tilemap_create(machine, bigtwin_get_fg_tile_info, tilemap_scan_rows, 16, 16, 32, 32);
tilemap_set_transparent_pen(state->m_tx_tilemap, 0);
state->m_xoffset = 0;
state->m_yoffset = 0;
state->m_txt_tile_offset = 0;
state->m_pri_masks[0] = 0;
state->m_pri_masks[1] = 0;
state->m_pri_masks[2] = 0;
}
VIDEO_START( bigtwinb )
{
playmark_state *state = machine.driver_data<playmark_state>();
state->m_tx_tilemap = tilemap_create(machine, bigtwinb_get_tx_tile_info,tilemap_scan_rows, 8, 8, 64, 64);
state->m_fg_tilemap = tilemap_create(machine, hrdtimes_get_fg_tile_info,tilemap_scan_rows, 16, 16, 32, 32);
state->m_bg_tilemap = tilemap_create(machine, hrdtimes_get_bg_tile_info,tilemap_scan_rows, 16, 16, 32, 32);
tilemap_set_transparent_pen(state->m_tx_tilemap, 0);
tilemap_set_transparent_pen(state->m_fg_tilemap, 0);
tilemap_set_scrolldx(state->m_bg_tilemap, -4, -4);
state->m_xoffset = 1;
state->m_yoffset = 0;
state->m_txt_tile_offset = 0x8000;
state->m_pri_masks[0] = 0;
state->m_pri_masks[1] = 0;
state->m_pri_masks[2] = 0;
}
VIDEO_START( wbeachvl )
{
playmark_state *state = machine.driver_data<playmark_state>();
state->m_tx_tilemap = tilemap_create(machine, wbeachvl_get_tx_tile_info, tilemap_scan_rows, 8, 8, 64, 32);
state->m_fg_tilemap = tilemap_create(machine, wbeachvl_get_fg_tile_info, tilemap_scan_rows, 16, 16, 64, 32);
state->m_bg_tilemap = tilemap_create(machine, wbeachvl_get_bg_tile_info, tilemap_scan_rows, 16, 16, 64, 32);
tilemap_set_transparent_pen(state->m_tx_tilemap, 0);
tilemap_set_transparent_pen(state->m_fg_tilemap, 0);
state->m_xoffset = 0;
state->m_yoffset = 0;
state->m_txt_tile_offset = 0;
state->m_pri_masks[0] = 0xfff0;
state->m_pri_masks[1] = 0xfffc;
state->m_pri_masks[2] = 0;
}
VIDEO_START( excelsr )
{
playmark_state *state = machine.driver_data<playmark_state>();
state->m_tx_tilemap = tilemap_create(machine, bigtwin_get_tx_tile_info, tilemap_scan_rows, 16, 16, 32, 32);
state->m_fg_tilemap = tilemap_create(machine, bigtwin_get_fg_tile_info, tilemap_scan_rows, 16, 16, 32, 32);
tilemap_set_transparent_pen(state->m_tx_tilemap, 0);
state->m_xoffset = 0;
state->m_yoffset = 0;
state->m_txt_tile_offset = 0;
state->m_pri_masks[0] = 0;
state->m_pri_masks[1] = 0xfffc;
state->m_pri_masks[2] = 0xfff0;
}
VIDEO_START( hotmind )
{
playmark_state *state = machine.driver_data<playmark_state>();
state->m_tx_tilemap = tilemap_create(machine, hrdtimes_get_tx_tile_info, tilemap_scan_rows, 8, 8, 64, 64);
state->m_fg_tilemap = tilemap_create(machine, hrdtimes_get_fg_tile_info, tilemap_scan_rows, 16, 16, 32, 32);
state->m_bg_tilemap = tilemap_create(machine, hrdtimes_get_bg_tile_info, tilemap_scan_rows, 16, 16, 32, 32);
tilemap_set_transparent_pen(state->m_tx_tilemap, 0);
tilemap_set_transparent_pen(state->m_fg_tilemap, 0);
tilemap_set_scrolldx(state->m_tx_tilemap, -14, -14);
tilemap_set_scrolldx(state->m_fg_tilemap, -14, -14);
tilemap_set_scrolldx(state->m_bg_tilemap, -14, -14);
state->m_xoffset = -9;
state->m_yoffset = -8;
state->m_txt_tile_offset = 0x9000;
state->m_pri_masks[0] = 0xfff0;
state->m_pri_masks[1] = 0xfffc;
state->m_pri_masks[2] = 0;
}
VIDEO_START( hrdtimes )
{
playmark_state *state = machine.driver_data<playmark_state>();
state->m_tx_tilemap = tilemap_create(machine, hrdtimes_get_tx_tile_info,tilemap_scan_rows, 8, 8, 64, 64);
state->m_fg_tilemap = tilemap_create(machine, hrdtimes_get_fg_tile_info,tilemap_scan_rows, 16, 16, 32, 32);
state->m_bg_tilemap = tilemap_create(machine, hrdtimes_get_bg_tile_info,tilemap_scan_rows, 16, 16, 32, 32);
tilemap_set_transparent_pen(state->m_tx_tilemap, 0);
tilemap_set_transparent_pen(state->m_fg_tilemap, 0);
tilemap_set_scrolldx(state->m_tx_tilemap, -14, -14);
tilemap_set_scrolldx(state->m_fg_tilemap, -10, -10);
tilemap_set_scrolldx(state->m_bg_tilemap, -12, -12);
state->m_xoffset = -8;
state->m_yoffset = -8;
state->m_txt_tile_offset = 0xfc00;
state->m_pri_masks[0] = 0xfff0;
state->m_pri_masks[1] = 0xfffc;
state->m_pri_masks[2] = 0;
}
/***************************************************************************
Memory handlers
***************************************************************************/
WRITE16_HANDLER( wbeachvl_txvideoram_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
COMBINE_DATA(&state->m_videoram1[offset]);
tilemap_mark_tile_dirty(state->m_tx_tilemap, offset / 2);
}
WRITE16_HANDLER( wbeachvl_fgvideoram_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
COMBINE_DATA(&state->m_videoram2[offset]);
tilemap_mark_tile_dirty(state->m_fg_tilemap, offset / 2);
}
WRITE16_HANDLER( wbeachvl_bgvideoram_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
COMBINE_DATA(&state->m_videoram3[offset]);
tilemap_mark_tile_dirty(state->m_bg_tilemap, offset / 2);
}
WRITE16_HANDLER( hrdtimes_txvideoram_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
COMBINE_DATA(&state->m_videoram1[offset]);
tilemap_mark_tile_dirty(state->m_tx_tilemap, offset);
}
WRITE16_HANDLER( hrdtimes_fgvideoram_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
COMBINE_DATA(&state->m_videoram2[offset]);
tilemap_mark_tile_dirty(state->m_fg_tilemap, offset);
}
WRITE16_HANDLER( hrdtimes_bgvideoram_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
COMBINE_DATA(&state->m_videoram3[offset]);
tilemap_mark_tile_dirty(state->m_bg_tilemap, offset);
}
WRITE16_HANDLER( bigtwin_paletteram_w )
{
int r, g, b, val;
COMBINE_DATA(&space->machine().generic.paletteram.u16[offset]);
val = space->machine().generic.paletteram.u16[offset];
r = (val >> 11) & 0x1e;
g = (val >> 7) & 0x1e;
b = (val >> 3) & 0x1e;
r |= ((val & 0x08) >> 3);
g |= ((val & 0x04) >> 2);
b |= ((val & 0x02) >> 1);
palette_set_color_rgb(space->machine(), offset, pal5bit(r), pal5bit(g), pal5bit(b));
}
WRITE16_HANDLER( bigtwin_scroll_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
data = COMBINE_DATA(&state->m_scroll[offset]);
switch (offset)
{
case 0: tilemap_set_scrollx(state->m_tx_tilemap, 0, data + 2); break;
case 1: tilemap_set_scrolly(state->m_tx_tilemap, 0, data); break;
case 2: state->m_bgscrollx = -(data + 4); break;
case 3: state->m_bgscrolly = (-data) & 0x1ff;
state->m_bg_enable = data & 0x0200;
state->m_bg_full_size = data & 0x0400;
break;
case 4: tilemap_set_scrollx(state->m_fg_tilemap, 0, data + 6); break;
case 5: tilemap_set_scrolly(state->m_fg_tilemap, 0, data); break;
}
}
WRITE16_HANDLER( wbeachvl_scroll_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
data = COMBINE_DATA(&state->m_scroll[offset]);
switch (offset)
{
case 0: tilemap_set_scrollx(state->m_tx_tilemap, 0, data + 2); break;
case 1: tilemap_set_scrolly(state->m_tx_tilemap, 0, data); break;
case 2: state->m_fgscrollx = data + 4;break;
case 3: tilemap_set_scrolly(state->m_fg_tilemap, 0, data & 0x3ff);
state->m_fg_rowscroll_enable = data & 0x0800;
break;
case 4: tilemap_set_scrollx(state->m_bg_tilemap, 0, data + 6); break;
case 5: tilemap_set_scrolly(state->m_bg_tilemap, 0, data); break;
}
}
WRITE16_HANDLER( excelsr_scroll_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
data = COMBINE_DATA(&state->m_scroll[offset]);
switch (offset)
{
case 0: tilemap_set_scrollx(state->m_tx_tilemap, 0, data + 2); break;
case 1: tilemap_set_scrolly(state->m_tx_tilemap, 0, data); break;
case 2: state->m_bgscrollx = -data; break;
case 3: state->m_bgscrolly = (-data + 2)& 0x1ff;
state->m_bg_enable = data & 0x0200;
state->m_bg_full_size = data & 0x0400;
break;
case 4: tilemap_set_scrollx(state->m_fg_tilemap, 0, data + 6); break;
case 5: tilemap_set_scrolly(state->m_fg_tilemap, 0, data); break;
}
}
WRITE16_HANDLER( hrdtimes_scroll_w )
{
playmark_state *state = space->machine().driver_data<playmark_state>();
data = COMBINE_DATA(&state->m_scroll[offset]);
switch (offset)
{
case 0: tilemap_set_scrollx(state->m_tx_tilemap, 0, data); break;
case 1: tilemap_set_scrolly(state->m_tx_tilemap, 0, data); break;
case 2: tilemap_set_scrollx(state->m_fg_tilemap, 0, data); break;
case 3: tilemap_set_scrolly(state->m_fg_tilemap, 0, data); break;
case 4: tilemap_set_scrollx(state->m_bg_tilemap, 0, data); break;
case 5: tilemap_set_scrolly(state->m_bg_tilemap, 0, data); break;
}
}
/***************************************************************************
Display refresh
***************************************************************************/
static void draw_sprites( running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, int codeshift )
{
playmark_state *state = machine.driver_data<playmark_state>();
int offs, start_offset = state->m_spriteram_size / 2 - 4;
int height = machine.gfx[0]->height;
int colordiv = machine.gfx[0]->color_granularity / 16;
UINT16 *spriteram = state->m_spriteram;
// find the "end of list" to draw the sprites in reverse order
for (offs = 4; offs < state->m_spriteram_size / 2; offs += 4)
{
if (spriteram[offs + 3 - 4] == 0x2000) /* end of list marker */
{
start_offset = offs - 4;
break;
}
}
for (offs = start_offset; offs >= 4; offs -= 4)
{
int sx, sy, code, color, flipx, pri;
sy = spriteram[offs + 3 - 4]; /* -4? what the... ??? */
flipx = sy & 0x4000;
sx = (spriteram[offs + 1] & 0x01ff) - 16 - 7;
sy = (256 - 8 - height - sy) & 0xff;
code = spriteram[offs + 2] >> codeshift;
color = ((spriteram[offs + 1] & 0x3e00) >> 9) / colordiv;
pri = (spriteram[offs + 1] & 0x8000) >> 15;
if(!pri && (color & 0x0c) == 0x0c)
pri = 2;
pdrawgfx_transpen(bitmap,cliprect,machine.gfx[0],
code,
color,
flipx,0,
sx + state->m_xoffset,sy + state->m_yoffset,
machine.priority_bitmap,state->m_pri_masks[pri],0);
}
}
static void bigtwinb_draw_sprites( running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, int codeshift )
{
playmark_state *state = machine.driver_data<playmark_state>();
int offs, start_offset = state->m_spriteram_size / 2 - 4;
int height = machine.gfx[0]->height;
UINT16 *spriteram = state->m_spriteram;
// find the "end of list" to draw the sprites in reverse order
for (offs = 4; offs < state->m_spriteram_size / 2; offs += 4)
{
if (spriteram[offs + 3 - 4] == 0x2000) /* end of list marker */
{
start_offset = offs - 4;
break;
}
}
for (offs = start_offset; offs >= 4; offs -= 4)
{
int sx, sy, code, color, flipx;
sy = spriteram[offs + 3 - 4]; /* -4? what the... ??? */
flipx = sy & 0x4000;
sx = (spriteram[offs + 1] & 0x01ff) - 16 - 7;
sy = (256 - 8 - height - sy) & 0xff;
code = spriteram[offs + 2] >> codeshift;
color = ((spriteram[offs + 1] & 0xf000) >> 12);
drawgfx_transpen(bitmap,cliprect,machine.gfx[0],
code,
color,
flipx,0,
sx + state->m_xoffset,sy + state->m_yoffset, 0);
}
}
static void draw_bitmap( running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect )
{
playmark_state *state = machine.driver_data<playmark_state>();
int x, y, count;
int color;
UINT8 *pri;
count = 0;
for (y = 0; y < 512; y++)
{
for (x = 0; x < 512; x++)
{
color = state->m_bgvideoram[count] & 0xff;
if (color)
{
if (state->m_bg_full_size)
{
*BITMAP_ADDR16(bitmap, (y + state->m_bgscrolly) & 0x1ff, (x + state->m_bgscrollx) & 0x1ff) = 0x100 + color;
pri = BITMAP_ADDR8(machine.priority_bitmap, (y + state->m_bgscrolly) & 0x1ff, 0);
pri[(x + state->m_bgscrollx) & 0x1ff] |= 2;
}
else
{
/* 50% size */
if(!(x % 2) && !(y % 2))
{
*BITMAP_ADDR16(bitmap, (y / 2 + state->m_bgscrolly) & 0x1ff, (x / 2 + state->m_bgscrollx) & 0x1ff) = 0x100 + color;
pri = BITMAP_ADDR8(machine.priority_bitmap, (y / 2 + state->m_bgscrolly) & 0x1ff, 0);
pri[(x / 2 + state->m_bgscrollx) & 0x1ff] |= 2;
}
}
}
count++;
}
}
}
SCREEN_UPDATE( bigtwin )
{
playmark_state *state = screen->machine().driver_data<playmark_state>();
bitmap_fill(screen->machine().priority_bitmap, cliprect, 0);
tilemap_draw(bitmap, cliprect, state->m_fg_tilemap, 0, 0);
if (state->m_bg_enable)
draw_bitmap(screen->machine(), bitmap, cliprect);
draw_sprites(screen->machine(), bitmap, cliprect, 4);
tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0);
return 0;
}
SCREEN_UPDATE( bigtwinb )
{
playmark_state *state = screen->machine().driver_data<playmark_state>();
// video enabled
if (state->m_scroll[6] & 1)
{
tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 0);
tilemap_draw(bitmap, cliprect, state->m_fg_tilemap, 0, 0);
bigtwinb_draw_sprites(screen->machine(), bitmap, cliprect, 4);
tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0);
}
else
bitmap_fill(bitmap, cliprect, get_black_pen(screen->machine()));
return 0;
}
SCREEN_UPDATE( excelsr )
{
playmark_state *state = screen->machine().driver_data<playmark_state>();
bitmap_fill(screen->machine().priority_bitmap, cliprect, 0);
tilemap_draw(bitmap, cliprect, state->m_fg_tilemap, 0, 1);
if (state->m_bg_enable)
draw_bitmap(screen->machine(), bitmap, cliprect);
tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 4);
draw_sprites(screen->machine(), bitmap, cliprect, 2);
return 0;
}
SCREEN_UPDATE( wbeachvl )
{
playmark_state *state = screen->machine().driver_data<playmark_state>();
if (state->m_fg_rowscroll_enable)
{
int i;
tilemap_set_scroll_rows(state->m_fg_tilemap, 512);
for (i = 0; i < 256; i++)
tilemap_set_scrollx(state->m_fg_tilemap, i + 1, state->m_rowscroll[8 * i]);
}
else
{
tilemap_set_scroll_rows(state->m_fg_tilemap, 1);
tilemap_set_scrollx(state->m_fg_tilemap, 0, state->m_fgscrollx);
}
bitmap_fill(screen->machine().priority_bitmap, cliprect, 0);
tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 1);
tilemap_draw(bitmap, cliprect, state->m_fg_tilemap, 0, 2);
draw_sprites(screen->machine(), bitmap, cliprect, 0);
tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0);
return 0;
}
SCREEN_UPDATE( hrdtimes )
{
playmark_state *state = screen->machine().driver_data<playmark_state>();
bitmap_fill(screen->machine().priority_bitmap, cliprect, 0);
// video enabled
if (state->m_scroll[6] & 1)
{
tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 1);
tilemap_draw(bitmap, cliprect, state->m_fg_tilemap, 0, 2);
draw_sprites(screen->machine(), bitmap, cliprect, 2);
tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0);
}
else
bitmap_fill(bitmap, cliprect, get_black_pen(screen->machine()));
return 0;
}