В MechCommander 1 есть дурацкий баг: всё крупное оружие меха сваливается в левую руку. Потеряешь эту руку — считай, потерял и меха. Автор решил разобраться, почему так происходит, и заодно пофиксить.
С помощью Ghidra (да, той самой от АНБ) он декомпилировал код игры и нашёл функцию getWeaponLarge(), которая определяет, «большое» оружие или «маленькое». Оказалось, что всё оружие из дополнения Desperate Measures по ошибке помечено как «маленькое» — разработчики просто забыли обновить функцию. А вот с распределением по локациям проблема серьёзнее.
Алгоритм для «мелкого» оружия работает так: кладёт первый экземпляр в первую проверяемую позицию (локацию 4), а для каждого следующего ищет место, где уже есть такое же оружие. Если не находит — использует «запасное» значение (0) и кладёт в первую позицию. Для «крупного» оружия логика та же, но «запасное» значение почему-то тоже 0 — только алгоритм проверяет локации в другом порядке, и последней оказывается та же самая позиция. Вуаля: всё крупное оружие сваливается в левую руку.
Автор исправил это через code cave в ассемблерном коде: он заменил значение в регистре EDI на 2 для случая с крупным оружием. Теперь первая пушка попадает в локацию 2, а следующие распределяются нормально. Также он попутно переписал функцию классификации — по умолчанию она считала всё «мелким», а теперь все пушки из Desperate Measures получили правильный статус.
Готовый патч — в виде конкретных байтовых замен по адресам в hex-редакторе. Для тех, кто боится править .exe вручную, автор выложил на GitHub автоматический патчер Mantis. Сам признаёт, что тестировал не очень тщательно — так что всё на свой страх и риск. А ещё по ходу дела выяснилось, что счётчик здоровья пилота, судя по всему, тоже глючит, но это уже совсем другая история. Автор предпочёл катапультироваться оттуда, пока не затянуло.