summaryrefslogtreecommitdiff
path: root/ToF
diff options
context:
space:
mode:
Diffstat (limited to 'ToF')
-rwxr-xr-xToF/Makefile25
-rw-r--r--ToF/ToF.map7
-rw-r--r--ToF/main_dump.cpp275
-rwxr-xr-xToF/map2sqr35
4 files changed, 342 insertions, 0 deletions
diff --git a/ToF/Makefile b/ToF/Makefile
new file mode 100755
index 0000000..6d644ed
--- /dev/null
+++ b/ToF/Makefile
@@ -0,0 +1,25 @@
+#!/usr/bin/make -f
+
+CPPFLAGS=-Wall -g -O3 -mcpu=i686 -pedantic -pedantic-errors -Werror -I../includes -DHAVE_ZLIB
+CXX=g++
+
+LIBS=-lz
+LDFLAGS=${LIBS}
+
+TARGET = main_dump ToF.sqr
+
+all: ${TARGET}
+
+main_dump: main_dump.o ../includes/cdutils.h ../includes/generic.h ../lib/lib.a ../generic/generic.a Makefile
+ ${CXX} ${LDFLAGS} main_dump.o ../lib/lib.a ../generic/generic.a -o main_dump
+
+clean:
+ rm -f *.o ${TARGET}
+
+ToF.sqr: ToF.map Makefile
+ ./map2sqr < $< > $@
+
+.map.sqr:
+ ./map2sqr < $< > $@
+
+redo: clean all
diff --git a/ToF/ToF.map b/ToF/ToF.map
new file mode 100644
index 0000000..f701629
--- /dev/null
+++ b/ToF/ToF.map
@@ -0,0 +1,7 @@
+Threads of Fate
+357454608
+TOF
+4935
+ 0 1 BOOT 3 Various file for booting
+ 2 2 JUNK 0 Zero sized file
+ 2 4934 JUNK 3 Various stuff (startup)
diff --git a/ToF/main_dump.cpp b/ToF/main_dump.cpp
new file mode 100644
index 0000000..8c7c5f1
--- /dev/null
+++ b/ToF/main_dump.cpp
@@ -0,0 +1,275 @@
+/*
+ * Threads of Fate extractor by Nicolas "Pixel" Noble (nicolas@nobis-crew.org)
+ * Highly based upon Yazoo's Chrono Cross CD extractor
+ *
+ * ******** Original disclaimer by Yazoo ********
+ *
+ * Chrono Cross CD extractor Copyright 2000-2001 by Yazoo (hamm@efrei.fr) Revision 0.1b ANSI C
+ *
+ *
+ * Features:
+ *
+ * Dump the complete content of Chrono Chross CD1/CD2 US and Japanese version It requires a iso
+ * named Chrono1.iso in the same directory
+ *
+ * Todo list:
+ *
+ * Find a way to locate end of the last file Better support for CD2 Dump in subdirectory according
+ * to CD1/CD2 repartition Recompilation in Visual C++ 6 for disk speed optimisation Source comment
+ * and reorganisation Log feature (Optional since you can redirect output with > ) Progression
+ * indicator Better detection of the ISO with error control Major code optimisation Integration in
+ * main Chrono Cross Hacking tool
+ *
+ * ******** End of original disclaimer by Yazoo ********
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "cdutils.h"
+#include "generic.h"
+#include "Input.h"
+#include "Output.h"
+#include "String.h"
+#include "Main.h"
+#include "cdabstract.h"
+
+CODE_BEGINS
+public:
+Appli() : tourne(0), nb_seqs(0), f_def(0), f_iso(0), f_out(0), cdutil(0) {}
+virtual ~Appli() {
+ delete cdutil;
+ delete f_def;
+ delete f_iso;
+ delete f_out;
+}
+private:
+
+unsigned int tourne;
+
+struct t_index_tab {
+ unsigned long address;
+ unsigned char flags;
+ long pad;
+ long index;
+ long type;
+};
+
+struct t_sequence {
+ unsigned int n;
+ unsigned int sum;
+ String prefix;
+ String name;
+ int type;
+};
+
+String title, iso_filename, prefix;
+unsigned long iso_size;
+unsigned int nb_records, nb_seqs;
+struct t_sequence sequences[1000];
+Handle * f_def, * f_iso, * f_out;
+cdutils * cdutil;
+
+unsigned char user_data[2352];
+
+virtual int startup() throw (GeneralException)
+{
+ verbosity = M_INFO;
+
+ fprintf(stderr,
+"Threads of Fate File Extractor by Nicolas \"Pixel\" Noble\n"
+"Highly based upon the Chrono Cross File Extractor By Yazoo\n\n");
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <definition_file.sqr> <iso_file_name>\nSee readme.txt for details\n",
+ argv[0]);
+ throw Exit(-1);
+ }
+
+ printm(M_STATUS, "Processing file %s...\n", argv[1]);
+
+ f_def = new Input(argv[1]);
+
+ if (process_def_file()) {
+ printm(M_ERROR, "Unable to process the definition file \"%s\"...\n", argv[1]);
+ throw Exit(-1);
+ }
+
+ iso_filename = argv[2];
+
+ printm(M_STATUS, "Begin processing iso file.\n");
+ f_iso = open_iso(iso_filename);
+
+ if (check_iso()) {
+ printm(M_ERROR, "Invalid iso file for " + title + "\n");
+ printm(M_ERROR, "===> Make sure you are using a Genuine iso file.\n");
+ } else {
+ printm(M_INFO, "Genuine " + title + " iso detected.\n");
+ }
+
+ cdutil = new cdutils(f_iso);
+
+ printm(M_STATUS, "Entering files read sequence\n");
+ read_files();
+ throw Exit(0);
+}
+
+/*
+ * Ugly but working... for now
+ */
+int process_def_file()
+{
+ String t;
+ unsigned int n, sum = 0;
+
+ *f_def >> title;
+ printm(M_INFO, "Read title: " + title + "\n");
+
+ *f_def >> t;
+ iso_size = t.to_int();
+ printm(M_INFO, "Read iso size: %lu bytes\n", iso_size);
+
+ *f_def >> prefix;
+ printm(M_INFO, "Read global directory prefix: " + prefix + "\n");
+
+ *f_def >> t;
+ nb_records = t.to_int();
+ printm(M_INFO, "Read total of records: %u\n", nb_records);
+
+ while (1) {
+ *f_def >> t;
+ n = t.to_int();
+ 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;
+ *f_def >> sequences[nb_seqs].prefix;
+ *f_def >> t;
+ sequences[nb_seqs].type = t.to_int();
+ *f_def >> sequences[nb_seqs].name;
+ printm(M_INFO, "Read definition of sequence %i:\n===> %5i (sum = %5i) chunks of " + sequences[nb_seqs].name + " (" + sequences[nb_seqs].prefix + ")\n",
+ nb_seqs, n, sum);
+ nb_seqs++;
+ }
+}
+
+long check_iso()
+{
+ unsigned long length;
+
+ length = f_iso->GetSize();
+ if (length < 0) {
+ printm(M_INFO, "Can not get file size, assuming reading from cd.\n");
+ } else {
+ printm(M_INFO, "Filesize of iso file " + iso_filename + " is %ld bytes\n", length);
+ if (length != iso_size) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void read_files()
+{
+ t_index_tab index_tab[10000];
+ unsigned long i;
+ unsigned long j;
+ unsigned int seq = 0;
+ unsigned long indexer;
+
+ unsigned char fat[24576];
+
+#define INDEXPOS 24
+
+ cdutil->sector_seek(INDEXPOS);
+ for (i = INDEXPOS; i < (INDEXPOS + 12); i++) {
+ printm(M_INFO, "Reading fat sector %lu\n", i);
+ cdutil->read_sector(&fat[2048 * (i - INDEXPOS)], MODE_2_FORM_1);
+ }
+
+ indexer = 0;
+ for (j = 0; j < 24576; j += 4) {
+ unsigned char c1, c2, c3;
+ c1 = fat[j];
+ c2 = fat[j + 1];
+ c3 = fat[j + 2] & 0x7f;
+ index_tab[indexer].address = c1 + c2 * 256 + c3 * 65536;
+ index_tab[indexer].index = j / 4;
+ index_tab[indexer].flags = fat[j + 2] & 0x80;
+ index_tab[indexer].pad = fat[j + 3];
+ printm(M_INFO, "Found a quite valid index: number %4lu, address %6lu - flags = %02x - pad = %i\n",
+ indexer, index_tab[indexer].address, fat[j + 3] & 0x80, fat[j + 3] & 0x7f);
+ indexer++;
+ if (indexer == nb_records)
+ break;
+ }
+ printm(M_STATUS, "Index file generation complete.\n\n");
+ index_tab[indexer].address = f_iso->GetSize() / 2352;
+
+ for (i = 0; i < nb_records; i++) {
+ if (sequences[seq].sum == i)
+ seq++;
+ index_tab[i].type = sequences[seq].type;
+ if (sequences[seq].type == 0) {
+ printm(M_INFO, "%6lu - %02x: ignored\n", index_tab[i].address, index_tab[i].flags);
+ } else {
+ int size;
+ printm(M_INFO, "%6lu - %02x: ", index_tab[i].address, index_tab[i].flags);
+ size = index_tab[i + 1].address - index_tab[i].address;
+ size *= sec_sizes[index_tab[i].type];
+ size -= index_tab[i].pad * 8;
+ file_dump(index_tab[i].address, size, i, seq);
+ if (verbosity >= M_INFO) {
+ fprintf(stderr, "\n");
+ }
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+void file_dump(unsigned long debut, unsigned long taille, long num, int seq)
+{
+ long i;
+ long nbsects;
+ String nom;
+ char type = sequences[seq].type;
+ char ptitbidule[] = "-\\|/";
+
+ nom = "./" + prefix + "/";
+ MKDIR(nom.to_charp());
+
+ nom += sequences[seq].prefix + "/";
+ MKDIR(nom.to_charp());
+
+ nom += String().set("%04ld.out", num);
+
+ f_out = new Output(nom);
+ nbsects = taille / sec_sizes[type];
+ if (taille % sec_sizes[type])
+ nbsects++;
+ cdutil->sector_seek(debut);
+ for (i = 0; i < nbsects; i++) {
+ if (verbosity < M_INFO)
+ fprintf(stderr, " (%c)\010\010\010\010\010", ptitbidule[((tourne++) >> 8) % 4]);
+ cdutil->read_sector(user_data, type);
+ if (i != (nbsects - 1)) {
+ f_out->write(user_data, sec_sizes[type]);
+ } else {
+ f_out->write(user_data, taille % sec_sizes[type] ? taille % sec_sizes[type] : sec_sizes[type]);
+ }
+ }
+ delete f_out;
+ f_out = 0;
+ printm(M_BARE, " (*) Dumped file number %4ld - type \"" + sequences[seq].name + "\" \r", num);
+}
+CODE_ENDS
diff --git a/ToF/map2sqr b/ToF/map2sqr
new file mode 100755
index 0000000..a5739a0
--- /dev/null
+++ b/ToF/map2sqr
@@ -0,0 +1,35 @@
+#!/usr/bin/awk -f
+BEGIN {
+ ol = -1;
+}
+
+NR <= 4 {
+ print $0;
+}
+
+NR > 4 {
+ f = $1;
+ l = $2;
+ c = l - f + 1;
+ if ((ol + 1) != f) {
+ print "You blew it @ line", NR > "/dev/stderr"
+ exit -1;
+ }
+ ol = l;
+ print c;
+
+ d = $3;
+ print d;
+ d = $4;
+ print d;
+
+ for (i = 5; i <= NF; i++) {
+ $(i - 4) = $i;
+ }
+ NF -= 4;
+ print $0;
+}
+
+END {
+ print 0;
+}