Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editing code that created directory which was breaking dump-sprites #6

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
Binary file modified config85.jag
Binary file not shown.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

95 changes: 83 additions & 12 deletions src/bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@

const { Config } = require('@2003scape/rsc-config');
const fs = require('fs').promises;
const mkdirp = require('mkdirp-promise');
const path = require('path');
const pkg = require('../package');
const yargs = require('yargs');
const { EntitySprites, MediaSprites, Textures } = require('./');
const compressSprites = require('./compress-sprites');
const { Image, createCanvas, loadImage } = require('canvas');

let fileNames = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,zz,zzz,zzzz".split(",");

async function dumpSprites(output, spriteMap) {
for (let [name, sprites] of spriteMap.entries()) {
sprites = Array.isArray(sprites) ? sprites : [sprites];

if (sprites.length > 1) {
await mkdirp(path.join(output, name));
fs.mkdir(path.join(output, name))

let index = 0;

for (const sprite of sprites) {
await fs.writeFile(
path.join(output, name, `${index}.png`),
path.join(output, name, `${fileNames[index]}.png`),
sprite.toBuffer()
);

Expand All @@ -34,6 +36,25 @@ async function dumpSprites(output, spriteMap) {
}
}

async function createImage(path) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onerror = err => reject(err);
image.onload = () => resolve(image);
image.src = path;
})
}

async function toCanvas(path) {
const image = await createImage(path);

const canvas = createCanvas(image.width, image.height);
const context = canvas.getContext('2d');
let loadedImage = await loadImage(path);
context.drawImage(loadedImage, 0, 0)
return canvas;
}

yargs
.scriptName('rsc-sprites')
.version(pkg.version)
Expand Down Expand Up @@ -75,9 +96,9 @@ yargs
try {
const config = new Config();
config.loadArchive(await fs.readFile(argv.config));

let spriteArchive;

if (argv.type === 'entity' || /entity/i.test(argv.archive)) {
spriteArchive = new EntitySprites(config);
} else if (
Expand All @@ -99,13 +120,13 @@ yargs
spriteArchive.loadArchive(await fs.readFile(argv.archive));

let output = argv.output;

if (!output) {
const ext = path.extname(argv.archive);
output = `${path.basename(argv.archive, ext)}-png`;
}

await mkdirp(output);
fs.mkdir(output);

await dumpSprites(output, spriteArchive.sprites);

if (
Expand Down Expand Up @@ -135,10 +156,60 @@ yargs
)
.command(
'pack-sprites <archive> <files..>',
'pack PNG file(s) into a sprites jag or mem archive',
(yargs) => {},
async (argv) => {}
'pack PNG file(s) into a sprites jag archive',
yargs => {
yargs.positional('archive', {
description: 'entity, media or textures jag/mem archive',
type: 'string'
});
yargs.positional('files', {
description: 'Dumped files to create a new archive'
});
yargs.positional('type', {
description: 'entity, media, or textures',
type: 'string'
});
},
async argv => {
const writeArchive = async (archive, filename) => {
await fs.writeFile(filename, archive);
};
if (argv.type === 'entity' || /entity/i.test(argv.archive)) {
try {
const ext = path.extname(argv.archive);
const archiveFileBase = argv.archive.split(ext)[0].replace(/[0-9]/g, '');
const archiveAddEdition = Number(argv.archive.split(ext)[0].replace(/\D/g,'')) + 1;
const newArchiveFileName = archiveFileBase + archiveAddEdition + ext;

let spriteMapToEncode = new Map();

for (const filename in argv.files) {

let subFolderFullName = argv.files[filename];
let subFolderPartialName = argv.files[filename].split("/")[1];
let subFolderValue = await fs.readdir(argv.files[filename]);

let canvasArray = [];

for(const png of subFolderValue) {
let pngFileLocation = subFolderFullName + "/" + png;
let newCanvas = await toCanvas(`${pngFileLocation}`);

canvasArray.push(newCanvas);
}
spriteMapToEncode.set(subFolderPartialName, canvasArray);
}

let spritesToEncode = compressSprites(spriteMapToEncode);

await writeArchive(spritesToEncode, `${newArchiveFileName}`);

} catch (e) {
console.log(e);
}
}
}
)
.command('dump-items <config> <archive>')
.command('dump-npcs <config> <archive>')
.demandCommand().argv;
.demandCommand().argv;
103 changes: 93 additions & 10 deletions src/compress-sprites.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,104 @@ const { JagArchive } = require('@2003scape/rsc-archiver');

function compressSprites(sprites) {
let indexLength = 0;
const encodedSprites = new Map();


const encodedSprites = new Map();
for (const [name, sprite] of sprites.entries()) {
const encoded = encodeSprite(sprite);
encodedSprites.set(name, encoded);
encoded.offset = indexLength;

// 2 shorts for full width and height 1 byte for palette length
indexLength += 5;
// A Sprite is an array of canvas objects
if (name === "gobweap" || name === "skelweap" || name === "zombweap" || name === "eyepatch") {
let spriteData = sprite.slice(0,15);
const encodedRegular = encodeSprite(spriteData);

encodedSprites.set(name, encodedRegular);

encodedRegular.offset = indexLength;

// 2 shorts (4 bytes) for full width and height 1 byte for palette length
indexLength = indexLength + 2 + 2 + 1;
// palette, 3 bytes per colour
indexLength += ((encodedRegular.palette.length - 1) * 3);
// 2 sprite offset bytes, width and height shorts, index order byte
indexLength += (encodedRegular.frames.length * 7);


let spriteDataFighting = sprite.slice(15,18);
const encodedFighting = encodeSprite(spriteDataFighting);

encodedSprites.set(`${name}a`, encodedFighting);

encodedFighting.offset = indexLength;

// 2 shorts (4 bytes) for full width and height 1 byte for palette length
indexLength = indexLength + 2 + 2 + 1;
// palette, 3 bytes per colour
indexLength += ((encodedFighting.palette.length - 1) * 3);
// 2 sprite offset bytes, width and height shorts, index order byte
indexLength += (encodedFighting.frames.length * 7);


// palette, 3 bytes per colour
indexLength += ((encoded.palette.length - 1) * 3);

// 2 sprite offset bytes, width and height shorts, index order byte
indexLength += (encoded.frames.length * 7);
let spriteDataAnimated = sprite.slice(18, 27);

const encodedAnimated = encodeSprite(spriteDataAnimated);

encodedSprites.set(`${name}f`, encodedAnimated);

encodedAnimated.offset = indexLength;

// 2 shorts (4 bytes) for full width and height 1 byte for palette length
indexLength = indexLength + 2 + 2 + 1;
// palette, 3 bytes per colour
indexLength += ((encodedAnimated.palette.length - 1) * 3);
// 2 sprite offset bytes, width and height shorts, index order byte
indexLength += (encodedAnimated.frames.length * 7);
count++;
}
if (name !== "crossbow" && name !== "longbow" && name !== "sheep" && name !== "gobweap" && name !== "skelweap" && name !== "zombweap" && name !== "eyepatch") {
let spriteData = sprite.slice(0,15);
const encodedRegular = encodeSprite(spriteData);
encodedSprites.set(name, encodedRegular);

encodedRegular.offset = indexLength;

// 2 shorts (4 bytes) for full width and height 1 byte for palette length
indexLength = indexLength + 2 + 2 + 1;
// palette, 3 bytes per colour
indexLength += ((encodedRegular.palette.length - 1) * 3);
// 2 sprite offset bytes, width and height shorts, index order byte
indexLength += (encodedRegular.frames.length * 7);


let spriteDataFighting = sprite.slice(15,18);

const encodedFighting = encodeSprite(spriteDataFighting);

encodedSprites.set(`${name}a`, encodedFighting);

encodedFighting.offset = indexLength;

// 2 shorts (4 bytes) for full width and height 1 byte for palette length
indexLength = indexLength + 2 + 2 + 1;
// palette, 3 bytes per colour
indexLength += ((encodedFighting.palette.length - 1) * 3);
// 2 sprite offset bytes, width and height shorts, index order byte
indexLength += (encodedFighting.frames.length * 7);
}
if (name === "crossbow" || name === "longbow" || name === "sheep") {
let spriteData = sprite;
const encodedRegular = encodeSprite(spriteData);

encodedSprites.set(name, encodedRegular);

encodedRegular.offset = indexLength;
// 2 shorts for full width and height 1 byte for palette length
indexLength += 5;
// palette, 3 bytes per colour
indexLength += (encodedRegular.palette.length - 1) * 3;
// 2 sprite offset bytes, width and height shorts, index order byte
indexLength += encodedRegular.frames.length * 7;
}
}

const archive = new JagArchive();
Expand Down
2 changes: 0 additions & 2 deletions src/encode-sprite.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ function getOffset(frame) {
// encode a collection of frames with the same palette
function encodeSprite(frames) {
frames = Array.isArray(frames) ? frames : [frames];

const fullWidth = frames[0].width;
const fullHeight = frames[0].height;

const palette = [0xff00ff];
const encodedFrames = [];

Expand Down
5 changes: 1 addition & 4 deletions src/entity-sprites.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class EntitySprites {
loadArchive(buffer) {
const archive = new JagArchive();
archive.readArchive(buffer);

const indexData = getDataBuffer(archive, 'index');

for (const { name, hasA, hasF } of this.animations) {
Expand All @@ -41,8 +40,7 @@ class EntitySprites {

try {
let spriteData = getDataBuffer(archive, name);
const frames = parseSprite(spriteData, indexData, 15);

let frames = parseSprite(spriteData, indexData, 15);
if (hasA) {
spriteData = getDataBuffer(archive, `${name}a`);
frames.push(...parseSprite(spriteData, indexData, 3));
Expand All @@ -52,7 +50,6 @@ class EntitySprites {
spriteData = getDataBuffer(archive, `${name}f`);
frames.push(...parseSprite(spriteData, indexData, 9));
}

this.sprites.set(name.toLowerCase(), frames);
} catch (e) {
// probably members animations when we only loaded free archive
Expand Down
Binary file removed textures17.jag
Binary file not shown.