2015-11-06 14:31:50 +00:00
using System ;
using System.Text ;
using System.IO ;
using System.Collections.Generic ;
using BizHawk.Emulation.Cores ;
using Newtonsoft.Json ;
//this file contains some cumbersome self-"serialization" in order to gain a modicum of control over what the serialized output looks like
//I don't want them to look like crufty json
2018-12-22 18:40:30 +00:00
namespace BizHawk.Client.Common
2015-11-06 14:31:50 +00:00
{
public interface IOpenAdvanced
{
string TypeName { get ; }
string DisplayName { get ; }
/// <summary>
/// returns a sole path to use for opening a rom (not sure if this is a good idea)
/// </summary>
string SimplePath { get ; }
void Deserialize ( string str ) ;
void Serialize ( TextWriter tw ) ;
}
public interface IOpenAdvancedLibretro
{
string CorePath { get ; set ; }
}
public static class OpenAdvancedTypes
{
public const string OpenRom = "OpenRom" ;
public const string Libretro = "Libretro" ;
public const string LibretroNoGame = "LibretroNoGame" ;
2019-10-29 15:37:27 +00:00
public const string MAME = "MAME" ;
2015-11-06 14:31:50 +00:00
}
public class OpenAdvancedSerializer
{
public static IOpenAdvanced ParseWithLegacy ( string text )
{
if ( text . StartsWith ( "*" ) )
return Deserialize ( text . Substring ( 1 ) ) ;
else return new OpenAdvanced_OpenRom { Path = text } ;
}
private static IOpenAdvanced Deserialize ( string text )
{
int idx = text . IndexOf ( '*' ) ;
string type = text . Substring ( 0 , idx ) ;
string token = text . Substring ( idx + 1 ) ;
IOpenAdvanced ioa ;
2019-10-29 15:37:27 +00:00
2019-11-04 01:55:38 +00:00
if ( type = = OpenAdvancedTypes . OpenRom )
{
ioa = new OpenAdvanced_OpenRom ( ) ;
2019-10-29 15:37:27 +00:00
}
2019-11-04 01:55:38 +00:00
else if ( type = = OpenAdvancedTypes . Libretro )
{
ioa = new OpenAdvanced_Libretro ( ) ;
2019-10-29 15:37:27 +00:00
}
2019-11-04 01:55:38 +00:00
else if ( type = = OpenAdvancedTypes . LibretroNoGame )
{
ioa = new OpenAdvanced_LibretroNoGame ( ) ;
2019-10-29 15:37:27 +00:00
}
2019-11-04 01:55:38 +00:00
else if ( type = = OpenAdvancedTypes . MAME )
{
ioa = new OpenAdvanced_MAME ( ) ;
2019-10-29 15:37:27 +00:00
}
2019-11-04 01:55:38 +00:00
else
{
ioa = null ;
2019-10-29 15:37:27 +00:00
}
2019-11-04 01:55:38 +00:00
if ( ioa = = null )
2019-10-29 15:37:27 +00:00
{
2019-11-04 01:55:38 +00:00
throw new InvalidOperationException ( $"{nameof(IOpenAdvanced)} deserialization error" ) ;
2019-10-29 15:37:27 +00:00
}
2015-11-06 14:31:50 +00:00
ioa . Deserialize ( token ) ;
return ioa ;
}
public static string Serialize ( IOpenAdvanced ioa )
{
StringWriter sw = new StringWriter ( ) ;
sw . Write ( "{0}*" , ioa . TypeName ) ;
ioa . Serialize ( sw ) ;
return sw . ToString ( ) ;
}
}
2018-12-22 18:40:30 +00:00
public class OpenAdvanced_Libretro : IOpenAdvanced , IOpenAdvancedLibretro
2015-11-06 14:31:50 +00:00
{
public OpenAdvanced_Libretro ( )
{
}
public struct Token
{
public string Path , CorePath ;
}
public Token token = new Token ( ) ;
public string TypeName { get { return "Libretro" ; } }
2019-12-06 18:34:20 +00:00
public string DisplayName { get { return $"{Path.GetFileNameWithoutExtension(token.CorePath)}: {token.Path}" ; } }
2015-11-06 14:31:50 +00:00
public string SimplePath { get { return token . Path ; } }
public void Deserialize ( string str )
{
token = JsonConvert . DeserializeObject < Token > ( str ) ;
}
public void Serialize ( TextWriter tw )
{
tw . Write ( JsonConvert . SerializeObject ( token ) ) ;
}
2020-01-25 04:53:45 +00:00
public string CorePath
{
get = > token . CorePath ;
set = > token . CorePath = value ;
}
2015-11-06 14:31:50 +00:00
}
2018-12-22 18:40:30 +00:00
public class OpenAdvanced_LibretroNoGame : IOpenAdvanced , IOpenAdvancedLibretro
2015-11-06 14:31:50 +00:00
{
//you might think ideally we'd fetch the libretro core name from the core info inside it
//but that would involve spinning up excess libretro core instances, which probably isnt good for stability, no matter how much we wish otherwise, not to mention slow.
//moreover it's kind of complicated here,
//and finally, I think the Displayname should really be file-based in all cases, since the user is going to be loading cores by filename and
//this is related to the recent roms filename management.
//so, leave it.
public OpenAdvanced_LibretroNoGame ( )
{
}
public OpenAdvanced_LibretroNoGame ( string corepath )
{
_corePath = corepath ;
}
string _corePath ;
public string TypeName { get { return "LibretroNoGame" ; } }
public string DisplayName { get { return Path . GetFileName ( _corePath ) ; } } //assume we like the filename of the core
public string SimplePath { get { return "" ; } } //effectively a signal to not use a game
public void Deserialize ( string str )
{
_corePath = str ;
}
public void Serialize ( TextWriter tw )
{
tw . Write ( _corePath ) ;
}
2020-01-25 04:53:45 +00:00
public string CorePath
{
get = > _corePath ;
set = > _corePath = value ;
}
2015-11-06 14:31:50 +00:00
}
2018-12-22 18:40:30 +00:00
public class OpenAdvanced_OpenRom : IOpenAdvanced
2015-11-06 14:31:50 +00:00
{
public OpenAdvanced_OpenRom ( )
{ }
public string Path ;
public string TypeName { get { return "OpenRom" ; } }
public string DisplayName { get { return Path ; } }
public string SimplePath { get { return Path ; } }
public void Deserialize ( string str )
{
Path = str ;
}
public void Serialize ( TextWriter tw )
{
tw . Write ( Path ) ;
}
}
2019-10-29 15:37:27 +00:00
public class OpenAdvanced_MAME : IOpenAdvanced
{
public OpenAdvanced_MAME ( )
{ }
public string Path ;
public string TypeName { get { return "MAME" ; } }
2019-12-06 18:34:20 +00:00
public string DisplayName { get { return $"{TypeName}: {Path}" ; } }
2019-10-29 15:37:27 +00:00
public string SimplePath { get { return Path ; } }
public void Deserialize ( string str )
{
Path = str ;
}
public void Serialize ( TextWriter tw )
{
tw . Write ( Path ) ;
}
}
2015-11-06 14:31:50 +00:00
}