157 lines
3.8 KiB
C#
157 lines
3.8 KiB
C#
using BizHawk.Emulation.Common;
|
|
using BizHawk.Emulation.Cores.Waterbox;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace BizHawk.Emulation.Cores.Consoles.Belogic
|
|
{
|
|
[Core("uzem", "David Etherton", true, true, "", "", false)]
|
|
public class Uzem : WaterboxCore
|
|
{
|
|
private LibUzem _uze;
|
|
private bool _mouseEnabled;
|
|
|
|
[CoreConstructor("UZE")]
|
|
public Uzem(CoreComm comm, byte[] rom)
|
|
:base(comm, new Configuration
|
|
{
|
|
DefaultWidth = 720,
|
|
DefaultHeight = 224,
|
|
MaxWidth = 720,
|
|
MaxHeight = 224,
|
|
MaxSamples = 4096,
|
|
SystemId = "UZE",
|
|
DefaultFpsNumerator = 28618182,
|
|
DefaultFpsDenominator = 476840
|
|
})
|
|
{
|
|
_uze = PreInit<LibUzem>(new PeRunnerOptions
|
|
{
|
|
Filename = "uzem.wbx",
|
|
SbrkHeapSizeKB = 20,
|
|
SealedHeapSizeKB = 4,
|
|
InvisibleHeapSizeKB = 4,
|
|
MmapHeapSizeKB = 4,
|
|
PlainHeapSizeKB = 4,
|
|
});
|
|
|
|
_exe.AddReadonlyFile(rom, "romfile");
|
|
if (!_uze.Init())
|
|
throw new InvalidOperationException("Core rejected the rom!");
|
|
_mouseEnabled = _uze.MouseEnabled();
|
|
_exe.RemoveReadonlyFile("romfile");
|
|
|
|
PostInit();
|
|
}
|
|
|
|
private static readonly ControllerDefinition TwoPads = new ControllerDefinition
|
|
{
|
|
Name = "SNES Controller",
|
|
BoolButtons =
|
|
{
|
|
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Select", "P1 Start", "P1 X", "P1 A", "P1 B", "P1 Y", "P1 L", "P1 R",
|
|
"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Select", "P2 Start", "P2 X", "P2 A", "P2 B", "P2 Y", "P2 L", "P2 R",
|
|
"Power"
|
|
}
|
|
};
|
|
|
|
private static readonly ControllerDefinition Mouse = new ControllerDefinition
|
|
{
|
|
Name = "SNES Controller",
|
|
BoolButtons =
|
|
{
|
|
"P1 Mouse Left", "P1 Mouse Right", "Power"
|
|
},
|
|
FloatControls =
|
|
{
|
|
"P1 Mouse X", "P1 Mouse Y"
|
|
},
|
|
FloatRanges =
|
|
{
|
|
new[] { -127f, 0f, 127f },
|
|
new[] { -127f, 0f, 127f }
|
|
}
|
|
};
|
|
|
|
private static readonly string[] PadBits =
|
|
{
|
|
"B", "Y", "Select", "Start", "Up", "Down", "Left", "Right", "A", "X", "L", "R"
|
|
};
|
|
|
|
private static int EncodePad(IController c, int p)
|
|
{
|
|
int ret = unchecked((int)0xffff0000);
|
|
int val = 1;
|
|
int idx = 0;
|
|
foreach (var s in PadBits)
|
|
{
|
|
if (c.IsPressed("P" + p + " " + PadBits[idx++]))
|
|
ret |= val;
|
|
val <<= 1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
private static int EncodeDelta(float value)
|
|
{
|
|
int v = (int)value;
|
|
if (v > 127)
|
|
v = 127;
|
|
if (v < -127)
|
|
v = -127;
|
|
|
|
int ret = 0;
|
|
if (v < 0)
|
|
{
|
|
ret |= 1;
|
|
v = -v;
|
|
}
|
|
|
|
int mask = 64;
|
|
int bit = 2;
|
|
while (mask != 0)
|
|
{
|
|
if ((v & mask) != 0)
|
|
ret |= bit;
|
|
mask >>= 1;
|
|
bit <<= 1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
public override ControllerDefinition ControllerDefinition => _mouseEnabled ? Mouse : TwoPads;
|
|
|
|
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
|
|
{
|
|
var ret = new LibUzem.FrameInfo();
|
|
if (_mouseEnabled)
|
|
{
|
|
ret.ButtonsP1 = EncodeDelta(controller.GetFloat("P1 Mouse X")) << 24
|
|
| EncodeDelta(controller.GetFloat("P1 Mouse Y")) << 16
|
|
| 0x8000;
|
|
if (controller.IsPressed("P1 Mouse Left"))
|
|
ret.ButtonsP1 |= 0x200;
|
|
if (controller.IsPressed("P1 Mouse Right"))
|
|
ret.ButtonsP1 |= 0x100;
|
|
}
|
|
else
|
|
{
|
|
ret.ButtonsP1 = EncodePad(controller, 1);
|
|
ret.ButtonsP2 = EncodePad(controller, 2);
|
|
}
|
|
if (controller.IsPressed("Power"))
|
|
ret.ButtonsConsole = 1;
|
|
|
|
return ret;
|
|
}
|
|
|
|
// with the high clockrate and full software signal generation, horizontal resolution is
|
|
// very variable. in practice, 240 wide, 360 wide, and 180 wide are what you'll see...
|
|
public override int VirtualWidth => 619;
|
|
public override int VirtualHeight => 448;
|
|
}
|
|
}
|