summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/detect.py36
-rw-r--r--platform/android/display_server_android.cpp70
-rw-r--r--platform/android/display_server_android.h10
-rw-r--r--platform/android/export/export_plugin.cpp2
-rw-r--r--platform/android/java/app/AndroidManifest.xml2
-rw-r--r--platform/android/java/app/config.gradle9
-rw-r--r--platform/android/java/editor/src/main/AndroidManifest.xml2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java3
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java49
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java47
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt3
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java14
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java11
-rw-r--r--platform/android/java/nativeSrcsConfigs/CMakeLists.txt2
-rw-r--r--platform/android/java_godot_view_wrapper.cpp13
-rw-r--r--platform/android/java_godot_view_wrapper.h5
-rw-r--r--platform/android/os_android.cpp7
-rw-r--r--platform/ios/app_delegate.mm9
-rw-r--r--platform/ios/godot_ios.mm8
-rw-r--r--platform/ios/os_ios.h6
-rw-r--r--platform/ios/os_ios.mm33
-rw-r--r--platform/macos/display_server_macos.mm6
-rw-r--r--platform/macos/export/export_plugin.cpp2
-rw-r--r--platform/web/js/engine/features.js10
-rw-r--r--platform/windows/crash_handler_windows.cpp2
-rw-r--r--platform/windows/display_server_windows.cpp4
-rw-r--r--platform/windows/godot.icobin359559 -> 142638 bytes
-rw-r--r--platform/windows/godot_console.icobin0 -> 140380 bytes
-rw-r--r--platform/windows/godot_res_wrap.rc2
30 files changed, 256 insertions, 113 deletions
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 6eb8ba34ed..ec36a40941 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -24,7 +24,11 @@ def can_build():
def get_opts():
return [
("ANDROID_SDK_ROOT", "Path to the Android SDK", get_env_android_sdk_root()),
- ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
+ (
+ "ndk_platform",
+ 'Target platform (android-<api>, e.g. "android-' + str(get_min_target_api()) + '")',
+ "android-" + str(get_min_target_api()),
+ ),
]
@@ -46,6 +50,11 @@ def get_ndk_version():
return "23.2.8568313"
+# This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
+def get_min_target_api():
+ return 21
+
+
def get_flags():
return [
("arch", "arm64"), # Default for convenience.
@@ -87,30 +96,26 @@ def configure(env: "Environment"):
)
sys.exit()
+ if get_min_sdk_version(env["ndk_platform"]) < get_min_target_api():
+ print(
+ "WARNING: minimum supported Android target api is %d. Forcing target api %d."
+ % (get_min_target_api(), get_min_target_api())
+ )
+ env["ndk_platform"] = "android-" + str(get_min_target_api())
+
install_ndk_if_needed(env)
ndk_root = env["ANDROID_NDK_ROOT"]
# Architecture
- if get_min_sdk_version(env["ndk_platform"]) < 21 and env["arch"] in ["x86_64", "arm64"]:
- print(
- 'WARNING: arch="%s" is not supported with "ndk_platform" lower than "android-21". Forcing platform 21.'
- % env["arch"]
- )
- env["ndk_platform"] = "android-21"
-
if env["arch"] == "arm32":
target_triple = "armv7a-linux-androideabi"
- env.extra_suffix = ".armv7" + env.extra_suffix
elif env["arch"] == "arm64":
target_triple = "aarch64-linux-android"
- env.extra_suffix = ".armv8" + env.extra_suffix
elif env["arch"] == "x86_32":
target_triple = "i686-linux-android"
- env.extra_suffix = ".x86" + env.extra_suffix
elif env["arch"] == "x86_64":
target_triple = "x86_64-linux-android"
- env.extra_suffix = ".x86_64" + env.extra_suffix
target_option = ["-target", target_triple + str(get_min_sdk_version(env["ndk_platform"]))]
env.Append(ASFLAGS=[target_option, "-c"])
@@ -165,7 +170,6 @@ def configure(env: "Environment"):
"-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing".split()
)
)
- env.Append(CPPDEFINES=["GLES_ENABLED"])
if get_min_sdk_version(env["ndk_platform"]) >= 24:
env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)])
@@ -188,9 +192,13 @@ def configure(env: "Environment"):
env.Prepend(CPPPATH=["#platform/android"])
env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"])
- env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "android", "log", "z", "dl"])
+ env.Append(LIBS=["OpenSLES", "EGL", "android", "log", "z", "dl"])
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
if not env["use_volk"]:
env.Append(LIBS=["vulkan"])
+
+ if env["opengl3"]:
+ env.Append(CPPDEFINES=["GLES3_ENABLED"])
+ env.Append(LIBS=["GLESv3"])
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 967f5c7dae..f76f3844e9 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -41,6 +41,10 @@
#include "platform/android/vulkan/vulkan_context_android.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
+#ifdef GLES3_ENABLED
+#include "drivers/gles3/rasterizer_gles3.h"
+#include <EGL/egl.h>
+#endif
DisplayServerAndroid *DisplayServerAndroid::get_singleton() {
return static_cast<DisplayServerAndroid *>(DisplayServer::get_singleton());
@@ -323,7 +327,7 @@ int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type,
}
#ifdef GLES3_ENABLED
case OPENGL_CONTEXT: {
- return eglGetCurrentContext();
+ return reinterpret_cast<int64_t>(eglGetCurrentContext());
}
#endif
default: {
@@ -449,6 +453,14 @@ DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_drive
DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error));
if (r_error != OK) {
OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver");
+ if (p_rendering_driver == "vulkan") {
+ OS::get_singleton()->alert("Your video card driver does not support the selected Vulkan version.\n"
+ "Please try exporting your game using the gl_compatibility renderer.",
+ "Unable to initialize Video driver");
+ } else {
+ OS::get_singleton()->alert("Your video card driver does not support OpenGL ES 3.0.",
+ "Unable to initialize Video driver");
+ }
}
return ds;
}
@@ -493,28 +505,11 @@ void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) {
DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
- // TODO: rendering_driver is broken, change when different drivers are supported again
- rendering_driver = "vulkan";
-
keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
- bool gl_initialization_error = false;
-
- if (RasterizerGLES3::is_viable() == OK) {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- } else {
- gl_initialization_error = true;
- }
-
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n"
- "Please try updating your Android version.",
- "Unable to initialize video driver");
- return;
- }
+ RasterizerGLES3::make_current();
}
#endif
@@ -619,11 +614,11 @@ MouseButton DisplayServerAndroid::mouse_get_button_state() const {
return (MouseButton)Input::get_singleton()->get_mouse_button_mask();
}
-void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape) {
+void DisplayServerAndroid::_cursor_set_shape_helper(CursorShape p_shape, bool force) {
if (!OS_Android::get_singleton()->get_godot_java()->get_godot_view()->can_update_pointer_icon()) {
return;
}
- if (cursor_shape == p_shape) {
+ if (cursor_shape == p_shape && !force) {
return;
}
@@ -634,10 +629,23 @@ void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape)
}
}
+void DisplayServerAndroid::cursor_set_shape(DisplayServer::CursorShape p_shape) {
+ _cursor_set_shape_helper(p_shape);
+}
+
DisplayServer::CursorShape DisplayServerAndroid::cursor_get_shape() const {
return cursor_shape;
}
+void DisplayServerAndroid::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ String cursor_path = p_cursor.is_valid() ? p_cursor->get_path() : "";
+ if (!cursor_path.is_empty()) {
+ cursor_path = ProjectSettings::get_singleton()->globalize_path(cursor_path);
+ }
+ OS_Android::get_singleton()->get_godot_java()->get_godot_view()->configure_pointer_icon(android_cursors[cursor_shape], cursor_path, p_hotspot);
+ _cursor_set_shape_helper(p_shape, true);
+}
+
void DisplayServerAndroid::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
#if defined(VULKAN_ENABLED)
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
@@ -651,3 +659,23 @@ DisplayServer::VSyncMode DisplayServerAndroid::window_get_vsync_mode(WindowID p_
return DisplayServer::VSYNC_ENABLED;
#endif
}
+
+void DisplayServerAndroid::reset_swap_buffers_flag() {
+ swap_buffers_flag = false;
+}
+
+bool DisplayServerAndroid::should_swap_buffers() const {
+ return swap_buffers_flag;
+}
+
+void DisplayServerAndroid::swap_buffers() {
+ swap_buffers_flag = true;
+}
+
+void DisplayServerAndroid::set_native_icon(const String &p_filename) {
+ // NOT SUPPORTED
+}
+
+void DisplayServerAndroid::set_icon(const Ref<Image> &p_icon) {
+ // NOT SUPPORTED
+}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index a6bc88e048..c7f4d8046f 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -66,6 +66,7 @@ class DisplayServerAndroid : public DisplayServer {
MouseMode mouse_mode = MouseMode::MOUSE_MODE_VISIBLE;
bool keep_screen_on;
+ bool swap_buffers_flag;
CursorShape cursor_shape = CursorShape::CURSOR_ARROW;
@@ -188,8 +189,10 @@ public:
void process_magnetometer(const Vector3 &p_magnetometer);
void process_gyroscope(const Vector3 &p_gyroscope);
+ void _cursor_set_shape_helper(CursorShape p_shape, bool force = false);
virtual void cursor_set_shape(CursorShape p_shape) override;
virtual CursorShape cursor_get_shape() const override;
+ virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
@@ -204,6 +207,13 @@ public:
virtual Point2i mouse_get_position() const override;
virtual MouseButton mouse_get_button_state() const override;
+ void reset_swap_buffers_flag();
+ bool should_swap_buffers() const;
+ virtual void swap_buffers() override;
+
+ virtual void set_native_icon(const String &p_filename) override;
+ virtual void set_icon(const Ref<Image> &p_icon) override;
+
DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error);
~DisplayServerAndroid();
};
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index c3fba625c6..737e25b270 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -245,7 +245,7 @@ static const int EXPORT_FORMAT_AAB = 1;
static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets";
static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets";
-static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
+static const int DEFAULT_MIN_SDK_VERSION = 21; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
#ifndef ANDROID_ENABLED
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index 2d4c4763a2..1db135826a 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -13,7 +13,7 @@
android:xlargeScreens="true" />
<uses-feature
- android:glEsVersion="0x00020000"
+ android:glEsVersion="0x00030000"
android:required="true" />
<application
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index e1d9dc4cde..f1b4bfd534 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,14 +1,17 @@
ext.versions = [
androidGradlePlugin: '7.2.1',
compileSdk : 32,
- minSdk : 19, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
- targetSdk : 32, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
+ // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
+ minSdk : 21,
+ // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
+ targetSdk : 32,
buildTools : '32.0.0',
kotlinVersion : '1.7.0',
fragmentVersion : '1.3.6',
nexusPublishVersion: '1.1.0',
javaVersion : 11,
- ndkVersion : '23.2.8568313' // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
+ // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
+ ndkVersion : '23.2.8568313'
]
diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml
index 6aa5f06f31..f3ddaafd0e 100644
--- a/platform/android/java/editor/src/main/AndroidManifest.xml
+++ b/platform/android/java/editor/src/main/AndroidManifest.xml
@@ -11,7 +11,7 @@
android:xlargeScreens="true" />
<uses-feature
- android:glEsVersion="0x00020000"
+ android:glEsVersion="0x00030000"
android:required="true" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index a002a37ab9..3487e5019c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -175,6 +175,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
public GodotIO io;
public GodotNetUtils netUtils;
public GodotTTS tts;
+ DirectoryAccessHandler directoryAccessHandler;
public interface ResultCallback {
void callback(int requestCode, int resultCode, Intent data);
@@ -488,7 +489,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
netUtils = new GodotNetUtils(activity);
tts = new GodotTTS(activity);
Context context = getContext();
- DirectoryAccessHandler directoryAccessHandler = new DirectoryAccessHandler(context);
+ directoryAccessHandler = new DirectoryAccessHandler(context);
FileAccessHandler fileAccessHandler = new FileAccessHandler(context);
mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index 3dfc37f6b0..f8d937521b 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -43,8 +43,13 @@ import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.os.Build;
+import android.text.TextUtils;
+import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.PointerIcon;
@@ -52,6 +57,8 @@ import android.view.SurfaceView;
import androidx.annotation.Keep;
+import java.io.InputStream;
+
/**
* A simple GLSurfaceView sub-class that demonstrate how to perform
* OpenGL ES 2.0 rendering into a GL Surface. Note the following important
@@ -61,7 +68,7 @@ import androidx.annotation.Keep;
* See ContextFactory class definition below.
*
* - The class must use a custom EGLConfigChooser to be able to select
- * an EGLConfig that supports 2.0. This is done by providing a config
+ * an EGLConfig that supports 3.0. This is done by providing a config
* specification to eglChooseConfig() that has the attribute
* EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
* set. See ConfigChooser class definition below.
@@ -74,6 +81,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
private final Godot godot;
private final GodotInputHandler inputHandler;
private final GodotRenderer godotRenderer;
+ private final SparseArray<PointerIcon> customPointerIcons = new SparseArray<>();
public GodotGLRenderView(Context context, Godot godot, XRMode xrMode, boolean p_use_debug_opengl) {
super(context);
@@ -169,12 +177,49 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
}
/**
+ * Used to configure the PointerIcon for the given type.
+ *
+ * Called from JNI
+ */
+ @Keep
+ @Override
+ public void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY) {
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+ try {
+ Bitmap bitmap = null;
+ if (!TextUtils.isEmpty(imagePath)) {
+ if (godot.directoryAccessHandler.filesystemFileExists(imagePath)) {
+ // Try to load the bitmap from the file system
+ bitmap = BitmapFactory.decodeFile(imagePath);
+ } else if (godot.directoryAccessHandler.assetsFileExists(imagePath)) {
+ // Try to load the bitmap from the assets directory
+ AssetManager am = getContext().getAssets();
+ InputStream imageInputStream = am.open(imagePath);
+ bitmap = BitmapFactory.decodeStream(imageInputStream);
+ }
+ }
+
+ PointerIcon customPointerIcon = PointerIcon.create(bitmap, hotSpotX, hotSpotY);
+ customPointerIcons.put(pointerType, customPointerIcon);
+ } catch (Exception e) {
+ // Reset the custom pointer icon
+ customPointerIcons.delete(pointerType);
+ }
+ }
+ }
+
+ /**
* called from JNI to change pointer icon
*/
@Keep
+ @Override
public void setPointerIcon(int pointerType) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- setPointerIcon(PointerIcon.getSystemIcon(getContext(), pointerType));
+ PointerIcon pointerIcon = customPointerIcons.get(pointerType);
+ if (pointerIcon == null) {
+ pointerIcon = PointerIcon.getSystemIcon(getContext(), pointerType);
+ }
+ setPointerIcon(pointerIcon);
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
index cb63fd885f..ab74ba037d 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
@@ -48,5 +48,7 @@ public interface GodotRenderView {
GodotInputHandler getInputHandler();
+ void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY);
+
void setPointerIcon(int pointerType);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
index 0becf00d93..56bc7f9e76 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -36,7 +36,12 @@ import org.godotengine.godot.vulkan.VkSurfaceView;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.os.Build;
+import android.text.TextUtils;
+import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.PointerIcon;
@@ -44,10 +49,13 @@ import android.view.SurfaceView;
import androidx.annotation.Keep;
+import java.io.InputStream;
+
public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView {
private final Godot godot;
private final GodotInputHandler mInputHandler;
private final VkRenderer mRenderer;
+ private final SparseArray<PointerIcon> customPointerIcons = new SparseArray<>();
public GodotVulkanRenderView(Context context, Godot godot) {
super(context);
@@ -143,12 +151,49 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV
}
/**
+ * Used to configure the PointerIcon for the given type.
+ *
+ * Called from JNI
+ */
+ @Keep
+ @Override
+ public void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY) {
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
+ try {
+ Bitmap bitmap = null;
+ if (!TextUtils.isEmpty(imagePath)) {
+ if (godot.directoryAccessHandler.filesystemFileExists(imagePath)) {
+ // Try to load the bitmap from the file system
+ bitmap = BitmapFactory.decodeFile(imagePath);
+ } else if (godot.directoryAccessHandler.assetsFileExists(imagePath)) {
+ // Try to load the bitmap from the assets directory
+ AssetManager am = getContext().getAssets();
+ InputStream imageInputStream = am.open(imagePath);
+ bitmap = BitmapFactory.decodeStream(imageInputStream);
+ }
+ }
+
+ PointerIcon customPointerIcon = PointerIcon.create(bitmap, hotSpotX, hotSpotY);
+ customPointerIcons.put(pointerType, customPointerIcon);
+ } catch (Exception e) {
+ // Reset the custom pointer icon
+ customPointerIcons.delete(pointerType);
+ }
+ }
+ }
+
+ /**
* called from JNI to change pointer icon
*/
@Keep
+ @Override
public void setPointerIcon(int pointerType) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- setPointerIcon(PointerIcon.getSystemIcon(getContext(), pointerType));
+ PointerIcon pointerIcon = customPointerIcons.get(pointerType);
+ if (pointerIcon == null) {
+ pointerIcon = PointerIcon.getSystemIcon(getContext(), pointerType);
+ }
+ setPointerIcon(pointerIcon);
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt
index fedcf4843f..6bc317415f 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/DirectoryAccessHandler.kt
@@ -79,6 +79,9 @@ class DirectoryAccessHandler(context: Context) {
private val assetsDirAccess = AssetsDirectoryAccess(context)
private val fileSystemDirAccess = FilesystemDirectoryAccess(context)
+ fun assetsFileExists(assetsPath: String) = assetsDirAccess.fileExists(assetsPath)
+ fun filesystemFileExists(path: String) = fileSystemDirAccess.fileExists(path)
+
private fun hasDirId(accessType: AccessType, dirId: Int): Boolean {
return when (accessType) {
ACCESS_RESOURCES -> assetsDirAccess.hasDirId(dirId)
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
index 445238b1c2..9834fdfb88 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
@@ -45,20 +45,18 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
private int[] mValue = new int[1];
- // FIXME: Add support for Vulkan.
-
- /* This EGL config specification is used to specify 2.0 rendering.
+ /* This EGL config specification is used to specify 3.0 rendering.
* We use a minimum size of 4 bits for red/green/blue, but will
* perform actual matching in chooseConfig() below.
*/
private static int EGL_OPENGL_ES2_BIT = 4;
- private static int[] s_configAttribs2 = {
+ private static int[] s_configAttribs = {
EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4,
- // EGL10.EGL_DEPTH_SIZE, 16,
+ // EGL10.EGL_DEPTH_SIZE, 16,
// EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE,
- EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //apparently there is no EGL_OPENGL_ES3_BIT
EGL10.EGL_NONE
};
@@ -75,7 +73,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
/* Get the number of minimally matching EGL configurations
*/
int[] num_config = new int[1];
- egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
+ egl.eglChooseConfig(display, s_configAttribs, null, 0, num_config);
int numConfigs = num_config[0];
@@ -86,7 +84,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
/* Allocate then read the array of minimally matching EGL configs
*/
EGLConfig[] configs = new EGLConfig[numConfigs];
- egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
+ egl.eglChooseConfig(display, s_configAttribs, configs, numConfigs, num_config);
if (GLUtils.DEBUG) {
GLUtils.printConfigs(egl, display, configs);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
index 5d62723170..8fb86bf6d0 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
@@ -52,17 +52,16 @@ public class RegularContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
- // FIXME: Add support for Vulkan.
- Log.w(TAG, "creating OpenGL ES 2.0 context :");
+ Log.w(TAG, "creating OpenGL ES 3.0 context :");
GLUtils.checkEglError(TAG, "Before eglCreateContext", egl);
EGLContext context;
if (GLUtils.use_debug_opengl) {
- int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
- context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2);
+ int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 3, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
+ context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
} else {
- int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
- context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2);
+ int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
+ context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
}
GLUtils.checkEglError(TAG, "After eglCreateContext", egl);
return context;
diff --git a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
index 711f7cd502..e1534c7685 100644
--- a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
+++ b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
@@ -17,4 +17,4 @@ target_include_directories(${PROJECT_NAME}
SYSTEM PUBLIC
${GODOT_ROOT_DIR})
-add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED)
+add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED -DTOOLS_ENABLED)
diff --git a/platform/android/java_godot_view_wrapper.cpp b/platform/android/java_godot_view_wrapper.cpp
index 378a467772..23cfc5f2e6 100644
--- a/platform/android/java_godot_view_wrapper.cpp
+++ b/platform/android/java_godot_view_wrapper.cpp
@@ -42,6 +42,7 @@ GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) {
int android_device_api_level = android_get_device_api_level();
if (android_device_api_level >= __ANDROID_API_N__) {
+ _configure_pointer_icon = env->GetMethodID(_cls, "configurePointerIcon", "(ILjava/lang/String;FF)V");
_set_pointer_icon = env->GetMethodID(_cls, "setPointerIcon", "(I)V");
}
if (android_device_api_level >= __ANDROID_API_O__) {
@@ -51,7 +52,7 @@ GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) {
}
bool GodotJavaViewWrapper::can_update_pointer_icon() const {
- return _set_pointer_icon != nullptr;
+ return _configure_pointer_icon != nullptr && _set_pointer_icon != nullptr;
}
bool GodotJavaViewWrapper::can_capture_pointer() const {
@@ -76,6 +77,16 @@ void GodotJavaViewWrapper::release_pointer_capture() {
}
}
+void GodotJavaViewWrapper::configure_pointer_icon(int pointer_type, const String &image_path, const Vector2 &p_hotspot) {
+ if (_configure_pointer_icon != nullptr) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_NULL(env);
+
+ jstring jImagePath = env->NewStringUTF(image_path.utf8().get_data());
+ env->CallVoidMethod(_godot_view, _configure_pointer_icon, pointer_type, jImagePath, p_hotspot.x, p_hotspot.y);
+ }
+}
+
void GodotJavaViewWrapper::set_pointer_icon(int pointer_type) {
if (_set_pointer_icon != nullptr) {
JNIEnv *env = get_jni_env();
diff --git a/platform/android/java_godot_view_wrapper.h b/platform/android/java_godot_view_wrapper.h
index b398c73cac..b58a6607ce 100644
--- a/platform/android/java_godot_view_wrapper.h
+++ b/platform/android/java_godot_view_wrapper.h
@@ -31,6 +31,7 @@
#ifndef JAVA_GODOT_VIEW_WRAPPER_H
#define JAVA_GODOT_VIEW_WRAPPER_H
+#include "core/math/vector2.h"
#include <android/log.h>
#include <jni.h>
@@ -45,6 +46,8 @@ private:
jmethodID _request_pointer_capture = 0;
jmethodID _release_pointer_capture = 0;
+
+ jmethodID _configure_pointer_icon = 0;
jmethodID _set_pointer_icon = 0;
public:
@@ -55,6 +58,8 @@ public:
void request_pointer_capture();
void release_pointer_capture();
+
+ void configure_pointer_icon(int pointer_type, const String &image_path, const Vector2 &p_hotspot);
void set_pointer_icon(int pointer_type);
~GodotJavaViewWrapper();
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 97fa90b1d2..4f81e4bccd 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -268,12 +268,16 @@ bool OS_Android::main_loop_iterate(bool *r_should_swap_buffers) {
if (!main_loop) {
return false;
}
+ DisplayServerAndroid::get_singleton()->reset_swap_buffers_flag();
DisplayServerAndroid::get_singleton()->process_events();
uint64_t current_frames_drawn = Engine::get_singleton()->get_frames_drawn();
bool exit = Main::iteration();
if (r_should_swap_buffers) {
- *r_should_swap_buffers = !is_in_low_processor_usage_mode() || RenderingServer::get_singleton()->has_changed() || current_frames_drawn != Engine::get_singleton()->get_frames_drawn();
+ *r_should_swap_buffers = !is_in_low_processor_usage_mode() ||
+ DisplayServerAndroid::get_singleton()->should_swap_buffers() ||
+ RenderingServer::get_singleton()->has_changed() ||
+ current_frames_drawn != Engine::get_singleton()->get_frames_drawn();
}
return exit;
@@ -474,7 +478,6 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god
#if defined(GLES3_ENABLED)
gl_extensions = nullptr;
- use_gl2 = false;
#endif
#if defined(VULKAN_ENABLED)
diff --git a/platform/ios/app_delegate.mm b/platform/ios/app_delegate.mm
index fb183d52d4..3ebd530585 100644
--- a/platform/ios/app_delegate.mm
+++ b/platform/ios/app_delegate.mm
@@ -45,7 +45,7 @@
extern int gargc;
extern char **gargv;
-extern int ios_main(int, char **, String, String);
+extern int ios_main(int, char **);
extern void ios_finish();
@implementation AppDelegate
@@ -66,12 +66,7 @@ static ViewController *mainViewController = nil;
// Create a full-screen window
self.window = [[UIWindow alloc] initWithFrame:windowBounds];
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
- paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
- NSString *cacheDirectory = [paths objectAtIndex:0];
-
- int err = ios_main(gargc, gargv, String::utf8([documentsDirectory UTF8String]), String::utf8([cacheDirectory UTF8String]));
+ int err = ios_main(gargc, gargv);
if (err != 0) {
// bail, things did not go very well for us, should probably output a message on screen with our error code...
diff --git a/platform/ios/godot_ios.mm b/platform/ios/godot_ios.mm
index 5f3e786b8a..abe7c59ce2 100644
--- a/platform/ios/godot_ios.mm
+++ b/platform/ios/godot_ios.mm
@@ -38,10 +38,6 @@
static OS_IOS *os = nullptr;
-int add_path(int, char **);
-int add_cmdline(int, char **);
-int ios_main(int, char **, String);
-
int add_path(int p_argc, char **p_args) {
NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"];
if (!str) {
@@ -74,7 +70,7 @@ int add_cmdline(int p_argc, char **p_args) {
return p_argc;
}
-int ios_main(int argc, char **argv, String data_dir, String cache_dir) {
+int ios_main(int argc, char **argv) {
size_t len = strlen(argv[0]);
while (len--) {
@@ -95,7 +91,7 @@ int ios_main(int argc, char **argv, String data_dir, String cache_dir) {
char cwd[512];
getcwd(cwd, sizeof(cwd));
printf("cwd %s\n", cwd);
- os = new OS_IOS(data_dir, cache_dir);
+ os = new OS_IOS();
// We must override main when testing is enabled
TEST_MAIN_OVERRIDE
diff --git a/platform/ios/os_ios.h b/platform/ios/os_ios.h
index 400040875f..3560de7486 100644
--- a/platform/ios/os_ios.h
+++ b/platform/ios/os_ios.h
@@ -71,9 +71,6 @@ private:
virtual void finalize() override;
- String user_data_dir;
- String cache_dir;
-
bool is_focused = false;
void deinitialize_modules();
@@ -81,7 +78,7 @@ private:
public:
static OS_IOS *get_singleton();
- OS_IOS(String p_data_dir, String p_cache_dir);
+ OS_IOS();
~OS_IOS();
void initialize_modules();
@@ -106,7 +103,6 @@ public:
virtual Error shell_open(String p_uri) override;
- void set_user_data_dir(String p_dir);
virtual String get_user_data_dir() const override;
virtual String get_cache_path() const override;
diff --git a/platform/ios/os_ios.mm b/platform/ios/os_ios.mm
index b6b94d2f5e..9a8cfc2593 100644
--- a/platform/ios/os_ios.mm
+++ b/platform/ios/os_ios.mm
@@ -90,7 +90,7 @@ OS_IOS *OS_IOS::get_singleton() {
return (OS_IOS *)OS::get_singleton();
}
-OS_IOS::OS_IOS(String p_data_dir, String p_cache_dir) {
+OS_IOS::OS_IOS() {
for (int i = 0; i < ios_init_callbacks_count; ++i) {
ios_init_callbacks[i]();
}
@@ -101,11 +101,6 @@ OS_IOS::OS_IOS(String p_data_dir, String p_cache_dir) {
main_loop = nullptr;
- // can't call set_data_dir from here, since it requires DirAccess
- // which is initialized in initialize_core
- user_data_dir = p_data_dir;
- cache_dir = p_cache_dir;
-
Vector<Logger *> loggers;
loggers.push_back(memnew(SyslogLogger));
#ifdef DEBUG_ENABLED
@@ -130,8 +125,6 @@ void OS_IOS::alert(const String &p_alert, const String &p_title) {
void OS_IOS::initialize_core() {
OS_Unix::initialize_core();
-
- set_user_data_dir(user_data_dir);
}
void OS_IOS::initialize() {
@@ -273,18 +266,26 @@ Error OS_IOS::shell_open(String p_uri) {
return OK;
}
-void OS_IOS::set_user_data_dir(String p_dir) {
- Ref<DirAccess> da = DirAccess::open(p_dir);
- user_data_dir = da->get_current_dir();
- printf("setting data dir to %s from %s\n", user_data_dir.utf8().get_data(), p_dir.utf8().get_data());
-}
-
String OS_IOS::get_user_data_dir() const {
- return user_data_dir;
+ static String ret;
+ if (ret.is_empty()) {
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ if (paths && [paths count] >= 1) {
+ ret.parse_utf8([[paths firstObject] UTF8String]);
+ }
+ }
+ return ret;
}
String OS_IOS::get_cache_path() const {
- return cache_dir;
+ static String ret;
+ if (ret.is_empty()) {
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
+ if (paths && [paths count] >= 1) {
+ ret.parse_utf8([[paths firstObject] UTF8String]);
+ }
+ }
+ return ret;
}
String OS_IOS::get_locale() const {
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 3aff5b8b7e..a3bee13f69 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -2348,9 +2348,6 @@ void DisplayServerMacOS::reparent_check(WindowID p_window) {
if (parent_screen == screen) {
if (![[wd_parent.window_object childWindows] containsObject:wd.window_object]) {
- if (wd.exclusive) {
- ERR_FAIL_COND_MSG([[wd_parent.window_object childWindows] count] > 0, "Transient parent has another exclusive child.");
- }
[wd.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
[wd_parent.window_object addChildWindow:wd.window_object ordered:NSWindowAbove];
}
@@ -2369,9 +2366,6 @@ void DisplayServerMacOS::reparent_check(WindowID p_window) {
if (child_screen == screen) {
if (![[wd.window_object childWindows] containsObject:wd_child.window_object]) {
- if (wd_child.exclusive) {
- ERR_FAIL_COND_MSG([[wd.window_object childWindows] count] > 0, "Transient parent has another exclusive child.");
- }
if (wd_child.fullscreen) {
[wd_child.window_object toggleFullScreen:nil];
}
diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp
index 5860a4f0ae..5e71d10a3f 100644
--- a/platform/macos/export/export_plugin.cpp
+++ b/platform/macos/export/export_plugin.cpp
@@ -1834,8 +1834,8 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor
if (p_preset->get("notarization/apple_id_name") != "") {
if (p_preset->get("notarization/apple_id_password") == "") {
err += TTR("Notarization: Apple ID password not specified.") + "\n";
+ valid = false;
}
- valid = false;
}
if (p_preset->get("notarization/api_uuid") != "") {
if (p_preset->get("notarization/api_key") == "") {
diff --git a/platform/web/js/engine/features.js b/platform/web/js/engine/features.js
index f91a4eff81..b7c6c9d445 100644
--- a/platform/web/js/engine/features.js
+++ b/platform/web/js/engine/features.js
@@ -76,19 +76,19 @@ const Features = { // eslint-disable-line no-unused-vars
getMissingFeatures: function () {
const missing = [];
if (!Features.isWebGLAvailable(2)) {
- missing.push('WebGL2');
+ missing.push('WebGL2 - Check web browser configuration and hardware support');
}
if (!Features.isFetchAvailable()) {
- missing.push('Fetch');
+ missing.push('Fetch - Check web browser version');
}
if (!Features.isSecureContext()) {
- missing.push('Secure Context');
+ missing.push('Secure Context - Check web server configuration (use HTTPS)');
}
if (!Features.isCrossOriginIsolated()) {
- missing.push('Cross Origin Isolation');
+ missing.push('Cross Origin Isolation - Check web server configuration (send correct headers)');
}
if (!Features.isSharedArrayBufferAvailable()) {
- missing.push('SharedArrayBuffer');
+ missing.push('SharedArrayBuffer - Check web server configuration (send correct headers)');
}
// Audio is normally optional since we have a dummy fallback.
return missing;
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index b501ee78db..7ba66750cf 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -157,7 +157,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
return EXCEPTION_CONTINUE_SEARCH;
}
- SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
+ SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_EXACT_SYMBOLS);
EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded);
module_handles.resize(cbNeeded / sizeof(HMODULE));
EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded);
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 0b878feb7f..29482213d8 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -3919,6 +3919,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution));
ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window.");
+ joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd);
+
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, main_window);
@@ -3958,8 +3960,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
_update_real_mouse_position(MAIN_WINDOW_ID);
- joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd);
-
r_error = OK;
static_cast<OS_Windows *>(OS::get_singleton())->set_main_window(windows[MAIN_WINDOW_ID].hWnd);
diff --git a/platform/windows/godot.ico b/platform/windows/godot.ico
index 25830ffdc6..f0bb68225d 100644
--- a/platform/windows/godot.ico
+++ b/platform/windows/godot.ico
Binary files differ
diff --git a/platform/windows/godot_console.ico b/platform/windows/godot_console.ico
new file mode 100644
index 0000000000..1d27e3d6ae
--- /dev/null
+++ b/platform/windows/godot_console.ico
Binary files differ
diff --git a/platform/windows/godot_res_wrap.rc b/platform/windows/godot_res_wrap.rc
index 9877ff6075..9dd29afe51 100644
--- a/platform/windows/godot_res_wrap.rc
+++ b/platform/windows/godot_res_wrap.rc
@@ -4,7 +4,7 @@
#define _MKSTR(m_x) _STR(m_x)
#endif
-GODOT_ICON ICON platform/windows/godot.ico
+GODOT_ICON ICON platform/windows/godot_console.ico
1 VERSIONINFO
FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,0