Как я писал фикс широкоэкранных разрешений для FlatOut


Не так давно я занимался написанием фиксов для нескольких старых игр, чтобы исправить искажение картинки и интерфейса на широкоформатных мониторах. Попросили взглянуть на FlatOut, вот и появилась идея заодно написать об этом.



Что требуется


Для создания полноценного фикса, который легко устанавливается и не требует замены файлов игры, я использовал: IDA, Cheat Engine, Visual Studio, универсальный ASI Loader(об этом чуть ниже), а для запуска исследуемой игры в окне — D3DWindower.

Разбор ресурсов


Заглянем в папку с установленной игрой, чтобы узнать, с чем придется работать. В данном случае, интерес представляет всего лишь один файл — «flatout.exe». В некоторых играх могут присутствовать дополнительные DLL, к примеру в Max Payne для исправления пропорций изображения я делал инжект в e2mfc.dll, а не в исполняемый файл. Flatout.exe пропатчен до v1.1, но официальный патч от российского дистрибьютора — компании «БУКА», содержит три разных EXE:



Я выбрал flatout,3.exe(2 822 144 байт) для исследования, так как IDA дизассемблирует его во вполне читабельный вид.

Опыты


Открыв flatout,3.exe в IDA, первым делом начинаю искать константы. Судя по моему предыдущему опыту, большинство старых игр используют для отображения интерфейса и 3D изображения одни из этих: 640.0, 480.0, 1.3333, 0.0015625 = 1.0/640.0, 0.00208333333 = 1.0/480.0 и т.п. Первым делом вбиваю в поиск 0.0015625, так как вторые по популярности константы 640.0 и 480.0 обычно находятся неподалеку. IDA находит искомое по адресу 0x667CE4:



Теперь можно запускать игру и попробовать изменить значение по этому адресу памяти. Вот так выглядит интерфейс FlatOut в разрешении 1280х720:

  

Запускаю параллельно Cheat Engine, присоединяюсь к процессу. Кнопкой «Add address manually» добавляю в таблицу адрес 0x667CE4:



Меняю его текущее значение на 0.0010, просто посмотреть, что из этого выйдет. По результату видно, что полдела сделано:

  

Теперь осталось найти, как исправить растягивание 3D изображения. Константу так называемого aspect ratio, 4:3 или 1.3333 я не нашел, поэтому решил попробовать поменять все числа 480 на 360. Этот метод я применял ранее в Max Payne, подумал, что он может помочь в поиске и здесь. В Cheat Engine устанавливаю следующие настройки и нажимаю «First Scan»:


 
Среди найденных адресов, добавляю в таблицу только отмеченные зелёным цветом. Зелёный цвет означает, что данные адреса принадлежат диапазону flatout.exe, а остальные нам попросту не нужны.


 
Меняю все найденные значения на 360:


 
Изображение игры пропадает, потом появляется ошибка. Опытным путём выясняю, что вылет происходит из за изменения двух адресов — FlatOut.exe+1069C3(0x5069C3) и FlatOut.exe+107CCB(0x507CCB). Перехожу по адресу 0x5069C3 в IDA, посмотреть, почему же вылетает:


 
480 здесь — смещение, а не константа, поэтому данная функция интереса не представляет, но внимание привлекает функция ниже, по адресу 0x5069D0, которая при небольшом преобразовании получает такой вид:


 
Пробую менять константы 4.0 и 3.0 на 16.0 и 9.0 соответственно:

 
C удивлением обнаруживаю что это и есть то самое aspect ratio, на разрешении 1280х720 картинка сразу обрела правильные пропорции(как было/как стало):


  
  

Теперь осталось написать плагин, который рассчитает вышеупомянутые константы в соответствии с текущим разрешением и сделает изображение игры корректным при любых настройках.

C++



Открываю Visual Studio, создаю новый проект Win32, тип приложения — библиотека DLL. В свойствах проекта устанавливаю следующие опции:
  • Конфигурация — Release
  • Набор символов — Использовать многобайтовую кодировку
  • Библиотека времени выполнения — Многопоточная (/MT)
  • Уровень предупреждений — Level1 (/W1)
  • Конечное расширение — .asi
  • Выходной каталог — E:\Games\FlatOut\FlatOut

Для работы с памятью я использую специальный класс CPatch.

Dllmain:
#include "stdafx.h"
#include "CPatch.h"

HANDLE HndThread;

int* g_Width = (int *)0x6B0D88;
int* g_Height = (int *)0x6B0D8C; 

int g_CameraAspectRatio_x = 0x5069DA;
int g_CameraAspectRatio_y = 0x5069E0;
int g_hud_stretch_x = 0x667CE4;

#define screen_width (float)*g_Width
#define screen_height (float)*g_Height


float hud_stretch_new = 0.0;

int Thread()
{
	while (!screen_width)
	{
		Sleep(0);
	}

	hud_stretch_new = 1.0/(480.0*(screen_width/screen_height));

	CPatch::SetFloat(g_CameraAspectRatio_x, screen_width);
	CPatch::SetFloat(g_CameraAspectRatio_y, screen_height);
	CPatch::SetFloat(g_hud_stretch_x, hud_stretch_new);
		
	return 0;
}


BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved)
{
    if(reason==DLL_PROCESS_ATTACH)
    {
		HndThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)&Thread,NULL,0,NULL);
    }
    return TRUE;
}


Чтобы моя ASI-библиотека загружалась вместе с игрой, нужно установить универсальный ASI Loader, скопировав dsound.dll из архива в папку с игрой. ASI — это всего лишь переименованная DLL, а dsound.dll загружает ASI в процесс любой игры, которая использует DirectSound. Возможна загрузка из подпапки scripts.

Результат


Это только первая версия плагина, и скорее всего она еще не раз обновится. Есть определенные недоработки, например главное меню. Также в случае несовместимости можно добавить поддержку других EXE, например steam-версии.


 

 

 
Скачать плагин можно с github.
Установка проста — распаковать архив в папку с игрой.

Обновление от 02.08.2013


Выпустил обновленную версию, с поддержкой steam-версии и steam-демоверсии игры.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 43

    +3
    Отлично! Жду поддержку стим-версии! Спасибо за проделанную работу
      0
      А стим ругаться не будет на то, что в игру что-то внедрилось?
        0
        Если запущена хоть одна игра с Valve Anti Cheat (VAC), то это может стать причиной VAC-бана аккаунта. Если не запускать одновременно Flatout и, например, Half-Life 2, то никаких проблем не будет, проверено.
          +4
          За VAC банят только на серваках, где включён VAC. Со своими играми можешь делать что угодно и сколько угодно. И по VAC банят не весь аккаунт, а только игры конкретного издателя/разработчика.
            0
            Отлично! Но я на всякий пожарный стараюсь придерживаться инструкции от Steam Achievement Manager:
            V. Exit any active VAC protected games if any are running.
            0
            Немного цитат из документации Steamworks SDK
            VAC is a component of Steamworks and the Steam client, and works by scanning the users system for cheats while your game is running. It works a lot like a virus scanner, and has a database of known cheats to detect.
            We only attempt to detect cheats reported by the developer.

            Следовательно получить бан за подобного рода фиксы отсутствует. А в случае с SAM причина в том, что он может в любой момент может оказаться в той базе, все-же тулза для открытия достижений подходит под определение чита.
          0
          Обязательно будет, как только заполучу доступ к exe. В стиме, говорят, используется версия 1.0, т.е. адреса 99% не совпадут.
            +1
            Готово! Если что-то вдруг не работает, обязательно дайте знать. Хоть я и проверил плагин на всех exe, которые нашел, всякое может быть.
            0
            Вы напомнили мне истории пятилетней давности, когда мы переделывали и добавляли новые фишки в Корейскую игру MU Online, исследуя OllyDbg'ером екзешник игры. Спасибо!
              +13
              Меня очень часто удивляло, как «легко» в подобных играх меняется соотношение экрана. Не лезет вёрстка после этого. Нигде ничего не хардкодится. Спидометр не уехал влево. Даже удивительно становится, как сами авторы не добавили эту функциональность.
                0
                Но на первых двух картинках спидометр так и остался сжат по вертикали.
                  0
                  Не пойму, о чём вы. Вроде везде и спидометр и 3д-изображение исправленно.
                    0
                    Я про вот эти две картинки (которые в статье первые сравниваются):
                    Тут как раз машинка нормальная, а всё меню сжато повертикали. На последних скринах да, всё исправлено.
                    Вообще там при комменте мысль была такая, что не так-то и легко меняется оно, раз меню скукоживается, а 3Д нормальное.
                    «до»
                    image
                    «после»
                    image
                      +1
                      А, это, просто после того, как игра вылетела, я больше не менял 0.0015625 в Cheat Engine, поэтому 2д-элементы остались растянутыми.
                        0
                        На этих скриншотах как раз заметна проблема с камерой. Смутно припоминаю те пляски с играми в 2005-2006 году, когда я обзавелся широкоформатным монитором, но одним из факторов успеха было не только исчезновение растягивания по горизонтали, но и увеличение обзора за счет пространства по бокам, а тут получается обратный эффект. Камеру всеже надо немного отдалить (POV, если не ошибаюсь).
                          0
                          Да, FOV(Field of View) неплохо было бы увеличить. Но там есть смена режимов камеры, и самый дальний вид вроде выглядит неплохо. Возможно позже посмотрю что можно сделать.
                      0
                      Вроде бы все идеально совпадает с оригинальными пропорциями: сравнение 1, сравнение 2.
                        0
                        Вероятно, это «опечатка», если можно так выразиться. Вряд ли создатели игры решили поместить спидометр в отдельный графический контекст со своим разрешением. В данном случае так поступать нет смысла.
                        0
                        Это точно. Но вот в старых NFS, 3D хоть и не растягивается(широкоформатные разрешения все же нужно добавлять вручную), интерфейс при уменьшении уползает в левый верхний угол. Хотя, все не так плохо, если отключить половину элементов. Особенно удивляет, как игра(NFSMW 2005), вышедшая и на Xbox360, в 720p, на PC не получила даже выбора широкоформатных разрешений в настройках.
                          0
                          В то время не были популярны разрешения в HD, у всех были мониторы 4:3 или 5:4.
                          Я бы очень хотел поиграть в NFSMW 2005 в формате 16:9 и с нормальным интерфейсом.
                          Реально ли такое сделать?
                            0
                            Уже сделано: www.wsgf.org/dr/need-speed-most-wanted
                            В Solutions & Issues я добавил свой фикс. В ini X=0 и Y=0 означают, что игра запустится в текущем разрешении рабочего стола.
                            Интерфейс мне перерасположить не удалось к сожалению. Все что смог сделать, контролируется опцией HUD_PATCH=1, а убираются отдельные элементы в меню игры.
                        +1
                        Всегда интересовало почему никто не сделал фикса под WC3. Там что-то принципиально отличается?
                          –2
                          Warcraft 3? В этой игре быстро привыкаешь к растяжению интерфейса, особенно если сидишь на 16:9 довольно долго.
                            +3
                            На мой взгляд это извращение :) В WC3 включаю принудительно формат 4:3 и играю с черными полосами по бокам.
                              0
                              Когда играешь не в сам Warcraft 3, а ее отрасль в виде карты DotA, то эти самые черные полоски очень сильно мешают, поэтому лучше привыкнуть к 16:9. чтобы не проигрывать! :)
                                +1
                                как они могут мешать? Реально мешает именно искарёженная картинка.
                                  –2
                                  Как я уже писал, глаз привыкает к искаженной картинке, когда думаешь, что она должна быть таковой. А черные полосы постоянно находятся по бокам и они не вписываются в дизайн игры.

                                  Хотя я могу ошибаться и мы действительно говорим о разных патчах, потому что сильно искаженного интерфейса на 16:9 я не наблюдаю.
                                    0
                                    Можно привести этот же самый аргумент к полоскам — к ним быстро привыкаешь и думаешь, что так и должно быть, как рамки у монитора. И вот уж растянутое всё точно не вписывается в дизайн игры.
                                      +5
                                      Когда вместо круга овал — это просто кошмар.
                                  +1
                                  Поддерживаю. Лучше черные полосы. Но надежда умирает последней.
                                0
                                Ну вообще в последних патчах добавили поддержку даже разрешения 1920х1080. (Если Вы о TFT, конечно. Насчёт оригинального WC3 не могу сказать.)
                                  +1
                                  О чем и речь, поддержку ввели, а растянутое изображение не исправили.
                                +4
                                Хорошая статья, спасибо. Без воды и прочей ерунды. Казалось бы, задача изменения разрешения в игре имеет далеко не самую низкую степень сложности, ан нет, нужно лишь как следует сперва подумать головой, и все станет на свои места.
                                Также возникает один вопрос, связанный с обнаружением функции, отвечающей за разрешение в игре.
                                Вы пишите:
                                480 здесь — смещение, а не константа, поэтому данная функция интереса не представляет, но внимание привлекает функция ниже, по адресу 0x5069D0...


                                Выходит, вам удалось обнаружить функцию случайно, отыскав смещение 0x1E в памяти ( выше по коду ), которое не имеет ничего общего с задачей?
                                  0
                                  Да, именно так.
                                    0
                                    Думал, я один такой :) Что ж, теория о том, что большинство взломов( хаков ) — лишь удачное стечение обстоятельств подтверждена.
                                  –4
                                  Одна из немногих игр в которые я играл.
                                    +12
                                    Молодец.
                                      –2
                                      ага, голодное детство, игр было мало, приходилось играть только в одну. :))) Я к тому что это одна из немногих игр которые мне нравятся и в которые я играю и сейчас иногда.
                                    +3
                                    для нескольких старых игр

                                    <ностальгия>Но ведь FlatOut — не старая игра, у меня же в тумбочке диск от Игромании с демо-версией, мы же только недавно с друзьями всю ночь в мини-игру из демо-версии играли… Как десять лет прошло?</ностальгия>
                                      0
                                      Можете попытать Dungeon Siege?
                                        0
                                        Я посмотрел страницу этой игры на WSGF, там описан способ запуска в широкоформатном разрешении, можно только этот процесс автоматизировать в виде плагина, но нужно ли это? В принципе, если скинете exe, могу попытаться.
                                          0
                                          Спасибо большое, не знал про WSGF. Просто в конфиге тупо поменял разрешение и ладно.
                                        +2
                                        Очень круто! Я хоть и разработчик ПО (корпоративный веб), но восхищен таким реверс инжирингом и как оказывается не так сложно свой патч добавить в игру, для меня до этой статьи было что-то вроде магии. :)

                                        Only users with full accounts can post comments. Log in, please.