Implemenmted rendering priorities

This commit is contained in:
2026-05-12 00:30:28 +01:00
parent f825e102a2
commit 95ac0ec7c1
5 changed files with 125 additions and 55 deletions

View File

@@ -1,22 +1,26 @@
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Reflection;
using System.Reflection.PortableExecutable;
using Core;
using System.Threading.Tasks;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using Core;
namespace Desktop
{
public partial class Form1 : Form
public partial class ParsonsForm1 : Form
{
private SmsMachine _machine = null!;
private DebuggerForm _debugger;
private Bitmap _screenBitmap = new Bitmap(256, 192, PixelFormat.Format32bppArgb);
private Task _emulatorTask;
private double TargetFrameTime = 16.667f;
public int TotalFrameCount = 0;
public double FrameTime { get; private set; } = 0;
public double FramesPerSecond { get; private set; } = 0;
private string _currentRomName = "No ROM";
private Stopwatch _stopwatch = new System.Diagnostics.Stopwatch();
public bool IsRunning { get; private set; } = false;
public ushort? Breakpoint
@@ -25,9 +29,10 @@ namespace Desktop
set { if (_machine != null) _machine.Breakpoint = value; }
}
public Form1()
public ParsonsForm1()
{
InitializeComponent();
this.Text = $"Parsons Master System 2026 - {_currentRomName}";
_machine = new SmsMachine();
PopulateIncludedRomsMenu();
@@ -46,32 +51,81 @@ namespace Desktop
// Update the PictureBox
pbScreen.Image = _screenBitmap;
TotalFrameCount++;
}
public void StartEmulator()
{
if (IsRunning) return;
IsRunning = true;
TotalFrameCount = 0;
double TargetFrameTime = 1000.0 / 60.0;
_emulatorTask = Task.Run(() =>
{
_stopwatch.Restart();
double nextFrameTargetTime = _stopwatch.Elapsed.TotalMilliseconds + TargetFrameTime;
double lastFpsUpdate = _stopwatch.Elapsed.TotalMilliseconds;
int framesThisSecond = 0;
while (IsRunning)
{
// Mark exactly when the emulator starts thinking
double frameStartTime = _stopwatch.Elapsed.TotalMilliseconds;
// 1. Do the heavy lifting (Z80 and VDP)
_machine.RunFrame();
Invoke((System.Windows.Forms.MethodInvoker)delegate { DrawScreen(); });
// 2. FIRE AND FORGET! Tell Windows to draw, but DO NOT WAIT for it to finish!
BeginInvoke((System.Windows.Forms.MethodInvoker)delegate { DrawScreen(); });
// Safety catch: If we hit a breakpoint while running, stop the loop!
// 3. Safety catch
if (_machine.Breakpoint.HasValue && _machine.Cpu.PC == _machine.Breakpoint.Value)
{
IsRunning = false;
// Optional: Force the debugger UI to update immediately so you see it!
Invoke((System.Windows.Forms.MethodInvoker)delegate { _debugger?.uiUpdateTimer_Tick(null, EventArgs.Empty); });
BeginInvoke((System.Windows.Forms.MethodInvoker)delegate { _debugger?.uiUpdateTimer_Tick(null, EventArgs.Empty); });
break;
}
else
// 4. Calculate TRUE Frame Time (Compute Time) BEFORE we go to sleep!
FrameTime = _stopwatch.Elapsed.TotalMilliseconds - frameStartTime;
// --- HIGH PRECISION THROTTLE ---
while (_stopwatch.Elapsed.TotalMilliseconds < nextFrameTargetTime)
{
// Only throttle the speed if we are actively running
Thread.Sleep(8);
if (nextFrameTargetTime - _stopwatch.Elapsed.TotalMilliseconds > 2.0)
{
Thread.Sleep(1);
}
else
{
Thread.SpinWait(10);
}
}
// --- METRICS MATH ---
double currentTime = _stopwatch.Elapsed.TotalMilliseconds;
TotalFrameCount++;
framesThisSecond++;
if (currentTime - lastFpsUpdate >= 1000.0)
{
FramesPerSecond = framesThisSecond / ((currentTime - lastFpsUpdate) / 1000.0);
framesThisSecond = 0;
lastFpsUpdate = currentTime;
BeginInvoke((System.Windows.Forms.MethodInvoker)delegate {
this.Text = $"Parsons Master System - {_currentRomName} [FPS/FT: {FramesPerSecond:F0}/{FrameTime:F1}]";
});
}
nextFrameTargetTime += TargetFrameTime;
if (currentTime > nextFrameTargetTime + TargetFrameTime)
{
nextFrameTargetTime = currentTime + TargetFrameTime;
}
}
});
@@ -102,8 +156,8 @@ namespace Desktop
// 3. Jam it into the Sega Mapper
_machine.LoadCartridge(rom);
// 4. Update the Window title so it looks professional
this.Text = $"Parsons Master System 2026 - {Path.GetFileNameWithoutExtension(filePath)}";
_currentRomName = Path.GetFileNameWithoutExtension(filePath);
this.Text = $"Parsons Master System - {_currentRomName}";
// 5. Turn the power on!