psx - disc swapping

This commit is contained in:
zeromus 2014-12-16 10:47:50 +00:00
parent bcf053d0e9
commit 7f44621f97
3 changed files with 62 additions and 58 deletions

View File

@ -66,8 +66,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
static Octoshock CurrOctoshockCore;
IntPtr psx;
DiscSystem.Disc disc;
DiscInterface discInterface;
bool disposed = false;
public void Dispose()
@ -78,6 +76,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
psx = IntPtr.Zero;
disposed = true;
//TODO - dispose disc wrappers
//TODO - dispose discs
}
/// <summary>
@ -85,7 +86,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
/// </summary>
class DiscInterface : IDisposable
{
public DiscInterface(DiscSystem.Disc disc, Action cbActivity)
public DiscInterface(DiscSystem.Disc disc, Action<DiscInterface> cbActivity)
{
this.Disc = disc;
cbReadTOC = ShockDisc_ReadTOC;
@ -96,7 +97,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
OctoshockDll.ShockDisc_ReadTOC cbReadTOC;
OctoshockDll.ShockDisc_ReadLBA cbReadLBA;
Action cbActivity;
Action<DiscInterface> cbActivity;
public DiscSystem.Disc Disc;
public IntPtr OctoshockHandle;
@ -145,7 +146,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
int ShockDisc_ReadLBA2448(IntPtr opaque, int lba, void* dst)
{
cbActivity();
cbActivity(this);
//lets you check subcode generation by logging it and checking against the CCD subcode
bool subcodeLog = false;
@ -170,6 +171,8 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
}
}
List<DiscInterface> discInterfaces = new List<DiscInterface>();
DiscInterface currentDiscInterface;
//note: its annoying that we have to have a disc before constructing this.
//might want to change that later. HOWEVER - we need to definitely have a region, at least
@ -177,10 +180,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
{
//analyze our first disc from the list by default, because i dont know
DiscSystem.Disc disc = null;
if (discs != null)
disc = discs[0];
ServiceProvider = new BasicServiceProvider(this);
CoreComm = comm;
@ -191,34 +190,40 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
Attach();
this.disc = disc;
string firmwareRegion = "U";
OctoshockDll.eRegion region = OctoshockDll.eRegion.NA;
if (disc != null)
if (discs != null)
{
discInterface = new DiscInterface(disc,
() =>
{
//if current disc this delegate disc, activity is happening
if (disc == this.disc)
DriveLightOn = true;
});
foreach(var disc in discs)
{
var discInterface = new DiscInterface(disc,
(di) =>
{
//if current disc this delegate disc, activity is happening
if (di == currentDiscInterface)
DriveLightOn = true;
});
//determine region of the provided disc
OctoshockDll.ShockDiscInfo discInfo;
OctoshockDll.shock_AnalyzeDisc(discInterface.OctoshockHandle, out discInfo);
//try to acquire the appropriate firmware
if (discInfo.region == OctoshockDll.eRegion.EU) firmwareRegion = "E";
if (discInfo.region == OctoshockDll.eRegion.JP) firmwareRegion = "J";
discInterfaces.Add(discInterface);
}
}
else
{
//assume its NA region for test programs, for now. could it be read out of the ps-exe header?
}
if (discInterfaces.Count != 0)
{
//determine region of one of the discs
OctoshockDll.ShockDiscInfo discInfo;
OctoshockDll.shock_AnalyzeDisc(discInterfaces[0].OctoshockHandle, out discInfo);
//try to acquire the appropriate firmware
if (discInfo.region == OctoshockDll.eRegion.EU) firmwareRegion = "E";
if (discInfo.region == OctoshockDll.eRegion.JP) firmwareRegion = "J";
}
byte[] firmware = comm.CoreFileProvider.GetFirmware("PSX", "U", true, "A PSX `" + firmwareRegion + "` region bios file is required");
//create the instance
@ -247,11 +252,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
BufferHeight = VirtualHeight;
frameBuffer = new int[BufferWidth * BufferHeight];
if (disc != null)
if (discInterfaces.Count != 0)
{
OctoshockDll.shock_OpenTray(psx);
OctoshockDll.shock_SetDisc(psx, discInterface.OctoshockHandle);
OctoshockDll.shock_CloseTray(psx);
//disc will be set during first frame advance
}
else
{
@ -334,6 +337,22 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
SetInput();
if (Controller["Eject"]) OctoshockDll.shock_OpenTray(psx);
//if requested disc is not matching current disc, set it now
int discChoice = (int)Controller.GetFloat("Disc Select") - 1;
if (discChoice >= discInterfaces.Count)
discChoice = discInterfaces.Count - 1;
if (discInterfaces[discChoice] != currentDiscInterface)
{
currentDiscInterface = discInterfaces[discChoice];
if (!Controller["Eject"]) OctoshockDll.shock_OpenTray(psx); //open tray if needed
OctoshockDll.shock_SetDisc(psx, currentDiscInterface.OctoshockHandle);
}
if (!Controller["Eject"]) OctoshockDll.shock_CloseTray(psx);
OctoshockDll.shock_Step(psx, OctoshockDll.eShockStep.Frame);
//what happens to sound in this case?

Binary file not shown.

View File

@ -159,7 +159,6 @@ class PSF1Loader {};
static PSF1Loader *psf_loader = NULL;
static std::vector<CDIF*> *cdifs = NULL;
static std::vector<const char *> cdifs_scex_ids;
static bool CD_TrayOpen;
static uint64 Memcard_PrevDC[8];
static int64 Memcard_SaveDelay[8];
@ -969,7 +968,6 @@ uint32 PSX_MemPeek32(uint32 A)
return MemPeek<uint32, false>(0, A);
}
// FIXME: Add PSX_Reset() and FrontIO::Reset() so that emulated input devices don't get power-reset on reset-button reset.
static void PSX_Power(bool powering_up)
{
PSX_PRNG.ResetState(); // Should occur first!
@ -1032,6 +1030,7 @@ struct ShockConfig
struct ShockState
{
bool power;
bool eject;
} s_ShockState;
@ -1268,9 +1267,10 @@ EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k)
MountCPUAddressSpace();
s_ShockState.power = false;
s_ShockState.eject = false;
//TODO - not the ideal starting condition, need to make sure its all sensible as being closed
CD_TrayOpen = true;
//set tray closed with no disc
CDC->SetDisc(false,NULL,"");
return SHOCK_OK;
}
@ -1849,28 +1849,6 @@ static void CloseGame(void)
Cleanup();
}
static void CDInsertEject(void)
{
CD_TrayOpen = !CD_TrayOpen;
for(unsigned disc = 0; disc < cdifs->size(); disc++)
{
if(!(*cdifs)[disc]->Eject(CD_TrayOpen))
{
CD_TrayOpen = !CD_TrayOpen;
}
}
//DAWWWWW
//CDC->SetDisc(CD_TrayOpen, (CD_SelectedDisc >= 0 && !CD_TrayOpen) ? (*cdifs)[CD_SelectedDisc] : NULL,
//(CD_SelectedDisc >= 0 && !CD_TrayOpen) ? cdifs_scex_ids[CD_SelectedDisc] : NULL);
}
EW_EXPORT s32 shock_CreateDisc(ShockDiscRef** outDisc, void *Opaque, s32 lbaCount, ShockDisc_ReadTOC ReadTOC, ShockDisc_ReadLBA ReadLBA2448, bool suppliesDeinterleavedSubcode)
{
*outDisc = new ShockDiscRef(Opaque, lbaCount, ReadTOC, ReadLBA2448, suppliesDeinterleavedSubcode);
@ -1880,6 +1858,7 @@ EW_EXPORT s32 shock_CreateDisc(ShockDiscRef** outDisc, void *Opaque, s32 lbaCoun
ShockDiscRef* s_CurrDisc = NULL;
ShockDiscInfo s_CurrDiscInfo;
//Sets the disc in the tray. Returns SHOCK_NOCANDO if it's closed. You can pass NULL to remove a disc from the tray
EW_EXPORT s32 shock_SetDisc(void* psx, ShockDiscRef* disc)
{
@ -1896,19 +1875,25 @@ EW_EXPORT s32 shock_SetDisc(void* psx, ShockDiscRef* disc)
s_CurrDiscInfo = info;
s_CurrDisc = disc;
CDC->SetDisc(true,s_CurrDisc,s_CurrDiscInfo.id);
//set the disc to the CDC, but since its necessarily open to insert, this is false
CDC->SetDisc(false,s_CurrDisc,s_CurrDiscInfo.id);
return SHOCK_OK;
}
EW_EXPORT s32 shock_OpenTray(void* psx)
{
if(s_ShockState.eject) return SHOCK_NOCANDO;
s_ShockState.eject = true;
CDC->SetDisc(true,s_CurrDisc,s_CurrDiscInfo.id);
return SHOCK_OK;
}
EW_EXPORT s32 shock_CloseTray(void* psx)
{
if(!s_ShockState.eject) return SHOCK_NOCANDO;
s_ShockState.eject = false;
CDC->SetDisc(false,s_CurrDisc,s_CurrDiscInfo.id);
return SHOCK_OK;
}
@ -2403,7 +2388,7 @@ void IRQ_SyncState(bool isReader, EW::NewState *ns);
SYNCFUNC(PSX)
{
NSS(CD_TrayOpen);
NSS(s_ShockState);
PSS(MainRAM.data8, 2*1024*1024);
NSS(SysControl.Regs);
NSS(PSX_PRNG.lcgo);