- put system and game names to emuhawk caption
- fix loading from recent menu
- temp fix for audio drift
This commit is contained in:
feos 2019-12-06 21:34:20 +03:00
parent 16136ae130
commit b5db6a7df6
7 changed files with 78 additions and 23 deletions

View File

@ -164,6 +164,8 @@ namespace BizHawk.Client.Common
return SystemInfo.ChannelF;
case "O2":
return SystemInfo.O2;
case "MAME":
return SystemInfo.MAME;
}
}
}

View File

@ -109,7 +109,7 @@ namespace BizHawk.Client.Common
public Token token = new Token();
public string TypeName { get { return "Libretro"; } }
public string DisplayName { get { return $"{Path.GetFileNameWithoutExtension(token.CorePath)}:{token.Path}"; } }
public string DisplayName { get { return $"{Path.GetFileNameWithoutExtension(token.CorePath)}: {token.Path}"; } }
public string SimplePath { get { return token.Path; } }
public void Deserialize(string str)
@ -192,7 +192,7 @@ namespace BizHawk.Client.Common
public string Path;
public string TypeName { get { return "MAME"; } }
public string DisplayName { get { return Path; } }
public string DisplayName { get { return $"{TypeName}: {Path}"; } }
public string SimplePath { get { return Path; } }
public void Deserialize(string str)

View File

@ -172,7 +172,7 @@ namespace BizHawk.Client.Common
return false;
}
public AdvancedRomLoaderType AdvancedLoader { get; set; }
public IOpenAdvanced OpenAdvanced { get; set; }
private bool HandleArchiveBinding(HawkFile file)
{
@ -271,7 +271,7 @@ namespace BizHawk.Client.Common
{
// MAME uses these extensions for arcade ROMs, but also accepts all sorts of variations of archives, folders, and files. if we let archive loader handle this, it won't know where to stop, since it'd require MAME's ROM database (which contains ROM names and blob hashes) to look things up, and even then it might be confused by archive/folder structure
// so assume the user provides the proper ROM directly, and handle possible errors later
if (AdvancedLoader == AdvancedRomLoaderType.MAMELaunchGame)
if (OpenAdvanced is OpenAdvanced_MAME)
{
file.NonArchiveExtensions = new[] { ".zip", ".7z" };
}
@ -295,7 +295,7 @@ namespace BizHawk.Client.Common
{
string ext = null;
if (AdvancedLoader == AdvancedRomLoaderType.LibretroLaunchGame)
if (OpenAdvanced is OpenAdvanced_Libretro)
{
string codePathPart = Path.GetFileNameWithoutExtension(nextComm.LaunchLibretroCore);
@ -1159,7 +1159,9 @@ namespace BizHawk.Client.Common
nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
break;
case "Arcade":
nextEmulator = new MAME(nextComm, file.Directory, file.CanonicalName);
string gameName = "";
nextEmulator = new MAME(nextComm, file.Directory, file.CanonicalName, out gameName);
rom.GameInfo.Name = gameName;
break;
case "GEN":
if (Global.Config.CoreForcingViaGameDB && game.ForcedCore?.ToLower() == "pico")

View File

@ -306,7 +306,6 @@ namespace BizHawk.Client.EmuHawk
private void OpenRomMenuItem_Click(object sender, EventArgs e)
{
AdvancedLoader = AdvancedRomLoaderType.None;
OpenRom();
}
@ -318,9 +317,7 @@ namespace BizHawk.Client.EmuHawk
return;
}
AdvancedLoader = oac.Result;
if (AdvancedLoader == AdvancedRomLoaderType.LibretroLaunchNoGame)
if (oac.Result == AdvancedRomLoaderType.LibretroLaunchNoGame)
{
var argsNoGame = new LoadRomArgs
{
@ -334,16 +331,16 @@ namespace BizHawk.Client.EmuHawk
var filter = RomFilter;
if (AdvancedLoader == AdvancedRomLoaderType.LibretroLaunchGame)
if (oac.Result == AdvancedRomLoaderType.LibretroLaunchGame)
{
args.OpenAdvanced = new OpenAdvanced_Libretro();
filter = oac.SuggestedExtensionFilter;
}
else if (AdvancedLoader == AdvancedRomLoaderType.ClassicLaunchGame)
else if (oac.Result == AdvancedRomLoaderType.ClassicLaunchGame)
{
args.OpenAdvanced = new OpenAdvanced_OpenRom();
}
else if (AdvancedLoader == AdvancedRomLoaderType.MAMELaunchGame)
else if (oac.Result == AdvancedRomLoaderType.MAMELaunchGame)
{
args.OpenAdvanced = new OpenAdvanced_MAME();
filter = "MAME Arcade ROMs (*.zip)|*.zip";

View File

@ -596,8 +596,6 @@ namespace BizHawk.Client.EmuHawk
// runloop won't exec lua
public bool SuppressLua { get; set; }
public AdvancedRomLoaderType AdvancedLoader { get; set; }
public long MouseWheelTracker { get; private set; }
private int? _pauseOnFrame;
@ -3530,7 +3528,7 @@ namespace BizHawk.Client.EmuHawk
ChoosePlatform = ChoosePlatformForRom,
Deterministic = deterministic,
MessageCallback = GlobalWin.OSD.AddMessage,
AdvancedLoader = AdvancedLoader
OpenAdvanced = args.OpenAdvanced
};
Global.FirmwareManager.RecentlyServed.Clear();
@ -3548,6 +3546,7 @@ namespace BizHawk.Client.EmuHawk
IOpenAdvanced ioa = args.OpenAdvanced;
var oa_openrom = ioa as OpenAdvanced_OpenRom;
var oa_mame = ioa as OpenAdvanced_MAME;
var oa_retro = ioa as OpenAdvanced_Libretro;
var ioa_retro = ioa as IOpenAdvancedLibretro;
@ -3591,6 +3590,11 @@ namespace BizHawk.Client.EmuHawk
oa_openrom.Path = loader.CanonicalFullPath;
}
if (oa_mame != null)
{
oa_mame.Path = loader.CanonicalFullPath;
}
if (result)
{
string openAdvancedArgs = $"*{OpenAdvancedSerializer.Serialize(ioa)}";

View File

@ -127,7 +127,7 @@ namespace BizHawk.Client.EmuHawk
SuggestedExtensionFilter = filter;
Result = AdvancedRomLoaderType.LibretroLaunchGame;
DialogResult = DialogResult.OK;
DialogResult = DialogResult.OK;
Close();
}

View File

@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
singleInstance: false)]
public partial class MAME : IEmulator, IVideoProvider, ISoundProvider
{
public MAME(CoreComm comm, string dir, string file)
public MAME(CoreComm comm, string dir, string file, out string gamename)
{
ServiceProvider = new BasicServiceProvider(this);
@ -29,6 +29,8 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
MAMEThread = new Thread(ExecuteMAMEThread);
AsyncLaunchMAME();
gamename = gameName;
}
#region Properties
@ -49,7 +51,6 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
public int BufferHeight { get; private set; } = 240;
public int VsyncNumerator { get; private set; } = 60;
public int VsyncDenominator { get; private set; } = 1;
private int samplesPerFrame => (int)Math.Round(sampleRate / this.VsyncRate());
#endregion
@ -61,8 +62,8 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
private SortedDictionary<string, string> fieldsPorts = new SortedDictionary<string, string>();
private IController Controller = NullController.Instance;
private int[] frameBuffer = new int[0];
private short[] audioBuffer = new short[0];
private Queue<short> audioSamples = new Queue<short>();
private decimal dAudioSamples = 0;
private int sampleRate = 44100;
private bool paused = true;
private bool exiting = false;
@ -70,6 +71,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
private int numSamples = 0;
private string gameDirectory;
private string gameFilename;
private string gameName = "Arcade";
private LibMAME.PeriodicCallbackDelegate periodicCallback;
private LibMAME.SoundCallbackDelegate soundCallback;
private LibMAME.BootCallbackDelegate bootCallback;
@ -123,12 +125,45 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
}
}
/*
* GetSamplesSync() and MAME
*
* MAME generates samples 50 times per second, regardless of the VBlank
* rate of the emulated machine. It then uses complicated logic to
* output the required amount of audio to the OS driver and to the AVI,
* where it's meant to tie flashed samples to video frame duration.
*
* I'm doing my own logic here for now. I grab MAME's audio buffer
* whenever it's filled (MAMESoundCallback()) and enqueue it.
*
* Whenever Hawk wants new audio, I dequeue it, but with a little quirk.
* Since sample count per frame may not align with frame duration, I
* subtract the entire decimal fraction of "required" samples from total
* samples. I check if the fractional reminder of total samples is > 0.5
* by rounding it. I invert it to see what number I should add to the
* integer representation of "required" samples, to compensate for
* misalignment between fractional and integral "required" samples.
*
* TODO: Figure out how MAME does this and maybe use their method instead.
*/
public void GetSamplesSync(out short[] samples, out int nsamp)
{
nsamp = samplesPerFrame;
samples = new short[samplesPerFrame * 2];
decimal dSamplesPerFrame = (decimal)sampleRate * VsyncDenominator / VsyncNumerator;
for (int i = 0; i < samplesPerFrame * 2; i++)
if (audioSamples.Any())
{
dAudioSamples -= dSamplesPerFrame;
int remainder = (int)Math.Round(dAudioSamples - Math.Truncate(dAudioSamples)) ^ 1;
nsamp = (int)Math.Round(dSamplesPerFrame) + remainder;
}
else
{
nsamp = (int)Math.Round(dSamplesPerFrame);
}
samples = new short[nsamp * 2];
for (int i = 0; i < nsamp * 2; i++)
{
if (audioSamples.Any())
{
@ -291,6 +326,18 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
$"MAMEHawk is { version }");
}
private void UpdateGameName()
{
int lengthInBytes;
IntPtr ptr = LibMAME.mame_lua_get_string(MAMELuaCommand.GetGameName, out lengthInBytes);
gameName = Marshal.PtrToStringAnsi(ptr, lengthInBytes);
if (!LibMAME.mame_lua_free_string(ptr))
{
Console.WriteLine("LibMAME ERROR: string buffer wasn't freed");
}
}
#endregion
#region Callbacks
@ -369,6 +416,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
for (int i = 0; i < numSamples; i++)
{
audioSamples.Enqueue(*(pSample + i));
dAudioSamples++;
}
}
@ -384,6 +432,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
CheckVersions();
GetInputFields();
Update();
UpdateGameName();
MAMEStartupComplete.Set();
}
@ -454,6 +503,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
public const string Unpause = "emu.unpause()";
public const string Exit = "manager:machine():exit()";
public const string GetVersion = "return emu.app_version()";
public const string GetGameName = "return manager:machine():system().description";
public const string GetPixels = "return manager:machine():video():pixels()";
public const string GetSamples = "return manager:machine():sound():samples()";
public const string GetFrameNumber = "return select(2, next(manager:machine().screens)):frame_number()";