Skurdt / SK.Libretro

Libretro wrapper written in C# with support for the Unity game engine
MIT License
28 stars 13 forks source link

add support with android (oculus quest) #17

Closed XenuIsWatching closed 2 months ago

XenuIsWatching commented 1 year ago

Android (Native Quest 2) builds use IL2CPP on unity. This presents an issue where having the error is given

IL2CPP does not support marshaling delegates that point to instance methods to native code. The method we're attempting to marshal is: SK.Libretro.EnvironmentHandler::EnvironmentCallback

The workaround is to having the functions be declared as static and are looked up within a Dictionary for the class instance with 'Thread' as it's index.

Android also has a limitation with where it can dynamically link in code The *.so library file of a libretro core just can not be from any location on the filesystem for 'security reasons'. The location must be within a specific directory. In this case, that directory is with in a temp location. Where tempDirectory in this case initialized to $"{GetAndroidPrivateAppDataPath()}/temp" and libretroDirectory is initialized to$"{Application.persistentDataPath}/libretro"`. GetAndroidPrivateAppDataPath() is shown below.

private string GetAndroidPrivateAppDataPath()
{
    string path;
    using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    {
        using (AndroidJavaObject currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity"))
        {
            path = currentActivity.Call<AndroidJavaObject>("getFilesDir").Call<string>("getCanonicalPath");
        }
    }
    return path;
}

Fixes #10

XenuIsWatching commented 1 year ago

draft because there may be some dead code left to remove

XenuIsWatching commented 1 year ago

There is another issue with Android builds with some libretro cores such as Dolphin do use a hardware accelerator such as OpenGL. The current implementation uses glfw. This isn't Android compatible right now. I'll get a separate issue for this.

Skurdt commented 6 months ago

I implemented something similar to this, though using the Thread as the dictionary key doesn't seem to work on some multithreaded cores. I only tried dolphin very briefly and with no hardware render path so for now I'm not really sure.