diff --git a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
index aa7d37a3b5..d5d8910f9b 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
@@ -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
}
///
@@ -85,7 +86,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
///
class DiscInterface : IDisposable
{
- public DiscInterface(DiscSystem.Disc disc, Action cbActivity)
+ public DiscInterface(DiscSystem.Disc disc, Action 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 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 discInterfaces = new List();
+ 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?
diff --git a/output/dll/octoshock.dll b/output/dll/octoshock.dll
index 2d53cb066f..4cc4ea8a1f 100644
Binary files a/output/dll/octoshock.dll and b/output/dll/octoshock.dll differ
diff --git a/psx/octoshock/psx/psx.cpp b/psx/octoshock/psx/psx.cpp
index 2dd2c195a7..20cd933ceb 100644
--- a/psx/octoshock/psx/psx.cpp
+++ b/psx/octoshock/psx/psx.cpp
@@ -159,7 +159,6 @@ class PSF1Loader {};
static PSF1Loader *psf_loader = NULL;
static std::vector *cdifs = NULL;
static std::vector 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(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);