aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Kagerer2009-11-28 18:40:37 +0000
committerFlorian Kagerer2009-11-28 18:40:37 +0000
commit5905b9e4795788e66a78fe4d8d58cb8ca677e481 (patch)
tree18f5b0c2ecf9c16c4243bc51e3ed2344a3f7a643
parent1c43f446c03d989bb53cc04786f93fd9e2cd8fca (diff)
downloadscummvm-rg350-5905b9e4795788e66a78fe4d8d58cb8ca677e481.tar.gz
scummvm-rg350-5905b9e4795788e66a78fe4d8d58cb8ca677e481.tar.bz2
scummvm-rg350-5905b9e4795788e66a78fe4d8d58cb8ca677e481.zip
LOL: completed support for floppy installer files
svn-id: r46174
-rw-r--r--engines/kyra/resource_intern.cpp203
-rw-r--r--engines/kyra/sequences_lol.cpp10
-rw-r--r--engines/kyra/sound_midi.cpp2
3 files changed, 205 insertions, 10 deletions
diff --git a/engines/kyra/resource_intern.cpp b/engines/kyra/resource_intern.cpp
index 639dc96800..9bbeaf8c66 100644
--- a/engines/kyra/resource_intern.cpp
+++ b/engines/kyra/resource_intern.cpp
@@ -871,6 +871,20 @@ struct InsArchive {
} // end of anonymouse namespace
+class CmpVocDecoder {
+public:
+ CmpVocDecoder();
+ ~CmpVocDecoder();
+ uint8 *process(uint8 *src, uint32 insize, uint32 *outsize, bool disposeInput = true);
+
+private:
+ void decodeHelper(int p);
+
+ int32 *_vtbl;
+ int32 *_tbl1, *_p1, *_tbl2, *_p2, *_tbl3, *_p3, *_tbl4, *_p4, *_floatArray, *_stTbl;
+ uint8 *_sndArray;
+};
+
Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &filename, const Common::String &extension, const uint8 containerOffset) {
uint32 pos = 0;
uint32 bytesleft = 0;
@@ -945,6 +959,7 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
}
FileExpander exp;
+ CmpVocDecoder cvdec;
CachedArchive::InputEntry newEntry;
uint32 insize = 0;
uint32 outsize = 0;
@@ -998,9 +1013,22 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
delete[] inbuffer;
inbuffer = 0;
+
newEntry.data = outbuffer;
newEntry.size = outsize;
newEntry.name = entryStr;
+
+ entryStr.toUppercase();
+ if (entryStr.hasSuffix(".CMP")) {
+ entryStr.deleteLastChar();
+ entryStr.deleteLastChar();
+ entryStr.deleteLastChar();
+ entryStr += "PAK";
+ newEntry.data = cvdec.process(outbuffer, outsize, &outsize);
+ newEntry.size = outsize;
+ newEntry.name = entryStr;
+ }
+
fileList.push_back(newEntry);
}
pos++;
@@ -1078,6 +1106,18 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
newEntry.data = outbuffer;
newEntry.size = outsize;
newEntry.name = entryStr;
+
+ entryStr.toUppercase();
+ if (entryStr.hasSuffix(".CMP")) {
+ entryStr.deleteLastChar();
+ entryStr.deleteLastChar();
+ entryStr.deleteLastChar();
+ entryStr += "PAK";
+ newEntry.data = cvdec.process(outbuffer, outsize, &outsize);
+ newEntry.size = outsize;
+ newEntry.name = entryStr;
+ }
+
fileList.push_back(newEntry);
}
@@ -1100,4 +1140,167 @@ Common::Archive *InstallerLoader::load(Resource *owner, const Common::String &fi
return new CachedArchive(fileList);
}
+CmpVocDecoder::CmpVocDecoder() {
+
+ _tbl1 = new int32[4000];
+ _p1 = _tbl1 + 2000;
+ _tbl2 = new int32[4000];
+ _p2 = _tbl2 + 2000;
+ _tbl3 = new int32[4000];
+ _p3 = _tbl3 + 2000;
+ _tbl4 = new int32[4000];
+ _p4 = _tbl4 + 2000;
+
+ _vtbl = new int32[8193];
+ _floatArray = new int32[8193];
+ _sndArray = new uint8[8192];
+ _stTbl = new int32[256];
+
+ assert(_tbl1);
+ assert(_tbl2);
+ assert(_tbl3);
+ assert(_tbl4);
+ assert(_vtbl);
+ assert(_floatArray);
+ assert(_sndArray);
+ assert(_stTbl);
+
+ for (int32 i = -2000; i < 2000; i++) {
+ int32 x = i + 2000;
+ _tbl1[x] = (int32)(0.4829629131445341 * (double)i * 256.0);
+ _tbl2[x] = (int32)(0.8365163037378079 * (double)i * 256.0);
+ _tbl3[x] = (int32)(0.2241438680420134 * (double)i * 256.0);
+ _tbl4[x] = (int32)(-0.1294095225512604 * (double)i * 256.0);
+ }
+}
+
+CmpVocDecoder::~CmpVocDecoder() {
+ delete[] _stTbl;
+ delete[] _sndArray;
+ delete[] _floatArray;
+ delete[] _vtbl;
+ delete[] _tbl1;
+ delete[] _tbl2;
+ delete[] _tbl3;
+ delete[] _tbl4;
+}
+
+uint8 *CmpVocDecoder::process(uint8 *src, uint32 insize, uint32 *outsize, bool disposeInput) {
+ *outsize = 0;
+ uint8 *outTemp = new uint8[insize];
+
+ uint8 *inPosH = src;
+ uint8 *outPosH = outTemp;
+ uint8 *outPosD = outTemp + READ_LE_UINT32(src);
+ uint8 *end = outPosD;
+
+ while (outPosH < end) {
+ uint8 *spos = inPosH;
+ uint32 offset = READ_LE_UINT32(inPosH);
+ inPosH += 4;
+ char *name = (char *)inPosH;
+ inPosH += strlen(name) + 1;
+
+ if (!name[0]) {
+ *outsize = outPosD - outTemp;
+ WRITE_LE_UINT32(outPosH, *outsize);
+ memset(outPosH + 4, 0, 5);
+ break;
+ }
+
+ uint32 fileSize = READ_LE_UINT32(inPosH) - offset;
+ int headerEntryLen = inPosH - spos;
+
+ if (scumm_stricmp(name + strlen(name) - 4, ".voc")) {
+ memcpy(outPosH, spos, headerEntryLen);
+ WRITE_LE_UINT32(outPosH, outPosD - outTemp);
+ outPosH += headerEntryLen;
+ memcpy(outPosD, src + offset, fileSize);
+ outPosD += fileSize;
+ continue;
+ }
+
+ uint8 *vocPtr = src + offset;
+ uint32 vocLen = (vocPtr[27] | (vocPtr[28] << 8) | (vocPtr[29] << 16)) - 2;
+
+ uint8 *vocOutEnd = outPosD + vocLen + 32;
+ uint8 *vocInEnd = src + offset + fileSize;
+ memcpy(outPosD, vocPtr, 32);
+ uint8 *dst = outPosD + 32;
+ vocPtr += 32;
+ float t = 0.0f;
+
+ while (dst < vocOutEnd) {
+ memcpy(&t, vocPtr, 4);
+ vocPtr += 4;
+ uint32 readSize = MIN(8192, vocInEnd - vocPtr);
+ memcpy(_sndArray, vocPtr, readSize);
+ vocPtr += readSize;
+
+ for (int i = -128; i < 128; i++)
+ _stTbl[i + 128] = (int32)((float)i / t + 0.5f);
+
+ int8 *ps = (int8*)_sndArray;
+ for (int i = 0; i < 8192; i++)
+ _floatArray[i + 1] = _stTbl[128 + *ps++];
+
+ for (int i = 4; i <= 8192; i <<= 1)
+ decodeHelper(i);
+
+ for (int i = 1; i <= 8192; i++) {
+ int32 v = CLIP(_floatArray[i] + 128, 0, 255);
+ _sndArray[i - 1] = v;
+ }
+
+ uint16 numBytesOut = MIN(vocOutEnd - dst, 8192);
+ memcpy(dst, _sndArray, numBytesOut);
+ dst += numBytesOut;
+ }
+
+ *dst++ = 0;
+ memcpy(outPosH, spos, headerEntryLen);
+ WRITE_LE_UINT32(outPosH, outPosD - outTemp);
+ outPosH += headerEntryLen;
+ outPosD += (vocLen + 33);
+ }
+
+ if (disposeInput)
+ delete[] src;
+
+ uint8 *outFinal = new uint8[*outsize];
+ memcpy(outFinal, outTemp, *outsize);
+ delete[] outTemp;
+
+ return outFinal;
+}
+
+void CmpVocDecoder::decodeHelper(int p1) {
+ int p2 = p1 >> 1;
+ int p3 = p2 + 1;
+
+ int16 fi1 = _floatArray[1];
+ int16 fi2 = _floatArray[p2];
+ int16 fi3 = _floatArray[p3];
+ int16 fi4 = _floatArray[p1];
+
+ _vtbl[1] = (*(_p3 + fi2) + *(_p2 + fi4) + *(_p1 + fi1) + *(_p4 + fi3)) >> 8;
+ _vtbl[2] = (*(_p4 + fi2) - *(_p1 + fi4) + *(_p2 + fi1) - *(_p3 + fi3)) >> 8;
+
+ int d = 3;
+ int s = 1;
+
+ while (s < p2) {
+ fi2 = _floatArray[s];
+ fi1 = _floatArray[s + 1];
+ fi4 = _floatArray[s + p2];
+ fi3 = _floatArray[s + p3];
+
+ _vtbl[d++] = (*(_p3 + fi2) + *(_p2 + fi4) + *(_p1 + fi1) + *(_p4 + fi3)) >> 8;
+ _vtbl[d++] = (*(_p4 + fi2) - *(_p1 + fi4) + *(_p2 + fi1) - *(_p3 + fi3)) >> 8;
+ s++;
+ }
+
+ memcpy(&_floatArray[1], &_vtbl[1], p1 * sizeof(int32));
+}
+
} // End of namespace Kyra
diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp
index 3521d30b3e..50e0982f81 100644
--- a/engines/kyra/sequences_lol.cpp
+++ b/engines/kyra/sequences_lol.cpp
@@ -127,16 +127,10 @@ void LoLEngine::setupPrologueData(bool load) {
"HISTORY.PAK", 0
};
- static const char * const fileListFloppyExtracted[] = {
- "INTRO.PAK", "INTROVOC.PAK", 0
- };
-
static const char * const fileListFloppy[] = {
- "INTRO.PAK", "INTROVOC.CMP", 0
+ "INTRO.PAK", "INTROVOC.PAK", 0
};
-
- const char * const *fileList = _flags.isTalkie ? fileListCD :
- (_flags.useInstallerPackage ? fileListFloppy : fileListFloppyExtracted);
+ const char * const *fileList = _flags.isTalkie ? fileListCD : fileListFloppy;
char filename[32];
for (uint i = 0; fileList[i]; ++i) {
diff --git a/engines/kyra/sound_midi.cpp b/engines/kyra/sound_midi.cpp
index 0c4affd162..c7b5958653 100644
--- a/engines/kyra/sound_midi.cpp
+++ b/engines/kyra/sound_midi.cpp
@@ -543,8 +543,6 @@ bool SoundMidiPC::init() {
} else {
if (_vm->gameFlags().isTalkie)
pakFile = "ENG/STARTUP.PAK";
- else if (_vm->gameFlags().useInstallerPackage)
- pakFile = "INTROVOC.CMP";
else
pakFile = "INTROVOC.PAK";
}