Skip to content

Instantly share code, notes, and snippets.

@bplaat
Created July 15, 2019 16:14
Show Gist options
  • Select an option

  • Save bplaat/892d3ace8aa440699820aa2f9ecfa68f to your computer and use it in GitHub Desktop.

Select an option

Save bplaat/892d3ace8aa440699820aa2f9ecfa68f to your computer and use it in GitHub Desktop.
Age of Empires 1 and 2 drs file unpacker
// http://wiki.xentax.com/index.php/GRAF:Age_Of_Empires_DRSArchive
// tcc drs.c && ./drs "C:\Program Files (x86)\Microsoft Games\Age of Empires\data\sounds.drs" sounds
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct DRS_TABLE {
uint32_t type;
uint32_t offset;
uint32_t count;
} DRS_TABLE;
typedef struct DRS_FILE {
uint32_t id;
uint32_t offset;
uint32_t size;
} DRS_FILE;
int main(int argc, char *argv[]) {
printf("PlaatSoft DRS Explorer\n");
if (argc >= 2) {
FILE *file = fopen(argv[1], "rb");
uint32_t number_of_tables;
fseek(file, 56, SEEK_CUR);
fread(&number_of_tables, sizeof(uint32_t), 1, file);
fseek(file, 4, SEEK_CUR);
for (int i = 0; i < number_of_tables; i++) {
DRS_TABLE drs_table;
char *file_extension;
fread(&drs_table, sizeof(DRS_TABLE), 1, file);
if (drs_table.type == 0x62696E61) {
printf("-------- BIN --------\n");
file_extension = "bin";
}
if (drs_table.type == 0x73687020) {
printf("-------- SHP --------\n");
file_extension = "shp";
}
if (drs_table.type == 0x736c7020) {
printf("-------- SLP --------\n");
file_extension = "slp";
}
if (drs_table.type == 0x77617620) {
printf("-------- WAV --------\n");
file_extension = "wav";
}
int current_position = ftell(file);
fseek(file, drs_table.offset, SEEK_SET);
for (int j = 0; j < drs_table.count; j++) {
DRS_FILE drs_file;
fread(&drs_file, sizeof(DRS_FILE), 1, file);
printf("%d.%s - %d bytes\n", drs_file.id, file_extension, drs_file.size);
if (argc >= 3) {
char path_buffer[255];
sprintf(path_buffer, "%s/%d.%s", argv[2], drs_file.id, file_extension);
FILE *out_file = fopen(path_buffer, "wb");
char *file_buffer = malloc(drs_file.size);
int current_position2 = ftell(file);
fseek(file, drs_file.offset, SEEK_SET);
fread(file_buffer, 1, drs_file.size, file);
fseek(file, current_position2, SEEK_SET);
fwrite(file_buffer, 1, drs_file.size, out_file);
free(file_buffer);
fclose(out_file);
}
}
fseek(file, current_position, SEEK_SET);
}
fclose(file);
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment