/******************************************************************************
Video Hardware for Nichibutsu Mahjong series.
Driver by Takahiro Nogi <nogi@kt.rim.or.jp> 2000/01/28 -
******************************************************************************/
#include "emu.h"
#include "includes/nb1413m3.h"
#include "includes/hyhoo.h"
static void hyhoo_gfxdraw(running_machine &machine);
WRITE8_HANDLER( hyhoo_blitter_w )
{
hyhoo_state *state = space->machine().driver_data<hyhoo_state>();
switch (offset)
{
case 0x00: state->m_blitter_src_addr = (state->m_blitter_src_addr & 0xff00) | data;
nb1413m3_gfxradr_l_w(space, 0, data); break;
case 0x01: state->m_blitter_src_addr = (state->m_blitter_src_addr & 0x00ff) | (data << 8);
nb1413m3_gfxradr_h_w(space, 0, data); break;
case 0x02: state->m_blitter_destx = data; break;
case 0x03: state->m_blitter_desty = data; break;
case 0x04: state->m_blitter_sizex = data; break;
case 0x05: state->m_blitter_sizey = data;
/* writing here also starts the blit */
hyhoo_gfxdraw(space->machine());
break;
case 0x06: state->m_blitter_direction_x = (data >> 0) & 0x01;
state->m_blitter_direction_y = (data >> 1) & 0x01;
state->m_flipscreen = (~data >> 2) & 0x01;
state->m_dispflag = (~data >> 3) & 0x01;
break;
case 0x07: break;
}
}
WRITE8_HANDLER( hyhoo_romsel_w )
{
hyhoo_state *state = space->machine().driver_data<hyhoo_state>();
int gfxlen = space->machine().region("gfx1")->bytes();
state->m_gfxrom = (((data & 0xc0) >> 4) + (data & 0x03));
state->m_highcolorflag = data;
nb1413m3_gfxrombank_w(space, 0, data);
if ((0x20000 * state->m_gfxrom) > (gfxlen - 1))
{
#ifdef MAME_DEBUG
popmessage("GFXROM BANK OVER!!");
#endif
state->m_gfxrom &= (gfxlen / 0x20000 - 1);
}
}
static TIMER_CALLBACK( blitter_timer_callback )
{
nb1413m3_busyflag = 1;
}
static void hyhoo_gfxdraw(running_machine &machine)
{
hyhoo_state *state = machine.driver_data<hyhoo_state>();
UINT8 *GFX = machine.region("gfx1")->base();
int x, y;
int dx1, dx2, dy;
int startx, starty;
int sizex, sizey;
int skipx, skipy;
int ctrx, ctry;
int gfxaddr, gfxlen;
UINT8 color, color1, color2;
int r, g, b;
pen_t pen;
nb1413m3_busyctr = 0;
state->m_gfxrom |= ((nb1413m3_sndrombank1 & 0x02) << 3);
startx = state->m_blitter_destx + state->m_blitter_sizex;
starty = state->m_blitter_desty + state->m_blitter_sizey;
if (state->m_blitter_direction_x)
{
sizex = state->m_blitter_sizex ^ 0xff;
skipx = 1;
}
else
{
sizex = state->m_blitter_sizex;
skipx = -1;
}
if (state->m_blitter_direction_y)
{
sizey = state->m_blitter_sizey ^ 0xff;
skipy = 1;
}
else
{
sizey = state->m_blitter_sizey;
skipy = -1;
}
gfxlen = machine.region("gfx1")->bytes();
gfxaddr = (state->m_gfxrom << 17) + (state->m_blitter_src_addr << 1);
for (y = starty, ctry = sizey; ctry >= 0; y += skipy, ctry--)
{
for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
{
if ((gfxaddr > (gfxlen - 1)))
{
#ifdef MAME_DEBUG
popmessage("GFXROM ADDRESS OVER!!");
#endif
gfxaddr = 0;
}
color = GFX[gfxaddr++];
dx1 = (2 * x + 0) & 0x1ff;
dx2 = (2 * x + 1) & 0x1ff;
dy = y & 0xff;
if (state->m_highcolorflag & 0x04)
{
// direct mode
if (color != 0xff)
{
if (state->m_highcolorflag & 0x20)
{
/* least significant bits */
// src xxxxxxxx_bbbggrrr
// dst xxbbbxxx_ggxxxrrr
r = ((color & 0x07) >> 0) & 0x07;
g = ((color & 0x18) >> 3) & 0x03;
b = ((color & 0xe0) >> 5) & 0x07;
pen = MAKE_RGB(pal6bit(r), pal5bit(g), pal5bit(b));
*BITMAP_ADDR32(state->m_tmpbitmap, dy, dx1) = *BITMAP_ADDR32(state->m_tmpbitmap, dy, dx1) | pen;
*BITMAP_ADDR32(state->m_tmpbitmap, dy, dx2) = *BITMAP_ADDR32(state->m_tmpbitmap, dy, dx2) | pen;
}
else
{
/* most significant bits */
// src xxxxxxxx_bbgggrrr
// dst bbxxxggg_xxrrrxxx
r = ((color & 0x07) >> 0) & 0x07;
g = ((color & 0x38) >> 3) & 0x07;
b = ((color & 0xc0) >> 6) & 0x03;
pen = MAKE_RGB(pal6bit(r << 3), pal5bit(g << 2), pal5bit(b << 3));
*BITMAP_ADDR32(state->m_tmpbitmap, dy, dx1) = pen;
*BITMAP_ADDR32(state->m_tmpbitmap, dy, dx2) = pen;
}
}
}
else
{
// lookup table mode
if (state->m_blitter_direction_x)
{
// flip
color1 = (color & 0x0f) >> 0;
color2 = (color & 0xf0) >> 4;
}
else
{
// normal
color1 = (color & 0xf0) >> 4;
color2 = (color & 0x0f) >> 0;
}
if (state->m_clut[color1])
{
// src xxxxxxxx_bbgggrrr
// dst bbxxxggg_xxrrrxxx
r = ((~state->m_clut[color1] & 0x07) >> 0) & 0x07;
g = ((~state->m_clut[color1] & 0x38) >> 3) & 0x07;
b = ((~state->m_clut[color1] & 0xc0) >> 6) & 0x03;
pen = MAKE_RGB(pal6bit(r << 3), pal5bit(g << 2), pal5bit(b << 3));
*BITMAP_ADDR32(state->m_tmpbitmap, dy, dx1) = pen;
}
if (state->m_clut[color2])
{
// src xxxxxxxx_bbgggrrr
// dst bbxxxggg_xxrrrxxx
r = ((~state->m_clut[color2] & 0x07) >> 0) & 0x07;
g = ((~state->m_clut[color2] & 0x38) >> 3) & 0x07;
b = ((~state->m_clut[color2] & 0xc0) >> 6) & 0x03;
pen = MAKE_RGB(pal6bit(r << 3), pal5bit(g << 2), pal5bit(b << 3));
*BITMAP_ADDR32(state->m_tmpbitmap, dy, dx2) = pen;
}
}
nb1413m3_busyctr++;
}
}
nb1413m3_busyflag = 0;
machine.scheduler().timer_set(attotime::from_hz(400000) * nb1413m3_busyctr, FUNC(blitter_timer_callback));
}
VIDEO_START( hyhoo )
{
hyhoo_state *state = machine.driver_data<hyhoo_state>();
state->m_tmpbitmap = machine.primary_screen->alloc_compatible_bitmap();
}
SCREEN_UPDATE( hyhoo )
{
hyhoo_state *state = screen->machine().driver_data<hyhoo_state>();
if (state->m_dispflag)
copybitmap(bitmap, state->m_tmpbitmap, state->m_flipscreen, state->m_flipscreen, 0, 0, cliprect);
else
bitmap_fill(bitmap, cliprect, RGB_BLACK);
return 0;
}