mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
seibu/dynduke_v.cpp: Use single-pass sprite drawing. (#11758)
Manage sprite/tilemap priorities using priority masks.
This commit is contained in:
parent
418d093e54
commit
3d6955e3d1
@ -49,14 +49,14 @@ private:
|
||||
tilemap_t *m_bg_layer = nullptr;
|
||||
tilemap_t *m_fg_layer = nullptr;
|
||||
tilemap_t *m_tx_layer = nullptr;
|
||||
int m_back_bankbase = 0;
|
||||
int m_fore_bankbase = 0;
|
||||
int m_back_enable = 0;
|
||||
int m_fore_enable = 0;
|
||||
int m_sprite_enable = 0;
|
||||
int m_txt_enable = 0;
|
||||
int m_old_back = 0;
|
||||
int m_old_fore = 0;
|
||||
uint32_t m_back_bankbase = 0;
|
||||
uint32_t m_fore_bankbase = 0;
|
||||
bool m_back_enable = false;
|
||||
bool m_fore_enable = false;
|
||||
bool m_sprite_enable = false;
|
||||
bool m_txt_enable = false;
|
||||
uint32_t m_old_back = 0;
|
||||
uint32_t m_old_fore = 0;
|
||||
|
||||
void background_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
void foreground_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
@ -71,8 +71,8 @@ private:
|
||||
virtual void video_start() override;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect,int pri);
|
||||
void draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect, int pri );
|
||||
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, uint32_t pri_mask);
|
||||
|
||||
void vblank_irq(int state);
|
||||
void master_map(address_map &map);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "emu.h"
|
||||
#include "dynduke.h"
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
@ -87,8 +88,8 @@ void dynduke_state::gfxbank_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
if (data&0x01) m_back_bankbase=0x1000; else m_back_bankbase=0;
|
||||
if (data&0x10) m_fore_bankbase=0x1000; else m_fore_bankbase=0;
|
||||
m_back_bankbase = BIT(data, 0) ? 0x1000 : 0;
|
||||
m_fore_bankbase = BIT(data, 4) ? 0x1000 : 0;
|
||||
|
||||
if (m_back_bankbase!=m_old_back)
|
||||
m_bg_layer->mark_all_dirty();
|
||||
@ -114,53 +115,60 @@ void dynduke_state::control_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
// bit 0x02 is used on the map screen (fore disable?)
|
||||
// bit 0x01 set when inserting coin.. bg disable?
|
||||
|
||||
if (data&0x1) m_back_enable = 0; else m_back_enable = 1;
|
||||
if (data&0x2) m_fore_enable=0; else m_fore_enable=1;
|
||||
if (data&0x4) m_txt_enable = 0; else m_txt_enable = 1;
|
||||
if (data&0x8) m_sprite_enable=0; else m_sprite_enable=1;
|
||||
m_back_enable = BIT(~data, 0);
|
||||
m_fore_enable = BIT(~data, 1);
|
||||
m_txt_enable = BIT(~data, 2);
|
||||
m_sprite_enable = BIT(~data, 3);
|
||||
|
||||
flip_screen_set(data & 0x40);
|
||||
flip_screen_set(BIT(data, 6));
|
||||
}
|
||||
}
|
||||
|
||||
void dynduke_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect,int pri)
|
||||
void dynduke_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
uint16_t *buffered_spriteram16 = m_spriteram->buffer();
|
||||
int offs,fx,fy,x,y,color,sprite;
|
||||
uint16_t const *const buffered_spriteram16 = m_spriteram->buffer();
|
||||
|
||||
if (!m_sprite_enable) return;
|
||||
|
||||
for (offs = 0x800-4;offs >= 0;offs -= 4)
|
||||
constexpr uint32_t pri_mask[4] = {
|
||||
GFX_PMASK_8 | GFX_PMASK_4 | GFX_PMASK_2, // Untested: does anything use it? Could be behind background
|
||||
GFX_PMASK_8 | GFX_PMASK_4 | GFX_PMASK_2,
|
||||
GFX_PMASK_8 | GFX_PMASK_4,
|
||||
GFX_PMASK_8,
|
||||
};
|
||||
|
||||
for (int offs = 0;offs < 0x800;offs += 4)
|
||||
{
|
||||
/* Don't draw empty sprite table entries */
|
||||
if ((buffered_spriteram16[offs+3] >> 8)!=0xf) continue;
|
||||
if (((buffered_spriteram16[offs+2]>>13)&3)!=pri) continue;
|
||||
uint32_t pri = pri_mask[((buffered_spriteram16[offs+2]>>13)&3)];
|
||||
|
||||
fx= buffered_spriteram16[offs+0]&0x2000;
|
||||
fy= buffered_spriteram16[offs+0]&0x4000;
|
||||
y = buffered_spriteram16[offs+0] & 0xff;
|
||||
x = buffered_spriteram16[offs+2] & 0xff;
|
||||
bool fx = BIT(buffered_spriteram16[offs+0], 13);
|
||||
bool fy = BIT(buffered_spriteram16[offs+0], 14);
|
||||
int32_t y = buffered_spriteram16[offs+0] & 0xff;
|
||||
int32_t x = buffered_spriteram16[offs+2] & 0xff;
|
||||
|
||||
if (buffered_spriteram16[offs+2]&0x100) x=0-(0x100-x);
|
||||
|
||||
color = (buffered_spriteram16[offs+0]>>8)&0x1f;
|
||||
sprite = buffered_spriteram16[offs+1];
|
||||
uint32_t const color = (buffered_spriteram16[offs+0]>>8)&0x1f;
|
||||
uint32_t sprite = buffered_spriteram16[offs+1];
|
||||
sprite &= 0x3fff;
|
||||
|
||||
if (flip_screen()) {
|
||||
x=240-x;
|
||||
y=240-y;
|
||||
if (fx) fx=0; else fx=1;
|
||||
if (fy) fy=0; else fy=1;
|
||||
fx=!fx;
|
||||
fy=!fy;
|
||||
}
|
||||
|
||||
m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
|
||||
m_gfxdecode->gfx(3)->prio_transpen(bitmap,cliprect,
|
||||
sprite,
|
||||
color,fx,fy,x,y,15);
|
||||
color,fx,fy,x,y,
|
||||
screen.priority(),pri,15);
|
||||
}
|
||||
}
|
||||
|
||||
void dynduke_state::draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect, int pri )
|
||||
void dynduke_state::draw_background(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, uint32_t pri_mask)
|
||||
{
|
||||
/* The transparency / palette handling on the background layer is very strange */
|
||||
bitmap_ind16 &bm = m_bg_layer->pixmap();
|
||||
@ -180,16 +188,17 @@ void dynduke_state::draw_background(bitmap_ind16 &bitmap, const rectangle &clipr
|
||||
scrollx = 256 - scrollx;
|
||||
}
|
||||
|
||||
for (int y=0;y<256;y++)
|
||||
for (int y=cliprect.top();y<=cliprect.bottom();y++)
|
||||
{
|
||||
int realy = (y + scrolly) & 0x1ff;
|
||||
int const realy = (y + scrolly) & 0x1ff;
|
||||
uint16_t const *const src = &bm.pix(realy);
|
||||
uint16_t *const dst = &bitmap.pix(y);
|
||||
uint8_t *const pdst = &screen.priority().pix(y);
|
||||
|
||||
|
||||
for (int x=0;x<256;x++)
|
||||
for (int x=cliprect.left();x<=cliprect.right();x++)
|
||||
{
|
||||
int realx = (x + scrollx) & 0x1ff;
|
||||
int const realx = (x + scrollx) & 0x1ff;
|
||||
uint16_t srcdat = src[realx];
|
||||
|
||||
/* 0x01 - data bits
|
||||
@ -208,6 +217,7 @@ void dynduke_state::draw_background(bitmap_ind16 &bitmap, const rectangle &clipr
|
||||
|
||||
srcdat = (srcdat & 0x000f) | ((srcdat & 0xffc0) >> 2);
|
||||
dst[x] = srcdat;
|
||||
pdst[x] |= pri_mask;
|
||||
}
|
||||
|
||||
|
||||
@ -223,16 +233,11 @@ uint32_t dynduke_state::screen_update(screen_device &screen, bitmap_ind16 &bitma
|
||||
m_fg_layer->enable(m_fore_enable);
|
||||
m_tx_layer->enable(m_txt_enable);
|
||||
|
||||
|
||||
draw_background(bitmap, cliprect,0x00);
|
||||
draw_sprites(bitmap,cliprect,0); // Untested: does anything use it? Could be behind background
|
||||
draw_sprites(bitmap,cliprect,1);
|
||||
draw_background(bitmap, cliprect,0x20);
|
||||
|
||||
draw_sprites(bitmap,cliprect,2);
|
||||
m_fg_layer->draw(screen, bitmap, cliprect, 0,0);
|
||||
draw_sprites(bitmap,cliprect,3);
|
||||
m_tx_layer->draw(screen, bitmap, cliprect, 0,0);
|
||||
draw_background(screen, bitmap, cliprect, 0x00, 1);
|
||||
draw_background(screen, bitmap, cliprect, 0x20, 2);
|
||||
m_fg_layer->draw(screen, bitmap, cliprect, 0,4);
|
||||
m_tx_layer->draw(screen, bitmap, cliprect, 0,8);
|
||||
draw_sprites(screen, bitmap, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user