diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 16266356cc..cdfa8efd4d 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -384,12 +384,6 @@ RewindConfig.cs - - Form - - - SaturnPrefs.cs - Form @@ -1091,9 +1085,6 @@ RewindConfig.cs - - SaturnPrefs.cs - SMSGraphicsConfig.cs @@ -1594,7 +1585,9 @@ true - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BizHawk.Common/BizHawk.Common.csproj b/BizHawk.Common/BizHawk.Common.csproj index db789947dd..2c22064973 100644 --- a/BizHawk.Common/BizHawk.Common.csproj +++ b/BizHawk.Common/BizHawk.Common.csproj @@ -65,6 +65,7 @@ + diff --git a/BizHawk.Common/SettingsUtil.cs b/BizHawk.Common/SettingsUtil.cs new file mode 100644 index 0000000000..f7fcb31354 --- /dev/null +++ b/BizHawk.Common/SettingsUtil.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection; +using System.Reflection.Emit; +using System.Collections.Concurrent; +using System.ComponentModel; + +namespace BizHawk.Common +{ + public class SettingsUtil + { + private class DefaultValueSetter + { + public Action SetDefaultValues; + public Type Type; + public object[] DefaultValues; + } + + + private static IDictionary DefaultValueSetters = new ConcurrentDictionary(); + + public static void SetDefaultValues(T obj) + { + DefaultValueSetter f; + if (!DefaultValueSetters.TryGetValue(typeof(T), out f)) + { + f = CreateSetter(typeof(T)); + DefaultValueSetters[typeof(T)] = f; + } + f.SetDefaultValues(obj, f.DefaultValues); + } + + private static DefaultValueSetter CreateSetter(Type t) + { + //var dyn = new DynamicMethod("SetDefaultValues_" + t.Name, null, new[] { t }, true); + var dyn = new DynamicMethod("SetDefaultValues_" + t.Name, null, new[] { typeof(object), typeof(object[]) }, false); + var il = dyn.GetILGenerator(); + List DefaultValues = new List(); + + il.Emit(OpCodes.Ldarg_0); // arg0: object to set properties of + il.Emit(OpCodes.Castclass, t); // cast to appropriate type + + foreach (var prop in t.GetProperties()) + { + if (!prop.CanWrite) + continue; + MethodInfo method = prop.GetSetMethod(true); + foreach (object attr in prop.GetCustomAttributes(true)) + { + if (attr is DefaultValueAttribute) + { + object value = (attr as DefaultValueAttribute).Value; + Type desiredType = method.GetParameters()[0].ParameterType; + + if (!desiredType.IsAssignableFrom(value.GetType())) + throw new InvalidOperationException(string.Format("Default value assignment will fail for {0}.{1}", t.Name, prop.Name)); + + int idx = DefaultValues.Count; + DefaultValues.Add(value); + + il.Emit(OpCodes.Dup); // object to act on + il.Emit(OpCodes.Ldarg_1); // arg1: array of default values + il.Emit(OpCodes.Ldc_I4, idx); // load index + il.Emit(OpCodes.Ldelem, typeof(object)); // get default value at appropriate index + il.Emit(OpCodes.Unbox_Any, desiredType); // cast to expected type of set method + il.Emit(OpCodes.Callvirt, method); + } + } + } + il.Emit(OpCodes.Pop); + il.Emit(OpCodes.Ret); + return new DefaultValueSetter + { + SetDefaultValues = (Action)dyn.CreateDelegate(typeof(Action)), + Type = t, + DefaultValues = DefaultValues.ToArray() + }; + } + } +} diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs index 42bc7f49b1..f3e70e1b44 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/LibYabause.cs @@ -177,9 +177,12 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn /// cd interface. struct need not persist after call, but the function pointers better /// path to bios, pass null to use built in bios emulation /// true for opengl + /// if true, skip bios opening + /// if true, sync RTC to actual emulated time; if false, use real real time + /// if non-zero, initial emulation time in unix format /// [DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern bool libyabause_init(ref CDInterface intf, string biosfn, bool usegl, CartType carttype); + public static extern bool libyabause_init(ref CDInterface intf, string biosfn, bool usegl, CartType carttype, bool quickload, bool clocksync, int clockbase); public struct CDInterface { diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs index 08b49ab7ac..bb57cd3078 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs @@ -4,11 +4,14 @@ using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.IO; +using System.ComponentModel; using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.DiscSystem; +using Newtonsoft.Json; + namespace BizHawk.Emulation.Cores.Sega.Saturn { [CoreAttributes( @@ -88,7 +91,23 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn string BiosPipe = fp.GetPipeNameNative(); fp.Offer(bios); - if (!LibYabause.libyabause_init(ref CDInt, BiosPipe, GL, SyncSettings.CartType)) + int basetime; + if (SyncSettings.RealTimeRTC) + basetime = 0; + else + basetime = (int)((SyncSettings.RTCInitialTime - new DateTime(1970, 1, 1).ToLocalTime()).TotalSeconds); + + + if (!LibYabause.libyabause_init + ( + ref CDInt, + BiosPipe, + GL, + SyncSettings.CartType, + SyncSettings.SkipBios, + !SyncSettings.RealTimeRTC, + basetime + )) throw new Exception("libyabause_init() failed!"); fp.Finish(); @@ -664,21 +683,60 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn public class SaturnSyncSettings { - public bool UseGL = false; - public int DispFactor = 1; - public bool DispFree = false; - public int GLW = 640; - public int GLH = 480; - public LibYabause.CartType CartType = LibYabause.CartType.NONE; + [Description("Use OpenGL mode for rendering instead of software.")] + [DefaultValue(false)] + public bool UseGL { get; set; } + + [Description("In OpenGL mode, the internal resolution as a multiple of the normal internal resolution (1x, 2x, 3x, 4x). Ignored in software mode or when a custom resolution is used.")] + [DefaultValue(1)] + public int DispFactor { get { return _DispFactor; } set { _DispFactor = Math.Max(1, Math.Min(value, 4)); } } + [JsonIgnore] + private int _DispFactor; + + [Description("In OpenGL mode, set to true to use a custom resolution and ignore DispFactor.")] + [DefaultValue(false)] + public bool DispFree { get; set; } + + [Description("In OpenGL mode and when DispFree is true, the width of the final resolution.")] + [DefaultValue(640)] + public int GLW { get { return _GLW; } set { _GLW = Math.Max(320, Math.Min(value, 2048)); } } + [JsonIgnore] + private int _GLW; + + [Description("In OpenGL mode and when DispFree is true, the height of the final resolution.")] + [DefaultValue(480)] + public int GLH { get { return _GLH; } set { _GLH = Math.Max(224, Math.Min(value, 1024)); } } + [JsonIgnore] + private int _GLH; + + [Description("The type of the attached RAM cart. Most games will not use this.")] + [DefaultValue(LibYabause.CartType.NONE)] + public LibYabause.CartType CartType { get; set; } + + [Description("Skip the Bios Intro screen.")] + [DefaultValue(false)] + public bool SkipBios { get; set; } + + [Description("If true, the real time clock will reflect real time, instead of emulated time. Ignored (forced to false) when a movie is recording.")] + [DefaultValue(false)] + public bool RealTimeRTC { get; set; } + + [Description("Set the initial RTC time. Only used when RealTimeRTC is false.")] + [DefaultValue(typeof(DateTime), "2010-01-01")] + public DateTime RTCInitialTime { get; set; } public static bool NeedsReboot(SaturnSyncSettings x, SaturnSyncSettings y) { - return x.UseGL != y.UseGL || x.CartType != y.CartType; + return x.UseGL != y.UseGL || x.CartType != y.CartType || x.SkipBios != y.SkipBios || x.RealTimeRTC != y.RealTimeRTC || x.RTCInitialTime != y.RTCInitialTime; } public SaturnSyncSettings Clone() { return (SaturnSyncSettings)MemberwiseClone(); } + public SaturnSyncSettings() + { + SettingsUtil.SetDefaultValues(this); + } } } } diff --git a/output/dll/libyabause.dll b/output/dll/libyabause.dll index d42a61f75d..2375ac83ac 100644 Binary files a/output/dll/libyabause.dll and b/output/dll/libyabause.dll differ diff --git a/yabause/src/libyabause/libyabause.vcxproj b/yabause/src/libyabause/libyabause.vcxproj index 01ab131546..8862e819e6 100644 --- a/yabause/src/libyabause/libyabause.vcxproj +++ b/yabause/src/libyabause/libyabause.vcxproj @@ -57,6 +57,9 @@ true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) + + copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\..\output\dll\$(TargetFileName) + @@ -76,6 +79,9 @@ true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;%(AdditionalDependencies) + + copy /y $(TargetDir)$(TargetFileName) $(ProjectDir)..\..\..\output\dll\$(TargetFileName) + diff --git a/yabause/src/libyabause/yui.cpp b/yabause/src/libyabause/yui.cpp index 5c3c58c134..cdc1e163c1 100644 --- a/yabause/src/libyabause/yui.cpp +++ b/yabause/src/libyabause/yui.cpp @@ -507,7 +507,16 @@ void vdp2newhook(u16 v) } } -extern "C" __declspec(dllexport) int libyabause_init(CDInterface *_CD, const char *biosfn, int usegl, int carttype) +extern "C" __declspec(dllexport) int libyabause_init +( + CDInterface *_CD, + const char *biosfn, + int usegl, + int carttype, + int quickload, + int clocksync, + int clockbase +) { usinggl = usegl; if (usegl && (!StartGLContext() || !LoadExtensions())) @@ -547,6 +556,11 @@ extern "C" __declspec(dllexport) int libyabause_init(CDInterface *_CD, const cha yinit.carttype = carttype; yinit.netlinksetting = NULL; yinit.videoformattype = VIDEOFORMATTYPE_NTSC; + yabsys.usequickload = quickload; + yinit.usethreads = 0; + yinit.frameskip = 0; + yinit.clocksync = clocksync; + yinit.basetime = clockbase; // same format as return from time(); 0 to use time() if (usegl && !vdp2hookfcn) { diff --git a/yabause/src/yabause.c b/yabause/src/yabause.c index cac4986b40..c662895084 100644 --- a/yabause/src/yabause.c +++ b/yabause/src/yabause.c @@ -250,7 +250,7 @@ int YabauseInit(yabauseinit_struct *init) else yabsys.emulatebios = 1; - yabsys.usequickload = 0; + //yabsys.usequickload = 0; #if defined(SH2_DYNAREC) if(SH2Core->id==2) {