From 77d14892fb3577a17a7471f463023af89ef2320b Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 20 Jul 2015 23:10:49 -0500 Subject: [PATCH] add PSF support logic --- .../BizHawk.Emulation.Cores.csproj | 1 + .../Consoles/Sony/PSX/Octoshock.cs | 38 ++++++++-- .../Consoles/Sony/PSX/OctoshockDll.cs | 2 +- .../Consoles/Sony/PSX/PSF.cs | 69 +++++++++++++++++++ 4 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Consoles/Sony/PSX/PSF.cs 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; + } + } +}