Fix DecodeLine2 + decode_datatxt.py
This commit is contained in:
parent
d78eca8ffa
commit
8a6fefaf46
|
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
|
|
|
|||
Loading…
Reference in New Issue