using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
{
///
/// The abstract class that all emulated models will inherit from
/// * Imported media *
///
public abstract partial class CPCBase
{
///
/// The tape or disk image(s) that are passed in from the main ZXSpectrum class
///
protected List mediaImages { get; set; }
///
/// Tape images
///
public List tapeImages { get; set; }
///
/// Disk images
///
public List diskImages { get; set; }
///
/// The index of the currently 'loaded' tape image
///
protected int tapeMediaIndex;
public int TapeMediaIndex
{
get => tapeMediaIndex;
set
{
int tmp = value;
int result = value;
if (tapeImages == null || tapeImages.Count() == 0)
{
// no tape images found
return;
}
if (value >= tapeImages.Count())
{
// media at this index does not exist - loop back to 0
result = 0;
}
else if (value < 0)
{
// negative index not allowed - move to last item in the collection
result = tapeImages.Count() - 1;
}
// load the media into the tape device
tapeMediaIndex = result;
// fire osd message
//Spectrum.OSD_TapeInserted();
LoadTapeMedia();
}
}
///
/// The index of the currently 'loaded' disk image
///
protected int diskMediaIndex;
public int DiskMediaIndex
{
get => diskMediaIndex;
set
{
int tmp = value;
int result = value;
if (diskImages == null || diskImages.Count() == 0)
{
// no tape images found
return;
}
if (value >= diskImages.Count())
{
// media at this index does not exist - loop back to 0
result = 0;
}
else if (value < 0)
{
// negative index not allowed - move to last item in the collection
result = diskImages.Count() - 1;
}
// load the media into the disk device
diskMediaIndex = result;
// fire osd message
CPC.OSD_DiskInserted();
LoadDiskMedia();
}
}
///
/// Called on first instantiation (and subsequent core reboots)
///
protected void InitializeMedia(List files)
{
mediaImages = files;
LoadAllMedia();
}
///
/// Attempts to load all media into the relevant structures
///
protected void LoadAllMedia()
{
tapeImages = new List();
diskImages = new List();
int cnt = 0;
foreach (var m in mediaImages)
{
switch (IdentifyMedia(m))
{
case CPCMediaType.Tape:
tapeImages.Add(m);
CPC._tapeInfo.Add(CPC._gameInfo[cnt]);
break;
case CPCMediaType.Disk:
diskImages.Add(m);
CPC._diskInfo.Add(CPC._gameInfo[cnt]);
break;
case CPCMediaType.DiskDoubleSided:
// this is a bit tricky. we will attempt to parse the double sided disk image byte array,
// then output two separate image byte arrays
List working = new List();
foreach (DiskType type in Enum.GetValues(typeof(DiskType)))
{
bool found = false;
switch (type)
{
case DiskType.CPCExtended:
found = CPCExtendedFloppyDisk.SplitDoubleSided(m, working);
break;
case DiskType.CPC:
found = CPCFloppyDisk.SplitDoubleSided(m, working);
break;
}
if (found)
{
// add side 1
diskImages.Add(working[0]);
// add side 2
diskImages.Add(working[1]);
Common.GameInfo one = new Common.GameInfo();
Common.GameInfo two = new Common.GameInfo();
var gi = CPC._gameInfo[cnt];
for (int i = 0; i < 2; i++)
{
Common.GameInfo work = new Common.GameInfo();
if (i == 0)
{
work = one;
}
else if (i == 1)
{
work = two;
}
work.FirmwareHash = gi.FirmwareHash;
work.Hash = gi.Hash;
work.Name = gi.Name + " (Parsed Side " + (i + 1) + ")";
work.Region = gi.Region;
work.NotInDatabase = gi.NotInDatabase;
work.Status = gi.Status;
work.System = gi.System;
CPC._diskInfo.Add(work);
}
}
else
{
}
}
break;
}
cnt++;
}
if (tapeImages.Count > 0)
LoadTapeMedia();
if (diskImages.Count > 0)
LoadDiskMedia();
}
///
/// Attempts to load a tape into the tape device based on tapeMediaIndex
///
protected void LoadTapeMedia()
{
TapeDevice.LoadTape(tapeImages[tapeMediaIndex]);
}
///
/// Attempts to load a disk into the disk device based on diskMediaIndex
///
protected void LoadDiskMedia()
{
if (this.GetType() == typeof(CPC464))
{
CPC.CoreComm.ShowMessage("You are trying to load one of more disk images.\n\n Please select something other than CPC 464 emulation immediately and reboot the core");
return;
}
UPDDiskDevice.FDD_LoadDisk(diskImages[diskMediaIndex]);
}
///
/// Identifies and sorts the various media types
///
private CPCMediaType IdentifyMedia(byte[] data)
{
// get first 16 bytes as a string
string hdr = Encoding.ASCII.GetString(data.Take(16).ToArray());
// disk checking first
if (hdr.ToUpper().Contains("EXTENDED CPC DSK") || hdr.ToUpper().Contains("MV - CPC"))
{
// amstrad .dsk disk file
// check for number of sides
var sides = data[0x31];
if (sides == 1)
return CPCMediaType.Disk;
else
return CPCMediaType.DiskDoubleSided;
}
// tape checking
if (hdr.ToUpper().StartsWith("ZXTAPE!"))
{
// cdt tape file
return CPCMediaType.Tape;
}
// not found
return CPCMediaType.None;
}
}
public enum CPCMediaType
{
None,
Tape,
Disk,
DiskDoubleSided
}
}