made the transition between different carts in the multislot driver

smooth again. when launching game-specific drivers, sprites are
in any case optimized only once before emulation starts, so that
yesterday changes made no difference, but we care about 6-slot
neogeo too. ;-) nw.
This commit is contained in:
etabeta78 2016-04-29 06:01:05 +02:00
parent 6bbd290d31
commit 693a75e2fc
5 changed files with 104 additions and 25 deletions

View File

@ -26,7 +26,6 @@ device_neogeo_cart_interface::device_neogeo_cart_interface(const machine_config
m_region_audio(*this, "^audiocpu"),
m_region_audiocrypt(*this, "^audiocrypt"),
m_region_spr(*this, "^sprites"),
m_region_spr_opt(*this, "^spr_opt"),
m_region_ym(*this, "^ymsnd"),
m_region_ymd(*this, "^ymsnd.deltat")
{
@ -40,6 +39,55 @@ device_neogeo_cart_interface::~device_neogeo_cart_interface()
{
}
UINT32 device_neogeo_cart_interface::get_region_mask(UINT8* rgn, UINT32 rgn_size)
{
// get mask based on the length rounded up to the nearest power of 2
UINT32 mask = 0xffffffff;
UINT32 len = rgn_size;
for (UINT32 bit = 0x80000000; bit != 0; bit >>= 1)
{
if ((len * 2 - 1) & bit)
break;
mask >>= 1;
}
return mask;
}
void device_neogeo_cart_interface::optimize_sprites(UINT8* region_sprites, UINT32 region_sprites_size)
{
// convert the sprite graphics data into a format that allows faster blitting
UINT32 spritegfx_address_mask = get_region_mask(region_sprites, region_sprites_size);
UINT8 *src = region_sprites;
m_sprites_opt.resize(spritegfx_address_mask + 1);
UINT8 *dest = &m_sprites_opt[0];
for (unsigned i = 0; i < region_sprites_size; i += 0x80, src += 0x80)
{
for (unsigned y = 0; y < 0x10; y++)
{
for (unsigned x = 0; x < 8; x++)
{
*(dest++) = (((src[0x43 | (y << 2)] >> x) & 0x01) << 3) |
(((src[0x41 | (y << 2)] >> x) & 0x01) << 2) |
(((src[0x42 | (y << 2)] >> x) & 0x01) << 1) |
(((src[0x40 | (y << 2)] >> x) & 0x01) << 0);
}
for (unsigned x = 0; x < 8; x++)
{
*(dest++) = (((src[0x03 | (y << 2)] >> x) & 0x01) << 3) |
(((src[0x01 | (y << 2)] >> x) & 0x01) << 2) |
(((src[0x02 | (y << 2)] >> x) & 0x01) << 1) |
(((src[0x00 | (y << 2)] >> x) & 0x01) << 0);
}
}
}
}
//**************************************************************************
// LIVE DEVICE
@ -262,6 +310,10 @@ bool neogeo_cart_slot_device::call_load()
m_cart->get_audio_base(), m_cart->get_audio_size(),
m_cart->get_audiocrypt_base(), m_cart->get_audiocrypt_size());
// SPEED UP WORKAROUND: to speed up sprite drawing routine, let us store the sprite data in
// a different format (we then always access such alt format for drawing)
m_cart->optimize_sprites(m_cart->get_sprites_base(), m_cart->get_sprites_size());
return IMAGE_INIT_PASS;
}
}

View File

@ -146,6 +146,12 @@ public:
UINT8* get_region_ymdelta_base() { if (m_region_ymd.found()) return m_region_ymd->base(); return nullptr; }
UINT32 get_region_ymdelta_size() { if (m_region_ymd.found()) return m_region_ymd->bytes(); return 0; }
// this is only used to setup optimized sprites when loading on multi-slot drivers from softlist
// therefore, we do not need a separate region accessor!
UINT8* get_sprites_opt_base() { return &m_sprites_opt[0]; }
UINT32 get_sprites_opt_size() { return m_sprites_opt.size(); }
void optimize_sprites(UINT8* region_sprites, UINT32 region_sprites_size);
protected:
// these are allocated when loading from softlist
std::vector<UINT16> m_rom;
@ -155,16 +161,19 @@ protected:
std::vector<UINT8> m_ym;
std::vector<UINT8> m_ymdelta;
std::vector<UINT8> m_audiocrypt;
std::vector<UINT8> m_sprites_opt;
// these replace m_rom, etc. above for non-user configurable carts!
optional_memory_region m_region_rom;
optional_memory_region m_region_fixed;
optional_memory_region m_region_audio;
optional_memory_region m_region_audiocrypt;
optional_memory_region m_region_spr;
optional_memory_region m_region_spr_opt;
optional_memory_region m_region_ym;
optional_memory_region m_region_ymd;
UINT32 get_region_mask(UINT8* rgn, UINT32 rgn_size);
};
@ -298,6 +307,13 @@ public:
return 0;
}
UINT8* get_sprites_opt_base() {
if (m_cart) return m_cart->get_sprites_opt_base(); else return nullptr;
}
UINT32 get_sprites_opt_size() {
if (m_cart) return m_cart->get_sprites_opt_size(); else return 0;
}
int get_fixed_bank_type(void) { if (m_cart) return m_cart->get_fixed_bank_type(); return 0; }
UINT32 get_bank_base(UINT16 sel) { if (m_cart) return m_cart->get_bank_base(sel); return 0; }
UINT32 get_special_bank() { if (m_cart) return m_cart->get_special_bank(); return 0; }

View File

@ -1142,7 +1142,10 @@ void neogeo_state::init_sprites()
{
m_sprgen->set_sprite_region(m_slots[m_curr_slot]->get_sprites_base(), m_slots[m_curr_slot]->get_sprites_size());
m_sprgen->set_fixed_regions(m_slots[m_curr_slot]->get_fixed_base(), m_slots[m_curr_slot]->get_fixed_size(), m_region_fixedbios);
m_sprgen->optimize_sprite_data();
if (!m_slots[m_curr_slot]->user_loadable())
m_sprgen->optimize_sprite_data();
else
m_sprgen->set_optimized_sprite_data(m_slots[m_curr_slot]->get_sprites_opt_base(), m_slots[m_curr_slot]->get_sprites_opt_size() - 1);
m_sprgen->m_fixed_layer_bank_type = m_slots[m_curr_slot]->get_fixed_bank_type();
}
else

View File

@ -35,8 +35,6 @@ void neosprite_base_device::device_start()
create_sprite_line_timer();
create_auto_animation_timer();
/* initialize values that are not modified on a reset */
m_vram_offset = 0;
m_vram_read_buffer = 0;
@ -79,7 +77,7 @@ void neosprite_base_device::device_reset()
*
*************************************/
void neosprite_base_device::set_videoram_offset( UINT16 data )
void neosprite_base_device::set_videoram_offset(UINT16 data)
{
m_vram_offset = (data & 0x8000 ? data & 0x87ff : data);
@ -88,13 +86,13 @@ void neosprite_base_device::set_videoram_offset( UINT16 data )
}
UINT16 neosprite_base_device::get_videoram_data( )
UINT16 neosprite_base_device::get_videoram_data()
{
return m_vram_read_buffer;
}
void neosprite_base_device::set_videoram_data( UINT16 data)
void neosprite_base_device::set_videoram_data(UINT16 data)
{
m_videoram[m_vram_offset] = data;
@ -103,13 +101,13 @@ void neosprite_base_device::set_videoram_data( UINT16 data)
}
void neosprite_base_device::set_videoram_modulo( UINT16 data)
void neosprite_base_device::set_videoram_modulo(UINT16 data)
{
m_vram_modulo = data;
}
UINT16 neosprite_base_device::get_videoram_modulo( )
UINT16 neosprite_base_device::get_videoram_modulo()
{
return m_vram_modulo;
}
@ -122,19 +120,19 @@ UINT16 neosprite_base_device::get_videoram_modulo( )
*
*************************************/
void neosprite_base_device::set_auto_animation_speed( UINT8 data)
void neosprite_base_device::set_auto_animation_speed(UINT8 data)
{
m_auto_animation_speed = data;
}
void neosprite_base_device::set_auto_animation_disabled( UINT8 data)
void neosprite_base_device::set_auto_animation_disabled(UINT8 data)
{
m_auto_animation_disabled = data;
}
UINT8 neosprite_base_device::neogeo_get_auto_animation_counter( )
UINT8 neosprite_base_device::neogeo_get_auto_animation_counter()
{
return m_auto_animation_counter;
}
@ -154,13 +152,13 @@ TIMER_CALLBACK_MEMBER(neosprite_base_device::auto_animation_timer_callback)
}
void neosprite_base_device::create_auto_animation_timer( )
void neosprite_base_device::create_auto_animation_timer()
{
m_auto_animation_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(neosprite_base_device::auto_animation_timer_callback),this));
}
void neosprite_base_device::start_auto_animation_timer( )
void neosprite_base_device::start_auto_animation_timer()
{
m_auto_animation_timer->adjust(m_screen->time_until_pos(NEOGEO_VSSTART));
}
@ -173,13 +171,13 @@ void neosprite_base_device::start_auto_animation_timer( )
*
*************************************/
void neosprite_base_device::neogeo_set_fixed_layer_source( UINT8 data )
void neosprite_base_device::neogeo_set_fixed_layer_source(UINT8 data)
{
m_fixed_layer_source = data;
}
void neosprite_base_device::draw_fixed_layer( bitmap_rgb32 &bitmap, int scanline )
void neosprite_base_device::draw_fixed_layer(bitmap_rgb32 &bitmap, int scanline)
{
int x;
@ -307,7 +305,7 @@ inline bool neosprite_base_device::sprite_on_scanline(int scanline, int y, int r
void neosprite_base_device::draw_sprites( bitmap_rgb32 &bitmap, int scanline )
void neosprite_base_device::draw_sprites(bitmap_rgb32 &bitmap, int scanline)
{
int sprite_index;
int max_sprite_index;
@ -497,7 +495,7 @@ void neosprite_base_device::draw_sprites( bitmap_rgb32 &bitmap, int scanline )
}
void neosprite_base_device::parse_sprites( int scanline )
void neosprite_base_device::parse_sprites(int scanline)
{
UINT16 sprite_number;
int y = 0;
@ -566,13 +564,13 @@ TIMER_CALLBACK_MEMBER(neosprite_base_device::sprite_line_timer_callback)
}
void neosprite_base_device::create_sprite_line_timer( )
void neosprite_base_device::create_sprite_line_timer()
{
m_sprite_line_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(neosprite_base_device::sprite_line_timer_callback),this));
}
void neosprite_base_device::start_sprite_line_timer( )
void neosprite_base_device::start_sprite_line_timer()
{
m_sprite_line_timer->adjust(m_screen->time_until_pos(0));
}
@ -610,6 +608,10 @@ void neosprite_base_device::optimize_sprite_data()
return;
}
void neosprite_base_device::set_optimized_sprite_data(UINT8* sprdata, UINT32 mask)
{
return;
}
// these are for passing in pointers from the main system
void neosprite_base_device::set_sprite_region(UINT8* region_sprites, UINT32 region_sprites_size)
@ -653,8 +655,6 @@ neosprite_regular_device::neosprite_regular_device(const machine_config &mconfig
{
}
void neosprite_regular_device::set_sprite_region(UINT8* region_sprites, UINT32 region_sprites_size)
{
m_region_sprites = region_sprites;
@ -750,6 +750,12 @@ void neosprite_optimized_device::optimize_sprite_data()
m_spritegfx8 = &m_sprite_gfx[0];
}
void neosprite_optimized_device::set_optimized_sprite_data(UINT8* sprdata, UINT32 mask)
{
m_sprite_gfx_address_mask = mask;
m_spritegfx8 = &sprdata[0];
}
inline void neosprite_optimized_device::draw_pixel(int romaddr, UINT32* dst, const pen_t *line_pens)
{
const UINT8 gfx = m_spritegfx8[romaddr];

View File

@ -25,7 +25,8 @@ public:
// neosprite_base_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual void optimize_sprite_data();
virtual void set_optimized_sprite_data(UINT8* sprdata, UINT32 mask);
virtual void draw_fixed_layer_2pixels(UINT32*&pixel_addr, int offset, UINT8* gfx_base, const pen_t* char_pens);
void draw_fixed_layer(bitmap_rgb32 &bitmap, int scanline);
void set_videoram_offset(UINT16 data);
@ -109,6 +110,7 @@ class neosprite_optimized_device : public neosprite_base_device
public:
neosprite_optimized_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual void optimize_sprite_data() override;
virtual void set_optimized_sprite_data(UINT8* sprdata, UINT32 mask) override;
virtual void draw_pixel(int romaddr, UINT32* dst, const pen_t *line_pens) override;
std::vector<UINT8> m_sprite_gfx;
UINT8* m_spritegfx8;