Cross-platform update of Jamesuminator's DMC3 Pac Tools (Including Cheburat0rr's HD updates)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

196 lines
4.5 KiB

/*DMC 3 Pac injector
* coded by James
*
* Intent for an unstable repacker
* too many exceptions, so injecting is simpler
* -James
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 512
int filesize(FILE *fil) {
int size;
fseek(fil, 0, SEEK_END);
size = ftell(fil);
fseek(fil, 0, SEEK_SET);
return(size);
}
//get unsigned int,
unsigned int GETINT(unsigned char *ptr) {
return((unsigned int)((ptr[3]<<24)|(ptr[2]<<16)|(ptr[1]<<8)|ptr[0]));
}
//Main
int main(int argc, char *argv[]) {
//Greeting and opening statements
printf("\n=================================\nDevil May Cry 3 \nPAC Injector\nvBETA\nCoded by James aka Jamesuminator\n=================================\n---------------------------------\n\n");
char *pac_file, *inj_file, *outfile;
int pos;
//if not enough args, exit with usage
if (argc < 4) {
printf("Usage: %s [Pac File] [Inject File] [Position] {outfile}\nif no outfile given, replaces [Pac File]\n", argv[0]);
return(-1);
} else {
pac_file = argv[1];
inj_file = argv[2];
pos = atoi(argv[3])+1;
//if no output, it replaces input
if (argc < 5) {
outfile = pac_file;
} else {
outfile = argv[4];
}
}
//if can't open, exit
printf("Opening: %s\n", pac_file);
FILE *pac_open;
if (!(pac_open = fopen(pac_file, "rb"))) {
printf("Error Opening %s\n", pac_file);
return(-1);
}
//if can't get size, exit
unsigned int size;
if (!(size = filesize(pac_open))) {
printf("Error Getting File Size\n");
return(-1);
}
//if not enough memory, exit
char *buffer;
if (!(buffer = malloc(size))) {
printf("Not Enough Memory\n");
return(-1);
}
//if can't read, exit
printf("Reading: %s\n", pac_file);
if (!(fread(buffer, 1, size, pac_open))) {
printf("Error Reading %s\n", pac_file);
return(-1);
}
fclose(pac_open); //close
//if can't get number of files, probably invalid file.
//exit
unsigned int num_files;
if (!(num_files = GETINT(buffer+4))) {
printf("Error Getting Filecount\n");
return(-1);
} else { //print the amount of files
printf("\nNumber of Files: %d\n", num_files);
}
//if the position is out of range
if (pos > num_files) {
printf("Indexed out of range: %d\n", pos-1);
return(-1);
}
//old file length, new file length, offset of the file
unsigned int old_len, new_len, offset;
if (!(offset = GETINT(buffer+((pos+1)*4)))) {
printf("Error Getting Offsets\n");
return(-1);
} else if (!(offset)) {
printf("Inavlid Position!\nNull Value @ 0x%X\n", pos);
} else {
printf("File @ 0x%X\n", offset);
}
//it's file after offset minus file offset
old_len = (GETINT(buffer +((pos+2)*4))) - (GETINT(buffer +((pos+1)*4)));
if (!(old_len)) { //if last file, it's size minus file offset
printf("%d", size);
old_len = size - (GETINT(buffer +((pos+1)*4)));
}
//injected file
//if can't open, exit
FILE *inj_open;
printf("\nOpening: %s\n", inj_file);
if (!(inj_open = fopen(inj_file, "rb"))) {
printf("Error Opening %s\n", inj_file);
return(-1);
}
//if can't get size, exit
if (!(new_len = filesize(inj_open))) {
printf("Error Getting File Size\n");
return(-1);
}
//if not enough memory, exit
char *inj;
if (!(inj = malloc(new_len))) {
printf("Not Enough Memory\n");
return(-1);
}
//if can't read, exit
printf("Reading: %s\n", inj_file);
if(!(fread(inj, 1, new_len, inj_open))) {
printf("Error Reading %s", inj_file);
return(-1);
}
fclose(inj_open); //close it
//output file
//Header
//if can't open, exit
FILE *outopen;
printf("\nOpening: %s\n", outfile);
if (!(outopen = fopen(outfile, "wb"))) {
printf("Error Opening %s\n", outfile);
return(-1);
}
//if can't write, exit
printf("\tWriting Header...");
if(!(fwrite(buffer, 1, (pos+2)*4, outopen))) {
printf("\nError Writing %s\n", outfile);
return(-1);
}
//get the end of header
int header_end = (num_files+2)*4;
int i, off;
//correct offsets of following pointers
for (i=pos; i<num_files; i++) {
off = ((GETINT(buffer + ((i+2)*4))) != 0) ? (GETINT(buffer + ((i+2)*4))) + (new_len-old_len) : 0;
fwrite(&off, 1, 4, outopen);
}
printf("Done\n");
//BODY
printf("\tWriting Body...");
//write after header, to offset
fwrite(buffer+header_end, 1, offset-header_end, outopen);
int end = offset+old_len; //end of old file
//write the inject file
fwrite(inj, 1, new_len, outopen);
//write past the old file
fwrite(buffer+end, 1, size-end, outopen);
printf("Done\n");
fclose(outopen); //close
//All Done!
printf("\nAll Done!\n");
return(0);
}