GBC IR Emulation for GambatteLink
This commit is contained in:
parent
d9893b1d27
commit
72ad5c7b0b
Binary file not shown.
|
@ -31,34 +31,34 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cableDiscoSignalNew = controller.IsPressed("Toggle Cable Connection");
|
bool linkDiscoSignalNew = controller.IsPressed("Toggle Link Connection");
|
||||||
if (cableDiscoSignalNew && !_cableDiscoSignal)
|
if (linkDiscoSignalNew && !_linkDiscoSignal)
|
||||||
{
|
{
|
||||||
_cableConnected ^= true;
|
_linkConnected ^= true;
|
||||||
Console.WriteLine("Cable connect status to {0}", _cableConnected);
|
Console.WriteLine("Link connect status to {0}", _linkConnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cableDiscoSignal = cableDiscoSignalNew;
|
_linkDiscoSignal = linkDiscoSignalNew;
|
||||||
|
|
||||||
if (_numCores > 2)
|
if (_numCores > 2)
|
||||||
{
|
{
|
||||||
bool cableShiftSignalNew = controller.IsPressed("Toggle Cable Shift");
|
bool linkShiftSignalNew = controller.IsPressed("Toggle Link Shift");
|
||||||
if (cableShiftSignalNew && !_cableShiftSignal)
|
if (linkShiftSignalNew && !_linkShiftSignal)
|
||||||
{
|
{
|
||||||
_cableShifted ^= true;
|
_linkShifted ^= true;
|
||||||
Console.WriteLine("Cable shift status to {0}", _cableShifted);
|
Console.WriteLine("Link shift status to {0}", _linkShifted);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cableShifted = cableShiftSignalNew;
|
_linkShifted = linkShiftSignalNew;
|
||||||
|
|
||||||
bool cableSpaceSignalNew = controller.IsPressed("Toggle Cable Spacing");
|
bool linkSpaceSignalNew = controller.IsPressed("Toggle Link Spacing");
|
||||||
if (cableSpaceSignalNew && !_cableSpaceSignal)
|
if (linkSpaceSignalNew && !_linkSpaceSignal)
|
||||||
{
|
{
|
||||||
_cableSpaced ^= true;
|
_linkSpaced ^= true;
|
||||||
Console.WriteLine("Cable spacing status to {0}", _cableSpaceSignal);
|
Console.WriteLine("Link spacing status to {0}", _linkSpaceSignal);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cableSpaceSignal = cableSpaceSignalNew;
|
_linkSpaceSignal = linkSpaceSignalNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _numCores; i++)
|
for (int i = 0; i < _numCores; i++)
|
||||||
|
@ -75,7 +75,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
|
|
||||||
fixed (short* sbuff = &SoundBuffer[0])
|
fixed (short* sbuff = &SoundBuffer[0])
|
||||||
{
|
{
|
||||||
const int Step = 32; // could be 1024 for GB
|
const int Step = 4;
|
||||||
|
|
||||||
int[] n = new int[_numCores];
|
int[] n = new int[_numCores];
|
||||||
for (int i = 0; i < _numCores; i++)
|
for (int i = 0; i < _numCores; i++)
|
||||||
|
@ -111,7 +111,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
}
|
}
|
||||||
|
|
||||||
// poll link cable statuses, but not when the cable is disconnected
|
// poll link cable statuses, but not when the cable is disconnected
|
||||||
if (!_cableConnected)
|
if (!_linkConnected)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -120,51 +120,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
TryCableBytewiseTransfer(P1, P2);
|
TryLinkTransfer(P1, P2);
|
||||||
TryCableBytewiseTransfer(P2, P1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
if (_cableSpaced)
|
if (_linkSpaced)
|
||||||
{
|
{
|
||||||
TryCableBytewiseTransfer(P1, P3);
|
TryLinkTransfer(P1, P3);
|
||||||
TryCableBytewiseTransfer(P3, P1);
|
|
||||||
}
|
}
|
||||||
else if (_cableShifted)
|
else if (_linkShifted)
|
||||||
{
|
{
|
||||||
TryCableBytewiseTransfer(P2, P3);
|
TryLinkTransfer(P2, P3);
|
||||||
TryCableBytewiseTransfer(P3, P2);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TryCableBytewiseTransfer(P1, P2);
|
TryLinkTransfer(P1, P2);
|
||||||
TryCableBytewiseTransfer(P2, P1);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
if (_cableSpaced)
|
if (_linkSpaced)
|
||||||
{
|
{
|
||||||
TryCableBytewiseTransfer(P1, P3);
|
TryLinkTransfer(P1, P3);
|
||||||
TryCableBytewiseTransfer(P3, P1);
|
TryLinkTransfer(P2, P4);
|
||||||
TryCableBytewiseTransfer(P2, P4);
|
|
||||||
TryCableBytewiseTransfer(P4, P2);
|
|
||||||
}
|
}
|
||||||
else if (_cableShifted)
|
else if (_linkShifted)
|
||||||
{
|
{
|
||||||
TryCableBytewiseTransfer(P2, P3);
|
TryLinkTransfer(P2, P3);
|
||||||
TryCableBytewiseTransfer(P3, P2);
|
TryLinkTransfer(P4, P1);
|
||||||
TryCableBytewiseTransfer(P4, P1);
|
|
||||||
TryCableBytewiseTransfer(P1, P4);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TryCableBytewiseTransfer(P1, P2);
|
TryLinkTransfer(P1, P2);
|
||||||
TryCableBytewiseTransfer(P2, P1);
|
TryLinkTransfer(P3, P4);
|
||||||
TryCableBytewiseTransfer(P3, P4);
|
|
||||||
TryCableBytewiseTransfer(P4, P3);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -217,16 +207,62 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryCableBytewiseTransfer(int master, int slave)
|
private void TryLinkTransfer(int one, int two)
|
||||||
{
|
{
|
||||||
if (LibGambatte.gambatte_linkstatus(_linkedCores[master].GambatteState, 256) != 0) // ClockTrigger
|
if (LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 256) != 0) // ClockTrigger
|
||||||
{
|
{
|
||||||
LibGambatte.gambatte_linkstatus(_linkedCores[master].GambatteState, 257); // ack
|
LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 257); // ack
|
||||||
int om = LibGambatte.gambatte_linkstatus(_linkedCores[master].GambatteState, 258); // GetOut
|
int oo = LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 258); // GetOut
|
||||||
int os = LibGambatte.gambatte_linkstatus(_linkedCores[slave].GambatteState, 258);
|
int ot = LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 258);
|
||||||
LibGambatte.gambatte_linkstatus(_linkedCores[slave].GambatteState, om & 0xff); // ShiftIn
|
LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, oo & 0xff); // ShiftIn
|
||||||
LibGambatte.gambatte_linkstatus(_linkedCores[master].GambatteState, os & 0xff); // ShiftIn
|
LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, ot & 0xff); // ShiftIn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 256) != 0) // ClockTrigger
|
||||||
|
{
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 257); // ack
|
||||||
|
int ot = LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 258); // GetOut
|
||||||
|
int oo = LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 258);
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, ot & 0xff); // ShiftIn
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, oo & 0xff); // ShiftIn
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CanIR(one, two))
|
||||||
|
{
|
||||||
|
if (LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 260) != 0) // InfraredTrigger
|
||||||
|
{
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 261); // ack
|
||||||
|
if (LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 262) != 0) // GetOut
|
||||||
|
{
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 263); // ShiftInOn
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 264); // ShiftInOff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 260) != 0) // InfraredTrigger
|
||||||
|
{
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 261); // ack
|
||||||
|
if (LibGambatte.gambatte_linkstatus(_linkedCores[two].GambatteState, 262) != 0) // GetOut
|
||||||
|
{
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 263); // ShiftInOn
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LibGambatte.gambatte_linkstatus(_linkedCores[one].GambatteState, 264); // ShiftInOff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanIR(int one, int two)
|
||||||
|
{
|
||||||
|
// the GB and GBA have no IR port, so ignore them for now
|
||||||
|
// todo: cart based IR
|
||||||
|
return _syncSettings._linkedSyncSettings[one].ConsoleMode is Gameboy.GambatteSyncSettings.ConsoleModeType.GBC
|
||||||
|
&& _syncSettings._linkedSyncSettings[two].ConsoleMode is Gameboy.GambatteSyncSettings.ConsoleModeType.GBC;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Frame { get; private set; }
|
public int Frame { get; private set; }
|
||||||
|
|
|
@ -19,23 +19,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
|
|
||||||
public PutSettingsDirtyBits PutSettings(GambatteLinkSettings o)
|
public PutSettingsDirtyBits PutSettings(GambatteLinkSettings o)
|
||||||
{
|
{
|
||||||
_settings = o;
|
|
||||||
var ret = PutSettingsDirtyBits.None;
|
var ret = PutSettingsDirtyBits.None;
|
||||||
for (int i = 0; i < _numCores; i++)
|
for (int i = 0; i < _numCores; i++)
|
||||||
{
|
{
|
||||||
ret |= _linkedCores[i].PutSettings(o._linkedSettings[i]);
|
ret |= _linkedCores[i].PutSettings(o._linkedSettings[i]);
|
||||||
}
|
}
|
||||||
|
_settings = o;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PutSettingsDirtyBits PutSyncSettings(GambatteLinkSyncSettings o)
|
public PutSettingsDirtyBits PutSyncSettings(GambatteLinkSyncSettings o)
|
||||||
{
|
{
|
||||||
_syncSettings = o;
|
|
||||||
var ret = PutSettingsDirtyBits.None;
|
var ret = PutSettingsDirtyBits.None;
|
||||||
for (int i = 0; i < _numCores; i++)
|
for (int i = 0; i < _numCores; i++)
|
||||||
{
|
{
|
||||||
ret |= _linkedCores[i].PutSyncSettings(o._linkedSyncSettings[i]);
|
ret |= _linkedCores[i].PutSyncSettings(o._linkedSyncSettings[i]);
|
||||||
}
|
}
|
||||||
|
_syncSettings = o;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,12 +30,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
IsLagFrame = s.IsLagFrame;
|
IsLagFrame = s.IsLagFrame;
|
||||||
LagCount = s.LagCount;
|
LagCount = s.LagCount;
|
||||||
Frame = s.Frame;
|
Frame = s.Frame;
|
||||||
_cableConnected = s.CableConnected;
|
_linkConnected = s.LinkConnected;
|
||||||
_cableDiscoSignal = s.CableDiscoSignal;
|
_linkDiscoSignal = s.LinkDiscoSignal;
|
||||||
_cableShifted = s.CableShifted;
|
_linkShifted = s.LinkShifted;
|
||||||
_cableShiftSignal = s.CableShiftSignal;
|
_linkShiftSignal = s.LinkShiftSignal;
|
||||||
_cableSpaced = s.CableSpaced;
|
_linkSpaced = s.LinkSpaced;
|
||||||
_cableSpaceSignal = s.CableSpaceSignal;
|
_linkSpaceSignal = s.LinkSpaceSignal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveStateBinary(BinaryWriter writer)
|
public void SaveStateBinary(BinaryWriter writer)
|
||||||
|
@ -51,12 +51,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
writer.Write(IsLagFrame);
|
writer.Write(IsLagFrame);
|
||||||
writer.Write(LagCount);
|
writer.Write(LagCount);
|
||||||
writer.Write(Frame);
|
writer.Write(Frame);
|
||||||
writer.Write(_cableConnected);
|
writer.Write(_linkConnected);
|
||||||
writer.Write(_cableDiscoSignal);
|
writer.Write(_linkDiscoSignal);
|
||||||
writer.Write(_cableShifted);
|
writer.Write(_linkShifted);
|
||||||
writer.Write(_cableShiftSignal);
|
writer.Write(_linkShiftSignal);
|
||||||
writer.Write(_cableSpaced);
|
writer.Write(_linkSpaced);
|
||||||
writer.Write(_cableSpaceSignal);
|
writer.Write(_linkSpaceSignal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadStateBinary(BinaryReader reader)
|
public void LoadStateBinary(BinaryReader reader)
|
||||||
|
@ -75,12 +75,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
IsLagFrame = reader.ReadBoolean();
|
IsLagFrame = reader.ReadBoolean();
|
||||||
LagCount = reader.ReadInt32();
|
LagCount = reader.ReadInt32();
|
||||||
Frame = reader.ReadInt32();
|
Frame = reader.ReadInt32();
|
||||||
_cableConnected = reader.ReadBoolean();
|
_linkConnected = reader.ReadBoolean();
|
||||||
_cableDiscoSignal = reader.ReadBoolean();
|
_linkDiscoSignal = reader.ReadBoolean();
|
||||||
_cableShifted = reader.ReadBoolean();
|
_linkShifted = reader.ReadBoolean();
|
||||||
_cableShiftSignal = reader.ReadBoolean();
|
_linkShiftSignal = reader.ReadBoolean();
|
||||||
_cableSpaced = reader.ReadBoolean();
|
_linkSpaced = reader.ReadBoolean();
|
||||||
_cableSpaceSignal = reader.ReadBoolean();
|
_linkSpaceSignal = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly JsonSerializer ser = new JsonSerializer { Formatting = Formatting.Indented };
|
private readonly JsonSerializer ser = new JsonSerializer { Formatting = Formatting.Indented };
|
||||||
|
@ -95,12 +95,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
public int Frame;
|
public int Frame;
|
||||||
public int[] LinkedOverflow;
|
public int[] LinkedOverflow;
|
||||||
public int[] LinkedLatches;
|
public int[] LinkedLatches;
|
||||||
public bool CableConnected;
|
public bool LinkConnected;
|
||||||
public bool CableDiscoSignal;
|
public bool LinkDiscoSignal;
|
||||||
public bool CableShifted;
|
public bool LinkShifted;
|
||||||
public bool CableShiftSignal;
|
public bool LinkShiftSignal;
|
||||||
public bool CableSpaced;
|
public bool LinkSpaced;
|
||||||
public bool CableSpaceSignal;
|
public bool LinkSpaceSignal;
|
||||||
|
|
||||||
public DGBSerialized(GambatteLink linkcore)
|
public DGBSerialized(GambatteLink linkcore)
|
||||||
{
|
{
|
||||||
|
@ -117,12 +117,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
IsLagFrame = linkcore.IsLagFrame;
|
IsLagFrame = linkcore.IsLagFrame;
|
||||||
LagCount = linkcore.LagCount;
|
LagCount = linkcore.LagCount;
|
||||||
Frame = linkcore.Frame;
|
Frame = linkcore.Frame;
|
||||||
CableConnected = linkcore._cableConnected;
|
LinkConnected = linkcore._linkConnected;
|
||||||
CableDiscoSignal = linkcore._cableDiscoSignal;
|
LinkDiscoSignal = linkcore._linkDiscoSignal;
|
||||||
CableShifted = linkcore._cableShifted;
|
LinkShifted = linkcore._linkShifted;
|
||||||
CableShiftSignal = linkcore._cableShiftSignal;
|
LinkShiftSignal = linkcore._linkShiftSignal;
|
||||||
CableSpaced = linkcore._cableSpaced;
|
LinkSpaced = linkcore._linkSpaced;
|
||||||
CableSpaceSignal = linkcore._cableSpaceSignal;
|
LinkSpaceSignal = linkcore._linkSpaceSignal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,8 +75,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
|
|
||||||
public bool LinkConnected
|
public bool LinkConnected
|
||||||
{
|
{
|
||||||
get => _cableConnected;
|
get => _linkConnected;
|
||||||
set => _cableConnected = value;
|
set => _linkConnected = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _numCores = 0;
|
private int _numCores = 0;
|
||||||
|
@ -89,23 +89,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
// counters to ensure we do 35112 samples per frame
|
// counters to ensure we do 35112 samples per frame
|
||||||
private readonly int[] _linkedOverflow;
|
private readonly int[] _linkedOverflow;
|
||||||
|
|
||||||
// if true, the link cable is currently connected
|
// if true, the link connection is currently active
|
||||||
private bool _cableConnected = true;
|
private bool _linkConnected = true;
|
||||||
|
|
||||||
// if true, the link cable is currently shifted (3x/4x only)
|
// if true, the link is currently shifted (3x/4x only)
|
||||||
private bool _cableShifted = false;
|
private bool _linkShifted = false;
|
||||||
|
|
||||||
// if true, the link cable is currently spaced outwards (3x/4x only)
|
// if true, the link is currently spaced outwards (3x/4x only)
|
||||||
private bool _cableSpaced = false;
|
private bool _linkSpaced = false;
|
||||||
|
|
||||||
// if true, the link cable toggle signal is currently asserted
|
// if true, the link toggle signal is currently asserted
|
||||||
private bool _cableDiscoSignal = false;
|
private bool _linkDiscoSignal = false;
|
||||||
|
|
||||||
// if true, the link cable shift signal is currently asserted
|
// if true, the link shift signal is currently asserted
|
||||||
private bool _cableShiftSignal = false;
|
private bool _linkShiftSignal = false;
|
||||||
|
|
||||||
// if true, the link cable spacing signal is currently asserted
|
// if true, the link cable spacing signal is currently asserted
|
||||||
private bool _cableSpaceSignal = false;
|
private bool _linkSpaceSignal = false;
|
||||||
|
|
||||||
private const int SampPerFrame = 35112;
|
private const int SampPerFrame = 35112;
|
||||||
private const int MaxSampsPerFrame = (SampPerFrame + 2064) * 2;
|
private const int MaxSampsPerFrame = (SampPerFrame + 2064) * 2;
|
||||||
|
@ -128,11 +128,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
new[] { "Up", "Down", "Left", "Right", "A", "B", "Select", "Start", "Power" }
|
new[] { "Up", "Down", "Left", "Right", "A", "B", "Select", "Start", "Power" }
|
||||||
.Select(s => $"P{i + 1} {s}"));
|
.Select(s => $"P{i + 1} {s}"));
|
||||||
}
|
}
|
||||||
ret.BoolButtons.Add("Toggle Cable Connection");
|
ret.BoolButtons.Add("Toggle Link Connection");
|
||||||
if (_numCores > 2)
|
if (_numCores > 2)
|
||||||
{
|
{
|
||||||
ret.BoolButtons.Add("Toggle Cable Shift");
|
ret.BoolButtons.Add("Toggle Link Shift");
|
||||||
ret.BoolButtons.Add("Toggle Cable Spacing");
|
ret.BoolButtons.Add("Toggle Link Spacing");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f1ae63f57778f9869bd79000f1d300ed532400ff
|
Subproject commit d5abea79e1571a2078c1fc689969b839e08d82e7
|
Loading…
Reference in New Issue