mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-17 23:36:41 +01:00
Add TXTH logical AND (&) operator for bitmasks
This commit is contained in:
parent
786c75aa73
commit
122622252a
22
doc/TXTH.md
22
doc/TXTH.md
@ -53,7 +53,7 @@ The following can be used in place of `(value)` for `(key) = (value)` commands.
|
||||
- `(other)`: other special values for certain keys, described per key
|
||||
|
||||
|
||||
The above may be combined with math operations (+-*/): `(key) = (number) (op) (offset) (op) (field) (...)`
|
||||
The above may be combined with math operations (+-*/&): `(key) = (number) (op) (offset) (op) (field) (...)`
|
||||
|
||||
### KEYS
|
||||
|
||||
@ -240,7 +240,7 @@ Modifies the meaning of sample fields when set *before* them.
|
||||
|
||||
Accepted values:
|
||||
- `samples`: exact sample (default)
|
||||
- `bytes`: automatically converts bytes/offset to samples (applies after */+- modifiers)
|
||||
- `bytes`: automatically converts bytes/offset to samples (applies after */+-& modifiers)
|
||||
- `blocks`: same as bytes, but value is given in blocks/frames
|
||||
* Value is internally converted from blocks to bytes first: `bytes = (value * interleave*channels)`
|
||||
|
||||
@ -520,13 +520,13 @@ sample_rate = 0x04 # sample rate is the same for all subsongs
|
||||
```
|
||||
|
||||
### Math
|
||||
Sometimes header values are in "sectors" or similar concepts (typical in DVD games), and need to be adjusted to a real value.
|
||||
Sometimes header values are in "sectors" or similar concepts (typical in DVD games), and need to be adjusted to a real value using some complex math:
|
||||
```
|
||||
sample_type = bytes
|
||||
start_offset = @0x10 * 0x800 # 0x15 * DVD sector size, for example
|
||||
```
|
||||
|
||||
You can also use certain fields' values:
|
||||
You can use `+-*/&` operators, and also certain fields' values:
|
||||
```
|
||||
num_samples = @0x10 * channels # byte-to-samples of channel_size
|
||||
```
|
||||
@ -825,3 +825,17 @@ PAD.XAG : 0x150
|
||||
JIN002.XAG: 0x168
|
||||
JIN003.XAG: 0x180
|
||||
```
|
||||
|
||||
|
||||
** Grandia (PS1) **
|
||||
```
|
||||
header_file = GM1.IDX
|
||||
body_file = GM1.STZ
|
||||
|
||||
subsong_count = 394 #last doesn't have size though
|
||||
subsong_offset = 0x04
|
||||
|
||||
subfile_offset = (@0x00 & 0xFFFFF) * 0x800
|
||||
subfile_extension = seb
|
||||
subfile_size = ((@0x04 - @0x00) & 0xFFFFF) * 0x800
|
||||
```
|
||||
|
@ -593,7 +593,8 @@ static VGMSTREAM *init_subfile(txth_header * txth) {
|
||||
vgmstream_force_loop(vgmstream, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (txth->chunk_count && txth->subsong_count) {
|
||||
/* assumes won't point to subfiles with subsongs */
|
||||
if (/*txth->chunk_count &&*/ txth->subsong_count) {
|
||||
vgmstream->num_streams = txth->subsong_count;
|
||||
}
|
||||
//todo: other combos with subsongs + subfile?
|
||||
@ -1256,7 +1257,7 @@ static int is_substring(const char * val, const char * cmp, int inline_field) {
|
||||
chr = val[len];
|
||||
|
||||
/* "val" can end with math for inline fields (like interleave*0x10) */
|
||||
if (inline_field && (chr == '+' || chr == '-' || chr == '*' || chr == '/'))
|
||||
if (inline_field && (chr == '+' || chr == '-' || chr == '*' || chr == '/' || chr == '&'))
|
||||
return len;
|
||||
|
||||
/* otherwise "val" ends in space or eof (to tell "interleave" and "interleave_last" apart) */
|
||||
@ -1532,7 +1533,7 @@ static int parse_num(STREAMFILE * streamFile, txth_header * txth, const char * v
|
||||
brackets--;
|
||||
n = 1;
|
||||
}
|
||||
else if (type == '+' || type == '-' || type == '/' || type == '*') { /* op */
|
||||
else if (type == '+' || type == '-' || type == '/' || type == '*' || type == '&') { /* op */
|
||||
op = type;
|
||||
n = 1;
|
||||
}
|
||||
@ -1600,6 +1601,8 @@ static int parse_num(STREAMFILE * streamFile, txth_header * txth, const char * v
|
||||
else if ((n = is_string_field(val,"loop_end_sample"))) value = txth->loop_end_sample;
|
||||
else if ((n = is_string_field(val,"subsong_count"))) value = txth->subsong_count;
|
||||
else if ((n = is_string_field(val,"subsong_offset"))) value = txth->subsong_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;
|
||||
//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_value1"))) value = txth->name_values[0];
|
||||
@ -1631,6 +1634,7 @@ static int parse_num(STREAMFILE * streamFile, txth_header * txth, const char * v
|
||||
case '-': value = result - value; break;
|
||||
case '*': value = result * value; break;
|
||||
case '/': if (value == 0) goto fail; value = result / value; break;
|
||||
case '&': value = result & value; break;
|
||||
default: break;
|
||||
}
|
||||
op = ' '; /* consume */
|
||||
|
Loading…
x
Reference in New Issue
Block a user