@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.
Files changed (75) hide show
  1. package/dist/cli.d.ts +59 -0
  2. package/dist/cli.js +141 -0
  3. package/dist/constants.d.ts +53 -0
  4. package/dist/constants.js +64 -0
  5. package/dist/context.d.ts +29 -0
  6. package/dist/context.js +19 -0
  7. package/dist/electron.d.ts +10 -0
  8. package/dist/electron.js +142 -0
  9. package/dist/index.js +18 -754
  10. package/dist/native.d.ts +27 -0
  11. package/dist/native.js +123 -0
  12. package/dist/utils.d.ts +27 -0
  13. package/dist/utils.js +40 -0
  14. package/dist/web.d.ts +18 -0
  15. package/dist/web.js +70 -0
  16. package/dist/xbox.d.ts +62 -0
  17. package/dist/xbox.js +426 -0
  18. package/package.json +12 -9
  19. package/templates/xbox/CMakeLists.txt +116 -11
  20. package/templates/xbox/README.md +34 -8
  21. package/templates/xbox/cmake/FetchDawn.cmake +47 -6
  22. package/templates/xbox/cmake/FindV8.cmake +15 -0
  23. package/templates/xbox/js/bootstrap.js +151 -28
  24. package/templates/xbox/js/selftest.js +740 -90
  25. package/templates/xbox/src/AssetLoader.cpp +115 -12
  26. package/templates/xbox/src/AssetLoader.h +4 -0
  27. package/templates/xbox/src/EmbeddedAssets.cpp +149 -0
  28. package/templates/xbox/src/EmbeddedAssets.h +60 -0
  29. package/templates/xbox/src/EventLoop.cpp +13 -1
  30. package/templates/xbox/src/EventLoop.h +12 -0
  31. package/templates/xbox/src/bindings/Audio.cpp +211 -31
  32. package/templates/xbox/src/bindings/Bindings.h +10 -0
  33. package/templates/xbox/src/bindings/Canvas.cpp +77 -2
  34. package/templates/xbox/src/bindings/Canvas2D.cpp +496 -43
  35. package/templates/xbox/src/bindings/Console.cpp +6 -1
  36. package/templates/xbox/src/bindings/DomShims.cpp +143 -0
  37. package/templates/xbox/src/bindings/EventTarget.cpp +11 -0
  38. package/templates/xbox/src/bindings/Fetch.cpp +2 -8
  39. package/templates/xbox/src/bindings/Image.cpp +243 -15
  40. package/templates/xbox/src/bindings/Polyfills.cpp +1226 -0
  41. package/templates/xbox/src/bindings/RasterCore.h +105 -1
  42. package/templates/xbox/src/bindings/Video.cpp +153 -10
  43. package/templates/xbox/src/bindings/webgpu/WebGPU.cpp +844 -18
  44. package/templates/xbox/src/bindings/webgpu/WebGPUCommon.h +7 -9
  45. package/templates/xbox/src/bindings/webgpu/WebGPUEnums.h +32 -0
  46. package/templates/xbox/src/gpu/DawnContext.cpp +245 -7
  47. package/templates/xbox/src/gpu/DawnContext.h +18 -0
  48. package/templates/xbox/src/main.cpp +459 -8
  49. package/templates/xbox/src/platform/AudioDecoder.cpp +121 -0
  50. package/templates/xbox/src/platform/AudioDecoder.h +18 -0
  51. package/templates/xbox/src/platform/AudioEngine.cpp +37 -6
  52. package/templates/xbox/src/platform/DecodeQueue.cpp +136 -0
  53. package/templates/xbox/src/platform/DecodeQueue.h +27 -0
  54. package/templates/xbox/src/platform/ImageDecoder.cpp +44 -0
  55. package/templates/xbox/src/platform/ImageDecoder.h +18 -0
  56. package/templates/xbox/src/platform/StbTextRasterizer.cpp +324 -0
  57. package/templates/xbox/src/platform/StbTextRasterizer.h +37 -0
  58. package/templates/xbox/src/platform/TextRasterizer.cpp +32 -0
  59. package/templates/xbox/src/platform/WicDecoder.cpp +19 -0
  60. package/templates/xbox/src/v8/CodeCache.h +223 -0
  61. package/templates/xbox/src/v8/V8Runtime.cpp +76 -11
  62. package/templates/xbox/src/v8/V8Util.h +79 -0
  63. package/templates/xbox/src/v8/WeakHandle.h +45 -0
  64. package/templates/xbox/src/worker/WorkerRuntime.cpp +432 -48
  65. package/templates/xbox/src/worker/WorkerRuntime.h +43 -13
  66. package/templates/xbox/tests/check_local.sh +7 -2
  67. package/templates/xbox/tests/gamecore_api_probe.cpp +172 -0
  68. package/templates/xbox/tests/raster_test.cpp +50 -0
  69. package/templates/xbox/tests/windows_platform_test.cpp +75 -3
  70. package/templates/xbox/third_party/LICENSES.md +14 -0
  71. package/templates/xbox/third_party/dr_mp3.h +5412 -0
  72. package/templates/xbox/third_party/dr_wav.h +9131 -0
  73. package/templates/xbox/third_party/stb_image.h +7988 -0
  74. package/templates/xbox/third_party/stb_truetype.h +5079 -0
  75. package/templates/xbox/third_party/stb_vorbis.c +5584 -0
package/dist/index.js CHANGED
@@ -1,779 +1,43 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- import pc from "picocolors";
4
- import fs from "fs";
5
- import os from "os";
6
- import path from "path";
7
- import { fileURLToPath } from "url";
8
- import cp from "child_process";
9
- import { loadConfigFromFile } from "vite";
10
- import { api } from "@electron-forge/core";
11
- const recommendeVersion = 22;
12
- const version = process.versions.node;
13
- if (recommendeVersion > parseInt(version.split(".")[0])) {
14
- pc.red(`You are running Node Version:${version}.
15
- View Generator requires Node ${recommendeVersion} or higher.
16
- Please update your version of Node.`);
17
- process.exit(1);
18
- }
19
- let platform = "";
20
- let environment = "";
21
- let hasHelp = false;
22
- let preview = false;
23
- let open = false;
24
- let build = false;
25
- let v8Root = "";
26
- for (let idx = 0; idx < process.argv.length; ++idx) {
27
- switch (process.argv[idx]) {
28
- case "--preview":
29
- preview = true;
30
- break;
31
- case "--open":
32
- open = true;
33
- break;
34
- case "--build":
35
- build = true;
36
- break;
37
- case "--help":
38
- case "--h":
39
- hasHelp = true;
40
- break;
41
- case "--platform":
42
- platform = process.argv[++idx].toLowerCase();
43
- break;
44
- case "--env":
45
- environment = process.argv[++idx];
46
- break;
47
- case "--v8-root":
48
- // Xbox ビルドで使う prebuilt V8 monolith のパス (環境変数 V8_ROOT より優先)
49
- v8Root = process.argv[++idx] || "";
50
- break;
51
- default:
52
- break;
53
- }
54
- if (hasHelp) {
55
- break;
56
- }
57
- }
58
- if (!platform || !environment) {
59
- hasHelp = true;
60
- }
61
- /**
62
- * @description ヘルプを出力して終了
63
- * Output help and exit
64
- *
65
- * @return {void}
66
- * @method
67
- * @public
68
- */
69
- const echoHelp = () => {
70
- console.log();
71
- console.log(pc.green("`--platform` can be specified for macOS, Windows, iOS, Android, Xbox, and Web"));
72
- console.log(pc.green("It is not case sensitive."));
73
- console.log();
74
- console.log("For build example:");
75
- console.log("npx @next2d/builder --platform web --env prd");
76
- console.log();
77
- console.log("For preview example:");
78
- console.log("npx @next2d/builder --preview --platform web --env prd");
79
- console.log();
80
- console.log("For Xbox build example (prebuilt V8 is downloaded automatically):");
81
- console.log("npx @next2d/builder --platform xbox --env prd");
82
- console.log("To use your own V8 build: --v8-root C:\\path\\to\\v8");
83
- console.log();
84
- process.exit(1);
85
- };
86
- if (hasHelp) {
87
- echoHelp();
88
- }
89
- if (!platform || !environment) {
90
- echoHelp();
91
- }
92
- switch (platform) {
93
- case "windows":
94
- case "macos":
95
- case "linux":
96
- case "steam:windows":
97
- case "steam:macos":
98
- case "steam:linux":
99
- case "ios":
100
- case "android":
101
- case "xbox":
102
- case "web":
103
- break;
104
- default:
105
- echoHelp();
106
- break;
107
- }
108
- /**
109
- * @type {string}
110
- * @private
111
- */
112
- const platformDir = platform.indexOf(":") ? platform.split(":").join("/") : platform;
113
- /**
114
- * @type {object}
115
- * @private
116
- */
117
- let $configObject = null;
118
- /**
119
- * @type {string}
120
- * @private
121
- */
122
- let $buildDir = "";
123
- /**
124
- * @type {string}
125
- * @private
126
- */
127
- let $outDir = "dist";
128
- // update env variables
129
- process.env.NEXT2D_EBUILD_ENVIRONMENT = environment;
130
- process.env.NEXT2D_TARGET_PLATFORM = platform;
131
- /**
132
- * @type {string}
133
- * @constant
134
- */
135
- const CAPACITOR_CONFIG_NAME = "capacitor.config.json";
136
- /**
137
- * @return {Promise}
138
- * @method
139
- * @public
140
- */
141
- const loadConfig = async () => {
142
- const packageJson = JSON.parse(fs.readFileSync(`${process.cwd()}/package.json`, { "encoding": "utf8" }));
143
- if (packageJson.type !== "module") {
144
- packageJson.type = "module";
145
- // overwride
146
- fs.writeFileSync(`${process.cwd()}/package.json`, JSON.stringify(packageJson, null, 2));
147
- }
148
- const ext = fs.existsSync(`${process.cwd()}/vite.config.ts`) ? "ts" : "js";
149
- const config = await loadConfigFromFile({
150
- "command": "build",
151
- "mode": "build"
152
- }, `${process.cwd()}/vite.config.${ext}`);
153
- // update config
154
- $configObject = config;
155
- $outDir = $configObject.config?.build?.outDir || "dist";
156
- $buildDir = `${process.cwd()}/${$outDir}/${platformDir}/${environment}`;
157
- if (!fs.existsSync(`${$buildDir}`)) {
158
- fs.mkdirSync(`${$buildDir}`, { "recursive": true });
159
- console.log(pc.green(`Create build directory: ${$buildDir}`));
160
- console.log();
161
- }
162
- };
163
- /**
164
- * @description Web用アプリの書き出し関数
165
- * Export function for web applications
166
- *
167
- * @return {Promise}
168
- * @method
169
- * @public
170
- */
171
- const buildWeb = () => {
172
- return new Promise((resolve, reject) => {
173
- const stream = cp.spawn("npx", [
174
- "@next2d/vite-plugin-next2d-auto-loader"
175
- ], { "stdio": "inherit" });
176
- stream.on("close", (code) => {
177
- if (code !== 0) {
178
- reject("vite plugin command failed.");
179
- }
180
- const stream = cp.spawn("npx", [
181
- "vite",
182
- "--outDir",
183
- $buildDir,
184
- "build"
185
- ], { "stdio": "inherit" });
186
- stream.on("close", (code) => {
187
- if (code !== 0) {
188
- reject("Export of `HTML` and `JavaScript` failed.");
189
- }
190
- console.log();
191
- console.log(pc.green("`HTML` and `JavaScript` files are written out."));
192
- resolve();
193
- });
194
- });
195
- });
196
- };
197
- /**
198
- * @description electronがインストールされてなければインストールを実行
199
- * If electron is not installed, run install.
200
- *
201
- * @return {Promise}
202
- * @method
203
- * @public
204
- */
205
- const installElectron = () => {
206
- return new Promise((resolve, reject) => {
207
- if (fs.existsSync(`${process.cwd()}/electron/node_modules`)) {
208
- return resolve();
209
- }
210
- const stream = cp.spawn("npm", [
211
- "--prefix",
212
- `${process.cwd()}/electron`,
213
- "install",
214
- `${process.cwd()}/electron`
215
- ], { "stdio": "inherit" });
216
- stream.on("close", (code) => {
217
- if (code !== 0) {
218
- reject("`Electron` installation failed.");
219
- }
220
- console.log(pc.green("`Electron` successfully installed."));
221
- resolve();
222
- });
223
- });
224
- };
225
- /**
226
- * @description electronに含むリソースを初期化
227
- * Initialize resources included in electron
228
- *
229
- * @return {Promise}
230
- * @method
231
- * @public
232
- */
233
- const removeResources = () => {
234
- return new Promise((resolve, reject) => {
235
- const stream = cp.spawn("rm", [
236
- "-rf",
237
- `${process.cwd()}/electron/resources/`
238
- ], { "stdio": "inherit" });
239
- stream.on("close", (code) => {
240
- if (code !== 0) {
241
- reject("Failed to remove built resources.");
242
- }
243
- console.log(pc.green("Successfully remove built resources."));
244
- resolve();
245
- });
246
- });
247
- };
248
- /**
249
- * @description ビルドしたリソースをコピー
250
- * Copy built resources
3
+ // エントリポイント。CLI を初期化し、Web ビルド → 各プラットフォーム書き出しを実行する。
4
+ // 各プラットフォームの実装は web/steam/native/xbox の各モジュールへ分割している。
5
+ import { ctx } from "./context.js";
6
+ import { initCli, echoHelp } from "./cli.js";
7
+ import { loadConfig, buildWeb } from "./web.js";
8
+ import { buildElectron } from "./electron.js";
9
+ import { runNative, openNative, buildNative } from "./native.js";
10
+ import { buildXbox } from "./xbox.js";
11
+ // Node バージョン検証・引数解析・ctx 初期化 (不正時はここで終了)。
12
+ initCli();
13
+ /**
14
+ * @description プラットフォーム別のビルド実行関数
15
+ * Build execution dispatcher per platform
251
16
  *
252
17
  * @return {Promise}
253
18
  * @method
254
19
  * @public
255
20
  */
256
- const copyResources = () => {
257
- return new Promise((resolve, reject) => {
258
- const stream = cp.spawn("cp", [
259
- "-r",
260
- `${$buildDir}/`,
261
- `${process.cwd()}/electron/resources`
262
- ], { "stdio": "inherit" });
263
- stream.on("close", (code) => {
264
- if (code !== 0) {
265
- reject("Failed to copy built resources.");
266
- }
267
- console.log(pc.green("Successfully copy built resources."));
268
- resolve();
269
- });
270
- });
271
- };
272
- /**
273
- * @description Windows用アプリの書き出し関数
274
- * Export function for Windows apps
275
- *
276
- * @return {Promise}
277
- * @method
278
- * @public
279
- */
280
- const buildSteam = async () => {
281
- // reset
282
- await removeResources();
283
- // copy HTML, JavaScript
284
- await copyResources();
285
- if (preview) {
286
- cp.spawn("npx", [
287
- "electron",
288
- `${process.cwd()}/electron/index.js`
289
- ], { "stdio": "inherit" });
290
- }
291
- else {
292
- await installElectron();
293
- console.log(pc.green("Start the `Electron` build process."));
294
- console.log();
295
- const packageOptions = {
296
- "dir": `${process.cwd()}/electron`,
297
- "outDir": `${$outDir}/${platformDir}/build`,
298
- "platform": "",
299
- "arch": "all"
300
- };
301
- switch (platform) {
302
- case "windows":
303
- case "steam:windows":
304
- packageOptions.platform = "win32";
305
- break;
306
- case "macos":
307
- case "steam:macos":
308
- packageOptions.platform = "mas";
309
- break;
310
- case "linux":
311
- case "steam:linux":
312
- packageOptions.platform = "linux";
313
- break;
314
- default:
315
- console.log(pc.red("There is an error in the export platform settings."));
316
- console.log();
317
- process.exit(1);
318
- }
319
- api
320
- .package(packageOptions)
321
- .then(() => {
322
- console.log(pc.green(`Finished building \`Electron\` for ${platform}.`));
323
- console.log();
324
- })
325
- .catch((error) => {
326
- console.log(pc.red("Export of Electron failed."));
327
- console.log(pc.red(error));
328
- });
329
- }
330
- };
331
- /**
332
- * @description iOSのプロジェクトを生成
333
- * Generate iOS project
334
- *
335
- * @return {Promise}
336
- * @method
337
- * @public
338
- */
339
- const generateNativeProject = () => {
340
- return new Promise((resolve, reject) => {
341
- if (fs.existsSync(`${process.cwd()}/${platform}`)) {
342
- return resolve();
343
- }
344
- const stream = cp.spawn("npx", [
345
- "cap",
346
- "add",
347
- platform
348
- ], { "stdio": "inherit" });
349
- stream.on("close", (code) => {
350
- if (code !== 0) {
351
- reject(`Failed generated ${platform} project.`);
352
- }
353
- console.log(pc.green(`Successfully generated ${platform} project.`));
354
- console.log();
355
- resolve();
356
- });
357
- });
358
- };
359
- /**
360
- * @description iOS用アプリの書き出し関数
361
- * Export function for iOS apps
362
- *
363
- * @return {Promise}
364
- * @method
365
- * @public
366
- */
367
- const runNative = async () => {
368
- await generateNativeProject();
369
- /**
370
- * Capacitorの書き出しに必要な設定を生成
371
- * Generate settings necessary for exporting Capacitor
372
- */
373
- const config = JSON.parse(fs.readFileSync(`${process.cwd()}/${CAPACITOR_CONFIG_NAME}`, { "encoding": "utf8" }));
374
- config.webDir = `${$outDir}/${platformDir}/${environment}/`;
375
- fs.writeFileSync(`${process.cwd()}/${CAPACITOR_CONFIG_NAME}`, JSON.stringify(config, null, 2));
376
- cp.spawn("npx", [
377
- "cap",
378
- "run",
379
- platform
380
- ], { "stdio": "inherit" });
381
- };
382
- /**
383
- * @description iOS/Androidアプリのオープン関数
384
- * Open function for iOS/Android apps
385
- *
386
- * @return {Promise}
387
- * @method
388
- * @public
389
- */
390
- const openNative = async () => {
391
- await generateNativeProject();
392
- /**
393
- * Capacitorの書き出しに必要な設定を生成
394
- * Generate settings necessary for exporting Capacitor
395
- */
396
- const config = JSON.parse(fs.readFileSync(`${process.cwd()}/${CAPACITOR_CONFIG_NAME}`, { "encoding": "utf8" }));
397
- config.webDir = `${$outDir}/${platformDir}/${environment}/`;
398
- fs.writeFileSync(`${process.cwd()}/${CAPACITOR_CONFIG_NAME}`, JSON.stringify(config, null, 2));
399
- const stream = cp.spawn("npx", [
400
- "cap",
401
- "sync",
402
- platform
403
- ], { "stdio": "inherit" });
404
- stream.on("close", (code) => {
405
- if (code !== 0) {
406
- console.log(pc.red(`Failed to sync ${platform} project.`));
407
- return;
408
- }
409
- cp.spawn("npx", [
410
- "cap",
411
- "open",
412
- platform
413
- ], { "stdio": "inherit" });
414
- });
415
- };
416
- /**
417
- * @description iOS/Androidアプリのビルド関数
418
- * Build function for iOS/Android apps
419
- *
420
- * @return {Promise}
421
- * @method
422
- * @public
423
- */
424
- const buildNative = async () => {
425
- await generateNativeProject();
426
- /**
427
- * Capacitorの書き出しに必要な設定を生成
428
- * Generate settings necessary for exporting Capacitor
429
- */
430
- const config = JSON.parse(fs.readFileSync(`${process.cwd()}/${CAPACITOR_CONFIG_NAME}`, { "encoding": "utf8" }));
431
- config.webDir = `${$outDir}/${platformDir}/${environment}/`;
432
- fs.writeFileSync(`${process.cwd()}/${CAPACITOR_CONFIG_NAME}`, JSON.stringify(config, null, 2));
433
- const stream = cp.spawn("npx", [
434
- "cap",
435
- "sync",
436
- platform
437
- ], { "stdio": "inherit" });
438
- stream.on("close", (code) => {
439
- if (code !== 0) {
440
- console.log(pc.red(`Failed to sync ${platform} project.`));
441
- return;
442
- }
443
- cp.spawn("npx", [
444
- "cap",
445
- "build",
446
- platform
447
- ], { "stdio": "inherit" });
448
- });
449
- };
450
- /**
451
- * @type {string}
452
- * @constant
453
- */
454
- const XBOX_DIR_NAME = "xbox";
455
- /**
456
- * @description builder パッケージに同梱したテンプレートの絶対パスを取得
457
- * Get the absolute path of a template shipped with the builder package
458
- *
459
- * @param {string} name
460
- * @return {string}
461
- * @method
462
- * @public
463
- */
464
- const getTemplateDir = (name) => {
465
- // dist/index.js から見た templates/ (パッケージルート直下)
466
- const currentDir = path.dirname(fileURLToPath(import.meta.url));
467
- return path.resolve(currentDir, "..", "templates", name);
468
- };
469
- /**
470
- * @type {string}
471
- * @constant
472
- */
473
- const XBOX_CONFIG_NAME = "MicrosoftGame.config";
474
- /**
475
- * @description 自動ダウンロードする prebuilt V8 のバージョン。
476
- * `.github/workflows/build-v8.yml` で発行した Releases のタグと、
477
- * `xbox-host-ci.yml` の V8_TAG に一致させること。
478
- * The prebuilt V8 version to auto-download. Must match the release tag
479
- * published by `build-v8.yml` and V8_TAG in `xbox-host-ci.yml`.
480
- *
481
- * @type {string}
482
- * @constant
483
- */
484
- const XBOX_V8_VERSION = "13.6.233.17";
485
- /**
486
- * @description ゲーム側の `xbox/` へスキャフォールドしないテンプレート内ファイル。
487
- * - MicrosoftGame.config : ゲーム固有設定 (injectGameConfig が注入)
488
- * - tests / .v8_headers : builder リポジトリ側の開発用テスト・キャッシュ
489
- * - build 系 : テンプレート内でビルドした場合の生成物
490
- * Template entries excluded from the per-game `xbox/` scaffold.
491
- *
492
- * @type {Set<string>}
493
- * @constant
494
- */
495
- const XBOX_SCAFFOLD_EXCLUDES = new Set([
496
- XBOX_CONFIG_NAME,
497
- "tests",
498
- ".v8_headers",
499
- "build",
500
- "out",
501
- "_deps",
502
- "CMakeCache.txt",
503
- "CMakeFiles"
504
- ]);
505
- /**
506
- * @description XboxホストのC++/CMake一式をbuilder同梱テンプレートから毎回更新する。
507
- * ホストは「エンジン相当」でユーザーは編集しない前提のため、常に最新へ上書きする。
508
- * ただし各ゲーム固有の `MicrosoftGame.config` は対象外(injectGameConfigが扱う)。
509
- * Refresh the Xbox host (C++/CMake) from the builder's bundled template on every build.
510
- * The host is engine-like and not user-edited, so it is always overwritten,
511
- * excluding the per-game `MicrosoftGame.config` (handled by injectGameConfig).
512
- *
513
- * @return {Promise}
514
- * @method
515
- * @public
516
- */
517
- const refreshXboxHost = () => {
518
- return new Promise((resolve, reject) => {
519
- const projectDir = `${process.cwd()}/${XBOX_DIR_NAME}`;
520
- const templateDir = getTemplateDir("xbox");
521
- if (!fs.existsSync(templateDir)) {
522
- return reject(`Xbox template not found: ${templateDir}`);
523
- }
524
- try {
525
- fs.cpSync(templateDir, projectDir, {
526
- "recursive": true,
527
- // ゲーム固有設定と builder 側の開発用ファイルはスキャフォールドしない
528
- "filter": (src) => !XBOX_SCAFFOLD_EXCLUDES.has(path.basename(src))
529
- });
530
- console.log(pc.green(`Successfully refreshed \`${XBOX_DIR_NAME}\` host.`));
531
- resolve();
532
- }
533
- catch (error) {
534
- reject(`Failed to refresh ${XBOX_DIR_NAME} host. ${error}`);
535
- }
536
- });
537
- };
538
- /**
539
- * @description ゲームルートの `MicrosoftGame.config` をXboxホストへ注入する。
540
- * capacitor.config.json と同様、各ゲーム固有の設定(TitleId/StoreId/名称/ロゴ)は
541
- * プロジェクトルートで管理し、それをホストのビルド対象へ配置する。
542
- * 未配置ならbuilder同梱の既定をフォールバックとして使い、作成を促す。
543
- * Inject the game-root `MicrosoftGame.config` into the Xbox host.
544
- *
545
- * @return {Promise}
546
- * @method
547
- * @public
548
- */
549
- const injectGameConfig = () => {
550
- return new Promise((resolve, reject) => {
551
- const rootConfig = `${process.cwd()}/${XBOX_CONFIG_NAME}`;
552
- const hostConfig = `${process.cwd()}/${XBOX_DIR_NAME}/${XBOX_CONFIG_NAME}`;
553
- try {
554
- if (fs.existsSync(rootConfig)) {
555
- fs.cpSync(rootConfig, hostConfig);
556
- console.log(pc.green(`Applied project \`${XBOX_CONFIG_NAME}\`.`));
557
- }
558
- else {
559
- // フォールバック: builder同梱の既定を配置し、ルートへの作成を促す
560
- fs.cpSync(`${getTemplateDir("xbox")}/${XBOX_CONFIG_NAME}`, hostConfig);
561
- console.log(pc.yellow(`\`${XBOX_CONFIG_NAME}\` not found at project root. Using the default template.`));
562
- console.log(pc.yellow(`Create \`${XBOX_CONFIG_NAME}\` at your project root (like capacitor.config.json) to set TitleId/StoreId/logos.`));
563
- }
564
- resolve();
565
- }
566
- catch (error) {
567
- reject(`Failed to apply ${XBOX_CONFIG_NAME}. ${error}`);
568
- }
569
- });
570
- };
571
- /**
572
- * @description ビルド済みWeb資材(JS/HTML/アセット)をXboxホストのassetsへ配置
573
- * Deploy built web resources (JS/HTML/assets) into the Xbox host assets
574
- *
575
- * @return {Promise}
576
- * @method
577
- * @public
578
- */
579
- const copyXboxResources = () => {
580
- return new Promise((resolve, reject) => {
581
- const assetsDir = `${process.cwd()}/${XBOX_DIR_NAME}/assets/app`;
582
- try {
583
- // reset
584
- fs.rmSync(assetsDir, { "recursive": true, "force": true });
585
- fs.mkdirSync(assetsDir, { "recursive": true });
586
- // copy built web resources (JS/HTML/assets)
587
- fs.cpSync(`${$buildDir}/`, assetsDir, { "recursive": true });
588
- console.log(pc.green("Successfully copy built resources to Xbox host."));
589
- resolve();
590
- }
591
- catch (error) {
592
- reject(`Failed to copy built resources to Xbox host. ${error}`);
593
- }
594
- });
595
- };
596
- /**
597
- * @description Xbox ビルドに使う V8 のパスを解決する。優先順:
598
- * 1. `--v8-root` 引数
599
- * 2. 環境変数 `V8_ROOT`
600
- * 3. キャッシュ済みの prebuilt (%LOCALAPPDATA%/next2d/v8/<version>)
601
- * 4. GitHub Releases (build-v8.yml が発行) から自動ダウンロード
602
- * 3・4 により、通常は何も指定せずに `--platform xbox` だけでビルドできる。
603
- * Resolve the V8 path for the Xbox build. With the cached/auto-downloaded
604
- * prebuilt, no flag or env var is required in the common case.
605
- *
606
- * @return {Promise<string>}
607
- * @method
608
- * @public
609
- */
610
- const resolveXboxV8Root = async () => {
611
- // 1. --v8-root 引数
612
- if (v8Root) {
613
- return path.resolve(process.cwd(), v8Root);
614
- }
615
- // 2. 環境変数 V8_ROOT
616
- if (process.env.V8_ROOT) {
617
- return process.env.V8_ROOT;
618
- }
619
- // 3. キャッシュ済み prebuilt
620
- const cacheBase = process.env.LOCALAPPDATA
621
- ? `${process.env.LOCALAPPDATA}/next2d`
622
- : `${os.homedir()}/.cache/next2d`;
623
- const cacheDir = `${cacheBase}/v8/${XBOX_V8_VERSION}`;
624
- if (fs.existsSync(`${cacheDir}/include/v8.h`)) {
625
- return cacheDir;
626
- }
627
- // 4. GitHub Releases から自動ダウンロード (マシンごとに初回のみ)
628
- const assetName = `v8-monolith-${XBOX_V8_VERSION}-windows-x64.zip`;
629
- const url = `https://github.com/Next2D/builder/releases/download/v8-${XBOX_V8_VERSION}-windows-x64/${assetName}`;
630
- console.log(pc.green(`Downloading prebuilt V8 ${XBOX_V8_VERSION} (first time only) ...`));
631
- console.log(url);
632
- const response = await fetch(url);
633
- if (!response.ok) {
634
- throw new Error(`download failed: HTTP ${response.status}`);
635
- }
636
- fs.mkdirSync(cacheDir, { "recursive": true });
637
- const zipPath = `${cacheDir}/${assetName}.tmp`;
638
- fs.writeFileSync(zipPath, Buffer.from(await response.arrayBuffer()));
639
- // Windows 10+ 標準の tar (bsdtar) は zip も展開できる
640
- const extract = cp.spawnSync("tar", ["-xf", zipPath, "-C", cacheDir], { "stdio": "inherit" });
641
- fs.rmSync(zipPath, { "force": true });
642
- if (extract.status !== 0 || !fs.existsSync(`${cacheDir}/include/v8.h`)) {
643
- fs.rmSync(cacheDir, { "recursive": true, "force": true });
644
- throw new Error("failed to extract the prebuilt V8 archive");
645
- }
646
- console.log(pc.green(`Prebuilt V8 cached at: ${cacheDir}`));
647
- return cacheDir;
648
- };
649
- /**
650
- * @description Xbox(GDKネイティブ)用アプリの書き出し関数。
651
- * V8にNext2DのJSを載せ、Dawn(WebGPU/D3D12)で描画するC++ホストをビルドする。
652
- * Export function for Xbox (GDK native) apps.
653
- * Builds a C++ host that runs Next2D's JS on V8 and renders via Dawn (WebGPU/D3D12).
654
- *
655
- * @return {Promise}
656
- * @method
657
- * @public
658
- */
659
- const buildXbox = async () => {
660
- // C++/CMake ホストを最新へ更新 (ゲーム固有設定は除外)
661
- await refreshXboxHost();
662
- // ゲームルートの MicrosoftGame.config を注入
663
- await injectGameConfig();
664
- // ビルド済みWeb資材を配置
665
- await copyXboxResources();
666
- /**
667
- * GDK ビルドは Windows + Visual Studio + Microsoft GDK が必須。
668
- * それ以外の環境ではスキャフォールドと資材配置のみを行い、手順を案内する。
669
- * The GDK build requires Windows + Visual Studio + Microsoft GDK.
670
- * On other platforms we only scaffold and copy assets, then guide the next steps.
671
- */
672
- if (process.platform !== "win32") {
673
- console.log();
674
- console.log(pc.yellow("Xbox host project has been generated and assets were copied."));
675
- console.log(pc.yellow("The GDK build must run on Windows with Visual Studio and the Microsoft GDK installed."));
676
- console.log(pc.yellow(`See ${XBOX_DIR_NAME}/README.md for the build steps.`));
677
- console.log();
678
- return;
679
- }
680
- /**
681
- * @type {string}
682
- * GDK の対象コンソール世代。既定は Xbox Series X|S (Scarlett)。
683
- * 必要に応じて `Gaming.Xbox.XboxOne.x64` / `Gaming.Desktop.x64` を選択。
684
- */
685
- const gdkArch = process.env.NEXT2D_XBOX_ARCH || "Gaming.Xbox.Scarlett.x64";
686
- const cmakeBuildDir = `${process.cwd()}/${$outDir}/${platformDir}/build`;
687
- /**
688
- * prebuilt V8 のパスを解決する (--v8-root > V8_ROOT > キャッシュ > 自動ダウンロード)。
689
- * 通常は何も指定せずにビルドできる。
690
- */
691
- let resolvedV8Root = "";
692
- try {
693
- resolvedV8Root = await resolveXboxV8Root();
694
- }
695
- catch (error) {
696
- console.log(pc.red(`Failed to prepare the prebuilt V8: ${error}`));
697
- console.log(pc.red("Fallbacks:"));
698
- console.log(pc.red(" 1) Retry later (the download may have failed temporarily)."));
699
- console.log(pc.red(" 2) Build V8 yourself and pass `--v8-root <path>`:"));
700
- console.log(pc.red(" npx @next2d/builder --platform xbox --env prd --v8-root C:\\path\\to\\v8"));
701
- console.log(pc.red(` See ${XBOX_DIR_NAME}/README.md ("V8 の用意") for the build steps.`));
702
- return;
703
- }
704
- if (!fs.existsSync(`${resolvedV8Root}/include/v8.h`)) {
705
- console.log(pc.red(`\`include/v8.h\` not found under: ${resolvedV8Root}`));
706
- console.log(pc.red(`Check the \`--v8-root\` path. See ${XBOX_DIR_NAME}/README.md for how to prepare the prebuilt V8.`));
707
- return;
708
- }
709
- const configure = () => {
710
- return new Promise((resolve, reject) => {
711
- const stream = cp.spawn("cmake", [
712
- "-S", `${process.cwd()}/${XBOX_DIR_NAME}`,
713
- "-B", cmakeBuildDir,
714
- "-G", "Visual Studio 17 2022",
715
- "-A", gdkArch,
716
- "-D", `V8_ROOT=${resolvedV8Root}`
717
- ], { "stdio": "inherit" });
718
- stream.on("close", (code) => {
719
- if (code !== 0) {
720
- return reject("Failed to configure the Xbox (CMake/GDK) project.");
721
- }
722
- resolve();
723
- });
724
- });
725
- };
726
- await configure();
727
- if (open || preview) {
728
- // Visual Studio ソリューションを開く (実機/エミュレータでの実行はVS側で行う)
729
- cp.spawn("cmake", [
730
- "--open", cmakeBuildDir
731
- ], { "stdio": "inherit" });
732
- return;
733
- }
734
- // フルビルド (Release パッケージまで)
735
- const stream = cp.spawn("cmake", [
736
- "--build", cmakeBuildDir,
737
- "--config", "Release"
738
- ], { "stdio": "inherit" });
739
- stream.on("close", (code) => {
740
- if (code !== 0) {
741
- console.log(pc.red("Export of the Xbox (GDK) package failed."));
742
- return;
743
- }
744
- console.log();
745
- console.log(pc.green(`Finished building the Xbox (GDK) package for ${gdkArch}.`));
746
- console.log();
747
- });
748
- };
749
- /**
750
- * @description ビルドの実行関数
751
- * Build Execution Functions
752
- *
753
- * @return {void}
754
- * @method
755
- * @public
756
- */
757
21
  const multiBuild = async () => {
758
- switch (platform) {
22
+ switch (ctx.platform) {
759
23
  case "windows":
760
24
  case "macos":
761
25
  case "linux":
762
26
  case "steam:windows":
763
27
  case "steam:macos":
764
28
  case "steam:linux":
765
- await buildSteam();
29
+ await buildElectron();
766
30
  break;
767
31
  case "ios":
768
32
  case "android":
769
33
  switch (true) {
770
- case open:
34
+ case ctx.open:
771
35
  await openNative();
772
36
  break;
773
- case build:
37
+ case ctx.build:
774
38
  await buildNative();
775
39
  break;
776
- case preview:
40
+ case ctx.preview:
777
41
  await runNative();
778
42
  break;
779
43
  default: