Encapsulate PCEHawk in new service for Sound Debugger

This commit is contained in:
YoshiRulz 2025-06-21 19:18:39 +10:00
parent 04d3fe707c
commit b31e973a8a
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
4 changed files with 64 additions and 7 deletions

View File

@ -6,7 +6,7 @@ using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Common;
using BizHawk.Emulation.Cores.PCEngine;
using BizHawk.Emulation.Cores.Components;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
@ -18,7 +18,10 @@ namespace BizHawk.Client.EmuHawk
=> Properties.Resources.BugIcon;
[RequiredService]
private PCEngine PCE { get; set; }
private IPCEngineSoundDebuggable/*?*/ _maybeSoundDebug { get; set; }
private IPCEngineSoundDebuggable SoundDebugImpl
=> _maybeSoundDebug!;
protected override string WindowTitleStatic => "Sound Debugger";
@ -46,6 +49,8 @@ namespace BizHawk.Client.EmuHawk
protected override void UpdateAfter()
{
var channelData = SoundDebugImpl.GetPSGChannelData();
foreach (var entry in _psgEntries)
{
entry.WasActive = entry.Active;
@ -58,7 +63,7 @@ namespace BizHawk.Client.EmuHawk
for (int i = 0; i < 6; i++)
{
var ch = PCE.PSG.Channels[i];
var ch = channelData[i];
// these conditions mean a sample isn't playing
if (!ch.Enabled)
@ -95,7 +100,7 @@ namespace BizHawk.Client.EmuHawk
lvChannels.Items[i].SubItems[3].Text = "-";
// ok, a sample is playing. copy out the waveform
short[] waveform = (short[])ch.Wave.Clone();
var waveform = ch.CloneWaveform();
// hash it
var ms = new MemoryStream(_waveformTemp);
@ -244,6 +249,6 @@ namespace BizHawk.Client.EmuHawk
}
private void lvChEn_ItemChecked(object sender, ItemCheckedEventArgs e)
=> PCE.PSG.UserMute[e.Item.Index] = !e.Item.Checked;
=> SoundDebugImpl.SetChannelMuted(e.Item.Index, newIsMuted: !e.Item.Checked);
}
}

View File

@ -0,0 +1,26 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Components
{
public interface IPCEngineSoundDebuggable : ISpecializedEmulatorService
{
public interface ChannelData
{
bool DDA { get; }
bool Enabled { get; }
ushort Frequency { get; }
bool NoiseChannel { get; }
byte Volume { get; }
short[] CloneWaveform();
}
ReadOnlySpan<ChannelData> GetPSGChannelData();
void SetChannelMuted(int channelIndex, bool newIsMuted);
}
}

View File

@ -321,6 +321,7 @@ namespace BizHawk.Emulation.Cores.PCEngine
ser.Register<IDisassemblable>(Cpu);
ser.Register<IVideoProvider>((IVideoProvider)VPC ?? VDC1);
ser.Register<ISoundProvider>(_soundProvider);
ser.Register<IPCEngineSoundDebuggable>(PSG);
ser.Register<IStatable>(new StateSerializer(SyncState));
SetupMemoryDomains();
}

View File

@ -11,10 +11,11 @@ namespace BizHawk.Emulation.Cores.Components
// Sound refactor TODO: IMixedSoundProvider must inherit ISoundProvider
// TODo: this provides "fake" sync sound by hardcoding the number of samples
public sealed class HuC6280PSG : ISoundProvider, IMixedSoundProvider
public sealed class HuC6280PSG : ISoundProvider, IMixedSoundProvider, IPCEngineSoundDebuggable
{
private readonly int _spf;
public class PSGChannel
public sealed class PSGChannel : IPCEngineSoundDebuggable.ChannelData
{
public ushort Frequency;
public byte Panning;
@ -26,6 +27,24 @@ namespace BizHawk.Emulation.Cores.Components
public short DDAValue;
public short[] Wave = new short[32];
public float SampleOffset;
bool IPCEngineSoundDebuggable.ChannelData.DDA
=> DDA;
bool IPCEngineSoundDebuggable.ChannelData.Enabled
=> Enabled;
ushort IPCEngineSoundDebuggable.ChannelData.Frequency
=> Frequency;
bool IPCEngineSoundDebuggable.ChannelData.NoiseChannel
=> NoiseChannel;
byte IPCEngineSoundDebuggable.ChannelData.Volume
=> Volume;
public short[] CloneWaveform()
=> (short[]) Wave.Clone();
}
public PSGChannel[] Channels = new PSGChannel[8];
@ -73,6 +92,12 @@ namespace BizHawk.Emulation.Cores.Components
frameStopTime = cycles;
}
public ReadOnlySpan<IPCEngineSoundDebuggable.ChannelData> GetPSGChannelData()
=> Channels;
public void SetChannelMuted(int channelIndex, bool newIsMuted)
=> UserMute[channelIndex] = newIsMuted;
internal void WritePSG(byte register, byte value, long cycles)
{
commands.Enqueue(new QueuedCommand { Register = register, Value = value, Time = cycles - frameStartTime });