Added VRAM Viewer and tried to fix noise channel
This commit is contained in:
@@ -22,6 +22,7 @@ namespace Core.Audio
|
||||
private int[] _counters = new int[4];
|
||||
private int[] _polarities = new int[4] { 1, 1, 1, 1 }; // 1 = High, -1 = Low
|
||||
private ushort _lfsr = 0x8000; // Linear Feedback Shift Register (For Noise)
|
||||
private bool _noiseFlipFlop = false;
|
||||
|
||||
// The SN76489 Volume Table reduces amplitude by exactly 2 decibels per step.
|
||||
private static readonly float[] VolumeTable = {
|
||||
@@ -83,27 +84,33 @@ namespace Core.Audio
|
||||
_counters[3]--;
|
||||
if (_counters[3] <= 0)
|
||||
{
|
||||
// Noise rate depends on Bits 0-1 of Register 6
|
||||
// Reload the counter
|
||||
int shiftRate = Registers[6] & 0x03;
|
||||
if (shiftRate == 0) _counters[3] = 0x10; // Fast
|
||||
else if (shiftRate == 1) _counters[3] = 0x20; // Medium
|
||||
else if (shiftRate == 2) _counters[3] = 0x40; // Slow
|
||||
else _counters[3] = (Registers[4] == 0) ? 1024 : Registers[4]; // Linked to Tone 2!
|
||||
else _counters[3] = (Registers[4] == 0) ? 1024 : Registers[4]; // Linked to Tone 2
|
||||
|
||||
// Shift the Noise LFSR
|
||||
int tappedBit = _lfsr & 1;
|
||||
_lfsr >>= 1;
|
||||
// THE FIX: Toggle the internal clock (Divide by 2!)
|
||||
_noiseFlipFlop = !_noiseFlipFlop;
|
||||
|
||||
if (tappedBit == 1)
|
||||
// Only shift the random static when the clock goes High
|
||||
if (_noiseFlipFlop)
|
||||
{
|
||||
bool isWhiteNoise = (Registers[6] & 0x04) != 0;
|
||||
// The Sega Master System physically tapped bits 0 and 3 for its white noise
|
||||
if (isWhiteNoise) _lfsr ^= 0x0009;
|
||||
int tappedBit = _lfsr & 1;
|
||||
_lfsr >>= 1;
|
||||
|
||||
_lfsr |= 0x8000; // Inject the high bit
|
||||
if (tappedBit == 1)
|
||||
{
|
||||
bool isWhiteNoise = (Registers[6] & 0x04) != 0;
|
||||
if (isWhiteNoise) _lfsr ^= 0x0009; // SMS-specific XOR mask
|
||||
|
||||
_lfsr |= 0x8000; // Inject the high bit
|
||||
}
|
||||
|
||||
// The noise channel output is driven directly by the tapped bit
|
||||
_polarities[3] = (tappedBit == 1) ? 1 : -1;
|
||||
}
|
||||
|
||||
_polarities[3] = (tappedBit == 1) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,12 +156,14 @@ namespace Core.Audio
|
||||
// Volume registers (1, 3, 5, 7) and Noise Control (6) only hold 4 bits total.
|
||||
// We completely overwrite them.
|
||||
Registers[_latchedRegister] = (ushort)data;
|
||||
if (_latchedRegister == 6) _lfsr = 0x8000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tone registers (0, 2, 4) hold 10 bits.
|
||||
// A Latch byte ONLY overwrites the bottom 4 bits and leaves the top 6 alone!
|
||||
Registers[_latchedRegister] = (ushort)((Registers[_latchedRegister] & 0x03F0) | data);
|
||||
if (_latchedRegister == 6) _lfsr = 0x8000;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
13
Desktop/Form1.Designer.cs
generated
13
Desktop/Form1.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
|
||||
BIN
Desktop/ROMS/Golden Axe Warrior.sav
Normal file
BIN
Desktop/ROMS/Golden Axe Warrior.sav
Normal file
Binary file not shown.
100
Desktop/VramViewerForm.cs
Normal file
100
Desktop/VramViewerForm.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user