/***************************************************************************
video.c
Functions to emulate the video hardware of the machine.
***************************************************************************/
#include "driver.h"
UINT8 *thepit_videoram;
UINT8 *thepit_colorram;
UINT8 *thepit_attributesram;
UINT8 *thepit_spriteram;
size_t thepit_spriteram_size;
static UINT8 graphics_bank;
static UINT8 thepit_flip_screen_x;
static UINT8 thepit_flip_screen_y;
static tilemap *thepit_solid_tilemap;
static tilemap *thepit_tilemap;
static UINT8 *dummy_tile;
static rectangle spritevisiblearea =
{
2*8+1, 32*8-1,
2*8, 30*8-1
};
static rectangle spritevisibleareaflipx =
{
0*8, 30*8-2,
2*8, 30*8-1
};
/***************************************************************************
Convert the color PROMs into a more useable format.
bit 7 -- 220 ohm resistor -- BLUE
-- 470 ohm resistor -- BLUE
-- 220 ohm resistor -- GREEN
-- 470 ohm resistor -- GREEN
-- 1 kohm resistor -- GREEN
-- 220 ohm resistor -- RED
-- 470 ohm resistor -- RED
bit 0 -- 1 kohm resistor -- RED
***************************************************************************/
PALETTE_INIT( thepit )
{
int i;
for (i = 0; i < 32; i++)
{
int bit0, bit1, bit2, r, g, b;
bit0 = (color_prom[i] >> 0) & 0x01;
bit1 = (color_prom[i] >> 1) & 0x01;
bit2 = (color_prom[i] >> 2) & 0x01;
r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
bit0 = (color_prom[i] >> 3) & 0x01;
bit1 = (color_prom[i] >> 4) & 0x01;
bit2 = (color_prom[i] >> 5) & 0x01;
g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
bit0 = 0;
bit1 = (color_prom[i] >> 6) & 0x01;
bit2 = (color_prom[i] >> 7) & 0x01;
b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
palette_set_color(machine, i, MAKE_RGB(r, g, b));
}
/* allocate primary colors for the background and foreground
this is wrong, but I don't know where to pick the colors from */
for (i = 0; i < 8; i++)
palette_set_color_rgb(machine, i + 32, pal1bit(i >> 2), pal1bit(i >> 1), pal1bit(i >> 0));
}
/***************************************************************************
Super Mouse has 5 bits per gun (maybe 6 for green), exact weights are
unknown.
***************************************************************************/
PALETTE_INIT( suprmous )
{
int i;
for (i = 0; i < 32; i++)
{
UINT8 r = ((color_prom[i + 0x20] >> 6) | (color_prom[i + 0x00] << 2)) & 0x1f;
UINT8 g = BITSWAP8(color_prom[i + 0x20], 7, 6, 0, 1, 2, 3, 4, 5) & 0x1f;
UINT8 b = BITSWAP8(color_prom[i + 0x00], 0, 1, 2, 3, 4, 5, 6, 7) & 0x1f;
palette_set_color_rgb(machine, i + 8, pal5bit(r), pal5bit(g), pal5bit(b));
}
/* allocate primary colors for the background and foreground
this is wrong, but I don't know where to pick the colors from */
for (i = 0; i < 8; i++)
palette_set_color_rgb(machine, i + 32, pal1bit(i >> 2), pal1bit(i >> 1), pal1bit(i >> 0));
}
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
static TILE_GET_INFO( solid_get_tile_info )
{
UINT8 back_color = (thepit_colorram[tile_index] & 0x70) >> 4;
int priority = (back_color != 0) && ((thepit_colorram[tile_index] & 0x80) == 0);
tileinfo->pen_data = dummy_tile;
tileinfo->palette_base = back_color + 32;
tileinfo->category = priority;
}
static TILE_GET_INFO( get_tile_info )
{
UINT8 fore_color = thepit_colorram[tile_index] % machine->gfx[0]->total_colors;
UINT8 code = thepit_videoram[tile_index];
SET_TILE_INFO(2 * graphics_bank, code, fore_color, 0);
}
/*************************************
*
* Video system start
*
*************************************/
VIDEO_START( thepit )
{
thepit_solid_tilemap = tilemap_create(solid_get_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
thepit_tilemap = tilemap_create(get_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
tilemap_set_transparent_pen(thepit_tilemap, 0);
tilemap_set_scroll_cols(thepit_solid_tilemap, 32);
tilemap_set_scroll_cols(thepit_tilemap, 32);
dummy_tile = auto_malloc(8*8);
memset(dummy_tile, 0, 8*8);
graphics_bank = 0; /* only used in intrepid */
}
/*************************************
*
* Memory handlers
*
*************************************/
WRITE8_HANDLER( thepit_videoram_w )
{
thepit_videoram[offset] = data;
tilemap_mark_tile_dirty(thepit_tilemap, offset);
}
WRITE8_HANDLER( thepit_colorram_w )
{
thepit_colorram[offset] = data;
tilemap_mark_tile_dirty(thepit_tilemap, offset);
tilemap_mark_tile_dirty(thepit_solid_tilemap, offset);
}
WRITE8_HANDLER( thepit_flip_screen_x_w )
{
thepit_flip_screen_x = data & 0x01;
tilemap_set_flip(thepit_tilemap, thepit_flip_screen_x ? TILEMAP_FLIPX : 0);
tilemap_set_flip(thepit_solid_tilemap, thepit_flip_screen_x ? TILEMAP_FLIPX : 0);
}
WRITE8_HANDLER( thepit_flip_screen_y_w )
{
thepit_flip_screen_y = data & 0x01;
tilemap_set_flip(thepit_tilemap, thepit_flip_screen_y ? TILEMAP_FLIPY : 0);
tilemap_set_flip(thepit_solid_tilemap, thepit_flip_screen_y ? TILEMAP_FLIPY : 0);
}
WRITE8_HANDLER( intrepid_graphics_bank_w )
{
if (graphics_bank != (data & 0x01))
{
graphics_bank = data & 0x01;
tilemap_mark_all_tiles_dirty(thepit_tilemap);
}
}
READ8_HANDLER( thepit_input_port_0_r )
{
/* Read either the real or the fake input ports depending on the
horizontal flip switch. (This is how the real PCB does it) */
if (thepit_flip_screen_x)
{
return input_port_3_r(offset);
}
else
{
return input_port_0_r(offset);
}
}
/*************************************
*
* Video update
*
*************************************/
static void draw_sprites(running_machine *machine,
mame_bitmap *bitmap,
const rectangle *cliprect,
int priority_to_draw)
{
int offs;
for (offs = thepit_spriteram_size - 4; offs >= 0; offs -= 4)
{
if (((thepit_spriteram[offs + 2] & 0x08) >> 3) == priority_to_draw)
{
UINT8 y, x, flipx, flipy;
if ((thepit_spriteram[offs + 0] == 0) || (thepit_spriteram[offs + 3] == 0))
{
continue;
}
y = 240 - thepit_spriteram[offs];
x = thepit_spriteram[offs + 3] + 1;
flipx = thepit_spriteram[offs + 1] & 0x40;
flipy = thepit_spriteram[offs + 1] & 0x80;
if (thepit_flip_screen_y)
{
y = 240 - y;
flipy = !flipy;
}
if (thepit_flip_screen_x)
{
x = 242 - x;
flipx = !flipx;
}
/* sprites 0-3 are drawn one pixel down */
if (offs < 16) y++;
drawgfx(bitmap, machine->gfx[2 * graphics_bank + 1],
thepit_spriteram[offs + 1] & 0x3f,
thepit_spriteram[offs + 2],
flipx, flipy, x, y,
thepit_flip_screen_x ? &spritevisibleareaflipx : &spritevisiblearea,
TRANSPARENCY_PEN, 0);
}
}
}
VIDEO_UPDATE( thepit )
{
offs_t offs;
for (offs = 0; offs < 32; offs++)
{
tilemap_set_scrolly(thepit_tilemap, offs, thepit_attributesram[offs << 1]);
tilemap_set_scrolly(thepit_solid_tilemap, offs, thepit_attributesram[offs << 1]);
}
/* low priority tiles */
tilemap_draw(bitmap, cliprect, thepit_solid_tilemap, 0, 0);
tilemap_draw(bitmap, cliprect, thepit_tilemap, 0, 0);
/* low priority sprites */
draw_sprites(machine, bitmap, cliprect, 0);
/* high priority tiles */
tilemap_draw(bitmap, cliprect, thepit_solid_tilemap, 1, 1);
/* high priority sprites */
draw_sprites(machine, bitmap, cliprect, 1);
return 0;
}