diff --git a/README.md b/README.md index af9ab28c..cad2fe12 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ This project depends on - [tup](http://gittup.org/tup/) - [GraphicsMagick](http://www.graphicsmagick.org/) - [AdvPng](http://www.advancemame.it/doc-advpng.html) +- [pnpm](https://pnpm.js.org) +- [node.js](https://nodejs.org) ### Windows @@ -19,7 +21,8 @@ Windows binaries of these dependencies can be found on the download pages of the _**TODO:** include installation instructions for `tup` given the Ubuntu PPA is defunct_ ``` -$ sudo apt install graphicsmagick advancecomp +$ sudo apt install nodejs graphicsmagick advancecomp +$ sudo npm install -g pnpm ``` ### macOS @@ -45,11 +48,15 @@ Pokemon sprite filenames are in a 1-to-1 correspondence with the Pokemon's name, - Characters outside `[0-9a-zA-Z-.]` will be escaped using `_` and four hex characters, similar to JavaScript Unicode escapes. This conforms to the POSIX portable filename character set. (example: `Flabébé` -> `Flabe_0301be_0301`) - The following JS function may be useful: + The following JS functions may be useful: ```javascript function encode(s) { return s.replace(/[^0-9a-zA-Z-.]/g, c => '_' + c.charCodeAt(0).toString(16).padStart(4, '0')); } + + function decode(s) { + return s.replace(/_(....)/g, (_, m) => String.fromCharCode(parseInt(m, 16))); + } ``` - Formes are separated with two dashes from their base. (example: `Necrozma--Dawn-Wings`) diff --git a/Tupfile.lua b/Tupfile.lua index 958beb2f..f37a9dd6 100644 --- a/Tupfile.lua +++ b/Tupfile.lua @@ -4,19 +4,42 @@ tup.include("util/lua-ext.lua") tup.include("util/tup-ext.lua") tup.include("util/pokemon.lua") -function symlink(input, output) - -- The path must be relative from output, walk back to the root - local prefix = "" - for _ in output:gmatch("/") do - prefix = "../" .. prefix - end +-- Generate uniform size minisprites + +function padsprite(input, output, w, h) tup.foreach_rule( input, - "^ symlink %f -> %o^ ln -s " .. prefix .. "%f %o", + "^ padsprite %f^ tools/padsprite.sh %f %o " .. w .. " " .. h, output ) end +for dir in iter{"asymmetrical", "custom", "misc", "pokemon"} do + for file in iglob{"src/minisprites/gen6/" .. dir .. "/*"} do + padsprite(file, + "build/gen6-minisprites-padded/" .. dir .. "/" .. tup.file(file), + 40, 30) + end +end + +-- Forum sprites + +for file in iglob{"build/gen6-minisprites-padded/pokemon/*"} do + local base = toSmogonAlias(decodeBase(file)) + symlink(file, + "build/smogon/forumsprites/" .. base .. ".png") +end + +-- PS spritesheet + +tup.rule( + "build/gen6-minisprites-padded/pokemon/*", + "node tools/sprites/ps.js build/gen6-minisprites-padded/pokemon/ --output-image build/ps/pokemonicons-sheet.png --output-metadata build/ps/pokemonicons.json", + {"build/ps/pokemonicons-sheet.png", "build/ps/pokemonicons.json"} +) + +-- PS models + for file in iglob{"src/models/front/*", "src/models/front-cosmetic/*", "src/models/front-misc/*"} do local output = toPSSpriteID(decodeBase(file)) .. "." .. tup.ext(file) symlink(file, "build/ps/ani/" .. output) @@ -37,6 +60,7 @@ for file in iglob{"src/models/back-shiny/*", "src/models/back-shiny-cosmetic/*"} symlink(file, "build/ps/ani-back-shiny/" .. output) end +-- Smogdex social images function fbsprite(input, output) tup.foreach_rule( @@ -61,15 +85,4 @@ for file in iglob{"src/models/front/*"} do twittersprite(file, "build/smogon/twittersprites/xy/" .. base .. ".png") end -function forumsprite(input, output, w, h) - tup.foreach_rule( - input, - "^ forumsprite %f^ tools/forumsprite.sh %f %o " .. w .. " " .. h, - output - ) -end -for file in iglob{"src/minisprites/gen6/pokemon/*"} do - local base = toSmogonAlias(decodeBase(file)) - forumsprite(file, "build/smogon/forumsprites/" .. base .. ".png", 40, 30) -end diff --git a/tools/forumsprite.sh b/tools/padsprite.sh similarity index 100% rename from tools/forumsprite.sh rename to tools/padsprite.sh diff --git a/tools/sprites/ps.js b/tools/sprites/ps.js index 6a1bde6a..0ed6f061 100755 --- a/tools/sprites/ps.js +++ b/tools/sprites/ps.js @@ -22,6 +22,10 @@ for (const directory of program.args) { } } +function decode(s) { + return s.replace(/_(....)/g, (_, m) => String.fromCharCode(parseInt(m, 16))); +} + function toPSID(s) { return s.toLowerCase().replace(/[^a-z0-9]+/g, ''); } @@ -33,7 +37,7 @@ function toPSID(s) { const sprites = Object.create(null); for (const [filename, {x, y, width, height}] of Object.entries(result.coordinates)) { - const id = toPSID(path.parse(filename).name); + const id = toPSID(decode(path.parse(filename).name)); sprites[id] = {left: x, top: y}; } diff --git a/util/tup-ext.lua b/util/tup-ext.lua index d52305d5..0f31de0d 100644 --- a/util/tup-ext.lua +++ b/util/tup-ext.lua @@ -20,3 +20,16 @@ end function iglob(pats) return iter(glob(pats)) end + +function symlink(input, output) + -- The path must be relative from output, walk back to the root + local prefix = "" + for _ in output:gmatch("/") do + prefix = "../" .. prefix + end + tup.foreach_rule( + input, + "^ symlink %f -> %o^ ln -s " .. prefix .. "%f %o", + output + ) +end