Skip to content

Instantly share code, notes, and snippets.

@tarik02
Created May 26, 2019 09:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tarik02/ba67059d2b34812ecc8fe6e11f7b3445 to your computer and use it in GitHub Desktop.
Save tarik02/ba67059d2b34812ecc8fe6e11f7b3445 to your computer and use it in GitHub Desktop.
Repack cossacks resources.gsc (all.gsc) from Russian to English version.
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#define INPUT_KEY 0x4EBA // Input key (Russian)
#define OUTPUT_KEY 0x78CD // Output key (English)
#define CHUNK_SIZE 1024 * 1024 // 1MB
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <INPUT_FILE> <OUTPUT_FILE>\n", argv[0]);
return -1;
}
char *input_file = argv[1];
char *output_file = argv[2];
FILE *inf = fopen(input_file, "rb");
if (inf == NULL) {
fprintf(stderr, "Failed to open input file.\n");
return -1;
}
FILE *outf = fopen(output_file, "wb");
if (outf == NULL) {
fprintf(stderr, "Failed to open output file.\n");
fclose(inf);
return -1;
}
uint64_t in_key = ~(INPUT_KEY >> 8);
uint64_t out_key = ~(OUTPUT_KEY >> 8);
for (int i = 1; i < 8; ++i) {
in_key = in_key | ((in_key & 0xFF) << i);
out_key = out_key | ((out_key & 0xFF) << i);
}
fseek(inf, 0, SEEK_END);
size_t file_size = ftell(inf);
fseek(inf, 0, SEEK_SET);
int chunk_counter = 0;
int chunk_count = (int) ceil(((double) file_size) / ((double) CHUNK_SIZE));
uint8_t *chunk = (uint8_t *) malloc(CHUNK_SIZE);
size_t count;
printf("File size: %d\n", file_size);
printf("Chunk count: %d\n", chunk_count);
while ((count = fread(chunk, 1, CHUNK_SIZE, inf)) > 0) {
size_t i = 0;
for (; i < (count / 8) * 8; i += 8) {
uint64_t value = *((uint64_t *) (chunk + i));
value = ~value;
value = value ^ in_key;
value = value ^ out_key;
value = ~value;
*((uint64_t *) (chunk + i)) = value;
}
for (; i < count; ++i) {
uint8_t value = chunk[i];
value = ~value;
value = value ^ (in_key & 0xFF);
value = value ^ (out_key & 0xFF);
value = ~value;
chunk[i] = value;
}
++chunk_counter;
printf("Progress %d/%d chunks\n", chunk_counter, chunk_count);
fwrite(chunk, 1, count, outf);
}
free(chunk);
fclose(inf);
fclose(outf);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment