
#include "driver.h"
#include "vidhrdw/generic.h"

static tilemap *bg_tilemap;
static int charbank;
static int spritebank;
static int palettebank;
static int colortablebank;
static int flipscreen;
static int bgpriority;

static int xoffsethack;

//static rectangle spritevisiblearea =
static rectangle xspritevisiblearea =
{
//	2*8, 34*8-1,
	2*16, 34*16-1,
//	0*8, 28*8-1
	0*16, 28*16-1
};



//PALETTE_INIT( pacman )
PALETTE_INIT( pacmanx )
{
	int i;
	for (i = 0;i < 32;i++)
	{
		int bit0,bit1,bit2,r,g,b;

		/* red component */
		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;
		/* green component */
		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;
		/* blue component */
		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,r,g,b);
	}

	/* color_prom now points to the beginning of the lookup table */
	color_prom += 32;

	/* character lookup table */
	/* sprites use the same color lookup table as characters */
	for (i = 0;i < 64*4;i++)
	{
		/* first palette bank */
		colortable[i] = color_prom[i] & 0x0f;

		/* second palette bank */
		if( colortable[i] != 0 )
		{
			colortable[i + 64*4] = colortable[i] + 0x10;
		}
		else
		{
			colortable[i + 64*4] = 0;
		}
	}
}

//UINT32 pacman_scan_rows( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows )
UINT32 pacmanx_scan_rows( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows )
{
	int offs;

	row += 2;
	col -= 2;
	if (col & 0x20)
		offs = row + ((col & 0x1f) << 5);
	else
		offs = col + (row << 5);

	return offs;
}

static void pacman_get_tile_info(int tile_index)
{
	int code = videoram[tile_index] | (charbank << 8);
	int attr = (colorram[tile_index] & 0x1f) | (colortablebank << 5) | (palettebank << 6 );

	SET_TILE_INFO(0,code,attr,0)
}

/***************************************************************************

  Start the video hardware emulation.

***************************************************************************/

//VIDEO_START( pacman )
VIDEO_START( pacmanx )
{
	charbank = 0;
	spritebank = 0;
	palettebank = 0;
	colortablebank = 0;
	flipscreen = 0;
	bgpriority = 0;

	/* In the Pac Man based games (NOT Pengo) the first two sprites must be offset */
	/* one pixel to the left to get a more correct placement */
//	xoffsethack = 1;
	xoffsethack = 2;

//	bg_tilemap = tilemap_create( pacman_get_tile_info, pacman_scan_rows, TILEMAP_OPAQUE, 8, 8, 36, 28 );
	bg_tilemap = tilemap_create( pacman_get_tile_info, pacmanx_scan_rows, TILEMAP_OPAQUE, 16, 16, 36, 28 );

	if( !bg_tilemap )
		return 1;

	return 0;
}

//WRITE8_HANDLER( pacman_videoram_w )
WRITE8_HANDLER( pacmanx_videoram_w )
{
	if (videoram[offset] != data)
	{
		videoram[offset] = data;
		tilemap_mark_tile_dirty( bg_tilemap, offset );
	}
}

//WRITE8_HANDLER( pacman_colorram_w )
WRITE8_HANDLER( pacmanx_colorram_w )
{
	if (colorram[offset] != data)
	{
		colorram[offset] = data;
		tilemap_mark_tile_dirty( bg_tilemap, offset );
	}
}

//WRITE8_HANDLER( pacman_flipscreen_w )
WRITE8_HANDLER( pacmanx_flipscreen_w )
{
	if (flipscreen != (data & 1))
	{
		flipscreen = data & 1;
		tilemap_set_flip( bg_tilemap, flipscreen * ( TILEMAP_FLIPX + TILEMAP_FLIPY ) );
	}
}


/***************************************************************************

  Draw the game screen in the given mame_bitmap.
  Do NOT call osd_update_display() from this function, it will be called by
  the main emulation engine.

***************************************************************************/
//VIDEO_UPDATE( pacman )
VIDEO_UPDATE( pacmanx )
{
	if (bgpriority != 0)
		fillbitmap(bitmap,Machine->pens[0],&Machine->screen[0].visarea);
	else
		tilemap_draw(bitmap,cliprect,bg_tilemap,TILEMAP_IGNORE_TRANSPARENCY,0);

	if( spriteram_size )
	{
		int offs;

//		rectangle spriteclip = spritevisiblearea;
		rectangle spriteclip = xspritevisiblearea;
		sect_rect(&spriteclip, cliprect);

		/* Draw the sprites. Note that it is important to draw them exactly in this */
		/* order, to have the correct priorities. */
		for (offs = spriteram_size - 2;offs > 2*2;offs -= 2)
		{
			int sx,sy;

//			sx = 272 - spriteram_2[offs + 1];
			sx = 544 - (spriteram_2[offs + 1] * 2);
//			sy = spriteram_2[offs] - 31;
			sy = (spriteram_2[offs] - 31) * 2;

			drawgfx(bitmap,Machine->gfx[1],
					( spriteram[offs] >> 2 ) | (spritebank << 6),
					( spriteram[offs + 1] & 0x1f ) | (colortablebank << 5) | (palettebank << 6 ),
					spriteram[offs] & 1,spriteram[offs] & 2,
					sx,sy,
					&spriteclip,TRANSPARENCY_COLOR,0);

			/* also plot the sprite with wraparound (tunnel in Crush Roller) */
			drawgfx(bitmap,Machine->gfx[1],
					( spriteram[offs] >> 2 ) | (spritebank << 6),
					( spriteram[offs + 1] & 0x1f ) | (colortablebank << 5) | (palettebank << 6 ),
					spriteram[offs] & 1,spriteram[offs] & 2,
//					sx - 256,sy,
					sx - 512,sy,
					&spriteclip,TRANSPARENCY_COLOR,0);
		}
		/* In the Pac Man based games (NOT Pengo) the first two sprites must be offset */
		/* one pixel to the left to get a more correct placement */
		for (offs = 2*2;offs >= 0;offs -= 2)
		{
			int sx,sy;

//			sx = 272 - spriteram_2[offs + 1];
			sx = 544 - (spriteram_2[offs + 1] * 2);
//			sy = spriteram_2[offs] - 31;
			sy = (spriteram_2[offs] - 31) * 2;

			drawgfx(bitmap,Machine->gfx[1],
					( spriteram[offs] >> 2 ) | (spritebank << 6),
					( spriteram[offs + 1] & 0x1f ) | (colortablebank << 5) | (palettebank << 6 ),
					spriteram[offs] & 1,spriteram[offs] & 2,
					sx,sy + xoffsethack,
					&spriteclip,TRANSPARENCY_COLOR,0);

			/* also plot the sprite with wraparound (tunnel in Crush Roller) */
			drawgfx(bitmap,Machine->gfx[1],
					( spriteram[offs] >> 2 ) | (spritebank << 6),
					( spriteram[offs + 1] & 0x1f ) | (colortablebank << 5) | (palettebank << 6 ),
					spriteram[offs] & 2,spriteram[offs] & 1,
//					sx - 256,sy + xoffsethack,
					sx - 512,sy + xoffsethack,
					&spriteclip,TRANSPARENCY_COLOR,0);
		}
	}

	if (bgpriority != 0)
		tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
	return 0;
}
