dm64ex.c (5136B)
1 // ===================================================================== 2 // DOOM 64 EXTRACTOR 3 // ===================================================================== 4 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <stdarg.h> 9 10 typedef unsigned char byte; 11 12 void show_info(void) 13 { 14 printf("\n"); 15 printf(" ################(ERICK194)################\n"); 16 printf(" # DOOM 64 EXTRACTOR #\n"); 17 printf(" # CREATED BY ERICK VASQUEZ GARCIA #\n"); 18 printf(" # Doom 64.z64 #\n"); 19 printf(" # (USA/EUR/JAP) VERSION #\n"); 20 printf(" # #\n"); 21 printf(" # USE: #\n"); 22 printf(" # Doom64Extractor.exe -i \"RomImage.z64\" #\n"); 23 printf(" ##########################################\n"); 24 printf("\n"); 25 } 26 27 void do_error(const char *s, ...) 28 { 29 va_list args; 30 va_start(args, s); 31 vfprintf(stderr, s, args); 32 fprintf(stderr, "\n"); 33 va_end(args); 34 exit(0); 35 } 36 37 byte header[65]; 38 int region = -1; 39 40 int read_header(FILE *f, int offset) 41 { 42 byte a; 43 44 fseek(f, offset, SEEK_SET); 45 46 for (int i = 0; i < 64; i++) 47 { 48 fread(&a, sizeof(byte), 1, f); 49 header[i] = a; 50 } 51 52 if (header[0x3E] == 0x45) // Region USA 53 { 54 if (header[0x10] == 0xA8) // Original release 55 { 56 region = 0; 57 printf("Region USA\n"); 58 } 59 else if (header[0x10] == 0x42) // Revision 1 release 60 { 61 region = 3; 62 printf("Region USA, Revision 1\n"); 63 } 64 else 65 { 66 do_error("Error Region %d\n", region); 67 exit(0); 68 } 69 } 70 else if (header[0x3E] == 0x50) // Region EUR 71 { 72 region = 1; 73 printf("Region EUR\n"); 74 } 75 else if (header[0x3E] == 0x4A) // Region JAP 76 { 77 region = 2; 78 printf("Region JAP\n"); 79 } 80 else 81 { 82 do_error("Error Region %d\n", region); 83 exit(0); 84 } 85 86 return 0; 87 } 88 89 byte name1[6] = {'D', 'o', 'o', 'm', '6', '4'}; // Usa, Eur 90 byte name2[6] = {'D', 'O', 'O', 'M', '6', '4'}; // Jap 91 92 int check_name(void) 93 { 94 for (int i = 0; i < 6; i++) 95 { 96 if (region == 2) // Jap 97 { 98 if (header[0x20 + i] != name2[i]) 99 { 100 return 0; 101 } 102 } 103 else 104 { 105 if (header[0x20 + i] != name1[i]) 106 { 107 return 0; 108 } 109 } 110 } 111 112 return 1; 113 } 114 115 int WAD_offset[4] = {0x63D10 , 0x63F60 , 0x64580 , 0x63DC0}; 116 int WAD_size[4] = {0x5D18B0, 0x5D6CDC, 0x5D8478, 0x5D301C}; 117 118 int WMD_offset[4] = {0x6355C0, 0x63AC40, 0x63CA00, 0x636DE0}; 119 int WMD_size[4] = {0xB9E0 , 0xB9E0 , 0xB9E0 , 0xB9E0}; 120 121 int WSD_offset[4] = {0x640FA0, 0x646620, 0x6483E0, 0x6427C0}; 122 int WSD_size[4] = {0x142F8 , 0x142F8 , 0x142F8 , 0x142F8}; 123 124 int WDD_offset[4] = {0x6552A0, 0x65A920, 0x65C6E0, 0x656AC0}; 125 int WDD_size[4] = {0x1716C4, 0x1716C4, 0x1716C4, 0x1716C4}; 126 127 int main(int argc, char *argv[]) 128 { 129 byte a; 130 131 // Parse arguments 132 char *romname; 133 for (int i = 1; i < argc; i++) 134 { 135 if (argv[i][0] == '-') 136 { 137 if (!strcmp(argv[i], "-i")) 138 { 139 i++; 140 romname = argv[i]; 141 } 142 } 143 } 144 145 show_info(); 146 if (argc == 1) 147 { 148 exit(0); 149 } 150 151 FILE *in, *out; 152 in = fopen(romname, "rb"); 153 154 if (!in) 155 { 156 do_error("Cannot open %s\n", romname); 157 exit(0); 158 } 159 160 read_header(in, 0); 161 162 if (!check_name()) 163 { 164 do_error("Not a Doom 64 Rom\n"); 165 exit(0); 166 } 167 168 // Extract the file DOOM64.WAD 169 printf("Extracting DOOM64.WAD "); 170 fseek(in, WAD_offset[region], SEEK_SET); 171 out = fopen("DOOM64.WAD", "wb"); 172 for (int i = 0; i < WAD_size[region]; i++) 173 { 174 fread(&a, sizeof(byte), 1, in); 175 fwrite(&a, sizeof(byte), 1, out); 176 } 177 fclose(out); 178 printf("Ok\n"); 179 180 // Extract the file DOOM64.WMD 181 printf("Extracting DOOM64.WMD "); 182 fseek(in, WMD_offset[region], SEEK_SET); 183 out = fopen("DOOM64.WMD", "wb"); 184 for (int i = 0; i < WMD_size[region]; i++) 185 { 186 fread(&a, sizeof(byte), 1, in); 187 fwrite(&a, sizeof(byte), 1, out); 188 } 189 fclose(out); 190 printf("Ok\n"); 191 192 // Extract the file DOOM64.WSD 193 printf("Extracting DOOM64.WSD "); 194 fseek(in, WSD_offset[region], SEEK_SET); 195 out = fopen("DOOM64.WSD", "wb"); 196 for (int i = 0; i < WSD_size[region]; i++) 197 { 198 fread(&a, sizeof(byte), 1, in); 199 fwrite(&a, sizeof(byte), 1, out); 200 } 201 fclose(out); 202 printf("Ok\n"); 203 204 // Extract the file DOOM64.WDD 205 printf("Extracting DOOM64.WDD "); 206 fseek(in, WDD_offset[region], SEEK_SET); 207 out = fopen("DOOM64.WDD", "wb"); 208 for (int i = 0; i < WDD_size[region]; i++) 209 { 210 fread(&a, sizeof(byte), 1, in); 211 fwrite(&a, sizeof(byte), 1, out); 212 } 213 fclose(out); 214 printf("Ok\n"); 215 216 fclose(in); 217 218 printf("\nCompleted\n"); 219 return 0; 220 }