9 changed files with 251 additions and 3 deletions
-
1src/android/app/src/main/AndroidManifest.xml
-
2src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java
-
3src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.java
-
53src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.java
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainPresenter.java
-
130src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverHelper.java
-
45src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GpuDriverMetadata.java
-
5src/android/app/src/main/res/menu/menu_game_grid.xml
-
10src/android/app/src/main/res/values/strings.xml
@ -0,0 +1,130 @@ |
|||
package org.yuzu.yuzu_emu.utils; |
|||
|
|||
import android.content.Context; |
|||
import android.net.Uri; |
|||
|
|||
import org.yuzu.yuzu_emu.NativeLibrary; |
|||
|
|||
import java.io.File; |
|||
import java.io.FileInputStream; |
|||
import java.io.FileOutputStream; |
|||
import java.io.IOException; |
|||
import java.util.zip.ZipEntry; |
|||
import java.util.zip.ZipInputStream; |
|||
|
|||
public class GpuDriverHelper { |
|||
private static final String META_JSON_FILENAME = "meta.json"; |
|||
private static final String DRIVER_INTERNAL_FILENAME = "gpu_driver.zip"; |
|||
private static String fileRedirectionPath; |
|||
private static String driverInstallationPath; |
|||
private static String hookLibPath; |
|||
|
|||
private static void unzip(String zipFilePath, String destDir) throws IOException { |
|||
File dir = new File(destDir); |
|||
|
|||
// Create output directory if it doesn't exist |
|||
if (!dir.exists()) dir.mkdirs(); |
|||
|
|||
// Unpack the files. |
|||
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath)); |
|||
byte[] buffer = new byte[1024]; |
|||
ZipEntry ze = zis.getNextEntry(); |
|||
while (ze != null) { |
|||
String fileName = ze.getName(); |
|||
File newFile = new File(destDir + fileName); |
|||
newFile.getParentFile().mkdirs(); |
|||
FileOutputStream fos = new FileOutputStream(newFile); |
|||
int len; |
|||
while ((len = zis.read(buffer)) > 0) { |
|||
fos.write(buffer, 0, len); |
|||
} |
|||
fos.close(); |
|||
zis.closeEntry(); |
|||
ze = zis.getNextEntry(); |
|||
} |
|||
zis.closeEntry(); |
|||
} |
|||
|
|||
public static void initializeDriverParameters(Context context) { |
|||
try { |
|||
// Initialize the file redirection directory. |
|||
fileRedirectionPath = context.getExternalFilesDir(null).getCanonicalPath() + "/gpu/vk_file_redirect/"; |
|||
|
|||
// Initialize the driver installation directory. |
|||
driverInstallationPath = context.getFilesDir().getCanonicalPath() + "/gpu_driver/"; |
|||
} catch (IOException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
|
|||
// Initialize directories. |
|||
initializeDirectories(); |
|||
|
|||
// Initialize hook libraries directory. |
|||
hookLibPath = context.getApplicationInfo().nativeLibraryDir + "/"; |
|||
|
|||
// Initialize GPU driver. |
|||
NativeLibrary.InitializeGpuDriver(hookLibPath, driverInstallationPath, getCustomDriverLibraryName(), fileRedirectionPath); |
|||
} |
|||
|
|||
public static void installDefaultDriver(Context context) { |
|||
// Removing the installed driver will result in the backend using the default system driver. |
|||
File driverInstallationDir = new File(driverInstallationPath); |
|||
deleteRecursive(driverInstallationDir); |
|||
initializeDriverParameters(context); |
|||
} |
|||
|
|||
public static void installCustomDriver(Context context, Uri driverPathUri) { |
|||
// Revert to system default in the event the specified driver is bad. |
|||
installDefaultDriver(context); |
|||
|
|||
// Ensure we have directories. |
|||
initializeDirectories(); |
|||
|
|||
// Copy the zip file URI into our private storage. |
|||
FileUtil.copyUriToInternalStorage(context, driverPathUri, driverInstallationPath, DRIVER_INTERNAL_FILENAME); |
|||
|
|||
// Unzip the driver. |
|||
try { |
|||
unzip(driverInstallationPath + DRIVER_INTERNAL_FILENAME, driverInstallationPath); |
|||
} catch (IOException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
|
|||
// Initialize the driver parameters. |
|||
initializeDriverParameters(context); |
|||
} |
|||
|
|||
public static String getCustomDriverName() { |
|||
// Parse the custom driver metadata to retrieve the name. |
|||
GpuDriverMetadata metadata = new GpuDriverMetadata(driverInstallationPath + META_JSON_FILENAME); |
|||
return metadata.name; |
|||
} |
|||
|
|||
private static String getCustomDriverLibraryName() { |
|||
// Parse the custom driver metadata to retrieve the library name. |
|||
GpuDriverMetadata metadata = new GpuDriverMetadata(driverInstallationPath + META_JSON_FILENAME); |
|||
return metadata.libraryName; |
|||
} |
|||
|
|||
private static void initializeDirectories() { |
|||
// Ensure the file redirection directory exists. |
|||
File fileRedirectionDir = new File(fileRedirectionPath); |
|||
if (!fileRedirectionDir.exists()) { |
|||
fileRedirectionDir.mkdirs(); |
|||
} |
|||
// Ensure the driver installation directory exists. |
|||
File driverInstallationDir = new File(driverInstallationPath); |
|||
if (!driverInstallationDir.exists()) { |
|||
driverInstallationDir.mkdirs(); |
|||
} |
|||
} |
|||
|
|||
private static void deleteRecursive(File fileOrDirectory) { |
|||
if (fileOrDirectory.isDirectory()) { |
|||
for (File child : fileOrDirectory.listFiles()) { |
|||
deleteRecursive(child); |
|||
} |
|||
} |
|||
fileOrDirectory.delete(); |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
package org.yuzu.yuzu_emu.utils; |
|||
|
|||
import org.json.JSONException; |
|||
import org.json.JSONObject; |
|||
|
|||
import java.io.IOException; |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.nio.file.Files; |
|||
import java.nio.file.Path; |
|||
import java.nio.file.Paths; |
|||
|
|||
public class GpuDriverMetadata { |
|||
|
|||
public String name; |
|||
public String description; |
|||
public String author; |
|||
public String vendor; |
|||
public String driverVersion; |
|||
public int minApi; |
|||
public String libraryName; |
|||
|
|||
public GpuDriverMetadata(String metadataFilePath) { |
|||
try { |
|||
JSONObject json = new JSONObject(getStringFromFile(metadataFilePath)); |
|||
name = json.getString("name"); |
|||
description = json.getString("description"); |
|||
author = json.getString("author"); |
|||
vendor = json.getString("vendor"); |
|||
driverVersion = json.getString("driverVersion"); |
|||
minApi = json.getInt("minApi"); |
|||
libraryName = json.getString("libraryName"); |
|||
} catch (JSONException e) { |
|||
// JSON is malformed, ignore and treat as unsupported metadata. |
|||
} catch (IOException e) { |
|||
// File is inaccessible, ignore and treat as unsupported metadata. |
|||
} |
|||
} |
|||
|
|||
private static String getStringFromFile(String filePath) throws IOException { |
|||
Path path = Paths.get(filePath); |
|||
byte[] bytes = Files.readAllBytes(path); |
|||
return new String(bytes, StandardCharsets.UTF_8); |
|||
} |
|||
|
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue