Add TXTH experimental 'subsong_sum' feature

This commit is contained in:
bnnm 2023-05-29 00:37:37 +02:00
parent ce295d4591
commit 372dfbffe5
2 changed files with 23 additions and 3 deletions

View File

@ -53,8 +53,7 @@ The following can be used in place of `(value)` for `(key) = (value)` commands.
* `:LE|BE`: value is little/big endian (optional, defaults to LE)
* `$1|2|3|4`: value has size of 8/16/24/32 bit (optional, defaults to 4)
* Example: `@0x10:BE$2` means `get big endian 16b value at 0x10`
- `(field)`: uses current value of some fields. Accepted strings:
- `interleave, interleave_last, channels, sample_rate, start_offset, data_size, num_samples, loop_start_sample, loop_end_sample, subsong_count, subsong_spacing, subfile_offset, subfile_size, base_offset, name_valueX`
- `(field)`: uses current value of some fields (`interleave`, `channels`, `start_offset`, `data_size`, `num_samples`, `subsong_count`, `subfile_size`, `base_offset`, `name_valueX`, etc)
- `subsong` is a special field for current subsong
- `(other)`: other special values for certain keys, described per key
@ -419,12 +418,14 @@ Sets the number of subsongs in the file, adjusting reads per subsong N: `value =
Instead of `subsong_spacing` you can use `subsong_offset` (older alias).
Mainly for bigfiles with consecutive headers per subsong, set subsong_offset to 0 when done as it affects any reads. The current subsong number is handled externally by plugins or TXTP.
Mainly for bigfiles with consecutive headers per subsong, set `subsong_offset` to 0 when done as it affects any reads. The current subsong number is handled externally by plugins or TXTP.
```
subsong_count = (value)
subsong_spacing = (value)
```
A experimental field is `subsong_sum = (value)`, that sums all subsong values up to current subsong. Mainly meant when offsets are the sum of subsong sizes: if you have a table of sizes at 0x10 for 3 subsongs, each of size 0x1000, then `subsong_sum = @0x10` for first subsong sums 0x0000, 0x1000 for second, 0x2000 for third (can be used later as `start_offset = subsong_sum`).
#### NAMES
Sets the name of the stream, most useful when used with subsongs. TXTH will read a string at `name_offset`, with `name_size characters`.

View File

@ -116,6 +116,7 @@ typedef struct {
int target_subsong;
uint32_t subsong_count;
uint32_t subsong_spacing;
uint32_t subsong_sum;
uint32_t name_offset_set;
uint32_t name_offset;
@ -1300,6 +1301,23 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha
else if (is_string(key,"subsong_spacing") || is_string(key,"subsong_offset")) {
if (!parse_num(txth->sf_head,txth,val, &txth->subsong_spacing)) goto fail;
}
else if (is_string(key,"subsong_sum")) {
/* add all values up to current subsong (for example, to add all sizes to get current offset, so get start_offset)
* doesn't include current (that is, reading size from fist subsong doesn't add anything) */
int default_subsong = txth->target_subsong;
uint32_t subsong_sum = 0;
for (int i = 0; i < default_subsong - 1; i++) {
txth->target_subsong = i + 1;
if (!parse_num(txth->sf_head,txth,val, &subsong_sum)) goto fail;
txth->subsong_sum += subsong_sum;
}
txth->target_subsong = default_subsong;
}
else if (is_string(key,"name_offset")) {
if (!parse_num(txth->sf_head,txth,val, &txth->name_offset)) goto fail;
txth->name_offset_set = 1;
@ -2001,6 +2019,7 @@ static int parse_num(STREAMFILE* sf, txth_header* txth, const char* val, uint32_
else if ((n = is_string_field(val,"subsong_count"))) value = txth->subsong_count;
else if ((n = is_string_field(val,"subsong_spacing"))) value = txth->subsong_spacing;
else if ((n = is_string_field(val,"subsong_offset"))) value = txth->subsong_spacing;
else if ((n = is_string_field(val,"subsong_sum"))) value = txth->subsong_sum;
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,"base_offset"))) value = txth->base_offset;