aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorTravis Howell2009-01-26 04:22:19 +0000
committerTravis Howell2009-01-26 04:22:19 +0000
commit53c71f8e4db7989b40da991ac6c631f6ca91a276 (patch)
tree7b3d2cac3dd542aa2cffb8799c3c6bf05d1ed3a8 /engines
parent4999677c579631cd54b4919a5766dcb8f2201366 (diff)
downloadscummvm-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
Diffstat (limited to 'engines')
-rw-r--r--engines/agos/agos.cpp10
-rw-r--r--engines/agos/agos.h13
-rw-r--r--engines/agos/detection_tables.h4
-rw-r--r--engines/agos/string.cpp166
4 files changed, 170 insertions, 23 deletions
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;