Updated graphics renderer to allow for pixel perfect resizing
This commit is contained in:
@@ -18,6 +18,7 @@ namespace Desktop
|
||||
private TapManager _tapManager = null!;
|
||||
private DebuggerForm? _debugger = null;
|
||||
private BeeperDevice _beeper = null!;
|
||||
private Bitmap _screenBitmap = null!;
|
||||
private string _baseTitle = "";
|
||||
private bool _isRunning = false;
|
||||
private bool _isPaused = false;
|
||||
@@ -34,6 +35,8 @@ namespace Desktop
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.DoubleBuffered = true;
|
||||
this.ResizeRedraw = true;
|
||||
InitializeEmulator();
|
||||
}
|
||||
|
||||
@@ -173,7 +176,10 @@ namespace Desktop
|
||||
{
|
||||
this.BeginInvoke((MethodInvoker)delegate
|
||||
{
|
||||
UpdateScreenBitmap();
|
||||
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}";
|
||||
});
|
||||
}
|
||||
@@ -181,10 +187,13 @@ namespace Desktop
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Invoke((MethodInvoker)delegate
|
||||
this.BeginInvoke((MethodInvoker)delegate
|
||||
{
|
||||
UpdateScreenBitmap();
|
||||
this.Text = $"{_baseTitle} - FPS: {FramesPerSecond:F1} - Tape Loaded: {tapeLoaded.ToString()}";
|
||||
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}";
|
||||
});
|
||||
}
|
||||
|
||||
@@ -225,6 +234,40 @@ namespace Desktop
|
||||
});
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
base.OnPaint(e);
|
||||
|
||||
// If we don't have a screen bitmap yet, just paint the background black and exit
|
||||
if (_screenBitmap == null)
|
||||
{
|
||||
e.Graphics.Clear(Color.Black);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Calculate the scaling factor to fit the window while preserving aspect ratio
|
||||
float scaleX = (float)this.ClientSize.Width / _screenBitmap.Width;
|
||||
float scaleY = (float)this.ClientSize.Height / _screenBitmap.Height;
|
||||
float scale = Math.Min(scaleX, scaleY); // Pick the smallest scale so it fits inside
|
||||
|
||||
int newWidth = (int)(_screenBitmap.Width * scale);
|
||||
int newHeight = (int)(_screenBitmap.Height * scale);
|
||||
|
||||
// 2. Center the image horizontally and vertically (Pillarboxing/Letterboxing)
|
||||
int posX = (this.ClientSize.Width - newWidth) / 2;
|
||||
int posY = (this.ClientSize.Height - newHeight) / 2;
|
||||
|
||||
// 3. RETRO MAGIC: Force Nearest-Neighbor interpolation for razor-sharp pixels!
|
||||
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
|
||||
// PixelOffsetMode.Half is a GDI+ trick required to make NearestNeighbor perfectly accurate
|
||||
e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
|
||||
|
||||
// 4. Paint the black borders (if any) and draw the screen
|
||||
e.Graphics.Clear(Color.Black);
|
||||
e.Graphics.DrawImage(_screenBitmap, posX, posY, newWidth, newHeight);
|
||||
}
|
||||
|
||||
private void HandleInstantTapeLoad()
|
||||
{
|
||||
byte[] block = _tapManager.GetNextBlock(); // Your original Queue.Dequeue() method
|
||||
@@ -271,7 +314,7 @@ namespace Desktop
|
||||
_cpu.SP++;
|
||||
_cpu.PC = (ushort)((pcHigh << 8) | pcLow);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void UpdateScreenBitmap()
|
||||
{
|
||||
@@ -286,8 +329,14 @@ namespace Desktop
|
||||
Marshal.Copy(_ula.FrameBuffer, 0, bmpData.Scan0, _ula.FrameBuffer.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
if (picScreen.Image != null) picScreen.Image.Dispose();
|
||||
picScreen.Image = bmp;
|
||||
// Dispose of the old frame to prevent massive RAM leaks!
|
||||
if (_screenBitmap != null)
|
||||
{
|
||||
_screenBitmap.Dispose();
|
||||
}
|
||||
|
||||
// Save the new frame so OnPaint() can draw it
|
||||
_screenBitmap = bmp;
|
||||
}
|
||||
|
||||
private void loadTAPToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user