vgmstream/src/meta/txtp.c

128 lines
4.1 KiB
C
Raw Normal View History

2019-12-05 22:20:06 +01:00
#include "meta.h"
2024-07-27 18:39:38 +02:00
#include "txtp.h"
2019-12-05 22:20:06 +01:00
/* TXTP - an artificial playlist-like format to play files with segments/layers/config */
2020-07-21 19:19:30 +02:00
VGMSTREAM* init_vgmstream_txtp(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
2024-07-27 18:39:38 +02:00
txtp_header_t* txtp = NULL;
bool ok;
2019-12-05 22:20:06 +01:00
/* checks */
2020-07-21 19:19:30 +02:00
if (!check_extensions(sf, "txtp"))
2019-12-05 22:20:06 +01:00
goto fail;
/* read .txtp with all files and settings */
2024-07-27 18:39:38 +02:00
txtp = txtp_parse(sf);
2019-12-05 22:20:06 +01:00
if (!txtp) goto fail;
2024-07-27 18:39:38 +02:00
/* apply settings to get final vgmstream */
ok = txtp_process(txtp, sf);
2020-07-21 19:19:30 +02:00
if (!ok) goto fail;
2019-12-05 22:20:06 +01:00
2020-07-21 19:19:30 +02:00
/* should result in a final, single vgmstream possibly containing multiple vgmstreams */
vgmstream = txtp->vgmstream[0];
2024-07-27 18:39:38 +02:00
txtp->vgmstream[0] = NULL;
2019-12-05 22:20:06 +01:00
/* flags for title config */
2024-07-27 18:39:38 +02:00
vgmstream->config.is_txtp = true;
vgmstream->config.is_mini_txtp = (get_streamfile_size(sf) == 0);
2024-07-27 18:39:38 +02:00
txtp_clean(txtp);
2020-07-21 19:19:30 +02:00
return vgmstream;
fail:
2024-07-27 18:39:38 +02:00
txtp_clean(txtp);
2020-07-21 19:19:30 +02:00
return NULL;
}
2019-12-05 22:20:06 +01:00
2024-07-27 18:39:38 +02:00
void txtp_clean(txtp_header_t* txtp) {
2020-07-21 19:19:30 +02:00
if (!txtp)
return;
2019-12-05 22:20:06 +01:00
2024-07-27 18:39:38 +02:00
/* first vgmstream may be NULL on success */
for (int i = 0; i < txtp->vgmstream_count; i++) {
2020-07-21 19:19:30 +02:00
close_vgmstream(txtp->vgmstream[i]);
2019-12-05 22:20:06 +01:00
}
2020-07-21 19:19:30 +02:00
free(txtp->vgmstream);
free(txtp->group);
free(txtp->entry);
free(txtp);
}
2019-12-05 22:20:06 +01:00
2020-07-21 19:19:30 +02:00
2024-07-27 15:30:32 +02:00
static void copy_flag(bool* dst_flag, bool* src_flag) {
if (!*src_flag)
return;
*dst_flag = 1;
}
2019-12-05 22:20:06 +01:00
2024-07-27 15:30:32 +02:00
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;
}
2024-07-27 15:30:32 +02:00
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;
}
2024-07-27 18:39:38 +02:00
void txtp_copy_config(play_config_t* dst, play_config_t* src) {
2020-07-26 11:19:52 +02:00
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);
}
2020-07-26 11:19:52 +02:00
#if 0
static void init_config(VGMSTREAM* vgmstream) {
play_config_t* cfg = &vgmstream->config;
2020-07-26 11:19:52 +02:00
//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
2024-07-27 18:39:38 +02:00
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) {
2019-12-05 22:20:06 +01:00
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++;
2019-12-05 22:20:06 +01:00
}