using BizHawk.Common;
using System.Collections.Generic;
namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
{
///
/// This class is responsible to "play" a tape file.
///
public class TapeBlockSetPlayer : ISupportsTapeBlockSetPlayback
{
///
/// All data blocks that can be played back
///
public List DataBlocks { get; }
///
/// Signs that the player completed playing back the file
///
private bool eof;
public bool Eof
{
get { return eof; }
set { eof = value; }
}
///
/// Gets the currently playing block's index
///
private int currentBlockIndex;
public int CurrentBlockIndex
{
get { return currentBlockIndex; }
set { currentBlockIndex = value; }
}
///
/// The current playable block
///
private ISupportsTapeBlockPlayback currentBlock;
public ISupportsTapeBlockPlayback CurrentBlock
{
get { return DataBlocks[CurrentBlockIndex]; }
//set { currentBlock = value; }
}
///
/// The current playing phase
///
private PlayPhase playPhase;
public PlayPhase PlayPhase
{
get { return playPhase; }
set { playPhase = value; }
}
///
/// The cycle count of the CPU when playing starts
///
private long startCycle;
public long StartCycle
{
get { return startCycle; }
set { startCycle = value; }
}
public TapeBlockSetPlayer(List dataBlocks)
{
DataBlocks = dataBlocks;
Eof = dataBlocks.Count == 0;
}
///
/// Initializes the player
///
public void InitPlay(long startTact)
{
CurrentBlockIndex = -1;
NextBlock(startTact);
PlayPhase = PlayPhase.None;
StartCycle = startTact;
}
///
/// Gets the EAR bit value for the specified cycle
///
/// Cycles to retrieve the EAR bit
///
/// A tuple of the EAR bit and a flag that indicates it is time to move to the next block
///
public bool GetEarBit(long currentCycle)
{
// --- Check for EOF
if (CurrentBlockIndex == DataBlocks.Count - 1
&& (CurrentBlock.PlayPhase == PlayPhase.Pause || CurrentBlock.PlayPhase == PlayPhase.Completed))
{
Eof = true;
}
if (CurrentBlockIndex >= DataBlocks.Count || CurrentBlock == null)
{
// --- After all playable block played back, there's nothing more to do
PlayPhase = PlayPhase.Completed;
return true;
}
var earbit = CurrentBlock.GetEarBit(currentCycle);
if (CurrentBlock.PlayPhase == PlayPhase.Completed)
{
NextBlock(currentCycle);
}
return earbit;
}
///
/// Moves the current block index to the next playable block
///
/// Cycles time to start the next block
public void NextBlock(long currentCycle)
{
if (CurrentBlockIndex >= DataBlocks.Count - 1)
{
PlayPhase = PlayPhase.Completed;
Eof = true;
return;
}
CurrentBlockIndex++;
CurrentBlock.InitPlay(currentCycle);
}
public void SyncState(Serializer ser)
{
ser.BeginSection("TapeBlockSetPlayer");
ser.Sync("eof", ref eof);
ser.Sync("currentBlockIndex", ref currentBlockIndex);
ser.SyncEnum("playPhase", ref playPhase);
ser.Sync("startCycle", ref startCycle);
currentBlock.SyncState(ser);
ser.EndSection();
}
}
}