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);