Update CRI UTF

This commit is contained in:
bnnm 2019-12-15 19:37:52 +01:00
parent 9303aaddb7
commit a3442d5966
2 changed files with 71 additions and 88 deletions

View File

@ -36,7 +36,7 @@ VGMSTREAM * init_vgmstream_acb(STREAMFILE *streamFile) {
//todo acb+cpk is also possible
if (!utf_query_data(streamFile, utf, 0, "AwbFile", &offset, &size))
if (!utf_query_data(utf, 0, "AwbFile", &offset, &size))
goto fail;
subfile_offset = table_offset + offset;
@ -132,7 +132,7 @@ static int open_utf_subtable(acb_header* acb, STREAMFILE* *TableSf, utf_context*
if (*Table != NULL)
return 1;
if (!utf_query_data(acb->acbFile, acb->Header, 0, TableName, &offset, NULL))
if (!utf_query_data(acb->Header, 0, TableName, &offset, NULL))
goto fail;
/* open a buffered streamfile to avoid so much IO back and forth between all the tables */
@ -189,16 +189,16 @@ static int load_acb_waveform(acb_header* acb, int16_t Index) {
/* read Waveform[Index] */
if (!open_utf_subtable(acb, &acb->WaveformSf, &acb->WaveformTable, "WaveformTable", NULL))
goto fail;
if (!utf_query_s16(acb->WaveformSf, acb->WaveformTable, Index, "Id", &Waveform_Id)) { /* older versions use Id */
if (!utf_query_s16(acb->WaveformTable, Index, "Id", &Waveform_Id)) { /* older versions use Id */
if (acb->is_memory) {
if (!utf_query_s16(acb->WaveformSf, acb->WaveformTable, Index, "MemoryAwbId", &Waveform_Id))
if (!utf_query_s16(acb->WaveformTable, Index, "MemoryAwbId", &Waveform_Id))
goto fail;
} else {
if (!utf_query_s16(acb->WaveformSf, acb->WaveformTable, Index, "StreamAwbId", &Waveform_Id))
if (!utf_query_s16(acb->WaveformTable, Index, "StreamAwbId", &Waveform_Id))
goto fail;
}
}
if (!utf_query_s8(acb->WaveformSf, acb->WaveformTable, Index, "Streaming", &Waveform_Streaming))
if (!utf_query_s8(acb->WaveformTable, Index, "Streaming", &Waveform_Streaming))
goto fail;
//;VGM_LOG("ACB: Waveform[%i]: Id=%i, Streaming=%i\n", Index, Waveform_Id, Waveform_Streaming);
@ -230,9 +230,9 @@ static int load_acb_synth(acb_header* acb, int16_t Index) {
/* read Synth[Index] */
if (!open_utf_subtable(acb, &acb->SynthSf, &acb->SynthTable, "SynthTable", NULL))
goto fail;
if (!utf_query_s8(acb->SynthSf, acb->SynthTable, Index, "Type", &Synth_Type))
if (!utf_query_s8(acb->SynthTable, Index, "Type", &Synth_Type))
goto fail;
if (!utf_query_data(acb->SynthSf, acb->SynthTable, Index, "ReferenceItems", &Synth_ReferenceItems_offset, &Synth_ReferenceItems_size))
if (!utf_query_data(acb->SynthTable, Index, "ReferenceItems", &Synth_ReferenceItems_offset, &Synth_ReferenceItems_size))
goto fail;
//;VGM_LOG("ACB: Synth[%i]: Type=%x, ReferenceItems={%x,%x}\n", Index, Synth_Type, Synth_ReferenceItems_offset, Synth_ReferenceItems_size);
@ -308,7 +308,7 @@ static int load_acb_track_event_command(acb_header* acb, int16_t Index) {
/* read Track[Index] */
if (!open_utf_subtable(acb, &acb->TrackSf, &acb->TrackTable, "TrackTable", NULL))
goto fail;
if (!utf_query_s16(acb->TrackSf, acb->TrackTable, Index, "EventIndex", &Track_EventIndex))
if (!utf_query_s16(acb->TrackTable, Index, "EventIndex", &Track_EventIndex))
goto fail;
//;VGM_LOG("ACB: Track[%i]: EventIndex=%i\n", Index, Track_EventIndex);
@ -317,7 +317,7 @@ static int load_acb_track_event_command(acb_header* acb, int16_t Index) {
/* read Command[EventIndex] */
if (!open_utf_subtable(acb, &acb->TrackCommandSf, &acb->TrackCommandTable, "CommandTable", NULL))
goto fail;
if (!utf_query_data(acb->TrackCommandSf, acb->TrackCommandTable, Track_EventIndex, "Command", &Track_Command_offset, &Track_Command_size))
if (!utf_query_data(acb->TrackCommandTable, Track_EventIndex, "Command", &Track_Command_offset, &Track_Command_size))
goto fail;
//;VGM_LOG("ACB: Command[%i]: Command={%x,%x}\n", Track_EventIndex, Track_Command_offset,Track_Command_size);
}
@ -325,7 +325,7 @@ static int load_acb_track_event_command(acb_header* acb, int16_t Index) {
/* read TrackEvent[EventIndex] */
if (!open_utf_subtable(acb, &acb->TrackCommandSf, &acb->TrackCommandTable, "TrackEventTable", NULL))
goto fail;
if (!utf_query_data(acb->TrackCommandSf, acb->TrackCommandTable, Track_EventIndex, "Command", &Track_Command_offset, &Track_Command_size))
if (!utf_query_data(acb->TrackCommandTable, Track_EventIndex, "Command", &Track_Command_offset, &Track_Command_size))
goto fail;
//;VGM_LOG("ACB: TrackEvent[%i]: Command={%x,%x}\n", Track_EventIndex, Track_Command_offset,Track_Command_size);
}
@ -398,9 +398,9 @@ static int load_acb_sequence(acb_header* acb, int16_t Index) {
/* read Sequence[Index] */
if (!open_utf_subtable(acb, &acb->SequenceSf, &acb->SequenceTable, "SequenceTable", NULL))
goto fail;
if (!utf_query_s16(acb->SequenceSf, acb->SequenceTable, Index, "NumTracks", &Sequence_NumTracks))
if (!utf_query_s16(acb->SequenceTable, Index, "NumTracks", &Sequence_NumTracks))
goto fail;
if (!utf_query_data(acb->SequenceSf, acb->SequenceTable, Index, "TrackIndex", &Sequence_TrackIndex_offset, &Sequence_TrackIndex_size))
if (!utf_query_data(acb->SequenceTable, Index, "TrackIndex", &Sequence_TrackIndex_offset, &Sequence_TrackIndex_size))
goto fail;
//;VGM_LOG("ACB: Sequence[%i]: NumTracks=%i, TrackIndex={%x, %x}\n", Index, Sequence_NumTracks, Sequence_TrackIndex_offset,Sequence_TrackIndex_size);
@ -441,9 +441,9 @@ static int load_acb_block(acb_header* acb, int16_t Index) {
/* read Block[Index] */
if (!open_utf_subtable(acb, &acb->BlockSf, &acb->BlockTable, "BlockTable", NULL))
goto fail;
if (!utf_query_s16(acb->BlockSf, acb->BlockTable, Index, "NumTracks", &Block_NumTracks))
if (!utf_query_s16(acb->BlockTable, Index, "NumTracks", &Block_NumTracks))
goto fail;
if (!utf_query_data(acb->BlockSf, acb->BlockTable, Index, "TrackIndex", &Block_TrackIndex_offset, &Block_TrackIndex_size))
if (!utf_query_data(acb->BlockTable, Index, "TrackIndex", &Block_TrackIndex_offset, &Block_TrackIndex_size))
goto fail;
//;VGM_LOG("ACB: Block[%i]: NumTracks=%i, TrackIndex={%x, %x}\n", Index, Block_NumTracks, Block_TrackIndex_offset,Block_TrackIndex_size);
@ -474,9 +474,9 @@ static int load_acb_cue(acb_header* acb, int16_t Index) {
/* read Cue[Index] */
if (!open_utf_subtable(acb, &acb->CueSf, &acb->CueTable, "CueTable", NULL))
goto fail;
if (!utf_query_s8 (acb->CueSf, acb->CueTable, Index, "ReferenceType", &Cue_ReferenceType))
if (!utf_query_s8 (acb->CueTable, Index, "ReferenceType", &Cue_ReferenceType))
goto fail;
if (!utf_query_s16(acb->CueSf, acb->CueTable, Index, "ReferenceIndex", &Cue_ReferenceIndex))
if (!utf_query_s16(acb->CueTable, Index, "ReferenceIndex", &Cue_ReferenceIndex))
goto fail;
//;VGM_LOG("ACB: Cue[%i]: ReferenceType=%i, ReferenceIndex=%i\n", Index, Cue_ReferenceType, Cue_ReferenceIndex);
@ -504,6 +504,8 @@ static int load_acb_cue(acb_header* acb, int16_t Index) {
goto fail;
break;
case 6: /* Cue > (Waveform/Synth/Command)? (ex. PES 2014) */
case 7: /* Cue > (Waveform/Synth/Command)? (ex. PES 2014) */
default:
VGM_LOG("ACB: unknown Cue.ReferenceType=%x, Cue.ReferenceIndex=%x\n", Cue_ReferenceType, Cue_ReferenceIndex);
break; /* ignore and continue */
@ -524,9 +526,9 @@ static int load_acb_cuename(acb_header* acb, int16_t Index) {
/* read CueName[Index] */
if (!open_utf_subtable(acb, &acb->CueNameSf, &acb->CueNameTable, "CueNameTable", NULL))
goto fail;
if (!utf_query_s16(acb->CueNameSf, acb->CueNameTable, Index, "CueIndex", &CueName_CueIndex))
if (!utf_query_s16(acb->CueNameTable, Index, "CueIndex", &CueName_CueIndex))
goto fail;
if (!utf_query_string(acb->CueNameSf, acb->CueNameTable, Index, "CueName", &CueName_CueName))
if (!utf_query_string(acb->CueNameTable, Index, "CueName", &CueName_CueName))
goto fail;
//;VGM_LOG("ACB: CueName[%i]: CueIndex=%i, CueName=%s\n", Index, CueName_CueIndex, CueName_CueName);
@ -583,8 +585,8 @@ void load_acb_wave_name(STREAMFILE *streamFile, VGMSTREAM* vgmstream, int waveid
acb.target_waveid = waveid;
acb.is_memory = is_memory;
acb.has_TrackEventTable = utf_query_data(acb.acbFile, acb.Header, 0, "TrackEventTable", NULL,NULL);
acb.has_CommandTable = utf_query_data(acb.acbFile, acb.Header, 0, "CommandTable", NULL,NULL);
acb.has_TrackEventTable = utf_query_data(acb.Header, 0, "TrackEventTable", NULL,NULL);
acb.has_CommandTable = utf_query_data(acb.Header, 0, "CommandTable", NULL,NULL);
/* read all possible cue names and find which waveids are referenced by it */

View File

@ -12,17 +12,19 @@
* (adapted from hcs's code to do multiple querys in the same table)
*/
// todo divide into some .c file and use for other @UTF parsing
//todo move to src/util subdir
/* API */
typedef struct utf_context utf_context; /* opaque struct */
/*static*/ utf_context* utf_open(STREAMFILE *sf, uint32_t table_offset, int *p_rows, const char **p_row_name);
/*static*/ void utf_close(utf_context *utf);
/* opaque struct */
typedef struct utf_context utf_context;
/*static*/ int utf_query_s8(STREAMFILE *sf, utf_context *utf, int row, const char *column, int8_t *value);
/*static*/ int utf_query_s16(STREAMFILE *sf, utf_context *utf, int row, const char *column, int16_t *value);
/*static*/ int utf_query_string(STREAMFILE *sf, utf_context *utf, int row, const char *column, const char **value);
/*static*/ int utf_query_data(STREAMFILE *sf, utf_context *utf, int row, const char *column, uint32_t *offset, uint32_t *size);
/* open a CRI UTF table at offset, returning table name and rows. Passed streamfile is used internally for next calls */
utf_context* utf_open(STREAMFILE *sf, uint32_t table_offset, int *p_rows, const char **p_row_name);
void utf_close(utf_context *utf);
/* query calls */
int utf_query_s8(utf_context *utf, int row, const char *column, int8_t *value);
int utf_query_s16(utf_context *utf, int row, const char *column, int16_t *value);
int utf_query_string(utf_context *utf, int row, const char *column, const char **value);
int utf_query_data(utf_context *utf, int row, const char *column, uint32_t *offset, uint32_t *size);
/* ************************************************* */
/* INTERNALS */
@ -54,9 +56,8 @@ enum column_type_t {
};
typedef struct {
int valid; /* table is valid */
int found;
int type; /* one of COLUMN_TYPE_* */
enum column_type_t type;
union {
int8_t value_s8;
uint8_t value_u8;
@ -74,9 +75,10 @@ typedef struct {
} value_data;
const char *value_string;
} value;
} utf_result;
} utf_result_t;
struct utf_context {
STREAMFILE *sf;
uint32_t table_offset;
/* header */
@ -111,6 +113,7 @@ struct utf_context {
utf = calloc(1, sizeof(utf_context));
if (!utf) goto fail;
utf->sf = sf;
utf->table_offset = table_offset;
/* check header */
@ -247,12 +250,10 @@ fail:
}
static int utf_query(STREAMFILE *sf, utf_context *utf, int row, const char *column, utf_result *result) {
static int utf_query(utf_context *utf, int row, const char *column, utf_result_t *result) {
int i;
/* fill in the default stuff */
result->valid = 0;
result->found = 0;
if (row >= utf->rows || row < 0)
@ -292,65 +293,43 @@ static int utf_query(STREAMFILE *sf, utf_context *utf, int row, const char *colu
/* read row/constant value */
switch (col->flags & COLUMN_BITMASK_TYPE) {
case COLUMN_TYPE_SINT8:
result->value.value_s8 = read_s8(data_offset, sf);
result->value.value_s8 = read_s8(data_offset, utf->sf);
break;
case COLUMN_TYPE_UINT8:
result->value.value_u8 = read_u8(data_offset, sf);
result->value.value_u8 = read_u8(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT16:
result->value.value_s16 = read_s16be(data_offset, sf);
result->value.value_s16 = read_s16be(data_offset, utf->sf);
break;
case COLUMN_TYPE_UINT16:
result->value.value_u16 = read_u16be(data_offset, sf);
result->value.value_u16 = read_u16be(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT32:
result->value.value_s32 = read_s32be(data_offset, sf);
result->value.value_s32 = read_s32be(data_offset, utf->sf);
break;
case COLUMN_TYPE_UINT32:
result->value.value_u32 = read_u32be(data_offset, sf);
result->value.value_u32 = read_u32be(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT64:
result->value.value_s64 = read_s64be(data_offset, sf);
result->value.value_s64 = read_s64be(data_offset, utf->sf);
break;
#if 0
case COLUMN_TYPE_UINT64:
result->value.value_u64 = read_u64be(data_offset, sf);
result->value.value_u64 = read_u64be(data_offset, utf->sf);
break;
#endif
case COLUMN_TYPE_FLOAT: {
union { //todo inline function?
float float_value;
uint32_t int_value;
} cnv;
if (sizeof(float) != 4) {
VGM_LOG("@UTF: can't convert float\n");
goto fail;
}
cnv.int_value = read_u32be(data_offset, sf);
result->value.value_float = cnv.float_value;
result->value.value_float = read_f32be(data_offset, utf->sf);
break;
}
#if 0
case COLUMN_TYPE_DOUBLE: {
union {
double float_value;
uint64_t int_value;
} cnv;
if (sizeof(double) != 8) {
VGM_LOG("@UTF: can't convert double\n");
goto fail;
}
cnv.int_value = read_u64be(data_offset, sf);
result->value.value_float = cnv.float_value;
result->value.value_double = read_d64be(data_offset, utf->sf);
break;
}
#endif
case COLUMN_TYPE_STRING: {
uint32_t name_offset = read_u32be(data_offset, sf);
uint32_t name_offset = read_u32be(data_offset, utf->sf);
if (name_offset > utf->strings_size)
goto fail;
result->value.value_string = utf->string_table + name_offset;
@ -358,8 +337,8 @@ static int utf_query(STREAMFILE *sf, utf_context *utf, int row, const char *colu
}
case COLUMN_TYPE_DATA:
result->value.value_data.offset = read_u32be(data_offset + 0x00, sf);
result->value.value_data.size = read_u32be(data_offset + 0x04, sf);
result->value.value_data.offset = read_u32be(data_offset + 0x00, utf->sf);
result->value.value_data.size = read_u32be(data_offset + 0x04, utf->sf);
break;
default:
@ -369,19 +348,17 @@ static int utf_query(STREAMFILE *sf, utf_context *utf, int row, const char *colu
break; /* column found and read */
}
result->valid = 1;
return 1;
fail:
return 0;
}
////////////////////////////////////////////////////////////
static int utf_query_value(utf_context *utf, int row, const char *column, void *value, enum column_type_t type) {
utf_result_t result = {0};
int valid;
static int utf_query_value(STREAMFILE *sf, utf_context *utf, int row, const char *column, void *value, int type) {
utf_result result = {0};
utf_query(sf, utf, row, column, &result);
if (!result.valid || !result.found || result.type != type)
valid = utf_query(utf, row, column, &result);
if (!valid || !result.found || result.type != type)
return 0;
switch(result.type) {
@ -401,21 +378,25 @@ static int utf_query_value(STREAMFILE *sf, utf_context *utf, int row, const char
return 1;
}
/*static*/ int utf_query_s8(STREAMFILE *sf, utf_context *utf, int row, const char *column, int8_t *value) {
return utf_query_value(sf, utf, row, column, (void*)value, COLUMN_TYPE_SINT8);
int utf_query_s8(utf_context *utf, int row, const char *column, int8_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT8);
}
/*static*/ int utf_query_s16(STREAMFILE *sf, utf_context *utf, int row, const char *column, int16_t *value) {
return utf_query_value(sf, utf, row, column, (void*)value, COLUMN_TYPE_SINT16);
int utf_query_s16(utf_context *utf, int row, const char *column, int16_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT16);
}
/*static*/ int utf_query_string(STREAMFILE *sf, utf_context *utf, int row, const char *column, const char **value) {
return utf_query_value(sf, utf, row, column, (void*)value, COLUMN_TYPE_STRING);
int utf_query_s32(utf_context *utf, int row, const char *column, int32_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT32);
}
int utf_query_string(utf_context *utf, int row, const char *column, const char **value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_STRING);
}
/*static*/ int utf_query_data(STREAMFILE *sf, utf_context *utf, int row, const char *column, uint32_t *p_offset, uint32_t *p_size) {
utf_result result = {0};
int utf_query_data(utf_context *utf, int row, const char *column, uint32_t *p_offset, uint32_t *p_size) {
utf_result_t result = {0};
int valid;
utf_query(sf, utf, row, column, &result);
if (!result.valid || !result.found || result.type != COLUMN_TYPE_DATA)
valid = utf_query(utf, row, column, &result);
if (!valid || !result.found || result.type != COLUMN_TYPE_DATA)
return 0;
if (p_offset) *p_offset = utf->table_offset + utf->data_offset + result.value.value_data.offset;