217 lines
4.9 KiB
C#
217 lines
4.9 KiB
C#
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 =
|
|
{
|
|
"Up", "Down", "Left", "Right", "Select", "Start", "L", "R", "Square", "Triangle", "Circle", "Cross", "Power"
|
|
},
|
|
FloatControls =
|
|
{
|
|
"Stick X", "Stick Y"
|
|
},
|
|
FloatRanges = // TODO
|
|
{
|
|
new[] {-1.0f, 0.0f, 1.0f},
|
|
new[] {-1.0f, 0.0f, 1.0f},
|
|
}
|
|
};
|
|
|
|
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; }
|
|
|
|
public string BoardName { get { return null; } }
|
|
|
|
PPSSPPDll.LogCB logcallback = null;
|
|
Queue<string> debugmsgs = new Queue<string>();
|
|
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, string isopath)
|
|
{
|
|
if (attachedcore != null)
|
|
{
|
|
attachedcore.Dispose();
|
|
attachedcore = null;
|
|
}
|
|
CoreComm = comm;
|
|
|
|
logcallback = new PPSSPPDll.LogCB(LogCallbackFunc);
|
|
|
|
bool good = PPSSPPDll.init(isopath, 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;
|
|
LogFlush();
|
|
Console.WriteLine("PSP Core Disposed.");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void FrameAdvance(bool render, bool rendersound = true)
|
|
{
|
|
PPSSPPDll.advance();
|
|
// problem 1: audio can be 48khz, if a particular core parameter is set. we're not accounting for that.
|
|
// problem 2: we seem to be getting approximately the right amount of output, but with
|
|
// a lot of jitter on the per-frame buffer size
|
|
nsampavail = PPSSPPDll.mixsound(audiobuffer, audiobuffer.Length / 2);
|
|
LogFlush();
|
|
//Console.WriteLine("Audio Service: {0}", nsampavail);
|
|
}
|
|
|
|
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 ResetCounters()
|
|
{
|
|
}
|
|
|
|
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<MemoryDomain> 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[2048 * 2];
|
|
int nsampavail = 0;
|
|
public void GetSamples(out short[] samples, out int nsamp)
|
|
{
|
|
samples = audiobuffer;
|
|
nsamp = nsampavail;
|
|
}
|
|
public void DiscardSamples()
|
|
{
|
|
}
|
|
}
|
|
}
|