You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

cemu-smm

Package Overview
Dependencies
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.3 to 1.0.4

87

index.js
const crc32 = require("buffer-crc32");
const jimp = require("jimp");

@@ -13,2 +14,11 @@ const fs = require("fs");

const TNL_JPEG_MAX_SIZE = 0xC7F8;
const TNL_DIMENSION = [
[ 720, 81 ],
[ 320, 240 ]
];
const TNL_ASPECT_RATIO = [
TNL_DIMENSION[0][0] / TNL_DIMENSION[0][1],
TNL_DIMENSION[1][0] / TNL_DIMENSION[1][1]
];
const TNL_ASPECT_RATIO_THRESHOLD = [ 3.5, 0.3 ];

@@ -149,3 +159,3 @@ module.exports = {

let tnl = new Tnl(coursePath + "/thumbnail0.tnl");
let jpeg = await tnl.toJpeg();
let jpeg = await tnl.toJpeg(true);
fs.writeFile(coursePath + "/thumbnail0.jpg", jpeg, null, () => {

@@ -161,3 +171,3 @@ resolve();

let tnl = new Tnl(coursePath + "/thumbnail1.tnl");
let jpeg = await tnl.toJpeg();
let jpeg = await tnl.toJpeg(false);
fs.writeFile(coursePath + "/thumbnail1.jpg", jpeg, null, () => {

@@ -201,23 +211,66 @@ resolve();

fromJpeg: async function () {
fromJpeg: async function (isWide, doClip = false) {
return new Promise((resolve, reject) => {
fs.readFile(this.pathToFile, (err, data) => {
if (err) throw err;
if (data.length > TNL_JPEG_MAX_SIZE) {
reject("File size too big. Maximum length is 0xC7F8 bytes.");
return new Promise(async (resolve, reject) => {
// image pre-processing
let image = await jimp.read(this.pathToFile);
if (isWide === null) {
let aspectRatio = image.bitmap.width / image.bitmap.height;
if (aspectRatio > TNL_ASPECT_RATIO[0] - TNL_ASPECT_RATIO_THRESHOLD[0] && aspectRatio < TNL_ASPECT_RATIO[0] + TNL_ASPECT_RATIO_THRESHOLD[0]) {
isWide = true;
} else if (aspectRatio > TNL_ASPECT_RATIO[1] - TNL_ASPECT_RATIO_THRESHOLD[1] && aspectRatio < TNL_ASPECT_RATIO[1] + TNL_ASPECT_RATIO_THRESHOLD[1]) {
isWide = false;
}
let length = Buffer.alloc(4);
length.writeUInt32BE(data.length, 0);
if (isWide === null) {
isWide = TNL_ASPECT_RATIO[0] - TNL_ASPECT_RATIO_THRESHOLD[0] - aspectRatio <= TNL_ASPECT_RATIO[1] + TNL_ASPECT_RATIO_THRESHOLD[1] + aspectRatio;
}
}
let padding = Buffer.alloc(0xC800 - data.length - 8);
if (isWide) {
if (doClip) {
image.cover(TNL_DIMENSION[0][0], TNL_DIMENSION[0][1]);
} else {
image.contain(TNL_DIMENSION[0][0], TNL_DIMENSION[0][1]);
}
} else {
if (doClip) {
image.cover(TNL_DIMENSION[1][0], TNL_DIMENSION[1][1]);
} else {
image.contain(TNL_DIMENSION[1][0], TNL_DIMENSION[1][1]);
}
}
let fileWithoutCrc = Buffer.concat([length, data, padding], 0xC800 - 4);
// wrap tnl data around jpeg
let data = await new Promise((resolve) => {
image.getBuffer(jimp.MIME_JPEG, (err, buffer) => { resolve(buffer); });
});
let crcBuffer = Buffer.alloc(4);
crcBuffer.writeUInt32BE(crc32.unsigned(fileWithoutCrc), 0);
// lower quality until it fits
let quality = 100;
while (data.length > TNL_JPEG_MAX_SIZE) {
quality -= 5;
if (quality < 0) {
reject("File could not be transformed into jpeg with lowest quality setting.");
}
data = await new Promise((resolve) => {
image.quality(quality);
image.getBuffer(jimp.MIME_JPEG, (err, buffer) => { resolve(buffer); });
});
}
let tnl = Buffer.concat([crcBuffer, fileWithoutCrc], TNL_SIZE);
resolve(tnl);
})
let length = Buffer.alloc(4);
length.writeUInt32BE(data.length, 0);
let padding = Buffer.alloc(0xC800 - data.length - 8);
let fileWithoutCrc = Buffer.concat([length, data, padding], 0xC800 - 4);
let crcBuffer = Buffer.alloc(4);
crcBuffer.writeUInt32BE(crc32.unsigned(fileWithoutCrc), 0);
let tnl = Buffer.concat([crcBuffer, fileWithoutCrc], TNL_SIZE);
resolve(tnl);
});

@@ -224,0 +277,0 @@

5

package.json
{
"name": "cemu-smm",
"version": "1.0.3",
"version": "1.0.4",
"description": "This is a module to simplify all kinds of tasks with Loadiine Super Mario Maker save files and respectively Cemu",

@@ -12,3 +12,4 @@ "main": "index.js",

"dependencies": {
"buffer-crc32": "latest"
"buffer-crc32": "latest",
"jimp": "^0.2.27"
},

@@ -15,0 +16,0 @@ "repository": {

@@ -39,10 +39,89 @@ # cemu-smm

fs.writeFileSync("path/to/newly/created/jpeg", jpeg);
// convert jpeg to tnl
jpeg = smm.loadImage("path/to/your/jpeg/file");
// default conversion
tnl = await jpeg.fromJpeg();
fs.writeFileSync("path/to/newly/created/tnl", tnl);
// to wide
tnl = await jpeg.fromJpeg(true);
fs.writeFileSync("path/to/newly/created/tnl", tnl);
// to 4:3
tnl = await jpeg.fromJpeg(false);
fs.writeFileSync("path/to/newly/created/tnl", tnl);
})();
```
## API
### Reorder
Load your save
```js
let save = await smm.loadSave("path/to/your/cemu/save/mlc01/emulatorSave/updateID");
```
When calling
```js
save.reorder();
```
![Alt text](https://raw.githubusercontent.com/Tarnadas/cemu-smm/master/test/reorder_before.jpg)
becomes
![Alt text](https://raw.githubusercontent.com/Tarnadas/cemu-smm/master/test/reorder_after.jpg)
### TNL to JPEG
Load an image with
```js
let tnl = smm.loadImage("path/to/your/tnl/file");
```
Do the conversion with
```js
let jpeg = await jpeg.fromJpeg([isWide, [doCrop = false]]);
```
Save your file
```js
fs.writeFileSync("path/to/newly/created/jpeg", jpeg);
```
### JPEG to TNL
Load an image with
```js
let jpeg = smm.loadImage("path/to/your/jpeg/file");
```
Do the conversion with
```js
let tnl = await jpeg.fromJpeg([isWide, [doCrop = false]]);
```
If ```isWide === true```, thumbnail0 will be created, otherwise thumbnail1.
If ```isWide === null```, the algorithm tries to guess the correct aspect ratio.
If ```doCrop === false```, parts of the image may be letter boxed.
If ```doCrop === false```, parts of the image may be cropped.
Images will automatically be resized to fit Super Mario Maker standards. You can even convert 4k images. If the file is still too big after rescaling, the quality of the JPEG will be shrinked.
Save your file
```js
fs.writeFileSync("path/to/newly/created/jpeg", tnl);
```
### JPEG mass export
To convert all tnl files inside your save to jpeg, call
```js
save.exportJpeg();
```
Navigate to your save folder and find jpeg files inside course folders.
## License

@@ -49,0 +128,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc