PickPickPick Четверг, 02.05.2024, 17:43
Приветствую Вас Фермер | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта

Категории раздела
Dangerous Dave [6]

Мини-чат

Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
------------------------
Сегодня нас посетили:
------------------------
------------------------

Форма входа

Главная » Статьи » Dangerous Dave

Dangerous Dave Forever
Dangerous Dave Forever
 
Часть 1: Введение


Запрограммированный двумя Джонами в Id Software, Опасный Дэйв в Особняке с привидениями был выпущен для IBM PC в 1991. Если Вы никогда не играли в Dave 2, Вы наверное думаете, что это очередной платформер в стиле Commander Keen; хорошо, если Вы играли в эту игру, Вы знаете, что это скорее ближе к франчайзу Doom. Том Холл проектировал эту игру для Softdisk’s Gamer’s Edge сразу после ухода из Softdisk и основания студии Id. Благодаря Адриану Кармаку на графике игра показала так много крови (для пиксельной графики конечно), что эта игровая часть должна была быть удалена.

Верно, что 1991 год видел игры с лучшей графикой чем Dave 2. Это был год релиза Another World и Monkey Island. Однако, Id должны были ограничить их игру, чтобы она поместилась в 360 Кб гибкого диска, и запускалась на 286/386 компьютерах с дисплеями EGA. Движок игры, который управляет dd2, как раз перед этим использовался для создания Shadow Knights, таким образом, я полагаю, что независимо от того, что сказано здесь, эта технология также применяется и там.

Я настоятельно рекомендую вам статью Planet Romero’s The Saga of Dangerous Dave ( http://rome.ro/article_saga_dave.htm ) и замечательную книгу Masters of Doom ( http://www.amazon.com/gp/product/0812972155/ ).

С моей историей:

Дэйв всегда был одним из моих любимых персонажей. Я начал проект, когда проснулся однажды с видением для нового эпизода Опасного Дэйва. С той идеей в памяти, я думал, что было бы хорошо начать со спрайтов из оригинального Dave 2, так как я не умею делать пиксель-арт (кто-либо здесь может сделать пиксель-арт?). В ближайшее время я был втянут в это, и всё закончилось тем, что я перепроектировал всю игру. Я раскопал статью на несколько подстраниц, и желаю Вам приятного чтения.


 
Часть 2: Файлы и сжатие


На Вашем гибком диске 360 Кб есть следующие файлы:
  • dave2.exe
  • level01.dd2
  • level02.dd2
  • level03.dd2
  • level04.dd2
  • level05.dd2
  • level06.dd2
  • level07.dd2
  • level08.dd2
  • intro.dd2
  • egatiles.dd2
  • s_chunk1.dd2
  • s_chunk2.dd2
  • s_dave.dd2
  • s_frank.dd2 <—–
  • s_master.dd2
  • title1.dd2
  • title2.dd2
  • progpic.dd2
Я не знаю как Вам, но мне было очень любопытно, кто такой Френк?

Файл запускающий игру — dave2.exe, логика игры никак не сосредоточена на других файлах (ни кодами, ни скриптами). Просматривая файлы hex редактором, я заметил, что большинство файлов начинаются с подписи HUFF. Файлы level%02d, egatiles.dd2 и intro.dd2 — единственные файлы, которые похоже не сжаты. Кроме того они являются наименьшими на дискетке.

Итак, первым шагом было выяснение смысла подписи HUFF. Запустив свой любимый Дизассемблер, я приступил к работе. Найти код, который проверяет наличие этой магической подписи было довольно просто. Я скопировал ассемблерный код в чистый *.c файл, и стал разбираться со смыслом этих мутных циклов. Довольно скоро передо мной были эти замечательные 90 строчек кода, выполняющие декомпрессию по методу Хаффмана, и я безупречно распаковал все *.dd2 файлы с подписью HUFF. Я был поражён, что такое простое сжатие сэкономило ~50% общего объёма, в этом и есть различие между игрой на двух дискетках и на одной. Классно.

Но давайте сделаем этот шаг за один раз…


 
Часть 3: Титульные экраны


Здесь есть фоновые изображения (или титульные экраны), взятые из нашей флоппи дискеты. Все эти изображения были сжаты, используя метод Хаффмана. Код декомпрессии начинается с seg000:7936h, и был весьма хорошим примером для подражания. Понять что это UnHUFF код было довольно просто: у каждого сжатого файла есть подпись «HUFF», я просмотрел строку и только проверил перекрёстную ссылку. Было только одно местоположение, которое имело какое-либо отношение к подписи строки, и эта же самая функция также гласила «Попытка расширить файл, который не является HUFF!» когда ничего не получалось. Так, как они указывали, что X отмечает место.

Переписывать выкачанные алгоритмы, всегда сложно. Даже если Вы знаете, как это должно работать, Вы никогда не сможете быть уверенны, что оригинальные кодеры не изменяли их по какой-либо причине. Когда я добрался до кода декомпрессии, я просто скопировал ассемблерный код в чистый *.c файл. «Привет, меня зовут — Джил, и я — направляюсь к пользователю». Исходный код, который был написан и фактически руководил, выглядел абсолютно ужасным. Имена переменных были названы в честь регистров; у массивов был просто префикс «макет». Я рассмотрел переписывание непонятного кода игры самостоятельно. Вы начинаете с чего-то, что хорошо работает, но плохо выглядит, и Ваша задача состоит в том, чтобы это выглядело хорошо и было читаемым, не нарушая того, что уже работает.

Менее часа я переписывал код дефляции, избавляясь от всех ассемблерных остатков, и как Добрый самаритянин, я даже прокомментировал свой код. После распаковки этих полноэкранных растровых изображений я заметил новый формат файла. Он начинается с «PIC\0», затем следует коротко значное 320, и другое — 200. Остальные 32000 байт — это четыре слоистые битовые плоскости размером 320×200 (EGA нужно любить!)

Кодеры, которые проделали определённую работу с EGA точно знают, как тяжело работать с этими разрядными матрицами. Взглянув на всё это, очень хорошо, что я начал с полноэкранных растровых изображений; это гораздо проще, попытаться и выяснить что происходит на большом растровом изображении, вернее в спрайте с размерами 16×16. С помощью, отличнейшей как швейцарский нож, многообещающей библиотеки PIL (Python Imaging Library), я взломал небольшой скрипт, который преобразует эти 32008 файлы в формат PNG.

Код декомпрессии доступен для скачивания, и называется decompress.c (Ну, Вот!).

 
starpic.dd2
 
starpic.dd2 – отображается как фон для логотипа Gamers Edge
 
progpic.dd2
 
progpic.dd2 — отображает статус игрока во время загрузки
 
title1.dd2
 
title1.dd2
 
title2.dd2
 
title2.dd2
 
Часть 4: Спрайты


Теперь, извлечение спрайтов было очень тяжёлой задачей. После распаковки этих .dd2 файлов, я написал простой скрипт, который преобразует эти выходные данные во что-то видимое. Я не мог сделать многое из того, что появилось у меня на мониторе. Размышляя, я заметил кое-что интересное: кроме мусора, который в настоящее время занимает большую часть экрана, верхние левые 24×32 пиксели действительно имели смысл!

Они создавали несколько искажённое изображение Дэйва. Цвета также были неправильными, но это означает, что мое начальное предположение о смещении разрядной матрицы EGA было ошибочным. Я снова покопался в разобранном коде, и заметил, что первые 2 байта из выкачанного файла спрайта были использованы в функции, которую я ранее назвал «put_ega_tile». Я вернулся к своему скрипту, и попытался использовать это магическое число в качестве расстояния между разрядными матрицами.

Вуаля! Это работает! Теперь мне удалось увидеть чёткое изображение Дэйва, охватывающее более 16 спрайтов. Это по-настоящему замечательное ощущение, не имея ничего до этого, вдруг увидеть что-то, что отображается должным образом. Следующие спрайты были искажены; я мог видеть, что они имели правильные цвета, и пиксели имели некоторый смысл в небольших блоках, но общее представление было полным дерьмом. Затем это поразило меня — Эти спрайты не имели одинаковых размеров, я умножил байты на разрядную матрицу по 4 (2^4 = 16 цветов), и это было точно таким же как выкачанный файл. Это может означать только одно: размеры спрайтов не хранятся в файлах спрайтов, они находятся в исполняемом файле.

Наблюдая, я вспомнил о некоторых забавных строках в исполняемом файле, таких как «DAVESTANDE», я просмотрел его снова и обнаружил, что Seg005 была полна ими; 10-байтовые строки, а затем несколько коротких 16-битных. Так как я знал, что первым спрайтом был Дэйв в стоячей (ожидающей) позиции, я полагал, что следующие короткие были шириной (разделённой на 8px), и высотой (в пикселях). За ними следовали ещё несколько коротких, но они не представляли интереса для меня. Я предполагаю, что они находятся на горячей позиции, файловое смещение или что-то в таком духе. Таким образом, я решил, что будет только проще найти размеры спрайтов простым методом проб и ошибок. Я просто угадывал размеры: если всё было правильно, я видел правильный спрайт; в противном случае было видно искажённую кучу тайлов. Я знаю, что это может показаться странным и глупым, но мне действительно, потребовалось 5 минут, чтобы получить остальную часть спрайтов.

view-sprites.py создаёт PNG для каждого спрайта дескрипторного файла; он блитирует (копирует битовый массив) все спрайты горизонтально друг рядом с другом. Вы можете нажать на миниатюры ниже и получить полные 1:1 дампы.

 
s_dave.dd2
 
s_dave.dd2
 
s_chunk1.dd2
 
s_chunk1.dd2
 
s_chunk2.dd2
 
s_chunk2.dd2
 
s_frank.dd2
 
s_frank.dd2 (<— это Френк!)
 
s_master.dd2
 
s_master.dd2
 
Часть 5: Уровни


Как и большинство платформенных игр, Опасный Дэйв использует тайлы, чтобы сэкономить память и сохранить отпечаток маленьким. Все уровни используют одну и ту же карту тайлов, которая хранится в несжатом виде в файле под названием egatiles.dd2. Тайлы хранятся последовательно в независимости друг от друга 16 x 16 пикселей, тайлы составляют 4 бита и записаны с чередованием EGA изображения. В этом файле нет заголовка, и тайлы не помечены или индексированы в любом случае. В дампе ниже, Вы можете увидеть 13 тайлов в одной строке, что приводит к ширине 208 пикселей; это магическое число, я просто предполагаю, поскольку это красиво смотрится. Взгляните на тайлы, и Вы увидите, что несколько тайлов отмечены текстом «FREE», другие — просто пустые ячейки, и некоторые даже не используются в игре.
 
egatiles.dd2

Дескрипторы уровней — это небольшие файлы с названием level%02d.dd2, есть 8 таких файлов, следовательно, только 8 уровней. Каждый файл сжат, используя RLEW, который является RLE сжатием, что работает над 16-ти битными словами.

0000000030: 4A 00 FE FE 27 00 33 00 ? 4A 00 FE FE 04 00 33 00

Очень просто, при поражении 0xfefe магией, следующее слово — это количество, за которым следует значение. Замените эти 3 слова значением x подсчёта и всё готово.
Вот первые 0×50 несжатые байты из первого уровня:

0000000000: 20 39 00 00 40 00 39 00 ? 02 00 00 00 00 00 50 00
0000000010: 2a 00 80 1c 80 03 80 36 ? 80 60 81 40 83 80 86 0c
0000000020: 80 04 84 60 33 00 33 00 ? 33 00 33 00 33 00 33 00
0000000030: 33 00 33 00 33 00 33 00 ? 33 00 33 00 33 00 33 00
0000000040: 33 00 33 00 33 00 33 00 ? 33 00 33 00 33 00 33 00

Байты 0×00 — 0×03: Размер распакованного файла (не должно быть 0xfefe:))

Байты 0×04 — 0×05: Ширина уровня в тайлах (16 пикселей)

Байты 0×06 — 0×7: Высота уровня в тайлах (16 пикселей)

Остаток уровня разделён на две части, видимую (восстанавливаемую) секцию, и магические локации (для монстров, старт и выход, бонусы и двери). Эти две секции в точности по ширине и высоте — 16 бит каждая. В видимой секции каждое такое 16-битное слово символизирует показатель в линейной карте тайлов. Вот некоторые магические числа из второй секции, эти значения были получены методом проб и ошибок. Я не тратил на это слишком много времени, но идея должна быть ясна:

Тег 0×0001: Зомби
Тег 0×0002: Старушка с ножом
Тег 0×00ff: Первоначальное положение игрока (точка входа)
Тег 0×0010: 400 очков
Тег 0×0013: 1UP
Тег 0×0633: Телепорт 1
Тег 0×0a06: Телепорт 2
Тег 0×8001: 100 очков внутри шкафа

Скрипт level-to-png.py растрирует ранее распакованный уровень с помощью unpack-level.py. Перед вами первый уровень; Вы можете заметить, что некоторые тайлы никогда не видны на экране. Имеется также изменённая ( http://www.flickr.com/photos/gawd0r/148617410/ ) копия, которая была сделана, используя свой собственный редактор уровней.

 
level01.dd2
 
level01.dd2 (hi-res)
 
Часть 6: Подождите, чего-то не хватает


Что-то явно отсутствовало! Я просмотрел файлы снова, как я мог это пропустить?? Этого просто там не было!

Всякий раз, когда Дэйв умирал, он делал это в стиле: в центре экрана появлялась очень маленькая анимация, которая показывает, что Дэйва бьют, высасывают плоть, сжигают, четвертуют или убивают в той или иной форме. Каждая такая последовательность анимации состоит из 5-ти кадров, с задержкой ~ 500мс между ними. Причина, по которой я не смог так просто найти эту графику, состояла в том, что у неё нет своего собственного файла с данными. Данные были встроеные внутрь исполняемого файла, по очевидной причине: .exe файл фактически сжат с помощью PKLITE (подпись LZ91). Это сжатие намного сильнее чем сжатие Хаффмана, используемое для фонов, и так как эта графика необходима для каждого уровня, я предполагаю, это имеет смысл, что она была размещена внутри исполняемого файла.

Я называю это «the-death-of-dave»:

 
Embedded animations
 
Часть 7: Что дальше запланировано для Дэйва?


Как я уже упоминал ранее, я увлечён созданием новой игры о приключениях Дэйва. На сегодняшний день существует 7 игр об Опасном Дэйве, но никто не говорит о них.

Я говорю о игре, которая показывает холодную индивидуальность Дэйва с уровнями в стиле Metal Slug и боссами как в Castlevania, и конечно же число жертв и разбрызганной крови — нечто вроде могучей Уличная борьба пиратского ребёнка 2006 ( http://video.google.com/videoplay?docid=-5208311714700987326&q=Pirate+Baby# ) Пола Робертсона.

У меня есть несколько идей, назревающих в ближайшее время. Я ищу людей с сильным желанием к созданию игр. Если Вы — графический либо фоновый художник или делаете пиксель-арт, будьте уверены, Вы свяжетесь со мной.

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

Эти программы используются и упоминаются в статье:
  • decompress.c — выкачивает «HUFF» файлы
  • unpack-level.py — распаковывает RLEW, используемый в level%02d
  • level-to-png.py — изображает уровень (в зависимости от unpack-level.py)
  • show-tiles.py — конвертирует EGATILES.DD2 файл в PNG
  • pic2png.py — конвертирует «PIC» файл в PNG (в зависимости от decompress.c)
  • view-death-sequences.py — конвертирует встроенные анимации в PNG
  • view-sprites.py — конвертирует спрайты в отдельных PNG (в зависимости от decompress.c)
  • ega_palette.py — EGA палитра, требуется для большинства скриптов
Код распространяется в соответствии с GNU Public License (GPL). Если вы внесли какие-либо изменения, пожалуйста, сделайте их общедоступными. Я хотел бы также получить известие по электронной почте.

Я даже написал немного кода для редактора уровней. Не знаю почему, но я работал над этим. Как я уже говорил, эта игра поместила в меня магическое заклинание. В любом случае, нажмите по картинке для просмотра полного размера.

 

Ура!
– gawd, 2006

 
Переведено на русский язык: Aspirin при поддержке Dangerous Dave Community™ в 2011 году.
Источник: http://www.megidish.net/museum/dangerousdave/part-1-introduction/

Категория: Dangerous Dave | Добавил: Aspirin (08.02.2011) E W
Просмотров: 5347 | Теги: Dangerous Dave Forever | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск

Друзья сайта
------------------------

------------------------

------------------------

------------------------

------------------------

Все материалы и товарные знаки, размещенные на сайте, принадлежат их владельцам и предоставляются исключительно в ознакомительных целях.
При размещении материалов сайта на любых ресурсах, настоятельно рекомендуется указать ссылку на сайт правообладатели и/или автора материала!
© 2010–2024 Сайт управляется системой uCoz