popntowav/popnchart.js
2020-03-17 19:40:39 +00:00

100 lines
2.9 KiB
JavaScript

const fs = require("fs");
class PopnChart {
constructor(filename, offsetKeysounds=false) {
this.filename = filename;
this.data = fs.readFileSync(filename);
let newFormat = false;
if (this.data.readInt8(16) == 69) {
newFormat = true;
} else if (this.data.readInt8(12) == 69) {
newFormat = false;
} else {
throw "Chart format not supported.";
}
this.events = [];
let offset = 0;
while (offset < this.data.length) {
const eventOffset = this.data.readInt32LE(offset);
offset += 5;
const eventFlag = this.data.readInt8(offset);
offset += 1;
let eventParam = 0;
let eventValue = 0;
let joined = this.data.slice(offset, offset+2);
offset += 2;
if (eventFlag === 2 || eventFlag === 7) {
joined.swap16();
const hx = joined.toString("hex");
eventParam = parseInt(hx.slice(1, 4), 16);
eventValue = parseInt(hx.slice(0, 1), 16);
} else {
eventParam = joined.readUInt8(0);
eventValue = joined.readUInt8(1);
}
if (newFormat) {
const longNoteData = this.data.readInt32LE(offset);
offset += 4;
}
this.events.push([eventOffset, eventFlag, eventParam, eventValue]);
}
this.bpm = 0;
this.bpmTransitions = [];
this.playEvents = [];
this.uniqueKeysounds = [];
this.notecount = 0;
const sampleColumns = [0, 0, 0, 0, 0, 0, 0, 0, 0];
for (const event of this.events) {
let [offset, eventType, param, value] = event;
if (eventType == 7 || eventType == 2) {
if (this.uniqueKeysounds.indexOf(param) == -1) {
this.uniqueKeysounds.push(param);
}
}
switch (eventType) {
case 1:
if (sampleColumns[param] != 0) {
this.playEvents.push([offset, sampleColumns[param]]);
}
this.notecount += 1;
break;
case 2:
if (offsetKeysounds) {
param -= 1;
}
sampleColumns[value] = param;
break;
case 3:
this.playEvents.push([offset, 0]);
break;
case 4:
this.bpm = param;
this.bpmTransitions.push(param);
break;
case 7:
if (offsetKeysounds) {
param -= 1;
}
this.playEvents.push([offset, param]);
}
}
}
}
module.exports = PopnChart;