diff --git a/project/Build.xml b/project/Build.xml index 81d5aa52d..b7d9172be 100755 --- a/project/Build.xml +++ b/project/Build.xml @@ -458,6 +458,12 @@
+ + + diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index fc1fdf1b4..62d89441c 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -52,6 +52,7 @@ #include #include #endif +#include #include #include @@ -134,15 +135,82 @@ namespace lime { } + std::string wstring_utf8 (const std::wstring& val) { + + std::string out; + unsigned int codepoint = 0; + + for (const wchar_t chr : val) { + + if (chr >= 0xd800 && chr <= 0xdbff) { + + codepoint = ((chr - 0xd800) << 10) + 0x10000; + + } else { + + if (chr >= 0xdc00 && chr <= 0xdfff) { + + codepoint |= chr - 0xdc00; + + } else { + + codepoint = chr; + + } + + if (codepoint <= 0x7f) { + + out.append (1, static_cast (codepoint)); + + } else if (codepoint <= 0x7ff) { + + out.append (1, static_cast (0xc0 | ((codepoint >> 6) & 0x1f))); + out.append (1, static_cast (0x80 | (codepoint & 0x3f))); + + } else if (codepoint <= 0xffff) { + + out.append (1, static_cast (0xe0 | ((codepoint >> 12) & 0x0f))); + out.append (1, static_cast (0x80 | ((codepoint >> 6) & 0x3f))); + out.append (1, static_cast (0x80 | (codepoint & 0x3f))); + + } else { + + out.append (1, static_cast (0xf0 | ((codepoint >> 18) & 0x07))); + out.append (1, static_cast (0x80 | ((codepoint >> 12) & 0x3f))); + out.append (1, static_cast (0x80 | ((codepoint >> 6) & 0x3f))); + out.append (1, static_cast (0x80 | (codepoint & 0x3f))); + + } + + codepoint = 0; + + } + + } + + return out; + + } + + + vbyte* hl_wstring_to_utf8_bytes (const std::wstring& val) { + + const std::string utf8 (wstring_utf8 (val)); + vbyte* const bytes = hl_alloc_bytes (utf8.size () + 1); + std::memcpy(bytes, utf8.c_str (), utf8.size () + 1); + return bytes; + + } + + std::wstring* hxstring_to_wstring (HxString val) { if (val.c_str ()) { - std::string _val = std::string (val.c_str ()); #ifdef HX_WINDOWS - std::wstring_convert> converter; - return new std::wstring (converter.from_bytes (_val)); + return new std::wstring (hxs_wchar (val, nullptr)); #else + const std::string _val (hxs_utf8 (val, nullptr)); return new std::wstring (_val.begin (), _val.end ()); #endif @@ -196,34 +264,6 @@ namespace lime { } - vbyte* wstring_to_vbytes (std::wstring* val) { - - if (val) { - - #ifdef HX_WINDOWS - int size = std::wcslen (val->c_str ()); - char* result = (char*)malloc (size + 1); - std::wcstombs (result, val->c_str (), size); - result[size] = '\0'; - return (vbyte*)result; - #else - std::string _val = std::string (val->begin (), val->end ()); - int size = std::strlen (_val.c_str ()); - char* result = (char*)malloc (size + 1); - std::strncpy (result, _val.c_str (), size); - result[size] = '\0'; - return (vbyte*)result; - #endif - - } else { - - return 0; - - } - - } - - value lime_application_create () { Application* application = CreateApplication (); @@ -522,7 +562,7 @@ namespace lime { value lime_bytes_read_file (HxString path, value bytes) { Bytes data (bytes); - data.ReadFile (path.c_str ()); + data.ReadFile (hxs_utf8 (path, nullptr)); return data.Value (bytes); } @@ -622,7 +662,7 @@ namespace lime { void lime_clipboard_set_text (HxString text) { - Clipboard::SetText (text.c_str ()); + Clipboard::SetText (hxs_utf8 (text, nullptr)); } @@ -769,9 +809,9 @@ namespace lime { if (path) { - vbyte* _path = wstring_to_vbytes (path); + vbyte* const result = hl_wstring_to_utf8_bytes (*path); delete path; - return _path; + return result; } else { @@ -835,9 +875,9 @@ namespace lime { if (path) { - vbyte* _path = wstring_to_vbytes (path); + vbyte* const result = hl_wstring_to_utf8_bytes (*path); delete path; - return _path; + return result; } else { @@ -906,8 +946,7 @@ namespace lime { for (int i = 0; i < files.size (); i++) { - vbyte* _file = wstring_to_vbytes (files[i]); - *resultData++ = _file; + *resultData++ = hl_wstring_to_utf8_bytes (*files[i]); delete files[i]; } @@ -970,9 +1009,9 @@ namespace lime { if (path) { - vbyte* _path = wstring_to_vbytes (path); + vbyte* const result = hl_wstring_to_utf8_bytes (*path); delete path; - return _path; + return result; } else { @@ -1143,12 +1182,11 @@ namespace lime { #ifdef LIME_FREETYPE Font *font = (Font*)fontHandle->ptr; wchar_t *name = font->GetFamilyName (); - int size = std::wcslen (name); - char* result = (char*)malloc (size + 1); - std::wcstombs (result, name, size); - result[size] = '\0'; + if (!name) + return nullptr; + vbyte* const result = hl_wstring_to_utf8_bytes (name); delete name; - return (vbyte*)result; + return result; #else return 0; #endif @@ -1160,7 +1198,7 @@ namespace lime { #ifdef LIME_FREETYPE Font *font = (Font*)val_data (fontHandle); - return font->GetGlyphIndex ((char*)character.c_str ()); + return font->GetGlyphIndex (hxs_utf8 (character, nullptr)); #else return -1; #endif @@ -1184,7 +1222,7 @@ namespace lime { #ifdef LIME_FREETYPE Font *font = (Font*)val_data (fontHandle); - return (value)font->GetGlyphIndices (true, (char*)characters.c_str ()); + return (value)font->GetGlyphIndices (true, hxs_utf8 (characters, nullptr)); #else return alloc_null (); #endif @@ -2347,7 +2385,7 @@ namespace lime { value lime_jpeg_decode_file (HxString path, bool decodeData, value buffer) { ImageBuffer imageBuffer (buffer); - Resource resource = Resource (path.c_str ()); + Resource resource = Resource (hxs_utf8 (path, nullptr)); #ifdef LIME_JPEG if (JPEG::Decode (&resource, &imageBuffer, decodeData)) { @@ -2585,7 +2623,7 @@ namespace lime { value lime_png_decode_file (HxString path, bool decodeData, value buffer) { ImageBuffer imageBuffer (buffer); - Resource resource = Resource (path.c_str ()); + Resource resource = Resource (hxs_utf8 (path, nullptr)); #ifdef LIME_PNG if (PNG::Decode (&resource, &imageBuffer, decodeData)) { @@ -2690,13 +2728,9 @@ namespace lime { if (model) { - int size = std::wcslen (model->c_str ()); - char* result = (char*)malloc (size + 1); - std::wcstombs (result, model->c_str (), size); - result[size] = '\0'; + vbyte* const result = hl_wstring_to_utf8_bytes (*model); delete model; - - return (vbyte*)result; + return result; } @@ -2734,13 +2768,9 @@ namespace lime { if (vendor) { - int size = std::wcslen (vendor->c_str ()); - char* result = (char*)malloc (size + 1); - std::wcstombs (result, vendor->c_str (), size); - result[size] = '\0'; + vbyte* const result = hl_wstring_to_utf8_bytes (*vendor); delete vendor; - - return (vbyte*)result; + return result; } @@ -2753,7 +2783,7 @@ namespace lime { value lime_system_get_directory (int type, HxString company, HxString title) { - std::wstring* path = System::GetDirectory ((SystemDirectory)type, company.c_str (), title.c_str ()); + std::wstring* path = System::GetDirectory ((SystemDirectory)type, hxs_utf8 (company, nullptr), hxs_utf8 (title, nullptr)); if (path) { @@ -2778,13 +2808,9 @@ namespace lime { if (path) { - int size = std::wcslen (path->c_str ()); - char* result = (char*)malloc (size + 1); - std::wcstombs (result, path->c_str (), size); - result[size] = '\0'; + vbyte* const result = hl_wstring_to_utf8_bytes (*path); delete path; - - return (vbyte*)result; + return result; } @@ -2872,13 +2898,9 @@ namespace lime { if (label) { - int size = std::wcslen (label->c_str ()); - char* result = (char*)malloc (size + 1); - std::wcstombs (result, label->c_str (), size); - result[size] = '\0'; + vbyte* const result = hl_wstring_to_utf8_bytes (*label); delete label; - - return (vbyte*)result; + return result; } @@ -2916,13 +2938,9 @@ namespace lime { if (name) { - int size = std::wcslen (name->c_str ()); - char* result = (char*)malloc (size + 1); - std::wcstombs (result, name->c_str (), size); - result[size] = '\0'; + vbyte* const result = hl_wstring_to_utf8_bytes (*name); delete name; - - return (vbyte*)result; + return result; } @@ -2960,14 +2978,9 @@ namespace lime { if (version) { - int size = std::wcslen (version->c_str ()); - char* result = (char*)malloc (size + 1); - std::wcstombs (result, version->c_str (), size); - result[size] = '\0'; + vbyte* const result = hl_wstring_to_utf8_bytes (*version); delete version; - - return (vbyte*)result; - + return result; } #endif @@ -3120,7 +3133,7 @@ namespace lime { void lime_window_alert (value window, HxString message, HxString title) { Window* targetWindow = (Window*)val_data (window); - targetWindow->Alert (message.c_str (), title.c_str ()); + targetWindow->Alert (hxs_utf8 (message, nullptr), hxs_utf8 (title, nullptr)); } @@ -3128,8 +3141,8 @@ namespace lime { HL_PRIM void HL_NAME(hl_window_alert) (HL_CFFIPointer* window, hl_vstring* message, hl_vstring* title) { Window* targetWindow = (Window*)window->ptr; - const char *cmessage = message ? hl_to_utf8(message->bytes) : NULL; - const char *ctitle = title ? hl_to_utf8(title->bytes) : NULL; + const char *cmessage = message ? hl_to_utf8(message->bytes) : nullptr; + const char *ctitle = title ? hl_to_utf8(title->bytes) : nullptr; targetWindow->Alert (cmessage, ctitle); } @@ -3209,7 +3222,7 @@ namespace lime { value lime_window_create (value application, int width, int height, int flags, HxString title) { - Window* window = CreateWindow ((Application*)val_data (application), width, height, flags, title.c_str ()); + Window* window = CreateWindow ((Application*)val_data (application), width, height, flags, hxs_utf8 (title, nullptr)); return CFFIPointer (window, gc_window); } @@ -3774,13 +3787,14 @@ namespace lime { value lime_window_set_title (value window, HxString title) { Window* targetWindow = (Window*)val_data (window); - const char* result = targetWindow->SetTitle (title.c_str ()); + const char* titleUtf8 = hxs_utf8 (title, nullptr); + const char* result = targetWindow->SetTitle (titleUtf8); if (result) { value _result = alloc_string (result); - if (result != title.c_str ()) { + if (result != titleUtf8) { free ((char*) result); diff --git a/src/lime/text/Font.hx b/src/lime/text/Font.hx index 52bde364f..19843c2e8 100644 --- a/src/lime/text/Font.hx +++ b/src/lime/text/Font.hx @@ -189,10 +189,11 @@ class Font public function getGlyphs(characters:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^`'\"/\\&*()[]{}<>|:;_-+=?,. "):Array { #if (lime_cffi && !macro) - var glyphs:Dynamic = NativeCFFI.lime_font_get_glyph_indices(src, characters); - // lime_font_get_glyph_indices returns Array - // cast it to Array instead (Glyph is an abstract) - return cast glyphs; + #if hl + return [for (index in NativeCFFI.lime_font_get_glyph_indices(src, characters)) new Glyph(index)]; + #else + return NativeCFFI.lime_font_get_glyph_indices(src, characters); + #end #else return null; #end diff --git a/src/lime/tools/HXProject.hx b/src/lime/tools/HXProject.hx index 357cea03e..26e90bdee 100644 --- a/src/lime/tools/HXProject.hx +++ b/src/lime/tools/HXProject.hx @@ -189,6 +189,10 @@ class HXProject extends Script else { environment = Sys.environment(); + for (conflict in ["air", "android", "cpp", "flash", "hl", "html5", "ios", "linux", "mac", "neko", "webassembly", "windows"]) + { + environment.remove(conflict); + } } haxedefs = new Map(); diff --git a/templates/android/template/app/src/main/java/org/haxe/lime/GameActivity.java b/templates/android/template/app/src/main/java/org/haxe/lime/GameActivity.java index e0c37f44c..3c28d7a6c 100644 --- a/templates/android/template/app/src/main/java/org/haxe/lime/GameActivity.java +++ b/templates/android/template/app/src/main/java/org/haxe/lime/GameActivity.java @@ -8,6 +8,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.VibrationEffect; import android.os.Vibrator; import android.util.DisplayMetrics; import android.util.Log; @@ -29,10 +30,10 @@ public class GameActivity extends SDLActivity { private static AssetManager assetManager; private static List extensions; private static DisplayMetrics metrics; + private static Vibrator vibrator; public Handler handler; - public static double getDisplayXDPI () { if (metrics == null) { @@ -109,6 +110,7 @@ public class GameActivity extends SDLActivity { super.onCreate (state); assetManager = getAssets (); + vibrator = (Vibrator)mSingleton.getSystemService (Context.VIBRATOR_SERVICE); handler = new Handler (); Extension.assetManager = assetManager; @@ -176,6 +178,12 @@ public class GameActivity extends SDLActivity { @Override protected void onPause () { + if (vibrator != null) { + + vibrator.cancel (); + + } + super.onPause (); for (Extension extension : extensions) { @@ -370,25 +378,47 @@ public class GameActivity extends SDLActivity { public static void vibrate (int period, int duration) { - Vibrator v = (Vibrator)mSingleton.getSystemService (Context.VIBRATOR_SERVICE); + if (vibrator == null || !vibrator.hasVibrator () || period < 0 || duration <= 0) { + + return; + + } if (period == 0) { - v.vibrate (duration); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + + vibrator.vibrate (VibrationEffect.createOneShot (duration, VibrationEffect.DEFAULT_AMPLITUDE)); + + } else { + + vibrator.vibrate (duration); + + } } else { - int periodMS = (int)Math.ceil (period / 2); - int count = (int)Math.ceil ((duration / period) * 2); + // each period has two halves (vibrator off/vibrator on), and each half requires a separate entry in the array + int periodMS = (int)Math.ceil (period / 2.0); + int count = (int)Math.ceil (duration / (double) periodMS); long[] pattern = new long[count]; - for (int i = 0; i < count; i++) { + // the first entry is the delay before vibration starts, so leave it as 0 + for (int i = 1; i < count; i++) { pattern[i] = periodMS; } - v.vibrate (pattern, -1); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + + vibrator.vibrate (VibrationEffect.createWaveform (pattern, -1)); + + } else { + + vibrator.vibrate (pattern, -1); + + } } diff --git a/tools/platforms/MacPlatform.hx b/tools/platforms/MacPlatform.hx index 09322efcb..14d121ff9 100644 --- a/tools/platforms/MacPlatform.hx +++ b/tools/platforms/MacPlatform.hx @@ -2,7 +2,6 @@ package; import haxe.io.Eof; import hxp.Haxelib; -import hxp.HostArchitecture; import hxp.HXML; import hxp.Log; import hxp.Path; @@ -191,17 +190,6 @@ class MacPlatform extends PlatformTarget NekoHelper.createExecutable(project.templatePaths, "mac" + dirSuffix.toLowerCase(), targetDirectory + "/obj/ApplicationMain.n", executablePath); NekoHelper.copyLibraries(project.templatePaths, "mac" + dirSuffix.toLowerCase(), executableDirectory); - - // starting in xcode 15, rpath doesn't automatically include - // /usr/local/lib, but we need it for libneko dylib - System.runCommand("", "install_name_tool", ["-add_rpath", "/usr/local/lib", Path.join([executableDirectory, "lime.ndll"])]); - if (System.hostArchitecture == HostArchitecture.ARM64) - { - // on Apple Silicon, the user may have installed Neko with - // Homebrew, which has a different path. however, if the - // Homebrew path doesn't exist, that's okay. - System.runCommand("", "install_name_tool", ["-add_rpath", "/opt/homebrew/lib", Path.join([executableDirectory, "lime.ndll"])]); - } } else if (targetType == "hl") {