Записки старого игруна

Elite 4: Dangerous
hipilion
Предисловие
Когда я был маленький, у меня был клон ZX Spectrum 48 и на нем я заигрывался в игру ELite. Вся страна заигрывалась.
Ну а как на "зависнуть" в такой игре, ведь до неё ничего подобного не было:
Настоящие полеты между звезд, в полноценном 3d, а не как в плоских стрелялках.
Возможность лететь куда угодно, делать что угодно и быть кем угодно.

Со временем, конечно, эйфория от таких возможностей проходила и выяснялось, что все звездные системы выглядят одинаково: звезда + одна планета + одна станция, а отличаются только некоторыми параметрами. Так-же выяснялось, что сам игровой процесс достаточно однообразен и прост: Взяли товар в одном месте, продали в другом и так много-много раз, попутно можно было отстреливать пиратов, которые и так постоянно нападали, можно было ещё побыть пиратом, но жизнь пирата - кортка и полицейские viper'ы все равно побеждали. Некоторые отправлялись искать легендарную RAXXLA'у, корабли поколений и прочие легендарные вещи. Но в конце концов игра надоедала и им.
И тем не менее Элита была колоссальным прорывом для своего времени.


Потом, когда у меня появился домашний ПК, а потом и доступ в интернет я естественно отправился его исследовать и наткнулся на портал http://homeoftheunderdogs.net, где можно было скачать многие старые игры.
Помимо многих разных игр, мною была скачана и Frontier: First Encounters, она-же Elite 3.
Не скажу, что игра сразу мне "зашла". Уж очень непривычна она была по сравнению с 1й частью. Однако спустя несколько попыток в неё поиграть, я разобрался с управлением и завис в 3-ей элите ещё сильнее и дольше, чем когда-то в первой.
А ведь это тоже был прорыв:
1) Появились полноценные звездные системы с кучей планет и разными типами звезд,
2) Появилась возможность посадки на планеты в любом месте! Хочешь в порту, а хочешь у берега океана.
3) Добавилась настоящая, честная физика, когда можно разогнаться до определенной скорости, выключить двигатель и лететь по инерции. Это очень сильно изменило внутрисистемные перелеты. Они стали намного сложнее и без автопилота мог летать только опытный пилот. На бои честная физика тоже повлияла. Если бои в первой части были похожи на DogFight 1й/2й мировой войны, то в новой части они стали похожи на битвы рыцарей на конях: Корабли сходятся, паля изо всех орудий, пролетают мимо, разворачиваются и снова сходятся, причем все это может происходить не бешеных скоростях относительно звездной системы и очень неспешно относительно друг-друга.
4) Стало можно менять и апгрейдить корабли
5) И это я уже не говорю про мелочи вроде сжатия времени, выполнения заданий и более продвинутой торговли.



Позже я познакомился с серией X. Сначала с X2 - the Threat, но она мне не очень понравилась, показалась очень скучной. И уже, относительно недавно: лет 5-7 назад я познакомился с X3 и влюбился. По моему мнению X3- albion prelude на данный момент является самым лучшим космосимом. Про X4 я умолчу т.к. это редкостная гадость для консольщиков.

Да, в X3 нет честных звездных систем, а есть абстрактные сектора, связанные вратами. Вселенная не почти бесконечна, а просто очень большая. Физика достаточно аркадна и нельзя садиться на планеты, зато:
1)можно строить станции,
2)создать свой флот,
3)сделать свою торговую империю,
4)мир в X3 живой: станции появляются и исчезают, сектора захватывают и отбивают обратно,
5)в X3 очень продвинутая торговля основанная на дефиците и переизбытке товара
6)и прочее.

Это было очень длинное вступление. Я написал столько букв, чтобы было понятно какие требования я возлагал на Elite 4, ведь все предыдущие игры как минимум на голову превосходили друг друга.





Обзор
Теперь приступим к Elite 4. Налетал я в неё порядка 15 часов и уже могу судить и делать выводы.
Для начала, мне не очень понятна ценовая политика разработчиков. За не очень ходовую игру они просят 1к рублей и ещё столько же за дополнение, которое дает возможность садиться на планеты и еще чего-то. Говорить я буду исключительно про базовую игру без дополнения ибо платить сумму большую, чем я заплатил за игру за дополнение, которое не вносит чего-то сверх-нового и важного меня задушит жаба.
И так, что есть в базовой версии:
- Есть красивая, современна картинка
- Если огромная вселенная (пожалуй самая большая, что я видел)
- Наличествуют и честные звездные системы с планетами, поясами астероидов и пр.
- Есть много разных кораблей, которые можно всячески апгрейдить. Оборудования много, есть из чего выбрать.
- Можно выполнять задания и зарабатывать на этом деньги
- Можно торговать
- Можно одним кликом расчитать маршрут перелета от одной системы к другой
- Можно пиратствовать или охотиться на пиратов
- Можно вступить в одну из группировок и получать зарплату.
и, пожалуй все.
Нельзя:
- Садиться на планеты (в базовой версии)
- Строить станции
- Нанимать пилотов к себе на службу
- Нельзя установить торговый софт на какой-нибудь из своих кораблей и отправить его зарабатывать мне деньги.
- Нет хотя-бы какой-нибудь сюжетной кампании.
- Многие вещи сделаны очень странно и неудобно

О последнем пункте подробнее.
Какие интерфейсы обычно в космосимах? Горячие клавиши как в Elite 1-3 или раскрывающиеся меню + горячие клавиши, как в серии X. К такому управлению системами иногда сложно привыкнуть т.к. нужно запоминать какая кнопка за что отвечает, зато потом ты управляешь огромной торговой империей и строишь маршруты через пол галактики очень легко и быстро.
В Elite 4 пошли иначе. В игре есть 2 панели: левая и правая. В левой игрок может посмотреть задания, выбрать маршруты, связаться с кораблями вокруг и п.р. А правой игрок управляет системами своего корабля: трюм, вооружение, прочее оборудование.
Это очень понятно и просто осваивается, но такая система крайне неудобна в использовании. Постоянно нужно совершать лишние действия для базовых вещей. В X3 для запроса стыковки нужно просто навестись на станцию, кликнув на ней, затем нажать "C" а потом "1".
Здесь нужно нажать "1", чтобы перейти в левую панель, 2 раза нажать вправо, выбрать станцию (а она может быть и не первой в списке), нажать пробел, выбрать 2й пункт меню и ещё раз нажать пробел. Как вам? В 2 раза больше манипуляций.

Управление кораблем сделано ещё страннее. На спидометре есть синяя полосочка. Если стрелка спидометра находится в синей зоне спидометра, то корабль имеет максимальную маневренность. Чуть наружу и он уже еле поворачивает. Вообще, корабль еле поворачивает даже с максимальной маневренностью, а без неё - вообще жуть.
Рысканье у корабля сильно притуплено, а крен наоборот, очень резкий.
Кажется, что разработчики хотели сделать что-то типа управления из 1й элиты (хотя в 3-ей оно было намного прдвинутей), но у них это явно не удалось. Управлять очень неудобно. Складывается ощущение, что управление затачивали под геймпад.
На доводку настроек управления я потратил уйму времени и все равно попадаю в ситуации, когда хочется обматерить разработчиков за криворукость.

Кораблем можно управлять и мышкой, вот только чувствительность у неё неадекватная. Чуть тронешь и нос уползает в сторону, а начнешь делать резкий разворот, как она неожиданно "тупеет" и приходится сильно елозить мышью по коврику.
От такого управленя страдает и боевка. Враги носятся как электровеники, точка попадания очень маленькая, а корабль игрока поворачивается со скоростью грузовика Белаз. Если бы не дополнительно купленные поворотные туррели, то я-бы воевать не смог вообще.

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

И таких странностей и неудобностей здесь ещё море.
Вообще, если бы мне нужно было охарактеризовать игру двумя словами, то они были-бы: НЕ УДОБНО.

Но это ещё не все. Элита 4 - это MMO. Можно летать и в соло-режиме, но постоянное подключение к интернету все равно требуется.
И даже при коллективном режиме игры, кого-то из живых игроков встретить здесь крайне сложно. Игроков не много, а мир огромен. При этом ката галактики и системы открываются порой до минуты! А ещё здесь нет сжатия времени и паузы.
Т.е. если я взял задание на отлов дезертира и в нем сказано, что он будет в 23:30 в указанном месте, а сейчас 22:40 и лететь тебе до него максимум минуту, то остальные 49 мнут реального времени займи себя чем хочешь.
Или ещё такая ситуация: ты выходишь из гипер-прыжка и хочешь открыть карту системы, чтобы нацелиться на станцию, а открытие карты подвисает минуты на 2, за которые ты не можешь ничего сделать и улетаешь на полном ходу в неведомые дали.

В журнале Игромания, в 2015 году на Элиту была издана статья, где все эти неудобства списали на хардкорность и реализм.
Ребяты: хардкорность и реализм - это Battlecruiser 3000AD. Там без 100-страничной инструкции ты крейсер даже с места не сдвинешь т.к. не сможешь отдать приказ офицеру, который за это ответственен.

И при всех своих косяках и неудобностях в 4й элите крайне мало контента. По сути - это сильно улучшенная 1я часть, в которую были добавлены элементы из 2й и 3-ей. А ведь Элита 3 вышла в далеком 95м году и с тех пор прогресс не стоял на месте. За 15 часов я увидел если не все, то почти все, что есть в базовой игре.
А в X3 я налетал около 150 и попробовал ещё не все, что можно.


И все-таки игра не так плоха, как я её расписал. Её можно даже порекомендовать тем, кто мало играл в космосимы или когда-то играл в элиту 1. Но, тем, кто играл в серию X или отечественный паркан, она покажется скучной и неудобной.

А я пока пойду ещё поиграю в X3- Terran Conflict.
Tags: , , ,

Диззи спасает Санта-Клауса
hipilion
Маленькая новогодняя игра от меня.
http://www.yolkfolk.com/site/download.php?id=355

1-е января №-цатого года. Где-то между 3-мя и 4-мя часами ночи.

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

Дизи с Дейзи решили перед сном выпить чаю, как вдруг....


Deus ex - киберпанк, Deus ex HR и последубщие - не киберпанк
hipilion
Знаете, ребята, у меня немножко прикипело. Все современные игруны в один голос утверждают, что оформление новых частей Deus Ex под эпоху возрождения - это хорошо, и вообще так оно и нужно.
Ну как же оно так нужно?! Deus Ex это что? Это киберпанк. Кто есть киберпанк? Это тень от огромных небоскрёбов, в которых живут нереально богатые люди, падающая на трущебы, куда боится соваться даже полиция. Это огромные мегакорпорации, управляюще марионеточным правительством. Это огромная пропасть между богатыми ибедными, это чувство одиночества и того, что ты очень маленький, какой-то винтик в огромной машине.
Это такой фантастический нуар. Эту атмосферу передают множество киберпанк фильмов и книг.
Атмосфера киберпанка очень близка к атмосфере антиутопических произведений, но там всё ещё не так плохо.

Вот как должен выглядеть классический киберпанк:








Вот как выглядит первый Deus Ex, которым занимался сам Уоррен Спектор.









Тот самый нуар из этих скриншотов прямо сочится. Все включая самых незначительных npc-прохожих выглядят футуристически и необычно. Странные защитные костюмы у солдат, аугументации на телах простых жителей, киборги Анна Новарре и Гюнтер и прочее, прочее. Всё выгляди так, как и показано в фильмах и описано в книгах.

А теперь глянем на то, что есть в Human revolution, которой Уоррен уже не занимался.






Это что за хрень?! Что за желтый цветофильтр? Что за рюшечки и жабо? Зачем эпоха возрождения? Где футуристическая одежда? От местных костюмов просто воротит, в главном герое нет никакой загадочности, а внешний вид города  интерьеров скатился к банальной фантастике. Нуара нет! Того тягучего ощущения одиночества нет! Никакой киберпанковской атмосферы. Новый геймдизайнер - Жан-Франсуа Дюга убил всё, что сделал Уоррен Спектор!

Итак испорченное редизайном впечатление от игры убивает переделанный гейплей, а точнее жуткая корридорность и полное отсутствие выбора.
Раньше было как: противника можно было убить или не убить. Убить десятком разных способов: взорвать, зарезать, застрелить, отравить, натравить робота в конце концов. И все выборы были равносильны и ценны одинаково. Хочешь быть Рэмбо - будь, хочешь быть Хитменом - пожалуйста, можешь вообще в хаккеры податься.
Я лично проходил всю игру с пистолетом с глушителем. От него пришлось отказаться только на последнем уровне, там все в касках и у пистолета просто не хватало мощности. Взламывал всё что только можно и стелсил по максимуму. К тому-же уровни в первой части по своей форме стремились к квадрату. Да, мне дают задание дойти от точки А к точек Б, но как это делать решать только мне. К тому-же на уровнях было спрятано огромное множество несюжетных возможностей, заданий, нычек и прочих итресных мест.
Что я увидел в Human revolution. Уровни стремятся к форме кишки с лёгкими ответвлениями. Несюжетные миссии есть, но только в уровнях-хабах. Игрока насильно заставляют стелсить, причем не просто сталсить, а убивать всех со спины. Просто прокрасться нельзя, т.к. опыт дают только за убийства и больше всего опыта дают за убийство со спины. Короче, хочешь быть сильным и прокаченным: нападай сзади и режь дефолтным ножиком. Какие там взломы систем охраны? Какие стратегически раложденные мины с газом или усыпляющие дротики? Вы о чем?! Здесь ничего этого нет, а если и встречается, то не нужно. Знай себе прокрадывайся между ящиками да режь горло проходящим мимо охранникам.

HR разительно отличается от первого Deus Ex. У меня складывается впечатление, что те люди, которые утверждают. что HR - хорошо и лучше, чем оригинал в тот самый оригинал просто банально не играли и не знакомы с жанром или играли но уже после HR.

ZX EVO - NOMAD - релиз
hipilion
После полу-года разработки я завершил свою новую игру для ZX Evolution - горизонтальный шмап - NOMAD.
Расписывать управление и т.д. не буде, всё есть в мануале.
Однако, предупрежу, что на дефолте игра сложная, но сложность настраивается в широких пределах.
Уровней всего 5, но они длинные, сложные и разнообразные.


СкриншотыCollapse )





Игра
http://www.kein1985.narod.ru/Nomad/NOMAD_zx_evo.zip

Эмулятор
http://www.kein1985.narod.ru/innsmouth/unreal_evo.7z

Google Cardboard или "Даёшь виртуальную реальность в массы!"
hipilion
Маленькое предисловие

Давно хотел попробовать что такое виртуальная реальность. Ещё в конце 90х в журналах проскакивали обзоры тогдашних VR шлемов. Но тогда это было всё очень далеко, дорого и недоступно. Относительно недавно появился VR шлем Oculus rift, штука тоже не дешевая, но более доступная. Во всяких кинотеатрах и торговых центрах появились точки, где можно было попробовать VR на вкус. Но 500р за 2 минуты!!! Меня жаба задушит за такое.

Пару недель назад я услышал про Google Cardboard (может прослоупочил и все уже про него давно знают, хз).

Для тех кто не в курсе.

Если в кратце, то Google Cardboard и ей подобные это такая коробка (не обязательно. Эта штука может быть оформлена и цивильно, в виде пластикового шлема с нормальной крепёжкой на голове) и  с линзами. В эту конструкцию с одной стороны вставляется смартфон на экран которого выводится обычная горизонтальная стереопара, а с другой стороны лицо.

А ведь идея на самом деле гениальная. В современных смартфонах есть все необходимые для отслеживания положения головы сенсоры: гироскопы и акселерометры.
Экраны выдают достаточное разрешение, а про вычислительные мощности я вообще молчу. Мой ZenFone2 мощнее чем болшинство моих старых настольных пк за последние 15 лет. Так зачем дорогущий шлем, если всё что нужно уже есть?...


И тут понеслась...

Нашел я тему вконтакте https://vk.com/topic-76644861_30514790 с выкройками. Распечател, разрезал, склеил, но всё упёрнлось в линзы. С теми линзами, что я смог раздобыть у меня никак не получалось добиться хоть какого-нибудь эффекта: либо жутко мутно, либо видно просто 2 изображения рядом.

В конечном итоге я плюнул и начал обшаривать сайты ближайших магазинов в поисках готового комплекта. Буквально за 10 минут на сайте Юлмарта нашлось то что мне нужно: Homido cardvoard 2.0 для смартфонов от 5' до 6' за 580 рублей. Пол часа и заветная игрушка у меня.





screen.JPG
Процесс сборки занял от силы 5 минут. отрезал обложку, сложил по сгибам и всё готово.

Далее дело осталось за софтом. На PlayMarket очень много разных программ под Cardboard. Есть просто "гляделки" когда камера движется "по рельсам", а человек просто вертит головой. Есть виртуальная экскурсия, есть игры: стрелялки, квесты, с джойстиком и без, есть даже игра, где нужно на самом деле прыгать. Разгуляться есть где.

Впечатления.

Ребята, это очень круто. Вау эффект сопостовим с эффектом от первой игры на WII (когда тебе нужно реально махать wiimote как ракеткой или веслом, а не жать кнопки). Очень необычно и интересно. В игре, что на скриншоте выше (называется Maze VR) эффект объёмности ощущается очень сильно, намного сильнее чем в 3d кино, а из-за необходимости постоянно вертеть головой можно реально потерять ориентацию в пространстве. В общем всем кто не пробовал Oculus rift или что-то  круче, рекомендую.


О достоинствах и недостатках Homido cardboard 2.0.

Достоинства: настоящая виртуальная реальность за очень скромные деньги.
Недостатки вытекают из цены: материал - картон. Со временем он расклеится и истреплется.
В комплекте шел ремешок, с помощью которого можно было крепить эту конструкцию на голове. Крепить можно, но жутко не удобно. Смартфон перевешивает дальний край и весь вес ложится на переносицу, от этого коробка перекашивается и глаза быстро устают.
Линзы не очень хорошего качества. Прямо по середине иображение четкое, ближе к краям линз оно становится расплывчатым.
Нету функции клика. Приходится просовывать палец в отверстие для носа.

Но все эти недостатки перевешиваются достоинством - ценой.
Лично я воспринимаю преобретение как "пробник" VR.
Если картонка развалится можно сделать что-нибудь своё. Растояние от линз до телефона и от линз до глаз я знаю, сами линзы не сломаются, остальное дело техники и фантазии. А если VR не надоест, то куплю в будущем что-нибудь более солидное с тем-же пинципом.

Brickgame MT1997
hipilion
Это вторая моя статься про brickgame, они-же в простонародье - Тетрис.
Первая про TS-9999 находится вот тут http://hipilion.livejournal.com/24635.html

Из пыльных закромов дачи мной был изъят, почищен и восстановлен мой старый тетрис MT1997, о котором говорилось в предыдущей статье.
Динамик был в нерабочем состоянии, через дырочки в задней стенке он притянул к себе металлическую стружку и поржавел. Кнопки тоже плхо нажимались.
У меня возникла идея попробовать взять нудные части у новодельного собрата. И, о чудо! После разборки обоих тетрисов выяснилось, что за 19 лет в их устройстве, кроме более дешевых материалов, ничего не поменялось.
Динамик и резинки что у старых тетрисов, что у новых абсолютно одинаковы.

В конечном итоге: от нового тетрса в старый перебрался динамик и 5 резинок. От сломанной игрушки в новый тетрис перебралась пьезопищалка (звук мерзкий, но главное что работает). Один не нужный пульт расстался с несколькими токопроводящими резиночкаи, которые пошли на замену негодных из старого тетриса, путём аккуратного срезания их лезвием и приклеивания суперклеем куда нужно.



DSC02463.JPG

Фото деда и внука бок о бок. Сразу бросается в глаза разница в размерах.
Так-же видна не стандартная компановка кнопок в MT1997. Из минусов могу отметить мелкие кнопки направления. Детским-тонким пальцам такие мелкие кнопки не доставляют неудобств, но взрослому человеку нужно приноравливаться.
Тетрис сгибается пополам, экран можно отогнуть примерно на 15 градусов. Замечу, что внутри на сгибе не тонкий, прозрачный пластиковый шлейф с токопроводящим  порошком, которые в то время китайцы вставляли куда угодно, а вполне себе добротный шлейф на подобие IDE, только сечение проводов намного больше. Примерно как у жилы из витрой пары. При включении этот Brickgame играет ламбаду. При выключении игра не сохраняется, но HighScore остаются в памяти.

DSC02464.JPG

Хоть на корпусе и красуется надпись "Talking" (говорящие тетрисы в ту пору ценились), пацана на экране нет но голос его есть (прячется где-то). Это фото я специально сделал так, чтобы было видно все сегменты. На фото видно надкиси "Game A", "Game B", "Rotate" и стрелочки. Эти сегменты не используются ни в одной игре. Отсюда следует двольно интересный вывод:
на brick game одной из поздних модификаций был установлен экран от первых моделей.


screens_compare.jpg
По этому фото хорошо видна разница в размере экранов. В новом тетрисе все информативные элементы перекомпанованы и убраны фрукты. Не смотря на сильно уменьшенную игровую область экрана, в "квадратиках" её размер не уменьшился. (Хотя у меня были подозрения об обратном. )

Игры
Всего в MT1997 9 разных игр, против 11 в TS-9999.

  1. Танки. 99 вариантов, разницы между ними я не нашел. ИИ субъективно лучше, чем в TS-9999. Если у врага перед номом пролетит снаряд игрока, он (враг) не поедет дальше, а будет ждать или развернётся. После каждого уровня есть босс, которому нужно попасть прямо в дуло.
    DSC02467.JPG

  2. Фроггер.33 варианта. Все разные. Отличаются размерами поля, скоростью движения брёвен, направением движения и даже инвертированностью управления. В TS-9999 все 99 вариантов одинаковые.
    DSC02468.JPG

  3. Стрелялка - Чапай. 4 варианта. 2 варианта на отстрел фигур и 2 на достройку фигур до прямоугольников.  С движением в бок и без него.  Потратив жизнь, можно вызвать подмогу, тогда к пушке пристраивается ещё одна. В TS-9999 - только отстрел.
    DSC02469.JPG

  4. Арканоид. 42 варианта.
    Отличия:
    а)Ракетка может подниматься выше от уровня к уровню
    б)По середине игрового поля может быть какая-нибудь буква
    в)У верхней границы будет ещё одна ракетка
    г)Внизу будут 2 ракетки
    д)Через поле будут летать непробиваемые точки
    у)С каждым ударом, кубики будут сдвигаться в бок.

    В этом арканоиде, в отличие от TS-9999 адекватная физика. Шарик всегда отскакивает под углом 45 градусов с какой-бы стороны планки он не отскочил. Если нужно пустить шарик под углом в 90 граусов, то нужно в момент соприкосновения шарика с планкой сдвинуть её чуть-чуть в сторону.
    DSC02470.JPG

  5. Гэлэкси или куча. 2 варианта. Сверху от кучи отделяются 2 мухи, их нужно отстреливать.
    DSC02471.JPG

  6. Гонки по трассе. 8 вариантов. Все варианты - это разные комбинации препятствий: машинки, стены, кубики, пешеходы и мотоциклисты. Сбивая пешеходов машинка преобретает возможность стрелять. В TS-9999 только один вариант - стены. Можно сказать, из за одной этой игры я и полез искать старый тетрис.
    DSC02473.JPG

  7. Гонки в тоннеле. 2 варианта. Разницы между ваиантами я не заметил. Может быть разница в различной генерации тоннеля.
    DSC02477.JPG

  8. Охота за привидениями. 99 вариантов, разницы нет. Точто такая-же игра, как и в TS-9999. Единственное отличие, там центральные привидения расположены криво.
    DSC02478.JPG

  9. Тетрис. Все остальные буквы, по 99 вариантов в каждой заняты тетрисом. Ну тетрис, он и в Африке тетрис: во всех brickgame одинаковый. Может быть порядок вариантов другой, не проверял.
    DSC02479.JPG

Итог

В MT1997 на 3 игры меньше, чем в TS-9999, из которых только одна более-менее интересная - Змейка. Однако змейка с TS-9999 сильно порезана и не бросает никакого челенджа игрку.
  При игре со звуком MT1997 не тормозит. А новые brickgame тормозят. Про более качественные материалы в MT1997, я думаю, упоминать нет смысла.

  Получается, что новый TS-9999 проигрывает своему более старому собрату почти по всем фронтам, кроме игры змейка, более удобных кнопок и трёх-уровневой регулировки громкости. Для "понастольгировать" и забыть TS-9999 ещё сойдёт, но если требования выше, нужны те самые игры, то нужно искать представителья BrickGame из 90х.

ZX EVO - NOMAD - первый уровень
hipilion
И так, первый уровень моей новой игры готов.

С музыкой у меня пока полный голяк, её нет и я не знаю к кому обратиться.
Поэтому я сделал два видео игрового процесса.
Первое с наложенными треками из разных игр с Sega mega drive.



Второе с оригинальным звуком.


Сама игра.
http://www.kein1985.narod.ru/Nomad/NOMAD_first_level.scl

Игра пойдёт на Zx Evo Baseconf (проверял на 2й редакции). По идее, должна пойти и на ATM2 turbo и на всём совместимом, но её нужно 14mhz иначе будет слайд-шоу.

Unreal настроенный под ZX evolution. На нём игра так-же прекрасно работает.
http://www.kein1985.narod.ru/innsmouth/unreal_evo.7z"]unreal_evo.7z


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

На нём не очень много врагов:
Череп - малый летун, который умеет стрелять. Нужно 2 попадания из пистолета.
Синий робот -  простой малый летун, стрелять не умеет. Нужно одно попадание из пистолета.
Желтый робот - средний летун, стреляет больней, чем череп. Нужно 2 попадания из пистолета.
Самонаводящаяся мина - нужно 2 попадания.
Танк-спавнер мин - противная штука с толстой шкурой.
Робот-танк - такой-же толстый, как и спавнер мин. Просто стреляет в игрока.

Управление:
A - Стрельба с залипанием (после зажатия клавиши, рука героя фиксируется и можно стрейфитсья в разные стороны)
S - Стрельба без залипания
С - Прыжок

Если при зажатой клавише А, зажать S, то рука расфиксиуется. Так можно быстро менять направление стрельбы.

Изначально я хотел разместить управление на Z,X,C, но столкнулся с неприятной особенностью клавиатуры - фантомными нажатиями. При зажатой X и нажатыми Вверх и Вправо, сама собой срабатывает C. Пришлось сместить его на ряд выше.

EVO SDK Статья3 - gimp как pixel art инструмент
hipilion

После статьи о конвертации графики из RGB к палитре ATM/ZX-Evolution в Photoshop, которая была опубликована в ACNews 61 у читателей возникли вопросы по поводу того-же, но применительно к GIMP. Сам процесс конвертации графики в Gimp не сильно отличается от него-же в Photoshop и делать статью только про это было бы не интересно. Посему я решил расширить тему и написать обзорную статью о применении GIMP в Pixel-art.

Инструменты (карандаш, заливка и т. д.) я думаю не стоит описывать. Всё то-же самое есть и в Photoshop. Упомяну про один инструмент, которого я не нашел в Photoshop (может быть плохо искал) -Select by color tool — Выделение по цвету. Как понятно из названия позволяет выделять в изображении все области выбранного цвета с определённым допуском — threshold. Это достаточно разноплановый инструмент, который помогает, как найти области с нужным цветом при конвертации, так и оградить какие-то области от изменения.

Вот несколько напоминалок, которые позволят сильно ускорить работу в GIMP: размер кисти можно менять горячими клавишами "[" и "]".

Быстро поменять местами основной и фоновый цвета можно клавишей "X".

Быстро "взять" цвет из изображения без инструмента Пипетка, просто зажав клавишу "Control" и кликнув по изображению (если у вас активен какой-то из «рисующих» инструментов).

Линии рисуются от последнего нарисованного пикселя зажатием клавиши "Shift".

Быстрый Zoom висит на цифровых клавишах.

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

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

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

Если выбрать в качестве основного цвета рисования цвет не из палитры, то при рисовании, пиксели будут окрашиваться в ближайший цвет из палитры.

Если вставить из буфера обмена RGB изображение в проект с палитрой, то RGB изображение будет автоматически сконвертировано в текущую палитру без сглаживания.

Сконвертировать готовое RGB изображение в палитровое очень просто. Для этого нужно открыть диалог ”Indexed Colour Conversion”. Меню Image->Mode->Indexed.


Пройдёмся по пунктам этого диалога.


  • "Generate optimum palette"Позволить программе самой решить какие цвета попадут в палитру. За максимальное количество цветов в итоговой палитре отвечает параметр "Maximum number of colours".


  • "Use web-optimized palette"Как понятно из названия, при выборе этого пункта программа постарается оптимизировать итоговую палитру для интернета.


  • "Use black and white (1-bit) palette"Преобразует изображение к монохромной черно-белой палитре.


  • "Use custom palette" - Преобразует изображение к заранее подготовленной палитре.


    • Remove unused colours from colourmap – Определяет удалять или нет неиспользованные цвета из конечной палитры.



Для нас наиболее полезны 1й и 4й пункты: "Generate optimum palette" и "Use custom palette". Советую всегда держать под рукой готовую палитру с цветовой картой ATM/ZX-Evolution.

Далее идёт группа пунктов, отвечающих за размытие цветов.


  • Colour dithering — позволяет выбрать метод размытия.


    • None – без размытия. Цвета конвертируются приближением к ближайшему цвету в палитре.


    • Floyd-Steinberg (normal) и Floyd-Steinberg (reduce colour bleeding) – размытие по Флойду Стейнбергу.


    • Positioned – Фиксированное размытие. Более простое, чем по Флойду Стейнбергу, но в то-же время более применимое в Pixel-Art.



  • Enable Dithering on transparency – Собственно, применять ли размытие к альфа-каналу.


Для конвертации небольших изображений лучше использовать фиксированное размытие или не использовать размытие вообще. В любом случае, автоматическое размытие на маленьких картинках выглядит «грязно». Более-менее приемлемая картинка получается от 320x200 и выше.

А теперь о том как-же с помощью этого диалога можно преобразовать любое изображение к ATM/ZX-Evolution палитре.


  1. Делаем "Generate optimum palette". "Maximum number of colours" подбираем опытным путём в зависимости от изображения, так чтобы после этого шага картинка выглядела пристойно, но количество цветов было минимальным. Обычно это ~60 – 70 цветов.


  2. Пробуем преобразовать изображение обратно в RGB, а затем в заранее подготовленную ATM/ZX-Evolution палитру "Use custom palette". На этом этапе Gimp приведёт все цвета в изображении к ближайшим из палитры.

    Если картинка сильно изменилась в цветах и чистая ATM палитра не подходит, откатываемся назад и пытаемся подстроить проблемные цвета вручную.


  3. Смотрим, если цветов <= 16, переходим к этапу ручной правки финальной картинки.


  4. Если цветов больше 16, то ищем похожие цвета, которые можно «слить вместе». Для этого я чаще всего использую следующий приём.

    Разглядываю палитру изображения и ищу похожие цвета, после чего прямо в палитре меняю какой-нибудь из них на любой другой, которого нет на картинке (например ядовито розовый). Если областей этим цветом получилось мало, просто меняю этот цвет на соседний. В итоге, в палитре получается несколько одинаковых цветов.


  5. Когда цветов, которые можно совместить не остаётся, можно попробовать избавиться от какого-то цвета совмещением 2х других. Допустим в изображении есть область оранжевого цвета. Можно заменить её шахматной штриховкой красного и желтого.
    Как это делается:
    - Создаётся ещё один слой. В этом слое рисуется маленький образец заливки. Например 4 пикселя: 2 красных и 2 желтых. Этот пример копируется в буфер обмена, а затем слой прячется.
    - Инструментом "
    Select by color" — "Выделение по цвету" выделяем все области в изображении с нужным нам цветом.
    - Выбираем инструмент "
    Bucket fill tool" – "Заливка".
    - В
    Fill type – тип заливки выбираем Pattern fill. Жмём на посветлевший квадратик с текстурой и в раскрывшемся списке выбираем левый-верхний угол. Это наш образец заливки.
    - Не забываем выделить
    Fill whole selection – Заливка всего выделения, иначе заливка произойдёт только в той области, куда мы ткнули мышкой.
    - Заливаем ненужный нам цвет. После чего смотрим на результат и правим его руками.


  6. После всех этих манипуляций, количество используемых цветов должно сильно сократиться. Чтобы обновить палитру изображения, преобразуем его в RGB Image->Mode->RGB. А затем обратно к палитре Image->Mode->Indexed, с использованием оптимальной палитры.


  7. Если цветов всё ещё больше 16, возвращаемся к пункту 4.


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

Это делается так:


  1. Colors->Map->Set Colormap


  2. Жмём на кнопку Default, откроется окно Script-fu: palette selection.


  3. Прокручиваем список в самый верх и находим там текущую цветовую карту изображения.


  4. Правой кнопкой мыши на этой цветовой карте. Выбираем Duplicate palette.


  5. Переименуем копию текущей цветовой карты в что-нибудь более понятное.


  6. Всё, теперь эта палитра будет доступна для всех изображений, во всех диалогах.


Сами палитры обычно хранятся в директории C:\Users\%username%\.gimp-2.8\palettes.

Этот путь можно изменить в меню Edit->Preferences->Folders->Palettes.

Файл палитры — это обычный текстовый файл, который открывается и редактируется простым блокнотом. Вот примерное содержание палитры:

GIMP Palette
Name: Colormap of Image #1
Columns: 8
#
255 0 0 #0
210 3 16 #1
6 8 4 #2
177 183 191 #3

208 97 145 #255

При необходимости, палитру можно полностью подготовить или исправить вручную.

После всех манипуляций с проектом вы скорее всего захотите получить готовый BMP, который можно будет использовать где-то ещё. В новых версиях GIMP, непонятно почему, простым сохранением "Sava/Save as" можно сохранять только в родной для GIMP формат - XCF. Для сохранения в другие форматы нужно пользоваться пунктами "Export/Export as".

Далее, очень важно. В диалоге "Export Image as BMP", нужно раскрыть "Compatibility options" и поставить галочку напротив "Do not write color space information". Иначе готовая BMP может неадекватно восприниматься другим софтом. Например EVO-SDK из таких изображений вообще не может достать палитру и воспринимает их как черно-белые.


EVO SDK Статья2 - Увеличение памяти под код в EvoSdk.
hipilion

Увеличение памяти под код в EvoSdk.

В своей предыдущей статье (InfoGuide 11) я упоминал о том, что под код и переменные в EvoSDK доступно примерно 32к, а так-же о том, что этого объёма вполне хватает для небольших программ, но для более крупных приходится прибегать к различным ухищрениям (например выносить часть данных в расширенную память). Но этого всё равно недостаточно. Код на C компилируется довольно размашисто, а это значит, что при написании большой игры, в любом случае придётся как-то ужиматься.

Я разработал способ, как можно расширить область памяти кода до очень больших объёмов. Кратко суть метода:


  1. Часть кода, который не вмещается в основную память мы компилируем отдельно;


  2. Преобразуем в бинарный файл;


  3. Забрасываем на дискету;


  4. В нужный момент загружаем этот файл в расширенную память


  5. Оттуда монтируем во 2й слот (0x8000-0xbfff)


  6. Вызываем этот код из основной программы.


По сути, этот подход очень похож на Динамически подключаемые библиотеки (.dll), но с кое-какими ограничениями.

«Плюс» этого метода один, но очень большой: объём кода теперь не ограничен, можно писать очень много.

«Минусов» несколько: Сложность в использовании и подготовке, небольшое замедление работы всей программы, некоторые ограничения загружаемых модулей.

Подготовка подключаемого модуля

Первым делом нужно исправить /evosdk/_compile.bat. В этом файле нужно убрать или закомментировать строку rd /s /q %temp%, чтобы после компиляции проекта не удалялась директория с временными файлами, которые нам очень нужны.

Следующим этапом будет извлечение адресов функций из файла out.map, который находится в директории _temp_. Для этого я использую вот ткой маленький Perl скрипт:

#!/usr/bin/perl

use strict;

my $str;

my @arr;

open FIL,"_temp_\\out.map";

open OUT,">map.h";

while($str=<FIL>)

{

chomp $str;

$str=~s/\s*//;

if(length($str)>0)

{

@arr=split(/ /,$str);

if(substr($arr[2],0,1) eq "_")

{

print "#define " .$arr[2]." 0x". $arr[0]."\n";

print OUT "#define " .$arr[2]." 0x". $arr[0]."\n";

}

}

}

На выходе этого скрипта получаем файл map.h, который нужно будет подключить к будущей библиотеке.

В конечном итоге, в компилируемой библиотеке, должны быть подключены следующие хедеры:

#include "..\evosdk\evo.h"

#include "..\evosdk\startup.h"

#include "..\Родительский проект\resources.h"

+

Все необходимые дополнительные хедеры из родительского проекта.

Теперь нам нужно научить дочерний проект понимать функции из родительского.

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

#define draw_image ((void(*)(u8,u8,u8))_draw_image)

#define select_image ((void(*)(u8))_select_image)

#define draw_tile_key ((void(*)(u8,u8,u16))_draw_tile_key)

#define put_mem ((void(*)(u8,u16,u8))_put_mem)

#define get_mem ((u8(*)(u8,u16))_get_mem)

и т. д.

После чего объявленные функции можно будет использовать в проекте так же, как и обычные.

Далее пишем основной код подключаемого модуля. Однако, чтобы не высчитывать после каждого изменения адрес входа в функцию main, все остальные функции лучше писать после неё (естественно, заранее объявив).

Подготовка основной программы

Логика работы основной программы с модулем такова: файл или файлы с дискеты загружаются в память, а потом в нужный момент подключаются во 2е окно и вызываются по адресу 0x800A.

В качестве примера подключения и вызова можно взять вот эту функцию:

void manager(u8 page,u8 operation,void *a,u8 b) __naked

{

u8 c;

put_mem(trigger_text_page,exchangedate_begin,operation);

put_memw(trigger_text_page,exchangedate_begin+1,(u16)a);

put_mem(trigger_text_page,exchangedate_begin+3,b);

//------------------------------------

__asm

push ix

ld ix,#0

add ix,sp

ld a,4 (ix)

PUSH AF

xor #0x7f

LD BC, #0xbff7

ld (_MEMSLOT2),a

OUT (C), A

POP AF

call #0x800a

pop ix

ret

__endasm;

}

pageНомер страницы, в которой лежит бинарник, operation — идентификатор операции (менеджер с другой стороны распределяет входные параметры и вызывает нужную функцию в зависимости от этого идентификатора), A – Бестиповый указатель — параметр, B - ещё один параметр.

Обратите внимание на строки типа put_mem(trigger_text_page,exchangedate_begin,operation);

Подключенная библиотека при вызове начинает вести себя как самостоятельная программа и творит какие-то непотребства со стеком, в результате чего вместо переданных данных функция получает что-то совсем другое. Однако это не влияет на последующую работоспособность всего проекта. Сильно копаться в этих процессах не стал. Если кому-то удастся разобраться как красиво передавать параметры в дочернюю функцию, буду только рад.

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

Подготовка EVO SDK

Однако, если вы соберёте и запустите этот проект, то ничего не заработает т. к. большинство функций EVO SDK, которые используют 2е окно, не «чистят за собой». Не подключают туда обратно страницу, которая была во 2м окне до их вызова.

Для правки, открываем put_get_mem_atm.h, lib_sprites.asm и lib_tiles.asm.

И добавляем в начало и конец нужных фунций:

В put_get_mem_atm.h

В начало :

push ix

ld ix,#0

add ix,sp

В конец:

pop af

LD BC, #0xbff7

ld (_MEMSLOT2),a

out (c),a

В lib_sprites.asm и lib_tiles.asm:

Вначало:

ld a,(_memSlot2)

push af

В конец:

pop af

ld (_memSlot2),a

ld bc,MEM_SLOT2

out (c),a

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

Список функций, которые точно нужно править:

_DOS_3D13, sprites_start, sprites_stop, draw_tile, draw_tile_key, draw_image, pal_select, swap_screen, все функции из put_get_mem_atm.h.

Так же замечу, что после внесения правок и пересборки библиотек EVO SDK. Он может перестать работать. Это случится из-за превышения максимального размера библиотеки. В этом случае можно закомментировать какие-либо «ненужные» функции, например _sample_play в lib_sound.asm. Эта функция отвечает за covox, который я не использую.

Сборка и компиляция

Тут всё тоже не так просто. Для компиляции дочернего проекта нужно использовать SDCC версии 2.9. Более новые версии содержат баг, из-за которого не получается явно задавать указатели на функции, а следовательно библиотека получается «вещью в себе». Мы не сможем вызывать функции родительского проекта.

Вызывать sdcc нужно с такими параметрами:

sdcc -mz80 --code-loc 0x8000 --data-loc 0xBC00 main.c -o %temp%\out.ihx

Код помещаем именно с адреса 0x8000, т. к. если поместить его с 0x0000 адреса, то все указатели на функции будут иметь ссылки начиная с этого адреса. А это нам не нужно т. к. с 0x0000 адреса у нас будет код основной программы.

Sdcc генерит скомпилированный код в Motorola hex формат. Для получения бинарника я пользуюсь утилитой hex2bin.exe (http://sourceforge.net/projects/hex2bin/).

Но и это ещё не всё. Код в полученном файле, как мы и указывали при компиляции, начинается с адреса 0x8000, а остальное место заполнено мусором.

Для обрезки бинарника я написал небольшую утилиту на java.

Для желающих, вот её код:

package cuter;

import java.io.IOException;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.util.logging.Level;

import java.util.logging.Logger;

/**

*

* @author VSurjenko

*/

public class Cuter {

public static void main(String[] args)

{

try {

String filename,destfile;

int addr,a;

byte arr[];

byte arr2[];

if(args.length>0)

{

filename=args[0];

}

else

{

System.out.println("Programm need 3 parameters: file name, destination file name and address of cutting.");

return;

}

if(args.length>1)

{

destfile=args[1];

}

else

{

destfile=filename.concat("_cuted");

} if(args.length>2)

{

addr= Integer.parseInt(args[2]);

}

else

{

addr=0x8000;

}

//------------------------------------

Path path = Paths.get(filename);

Path path2 = Paths.get(destfile);

arr=Files.readAllBytes(path);

arr2=new byte[arr.length-addr];

for(a=0;a<arr.length-addr;a++)

{

arr2[a]=arr[a+addr];

}

Files.write(path2, arr2);

} catch (IOException ex) {

Logger.getLogger(Cuter.class.getName()).log(Level.SEVERE, null, ex);

System.out.println(ex.getLocalizedMessage());

}

catch(Exception ex)

{

System.out.println(ex.getLocalizedMessage());

}

}

}

Остальные могут либо придумать что-то сами, либо обратиться ко мне, я дам jar файл.

Всё, теперь полученный бинарник готов к использованию в основной программе.

В итоге, полный процесс сборки всего проекта будет выглядеть так:


  1. Компилируем основную программу, но не собираем образ.


  2. Втягиваем из Out.map указатели на функции


  3. Компилируем дочернюю программу, преобразуем в бинарный файл из hex формата, обрезаем и забрасываем в директорию к основной программе.


  4. Собираем весь проект в образ дискеты


  5. Тестируем.


Теперь кратко об ограничениях дочернего модуля.


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


  2. Размер одного модуля ограничен 16к — одна страница. Это не должно быть большой проблемой. Всегда можно сделать несколько модулей и подключать нужный в данный момент.


  3. Я так и не нашел способа «подружить» загружаемый модуль с глобальными переменными основной программы.


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

К примеру, код мануала от SpaceMerc Liberation занимает 8377 байт, я перенёс функцию вывода текста в отдельный бинарник и, вместе с функцией вызова и разросшийся библиотекой EVO SDK код стал занимать 6890 байт. Почти 1.5к. чистой выгоды.


EVO SDK Статья1 - общие моменты
hipilion

Выкладываю все свои статьи по ZX EVO SDK, зарелиженые ранее в Infoguide и ACNews

На чём делать игру? Могу предложить EVO sdk. Почему именно его? Потому что я делаю игры в основном в этой среде и достаточно неплохо её изучил.

Я перешел на неё со связки C++, OpenGl из за того, что мне хотелось просто делать свои игры, без долгой возни с оборудованием, разработки формата хранения моделей и создания конвертера под него (Open GL не имеет какого-то стандартного формата хранения моделей), хотелось чего-то более интересного чем банальный PC. Готовые движки меня не устраивали т.к. игра созданная на чужом движке не давала той радости, как игра написанная своими руками полностью с нуля. Языком Assembler я не владею и выбор сам собой пал на EVO sdk. Вот несколько аргументов в его ползу (Если, конечно вам не важна платформа, и вы не хотите делать трёхмерные игры):


  • Лёгкий старт. Для того чтобы просто инициализировать видеокарту и создать пустое окно на OpenGl нужно написать около экрана кода, в EVO sdk не нужно ничего инициализировать, всё уже готово. Если есть картинка спрайта, то её можно отобразить всего парой вызовов. Для начала работы нужно всего лишь взять заготовку empty_project, открыть main.c и начать писать свой код.


  • Ресурсы. С одной стороны ограниченные ресурсы платформ ZX Evolution и ATM 2 это огромный минус по сравнению с обычным пк с его гигабайтами и гигагерцами. Здесь нельзя воспроизвести mp3 в качестве фоновой музыки, нельзя использовать графику высокого разрешения в 24 битном цвете. Зато, ограничения «железа» сдерживают амбиции разработчика, тут уже сложнее «увязнуть» в процессе подготовки ресурсов. Ещё, в отличие от поиска готовых текстур, рисование пиксельной графики — это настоящее искусство. Программирование в условиях ограниченного пространства с не шибко быстром процессором быстро оттачивает навыки программиста. Приходится как-то «ужиматься», оптимизировать код, выдумывать более быстрые алгоритмы, что само по себе уже довольно интересно.


  • «Теплота и ламповость» - Как ни крути, а Zx-evolution и АТМ 2 являются клонами, zx Spectrum, только с дополнительными возможностями, которые мы и задействуем.


Что собственно из себя представляет EVO sdk. Это кросс компилятор языка C SDCC, набор библиотек позволяющих максимально отдалиться от низкоуровневой работы с железом и набор утилит и скриптов, позволяющих максимально просто и быстро из исходников и ресурсов собрать готовый образ tr-dos. Вся эта система позволяет без лишних телодвижений на домашнем компьютере, в любом удобном для вас редакторе на простом и понятном языке С написать игру, которая будет использовать навороты ATM2 или Pentevo. Правда за удобства придётся расплачиваться потерей быстродействия, увеличенным объемом кода (компилятор не совершенен и там где опытный программист на ассемблере обойдётся десятью командами, компилятор может использовать тридцать и более) и ограниченными возможностями (это не такая большая проблема, ассемблерные вставки делать никто не запрещал).

Взять её можно вот здесь: http://alonecoder.nedopc.com/zx/evosdk_libs.rar

В рамках этой статьи я не буду подробно описывать все возможности EVO sdk, и давать комментарии ко всем его функциям. Вся необходимая информация есть в readme.txt, и все функции подробно прокомментированы в evo.h. Здесь я опишу новые «фишки» SDK, такие как работа с памятью и диском, а так же несколько «подводных камней» с которыми можно столкнуться в начале работы с SDK:

Графика:

Руководство говорит: «Графика должна быть подготовлена в формате BMP без сжатия, с 16 или 256 цветами (используются первые 16 цветов). Для этого могут использоваться любые стандартные графические редакторы.». Включая стандартный paint. Однако не все редакторы подходят для этой цели. Вся графика, очень желательно, должна быть в 16 цветах т. к. 256-цветные изображения занимают существенно больше места. Следовательно Paint и подобные ему редакторы не подходят. Для подготовки графики наилучшим образом подходят программы типа GIMP и Photoshop, которые умеют создавать «палитровые» изображения. Но здесь есть одна меленькая деталь. Gimp начиная с версии 2.8 и новые версии Photoshop, сохраняют «палитровые» BMP несколько странно. Из картинок сделанных в этих редакторах SDK не может получить палитру, причём вся информация о цветах сохраняется и если подставить к изображению уже готовую палитру, то оно будет отображаться нормально. Я настоятельно рекомендую использовать GIMP версии 2.6.9. В версии 2.7.* есть небольшой глюк с рендером рабочего пространства при сильном увеличении.

SDK умеет работать со спрайтами 16x16px (до 64х штук) и имеет два режима: Отображение спрайтов включено или выключено. При включённом отображении спрайтов, рисовка всех тайлов происходит на два экрана сразу, при выключенном — только в теневой экран. Это нужно учитывать при построении изображения. С включёнными спрайтами рисовка тайлов идёт существенно медленней.

Так же при отображении спрайтов прозрачными считаются цвета после 16го т. е. можно использовать все цвета палитры плюс прозрачный, а при отображении тайлов прозрачный цвет нужно указывать из палитры. Следует учитывать при разработке игры, что спрайты имеют на один цвет больше и либо не использовать тайлы с прозрачностью, либо дублировать прозрачный цвет из карты тайлов в карту спрайтов, либо выдумать что-нибудь ещё.

Звук:

Со звуком не должно возникнуть каких-либо затруднений, но стоит предостеречь от чрезмерного использования Covox. Воспроизведение wav через covox хоть и звучит внушительно, но приостанавливает выполнение основной программы, что нарушает динамику игры, а так же сами звуки занимают достаточно много места в памяти. Covox можно использовать при переходах в меню, окончании уровня и т.д.

Программирование:

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

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

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

Чтобы ещё сильнее сэкономить место в памяти, карты уровней можно вынести в отдельные файлы на диске

Руководство по SDK обещает около 55кб. Под скомпилированный код, однако счётчик объёма кода врёт. По факту это ограничение = 32к. Игра нормально скомпилируется, но может не заработать или в процессе игры начнут самопроизвольно появляться и исчезать какие-либо объекты. Если подобные странности начали происходить, скорее всего ваш скомпилированный код превысил максимальный объём. (Сейчас уже решено модульной системой: максимальный размер основного модуля =32к, максимальный размер дополнительного модуля =16к, количество дополнительных модулей не ограничено)

Чуть выше я сказал, что SDK умеет работать со страницами памяти. Для этого вам понадобятся функции из getmem.c и хедер startup.h. Для записи данных в память есть функции: put_mem (1 байт), put_memw(2 байта) и put_meml(4 байта). Где параметры:

PGномер страницы, куда пишутся данные.

ADDRадрес внутри страницы куда данные пишутся.

DATAсобственно сами данные.

Будьте внимательны, не пишите данные в страницы уже занятые игрой под ресурсы или код. Посмотреть какие страницы под что отведены можно после компиляции проекта в окошке компилятора. Так же следует помнить, что эти функции предназначены для работы с памятью ATM2 и у нас есть всего 64 страницы — 1мб. Адрес смещения от начала страницы должен выглядеть так: 32768+смещение.

Для получения данных из памяти есть функции: get_mem,get_memw и get_meml, которые возвращают 1,2 и 4 байта соответственно.

Теперь о работе с диском. В Sdk реализована функция TR-dos 3d13, правда вызвать её можно только из ассемблерной вставки, но есть обвязка этой функции на языке С, которая находится в call_3d13.c. Я предлагаю свой вариант обвязки основанный на функции из call_3d13.c, который чуть менее универсален, но удобнее в использовании.

void DOS(u8 pg, u8 operation,u8 blocks, u8 sector, u8 track, u16 begin_page) __naked

{

__asm

push ix

ld ix,#0

add ix,sp

ld a,4 (ix)

ex af,af

ld c,5 (ix)

ld b,6 (ix)

ld e,7 (ix)

ld d,8 (ix)

ld l,9 (ix)

ld h,10 (ix)

call #_DOS_3D13

pop ix

ret

__endasm;

}

Пройдёмся по параметрам.

PGномер страницы — буфера. В которую или из которой читаются или пишутся данные при работе с диском. Значение должно иметь вид: #0x7f - номер желаемой страницы.

Operationномер операции. Нас больше всего будут интересовать две операции: 5 — чтение блока секторов, 6 — запись блока секторов.

Blocksколичество считываемых секторов.

Sectorначальный сектор, с которого пойдёт считывание или запись.

Trackначальная дорожка, с которой пойдёт считывание или запись.

Begin_page — Адрес в странице PG начиная с которого в памяти будут размещены данные с диска или с которого эти данные начнут считываться.

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

u16 strlen (u8 * str)
{
static u8 a,i;
a=0;
while(1)
{
i=*str++;
if(!i) break;
if(i=='\0') break;// проверка на нуль-терминатор
if(i=='^') break;// ещё одна проверка на нуль-терминатор, который используется во внутреигровых текстах
a++;
}
return a;
}

i8 strcmp(u8 *str1, u8 *str2)
{
static u8 a,l1,l2;
l1=strlen(str1);
l2=strlen(str2);
if(l1>l2) return -1;
else if(l1

[Error: Irreparable invalid markup ('<l2)>') in entry. Owner must fix manually. Raw contents below.]

<p lang="ru-RU" style="font-style: normal; font-weight: normal">Выкладываю все свои статьи по ZX EVO SDK, зарелиженые ранее в Infoguide и ACNews

На чём делать игру? Могу предложить <span lang="en-US">EVO sdk. </span>Почему именно его?<span lang="en-US"> </span>Потому что я делаю игры в основном в этой среде и достаточно неплохо её изучил.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Я перешел на неё со связки <span lang="en-US">C++, OpenGl и</span>з за того, что мне хотелось просто делать свои игры, без долгой возни с оборудованием, разработки формата хранения моделей и создания конвертера под него (<span lang="en-US">Open GL </span>не имеет какого-то стандартного формата хранения моделей), хотелось чего-то более интересного чем банальный <span lang="en-US">PC.</span> Готовые движки меня не устраивали т.к. игра созданная на чужом движке не давала той радости, как игра написанная своими руками полностью с нуля. Языком <span lang="en-US">Assembler </span>я не владею и выбор сам собой пал на <span lang="en-US">EVO sdk.</span> Вот несколько аргументов в его ползу (Если, конечно вам не важна платформа, и вы не хотите делать трёхмерные игры):</p><ul>
<li><p><span lang="ru-RU"><span style="font-style: normal"><b>Лёгкий старт</b></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">. Для того чтобы просто инициализировать видеокарту и создать пустое окно на </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">OpenGl </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">нужно написать около экрана кода, в </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">EVO sdk </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">не нужно ничего инициализировать, всё уже готово. Если есть картинка спрайта, то её можно отобразить всего парой вызовов. Для начала работы нужно всего лишь взять заготовку </span></span></span><span lang="en-US"><i><span style="font-weight: normal">empty_project</span></i></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">, </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">открыть </span></span></span><span lang="en-US"><i><span style="font-weight: normal">main.c </span></i></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">и начать писать свой код.</span></span></span></p></li>
<li><p><span lang="ru-RU"><span style="font-style: normal"><b>Ресурсы</b></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">. С одной стороны ограниченные ресурсы платформ </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">ZX Evolution </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">и </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">ATM 2 </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">это огромный минус по сравнению с обычным пк с его гигабайтами и гигагерцами. Здесь нельзя воспроизвести </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">mp3 </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">в качестве фоновой музыки, нельзя использовать графику высокого разрешения в 24 битном цвете. Зато, ограничения &laquo;железа&raquo; сдерживают амбиции разработчика, тут уже сложнее &laquo;увязнуть&raquo; в процессе подготовки ресурсов. Ещё, в отличие от поиска готовых текстур, рисование пиксельной графики &mdash; это настоящее искусство. Программирование в условиях ограниченного пространства с не шибко быстром процессором быстро оттачивает навыки программиста. Приходится как-то &laquo;ужиматься&raquo;, оптимизировать код, выдумывать более быстрые алгоритмы, что само по себе уже довольно интересно.</span></span></span></p></li>
<li><p><b><span lang="ru-RU"><span style="font-style: normal">&laquo;Теплота и ламповость&raquo; - </span></span></b><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">Как ни крути, а </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">Zx-evolution </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">и АТМ 2 являются клонами, </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">zx Spectrum, т</span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">олько с дополнительными возможностями, которые мы и задействуем.</span></span></span></p></li>
</ul><p><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">Что собственно из себя представляет </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">EVO sdk. </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">Это кросс компилятор языка </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">C SDCC</span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">, набор библиотек позволяющих максимально отдалиться от низкоуровневой работы с железом и набор утилит и скриптов, позволяющих максимально просто и быстро из исходников и ресурсов собрать готовый образ </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">tr-dos. </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">Вся эта система позволяет без лишних телодвижений на домашнем компьютере, в любом удобном для вас редакторе на простом и понятном языке С написать игру, которая будет использовать навороты </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">ATM2 </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">или </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">Pentevo. </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">Правда за удобства придётся расплачиваться потерей быстродействия, увеличенным объемом кода (компилятор не совершенен и там где опытный программист на ассемблере обойдётся десятью командами, компилятор может использовать тридцать и более) и ограниченными возможностями (это не такая большая проблема, ассемблерные вставки делать никто не запрещал).</span></span></span></p><p><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">Взять её можно вот здесь: </span></span></span><a href="http://alonecoder.nedopc.com/zx/evosdk_libs.rar">http://alonecoder.nedopc.com/zx/evosdk_libs.rar</a></p><p><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">В рамках этой статьи я не буду подробно описывать все возможности </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">EVO sdk</span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">, и давать комментарии ко всем его функциям</span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">.</span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal"> Вся необходимая информация есть в </span></span></span><span lang="en-US"><i><span style="font-weight: normal">readme.txt</span></i></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">, </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">и все функции подробно прокомментированы в </span></span></span><span lang="en-US"><i><span style="font-weight: normal">evo.h</span></i></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">.</span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal"> Здесь я опишу новые &laquo;фишки&raquo; </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">SDK, </span></span></span><span lang="ru-RU"><span style="font-style: normal"><span style="font-weight: normal">такие как работа с памятью и диском, а так же несколько &laquo;подводных камней&raquo; с которыми можно столкнуться в начале работы с </span></span></span><span lang="en-US"><span style="font-style: normal"><span style="font-weight: normal">SDK:</span></span></span></p><p style="margin-top: 0.42cm; page-break-after: avoid"><font face="Arial, sans-serif"><font size="4">Графика: </font></font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Руководство говорит: &laquo;Графика должна быть подготовлена в формате BMP без сжатия, с 16 или 256 цветами (используются первые 16 цветов). Для этого могут использоваться любые стандартные графические редакторы.&raquo;. Включая стандартный <span lang="en-US">paint. </span>Однако не все редакторы подходят для этой цели. Вся графика, очень желательно, должна быть в 16 цветах т.&nbsp;к. 256-цветные изображения занимают существенно больше места. Следовательно <span lang="en-US">Paint </span>и подобные ему редакторы не подходят. Для подготовки графики наилучшим образом подходят программы типа <span lang="en-US">GIMP </span>и <span lang="en-US">Photoshop, </span>которые умеют создавать &laquo;палитровые&raquo; изображения. Но здесь есть одна меленькая деталь. <span lang="en-US">Gimp </span>начиная с версии 2.8 и новые версии <span lang="en-US">Photoshop</span>, сохраняют &laquo;палитровые&raquo; <span lang="en-US">BMP </span>несколько странно. Из картинок сделанных в этих редакторах <span lang="en-US">SDK </span>не может получить палитру, причём вся информация о цветах сохраняется и если подставить к изображению уже готовую палитру, то оно будет отображаться нормально. Я настоятельно рекомендую использовать <span lang="en-US">GIMP </span>версии 2.6.9. В версии 2.7.* есть небольшой глюк с рендером рабочего пространства при сильном увеличении.</p><p lang="en-US" style="font-style: normal; font-weight: normal">SDK <span lang="ru-RU">умеет работать со спрайтами 16x16px</span> <span lang="ru-RU">(до 64х штук) и имеет два режима: Отображение спрайтов включено или выключено. При включённом отображении спрайтов, рисовка всех тайлов происходит на два экрана сразу, при выключенном &mdash; только в теневой экран. Это нужно учитывать при построении изображения. С включёнными спрайтами рисовка тайлов идёт существенно медленней.</span></p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Так же при отображении спрайтов прозрачными считаются цвета после 16го т.&nbsp;е. можно использовать все цвета палитры плюс прозрачный, а при отображении тайлов прозрачный цвет нужно указывать из палитры. Следует учитывать при разработке игры, что спрайты имеют на один цвет больше и либо не использовать тайлы с прозрачностью, либо дублировать прозрачный цвет из карты тайлов в карту спрайтов, либо выдумать что-нибудь ещё.</p><p lang="ru-RU" style="margin-top: 0.42cm; page-break-after: avoid"><font face="Arial, sans-serif"><font size="4">Звук:</font></font></p><p lang="en-US" style="font-style: normal; font-weight: normal"><span lang="ru-RU">Со звуком не должно возникнуть каких-либо затруднений, но стоит предостеречь от чрезмерного использования </span><i>Covox</i>. <span lang="ru-RU">Воспроизведение </span><i>wav</i> <span lang="ru-RU">через </span><i>covox</i> <span lang="ru-RU">хоть и звучит внушительно, но приостанавливает выполнение основной программы, что нарушает динамику игры, а так же сами звуки занимают достаточно много места в памяти. </span><i>Covox</i> <span lang="ru-RU">можно использовать при переходах в меню, окончании уровня и т.д. </span></p><p lang="ru-RU" style="margin-top: 0.42cm; page-break-after: avoid"><font face="Arial, sans-serif"><font size="4">Программирование:</font></font></p><p lang="en-US" style="font-style: normal; font-weight: normal"><span lang="ru-RU">Переменные внутри функций желательно объявлять с использованием ключевого слова </span><b>static</b>, <span lang="ru-RU">это существенно уменьшает объём скомпилированного кода.</span></p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Так же, желательно избегать частого вызова функций с большим количеством параметров или со сложными типами в качестве параметров. Это так-же увеличивает объём скомпилированного кода. В случае если работы с такими функциями избежать не удаётся, можно объявить параметры этой функции как глобальные переменные и инициализировать их данными до вызова.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Карты игровых уровней и прочие большие массивы данных, которые нужны не часто, лучше всего выносить в отдельные страницы памяти и при необходимости загружать их во временный буфер в основной памяти. Это замедляет программу, но экономит место в памяти, которое можно занять более полезными вещами.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Чтобы ещё сильнее сэкономить место в памяти, карты уровней можно вынести в отдельные файлы на диске</p><p lang="en-US" style="font-style: normal; font-weight: normal"><span lang="ru-RU">Руководство по </span>SDK <span lang="ru-RU">обещает около 55кб. Под скомпилированный код, однако счётчик объёма кода врёт. По факту это ограничение = 32к. Игра нормально скомпилируется, но может не заработать или в процессе игры начнут самопроизвольно появляться и исчезать какие-либо объекты. Если подобные странности начали происходить, скорее всего ваш скомпилированный код превысил максимальный объём. </span><span lang="ru-RU"><i>(Сейчас уже решено модульной системой: максимальный размер основного модуля =32к, максимальный размер дополнительного модуля =16к, количество дополнительных модулей не ограничено)</i></span></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"></p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Чуть выше я сказал, что <span lang="en-US">SDK </span>умеет работать со страницами памяти. Для этого вам понадобятся функции из <span lang="en-US"><i>getmem.c</i></span><span lang="en-US"> </span>и хедер <span lang="en-US"><i>startup.h</i></span><span lang="en-US">. </span>Для записи данных в память есть функции: <u>put_mem</u> (1 байт), <span lang="en-US"><u>put_memw</u></span><span lang="en-US">(2 </span>байта) и <span lang="en-US"><u>put_meml</u></span><span lang="en-US">(</span>4 байта). Где параметры:</p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><span lang="en-US"><u>PG</u></span><span lang="en-US"> &ndash; </span>номер страницы, куда пишутся данные.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><span lang="en-US"><u>ADDR</u></span><span lang="en-US"> &ndash; </span>адрес внутри страницы куда данные пишутся.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><span lang="en-US"><u>DATA</u></span><span lang="en-US"> &ndash; </span>собственно сами данные.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Будьте внимательны, не пишите данные в страницы уже занятые игрой под ресурсы или код. Посмотреть какие страницы под что отведены можно после компиляции проекта в окошке компилятора. Так же следует помнить, что эти функции предназначены для работы с памятью <span lang="en-US"><i>ATM2</i></span><span lang="en-US"> </span>и у нас есть всего 64 страницы &mdash; 1мб. Адрес смещения от начала страницы должен выглядеть так: 32768+смещение.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Для получения данных из памяти есть функции: <span lang="en-US"><i><u>get_mem,get_memw </u></i></span><i><u>и </u></i><span lang="en-US"><i><u>get_meml</u></i></span><span lang="en-US">, </span>которые возвращают 1,2 и 4 байта соответственно.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal"></p><p lang="ru-RU" style="font-style: normal; font-weight: normal">Теперь о работе с диском. В <span lang="en-US">Sdk </span>реализована функция <span lang="en-US"><i>TR-dos</i></span><i> </i><u>3</u><span lang="en-US"><u>d13</u></span><span lang="en-US">, </span>правда вызвать её можно только из ассемблерной вставки, но есть обвязка этой функции на языке С, которая находится в <i>call_3d13.c</i>. Я предлагаю свой вариант обвязки основанный на функции из <span lang="en-US"><i>call_3d13.c</i></span><span lang="en-US">, </span>который чуть менее универсален, но удобнее в использовании.</p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">void DOS(u8 pg, u8 operation,u8 blocks, u8 sector, u8 track, u16 begin_page) __naked</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">{</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">__asm</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">push ix</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ld ix,#0</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">add ix,sp</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ld a,4 (ix)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ex af,af</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ld c,5 (ix)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ld b,6 (ix)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ld e,7 (ix)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ld d,8 (ix)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ld l,9 (ix)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ld h,10 (ix)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">call #_DOS_3D13</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">pop ix</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">ret</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">__endasm;</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">}</font></p><p lang="ru-RU" style="margin-top: 0.42cm; font-style: normal; font-weight: normal; page-break-after: avoid"><font face="Times New Roman, serif"><font size="3">Пройдёмся по параметрам.</font></font></p><p lang="en-US" style="font-style: normal; font-weight: normal"><u>PG</u> &ndash; <span lang="ru-RU">номер страницы &mdash; буфера. В которую или из которой читаются или пишутся данные при работе с диском. Значение должно иметь вид: #0x7f - номер желаемой страницы.</span></p><p lang="en-US" style="font-style: normal; font-weight: normal"><u>Operation</u> &ndash; <span lang="ru-RU">номер операции. Нас больше всего будут интересовать две операции: 5 &mdash; чтение блока секторов, 6 &mdash; запись блока секторов.</span></p><p lang="en-US" style="font-style: normal; font-weight: normal"><u>Blocks</u> &ndash; <span lang="ru-RU">количество считываемых секторов.</span></p><p lang="en-US" style="font-style: normal; font-weight: normal"><u>Sector</u> &ndash; <span lang="ru-RU">начальный сектор, с которого пойдёт считывание или запись.</span></p><p lang="en-US" style="font-style: normal; font-weight: normal"><u>Track</u> &ndash; <span lang="ru-RU">начальная дорожка, с которой пойдёт считывание или запись.</span></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3"><span lang="en-US"><u>B</u></span><u>egin_page</u> &mdash; Адрес в странице <span lang="en-US">PG </span>начиная с которого в памяти будут размещены данные с диска или с которого эти данные начнут считываться.</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">Всё достаточно просто, но для ещё большего удобства можно использовать вот такую конструкцию.</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">u16 strlen (u8 * str)
{
static u8 a,i;
a=0;
while(1)
{
i=*str++;
if(!i) break;
if(i==&#39;\0&#39;) break;// проверка на нуль-терминатор
if(i==&#39;^&#39;) break;// ещё одна проверка на нуль-терминатор, который используется во внутреигровых текстах
a++;
}
return a;
}</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">i8 strcmp(u8 *str1, u8 *str2)
{
static u8 a,l1,l2;
l1=strlen(str1);
l2=strlen(str2);
if(l1&gt;l2) return -1;
else if(l1<l2) br="" return="">else
{
for(a=0;a<l1;a++)<br>{
if(*(str1+a)&lt;*(str2+a)) return 1;
if(*(str1+a)&gt;*(str2+a)) return -1;
}
}
return 0;
}</l1;a++)<br></l2)></font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">void load_file(u8 *filename,u8 page,u8 saveload)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">{</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">static u8 buf[16];</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">static u8 a;</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">static u16 c;</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">DOS(#0x7f-dospage,5,7,0,0,32768);//прочтем нулевую дорожку</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">vsync();</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">buf[8]=&#39;^&#39;;</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">c=0;</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">while(strcmp(buf,filename)!=0 &amp;&amp; c&lt;1792)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">{</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">for(a=0;a&lt;16;a++)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">{</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">buf[a]=get_mem(dospage,32768+a+c);</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">}</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">buf[8]=&#39;^&#39;;</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">c+=16;</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">}</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">vsync();</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">if(saveload==1)</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">{</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">DOS(#0x7f-page,5,buf[13],buf[14],buf[15],32768);</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">}</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">else</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">{</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">DOS(#0x7f-page,6,1,buf[14],buf[15],32768);</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">}</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">vsync();</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">}</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">Функций <span lang="en-US"><u>strcmp</u></span><span lang="en-US"> </span>и <span lang="en-US"><u>strlen</u></span><span lang="en-US"> </span>нет в <span lang="en-US">EVO_sdk, </span>как и всех стандартных функций <span lang="en-US">C, </span>поэтому пришлось дописать вручную. Привожу их на всякий случай, вы с лёгкостью можете написать свои. Теперь подробнее о функции <span lang="en-US"><u>Load_file</u></span><span lang="en-US">.</span></font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3"><span lang="en-US"><u>Filename</u></span><span lang="en-US"> &mdash;</span> указатель на буфер, хранящий имя файла на диске.</font></p><p lang="en-US" style="font-style: normal; font-weight: normal"><font size="3"><u>Page</u> &ndash; <span lang="ru-RU">номер страницы в которую писать или из которой читать данные.</span></font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3"><u>Saveload</u> &mdash; операция. 1 &mdash; чтение, остальные значения &mdash; загрузка.</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">Функция <u>load_file</u> читает нулевую дорожку диска в страницу &mdash; буфер, указанную в dospage, затем пробегает по полученным файловым записям и ищет в них вхождение имени искомого файла. А затем производит чтение или запись при помощи функции <span lang="en-US">DOS.</span> </font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">Чтобы вставить свои файлы в финальный образ и дать свежескомпилированной программе к ним доступ нужно открыть compile.bat и после строчки<i> call ..\evosdk\_compile.bat</i></font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">вставить строку такого вида: <i>call trdtool.exe + %output% </i><span lang="en-US"><i>filename</i></span><i>.0</i></font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">где <span lang="en-US">filename &ndash; </span>имя файла, который вы хотите добавить в образ.</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">В общем-то и всё. По <span lang="en-US">EVO sdk </span>я описал самые коварные моменты, всё остальное легко разбирается по документации <span lang="en-US">SDK. </span>Так-же как хороший пример можно разобрать исходники, которые идут в комплекте со средой.</font></p><p lang="ru-RU" style="font-style: normal; font-weight: normal"><font size="3">А для тех, кто не умеет писать на </font><font size="3"><span lang="en-US">C. </span></font><font size="3">На </font><font size="3"><span lang="en-US">EVO sdk </span></font><font size="3">свет клином не сошелся, есть ещё множество сред разработки как с программированием, так и без. Главное, чтобы было желание, идеи и вдохновение, остальное приложится. Дерзайте!</font></p><p lang="en-US" style="font-style: normal; font-weight: normal"><font size="3">Hippiman 2015</font></p>

?

Log in