company_banner

Как и зачем Morrowind перезапускала оригинальный Xbox во время экрана загрузки

Автор оригинала: Modern Vintage Gamer
  • Перевод

Оригинальный Xbox известен тем, что имел всего 64 мегабайта оперативной памяти, чего даже в то время не всегда хватало играм. В недавнем подкасте о слиянии Bethesda и Xbox директор Bethesda Game Studios Тодд Говард рассказал о том, что именно из-за нехватки памяти и для ее освобождения Morrowind иногда перезагружала Xbox незаметно для пользователя. Долгие внутриигровые загрузки — это как раз то, о чем идет речь. 

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

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

Теперь настало время доказать это.

Для этого нам понадобятся три вещи:

  1. Копия игры;

  2. Комплект разработчика Xbox (XDK):

  3. Декомпилятор.

В качестве последнего будем использовать IDA Pro.

В первую очередь установим игру на девкит и запустим ее. Для удобства возьмем файл сохранения из Интернета, чтобы понаблюдать, как он будет загружаться посредством экрана загрузки.

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

Но если использовать Xbox Neighborhood для тихой перезагрузки Xbox, мы увидим, что консоль действительно перезагружается — и сразу после этого игра попадает на момент экрана загрузки. 

Отсюда вопрос: как все это работает?

Можно припомнить, что раньше существовала конкретная функция в API Xbox, которая могла запускать исполняемый файл Xbox из уже существующего и просто передавать аргументы из старого файла в новый. Если взглянуть на дашборд Xbox, такой как Evolution X, он запускается прямо из исполняемого файла Xbox, но также производит тихую перезагрузку.

Эта часть API Xbox — XLaunchNewImage. Согласно документации, она перезагружает консоль для запуска другого файла XBE с DVD-диска.

При вызове XLaunchNewImage игра должна иметь минимальную активность. Не должно ничего происходить в других потоках, никаких асинхронных задач, записи на жесткий диск и т. д. 

Вот мы и получили достаточно весомое доказательство того, что Xbox перезапускается в процессе исполнения Morrowind, при этом сохраняя состояние игры и загружаясь из сохранения. Теперь выясним, как же это работает.

Запустим игру на девките. В этом случае XLaunchNewImage должна перезапустить консоль. Теперь загрузим сохраненную игру с жесткого диска, но перед этим задействуем инструмент под названием Xbox File Event Viewer. Он будет отслеживать и выводить на экран создание каждого нового файла для чтения или записи.

Установим фильтр на названии morrowind.xbe. Если будет происходить запуск файла с таким именем, скорее всего, в этом вызове будет задействована XLaunchNewImage, которая и производит перезапуск консоли для исполнения другого файла XBE с диска.

Теперь запустим Xbox File Event Viewer и наш файл сохранения. Как мы видим, происходят множественные чтения файла morrowind.xbe. Это не обязательно говорит о перезапуске консоли, но наверняка указывает на то, что происходит активность XLaunchNewImage. 

Теперь используем инструмент для реверс-инжиниринга и декомпилируем исполняемый файл morrowind.xbe. Для этого загрузим его в IDA Pro. И для начала поищем в нем непосредственно упоминание morrowind.xbe. 

Первое, что мы видим в результатах поиска — функцию получения доступа к файлу. Декомпилируем этот кодовый блок. 

По-видимому, выделенный путь и исполняет XLaunchNewImage — ведь, как мы видим в документации, один из требуемых для этого параметров — строка для адреса XPE, а второй — данные о запуске. Это вполне себе коррелирует с функцией sub_23AB90. Переименуем ее в XLaunchNewImage. 

Но прежде, чем утверждать, что дело раскрыто, взглянем еще раз на код. Стоит обратить внимание на это условие. 

Если байт byte_3A3209 имеет значение true, выполняется один кусок кода, в противном случае  — другой, заканчивающийся исполнением команды XLaunchNewImage. 

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

Перейдем к ней.

Один из двух байтов здесь говорит о том, чтобы если флаг «No reboot on new game» = 1 в файле Morrowind.ini, тогда этот байт равен true. Что касается второго, искомого байта, он становится true, если выполняется условие «No reboot on load game» = 1 в Morrowind.ini. 

Если открыть Morrowind.ini, мы увидим, что оба значения «No reboot on new game» и «No reboot on load game» установлены в нуле, а значит — игра будет перезагружаться на Xbox. Но на девкитах для отладки, когда игра разрабатывалась Bethesda, скорее всего, они имели значения единицы, поскольку те использовали 128 МБ вместо 64. 

Итак, мы получили подтверждение того, что консоль перезагружается на экранах загрузки. Но также мы открыли то, что это происходит не только при загрузке, но и создании новой игры, что тоже весьма любопытно. Взглянем теперь на это условие, когда NoRebootOnNewGame = false.

В этом месте происходит загрузка состояния, в котором игра была перед сохранением и перезапуском:

Мы убедились, что Xbox действительно перезагружается для очистки памяти во время экранов загрузки Morrowind, и вместо того, чтобы возвращаться к главному экрану игры, сразу переходит на экран загрузки и вызывает последнее сохранение.  Достигается это с помощью процедуры под названием XLaunchNewImage — части API Xbox, которую можно использовать для тихой перезагрузки консоли и запуска исполняемого файла. Но чего Говард не упомянул, так это того, что то же самое происходит при старте новой игры. 

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

Pixonic
Разрабатываем и издаем игры с 2009 года

Комментарии 16

    +24
    Причина такого поведения в том, что проще загрузить игру заново при загрузке сохранения, чем пытаться выгрузить все игровые ассеты в памяти из текущей игры. Это достаточно изящный трюк, который, вероятно, в свое время значительно упростил жизнь команде разработчиков.
    Я бы сказал, что это скорее некрасивый костыль, решающий проблемы кривого кода, неспособного корректно освободить ресурсы.
      –20
      Лайк поставить не хватает прав, так что текстом пишу: полностью с вами согласен — «перезагрузка» всегда была «решением» каких-либо проблем с мелкомягким софтом
        –17

        Не могу лакнуть, так что просто поддержу.

          +1
          У ас сейчас F5 автоматически прожимается на любой странице, на которой что-то пошло не так. Тоже костыль?
          +1
          Мало корректно освободить ресурсы — память после этого может остаться фрагментированной и новые ассеты будет некуда грузить.
          –12
          А где вы столько денег взяли на ida pro + hexrays? Это же какие деньги надо зарабатывать.
            +8
            Это не мы, это переводной материал :)
              +4
              У этого молодого человека ещё и девкиты некоторых консолей есть, в том числе и xBox origin. Без девкита, это исследование провернуть, я так понимаю, тоже не вышло бы.
                +1
                Автор оригинала — игровой разработчик из Nightdive Studios.
                0
                По тексту иногда проскакивает то, что перезагружался Morrowind, хотя на деле перезагружалась консоль целиком.
                  0
                  Да, перезагружалась вся консоль во время загрузочного экрана игры. В целом это означает, что игра перезагружалась вместе с консолью, но все это происходило незаметно для пользователя.
                  0
                  Я вот не понимаю, почему некоторые игры и программы при закрытии просто за секунду закрываются, а другие могут тупить минуту, выводя всякие сообщения типа «Destroying level» (привет, Сталкер). Казалось бы, что проще — пометить, что от сих до сих оперативная память теперь пуста.
                  Или вот. Винда выключается довольно долго, что-то там пишет на диск и т.д. А live-DVD (BartPE) от Сергея Стрельца, грузящийся с диска/флешки, при команде выключения падает за секунду-две.
                    +1

                    Конкретно в случае винды есть сервисы, которые работают в фоне и делают операции чтения/записи на доступные носители, живые ос пишут очень мало на свой носитель. Вот о сталкере, есть вероятность того что нельзя просто взять и пометить диапазон адресов, а процесс уничтожения однопоточен и перебирает каждую переменную.

                      0
                      так можно в реестре настроить время выключения винды, я ставил, чтоб сразу выключался
                      +2

                      Надеялся прочитать разбор того, какое железо в каком порядке перезагружается, как при этом не гаснет экран (или он гаснет?), кровь-кишки-расчленёнка. А вместо этого просто «Я декомпилировал, оно действительно дёргает стандартyую функцию API и перезагружается».
                      Грусть-печаль.

                        +1

                        Я ещё ожидал, что будут поиски причин такого решения. Например, попробуют переполнить память.

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое