BizHawk/BizHawk.Emulation.Cores/Consoles/Atari/2600/Tia/Tia.MissleData.cs

142 lines
3.2 KiB
C#

using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
public partial class TIA
{
private struct MissileData
{
public bool Enabled;
public bool ResetToPlayer;
public byte HPosCnt;
public byte Size;
public byte Number;
public byte Hm;
public byte Collisions;
// Resp commands do not trigger start signals for main copies. We need to model this
private int _drawTo;
private byte _scanCnt;
private bool _scanCntInit;
private int _startSignal;
private int _signalReached;
public bool _draw_signaled;
public bool Tick()
{
var result = false;
if (_scanCntInit)
{
if (_scanCnt < 1 << Size && Enabled && !ResetToPlayer)
{
result = true;
_scanCnt++;
}
else
{
_scanCntInit = false;
}
}
if (_startSignal == 160)
{
_scanCnt = 0;
_startSignal++;
_scanCntInit = true;
}
if (_startSignal == 16 && ((Number & 0x07) == 0x01 || ((Number & 0x07) == 0x03)))
{
_scanCnt = 0;
_startSignal++;
_scanCntInit = true;
_draw_signaled = false;
}
if (_startSignal == 32 && ((Number & 0x07) == 0x02 || ((Number & 0x07) == 0x03) || ((Number & 0x07) == 0x06)))
{
_scanCnt = 0;
_startSignal++;
_scanCntInit = true;
_draw_signaled = false;
}
if (_startSignal == 64 && ((Number & 0x07) == 0x04 || ((Number & 0x07) == 0x06)))
{
_scanCnt = 0;
_startSignal++;
_scanCntInit = true;
_draw_signaled = false;
}
// Increment the counter
HPosCnt++;
// Counter loops at 160
HPosCnt %= 160;
// our goal here is to send a start signal 4 clocks before drawing begins. The properly emulates
// drawing on a real TIA
if (HPosCnt == 156 || HPosCnt == 12 || HPosCnt == 28 || HPosCnt == 60)
{
_startSignal = HPosCnt;
_signalReached = HPosCnt + 5;
_draw_signaled = true;
}
if (_startSignal < _signalReached)
{
_startSignal++;
}
return result;
}
public void Resp_check()
{
if (_draw_signaled)
{
if (_startSignal < 17)
{
_startSignal -= _startSignal - 12;
}
else if (_startSignal < 33)
{
_startSignal -= _startSignal - 28;
}
else if (_startSignal < 65)
{
_startSignal -= _startSignal - 60;
}
else if (_startSignal < 161)
{
_startSignal -= _startSignal - 156;
}
}
}
public void SyncState(Serializer ser)
{
ser.BeginSection("Missile");
ser.Sync("enabled", ref Enabled);
ser.Sync("resetToPlayer", ref ResetToPlayer);
ser.Sync("hPosCnt", ref HPosCnt);
ser.Sync("size", ref Size);
ser.Sync("number", ref Number);
ser.Sync("HM", ref Hm);
ser.Sync("collisions", ref Collisions);
ser.Sync("start_signal", ref _startSignal);
ser.Sync("signal_reached", ref _signalReached);
ser.Sync("draw_to", ref _drawTo);
ser.Sync("scanCnt", ref _scanCnt);
ser.Sync("scanCntInit", ref _scanCntInit);
ser.Sync("_draw_signaled", ref _draw_signaled);
ser.EndSection();
}
}
}
}