From 6d86a63648c65c9e5e72747130ee3cb0ed49ab4c Mon Sep 17 00:00:00 2001 From: eska Date: Fri, 18 Nov 2016 18:52:44 +0100 Subject: [PATCH] OS additions and fixes for WebAssembly/asm.js - Implement alert, shell_open, set_window_title - Add locale lookup, fixes #2477 - Print without color control sequences - Move get_executable_path implementation to OS_JavaScript --- drivers/unix/os_unix.cpp | 3 - platform/javascript/javascript_main.cpp | 2 +- platform/javascript/os_javascript.cpp | 84 ++++++++++++------------- platform/javascript/os_javascript.h | 17 +++-- 4 files changed, 49 insertions(+), 57 deletions(-) diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index fd515d6dd3..72582837ec 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -522,9 +522,6 @@ String OS_Unix::get_executable_path() const { delete[] resolved_path; return path; -#elif defined(EMSCRIPTEN) - // We return nothing - return String(); #else ERR_PRINT("Warning, don't know how to obtain executable path on this OS! Please override this function properly."); return OS::get_executable_path(); diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index d9342cfe10..af12384bc9 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -148,7 +148,7 @@ int main(int argc, char *argv[]) { /* Initialize the window */ printf("let it go!\n"); glutInit(&argc, argv); - os = new OS_JavaScript(_gfx_init,NULL,NULL,NULL,NULL); + os = new OS_JavaScript(_gfx_init,NULL,NULL); #if 0 char *args[]={"-test","gui","-v",NULL}; Error err = Main::setup("apk",3,args); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 1defcb7cb2..37ae7bf276 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -37,6 +37,7 @@ #include "main/main.h" #include "core/globals.h" +#include "stdlib.h" #include "emscripten.h" #include "dom_keys.h" @@ -89,7 +90,9 @@ static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_eve ev.key.scancode = dom2godot_scancode(emscripten_event->keyCode); String unicode = String::utf8(emscripten_event->key); + // check if empty or multi-character (e.g. `CapsLock`) if (unicode.length()!=1) { + // might be empty as well, but better than nonsense unicode = String::utf8(emscripten_event->charValue); } if (unicode.length()==1) { @@ -153,6 +156,25 @@ void OS_JavaScript::initialize(const VideoMode& p_desired,int p_video_driver,int default_videomode=p_desired; + // find locale, emscripten only sets "C" + char locale_ptr[16]; + EM_ASM_({ + var locale = ""; + if (Module.locale) { + // best case: server-side script reads Accept-Language early and + // defines the locale to be read here + locale = Module.locale; + } else { + // no luck, use what the JS engine can tell us + // if this turns out not compatible enough, add tests for + // browserLanguage, systemLanguage and userLanguage + locale = navigator.languages ? navigator.languages[0] : navigator.language; + } + locale = locale.split('.')[0]; + stringToUTF8(locale, $0, 16); + }, locale_ptr); + setenv("LANG", locale_ptr, true); + print_line("Init Audio"); AudioDriverManagerSW::add_driver(&audio_driver_javascript); @@ -249,32 +271,11 @@ void OS_JavaScript::finalize() { memdelete(input); } +void OS_JavaScript::alert(const String& p_alert,const String& p_title) { -void OS_JavaScript::vprint(const char* p_format, va_list p_list, bool p_stderr) { - - if (p_stderr) { - - vfprintf(stderr,p_format,p_list); - fflush(stderr); - } else { - - vprintf(p_format,p_list); - fflush(stdout); - } -} - -void OS_JavaScript::print(const char *p_format, ... ) { - - va_list argp; - va_start(argp, p_format); - vprintf(p_format, argp ); - va_end(argp); - -} - -void OS_JavaScript::alert(const String& p_alert) { - - print("ALERT: %s\n",p_alert.utf8().get_data()); + EM_ASM_({ + window.alert(UTF8ToString($0)); + }, p_alert.utf8().get_data()); } @@ -301,9 +302,12 @@ int OS_JavaScript::get_mouse_button_state() const { return 0; } + void OS_JavaScript::set_window_title(const String& p_title) { - + EM_ASM_({ + document.title = UTF8ToString($0); + }, p_title.utf8().get_data()); } //interesting byt not yet @@ -659,25 +663,17 @@ void OS_JavaScript::reload_gfx() { } Error OS_JavaScript::shell_open(String p_uri) { - - if (open_uri_func) - return open_uri_func(p_uri)?ERR_CANT_OPEN:OK; - return ERR_UNAVAILABLE; -}; + EM_ASM_({ + window.open(UTF8ToString($0), '_blank'); + }, p_uri.utf8().get_data()); + return OK; +} String OS_JavaScript::get_resource_dir() const { return "/"; //javascript has it's own filesystem for resources inside the APK } -String OS_JavaScript::get_locale() const { - - if (get_locale_func) - return get_locale_func(); - return OS_Unix::get_locale(); -} - - String OS_JavaScript::get_data_dir() const { //if (get_data_dir_func) @@ -686,6 +682,10 @@ String OS_JavaScript::get_data_dir() const { //return Globals::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir"); }; +String OS_JavaScript::get_executable_path() const { + + return String(); +} void OS_JavaScript::_close_notification_funcs(const String& p_file,int p_flags) { @@ -752,9 +752,7 @@ String OS_JavaScript::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } -OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func) { - - +OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, GetDataDirFunc p_get_data_dir_func) { default_videomode.width=800; default_videomode.height=600; default_videomode.fullscreen=true; @@ -767,9 +765,7 @@ OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, Ope gl_extensions=NULL; rasterizer=NULL; - open_uri_func=p_open_uri_func; get_data_dir_func=p_get_data_dir_func; - get_locale_func=p_get_locale_func; FileAccessUnix::close_notification_func=_close_notification_funcs; time_to_save_sync=-1; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 16e4781d15..0f52d671d9 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -44,9 +44,7 @@ #include "emscripten/html5.h" typedef void (*GFXInitFunc)(void *ud,bool gl2,int w, int h, bool fs); -typedef int (*OpenURIFunc)(const String&); typedef String (*GetDataDirFunc)(); -typedef String (*GetLocaleFunc)(); class OS_JavaScript : public OS_Unix { public: @@ -84,9 +82,7 @@ private: VideoMode default_videomode; MainLoop * main_loop; - OpenURIFunc open_uri_func; GetDataDirFunc get_data_dir_func; - GetLocaleFunc get_locale_func; static void _close_notification_funcs(const String& p_file,int p_flags); @@ -116,9 +112,12 @@ public: //static OS* get_singleton(); - virtual void vprint(const char* p_format, va_list p_list, bool p_stderr=false); - virtual void print(const char *p_format, ... ); - virtual void alert(const String& p_alert); + virtual void print_error(const char* p_function, const char* p_file, int p_line, const char *p_code, const char* p_rationale, ErrorType p_type) { + + OS::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type); + } + + virtual void alert(const String& p_alert,const String& p_title="ALERT!"); virtual void set_mouse_show(bool p_show); @@ -159,8 +158,8 @@ public: virtual Error shell_open(String p_uri); virtual String get_data_dir() const; + String get_executable_path() const; virtual String get_resource_dir() const; - virtual String get_locale() const; void process_accelerometer(const Vector3& p_accelerometer); void process_touch(int p_what,int p_pointer, const Vector& p_points); @@ -170,7 +169,7 @@ public: virtual String get_joy_guid(int p_device) const; bool joy_connection_changed(int p_type, const EmscriptenGamepadEvent *p_event); - OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func); + OS_JavaScript(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, GetDataDirFunc p_get_data_dir_func); ~OS_JavaScript(); };