Added double buffering
This commit is contained in:
101
Desktop/Form1.cs
101
Desktop/Form1.cs
@@ -1,11 +1,12 @@
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using Core.Cpu;
|
||||
using Core.Io;
|
||||
using Core.Memory;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Desktop
|
||||
{
|
||||
@@ -35,6 +36,7 @@ namespace Desktop
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
PopulateIncludedTapsMenu();
|
||||
this.DoubleBuffered = true;
|
||||
this.ResizeRedraw = true;
|
||||
InitializeEmulator();
|
||||
@@ -94,7 +96,7 @@ namespace Desktop
|
||||
audioSampleCount = 0;
|
||||
nextScanlineTarget = TStatesPerFrame;
|
||||
stopwatch.Restart();
|
||||
|
||||
tapeLoaded = false;
|
||||
_pendingReset = false;
|
||||
}
|
||||
|
||||
@@ -174,26 +176,26 @@ namespace Desktop
|
||||
{
|
||||
if (TotalFrameCount % 10 == 0)
|
||||
{
|
||||
this.BeginInvoke((MethodInvoker)delegate
|
||||
this.BeginInvoke((System.Windows.Forms.MethodInvoker)delegate
|
||||
{
|
||||
UpdateScreenBitmap(); // Your existing method that writes the ULA data to _screenBitmap
|
||||
|
||||
this.Invalidate(); // Tells Windows: "The bitmap changed, please run OnPaint()!"
|
||||
|
||||
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1}";
|
||||
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1} - Tape Loaded: {tapeLoaded.ToString()}";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
this.BeginInvoke((MethodInvoker)delegate
|
||||
this.BeginInvoke((System.Windows.Forms.MethodInvoker)delegate
|
||||
{
|
||||
UpdateScreenBitmap(); // Your existing method that writes the ULA data to _screenBitmap
|
||||
|
||||
this.Invalidate(); // Tells Windows: "The bitmap changed, please run OnPaint()!"
|
||||
|
||||
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1}";
|
||||
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1} - Tape Loaded: {tapeLoaded.ToString()}";
|
||||
});
|
||||
}
|
||||
|
||||
@@ -225,7 +227,7 @@ namespace Desktop
|
||||
catch (Exception ex)
|
||||
{
|
||||
_isPaused = true;
|
||||
this.Invoke((MethodInvoker)delegate
|
||||
this.Invoke((System.Windows.Forms.MethodInvoker)delegate
|
||||
{
|
||||
MessageBox.Show(ex.Message, "CPU Crash", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
@@ -234,6 +236,77 @@ namespace Desktop
|
||||
});
|
||||
}
|
||||
|
||||
private void PopulateIncludedTapsMenu()
|
||||
{
|
||||
// 1. Get the current assembly (your .exe)
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
// 2. Find all embedded resources
|
||||
string[] resourceNames = assembly.GetManifestResourceNames();
|
||||
|
||||
foreach (string resourceName in resourceNames)
|
||||
{
|
||||
// Check if it is a TAP file in our TestRoms folder
|
||||
// (Embedded resources use dot-notation, e.g., "Desktop.TestRoms.ZEXALL.TAP")
|
||||
if (resourceName.Contains("Desktop.ROMS.TAP.") && resourceName.EndsWith(".TAP", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Clean up the name for the menu (e.g., "Desktop.TestRoms.ZEXALL.TAP" -> "ZEXALL")
|
||||
string[] parts = resourceName.Split('.');
|
||||
string displayName = parts[parts.Length - 2];
|
||||
|
||||
// Create the new menu item
|
||||
ToolStripMenuItem item = new ToolStripMenuItem(displayName);
|
||||
|
||||
// Store the full internal path in the Tag so we know what to load when clicked
|
||||
item.Tag = resourceName;
|
||||
|
||||
// Wire up the click event
|
||||
item.Click += IncludedTapMenuItem_Click;
|
||||
|
||||
// Add it to the "Open Included..." dropdown
|
||||
tAPToolStripMenuItem1.DropDownItems.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void IncludedTapMenuItem_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (sender is ToolStripMenuItem item && item.Tag is string resourceName)
|
||||
{
|
||||
_isPaused = true;
|
||||
|
||||
try
|
||||
{
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
// Open a stream directly into the binary file
|
||||
using (Stream? stream = assembly.GetManifestResourceStream(resourceName))
|
||||
{
|
||||
if (stream == null) throw new Exception("Could not find embedded resource.");
|
||||
|
||||
// Copy the binary stream into a byte array
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
stream.CopyTo(ms);
|
||||
byte[] tapBytes = ms.ToArray();
|
||||
|
||||
// Feed it directly to your existing TapManager!
|
||||
_tapManager.LoadTapData(tapBytes);
|
||||
tapeLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Failed to load built-in TAP:\n{ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isPaused = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaint(e);
|
||||
@@ -326,7 +399,7 @@ namespace Desktop
|
||||
bmp.PixelFormat);
|
||||
|
||||
// Pull the raw pixel data
|
||||
Marshal.Copy(_ula.FrameBuffer, 0, bmpData.Scan0, _ula.FrameBuffer.Length);
|
||||
Marshal.Copy(_ula.FrontBuffer, 0, bmpData.Scan0, _ula.FrontBuffer.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
// Dispose of the old frame to prevent massive RAM leaks!
|
||||
@@ -388,10 +461,6 @@ namespace Desktop
|
||||
private void btnReset_Click(object sender, EventArgs e)
|
||||
{
|
||||
_pendingReset = true;
|
||||
_isPaused = true;
|
||||
_cpu.Reset();
|
||||
_memoryBus.CleanRAMData();
|
||||
_isPaused = false;
|
||||
}
|
||||
|
||||
private void btnExit_Click(object sender, EventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user