@modplayjs/fmt-prowizard 0.0.0-stage → 0.2.1

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 (110) hide show
  1. package/README.md +42 -2
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +7 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/prowiz.d.ts +44 -0
  7. package/dist/prowiz.d.ts.map +1 -0
  8. package/dist/prowiz.js +157 -0
  9. package/dist/prowiz.js.map +1 -0
  10. package/dist/ptktable.d.ts +5 -0
  11. package/dist/ptktable.d.ts.map +1 -0
  12. package/dist/ptktable.js +49 -0
  13. package/dist/ptktable.js.map +1 -0
  14. package/dist/pw-ac1d.d.ts +4 -0
  15. package/dist/pw-ac1d.d.ts.map +1 -0
  16. package/dist/pw-ac1d.js +133 -0
  17. package/dist/pw-ac1d.js.map +1 -0
  18. package/dist/pw-di.d.ts +4 -0
  19. package/dist/pw-di.d.ts.map +1 -0
  20. package/dist/pw-di.js +177 -0
  21. package/dist/pw-di.js.map +1 -0
  22. package/dist/pw-eureka.d.ts +4 -0
  23. package/dist/pw-eureka.d.ts.map +1 -0
  24. package/dist/pw-eureka.js +171 -0
  25. package/dist/pw-eureka.js.map +1 -0
  26. package/dist/pw-fcm.d.ts +4 -0
  27. package/dist/pw-fcm.d.ts.map +1 -0
  28. package/dist/pw-fcm.js +102 -0
  29. package/dist/pw-fcm.js.map +1 -0
  30. package/dist/pw-fuchs.d.ts +4 -0
  31. package/dist/pw-fuchs.d.ts.map +1 -0
  32. package/dist/pw-fuchs.js +139 -0
  33. package/dist/pw-fuchs.js.map +1 -0
  34. package/dist/pw-heatseek.d.ts +4 -0
  35. package/dist/pw-heatseek.d.ts.map +1 -0
  36. package/dist/pw-heatseek.js +197 -0
  37. package/dist/pw-heatseek.js.map +1 -0
  38. package/dist/pw-hrt.d.ts +4 -0
  39. package/dist/pw-hrt.d.ts.map +1 -0
  40. package/dist/pw-hrt.js +104 -0
  41. package/dist/pw-hrt.js.map +1 -0
  42. package/dist/pw-ksm.d.ts +4 -0
  43. package/dist/pw-ksm.d.ts.map +1 -0
  44. package/dist/pw-ksm.js +212 -0
  45. package/dist/pw-ksm.js.map +1 -0
  46. package/dist/pw-mp.d.ts +6 -0
  47. package/dist/pw-mp.d.ts.map +1 -0
  48. package/dist/pw-mp.js +171 -0
  49. package/dist/pw-mp.js.map +1 -0
  50. package/dist/pw-np12.d.ts +6 -0
  51. package/dist/pw-np12.d.ts.map +1 -0
  52. package/dist/pw-np12.js +234 -0
  53. package/dist/pw-np12.js.map +1 -0
  54. package/dist/pw-np3.d.ts +4 -0
  55. package/dist/pw-np3.d.ts.map +1 -0
  56. package/dist/pw-np3.js +218 -0
  57. package/dist/pw-np3.js.map +1 -0
  58. package/dist/pw-p40.d.ts +4 -0
  59. package/dist/pw-p40.d.ts.map +1 -0
  60. package/dist/pw-p40.js +221 -0
  61. package/dist/pw-p40.js.map +1 -0
  62. package/dist/pw-plugin.d.ts +8 -0
  63. package/dist/pw-plugin.d.ts.map +1 -0
  64. package/dist/pw-plugin.js +27 -0
  65. package/dist/pw-plugin.js.map +1 -0
  66. package/dist/pw-pp.d.ts +8 -0
  67. package/dist/pw-pp.d.ts.map +1 -0
  68. package/dist/pw-pp.js +341 -0
  69. package/dist/pw-pp.js.map +1 -0
  70. package/dist/pw-skyt.d.ts +4 -0
  71. package/dist/pw-skyt.d.ts.map +1 -0
  72. package/dist/pw-skyt.js +116 -0
  73. package/dist/pw-skyt.js.map +1 -0
  74. package/dist/pw-starpack.d.ts +4 -0
  75. package/dist/pw-starpack.d.ts.map +1 -0
  76. package/dist/pw-starpack.js +253 -0
  77. package/dist/pw-starpack.js.map +1 -0
  78. package/dist/pw-theplayer.d.ts +6 -0
  79. package/dist/pw-theplayer.d.ts.map +1 -0
  80. package/dist/pw-theplayer.js +367 -0
  81. package/dist/pw-theplayer.js.map +1 -0
  82. package/dist/pw-tp1.d.ts +4 -0
  83. package/dist/pw-tp1.d.ts.map +1 -0
  84. package/dist/pw-tp1.js +162 -0
  85. package/dist/pw-tp1.js.map +1 -0
  86. package/dist/pw-tp3.d.ts +6 -0
  87. package/dist/pw-tp3.d.ts.map +1 -0
  88. package/dist/pw-tp3.js +217 -0
  89. package/dist/pw-tp3.js.map +1 -0
  90. package/dist/pw-unic.d.ts +8 -0
  91. package/dist/pw-unic.d.ts.map +1 -0
  92. package/dist/pw-unic.js +285 -0
  93. package/dist/pw-unic.js.map +1 -0
  94. package/dist/pw-unic2.d.ts +4 -0
  95. package/dist/pw-unic2.d.ts.map +1 -0
  96. package/dist/pw-unic2.js +173 -0
  97. package/dist/pw-unic2.js.map +1 -0
  98. package/dist/pw-wn.d.ts +4 -0
  99. package/dist/pw-wn.d.ts.map +1 -0
  100. package/dist/pw-wn.js +82 -0
  101. package/dist/pw-wn.js.map +1 -0
  102. package/dist/pw-xann.d.ts +4 -0
  103. package/dist/pw-xann.d.ts.map +1 -0
  104. package/dist/pw-xann.js +220 -0
  105. package/dist/pw-xann.js.map +1 -0
  106. package/dist/pw-zen.d.ts +4 -0
  107. package/dist/pw-zen.d.ts.map +1 -0
  108. package/dist/pw-zen.js +162 -0
  109. package/dist/pw-zen.js.map +1 -0
  110. package/package.json +49 -4
package/dist/pw-mp.js ADDED
@@ -0,0 +1,171 @@
1
+ // SPDX-License-Identifier: BSD-3-Clause
2
+ // Copyright (c) 2026 Bitti09 — modplayjs contributors
3
+ // Ported from: libxmp src/loaders/prowizard/mp.c (Module Protector, id +
4
+ // noID variants share depack_mp :36-80; test_mp_id :177-212, test_mp_noid
5
+ // :82-173).
6
+ import { readmem16b, readmem32b, moveData, writeZero, pwReadTitle } from './prowiz.js';
7
+ const MAGIC_TRK1 = 0x54524b31; // 'TRK1'
8
+ const PW_MOD_MAGIC = 0x4d2e4b2e; // 'M.K.'
9
+ function put8(out, b) { out.push(b & 0xff); }
10
+ function put16b(out, v) { out.push((v >> 8) & 0xff, v & 0xff); }
11
+ function put32b(out, v) {
12
+ out.push((v >>> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);
13
+ }
14
+ /** depack_mp (mp.c:36-80). */
15
+ function depackMp(data, start) {
16
+ let pos = start;
17
+ const out = [];
18
+ const u8 = () => data[pos++] ?? 0;
19
+ const u16 = () => { const v = readmem16b(data, pos); pos += 2; return v; };
20
+ const u32 = () => { const v = readmem32b(data, pos); pos += 4; return v; };
21
+ writeZero(out, 20); // title
22
+ // TRK1 magic present → skip it; otherwise rewind (mp.c:48-49)
23
+ if (u32() !== MAGIC_TRK1)
24
+ pos -= 4;
25
+ // Sample headers (mp.c:51-59)
26
+ let ssize = 0;
27
+ for (let i = 0; i < 31; i++) {
28
+ writeZero(out, 22); // name
29
+ const size = u16();
30
+ ssize += size * 2;
31
+ put16b(out, size);
32
+ put8(out, u8()); // finetune
33
+ put8(out, u8()); // volume
34
+ put16b(out, u16()); // loop start
35
+ put16b(out, u16()); // loop size
36
+ }
37
+ put8(out, u8()); // pattern table length
38
+ put8(out, u8()); // NoiseTracker restart byte
39
+ // Pattern list (mp.c:64-69)
40
+ let max = 0;
41
+ for (let i = 0; i < 128; i++) {
42
+ const c1 = u8();
43
+ put8(out, c1);
44
+ if (c1 > max)
45
+ max = c1;
46
+ }
47
+ max++;
48
+ put32b(out, PW_MOD_MAGIC);
49
+ // Bypass unknown empty bytes (mp.c:73-74)
50
+ if (u32() !== 0)
51
+ pos -= 4;
52
+ // Pattern + sample data (mp.c:76-77)
53
+ moveData(data, pos, out, 1024 * max);
54
+ pos += 1024 * max;
55
+ moveData(data, pos, out, ssize);
56
+ return Uint8Array.from(out);
57
+ }
58
+ /** test_mp_noid (mp.c:82-173). */
59
+ function testMpNoid(data, start) {
60
+ const s = data.length - start;
61
+ if (s < 378)
62
+ return 378 - s;
63
+ // test #2 (mp.c:86-120): 31 × 8-byte sample headers
64
+ let hdrSsize = 0;
65
+ for (let i = 0; i < 31; i++) {
66
+ const d = start + i * 8;
67
+ const size = readmem16b(data, d) << 1;
68
+ const lstart = readmem16b(data, d + 4) << 1;
69
+ const lsize = readmem16b(data, d + 6) << 1;
70
+ hdrSsize += size;
71
+ if (data[d + 2] > 0x0f)
72
+ return -1;
73
+ if (lsize !== 2 && lstart + lsize > size)
74
+ return -1;
75
+ if (lsize > size + 2)
76
+ return -1;
77
+ if (lstart !== 0 && lsize <= 2)
78
+ return -1;
79
+ if (size !== 0 && lsize === 0)
80
+ return -1;
81
+ }
82
+ if (hdrSsize <= 2)
83
+ return -1;
84
+ // test #3 (mp.c:122-127)
85
+ const len = data[start + 248];
86
+ if (len === 0 || len > 0x7f)
87
+ return -1;
88
+ // test #4 (mp.c:129-142)
89
+ let psize = 0;
90
+ for (let i = 0; i < 128; i++) {
91
+ const pat = data[start + 250 + i];
92
+ if (pat > 0x7f)
93
+ return -1;
94
+ if (pat > psize)
95
+ psize = pat;
96
+ if (i > len + 3 && pat !== 0)
97
+ return -1;
98
+ }
99
+ psize++;
100
+ psize <<= 8;
101
+ if (s < 378 + psize * 4)
102
+ return 378 + psize * 4 - s;
103
+ // test #5 (mp.c:145-151): ptk note check on pattern data
104
+ // test #5 (mp.c:144-152): sample-header words must be >= 0x71 (d = i*8)
105
+ for (let i = 0; i < 31; i++) {
106
+ const d = start + i * 8;
107
+ const val = readmem16b(data, d) & 0x0fff;
108
+ if (val > 0 && val < 0x71)
109
+ return -1;
110
+ }
111
+ // test #6 (mp.c:156-164)
112
+ for (let i = 0; i < 31; i++) {
113
+ const d = start + i * 8;
114
+ const size = readmem16b(data, d) << 1;
115
+ const lend = (readmem16b(data, d + 4) + readmem16b(data, d + 6)) << 1;
116
+ if (lend > size + 2)
117
+ return -1;
118
+ }
119
+ pwReadTitle(null, 0);
120
+ return 0;
121
+ }
122
+ /** test_mp_id (mp.c:177-212) — "TRK1" signature. */
123
+ function testMpId(data, start) {
124
+ const s = data.length - start;
125
+ if (s < 382)
126
+ return 382 - s;
127
+ if (readmem32b(data, start) !== MAGIC_TRK1)
128
+ return -1;
129
+ // test #1 (mp.c:184-188)
130
+ for (let i = 0; i < 31; i++) {
131
+ if (data[start + 6 + 8 * i] > 0x0f)
132
+ return -1;
133
+ }
134
+ // test #2 (mp.c:190-194)
135
+ const len = data[start + 252];
136
+ if (len === 0 || len > 0x7f)
137
+ return -1;
138
+ // test #4 (mp.c:196-207)
139
+ let psize = 0;
140
+ for (let i = 0; i < 128; i++) {
141
+ const pat = data[start + 254 + i];
142
+ if (pat > 0x7f)
143
+ return -1;
144
+ if (pat > psize)
145
+ psize = pat;
146
+ }
147
+ psize++;
148
+ psize <<= 8;
149
+ if (s < 382 + psize * 4)
150
+ return 382 + psize * 4 - s;
151
+ // test #5 (mp.c:210-214)
152
+ for (let i = 0; i < psize; i++) {
153
+ if (data[start + 382 + i * 4] > 19)
154
+ return -1;
155
+ }
156
+ pwReadTitle(null, 0);
157
+ return 0;
158
+ }
159
+ /** pw_mp_id: "Module Protector" (TRK1). */
160
+ export const pwMpId = {
161
+ name: 'Module Protector',
162
+ test: testMpId,
163
+ depack: depackMp,
164
+ };
165
+ /** pw_mp_noid: "Module Protector noID". */
166
+ export const pwMpNoid = {
167
+ name: 'Module Protector noID',
168
+ test: testMpNoid,
169
+ depack: depackMp,
170
+ };
171
+ //# sourceMappingURL=pw-mp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pw-mp.js","sourceRoot":"","sources":["../src/pw-mp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type PwFormat } from './prowiz.js';
2
+ /** pw_np1: "NoisePacker v1". */
3
+ export declare const pwNp1: PwFormat;
4
+ /** pw_np2: "NoisePacker v2". */
5
+ export declare const pwNp2: PwFormat;
6
+ //# sourceMappingURL=pw-np12.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pw-np12.d.ts","sourceRoot":"","sources":["../src/pw-np12.ts"],"names":[],"mappings":"AAMA,OAAO,EAA4D,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAiOtG,gCAAgC;AAChC,eAAO,MAAM,KAAK,EAAE,QAInB,CAAC;AAEF,gCAAgC;AAChC,eAAO,MAAM,KAAK,EAAE,QAInB,CAAC"}
@@ -0,0 +1,234 @@
1
+ // SPDX-License-Identifier: BSD-3-Clause
2
+ // Copyright (c) 2026 Bitti09 — modplayjs contributors
3
+ // Ported from: libxmp src/loaders/prowizard/np1.c (NoisePacker v1) and
4
+ // np2.c (NoisePacker v2) — np2 shares np1's layout with small deltas.
5
+ import { ptkTable, ptkIsValidNote } from './ptktable.js';
6
+ import { readmem16b, readmem32b, moveData, writeZero, pwReadTitle } from './prowiz.js';
7
+ const PW_MOD_MAGIC = 0x4d2e4b2e; // 'M.K.'
8
+ function put8(out, b) { out.push(b & 0xff); }
9
+ function put16b(out, v) { out.push((v >> 8) & 0xff, v & 0xff); }
10
+ function put32b(out, v) {
11
+ out.push((v >>> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);
12
+ }
13
+ /**
14
+ * Shared depack (np1.c:40-156, np2.c:34-155). ver1: loop start halved and
15
+ * effect table lacks the 0x0e case + npat sanity.
16
+ */
17
+ function depackNp12(data, start, ver1) {
18
+ let pos = start;
19
+ const out = [];
20
+ const u8 = () => data[pos++] ?? 0;
21
+ const u16 = () => { const v = readmem16b(data, pos); pos += 2; return v; };
22
+ const u32 = () => { const v = readmem32b(data, pos); pos += 4; return v; };
23
+ const c1 = u8();
24
+ const c2 = u8();
25
+ const nins = ((c1 << 4) & 0xf0) | ((c2 >> 4) & 0x0f);
26
+ writeZero(out, 20); // title
27
+ const len = u16() >> 1; // size of pattern list
28
+ if (len > 128)
29
+ throw new Error('np: pattern list too long');
30
+ u16(); // 2 unknown bytes
31
+ u16(); // track data size
32
+ // Sample descriptions (np1.c:65-83 / np2.c:63-82)
33
+ let ssize = 0;
34
+ for (let i = 0; i < nins; i++) {
35
+ u32(); // bypass 4 unknown bytes
36
+ writeZero(out, 22); // sample name
37
+ const size = u16();
38
+ ssize += size * 2;
39
+ put16b(out, size);
40
+ put8(out, u8()); // finetune
41
+ put8(out, u8()); // volume
42
+ u32(); // bypass 4 unknown bytes
43
+ const loopSize = u16();
44
+ put16b(out, ver1 ? u16() / 2 : u16()); // loop start
45
+ put16b(out, loopSize); // loop size
46
+ }
47
+ // Fill to 31 samples (np1.c:86-92): zeros with 0x01 loop flag.
48
+ {
49
+ const pad = new Array(30).fill(0);
50
+ pad[29] = 0x01;
51
+ for (let i = nins; i < 31; i++)
52
+ out.push(...pad);
53
+ }
54
+ put8(out, len);
55
+ put8(out, 0x7f); // noisetracker byte
56
+ pos += 2; // always $02? (np1.c:98)
57
+ pos += 2; // unknown (np1.c:99)
58
+ // Pattern table (np1.c:102-111)
59
+ const ptable = [];
60
+ let npat = 0;
61
+ for (let i = 0; i < len; i++) {
62
+ const p = u16() >> 3;
63
+ ptable.push(p);
64
+ if (p > npat)
65
+ npat = p;
66
+ }
67
+ npat++;
68
+ if (!ver1 && npat > 128)
69
+ throw new Error('np2: too many patterns');
70
+ for (let i = 0; i < 128; i++)
71
+ put8(out, ptable[i]);
72
+ put32b(out, PW_MOD_MAGIC);
73
+ // Track addresses per pattern (np1.c:114-129)
74
+ const trkAddr = [];
75
+ let maxAddr = 0;
76
+ for (let i = 0; i < npat; i++) {
77
+ const row = [];
78
+ for (let j = 0; j < 4; j++) {
79
+ const a = u16();
80
+ row.push(a);
81
+ if (a > maxAddr)
82
+ maxAddr = a;
83
+ }
84
+ trkAddr.push(row);
85
+ }
86
+ const trkStart = pos;
87
+ // Track data (np1.c:132-152): channel j reads track [3-j] (reversed);
88
+ // cells are placed ROW-MAJOR into the pattern body (tmp[x], x = k*16 + j*4).
89
+ for (let i = 0; i < npat; i++) {
90
+ const tmp = new Uint8Array(1024);
91
+ for (let j = 0; j < 4; j++) {
92
+ pos = trkStart + trkAddr[i][3 - j];
93
+ for (let k = 0; k < 64; k++) {
94
+ const x = k * 16 + j * 4;
95
+ const c1 = u8();
96
+ const c2 = u8();
97
+ const c3 = u8();
98
+ const c4 = Math.trunc((c1 & 0xfe) / 2);
99
+ if (!ptkIsValidNote(c4))
100
+ throw new Error('np: invalid note');
101
+ let eff2 = c2;
102
+ let eff3 = c3;
103
+ switch (c2 & 0x0f) {
104
+ case 0x08:
105
+ eff2 &= 0xf0;
106
+ break;
107
+ case 0x07:
108
+ eff2 = (eff2 & 0xf0) + 0x0a;
109
+ // falls through to 06/05 handling
110
+ eff3 = eff3 > 0x80 ? 0x100 - eff3 : (eff3 << 4) & 0xf0;
111
+ break;
112
+ case 0x06:
113
+ case 0x05:
114
+ eff3 = eff3 > 0x80 ? 0x100 - eff3 : (eff3 << 4) & 0xf0;
115
+ break;
116
+ case 0x0b:
117
+ eff3 = Math.trunc((eff3 + 4) / 2);
118
+ break;
119
+ case 0x0e:
120
+ if (!ver1)
121
+ eff3--;
122
+ break;
123
+ }
124
+ tmp[x] = ((c1 << 4) & 0x10) | ptkTable[c4][0];
125
+ tmp[x + 1] = ptkTable[c4][1];
126
+ tmp[x + 2] = eff2 & 0xff;
127
+ tmp[x + 3] = eff3 & 0xff;
128
+ }
129
+ }
130
+ for (let k = 0; k < 1024; k++)
131
+ out.push(tmp[k]);
132
+ }
133
+ // Sample data (np1.c:155-158)
134
+ moveData(data, start + maxAddr + 192 + trkStart, out, ssize);
135
+ return Uint8Array.from(out);
136
+ }
137
+ /** Shared test (np1.c:161-251, np2.c:158-269). */
138
+ function testNp12(data, start, ver1) {
139
+ const s = data.length - start;
140
+ if (s < 10)
141
+ return 10 - s;
142
+ // Pattern table size (np1.c:169-173)
143
+ const ptabSize = readmem16b(data, start + 2);
144
+ if (ptabSize === 0 || (ptabSize & 1) !== 0 || ptabSize > 0xff)
145
+ return -1;
146
+ // Sample count nibble check (np1.c:176-178)
147
+ if ((data[start + 1] & 0x0f) !== 0x0c)
148
+ return -1;
149
+ const numIns = ((data[start] << 4) & 0xf0) | ((data[start + 1] >> 4) & 0x0f);
150
+ if (numIns === 0 || numIns > 0x1f)
151
+ return -1;
152
+ // PW_REQUEST_DATA(s, 15 + num_ins * 16)
153
+ if (s < 15 + numIns * 16)
154
+ return 15 + numIns * 16 - s;
155
+ for (let i = 0; i < numIns; i++) {
156
+ if (data[start + 15 + i * 16] > 0x40)
157
+ return -1; // volumes
158
+ }
159
+ // Sample sizes (np1.c:185-206)
160
+ let ssize = 0;
161
+ for (let i = 0; i < numIns; i++) {
162
+ const d = start + i * 16;
163
+ const len = readmem16b(data, d + 12) << 1;
164
+ const lstart = readmem16b(data, d + 20) << 1;
165
+ const lsize = ver1 ? readmem16b(data, d + 22) : readmem16b(data, d + 22) << 1;
166
+ if (len > 0xffff || lstart > 0xffff || lsize > 0xffff)
167
+ return -1;
168
+ if (lstart + lsize > len + 2)
169
+ return -1;
170
+ if (lstart === 0 && lsize !== 0)
171
+ return -1;
172
+ ssize += len;
173
+ }
174
+ if (ssize <= 4)
175
+ return -1;
176
+ // Header size (np1.c:209-211)
177
+ let hdrSize = numIns * 16 + 8 + 4;
178
+ // PW_REQUEST_DATA(s, hdr_size + ptab_size + 2)
179
+ if (s < hdrSize + ptabSize + 2)
180
+ return hdrSize + ptabSize + 2 - s;
181
+ // Pattern table (np1.c:213-224)
182
+ let maxPptr = 0;
183
+ for (let i = 0; i < ptabSize; i += 2) {
184
+ const pptr = readmem16b(data, start + hdrSize + i);
185
+ if (ver1) {
186
+ if ((pptr & 0x07) !== 0 || pptr >= 0x400)
187
+ return -1;
188
+ }
189
+ else {
190
+ if ((pptr & 0x07) !== 0 || pptr > 0x400)
191
+ return -1;
192
+ }
193
+ if (pptr > maxPptr)
194
+ maxPptr = pptr;
195
+ }
196
+ // Header to end of track list (np1.c:227-231)
197
+ hdrSize += ptabSize + maxPptr + 8;
198
+ // Track data size (np1.c:234-237)
199
+ const trkSize = readmem16b(data, start + 6);
200
+ if (trkSize < 192 || (trkSize & 0x3f) !== 0)
201
+ return -1;
202
+ // PW_REQUEST_DATA(s, hdr_size + trk_size [+16 for np2])
203
+ const need = hdrSize + trkSize + (ver1 ? 0 : 16);
204
+ if (s < need)
205
+ return need - s;
206
+ // Notes (np1.c:239-247, np2.c:245-262)
207
+ for (let i = 0; i < trkSize; i += 3) {
208
+ const d = start + hdrSize + i;
209
+ if (data[d] > 0x49)
210
+ return -1;
211
+ if (!ver1) {
212
+ const ins = ((data[d] << 4) & 0x10) | ((data[d + 1] >> 4) & 0x0f);
213
+ if (ins > numIns)
214
+ return -1;
215
+ if ((data[d + 1] & 0x0f) === 0 && data[d + 2] !== 0)
216
+ return -1;
217
+ }
218
+ }
219
+ pwReadTitle(null, 0);
220
+ return 0;
221
+ }
222
+ /** pw_np1: "NoisePacker v1". */
223
+ export const pwNp1 = {
224
+ name: 'NoisePacker v1',
225
+ test: (data, st) => testNp12(data, st, true),
226
+ depack: (data, st) => depackNp12(data, st, true),
227
+ };
228
+ /** pw_np2: "NoisePacker v2". */
229
+ export const pwNp2 = {
230
+ name: 'NoisePacker v2',
231
+ test: (data, st) => testNp12(data, st, false),
232
+ depack: (data, st) => depackNp12(data, st, false),
233
+ };
234
+ //# sourceMappingURL=pw-np12.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pw-np12.js","sourceRoot":"","sources":["../src/pw-np12.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type PwFormat } from './prowiz.js';
2
+ /** pw_np3: "NoisePacker v3". */
3
+ export declare const pwNp3: PwFormat;
4
+ //# sourceMappingURL=pw-np3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pw-np3.d.ts","sourceRoot":"","sources":["../src/pw-np3.ts"],"names":[],"mappings":"AAMA,OAAO,EAAgD,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAuN1F,gCAAgC;AAChC,eAAO,MAAM,KAAK,EAAE,QAInB,CAAC"}
package/dist/pw-np3.js ADDED
@@ -0,0 +1,218 @@
1
+ // SPDX-License-Identifier: BSD-3-Clause
2
+ // Copyright (c) 2026 Bitti09 — modplayjs contributors
3
+ // Ported from: libxmp src/loaders/prowizard/np3.c (NoisePacker v3) —
4
+ // depack_np3 :34-217, test_np3 :220-304.
5
+ import { ptkTable, ptkIsValidNote } from './ptktable.js';
6
+ import { readmem16b, moveData, writeZero, pwReadTitle } from './prowiz.js';
7
+ const PW_MOD_MAGIC = 0x4d2e4b2e; // 'M.K.'
8
+ function put8(out, b) { out.push(b & 0xff); }
9
+ function put16b(out, v) { out.push((v >> 8) & 0xff, v & 0xff); }
10
+ function put32b(out, v) {
11
+ out.push((v >>> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);
12
+ }
13
+ /** depack_np3 (np3.c:34-217). */
14
+ function depackNp3(data, start) {
15
+ let pos = start;
16
+ const out = [];
17
+ const u8 = () => data[pos++] ?? 0;
18
+ const u16 = () => { const v = readmem16b(data, pos); pos += 2; return v; };
19
+ const c1 = u8();
20
+ const c2 = u8();
21
+ const nins = ((c1 << 4) & 0xf0) | ((c2 >> 4) & 0x0f);
22
+ writeZero(out, 20); // title
23
+ const len = u16() >> 1; // pattern list size
24
+ if (len > 128)
25
+ throw new Error('np3: pattern list too long');
26
+ u16(); // 2 unknown bytes
27
+ u16(); // track data size
28
+ // Sample descriptions (np3.c:64-74): 16-byte records, reordered fields.
29
+ let ssize = 0;
30
+ for (let i = 0; i < nins; i++) {
31
+ const rec = data.subarray(pos, pos + 16);
32
+ pos += 16;
33
+ writeZero(out, 22); // sample name
34
+ const size = readmem16b(rec, 6);
35
+ ssize += size * 2;
36
+ put16b(out, size);
37
+ put8(out, rec[0]); // finetune
38
+ put8(out, rec[1]); // volume
39
+ // write loop start (tmp+14) then loop size (tmp+12) — swapped in file
40
+ out.push(rec[14], rec[15]);
41
+ out.push(rec[12], rec[13]);
42
+ }
43
+ // Fill to 31 (np3.c:77-81)
44
+ {
45
+ const pad = new Array(30).fill(0);
46
+ pad[29] = 0x01;
47
+ for (let i = nins; i < 31; i++)
48
+ out.push(...pad);
49
+ }
50
+ put8(out, len);
51
+ put8(out, 0x7f);
52
+ pos += 2; // always $02?
53
+ pos += 2; // unknown
54
+ // Pattern table (np3.c:84-93): u16 / 8
55
+ const ptable = [];
56
+ let npat = 0;
57
+ for (let i = 0; i < len; i++) {
58
+ const p = Math.trunc(u16() / 8);
59
+ ptable.push(p);
60
+ if (p > npat)
61
+ npat = p;
62
+ }
63
+ npat++;
64
+ for (let i = 0; i < 128; i++)
65
+ put8(out, ptable[i]);
66
+ put32b(out, PW_MOD_MAGIC);
67
+ // Track addresses (np3.c:96-110)
68
+ const trkAddr = [];
69
+ for (let i = 0; i < npat; i++) {
70
+ const row = [];
71
+ for (let j = 0; j < 4; j++)
72
+ row.push(u16());
73
+ trkAddr.push(row);
74
+ }
75
+ const trkStart = pos;
76
+ // Track data (np3.c:113-196): 0x80-or-more = blank-run skip; smp_addr
77
+ // tracks the furthest read position across all tracks.
78
+ let smpAddr = 0;
79
+ for (let i = 0; i < npat; i++) {
80
+ const tmp = new Uint8Array(1024);
81
+ for (let j = 0; j < 4; j++) {
82
+ pos = trkStart + trkAddr[i][3 - j];
83
+ for (let k = 0; k < 64; k++) {
84
+ const x = k * 16 + j * 4;
85
+ const c1 = u8();
86
+ if (c1 >= 0x80) {
87
+ k += (0x100 - c1) - 1;
88
+ continue;
89
+ }
90
+ const c2 = u8();
91
+ const c3 = u8();
92
+ const c4 = Math.trunc((c1 & 0xfe) / 2);
93
+ if (!ptkIsValidNote(c4))
94
+ throw new Error('np3: invalid note');
95
+ let eff2 = c2;
96
+ let eff3 = c3;
97
+ switch (c2 & 0x0f) {
98
+ case 0x08:
99
+ eff2 &= 0xf0;
100
+ break;
101
+ case 0x07:
102
+ eff2 = (eff2 & 0xf0) + 0x0a;
103
+ eff3 = eff3 > 0x80 ? 0x100 - eff3 : (eff3 << 4) & 0xf0;
104
+ break;
105
+ case 0x06:
106
+ case 0x05:
107
+ eff3 = eff3 > 0x80 ? 0x100 - eff3 : (eff3 << 4) & 0xf0;
108
+ break;
109
+ case 0x0e:
110
+ eff3 = 1;
111
+ break;
112
+ case 0x0b:
113
+ eff3 = Math.trunc((eff3 + 4) / 2);
114
+ break;
115
+ }
116
+ tmp[x] = ((c1 << 4) & 0x10) | ptkTable[c4][0];
117
+ tmp[x + 1] = ptkTable[c4][1];
118
+ tmp[x + 2] = eff2;
119
+ tmp[x + 3] = eff3;
120
+ if ((c2 & 0x0f) === 0x0d)
121
+ break; // pattern break ends the track
122
+ }
123
+ if (pos > smpAddr)
124
+ smpAddr = pos;
125
+ }
126
+ for (let k = 0; k < 1024; k++)
127
+ out.push(tmp[k]);
128
+ }
129
+ // Sample data (np3.c:200-206): smp_addr aligned to even.
130
+ if ((smpAddr & 1) !== 0)
131
+ smpAddr++;
132
+ moveData(data, smpAddr, out, ssize);
133
+ return Uint8Array.from(out);
134
+ }
135
+ /** test_np3 (np3.c:220-304). */
136
+ function testNp3(data, start) {
137
+ const s = data.length - start;
138
+ if (s < 10)
139
+ return 10 - s;
140
+ const ptabSize = readmem16b(data, start + 2);
141
+ if (ptabSize === 0 || (ptabSize & 0x01) !== 0 || ptabSize > 0xff)
142
+ return -1;
143
+ if ((data[start + 1] & 0x0f) !== 0x0c)
144
+ return -1;
145
+ const numIns = ((data[start] << 4) & 0xf0) | ((data[start + 1] >> 4) & 0x0f);
146
+ if (numIns === 0 || numIns > 0x1f)
147
+ return -1;
148
+ if (s < 15 + numIns * 16)
149
+ return 15 + numIns * 16 - s;
150
+ // Volumes (np3.c:241-245) — note offset 9, not 15.
151
+ for (let i = 0; i < numIns; i++) {
152
+ if (data[start + 9 + i * 16] > 0x40)
153
+ return -1;
154
+ }
155
+ // Sample sizes (np3.c:248-268): len at d+14 (not d+12).
156
+ let ssize = 0;
157
+ for (let i = 0; i < numIns; i++) {
158
+ const d = start + i * 16;
159
+ const len = readmem16b(data, d + 14) << 1;
160
+ const lstart = readmem16b(data, d + 20) << 1;
161
+ const lsize = readmem16b(data, d + 22) << 1;
162
+ if (len > 0xffff || lstart > 0xffff || lsize > 0xffff)
163
+ return -1;
164
+ if (lstart + lsize > len + 2)
165
+ return -1;
166
+ if (lstart === 0 && lsize !== 0)
167
+ return -1;
168
+ ssize += len;
169
+ }
170
+ if (ssize <= 4)
171
+ return -1;
172
+ let hdrSize = numIns * 16 + 8 + 4;
173
+ if (s < hdrSize + ptabSize + 2)
174
+ return hdrSize + ptabSize + 2 - s;
175
+ // Pattern table (np3.c:275-284)
176
+ let maxPptr = 0;
177
+ for (let i = 0; i < ptabSize; i += 2) {
178
+ const pptr = readmem16b(data, start + hdrSize + i);
179
+ if ((pptr & 0x07) !== 0 || pptr >= 0x400)
180
+ return -1;
181
+ if (pptr > maxPptr)
182
+ maxPptr = pptr;
183
+ }
184
+ hdrSize += ptabSize + maxPptr + 8;
185
+ // Track data size (np3.c:291-294): > 63, no alignment check.
186
+ const trkSize = readmem16b(data, start + 6);
187
+ if (trkSize <= 63)
188
+ return -1;
189
+ if (s < hdrSize + trkSize + 2)
190
+ return hdrSize + trkSize + 2 - s;
191
+ // Notes (np3.c:297-322): errcount tolerance of 1 (Shadow Fighter quirk).
192
+ let errcount = 0;
193
+ for (let i = 0; i < trkSize; i++) {
194
+ const d = start + hdrSize + i;
195
+ if ((data[d] & 0x80) !== 0)
196
+ continue;
197
+ if (data[d] > 0x49 || (data[d + 1] & 0x0f) === 0x0a)
198
+ errcount++;
199
+ if ((data[d + 1] & 0x0f) === 0x0d && data[d + 2] > 0x40)
200
+ errcount++;
201
+ if ((((data[d] << 4) & 0x10) | ((data[d + 1] >> 4) & 0x0f)) > numIns)
202
+ errcount++;
203
+ if (data[d] === 0 && data[d + 1] === 0 && data[d + 2] === 0 && i < trkSize - 3)
204
+ errcount++;
205
+ if (errcount > 1)
206
+ return -1;
207
+ i += 2;
208
+ }
209
+ pwReadTitle(null, 0);
210
+ return 0;
211
+ }
212
+ /** pw_np3: "NoisePacker v3". */
213
+ export const pwNp3 = {
214
+ name: 'NoisePacker v3',
215
+ test: testNp3,
216
+ depack: depackNp3,
217
+ };
218
+ //# sourceMappingURL=pw-np3.js.map