Refactor sprites to async/await

This cleans up the implementation quite a bit, and allows us to clean up the
data for the sprite data.

Most importantly, this allows us to avoid problems where a cursor file like
`main.cur` would be picked up as the `main.bmp` file as was the case here:

https://twitter.com/LuigiHann/status/879077419331747841
This commit is contained in:
Jordan Eldredge 2017-06-27 20:55:10 -07:00
parent e27a0db3fe
commit 9775c6b915
4 changed files with 476 additions and 557 deletions

View file

@ -1,6 +1,6 @@
{
"parserOptions": {
"ecmaVersion": 7,
"ecmaVersion": 8,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true,

View file

@ -3,7 +3,8 @@ import JSZip from "../node_modules/jszip/dist/jszip"; // Hack
import { parseViscolors, parseIni } from "./utils";
const bmpUriFromBase64 = data64 => `data:image/bmp;base64,${data64}`;
const imgFromUri = uri =>
const genImgNodeFromUri = uri =>
new Promise(resolve => {
const img = new Image();
img.onload = () => {
@ -13,101 +14,68 @@ const imgFromUri = uri =>
});
// "Promisify" processBuffer
const getBufferFromFile = file =>
const genBufferFromFile = file =>
new Promise(resolve => {
file.processBuffer(resolve);
});
const getZipFromBuffer = buffer => JSZip.loadAsync(buffer);
async function genFileFromZip(zip, fileName, ext, mode) {
const regex = new RegExp(`^(.*/)?${fileName}(\.${ext})?$`, "i");
const files = zip.file(regex);
if (!files.length) {
return null;
}
// Return a promise (awaitable).
return files[0].async(mode);
}
const getSpriteSheetFilesFromZip = zip => {
const spriteObjs = SKIN_SPRITES.map(spriteObj => ({
...spriteObj,
file: zip.file(new RegExp(`(/|^)${spriteObj.name}`, "i"))[0]
}));
return spriteObjs.filter(spriteObj => spriteObj.file);
};
function getSpriteUrisFromImg(img, sprites) {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
return sprites.reduce((images, sprite) => {
canvas.height = sprite.height;
canvas.width = sprite.width;
// Extract the CSS rules for a given file, and add them to the object
const extractCss = spriteObj =>
spriteObj.file
.async("base64")
.then(bmpUriFromBase64)
.then(imgFromUri)
.then(img => {
const canvas = document.createElement("canvas");
const images = {};
spriteObj.sprites.forEach(sprite => {
canvas.height = sprite.height;
canvas.width = sprite.width;
context.drawImage(img, -sprite.x, -sprite.y);
const image = canvas.toDataURL();
images[sprite.name] = image;
return images;
}, {});
}
const context = canvas.getContext("2d");
context.drawImage(img, -sprite.x, -sprite.y);
const image = canvas.toDataURL();
if (sprite.name) {
images[sprite.name] = image;
}
});
return { ...spriteObj, images };
});
// Extract the color data from a VISCOLOR.TXT file and add it to the object
const extractColors = spriteObj =>
spriteObj.file.async("text").then(content => ({
...spriteObj,
colors: parseViscolors(content)
}));
// Extract the color data from a VISCOLOR.TXT file and add it to the object
const extractPlaylistStyle = spriteObj =>
spriteObj.file.async("text").then(content => ({
...spriteObj,
playlistStyle: parseIni(content)
}));
const getSkinDataFromFiles = spriteObjs =>
Promise.all(
spriteObjs.map(spriteObj => {
switch (spriteObj.name) {
case "VISCOLOR":
return extractColors(spriteObj);
case "PLEDIT.TXT":
return extractPlaylistStyle(spriteObj);
default:
return extractCss(spriteObj);
}
})
);
const collectCssAndColors = spriteObjs => {
let images = {};
let colors = null;
let playlistStyle = null;
spriteObjs.forEach(spriteObj => {
if (spriteObj.images) {
images = { ...images, ...spriteObj.images };
}
if (spriteObj.colors) {
colors = spriteObj.colors;
}
if (spriteObj.playlistStyle) {
playlistStyle = spriteObj.playlistStyle;
}
});
return {
images,
colors,
playlistStyle
};
};
async function genSpriteUrisFromFilename(zip, fileName) {
const base64 = await genFileFromZip(zip, fileName, "bmp", "base64");
if (!base64) {
return {};
}
const uri = bmpUriFromBase64(base64);
const img = await genImgNodeFromUri(uri);
const spriteUris = getSpriteUrisFromImg(img, SKIN_SPRITES[fileName]);
return spriteUris;
}
// A promise that, given a File object, returns a skin style object
const parseSkin = file =>
getBufferFromFile(file)
.then(getZipFromBuffer)
.then(getSpriteSheetFilesFromZip)
.then(getSkinDataFromFiles)
.then(collectCssAndColors);
async function parseSkin(zipFile) {
const buffer = await genBufferFromFile(zipFile);
const zip = await JSZip.loadAsync(buffer);
const imageObjs = await Promise.all(
Object.keys(SKIN_SPRITES).map(
async fileName => await genSpriteUrisFromFilename(zip, fileName)
)
);
// Merge all the objects into a single object. Tests assert that sprite keys are unique.
const images = imageObjs.reduce(Object.assign, {});
// TODO: Handle this being null.
const viscolorContent = await genFileFromZip(zip, "VISCOLOR", "txt", "text");
const colors = parseViscolors(viscolorContent);
// TODO: Handle this being null.
const pleditContent = await genFileFromZip(zip, "PLEDIT", "txt", "text");
const playlistStyle = parseIni(pleditContent);
return { colors, playlistStyle, images };
}
export default parseSkin;

View file

@ -88,464 +88,416 @@ for (const key in FONT_LOOKUP) {
}
}
export default [
{
name: "BALANCE",
sprites: [
{ name: "MAIN_BALANCE_BACKGROUND", x: 9, y: 0, width: 38, height: 420 },
{ name: "MAIN_BALANCE_THUMB", x: 15, y: 422, width: 14, height: 11 },
{ name: "MAIN_BALANCE_THUMB_ACTIVE", x: 0, y: 422, width: 14, height: 11 }
]
},
{
name: "CBUTTONS",
sprites: [
{ name: "MAIN_PREVIOUS_BUTTON", x: 0, y: 0, width: 23, height: 18 },
{
name: "MAIN_PREVIOUS_BUTTON_ACTIVE",
x: 0,
y: 18,
width: 23,
height: 18
},
{ name: "MAIN_PLAY_BUTTON", x: 23, y: 0, width: 23, height: 18 },
{ name: "MAIN_PLAY_BUTTON_ACTIVE", x: 23, y: 18, width: 23, height: 18 },
{ name: "MAIN_PAUSE_BUTTON", x: 46, y: 0, width: 23, height: 18 },
{ name: "MAIN_PAUSE_BUTTON_ACTIVE", x: 46, y: 18, width: 23, height: 18 },
{ name: "MAIN_STOP_BUTTON", x: 69, y: 0, width: 23, height: 18 },
{ name: "MAIN_STOP_BUTTON_ACTIVE", x: 69, y: 18, width: 23, height: 18 },
{ name: "MAIN_NEXT_BUTTON", x: 92, y: 0, width: 23, height: 18 },
{ name: "MAIN_NEXT_BUTTON_ACTIVE", x: 92, y: 18, width: 22, height: 18 },
{ name: "MAIN_EJECT_BUTTON", x: 114, y: 0, width: 22, height: 16 },
{ name: "MAIN_EJECT_BUTTON_ACTIVE", x: 114, y: 16, width: 22, height: 16 }
]
},
{
name: "MAIN",
sprites: [
{ name: "MAIN_WINDOW_BACKGROUND", x: 0, y: 0, width: 275, height: 116 }
]
},
{
name: "MONOSTER",
sprites: [
{ name: "MAIN_STEREO", x: 0, y: 12, width: 29, height: 12 },
{ name: "MAIN_STEREO_SELECTED", x: 0, y: 0, width: 29, height: 12 },
{ name: "MAIN_MONO", x: 29, y: 12, width: 29, height: 12 },
{ name: "MAIN_MONO_SELECTED", x: 29, y: 0, width: 29, height: 12 }
]
},
{
name: "NUMBERS",
sprites: [
{ name: "NO_MINUS_SIGN", x: 9, y: 6, width: 5, height: 1 },
{ name: "MINUS_SIGN", x: 20, y: 6, width: 5, height: 1 },
{ name: "DIGIT_0", x: 0, y: 0, width: 9, height: 13 },
{ name: "DIGIT_1", x: 9, y: 0, width: 9, height: 13 },
{ name: "DIGIT_2", x: 18, y: 0, width: 9, height: 13 },
{ name: "DIGIT_3", x: 27, y: 0, width: 9, height: 13 },
{ name: "DIGIT_4", x: 36, y: 0, width: 9, height: 13 },
{ name: "DIGIT_5", x: 45, y: 0, width: 9, height: 13 },
{ name: "DIGIT_6", x: 54, y: 0, width: 9, height: 13 },
{ name: "DIGIT_7", x: 63, y: 0, width: 9, height: 13 },
{ name: "DIGIT_8", x: 72, y: 0, width: 9, height: 13 },
{ name: "DIGIT_9", x: 81, y: 0, width: 9, height: 13 }
]
},
{
name: "NUMS_EX",
sprites: [
{ name: "NO_MINUS_SIGN_EX", x: 90, y: 0, width: 9, height: 13 },
{ name: "MINUS_SIGN_EX", x: 99, y: 0, width: 9, height: 13 },
{ name: "DIGIT_0_EX", x: 0, y: 0, width: 9, height: 13 },
{ name: "DIGIT_1_EX", x: 9, y: 0, width: 9, height: 13 },
{ name: "DIGIT_2_EX", x: 18, y: 0, width: 9, height: 13 },
{ name: "DIGIT_3_EX", x: 27, y: 0, width: 9, height: 13 },
{ name: "DIGIT_4_EX", x: 36, y: 0, width: 9, height: 13 },
{ name: "DIGIT_5_EX", x: 45, y: 0, width: 9, height: 13 },
{ name: "DIGIT_6_EX", x: 54, y: 0, width: 9, height: 13 },
{ name: "DIGIT_7_EX", x: 63, y: 0, width: 9, height: 13 },
{ name: "DIGIT_8_EX", x: 72, y: 0, width: 9, height: 13 },
{ name: "DIGIT_9_EX", x: 81, y: 0, width: 9, height: 13 }
]
},
{
name: "PLAYPAUS",
sprites: [
{ name: "MAIN_PLAYING_INDICATOR", x: 0, y: 0, width: 9, height: 9 },
{ name: "MAIN_PAUSED_INDICATOR", x: 9, y: 0, width: 9, height: 9 },
{ name: "MAIN_STOPPED_INDICATOR", x: 18, y: 0, width: 9, height: 9 },
{ name: "MAIN_NOT_WORKING_INDICATOR", x: 36, y: 0, width: 9, height: 9 },
{ name: "MAIN_WORKING_INDICATOR", x: 39, y: 0, width: 9, height: 9 }
]
},
{
name: "PLEDIT.BMP",
sprites: [
{ name: "PLAYLIST_TOP_TILE", x: 127, y: 21, width: 25, height: 20 },
{ name: "PLAYLIST_TOP_LEFT_CORNER", x: 0, y: 21, width: 25, height: 20 },
{ name: "PLAYLIST_TITLE_BAR", x: 26, y: 21, width: 100, height: 20 },
{
name: "PLAYLIST_TOP_RIGHT_CORNER",
x: 153,
y: 21,
width: 25,
height: 20
},
{
name: "PLAYLIST_TOP_TILE_SELECTED",
x: 127,
y: 0,
width: 25,
height: 20
},
{ name: "PLAYLIST_TOP_LEFT_SELECTED", x: 0, y: 0, width: 25, height: 20 },
{
name: "PLAYLIST_TITLE_BAR_SELECTED",
x: 26,
y: 0,
width: 100,
height: 20
},
{
name: "PLAYLIST_TOP_RIGHT_CORNER_SELECTED",
x: 153,
y: 0,
width: 25,
height: 20
},
{ name: "PLAYLIST_LEFT_TILE", x: 0, y: 42, width: 25, height: 29 },
{ name: "PLAYLIST_RIGHT_TILE", x: 26, y: 42, width: 25, height: 29 },
{ name: "PLAYLIST_BOTTOM_TILE", x: 179, y: 0, width: 25, height: 38 },
{
name: "PLAYLIST_BOTTOM_LEFT_CORNER",
x: 0,
y: 72,
width: 125,
height: 38
},
{
name: "PLAYLIST_BOTTOM_RIGHT_CORNER",
x: 126,
y: 72,
width: 150,
height: 38
},
{
name: "PLAYLIST_VISUALIZER_BACKGROUND",
x: 205,
y: 0,
width: 75,
height: 38
},
{ name: "PLAYLIST_SHADE_BACKGROUND", x: 72, y: 57, width: 25, height: 14 }
]
},
{
name: "EQMAIN",
sprites: [
{ name: "EQ_WINDOW_BACKGROUND", x: 0, y: 0, width: 275, height: 116 },
{ name: "EQ_TITLE_BAR", x: 0, y: 149, width: 275, height: 14 },
{ name: "EQ_TITLE_BAR_SELECTED", x: 0, y: 134, width: 275, height: 14 },
{ name: "EQ_SLIDER_BACKGROUND", x: 13, y: 164, width: 209, height: 129 },
{ name: "EQ_SLIDER_THUMB", x: 0, y: 164, width: 11, height: 11 },
{ name: "EQ_SLIDER_THUMB_SELECTED", x: 0, y: 176, width: 11, height: 11 },
{ name: "EQ_ON_BUTTON", x: 10, y: 119, width: 26, height: 12 },
{ name: "EQ_ON_BUTTON_DEPRESSED", x: 128, y: 119, width: 26, height: 12 },
{ name: "EQ_ON_BUTTON_SELECTED", x: 69, y: 119, width: 26, height: 12 },
{
name: "EQ_ON_BUTTON_SELECTED_DEPRESSED",
x: 187,
y: 119,
width: 26,
height: 12
},
{ name: "EQ_AUTO_BUTTON", x: 36, y: 119, width: 32, height: 12 },
{
name: "EQ_AUTO_BUTTON_DEPRESSED",
x: 154,
y: 119,
width: 32,
height: 12
},
{ name: "EQ_AUTO_BUTTON_SELECTED", x: 95, y: 119, width: 32, height: 12 },
{
name: "EQ_AUTO_BUTTON_SELECTED_DEPRESSED",
x: 213,
y: 119,
width: 32,
height: 12
},
{ name: "EQ_GRAPH_BACKGROUND", x: 0, y: 294, width: 113, height: 19 },
{ name: "EQ_GRAPH_LINE_COLORS", x: 115, y: 294, width: 1, height: 19 },
{ name: "EQ_PRESETS_BUTTON", x: 224, y: 164, width: 44, height: 12 },
{
name: "EQ_PRESETS_BUTTON_SELECTED",
x: 224,
y: 176,
width: 44,
height: 12
},
{ name: "EQ_PREAMP_LINE", x: 0, y: 314, width: 113, height: 1 }
]
},
{
name: "POSBAR",
sprites: [
{
name: "MAIN_POSITION_SLIDER_BACKGROUND",
x: 0,
y: 0,
width: 248,
height: 10
},
{
name: "MAIN_POSITION_SLIDER_THUMB",
x: 248,
y: 0,
width: 29,
height: 10
},
{
name: "MAIN_POSITION_SLIDER_THUMB_SELECTED",
x: 278,
y: 0,
width: 29,
height: 10
}
]
},
{
name: "SHUFREP",
sprites: [
{ name: "MAIN_SHUFFLE_BUTTON", x: 28, y: 0, width: 47, height: 15 },
{
name: "MAIN_SHUFFLE_BUTTON_DEPRESSED",
x: 28,
y: 15,
width: 47,
height: 15
},
{
name: "MAIN_SHUFFLE_BUTTON_SELECTED",
x: 28,
y: 30,
width: 47,
height: 15
},
{
name: "MAIN_SHUFFLE_BUTTON_SELECTED_DEPRESSED",
x: 28,
y: 45,
width: 47,
height: 15
},
{ name: "MAIN_REPEAT_BUTTON", x: 0, y: 0, width: 28, height: 15 },
{
name: "MAIN_REPEAT_BUTTON_DEPRESSED",
x: 0,
y: 15,
width: 28,
height: 15
},
{
name: "MAIN_REPEAT_BUTTON_SELECTED",
x: 0,
y: 30,
width: 28,
height: 15
},
{
name: "MAIN_REPEAT_BUTTON_SELECTED_DEPRESSED",
x: 0,
y: 45,
width: 28,
height: 15
},
{ name: "MAIN_EQ_BUTTON", x: 0, y: 61, width: 23, height: 12 },
{ name: "MAIN_EQ_BUTTON_SELECTED", x: 0, y: 73, width: 23, height: 12 },
{ name: "MAIN_EQ_BUTTON_DEPRESSED", x: 46, y: 61, width: 23, height: 12 },
{
name: "MAIN_EQ_BUTTON_DEPRESSED_SELECTED",
x: 46,
y: 73,
width: 23,
height: 12
},
{ name: "MAIN_PLAYLIST_BUTTON", x: 23, y: 61, width: 23, height: 12 },
{
name: "MAIN_PLAYLIST_BUTTON_SELECTED",
x: 23,
y: 73,
width: 23,
height: 12
},
{
name: "MAIN_PLAYLIST_BUTTON_DEPRESSED",
x: 69,
y: 61,
width: 23,
height: 12
},
{
name: "MAIN_PLAYLIST_BUTTON_DEPRESSED_SELECTED",
x: 69,
y: 62,
width: 23,
height: 12
}
]
},
{
name: "TEXT",
sprites: characterSprites
},
{
name: "TITLEBAR",
sprites: [
{ name: "MAIN_TITLE_BAR", x: 27, y: 15, width: 275, height: 14 },
{ name: "MAIN_TITLE_BAR_SELECTED", x: 27, y: 0, width: 275, height: 14 },
{
name: "MAIN_EASTER_EGG_TITLE_BAR",
x: 27,
y: 61,
width: 275,
height: 14
},
{
name: "MAIN_EASTER_EGG_TITLE_BAR_SELECTED",
x: 27,
y: 57,
width: 275,
height: 14
},
{ name: "MAIN_OPTIONS_BUTTON", x: 0, y: 0, width: 9, height: 9 },
{
name: "MAIN_OPTIONS_BUTTON_DEPRESSED",
x: 0,
y: 9,
width: 9,
height: 9
},
{ name: "MAIN_MINIMIZE_BUTTON", x: 9, y: 0, width: 9, height: 9 },
{
name: "MAIN_MINIMIZE_BUTTON_DEPRESSED",
x: 9,
y: 9,
width: 9,
height: 9
},
{ name: "MAIN_SHADE_BUTTON", x: 0, y: 18, width: 9, height: 9 },
{ name: "MAIN_SHADE_BUTTON_DEPRESSED", x: 9, y: 18, width: 9, height: 9 },
{ name: "MAIN_CLOSE_BUTTON", x: 18, y: 0, width: 9, height: 9 },
{ name: "MAIN_CLOSE_BUTTON_DEPRESSED", x: 18, y: 9, width: 9, height: 9 },
{
name: "MAIN_CLUTTER_BAR_BACKGROUND",
x: 304,
y: 0,
width: 8,
height: 43
},
{
name: "MAIN_CLUTTER_BAR_BACKGROUND_DISABLED",
x: 312,
y: 0,
width: 8,
height: 43
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_O_SELECTED",
x: 304,
y: 47,
width: 8,
height: 8
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_A_SELECTED",
x: 312,
y: 55,
width: 8,
height: 7
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_I_SELECTED",
x: 320,
y: 62,
width: 8,
height: 7
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_D_SELECTED",
x: 328,
y: 69,
width: 8,
height: 8
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_V_SELECTED",
x: 336,
y: 77,
width: 8,
height: 7
},
{ name: "MAIN_SHADE_BACKGROUND", x: 27, y: 42, width: 275, height: 14 },
{
name: "MAIN_SHADE_BACKGROUND_SELECTED",
x: 27,
y: 29,
width: 275,
height: 14
},
{ name: "MAIN_SHADE_BUTTON_SELECTED", x: 0, y: 27, width: 9, height: 9 },
{
name: "MAIN_SHADE_BUTTON_SELECTED_DEPRESSED",
x: 9,
y: 27,
width: 9,
height: 9
},
{
name: "MAIN_SHADE_POSITION_BACKGROUND",
x: 0,
y: 36,
width: 17,
height: 7
},
{ name: "MAIN_SHADE_POSITION_THUMB", x: 20, y: 36, width: 3, height: 7 },
{
name: "MAIN_SHADE_POSITION_THUMB_LEFT",
x: 17,
y: 36,
width: 3,
height: 7
},
{
name: "MAIN_SHADE_POSITION_THUMB_RIGHT",
x: 23,
y: 36,
width: 3,
height: 7
}
]
},
{
name: "VOLUME",
sprites: [
{ name: "MAIN_VOLUME_BACKGROUND", x: 0, y: 0, width: 68, height: 420 },
{ name: "MAIN_VOLUME_THUMB", x: 15, y: 422, width: 14, height: 11 },
{
name: "MAIN_VOLUME_THUMB_SELECTED",
x: 0,
y: 422,
width: 14,
height: 11
}
]
},
{
name: "VISCOLOR"
},
{
name: "PLEDIT.TXT"
}
];
export default {
BALANCE: [
{ name: "MAIN_BALANCE_BACKGROUND", x: 9, y: 0, width: 38, height: 420 },
{ name: "MAIN_BALANCE_THUMB", x: 15, y: 422, width: 14, height: 11 },
{ name: "MAIN_BALANCE_THUMB_ACTIVE", x: 0, y: 422, width: 14, height: 11 }
],
CBUTTONS: [
{ name: "MAIN_PREVIOUS_BUTTON", x: 0, y: 0, width: 23, height: 18 },
{
name: "MAIN_PREVIOUS_BUTTON_ACTIVE",
x: 0,
y: 18,
width: 23,
height: 18
},
{ name: "MAIN_PLAY_BUTTON", x: 23, y: 0, width: 23, height: 18 },
{ name: "MAIN_PLAY_BUTTON_ACTIVE", x: 23, y: 18, width: 23, height: 18 },
{ name: "MAIN_PAUSE_BUTTON", x: 46, y: 0, width: 23, height: 18 },
{ name: "MAIN_PAUSE_BUTTON_ACTIVE", x: 46, y: 18, width: 23, height: 18 },
{ name: "MAIN_STOP_BUTTON", x: 69, y: 0, width: 23, height: 18 },
{ name: "MAIN_STOP_BUTTON_ACTIVE", x: 69, y: 18, width: 23, height: 18 },
{ name: "MAIN_NEXT_BUTTON", x: 92, y: 0, width: 23, height: 18 },
{ name: "MAIN_NEXT_BUTTON_ACTIVE", x: 92, y: 18, width: 22, height: 18 },
{ name: "MAIN_EJECT_BUTTON", x: 114, y: 0, width: 22, height: 16 },
{ name: "MAIN_EJECT_BUTTON_ACTIVE", x: 114, y: 16, width: 22, height: 16 }
],
MAIN: [
{ name: "MAIN_WINDOW_BACKGROUND", x: 0, y: 0, width: 275, height: 116 }
],
MONOSTER: [
{ name: "MAIN_STEREO", x: 0, y: 12, width: 29, height: 12 },
{ name: "MAIN_STEREO_SELECTED", x: 0, y: 0, width: 29, height: 12 },
{ name: "MAIN_MONO", x: 29, y: 12, width: 29, height: 12 },
{ name: "MAIN_MONO_SELECTED", x: 29, y: 0, width: 29, height: 12 }
],
NUMBERS: [
{ name: "NO_MINUS_SIGN", x: 9, y: 6, width: 5, height: 1 },
{ name: "MINUS_SIGN", x: 20, y: 6, width: 5, height: 1 },
{ name: "DIGIT_0", x: 0, y: 0, width: 9, height: 13 },
{ name: "DIGIT_1", x: 9, y: 0, width: 9, height: 13 },
{ name: "DIGIT_2", x: 18, y: 0, width: 9, height: 13 },
{ name: "DIGIT_3", x: 27, y: 0, width: 9, height: 13 },
{ name: "DIGIT_4", x: 36, y: 0, width: 9, height: 13 },
{ name: "DIGIT_5", x: 45, y: 0, width: 9, height: 13 },
{ name: "DIGIT_6", x: 54, y: 0, width: 9, height: 13 },
{ name: "DIGIT_7", x: 63, y: 0, width: 9, height: 13 },
{ name: "DIGIT_8", x: 72, y: 0, width: 9, height: 13 },
{ name: "DIGIT_9", x: 81, y: 0, width: 9, height: 13 }
],
NUMS_EX: [
{ name: "NO_MINUS_SIGN_EX", x: 90, y: 0, width: 9, height: 13 },
{ name: "MINUS_SIGN_EX", x: 99, y: 0, width: 9, height: 13 },
{ name: "DIGIT_0_EX", x: 0, y: 0, width: 9, height: 13 },
{ name: "DIGIT_1_EX", x: 9, y: 0, width: 9, height: 13 },
{ name: "DIGIT_2_EX", x: 18, y: 0, width: 9, height: 13 },
{ name: "DIGIT_3_EX", x: 27, y: 0, width: 9, height: 13 },
{ name: "DIGIT_4_EX", x: 36, y: 0, width: 9, height: 13 },
{ name: "DIGIT_5_EX", x: 45, y: 0, width: 9, height: 13 },
{ name: "DIGIT_6_EX", x: 54, y: 0, width: 9, height: 13 },
{ name: "DIGIT_7_EX", x: 63, y: 0, width: 9, height: 13 },
{ name: "DIGIT_8_EX", x: 72, y: 0, width: 9, height: 13 },
{ name: "DIGIT_9_EX", x: 81, y: 0, width: 9, height: 13 }
],
PLAYPAUS: [
{ name: "MAIN_PLAYING_INDICATOR", x: 0, y: 0, width: 9, height: 9 },
{ name: "MAIN_PAUSED_INDICATOR", x: 9, y: 0, width: 9, height: 9 },
{ name: "MAIN_STOPPED_INDICATOR", x: 18, y: 0, width: 9, height: 9 },
{ name: "MAIN_NOT_WORKING_INDICATOR", x: 36, y: 0, width: 9, height: 9 },
{ name: "MAIN_WORKING_INDICATOR", x: 39, y: 0, width: 9, height: 9 }
],
PLEDIT: [
{ name: "PLAYLIST_TOP_TILE", x: 127, y: 21, width: 25, height: 20 },
{ name: "PLAYLIST_TOP_LEFT_CORNER", x: 0, y: 21, width: 25, height: 20 },
{ name: "PLAYLIST_TITLE_BAR", x: 26, y: 21, width: 100, height: 20 },
{
name: "PLAYLIST_TOP_RIGHT_CORNER",
x: 153,
y: 21,
width: 25,
height: 20
},
{
name: "PLAYLIST_TOP_TILE_SELECTED",
x: 127,
y: 0,
width: 25,
height: 20
},
{ name: "PLAYLIST_TOP_LEFT_SELECTED", x: 0, y: 0, width: 25, height: 20 },
{
name: "PLAYLIST_TITLE_BAR_SELECTED",
x: 26,
y: 0,
width: 100,
height: 20
},
{
name: "PLAYLIST_TOP_RIGHT_CORNER_SELECTED",
x: 153,
y: 0,
width: 25,
height: 20
},
{ name: "PLAYLIST_LEFT_TILE", x: 0, y: 42, width: 25, height: 29 },
{ name: "PLAYLIST_RIGHT_TILE", x: 26, y: 42, width: 25, height: 29 },
{ name: "PLAYLIST_BOTTOM_TILE", x: 179, y: 0, width: 25, height: 38 },
{
name: "PLAYLIST_BOTTOM_LEFT_CORNER",
x: 0,
y: 72,
width: 125,
height: 38
},
{
name: "PLAYLIST_BOTTOM_RIGHT_CORNER",
x: 126,
y: 72,
width: 150,
height: 38
},
{
name: "PLAYLIST_VISUALIZER_BACKGROUND",
x: 205,
y: 0,
width: 75,
height: 38
},
{ name: "PLAYLIST_SHADE_BACKGROUND", x: 72, y: 57, width: 25, height: 14 }
],
EQMAIN: [
{ name: "EQ_WINDOW_BACKGROUND", x: 0, y: 0, width: 275, height: 116 },
{ name: "EQ_TITLE_BAR", x: 0, y: 149, width: 275, height: 14 },
{ name: "EQ_TITLE_BAR_SELECTED", x: 0, y: 134, width: 275, height: 14 },
{ name: "EQ_SLIDER_BACKGROUND", x: 13, y: 164, width: 209, height: 129 },
{ name: "EQ_SLIDER_THUMB", x: 0, y: 164, width: 11, height: 11 },
{ name: "EQ_SLIDER_THUMB_SELECTED", x: 0, y: 176, width: 11, height: 11 },
{ name: "EQ_ON_BUTTON", x: 10, y: 119, width: 26, height: 12 },
{ name: "EQ_ON_BUTTON_DEPRESSED", x: 128, y: 119, width: 26, height: 12 },
{ name: "EQ_ON_BUTTON_SELECTED", x: 69, y: 119, width: 26, height: 12 },
{
name: "EQ_ON_BUTTON_SELECTED_DEPRESSED",
x: 187,
y: 119,
width: 26,
height: 12
},
{ name: "EQ_AUTO_BUTTON", x: 36, y: 119, width: 32, height: 12 },
{
name: "EQ_AUTO_BUTTON_DEPRESSED",
x: 154,
y: 119,
width: 32,
height: 12
},
{ name: "EQ_AUTO_BUTTON_SELECTED", x: 95, y: 119, width: 32, height: 12 },
{
name: "EQ_AUTO_BUTTON_SELECTED_DEPRESSED",
x: 213,
y: 119,
width: 32,
height: 12
},
{ name: "EQ_GRAPH_BACKGROUND", x: 0, y: 294, width: 113, height: 19 },
{ name: "EQ_GRAPH_LINE_COLORS", x: 115, y: 294, width: 1, height: 19 },
{ name: "EQ_PRESETS_BUTTON", x: 224, y: 164, width: 44, height: 12 },
{
name: "EQ_PRESETS_BUTTON_SELECTED",
x: 224,
y: 176,
width: 44,
height: 12
},
{ name: "EQ_PREAMP_LINE", x: 0, y: 314, width: 113, height: 1 }
],
POSBAR: [
{
name: "MAIN_POSITION_SLIDER_BACKGROUND",
x: 0,
y: 0,
width: 248,
height: 10
},
{
name: "MAIN_POSITION_SLIDER_THUMB",
x: 248,
y: 0,
width: 29,
height: 10
},
{
name: "MAIN_POSITION_SLIDER_THUMB_SELECTED",
x: 278,
y: 0,
width: 29,
height: 10
}
],
SHUFREP: [
{ name: "MAIN_SHUFFLE_BUTTON", x: 28, y: 0, width: 47, height: 15 },
{
name: "MAIN_SHUFFLE_BUTTON_DEPRESSED",
x: 28,
y: 15,
width: 47,
height: 15
},
{
name: "MAIN_SHUFFLE_BUTTON_SELECTED",
x: 28,
y: 30,
width: 47,
height: 15
},
{
name: "MAIN_SHUFFLE_BUTTON_SELECTED_DEPRESSED",
x: 28,
y: 45,
width: 47,
height: 15
},
{ name: "MAIN_REPEAT_BUTTON", x: 0, y: 0, width: 28, height: 15 },
{
name: "MAIN_REPEAT_BUTTON_DEPRESSED",
x: 0,
y: 15,
width: 28,
height: 15
},
{
name: "MAIN_REPEAT_BUTTON_SELECTED",
x: 0,
y: 30,
width: 28,
height: 15
},
{
name: "MAIN_REPEAT_BUTTON_SELECTED_DEPRESSED",
x: 0,
y: 45,
width: 28,
height: 15
},
{ name: "MAIN_EQ_BUTTON", x: 0, y: 61, width: 23, height: 12 },
{ name: "MAIN_EQ_BUTTON_SELECTED", x: 0, y: 73, width: 23, height: 12 },
{ name: "MAIN_EQ_BUTTON_DEPRESSED", x: 46, y: 61, width: 23, height: 12 },
{
name: "MAIN_EQ_BUTTON_DEPRESSED_SELECTED",
x: 46,
y: 73,
width: 23,
height: 12
},
{ name: "MAIN_PLAYLIST_BUTTON", x: 23, y: 61, width: 23, height: 12 },
{
name: "MAIN_PLAYLIST_BUTTON_SELECTED",
x: 23,
y: 73,
width: 23,
height: 12
},
{
name: "MAIN_PLAYLIST_BUTTON_DEPRESSED",
x: 69,
y: 61,
width: 23,
height: 12
},
{
name: "MAIN_PLAYLIST_BUTTON_DEPRESSED_SELECTED",
x: 69,
y: 62,
width: 23,
height: 12
}
],
TEXT: characterSprites,
TITLEBAR: [
{ name: "MAIN_TITLE_BAR", x: 27, y: 15, width: 275, height: 14 },
{ name: "MAIN_TITLE_BAR_SELECTED", x: 27, y: 0, width: 275, height: 14 },
{
name: "MAIN_EASTER_EGG_TITLE_BAR",
x: 27,
y: 61,
width: 275,
height: 14
},
{
name: "MAIN_EASTER_EGG_TITLE_BAR_SELECTED",
x: 27,
y: 57,
width: 275,
height: 14
},
{ name: "MAIN_OPTIONS_BUTTON", x: 0, y: 0, width: 9, height: 9 },
{
name: "MAIN_OPTIONS_BUTTON_DEPRESSED",
x: 0,
y: 9,
width: 9,
height: 9
},
{ name: "MAIN_MINIMIZE_BUTTON", x: 9, y: 0, width: 9, height: 9 },
{
name: "MAIN_MINIMIZE_BUTTON_DEPRESSED",
x: 9,
y: 9,
width: 9,
height: 9
},
{ name: "MAIN_SHADE_BUTTON", x: 0, y: 18, width: 9, height: 9 },
{ name: "MAIN_SHADE_BUTTON_DEPRESSED", x: 9, y: 18, width: 9, height: 9 },
{ name: "MAIN_CLOSE_BUTTON", x: 18, y: 0, width: 9, height: 9 },
{ name: "MAIN_CLOSE_BUTTON_DEPRESSED", x: 18, y: 9, width: 9, height: 9 },
{
name: "MAIN_CLUTTER_BAR_BACKGROUND",
x: 304,
y: 0,
width: 8,
height: 43
},
{
name: "MAIN_CLUTTER_BAR_BACKGROUND_DISABLED",
x: 312,
y: 0,
width: 8,
height: 43
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_O_SELECTED",
x: 304,
y: 47,
width: 8,
height: 8
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_A_SELECTED",
x: 312,
y: 55,
width: 8,
height: 7
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_I_SELECTED",
x: 320,
y: 62,
width: 8,
height: 7
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_D_SELECTED",
x: 328,
y: 69,
width: 8,
height: 8
},
{
name: "MAIN_CLUTTER_BAR_BUTTON_V_SELECTED",
x: 336,
y: 77,
width: 8,
height: 7
},
{ name: "MAIN_SHADE_BACKGROUND", x: 27, y: 42, width: 275, height: 14 },
{
name: "MAIN_SHADE_BACKGROUND_SELECTED",
x: 27,
y: 29,
width: 275,
height: 14
},
{ name: "MAIN_SHADE_BUTTON_SELECTED", x: 0, y: 27, width: 9, height: 9 },
{
name: "MAIN_SHADE_BUTTON_SELECTED_DEPRESSED",
x: 9,
y: 27,
width: 9,
height: 9
},
{
name: "MAIN_SHADE_POSITION_BACKGROUND",
x: 0,
y: 36,
width: 17,
height: 7
},
{ name: "MAIN_SHADE_POSITION_THUMB", x: 20, y: 36, width: 3, height: 7 },
{
name: "MAIN_SHADE_POSITION_THUMB_LEFT",
x: 17,
y: 36,
width: 3,
height: 7
},
{
name: "MAIN_SHADE_POSITION_THUMB_RIGHT",
x: 23,
y: 36,
width: 3,
height: 7
}
],
VOLUME: [
{ name: "MAIN_VOLUME_BACKGROUND", x: 0, y: 0, width: 68, height: 420 },
{ name: "MAIN_VOLUME_THUMB", x: 15, y: 422, width: 14, height: 11 },
{
name: "MAIN_VOLUME_THUMB_SELECTED",
x: 0,
y: 422,
width: 14,
height: 11
}
]
};

View file

@ -1,12 +1,11 @@
import { each } from "lodash";
import skinSprites from "./skinSprites";
const getNames = arr => arr.map(item => item.name);
const spriteFiles = skinSprites.filter(file => file.sprites);
describe("skinSprites", () => {
it("each spritSheet has a unique name", () => {
const spriteSheetNames = getNames(skinSprites);
const spriteSheetNames = Object.keys(skinSprites);
const seenNames = [];
spriteSheetNames.forEach(name => {
expect(seenNames).not.toContain(name);
@ -15,8 +14,8 @@ describe("skinSprites", () => {
});
it("each sprite has a unique name", () => {
let spriteNames = [];
spriteFiles.forEach(spriteSheet => {
spriteNames = spriteNames.concat(getNames(spriteSheet.sprites));
each(skinSprites, spriteSheet => {
spriteNames = spriteNames.concat(getNames(spriteSheet));
});
const seenNames = [];
spriteNames.forEach(name => {
@ -25,8 +24,8 @@ describe("skinSprites", () => {
});
});
it("each sprite has the needed properties", () => {
spriteFiles.forEach(spriteSheet => {
spriteSheet.sprites.forEach(sprite => {
each(skinSprites, spriteSheet => {
spriteSheet.forEach(sprite => {
expect(typeof sprite.name).toBe("string");
expect(typeof sprite.x).toBe("number");
expect(typeof sprite.y).toBe("number");