summaryrefslogtreecommitdiff
path: root/Xenogears/reinsert.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Xenogears/reinsert.cpp')
-rw-r--r--Xenogears/reinsert.cpp305
1 files changed, 305 insertions, 0 deletions
diff --git a/Xenogears/reinsert.cpp b/Xenogears/reinsert.cpp
new file mode 100644
index 0000000..e58b871
--- /dev/null
+++ b/Xenogears/reinsert.cpp
@@ -0,0 +1,305 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "fileutils.h"
+#include "cdutils.h"
+#include "generic.h"
+
+unsigned int tourne = 0;
+
+struct t_index_tab {
+ unsigned long address;
+ long size;
+ long type;
+ long index;
+};
+
+struct t_sequence {
+ unsigned int n;
+ unsigned int sum;
+ char *prefix;
+ char *name;
+ int type;
+};
+
+char *title, *iso_filename, *tbl_filename, *prefix, *in_filename;
+unsigned long iso_size;
+unsigned int nb_records, nb_seqs = 0;
+struct t_sequence sequences[1000];
+
+int slus_index = -1, force = 0;
+
+long check_iso(int f_iso);
+void write_files(int f_iso_r, int f_iso_w, int f_in, int fileindex);
+int process_def_file(int f_def);
+
+unsigned char user_data[2352];
+
+void usage(char ** argv) {
+ fprintf(stderr, "Usage: %s <definition_file.sqr> <iso_file_name> <file_index> <filename> [-f]\nSee readme.txt for details\n",
+ argv[0]);
+ exit(-1);
+}
+
+int main(int argc, char **argv)
+{
+ int f_def, f_iso_r, f_iso_w, f_in;
+ int fileindex;
+
+ verbosity = 1;
+
+ fprintf(stderr, "Xenogears File Insertor by Nicolas \"Pixel\" Noble\n\n");
+
+ if ((argc != 5) && (argc != 6)) {
+ usage(argv);
+ }
+
+ if (argc == 6) {
+ if (strcmp(argv[5], "-f")) {
+ usage(argv);
+ } else {
+ force = 1;
+ }
+ }
+
+ printm(M_STATUS, "Processing file %s...\n", argv[1]);
+
+ if ((f_def = open(argv[1], O_RDONLY)) < 0) {
+ printm(M_ERROR, "Unable to open the definition file \"%s\"...\n", argv[1]);
+ exit(-1);
+ }
+
+ if (process_def_file(f_def)) {
+ close(f_def);
+ printm(M_ERROR, "Unable to process the definition file \"%s\"...\n", argv[1]);
+ exit(-1);
+ }
+
+ iso_filename = argv[2];
+
+ printm(M_STATUS, "Begin processing iso file.\n");
+ if ((f_iso_r = open(iso_filename, O_RDONLY)) < 0) {
+ printm(M_ERROR, "Unable to open the iso file \"%s\"...\n", iso_filename);
+ exit(-1);
+ }
+
+ if ((f_iso_w = open(iso_filename, O_WRONLY)) < 0) {
+ printm(M_ERROR, "Unable to open the iso file \"%s\"...\n", iso_filename);
+ exit(-1);
+ }
+
+ if (check_iso(f_iso_r)) {
+ printm(M_ERROR, "Invalid iso file for %s\n", title);
+ printm(M_ERROR, "===> Make sure you are using a Genuine iso file.\n");
+ } else {
+ printm(M_INFO, "Genuine %s iso detected.\n", title);
+ }
+
+ fileindex = atoi(argv[3]);
+ in_filename = argv[4];
+ if ((f_in = open(in_filename, O_RDONLY)) < 0) {
+ printm(M_ERROR, "Unable to open the file \"%s\"...\n", in_filename);
+ exit(-1);
+ }
+
+ printm(M_STATUS, "Entering files write sequence\n");
+ write_files(f_iso_r, f_iso_w, f_in, fileindex);
+ close(f_iso_r);
+ close(f_iso_w);
+ exit(0);
+}
+
+/*
+ * Ugly but working... for now
+ */
+int process_def_file(int h_f_def)
+{
+ char t[1024], *p;
+ unsigned int n, sum = 0;
+ FILE * f_def = fdopen(h_f_def, "r");
+
+ if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL)
+ return 1;
+ *p = 0;
+ printm(M_INFO, "Read title: %s\n", t);
+ title = strdup(t);
+
+ if (fscanf(f_def, "%lu\n", &iso_size) != 1)
+ return 1;
+ printm(M_INFO, "Read iso size: %lu bytes\n", iso_size);
+
+ if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL)
+ return 1;
+ *p = 0;
+ printm(M_INFO, "Read index table filename: %s\n", t);
+ tbl_filename = strdup(t);
+
+ if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL)
+ return 1;
+ *p = 0;
+ printm(M_INFO, "Read global directory prefix: %s\n", t);
+ prefix = strdup(t);
+
+ if (fscanf(f_def, "%u\n", &nb_records) != 1)
+ return 1;
+ printm(M_INFO, "Read total of records: %u\n", nb_records);
+
+ while (1) {
+ if (fscanf(f_def, "%u\n", &n) != 1)
+ return 1;
+ if (!n) {
+ if (sum == nb_records) {
+ printm(M_INFO, "Definition file seems coherent\n");
+ return 0;
+ } else {
+ printm(M_ERROR, "Definition file incoherent\n");
+ return 1;
+ }
+ }
+ sum += n;
+ sequences[nb_seqs].n = n;
+ sequences[nb_seqs].sum = sum;
+ if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL)
+ return 1;
+ *p = 0;
+ sequences[nb_seqs].prefix = strdup(t);
+ if (fscanf(f_def, "%u\n", &n) != 1)
+ return 1;
+ sequences[nb_seqs].type = n;
+ if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL)
+ return 1;
+ *p = 0;
+ sequences[nb_seqs].name = strdup(t);
+ printm(M_INFO, "Read definition of sequence %i:\n===> %5i (sum = %5i) chunks of %s (%s)\n",
+ nb_seqs, n, sum, t, sequences[nb_seqs].prefix);
+ nb_seqs++;
+ }
+}
+
+long check_iso(int f_iso)
+{
+ unsigned long length;
+
+ length = filesize(f_iso);
+ printm(M_INFO, "Filesize of iso file %s is %ld bytes\n", iso_filename, length);
+ if (length != iso_size) {
+ return 1;
+ }
+ return 0;
+}
+
+#define INDEXPOS 24
+
+void rewrite_fat(int f_iso_r, int f_iso_w, unsigned char * new_fat) {
+ unsigned char old_fat[34816];
+ int i;
+
+ sector_seek(f_iso_w, INDEXPOS);
+ for (i = INDEXPOS; i < (INDEXPOS + 16); i++) {
+ printm(M_INFO, "Writing fat sector %lu\n", i);
+ write_sector(f_iso_r, f_iso_w, &new_fat[2048 * (i - INDEXPOS)], MODE_2_FORM_1);
+ }
+
+ sector_seek(f_iso_r, slus_index + 1);
+ for (i = slus_index + 1; i < (slus_index + 18); i++) {
+ printm(M_INFO, "Reading SLUS sector %lu\n", i);
+ read_sector(f_iso_r, &old_fat[2048 * (i - slus_index - 1)], MODE_2_FORM_1);
+ }
+
+ bcopy((char *) new_fat, (char *) old_fat + 4, 32768);
+ sector_seek(f_iso_w, slus_index + 1);
+ for (i = slus_index + 1; i < (slus_index + 18); i++) {
+ printm(M_INFO, "Writing SLUS sector %lu\n", i);
+ write_sector(f_iso_r, f_iso_w, &old_fat[2048 * (i - slus_index - 1)], MODE_2_FORM_1);
+ }
+}
+
+void write_files(int f_iso_r, int f_iso_w, int f_in, int fileindex)
+{
+ t_index_tab index_tab[10000];
+ unsigned char t[8];
+ unsigned long i;
+ unsigned long j;
+ unsigned int seq = 0;
+ unsigned long indexer;
+ struct t_index_tab *p = (struct t_index_tab *) t;
+
+ long old_file_size, new_file_size, old_nb_sects, new_nb_sects;
+ unsigned char fat[32768];
+
+ sector_seek(f_iso_r, INDEXPOS);
+ for (i = INDEXPOS; i < (INDEXPOS + 16); i++) {
+ printm(M_INFO, "Reading fat sector %lu\n", i);
+ read_sector(f_iso_r, &fat[2048 * (i - INDEXPOS)], MODE_2_FORM_1);
+ }
+
+ indexer = 0;
+ for (j = 0; j < 32768; j = j + 7) {
+ t[0] = 0;
+ bcopy((char *) &fat[j], (char *) t + 1, 7);
+ p->address >>= 8;
+ index_tab[indexer] = *p;
+ if (p->size > 0 && p->address != 0) {
+ index_tab[indexer].index = j / 7;
+ printm(M_INFO, "Found a quite valid index: number %4lu, address %6lu, size %3li\n",
+ indexer, index_tab[indexer].address, index_tab[indexer].size);
+ indexer++;
+ if (indexer == nb_records)
+ break;
+ } else {
+ printm(M_WARNING, "Ignored invalid index chunk number %4lu (size = %lu) (%02x %02x %02x %02x %02x %02x %02x)\n",
+ j / 7, -index_tab[indexer].size, t[0], t[1], t[2], t[4], t[5], t[6], t[7]);
+ }
+ }
+ printm(M_STATUS, "Index file generation complete.\n\n");
+
+ for (i = 0; i < nb_records; i++) {
+ if (sequences[seq].sum == i)
+ seq++;
+ index_tab[i].type = sequences[seq].type;
+ if (!strcmp(sequences[seq].prefix, "SLUS")) {
+ if (slus_index >= 0) {
+ printm(M_ERROR, "Two SLUS files defined\n");
+ exit(-1);
+ }
+ slus_index = index_tab[i].address;
+ }
+ }
+
+ if (slus_index < 0) {
+ printm(M_ERROR, "No SLUS file defined\n");
+ exit(-1);
+ }
+
+ printm(M_INFO, "SLUS file found at sector %6i\n", slus_index);
+
+ new_file_size = filesize(f_in);
+ old_file_size = index_tab[fileindex].size;
+
+ new_nb_sects = new_file_size / sec_sizes[index_tab[fileindex].type];
+ old_nb_sects = old_file_size / sec_sizes[index_tab[fileindex].type];
+
+ if (new_file_size % sec_sizes[index_tab[fileindex].type]) {
+ new_nb_sects++;
+ }
+
+ if (old_file_size % sec_sizes[index_tab[fileindex].type]) {
+ old_nb_sects++;
+ }
+
+ if (new_nb_sects > old_nb_sects) {
+ printm(M_ERROR, "New file too big.\n");
+ if (!force) {
+ exit(-1);
+ }
+ }
+
+ printm(M_INFO, "New file size: %12li, old file size: %12li\n", new_file_size, old_file_size);
+ printm(M_INFO, "New file ssize: %12li, old file ssize: %12li\n", new_nb_sects, old_nb_sects);
+
+ printm(M_INFO, "File address: %6i\n", index_tab[fileindex].address);
+
+ write_file(f_iso_r, f_iso_w, f_in, index_tab[fileindex].type, index_tab[fileindex].address);
+ *((long *)(&fat[index_tab[fileindex].index * 7 + 3])) = new_file_size;
+ rewrite_fat(f_iso_r, f_iso_w, fat);
+}