diff options
| author | Travis Howell | 2009-01-26 04:22:19 +0000 | 
|---|---|---|
| committer | Travis Howell | 2009-01-26 04:22:19 +0000 | 
| commit | 53c71f8e4db7989b40da991ac6c631f6ca91a276 (patch) | |
| tree | 7b3d2cac3dd542aa2cffb8799c3c6bf05d1ed3a8 | |
| parent | 4999677c579631cd54b4919a5766dcb8f2201366 (diff) | |
| download | scummvm-rg350-53c71f8e4db7989b40da991ac6c631f6ca91a276.tar.gz scummvm-rg350-53c71f8e4db7989b40da991ac6c631f6ca91a276.tar.bz2 scummvm-rg350-53c71f8e4db7989b40da991ac6c631f6ca91a276.zip | |
Add support for text compression in the AtariST version of Elvira 1.
svn-id: r36065
| -rw-r--r-- | README | 8 | ||||
| -rw-r--r-- | engines/agos/agos.cpp | 10 | ||||
| -rw-r--r-- | engines/agos/agos.h | 13 | ||||
| -rw-r--r-- | engines/agos/detection_tables.h | 4 | ||||
| -rw-r--r-- | engines/agos/string.cpp | 166 | 
5 files changed, 178 insertions, 23 deletions
| @@ -670,6 +670,14 @@ the section on reporting bugs.       Broken Sword 2:            - PlayStation 1 version isn't supported +     Elvira - Mistress of the Dark +          - No music in the AtariST version + +     Elvira II - The Jaws of Cerberus +          - No music in the AtariST version +          - No sound effects in the PC version +          - Palette issues in the AtariST version +       Inherit the Earth: Quest for the Orb            - Amiga versions aren't supported diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 0bbbfd0f4a..1c60d0a875 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -427,6 +427,16 @@ AGOSEngine::AGOSEngine(OSystem *syst)  	memset(_fcsData1, 0, sizeof(_fcsData1));  	memset(_fcsData2, 0, sizeof(_fcsData2)); +	_awaitTwoByteToken = 0; +	_byteTokens = 0; +	_byteTokenStrings = 0; +	_twoByteTokens = 0; +	_twoByteTokenStrings = 0; +	_secondTwoByteTokenStrings = 0; +	_thirdTwoByteTokenStrings = 0; +	memset(_textBuffer, 0, sizeof(_textBuffer)); +	_textCount = 0; +  	_freeStringSlot = 0;  	memset(_stringReturnBuffer, 0, sizeof(_stringReturnBuffer)); diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 18a7fbe679..4613977bc6 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -486,6 +486,16 @@ protected:  	TextLocation _textLocation1, _textLocation2, _textLocation3, _textLocation4; +	byte _awaitTwoByteToken; +	byte *_byteTokens; +	byte *_byteTokenStrings; +	byte *_twoByteTokens; +	byte *_twoByteTokenStrings; +	byte *_secondTwoByteTokenStrings; +	byte *_thirdTwoByteTokenStrings; +	byte _textBuffer[180]; +	int _textCount; +  	int _freeStringSlot;  	byte _stringReturnBuffer[2][180]; @@ -658,6 +668,9 @@ protected:  	Item *me();  	Item *actor(); +	void uncompressText(byte *ptr); +	byte *uncompressToken(byte a, byte *ptr); +  	void showMessageFormat(const char *s, ...);  	const byte *getStringPtrByID(uint16 stringId, bool upperCase = false);  	const byte *getLocalStringByID(uint16 stringId); diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h index 62ae5578ce..dddc8a7aa6 100644 --- a/engines/agos/detection_tables.h +++ b/engines/agos/detection_tables.h @@ -152,7 +152,7 @@ static const AGOSGameDescription gameDescriptions[] = {  		GF_OLD_BUNDLE | GF_CRUNCHED | GF_PLANAR  	}, -	// Elvira 1 - French Atari ST Floppy +	// Elvira 1 - English Atari ST Floppy alternative?  	{  		{  			"elvira1", @@ -164,7 +164,7 @@ static const AGOSGameDescription gameDescriptions[] = {  	{ "tbllist",		GAME_TBLFILE,	"5b6ff494bf7e24213758598ef4ac0a8b", 476},  	{ NULL, 0, NULL, 0}  			}, -			Common::FR_FRA, +			Common::EN_ANY,  			Common::kPlatformAtariST,  			Common::ADGF_NO_FLAGS  		}, diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp index d83a885d40..0ff004e1fe 100644 --- a/engines/agos/string.cpp +++ b/engines/agos/string.cpp @@ -32,21 +32,107 @@ using Common::File;  namespace AGOS { +void AGOSEngine::uncompressText(byte *ptr) { +	byte a; +	while (1) { +		if (_awaitTwoByteToken != 0) +			a = _awaitTwoByteToken; +		else +			a = *ptr++; +		if (a == 0) +			return; +		ptr = uncompressToken(a, ptr); +		if (ptr == 0) +			return; +	} +} + +byte *AGOSEngine::uncompressToken(byte a, byte *ptr) { +	byte *ptr1; +	byte *ptr2; +	byte b; +	int count1 = 0; + +	if (a == 0xFF || a == 0xFE || a == 0xFD) { +		if (a == 0xFF) +			ptr2 = _twoByteTokenStrings; +		if (a == 0xFE)  +			ptr2 = _secondTwoByteTokenStrings; +		if (a == 0xFD) +			ptr2 = _thirdTwoByteTokenStrings; +		_awaitTwoByteToken = a; +		b = a; +		a = *ptr++; +		if (a == 0)		/* Need to return such that next byte   */ +			return 0;	/* is used as two byte token		*/ + +		_awaitTwoByteToken = 0; +		ptr1 = _twoByteTokens; +		while (*ptr1 != a) { +			ptr1++; +			count1++; +			if (*ptr1 == 0)	{	/* If was not a two byte token  */ +				count1 = 0;	/* then was a byte token.	*/ +				ptr1 = _byteTokens; +				while (*ptr1 != a) { +					ptr1++; +					count1++; +				} +				ptr1 = _byteTokenStrings;		/* Find it */ +				while (count1--)	{			 +					while (*ptr1++); +				} +				ptr1 = uncompressToken(b, ptr1);	/* Try this one as a two byte token */ +				uncompressText(ptr1);			/* Uncompress rest of this token    */ +				return ptr; +			} +		} +		while (count1--) { +			while (*ptr2++); +		} +		uncompressText(ptr2); +	} else { +		ptr1 = _byteTokens; +		while (*ptr1 != a) { +			ptr1++; +			count1++; +			if (*ptr1 == 0) { +				_textBuffer[_textCount++] = a;	/* Not a byte token */ +				return ptr;			/* must be real character */ +			} +		} +		ptr1 = _byteTokenStrings; +		while (count1--)	{		/* Is a byte token so count */ +			while (*ptr1++);		/* to start of token */ +		} +		uncompressText(ptr1);			/* and do it */ +	} +	return ptr; +} +  const byte *AGOSEngine::getStringPtrByID(uint16 stringId, bool upperCase) {  	const byte *string_ptr;  	byte *dst;  	_freeStringSlot ^= 1; +	dst = _stringReturnBuffer[_freeStringSlot]; -	if (stringId < 0x8000) { -		string_ptr = _stringTabPtr[stringId]; +	if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformAtariST) { +		byte *ptr = _stringTabPtr[stringId]; +		_textCount = 0; +		_awaitTwoByteToken = 0; +		uncompressText(ptr); +		_textBuffer[_textCount] = 0; +		strcpy((char *)dst, (const char *)_textBuffer);  	} else { -		string_ptr = getLocalStringByID(stringId); +		if (stringId < 0x8000) { +			string_ptr = _stringTabPtr[stringId]; +		} else { +			string_ptr = getLocalStringByID(stringId); +		} +		strcpy((char *)dst, (const char *)string_ptr);  	} -	dst = _stringReturnBuffer[_freeStringSlot]; -	strcpy((char *)dst, (const char *)string_ptr); -  	if (upperCase && *dst) {  		if (islower(*dst))  			*dst = toupper(*dst); @@ -86,15 +172,53 @@ void AGOSEngine::allocateStringTable(int num) {  void AGOSEngine::setupStringTable(byte *mem, int num) {  	int i = 0; -	for (;;) { -		_stringTabPtr[i++] = mem; -		if (--num == 0) -			break; -		for (; *mem; mem++); -		mem++; -	} -	_stringTabPos = i; +	if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformAtariST) { +		int ct1; + +		_twoByteTokens = mem; +		while (*mem++) { +			i++; +		} +		_twoByteTokenStrings = mem; +		ct1 = i; +		while (*mem++) { +			while (*mem++); +			i--; +			if ((i == 0) && (ct1 != 0)) { +				_secondTwoByteTokenStrings = mem; +				i = ct1; +				ct1 = 0; +			} +			if (i == 0) +				_thirdTwoByteTokenStrings = mem; +		} +		_byteTokens = mem; +		while (*mem++); +		_byteTokenStrings = mem; +		while (*mem++) { +			while(*mem++); +		} +		i = 0; +l1:		_stringTabPtr[i++] = mem; +		num--; +		if (!num) { +			_stringTabPos = i; +			return; +		} +		while (*mem++); +		goto l1; +	} else { +		for (;;) { +			_stringTabPtr[i++] = mem; +			if (--num == 0) +				break; +			for (; *mem; mem++); +			mem++; +		} +	 +		_stringTabPos = i; +	}  }  void AGOSEngine::setupLocalStringTable(byte *mem, int num) { @@ -665,26 +789,26 @@ uint16 AGOSEngine_Waxworks::getBoxSize() {  } -uint16 AGOSEngine_Waxworks::checkFit(char *Ptr, int width, int lines) { +uint16 AGOSEngine_Waxworks::checkFit(char *ptr, int width, int lines) {  	int countw = 0;  	int countl = 0;  	char *x = NULL; -	while (*Ptr) { -		if (*Ptr == '\n') +	while (*ptr) { +		if (*ptr == '\n')  			return 1;  		if (countw == width) {  			countl++;  			countw = 0; -			Ptr = x; +			ptr = x;  		} -		if (*Ptr == ' ') { -			x = Ptr; +		if (*ptr == ' ') { +			x = ptr;  			x++;  		}  		countw++;  		if (countl == lines)  			return 0; -		Ptr++; +		ptr++;  	}  	return 1; | 
