Last active
February 26, 2022 16:40
-
-
Save Xymph/ffa52a765f738848b46d10db718b5726 to your computer and use it in GitHub Desktop.
Process a PLAYPAL lump (https://doomwiki.org/wiki/PLAYPAL) extracted from a Doom-engine WAD and count the number of unique colors, optionally skipping unused palettes and truncating 8-bits colors to 6-bits - see https://www.doomworld.com/vb/post/1839737 for example results
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/php -q | |
<?php | |
// count total number of unique colors used in palettes of Doom-engine games, | |
// optionally skipping unused palettes and truncating 8-bits colors to 6-bits | |
// by Frans P. de Vries (Xymph) | |
define('PALSIZE', 3 * 256); | |
define('USAGE', "usage: {$argv[0]} [-u] [-t] -d|-h|-x|-s PLAYPAL-file\n"); | |
// check options & file parameter | |
$game = ''; // 'd' = doom, 'h' = heretic, 'x' = hexen, 's' = strife | |
$unused = $truncate = false; | |
while (isset($argv[1]) && $argv[1][0] == '-') { | |
switch (substr($argv[1], 1)) { | |
case 'd': | |
case 'h': | |
case 'x': | |
case 's': | |
$game = substr($argv[1], 1); | |
break; | |
case 't': | |
$truncate = true; | |
break; | |
case 'u': | |
$unused = true; | |
break; | |
default: | |
echo USAGE; | |
exit(1); | |
} | |
unset($argv[1]); | |
$argc--; | |
$argv = array_merge($argv); | |
} | |
if ($game != '' && isset($argv[1]) && $argv[1] != '') { | |
$pname = $argv[1]; | |
} else { | |
echo USAGE; | |
exit(1); | |
} | |
// check palette file | |
$PALSETS = ($game == 'x' ? 28 : 14); | |
if (!file_exists($pname)) { | |
echo "$pname: No such PLAYPAL file\n"; | |
exit(1); | |
} | |
if (filesize($pname) != $PALSETS * PALSIZE) { | |
echo "$pname: Invalid PLAYPAL size for this game\n"; | |
exit(1); | |
} | |
// process palette file | |
if (($fp = @fopen($pname, 'rb')) === FALSE) { | |
echo "$pname: Unable to open palette file\n"; | |
exit(1); | |
} | |
$palused = 0; | |
// read all palettes and tally unique colors | |
$colors = array(); | |
for ($palno = 0; $palno < $PALSETS; $palno++) { | |
if (($palette = fread($fp, PALSIZE)) === FALSE) { | |
echo "$pname: Unable to read palette file\n"; | |
exit(1); | |
} | |
// skip unused palettes? | |
if ($unused && | |
(($game != 'x' && ($palno == 1 || $palno == 9)) || | |
($game == 'h' && $palno == 13))) | |
continue; | |
$palused++; | |
// tally unique colors | |
for ($i = 0; $i < PALSIZE; $i += 3) | |
// truncate to 6-bit colors? | |
if ($truncate) | |
$colors[ sprintf('%02X%02X%02X', | |
ord($palette[$i]) & 0xFC, | |
ord($palette[$i+1]) & 0xFC, | |
ord($palette[$i+2]) & 0xFC) ] = true; | |
else | |
$colors[ sprintf('%02X%02X%02X', | |
ord($palette[$i]), | |
ord($palette[$i+1]), | |
ord($palette[$i+2])) ] = true; | |
} | |
fclose($fp); | |
// report results | |
switch ($game) { | |
case 'd': | |
echo "Doom"; | |
break; | |
case 'h': | |
echo "Heretic"; | |
break; | |
case 'x': | |
echo "Hexen"; | |
break; | |
case 's': | |
echo "Strife"; | |
break; | |
} | |
echo " uses $palused palettes with " . count($colors) . " unique colors\n"; | |
// vim: set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment