diff --git a/README.md b/README.md index 5ca82b6..99f46ab 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ If you wish to change the colors of the buttons, simply change the color values * jme3-lwjgl3 or jme3-lwjgl (if running as standalone) * jme3-android (if running on Android) * jme3-android-natives (if running on Android) -* slf4j-api 1.7.15+ +* slf4j-api 1.7.30+ ## Building from Source To build from source, start by downloading the source from github. If you have the [git command line tool](https://git-scm.com/downloads) installed, the following line will download the git repository from github: @@ -45,7 +45,7 @@ If you want to test this without implementing it in your software, simply downlo This will run a bare-bones version dedicated to the utility using LWJGL3. -Alternativly, you can use the :desktopLegacy subproject for LWJGL2, or the :android subproject for testing on Android. +Alternatively, you can use the :desktopLegacy subproject for LWJGL2, or the :android subproject for testing on Android. ## Troubleshooting diff --git a/android/build.gradle b/android/build.gradle index b9ea611..5ee5567 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.1' + classpath 'com.android.tools.build:gradle:4.1.2' } } @@ -17,13 +17,13 @@ repositories { } android { - compileSdkVersion 29 - buildToolsVersion "30.0.2" + compileSdkVersion 30 + buildToolsVersion "30.0.3" defaultConfig { applicationId "markil3.controller" minSdkVersion 19 - targetSdkVersion 29 + targetSdkVersion 30 versionCode 1 versionName "1.0" @@ -43,15 +43,17 @@ android { } dependencies { - api(project(":desktop")) { - exclude module: "jme3-lwjgl3" - exclude module: "jme3-desktop" + api(project(":library")) { exclude module: "slf4j-simple" } implementation "uk.uuid.slf4j:slf4j-android:1.7.30-0" implementation "${jme3.g}:jme3-android:${jme3.version}" implementation "${jme3.g}:jme3-android-native:${jme3.version}" - implementation "androidx.appcompat:appcompat:1.1.0" - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.0.9" +// implementation rootProject.files('libs/jme3-android.jar') +// implementation rootProject.files('libs/jme3-core.jar') +// implementation rootProject.files('libs/jme3-plugins.jar') +// implementation rootProject.files('libs/jme3-android-native.jar') + implementation "androidx.appcompat:appcompat:1.2.0" + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5" } diff --git a/android/src/main/java/markil3/controller/Main.java b/android/src/main/java/markil3/controller/Main.java new file mode 100644 index 0000000..49a2ac2 --- /dev/null +++ b/android/src/main/java/markil3/controller/Main.java @@ -0,0 +1,276 @@ +/* + * Copyright 2020 Markil 3. All rights reserved. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package markil3.controller; + +import com.jme3.app.DebugKeysAppState; +import com.jme3.app.SimpleApplication; +import com.jme3.app.StatsAppState; +import com.jme3.font.BitmapText; +import com.jme3.input.JoystickCompatibilityMappings; +import com.jme3.input.controls.ActionListener; +import com.jme3.scene.Node; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeSystem; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +/** + * Launch point for the application. This is primarily for demo purposes, and + * games using this as a library can safely ignore it. + * + * @author Markil 3 + * @version 1.0 + */ +public class Main extends SimpleApplication implements ActionListener +{ + private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory. + getLogger(Main.class); + + public static File GAME_FOLDER; + public static File CALIBRATION_FILE; + + public static File getGameFolder() + { + return GAME_FOLDER; + } + + private static void initializeJoystickMappings() + { + if (CALIBRATION_FILE == null) + { + CALIBRATION_FILE = + new File(GAME_FOLDER, "controllerCalibration.properties"); + URL mappingUrl; + switch (JmeSystem.getPlatform()) + { + case Windows32: + case Windows64: + mappingUrl = Main.class. + getResource("/joystick-mapping.windows.properties"); + break; + case MacOSX32: + case MacOSX64: + case MacOSX_PPC32: + case MacOSX_PPC64: + mappingUrl = Main.class. + getResource("/joystick-mapping.osx.properties"); + break; + case Linux32: + case Linux64: + case Linux_ARM32: + case Linux_ARM64: + mappingUrl = Main.class. + getResource("/joystick-mapping.linux.properties"); + break; + case Android_ARM5: + case Android_ARM6: + case Android_ARM7: + case Android_ARM8: + case Android_X86: + case Android_Other: + mappingUrl = Main.class. + getResource("/joystick-mapping.android.properties"); + break; + case iOS_ARM: + case iOS_X86: + mappingUrl = Main.class. + getResource("/joystick-mapping.ios.properties"); + break; + default: + mappingUrl = null; + } + if (mappingUrl != null) + { + try + { + JoystickCompatibilityMappings + .loadMappingProperties(mappingUrl); + } + catch (IOException e) + { + logger.error("Unable to load joystick mappings for " + + mappingUrl, e); + } + } + mappingUrl = Main.class. + getResource("/joystick-mapping." + + JmeSystem.getPlatform().toString().toLowerCase() + + ".properties"); + if (mappingUrl != null) + { + try + { + JoystickCompatibilityMappings + .loadMappingProperties(mappingUrl); + } + catch (IOException e) + { + logger.error("Unable to load joystick mappings for " + + mappingUrl, e); + } + } + if (CALIBRATION_FILE.isFile()) + { + try + { + JoystickCompatibilityMappings.loadMappingProperties( + CALIBRATION_FILE.toURI().toURL()); + } + catch (IOException e) + { + logger.error("Unable to load joystick mappings.", e); + } + } + } + } + + public static void main(String[] args) + { + Main app; + AppSettings settings; + app = new Main(); + settings = new AppSettings(true); + settings.setTitle("Joystick Preview"); + settings.setUseJoysticks(true); + settings.setEmulateMouse(true); + settings.setVSync(true); + settings.setWidth(1280); + settings.setHeight(720); + app.setSettings(settings); + app.start(); + } + + private Node calibrateButton; + + public Main() + { + super(new StatsAppState(), new DebugKeysAppState(), + new JoystickPreviewScreen()); + } + + @Override + public void initialize() + { + final File[] possibleGameDirs = + new File[]{new File(System.getProperty("user.dir")), + new File(System.getProperty("user.home")), + JmeSystem.getStorageFolder( + JmeSystem.StorageFolderType.External)}; + int i, l; + if (GAME_FOLDER == null) + { + for (i = 0, l = possibleGameDirs.length; i < l; i++) + { + GAME_FOLDER = possibleGameDirs[i]; + if (!GAME_FOLDER.isDirectory()) + { + if (!GAME_FOLDER.mkdir()) + { + logger.warn("Cannot make " + GAME_FOLDER); + continue; + } + } + if (!GAME_FOLDER.canWrite()) + { + logger.warn("Cannot write to " + GAME_FOLDER); + continue; + } + break; + } + if (i == l) + { + throw new RuntimeException( + "Could not create game directory folder."); + } + } + /* + * Add custom joystick mappings before the input manager is loaded. + */ + initializeJoystickMappings(); + super.initialize(); + } + + @Override + public void simpleInitApp() + { + this.calibrateButton = + GUIUtils.createButton(this.getAssetManager(), this.guiFont, + this.getContext().getTouchInput() != null, "calibrate", + "Calibrate Gamepad"); + } + + @Override + public void simpleUpdate(float tpf) + { + JoystickPreviewScreen screen = + this.getStateManager().getState(JoystickPreviewScreen.class); + if (this.calibrateButton.getParent() == null && screen != null) + { + this.guiNode.attachChild(this.calibrateButton); + this.calibrateButton.setLocalTranslation( + (this.getCamera().getWidth() - + ((BitmapText) this.calibrateButton.getChild(1)) + .getLineWidth() - 10) / 2F, + this.getCamera().getHeight(), 0); + this.inputManager.addListener(this, screen.CLICK_MAPPING); + } + else if (this.calibrateButton.getParent() != null && screen == null) + { + this.guiNode.detachChild(this.calibrateButton); + this.inputManager.removeListener(this); + } + } + + @Override + public void onAction(String name, boolean isPressed, float tpf) + { + String buttonId; + JoystickPreviewScreen screen = + this.getStateManager().getState(JoystickPreviewScreen.class); + if (screen != null && name.equals(screen.CLICK_MAPPING)) + { + buttonId = GUIUtils.handleButtonPress(this.calibrateButton, + this.getInputManager().getCursorPosition(), isPressed); + if (!isPressed && "calibrate".equals(buttonId)) + { + this.getStateManager().detach(screen); + this.getStateManager() + .attach(new CalibrateInputScreen(CALIBRATION_FILE)); + } + } + } + + @Override + public void restart() + { + super.restart(); + this.enqueue(() -> { + JoystickPreviewScreen previewScreen = this.getStateManager() + .getState(JoystickPreviewScreen.class); + CalibrateInputScreen calibrateScreen = + this.getStateManager().getState(CalibrateInputScreen.class); + if (previewScreen != null) + { + previewScreen.resize(); + } + if (calibrateScreen != null) + { + calibrateScreen.resize(); + } + this.calibrateButton.setLocalTranslation( + (this.getCamera().getWidth() - + ((BitmapText) this.calibrateButton.getChild(1)) + .getLineWidth() - 10) / 2F, + this.getCamera().getHeight(), 0); + }); + } +} diff --git a/android/src/main/java/markil3/controller/MainActivity.java b/android/src/main/java/markil3/controller/MainActivity.java index 1876357..27a58fb 100644 --- a/android/src/main/java/markil3/controller/MainActivity.java +++ b/android/src/main/java/markil3/controller/MainActivity.java @@ -1,10 +1,8 @@ package markil3.controller; -import android.content.res.Configuration; import android.os.Bundle; import com.jme3.app.AndroidHarness; -import com.jme3.system.AppSettings; import java.util.logging.Level; import java.util.logging.LogManager; diff --git a/build.gradle b/build.gradle index 1eaa44a..cd87bc6 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ ext { jme3 = [version: '3.3.2-stable', g: 'org.jmonkeyengine'] versionNumber = 2 } -version = "1.1" +version = "1.2" task run { doFirst { diff --git a/desktop/build.gradle b/desktop/build.gradle index b8a9618..a589c9f 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -20,15 +20,41 @@ plugins { [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' +//def lwjglVersion = '3.2.3' + dependencies { // Logging - implementation "org.slf4j:slf4j-api:1.7.15" + implementation "org.slf4j:slf4j-api:1.7.30" implementation "org.slf4j:slf4j-simple:1.7.5" implementation project(':library') implementation "${jme3.g}:jme3-core:${jme3.version}" implementation "${jme3.g}:jme3-desktop:${jme3.version}" implementation "${jme3.g}:jme3-lwjgl3:${jme3.version}" +// implementation rootProject.files('libs/jme3-core.jar') +// implementation rootProject.files('libs/jme3-desktop.jar') +// implementation rootProject.files('libs/jme3-lwjgl3.jar') +// implementation "org.lwjgl:lwjgl:${lwjglVersion}" +// implementation "org.lwjgl:lwjgl-glfw:${lwjglVersion}" +// implementation "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}" +// implementation "org.lwjgl:lwjgl-openal:${lwjglVersion}" +// implementation "org.lwjgl:lwjgl-opencl:${lwjglVersion}" +// implementation "org.lwjgl:lwjgl-opengl:${lwjglVersion}" +// runtime "org.lwjgl:lwjgl:${lwjglVersion}:natives-windows" +// runtime "org.lwjgl:lwjgl:${lwjglVersion}:natives-linux" +// runtime "org.lwjgl:lwjgl:${lwjglVersion}:natives-macos" +// runtime "org.lwjgl:lwjgl-glfw:${lwjglVersion}:natives-windows" +// runtime "org.lwjgl:lwjgl-glfw:${lwjglVersion}:natives-linux" +// runtime "org.lwjgl:lwjgl-glfw:${lwjglVersion}:natives-macos" +// runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-windows" +// runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-linux" +// runtime "org.lwjgl:lwjgl-jemalloc:${lwjglVersion}:natives-macos" +// runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-windows" +// runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-linux" +// runtime "org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-macos" +// runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-windows" +// runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-linux" +// runtime "org.lwjgl:lwjgl-openal:${lwjglVersion}:natives-macos" } // Define the main class for the application @@ -38,7 +64,7 @@ mainClassName = 'markil3.controller.Main' * TODO - The default zipped distributions are a bit of a mess. */ jar { - baseName rootProject.name + baseName rootProject.name + "-desktop" version rootProject.version manifest { attributes "Main-Class": mainClassName, diff --git a/desktopLegacy/build.gradle b/desktopLegacy/build.gradle index 3eebf97..69a6978 100644 --- a/desktopLegacy/build.gradle +++ b/desktopLegacy/build.gradle @@ -22,9 +22,18 @@ plugins { dependencies { implementation(project(':desktop')) { - exclude group: jme3.g, module: "jme3-lwjgl3" + exclude module: "jme3-lwjgl3" + exclude group: "org.lwjgl" } implementation "${jme3.g}:jme3-lwjgl:${jme3.version}" +// implementation rootProject.files('libs/jme3-lwjgl.jar') +// implementation 'org.lwjgl.lwjgl:lwjgl:2.9.3' +// /* +// * Upgrades the default jinput-2.0.5 to jinput-2.0.9 to fix a bug with gamepads on Linux. +// * See https://hub.jmonkeyengine.org/t/linux-gamepad-input-on-jme3-lwjgl-splits-input-between-two-logical-gamepads +// */ +// implementation 'net.java.jinput:jinput:2.0.9' +// implementation 'net.java.jinput:jinput:2.0.9:natives-all' } // Define the main class for the application diff --git a/library/build.gradle b/library/build.gradle index 0151f60..aed5afb 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -18,11 +18,13 @@ targetCompatibility = "1.8" dependencies { // Logging - implementation "org.slf4j:slf4j-api:1.7.15" + implementation "org.slf4j:slf4j-api:1.7.30" implementation "org.slf4j:slf4j-simple:1.7.5" implementation "${jme3.g}:jme3-core:${jme3.version}" implementation "${jme3.g}:jme3-testdata:${jme3.version}" +// implementation rootProject.files('libs/jme3-core.jar') +// implementation rootProject.files('libs/jme3-testdata.jar') } processResources {