Proof-of-concept PS spritesheet generation

This commit is contained in:
Christopher Monsanto 2020-04-16 02:49:01 -04:00
parent 5ba2e316e4
commit 2446302997
5 changed files with 58 additions and 21 deletions

View File

@ -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`)

View File

@ -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

View File

@ -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};
}

View File

@ -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