package com.grapeshot.halfnes; import java.io.*; import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.security.AccessController; import java.security.PrivilegedAction; /** * Created by KlausH on 29.11.2015. */ public enum JInputHelper { ; private static final String[] NATIVE_LIBRARIES = new String[]{ // Windows "jinput-dx8.dll", "jinput-dx8_64.dll", "jinput-raw.dll", "jinput-raw_64.dll", "jinput-wintab.dll", "jinput-wintab.dll", // Linux "libjinput-linux.so", "libjinput-linux64.so", // OsX (Mac) "libjinput-osx.jnilib",}; public static void setupJInput() { try { File nativesDirectory = createTempDirectory(); unpackNativeLibraries(nativesDirectory); setLibraryPath(nativesDirectory); fixInputPluginForWindows8(); } catch (Exception exception) { throw new RuntimeException("Unable to setup native libraries.", exception); } } private static void unpackNativeLibraries(File nativesDirectory) throws IOException { for (String nativeLibrary : NATIVE_LIBRARIES) { unpackNativeLibrary(nativesDirectory, nativeLibrary); } } private static void unpackNativeLibrary(File nativesDirectory, String nativeLibrary) throws IOException { try (InputStream nativeLibraryInputStream = ClassLoader.getSystemResourceAsStream(nativeLibrary)) { File nativeLibraryTempFile = new File(nativesDirectory, nativeLibrary); nativeLibraryTempFile.deleteOnExit(); if (!nativeLibraryTempFile.exists()) { try (BufferedOutputStream nativeLibraryTempFileOutputStream = new BufferedOutputStream(new FileOutputStream(nativeLibraryTempFile))) { byte[] buffer = new byte[4096]; int length; while ((length = nativeLibraryInputStream.read(buffer)) > 0) { nativeLibraryTempFileOutputStream.write(buffer, 0, length); } } } } } private static File createTempDirectory() throws IOException { String tmpdir = System.getProperty("java.io.tmpdir") + "/halfnes-" + NES.VERSION; System.err.println(tmpdir); File f = new File(tmpdir); if (!f.exists()) { f.mkdir(); } //File nativeDirectory = Files.createTempDirectory("halfNES-natives").toFile(); f.deleteOnExit(); return f; } private static void setLibraryPath(final File nativesDirectory) throws NoSuchFieldException, IllegalAccessException { System.setProperty("java.library.path", nativesDirectory.getAbsolutePath()); final Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); fieldSysPath.setAccessible(true); fieldSysPath.set(null, null); } private static void fixInputPluginForWindows8() { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { String os = System.getProperty("os.name", "").trim(); if (os.startsWith("Windows")) { if (os.startsWith("Windows 8")) { // disable default plugin lookup System.setProperty("jinput.useDefaultPlugin", "false"); // set to same as windows 7 System.setProperty("net.java.games.input.plugins", "net.java.games.input.DirectAndRawInputEnvironmentPlugin"); } if (os.startsWith("Windows 10") || isWindows10()) { // disable default plugin lookup System.setProperty("jinput.useDefaultPlugin", "false"); // set fallback to AWT plugin System.setProperty("net.java.games.input.plugins", "net.java.games.input.DirectAndRawInputEnvironmentPlugin"); } } return null; }); } private static boolean isWindows10() { try { Process process = Runtime.getRuntime().exec("cmd.exe /c ver"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)); bufferedReader.readLine(); String line = bufferedReader.readLine(); process.waitFor(); return line.contains("10"); } catch (Exception exception) { throw new RuntimeException(exception); } } }