Support multi-awb .acb names using .txtm [Snack World (Switch)]

This commit is contained in:
bnnm 2021-06-20 13:45:01 +02:00
parent f5cefd544e
commit af3851afff
5 changed files with 34 additions and 10 deletions

View File

@ -424,6 +424,11 @@ willow.mpf:willow.mus,willow_o.mus
# Metal Gear Solid: Snake Eater 3D (3DS) names for .awb
bgm_2_streamfiles.awb: bgm_2.acb
```
```
# Snack World (Switch) names for .awb (single .acb for all .awb, order matters)
bgm.awb: bgm.acb
bgm_DLC1.awb: bgm.acb
```
### Plugin conflicts

View File

@ -132,6 +132,7 @@ typedef struct {
/* config */
int is_memory;
int target_waveid;
int target_port;
int has_TrackEventTable;
int has_CommandTable;
@ -221,7 +222,7 @@ static void add_acb_name(acb_header* acb, int8_t Streaming) {
/* OBJECT HANDLERS */
static int load_acb_waveform(acb_header* acb, int16_t Index) {
uint16_t Id;
uint16_t Id, PortNo;
uint8_t Streaming;
/* read Waveform[Index] */
@ -231,18 +232,30 @@ static int load_acb_waveform(acb_header* acb, int16_t Index) {
if (acb->is_memory) {
if (!utf_query_u16(acb->WaveformTable, Index, "MemoryAwbId", &Id))
goto fail;
PortNo = 0xFFFF;
} else {
if (!utf_query_u16(acb->WaveformTable, Index, "StreamAwbId", &Id))
goto fail;
if (!utf_query_u16(acb->WaveformTable, Index, "StreamAwbPortNo", &PortNo))
PortNo = 0; /* assumed */
}
}
else {
PortNo = 0xFFFF;
}
if (!utf_query_u8(acb->WaveformTable, Index, "Streaming", &Streaming))
goto fail;
//;VGM_LOG("ACB: Waveform[%i]: Id=%i, Streaming=%i\n", Index, Id, Streaming);
//;VGM_LOG("ACB: Waveform[%i]: Id=%i, PortNo=%i, Streaming=%i\n", Index, Id, PortNo, Streaming);
/* not found but valid */
if (Id != acb->target_waveid)
return 1;
/* correct AWB port (check ignored if set to -1) */
if (acb->target_port >= 0 && PortNo != 0xFFFF && PortNo != acb->target_port)
return 1;
/* must match our target's (0=memory, 1=streaming, 2=memory (prefetch)+stream) */
if ((acb->is_memory && Streaming == 1) || (!acb->is_memory && Streaming == 0))
return 1;
@ -694,7 +707,7 @@ fail:
}
void load_acb_wave_name(STREAMFILE* sf, VGMSTREAM* vgmstream, int waveid, int is_memory) {
void load_acb_wave_name(STREAMFILE* sf, VGMSTREAM* vgmstream, int waveid, int port, int is_memory) {
acb_header acb = {0};
int i, CueName_rows;
@ -722,9 +735,12 @@ void load_acb_wave_name(STREAMFILE* sf, VGMSTREAM* vgmstream, int waveid, int is
* Atom Craft may only target certain .acb versions so some links are later removed
* Not all cues to point to Waveforms, some are just config events/commands.
* .acb link to .awb by name (loaded manually), though they have a checksum/hash/header to validate.
*
* .acb can contain info for multiple .awb, that are loaded sequentially and assigned "port numbers" (0 to N).
* Both Wave ID and port number must be passed externally to find appropriate song name.
*/
//;VGM_LOG("ACB: find waveid=%i\n", waveid);
//;VGM_LOG("ACB: find waveid=%i, port=%i\n", waveid, port);
acb.acbFile = sf;
@ -732,6 +748,7 @@ void load_acb_wave_name(STREAMFILE* sf, VGMSTREAM* vgmstream, int waveid, int is
if (!acb.Header) goto fail;
acb.target_waveid = waveid;
acb.target_port = port;
acb.is_memory = is_memory;
acb.has_TrackEventTable = utf_query_data(acb.Header, 0, "TrackEventTable", NULL,NULL);
acb.has_CommandTable = utf_query_data(acb.Header, 0, "CommandTable", NULL,NULL);

View File

@ -190,6 +190,7 @@ fail:
static void load_awb_name(STREAMFILE* sf, STREAMFILE* sf_acb, VGMSTREAM* vgmstream, int waveid) {
int is_memory = (sf_acb != NULL);
int port = 0;
/* .acb is passed when loading memory .awb inside .acb */
if (!is_memory) {
@ -198,7 +199,7 @@ static void load_awb_name(STREAMFILE* sf, STREAMFILE* sf_acb, VGMSTREAM* vgmstre
int len_name, len_cmp;
/* try parsing TXTM if present */
sf_acb = read_filemap_file(sf, 0);
sf_acb = read_filemap_file_pos(sf, 0, &port);
/* try (name).awb + (name).awb */
if (!sf_acb) {
@ -249,11 +250,11 @@ static void load_awb_name(STREAMFILE* sf, STREAMFILE* sf_acb, VGMSTREAM* vgmstre
}
/* probably loaded */
load_acb_wave_name(sf_acb, vgmstream, waveid, is_memory);
load_acb_wave_name(sf_acb, vgmstream, waveid, port, is_memory);
close_streamfile(sf_acb);
}
else {
load_acb_wave_name(sf_acb, vgmstream, waveid, is_memory);
load_acb_wave_name(sf_acb, vgmstream, waveid, port, is_memory);
}
}

View File

@ -222,6 +222,7 @@ fail:
static void load_cpk_name(STREAMFILE* sf, STREAMFILE* sf_acb, VGMSTREAM* vgmstream, int waveid) {
int is_memory = (sf_acb != NULL);
int port = -1; /* cpk has no port numbers */
/* .acb is passed when loading memory .awb inside .acb */
if (!is_memory) {
@ -238,11 +239,11 @@ static void load_cpk_name(STREAMFILE* sf, STREAMFILE* sf_acb, VGMSTREAM* vgmstre
return;
/* companion .acb probably loaded */
load_acb_wave_name(sf_acb, vgmstream, waveid, is_memory);
load_acb_wave_name(sf_acb, vgmstream, waveid, port, is_memory);
close_streamfile(sf_acb);
}
else {
load_acb_wave_name(sf_acb, vgmstream, waveid, is_memory);
load_acb_wave_name(sf_acb, vgmstream, waveid, port, is_memory);
}
}

View File

@ -846,7 +846,7 @@ VGMSTREAM * init_vgmstream_awb(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_awb_memory(STREAMFILE * streamFile, STREAMFILE *acbFile);
VGMSTREAM * init_vgmstream_acb(STREAMFILE * streamFile);
void load_acb_wave_name(STREAMFILE *acbFile, VGMSTREAM* vgmstream, int waveid, int is_memory);
void load_acb_wave_name(STREAMFILE *acbFile, VGMSTREAM* vgmstream, int waveid, int port, int is_memory);
VGMSTREAM * init_vgmstream_rad(STREAMFILE * streamFile);