M res/resources.json +1 -0
@@ 1,6 1,7 @@
{
"screenMode": 5,
"frameRate": 59.922743404312307,
+ "gamma": 2.42,
"tilemaps": [
{
"name": "FieldMap",
M tools/images.js +6 -2
@@ 153,9 153,13 @@ class PaletteColor {
}
class PNGLoader {
- constructor(path) {
+ constructor(path, gamma) {
checkTypes(arguments, "string");
this.path = path;
+ this.valueMapping3Bit = new Array(256);
+ for (let i = 0; i < 256; i++) {
+ this.valueMapping3Bit[i] = Math.round(Math.pow(i / 255, gamma / 2.2) * 7);
+ }
}
async loadImage() {
@@ 178,7 182,7 @@ class PNGLoader {
toPalette(palette8bit) {
checkTypes(arguments, Array);
const palette = new Palette();
- const palette3bit = palette8bit.map(c => Math.round(c / 255 * 7));
+ const palette3bit = palette8bit.map(c => this.valueMapping3Bit[c]);
for (let i = 0; i < palette3bit.length / 3; i++) {
const r = palette3bit[i * 3] || 0;
const g = palette3bit[i * 3 + 1] || 0;
M tools/resources.js +8 -6
@@ 21,10 21,11 @@ async function main() {
}
class Resources {
- constructor(screenMode, frameRate) {
- checkTypes(arguments, "number", "number");
+ constructor(screenMode, frameRate, gamma) {
+ checkTypes(arguments, "number", "number", "number");
this.screenMode = screenMode;
this.frameRate = frameRate;
+ this.gamma = gamma;
this.tileMaps = [];
this.images = [];
this.sprites = [];
@@ 86,24 87,25 @@ class ResourcesLoader {
const resources = new Resources(
json.screenMode,
- json.frameRate
+ json.frameRate,
+ json.gamma
);
const tileMaps = Promise.all(json.tilemaps.map(async jsonTileMap => {
const tileMapPath = path.resolve(path.dirname(this.path), jsonTileMap.path);
- return new Tmx(jsonTileMap.name, tileMapPath).parse();
+ return new Tmx(jsonTileMap.name, tileMapPath).parse(resources.gamma);
}));
const images = Promise.all(json.images.map(async jsonImage => {
const imagePath = path.resolve(path.dirname(this.path), jsonImage.path);
- const image = await new PNGLoader(imagePath).loadImage();
+ const image = await new PNGLoader(imagePath, resources.gamma).loadImage();
image.name = jsonImage.name;
return image;
}));
const sprites = Promise.all(json.sprites.map(async jsonSprite => {
const spritePath = path.resolve(path.dirname(this.path), jsonSprite.path);
- return new AsepriteSheet(jsonSprite.name, spritePath).parse();
+ return new AsepriteSheet(jsonSprite.name, spritePath).parse(resources.gamma);
}));
const audio = Promise.all(json.audio.map(async jsonTrack => {
M tools/sprites.js +7 -6
@@ 103,18 103,19 @@ class AsepriteSheet {
this.path = path;
}
- async parse() {
+ async parse(gamma) {
+ checkTypes(arguments, "number");
const json = JSON.parse(await fs.promises.readFile(this.path));
- const sprite = await this.parseSprite(json.meta, this.name);
+ const sprite = await this.parseSprite(json.meta, gamma);
this.parseFrames(json.frames, sprite);
return sprite;
}
- async parseSprite(jsonMeta, name) {
- checkTypes(arguments, Object, "string");
+ async parseSprite(jsonMeta, gamma) {
+ checkTypes(arguments, Object, "number");
const imagepath = path.resolve(path.dirname(this.path), jsonMeta.image);
- const image = await new PNGLoader(imagepath).loadImage();
- return new Sprite(name, image);
+ const image = await new PNGLoader(imagepath, gamma).loadImage();
+ return new Sprite(this.name, image);
}
parseFrames(jsonFrames, sprite) {
M tools/tilemaps.js +9 -8
@@ 128,14 128,15 @@ class Tmx {
this.path = path;
}
- async parse() {
+ async parse(gamma) {
+ checkTypes(arguments, "number");
const xml = await xml2js.parseStringPromise(await fs.promises.readFile(this.path));
- return this.parseMap(xml.map);
+ return this.parseMap(xml.map, gamma);
}
- async parseMap(mapXml) {
- checkTypes(arguments, Object);
- const tileSet = await this.parseSet(mapXml.tileset[0]);
+ async parseMap(mapXml, gamma) {
+ checkTypes(arguments, Object, "number");
+ const tileSet = await this.parseSet(mapXml.tileset[0], gamma);
const tileMap = new TileMap(this.name, ~~mapXml.$.width, ~~mapXml.$.height, tileSet);
const indices = mapXml.layer[0].data[0]._.replace(/\s/g, "").split(",").map(i => ~~i - 1);
for (const index of indices) {
@@ 144,10 145,10 @@ class Tmx {
return tileMap;
}
- async parseSet(setXml) {
- checkTypes(arguments, Object);
+ async parseSet(setXml, gamma) {
+ checkTypes(arguments, Object, "number");
const imagepath = path.resolve(path.dirname(this.path), setXml.image[0].$.source);
- const image = await new PNGLoader(imagepath).loadImage();
+ const image = await new PNGLoader(imagepath, gamma).loadImage();
const tileSet = new TileSet(setXml.$.name, ~~setXml.$.tilewidth, ~~setXml.$.tileheight, image.palette);
const tileImages = image.toTiles(tileSet.width, tileSet.height);
for (let i = 0; i < tileImages.length; i++) {