diff --git a/Dockerfile b/Dockerfile index 38543404..03eea6c6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,4 +19,6 @@ COPY tools/RK211.COM . COPY tools/RUSSIAN.RK . COPY tools/8X16.RK . +COPY tools/DEBUG.EXE . + ENTRYPOINT ["python3", "-m", "unittest", "-v"] diff --git a/docker-compose.yml b/docker-compose.yml index eb77d152..ad2fee19 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,10 +9,11 @@ services: test: build: . pull_policy: build + ipc: host # FIXME environment: - DISPLAY volumes: - - "/tmp/.X11-unix:/tmp/.X11-unix" - - "/dev/snd:/dev/snd" + - /tmp/.X11-unix:/tmp/.X11-unix + - /dev/snd:/dev/snd depends_on: - testbox diff --git a/patches/bad-references.json b/patches/bad-references.json index c9f14b16..3303d9d0 100644 --- a/patches/bad-references.json +++ b/patches/bad-references.json @@ -14,6 +14,13 @@ 38281 ] }, + { + "source": "GAME.EXE", + "offset": 198944, + "bad-references": [ + 212818 + ] + }, { "source": "U.EXE", "offset": 92153, diff --git a/screenshots/U/create.png b/screenshots/U/create.png new file mode 100644 index 00000000..375e42eb Binary files /dev/null and b/screenshots/U/create.png differ diff --git a/screenshots/U/inside.png b/screenshots/U/inside.png new file mode 100644 index 00000000..d78b1583 Binary files /dev/null and b/screenshots/U/inside.png differ diff --git a/screenshots/U/name.png b/screenshots/U/name.png new file mode 100644 index 00000000..3b488b67 Binary files /dev/null and b/screenshots/U/name.png differ diff --git a/screenshots/U/new.png b/screenshots/U/new.png new file mode 100644 index 00000000..cf6b90f6 Binary files /dev/null and b/screenshots/U/new.png differ diff --git a/screenshots/U/scroll.png b/screenshots/U/scroll.png new file mode 100644 index 00000000..054cd9a9 Binary files /dev/null and b/screenshots/U/scroll.png differ diff --git a/tests/__init__.py b/tests/__init__.py index aa053906..7456dcb8 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -5,6 +5,9 @@ import testbox +import tools.file +import tools.lzw + class TestCase(unittest.TestCase): def __init__(self, *args, **kwargs): @@ -48,10 +51,22 @@ def setUp(self): box.send_keys(keys) time.sleep(0.1) - box.wait_image('screenshots/INSTALL/install.png', bbox=(0, 16, 640, 400), timeout=1) + box.wait_image('screenshots/INSTALL/install.png', bbox=(0, 16, 640, 400), timeout=2) self.assertTrue(os.path.isfile('CONFIG.U6')) def tearDown(self): os.remove('MAP') os.remove('CONFIG.U6') shutil.rmtree('SAVEGAME') + + +class ConfiguredTestCase(unittest.TestCase): + def setUp(self): + tools.file.write('CONFIG.U6', b'\x76\x6d\x61\x33\x38\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') + tools.file.write('MAP', tools.lzw.decompress(tools.file.read('original/LZMAP'))) + + def tearDown(self): + os.remove('MAP') + os.remove('CONFIG.U6') + if os.path.isdir('SAVEGAME'): + shutil.rmtree('SAVEGAME') diff --git a/tests/test_game.py b/tests/test_game.py index 5754bce1..f42123b7 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -1,3 +1,4 @@ +import shutil import time import unittest @@ -5,10 +6,11 @@ import tests -class TestGame(tests.InstalledTestCase): +class TestGame(tests.ConfiguredTestCase): @unittest.skip('TBD') def testGame(self): # FIXME игре нужен созданный персонаж + shutil.copytree('tests/testgame', 'SAVEGAME') configuration = { 'cpu': { diff --git a/tests/test_u.py b/tests/test_u.py index 47986e11..bad3c253 100644 --- a/tests/test_u.py +++ b/tests/test_u.py @@ -14,7 +14,7 @@ def testExitWithDriver(self): }, 'render': { 'scaler': 'normal5x', - }, + } } with testbox.TestBox( @@ -22,13 +22,13 @@ def testExitWithDriver(self): '-c', 'MOUNT C: .', '-c', 'C:', '-c', 'RK211.COM /L:RUSSIAN.RK /F:8X16.RK', # FIXME `RK.COM` - 'U.EXE', + 'U.EXE' ], configuration, timeout_error=AssertionError, ) as box: box.send_keys('\x1b') # Esc. - box.wait_image('screenshots/U/menu.png', timeout=6) + box.wait_image('screenshots/U/menu.png', timeout=10) box.send_keys('\x11') # Ctrl+Q. box.wait_image('screenshots/U/exit.png', timeout=1) @@ -40,17 +40,46 @@ def testU(self): }, 'render': { 'scaler': 'normal5x', - }, + } } with testbox.TestBox( [ '-c', 'MOUNT C: .', '-c', 'C:', - '-c', 'RK.COM /L:RUSSIAN.RK /F:8X16.RK', - 'U.EXE', + '-c', 'RK211.COM /L:RUSSIAN.RK /F:8X16.RK', # FIXME `RK.COM` + 'U.EXE' ], configuration, timeout_error=AssertionError, ) as box: + box.send_keys('\x1b') # Esc. + box.wait_image('screenshots/U/menu.png', timeout=10) + box.send_keys('▾') + box.wait_image('screenshots/U/new.png', timeout=1) + time.sleep(0.1) + box.send_keys('\r') + box.wait_image('screenshots/U/name.png', timeout=10) + box.send_keys('Vladimir\r') + time.sleep(0.1) + box.send_keys('M') + time.sleep(0.1) + box.send_keys('C') + box.wait_image('screenshots/U/create.png', timeout=10) + box.send_keys('\r') + box.wait_image('screenshots/U/scroll.png', timeout=10) + box.send_keys('\r') + time.sleep(0.1) + box.send_keys('\r') + box.wait_image('screenshots/U/inside.png', timeout=5) + box.send_keys('\r') + time.sleep(0.1) + box.send_keys('\r') + for _ in range(7): + time.sleep(0.5) + box.send_keys('A') + + # TODO Five spaces one Esc + + print('Go') time.sleep(1000) diff --git a/tests/testgame/OBJBLKAA b/tests/testgame/OBJBLKAA new file mode 100644 index 00000000..7dbb8b39 Binary files /dev/null and b/tests/testgame/OBJBLKAA differ diff --git a/tests/testgame/OBJBLKAB b/tests/testgame/OBJBLKAB new file mode 100644 index 00000000..c0658aa9 Binary files /dev/null and b/tests/testgame/OBJBLKAB differ diff --git a/tests/testgame/OBJBLKAC b/tests/testgame/OBJBLKAC new file mode 100644 index 00000000..e2312c83 Binary files /dev/null and b/tests/testgame/OBJBLKAC differ diff --git a/tests/testgame/OBJBLKAD b/tests/testgame/OBJBLKAD new file mode 100644 index 00000000..172bea55 Binary files /dev/null and b/tests/testgame/OBJBLKAD differ diff --git a/tests/testgame/OBJBLKAE b/tests/testgame/OBJBLKAE new file mode 100644 index 00000000..a52f3d4b Binary files /dev/null and b/tests/testgame/OBJBLKAE differ diff --git a/tests/testgame/OBJBLKAF b/tests/testgame/OBJBLKAF new file mode 100644 index 00000000..09f370e3 Binary files /dev/null and b/tests/testgame/OBJBLKAF differ diff --git a/tests/testgame/OBJBLKAG b/tests/testgame/OBJBLKAG new file mode 100644 index 00000000..e2583404 Binary files /dev/null and b/tests/testgame/OBJBLKAG differ diff --git a/tests/testgame/OBJBLKAH b/tests/testgame/OBJBLKAH new file mode 100644 index 00000000..55b08c1c Binary files /dev/null and b/tests/testgame/OBJBLKAH differ diff --git a/tests/testgame/OBJBLKAI b/tests/testgame/OBJBLKAI new file mode 100644 index 00000000..00c68fb4 Binary files /dev/null and b/tests/testgame/OBJBLKAI differ diff --git a/tests/testgame/OBJBLKBA b/tests/testgame/OBJBLKBA new file mode 100644 index 00000000..512c1f61 Binary files /dev/null and b/tests/testgame/OBJBLKBA differ diff --git a/tests/testgame/OBJBLKBB b/tests/testgame/OBJBLKBB new file mode 100644 index 00000000..7bde6777 Binary files /dev/null and b/tests/testgame/OBJBLKBB differ diff --git a/tests/testgame/OBJBLKBC b/tests/testgame/OBJBLKBC new file mode 100644 index 00000000..3454bd87 Binary files /dev/null and b/tests/testgame/OBJBLKBC differ diff --git a/tests/testgame/OBJBLKBD b/tests/testgame/OBJBLKBD new file mode 100644 index 00000000..fdfebdb6 Binary files /dev/null and b/tests/testgame/OBJBLKBD differ diff --git a/tests/testgame/OBJBLKBE b/tests/testgame/OBJBLKBE new file mode 100644 index 00000000..abf22ccf Binary files /dev/null and b/tests/testgame/OBJBLKBE differ diff --git a/tests/testgame/OBJBLKBF b/tests/testgame/OBJBLKBF new file mode 100644 index 00000000..27b23652 Binary files /dev/null and b/tests/testgame/OBJBLKBF differ diff --git a/tests/testgame/OBJBLKBG b/tests/testgame/OBJBLKBG new file mode 100644 index 00000000..d231d605 Binary files /dev/null and b/tests/testgame/OBJBLKBG differ diff --git a/tests/testgame/OBJBLKBH b/tests/testgame/OBJBLKBH new file mode 100644 index 00000000..46882f45 Binary files /dev/null and b/tests/testgame/OBJBLKBH differ diff --git a/tests/testgame/OBJBLKBI b/tests/testgame/OBJBLKBI new file mode 100644 index 00000000..a9c2b268 Binary files /dev/null and b/tests/testgame/OBJBLKBI differ diff --git a/tests/testgame/OBJBLKCA b/tests/testgame/OBJBLKCA new file mode 100644 index 00000000..84b2cb2b Binary files /dev/null and b/tests/testgame/OBJBLKCA differ diff --git a/tests/testgame/OBJBLKCB b/tests/testgame/OBJBLKCB new file mode 100644 index 00000000..2809bec8 Binary files /dev/null and b/tests/testgame/OBJBLKCB differ diff --git a/tests/testgame/OBJBLKCC b/tests/testgame/OBJBLKCC new file mode 100644 index 00000000..95d440c7 Binary files /dev/null and b/tests/testgame/OBJBLKCC differ diff --git a/tests/testgame/OBJBLKCD b/tests/testgame/OBJBLKCD new file mode 100644 index 00000000..ec696c1a Binary files /dev/null and b/tests/testgame/OBJBLKCD differ diff --git a/tests/testgame/OBJBLKCE b/tests/testgame/OBJBLKCE new file mode 100644 index 00000000..bfad73c2 Binary files /dev/null and b/tests/testgame/OBJBLKCE differ diff --git a/tests/testgame/OBJBLKCF b/tests/testgame/OBJBLKCF new file mode 100644 index 00000000..32539e6d Binary files /dev/null and b/tests/testgame/OBJBLKCF differ diff --git a/tests/testgame/OBJBLKCG b/tests/testgame/OBJBLKCG new file mode 100644 index 00000000..b557d0c7 Binary files /dev/null and b/tests/testgame/OBJBLKCG differ diff --git a/tests/testgame/OBJBLKCH b/tests/testgame/OBJBLKCH new file mode 100644 index 00000000..09f370e3 Binary files /dev/null and b/tests/testgame/OBJBLKCH differ diff --git a/tests/testgame/OBJBLKCI b/tests/testgame/OBJBLKCI new file mode 100644 index 00000000..37875610 Binary files /dev/null and b/tests/testgame/OBJBLKCI differ diff --git a/tests/testgame/OBJBLKDA b/tests/testgame/OBJBLKDA new file mode 100644 index 00000000..d84e99ab Binary files /dev/null and b/tests/testgame/OBJBLKDA differ diff --git a/tests/testgame/OBJBLKDB b/tests/testgame/OBJBLKDB new file mode 100644 index 00000000..b7c6ae9b Binary files /dev/null and b/tests/testgame/OBJBLKDB differ diff --git a/tests/testgame/OBJBLKDC b/tests/testgame/OBJBLKDC new file mode 100644 index 00000000..b3ee1469 Binary files /dev/null and b/tests/testgame/OBJBLKDC differ diff --git a/tests/testgame/OBJBLKDD b/tests/testgame/OBJBLKDD new file mode 100644 index 00000000..b7301074 Binary files /dev/null and b/tests/testgame/OBJBLKDD differ diff --git a/tests/testgame/OBJBLKDE b/tests/testgame/OBJBLKDE new file mode 100644 index 00000000..8234c28e Binary files /dev/null and b/tests/testgame/OBJBLKDE differ diff --git a/tests/testgame/OBJBLKDF b/tests/testgame/OBJBLKDF new file mode 100644 index 00000000..ce878755 Binary files /dev/null and b/tests/testgame/OBJBLKDF differ diff --git a/tests/testgame/OBJBLKDG b/tests/testgame/OBJBLKDG new file mode 100644 index 00000000..de05ad06 Binary files /dev/null and b/tests/testgame/OBJBLKDG differ diff --git a/tests/testgame/OBJBLKDH b/tests/testgame/OBJBLKDH new file mode 100644 index 00000000..50483d5d Binary files /dev/null and b/tests/testgame/OBJBLKDH differ diff --git a/tests/testgame/OBJBLKDI b/tests/testgame/OBJBLKDI new file mode 100644 index 00000000..020682b4 Binary files /dev/null and b/tests/testgame/OBJBLKDI differ diff --git a/tests/testgame/OBJBLKEA b/tests/testgame/OBJBLKEA new file mode 100644 index 00000000..6e6ca532 Binary files /dev/null and b/tests/testgame/OBJBLKEA differ diff --git a/tests/testgame/OBJBLKEB b/tests/testgame/OBJBLKEB new file mode 100644 index 00000000..8b087ff4 Binary files /dev/null and b/tests/testgame/OBJBLKEB differ diff --git a/tests/testgame/OBJBLKEC b/tests/testgame/OBJBLKEC new file mode 100644 index 00000000..6747e135 Binary files /dev/null and b/tests/testgame/OBJBLKEC differ diff --git a/tests/testgame/OBJBLKED b/tests/testgame/OBJBLKED new file mode 100644 index 00000000..09f370e3 Binary files /dev/null and b/tests/testgame/OBJBLKED differ diff --git a/tests/testgame/OBJBLKEE b/tests/testgame/OBJBLKEE new file mode 100644 index 00000000..e5aed92c Binary files /dev/null and b/tests/testgame/OBJBLKEE differ diff --git a/tests/testgame/OBJBLKEF b/tests/testgame/OBJBLKEF new file mode 100644 index 00000000..7a1b5309 Binary files /dev/null and b/tests/testgame/OBJBLKEF differ diff --git a/tests/testgame/OBJBLKEG b/tests/testgame/OBJBLKEG new file mode 100644 index 00000000..09f370e3 Binary files /dev/null and b/tests/testgame/OBJBLKEG differ diff --git a/tests/testgame/OBJBLKEH b/tests/testgame/OBJBLKEH new file mode 100644 index 00000000..91c2b4ec Binary files /dev/null and b/tests/testgame/OBJBLKEH differ diff --git a/tests/testgame/OBJBLKEI b/tests/testgame/OBJBLKEI new file mode 100644 index 00000000..bb7c378f Binary files /dev/null and b/tests/testgame/OBJBLKEI differ diff --git a/tests/testgame/OBJBLKFA b/tests/testgame/OBJBLKFA new file mode 100644 index 00000000..d088d11a Binary files /dev/null and b/tests/testgame/OBJBLKFA differ diff --git a/tests/testgame/OBJBLKFB b/tests/testgame/OBJBLKFB new file mode 100644 index 00000000..90ca4164 Binary files /dev/null and b/tests/testgame/OBJBLKFB differ diff --git a/tests/testgame/OBJBLKFC b/tests/testgame/OBJBLKFC new file mode 100644 index 00000000..40b3777b Binary files /dev/null and b/tests/testgame/OBJBLKFC differ diff --git a/tests/testgame/OBJBLKFD b/tests/testgame/OBJBLKFD new file mode 100644 index 00000000..09f370e3 Binary files /dev/null and b/tests/testgame/OBJBLKFD differ diff --git a/tests/testgame/OBJBLKFE b/tests/testgame/OBJBLKFE new file mode 100644 index 00000000..09f370e3 Binary files /dev/null and b/tests/testgame/OBJBLKFE differ diff --git a/tests/testgame/OBJBLKFF b/tests/testgame/OBJBLKFF new file mode 100644 index 00000000..5274e60b Binary files /dev/null and b/tests/testgame/OBJBLKFF differ diff --git a/tests/testgame/OBJBLKFG b/tests/testgame/OBJBLKFG new file mode 100644 index 00000000..d1612cf0 Binary files /dev/null and b/tests/testgame/OBJBLKFG differ diff --git a/tests/testgame/OBJBLKFH b/tests/testgame/OBJBLKFH new file mode 100644 index 00000000..8900d6e3 Binary files /dev/null and b/tests/testgame/OBJBLKFH differ diff --git a/tests/testgame/OBJBLKGA b/tests/testgame/OBJBLKGA new file mode 100644 index 00000000..8ed78ea4 Binary files /dev/null and b/tests/testgame/OBJBLKGA differ diff --git a/tests/testgame/OBJBLKGB b/tests/testgame/OBJBLKGB new file mode 100644 index 00000000..d7021cad Binary files /dev/null and b/tests/testgame/OBJBLKGB differ diff --git a/tests/testgame/OBJBLKGC b/tests/testgame/OBJBLKGC new file mode 100644 index 00000000..b0e5eeef Binary files /dev/null and b/tests/testgame/OBJBLKGC differ diff --git a/tests/testgame/OBJBLKGD b/tests/testgame/OBJBLKGD new file mode 100644 index 00000000..08818100 Binary files /dev/null and b/tests/testgame/OBJBLKGD differ diff --git a/tests/testgame/OBJBLKGE b/tests/testgame/OBJBLKGE new file mode 100644 index 00000000..e6a25b9d Binary files /dev/null and b/tests/testgame/OBJBLKGE differ diff --git a/tests/testgame/OBJBLKGF b/tests/testgame/OBJBLKGF new file mode 100644 index 00000000..710e385b Binary files /dev/null and b/tests/testgame/OBJBLKGF differ diff --git a/tests/testgame/OBJBLKGG b/tests/testgame/OBJBLKGG new file mode 100644 index 00000000..288f6953 Binary files /dev/null and b/tests/testgame/OBJBLKGG differ diff --git a/tests/testgame/OBJBLKGH b/tests/testgame/OBJBLKGH new file mode 100644 index 00000000..182e9031 Binary files /dev/null and b/tests/testgame/OBJBLKGH differ diff --git a/tests/testgame/OBJBLKHA b/tests/testgame/OBJBLKHA new file mode 100644 index 00000000..da89fdb9 Binary files /dev/null and b/tests/testgame/OBJBLKHA differ diff --git a/tests/testgame/OBJBLKHB b/tests/testgame/OBJBLKHB new file mode 100644 index 00000000..f7ed35a1 Binary files /dev/null and b/tests/testgame/OBJBLKHB differ diff --git a/tests/testgame/OBJBLKHC b/tests/testgame/OBJBLKHC new file mode 100644 index 00000000..e62695dc Binary files /dev/null and b/tests/testgame/OBJBLKHC differ diff --git a/tests/testgame/OBJBLKHD b/tests/testgame/OBJBLKHD new file mode 100644 index 00000000..25264cf5 Binary files /dev/null and b/tests/testgame/OBJBLKHD differ diff --git a/tests/testgame/OBJBLKHE b/tests/testgame/OBJBLKHE new file mode 100644 index 00000000..abafb9ff Binary files /dev/null and b/tests/testgame/OBJBLKHE differ diff --git a/tests/testgame/OBJBLKHF b/tests/testgame/OBJBLKHF new file mode 100644 index 00000000..09f370e3 Binary files /dev/null and b/tests/testgame/OBJBLKHF differ diff --git a/tests/testgame/OBJBLKHG b/tests/testgame/OBJBLKHG new file mode 100644 index 00000000..9d6c83c6 Binary files /dev/null and b/tests/testgame/OBJBLKHG differ diff --git a/tests/testgame/OBJBLKHH b/tests/testgame/OBJBLKHH new file mode 100644 index 00000000..707a38a0 Binary files /dev/null and b/tests/testgame/OBJBLKHH differ diff --git a/tests/testgame/OBJLIST b/tests/testgame/OBJLIST new file mode 100644 index 00000000..c2a8f9cf Binary files /dev/null and b/tests/testgame/OBJLIST differ diff --git a/tools/DEBUG.EXE b/tools/DEBUG.EXE new file mode 100644 index 00000000..7065b703 Binary files /dev/null and b/tools/DEBUG.EXE differ diff --git a/tools/duplicates.py b/tools/duplicates.py index 1ace8fab..be861699 100644 --- a/tools/duplicates.py +++ b/tools/duplicates.py @@ -1,5 +1,7 @@ import json import os +import random +import sys output_directory = os.getcwd() @@ -9,14 +11,46 @@ references = {(x['source'], x['offset']): x['references'] for x in json.loads(f.read())} with open('patches/bad-references.json') as f: - for x in json.loads(f.read()): - bad = set(x['bad-references']) - references[(x['source'], x['offset'])] = [ - y - for y in references[(x['source'], x['offset'])] - if y['origin'] not in bad - ] + br = json.loads(f.read()) + +for x in br: + bad = set(x['bad-references']) + references[(x['source'], x['offset'])] = [ + y + for y in references[(x['source'], x['offset'])] + if y['origin'] not in bad + ] for k, v in references.items(): if len(v) > 1: print('WARNING', k[0], hex(k[1]), len(v), 'references:', ', '.join((hex(x['origin']) for x in v))) + +if sys.argv[1:] in (['--fix'], ['--fix-half'], ['--fix-tenth']): + added = set() + if sys.argv[1:] == ['--fix-half']: + threshold = 0.5 + elif sys.argv[1:] == ['--fix-tenth']: + threshold = 0.1 + else: + threshold = 1.0 + + for k, v in references.items(): + if len(v) > 1: + for b in br: + if b['source'] == k[0] and b['offset'] == k[1]: + found = b + break + else: + found = {'source': k[0], 'offset': k[1], 'bad-references': [x['origin'] for x in v]} + br.append(found) + + for x in v: + if random.random() <= threshold: + found['bad-references'].append(x['origin']) + added.add((k[0], k[1], x['origin'])) + found['bad-references'] = sorted(found['bad-references']) + + print('Added:', sorted(added)) + br = sorted(br, key=lambda x: (x['source'], x['offset'])) + with open('patches/bad-references.json', 'w') as f: + f.write(json.dumps(br, indent=4)) diff --git a/tools/patch.py b/tools/patch.py index 11b78605..fb3f8066 100644 --- a/tools/patch.py +++ b/tools/patch.py @@ -232,34 +232,49 @@ def pi_jump(s, a): elif binary == 'U.EXE': patches.patch_U(d) + ds = d[header + segments[-1]*0x10:] + uninitialized_fill, = find_all(d, [0xbf, None, None, 0xb9, None, None, 0x2b, 0xcf, 0xf3, 0xaa]) initialized_size = int.from_bytes(d[uninitialized_fill+1:uninitialized_fill+3], 'little') assert initialized_size in (len(d) - segments[-1]*0x10 - header, len(d) - segments[-1]*0x10 - header-2) uninitialized_size = int.from_bytes(d[uninitialized_fill+4:uninitialized_fill+6], 'little') - initialized_size + + # FIXME not used dereferencing = [b'\xbf', b'\xa1', b'\x8b\x1e', b'\xa3', b'\xc4\x1e', b'\xff\x36', b'\x89\x1e', b'\x8c\x06', b'\x8b\x16', b'\x89\x16', b'\x3b\x06', b'\x29\x06', b'\x3b\x16', b'\x19\x16'] + system_break_shift, = find_all(d, [0x8b, 0x56, 8, 3, 6, None, None, 0x83, 0xd2, 0, 0x8b, 0xc8, 0x81, 0xc1, 0, 1, 0x83, 0xd2, 0]) system_break_address = int.from_bytes(d[system_break_shift+5:system_break_shift+7], 'little') system_break = int.from_bytes(d[system_break_address+segments[-1]*0x10+header:system_break_address+segments[-1]*0x10+header+2], 'little') assert system_break == initialized_size + uninitialized_size + # FIXME not used + extra_alloc_update, = find_all(d, [0x8b, 0x3e, None, None, 0x81, 0xff, 0, 2, 0x73, 7, 0xbf, 0, 2, 0x89, 0x3e]) + extra_alloc_address = int.from_bytes(d[extra_alloc_update+2:extra_alloc_update+4], 'little') + extra_alloc = int.from_bytes(ds[extra_alloc_address:extra_alloc_address+2], 'little') + replaces = [] - ds = d[header + segments[-1]*0x10:] ds_size = len(ds) ds = ljust(ds, system_break, b'www.old-games.ru.') + ds_full_size = len(ds) required_space = 0 if mode == 'russian': for t in translation: if t['source'] == binary: if not t['russian'].startswith('FIXME ') and t['russian'] != t['english']: references_segments = [x['segment'] for x in references.get((binary, t['offset']), [])] + new_string = t['russian'].encode('cp866') + import random + if random.random() < 0.95: + new_string = t['russian'].encode('cp866')[:len(t['english'].encode('cp866'))] - if len(t['russian'].encode('cp866')) <= len(t['english'].encode('cp866')): + if len(new_string) <= len(t['english'].encode('cp866')): # FIXME упаковать фразы лучше - message = t['russian'].encode('cp866').ljust(len(t['english']), b'\x00') + message = new_string.ljust(len(t['english']), b'\x00') replaces.append((t['offset'], len(message), message)) replaced += 1 elif t['offset'] > header + segments[-1]*0x10: + # Data segment. # FIXME reuse old space rr = references.get((binary, t['offset']), []) for r in rr: @@ -272,17 +287,28 @@ def pi_jump(s, a): added += 1 elif all(map(lambda x: isinstance(x, int), references_segments)): + # (Probably) only referenced by far pointers. print(f'String {repr(t["russian"])} can be moved!') - # FIXME why it can? else: missing += 1 ds[system_break_address:system_break_address+2] = len(ds).to_bytes(2, 'little') + + print('Old DS size:', hex(ds_size)) ds.extend(b'\x00' * ((len(ds) - ds_size + 0x1ff) // 0x200 * 0x200 - len(ds) + ds_size)) + print('Required space:', hex(len(ds)-ds_full_size)) assert (len(ds) - ds_size) % 0x200 == 0 data_space = (len(ds) - ds_size) // 0x200 + print('DS size:', hex(len(ds))) print(f'{binary} — adding {data_space*0x200 + len(code_block)} bytes for {len(functions)} functions and {added} strings') + + # TODO FIXME check for remaining memory + + #Reduce stack??? + #assert extra_alloc - data_space*0x20 >= 0x200 # Stack? FIXME find a way to leave stack size as is. + #ds[extra_alloc_address:extra_alloc_address+2] = (extra_alloc-data_space*0x20).to_bytes(2, 'little') + d[header + segments[-1]*0x10:] = ds # FIXME переставил это на абзац ниже, проверить, что это ничего не ломает. как будто бы не должно @@ -330,8 +356,25 @@ def pi_jump(s, a): assert ss + 0x10 < 0x10000 d[0x0e:0x10] = ss.to_bytes(2, 'little') d[4:6] = pages.to_bytes(2, 'little') + + assert d[0x0c:0x0e] == b'\xff\xff' # Maximum allocation. + d[0x0a:0x0c] = (max(0, int.from_bytes(d[0x0a:0x0c], 'little') - data_space*0x20)).to_bytes(2, 'little') - d[0x0c:0x0e] = (max(0, int.from_bytes(d[0x0c:0x0e], 'little') - data_space*0x20)).to_bytes(2, 'little') + + if d[0x0c:0x0e] != b'\xff\xff': + d[0x0c:0x0e] = (max(0, int.from_bytes(d[0x0c:0x0e], 'little') - data_space*0x20)).to_bytes(2, 'little') + + replace_system_breaks = { # TODO more strict. + b'\x81\xc7': 1, + b'\xb9': 1, + } + for i in range(len(d)): + if int.from_bytes(d[i:i+2], 'little') == system_break: + for prefix in replace_system_breaks: + if i >= len(prefix) and prefix == d[i-len(prefix):i]: + replace_system_breaks[prefix] -= 1 + d[i:i+2] = len(ds).to_bytes(2, 'little') + assert set(replace_system_breaks.values()) == {0} d = d[:header] + code_block + d[header:]