sonolus-pjsekai-js 1.2.19 → 1.3.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.
Binary file
Binary file
@@ -1,8 +1,8 @@
1
- export { susToUSC } from "./sus/convert.cjs";
2
- export { uscToLevelData } from "./usc/convert.cjs";
3
- export * from "./usc/index.cjs";
4
- export { uscToUSC } from "./usc/revert.cjs";
5
- export declare const version = "1.2.19";
1
+ export { susToUSC } from "./sus/convert.js";
2
+ export { uscToLevelData } from "./usc/convert.js";
3
+ export * from "./usc/index.js";
4
+ export { uscToUSC } from "./usc/revert.js";
5
+ export declare const version = "1.3.1";
6
6
  export declare const databaseEngineItem: {
7
7
  readonly name: "prosekaR";
8
8
  readonly version: 13;
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ export { susToUSC } from "./sus/convert.js";
2
+ export { uscToLevelData } from "./usc/convert.js";
3
+ export * from "./usc/index.js";
4
+ export { uscToUSC } from "./usc/revert.js";
5
+ export const version = "1.3.1";
6
+ export const databaseEngineItem = {
7
+ name: "prosekaR",
8
+ version: 13,
9
+ title: {
10
+ en: "ProSeka R",
11
+ ja: "プロセカ R",
12
+ ko: "프로세카 R",
13
+ zhs: "世界计划 R",
14
+ zht: "世界計劃 R",
15
+ },
16
+ subtitle: {
17
+ en: "ProSeka Rush",
18
+ ja: "プロセカ ラッシュ",
19
+ ko: "프로세카 러쉬",
20
+ zhs: "世界计划 匆忙",
21
+ zht: "世界計劃 匆忙",
22
+ },
23
+ author: {
24
+ en: "Hyeon2#7895",
25
+ },
26
+ description: {
27
+ en: [
28
+ "A recreation of Project Sekai: Colorful Stage! engine in Sonolus.",
29
+ `Version: ${version}`,
30
+ "",
31
+ "Forked from the pjsekai engine by Burrito#1000.",
32
+ "https://github.com/NonSpicyBurrito/sonolus-pjsekai-engine",
33
+ "",
34
+ "Github:",
35
+ "https://github.com/hyeon2006/sonolus-pjsekai-js",
36
+ ].join("\n"),
37
+ ko: [
38
+ "프로젝트 세카이: 컬러풀 스테이지! 엔진을 Sonolus로 재현했습니다.",
39
+ `버전: ${version}`,
40
+ "",
41
+ "Burrito#1000의 pjsekai 엔진에서 포크되었습니다.",
42
+ "https://github.com/NonSpicyBurrito/sonolus-pjsekai-engine",
43
+ "",
44
+ "깃허브:",
45
+ "https://github.com/hyeon2006/sonolus-pjsekai-js",
46
+ ].join("\n"),
47
+ },
48
+ };
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.analyze = void 0;
4
- const analyze = (sus) => {
1
+ export const analyze = (sus) => {
5
2
  const { lines, measureChanges, meta } = parse(sus);
6
3
  const offset = -+(meta.get("WAVEOFFSET") || "0");
7
4
  if (Number.isNaN(offset))
@@ -73,7 +70,6 @@ const analyze = (sus) => {
73
70
  slides,
74
71
  };
75
72
  };
76
- exports.analyze = analyze;
77
73
  const parse = (sus) => {
78
74
  const lines = [];
79
75
  const measureChanges = [];
@@ -1,2 +1,2 @@
1
- import { USC } from '../usc/index.cjs';
1
+ import { USC } from '../usc/index.js';
2
2
  export declare const susToUSC: (sus: string) => USC;
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.susToUSC = void 0;
4
- const analyze_cjs_1 = require("./analyze.cjs");
5
- const susToUSC = (sus) => {
6
- const score = (0, analyze_cjs_1.analyze)(sus);
1
+ import { analyze } from './analyze.js';
2
+ export const susToUSC = (sus) => {
3
+ const score = analyze(sus);
7
4
  const flickMods = new Map();
8
5
  const traceMods = new Set();
9
6
  const criticalMods = new Set();
@@ -236,5 +233,4 @@ const susToUSC = (sus) => {
236
233
  objects,
237
234
  };
238
235
  };
239
- exports.susToUSC = susToUSC;
240
236
  const getKey = (note) => `${note.lane}-${note.tick}`;
@@ -0,0 +1,15 @@
1
+ export const USCColor = {
2
+ neutral: 0,
3
+ red: 1,
4
+ green: 2,
5
+ blue: 3,
6
+ yellow: 4,
7
+ purple: 5,
8
+ cyan: 6,
9
+ black: 7,
10
+ };
11
+ export const USCFade = {
12
+ in: 2,
13
+ out: 0,
14
+ none: 1,
15
+ };
@@ -1,3 +1,3 @@
1
1
  import { LevelData } from '@sonolus/core';
2
- import { USC } from './index.cjs';
2
+ import { USC } from './index.js';
3
3
  export declare const uscToLevelData: (usc: USC, offset?: number) => LevelData;
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uscToLevelData = void 0;
4
- const core_1 = require("@sonolus/core");
5
- const uscToLevelData = (usc, offset = 0) => {
1
+ import { EngineArchetypeDataName, EngineArchetypeName, } from '@sonolus/core';
2
+ export const uscToLevelData = (usc, offset = 0) => {
6
3
  const entities = [];
7
4
  const timeToIntermediates = new Map();
8
5
  const intermediateToRef = new Map();
@@ -25,7 +22,7 @@ const uscToLevelData = (usc, offset = 0) => {
25
22
  data: [],
26
23
  };
27
24
  if (intermediate.sim) {
28
- const beat = intermediate.data[core_1.EngineArchetypeDataName.Beat];
25
+ const beat = intermediate.data[EngineArchetypeDataName.Beat];
29
26
  if (typeof beat !== 'number')
30
27
  throw new Error('Unexpected beat');
31
28
  const intermediates = timeToIntermediates.get(beat);
@@ -88,7 +85,6 @@ const uscToLevelData = (usc, offset = 0) => {
88
85
  entities,
89
86
  };
90
87
  };
91
- exports.uscToLevelData = uscToLevelData;
92
88
  const directions = {
93
89
  left: -1,
94
90
  up: 0,
@@ -103,20 +99,20 @@ const eases = {
103
99
  };
104
100
  const bpm = (object, append) => {
105
101
  append({
106
- archetype: core_1.EngineArchetypeName.BpmChange,
102
+ archetype: EngineArchetypeName.BpmChange,
107
103
  data: {
108
- [core_1.EngineArchetypeDataName.Beat]: object.beat,
109
- [core_1.EngineArchetypeDataName.Bpm]: object.bpm,
104
+ [EngineArchetypeDataName.Beat]: object.beat,
105
+ [EngineArchetypeDataName.Bpm]: object.bpm,
110
106
  },
111
107
  sim: false,
112
108
  });
113
109
  };
114
110
  const timeScale = (object, append) => {
115
111
  append({
116
- archetype: core_1.EngineArchetypeName.TimeScaleChange,
112
+ archetype: EngineArchetypeName.TimeScaleChange,
117
113
  data: {
118
- [core_1.EngineArchetypeDataName.Beat]: object.beat,
119
- [core_1.EngineArchetypeDataName.TimeScale]: object.timeScale,
114
+ [EngineArchetypeDataName.Beat]: object.beat,
115
+ [EngineArchetypeDataName.TimeScale]: object.timeScale,
120
116
  },
121
117
  sim: false,
122
118
  });
@@ -139,7 +135,7 @@ const single = (object, append) => {
139
135
  ? 'CriticalTapNote'
140
136
  : 'NormalTapNote',
141
137
  data: {
142
- [core_1.EngineArchetypeDataName.Beat]: object.beat,
138
+ [EngineArchetypeDataName.Beat]: object.beat,
143
139
  lane: object.lane,
144
140
  size: object.size,
145
141
  direction: object.direction && directions[object.direction],
@@ -167,7 +163,7 @@ const slide = (object, append) => {
167
163
  ? 'CriticalSlideStartNote'
168
164
  : 'NormalSlideStartNote',
169
165
  data: {
170
- [core_1.EngineArchetypeDataName.Beat]: connection.beat,
166
+ [EngineArchetypeDataName.Beat]: connection.beat,
171
167
  lane: connection.lane,
172
168
  size: connection.size,
173
169
  },
@@ -182,7 +178,7 @@ const slide = (object, append) => {
182
178
  const ci = {
183
179
  archetype: 'IgnoredSlideTickNote',
184
180
  data: {
185
- [core_1.EngineArchetypeDataName.Beat]: connection.beat,
181
+ [EngineArchetypeDataName.Beat]: connection.beat,
186
182
  lane: connection.lane,
187
183
  size: connection.size,
188
184
  },
@@ -217,7 +213,7 @@ const slide = (object, append) => {
217
213
  ? 'CriticalSlideEndNote'
218
214
  : 'NormalSlideEndNote',
219
215
  data: {
220
- [core_1.EngineArchetypeDataName.Beat]: connection.beat,
216
+ [EngineArchetypeDataName.Beat]: connection.beat,
221
217
  lane: connection.lane,
222
218
  size: connection.size,
223
219
  direction: connection.direction && directions[connection.direction],
@@ -233,7 +229,7 @@ const slide = (object, append) => {
233
229
  const ci = {
234
230
  archetype: 'IgnoredSlideTickNote',
235
231
  data: {
236
- [core_1.EngineArchetypeDataName.Beat]: connection.beat,
232
+ [EngineArchetypeDataName.Beat]: connection.beat,
237
233
  lane: connection.lane,
238
234
  size: connection.size,
239
235
  },
@@ -253,7 +249,7 @@ const slide = (object, append) => {
253
249
  const ci = {
254
250
  archetype: 'IgnoredSlideTickNote',
255
251
  data: {
256
- [core_1.EngineArchetypeDataName.Beat]: connection.beat,
252
+ [EngineArchetypeDataName.Beat]: connection.beat,
257
253
  lane: connection.lane,
258
254
  size: connection.size,
259
255
  },
@@ -274,7 +270,7 @@ const slide = (object, append) => {
274
270
  ? 'CriticalSlideTickNote'
275
271
  : 'NormalSlideTickNote',
276
272
  data: {
277
- [core_1.EngineArchetypeDataName.Beat]: connection.beat,
273
+ [EngineArchetypeDataName.Beat]: connection.beat,
278
274
  lane: connection.lane,
279
275
  size: connection.size,
280
276
  },
@@ -289,7 +285,7 @@ const slide = (object, append) => {
289
285
  const ci = {
290
286
  archetype: 'HiddenSlideTickNote',
291
287
  data: {
292
- [core_1.EngineArchetypeDataName.Beat]: connection.beat,
288
+ [EngineArchetypeDataName.Beat]: connection.beat,
293
289
  },
294
290
  sim: false,
295
291
  };
@@ -303,7 +299,7 @@ const slide = (object, append) => {
303
299
  ? 'CriticalAttachedSlideTickNote'
304
300
  : 'NormalAttachedSlideTickNote',
305
301
  data: {
306
- [core_1.EngineArchetypeDataName.Beat]: connection.beat,
302
+ [EngineArchetypeDataName.Beat]: connection.beat,
307
303
  },
308
304
  sim: false,
309
305
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
- import * as B from './ccIndex.cjs';
2
- import * as A from './index.cjs';
1
+ import * as B from './ccIndex.js';
2
+ import * as A from './index.js';
3
3
  /**
4
4
  * B 타입의 USC 객체를 A 타입 USC 객체로 변환합니다.
5
5
  * @param uscB B 타입 USC 객체
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uscToUSC = void 0;
4
1
  /**
5
2
  * B 타입의 USC 슬라이드 연결 노드를 A 타입으로 변환합니다.
6
3
  * @param connection B 타입의 연결 노트
@@ -94,7 +91,7 @@ const getBeatForSort = (obj) => {
94
91
  * @param uscB B 타입 USC 객체
95
92
  * @returns A 타입 USC 객체
96
93
  */
97
- const uscToUSC = (uscB) => {
94
+ export const uscToUSC = (uscB) => {
98
95
  const newObjects = [];
99
96
  let timeScaleGroupConverted = false; // 첫 번째 timeScaleGroup만 변환하기 위한 플래그
100
97
  for (const object of uscB.objects) {
@@ -168,4 +165,3 @@ const uscToUSC = (uscB) => {
168
165
  objects: newObjects,
169
166
  };
170
167
  };
171
- exports.uscToUSC = uscToUSC;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "sonolus-pjsekai-js",
3
- "version": "1.2.19",
3
+ "version": "1.3.1",
4
4
  "description": "A recreation of Project Sekai: Colorful Stage! engine in Sonolus",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
8
8
  ],
9
9
  "exports": {
10
- ".": "./dist/index.cjs",
10
+ ".": "./dist/index.js",
11
11
  "./EngineConfiguration": "./dist/EngineConfiguration",
12
12
  "./EnginePlayData": "./dist/EnginePlayData",
13
13
  "./EngineWatchData": "./dist/EngineWatchData",
@@ -16,22 +16,22 @@
16
16
  "./EngineThumbnail": "./dist/thumbnail.png"
17
17
  },
18
18
  "scripts": {
19
- "dev:play": "sonolus-cli --dev ./play",
20
- "dev:watch": "sonolus-cli --dev ./watch",
21
- "dev:preview": "sonolus-cli --dev ./preview",
22
- "dev:tutorial": "sonolus-cli --dev ./tutorial",
19
+ "dev-play": "sonolus-cli --dev ./play",
20
+ "dev-watch": "sonolus-cli --dev ./watch",
21
+ "dev-preview": "sonolus-cli --dev ./preview",
22
+ "dev-tutorial": "sonolus-cli --dev ./tutorial",
23
23
  "format": "biome format --write",
24
24
  "lint": "biome lint",
25
25
  "lint-fix": "biome lint --write",
26
26
  "biome": "biome check",
27
- "build": "tsc -p ./lib && sonolus-cli --build ./play && sonolus-cli --build ./watch && sonolus-cli --build ./preview && sonolus-cli --build ./tutorial && node ./lib/build.mjs"
27
+ "build": "tsc -p ./lib && sonolus-cli --build ./play && sonolus-cli --build ./watch && sonolus-cli --build ./preview && sonolus-cli --build ./tutorial && node ./lib/build.js"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@biomejs/biome": "2.0.6",
31
- "@sonolus/sonolus.js": "~9.5.6",
31
+ "@sonolus/sonolus.js": "~9.6.0",
32
32
  "typescript": "~5.8.3"
33
33
  },
34
34
  "dependencies": {
35
- "@sonolus/core": "~7.13.3"
35
+ "@sonolus/core": "~7.14.0"
36
36
  }
37
37
  }
package/dist/index.cjs DELETED
@@ -1,68 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.databaseEngineItem = exports.version = exports.uscToUSC = exports.uscToLevelData = exports.susToUSC = void 0;
18
- var convert_cjs_1 = require("./sus/convert.cjs");
19
- Object.defineProperty(exports, "susToUSC", { enumerable: true, get: function () { return convert_cjs_1.susToUSC; } });
20
- var convert_cjs_2 = require("./usc/convert.cjs");
21
- Object.defineProperty(exports, "uscToLevelData", { enumerable: true, get: function () { return convert_cjs_2.uscToLevelData; } });
22
- __exportStar(require("./usc/index.cjs"), exports);
23
- var revert_cjs_1 = require("./usc/revert.cjs");
24
- Object.defineProperty(exports, "uscToUSC", { enumerable: true, get: function () { return revert_cjs_1.uscToUSC; } });
25
- exports.version = "1.2.19";
26
- exports.databaseEngineItem = {
27
- name: "prosekaR",
28
- version: 13,
29
- title: {
30
- en: "ProSeka R",
31
- ja: "プロセカ R",
32
- ko: "프로세카 R",
33
- zhs: "世界计划 R",
34
- zht: "世界計劃 R",
35
- },
36
- subtitle: {
37
- en: "ProSeka Rush",
38
- ja: "プロセカ ラッシュ",
39
- ko: "프로세카 러쉬",
40
- zhs: "世界计划 匆忙",
41
- zht: "世界計劃 匆忙",
42
- },
43
- author: {
44
- en: "Hyeon2#7895",
45
- },
46
- description: {
47
- en: [
48
- "A recreation of Project Sekai: Colorful Stage! engine in Sonolus.",
49
- `Version: ${exports.version}`,
50
- "",
51
- "Forked from the pjsekai engine by Burrito#1000.",
52
- "https://github.com/NonSpicyBurrito/sonolus-pjsekai-engine",
53
- "",
54
- "Github:",
55
- "https://github.com/hyeon2006/sonolus-pjsekai-js",
56
- ].join("\n"),
57
- ko: [
58
- "프로젝트 세카이: 컬러풀 스테이지! 엔진을 Sonolus로 재현했습니다.",
59
- `버전: ${exports.version}`,
60
- "",
61
- "Burrito#1000의 pjsekai 엔진에서 포크되었습니다.",
62
- "https://github.com/NonSpicyBurrito/sonolus-pjsekai-engine",
63
- "",
64
- "깃허브:",
65
- "https://github.com/hyeon2006/sonolus-pjsekai-js",
66
- ].join("\n"),
67
- },
68
- };
@@ -1,318 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uscToSUS = void 0;
4
- const TICKS_PER_BEAT = 480;
5
- const uscToSUS = (uscData) => {
6
- const usc = uscData.usc ? uscData.usc : uscData;
7
- const susLines = [];
8
- const noteData = new Map();
9
- let slideChannelCounter = 0;
10
- // (메타데이터 및 전역 정의 생성은 이전과 동일)
11
- susLines.push(`#TITLE ""`, `#ARTIST ""`, `#DESIGNER ""`, `#WAVEOFFSET ${-usc.offset}`, `#REQUEST "ticks_per_beat ${TICKS_PER_BEAT}"`, ``);
12
- const ticksPerMeasure = TICKS_PER_BEAT * 4;
13
- const bpmObjects = usc.objects.filter((obj) => obj.type === "bpm");
14
- const bpmDefinitions = new Map();
15
- let bpmCounter = 1;
16
- for (const bpmObject of bpmObjects) {
17
- if (!bpmDefinitions.has(bpmObject.bpm)) {
18
- const bpmId = bpmCounter.toString().padStart(2, "0");
19
- bpmDefinitions.set(bpmObject.bpm, bpmId);
20
- susLines.push(`#BPM${bpmId}: ${bpmObject.bpm}`);
21
- bpmCounter++;
22
- }
23
- }
24
- susLines.push(``);
25
- const timeScaleGroups = usc.objects.filter((obj) => obj.type === "timeScaleGroup");
26
- const tilIdMap = new Map();
27
- timeScaleGroups.forEach((group, index) => {
28
- const tilId = index.toString().padStart(2, "0");
29
- tilIdMap.set(index, tilId);
30
- const changesString = group.changes
31
- .map(change => {
32
- const totalTicks = change.beat * TICKS_PER_BEAT;
33
- const measure = Math.floor(totalTicks / ticksPerMeasure);
34
- const tickInMeasure = totalTicks % ticksPerMeasure;
35
- return `${measure}'${tickInMeasure}:${change.timeScale}`;
36
- })
37
- .join(", ");
38
- susLines.push(`#TIL${tilId}: "${changesString}"`);
39
- });
40
- susLines.push(``);
41
- addNoteData(0, "00002", 0, "4", 0);
42
- for (const bpmObject of bpmObjects) {
43
- const tick = bpmObject.beat * TICKS_PER_BEAT;
44
- const measure = Math.floor(tick / ticksPerMeasure);
45
- const tickInMeasure = tick % ticksPerMeasure;
46
- const bpmId = bpmDefinitions.get(bpmObject.bpm);
47
- if (bpmId) {
48
- addNoteData(measure, `${measure.toString().padStart(3, "0")}08`, tickInMeasure, bpmId, 0);
49
- }
50
- }
51
- for (const obj of usc.objects) {
52
- switch (obj.type) {
53
- case "single":
54
- case "damage":
55
- processSingleOrDamage(obj);
56
- break;
57
- case "slide":
58
- processSlide(obj);
59
- slideChannelCounter++;
60
- break;
61
- case "guide":
62
- processGuide(obj);
63
- slideChannelCounter++;
64
- break;
65
- case "timeScaleGroup":
66
- case "bpm":
67
- break;
68
- }
69
- }
70
- const sortedMeasures = Array.from(noteData.keys()).sort((a, b) => a - b);
71
- let activeTimeScaleGroup = -1;
72
- for (const measure of sortedMeasures) {
73
- const headerMap = noteData.get(measure);
74
- const sortedHeaders = Array.from(headerMap.keys()).sort();
75
- for (const header of sortedHeaders) {
76
- const notes = headerMap.get(header);
77
- if (!notes || notes.length === 0)
78
- continue;
79
- const noteTimeScaleGroup = notes[0].timeScaleGroup;
80
- const tilId = tilIdMap.get(noteTimeScaleGroup);
81
- if (noteTimeScaleGroup !== activeTimeScaleGroup && tilId !== undefined) {
82
- susLines.push(`#HISPEED ${tilId}`);
83
- activeTimeScaleGroup = noteTimeScaleGroup;
84
- }
85
- if (header.endsWith("02") || header.endsWith("08")) {
86
- susLines.push(`#${header}: ${notes[0].value}`);
87
- continue;
88
- }
89
- const granularity = 1920;
90
- const data = Array(granularity).fill("00");
91
- for (const note of notes) {
92
- const index = Math.floor((note.tick / ticksPerMeasure) * granularity);
93
- if (index < granularity) {
94
- data[index] = note.value;
95
- }
96
- }
97
- susLines.push(`#${header}: ${data.join("")}`);
98
- }
99
- }
100
- return susLines.join("\r\n");
101
- // --- Helper Functions ---
102
- function addNoteData(measure, header, tickInMeasure, value, timeScaleGroup) {
103
- if (!noteData.has(measure))
104
- noteData.set(measure, new Map());
105
- const headerMap = noteData.get(measure);
106
- if (!headerMap.has(header))
107
- headerMap.set(header, []);
108
- headerMap.get(header).push({ tick: tickInMeasure, value, timeScaleGroup });
109
- }
110
- function getSusLaneAndWidth(uscLane, uscSize) {
111
- const susWidth = Math.round(uscSize * 2);
112
- const susLane = Math.round(uscLane - uscSize + 8);
113
- return [Math.max(0, susLane), Math.max(1, susWidth)];
114
- }
115
- function addTapNote(beat, lane, width, noteType, timeScaleGroup) {
116
- const tick = beat * TICKS_PER_BEAT;
117
- const measure = Math.floor(tick / ticksPerMeasure);
118
- const tickInMeasure = tick % ticksPerMeasure;
119
- const laneHex = lane.toString(36);
120
- const widthHex = width.toString(36);
121
- const header = `${measure.toString().padStart(3, "0")}1${laneHex}`;
122
- const value = `${noteType}${widthHex}`;
123
- addNoteData(measure, header, tickInMeasure, value, timeScaleGroup);
124
- }
125
- function processSingleOrDamage(note) {
126
- if (note.type === 'damage') {
127
- const [lane, width] = getSusLaneAndWidth(note.lane, note.size);
128
- addTapNote(note.beat, lane, width, "4", note.timeScaleGroup);
129
- return;
130
- }
131
- const [lane, width] = getSusLaneAndWidth(note.lane, note.size);
132
- let susNoteType = "1";
133
- if (note.critical && note.trace)
134
- susNoteType = "6";
135
- else if (note.critical)
136
- susNoteType = "2";
137
- else if (note.trace)
138
- susNoteType = "5";
139
- addTapNote(note.beat, lane, width, susNoteType, note.timeScaleGroup);
140
- if (note.direction && note.direction !== "none") {
141
- let directionalType;
142
- switch (note.direction) {
143
- case "up":
144
- directionalType = "1";
145
- break;
146
- case "left":
147
- directionalType = "3";
148
- break;
149
- case "right":
150
- directionalType = "4";
151
- break;
152
- default: return;
153
- }
154
- const [dirLane, dirWidth] = getSusLaneAndWidth(note.lane, note.size);
155
- const tick = note.beat * TICKS_PER_BEAT;
156
- const measure = Math.floor(tick / ticksPerMeasure);
157
- const tickInMeasure = tick % ticksPerMeasure;
158
- const dirHeader = `${measure.toString().padStart(3, "0")}5${dirLane.toString(36)}`;
159
- const dirValue = `${directionalType}${dirWidth.toString(36)}`;
160
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, note.timeScaleGroup);
161
- }
162
- }
163
- // ▼▼▼ 'tick', 'hidden', 'skip' 개념을 최종적으로 수정한 `processSlide` 함수 ▼▼▼
164
- function processSlide(slide) {
165
- const channel = (slideChannelCounter % 36).toString(36);
166
- const sortedConnections = [...slide.connections].sort((a, b) => a.beat - b.beat);
167
- let lastKnownLane = 0;
168
- let lastKnownWidth = 0;
169
- for (const conn of sortedConnections) {
170
- const tick = conn.beat * TICKS_PER_BEAT;
171
- const measure = Math.floor(tick / ticksPerMeasure);
172
- const tickInMeasure = tick % ticksPerMeasure;
173
- const timeScaleGroup = conn.timeScaleGroup ?? 0;
174
- // --- 3가지 규칙에 따른 분기 처리 ---
175
- if (conn.type === "tick") {
176
- // `critical` 속성 존재 여부로 '일반 Tick'과 'Hidden'을 구분합니다.
177
- if (conn.critical !== undefined) {
178
- // --- 일반 Tick 처리 ---
179
- // 경로에 영향을 주는 보이는 경유점(타입 3)을 생성합니다.
180
- const [lane, width] = getSusLaneAndWidth(conn.lane, conn.size);
181
- lastKnownLane = lane;
182
- lastKnownWidth = width;
183
- const laneHex = lane.toString(36);
184
- const header = `${measure.toString().padStart(3, "0")}3${laneHex}${channel}`;
185
- const value = `3${width.toString(36)}`;
186
- addNoteData(measure, header, tickInMeasure, value, timeScaleGroup);
187
- }
188
- else {
189
- // --- Hidden 노트 처리 ---
190
- // 경로에 영향을 주는 보이지 않는 경유점(타입 5)을 생성합니다.
191
- // 위치는 직전 노트의 것을 그대로 사용합니다.
192
- const laneHex = lastKnownLane.toString(36);
193
- const widthHex = lastKnownWidth.toString(36);
194
- const header = `${measure.toString().padStart(3, "0")}3${laneHex}${channel}`;
195
- const value = `5${widthHex}`;
196
- addNoteData(measure, header, tickInMeasure, value, timeScaleGroup);
197
- }
198
- }
199
- else if (conn.type === "attach") {
200
- // --- Skip 노트 처리 ---
201
- // 경로에 영향을 주지 않으므로 아무것도 생성하지 않고 건너뜁니다.
202
- continue;
203
- }
204
- else {
205
- // --- Start, End 노트 처리 ---
206
- const [lane, width] = getSusLaneAndWidth(conn.lane, conn.size);
207
- lastKnownLane = lane;
208
- lastKnownWidth = width;
209
- const isCritical = slide.critical || conn.critical;
210
- let markerType = null;
211
- if ("judgeType" in conn) {
212
- if (conn.judgeType === "none")
213
- markerType = isCritical ? "8" : "7";
214
- else if (conn.judgeType === "trace")
215
- markerType = isCritical ? "6" : "5";
216
- }
217
- if (conn.type === "start" && isCritical && markerType === null) {
218
- markerType = "2";
219
- }
220
- if (markerType) {
221
- addTapNote(conn.beat, lane, width, markerType, timeScaleGroup);
222
- }
223
- if ("ease" in conn && conn.ease) {
224
- let easeType = conn.ease;
225
- if (easeType === 'inout')
226
- easeType = 'in';
227
- if (easeType === 'outin')
228
- easeType = 'out';
229
- let directionalType = null;
230
- if (easeType === 'in')
231
- directionalType = '2';
232
- else if (easeType === 'out')
233
- directionalType = '5';
234
- if (directionalType) {
235
- const laneHex = lane.toString(36);
236
- const widthHex = width.toString(36);
237
- const dirHeader = `${measure.toString().padStart(3, "0")}5${laneHex}`;
238
- const dirValue = `${directionalType}${widthHex}`;
239
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, timeScaleGroup);
240
- }
241
- }
242
- const noteType = conn.type === "start" ? "1" : "2";
243
- const laneHex = lane.toString(36);
244
- const header = `${measure.toString().padStart(3, "0")}3${laneHex}${channel}`;
245
- const value = `${noteType}${width.toString(36)}`;
246
- addNoteData(measure, header, tickInMeasure, value, timeScaleGroup);
247
- if (conn.type === "end" && conn.direction) {
248
- let directionalType;
249
- switch (conn.direction) {
250
- case "up":
251
- directionalType = "1";
252
- break;
253
- case "left":
254
- directionalType = "3";
255
- break;
256
- case "right":
257
- directionalType = "4";
258
- break;
259
- default: continue;
260
- }
261
- const dirHeader = `${measure.toString().padStart(3, "0")}5${laneHex}`;
262
- const dirValue = `${directionalType}${width.toString(36)}`;
263
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, timeScaleGroup);
264
- }
265
- }
266
- }
267
- }
268
- function processGuide(guide) {
269
- const channel = (slideChannelCounter % 36).toString(36);
270
- const sortedMidpoints = [...guide.midpoints].sort((a, b) => a.beat - b.beat);
271
- sortedMidpoints.forEach((midpoint, index) => {
272
- const tick = midpoint.beat * TICKS_PER_BEAT;
273
- const measure = Math.floor(tick / ticksPerMeasure);
274
- const tickInMeasure = tick % ticksPerMeasure;
275
- let noteType;
276
- if (index === 0)
277
- noteType = "1";
278
- else if (index === sortedMidpoints.length - 1)
279
- noteType = "2";
280
- else
281
- noteType = "3";
282
- const [lane, width] = getSusLaneAndWidth(midpoint.lane, midpoint.size);
283
- const laneHex = lane.toString(36);
284
- const widthHex = width.toString(36);
285
- if (guide.fade === "in" && index === 0) {
286
- const dirHeader = `${measure.toString().padStart(3, "0")}5${laneHex}`;
287
- const dirValue = `2${widthHex}`;
288
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, midpoint.timeScaleGroup);
289
- }
290
- if (guide.fade === "out" && index === sortedMidpoints.length - 1) {
291
- const dirHeader = `${measure.toString().padStart(3, "0")}5${laneHex}`;
292
- const dirValue = `5${widthHex}`;
293
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, midpoint.timeScaleGroup);
294
- }
295
- if (midpoint.ease) {
296
- let easeType = midpoint.ease;
297
- if (easeType === 'inout')
298
- easeType = 'in';
299
- if (easeType === 'outin')
300
- easeType = 'out';
301
- let directionalType = null;
302
- if (easeType === 'in')
303
- directionalType = '2';
304
- else if (easeType === 'out')
305
- directionalType = '5';
306
- if (directionalType) {
307
- const dirHeader = `${measure.toString().padStart(3, "0")}5${laneHex}`;
308
- const dirValue = `${directionalType}${widthHex}`;
309
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, midpoint.timeScaleGroup);
310
- }
311
- }
312
- const header = `${measure.toString().padStart(3, "0")}9${laneHex}${channel}`;
313
- const value = `${noteType}${widthHex}`;
314
- addNoteData(measure, header, tickInMeasure, value, midpoint.timeScaleGroup);
315
- });
316
- }
317
- };
318
- exports.uscToSUS = uscToSUS;
@@ -1 +0,0 @@
1
- export declare const uscToSUS: (uscData: any) => string;
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.USCFade = exports.USCColor = void 0;
4
- exports.USCColor = {
5
- neutral: 0,
6
- red: 1,
7
- green: 2,
8
- blue: 3,
9
- yellow: 4,
10
- purple: 5,
11
- cyan: 6,
12
- black: 7,
13
- };
14
- exports.USCFade = {
15
- in: 2,
16
- out: 0,
17
- none: 1,
18
- };
@@ -1,339 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uscToSUS = void 0;
4
- const TICKS_PER_BEAT = 480;
5
- const uscToSUS = (uscData) => {
6
- const usc = uscData.usc ? uscData.usc : uscData;
7
- const susLines = [];
8
- const noteData = new Map();
9
- let slideChannelCounter = 0;
10
- // (메타데이터 및 전역 정의 생성은 이전과 동일)
11
- susLines.push(`#TITLE ""`, `#ARTIST ""`, `#DESIGNER ""`, `#WAVEOFFSET ${-usc.offset}`, `#REQUEST "ticks_per_beat ${TICKS_PER_BEAT}"`, ``);
12
- const ticksPerMeasure = TICKS_PER_BEAT * 4;
13
- const bpmObjects = usc.objects.filter((obj) => obj.type === 'bpm');
14
- const bpmDefinitions = new Map();
15
- let bpmCounter = 1;
16
- for (const bpmObject of bpmObjects) {
17
- if (!bpmDefinitions.has(bpmObject.bpm)) {
18
- const bpmId = bpmCounter.toString().padStart(2, '0');
19
- bpmDefinitions.set(bpmObject.bpm, bpmId);
20
- susLines.push(`#BPM${bpmId}: ${bpmObject.bpm}`);
21
- bpmCounter++;
22
- }
23
- }
24
- susLines.push(``);
25
- const timeScaleGroups = usc.objects.filter((obj) => obj.type === 'timeScaleGroup');
26
- const tilIdMap = new Map();
27
- timeScaleGroups.forEach((group, index) => {
28
- const tilId = index.toString().padStart(2, '0');
29
- tilIdMap.set(index, tilId);
30
- const changesString = group.changes
31
- .map((change) => {
32
- const totalTicks = change.beat * TICKS_PER_BEAT;
33
- const measure = Math.floor(totalTicks / ticksPerMeasure);
34
- const tickInMeasure = totalTicks % ticksPerMeasure;
35
- return `${measure}'${tickInMeasure}:${change.timeScale}`;
36
- })
37
- .join(', ');
38
- susLines.push(`#TIL${tilId}: "${changesString}"`);
39
- });
40
- susLines.push(``);
41
- addNoteData(0, '00002', 0, '4', 0);
42
- for (const bpmObject of bpmObjects) {
43
- const tick = bpmObject.beat * TICKS_PER_BEAT;
44
- const measure = Math.floor(tick / ticksPerMeasure);
45
- const tickInMeasure = tick % ticksPerMeasure;
46
- const bpmId = bpmDefinitions.get(bpmObject.bpm);
47
- if (bpmId) {
48
- addNoteData(measure, `${measure.toString().padStart(3, '0')}08`, tickInMeasure, bpmId, 0);
49
- }
50
- }
51
- for (const obj of usc.objects) {
52
- switch (obj.type) {
53
- case 'single':
54
- case 'damage':
55
- processSingleOrDamage(obj);
56
- break;
57
- case 'slide':
58
- processSlide(obj);
59
- slideChannelCounter++;
60
- break;
61
- case 'guide':
62
- processGuide(obj);
63
- slideChannelCounter++;
64
- break;
65
- case 'timeScaleGroup':
66
- case 'bpm':
67
- break;
68
- }
69
- }
70
- // ▼▼▼ 노트 겹침 및 BPM 겹침 오류를 모두 해결한 최종 렌더링 로직 ▼▼▼
71
- const sortedMeasures = Array.from(noteData.keys()).sort((a, b) => a - b);
72
- let activeTimeScaleGroup = -1;
73
- for (const measure of sortedMeasures) {
74
- const headerMap = noteData.get(measure);
75
- const sortedHeaders = Array.from(headerMap.keys()).sort();
76
- for (const header of sortedHeaders) {
77
- const notes = headerMap.get(header);
78
- if (!notes || notes.length === 0)
79
- continue;
80
- const noteTimeScaleGroup = notes[0].timeScaleGroup;
81
- const tilId = tilIdMap.get(noteTimeScaleGroup);
82
- if (noteTimeScaleGroup !== activeTimeScaleGroup && tilId !== undefined) {
83
- susLines.push(`#HISPEED ${tilId}`);
84
- activeTimeScaleGroup = noteTimeScaleGroup;
85
- }
86
- if (header.endsWith('02')) {
87
- susLines.push(`#${header}: ${notes[0].value}`);
88
- continue;
89
- }
90
- const granularity = 1920;
91
- const data = Array(granularity).fill('00');
92
- const finalNotes = new Map();
93
- const getPriority = (value) => {
94
- const typeChar = value.charAt(0);
95
- // Hidden 노트(타입 5)는 우선순위가 낮습니다.
96
- if (typeChar === '5')
97
- return 2;
98
- // 그 외 모든 노트(BPM 변경 포함)는 우선순위가 높습니다.
99
- return 1;
100
- };
101
- for (const note of notes) {
102
- const index = Math.floor((note.tick / ticksPerMeasure) * granularity);
103
- if (index >= granularity)
104
- continue;
105
- const existingNoteValue = finalNotes.get(index);
106
- const newNoteValue = note.value;
107
- if (!existingNoteValue ||
108
- getPriority(newNoteValue) <= getPriority(existingNoteValue)) {
109
- finalNotes.set(index, newNoteValue);
110
- }
111
- }
112
- for (const [index, value] of finalNotes.entries()) {
113
- data[index] = value;
114
- }
115
- susLines.push(`#${header}: ${data.join('')}`);
116
- }
117
- }
118
- return susLines.join('\r\n');
119
- // --- Helper Functions ---
120
- function addNoteData(measure, header, tickInMeasure, value, timeScaleGroup) {
121
- if (!noteData.has(measure))
122
- noteData.set(measure, new Map());
123
- const headerMap = noteData.get(measure);
124
- if (!headerMap.has(header))
125
- headerMap.set(header, []);
126
- headerMap.get(header).push({ tick: tickInMeasure, value, timeScaleGroup });
127
- }
128
- function getSusLaneAndWidth(uscLane, uscSize) {
129
- const susWidth = Math.round(uscSize * 2);
130
- const susLane = Math.round(uscLane - uscSize + 8);
131
- return [Math.max(0, susLane), Math.max(1, susWidth)];
132
- }
133
- function addTapNote(beat, lane, width, noteType, timeScaleGroup) {
134
- const tick = beat * TICKS_PER_BEAT;
135
- const measure = Math.floor(tick / ticksPerMeasure);
136
- const tickInMeasure = tick % ticksPerMeasure;
137
- const laneHex = lane.toString(36);
138
- const widthHex = width.toString(36);
139
- const header = `${measure.toString().padStart(3, '0')}1${laneHex}`;
140
- const value = `${noteType}${widthHex}`;
141
- addNoteData(measure, header, tickInMeasure, value, timeScaleGroup);
142
- }
143
- function processSingleOrDamage(note) {
144
- if (note.type === 'damage') {
145
- const [lane, width] = getSusLaneAndWidth(note.lane, note.size);
146
- addTapNote(note.beat, lane, width, '4', note.timeScaleGroup);
147
- return;
148
- }
149
- const [lane, width] = getSusLaneAndWidth(note.lane, note.size);
150
- let susNoteType = '1';
151
- if (note.critical && note.trace)
152
- susNoteType = '6';
153
- else if (note.critical)
154
- susNoteType = '2';
155
- else if (note.trace)
156
- susNoteType = '5';
157
- addTapNote(note.beat, lane, width, susNoteType, note.timeScaleGroup);
158
- if (note.direction && note.direction !== 'none') {
159
- let directionalType;
160
- switch (note.direction) {
161
- case 'up':
162
- directionalType = '1';
163
- break;
164
- case 'left':
165
- directionalType = '3';
166
- break;
167
- case 'right':
168
- directionalType = '4';
169
- break;
170
- default:
171
- return;
172
- }
173
- const [dirLane, dirWidth] = getSusLaneAndWidth(note.lane, note.size);
174
- const tick = note.beat * TICKS_PER_BEAT;
175
- const measure = Math.floor(tick / ticksPerMeasure);
176
- const tickInMeasure = tick % ticksPerMeasure;
177
- const dirHeader = `${measure.toString().padStart(3, '0')}5${dirLane.toString(36)}`;
178
- const dirValue = `${directionalType}${dirWidth.toString(36)}`;
179
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, note.timeScaleGroup);
180
- }
181
- }
182
- // ▼▼▼ `ease` 처리 로직을 최종 수정한 `processSlide` 함수 ▼▼▼
183
- function processSlide(slide) {
184
- const channel = (slideChannelCounter % 36).toString(36);
185
- const sortedConnections = [...slide.connections].sort((a, b) => a.beat - b.beat);
186
- let lastKnownLane = 0;
187
- let lastKnownWidth = 0;
188
- for (const conn of sortedConnections) {
189
- const tick = conn.beat * TICKS_PER_BEAT;
190
- const measure = Math.floor(tick / ticksPerMeasure);
191
- const tickInMeasure = tick % ticksPerMeasure;
192
- const timeScaleGroup = conn.timeScaleGroup ?? 0;
193
- const isCritical = slide.critical || conn.critical;
194
- let lane, width;
195
- if (conn.type !== 'attach' && 'lane' in conn && 'size' in conn) {
196
- ;
197
- [lane, width] = getSusLaneAndWidth(conn.lane, conn.size);
198
- lastKnownLane = lane;
199
- lastKnownWidth = width;
200
- }
201
- else {
202
- lane = lastKnownLane;
203
- width = lastKnownWidth;
204
- }
205
- const laneHex = lane.toString(36);
206
- const widthHex = width.toString(36);
207
- // --- 마커 및 방향성 노트 생성 로직 ---
208
- // 1. Easing 마커 (start, end, tick 모두에 적용)
209
- if ('ease' in conn && conn.ease) {
210
- let easeType = conn.ease;
211
- if (easeType === 'inout')
212
- easeType = 'in';
213
- if (easeType === 'outin')
214
- easeType = 'out';
215
- let directionalType = null;
216
- if (easeType === 'in')
217
- directionalType = '2';
218
- else if (easeType === 'out')
219
- directionalType = '5';
220
- if (directionalType) {
221
- const dirHeader = `${measure.toString().padStart(3, '0')}5${laneHex}`;
222
- const dirValue = `${directionalType}${widthHex}`;
223
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, timeScaleGroup);
224
- }
225
- }
226
- // 2. 기타 마커 및 Flick (start, end 에만 적용)
227
- if (conn.type === 'start' || conn.type === 'end') {
228
- let markerType = null;
229
- if ('judgeType' in conn) {
230
- if (conn.judgeType === 'none')
231
- markerType = isCritical ? '8' : '7';
232
- else if (conn.judgeType === 'trace')
233
- markerType = isCritical ? '6' : '5';
234
- }
235
- if (conn.type === 'start' && isCritical && markerType === null) {
236
- markerType = '2';
237
- }
238
- if (markerType) {
239
- addTapNote(conn.beat, lane, width, markerType, timeScaleGroup);
240
- }
241
- if (conn.type === 'end' && conn.direction) {
242
- let directionalType;
243
- switch (conn.direction) {
244
- case 'up':
245
- directionalType = '1';
246
- break;
247
- case 'left':
248
- directionalType = '3';
249
- break;
250
- case 'right':
251
- directionalType = '4';
252
- break;
253
- default:
254
- continue;
255
- }
256
- const dirHeader = `${measure.toString().padStart(3, '0')}5${laneHex}`;
257
- const dirValue = `${directionalType}${widthHex}`;
258
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, timeScaleGroup);
259
- }
260
- }
261
- // --- 실제 슬라이드 경로 노트 생성 로직 ---
262
- let noteType = null;
263
- switch (conn.type) {
264
- case 'start':
265
- noteType = '1';
266
- break;
267
- case 'end':
268
- noteType = '2';
269
- break;
270
- case 'tick':
271
- noteType = conn.critical !== undefined ? '3' : '5';
272
- break;
273
- case 'attach':
274
- // `convert.ts` 원리: '보이는 경유점(타입 3)' + '틱 제거 마커(타입 3)' 조합으로 변환
275
- const attachHeader = `${measure.toString().padStart(3, '0')}3${laneHex}${channel}`;
276
- const attachValue = `3${widthHex}`; // 보이는 경유점
277
- addNoteData(measure, attachHeader, tickInMeasure, attachValue, timeScaleGroup);
278
- // 틱 제거용 마커(SUS 탭 타입 3)
279
- addTapNote(conn.beat, lane, width, '3', timeScaleGroup);
280
- continue;
281
- }
282
- if (noteType) {
283
- const header = `${measure.toString().padStart(3, '0')}3${laneHex}${channel}`;
284
- const value = `${noteType}${widthHex}`;
285
- addNoteData(measure, header, tickInMeasure, value, timeScaleGroup);
286
- }
287
- }
288
- }
289
- function processGuide(guide) {
290
- const channel = (slideChannelCounter % 36).toString(36);
291
- const sortedMidpoints = [...guide.midpoints].sort((a, b) => a.beat - b.beat);
292
- sortedMidpoints.forEach((midpoint, index) => {
293
- const tick = midpoint.beat * TICKS_PER_BEAT;
294
- const measure = Math.floor(tick / ticksPerMeasure);
295
- const tickInMeasure = tick % ticksPerMeasure;
296
- let noteType;
297
- if (index === 0)
298
- noteType = '1';
299
- else if (index === sortedMidpoints.length - 1)
300
- noteType = '2';
301
- else
302
- noteType = '3';
303
- const [lane, width] = getSusLaneAndWidth(midpoint.lane, midpoint.size);
304
- const laneHex = lane.toString(36);
305
- const widthHex = width.toString(36);
306
- if (guide.fade === 'in' && index === 0) {
307
- const dirHeader = `${measure.toString().padStart(3, '0')}5${laneHex}`;
308
- const dirValue = `2${widthHex}`;
309
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, midpoint.timeScaleGroup);
310
- }
311
- if (guide.fade === 'out' && index === sortedMidpoints.length - 1) {
312
- const dirHeader = `${measure.toString().padStart(3, '0')}5${laneHex}`;
313
- const dirValue = `5${widthHex}`;
314
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, midpoint.timeScaleGroup);
315
- }
316
- if (midpoint.ease) {
317
- let easeType = midpoint.ease;
318
- if (easeType === 'inout')
319
- easeType = 'in';
320
- if (easeType === 'outin')
321
- easeType = 'out';
322
- let directionalType = null;
323
- if (easeType === 'in')
324
- directionalType = '2';
325
- else if (easeType === 'out')
326
- directionalType = '5';
327
- if (directionalType) {
328
- const dirHeader = `${measure.toString().padStart(3, '0')}5${laneHex}`;
329
- const dirValue = `${directionalType}${widthHex}`;
330
- addNoteData(measure, dirHeader, tickInMeasure, dirValue, midpoint.timeScaleGroup);
331
- }
332
- }
333
- const header = `${measure.toString().padStart(3, '0')}9${laneHex}${channel}`;
334
- const value = `${noteType}${widthHex}`;
335
- addNoteData(measure, header, tickInMeasure, value, midpoint.timeScaleGroup);
336
- });
337
- }
338
- };
339
- exports.uscToSUS = uscToSUS;
@@ -1 +0,0 @@
1
- export declare const uscToSUS: (uscData: any) => string;
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.USCFade = exports.USCColor = void 0;
4
- exports.USCColor = {
5
- neutral: 0,
6
- red: 1,
7
- green: 2,
8
- blue: 3,
9
- yellow: 4,
10
- purple: 5,
11
- cyan: 6,
12
- black: 7,
13
- };
14
- exports.USCFade = {
15
- in: 2,
16
- out: 0,
17
- none: 1,
18
- };
@@ -1,91 +0,0 @@
1
- export type USC = {
2
- offset: number;
3
- objects: USCObject[];
4
- };
5
- export type USCObject = USCBpmChange | USCTimeScaleChange | USCSingleNote | USCSlideNote | USCGuideNote | USCDamageNote;
6
- type BaseUSCObject = {
7
- beat: number;
8
- timeScaleGroup: number;
9
- };
10
- export type USCBpmChange = Omit<BaseUSCObject, 'timeScaleGroup'> & {
11
- type: 'bpm';
12
- bpm: number;
13
- };
14
- export type USCTimeScaleChange = {
15
- type: 'timeScaleGroup';
16
- changes: {
17
- beat: number;
18
- timeScale: number;
19
- }[];
20
- };
21
- type BaseUSCNote = BaseUSCObject & {
22
- lane: number;
23
- size: number;
24
- };
25
- export type USCSingleNote = BaseUSCNote & {
26
- type: 'single';
27
- critical: boolean;
28
- trace: boolean;
29
- direction?: 'left' | 'up' | 'right' | 'none';
30
- };
31
- export type USCDamageNote = BaseUSCNote & {
32
- type: 'damage';
33
- };
34
- export type USCConnectionStartNote = BaseUSCNote & {
35
- type: 'start';
36
- critical: boolean;
37
- ease: 'out' | 'linear' | 'in' | 'inout' | 'outin';
38
- judgeType: 'normal' | 'trace' | 'none';
39
- };
40
- export type USCConnectionTickNote = BaseUSCNote & {
41
- type: 'tick';
42
- critical?: boolean;
43
- ease: 'out' | 'linear' | 'in' | 'inout' | 'outin';
44
- };
45
- export type USCConnectionAttachNote = Omit<BaseUSCObject, 'timeScaleGroup'> & {
46
- type: 'attach';
47
- critical?: boolean;
48
- timeScaleGroup?: number;
49
- };
50
- export type USCConnectionEndNote = BaseUSCNote & {
51
- type: 'end';
52
- critical: boolean;
53
- direction?: 'left' | 'up' | 'right';
54
- judgeType: 'normal' | 'trace' | 'none';
55
- };
56
- export type USCSlideNote = {
57
- type: 'slide';
58
- critical: boolean;
59
- connections: [
60
- USCConnectionStartNote,
61
- ...(USCConnectionTickNote | USCConnectionAttachNote)[],
62
- USCConnectionEndNote
63
- ];
64
- };
65
- export declare const USCColor: {
66
- neutral: number;
67
- red: number;
68
- green: number;
69
- blue: number;
70
- yellow: number;
71
- purple: number;
72
- cyan: number;
73
- black: number;
74
- };
75
- export type USCColor = keyof typeof USCColor;
76
- export type USCGuideMidpointNote = BaseUSCNote & {
77
- ease: 'out' | 'linear' | 'in' | 'inout' | 'outin';
78
- };
79
- export declare const USCFade: {
80
- in: number;
81
- out: number;
82
- none: number;
83
- };
84
- export type USCFade = keyof typeof USCFade;
85
- export type USCGuideNote = {
86
- type: 'guide';
87
- color: USCColor;
88
- fade: USCFade;
89
- midpoints: USCGuideMidpointNote[];
90
- };
91
- export {};
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
File without changes
File without changes
File without changes