aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2019-10-31 22:10:41 -0700
committerPaul Gilbert2019-11-11 18:20:29 -0800
commitfdb5ead5ca91a92c11192e61d23beee90e4caacb (patch)
tree4bc6cf0c7400d3d0f41529fd63174e399f4970e6
parentd4cba56b418d04d6bca2ded3cabd3376aab5d3f3 (diff)
downloadscummvm-rg350-fdb5ead5ca91a92c11192e61d23beee90e4caacb.tar.gz
scummvm-rg350-fdb5ead5ca91a92c11192e61d23beee90e4caacb.tar.bz2
scummvm-rg350-fdb5ead5ca91a92c11192e61d23beee90e4caacb.zip
GLK: ARCHETYPE: Fixes for string decryption
-rw-r--r--engines/glk/archetype/crypt.cpp57
-rw-r--r--engines/glk/archetype/crypt.h5
-rw-r--r--engines/glk/archetype/misc.cpp13
3 files changed, 55 insertions, 20 deletions
diff --git a/engines/glk/archetype/crypt.cpp b/engines/glk/archetype/crypt.cpp
index d99dab0907..1b59163daf 100644
--- a/engines/glk/archetype/crypt.cpp
+++ b/engines/glk/archetype/crypt.cpp
@@ -28,10 +28,40 @@ namespace Archetype {
byte CryptMask;
EncryptionType Encryption;
+static uint RandSeed;
+const int RANDOM_KEY = 33797;
void crypt_init() {
Encryption = NONE;
CryptMask = 0x55;
+ RandSeed = 0;
+}
+
+static void setDecryptionSeed(uint new_seed) {
+ RandSeed = new_seed;
+}
+
+static void cycleRandomSeed() {
+ uint16 c = RandSeed & 0xffff;
+ uint val = (uint)c * RANDOM_KEY;
+ c <<= 3;
+ c = (c & 0xff) | ((((c >> 8) + c) & 0xff) << 8);
+ val += (uint)c << 16;
+
+ uint16 b = RandSeed >> 16;
+ val += (uint)b << 16;
+ b <<= 2;
+ val += (uint)b << 16;
+ val += (uint)(b & 0xff) << 24;
+ b <<= 5;
+ val += (uint)(b & 0xff) << 24;
+
+ RandSeed = val + 1;
+}
+
+static uint getDeterministicRandomNumber(uint limit) {
+ cycleRandomSeed();
+ return (limit == 0) ? 0 : (RandSeed >> 16) % limit;
}
void cryptinit(EncryptionType crypt_kind, uint seed) {
@@ -39,37 +69,38 @@ void cryptinit(EncryptionType crypt_kind, uint seed) {
Encryption = crypt_kind;
if (Encryption == COMPLEX)
- g_vm->setRandomNumberSeed(seed);
+ setDecryptionSeed(seed);
}
-void cryptstr(Common::String &s) {
+void cryptstr(char *buffer, size_t length) {
byte nextMask;
+ char *p = buffer;
switch (Encryption) {
case SIMPLE:
- for (uint i = 0; i < s.size(); ++i)
- s.setChar(s[i] ^ CryptMask, i);
+ for (size_t i = 0; i < length; ++i, ++p)
+ *p ^= CryptMask;
break;
case PURPLE:
- for (uint i = 0; i < s.size(); ++i) {
- s.setChar(s[i] ^ CryptMask, i);
- CryptMask += s[i] & 7;
+ for (size_t i = 0; i < length; ++i, ++p) {
+ *p ^= CryptMask;
+ CryptMask += *p & 7;
}
break;
case UNPURPLE:
- for (uint i = 0; i < s.size(); ++i) {
- nextMask = CryptMask + (s[i] & 7);
- s.setChar(s[i] ^ CryptMask, i);
+ for (size_t i = 0; i < length; ++i, ++p) {
+ nextMask = CryptMask + (*p & 7);
+ *p ^= CryptMask;
CryptMask = nextMask;
}
break;
case COMPLEX:
- for (uint i = 0; i < s.size(); ++i) {
- s.setChar(s[i] ^ CryptMask, i);
- CryptMask = g_vm->getRandomNumber(0x100);
+ for (size_t i = 0; i < length; ++i, ++p) {
+ *p ^= CryptMask;
+ CryptMask = (byte)getDeterministicRandomNumber(0x100);
}
break;
diff --git a/engines/glk/archetype/crypt.h b/engines/glk/archetype/crypt.h
index d978210e9a..d92fe39cf6 100644
--- a/engines/glk/archetype/crypt.h
+++ b/engines/glk/archetype/crypt.h
@@ -23,8 +23,7 @@
#ifndef ARCHETYPE_CRYPT
#define ARCHETYPE_CRYPT
-#include "common/scummsys.h"
-#include "common/str.h"
+#include "glk/archetype/string.h"
namespace Glk {
namespace Archetype {
@@ -56,7 +55,7 @@ extern void cryptinit(EncryptionType crypt_kind, uint seed);
* if <method> is COMPLEX, a pseudorandom sequence is used to alter the
* CryptMask.This can make prediction well-nigh impossible.
*/
-extern void cryptstr(Common::String &s);
+extern void cryptstr(char *buffer, size_t length);
} // End of namespace Archetype
} // End of namespace Glk
diff --git a/engines/glk/archetype/misc.cpp b/engines/glk/archetype/misc.cpp
index e5a858ba00..c10bba1b33 100644
--- a/engines/glk/archetype/misc.cpp
+++ b/engines/glk/archetype/misc.cpp
@@ -155,11 +155,13 @@ String formatFilename(const String &name, const String &ext, bool replace) {
void load_string(Common::ReadStream *fIn, String &the_string) {
char buffer[257];
size_t strSize = fIn->readByte();
+ (void)fIn->readByte(); // Redundant second copy of the length
+
fIn->read(buffer, strSize);
buffer[strSize] = '\0';
+ cryptstr(buffer, strSize);
the_string = String(buffer);
- cryptstr(the_string);
}
void dump_string(Common::WriteStream *fOut, const String &the_string) {
@@ -170,9 +172,12 @@ void dump_string(Common::WriteStream *fOut, const String &the_string) {
fOut->write(the_string.c_str(), the_string.size());
} else {
- String tmp = the_string;
- cryptstr(tmp);
- fOut->write(tmp.c_str(), tmp.size());
+ char buffer[257];
+ strncpy(buffer, the_string.c_str(), 256);
+ buffer[256] = '\0';
+
+ cryptstr(buffer, the_string.size());
+ fOut->write(buffer, the_string.size());
}
}