Marching onward
This commit is contained in:
parent
2de9c1d117
commit
0f65351e13
|
@ -287,7 +287,7 @@ namespace BizHawk.BizInvoke
|
|||
var paramTypes = paramInfos.Select(p => p.ParameterType).ToArray();
|
||||
var nativeParamTypes = new List<Type>();
|
||||
var returnType = baseMethod.ReturnType;
|
||||
if (returnType != typeof(void) && !returnType.IsPrimitive)
|
||||
if (returnType != typeof(void) && !returnType.IsPrimitive && !returnType.IsPointer)
|
||||
{
|
||||
throw new InvalidOperationException("Only primitive return types are supported");
|
||||
}
|
||||
|
@ -527,7 +527,7 @@ namespace BizHawk.BizInvoke
|
|||
return typeof(IntPtr);
|
||||
}
|
||||
|
||||
if (type.IsPrimitive || type.IsEnum)
|
||||
if (type.IsPrimitive || type.IsEnum || type.IsPointer)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg, (short)idx);
|
||||
return type;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Waterbox;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.NEC.PCE
|
||||
{
|
||||
[Core("Terbo Grafix", "Mednafen Team", true, false, "", "", false)]
|
||||
public class TerboGrafix : NymaCore, IRegionable
|
||||
{
|
||||
[CoreConstructor("PCE")]
|
||||
public TerboGrafix(GameInfo game, byte[] rom, CoreComm comm)
|
||||
: base(game, rom, comm, new Configuration
|
||||
{
|
||||
// TODO: This stuff isn't used so much
|
||||
})
|
||||
{
|
||||
DoInit<LibNymaCore>(game, rom, "pce.wbx");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
public sealed partial class PCEngine : IEmulator, ISaveRam, IInputPollable, IVideoLogicalOffsets, IRomInfo,
|
||||
IDebuggable, ISettable<PCEngine.PCESettings, PCEngine.PCESyncSettings>, IDriveLight, ICodeDataLogger
|
||||
{
|
||||
[CoreConstructor(new[] { "PCE", "SGX" })]
|
||||
// [CoreConstructor(new[] { "PCE", "SGX" })]
|
||||
public PCEngine(GameInfo game, byte[] rom, object settings, object syncSettings)
|
||||
{
|
||||
switch (game.System)
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using BizHawk.BizInvoke;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Waterbox
|
||||
{
|
||||
public abstract unsafe class LibNymaCore : LibWaterboxCore
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class InitData
|
||||
{
|
||||
/// <summary>
|
||||
/// Filename without extension. Used in autodetect
|
||||
/// </summary>
|
||||
public string FileNameBase;
|
||||
/// <summary>
|
||||
/// Just the extension. Used in autodetect. LOWERCASE PLEASE.
|
||||
/// </summary>
|
||||
public string FileNameExt;
|
||||
/// <summary>
|
||||
/// Full filename. This will be fopen()ed by the core
|
||||
/// </summary>
|
||||
public string FileNameFull;
|
||||
}
|
||||
|
||||
[BizImport(CC, Compatibility = true)]
|
||||
public abstract bool Init([In]InitData data);
|
||||
|
||||
public enum CommandType : int
|
||||
{
|
||||
NONE = 0x00,
|
||||
RESET = 0x01,
|
||||
POWER = 0x02,
|
||||
|
||||
INSERT_COIN = 0x07,
|
||||
|
||||
TOGGLE_DIP0 = 0x10,
|
||||
TOGGLE_DIP1,
|
||||
TOGGLE_DIP2,
|
||||
TOGGLE_DIP3,
|
||||
TOGGLE_DIP4,
|
||||
TOGGLE_DIP5,
|
||||
TOGGLE_DIP6,
|
||||
TOGGLE_DIP7,
|
||||
TOGGLE_DIP8,
|
||||
TOGGLE_DIP9,
|
||||
TOGGLE_DIP10,
|
||||
TOGGLE_DIP11,
|
||||
TOGGLE_DIP12,
|
||||
TOGGLE_DIP13,
|
||||
TOGGLE_DIP14,
|
||||
TOGGLE_DIP15,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public new class FrameInfo : LibWaterboxCore.FrameInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// true to skip video rendering
|
||||
/// </summary>
|
||||
public int SkipRendering;
|
||||
/// <summary>
|
||||
/// a single command to run at the start of this frame
|
||||
/// </summary>
|
||||
public CommandType Command;
|
||||
/// <summary>
|
||||
/// raw data for each input port, assumed to be MAX_PORTS * MAX_PORT_DATA long
|
||||
/// </summary>
|
||||
public byte* InputPortData;
|
||||
}
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract byte* GetLayerData();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string array of valid layers to pass to SetLayers, or null if that method should not be called
|
||||
/// TODO: This needs to be in NymaCore under a monitor lock
|
||||
/// </summary>
|
||||
public string[] GetLayerDataReal()
|
||||
{
|
||||
var p = GetLayerData();
|
||||
if (p == null)
|
||||
return null;
|
||||
var ret = new List<string>();
|
||||
var q = p;
|
||||
while (true)
|
||||
{
|
||||
if (*q == 0)
|
||||
{
|
||||
if (q > p)
|
||||
ret.Add(Marshal.PtrToStringAnsi((IntPtr)p));
|
||||
else
|
||||
break;
|
||||
p = ++q;
|
||||
}
|
||||
q++;
|
||||
}
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set enabled layers (or is it disabled layers?). Only call if GetLayerDataReal() returned non null
|
||||
/// </summary>
|
||||
/// <param name="layers">bitmask in order defined by GetLayerDataReal</param>
|
||||
[BizImport(CC)]
|
||||
public abstract void SetLayers(ulong layers);
|
||||
|
||||
public enum InputType : byte
|
||||
{
|
||||
PADDING = 0, // n-bit, zero
|
||||
|
||||
BUTTON, // 1-bit
|
||||
BUTTON_CAN_RAPID, // 1-bit
|
||||
|
||||
SWITCH, // ceil(log2(n))-bit
|
||||
// Current switch position(default 0).
|
||||
// Persistent, and bidirectional communication(can be modified driver side, and Mednafen core and emulation module side)
|
||||
|
||||
STATUS, // ceil(log2(n))-bit
|
||||
// emulation module->driver communication
|
||||
|
||||
AXIS, // 16-bits; 0 through 65535; 32768 is centered position
|
||||
|
||||
POINTER_X, // mouse pointer, 16-bits, signed - in-screen/window range before scaling/offseting normalized coordinates: [0.0, 1.0)
|
||||
POINTER_Y, // see: mouse_scale_x, mouse_scale_y, mouse_offs_x, mouse_offs_y
|
||||
|
||||
AXIS_REL, // mouse relative motion, 16-bits, signed
|
||||
|
||||
BYTE_SPECIAL,
|
||||
|
||||
RESET_BUTTON, // 1-bit
|
||||
|
||||
BUTTON_ANALOG, // 16-bits, 0 - 65535
|
||||
|
||||
RUMBLE, // 16-bits, lower 8 bits are weak rumble(0-255), next 8 bits are strong rumble(0-255), 0=no rumble, 255=max rumble. Somewhat subjective, too...
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum AxisFlags: byte
|
||||
{
|
||||
NONE = 0,
|
||||
// Denotes analog data that may need to be scaled to ensure a more squareish logical range(for emulated analog sticks)
|
||||
SQLR = 0x01,
|
||||
// Invert config order of the two components(neg,pos) of the axis
|
||||
INVERT_CO = 0x02,
|
||||
SETTINGS_UNDOC = 0x80,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DeviceFlags: uint
|
||||
{
|
||||
NONE = 0,
|
||||
KEYBOARD = 1
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class NPortInfos
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPArray, SizeConst = 16)]
|
||||
public NPortInfo[] Infos;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class NPortInfo
|
||||
{
|
||||
public string ShortName;
|
||||
public string FullName;
|
||||
public string DefaultDeviceShortName;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class NDeviceInfo
|
||||
{
|
||||
public string ShortName;
|
||||
public string FullName;
|
||||
public string Description;
|
||||
public DeviceFlags Flags;
|
||||
public uint ByteLength;
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class NInput
|
||||
{
|
||||
public string SettingName;
|
||||
public string Name;
|
||||
public short ConfigOrder;
|
||||
public ushort BitOffset;
|
||||
public InputType Type;
|
||||
public AxisFlags Flags;
|
||||
public byte BitSize;
|
||||
public byte _Padding;
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class Button
|
||||
{
|
||||
public string ExcludeName;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class Axis
|
||||
{
|
||||
public string SettingsNameNeg;
|
||||
public string SettingsNamePos;
|
||||
public string NameNeg;
|
||||
public string NamePos;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class Switch
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class Position
|
||||
{
|
||||
public string SettingName;
|
||||
public string Name;
|
||||
public string Description;
|
||||
}
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public Position[] Positions;
|
||||
public uint NumPositions;
|
||||
public uint DefaultPosition;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class Status
|
||||
{
|
||||
public class State
|
||||
{
|
||||
public IntPtr ShortName;
|
||||
public IntPtr Name;
|
||||
public int Color; // (msb)0RGB(lsb), -1 for unused.
|
||||
public int _Padding;
|
||||
}
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public State[] States;
|
||||
public uint NumStates;
|
||||
}
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 400)]
|
||||
public byte[] UnionData;
|
||||
}
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
|
||||
public NInput[] Inputs;
|
||||
}
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public NDeviceInfo[] Devices;
|
||||
}
|
||||
|
||||
[BizImport(CC, Compatibility = true)]
|
||||
public abstract NPortInfos GetInputDevices();
|
||||
|
||||
[BizImport(CC, Compatibility = true)]
|
||||
public abstract void SetInputDevices(string[] devices);
|
||||
|
||||
public enum VideoSystem : int
|
||||
{
|
||||
NONE,
|
||||
PAL,
|
||||
PAL_M,
|
||||
NTSC,
|
||||
SECAM
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class SystemInfo
|
||||
{
|
||||
public int MaxWidth;
|
||||
public int MaxHeight;
|
||||
public int NominalWidth;
|
||||
public int NominalHeight;
|
||||
public VideoSystem VideoSystem;
|
||||
public int FpsFixed;
|
||||
}
|
||||
|
||||
[BizImport(CC, Compatibility = true)]
|
||||
public abstract SystemInfo GetSystemInfo();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Waterbox
|
||||
{
|
||||
public unsafe abstract class NymaCore : WaterboxCore
|
||||
{
|
||||
protected NymaCore(GameInfo game, byte[] rom, CoreComm comm, Configuration c)
|
||||
: base(comm, c)
|
||||
{
|
||||
}
|
||||
|
||||
private LibNymaCore _nyma;
|
||||
private ControllerAdapter _controllerAdapter;
|
||||
private readonly byte[] _inputPortData = new byte[16 * 16];
|
||||
|
||||
protected T DoInit<T>(GameInfo game, byte[] rom, string filename)
|
||||
where T : LibNymaCore
|
||||
{
|
||||
var t = PreInit<T>(new WaterboxOptions
|
||||
{
|
||||
// TODO cfg and stuff
|
||||
Filename = filename,
|
||||
SbrkHeapSizeKB = 1024 * 16,
|
||||
SealedHeapSizeKB = 1024 * 16,
|
||||
InvisibleHeapSizeKB = 1024 * 16,
|
||||
PlainHeapSizeKB = 1024 * 16,
|
||||
StartAddress = WaterboxHost.CanonicalStart,
|
||||
SkipCoreConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck),
|
||||
SkipMemoryConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck),
|
||||
});
|
||||
_nyma = t;
|
||||
|
||||
using (_exe.EnterExit())
|
||||
{
|
||||
var fn = game.FilesystemSafeName();
|
||||
|
||||
_exe.AddReadonlyFile(rom, fn);
|
||||
|
||||
var didInit = _nyma.Init(new LibNymaCore.InitData
|
||||
{
|
||||
// TODO: Set these as some cores need them
|
||||
FileNameBase = "",
|
||||
FileNameExt = "",
|
||||
FileNameFull = fn
|
||||
});
|
||||
|
||||
if (!didInit)
|
||||
throw new InvalidOperationException("Core rejected the rom!");
|
||||
|
||||
_exe.RemoveReadonlyFile(fn);
|
||||
|
||||
var info = _nyma.GetSystemInfo();
|
||||
_videoBuffer = new int[info.MaxWidth * info.MaxHeight];
|
||||
BufferWidth = info.NominalWidth;
|
||||
BufferHeight = info.NominalHeight;
|
||||
switch (info.VideoSystem)
|
||||
{
|
||||
// TODO: There seriously isn't any region besides these?
|
||||
case LibNymaCore.VideoSystem.PAL:
|
||||
case LibNymaCore.VideoSystem.SECAM:
|
||||
Region = DisplayType.PAL;
|
||||
break;
|
||||
case LibNymaCore.VideoSystem.PAL_M:
|
||||
Region = DisplayType.Dendy; // sort of...
|
||||
break;
|
||||
default:
|
||||
Region = DisplayType.NTSC;
|
||||
break;
|
||||
}
|
||||
VsyncNumerator = info.FpsFixed;
|
||||
VsyncDenominator = 1 << 24;
|
||||
|
||||
_controllerAdapter = new ControllerAdapter(_nyma.GetInputDevices().Infos, new string[0]);
|
||||
_nyma.SetInputDevices(_controllerAdapter.Devices);
|
||||
|
||||
PostInit();
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// todo: bleh
|
||||
private GCHandle _frameAdvanceInputLock;
|
||||
|
||||
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
_controllerAdapter.SetBits(controller, _inputPortData);
|
||||
_frameAdvanceInputLock = GCHandle.Alloc(_inputPortData, GCHandleType.Pinned);
|
||||
var ret = new LibNymaCore.FrameInfo
|
||||
{
|
||||
SkipRendering = render ? 0 : 1,
|
||||
Command = LibNymaCore.CommandType.NONE,
|
||||
InputPortData = (byte*)_frameAdvanceInputLock.AddrOfPinnedObject()
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
protected override void FrameAdvancePost()
|
||||
{
|
||||
_frameAdvanceInputLock.Free();
|
||||
}
|
||||
|
||||
private static T ControllerData<T>(byte[] data)
|
||||
{
|
||||
fixed(byte *p = data)
|
||||
{
|
||||
return (T)Marshal.PtrToStructure((IntPtr)p, typeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
protected delegate void ControllerThunk(IController c, byte[] b);
|
||||
|
||||
protected class ControllerAdapter
|
||||
{
|
||||
public string[] Devices { get; }
|
||||
public ControllerDefinition Definition { get; }
|
||||
public ControllerAdapter(LibNymaCore.NPortInfo[] portInfos, string[] devices)
|
||||
{
|
||||
var ret = new ControllerDefinition
|
||||
{
|
||||
Name = "TODO"
|
||||
};
|
||||
|
||||
var finalDevices = new List<string>();
|
||||
|
||||
for (int i = 0, devByteStart = 0; i < portInfos.Length && portInfos[i].ShortName != null; i++)
|
||||
{
|
||||
var port = portInfos[i];
|
||||
var devName = i < devices.Length ? devices[i] : port.DefaultDeviceShortName;
|
||||
finalDevices.Add(devName);
|
||||
|
||||
var dev = port.Devices.SingleOrDefault(d => d.ShortName == devName);
|
||||
var category = port.FullName + " - " + dev.FullName;
|
||||
|
||||
foreach (var input in dev.Inputs.OrderBy(i => i.ConfigOrder))
|
||||
{
|
||||
var bitSize = (int)input.BitSize;
|
||||
var bitOffset = (int)input.BitOffset;
|
||||
var byteStart = devByteStart + bitOffset / 8;
|
||||
bitOffset %= 8;
|
||||
var name = input.Name;
|
||||
switch (input.Type)
|
||||
{
|
||||
case LibNymaCore.InputType.PADDING:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case LibNymaCore.InputType.BUTTON:
|
||||
case LibNymaCore.InputType.BUTTON_CAN_RAPID:
|
||||
{
|
||||
var data = ControllerData<LibNymaCore.NPortInfo.NDeviceInfo.NInput.Button>(input.UnionData);
|
||||
// TODO: Wire up data.ExcludeName
|
||||
ret.BoolButtons.Add(name);
|
||||
_thunks.Add((c, b) =>
|
||||
{
|
||||
if (c.IsPressed(name))
|
||||
b[byteStart] |= (byte)(1 << bitOffset);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case LibNymaCore.InputType.SWITCH:
|
||||
{
|
||||
var data = ControllerData<LibNymaCore.NPortInfo.NDeviceInfo.NInput.Switch>(input.UnionData);
|
||||
// TODO: Possibly bulebutton for 2 states?
|
||||
ret.AxisControls.Add(name);
|
||||
ret.AxisRanges.Add(new ControllerDefinition.AxisRange(
|
||||
0, (int)data.DefaultPosition, (int)data.NumPositions - 1));
|
||||
_thunks.Add((c, b) =>
|
||||
{
|
||||
var val = (int)Math.Round(c.AxisValue(name));
|
||||
b[byteStart] |= (byte)(1 << bitOffset);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case LibNymaCore.InputType.AXIS:
|
||||
{
|
||||
var data = ControllerData<LibNymaCore.NPortInfo.NDeviceInfo.NInput.Axis>(input.UnionData);
|
||||
ret.AxisControls.Add(name);
|
||||
ret.AxisRanges.Add(new ControllerDefinition.AxisRange(
|
||||
0, 0x8000, 0xffff, (input.Flags & LibNymaCore.AxisFlags.INVERT_CO) != 0
|
||||
));
|
||||
_thunks.Add((c, b) =>
|
||||
{
|
||||
var val = (ushort)Math.Round(c.AxisValue(name));
|
||||
b[byteStart] = (byte)val;
|
||||
b[byteStart + 1] = (byte)(val >> 8);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case LibNymaCore.InputType.AXIS_REL:
|
||||
{
|
||||
var data = ControllerData<LibNymaCore.NPortInfo.NDeviceInfo.NInput.Axis>(input.UnionData);
|
||||
ret.AxisControls.Add(name);
|
||||
ret.AxisRanges.Add(new ControllerDefinition.AxisRange(
|
||||
-0x8000, 0, 0x7fff, (input.Flags & LibNymaCore.AxisFlags.INVERT_CO) != 0
|
||||
));
|
||||
_thunks.Add((c, b) =>
|
||||
{
|
||||
var val = (short)Math.Round(c.AxisValue(name));
|
||||
b[byteStart] = (byte)val;
|
||||
b[byteStart + 1] = (byte)(val >> 8);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case LibNymaCore.InputType.POINTER_X:
|
||||
{
|
||||
throw new Exception("TODO: Axis ranges are ints????");
|
||||
// ret.AxisControls.Add(name);
|
||||
// ret.AxisRanges.Add(new ControllerDefinition.AxisRange(0, 0.5, 1));
|
||||
// break;
|
||||
}
|
||||
case LibNymaCore.InputType.POINTER_Y:
|
||||
{
|
||||
throw new Exception("TODO: Axis ranges are ints????");
|
||||
// ret.AxisControls.Add(name);
|
||||
// ret.AxisRanges.Add(new ControllerDefinition.AxisRange(0, 0.5, 1, true));
|
||||
// break;
|
||||
}
|
||||
default:
|
||||
throw new NotImplementedException($"Unimplemented button type {input.Type}");
|
||||
}
|
||||
ret.CategoryLabels[name] = category;
|
||||
}
|
||||
|
||||
devByteStart += (int)dev.ByteLength;
|
||||
}
|
||||
Definition = ret;
|
||||
Devices = finalDevices.ToArray();
|
||||
}
|
||||
|
||||
private readonly List<Action<IController, byte[]>> _thunks = new List<Action<IController, byte[]>>();
|
||||
|
||||
public void SetBits(IController src, byte[] dest)
|
||||
{
|
||||
Array.Clear(dest, 0, dest.Length);
|
||||
foreach (var t in _thunks)
|
||||
t(src, dest);
|
||||
}
|
||||
}
|
||||
|
||||
public DisplayType Region { get; protected set; }
|
||||
}
|
||||
}
|
|
@ -329,7 +329,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
return _videoBuffer;
|
||||
}
|
||||
|
||||
protected readonly int[] _videoBuffer;
|
||||
protected int[] _videoBuffer;
|
||||
public virtual int VirtualWidth => BufferWidth;
|
||||
public virtual int VirtualHeight => BufferHeight;
|
||||
public int BufferWidth { get; protected set; }
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace Mednafen
|
|||
va_start(argp, format);
|
||||
vfprintf(t == MDFN_NOTICE_ERROR ? stderr : stdout, format, argp);
|
||||
}
|
||||
void MDFND_MidSync(EmulateSpecStruct *espec, const unsigned flags)
|
||||
void MDFN_MidSync(EmulateSpecStruct *espec, const unsigned flags)
|
||||
{}
|
||||
|
||||
bool MDFNSS_StateAction(StateMem *sm, const unsigned load, const bool data_only, const SFORMAT *sf, const char *sname, const bool optional) noexcept
|
||||
|
@ -100,6 +100,8 @@ namespace Mednafen
|
|||
{}
|
||||
void MDFNMP_ApplyPeriodicCheats(void)
|
||||
{}
|
||||
std::vector<SUBCHEAT> SubCheats[8];
|
||||
bool SubCheatsOn;
|
||||
|
||||
// player.h
|
||||
void Player_Init(int tsongs, const std::string &album, const std::string &artist, const std::string ©right, const std::vector<std::string> &snames, bool override_gi)
|
||||
|
|
|
@ -113,6 +113,33 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo& frame)
|
|||
}
|
||||
}
|
||||
|
||||
struct SystemInfo
|
||||
{
|
||||
int32_t MaxWidth;
|
||||
int32_t MaxHeight;
|
||||
int32_t NominalWidth;
|
||||
int32_t NominalHeight;
|
||||
int32_t VideoSystem;
|
||||
int32_t FpsFixed;
|
||||
};
|
||||
SystemInfo SI;
|
||||
|
||||
ECL_EXPORT SystemInfo* GetSystemInfo()
|
||||
{
|
||||
SI.MaxWidth = Game->fb_width;
|
||||
SI.MaxHeight = Game->fb_height;
|
||||
SI.NominalWidth = Game->nominal_width;
|
||||
SI.NominalHeight = Game->nominal_height;
|
||||
SI.VideoSystem = Game->VideoSystem;
|
||||
SI.FpsFixed = Game->fps;
|
||||
return &SI;
|
||||
}
|
||||
|
||||
ECL_EXPORT const char* GetLayerData()
|
||||
{
|
||||
return Game->LayerNames;
|
||||
}
|
||||
|
||||
ECL_EXPORT void SetLayers(uint64_t layers)
|
||||
{
|
||||
Game->SetLayerEnableMask(layers);
|
||||
|
@ -127,20 +154,20 @@ ECL_EXPORT void SetInputCallback(void (*cb)())
|
|||
// same information as PortInfo, but easier to marshal
|
||||
struct NPortInfo
|
||||
{
|
||||
const char *ShortName;
|
||||
const char *FullName;
|
||||
const char *DefaultDeviceShortName;
|
||||
const char* ShortName;
|
||||
const char* FullName;
|
||||
const char* DefaultDeviceShortName;
|
||||
struct NDeviceInfo
|
||||
{
|
||||
const char *ShortName;
|
||||
const char *FullName;
|
||||
const char *Description;
|
||||
const char* ShortName;
|
||||
const char* FullName;
|
||||
const char* Description;
|
||||
uint32_t Flags;
|
||||
uint32_t ByteLength;
|
||||
struct NInput
|
||||
{
|
||||
const char *SettingName;
|
||||
const char *Name;
|
||||
const char* SettingName;
|
||||
const char* Name;
|
||||
int16_t ConfigOrder;
|
||||
uint16_t BitOffset;
|
||||
InputDeviceInputType Type; // uint8_t
|
||||
|
@ -166,7 +193,7 @@ struct NPortInfo
|
|||
const char* SettingName;
|
||||
const char* Name;
|
||||
const char* Description;
|
||||
}* Positions;
|
||||
} Positions[16];
|
||||
uint32_t NumPositions;
|
||||
uint32_t DefaultPosition;
|
||||
} Switch;
|
||||
|
@ -178,9 +205,10 @@ struct NPortInfo
|
|||
const char* Name;
|
||||
int32_t Color; // (msb)0RGB(lsb), -1 for unused.
|
||||
int32_t _Padding;
|
||||
}* States;
|
||||
} States[16];
|
||||
uint32_t NumStates;
|
||||
} Status;
|
||||
uint8_t _Padding2[400];
|
||||
};
|
||||
} Inputs[256];
|
||||
} Devices[32];
|
||||
|
@ -226,8 +254,7 @@ ECL_EXPORT NPortInfo* GetInputDevices()
|
|||
case IDIT_SWITCH:
|
||||
c.Switch.NumPositions = z.Switch.NumPos;
|
||||
c.Switch.DefaultPosition = z.Switch.DefPos;
|
||||
c.Switch.Positions = (decltype(c.Switch.Positions))calloc(z.Switch.NumPos, sizeof(*c.Switch.Positions));
|
||||
for (unsigned i = 0; i < z.Switch.NumPos; i++)
|
||||
for (unsigned i = 0; i < 16 && i < z.Switch.NumPos; i++)
|
||||
{
|
||||
c.Switch.Positions[i].SettingName = z.Switch.Pos[i].SettingName;
|
||||
c.Switch.Positions[i].Name = z.Switch.Pos[i].Name;
|
||||
|
@ -236,8 +263,7 @@ ECL_EXPORT NPortInfo* GetInputDevices()
|
|||
break;
|
||||
case IDIT_STATUS:
|
||||
c.Status.NumStates = z.Status.NumStates;
|
||||
c.Status.States = (decltype(c.Status.States))calloc(z.Status.NumStates, sizeof(*c.Status.States));
|
||||
for (unsigned i = 0; i < z.Status.NumStates; i++)
|
||||
for (unsigned i = 0; i < 16 && i < z.Status.NumStates; i++)
|
||||
{
|
||||
c.Status.States[i].ShortName = z.Status.States[i].ShortName;
|
||||
c.Status.States[i].Name = z.Status.States[i].Name;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#include "mednafen/src/types.h"
|
||||
#include "nyma.h"
|
||||
#include <emulibc.h>
|
||||
#include "mednafen/src/pce/pce.h"
|
||||
|
||||
using namespace MDFN_IEN_PCE;
|
||||
|
||||
extern Mednafen::MDFNGI EmulatedPCE;
|
||||
|
||||
void SetupMDFNGameInfo()
|
||||
{
|
||||
Mednafen::MDFNGameInfo = &EmulatedPCE;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
include common.mak
|
||||
|
||||
# $(call cppdir,hw_video/huc6270)
|
||||
# $(call cppdir,hw_sound/pce_psg)
|
||||
|
||||
SRCS += \
|
||||
$(filter-out %debug.cpp,$(call cppdir,pce)) \
|
||||
$(filter-out %CDAFReader_SF.cpp,$(call cppdir,cdrom)) \
|
||||
$(call cdir,tremor) \
|
||||
$(call cdir,mpcdec) \
|
||||
mednafen/src/mthreading/MThreading_POSIX.cpp \
|
||||
$(call cppdir,hw_sound/pce_psg) \
|
||||
$(call cppdir,hw_misc/arcade_card) \
|
||||
$(call cppdir,hw_video/huc6270) \
|
||||
pce.cpp
|
||||
|
||||
include ../common.mak
|
Loading…
Reference in New Issue