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.
 
 
 
 
 

124 lines
3.9 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Events;
public class Uniquake: MonoBehaviour
{
private const string DllName = "uniquake.dll";
private const int MemSize = 0x4000000; // 64 MB of heap space
private UnityCallbacks callbacks;
private QuakeParms quakeParms;
void Start()
{
callbacks = new UnityCallbacks
{
DebugLog = Callback_DebugLog,
DebugLogError = Callback_DebugLogError,
ApplicationQuit = Callback_ApplicationQuit,
RealtimeSinceStartup = Callback_RealtimeSinceStartup,
};
string[] args = Environment.GetCommandLineArgs();
quakeParms = new QuakeParms
{
baseDir = Application.dataPath,
cacheDir = null,
argc = 0,//args.Length,
argv = null,//args, // TODO: marshaling of string arrays is still tricky
memBase = Marshal.AllocHGlobal(MemSize),
memSize = MemSize,
};
Uniquake_Init(callbacks, quakeParms);
}
void Update()
{
Uniquake_Update(Time.deltaTime);
}
private void OnDestroy()
{
if (quakeParms != null && quakeParms.memBase != IntPtr.Zero)
{
Marshal.FreeHGlobal(quakeParms.memBase);
quakeParms.memBase = IntPtr.Zero;
}
}
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void Uniquake_Echo(UnityCallbacks.DebugLogCallback logCallback, [MarshalAs(UnmanagedType.LPStr)] string message);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void Uniquake_Init(UnityCallbacks callbacks, QuakeParms parms);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
private static extern void Uniquake_Update(float deltaTime);
[AOT.MonoPInvokeCallback(typeof(UnityCallbacks.DebugLogCallback))]
private static void Callback_DebugLog(string message)
{
Debug.Log(message);
}
[AOT.MonoPInvokeCallback(typeof(UnityCallbacks.DebugLogErrorCallback))]
private static void Callback_DebugLogError(string message)
{
Debug.LogError(message);
}
[AOT.MonoPInvokeCallback(typeof(UnityCallbacks.ApplicationQuitCallback))]
private static void Callback_ApplicationQuit(int exitCode)
{
Debug.Log($"Quitting application with exit code: {exitCode}");
// TODO: kill execution of the DLL entirely (Sys_Quit expects immediate exit, which Application.Quit doesn't do)
Application.Quit(exitCode);
}
[AOT.MonoPInvokeCallback(typeof(UnityCallbacks.RealtimeSinceStartupCallback))]
private static double Callback_RealtimeSinceStartup()
{
return Time.realtimeSinceStartupAsDouble;
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class UnityCallbacks
{
public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)] string message);
public DebugLogCallback DebugLog;
public delegate void DebugLogErrorCallback([MarshalAs(UnmanagedType.LPStr)] string message);
public DebugLogErrorCallback DebugLogError;
public delegate void ApplicationQuitCallback(int exitCode);
public ApplicationQuitCallback ApplicationQuit;
public delegate double RealtimeSinceStartupCallback();
public RealtimeSinceStartupCallback RealtimeSinceStartup;
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
private class QuakeParms
{
[MarshalAs(UnmanagedType.LPStr)]
public string baseDir;
[MarshalAs(UnmanagedType.LPStr)]
public string cacheDir;
public int argc;
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)]
public string[] argv;
public IntPtr memBase;
public int memSize;
}
}