Fix DecodeLine2 + decode_datatxt.py

This commit is contained in:
Anonymous Maarten 2022-11-08 20:13:42 +01:00
parent d78eca8ffa
commit 8a6fefaf46
3 changed files with 99 additions and 45 deletions

View File

@ -26,16 +26,16 @@
#define MIN_SERVICE_INTERVAL 200
// <<
int gIn_check_quit;
tU32 gLost_time;
int gIn_check_quit = 0;
tU32 gLost_time = 0;
#if BR_ENDIAN_BIG
tU32 gLong_key[4] = { 0x6C1B995F, 0xB9CD5F13, 0xCB04200E, 0x5E1CA10E };
tU32 gOther_long_key[4] = { 0x67A8D626, 0xB6DD451B, 0x327E2213, 0x15C29437};
tU32 gLong_key[4] = { 0x6c1b995f, 0xb9cd5f13, 0xcb04200e, 0x5e1ca10e };
tU32 gOther_long_key[4] = { 0x67a8d626, 0xb6dd451b, 0x327e2213, 0x15c29437};
#else
tU32 gLong_key[4] = { 0x5F991B6C, 0x135FCDB9, 0x0E2004CB, 0x0EA11C5E };
tU32 gOther_long_key[4] = { 0x26D6A867, 0x1B45DDB6, 0x13227E32, 0x3794C215 };
tU32 gLong_key[4] = { 0x5f991b6c, 0x135fcdb9, 0x0e2004cb, 0x0ea11c5e };
tU32 gOther_long_key[4] = { 0x26d6a867, 0x1b45ddb6, 0x13227e32, 0x3794c215 };
#endif
int gEncryption_method;
int gEncryption_method = 0;
char* gMisc_strings[250];
br_pixelmap* g16bit_palette;
br_pixelmap* gSource_for_16bit_palette;
@ -1168,31 +1168,34 @@ void DecodeLine2(char* pS) {
}
if (gEncryption_method == 1) {
if (c == '\t') {
c = 0x80;
c = 0x9f;
}
c -= 0x20;
if (!(c & 0x80)) {
c = (c ^ key[seed]) & 0x7f;
c += 0x20;
}
seed += 7;
seed = seed % 16;
if (c == 0x80) {
c -= 0x20;
c ^= key[seed];
c &= 0x7f;
c += 0x20;
seed += 7;
seed %= 16;
if (c == 0x9f) {
c = '\t';
}
} else {
if (c == '\t') {
c = 0x9f;
c = 0x80;
}
c -= 0x20;
c = (c ^ key[seed]) & 0x7f;
if ((c & 0x80) == 0) {
c ^= key[seed] & 0x7f;
}
c += 0x20;
seed += 7;
seed = seed % 16;
seed %= 16;
if (c == 0x9f) {
if (c == 0x80) {
c = '\t';
}
}

View File

@ -18,7 +18,7 @@ void test_utility_EncodeLinex() {
void test_utility_DecodeLine2() {
char buf[50];
gEncryption_method = 1;
gEncryption_method = 2;
// first line of GENERAL.TXT, "@" prefix and line ending stripped
char input[] = "\x29\x2a\x9c\x22\x61\x4d\x5e\x5f\x60\x34\x64\x57\x8d\x2b\x82\x7b\x33\x4c";
strcpy(buf, input);

View File

@ -13,43 +13,94 @@ OTHER_LONG_KEY = (
)
class Byte:
def __init__(self, v: int):
self.v = v & 0xff
def __add__(self, v: int):
return Byte(self.v + v)
def __iadd__(self, v: "Byte"):
self.v = (self.v + v) & 0xff
return self
def __sub__(self, v: int):
return Byte(self.v - v)
def __isub__(self, v: "Byte"):
self.v = (self.v - v) & 0xff
return self
def __mod__(self, v: int):
return Byte(self.v % v)
def __imod__(self, v: int):
self.v %= v
return self
def __xor__(self, v: int):
return Byte(self.v ^ v)
def __ixor__(self, v: int):
self.v = (self.v ^ v) & 0xff
return self
def __and__(self, v: int):
return Byte(self.v & v)
def __iand__(self, v: int):
self.v = (self.v & v) & 0xff
return self
def __eq__(self, other):
if isinstance(other, Byte):
return self.v == other.v
elif isinstance(other, int):
return self.v == (other & 0xff)
raise ValueError(f"Object {other:r} of invalid type {type(other)}")
def decode_line(line: bytes, method: int) -> str:
line = line.rstrip(b"\r\n")
key = LONG_KEY
seed = len(line) % 16
seed = len(line) % len(LONG_KEY)
dline = bytearray(len(line))
for i, c in enumerate(line):
if i >= 2:
if line[i - 1] == b'/' and line[i - 2] == b'/':
key = OTHER_LONG_KEY
b = Byte(c)
if dline[i - 2:i] == b'//':
key = OTHER_LONG_KEY
if method == 1:
if c == ord(b'\t'):
c = 0x80
c -= 0x20
if not (c & 0x80):
c ^= key[seed]
c &= 0x7f
c += 0x20
if b == ord(b'\t'):
b = Byte(0x9f)
b -= 0x20
b ^= key[seed]
b &= 0x7f
b += 0x20
seed += 7
seed %= 16
if c == 0x80:
c = ord(b'\t')
seed %= len(key)
if b == 0x9f:
b = Byte(ord(b'\t'))
else:
if c == ord(b'\t'):
c = 0x9f
c -= 0x20
c ^= key[seed]
c &= 0x7f
c += 0x20
if b == ord(b'\t'):
b = Byte(0x80)
b -= 0x20
if (b & 0x80) == 0:
b ^= key[seed] & 0x7f
b += 0x20
seed += 7
seed %= 16
if c == 0x9f:
c = ord(b'\t')
dline[i] = c
seed %= len(key)
if b == 0x80:
b = Byte(ord(b'\t'))
dline[i] = b.v
return dline.decode(errors="replace")
def main():
parser = argparse.ArgumentParser(allow_abbrev=False, description="Decode a Carmageddon encoded file")
parser.add_argument("file", metavar="FILE", nargs="?", help="input file (default=stdin)")