AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/Iremga20.cs

201 lines
7.2 KiB
C#
Raw Normal View History

using System.IO;
namespace MAME.Core
{
public unsafe class Iremga20
{
public struct IremGA20_channel_def
{
public int rate;
public int size;
public int start;
public int pos;
public int frac;
public int end;
public int volume;
public int pan;
public int effect;
public int play;
};
public struct IremGA20_chip_def
{
public ushort[] regs;
public IremGA20_channel_def[] channel;
};
public static IremGA20_chip_def chip;
public static byte[] iremrom;
public static void iremga20_update(int offset, int length)
{
int[] rate = new int[4], pos = new int[4], frac = new int[4], end = new int[4], vol = new int[4], play = new int[4];
int i, sampleout;
for (i = 0; i < 4; i++)
{
rate[i] = chip.channel[i].rate;
pos[i] = chip.channel[i].pos;
frac[i] = chip.channel[i].frac;
end[i] = chip.channel[i].end - 0x20;
vol[i] = chip.channel[i].volume;
play[i] = chip.channel[i].play;
}
i = length;
for (i = 0; i < length; i++)
{
sampleout = 0;
if (play[0] != 0)
{
sampleout += (iremrom[pos[0]] - 0x80) * vol[0];
frac[0] += rate[0];
pos[0] += frac[0] >> 24;
frac[0] &= 0xffffff;
play[0] = pos[0] < end[0] ? 1 : 0;
}
if (play[1] != 0)
{
sampleout += (iremrom[pos[1]] - 0x80) * vol[1];
frac[1] += rate[1];
pos[1] += frac[1] >> 24;
frac[1] &= 0xffffff;
play[1] = pos[1] < end[1] ? 1 : 0;
}
if (play[2] != 0)
{
sampleout += (iremrom[pos[2]] - 0x80) * vol[2];
frac[2] += rate[2];
pos[2] += frac[2] >> 24;
frac[2] &= 0xffffff;
play[2] = pos[2] < end[2] ? 1 : 0;
}
if (play[3] != 0)
{
sampleout += (iremrom[pos[3]] - 0x80) * vol[3];
frac[3] += rate[3];
pos[3] += frac[3] >> 24;
frac[3] &= 0xffffff;
play[3] = pos[3] < end[3] ? 1 : 0;
}
sampleout >>= 2;
Sound.iremga20stream.streamoutput_Ptrs[0][offset + i] = sampleout;
Sound.iremga20stream.streamoutput_Ptrs[1][offset + i] = sampleout;
}
for (i = 0; i < 4; i++)
{
chip.channel[i].pos = pos[i];
chip.channel[i].frac = frac[i];
chip.channel[i].play = play[i];
}
}
public static void irem_ga20_w(int offset, ushort data)
{
int channel;
Sound.iremga20stream.stream_update();
channel = offset >> 3;
chip.regs[offset] = data;
switch (offset & 0x7)
{
case 0:
chip.channel[channel].start = ((chip.channel[channel].start) & 0xff000) | (data << 4);
break;
case 1:
chip.channel[channel].start = ((chip.channel[channel].start) & 0x00ff0) | (data << 12);
break;
case 2:
chip.channel[channel].end = ((chip.channel[channel].end) & 0xff000) | (data << 4);
break;
case 3:
chip.channel[channel].end = ((chip.channel[channel].end) & 0x00ff0) | (data << 12);
break;
case 4:
chip.channel[channel].rate = 0x1000000 / (256 - data);
break;
case 5:
chip.channel[channel].volume = (data * 0x100) / (data + 10);
break;
case 6:
chip.channel[channel].play = data;
chip.channel[channel].pos = chip.channel[channel].start;
chip.channel[channel].frac = 0;
break;
}
}
public static ushort irem_ga20_r(int offset)
{
int channel;
ushort result;
Sound.iremga20stream.stream_update();
channel = offset >> 3;
switch (offset & 0x7)
{
case 7:
result = (ushort)(chip.channel[channel].play != 0 ? 1 : 0);
break;
default:
result = 0;
break;
}
return result;
}
public static void iremga20_reset()
{
int i;
for (i = 0; i < 4; i++)
{
chip.channel[i].rate = 0;
chip.channel[i].size = 0;
chip.channel[i].start = 0;
chip.channel[i].pos = 0;
chip.channel[i].frac = 0;
chip.channel[i].end = 0;
chip.channel[i].volume = 0;
chip.channel[i].pan = 0;
chip.channel[i].effect = 0;
chip.channel[i].play = 0;
}
}
public static void iremga20_start()
{
int i;
chip.regs = new ushort[0x40];
chip.channel = new IremGA20_channel_def[4];
iremga20_reset();
for (i = 0; i < 0x40; i++)
{
chip.regs[i] = 0;
}
}
public static void SaveStateBinary(BinaryWriter writer)
{
int i;
for (i = 0; i < 4; i++)
{
writer.Write(chip.channel[i].rate);
writer.Write(chip.channel[i].size);
writer.Write(chip.channel[i].start);
writer.Write(chip.channel[i].pos);
writer.Write(chip.channel[i].frac);
writer.Write(chip.channel[i].end);
writer.Write(chip.channel[i].volume);
writer.Write(chip.channel[i].pan);
writer.Write(chip.channel[i].effect);
writer.Write(chip.channel[i].play);
}
}
public static void LoadStateBinary(BinaryReader reader)
{
int i;
for (i = 0; i < 4; i++)
{
chip.channel[i].rate = reader.ReadInt32();
chip.channel[i].size = reader.ReadInt32();
chip.channel[i].start = reader.ReadInt32();
chip.channel[i].pos = reader.ReadInt32();
chip.channel[i].frac = reader.ReadInt32();
chip.channel[i].end = reader.ReadInt32();
chip.channel[i].volume = reader.ReadInt32();
chip.channel[i].pan = reader.ReadInt32();
chip.channel[i].effect = reader.ReadInt32();
chip.channel[i].play = reader.ReadInt32();
}
}
}
}