
Порт с иксбокса говорите? Возможно, однако хотелось бы поконкретнее. Например Halo 1 и 2 также портированы с xBox, однако у Bungie вполне получилось сделать адекватную PC-версию. Что же в таком случае помешало Irrational Games?
Поскольку, в качестве домашней ОС у меня стоит Windows Server 2012, то софт в котором QA было в стиле "на моем компьютере всё работает" видно издалека. К сожалению, BioShock попадает именно в эту категорию. Основные проблемы, с которыми встречается почти каждый запускавший игру это:
- Игра не запускается с ошибкой "Failed to create GameExplorer object"
- При выходе из игры, она через раз падает, зачастую портя собственные файлы конфигурации
- Неотключаемое ускорение мыши в игре, "резиновая" мышь во внутриигровых и главном меню
Проведя несколько увлекательных вечеров в обнимку с отладчиком, дизассемблером, гуглом и другими подручными инструментами, я смог выяснить, что именно происходит и частично исправить ситуацию.
Failed to create GameExplorer object

Game Explorer это оболочка для быстрого доступа к играм, присутствовавшая в Windows Vista\7. В теории он позволял получать обновления\новости, ограничивать запуск игр помощью системы родительского контроля и предоставлял интеграцию с Games for Windows Live. Почему в теории? А потому, что единственным стимулом внедрять его в свои продукты для разработчиков была сертификация на логотип Games for Windows, для прохождения которой требовалась поддержка Game Explorer. Таким образом функциональность в большинстве случаев реализовывалась для галочки и не давала пользователям ничего кроме проблем. Посему, просуществовав всего два мажорных релиза Windows, Game Explorer был оттуда тихо выпилен.
Код Game Explorer в Windows находится в библиотеке gameux.dll и доступен только в клиентских релизах, в серверных версиях этого компонента нет. Разумно предположить, что на серверных конфигурациях игры не тестируются и отсутствие Game Explorer это "проблемы индейцев". Однако, по неясной причине, BioShock падает при попытке обратиться к Game Explorer и на ПК с Windows Vista\7, что подтверждается бесчисленным количеством криков о помощи в интернетах. Технически, это выглядит как попытка создать объект IGameExplorer, которая заканчивается ошибкой при вызове CoCreateInstance с кодом 0x80040154 (Class not registered).
Я к сожалению не смог докопаться до самой сути проблемы и выяснить, почему объект не создается (сами библиотеки у меня есть и зарегистрированы). Поэтому я пошел более простым путем и отключил инициализацию Game Explorer при запуске игры под Vista и выше.
Код определения версии ОС начинается с хитрого трюка с вызовом timeBeginPeriod. Эта функция отвечает за разрешение системного таймера и её вызов с минимальным значением 1 позволяет повысить точность таймеров и улучшить синхронизацию событий по времени внутри приложения. Удивительно, что в зависимости от того, сработала функция или нет, игра решает, какой вариант функции ей использовать для определения версии ОС: юникодный (GetVersionExW) или ANSI (GetVersionExA). Я не смог найти объяснения такому поведению, т.к. по документации timeBeginPeriod доступна с Windows 95 и во всех ОС ведет себя одинаково. С документацией кстати отдельная история: гугл и страница на японском MSDN говорят, что timeBeginPeriod присутствует c Windows 95, а вот английская версия уверена в обратном и заявляет минимальной поддерживаемой системой Windows 2000. Мистика, не иначе.

Затем, если Bioshock обнаруживает, что он запущен под Vista, он проверяет значение некоей внутренней переменной (которая всегда устанавливается в единицу из другого куска кода) и если она не равна нулю пытается инициализировать Game Explorer. Такое поведение нам только на пользу, т.к. исправив всего один условный переход мы отключаем ненужный нам код, не рискуя сломать что-либо. На рисунке он выделен серым цветом.

После патча игра запускается без ошибок. К слову, такого же результат можно добиться, поставив в свойства исполняемого файла запуск в режиме совмести с Windows XP и именно это рекомендуют всем столкнувшимся с такой проблемой. Однако, в этом случае при запуске будет срабатывать UAC, вынуждая пользователя каждый раз совершать лишние движения.
Падение при выходе
С завидной регулярностью, при попытке выйти из игры, она в последний момент падает и норовит испортить при этом собственные конфиги. В интернетах опытным путем установили, что если в конфиге указать другой звуковой драйвер (D3DDrv.D3DAudioDevice вместо FMOD.FMODAudioDevice), то ошибка пропадает. Проблема в том, что после этого звук работает только в меню, но не в самой игре. Это связано с тем, что все внутриигровые звуки хранятся в формате FSB (FMOD's sample bank format) и без драйвера FMOD не воспроизводятся.Обновить же библиотеку FMOD тоже нельзя, т.к. она статически слинкована в BioShock.exe. При попытке посмотреть, где же именно она падает, я выяснил, что это происходит где-то внутри критических секций и скорее всего связано с проблемами при синхронизации потоков игры. Дебажить такое без исходников очень сложно и тут я бессилен. Единственное, что можно сделать, это настроив Bioshock, установить файлам конфигурации атрибут Read Only. Это предотвратит их порчу.
Резиновая мышь
Первое, что меня поразило в BioShock, это разная чувствительность мыши в главном меню, в самой игре и во внутриигровых меню. Причем, если в самой игре вcё было еще более или менее прилично, то в главном и дополнительных меню курсор мыши натурально ведет себя как привязанный резинкой. Горизонтальная и вертикальная чувствительность различаются, а курсор остается неподвижным, если перемещать мышь медленно, что очень похоже на реализацию мертвой зоны для стиков геймпада.
С чувствительностью внутри игры проблему удалось решить достаточно просто. Нужно добавить в файлы DefUser.ini и User.ini следующую секцию:
[Engine.PlayerInput]
MouseSmoothingMode=0
MouseAccelThreshold=0
Причем это официальное решение проблемы, вошедшее в патч 1.1
Дополнительно можно установить в False следующие параметры в секциях [D3DDrv.D3DRenderDevice] и [D3DDrv10.D3DRenderDevice10]:
ReduceMouseLag=False
CaptureMouse=False
DoubleBufferMouseLag=False
Замечу, что установка CaptureMouse=False иногда позволяет видеть в главном меню нативный курсор мыши, на фоне которого особенно заметно как тормозит нарисованный игрой. К сожалению добиться повторяемости этого эффекта мне не удалось.
Но почему же поведение мыши так разительно отличается? А дело вот в чем: весь GUI, включая главное, внутриигровые меню и HUD реализован с помощью Scaleform (в 2011 их купил Autodesk). Это middleware для построения GUI в играх, использующее флеш. В этом легко убедится заглянув в папку Bioshock\Content\FlashMovies\ и обнаружив там набор флешек с говорящими именами:
- Bathysphere.swf
- BathyspherePC.swf
- ...
- pausePC.swf
- PCWeaponSelection.swf
- ...
- WarningPC.swf
Как выяснилось, проблема с чувствительностью мыши у Scaleform давно известна, и для её решения необходимо написать простой обработчик, в виде нативной dll, который захватывал бы аппаратный курсор мыши и обрабатывал его координаты самостоятельно, минуя Scaleform. Например так. Однако, не все разработчики учитывают это при портировании, например от такой же болезни страдает польский The Witcher. Я на всякий случай разобрал sfw-файлы декомпилером, однако ничего относящегося к работе с мышью не нашел. Так, например выглядит код из меню паузы (pausePC.swf)

Скорее всего обработчик находится в скриптах UnrealScript, и выглядит приблизительно так. Добраться до скриптов у меня не получилось, распаковщики сильно привязаны к версии движка, который был серьезно допилен Irrational Games и к которому они зажали SDK.
Кстати, в файле ConfigINI.IBF, где в склееном виде хранятся конфиги игры есть такие строки:
;Controls the sensitivity of the mouse in flash
FlashMouseSensitivity=0.75
Я пробовал менять значение этой переменной, но никакого эффекта это не дало.
Заключение
В целом,
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Actually, there are several other possible explanations:
- The devs deliberately made the mouse input the way it is to give PC users a simulation of the clunky experience of playing an FPS with a gamepad.
- The PC testers had never actually played a FPS before, and assumed that the mouse behavior was supposed to simulate the movements of a drunken spastic.
- The PC testers were actual drunken spastics, and therefore didn't notice.
- There were no PC testers.
- There were PC testers, they did notice, but the devs/publisher decided it was more important to get the game on shelves than it was to have it playable.
no subject
Date: 03/04/2013 03:24 (UTC)From:no subject
Date: 03/04/2013 10:08 (UTC)From:no subject
Date: 03/04/2013 03:25 (UTC)From:no subject
Date: 03/04/2013 10:10 (UTC)From: