L'Armure Sacrée d'Antiriad

par davidnurdin · Remakes
pas encore noté
▶ Jouer Sources Éditer GitHub
games/antiriad-php / src / Antiriad / CpcFont.php · commit decc30a
<?phpnamespace App\Antiriad;use JumPHP\Renderer\BitmapFont;use JumPHP\Renderer\Renderer;use JumPHP\Renderer\Sdl;use JumPHP\Renderer\TextDrawer;use JumPHP\Util\Color;/** * The original's 8 x 8 font (mode 1, #0400): capitals, digits and a few signs. The engine's pixel font * draws the characters it lacks (%, :, '...), accents are dropped. */final class CpcFont implements TextDrawer{    private const ACCENTS = ['À' => 'A', 'Â' => 'A', 'Ä' => 'A', 'Ç' => 'C', 'É' => 'E', 'È' => 'E', 'Ê' => 'E', 'Ë' => 'E',        'Î' => 'I', 'Ï' => 'I', 'Ô' => 'O', 'Ö' => 'O', 'Ù' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ñ' => 'N', '_' => '-'];    /** @var array<string, mixed> one glyph strip per colour */    private array $strips = [];    private BitmapFont $fallback;    public function __construct(private Sdl $sdl, private World $world)    {        $this->fallback = new BitmapFont($sdl);    }    private function strip(Color $c)    {        $key = 'cpcfont-' . $c->key();        if (!isset($this->strips[$key])) {            $rows = array_fill(0, 8, '');            foreach ($this->world->font['glyphs'] as $glyph) {                foreach ($glyph as $y => $line) {                    $rows[$y] .= $line;                }            }            $this->sdl->createTextureFromPixels($key, $rows, ['#' => $c]);            $this->strips[$key] = $this->sdl->getTexture($key)['texture'];        }        return $this->strips[$key];    }    private function normalize(string $text): string    {        return strtr(mb_strtoupper($text, 'UTF-8'), self::ACCENTS);    }    public function draw(Renderer $r, string $text, float $x, float $y, float $scale = 1, Color|array|string $color = [255, 255, 255],                         string $align = 'left', Color|array|string|null $shadow = null): void    {        if ($shadow !== null) {            $this->draw($r, $text, $x + $scale, $y + $scale, $scale, $shadow, $align);        }        $c = Color::of($color);        $strip = $this->strip($c);        $size = 8 * $scale;        foreach (explode("\n", $this->normalize($text)) as $n => $line) {            $cx = $x;            if ($align !== 'left') {                $w = $this->width($line, $scale);                $cx -= $align === 'center' ? $w / 2 : $w;            }            $cy = $y + $n * $this->lineHeight($scale);            foreach (mb_str_split($line, 1, 'UTF-8') as $ch) {                $code = $this->world->font['chars'][$ch] ?? null;                if ($code !== null) {                    if ($code !== 0) {                        $r->copy($strip, [$code * 8, 0, 8, 8], $cx, $cy, $size, $size);                    }                } else {                    $this->fallback->draw($r, $ch, $cx + $scale, $cy, $scale, $c);                }                $cx += $size;            }        }    }    /** One character as #6FBE draws it: the dashboard's signs are small letters ('z' = glyph #2E...). */    public function sign(Renderer $r, string $ch, float $x, float $y, Color|array|string $color): void    {        $this->glyph($r, $this->world->font['chars'][$ch] ?? 0, $x, $y, $color);    }    /** Glyph $code (0-127: #6FBE draws the dashboard's graphics with codes 64-127) at view pixels x, y. */    public function glyph(Renderer $r, int $code, float $x, float $y, Color|array|string $color): void    {        $r->copy($this->strip(Color::of($color)), [$code * 8, 0, 8, 8], $x, $y, 8, 8);    }    public function width(string $text, float $scale = 1): int    {        $lines = explode("\n", $this->normalize($text));        return (int)round(max(array_map(fn ($l) => mb_strlen($l, 'UTF-8'), $lines)) * 8 * $scale);    }    public function height(float $scale = 1): int    {        return (int)round(8 * $scale);    }    public function lineHeight(float $scale = 1): int    {        return (int)round(10 * $scale);    }}