Дом в Little Computer People. Разве этот декор в стиле 1980-х не прекрасен?
Дом в Little Computer People. Разве этот декор в стиле 1980-х не прекрасен?

TL;DR

В этом посте я расскажу о том, как выполнил частичный реверс-инжиниринг файлов данных Little Computer People, чтобы включить опции конфигурации, недоступные в оригинальной игре. Я написал и выпустил инструмент, работающий с LCP для Amiga, который можно скачать в конце поста.

Little Computer что?

В 1985 году на самых популярных 8-битных домашних компьютерных системах (и Atari ST) была выпущена «игра» под названием «Little Computer People», а через два года появилась версия и для Amiga. Сюжет игры заключается в том, что внутри вашего компьютера живёт маленький человечек, и это ПО позволяет вам следить за его действиями и взаимодействовать с ним. Если вы незнакомы с LCP, в Википедии есть хорошая статья о ней, которую стоит прочитать.

Уилл Райт (дизайнер The Sims) сказал, что игра в LCP и общение с одним из создателей LCP (Ричем Голдом) помогли ему в разработке концепций The Sims, и одно это делает LCP важной вехой в истории ПО.

Для многих людей LCP была скучной игрой. Считалось, что никто не захочет следить за жизнями персонажей на экране. Думаю, наблюдая за успехом франшизы The Sims и бесконечных реалити-шоу, можно с полным правом сказать, что это мнение было совершенно ошибочным. Возможно, LCP просто опередила своё время?

Каждый из этих дисков не похож ни на один другой

В дисковой версии LCP для Commodore 64 каждый диск вручную (в студии копирования) модифицировался: в пустой неиспользуемый сектор записывался секретный серийный номер. Этот серийный номер использовался для контроля аспектов конкретной версии LCP. Смысл был в том. что у каждого игрока LCP должна быть своей. Вы впервые запускаете игру, видите, как ваш уникальный человечек входит в дом, выглядя и ведя себя совершенно иначе, чем у вашего друга. Как мы узнаем ниже, на Amiga всё было организовано иначе.

В версии для Amiga (которую я и буду исследовать в этом посте) применена та же идея, но с использованием специального файла в файловой системе. Этот файл называется SN и находится в папке Misc.

Как можно догадаться, SN обозначает «serial number», и каждая копия этого файла должна содержать уникальный серийный номер, который, как и в случае с версией для Commodore 64, записывался во время процесса создания копий, а не при первом запуске, как в то время думали многие. Сегодня можно найти запечатанный диск LCP для Amiga и сделать образ этого гибкого диска, найдя этот файл SN и его уникальное содержимое. Для той эпохи это было впечатляющее достижение, и если бы игра имела успех, мы бы увидели больше подобных проектов. Однако мы говорим о рынке Commodore и Amiga, на котором присутствовала серьёзная проблема: преобладание пиратства ПО.

Из-за огромной популярности пиратства на Amiga большинство детей ни разу не купили игру или программу; они просто копировали диски своих друзей. Как и в современной сфере программного пиратства, где-то в цепочке поставок команда взломщиков убирала оригинальную защиту от копирования и выпускала взломанную версию игры. Без Интернета это в основном происходило через BBS с коммутируемым доступом и при личных встречах.

Thor и Elliott

The Old School Emulation Center, (TOSEC) - это проект каталогизации компьютерного ПО для ретрокомпьютеров и старых аркадных автоматов. Сам по себе TOSEC полностью законен, потому что он не собирает и не публикует ПО, но существуют другие серые с точки зрения закона проекты, в которых можно получить доступ к библиотеке образов ПО, упомянутых в TOSEC.

В индексе TOSEC для Amiga по LCP есть следующие записи:

  • Little Computer People (1987)(Activision)

  • Little Computer People (1987)(Activision)[a2]

  • Little Computer People (1987)(Activision)[a]

  • Little Computer People (1987)(Activision)[b checksum error]

  • Little Computer People (1987)(Activision)[cr ECA]

  • Little Computer People (1987)(Activision)[f AGA HF]

  • Little Computer People (1987)(Activision)[h Drifter]

Можно предположить, что это копии, которые были в обращении в конце 1980-х и начале 1990-х.

Каждая из них (теоретически) немного отличается от других версий LCP. Я запустил каждую из копий и записал различия. Я отмечу каждую версию буквой-суффиксом в квадратных скобках или «NoSuffix» для копии без суффикса.

Здесь полезно будет знать, что было опубликовано две версии LCP – оригинальный релиз с защитой от копирования и более поздний «бюджетный» релиз без защиты. Кроме того, в бюджетном релизе нет случайного значения в файле SN, там установлено одинаковое значение, поэтому игрок не имеет никаких шансов получить уникального человечка (LCP).

Давайте взглянем на таблицу различий копий:

ID

Релиз

Файл SN

Имя LCP

Примечания

NoSuffix

Оригинальный

23510000NVTCA

Tucker

Образ диска неиспользованной копии

a

Оригинальный

22910000NVTCA

Thor

LCP уже въехал в дом.

a2

Бюджетный

32145678NVTCA

Elliott

LCP уже въехал в дом.

b

Бюджетный

32145678NVTCA

Elliott

То же, что и [a2]. По стандарту TOSEC используется суффикс «b», означающий «bad copy».

cr

Оригинальный

22910000NVTCA

Thor

То же, что и [a]. По стандарту TOSEC используется суффикс «cr», означающий «cracked copy».

f

Бюджетный

32145678NVTCA

Elliott

То же, что и [a2].

h

Оригинальный

33900000NVTCA

Floyd

LCP уже въехал в дом.

Здесь важно то, что только «NoSuffix» является копией неиспользованного диска. Так что если вам досталась эта копия на встрече обмена дисками X-Copy, то вам крупно повезло. Даже несмотря на то, что ваш LCP (по имени Tucker) был бы неуникальным, о крайней мере, вы увидели бы, как он вселяется в дом. Если вы хотите поиграть в нетронутую версию LCP, то ищите эту копию.

Во всех других вариантах LCP уже въехал в дом, и не существует никакого задокументированного способа выгнать его или сбросить игру. Судя по найденной в Интернете информации, у большинства людей с копией LCP в те времена был Thor, то есть самым распространённым в обращении был вариант [a]/[cr].

Что за крутой парень?

Как же значение в файле SN влияет на внешний вид и имя LCP? Воспользовавшись сложной аналитической системой (я много раз менял значение и перезапускал игру), мне удалось определить, как используется это значение.

Хотя значение, похоже, может состоять из 8 или менее случайных чисел (см. таблицу выше), я выяснил, что важны только первые три:

Первая цифра управляет типом LCP (и его собаки):

  • 0 или 5 - пожилой лысеющий мужчина

  • 1 или 6 - крутой парень

  • 2 или 7 - мужчина средних лет с усами

  • 3 или 8 - молодой парень

  • 4 или 9 - парень в бейсболке

  • от 0 до 2 - тёмно-коричневая собака

  • от 3 до 5 - светло-коричневая собака

  • от 6 до 9 - серая собака

(То есть первая цифра 3 даст на молодого парня с светло-коричневой собакой.)

Вторая цифра управляет цветом его волос:

  • 0 или 5 - тёмно-коричневый

  • 1 или 6 - блондин

  • 2 или 7 - светло-коричневый

  • 3 или 8 - коричневый

  • 4 или 9 - рыжий

Третья цифра вместе с первой и третьей используется для выбора его имени:

  • В папке Misc есть файл Names, в котором содержится 256 мужских имён. Остаток от деления первых трёх цифр в значении SN на 256 плюс 1 используется как число поиска строки в файле Names, из которой и берётся имя. Например, в варианте [a2] записаны первые три цифры 321. То есть (321 MOD 256) +1 = 66 = Elliott.

Из всех типов внешности LCP для меня был новым крутой парень (Cool Dude). Думаю, большинство людей тоже его не видело.

Часть LCP и их собаки
Часть LCP и их собаки

Добро пожаловать в новый дом

Теперь мы знаем, как управлять внешним видом и именем LCP. Давайте перейдём к тому, как сбросить игру, чтобы персонаж выполнил «процедуру въезда», описанную в руководстве по LCP. Как мы выяснили, это происходит только один раз, при первом запуске игры, и записывается куда-то на диск. После этого при запуске игры персонаж уже будет жить в доме.

В каждой копии LCP есть файл Brain (тоже находящийся в папке Misc) — блоб из 200 байтов двоичной информации, изменяющийся каждый раз, когда LCP выполняет определённое действие, вызывающее «точку сохранения».

Так как в ­«NoSuffix» LCP только собирается въехать в дом, в файле Brain должен быть установлен или сброшен флаг, отличающийся от флага во всех других файлах Brain остальных версий. Однако при беглом изучении этих файлов brain видно, что в большинстве из этих 200 байтов значения сильно отличаются.

Первым делом я попытался обнулить все байты в файле Brain. Я воспользовался этой методикой, ориентируясь на слова Дэвида Крейна (одного из создателей LCP). Однако мне кажется, он просто предполагал, потому что при этом оказывалось, что LCP уже въехал в дом, но очень болен (LCP стал зелёным и быстро лёг в постель). Поэтому я отказался от этой попытки.

Затем я попытался воспользоваться уже имеющимся файлом Brain и постепенно менять каждый ненулевой байт от 0x00 или 0xFF (в зависимости от того, было ли исходное значение больше или меньше 0x80), а затем запускал игру, чтобы посмотреть, что изменилось. Очевидно, что этот процесс на гибком диск или даже на образе ADF был бы очень медленным.

Чтобы ускорить процесс, я воспользовался WinUAE и создал Amiga 500 с эмулятором жёсткого диска SCSI. Я использовал функцию WinUAE, позволяющую привязывать жёсткий диск Amiga со структурой папок Windows. Это позволило мне мониторить изменения в файле Brain в реальном времени. Также это позволило мне легко изменять байтовые значения и быстро перезапускать игру. Так как LCP не любит Fast RAM и запуск из Workbench, я изменил Startup-Sequence, чтобы имитировать то, как вёл себя при запуске оригинальный гибкий диск LCP, а именно убил Fast RAM, выполнив NOFASTMEM, а затем загрузив основную программу LCP, которая называется «pet».

Amiga — это 32-битная машина, поэтому логично будет предположить, что значения файла Brain — это long integer, что подтверждается структурой данных в первой половине файла. Тем не менее, я просто занялся изменением байтов, если только байт не находился на нечётном смещении.

После множества перезапусков я смог сопоставить многие части файла Brain:

Смещение

Назначение

x02

Неизвестно

x13

Неизвестно

x07

Неизвестно

x13

Неизвестно

x23

Неизвестно

x27

Здоровье – пища? 0x00 = болен, 0xFE = полностью здоров

x2F

Флаг болезни: 0x00 = болен, 0x14 = здоров

x33

Здоровье – вода? 0x00 = болен, 0xFF = полностью здоров

x37

Неизвестно

x3B

Неизвестно

x43

Флаг въезда: 0x7A, после процесса въезда 0x00.

x47

Уровень бутылки для воды: 0x00 = пустая, 0x0F = полная

x4B

Еда в буфете: 0x00 = нет, 0x15 = вся
(Это битовая маска: 1=справа внизу, 2=слева внизу, 4=справа наверху, 8=слева наверху)

x4F

Неизвестно

x55

Неизвестно

x57

Неизвестно

x58,x59

Неизвестно

x5d,x5e,x5f

Неизвестно

x66,x67

Неизвестно

x6A,x6b

Неизвестно

x6f

Вызывает «дверное сохранение» при перезапуске: 0x00=выполнить дверное сохранение, 0x01 = дверное сохранение завершено.

x73

Неизвестно, никогда не меняется: 0x3E

x75

Неизвестно, никогда не меняется: 0x30

x76,x77

Неизвестно, всегда сбрасывается обратно на 0x2C11

x60 и далее

Обнуление не влияет на загрузку, но, похоже, вызывает «туалетное сохранение».

x58 и далее

Обнуление не влияет на загрузку.

 

Здесь много неизвестного, но мне удалось найти некоторые важные вещи:

  • Способ восстановления припасов еды и воды. Впрочем, это можно делать и в игре, нажимая Ctrl+F и Ctrl-W, так что особой пользы не несёт.

  • Способ выздоровления больного LCP — очень полезно, потому что «в игре» вылечить больного LCP может быть сложно (на самом деле, почти невозможно).

  • Запуск процесса въезда — именно это мы и искали! Это, а также знание той информации, которую мы получили при изучении файла SN, позволяет каждому игроку получать удовольствие от LCP, как будто он купил свою личную копию.

Кроме того, при каждом сохранении интервал от x58 до xC8 сильно изменяется; в структуре данных есть какой-то паттерн, но я предполагаю, что эти данные задаются на основании показателей личности, в том числе на уровне счастья LCP и его поведения, плюс его предпочитаемых действий. Похоже, обнуление всех байтов в этом интервале не даёт отрицательных эффектов, и первое сохранение (после процесса въезда) переписывает значения серией стандартных «начальных» значений. То есть, похоже, это хороший способ сброса личности LCP. Однако без декомпиляции игры в исходный код мы, мне кажется, не сможем узнать этого точно.

Инструмент управления Little Computer People

Отлично, мы знаем всю эту информацию, но кто будет заморачиваться редактированием этих файлов, если нужно попробовать поиграть новым LCP или исправить текущего? Думаю, что вряд ли многие (кроме меня, разумеется!). Поэтому, следующим логичным шагом стало написание инструмента для выполнения этих действий.

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

При помощи Lattice C v5.0 плюс Lattice Screen Editor и Workbench 1.3 я написал The Little Computer People Management Tool, ссылка на скачивание которого приведена ниже (также я выложил его на Aminet). Хотя я использовал вместо реальной Amiga WinUAE (по логистическим причинам), вся разработка велась на AmigaOS 1.3, как будто на дворе не 2023 год, а 1980-е — знаю, это безумие, но, по крайней мере, я теперь могу сказать, что сделал это сам.

Little Computer People Management Tool для Amiga
Little Computer People Management Tool для Amiga

В инструменте есть три опции, которые можно применить к копии LCP (см. картинку). Также мне удалось уместить на диск и копию оригинального руководства по LCP, его определённо стоит прочитать. Приведённый ниже образ диска основан на варианте TOSEC [a2], то есть в версии исполняемого файла «pet» не было защиты от копирования и она никак не была взломана. Мне пришлось удалить несколько не относящихся к игре файлов (в основном, лишние файлы .info), чтобы освободить место для инструмента и руководства, но во всём остальном файлы оригинальной игры остались нетронутыми. Инструмент загружается при запуске диска, после чего можно запустить LCP как обычно или сначала применить одну из опций модификации.

Можно скачать мой модифицированный ADF Little Computer People для Amiga или только сам инструмент (который также содержит мой ужасный исходный код).

Файлы

  • NewLCPv1.ADF — образ ADF Little Computer People с моим добавленным Management Tool.

  • NewLCPv1.zip — образ ADF Little Computer People с моим добавленным Management Tool, но в виде файла Zip.

  • ModifyLCPToolSrc.zip — инструмент отдельно вместе с исходным кодом.

Комментарии (0)