@next2d/builder 0.1.7 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +59 -0
- package/dist/cli.js +141 -0
- package/dist/constants.d.ts +53 -0
- package/dist/constants.js +64 -0
- package/dist/context.d.ts +29 -0
- package/dist/context.js +19 -0
- package/dist/electron.d.ts +10 -0
- package/dist/electron.js +142 -0
- package/dist/index.js +18 -754
- package/dist/native.d.ts +27 -0
- package/dist/native.js +123 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.js +40 -0
- package/dist/web.d.ts +18 -0
- package/dist/web.js +70 -0
- package/dist/xbox.d.ts +62 -0
- package/dist/xbox.js +426 -0
- package/package.json +12 -9
- package/templates/xbox/CMakeLists.txt +116 -11
- package/templates/xbox/README.md +34 -8
- package/templates/xbox/cmake/FetchDawn.cmake +47 -6
- package/templates/xbox/cmake/FindV8.cmake +15 -0
- package/templates/xbox/js/bootstrap.js +151 -28
- package/templates/xbox/js/selftest.js +740 -90
- package/templates/xbox/src/AssetLoader.cpp +115 -12
- package/templates/xbox/src/AssetLoader.h +4 -0
- package/templates/xbox/src/EmbeddedAssets.cpp +149 -0
- package/templates/xbox/src/EmbeddedAssets.h +60 -0
- package/templates/xbox/src/EventLoop.cpp +13 -1
- package/templates/xbox/src/EventLoop.h +12 -0
- package/templates/xbox/src/bindings/Audio.cpp +211 -31
- package/templates/xbox/src/bindings/Bindings.h +10 -0
- package/templates/xbox/src/bindings/Canvas.cpp +77 -2
- package/templates/xbox/src/bindings/Canvas2D.cpp +496 -43
- package/templates/xbox/src/bindings/Console.cpp +6 -1
- package/templates/xbox/src/bindings/DomShims.cpp +143 -0
- package/templates/xbox/src/bindings/EventTarget.cpp +11 -0
- package/templates/xbox/src/bindings/Fetch.cpp +2 -8
- package/templates/xbox/src/bindings/Image.cpp +243 -15
- package/templates/xbox/src/bindings/Polyfills.cpp +1226 -0
- package/templates/xbox/src/bindings/RasterCore.h +105 -1
- package/templates/xbox/src/bindings/Video.cpp +153 -10
- package/templates/xbox/src/bindings/webgpu/WebGPU.cpp +844 -18
- package/templates/xbox/src/bindings/webgpu/WebGPUCommon.h +7 -9
- package/templates/xbox/src/bindings/webgpu/WebGPUEnums.h +32 -0
- package/templates/xbox/src/gpu/DawnContext.cpp +245 -7
- package/templates/xbox/src/gpu/DawnContext.h +18 -0
- package/templates/xbox/src/main.cpp +459 -8
- package/templates/xbox/src/platform/AudioDecoder.cpp +121 -0
- package/templates/xbox/src/platform/AudioDecoder.h +18 -0
- package/templates/xbox/src/platform/AudioEngine.cpp +37 -6
- package/templates/xbox/src/platform/DecodeQueue.cpp +136 -0
- package/templates/xbox/src/platform/DecodeQueue.h +27 -0
- package/templates/xbox/src/platform/ImageDecoder.cpp +44 -0
- package/templates/xbox/src/platform/ImageDecoder.h +18 -0
- package/templates/xbox/src/platform/StbTextRasterizer.cpp +324 -0
- package/templates/xbox/src/platform/StbTextRasterizer.h +37 -0
- package/templates/xbox/src/platform/TextRasterizer.cpp +32 -0
- package/templates/xbox/src/platform/WicDecoder.cpp +19 -0
- package/templates/xbox/src/v8/CodeCache.h +223 -0
- package/templates/xbox/src/v8/V8Runtime.cpp +76 -11
- package/templates/xbox/src/v8/V8Util.h +79 -0
- package/templates/xbox/src/v8/WeakHandle.h +45 -0
- package/templates/xbox/src/worker/WorkerRuntime.cpp +432 -48
- package/templates/xbox/src/worker/WorkerRuntime.h +43 -13
- package/templates/xbox/tests/check_local.sh +7 -2
- package/templates/xbox/tests/gamecore_api_probe.cpp +172 -0
- package/templates/xbox/tests/raster_test.cpp +50 -0
- package/templates/xbox/tests/windows_platform_test.cpp +75 -3
- package/templates/xbox/third_party/LICENSES.md +14 -0
- package/templates/xbox/third_party/dr_mp3.h +5412 -0
- package/templates/xbox/third_party/dr_wav.h +9131 -0
- package/templates/xbox/third_party/stb_image.h +7988 -0
- package/templates/xbox/third_party/stb_truetype.h +5079 -0
- package/templates/xbox/third_party/stb_vorbis.c +5584 -0
package/templates/xbox/README.md
CHANGED
|
@@ -51,7 +51,7 @@ C++ 実行ファイルをビルドします。Electron や WebView は使用し
|
|
|
51
51
|
### ランタイム環境の要点
|
|
52
52
|
|
|
53
53
|
- **jitless V8**: Xbox/Switch のリテールは JIT(動的コード生成)を禁止するため、V8 は
|
|
54
|
-
`--jitless`(Ignition
|
|
54
|
+
`--jitless --wasm-jitless` で起動する (JS=Ignition インタプリタ、wasm=DrumBrake インタープリタ)。
|
|
55
55
|
- **Worker / OffscreenCanvas**: player はレンダラを Worker + `transferControlToOffscreen`
|
|
56
56
|
で動かす。本ホストは **「同一 Isolate 内の別 Context を協調スケジューリングする単一スレッド
|
|
57
57
|
Worker モデル」** を採用(`src/worker/WorkerRuntime`)。`postMessage` は V8 の
|
|
@@ -73,7 +73,7 @@ C++ 実行ファイルをビルドします。Electron や WebView は使用し
|
|
|
73
73
|
|------|------|
|
|
74
74
|
| OS | Windows 11 |
|
|
75
75
|
| IDE | Visual Studio 2022 (v143, C++ Game development workload) |
|
|
76
|
-
| GDK |
|
|
76
|
+
| GDK | 公開版 GDK をインストール (`-A Gaming.Desktop.x64`)、**または** NuGet `Microsoft.GDK.Windows` を展開して `-A x64` + 環境変数/`-D` `GDK_ROOT=<pkg>/native/<edition>/windows`(インストーラ不要・CI 向け)。コンソール向け GDKX は ID@Xbox 登録が必要 |
|
|
77
77
|
| CMake | 3.26 以降 |
|
|
78
78
|
| V8 | 不要 (builder が prebuilt を自動ダウンロード)。自前ビルドは `--v8-root` で指定可 |
|
|
79
79
|
| Dawn | CMake の FetchContent で自動取得(ネットワーク必須) |
|
|
@@ -120,9 +120,9 @@ set DEPOT_TOOLS_WIN_TOOLCHAIN=0
|
|
|
120
120
|
fetch v8
|
|
121
121
|
cd v8
|
|
122
122
|
:: CI のコンパイル検証と同じバージョンに固定 (xbox-host-ci.yml の V8_TAG)
|
|
123
|
-
git checkout 13.
|
|
123
|
+
git checkout 13.7.152.19
|
|
124
124
|
gclient sync
|
|
125
|
-
gn gen out\x64.release --args="v8_monolithic=true v8_use_external_startup_data=false is_component_build=false use_custom_libcxx=false icu_use_data_file=false treat_warnings_as_errors=false
|
|
125
|
+
gn gen out\x64.release --args="v8_monolithic=true v8_use_external_startup_data=false is_component_build=false use_custom_libcxx=false icu_use_data_file=false treat_warnings_as_errors=false v8_enable_drumbrake=true target_cpu=\"x64\" is_debug=false v8_enable_pointer_compression=true v8_enable_sandbox=false"
|
|
126
126
|
ninja -C out\x64.release v8_monolith
|
|
127
127
|
```
|
|
128
128
|
|
|
@@ -142,9 +142,12 @@ ninja -C out\x64.release v8_monolith
|
|
|
142
142
|
> - `treat_warnings_as_errors=false` を推奨。`use_custom_libcxx=false` では MSVC STL の
|
|
143
143
|
> ヘッダ警告が -Werror で停止することがあります。**VS のバージョンは VS2022 (v143) を推奨**
|
|
144
144
|
> (新しすぎる STL は V8 の clang が警告/エラーを出しやすい)。
|
|
145
|
-
> - `
|
|
146
|
-
>
|
|
147
|
-
>
|
|
145
|
+
> - `v8_enable_drumbrake=true` は必須 (r2)。**DrumBrake = V8 の wasm インタープリタ**で、
|
|
146
|
+
> JIT 禁止環境 (コンソール) でも wasm を解釈実行できます。wasm はビルド時に turbofan を
|
|
147
|
+
> 要求するため `v8_jitless` ビルドは使えません — JIT の無効化はホストが実行時フラグ
|
|
148
|
+
> `--jitless --wasm-jitless` で行います (JS=Ignition / wasm=DrumBrake)。
|
|
149
|
+
> 注意: DrumBrake は既定ビルド対象外のためタグによりコンパイル不能な場合があります
|
|
150
|
+
> (13.6.233.17 は不可 → 13.7.152.19 で修正済み)。
|
|
148
151
|
> - pointer compression は `CMakeLists.txt` の `V8_COMPRESS_POINTERS` と一致させてください
|
|
149
152
|
> (sandbox 無効に合わせ `V8_ENABLE_SANDBOX` は定義しません)。不一致は ABI 崩れの原因になります。
|
|
150
153
|
> - 上記は PC (`Gaming.Desktop.x64`) 用。コンソール実機 (`Gaming.Xbox.*`) 向けは
|
|
@@ -210,7 +213,7 @@ macOS / Linux でそのまま実行できます:
|
|
|
210
213
|
tests/check_local.sh
|
|
211
214
|
```
|
|
212
215
|
|
|
213
|
-
構文チェックは実 V8 ヘッダ (pin: `13.
|
|
216
|
+
構文チェックは実 V8 ヘッダ (pin: `13.7.152.19`) に対して、Windows API 非依存の
|
|
214
217
|
V8 バインディング 12 ファイルをコンパイル検証します (API 削除・型不整合を検出)。
|
|
215
218
|
|
|
216
219
|
### 2. GitHub Actions (windows-latest) — `.github/workflows/xbox-host-ci.yml`
|
|
@@ -302,6 +305,11 @@ player の実 API 使用を全面調査し、以下を実装済み。**この環
|
|
|
302
305
|
| ポインタ/キーボード/ホイール入力 | ⚠️ 実装(要検証) | `WndProc`→`DispatchEvent`。配送先canvasの特定は実機検証 |
|
|
303
306
|
| 動画 (HTMLVideoElement) | ⚠️ 実装(要検証) | `Video.cpp`(Media Foundation)。フレーム精度/音声同期は実機検証 |
|
|
304
307
|
| クリップボード (`navigator.clipboard`) | ✅ 実装 | Win32 クリップボード (readText/writeText) |
|
|
308
|
+
| **JS エンジン/グローバル機能** (player 全数調査) | ✅ 実装 | Proxy=V8コア。`crypto.randomUUID`/`getRandomValues`(BCrypt)、`TextEncoder`/`TextDecoder`/`queueMicrotask`/`location`/`atob`/`btoa` は worker 含む全コンテキストへ注入。`createImageBitmap` は ImageData/ImageBitmap/canvas/Blob を受理 |
|
|
309
|
+
| **WebAssembly** | ✅ 実装 (要 V8 r2) | prebuilt V8 r2 = wasm + **DrumBrake**(V8 の wasm インタープリタ、JIT 禁止コンソール向け)。実行時 `--jitless --wasm-jitless` で JS=Ignition / wasm=DrumBrake 解釈実行 |
|
|
310
|
+
| **indexedDB** (最小実装) | ✅ 実装 | open/createObjectStore/transaction/get/put/delete/clear/getAll/count/keyPath。値は JSON 化可能なもの + ArrayBuffer/TypedArray(base64 永続化)。カーソル/インデックスは未対応。保存先 `%LOCALAPPDATA%\Next2D\idb_<db>.json` |
|
|
311
|
+
| **localStorage / sessionStorage** | ✅ 実装 | JS セマンティクス + ファイル永続化 (`%LOCALAPPDATA%\Next2D\`)。コンソール実機では XGameSave 化が必要 («EXTEND») |
|
|
312
|
+
| **Audio 要素** (`new Audio(url)`) | ✅ 実装 | play/pause/paused/loop/volume/currentTime/preload (pause→play は先頭から) |
|
|
305
313
|
|
|
306
314
|
> player が使用する API はコード上すべて実装済み。残る唯一の障壁は
|
|
307
315
|
> **GDK/devkit を要するコンパイル・実機検証**(この環境では物理的に不可)。
|
|
@@ -370,3 +378,21 @@ xbox/
|
|
|
370
378
|
├─ Gamepad.cpp DomShims.cpp
|
|
371
379
|
└─ webgpu/{WebGPU.cpp,WebGPUCommon.h,WebGPUEnums.h}
|
|
372
380
|
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## コンソール (Game Core OS) とテキスト描画・フォント
|
|
385
|
+
|
|
386
|
+
コンソールには DirectWrite / システムフォントが存在しないため、`fillText`/`measureText`
|
|
387
|
+
は同梱の stb_truetype 実装 (`platform/StbTextRasterizer`) が担う。フォントは実行時登録:
|
|
388
|
+
|
|
389
|
+
- **ゲーム資材に TTF/OTF を含める**(推奨): Web ビルドの資材 (`assets/app`) に
|
|
390
|
+
`*.ttf` / `*.otf` があれば起動時に自動登録される (vite の `public/` に置く等)。
|
|
391
|
+
日本語テキストを使う場合は Noto Sans JP (OFL) などの同梱を推奨。
|
|
392
|
+
- 開発ビルド: exe 隣接の `fonts/` ディレクトリからも読み込む。
|
|
393
|
+
- フォント未登録の場合、テキストは近似メトリクスのみ (グリフ描画なし) になる。
|
|
394
|
+
|
|
395
|
+
デスクトップ (PC/GDK) は従来どおり DirectWrite が主経路のため、フォント同梱は不要。
|
|
396
|
+
同様に、画像は stb_image、音声は dr_mp3/dr_wav/stb_vorbis が全プラットフォーム共通の
|
|
397
|
+
第一経路で、WIC / Media Foundation はデスクトップ限定のフォールバック
|
|
398
|
+
(AAC/TIFF 等の非標準形式向け)。コンソールでの動画 (`<video>`) は未対応。
|
|
@@ -3,13 +3,18 @@
|
|
|
3
3
|
# D3D12 バックエンドのみを有効化し、Xbox(GDK)/PC(GDK) で利用する。
|
|
4
4
|
#
|
|
5
5
|
# 注意:
|
|
6
|
-
# -
|
|
6
|
+
# - submodule はクローンしない (GIT_SUBMODULES "")。SwiftShader→LLVM まで再帰して
|
|
7
|
+
# 数 GB のクローン + Windows の MAX_PATH 超過 ("Filename too long") で失敗するため。
|
|
8
|
+
# 依存は Dawn 公式の DAWN_FETCH_DEPENDENCIES (python スクリプト) が必要分だけ取得する。
|
|
9
|
+
# - DAWN_FETCH_DEPENDENCIES には python3 が PATH に必要。
|
|
7
10
|
# - 初回構成はネットワークとビルド時間を要する。CI ではキャッシュ推奨。
|
|
8
|
-
# - DAWN_TAG
|
|
11
|
+
# - DAWN_TAG はバインディング (bindings/webgpu/*) が使う API 世代と一致させること:
|
|
12
|
+
# wgpu::Limits / ShaderSourceWGSL / SurfaceSourceWindowsHWND / OptionalBool
|
|
13
|
+
# (いずれも 2025 以降の命名。古いタグでは SupportedLimits 等になりビルド不可)
|
|
9
14
|
# =============================================================================
|
|
10
15
|
include(FetchContent)
|
|
11
16
|
|
|
12
|
-
set(DAWN_TAG "
|
|
17
|
+
set(DAWN_TAG "v20260402.171122" CACHE STRING "Dawn のチェックアウトタグ (github.com/google/dawn)")
|
|
13
18
|
|
|
14
19
|
# Dawn のビルドオプション: 必要なものだけを有効化
|
|
15
20
|
set(DAWN_FETCH_DEPENDENCIES ON CACHE BOOL "" FORCE)
|
|
@@ -24,14 +29,24 @@ set(DAWN_BUILD_SAMPLES OFF CACHE BOOL "" FORCE)
|
|
|
24
29
|
set(TINT_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
|
25
30
|
set(TINT_BUILD_CMD_TOOLS OFF CACHE BOOL "" FORCE)
|
|
26
31
|
|
|
27
|
-
# webgpu_dawn: webgpu.h C-API を提供する統合ライブラリ (バインディング層はこれを叩く)
|
|
28
|
-
|
|
32
|
+
# webgpu_dawn: webgpu.h C-API を提供する統合ライブラリ (バインディング層はこれを叩く)。
|
|
33
|
+
# 2025 以降の Dawn では SHARED / STATIC / OFF の3値。
|
|
34
|
+
# SHARED (DLL) を選ぶ理由: V8 monolith と Dawn は双方が abseil を静的に内蔵しており、
|
|
35
|
+
# STATIC だと raw_hash_set 等の同名シンボルが LNK2005 で衝突する (しかも absl の
|
|
36
|
+
# バージョンが異なるため /FORCE:MULTIPLE は実行時破壊のリスクがある)。
|
|
37
|
+
# DLL にすれば公開されるのは WebGPU C API のみで、absl は DLL 内部に閉じる。
|
|
38
|
+
set(DAWN_BUILD_MONOLITHIC_LIBRARY SHARED CACHE STRING "" FORCE)
|
|
39
|
+
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
|
29
40
|
|
|
30
41
|
FetchContent_Declare(
|
|
31
42
|
dawn
|
|
32
|
-
|
|
43
|
+
# GitHub ミラーの方が CI から高速・安定 (googlesource はレート制限がきつい)
|
|
44
|
+
GIT_REPOSITORY https://github.com/google/dawn.git
|
|
33
45
|
GIT_TAG ${DAWN_TAG}
|
|
34
46
|
GIT_SHALLOW TRUE
|
|
47
|
+
# submodule は取得しない (DAWN_FETCH_DEPENDENCIES が必要分を取得する)
|
|
48
|
+
GIT_SUBMODULES ""
|
|
49
|
+
GIT_SUBMODULES_RECURSE FALSE
|
|
35
50
|
)
|
|
36
51
|
|
|
37
52
|
FetchContent_MakeAvailable(dawn)
|
|
@@ -40,3 +55,29 @@ FetchContent_MakeAvailable(dawn)
|
|
|
40
55
|
if(NOT TARGET dawn::webgpu_dawn AND TARGET webgpu_dawn)
|
|
41
56
|
add_library(dawn::webgpu_dawn ALIAS webgpu_dawn)
|
|
42
57
|
endif()
|
|
58
|
+
|
|
59
|
+
# -----------------------------------------------------------------------------
|
|
60
|
+
# CRT を静的 (/MT) へ強制統一する。
|
|
61
|
+
# CMAKE_MSVC_RUNTIME_LIBRARY 変数だけでは Dawn の third_party (fetch_dawn_dependencies
|
|
62
|
+
# が取得する abseil/protobuf 等) の一部に伝播せず /MD が混ざり、静的 CRT 固定の
|
|
63
|
+
# prebuilt V8 とのリンクで LNK2005/LNK2019 になる。全ターゲットへ再帰的に
|
|
64
|
+
# プロパティを直接設定して確実に揃える。
|
|
65
|
+
# -----------------------------------------------------------------------------
|
|
66
|
+
function(next2d_force_static_crt dir)
|
|
67
|
+
get_property(_targets DIRECTORY "${dir}" PROPERTY BUILDSYSTEM_TARGETS)
|
|
68
|
+
foreach(_t IN LISTS _targets)
|
|
69
|
+
get_target_property(_type ${_t} TYPE)
|
|
70
|
+
if(NOT _type STREQUAL "INTERFACE_LIBRARY")
|
|
71
|
+
set_property(TARGET ${_t} PROPERTY
|
|
72
|
+
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
|
73
|
+
endif()
|
|
74
|
+
endforeach()
|
|
75
|
+
get_property(_subdirs DIRECTORY "${dir}" PROPERTY SUBDIRECTORIES)
|
|
76
|
+
foreach(_sd IN LISTS _subdirs)
|
|
77
|
+
next2d_force_static_crt("${_sd}")
|
|
78
|
+
endforeach()
|
|
79
|
+
endfunction()
|
|
80
|
+
|
|
81
|
+
if(MSVC)
|
|
82
|
+
next2d_force_static_crt("${dawn_SOURCE_DIR}")
|
|
83
|
+
endif()
|
|
@@ -40,6 +40,21 @@ if(NOT V8_ROOT OR NOT EXISTS "${V8_ROOT}")
|
|
|
40
40
|
"詳細は README.md の『V8 の用意』を参照。")
|
|
41
41
|
endif()
|
|
42
42
|
|
|
43
|
+
# find_path/find_library の結果は CMakeCache に永続化されるため、
|
|
44
|
+
# V8_ROOT の変更 (バージョン更新等) や参照先の消滅に追随しない。
|
|
45
|
+
# 古い/無効な検出結果はここで破棄して再探索させる。
|
|
46
|
+
if(DEFINED CACHE{NEXT2D_V8_ROOT_LAST} AND NOT "$CACHE{NEXT2D_V8_ROOT_LAST}" STREQUAL "${V8_ROOT}")
|
|
47
|
+
unset(V8_INCLUDE_DIR CACHE)
|
|
48
|
+
unset(V8_MONOLITH_LIB CACHE)
|
|
49
|
+
endif()
|
|
50
|
+
if(V8_INCLUDE_DIR AND NOT EXISTS "${V8_INCLUDE_DIR}/v8.h")
|
|
51
|
+
unset(V8_INCLUDE_DIR CACHE)
|
|
52
|
+
endif()
|
|
53
|
+
if(V8_MONOLITH_LIB AND NOT EXISTS "${V8_MONOLITH_LIB}")
|
|
54
|
+
unset(V8_MONOLITH_LIB CACHE)
|
|
55
|
+
endif()
|
|
56
|
+
set(NEXT2D_V8_ROOT_LAST "${V8_ROOT}" CACHE INTERNAL "直近の構成で使った V8_ROOT")
|
|
57
|
+
|
|
43
58
|
find_path(V8_INCLUDE_DIR
|
|
44
59
|
NAMES v8.h
|
|
45
60
|
PATHS "${V8_ROOT}/include"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
// V8 単体には Web の Text* が含まれないため最小実装を提供する。
|
|
26
26
|
if (typeof global.TextEncoder === "undefined") {
|
|
27
27
|
global.TextEncoder = class TextEncoder {
|
|
28
|
-
get encoding() { return "utf-8"
|
|
28
|
+
get encoding() { return "utf-8" }
|
|
29
29
|
encode(str) {
|
|
30
30
|
str = String(str);
|
|
31
31
|
const out = [];
|
|
@@ -34,23 +34,23 @@
|
|
|
34
34
|
if (code < 0x80) {
|
|
35
35
|
out.push(code);
|
|
36
36
|
} else if (code < 0x800) {
|
|
37
|
-
out.push(0xc0 |
|
|
37
|
+
out.push(0xc0 | code >> 6, 0x80 | code & 0x3f);
|
|
38
38
|
} else if (code >= 0xd800 && code <= 0xdbff) {
|
|
39
39
|
// サロゲートペア
|
|
40
40
|
const hi = code;
|
|
41
41
|
const lo = str.charCodeAt(++i);
|
|
42
|
-
code = 0x10000 + (
|
|
42
|
+
code = 0x10000 + (hi - 0xd800 << 10) + (lo - 0xdc00);
|
|
43
43
|
out.push(
|
|
44
|
-
0xf0 |
|
|
45
|
-
0x80 |
|
|
46
|
-
0x80 |
|
|
47
|
-
0x80 |
|
|
44
|
+
0xf0 | code >> 18,
|
|
45
|
+
0x80 | code >> 12 & 0x3f,
|
|
46
|
+
0x80 | code >> 6 & 0x3f,
|
|
47
|
+
0x80 | code & 0x3f
|
|
48
48
|
);
|
|
49
49
|
} else {
|
|
50
50
|
out.push(
|
|
51
|
-
0xe0 |
|
|
52
|
-
0x80 |
|
|
53
|
-
0x80 |
|
|
51
|
+
0xe0 | code >> 12,
|
|
52
|
+
0x80 | code >> 6 & 0x3f,
|
|
53
|
+
0x80 | code & 0x3f
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
|
|
62
62
|
if (typeof global.TextDecoder === "undefined") {
|
|
63
63
|
global.TextDecoder = class TextDecoder {
|
|
64
|
-
constructor(label) { this._label = label || "utf-8"
|
|
65
|
-
get encoding() { return "utf-8"
|
|
64
|
+
constructor(label) { this._label = label || "utf-8" }
|
|
65
|
+
get encoding() { return "utf-8" }
|
|
66
66
|
decode(input) {
|
|
67
|
-
if (!input) return ""
|
|
67
|
+
if (!input) { return "" }
|
|
68
68
|
const bytes = input instanceof Uint8Array
|
|
69
69
|
? input
|
|
70
70
|
: new Uint8Array(input.buffer || input);
|
|
@@ -75,14 +75,14 @@
|
|
|
75
75
|
if (c < 0x80) {
|
|
76
76
|
out += String.fromCharCode(c);
|
|
77
77
|
} else if (c < 0xe0) {
|
|
78
|
-
out += String.fromCharCode((
|
|
78
|
+
out += String.fromCharCode((c & 0x1f) << 6 | bytes[i++] & 0x3f);
|
|
79
79
|
} else if (c < 0xf0) {
|
|
80
80
|
out += String.fromCharCode(
|
|
81
|
-
(
|
|
81
|
+
(c & 0x0f) << 12 | (bytes[i++] & 0x3f) << 6 | bytes[i++] & 0x3f
|
|
82
82
|
);
|
|
83
83
|
} else {
|
|
84
|
-
let code = (
|
|
85
|
-
(
|
|
84
|
+
let code = (c & 0x07) << 18 | (bytes[i++] & 0x3f) << 12 |
|
|
85
|
+
(bytes[i++] & 0x3f) << 6 | bytes[i++] & 0x3f;
|
|
86
86
|
code -= 0x10000;
|
|
87
87
|
out += String.fromCharCode(0xd800 + (code >> 10), 0xdc00 + (code & 0x3ff));
|
|
88
88
|
}
|
|
@@ -97,28 +97,151 @@
|
|
|
97
97
|
if (typeof global.URL === "undefined") {
|
|
98
98
|
global.URL = class URL {
|
|
99
99
|
constructor(url, base) {
|
|
100
|
-
this.href = base ?
|
|
100
|
+
this.href = base ? String(base).replace(/\/?$/, "/") + url : String(url);
|
|
101
101
|
this.pathname = this.href.replace(/^[a-z]+:\/\/[^/]*/i, "");
|
|
102
102
|
this.search = "";
|
|
103
103
|
this.hash = "";
|
|
104
104
|
}
|
|
105
|
-
toString() { return this.href
|
|
105
|
+
toString() { return this.href }
|
|
106
106
|
};
|
|
107
|
-
global.URL.createObjectURL = function () { return ""
|
|
107
|
+
global.URL.createObjectURL = function () { return "" };
|
|
108
|
+
// 意図的な no-op スタブ (ローカル実行では解放処理は不要)
|
|
109
|
+
// eslint-disable-next-line no-empty-function
|
|
108
110
|
global.URL.revokeObjectURL = function () {};
|
|
109
111
|
}
|
|
110
112
|
|
|
113
|
+
// --- URLSearchParams の最小補完 ----------------------------------------
|
|
114
|
+
// V8 単体には URLSearchParams が存在しないため補完する。
|
|
115
|
+
// Next2D アプリがクエリ文字列 (?mode=0 等) を解析する際に使用する。
|
|
116
|
+
if (typeof global.URLSearchParams === "undefined") {
|
|
117
|
+
global.URLSearchParams = class URLSearchParams {
|
|
118
|
+
constructor(init) {
|
|
119
|
+
this._list = [];
|
|
120
|
+
if (typeof init === "string") {
|
|
121
|
+
let query = init;
|
|
122
|
+
if (query.charAt(0) === "?") {
|
|
123
|
+
query = query.slice(1);
|
|
124
|
+
}
|
|
125
|
+
if (query.length) {
|
|
126
|
+
const pairs = query.split("&");
|
|
127
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
128
|
+
const pair = pairs[i];
|
|
129
|
+
if (!pair) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const index = pair.indexOf("=");
|
|
133
|
+
const decode = (value) => {
|
|
134
|
+
try {
|
|
135
|
+
return decodeURIComponent(value.replace(/\+/g, " "));
|
|
136
|
+
} catch {
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
if (index === -1) {
|
|
141
|
+
this._list.push([decode(pair), ""]);
|
|
142
|
+
} else {
|
|
143
|
+
this._list.push([decode(pair.slice(0, index)), decode(pair.slice(index + 1))]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} else if (init && typeof init === "object") {
|
|
148
|
+
if (Array.isArray(init)) {
|
|
149
|
+
for (let i = 0; i < init.length; i++) {
|
|
150
|
+
this._list.push([String(init[i][0]), String(init[i][1])]);
|
|
151
|
+
}
|
|
152
|
+
} else if (typeof init.forEach === "function") {
|
|
153
|
+
init.forEach((value, key) => this._list.push([String(key), String(value)]));
|
|
154
|
+
} else {
|
|
155
|
+
for (const key in init) {
|
|
156
|
+
if (Object.prototype.hasOwnProperty.call(init, key)) {
|
|
157
|
+
this._list.push([key, String(init[key])]);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
get(name) {
|
|
164
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
165
|
+
if (this._list[i][0] === name) {
|
|
166
|
+
return this._list[i][1];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
getAll(name) {
|
|
172
|
+
const result = [];
|
|
173
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
174
|
+
if (this._list[i][0] === name) {
|
|
175
|
+
result.push(this._list[i][1]);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
has(name) {
|
|
181
|
+
return this.get(name) !== null;
|
|
182
|
+
}
|
|
183
|
+
set(name, value) {
|
|
184
|
+
const text = String(value);
|
|
185
|
+
let done = false;
|
|
186
|
+
const next = [];
|
|
187
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
188
|
+
if (this._list[i][0] === name) {
|
|
189
|
+
if (!done) {
|
|
190
|
+
next.push([name, text]);
|
|
191
|
+
done = true;
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
next.push(this._list[i]);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (!done) {
|
|
198
|
+
next.push([name, text]);
|
|
199
|
+
}
|
|
200
|
+
this._list = next;
|
|
201
|
+
}
|
|
202
|
+
append(name, value) {
|
|
203
|
+
this._list.push([String(name), String(value)]);
|
|
204
|
+
}
|
|
205
|
+
delete(name) {
|
|
206
|
+
this._list = this._list.filter((pair) => pair[0] !== name);
|
|
207
|
+
}
|
|
208
|
+
forEach(callback, thisArg) {
|
|
209
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
210
|
+
callback.call(thisArg, this._list[i][1], this._list[i][0], this);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
keys() {
|
|
214
|
+
return this._list.map((pair) => pair[0])[Symbol.iterator]();
|
|
215
|
+
}
|
|
216
|
+
values() {
|
|
217
|
+
return this._list.map((pair) => pair[1])[Symbol.iterator]();
|
|
218
|
+
}
|
|
219
|
+
entries() {
|
|
220
|
+
return this._list.map((pair) => [pair[0], pair[1]])[Symbol.iterator]();
|
|
221
|
+
}
|
|
222
|
+
toString() {
|
|
223
|
+
return this._list
|
|
224
|
+
.map((pair) => encodeURIComponent(pair[0]) + "=" + encodeURIComponent(pair[1]))
|
|
225
|
+
.join("&");
|
|
226
|
+
}
|
|
227
|
+
[Symbol.iterator]() {
|
|
228
|
+
return this.entries();
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
111
233
|
// --- location (Next2D が参照する場合の最小値) ---------------------------
|
|
112
234
|
if (typeof global.location === "undefined") {
|
|
113
235
|
global.location = {
|
|
114
|
-
href: "app://local/",
|
|
115
|
-
origin: "app://local",
|
|
116
|
-
protocol: "app:",
|
|
117
|
-
host: "local",
|
|
118
|
-
hostname: "local",
|
|
119
|
-
pathname: "/",
|
|
120
|
-
search: "",
|
|
121
|
-
hash: "",
|
|
236
|
+
"href": "app://local/",
|
|
237
|
+
"origin": "app://local",
|
|
238
|
+
"protocol": "app:",
|
|
239
|
+
"host": "local",
|
|
240
|
+
"hostname": "local",
|
|
241
|
+
"pathname": "/",
|
|
242
|
+
"search": "",
|
|
243
|
+
"hash": "",
|
|
244
|
+
// eslint-disable-next-line no-empty-function
|
|
122
245
|
reload() {}
|
|
123
246
|
};
|
|
124
247
|
}
|