163 lines
3.4 KiB
C#
163 lines
3.4 KiB
C#
using BizHawk.Common;
|
|
|
|
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|
{
|
|
public partial class TIA
|
|
{
|
|
private struct PlayerData
|
|
{
|
|
public MissileData Missile;
|
|
|
|
public byte Grp;
|
|
public byte Dgrp;
|
|
public byte Color;
|
|
public byte HPosCnt;
|
|
public byte ScanCnt;
|
|
public byte ScanStrchCnt;
|
|
public byte HM;
|
|
public bool Reflect;
|
|
public bool Delay;
|
|
public byte Nusiz;
|
|
public bool Reset;
|
|
public byte ResetCnt;
|
|
public byte Collisions;
|
|
|
|
public bool Tick()
|
|
{
|
|
var result = false;
|
|
if (ScanCnt < 8)
|
|
{
|
|
// Make the mask to check the graphic
|
|
byte playerMask = (byte)(1 << (8 - 1 - ScanCnt));
|
|
|
|
// Reflect it if needed
|
|
if (Reflect)
|
|
{
|
|
playerMask = (byte)ReverseBits(playerMask, 8);
|
|
}
|
|
|
|
// Check the graphic (depending on delay)
|
|
if (!Delay)
|
|
{
|
|
if ((Grp & playerMask) != 0)
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((Dgrp & playerMask) != 0)
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
// Reset missile, if desired
|
|
if (ScanCnt == 0x04 && HPosCnt <= 16 && Missile.ResetToPlayer)
|
|
{
|
|
Missile.HPosCnt = 0;
|
|
}
|
|
|
|
// Increment counter
|
|
// When this reaches 8, we've run out of pixel
|
|
|
|
// If we're drawing a stretched player, only incrememnt the
|
|
// counter every 2 or 4 clocks
|
|
|
|
// Double size player
|
|
if ((Nusiz & 0x07) == 0x05)
|
|
{
|
|
ScanStrchCnt++;
|
|
ScanStrchCnt %= 2;
|
|
}
|
|
|
|
// Quad size player
|
|
else if ((Nusiz & 0x07) == 0x07)
|
|
{
|
|
ScanStrchCnt++;
|
|
ScanStrchCnt %= 4;
|
|
}
|
|
|
|
// Single size player
|
|
else
|
|
{
|
|
ScanStrchCnt = 0;
|
|
}
|
|
|
|
if (ScanStrchCnt == 0)
|
|
{
|
|
ScanCnt++;
|
|
}
|
|
}
|
|
|
|
// At counter position 0 we should start drawing, a pixel late
|
|
// Set the scan counter at 0, and at the next pixel the graphic will start drawing
|
|
if (HPosCnt == 0 && !Reset)
|
|
{
|
|
ScanCnt = 0;
|
|
if ((Nusiz & 0x07) == 0x05 || (Nusiz & 0x07) == 0x07)
|
|
{
|
|
ScanStrchCnt = 0;
|
|
}
|
|
}
|
|
|
|
if (HPosCnt == 16 && ((Nusiz & 0x07) == 0x01 || ((Nusiz & 0x07) == 0x03)))
|
|
{
|
|
ScanCnt = 0;
|
|
}
|
|
|
|
if (HPosCnt == 32 && ((Nusiz & 0x07) == 0x02 || ((Nusiz & 0x07) == 0x03) || ((Nusiz & 0x07) == 0x06)))
|
|
{
|
|
ScanCnt = 0;
|
|
}
|
|
|
|
if (HPosCnt == 64 && ((Nusiz & 0x07) == 0x04 || ((Nusiz & 0x07) == 0x06)))
|
|
{
|
|
ScanCnt = 0;
|
|
}
|
|
|
|
// Reset is no longer in effect
|
|
Reset = false;
|
|
|
|
// Increment the counter
|
|
HPosCnt++;
|
|
|
|
// Counter loops at 160
|
|
HPosCnt %= 160;
|
|
|
|
if (ResetCnt < 4)
|
|
{
|
|
ResetCnt++;
|
|
}
|
|
|
|
if (ResetCnt == 4)
|
|
{
|
|
HPosCnt = 0;
|
|
Reset = true;
|
|
ResetCnt++;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public void SyncState(Serializer ser)
|
|
{
|
|
Missile.SyncState(ser);
|
|
ser.Sync("grp", ref Grp);
|
|
ser.Sync("dgrp", ref Dgrp);
|
|
ser.Sync("color", ref Color);
|
|
ser.Sync("hPosCnt", ref HPosCnt);
|
|
ser.Sync("scanCnt", ref ScanCnt);
|
|
ser.Sync("scanStrchCnt", ref ScanStrchCnt);
|
|
ser.Sync("HM", ref HM);
|
|
ser.Sync("reflect", ref Reflect);
|
|
ser.Sync("delay", ref Delay);
|
|
ser.Sync("nusiz", ref Nusiz);
|
|
ser.Sync("reset", ref Reset);
|
|
ser.Sync("resetCnt", ref ResetCnt);
|
|
ser.Sync("collisions", ref Collisions);
|
|
}
|
|
}
|
|
}
|
|
}
|