Просмотр полной версии : Портирование Asteroids
В начале июня начал попытки портирования Asteroids - игра на аркадном автомате от Atari - на Вектор-06Ц.
Этот аркадный автомат полностью векторный, на процессоре 6502.
Разобранные исходники оригинала:
https://www.computerarcheology.com/Arcade/Asteroids/
https://github.com/nmikstas/asteroids-disassembly/tree/master/AsteroidsSource
Моя задумка: обойтись полностью без рисования линий, всё только на спрайтах через XOR.
Память не экономим - держим все спрайты во всех фазах движения по горизонтали, всего порядка 22К на все спрайты.
Из объектов крутится только кораблик - делаю 8 фаз на сектор, в оригинале было 17 фаз на сектор.
0/1 планы под геймплей, переключать по завершению рисования через палитру.
2-й план под индикаторы.
Репозиторий с кодом:
https://github.com/nzeemin/vector06c-asteroids
Как обычно, буду рад вашим советам как сделать лучше.
UPDATE: скриншоты
https://pic.maxiol.com/thumbs2/1624121921.1845257517.202106105.png (https://pic.maxiol.com/?v=1624121921.1845257517.202106105.png&dp=2) https://pic.maxiol.com/thumbs2/1625699840.1845257631.202107064.png (https://pic.maxiol.com/?v=1625699840.1845257631.202107064.png&dp=2)
https://pic.maxiol.com/images2/1625936473.1845257631.a.gif
Текущее состояние: играбельная демо-версия: кораблик поворачивается и стреляет, но не летает.
Asteroids или клонов на стандартном векторе нет (есть для z80 (http://www.sensi.org/scalar/ware/293/)), поэтому несомненно плюсую.
Отличный выбор, присоединяюсь к ivagor-у.
Заранее просчитанные спрайты можно хранить сразу в виде кода, если влезают в память.
Отличный выбор, присоединяюсь к ivagor-у.
Заранее просчитанные спрайты можно хранить сразу в виде кода, если влезают в память.
Идея неплохая. А можно пример как это сделать наиболее эффективно?
То есть это через серию "загрузить в A байт, сохранить в (HL)" или "загрузить в HL слово, push его в стек" ?
Здесь же ещё и XOR с экраном нужно делать.
Здесь же ещё и XOR с экраном нужно делать.
Надо еще подумать, для начала что-то вроде
;HL=адрес в экране
;32 такта/байт спрайта, 5 байт программы/байт спрайта
mov a,m
xri байт спрайта
mov m,a
inr l (или dcr l или inr h или dcr h)
Я могу похвастаться только своими спрайтами в Рива рейде, вот их генератор
https://github.com/svofski/incursiondelrio/blob/master/makesprites.py
И пример того, что он делает
https://github.com/svofski/incursiondelrio/blob/master/ship.inc
Он идет зигзагом, загружает данные lxi и записывает в экран через push. Там нету перекрытий, поэтому получилось здорово сэкономить.
Для XOR разве только
mov a, m \\ xri xyz \\ mov m, a \\ inr l ; 8 + 8 + 8 + 8 = 32, или 64 на два байта
Или попробовать парами?
lxi b, xyz \\ mov a, m \\ xra c \\ mov m, a \\ inr l \\ mov a, m \\ xra b \\ mov m, a \\ inr l ;; 12 + 8 + 4 + 8 + 8 + 8 + 4 + 8 + 8 = 68
получается хуже, но если вместо lxi будет pop, получается, что не надо инлайнить данные и код. В общем с xor-ом похоже много не выгадаешь за счет такого разворачивания.
Еще идея - у нас 4 плоскости. Если три плоскости сделать одним цветом, можно три спрайта перекрывать "аппаратно". Вопрос к логике игры, сможет ли она группировать перекрывающиеся спрайты так, чтобы они были в разных плоскостях? Если да, то круто и можно упростить отрисовку спрайтов до простого затирания. Эффект не обязательно должен быть всегда идеально выполнен. Если что-то частично перетрется, но это исчезнет с глаз долой за 20мс, ну и ладно.
- - - Добавлено - - -
P.S. ivagor меня опередил. То, что у нас получились одинаковые примеры говорит о том, что может быть точно один из нас прав.
Если сравнить вариант с инлайнами данных спрайта с вариантом без инлайнов (с pop), то казалось бы разница всего в 2 такта/байт спрайта (32 vs 34), но надо учесть и возможность локальной оптимизации варианта с инлайнами в местах, где байты спрайта=0, и тогда разрыв увеличится. Насколько помню в river raid svofski так делал (без xor). При наличии места можно все спрайты заинлайнить, а если не хватает, то только самые критичные. Пишу капитанские вещи, но сужу по себе, иногда что-то давно знакомое вылетает из головы и напоминание помогает.
Насколько помню в river raid svofski так делал (без xor).
Да, разрывы и повторы. Повторов в астероидах много не случится, а вот разрывы могут быть. Прикольно, кольцевой спрайт с дыркой посередине. Если будет вообще получаться, можно будет внимательно посмотреть -- если вдруг где-то дырка портится из-за пары пикселей, попрощаться с парой пикселей и получить хорошую дырку.
Можно пойти еще дальше и сделать дырки через строку. Когда все быстро мельтешит можно много деталей простить.
Хорошо, что ivagor накапитанил, потому что я сам про это забыл.
Надо еще подумать, для начала что-то вроде
Т.е. хранить все 8 сдвинутых спрайтов? Это-ж сколько из будет?
Допустим 8 разных размеров (включая сам корабль) * 8(или 16) поворотов * 8(или 4) сдвигов = 512 спрайтов. Памяти-то хватит?
- - - Добавлено - - -
Из объектов крутится только кораблик
Так неинтересно...
Т.е. хранить все 8 сдвинутых спрайтов? Это-ж сколько из будет?
Да, я тоже прикидываю что процедурами хранить очень накладно получается.
Так неинтересно...
В смысле? в оригинале тоже только кораблик крутится - посмотрите внимательно.
Ещё можно посмотреть на векторный ROM - только для кораблика там заданы фазы поворота:
https://www.computerarcheology.com/Arcade/Asteroids/VectorROM.html
Да, я тоже прикидываю что процедурами хранить очень накладно получается.
Может быть все-таки попробовать, а уж как перестанет влезать, так и начать экономить? Вдруг влезет.
Насколько я увидел, на экране больше всего астероидов, т.е. основное время тратится на них, соответственно если пробовать инлайнить, то только астероиды(камни). В камнях много повторов, поэтому можно инлайнить процедуру с lxi, учитывая, что при переходе к следующей паре байтов не всегда надо их менять. Иногда надо будет поменять только один байт из двух (mvi вместо lxi). Еще можно попробовать проанализировать более тщательно и задействовать вторую регистровую пару под самые частые байты в камне. Их достаточно задать один раз на спрайт. Как минимум стоит попробовать инлайнить самые большие камни.
Вероятно стирание всего экрана это временное решение для прототипа, но на всякий случай обращу на него внимание. Переход на пообъектное стирание даст заметную прибавку скорости, а то сейчас очистка экрана отъедает >1/3 времени.
Вероятно стирание всего экрана это временное решение для прототипа, но на всякий случай обращу на него внимание. Переход на пообъектное стирание даст заметную прибавку скорости, а то сейчас очистка экрана отъедает >1/3 времени.
Я ещё подумаю.
Появилась ещё такая мысль: можно использовать ТРИ плана под игровой экран, переключая их по очереди, текущий ярко, предыдущий бледно - получим "эхо" для всех движущихся объектов.
Если использовать много плоскостей, и если выбрать приоритетом скорость, то можно как написал svofski раскидывать спрайты по плоскостям. Готового механизма в игре нет, я представляю примерно так: при выводе очередного спрайта смотрим по координатам, если нет наложения, то используем основную плоскость+0, если есть, то плоскость+1, если и там уже есть, то +2, и т.д. (если хватит памяти) до +3. Если плоскости кончились, то или рисуем процедурой с xor или просто портим какую-то из плоскостей. Выигрыш за счет отказа от чтения экрана и логических операций, но, конечно, будет помигивать.
Вариантов много, вопрос в приоритетах - "безмигательность", скорость, наличие спецэффекта, наверно еще что-то можно придумать.
- - - Добавлено - - -
будет помигивать.
Если разделить плоскости 2+2, то можно использовать переключение страниц и мигать не будет, но вопрос наложения спрайтов становится более острым.
Можно ещё поиграть с вариантом когда держим группу флажков "мы тут рисовали" и очищаем только там где запачкали.
Но пока я всё это откладываю на потом - хочу сначала логику реализовать, хотя бы основную часть.
Умозрительно представляется, что поблочное стирание эффективнее пообъектного при большом "коэффициенте перекрытия" спрайтов, но и пообъектное и поблочное стирание для asteroids явно должны быть эффективнее полноэкранного.
Сделал процедурное рисование для больших камней - спрайтов размером 32x32.
Пока набросал грубо, есть ещё возможность для некоторой оптимизации.
Объём кода процедур - 11164 байта, против 4*32*8*4 = 4096 байт данных спрайтов.
Результат: до того в 3 фрейма укладывалось 15 камней, сейчас 23 камня!
В эти 3 фрейма также входит стирание одного плана и обработка клавиатуры.
На ужасы нашего городка можно посмотреть тут: https://github.com/nzeemin/vector06c-asteroids/blob/master/astrosprt.asm и метод WriteSprite32x32Code() в SpriteRotate.
Приложил превью с 23-мя камнями. Кораблик вращается клавишами влево-вправо. Клавиша вверх - эффект взрыва кораблика.
Игра смотрится уже очень круто!
Пробую применить переключение планов через смену палитры.
Но есть ощущение, что я что-то делаю не так. Потому что изображение заметно моргает.
Причём моргают не только движущиеся, но и статичные объекты.
UPDATE: Разобрался, исправил. Теперь картинка такая как надо. Красота неописсуемая. Оч доволен.
Превью-4 в аттаче. стрелочка вверх - показать пламя.
https://pic.maxiol.com/thumbs2/1625014550.1845257517.202106292.png (https://pic.maxiol.com/?v=1625014550.1845257517.202106292.png&dp=2)
Выглядит круто, только немного смущают "волны", которые идут по камням при движении.
Волны явно не могут быть просто так, слишком они аккуратные. Это анимация?
Возможно "волны" - результат наложения единиц (от предыдущего изображения) при xor
Возможно, стоит подумать о рисовании спрайтов стеком и змейкой.
Волны тут от космического ветра 8-)
Может ошибся где-то при подготовке спрайтов, буду посмотреть.
Разбираюсь пока с тем как устроены столкновения в оригинале. В общем всё просто - для каждого объекта определяется размер хитбокса (hitbox), если хитбоксы пересеклись, то есть попадание. То есть берём расстояние между позициями по X и Y и проверяем что меньше заданного значения.
Я конечно не ожидал что там сумма квадратов будет считаться, но вроде бы восьмиугольник сделать не так сложно - проверять ещё (dX + dY) < N.
Я конечно не ожидал что там сумма квадратов будет считаться, но вроде бы восьмиугольник сделать не так сложно - проверять ещё (dX + dY) < N.
Для восьмиугольника есть красивая формула: dist = max(dx, dy) + (dx + dy) / 2;
Если множитель 1/2 заменить на 2/5, то ошибка представления диагоналей (относительно Евклида) будет чуть меньше 1%, о чём знали ещё древние греки.
Приаттачил превью 5.
Стрелки влево-вправо - повернуть кораблик, стрелка вверх - показать пламя, шифт - стрелять.
Набросал HitTest для двух объектов и определение столкновения "пуля - камень".
Действует пока нестабильно, есть ошибки, работаю над этим.
Превью 6.
Сделал разбиение камней на два при попадании.
И потом уже понял что перестарался - я сделал разделение с траекториями новых двух камней перпендикулярно пути исходного камня.
Получилось что камни при разделении ведут себя очень предсказуемо. Надо просто давать новым камням случайные скорости да и всё.
Хитбокс для всех камней пока одинаковый. Но как я говорил, там ещё и ошибки есть, буду исправлять.
Шрапнель (набор точек которые остаются после камня) - не нравится как получилось, надо менять.
Осколки кораблика - тоже не нравится, переделаю.
Круто! Уже почти можно играть.
Уже почти игра, выглядит здорово. "Финальные каменные брызги" очень желательно поправить. В оригинале, как я понимаю, при попадании в маленький камень есть 3 (или около того) кадра анимации, когда точки разлетаются из бывшего центра, это выглядит сильно лучше, чем синхронный полет облака точек в одном направлении.
Прогресс, и это здорово. Только вот снаряды при достижении края экрана вылетают с его противоположной стороны. Видимо искривление космического пространства ;).
Прогресс, и это здорово. Только вот снаряды при достижении края экрана вылетают с его противоположной стороны. Видимо искривление космического пространства ;).
Насколько я помню Астероиды, это труъ. Игра на торе.
снаряды при достижении края экрана вылетают с его противоположной стороны
В оригинале тоже вылетают с другой стороны, хотя может там пробег чуть меньше, но не уверен.
Странно, вот только-что смотрел какую-то версию с атари, на ютубе и там был клиппинг. Причём с запасом зачем-то
PS. Пересмотрел ещё раз. Точно, вылетают с другой стороны.
Пролетают всегда одно и то же расстояние - полный экран. И правда получается тор. Если кораблик не в центре и стрельба ведётся через весь экран то не так заметно просто.
https://www.youtube.com/watch?v=w60sfReTsRA
Вот например, оригинальная аркада. Здесь отчетливо видно, как выстрелы улетают и появляются с противоположного края экрана.
Я смотрел вот эту (https://www.youtube.com/watch?v=WYSupJ5r2zo), мутноватую :)
В моей экранка, но источник труъ =)
Реализовал переключение трёх планов, с эффектом эха, ну получился такой типа эффект "motion blur".
Ох у меня и так перед глазами все плывет, не уверен, что требуется спецэффект для этого. Но как опцию может быть прикольно было бы оставить.
При всей интересности идеи фиолетовое эхо не выглядит убедительно. Возможно его отбеливание с уменьшением яркости поможет делу, но я однозначно за опциональность такого эффекта.
"Фиолетовое эхо" звучит как сленговое название какой-то стадии опьянения.
- - - Добавлено - - -
А, ну точно -- purple haze
Shumadan
06.07.2021, 14:01
а на Спец ее можно портировать?
а на Спец ее можно портировать?
Если ваш вопрос о том - можно ли? - то ответ "конечно да", считайте, что все материалы на гитхабе выложены под public domain (нет никаких ограничений по использованию).
Я могу рассказать-показать-помочь, если где что непонятно.
Если же вопрос о том - буду ли я это делать - то ответ "скорее всего нет", мне это просто не очень интересно, сорри.
Портировать на специалист в лоб все же было бы затруднительно в связи с наличием только одной экранной плоскости, надо перерабатывать организацию вывода спрайтов.
Превью версии 9.
- Исправил ошибки с рисованием больших камней
- Демо-режим, при переходе с заставки, переход в игровой режим по нажатию Fire
- Счётчик количества живых камней в углу - но иногда он где-то лажает
- После уничтожения последнего камня начинаем новую волну (если счётчик не слажал)
Превью версии 9.
...
- Демо-режим, при переходе с заставки, переход в игровой режим по нажатию Fire
...
При перезапуске не корректно инициализируется: Текст с экрана не исчезает; кораблик пропадает.
А траектории камней принципиально выбраны по диагонали? Просто разлёт осколков под прямым углом - выглядит странно. Угол 45 градусов возможно воспринимался бы более естественным (с моей субъективной точки зрения). Понятно, что ни у кого нет практического опыта отклонения орбиты астероидов при помощи дробления их на более мелкие ;)
При перезапуске не корректно инициализируется: Текст с экрана не исчезает; кораблик пропадает.
Речь про "мягкий" ресет видимо, особенность Вектора? пока не занимался этим совсем.
А траектории камней принципиально выбраны по диагонали? Просто разлёт осколков под прямым углом - выглядит странно. Угол 45 градусов возможно воспринимался бы более естественным (с моей субъективной точки зрения).
Говорил уже об этом - сделаю просто рандомные скорости от точки разлёта. Сейчас слишком предсказуемо разлетаются, неинтересно.
Хотя игра в целом уже и выглядит как "почти готово", но на самом деле там ещё очень много работы: доделка анализа столкновений, НЛО, доделать цикл игры и game over, подсчёт очков, бонусные жизни итд.
Речь про "мягкий" ресет видимо, особенность Вектора?
Именно так - в "Векторе" по БЛК-СБР память не очищается, и даже некоторые коммерческие игры (или, возможно, их криво взломанные пиратские копии :smile:) "грешили" тем, что корректно не рестартовали по БЛК-СБР
P.S. Запустил самую последнюю версию в эмуляторе - это огонь, бомба-пушка-ракета!
Даже в текущей MVP стадии создаётся стойкое ощущение, что играешь не на "Векторе", а на настоящем игровом автомате :Atari:
Иногда снаряды пролетают насквозь через самые большие астероиды, это особенно заметно в начале новой волны. Нетерпится уже поуправлять корабликом.
Похоже, я понял в чём проблема с хит тестом. Скорость пуль относительно высокая, часто получалось так что проверки на попадание были до и после объекта - в результате попадания нет. Компенсировал это бОльшим размером хитбокса.
Исправил проблему с неверным подсчётом камней - дело было в попадании в шрапнель, исключил её из проверок.
Сделал паузу перед каждой волной с показом надписи "WAVE N".
В целом это уже более похоже на демо.
Сделал детектирование столкновения "камень - кораблик", уменьшение жизней, переход на Game Over.
Кому лень запускать эмулятор - жирная гифка под спойлером:
https://pic.maxiol.com/images2/1625936473.1845257631.a.gif
Эта версия очень промежуточная, выкладываю только для сравнения с предыдущей.
Сделал флаги "испачканности" колонок (column dirty flags) - при рисовании в колонке отмечаю что она "грязная", при очистке плана очищаю только грязные колонки.
Как результат - ускорение наверное раза в полтора или чуть меньше. Если раньше в игре было 2-3 фрейма, то теперь 1-2.
Не ожидал что получится достичь такой скорости.
Видимо, буду искуственно притормаживать до двух фреймов, чтобы скорость геймплея была постоянной.
Обалдеть как быстро стало!
Демо версия 4:
# Рисовать индикаторы только когда есть изменения
# Замедлять игру до 2 фреймов на цикл
# После Game Over по таймеру возвращаться в демо-режим
Чисто как идея, куда ещё можно было бы применить движок от Asteroids:
https://www.youtube.com/watch?v=Dt44PEIWBRg
Если ограничиться только вертикальным скроллом, то можно было бы запилить подобную игру и на Векторе.
Чисто как идея, куда ещё можно было бы применить движок от Asteroids:
https://www.youtube.com/watch?v=Dt44PEIWBRg
Если ограничиться только вертикальным скроллом, то можно было бы запилить подобную игру и на Векторе.
Сначала надо эту игру доделать, что-то тяжело идёт.
А вообще я думал ещё про Lunar Lander: https://youtu.be/KQHD7TRAank
На первый взгляд thrust part в реализации на векторе заметно сложнее asteroids, а вот lunar lander возможно даже на бейсике получился бы неплохо (или хотя бы только спрайт кораблика рисовать в кодах).
Я тоже за доделанный Астероидс =)
Второй голос за Lunar Lander. Его можно и на калькуляторе, но все же там есть чему быстро реагировать и плавно двигаться и когда экран быстро обновляется выглядит это кайфово.
Improver
16.07.2021, 13:30
Я что-то погуглил про Lunar Lander, был ещё и такой вариант: https://lunar69.uber.space/
Текстовая версия, а зацепила... :)
Есть несколько векторовских посадок на луну на бейсике, lafromm31 стримил, в т.ч. и текстовая, если не ошибаюсь.
Есть несколько векторовских посадок на луну на бейсике, lafromm31 стримил, в т.ч. и текстовая, если не ошибаюсь.
Их скорее всего почти каждый обладатель Вектора делал, кто выписывал "Технику молодежи" ;)
Improver
16.07.2021, 16:48
Что lafromm31 стримил я не видел, но да, помню, было что-то. Бегло просмотрел архив бейсиковских игр, есть "Лунолёт-2", почти текстовый, но там надо взлететь, пролететь какое-то расстояние и сеть на луну. Есть ещё игра "Посадка на луну", с вырвиглазной палитрой и текстовой графикой, скорее всего порт с другого ПК, по смыслу больше похожа, хотя посадить лунолёт в ней гораздо проще, чем в Lunar Lander.
На Бейсике я и сам тогда делал что-то подобное, но не по "Технике молодёжи", а по журналу "Наука и жизнь" (который выписывал), жаль именно от этой игры ничего не осталось.
... Есть ещё игра "Посадка на луну", с вырвиглазной палитрой и текстовой графикой, скорее всего порт с другого ПК, по смыслу больше похожа, хотя посадить лунолёт в ней гораздо проще, чем в Lunar Lander.
На Бейсике я и сам тогда делал что-то подобное, но не по "Технике молодёжи", а по журналу "Наука и жизнь" (который выписывал), жаль именно от этой игры ничего не осталось.
В журнале "Техника молодежи" была серия статей с программами для калькуляторов МК52/МК61 соответственно портируя их и графика была "любительская", т.к. в оригинале её вообще не было.
Сколько было программ в серии уже не помню 6 или 7. Программы объединялись одной историей перелёта с Луны на Землю на не большом челноке.
Взлёт-посадка, перелёт на расстояние - это первые "эпизоды", так сказать обучение азам управления челноком. Могу ошибаться, но мне кажется его называли "Кон-Тики", как плот Хейердала.
Потом были взлёт с Луны и стыковка к (окололунной) орбитальной станции.
Перелёт вокруг станции. Полёт от станции до "точки Лагранжа", для дозаправки.
Перелёт до орбиты Земли. Вход в атмосферу. Посадка в стиле Шаттлов.
Это если склероз не изменяет...
И естественно были попытки переложить эти алгоритмы на Бейсик.
Удивлён, что сохранилось только по одному экземпляру...
Хотя я в то время вообще записывал не на кассеты, а на бабины/катушки...
Привет всем...
С Техники молодежи - делал игру Страна Монстров...
Версия для Спектрума осталась...
На vtrd.in
Вчера посмотрел игрушку на «почти» реальной машине - на MiSTer FPGA в конфигурации Вектор-06Ц - работает, так приятно.
https://pic.maxiol.com/thumbs2/1628759479.1845257631.202108111.jpg (https://pic.maxiol.com/?v=1628759479.1845257631.202108111.jpg&dp=2) https://pic.maxiol.com/thumbs2/1628759496.1845257631.202108112.jpg (https://pic.maxiol.com/?v=1628759496.1845257631.202108112.jpg&dp=2) https://pic.maxiol.com/thumbs2/1628759507.1845257631.202108113.jpg (https://pic.maxiol.com/?v=1628759507.1845257631.202108113.jpg&dp=2)
А на ЭЛТ будет еще приятней =)
Добавлена поддержка Джойстик-П, по спекам отсюда: https://zx-pk.ru/threads/29374-dzhojstiki-na-vektore-06ts.html
https://github.com/nzeemin/vector06c-asteroids/commit/6a9a90b4959392557b777856d6dbd6546f466240
Проверил на эмуляторе VV_702.
Версия упакованная через LZSA2, с распаковщиком от ivagor.
Свободной памяти осталось чуть меньше килобайта.
В текущей версии с большим трудом добираюсь до третьей волны - видимо надо облегчить игроку задачу?
Летать пока нельзя?
Сделаю обязательно.
А вот про НЛО и гиперспейс уже сомневаюсь, нужны ли вообще.
А вот про НЛО и гиперспейс уже сомневаюсь, нужны ли вообще.
Я не большой спец по Астероидсам. Но могу представить себе, что тот, у кого рука набита, может быть разочарован тем, что их нет.
Добавлена поддержка Джойстик-П, ...
А чего *demo5 64КБ, хотел в реал загрузить, а он великоват оказался ...
В *demo6 Джойстик-П не работает.
Есть желание дописать игру, но пока нет возможности.
К сожалению, с сентября занят на 100%, ни на что времени нет.
svofski, прошу поместить пока демо-версию игры в Базис как есть.
Понимаю. Будем ждать!
Upd: http://sensi.org/scalar/ware/914/
А чего *demo5 64КБ, хотел в реал загрузить, а он великоват оказался ...
В *demo6 Джойстик-П не работает.
Вроде как исправил работу с Джойтик-П, проверил на эмуляторе и на MiSTer.
Проверьте пожалуйста, если у кого есть такая возможность.
aGGreSSor
19.10.2025, 02:11
В принципе, да - в космосе нет звуков.
Чтобы второй раз не искать: https://caglrc.cc/scalar/ware/914/
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot