Guest User

Extract maps from King's Bounty Genesis

a guest
Apr 28th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.04 KB | None | 0 0
  1. #include <stdio.h> // For fputs/fprintf
  2. #include <stdlib.h> // For EXIT_FAILURE/EXIT_SUCCESS
  3. #include <sys/types.h> // For stat()
  4. #include <sys/stat.h> // For stat()
  5. #include <stdint.h> // For uint8_t
  6. #if defined(_WIN32)
  7. #include <direct.h> // For _mkdir
  8. #endif
  9.  
  10. void print_usage() {
  11.     fputs("Usage: <program> <rom> <output directory>", stderr);
  12. }
  13.  
  14. int main(int argc, char** argv) {
  15.     if (argc != 3) {
  16.         print_usage();
  17.         return EXIT_FAILURE;
  18.     }
  19.  
  20.     FILE* rom = fopen(argv[1], "rb");
  21.     if (rom == NULL) {
  22.         fprintf(stderr, "Error: Couldn't open ROM file \"%s\"", argv[1]);
  23.         print_usage();
  24.         return EXIT_FAILURE;
  25.     }
  26.  
  27.     fseek(rom, 0, SEEK_END);
  28.     size_t rom_size = ftell(rom);
  29.     fseek(rom, 0, SEEK_SET);
  30.  
  31.     uint8_t data[rom_size];
  32.     fread(&data, sizeof(uint8_t), rom_size, rom);
  33.  
  34.     fclose(rom);
  35.  
  36.     // Not sure why I have to minus 64 here, but without it, the top row
  37.     // of tiles is cut off in the output
  38.     const int maps_begin = 0x1AA8E - 64;
  39.     const int map_width = 64;
  40.     const int map_height = 64;
  41.     const int map_size = map_width * map_height;
  42.  
  43.     static const char* filenames[4] = {
  44.         "continentia.bin",
  45.         "forestria.bin",
  46.         "archipelia.bin",
  47.         "saharia.bin"
  48.     };
  49.  
  50.     for (int i = 0; i < 4; ++i) {
  51.         int start_offset = maps_begin + (i * map_size);
  52.  
  53.         uint8_t flipped_vertically[map_size];
  54.  
  55.         for (int j = 0; j < map_size; ++j) {
  56.             // Break down index
  57.             int x = j % map_width;
  58.             int y = j / map_width;
  59.  
  60.             // Invert y
  61.             y = map_height - y;
  62.  
  63.             // Recreate index
  64.             int index = (y * map_width) + x;
  65.  
  66.             flipped_vertically[j] = data[start_offset + index];
  67.         }
  68.  
  69.         char outfile_path[256];
  70.  
  71. #if defined(_WIN32)
  72.         _mkdir(argv[2]);
  73. #else
  74.         mkdir(argv[2], 0700);
  75. #endif
  76.  
  77.         if (snprintf(outfile_path, 256, "%s/%s", argv[2], filenames[i]) > 256) {
  78.             fputs("Error: Output path too large", stderr);
  79.             return EXIT_FAILURE;
  80.         }
  81.  
  82.         // Write flipped data to file
  83.         FILE* map_out = fopen(outfile_path, "wb");
  84.         fwrite(flipped_vertically, sizeof(uint8_t), map_size, map_out);
  85.         fclose(map_out);
  86.     }
  87.  
  88.     return EXIT_SUCCESS;   
  89. }
Advertisement
Add Comment
Please, Sign In to add comment