update to LibGDX 1.13.0, add ForgeAndroidApplication (modified AndroidApplication)

This commit is contained in:
Anthony Calosa
2024-10-18 19:44:30 +08:00
parent e6caed4ced
commit c1779a55d5
38 changed files with 568 additions and 21 deletions

View File

@@ -109,36 +109,36 @@
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-platform</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<classifier>natives-desktop</classifier>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-freetype</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-backend-lwjgl</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-tools</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-freetype-platform</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<classifier>natives-desktop</classifier>
</dependency>
<dependency>

View File

@@ -41,9 +41,14 @@ public class EditorMainWindow extends JFrame {
}
BorderLayout layout=new BorderLayout();
JToolBar toolBar = new JToolBar("toolbar");
JButton newButton=new JButton("open ParticleEditor");
newButton.addActionListener(e -> EventQueue.invokeLater(ParticleEditor::new));
toolBar.add(newButton);
// refer to removal of Swing Particle Editor: https://github.com/libgdx/libgdx/issues/7285
//todo add New Particle Editor here (needs Java 11+): https://github.com/libgdx/gdx-particle-editor
//JButton newButton=new JButton("open ParticleEditor");
//newButton.addActionListener(e -> EventQueue.invokeLater(ParticleEditor::new));
JButton quit = new JButton("Quit");
quit.addActionListener(e-> System.exit(0));
//toolBar.add(newButton);
toolBar.add(quit);
setLayout(layout);
toolBar.setFloatable(false);
add(toolBar, BorderLayout.NORTH);

Binary file not shown.

Binary file not shown.

View File

@@ -144,7 +144,7 @@
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-backend-android</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<scope>system</scope>
<systemPath>${pom.basedir}/libs/gdx-backend-android.jar</systemPath>
</dependency>

View File

@@ -0,0 +1,537 @@
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 com.badlogic.gdx.backends.android;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import com.badlogic.gdx.*;
// androidx dependencies disabled so it will not crash Forge app on startup
//import com.badlogic.gdx.backends.android.keyboardheight.AndroidXKeyboardHeightProvider;
//import com.badlogic.gdx.backends.android.keyboardheight.KeyboardHeightProvider;
//import com.badlogic.gdx.backends.android.keyboardheight.StandardKeyboardHeightProvider;
import com.badlogic.gdx.backends.android.surfaceview.FillResolutionStrategy;
import com.badlogic.gdx.utils.*;
/** A modified implementation of the {@link Application} interface for Android - Forge app. Create an {@link Activity} that derives from this class.
* In the {@link Activity#onCreate(Bundle)} method call the {@link #initialize(ApplicationListener)} method specifying the
* configuration for the GLSurfaceView.
*
* @author mzechner */
public class ForgeAndroidApplication extends Activity implements AndroidApplicationBase {
protected AndroidGraphics graphics;
protected AndroidInput input;
protected AndroidAudio audio;
protected AndroidFiles files;
protected AndroidNet net;
protected AndroidClipboard clipboard;
protected ApplicationListener listener;
public Handler handler;
protected boolean firstResume = true;
protected final Array<Runnable> runnables = new Array<Runnable>();
protected final Array<Runnable> executedRunnables = new Array<Runnable>();
protected final SnapshotArray<LifecycleListener> lifecycleListeners = new SnapshotArray<LifecycleListener>(
LifecycleListener.class);
private final Array<AndroidEventListener> androidEventListeners = new Array<AndroidEventListener>();
protected int logLevel = LOG_INFO;
protected ApplicationLogger applicationLogger;
protected boolean useImmersiveMode = false;
private int wasFocusChanged = -1;
private boolean isWaitingForAudio = false;
//private KeyboardHeightProvider keyboardHeightProvider;
protected boolean renderUnderCutout = false;
/** This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get
* input, render via OpenGL and so on. Uses a default {@link AndroidApplicationConfiguration}.
*
* @param listener the {@link ApplicationListener} implementing the program logic **/
public void initialize (ApplicationListener listener) {
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(listener, config);
}
/** This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get
* input, render via OpenGL and so on. You can configure other aspects of the application with the rest of the fields in the
* {@link AndroidApplicationConfiguration} instance.
*
* @param listener the {@link ApplicationListener} implementing the program logic
* @param config the {@link AndroidApplicationConfiguration}, defining various settings of the application (use accelerometer,
* etc.). */
public void initialize (ApplicationListener listener, AndroidApplicationConfiguration config) {
init(listener, config, false);
}
/** This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get
* input, render via OpenGL and so on. Uses a default {@link AndroidApplicationConfiguration}.
* <p>
* Note: you have to add the returned view to your layout!
*
* @param listener the {@link ApplicationListener} implementing the program logic
* @return the GLSurfaceView of the application */
public View initializeForView (ApplicationListener listener) {
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
return initializeForView(listener, config);
}
/** This method has to be called in the {@link Activity#onCreate(Bundle)} method. It sets up all the things necessary to get
* input, render via OpenGL and so on. You can configure other aspects of the application with the rest of the fields in the
* {@link AndroidApplicationConfiguration} instance.
* <p>
* Note: you have to add the returned view to your layout!
*
* @param listener the {@link ApplicationListener} implementing the program logic
* @param config the {@link AndroidApplicationConfiguration}, defining various settings of the application (use accelerometer,
* etc.).
* @return the GLSurfaceView of the application */
public View initializeForView (ApplicationListener listener, AndroidApplicationConfiguration config) {
init(listener, config, true);
return graphics.getView();
}
private void init (ApplicationListener listener, AndroidApplicationConfiguration config, boolean isForView) {
if (this.getVersion() < MINIMUM_SDK) {
throw new GdxRuntimeException("libGDX requires Android API Level " + MINIMUM_SDK + " or later.");
}
config.nativeLoader.load();
setApplicationLogger(new AndroidApplicationLogger());
graphics = new AndroidGraphics(this, config,
config.resolutionStrategy == null ? new FillResolutionStrategy() : config.resolutionStrategy);
input = createInput(this, this, graphics.view, config);
audio = createAudio(this, config);
files = createFiles();
net = new AndroidNet(this, config);
this.listener = listener;
this.handler = new Handler();
this.useImmersiveMode = config.useImmersiveMode;
this.clipboard = new AndroidClipboard(this);
this.renderUnderCutout = config.renderUnderCutout;
// Add a specialized audio lifecycle listener
addLifecycleListener(new LifecycleListener() {
@Override
public void resume () {
// No need to resume audio here
}
@Override
public void pause () {
audio.pause();
}
@Override
public void dispose () {
audio.dispose();
}
});
Gdx.app = this;
Gdx.input = this.getInput();
Gdx.audio = this.getAudio();
Gdx.files = this.getFiles();
Gdx.graphics = this.getGraphics();
Gdx.net = this.getNet();
if (!isForView) {
try {
requestWindowFeature(Window.FEATURE_NO_TITLE);
} catch (Exception ex) {
log("AndroidApplication", "Content already displayed, cannot request FEATURE_NO_TITLE", ex);
}
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
setContentView(graphics.getView(), createLayoutParams());
}
createWakeLock(config.useWakelock);
useImmersiveMode(this.useImmersiveMode);
if (this.useImmersiveMode) {
AndroidVisibilityListener vlistener = new AndroidVisibilityListener();
vlistener.createListener(this);
}
// detect an already connected bluetooth keyboardAvailable
if (getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS) input.setKeyboardAvailable(true);
setLayoutInDisplayCutoutMode(this.renderUnderCutout);
// As per the docs, it might work unreliable < 23 https://developer.android.com/jetpack/androidx/releases/core#1.5.0-alpha02
// So, I guess since 23 is pretty rare we can use the old API for the users
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
keyboardHeightProvider = new AndroidXKeyboardHeightProvider(this);
} else {
keyboardHeightProvider = new StandardKeyboardHeightProvider(this);
}*/
}
protected FrameLayout.LayoutParams createLayoutParams () {
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
android.view.ViewGroup.LayoutParams.MATCH_PARENT);
layoutParams.gravity = Gravity.CENTER;
return layoutParams;
}
protected void createWakeLock (boolean use) {
if (use) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
@TargetApi(Build.VERSION_CODES.P)
private void setLayoutInDisplayCutoutMode (boolean render) {
if (render && getVersion() >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
}
@Override
public void onWindowFocusChanged (boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
useImmersiveMode(this.useImmersiveMode);
if (hasFocus) {
this.wasFocusChanged = 1;
if (this.isWaitingForAudio) {
this.audio.resume();
this.isWaitingForAudio = false;
}
} else {
this.wasFocusChanged = 0;
}
}
@Override
public void useImmersiveMode (boolean use) {
if (!use) return;
View view = getWindow().getDecorView();
int code = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
view.setSystemUiVisibility(code);
}
@Override
protected void onPause () {
boolean isContinuous = graphics.isContinuousRendering();
boolean isContinuousEnforced = AndroidGraphics.enforceContinuousRendering;
// from here we don't want non continuous rendering
AndroidGraphics.enforceContinuousRendering = true;
graphics.setContinuousRendering(true);
// calls to setContinuousRendering(false) from other thread (ex: GLThread)
// will be ignored at this point...
graphics.pause();
input.onPause();
if (isFinishing()) {
graphics.clearManagedCaches();
graphics.destroy();
}
AndroidGraphics.enforceContinuousRendering = isContinuousEnforced;
graphics.setContinuousRendering(isContinuous);
graphics.onPauseGLSurfaceView();
super.onPause();
//keyboardHeightProvider.setKeyboardHeightObserver(null);
}
@Override
protected void onResume () {
Gdx.app = this;
Gdx.input = this.getInput();
Gdx.audio = this.getAudio();
Gdx.files = this.getFiles();
Gdx.graphics = this.getGraphics();
Gdx.net = this.getNet();
input.onResume();
if (graphics != null) {
graphics.onResumeGLSurfaceView();
}
if (!firstResume) {
graphics.resume();
} else
firstResume = false;
this.isWaitingForAudio = true;
if (this.wasFocusChanged == 1 || this.wasFocusChanged == -1) {
this.audio.resume();
this.isWaitingForAudio = false;
}
super.onResume();
/*keyboardHeightProvider.setKeyboardHeightObserver((DefaultAndroidInput)Gdx.input);
((AndroidGraphics)getGraphics()).getView().post(new Runnable() {
@Override
public void run () {
keyboardHeightProvider.start();
}
});*/
}
@Override
protected void onDestroy () {
super.onDestroy();
//keyboardHeightProvider.close();
}
@Override
public ApplicationListener getApplicationListener () {
return listener;
}
@Override
public Audio getAudio () {
return audio;
}
@Override
public AndroidInput getInput () {
return input;
}
@Override
public Files getFiles () {
return files;
}
@Override
public Graphics getGraphics () {
return graphics;
}
@Override
public Net getNet () {
return net;
}
@Override
public ApplicationType getType () {
return ApplicationType.Android;
}
@Override
public int getVersion () {
return android.os.Build.VERSION.SDK_INT;
}
@Override
public long getJavaHeap () {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
@Override
public long getNativeHeap () {
return Debug.getNativeHeapAllocatedSize();
}
@Override
public Preferences getPreferences (String name) {
return new AndroidPreferences(getSharedPreferences(name, Context.MODE_PRIVATE));
}
@Override
public Clipboard getClipboard () {
return clipboard;
}
@Override
public void postRunnable (Runnable runnable) {
synchronized (runnables) {
runnables.add(runnable);
Gdx.graphics.requestRendering();
}
}
@Override
public void onConfigurationChanged (Configuration config) {
super.onConfigurationChanged(config);
boolean keyboardAvailable = false;
if (config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) keyboardAvailable = true;
input.setKeyboardAvailable(keyboardAvailable);
}
@Override
public void exit () {
handler.post(new Runnable() {
@Override
public void run () {
ForgeAndroidApplication.this.finish();
}
});
}
@Override
public void debug (String tag, String message) {
if (logLevel >= LOG_DEBUG) getApplicationLogger().debug(tag, message);
}
@Override
public void debug (String tag, String message, Throwable exception) {
if (logLevel >= LOG_DEBUG) getApplicationLogger().debug(tag, message, exception);
}
@Override
public void log (String tag, String message) {
if (logLevel >= LOG_INFO) getApplicationLogger().log(tag, message);
}
@Override
public void log (String tag, String message, Throwable exception) {
if (logLevel >= LOG_INFO) getApplicationLogger().log(tag, message, exception);
}
@Override
public void error (String tag, String message) {
if (logLevel >= LOG_ERROR) getApplicationLogger().error(tag, message);
}
@Override
public void error (String tag, String message, Throwable exception) {
if (logLevel >= LOG_ERROR) getApplicationLogger().error(tag, message, exception);
}
@Override
public void setLogLevel (int logLevel) {
this.logLevel = logLevel;
}
@Override
public int getLogLevel () {
return logLevel;
}
@Override
public void setApplicationLogger (ApplicationLogger applicationLogger) {
this.applicationLogger = applicationLogger;
}
@Override
public ApplicationLogger getApplicationLogger () {
return applicationLogger;
}
@Override
public void addLifecycleListener (LifecycleListener listener) {
synchronized (lifecycleListeners) {
lifecycleListeners.add(listener);
}
}
@Override
public void removeLifecycleListener (LifecycleListener listener) {
synchronized (lifecycleListeners) {
lifecycleListeners.removeValue(listener, true);
}
}
@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// forward events to our listeners if there are any installed
synchronized (androidEventListeners) {
for (int i = 0; i < androidEventListeners.size; i++) {
androidEventListeners.get(i).onActivityResult(requestCode, resultCode, data);
}
}
}
/** Adds an event listener for Android specific event such as onActivityResult(...). */
public void addAndroidEventListener (AndroidEventListener listener) {
synchronized (androidEventListeners) {
androidEventListeners.add(listener);
}
}
/** Removes an event listener for Android specific event such as onActivityResult(...). */
public void removeAndroidEventListener (AndroidEventListener listener) {
synchronized (androidEventListeners) {
androidEventListeners.removeValue(listener, true);
}
}
@Override
public Context getContext () {
return this;
}
@Override
public Array<Runnable> getRunnables () {
return runnables;
}
@Override
public Array<Runnable> getExecutedRunnables () {
return executedRunnables;
}
@Override
public SnapshotArray<LifecycleListener> getLifecycleListeners () {
return lifecycleListeners;
}
@Override
public Window getApplicationWindow () {
return this.getWindow();
}
@Override
public Handler getHandler () {
return this.handler;
}
@Override
public AndroidAudio createAudio (Context context, AndroidApplicationConfiguration config) {
if (!config.disableAudio)
return new DefaultAndroidAudio(context, config);
else
return new DisabledAndroidAudio();
}
@Override
public AndroidInput createInput (Application activity, Context context, Object view, AndroidApplicationConfiguration config) {
return new DefaultAndroidInput(this, this, graphics.view, config);
}
protected AndroidFiles createFiles () {
this.getFilesDir(); // workaround for Android bug #10515463
return new DefaultAndroidFiles(this.getAssets(), this, true);
}
/*public KeyboardHeightProvider getKeyboardHeightProvider () {
return keyboardHeightProvider;
}*/
}

View File

@@ -51,7 +51,7 @@ import android.widget.TableRow;
import android.widget.TextView;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Version;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.ForgeAndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.badlogic.gdx.backends.android.AndroidAudio;
import com.badlogic.gdx.backends.android.AsynchronousAndroidAudio;
@@ -72,7 +72,7 @@ import java.io.OutputStream;
import java.text.Normalizer;
import java.util.ArrayList;
public class Main extends AndroidApplication {
public class Main extends ForgeAndroidApplication {
private AndroidAdapter Gadapter;
private ArrayList<String> gamepads;
private AndroidClipboard androidClipboard;

Binary file not shown.

Binary file not shown.

View File

@@ -67,7 +67,7 @@
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-backend-robovm</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
</dependency>
</dependencies>
</project>

View File

@@ -177,18 +177,18 @@
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-backend-lwjgl3</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-platform</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<classifier>natives-desktop</classifier>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-freetype-platform</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<classifier>natives-desktop</classifier>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
@@ -211,7 +211,7 @@
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-box2d-platform</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
<classifier>natives-desktop</classifier>
</dependency>
</dependencies>

View File

@@ -6,11 +6,13 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Clipboard;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3WindowAdapter;
import com.badlogic.gdx.graphics.glutils.HdpiMode;
import com.badlogic.gdx.utils.SharedLibraryLoader;
import forge.Forge;
import forge.adventure.util.Config;
import forge.assets.AssetsDownloader;
import forge.util.BuildInfo;
import forge.util.FileUtil;
import org.lwjgl.system.Configuration;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -41,7 +43,10 @@ public class GameLauncher {
// Place the file "switch_orientation.ini" to your assets folder to make the game switch to landscape orientation (unless desktopMode = true)
String switchOrientationFile = assetsDir + "switch_orientation.ini";
// This should fix MAC-OS startup without the need for -XstartOnFirstThread parameter
if (SharedLibraryLoader.isMac) {
Configuration.GLFW_LIBRARY_NAME.set("glfw_async");
}
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setResizable(false);
ApplicationListener start = Forge.getApp(new Lwjgl3Clipboard(), new Main.DesktopAdapter(switchOrientationFile),//todo get totalRAM && isTabletDevice

Binary file not shown.

View File

@@ -75,12 +75,12 @@
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-freetype</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>com.github.raeleus.TenPatch</groupId>
@@ -97,7 +97,7 @@
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-box2d</artifactId>
<version>1.12.1</version>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>com.badlogicgames.gdx</groupId>