[Scummvm-cvs-logs] SF.net SVN: scummvm:[42089] tools/branches/gsoc2009-gui
Remere at users.sourceforge.net
Remere at users.sourceforge.net
Sat Jul 4 15:29:16 CEST 2009
Revision: 42089
http://scummvm.svn.sourceforge.net/scummvm/?rev=42089&view=rev
Author: Remere
Date: 2009-07-04 13:29:16 +0000 (Sat, 04 Jul 2009)
Log Message:
-----------
*Merged with tools/trunk revision 41687.
Note: compress_tinsel will not compile
Revision Links:
--------------
http://scummvm.svn.sourceforge.net/scummvm/?rev=41687&view=rev
Modified Paths:
--------------
tools/branches/gsoc2009-gui/Makefile
tools/branches/gsoc2009-gui/Makefile.mingw
tools/branches/gsoc2009-gui/compress.cpp
tools/branches/gsoc2009-gui/compress_gob.cpp
tools/branches/gsoc2009-gui/compress_tucker.cpp
tools/branches/gsoc2009-gui/degob_script.cpp
tools/branches/gsoc2009-gui/degob_script.h
tools/branches/gsoc2009-gui/descumm6.cpp
tools/branches/gsoc2009-gui/extract_gob_stk.cpp
tools/branches/gsoc2009-gui/extract_t7g_mac.cpp
tools/branches/gsoc2009-gui/util.cpp
Added Paths:
-----------
tools/branches/gsoc2009-gui/compress_gob.h
tools/branches/gsoc2009-gui/compress_tinsel.cpp
Property Changed:
----------------
tools/branches/gsoc2009-gui/degob_script_v6.cpp
tools/branches/gsoc2009-gui/extract_t7g_mac.cpp
tools/branches/gsoc2009-gui/sci/
Modified: tools/branches/gsoc2009-gui/Makefile
===================================================================
--- tools/branches/gsoc2009-gui/Makefile 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/Makefile 2009-07-04 13:29:16 UTC (rev 42089)
@@ -68,6 +68,7 @@
compress_scumm_sou$(EXEEXT) \
compress_sword1$(EXEEXT) \
compress_sword2$(EXEEXT) \
+ compress_tinsel$(EXEEXT) \
compress_touche$(EXEEXT) \
compress_tucker$(EXEEXT) \
decine$(EXEEXT) \
@@ -144,6 +145,9 @@
compress_sword2$(EXEEXT): compress_sword2.o compress.o util.o
$(CXX) $(LDFLAGS) -o $@ $+ -lvorbis -logg -lvorbisenc -lFLAC
+compress_tinsel$(EXEEXT): compress_tinsel.o compress.o util.o
+ $(CXX) $(LDFLAGS) -o $@ $+ -lvorbis -logg -lvorbisenc -lFLAC
+
compress_touche$(EXEEXT): compress_touche.o compress.o util.o
$(CXX) $(LDFLAGS) -o $@ $+ -lvorbis -logg -lvorbisenc -lFLAC
Modified: tools/branches/gsoc2009-gui/Makefile.mingw
===================================================================
--- tools/branches/gsoc2009-gui/Makefile.mingw 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/Makefile.mingw 2009-07-04 13:29:16 UTC (rev 42089)
@@ -21,6 +21,7 @@
strip compress_scumm_sou.exe -o $(SCUMMVMPATH)/tools/compress_scumm_sou.exe
strip compress_sword1.exe -o $(SCUMMVMPATH)/tools/compress_sword1.exe
strip compress_sword2.exe -o $(SCUMMVMPATH)/tools/compress_sword2.exe
+ strip compress_tinsel.exe -o $(SCUMMVMPATH)/tools/compress_tinsel.exe
strip compress_touche.exe -o $(SCUMMVMPATH)/tools/compress_touche.exe
strip compress_tucker.exe -o $(SCUMMVMPATH)/tools/compress_tucker.exe
strip decine.exe -o $(SCUMMVMPATH)/tools/decine.exe
Modified: tools/branches/gsoc2009-gui/compress.cpp
===================================================================
--- tools/branches/gsoc2009-gui/compress.cpp 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/compress.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -302,7 +302,7 @@
printf(" - sample rate = %d\n", sampleRate);
printf(" - compression = %dbits\n", bitsPerSample);
- setRawAudioType(true, numChannels == 2, bitsPerSample);
+ setRawAudioType(true, numChannels == 2, (uint8)bitsPerSample);
encodeRaw(wavData, length, sampleRate, outname, compmode);
fclose(inputWav);
Modified: tools/branches/gsoc2009-gui/compress_gob.cpp
===================================================================
--- tools/branches/gsoc2009-gui/compress_gob.cpp 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/compress_gob.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -21,32 +21,36 @@
*/
#include "util.h"
-#define confSTK21 "STK21"
-#define confSTK10 "STK10"
+#include "compress_gob.h"
struct Chunk {
char name[64];
- uint32 size, offset;
- bool packed;
-
+ uint32 size, realSize, offset;
+ uint8 packed;
+ Chunk *replChunk;
Chunk *next;
Chunk() : next(0) { }
~Chunk() { delete next; }
};
-Chunk *readChunkConf(FILE *gobconf, uint16 &chunkCount);
+Chunk *readChunkConf(FILE *gobconf, const char *stkName, uint16 &chunkCount);
void writeEmptyHeader(FILE *stk, uint16 chunkCount);
-void writeBody(Filename *inpath, FILE *stk, uint16 chunkcount, Chunk *chunks);
-uint32 writeBodyFile(FILE *stk, FILE *src);
+void writeBody(Filename *inpath, FILE *stk, Chunk *chunks);
+uint32 writeBodyStoreFile(FILE *stk, FILE *src);
uint32 writeBodyPackFile(FILE *stk, FILE *src);
void rewriteHeader(FILE *stk, uint16 chunkCount, Chunk *chunks);
-bool checkDico(byte *unpacked, uint32 unpackedIndex, int32 counter, byte *dico, uint16 &pos, uint8 &length);
+bool filcmp(FILE *src1, Chunk *compChunk);
+bool checkDico(byte *unpacked, uint32 unpackedIndex, int32 counter, byte *dico, uint16 currIndex, uint16 &pos, uint8 &length);
-byte *packData(byte *src, uint32 &size);
+uint8 execMode;
int export_main(compress_gob)(int argc, char *argv[]) {
- const char *helptext = "\nUsage: %s [-o <output> = out.stk] <input file>\n";
+ const char *helptext =
+ "\nUsage: %s [-f] [-o <output> = out.stk] <conf file>\n"
+ "<conf file> is a .gob file generated extract_gob_stk\n"
+ "<-f> ignores the compression flag in the .gob file and force compression for all files\n\n"
+ "The STK/ITK archive will be created in the current directory.\n";
Chunk *chunks;
FILE *stk;
@@ -56,9 +60,6 @@
int first_arg = 1;
int last_arg = argc - 1;
- // Check if we should display some helpful text
- parseHelpArguments(argv, argc, helptext);
-
// Now we try to find the proper output
// also make sure we skip those arguments
if (parseOutputFileArguments(&outpath, argv, argc, first_arg))
@@ -69,6 +70,13 @@
// Standard output
outpath.setFullPath("out.stk");
+
+ execMode = MODE_NORMAL;
+ if(strcmp(argv[first_arg], "-f") == 0) {
+ execMode |= MODE_FORCE;
+ ++first_arg;
+ }
+
if (last_arg - first_arg != 0)
error("Expected only one input file");
@@ -84,17 +92,16 @@
if (!(gobConf = fopen(inpath.getFullPath().c_str(), "r")))
error("Couldn't open conf file '%s'", inpath.getFullPath().c_str());
- // Open output filk
if (!(stk = fopen(outpath.getFullPath().c_str(), "wb")))
error("Couldn't create file \"%s\"", outpath.getFullPath().c_str());
// Read the input into memory
- chunks = readChunkConf(gobConf, chunkCount);
+ chunks = readChunkConf(gobConf, outpath.getFullName().c_str(), chunkCount);
fclose(gobConf);
// Output in compressed format
writeEmptyHeader (stk, chunkCount);
- writeBody(&inpath, stk, chunkCount, chunks);
+ writeBody(&inpath, stk, chunks);
rewriteHeader(stk, chunkCount, chunks);
// Cleanup
@@ -114,25 +121,72 @@
error(msg);
}
-Chunk *readChunkConf(FILE *gobConf, uint16 &chunkCount) {
+/*! \brief Config file parser
+ * \param gobConf Config file to parse
+ * \param stk STK/ITK archive file to be created
+ * \param chunkCount Number of chunks to be written in the archive file
+ * \return A list of chunks
+ *
+ * This function reads the '.gob' config file (generated by extract_gob_stk).
+ * It creates the output archive file and a list of chunks containing the file
+ * and compression information.
+ * In order to have a slightly better compression ration in some cases (Playtoons), it
+ * also detects duplicate files.
+ */
+Chunk *readChunkConf(FILE *gobConf, const char *stkName, uint16 &chunkCount) {
Chunk *chunks = new Chunk;
Chunk *curChunk = chunks;
- char buffer [1024];
+ Chunk *parseChunk;
+ FILE *src1;
+ char buffer[1024];
chunkCount = 1;
-// first read (signature, not yet used)
+// First read: Output filename
+ fscanf(gobConf, "%s", stkName);
+
+// Second read: signature
fscanf(gobConf, "%s", buffer);
+ if (!strcmp(buffer, confSTK21))
+ error("STK21 not yet handled");
+ else if (strcmp(buffer, confSTK10))
+ error("Unknown format signature");
+// All the other reads concern file + compression flag
fscanf(gobConf, "%s", buffer);
while (!feof(gobConf)) {
strcpy(curChunk->name, buffer);
fscanf(gobConf, "%s", buffer);
- if (strcmp(buffer, "1") == 0)
+ if ((strcmp(buffer, "1") == 0) || (execMode & MODE_FORCE))
curChunk->packed = true;
else
curChunk->packed = false;
+ if (! (src1 = fopen(curChunk->name, "rb"))) {
+ error("Unable to read %s", curChunk->name);
+ }
+ fseek(src1, 0, SEEK_END);
+// if file is too small, force 'Store' method
+ if ((curChunk->realSize = ftell(src1)) < 8)
+ curChunk->packed = 0;
+
+ parseChunk = chunks;
+ while (parseChunk != curChunk) {
+ if ((parseChunk->realSize == curChunk->realSize) & (parseChunk->packed != 2)) {
+ if (strcmp(parseChunk->name, curChunk->name) == 0)
+ error("Duplicate filename found in conf file: %s", parseChunk->name);
+ if (filcmp(src1, parseChunk)) {
+// If files are identical, use the same compressed chunk instead of re-compressing the same thing
+ curChunk->packed = 2;
+ curChunk->replChunk = parseChunk;
+ printf("Identical files : %s %s (%d bytes)\n", curChunk->name, parseChunk->name, curChunk->realSize);
+ break;
+ }
+ }
+ parseChunk = parseChunk->next;
+ }
+ fclose(src1);
+
fscanf(gobConf, "%s", buffer);
if (!feof(gobConf)) {
curChunk->next = new Chunk;
@@ -143,87 +197,104 @@
return chunks;
}
+/*! \brief Write an empty header to the STK archive
+ * \param stk STK/ITK archive file
+ * \param chunkCount Number of chunks to be written in the archive file
+ *
+ * This function writes an empty header in the STK archive. This is required as
+ * the header length is variable and depends on the number of chunks to be written
+ * in the archive file.
+ *
+ * This header will be overwritten just before the end of the program execution
+ */
void writeEmptyHeader(FILE *stk, uint16 chunkCount) {
- int count;
-
-// Write empty header
- for (count = 0; count < 2 + (chunkCount * 22); count++)
+ for (uint32 count = 0; count < 2 + (uint32) (chunkCount * 22); count++)
fputc(0, stk);
return;
}
-void writeBody(Filename *inpath, FILE *stk, uint16 chunkCount, Chunk *chunks) {
+/*! \brief Write the body of the STK archive
+ * \param stk STK/ITK archive file
+ * \param chunks Chunk list
+ *
+ * This function writes the body of the STK archive by storing or compressing
+ * (or skipping duplicate files) the files. It also updates the chunk information
+ * with the size of the chunk in the archive, the compression method (if modified),
+ * ...
+ */
+void writeBody(Filename *inpath, FILE *stk, Chunk *chunks) {
Chunk *curChunk = chunks;
FILE *src;
- uint32 realSize;
- int count;
- char buffer[4096];
uint32 tmpSize;
-
- while (curChunk) {
+
+ while(curChunk) {
inpath->setFullName(curChunk->name);
if (!(src = fopen(inpath->getFullPath().c_str(), "rb")))
- error("Couldn't open conf file \"%s\"", inpath->getFullPath().c_str());
+ error("Couldn't open file \"%s\"", inpath->getFullPath().c_str());
- realSize = fileSize(src);
+ if (curChunk->packed == 2)
+ printf("Identical file %12s\t(compressed size %d bytes)\n", curChunk->name, curChunk->replChunk->size);
- if (curChunk->packed)
+ curChunk->offset = ftell(stk);
+ if (curChunk->packed == 1) {
+ printf("Compressing %12s\t", curChunk->name);
curChunk->size = writeBodyPackFile(stk, src);
- else {
+ printf("%d -> %d bytes", curChunk->realSize, curChunk->size);
+ if (curChunk->size >= curChunk->realSize) {
+// If compressed size >= realsize, compression is useless
+// => Store instead
+ curChunk->packed = 0;
+ fseek(stk, curChunk->offset, SEEK_SET);
+ rewind(src);
+ printf("!!!");
+ }
+ printf("\n");
+ }
+
+ if (curChunk->packed == 0) {
tmpSize = 0;
- do {
- count = fread(buffer, 1, 4096, src);
- fwrite(buffer, 1, count, stk);
- tmpSize += count;
- } while (count == 4096);
- curChunk->size = tmpSize;
+ printf("Storing %12s\t", curChunk->name);
+ curChunk->size = writeBodyStoreFile(stk, src);
+ printf("%d bytes\n", curChunk->size);
}
-// printf("File: %s inside STK size: %d original size: %d\n", curChunk->name, curChunk->size, realSize);
fclose(src);
curChunk = curChunk->next;
}
return;
}
-uint32 writeBodyFile(FILE *stk, FILE *src) {
- int count;
- char buffer[4096];
- uint32 tmpSize;
-
- tmpSize = 0;
- do {
- count = fread(buffer, 1, 4096, src);
- fwrite(buffer, 1, count, stk);
- tmpSize += count;
- } while (count == 4096);
- return tmpSize;
-}
-
-
+/*! \brief Rewrites the header of the archive file
+ * \param stk STK/ITK archive file
+ * \param chunkCount Number of chunks
+ * \param chunks List of chunks
+ *
+ * This function rewrites the header of the archive, replacing dummy values
+ * by the one computed during execution.
+ * The structure of the header is the following :
+ * + 2 bytes : numbers of files archived in the .stk/.itk
+ * Then, for each files :
+ * + 13 bytes : the filename, terminated by '\0'. In original, there's
+ * garbage after if the filename has not the maximum length
+ * + 4 bytes : size of the chunk
+ * + 4 bytes : start position of the chunk in the file
+ * + 1 byte : If 0 : not compressed, if 1 : compressed
+ *
+ * The duplicate files are defined using the same information
+ * as the one of the replacement file.
+*/
void rewriteHeader(FILE *stk, uint16 chunkCount, Chunk *chunks) {
uint16 i;
char buffer[1024];
Chunk *curChunk = chunks;
- uint32 filPos;
rewind(stk);
-// The structure of the header is the following :
-//+ 2 bytes : numbers of files archived in the .stk/.itk
-// Then, for each files :
-//+ 13 bytes : the filename, terminated by '\0'. In original, there's
-// garbage after if the filename has not the maximum length
-//+ 4 bytes : size of the chunk
-//+ 4 bytes : start position of the chunk in the file
-//+ 1 byte : If 0 : not compressed, if 1 : compressed
- filPos = 2 + (chunkCount * 22);
-
buffer[0] = chunkCount & 0xFF;
buffer[1] = chunkCount >> 8;
fwrite(buffer, 1, 2, stk);
- // TODO : Implement STK21
+// TODO : Implement STK21
while (curChunk) {
for (i = 0; i < 13; i++)
if (i < strlen(curChunk->name))
@@ -232,26 +303,61 @@
buffer[i] = '\0';
fwrite(buffer, 1, 13, stk);
- buffer[0] = curChunk->size;
- buffer[1] = curChunk->size >> 8;
- buffer[2] = curChunk->size >> 16;
- buffer[3] = curChunk->size >> 24;
- buffer[4] = filPos;
- buffer[5] = filPos >> 8;
- buffer[6] = filPos >> 16;
- buffer[7] = filPos >> 24;
-
- buffer[8] = curChunk->packed ? 0x1 : 0x0;
-
+ if (curChunk->packed == 2)
+ {
+ buffer[0] = curChunk->replChunk->size;
+ buffer[1] = curChunk->replChunk->size >> 8;
+ buffer[2] = curChunk->replChunk->size >> 16;
+ buffer[3] = curChunk->replChunk->size >> 24;
+ buffer[4] = curChunk->replChunk->offset;
+ buffer[5] = curChunk->replChunk->offset >> 8;
+ buffer[6] = curChunk->replChunk->offset >> 16;
+ buffer[7] = curChunk->replChunk->offset >> 24;
+ buffer[8] = curChunk->replChunk->packed;
+ } else {
+ buffer[0] = curChunk->size;
+ buffer[1] = curChunk->size >> 8;
+ buffer[2] = curChunk->size >> 16;
+ buffer[3] = curChunk->size >> 24;
+ buffer[4] = curChunk->offset;
+ buffer[5] = curChunk->offset >> 8;
+ buffer[6] = curChunk->offset >> 16;
+ buffer[7] = curChunk->offset >> 24;
+ buffer[8] = curChunk->packed;
+ }
fwrite(buffer, 1, 9, stk);
- filPos += curChunk->size;
-
curChunk = curChunk->next;
}
return;
}
-// Some LZ77-variant
+/*! \brief Stores a file in the archive file
+ * \param stk STK/ITK archive file
+ * \param src File to be stored
+ * \return Size of the file stored
+ *
+ * This function stores a file in the STK archive
+ */
+uint32 writeBodyStoreFile(FILE *stk, FILE *src) {
+ int count;
+ char buffer[4096];
+ uint32 tmpSize = 0;
+
+ do {
+ count = fread(buffer, 1, 4096, src);
+ fwrite(buffer, 1, count, stk);
+ tmpSize += count;
+ } while (count == 4096);
+ return tmpSize;
+}
+
+/*! \brief Compress a file in the archive file
+ * \param stk STK/ITK archive file
+ * \param src File to be stored
+ * \return Size of the resulting compressed chunk
+ *
+ * This function compress a file in the STK archive
+ */
uint32 writeBodyPackFile(FILE *stk, FILE *src) {
byte dico[4114];
byte writeBuffer[17];
@@ -277,33 +383,35 @@
writeBuffer[3] = size >> 24;
fwrite(writeBuffer, 1, 4, stk);
-// TODO : check size, if too small, handle correctly
-
+// Size is already checked : small files (less than 8 characters)
+// are not compressed, so copying the first three bytes is safe.
dicoIndex = 4078;
dico[dicoIndex] = unpacked[0];
dico[dicoIndex+1] = unpacked[1];
dico[dicoIndex+2] = unpacked[2];
dicoIndex += 3;
-//writeBuffer[0] is reserved for the command byte
+// writeBuffer[0] is reserved for the command byte
writeBuffer[1] = unpacked[0];
writeBuffer[2] = unpacked[1];
writeBuffer[3] = unpacked[2];
+// Force the 3 first operation bits to 'copy character'
+ cmd = (1 << 3) - 1;
counter = size - 3;
unpackedIndex = 3;
cpt = 3;
buffIndex = 4;
- cmd = (1 << 3) - 1;
size=4;
resultcheckpos = 0;
resultchecklength = 0;
while (counter>0) {
- if (!checkDico(unpacked, unpackedIndex, counter, dico, resultcheckpos, resultchecklength)) {
+ if (!checkDico(unpacked, unpackedIndex, counter, dico, dicoIndex, resultcheckpos, resultchecklength)) {
dico[dicoIndex] = unpacked[unpackedIndex];
writeBuffer[buffIndex] = unpacked[unpackedIndex];
+// set the operation bit : copy character
cmd |= (1 << cpt);
unpackedIndex++;
dicoIndex = (dicoIndex + 1) % 4096;
@@ -311,14 +419,16 @@
counter--;
} else {
// Copy the string in the dictionary
- for (int i=0; i < resultchecklength; i++)
+ for (int i = 0; i < resultchecklength; i++)
dico[((dicoIndex + i) % 4096)] = dico[((resultcheckpos + i) % 4096)];
// Write the copy string command
writeBuffer[buffIndex] = resultcheckpos & 0xFF;
writeBuffer[buffIndex + 1] = ((resultcheckpos & 0x0F00) >> 4) + (resultchecklength - 3);
-// printf("ptr 0x%x cpt 0x%x -> 0x%x 0x%x\n", resultcheckpos, resultchecklength, (byte) writeBuffer[buffIndex], writeBuffer[buffIndex + 1]);
+// Do not set the operation bit : copy string from dictionary
+// cmd |= (0 << cpt);
+
unpackedIndex += resultchecklength;
dicoIndex = (dicoIndex + resultchecklength) % 4096;
resultcheckpos = (resultcheckpos + resultchecklength) % 4096;
@@ -327,7 +437,8 @@
counter -= resultchecklength;
}
-
+// The command byte is complete when the file is entirely compressed, or
+// when the 8 operation bits are set.
if ((cpt == 7) | (counter == 0)) {
writeBuffer[0] = cmd;
fwrite(writeBuffer, 1, buffIndex, stk);
@@ -339,61 +450,92 @@
cpt++;
}
-// filDico = fopen("dico.gob", "wb");
-// fwrite(dico, 1, 4114, filDico);
-// fclose(filDico);
-
delete[] unpacked;
return size;
}
-bool checkDico(byte *unpacked, uint32 unpackedIndex, int32 counter, byte *dico, uint16 &pos, uint8 &length) {
+/*! \brief Compare a file to a file defined in a chunk
+ * \param src1 File to be compared
+ * \param compChunk Chunk containing information on second file to be compared
+ * \return whether they are identical or not.
+ *
+ * This function compares a file to another defined in a chunk. The file sizes
+ * are already tested outside the function.
+ */
+bool filcmp(FILE *src1, Chunk *compChunk) {
+ uint16 readCount;
+ bool checkFl = true;
+ char buf1[4096];
+ char buf2[4096];
+ FILE *src2;
+
+ rewind(src1);
+ if (!(src2 = fopen(compChunk->name, "rb")))
+ error("Couldn't open file \"%s\"", compChunk->name);
+
+ do {
+ readCount = fread(buf1, 1, 4096, src1);
+ fread(buf2, 1, 4096, src2);
+ for (int i = 0; checkFl & (i < readCount); i++)
+ if (buf1[i] != buf2[i])
+ checkFl = false;
+ } while (checkFl & (readCount == 4096));
+ fclose(src2);
+
+ return checkFl;
+}
+
+/*! \brief Compare a file to a file defined in a chunk
+ * \param unpacked Buffer being compressed
+ * \param unpackedIndex Current 'read' position in this buffer
+ * \param counter Number of bytes still to be compressed in the file
+ * \param dico Dictionary
+ * \param currIndex Current 'write' position in the dictionary (used to avoid dictionary collision)
+ * \param pos Position of the better match found, if any
+ * \param length Length of the better match found, if any
+ * \return whether a match has been found or not or not.
+ *
+ * This function search in the dictionary for matches with the characters still to be compressed.
+ * 'A match' is when at least three characters of the buffer (comparing from the current 'read' position)
+ * are found in the dictionary. The match lengths are limited to 18 characters, as the
+ * length (minus 3) is stored on 4 bits.
+ */
+bool checkDico(byte *unpacked, uint32 unpackedIndex, int32 counter, byte *dico, uint16 currIndex, uint16 &pos, uint8 &length) {
uint16 tmpPos, bestPos;
uint8 tmpLength, bestLength, i;
-// FILE *filDico;
bestPos = 0;
- bestLength = 0;
+ bestLength = 2;
if (counter < 3)
return false;
for (tmpPos = 0; tmpPos < 0x1000; tmpPos++) {
tmpLength = 0;
- for (i = 0; ((i < 8) & (i < counter)); i++)
- if (unpacked[unpackedIndex + i] == dico[(tmpPos + i) % 4096])
+ for (i = 0; ((i < 18) & (i < counter)); i++)
+ if ((unpacked[unpackedIndex + i] == dico[(tmpPos + i) % 4096]) &
+ // avoid dictionary collision
+ (((tmpPos + i) % 4096 != currIndex) | (i == 0)))
tmpLength++;
else
break;
- if (tmpLength > bestLength) {
- bestLength = tmpLength;
+ if (tmpLength > bestLength)
+ {
bestPos = tmpPos;
+ if ((bestLength = tmpLength) == 18)
+ break;
}
-
- if (bestLength == 8)
- break;
}
pos = bestPos;
length = bestLength;
- if (bestLength > 2) {
-// filDico = fopen("dico.gob", "wb");
-// fwrite(dico, 1, 4114, filDico);
-// fclose(filDico);
-// printf("Found ");
-// for (i = 0; i < bestLength; i++)
-// printf("0x%x ", dico[(bestPos + i) % 4096]);
-//
-// printf("while looking for ");
-// for (i = 0; i < bestLength; i++)
-// printf("0x%x ", unpacked[unpackedIndex + i]);
-// printf("org pos 0x%x at dico pos 0x%x\n", unpackedIndex, bestPos);
-//
+ if (bestLength > 2)
return true;
+ else {
+ length = 0;
+ return false;
}
- else
- return false;
}
#if defined(UNIX) && defined(EXPORT_MAIN)
@@ -401,4 +543,4 @@
int main(int argc, char *argv[]) {
return export_main(compress_gob)(argc, argv);
}
-#endif
+#endif
\ No newline at end of file
Copied: tools/branches/gsoc2009-gui/compress_gob.h (from rev 42088, tools/trunk/compress_gob.h)
===================================================================
--- tools/branches/gsoc2009-gui/compress_gob.h (rev 0)
+++ tools/branches/gsoc2009-gui/compress_gob.h 2009-07-04 13:29:16 UTC (rev 42089)
@@ -0,0 +1,34 @@
+/* Scumm Tools
+ * Copyright (C) 2007 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef COMPRESS_GOB_H
+#define COMPRESS_GOB_H
+
+#define confSTK21 "STK21"
+#define confSTK10 "STK10"
+
+#define MODE_NORMAL 0
+#define MODE_HELP 1
+#define MODE_FORCE 2
+#define MODE_SET 4
+
+#endif
Copied: tools/branches/gsoc2009-gui/compress_tinsel.cpp (from rev 42088, tools/trunk/compress_tinsel.cpp)
===================================================================
--- tools/branches/gsoc2009-gui/compress_tinsel.cpp (rev 0)
+++ tools/branches/gsoc2009-gui/compress_tinsel.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -0,0 +1,409 @@
+/* compress_tinsel - .smp compressor
+ * Copyright (C) 2009 The ScummVM Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+// By Jimi (m [underline] kiewitz [AT] users.sourceforge.net)
+
+#include "compress.h"
+#include "util.h"
+
+// data-format of index-file:
+// [pointer to data file DWORD] [pointer to data file DWORD] [pointer to data file DWORD]
+// we use index[0] to signal the engine what data format it's supposed to expect. It may be 'MP3 ', 'OGG ' or 'FLAC'
+
+// data-format of sample-file:
+// [sample-length DWORD] [sample-data]
+// or
+// [subsamplecount DWORD] [sample-length DWORD] [sample-data]
+// where subsamplecount has upmost bit 31 set (that's how one differentiates sample-length and subsamplecount)
+// It seems that data-format 1 is used by DiscWorld 1 and data-format 2 is used by DiscWorld 2. Also DiscWorld 1 uses
+// raw-data as samples and DiscWorld 2 uses ADPCM 6-bit encoded data as samples. We suppose that we will need to do ADPCM
+// decoding on all multi-sample data.
+
+// We also copy over the first 5000 bytes of the .smp file, because otherwise we would trash ScummVM detection.
+
+#define TEMP_IDX "compressed.idx"
+#define TEMP_SMP "compressed.smp"
+#define TEMP_RAW "tempfile.raw"
+#define TEMP_ENC "tempfile.enc"
+
+static FILE *input_idx, *input_smp, *output_idx, *output_smp;
+static CompressMode gCompMode = kMP3Mode;
+static char INPUT_IDX[256], INPUT_SMP[256];
+
+/* Converts raw-data sample in input_smp of size SampleSize to requested dataformat and writes to output_smp */
+void convertTinselRawSample (uint32 sampleSize) {
+ uint32 copyLeft = 0;
+ uint32 doneRead = 0;
+ char buffer[2048];
+ FILE *curFileHandle;
+
+ printf("Assuming DW1 sample being 8-bit raw...\n");
+
+ unlink(TEMP_RAW); unlink(TEMP_ENC);
+ curFileHandle = fopen(TEMP_RAW, "wb");
+ copyLeft = sampleSize;
+ while (copyLeft > 0) {
+ doneRead = fread(buffer, 1, copyLeft > sizeof(buffer) ? sizeof(buffer) : copyLeft, input_smp);
+ if (doneRead <= 0)
+ break;
+ copyLeft -= (int)doneRead;
+ fwrite(buffer, 1, doneRead, curFileHandle);
+ }
+ fclose(curFileHandle);
+
+ // Encode this raw data...
+ setRawAudioType(true, false, 8); // LE, mono, 8-bit (??)
+ encodeAudio(TEMP_RAW, true, 22050, TEMP_ENC, gCompMode);
+
+ // Append compressed data to output_smp
+ curFileHandle = fopen(TEMP_ENC, "rb");
+ fseek(curFileHandle, 0, SEEK_END);
+ copyLeft = ftell(curFileHandle);
+ fseek(curFileHandle, 0, SEEK_SET);
+ // Write size of compressed data
+ writeUint32LE(output_smp, copyLeft);
+ // Write actual data
+ while (copyLeft > 0) {
+ doneRead = fread(buffer, 1, copyLeft > sizeof(buffer) ? sizeof(buffer) : copyLeft, curFileHandle);
+ if (doneRead <= 0)
+ break;
+ copyLeft -= (int)doneRead;
+ fwrite(buffer, 1, doneRead, output_smp);
+ }
+ fclose(curFileHandle);
+}
+
+static const double TinselFilterTable[4][2] = {
+ {0, 0 },
+ {0.9375, 0},
+ {1.796875, -0.8125},
+ {1.53125, -0.859375}
+};
+
+template<typename T> inline T CLIP (T v, T amin, T amax)
+ { if (v < amin) return amin; else if (v > amax) return amax; else return v; }
+
+/* Converts ADPCM-data sample in input_smp of size SampleSize to requested dataformat and writes to output_smp */
+/* Quick hack together from adpcm.cpp */
+void convertTinselADPCMSample (uint32 sampleSize) {
+ byte *inBuffer, *inPos;
+ int16 *outBuffer, *outPos;
+ double predictor = 0;
+ double k0 = 0, k1 = 0;
+ double d0 = 0, d1 = 0;
+ uint32 blockAlign, blockPos;
+ uint16 chunkData;
+ int16 chunkWord;
+ uint8 headerByte, filterVal, chunkPos;
+ const double eVal = 1.032226562;
+ uint32 decodeLeft = 0, decodedCount = 0;
+ uint32 uncompressedSize;
+ double sample;
+
+ uint32 copyLeft = 0;
+ uint32 doneRead = 0;
+ char buffer[2048];
+ FILE *curFileHandle;
+
+ printf("Assuming DW2 sample using ADPCM 6-bit, decoding to 16-bit raw...\n");
+
+ // Allocate buffer for the ADPCM-compressed sample
+ inBuffer = (byte *)malloc(sampleSize);
+ if (!inBuffer) {
+ printf("malloc failed!\n");
+ return;
+ }
+
+ // Allocate buffer for uncompressed sample data (3 bytes will be uncompressed to 8 bytes)
+ uncompressedSize = (sampleSize/3)*4*2+16;
+ outBuffer = (int16 *)malloc(uncompressedSize);
+ if (!outBuffer) {
+ printf("malloc failed!\n");
+ return;
+ }
+
+ fread(inBuffer, 1, sampleSize, input_smp);
+
+ // 1 channel, 22050 rate, block align 24,
+ blockAlign = 24; // Fixed for Tinsel 6-bit
+ blockPos = blockAlign; // To make sure first header is read
+
+ inPos = inBuffer; outPos = outBuffer;
+ decodeLeft = sampleSize;
+ while (decodeLeft > 0) {
+ if (blockPos == blockAlign) {
+ // read Tinsel header
+ headerByte = *inPos; inPos++; decodeLeft--;
+ filterVal = (headerByte & 0xC0) >> 6;
+
+ if ((headerByte & 0x20) != 0) {
+ //Lower 6 bit are negative
+ // Negate
+ headerByte = ~(headerByte | 0xC0) + 1;
+ predictor = 1 << headerByte;
+ } else {
+ // Lower 6 bit are positive
+ // Truncate
+ headerByte &= 0x1F;
+ predictor = ((double) 1.0) / (1 << headerByte);
+ }
+ k0 = TinselFilterTable[filterVal][0];
+ k1 = TinselFilterTable[filterVal][1];
+ blockPos = 0;
+ chunkPos = 0;
+ }
+
+ switch (chunkPos) {
+ case 0:
+ chunkData = *inPos; inPos++; decodeLeft--;
+ chunkWord = (chunkData << 8) & 0xFC00;
+ break;
+ case 1:
+ chunkData = (chunkData << 8) | *inPos; inPos++; decodeLeft--;
+ blockPos++;
+ chunkWord = (chunkData << 6) & 0xFC00;
+ break;
+ case 2:
+ chunkData = (chunkData << 8) | *inPos; inPos++; decodeLeft--;
+ blockPos++;
+ chunkWord = (chunkData << 4) & 0xFC00;
+ break;
+ case 3:
+ chunkData = chunkData << 8;
+ blockPos++;
+ chunkWord = (chunkData << 2) & 0xFC00;
+ break;
+ }
+ sample = chunkWord;
+ sample *= eVal * predictor;
+ sample += (d0 * k0) + (d1 * k1);
+ d1 = d0;
+ d0 = sample;
+ *outPos = (int16) CLIP<double>(sample, -32768.0, 32767.0); outPos++;
+ decodedCount++;
+ chunkPos = (chunkPos + 1) % 4;
+ }
+
+ unlink(TEMP_RAW); unlink(TEMP_ENC);
+ curFileHandle = fopen(TEMP_RAW, "wb");
+ fwrite(outBuffer, 1, decodedCount*2, curFileHandle);
+ fclose(curFileHandle);
+
+ free(inBuffer); free(outBuffer);
+
+ // Encode this raw data...
+ setRawAudioType(true, false, 16); // LE, mono, 16-bit
+ encodeAudio(TEMP_RAW, true, 22050, TEMP_ENC, gCompMode);
+
+ // Append compressed data to output_smp
+ curFileHandle = fopen(TEMP_ENC, "rb");
+ fseek(curFileHandle, 0, SEEK_END);
+ copyLeft = ftell(curFileHandle);
+ fseek(curFileHandle, 0, SEEK_SET);
+ // Write size of compressed data
+ writeUint32LE(output_smp, copyLeft);
+ // Write actual data
+ while (copyLeft > 0) {
+ doneRead = fread(buffer, 1, copyLeft > sizeof(buffer) ? sizeof(buffer) : copyLeft, curFileHandle);
+ if (doneRead <= 0)
+ break;
+ copyLeft -= (int)doneRead;
+ fwrite(buffer, 1, doneRead, output_smp);
+ }
+ fclose(curFileHandle);
+}
+
+void showhelp(char *exename) {
+ printf("\nUsage: %s [params] [file]\n", exename);
+
+ printf("\nParams:\n");
+ printf(" --mp3 encode to MP3 format (default)\n");
+ printf(" --vorbis encode to Vorbis format\n");
+ printf(" --flac encode to Flac format\n");
+ printf("(If one of these is specified, it must be the first parameter.)\n");
+
+ printf("\nMP3 mode params:\n");
+ printf(" -b <rate> <rate> is the target bitrate(ABR)/minimal bitrate(VBR) (default:%d)\n", minBitrDef);
+ printf(" -B <rate> <rate> is the maximum VBR/ABR bitrate (default:%d)\n", maxBitrDef);
+ printf(" --vbr LAME uses the VBR mode (default)\n");
+ printf(" --abr LAME uses the ABR mode\n");
+ printf(" -V <value> specifies the value (0 - 9) of VBR quality (0=best) (default:%d)\n", vbrqualDef);
+ printf(" -q <value> specifies the MPEG algorithm quality (0-9; 0=best) (default:%d)\n", algqualDef);
+ printf(" --silent the output of LAME is hidden (default:disabled)\n");
+
+ printf("\nVorbis mode params:\n");
+ printf(" -b <rate> <rate> is the nominal bitrate (default:unset)\n");
+ printf(" -m <rate> <rate> is the minimum bitrate (default:unset)\n");
+ printf(" -M <rate> <rate> is the maximum bitrate (default:unset)\n");
+ printf(" -q <value> specifies the value (0 - 10) of VBR quality (10=best) (default:%d)\n", oggqualDef);
+ printf(" --silent the output of oggenc is hidden (default:disabled)\n");
+
+ printf("\nFlac mode params:\n");
+ printf(" --fast FLAC uses compression level 0\n");
+ printf(" --best FLAC uses compression level 8\n");
+ printf(" -<value> specifies the value (0 - 8) of compression (8=best)(default:%d)\n", flacCompressDef);
+ printf(" -b <value> specifies a blocksize of <value> samples (default:%d)\n", flacBlocksizeDef);
+ printf(" --verify files are encoded and then decoded to check accuracy\n");
+ printf(" --silent the output of FLAC is hidden (default:disabled)\n");
+
+ printf("\n --help this help message\n");
+
+ printf("\n\nIf a parameter is not given the default value is used\n");
+ printf("If using VBR mode for MP3 -b and -B must be multiples of 8; the maximum is 160!\n");
+ exit(2);
+}
+
+int main(int argc, char *argv[]) {
+ char inputPath[768];
+ int i;
+ uint32 indexNo = 0;
+ uint32 indexCount = 0;
+ uint32 indexOffset = 0;
+ uint32 loopCount = 0;
+ uint32 sampleSize = 0;
+ uint32 sampleCount = 0;
+
+ if (argc < 2) {
+ showhelp(argv[0]);
+ }
+
+ /* Compression mode */
+ gCompMode = kMP3Mode;
+ i = 1;
+
+ if (strcmp(argv[1], "--mp3") == 0) {
+ gCompMode = kMP3Mode;
+ i++;
+ } else if (strcmp(argv[1], "--vorbis") == 0) {
+ gCompMode = kVorbisMode;
+ i++;
+ } else if (strcmp(argv[1], "--flac") == 0) {
+ gCompMode = kFlacMode;
+ i++;
+ }
+
+ switch (gCompMode) {
+ case kMP3Mode:
+ if (!process_mp3_parms(argc, argv, i))
+ showhelp(argv[0]);
+ break;
+ case kVorbisMode:
+ if (!process_ogg_parms(argc, argv, i))
+ showhelp(argv[0]);
+ break;
+ case kFlacMode:
+ if (!process_flac_parms(argc, argv, i))
+ showhelp(argv[0]);
+ break;
+ }
+
+ getPath(argv[argc - 1], inputPath);
+
+ sprintf(INPUT_IDX, "%s.idx", argv[argc - 1]);
+ sprintf(INPUT_SMP, "%s.smp", argv[argc - 1]);
+
+ input_idx = fopen(INPUT_IDX, "rb");
+ if (!input_idx) {
+ printf("Cannot open file: %s\n", INPUT_IDX);
+ exit(-1);
+ }
+
+ input_smp = fopen(INPUT_SMP, "rb");
+ if (!input_smp) {
+ printf("Cannot open file: %s\n", INPUT_SMP);
+ exit(-1);
+ }
+
+ unlink(TEMP_IDX);
+ output_idx = fopen(TEMP_IDX, "wb");
+ if (!output_idx) {
+ printf("Can't open file " TEMP_IDX " for write!\n" );
+ exit(-1);
+ }
+ unlink(TEMP_SMP);
+ output_smp = fopen(TEMP_SMP, "wb");
+ if (!output_smp) {
+ printf("Can't open file " TEMP_SMP " for write!\n");
+ exit(-1);
+ }
+
+ fseek(input_idx, 0, SEEK_END);
+ indexCount = ftell(input_idx) / sizeof(uint32);
+ fseek(input_idx, 0, SEEK_SET);
+
+ loopCount = indexCount;
+ while (loopCount>0) {
+ indexOffset = readUint32LE(input_idx);
+ if (indexOffset) {
+ if (indexNo==0) {
+ printf("The sourcefiles are already compressed, aborting...\n");
+ return 1;
+ }
+ // Got sample(s), so convert...
+ printf("Converting sample %d of %d\n", indexNo, indexCount);
+
+ // Seek to Sample in input-file and read SampleSize
+ fseek(input_smp, indexOffset, SEEK_SET);
+ sampleSize = readUint32LE(input_smp);
+
+ // Write offset of new data to new index file
+ writeUint32LE(output_idx, ftell(output_smp));
+
+ if (sampleSize & 0x80000000) {
+ // multiple samples in ADPCM format
+ sampleCount = sampleSize & ~0x80000000;
+ // Write sample count to new sample file
+ writeUint32LE(output_smp, sampleSize);
+ while (sampleCount>0) {
+ sampleSize = readUint32LE(input_smp);
+ convertTinselADPCMSample(sampleSize);
+ sampleCount--;
+ }
+ } else {
+ // just one sample in raw format
+ convertTinselRawSample(sampleSize);
+ }
+ } else {
+ if (indexNo==0) {
+ // Write signature as index 0
+ switch (gCompMode) {
+ case kMP3Mode: writeUint32BE(output_idx, MKID_BE('MP3 ')); break;
+ case kVorbisMode: writeUint32BE(output_idx, MKID_BE('OGG ')); break;
+ case kFlacMode: writeUint32BE(output_idx, MKID_BE('FLAC')); break;
+ }
+ } else {
+ writeUint32LE(output_idx, 0);
+ }
+ }
+ loopCount--; indexNo++;
+ }
+ fclose(output_smp);
+ fclose(output_idx);
+ fclose(input_smp);
+ fclose(input_idx);
+
+ /* And some clean-up :-) */
+ unlink(TEMP_RAW);
+ unlink(TEMP_ENC);
+
+ return 0;
+}
Modified: tools/branches/gsoc2009-gui/compress_tucker.cpp
===================================================================
--- tools/branches/gsoc2009-gui/compress_tucker.cpp 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/compress_tucker.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -149,19 +149,14 @@
return current_offset + dir->count * 8;
}
-#define AUDIO_TYPES_COUNT 2
-
-#define AUDIO_WAV_COUNT 120
-#define AUDIO_RAW_COUNT 51
-
-static const char *audio_wav_fileslist[] = {
- "fx100.wav",
+static const char *audio_files_list[] = {
+ "demomenu.raw",
+ "demorolc.raw",
"fx101.wav",
"fx102.wav",
"fx103.wav",
"fx104.wav",
"fx105.wav",
- "fx106.wav",
"fx107.wav",
"fx108.wav",
"fx109.wav",
@@ -170,7 +165,6 @@
"fx112.wav",
"fx113.wav",
"fx114.wav",
- "fx115.wav",
"fx116.wav",
"fx117.wav",
"fx32.wav",
@@ -186,15 +180,12 @@
"fx43.wav",
"fx44.wav",
"fx45.wav",
- "fx46.wav",
"fx47.wav",
"fx48.wav",
"fx49.wav",
"fx50.wav",
- "fx51.wav",
"fx52.wav",
"fx53.wav",
- "fx54.wav",
"fx55.wav",
"fx56.wav",
"fx57.wav",
@@ -221,74 +212,14 @@
"fx79.wav",
"fx80.wav",
"fx81.wav",
- "fx82.wav",
"fx83.wav",
- "fx84.wav",
- "fx85.wav",
"fx86.wav",
- "fx87.wav",
- "fx88.wav",
- "fx89.wav",
- "fx90.wav",
"fx91.wav",
"fx92.wav",
"fx93.wav",
- "fx96.wav",
"fx97.wav",
"fx98.wav",
- "fx99.wav",
- "introdua.wav",
- "rdfx1.wav",
- "rdfx10.wav",
- "rdfx11.wav",
- "rdfx12.wav",
- "rdfx13.wav",
- "rdfx14.wav",
- "rdfx15.wav",
- "rdfx16.wav",
- "rdfx17.wav",
- "rdfx18.wav",
- "rdfx19.wav",
- "rdfx2.wav",
- "rdfx20.wav",
- "rdfx21.wav",
- "rdfx22.wav",
- "rdfx23.wav",
- "rdfx24.wav",
- "rdfx25.wav",
- "rdfx26.wav",
- "rdfx27.wav",
- "rdfx28.wav",
- "rdfx29.wav",
- "rdfx3.wav",
- "rdfx30.wav",
- "rdfx31.wav",
- "rdfx32.wav",
- "rdfx33.wav",
- "rdfx35.wav",
- "rdfx36.wav",
- "rdfx37.wav",
- "rdfx38.wav",
- "rdfx4.wav",
- "rdfx5.wav",
- "rdfx6.wav",
- "rdfx7.wav",
- "rdfx8.wav",
- "rdfx9.wav"
-};
-
-static const char *audio_raw_fileslist[] = {
- "democha1.raw",
- "democha2.raw",
- "demomenu.raw",
- "demorola.raw",
- "demorolc.raw",
- "icrmusic.raw",
"int1.raw",
- "int10.raw",
- "int11.raw",
- "int12.raw",
- "int13.raw",
"int14.raw",
"int15.raw",
"int16.raw",
@@ -316,87 +247,64 @@
"int36.raw",
"int37.raw",
"int38.raw",
- "int39.raw",
"int4.raw",
- "int40.raw",
"int41.raw",
"int42.raw",
"int5.raw",
"int6.raw",
"int7.raw",
- "int8.raw",
- "int9.raw",
- "introdua.raw",
- "introdub.raw",
- "merilogo.raw"
+ "introdua.wav",
+ "merilogo.raw",
+ "rdfx1.wav",
+ "rdfx12.wav",
+ "rdfx13.wav",
+ "rdfx14.wav",
+ "rdfx15.wav",
+ "rdfx16.wav",
+ "rdfx17.wav",
+ "rdfx18.wav",
+ "rdfx20.wav",
+ "rdfx21.wav",
+ "rdfx22.wav",
+ "rdfx24.wav",
+ "rdfx25.wav",
+ "rdfx26.wav",
+ "rdfx27.wav",
+ "rdfx28.wav",
+ "rdfx3.wav",
+ "rdfx30.wav",
+ "rdfx31.wav",
+ "rdfx33.wav",
+ "rdfx36.wav",
+ "rdfx37.wav",
+ "rdfx38.wav",
+ "rdfx8.wav",
+ "rdfx9.wav"
};
-static const char *audio_raw_fileslist_16LE[] = {
- "int1.raw",
- "int15.raw",
- "int16.raw",
- "int17.raw",
- "int18.raw",
- "int19.raw",
- "int2.raw",
- "int20.raw",
- "int21.raw",
- "int22.raw",
- "int23.raw",
- "int24.raw",
- "int25.raw",
- "int26.raw",
- "int27.raw",
- "int28.raw",
- "int29.raw",
- "int3.raw",
- "int30.raw",
- "int31.raw",
- "int32.raw",
- "int33.raw",
- "int34.raw",
- "int35.raw",
- "int36.raw",
- "int37.raw",
- "int38.raw",
- "int4.raw",
- "int41.raw",
- "int42.raw",
- "int5.raw",
- "int6.raw",
- "int7.raw"
+static const int audio_formats_table[] = {
+ 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2,
+ 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 2, 3, 1, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 1
};
-static int cmp_helper(const void *a, const void *b) {
- return strcmp((const char *)a, *(const char **)b);
-}
-
-struct AudioDirectory {
- const char *ext;
- int count;
-};
-
-static AudioDirectory audio_directory_table[AUDIO_TYPES_COUNT] = {
- { "wav", AUDIO_WAV_COUNT },
- { "raw", AUDIO_RAW_COUNT }
-};
-
-static uint32 compress_audio_directory(const Filename *inpath, const Filename *outpath, FILE *output, int count, int index) {
+static uint32 compress_audio_directory(const Filename *inpath, const Filename *outpath, FILE *output) {
char filepath[1024];
- int i, pos;
+ int i, pos, count;
uint32 current_offset;
FILE *input;
- char entry_name[13];
- bool is_16LE;
- assert(ARRAYSIZE(audio_wav_fileslist) == AUDIO_WAV_COUNT);
-
+ count = ARRAYSIZE(audio_files_list);
pos = ftell(output);
/* write 0 offsets/sizes table */
- memset(entry_name, 0, sizeof(entry_name));
for (i = 0; i < count; ++i) {
- fwrite(entry_name, 1, 12, output);
writeUint32LE(output, 0);
writeUint32LE(output, 0);
}
@@ -404,29 +312,25 @@
current_offset = 0;
for (i = 0; i < count; ++i) {
temp_table[i].offset = current_offset;
- switch (index) {
- case 0: /* .wav */
- sprintf(filepath, "%s/audio/%s", inpath->getPath().c_str(), audio_wav_fileslist[i]);
- input = fopen(filepath, "rb");
- if (!input) {
- error("Cannot open file '%s'", filepath);
+ sprintf(filepath, "%s/audio/%s", inpath->getPath().c_str(), audio_files_list[i]);
+ input = fopen(filepath, "rb");
+ if (!input) {
+ warning("Can't open file '%s'", filepath);
+ temp_table[i].size = 0;
+ } else {
+ switch (audio_formats_table[i]) {
+ case 1:
+ case 2:
+ temp_table[i].size = compress_file_wav(input, output);
+ break;
+ case 3:
+ temp_table[i].size = compress_file_raw(filepath, 0, output);
+ break;
+ case 4:
+ temp_table[i].size = compress_file_raw(filepath, 1, output);
+ break;
}
- temp_table[i].size = compress_file_wav(input, output);
fclose(input);
- break;
- case 1: /* .raw */
- is_16LE = bsearch(audio_raw_fileslist[i], audio_raw_fileslist_16LE,
- ARRAYSIZE(audio_raw_fileslist_16LE), sizeof(const char *), cmp_helper) != NULL;
- temp_table[i].offset = current_offset;
- sprintf(filepath, "%s/audio/%s", inpath->getPath().c_str(), audio_raw_fileslist[i]);
- input = fopen(filepath, "rb");
- if (input) {
- fclose(input);
- temp_table[i].size = compress_file_raw(filepath, is_16LE, output);
- } else {
- temp_table[i].size = 0;
- }
- break;
}
current_offset += temp_table[i].size;
}
@@ -434,9 +338,6 @@
/* fix offsets/sizes table */
fseek(output, pos, SEEK_SET);
for (i = 0; i < count; ++i) {
- memset(entry_name, 0, sizeof(entry_name));
- strcpy(entry_name, audio_wav_fileslist[i]);
- fwrite(entry_name, 1, 12, output);
writeUint32LE(output, temp_table[i].offset);
writeUint32LE(output, temp_table[i].size);
}
@@ -450,7 +351,7 @@
FILE *output;
uint32 current_offset;
uint32 sound_directory_size[SOUND_TYPES_COUNT];
- uint32 audio_directory_size[AUDIO_TYPES_COUNT];
+ uint32 audio_directory_size;
const uint16 flags = 0; // HEADER_FLAG_AUDIO_INTRO;
output = fopen(outpath->getFullPath().c_str(), "wb");
@@ -467,10 +368,7 @@
writeUint32LE(output, 0);
}
if (flags & HEADER_FLAG_AUDIO_INTRO) {
- for (i = 0; i < AUDIO_TYPES_COUNT; ++i) {
- writeUint32LE(output, 0);
- writeUint32LE(output, 0);
- }
+ writeUint32LE(output, 0);
}
/* compress the .wav files in each directory */
@@ -480,11 +378,9 @@
printf("Done (%d bytes)\n", sound_directory_size[i]);
}
if (flags & HEADER_FLAG_AUDIO_INTRO) {
- for (i = 0; i < AUDIO_TYPES_COUNT; ++i) {
- printf("Processing 'audio/*.%s' files...\n", audio_directory_table[i].ext);
- audio_directory_size[i] = compress_audio_directory(inpath, outpath, output, audio_directory_table[i].count, i);
- printf("Done (%d bytes)\n", audio_directory_size[i]);
- }
+ printf("Processing directory 'audio'...\n");
+ audio_directory_size = compress_audio_directory(inpath, outpath, output);
+ printf("Done (%d bytes)\n", audio_directory_size);
}
/* fix sound types offsets/counts */
@@ -496,11 +392,9 @@
current_offset += sound_directory_size[i];
}
if (flags & HEADER_FLAG_AUDIO_INTRO) {
- for (i = 0; i < AUDIO_TYPES_COUNT; ++i) {
- writeUint32LE(output, current_offset);
- writeUint32LE(output, audio_directory_table[i].count);
- current_offset += audio_directory_size[i];
- }
+ writeUint32LE(output, current_offset);
+ writeUint32LE(output, ARRAYSIZE(audio_files_list));
+ current_offset += audio_directory_size;
}
fclose(output);
Modified: tools/branches/gsoc2009-gui/degob_script.cpp
===================================================================
--- tools/branches/gsoc2009-gui/degob_script.cpp 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/degob_script.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -867,6 +867,14 @@
} while (params.counter != params.cmdCount);
}
+void Script::addStartingOffsets() {
+ for (int i = 100; i < 128; i += 2) {
+ uint16 offset = READ_LE_UINT16(_totData + i);
+ if ((offset >= 128) && (offset != ((uint16) -1)))
+ addFuncOffset(offset);
+ }
+}
+
void Script::addFuncOffset(uint32 offset) {
for (std::list<uint32>::iterator it = _funcOffsets.begin(); it != _funcOffsets.end(); ++it)
if (*it == offset)
@@ -876,10 +884,11 @@
}
void Script::deGob(int32 offset) {
+ _funcOffsets.clear();
+
if (offset < 0)
- offset = _start;
-
- _funcOffsets.clear();
+ addStartingOffsets();
+ else
_funcOffsets.push_back(offset);
for (std::list<uint32>::iterator it = _funcOffsets.begin(); it != _funcOffsets.end(); ++it) {
Modified: tools/branches/gsoc2009-gui/degob_script.h
===================================================================
--- tools/branches/gsoc2009-gui/degob_script.h 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/degob_script.h 2009-07-04 13:29:16 UTC (rev 42089)
@@ -156,6 +156,8 @@
void funcBlock(int16 retFlag);
+ void addStartingOffsets();
+
void addFuncOffset(uint32 offset);
void deGobFunction();
Property changes on: tools/branches/gsoc2009-gui/degob_script_v6.cpp
___________________________________________________________________
Deleted: svn:mergeinfo
-
Modified: tools/branches/gsoc2009-gui/descumm6.cpp
===================================================================
--- tools/branches/gsoc2009-gui/descumm6.cpp 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/descumm6.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -1874,10 +1874,10 @@
"\x83|startFont,"
"\x84pp|setPosition,"
"\x85pppppppp|ellipse,"
- "\x86ppp|processMode12,"
+ "\x86ppp|fillWizFlood,"
"\x87p|setDstResNum,"
- "\x88ppppp|processMode10,"
- "\x89ppp|processMode11,"
+ "\x88ppppp|fillWizLine,"
+ "\x89ppp|fillWizPixel,"
"\x8Appppp|fillWizRect");
break;
case 0x38:
@@ -2253,7 +2253,7 @@
"\xFl|charsetColors,"
"\x80z|setCursorImg,"
"\x81z|setCursorImg,"
- "\x82zp|setCursorImg,"
+ "\x82zp|setCursorImgWithPal,"
"\x86|cursorOn,"
"\x87|cursorOff,"
"\x88|softCursorOn,"
@@ -2513,10 +2513,10 @@
break;
case 0xC8:
ext(output, "rx" "getPaletteData\0"
- "\xDpp|getColorCompontent2,"
+ "\xDpp|get16BitColorComponent,"
"\x14pp|getColor,"
- "\x21pppppp|,"
- "\x35ppp|getSimilarColor2,"
+ "\x21pppppp|getSimilarColor,"
+ "\x35ppp|get16BitColor,"
"\x49ppp|getColorCompontent");
break;
case 0xC9:
@@ -2782,7 +2782,7 @@
"\x87ppp|fillWizPixel,"
"\x88ppp|fillWizFlood,"
"\x89p|setDstResNum,"
- "\x8Bpp|setThinkLine,"
+ "\x8Bpp|setThickLine,"
"\x8D|startFont,"
"\x8Epppph|createFont,"
"\x8Fpph|renderFontString,"
@@ -3242,7 +3242,7 @@
ext(output, "x" "cursorCommand\0"
"\x13z|setCursorImg,"
"\x14z|setCursorImg,"
- "\x3Czp|setCursorImg,"
+ "\x3Czp|setCursorImgWithPal,"
"\x90|cursorOn,"
"\x91|cursorOff,"
"\x92|userPutOn,"
@@ -3386,11 +3386,11 @@
case 0x94:
if (g_options.heVersion >= 90) {
ext(output, "rx" "getPaletteData\0"
- "\x2Dpppppp|,"
+ "\x2Dpppppp|getSimilarColor,"
"\x34ppp|getColorCompontent,"
"\x42pp|getColor,"
- "\x84pp|getColorCompontent2,"
- "\xD9ppp|getSimilarColor2");
+ "\x84pp|get16BitColorComponent,"
+ "\xD9ppp|get16BitColor");
} else {
ext(output, "rpp|getVerbFromXY");
}
Modified: tools/branches/gsoc2009-gui/extract_gob_stk.cpp
===================================================================
--- tools/branches/gsoc2009-gui/extract_gob_stk.cpp 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/extract_gob_stk.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -55,7 +55,6 @@
File f1;
File f2;
- std::auto_ptr<Chunk> _chunk;
// We only got one input file
if (_inputPaths.size() > 1)
@@ -73,6 +72,8 @@
gobConf.open(_outputPath.getFullPath(), "w");
+ fprintf(gobConf, "%s\n", inpath.getFullName().c_str());
+
stk.read(signature, 1, 6);
if (strncmp(signature, "STK2.1", 6) == 0) {
@@ -260,35 +261,37 @@
outpath.setFullName(curChunk->name);
File chunkFile(outpath, "wb");
- chunkFile.seek(curChunk->offset, SEEK_SET);
+ if (curChunk->size > 0) {
+ chunkFile.seek(curChunk->offset, SEEK_SET);
- byte *data = new byte[curChunk->size];
+ byte *data = new byte[curChunk->size];
- stk.read((char *) data, curChunk->size, 1);
+ stk.read((char *) data, curChunk->size, 1);
- try {
- if (curChunk->packed) {
- uint32 realSize;
+ try {
+ if (curChunk->packed) {
+ uint32 realSize;
- if (curChunk->preGob) {
- unpackedData = unpackPreGobData(data, realSize, curChunk->size);
+ if (curChunk->preGob) {
+ unpackedData = unpackPreGobData(data, realSize, curChunk->size);
+ } else {
+ unpackedData = unpackData(data, realSize);
+ }
+
+ chunkFile.write((char *) unpackedData, realSize, 1);
+
+ delete[] unpackedData;
} else {
- unpackedData = unpackData(data, realSize);
+ chunkFile.write((char *) data, curChunk->size, 1);
}
-
- chunkFile.write((char *) unpackedData, realSize, 1);
-
+ } catch(...) {
+ delete[] data;
delete[] unpackedData;
- } else {
- chunkFile.write((char *) data, curChunk->size, 1);
+ throw;
}
- } catch(...) {
- delete[] data;
- delete[] unpackedData;
- throw;
}
- delete[] data;
+ fflush(chunkFile);
curChunk = curChunk->next;
}
@@ -346,7 +349,6 @@
tmpIndex++;
tmpIndex %= 4096;
}
-
}
}
Modified: tools/branches/gsoc2009-gui/extract_t7g_mac.cpp
===================================================================
--- tools/branches/gsoc2009-gui/extract_t7g_mac.cpp 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/extract_t7g_mac.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -1,10 +1,93 @@
+/* extract_t7g_mac - Extractor for the Mac version of The 7th Guest
+ * Copyright (C) 2008-2009 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+// Resource fork format taken from:
+// http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html
+
#include "util.h"
-#define NUM_FILES 45
+#define offsetResFork 128
+uint32 offsetResourceData;
+char *readString(FILE *ifp) {
+ byte len = readByte(ifp);
+ char *name = new char[len + 1];
+ fread(name, len, 1, ifp);
+ name[len] = 0;
+ return name;
+}
+
+void dumpResource(FILE *ifp, char *name) {
+ // Show the resource details
+ uint32 fileSize = readUint32BE(ifp);
+ printf(" \"%s\" (%d bytes)\n", name, fileSize);
+
+ // Read the resource contents
+ byte *buf = new byte[fileSize];
+ if (!buf) {
+ fclose(ifp);
+ error("Could not allocate %ld bytes of memory", fileSize);
+ }
+
+ // Dump the resource to the output file
+ FILE *ofp = fopen(name, "wb");
+ fread(buf, 1, fileSize, ifp);
+ fwrite(buf, 1, fileSize, ofp);
+ fclose(ofp);
+
+ // Free the resource memory
+ delete[] buf;
+}
+
+void handleReferenceList(FILE *ifp, uint32 offsetRefList, uint16 numRes, uint32 offsetResNames) {
+ for (int i = 0; i < numRes; i++) {
+ if (fseek(ifp, offsetRefList + 12 * i + 2, SEEK_SET)) {
+ fclose(ifp);
+ error("Seek error");
+ }
+ uint32 offsetResName = offsetResNames + readUint16BE(ifp);
+ uint32 offsetResData = offsetResourceData + (readUint32BE(ifp) & 0xFFFFFF);
+
+ // Read the resource name
+ if (fseek(ifp, offsetResName, SEEK_SET)) {
+ fclose(ifp);
+ error("Seek error");
+ }
+ char *name = readString(ifp);
+
+ // Dump the resource
+ if (fseek(ifp, offsetResData, SEEK_SET)) {
+ fclose(ifp);
+ error("Seek error");
+ }
+ dumpResource(ifp, name);
+
+ // Free the resource name
+ delete[] name;
+ }
+}
+
int main(int argc, char *argv[]) {
FILE *ifp;
- char *filenames[NUM_FILES];
if (argc != 2) {
displayHelp("Usage: %s <file>\n", argv[0]);
@@ -14,46 +97,59 @@
error("Could not open \'%s\'", argv[1]);
}
- // Load the file names
- printf("Getting the name of the files...\n");
- if (fseek(ifp, 0x1BEEA8, SEEK_SET)) {
+ // Read the resource fork header
+ if (fseek(ifp, offsetResFork, SEEK_SET)) {
fclose(ifp);
error("Seek error");
}
- for (int i = 0; i < NUM_FILES; i++) {
- uint8 len = readByte(ifp);
- char *name = new char[len + 1];
- fread(name, len, 1, ifp);
- name[len] = 0;
- filenames[i] = name;
+ offsetResourceData = offsetResFork + readUint32BE(ifp);
+ uint32 offsetResMap = offsetResFork + readUint32BE(ifp);
+
+ // Read the resource map
+ if (fseek(ifp, offsetResMap + 24, SEEK_SET)) {
+ fclose(ifp);
+ error("Seek error");
}
+ uint32 offsetResTypes = offsetResMap + readUint16BE(ifp);
+ uint32 offsetResNames = offsetResMap + readUint16BE(ifp);
- // Extract the data
- printf("Extracting the files...\n");
- if (fseek(ifp, 0x1777B2, SEEK_SET)) {
+ // Handle the resource types
+ if (fseek(ifp, offsetResTypes, SEEK_SET)) {
fclose(ifp);
error("Seek error");
}
- for (int i = 0; i < NUM_FILES; i++) {
- printf(" %s\n", filenames[i]);
- uint32 file_size = readUint32BE(ifp);
-
- byte *buf = new byte[file_size];
- if (!buf) {
+ uint16 numResTypes = readUint16BE(ifp) + 1;
+ char resType[5];
+ resType[4] = 0;
+ for (uint16 i = 0; i < numResTypes; i++) {
+ if (fseek(ifp, offsetResTypes + 2 + 8 * i, SEEK_SET)) {
fclose(ifp);
- error("Could not allocate %ld bytes of memory", file_size);
+ error("Seek error");
}
- FILE *ofp = fopen(filenames[i], "wb");
- fread(buf, 1, file_size, ifp);
- fwrite(buf, 1, file_size, ofp);
- fclose(ofp);
- delete[] buf;
- }
+ // Read the resource type name
+ fread(resType, 4, 1, ifp);
+ switch (READ_BE_UINT32(resType)) {
+ case MKID_BE('csnd'):
+ case MKID_BE('snd '):
+ case MKID_BE('Midi'):
+ case MKID_BE('cmid'):
+ //case MKID_BE('SMOD'):
+ case MKID_BE('SONG'):
+ case MKID_BE('INST'):
+ case MKID_BE('T7GM'):
+ {
+ printf("Extracting \"%s\" resources\n", resType);
+ uint16 numRes = readUint16BE(ifp);
+ uint32 offsetRefList = offsetResTypes + readUint16BE(ifp);
- // Free the allocated filenames
- for (int i = 0; i < NUM_FILES; i++) {
- delete[] filenames[i];
+ handleReferenceList(ifp, offsetRefList, numRes, offsetResNames);
+ break;
+ }
+ default:
+ printf("Skipping \"%s\" resources\n", resType);
+ break;
+ }
}
fclose(ifp);
Property changes on: tools/branches/gsoc2009-gui/extract_t7g_mac.cpp
___________________________________________________________________
Added: svn:keywords
+ Date Rev Author URL Id
Property changes on: tools/branches/gsoc2009-gui/sci
___________________________________________________________________
Deleted: svn:mergeinfo
-
Modified: tools/branches/gsoc2009-gui/util.cpp
===================================================================
--- tools/branches/gsoc2009-gui/util.cpp 2009-07-04 11:33:51 UTC (rev 42088)
+++ tools/branches/gsoc2009-gui/util.cpp 2009-07-04 13:29:16 UTC (rev 42089)
@@ -74,7 +74,7 @@
}
uint8 readByte(FILE *fp) {
- return fgetc(fp);
+ return (uint8)fgetc(fp);
}
uint16 readUint16BE(FILE *fp) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list