Add TXTH offset absolute modifier

This commit is contained in:
bnnm 2021-10-24 16:07:35 +02:00
parent 2570fcac4d
commit bab7d21b3e
2 changed files with 18 additions and 6 deletions

View File

@ -338,6 +338,8 @@ Usually each channel uses its own list, so we may need to set separation per cha
Those 16-bit coefs can be little or big endian (usually BE), set `coef_endianness` directly or in an offset value where `0=LE, >0=BE`. Those 16-bit coefs can be little or big endian (usually BE), set `coef_endianness` directly or in an offset value where `0=LE, >0=BE`.
While the coef table is almost always included per-file, some games have their coef table in the executable or precalculated somehow. You can set inline coefs instead of coef_offset. Format is a long string of bytes (optionally space-separated) like `coef_table = 0x1E02DE01 3C0C0EFA ...`. You still need to set `coef_spacing` and `coef_endianness` though. While the coef table is almost always included per-file, some games have their coef table in the executable or precalculated somehow. You can set inline coefs instead of coef_offset. Format is a long string of bytes (optionally space-separated) like `coef_table = 0x1E02DE01 3C0C0EFA ...`. You still need to set `coef_spacing` and `coef_endianness` though.
`coef_offset` is adjusted by `base_offset` and `subsong_spacing`. If offset points to some absolute offset that doesn't depend on subsong, set first `offset_absolute = 1`.
``` ```
coef_offset = (value) coef_offset = (value)
coef_spacing = (value) coef_spacing = (value)
@ -394,7 +396,7 @@ Sets the name of the stream, most useful when used with subsongs. TXTH will read
`name_size` defaults to 0, which reads until null-terminator or a non-ascii character is found. `name_size` defaults to 0, which reads until null-terminator or a non-ascii character is found.
`name_offset` can be a (number) value, but being an offset it's also adjusted by `subsong_spacing`. If you need to point to some absolute offset (for example a subsong pointing to name in another table) that doesn't depend on subsong (must not be changed by `subsong_spacing`), use `name_offset_absolute`. `name_offset` is adjusted by `base_offset` and `subsong_spacing`. If offset points to some absolute offset that doesn't depend on subsong, set first `offset_absolute = 1`.
``` ```
name_offset = (value) name_offset = (value)
name_size = (value) name_size = (value)

View File

@ -128,6 +128,7 @@ typedef struct {
int chunk_count_set; int chunk_count_set;
uint32_t base_offset; uint32_t base_offset;
uint32_t is_offset_absolute;
uint32_t name_values[16]; uint32_t name_values[16];
int name_values_count; int name_values_count;
@ -460,7 +461,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
{ {
int16_t (*read_16bit)(off_t, STREAMFILE*) = txth.coef_big_endian ? read_16bitBE : read_16bitLE; int16_t (*read_16bit)(off_t, STREAMFILE*) = txth.coef_big_endian ? read_16bitBE : read_16bitLE;
int16_t (*get_16bit)(const uint8_t* p) = txth.coef_big_endian ? get_16bitBE : get_16bitLE; int16_t (*get_16bit)(const uint8_t* p) = txth.coef_big_endian ? get_16bitBE : get_16bitLE;
VGM_LOG("coef=%x\n",txth.coef_offset );
for (i = 0; i < vgmstream->channels; i++) { for (i = 0; i < vgmstream->channels; i++) {
if (txth.coef_mode == 0) { /* normal coefs */ if (txth.coef_mode == 0) { /* normal coefs */
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
@ -1196,13 +1197,20 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha
goto fail; goto fail;
} }
else if (is_string(key,"offset_absolute")) {
if (!parse_num(txth->sf_head,txth,val, &txth->is_offset_absolute)) goto fail;
}
/* COEFS */ /* COEFS */
else if (is_string(key,"coef_offset")) { else if (is_string(key,"coef_offset")) {
if (!parse_num(txth->sf_head,txth,val, &txth->coef_offset)) goto fail; if (!parse_num(txth->sf_head,txth,val, &txth->coef_offset)) goto fail;
/* special adjustments */ /* special adjustments */
VGM_LOG("coef norm=%x\n",txth->coef_offset );
txth->coef_offset += txth->base_offset; txth->coef_offset += txth->base_offset;
if (txth->subsong_spacing) VGM_LOG("coef+base=%x\n",txth->coef_offset );
if (txth->subsong_spacing && !txth->is_offset_absolute)
txth->coef_offset += txth->subsong_spacing * (txth->target_subsong - 1); txth->coef_offset += txth->subsong_spacing * (txth->target_subsong - 1);
VGM_LOG("coef+spac=%x\n",txth->coef_offset );
} }
else if (is_string(key,"coef_spacing")) { else if (is_string(key,"coef_spacing")) {
if (!parse_num(txth->sf_head,txth,val, &txth->coef_spacing)) goto fail; if (!parse_num(txth->sf_head,txth,val, &txth->coef_spacing)) goto fail;
@ -1224,7 +1232,7 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha
txth->hist_set = 1; txth->hist_set = 1;
/* special adjustment */ /* special adjustment */
txth->hist_offset += txth->hist_offset; txth->hist_offset += txth->hist_offset;
if (txth->subsong_spacing) if (txth->subsong_spacing && !txth->is_offset_absolute)
txth->hist_offset += txth->subsong_spacing * (txth->target_subsong - 1); txth->hist_offset += txth->subsong_spacing * (txth->target_subsong - 1);
} }
else if (is_string(key,"hist_spacing")) { else if (is_string(key,"hist_spacing")) {
@ -1246,10 +1254,10 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha
txth->name_offset_set = 1; txth->name_offset_set = 1;
/* special adjustment */ /* special adjustment */
txth->name_offset += txth->base_offset; txth->name_offset += txth->base_offset;
if (txth->subsong_spacing) if (txth->subsong_spacing && !txth->is_offset_absolute)
txth->name_offset += txth->subsong_spacing * (txth->target_subsong - 1); txth->name_offset += txth->subsong_spacing * (txth->target_subsong - 1);
} }
else if (is_string(key,"name_offset_absolute")) { else if (is_string(key,"name_offset_absolute")) { //TODO: remove
if (!parse_num(txth->sf_head,txth,val, &txth->name_offset)) goto fail; if (!parse_num(txth->sf_head,txth,val, &txth->name_offset)) goto fail;
txth->name_offset_set = 1; txth->name_offset_set = 1;
/* special adjustment */ /* special adjustment */
@ -1926,6 +1934,8 @@ static int parse_num(STREAMFILE* sf, txth_header* txth, const char* val, uint32_
else if ((n = is_string_field(val,"subfile_offset"))) value = txth->subfile_offset; else if ((n = is_string_field(val,"subfile_offset"))) value = txth->subfile_offset;
else if ((n = is_string_field(val,"subfile_size"))) value = txth->subfile_size; else if ((n = is_string_field(val,"subfile_size"))) value = txth->subfile_size;
else if ((n = is_string_field(val,"base_offset"))) value = txth->base_offset; else if ((n = is_string_field(val,"base_offset"))) value = txth->base_offset;
else if ((n = is_string_field(val,"coef_offset"))) value = txth->coef_offset;
else if ((n = is_string_field(val,"hist_offset"))) value = txth->hist_offset;
//todo whatever, improve //todo whatever, improve
else if ((n = is_string_field(val,"name_value"))) value = txth->name_values[0]; else if ((n = is_string_field(val,"name_value"))) value = txth->name_values[0];
else if ((n = is_string_field(val,"name_value1"))) value = txth->name_values[0]; else if ((n = is_string_field(val,"name_value1"))) value = txth->name_values[0];