Comparing version 0.1.2 to 0.1.3
@@ -1,3 +0,4 @@ | ||
import { Envelope, VoiceData, MGSObject, TrackData } from "./types"; | ||
import { Envelope, VoiceData, MGSObject, TrackData, TextResource } from "./types"; | ||
export declare function declareEnvelope(env: Envelope): string; | ||
export declare function declareText(text: TextResource): string; | ||
export declare function buildAllocList(mgs: MGSObject): string; | ||
@@ -4,0 +5,0 @@ export declare function buildMMLHeader(mgs: MGSObject): string; |
@@ -55,2 +55,6 @@ "use strict"; | ||
exports.declareEnvelope = declareEnvelope; | ||
function declareText(text) { | ||
return "@m" + text.number + "={ \"" + text.text + "\" }"; | ||
} | ||
exports.declareText = declareText; | ||
function buildAllocList(mgs) { | ||
@@ -74,19 +78,20 @@ var allocMap = {}; | ||
exports.buildAllocList = buildAllocList; | ||
function buildMMLHeader(mgs) { | ||
var titleLines = mgs.title | ||
function makeTextBlock(text) { | ||
var lines = text | ||
.split(/\r\n/) | ||
.filter(function (e) { return e !== ""; }) | ||
.map(function (e) { return "\"" + e + "\""; }); | ||
var titleCommand; | ||
if (2 <= titleLines.length) { | ||
titleCommand = "#title {\n " + titleLines.join("\n ") + "\n}"; | ||
if (lines.length === 0) { | ||
return null; | ||
} | ||
else if (titleLines.length == 0 || titleLines[0] == '""') { | ||
titleCommand = ""; | ||
if (lines.length === 1) { | ||
return "{ " + lines.join("\n") + " }"; | ||
} | ||
else { | ||
titleCommand = "#title { " + titleLines.join("\n") + " }"; | ||
} | ||
return "; MML decompiled from MGS" + mgs.version + " object.\n#opll_mode " + mgs.settings.opllMode + "\n#lfo_mode " + mgs.settings.lfoMode + "\n#machine_id " + mgs.settings.machineId + "\n" + titleCommand + "\n#tempo " + mgs.tempo + "\n#alloc " + buildAllocList(mgs) + "\n"; | ||
return "{\n " + lines.join("\n ") + "\n}"; | ||
} | ||
function buildMMLHeader(mgs) { | ||
var titleBlock = makeTextBlock(mgs.title); | ||
var titleCommand = titleBlock ? "#title " + titleBlock : ""; | ||
return "; decompiler: mgsrc-js\n; mgs-version: " + mgs.version + "\n#opll_mode " + mgs.settings.opllMode + "\n#lfo_mode " + mgs.settings.lfoMode + "\n#machine_id " + mgs.settings.machineId + "\n" + titleCommand + "\n#tempo " + mgs.tempo + "\n#alloc " + buildAllocList(mgs) + "\n"; | ||
} | ||
exports.buildMMLHeader = buildMMLHeader; | ||
@@ -99,2 +104,3 @@ function buildVoiceMML(data) { | ||
} | ||
res.push(""); | ||
for (var _b = 0, _c = data.sccPatches; _b < _c.length; _b++) { | ||
@@ -104,2 +110,3 @@ var patch = _c[_b]; | ||
} | ||
res.push(""); | ||
for (var _d = 0, _e = data.envelopes; _d < _e.length; _d++) { | ||
@@ -109,2 +116,8 @@ var envelope = _e[_d]; | ||
} | ||
res.push(""); | ||
for (var _f = 0, _g = data.texts; _f < _g.length; _f++) { | ||
var text = _g[_f]; | ||
res.push(declareText(text)); | ||
} | ||
res.push(""); | ||
return res.join("\n"); | ||
@@ -125,3 +138,3 @@ } | ||
var cmd = _a[_i]; | ||
if (80 <= line.length) { | ||
if (!inPortamento && 80 <= line.length) { | ||
commitLine(); | ||
@@ -128,0 +141,0 @@ } |
@@ -78,5 +78,5 @@ "use strict"; | ||
catch (e) { | ||
console.error(e.message); | ||
console.error(e); | ||
} | ||
} | ||
main(process.argv); |
@@ -20,11 +20,13 @@ "use strict"; | ||
function c2l(n) { | ||
if (192 % n === 0) { | ||
return "" + 192 / n; | ||
if (2 < n) { | ||
if (192 % n === 0) { | ||
return "" + 192 / n; | ||
} | ||
if ((192 + 96) % n === 0) { | ||
return (192 + 96) / n + "."; | ||
} | ||
if ((192 + 96 + 48) % n === 0) { | ||
return (192 + 96 + 48) / n + ".."; | ||
} | ||
} | ||
if ((192 + 96) % n === 0) { | ||
return (192 + 96) / n + "."; | ||
} | ||
if ((192 + 96 + 48) % n === 0) { | ||
return (192 + 96 + 48) / n + ".."; | ||
} | ||
return "%" + n; | ||
@@ -78,4 +80,3 @@ } | ||
else if (cmd === 0x60) { | ||
var n = v.getUint8(idx++); | ||
res.push({ mml: "]" + n + "." }); | ||
res.push({ mml: "]" }); | ||
} | ||
@@ -92,2 +93,5 @@ else if (0x80 <= cmd && cmd <= 0x9f) { | ||
} | ||
else { | ||
throw new Error("Unknown Envelope Command: 0x" + cmd.toString(16)); | ||
} | ||
} | ||
@@ -97,2 +101,36 @@ return res; | ||
exports.parseStepEnvelope = parseStepEnvelope; | ||
function decodeMGSText(msg) { | ||
var seq = Array(); | ||
var i = 0; | ||
while (i < msg.length) { | ||
var ch = msg[i++]; | ||
if (ch < 0x20 || 0x80 === ch || (0xf0 <= ch && ch <= 0xff)) { | ||
var s = "\\x" + ("0" + ch.toString(16)).slice(-2); | ||
seq.push(s.charCodeAt(0)); | ||
seq.push(s.charCodeAt(1)); | ||
seq.push(s.charCodeAt(2)); | ||
seq.push(s.charCodeAt(3)); | ||
} | ||
else if (0x81 <= ch && ch <= 0x9f) { | ||
// SJIS 2-byte character | ||
seq.push(ch); | ||
seq.push(msg[i++]); | ||
} | ||
else if (0xe0 <= ch && ch <= 0xef) { | ||
// SJIS 2-byte character | ||
seq.push(ch); | ||
seq.push(msg[i++]); | ||
} | ||
else if (ch === 34 || ch === 92) { | ||
// double quote or backslash | ||
seq.push(92); | ||
seq.push(ch); | ||
} | ||
else { | ||
// Other characters | ||
seq.push(ch); | ||
} | ||
} | ||
return String.fromCharCode.apply(String, encoding_japanese_1.default.convert(seq, "UNICODE", "SJIS")); | ||
} | ||
function parseVoiceTrack(data) { | ||
@@ -103,2 +141,3 @@ var idx = 0; | ||
var envelopes = Array(); | ||
var texts = Array(); | ||
var v = new DataView(data); | ||
@@ -108,3 +147,3 @@ while (idx < v.byteLength) { | ||
if (cmd === 0x00) { | ||
var number = v.getUint8(idx++) & 0x1f; | ||
var number = v.getUint8(idx++); | ||
var patch = []; | ||
@@ -114,3 +153,3 @@ for (var i = 0; i < 8; i++) { | ||
} | ||
opllPatches.push({ number: number, data: patch }); | ||
opllPatches.push({ number: number & 0x1f, data: patch }); | ||
} | ||
@@ -150,5 +189,19 @@ else if (cmd === 0x02) { | ||
} | ||
else if (cmd === 0x06) { | ||
var number = v.getUint8(idx++); | ||
var buf = []; | ||
while (true) { | ||
var c = v.getUint8(idx++); | ||
if (c === 0) | ||
break; | ||
buf.push(c); | ||
} | ||
texts.push({ number: number, text: decodeMGSText(buf) }); | ||
} | ||
else if (cmd === 0xff) { | ||
break; | ||
} | ||
else { | ||
throw new Error("Unknown voice track command: 0x" + cmd.toString(16)); | ||
} | ||
} | ||
@@ -159,2 +212,3 @@ return { | ||
envelopes: envelopes, | ||
texts: texts, | ||
sccPatches: sccPatches, | ||
@@ -360,2 +414,5 @@ psgTunes: [], | ||
} | ||
else if (0xe0 <= cmd && cmd <= 0xe3) { | ||
_wrt({ mml: "/" + (cmd & 0x3) }); | ||
} | ||
else if (cmd === 0xff) { | ||
@@ -362,0 +419,0 @@ return "break"; |
@@ -7,2 +7,6 @@ export declare type Envelope = { | ||
}; | ||
export declare type TextResource = { | ||
number: number; | ||
text: string; | ||
}; | ||
export declare type StepEnvelope = Envelope & { | ||
@@ -43,2 +47,3 @@ commands: Array<any>; | ||
sccPatches: Array<SccPatch>; | ||
texts: Array<TextResource>; | ||
psgTunes: number[]; | ||
@@ -45,0 +50,0 @@ opllTunes: number[]; |
{ | ||
"name": "mgsrc-js", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"description": "Reverse Compiler for MGSDRV", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
29752
912