Fix some N1 .at9 [Labyrinth of Galleria (PC)]

This commit is contained in:
bnnm 2023-10-14 12:50:29 +02:00
parent edf74fbcba
commit 0c90f4842b

View File

@ -74,27 +74,30 @@ fail:
return NULL; return NULL;
} }
#define SEGMENT_MAX 3
/* Nippon Ichi SPS wrapper (segmented) [Penny-Punching Princess (Switch), Disgaea 4 Complete (PC)] */ /* Nippon Ichi SPS wrapper (segmented) [Penny-Punching Princess (Switch), Disgaea 4 Complete (PC)] */
VGMSTREAM* init_vgmstream_sps_n1_segmented(STREAMFILE* sf) { VGMSTREAM* init_vgmstream_sps_n1_segmented(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL; VGMSTREAM* vgmstream = NULL;
off_t segment_offset;
size_t data_size, max_size; size_t data_size, max_size;
int loop_flag, type, sample_rate; int loop_flag, type, sample_rate;
int i, segment;
init_vgmstream_t init_vgmstream = NULL; init_vgmstream_t init_vgmstream = NULL;
const char* extension; const char* extension;
segmented_layout_data* data = NULL; segmented_layout_data* data = NULL;
int segment_count, loop_start_segment, loop_end_segment; int loop_start_segment, loop_end_segment;
/* checks */ /* checks */
/* .at9: Penny-Punching Princess (Switch) type = read_u32le(0x00,sf);
if (type > 10)
return NULL;
/* .at9: Penny-Punching Princess (Switch), Labyrinth of Galleria (PC)
* .nlsd: Disgaea 4 Complete (PC) */ * .nlsd: Disgaea 4 Complete (PC) */
if (!check_extensions(sf, "at9,nlsd")) if (!check_extensions(sf, "at9,nlsd"))
goto fail; return NULL;
type = read_u32le(0x00,sf);
data_size = read_u32le(0x04,sf); data_size = read_u32le(0x04,sf);
sample_rate = read_u16le(0x08,sf); sample_rate = read_u16le(0x08,sf);
/* 0x0a: flag? (stereo?) */ /* 0x0a: flag? (stereo?) */
@ -113,23 +116,58 @@ VGMSTREAM* init_vgmstream_sps_n1_segmented(STREAMFILE* sf) {
break; break;
default: default:
goto fail; return NULL;
} }
segment_offset = 0x1c;
if (data_size + segment_offset != get_streamfile_size(sf))
goto fail;
/* segmented using 3 files (intro/loop/outro). non-segmented wrapper is the same /* segmented using 3 files (intro/loop/outro). non-segmented wrapper is the same
* but with loop samples instead of sub-sizes */ * but with loop samples instead of sub-sizes */
uint32_t segment_offsets[SEGMENT_MAX];
uint32_t segment_sizes[SEGMENT_MAX];
uint32_t segment_start, offset;
int segment_count, segment;
if (data_size + 0x1c == get_streamfile_size(sf)) {
/* common */
segment_start = 0x1c;
offset = segment_start;
for (int i = 0; i < SEGMENT_MAX; i++) {
uint32_t segment_size = read_u32le(0x10 + 0x04*i,sf);
segment_sizes[i] = segment_size;
segment_offsets[i] = offset;
offset += segment_sizes[i];
}
}
else if (data_size + 0x18 == get_streamfile_size(sf)) {
/* Labyrinth of Galleria (PC) */
segment_start = 0x18;
offset = segment_start;
for (int i = 0; i < SEGMENT_MAX; i++) {
uint32_t next_offset;
if (i >= 2) {
next_offset = get_streamfile_size(sf) - segment_start;
}
else {
next_offset = read_u32le(0x10 + 0x04*i,sf); /* only 2 (not sure if it can be 0) */
}
segment_sizes[i] = next_offset - offset + segment_start;
segment_offsets[i] = offset;
offset += segment_sizes[i];
}
}
else {
goto fail;
}
max_size = 0; max_size = 0;
segment_count = 0; segment_count = 0;
for (i = 0; i < 3; i++) { for (int i = 0; i < SEGMENT_MAX; i++) {
size_t segment_size = read_u32le(0x10 + 0x04*i,sf); /* may only set 1 segment, with empty intro/outro (Disgaea4's bgm_185) */
max_size += segment_size; if (segment_sizes[i])
/* may only set 1 segment (Disgaea4's bgm_185) */
if (segment_size)
segment_count++; segment_count++;
max_size += segment_sizes[i];
} }
if (data_size != max_size) if (data_size != max_size)
goto fail; goto fail;
@ -144,25 +182,21 @@ VGMSTREAM* init_vgmstream_sps_n1_segmented(STREAMFILE* sf) {
/* open each segment subfile */ /* open each segment subfile */
segment = 0; segment = 0;
for (i = 0; i < 3; i++) { for (int i = 0; i < SEGMENT_MAX; i++) {
STREAMFILE* temp_sf; if (!segment_sizes[i])
size_t segment_size = read_u32le(0x10 + 0x04*i,sf);
if (!segment_size)
continue; continue;
temp_sf = setup_subfile_streamfile(sf, segment_offset,segment_size, extension); STREAMFILE* temp_sf = setup_subfile_streamfile(sf, segment_offsets[i],segment_sizes[i], extension);
if (!temp_sf) goto fail; if (!temp_sf) goto fail;
data->segments[segment] = init_vgmstream(temp_sf); data->segments[segment] = init_vgmstream(temp_sf);
close_streamfile(temp_sf); close_streamfile(temp_sf);
if (!data->segments[segment]) goto fail; if (!data->segments[segment]) goto fail;
segment_offset += segment_size;
segment++; segment++;
if (type == 9) { if (type == 9) {
//todo there are some trailing samples that must be removed for smooth loops, start skip seems ok //TODO there are some trailing samples that must be removed for smooth loops, start skip seems ok
//not correct for all files, no idea how to calculate //not correct for all files, no idea how to calculate
data->segments[segment]->num_samples -= 374; data->segments[segment]->num_samples -= 374;
} }