Beast Busters - use single pass sprite render with priority buffer in case of cut-out effects

This commit is contained in:
bmcphail 2018-09-05 11:30:28 -04:00
parent 993b42e8b4
commit 1b776b299d
2 changed files with 34 additions and 22 deletions

View File

@ -7,6 +7,7 @@
#include "machine/gen_latch.h" #include "machine/gen_latch.h"
#include "video/bufsprite.h" #include "video/bufsprite.h"
#include "screen.h"
class bbusters_state : public driver_device class bbusters_state : public driver_device
{ {
@ -58,8 +59,8 @@ protected:
template<int Layer> DECLARE_WRITE16_MEMBER(pf_w); template<int Layer> DECLARE_WRITE16_MEMBER(pf_w);
inline const uint8_t *get_source_ptr(gfx_element *gfx, uint32_t sprite, int dx, int dy, int block); inline const uint8_t *get_source_ptr(gfx_element *gfx, uint32_t sprite, int dx, int dy, int block);
void draw_block(bitmap_ind16 &dest,int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int bank,int block); void draw_block(screen_device &screen, bitmap_ind16 &dest,int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int bank,int block,int priority);
void draw_sprites(bitmap_ind16 &bitmap, const uint16_t *source, int bank, int pass); void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const uint16_t *source, int bank);
void sound_map(address_map &map); void sound_map(address_map &map);
private: private:

View File

@ -128,7 +128,7 @@ inline const uint8_t *bbusters_state::get_source_ptr(gfx_element *gfx, uint32_t
return gfx->get_data((sprite+code) % gfx->elements()) + ((dy%16) * gfx->rowbytes()); return gfx->get_data((sprite+code) % gfx->elements()) + ((dy%16) * gfx->rowbytes());
} }
void bbusters_state::draw_block(bitmap_ind16 &dest,int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int bank,int block) void bbusters_state::draw_block(screen_device &screen, bitmap_ind16 &dest,int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int bank,int block,int priority)
{ {
gfx_element *gfx = m_gfxdecode->gfx(bank); gfx_element *gfx = m_gfxdecode->gfx(bank);
pen_t pen_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors()); pen_t pen_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors());
@ -141,6 +141,7 @@ void bbusters_state::draw_block(bitmap_ind16 &dest,int x,int y,int size,int flip
while (m_scale_line_count) { while (m_scale_line_count) {
if (dy>=16 && dy<240) { if (dy>=16 && dy<240) {
uint16_t *destline = &dest.pix16(dy); uint16_t *destline = &dest.pix16(dy);
uint8_t *priorityline = &screen.priority().pix8(dy);
uint8_t srcline=*m_scale_table_ptr; uint8_t srcline=*m_scale_table_ptr;
const uint8_t *srcptr=nullptr; const uint8_t *srcptr=nullptr;
@ -157,8 +158,11 @@ void bbusters_state::draw_block(bitmap_ind16 &dest,int x,int y,int size,int flip
srcptr=get_source_ptr(gfx,sprite,sx,srcline,block); srcptr=get_source_ptr(gfx,sprite,sx,srcline,block);
pixel=*srcptr++; pixel=*srcptr++;
if (pixel!=15) if (pixel!=15 && priority > priorityline[(x+(x_index>>16)) & 0x1ff])
{
priorityline[(x+(x_index>>16)) & 0x1ff] = priority;
destline[(x+(x_index>>16)) & 0x1ff]= pen_base + pixel; destline[(x+(x_index>>16)) & 0x1ff]= pen_base + pixel;
}
if (flipx) if (flipx)
x_index-=xinc; x_index-=xinc;
@ -173,14 +177,20 @@ void bbusters_state::draw_block(bitmap_ind16 &dest,int x,int y,int size,int flip
} }
} }
void bbusters_state::draw_sprites(bitmap_ind16 &bitmap, const uint16_t *source, int bank, int pass) void bbusters_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const uint16_t *source, int bank)
{ {
int offs; int offs;
for (offs = 0;offs <0x800 ;offs += 4) { // Sprites are stored in memory in back to front order.
// We draw them here front to back with a priority buffer in case any sprite
// with priority under a tilemap is later in the list than a sprite with
// above tilemap priority (which would cause a cut-out as only the top-most sprite
// in the line buffer goes to the priority mixer)
for (offs = 0x7fc;offs >=0 ;offs -= 4) {
int x,sprite,colour,fx,fy,scale; int x,sprite,colour,fx,fy,scale;
int16_t y; int16_t y;
int block; int block;
int priority;
sprite=source[offs+1]; sprite=source[offs+1];
colour=source[offs+0]; colour=source[offs+0];
@ -215,36 +225,33 @@ void bbusters_state::draw_sprites(bitmap_ind16 &bitmap, const uint16_t *source,
fx=source[offs+0]&0x800; fx=source[offs+0]&0x800;
sprite=sprite&0x3fff; sprite=sprite&0x3fff;
// Palettes 0xc-0xf confirmed to be behind tilemap on Beast Busters // Palettes 0xc-0xf confirmed to be behind tilemap on Beast Busters for 2nd sprite chip
if (pass==1 && (colour&0xc)!=0xc) priority = (bank==2) ? (((colour&0xc)==0xc) ? 1 : 4) : 8;
continue;
if (pass==0 && (colour&0xc)==0xc)
continue;
switch ((source[offs+0]>>8)&0x3) { switch ((source[offs+0]>>8)&0x3) {
case 0: case 0:
scale=source[offs+0]&0x7; scale=source[offs+0]&0x7;
m_scale_table_ptr = m_scale_table+0x387f+(0x80*scale); m_scale_table_ptr = m_scale_table+0x387f+(0x80*scale);
m_scale_line_count = 0x10-scale; m_scale_line_count = 0x10-scale;
draw_block(bitmap,x,y,16,fx,fy,sprite,colour,bank,block); draw_block(screen,bitmap,x,y,16,fx,fy,sprite,colour,bank,block,priority);
break; break;
case 1: /* 2 x 2 */ case 1: /* 2 x 2 */
scale=source[offs+0]&0xf; scale=source[offs+0]&0xf;
m_scale_table_ptr = m_scale_table+0x707f+(0x80*scale); m_scale_table_ptr = m_scale_table+0x707f+(0x80*scale);
m_scale_line_count = 0x20-scale; m_scale_line_count = 0x20-scale;
draw_block(bitmap,x,y,32,fx,fy,sprite,colour,bank,block); draw_block(screen,bitmap,x,y,32,fx,fy,sprite,colour,bank,block,priority);
break; break;
case 2: /* 64 by 64 block (2 x 2) x 2 */ case 2: /* 64 by 64 block (2 x 2) x 2 */
scale=source[offs+0]&0x1f; scale=source[offs+0]&0x1f;
m_scale_table_ptr = m_scale_table+0xa07f+(0x80*scale); m_scale_table_ptr = m_scale_table+0xa07f+(0x80*scale);
m_scale_line_count = 0x40-scale; m_scale_line_count = 0x40-scale;
draw_block(bitmap,x,y,64,fx,fy,sprite,colour,bank,block); draw_block(screen,bitmap,x,y,64,fx,fy,sprite,colour,bank,block,priority);
break; break;
case 3: /* 2 x 2 x 2 x 2 */ case 3: /* 2 x 2 x 2 x 2 */
scale=source[offs+0]&0x3f; scale=source[offs+0]&0x3f;
m_scale_table_ptr = m_scale_table+0xc07f+(0x80*scale); m_scale_table_ptr = m_scale_table+0xc07f+(0x80*scale);
m_scale_line_count = 0x80-scale; m_scale_line_count = 0x80-scale;
draw_block(bitmap,x,y,128,fx,fy,sprite,colour,bank,block); draw_block(screen,bitmap,x,y,128,fx,fy,sprite,colour,bank,block,priority);
break; break;
} }
} }
@ -254,22 +261,26 @@ void bbusters_state::draw_sprites(bitmap_ind16 &bitmap, const uint16_t *source,
uint32_t bbusters_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) uint32_t bbusters_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
screen.priority().fill(0, cliprect);
m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]); m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]);
m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]); m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]);
m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]); m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]);
m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]); m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]);
m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0); m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, m_spriteram[1]->buffer(), 2, 1); m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 2);
m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0); draw_sprites(screen, bitmap, m_spriteram[1]->buffer(), 2);
draw_sprites(bitmap, m_spriteram[1]->buffer(), 2, 0); draw_sprites(screen, bitmap, m_spriteram[0]->buffer(), 1);
draw_sprites(bitmap, m_spriteram[0]->buffer(), 1, -1);
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0; return 0;
} }
uint32_t mechatt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) uint32_t mechatt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
screen.priority().fill(0, cliprect);
m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]); m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]);
m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]); m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]);
m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]); m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]);
@ -277,7 +288,7 @@ uint32_t mechatt_state::screen_update(screen_device &screen, bitmap_ind16 &bitma
m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0); m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0); m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, m_spriteram[0]->buffer(), 1, -1); draw_sprites(screen, bitmap, m_spriteram[0]->buffer(), 1);
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0); m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0; return 0;
} }