summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/java_glue.cpp27
-rw-r--r--platform/iphone/SCsub7
-rw-r--r--platform/iphone/power_iphone.cpp2
-rw-r--r--platform/javascript/SCsub49
-rw-r--r--platform/javascript/detect.py122
-rw-r--r--platform/javascript/engine.js40
-rw-r--r--platform/javascript/http_client_javascript.cpp2
-rw-r--r--platform/javascript/javascript_main.cpp2
-rw-r--r--platform/javascript/os_javascript.cpp19
-rw-r--r--platform/javascript/os_javascript.h3
-rw-r--r--platform/javascript/power_javascript.cpp73
-rw-r--r--platform/javascript/power_javascript.h53
-rw-r--r--platform/javascript/pre.js2
-rw-r--r--platform/osx/detect.py1
-rw-r--r--platform/osx/godot_main_osx.mm2
-rw-r--r--platform/osx/os_osx.mm113
-rw-r--r--platform/uwp/detect.py2
-rw-r--r--platform/windows/os_windows.cpp13
-rw-r--r--platform/x11/os_x11.cpp10
19 files changed, 293 insertions, 249 deletions
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 9baf58c3eb..579c06f76b 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -936,6 +936,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) {
+ if (step == 0)
+ return;
+
os_android->main_loop_request_go_back();
}
@@ -976,6 +979,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions) {
+ if (step == 0)
+ return;
+
Vector<OS_Android::TouchPos> points;
for (int i = 0; i < count; i++) {
@@ -1250,6 +1256,8 @@ static unsigned int android_get_keysym(unsigned int p_code) {
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jobject obj, jint p_device, jint p_button, jboolean p_pressed) {
+ if (step == 0)
+ return;
OS_Android::JoypadEvent jevent;
jevent.device = p_device;
@@ -1261,6 +1269,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value) {
+ if (step == 0)
+ return;
OS_Android::JoypadEvent jevent;
jevent.device = p_device;
@@ -1272,6 +1282,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env,
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) {
+ if (step == 0)
+ return;
+
OS_Android::JoypadEvent jevent;
jevent.device = p_device;
jevent.type = OS_Android::JOY_EVENT_HAT;
@@ -1301,6 +1314,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) {
+ if (step == 0)
+ return;
Ref<InputEventKey> ievent;
ievent.instance();
@@ -1344,14 +1359,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jobject obj) {
- if (os_android && step > 0)
- os_android->main_loop_focusin();
+ if (step == 0)
+ return;
+
+ os_android->main_loop_focusin();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jobject obj) {
- if (os_android && step > 0)
- os_android->main_loop_focusout();
+ if (step == 0)
+ return;
+
+ os_android->main_loop_focusout();
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jobject obj) {
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index 6b5f30dc41..b96bec16b4 100644
--- a/platform/iphone/SCsub
+++ b/platform/iphone/SCsub
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+import os
Import('env')
@@ -21,6 +22,10 @@ ios_lib = env_ios.add_library('iphone', iphone_lib)
def combine_libs(target=None, source=None, env=None):
lib_path = target[0].srcnode().abspath
- env.Execute('$IPHONEPATH/usr/bin/libtool -static -o "' + lib_path + '" ' + ' '.join([('"' + lib.srcnode().abspath + '"') for lib in source]))
+ if ("OSXCROSS_IOS" in os.environ):
+ libtool = '$IPHONEPATH/usr/bin/${ios_triple}libtool'
+ else:
+ libtool = "$IPHONEPATH/usr/bin/libtool"
+ env.Execute(libtool + ' -static -o "' + lib_path + '" ' + ' '.join([('"' + lib.srcnode().abspath + '"') for lib in source]))
combine_command = env_ios.Command('#bin/libgodot' + env_ios['LIBSUFFIX'], [ios_lib] + env_ios['LIBS'], combine_libs)
diff --git a/platform/iphone/power_iphone.cpp b/platform/iphone/power_iphone.cpp
index 95a9aa9705..7f9dadc363 100644
--- a/platform/iphone/power_iphone.cpp
+++ b/platform/iphone/power_iphone.cpp
@@ -30,7 +30,7 @@
#include "power_iphone.h"
-bool OS::PowerState::UpdatePowerInfo() {
+bool PowerIphone::UpdatePowerInfo() {
return false;
}
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 66a8a8d93c..5991075e29 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -3,38 +3,35 @@
Import('env')
javascript_files = [
- "os_javascript.cpp",
- "audio_driver_javascript.cpp",
- "javascript_main.cpp",
- "power_javascript.cpp",
- "http_client_javascript.cpp",
- "javascript_eval.cpp",
+ 'audio_driver_javascript.cpp',
+ 'http_client_javascript.cpp',
+ 'javascript_eval.cpp',
+ 'javascript_main.cpp',
+ 'os_javascript.cpp',
]
-env_javascript = env.Clone()
-if env['target'] == "profile":
- env_javascript.Append(CPPFLAGS=['-DPROFILER_ENABLED'])
-
-javascript_objects = []
-for x in javascript_files:
- javascript_objects.append(env_javascript.Object(x))
-
-env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_main_after_fs_sync','_send_notification']\""])
-
-target_dir = env.Dir("#bin")
-build = env.add_program(['#bin/godot', target_dir.File('godot' + env['PROGSUFFIX'] + '.wasm')], javascript_objects, PROGSUFFIX=env['PROGSUFFIX'] + '.js');
+build = env.add_program(['#bin/godot${PROGSUFFIX}.js', '#bin/godot${PROGSUFFIX}.wasm'], javascript_files);
js, wasm = build
-js_libraries = []
-js_libraries.append(env.File('http_request.js'))
+js_libraries = [
+ 'http_request.js',
+]
for lib in js_libraries:
- env.Append(LINKFLAGS=['--js-library', lib.path])
+ env.Append(LINKFLAGS=['--js-library', env.File(lib).path])
env.Depends(build, js_libraries)
wrapper_start = env.File('pre.js')
wrapper_end = env.File('engine.js')
-js_final = env.Textfile('#bin/godot', [wrapper_start, js, wrapper_end], TEXTFILESUFFIX=env['PROGSUFFIX'] + '.wrapped.js')
-
-zip_dir = target_dir.Dir('.javascript_zip')
-zip_files = env.InstallAs([zip_dir.File('godot.js'), zip_dir.File('godot.wasm'), zip_dir.File('godot.html')], [js_final, wasm, '#misc/dist/html/default.html'])
-Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX'] + env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET")
+js_wrapped = env.Textfile('#bin/godot', [wrapper_start, js, wrapper_end], TEXTFILESUFFIX='${PROGSUFFIX}.wrapped.js')
+
+zip_dir = env.Dir('#bin/.javascript_zip')
+zip_files = env.InstallAs([
+ zip_dir.File('godot.js'),
+ zip_dir.File('godot.wasm'),
+ zip_dir.File('godot.html')
+], [
+ js_wrapped,
+ wasm,
+ '#misc/dist/html/default.html'
+])
+env.Zip('#bin/godot', zip_files, ZIPROOT=zip_dir, ZIPSUFFIX='${PROGSUFFIX}${ZIPSUFFIX}', ZIPCOMSTR='Archving $SOURCES as $TARGET')
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index ad6b710382..a48cb872ee 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -8,23 +8,22 @@ def is_active():
def get_name():
- return "JavaScript"
+ return 'JavaScript'
def can_build():
-
- return ("EMSCRIPTEN_ROOT" in os.environ or "EMSCRIPTEN" in os.environ)
+ return 'EM_CONFIG' in os.environ or os.path.exists(os.path.expanduser('~/.emscripten'))
def get_opts():
from SCons.Variables import BoolVariable
return [
+ # eval() can be a security concern, so it can be disabled.
BoolVariable('javascript_eval', 'Enable JavaScript eval interface', True),
]
def get_flags():
-
return [
('tools', False),
('module_theora_enabled', False),
@@ -36,24 +35,11 @@ def get_flags():
]
-def create(env):
-
- # remove Windows' .exe suffix
- return env.Clone(tools=['textfile', 'zip'], PROGSUFFIX='')
-
-
-def escape_sources_backslashes(target, source, env, for_signature):
- return [path.replace('\\','\\\\') for path in env.GetBuildPath(source)]
-
-def escape_target_backslashes(target, source, env, for_signature):
- return env.GetBuildPath(target[0]).replace('\\','\\\\')
-
-
def configure(env):
## Build type
- if (env["target"] == "release"):
+ if env['target'] == 'release' or env['target'] == 'profile':
# Use -Os to prioritize optimizing for reduced file size. This is
# particularly valuable for the web platform because it directly
# decreases download time.
@@ -62,66 +48,102 @@ def configure(env):
# run-time performance.
env.Append(CCFLAGS=['-Os'])
env.Append(LINKFLAGS=['-Os'])
+ if env['target'] == 'profile':
+ env.Append(LINKFLAGS=['--profiling-funcs'])
- elif (env["target"] == "release_debug"):
- env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
+ elif env['target'] == 'release_debug':
+ env.Append(CPPDEFINES=['DEBUG_ENABLED'])
+ env.Append(CCFLAGS=['-O2'])
env.Append(LINKFLAGS=['-O2'])
- # retain function names at the cost of file size, for backtraces and profiling
+ # Retain function names for backtraces at the cost of file size.
env.Append(LINKFLAGS=['--profiling-funcs'])
- elif (env["target"] == "debug"):
- env.Append(CCFLAGS=['-O1', '-D_DEBUG', '-g', '-DDEBUG_ENABLED'])
+ elif env['target'] == 'debug':
+ env.Append(CPPDEFINES=['DEBUG_ENABLED'])
+ env.Append(CCFLAGS=['-O1', '-g'])
env.Append(LINKFLAGS=['-O1', '-g'])
env.Append(LINKFLAGS=['-s', 'ASSERTIONS=1'])
## Compiler configuration
env['ENV'] = os.environ
- if ("EMSCRIPTEN_ROOT" in os.environ):
- env.PrependENVPath('PATH', os.environ['EMSCRIPTEN_ROOT'])
- elif ("EMSCRIPTEN" in os.environ):
- env.PrependENVPath('PATH', os.environ['EMSCRIPTEN'])
- env['CC'] = 'emcc'
- env['CXX'] = 'em++'
- env['LINK'] = 'emcc'
- env['RANLIB'] = 'emranlib'
- # Emscripten's ar has issues with duplicate file names, so use cc
- env['AR'] = 'emcc'
- env['ARFLAGS'] = '-o'
-
- if (os.name == 'nt'):
- # use TempFileMunge on Windows since some commands get too long for
- # cmd.exe even with spawn_fix
- # need to escape backslashes for this
- env['ESCAPED_SOURCES'] = escape_sources_backslashes
- env['ESCAPED_TARGET'] = escape_target_backslashes
- env['ARCOM'] = '${TEMPFILE("%s")}' % env['ARCOM'].replace('$SOURCES', '$ESCAPED_SOURCES').replace('$TARGET', '$ESCAPED_TARGET')
+ em_config_file = os.getenv('EM_CONFIG') or os.path.expanduser('~/.emscripten')
+ if not os.path.exists(em_config_file):
+ raise RuntimeError("Emscripten configuration file '%s' does not exist" % em_config_file)
+ with open(em_config_file) as f:
+ em_config = {}
+ try:
+ # Emscripten configuration file is a Python file with simple assignments.
+ exec(f.read(), em_config)
+ except StandardError as e:
+ raise RuntimeError("Emscripten configuration file '%s' is invalid:\n%s" % (em_config_file, e))
+ if 'EMSCRIPTEN_ROOT' not in em_config:
+ raise RuntimeError("'EMSCRIPTEN_ROOT' missing in Emscripten configuration file '%s'" % em_config_file)
+ env.PrependENVPath('PATH', em_config['EMSCRIPTEN_ROOT'])
+
+ env['CC'] = 'emcc'
+ env['CXX'] = 'em++'
+ env['LINK'] = 'emcc'
+
+ # Emscripten's ar has issues with duplicate file names, so use cc.
+ env['AR'] = 'emcc'
+ env['ARFLAGS'] = '-o'
+ # emranlib is a noop, so it's safe to use with AR=emcc.
+ env['RANLIB'] = 'emranlib'
+
+ # Use TempFileMunge since some AR invocations are too long for cmd.exe.
+ # Use POSIX-style paths, required with TempFileMunge.
+ env['ARCOM_POSIX'] = env['ARCOM'].replace(
+ '$TARGET', '$TARGET.posix').replace(
+ '$SOURCES', '$SOURCES.posix')
+ env['ARCOM'] = '${TEMPFILE(ARCOM_POSIX)}'
+
+ # All intermediate files are just LLVM bitcode.
+ env['OBJPREFIX'] = ''
env['OBJSUFFIX'] = '.bc'
+ env['PROGPREFIX'] = ''
+ # Program() output consists of multiple files, so specify suffixes manually at builder.
+ env['PROGSUFFIX'] = ''
+ env['LIBPREFIX'] = 'lib'
env['LIBSUFFIX'] = '.bc'
+ env['LIBPREFIXES'] = ['$LIBPREFIX']
+ env['LIBSUFFIXES'] = ['$LIBSUFFIX']
## Compile flags
env.Append(CPPPATH=['#platform/javascript'])
- env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DTYPED_METHOD_BIND', '-DNO_THREADS'])
- env.Append(CPPFLAGS=['-DGLES3_ENABLED'])
+ env.Append(CPPDEFINES=['JAVASCRIPT_ENABLED', 'UNIX_ENABLED'])
+
+ # No multi-threading (SharedArrayBuffer) available yet,
+ # once feasible also consider memory buffer size issues.
+ env.Append(CPPDEFINES=['NO_THREADS'])
- # These flags help keep the file size down
- env.Append(CPPFLAGS=["-fno-exceptions", '-DNO_SAFE_CAST', '-fno-rtti'])
+ # These flags help keep the file size down.
+ env.Append(CCFLAGS=['-fno-exceptions', '-fno-rtti'])
+ # Don't use dynamic_cast, necessary with no-rtti.
+ env.Append(CPPDEFINES=['NO_SAFE_CAST'])
if env['javascript_eval']:
- env.Append(CPPFLAGS=['-DJAVASCRIPT_EVAL_ENABLED'])
+ env.Append(CPPDEFINES=['JAVASCRIPT_EVAL_ENABLED'])
## Link flags
env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
+
+ # Allow increasing memory buffer size during runtime. This is efficient
+ # when using WebAssembly (in comparison to asm.js) and works well for
+ # us since we don't know requirements at compile-time.
env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1'])
+
+ # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1.
env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1'])
- env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="[\'FS\']"'])
env.Append(LINKFLAGS=['-s', 'INVOKE_RUN=0'])
+
+ # TODO: Reevaluate usage of this setting now that engine.js manages engine runtime.
env.Append(LINKFLAGS=['-s', 'NO_EXIT_RUNTIME=1'])
- # TODO: Move that to opus module's config
+ # TODO: Move that to opus module's config.
if 'module_opus_enabled' in env and env['module_opus_enabled']:
- env.opus_fixed_point = "yes"
+ env.opus_fixed_point = 'yes'
diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js
index e6fb48d0d2..e4839af433 100644
--- a/platform/javascript/engine.js
+++ b/platform/javascript/engine.js
@@ -1,3 +1,5 @@
+ exposedLibs['PATH'] = PATH;
+ exposedLibs['FS'] = FS;
return Module;
},
};
@@ -12,6 +14,13 @@
var loadingFiles = {};
+ function getPathLeaf(path) {
+
+ while (path.endsWith('/'))
+ path = path.slice(0, -1);
+ return path.slice(path.lastIndexOf('/') + 1);
+ }
+
function getBasePath(path) {
if (path.endsWith('/'))
@@ -23,14 +32,15 @@
function getBaseName(path) {
- path = getBasePath(path);
- return path.slice(path.lastIndexOf('/') + 1);
+ return getPathLeaf(getBasePath(path));
}
Engine = function Engine() {
this.rtenv = null;
+ var LIBS = {};
+
var initPromise = null;
var unloadAfterInit = true;
@@ -80,11 +90,11 @@
return new Promise(function(resolve, reject) {
rtenvProps.onRuntimeInitialized = resolve;
rtenvProps.onAbort = reject;
- rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps);
+ rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps, LIBS);
});
}
- this.preloadFile = function(pathOrBuffer, bufferFilename) {
+ this.preloadFile = function(pathOrBuffer, destPath) {
if (pathOrBuffer instanceof ArrayBuffer) {
pathOrBuffer = new Uint8Array(pathOrBuffer);
@@ -93,14 +103,14 @@
}
if (pathOrBuffer instanceof Uint8Array) {
preloadedFiles.push({
- name: bufferFilename,
+ path: destPath,
buffer: pathOrBuffer
});
return Promise.resolve();
} else if (typeof pathOrBuffer === 'string') {
return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) {
preloadedFiles.push({
- name: pathOrBuffer,
+ path: destPath || pathOrBuffer,
buffer: xhr.response
});
});
@@ -119,7 +129,12 @@
this.startGame = function(mainPack) {
executableName = getBaseName(mainPack);
- return Promise.all([this.init(getBasePath(mainPack)), this.preloadFile(mainPack)]).then(
+ return Promise.all([
+ // Load from directory,
+ this.init(getBasePath(mainPack)),
+ // ...but write to root where the engine expects it.
+ this.preloadFile(mainPack, getPathLeaf(mainPack))
+ ]).then(
Function.prototype.apply.bind(synchronousStart, this, [])
);
};
@@ -163,7 +178,16 @@
this.rtenv.thisProgram = executableName || getBaseName(basePath);
preloadedFiles.forEach(function(file) {
- this.rtenv.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true);
+ var dir = LIBS.PATH.dirname(file.path);
+ try {
+ LIBS.FS.stat(dir);
+ } catch (e) {
+ if (e.code !== 'ENOENT') {
+ throw e;
+ }
+ LIBS.FS.mkdirTree(dir);
+ }
+ LIBS.FS.createDataFile('/', file.path, new Uint8Array(file.buffer), true, true, true);
}, this);
preloadedFiles = null;
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index 118a77835e..8d90e01ae1 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -88,7 +88,7 @@ Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Ve
ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
- String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + "/" + p_url;
+ String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + p_url;
godot_xhr_reset(xhr_id);
godot_xhr_open(xhr_id, _methods[p_method], url.utf8().get_data(),
username.empty() ? NULL : username.utf8().get_data(),
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index e85fe0800f..54d4755bd7 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -40,7 +40,7 @@ static void main_loop() {
os->main_loop_iterate();
}
-extern "C" void main_after_fs_sync(char *p_idbfs_err) {
+extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
String idbfs_err = String::utf8(p_idbfs_err);
if (!idbfs_err.empty()) {
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index cbfe99ba2d..a275fb7929 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -413,14 +413,13 @@ static EM_BOOL joy_callback_func(int p_type, const EmscriptenGamepadEvent *p_eve
return false;
}
-extern "C" {
-void send_notification(int notif) {
+extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int notif) {
+
if (notif == MainLoop::NOTIFICATION_WM_MOUSE_ENTER || notif == MainLoop::NOTIFICATION_WM_MOUSE_EXIT) {
_cursor_inside_canvas = notif == MainLoop::NOTIFICATION_WM_MOUSE_ENTER;
}
OS_JavaScript::get_singleton()->get_main_loop()->notification(notif);
}
-}
Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
@@ -480,8 +479,6 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
input = memnew(InputDefault);
_input = input;
- power_manager = memnew(PowerJavascript);
-
#define EM_CHECK(ev) \
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result))
@@ -968,15 +965,21 @@ String OS_JavaScript::get_joy_guid(int p_device) const {
}
OS::PowerState OS_JavaScript::get_power_state() {
- return power_manager->get_power_state();
+
+ WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to POWERSTATE_UNKNOWN");
+ return OS::POWERSTATE_UNKNOWN;
}
int OS_JavaScript::get_power_seconds_left() {
- return power_manager->get_power_seconds_left();
+
+ WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1");
+ return -1;
}
int OS_JavaScript::get_power_percent_left() {
- return power_manager->get_power_percent_left();
+
+ WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1");
+ return -1;
}
bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index f0ba9422e8..46eb1b3f13 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -36,7 +36,6 @@
#include "main/input_default.h"
#include "os/input.h"
#include "os/main_loop.h"
-#include "power_javascript.h"
#include "servers/audio_server.h"
#include "servers/visual/rasterizer.h"
@@ -64,8 +63,6 @@ class OS_JavaScript : public OS_Unix {
GetUserDataDirFunc get_user_data_dir_func;
- PowerJavascript *power_manager;
-
static void _close_notification_funcs(const String &p_file, int p_flags);
void process_joypads();
diff --git a/platform/javascript/power_javascript.cpp b/platform/javascript/power_javascript.cpp
deleted file mode 100644
index 5241644dbc..0000000000
--- a/platform/javascript/power_javascript.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*************************************************************************/
-/* power_javascript.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "power_javascript.h"
-#include "error_macros.h"
-
-bool PowerJavascript::UpdatePowerInfo() {
- // TODO Javascript implementation
- return false;
-}
-
-OS::PowerState PowerJavascript::get_power_state() {
- if (UpdatePowerInfo()) {
- return power_state;
- } else {
- WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN");
- return OS::POWERSTATE_UNKNOWN;
- }
-}
-
-int PowerJavascript::get_power_seconds_left() {
- if (UpdatePowerInfo()) {
- return nsecs_left;
- } else {
- WARN_PRINT("Power management is not implemented on this platform, defaulting to -1");
- return -1;
- }
-}
-
-int PowerJavascript::get_power_percent_left() {
- if (UpdatePowerInfo()) {
- return percent_left;
- } else {
- WARN_PRINT("Power management is not implemented on this platform, defaulting to -1");
- return -1;
- }
-}
-
-PowerJavascript::PowerJavascript() :
- nsecs_left(-1),
- percent_left(-1),
- power_state(OS::POWERSTATE_UNKNOWN) {
-}
-
-PowerJavascript::~PowerJavascript() {
-}
diff --git a/platform/javascript/power_javascript.h b/platform/javascript/power_javascript.h
deleted file mode 100644
index c0c564aa60..0000000000
--- a/platform/javascript/power_javascript.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*************************************************************************/
-/* power_javascript.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef PLATFORM_JAVASCRIPT_POWER_JAVASCRIPT_H_
-#define PLATFORM_JAVASCRIPT_POWER_JAVASCRIPT_H_
-
-#include "os/os.h"
-
-class PowerJavascript {
-private:
- int nsecs_left;
- int percent_left;
- OS::PowerState power_state;
-
- bool UpdatePowerInfo();
-
-public:
- PowerJavascript();
- virtual ~PowerJavascript();
-
- OS::PowerState get_power_state();
- int get_power_seconds_left();
- int get_power_percent_left();
-};
-
-#endif /* PLATFORM_JAVASCRIPT_POWER_JAVASCRIPT_H_ */
diff --git a/platform/javascript/pre.js b/platform/javascript/pre.js
index 311aa44fda..02194bc75e 100644
--- a/platform/javascript/pre.js
+++ b/platform/javascript/pre.js
@@ -1,2 +1,2 @@
var Engine = {
- RuntimeEnvironment: function(Module) {
+ RuntimeEnvironment: function(Module, exposedLibs) {
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index e51a8082f7..1e9631fae0 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -93,6 +93,7 @@ def configure(env):
env['AR'] = basecmd + "ar"
env['RANLIB'] = basecmd + "ranlib"
env['AS'] = basecmd + "as"
+ env.Append(CCFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define
if (env["CXX"] == "clang++"):
env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm
index 6ccbaf896b..64116fa1e0 100644
--- a/platform/osx/godot_main_osx.mm
+++ b/platform/osx/godot_main_osx.mm
@@ -101,5 +101,5 @@ int main(int argc, char **argv) {
Main::cleanup();
- return 0;
+ return os.get_exit_code();
};
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index ef23d61141..0c5524dd08 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -192,6 +192,7 @@ static Vector2 get_mouse_pos(NSEvent *event) {
// Note: called before main loop init!
char *utfs = strdup([filename UTF8String]);
OS_OSX::singleton->open_with_filename.parse_utf8(utfs);
+ free(utfs);
return YES;
}
@@ -838,6 +839,108 @@ static int translateKey(unsigned int key) {
return table[key];
}
+struct _KeyCodeMap {
+ UniChar kchar;
+ int kcode;
+};
+
+static const _KeyCodeMap _keycodes[55] = {
+ { '`', KEY_QUOTELEFT },
+ { '~', KEY_ASCIITILDE },
+ { '0', KEY_KP_0 },
+ { '1', KEY_KP_1 },
+ { '2', KEY_KP_2 },
+ { '3', KEY_KP_3 },
+ { '4', KEY_KP_4 },
+ { '5', KEY_KP_5 },
+ { '6', KEY_KP_6 },
+ { '7', KEY_KP_7 },
+ { '8', KEY_KP_8 },
+ { '9', KEY_KP_9 },
+ { '-', KEY_MINUS },
+ { '_', KEY_UNDERSCORE },
+ { '=', KEY_EQUAL },
+ { '+', KEY_PLUS },
+ { 'q', KEY_Q },
+ { 'w', KEY_W },
+ { 'e', KEY_E },
+ { 'r', KEY_R },
+ { 't', KEY_T },
+ { 'y', KEY_Y },
+ { 'u', KEY_U },
+ { 'i', KEY_I },
+ { 'o', KEY_O },
+ { 'p', KEY_P },
+ { '[', KEY_BRACERIGHT },
+ { ']', KEY_BRACELEFT },
+ { '{', KEY_BRACERIGHT },
+ { '}', KEY_BRACELEFT },
+ { 'a', KEY_A },
+ { 's', KEY_S },
+ { 'd', KEY_D },
+ { 'f', KEY_F },
+ { 'g', KEY_G },
+ { 'h', KEY_H },
+ { 'j', KEY_J },
+ { 'k', KEY_K },
+ { 'l', KEY_L },
+ { ';', KEY_SEMICOLON },
+ { ':', KEY_COLON },
+ { '\'', KEY_APOSTROPHE },
+ { '\"', KEY_QUOTEDBL },
+ { '\\', KEY_BACKSLASH },
+ { '#', KEY_NUMBERSIGN },
+ { 'z', KEY_Z },
+ { 'x', KEY_X },
+ { 'c', KEY_C },
+ { 'v', KEY_V },
+ { 'b', KEY_B },
+ { 'n', KEY_N },
+ { 'm', KEY_M },
+ { ',', KEY_COMMA },
+ { '.', KEY_PERIOD },
+ { '/', KEY_SLASH }
+};
+
+static int remapKey(unsigned int key) {
+
+ TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+ if (!currentKeyboard)
+ return translateKey(key);
+
+ CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
+ if (!layoutData)
+ return nil;
+
+ const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+
+ UInt32 keysDown = 0;
+ UniChar chars[4];
+ UniCharCount realLength;
+
+ OSStatus err = UCKeyTranslate(keyboardLayout,
+ key,
+ kUCKeyActionDisplay,
+ 0,
+ LMGetKbdType(),
+ kUCKeyTranslateNoDeadKeysBit,
+ &keysDown,
+ sizeof(chars) / sizeof(chars[0]),
+ &realLength,
+ chars);
+
+ if (err != noErr) {
+ return translateKey(key);
+ }
+
+ for (unsigned int i = 0; i < 55; i++) {
+ if (_keycodes[i].kchar == chars[0]) {
+ return _keycodes[i].kcode;
+ }
+ }
+ return translateKey(key);
+}
+
- (void)keyDown:(NSEvent *)event {
//disable raw input in IME mode
@@ -847,7 +950,7 @@ static int translateKey(unsigned int key) {
ke.osx_state = [event modifierFlags];
ke.pressed = true;
ke.echo = [event isARepeat];
- ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode]));
+ ke.scancode = remapKey([event keyCode]);
ke.unicode = 0;
push_to_key_event_buffer(ke);
@@ -900,7 +1003,7 @@ static int translateKey(unsigned int key) {
}
ke.osx_state = mod;
- ke.scancode = latin_keyboard_keycode_convert(translateKey(key));
+ ke.scancode = remapKey(key);
ke.unicode = 0;
push_to_key_event_buffer(ke);
@@ -916,7 +1019,7 @@ static int translateKey(unsigned int key) {
ke.osx_state = [event modifierFlags];
ke.pressed = false;
ke.echo = false;
- ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode]));
+ ke.scancode = remapKey([event keyCode]);
ke.unicode = 0;
push_to_key_event_buffer(ke);
@@ -1404,9 +1507,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
Ref<Texture> texture = p_cursor;
Ref<Image> image = texture->get_data();
- int image_size = 32 * 32;
-
- ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32);
+ ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256);
NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 3ee195e4f9..0e7b125dc5 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -43,6 +43,8 @@ def get_flags():
def configure(env):
+ env.msvc = True
+
if (env["bits"] != "default"):
print("Error: bits argument is disabled for MSVC")
print("""
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 13fe781ff3..f51d969c16 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -1896,26 +1896,25 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
Ref<Texture> texture = p_cursor;
Ref<Image> image = texture->get_data();
- UINT image_size = 32 * 32;
+ UINT image_size = texture->get_width() * texture->get_height();
UINT size = sizeof(UINT) * image_size;
- ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32);
+ ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256);
// Create the BITMAP with alpha channel
COLORREF *buffer = (COLORREF *)malloc(sizeof(COLORREF) * image_size);
image->lock();
for (UINT index = 0; index < image_size; index++) {
- int column_index = floor(index / 32);
- int row_index = index % 32;
+ int row_index = floor(index / texture->get_width());
+ int column_index = index % texture->get_width();
- Color pcColor = image->get_pixel(row_index, column_index);
- *(buffer + index) = image->get_pixel(row_index, column_index).to_argb32();
+ *(buffer + index) = image->get_pixel(column_index, row_index).to_argb32();
}
image->unlock();
// Using 4 channels, so 4 * 8 bits
- HBITMAP bitmap = CreateBitmap(32, 32, 1, 4 * 8, buffer);
+ HBITMAP bitmap = CreateBitmap(texture->get_width(), texture->get_height(), 1, 4 * 8, buffer);
COLORREF clrTransparent = -1;
// Create the AND and XOR masks for the bitmap
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index c06c7516d0..338d13410f 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -2375,11 +2375,11 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
Ref<Texture> texture = p_cursor;
Ref<Image> image = texture->get_data();
- ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32);
+ ERR_FAIL_COND(texture->get_width() > 256 || texture->get_height() > 256);
// Create the cursor structure
XcursorImage *cursor_image = XcursorImageCreate(texture->get_width(), texture->get_height());
- XcursorUInt image_size = 32 * 32;
+ XcursorUInt image_size = texture->get_width() * texture->get_height();
XcursorDim size = sizeof(XcursorPixel) * image_size;
cursor_image->version = 1;
@@ -2393,10 +2393,10 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
image->lock();
for (XcursorPixel index = 0; index < image_size; index++) {
- int column_index = floor(index / 32);
- int row_index = index % 32;
+ int row_index = floor(index / texture->get_width());
+ int column_index = index % texture->get_width();
- *(cursor_image->pixels + index) = image->get_pixel(row_index, column_index).to_argb32();
+ *(cursor_image->pixels + index) = image->get_pixel(column_index, row_index).to_argb32();
}
image->unlock();