diff options
author | Robert Göffringmann | 2004-11-15 02:48:30 +0000 |
---|---|---|
committer | Robert Göffringmann | 2004-11-15 02:48:30 +0000 |
commit | 183a11153e680a1b6cd399da09deff7a690304dc (patch) | |
tree | e92ebc67ceedab484b02215b3c9761d88288bd29 | |
parent | 0b3949389e9f7a48023894174d5e8e19286c199a (diff) | |
download | scummvm-rg350-183a11153e680a1b6cd399da09deff7a690304dc.tar.gz scummvm-rg350-183a11153e680a1b6cd399da09deff7a690304dc.tar.bz2 scummvm-rg350-183a11153e680a1b6cd399da09deff7a690304dc.zip |
BS1 demo's speech and logic work now.
But there's something wrong with the SFX, which can lead to crashes.
svn-id: r15813
-rw-r--r-- | sword1/logic.cpp | 19 | ||||
-rw-r--r-- | sword1/sound.cpp | 53 | ||||
-rw-r--r-- | sword1/sword1.cpp | 5 | ||||
-rw-r--r-- | sword1/sword1.h | 1 |
4 files changed, 47 insertions, 31 deletions
diff --git a/sword1/logic.cpp b/sword1/logic.cpp index 1d7e85093c..8c4095b215 100644 --- a/sword1/logic.cpp +++ b/sword1/logic.cpp @@ -474,6 +474,7 @@ int Logic::interpretScript(Object *compact, int id, Header *scriptModule, int sc int32 a, b, c, d, e, f; int mCodeReturn = 0; int32 mCodeNumber = 0, mCodeArguments = 0; + uint32 varNum = 0; while (1) { assert((stackIdx >= 0) && (stackIdx <= MAX_STACK_SIZE)); switch (scriptCode[pc++]) { @@ -504,7 +505,14 @@ int Logic::interpretScript(Object *compact, int id, Header *scriptModule, int sc break; case IT_PUSHVARIABLE: debug(9, "IT_PUSHVARIABLE: ScriptVar[%d] => %d", scriptCode[pc], _scriptVars[scriptCode[pc]]); - stack[stackIdx++] = _scriptVars[scriptCode[pc++]]; + varNum = scriptCode[pc++]; + if (SwordEngine::_systemVars.isDemo) { + if (varNum >= 397) // BS1 Demo has different number of script variables + varNum++; + if (varNum >= 699) + varNum++; + } + stack[stackIdx++] = _scriptVars[varNum]; break; case IT_NOTEQUAL: stackIdx--; @@ -588,7 +596,14 @@ int Logic::interpretScript(Object *compact, int id, Header *scriptModule, int sc return 0; case IT_POPVAR: // pop a variable debug(9, "IT_POPVAR: ScriptVars[%d] = %d", scriptCode[pc], stack[stackIdx-1]); - _scriptVars[scriptCode[pc++]] = stack[--stackIdx]; + varNum = scriptCode[pc++]; + if (SwordEngine::_systemVars.isDemo) { + if (varNum >= 397) // BS1 Demo has different number of script variables + varNum++; + if (varNum >= 699) + varNum++; + } + _scriptVars[varNum] = stack[--stackIdx]; break; case IT_POPLONGOFFSET: offset = scriptCode[pc++]; diff --git a/sword1/sound.cpp b/sword1/sound.cpp index 550d8dd54b..fde2a402cc 100644 --- a/sword1/sound.cpp +++ b/sword1/sound.cpp @@ -218,36 +218,28 @@ int16 *Sound::uncompressSpeech(uint32 index, uint32 cSize, uint32 *size) { headerPos++; if (headerPos < 100) { int32 resSize; - if (_cowMode == CowDemo) { // Demo uses slightly different headers - resSize = READ_LE_UINT32(fBuf + headerPos + 6) >> 1; - headerPos += 2; - } else - resSize = READ_LE_UINT32(fBuf + headerPos + 4) >> 1; - int16 *srcData = (int16*)(fBuf + headerPos + 8); - uint32 srcPos = 0; - uint32 dstPos = 0; - cSize = (cSize - (headerPos + 8)) / 2; - if (_cowMode == CowDemo) { - // FIXME: Until someone figures out how to really - // calculate the uncompressed buffer size, use - // brute force to avoid crashes. - debug(1, "old resSize = %d", resSize); - resSize = 0; - while (srcPos < cSize) { - int16 length = (int16)READ_LE_UINT16(srcData + srcPos); - srcPos++; - if (length < 0) { - length = -length; - srcPos++; - } else { - srcPos += length; - } - resSize += length; - } - debug(1, "new resSize = %d", resSize); + headerPos += 4; // skip 'data' tag + if (_cowMode != CowDemo) { + resSize = READ_LE_UINT32(fBuf + headerPos) >> 1; + headerPos += 4; + } else { + // the demo speech files have the uncompressed size embedded + // in the compressed stream *sigh* + if (READ_LE_UINT16(fBuf + headerPos) == 1) { + resSize = READ_LE_UINT16(fBuf + headerPos + 2); + resSize |= READ_LE_UINT16(fBuf + headerPos + 6) << 16; + resSize >>= 1; + } else + resSize = READ_LE_UINT32(fBuf + headerPos + 2) >> 1; } - int16 *dstData = (int16*)malloc(resSize * 2); - srcPos = 0; + assert(!(headerPos & 1)); + int16 *srcData = (int16*)fBuf; + uint32 srcPos = headerPos >> 1; + cSize /= 2; + uint32 dstPos = 0; + /* alloc 200 additional bytes, as the demo sometimes has ASCII junk + at the end of the wave data */ + int16 *dstData = (int16*)malloc(resSize * 2 + 200); while (srcPos < cSize) { int16 length = (int16)READ_LE_UINT16(srcData + srcPos); srcPos++; @@ -262,6 +254,9 @@ int16 *Sound::uncompressSpeech(uint32 index, uint32 cSize, uint32 *size) { srcPos += length; } } + assert(dstPos < (uint32)resSize + 100); + if (_cowMode == CowDemo) // demo has wave output size embedded in the compressed data + *(uint32*)dstData = 0; free(fBuf); *size = resSize * 2; calcWaveVolume(dstData, resSize); diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index 82aa029f85..f9cbb2115d 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -1095,6 +1095,7 @@ void SwordEngine::checkCdFiles(void) { // check if we're running from cd, hdd or File test; _systemVars.playSpeech = true; + _systemVars.isDemo = false; for (int i = 1; i <= 2; i++) { for (int j = 0; j < ARRAYSIZE(speechFiles); j++) { @@ -1113,6 +1114,10 @@ void SwordEngine::checkCdFiles(void) { // check if we're running from cd, hdd or _systemVars.runningFromCd = false; _systemVars.playSpeech = true; } else { // speech1 & speech2 not present. are we running from cd? + if (test.open("cows.mad")) { + _systemVars.isDemo = true; + test.close(); + } if (test.open("cd1.id")) { _systemVars.runningFromCd = true; _systemVars.currentCD = 1; diff --git a/sword1/sword1.h b/sword1/sword1.h index 22a51960d5..330d47a38c 100644 --- a/sword1/sword1.h +++ b/sword1/sword1.h @@ -63,6 +63,7 @@ struct SystemVars { uint8 playSpeech; uint8 showText; uint8 language; + bool isDemo; }; class SwordEngine : public Engine { |