Added VRAM Viewer and tried to fix noise channel

This commit is contained in:
2026-05-15 16:34:34 +01:00
parent 787e403232
commit f52a5cbfdb
6 changed files with 227 additions and 96 deletions

View File

@@ -90,255 +90,257 @@
<None Remove="ROMS\Wonder Boy 2 - Wonderboy in Monsterland %28UE%29 [!].sms" />
<None Remove="ROMS\Wonder Boy 3 - The Dragon%27s Trap %28UE%29 [!].sms" />
<None Remove="ROMS\zexall.sms" />
<None Remove="ROMS\zexdoc.sav" />
<None Remove="ROMS\zexdoc.sms" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ROMS\After Burner (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Alex Kidd in High Tech World (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Alex Kidd in Miracle World (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Back to the Future 2 (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Back to the Future 3 (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Bart vs. the Space Mutants (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Bart vs. the World (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Black Belt (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\California Games (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\California Games 2 (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Casino Games (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Choplifter (SG-1000) [!].sg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Cloud Master (JUE).sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Cool Spot (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Desert Strike (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Double Dragon (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Dynamite Dux (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Ecco the Dolphin (UE).sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Fantasy Zone (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Fantasy Zone 2 - The Tears of Opa-Opa (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Fantasy Zone 3 - The Maze (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Gangster Town (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Gauntlet (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Ghost House (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Ghouls 'n Ghosts (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Global Defense (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Golden Axe (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Golden Axe Warrior.sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Great Baseball (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Great Basketball (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Great Football (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Great Golf (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Great Ice Hockey (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Great Volleyball (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Hang-On (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Hang-On 2 (SG-1000).sg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Heavyweight Champ (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Home Alone (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Impossible Mission (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Japanese SMS BIOS v2.1 (J) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Jurassic Park (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Mickey Mouse - Castle of Illusion (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Mickey Mouse - Land of Illusion (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Mickey Mouse - Legend of Illusion (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Mortal Kombat (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Mortal Kombat 2 (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Mortal Kombat 3 (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\OutRun (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Paperboy (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Parlour Games (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Phantasy Star (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Populous (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Psychic World (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Psycho Fox (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\R-Type.sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Road Rash (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Shadow of the Beast (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Smash TV (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\SMSTestSuite.sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Sonic 2.sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Sonic Chaos (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Sonic.sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Space Harrier (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Speedball (UE) (Virgin) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Star Wars (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Street Fighter 2 (Brazil) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Streets of Rage (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Streets of Rage 2 (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Summer Games (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Super Kick Off (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Super Monaco GP (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Super Monaco GP 2 (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Super Tennis (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Terminator 2 - Judgment Day (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Terminator, The (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Trans-Bot (UE).sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Winter Olympics '94 (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Wonder Boy (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Wonder Boy 2 - Wonderboy in Monsterland (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\Wonder Boy 3 - The Dragon's Trap (UE) [!].sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\zexall.sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="ROMS\zexdoc.sav" />
<EmbeddedResource Include="ROMS\zexdoc.sms">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>

View File

@@ -40,6 +40,7 @@
resetToolStripMenuItem = new ToolStripMenuItem();
helpToolStripMenuItem = new ToolStripMenuItem();
aboutToolStripMenuItem = new ToolStripMenuItem();
vRAMViewerToolStripMenuItem = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
SuspendLayout();
//
@@ -90,7 +91,7 @@
//
// viewToolStripMenuItem
//
viewToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { debuggerToolStripMenuItem });
viewToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { debuggerToolStripMenuItem, vRAMViewerToolStripMenuItem });
viewToolStripMenuItem.Name = "viewToolStripMenuItem";
viewToolStripMenuItem.Size = new Size(65, 29);
viewToolStripMenuItem.Text = "View";
@@ -98,7 +99,7 @@
// debuggerToolStripMenuItem
//
debuggerToolStripMenuItem.Name = "debuggerToolStripMenuItem";
debuggerToolStripMenuItem.Size = new Size(194, 34);
debuggerToolStripMenuItem.Size = new Size(270, 34);
debuggerToolStripMenuItem.Text = "Debugger";
debuggerToolStripMenuItem.Click += debuggerToolStripMenuItem_Click;
//
@@ -129,6 +130,13 @@
aboutToolStripMenuItem.Size = new Size(164, 34);
aboutToolStripMenuItem.Text = "About";
//
// vRAMViewerToolStripMenuItem
//
vRAMViewerToolStripMenuItem.Name = "vRAMViewerToolStripMenuItem";
vRAMViewerToolStripMenuItem.Size = new Size(270, 34);
vRAMViewerToolStripMenuItem.Text = "VRAM Viewer";
vRAMViewerToolStripMenuItem.Click += vramViewerToolStripMenuItem_Click;
//
// ParsonsForm1
//
AutoScaleDimensions = new SizeF(10F, 25F);
@@ -159,5 +167,6 @@
private ToolStripMenuItem aboutToolStripMenuItem;
private ToolStripMenuItem includedToolStripMenuItem;
private ToolStripMenuItem selectROMToolStripMenuItem1;
private ToolStripMenuItem vRAMViewerToolStripMenuItem;
}
}

View File

@@ -14,6 +14,7 @@ namespace Desktop
{
public SmsMachine _machine = null!;
private DebuggerForm _debugger;
private VramViewerForm _vramViewer;
private Bitmap _screenBitmap = new Bitmap(256, 192, PixelFormat.Format32bppArgb);
private NAudioPlayer _audioPlayer;
private Task _emulatorTask;
@@ -296,6 +297,16 @@ namespace Desktop
_debugger.Show();
}
private void vramViewerToolStripMenuItem_Click(object sender, EventArgs e)
{
if (_vramViewer == null || _vramViewer.IsDisposed)
{
// Pass the VDP directly to the viewer!
_vramViewer = new VramViewerForm(_machine.VideoProcessor);
}
_vramViewer.Show();
}
private void includedToolStripMenuItem_Click(object sender, EventArgs e)
{

Binary file not shown.

100
Desktop/VramViewerForm.cs Normal file
View File

@@ -0,0 +1,100 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Core.Video;
namespace Desktop
{
public class VramViewerForm : Form
{
private readonly SmsVdp _vdp;
private readonly System.Windows.Forms.Timer _refreshTimer;
private readonly Bitmap _vramBitmap;
private readonly int[] _pixelData;
public VramViewerForm(SmsVdp vdp)
{
_vdp = vdp;
this.Text = "VRAM Viewer (512 Tiles)";
// 256x128 native resolution, scaled up by 2 for visibility!
this.ClientSize = new Size(512, 256);
this.DoubleBuffered = true;
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
_vramBitmap = new Bitmap(256, 128, PixelFormat.Format32bppArgb);
_pixelData = new int[256 * 128];
// Update the window 10 times a second so it doesn't drain CPU power
_refreshTimer = new System.Windows.Forms.Timer();
_refreshTimer.Interval = 100;
_refreshTimer.Tick += (s, e) => UpdateVramImage();
_refreshTimer.Start();
}
private void UpdateVramImage()
{
if (_vdp == null) return;
// Loop through all 512 tiles in VRAM
for (int tile = 0; tile < 512; tile++)
{
// Calculate grid position (32 columns, 16 rows)
int tileX = (tile % 32) * 8;
int tileY = (tile / 32) * 8;
int tileAddress = tile * 32;
// Decode the 8x8 pixels
for (int y = 0; y < 8; y++)
{
byte bp0 = _vdp.VRAM[tileAddress + (y * 4) + 0];
byte bp1 = _vdp.VRAM[tileAddress + (y * 4) + 1];
byte bp2 = _vdp.VRAM[tileAddress + (y * 4) + 2];
byte bp3 = _vdp.VRAM[tileAddress + (y * 4) + 3];
for (int x = 0; x < 8; x++)
{
int shift = 7 - x;
int colorIndex = ((bp0 >> shift) & 1) | (((bp1 >> shift) & 1) << 1) |
(((bp2 >> shift) & 1) << 2) | (((bp3 >> shift) & 1) << 3);
// Use the Sprite Palette (Offset 16) so characters and enemies are colored correctly
byte smsColor = _vdp.CRAM[16 + colorIndex];
int r = (smsColor & 0x03) * 85;
int g = ((smsColor >> 2) & 0x03) * 85;
int b = ((smsColor >> 4) & 0x03) * 85;
// Background color (Index 0) is technically transparent for sprites, so we render it as magenta
if (colorIndex == 0) { r = 255; g = 0; b = 255; }
_pixelData[((tileY + y) * 256) + (tileX + x)] = (255 << 24) | (r << 16) | (g << 8) | b;
}
}
}
// Blast the array into the Bitmap
var data = _vramBitmap.LockBits(new Rectangle(0, 0, 256, 128), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(_pixelData, 0, data.Scan0, _pixelData.Length);
_vramBitmap.UnlockBits(data);
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// Draw it chunky and pixel-perfect
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
e.Graphics.DrawImage(_vramBitmap, new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height));
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
_refreshTimer.Stop();
base.OnFormClosing(e);
}
}
}