diff --git a/BizHawk.Emulation/Consoles/Sony/PSP/PPSSPPDll.cs b/BizHawk.Emulation/Consoles/Sony/PSP/PPSSPPDll.cs new file mode 100644 index 0000000000..40c1634fb8 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Sony/PSP/PPSSPPDll.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +namespace BizHawk.Emulation.Consoles.Sony.PSP +{ + public static class PPSSPPDll + { + const CallingConvention cc = CallingConvention.StdCall; + const string dd = "PPSSPPBizhawk.dll"; + + [UnmanagedFunctionPointer(cc)] + public delegate void LogCB(char type, string message); + + [DllImport(dd, CallingConvention = cc)] + public static extern bool init(string fn, LogCB logcallback); + + [DllImport(dd, CallingConvention = cc)] + public static extern void setvidbuff(IntPtr buff); + + [DllImport(dd, CallingConvention = cc)] + public static extern void die(); + + [DllImport(dd, CallingConvention = cc)] + public static extern void advance(); + } +} diff --git a/BizHawk.Emulation/Consoles/Sony/PSP/PSP.cs b/BizHawk.Emulation/Consoles/Sony/PSP/PSP.cs new file mode 100644 index 0000000000..4e3c66b2a6 --- /dev/null +++ b/BizHawk.Emulation/Consoles/Sony/PSP/PSP.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; + +namespace BizHawk.Emulation.Consoles.Sony.PSP +{ + public class PSP : IEmulator, IVideoProvider, ISyncSoundProvider + { + public static readonly ControllerDefinition PSPController = new ControllerDefinition + { + Name = "PSP Controller", + BoolButtons = { "TO", "BE", "CHANGED" } + }; + + public IVideoProvider VideoProvider { get { return this; } } + public ISoundProvider SoundProvider { get { return null; } } + public ISyncSoundProvider SyncSoundProvider { get { return this; } } + public bool StartAsyncSound() { return false; } + public void EndAsyncSound() { } + public ControllerDefinition ControllerDefinition { get { return PSPController; } } + public IController Controller { get; set; } + public bool DeterministicEmulation { get { return true; } } + public string SystemId { get { return "PSP"; } } + public bool BinarySaveStatesPreferred { get { return true; } } + public CoreComm CoreComm { get; private set; } + + + PPSSPPDll.LogCB logcallback = null; + Queue debugmsgs = new Queue(); + void LogCallbackFunc(char type, string message) + { + debugmsgs.Enqueue(string.Format("PSP: {0} {1}", type, message)); + } + void LogFlush() + { + while (debugmsgs.Count > 0) + { + Console.WriteLine(debugmsgs.Dequeue()); + } + } + + + bool disposed = false; + static PSP attachedcore = null; + GCHandle vidhandle; + + public PSP(CoreComm comm) + { + if (attachedcore != null) + { + attachedcore.Dispose(); + attachedcore = null; + } + CoreComm = comm; + + logcallback = new PPSSPPDll.LogCB(LogCallbackFunc); + + bool good = PPSSPPDll.init(@"D:\Games\jpcsp\umdimages\Final Fantasy Anniversary Edition [U] [ULUS-10251].iso", logcallback); + LogFlush(); + if (!good) + throw new Exception("PPSSPP Init failed!"); + vidhandle = GCHandle.Alloc(screenbuffer, GCHandleType.Pinned); + PPSSPPDll.setvidbuff(vidhandle.AddrOfPinnedObject()); + + CoreComm.VsyncDen = 1; + CoreComm.VsyncNum = 60; + CoreComm.RomStatusDetails = "It puts the scythe in the chicken or it gets the abyss again!"; + + attachedcore = this; + } + + public void Dispose() + { + if (!disposed) + { + vidhandle.Free(); + PPSSPPDll.setvidbuff(IntPtr.Zero); + PPSSPPDll.die(); + logcallback = null; + disposed = true; + } + } + + + + public void FrameAdvance(bool render, bool rendersound = true) + { + PPSSPPDll.advance(); + } + + public int Frame + { + get { return 0; } + } + + public int LagCount + { + get + { + return 0; + } + set + { + } + } + + public bool IsLagFrame + { + get { return true; } + } + + public byte[] ReadSaveRam() + { + return new byte[0]; + } + + public void StoreSaveRam(byte[] data) + { + } + + public void ClearSaveRam() + { + } + + public bool SaveRamModified + { + get + { + return false; + } + set + { + } + } + + public void ResetFrameCounter() + { + } + + public void SaveStateText(System.IO.TextWriter writer) + { + } + + public void LoadStateText(System.IO.TextReader reader) + { + } + + public void SaveStateBinary(System.IO.BinaryWriter writer) + { + } + + public void LoadStateBinary(System.IO.BinaryReader reader) + { + } + + public byte[] SaveStateBinary() + { + return new byte[0]; + } + + public IList MemoryDomains + { + get { throw new NotImplementedException(); } + } + + public MemoryDomain MainMemory + { + get { throw new NotImplementedException(); } + } + + + + const int screenwidth = 480; + const int screenheight = 272; + readonly int[] screenbuffer = new int[screenwidth * screenheight]; + public int[] GetVideoBuffer() { return screenbuffer; } + public int VirtualWidth { get { return screenwidth; } } + public int BufferWidth { get { return screenwidth; } } + public int BufferHeight { get { return screenheight; } } + public int BackgroundColor { get { return unchecked((int)0xff000000); } } + + readonly short[] audiobuffer = new short[735 * 2]; + public void GetSamples(out short[] samples, out int nsamp) + { + samples = audiobuffer; + nsamp = 735; + } + public void DiscardSamples() + { + } + } +} diff --git a/BizHawk.MultiClient/output/dll/PPSSPPBizhawk.dll b/BizHawk.MultiClient/output/dll/PPSSPPBizhawk.dll new file mode 100644 index 0000000000..ee9d876d92 Binary files /dev/null and b/BizHawk.MultiClient/output/dll/PPSSPPBizhawk.dll differ