-
Notifications
You must be signed in to change notification settings - Fork 6
/
index.js
124 lines (99 loc) · 3.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
var fs, BufferReader, PNGImage, MultiBar, mbars, bars, sprFile, baseColor, base, async, exportImg, outDir;
fs = require('fs');
sprFile = process.argv[2];
outDir = process.argv[3];
// Checking if pass first argument
if(!sprFile || sprFile.length < 6) {
throw new Error('Missing Tibia.spr.');
}
// Check if second arg passed otherwise set to default output
if(!outDir) {
outDir = './out/';
}
// Check if last char is '/'
if(outDir.charAt(outDir.length-1) !='/') {
outDir = outDir + '/';
}
if(!fs.existsSync(outDir)) {
fs.mkdirSync(outDir);
}
// Checking if extension is .spr
if(sprFile.substring((sprFile.length - 4), sprFile.length) != '.spr') {
throw new Error('Only .spr is allowed!');
}
// Checking if file exists
if(!fs.existsSync(sprFile)) {
throw new Error('File not found: ' + sprFile);
}
MultiBar = require('./multibar.js');
mbars = new MultiBar();
bars = [];
BufferReader = require('buffer-reader');
PNGImage = require('pngjs-image');
async = require('async');
baseColor = {red: 255, green: 0, blue: 255, alpha: 255};
// Create a 32x32 with pink bg
base = function(spriteId) {
var image = PNGImage.createImage(32, 32);
for(i = 0; i < 32; i++) {
for(j = 0; j < 32; j++) {
image.setPixel(i,j, baseColor);
}
}
return {filename: spriteId, img: image};
}
exportImg = function(obj, cb) {
obj.img.writeImage(outDir + obj.filename + '.png', function() {
cb();
bars[1].tick();
});
};
var queue = async.queue(exportImg, 10);
queue.drain = function() {
console.log("\n");
}
fs.readFile(sprFile, function (err, buffer) {
if (err) throw err;
var reader = new BufferReader(buffer),
count = 0,
info = {
signature: reader.nextUInt32LE(),
size: reader.nextUInt16LE(),
};
console.log("Signature: " + info.signature);
console.log(" Sprites: " + info.size);
bars.push(mbars.newBar(' Parsing: [:bar] :percent | ETA: :eta | Time Elapsed: :elapsed', { complete: '=', incomplete: ' ', clear: true, width: 40, total: info.size }));
for(var spriteId = 1; spriteId < info.size; spriteId++) {
var obj = base(spriteId);
var formula = 6 + (spriteId - 1) * 4;
reader.seek(formula);
var address = reader.nextUInt32LE();
if (address == 0) { // Address 0 always is an empty sprite.
bars[0].tick();
continue;
}
reader.seek(address);
// Skipping color key.
reader.move(3);
var offset = reader.tell() + reader.nextUInt16LE();
var currentPixel = 0;
var size = 32;
while(reader.tell() < offset) {
var transparentPixels = reader.nextUInt16LE();
var coloredPixels = reader.nextUInt16LE();
currentPixel += transparentPixels;
for (var i = 0; i < coloredPixels; i++)
{
obj.img.setPixel(
parseInt(currentPixel % size),
parseInt(currentPixel / size),
{red:reader.nextUInt8(), green:reader.nextUInt8(), blue:reader.nextUInt8(), alpha:255});
currentPixel++;
}
}
count++;
queue.push(obj);
bars[0].tick();
}
bars.push(mbars.newBar('Exporting: [:bar] :percent | ETA: :eta | Time Elapsed: :elapsed', { complete: '=', incomplete: ' ', clear: true, width: 40, total: count }));
});