From 53c71f8e4db7989b40da991ac6c631f6ca91a276 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Mon, 26 Jan 2009 04:22:19 +0000 Subject: Add support for text compression in the AtariST version of Elvira 1. svn-id: r36065 --- engines/agos/agos.cpp | 10 +++ engines/agos/agos.h | 13 ++++ engines/agos/detection_tables.h | 4 +- engines/agos/string.cpp | 166 +++++++++++++++++++++++++++++++++++----- 4 files changed, 170 insertions(+), 23 deletions(-) (limited to 'engines') 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; -- cgit v1.2.3