mame
- put system and game names to emuhawk caption - fix loading from recent menu - temp fix for audio drift
This commit is contained in:
parent
16136ae130
commit
b5db6a7df6
|
@ -164,6 +164,8 @@ namespace BizHawk.Client.Common
|
|||
return SystemInfo.ChannelF;
|
||||
case "O2":
|
||||
return SystemInfo.O2;
|
||||
case "MAME":
|
||||
return SystemInfo.MAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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)}";
|
||||
|
|
|
@ -127,7 +127,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
SuggestedExtensionFilter = filter;
|
||||
|
||||
Result = AdvancedRomLoaderType.LibretroLaunchGame;
|
||||
DialogResult = DialogResult.OK;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
|
|
|
@ -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()";
|
||||
|
|
Loading…
Reference in New Issue