vgmstream/src/meta/txtp.c
2024-07-27 18:39:38 +02:00

128 lines
4.1 KiB
C

#include "meta.h"
#include "txtp.h"
/* TXTP - an artificial playlist-like format to play files with segments/layers/config */
VGMSTREAM* init_vgmstream_txtp(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
txtp_header_t* txtp = NULL;
bool ok;
/* checks */
if (!check_extensions(sf, "txtp"))
goto fail;
/* read .txtp with all files and settings */
txtp = txtp_parse(sf);
if (!txtp) goto fail;
/* apply settings to get final vgmstream */
ok = txtp_process(txtp, sf);
if (!ok) goto fail;
/* should result in a final, single vgmstream possibly containing multiple vgmstreams */
vgmstream = txtp->vgmstream[0];
txtp->vgmstream[0] = NULL;
/* flags for title config */
vgmstream->config.is_txtp = true;
vgmstream->config.is_mini_txtp = (get_streamfile_size(sf) == 0);
txtp_clean(txtp);
return vgmstream;
fail:
txtp_clean(txtp);
return NULL;
}
void txtp_clean(txtp_header_t* txtp) {
if (!txtp)
return;
/* first vgmstream may be NULL on success */
for (int i = 0; i < txtp->vgmstream_count; i++) {
close_vgmstream(txtp->vgmstream[i]);
}
free(txtp->vgmstream);
free(txtp->group);
free(txtp->entry);
free(txtp);
}
static void copy_flag(bool* dst_flag, bool* src_flag) {
if (!*src_flag)
return;
*dst_flag = 1;
}
static void copy_secs(bool* dst_flag, double* dst_secs, bool* src_flag, double* src_secs) {
if (!*src_flag)
return;
*dst_flag = 1;
*dst_secs = *src_secs;
}
static void copy_time(bool* dst_flag, int32_t* dst_time, double* dst_time_s, bool* src_flag, int32_t* src_time, double* src_time_s) {
if (!*src_flag)
return;
*dst_flag = 1;
*dst_time = *src_time;
*dst_time_s = *src_time_s;
}
void txtp_copy_config(play_config_t* dst, play_config_t* src) {
if (!src->config_set)
return;
dst->config_set = 1;
copy_flag(&dst->play_forever, &src->play_forever);
copy_flag(&dst->ignore_fade, &src->ignore_fade);
copy_flag(&dst->force_loop, &src->force_loop);
copy_flag(&dst->really_force_loop, &src->really_force_loop);
copy_flag(&dst->ignore_loop, &src->ignore_loop);
copy_secs(&dst->loop_count_set, &dst->loop_count, &src->loop_count_set, &src->loop_count);
copy_secs(&dst->fade_time_set, &dst->fade_time, &src->fade_time_set, &src->fade_time);
copy_secs(&dst->fade_delay_set, &dst->fade_delay, &src->fade_delay_set, &src->fade_delay);
copy_time(&dst->pad_begin_set, &dst->pad_begin, &dst->pad_begin_s, &src->pad_begin_set, &src->pad_begin, &src->pad_begin_s);
copy_time(&dst->pad_end_set, &dst->pad_end, &dst->pad_end_s, &src->pad_end_set, &src->pad_end, &src->pad_end_s);
copy_time(&dst->trim_begin_set, &dst->trim_begin, &dst->trim_begin_s, &src->trim_begin_set, &src->trim_begin, &src->trim_begin_s);
copy_time(&dst->trim_end_set, &dst->trim_end, &dst->trim_end_s, &src->trim_end_set, &src->trim_end, &src->trim_end_s);
copy_time(&dst->body_time_set, &dst->body_time, &dst->body_time_s, &src->body_time_set, &src->body_time, &src->body_time_s);
}
#if 0
static void init_config(VGMSTREAM* vgmstream) {
play_config_t* cfg = &vgmstream->config;
//todo only on segmented/layered?
if (cfg->play_forever
cfg->loop_count_set || cfg->fade_time_set || cfg->fade_delay_set ||
cfg->pad_begin_set || cfg->pad_end_set || cfg->trim_begin_set || cfg->trim_end_set ||
cfg->body_time_set) {
VGM_LOG("setup!\n");
}
}
#endif
void txtp_add_mixing(txtp_entry_t* entry, txtp_mix_data_t* mix, txtp_mix_t command) {
if (entry->mixing_count + 1 > TXTP_MIXING_MAX) {
VGM_LOG("TXTP: too many mixes\n");
return;
}
/* parser reads ch1 = first, but for mixing code ch0 = first
* (if parser reads ch0 here it'll become -1 with meaning of "all channels" in mixing code) */
mix->ch_dst--;
mix->ch_src--;
mix->command = command;
entry->mixing[entry->mixing_count] = *mix; /* memcpy'ed */
entry->mixing_count++;
}