[Scummvm-git-logs] scummvm master -> 92dd9c091164ac565ef9c8fa9009f215e7dfcbab

lephilousophe noreply at scummvm.org
Sun Jan 2 16:45:38 UTC 2022


This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
7b36b56925 ANDROID: Rework Android 3D texture interfaces
b60c99ce98 OPENGL: Allow backends to draw textures clipped
325c47f954 ANDROID: Use Android runtime to open touch controls image
b6c0a1c6c8 ANDROID: Refactor touch controls to be graphics backend agnostic
dcd02117cf OPENGL: Make back buffer accessible from derivated classes
639d633f12 ANDROID: Add touch controls to 2D backend
523b226243 ANDROID: Allow user to enable touch controls
92dd9c0911 ANDROID: Keep last touch mode when displaying overlay


Commit: 7b36b56925335320d3a2a29c4ea3bef116412d2c
    https://github.com/scummvm/scummvm/commit/7b36b56925335320d3a2a29c4ea3bef116412d2c
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-01-02T17:45:32+01:00

Commit Message:
ANDROID: Rework Android 3D texture interfaces

Changed paths:
    backends/graphics3d/android/texture.h


diff --git a/backends/graphics3d/android/texture.h b/backends/graphics3d/android/texture.h
index 5fd1aaa2fcf..e2b4a57cb5c 100644
--- a/backends/graphics3d/android/texture.h
+++ b/backends/graphics3d/android/texture.h
@@ -49,7 +49,6 @@ public:
 
 	void release();
 	void reinit();
-	void initSize();
 
 	void setLinearFilter(bool value);
 
@@ -64,8 +63,6 @@ public:
 	}
 	void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
 
-	virtual void *prepareTextureBuffer(const Common::Rect &rect) = 0;
-
 	inline void setDrawRect(const Common::Rect &rect) {
 		_draw_rect = rect;
 	}
@@ -151,6 +148,10 @@ public:
 	}
 
 protected:
+	void initSize();
+
+	virtual void *prepareTextureBuffer(const Common::Rect &rect) = 0;
+
 	inline void setDirty() {
 		_all_dirty = true;
 	}
@@ -206,21 +207,21 @@ protected:
 public:
 	virtual ~GLESTexture();
 
-	virtual void allocBuffer(GLuint w, GLuint h);
-
-	virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
-	                          const void *buf, int pitch_buf);
-	virtual void fillBuffer(uint32 color);
+	void allocBuffer(GLuint w, GLuint h) override;
 
-	virtual void *prepareTextureBuffer(const Common::Rect &rect) override;
+	void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
+	                          const void *buf, int pitch_buf) override;
+	void fillBuffer(uint32 color) override;
 
-	virtual void setPalette(const byte *colors, uint start, uint num) override {}
-	virtual void setKeycolor(byte color) override {};
-	virtual void grabPalette(byte *colors, uint start, uint num) const override {}
+	void setPalette(const byte *colors, uint start, uint num) override {}
+	void setKeycolor(byte color) override {};
+	void grabPalette(byte *colors, uint start, uint num) const override {}
 
 	void readPixels();
 
 protected:
+	void *prepareTextureBuffer(const Common::Rect &rect) override;
+
 	byte *_pixels;
 	byte *_buf;
 };
@@ -294,12 +295,12 @@ protected:
 public:
 	virtual ~GLESFakePaletteTexture();
 
-	virtual void allocBuffer(GLuint w, GLuint h) override;
-	virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
+	void allocBuffer(GLuint w, GLuint h) override;
+	void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
 	                          const void *buf, int pitch_buf) override;
-	virtual void fillBuffer(uint32 color) override;
+	void fillBuffer(uint32 color) override;
 
-	virtual const Graphics::PixelFormat &getPixelFormat() const override {
+	const Graphics::PixelFormat &getPixelFormat() const override {
 		return _fake_format;
 	}
 
@@ -315,13 +316,14 @@ protected:
 public:
 	virtual ~GLESFakePalette16Texture();
 
-	virtual void allocBuffer(GLuint w, GLuint h) override;
-	virtual void *prepareTextureBuffer(const Common::Rect &rect) override;
+	void allocBuffer(GLuint w, GLuint h) override;
 
-	virtual void setPalette(const byte *colors, uint start, uint num) override;
-	virtual void grabPalette(byte *colors, uint start, uint num) const override;
+	void setPalette(const byte *colors, uint start, uint num) override;
+	void grabPalette(byte *colors, uint start, uint num) const override;
 
 protected:
+	void *prepareTextureBuffer(const Common::Rect &rect) override;
+
 	uint16 *_palette;
 	uint16 *_buf;
 };
@@ -331,7 +333,7 @@ public:
 	GLESFakePalette565Texture();
 	virtual ~GLESFakePalette565Texture() {}
 
-	virtual void setKeycolor(byte color) override {};
+	void setKeycolor(byte color) override {};
 };
 
 class GLESFakePalette5551Texture : public GLESFakePalette16Texture {
@@ -339,7 +341,7 @@ public:
 	GLESFakePalette5551Texture();
 	virtual ~GLESFakePalette5551Texture() {}
 
-	virtual void setKeycolor(byte color) override;
+	void setKeycolor(byte color) override;
 
 protected:
 	byte _keycolor;
@@ -350,14 +352,15 @@ public:
 	GLESFakePalette888Texture();
 	virtual ~GLESFakePalette888Texture();
 
-	virtual void allocBuffer(GLuint w, GLuint h) override;
-	virtual void *prepareTextureBuffer(const Common::Rect &rect) override;
+	void allocBuffer(GLuint w, GLuint h) override;
 
-	virtual void setPalette(const byte *colors, uint start, uint num) override;
-	virtual void setKeycolor(byte color) override {};
-	virtual void grabPalette(byte *colors, uint start, uint num) const override;
+	void setPalette(const byte *colors, uint start, uint num) override;
+	void setKeycolor(byte color) override {};
+	void grabPalette(byte *colors, uint start, uint num) const override;
 
 protected:
+	void *prepareTextureBuffer(const Common::Rect &rect) override;
+
 	byte *_palette;
 	byte *_buf;
 };
@@ -367,14 +370,15 @@ public:
 	GLESFakePalette8888Texture();
 	virtual ~GLESFakePalette8888Texture();
 
-	virtual void allocBuffer(GLuint w, GLuint h) override;
-	virtual void *prepareTextureBuffer(const Common::Rect &rect) override;
+	void allocBuffer(GLuint w, GLuint h) override;
 
-	virtual void setPalette(const byte *colors, uint start, uint num) override;
-	virtual void setKeycolor(byte color) override;
-	virtual void grabPalette(byte *colors, uint start, uint num) const override;
+	void setPalette(const byte *colors, uint start, uint num) override;
+	void setKeycolor(byte color) override;
+	void grabPalette(byte *colors, uint start, uint num) const override;
 
 protected:
+	void *prepareTextureBuffer(const Common::Rect &rect) override;
+
 	uint32 *_palette;
 	uint32 *_buf;
 	byte _keycolor;


Commit: b60c99ce98c873ea3e7b2d8cc05a901bf061a6d3
    https://github.com/scummvm/scummvm/commit/b60c99ce98c873ea3e7b2d8cc05a901bf061a6d3
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-01-02T17:45:32+01:00

Commit Message:
OPENGL: Allow backends to draw textures clipped

Changed paths:
    backends/graphics/opengl/pipelines/clut8.cpp
    backends/graphics/opengl/pipelines/clut8.h
    backends/graphics/opengl/pipelines/fixed.cpp
    backends/graphics/opengl/pipelines/fixed.h
    backends/graphics/opengl/pipelines/pipeline.h
    backends/graphics/opengl/pipelines/shader.cpp
    backends/graphics/opengl/pipelines/shader.h


diff --git a/backends/graphics/opengl/pipelines/clut8.cpp b/backends/graphics/opengl/pipelines/clut8.cpp
index 964d836a6c3..5f2db578b3f 100644
--- a/backends/graphics/opengl/pipelines/clut8.cpp
+++ b/backends/graphics/opengl/pipelines/clut8.cpp
@@ -30,7 +30,7 @@ CLUT8LookUpPipeline::CLUT8LookUpPipeline()
 	: ShaderPipeline(ShaderMan.query(ShaderManager::kCLUT8LookUp)), _paletteTexture(nullptr) {
 }
 
-void CLUT8LookUpPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+void CLUT8LookUpPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
 	// Set the palette texture.
 	GL_CALL(glActiveTexture(GL_TEXTURE1));
 	if (_paletteTexture) {
@@ -38,7 +38,7 @@ void CLUT8LookUpPipeline::drawTexture(const GLTexture &texture, const GLfloat *c
 	}
 
 	GL_CALL(glActiveTexture(GL_TEXTURE0));
-	ShaderPipeline::drawTexture(texture, coordinates);
+	ShaderPipeline::drawTexture(texture, coordinates, texcoords);
 }
 #endif // !USE_FORCED_GLES
 
diff --git a/backends/graphics/opengl/pipelines/clut8.h b/backends/graphics/opengl/pipelines/clut8.h
index 3f6bdaa0f09..532db3e91ea 100644
--- a/backends/graphics/opengl/pipelines/clut8.h
+++ b/backends/graphics/opengl/pipelines/clut8.h
@@ -33,7 +33,7 @@ public:
 
 	void setPaletteTexture(const GLTexture *paletteTexture) { _paletteTexture = paletteTexture; }
 
-	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords);
 
 private:
 	const GLTexture *_paletteTexture;
diff --git a/backends/graphics/opengl/pipelines/fixed.cpp b/backends/graphics/opengl/pipelines/fixed.cpp
index 8eb1450f99f..bac928374d2 100644
--- a/backends/graphics/opengl/pipelines/fixed.cpp
+++ b/backends/graphics/opengl/pipelines/fixed.cpp
@@ -45,10 +45,10 @@ void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 	GL_CALL(glColor4f(r, g, b, a));
 }
 
-void FixedPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+void FixedPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
 	texture.bind();
 
-	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texture.getTexCoords()));
+	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
 	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, coordinates));
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 }
diff --git a/backends/graphics/opengl/pipelines/fixed.h b/backends/graphics/opengl/pipelines/fixed.h
index 9e2ff9840b0..d1adc02ae36 100644
--- a/backends/graphics/opengl/pipelines/fixed.h
+++ b/backends/graphics/opengl/pipelines/fixed.h
@@ -31,7 +31,7 @@ class FixedPipeline : public Pipeline {
 public:
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
-	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords);
 
 	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
 
diff --git a/backends/graphics/opengl/pipelines/pipeline.h b/backends/graphics/opengl/pipelines/pipeline.h
index fe07bd94344..53782476f59 100644
--- a/backends/graphics/opengl/pipelines/pipeline.h
+++ b/backends/graphics/opengl/pipelines/pipeline.h
@@ -79,7 +79,11 @@ public:
 	 * @param texture     Texture to use for drawing.
 	 * @param coordinates x1, y1, x2, y2 coordinates where to draw the texture.
 	 */
-	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates) = 0;
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) = 0;
+
+	void drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+		drawTexture(texture, coordinates, texture.getTexCoords());
+	}
 
 	void drawTexture(const GLTexture &texture, GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 		const GLfloat coordinates[4*2] = {
@@ -88,7 +92,33 @@ public:
 			x,     y + h,
 			x + w, y + h
 		};
-		drawTexture(texture, coordinates);
+		drawTexture(texture, coordinates, texture.getTexCoords());
+	}
+
+	void drawTexture(const GLTexture &texture, GLfloat x, GLfloat y, GLfloat w, GLfloat h, const Common::Rect &clip) {
+		const GLfloat coordinates[4*2] = {
+			x,     y,
+			x + w, y,
+			x,     y + h,
+			x + w, y + h
+		};
+
+		const uint tw = texture.getWidth(),
+			  th = texture.getHeight();
+
+		if (tw == 0 || th == 0) {
+			// Nothing to display
+			return;
+		}
+
+		const GLfloat texcoords[4*2] = {
+			(float)clip.left  / tw, (float)clip.top    / th,
+			(float)clip.right / tw, (float)clip.top    / th,
+			(float)clip.left  / tw, (float)clip.bottom / th,
+			(float)clip.right / tw, (float)clip.bottom / th
+		};
+
+		drawTexture(texture, coordinates, texcoords);
 	}
 
 	/**
diff --git a/backends/graphics/opengl/pipelines/shader.cpp b/backends/graphics/opengl/pipelines/shader.cpp
index e672749231b..d9e6c64ceb8 100644
--- a/backends/graphics/opengl/pipelines/shader.cpp
+++ b/backends/graphics/opengl/pipelines/shader.cpp
@@ -77,10 +77,10 @@ void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 	}
 }
 
-void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords) {
 	texture.bind();
 
-	GL_CALL(glVertexAttribPointer(_texCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texture.getTexCoords()));
+	GL_CALL(glVertexAttribPointer(_texCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
 	GL_CALL(glVertexAttribPointer(_vertexAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, coordinates));
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 }
diff --git a/backends/graphics/opengl/pipelines/shader.h b/backends/graphics/opengl/pipelines/shader.h
index fefd970aabc..cbba6272f4c 100644
--- a/backends/graphics/opengl/pipelines/shader.h
+++ b/backends/graphics/opengl/pipelines/shader.h
@@ -35,7 +35,7 @@ public:
 
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
-	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates, const GLfloat *texcoords);
 
 	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
 


Commit: 325c47f9548f4489f50d60f7020e13a94ea27ee4
    https://github.com/scummvm/scummvm/commit/325c47f9548f4489f50d60f7020e13a94ea27ee4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-01-02T17:45:32+01:00

Commit Message:
ANDROID: Use Android runtime to open touch controls image

This allows to use PNG file for sure and don't make us use TGA decoder

Changed paths:
  A dists/android/res/drawable/touch_arrows.png
  R dists/android/assets/arrows.tga
    backends/platform/android/android.mk
    backends/platform/android/jni-android.cpp
    backends/platform/android/jni-android.h
    backends/platform/android/org/scummvm/scummvm/ScummVM.java
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
    backends/platform/android/touchcontrols.cpp
    configure


diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk
index 984ef506ee2..490f43e7fc3 100644
--- a/backends/platform/android/android.mk
+++ b/backends/platform/android/android.mk
@@ -1,8 +1,6 @@
 # Android specific build targets
 PATH_DIST = $(srcdir)/dists/android
 
-DIST_ANDROID_CONTROLS = $(PATH_DIST)/assets/arrows.tga
-
 GRADLE_FILES = $(shell find $(PATH_DIST)/gradle -type f) $(PATH_DIST)/gradlew $(PATH_DIST)/build.gradle
 
 PATH_BUILD = ./android_project
@@ -27,9 +25,9 @@ $(PATH_BUILD_GRADLE): $(GRADLE_FILES) | $(PATH_BUILD)
 	$(ECHO) "android.enableJetifier=true\n" >> $(PATH_BUILD)/gradle.properties
 	$(ECHO) "sdk.dir=$(realpath $(ANDROID_SDK_ROOT))\n" > $(PATH_BUILD)/local.properties
 
-$(PATH_BUILD_ASSETS): $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(DIST_FILES_DOCS) $(DIST_ANDROID_CONTROLS) | $(PATH_BUILD)
+$(PATH_BUILD_ASSETS): $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(DIST_FILES_DOCS) | $(PATH_BUILD)
 	$(INSTALL) -d $(PATH_BUILD_ASSETS)
-	$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(DIST_FILES_DOCS) $(DIST_ANDROID_CONTROLS) $(PATH_BUILD_ASSETS)/
+	$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_FILES_NETWORKING) $(DIST_FILES_VKEYBD) $(DIST_FILES_DOCS) $(PATH_BUILD_ASSETS)/
 ifneq ($(DIST_FILES_SHADERS),)
 	$(INSTALL) -d $(PATH_BUILD_ASSETS)/shaders
 	$(INSTALL) -c -m 644 $(DIST_FILES_SHADERS) $(PATH_BUILD_ASSETS)/shaders
diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index 28aa08af83e..98b00cf1d65 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -39,12 +39,15 @@
 // for the Android port
 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
 
+#include <android/bitmap.h>
+
 #include "base/main.h"
 #include "base/version.h"
 #include "common/config-manager.h"
 #include "common/error.h"
 #include "common/textconsole.h"
 #include "engines/engine.h"
+#include "graphics/surface.h"
 
 #include "backends/platform/android/android.h"
 #include "backends/platform/android/asset-archive.h"
@@ -84,6 +87,7 @@ jmethodID JNI::_MID_isConnectionLimited = 0;
 jmethodID JNI::_MID_setWindowCaption = 0;
 jmethodID JNI::_MID_showVirtualKeyboard = 0;
 jmethodID JNI::_MID_showKeyboardControl = 0;
+jmethodID JNI::_MID_getBitmapResource = 0;
 jmethodID JNI::_MID_setTouch3DMode = 0;
 jmethodID JNI::_MID_showSAFRevokePermsControl = 0;
 jmethodID JNI::_MID_getSysArchives = 0;
@@ -389,6 +393,71 @@ void JNI::showKeyboardControl(bool enable) {
 	}
 }
 
+Graphics::Surface *JNI::getBitmapResource(BitmapResources resource) {
+	JNIEnv *env = JNI::getEnv();
+
+	jobject bitmap = env->CallObjectMethod(_jobj, _MID_getBitmapResource, (int) resource);
+
+	if (env->ExceptionCheck()) {
+		LOGE("Can't get bitmap resource");
+
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+
+		return nullptr;
+	}
+
+	if (bitmap == nullptr) {
+		LOGE("Bitmap resource was not found");
+		return nullptr;
+	}
+
+	AndroidBitmapInfo bitmap_info;
+	if (AndroidBitmap_getInfo(env, bitmap, &bitmap_info) != ANDROID_BITMAP_RESULT_SUCCESS) {
+		LOGE("Error reading bitmap info");
+		env->DeleteLocalRef(bitmap);
+		return nullptr;
+	}
+
+	Graphics::PixelFormat fmt;
+	switch(bitmap_info.format) {
+		case ANDROID_BITMAP_FORMAT_RGBA_8888:
+#ifdef SCUMM_BIG_ENDIAN
+			fmt = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+			fmt = Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+			break;
+		case ANDROID_BITMAP_FORMAT_RGBA_4444:
+			fmt = Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0);
+			break;
+		case ANDROID_BITMAP_FORMAT_RGB_565:
+			fmt = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
+			break;
+		default:
+			LOGE("Bitmap has unsupported format");
+			env->DeleteLocalRef(bitmap);
+			return nullptr;
+	}
+
+	void *src_pixels = nullptr;
+	if (AndroidBitmap_lockPixels(env, bitmap, &src_pixels) != ANDROID_BITMAP_RESULT_SUCCESS) {
+		LOGE("Error locking bitmap pixels");
+		env->DeleteLocalRef(bitmap);
+		return nullptr;
+	}
+
+	Graphics::Surface *ret = new Graphics::Surface();
+	ret->create(bitmap_info.width, bitmap_info.height, fmt);
+	ret->copyRectToSurface(src_pixels, bitmap_info.stride,
+			0, 0, bitmap_info.width, bitmap_info.height);
+
+	AndroidBitmap_unlockPixels(env, bitmap);
+	env->DeleteLocalRef(bitmap);
+
+	return ret;
+}
+
 void JNI::setTouch3DMode(bool touch3DMode) {
 	JNIEnv *env = JNI::getEnv();
 
@@ -587,6 +656,7 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
 	FIND_METHOD(, isConnectionLimited, "()Z");
 	FIND_METHOD(, showVirtualKeyboard, "(Z)V");
 	FIND_METHOD(, showKeyboardControl, "(Z)V");
+	FIND_METHOD(, getBitmapResource, "(I)Landroid/graphics/Bitmap;");
 	FIND_METHOD(, setTouch3DMode, "(Z)V");
 	FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
 	FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index 4d8cfccbcd4..ad4c63ac7b9 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -33,6 +33,10 @@
 #include "common/ustr.h"
 #include "engines/engine.h"
 
+namespace Graphics {
+	struct Surface;
+}
+
 class OSystem_Android;
 
 class JNI {
@@ -41,6 +45,10 @@ private:
 	virtual ~JNI();
 
 public:
+	enum struct BitmapResources {
+		TOUCH_ARROWS_BITMAP = 0
+	};
+
 	static bool pause;
 	static sem_t pause_sem;
 
@@ -68,6 +76,7 @@ public:
 	static bool isConnectionLimited();
 	static void showVirtualKeyboard(bool enable);
 	static void showKeyboardControl(bool enable);
+	static Graphics::Surface *getBitmapResource(BitmapResources resource);
 	static void setTouch3DMode(bool touch3DMode);
 	static void showSAFRevokePermsControl(bool enable);
 	static void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
@@ -115,6 +124,7 @@ private:
 	static jmethodID _MID_setWindowCaption;
 	static jmethodID _MID_showVirtualKeyboard;
 	static jmethodID _MID_showKeyboardControl;
+	static jmethodID _MID_getBitmapResource;
 	static jmethodID _MID_setTouch3DMode;
 	static jmethodID _MID_showSAFRevokePermsControl;
 	static jmethodID _MID_getSysArchives;
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 0cb8ac8a793..41dca1cab89 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -2,6 +2,7 @@ package org.scummvm.scummvm;
 
 import androidx.annotation.NonNull;
 import android.content.res.AssetManager;
+import android.graphics.Bitmap;
 import android.graphics.PixelFormat;
 import android.media.AudioAttributes;
 import android.media.AudioFormat;
@@ -72,6 +73,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
 	abstract protected void setWindowCaption(String caption);
 	abstract protected void showVirtualKeyboard(boolean enable);
 	abstract protected void showKeyboardControl(boolean enable);
+	abstract protected Bitmap getBitmapResource(int resource);
 	abstract protected void setTouch3DMode(boolean touch3DMode);
 	abstract protected void showSAFRevokePermsControl(boolean enable);
 	abstract protected String[] getSysArchives();
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 93dffe6e4bc..963a605b715 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -12,6 +12,8 @@ import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
 import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.Rect;
 import android.media.AudioManager;
 import android.net.Uri;
@@ -705,6 +707,23 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			});
 		}
 
+		@Override
+		protected Bitmap getBitmapResource(int resource) {
+			int id;
+			switch(resource) {
+				case 0: // TOUCH_ARROWS_BITMAP
+					id = R.drawable.touch_arrows;
+					break;
+				default:
+					return null;
+			}
+
+			BitmapFactory.Options opts = new BitmapFactory.Options();
+			opts.inScaled = false;
+
+			return BitmapFactory.decodeResource(getResources(), id, opts);
+		}
+
 		@Override
 		protected void setTouch3DMode(final boolean touch3DMode) {
 			runOnUiThread(new Runnable() {
diff --git a/backends/platform/android/touchcontrols.cpp b/backends/platform/android/touchcontrols.cpp
index 3b86a06838f..de50325610d 100644
--- a/backends/platform/android/touchcontrols.cpp
+++ b/backends/platform/android/touchcontrols.cpp
@@ -37,13 +37,11 @@
 // for the Android port
 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
 
-#include "common/fs.h"
-#include "common/stream.h"
-#include "common/archive.h"
-#include "image/tga.h"
+#include "graphics/conversion.h"
 
 #include "backends/graphics3d/android/texture.h"
 #include "backends/platform/android/android.h"
+#include "backends/platform/android/jni-android.h"
 #include "backends/platform/android/touchcontrols.h"
 
 TouchControls::TouchControls() :
@@ -156,26 +154,28 @@ TouchControls::FunctionBehavior TouchControls::functionBehaviors[TouchControls::
 	{ touchToRightState,    true,  .8f, .5f }
 };
 
-static GLES8888Texture *loadBuiltinTexture(const char *filename) {
-	Common::ArchiveMemberPtr member = SearchMan.getMember(filename);
-	Common::SeekableReadStream *str = member->createReadStream();
-	Image::TGADecoder dec;
-	dec.loadStream(*str);
-	const void *pixels = dec.getSurface()->getPixels();
+static GLES8888Texture *loadBuiltinTexture(JNI::BitmapResources resource) {
+	const Graphics::Surface *src = JNI::getBitmapResource(JNI::BitmapResources::TOUCH_ARROWS_BITMAP);
+	if (!src) {
+		error("Failed to fetch touch arrows bitmap");
+	}
 
 	GLES8888Texture *ret = new GLES8888Texture();
-	uint16 w = dec.getSurface()->w;
-	uint16 h = dec.getSurface()->h;
-	uint16 pitch = dec.getSurface()->pitch;
-	ret->allocBuffer(w, h);
-	ret->updateBuffer(0, 0, w, h, pixels, pitch);
+	ret->allocBuffer(src->w, src->h);
+	Graphics::Surface *dst = ret->surface();
+
+	Graphics::crossBlit(
+			(byte *)dst->getPixels(), (const byte *)src->getPixels(),
+			dst->pitch, src->pitch,
+			src->w, src->h,
+			src->format, dst->format);
 
-	delete str;
+	delete src;
 	return ret;
 }
 
 void TouchControls::init(int width, int height) {
-	_arrows_texture = loadBuiltinTexture("arrows.tga");
+	_arrows_texture = loadBuiltinTexture(JNI::BitmapResources::TOUCH_ARROWS_BITMAP);
 	_screen_width = width;
 	_screen_height = height;
 }
diff --git a/configure b/configure
index 1e272971ec8..f4390f4d3aa 100755
--- a/configure
+++ b/configure
@@ -6097,7 +6097,7 @@ case $_host_os in
 		# -lgcc is carefully placed here - we want to catch
 		# all toolchain symbols in *our* libraries rather
 		# than pick up anything unhygenic from the Android libs.
-		LIBS="-Wl,-Bstatic $static_libs -Wl,-Bdynamic -lgcc $system_libs -llog -landroid -lGLESv2"
+		LIBS="-Wl,-Bstatic $static_libs -Wl,-Bdynamic -lgcc $system_libs -llog -landroid -ljnigraphics -lGLESv2"
 		;;
 	ds)
 		# Moved -Wl,--gc-sections here to avoid it interfering with the library checks
diff --git a/dists/android/assets/arrows.tga b/dists/android/assets/arrows.tga
deleted file mode 100644
index 64a504fe4a6..00000000000
Binary files a/dists/android/assets/arrows.tga and /dev/null differ
diff --git a/dists/android/res/drawable/touch_arrows.png b/dists/android/res/drawable/touch_arrows.png
new file mode 100644
index 00000000000..816dabfd998
Binary files /dev/null and b/dists/android/res/drawable/touch_arrows.png differ


Commit: b6c0a1c6c87d6774dd18ec14843c3c1f4a656d1b
    https://github.com/scummvm/scummvm/commit/b6c0a1c6c87d6774dd18ec14843c3c1f4a656d1b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-01-02T17:45:32+01:00

Commit Message:
ANDROID: Refactor touch controls to be graphics backend agnostic

Changed paths:
    backends/graphics3d/android/android-graphics3d.cpp
    backends/graphics3d/android/android-graphics3d.h
    backends/platform/android/android.cpp
    backends/platform/android/touchcontrols.cpp
    backends/platform/android/touchcontrols.h


diff --git a/backends/graphics3d/android/android-graphics3d.cpp b/backends/graphics3d/android/android-graphics3d.cpp
index 720316d6007..b53980f3434 100644
--- a/backends/graphics3d/android/android-graphics3d.cpp
+++ b/backends/graphics3d/android/android-graphics3d.cpp
@@ -53,6 +53,26 @@
 #define CONTEXT_RESET_ENABLE(gl_param) if (!(saved ## gl_param)) { GLCALL(glDisable(gl_param)); }
 #define CONTEXT_RESET_DISABLE(gl_param) if (saved ## gl_param) { GLCALL(glEnable(gl_param)); }
 
+static GLES8888Texture *loadBuiltinTexture(JNI::BitmapResources resource) {
+	const Graphics::Surface *src = JNI::getBitmapResource(JNI::BitmapResources::TOUCH_ARROWS_BITMAP);
+	if (!src) {
+		error("Failed to fetch touch arrows bitmap");
+	}
+
+	GLES8888Texture *ret = new GLES8888Texture();
+	ret->allocBuffer(src->w, src->h);
+	Graphics::Surface *dst = ret->surface();
+
+	Graphics::crossBlit(
+			(byte *)dst->getPixels(), (const byte *)src->getPixels(),
+			dst->pitch, src->pitch,
+			src->w, src->h,
+			src->format, dst->format);
+
+	delete src;
+	return ret;
+}
+
 AndroidGraphics3dManager::AndroidGraphics3dManager() :
 	_screenChangeID(0),
 	_graphicsMode(0),
@@ -66,12 +86,13 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
 	_overlay_texture(0),
 	_overlay_background(nullptr),
 	_show_overlay(false),
-	_mouse_texture(0),
-	_mouse_texture_palette(0),
-	_mouse_texture_rgb(0),
+	_mouse_texture(nullptr),
+	_mouse_texture_palette(nullptr),
+	_mouse_texture_rgb(nullptr),
 	_mouse_hotspot(),
 	_mouse_dont_scale(false),
-	_show_mouse(false) {
+	_show_mouse(false),
+	_touchcontrols_texture(nullptr) {
 
 	if (JNI::egl_bits_per_pixel == 16) {
 		// We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
@@ -88,6 +109,8 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
 	}
 	_mouse_texture = _mouse_texture_palette;
 
+	_touchcontrols_texture = loadBuiltinTexture(JNI::BitmapResources::TOUCH_ARROWS_BITMAP);
+
 	initSurface();
 	JNI::setTouch3DMode(true);
 }
@@ -100,6 +123,8 @@ AndroidGraphics3dManager::~AndroidGraphics3dManager() {
 	glBindRenderbuffer(GL_RENDERBUFFER, 0);
 	glUseProgram(0);
 
+	JNI::setTouch3DMode(false);
+
 	deinitSurface();
 
 	delete _frame_buffer;
@@ -108,8 +133,7 @@ AndroidGraphics3dManager::~AndroidGraphics3dManager() {
 	delete _overlay_background;
 	delete _mouse_texture_palette;
 	delete _mouse_texture_rgb;
-
-	JNI::setTouch3DMode(false);
+	delete _touchcontrols_texture;
 }
 
 static void logExtensions() {
@@ -176,12 +200,15 @@ void AndroidGraphics3dManager::initSurface() {
 		_mouse_texture->reinit();
 	}
 
+	if (_touchcontrols_texture) {
+		_touchcontrols_texture->reinit();
+	}
+	dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().init(
+	    this, JNI::egl_surface_width, JNI::egl_surface_height);
+
 	updateScreenRect();
 	// double buffered, flip twice
 	clearScreen(kClearUpdate, 2);
-
-	dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().init(
-	    JNI::egl_surface_width, JNI::egl_surface_height);
 }
 
 void AndroidGraphics3dManager::deinitSurface() {
@@ -210,6 +237,12 @@ void AndroidGraphics3dManager::deinitSurface() {
 		_mouse_texture->release();
 	}
 
+	dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().init(
+	    nullptr, 0, 0);
+	if (_touchcontrols_texture) {
+		_touchcontrols_texture->release();
+	}
+
 	OpenGL::ContextGL::destroy();
 
 	JNI::deinitSurface();
@@ -286,9 +319,6 @@ void AndroidGraphics3dManager::updateScreen() {
 	clearScreen(kClear);
 
 	_game_texture->drawTextureRect();
-	if (!_show_overlay) {
-		dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().draw();
-	}
 
 	if (_show_overlay) {
 		if (_overlay_background && _overlay_background->getTextureName() != 0) {
@@ -302,6 +332,8 @@ void AndroidGraphics3dManager::updateScreen() {
 		}
 	}
 
+	dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().draw();
+
 	if (!JNI::swapBuffers()) {
 		LOGW("swapBuffers failed: 0x%x", glGetError());
 	}
@@ -932,3 +964,12 @@ bool AndroidGraphics3dManager::setState(const AndroidCommonGraphics::State &stat
 
 	return true;
 }
+
+void AndroidGraphics3dManager::touchControlNotifyChanged() {
+	// Make sure we redraw the screen
+	_force_redraw = true;
+}
+
+void AndroidGraphics3dManager::touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) {
+	_touchcontrols_texture->drawTexture(x, y, w, h, clip);
+}
diff --git a/backends/graphics3d/android/android-graphics3d.h b/backends/graphics3d/android/android-graphics3d.h
index 95d5c70a31d..c61cba89754 100644
--- a/backends/graphics3d/android/android-graphics3d.h
+++ b/backends/graphics3d/android/android-graphics3d.h
@@ -29,7 +29,10 @@
 #include "backends/graphics/android/android-graphics.h"
 #include "backends/graphics3d/android/texture.h"
 
-class AndroidGraphics3dManager : public GraphicsManager, public AndroidCommonGraphics {
+#include "backends/platform/android/touchcontrols.h"
+
+class AndroidGraphics3dManager :
+	public GraphicsManager, public AndroidCommonGraphics, public TouchControlsDrawer {
 public:
 	AndroidGraphics3dManager();
 	virtual ~AndroidGraphics3dManager();
@@ -116,6 +119,9 @@ public:
 	virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
 #endif
 
+	void touchControlNotifyChanged() override;
+	void touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) override;
+
 protected:
 	void updateScreenRect();
 	void updateCursorScaling();
@@ -176,6 +182,9 @@ private:
 	int _mouse_width_scaled, _mouse_height_scaled;
 	bool _mouse_dont_scale;
 	bool _show_mouse;
+
+	// Touch controls layer
+	GLESTexture *_touchcontrols_texture;
 };
 
 #endif
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 4d7b046ac7c..4ec28f177f8 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -180,6 +180,9 @@ OSystem_Android::~OSystem_Android() {
 
 	delete _savefileManager;
 	_savefileManager = 0;
+
+	// Uninitialize surface now to avoid it to be done later when touch controls are destroyed
+	dynamic_cast<AndroidCommonGraphics *>(_graphicsManager)->deinitSurface();
 }
 
 void *OSystem_Android::timerThreadFunc(void *arg) {
diff --git a/backends/platform/android/touchcontrols.cpp b/backends/platform/android/touchcontrols.cpp
index de50325610d..4712ac868cb 100644
--- a/backends/platform/android/touchcontrols.cpp
+++ b/backends/platform/android/touchcontrols.cpp
@@ -37,27 +37,21 @@
 // for the Android port
 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
 
-#include "graphics/conversion.h"
-
-#include "backends/graphics3d/android/texture.h"
 #include "backends/platform/android/android.h"
-#include "backends/platform/android/jni-android.h"
 #include "backends/platform/android/touchcontrols.h"
 
 TouchControls::TouchControls() :
-	_arrows_texture(nullptr),
+	_drawer(nullptr),
 	_screen_width(0),
 	_screen_height(0) {
 }
 
-TouchControls::~TouchControls() {
-	if (_arrows_texture) {
-		delete _arrows_texture;
-		_arrows_texture = 0;
+TouchControls::Function TouchControls::getFunction(int x, int y) {
+	if (_screen_width == 0) {
+		// Avoid divide by 0 error
+		return kFunctionNone;
 	}
-}
 
-TouchControls::Function TouchControls::getFunction(int x, int y) {
 	float xPercent = float(x) / _screen_width;
 
 	if (xPercent < 0.3) {
@@ -154,28 +148,8 @@ TouchControls::FunctionBehavior TouchControls::functionBehaviors[TouchControls::
 	{ touchToRightState,    true,  .8f, .5f }
 };
 
-static GLES8888Texture *loadBuiltinTexture(JNI::BitmapResources resource) {
-	const Graphics::Surface *src = JNI::getBitmapResource(JNI::BitmapResources::TOUCH_ARROWS_BITMAP);
-	if (!src) {
-		error("Failed to fetch touch arrows bitmap");
-	}
-
-	GLES8888Texture *ret = new GLES8888Texture();
-	ret->allocBuffer(src->w, src->h);
-	Graphics::Surface *dst = ret->surface();
-
-	Graphics::crossBlit(
-			(byte *)dst->getPixels(), (const byte *)src->getPixels(),
-			dst->pitch, src->pitch,
-			src->w, src->h,
-			src->format, dst->format);
-
-	delete src;
-	return ret;
-}
-
-void TouchControls::init(int width, int height) {
-	_arrows_texture = loadBuiltinTexture(JNI::BitmapResources::TOUCH_ARROWS_BITMAP);
+void TouchControls::init(TouchControlsDrawer *drawer, int width, int height) {
+	_drawer = drawer;
 	_screen_width = width;
 	_screen_height = height;
 }
@@ -214,6 +188,8 @@ TouchControls::Pointer *TouchControls::findPointerFromFunction(Function function
 }
 
 void TouchControls::draw() {
+	assert(_drawer != nullptr);
+
 	for (uint i = 0; i < kFunctionMax + 1; i++) {
 		FunctionState &state = _functionStates[i];
 		FunctionBehavior behavior = functionBehaviors[i];
@@ -221,7 +197,7 @@ void TouchControls::draw() {
 		if (state.clip.isEmpty()) {
 			continue;
 		}
-		_arrows_texture->drawTexture(_screen_width * behavior.xRatio, _screen_height * behavior.yRatio,
+		_drawer->touchControlDraw(_screen_width * behavior.xRatio, _screen_height * behavior.yRatio,
 		                             64, 64, state.clip);
 
 	}
@@ -238,6 +214,10 @@ void TouchControls::update(Action action, int ptrId, int x, int y) {
 		// ptrId is active no matter what
 		ptr->active = true;
 
+		if (function == kFunctionNone) {
+			// No function for this finger
+			return;
+		}
 		if (findPointerFromFunction(function)) {
 			// Some finger is already using this function: don't do anything
 			return;
@@ -280,6 +260,9 @@ void TouchControls::update(Action action, int ptrId, int x, int y) {
 			}
 		}
 		oldState = newState;
+		if (_drawer) {
+			_drawer->touchControlNotifyChanged();
+		}
 	} else if (action == JACTION_UP) {
 		Pointer *ptr = getPointerFromId(ptrId, false);
 		if (!ptr || ptr->function == kFunctionNone) {
@@ -307,6 +290,9 @@ void TouchControls::update(Action action, int ptrId, int x, int y) {
 
 		functionState.reset();
 		ptr->active = false;
+		if (_drawer) {
+			_drawer->touchControlNotifyChanged();
+		}
 	} else if (action == JACTION_CANCEL) {
 		for (uint i = 0; i < kNumPointers; i++) {
 			Pointer &ptr = _pointers[i];
@@ -325,6 +311,9 @@ void TouchControls::update(Action action, int ptrId, int x, int y) {
 
 			functionState.reset();
 		}
+		if (_drawer) {
+			_drawer->touchControlNotifyChanged();
+		}
 	}
 }
 
diff --git a/backends/platform/android/touchcontrols.h b/backends/platform/android/touchcontrols.h
index c8f2292d49f..09811a7c8af 100644
--- a/backends/platform/android/touchcontrols.h
+++ b/backends/platform/android/touchcontrols.h
@@ -24,7 +24,14 @@
 
 #include "common/events.h"
 
-#include "backends/graphics3d/android/texture.h"
+class TouchControlsDrawer {
+public:
+	virtual void touchControlNotifyChanged() = 0;
+	virtual void touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) = 0;
+
+protected:
+	~TouchControlsDrawer() {}
+};
 
 class TouchControls {
 public:
@@ -37,13 +44,14 @@ public:
 	};
 
 	TouchControls();
-	~TouchControls();
 
-	void init(int width, int height);
+	void init(TouchControlsDrawer *drawer, int width, int height);
 	void draw();
 	void update(Action action, int ptr, int x, int y);
 
 private:
+	TouchControlsDrawer *_drawer;
+
 	int _screen_width, _screen_height;
 
 	enum Function {
@@ -95,7 +103,6 @@ private:
 
 	FunctionState _functionStates[kFunctionMax + 1];
 
-	GLESTexture *_arrows_texture;
 	void buttonDown(Common::JoystickButton jb);
 	void buttonUp(Common::JoystickButton jb);
 	void buttonPress(Common::JoystickButton jb);
@@ -112,8 +119,6 @@ private:
 	static void touchToJoystickState(int dX, int dY, FunctionState &state);
 	static void touchToCenterState(int dX, int dY, FunctionState &state);
 	static void touchToRightState(int dX, int dY, FunctionState &state);
-
-
 };
 
 #endif


Commit: dcd02117cfcfc6997a111e8eb1e5bd28e77facca
    https://github.com/scummvm/scummvm/commit/dcd02117cfcfc6997a111e8eb1e5bd28e77facca
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-01-02T17:45:32+01:00

Commit Message:
OPENGL: Make back buffer accessible from derivated classes

Changed paths:
    backends/graphics/opengl/opengl-graphics.h


diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 0ef7a2c86af..5ff7ebbbaaa 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -295,11 +295,6 @@ private:
 	 */
 	void initializeGLContext();
 
-	/**
-	 * Render back buffer.
-	 */
-	Backbuffer _backBuffer;
-
 	/**
 	 * OpenGL pipeline used for rendering.
 	 */
@@ -342,6 +337,11 @@ protected:
 	 */
 	Graphics::PixelFormat _defaultFormatAlpha;
 
+	/**
+	 * Render back buffer.
+	 */
+	Backbuffer _backBuffer;
+
 	/**
 	 * The rendering surface for the virtual game screen.
 	 */


Commit: 639d633f12b58c3a00aacfdf693e8f44cfdd5866
    https://github.com/scummvm/scummvm/commit/639d633f12b58c3a00aacfdf693e8f44cfdd5866
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-01-02T17:45:32+01:00

Commit Message:
ANDROID: Add touch controls to 2D backend

This is not usable for now as it's always disabled

Changed paths:
    backends/graphics/android/android-graphics.cpp
    backends/graphics/android/android-graphics.h


diff --git a/backends/graphics/android/android-graphics.cpp b/backends/graphics/android/android-graphics.cpp
index c35dcbefc1c..27d1e7bb3fb 100644
--- a/backends/graphics/android/android-graphics.cpp
+++ b/backends/graphics/android/android-graphics.cpp
@@ -36,19 +36,48 @@
 // for the Android port
 #define FORBIDDEN_SYMBOL_EXCEPTION_printf
 
+#include "graphics/conversion.h"
+
+#include "backends/graphics/opengl/pipelines/pipeline.h"
+
 #include "backends/graphics/android/android-graphics.h"
 #include "backends/platform/android/android.h"
 #include "backends/platform/android/jni-android.h"
 
+static void loadBuiltinTexture(JNI::BitmapResources resource, OpenGL::Surface *surf) {
+	const Graphics::Surface *src = JNI::getBitmapResource(resource);
+	if (!src) {
+		error("Failed to fetch touch arrows bitmap");
+	}
+
+	surf->allocate(src->w, src->h);
+	Graphics::Surface *dst = surf->getSurface();
+
+	Graphics::crossBlit(
+			(byte *)dst->getPixels(), (const byte *)src->getPixels(),
+			dst->pitch, src->pitch,
+			src->w, src->h,
+			src->format, dst->format);
+
+	delete src;
+}
+
 //
 // AndroidGraphicsManager
 //
-AndroidGraphicsManager::AndroidGraphicsManager() {
+AndroidGraphicsManager::AndroidGraphicsManager() :
+	_touchcontrols(nullptr) {
 	ENTER();
 
 	// Initialize our OpenGL ES context.
 	initSurface();
 
+	_touchcontrols = createSurface(_defaultFormatAlpha);
+	loadBuiltinTexture(JNI::BitmapResources::TOUCH_ARROWS_BITMAP, _touchcontrols);
+	_touchcontrols->updateGLTexture();
+
+	// In 2D we always fallback to standard 2D mode
+	JNI::setTouch3DMode(false);
 }
 
 AndroidGraphicsManager::~AndroidGraphicsManager() {
@@ -78,6 +107,13 @@ void AndroidGraphicsManager::initSurface() {
 #endif
 	}
 
+	if (_touchcontrols) {
+		_touchcontrols->recreate();
+		_touchcontrols->updateGLTexture();
+	}
+	dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().init(
+	    this, JNI::egl_surface_width, JNI::egl_surface_height);
+
 	handleResize(JNI::egl_surface_width, JNI::egl_surface_height);
 }
 
@@ -87,6 +123,13 @@ void AndroidGraphicsManager::deinitSurface() {
 
 	LOGD("deinitializing 2D surface");
 
+	// Deregister us from touch control
+	dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().init(
+	    nullptr, 0, 0);
+	if (_touchcontrols) {
+		_touchcontrols->destroy();
+	}
+
 	notifyContextDestroy();
 
 	JNI::deinitSurface();
@@ -107,6 +150,17 @@ void AndroidGraphicsManager::displayMessageOnOSD(const Common::U32String &msg) {
 	JNI::displayMessageOnOSD(msg);
 }
 
+bool AndroidGraphicsManager::showMouse(bool visible) {
+	bool last = OpenGL::OpenGLGraphicsManager::showMouse(visible);
+
+	if (visible && last != visible) {
+		// We just displayed a mouse cursor, disable the 3D mode if user enabled it
+		JNI::setTouch3DMode(false);
+	}
+
+	return last;
+}
+
 float AndroidGraphicsManager::getHiDPIScreenFactor() const {
 	// TODO: Use JNI to get DisplayMetrics.density, which according to the documentation
 	// seems to be what we want.
@@ -130,9 +184,23 @@ bool AndroidGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHe
 void AndroidGraphicsManager::refreshScreen() {
 	//ENTER();
 
+	// Last minute draw of touch controls
+	dynamic_cast<OSystem_Android *>(g_system)->getTouchControls().draw();
+
 	JNI::swapBuffers();
 }
 
+void AndroidGraphicsManager::touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) {
+	_backBuffer.enableBlend(OpenGL::Framebuffer::kBlendModeTraditionalTransparency);
+	OpenGL::g_context.getActivePipeline()->drawTexture(_touchcontrols->getGLTexture(),
+		                                           x, y, w, h, clip);
+}
+
+void AndroidGraphicsManager::touchControlNotifyChanged() {
+	// Make sure we redraw the screen
+	_forceRedraw = true;
+}
+
 void *AndroidGraphicsManager::getProcAddress(const char *name) const {
 	ENTER("%s", name);
 
diff --git a/backends/graphics/android/android-graphics.h b/backends/graphics/android/android-graphics.h
index b0e71d9590d..76e493acc50 100644
--- a/backends/graphics/android/android-graphics.h
+++ b/backends/graphics/android/android-graphics.h
@@ -25,6 +25,8 @@
 #include "common/scummsys.h"
 #include "backends/graphics/opengl/opengl-graphics.h"
 
+#include "backends/platform/android/touchcontrols.h"
+
 class AndroidCommonGraphics {
 public:
 	virtual ~AndroidCommonGraphics() {}
@@ -61,7 +63,8 @@ public:
 	virtual bool setState(const State &state) = 0;
 };
 
-class AndroidGraphicsManager : public OpenGL::OpenGLGraphicsManager, public AndroidCommonGraphics {
+class AndroidGraphicsManager :
+	public OpenGL::OpenGLGraphicsManager, public AndroidCommonGraphics, public TouchControlsDrawer {
 public:
 	AndroidGraphicsManager();
 	virtual ~AndroidGraphicsManager();
@@ -81,8 +84,12 @@ public:
 
 	float getHiDPIScreenFactor() const override;
 
+	void touchControlNotifyChanged() override;
+	void touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) override;
+
 protected:
 	void setSystemMousePosition(const int x, const int y) override {}
+	bool showMouse(bool visible) override;
 
 	bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) override;
 
@@ -90,6 +97,8 @@ protected:
 
 	void *getProcAddress(const char *name) const override;
 
+private:
+	OpenGL::Surface *_touchcontrols;
 };
 
 #endif


Commit: 523b2262434f9e0f17767c0459043dfcaae6733e
    https://github.com/scummvm/scummvm/commit/523b2262434f9e0f17767c0459043dfcaae6733e
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-01-02T17:45:32+01:00

Commit Message:
ANDROID: Allow user to enable touch controls

Changed paths:
  A dists/android/res/drawable/ic_action_gamepad.xml
  A dists/android/res/drawable/ic_action_mouse.xml
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
    backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java


diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 963a605b715..23e565abfef 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -118,6 +118,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	FrameLayout _videoLayout = null;
 
 	private EditableSurfaceView _main_surface = null;
+	private ImageView _toggleGamepadBtnIcon = null;
 	private ImageView _toggleKeyboardBtnIcon = null;
 	private ImageView _openMenuBtnIcon = null;
 	private ImageView _revokeSafPermissionsBtnIcon = null;
@@ -569,6 +570,19 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	// ---------------------------------------------------------------------------------------------------------------------------
 	//
 
+	public final View.OnClickListener gamepadBtnOnClickListener = new View.OnClickListener() {
+		@Override
+		public void onClick(View v) {
+			runOnUiThread(new Runnable() {
+				public void run() {
+					boolean touch3DMode = !_events.getTouch3DMode();
+					_events.setTouch3DMode(touch3DMode);
+					_toggleGamepadBtnIcon.setImageResource(touch3DMode ? R.drawable.ic_action_mouse : R.drawable.ic_action_gamepad);
+				}
+			});
+		}
+	};
+
 	public final View.OnClickListener keyboardBtnOnClickListener = new View.OnClickListener() {
 		@Override
 		public void onClick(View v) {
@@ -726,9 +740,13 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 
 		@Override
 		protected void setTouch3DMode(final boolean touch3DMode) {
+			if (_events.getTouch3DMode() == touch3DMode) {
+				return;
+			}
 			runOnUiThread(new Runnable() {
 				public void run() {
 					_events.setTouch3DMode(touch3DMode);
+					_toggleGamepadBtnIcon.setImageResource(touch3DMode ? R.drawable.ic_action_mouse : R.drawable.ic_action_gamepad);
 				}
 			});
 		}
@@ -986,6 +1004,11 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		_videoLayout.addView(buttonLayout, buttonLayoutParams);
 		_videoLayout.bringChildToFront(buttonLayout);
 
+		_toggleGamepadBtnIcon = new ImageView(this);
+		_toggleGamepadBtnIcon.setImageResource(R.drawable.ic_action_gamepad);
+		buttonLayout.addView(_toggleGamepadBtnIcon, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
+		buttonLayout.bringChildToFront(_toggleGamepadBtnIcon);
+
 		_toggleKeyboardBtnIcon = new ImageView(this);
 		_toggleKeyboardBtnIcon.setImageResource(R.drawable.ic_action_keyboard);
 		buttonLayout.addView(_toggleKeyboardBtnIcon, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
@@ -1095,6 +1118,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 
 			// On screen button listener
 			//findViewById(R.id.show_keyboard).setOnClickListener(keyboardBtnOnClickListener);
+			_toggleGamepadBtnIcon.setOnClickListener(gamepadBtnOnClickListener);
 			_toggleKeyboardBtnIcon.setOnClickListener(keyboardBtnOnClickListener);
 			_openMenuBtnIcon.setOnClickListener(menuBtnOnClickListener);
 			_revokeSafPermissionsBtnIcon.setOnClickListener(revokeSafPermissionsBtnOnClickListener);
@@ -1359,11 +1383,11 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		}
 
 		if (_openMenuBtnIcon != null ) {
-			if (show) {
-				_openMenuBtnIcon.setVisibility(View.VISIBLE);
-			} else {
-				_openMenuBtnIcon.setVisibility(View.GONE);
-			}
+			_openMenuBtnIcon.setVisibility(show ? View.VISIBLE : View.GONE);
+		}
+
+		if (_toggleGamepadBtnIcon != null ) {
+			_toggleGamepadBtnIcon.setVisibility(show ? View.VISIBLE : View.GONE);
 		}
 	}
 
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
index b3d0e7be814..d1dba19c3af 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
@@ -142,6 +142,10 @@ public class ScummVMEventsBase implements
 		}
 	}
 
+	final public boolean getTouch3DMode() {
+		return _touch3DMode;
+	}
+
 	final public void setTouch3DMode(boolean touch3DMode) {
 		if (_touch3DMode != touch3DMode && !touch3DMode) {
 			_scummvm.updateTouch(JACTION_CANCEL, 0, 0, 0);
diff --git a/dists/android/res/drawable/ic_action_gamepad.xml b/dists/android/res/drawable/ic_action_gamepad.xml
new file mode 100644
index 00000000000..392d5dee7d9
--- /dev/null
+++ b/dists/android/res/drawable/ic_action_gamepad.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:alpha="0.5">
+  <path
+      android:fillColor="#ffffff"
+      android:pathData="M42,12L6,12c-2.2,0 -4,1.8 -4,4v16c0,2.2 1.8,4 4,4h36c2.2,0 4,-1.8 4,-4L46,16c0,-2.2 -1.8,-4 -4,-4zM22,26L16,26v6L12,32v-6L6,26v-4h6L12,16h4v6h6v4zM31,30c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM39,24c-1.66,0 -3,-1.34 -3,-3S37.34,18 39,18s3,1.34 3,3 -1.34,3 -3,3z"/>
+</vector>
diff --git a/dists/android/res/drawable/ic_action_mouse.xml b/dists/android/res/drawable/ic_action_mouse.xml
new file mode 100644
index 00000000000..b9c57cc68d3
--- /dev/null
+++ b/dists/android/res/drawable/ic_action_mouse.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:alpha="0.5">
+  <path
+      android:fillColor="#ffffff"
+      android:pathData="M26,2.14L26,18h14c0,-8.16 -6.1,-14.88 -14,-15.86zM8,30c0,8.84 7.16,16 16,16s16,-7.16 16,-16v-8L8,22v8zM22,2.14C14.1,3.12 8,9.84 8,18h14L22,2.14z"/>
+</vector>


Commit: 92dd9c091164ac565ef9c8fa9009f215e7dfcbab
    https://github.com/scummvm/scummvm/commit/92dd9c091164ac565ef9c8fa9009f215e7dfcbab
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-01-02T17:45:32+01:00

Commit Message:
ANDROID: Keep last touch mode when displaying overlay

Changed paths:
    backends/graphics/android/android-graphics.cpp
    backends/graphics/android/android-graphics.h
    backends/graphics3d/android/android-graphics3d.cpp
    backends/graphics3d/android/android-graphics3d.h
    backends/platform/android/jni-android.cpp
    backends/platform/android/jni-android.h
    backends/platform/android/org/scummvm/scummvm/ScummVM.java
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java


diff --git a/backends/graphics/android/android-graphics.cpp b/backends/graphics/android/android-graphics.cpp
index 27d1e7bb3fb..2e76100bc58 100644
--- a/backends/graphics/android/android-graphics.cpp
+++ b/backends/graphics/android/android-graphics.cpp
@@ -161,6 +161,25 @@ bool AndroidGraphicsManager::showMouse(bool visible) {
 	return last;
 }
 
+void AndroidGraphicsManager::showOverlay() {
+	if (_overlayVisible)
+		return;
+
+	_old_touch_3d_mode = JNI::getTouch3DMode();
+	JNI::setTouch3DMode(false);
+
+	OpenGL::OpenGLGraphicsManager::showOverlay();
+}
+
+void AndroidGraphicsManager::hideOverlay() {
+	if (!_overlayVisible)
+		return;
+
+	JNI::setTouch3DMode(_old_touch_3d_mode);
+
+	OpenGL::OpenGLGraphicsManager::hideOverlay();
+}
+
 float AndroidGraphicsManager::getHiDPIScreenFactor() const {
 	// TODO: Use JNI to get DisplayMetrics.density, which according to the documentation
 	// seems to be what we want.
diff --git a/backends/graphics/android/android-graphics.h b/backends/graphics/android/android-graphics.h
index 76e493acc50..beb0a58ae58 100644
--- a/backends/graphics/android/android-graphics.h
+++ b/backends/graphics/android/android-graphics.h
@@ -91,6 +91,10 @@ protected:
 	void setSystemMousePosition(const int x, const int y) override {}
 	bool showMouse(bool visible) override;
 
+	void showOverlay() override;
+	void hideOverlay() override;
+
+
 	bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) override;
 
 	void refreshScreen() override;
@@ -99,6 +103,7 @@ protected:
 
 private:
 	OpenGL::Surface *_touchcontrols;
+	bool _old_touch_3d_mode;
 };
 
 #endif
diff --git a/backends/graphics3d/android/android-graphics3d.cpp b/backends/graphics3d/android/android-graphics3d.cpp
index b53980f3434..ea78e61b755 100644
--- a/backends/graphics3d/android/android-graphics3d.cpp
+++ b/backends/graphics3d/android/android-graphics3d.cpp
@@ -92,7 +92,8 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
 	_mouse_hotspot(),
 	_mouse_dont_scale(false),
 	_show_mouse(false),
-	_touchcontrols_texture(nullptr) {
+	_touchcontrols_texture(nullptr),
+	_old_touch_3d_mode(false) {
 
 	if (JNI::egl_bits_per_pixel == 16) {
 		// We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
@@ -456,6 +457,7 @@ void AndroidGraphics3dManager::showOverlay() {
 		return;
 	}
 
+	_old_touch_3d_mode = JNI::getTouch3DMode();
 	JNI::setTouch3DMode(false);
 
 	_show_overlay = true;
@@ -502,7 +504,7 @@ void AndroidGraphics3dManager::hideOverlay() {
 
 	_overlay_background->release();
 
-	JNI::setTouch3DMode(true);
+	JNI::setTouch3DMode(_old_touch_3d_mode);
 
 	warpMouse(_game_texture->width() / 2, _game_texture->height() / 2);
 
diff --git a/backends/graphics3d/android/android-graphics3d.h b/backends/graphics3d/android/android-graphics3d.h
index c61cba89754..616d80fc0d1 100644
--- a/backends/graphics3d/android/android-graphics3d.h
+++ b/backends/graphics3d/android/android-graphics3d.h
@@ -185,6 +185,7 @@ private:
 
 	// Touch controls layer
 	GLESTexture *_touchcontrols_texture;
+	bool _old_touch_3d_mode;
 };
 
 #endif
diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index 98b00cf1d65..d8eb3d689eb 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -89,6 +89,7 @@ jmethodID JNI::_MID_showVirtualKeyboard = 0;
 jmethodID JNI::_MID_showKeyboardControl = 0;
 jmethodID JNI::_MID_getBitmapResource = 0;
 jmethodID JNI::_MID_setTouch3DMode = 0;
+jmethodID JNI::_MID_getTouch3DMode = 0;
 jmethodID JNI::_MID_showSAFRevokePermsControl = 0;
 jmethodID JNI::_MID_getSysArchives = 0;
 jmethodID JNI::_MID_getAllStorageLocations = 0;
@@ -464,11 +465,26 @@ void JNI::setTouch3DMode(bool touch3DMode) {
 	env->CallVoidMethod(_jobj, _MID_setTouch3DMode, touch3DMode);
 
 	if (env->ExceptionCheck()) {
-		LOGE("Error trying to show virtual keyboard control");
+		LOGE("Error trying to set touch controls mode");
+
+		env->ExceptionDescribe();
+		env->ExceptionClear();
+	}
+}
+
+bool JNI::getTouch3DMode() {
+	JNIEnv *env = JNI::getEnv();
+
+	bool enabled = env->CallBooleanMethod(_jobj, _MID_getTouch3DMode);
+
+	if (env->ExceptionCheck()) {
+		LOGE("Error trying to get touch controls status");
 
 		env->ExceptionDescribe();
 		env->ExceptionClear();
 	}
+
+	return enabled;
 }
 
 void JNI::showSAFRevokePermsControl(bool enable) {
@@ -658,6 +674,7 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
 	FIND_METHOD(, showKeyboardControl, "(Z)V");
 	FIND_METHOD(, getBitmapResource, "(I)Landroid/graphics/Bitmap;");
 	FIND_METHOD(, setTouch3DMode, "(Z)V");
+	FIND_METHOD(, getTouch3DMode, "()Z");
 	FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
 	FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
 	FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index ad4c63ac7b9..d3afb71f2e7 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -78,6 +78,7 @@ public:
 	static void showKeyboardControl(bool enable);
 	static Graphics::Surface *getBitmapResource(BitmapResources resource);
 	static void setTouch3DMode(bool touch3DMode);
+	static bool getTouch3DMode();
 	static void showSAFRevokePermsControl(bool enable);
 	static void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
 
@@ -126,6 +127,7 @@ private:
 	static jmethodID _MID_showKeyboardControl;
 	static jmethodID _MID_getBitmapResource;
 	static jmethodID _MID_setTouch3DMode;
+	static jmethodID _MID_getTouch3DMode;
 	static jmethodID _MID_showSAFRevokePermsControl;
 	static jmethodID _MID_getSysArchives;
 	static jmethodID _MID_getAllStorageLocations;
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 41dca1cab89..c042a9d6183 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -75,6 +75,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
 	abstract protected void showKeyboardControl(boolean enable);
 	abstract protected Bitmap getBitmapResource(int resource);
 	abstract protected void setTouch3DMode(boolean touch3DMode);
+	abstract protected boolean getTouch3DMode();
 	abstract protected void showSAFRevokePermsControl(boolean enable);
 	abstract protected String[] getSysArchives();
 	abstract protected String[] getAllStorageLocations();
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 23e565abfef..18b537643ee 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -751,6 +751,11 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			});
 		}
 
+		@Override
+		protected boolean getTouch3DMode() {
+			return _events.getTouch3DMode();
+		}
+
 		@Override
 		protected void showSAFRevokePermsControl(final boolean enable) {
 			runOnUiThread(new Runnable() {




More information about the Scummvm-git-logs mailing list