mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
Beast Busters - use single pass sprite render with priority buffer in case of cut-out effects
This commit is contained in:
parent
993b42e8b4
commit
1b776b299d
@ -7,6 +7,7 @@
|
||||
|
||||
#include "machine/gen_latch.h"
|
||||
#include "video/bufsprite.h"
|
||||
#include "screen.h"
|
||||
|
||||
class bbusters_state : public driver_device
|
||||
{
|
||||
@ -58,8 +59,8 @@ protected:
|
||||
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);
|
||||
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_sprites(bitmap_ind16 &bitmap, const uint16_t *source, int bank, int pass);
|
||||
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(screen_device &screen, bitmap_ind16 &bitmap, const uint16_t *source, int bank);
|
||||
|
||||
void sound_map(address_map &map);
|
||||
private:
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
if (dy>=16 && dy<240) {
|
||||
uint16_t *destline = &dest.pix16(dy);
|
||||
uint8_t *priorityline = &screen.priority().pix8(dy);
|
||||
uint8_t srcline=*m_scale_table_ptr;
|
||||
const uint8_t *srcptr=nullptr;
|
||||
|
||||
@ -157,9 +158,12 @@ 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);
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
if (flipx)
|
||||
x_index-=xinc;
|
||||
else
|
||||
@ -173,15 +177,21 @@ 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;
|
||||
|
||||
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;
|
||||
int16_t y;
|
||||
int block;
|
||||
|
||||
int priority;
|
||||
|
||||
sprite=source[offs+1];
|
||||
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;
|
||||
sprite=sprite&0x3fff;
|
||||
|
||||
// Palettes 0xc-0xf confirmed to be behind tilemap on Beast Busters
|
||||
if (pass==1 && (colour&0xc)!=0xc)
|
||||
continue;
|
||||
if (pass==0 && (colour&0xc)==0xc)
|
||||
continue;
|
||||
// Palettes 0xc-0xf confirmed to be behind tilemap on Beast Busters for 2nd sprite chip
|
||||
priority = (bank==2) ? (((colour&0xc)==0xc) ? 1 : 4) : 8;
|
||||
|
||||
switch ((source[offs+0]>>8)&0x3) {
|
||||
case 0:
|
||||
scale=source[offs+0]&0x7;
|
||||
m_scale_table_ptr = m_scale_table+0x387f+(0x80*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;
|
||||
case 1: /* 2 x 2 */
|
||||
scale=source[offs+0]&0xf;
|
||||
m_scale_table_ptr = m_scale_table+0x707f+(0x80*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;
|
||||
case 2: /* 64 by 64 block (2 x 2) x 2 */
|
||||
scale=source[offs+0]&0x1f;
|
||||
m_scale_table_ptr = m_scale_table+0xa07f+(0x80*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;
|
||||
case 3: /* 2 x 2 x 2 x 2 */
|
||||
scale=source[offs+0]&0x3f;
|
||||
m_scale_table_ptr = m_scale_table+0xc07f+(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;
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
screen.priority().fill(0, cliprect);
|
||||
|
||||
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[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]->draw(screen, bitmap, cliprect, 0, 0);
|
||||
draw_sprites(bitmap, m_spriteram[1]->buffer(), 2, 1);
|
||||
m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
|
||||
draw_sprites(bitmap, m_spriteram[1]->buffer(), 2, 0);
|
||||
draw_sprites(bitmap, m_spriteram[0]->buffer(), 1, -1);
|
||||
m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 2);
|
||||
draw_sprites(screen, bitmap, m_spriteram[1]->buffer(), 2);
|
||||
draw_sprites(screen, bitmap, m_spriteram[0]->buffer(), 1);
|
||||
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_scrolly(0, m_pf_scroll_data[0][1]);
|
||||
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[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);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user