You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
3.6 KiB
89 lines
3.6 KiB
using System;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using UnityEngine;
|
|
|
|
public partial class UniQuake
|
|
{
|
|
#if UNITY_EDITOR
|
|
private const string DllPath = "Plugins/windows/x86_64/uniquake.dll";
|
|
#elif UNITY_STANDALONE_WIN
|
|
#if UNITY_64
|
|
private const string DllPath = "Plugins/x86_64/uniquake.dll";
|
|
#else
|
|
private const string DllPath = "Plugins/x86/uniquake.dll";
|
|
#endif
|
|
#endif
|
|
|
|
private IntPtr libraryHandle;
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
private delegate void UniQuake_InitFunc(IntPtr parms);
|
|
private UniQuake_InitFunc UniQuake_Init;
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
private delegate void UniQuake_UpdateFunc(float deltaTime);
|
|
private UniQuake_UpdateFunc UniQuake_Update;
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
private delegate void UniQuake_ShutdownFunc();
|
|
private UniQuake_ShutdownFunc UniQuake_Shutdown;
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
private delegate void UniQuake_SetFmodSystemFunc(IntPtr fmodSystem, int playerNumber = 0);
|
|
private UniQuake_SetFmodSystemFunc UniQuake_SetFmodSystem;
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
private delegate void UniQuake_SetCallbacksFunc(IntPtr context, IntPtr callbacks);
|
|
private UniQuake_SetCallbacksFunc UniQuake_SetSysCallbacks;
|
|
private UniQuake_SetCallbacksFunc UniQuake_SetRenderCallbacks;
|
|
private UniQuake_SetCallbacksFunc UniQuake_SetGameCallbacks;
|
|
|
|
private void LoadLibrary()
|
|
{
|
|
string dllFile = Path.Combine(Application.dataPath, DllPath);
|
|
|
|
// Experimental code to allow running multiple instances of Quake next to each other
|
|
if (PlayerNumber > 1)
|
|
{
|
|
string directory = Path.GetDirectoryName(dllFile);
|
|
string filename = Path.GetFileNameWithoutExtension(dllFile);
|
|
string extension = Path.GetExtension(dllFile);
|
|
dllFile = Path.Combine(directory, filename + PlayerNumber + extension);
|
|
}
|
|
|
|
libraryHandle = SystemLibrary.LoadLibrary(dllFile);
|
|
if (libraryHandle == IntPtr.Zero)
|
|
{
|
|
throw new DllNotFoundException($"Failed to load UniQuake library from path: {dllFile}, last error = {Marshal.GetLastWin32Error()}");
|
|
}
|
|
|
|
UniQuake_Init = LoadLibraryFunction<UniQuake_InitFunc>(nameof(UniQuake_Init));
|
|
UniQuake_Update = LoadLibraryFunction<UniQuake_UpdateFunc>(nameof(UniQuake_Update));
|
|
UniQuake_Shutdown = LoadLibraryFunction<UniQuake_ShutdownFunc>(nameof(UniQuake_Shutdown));
|
|
UniQuake_SetFmodSystem = LoadLibraryFunction<UniQuake_SetFmodSystemFunc>(nameof(UniQuake_SetFmodSystem));
|
|
UniQuake_SetSysCallbacks = LoadLibraryFunction<UniQuake_SetCallbacksFunc>(nameof(UniQuake_SetSysCallbacks));
|
|
UniQuake_SetRenderCallbacks = LoadLibraryFunction<UniQuake_SetCallbacksFunc>(nameof(UniQuake_SetRenderCallbacks));
|
|
UniQuake_SetGameCallbacks = LoadLibraryFunction<UniQuake_SetCallbacksFunc>(nameof(UniQuake_SetGameCallbacks));
|
|
}
|
|
|
|
private TDelegate LoadLibraryFunction<TDelegate>(string functionName)
|
|
{
|
|
IntPtr procAddress = SystemLibrary.GetProcAddress(libraryHandle, functionName);
|
|
if (procAddress == IntPtr.Zero)
|
|
{
|
|
throw new DllNotFoundException($"Could not find library function: {functionName}");
|
|
}
|
|
|
|
return Marshal.GetDelegateForFunctionPointer<TDelegate>(procAddress);
|
|
}
|
|
|
|
private void FreeLibrary()
|
|
{
|
|
if (libraryHandle != IntPtr.Zero)
|
|
{
|
|
SystemLibrary.FreeLibrary(libraryHandle);
|
|
libraryHandle = IntPtr.Zero;
|
|
}
|
|
}
|
|
}
|