MAME:NEOGEO 把高频sprite频处理从优化后的指针化的unsafe数组,循环直接改为指针推进,避免重新计算地址,争取到了一些性能

This commit is contained in:
sin365 2025-11-17 01:29:37 +08:00
parent 4914db1b54
commit 96039886f4
2 changed files with 119 additions and 84 deletions

View File

@ -354,7 +354,8 @@ namespace MAME.Core
/// <param name="scanline"></param> /// <param name="scanline"></param>
unsafe private static void draw_sprites(int iBitmap, int scanline) unsafe private static void draw_sprites(int iBitmap, int scanline)
{ {
int pixel_addr_offsety = scanline;
int pixel_addr_offsety_x_384 = pixel_addr_offsety * 384;
fixed (ushort* videoramPtr = &neogeo_videoram[0]) fixed (ushort* videoramPtr = &neogeo_videoram[0])
//fixed (int* bitmapbasePtr = &Video.bitmapbaseN_Ptrs[iBitmap][0]) //fixed (int* bitmapbasePtr = &Video.bitmapbaseN_Ptrs[iBitmap][0])
fixed (byte* spriteGfxPtr = &sprite_gfx[0]) fixed (byte* spriteGfxPtr = &sprite_gfx[0])
@ -499,55 +500,70 @@ namespace MAME.Core
{ {
x_inc = 1; x_inc = 1;
} }
int pixel_addr_offsetx, pixel_addr_offsety; //int pixel_addr_offsetx;
int pixel_addr_offsety_x_384 = scanline * 384;
if (x <= 0x01f0) if (x <= 0x01f0)
{ {
int i; int i;
pixel_addr_offsetx = x + NEOGEO_HBEND; //pixel_addr_offsetx = x + NEOGEO_HBEND;
pixel_addr_offsety = scanline; int* pixel_ptr = &bitmapbase[pixel_addr_offsety_x_384 + x + NEOGEO_HBEND];
int* zoom_x_tablePtr = &zoom_x_tables[zoom_x_table_offset];
byte* spriteGfx_offset_Ptr = &spriteGfx[gfx_offset];
for (i = 0; i < 0x10; i++) for (i = 0; i < 0x10; i++)
{ {
//if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0) //if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
if (zoom_x_tables[zoom_x_table_offset] != 0) //if (zoom_x_tables[zoom_x_table_offset] != 0)
if (*zoom_x_tablePtr != 0)
{ {
//if (sprite_gfx[gfx_offset] != 0) //if (sprite_gfx[gfx_offset] != 0)
if (spriteGfx[gfx_offset] != 0) //if (spriteGfx[gfx_offset] != 0)
if (*spriteGfx_offset_Ptr != 0)
{ {
//Video.bitmapbaseN_Ptrs[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]]; //Video.bitmapbaseN_Ptrs[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
bitmapbase[pixel_addr_offsety_x_384 + pixel_addr_offsetx] = pens[line_pens_offset + spriteGfx[gfx_offset]]; //bitmapbase[pixel_addr_offsety_x_384 + pixel_addr_offsetx] = pens[line_pens_offset + spriteGfx[gfx_offset]];
*pixel_ptr = pens[line_pens_offset + *spriteGfx_offset_Ptr];
} }
pixel_addr_offsetx++; //pixel_addr_offsetx++;
pixel_ptr++;
} }
zoom_x_table_offset++; //zoom_x_table_offset++;
gfx_offset += x_inc; zoom_x_tablePtr++;
//gfx_offset += x_inc;
spriteGfx_offset_Ptr += x_inc;
} }
} }
else else
{ {
int i; int i;
int x_save = x; int x_save = x;
pixel_addr_offsetx = NEOGEO_HBEND; //pixel_addr_offsetx = NEOGEO_HBEND;
pixel_addr_offsety = scanline; int* pixel_ptr = &bitmapbase[pixel_addr_offsety_x_384 + NEOGEO_HBEND];
int* zoom_x_tablePtr = &zoom_x_tables[zoom_x_table_offset];
byte* spriteGfx_offset_Ptr = &spriteGfx[gfx_offset];
for (i = 0; i < 0x10; i++) for (i = 0; i < 0x10; i++)
{ {
//if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0) //if (zoom_x_tables[zoom_x, zoom_x_table_offset] != 0)
if (zoom_x_tables[zoom_x_table_offset] != 0) //if (zoom_x_tables[zoom_x_table_offset] != 0)
if (*zoom_x_tablePtr != 0)
{ {
if (x >= 0x200) if (x >= 0x200)
{ {
//if (sprite_gfx[gfx_offset] != 0) //if (sprite_gfx[gfx_offset] != 0)
if (spriteGfx[gfx_offset] != 0) //if (spriteGfx[gfx_offset] != 0)
if (*spriteGfx_offset_Ptr != 0)
{ {
//Video.bitmapbaseN_Ptrs[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]]; //Video.bitmapbaseN_Ptrs[iBitmap][pixel_addr_offsety * 384 + pixel_addr_offsetx] = pens[line_pens_offset + sprite_gfx[gfx_offset]];
bitmapbase[pixel_addr_offsety_x_384 + pixel_addr_offsetx] = pens[line_pens_offset + spriteGfx[gfx_offset]]; //bitmapbase[pixel_addr_offsety_x_384 + pixel_addr_offsetx] = pens[line_pens_offset + spriteGfx[gfx_offset]];
*pixel_ptr = pens[line_pens_offset + *spriteGfx_offset_Ptr];
} }
pixel_addr_offsetx++; //pixel_addr_offsetx++;
pixel_ptr++;
} }
x++; x++;
} }
zoom_x_table_offset++; //zoom_x_table_offset++;
gfx_offset += x_inc; zoom_x_tablePtr++;
//gfx_offset += x_inc;
spriteGfx_offset_Ptr += x_inc;
} }
x = x_save; x = x_save;
} }
@ -796,6 +812,13 @@ namespace MAME.Core
static int[] garouoffsets = new int[32]; static int[] garouoffsets = new int[32];
private static void draw_fixed_layer(int iBitmap, int scanline) private static void draw_fixed_layer(int iBitmap, int scanline)
{ {
fixed (ushort* videoramPtr = &neogeo_videoram[0])
{
int* bitmapbase = &Video.bitmapbaseN_Ptrs[iBitmap][0];
int scanline_x_384 = 384 * scanline;
int i, j, x, y; int i, j, x, y;
byte[] gfx_base; byte[] gfx_base;
//int[] garouoffsets = new int[32], pix_offsets = new int[] { 0x10, 0x18, 0x00, 0x08 }; //int[] garouoffsets = new int[32], pix_offsets = new int[] { 0x10, 0x18, 0x00, 0x08 };
@ -824,35 +847,39 @@ namespace MAME.Core
y = 0; y = 0;
while (y < 32) while (y < 32)
{ {
if (neogeo_videoram[0x7500 + k] == 0x0200 && (neogeo_videoram[0x7580 + k] & 0xff00) == 0xff00) if (videoramPtr[0x7500 + k] == 0x0200 && (videoramPtr[0x7580 + k] & 0xff00) == 0xff00)
{ {
garoubank = neogeo_videoram[0x7580 + k] & 3; garoubank = videoramPtr[0x7580 + k] & 3;
garouoffsets[y++] = garoubank; garouoffsets[y++] = garoubank;
} }
garouoffsets[y++] = garoubank; garouoffsets[y++] = garoubank;
k += 2; k += 2;
} }
} }
y = scanline >> 3;
int temp_yvale = 0x7500 + ((y - 1) & 31);
for (x = 0; x < 40; x++) for (x = 0; x < 40; x++)
{ {
code_and_palette = neogeo_videoram[video_data_offset]; code_and_palette = videoramPtr[video_data_offset];
code = code_and_palette & 0x0fff; code = code_and_palette & 0x0fff;
if (banked) if (banked)
{ {
y = scanline >> 3; //y = scanline >> 3;
switch (neogeo_fixed_layer_bank_type) switch (neogeo_fixed_layer_bank_type)
{ {
case 1: case 1:
code += 0x1000 * (garouoffsets[(y - 2) & 31] ^ 3); code += 0x1000 * (garouoffsets[(y - 2) & 31] ^ 3);
break; break;
case 2: case 2:
code += 0x1000 * (((neogeo_videoram[0x7500 + ((y - 1) & 31) + 32 * (x / 6)] >> (5 - (x % 6)) * 2) & 3) ^ 3); code += 0x1000 * (((videoramPtr[temp_yvale + 32 * (x / 6)] >> (5 - (x % 6)) * 2) & 3) ^ 3);
break; break;
} }
} }
data = 0; data = 0;
gfx_offset = ((code << 5) | (scanline & 0x07)) & addr_mask; gfx_offset = ((code << 5) | (scanline & 0x07)) & addr_mask;
char_pens_offset = code_and_palette >> 12 << 4; char_pens_offset = code_and_palette >> 12 << 4;
int temp_xval = scanline_x_384 + 30 + x * 8;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
if ((i & 0x01) != 0) if ((i & 0x01) != 0)
@ -865,12 +892,13 @@ namespace MAME.Core
} }
if ((data & 0x0f) != 0) if ((data & 0x0f) != 0)
{ {
Video.bitmapbaseN_Ptrs[iBitmap][384 * scanline + 30 + x * 8 + i] = pens[char_pens_offset + (data & 0x0f)]; bitmapbase[/*scanline_x_384 + 30 + x * 8*/temp_xval + i] = pens[char_pens_offset + (data & 0x0f)];
} }
} }
video_data_offset += 0x20; video_data_offset += 0x20;
} }
} }
}
private static void optimize_sprite_data() private static void optimize_sprite_data()
{ {
sprite_gfx_address_mask = (uint)(spritesromLength * 2 - 1); sprite_gfx_address_mask = (uint)(spritesromLength * 2 - 1);

View File

@ -544,6 +544,9 @@ namespace MAME.Core
} }
OPN.refresh_fc_eg_chan(F2610.OPN.type, 4); OPN.refresh_fc_eg_chan(F2610.OPN.type, 4);
OPN.refresh_fc_eg_chan(F2610.OPN.type, 5); OPN.refresh_fc_eg_chan(F2610.OPN.type, 5);
int* streamoutput_0_offset_ptr = &Sound.ym2610stream.streamoutput_Ptrs[0][offset];
int* streamoutput_1_offset_ptr = &Sound.ym2610stream.streamoutput_Ptrs[1][offset];
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {
OPN.advance_lfo(); OPN.advance_lfo();
@ -601,8 +604,12 @@ namespace MAME.Core
lt = Math.Max(lt, -32768); lt = Math.Max(lt, -32768);
rt = Math.Min(rt, 32767); rt = Math.Min(rt, 32767);
rt = Math.Max(rt, -32768); rt = Math.Max(rt, -32768);
Sound.ym2610stream.streamoutput_Ptrs[0][offset + i] = lt; //Sound.ym2610stream.streamoutput_Ptrs[0][offset + i] = lt;
Sound.ym2610stream.streamoutput_Ptrs[1][offset + i] = rt; *streamoutput_0_offset_ptr = lt;
streamoutput_0_offset_ptr++;
//Sound.ym2610stream.streamoutput_Ptrs[1][offset + i] = rt;
*streamoutput_1_offset_ptr = rt;
streamoutput_1_offset_ptr++;
} }
} }
public void ym2610b_update_one(int offset, int length) public void ym2610b_update_one(int offset, int length)