SubGambatte (squashed PR #2732)
This commit is contained in:
parent
b62f4bc6a9
commit
e5e187982a
|
@ -9,56 +9,91 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
{
|
||||
public IEmulatorServiceProvider ServiceProvider { get; }
|
||||
|
||||
public ControllerDefinition ControllerDefinition => GbController;
|
||||
public ControllerDefinition ControllerDefinition => (_syncSettings.FrameLength == GambatteSyncSettings.FrameLengthType.UserDefinedFrames) ? SubGbController : GbController;
|
||||
|
||||
public bool FrameAdvance(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
FrameAdvancePrep(controller);
|
||||
if (_syncSettings.EqualLengthFrames)
|
||||
uint samplesEmitted;
|
||||
switch (_syncSettings.FrameLength)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// target number of samples to emit: length of 1 frame minus whatever overflow
|
||||
uint samplesEmitted = TICKSINFRAME - frameOverflow;
|
||||
Debug.Assert(samplesEmitted * 2 <= _soundbuff.Length);
|
||||
case GambatteSyncSettings.FrameLengthType.VBlankDrivenFrames:
|
||||
// target number of samples to emit: always 59.7fps
|
||||
// runfor() always ends after creating a video frame, so sync-up is guaranteed
|
||||
// when the display has been off, some frames can be markedly shorter than expected
|
||||
samplesEmitted = TICKSINFRAME;
|
||||
if (LibGambatte.gambatte_runfor(GambatteState, _soundbuff, ref samplesEmitted) > 0)
|
||||
{
|
||||
LibGambatte.gambatte_blitto(GambatteState, VideoBuffer, 160);
|
||||
}
|
||||
|
||||
// account for actual number of samples emitted
|
||||
_cycleCount += samplesEmitted;
|
||||
frameOverflow += samplesEmitted;
|
||||
|
||||
frameOverflow = 0;
|
||||
if (rendersound && !Muted)
|
||||
{
|
||||
ProcessSound((int)samplesEmitted);
|
||||
}
|
||||
|
||||
if (frameOverflow >= TICKSINFRAME)
|
||||
break;
|
||||
case GambatteSyncSettings.FrameLengthType.EqualLengthFrames:
|
||||
while (true)
|
||||
{
|
||||
frameOverflow -= TICKSINFRAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// target number of samples to emit: always 59.7fps
|
||||
// runfor() always ends after creating a video frame, so sync-up is guaranteed
|
||||
// when the display has been off, some frames can be markedly shorter than expected
|
||||
uint samplesEmitted = TICKSINFRAME;
|
||||
if (LibGambatte.gambatte_runfor(GambatteState, _soundbuff, ref samplesEmitted) > 0)
|
||||
{
|
||||
LibGambatte.gambatte_blitto(GambatteState, VideoBuffer, 160);
|
||||
}
|
||||
// target number of samples to emit: length of 1 frame minus whatever overflow
|
||||
samplesEmitted = TICKSINFRAME - frameOverflow;
|
||||
Debug.Assert(samplesEmitted * 2 <= _soundbuff.Length);
|
||||
if (LibGambatte.gambatte_runfor(GambatteState, _soundbuff, ref samplesEmitted) > 0)
|
||||
{
|
||||
LibGambatte.gambatte_blitto(GambatteState, VideoBuffer, 160);
|
||||
}
|
||||
|
||||
_cycleCount += samplesEmitted;
|
||||
frameOverflow = 0;
|
||||
if (rendersound && !Muted)
|
||||
{
|
||||
ProcessSound((int)samplesEmitted);
|
||||
}
|
||||
// account for actual number of samples emitted
|
||||
_cycleCount += samplesEmitted;
|
||||
frameOverflow += samplesEmitted;
|
||||
|
||||
if (rendersound && !Muted)
|
||||
{
|
||||
ProcessSound((int)samplesEmitted);
|
||||
}
|
||||
|
||||
if (frameOverflow >= TICKSINFRAME)
|
||||
{
|
||||
frameOverflow -= TICKSINFRAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GambatteSyncSettings.FrameLengthType.UserDefinedFrames:
|
||||
while (true)
|
||||
{
|
||||
// target number of samples to emit: input length minus whatever overflow
|
||||
float inputFrameLength = controller.AxisValue("Input Length");
|
||||
uint inputFrameLengthInt = (uint)Math.Floor(inputFrameLength);
|
||||
if (inputFrameLengthInt == 0)
|
||||
{
|
||||
inputFrameLengthInt = TICKSINFRAME;
|
||||
}
|
||||
samplesEmitted = inputFrameLengthInt - frameOverflow;
|
||||
Debug.Assert(samplesEmitted * 2 <= _soundbuff.Length);
|
||||
if (LibGambatte.gambatte_runfor(GambatteState, _soundbuff, ref samplesEmitted) > 0)
|
||||
{
|
||||
LibGambatte.gambatte_blitto(GambatteState, VideoBuffer, 160);
|
||||
}
|
||||
|
||||
// account for actual number of samples emitted
|
||||
_cycleCount += samplesEmitted;
|
||||
frameOverflow += samplesEmitted;
|
||||
|
||||
if (rendersound && !Muted)
|
||||
{
|
||||
ProcessSound((int)samplesEmitted);
|
||||
}
|
||||
|
||||
if (frameOverflow >= inputFrameLengthInt)
|
||||
{
|
||||
frameOverflow -= inputFrameLengthInt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (rendersound && !Muted)
|
||||
|
|
|
@ -255,16 +255,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
get => _latchedRTCSeconds;
|
||||
set => _latchedRTCSeconds = Math.Max(0, Math.Min(63, value));
|
||||
}
|
||||
|
||||
[DisplayName("Equal Length Frames")]
|
||||
[Description("When false, emulation frames sync to vblank. Only useful for high level TASing.")]
|
||||
[DefaultValue(false)]
|
||||
public bool EqualLengthFrames
|
||||
|
||||
public enum FrameLengthType
|
||||
{
|
||||
get => _equalLengthFrames;
|
||||
set => _equalLengthFrames = value;
|
||||
VBlankDrivenFrames,
|
||||
EqualLengthFrames,
|
||||
UserDefinedFrames
|
||||
}
|
||||
|
||||
[DisplayName("Frame Length")]
|
||||
[Description("Sets how long an emulation frame will last.\nVBlank Driven Frames will make emulation frames sync to VBlank. Recommended for TASing.\nEqual Length Frames will force all frames to emit 35112 samples. Legacy, not recommended for TASing.\nUser Defined Frames allows for the user to define how many samples are emitted for each frame. Only useful if sub-frame input is desired.")]
|
||||
[DefaultValue(FrameLengthType.VBlankDrivenFrames)]
|
||||
public FrameLengthType FrameLength { get; set; }
|
||||
|
||||
[DisplayName("Display BG")]
|
||||
[Description("Display background")]
|
||||
[DefaultValue(true)]
|
||||
|
@ -282,7 +285,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
|
||||
[JsonIgnore]
|
||||
[DeepEqualsIgnore]
|
||||
private bool _equalLengthFrames;
|
||||
private FrameLengthType _frameLength;
|
||||
|
||||
public GambatteSyncSettings()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.BufferExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy;
|
||||
|
@ -246,6 +247,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
"Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
|
||||
}
|
||||
};
|
||||
|
||||
public static readonly ControllerDefinition SubGbController = new ControllerDefinition
|
||||
{
|
||||
Name = "Subframe Gameboy Controller",
|
||||
BoolButtons =
|
||||
{
|
||||
"Up", "Down", "Left", "Right", "Start", "Select", "B", "A", "Power"
|
||||
}
|
||||
}.AddAxis("Input Length", 0.RangeTo(35112), 35112);
|
||||
|
||||
private LibGambatte.Buttons ControllerCallback()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue