diff options
| -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 { | 
