From c26fabb9e79d71321ad7cc462289b3c05d6c8da2 Mon Sep 17 00:00:00 2001 From: Ian C Date: Mon, 12 Mar 2012 23:21:04 +0000 Subject: Added a frame skip -- the graphics rendering seems to be a bottleneck. --- wpspec/wpspec/GamePage.xaml.cs | 43 ++++++++++------- wpspec/wpspec/Spectrum/Emulation.cs | 93 ++++++++++++++++++++++++++----------- 2 files changed, 92 insertions(+), 44 deletions(-) diff --git a/wpspec/wpspec/GamePage.xaml.cs b/wpspec/wpspec/GamePage.xaml.cs index f85977b..7645921 100644 --- a/wpspec/wpspec/GamePage.xaml.cs +++ b/wpspec/wpspec/GamePage.xaml.cs @@ -24,6 +24,7 @@ namespace wpspec private ContentManager contentManager; private GameTimer timer; private SpriteBatch spriteBatch; + private Texture2D screen; #endregion @@ -40,10 +41,10 @@ namespace wpspec // contentManager = (Application.Current as App).Content; - // Create a timer for this page. Updates at 50 frames a second (PAL). + // Create a timer for this page. // timer = new GameTimer(); - timer.UpdateInterval = TimeSpan.FromMilliseconds(20); + timer.UpdateInterval = TimeSpan.FromMilliseconds(20 * Shared.FrameSkip); timer.Update += OnUpdate; timer.Draw += OnDraw; } @@ -62,6 +63,14 @@ namespace wpspec // spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice); + // Create screen object + // + screen = new Texture2D + (SharedGraphicsDeviceManager.Current.GraphicsDevice, + Shared.Spectrum.Width, + Shared.Spectrum.Height, + false, Shared.Spectrum.ScreenFormat); + // Start the timer // timer.Start(); @@ -79,6 +88,9 @@ namespace wpspec // SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(false); + screen.Dispose(); + screen = null; + base.OnNavigatedFrom(e); } @@ -101,25 +113,20 @@ namespace wpspec /// private void OnDraw(object sender, GameTimerEventArgs e) { + Stopwatch s = Stopwatch.StartNew(); + SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.Black); + Shared.Spectrum.Update(); - DateTime now = DateTime.Now; + screen.SetData(Shared.Spectrum.Screen); - using (Texture2D screen = - new Texture2D - (SharedGraphicsDeviceManager.Current.GraphicsDevice, - Shared.Spectrum.Width, - Shared.Spectrum.Height, - false, SurfaceFormat.Color)) - { - Shared.Spectrum.Update(); - screen.SetData(Shared.Spectrum.Screen); - - spriteBatch.Begin(); - spriteBatch.Draw(screen, Vector2.Zero, Color.White); - spriteBatch.End(); - Debug.WriteLine("Render - {0} msec", (DateTime.Now - now).TotalMilliseconds); - } + spriteBatch.Begin(); + spriteBatch.Draw(screen, Vector2.Zero, Color.White); + spriteBatch.End(); + SharedGraphicsDeviceManager.Current.GraphicsDevice.Textures[0] = null; + + s.Stop(); + Debug.WriteLine("RENDER: {0} ms {1} ticks", s.ElapsedMilliseconds, s.ElapsedTicks); } #endregion diff --git a/wpspec/wpspec/Spectrum/Emulation.cs b/wpspec/wpspec/Spectrum/Emulation.cs index 0e4a286..e81f2ed 100644 --- a/wpspec/wpspec/Spectrum/Emulation.cs +++ b/wpspec/wpspec/Spectrum/Emulation.cs @@ -8,6 +8,7 @@ using System.Windows.Resources; using System.IO; using Microsoft.Xna.Framework; using System.Diagnostics; +using Microsoft.Xna.Framework.Graphics; namespace wpspec.Spectrum { @@ -19,7 +20,7 @@ namespace wpspec.Spectrum #region Private private readonly byte[] mem = new byte[0x10000]; - private readonly Clock clock = new Clock(69888, 50); + private readonly Clock clock = new Clock(69888 * Shared.FrameSkip, 50 / Shared.FrameSkip); private readonly Z80Cpu z80 = new Z80Cpu(); private byte[] tape; @@ -28,26 +29,55 @@ namespace wpspec.Spectrum private readonly int[] screen = new int[192]; - private readonly uint[] colours = new uint[16] + //private readonly uint[] colours = new uint[16] + //{ + // new Color(0x00, 0x00, 0x00).PackedValue, // BLACK + // new Color(0x00, 0x00, 0xe6).PackedValue, // BLUE + // new Color(0xe6, 0x00, 0x00).PackedValue, // RED + // new Color(0xe6, 0x00, 0xe6).PackedValue, // MAGENTA + // new Color(0x00, 0xe6, 0x00).PackedValue, // GREEN + // new Color(0x00, 0xe6, 0xe6).PackedValue, // CYAN + // new Color(0xe6, 0xe6, 0x00).PackedValue, // YELLOW + // new Color(0xe6, 0xe6, 0xe6).PackedValue, // WHITE + // new Color(0x00, 0x00, 0x00).PackedValue, // BLACK (BRIGHT) + // new Color(0x00, 0x00, 0xff).PackedValue, // BLUE (BRIGHT) + // new Color(0xff, 0x00, 0x00).PackedValue, // RED (BRIGHT) + // new Color(0xff, 0x00, 0xff).PackedValue, // MAGENTA (BRIGHT) + // new Color(0x00, 0xff, 0x00).PackedValue, // GREEN (BRIGHT) + // new Color(0x00, 0xff, 0xff).PackedValue, // CYAN (BRIGHT) + // new Color(0xff, 0xff, 0x00).PackedValue, // YELLOW (BRIGHT) + // new Color(0xff, 0xff, 0xff).PackedValue // WHITE (BRIGHT) + //}; + + private readonly ushort[] colours = new ushort[16] { - new Color(0x00, 0x00, 0x00).PackedValue, // BLACK - new Color(0x00, 0x00, 0xe6).PackedValue, // BLUE - new Color(0xe6, 0x00, 0x00).PackedValue, // RED - new Color(0xe6, 0x00, 0xe6).PackedValue, // MAGENTA - new Color(0x00, 0xe6, 0x00).PackedValue, // GREEN - new Color(0x00, 0xe6, 0xe6).PackedValue, // CYAN - new Color(0xe6, 0xe6, 0x00).PackedValue, // YELLOW - new Color(0xe6, 0xe6, 0xe6).PackedValue, // WHITE - new Color(0x00, 0x00, 0x00).PackedValue, // BLACK (BRIGHT) - new Color(0x00, 0x00, 0xff).PackedValue, // BLUE (BRIGHT) - new Color(0xff, 0x00, 0x00).PackedValue, // RED (BRIGHT) - new Color(0xff, 0x00, 0xff).PackedValue, // MAGENTA (BRIGHT) - new Color(0x00, 0xff, 0x00).PackedValue, // GREEN (BRIGHT) - new Color(0x00, 0xff, 0xff).PackedValue, // CYAN (BRIGHT) - new Color(0xff, 0xff, 0x00).PackedValue, // YELLOW (BRIGHT) - new Color(0xff, 0xff, 0xff).PackedValue // WHITE (BRIGHT) + GetColour(0x00, 0x00, 0x00), // BLACK + GetColour(0x00, 0x00, 0xe6), // BLUE + GetColour(0xe6, 0x00, 0x00), // RED + GetColour(0xe6, 0x00, 0xe6), // MAGENTA + GetColour(0x00, 0xe6, 0x00), // GREEN + GetColour(0x00, 0xe6, 0xe6), // CYAN + GetColour(0xe6, 0xe6, 0x00), // YELLOW + GetColour(0xe6, 0xe6, 0xe6), // WHITE + GetColour(0x00, 0x00, 0x00), // BLACK (BRIGHT) + GetColour(0x00, 0x00, 0xff), // BLUE (BRIGHT) + GetColour(0xff, 0x00, 0x00), // RED (BRIGHT) + GetColour(0xff, 0x00, 0xff), // MAGENTA (BRIGHT) + GetColour(0x00, 0xff, 0x00), // GREEN (BRIGHT) + GetColour(0x00, 0xff, 0xff), // CYAN (BRIGHT) + GetColour(0xff, 0xff, 0x00), // YELLOW (BRIGHT) + GetColour(0xff, 0xff, 0xff) // WHITE (BRIGHT) }; + private static ushort GetColour(int r, int g, int b) + { + r >>= 3; + g >>= 2; + b >>= 3; + + return (ushort)((r << 11) | (g << 5) | b); + } + private bool flash; private int flashCounter; @@ -158,11 +188,16 @@ namespace wpspec.Spectrum public int Height {get {return 192;}} /// - /// Get the emulated screen contents as packed RGBA values. + /// Gets the format of data returned by + /// + public SurfaceFormat ScreenFormat {get {return SurfaceFormat.Bgr565;}} + + /// + /// Get the emulated screen contents. /// This array must have times /// elements. /// - public uint[] Screen {get; private set;} + public ushort[] Screen {get; private set;} /// /// Get/set the tape file to load. @@ -197,11 +232,14 @@ namespace wpspec.Spectrum /// public void Run() { + Stopwatch s = Stopwatch.StartNew(); + clock.StartFrame(); - DateTime now = DateTime.Now; z80.Run(); z80.MaskableInterrupt(0); - Debug.WriteLine("Exec - {0} msec", (DateTime.Now - now).TotalMilliseconds); + + s.Stop(); + Debug.WriteLine("EXEC: {0} ms {1} ticks", s.ElapsedMilliseconds, s.ElapsedTicks); } /// @@ -209,7 +247,9 @@ namespace wpspec.Spectrum /// public void Update() { - uint[] scr = Screen; + Stopwatch s = Stopwatch.StartNew(); + + ushort[] scr = Screen; int addr; int attr; int ink; @@ -218,7 +258,6 @@ namespace wpspec.Spectrum int p = 0; byte b; - DateTime now = DateTime.Now; for(int y = 0; y < 192; y++) { addr = screen[y]; @@ -268,7 +307,9 @@ namespace wpspec.Spectrum flashCounter = 0; flash = !flash; } - Debug.WriteLine("Draw - {0} msec", (DateTime.Now - now).TotalMilliseconds); + + s.Stop(); + Debug.WriteLine("UPDATE: {0} ms {1} ticks", s.ElapsedMilliseconds, s.ElapsedTicks); } #endregion @@ -291,7 +332,7 @@ namespace wpspec.Spectrum // Set up screen and accelerators // - Screen = new uint[Width * Height]; + Screen = new ushort[Width * Height]; int c = 0; int r = 0; -- cgit v1.2.3