TSTHawk: controller stuff

This commit is contained in:
nattthebear 2017-07-09 13:40:52 -04:00
parent 2396ebeb82
commit 110d741cb3
4 changed files with 185 additions and 5 deletions

View File

@ -470,6 +470,7 @@
<Compile Include="Consoles\Magnavox\O2Em.cs" />
<Compile Include="Consoles\NEC\PCFX\LibTst.cs" />
<Compile Include="Consoles\NEC\PCFX\Tst.cs" />
<Compile Include="Consoles\NEC\PCFX\TstControllerDeck.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.ICodeDataLog.cs">
<DependentUpon>Gambatte.cs</DependentUpon>

View File

@ -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<Disc> 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)

View File

@ -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<ControllerType> ports)
{
_devices = ports.Select<ControllerType, IPortDevice>(p =>
{
switch (p)
{
case ControllerType.Gamepad:
return new Gamepad();
case ControllerType.Mouse:
return new Mouse();
default:
return new None();
}
}).ToArray();
List<ControlDefUnMerger> 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;
}
}
}
}

View File

@ -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<int>(NewActiveDisk, CDInterfaces.size() - 1);