Note: I called this method of encoding/compression Dizio-Encoding because it's a sort of text substitution based on a fixed dictionary table. Isn't really a compressor because the efficiency is minimal (at best from 1 char we obtain 2 chars), but is good to obfuscate text. This method is also used in other Westwood games (and the table is always the same) like Kyrandia2.

We have two alphabetic tables (can be found into main .exe file of the game), the MainTable of 16 chars, and a SubTable that is an array of 16 strings made of 8 chars each.

To decode the text, we take a byte at time in the original string.
If bit 7 is set, we must decode the char to obtain two chars, else if the byte value is < 32 the next byte is an "high" char (usually international letters like accent chars and similar) else we have a normal char.
The spec for the encoded char is the following:

Bits 6,5,4,3 (4bit) are the first index, while 2,1,0 (3bit) are second index.
Now, FirstIndex index the char in the MainTable and give the first char, SecondIndex index the char in the string of the SubTable, but the string is indexed by the FirstIndex.
Example:
Original String (hex value): 52 6F CA A9 21 52, bit 7 is not set, so we have a letter, in this case R 6F, bit 7 is not set, so we have a letter, in this case o CA, bit 7 is set, so we must decode:
CA in binary is 11001010, so the FirstIndex is 1001=9 and SecondIndex is 010=2.
From MainTable we get the first char that is l From SubTable we get the string index by FirstIndex that is " laeiyod", then we get the second char using the SecondIndex value and we get a.
So, from the byte CA we get the chars la. A9, bit 7 is set, so we must decode: FirstIndex is 0101=5 and SecondIndex is 001=1, so the first char is n and the second char is d (getting from " dtgesio"), the two chars are "nd" 21, bit 7 is not set, so we have a letter, in this case !

At end of the decoding process we obtain the final string: Roland!

When there is an "high char" to decode (byte value < 32), we have the possibility:
- byte value is 27, so the next byte is the "high char" and we must add 127 to get the real value.
- byte value is 13, we have a "carriage return" (\r) value
- other values are unknown to me

Decompression routine (in Pascal):

const
MainTable =' etainosrlhcdupm';
SubTable:array[0..15]ofstring[8]=('tasio wb',' rnsdalm','h ieoras','nrtlc sy','nstcloer',' dtgesio','nr ufmsw',' tep.ica','e oiadur',' laeiyod','eia otru','etoakhlr',' eiu,.oa','nsrctlai','leoiratp','eaoip bm');var i:Integer;
c, c1, c2:byte;
ch1, ch2:char;begin
Result :='';//result is a string variable - default return value of a function
i :=1;while(i <=length(s))dobegin
c :=byte(s[i]);if(c and$80) > 0then//bit 7 setbegin
c1 :=((c shr3)and$0F);//c1 = bit 6,5,4,3
ch1 := MainTable[c1 +1];//c1+1 because pascal string start from 1 not 0
c2 :=(c and$07);//c2 = bit 2,1,0
ch2 := SubTable[c1][c2 +1];//c2+1 because pascal string start from 1 not 0
Result := Result + ch1 + ch2;endelseif(c < 32)thenbeginif(c =27)thenbegininc(i);
c1 :=byte(s[i]);
ch1 :=char(127+ c1);
Result := Result + ch1;endelseif(c =13)then Result := Result +'\r'else Result := Result +'§';//unknown valueendelse Result := Result + s[i];inc(i);end;//whileend;

Here's the complete Decoding/Encoding routine in Pascal:

Dizio-Encodingbecause it's a sort of text substitution based on a fixed dictionary table. Isn't really a compressor because the efficiency is minimal (at best from 1 char we obtain 2 chars), but is good to obfuscate text. This method is also used in other Westwood games (and the table is always the same) like Kyrandia2.We have two alphabetic tables (can be found into main .exe file of the game), the

MainTableof 16 chars, and aSubTablethat is an array of 16 strings made of 8 chars each.MainTable = " etainosrlhcdupm"

SubTable = (

"tasio wb",

" rnsdalm",

"h ieoras",

"nrtlc sy",

"nstcloer",

" dtgesio",

"nr ufmsw",

" tep.ica",

"e oiadur",

" laeiyod",

"eia otru",

"etoakhlr",

" eiu,.oa",

"nsrctlai",

"leoiratp",

"eaoip bm"

)

To decode the text, we take a byte at time in the original string.

If bit 7 is set, we must decode the char to obtain two chars, else if the byte value is < 32 the next byte is an "high" char (usually international letters like accent chars and similar) else we have a normal char.

The spec for the encoded char is the following:

Bits 6,5,4,3 (4bit) are the first index, while 2,1,0 (3bit) are second index.

Now,

FirstIndexindex the char in theMainTableand give the first char,SecondIndexindex the char in the string of theSubTable, but the string is indexed by theFirstIndex.Example:

Original String (hex value):

52 6F CA A9 2152, bit 7 is not set, so we have a letter, in this caseR6F, bit 7 is not set, so we have a letter, in this caseoCA, bit 7 is set, so we must decode:CA in binary is 11001010, so the

FirstIndexis 1001=9 andSecondIndexis 010=2.From

MainTablewe get the first char that islFromSubTablewe get the string index byFirstIndexthat is "laeiyod", then we get the second char using theSecondIndexvalue and we geta.So, from the byte

CAwe get the charsla.A9, bit 7 is set, so we must decode:FirstIndexis 0101=5 andSecondIndexis 001=1, so the first char isnand the second char isd(getting from "dtgesio"), the two chars are "nd"21, bit 7 is not set, so we have a letter, in this case!At end of the decoding process we obtain the final string:

Roland!When there is an "high char" to decode (byte value < 32), we have the possibility:

- byte value is 27, so the next byte is the "high char" and we must add 127 to get the real value.

- byte value is 13, we have a "carriage return" (\r) value

- other values are unknown to me

Decompression routine (in Pascal):

Here's the complete Decoding/Encoding routine in Pascal: