diff --git a/.gitignore b/.gitignore
index 8f5d0c5..09f66fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.vs
Debug
Release
-log.txt
\ No newline at end of file
+log.txt
+build
\ No newline at end of file
diff --git a/proj.android-studio/app/.gitignore b/proj.android-studio/app/.gitignore
deleted file mode 100755
index 796b96d..0000000
--- a/proj.android-studio/app/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/proj.android-studio/app/CMakeLists.txt b/proj.android-studio/app/CMakeLists.txt
index 1659b89..f9ea7c9 100755
--- a/proj.android-studio/app/CMakeLists.txt
+++ b/proj.android-studio/app/CMakeLists.txt
@@ -20,7 +20,6 @@ include_directories(${LIBJPEG_PATH}/vc10)
include_directories(${LUA_PATH})
include_directories(${EIGEN_PATH})
include_directories(${SOL2_PATH})
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../)
include_directories(${BOOST_PATH})
include_directories(${LIBPNG_PATH})
include_directories(${LIBJPEG_PATH})
diff --git a/proj.android-studio/app/build.gradle b/proj.android-studio/app/build.gradle
index da141e3..68332a8 100755
--- a/proj.android-studio/app/build.gradle
+++ b/proj.android-studio/app/build.gradle
@@ -1,43 +1,75 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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.
+ */
+
apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
android {
compileSdkVersion 28
- buildToolsVersion "28.0.0"
+
defaultConfig {
applicationId "fishrungames.mountainwallpaper"
minSdkVersion 19
targetSdkVersion 28
versionCode 2
versionName "1.1"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions -fsigned-char -Wno-c++11-narrowing"
+ abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86'
}
}
}
+
buildTypes {
release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
- externalNativeBuild {
- cmake {
- path "CMakeLists.txt"
+ minifyEnabled true
+ shrinkResources true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), file('proguard-project.txt')
}
}
+
sourceSets {
main {
assets.srcDirs = ['../../assets/']
}
}
+
+ splits {
+ abi {
+ enable true
+ reset()
+ include 'arm64-v8a', 'armeabi-v7a', 'x86'
+ }
+ }
+
+ externalNativeBuild {
+ cmake {
+ path 'CMakeLists.txt'
+ }
+ }
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
- compile 'com.android.support:appcompat-v7:28+'
+ implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
+ implementation "com.android.support:preference-v7:$supportLibraryVersion"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
- compile project(':SalmonEngineAndroid')
-}
+ implementation project(':SalmonEngineAndroid')
+}
\ No newline at end of file
diff --git a/proj.android-studio/app/src/androidTest/java/fishrungames/salmonandroidtemplate/ExampleInstrumentedTest.java b/proj.android-studio/app/src/androidTest/java/fishrungames/salmonandroidtemplate/ExampleInstrumentedTest.java
deleted file mode 100755
index c282df4..0000000
--- a/proj.android-studio/app/src/androidTest/java/fishrungames/salmonandroidtemplate/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package fishrungames.salmonandroidtemplate;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumentation test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("fishrungames.salmonandroidtemplate", appContext.getPackageName());
- }
-}
diff --git a/proj.android-studio/app/src/main/AndroidManifest.xml b/proj.android-studio/app/src/main/AndroidManifest.xml
index 42e214a..06c84e0 100755
--- a/proj.android-studio/app/src/main/AndroidManifest.xml
+++ b/proj.android-studio/app/src/main/AndroidManifest.xml
@@ -1,41 +1,90 @@
-
+
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="fishrungames.mountainwallpaper">
-
+
+
-
+
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
-
+
+
+
+
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/BaseConfigChooser.kt b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/BaseConfigChooser.kt
new file mode 100755
index 0000000..25dac47
--- /dev/null
+++ b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/BaseConfigChooser.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 fishrungames.mountainwallpaper
+
+import android.opengl.GLSurfaceView
+
+import javax.microedition.khronos.egl.EGL10
+import javax.microedition.khronos.egl.EGLConfig
+import javax.microedition.khronos.egl.EGLDisplay
+
+/**
+ * Created by romannurik on 11/6/13.
+ */
+internal abstract class BaseConfigChooser(configSpec: IntArray, private val eglContextClientVersion: Int) : GLSurfaceView.EGLConfigChooser {
+
+ protected var mConfigSpec: IntArray
+
+ init {
+ mConfigSpec = filterConfigSpec(configSpec)
+ }
+
+ override fun chooseConfig(egl: EGL10, display: EGLDisplay): EGLConfig {
+ val num_config = IntArray(1)
+ if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
+ num_config)) {
+ throw IllegalArgumentException("eglChooseConfig failed")
+ }
+
+ val numConfigs = num_config[0]
+
+ if (numConfigs <= 0) {
+ throw IllegalArgumentException(
+ "No configs match configSpec")
+ }
+
+ val configs = kotlin.arrayOfNulls(numConfigs)
+ if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
+ num_config)) {
+ throw IllegalArgumentException("eglChooseConfig#2 failed")
+ }
+ return chooseConfig(egl, display, configs)
+ ?: throw IllegalArgumentException("No config chosen")
+ }
+
+ internal abstract fun chooseConfig(egl: EGL10, display: EGLDisplay,
+ configs: Array): EGLConfig?
+
+ private fun filterConfigSpec(configSpec: IntArray): IntArray {
+ if (eglContextClientVersion != 2) {
+ return configSpec
+ }
+ /* We know none of the subclasses define EGL_RENDERABLE_TYPE.
+ * And we know the configSpec is well formed.
+ */
+ val len = configSpec.size
+ val newConfigSpec = IntArray(len + 2)
+ System.arraycopy(configSpec, 0, newConfigSpec, 0, len - 1)
+ newConfigSpec[len - 1] = EGL10.EGL_RENDERABLE_TYPE
+ newConfigSpec[len] = 4 /* EGL_OPENGL_ES2_BIT */
+ newConfigSpec[len + 1] = EGL10.EGL_NONE
+ return newConfigSpec
+ }
+
+ open class ComponentSizeChooser(// Subclasses can adjust these values:
+ protected var mRedSize: Int, protected var mGreenSize: Int, protected var mBlueSize: Int, protected var mAlphaSize: Int, protected var mDepthSize: Int,
+ protected var mStencilSize: Int, eglContextClientVersion: Int) : BaseConfigChooser(intArrayOf(EGL10.EGL_RED_SIZE, mRedSize, EGL10.EGL_GREEN_SIZE, mGreenSize, EGL10.EGL_BLUE_SIZE, mBlueSize, EGL10.EGL_ALPHA_SIZE, mAlphaSize, EGL10.EGL_DEPTH_SIZE, mDepthSize, EGL10.EGL_STENCIL_SIZE, mStencilSize, EGL10.EGL_NONE), eglContextClientVersion) {
+
+ private val mValue: IntArray
+
+ init {
+ mValue = IntArray(1)
+ }
+
+ public override fun chooseConfig(egl: EGL10, display: EGLDisplay, configs: Array): EGLConfig? {
+ var closestConfig: EGLConfig? = null
+ var closestDistance = 1000
+ for (config in configs) {
+ val d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE)
+ val s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE)
+ if (d >= mDepthSize && s >= mStencilSize) {
+ val r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE)
+ val g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE)
+ val b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE)
+ val a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE)
+ val distance = (Math.abs(r - mRedSize) + Math.abs(g - mGreenSize) + Math.abs(b - mBlueSize)
+ + Math.abs(a - mAlphaSize))
+ if (distance < closestDistance) {
+ closestDistance = distance
+ closestConfig = config
+ }
+ }
+ }
+ return closestConfig
+ }
+
+ private fun findConfigAttrib(egl: EGL10, display: EGLDisplay, config: EGLConfig?, attribute: Int): Int {
+
+ return if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
+ mValue[0]
+ } else 0
+ }
+ }
+
+ /**
+ * This class will choose a supported surface as close to RGB565 as possible, with or without a depth buffer.
+ */
+ class SimpleEGLConfigChooser(withDepthBuffer: Boolean, eglContextClientVersion: Int) : ComponentSizeChooser(4, 4, 4, 0, if (withDepthBuffer) 16 else 0, 0, eglContextClientVersion) {
+ init {
+ // Adjust target values. This way we'll accept a 4444 or
+ // 555 buffer if there's no 565 buffer available.
+ mRedSize = 5
+ mGreenSize = 6
+ mBlueSize = 5
+ }
+ }
+}
\ No newline at end of file
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/GLWallpaperService.java b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/GLWallpaperService.java
deleted file mode 100755
index 45a91ad..0000000
--- a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/GLWallpaperService.java
+++ /dev/null
@@ -1,960 +0,0 @@
-package fishrungames.mountainwallpaper;
-
-
-import fishrungames.mountainwallpaper.BaseConfigChooser.ComponentSizeChooser;
-import fishrungames.mountainwallpaper.BaseConfigChooser.SimpleEGLConfigChooser;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-
-
-import android.service.wallpaper.WallpaperService;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import fishrungames.salmonengineandroid.EngineWrapper;
-
-
-public class GLWallpaperService extends WallpaperService {
- private static final String TAG = "GLWallpaperService";
-
- @Override
- public Engine onCreateEngine() {
- return new GLEngine();
- }
-
- public class GLEngine extends Engine {
- public final static int RENDERMODE_WHEN_DIRTY = 0;
- public final static int RENDERMODE_CONTINUOUSLY = 1;
-
- private GLThread mGLThread;
- private EGLConfigChooser mEGLConfigChooser;
- private EGLContextFactory mEGLContextFactory;
- private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
-
- private int mDebugFlags;
-
- public GLEngine() {
- super();
- }
-
- @Override
- public void onVisibilityChanged(boolean visible) {
- if (visible) {
- onResume();
- } else {
- onPause();
- }
- super.onVisibilityChanged(visible);
- }
-
- @Override
- public void onCreate(SurfaceHolder surfaceHolder) {
- super.onCreate(surfaceHolder);
- // Log.d(TAG, "GLEngine.onCreate()");
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- // Log.d(TAG, "GLEngine.onDestroy()");
- mGLThread.requestExitAndWait();
- }
-
- @Override
- public void onSurfaceChanged(SurfaceHolder holder, int format,
- int width, int height) {
- // Log.d(TAG, "onSurfaceChanged()");
-
-
-
- mGLThread.onWindowResize(width, height);
-
- super.onSurfaceChanged(holder, format, width, height);
- }
-
- @Override
- public void onSurfaceCreated(SurfaceHolder holder) {
- Log.d(TAG, "onSurfaceCreated()");
- mGLThread.surfaceCreated(holder);
- super.onSurfaceCreated(holder);
- }
-
- @Override
- public void onSurfaceDestroyed(SurfaceHolder holder) {
- Log.d(TAG, "onSurfaceDestroyed()");
- mGLThread.surfaceDestroyed();
- super.onSurfaceDestroyed(holder);
- }
-
-
- public void setDebugFlags(int debugFlags) {
- mDebugFlags = debugFlags;
- }
-
- public int getDebugFlags() {
- return mDebugFlags;
- }
-
- public void setRenderer() {
- checkRenderThreadState();
- if (mEGLConfigChooser == null) {
- mEGLConfigChooser = new SimpleEGLConfigChooser(true);
- }
- if (mEGLContextFactory == null) {
- //mEGLContextFactory = new DefaultContextFactory();
- mEGLContextFactory = new ES20ContextFactory();
- }
- if (mEGLWindowSurfaceFactory == null) {
- mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
- }
- mGLThread = new GLThread(mEGLConfigChooser,
- mEGLContextFactory, mEGLWindowSurfaceFactory);
- mGLThread.start();
- }
-
- public void setEGLContextFactory(EGLContextFactory factory) {
- checkRenderThreadState();
- mEGLContextFactory = factory;
- }
-
- public void setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {
- checkRenderThreadState();
- mEGLWindowSurfaceFactory = factory;
- }
-
- public void setEGLConfigChooser(EGLConfigChooser configChooser) {
- checkRenderThreadState();
- mEGLConfigChooser = configChooser;
- }
-
- public void setEGLConfigChooser(boolean needDepth) {
- setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth));
- }
-
- public void setEGLConfigChooser(int redSize, int greenSize,
- int blueSize, int alphaSize, int depthSize, int stencilSize) {
- setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize,
- blueSize, alphaSize, depthSize, stencilSize));
- }
-
- public void setRenderMode(int renderMode) {
- mGLThread.setRenderMode(renderMode);
- }
-
- public int getRenderMode() {
- return mGLThread.getRenderMode();
- }
-
- public void requestRender() {
- mGLThread.requestRender();
- }
-
- public void onPause() {
- mGLThread.onPause();
- }
-
- public void onResume() {
- mGLThread.onResume();
- }
-
- public void queueEvent(Runnable r) {
- mGLThread.queueEvent(r);
- }
-
- private void checkRenderThreadState() {
- if (mGLThread != null) {
- throw new IllegalStateException(
- "setRenderer has already been called for this instance.");
- }
- }
- }
-}
-
-
-// ----------------------------------------------------------------------
-
-/**
- * An interface for customizing the eglCreateContext and eglDestroyContext
- * calls.
- *
- *
- * This interface must be implemented by clients wishing to call
- * {@link GLWallpaperService.GLEngine#setEGLContextFactory(EGLContextFactory)}
- */
-interface EGLContextFactory {
- EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig);
-
- void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context);
-}
-
-class DefaultContextFactory implements EGLContextFactory {
-
- public EGLContext createContext(EGL10 egl, EGLDisplay display,
- EGLConfig config) {
- return egl
- .eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null);
- }
-
- public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
- egl.eglDestroyContext(display, context);
- }
-}
-
-
-class ES20ContextFactory implements EGLContextFactory {
-
- private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
-
- public EGLContext createContext(EGL10 egl, EGLDisplay display,
- EGLConfig config) {
-
-
- int[] attrib_list =
- { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
-
- return egl
- .eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, attrib_list);
- }
-
- public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
- egl.eglDestroyContext(display, context);
- }
-}
-
-/**
- * An interface for customizing the eglCreateWindowSurface and eglDestroySurface
- * calls.
- *
- *
- * This interface must be implemented by clients wishing to call
- * {@link GLWallpaperService.GLEngine#setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory)}
- */
-interface EGLWindowSurfaceFactory {
- EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
- EGLConfig config, Object nativeWindow);
-
- void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface);
-}
-
-class DefaultWindowSurfaceFactory implements EGLWindowSurfaceFactory {
-
- public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
- EGLConfig config, Object nativeWindow) {
- // this is a bit of a hack to work around Droid init problems - if you
- // don't have this, it'll get hung up on orientation changes
- EGLSurface eglSurface = null;
- while (eglSurface == null) {
- try {
- eglSurface = egl.eglCreateWindowSurface(display, config,
- nativeWindow, null);
- } catch (Throwable t) {
- } finally {
- if (eglSurface == null) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException t) {
- }
- }
- }
- }
- return eglSurface;
- }
-
- public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
- egl.eglDestroySurface(display, surface);
- }
-}
-
-
-class EglHelper {
-
- private EGL10 mEgl;
- private EGLDisplay mEglDisplay;
- private EGLSurface mEglSurface;
- private EGLContext mEglContext;
- EGLConfig mEglConfig;
-
- private EGLConfigChooser mEGLConfigChooser;
- private EGLContextFactory mEGLContextFactory;
- private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
-
-
- public EglHelper(EGLConfigChooser chooser,
- EGLContextFactory contextFactory,
- EGLWindowSurfaceFactory surfaceFactory) {
- this.mEGLConfigChooser = chooser;
- this.mEGLContextFactory = contextFactory;
- this.mEGLWindowSurfaceFactory = surfaceFactory;
-
- }
-
- /**
- * Initialize EGL for a given configuration spec.
- *
- * configSpec
- */
- public void start() {
- String instanceId = "";
- Log.d("EglHelper" + instanceId, "start()");
- if (mEgl == null) {
- Log.d("EglHelper" + instanceId, "getting new EGL");
- /*
- * Get an EGL instance
- */
- mEgl = (EGL10) EGLContext.getEGL();
- } else {
- Log.d("EglHelper" + instanceId, "reusing EGL");
- }
-
- if (mEglDisplay == null) {
- Log.d("EglHelper" + instanceId, "getting new display");
- /*
- * Get to the default display.
- */
- mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
- } else {
- Log.d("EglHelper" + instanceId, "reusing display");
- }
-
- if (mEglConfig == null) {
- Log.d("EglHelper" + instanceId, "getting new config");
- /*
- * We can now initialize EGL for that display
- */
- int[] version = new int[2];
- mEgl.eglInitialize(mEglDisplay, version);
- mEglConfig = mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
- } else {
- Log.d("EglHelper" + instanceId, "reusing config");
- }
-
- if (mEglContext == null) {
- Log.d("EglHelper" + instanceId, "creating new context");
- /*
- * Create an OpenGL ES context. This must be done only once, an
- * OpenGL context is a somewhat heavy object.
- */
- mEglContext = mEGLContextFactory.createContext(mEgl, mEglDisplay,
- mEglConfig);
- if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
- throw new RuntimeException("createContext failed");
- }
- } else {
- Log.d("EglHelper" + instanceId, "reusing context");
- }
-
- mEglSurface = null;
- }
-
- /*
- * React to the creation of a new surface by creating and returning an
- * OpenGL interface that renders to that surface.
- */
-
-
- public void createSurface(SurfaceHolder holder) {
-
- if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
-
-
- mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
- EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
- mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay,
- mEglSurface);
- }
-
-
- mEglSurface = mEGLWindowSurfaceFactory.createWindowSurface(mEgl,
- mEglDisplay, mEglConfig, holder);
-
- if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
- throw new RuntimeException("createWindowSurface failed");
- }
-
-
- if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
- mEglContext)) {
- //throw new RuntimeException("eglMakeCurrent failed.");
- }
-
-
- }
-
- /**
- * Display the current render surface.
- *
- * @return false if the context has been lost.
- */
- public boolean swap() {
- try {
- mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
- } catch (Exception e) {
- return false;
- }
-
- return true;
-
-
- /*
- * Always check for EGL_CONTEXT_LOST, which means the context and all
- * associated data were lost (For instance because the device went to
- * sleep). We need to sleep until we get a new surface.
- */
-
- }
-
- public void destroySurface() {
- if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
- mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
- EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
- mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay,
- mEglSurface);
- mEglSurface = null;
- }
- }
-
- public void finish() {
- if (mEglContext != null) {
- mEGLContextFactory.destroyContext(mEgl, mEglDisplay, mEglContext);
- mEglContext = null;
- }
- if (mEglDisplay != null) {
- mEgl.eglTerminate(mEglDisplay);
- mEglDisplay = null;
- }
- }
-}
-
-class GLThread extends Thread {
- private final static boolean LOG_THREADS = false;
- public final static int DEBUG_CHECK_GL_ERROR = 1;
- public final static int DEBUG_LOG_GL_CALLS = 2;
-
- private final GLThreadManager sGLThreadManager = new GLThreadManager();
- private GLThread mEglOwner;
-
- private EGLConfigChooser mEGLConfigChooser;
- private EGLContextFactory mEGLContextFactory;
- private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
-
-
- public SurfaceHolder mHolder;
- private boolean mSizeChanged = true;
-
- // Once the thread is started, all accesses to the following member
- // variables are protected by the sGLThreadManager monitor
- public boolean mDone;
- private boolean mPaused;
- private boolean mHasSurface;
- private boolean mWaitingForSurface;
- private boolean mHaveEgl;
- private int mWidth;
- private int mHeight;
- private int mRenderMode;
- private boolean mRequestRender;
- private boolean mEventsWaiting;
- // End of member variables protected by the sGLThreadManager monitor.
-
- //private GLWallpaperService.Renderer mRenderer;
-
- private ArrayList mEventQueue = new ArrayList();
- private EglHelper mEglHelper;
-
-
- static long lastTimeStamp;
- static boolean gameIsInited = false;
-
- GLThread(EGLConfigChooser chooser,
- EGLContextFactory contextFactory,
- EGLWindowSurfaceFactory surfaceFactory) {
- super();
- mDone = false;
- mWidth = 0;
- mHeight = 0;
- mRequestRender = true;
- mRenderMode = GLWallpaperService.GLEngine.RENDERMODE_CONTINUOUSLY;
-
- this.mEGLConfigChooser = chooser;
- this.mEGLContextFactory = contextFactory;
- this.mEGLWindowSurfaceFactory = surfaceFactory;
-
- Calendar c = Calendar.getInstance();
- lastTimeStamp = c.getTimeInMillis();
- gameIsInited = true;
- }
-
- @Override
- public void run() {
- setName("GLThread " + getId());
- if (LOG_THREADS) {
- Log.i("GLThread", "starting tid=" + getId());
- }
-
- try {
- guardedRun();
- } catch (InterruptedException e) {
- // fall thru and exit normally
- } finally {
- sGLThreadManager.threadExiting(this);
- }
- }
-
- /*
- * This private method should only be called inside a
- * synchronized(sGLThreadManager) block.
- */
- private void stopEglLocked() {
- if (mHaveEgl) {
- mHaveEgl = false;
- mEglHelper.destroySurface();
- sGLThreadManager.releaseEglSurface(this);
- }
- }
-
- private void guardedRun() throws InterruptedException {
- mEglHelper = new EglHelper(mEGLConfigChooser, mEGLContextFactory,
- mEGLWindowSurfaceFactory/*, mGLWrapper*/);
- try {
-
- boolean tellRendererSurfaceCreated = true;
- boolean tellRendererSurfaceChanged = true;
-
- /*
- * This is our main activity thread's loop, we go until asked to
- * quit.
- */
- while (!isDone()) {
- /*
- * Update the asynchronous state (window size)
- */
- int w = 0;
- int h = 0;
- boolean changed = false;
- boolean needStart = false;
- boolean eventsWaiting = false;
-
- synchronized (sGLThreadManager) {
- while (true) {
- // Manage acquiring and releasing the SurfaceView
- // surface and the EGL surface.
- if (mPaused) {
- stopEglLocked();
- }
- if (!mHasSurface) {
- if (!mWaitingForSurface) {
- stopEglLocked();
- mWaitingForSurface = true;
- sGLThreadManager.notifyAll();
- }
- } else {
- if (!mHaveEgl) {
- if (sGLThreadManager.tryAcquireEglSurface(this)) {
- mHaveEgl = true;
- mEglHelper.start();
- mRequestRender = true;
- needStart = true;
- }
- }
- }
-
- // Check if we need to wait. If not, update any state
- // that needs to be updated, copy any state that
- // needs to be copied, and use "break" to exit the
- // wait loop.
-
- if (mDone) {
- return;
- }
-
- if (mEventsWaiting) {
- eventsWaiting = true;
- mEventsWaiting = false;
- break;
- }
-
- if ((!mPaused)
- && mHasSurface
- && mHaveEgl
- && (mWidth > 0)
- && (mHeight > 0)
- && (mRequestRender || (mRenderMode == GLWallpaperService.GLEngine.RENDERMODE_CONTINUOUSLY))) {
- changed = mSizeChanged;
- w = mWidth;
- h = mHeight;
- mSizeChanged = false;
- mRequestRender = false;
- if (mHasSurface && mWaitingForSurface) {
- changed = true;
- mWaitingForSurface = false;
- sGLThreadManager.notifyAll();
- }
- break;
- }
-
-
-
- // By design, this is the only place where we wait().
-
- if (LOG_THREADS) {
- Log.i("GLThread", "waiting tid=" + getId());
- }
- sGLThreadManager.wait();
- }
- } // end of synchronized(sGLThreadManager)
-
- /*
- * Handle queued events
- */
- if (eventsWaiting) {
- Runnable r;
- while ((r = getEvent()) != null) {
- r.run();
- if (isDone()) {
- return;
- }
- }
- // Go back and see if we need to wait to render.
- continue;
- }
-
- if (needStart) {
- tellRendererSurfaceCreated = true;
- changed = true;
- }
- if (changed) {
- mEglHelper.createSurface(mHolder);
- tellRendererSurfaceChanged = true;
- }
- if (tellRendererSurfaceCreated) {
-
- tellRendererSurfaceCreated = false;
- }
-
- if (tellRendererSurfaceChanged) {
-
-
- //Xperimental -- VLAD KHOREV
- JniWrapper.Init(w, h);
-
- tellRendererSurfaceChanged = false;
- }
-
-
- if ((w > 0) && (h > 0)) {
- /* draw a frame here */
-
- if (gameIsInited)
- {
- Calendar c = Calendar.getInstance();
-
- long currentTimeStamp = c.getTimeInMillis();
-
- EngineWrapper.Update(currentTimeStamp - lastTimeStamp);
-
- lastTimeStamp = currentTimeStamp;
-
- }
-
- /*
- * Once we're done with GL, we need to call swapBuffers() to
- * instruct the system to display the rendered frame
- */
- mEglHelper.swap();
- }
- }
- } finally {
- /*
- * clean-up everything...
- */
- synchronized (sGLThreadManager) {
- stopEglLocked();
- mEglHelper.finish();
- }
- }
- }
-
- private boolean isDone() {
- synchronized (sGLThreadManager) {
- return mDone;
- }
- }
-
- public void setRenderMode(int renderMode) {
- if (!((GLWallpaperService.GLEngine.RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= GLWallpaperService.GLEngine.RENDERMODE_CONTINUOUSLY))) {
- throw new IllegalArgumentException("renderMode");
- }
- synchronized (sGLThreadManager) {
- mRenderMode = renderMode;
- if (renderMode == GLWallpaperService.GLEngine.RENDERMODE_CONTINUOUSLY) {
- sGLThreadManager.notifyAll();
- }
- }
- }
-
- public int getRenderMode() {
- synchronized (sGLThreadManager) {
- return mRenderMode;
- }
- }
-
- public void requestRender() {
- synchronized (sGLThreadManager) {
- mRequestRender = true;
- sGLThreadManager.notifyAll();
- }
- }
-
- public void surfaceCreated(SurfaceHolder holder) {
- mHolder = holder;
- synchronized (sGLThreadManager) {
- if (LOG_THREADS) {
- Log.i("GLThread", "surfaceCreated tid=" + getId());
- }
- mHasSurface = true;
- sGLThreadManager.notifyAll();
- }
- }
-
- public void surfaceDestroyed() {
- synchronized (sGLThreadManager) {
- if (LOG_THREADS) {
- Log.i("GLThread", "surfaceDestroyed tid=" + getId());
- }
- mHasSurface = false;
- sGLThreadManager.notifyAll();
- while (!mWaitingForSurface && isAlive() && !mDone) {
- try {
- sGLThreadManager.wait();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- }
- }
-
- public void onPause() {
- synchronized (sGLThreadManager) {
- mPaused = true;
- sGLThreadManager.notifyAll();
- }
- }
-
- public void onResume() {
- synchronized (sGLThreadManager) {
- mPaused = false;
- mRequestRender = true;
- sGLThreadManager.notifyAll();
- }
- }
-
- public void onWindowResize(int w, int h) {
- synchronized (sGLThreadManager) {
- mWidth = w;
- mHeight = h;
- mSizeChanged = true;
- sGLThreadManager.notifyAll();
- }
- }
-
- public void requestExitAndWait() {
- // don't call this from GLThread thread or it is a guaranteed
- // deadlock!
- synchronized (sGLThreadManager) {
- mDone = true;
- sGLThreadManager.notifyAll();
- }
- try {
- join();
- } catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
-
- /**
- * Queue an "event" to be run on the GL rendering thread.
- *
- * @param r
- * the runnable to be run on the GL rendering thread.
- */
- public void queueEvent(Runnable r) {
- synchronized (this) {
- mEventQueue.add(r);
- synchronized (sGLThreadManager) {
- mEventsWaiting = true;
- sGLThreadManager.notifyAll();
- }
- }
- }
-
- private Runnable getEvent() {
- synchronized (this) {
- if (mEventQueue.size() > 0) {
- return (Runnable) mEventQueue.remove(0);
- }
-
- }
- return null;
- }
-
- private class GLThreadManager {
-
- public synchronized void threadExiting(GLThread thread) {
- if (LOG_THREADS) {
- Log.i("GLThread", "exiting tid=" + thread.getId());
- }
- thread.mDone = true;
- if (mEglOwner == thread) {
- mEglOwner = null;
- }
- notifyAll();
- }
-
- /*
- * Tries once to acquire the right to use an EGL surface. Does not
- * block.
- *
- * @return true if the right to use an EGL surface was acquired.
- */
- public synchronized boolean tryAcquireEglSurface(GLThread thread) {
- if (mEglOwner == thread || mEglOwner == null) {
- mEglOwner = thread;
- notifyAll();
- return true;
- }
- return false;
- }
-
- public synchronized void releaseEglSurface(GLThread thread) {
- if (mEglOwner == thread) {
- mEglOwner = null;
- }
- notifyAll();
- }
- }
-}
-
-interface EGLConfigChooser {
- EGLConfig chooseConfig(EGL10 egl, EGLDisplay display);
-}
-
-abstract class BaseConfigChooser implements EGLConfigChooser {
- public BaseConfigChooser(int[] configSpec) {
- mConfigSpec = configSpec;
- }
-
- public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
- int[] num_config = new int[1];
- egl.eglChooseConfig(display, mConfigSpec, null, 0, num_config);
-
- int numConfigs = num_config[0];
-
- if (numConfigs <= 0) {
- throw new IllegalArgumentException("No configs match configSpec");
- }
-
- EGLConfig[] configs = new EGLConfig[numConfigs];
- egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
- num_config);
- EGLConfig config = chooseConfig(egl, display, configs);
- if (config == null) {
- throw new IllegalArgumentException("No config chosen");
- }
- return config;
- }
-
- abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
- EGLConfig[] configs);
-
- protected int[] mConfigSpec;
-
- public static class ComponentSizeChooser extends BaseConfigChooser {
- public ComponentSizeChooser(int redSize, int greenSize, int blueSize,
- int alphaSize, int depthSize, int stencilSize) {
- super(new int[] { EGL10.EGL_RED_SIZE, redSize,
- EGL10.EGL_GREEN_SIZE, greenSize, EGL10.EGL_BLUE_SIZE,
- blueSize, EGL10.EGL_ALPHA_SIZE, alphaSize,
- EGL10.EGL_DEPTH_SIZE, depthSize, EGL10.EGL_STENCIL_SIZE,
- stencilSize, EGL10.EGL_NONE });
- mValue = new int[1];
- mRedSize = redSize;
- mGreenSize = greenSize;
- mBlueSize = blueSize;
- mAlphaSize = alphaSize;
- mDepthSize = depthSize;
- mStencilSize = stencilSize;
- }
-
- @Override
- public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
- EGLConfig[] configs) {
- EGLConfig closestConfig = null;
- int closestDistance = 1000;
- for (EGLConfig config : configs) {
- int d = findConfigAttrib(egl, display, config,
- EGL10.EGL_DEPTH_SIZE, 0);
- int s = findConfigAttrib(egl, display, config,
- EGL10.EGL_STENCIL_SIZE, 0);
- if (d >= mDepthSize && s >= mStencilSize) {
- int r = findConfigAttrib(egl, display, config,
- EGL10.EGL_RED_SIZE, 0);
- int g = findConfigAttrib(egl, display, config,
- EGL10.EGL_GREEN_SIZE, 0);
- int b = findConfigAttrib(egl, display, config,
- EGL10.EGL_BLUE_SIZE, 0);
- int a = findConfigAttrib(egl, display, config,
- EGL10.EGL_ALPHA_SIZE, 0);
- int distance = Math.abs(r - mRedSize)
- + Math.abs(g - mGreenSize)
- + Math.abs(b - mBlueSize)
- + Math.abs(a - mAlphaSize);
- if (distance < closestDistance) {
- closestDistance = distance;
- closestConfig = config;
- }
- }
- }
- return closestConfig;
- }
-
- private int findConfigAttrib(EGL10 egl, EGLDisplay display,
- EGLConfig config, int attribute, int defaultValue) {
-
- if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
- return mValue[0];
- }
- return defaultValue;
- }
-
- private int[] mValue;
- // Subclasses can adjust these values:
- protected int mRedSize;
- protected int mGreenSize;
- protected int mBlueSize;
- protected int mAlphaSize;
- protected int mDepthSize;
- protected int mStencilSize;
- }
-
- /**
- * This class will choose a supported surface as close to RGB565 as
- * possible, with or without a depth buffer.
- *
- */
- public static class SimpleEGLConfigChooser extends ComponentSizeChooser {
- public SimpleEGLConfigChooser(boolean withDepthBuffer) {
- super(4, 4, 4, 0, withDepthBuffer ? 16 : 0, 0);
- // Adjust target values. This way we'll accept a 4444 or
- // 555 buffer if there's no 565 buffer available.
- mRedSize = 5;
- mGreenSize = 6;
- mBlueSize = 5;
- }
- }
-}
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/GLWallpaperService.kt b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/GLWallpaperService.kt
new file mode 100755
index 0000000..b5f6e09
--- /dev/null
+++ b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/GLWallpaperService.kt
@@ -0,0 +1,764 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 fishrungames.mountainwallpaper
+
+import java.io.Writer
+import java.util.ArrayList
+
+import javax.microedition.khronos.egl.EGL10
+import javax.microedition.khronos.egl.EGL11
+import javax.microedition.khronos.egl.EGLConfig
+import javax.microedition.khronos.egl.EGLContext
+import javax.microedition.khronos.egl.EGLDisplay
+import javax.microedition.khronos.egl.EGLSurface
+import javax.microedition.khronos.opengles.GL
+import javax.microedition.khronos.opengles.GL10
+
+import android.opengl.GLSurfaceView
+import android.service.wallpaper.WallpaperService
+import android.util.Log
+import android.view.SurfaceHolder
+
+// Original code provided by Robert Green
+// http://www.rbgrn.net/content/354-glsurfaceview-adapted-3d-live-wallpapers
+
+open class GLWallpaperService : WallpaperService() {
+
+ companion object {
+ private val TAG = "GLWallpaperService"
+ val RENDERMODE_WHEN_DIRTY = 0;
+ val RENDERMODE_CONTINUOUSLY = 1;
+ }
+
+ override fun onCreateEngine(): WallpaperService.Engine {
+ return GLEngine()
+ }
+
+ open inner class GLEngine : WallpaperService.Engine() {
+
+ private var mGLThread: GLThread? = null
+ private var mEGLConfigChooser: GLSurfaceView.EGLConfigChooser? = null
+ private var mEGLContextFactory: GLSurfaceView.EGLContextFactory? = null
+ private var mEGLWindowSurfaceFactory: GLSurfaceView.EGLWindowSurfaceFactory? = null
+ private var mEGLContextClientVersion: Int = 0
+ var renderMode: Int
+ get() = mGLThread!!.renderMode
+ set(renderMode) {
+ mGLThread!!.renderMode = renderMode
+ }
+
+ override fun onVisibilityChanged(visible: Boolean) {
+ if (visible) {
+ onResume()
+ } else {
+ onPause()
+ }
+ super.onVisibilityChanged(visible)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // Log.d(TAG, "GLEngine.onDestroy()");
+ mGLThread!!.requestExitAndWait()
+ }
+
+ override fun onSurfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
+ // Log.d(TAG, "onSurfaceChanged()");
+ mGLThread!!.onWindowResize(width, height)
+ super.onSurfaceChanged(holder, format, width, height)
+ }
+
+ override fun onSurfaceCreated(holder: SurfaceHolder) {
+ Log.d(TAG, "onSurfaceCreated()")
+ mGLThread!!.surfaceCreated(holder)
+ super.onSurfaceCreated(holder)
+ }
+
+ override fun onSurfaceDestroyed(holder: SurfaceHolder) {
+ Log.d(TAG, "onSurfaceDestroyed()")
+ mGLThread!!.surfaceDestroyed()
+ super.onSurfaceDestroyed(holder)
+ }
+
+ fun setRenderer(renderer: GLSurfaceView.Renderer) {
+ checkRenderThreadState()
+
+ var mEGLConfigChooser = this.mEGLConfigChooser;
+ var mEGLContextFactory = this.mEGLContextFactory;
+ var mEGLWindowSurfaceFactory = this.mEGLWindowSurfaceFactory;
+
+ if (mEGLConfigChooser == null) {
+ mEGLConfigChooser = BaseConfigChooser.SimpleEGLConfigChooser(true, mEGLContextClientVersion)
+ }
+ if (mEGLContextFactory == null) {
+ mEGLContextFactory = DefaultContextFactory(mEGLContextClientVersion)
+ }
+ if (mEGLWindowSurfaceFactory == null) {
+ mEGLWindowSurfaceFactory = DefaultWindowSurfaceFactory()
+ }
+ mGLThread = GLThread(renderer, mEGLConfigChooser, mEGLContextFactory, mEGLWindowSurfaceFactory)
+ mGLThread!!.start()
+ }
+
+ fun setEGLContextFactory(factory: GLSurfaceView.EGLContextFactory) {
+ checkRenderThreadState()
+ mEGLContextFactory = factory
+ }
+
+ fun setEGLWindowSurfaceFactory(factory: GLSurfaceView.EGLWindowSurfaceFactory) {
+ checkRenderThreadState()
+ mEGLWindowSurfaceFactory = factory
+ }
+
+ fun setEGLConfigChooser(configChooser: GLSurfaceView.EGLConfigChooser) {
+ checkRenderThreadState()
+ mEGLConfigChooser = configChooser
+ }
+
+ fun setEGLConfigChooser(needDepth: Boolean) {
+ setEGLConfigChooser(BaseConfigChooser.SimpleEGLConfigChooser(needDepth, mEGLContextClientVersion))
+ }
+
+ fun setEGLConfigChooser(redSize: Int, greenSize: Int, blueSize: Int, alphaSize: Int, depthSize: Int,
+ stencilSize: Int) {
+ setEGLConfigChooser(
+ BaseConfigChooser.ComponentSizeChooser(redSize, greenSize, blueSize, alphaSize,
+ depthSize,
+ stencilSize, mEGLContextClientVersion))
+ }
+
+ fun setEGLContextClientVersion(version: Int) {
+ checkRenderThreadState()
+ mEGLContextClientVersion = version
+ }
+
+ open fun requestRender() {
+ mGLThread!!.requestRender()
+ }
+
+ fun onPause() {
+ mGLThread!!.onPause()
+ }
+
+ fun onResume() {
+ mGLThread!!.onResume()
+ }
+
+ fun queueEvent(r: Runnable) {
+ mGLThread!!.queueEvent(r)
+ }
+
+ private fun checkRenderThreadState() {
+ if (mGLThread != null) {
+ throw IllegalStateException("setRenderer has already been called for this instance.")
+ }
+ }
+ }
+}
+
+internal class LogWriter : Writer() {
+ private val mBuilder = StringBuilder()
+
+ override fun close() {
+ flushBuilder()
+ }
+
+ override fun flush() {
+ flushBuilder()
+ }
+
+ override fun write(buf: CharArray, offset: Int, count: Int) {
+ for (i in 0 until count) {
+ val c = buf[offset + i]
+ if (c == '\n') {
+ flushBuilder()
+ } else {
+ mBuilder.append(c)
+ }
+ }
+ }
+
+ private fun flushBuilder() {
+ if (mBuilder.length > 0) {
+ Log.v("GLSurfaceView", mBuilder.toString())
+ mBuilder.delete(0, mBuilder.length)
+ }
+ }
+}
+
+// ----------------------------------------------------------------------
+
+internal class DefaultContextFactory(val eglContextClientVersion : Int) : GLSurfaceView.EGLContextFactory {
+
+ private val EGL_CONTEXT_CLIENT_VERSION = 0x3098
+
+ override fun createContext(egl: EGL10, display: EGLDisplay, config: EGLConfig): EGLContext {
+ val attrib_list = intArrayOf(EGL_CONTEXT_CLIENT_VERSION, eglContextClientVersion, EGL10.EGL_NONE)
+ return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT,
+ if (eglContextClientVersion != 0) attrib_list else null)
+ }
+
+ override fun destroyContext(egl: EGL10, display: EGLDisplay, context: EGLContext) {
+ egl.eglDestroyContext(display, context)
+ }
+}
+
+internal class DefaultWindowSurfaceFactory : GLSurfaceView.EGLWindowSurfaceFactory {
+
+ override fun createWindowSurface(egl: EGL10, display: EGLDisplay, config: EGLConfig, nativeWindow: Any): EGLSurface {
+ // this is a bit of a hack to work around Droid init problems - if you don't have this, it'll get hung up on orientation changes
+ var eglSurface: EGLSurface? = null
+ while (eglSurface == null) {
+ try {
+ eglSurface = egl.eglCreateWindowSurface(display,
+ config, nativeWindow, null)
+ } catch (t: Throwable) {
+ } finally {
+ if (eglSurface == null) {
+ try {
+ Thread.sleep(10)
+ } catch (t: InterruptedException) {
+ }
+
+ }
+ }
+ }
+ return eglSurface
+ }
+
+ override fun destroySurface(egl: EGL10, display: EGLDisplay, surface: EGLSurface) {
+ egl.eglDestroySurface(display, surface)
+ }
+}
+
+internal class EglHelper(private val mEGLConfigChooser: GLSurfaceView.EGLConfigChooser, private val mEGLContextFactory: GLSurfaceView.EGLContextFactory,
+ private val mEGLWindowSurfaceFactory: GLSurfaceView.EGLWindowSurfaceFactory) {
+
+ private var mEgl: EGL10? = null
+ private var mEglDisplay: EGLDisplay? = null
+ private var mEglSurface: EGLSurface? = null
+ private var mEglContext: EGLContext? = null
+ var mEglConfig: EGLConfig? = null
+
+ /**
+ * Initialize EGL for a given configuration spec.
+ *
+ * @param configSpec
+ */
+ fun start() {
+ // Log.d("EglHelper" + instanceId, "start()");
+ if (mEgl == null) {
+ // Log.d("EglHelper" + instanceId, "getting new EGL");
+ /*
+ * Get an EGL instance
+ */
+ mEgl = EGLContext.getEGL() as EGL10
+ } else {
+ // Log.d("EglHelper" + instanceId, "reusing EGL");
+ }
+
+ if (mEglDisplay == null) {
+ // Log.d("EglHelper" + instanceId, "getting new display");
+ /*
+ * Get to the default display.
+ */
+ mEglDisplay = mEgl!!.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
+ } else {
+ // Log.d("EglHelper" + instanceId, "reusing display");
+ }
+
+ if (mEglConfig == null) {
+ // Log.d("EglHelper" + instanceId, "getting new config");
+ /*
+ * We can now initialize EGL for that display
+ */
+ val version = IntArray(2)
+ mEgl!!.eglInitialize(mEglDisplay, version)
+ mEglConfig = mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay)
+ } else {
+ // Log.d("EglHelper" + instanceId, "reusing config");
+ }
+
+ if (mEglContext == null) {
+ // Log.d("EglHelper" + instanceId, "creating new context");
+ /*
+ * Create an OpenGL ES context. This must be done only once, an OpenGL context is a somewhat heavy object.
+ */
+ mEglContext = mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig)
+ if (mEglContext == null || mEglContext === EGL10.EGL_NO_CONTEXT) {
+ throw RuntimeException("createContext failed")
+ }
+ } else {
+ // Log.d("EglHelper" + instanceId, "reusing context");
+ }
+
+ mEglSurface = null
+ }
+
+ /*
+ * React to the creation of a new surface by creating and returning an OpenGL interface that renders to that
+ * surface.
+ */
+ fun createSurface(holder: SurfaceHolder): GL {
+ /*
+ * The window size has changed, so we need to create a new surface.
+ */
+ if (mEglSurface != null && mEglSurface !== EGL10.EGL_NO_SURFACE) {
+
+ /*
+ * Unbind and destroy the old EGL surface, if there is one.
+ */
+ mEgl!!.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)
+ mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay, mEglSurface)
+ }
+
+ /*
+ * Create an EGL surface we can render into.
+ */
+ mEglSurface = mEGLWindowSurfaceFactory.createWindowSurface(mEgl, mEglDisplay, mEglConfig, holder)
+
+ if (mEglSurface == null || mEglSurface === EGL10.EGL_NO_SURFACE) {
+ throw RuntimeException("createWindowSurface failed")
+ }
+
+ /*
+ * Before we can issue GL commands, we need to make sure the context is current and bound to a surface.
+ */
+ if (!mEgl!!.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+ throw RuntimeException("eglMakeCurrent failed.")
+ }
+
+ var gl = mEglContext!!.gl
+
+ /*
+ * if ((mDebugFlags & (DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS))!= 0) { int configFlags = 0; Writer log =
+ * null; if ((mDebugFlags & DEBUG_CHECK_GL_ERROR) != 0) { configFlags |= GLDebugHelper.CONFIG_CHECK_GL_ERROR; }
+ * if ((mDebugFlags & DEBUG_LOG_GL_CALLS) != 0) { log = new LogWriter(); } gl = GLDebugHelper.wrap(gl,
+ * configFlags, log); }
+ */
+
+ return gl
+ }
+
+ /**
+ * Display the current render surface.
+ *
+ * @return false if the context has been lost.
+ */
+ fun swap(): Boolean {
+ mEgl!!.eglSwapBuffers(mEglDisplay, mEglSurface)
+
+ /*
+ * Always check for EGL_CONTEXT_LOST, which means the context and all associated data were lost (For instance
+ * because the device went to sleep). We need to sleep until we get a new surface.
+ */
+ return mEgl!!.eglGetError() != EGL11.EGL_CONTEXT_LOST
+ }
+
+ fun destroySurface() {
+ if (mEglSurface != null && mEglSurface !== EGL10.EGL_NO_SURFACE) {
+ mEgl!!.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT)
+ mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay, mEglSurface)
+ mEglSurface = null
+ }
+ }
+
+ fun finish() {
+ if (mEglContext != null) {
+ mEGLContextFactory.destroyContext(mEgl, mEglDisplay, mEglContext)
+ mEglContext = null
+ }
+ if (mEglDisplay != null) {
+ mEgl!!.eglTerminate(mEglDisplay)
+ mEglDisplay = null
+ }
+ }
+}
+
+internal class GLThread
+(
+ // End of member variables protected by the sGLThreadManager monitor.
+
+ private val mRenderer: GLSurfaceView.Renderer, private val mEGLConfigChooser: GLSurfaceView.EGLConfigChooser, private val mEGLContextFactory: GLSurfaceView.EGLContextFactory,
+ private val mEGLWindowSurfaceFactory: GLSurfaceView.EGLWindowSurfaceFactory) : Thread() {
+
+ private val sGLThreadManager = GLThreadManager()
+ private var mEglOwner: GLThread? = null
+
+ lateinit var mHolder: SurfaceHolder
+ private var mSizeChanged = true
+
+ // Once the thread is started, all accesses to the following member
+ // variables are protected by the sGLThreadManager monitor
+ var mDone: Boolean = false
+ private var mPaused: Boolean = false
+ private var mHasSurface: Boolean = false
+ private var mWaitingForSurface: Boolean = false
+ private var mHaveEgl: Boolean = false
+ private var mWidth: Int = 0
+ private var mHeight: Int = 0
+ private var mRenderMode: Int = 0
+ private var mRequestRender: Boolean = false
+ private var mEventsWaiting: Boolean = false
+ private val mEventQueue = ArrayList()
+ private var mEglHelper: EglHelper? = null
+
+ private val isDone: Boolean
+ get() = synchronized(sGLThreadManager.lockObject) {
+ return mDone
+ }
+
+ var renderMode: Int
+ get() = synchronized(sGLThreadManager.lockObject) {
+ return mRenderMode
+ }
+ set(renderMode) {
+ if (!(GLWallpaperService.RENDERMODE_WHEN_DIRTY <= renderMode && renderMode <= GLWallpaperService.RENDERMODE_CONTINUOUSLY)) {
+ throw IllegalArgumentException("renderMode")
+ }
+ synchronized(sGLThreadManager.lockObject) {
+ mRenderMode = renderMode
+ if (renderMode == GLWallpaperService.RENDERMODE_CONTINUOUSLY) {
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ }
+ }
+
+ private val event: Runnable?
+ get() {
+ synchronized(this) {
+ if (mEventQueue.size > 0) {
+ return mEventQueue.removeAt(0)
+ }
+
+ }
+ return null
+ }
+
+ init {
+ mDone = false
+ mWidth = 0
+ mHeight = 0
+ mRequestRender = true
+ mRenderMode = GLWallpaperService.RENDERMODE_CONTINUOUSLY
+ }
+
+ override fun run() {
+ name = "GLThread $id"
+ if (LOG_THREADS) {
+ Log.i("GLThread", "starting tid=$id")
+ }
+
+ try {
+ guardedRun()
+ } catch (e: InterruptedException) {
+ // fall thru and exit normally
+ } finally {
+ sGLThreadManager.threadExiting(this)
+ }
+ }
+
+ /*
+ * This private method should only be called inside a synchronized(sGLThreadManager.lockObject) block.
+ */
+ private fun stopEglLocked() {
+ if (mHaveEgl) {
+ mHaveEgl = false
+ mEglHelper!!.destroySurface()
+ sGLThreadManager.releaseEglSurface(this)
+ }
+ }
+
+ @Throws(InterruptedException::class)
+ private fun guardedRun() {
+ mEglHelper = EglHelper(mEGLConfigChooser, mEGLContextFactory, mEGLWindowSurfaceFactory)
+ try {
+ var gl: GL10? = null
+ var tellRendererSurfaceCreated = true
+ var tellRendererSurfaceChanged = true
+
+ /*
+ * This is our main activity thread's loop, we go until asked to quit.
+ */
+ while (!isDone) {
+ /*
+ * Update the asynchronous state (window size)
+ */
+ var w = 0
+ var h = 0
+ var changed = false
+ var needStart = false
+ var eventsWaiting = false
+
+ synchronized(sGLThreadManager.lockObject) {
+ while (true) {
+ // Manage acquiring and releasing the SurfaceView
+ // surface and the EGL surface.
+ if (mPaused) {
+ stopEglLocked()
+ }
+ if (!mHasSurface) {
+ if (!mWaitingForSurface) {
+ stopEglLocked()
+ mWaitingForSurface = true
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ } else {
+ if (!mHaveEgl) {
+ if (sGLThreadManager.tryAcquireEglSurface(this)) {
+ mHaveEgl = true
+ mEglHelper!!.start()
+ mRequestRender = true
+ needStart = true
+ }
+ }
+ }
+
+ // Check if we need to wait. If not, update any state
+ // that needs to be updated, copy any state that
+ // needs to be copied, and use "break" to exit the
+ // wait loop.
+
+ if (mDone) {
+ return
+ }
+
+ if (mEventsWaiting) {
+ eventsWaiting = true
+ mEventsWaiting = false
+ break
+ }
+
+ if (!mPaused && mHasSurface && mHaveEgl && mWidth > 0 && mHeight > 0
+ && (mRequestRender || mRenderMode == GLWallpaperService.RENDERMODE_CONTINUOUSLY)) {
+ changed = mSizeChanged
+ w = mWidth
+ h = mHeight
+ mSizeChanged = false
+ mRequestRender = false
+ if (mHasSurface && mWaitingForSurface) {
+ changed = true
+ mWaitingForSurface = false
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ break
+ }
+
+ // By design, this is the only place where we wait().
+
+ if (LOG_THREADS) {
+ Log.i("GLThread", "waiting tid=$id")
+ }
+ sGLThreadManager.lockObject.wait()
+ }
+ } // end of synchronized(sGLThreadManager.lockObject)
+
+ /*
+ * Handle queued events
+ */
+ if (eventsWaiting) {
+ var r: Runnable? = event
+ while (r != null) {
+ r!!.run()
+ if (isDone) {
+ return
+ }
+ }
+ // Go back and see if we need to wait to render.
+ continue
+ }
+
+ if (needStart) {
+ tellRendererSurfaceCreated = true
+ changed = true
+ }
+ if (changed) {
+ gl = mEglHelper!!.createSurface(mHolder) as GL10
+ tellRendererSurfaceChanged = true
+ }
+ if (tellRendererSurfaceCreated) {
+ mRenderer.onSurfaceCreated(gl, mEglHelper!!.mEglConfig)
+ tellRendererSurfaceCreated = false
+ }
+ if (tellRendererSurfaceChanged) {
+ mRenderer.onSurfaceChanged(gl, w, h)
+ tellRendererSurfaceChanged = false
+ }
+ if (w > 0 && h > 0) {
+ /* draw a frame here */
+ mRenderer.onDrawFrame(gl)
+
+ /*
+ * Once we're done with GL, we need to call swapBuffers() to instruct the system to display the
+ * rendered frame
+ */
+ mEglHelper!!.swap()
+ Thread.sleep(10)
+ }
+ }
+ } finally {
+ /*
+ * clean-up everything...
+ */
+ synchronized(sGLThreadManager.lockObject) {
+ stopEglLocked()
+ mEglHelper!!.finish()
+ }
+ }
+ }
+
+ fun requestRender() {
+ synchronized(sGLThreadManager.lockObject) {
+ mRequestRender = true
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ }
+
+ fun surfaceCreated(holder: SurfaceHolder) {
+ mHolder = holder
+ synchronized(sGLThreadManager.lockObject) {
+ if (LOG_THREADS) {
+ Log.i("GLThread", "surfaceCreated tid=$id")
+ }
+ mHasSurface = true
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ }
+
+ fun surfaceDestroyed() {
+ synchronized(sGLThreadManager.lockObject) {
+ if (LOG_THREADS) {
+ Log.i("GLThread", "surfaceDestroyed tid=$id")
+ }
+ mHasSurface = false
+ sGLThreadManager.lockObject.notifyAll()
+ while (!mWaitingForSurface && isAlive && !mDone) {
+ try {
+ sGLThreadManager.lockObject.wait()
+ } catch (e: InterruptedException) {
+ Thread.currentThread().interrupt()
+ }
+
+ }
+ }
+ }
+
+ fun onPause() {
+ synchronized(sGLThreadManager.lockObject) {
+ mPaused = true
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ }
+
+ fun onResume() {
+ synchronized(sGLThreadManager.lockObject) {
+ mPaused = false
+ mRequestRender = true
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ }
+
+ fun onWindowResize(w: Int, h: Int) {
+ synchronized(sGLThreadManager.lockObject) {
+ mWidth = w
+ mHeight = h
+ mSizeChanged = true
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ }
+
+ fun requestExitAndWait() {
+ // don't call this from GLThread thread or it is a guaranteed
+ // deadlock!
+ synchronized(sGLThreadManager.lockObject) {
+ mDone = true
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ try {
+ join()
+ } catch (ex: InterruptedException) {
+ Thread.currentThread().interrupt()
+ }
+
+ }
+
+ /**
+ * Queue an "event" to be run on the GL rendering thread.
+ *
+ * @param r
+ * the runnable to be run on the GL rendering thread.
+ */
+ fun queueEvent(r: Runnable) {
+ synchronized(this) {
+ mEventQueue.add(r)
+ synchronized(sGLThreadManager.lockObject) {
+ mEventsWaiting = true
+ sGLThreadManager.lockObject.notifyAll()
+ }
+ }
+ }
+
+ private inner class GLThreadManager {
+
+ val lockObject = Object()
+
+ @Synchronized
+ fun threadExiting(thread: GLThread) {
+ synchronized(lockObject)
+ {
+ if (LOG_THREADS) {
+ Log.i("GLThread", "exiting tid=" + thread.id)
+ }
+ thread.mDone = true
+ if (mEglOwner === thread) {
+ mEglOwner = null
+ }
+ lockObject.notifyAll()
+ }
+ }
+
+ /*
+ * Tries once to acquire the right to use an EGL surface. Does not block.
+ *
+ * @return true if the right to use an EGL surface was acquired.
+ */
+ @Synchronized
+ fun tryAcquireEglSurface(thread: GLThread): Boolean {
+ if (mEglOwner === thread || mEglOwner == null) {
+ mEglOwner = thread
+ lockObject.notifyAll()
+ return true
+ }
+ return false
+ }
+
+ @Synchronized
+ fun releaseEglSurface(thread: GLThread) {
+ if (mEglOwner === thread) {
+ mEglOwner = null
+ }
+ lockObject.notifyAll()
+ }
+ }
+
+ companion object {
+ private val LOG_THREADS = false
+ val DEBUG_CHECK_GL_ERROR = 1
+ val DEBUG_LOG_GL_CALLS = 2
+ }
+}
+
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/JniWrapper.java b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/JniWrapper.java
index a25670b..4e4933d 100755
--- a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/JniWrapper.java
+++ b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/JniWrapper.java
@@ -1,25 +1,17 @@
package fishrungames.mountainwallpaper;
-public class JniWrapper
+class JniWrapper
{
-
static
{
System.loadLibrary("MountainWallpaper");
}
-
- public static void LoadLibrary()
- {
- //To force loading libraries
- }
-
- public static native void SetTimeOfDayPref(int timeofday);
-
- public static native void SetSnowPref(boolean snow);
-
-
- public static native void Init(int width, int height);
-
- public static native void SetOffset(float offsetX, float offsetY);
+ public static native void SetTimeOfDayPref(int timeofday);
+
+ public static native void SetSnowPref(boolean snow);
+
+ public static native void Init(int width, int height);
+
+ public static native void SetOffset(float offsetX, float offsetY);
}
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/MountainWallpaper.kt b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/MountainWallpaper.kt
new file mode 100755
index 0000000..847500a
--- /dev/null
+++ b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/MountainWallpaper.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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 fishrungames.mountainwallpaper
+
+import android.content.*
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.preference.PreferenceManager
+import android.view.GestureDetector
+import android.view.MotionEvent
+import android.view.SurfaceHolder
+import fishrungames.salmonengineandroid.EngineWrapper
+
+class MountainWallpaper : GLWallpaperService(), SharedPreferences.OnSharedPreferenceChangeListener {
+
+ init
+ {
+ EngineWrapper.LoadSalmonEngineLibrary();
+ //JniWrapper.LoadLibrary();
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+
+ PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this)
+
+ EngineWrapper.SetActivityInstance(this)
+ EngineWrapper.SetupEnviroment()
+
+ var apkFilePath: String? = null
+ var appInfo: ApplicationInfo? = null
+ val packMgmr = this.packageManager
+ try {
+ appInfo = packMgmr.getApplicationInfo("fishrungames.mountainwallpaper", 0)
+ } catch (e: PackageManager.NameNotFoundException) {
+ e.printStackTrace()
+ throw RuntimeException("Unable to locate assets, aborting...")
+ }
+
+ apkFilePath = appInfo!!.sourceDir
+
+ EngineWrapper.SetupApkFilePath(apkFilePath)
+ }
+
+ override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+ return START_STICKY
+ }
+
+ override fun onCreateEngine(): Engine {
+ return MuzeiWallpaperEngine()
+ }
+
+ override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
+
+ if (key.compareTo("Timeofday", ignoreCase = true) == 0) {
+ val time = Integer.parseInt(sharedPreferences.getString("Timeofday", "0")!!)
+ JniWrapper.SetTimeOfDayPref(time)
+ }
+
+ if (key.compareTo("Snow", ignoreCase = true) == 0) {
+
+ JniWrapper.SetSnowPref(sharedPreferences.getBoolean("Snow", false))
+
+ }
+ }
+
+ inner class MuzeiWallpaperEngine : GLWallpaperService.GLEngine()
+ {
+
+ private lateinit var renderer: WallpaperRenderer
+
+ private val gestureListener = object : GestureDetector.SimpleOnGestureListener() {
+ override fun onDown(e: MotionEvent): Boolean {
+ return true
+ }
+ }
+ private val gestureDetector: GestureDetector = GestureDetector(this@MountainWallpaper,
+ gestureListener)
+
+ override fun onCreate(surfaceHolder: SurfaceHolder) {
+ super.onCreate(surfaceHolder)
+
+ setEGLContextClientVersion(2)
+ setRenderer(WallpaperRenderer())
+ renderMode = RENDERMODE_CONTINUOUSLY
+ requestRender()
+
+ // Use the MuzeiWallpaperService's lifecycle to wait for the user to unlock
+
+ setTouchEventsEnabled(true)
+ setOffsetNotificationsEnabled(true)
+ }
+
+ override fun onOffsetsChanged(
+ xOffset: Float,
+ yOffset: Float,
+ xOffsetStep: Float,
+ yOffsetStep: Float,
+ xPixelOffset: Int,
+ yPixelOffset: Int
+ ) {
+ super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset,
+ yPixelOffset)
+
+ JniWrapper.SetOffset(xPixelOffset * xOffsetStep, yPixelOffset * yOffsetStep)
+ }
+
+ override fun onTouchEvent(event: MotionEvent) {
+ super.onTouchEvent(event)
+ gestureDetector.onTouchEvent(event)
+ }
+ }
+}
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/MountainWallpaperService.java b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/MountainWallpaperService.java
deleted file mode 100755
index ad9577a..0000000
--- a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/MountainWallpaperService.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package fishrungames.mountainwallpaper;
-
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-
-import android.net.ConnectivityManager;
-
-import android.os.Handler;
-import android.preference.PreferenceManager;
-
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-
-//import com.seb.SLWP.SLWP.GlEngine.DownloadTask;
-
-import fishrungames.salmonengineandroid.EngineWrapper;
-
-public class MountainWallpaperService extends GLWallpaperService implements
- OnSharedPreferenceChangeListener {
- /*
- * (non-Javadoc)
- *
- * @see android.app.Service#onLowMemory()
- */
- static
- {
- EngineWrapper.LoadSalmonEngineLibrary();
- JniWrapper.LoadLibrary();
- }
-
-
- public static final long SLEEPTIME = 1000 * 60 * 30; // 30 minutes
- private GlEngine mGle;
-
- public static Context mContext;
- public static boolean ShowClouds;
- public static boolean TouchRot;
-
- public static int Bg;
- public static boolean Usebg;
- public static int Tex;
-
- static long Synctime;
-
- public boolean Slidedir;
- public boolean Slideplanet;
- public boolean Syncrot;
- public static boolean Randomtex = true;
- public static boolean visible = false;
-
- public static boolean useCropper = true;
- public static int Cropaspect;
- public static boolean loading = false;
-
- public static final Handler mHandler = new Handler();
- public static final int RNDMAP = -1;
- public static boolean destroyed;
- public static String bgfile;
- public ConnectivityManager cm;
- public boolean needresume;
- public boolean fstart;
- public static String[] randlist;
- public int curtexidx = -99;
-
- static final String ACTION_FOREGROUND = "fishrungames.mountainwallpaper.FOREGROUND";
- static final String ACTION_BACKGROUND = "fishrungames.mountainwallpaper.BACKGROUND";
-
-
-
- @Override
- public void onCreate() {
- // TODO Auto-generated method stub
- super.onCreate();
-
-
- PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
-
- EngineWrapper.SetActivityInstance(this);
- EngineWrapper.SetupEnviroment();
-
- String apkFilePath = null;
- ApplicationInfo appInfo = null;
- PackageManager packMgmr = this.getPackageManager();
- try {
- appInfo = packMgmr.getApplicationInfo("fishrungames.mountainwallpaper", 0);
- } catch (NameNotFoundException e) {
-
-
-
- e.printStackTrace();
- throw new RuntimeException("Unable to locate assets, aborting...");
- }
- apkFilePath = appInfo.sourceDir;
-
- EngineWrapper.SetupApkFilePath(apkFilePath);
-
- Init();
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- // handleCommand(intent);
- // We want this service to continue running until it is explicitly
- // stopped, so return sticky.
- return START_STICKY;
- }
-
- private void Init() {
- try {
- mContext = this;
- cm = (ConnectivityManager) mContext
- .getSystemService(Context.CONNECTIVITY_SERVICE);
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
- String key) {
-
- if (key.compareToIgnoreCase("Timeofday") == 0)
- {
- int time = Integer.parseInt(sharedPreferences.getString("Timeofday", "0"));
- JniWrapper.SetTimeOfDayPref(time);
- }
-
- if (key.compareToIgnoreCase("Snow") == 0) {
-
- JniWrapper.SetSnowPref(sharedPreferences.getBoolean("Snow", false));
-
- }
- }
-
- @Override
- public Engine onCreateEngine() {
- if (mGle != null) {
- mGle = null;
- }
- try {
-
- mGle = new GlEngine();
-
- } catch (Exception e) {
- return null;
- }
-
- return mGle;
- }
-
- class GlEngine extends GLEngine {
-
- public Handler mHandler = new Handler();
-
- long NOW;
-
- @Override
- public void onCreate(SurfaceHolder surfaceHolder) {
- super.onCreate(surfaceHolder);
- try {
- this.setTouchEventsEnabled(true);
- fstart = true;
- setRenderer();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void onTouchEvent(MotionEvent e) {
-
- return;
- }
-
- @Override
- public void onOffsetsChanged(float xOffset, float yOffset,
- float xOffsetStep, float yOffsetStep, int xPixelOffset,
- int yPixelOffset) {
-
- super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,
- xPixelOffset, yPixelOffset);
-
- JniWrapper.SetOffset(xPixelOffset*xOffsetStep, yPixelOffset*yOffsetStep);
-
- }
-
- @Override
- public void onVisibilityChanged(boolean visible) {
- // TODO Auto-generated method stub
- super.onVisibilityChanged(visible);
- MountainWallpaperService.visible = visible;
- if (visible) {
-
- } else {
-
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- }
-
- @Override
- public void onResume() {
-
- super.onResume();
- }
-
- @Override
- public void onSurfaceChanged(SurfaceHolder holder, int format,
- int width, int height) {
- // TODO Auto-generated method stub
- super.onSurfaceChanged(holder, format, width, height);
- fstart = true;
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/Prefs.java b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/Prefs.java
deleted file mode 100755
index 79c7c3e..0000000
--- a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/Prefs.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package fishrungames.mountainwallpaper;
-
-import fishrungames.mountainwallpaper.R;
-import fishrungames.mountainwallpaper.JniWrapper;
-
-
-import android.content.Intent;
-
-import android.net.Uri;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-
-import android.preference.Preference.OnPreferenceChangeListener;
-
-
-public class Prefs extends PreferenceActivity implements
- OnPreferenceChangeListener {
-
-
- private CheckBoxPreference snowPref;
- private ListPreference timeOfDayPref;
-
-
- public static Uri currImageURI;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.prefliste);
- addPreferencesFromResource(R.xml.preferences);
-
-
- snowPref = (CheckBoxPreference)this.getPreferenceManager().findPreference("Snow");
- timeOfDayPref = (ListPreference) findPreference("Timeofday");
-
- if (timeOfDayPref.getKey().compareToIgnoreCase("Timeofday") == 0)
- {
- JniWrapper.SetTimeOfDayPref(Integer.parseInt((String) timeOfDayPref.getValue()));
-
- }
-
- if (snowPref.getKey().compareToIgnoreCase("Snow") == 0) {
- if (!snowPref.isChecked())
- {
- JniWrapper.SetSnowPref(false);
- }
- else
- {
- JniWrapper.SetSnowPref(true);
- }
- }
-
- }
-
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
-
- return true;
-
- }
-
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
-
- }
-
-}
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperPreferenceFragment.kt b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperPreferenceFragment.kt
new file mode 100755
index 0000000..e2d1914
--- /dev/null
+++ b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperPreferenceFragment.kt
@@ -0,0 +1,11 @@
+package fishrungames.mountainwallpaper
+
+import android.support.v7.preference.PreferenceFragmentCompat
+import android.os.Bundle
+
+class WallpaperPreferenceFragment : PreferenceFragmentCompat()
+{
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ setPreferencesFromResource(R.xml.preferences, rootKey)
+ }
+}
\ No newline at end of file
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperPreferences.kt b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperPreferences.kt
new file mode 100755
index 0000000..ef21221
--- /dev/null
+++ b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperPreferences.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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 fishrungames.mountainwallpaper
+
+import android.os.Bundle
+import android.support.v4.app.FragmentActivity
+
+class WallpaperPreferences : FragmentActivity()
+{
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.pref_activity)
+ }
+}
diff --git a/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperRenderer.kt b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperRenderer.kt
new file mode 100755
index 0000000..f166731
--- /dev/null
+++ b/proj.android-studio/app/src/main/java/fishrungames/mountainwallpaper/WallpaperRenderer.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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 fishrungames.mountainwallpaper
+
+import android.opengl.GLES20
+import android.opengl.GLSurfaceView
+import android.util.Log
+import fishrungames.salmonengineandroid.EngineWrapper
+import java.util.*
+import javax.microedition.khronos.egl.EGLConfig
+import javax.microedition.khronos.opengles.GL10
+
+class WallpaperRenderer() : GLSurfaceView.Renderer {
+
+ private var surfaceCreated: Boolean = false
+ private var lastTimeStamp: Long = 0
+
+ override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
+ surfaceCreated = true
+ }
+
+ override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) {
+ JniWrapper.Init(width, height)
+ }
+
+ override fun onDrawFrame(unused: GL10) {
+ val currentTimeStamp = Calendar.getInstance().timeInMillis
+ if (lastTimeStamp == 0L)
+ {
+ lastTimeStamp = currentTimeStamp
+ }
+
+ EngineWrapper.Update(currentTimeStamp - lastTimeStamp)
+
+ lastTimeStamp = currentTimeStamp
+ }
+}
diff --git a/proj.android-studio/app/src/main/res/drawable-nodpi/icon.png b/proj.android-studio/app/src/main/res/drawable-nodpi/icon.png
new file mode 100755
index 0000000..71b697f
Binary files /dev/null and b/proj.android-studio/app/src/main/res/drawable-nodpi/icon.png differ
diff --git a/proj.android-studio/app/src/main/res/drawable/icon.png b/proj.android-studio/app/src/main/res/drawable/icon.png
new file mode 100755
index 0000000..6d35977
Binary files /dev/null and b/proj.android-studio/app/src/main/res/drawable/icon.png differ
diff --git a/proj.android-studio/app/src/main/res/drawable/notificon.png b/proj.android-studio/app/src/main/res/drawable/notificon.png
deleted file mode 100755
index 656209b..0000000
Binary files a/proj.android-studio/app/src/main/res/drawable/notificon.png and /dev/null differ
diff --git a/proj.android-studio/app/src/main/res/drawable/thumb.jpg b/proj.android-studio/app/src/main/res/drawable/thumb.jpg
deleted file mode 100755
index cfe281b..0000000
Binary files a/proj.android-studio/app/src/main/res/drawable/thumb.jpg and /dev/null differ
diff --git a/proj.android-studio/app/src/main/res/font/alegreya_black_italic.ttf b/proj.android-studio/app/src/main/res/font/alegreya_black_italic.ttf
new file mode 100755
index 0000000..7cd03db
Binary files /dev/null and b/proj.android-studio/app/src/main/res/font/alegreya_black_italic.ttf differ
diff --git a/proj.android-studio/app/src/main/res/font/alegreya_italic.ttf b/proj.android-studio/app/src/main/res/font/alegreya_italic.ttf
new file mode 100755
index 0000000..125edeb
Binary files /dev/null and b/proj.android-studio/app/src/main/res/font/alegreya_italic.ttf differ
diff --git a/proj.android-studio/app/src/main/res/font/alegreya_sans_black.ttf b/proj.android-studio/app/src/main/res/font/alegreya_sans_black.ttf
new file mode 100755
index 0000000..1b29b38
Binary files /dev/null and b/proj.android-studio/app/src/main/res/font/alegreya_sans_black.ttf differ
diff --git a/proj.android-studio/app/src/main/res/font/alegreya_sans_medium.ttf b/proj.android-studio/app/src/main/res/font/alegreya_sans_medium.ttf
new file mode 100755
index 0000000..dfed9d2
Binary files /dev/null and b/proj.android-studio/app/src/main/res/font/alegreya_sans_medium.ttf differ
diff --git a/proj.android-studio/app/src/main/res/layout/main.xml b/proj.android-studio/app/src/main/res/layout/main.xml
deleted file mode 100755
index 4361cfe..0000000
--- a/proj.android-studio/app/src/main/res/layout/main.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
diff --git a/proj.android-studio/app/src/main/res/layout/pref_activity.xml b/proj.android-studio/app/src/main/res/layout/pref_activity.xml
new file mode 100755
index 0000000..d050e6e
--- /dev/null
+++ b/proj.android-studio/app/src/main/res/layout/pref_activity.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/proj.android-studio/app/src/main/res/layout/prefliste.xml b/proj.android-studio/app/src/main/res/layout/prefliste.xml
deleted file mode 100755
index 3c2ad7c..0000000
--- a/proj.android-studio/app/src/main/res/layout/prefliste.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/proj.android-studio/app/src/main/res/xml/preferences.xml b/proj.android-studio/app/src/main/res/xml/preferences.xml
index 4917e51..5122a24 100755
--- a/proj.android-studio/app/src/main/res/xml/preferences.xml
+++ b/proj.android-studio/app/src/main/res/xml/preferences.xml
@@ -5,9 +5,11 @@
-
+
+ android:summaryOff="@string/p_snow_off" android:defaultValue="false"
+ />
diff --git a/proj.android-studio/app/src/main/res/xml/wallpaper.xml b/proj.android-studio/app/src/main/res/xml/wallpaper.xml
index 0a9c5da..e7a7b87 100755
--- a/proj.android-studio/app/src/main/res/xml/wallpaper.xml
+++ b/proj.android-studio/app/src/main/res/xml/wallpaper.xml
@@ -1,6 +1,8 @@
-
\ No newline at end of file
+ android:settingsActivity="fishrungames.mountainwallpaper.WallpaperPreferences"
+ />
\ No newline at end of file
diff --git a/proj.android-studio/app/src/test/java/fishrungames/salmonandroidtemplate/ExampleUnitTest.java b/proj.android-studio/app/src/test/java/fishrungames/salmonandroidtemplate/ExampleUnitTest.java
deleted file mode 100755
index 49c0291..0000000
--- a/proj.android-studio/app/src/test/java/fishrungames/salmonandroidtemplate/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package fishrungames.salmonandroidtemplate;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/proj.android-studio/build.gradle b/proj.android-studio/build.gradle
index 0a832c6..0e5c0fe 100755
--- a/proj.android-studio/build.gradle
+++ b/proj.android-studio/build.gradle
@@ -1,14 +1,20 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.2.70'
+ ext {
+ compileSdkVersion = 28
+ targetSdkVersion = 28
+
+ kotlin_version = "1.3.10"
+ supportLibraryVersion = "28.0.0"
+ }
repositories {
jcenter()
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.2.0-rc03'
+ classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong