get some of the disc api interop stuff checked in
This commit is contained in:
parent
074edfdc67
commit
19d0cc627e
|
@ -1,10 +1,43 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
//main apis for emulator core routine use
|
//main apis for emulator core routine use
|
||||||
|
|
||||||
namespace BizHawk.Disc
|
namespace BizHawk.Disc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public class DiscHopper
|
||||||
|
{
|
||||||
|
public Disc CurrentDisc;
|
||||||
|
|
||||||
|
public Queue<Disc> Queue = new Queue<Disc>();
|
||||||
|
|
||||||
|
public void Enqueue(Disc disc)
|
||||||
|
{
|
||||||
|
Queue.Enqueue(disc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Next()
|
||||||
|
{
|
||||||
|
if (Queue.Count != 0) Queue.Dequeue();
|
||||||
|
}
|
||||||
|
public void Eject()
|
||||||
|
{
|
||||||
|
CurrentDisc = null;
|
||||||
|
}
|
||||||
|
public void Insert()
|
||||||
|
{
|
||||||
|
if (Queue.Count > 0)
|
||||||
|
CurrentDisc = Queue.Peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
CurrentDisc = null;
|
||||||
|
Queue.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public partial class Disc
|
public partial class Disc
|
||||||
{
|
{
|
||||||
//main API to read a 2352-byte LBA from a disc.
|
//main API to read a 2352-byte LBA from a disc.
|
||||||
|
|
|
@ -288,9 +288,10 @@ namespace BizHawk.Disc
|
||||||
blob.PhysicalPath = fiIso.FullName;
|
blob.PhysicalPath = fiIso.FullName;
|
||||||
Blobs.Add(blob);
|
Blobs.Add(blob);
|
||||||
int num_lba = (int)(fiIso.Length / 2048);
|
int num_lba = (int)(fiIso.Length / 2048);
|
||||||
//index.length_lba = num_lba;
|
track.length_lba = num_lba;
|
||||||
if (fiIso.Length % 2048 != 0)
|
if (fiIso.Length % 2048 != 0)
|
||||||
throw new InvalidOperationException("invalid iso file (size not multiple of 2048)");
|
throw new InvalidOperationException("invalid iso file (size not multiple of 2048)");
|
||||||
|
//TODO - handle this with Final Fantasy 9 cd1.iso
|
||||||
|
|
||||||
var ecmCacheBlob = new ECMCacheBlob(blob);
|
var ecmCacheBlob = new ECMCacheBlob(blob);
|
||||||
for (int i = 0; i < num_lba; i++)
|
for (int i = 0; i < num_lba; i++)
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace BizHawk.Disc
|
||||||
public int num;
|
public int num;
|
||||||
public List<Track> Tracks = new List<Track>();
|
public List<Track> Tracks = new List<Track>();
|
||||||
|
|
||||||
//the length of the track (should be the sum of all track lengths)
|
//the length of the session (should be the sum of all track lengths)
|
||||||
public int length_lba;
|
public int length_lba;
|
||||||
public Cue.CueTimestamp FriendlyLength { get { return new Cue.CueTimestamp(length_lba); } }
|
public Cue.CueTimestamp FriendlyLength { get { return new Cue.CueTimestamp(length_lba); } }
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,22 +13,99 @@ using System.Threading;
|
||||||
|
|
||||||
namespace BizHawk
|
namespace BizHawk
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// represents an external core's interface to a disc
|
||||||
|
/// </summary>
|
||||||
|
public class DiscInterface : ExternalCore
|
||||||
|
{
|
||||||
|
public DiscInterface(IExternalCoreAccessor accessor)
|
||||||
|
: base(accessor)
|
||||||
|
{
|
||||||
|
UnmanagedOpaque = QueryCoreCall<Func<IntPtr, IntPtr>>("DiscInterface.Construct")(ManagedOpaque);
|
||||||
|
|
||||||
|
SetFp("Dispose", new disposeDelegate(Dispose));
|
||||||
|
SetFp("GetNumSessions", new GetNumSessionsDelegate(GetNumSessions));
|
||||||
|
SetFp("GetNumTracks", new GetNumTracksDelegate(GetNumTracks));
|
||||||
|
SetFp("GetTrack", new GetTrackDelegate(GetTrack));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool disposed = false;
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
if (disposed) return;
|
||||||
|
disposed = true;
|
||||||
|
|
||||||
|
QueryCoreCall<Action>("DiscInterface.Delete")();
|
||||||
|
|
||||||
|
base.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Disc.DiscHopper DiscHopper;
|
||||||
|
|
||||||
|
void SetFp(string name, Delegate del)
|
||||||
|
{
|
||||||
|
QueryCoreCall<Action<string, IntPtr>>("DiscInterface.Set_fp")(name, ExportDelegate(del));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TrackInfo
|
||||||
|
{
|
||||||
|
public Disc.ETrackType TrackType;
|
||||||
|
public int length_lba;
|
||||||
|
public int start_lba;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetNumSessions()
|
||||||
|
{
|
||||||
|
return DiscHopper.CurrentDisc.ReadTOC().Sessions.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetNumTracks(int session)
|
||||||
|
{
|
||||||
|
return DiscHopper.CurrentDisc.ReadTOC().Sessions[session].Tracks.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackInfo GetTrack(int session, int track)
|
||||||
|
{
|
||||||
|
var ti = new TrackInfo();
|
||||||
|
var toc_track = DiscHopper.CurrentDisc.ReadTOC().Sessions[session].Tracks[track];
|
||||||
|
ti.TrackType = toc_track.TrackType;
|
||||||
|
ti.length_lba = toc_track.length_lba;
|
||||||
|
return ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
delegate void disposeDelegate();
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
delegate int GetNumSessionsDelegate();
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
delegate int GetNumTracksDelegate(int session);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
delegate TrackInfo GetTrackDelegate(int session, int track);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class EmuFile : ExternalCore
|
public class EmuFile : ExternalCore
|
||||||
{
|
{
|
||||||
|
|
||||||
public EmuFile(IExternalCoreAccessor accessor)
|
public EmuFile(IExternalCoreAccessor accessor)
|
||||||
: base(accessor)
|
: base(accessor)
|
||||||
{
|
{
|
||||||
UnmanagedOpaque = QueryCoreCall<Func<IntPtr, IntPtr>>("EmuFile.Construct")(ManagedOpaque);
|
UnmanagedOpaque = QueryCoreCall<Func<IntPtr, IntPtr>>("EmuFile.Construct")(ManagedOpaque);
|
||||||
|
|
||||||
QueryCoreCall<Action<string, IntPtr>>("EmuFile.Set_fp")("fgetc", ExportDelegate(new fgetcDelegate(fgetc)));
|
SetFp("fgetc", new fgetcDelegate(fgetc));
|
||||||
QueryCoreCall<Action<string, IntPtr>>("EmuFile.Set_fp")("fread", ExportDelegate(new freadDelegate(fread)));
|
SetFp("fread", new freadDelegate(fread));
|
||||||
QueryCoreCall<Action<string, IntPtr>>("EmuFile.Set_fp")("fwrite", ExportDelegate(new fwriteDelegate(fwrite)));
|
SetFp("fwrite", new fwriteDelegate(fwrite));
|
||||||
QueryCoreCall<Action<string, IntPtr>>("EmuFile.Set_fp")("fseek", ExportDelegate(new fseekDelegate(fseek)));
|
SetFp("fseek", new fseekDelegate(fseek));
|
||||||
QueryCoreCall<Action<string, IntPtr>>("EmuFile.Set_fp")("ftell", ExportDelegate(new ftellDelegate(ftell)));
|
SetFp("ftell", new ftellDelegate(ftell));
|
||||||
QueryCoreCall<Action<string, IntPtr>>("EmuFile.Set_fp")("size", ExportDelegate(new sizeDelegate(size)));
|
SetFp("size", new sizeDelegate(size));
|
||||||
QueryCoreCall<Action<string, IntPtr>>("EmuFile.Set_fp")("size", ExportDelegate(new sizeDelegate(size)));
|
SetFp("dispose", new disposeDelegate(Dispose));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFp(string name, Delegate del)
|
||||||
|
{
|
||||||
|
QueryCoreCall<Action<string, IntPtr>>("EmuFile.Set_fp")(name, ExportDelegate(del));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream BaseStream { get; set; }
|
public Stream BaseStream { get; set; }
|
||||||
|
@ -54,6 +131,7 @@ namespace BizHawk
|
||||||
{
|
{
|
||||||
return BaseStream.ReadByte();
|
return BaseStream.ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
IntPtr fread(
|
IntPtr fread(
|
||||||
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
|
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
|
||||||
byte[] ptr,
|
byte[] ptr,
|
||||||
|
@ -65,12 +143,14 @@ namespace BizHawk
|
||||||
int ret = BaseStream.Read(ptr, 0, (int)len);
|
int ret = BaseStream.Read(ptr, 0, (int)len);
|
||||||
return new IntPtr(ret);
|
return new IntPtr(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
IntPtr fseek(IntPtr offset, IntPtr origin)
|
IntPtr fseek(IntPtr offset, IntPtr origin)
|
||||||
{
|
{
|
||||||
SeekOrigin so = (SeekOrigin)origin.ToInt32();
|
SeekOrigin so = (SeekOrigin)origin.ToInt32();
|
||||||
long loffset = offset.ToInt64();
|
long loffset = offset.ToInt64();
|
||||||
return new IntPtr(BaseStream.Seek(loffset, so));
|
return new IntPtr(BaseStream.Seek(loffset, so));
|
||||||
}
|
}
|
||||||
|
|
||||||
IntPtr ftell() { return new IntPtr(BaseStream.Position); }
|
IntPtr ftell() { return new IntPtr(BaseStream.Position); }
|
||||||
IntPtr size() { return new IntPtr(BaseStream.Length); }
|
IntPtr size() { return new IntPtr(BaseStream.Length); }
|
||||||
|
|
||||||
|
@ -89,6 +169,8 @@ namespace BizHawk
|
||||||
delegate int fgetcDelegate();
|
delegate int fgetcDelegate();
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
delegate void disposeDelegate();
|
delegate void disposeDelegate();
|
||||||
|
//TODO - for more speed fread and fwrite might appreciate taking pointers
|
||||||
|
//(although, we'll have to convert it to an array to deal with an underlying stream anyway -- or will we?
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
delegate IntPtr freadDelegate(
|
delegate IntPtr freadDelegate(
|
||||||
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
|
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
|
||||||
|
|
|
@ -14,6 +14,7 @@ using System.Collections.Generic;
|
||||||
namespace BizHawk
|
namespace BizHawk
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// universal interface to a shared library
|
/// universal interface to a shared library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -62,14 +63,16 @@ namespace BizHawk
|
||||||
|
|
||||||
if (register)
|
if (register)
|
||||||
{
|
{
|
||||||
|
mCoreRegistry[core.ManagedOpaque] = core;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//delete
|
mCoreRegistry.Remove(core.ManagedOpaque);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticCoreCommon scc;
|
StaticCoreCommon scc;
|
||||||
|
Dictionary<IntPtr, ExternalCore> mCoreRegistry = new Dictionary<IntPtr, ExternalCore>();
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
@ -95,7 +98,10 @@ namespace BizHawk
|
||||||
{
|
{
|
||||||
return scc.ClientSignal(type, obj, param, value);
|
return scc.ClientSignal(type, obj, param, value);
|
||||||
}
|
}
|
||||||
else return IntPtr.Zero;
|
else
|
||||||
|
{
|
||||||
|
return mCoreRegistry[obj].ClientSignal(type, obj, param, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntPtr Signal(string type, IntPtr obj, string param, IntPtr value)
|
public IntPtr Signal(string type, IntPtr obj, string param, IntPtr value)
|
||||||
|
@ -112,17 +118,18 @@ namespace BizHawk
|
||||||
public IntPtr ManagedOpaque;
|
public IntPtr ManagedOpaque;
|
||||||
public IntPtr UnmanagedOpaque;
|
public IntPtr UnmanagedOpaque;
|
||||||
static int _ManagedOpaque_Counter = 1;
|
static int _ManagedOpaque_Counter = 1;
|
||||||
|
private static object oLock = new object();
|
||||||
|
|
||||||
protected IExternalCoreAccessor mAccessor;
|
protected IExternalCoreAccessor mAccessor;
|
||||||
public ExternalCore(IExternalCoreAccessor accessor)
|
public ExternalCore(IExternalCoreAccessor accessor)
|
||||||
{
|
{
|
||||||
mAccessor = accessor;
|
mAccessor = accessor;
|
||||||
mAccessor.RegisterCore(this,true);
|
lock (oLock)
|
||||||
lock (this)
|
|
||||||
{
|
{
|
||||||
ManagedOpaque = new IntPtr(_ManagedOpaque_Counter);
|
ManagedOpaque = new IntPtr(_ManagedOpaque_Counter);
|
||||||
_ManagedOpaque_Counter++;
|
_ManagedOpaque_Counter++;
|
||||||
}
|
}
|
||||||
|
mAccessor.RegisterCore(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Dispose()
|
public virtual void Dispose()
|
||||||
|
@ -136,8 +143,13 @@ namespace BizHawk
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// cores call into the client from here. this system is not fully baked yet, though
|
/// cores call into the client from here. this system is not fully baked yet, though
|
||||||
/// </summary>
|
/// </summary>
|
||||||
virtual public IntPtr ClientSignal(string type, IntPtr obj, string param, IntPtr value)
|
public virtual IntPtr ClientSignal(string type, IntPtr obj, string param, IntPtr value)
|
||||||
{
|
{
|
||||||
|
//if (type == "FACTORY")
|
||||||
|
//{
|
||||||
|
// return new DiscInterface(mAccessor).UnmanagedOpaque;
|
||||||
|
//}
|
||||||
|
//else return IntPtr.Zero;
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,6 +242,11 @@ namespace BizHawk
|
||||||
mAccessor.Signal("SET_CLIENT_SIGNAL", IntPtr.Zero, null, ExportDelegate(ClientSignal));
|
mAccessor.Signal("SET_CLIENT_SIGNAL", IntPtr.Zero, null, ExportDelegate(ClientSignal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override IntPtr ClientSignal(string type, IntPtr obj, string param, IntPtr value)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace BizHawk
|
||||||
CoreOutputComm = new CoreOutputComm();
|
CoreOutputComm = new CoreOutputComm();
|
||||||
CoreInputComm = new CoreInputComm();
|
CoreInputComm = new CoreInputComm();
|
||||||
|
|
||||||
|
mDiscInterface = new DiscInterface(mAccessor);
|
||||||
|
|
||||||
UnmanagedOpaque = QueryCoreCall<Func<IntPtr,IntPtr>>("PsxCore.Construct")(ManagedOpaque);
|
UnmanagedOpaque = QueryCoreCall<Func<IntPtr,IntPtr>>("PsxCore.Construct")(ManagedOpaque);
|
||||||
|
|
||||||
QueryCoreCall(out cGetResolution, "PsxCore.GetResolution");
|
QueryCoreCall(out cGetResolution, "PsxCore.GetResolution");
|
||||||
|
@ -26,6 +28,21 @@ namespace BizHawk
|
||||||
QueryCoreCall(out cFrameAdvance, "PsxCore.FrameAdvance");
|
QueryCoreCall(out cFrameAdvance, "PsxCore.FrameAdvance");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiscInterface mDiscInterface;
|
||||||
|
public void SetDiscHopper(Disc.DiscHopper hopper)
|
||||||
|
{
|
||||||
|
mDiscInterface.DiscHopper = hopper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IntPtr ClientSignal(string type, IntPtr obj, string param, IntPtr value)
|
||||||
|
{
|
||||||
|
if (param == "GetDiscInterface")
|
||||||
|
{
|
||||||
|
return mDiscInterface.UnmanagedOpaque;
|
||||||
|
}
|
||||||
|
return base.ClientSignal(type, obj, param, value);
|
||||||
|
}
|
||||||
|
|
||||||
Func<System.Drawing.Size> cGetResolution;
|
Func<System.Drawing.Size> cGetResolution;
|
||||||
Action cFrameAdvance;
|
Action cFrameAdvance;
|
||||||
Action<IntPtr> cUpdateVideoBuffer;
|
Action<IntPtr> cUpdateVideoBuffer;
|
||||||
|
|
|
@ -74,6 +74,9 @@ namespace BizHawk.MultiClient
|
||||||
return mg.GetControllersAsMnemonic();
|
return mg.GetControllersAsMnemonic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Disc.DiscHopper DiscHopper = new BizHawk.Disc.DiscHopper();
|
||||||
|
|
||||||
|
|
||||||
public static CoreAccessor PsxCoreLibrary = new CoreAccessor(new Win32LibAccessor("PsxHawk.Core.dll"));
|
public static CoreAccessor PsxCoreLibrary = new CoreAccessor(new Win32LibAccessor("PsxHawk.Core.dll"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -848,12 +848,10 @@ namespace BizHawk.MultiClient
|
||||||
nextEmulator = psx;
|
nextEmulator = psx;
|
||||||
game = new RomGame();
|
game = new RomGame();
|
||||||
var disc = Disc.Disc.FromIsoPath(path);
|
var disc = Disc.Disc.FromIsoPath(path);
|
||||||
//Global.DiscHopper.Clear();
|
Global.DiscHopper.Clear();
|
||||||
//Global.DiscHopper.Enqueue(disc);
|
Global.DiscHopper.Enqueue(disc);
|
||||||
//Global.DiscHopper.Insert();
|
Global.DiscHopper.Insert();
|
||||||
|
psx.SetDiscHopper(Global.DiscHopper);
|
||||||
//set disc
|
|
||||||
//psx.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
DebugInformationFormat="4"
|
DebugInformationFormat="4"
|
||||||
|
CallingConvention="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCManagedResourceCompilerTool"
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
@ -110,6 +111,7 @@
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
DebugInformationFormat="3"
|
DebugInformationFormat="3"
|
||||||
|
CallingConvention="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCManagedResourceCompilerTool"
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
@ -151,6 +153,14 @@
|
||||||
RelativePath=".\core.h"
|
RelativePath=".\core.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\DiscInterface.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\DiscInterface.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\emufile.cpp"
|
RelativePath=".\emufile.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "DiscInterface.h"
|
||||||
|
|
||||||
|
static FunctionRecord records[] = {
|
||||||
|
REG("DiscInterface.Construct", &DiscInterface::Construct),
|
||||||
|
REG("DiscInterface.Set_fp", &DiscInterface::Set_fp),
|
||||||
|
};
|
||||||
|
|
||||||
|
void* DiscInterface::Construct(void* ManagedOpaque)
|
||||||
|
{
|
||||||
|
return new DiscInterface(ManagedOpaque);
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef _DISCINTERFACE_H_
|
||||||
|
#define _DISCINTERFACE_H_
|
||||||
|
|
||||||
|
#include "DiscInterface.h"
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
class DiscInterface
|
||||||
|
{
|
||||||
|
void* ManagedOpaque;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum ETrackType : int
|
||||||
|
{
|
||||||
|
ETrackType_Mode1_2352,
|
||||||
|
ETrackType_Mode1_2048,
|
||||||
|
ETrackType_Mode2_2352,
|
||||||
|
ETrackType_Audio
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TrackInfo
|
||||||
|
{
|
||||||
|
ETrackType TrackType;
|
||||||
|
int length_lba;
|
||||||
|
int start_lba;
|
||||||
|
};
|
||||||
|
|
||||||
|
FUNC<void()> Dispose;
|
||||||
|
FUNC<int()> GetNumSessions;
|
||||||
|
FUNC<int(int)> GetNumTracks;
|
||||||
|
FUNC<TrackInfo(int,int)> GetTrack;
|
||||||
|
|
||||||
|
~DiscInterface()
|
||||||
|
{
|
||||||
|
Dispose.func();
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscInterface(void* _ManagedOpaque)
|
||||||
|
: ManagedOpaque(_ManagedOpaque)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Construct(void* ManagedOpaque);
|
||||||
|
|
||||||
|
void Delete()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Set_fp(const char* param, void* value)
|
||||||
|
{
|
||||||
|
if(!strcmp(param,"GetNumSessions")) GetNumSessions.set(value);
|
||||||
|
if(!strcmp(param,"GetNumTracks")) GetNumTracks.set(value);
|
||||||
|
if(!strcmp(param,"GetTrack")) GetTrack.set(value);
|
||||||
|
if(!strcmp(param,"Dispose")) Dispose.set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_DISCINTERFACE_H_
|
|
@ -2,13 +2,7 @@
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "emufile.h"
|
#include "emufile.h"
|
||||||
#include "emufile_hawk.h"
|
#include "emufile_hawk.h"
|
||||||
|
#include "DiscInterface.h"
|
||||||
|
|
||||||
//TODO
|
|
||||||
class DISC_INTERFACE
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//TODO - setup a null file to use as the default console, so we dont have to check whether its set to null everywhere
|
//TODO - setup a null file to use as the default console, so we dont have to check whether its set to null everywhere
|
||||||
class EMUFILE_HAWK;
|
class EMUFILE_HAWK;
|
||||||
|
@ -84,7 +78,9 @@ extern "C" __declspec(dllexport) void* Core_signal(const char* type, void* obj,
|
||||||
//force a reference to our core types. a bit annoying but if its this easy i guess i dont mind
|
//force a reference to our core types. a bit annoying but if its this easy i guess i dont mind
|
||||||
if(!strcmp(type,"IMPOSSIBLE"))
|
if(!strcmp(type,"IMPOSSIBLE"))
|
||||||
{
|
{
|
||||||
return new EMUFILE_HAWK(0);
|
con->fprintf("%x\n",((DiscInterface*)NULL)->Construct(NULL));
|
||||||
|
con->fprintf("%x\n",((EMUFILE_HAWK*)NULL)->Construct(NULL));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -23,6 +23,7 @@ extern EMUFILE_HAWK* con;
|
||||||
//since we may need to change all these later to work un-generalized
|
//since we may need to change all these later to work un-generalized
|
||||||
//but seriously. before doing that, i would rather return sizeof(functionpointer) bytes as a token to the managed code and pass that back in
|
//but seriously. before doing that, i would rather return sizeof(functionpointer) bytes as a token to the managed code and pass that back in
|
||||||
//(MP stands for MEMBER POINTER)
|
//(MP stands for MEMBER POINTER)
|
||||||
|
//we could also try using the FastDelegate. really, we probably should.
|
||||||
template<typename T> void* MP(const T& a)
|
template<typename T> void* MP(const T& a)
|
||||||
{
|
{
|
||||||
union U{
|
union U{
|
||||||
|
@ -35,7 +36,7 @@ template<typename T> void* MP(const T& a)
|
||||||
}
|
}
|
||||||
|
|
||||||
//this is a function pointer which can be assigned without having to type the function protoype again to cast it.
|
//this is a function pointer which can be assigned without having to type the function protoype again to cast it.
|
||||||
template<typename T> class FP
|
template<typename T> class __FP
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
template<typename T> T MPX(void* a)
|
template<typename T> T MPX(void* a)
|
||||||
|
@ -48,12 +49,39 @@ private:
|
||||||
return u.t;
|
return u.t;
|
||||||
CTASSERT(sizeof(U)==4||(sizeof(U)==8&&sizeof(void*)==8));
|
CTASSERT(sizeof(U)==4||(sizeof(U)==8&&sizeof(void*)==8));
|
||||||
}
|
}
|
||||||
|
//protected:
|
||||||
public:
|
public:
|
||||||
T func;
|
T func;
|
||||||
void set(void* val) { func = MPX<T>(val); }
|
void set(void* val) { func = MPX<T>(val); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//nothing important
|
//----------------
|
||||||
|
//these templates help us call a function pointer directly with () instead of fp.func()
|
||||||
|
|
||||||
|
template<typename R=void> struct FUNC0 : public __FP<R(*)()> { public:
|
||||||
|
R operator()() { return func(); }
|
||||||
|
};
|
||||||
|
template<typename A1, typename R=void> struct FUNC1 : public __FP<R(*)(A1)> { public:
|
||||||
|
R operator()(A1 a1) { return func(a1); }
|
||||||
|
};
|
||||||
|
template<typename A1, typename A2, typename R=void> struct FUNC2 : public __FP<R(*)(A1,A2)> { public:
|
||||||
|
R operator()(A1 a1, A2 a2) { return func(a1,a2); }
|
||||||
|
};
|
||||||
|
template<typename A1, typename A2, typename A3, typename R=void> struct FUNC3 : public __FP<R(*)(A1,A2,A3)> { public:
|
||||||
|
R operator()(A1 a1, A2 a2, A3 a3) { return func(a1,a2,a3); }
|
||||||
|
};
|
||||||
|
template<typename A1, typename A2, typename A3, typename A4, typename R=void> struct FUNC4 : public __FP<R(*)(A1,A2,A3,A4)> { public:
|
||||||
|
R operator()(A1 a1, A2 a2, A3 a3, A4 a4) { return func(a1,a2,a3,a4); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Signature> class FUNC;
|
||||||
|
template<typename R> class FUNC<R()> : public FUNC0<R> {};
|
||||||
|
template<typename A1, typename R> class FUNC<R(A1)> : public FUNC1<A1,R> {};
|
||||||
|
template<typename A1, typename A2, typename R> class FUNC<R(A1,A2)> : public FUNC2<A1,A2,R> {};
|
||||||
|
template<typename A1, typename A2, typename A3, typename R> class FUNC<R(A1,A2,A3)> : public FUNC3<A1,A2,A3,R> {};
|
||||||
|
template<typename A1, typename A2, typename A3, typename A4, typename R> class FUNC<R(A1,A2,A3,A4)> : public FUNC4<A1,A2,A3,A4,R> {};
|
||||||
|
//----------------
|
||||||
|
|
||||||
void _registerFunction(const char* _name, void* _funcptr);
|
void _registerFunction(const char* _name, void* _funcptr);
|
||||||
struct FunctionRecord
|
struct FunctionRecord
|
||||||
{
|
{
|
||||||
|
@ -64,7 +92,7 @@ struct FunctionRecord
|
||||||
};
|
};
|
||||||
|
|
||||||
//register a core object member function. put it in a global static array
|
//register a core object member function. put it in a global static array
|
||||||
template<typename T> FunctionRecord FUNC(const char* name, const T& a)
|
template<typename T> FunctionRecord REG(const char* name, const T& a)
|
||||||
{
|
{
|
||||||
return FunctionRecord(name,MP(a));
|
return FunctionRecord(name,MP(a));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,3 @@
|
||||||
/* Copyright (C) 2009 DeSmuME team
|
|
||||||
*
|
|
||||||
* This file is part of DeSmuME
|
|
||||||
*
|
|
||||||
* DeSmuME is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* DeSmuME is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with DeSmuME; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EMUFILE_H
|
#ifndef EMUFILE_H
|
||||||
#define EMUFILE_H
|
#define EMUFILE_H
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
static FunctionRecord records[] = {
|
static FunctionRecord records[] = {
|
||||||
FUNC("EmuFile.Construct", &EMUFILE_HAWK::Construct),
|
REG("EmuFile.Construct", &EMUFILE_HAWK::Construct),
|
||||||
FUNC("EmuFile.Set_fp", &EMUFILE_HAWK::Set_fp),
|
REG("EmuFile.Set_fp", &EMUFILE_HAWK::Set_fp),
|
||||||
FUNC("EmuFile.Delete", &EMUFILE_HAWK::Delete),
|
REG("EmuFile.Delete", &EMUFILE_HAWK::Delete),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ int EMUFILE_HAWK::fprintf(const char *format, ...)
|
||||||
return amt;
|
return amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* EMUFILE_HAWK::Construct(void* ManagedOpaque)
|
void* EMUFILE_HAWK::Construct(void* ManagedOpaque)
|
||||||
{
|
{
|
||||||
return new EMUFILE_HAWK(ManagedOpaque);
|
return new EMUFILE_HAWK(ManagedOpaque);
|
||||||
|
|
|
@ -10,20 +10,21 @@ class EMUFILE_HAWK : public EMUFILE
|
||||||
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
FP<int(*)()> fgetc;
|
FUNC<int()> fgetc;
|
||||||
FP<size_t(*)(const void* ptr, size_t bytes)> fread;
|
FUNC<int(const void* ptr, size_t bytes)> fread;
|
||||||
FP<void(*)(const void* ptr, size_t bytes)> fwrite;
|
FUNC<void(const void* ptr, size_t bytes)> fwrite;
|
||||||
FP<int(*)(int offset, int origin)> fseek;
|
FUNC<int(int offset, int origin)> fseek;
|
||||||
FP<int(*)()> ftell;
|
FUNC<int()> ftell;
|
||||||
FP<int(*)()> size;
|
FUNC<int()> size;
|
||||||
FP<void(*)()> dispose;
|
FUNC<void()> dispose;
|
||||||
} _;
|
} _;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~EMUFILE_HAWK()
|
~EMUFILE_HAWK()
|
||||||
{
|
{
|
||||||
_.dispose.func();
|
_.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
EMUFILE_HAWK(void* _ManagedOpaque)
|
EMUFILE_HAWK(void* _ManagedOpaque)
|
||||||
: ManagedOpaque(_ManagedOpaque)
|
: ManagedOpaque(_ManagedOpaque)
|
||||||
{
|
{
|
||||||
|
@ -47,18 +48,15 @@ public:
|
||||||
if(!strcmp(param,"dispose")) _.dispose.set(value);
|
if(!strcmp(param,"dispose")) _.dispose.set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int fgetc() { return _.fgetc.func(); }
|
virtual int fgetc() { return _.fgetc(); }
|
||||||
virtual FILE *get_fp() { return NULL; }
|
virtual FILE *get_fp() { return NULL; }
|
||||||
virtual int fputc(int c) { return -1; }
|
virtual int fputc(int c) { return -1; }
|
||||||
virtual int fprintf(const char *format, ...);
|
virtual int fprintf(const char *format, ...);
|
||||||
virtual size_t _fread(const void *ptr, size_t bytes) { return _.fread.func(ptr,bytes); }
|
virtual size_t _fread(const void *ptr, size_t bytes) { return _.fread(ptr,bytes); }
|
||||||
virtual void fwrite(const void *ptr, size_t bytes) { return _.fwrite.func(ptr,bytes); }
|
virtual void fwrite(const void *ptr, size_t bytes) { return _.fwrite(ptr,bytes); }
|
||||||
virtual int fseek(int offset, int origin) { return _.fseek.func(offset,origin); }
|
virtual int fseek(int offset, int origin) { return _.fseek(offset,origin); }
|
||||||
virtual int ftell() { return _.ftell.func(); }
|
virtual int ftell() { return _.ftell(); }
|
||||||
virtual int size() { return _.size.func(); }
|
virtual int size() { return _.size(); }
|
||||||
|
|
||||||
|
|
||||||
void* signal(const char* _param, void* value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,21 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "emufile_hawk.h"
|
#include "emufile_hawk.h"
|
||||||
|
#include "DiscInterface.h"
|
||||||
|
|
||||||
|
|
||||||
static FunctionRecord records[] = {
|
static FunctionRecord records[] = {
|
||||||
FUNC("PsxCore.Construct", &PsxCore::Construct),
|
REG("PsxCore.Construct", &PsxCore::Construct),
|
||||||
FUNC("PsxCore.GetResolution", &PsxCore::GetResolution),
|
REG("PsxCore.GetResolution", &PsxCore::GetResolution),
|
||||||
FUNC("PsxCore.FrameAdvance", &PsxCore::FrameAdvance),
|
REG("PsxCore.FrameAdvance", &PsxCore::FrameAdvance),
|
||||||
FUNC("PsxCore.UpdateVideoBuffer", &PsxCore::UpdateVideoBuffer)
|
REG("PsxCore.UpdateVideoBuffer", &PsxCore::UpdateVideoBuffer)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PsxCore::PsxCore(void* _opaque)
|
||||||
|
: opaque(_opaque)
|
||||||
|
{
|
||||||
|
discInterface = (DiscInterface*)ClientSignal(NULL,opaque,"GetDiscInterface",NULL);
|
||||||
|
}
|
||||||
|
|
||||||
PsxCore::Size PsxCore::GetResolution()
|
PsxCore::Size PsxCore::GetResolution()
|
||||||
{
|
{
|
||||||
|
@ -28,6 +34,8 @@ void PsxCore::FrameAdvance()
|
||||||
{
|
{
|
||||||
videoBuffer[i] = rand() | (rand()<<15) | 0xFF000000;
|
videoBuffer[i] = rand() | (rand()<<15) | 0xFF000000;
|
||||||
}
|
}
|
||||||
|
DiscInterface::TrackInfo ti = discInterface->GetTrack(0,0);
|
||||||
|
con->fprintf("lba len: %d\n",ti.length_lba);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PsxCore::UpdateVideoBuffer(void* target)
|
void PsxCore::UpdateVideoBuffer(void* target)
|
||||||
|
|
|
@ -3,16 +3,16 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class DiscInterface;
|
||||||
|
|
||||||
class PsxCore
|
class PsxCore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PsxCore(void* _opaque)
|
PsxCore(void* _opaque);
|
||||||
: opaque(_opaque)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* opaque;
|
void* opaque;
|
||||||
|
DiscInterface* discInterface;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void* Construct(void* ManagedOpaque)
|
void* Construct(void* ManagedOpaque)
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
DebugInformationFormat="4"
|
DebugInformationFormat="4"
|
||||||
|
CallingConvention="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCManagedResourceCompilerTool"
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
@ -124,6 +125,7 @@
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
DebugInformationFormat="3"
|
DebugInformationFormat="3"
|
||||||
|
CallingConvention="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCManagedResourceCompilerTool"
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
|
Loading…
Reference in New Issue