mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 08:20:54 +01:00
Fix some CPK .awb [Puyo Puyo 20th Anniv. (3DS)]
This commit is contained in:
parent
92642bb6b0
commit
ed00ccb1a8
@ -18,6 +18,8 @@ VGMSTREAM* init_vgmstream_cpk_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
|
||||
off_t subfile_offset = 0;
|
||||
size_t subfile_size = 0;
|
||||
utf_context* utf = NULL;
|
||||
utf_context* utf_h = NULL;
|
||||
utf_context* utf_l = NULL;
|
||||
int total_subsongs, target_subsong = sf->stream_index;
|
||||
int subfile_id = 0;
|
||||
cpk_type_t type;
|
||||
@ -40,14 +42,17 @@ VGMSTREAM* init_vgmstream_cpk_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
|
||||
/* CPK .cpk is CRI's generic file container, but here we only support CPK .awb used as
|
||||
* early audio bank, that like standard AFS2 .awb comes with .acb */
|
||||
{
|
||||
int rows, i;
|
||||
int rows, rows_l, rows_h, i;
|
||||
const char* name;
|
||||
const char* name_l;
|
||||
const char* name_h;
|
||||
const char* Tvers;
|
||||
uint32_t table_offset = 0, offset;
|
||||
uint32_t Files = 0, FilesL = 0, FilesH = 0;
|
||||
uint64_t ContentOffset = 0, ItocOffset = 0;
|
||||
uint16_t Align = 0;
|
||||
uint32_t DataL_offset = 0, DataL_size = 0, DataH_offset = 0, DataH_size = 0;
|
||||
int id_align;
|
||||
|
||||
/* base header */
|
||||
table_offset = 0x10;
|
||||
@ -65,7 +70,7 @@ VGMSTREAM* init_vgmstream_cpk_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
|
||||
utf_close(utf);
|
||||
utf = NULL;
|
||||
|
||||
if (strncmp(Tvers, "awb", 3) != 0) /* starts with "awb" + ".(version)" (SFvTK, MGS3D) or " for (version)" (ACI) */
|
||||
if (strncmp(Tvers, "awb", 3) != 0) /* starts with "awb" + ".(version)" (SFvTK, MGS3D) or " for (version)" (ACI, Puyo) */
|
||||
goto fail;
|
||||
if (Files <= 0)
|
||||
goto fail;
|
||||
@ -104,51 +109,77 @@ VGMSTREAM* init_vgmstream_cpk_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
|
||||
|
||||
/* DataL header */
|
||||
table_offset = DataL_offset;
|
||||
utf = utf_open(sf, table_offset, &rows, &name);
|
||||
if (!utf || strcmp(name, "CpkItocL") != 0 || rows != FilesL)
|
||||
utf_l = utf_open(sf, table_offset, &rows_l, &name_l);
|
||||
if (!utf_l || strcmp(name_l, "CpkItocL") != 0 || rows_l != FilesL)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < rows; i++) {
|
||||
/* DataH header */
|
||||
table_offset = DataH_offset;
|
||||
utf_h = utf_open(sf, table_offset, &rows_h, &name_h);
|
||||
if (!utf_h || strcmp(name_h, "CpkItocH") != 0 || rows_h != FilesH)
|
||||
goto fail;
|
||||
|
||||
|
||||
/* rarely ID doesn't start at 0, adjust values [Puyo Puyo 20th Anniversary (3DS)-3DS_manzai_voice] */
|
||||
id_align = 0;
|
||||
{
|
||||
uint16_t ID_l = 0;
|
||||
uint16_t ID_h = 0;
|
||||
|
||||
/* use lower as base, one table may not exist */
|
||||
utf_query_u16(utf_l, 0, "ID", &ID_l);
|
||||
utf_query_u16(utf_h, 0, "ID", &ID_h);
|
||||
if (rows_l > 0 && rows_h > 0) {
|
||||
if (ID_l > 0 && ID_h > 0) /* one is 0 = no adjust needed */
|
||||
id_align = ID_l < ID_h ? ID_l : ID_h;
|
||||
}
|
||||
else if (rows_l) {
|
||||
id_align = ID_l;
|
||||
}
|
||||
else if (rows_h) {
|
||||
id_align = ID_h;
|
||||
}
|
||||
}
|
||||
|
||||
/* save DataL sizes */
|
||||
for (i = 0; i < rows_l; i++) {
|
||||
uint16_t ID = 0;
|
||||
uint16_t FileSize, ExtractSize;
|
||||
|
||||
if (!utf_query_u16(utf, i, "ID", &ID) ||
|
||||
!utf_query_u16(utf, i, "FileSize", &FileSize) ||
|
||||
!utf_query_u16(utf, i, "ExtractSize", &ExtractSize))
|
||||
if (!utf_query_u16(utf_l, i, "ID", &ID) ||
|
||||
!utf_query_u16(utf_l, i, "FileSize", &FileSize) ||
|
||||
!utf_query_u16(utf_l, i, "ExtractSize", &ExtractSize))
|
||||
goto fail;
|
||||
|
||||
ID -= id_align;
|
||||
if (ID >= Files || FileSize != ExtractSize || sizes[ID])
|
||||
goto fail;
|
||||
|
||||
sizes[ID] = FileSize;
|
||||
}
|
||||
|
||||
utf_close(utf);
|
||||
utf = NULL;
|
||||
|
||||
/* DataR header */
|
||||
table_offset = DataH_offset;
|
||||
utf = utf_open(sf, table_offset, &rows, &name);
|
||||
if (!utf || strcmp(name, "CpkItocH") != 0 || rows != FilesH)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < rows; i++) {
|
||||
/* save DataH sizes */
|
||||
for (i = 0; i < rows_h; i++) {
|
||||
uint16_t ID = 0;
|
||||
uint32_t FileSize, ExtractSize;
|
||||
|
||||
if (!utf_query_u16(utf, i, "ID", &ID) ||
|
||||
!utf_query_u32(utf, i, "FileSize", &FileSize) ||
|
||||
!utf_query_u32(utf, i, "ExtractSize", &ExtractSize))
|
||||
if (!utf_query_u16(utf_h, i, "ID", &ID) ||
|
||||
!utf_query_u32(utf_h, i, "FileSize", &FileSize) ||
|
||||
!utf_query_u32(utf_h, i, "ExtractSize", &ExtractSize))
|
||||
goto fail;
|
||||
|
||||
ID -= id_align;
|
||||
if (ID >= Files || FileSize != ExtractSize || sizes[ID])
|
||||
goto fail;
|
||||
|
||||
sizes[ID] = FileSize;
|
||||
}
|
||||
|
||||
utf_close(utf);
|
||||
utf = NULL;
|
||||
utf_close(utf_l);
|
||||
utf_l = NULL;
|
||||
|
||||
utf_close(utf_h);
|
||||
utf_h = NULL;
|
||||
|
||||
|
||||
/* find actual offset */
|
||||
@ -156,7 +187,7 @@ VGMSTREAM* init_vgmstream_cpk_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
|
||||
for (i = 0; i < Files; i++) {
|
||||
uint32_t size = sizes[i];
|
||||
if (i + 1 == target_subsong) {
|
||||
subfile_id = i;
|
||||
subfile_id = i + id_align;
|
||||
subfile_offset = offset;
|
||||
subfile_size = size;
|
||||
break;
|
||||
@ -166,7 +197,7 @@ VGMSTREAM* init_vgmstream_cpk_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
|
||||
if (Align && (offset % Align))
|
||||
offset += Align - (offset % Align);
|
||||
}
|
||||
|
||||
|
||||
free(sizes);
|
||||
sizes = NULL;
|
||||
}
|
||||
@ -224,6 +255,8 @@ VGMSTREAM* init_vgmstream_cpk_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
|
||||
fail:
|
||||
free(sizes);
|
||||
utf_close(utf);
|
||||
utf_close(utf_l);
|
||||
utf_close(utf_h);
|
||||
close_streamfile(temp_sf);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user