From 1c52444e04fc8bb59158d528027bd9f11417500f Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 21 Mar 2011 01:49:20 +0000 Subject: [PATCH] [NES] here, have a cup of speedup --- .../Consoles/Nintendo/NES/APU.cs | 9 +- .../Consoles/Nintendo/NES/Core.cs | 31 ++-- .../Consoles/Nintendo/NES/NES.cs | 19 ++- .../Consoles/Nintendo/NES/PPU.regs.cs | 4 +- .../Consoles/Nintendo/NES/PPU.run.cs | 2 +- .../Consoles/Nintendo/NES/Palettes.cs | 132 +++++++++--------- BizHawk.MultiClient/NEStools/NESPPU.cs | 4 - BizHawk.MultiClient/NEStools/PaletteViewer.cs | 2 +- 8 files changed, 93 insertions(+), 110 deletions(-) diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/APU.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/APU.cs index 99fbf165bd..34cd3d92d8 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/APU.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/APU.cs @@ -566,12 +566,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo EmitSample(mix); sequencer_tick(); - - //since the units run concurrently, the APU frame sequencer - //is ran last because - //it can change the ouput values of the pulse/triangle channels, - //we want the - //changes to affect it on the *next* cycle. + //since the units run concurrently, the APU frame sequencer is ran last because + //it can change the ouput values of the pulse/triangle channels + //we want the changes to affect it on the *next* cycle. } double accumulate; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs index 5a99243c60..98801500cb 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs @@ -32,7 +32,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo //user configuration int[,] palette = new int[64,3]; - int[] palette_compiled = new int[64]; + int[] palette_compiled = new int[64*8]; IPortDevice[] ports; public void HardReset() @@ -184,32 +184,21 @@ namespace BizHawk.Emulation.Consoles.Nintendo void SetPalette(int[,] pal) { Array.Copy(pal,palette,64*3); - for(int i=0;i<64;i++) + for(int i=0;i<64*8;i++) { - int r = palette[i, 0]; - int g = palette[i, 1]; - int b = palette[i, 2]; + int d = i >> 6; + int c = i & 63; + if (d >= 7) continue; + int r = palette[c, 0]; + int g = palette[c, 1]; + int b = palette[c, 2]; + Palettes.ApplyDeemphasis(ref r, ref g, ref b, d); palette_compiled[i] = (int)unchecked((int)0xFF000000 | (r << 16) | (g << 8) | b); } } - /// - /// Converts an internal NES core pixel value (includes deemph bits) to an rgb int. - /// - int CompleteDecodeColor(int pixel) - { - int deemph = pixel >> 8; - int palentry = pixel & 0xFF; - int r = palette[palentry, 0]; - int g = palette[palentry, 1]; - int b = palette[palentry, 2]; - Palettes.ApplyDeemphasis(ref r, ref g, ref b, deemph); - return (r << 16) | (g << 8) | b; - } - - /// - /// looks up an internal NES pixel value to an rgb int. + /// looks up an internal NES pixel value to an rgb int (applying the core's current palette and assuming no deemph) /// public int LookupColor(int pixel) { diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs index ab4fc9b887..5cde42d723 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs @@ -34,6 +34,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo { BootGodDB.Initialize(); SetPalette(Palettes.FCEUX_Standard); + videoProvider = new MyVideoProvider(this); } NESWatch GetWatch(NESWatch.EDomain domain, int address) @@ -124,25 +125,23 @@ namespace BizHawk.Emulation.Consoles.Nintendo this.emu = emu; } + int[] pixels = new int[256 * 240]; public int[] GetVideoBuffer() { //why is it faster to continually reallocate? i have no idea. - int[] pixels = new int[256 * 240]; - int i = 0; - for (int y = 0; y < 240; y++) - for (int x = 0; x < 256; x++) - { - int pixel = emu.ppu.xbuf[i]; - pixels[i] = unchecked(emu.CompleteDecodeColor(pixel) | (int)0xFF000000); - i++; - } + //TODO - we could recalculate this on the fly (and invalidate/recalculate it when the palette is changed) + for (int i = 0; i < 256*240; i++) + { + pixels[i] = emu.palette_compiled[emu.ppu.xbuf[i]]; + } return pixels; } public int BufferWidth { get { return 256; } } public int BufferHeight { get { return 240; } } public int BackgroundColor { get { return 0; } } } - public IVideoProvider VideoProvider { get { return new MyVideoProvider(this); } } + public IVideoProvider VideoProvider { get { return videoProvider; } } + MyVideoProvider videoProvider; public ISoundProvider SoundProvider { get { return apu; } } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs index 27ca5b934f..8d3e476e97 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs @@ -31,7 +31,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo public Bit intense_blue; //Intensify blues (and darken other colors) public Bit intense_red; //Intensify reds (and darken other colors) - public int intensity_lsl_8; //an optimization.. + public int intensity_lsl_6; //an optimization.. public bool PPUON { get { return show_bg || show_obj; } } @@ -51,7 +51,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo intense_green = (value >> 5) & 1; intense_blue = (value >> 6) & 1; intense_red = (value >> 7) & 1; - intensity_lsl_8 = ((value >> 5) & 7)<<8; + intensity_lsl_6 = ((value >> 5) & 7)<<6; } } } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs index e2b196083b..da630a5a6e 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs @@ -70,7 +70,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo short PaletteAdjustPixel(int pixel) { //tack on the deemph bits. THESE MAY BE ORDERED WRONG. PLEASE CHECK IN THE PALETTE CODE - return (short)(pixel| reg_2001.intensity_lsl_8); + return (short)(pixel | reg_2001.intensity_lsl_6); } const int kLineTime = 341; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Palettes.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Palettes.cs index f3c3450036..ef8c1391a5 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Palettes.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Palettes.cs @@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo static float[] gtmul = { 0.915f, 1.086f, 0.98f, 1.026f, 0.908f, 0.987f, 0.75f }; static float[] btmul = { 0.743f, 0.882f, 0.653f, 1.277f, 0.979f, 0.101f, 0.75f }; - public static void ApplyDeemphasis(ref int r, ref int g, ref int b, int deemph_bits) + public static void ApplyDeemphasis(ref int r, ref int g, ref int b, int deemph_bits) { //DEEMPH BITS MAY BE ORDERED WRONG. PLEASE CHECK if (deemph_bits == 0) return; @@ -28,72 +28,74 @@ namespace BizHawk.Emulation.Consoles.Nintendo if (g > 0xFF) g = 0xFF; if (b > 0xFF) b = 0xFF; } + + const int SHIFT = 2; public static int[,] FCEUX_Standard = new int[,] { - { 0x1D<<2, 0x1D<<2, 0x1D<<2 }, /* Value 0 */ - { 0x09<<2, 0x06<<2, 0x23<<2 }, /* Value 1 */ - { 0x00<<2, 0x00<<2, 0x2A<<2 }, /* Value 2 */ - { 0x11<<2, 0x00<<2, 0x27<<2 }, /* Value 3 */ - { 0x23<<2, 0x00<<2, 0x1D<<2 }, /* Value 4 */ - { 0x2A<<2, 0x00<<2, 0x04<<2 }, /* Value 5 */ - { 0x29<<2, 0x00<<2, 0x00<<2 }, /* Value 6 */ - { 0x1F<<2, 0x02<<2, 0x00<<2 }, /* Value 7 */ - { 0x10<<2, 0x0B<<2, 0x00<<2 }, /* Value 8 */ - { 0x00<<2, 0x11<<2, 0x00<<2 }, /* Value 9 */ - { 0x00<<2, 0x14<<2, 0x00<<2 }, /* Value 10 */ - { 0x00<<2, 0x0F<<2, 0x05<<2 }, /* Value 11 */ - { 0x06<<2, 0x0F<<2, 0x17<<2 }, /* Value 12 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 13 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 14 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 15 */ - { 0x2F<<2, 0x2F<<2, 0x2F<<2 }, /* Value 16 */ - { 0x00<<2, 0x1C<<2, 0x3B<<2 }, /* Value 17 */ - { 0x08<<2, 0x0E<<2, 0x3B<<2 }, /* Value 18 */ - { 0x20<<2, 0x00<<2, 0x3C<<2 }, /* Value 19 */ - { 0x2F<<2, 0x00<<2, 0x2F<<2 }, /* Value 20 */ - { 0x39<<2, 0x00<<2, 0x16<<2 }, /* Value 21 */ - { 0x36<<2, 0x0A<<2, 0x00<<2 }, /* Value 22 */ - { 0x32<<2, 0x13<<2, 0x03<<2 }, /* Value 23 */ - { 0x22<<2, 0x1C<<2, 0x00<<2 }, /* Value 24 */ - { 0x00<<2, 0x25<<2, 0x00<<2 }, /* Value 25 */ - { 0x00<<2, 0x2A<<2, 0x00<<2 }, /* Value 26 */ - { 0x00<<2, 0x24<<2, 0x0E<<2 }, /* Value 27 */ - { 0x00<<2, 0x20<<2, 0x22<<2 }, /* Value 28 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 29 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 30 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 31 */ - { 0x3F<<2, 0x3F<<2, 0x3F<<2 }, /* Value 32 */ - { 0x0F<<2, 0x2F<<2, 0x3F<<2 }, /* Value 33 */ - { 0x17<<2, 0x25<<2, 0x3F<<2 }, /* Value 34 */ - { 0x10<<2, 0x22<<2, 0x3F<<2 }, /* Value 35 */ - { 0x3D<<2, 0x1E<<2, 0x3F<<2 }, /* Value 36 */ - { 0x3F<<2, 0x1D<<2, 0x2D<<2 }, /* Value 37 */ - { 0x3F<<2, 0x1D<<2, 0x18<<2 }, /* Value 38 */ - { 0x3F<<2, 0x26<<2, 0x0E<<2 }, /* Value 39 */ - { 0x3C<<2, 0x2F<<2, 0x0F<<2 }, /* Value 40 */ - { 0x20<<2, 0x34<<2, 0x04<<2 }, /* Value 41 */ - { 0x13<<2, 0x37<<2, 0x12<<2 }, /* Value 42 */ - { 0x16<<2, 0x3E<<2, 0x26<<2 }, /* Value 43 */ - { 0x00<<2, 0x3A<<2, 0x36<<2 }, /* Value 44 */ - { 0x1E<<2, 0x1E<<2, 0x1E<<2 }, /* Value 45 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 46 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 47 */ - { 0x3F<<2, 0x3F<<2, 0x3F<<2 }, /* Value 48 */ - { 0x2A<<2, 0x39<<2, 0x3F<<2 }, /* Value 49 */ - { 0x31<<2, 0x35<<2, 0x3F<<2 }, /* Value 50 */ - { 0x35<<2, 0x32<<2, 0x3F<<2 }, /* Value 51 */ - { 0x3F<<2, 0x31<<2, 0x3F<<2 }, /* Value 52 */ - { 0x3F<<2, 0x31<<2, 0x36<<2 }, /* Value 53 */ - { 0x3F<<2, 0x2F<<2, 0x2C<<2 }, /* Value 54 */ - { 0x3F<<2, 0x36<<2, 0x2A<<2 }, /* Value 55 */ - { 0x3F<<2, 0x39<<2, 0x28<<2 }, /* Value 56 */ - { 0x38<<2, 0x3F<<2, 0x28<<2 }, /* Value 57 */ - { 0x2A<<2, 0x3C<<2, 0x2F<<2 }, /* Value 58 */ - { 0x2C<<2, 0x3F<<2, 0x33<<2 }, /* Value 59 */ - { 0x27<<2, 0x3F<<2, 0x3C<<2 }, /* Value 60 */ - { 0x31<<2, 0x31<<2, 0x31<<2 }, /* Value 61 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 62 */ - { 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 63 */ + { 0x1D<