[Gambatte] API updates, setting time now uses a single function which takes in dividers

This commit is contained in:
CasualPokePlayer 2022-04-03 02:34:23 -07:00
parent c33d2cfbe5
commit d4bb5e047e
7 changed files with 24 additions and 186 deletions

Binary file not shown.

Binary file not shown.

View File

@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{ {
get get
{ {
if (LibGambatte.gambatte_savesavedatalength(GambatteState, DeterministicEmulation) == 0) if (LibGambatte.gambatte_getsavedatalength(GambatteState) == 0)
{ {
return false; return false;
} }
@ -21,12 +21,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public byte[] CloneSaveRam() public byte[] CloneSaveRam()
{ {
int length = LibGambatte.gambatte_savesavedatalength(GambatteState, DeterministicEmulation); int length = LibGambatte.gambatte_getsavedatalength(GambatteState);
if (length > 0) if (length > 0)
{ {
byte[] ret = new byte[length]; byte[] ret = new byte[length];
LibGambatte.gambatte_savesavedata(GambatteState, ret, DeterministicEmulation); LibGambatte.gambatte_savesavedata(GambatteState, ret);
return ret; return ret;
} }
@ -35,7 +35,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public void StoreSaveRam(byte[] data) public void StoreSaveRam(byte[] data)
{ {
int expected = LibGambatte.gambatte_savesavedatalength(GambatteState, DeterministicEmulation); int expected = LibGambatte.gambatte_getsavedatalength(GambatteState);
switch (data.Length - expected) switch (data.Length - expected)
{ {
case 0: case 0:
@ -44,7 +44,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
throw new ArgumentException("Size of saveram data does not match expected!"); throw new ArgumentException("Size of saveram data does not match expected!");
} }
LibGambatte.gambatte_loadsavedata(GambatteState, data, DeterministicEmulation); LibGambatte.gambatte_loadsavedata(GambatteState, data);
if (DeterministicEmulation)
{
ulong dividers = _syncSettings.InitialTime * (0x400000UL + (ulong)_syncSettings.RTCDivisorOffset) / 2UL;
LibGambatte.gambatte_settime(GambatteState, dividers);
}
} }
} }
} }

View File

@ -135,133 +135,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
[DefaultValue(0)] [DefaultValue(0)]
public int RTCDivisorOffset { get; set; } public int RTCDivisorOffset { get; set; }
[JsonIgnore] [DisplayName("Initial Time")]
private int _internalRTCDays; [Description("Initial time of emulation in seconds.")]
[DefaultValue(typeof(ulong), "0")]
[JsonIgnore] public ulong InitialTime { get; set; }
private int _internalRTCHours;
[JsonIgnore]
private int _internalRTCMinutes;
[JsonIgnore]
private int _internalRTCSeconds;
[JsonIgnore]
private int _internalRTCCycles;
[JsonIgnore]
private int _latchedRTCDays;
[JsonIgnore]
private int _latchedRTCHours;
[JsonIgnore]
private int _latchedRTCMinutes;
[JsonIgnore]
private int _latchedRTCSeconds;
[DisplayName("RTC Overflow")]
[Description("Sets whether the internal RTC day counter has overflowed.")]
[DefaultValue(false)]
public bool InternalRTCOverflow { get; set; }
[DisplayName("RTC Halt")]
[Description("Sets whether the internal RTC has halted.")]
[DefaultValue(false)]
public bool InternalRTCHalt { get; set; }
[DisplayName("RTC Days")]
[Description("Sets the internal RTC day counter. Ranges from 0 to 511.")]
[DefaultValue(0)]
public int InternalRTCDays
{
get => _internalRTCDays;
set => _internalRTCDays = Math.Max(0, Math.Min(511, value));
}
[DisplayName("RTC Hours")]
[Description("Sets the internal RTC hour counter. Ranges from -8 to 23.")]
[DefaultValue(0)]
public int InternalRTCHours
{
get => _internalRTCHours;
set => _internalRTCHours = Math.Max(-8, Math.Min(23, value));
}
[DisplayName("RTC Minutes")]
[Description("Sets the internal RTC minute counter. Ranges from -4 to 59.")]
[DefaultValue(0)]
public int InternalRTCMinutes
{
get => _internalRTCMinutes;
set => _internalRTCMinutes = Math.Max(-4, Math.Min(59, value));
}
[DisplayName("RTC Seconds")]
[Description("Sets the internal RTC second counter. Ranges from -4 to 59.")]
[DefaultValue(0)]
public int InternalRTCSeconds
{
get => _internalRTCSeconds;
set => _internalRTCSeconds = Math.Max(-4, Math.Min(59, value));
}
[DisplayName("RTC Sub-Seconds")]
[Description("Sets the internal RTC sub-second counter, expressed in CPU cycles. Ranges from 0 to 4194303 + the set RTC divisor offset.")]
[DefaultValue(0)]
public int InternalRTCCycles
{
get => _internalRTCCycles;
set => _internalRTCCycles = Math.Max(0, Math.Min((4194303 + RTCDivisorOffset), value));
}
[DisplayName("Latched RTC Overflow")]
[Description("Sets whether the latched RTC shows an overflow.")]
[DefaultValue(false)]
public bool LatchedRTCOverflow { get; set; }
[DisplayName("Latched RTC Halt")]
[Description("Sets whether the latched RTC shows a halt.")]
[DefaultValue(false)]
public bool LatchedRTCHalt { get; set; }
[DisplayName("Latched RTC Days")]
[Description("Sets the latched RTC days. Ranges from 0 to 511.")]
[DefaultValue(0)]
public int LatchedRTCDays
{
get => _latchedRTCDays;
set => _latchedRTCDays = Math.Max(0, Math.Min(511, value));
}
[DisplayName("Latched RTC Hours")]
[Description("Sets the latched RTC hours. Ranges from 0 to 31.")]
[DefaultValue(0)]
public int LatchedRTCHours
{
get => _latchedRTCHours;
set => _latchedRTCHours = Math.Max(0, Math.Min(63, value));
}
[DisplayName("Latched RTC Minutes")]
[Description("Sets the latched RTC minutes. Ranges from 0 to 63.")]
[DefaultValue(0)]
public int LatchedRTCMinutes
{
get => _latchedRTCMinutes;
set => _latchedRTCMinutes = Math.Max(0, Math.Min(63, value));
}
[DisplayName("Latched RTC Seconds")]
[Description("Sets the latched RTC seconds. Ranges from 0 to 63.")]
[DefaultValue(0)]
public int LatchedRTCSeconds
{
get => _latchedRTCSeconds;
set => _latchedRTCSeconds = Math.Max(0, Math.Min(63, value));
}
public enum FrameLengthType public enum FrameLengthType
{ {

View File

@ -172,37 +172,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
if (DeterministicEmulation) if (DeterministicEmulation)
{ {
int[] rtcRegs = new int[11]; ulong dividers = _syncSettings.InitialTime * (0x400000UL + (ulong)_syncSettings.RTCDivisorOffset) / 2UL;
rtcRegs[(int)LibGambatte.RtcRegIndices.Dh] = 0; LibGambatte.gambatte_settime(GambatteState, dividers);
if (_syncSettings.InternalRTCOverflow)
{
rtcRegs[(int)LibGambatte.RtcRegIndices.Dh] |= 0x80;
}
if (_syncSettings.InternalRTCHalt)
{
rtcRegs[(int)LibGambatte.RtcRegIndices.Dh] |= 0x40;
}
rtcRegs[(int)LibGambatte.RtcRegIndices.Dh] |= _syncSettings.InternalRTCDays >> 8;
rtcRegs[(int)LibGambatte.RtcRegIndices.Dl] = _syncSettings.InternalRTCDays & 0xFF;
rtcRegs[(int)LibGambatte.RtcRegIndices.H] = (_syncSettings.InternalRTCHours < 0) ? (_syncSettings.InternalRTCHours + 0x20) : _syncSettings.InternalRTCHours;
rtcRegs[(int)LibGambatte.RtcRegIndices.M] = (_syncSettings.InternalRTCMinutes < 0) ? (_syncSettings.InternalRTCMinutes + 0x40) : _syncSettings.InternalRTCMinutes;
rtcRegs[(int)LibGambatte.RtcRegIndices.S] = (_syncSettings.InternalRTCSeconds < 0) ? (_syncSettings.InternalRTCSeconds + 0x40) : _syncSettings.InternalRTCSeconds;
rtcRegs[(int)LibGambatte.RtcRegIndices.C] = _syncSettings.InternalRTCCycles;
rtcRegs[(int)LibGambatte.RtcRegIndices.Dh_L] = 0;
if (_syncSettings.LatchedRTCOverflow)
{
rtcRegs[(int)LibGambatte.RtcRegIndices.Dh_L] |= 0x80;
}
if (_syncSettings.LatchedRTCHalt)
{
rtcRegs[(int)LibGambatte.RtcRegIndices.Dh_L] |= 0x40;
}
rtcRegs[(int)LibGambatte.RtcRegIndices.Dh_L] |= _syncSettings.LatchedRTCDays >> 8;
rtcRegs[(int)LibGambatte.RtcRegIndices.Dl_L] = _syncSettings.LatchedRTCDays & 0xFF;
rtcRegs[(int)LibGambatte.RtcRegIndices.H_L] = _syncSettings.LatchedRTCHours;
rtcRegs[(int)LibGambatte.RtcRegIndices.M_L] = _syncSettings.LatchedRTCMinutes;
rtcRegs[(int)LibGambatte.RtcRegIndices.S_L] = _syncSettings.LatchedRTCSeconds;
LibGambatte.gambatte_setrtcregs(GambatteState, rtcRegs);
} }
LibGambatte.gambatte_setrtcdivisoroffset(GambatteState, _syncSettings.RTCDivisorOffset); LibGambatte.gambatte_setrtcdivisoroffset(GambatteState, _syncSettings.RTCDivisorOffset);

View File

@ -340,27 +340,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
/// </summary> /// </summary>
/// <param name="core">opaque state pointer</param> /// <param name="core">opaque state pointer</param>
/// <param name="dest">byte buffer to write into. gambatte_savesavedatalength() bytes will be written</param> /// <param name="dest">byte buffer to write into. gambatte_savesavedatalength() bytes will be written</param>
/// <param name="isDeterministic">determinism bool. RTC data is ignored if set </param>
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)] [DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_savesavedata(IntPtr core, byte[] dest, bool isDeterministic); public static extern void gambatte_savesavedata(IntPtr core, byte[] dest);
/// <summary> /// <summary>
/// restore persistant cart memory. /// restore persistant cart memory.
/// </summary> /// </summary>
/// <param name="core">opaque state pointer</param> /// <param name="core">opaque state pointer</param>
/// <param name="data">byte buffer to read from. gambatte_savesavedatalength() bytes will be read</param> /// <param name="data">byte buffer to read from. gambatte_savesavedatalength() bytes will be read</param>
/// <param name="isDeterministic">determinism bool. RTC data is ignored if set </param>
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)] [DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_loadsavedata(IntPtr core, byte[] data, bool isDeterministic); public static extern void gambatte_loadsavedata(IntPtr core, byte[] data);
/// <summary> /// <summary>
/// get the size of the persistant cart memory block. this value DEPENDS ON THE PARTICULAR CART LOADED /// get the size of the persistant cart memory block. this value DEPENDS ON THE PARTICULAR CART LOADED
/// </summary> /// </summary>
/// <param name="core">opaque state pointer</param> /// <param name="core">opaque state pointer</param>
/// <param name="isDeterministic">determinism bool. RTC data is ignored if set </param>
/// <returns>length in bytes. 0 means no internal persistant cart memory</returns> /// <returns>length in bytes. 0 means no internal persistant cart memory</returns>
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)] [DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_savesavedatalength(IntPtr core, bool isDeterministic); public static extern int gambatte_getsavedatalength(IntPtr core);
/// <summary> /// <summary>
/// new savestate method /// new savestate method
@ -555,24 +552,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
} }
/// <summary> /// <summary>
/// get MBC3 RTC reg values /// set time in dividers (2^21/sec)
/// </summary> /// </summary>
/// <param name="core">opaque state pointer</param> /// <param name="core">opaque state pointer</param>
/// <param name="dest">length of at least 11, please</param> /// <param name="dividers">time in dividers</param>
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)] [DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_getrtcregs(IntPtr core, int[] dest); public static extern void gambatte_settime(IntPtr core, ulong dividers);
/// <summary>
/// set MBC3 RTC reg values
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="src">length of at least 11, please</param>
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_setrtcregs(IntPtr core, int[] src);
public enum RtcRegIndices : int
{
Dh, Dl, H, M, S, C, Dh_L, Dl_L, H_L, M_L, S_L
}
} }
} }

@ -1 +1 @@
Subproject commit 08e3ed73f45c2902157b2eba3030fcf007e7947c Subproject commit fe395de27ee371bed3482e63c9a5536061df9d5d