Skip to content

Commit b6fc1f1

Browse files
committed
Support bnk version 0x58
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
1 parent 15d8172 commit b6fc1f1

File tree

1 file changed

+34
-28
lines changed

1 file changed

+34
-28
lines changed

bnk-extract/sound.c

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,20 @@ void free_music_track_section(MusicTrackSection* section)
105105
free(section->objects);
106106
}
107107

108-
int read_random_container_object(FILE* bnk_file, uint32_t object_length, RandomContainerSection* random_containers)
108+
int read_random_container_object(FILE* bnk_file, RandomContainerSection* random_containers, uint32_t bnk_version)
109109
{
110-
uint32_t initial_position = ftell(bnk_file);
111110
struct random_container new_random_container_object;
112111
assert(fread(&new_random_container_object.self_id, 4, 1, bnk_file) == 1);
113112
dprintf("at the beginning: %ld\n", ftell(bnk_file));
114113
fseek(bnk_file, 1, SEEK_CUR);
115114
uint8_t unk = getc(bnk_file);
116-
fseek(bnk_file, 5 + (unk != 0) + (unk * 7), SEEK_CUR);
115+
fseek(bnk_file, 5 + (unk != 0) + (unk * 7) - (bnk_version == 0x58), SEEK_CUR);
117116
dprintf("reading in switch container id at position %ld\n", ftell(bnk_file));
118117
assert(fread(&new_random_container_object.switch_container_id, 4, 1, bnk_file) == 1);
118+
if (bnk_version == 0x58) {
119+
while(getc(bnk_file) != '\x7a' || getc(bnk_file) != '\x44');
120+
fseek(bnk_file, 18, SEEK_CUR);
121+
} else {
119122
fseek(bnk_file, 1, SEEK_CUR);
120123
uint8_t unk2 = getc(bnk_file);
121124
if (unk2 != 0) {
@@ -132,7 +135,6 @@ int read_random_container_object(FILE* bnk_file, uint32_t object_length, RandomC
132135
if (unk4 > 1) { // skip this object, because I don't understand the format
133136
// examples: ashe skin23 sfx, ivern skin1 sfx, rammus skin6 and 16 sfx, yasuo skin17 sfx with unk4 = 2, and gangplank 8+ with unk4 = 56???
134137
v_printf(2, "Info: Skipping object because I can't read it lol.\n");
135-
fseek(bnk_file, initial_position + object_length, SEEK_SET);
136138
return -1;
137139
}
138140
int to_seek = 25;
@@ -145,6 +147,7 @@ int read_random_container_object(FILE* bnk_file, uint32_t object_length, RandomC
145147
dprintf("ftell before the seek: %ld\n", ftell(bnk_file));
146148
dprintf("gonna seek %d\n", to_seek);
147149
fseek(bnk_file, to_seek, SEEK_CUR);
150+
} // end else
148151
assert(fread(&new_random_container_object.sound_id_amount, 4, 1, bnk_file) == 1);
149152
dprintf("sound object id amount: %u\n", new_random_container_object.sound_id_amount);
150153
if (new_random_container_object.sound_id_amount > 100) {
@@ -154,33 +157,30 @@ int read_random_container_object(FILE* bnk_file, uint32_t object_length, RandomC
154157
new_random_container_object.sound_ids = malloc(new_random_container_object.sound_id_amount * 4);
155158
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);
156159

157-
fseek(bnk_file, initial_position + object_length, SEEK_SET);
158160
add_object(random_containers, &new_random_container_object);
159161

160162
return 0;
161163
}
162164

163-
int read_sound_object(FILE* bnk_file, uint32_t object_length, SoundSection* sounds)
165+
int read_sound_object(FILE* bnk_file, SoundSection* sounds, uint32_t bnk_version)
164166
{
165-
uint32_t initial_position = ftell(bnk_file);
166167
struct sound new_sound_object;
167168
assert(fread(&new_sound_object.self_id, 4, 1, bnk_file) == 1);
168169
fseek(bnk_file, 4, SEEK_CUR);
169170
assert(fread(&new_sound_object.is_streamed, 1, 1, bnk_file) == 1);
171+
if (bnk_version == 0x58) fseek(bnk_file, 3, SEEK_CUR); // was 4 byte field with 3 bytes zero
170172
assert(fread(&new_sound_object.file_id, 4, 1, bnk_file) == 1);
171173
assert(fread(&new_sound_object.source_id, 4, 1, bnk_file) == 1);
172-
fseek(bnk_file, 8, SEEK_CUR);
174+
fseek(bnk_file, 8 - (bnk_version == 0x58), SEEK_CUR);
173175
assert(fread(&new_sound_object.sound_object_id, 4, 1, bnk_file) == 1);
174176

175-
fseek(bnk_file, initial_position + object_length, SEEK_SET);
176177
add_object(sounds, &new_sound_object);
177178

178179
return 0;
179180
}
180181

181-
int read_event_action_object(FILE* bnk_file, uint32_t object_length, EventActionSection* event_actions)
182+
int read_event_action_object(FILE* bnk_file, EventActionSection* event_actions)
182183
{
183-
uint32_t initial_position = ftell(bnk_file);
184184
struct event_action new_event_action_object;
185185
assert(fread(&new_event_action_object.self_id, 4, 1, bnk_file) == 1);
186186
assert(fread(&new_event_action_object.scope, 1, 1, bnk_file) == 1);
@@ -192,17 +192,17 @@ int read_event_action_object(FILE* bnk_file, uint32_t object_length, EventAction
192192
assert(fread(&new_event_action_object.sound_object_id, 4, 1, bnk_file) == 1);
193193
}
194194

195-
fseek(bnk_file, initial_position + object_length, SEEK_SET);
196195
add_object(event_actions, &new_event_action_object);
197196

198197
return 0;
199198
}
200199

201-
int read_event_object(FILE* bnk_file, EventSection* events)
200+
int read_event_object(FILE* bnk_file, EventSection* events, uint32_t bnk_version)
202201
{
203202
struct event new_event_object;
204203
assert(fread(&new_event_object.self_id, 4, 1, bnk_file) == 1);
205204
assert(fread(&new_event_object.event_amount, 1, 1, bnk_file) == 1);
205+
if (bnk_version == 0x58) fseek(bnk_file, 3, SEEK_CUR); // presumably padding bytes or 4 byte int which was later deemed unnecessarily high
206206
new_event_object.event_ids = malloc(new_event_object.event_amount * 4);
207207
assert(fread(new_event_object.event_ids, 4, new_event_object.event_amount, bnk_file) == new_event_object.event_amount);
208208

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

214-
int read_music_container_object(FILE* bnk_file, uint32_t object_length, MusicContainerSection* music_containers)
214+
int read_music_container_object(FILE* bnk_file, MusicContainerSection* music_containers)
215215
{
216-
uint32_t initial_position = ftell(bnk_file);
217216
struct music_container new_music_container_object;
218217
assert(fread(&new_music_container_object.self_id, 4, 1, bnk_file) == 1);
219218
fseek(bnk_file, 4, SEEK_CUR);
@@ -235,23 +234,20 @@ int read_music_container_object(FILE* bnk_file, uint32_t object_length, MusicCon
235234
new_music_container_object.music_track_ids = malloc(new_music_container_object.music_track_id_amount * 4);
236235
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);
237236

238-
fseek(bnk_file, initial_position + object_length, SEEK_SET);
239237
add_object(music_containers, &new_music_container_object);
240238

241239
return 0;
242240
}
243241

244-
int read_music_track_object(FILE* bnk_file, uint32_t object_length, MusicTrackSection* music_tracks)
242+
int read_music_track_object(FILE* bnk_file, MusicTrackSection* music_tracks)
245243
{
246-
uint32_t initial_position = ftell(bnk_file);
247244
struct music_track new_music_track_object;
248245
assert(fread(&new_music_track_object.self_id, 4, 1, bnk_file) == 1);
249246
fseek(bnk_file, 10, SEEK_CUR);
250247
assert(fread(&new_music_track_object.file_id, 4, 1, bnk_file) == 1);
251248
fseek(bnk_file, 64, SEEK_CUR);
252249
assert(fread(&new_music_track_object.music_container_id, 4, 1, bnk_file) == 1);
253250

254-
fseek(bnk_file, initial_position + object_length, SEEK_SET);
255251
add_object(music_tracks, &new_music_track_object);
256252

257253
return 0;
@@ -265,8 +261,17 @@ int parse_event_bnk_file(char* path, SoundSection* sounds, EventActionSection* e
265261
eprintf("Error: Failed to open \"%s\".\n", path);
266262
return -1;
267263
}
264+
char magic[4];
265+
assert(fread(magic, 1, 4, bnk_file) == 4);
266+
if (memcmp(magic, "BKHD", 4) != 0) {
267+
eprintf("Error: Not a bnk file!\n");
268+
return -1;
269+
}
270+
fseek(bnk_file, 4, SEEK_CUR);
271+
uint32_t bnk_version;
272+
assert(fread(&bnk_version, 4, 1, bnk_file) == 1);
268273

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

284289
dprintf("Am here with an object of type %u\n", type);
290+
int object_start = ftell(bnk_file);
285291
switch (type)
286292
{
287293
case 2:
288-
read_sound_object(bnk_file, object_length, sounds);
294+
read_sound_object(bnk_file, sounds, bnk_version);
289295
break;
290296
case 3:
291-
read_event_action_object(bnk_file, object_length, event_actions);
297+
read_event_action_object(bnk_file, event_actions);
292298
break;
293299
case 4:
294-
read_event_object(bnk_file, events);
300+
read_event_object(bnk_file, events, bnk_version);
295301
break;
296302
case 5:
297-
read_random_container_object(bnk_file, object_length, random_containers);
303+
read_random_container_object(bnk_file, random_containers, bnk_version);
298304
break;
299305
case 10:
300-
read_music_container_object(bnk_file, object_length, music_segments);
306+
read_music_container_object(bnk_file, music_segments);
301307
break;
302308
case 11:
303-
read_music_track_object(bnk_file, object_length, music_tracks);
309+
read_music_track_object(bnk_file, music_tracks);
304310
break;
305311
case 13:
306-
read_music_container_object(bnk_file, object_length, music_playlists);
312+
read_music_container_object(bnk_file, music_playlists);
307313
break;
308314
default:
309315
dprintf("Skipping object, as it is irrelevant for me.\n");
310316
dprintf("gonna seek %u forward\n", object_length);
311-
fseek(bnk_file, object_length, SEEK_CUR);
312317
}
318+
fseek(bnk_file, object_start + object_length, SEEK_SET);
313319

314320
objects_read++;
315321
}

0 commit comments

Comments
 (0)