- PVSM.RU - https://www.pvsm.ru -

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

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

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

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

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

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

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

Я выбрал 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

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

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

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

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

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

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

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

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

Как я писал фикс широкоэкранных разрешений для FlatOut
 
Меняю все найденные значения на 360:

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

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

Как я писал фикс широкоэкранных разрешений для FlatOut
 
Пробую менять константы 4.0 и 3.0 на 16.0 и 9.0 соответственно:
Как я писал фикс широкоэкранных разрешений для FlatOut
 
C удивлением обнаруживаю что это и есть то самое aspect ratio, на разрешении 1280х720 картинка сразу обрела правильные пропорции(как было/как стало):

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

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

C++

Открываю Visual Studio, создаю новый проект Win32, тип приложения — библиотека DLL. В свойствах проекта устанавливаю следующие опции:

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

Для работы с памятью я использую специальный класс 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_heigth (float)*g_Height
#define hud_stretch_x (float)*g_hud_stretch_x

float hud_stretch_new = 0.0;

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


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

	CPatch::SetFloat(g_CameraAspectRatio_x, screen_width);
	CPatch::SetFloat(g_CameraAspectRatio_y, screen_heigth);
	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 [5], скопировав dsound.dll из архива в папку с игрой. ASI — это всего лишь переименованная DLL, а dsound.dll загружает ASI в процесс любой игры, которая использует DirectSound. Возможна загрузка из подпапки scripts.

Результат

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

Автор: ThirteenAG

Источник [13]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/igry/39967

Ссылки в тексте:

[1] FlatOut: http://en.wikipedia.org/wiki/Flatout

[2] IDA: https://www.hex-rays.com/products/ida/support/download.shtml

[3] Cheat Engine: http://www.cheatengine.org/

[4] Visual Studio: http://www.microsoft.com/visualstudio/rus

[5] универсальный ASI Loader: https://dl.dropboxusercontent.com/u/13992625/gta/stuff/Universal_asi_loader.zip

[6] D3DWindower: http://forum.xentax.com/viewtopic.php?f=33&t=10242

[7] официальный патч: http://www.buka.ru/cgi-bin/show.pl?option=Show_patch&id=143

[8] Image: http://habrastorage.org/storage2/d3a/7ca/29f/d3a7ca29f575c41d532062a7b443e40d.jpg

[9] Image: http://img707.imageshack.us/img707/5194/vfxb.jpg

[10] aspect ratio: http://ru.wikipedia.org/wiki/Соотношение_сторон_экрана

[11] Image: http://habrastorage.org/storage2/241/495/317/24149531705d92b3301c9d7e7161f3db.jpg

[12] Image: http://habrastorage.org/storage2/932/7c9/f22/9327c9f228237e6da77a174b94279443.jpg

[13] Источник: http://habrahabr.ru/post/188594/