diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/LibVirtualBoyee.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/LibVirtualBoyee.cs index 6e25e72e3a..d41b77ec6e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/LibVirtualBoyee.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/LibVirtualBoyee.cs @@ -21,37 +21,47 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB public int H; } - [StructLayout(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Explicit)] // TODO: find out why Sequential is sometimes ignored on the native layout public class EmulateSpec { // Pitch(32-bit) must be equal to width and >= the "fb_width" specified in the MDFNGI struct for the emulated system. // Height must be >= to the "fb_height" specified in the MDFNGI struct for the emulated system. // The framebuffer pointed to by surface->pixels is written to by the system emulation code. + [FieldOffset(0)] public IntPtr Pixels; // Pointer to sound buffer, set by the driver code, that the emulation code should render sound to. // Guaranteed to be at least 500ms in length, but emulation code really shouldn't exceed 40ms or so. Additionally, if emulation code // generates >= 100ms, // DEPRECATED: Emulation code may set this pointer to a sound buffer internal to the emulation module. + [FieldOffset(8)] public IntPtr SoundBuf; // Number of cycles that this frame consumed, using MDFNGI::MasterClock as a time base. // Set by emulation code. + [FieldOffset(16)] public long MasterCycles; // Set by the system emulation code every frame, to denote the horizontal and vertical offsets of the image, and the size // of the image. If the emulated system sets the elements of LineWidths, then the width(w) of this structure // is ignored while drawing the image. + [FieldOffset(24)] public Rect DisplayRect; // Maximum size of the sound buffer, in frames. Set by the driver code. + [FieldOffset(40)] public int SoundBufMaxSize; // Number of frames currently in internal sound buffer. Set by the system emulation code, to be read by the driver code. + [FieldOffset(44)] public int SoundBufSize; // 0 UDLR SelectStartBA UDLR(right dpad) LtrigRtrig 13 + [FieldOffset(48)] public Buttons Buttons; + + [FieldOffset(52)] + public bool Lagged; } public enum MemoryArea : int @@ -77,6 +87,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB R = 0x4 } + [UnmanagedFunctionPointer(CC)] + public delegate void InputCallback(); + [BizImport(CC)] public abstract bool Load(byte[] rom, int length); @@ -88,5 +101,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB [BizImport(CC)] public abstract void HardReset(); + + [BizImport(CC)] + public abstract void SetInputCallback(InputCallback callback); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/VirtualBoyee.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/VirtualBoyee.cs index 2ca48735a6..d21f9054e7 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/VirtualBoyee.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/VB/VirtualBoyee.cs @@ -11,9 +11,10 @@ using System.Threading.Tasks; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB { - [CoreAttributes("Virtual Boyee", "???", true, false, "0.9.44.1", + [CoreAttributes("Virtual Boyee", "???", true, false, "0.9.44.1", "https://mednafen.github.io/releases/", false)] - public class VirtualBoyee : IEmulator, IVideoProvider, ISoundProvider, IStatable + public class VirtualBoyee : IEmulator, IVideoProvider, ISoundProvider, IStatable, + IInputPollable { private PeRunner _exe; private LibVirtualBoyee _boyee; @@ -42,6 +43,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB } _exe.Seal(); + + _inputCallback = InputCallbacks.Call; } private bool _disposed = false; @@ -60,6 +63,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB public unsafe void FrameAdvance(IController controller, bool render, bool rendersound = true) { + _boyee.SetInputCallback(InputCallbacks.Count > 0 ? _inputCallback : null); + if (controller.IsPressed("Power")) _boyee.HardReset(); @@ -78,20 +83,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB BufferWidth = spec.DisplayRect.W; BufferHeight = spec.DisplayRect.H; _numSamples = spec.SoundBufSize; + + Frame++; + + IsLagFrame = spec.Lagged; + if (IsLagFrame) + LagCount++; + } - - Frame++; - - /*_core.biz_set_input_callback(InputCallbacks.Count > 0 ? _inputCallback : null); - - UpdateControls(controller); - Frame++; - LibSnes9x.frame_info frame = new LibSnes9x.frame_info(); - - _core.biz_run(frame, _inputState); - IsLagFrame = frame.padread == 0; - if (IsLagFrame) - LagCount++;*/ } public int Frame { get; private set; } @@ -199,6 +198,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB public int LagCount { get; set; } public bool IsLagFrame { get; set; } + private LibVirtualBoyee.InputCallback _inputCallback; + + public IInputCallbackSystem InputCallbacks { get; } = new InputCallbackSystem(); + #region IStatable public bool BinarySaveStatesPreferred @@ -230,6 +233,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.VB LagCount = reader.ReadInt32(); IsLagFrame = reader.ReadBoolean(); // any managed pointers that we sent to the core need to be resent now! + _boyee.SetInputCallback(null); } public void SaveStateBinary(BinaryWriter writer) diff --git a/output64/dll/vb.wbx b/output64/dll/vb.wbx index f398cbff38..34b3f7d413 100644 Binary files a/output64/dll/vb.wbx and b/output64/dll/vb.wbx differ diff --git a/waterbox/vb/git.h b/waterbox/vb/git.h index edcd8a8415..d9e8108b3d 100644 --- a/waterbox/vb/git.h +++ b/waterbox/vb/git.h @@ -41,6 +41,9 @@ struct EmulateSpecStruct // 0 UDLR SelectStartBA UDLR(right dpad) LtrigRtrig 13 int32 Buttons; + + // set by core, true if lagged + int32 Lagged; }; /*typedef struct diff --git a/waterbox/vb/vb.cpp b/waterbox/vb/vb.cpp index bf0639cc4f..8e79dc7671 100644 --- a/waterbox/vb/vb.cpp +++ b/waterbox/vb/vb.cpp @@ -25,6 +25,9 @@ namespace MDFN_IEN_VB { +static void (*input_callback)(); +static bool lagged; + enum { ANAGLYPH_PRESET_DISABLED = 0, @@ -126,6 +129,9 @@ static MDFN_FASTCALL uint8 HWCTRL_Read(v810_timestamp_t ×tamp, uint32 A) case 0x10: case 0x14: case 0x28: + lagged = false; + if (input_callback) + input_callback(); ret = VBINPUT_Read(timestamp, A); break; } @@ -738,6 +744,7 @@ EXPORT void GetMemoryArea(int which, void **ptr, int *size) EXPORT void Emulate(EmulateSpecStruct *espec) { v810_timestamp_t v810_timestamp; + lagged = true; VBINPUT_Frame(&espec->Buttons); @@ -753,6 +760,7 @@ EXPORT void Emulate(EmulateSpecStruct *espec) VSU_CycleFix = (v810_timestamp + VSU_CycleFix) & 3; espec->MasterCycles = v810_timestamp; + espec->Lagged = lagged; TIMER_ResetTS(); VBINPUT_ResetTS(); @@ -768,6 +776,11 @@ EXPORT void HardReset() VB_Power(); } +EXPORT void SetInputCallback(void (*callback)()) +{ + input_callback = callback; +} + int main() { return 0;