swf-toolkit 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +125 -2
- package/README.tr.md +126 -0
- package/dist/abc/abc-file.d.ts +168 -0
- package/dist/abc/abc-file.js +656 -0
- package/dist/abc/analysis.d.ts +36 -0
- package/dist/abc/analysis.js +213 -0
- package/dist/abc/code.d.ts +59 -0
- package/dist/abc/code.js +379 -0
- package/dist/abc/constants.d.ts +80 -0
- package/dist/abc/constants.js +93 -0
- package/dist/abc/interner.d.ts +46 -0
- package/dist/abc/interner.js +168 -0
- package/dist/abc/model.d.ts +40 -0
- package/dist/abc/model.js +146 -0
- package/dist/abc/opcodes.d.ts +39 -0
- package/dist/abc/opcodes.js +196 -0
- package/dist/abc/pcode/assembler.d.ts +42 -0
- package/dist/abc/pcode/assembler.js +635 -0
- package/dist/abc/pcode/disassembler.d.ts +17 -0
- package/dist/abc/pcode/disassembler.js +147 -0
- package/dist/abc/pcode/format.d.ts +23 -0
- package/dist/abc/pcode/format.js +131 -0
- package/dist/abc/pcode/lexer.d.ts +34 -0
- package/dist/abc/pcode/lexer.js +183 -0
- package/dist/assets/assets.d.ts +26 -0
- package/dist/assets/assets.js +151 -0
- package/dist/assets/images.d.ts +31 -0
- package/dist/assets/images.js +238 -0
- package/dist/assets/png.d.ts +12 -0
- package/dist/assets/png.js +196 -0
- package/dist/assets/sounds.d.ts +37 -0
- package/dist/assets/sounds.js +236 -0
- package/dist/avm1/avm1.d.ts +55 -0
- package/dist/avm1/avm1.js +642 -0
- package/dist/avm1/project.d.ts +16 -0
- package/dist/avm1/project.js +81 -0
- package/dist/cjs/abc/abc-file.d.ts +168 -0
- package/dist/cjs/abc/abc-file.js +663 -0
- package/dist/cjs/abc/analysis.d.ts +36 -0
- package/dist/cjs/abc/analysis.js +221 -0
- package/dist/cjs/abc/code.d.ts +59 -0
- package/dist/cjs/abc/code.js +387 -0
- package/dist/cjs/abc/constants.d.ts +80 -0
- package/dist/cjs/abc/constants.js +97 -0
- package/dist/cjs/abc/interner.d.ts +46 -0
- package/dist/cjs/abc/interner.js +172 -0
- package/dist/cjs/abc/model.d.ts +40 -0
- package/dist/cjs/abc/model.js +155 -0
- package/dist/cjs/abc/opcodes.d.ts +39 -0
- package/dist/cjs/abc/opcodes.js +201 -0
- package/dist/cjs/abc/pcode/assembler.d.ts +42 -0
- package/dist/cjs/abc/pcode/assembler.js +640 -0
- package/dist/cjs/abc/pcode/disassembler.d.ts +17 -0
- package/dist/cjs/abc/pcode/disassembler.js +152 -0
- package/dist/cjs/abc/pcode/format.d.ts +23 -0
- package/dist/cjs/abc/pcode/format.js +141 -0
- package/dist/cjs/abc/pcode/lexer.d.ts +34 -0
- package/dist/cjs/abc/pcode/lexer.js +188 -0
- package/dist/cjs/assets/assets.d.ts +26 -0
- package/dist/cjs/assets/assets.js +159 -0
- package/dist/cjs/assets/images.d.ts +31 -0
- package/dist/cjs/assets/images.js +246 -0
- package/dist/cjs/assets/png.d.ts +12 -0
- package/dist/cjs/assets/png.js +202 -0
- package/dist/cjs/assets/sounds.d.ts +37 -0
- package/dist/cjs/assets/sounds.js +246 -0
- package/dist/cjs/avm1/avm1.d.ts +55 -0
- package/dist/cjs/avm1/avm1.js +649 -0
- package/dist/cjs/avm1/project.d.ts +16 -0
- package/dist/cjs/avm1/project.js +88 -0
- package/dist/cjs/compiler/ast.d.ts +285 -0
- package/dist/cjs/compiler/ast.js +3 -0
- package/dist/cjs/compiler/class-compiler.d.ts +34 -0
- package/dist/cjs/compiler/class-compiler.js +440 -0
- package/dist/cjs/compiler/codegen.d.ts +144 -0
- package/dist/cjs/compiler/codegen.js +1589 -0
- package/dist/cjs/compiler/lexer.d.ts +27 -0
- package/dist/cjs/compiler/lexer.js +254 -0
- package/dist/cjs/compiler/parser.d.ts +58 -0
- package/dist/cjs/compiler/parser.js +989 -0
- package/dist/cjs/compiler/program.d.ts +29 -0
- package/dist/cjs/compiler/program.js +36 -0
- package/dist/cjs/compiler/scope.d.ts +22 -0
- package/dist/cjs/compiler/scope.js +242 -0
- package/dist/cjs/compression/lzma.d.ts +37 -0
- package/dist/cjs/compression/lzma.js +575 -0
- package/dist/cjs/compression/swf-container.d.ts +19 -0
- package/dist/cjs/compression/swf-container.js +92 -0
- package/dist/cjs/decompiler/ast.d.ts +228 -0
- package/dist/cjs/decompiler/ast.js +455 -0
- package/dist/cjs/decompiler/cfg.d.ts +40 -0
- package/dist/cjs/decompiler/cfg.js +236 -0
- package/dist/cjs/decompiler/class-printer.d.ts +9 -0
- package/dist/cjs/decompiler/class-printer.js +173 -0
- package/dist/cjs/decompiler/method.d.ts +41 -0
- package/dist/cjs/decompiler/method.js +436 -0
- package/dist/cjs/decompiler/simulate.d.ts +55 -0
- package/dist/cjs/decompiler/simulate.js +591 -0
- package/dist/cjs/decompiler/structure.d.ts +48 -0
- package/dist/cjs/decompiler/structure.js +764 -0
- package/dist/cjs/errors.d.ts +11 -0
- package/dist/cjs/errors.js +25 -0
- package/dist/cjs/index.d.ts +41 -0
- package/dist/cjs/index.js +82 -0
- package/dist/cjs/io/reader.d.ts +48 -0
- package/dist/cjs/io/reader.js +180 -0
- package/dist/cjs/io/writer.d.ts +37 -0
- package/dist/cjs/io/writer.js +175 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/project/pcode-project.d.ts +32 -0
- package/dist/cjs/project/pcode-project.js +210 -0
- package/dist/cjs/project/source-export.d.ts +12 -0
- package/dist/cjs/project/source-export.js +51 -0
- package/dist/cjs/project/source-import.d.ts +13 -0
- package/dist/cjs/project/source-import.js +73 -0
- package/dist/cjs/swf/swf.d.ts +63 -0
- package/dist/cjs/swf/swf.js +147 -0
- package/dist/cjs/swf/tag-codes.d.ts +77 -0
- package/dist/cjs/swf/tag-codes.js +109 -0
- package/dist/cjs/swf/tags.d.ts +118 -0
- package/dist/cjs/swf/tags.js +330 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +296 -0
- package/dist/compiler/ast.d.ts +285 -0
- package/dist/compiler/ast.js +2 -0
- package/dist/compiler/class-compiler.d.ts +34 -0
- package/dist/compiler/class-compiler.js +437 -0
- package/dist/compiler/codegen.d.ts +144 -0
- package/dist/compiler/codegen.js +1585 -0
- package/dist/compiler/lexer.d.ts +27 -0
- package/dist/compiler/lexer.js +249 -0
- package/dist/compiler/parser.d.ts +58 -0
- package/dist/compiler/parser.js +984 -0
- package/dist/compiler/program.d.ts +29 -0
- package/dist/compiler/program.js +32 -0
- package/dist/compiler/scope.d.ts +22 -0
- package/dist/compiler/scope.js +238 -0
- package/dist/compression/lzma.d.ts +37 -0
- package/dist/compression/lzma.js +569 -0
- package/dist/compression/swf-container.d.ts +19 -0
- package/dist/compression/swf-container.js +87 -0
- package/dist/decompiler/ast.d.ts +228 -0
- package/dist/decompiler/ast.js +441 -0
- package/dist/decompiler/cfg.d.ts +40 -0
- package/dist/decompiler/cfg.js +231 -0
- package/dist/decompiler/class-printer.d.ts +9 -0
- package/dist/decompiler/class-printer.js +170 -0
- package/dist/decompiler/method.d.ts +41 -0
- package/dist/decompiler/method.js +427 -0
- package/dist/decompiler/simulate.d.ts +55 -0
- package/dist/decompiler/simulate.js +586 -0
- package/dist/decompiler/structure.d.ts +48 -0
- package/dist/decompiler/structure.js +760 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +20 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +49 -0
- package/dist/io/reader.d.ts +48 -0
- package/dist/io/reader.js +176 -0
- package/dist/io/writer.d.ts +37 -0
- package/dist/io/writer.js +169 -0
- package/dist/project/pcode-project.d.ts +32 -0
- package/dist/project/pcode-project.js +203 -0
- package/dist/project/source-export.d.ts +12 -0
- package/dist/project/source-export.js +47 -0
- package/dist/project/source-import.d.ts +13 -0
- package/dist/project/source-import.js +70 -0
- package/dist/swf/swf.d.ts +63 -0
- package/dist/swf/swf.js +143 -0
- package/dist/swf/tag-codes.d.ts +77 -0
- package/dist/swf/tag-codes.js +105 -0
- package/dist/swf/tags.d.ts +118 -0
- package/dist/swf/tags.js +316 -0
- package/package.json +71 -4
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SOUND_RATES = void 0;
|
|
4
|
+
exports.parseDefineSound = parseDefineSound;
|
|
5
|
+
exports.encodeWav = encodeWav;
|
|
6
|
+
exports.decodeAdpcm = decodeAdpcm;
|
|
7
|
+
exports.extractSound = extractSound;
|
|
8
|
+
exports.parseMp3 = parseMp3;
|
|
9
|
+
exports.encodeDefineSound = encodeDefineSound;
|
|
10
|
+
exports.replaceSound = replaceSound;
|
|
11
|
+
/**
|
|
12
|
+
* DefineSound ↔ audio files: MP3 passthrough, uncompressed PCM / ADPCM → WAV,
|
|
13
|
+
* MP3 / WAV import.
|
|
14
|
+
*/
|
|
15
|
+
const reader_js_1 = require("../io/reader.js");
|
|
16
|
+
const writer_js_1 = require("../io/writer.js");
|
|
17
|
+
const tag_codes_js_1 = require("../swf/tag-codes.js");
|
|
18
|
+
const tags_js_1 = require("../swf/tags.js");
|
|
19
|
+
exports.SOUND_RATES = [5512, 11025, 22050, 44100];
|
|
20
|
+
function parseDefineSound(tag) {
|
|
21
|
+
const r = new reader_js_1.ByteReader(tag.data);
|
|
22
|
+
const id = r.u16();
|
|
23
|
+
const flags = r.u8();
|
|
24
|
+
return {
|
|
25
|
+
id,
|
|
26
|
+
format: flags >> 4,
|
|
27
|
+
rate: exports.SOUND_RATES[(flags >> 2) & 3],
|
|
28
|
+
bits: flags & 2 ? 16 : 8,
|
|
29
|
+
channels: flags & 1 ? 2 : 1,
|
|
30
|
+
sampleCount: r.u32(),
|
|
31
|
+
data: r.rest(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function encodeWav(pcm, rate, channels, bits) {
|
|
35
|
+
const w = new writer_js_1.ByteWriter(pcm.length + 44);
|
|
36
|
+
const str = (s) => {
|
|
37
|
+
for (const c of s)
|
|
38
|
+
w.u8(c.charCodeAt(0));
|
|
39
|
+
};
|
|
40
|
+
str('RIFF');
|
|
41
|
+
w.u32(36 + pcm.length);
|
|
42
|
+
str('WAVE');
|
|
43
|
+
str('fmt ');
|
|
44
|
+
w.u32(16).u16(1).u16(channels).u32(rate).u32((rate * channels * bits) / 8).u16((channels * bits) / 8).u16(bits);
|
|
45
|
+
str('data');
|
|
46
|
+
w.u32(pcm.length);
|
|
47
|
+
w.bytes(pcm);
|
|
48
|
+
return w.toBytes();
|
|
49
|
+
}
|
|
50
|
+
const STEP_TABLE = [
|
|
51
|
+
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190,
|
|
52
|
+
209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499,
|
|
53
|
+
2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385,
|
|
54
|
+
24623, 27086, 29794, 32767,
|
|
55
|
+
];
|
|
56
|
+
const INDEX_TABLES = [
|
|
57
|
+
[-1, 2],
|
|
58
|
+
[-1, -1, 2, 4],
|
|
59
|
+
[-1, -1, -1, -1, 2, 4, 6, 8],
|
|
60
|
+
[-1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16],
|
|
61
|
+
];
|
|
62
|
+
/** Decodes SWF ADPCM to 16-bit little-endian PCM. */
|
|
63
|
+
function decodeAdpcm(data, channels, sampleCount) {
|
|
64
|
+
const r = new reader_js_1.ByteReader(data);
|
|
65
|
+
const bitsTotal = data.length * 8;
|
|
66
|
+
let bitsRead = 0;
|
|
67
|
+
const ub = (n) => {
|
|
68
|
+
bitsRead += n;
|
|
69
|
+
return r.ub(n);
|
|
70
|
+
};
|
|
71
|
+
const sb = (n) => {
|
|
72
|
+
bitsRead += n;
|
|
73
|
+
return r.sb(n);
|
|
74
|
+
};
|
|
75
|
+
const nb = ub(2) + 2;
|
|
76
|
+
const table = INDEX_TABLES[nb - 2];
|
|
77
|
+
const signMask = 1 << (nb - 1);
|
|
78
|
+
const out = new Int16Array(sampleCount * channels);
|
|
79
|
+
let o = 0;
|
|
80
|
+
const pred = [0, 0];
|
|
81
|
+
const index = [0, 0];
|
|
82
|
+
outer: while (o < out.length) {
|
|
83
|
+
if (bitsRead + channels * 22 > bitsTotal)
|
|
84
|
+
break;
|
|
85
|
+
for (let c = 0; c < channels; c++) {
|
|
86
|
+
pred[c] = sb(16);
|
|
87
|
+
index[c] = ub(6);
|
|
88
|
+
out[o++] = pred[c];
|
|
89
|
+
}
|
|
90
|
+
for (let i = 0; i < 4095 && o < out.length; i++) {
|
|
91
|
+
for (let c = 0; c < channels; c++) {
|
|
92
|
+
if (bitsRead + nb > bitsTotal)
|
|
93
|
+
break outer;
|
|
94
|
+
const code = ub(nb);
|
|
95
|
+
let step = STEP_TABLE[index[c]];
|
|
96
|
+
let diff = step >> (nb - 1);
|
|
97
|
+
for (let k = signMask >> 1; k; k >>= 1) {
|
|
98
|
+
if (code & k)
|
|
99
|
+
diff += step;
|
|
100
|
+
step >>= 1;
|
|
101
|
+
}
|
|
102
|
+
let p = pred[c] + (code & signMask ? -diff : diff);
|
|
103
|
+
p = Math.max(-32768, Math.min(32767, p));
|
|
104
|
+
pred[c] = p;
|
|
105
|
+
index[c] = Math.max(0, Math.min(88, index[c] + table[code & ~signMask]));
|
|
106
|
+
out[o++] = p;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return new Uint8Array(out.buffer, 0, o * 2);
|
|
111
|
+
}
|
|
112
|
+
function extractSound(tag) {
|
|
113
|
+
if (!(tag instanceof tags_js_1.RawTag) || tag.code !== tag_codes_js_1.TagCode.DefineSound)
|
|
114
|
+
return undefined;
|
|
115
|
+
const s = parseDefineSound(tag);
|
|
116
|
+
const { data, ...info } = s;
|
|
117
|
+
switch (s.format) {
|
|
118
|
+
case 2:
|
|
119
|
+
return { id: s.id, ext: 'mp3', data: data.subarray(2).slice(), info };
|
|
120
|
+
case 0:
|
|
121
|
+
case 3:
|
|
122
|
+
return { id: s.id, ext: 'wav', data: encodeWav(data, s.rate, s.channels, s.bits), info };
|
|
123
|
+
case 1:
|
|
124
|
+
return { id: s.id, ext: 'wav', data: encodeWav(decodeAdpcm(data, s.channels, s.sampleCount), s.rate, s.channels, 16), info };
|
|
125
|
+
case 11:
|
|
126
|
+
return { id: s.id, ext: 'speex', data: data.slice(), info };
|
|
127
|
+
default:
|
|
128
|
+
return { id: s.id, ext: 'nelly', data: data.slice(), info };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Import
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
const MP3_BITRATES = {
|
|
135
|
+
v1: [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
|
|
136
|
+
v2: [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160],
|
|
137
|
+
};
|
|
138
|
+
const MP3_RATES = { 3: [44100, 48000, 32000], 2: [22050, 24000, 16000], 0: [11025, 12000, 8000] };
|
|
139
|
+
function parseMp3(b) {
|
|
140
|
+
let i = 0;
|
|
141
|
+
if (b[0] === 0x49 && b[1] === 0x44 && b[2] === 0x33) {
|
|
142
|
+
const size = ((b[6] & 0x7f) << 21) | ((b[7] & 0x7f) << 14) | ((b[8] & 0x7f) << 7) | (b[9] & 0x7f);
|
|
143
|
+
i = 10 + size;
|
|
144
|
+
}
|
|
145
|
+
let start = -1;
|
|
146
|
+
let rate = 0;
|
|
147
|
+
let channels = 2;
|
|
148
|
+
let samples = 0;
|
|
149
|
+
let end = i;
|
|
150
|
+
while (i + 4 <= b.length) {
|
|
151
|
+
if (b[i] !== 0xff || (b[i + 1] & 0xe0) !== 0xe0) {
|
|
152
|
+
if (start >= 0)
|
|
153
|
+
break;
|
|
154
|
+
i++;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const version = (b[i + 1] >> 3) & 3; // 3 = MPEG1, 2 = MPEG2, 0 = MPEG2.5
|
|
158
|
+
const layer = (b[i + 1] >> 1) & 3; // 1 = layer III
|
|
159
|
+
const brIdx = b[i + 2] >> 4;
|
|
160
|
+
const srIdx = (b[i + 2] >> 2) & 3;
|
|
161
|
+
const pad = (b[i + 2] >> 1) & 1;
|
|
162
|
+
if (version === 1 || layer !== 1 || brIdx === 0 || brIdx === 15 || srIdx === 3) {
|
|
163
|
+
if (start >= 0)
|
|
164
|
+
break;
|
|
165
|
+
i++;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const sr = MP3_RATES[version][srIdx];
|
|
169
|
+
const br = (version === 3 ? MP3_BITRATES.v1 : MP3_BITRATES.v2)[brIdx] * 1000;
|
|
170
|
+
const len = Math.floor(((version === 3 ? 144 : 72) * br) / sr) + pad;
|
|
171
|
+
if (start < 0) {
|
|
172
|
+
start = i;
|
|
173
|
+
rate = sr;
|
|
174
|
+
channels = (b[i + 3] >> 6) === 3 ? 1 : 2;
|
|
175
|
+
}
|
|
176
|
+
samples += version === 3 ? 1152 : 576;
|
|
177
|
+
i += len;
|
|
178
|
+
end = Math.min(i, b.length);
|
|
179
|
+
}
|
|
180
|
+
if (start < 0)
|
|
181
|
+
throw new Error('No MP3 frames found');
|
|
182
|
+
return { rate, channels, sampleCount: samples, start, end };
|
|
183
|
+
}
|
|
184
|
+
function rateCode(rate) {
|
|
185
|
+
const i = exports.SOUND_RATES.indexOf(rate === 5513 ? 5512 : rate);
|
|
186
|
+
if (i < 0)
|
|
187
|
+
throw new Error(`Sample rate ${rate} Hz is not supported by SWF (use 5512, 11025, 22050 or 44100)`);
|
|
188
|
+
return i;
|
|
189
|
+
}
|
|
190
|
+
/** Builds a DefineSound body from an MP3 or WAV file. */
|
|
191
|
+
function encodeDefineSound(id, file) {
|
|
192
|
+
const w = new writer_js_1.ByteWriter(file.length + 16);
|
|
193
|
+
const isWav = file[0] === 0x52 && file[1] === 0x49 && file[2] === 0x46 && file[3] === 0x46;
|
|
194
|
+
if (isWav) {
|
|
195
|
+
const r = new reader_js_1.ByteReader(file, 12);
|
|
196
|
+
let fmt;
|
|
197
|
+
let pcm;
|
|
198
|
+
while (r.remaining >= 8) {
|
|
199
|
+
const ck = String.fromCharCode(...r.bytesView(4));
|
|
200
|
+
const len = r.u32();
|
|
201
|
+
const body = r.bytesView(Math.min(len, r.remaining));
|
|
202
|
+
if (ck === 'fmt ') {
|
|
203
|
+
const f = new reader_js_1.ByteReader(body);
|
|
204
|
+
if (f.u16() !== 1)
|
|
205
|
+
throw new Error('Only PCM WAV files are supported');
|
|
206
|
+
fmt = { channels: f.u16(), rate: f.u32(), bits: (f.u32(), f.u16(), f.u16()) };
|
|
207
|
+
}
|
|
208
|
+
else if (ck === 'data')
|
|
209
|
+
pcm = body;
|
|
210
|
+
if (len & 1 && r.remaining)
|
|
211
|
+
r.u8();
|
|
212
|
+
}
|
|
213
|
+
if (!fmt || !pcm)
|
|
214
|
+
throw new Error('Invalid WAV file');
|
|
215
|
+
if (fmt.bits !== 8 && fmt.bits !== 16)
|
|
216
|
+
throw new Error('WAV must be 8 or 16 bit');
|
|
217
|
+
if (fmt.channels !== 1 && fmt.channels !== 2)
|
|
218
|
+
throw new Error('WAV must be mono or stereo');
|
|
219
|
+
w.u16(id);
|
|
220
|
+
w.u8((3 << 4) | (rateCode(fmt.rate) << 2) | (fmt.bits === 16 ? 2 : 0) | (fmt.channels === 2 ? 1 : 0));
|
|
221
|
+
w.u32(pcm.length / ((fmt.bits / 8) * fmt.channels));
|
|
222
|
+
w.bytes(pcm);
|
|
223
|
+
return w.toBytes();
|
|
224
|
+
}
|
|
225
|
+
const mp3 = parseMp3(file);
|
|
226
|
+
w.u16(id);
|
|
227
|
+
w.u8((2 << 4) | (rateCode(mp3.rate) << 2) | 2 | (mp3.channels === 2 ? 1 : 0));
|
|
228
|
+
w.u32(mp3.sampleCount);
|
|
229
|
+
w.s16(0); // seek samples
|
|
230
|
+
w.bytes(file.subarray(mp3.start, mp3.end));
|
|
231
|
+
return w.toBytes();
|
|
232
|
+
}
|
|
233
|
+
/** Replaces DefineSound `id` with an MP3 or WAV file. */
|
|
234
|
+
function replaceSound(swf, id, file) {
|
|
235
|
+
for (const { tag, parent, index } of swf.walkTags()) {
|
|
236
|
+
if (tag.characterId !== id)
|
|
237
|
+
continue;
|
|
238
|
+
if (tag.code !== tag_codes_js_1.TagCode.DefineSound)
|
|
239
|
+
throw new Error(`Character ${id} is a ${tag.name}, not a sound`);
|
|
240
|
+
const next = new tags_js_1.RawTag(tag_codes_js_1.TagCode.DefineSound, encodeDefineSound(id, file));
|
|
241
|
+
next.longHeader = true;
|
|
242
|
+
(parent ? parent.tags : swf.tags)[index] = next;
|
|
243
|
+
return next;
|
|
244
|
+
}
|
|
245
|
+
throw new Error(`No character with id ${id}`);
|
|
246
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type Avm1Value = {
|
|
2
|
+
t: 'string';
|
|
3
|
+
v: string;
|
|
4
|
+
} | {
|
|
5
|
+
t: 'float';
|
|
6
|
+
v: number;
|
|
7
|
+
} | {
|
|
8
|
+
t: 'null';
|
|
9
|
+
} | {
|
|
10
|
+
t: 'undefined';
|
|
11
|
+
} | {
|
|
12
|
+
t: 'register';
|
|
13
|
+
v: number;
|
|
14
|
+
} | {
|
|
15
|
+
t: 'boolean';
|
|
16
|
+
v: boolean;
|
|
17
|
+
} | {
|
|
18
|
+
t: 'double';
|
|
19
|
+
v: number;
|
|
20
|
+
} | {
|
|
21
|
+
t: 'integer';
|
|
22
|
+
v: number;
|
|
23
|
+
} | {
|
|
24
|
+
t: 'constant8';
|
|
25
|
+
v: number;
|
|
26
|
+
} | {
|
|
27
|
+
t: 'constant16';
|
|
28
|
+
v: number;
|
|
29
|
+
};
|
|
30
|
+
export interface Avm1Action {
|
|
31
|
+
type: 'action';
|
|
32
|
+
code: number;
|
|
33
|
+
/** Operands; label ids are numbers in `labels`. */
|
|
34
|
+
args: unknown[];
|
|
35
|
+
/** Label operands (jump target / block ends), in action-specific order. */
|
|
36
|
+
labels: number[];
|
|
37
|
+
/** Unknown action payload (kept verbatim). */
|
|
38
|
+
raw?: Uint8Array;
|
|
39
|
+
}
|
|
40
|
+
export interface Avm1Label {
|
|
41
|
+
type: 'label';
|
|
42
|
+
id: number;
|
|
43
|
+
}
|
|
44
|
+
export type Avm1Item = Avm1Action | Avm1Label;
|
|
45
|
+
export declare function actionName(code: number): string;
|
|
46
|
+
/** Decodes AVM1 action bytes. Branches and block sizes become labels. */
|
|
47
|
+
export declare function decodeActions(bytes: Uint8Array): Avm1Item[];
|
|
48
|
+
/** Encodes an action list back to bytes. Sizes are fixed-point iterated (branches never change length). */
|
|
49
|
+
export declare function encodeActions(items: readonly Avm1Item[]): Uint8Array;
|
|
50
|
+
/** Formats actions as editable AS1/AS2 P-code. */
|
|
51
|
+
export declare function formatActions(items: readonly Avm1Item[], options?: {
|
|
52
|
+
constantPool?: string[];
|
|
53
|
+
}): string;
|
|
54
|
+
/** Parses P-code produced by {@link formatActions}. */
|
|
55
|
+
export declare function parseActions(text: string): Avm1Item[];
|