Info Guide #09
31 июля 2006

Gamedev - История создания игры Ball Quest.

<b>Gamedev</b> - История создания игры Ball Quest.
  Как делался Ball Quest
Alone Coder 

   Идея этой игры (тогда ещё без названия)
заползла в мою больную голову 16 мая,после
того, как не состоялся ожидавшийся на май─
ские праздники натиск на v9990. Дикая идея
была отправлена Shiru Otaku, и 20-го числа
Shiru выслал мне для экспериментов пробный 
набор  спрайтов мячика (достаточно большие
- 64x64,- чтобы  я  мог  попробовать подо─
гнать размер). Я покрутил так и эдак и ре─
шил,что надо 24x24. 23-го Shiru переренде─
рил  мячик  в 24x24 (надо соблюдать размер
при рендеринге,поскольку при масштабирова─
нии  может появиться окантовка), и процесс
медленно пошёл.
   Shiru: Если по-хорошему, то надо соблю─
дать размер ещё при моделинге.Швы и шести─ 
угольники  на  мячике  я сделал геометрией 
(есть  простой способ, проще, чем рисовать 
текстуру) и выбирал  их  размер, чтобы они 
смотрелись нормально в 64x64.Поэтому после 
пере-рендера в 24x24 швы почти исчезли.Ко─ 
нечно,надо было перемоделить заново, но не 
дошли руки. 
   Alone: А по-моему, мячик  и так  вполне
хороший, перемоделивать не надо. 
   Сначала  я  организовал  в  движке Pang
возможность  смены координат камеры (чтобы
шарик был в центре). Потом нарисовал стен─
ки, алмазы,стрелочки,EXIT и вылетающие ци─
фры, набросал  в исходнике тестовую карту.
К 13 июня уже была готова физика, сконвер─
чен  один  небоскрёб, подобрано  несколько
звучков (на  звуковом движке Wolf2004/Pang
16C ).И придумано название - Ball Quest. В 
принципе,работы тут было не на три недели,
а на три дня.
   15 июня  я перебрался в Москву к Shiru,
 где мы почти сразу выяснили следующее:
  1. Нерелизенной  музыки  не хватит на 10
уровней,даже если доделать недоделки.Кроме 
нерелизенной  есть недорелизенная, но пло─ 
 хая. 
  2. Подходящего редактора для карт такого
 вида нет, надо писать. 
  3. Надо исправить клипирование в АТМовс─
 кой версии движка. 
  4. Трудновато найти фотографии небоскрё─
бов с приличной высоты  и с горизонтальным 
направлением взгляда. 
   Редактор  Shiru наваял довольно быстро,
с редактированием  по тайловому принципу и
сохранением  в нужном  для  игры формате с
координатами. Но выяснилось, что не только
мы, но и зашедшие в гости CHRV, Максагор и
Wlodek - никто  не любит придумывать уров─ 
ни! Совместными с Shiru усилиями...
   Shiru: Мои  усилия заключались в наблю─
дении за сочинением ;) 
...к концу недели мы сумели сочинить толь─
ко три штуки, которые,впрочем,из нас двоих
прошёл  только я :)) (Тогда игра умела ра─
ботать только в режиме FAST GAME,и я хотел
релизить её именно в этом виде.)
   Фоновые картинки мы искали по интернету
три раза. Половина найденных картинок либо
была снята с плохим ракурсом,либо выложена
с плохим разрешением, либо некрасиво смот─
релась  в 16 цветах. И стало  ясно, что 10
хороших уровней у нас получится вряд ли...
   Отдельной проблемой оказалась начальная
заставка. По  проекту  там должен был быть
изображён  мячик, лежащий  в траве на фоне
небоскрёба. Однако  эксперименты показали,
что  отрендерить  красивую траву не так-то
просто. Shiru  с ходу отмёл идею позаимст─
вовать  мячик у соседей  и сфоткать его во
дворе.
   Shiru: Старушки-соседки  вряд ли согла─
сились бы расстаться,даже на время,со сво─ 
им футбольным инвентарём! 
   Взамен  он  запустил  поиск  в инете на
"ball grass"  и нашёл на visualparadox.com
почти то, что требовалось - только на фоне
футбольных ворот. Текстура травы была дос─
таточно  хороша, но  количества оной травы
явно  не хватало. Shiru размножил её копи─
рованием и штампами,передвинул мячик,убрал
задний план и поставил вместо него одно из
забракованных высотных зданий (забракован─
ное потому,что было сфотографировано с зе─
мли). Дальше стало интереснее:я обнаружил,
что мячик получается терпимо только с dia─
mond штриховкой, а трава - только с Floyd.
Поэтому  пришлось каждый объект конвертить
отдельно,а потом склеивать. И потом до ко─
нца июля мы по очереди чистили получившую─
ся картинку - и в интересах красоты, и для
экономии памяти (она всегда в памяти;впро─
чем,можно было подгружать). Например,верх─
няя часть травы размыта вручную. Блок окон
в левой части здания тоже нарисован по пи─
кселям.
   Но  заставка - это  ещё не весь дизайн.
Надо  было  придумать  и игровую панельку.
Предложение сделать её в виде сыра (инфор─
мация - в  дырках) Shiru отверг, поэтому я
решил сделать её в виде поезда (информация
- в окнах).
   Shiru: Мне не понравилась идея  с сыром
тем,что сам по себе сыр ничего не символи─ 
зирует. Поезд - ещё куда ни шло,ассоциации 
с путешествием. 
   После  очередного  копания  в интернете
был найден всего один приличный вагон,сня─
тый почти в профиль - на сайте московского
метро. Shiru, оглянув  сей  шедевр, изрёк:
"ничего из этого не получится". Но он ока─
зался  не прав! =)) Чтобы развернуть вагон
вдоль экрана, я натравил на картинку трёх─
мерное преобразование.Далее обычная опера─
ция обкусывания фона, замены цветов,подго─
нки  под нужный размер (в том числе окна -
под знакоместа) - и вуаля!
   И тут выяснилось, что панельку надо на─
ложить  на все фоновые картинки. Ведь кар─
тинки  грузятся прямо в экранную область и
там же разворачиваются (см.статью про Pang
в прошлом номере).Альтернатив хранению па─
 нельки в картинках было всего три:
  1. Иметь её на экране всегда, даже в ме─
 ню; 
  2. Хранить её в верхней памяти (надо ли─
 шних 4k ОЗУ); 
  3. Постоянно её подгружать.
   Нельзя было сохранить панельку на неви─
димом экране,т.к.во время распаковки любой
картинки  он становился видимым, и было бы
некрасиво. Хотя...
   Но я решил не усложнять задачу,чтобы не
превращать  проект в долгострой. Была даже
надежда на завершение игры прямо в Москве.
У меня дома всё пишется гораздо медленнее.
   И вот, решив  накладывать  панельку  на
пейзаж, я осознал,что надо сейчас же доде─
лать панельку окончательно, чтобы потом не
пришлось  по  второму  разу конвертировать
все пейзажи.(Забегая вперёд,скажу,что всё-
таки  пришлось! После  того, как  я уехал,
Shiru  лишний  раз  почистил её от шальных 
пикселов, оставшихся после конверсии и из─
бежавших моей чистки.)
   Я настроил  в исходнике игры координаты
чисел,и Shiru взялся рисовать надписи типа
"LIVES". Заодно  он нарисовал два шрифта -
один  мелкий, для  обычных  нужд, а другой
крупный, но  неполный - для сообщений типа
"LEVEL COMPLETE!". В запаснике у него наш─
лась  утилитка  для  разбиения картинок на
тайлы,и он разбил с её помощью все крупные
надписи на неповторяющиеся знакоместа. Так
была сэкономлена куча памяти.Полученный на
выходе той утилитки длинный-предлинный bmp
я сконвертировал на ZX так же,как спрайты,
только  исправив  несколько  строчек в том
конверторе.
   Shiru: Хотя эта утилита умела также со─
ставлять список  номеров  тайлов, она была 
написана  немного  для  других  целей (под 
другие  размеры изображений), поэтому спи─ 
сок номеров AlCo пришлось составлять вруч─ 
ную, при  помощи  ручки, бумажки и зоркого 
глаза. Потеряли лишние полчаса, но исправ─ 
лять утилиту было бы дольше. 
   Всю  музыку для игры делал Shiru. Музы─
ка, к сожалению,не оригинальная - в основ─
ном это ремиксы известных тем с приставок,
исключение  составляет  трек 2-го уровня -
он заремиксен с живой музыки. Проблема бы─
ла  в том, что Shiru пишет исключительно в
Vortex Tracker'е, и пересадить  его  в Pro 
Tracker не удаётся. 
   Shiru: В PT я писал бы медленнее,привы─
чка - страшная сила. Для меня создание од─ 
ного  кавера в VT - дело нескольких часов, 
особенно  если  под  рукой  есть набранная 
кем-нибудь  ранее  midi-шка с мелодией (их 
полно  в  интернете, из  игр  -  на  сайте 
vgmusic.com ). 
   В VT  один TS музон - это 2 модуля, а в
PT - 1 модуль. К моменту  начала работ над 
игрой  я  уже успел перевести два музона в
формат  PT (один из них несколько даже ис─
правив).И TS плейер для PT уже был.Поэтому
я решил  перетащить на PT и остальные ком─
позиции. Это  задача вовсе не тривиальная,
поскольку  два набора сэмплов и орнаментов
надо сводить к одному, исправляя цифры и в
самой мелодии...
   Звуковые эффекты мы реализовали с помо─
щью  нового пакета AY Sound FX Editor (ре─
дактор звуковых эффектов для AY на PC, под
Windows ),который Shiru написал в феврале- 
мае. К нему  прилагался плейер и несколько
наборов звуков, из которых мы выбрали нуж─
ные. Для многих событий там было по неско─
лько звучков-кандидатов, но некоторые дру─
гие  звучки  всё-таки пришлось нарисовать:
удары, падение, подсчёт очков.
   Shiru нарендерил анимацию пяти объектов
(вишенки,гиря,бутылка,ключ,часы).Я выбирал
из последовательности  нужные кадры и кон─
вертировал  их в Photoshop'е следующим ме─
 тодом.
  1. Загружаем  первый кадр, клипируем его
(масштаб  надо было указать ещё при ренде─ 
ринге! Желательно и клипирование произвес─ 
 ти тогда же). 
  2. Конвертируем (штриховка - по вкусу; у
нас - без)  в адаптивную  палитру  из 8-10 
цветов (редко  надо больше). Сохраняем эту 
 палитру под названием "from.act". 
  3. Исправляем  цвета  в  этой палитре на
ближайшие к ним спектрумовские,кроме фоно─ 
вого, который надо выбрать нестандартным - 
допустим,иссиня-фиолетовым. Полученную па─ 
 литру сохраняем как "to.act". 
  4. Конвертируем в RGB,потом в спектрумо─
вскую палитру,в которой 0-й цвет равен то─ 
му,нестандартному. Пусть эта палитра лежит 
в файле "zx.pal". Сохраняем картинку (вер─ 
сия  Photoshop, которая стоит у Shiru, по─ 
чему-то  виснет при сохранении indexed co─ 
lor картинки  поверх RGB картинки с тем же 
 названием). 
  5. Повторяем всё это со всеми остальными
картинками,НО УЖЕ ИСПОЛЬЗУЯ ГОТОВЫЕ СОХРА─ 
НЁННЫЕ ПАЛИТРЫ.Можно воспользоваться фото─ 
шоповской  системой макросов (я воспользо─ 
вался). 
   Потом, в процессе перекапывания коллек─
ций  Shiru, я обнаружил одного замечатель─
ного паучка,отрендеренного Surfin' Bird'ом
(тем  самым, который  нарисовал  графику к
Fire & Ice  и отрендерил АТМ в корпусе под 
орех :)). Я покрасил паучка в красный цвет
и тоже внёс в игру.
   Ещё  несколько  объектов  (проломленная
доска, стекло,разбитое стекло) я нарисовал
по пикселям.В общем,мы штамповали графику,
пока не кончилась страничка памяти,зарезе─
рвированная под спрайты :) Можно было про─
должить в другой страничке, но это грозило
отказом от чего-нибудь другого.Мы даже от─
кусили половину фаз ключа.
   Редактирование  уровней шло вяло. Чтобы
ускорить  их проверку, Shiru организовал в
своём  редакторе  запись  в формате хобеты
(её  умеет  грузить Unreal Speccy, правда,
забывая при этом имя текущего trd-шника).
   Shiru: Добавление файлов в trd-шник, со
всеми проверками, было бы существенно сло─ 
жнее (то есть дольше,что было принципиаль─ 
ным  моментом), поэтому  от этого варианта 
я  отказался. Позднее  для  решения подоб─ 
ных  задач  я написал  специальную утилиту 
trdtool, она есть на Virtual TR-DOS. 
   Уже  собираясь уезжать, я врубился, что
время уровня должно лежать в самом уровне,
а не в программе.Эту функцию Shiru добавил
за последние минуты, заодно переведя гото─
вые уровни в новый формат.
   Итак, я отъезжал 20 июня в Рязань,имея,
по  большому счёту, набор конвертированных
фонов, 3 уровня, редактор  и почти готовый
исходник игры,который в режиме АТМ почему-
то  отказывался  грузить второй уровень по
прохождении  первого. И  при  всём  этом я
очень хотел спать!
   Было  видно, что всю неделю мы работали
эффективнее, чем  в  прошлый  раз (январь,
Time Gal ), но  игру  всё-таки доделать не 
успели.
   После долгого отсыпа (в течение которо─
го Shiru наремиксил ещё 2 трека) я нарисо─
вал  один уровень по идее Shiru (4) и поз─
вал John'а помочь. Один уровень мы сделали
вместе (5), ещё два он набросал на бумажке
(6,7). John настраивал уровень 4 так,чтобы
сам  мог  пройти  его только с 10-й - 20-й
попытки (а он играл в режиме SLOW GAME). Я
еле убедил его не издеваться над игроком:)
Когда John пришёл в следующий раз, его бу─
мажные  уровни  уже были готовы. Я показал
ему результат и заодно нарисовал последний
уровень (8), но John уже потерял интерес и
смотрел по сторонам :(
   Далее  я  в  основном  отлаживал  игру,
тестировал  и причёсывал (добавил  бегущую
строчку,кэш,отклеил мячик от фона - раньше
он был всегда точно в центре экрана). Тес─
тировать помог Максагор. 2 августа я успе─
шно (кажется) завершил  этот процесс и за─
бил  остаток  памяти  демками прохождения.
Демки  -  это  последовательность  нажатий
клавиш. Можно было пожать их через RLE, но
влезло и так... Впритык, правда...
   5 августа пришёл John и исправил трек к
4-му уровню.
   Дальше я только оформлял исходники.

              Об исходниках

   В движке  по сравнению с Pang'овским вы
можете обнаружить следующие важные улучше─
 ния:
  - Появилась  поддержка  кэша. Там  лежат
основные циклы вывода и стирания спрайтов. 
 В АТМ версии кэш тоже поддерживается! 
  - Спрайты, лежащие  в нижней  памяти, не
копируются перед использованием (это брев─ 
 но и бетонная плита). 
  - Спрайт, который  перед  тем был только
что скопирован в нижнюю память, не копиру─ 
 ется снова во 2-й, 3-й и т.д. раз. 
  - Копирование производится LDIR'ом,лежа─
щим не в ОЗУ, а в ПЗУ/кэше. В турбо-режиме 
ПЗУ  и  кэш  работают  существенно быстрее 
 ОЗУ. 
  - На АТМ организовано клипирование снизу
(макрос D31 ). Высота игрового окна должна 
 делиться на 32. 
  - При построении списка выводимых спрай─
тов учитывается их высота (ID объектов ра─ 
збиты  на несколько групп в зависимости от 
размера - в следующий  раз  надо будет по─ 
пробовать  читать  высоту из самого спрай─ 
 та). 
  - Предусмотрено  отключение всех режимов
и восстановление состояния vTRDOS  на вре─ 
мя  дисковых  операций  (процедуры  VTRON, 
 INIATM). 
  - Шрифт теперь 16-цветный.Плюс добавлена
 печать больших сообщений спецшрифтом. 
  - Можно убрать (метка re) сохранение эк─
рана под спрайтами  и  все соответствующие 
буфера. Это сохранение не нужно для многих 
видов игр, например, для стратегических. 

   Коллизии  организованы  следующим обра─
зом. Имеется  карта (BMAP) 64x64, по байту
на знакоместо. Вне границ уровня эта карта
не действует - считается, что снаружи пус─
то. В карте проницаемые знакоместа обозна─
чаются 0. Призы  обозначаются 2. Препятст─
вия обозначаются числами от 3 до 255. Каж─
дое  такое  число - номер  юнита  в списке
юнитов  уровня  (эти номера не меняются по
ходу игры, т.к. в BQ юнит при удалении фи─
зически  не  удаляется, а  превращается  в
IDerased).Мячик постоянно проверяет неско─
лько  знакомест внутри себя. Его поведение
(процедура BOUNCE) зависит от того,с какой
стороны он чувствует препятствие. Тип зву─
ка столкновения определяется типом препят─
ствия (номер юнита в BMAP нужен только для
этого;можно было взамен положить сам тип).
Разрушение препятствия - там же. Громкость
звука зависит от скорости мяча.
   Обратите  внимание  на управление мячом
(CPlrf). Оно  работает только во время ка─
сания  стен/пола/потолка (признаки генери─
руются в BOUNCE). Точнее,не только во вре─
мя, но  потом  ещё один раз через 2 фрейма
(в SLOW GAME - через 4). Это сделано,чтобы
опытный  игрок  смог более хитро управлять
движениями.

              Разбор полётов

   Что было сделано правильно:
 

  1. На  момент  начала  совместной работы
уже имелся движок,конверторы,половина объ─ 
 ектов и физика. 
  2. Было много запасной музыки (полунедо─
писанной  и  недополурелизенной). В случае 
цейтнота  успели  бы  вставить  garbage (к 
 счастью, не пришлось). 
  3. Редактор эффектов Shiru написал очень
кстати, и  эффекты  с MSX были сконверчены 
 тоже очень кстати. 
  4. Я успел ещё раньше переделать Mr Gluk
Reset Service и ALASM под АТМ, и это весь─ 
ма помогло. Впрочем,можно было (как в слу─ 
чае Pang) писать в конфигурации Pentagon с 
фальшивым  значением в порту #eff7, но по─ 
том всё равно пришлось бы возиться с адап─ 
 тацией под АТМ, удобство так и так нужно. 
  5. Весь набор программ имелся на компью─
тере,не пришлось,как в прошлый раз, качать 
 Delphi ;))) 
  6. Ничего не пришлось изучать в процессе
(в прошлый  раз  приходилось на каждый чих 
водить пальцем по талмуду Максагора об ар─ 
хитектуре АТМ turbo 2+ и по pdf-кам с ATA/ 
 ATAPI/CD-ROM/CDFS стандартами). 
  7. Был опыт совместной работы.

   Что было сделано неправильно:
 

  1. Надо  было  посидеть  вместе ещё один
день, точнее ночь - до последнего утра мо─ 
его отпуска (хотя у меня тогда был бы риск 
опять проспать поезд, как в прошлый раз) и 
всё-таки нарисовать уровни.Так была бы на─ 
 верняка сэкономлена целая неделя. 
  2. Плейер  эффектов, прилагавшийся  к AY
Sound FX Editor'у, был  не вполне  готов - 
его пришлось доделывать на лету (последний 
фикс  я вносил  уже дома). Впредь этого не 
 повторится, плейер теперь исправлен. 
  3. Не  надо было исправлять клипирование
на месте - я внёс из-за этого глюк,который 
потом долго искал - аж по распечатке! Надо 
было заниматься этим клипированием дома, в 
 спокойной обстановке, до или после. 
  4. Один  компьютер  на  двоих - всё-таки
маловато :) В прошлый раз получалась одно─ 
временная  работа - один  кодит/конвертит, 
другой в это время тестирует на АТМ. Хотя, 
конечно, размышления  лёжа на диване - это 
 тоже работа... 
  5. Из-за Pang'овской системы "1 файл = 1
спрайт" на рабочем диске накопилось аж 125 
файлов. Постоянно  приходилось делать MOVE 
(хорошо,что в ALASM'е есть MOVE),а графику 
переносить  на  диск по частям (т.к. после 
конвертации .bmp  появляется один файл .C, 
и  ещё  один - после  упаковки этого .C, а 
стираю я  этот .bmp  и этот .C только пос─ 
ле).  Надо  было  организовать  контейнеры 
спрайтов и сделать 2 рабочих диска (диско─ 
 вод A: - исходники,дисковод C: - ресурсы). 
  6. Копирование файлов через ESN было не─
удобно - после  его запуска (а не выходить 
из  него нельзя - он страшно греет процес─ 
сор)... 
   Shiru: Возможно, это проблемы моего из─
лишне горячего P4. 
... приходилось  долго переходить к нужным 
каталогам, а мы даже не приблизили эти ка─ 
талоги друг к другу. В SN была функция бы─ 
строго перехода (через Alt+цифра),но в ESN 
 её почему-то выкинули. 
  7. Конвертирование  рендеренных анимаций
через  Photoshop - долго  и нудно. Если бы 
было нарендерено не 7 объектов,а 70,да ещё 
и не по 4-8 фаз, а по 16-32, то это был бы 
капец. Нужна утилита,которая бы конвертила 
анимации и заодно кидала полученные конте─ 
йнеры спрайтов на рабочий диск с графикой, 
чтобы  не запускать этот дурацкий ESN. Бо─ 
нус был бы,если бы таблицы персонажей (где 
лежат  их  метки-названия, число фаз и всё 
такое в этом духе) составлялись  в этой же 
 утилите и сохранялись в формате ALASM. 
  8. Загрузку  уровня  надо  было написать
заранее.А не искать на месте часами,почему 
АТМ  не  грузит, и не выяснять лишний раз, 
какой  экран  надо включить, чтобы юзер не 
 видел левоту. 
  9. В редакторе уровня  были неудачно по─
добраны горячие кнопки (NumPad). Они так и 
не пригодились. Ещё в редакторе не хватало 
фичи: при  переключении объектов надо сде─ 
лать текущим тот тип объектов, объекты ко─ 
 торого мы щёлкаем. 
  10. Как-то раз потребовался STS. А пере─
делать под АТМ я его не успел.Надо переде─ 
 лать (сделать в ПЗУ резиденты для этого). 
  11. Не  нашли  человека, который  мог бы
качественно почистить конверченные картин─ 
 ки, пока мы занимались другими делами. 
  12. Ходили тут всякие - типа посмотреть,
как  мы  игру пишем :) Какая там писанина, 
когда гости нагрянули! 



Другие статьи номера:

Ликбез - Аккумуляторы. История, типа преимущества и недостатки.

Ликбез - Аккумуляторы. Практическое применение различных типов.

Inferno - Авторы журнала.

Gamedev - История создания игры Ball Quest.

Gameland - Описание игры Ball Quest.

Others - Двенадцать приёмов литературной полемики или Пособие по газетным дискуссиям.

Others - Вопросы о музыкальной консерватории.

For Coderz - Предложения по улучшению дисковых утилит.

Inferno - Вступление от редактора.

Ликбез - Распространённые приёмы неверного аргументирования и просто логические ошибки.

Звук - Ламповые усилители. Стерео лампочник 2х5 Вт из старых телевизоров. Часть 2.

Ремонт - Ремонт магнитолы Panasonic.

Inferno - Письма в редакцию.

Реклама - Реклама NedoPC.

Inferno - Об оболочке.

Others - О спортивном ориентировании.

Железо - История одного пентагона 1024SL.

Ликбез - Характеристика p-n переходов при слабом токе.

Ремонт - История ремонта принтера DAEWOO DP-2210.

DIY - Схема защиты компьютера от перенапряжения.

Sofтинка - Музыкальный редактор Pro Tracker v3.7. История изменений.

Sofтинка - Архиватор ZXRar v0.29. История изменений.

Реклама - Реклама от King Of Evil.

Реклама - Реклама от В. Богдановича.

Others - О роликовых коньках. Выбор, тоерия езды.

Others - О автоматах-рулетках в игровых клубах.

Inferno - О воксельном летающем слоне IG #5.

For Coderz - О сортировке элементов массива.

Others - Системный диск Alone Coder'а.

Gamedev - Ответы на вопросы по поводу игры Time Gal.

Gameland - об игре Time Gal, первой CD-игре для ZX!

Sofтинка - Video Player для ATM.

Будущее Спектрума - Размышления об игровой приставке ZX-Box на основе Spectrum'а.

Будущее Спектрума - Диалоги об игровой приставке ZX-Box на основе Spectrum'а.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Spectrum программинг - Быстрые 3D-расчеты: продвинутый алгоритм.
Смайлик - подборка смешных анекдотов.
User Group - Текстовые редакторы.
Post scriptum - C Ya! Viva el Speccy!
Терминалка - Что такое модем - Как правильно настроить программу MMD для нормальной и удобной работы.

В этот день...   16 апреля