Retype IMovie.TimeLength to TimeSpan; cleanup frame rate code (#2206)

* Retype IMovie.TimeLength to TimeSpan; cleanup frame rate code

* More concise IsPal field.
This commit is contained in:
RetroEdit 2020-07-06 21:24:04 +00:00 committed by GitHub
parent f52b02d499
commit 9cdf0abc0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 84 deletions

View File

@ -38,6 +38,9 @@ namespace BizHawk.Client.Common
["WSWAN"] = (3072000.0 / (159 * 256)), // 75.4716981132
["GB"] = 262144.0 / 4389.0, // 59.7275005696
["GBC"] = 262144.0 / 4389.0, // 59.7275005696
// RetroEdit: I don't like how this is cycles per second instead of FPS.
// It probably should be moved to a separate place.
["GB_Clock"] = 2097152.0,
["GBA"] = 262144.0 / 4389.0, // 59.7275005696
["GEN"] = 53693175 / (3420.0 * 262),
@ -70,51 +73,10 @@ namespace BizHawk.Client.Common
["AmstradCPC_PAL"] = 50.08012820512821,
};
public double this[string systemId, bool pal]
public static double GetFrameRate(string systemId, bool pal)
{
get
{
var key = systemId + (pal ? "_PAL" : "");
return Rates.ContainsKey(key) ? Rates[key] : 60.0;
}
}
public TimeSpan MovieTime(IMovie movie)
{
var dblSeconds = GetSeconds(movie);
var seconds = (int)(dblSeconds % 60);
var days = seconds / 86400;
var hours = seconds / 3600;
var minutes = (seconds / 60) % 60;
var milliseconds = (int)((dblSeconds - seconds) * 1000);
return new TimeSpan(days, hours, minutes, seconds, milliseconds);
}
private double Fps(IMovie movie)
{
var system = movie.HeaderEntries[HeaderKeys.Platform];
var core = movie.HeaderEntries[HeaderKeys.Core];
var pal = movie.HeaderEntries.ContainsKey(HeaderKeys.Pal)
&& movie.HeaderEntries[HeaderKeys.Pal] == "1";
if (movie.HeaderEntries.ContainsKey(HeaderKeys.CycleCount) && ((core == "Gambatte") || (core == "SubGBHawk")))
{
system = "GB_Clock";
}
return this[system, pal];
}
private double GetSeconds(IMovie movie)
{
double frames = movie.TimeLength;
if (frames < 1)
{
return 0;
}
return frames / Fps(movie);
var key = systemId + (pal ? "_PAL" : "");
return Rates.ContainsKey(key) ? Rates[key] : 60.0;
}
}
}

View File

@ -216,6 +216,8 @@ namespace BizHawk.Client.Common
return sb.ToString();
}
public bool IsPal => Header.ContainsKey(HeaderKeys.Pal) && Header[HeaderKeys.Pal] == "1";
public string TextSavestate { get; set; }
public byte[] BinarySavestate { get; set; }
public int[] SavestateFramebuffer { get; set; }

View File

@ -70,26 +70,44 @@ namespace BizHawk.Client.Common
public int FrameCount => Log.Count;
public int InputLogLength => Log.Count;
public ulong TimeLength
public TimeSpan TimeLength
{
get
{
if (Header.ContainsKey(HeaderKeys.VBlankCount))
double dblSeconds;
var core = Header[HeaderKeys.Core];
if (Header.ContainsKey(HeaderKeys.CycleCount) && (core == CoreNames.Gambatte || core == CoreNames.SubGbHawk))
{
return Convert.ToUInt64(Header[HeaderKeys.VBlankCount]);
ulong numCycles = Convert.ToUInt64(Header[HeaderKeys.CycleCount]);
double cyclesPerSecond = PlatformFrameRates.GetFrameRate("GB_Clock", IsPal);
dblSeconds = numCycles / cyclesPerSecond;
}
else
{
ulong numFrames = (ulong) FrameCount;
if (Header.ContainsKey(HeaderKeys.VBlankCount))
{
numFrames = Convert.ToUInt64(Header[HeaderKeys.VBlankCount]);
}
dblSeconds = numFrames / FrameRate;
}
if (Header.ContainsKey(HeaderKeys.CycleCount) && Header[HeaderKeys.Core] == CoreNames.Gambatte)
{
return Convert.ToUInt64(Header[HeaderKeys.CycleCount]);
}
var seconds = (int)(dblSeconds % 60);
var days = seconds / 86400;
var hours = seconds / 3600;
var minutes = (seconds / 60) % 60;
var milliseconds = (int)((dblSeconds - seconds) * 1000);
return new TimeSpan(days, hours, minutes, seconds, milliseconds);
}
}
if (Header.ContainsKey(HeaderKeys.CycleCount) && Header[HeaderKeys.Core] == CoreNames.SubGbHawk)
{
return Convert.ToUInt64(Header[HeaderKeys.CycleCount]);
}
return (ulong)Log.Count;
public double FrameRate
{
get
{
var system = HeaderEntries[HeaderKeys.Platform];
return PlatformFrameRates.GetFrameRate(system, IsPal);
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using BizHawk.Emulation.Common;
@ -56,7 +57,12 @@ namespace BizHawk.Client.Common
/// <summary>
/// Gets the actual length of time a movie lasts for. For subframe cores, this will be different then the above two options
/// </summary>
ulong TimeLength { get; }
TimeSpan TimeLength { get; }
/// <summary>
/// Gets the frame rate in frames per second for the movie's system.
/// </summary>
double FrameRate { get; }
/// <summary>
/// Gets the file extension for the current <see cref="IMovie"/> implementation

View File

@ -114,15 +114,13 @@ namespace BizHawk.Client.EmuHawk
public double GetFps()
{
var movie = GlobalWin.MovieSession.Movie;
// Why does it need the movie to be active to know the frame rate?
if (movie.NotActive())
{
return default;
}
return new PlatformFrameRates()[
movie.HeaderEntries[HeaderKeys.Platform],
movie.HeaderEntries.TryGetValue(HeaderKeys.Pal, out var isPal) && isPal == "1"
];
return movie.FrameRate;
}
}
}

View File

@ -213,16 +213,11 @@ namespace BizHawk.Client.EmuHawk
return;
}
// Fetch fps
var system = _selectedMovie.HeaderEntries[HeaderKeys.Platform];
var pal = _selectedMovie.HeaderEntries.ContainsKey(HeaderKeys.Pal)
&& _selectedMovie.HeaderEntries[HeaderKeys.Pal] == "1";
var pfr = new PlatformFrameRates();
double fps;
try
{
fps = pfr[system, pal];
// RetroEdit: This cannot actually fail because it defaults to 60.0, so the try-catch block is pointless
fps = _selectedMovie.FrameRate;
}
catch
{

View File

@ -21,7 +21,6 @@ namespace BizHawk.Client.EmuHawk
private readonly GameInfo _game;
private readonly IEmulator _emulator;
private readonly IMovieSession _movieSession;
private readonly PlatformFrameRates _platformFrameRates = new PlatformFrameRates();
private List<IMovie> _movieList = new List<IMovie>();
private bool _sortReverse;
@ -71,7 +70,7 @@ namespace BizHawk.Client.EmuHawk
e.Item = new ListViewItem(entry.Filename);
e.Item.SubItems.Add(entry.SystemID);
e.Item.SubItems.Add(entry.GameName);
e.Item.SubItems.Add(_platformFrameRates.MovieTime(entry).ToString(@"hh\:mm\:ss\.fff"));
e.Item.SubItems.Add(entry.TimeLength.ToString(@"hh\:mm\:ss\.fff"));
}
private void Run()
@ -328,7 +327,7 @@ namespace BizHawk.Client.EmuHawk
.Append(_movieList[index].Filename).Append('\t')
.Append(_movieList[index].SystemID).Append('\t')
.Append(_movieList[index].GameName).Append('\t')
.Append(_platformFrameRates.MovieTime(_movieList[index]).ToString(@"hh\:mm\:ss\.fff"))
.Append(_movieList[index].TimeLength.ToString(@"hh\:mm\:ss\.fff"))
.AppendLine();
}
@ -444,7 +443,7 @@ namespace BizHawk.Client.EmuHawk
}
var fpsItem = new ListViewItem("Fps");
fpsItem.SubItems.Add($"{Fps(_movieList[firstIndex]):0.#######}");
fpsItem.SubItems.Add($"{_movieList[firstIndex].FrameRate:0.#######}");
DetailsView.Items.Add(fpsItem);
var framesItem = new ListViewItem("Frames");
@ -454,16 +453,6 @@ namespace BizHawk.Client.EmuHawk
SubtitlesBtn.Enabled = _movieList[firstIndex].Subtitles.Any();
}
public double Fps(IMovie movie)
{
var system = movie.HeaderEntries[HeaderKeys.Platform];
var pal = movie.HeaderEntries.ContainsKey(HeaderKeys.Pal)
&& movie.HeaderEntries[HeaderKeys.Pal] == "1";
return new PlatformFrameRates()[system, pal];
}
private void EditMenuItem_Click(object sender, EventArgs e)
{
foreach (var movie in MovieView.SelectedIndices.Cast<int>()