From 9775c6b91520344c372d5891ba10ff3c3d171a0e Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Tue, 27 Jun 2017 20:55:10 -0700 Subject: [PATCH] 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 --- .eslintrc | 2 +- js/skinParser.js | 144 +++---- js/skinSprites.js | 874 +++++++++++++++++++---------------------- js/skinSprites.test.js | 13 +- 4 files changed, 476 insertions(+), 557 deletions(-) diff --git a/.eslintrc b/.eslintrc index 82db331d..6195a8a7 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,6 @@ { "parserOptions": { - "ecmaVersion": 7, + "ecmaVersion": 8, "sourceType": "module", "ecmaFeatures": { "jsx": true, diff --git a/js/skinParser.js b/js/skinParser.js index 04fe8950..d62b3459 100644 --- a/js/skinParser.js +++ b/js/skinParser.js @@ -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; diff --git a/js/skinSprites.js b/js/skinSprites.js index 1a8a93f8..cb0b8f1e 100644 --- a/js/skinSprites.js +++ b/js/skinSprites.js @@ -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 + } + ] +}; diff --git a/js/skinSprites.test.js b/js/skinSprites.test.js index 47b4f26a..b84b4e5f 100644 --- a/js/skinSprites.test.js +++ b/js/skinSprites.test.js @@ -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");