#pragma once #include "playback_backend.hpp" #include #include #include #include "file_backend.hpp" enum ZsmCommandId { PsgWrite, ExtCmd, FmWrite, ZsmEOF, Delay }; struct reg_pair { uint8_t reg; uint8_t val; }; struct ZsmCommand { ZsmCommandId id; union { struct { uint8_t reg; uint8_t val; } psg_write; struct { uint8_t channel; uint8_t bytes; union { uint8_t *pcm; struct { uint8_t chip_id; uint8_t writes; uint8_t *write_bytes; } expansion; uint8_t *sync; uint8_t *custom; }; } extcmd; struct { uint8_t len; reg_pair *regs; } fm_write; uint8_t delay; }; ~ZsmCommand(); }; class ZsmBackend : public PlaybackBackend { File *file; std::vector audio_buf; uint32_t loop_point; uint32_t pcm_offset; uint8_t fm_mask; uint16_t psg_channel_mask; uint16_t tick_rate; size_t music_data_start; size_t music_data_len; double ticks; double delayTicks = 0.0; double position; void seek_internal(double position); ZsmCommand get_command(); public: inline std::string get_id() override { return "zsm"; } inline std::string get_name() override { return "ZSM player"; } void seek(double position) override; void load(const char *filename) override; void switch_stream(int idx) override; void cleanup() override; int get_stream_idx() override; size_t render(void *buf, size_t maxlen) override; double get_position() override; inline ~ZsmBackend() override { } };