StoicGoose.Unity/Assets/Plugins/StoicGooseUnity/StoicGoose.Core/Sound/AswanSoundController.cs

127 lines
3.8 KiB
C#

using StoicGoose.Common.Attributes;
using StoicGoose.Core.Interfaces;
namespace StoicGoose.Core.Sound
{
public class AswanSoundController : SoundControllerCommon
{
public override byte MaxMasterVolume => 2;
public override int NumChannels => 4;
/* REG_SND_9697 */
protected ushort unknown9697;
/* REG_SND_9899 */
protected ushort unknown9899;
public AswanSoundController(IMachine machine, int rate, int outChannels) : base(machine, rate, outChannels) { }
public override void ResetRegisters()
{
base.ResetRegisters();
unknown9697 = 0;
unknown9899 = 0;
}
public override int[] GenerateSample()
{
channelSampleBuffers[0].Add((short)(channel1.IsEnabled ? (channel1.OutputLeft & 0x07FF) << 5 : 0));
channelSampleBuffers[0].Add((short)(channel1.IsEnabled ? (channel1.OutputRight & 0x07FF) << 5 : 0));
channelSampleBuffers[1].Add((short)(channel2.IsEnabled ? (channel2.OutputLeft & 0x07FF) << 5 : 0));
channelSampleBuffers[1].Add((short)(channel2.IsEnabled ? (channel2.OutputRight & 0x07FF) << 5 : 0));
channelSampleBuffers[2].Add((short)(channel3.IsEnabled ? (channel3.OutputLeft & 0x07FF) << 5 : 0));
channelSampleBuffers[2].Add((short)(channel3.IsEnabled ? (channel3.OutputRight & 0x07FF) << 5 : 0));
channelSampleBuffers[3].Add((short)(channel4.IsEnabled ? (channel4.OutputLeft & 0x07FF) << 5 : 0));
channelSampleBuffers[3].Add((short)(channel4.IsEnabled ? (channel4.OutputRight & 0x07FF) << 5 : 0));
var mixedLeft = 0;
if (channel1.IsEnabled) mixedLeft += channel1.OutputLeft;
if (channel2.IsEnabled) mixedLeft += channel2.OutputLeft;
if (channel3.IsEnabled) mixedLeft += channel3.OutputLeft;
if (channel4.IsEnabled) mixedLeft += channel4.OutputLeft;
mixedLeft = (mixedLeft & 0x07FF) << 5;
var mixedRight = 0;
if (channel1.IsEnabled) mixedRight += channel1.OutputRight;
if (channel2.IsEnabled) mixedRight += channel2.OutputRight;
if (channel3.IsEnabled) mixedRight += channel3.OutputRight;
if (channel4.IsEnabled) mixedRight += channel4.OutputRight;
mixedRight = (mixedRight & 0x07FF) << 5;
return new[] { mixedLeft, mixedRight };
}
public override byte ReadPort(ushort port)
{
return port switch
{
/* REG_SND_9697 (low) */
0x96 => (byte)((unknown9697 >> 0) & 0b11111111),
/* REG_SND_9697 (high) */
0x97 => (byte)((unknown9697 >> 8) & 0b00000011),
/* REG_SND_9899 (low) */
0x98 => (byte)((unknown9899 >> 0) & 0b11111111),
/* REG_SND_9899 (high) */
0x99 => (byte)((unknown9899 >> 8) & 0b00000011),
/* REG_SND_9A */
0x9A => 0b111,
/* REG_SND_9B */
0x9B => 0b11111110,
/* REG_SND_9C */
0x9C => 0b11111111,
/* REG_SND_9D */
0x9D => 0b11111111,
/* Fall through to common */
_ => base.ReadPort(port)
};
}
public override void WritePort(ushort port, byte value)
{
switch (port)
{
case 0x96:
/* REG_SND_9697 (low) */
unknown9697 = (ushort)((unknown9697 & 0x0300) | (value << 0));
break;
case 0x97:
/* REG_SND_9697 (high) */
unknown9697 = (ushort)((unknown9697 & 0x00FF) | (value << 8));
break;
case 0x98:
/* REG_SND_9899 (low) */
unknown9899 = (ushort)((unknown9899 & 0x0300) | (value << 0));
break;
case 0x99:
/* REG_SND_9899 (high) */
unknown9899 = (ushort)((unknown9899 & 0x00FF) | (value << 8));
break;
case 0x9A:
case 0x9B:
case 0x9C:
case 0x9D:
/* REG_SND_9x */
break;
default:
/* Fall through to common */
base.WritePort(port, value);
break;
}
}
[Port("REG_SND_9697", 0x096, 0x097)]
[BitDescription("Unknown data", 0, 9)]
[Format("X4")]
public ushort Unknown9697 => unknown9697;
[Port("REG_SND_9899", 0x098, 0x099)]
[BitDescription("Unknown data", 0, 9)]
[Format("X4")]
public ushort Unknown9899 => unknown9899;
}
}