2017-04-25 15:11:43 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
|
|
|
|
using BizHawk.Emulation.Common;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|
|
|
|
{
|
2017-05-01 02:01:37 +00:00
|
|
|
|
public partial class Gameboy : IEmulator, IBoardInfo
|
2017-04-25 15:11:43 +00:00
|
|
|
|
{
|
|
|
|
|
public IEmulatorServiceProvider ServiceProvider { get; }
|
|
|
|
|
|
|
|
|
|
public ControllerDefinition ControllerDefinition => GbController;
|
|
|
|
|
|
2017-05-02 01:09:11 +00:00
|
|
|
|
public void FrameAdvance(IController controller, bool render, bool rendersound)
|
2017-04-25 15:11:43 +00:00
|
|
|
|
{
|
2017-05-02 01:09:11 +00:00
|
|
|
|
FrameAdvancePrep(controller);
|
2017-04-25 15:11:43 +00:00
|
|
|
|
if (_syncSettings.EqualLengthFrames)
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
// target number of samples to emit: length of 1 frame minus whatever overflow
|
|
|
|
|
uint samplesEmitted = TICKSINFRAME - frameOverflow;
|
2017-04-25 16:06:50 +00:00
|
|
|
|
Debug.Assert(samplesEmitted * 2 <= _soundbuff.Length);
|
|
|
|
|
if (LibGambatte.gambatte_runfor(GambatteState, _soundbuff, ref samplesEmitted) > 0)
|
2017-04-25 15:11:43 +00:00
|
|
|
|
{
|
|
|
|
|
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 >= TICKSINFRAME)
|
|
|
|
|
{
|
|
|
|
|
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;
|
2017-04-25 16:06:50 +00:00
|
|
|
|
if (LibGambatte.gambatte_runfor(GambatteState, _soundbuff, ref samplesEmitted) > 0)
|
2017-04-25 15:11:43 +00:00
|
|
|
|
{
|
|
|
|
|
LibGambatte.gambatte_blitto(GambatteState, VideoBuffer, 160);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_cycleCount += samplesEmitted;
|
|
|
|
|
frameOverflow = 0;
|
|
|
|
|
if (rendersound && !Muted)
|
|
|
|
|
{
|
|
|
|
|
ProcessSound((int)samplesEmitted);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rendersound && !Muted)
|
|
|
|
|
{
|
|
|
|
|
ProcessSoundEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrameAdvancePost();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Frame { get; private set; }
|
|
|
|
|
|
|
|
|
|
public string SystemId => "GB";
|
|
|
|
|
|
|
|
|
|
public string BoardName { get; }
|
|
|
|
|
|
|
|
|
|
public bool DeterministicEmulation { get; }
|
|
|
|
|
|
|
|
|
|
public void ResetCounters()
|
|
|
|
|
{
|
|
|
|
|
Frame = 0;
|
|
|
|
|
LagCount = 0;
|
|
|
|
|
IsLagFrame = false;
|
|
|
|
|
|
|
|
|
|
// reset frame counters is meant to "re-zero" emulation time wherever it was
|
|
|
|
|
// so these should be reset as well
|
|
|
|
|
_cycleCount = 0;
|
|
|
|
|
frameOverflow = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public CoreComm CoreComm { get; }
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (GambatteState != IntPtr.Zero)
|
|
|
|
|
{
|
2017-06-24 17:05:00 +00:00
|
|
|
|
Console.WriteLine("disposing");
|
2017-04-25 15:11:43 +00:00
|
|
|
|
LibGambatte.gambatte_destroy(GambatteState);
|
2017-06-24 17:05:00 +00:00
|
|
|
|
Console.WriteLine("step2");
|
2017-04-25 15:11:43 +00:00
|
|
|
|
GambatteState = IntPtr.Zero;
|
2017-06-24 17:05:00 +00:00
|
|
|
|
Console.WriteLine("disposed");
|
2017-04-25 15:11:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DisposeSound();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|