@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
@@ -0,0 +1,121 @@
1
+ #include "AudioDecoder.h"
2
+
3
+ // dr_mp3 / dr_wav / stb_vorbis: public domain のヘッダオンリーデコーダ (third_party/)。
4
+ // メモリ入力のみ使用する。実装は本 TU に集約する (ODR 一意)。
5
+ #define DR_MP3_IMPLEMENTATION
6
+ #define DR_MP3_NO_STDIO
7
+ #include "third_party/dr_mp3.h"
8
+
9
+ #define DR_WAV_IMPLEMENTATION
10
+ #define DR_WAV_NO_STDIO
11
+ #include "third_party/dr_wav.h"
12
+
13
+ // stb_vorbis は .c 配布のためここで取り込む (STB_VORBIS_HEADER_ONLY は使わない)。
14
+ #define STB_VORBIS_NO_STDIO
15
+ #define STB_VORBIS_NO_PUSHDATA_API
16
+ #include "third_party/stb_vorbis.c"
17
+
18
+ #include <cstring>
19
+
20
+ namespace next2d {
21
+
22
+ namespace {
23
+
24
+ bool DecodeMp3(const std::vector<uint8_t>& input, PcmBuffer& out)
25
+ {
26
+ drmp3_config config = {};
27
+ drmp3_uint64 total_frames = 0;
28
+ float* frames = drmp3_open_memory_and_read_pcm_frames_f32(
29
+ input.data(), input.size(), &config, &total_frames, nullptr);
30
+ if (!frames || total_frames == 0 || config.channels == 0) {
31
+ if (frames) {
32
+ drmp3_free(frames, nullptr);
33
+ }
34
+ return false;
35
+ }
36
+ out.channels = config.channels;
37
+ out.sample_rate = config.sampleRate;
38
+ out.samples.assign(frames, frames + total_frames * config.channels);
39
+ drmp3_free(frames, nullptr);
40
+ return true;
41
+ }
42
+
43
+ bool DecodeWav(const std::vector<uint8_t>& input, PcmBuffer& out)
44
+ {
45
+ unsigned int channels = 0, sample_rate = 0;
46
+ drwav_uint64 total_frames = 0;
47
+ float* frames = drwav_open_memory_and_read_pcm_frames_f32(
48
+ input.data(), input.size(), &channels, &sample_rate, &total_frames, nullptr);
49
+ if (!frames || total_frames == 0 || channels == 0) {
50
+ if (frames) {
51
+ drwav_free(frames, nullptr);
52
+ }
53
+ return false;
54
+ }
55
+ out.channels = channels;
56
+ out.sample_rate = sample_rate;
57
+ out.samples.assign(frames, frames + total_frames * channels);
58
+ drwav_free(frames, nullptr);
59
+ return true;
60
+ }
61
+
62
+ bool DecodeOgg(const std::vector<uint8_t>& input, PcmBuffer& out)
63
+ {
64
+ int err = 0;
65
+ stb_vorbis* vorbis = stb_vorbis_open_memory(
66
+ input.data(), static_cast<int>(input.size()), &err, nullptr);
67
+ if (!vorbis) {
68
+ return false;
69
+ }
70
+ const stb_vorbis_info info = stb_vorbis_get_info(vorbis);
71
+ const unsigned int total_frames = stb_vorbis_stream_length_in_samples(vorbis);
72
+ if (info.channels <= 0 || total_frames == 0) {
73
+ stb_vorbis_close(vorbis);
74
+ return false;
75
+ }
76
+ out.channels = static_cast<uint32_t>(info.channels);
77
+ out.sample_rate = info.sample_rate;
78
+ out.samples.resize(static_cast<size_t>(total_frames) * info.channels);
79
+ const int read = stb_vorbis_get_samples_float_interleaved(
80
+ vorbis, info.channels, out.samples.data(),
81
+ static_cast<int>(out.samples.size()));
82
+ stb_vorbis_close(vorbis);
83
+ if (read <= 0) {
84
+ out.samples.clear();
85
+ return false;
86
+ }
87
+ out.samples.resize(static_cast<size_t>(read) * info.channels);
88
+ return true;
89
+ }
90
+
91
+ } // namespace
92
+
93
+ bool DecodeAudio(const std::vector<uint8_t>& input, PcmBuffer& out)
94
+ {
95
+ if (input.size() < 12) {
96
+ return false;
97
+ }
98
+ const uint8_t* d = input.data();
99
+
100
+ // マジックナンバーで形式を判定して該当デコーダを先に試し、
101
+ // 外れたら残りをカスケード (誤判定・ヘッダ無し MP3 の保険)。
102
+ const bool looks_wav = std::memcmp(d, "RIFF", 4) == 0 && std::memcmp(d + 8, "WAVE", 4) == 0;
103
+ const bool looks_ogg = std::memcmp(d, "OggS", 4) == 0;
104
+ const bool looks_mp3 = std::memcmp(d, "ID3", 3) == 0
105
+ || (d[0] == 0xFF && (d[1] & 0xE0) == 0xE0);
106
+
107
+ if (looks_wav && DecodeWav(input, out)) {
108
+ return true;
109
+ }
110
+ if (looks_ogg && DecodeOgg(input, out)) {
111
+ return true;
112
+ }
113
+ if (looks_mp3 && DecodeMp3(input, out)) {
114
+ return true;
115
+ }
116
+
117
+ // 判定が外れた場合のカスケード
118
+ return DecodeWav(input, out) || DecodeOgg(input, out) || DecodeMp3(input, out);
119
+ }
120
+
121
+ } // namespace next2d
@@ -0,0 +1,18 @@
1
+ // 音声デコード (エンコード済みバイト列 -> float32 interleaved PCM)。
2
+ //
3
+ // 第一候補は dr_mp3 / dr_wav / stb_vorbis (MP3/WAV/OGG、全プラットフォーム共通、
4
+ // public domain)。コンソール (Game Core OS) にはデスクトップの Media Foundation が
5
+ // 無いため、MF 依存を第一経路から外して PC 検証と実機の挙動を一致させる。
6
+ // デスクトップのみ AAC 等の保険として AudioEngine::Decode 側に MF フォールバックが残る。
7
+ #pragma once
8
+
9
+ #include "AudioEngine.h" // PcmBuffer
10
+
11
+ #include <cstdint>
12
+ #include <vector>
13
+
14
+ namespace next2d {
15
+
16
+ bool DecodeAudio(const std::vector<uint8_t>& input, PcmBuffer& out);
17
+
18
+ } // namespace next2d
@@ -1,12 +1,18 @@
1
1
  #include "AudioEngine.h"
2
+ #include "AudioDecoder.h"
2
3
 
3
4
  #include <xaudio2.h>
5
+ #include <iostream>
6
+
7
+ // Media Foundation / shlwapi はコンソール (Game Core OS) に無いデスクトップ専用 API。
8
+ // 第一経路は AudioDecoder (dr_mp3/dr_wav/stb_vorbis) で、MF は AAC 等の
9
+ // デスクトップ限定フォールバックのみ。XAudio2 は両プラットフォームで使える。
10
+ #if !NEXT2D_XBOX_CONSOLE
4
11
  #include <mfapi.h>
5
12
  #include <mfidl.h>
6
13
  #include <mfreadwrite.h>
7
14
  #include <shlwapi.h>
8
15
  #include <wrl/client.h>
9
- #include <iostream>
10
16
 
11
17
  #pragma comment(lib, "mfplat.lib")
12
18
  #pragma comment(lib, "mfreadwrite.lib")
@@ -14,6 +20,7 @@
14
20
  #pragma comment(lib, "shlwapi.lib")
15
21
 
16
22
  using Microsoft::WRL::ComPtr;
23
+ #endif
17
24
 
18
25
  namespace next2d {
19
26
 
@@ -41,6 +48,10 @@ AudioVoice::~AudioVoice()
41
48
 
42
49
  void AudioVoice::Start(bool loop)
43
50
  {
51
+ // 音声デバイスが無い環境 (CI 等) でも「再生開始→即終了」として扱えるよう、
52
+ // voice_ の有無に関わらず開始状態は記録する (IsFinished が ended 発火を導く)。
53
+ started_ = true;
54
+ looping_ = loop;
44
55
  if (!voice_) {
45
56
  return;
46
57
  }
@@ -51,8 +62,6 @@ void AudioVoice::Start(bool loop)
51
62
  buf.LoopCount = loop ? XAUDIO2_LOOP_INFINITE : 0;
52
63
  voice_->SubmitSourceBuffer(&buf);
53
64
  voice_->Start(0);
54
- started_ = true;
55
- looping_ = loop;
56
65
  }
57
66
 
58
67
  void AudioVoice::Stop()
@@ -66,9 +75,13 @@ void AudioVoice::Stop()
66
75
 
67
76
  bool AudioVoice::IsFinished() const
68
77
  {
69
- if (!voice_ || !started_ || looping_) {
78
+ if (!started_ || looping_) {
70
79
  return false;
71
80
  }
81
+ if (!voice_) {
82
+ // 実ボイスが無い (音声デバイス無し) 場合は開始と同時に終了扱い。
83
+ return true;
84
+ }
72
85
  XAUDIO2_VOICE_STATE state = {};
73
86
  voice_->GetState(&state);
74
87
  return state.BuffersQueued == 0;
@@ -91,15 +104,19 @@ AudioEngine::~AudioEngine()
91
104
  if (xaudio_) {
92
105
  xaudio_->Release();
93
106
  }
107
+ #if !NEXT2D_XBOX_CONSOLE
94
108
  MFShutdown();
109
+ #endif
95
110
  }
96
111
 
97
112
  bool AudioEngine::Initialize()
98
113
  {
114
+ #if !NEXT2D_XBOX_CONSOLE
99
115
  if (FAILED(MFStartup(MF_VERSION))) {
100
116
  std::cerr << "[Audio] MFStartup failed" << std::endl;
101
117
  return false;
102
118
  }
119
+ #endif
103
120
  if (FAILED(XAudio2Create(&xaudio_, 0, XAUDIO2_DEFAULT_PROCESSOR))) {
104
121
  std::cerr << "[Audio] XAudio2Create failed" << std::endl;
105
122
  return false;
@@ -113,8 +130,21 @@ bool AudioEngine::Initialize()
113
130
 
114
131
  bool AudioEngine::Decode(const std::vector<uint8_t>& input, PcmBuffer& out)
115
132
  {
116
- // メモリストリームから Media Foundation の SourceReader を作り、
117
- // 32bit float PCM へ変換して読み出す。
133
+ // 第一候補: ポータブルデコーダ (dr_mp3/dr_wav/stb_vorbis)。
134
+ // コンソール (Game Core) には Media Foundation が無いため、共通経路を先に
135
+ // 通すことで PC 検証と実機の挙動を一致させる。
136
+ if (DecodeAudio(input, out)) {
137
+ return true;
138
+ }
139
+
140
+ #if NEXT2D_XBOX_CONSOLE
141
+ // コンソール: MF が無いため共通デコーダで扱えない形式は失敗とする
142
+ // (呼び出し側の graceful degradation = 無音バッファで進行)。
143
+ return false;
144
+ #else
145
+ // フォールバック (デスクトップのみ): Media Foundation の SourceReader。
146
+ // AAC/WMA 等、MP3/WAV/OGG 以外の形式への保険。
147
+ // メモリストリームから 32bit float PCM へ変換して読み出す。
118
148
  ComPtr<IStream> stream =
119
149
  SHCreateMemStream(input.data(), static_cast<UINT>(input.size()));
120
150
  if (!stream) {
@@ -174,6 +204,7 @@ bool AudioEngine::Decode(const std::vector<uint8_t>& input, PcmBuffer& out)
174
204
  }
175
205
 
176
206
  return !out.samples.empty();
207
+ #endif // NEXT2D_XBOX_CONSOLE
177
208
  }
178
209
 
179
210
  std::shared_ptr<AudioVoice> AudioEngine::CreateVoice(std::shared_ptr<PcmBuffer> buffer)
@@ -0,0 +1,136 @@
1
+ #include "DecodeQueue.h"
2
+
3
+ #ifdef _WIN32
4
+ #include <objbase.h>
5
+ #endif
6
+
7
+ #include <algorithm>
8
+ #include <condition_variable>
9
+ #include <deque>
10
+ #include <mutex>
11
+ #include <thread>
12
+ #include <vector>
13
+
14
+ namespace next2d::decodequeue {
15
+
16
+ namespace {
17
+
18
+ struct Job {
19
+ std::function<void()> work;
20
+ std::function<void()> complete;
21
+ };
22
+
23
+ struct Queue {
24
+ std::mutex mutex;
25
+ std::condition_variable cv;
26
+ std::deque<Job> pending; // 未処理 (プールスレッドが取る)
27
+ std::deque<std::function<void()>> done; // work 完了済み (Pump が実行)
28
+ std::vector<std::thread> threads;
29
+ bool stop = false;
30
+
31
+ void ThreadMain()
32
+ {
33
+ #ifdef _WIN32
34
+ // WIC / Media Foundation は COM を要する。プールスレッド毎に MTA で初期化する
35
+ // (per-call 実装なので MTA スレッド間で共有状態は無い)。
36
+ CoInitializeEx(nullptr, COINIT_MULTITHREADED);
37
+ #endif
38
+ for (;;) {
39
+ Job job;
40
+ {
41
+ std::unique_lock<std::mutex> lock(mutex);
42
+ cv.wait(lock, [this] { return stop || !pending.empty(); });
43
+ if (stop) {
44
+ break;
45
+ }
46
+ job = std::move(pending.front());
47
+ pending.pop_front();
48
+ }
49
+ if (job.work) {
50
+ job.work();
51
+ }
52
+ {
53
+ std::lock_guard<std::mutex> lock(mutex);
54
+ done.push_back(std::move(job.complete));
55
+ }
56
+ }
57
+ #ifdef _WIN32
58
+ CoUninitialize();
59
+ #endif
60
+ }
61
+
62
+ void EnsureThreads()
63
+ {
64
+ if (!threads.empty()) {
65
+ return;
66
+ }
67
+ // デコードは CPU バウンド。コア数の半分 (2〜4) で遷移時のバースト
68
+ // (画像数十枚 + BGM) を並列処理しつつ、メイン/GC スレッドを圧迫しない。
69
+ const unsigned hw = std::thread::hardware_concurrency();
70
+ const unsigned count = std::clamp(hw / 2u, 2u, 4u);
71
+ threads.reserve(count);
72
+ for (unsigned i = 0; i < count; ++i) {
73
+ threads.emplace_back([this] { ThreadMain(); });
74
+ }
75
+ }
76
+ };
77
+
78
+ Queue& Q()
79
+ {
80
+ static Queue q;
81
+ return q;
82
+ }
83
+
84
+ } // namespace
85
+
86
+ void Submit(std::function<void()> work, std::function<void()> complete)
87
+ {
88
+ Queue& q = Q();
89
+ {
90
+ std::lock_guard<std::mutex> lock(q.mutex);
91
+ if (q.stop) {
92
+ return; // Shutdown 後の Submit は破棄 (終了処理中のロード要求)
93
+ }
94
+ q.EnsureThreads();
95
+ q.pending.push_back({std::move(work), std::move(complete)});
96
+ }
97
+ q.cv.notify_one();
98
+ }
99
+
100
+ void Pump()
101
+ {
102
+ Queue& q = Q();
103
+ std::deque<std::function<void()>> ready;
104
+ {
105
+ std::lock_guard<std::mutex> lock(q.mutex);
106
+ ready.swap(q.done);
107
+ }
108
+ for (auto& complete : ready) {
109
+ if (complete) {
110
+ complete();
111
+ }
112
+ }
113
+ }
114
+
115
+ void Shutdown()
116
+ {
117
+ Queue& q = Q();
118
+ {
119
+ std::lock_guard<std::mutex> lock(q.mutex);
120
+ q.stop = true;
121
+ }
122
+ q.cv.notify_all();
123
+ for (auto& t : q.threads) {
124
+ if (t.joinable()) {
125
+ t.join();
126
+ }
127
+ }
128
+ q.threads.clear();
129
+ // 未実行の work / complete を破棄する。complete は v8::Global を捕捉して
130
+ // いるため、この関数は Isolate 破棄前に呼ばれる必要がある (main.cpp の後始末順)。
131
+ std::lock_guard<std::mutex> lock(q.mutex);
132
+ q.pending.clear();
133
+ q.done.clear();
134
+ }
135
+
136
+ } // namespace next2d::decodequeue
@@ -0,0 +1,27 @@
1
+ // DecodeQueue: リソースデコード用のバックグラウンドスレッドプール。
2
+ //
3
+ // 画像 (WIC) / 音声 (Media Foundation) のデコードはメインスレッドで同期実行すると
4
+ // 画面遷移時に 1 秒超のフレームヒッチになる (--perf 計測で特定)。work を
5
+ // プールスレッドへ逃がし、complete をメインループの Pump() で実行することで
6
+ // ヒッチを解消し、複数リソースの並列デコードでロード時間も短縮する。
7
+ // スレッドは Xbox で許可されている (禁止は動的コード生成のみ)。
8
+ //
9
+ // 契約:
10
+ // - work : プールスレッドで実行される。V8 / JS ヒープに触れてはならない。
11
+ // (WIC/MF は per-call 実装で COM はスレッド毎に MTA 初期化済み)
12
+ // - complete: work 完了後、メインスレッドの Pump() から実行される。V8 可。
13
+ // (v8::Global を捕捉してよい。Pump は isolate/コンテキストスコープ外で
14
+ // 呼ばれるため、complete 側で HandleScope/Context::Scope を張ること)
15
+ // - Shutdown: 全スレッドを join し、未実行の work / complete を破棄する。
16
+ // 捕捉された v8::Global の破棄があるため Isolate 破棄前に呼ぶこと。
17
+ #pragma once
18
+
19
+ #include <functional>
20
+
21
+ namespace next2d::decodequeue {
22
+
23
+ void Submit(std::function<void()> work, std::function<void()> complete);
24
+ void Pump();
25
+ void Shutdown();
26
+
27
+ } // namespace next2d::decodequeue
@@ -0,0 +1,44 @@
1
+ #include "ImageDecoder.h"
2
+
3
+ // stb_image: public domain のヘッダオンリー画像デコーダ (third_party/)。
4
+ // メモリ入力のみ使用するため stdio を切る。
5
+ #define STB_IMAGE_IMPLEMENTATION
6
+ #define STBI_NO_STDIO
7
+ #include "third_party/stb_image.h"
8
+
9
+ #if defined(_WIN32) && !NEXT2D_XBOX_CONSOLE
10
+ #include "WicDecoder.h"
11
+ #endif
12
+
13
+ #include <cstring>
14
+
15
+ namespace next2d {
16
+
17
+ bool DecodeImage(const std::vector<uint8_t>& input, DecodedImage& out)
18
+ {
19
+ if (input.empty()) {
20
+ return false;
21
+ }
22
+
23
+ // 1) stb_image (PNG/JPEG/GIF/BMP/TGA/PSD)。コンソールでも動く共通経路。
24
+ int w = 0, h = 0, comp = 0;
25
+ stbi_uc* pixels = stbi_load_from_memory(
26
+ input.data(), static_cast<int>(input.size()), &w, &h, &comp, 4);
27
+ if (pixels) {
28
+ out.width = static_cast<uint32_t>(w);
29
+ out.height = static_cast<uint32_t>(h);
30
+ out.rgba.assign(pixels, pixels + static_cast<size_t>(w) * h * 4);
31
+ stbi_image_free(pixels);
32
+ return true;
33
+ }
34
+
35
+ #if defined(_WIN32) && !NEXT2D_XBOX_CONSOLE
36
+ // 2) デスクトップのみ: WIC フォールバック (TIFF/HEIF 等 stb 非対応形式の保険)。
37
+ // コンソールには WIC が無いためこの経路はコンパイルされない。
38
+ return DecodeImageWithWIC(input, out);
39
+ #else
40
+ return false;
41
+ #endif
42
+ }
43
+
44
+ } // namespace next2d
@@ -0,0 +1,18 @@
1
+ // 画像デコード (エンコード済みバイト列 -> RGBA8)。
2
+ //
3
+ // 第一候補は stb_image (PNG/JPEG/GIF/BMP、全プラットフォーム共通)。
4
+ // コンソール (Game Core OS) には WIC が存在しないため、WIC 依存を第一経路から
5
+ // 外すことで PC 検証と実機の挙動を一致させる。デスクトップのみ、stb が扱えない
6
+ // 形式 (TIFF/HEIF 等) への保険として WIC フォールバックを残す。
7
+ #pragma once
8
+
9
+ #include "ImageTypes.h"
10
+
11
+ #include <cstdint>
12
+ #include <vector>
13
+
14
+ namespace next2d {
15
+
16
+ bool DecodeImage(const std::vector<uint8_t>& input, DecodedImage& out);
17
+
18
+ } // namespace next2d