diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index 9be03c184d..07fb3f1ede 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -470,6 +470,7 @@
+
Gambatte.cs
diff --git a/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/Tst.cs b/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/Tst.cs
index f3d6182ff5..591a9184da 100644
--- a/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/Tst.cs
+++ b/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/Tst.cs
@@ -26,6 +26,7 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX
private DiscSectorReader[] _diskReaders;
private LibSaturnus.CDTOCCallback _cdTocCallback;
private LibSaturnus.CDSectorCallback _cdSectorCallback;
+ private TstControllerDeck _controllerDeck;
[CoreConstructor("PCFX")]
public Tst(CoreComm comm, byte[] rom)
@@ -34,7 +35,6 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX
throw new InvalidOperationException("To load a PC-FX game, please load the CUE file and not the BIN file.");
}
- // MDFNGameInfo->fps = (uint32)((double)7159090.90909090 / 455 / 263 * 65536 * 256);
public Tst(CoreComm comm, IEnumerable disks)
:base(comm, new Configuration
{
@@ -74,6 +74,8 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX
PostInit();
SetCdCallbacks();
+ _controllerDeck = new TstControllerDeck(new[] { ControllerType.Gamepad, ControllerType.Gamepad });
+ ControllerDefinition = _controllerDeck.Definition;
}
protected override void LoadStateBinaryInternal(BinaryReader reader)
@@ -83,7 +85,13 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
{
- return new LibTst.FrameInfo();
+ DriveLightOn = false;
+ var ret = new LibTst.FrameInfo();
+ var controls = _controllerDeck.GetData(controller);
+ ret.Port1Buttons = controls[0];
+ ret.Port2Buttons = controls[1];
+ ret.ConsoleButtons = controls[2];
+ return ret;
}
private void CDTOCCallback(int disk, [In, Out]LibSaturnus.TOC t)
diff --git a/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/TstControllerDeck.cs b/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/TstControllerDeck.cs
new file mode 100644
index 0000000000..bacae959db
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Consoles/NEC/PCFX/TstControllerDeck.cs
@@ -0,0 +1,171 @@
+using BizHawk.Emulation.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BizHawk.Emulation.Cores.Consoles.NEC.PCFX
+{
+ public enum ControllerType
+ {
+ None = 0,
+ Gamepad = 1,
+ Mouse
+ }
+
+ public class TstControllerDeck
+ {
+ private readonly ControlDefUnMerger[] _cdums;
+ private readonly IPortDevice[] _devices;
+
+ private static readonly string[] _consoleButtons =
+ {
+ "Power",
+ "Reset",
+ "Previous Disk",
+ "Next Disk"
+ };
+
+ public TstControllerDeck(IEnumerable ports)
+ {
+ _devices = ports.Select(p =>
+ {
+ switch (p)
+ {
+ case ControllerType.Gamepad:
+ return new Gamepad();
+ case ControllerType.Mouse:
+ return new Mouse();
+ default:
+ return new None();
+ }
+ }).ToArray();
+
+ List tmp;
+ Definition = ControllerDefinitionMerger.GetMerged(
+ _devices.Select(d => d.Definition),
+ out tmp);
+ _cdums = tmp.ToArray();
+
+ Definition.Name = "PC-FX Controller";
+ Definition.BoolButtons.AddRange(_consoleButtons);
+ }
+
+ public uint[] GetData(IController c)
+ {
+ var ret = new uint[_devices.Length + 1];
+ for (int i = 0; i < _devices.Length; i++)
+ ret[i] = _devices[i].GetData(_cdums[i].UnMerge(c));
+
+ uint console = 0;
+ uint val = 1;
+ foreach (var s in _consoleButtons)
+ {
+ if (c.IsPressed(s))
+ console |= val;
+ val <<= 1;
+ }
+ ret[_devices.Length] = console;
+ return ret;
+ }
+
+ public ControllerDefinition Definition { get; }
+
+ private interface IPortDevice
+ {
+ ControllerDefinition Definition { get; }
+ uint GetData(IController c);
+ }
+
+ private class None : IPortDevice
+ {
+ private static readonly ControllerDefinition _definition = new ControllerDefinition();
+
+ public ControllerDefinition Definition => _definition;
+
+ public uint GetData(IController c)
+ {
+ return 0;
+ }
+ }
+
+ private class Gamepad : IPortDevice
+ {
+ private static readonly ControllerDefinition _definition;
+ static Gamepad()
+ {
+ _definition = new ControllerDefinition
+ {
+ BoolButtons = Buttons
+ .Where(s => s != null)
+ .Select((s, i) => new { s, i })
+ .OrderBy(a => ButtonOrders[a.i])
+ .Select(a => a.s)
+ .ToList()
+ };
+ }
+
+ private static readonly string[] Buttons =
+ {
+ "0I", "0II", "0III", "0IV", "0V", "0VI",
+ "0Select", "0Run",
+ "0Up", "0Right", "0Down", "0Left",
+ "0Mode 1", null, "0Mode 2"
+ };
+
+ private static readonly int[] ButtonOrders =
+ {
+ 1, 1, 1, 1, 1, 1,
+ 1, 1,
+ 1, 1, 1, 1,
+ 1, 1
+ };
+
+ public ControllerDefinition Definition => _definition;
+
+ public uint GetData(IController c)
+ {
+ uint ret = 0;
+ uint val = 1;
+ foreach (var s in Buttons)
+ {
+ if (s != null && c.IsPressed(s))
+ ret |= val;
+ val <<= 1;
+ }
+ return ret;
+ }
+ }
+
+ private class Mouse : IPortDevice
+ {
+ private static readonly ControllerDefinition _definition = new ControllerDefinition
+ {
+ BoolButtons = { "0Mouse Left", "0Mouse Right" },
+ FloatControls = { "0X", "0Y" },
+ FloatRanges =
+ {
+ new[] { -127f, 0f, 127f },
+ new[] { -127f, 0f, 127f }
+ }
+ };
+
+ public ControllerDefinition Definition => _definition;
+
+ public uint GetData(IController c)
+ {
+ var dx = (byte)(int)c.GetFloat("0X");
+ var dy = (byte)(int)c.GetFloat("0Y");
+ uint ret = 0;
+ if (c.IsPressed("0Mouse Left"))
+ ret |= 0x10000;
+ if (c.IsPressed("0Mouse Right"))
+ ret |= 0x20000;
+ ret |= dx;
+ ret |= (uint)(dy << 8);
+ return ret;
+ }
+ }
+ }
+}
diff --git a/waterbox/pcfx/pcfx.cpp b/waterbox/pcfx/pcfx.cpp
index 75d8307d67..6a96c95b70 100644
--- a/waterbox/pcfx/pcfx.cpp
+++ b/waterbox/pcfx/pcfx.cpp
@@ -708,7 +708,7 @@ EXPORT void FrameAdvance(MyFrameInfo& f)
for (int i = 0; i < 2; i++)
InputData[i] = f.Buttons[i];
- uint32_t ConsoleButtons = f.Buttons[3];
+ uint32_t ConsoleButtons = f.Buttons[2];
int NewActiveDisk = ActiveDisk;
#define ROSE(n) ((ConsoleButtons & 1 << (n)) > (PrevConsoleButtons & 1 << (n)))
if (ROSE(0))
@@ -716,9 +716,9 @@ EXPORT void FrameAdvance(MyFrameInfo& f)
if (ROSE(1))
PCFX_Reset();
if (ROSE(2))
- NewActiveDisk++;
- if (ROSE(3))
NewActiveDisk--;
+ if (ROSE(3))
+ NewActiveDisk++;
#undef ROSE
NewActiveDisk = std::max(NewActiveDisk, -1);
NewActiveDisk = std::min(NewActiveDisk, CDInterfaces.size() - 1);