wire up sameboy's rumble
This commit is contained in:
parent
ea5e8b70d3
commit
d84da4ec4b
Binary file not shown.
Binary file not shown.
|
@ -182,7 +182,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
|
|
||||||
_cdCallback = new LibGambatte.CDCallback(CDCallbackProc);
|
_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();
|
NewSaveCoreSetBuff();
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
public long CycleCount => (long)_cycleCount;
|
public long CycleCount => (long)_cycleCount;
|
||||||
public double ClockRate => TICKSPERSECOND;
|
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" : ""));
|
var ret = new ControllerDefinition((sub ? "Subframe " : "") + "Gameboy Controller" + (tilt ? " + Tilt" : ""));
|
||||||
if (sub)
|
if (sub)
|
||||||
|
@ -258,6 +258,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
{
|
{
|
||||||
ret.AddXYPair($"Tilt {{0}}", AxisPairOrientation.RightAndUp, (-90).RangeTo(90), 0);
|
ret.AddXYPair($"Tilt {{0}}", AxisPairOrientation.RightAndUp, (-90).RangeTo(90), 0);
|
||||||
}
|
}
|
||||||
|
if (rumble)
|
||||||
|
{
|
||||||
|
ret.HapticsChannels.Add("Rumble");
|
||||||
|
}
|
||||||
if (sgb)
|
if (sgb)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
|
|
|
@ -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] = 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].ConnectInputCallbackSystem(_inputCallbacks);
|
||||||
_linkedCores[i].ConnectMemoryCallbackSystem(_memoryCallbacks, i);
|
_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] = new BlipBuffer(1024);
|
||||||
_linkedBlips[i].SetRates(2097152 * 2, 44100);
|
_linkedBlips[i].SetRates(2097152 * 2, 44100);
|
||||||
_linkedOverflow[i] = 0;
|
_linkedOverflow[i] = 0;
|
||||||
|
|
|
@ -53,6 +53,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
||||||
[BizImport(cc)]
|
[BizImport(cc)]
|
||||||
public abstract void sameboy_setinputcallback(IntPtr core, InputCallback callback);
|
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)]
|
[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);
|
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);
|
public abstract int sameboy_statelen(IntPtr core);
|
||||||
|
|
||||||
[BizImport(cc)]
|
[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)]
|
[BizImport(cc)]
|
||||||
public abstract byte sameboy_cpuread(IntPtr core, ushort addr);
|
public abstract byte sameboy_cpuread(IntPtr core, ushort addr);
|
||||||
|
|
|
@ -11,10 +11,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
||||||
|
|
||||||
public ControllerDefinition ControllerDefinition { get; }
|
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 static readonly IReadOnlyList<string> GB_BUTTON_ORDER_IN_BITMASK = new[] { "Start", "Select", "B", "A", "Down", "Up", "Left", "Right", };
|
||||||
|
|
||||||
private LibSameboy.Buttons FrameAdvancePrep(IController controller)
|
private LibSameboy.Buttons FrameAdvancePrep(IController controller)
|
||||||
{
|
{
|
||||||
|
_controller = controller;
|
||||||
|
|
||||||
uint b = 0;
|
uint b = 0;
|
||||||
for (var i = 0; i < 8; i++)
|
for (var i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,14 +7,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
||||||
{
|
{
|
||||||
public partial class 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 IMemoryDomains MemoryDomains { get; set; }
|
||||||
|
|
||||||
private void CreateMemoryDomain(LibSameboy.MemoryAreas which, string name)
|
private void CreateMemoryDomain(LibSameboy.MemoryAreas which, string name)
|
||||||
{
|
{
|
||||||
IntPtr data = IntPtr.Zero;
|
IntPtr data = IntPtr.Zero;
|
||||||
int length = 0;
|
long length = 0;
|
||||||
|
|
||||||
if (!LibSameboy.sameboy_getmemoryarea(SameboyState, which, ref data, ref length))
|
if (!LibSameboy.sameboy_getmemoryarea(SameboyState, which, ref data, ref length))
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,6 +39,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
||||||
|
|
||||||
private readonly LibSameboy.InputCallback _inputcb;
|
private readonly LibSameboy.InputCallback _inputcb;
|
||||||
|
|
||||||
|
private readonly LibSameboy.RumbleCallback _rumblecb;
|
||||||
|
|
||||||
[CoreConstructor(VSystemID.Raw.GB)]
|
[CoreConstructor(VSystemID.Raw.GB)]
|
||||||
[CoreConstructor(VSystemID.Raw.GBC)]
|
[CoreConstructor(VSystemID.Raw.GBC)]
|
||||||
public Sameboy(CoreComm comm, GameInfo game, byte[] file, SameboySettings settings, SameboySyncSettings syncSettings, bool deterministic)
|
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();
|
InitMemoryCallbacks();
|
||||||
|
|
||||||
_inputcb = InputCallback;
|
_inputcb = InputCallback;
|
||||||
LibSameboy.sameboy_setinputcallback(SameboyState, _inputcb);
|
_rumblecb = RumbleCallback;
|
||||||
_tracecb = MakeTrace;
|
_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_setscanlinecallback(SameboyState, null, 0);
|
||||||
LibSameboy.sameboy_setprintercallback(SameboyState, null);
|
LibSameboy.sameboy_setprintercallback(SameboyState, null);
|
||||||
|
|
||||||
|
@ -112,7 +117,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
||||||
BoardName = MapperName(file);
|
BoardName = MapperName(file);
|
||||||
|
|
||||||
_hasAcc = BoardName is "MBC7 ROM+ACCEL+EEPROM";
|
_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);
|
LibSameboy.sameboy_setrtcdivisoroffset(SameboyState, _syncSettings.RTCDivisorOffset);
|
||||||
CycleCount = 0;
|
CycleCount = 0;
|
||||||
|
@ -140,6 +145,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
||||||
_inputCallbacks.Call();
|
_inputCallbacks.Call();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RumbleCallback(int amplitude)
|
||||||
|
{
|
||||||
|
_controller.SetHapticChannelStrength("Rumble", amplitude);
|
||||||
|
}
|
||||||
|
|
||||||
public bool LinkConnected
|
public bool LinkConnected
|
||||||
{
|
{
|
||||||
get => _printercb != null;
|
get => _printercb != null;
|
||||||
|
@ -187,7 +197,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Sameboy
|
||||||
var _bgpal = IntPtr.Zero;
|
var _bgpal = IntPtr.Zero;
|
||||||
var _sppal = IntPtr.Zero;
|
var _sppal = IntPtr.Zero;
|
||||||
var _oam = IntPtr.Zero;
|
var _oam = IntPtr.Zero;
|
||||||
int unused = 0;
|
long unused = 0;
|
||||||
if (!LibSameboy.sameboy_getmemoryarea(SameboyState, LibSameboy.MemoryAreas.VRAM, ref _vram, ref unused)
|
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.BGPRGB, ref _bgpal, ref unused)
|
||||||
|| !LibSameboy.sameboy_getmemoryarea(SameboyState, LibSameboy.MemoryAreas.OBPRGB, ref _sppal, ref unused)
|
|| !LibSameboy.sameboy_getmemoryarea(SameboyState, LibSameboy.MemoryAreas.OBPRGB, ref _sppal, ref unused)
|
||||||
|
|
|
@ -19,6 +19,7 @@ typedef uint32_t u32;
|
||||||
typedef uint64_t u64;
|
typedef uint64_t u64;
|
||||||
|
|
||||||
typedef void (*input_callback_t)(void);
|
typedef void (*input_callback_t)(void);
|
||||||
|
typedef void (*rumble_callback_t)(u32);
|
||||||
typedef void (*trace_callback_t)(u16);
|
typedef void (*trace_callback_t)(u16);
|
||||||
typedef void (*memory_callback_t)(u16);
|
typedef void (*memory_callback_t)(u16);
|
||||||
typedef void (*printer_callback_t)(u32*, u8, u8, u8, u8);
|
typedef void (*printer_callback_t)(u32*, u8, u8, u8, u8);
|
||||||
|
@ -36,6 +37,7 @@ typedef struct
|
||||||
u32 obj_pal[0x20];
|
u32 obj_pal[0x20];
|
||||||
GB_palette_t custom_pal;
|
GB_palette_t custom_pal;
|
||||||
input_callback_t input_cb;
|
input_callback_t input_cb;
|
||||||
|
rumble_callback_t rumble_cb;
|
||||||
trace_callback_t trace_cb;
|
trace_callback_t trace_cb;
|
||||||
memory_callback_t read_cb;
|
memory_callback_t read_cb;
|
||||||
memory_callback_t write_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;
|
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;
|
((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)
|
// stub for now (also needed for determinism)
|
||||||
return 0;
|
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)
|
static u8 ReadCallbackRelay(GB_gameboy_t* gb, u16 addr, u8 data)
|
||||||
{
|
{
|
||||||
((biz_t*)gb)->read_cb(addr);
|
((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_rom_from_buffer(&biz->gb, romdata, romlen);
|
||||||
GB_load_boot_rom_from_buffer(&biz->gb, biosdata, bioslen);
|
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_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_apu_set_sample_callback(&biz->gb, sample_cb);
|
||||||
GB_set_rgb_encode_callback(&biz->gb, rgb_cb);
|
GB_set_rgb_encode_callback(&biz->gb, rgb_cb);
|
||||||
GB_set_vblank_callback(&biz->gb, vblank_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;
|
biz->input_cb = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT void sameboy_setrumblecallback(biz_t* biz, rumble_callback_t callback)
|
||||||
|
{
|
||||||
|
biz->rumble_cb = callback;
|
||||||
|
}
|
||||||
|
|
||||||
static double FromRawToG(u16 raw)
|
static double FromRawToG(u16 raw)
|
||||||
{
|
{
|
||||||
return (raw - 0x81D0) / (0x70 * 1.0);
|
return (raw - 0x81D0) / (0x70 * 1.0);
|
||||||
|
|
Loading…
Reference in New Issue