draw sprites front to back, this fixes some issues with shadow

This commit is contained in:
Michaël Banaan Ananas 2014-09-05 22:26:12 +00:00
parent cc0655af59
commit 05a04d58fc
2 changed files with 70 additions and 87 deletions

View File

@ -121,11 +121,11 @@ public:
INTERRUPT_GEN_MEMBER(spi_interrupt); INTERRUPT_GEN_MEMBER(spi_interrupt);
void set_layer_offsets(); void set_layer_offsets();
void drawgfx_blend(bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx, UINT32 code, UINT32 color, int flipx, int flipy, int sx, int sy); void drawgfx_blend(bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx, UINT32 code, UINT32 color, int flipx, int flipy, int sx, int sy, bitmap_ind8 &primap, int primask);
void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri_mask); void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, bitmap_ind8 &primap, int priority);
void set_rowscroll(tilemap_t *layer, int scroll, INT16* rows); void set_rowscroll(tilemap_t *layer, int scroll, INT16* rows);
void set_scroll(tilemap_t *layer, int scroll); void set_scroll(tilemap_t *layer, int scroll);
void combine_tilemap(bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tile, int x, int y, int opaque, INT16 *rowscroll); void combine_tilemap(bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tile, int sx, int sy, int opaque, INT16 *rowscroll);
virtual void machine_start(); virtual void machine_start();
virtual void video_start(); virtual void video_start();

View File

@ -229,23 +229,15 @@ WRITE16_MEMBER(seibuspi_state::sprite_dma_start_w)
/*****************************************************************************/ /*****************************************************************************/
void seibuspi_state::drawgfx_blend(bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx, UINT32 code, UINT32 color, int flipx, int flipy, int sx, int sy) void seibuspi_state::drawgfx_blend(bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx, UINT32 code, UINT32 color, int flipx, int flipy, int sx, int sy, bitmap_ind8 &primap, int primask)
{ {
const pen_t *pens = &m_palette->pen(gfx->colorbase());
const UINT8 *dp;
int i, j;
int x1, x2;
int y1, y2;
int px, py;
int xd = 1, yd = 1;
int width = gfx->width(); int width = gfx->width();
int height = gfx->height(); int height = gfx->height();
x1 = sx; int x1 = sx;
x2 = sx + width - 1; int x2 = sx + width - 1;
y1 = sy; int y1 = sy;
y2 = sy + height - 1; int y2 = sy + height - 1;
if (x1 > cliprect.max_x || x2 < cliprect.min_x) if (x1 > cliprect.max_x || x2 < cliprect.min_x)
{ {
@ -256,8 +248,10 @@ void seibuspi_state::drawgfx_blend(bitmap_rgb32 &bitmap, const rectangle &clipre
return; return;
} }
px = 0; int px = 0;
py = 0; int py = 0;
int xd = 1;
int yd = 1;
if (flipx) if (flipx)
{ {
@ -306,44 +300,37 @@ void seibuspi_state::drawgfx_blend(bitmap_rgb32 &bitmap, const rectangle &clipre
y2 = cliprect.max_y; y2 = cliprect.max_y;
} }
dp = gfx->get_data(code); const pen_t *pens = &m_palette->pen(gfx->colorbase());
const UINT8 *src = gfx->get_data(code);
// draw // draw
for (j = y1; j <= y2; j++) for (int y = y1; y <= y2; y++)
{ {
UINT32 *p = &bitmap.pix32(j); UINT32 *dest = &bitmap.pix32(y);
UINT8 *pri = &primap.pix8(y);
UINT8 trans_pen = (1 << m_sprite_bpp) - 1; UINT8 trans_pen = (1 << m_sprite_bpp) - 1;
int dp_i = (py * width) + px; int src_i = (py * width) + px;
py += yd; py += yd;
for (i = x1; i <= x2; i++) for (int x = x1; x <= x2; x++)
{ {
UINT8 pen = dp[dp_i]; UINT8 pen = src[src_i];
if (pen != trans_pen) if (!(pri[x] & primask) && pen != trans_pen)
{ {
pri[x] |= primask;
int global_pen = pen + (color << m_sprite_bpp); int global_pen = pen + (color << m_sprite_bpp);
if (m_alpha_enable && m_alpha_table[global_pen]) if (m_alpha_enable && m_alpha_table[global_pen])
{ dest[x] = alpha_blend_r32(dest[x], pens[global_pen], 0x7f);
p[i] = alpha_blend_r32(p[i], pens[global_pen], 0x7f);
}
else else
{ dest[x] = pens[global_pen];
p[i] = pens[global_pen];
} }
} src_i += xd;
dp_i += xd;
} }
} }
} }
void seibuspi_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri_mask) void seibuspi_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, bitmap_ind8 &primap, int priority)
{ {
INT16 xpos, ypos;
int tile_num, color;
int width, height;
int flip_x, flip_y;
int priority;
int x1, y1;
gfx_element *gfx = m_gfxdecode->gfx(2); gfx_element *gfx = m_gfxdecode->gfx(2);
const int has_tile_high = (gfx->elements() > 0x10000) ? 1 : 0; const int has_tile_high = (gfx->elements() > 0x10000) ? 1 : 0;
const int colormask = (m_sprite_bpp == 6) ? 0x3f : 0x1f; const int colormask = (m_sprite_bpp == 6) ? 0x3f : 0x1f;
@ -362,7 +349,7 @@ void seibuspi_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec
if (m_layer_enable & 0x10) if (m_layer_enable & 0x10)
return; return;
for (int a = m_sprite_ram_size / 4 - 2; a >= 0; a -= 2) for (int a = 0; a < (m_sprite_ram_size / 4); a += 2)
{ {
/* /*
Word 0 Word 0
@ -379,31 +366,31 @@ void seibuspi_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec
-------- -------- ---x---- -------- tile_num high (only on RISE10/11 chip) -------- -------- ---x---- -------- tile_num high (only on RISE10/11 chip)
-------- -------- ------xx xxxxxxxx xpos -------- -------- ------xx xxxxxxxx xpos
*/ */
tile_num = m_sprite_ram[a + 0] >> 16 & 0xffff; int tile_num = m_sprite_ram[a + 0] >> 16 & 0xffff;
if (tile_num == 0) if (tile_num == 0)
continue; continue;
if (has_tile_high) if (has_tile_high)
tile_num |= m_sprite_ram[a + 1] << 4 & 0x10000; tile_num |= m_sprite_ram[a + 1] << 4 & 0x10000;
priority = m_sprite_ram[a + 0] >> 6 & 0x3; if (priority != (m_sprite_ram[a + 0] >> 6 & 0x3))
if (pri_mask != priority)
continue; continue;
int primask = 1 << priority;
xpos = m_sprite_ram[a + 1] & 0x3ff; INT16 xpos = m_sprite_ram[a + 1] & 0x3ff;
if (xpos & 0x200) if (xpos & 0x200)
xpos |= 0xfc00; xpos |= 0xfc00;
ypos = m_sprite_ram[a + 1] >> 16 & 0x1ff; INT16 ypos = m_sprite_ram[a + 1] >> 16 & 0x1ff;
if (ypos & 0x100) if (ypos & 0x100)
ypos |= 0xfe00; ypos |= 0xfe00;
color = m_sprite_ram[a + 0] & colormask; int color = m_sprite_ram[a + 0] & colormask;
width = (m_sprite_ram[a + 0] >> 8 & 0x7) + 1; int width = (m_sprite_ram[a + 0] >> 8 & 0x7) + 1;
height = (m_sprite_ram[a + 0] >> 12 & 0x7) + 1; int height = (m_sprite_ram[a + 0] >> 12 & 0x7) + 1;
flip_x = m_sprite_ram[a + 0] >> 11 & 0x1; int flip_x = m_sprite_ram[a + 0] >> 11 & 0x1;
flip_y = m_sprite_ram[a + 0] >> 15 & 0x1; int flip_y = m_sprite_ram[a + 0] >> 15 & 0x1;
x1 = 0; int x1 = 0;
y1 = 0; int y1 = 0;
if (flip_x) if (flip_x)
{ {
@ -420,13 +407,11 @@ void seibuspi_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec
{ {
for (int y = y1; y < height; y++) for (int y = y1; y < height; y++)
{ {
drawgfx_blend(bitmap, cliprect, gfx, tile_num, color, flip_x, flip_y, xpos + sprite_xtable[flip_x][x], ypos + sprite_ytable[flip_y][y]); drawgfx_blend(bitmap, cliprect, gfx, tile_num, color, flip_x, flip_y, xpos + sprite_xtable[flip_x][x], ypos + sprite_ytable[flip_y][y], primap, primask);
/* xpos seems to wrap-around to 0 at 512 */ /* xpos seems to wrap-around to 0 at 512 */
if ((xpos + (16 * x) + 16) >= 512) if ((xpos + (16 * x) + 16) >= 512)
{ drawgfx_blend(bitmap, cliprect, gfx, tile_num, color, flip_x, flip_y, xpos - 512 + sprite_xtable[flip_x][x], ypos + sprite_ytable[flip_y][y], primap, primask);
drawgfx_blend(bitmap, cliprect, gfx, tile_num, color, flip_x, flip_y, xpos - 512 + sprite_xtable[flip_x][x], ypos + sprite_ytable[flip_y][y]);
}
tile_num++; tile_num++;
} }
@ -434,11 +419,11 @@ void seibuspi_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprec
} }
} }
void seibuspi_state::combine_tilemap(bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tile, int x, int y, int opaque, INT16 *rowscroll) void seibuspi_state::combine_tilemap(bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *tile, int sx, int sy, int opaque, INT16 *rowscroll)
{ {
UINT16 *s; UINT16 *src;
UINT32 *d; UINT32 *dest;
UINT8 *t; UINT8 *flags;
UINT32 xscroll_mask, yscroll_mask; UINT32 xscroll_mask, yscroll_mask;
bitmap_ind16 &pen_bitmap = tile->pixmap(); bitmap_ind16 &pen_bitmap = tile->pixmap();
@ -446,32 +431,28 @@ void seibuspi_state::combine_tilemap(bitmap_rgb32 &bitmap, const rectangle &clip
xscroll_mask = pen_bitmap.width() - 1; xscroll_mask = pen_bitmap.width() - 1;
yscroll_mask = pen_bitmap.height() - 1; yscroll_mask = pen_bitmap.height() - 1;
for (int j = cliprect.min_y; j <= cliprect.max_y; j++) for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{ {
int rx = x; int rx = sx;
if (rowscroll) if (rowscroll)
{ {
rx += rowscroll[(j+y) & yscroll_mask]; rx += rowscroll[(y + sy) & yscroll_mask];
} }
d = &bitmap.pix32(j); dest = &bitmap.pix32(y);
s = &pen_bitmap.pix16((j+y) & yscroll_mask); src = &pen_bitmap.pix16((y + sy) & yscroll_mask);
t = &flags_bitmap.pix8((j+y) & yscroll_mask); flags = &flags_bitmap.pix8((y + sy) & yscroll_mask);
for (int i = cliprect.min_x+rx; i <= cliprect.max_x+rx; i++) for (int x = cliprect.min_x + rx; x <= cliprect.max_x + rx; x++)
{ {
if (opaque || (t[i & xscroll_mask] & (TILEMAP_PIXEL_LAYER0 | TILEMAP_PIXEL_LAYER1))) if (opaque || (flags[x & xscroll_mask] & (TILEMAP_PIXEL_LAYER0 | TILEMAP_PIXEL_LAYER1)))
{ {
UINT16 pen = s[i & xscroll_mask]; UINT16 pen = src[x & xscroll_mask];
if (m_alpha_enable && m_alpha_table[pen]) if (m_alpha_enable && m_alpha_table[pen])
{ *dest = alpha_blend_r32(*dest, m_palette->pen(pen), 0x7f);
*d = alpha_blend_r32(*d, m_palette->pen(pen), 0x7f);
}
else else
{ *dest = m_palette->pen(pen);
*d = m_palette->pen(pen);
} }
} dest++;
++d;
} }
} }
} }
@ -493,13 +474,14 @@ UINT32 seibuspi_state::screen_update_spi(screen_device &screen, bitmap_rgb32 &bi
fore_rowscroll = NULL; fore_rowscroll = NULL;
} }
screen.priority().fill(0, cliprect);
if (m_layer_enable & 1) if (m_layer_enable & 1)
bitmap.fill(0, cliprect); bitmap.fill(0, cliprect);
else
if (~m_layer_enable & 1)
combine_tilemap(bitmap, cliprect, m_back_layer, m_scrollram[0] & 0xffff, (m_scrollram[0] >> 16) & 0xffff, 1, back_rowscroll); combine_tilemap(bitmap, cliprect, m_back_layer, m_scrollram[0] & 0xffff, (m_scrollram[0] >> 16) & 0xffff, 1, back_rowscroll);
draw_sprites(bitmap, cliprect, 0); draw_sprites(bitmap, cliprect, screen.priority(), 0);
// if fore layer is enabled, draw priority 0 sprites behind back layer // if fore layer is enabled, draw priority 0 sprites behind back layer
if ((m_layer_enable & 0x15) == 0) if ((m_layer_enable & 0x15) == 0)
@ -507,21 +489,21 @@ UINT32 seibuspi_state::screen_update_spi(screen_device &screen, bitmap_rgb32 &bi
// if fore layer is enabled, draw priority 1 sprites behind middle layer // if fore layer is enabled, draw priority 1 sprites behind middle layer
if (~m_layer_enable & 4) if (~m_layer_enable & 4)
draw_sprites(bitmap, cliprect, 1); draw_sprites(bitmap, cliprect, screen.priority(), 1);
if (~m_layer_enable & 2) if (~m_layer_enable & 2)
combine_tilemap(bitmap, cliprect, m_midl_layer, m_scrollram[1] & 0xffff, (m_scrollram[1] >> 16) & 0xffff, 0, midl_rowscroll); combine_tilemap(bitmap, cliprect, m_midl_layer, m_scrollram[1] & 0xffff, (m_scrollram[1] >> 16) & 0xffff, 0, midl_rowscroll);
// if fore layer is disabled, draw priority 1 sprites above middle layer // if fore layer is disabled, draw priority 1 sprites above middle layer
if (m_layer_enable & 4) if (m_layer_enable & 4)
draw_sprites(bitmap, cliprect, 1); draw_sprites(bitmap, cliprect, screen.priority(), 1);
draw_sprites(bitmap, cliprect, 2); draw_sprites(bitmap, cliprect, screen.priority(), 2);
if (~m_layer_enable & 4) if (~m_layer_enable & 4)
combine_tilemap(bitmap, cliprect, m_fore_layer, m_scrollram[2] & 0xffff, (m_scrollram[2] >> 16) & 0xffff, 0, fore_rowscroll); combine_tilemap(bitmap, cliprect, m_fore_layer, m_scrollram[2] & 0xffff, (m_scrollram[2] >> 16) & 0xffff, 0, fore_rowscroll);
draw_sprites(bitmap, cliprect, 3); draw_sprites(bitmap, cliprect, screen.priority(), 3);
if (~m_layer_enable & 8) if (~m_layer_enable & 8)
combine_tilemap(bitmap, cliprect, m_text_layer, 0, 0, 0, NULL); combine_tilemap(bitmap, cliprect, m_text_layer, 0, 0, 0, NULL);
@ -531,12 +513,13 @@ UINT32 seibuspi_state::screen_update_spi(screen_device &screen, bitmap_rgb32 &bi
UINT32 seibuspi_state::screen_update_sys386f(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) UINT32 seibuspi_state::screen_update_sys386f(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{ {
screen.priority().fill(0, cliprect);
bitmap.fill(0, cliprect); bitmap.fill(0, cliprect);
draw_sprites(bitmap, cliprect, 0); draw_sprites(bitmap, cliprect, screen.priority(), 0);
draw_sprites(bitmap, cliprect, 1); draw_sprites(bitmap, cliprect, screen.priority(), 1);
draw_sprites(bitmap, cliprect, 2); draw_sprites(bitmap, cliprect, screen.priority(), 2);
draw_sprites(bitmap, cliprect, 3); draw_sprites(bitmap, cliprect, screen.priority(), 3);
return 0; return 0;
} }