diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index f4eb67bf9a..d4aa48fdd5 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -769,6 +769,7 @@
+
diff --git a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
index 02f1b3ddf4..1e81870c93 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs
@@ -221,9 +221,21 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public List HackyDiscButtons = new List();
+ public Octoshock(CoreComm comm, PSF psf, object settings, object syncSettings)
+ {
+ Load(comm, null, null, null, settings, syncSettings, psf);
+ OctoshockDll.shock_PowerOn(psx);
+ }
+
//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
public Octoshock(CoreComm comm, List discs, List discNames, byte[] exe, object settings, object syncSettings)
+ {
+ Load(comm, discs, discNames, exe, settings, syncSettings, null);
+ OctoshockDll.shock_PowerOn(psx);
+ }
+
+ void Load(CoreComm comm, List discs, List discNames, byte[] exe, object settings, object syncSettings, PSF psf)
{
ServiceProvider = new BasicServiceProvider(this);
(ServiceProvider as BasicServiceProvider).Register(tracer);
@@ -237,14 +249,14 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
Attach();
- HackyDiscButtons.AddRange(discNames);
-
//assume this region for EXE and PSF, maybe not correct though
string firmwareRegion = "U";
SystemRegion = OctoshockDll.eRegion.NA;
if (discs != null)
{
+ HackyDiscButtons.AddRange(discNames);
+
foreach (var disc in discs)
{
var discInterface = new DiscInterface(disc,
@@ -326,11 +338,25 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
CurrentTrayOpen = false;
CurrentDiscIndexMounted = 1;
}
- else
+ else if (psf == null)
{
//must be an exe
fixed (byte* pExeBuffer = exe)
- OctoshockDll.shock_MountEXE(psx, pExeBuffer, exe.Length);
+ OctoshockDll.shock_MountEXE(psx, pExeBuffer, exe.Length, false);
+
+ //start with no disc inserted and tray closed
+ CurrentTrayOpen = false;
+ CurrentDiscIndexMounted = 0;
+ OctoshockDll.shock_CloseTray(psx);
+ }
+ else
+ {
+ //must be a psf
+ if(psf.LibData != null)
+ fixed (byte* pBuf = psf.LibData)
+ OctoshockDll.shock_MountEXE(psx, pBuf, psf.LibData.Length, true);
+ fixed (byte* pBuf = psf.Data)
+ OctoshockDll.shock_MountEXE(psx, pBuf, psf.Data.Length, false);
//start with no disc inserted and tray closed
CurrentTrayOpen = false;
@@ -359,8 +385,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
//do this after framebuffers and peripherals and whatever crap are setup. kind of lame, but thats how it is for now
StudySaveBufferSize();
-
- OctoshockDll.shock_PowerOn(psx);
}
public IEmulatorServiceProvider ServiceProvider { get; private set; }
@@ -535,7 +559,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
CurrentDiscIndexMounted = requestedDisc;
}
- if (CurrentDiscIndexMounted == 0)
+ if (CurrentDiscIndexMounted == 0 || discInterfaces.Count == 0)
{
currentDiscInterface = null;
OctoshockDll.shock_SetDisc(psx, IntPtr.Zero);
diff --git a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/OctoshockDll.cs b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/OctoshockDll.cs
index d9ea87a8c9..5f897a0c90 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/OctoshockDll.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/OctoshockDll.cs
@@ -197,7 +197,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public static extern int shock_Peripheral_PollActive(IntPtr psx, int address, bool clear);
[DllImport(dd, CallingConvention = cc)]
- public static extern int shock_MountEXE(IntPtr psx, void* exebuf, int size);
+ public static extern int shock_MountEXE(IntPtr psx, void* exebuf, int size, bool ignore_pcsp);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_PowerOn(IntPtr psx);
diff --git a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/PSF.cs b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/PSF.cs
new file mode 100644
index 0000000000..025daee0ed
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/PSF.cs
@@ -0,0 +1,69 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+using BizHawk.Common.IOExtensions;
+
+namespace BizHawk.Emulation.Cores.Sony.PSX
+{
+ public class PSF
+ {
+ public Dictionary TagsDictionary = new Dictionary();
+ public List LooseTags = new List();
+
+ public byte[] Data;
+ public byte[] LibData;
+
+ public bool Load(string fpPSF, Func cbDeflater)
+ {
+ using(var fs = File.OpenRead(fpPSF))
+ {
+ //not endian safe
+ var br = new BinaryReader(fs);
+ var sig = br.ReadStringFixedAscii(4);
+ if (sig != "PSF\x1")
+ return false;
+
+ int reserved_size = br.ReadInt32();
+ int compressed_size = br.ReadInt32();
+ int compressed_crc32 = br.ReadInt32();
+
+ //load tags
+ //tags run until the end of the file
+ fs.Position = 16 + reserved_size + compressed_size;
+ if (br.ReadStringFixedAscii(5) == "[TAG]")
+ {
+ var tagstring = br.ReadStringFixedAscii((int)(fs.Length - fs.Position)).Replace("\r\n","\n");
+ foreach (var tag in tagstring.Split('\n', '\x0'))
+ {
+ if (tag.Trim() == "")
+ continue;
+ int eq = tag.IndexOf('=');
+ if (eq != -1)
+ TagsDictionary[tag.Substring(0, eq)] = tag.Substring(eq + 1);
+ else
+ LooseTags.Add(tag);
+ }
+ }
+
+ //load compressed section buffer
+ fs.Position = 16 + reserved_size;
+ Data = cbDeflater(fs, compressed_size);
+
+ //load lib if needed
+ if (TagsDictionary.ContainsKey("_lib"))
+ {
+ var fpLib = Path.Combine(Path.GetDirectoryName(fpPSF), TagsDictionary["_lib"]);
+ if (!File.Exists(fpLib))
+ return false;
+ PSF lib = new PSF();
+ if (!lib.Load(fpLib,cbDeflater))
+ return false;
+ LibData = lib.Data;
+ }
+ }
+
+ return true;
+ }
+ }
+}