SubGambatte (squashed PR #2732)

This commit is contained in:
CasualPokePlayer 2021-06-07 02:18:24 -07:00 committed by GitHub
parent b62f4bc6a9
commit e5e187982a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 41 deletions

View File

@ -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)

View File

@ -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()
{

View File

@ -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()
{