Skip to content
This repository has been archived by the owner on May 27, 2024. It is now read-only.

Commit

Permalink
Add support for reading non compressed archives
Browse files Browse the repository at this point in the history
  • Loading branch information
chaoticgd committed Aug 12, 2023
1 parent 4fc1701 commit bf787af
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 26 deletions.
2 changes: 1 addition & 1 deletion dsar.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static void ls(const char* path) {

RA_Archive archive;
if((result = RA_archive_open(&archive, path)) != RA_SUCCESS) {
fprintf(stderr, "Failed to parse archive file '%s' (%s).", path, result);
fprintf(stderr, "Failed to parse archive file '%s' (%s).\n", path, result);
exit(1);
}

Expand Down
58 changes: 37 additions & 21 deletions extractall.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ static int compare_toc_assets(const void* lhs, const void* rhs) {
if(((RA_TocAsset*) lhs)->location.archive_index != ((RA_TocAsset*) rhs)->location.archive_index) {
return ((RA_TocAsset*) lhs)->location.archive_index > ((RA_TocAsset*) rhs)->location.archive_index;
} else {
return ((RA_TocAsset*) lhs)->location.decompressed_offset > ((RA_TocAsset*) rhs)->location.decompressed_offset;
return ((RA_TocAsset*) lhs)->location.offset > ((RA_TocAsset*) rhs)->location.offset;
}
}

Expand All @@ -32,20 +32,10 @@ int main(int argc, char** argv) {
// open archive files and decompress blocks one by one.
qsort(toc.assets, toc.asset_count, sizeof(RA_TocAsset), compare_toc_assets);

for(u32 i = 0; i < toc.asset_count; i++) {
u64 target_crc = 0xacea7075a95d9b8c;
RA_TocAsset* toc_asset = &toc.assets[i];
if(toc.assets[i].path_hash == target_crc) {
RA_DependencyDagAsset* dag_asset = RA_dag_lookup_asset(&dag, toc_asset->path_hash);
if(dag_asset) {
printf("haspath %s\n", dag_asset->path);
}
printf("arch: %s\n", toc.archives[toc_asset->location.archive_index].data);
}
}
return 0;
b8 is_archive_compressed = false;
RA_Archive archive;
s32 current_archive_index = -1;
FILE* uncompressed_file = NULL;

// Extract all the files.
for(u32 i = 0; i < toc.asset_count; i++) {
Expand All @@ -68,32 +58,58 @@ int main(int argc, char** argv) {
if(toc_asset->location.archive_index != current_archive_index) {
if(current_archive_index != -1) {
current_archive_index = -1;
RA_archive_close(&archive);
if(is_archive_compressed) {
RA_archive_close(&archive);
} else {
fclose(uncompressed_file);
uncompressed_file = NULL;
}
}
if(toc_asset->location.archive_index >= toc.archive_count) {
fprintf(stderr, "error: Archive index out of range!\n");
return 1;
}
RA_TocArchive* toc_archive = &toc.archives[toc_asset->location.archive_index];
char archive_path[RA_MAX_PATH];
if(snprintf(archive_path, RA_MAX_PATH, "%s/%s", game_dir, toc.archives[toc_asset->location.archive_index].data) < 0) {
if(snprintf(archive_path, RA_MAX_PATH, "%s/%s", game_dir, toc_archive->data) < 0) {
fprintf(stderr, "error: Output path too long.\n");
return 1;
}
RA_file_fix_path(archive_path + strlen(game_dir));
if((result = RA_archive_open(&archive, archive_path)) != RA_SUCCESS) {
fprintf(stderr, "Cannot to open archive '%s'. This is normal for localization files.\n", archive_path);
continue;
if(strcmp(result, "magic bytes don't match") == 0) {
is_archive_compressed = false;
if((uncompressed_file = fopen(archive_path, "rb")) == NULL) {
fprintf(stderr, "Cannot to open uncompressed archive '%s'.\n", archive_path);
continue;
}
} else {
fprintf(stderr, "Cannot to open archive '%s'. This is normal for localization files.\n", archive_path);
continue;
}
} else {
is_archive_compressed = true;
}
current_archive_index = toc_asset->location.archive_index;
}

// Read and decompress blocks as necessary, and assemble the asset.
u8* data = calloc(1, toc_asset->location.size);
u32 size = toc_asset->location.size;
u8 compression_mode;
if((result = RA_archive_read_decompressed(&archive, toc_asset->location.decompressed_offset, size, data, &compression_mode)) != RA_SUCCESS) {
fprintf(stderr, "error: Failed to read block for asset '%s' (%s).\n", asset_path, result);
return 1;
if(is_archive_compressed) {
if((result = RA_archive_read_decompressed(&archive, toc_asset->location.offset, size, data)) != RA_SUCCESS) {
fprintf(stderr, "error: Failed to read block for asset '%s' (%s).\n", asset_path, result);
return 1;
}
} else {
if(fseek(uncompressed_file, toc_asset->location.offset, SEEK_SET) != 0) {
fprintf(stderr, "error: Failed to seek to uncompressed asset '%s'.\n", asset_path);
return 1;
}
if(fread(data, size, 1, uncompressed_file) != 1) {
fprintf(stderr, "error: Failed to read uncompressed asset '%s'.\n", asset_path);
return 1;
}
}

// Write out the file.
Expand Down
7 changes: 5 additions & 2 deletions libra/archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ RA_Result RA_archive_open(RA_Archive* archive, const char* path) {
return "fread header";
}

if(header.magic != FOURCC("DSAR")) {
return "magic bytes don't match";
}

archive->blocks = calloc(header.block_count, sizeof(RA_ArchiveBlock));
archive->block_count = header.block_count;
if(archive->blocks == NULL) {
Expand Down Expand Up @@ -44,7 +48,7 @@ RA_Result RA_archive_close(RA_Archive* archive) {
return RA_SUCCESS;
}

RA_Result RA_archive_read_decompressed(RA_Archive* archive, u32 decompressed_offset, u32 decompressed_size, u8* data_dest, u8* compression_mode_dest) {
RA_Result RA_archive_read_decompressed(RA_Archive* archive, u32 decompressed_offset, u32 decompressed_size, u8* data_dest) {
RA_Result result;

for(u32 i = 0; i < archive->block_count; i++) {
Expand All @@ -67,7 +71,6 @@ RA_Result RA_archive_read_decompressed(RA_Archive* archive, u32 decompressed_off
s64 copy_size = end - begin;

memcpy(data_dest + dest_offset, block->decompressed_data + src_offset, copy_size);
*compression_mode_dest = block->header.compression_mode;
} else if(block->decompressed_data != NULL) {
free(block->decompressed_data);
block->decompressed_data = NULL;
Expand Down
2 changes: 1 addition & 1 deletion libra/archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ typedef struct {

RA_Result RA_archive_open(RA_Archive* archive, const char* path);
RA_Result RA_archive_close(RA_Archive* archive);
RA_Result RA_archive_read_decompressed(RA_Archive* archive, u32 decompressed_offset, u32 decompressed_size, u8* data_dest, u8* compression_mode_dest);
RA_Result RA_archive_read_decompressed(RA_Archive* archive, u32 decompressed_offset, u32 decompressed_size, u8* data_dest);

#endif
2 changes: 1 addition & 1 deletion libra/table_of_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ typedef struct {
typedef struct {
u32 size;
u32 archive_index;
u32 decompressed_offset;
u32 offset;
u32 header_offset;
} RA_TocFileLocation;

Expand Down

0 comments on commit bf787af

Please sign in to comment.