/***************************************************************************
video.c
Functions to emulate the video hardware of the machine.
***************************************************************************/
#include "driver.h"
UINT8 *cop01_bgvideoram,*cop01_fgvideoram;
static UINT8 mightguy_vreg[4];
static tilemap *bg_tilemap,*fg_tilemap;
PALETTE_INIT( cop01 )
{
int i;
#define TOTAL_COLORS(gfxn) (machine->gfx[gfxn]->total_colors * machine->gfx[gfxn]->color_granularity)
#define COLOR(gfxn,offs) (colortable[machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
for (i = 0;i < machine->drv->total_colors;i++)
{
int bit0,bit1,bit2,bit3,r,g,b;
bit0 = (color_prom[0] >> 0) & 0x01;
bit1 = (color_prom[0] >> 1) & 0x01;
bit2 = (color_prom[0] >> 2) & 0x01;
bit3 = (color_prom[0] >> 3) & 0x01;
r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
bit0 = (color_prom[machine->drv->total_colors] >> 0) & 0x01;
bit1 = (color_prom[machine->drv->total_colors] >> 1) & 0x01;
bit2 = (color_prom[machine->drv->total_colors] >> 2) & 0x01;
bit3 = (color_prom[machine->drv->total_colors] >> 3) & 0x01;
g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
bit0 = (color_prom[2*machine->drv->total_colors] >> 0) & 0x01;
bit1 = (color_prom[2*machine->drv->total_colors] >> 1) & 0x01;
bit2 = (color_prom[2*machine->drv->total_colors] >> 2) & 0x01;
bit3 = (color_prom[2*machine->drv->total_colors] >> 3) & 0x01;
b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
palette_set_color(machine,i,MAKE_RGB(r,g,b));
color_prom++;
}
color_prom += 2*machine->drv->total_colors;
/* color_prom now points to the beginning of the lookup tables */
/* characters use colors 0-15 (or 0-127, but the eight rows are identical) */
for (i = 0;i < TOTAL_COLORS(0);i++)
COLOR(0,i) = i;
/* background tiles use colors 192-255 */
/* I don't know how much of the lookup table PROM is hooked up, */
/* I'm only using the first 32 bytes because the rest is empty. */
for (i = 0;i < TOTAL_COLORS(1);i++)
COLOR(1,i) = 0xc0 + (i & 0x30) + (color_prom[((i & 0x40) >> 2) + (i & 0x0f)] & 0x0f);
color_prom += 256;
/* sprites use colors 128-143 (or 128-191, but the four rows are identical) */
for (i = 0;i < TOTAL_COLORS(2);i++)
COLOR(2,i) = 0x80 + (*(color_prom++) & 0x0f);
}
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
static TILE_GET_INFO( get_bg_tile_info )
{
int tile = cop01_bgvideoram[tile_index];
int attr = cop01_bgvideoram[tile_index+0x800];
int pri = (attr & 0x80) >> 7;
/* kludge: priority is not actually pen based, but color based. Since the
* game uses a lookup table, the two are not the same thing.
* Palette entries with bits 2&3 set have priority over sprites.
* tilemap.c can't handle that yet, so I'm cheating, because I know that
* color codes using the second row of the lookup table don't use palette
* entries 12-15.
* The only place where this has any effect is the beach at the bottom of
* the screen right at the beginning of mightguy. cop01 doesn't seem to
* use priority at all.
*/
if (attr & 0x10) pri = 0;
SET_TILE_INFO(1,tile + ((attr & 0x03) << 8),(attr & 0x1c) >> 2,0);
tileinfo->group = pri;
}
static TILE_GET_INFO( get_fg_tile_info )
{
int tile = cop01_fgvideoram[tile_index];
SET_TILE_INFO(0,tile,0,0);
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
VIDEO_START( cop01 )
{
bg_tilemap = tilemap_create(get_bg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8,8,64,32);
fg_tilemap = tilemap_create(get_fg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
tilemap_set_transparent_pen(fg_tilemap,15);
/* priority doesn't exactly work this way, see above */
tilemap_set_transmask(bg_tilemap,0,0xffff,0x0000); /* split type 0 is totally transparent in front half */
tilemap_set_transmask(bg_tilemap,1,0x0fff,0xf000); /* split type 1 has pens 0-11 transparent in front half */
}
/***************************************************************************
Memory handlers
***************************************************************************/
WRITE8_HANDLER( cop01_background_w )
{
cop01_bgvideoram[offset] = data;
tilemap_mark_tile_dirty(bg_tilemap,offset & 0x7ff);
}
WRITE8_HANDLER( cop01_foreground_w )
{
cop01_fgvideoram[offset] = data;
tilemap_mark_tile_dirty(fg_tilemap,offset);
}
WRITE8_HANDLER( cop01_vreg_w )
{
/* 0x40: --xx---- sprite bank, coin counters, flip screen
* -----x-- flip screen
* ------xx coin counters
* 0x41: xxxxxxxx xscroll
* 0x42: ---xx--- ? matches the bg tile color most of the time, but not
* during level transitions. Maybe sprite palette bank?
* (the four banks in the PROM are identical)
* ------x- unused (xscroll overflow)
* -------x msb xscroll
* 0x43: xxxxxxxx yscroll
*/
mightguy_vreg[offset] = data;
if (offset == 0)
{
coin_counter_w(0,data & 1);
coin_counter_w(1,data & 2);
flip_screen_set(data & 4);
}
}
/***************************************************************************
Display refresh
***************************************************************************/
static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect)
{
int offs,code,attr,sx,sy,flipx,flipy,color;
for (offs = 0;offs < spriteram_size;offs += 4)
{
code = spriteram[offs+1];
attr = spriteram[offs+2];
/* xxxx---- color
* ----xx-- flipy,flipx
* -------x msbx
*/
color = attr>>4;
flipx = attr & 0x04;
flipy = attr & 0x08;
sx = (spriteram[offs+3] - 0x80) + 256 * (attr & 0x01);
sy = 240 - spriteram[offs];
if (flip_screen)
{
sx = 240 - sx;
sy = 240 - sy;
flipx = !flipx;
flipy = !flipy;
}
if (code&0x80)
code += (mightguy_vreg[0]&0x30)<<3;
drawgfx(bitmap,machine->gfx[2],
code,
color,
flipx,flipy,
sx,sy,
cliprect,TRANSPARENCY_PEN,0 );
}
}
VIDEO_UPDATE( cop01 )
{
tilemap_set_scrollx(bg_tilemap,0,mightguy_vreg[1] + 256 * (mightguy_vreg[2] & 1));
tilemap_set_scrolly(bg_tilemap,0,mightguy_vreg[3]);
tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_DRAW_LAYER1,0);
draw_sprites(machine, bitmap,cliprect);
tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_DRAW_LAYER0,0);
tilemap_draw(bitmap,cliprect,fg_tilemap,0,0 );
return 0;
}