fix some assorted bugs, and experiments with handling more environment calls

This commit is contained in:
zeromus 2015-11-07 02:29:04 -06:00
parent 7651f418fe
commit 5c16f8b107
5 changed files with 110 additions and 37 deletions

View File

@ -32,6 +32,11 @@ namespace BizHawk.Client.Common
return PathManager.SaveRamPath(Global.Game);
}
public string GetGameBasePath()
{
return PathManager.GetGameBasePath(Global.Game);
}
#region EmuLoadHelper api
private void FirmwareWarn(string sysID, string firmwareID, bool required, string msg = null)

View File

@ -259,9 +259,6 @@ namespace BizHawk.Client.Common
var filesystemSafeName = game.Name.Replace("|", "+");
// zero 06-nov-2015 - regarding the below, i changed my mind. for libretro i want subdirectories here.
//var parts = filesystemSafeName.Split(System.IO.Path.PathSeparator);
//var dirParts = new string[parts.Length - 1];
//Array.Copy(parts, dirParts, dirParts.Length);
var filesystemDir = Path.GetDirectoryName(filesystemSafeName);
filesystemSafeName = Path.GetFileName(filesystemSafeName);
@ -295,6 +292,14 @@ namespace BizHawk.Client.Common
return Path.Combine(MakeAbsolutePath(pathEntry.Path, game.System), name) + ".SaveRAM";
}
public static string GetGameBasePath(GameInfo game)
{
var name = FilesystemSafeName(game);
var pathEntry = Global.Config.PathEntries[game.System, "Base"];
return MakeAbsolutePath(pathEntry.Path, game.System);
}
public static string GetSaveStatePath(GameInfo game)
{
var pathEntry = Global.Config.PathEntries[game.System, "Savestates"] ??

View File

@ -181,6 +181,35 @@ namespace BizHawk.Client.Common
public bool AsLibretro;
bool HandleArchiveBinding(HawkFile file)
{
var romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", "V64", "N64", "WS", "WSC", "GBA" };
// try binding normal rom extensions first
if (!file.IsBound)
{
file.BindSoleItemOf(romExtensions);
}
// if we have an archive and need to bind something, then pop the dialog
if (file.IsArchive && !file.IsBound)
{
int? result = HandleArchive(file);
if (result.HasValue)
{
file.BindArchiveMember(result.Value);
}
else
{
return false;
}
}
CanonicalFullPath = file.CanonicalFullPath;
return true;
}
public bool LoadRom(string path, CoreComm nextComm, bool forceAccurateCore = false,
int recursiveCount = 0) // forceAccurateCore is currently just for Quicknes vs Neshawk but could be used for other situations
{
@ -199,7 +228,6 @@ namespace BizHawk.Client.Common
using (var file = new HawkFile())
{
var romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", "V64", "N64", "WS", "WSC", "GBA" };
//only try mounting a file if a filename was given
if (!string.IsNullOrEmpty(path))
@ -213,31 +241,10 @@ namespace BizHawk.Client.Common
{
return false;
}
// try binding normal rom extensions first
if (!file.IsBound)
{
file.BindSoleItemOf(romExtensions);
}
// if we have an archive and need to bind something, then pop the dialog
if (file.IsArchive && !file.IsBound)
{
int? result = HandleArchive(file);
if (result.HasValue)
{
file.BindArchiveMember(result.Value);
}
else
{
return false;
}
}
// set this here so we can see what file we tried to load even if an error occurs
CanonicalFullPath = file.CanonicalFullPath;
}
CanonicalFullPath = file.CanonicalFullPath;
IEmulator nextEmulator = null;
RomGame rom = null;
GameInfo game = null;
@ -291,7 +298,11 @@ namespace BizHawk.Client.Common
if (retro.system_info.need_fullpath)
ret = retro.LoadPath(file.FullPathWithoutMember);
else
ret = retro.LoadData(file.ReadAllBytes());
{
ret = HandleArchiveBinding(file);
if (ret)
ret = retro.LoadData(file.ReadAllBytes());
}
if (!ret)
{
@ -311,8 +322,14 @@ namespace BizHawk.Client.Common
}
else
{
//if not libretro, do extension checknig
//if not libretro:
//do extension checknig
ext = file.Extension.ToLowerInvariant();
//do the archive binding we had to skip
if (!HandleArchiveBinding(file))
return false;
}
if (string.IsNullOrEmpty(ext)) { }

View File

@ -22,6 +22,8 @@ namespace BizHawk.Emulation.Common
/// </summary>
string GetSaveRAMPath();
string GetGameBasePath();
#region EmuLoadHelper api

View File

@ -92,6 +92,7 @@ namespace BizHawk.Emulation.Cores
unsafe bool retro_environment(LibRetro.RETRO_ENVIRONMENT cmd, IntPtr data)
{
Console.WriteLine(cmd);
switch (cmd)
{
case LibRetro.RETRO_ENVIRONMENT.SET_ROTATION:
@ -113,6 +114,9 @@ namespace BizHawk.Emulation.Cores
case LibRetro.RETRO_ENVIRONMENT.SET_PERFORMANCE_LEVEL:
return false;
case LibRetro.RETRO_ENVIRONMENT.GET_SYSTEM_DIRECTORY:
//an alternative (alongside where the saverams and such will go?)
//*((IntPtr*)data.ToPointer()) = unmanagedResources.StringToHGlobalAnsi(CoreComm.CoreFileProvider.GetGameBasePath());
*((IntPtr*)data.ToPointer()) = SystemDirectoryAtom;
return false;
case LibRetro.RETRO_ENVIRONMENT.SET_PIXEL_FORMAT:
{
@ -143,8 +147,28 @@ namespace BizHawk.Emulation.Cores
// this can be done in principle, but there's no reason to right now
return false;
case LibRetro.RETRO_ENVIRONMENT.GET_VARIABLE:
{
void** variables = (void**)data.ToPointer();
IntPtr pKey = new IntPtr(*variables++);
string key = Marshal.PtrToStringAnsi(pKey);
Console.WriteLine("Requesting variable: {0}", key);
*variables = unmanagedResources.StringToHGlobalAnsi("0").ToPointer();
}
return false;
case LibRetro.RETRO_ENVIRONMENT.SET_VARIABLES:
{
void** variables = (void**)data.ToPointer();
for (; ; )
{
IntPtr pKey = new IntPtr(*variables++);
IntPtr pValue = new IntPtr(*variables++);
if(pKey == IntPtr.Zero)
break;
string key = Marshal.PtrToStringAnsi(pKey);
string value = Marshal.PtrToStringAnsi(pValue);
Console.WriteLine("Defined variable: {0} = {1}", key, value);
}
}
return false;
case LibRetro.RETRO_ENVIRONMENT.GET_VARIABLE_UPDATE:
return false;
@ -174,6 +198,8 @@ namespace BizHawk.Emulation.Cores
//unmanagedResources and CoreFileProvider
*((IntPtr*)data.ToPointer()) = IntPtr.Zero;
return false;
case LibRetro.RETRO_ENVIRONMENT.SET_CONTROLLER_INFO:
return true;
default:
Console.WriteLine("Unknkown retro_environment command {0}", (int)cmd);
return false;
@ -253,9 +279,16 @@ namespace BizHawk.Emulation.Cores
}
public RetroEnvironmentInfo EnvironmentInfo = new RetroEnvironmentInfo();
string CoresDirectory;
string SystemDirectory;
IntPtr SystemDirectoryAtom;
public LibRetroEmulator(CoreComm nextComm, string modulename)
{
CoresDirectory = Path.GetDirectoryName(new FileInfo(modulename).FullName);
SystemDirectory = Path.Combine(CoresDirectory, "System");
SystemDirectoryAtom = unmanagedResources.StringToHGlobalAnsi(SystemDirectory);
ServiceProvider = new BasicServiceProvider(this);
_SyncSettings = new SyncSettings();
@ -371,7 +404,6 @@ namespace BizHawk.Emulation.Cores
public void FrameAdvance(bool render, bool rendersound = true)
{
//TODO - consider changing directory and using Libretro subdir of bizhawk as a kind of sandbox, for the duration of the run?
CloneSaveRam();
IsLagFrame = true;
Frame++;
nsamprecv = 0;
@ -476,11 +508,16 @@ namespace BizHawk.Emulation.Cores
public void SaveStateBinary(System.IO.BinaryWriter writer)
{
fixed (byte* ptr = &savebuff[0])
//is this the only way we know of to detect unavailable savestates?
if (savebuff.Length > 0)
{
if (!retro.retro_serialize((IntPtr)ptr, (uint)savebuff.Length))
throw new Exception("retro_serialize() failed");
fixed (byte* ptr = &savebuff[0])
{
if (!retro.retro_serialize((IntPtr)ptr, (uint)savebuff.Length))
throw new Exception("retro_serialize() failed");
}
}
writer.Write(savebuff.Length);
writer.Write(savebuff);
// other variables
@ -495,10 +532,13 @@ namespace BizHawk.Emulation.Cores
if (newlen > savebuff.Length)
throw new Exception("Unexpected buffer size");
reader.Read(savebuff, 0, newlen);
fixed (byte* ptr = &savebuff[0])
if (savebuff.Length > 0)
{
if (!retro.retro_unserialize((IntPtr)ptr, (uint)newlen))
throw new Exception("retro_unserialize() failed");
fixed (byte* ptr = &savebuff[0])
{
if (!retro.retro_unserialize((IntPtr)ptr, (uint)newlen))
throw new Exception("retro_unserialize() failed");
}
}
// other variables
Frame = reader.ReadInt32();
@ -699,7 +739,9 @@ namespace BizHawk.Emulation.Cores
{
get
{
if (dar > 1.0f)
if(dar==0)
return BufferWidth;
else if (dar > 1.0f)
return (int)(BufferHeight * dar);
else
return BufferWidth;
@ -709,6 +751,8 @@ namespace BizHawk.Emulation.Cores
{
get
{
if(dar==0)
return BufferHeight;
if (dar < 1.0f)
return (int)(BufferWidth / dar);
else