169 lines
5.2 KiB
C++
169 lines
5.2 KiB
C++
#include "mednafen/src/types.h"
|
|
#include <emulibc.h>
|
|
#include <waterboxcore.h>
|
|
#include <src/mednafen.h>
|
|
#include <stdint.h>
|
|
#include <src/cdrom/CDInterface.h>
|
|
#include <src/cdrom/CDInterface_MT.h>
|
|
#include <src/cdrom/CDInterface_ST.h>
|
|
#include <src/cdrom/CDAccess.h>
|
|
#include <trio/trio.h>
|
|
|
|
#include "cdrom.h"
|
|
|
|
using namespace Mednafen;
|
|
|
|
struct NymaTOC
|
|
{
|
|
int32_t FirstTrack;
|
|
int32_t LastTrack;
|
|
int32_t DiskType;
|
|
struct
|
|
{
|
|
int32_t Adr;
|
|
int32_t Control;
|
|
int32_t Lba;
|
|
int32_t Valid;
|
|
} Tracks[101];
|
|
};
|
|
|
|
static void (*ReadTOCCallback)(int disk, NymaTOC *dest);
|
|
static void (*ReadSector2448Callback)(int disk, int lba, uint8 *dest);
|
|
|
|
ECL_EXPORT void SetCDCallbacks(void (*toccallback)(int disk, NymaTOC *dest), void (*sectorcallback)(int disk, int lba, uint8 *dest))
|
|
{
|
|
ReadTOCCallback = toccallback;
|
|
ReadSector2448Callback = sectorcallback;
|
|
}
|
|
|
|
CDInterfaceNyma::CDInterfaceNyma(int d) : disk(d)
|
|
{
|
|
NymaTOC t;
|
|
ReadTOCCallback(disk, &t);
|
|
disc_toc.first_track = t.FirstTrack;
|
|
disc_toc.last_track = t.LastTrack;
|
|
disc_toc.disc_type = t.DiskType;
|
|
for (int i = 0; i < 101; i++)
|
|
{
|
|
disc_toc.tracks[i].adr = t.Tracks[i].Adr;
|
|
disc_toc.tracks[i].control = t.Tracks[i].Control;
|
|
disc_toc.tracks[i].lba = t.Tracks[i].Lba;
|
|
disc_toc.tracks[i].valid = t.Tracks[i].Valid;
|
|
}
|
|
}
|
|
|
|
void CDInterfaceNyma::HintReadSector(int32 lba) {}
|
|
bool CDInterfaceNyma::ReadRawSector(uint8 *buf, int32 lba)
|
|
{
|
|
ReadSector2448Callback(disk, lba, buf);
|
|
return true;
|
|
}
|
|
bool CDInterfaceNyma::ReadRawSectorPWOnly(uint8 *pwbuf, int32 lba, bool hint_fullread)
|
|
{
|
|
uint8 buff[2448];
|
|
ReadSector2448Callback(disk, lba, buff);
|
|
memcpy(pwbuf, buff + 2352, 96);
|
|
return true;
|
|
}
|
|
|
|
std::vector<CDInterface*>* CDInterfaces;
|
|
|
|
void StartGameWithCds(int numdisks)
|
|
{
|
|
CDInterfaces = new std::vector<CDInterface*>();
|
|
for (int d = 0; d < numdisks; d++)
|
|
{
|
|
CDInterfaces->push_back(new CDInterfaceNyma(d));
|
|
}
|
|
MDFNGameInfo->LoadCD(CDInterfaces);
|
|
|
|
// TODO: Figure out wtf all this RMD stuff is
|
|
auto rmd = new RMD_Layout();
|
|
{
|
|
RMD_Drive dr;
|
|
|
|
dr.Name = "Virtual CD Drive";
|
|
dr.PossibleStates.push_back(RMD_State({"Tray Open", false, false, true}));
|
|
dr.PossibleStates.push_back(RMD_State({"Tray Closed (Empty)", false, false, false}));
|
|
dr.PossibleStates.push_back(RMD_State({"Tray Closed", true, true, false}));
|
|
dr.CompatibleMedia.push_back(0);
|
|
dr.MediaMtoPDelay = 2000;
|
|
|
|
rmd->Drives.push_back(dr);
|
|
rmd->DrivesDefaults.push_back(RMD_DriveDefaults({0, 0, 0}));
|
|
rmd->MediaTypes.push_back(RMD_MediaType({"CD"}));
|
|
}
|
|
|
|
const int default_cd = 0;
|
|
|
|
for(size_t i = 0; i < CDInterfaces->size(); i++)
|
|
{
|
|
if (i == default_cd)
|
|
{
|
|
rmd->DrivesDefaults[0].State = 2; // Tray Closed
|
|
rmd->DrivesDefaults[0].Media = i;
|
|
rmd->DrivesDefaults[0].Orientation = 0;
|
|
}
|
|
char namebuf[128];
|
|
trio_snprintf(namebuf, sizeof(namebuf), _("Disc %zu of %zu"), i + 1, CDInterfaces->size());
|
|
rmd->Media.push_back(RMD_Media({namebuf, 0}));
|
|
}
|
|
MDFNGameInfo->RMD = rmd;
|
|
|
|
Mednafen::MDFNGameInfo->SetMedia(
|
|
0, // drive: 0 unless there's more than one drive
|
|
2, // state: 0 = open, 1 = closed (media absent), 2 = closed (media present)
|
|
0, // media: index into the disk list
|
|
0 // orientation: flip sides on NES FDS. not used elsewhere?
|
|
);
|
|
}
|
|
static bool trayOpen = false;
|
|
static int curCd = 0; // -1 means no media present
|
|
void SwitchCds(bool open, bool close, int cd)
|
|
{
|
|
if (open && !trayOpen)
|
|
{
|
|
Mednafen::MDFNGameInfo->SetMedia(
|
|
0, // drive: 0 unless there's more than one drive
|
|
0, // state: 0 = open, 1 = closed (media absent), 2 = closed (media present)
|
|
std::max(curCd, 0), // media: index into the disk list
|
|
0 // orientation: flip sides on NES FDS. not used elsewhere?
|
|
);
|
|
|
|
trayOpen = true;
|
|
}
|
|
|
|
if (close && trayOpen)
|
|
{
|
|
Mednafen::MDFNGameInfo->SetMedia(
|
|
0, // drive: 0 unless there's more than one drive
|
|
cd == -1 ? 1 : 2, // state: 0 = open, 1 = closed (media absent), 2 = closed (media present)
|
|
std::max(cd, 0), // media: index into the disk list
|
|
0 // orientation: flip sides on NES FDS. not used elsewhere?
|
|
);
|
|
|
|
trayOpen = false;
|
|
curCd = cd;
|
|
}
|
|
}
|
|
|
|
// CDInterface::Load pulls in a bunch of things that we do not want, stub them out here
|
|
namespace Mednafen
|
|
{
|
|
using namespace CDUtility;
|
|
CDInterface_MT::CDInterface_Message::~CDInterface_Message(){}
|
|
CDInterface_MT::CDInterface_Queue::CDInterface_Queue(){}
|
|
CDInterface_MT::CDInterface_Queue::~CDInterface_Queue(){}
|
|
CDInterface_MT::CDInterface_MT(std::unique_ptr<CDAccess> cda, const uint64 affinity){}
|
|
CDInterface_MT::~CDInterface_MT(){}
|
|
bool CDInterface_MT::ReadRawSector(uint8 *buf, int32 lba){return false;}
|
|
bool CDInterface_MT::ReadRawSectorPWOnly(uint8* pwbuf, int32 lba, bool hint_fullread){return false;}
|
|
void CDInterface_MT::HintReadSector(int32 lba){}
|
|
CDInterface_ST::CDInterface_ST(std::unique_ptr<CDAccess> cda) : disc_cdaccess(std::move(cda)){}
|
|
CDInterface_ST::~CDInterface_ST(){}
|
|
void CDInterface_ST::HintReadSector(int32 lba){}
|
|
bool CDInterface_ST::ReadRawSector(uint8 *buf, int32 lba){return false;}
|
|
bool CDInterface_ST::ReadRawSectorPWOnly(uint8* pwbuf, int32 lba, bool hint_fullread){return false;}
|
|
CDAccess* CDAccess_Open(VirtualFS* vfs, const std::string& path, bool image_memcache){return nullptr;}
|
|
}
|