From 693a75e2fc22301c2582538ddf3494365d45f9fa Mon Sep 17 00:00:00 2001 From: etabeta78 Date: Fri, 29 Apr 2016 06:01:05 +0200 Subject: [PATCH] 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. --- src/devices/bus/neogeo/slot.cpp | 54 ++++++++++++++++++++++++++++++++- src/devices/bus/neogeo/slot.h | 20 ++++++++++-- src/mame/drivers/neogeo.cpp | 5 ++- src/mame/video/neogeo_spr.cpp | 46 ++++++++++++++++------------ src/mame/video/neogeo_spr.h | 4 ++- 5 files changed, 104 insertions(+), 25 deletions(-) diff --git a/src/devices/bus/neogeo/slot.cpp b/src/devices/bus/neogeo/slot.cpp index cc9abafe17a..b7ceb2d12cf 100644 --- a/src/devices/bus/neogeo/slot.cpp +++ b/src/devices/bus/neogeo/slot.cpp @@ -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; } } diff --git a/src/devices/bus/neogeo/slot.h b/src/devices/bus/neogeo/slot.h index d5b14700599..3bb01d8c359 100644 --- a/src/devices/bus/neogeo/slot.h +++ b/src/devices/bus/neogeo/slot.h @@ -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 m_rom; @@ -155,16 +161,19 @@ protected: std::vector m_ym; std::vector m_ymdelta; std::vector m_audiocrypt; - + + std::vector 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; } diff --git a/src/mame/drivers/neogeo.cpp b/src/mame/drivers/neogeo.cpp index 908d4029915..6c8fbc79eaa 100644 --- a/src/mame/drivers/neogeo.cpp +++ b/src/mame/drivers/neogeo.cpp @@ -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 diff --git a/src/mame/video/neogeo_spr.cpp b/src/mame/video/neogeo_spr.cpp index eef5c9e8be0..93a9ca1e68e 100644 --- a/src/mame/video/neogeo_spr.cpp +++ b/src/mame/video/neogeo_spr.cpp @@ -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]; diff --git a/src/mame/video/neogeo_spr.h b/src/mame/video/neogeo_spr.h index 2fe3a25c202..6be770b9c3b 100644 --- a/src/mame/video/neogeo_spr.h +++ b/src/mame/video/neogeo_spr.h @@ -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 m_sprite_gfx; UINT8* m_spritegfx8;