From 8c0276c562c769ead0e127a4e7d8319d63e59a2d Mon Sep 17 00:00:00 2001 From: megboyzz Date: Thu, 28 Aug 2025 12:49:40 +0300 Subject: [PATCH] =?UTF-8?q?=D0=91=D0=BE=D0=BB=D0=B5=D0=B5=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D0=B5=20=D1=81=D1=82=D0=B0=D0=B1=D0=B8=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/deploymentTargetSelector.xml | 8 + .idea/misc.xml | 3 +- app/src/main/AndroidManifest.xml | 2 +- app/src/main/java/com/ea/EAIO/EAIO.kt | 31 +- .../java/com/ea/EAMIO/StorageDirectory.kt | 60 +- .../java/com/ea/ironmonkey/BitmapGraphics.kt | 88 +- .../com/ea/ironmonkey/DrawFrameListener.kt | 9 +- .../com/ea/ironmonkey/GameActivityMain.kt | 1529 +++++++---------- app/src/main/java/com/ea/ironmonkey/Log.kt | 56 +- .../java/com/ea/ironmonkey/MogaController.kt | 125 +- .../main/java/com/ea/ironmonkey/ObbHelper.kt | 15 +- .../com/ea/ironmonkey/PermissionsActivity.kt | 276 +-- .../main/java/com/ea/ironmonkey/RunLoop.kt | 71 +- .../java/com/ea/ironmonkey/SplashScreen.kt | 341 ++-- .../ea/ironmonkey/domain/AssetLocationType.kt | 7 + .../java/com/ea/ironmonkey/domain/FSNode.kt | 11 + 16 files changed, 1228 insertions(+), 1404 deletions(-) create mode 100644 app/src/main/java/com/ea/ironmonkey/domain/AssetLocationType.kt create mode 100644 app/src/main/java/com/ea/ironmonkey/domain/FSNode.kt diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index b268ef3..548f36a 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,6 +4,14 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index 1a1bf72..74dd639 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,7 @@ + - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 53b05a2..814c3d1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -26,7 +26,7 @@ 2 + Environment.MEDIA_MOUNTED_READ_ONLY == externalStorageState -> 1 + else -> 0 } - return "mounted_ro".equals(externalStorageState) ? 1 : 0; } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/ea/ironmonkey/BitmapGraphics.kt b/app/src/main/java/com/ea/ironmonkey/BitmapGraphics.kt index cd78220..6aa9f14 100644 --- a/app/src/main/java/com/ea/ironmonkey/BitmapGraphics.kt +++ b/app/src/main/java/com/ea/ironmonkey/BitmapGraphics.kt @@ -1,64 +1,58 @@ -package com.ea.ironmonkey; +package com.ea.ironmonkey -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.Typeface; -import android.util.Log; +import android.content.res.AssetManager +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.PorterDuff +import android.graphics.Typeface +import androidx.core.graphics.createBitmap +import com.ea.ironmonkey.GameActivityMain.Companion.mAssetLocationType +import com.ea.ironmonkey.domain.AssetLocationType -import nfs.mod.mpcore.MultiplayerCore; +class BitmapGraphics(width: Int, height: Int) { + val bitmap = createBitmap(width, height) + val canvas = Canvas() - -public class BitmapGraphics { - private Bitmap bitmap; - private Canvas canvas = new Canvas(); - - public BitmapGraphics(int i, int i2) { - this.bitmap = Bitmap.createBitmap(i, i2, Bitmap.Config.ARGB_8888); - this.canvas.setBitmap(this.bitmap); + init { + canvas.setBitmap(bitmap) } - public Bitmap getBitmap() { - return this.bitmap; + fun clear() { + canvas.drawColor(0, PorterDuff.Mode.CLEAR) } - public Canvas getCanvas() { - return this.canvas; - } + fun drawString(paint: Paint, text: String, x: Int, y: Int) = canvas.drawText(text, x.toFloat(), y.toFloat(), paint) - public void clear() { - this.canvas.drawColor(0, PorterDuff.Mode.CLEAR); - } + companion object { + private fun createPaint(typeface: Typeface?, f: Float): Paint { + val paint = Paint() + paint.setTypeface(typeface) + paint.textSize = f + paint.setColor(-1) + paint.isAntiAlias = true + return paint + } - private static Paint createPaint(Typeface typeface, float f) { - Paint paint = new Paint(); - paint.setTypeface(typeface); - paint.setTextSize(f); - paint.setColor(-1); - paint.setAntiAlias(true); - return paint; - } + @JvmStatic + fun createPaintFromFamilyName(familyName: String, f: Float): Paint { + return createPaint(Typeface.create(familyName, Typeface.NORMAL), f) + } - public static Paint createPaintFromFamilyName(String str, float f) { - return createPaint(Typeface.create(str, 0), f); - } + @JvmStatic + fun createPaintFromFile(str: String, f: Float): Paint { + return createPaint(internalCreateFromFile(str), f) + } - public static Paint createPaintFromFile(String str, float f) { - return createPaint(internalCreateFromFile(str), f); - } - - private static Typeface internalCreateFromFile(String str) { - if (GameActivityMain.instance.useAssetsFileSystem()) { + private fun internalCreateFromFile(str: String): Typeface? { + var str = str + /*if (mAssetLocationType != AssetLocationType.EXTERNAL) { + return Typeface.createFromFile(str); + }*/ if (str.startsWith("/")) { str = str.substring(1); } - return Typeface.createFromAsset(GameActivityMain.instance.getAssetManager(), str); - } - return Typeface.createFromFile(str); - } + return Typeface.createFromAsset(GameActivityMain.assetManager, str); - public void drawString(Paint paint, String str, int x, int y) { - this.canvas.drawText(str, x, y, paint); + } } } diff --git a/app/src/main/java/com/ea/ironmonkey/DrawFrameListener.kt b/app/src/main/java/com/ea/ironmonkey/DrawFrameListener.kt index ae1a993..14a3590 100644 --- a/app/src/main/java/com/ea/ironmonkey/DrawFrameListener.kt +++ b/app/src/main/java/com/ea/ironmonkey/DrawFrameListener.kt @@ -1,8 +1,7 @@ -package com.ea.ironmonkey; +package com.ea.ironmonkey -import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL10 - -public interface DrawFrameListener { - void onDrawFrame(GL10 gl10); +interface DrawFrameListener { + fun onDrawFrame(gl10: GL10?) } diff --git a/app/src/main/java/com/ea/ironmonkey/GameActivityMain.kt b/app/src/main/java/com/ea/ironmonkey/GameActivityMain.kt index c3716db..ba6d408 100644 --- a/app/src/main/java/com/ea/ironmonkey/GameActivityMain.kt +++ b/app/src/main/java/com/ea/ironmonkey/GameActivityMain.kt @@ -1,1070 +1,787 @@ -package com.ea.ironmonkey; +package com.ea.ironmonkey -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.ActivityManager; -import android.app.AlertDialog; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.graphics.Rect; -import android.hardware.Sensor; -import android.hardware.SensorManager; -import android.media.AudioManager; -import android.net.Uri; -import android.opengl.GLES20; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.os.Handler; -import android.os.PowerManager; -import android.os.Process; -import android.provider.Settings; -import android.util.DisplayMetrics; -import android.view.Display; -import android.view.DisplayCutout; -import android.view.KeyEvent; -import android.view.OrientationEventListener; -import android.view.View; -import android.view.ViewParent; -import android.view.WindowManager; -import android.view.inputmethod.InputMethodManager; -import android.widget.FrameLayout; +import android.annotation.SuppressLint +import android.app.ActivityManager +import android.app.AlertDialog +import android.content.DialogInterface +import android.content.Intent +import android.content.pm.ActivityInfo +import android.content.pm.PackageManager +import android.content.res.AssetManager +import android.content.res.Configuration +import android.hardware.SensorManager +import android.media.AudioManager +import android.net.Uri +import android.opengl.GLES20 +import android.os.Build +import android.os.Bundle +import android.os.Environment +import android.os.Handler +import android.os.PowerManager +import android.os.PowerManager.WakeLock +import android.os.Process +import android.provider.Settings +import android.util.DisplayMetrics +import android.view.DisplayCutout +import android.view.KeyEvent +import android.view.OrientationEventListener +import android.view.View +import android.view.ViewParent +import android.view.WindowManager +import android.view.inputmethod.InputMethodManager +import android.widget.FrameLayout +import androidx.appcompat.app.AppCompatActivity +import com.ea.EAIO.EAIO +import com.ea.EAMIO.StorageDirectory +import com.ea.ironmonkey.Log.d +import com.ea.ironmonkey.Log.i +import com.ea.ironmonkey.Log.setEnable +import com.ea.ironmonkey.Log.w +import com.ea.ironmonkey.ObbHelper.getObbFileName +import com.ea.ironmonkey.domain.AssetLocationType +import com.ea.nimble.ApplicationLifecycle +import com.ea.nimble.Global +import com.google.gson.annotations.SerializedName +import nfs.mod.mpcore.MultiplayerCore.loadCore +import org.fmod.FMODAudioDevice +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream +import java.util.Locale +import java.util.concurrent.TimeUnit +import javax.microedition.khronos.egl.EGLConfig +import javax.microedition.khronos.opengles.GL10 +import androidx.core.net.toUri +import com.ea.ironmonkey.domain.FSNode +import org.apache.http.BuildConfig +import kotlin.system.exitProcess -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ComponentActivity; +class GameActivityMain : AppCompatActivity(), DrawFrameListener { + lateinit var accelerometer: Accelerometer + private lateinit var gameGLSurfaceView: GameGLSurfaceView + private lateinit var gameRenderer: GameRenderer + private lateinit var handler: Handler + private lateinit var mAd: AlertDialog.Builder + private lateinit var mFMODAudioDevice: FMODAudioDevice + private lateinit var mFrameLayout: FrameLayout + //private lateinit var mOrientationListener: OrientationEventListener + private val mResources: MutableMap<*, *>? = null + private lateinit var mWakeLock: WakeLock + + lateinit var runLoop: RunLoop + private var splash = SplashScreen(this) + private var splashCounter = 0 + private var splashDelay: Long = 0 + private var splashTimer: Long = 0 -import com.ea.EAIO.EAIO; -import com.ea.EAMIO.StorageDirectory; -import com.ea.nimble.ApplicationLifecycle; -import com.ea.nimble.Global; -import com.google.gson.Gson; -import com.google.gson.annotations.SerializedName; -import com.google.gson.reflect.TypeToken; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.opengles.GL10; -import org.fmod.FMODAudioDevice; + private var laststate = 0 + private var isSleepModeEnabled = true + private var mRotation = 0 -import nfs.mod.mpcore.MultiplayerCore; - - -public class GameActivityMain extends AppCompatActivity implements DrawFrameListener { - private static final String DOWNLOAD_PROPERTIES = "downloadcontent/config.properties"; - public static final int LIFECYCLE_CREATED = 1; - public static final int LIFECYCLE_DESTROYED = 5; - public static final int LIFECYCLE_NONE = 0; - public static final int LIFECYCLE_RUNNING = 3; - public static final int LIFECYCLE_STARTED = 2; - public static final int LIFECYCLE_STOPPED = 4; - private static String SDCARD_DATA_FOLDER = ""; - public static final int STATE_ADC_PROCESS = 4; - public static final int STATE_ADC_START = 3; - public static final int STATE_FULL_PROCESS = 6; - public static final int STATE_FULL_START = 5; - public static final int STATE_GAME_START = 8; - public static final int STATE_GOOGLE_DRM = 2; - public static final int STATE_RESTORE_CONTEXT = 7; - public static final int STATE_SPLASH = 0; - public static final int STATE_SPLASH_PROCESS = 1; - public static final String TAG = "GameActivityMain"; - private static boolean assetsReady; - public static GameActivityMain instance; - private static boolean isAmazonDev; - private static AudioManager mAudioManager; - private static int oldState; - private static boolean sIsOtherMusicPlaying; - public static int state; - private Accelerometer accelerometer; - private GameGLSurfaceView gameGLSurfaceView; - private GameRenderer gameRenderer; - private Handler handler; - private int laststate; - private int lifecycle; - private AlertDialog.Builder mAd; - private FMODAudioDevice mFMODAudioDevice; - private FrameLayout mFrameLayout; - private OrientationEventListener mOrientationListener; - private Map mResources; - private PowerManager.WakeLock mWakeLock; - public int naturalOrientation; - private RunLoop runLoop; - private SplashScreen splash; - private int splashCounter; - private long splashDelay; - private long splashTimer; - private boolean isXperiaPlay = false; - private boolean isSleepModeEnabled = true; - private int mRotation = 0; - private AssetLocationType mAssetLocationType = AssetLocationType.EXTERNAL; - private String[] lifecycleNames = {"LIFECYCLE_NONE", "LIFECYCLE_CREATED", "LIFECYCLE_STARTED", "LIFECYCLE_RUNNING", "LIFECYCLE_STOPPED", "LIFECYCLE_DESTROYED"}; - - public File getSave() { - return save; + private fun updateRequestedOrientation(i: Int) { } - public void setSave(File save) { - this.save = save; - } + fun IsSystemKey(i: Int) = false - enum AssetLocationType { - EXTERNAL, - ASSETS, - OBB - } + companion object { + private const val DOWNLOAD_PROPERTIES = "downloadcontent/config.properties" + const val STATE_ADC_PROCESS: Int = 4 + const val STATE_ADC_START: Int = 3 + const val STATE_FULL_PROCESS: Int = 6 + const val STATE_FULL_START: Int = 5 + const val STATE_GAME_START: Int = 8 + const val STATE_GOOGLE_DRM: Int = 2 + const val STATE_RESTORE_CONTEXT: Int = 7 + const val STATE_SPLASH: Int = 0 + const val STATE_SPLASH_PROCESS: Int = 1 + const val TAG: String = "GameActivityMain" - private void updateRequestedOrientation(int i) { - } + // Нужен в BitmapGraphics (( + lateinit var assetManager: AssetManager - public boolean IsSystemKey(int i) { - if (i == 3 || i == 91) { - return true; + var mAssetLocationType = AssetLocationType.EXTERNAL + var isAssetsReady: Boolean = false + private var mAudioManager: AudioManager? = null + private var oldState = 0 + var isAnyMusicPlaying: Boolean = false + @JvmName("isAnyMusicPlaying") @JvmStatic get + private set + var state: Int = 0 + + fun isAtLeastAPI(i: Int): Boolean { + return Build.VERSION.SDK_INT >= i } - switch (i) { - case 5: - case 6: - return true; - default: - switch (i) { - case 24: - case 25: - case 26: - case 27: - return true; - default: - return false; - } + + @JvmStatic + fun GetDeviceName() = Build.MODEL + + val osVersion: String + @JvmStatic get() = Build.VERSION.RELEASE + + @JvmStatic + fun isAmazon() = false + + @JvmStatic + fun GetDefaultLanguage() = Locale.getDefault().toString().substring(0, 2) + + @JvmStatic + fun GetDeviceLocale(): String { + val upperCase = + Locale.getDefault().toString().replace('_', '-').uppercase(Locale.getDefault()) + d(TAG, "GetDeviceLocale locale = $upperCase") + return upperCase } + + @JvmStatic + fun GetApplicationVersion() = BuildConfig.VERSION_NAME } - public native void nativeOnCreate(); + fun useAssetsFileSystem(): Boolean { + return mAssetLocationType != AssetLocationType.EXTERNAL + } - public native void nativeOnDestroy(); + external fun nativeOnCreate() - public native void nativeOnMusicPlayerStateChanged(); + external fun nativeOnDestroy() - public native void nativeOnOrientationChange(int i); + external fun nativeOnMusicPlayerStateChanged() - public native void nativeOnPause(); + external fun nativeOnOrientationChange(i: Int) - public native void nativeOnPhysicalKeyDown(int i, int i2); + external fun nativeOnPause() - public native void nativeOnPhysicalKeyUp(int i, int i2); + external fun nativeOnPhysicalKeyDown(i: Int, i2: Int) - public native void nativeOnPhysicalKeyboardVisibilityChanged(boolean z); + external fun nativeOnPhysicalKeyUp(i: Int, i2: Int) - public native void nativeOnPhysicalNavigationVisibilityChanged(boolean z); + external fun nativeOnPhysicalKeyboardVisibilityChanged(z: Boolean) - public native void nativeOnRestart(); + external fun nativeOnPhysicalNavigationVisibilityChanged(z: Boolean) - public native void nativeOnResume(); + external fun nativeOnRestart() - public native void nativeOnStart(); + external fun nativeOnResume() - public native void nativeOnStop(); + external fun nativeOnStart() - public native boolean nativeRestoreContext(); + external fun nativeOnStop() - public native void nativeSurfaceChanged(GL10 gl10, int i, int i2); + external fun nativeRestoreContext(): Boolean - public native void nativeSurfaceCreated(GL10 gl10, EGLConfig eGLConfig); + external fun nativeSurfaceChanged(gl10: GL10?, i: Int, i2: Int) - @Override // android.app.Activity - public void onCreate(Bundle bundle) { - Log.setEnable(true); - Log.i(TAG, "onCreate"); - super.onCreate(bundle); - instance = this; - if (this.lifecycle == 5) { - Log.w(TAG, "onCreate called on destroyed app, finishing"); - finish(); - return; - } - if (this.lifecycle >= 1) { - Log.w(TAG, "onCreate ignored, lifecycle is already " + this.lifecycleNames[this.lifecycle]); - return; - } - this.handler = new Handler(); - setLifecycle(1); + external fun nativeSurfaceCreated(gl10: GL10?, eGLConfig: EGLConfig?) + + + public override fun onCreate(bundle: Bundle?) { + setEnable(true) + + Companion.assetManager = assets + + i(TAG, "onCreate") + super.onCreate(bundle) + + + handler = Handler() if (!isAtLeastAPI(18) && getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) } if (isAtLeastAPI(28)) { - getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; - getWindow().addFlags(67108864); + window.attributes.layoutInDisplayCutoutMode = + WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES + window.addFlags(67108864) } - getWindow().setFlags(1024, 1024); - requestWindowFeature(1); - this.mOrientationListener = new OrientationEventListener(getApplicationContext()) { - @Override - public void onOrientationChanged(int i) { - int rotation; - if (GameActivityMain.this.accelerometer == null || GameActivityMain.this.mRotation == (rotation = GameActivityMain.this.getWindow().getWindowManager().getDefaultDisplay().getRotation())) { - return; + window.setFlags(1024, 1024) + requestWindowFeature(1) + /*mOrientationListener = object : OrientationEventListener(applicationContext) { + override fun onOrientationChanged(i: Int) { + if (this@GameActivityMain.mRotation == (this@GameActivityMain.window + .windowManager.defaultDisplay.rotation + .also { this@GameActivityMain.mRotation = it }) + ) + if (Settings.System.getInt( + this@GameActivityMain.contentResolver, + "accelerometer_rotation", + 0 + ) == 1 || !isAtLeastAPI(18) + ) { + this@GameActivityMain.accelerometer.updateOrientation(this@GameActivityMain.mRotation) + this@GameActivityMain.nativeOnOrientationChange(this@GameActivityMain.mRotation) + d( + TAG, + "OrientationEventListener::onOrientationChanged mRotation = " + this@GameActivityMain.mRotation.toString() + ) + return } - GameActivityMain.this.mRotation = rotation; - if (Settings.System.getInt(GameActivityMain.this.getContentResolver(), "accelerometer_rotation", 0) == 1 || !GameActivityMain.isAtLeastAPI(18) || GameActivityMain.isAmazonDev) { - GameActivityMain.this.accelerometer.updateOrientation(GameActivityMain.this.mRotation); - GameActivityMain.this.nativeOnOrientationChange(GameActivityMain.this.mRotation); - Log.d(GameActivityMain.TAG, "OrientationEventListener::onOrientationChanged mRotation = " + Integer.toString(GameActivityMain.this.mRotation)); - return; - } - Log.d(GameActivityMain.TAG, "OrientationEventListener::onOrientationChanged rotation disabled!"); + d(TAG, "OrientationEventListener::onOrientationChanged rotation disabled!") } - }; - if (this.mOrientationListener.canDetectOrientation()) { - this.mOrientationListener.enable(); } - mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); - sIsOtherMusicPlaying = mAudioManager.isMusicActive(); - Log.i(TAG, "onCreate() isMusicActive = " + Boolean.toString(sIsOtherMusicPlaying)); - this.mFMODAudioDevice = new FMODAudioDevice(); + if (mOrientationListener.canDetectOrientation()) { + mOrientationListener.enable() + }*/ + mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager? + isAnyMusicPlaying = mAudioManager!!.isMusicActive() + i(TAG, "onCreate() isMusicActive = $isAnyMusicPlaying") + mFMODAudioDevice = FMODAudioDevice() - if (this.mAssetLocationType != AssetLocationType.ASSETS) { + if (mAssetLocationType != AssetLocationType.ASSETS) { try { - InputStream open2 = getResources().getAssets().open("obb.size"); - if (open2 != null) { - this.mAssetLocationType = AssetLocationType.OBB; - open2.close(); - } - } catch (IOException e2) { - Log.e(TAG, e2.getMessage()); + val open2 = getResources().assets.open("obb.size") + mAssetLocationType = AssetLocationType.OBB + open2.close() + } catch (e2: IOException) { + Log.e(TAG, e2.message!!) } } - SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); - Sensor defaultSensor = sensorManager.getDefaultSensor(1); - int rotation = getWindow().getWindowManager().getDefaultDisplay().getRotation(); - switch (rotation) { - case 0: - Log.d(TAG, "Orientation: ROTATION_0"); - break; - case 1: - Log.d(TAG, "Orientation: ROTATION_90"); - break; - case 2: - Log.d(TAG, "Orientation: ROTATION_180"); - break; - case 3: - Log.d(TAG, "Orientation: ROTATION_270"); - break; + val sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager + val defaultSensor = sensorManager.getDefaultSensor(1) + val rotation = window.getWindowManager().getDefaultDisplay().getRotation() + when (rotation) { + 0 -> d(TAG, "Orientation: ROTATION_0") + 1 -> d(TAG, "Orientation: ROTATION_90") + 2 -> d(TAG, "Orientation: ROTATION_180") + 3 -> d(TAG, "Orientation: ROTATION_270") } - this.mRotation = rotation; - updateRequestedOrientation(rotation); - if (defaultSensor != null) { - this.accelerometer = new Accelerometer(sensorManager, defaultSensor, rotation); - } - this.gameGLSurfaceView = new GameGLSurfaceView(this); - this.gameRenderer = new GameRenderer(this); - this.gameRenderer.setDrawFrameListener(this); - this.gameGLSurfaceView.setRenderer(this.gameRenderer); - this.runLoop = new RunLoop(this.gameGLSurfaceView); - this.mFrameLayout = new FrameLayout(this); - this.mFrameLayout.addView(this.gameGLSurfaceView); - setContentView(this.mFrameLayout); - System.loadLibrary("fmodex"); - System.loadLibrary("fmodevent"); - System.loadLibrary("c++_shared"); - System.loadLibrary(Global.NIMBLE_ID); - System.loadLibrary("app"); - MultiplayerCore.INSTANCE.loadCore(); - Log.d(TAG, "Init EAIO/EAMIO"); - EAIO.Startup(this); - StorageDirectory.Startup(this); - ApplicationLifecycle.onActivityCreate(bundle, this); - Log.d(TAG, "nativeOnCreate"); - nativeOnCreate(); + mRotation = rotation + updateRequestedOrientation(rotation) + accelerometer = Accelerometer(sensorManager, defaultSensor, rotation) + gameGLSurfaceView = GameGLSurfaceView(this) + gameRenderer = GameRenderer(this) + gameRenderer.setDrawFrameListener(this) + gameGLSurfaceView.setRenderer(gameRenderer) + runLoop = RunLoop(gameGLSurfaceView) + mFrameLayout = FrameLayout(this) + mFrameLayout.addView(gameGLSurfaceView) + setContentView(mFrameLayout) + System.loadLibrary("fmodex") + System.loadLibrary("fmodevent") + System.loadLibrary("c++_shared") + System.loadLibrary(Global.NIMBLE_ID) + System.loadLibrary("app") + loadCore() + d(TAG, "Init EAIO/EAMIO") + EAIO.Startup(this) + StorageDirectory.Startup(this) + ApplicationLifecycle.onActivityCreate(bundle, this) + d(TAG, "nativeOnCreate") + nativeOnCreate() } - public String[] forEach(String input) { - return new String[] { input }; + fun forEach(input: String?): Array { + return arrayOf(input) } - public int getAssetSize(String str) { - Log.d(TAG, "getAssetSize filename = " + str); - File file = new File(str); - String parent = file.getParent(); + fun getAssetSize(str: String): Int { + d(TAG, "getAssetSize filename = " + str) + val file = File(str) + val parent = file.getParent() if (parent == null) { - if (this.mResources.containsKey(str)) { - Log.d(TAG, "getAssetSize mResources contains " + str); - return -1; + if (mResources!!.containsKey(str)) { + d(TAG, "getAssetSize mResources contains $str") + return -1 } - Log.d(TAG, "getAssetSize mResources not contains " + str); + d(TAG, "getAssetSize mResources not contains $str") } else { - Log.d(TAG, "getAssetSize path = " + parent); - if (this.mResources.containsKey(parent)) { - Log.d(TAG, "getAssetSize mResources contains " + parent); - Map map = (Map) this.mResources.get(parent); - String name = file.getName(); - Log.d(TAG, "getAssetSize name = " + name); - if (map.containsKey(name)) { - Log.d(TAG, "getAssetSize dir contains " + name); - FSNode fSNode = map.get(name); - int i = fSNode.directory ? -1 : fSNode.size; - Log.d(TAG, "getAssetSize filename = " + str + ", directory = " + Boolean.toString(fSNode.directory) + ", size = " + Integer.toString(fSNode.size)); - return i; + d(TAG, "getAssetSize path = $parent") + if (mResources!!.containsKey(parent)) { + d(TAG, "getAssetSize mResources contains $parent") + val map = mResources[parent] as MutableMap<*, *>? + val name = file.getName() + d(TAG, "getAssetSize name = $name") + if (map!!.containsKey(name)) { + d(TAG, "getAssetSize dir contains $name") + val fSNode = map[name] as FSNode + val i = if (fSNode.directory) -1 else fSNode.size + d( + TAG, + "getAssetSize filename = " + str + ", directory = " + fSNode.directory.toString() + ", size = " + fSNode.size.toString() + ) + return i } - Log.d(TAG, "getAssetSize dir not contains " + name); + d(TAG, "getAssetSize dir not contains $name") } else { - Log.d(TAG, "getAssetSize mResources not contains " + parent); + d(TAG, "getAssetSize mResources not contains $parent") } } - return -2; + return -2 } - public boolean isObbAssets() { - return this.mAssetLocationType == AssetLocationType.OBB; + val isObbAssets: Boolean + get() = mAssetLocationType == AssetLocationType.OBB + + val isFullApkAssets: Boolean + get() = mAssetLocationType == AssetLocationType.ASSETS + + + + private val versionCode: Int + get() { + try { + return getPackageManager().getPackageInfo(getPackageName(), 0).versionCode + } catch (e: PackageManager.NameNotFoundException) { + e.printStackTrace() + return 0 + } + } + + val obbFullPath: String + get() { + i( + javaClass.getName(), + obbDir.toString() + "/" + getObbFileName(this, versionCode) + ) + return obbDir.toString() + "/" + getObbFileName(this, versionCode) + } + + val assetManager: AssetManager? + get() = getResources().getAssets() + + fun enableSleepMode() { + if (isSleepModeEnabled) { + return + } + isSleepModeEnabled = true + wakeLockRelease() } - public boolean isFullApkAssets() { - return this.mAssetLocationType == AssetLocationType.ASSETS; - } - - public boolean useAssetsFileSystem() { - return this.mAssetLocationType != AssetLocationType.EXTERNAL; - } - - private int getVersionCode() { - try { - return getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return 0; + fun disableSleepMode() { + if (isSleepModeEnabled) { + isSleepModeEnabled = false + wakeLockAcquire() } } - public String getObbFullPath() { - Log.i(this.getClass().getName(), getObbDir() + "/" + ObbHelper.getObbFileName(this, getVersionCode())); - return getObbDir() + "/" + ObbHelper.getObbFileName(this, getVersionCode()); - } - - public AssetManager getAssetManager() { - return getResources().getAssets(); - } - - public static boolean isAnyMusicPlaying() { - return sIsOtherMusicPlaying; - } - - public static boolean isAmazon() { - return isAmazonDev; - } - - public static boolean isAtLeastAPI(int i) { - return Build.VERSION.SDK_INT >= i; - } - - public void enableSleepMode() { - if (this.isSleepModeEnabled) { - return; - } - this.isSleepModeEnabled = true; - wakeLockRelease(); - } - - public void disableSleepMode() { - if (this.isSleepModeEnabled) { - this.isSleepModeEnabled = false; - wakeLockAcquire(); - } - } - - private void checkAnyMusicActive() { + private fun checkAnyMusicActive() { if (mAudioManager != null) { - sIsOtherMusicPlaying = mAudioManager.isMusicActive(); - nativeOnMusicPlayerStateChanged(); + isAnyMusicPlaying = mAudioManager!!.isMusicActive() + nativeOnMusicPlayerStateChanged() } } - @Override // android.app.Activity - public void onStart() { - CallGC(); - Log.i(TAG, "onStart"); - super.onStart(); - Log.i(TAG, "onStart 1"); - wakeLockAcquire(); - Log.i(TAG, "onStart 2"); - if (this.lifecycle >= 2 && this.lifecycle < 4) { - Log.w(TAG, "onStart ignored, lifecycle is already " + this.lifecycleNames[this.lifecycle]); - return; - } - Log.i(TAG, "onStart 3"); - setLifecycle(2); - Log.i(TAG, "nativeOnStart"); - nativeOnStart(); - Log.i(TAG, "nativeOnStart - end"); - if (this.isXperiaPlay) { - switch (getResources().getConfiguration().navigationHidden) { - case 1: - nativeOnPhysicalNavigationVisibilityChanged(true); - break; - case 2: - nativeOnPhysicalNavigationVisibilityChanged(false); - break; - } - } - Log.i(TAG, "ApplicationLifecycle"); - ApplicationLifecycle.onActivityStart(this); + + public override fun onStart() { + CallGC() + super.onStart() + wakeLockAcquire() + nativeOnStart() + ApplicationLifecycle.onActivityStart(this) + } + + + public override fun onRestart() { + i(TAG, "onRestart") + super.onRestart() + ApplicationLifecycle.onActivityRestart(this) + nativeOnRestart() } - // Методы для воостановления сейва и его сохранения чтобы всегда использовать внешний сейв - - private String saveFileName = "nfstr_save.sb"; - private File save = null; - private File externalSave = new File(Environment.getStorageDirectory(),"games/nfsmw/nfstr_save.sb"); - - // Сохранить - private void storeSave() { - try { - save = new File(getFilesDir(), "var/nfstr_save.sb"); - - // Создаем директории, если они не существуют - externalSave.getParentFile().mkdirs(); - - // Копируем файл из внутреннего хранилища во внешнее - try (InputStream in = new FileInputStream(save); - OutputStream out = new FileOutputStream(externalSave)) { - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - } - } catch (IOException e) { - e.printStackTrace(); - // Обработка ошибки сохранения - } + + public override fun onPause() { + i(TAG, "onPause state=$state") + super.onPause() + mFMODAudioDevice.stop() + /*if (mOrientationListener.canDetectOrientation()) { + mOrientationListener.disable() + }*/ + gameGLSurfaceView.onPause() + ApplicationLifecycle.onActivityPause(this) + nativeOnPause() } - // Восстановить - private void restoreSave() { - try { - save = new File(getFilesDir(), "var/nfstr_save.sb"); - // Проверяем, существует ли внешний файл - if (!externalSave.exists()) { - return; // ничего не делаем, если файла нет - } - - // Создаем директории для внутреннего файла, если нужно - save.getParentFile().mkdirs(); - - // Копируем файл из внешнего хранилища во внутреннее - try (InputStream in = new FileInputStream(externalSave); - OutputStream out = new FileOutputStream(save)) { - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - } - } catch (IOException e) { - e.printStackTrace(); - // Обработка ошибки восстановления - } - } - - @Override // android.app.Activity - public void onRestart() { - Log.i(TAG, "onRestart"); - super.onRestart(); - ApplicationLifecycle.onActivityRestart(this); - nativeOnRestart(); - } - - @Override // android.app.Activity - public void onPause() { - Log.i(TAG, "onPause state=" + state); - super.onPause(); - this.mFMODAudioDevice.stop(); - if (this.mOrientationListener.canDetectOrientation()) { - this.mOrientationListener.disable(); - } - if (this.lifecycle != 3) { - Log.w(TAG, "onPause ignored, lifecycle is currently " + this.lifecycleNames[this.lifecycle]); - return; - } - setLifecycle(2); - this.gameGLSurfaceView.onPause(); - ApplicationLifecycle.onActivityPause(this); - nativeOnPause(); - this.splash = null; - } - - private void ForceHideVirtualKeyboard() { - View currentFocus = getCurrentFocus(); + private fun ForceHideVirtualKeyboard() { + val currentFocus = getCurrentFocus() if (currentFocus != null) { - ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(currentFocus.getWindowToken(), 0); + (getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow( + currentFocus.getWindowToken(), + 0 + ) } - getWindow().setSoftInputMode(3); + window.setSoftInputMode(3) } - @Override // android.app.Activity - public void onResume() { - Log.i(TAG, "onResume"); - super.onResume(); + + public override fun onResume() { + i(TAG, "onResume") + super.onResume() if (state != 7) { - oldState = state; - state = 7; - this.gameRenderer.setDrawFrameListener(this); + oldState = state + state = 7 + gameRenderer.setDrawFrameListener(this) } - if (this.mOrientationListener.canDetectOrientation()) { - this.mOrientationListener.enable(); - } - if (this.lifecycle == 3) { - Log.w(TAG, "onResume ignored, lifecycle is currently " + this.lifecycleNames[this.lifecycle]); - return; - } - setLifecycle(3); - this.gameGLSurfaceView.onResume(); - ApplicationLifecycle.onActivityResume(this); - nativeOnResume(); - checkAnyMusicActive(); - this.mFMODAudioDevice.start(); - Log.i(TAG, "onResume() isMusicActive = " + Boolean.toString(sIsOtherMusicPlaying)); + gameGLSurfaceView.onResume() + ApplicationLifecycle.onActivityResume(this) + nativeOnResume() + checkAnyMusicActive() + mFMODAudioDevice.start() + i(TAG, "onResume() isMusicActive = $isAnyMusicPlaying") } - @Override // android.app.Activity - public void onStop() { - Log.i(TAG, "onStop"); - super.onStop(); - if (this.lifecycle >= 4) { - Log.w(TAG, "onStop ignored, lifecycle is already " + this.lifecycleNames[this.lifecycle]); - return; - } - setLifecycle(4); - wakeLockRelease(); - nativeOnStop(); + + public override fun onStop() { + i(TAG, "onStop") + super.onStop() + wakeLockRelease() + nativeOnStop() } - @Override // android.app.Activity - public void onDestroy() { - Log.i(TAG, "onDestroy"); - super.onDestroy(); - if (this.lifecycle >= 5) { - Log.w(TAG, "onDestroy ignored, lifecycle is already " + this.lifecycleNames[this.lifecycle]); - return; - } - setLifecycle(5); - storeSave(); + + public override fun onDestroy() { + i(TAG, "onDestroy") + super.onDestroy() if (state == 8) { - ApplicationLifecycle.onActivityDestroy(this); - nativeOnDestroy(); + ApplicationLifecycle.onActivityDestroy(this) + nativeOnDestroy() } - StorageDirectory.Shutdown(); - EAIO.Shutdown(); - System.exit(0); + StorageDirectory.Shutdown() + EAIO.Shutdown() + exitProcess(0) } @SuppressLint("InvalidWakeLockTag") - public void wakeLockAcquire() { - if (this.isSleepModeEnabled) { - return; - } - if (this.mWakeLock == null) { - this.mWakeLock = ((PowerManager) getSystemService(Context.POWER_SERVICE)).newWakeLock(10, TAG); - } - if (this.mWakeLock.isHeld()) { - return; - } - try { - this.mWakeLock.acquire(); - } catch (SecurityException unused) { - Log.w(TAG, "Missing WAKE_LOCK permission."); - } + fun wakeLockAcquire() { + if (isSleepModeEnabled) return + if (mWakeLock.isHeld) return + mWakeLock.acquire(10*60*1000L /*10 minutes*/) } - public void wakeLockRelease() { - if (this.isSleepModeEnabled) { - return; - } - try { - if (this.mWakeLock == null || !this.mWakeLock.isHeld()) { - return; - } - this.mWakeLock.release(); - } catch (SecurityException unused) { - Log.w(TAG, "Missing WAKE_LOCK permission."); - } + fun wakeLockRelease() { + if (isSleepModeEnabled) return + if (mWakeLock.isHeld) return + mWakeLock.release() } - @Override // android.app.Activity - protected void onSaveInstanceState(Bundle bundle) { - super.onSaveInstanceState(bundle); - ApplicationLifecycle.onActivitySaveInstanceState(bundle, this); + + override fun onSaveInstanceState(bundle: Bundle) { + super.onSaveInstanceState(bundle) + ApplicationLifecycle.onActivitySaveInstanceState(bundle, this) } - @Override // android.app.Activity - public void onActivityResult(int i, int i2, Intent intent) { - super.onActivityResult(i, i2, intent); - ApplicationLifecycle.onActivityResult(i, i2, intent, this); + + public override fun onActivityResult(i: Int, i2: Int, intent: Intent?) { + super.onActivityResult(i, i2, intent) + ApplicationLifecycle.onActivityResult(i, i2, intent, this) } - @Override // android.app.Activity, android.view.KeyEvent.Callback - public boolean onKeyDown(final int i, KeyEvent keyEvent) { - super.onKeyDown(i, keyEvent); + override fun onKeyDown(i: Int, keyEvent: KeyEvent): Boolean { + super.onKeyDown(i, keyEvent) if (state != 8) { - return true; + return true } if ((i == 4 || i == 108) && keyEvent.getRepeatCount() > 0) { - return true; + return true } - final int scanCode = keyEvent.getScanCode(); - this.gameGLSurfaceView.queueEvent(new Runnable() { // from class: com.ea.ironmonkey.GameActivityMain.3 - @Override // java.lang.Runnable - public void run() { - GameActivityMain.this.nativeOnPhysicalKeyDown(i, scanCode); + val scanCode = keyEvent.getScanCode() + gameGLSurfaceView!!.queueEvent(object : Runnable { + // from class: com.ea.ironmonkey.GameActivityMain.3 + // java.lang.Runnable + override fun run() { + this@GameActivityMain.nativeOnPhysicalKeyDown(i, scanCode) } - }); - return !IsSystemKey(i); + }) + return !IsSystemKey(i) } - @Override // android.app.Activity, android.view.KeyEvent.Callback - public boolean onKeyUp(final int i, KeyEvent keyEvent) { - super.onKeyUp(i, keyEvent); + override fun onKeyUp(i: Int, keyEvent: KeyEvent): Boolean { + super.onKeyUp(i, keyEvent) if (state != 8) { - return true; + return true } - final int scanCode = keyEvent.getScanCode(); - this.gameGLSurfaceView.queueEvent(new Runnable() { // from class: com.ea.ironmonkey.GameActivityMain.4 - @Override // java.lang.Runnable - public void run() { - GameActivityMain.this.nativeOnPhysicalKeyUp(i, scanCode); - } - }); - return !IsSystemKey(i); + val scanCode = keyEvent.scanCode + gameGLSurfaceView.queueEvent { this@GameActivityMain.nativeOnPhysicalKeyUp(i, scanCode) } + return !IsSystemKey(i) } - @Override // android.app.Activity - public void onBackPressed() { - //super.onBackPressed(); - if (state == 1 || state == 0 || state == 7) { - finish(); - } - ApplicationLifecycle.onBackPressed(); + + @Deprecated("Deprecated in Java") + override fun onBackPressed() { + //super.onBackPressed() + ApplicationLifecycle.onBackPressed() } - @Override // android.app.Activity, android.content.ComponentCallbacks - public void onConfigurationChanged(Configuration configuration) { - Log.d(TAG, "onConfigurationChanged(" + configuration.toString() + ")"); - super.onConfigurationChanged(configuration); - if (this.accelerometer != null) { - int rotation = getWindow().getWindowManager().getDefaultDisplay().getRotation(); - switch (rotation) { - case 0: - Log.i(TAG, "Orientation: ROTATION_0"); - break; - case 1: - Log.i(TAG, "Orientation: ROTATION_90"); - break; - case 2: - Log.i(TAG, "Orientation: ROTATION_180"); - break; - case 3: - Log.i(TAG, "Orientation: ROTATION_270"); - break; - } - if (isAmazonDev) { - this.accelerometer.updateOrientation(rotation); - } - } - if (this.isXperiaPlay) { - switch (configuration.navigationHidden) { - case 1: - nativeOnPhysicalNavigationVisibilityChanged(true); - break; - case 2: - nativeOnPhysicalNavigationVisibilityChanged(false); - break; - } + override fun onConfigurationChanged(configuration: Configuration) { + d(TAG, "onConfigurationChanged($configuration)") + super.onConfigurationChanged(configuration) + val rotation = window.windowManager.defaultDisplay.rotation + when (rotation) { + 0 -> i(TAG, "Orientation: ROTATION_0") + 1 -> i(TAG, "Orientation: ROTATION_90") + 2 -> i(TAG, "Orientation: ROTATION_180") + 3 -> i(TAG, "Orientation: ROTATION_270") } } - @Override // android.app.Activity, android.view.Window.Callback - public void onWindowFocusChanged(boolean z) { - super.onWindowFocusChanged(z); - Log.i(TAG, "onWindowsFocusChanged(" + z + ") state=" + state); - if (getGameGLSurfaceView() != null) { - getGameGLSurfaceView().setRenderMode(z ? 1 : 0); - } + override fun onWindowFocusChanged(z: Boolean) { + super.onWindowFocusChanged(z) + i(TAG, "onWindowsFocusChanged($z) state=$state") + getGameGLSurfaceView().renderMode = if (z) 1 else 0 if (!z) { - if (this.mFMODAudioDevice.isMixing()) { - this.mFMODAudioDevice.stop(); - checkAnyMusicActive(); + if (mFMODAudioDevice.isMixing) { + mFMODAudioDevice.stop() + checkAnyMusicActive() } - Log.i(TAG, "onWindowFocusChanged() isMusicActive = " + Boolean.toString(sIsOtherMusicPlaying)); - ForceHideVirtualKeyboard(); - nativeOnPhysicalKeyDown(131, 0); - nativeOnPhysicalKeyUp(131, 0); - if (state == 8 && !isAmazonDev) { - oldState = state; - state = 7; - this.gameRenderer.setDrawFrameListener(this); + i(TAG, "onWindowFocusChanged() isMusicActive = $isAnyMusicPlaying") + ForceHideVirtualKeyboard() + nativeOnPhysicalKeyDown(131, 0) + nativeOnPhysicalKeyUp(131, 0) + if (state == 8) { + oldState = state + state = 7 + gameRenderer.setDrawFrameListener(this) } } else { - if (!this.mFMODAudioDevice.isMixing()) { - checkAnyMusicActive(); - this.mFMODAudioDevice.start(); + if (!mFMODAudioDevice.isMixing) { + checkAnyMusicActive() + mFMODAudioDevice.start() } - Log.i(TAG, "onWindowFocusChanged() isMusicActive = " + Boolean.toString(sIsOtherMusicPlaying)); - if (!isAmazonDev) { - getWindow().getDecorView().setSystemUiVisibility(5894); + i(TAG, "onWindowFocusChanged() isMusicActive = $isAnyMusicPlaying") + } + ApplicationLifecycle.onActivityWindowFocusChanged(z, this) + } + + fun getGameGLSurfaceView(): GameGLSurfaceView { + return gameGLSurfaceView + } + + fun GetViewRoot() = window.decorView.getRootView().parent + + fun CallGC() { + d(TAG, "Call garbage collector") + System.gc() + } + + fun ShowMessage(str: String?, strArr: Array, z: Boolean) { + d(TAG, "ShowMessage msg=$str finish=$z") + mAd = AlertDialog.Builder(this) + mAd.setMessage(str) + mAd.setCancelable(false) + mAd.setPositiveButton(strArr[0]) { dialogInterface, i -> + if (z) { + this@GameActivityMain.finish() } } - ApplicationLifecycle.onActivityWindowFocusChanged(z, this); + handler.postDelayed({ this@GameActivityMain.mAd.show() }, 20L) } - private void setLifecycle(int i) { - if (i == this.lifecycle) { - return; - } - Log.i(TAG, this.lifecycleNames[this.lifecycle] + " -> " + this.lifecycleNames[i]); - this.lifecycle = i; + override fun onLowMemory() { + val activityManager = getSystemService(ACTIVITY_SERVICE) as ActivityManager + val memoryInfo = ActivityManager.MemoryInfo() + activityManager.getMemoryInfo(memoryInfo) + super.onLowMemory() } - public RunLoop getRunLoop() { - return this.runLoop; - } - - public GameGLSurfaceView getGameGLSurfaceView() { - return this.gameGLSurfaceView; - } - - public ViewParent GetViewRoot() { - return getWindow().getDecorView().getRootView().getParent(); - } - - public void CallGC() { - Log.d(TAG, "Call garbage collector"); - System.gc(); - } - - public static String GetDeviceName() { - return Build.MODEL; - } - - public static String getOsVersion() { - return Build.VERSION.RELEASE; - } - - public static String GetDefaultLanguage() { - return Locale.getDefault().toString().substring(0, 2); - } - - public static String GetDeviceLocale() { - String upperCase = Locale.getDefault().toString().replace('_', '-').toUpperCase(); - Log.d(TAG, "GetDeviceLocale locale = " + upperCase); - return upperCase; - } - - public void ShowMessage(String str, String[] strArr, final boolean z) { - Log.d(TAG, "ShowMessage msg=" + str + " finish=" + z); - this.mAd = new AlertDialog.Builder(this); - this.mAd.setMessage(str); - this.mAd.setCancelable(false); - this.mAd.setPositiveButton(strArr[0], new DialogInterface.OnClickListener() { // from class: com.ea.ironmonkey.GameActivityMain.5 - @Override // android.content.DialogInterface.OnClickListener - public void onClick(DialogInterface dialogInterface, int i) { - if (z) { - GameActivityMain.this.finish(); - } + fun GetNaturalOrientation(): Int { + val width: Int + val height: Int + val defaultDisplay = window.windowManager.defaultDisplay + when (defaultDisplay.rotation) { + 0, 2 -> { + width = defaultDisplay.getWidth() + height = defaultDisplay.getHeight() } - }); - this.handler.postDelayed(new Runnable() { // from class: com.ea.ironmonkey.GameActivityMain.6 - @Override // java.lang.Runnable - public void run() { - GameActivityMain.this.mAd.show(); + + 1, 3 -> { + width = defaultDisplay.getHeight() + height = defaultDisplay.getWidth() } - }, 20L); - } - @Override // android.app.Activity, android.content.ComponentCallbacks - public void onLowMemory() { - ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); - activityManager.getMemoryInfo(memoryInfo); - super.onLowMemory(); - } - - public static String GetApplicationVersion() { - try { - return instance.getPackageManager().getPackageInfo(instance.getPackageName(), 0).versionName; - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return "1.0.1"; - } - } - - public int GetNaturalOrientation() { - int width; - int height; - Display defaultDisplay = getWindow().getWindowManager().getDefaultDisplay(); - switch (defaultDisplay.getRotation()) { - case 0: - case 2: - width = defaultDisplay.getWidth(); - height = defaultDisplay.getHeight(); - break; - case 1: - case 3: - width = defaultDisplay.getHeight(); - height = defaultDisplay.getWidth(); - break; - default: - height = 0; - width = 0; - break; + else -> { + height = 0 + width = 0 + } } if (width > height) { - Log.d(TAG, "NaturalOrientation = LANDSCAPE"); - return 0; + d(TAG, "NaturalOrientation = LANDSCAPE") + return 0 } - Log.d(TAG, "NaturalOrientation = PORTRAIT"); - return 1; + d(TAG, "NaturalOrientation = PORTRAIT") + return 1 } - public Accelerometer getAccelerometer() { - return this.accelerometer; - } - - public DisplayMetrics getDisplayMetrics() { - if (Build.VERSION.SDK_INT >= 17) { - DisplayMetrics displayMetrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics); - return displayMetrics; + val displayMetrics: DisplayMetrics? + get() { + val displayMetrics = DisplayMetrics() + windowManager.getDefaultDisplay().getRealMetrics(displayMetrics) + return displayMetrics } - return getResources().getDisplayMetrics(); - } - public boolean isAssetsReady() { - return assetsReady; - } - - @Override // android.app.Activity - public void setContentView(View view) { - Log.d(TAG, "setContentView(" + view + ")"); - if (view != null) { - if (view == this.mFrameLayout) { - super.setContentView(view); - return; + + override fun setContentView(view: View) { + d(TAG, "setContentView($view)") + if (view === mFrameLayout) { + super.setContentView(view) + return + } + val childCount = mFrameLayout.childCount + for (i in 0.. 0) { - this.splashCounter--; - break; + + when (state) { + STATE_SPLASH -> { + splash = SplashScreen(this) + splash.init( + gl10, + gameRenderer.width, + gameRenderer.height + ) + state = STATE_SPLASH_PROCESS + splashCounter = 3 + } + + STATE_SPLASH_PROCESS -> { + if (splashCounter > 0) { + splashCounter-- } else { - this.splashTimer = System.currentTimeMillis() + 2500; - if (!assetsReady) { - try { - inputStream = getAssets().open(DOWNLOAD_PROPERTIES); - try { - inputStream.close(); - } catch (Exception unused) { - } - } catch (Exception unused2) { - inputStream = null; + splashTimer = System.currentTimeMillis() + 2500 + if (!isAssetsReady) { + inputStream = try { + assets.open(DOWNLOAD_PROPERTIES) + } catch (e: Exception) { + null } if (inputStream != null) { - this.handler.postDelayed(new Runnable() { // from class: com.ea.ironmonkey.GameActivityMain.8 - @Override // java.lang.Runnable - public void run() { - } - }, 20L); - Log.i(TAG, "state ADC start"); - state = 3; - break; + handler!!.postDelayed({ }, 20L) + Log.i(TAG, "state ADC start") + state = STATE_ADC_START } else { - Log.i(TAG, "STATE_GAME_START 1"); - state = 8; - break; + Log.i(TAG, "STATE_GAME_START 1") + state = STATE_GAME_START } } else { - Log.i(TAG, "STATE_GAME_START 2"); - state = 8; - break; + Log.i(TAG, "STATE_GAME_START 2") + state = STATE_GAME_START } } - case 3: - Log.i(TAG, "ADC start"); - break; - case 7: - if (this.splash == null) { - this.splash = new SplashScreen(this); - this.splash.init(gl10, this.gameRenderer.getWidth(), this.gameRenderer.getHeight()); - this.splashDelay = System.currentTimeMillis() + 2000; + } + + STATE_ADC_START -> { + Log.i(TAG, "ADC start") + // Здесь должен быть код для обработки ADC start + // state = ... // переходим в следующее состояние + } + + STATE_RESTORE_CONTEXT -> { + if (splash == null) { + splash = SplashScreen(this) + splash!!.init( + gl10, + gameRenderer!!.width, + gameRenderer!!.height + ) + splashDelay = System.currentTimeMillis() + 2000 } - if (this.splashDelay < System.currentTimeMillis() && hasWindowFocus()) { - if (oldState == 8) { - this.splashTimer = System.currentTimeMillis() + 300; - state = 8; - break; + + if (splashDelay < System.currentTimeMillis() && hasWindowFocus()) { + state = if (oldState == STATE_GAME_START) { + splashTimer = System.currentTimeMillis() + 300 + STATE_GAME_START } else { - state = oldState; - break; + oldState } } - break; - case 8: - if (this.splashTimer < System.currentTimeMillis() && nativeRestoreContext()) { - assetsReady = true; - nativeOnStart(); - nativeOnResume(); - this.gameRenderer.setDrawFrameListener(null); - z = true; - break; - } - break; - } - GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - GLES20.glClear(16640); - if (this.splash != null) { - this.splash.draw(gl10, this.gameRenderer.getWidth(), this.gameRenderer.getHeight()); - } - if (!z || this.splash == null) { - return; - } - this.splash.destroy(gl10); - this.splash = null; - } + } - public void onResult(String str, int i) { - Log.w(TAG, "onResult(" + str + "," + i + ")"); - if (i == -1) { - File file = new File(new File(str).getParent() + "/.nomedia"); - if (!file.exists()) { - try { - file.createNewFile(); - } catch (Exception unused) { + STATE_GAME_START -> { + if (splashTimer < System.currentTimeMillis() && nativeRestoreContext()) { + isAssetsReady = true + nativeOnStart() + nativeOnResume() + gameRenderer!!.setDrawFrameListener(null) + shouldCleanupSplash = true } } - this.handler.postDelayed(new Runnable() { // from class: com.ea.ironmonkey.GameActivityMain.9 - @Override // java.lang.Runnable - public void run() { - GameActivityMain.this.setContentView(GameActivityMain.this.gameGLSurfaceView); - } - }, 20L); - if (hasWindowFocus()) { - state = 8; - return; - } else { - oldState = 8; - state = 7; - return; + + // Добавляем обработку остальных состояний + STATE_GOOGLE_DRM -> { + // Обработка Google DRM + } + + STATE_ADC_PROCESS -> { + // Обработка ADC процесса + } + + STATE_FULL_START -> { + // Обработка Full start + } + + STATE_FULL_PROCESS -> { + // Обработка Full процесса } } - finish(); - Process.killProcess(Process.myPid()); - } - public int getTotalMemory() { - return 40000; - } + // Очистка экрана + GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f) + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT) - public void openURL(String str) { - openURLinBrowser(str); - } + // Отрисовка сплеш-скрина если он существует + splash.draw( + gl10, + gameRenderer.width, + gameRenderer.height + ) - public void openURLinBrowser(String str) { - String replace = str.replace("http://", "https://"); - Log.d("OpenURLinBrowser", replace); - try { - startActivity(new Intent("android.intent.action.VIEW", Uri.parse(replace))); - } catch (Exception e) { - e.printStackTrace(); + // Очистка сплеш-скрина если нужно + if (shouldCleanupSplash) { + splash.destroy(gl10) } } - public float getPerformanceScore() { - return 6.6f; + val totalMemory: Int + get() = 40000 + + fun openURL(str: String) { + val replace = str.replace("http://", "https://") + startActivity(Intent("android.intent.action.VIEW", replace.toUri())) } - public boolean needInstallWallpaper() { - Log.i(TAG, "needInstallWallpaper()"); - return false; + val performanceScore: Float + get() = 6.6f + + fun needInstallWallpaper(): Boolean { + i(TAG, "needInstallWallpaper()") + return false } - public void installWallpaper() {} + fun installWallpaper() {} - public long getUtcTime() { - return TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis()); - } + val utcTime: Long + get() = TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis()) - public int[][] getNotchesBoundingRects() { - DisplayCutout displayCutout; - int[][] iArr = (int[][]) Array.newInstance((Class) int.class, 0, 0); - if (Build.VERSION.SDK_INT < 28 || (displayCutout = getWindow().getDecorView().getRootWindowInsets().getDisplayCutout()) == null) { - return iArr; + val notchesBoundingRects: Array + get() { + if (Build.VERSION.SDK_INT < 28) { + return emptyArray() + } + + val displayCutout = window.decorView.rootWindowInsets?.displayCutout + if (displayCutout == null) { + return emptyArray() + } + + val boundingRects = displayCutout.boundingRects + return boundingRects.map { rect -> + intArrayOf(rect.left, rect.top, rect.width(), rect.height()) + }.toTypedArray() } - List boundingRects = displayCutout.getBoundingRects(); - int[][] iArr2 = (int[][]) Array.newInstance((Class) int.class, boundingRects.size(), 4); - for (int i = 0; i < boundingRects.size(); i++) { - iArr2[i][0] = boundingRects.get(i).left; - iArr2[i][1] = boundingRects.get(i).top; - iArr2[i][2] = boundingRects.get(i).width(); - iArr2[i][3] = boundingRects.get(i).height(); - } - return iArr2; - } - - class FSNode { - - @SerializedName("directory") - public boolean directory; - - @SerializedName("size") - public int size; - - FSNode() { - } - } } diff --git a/app/src/main/java/com/ea/ironmonkey/Log.kt b/app/src/main/java/com/ea/ironmonkey/Log.kt index 4ccf488..d158721 100644 --- a/app/src/main/java/com/ea/ironmonkey/Log.kt +++ b/app/src/main/java/com/ea/ironmonkey/Log.kt @@ -1,46 +1,30 @@ -package com.ea.ironmonkey; +package com.ea.ironmonkey + +import android.util.Log -public class Log { - private static boolean enable; +object Log { + private var enable = false - public static void setEnable(boolean z) { - enable = z; + fun setEnable(enabled: Boolean) { + enable = enabled } - public static void i(String str, String str2) { - if (enable) { - android.util.Log.i(str, str2); - } - } + @JvmStatic + fun i(tag: String, msg: String) = if (enable) Log.i(tag, msg) else Unit - public static void e(String str, String str2) { - if (enable) { - android.util.Log.e(str, str2); - } - } + @JvmStatic + fun e(tag: String, msg: String) = if (enable) Log.e(tag, msg) else Unit - public static void w(String str, String str2) { - if (enable) { - android.util.Log.w(str, str2); - } - } + @JvmStatic + fun w(tag: String, msg: String) = if (enable) Log.w(tag, msg) else Unit - public static void d(String str, String str2) { - if (enable) { - android.util.Log.d(str, str2); - } - } + @JvmStatic + fun d(tag: String, msg: String) = if (enable) Log.d(tag, msg) else Unit - public static void v(String str, String str2) { - if (enable) { - android.util.Log.v(str, str2); - } - } + @JvmStatic + fun v(tag: String, msg: String) = if (enable) Log.v(tag, msg) else Unit - public static void e(String str, String str2, Exception exc) { - if (enable) { - android.util.Log.e(str, str2, exc); - } - } -} + @JvmStatic + fun e(tag: String, msg: String?, exc: Exception?) = if (enable) Log.e(tag, msg, exc) else Unit +} \ No newline at end of file diff --git a/app/src/main/java/com/ea/ironmonkey/MogaController.kt b/app/src/main/java/com/ea/ironmonkey/MogaController.kt index 3824bf9..a2f937e 100644 --- a/app/src/main/java/com/ea/ironmonkey/MogaController.kt +++ b/app/src/main/java/com/ea/ironmonkey/MogaController.kt @@ -1,30 +1,117 @@ -package com.ea.ironmonkey; +package com.ea.ironmonkey -import com.bda.controller.ControllerListener; -import com.bda.controller.KeyEvent; -import com.bda.controller.MotionEvent; -import com.bda.controller.StateEvent; +import android.content.Context +import android.hardware.input.InputManager +import android.util.Log +import android.view.InputDevice +import androidx.activity.ComponentActivity +import com.bda.controller.ControllerListener +import com.bda.controller.KeyEvent +import com.bda.controller.MotionEvent +import com.bda.controller.StateEvent +object MogaController : ControllerListener { + external fun nativeOnKeyEvent(keyEvent: KeyEvent?) -public class MogaController implements ControllerListener { - native void nativeOnKeyEvent(KeyEvent keyEvent); + external fun nativeOnMotionEvent(motionEvent: MotionEvent?) - native void nativeOnMotionEvent(MotionEvent motionEvent); + external fun nativeOnStateEvent(stateEvent: StateEvent?) - native void nativeOnStateEvent(StateEvent stateEvent); - - @Override // com.bda.controller.ControllerListener - public void onKeyEvent(KeyEvent keyEvent) { - nativeOnKeyEvent(keyEvent); + override fun onKeyEvent(keyEvent: KeyEvent?) { + nativeOnKeyEvent(keyEvent) } - @Override // com.bda.controller.ControllerListener - public void onMotionEvent(MotionEvent motionEvent) { - nativeOnMotionEvent(motionEvent); + override fun onMotionEvent(motionEvent: MotionEvent?) { + nativeOnMotionEvent(motionEvent) } - @Override // com.bda.controller.ControllerListener - public void onStateEvent(StateEvent stateEvent) { - nativeOnStateEvent(stateEvent); + override fun onStateEvent(stateEvent: StateEvent?) { + nativeOnStateEvent(stateEvent) } + + fun doForAllControllers( + action: (Int) -> Unit + ){ + val deviceIds = InputDevice.getDeviceIds() + + deviceIds.forEach { + if(deviceIsController(it)) action(it) + } + } + + infix fun Int.isFlag(flag: Int) = this and flag == flag + + fun deviceIsController(deviceId: Int): Boolean { + val inputDevice = InputDevice.getDevice(deviceId) ?: return false + + if(inputDevice.id == -1) return false + + return (inputDevice.sources isFlag InputDevice.SOURCE_GAMEPAD) && + (inputDevice.sources isFlag InputDevice.SOURCE_JOYSTICK) + } + + fun registerControllerHandlers( + context: Context, + onInputDeviceAdded: (Int) -> Unit, + onInputDeviceRemoved: (Int) -> Unit, + onInputDeviceChanged: (Int) -> Unit = {}, + ){ + + val inputManager = context.getSystemService(ComponentActivity.INPUT_SERVICE) as InputManager + + inputManager.registerInputDeviceListener(object : InputManager.InputDeviceListener { + + var lastControllerId: Int = 0; + + override fun onInputDeviceAdded(deviceId: Int) { + if(deviceIsController(deviceId)) { + lastControllerId = deviceId + onInputDeviceAdded(deviceId) + } + } + + override fun onInputDeviceRemoved(deviceId: Int) { + + if(deviceIsController(deviceId) || lastControllerId == deviceId) onInputDeviceRemoved(deviceId) + } + + override fun onInputDeviceChanged(deviceId: Int) { + if(deviceIsController(deviceId)) onInputDeviceChanged(deviceId) + } + }, null) + + } + + fun createDisconnectEvent(deviceId: Int) = StateEvent( + System.currentTimeMillis(), + deviceId, + StateEvent.STATE_UNKNOWN, + StateEvent.ACTION_DISCONNECTED + ) + + fun createConnectEvent(deviceId: Int) = StateEvent( + System.currentTimeMillis(), + deviceId, + StateEvent.STATE_CONNECTION, + StateEvent.ACTION_CONNECTED + ) + + fun androidKeyEventToBda(keyEvent: android.view.KeyEvent) = KeyEvent( + keyEvent.eventTime, + keyEvent.deviceId, + keyEvent.keyCode, + keyEvent.action + ) + + fun androidMotionEventToBda(motionEvent: android.view.MotionEvent) = MotionEvent( + motionEvent.eventTime, + motionEvent.deviceId, + motionEvent.x, + motionEvent.y, + motionEvent.rawX, + motionEvent.rawY, + motionEvent.xPrecision, + motionEvent.yPrecision + ) + } diff --git a/app/src/main/java/com/ea/ironmonkey/ObbHelper.kt b/app/src/main/java/com/ea/ironmonkey/ObbHelper.kt index f0290f2..66231e9 100644 --- a/app/src/main/java/com/ea/ironmonkey/ObbHelper.kt +++ b/app/src/main/java/com/ea/ironmonkey/ObbHelper.kt @@ -1,13 +1,8 @@ -package com.ea.ironmonkey; +package com.ea.ironmonkey -import android.content.Context; +import android.content.Context - -class ObbHelper { - ObbHelper() { - } - - public static String getObbFileName(Context context, int i) { - return "main." + i + "." + context.getPackageName() + ".obb"; - } +internal object ObbHelper { + @JvmStatic + fun getObbFileName(context: Context, versionCode: Int) = "main.$versionCode.${context.packageName}.obb" } diff --git a/app/src/main/java/com/ea/ironmonkey/PermissionsActivity.kt b/app/src/main/java/com/ea/ironmonkey/PermissionsActivity.kt index 1df4d98..982441c 100644 --- a/app/src/main/java/com/ea/ironmonkey/PermissionsActivity.kt +++ b/app/src/main/java/com/ea/ironmonkey/PermissionsActivity.kt @@ -1,182 +1,186 @@ -package com.ea.ironmonkey; +package com.ea.ironmonkey +import android.Manifest +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.provider.Settings +import android.util.Log +import android.view.KeyEvent +import android.widget.Toast +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat -import android.Manifest; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; -import android.provider.Settings; -import android.util.Log; -import android.view.KeyEvent; +class PermissionsActivity : AppCompatActivity() { -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import android.os.Build; -import android.widget.Toast; -import androidx.activity.result.ActivityResultLauncher; -import androidx.activity.result.contract.ActivityResultContracts; - -import java.util.ArrayList; -import java.util.List; - -public class PermissionsActivity extends AppCompatActivity { - private static final int SETTINGS_REQUEST_CODE = 100; - private final ActivityResultLauncher requestPermissionLauncher = - registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> { - if (areAllPermissionsGranted()) { - initActivity(); - } else { - handlePermissionsDenied(); - } - }); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - checkPermissions(); + companion object { + private const val SETTINGS_REQUEST_CODE = 100 } - private void checkPermissions() { + private val requestPermissionLauncher: ActivityResultLauncher> = + registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result -> + if (areAllPermissionsGranted()) { + initActivity() + } else { + handlePermissionsDenied() + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + checkPermissions() + } + + private fun checkPermissions() { if (areAllPermissionsGranted()) { - initActivity(); + initActivity() } else { - requestPermissions(); + requestPermissions() } } - private boolean areAllPermissionsGranted() { - for (String permission : getRequiredPermissions()) { - if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { - return false; - } + private fun areAllPermissionsGranted(): Boolean { + return getRequiredPermissions().all { permission -> + ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED } - return true; } - private String[] getRequiredPermissions() { - List permissions = new ArrayList<>(); + private fun getRequiredPermissions(): Array { + val permissions = mutableListOf() - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { - // Android 9 (Pie) и ниже - нужны оба разрешения - permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); - permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { - // Android 10 (Q) - только чтение - permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - // Android 13+ - новые раздельные разрешения для медиа - //permissions.add(Manifest.permission.READ_MEDIA_IMAGES); - //permissions.add(Manifest.permission.READ_MEDIA_VIDEO); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - // Android 14+ - дополнительно для аудио - permissions.add(Manifest.permission.READ_MEDIA_AUDIO); + when { + Build.VERSION.SDK_INT <= Build.VERSION_CODES.P -> { + // Android 9 (Pie) и ниже - нужны оба разрешения + permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE) + permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE) + } + Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q -> { + // Android 10 (Q) - только чтение + permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE) + } + Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> { + // Android 13+ - новые раздельные разрешения для медиа + // permissions.add(Manifest.permission.READ_MEDIA_IMAGES) + // permissions.add(Manifest.permission.READ_MEDIA_VIDEO) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + // Android 14+ - дополнительно для аудио + //permissions.add(Manifest.permission.READ_MEDIA_AUDIO) + } + } + else -> { + // Android 11-12 - только чтение + permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE) } - } else { - // Android 11-12 - только чтение - permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); } - permissions.forEach(e -> { - Log.i("Permissions", e); - }); + permissions.forEach { permission -> + Log.i("Permissions", permission) + } - return permissions.toArray(new String[0]); + return permissions.toTypedArray() } - private void requestPermissions() { - String[] permissions = getRequiredPermissions(); - boolean shouldShowRationale = false; - - for (String permission : permissions) { - if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { - shouldShowRationale = true; - break; - } + private fun requestPermissions() { + val permissions = getRequiredPermissions() + val shouldShowRationale = permissions.any { permission -> + ActivityCompat.shouldShowRequestPermissionRationale(this, permission) } if (shouldShowRationale) { - showPermissionRationaleDialog(); + showPermissionRationaleDialog() } else { - requestPermissionLauncher.launch(permissions); + requestPermissionLauncher.launch(permissions) } } - private void showPermissionRationaleDialog() { - new AlertDialog.Builder(this) - .setTitle("Требуются разрешения") - .setMessage("Для корректной работы приложения необходимы разрешения на доступ к хранилищу. Пожалуйста, предоставьте запрашиваемые разрешения.") - .setPositiveButton("OK", (dialog, which) -> requestPermissionLauncher.launch(getRequiredPermissions())) - .setNegativeButton("Отмена", (dialog, which) -> finish()) - .setCancelable(false) - .setOnKeyListener((dialog, keyCode, event) -> { - if (keyCode == KeyEvent.KEYCODE_BACK) { - finish(); - return true; - } - return false; - }) - .show(); - } - - private void handlePermissionsDenied() { - if (areSomePermissionsPermanentlyDenied()) { - showPermanentlyDeniedDialog(); - } else { - Toast.makeText(this, "Разрешения необходимы для работы приложения", Toast.LENGTH_SHORT).show(); - finish(); - } - } - - private boolean areSomePermissionsPermanentlyDenied() { - for (String permission : getRequiredPermissions()) { - if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permission) && - ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { - return true; + private fun showPermissionRationaleDialog() { + AlertDialog.Builder(this) + .setTitle("Требуются разрешения") + .setMessage("Для корректной работы приложения необходимы разрешения на доступ к хранилищу. Пожалуйста, предоставьте запрашиваемые разрешения.") + .setPositiveButton("OK") { dialog, _ -> + dialog.dismiss() + requestPermissionLauncher.launch(getRequiredPermissions()) } + .setNegativeButton("Отмена") { dialog, _ -> + dialog.dismiss() + finish() + } + .setCancelable(false) + .setOnKeyListener { _, keyCode, event -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + finish() + true + } else { + false + } + } + .show() + } + + private fun handlePermissionsDenied() { + if (areSomePermissionsPermanentlyDenied()) { + showPermanentlyDeniedDialog() + } else { + Toast.makeText(this, "Разрешения необходимы для работы приложения", Toast.LENGTH_SHORT).show() + finish() } - return false; } - private void showPermanentlyDeniedDialog() { - new AlertDialog.Builder(this) - .setTitle("Разрешения отклонены") - .setMessage("Вы навсегда отклонили некоторые разрешения. Чтобы использовать приложение, предоставьте разрешения в настройках.") - .setPositiveButton("Настройки", (dialog, which) -> openAppSettings()) - .setNegativeButton("Выход", (dialog, which) -> finish()) - .setCancelable(false) - .show(); + private fun areSomePermissionsPermanentlyDenied(): Boolean { + return getRequiredPermissions().any { permission -> + !ActivityCompat.shouldShowRequestPermissionRationale(this, permission) && + ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED + } } - private void openAppSettings() { - Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); - intent.setData(Uri.parse("package:" + getPackageName())); - startActivityForResult(intent, SETTINGS_REQUEST_CODE); + private fun showPermanentlyDeniedDialog() { + AlertDialog.Builder(this) + .setTitle("Разрешения отклонены") + .setMessage("Вы навсегда отклонили некоторые разрешения. Чтобы использовать приложение, предоставьте разрешения в настройках.") + .setPositiveButton("Настройки") { dialog, _ -> + dialog.dismiss() + openAppSettings() + } + .setNegativeButton("Выход") { dialog, _ -> + dialog.dismiss() + finish() + } + .setCancelable(false) + .show() } - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); + private fun openAppSettings() { + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.fromParts("package", packageName, null) + } + startActivityForResult(intent, SETTINGS_REQUEST_CODE) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) if (requestCode == SETTINGS_REQUEST_CODE) { if (areAllPermissionsGranted()) { - initActivity(); + initActivity() } else { - handlePermissionsDenied(); + handlePermissionsDenied() } } } - private void initActivity() { + private fun initActivity() { try { - startActivity(new Intent(this, GameActivityMain.class)); - finish(); - } catch (Exception e) { - e.printStackTrace(); - Toast.makeText(this, "Ошибка запуска приложения", Toast.LENGTH_SHORT).show(); - finish(); + startActivity(Intent(this, GameActivityMain::class.java)) + finish() + } catch (e: Exception) { + e.printStackTrace() + Toast.makeText(this, "Ошибка запуска приложения", Toast.LENGTH_SHORT).show() + finish() } } } \ No newline at end of file diff --git a/app/src/main/java/com/ea/ironmonkey/RunLoop.kt b/app/src/main/java/com/ea/ironmonkey/RunLoop.kt index cceb6c2..f4eb128 100644 --- a/app/src/main/java/com/ea/ironmonkey/RunLoop.kt +++ b/app/src/main/java/com/ea/ironmonkey/RunLoop.kt @@ -1,57 +1,52 @@ -package com.ea.ironmonkey; - -import android.opengl.GLSurfaceView; +package com.ea.ironmonkey -public class RunLoop { - public static final int STATE_RUNNING = 1; - public static final int STATE_STOPPED = 0; - private GLSurfaceView glSurfaceView; - private int state; +import android.opengl.GLSurfaceView +import android.util.Log - private native void nativeOnRunLoopTick(); +class RunLoop(private val glSurfaceView: GLSurfaceView) { - public RunLoop(GLSurfaceView gLSurfaceView) { - this.glSurfaceView = gLSurfaceView; - updateRenderMode(); + companion object { + private const val TAG = "RunLoop" + private const val STATE_STOPPED = 0 + private const val STATE_RUNNING = 1 } - public int getState() { - return this.state; + private var state: Int = STATE_STOPPED + + private external fun nativeOnRunLoopTick() + + val currentState: Int + get() = state + + fun start() { + setState(STATE_RUNNING) } - public void start() { - setState(1); + fun stop() { + setState(STATE_STOPPED) } - public void stop() { - setState(0); + fun join() { + setState(STATE_STOPPED) } - public void join() { - setState(0); + private fun setState(newState: Int) { + state = newState + updateRenderMode() } - private void setState(int i) { - this.state = i; - updateRenderMode(); - } - - private void updateRenderMode() { - Log.v("RunLoop", "RunLoop.state = " + this.state); - switch (this.state) { - case 0: - this.glSurfaceView.setRenderMode(0); - break; - case 1: - this.glSurfaceView.setRenderMode(1); - break; + private fun updateRenderMode() { + Log.v(TAG, "RunLoop.state = $state") + when (state) { + STATE_STOPPED -> glSurfaceView.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY + STATE_RUNNING -> glSurfaceView.renderMode = GLSurfaceView.RENDERMODE_CONTINUOUSLY } } - public void onRunLoopTick() { - if (this.state == 1) { - nativeOnRunLoopTick(); + fun onRunLoopTick() { + if (state == STATE_RUNNING) { + nativeOnRunLoopTick() } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/ea/ironmonkey/SplashScreen.kt b/app/src/main/java/com/ea/ironmonkey/SplashScreen.kt index 9d25f97..d6e79de 100644 --- a/app/src/main/java/com/ea/ironmonkey/SplashScreen.kt +++ b/app/src/main/java/com/ea/ironmonkey/SplashScreen.kt @@ -1,255 +1,258 @@ -package com.ea.ironmonkey; +package com.ea.ironmonkey -import android.app.Activity; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.opengl.GLES20; -import android.opengl.GLUtils; +import android.app.Activity +import android.graphics.BitmapFactory +import android.opengl.GLES20 +import android.opengl.GLUtils +import android.util.Log +import java.io.IOException +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.FloatBuffer +import javax.microedition.khronos.opengles.GL10 -import java.io.IOException; -import java.io.InputStream; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import javax.microedition.khronos.opengles.GL10; +class SplashScreen(private val activity: Activity) { - -public class SplashScreen { - private static final String TAG = "SplashScreen"; - private Activity _activity; - private int _attPosition; - private int _attSampler; - private int _attTexCoord; - private int _fragmentShader; - private int _program; - private int _vertexShader; - private FloatBuffer vBuffer; - - // Вершинный шейдер - private final String vShaderStr = - "attribute vec4 a_position; \n" + - "attribute vec2 a_texCoord; \n" + - "varying vec2 v_texCoord; \n" + - "void main() { \n" + - " gl_Position = a_position; \n" + - " v_texCoord = a_texCoord; \n" + - "} \n"; - - // Фрагментный шейдер - private final String fShaderStr = - "precision mediump float; \n" + - "varying vec2 v_texCoord; \n" + - "uniform sampler2D s_texture; \n" + - "void main() { \n" + - " gl_FragColor = texture2D(s_texture, v_texCoord); \n" + - "} \n"; - - private int[] _textureId = new int[1]; - - public SplashScreen(Activity activity) { - this._activity = activity; + companion object { + private const val TAG = "SplashScreen" } - public void init(GL10 gl10, int width, int height) { + // Вершинный шейдер + private val vertexShaderStr = """ + attribute vec4 a_position; + attribute vec2 a_texCoord; + varying vec2 v_texCoord; + void main() { + gl_Position = a_position; + v_texCoord = a_texCoord; + } + """.trimIndent() + + // Фрагментный шейдер + private val fragmentShaderStr = """ + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + void main() { + gl_FragColor = texture2D(s_texture, v_texCoord); + } + """.trimIndent() + + private var attPosition = 0 + private var attSampler = 0 + private var attTexCoord = 0 + private var fragmentShader = 0 + private var program = 0 + private var vertexShader = 0 + private var vBuffer: FloatBuffer? = null + private var textureId = IntArray(1) + + fun init(gl10: GL10?, width: Int, height: Int) { + Log.i("splash", "Я родился!") if (!initRenderer()) { - destroy(gl10); - return; + destroy(gl10) + return } // Загрузка текстуры - GLES20.glGenTextures(1, _textureId, 0); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, _textureId[0]); + GLES20.glGenTextures(1, textureId, 0) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId[0]) // Установка параметров текстуры - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR) + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR) + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE) + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE) // Загрузка изображения - Bitmap bitmap = null; - try { - InputStream is = _activity.getAssets().open("splash.png"); - bitmap = BitmapFactory.decodeStream(is); - } catch (IOException e) { - Log.e(TAG, "Could not load bitmap", e); + val bitmap = try { + activity.assets.open("splash.png").use { stream -> + BitmapFactory.decodeStream(stream) + } + } catch (e: IOException) { + Log.e(TAG, "Could not load bitmap", e) + null } if (bitmap != null) { - GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); - bitmap.recycle(); + GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0) + bitmap.recycle() } else { - Log.e(TAG, "Failed to load bitmap"); - destroy(gl10); - return; + Log.e(TAG, "Failed to load bitmap") + destroy(gl10) + return } // Проверка ошибок - int error = GLES20.glGetError(); + val error = GLES20.glGetError() if (error != GLES20.GL_NO_ERROR) { - Log.e(TAG, "Texture Load GLError: " + error); - destroy(gl10); + Log.e(TAG, "Texture Load GLError: $error") + destroy(gl10) } } - private boolean initRenderer() { + private fun initRenderer(): Boolean { // Загрузка шейдеров - _vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vShaderStr); - _fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fShaderStr); + vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderStr) + fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderStr) // Создание программы - _program = GLES20.glCreateProgram(); - if (_program == 0) { - Log.e(TAG, "Failed to create program"); - return false; + program = GLES20.glCreateProgram() + if (program == 0) { + Log.e(TAG, "Failed to create program") + return false } // Прикрепление шейдеров - GLES20.glAttachShader(_program, _vertexShader); - GLES20.glAttachShader(_program, _fragmentShader); + GLES20.glAttachShader(program, vertexShader) + GLES20.glAttachShader(program, fragmentShader) // Линковка программы - GLES20.glLinkProgram(_program); + GLES20.glLinkProgram(program) // Проверка статуса линковки - int[] linkStatus = new int[1]; - GLES20.glGetProgramiv(_program, GLES20.GL_LINK_STATUS, linkStatus, 0); + val linkStatus = IntArray(1) + GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0) if (linkStatus[0] != GLES20.GL_TRUE) { - Log.e(TAG, "Could not link program: " + GLES20.glGetProgramInfoLog(_program)); - GLES20.glDeleteProgram(_program); - _program = 0; - return false; + Log.e(TAG, "Could not link program: ${GLES20.glGetProgramInfoLog(program)}") + GLES20.glDeleteProgram(program) + program = 0 + return false } // Получение атрибутов - _attPosition = GLES20.glGetAttribLocation(_program, "a_position"); - _attTexCoord = GLES20.glGetAttribLocation(_program, "a_texCoord"); - _attSampler = GLES20.glGetUniformLocation(_program, "s_texture"); + attPosition = GLES20.glGetAttribLocation(program, "a_position") + attTexCoord = GLES20.glGetAttribLocation(program, "a_texCoord") + attSampler = GLES20.glGetUniformLocation(program, "s_texture") - return true; + return true } - private int loadShader(int type, String shaderCode) { - int shader = GLES20.glCreateShader(type); + private fun loadShader(type: Int, shaderCode: String): Int { + val shader = GLES20.glCreateShader(type) if (shader == 0) { - Log.e(TAG, "Failed to create shader"); - return 0; + Log.e(TAG, "Failed to create shader") + return 0 } - GLES20.glShaderSource(shader, shaderCode); - GLES20.glCompileShader(shader); + GLES20.glShaderSource(shader, shaderCode) + GLES20.glCompileShader(shader) // Проверка статуса компиляции - int[] compiled = new int[1]; - GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); + val compiled = IntArray(1) + GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0) if (compiled[0] == 0) { - Log.e(TAG, "Could not compile shader: " + GLES20.glGetShaderInfoLog(shader)); - GLES20.glDeleteShader(shader); - return 0; + Log.e(TAG, "Could not compile shader: ${GLES20.glGetShaderInfoLog(shader)}") + GLES20.glDeleteShader(shader) + return 0 } - return shader; + return shader } - public boolean draw(GL10 gl10, int width, int height) { - if (_textureId[0] == 0 || _program == 0) { - return false; + fun draw(gl10: GL10?, width: Int, height: Int): Boolean { + if (textureId[0] == 0 || program == 0) { + return false } // Расчет координат с уменьшением на 20% - float ratio = (float) width / height; - float imageRatio = 1.0f; // Предполагаем квадратное изображение + val ratio = width.toFloat() / height + val imageRatio = 1.0f // Предполагаем квадратное изображение - float scaleX, scaleY; - if (ratio > imageRatio) { + val (scaleX, scaleY) = if (ratio > imageRatio) { // Шире, чем изображение - scaleY = 0.8f; // Уменьшаем на 20% - scaleX = imageRatio / ratio * 0.8f; + val scaleY = 0.8f // Уменьшаем на 20% + val scaleX = imageRatio / ratio * 0.8f + scaleX to scaleY } else { // Уже, чем изображение - scaleX = 0.8f; // Уменьшаем на 20% - scaleY = ratio / imageRatio * 0.8f; + val scaleX = 0.8f // Уменьшаем на 20% + val scaleY = ratio / imageRatio * 0.8f + scaleX to scaleY } // Координаты вершин и текстур - float[] vertices = { - -scaleX, -scaleY, 0.0f, // нижний левый - scaleX, -scaleY, 0.0f, // нижний правый - -scaleX, scaleY, 0.0f, // верхний левый - scaleX, scaleY, 0.0f // верхний правый - }; + val vertices = floatArrayOf( + -scaleX, -scaleY, 0.0f, // нижний левый + scaleX, -scaleY, 0.0f, // нижний правый + -scaleX, scaleY, 0.0f, // верхний левый + scaleX, scaleY, 0.0f // верхний правый + ) - float[] texCoords = { - 0.0f, 1.0f, // нижний левый - 1.0f, 1.0f, // нижний правый - 0.0f, 0.0f, // верхний левый - 1.0f, 0.0f // верхний правый - }; + val texCoords = floatArrayOf( + 0.0f, 1.0f, // нижний левый + 1.0f, 1.0f, // нижний правый + 0.0f, 0.0f, // верхний левый + 1.0f, 0.0f // верхний правый + ) // Создание буферов - ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4); - bb.order(ByteOrder.nativeOrder()); - FloatBuffer vertexBuffer = bb.asFloatBuffer(); - vertexBuffer.put(vertices); - vertexBuffer.position(0); + val vertexBuffer = ByteBuffer + .allocateDirect(vertices.size * 4) + .order(ByteOrder.nativeOrder()) + .asFloatBuffer() + .apply { + put(vertices) + position(0) + } - bb = ByteBuffer.allocateDirect(texCoords.length * 4); - bb.order(ByteOrder.nativeOrder()); - FloatBuffer texBuffer = bb.asFloatBuffer(); - texBuffer.put(texCoords); - texBuffer.position(0); + val texBuffer = ByteBuffer + .allocateDirect(texCoords.size * 4) + .order(ByteOrder.nativeOrder()) + .asFloatBuffer() + .apply { + put(texCoords) + position(0) + } // Отрисовка с белым фоном - GLES20.glViewport(0, 0, width, height); - GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Белый цвет - GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); + GLES20.glViewport(0, 0, width, height) + GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f) // Белый цвет + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) - GLES20.glUseProgram(_program); + GLES20.glUseProgram(program) // Передача вершин - GLES20.glVertexAttribPointer(_attPosition, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer); - GLES20.glEnableVertexAttribArray(_attPosition); + GLES20.glVertexAttribPointer(attPosition, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer) + GLES20.glEnableVertexAttribArray(attPosition) // Передача текстурных координат - GLES20.glVertexAttribPointer(_attTexCoord, 2, GLES20.GL_FLOAT, false, 0, texBuffer); - GLES20.glEnableVertexAttribArray(_attTexCoord); + GLES20.glVertexAttribPointer(attTexCoord, 2, GLES20.GL_FLOAT, false, 0, texBuffer) + GLES20.glEnableVertexAttribArray(attTexCoord) // Активация текстуры - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, _textureId[0]); - GLES20.glUniform1i(_attSampler, 0); + GLES20.glActiveTexture(GLES20.GL_TEXTURE0) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId[0]) + GLES20.glUniform1i(attSampler, 0) // Отрисовка - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4) // Отключение атрибутов - GLES20.glDisableVertexAttribArray(_attPosition); - GLES20.glDisableVertexAttribArray(_attTexCoord); + GLES20.glDisableVertexAttribArray(attPosition) + GLES20.glDisableVertexAttribArray(attTexCoord) - return true; + return true } - public void destroy(GL10 gl10) { - if (_textureId[0] != 0) { - GLES20.glDeleteTextures(1, _textureId, 0); - _textureId[0] = 0; + fun destroy(gl10: GL10?) { + if (textureId[0] != 0) { + GLES20.glDeleteTextures(1, textureId, 0) + textureId[0] = 0 } - if (_program != 0) { - GLES20.glDeleteProgram(_program); - _program = 0; + if (program != 0) { + GLES20.glDeleteProgram(program) + program = 0 } - if (_vertexShader != 0) { - GLES20.glDeleteShader(_vertexShader); - _vertexShader = 0; + if (vertexShader != 0) { + GLES20.glDeleteShader(vertexShader) + vertexShader = 0 } - if (_fragmentShader != 0) { - GLES20.glDeleteShader(_fragmentShader); - _fragmentShader = 0; - } - if (vBuffer != null) { - vBuffer.clear(); - vBuffer = null; + if (fragmentShader != 0) { + GLES20.glDeleteShader(fragmentShader) + fragmentShader = 0 } + vBuffer?.clear() + vBuffer = null } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/ea/ironmonkey/domain/AssetLocationType.kt b/app/src/main/java/com/ea/ironmonkey/domain/AssetLocationType.kt new file mode 100644 index 0000000..fe2def1 --- /dev/null +++ b/app/src/main/java/com/ea/ironmonkey/domain/AssetLocationType.kt @@ -0,0 +1,7 @@ +package com.ea.ironmonkey.domain + +enum class AssetLocationType { + EXTERNAL, + ASSETS, + OBB +} \ No newline at end of file diff --git a/app/src/main/java/com/ea/ironmonkey/domain/FSNode.kt b/app/src/main/java/com/ea/ironmonkey/domain/FSNode.kt new file mode 100644 index 0000000..e7dc79a --- /dev/null +++ b/app/src/main/java/com/ea/ironmonkey/domain/FSNode.kt @@ -0,0 +1,11 @@ +package com.ea.ironmonkey.domain + +import com.google.gson.annotations.SerializedName + +class FSNode { + @SerializedName("directory") + var directory: Boolean = false + + @SerializedName("size") + var size: Int = 0 +} \ No newline at end of file