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

Ikki (c) 1985 Sun Electronics

Video hardware driver by Uki

    20/Jun/2001 -

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

#include "emu.h"
#include "includes/ikki.h"

PALETTE_INIT( ikki )
{
	ikki_state *state = machine.driver_data<ikki_state>();
	int i;

	/* allocate the colortable - extra pen for the punch through pen */
	machine.colortable = colortable_alloc(machine, 0x101);

	/* create a lookup table for the palette */
	for (i = 0; i < 0x100; i++)
	{
		int r = pal4bit(color_prom[i + 0x000]);
		int g = pal4bit(color_prom[i + 0x100]);
		int b = pal4bit(color_prom[i + 0x200]);

		colortable_palette_set_color(machine.colortable, i, MAKE_RGB(r, g, b));
	}

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

	/* sprites lookup table */
	for (i = 0; i < 0x200; i++)
	{
		UINT16 ctabentry = color_prom[i] ^ 0xff;

		if (((i & 0x07) == 0x07) && (ctabentry == 0))
		{
			/* punch through */
			state->m_punch_through_pen = i;
			ctabentry = 0x100;
		}

		colortable_entry_set_value(machine.colortable, i, ctabentry);
	}

	/* bg lookup table */
	for (i = 0x200; i < 0x400; i++)
	{
		UINT8 ctabentry = color_prom[i];
		colortable_entry_set_value(machine.colortable, i, ctabentry);
	}
}

WRITE8_HANDLER( ikki_scrn_ctrl_w )
{
	ikki_state *state = space->machine().driver_data<ikki_state>();
	state->m_flipscreen = (data >> 2) & 1;
}


static void draw_sprites( running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect )
{
	ikki_state *state = machine.driver_data<ikki_state>();
	UINT8 *spriteram = state->m_spriteram;
	int y;
	offs_t offs;

	bitmap_fill(state->m_sprite_bitmap, cliprect, state->m_punch_through_pen);

	for (offs = 0; offs < state->m_spriteram_size; offs += 4)
	{
		int code = (spriteram[offs + 2] & 0x80) | (spriteram[offs + 1] >> 1);
		int color = spriteram[offs + 2] & 0x3f;

		int x = spriteram[offs + 3];
		    y = spriteram[offs + 0];

		if (state->m_flipscreen)
			x = 240 - x;
		else
			y = 224 - y;

		x = x & 0xff;
		y = y & 0xff;

		if (x > 248)
			x = x - 256;

		if (y > 240)
			y = y - 256;

		drawgfx_transmask(state->m_sprite_bitmap,cliprect, machine.gfx[1],
				code, color,
				state->m_flipscreen,state->m_flipscreen,
				x,y,
				colortable_get_transpen_mask(machine.colortable, machine.gfx[1], color, 0));
	}

	/* copy the sprite bitmap into the main bitmap, skipping the transparent pixels */
	for (y = cliprect->min_y; y <= cliprect->max_y; y++)
	{
		int x;

		for (x = cliprect->min_x; x <= cliprect->max_x; x++)
		{
			UINT16 pen = *BITMAP_ADDR16(state->m_sprite_bitmap, y, x);

			if (colortable_entry_get_value(machine.colortable, pen) != 0x100)
				*BITMAP_ADDR16(bitmap, y, x) = pen;
		}
	}
}


VIDEO_START( ikki )
{
	ikki_state *state = machine.driver_data<ikki_state>();
	state->m_sprite_bitmap = machine.primary_screen->alloc_compatible_bitmap();
	state->save_item(NAME(*state->m_sprite_bitmap));
}


SCREEN_UPDATE( ikki )
{
	ikki_state *state = screen->machine().driver_data<ikki_state>();
	offs_t offs;
	UINT8 *VIDEOATTR = screen->machine().region("user1")->base();

	/* draw bg layer */

	for (offs = 0; offs < (state->m_videoram_size / 2); offs++)
	{
		int color, bank;

		int sx = offs / 32;
		int sy = offs % 32;
		int y = sy*8;
		int x = sx*8;

		int d = VIDEOATTR[sx];

		switch (d)
		{
			case 0x02: /* scroll area */
				x = sx * 8 - state->m_scroll[1];
				if (x < 0)
					x += 8 * 22;
				y = (sy * 8 + ~state->m_scroll[0]) & 0xff;
				break;

			case 0x03: /* non-scroll area */
				break;

			case 0x00: /* sprite disable? */
				break;

			case 0x0d: /* sprite disable? */
				break;

			case 0x0b: /* non-scroll area (?) */
				break;

			case 0x0e: /* unknown */
				break;
		}

		if (state->m_flipscreen)
		{
			x = 248 - x;
			y = 248 - y;
		}

		color = state->m_videoram[offs * 2];
		bank = (color & 0xe0) << 3;
		color = ((color & 0x1f)<<0) | ((color & 0x80) >> 2);

		drawgfx_opaque(bitmap,cliprect,screen->machine().gfx[0],
			state->m_videoram[offs * 2 + 1] + bank,
			color,
			state->m_flipscreen,state->m_flipscreen,
			x,y);
	}

	draw_sprites(screen->machine(), bitmap, cliprect);

	/* mask sprites */

	for (offs = 0; offs < (state->m_videoram_size / 2); offs++)
	{
		int sx = offs / 32;
		int sy = offs % 32;

		int d = VIDEOATTR[sx];

		if ((d == 0) || (d == 0x0d))
		{
			int color, bank;

			int y = sy * 8;
			int x = sx * 8;

			if (state->m_flipscreen)
			{
				x = 248 - x;
				y = 248 - y;
			}

			color = state->m_videoram[offs * 2];
			bank = (color & 0xe0) << 3;
			color = ((color & 0x1f)<<0) | ((color & 0x80) >> 2);

			drawgfx_opaque(bitmap,cliprect,screen->machine().gfx[0],
				state->m_videoram[offs * 2 + 1] + bank,
				color,
				state->m_flipscreen,state->m_flipscreen,
				x,y);
		}
	}

	return 0;
}
