wire up sameboy's rumble

This commit is contained in:
CasualPokePlayer 2022-07-25 00:10:46 -07:00
parent ea5e8b70d3
commit d84da4ec4b
9 changed files with 50 additions and 12 deletions

Binary file not shown.

Binary file not shown.

View File

@ -182,7 +182,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
_cdCallback = new LibGambatte.CDCallback(CDCallbackProc);
ControllerDefinition = CreateControllerDefinition(sgb: IsSgb, sub: _syncSettings.FrameLength is GambatteSyncSettings.FrameLengthType.UserDefinedFrames, tilt: false);
ControllerDefinition = CreateControllerDefinition(sgb: IsSgb, sub: _syncSettings.FrameLength is GambatteSyncSettings.FrameLengthType.UserDefinedFrames, tilt: false, rumble: false);
NewSaveCoreSetBuff();
}
@ -247,7 +247,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public long CycleCount => (long)_cycleCount;
public double ClockRate => TICKSPERSECOND;
public static ControllerDefinition CreateControllerDefinition(bool sgb, bool sub, bool tilt)
public static ControllerDefinition CreateControllerDefinition(bool sgb, bool sub, bool tilt, bool rumble)
{
var ret = new ControllerDefinition((sub ? "Subframe " : "") + "Gameboy Controller" + (tilt ? " + Tilt" : ""));
if (sub)
@ -258,6 +258,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
ret.AddXYPair($"Tilt {{0}}", AxisPairOrientation.RightAndUp, (-90).RangeTo(90), 0);
}
if (rumble)
{
ret.HapticsChannels.Add("Rumble");
}
if (sgb)
{
for (int i = 0; i < 4; i++)

View File

@ -49,7 +49,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
_linkedCores[i] = new Gameboy(lp.Comm, lp.Roms[i].Game, lp.Roms[i].RomData, _settings._linkedSettings[i], _syncSettings._linkedSyncSettings[i], lp.DeterministicEmulationRequested);
_linkedCores[i].ConnectInputCallbackSystem(_inputCallbacks);
_linkedCores[i].ConnectMemoryCallbackSystem(_memoryCallbacks, i);
_linkedConts[i] = new SaveController(Gameboy.CreateControllerDefinition(sgb: false, sub: false, tilt: false));
_linkedConts[i] = new SaveController(Gameboy.CreateControllerDefinition(sgb: false, sub: false, tilt: false, rumble: false));
_linkedBlips[i] = new BlipBuffer(1024);
_linkedBlips[i].SetRates(2097152 * 2, 44100);
_linkedOverflow[i] = 0;

View File

@ -53,6 +53,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
[BizImport(cc)]
public abstract void sameboy_setinputcallback(IntPtr core, InputCallback callback);
[UnmanagedFunctionPointer(cc)]
public delegate void RumbleCallback(int amplitude);
[BizImport(cc)]
public abstract void sameboy_setrumblecallback(IntPtr core, RumbleCallback callback);
[BizImport(cc)]
public abstract void sameboy_frameadvance(IntPtr core, Buttons buttons, ushort x, ushort y, short[] soundbuf, ref int nsamps, int[] videobuf, bool render, bool border);
@ -81,7 +87,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
public abstract int sameboy_statelen(IntPtr core);
[BizImport(cc)]
public abstract bool sameboy_getmemoryarea(IntPtr core, MemoryAreas which, ref IntPtr data, ref int length);
public abstract bool sameboy_getmemoryarea(IntPtr core, MemoryAreas which, ref IntPtr data, ref long length);
[BizImport(cc)]
public abstract byte sameboy_cpuread(IntPtr core, ushort addr);

View File

@ -11,10 +11,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
public ControllerDefinition ControllerDefinition { get; }
private IController _controller = NullController.Instance;
private static readonly IReadOnlyList<string> GB_BUTTON_ORDER_IN_BITMASK = new[] { "Start", "Select", "B", "A", "Down", "Up", "Left", "Right", };
private LibSameboy.Buttons FrameAdvancePrep(IController controller)
{
_controller = controller;
uint b = 0;
for (var i = 0; i < 8; i++)
{

View File

@ -7,14 +7,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
{
public partial class Sameboy
{
private readonly List<MemoryDomain> _memoryDomains = new List<MemoryDomain>();
private readonly List<MemoryDomain> _memoryDomains = new();
private IMemoryDomains MemoryDomains { get; set; }
private void CreateMemoryDomain(LibSameboy.MemoryAreas which, string name)
{
IntPtr data = IntPtr.Zero;
int length = 0;
long length = 0;
if (!LibSameboy.sameboy_getmemoryarea(SameboyState, which, ref data, ref length))
{

View File

@ -39,6 +39,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
private readonly LibSameboy.InputCallback _inputcb;
private readonly LibSameboy.RumbleCallback _rumblecb;
[CoreConstructor(VSystemID.Raw.GB)]
[CoreConstructor(VSystemID.Raw.GBC)]
public Sameboy(CoreComm comm, GameInfo game, byte[] file, SameboySettings settings, SameboySyncSettings syncSettings, bool deterministic)
@ -90,10 +92,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
InitMemoryCallbacks();
_inputcb = InputCallback;
LibSameboy.sameboy_setinputcallback(SameboyState, _inputcb);
_rumblecb = RumbleCallback;
_tracecb = MakeTrace;
LibSameboy.sameboy_settracecallback(SameboyState, null);
LibSameboy.sameboy_setinputcallback(SameboyState, _inputcb);
LibSameboy.sameboy_setrumblecallback(SameboyState, _rumblecb);
LibSameboy.sameboy_settracecallback(SameboyState, null);
LibSameboy.sameboy_setscanlinecallback(SameboyState, null, 0);
LibSameboy.sameboy_setprintercallback(SameboyState, null);
@ -112,7 +117,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
BoardName = MapperName(file);
_hasAcc = BoardName is "MBC7 ROM+ACCEL+EEPROM";
ControllerDefinition = Gameboy.Gameboy.CreateControllerDefinition(sgb: false, sub: false, tilt: _hasAcc);
ControllerDefinition = Gameboy.Gameboy.CreateControllerDefinition(sgb: false, sub: false, tilt: _hasAcc, rumble: true);
LibSameboy.sameboy_setrtcdivisoroffset(SameboyState, _syncSettings.RTCDivisorOffset);
CycleCount = 0;
@ -140,6 +145,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
_inputCallbacks.Call();
}
private void RumbleCallback(int amplitude)
{
_controller.SetHapticChannelStrength("Rumble", amplitude);
}
public bool LinkConnected
{
get => _printercb != null;
@ -187,7 +197,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
var _bgpal = IntPtr.Zero;
var _sppal = IntPtr.Zero;
var _oam = IntPtr.Zero;
int unused = 0;
long unused = 0;
if (!LibSameboy.sameboy_getmemoryarea(SameboyState, LibSameboy.MemoryAreas.VRAM, ref _vram, ref unused)
|| !LibSameboy.sameboy_getmemoryarea(SameboyState, LibSameboy.MemoryAreas.BGPRGB, ref _bgpal, ref unused)
|| !LibSameboy.sameboy_getmemoryarea(SameboyState, LibSameboy.MemoryAreas.OBPRGB, ref _sppal, ref unused)

View File

@ -19,6 +19,7 @@ typedef uint32_t u32;
typedef uint64_t u64;
typedef void (*input_callback_t)(void);
typedef void (*rumble_callback_t)(u32);
typedef void (*trace_callback_t)(u16);
typedef void (*memory_callback_t)(u16);
typedef void (*printer_callback_t)(u32*, u8, u8, u8, u8);
@ -36,6 +37,7 @@ typedef struct
u32 obj_pal[0x20];
GB_palette_t custom_pal;
input_callback_t input_cb;
rumble_callback_t rumble_cb;
trace_callback_t trace_cb;
memory_callback_t read_cb;
memory_callback_t write_cb;
@ -77,17 +79,22 @@ static u32 rgb_cb(GB_gameboy_t *gb, u8 r, u8 g, u8 b)
return (0xFF << 24) | (r << 16) | (g << 8) | b;
}
static void vblank_cb(GB_gameboy_t *gb, GB_vblank_type_t type)
static void vblank_cb(GB_gameboy_t* gb, GB_vblank_type_t type)
{
((biz_t*)gb)->vblank_occured = true;
}
static u8 camera_pixel_cb(GB_gameboy_t *gb, u8 x, u8 y)
static u8 camera_pixel_cb(GB_gameboy_t* gb, u8 x, u8 y)
{
// stub for now (also needed for determinism)
return 0;
}
static void RumbleCallbackRelay(GB_gameboy_t* gb, double rumble_amplitude)
{
((biz_t*)gb)->rumble_cb(INT32_MAX * rumble_amplitude);
}
static u8 ReadCallbackRelay(GB_gameboy_t* gb, u16 addr, u8 data)
{
((biz_t*)gb)->read_cb(addr);
@ -135,6 +142,8 @@ EXPORT biz_t* sameboy_create(u8* romdata, u32 romlen, u8* biosdata, u32 bioslen,
GB_load_rom_from_buffer(&biz->gb, romdata, romlen);
GB_load_boot_rom_from_buffer(&biz->gb, biosdata, bioslen);
GB_set_sample_rate(&biz->gb, GB_get_clock_rate(&biz->gb) / 2 / 8);
GB_set_rumble_mode(&biz->gb, GB_RUMBLE_ALL_GAMES);
GB_set_rumble_callback(&biz->gb, RumbleCallbackRelay);
GB_apu_set_sample_callback(&biz->gb, sample_cb);
GB_set_rgb_encode_callback(&biz->gb, rgb_cb);
GB_set_vblank_callback(&biz->gb, vblank_cb);
@ -163,6 +172,11 @@ EXPORT void sameboy_setinputcallback(biz_t* biz, input_callback_t callback)
biz->input_cb = callback;
}
EXPORT void sameboy_setrumblecallback(biz_t* biz, rumble_callback_t callback)
{
biz->rumble_cb = callback;
}
static double FromRawToG(u16 raw)
{
return (raw - 0x81D0) / (0x70 * 1.0);