C# changes for melonDS OpenGL support
also add in a way to debug OpenGL stuff (only built when uncommenting a define) also do various cleanup here
This commit is contained in:
parent
f71f2fafc6
commit
f63e50c91b
|
@ -1,5 +1,12 @@
|
|||
// #define DEBUG_OPENGL
|
||||
|
||||
using System;
|
||||
|
||||
#if DEBUG_OPENGL
|
||||
using System.Runtime.InteropServices;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
#endif
|
||||
|
||||
using static SDL2.SDL;
|
||||
|
||||
namespace BizHawk.Bizware.Graphics
|
||||
|
@ -42,6 +49,12 @@ namespace BizHawk.Bizware.Graphics
|
|||
SDL_SetHint(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, "0");
|
||||
}
|
||||
|
||||
#if DEBUG_OPENGL
|
||||
private static readonly DebugProc _debugProc = DebugCallback;
|
||||
private static void DebugCallback(GLEnum source, GLEnum type, int id, GLEnum severity, int length, IntPtr message, IntPtr userParam)
|
||||
=> Console.WriteLine($"{source} {type} {severity}: {Marshal.PtrToStringAnsi(message, length)}");
|
||||
#endif
|
||||
|
||||
private IntPtr _sdlWindow;
|
||||
private IntPtr _glContext;
|
||||
|
||||
|
@ -64,6 +77,13 @@ namespace BizHawk.Bizware.Graphics
|
|||
throw new($"Could not set GL Context Flags! SDL Error: {SDL_GetError()}");
|
||||
}
|
||||
|
||||
#if DEBUG_OPENGL
|
||||
if (SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_CONTEXT_FLAGS, (int)SDL_GLcontext.SDL_GL_CONTEXT_DEBUG_FLAG) != 0)
|
||||
{
|
||||
throw new($"Could not set GL Debug Flag! SDL Error: {SDL_GetError()}");
|
||||
}
|
||||
#endif
|
||||
|
||||
var profile = coreProfile
|
||||
? SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_CORE
|
||||
: SDL_GLprofile.SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
|
||||
|
@ -78,6 +98,17 @@ namespace BizHawk.Bizware.Graphics
|
|||
{
|
||||
throw new($"Could not create GL Context! SDL Error: {SDL_GetError()}");
|
||||
}
|
||||
|
||||
#if DEBUG_OPENGL
|
||||
if (GetGLProcAddress("glDebugMessageCallback") != IntPtr.Zero)
|
||||
{
|
||||
using var gl = GL.GetApi(GetGLProcAddress);
|
||||
unsafe
|
||||
{
|
||||
gl.DebugMessageCallback(_debugProc, null);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public SDL2OpenGLContext(IntPtr nativeWindowhandle, int majorVersion, int minorVersion, bool coreProfile, bool forwardCompatible)
|
||||
|
|
|
@ -58,6 +58,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
public bool DSi;
|
||||
public bool ClearNAND;
|
||||
public bool LoadDSiWare;
|
||||
public bool IsWinApi;
|
||||
public NDS.NDSSyncSettings.ThreeDeeRendererType ThreeDeeRenderer;
|
||||
public RenderSettings RenderSettings;
|
||||
}
|
||||
|
@ -168,21 +169,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
[UnmanagedFunctionPointer(CC)]
|
||||
public delegate IntPtr GetGLProcAddressCallback(string proc);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct GLCallbackInterface
|
||||
{
|
||||
public RequestGLContextCallback RequestGLContext;
|
||||
public ReleaseGLContextCallback ReleaseGLContext;
|
||||
public ActivateGLContextCallback ActivateGLContext;
|
||||
public GetGLProcAddressCallback GetGLProcAddress;
|
||||
|
||||
public IntPtr[] AllCallbacksInArray(ICallingConventionAdapter adapter)
|
||||
{
|
||||
return new Delegate[] { RequestGLContext, ReleaseGLContext, ActivateGLContext, GetGLProcAddress }
|
||||
.Select(adapter.GetFunctionPointerForDelegate).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public enum LogLevel : int
|
||||
{
|
||||
Debug,
|
||||
|
@ -197,10 +183,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
[BizImport(CC)]
|
||||
public abstract IntPtr Init(
|
||||
ref InitConfig loadData,
|
||||
/* ref ConfigCallbackInterface */ IntPtr[] configCallbackInterface,
|
||||
/* ref FileCallbackInterface */ IntPtr[] fileCallbackInterface,
|
||||
// /* ref GLCallbackInterface */ IntPtr[] glCallbackInterface, // TODO
|
||||
LogCallback logCallback);
|
||||
IntPtr[] configCallbackInterface, /* ref ConfigCallbackInterface */
|
||||
IntPtr[] fileCallbackInterface, /* ref FileCallbackInterface */
|
||||
LogCallback logCallback,
|
||||
GetGLProcAddressCallback getGLProcAddressCallback);
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract void PutSaveRam(byte[] data, uint len);
|
||||
|
@ -271,5 +257,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
|
||||
[BizImport(CC)]
|
||||
public abstract void GetNANDData(byte[] buf);
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract int GetGLTexture();
|
||||
|
||||
[BizImport(CC)]
|
||||
public abstract void ReadFrameBuffer(int[] buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
|
||||
public void SetCpuRegister(string register, int value)
|
||||
{
|
||||
if (register.Length != 7 && register.Length != 8)
|
||||
if (register.Length is not (7 or 8))
|
||||
{
|
||||
throw new InvalidOperationException("Wrong String Length???");
|
||||
}
|
||||
|
@ -50,13 +50,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
|
||||
public long TotalExecutedCycles => CycleCount + _core.GetCallbackCycleOffset();
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks => _memorycallbacks;
|
||||
public IMemoryCallbackSystem MemoryCallbacks => _memoryCallbacks;
|
||||
|
||||
private readonly MemoryCallbackSystem _memorycallbacks = new(new[] { "System Bus" });
|
||||
private readonly MemoryCallbackSystem _memoryCallbacks = new(new[] { "System Bus" });
|
||||
|
||||
private LibMelonDS.MemoryCallback _readcb;
|
||||
private LibMelonDS.MemoryCallback _writecb;
|
||||
private LibMelonDS.MemoryCallback _execcb;
|
||||
private LibMelonDS.MemoryCallback _readCallback;
|
||||
private LibMelonDS.MemoryCallback _writeCallback;
|
||||
private LibMelonDS.MemoryCallback _execCallback;
|
||||
|
||||
private void InitMemoryCallbacks()
|
||||
{
|
||||
|
@ -72,18 +72,18 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
};
|
||||
}
|
||||
|
||||
_readcb = CreateCallback(MemoryCallbackFlags.AccessRead, () => MemoryCallbacks.HasReads);
|
||||
_writecb = CreateCallback(MemoryCallbackFlags.AccessWrite, () => MemoryCallbacks.HasWrites);
|
||||
_execcb = CreateCallback(MemoryCallbackFlags.AccessExecute, () => MemoryCallbacks.HasExecutes);
|
||||
_readCallback = CreateCallback(MemoryCallbackFlags.AccessRead, () => MemoryCallbacks.HasReads);
|
||||
_writeCallback = CreateCallback(MemoryCallbackFlags.AccessWrite, () => MemoryCallbacks.HasWrites);
|
||||
_execCallback = CreateCallback(MemoryCallbackFlags.AccessExecute, () => MemoryCallbacks.HasExecutes);
|
||||
|
||||
_memorycallbacks.ActiveChanged += SetMemoryCallbacks;
|
||||
_memoryCallbacks.ActiveChanged += SetMemoryCallbacks;
|
||||
}
|
||||
|
||||
private void SetMemoryCallbacks()
|
||||
{
|
||||
_core.SetMemoryCallback(0, MemoryCallbacks.HasReads ? _readcb : null);
|
||||
_core.SetMemoryCallback(1, MemoryCallbacks.HasWrites ? _writecb : null);
|
||||
_core.SetMemoryCallback(2, MemoryCallbacks.HasExecutes ? _execcb : null);
|
||||
_core.SetMemoryCallback(0, MemoryCallbacks.HasReads ? _readCallback : null);
|
||||
_core.SetMemoryCallback(1, MemoryCallbacks.HasWrites ? _writeCallback : null);
|
||||
_core.SetMemoryCallback(2, MemoryCallbacks.HasExecutes ? _execCallback : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
||||
{
|
||||
public class MelonDSGLTextureProvider : IGLTextureProvider
|
||||
{
|
||||
private readonly IVideoProvider _vp;
|
||||
private readonly LibMelonDS _core;
|
||||
private readonly Action _activateGLContextCallback;
|
||||
private readonly int[] _vbuf = new int[256 * 16 * 384 * 16];
|
||||
|
||||
internal bool VideoDirty;
|
||||
|
||||
internal MelonDSGLTextureProvider(IVideoProvider vp, LibMelonDS core, Action activateGLContextCallback)
|
||||
{
|
||||
_vp = vp;
|
||||
_core = core;
|
||||
_activateGLContextCallback = activateGLContextCallback;
|
||||
}
|
||||
|
||||
public int GetGLTexture()
|
||||
=> _core.GetGLTexture();
|
||||
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
if (VideoDirty)
|
||||
{
|
||||
_activateGLContextCallback();
|
||||
_core.ReadFrameBuffer(_vbuf);
|
||||
VideoDirty = false;
|
||||
}
|
||||
|
||||
return _vbuf;
|
||||
}
|
||||
|
||||
public int VirtualWidth => 256;
|
||||
public int VirtualHeight => 384;
|
||||
public int BufferWidth => _vp.BufferWidth;
|
||||
public int BufferHeight => _vp.BufferHeight;
|
||||
public int VsyncNumerator => _vp.VsyncNumerator;
|
||||
public int VsyncDenominator => _vp.VsyncDenominator;
|
||||
public int BackgroundColor => _vp.BackgroundColor;
|
||||
}
|
||||
}
|
|
@ -12,19 +12,24 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
if (IsDSiWare)
|
||||
{
|
||||
_core.DSiWareSavsLength(DSiTitleId.Lower, out var publicSavSize, out var privateSavSize, out var bannerSavSize);
|
||||
if (publicSavSize + privateSavSize + bannerSavSize == 0) return null;
|
||||
if (publicSavSize + privateSavSize + bannerSavSize == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
_exe.AddTransientFile(Array.Empty<byte>(), "public.sav");
|
||||
_exe.AddTransientFile(Array.Empty<byte>(), "private.sav");
|
||||
_exe.AddTransientFile(Array.Empty<byte>(), "banner.sav");
|
||||
_core.ExportDSiWareSavs(DSiTitleId.Lower);
|
||||
|
||||
var publicSav = _exe.RemoveTransientFile("public.sav");
|
||||
var privateSav = _exe.RemoveTransientFile("private.sav");
|
||||
var bannerSav = _exe.RemoveTransientFile("banner.sav");
|
||||
if (publicSav.Length != publicSavSize || privateSav.Length != privateSavSize ||
|
||||
bannerSav.Length != bannerSavSize)
|
||||
if (publicSav.Length != publicSavSize || privateSav.Length != privateSavSize || bannerSav.Length != bannerSavSize)
|
||||
{
|
||||
throw new InvalidOperationException("Unexpected size difference in DSiWare sav files!");
|
||||
}
|
||||
|
||||
var ret = new byte[publicSavSize + privateSavSize + bannerSavSize];
|
||||
publicSav.AsSpan().CopyTo(ret.AsSpan().Slice(0, publicSavSize));
|
||||
privateSav.AsSpan().CopyTo(ret.AsSpan().Slice(publicSavSize, privateSavSize));
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
Marshal.WriteByte(buffer, numToCopy, 0);
|
||||
}
|
||||
|
||||
private void GetArraySettingCallback(LibMelonDS.ConfigEntry configEntry, IntPtr buffer)
|
||||
private static void GetArraySettingCallback(LibMelonDS.ConfigEntry configEntry, IntPtr buffer)
|
||||
{
|
||||
if (configEntry != LibMelonDS.ConfigEntry.Firm_MAC)
|
||||
{
|
||||
|
@ -195,18 +195,20 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
return ret;
|
||||
}
|
||||
|
||||
public NDSSettings Clone() => MemberwiseClone() as NDSSettings;
|
||||
public NDSSettings Clone()
|
||||
=> (NDSSettings)MemberwiseClone();
|
||||
|
||||
public static bool NeedsScreenResize(NDSSettings x, NDSSettings y)
|
||||
{
|
||||
bool ret = false;
|
||||
var ret = false;
|
||||
ret |= x.ScreenLayout != y.ScreenLayout;
|
||||
ret |= x.ScreenGap != y.ScreenGap;
|
||||
ret |= x.ScreenRotation != y.ScreenRotation;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public NDSSettings() => SettingsUtil.SetDefaultValues(this);
|
||||
public NDSSettings()
|
||||
=> SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
|
||||
private static readonly DateTime minDate = new(2000, 1, 1);
|
||||
|
@ -217,20 +219,41 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
public enum ThreeDeeRendererType : int
|
||||
{
|
||||
Software,
|
||||
//OpenGL_Classic,
|
||||
[Display(Name = "OpenGL Classic")]
|
||||
OpenGL_Classic,
|
||||
// [Display(Name = "OpenGL Compute")]
|
||||
//OpenGL_Compute,
|
||||
}
|
||||
|
||||
[DisplayName("3D Renderer")]
|
||||
[Description("Renderer used for 3D. OpenGL Classic requires at least OpenGL 3.2, OpenGL Compute requires at least OpenGL 4.3. Forced to Software when recording a movie.")]
|
||||
// [Description("Renderer used for 3D. OpenGL Classic requires at least OpenGL 3.2, OpenGL Compute requires at least OpenGL 4.3. Forced to Software when recording a movie.")]
|
||||
[Description("Renderer used for 3D. OpenGL Classic requires at least OpenGL 3.2. Forced to Software when recording a movie.")]
|
||||
[DefaultValue(ThreeDeeRendererType.Software)]
|
||||
[TypeConverter(typeof(DescribableEnumConverter))]
|
||||
public ThreeDeeRendererType ThreeDeeRenderer { get; set; }
|
||||
|
||||
[DisplayName("Threaded 3D Rendering")]
|
||||
[Description("Offloads 3D rendering to a separate thread. Only used for the software 3D renderer.")]
|
||||
[DisplayName("Threaded Software 3D Rendering")]
|
||||
[Description("Offloads 3D rendering to a separate thread. Only used for the software renderer.")]
|
||||
[DefaultValue(true)]
|
||||
public bool ThreadedRendering { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
private int _glScaleFactor;
|
||||
|
||||
[DisplayName("OpenGL Scale Factor")]
|
||||
[Description("Factor at which OpenGL upscales the final image. Not used for the software renderer.")]
|
||||
[DefaultValue(1)]
|
||||
public int GLScaleFactor
|
||||
{
|
||||
get => _glScaleFactor;
|
||||
set => _glScaleFactor = Math.Max(1, Math.Min(16, value));
|
||||
}
|
||||
|
||||
[DisplayName("OpenGL Better Polygons")]
|
||||
[Description("Enhances polygon quality with OpenGL. Not used for the software renderer.")]
|
||||
[DefaultValue(false)]
|
||||
public bool GLBetterPolygons { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
private DateTime _initaltime;
|
||||
|
||||
|
@ -406,16 +429,21 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
set => _firmwaremessage = value.Substring(0, Math.Min(26, value.Length));
|
||||
}
|
||||
|
||||
public NDSSyncSettings Clone() => MemberwiseClone() as NDSSyncSettings;
|
||||
public NDSSyncSettings Clone()
|
||||
=> (NDSSyncSettings)MemberwiseClone();
|
||||
|
||||
public static bool NeedsReboot(NDSSyncSettings x, NDSSyncSettings y) => !DeepEquality.DeepEquals(x, y);
|
||||
public static bool NeedsReboot(NDSSyncSettings x, NDSSyncSettings y)
|
||||
=> !DeepEquality.DeepEquals(x, y);
|
||||
|
||||
public NDSSyncSettings() => SettingsUtil.SetDefaultValues(this);
|
||||
public NDSSyncSettings()
|
||||
=> SettingsUtil.SetDefaultValues(this);
|
||||
}
|
||||
|
||||
public NDSSettings GetSettings() => _settings.Clone();
|
||||
public NDSSettings GetSettings()
|
||||
=> _settings.Clone();
|
||||
|
||||
public NDSSyncSettings GetSyncSettings() => _syncSettings.Clone();
|
||||
public NDSSyncSettings GetSyncSettings()
|
||||
=> _syncSettings.Clone();
|
||||
|
||||
public PutSettingsDirtyBits PutSettings(NDSSettings o)
|
||||
{
|
||||
|
@ -433,28 +461,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
|
||||
private static int SanitizeBirthdayDay(int day, NDSSyncSettings.Month fwMonth)
|
||||
{
|
||||
int maxdays;
|
||||
switch (fwMonth)
|
||||
var maxdays = fwMonth switch
|
||||
{
|
||||
case NDSSyncSettings.Month.February:
|
||||
{
|
||||
maxdays = 29;
|
||||
break;
|
||||
}
|
||||
case NDSSyncSettings.Month.April:
|
||||
case NDSSyncSettings.Month.June:
|
||||
case NDSSyncSettings.Month.September:
|
||||
case NDSSyncSettings.Month.November:
|
||||
{
|
||||
maxdays = 30;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
maxdays = 31;
|
||||
break;
|
||||
}
|
||||
}
|
||||
NDSSyncSettings.Month.February => 29,
|
||||
NDSSyncSettings.Month.April or NDSSyncSettings.Month.June or NDSSyncSettings.Month.September or NDSSyncSettings.Month.November => 30,
|
||||
_ => 31
|
||||
};
|
||||
|
||||
return Math.Max(1, Math.Min(day, maxdays));
|
||||
}
|
||||
|
|
|
@ -8,10 +8,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
public partial class NDS
|
||||
{
|
||||
private ITraceable Tracer { get; }
|
||||
private readonly LibMelonDS.TraceCallback _tracecb;
|
||||
private readonly LibMelonDS.TraceCallback _traceCallback;
|
||||
|
||||
private unsafe void MakeTrace(LibMelonDS.TraceMask type, uint opcode, IntPtr r, IntPtr disasm, uint cyclesOff)
|
||||
{
|
||||
// ReSharper disable once SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault
|
||||
var cpu = type switch
|
||||
{
|
||||
LibMelonDS.TraceMask.ARM7_THUMB => "ARM7 (Thumb)",
|
||||
|
|
|
@ -62,14 +62,22 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
private static void LogCallback(LibMelonDS.LogLevel level, string message)
|
||||
=> Console.Write($"[{level}] {message}");
|
||||
|
||||
private readonly MelonDSGLTextureProvider _glTextureProvider;
|
||||
private readonly IOpenGLProvider _openGLProvider;
|
||||
private readonly object _glContext;
|
||||
private readonly LibMelonDS.GetGLProcAddressCallback _getGLProcAddressCallback;
|
||||
|
||||
private IntPtr GetGLProcAddressCallback(string proc)
|
||||
=> _openGLProvider.GetGLProcAddress(proc);
|
||||
|
||||
[CoreConstructor(VSystemID.Raw.NDS)]
|
||||
public NDS(CoreLoadParameters<NDSSettings, NDSSyncSettings> lp)
|
||||
: base(lp.Comm, new()
|
||||
{
|
||||
DefaultWidth = 256,
|
||||
DefaultHeight = 384,
|
||||
MaxWidth = 256,
|
||||
MaxHeight = 384,
|
||||
MaxWidth = 256 * 16,
|
||||
MaxHeight = 384 * 16,
|
||||
MaxSamples = 1024,
|
||||
DefaultFpsNumerator = 33513982,
|
||||
DefaultFpsDenominator = 560190,
|
||||
|
@ -93,12 +101,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
throw new InvalidOperationException("Wrong number of ROMs!");
|
||||
}
|
||||
|
||||
var gbacartpresent = roms.Count == 2;
|
||||
|
||||
InitMemoryCallbacks();
|
||||
|
||||
_tracecb = MakeTrace;
|
||||
_threadstartcb = ThreadStartCallback;
|
||||
_traceCallback = MakeTrace;
|
||||
_threadStartCallback = ThreadStartCallback;
|
||||
|
||||
_configCallbackInterface.GetBoolean = GetBooleanSettingCallback;
|
||||
_configCallbackInterface.GetInteger = GetIntegerSettingCallback;
|
||||
|
@ -110,6 +116,35 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
|
||||
_logCallback = LogCallback;
|
||||
|
||||
_openGLProvider = CoreComm.OpenGLProvider;
|
||||
_getGLProcAddressCallback = GetGLProcAddressCallback;
|
||||
|
||||
if (lp.DeterministicEmulationRequested)
|
||||
{
|
||||
_activeSyncSettings.ThreeDeeRenderer = NDSSyncSettings.ThreeDeeRendererType.Software;
|
||||
}
|
||||
|
||||
if (_activeSyncSettings.ThreeDeeRenderer != NDSSyncSettings.ThreeDeeRendererType.Software)
|
||||
{
|
||||
// ReSharper disable once SwitchExpressionHandlesSomeKnownEnumValuesWithExceptionInDefault
|
||||
var (majorGlVersion, minorGlVersion) = _activeSyncSettings.ThreeDeeRenderer switch
|
||||
{
|
||||
NDSSyncSettings.ThreeDeeRendererType.OpenGL_Classic => (3, 2),
|
||||
// NDSSyncSettings.ThreeDeeRendererType.OpenGL_Compute => (4, 3),
|
||||
_ => throw new InvalidOperationException($"Invalid {nameof(NDSSyncSettings.ThreeDeeRenderer)}")
|
||||
};
|
||||
|
||||
if (!_openGLProvider.SupportsGLVersion(majorGlVersion, minorGlVersion))
|
||||
{
|
||||
lp.Comm.Notify($"OpenGL {majorGlVersion}.{minorGlVersion} is not supported on this machine, falling back to software renderer", null);
|
||||
_activeSyncSettings.ThreeDeeRenderer = NDSSyncSettings.ThreeDeeRendererType.Software;
|
||||
}
|
||||
else
|
||||
{
|
||||
_glContext = _openGLProvider.RequestGLContext(majorGlVersion, minorGlVersion, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
_core = PreInit<LibMelonDS>(new()
|
||||
{
|
||||
Filename = "melonDS.wbx",
|
||||
|
@ -122,11 +157,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
SkipMemoryConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck),
|
||||
}, new Delegate[]
|
||||
{
|
||||
_readcb, _writecb, _execcb, _tracecb, _threadstartcb,
|
||||
_readCallback, _writeCallback, _execCallback, _traceCallback, _threadStartCallback,
|
||||
_configCallbackInterface.GetBoolean, _configCallbackInterface.GetInteger,
|
||||
_configCallbackInterface.GetString, _configCallbackInterface.GetArray,
|
||||
_fileCallbackInterface.GetLength, _fileCallbackInterface.GetData,
|
||||
_logCallback
|
||||
_logCallback, _getGLProcAddressCallback
|
||||
});
|
||||
|
||||
_activeSyncSettings.UseRealBIOS |= IsDSi;
|
||||
|
@ -164,22 +199,23 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
else
|
||||
{
|
||||
AddCoreFile("nds.rom", roms[0]);
|
||||
if (gbacartpresent)
|
||||
if (roms.Count == 2)
|
||||
{
|
||||
AddCoreFile("gba.rom", roms[1]);
|
||||
}
|
||||
}
|
||||
|
||||
LibMelonDS.InitConfig initConfig;
|
||||
initConfig.SkipFW = _activeSyncSettings.SkipFirmware;
|
||||
initConfig.HasGBACart = gbacartpresent;
|
||||
initConfig.SkipFW = _activeSyncSettings.SkipFirmware && !IsDSi;
|
||||
initConfig.HasGBACart = roms.Count == 2;
|
||||
initConfig.DSi = IsDSi;
|
||||
initConfig.ClearNAND = _activeSyncSettings.ClearNAND || lp.DeterministicEmulationRequested;
|
||||
initConfig.LoadDSiWare = IsDSiWare;
|
||||
initConfig.IsWinApi = !OSTailoredCode.IsUnixHost;
|
||||
initConfig.ThreeDeeRenderer = _activeSyncSettings.ThreeDeeRenderer;
|
||||
initConfig.RenderSettings.SoftThreaded = _activeSyncSettings.ThreadedRendering;
|
||||
initConfig.RenderSettings.GLScaleFactor = 1; // TODO
|
||||
initConfig.RenderSettings.GLBetterPolygons = false; // TODO
|
||||
initConfig.RenderSettings.GLScaleFactor = _activeSyncSettings.GLScaleFactor;
|
||||
initConfig.RenderSettings.GLBetterPolygons = _activeSyncSettings.GLBetterPolygons;
|
||||
|
||||
_activeSyncSettings.FirmwareOverride |= !_activeSyncSettings.UseRealBIOS || lp.DeterministicEmulationRequested;
|
||||
|
||||
|
@ -205,7 +241,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
ref initConfig,
|
||||
_configCallbackInterface.AllCallbacksInArray(_adapter),
|
||||
_fileCallbackInterface.AllCallbacksInArray(_adapter),
|
||||
_logCallback);
|
||||
_logCallback,
|
||||
_getGLProcAddressCallback);
|
||||
if (error != IntPtr.Zero)
|
||||
{
|
||||
using (_exe.EnterExit())
|
||||
|
@ -233,7 +270,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
_frameThreadAction = CallingConventionAdapters
|
||||
.GetWaterboxUnsafeUnwrapped()
|
||||
.GetDelegateForFunctionPointer<Action>(_frameThreadPtr);
|
||||
_core.SetThreadStartCallback(_threadstartcb);
|
||||
_core.SetThreadStartCallback(_threadStartCallback);
|
||||
}
|
||||
|
||||
_disassembler = new(_core);
|
||||
|
@ -242,6 +279,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
const string TRACE_HEADER = "ARM9+ARM7: Opcode address, opcode, registers (r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, SP, LR, PC, Cy, CpuMode)";
|
||||
Tracer = new TraceBuffer(TRACE_HEADER);
|
||||
_serviceProvider.Register(Tracer);
|
||||
|
||||
if (_glContext != null)
|
||||
{
|
||||
_glTextureProvider = new(this, _core, () => _openGLProvider.ActivateGLContext(_glContext));
|
||||
_serviceProvider.Register<IVideoProvider>(_glTextureProvider);
|
||||
}
|
||||
}
|
||||
|
||||
private static (ulong Full, uint Upper, uint Lower) GetDSiTitleId(IReadOnlyList<byte> file)
|
||||
|
@ -361,7 +404,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
|
||||
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
|
||||
{
|
||||
_core.SetTraceCallback(Tracer.IsEnabled() ? _tracecb : null, _settings.GetTraceMask());
|
||||
if (_glContext != null)
|
||||
{
|
||||
_openGLProvider.ActivateGLContext(_glContext);
|
||||
}
|
||||
|
||||
_core.SetTraceCallback(Tracer.IsEnabled() ? _traceCallback : null, _settings.GetTraceMask());
|
||||
|
||||
return new LibMelonDS.FrameInfo
|
||||
{
|
||||
Time = GetRtcTime(!DeterministicEmulation),
|
||||
|
@ -376,7 +425,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
|
||||
private readonly IntPtr _frameThreadPtr;
|
||||
private readonly Action _frameThreadAction;
|
||||
private readonly LibMelonDS.ThreadStartCallback _threadstartcb;
|
||||
private readonly LibMelonDS.ThreadStartCallback _threadStartCallback;
|
||||
|
||||
private readonly Thread _frameThread;
|
||||
private readonly SemaphoreSlim _frameThreadStartEvent = new(0, 1);
|
||||
|
@ -391,6 +440,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
_frameThread?.Join();
|
||||
_frameThreadStartEvent.Dispose();
|
||||
_frameThreadEndEvent.Dispose();
|
||||
|
||||
if (_glContext != null)
|
||||
{
|
||||
_openGLProvider.ReleaseGLContext(_glContext);
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
|
@ -425,12 +480,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS
|
|||
_frameThreadEndEvent.Wait();
|
||||
_renderThreadRanThisFrame = false;
|
||||
}
|
||||
|
||||
if (_glTextureProvider != null)
|
||||
{
|
||||
_glTextureProvider.VideoDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadStateBinaryInternal(BinaryReader reader)
|
||||
{
|
||||
SetMemoryCallbacks();
|
||||
_core.SetThreadStartCallback(_threadstartcb);
|
||||
_core.SetThreadStartCallback(_threadStartCallback);
|
||||
if (_frameThreadPtr != _core.GetFrameThreadProc())
|
||||
{
|
||||
throw new InvalidOperationException("_frameThreadPtr mismatch");
|
||||
|
|
Loading…
Reference in New Issue