Skip to content

Commit

Permalink
Support bnk version 0x58
Browse files Browse the repository at this point in the history
this commit was present in release v1.1_fix2, but I must have forgotten to commit it

- also includes more safety by always seeking to an objects end position, even if i believe to handle it correctly
  • Loading branch information
Morilli committed Aug 13, 2022
1 parent 15d8172 commit b6fc1f1
Showing 1 changed file with 34 additions and 28 deletions.
62 changes: 34 additions & 28 deletions bnk-extract/sound.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,20 @@ void free_music_track_section(MusicTrackSection* section)
free(section->objects);
}

int read_random_container_object(FILE* bnk_file, uint32_t object_length, RandomContainerSection* random_containers)
int read_random_container_object(FILE* bnk_file, RandomContainerSection* random_containers, uint32_t bnk_version)
{
uint32_t initial_position = ftell(bnk_file);
struct random_container new_random_container_object;
assert(fread(&new_random_container_object.self_id, 4, 1, bnk_file) == 1);
dprintf("at the beginning: %ld\n", ftell(bnk_file));
fseek(bnk_file, 1, SEEK_CUR);
uint8_t unk = getc(bnk_file);
fseek(bnk_file, 5 + (unk != 0) + (unk * 7), SEEK_CUR);
fseek(bnk_file, 5 + (unk != 0) + (unk * 7) - (bnk_version == 0x58), SEEK_CUR);
dprintf("reading in switch container id at position %ld\n", ftell(bnk_file));
assert(fread(&new_random_container_object.switch_container_id, 4, 1, bnk_file) == 1);
if (bnk_version == 0x58) {
while(getc(bnk_file) != '\x7a' || getc(bnk_file) != '\x44');
fseek(bnk_file, 18, SEEK_CUR);
} else {
fseek(bnk_file, 1, SEEK_CUR);
uint8_t unk2 = getc(bnk_file);
if (unk2 != 0) {
Expand All @@ -132,7 +135,6 @@ int read_random_container_object(FILE* bnk_file, uint32_t object_length, RandomC
if (unk4 > 1) { // skip this object, because I don't understand the format
// examples: ashe skin23 sfx, ivern skin1 sfx, rammus skin6 and 16 sfx, yasuo skin17 sfx with unk4 = 2, and gangplank 8+ with unk4 = 56???
v_printf(2, "Info: Skipping object because I can't read it lol.\n");
fseek(bnk_file, initial_position + object_length, SEEK_SET);
return -1;
}
int to_seek = 25;
Expand All @@ -145,6 +147,7 @@ int read_random_container_object(FILE* bnk_file, uint32_t object_length, RandomC
dprintf("ftell before the seek: %ld\n", ftell(bnk_file));
dprintf("gonna seek %d\n", to_seek);
fseek(bnk_file, to_seek, SEEK_CUR);
} // end else
assert(fread(&new_random_container_object.sound_id_amount, 4, 1, bnk_file) == 1);
dprintf("sound object id amount: %u\n", new_random_container_object.sound_id_amount);
if (new_random_container_object.sound_id_amount > 100) {
Expand All @@ -154,33 +157,30 @@ int read_random_container_object(FILE* bnk_file, uint32_t object_length, RandomC
new_random_container_object.sound_ids = malloc(new_random_container_object.sound_id_amount * 4);
assert(fread(new_random_container_object.sound_ids, 4, new_random_container_object.sound_id_amount, bnk_file) == new_random_container_object.sound_id_amount);

fseek(bnk_file, initial_position + object_length, SEEK_SET);
add_object(random_containers, &new_random_container_object);

return 0;
}

int read_sound_object(FILE* bnk_file, uint32_t object_length, SoundSection* sounds)
int read_sound_object(FILE* bnk_file, SoundSection* sounds, uint32_t bnk_version)
{
uint32_t initial_position = ftell(bnk_file);
struct sound new_sound_object;
assert(fread(&new_sound_object.self_id, 4, 1, bnk_file) == 1);
fseek(bnk_file, 4, SEEK_CUR);
assert(fread(&new_sound_object.is_streamed, 1, 1, bnk_file) == 1);
if (bnk_version == 0x58) fseek(bnk_file, 3, SEEK_CUR); // was 4 byte field with 3 bytes zero
assert(fread(&new_sound_object.file_id, 4, 1, bnk_file) == 1);
assert(fread(&new_sound_object.source_id, 4, 1, bnk_file) == 1);
fseek(bnk_file, 8, SEEK_CUR);
fseek(bnk_file, 8 - (bnk_version == 0x58), SEEK_CUR);
assert(fread(&new_sound_object.sound_object_id, 4, 1, bnk_file) == 1);

fseek(bnk_file, initial_position + object_length, SEEK_SET);
add_object(sounds, &new_sound_object);

return 0;
}

int read_event_action_object(FILE* bnk_file, uint32_t object_length, EventActionSection* event_actions)
int read_event_action_object(FILE* bnk_file, EventActionSection* event_actions)
{
uint32_t initial_position = ftell(bnk_file);
struct event_action new_event_action_object;
assert(fread(&new_event_action_object.self_id, 4, 1, bnk_file) == 1);
assert(fread(&new_event_action_object.scope, 1, 1, bnk_file) == 1);
Expand All @@ -192,17 +192,17 @@ int read_event_action_object(FILE* bnk_file, uint32_t object_length, EventAction
assert(fread(&new_event_action_object.sound_object_id, 4, 1, bnk_file) == 1);
}

fseek(bnk_file, initial_position + object_length, SEEK_SET);
add_object(event_actions, &new_event_action_object);

return 0;
}

int read_event_object(FILE* bnk_file, EventSection* events)
int read_event_object(FILE* bnk_file, EventSection* events, uint32_t bnk_version)
{
struct event new_event_object;
assert(fread(&new_event_object.self_id, 4, 1, bnk_file) == 1);
assert(fread(&new_event_object.event_amount, 1, 1, bnk_file) == 1);
if (bnk_version == 0x58) fseek(bnk_file, 3, SEEK_CUR); // presumably padding bytes or 4 byte int which was later deemed unnecessarily high
new_event_object.event_ids = malloc(new_event_object.event_amount * 4);
assert(fread(new_event_object.event_ids, 4, new_event_object.event_amount, bnk_file) == new_event_object.event_amount);

Expand All @@ -211,9 +211,8 @@ int read_event_object(FILE* bnk_file, EventSection* events)
return 0;
}

int read_music_container_object(FILE* bnk_file, uint32_t object_length, MusicContainerSection* music_containers)
int read_music_container_object(FILE* bnk_file, MusicContainerSection* music_containers)
{
uint32_t initial_position = ftell(bnk_file);
struct music_container new_music_container_object;
assert(fread(&new_music_container_object.self_id, 4, 1, bnk_file) == 1);
fseek(bnk_file, 4, SEEK_CUR);
Expand All @@ -235,23 +234,20 @@ int read_music_container_object(FILE* bnk_file, uint32_t object_length, MusicCon
new_music_container_object.music_track_ids = malloc(new_music_container_object.music_track_id_amount * 4);
assert(fread(new_music_container_object.music_track_ids, 4, new_music_container_object.music_track_id_amount, bnk_file) == new_music_container_object.music_track_id_amount);

fseek(bnk_file, initial_position + object_length, SEEK_SET);
add_object(music_containers, &new_music_container_object);

return 0;
}

int read_music_track_object(FILE* bnk_file, uint32_t object_length, MusicTrackSection* music_tracks)
int read_music_track_object(FILE* bnk_file, MusicTrackSection* music_tracks)
{
uint32_t initial_position = ftell(bnk_file);
struct music_track new_music_track_object;
assert(fread(&new_music_track_object.self_id, 4, 1, bnk_file) == 1);
fseek(bnk_file, 10, SEEK_CUR);
assert(fread(&new_music_track_object.file_id, 4, 1, bnk_file) == 1);
fseek(bnk_file, 64, SEEK_CUR);
assert(fread(&new_music_track_object.music_container_id, 4, 1, bnk_file) == 1);

fseek(bnk_file, initial_position + object_length, SEEK_SET);
add_object(music_tracks, &new_music_track_object);

return 0;
Expand All @@ -265,8 +261,17 @@ int parse_event_bnk_file(char* path, SoundSection* sounds, EventActionSection* e
eprintf("Error: Failed to open \"%s\".\n", path);
return -1;
}
char magic[4];
assert(fread(magic, 1, 4, bnk_file) == 4);
if (memcmp(magic, "BKHD", 4) != 0) {
eprintf("Error: Not a bnk file!\n");
return -1;
}
fseek(bnk_file, 4, SEEK_CUR);
uint32_t bnk_version;
assert(fread(&bnk_version, 4, 1, bnk_file) == 1);

uint32_t section_length = skip_to_section(bnk_file, "HIRC", false);
uint32_t section_length = skip_to_section(bnk_file, "HIRC", true);
if (!section_length) {
eprintf("Error: Failed to skip to section \"HIRC\" in file \"%s\".\nMake sure to provide the correct file.\n", path);
return -1;
Expand All @@ -282,34 +287,35 @@ int parse_event_bnk_file(char* path, SoundSection* sounds, EventActionSection* e
assert(fread(&object_length, 4, 1, bnk_file) == 1);

dprintf("Am here with an object of type %u\n", type);
int object_start = ftell(bnk_file);
switch (type)
{
case 2:
read_sound_object(bnk_file, object_length, sounds);
read_sound_object(bnk_file, sounds, bnk_version);
break;
case 3:
read_event_action_object(bnk_file, object_length, event_actions);
read_event_action_object(bnk_file, event_actions);
break;
case 4:
read_event_object(bnk_file, events);
read_event_object(bnk_file, events, bnk_version);
break;
case 5:
read_random_container_object(bnk_file, object_length, random_containers);
read_random_container_object(bnk_file, random_containers, bnk_version);
break;
case 10:
read_music_container_object(bnk_file, object_length, music_segments);
read_music_container_object(bnk_file, music_segments);
break;
case 11:
read_music_track_object(bnk_file, object_length, music_tracks);
read_music_track_object(bnk_file, music_tracks);
break;
case 13:
read_music_container_object(bnk_file, object_length, music_playlists);
read_music_container_object(bnk_file, music_playlists);
break;
default:
dprintf("Skipping object, as it is irrelevant for me.\n");
dprintf("gonna seek %u forward\n", object_length);
fseek(bnk_file, object_length, SEEK_CUR);
}
fseek(bnk_file, object_start + object_length, SEEK_SET);

objects_read++;
}
Expand Down

0 comments on commit b6fc1f1

Please sign in to comment.