MOKTAR

par davidnurdin · Remakes
pas encore noté
▶ Jouer Sources Éditer GitHub
. / src / Titus / AudioTrait.php · commit 2fb9809
<?phpnamespace App\Titus;/** * audio.c, game side. The original music is an AdLib (OPL2) driver reading MUSIC_MOK.BIN; tools/render-audio.php * runs that driver on DbOpl (the OPL2 emulator of OpenTitus, ported to PHP) once and writes the songs and sound effects as WAV files * (assets/music/audio.json lists them). Here SELECT_MUSIC / FX_START play those files. */trait AudioTrait{    /** 0: level music, 1: bonus (a song that does not become the "last song") */    private const SONG_TYPE = [0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0];    /** @var array<int, array{file: string, duration: float, loops: bool}> */    private array $songs = [];    private int $last_song = 0;    private int $currentSong = -1;    private float $songStart = 0.0;    public function initaudio(): void    {        $this->AUDIOMODE = 1;        $manifest = $this->dataDir . '/../music/audio.json';        if (!is_file($manifest)) {            return;        }        $data = json_decode((string)file_get_contents($manifest), true);        if (!is_array($data)) {            return;        }        $dir = dirname($manifest);        foreach ($data['songs'] ?? [] as $n => $song) {            $this->songs[(int)$n] = ['file' => $song['file'], 'duration' => (float)$song['duration'], 'loops' => (bool)$song['loops']];            if ($this->sound !== null && is_file("$dir/{$song['file']}")) {                $this->sound->loadMusic("moktar-song$n", "$dir/{$song['file']}");            }        }        foreach ($data['sfx'] ?? [] as $n => $file) {            if ($this->sound !== null && is_file("$dir/$file")) {                $this->sound->loadSfx("moktar-fx$n", "$dir/$file");            }        }    }    public function SELECT_MUSIC(int $song_number): void    {        if ((self::SONG_TYPE[$song_number] ?? 0) === 0) {            $this->last_song = $song_number;        }        $this->currentSong = $song_number;        $this->songStart = $this->ms;        if ($this->AUDIOMODE === 1) {            $this->startmusic();        }    }    /** The current song played to its end (the looping ones never end) */    private function songFinished(): bool    {        $song = $this->songs[$this->currentSong] ?? null;        if ($song === null) {            return true;        }        return !$song['loops'] && $this->ms - $this->songStart >= $song['duration'] * 1000;    }    public function startmusic(): void    {        if ($this->sound === null || !isset($this->songs[$this->currentSong])) {            return;        }        $this->sound->stopMusic();        $this->sound->playMusic("moktar-song{$this->currentSong}", $this->songs[$this->currentSong]['loops']);    }    public function stopmusic(): void    {        $this->sound?->stopMusic();    }    /** Waits for the end of the current song */    public function WAIT_SONG(): \Generator    {        if ($this->AUDIOMODE === 0) {            return 0;        }        while (!$this->songFinished()) {            yield 0;            foreach ($this->pollEvents() as [$type, $key]) {                if ($type !== 'down') {                    continue;                }                if ($key === self::KEY_ESC) {                    return self::TITUS_ERROR_QUIT;                }                if ($key === self::KEY_MUSIC) {                    $this->musicKey($key);                    if ($this->AUDIOMODE === 0) {                        return 0;                    }                }            }        }        return 0;    }    public function FX_START(int $fx_number): void    {        if ($this->AUDIOMODE === 1) {            $this->sound?->playSfx("moktar-fx$fx_number");        }    }    /** Restart music if the song is finished */    public function RETURN_MUSIC(): void    {        if ($this->AUDIOMODE === 1 && $this->songFinished() && isset($this->songs[$this->last_song])) {            $this->SELECT_MUSIC($this->last_song);        }    }}