Unchained Nostalgia v1.3.1 [2016/10/14] (демка для NES/Famicom/Dendy)

Демка на основе популярного многоигрового картриджа для Dendy с романтическим сюжетом и Unchained Melody в меню. Для запуска нужен эмулятор NES (например, Nestopia). Архив включает также Unchained Melody в форматах NSF и NSFe. Прослушать её можно, например, в foobar2000 с плагином Game Emu Player. Вариант в формате NSFe более предпочтителен, так как он содержит больше мета-информации и длину трека, чего не может быть в устаревшем формате NSF. Это означает, что проигрывание NSFe корректно заканчивается вовремя, в отличие от NSF.

Скачать: unchained_nostalgia.zip (20KB). Исходный код →

Посмотреть в записи

Что сделано?

  • Создано на основе Super HIK 300-in-1.
  • Появились осмысленные облака и звёзды, теперь все слайды уникальны и нет дублей только с изменённой палитрой.
  • Добавлено два новых слайда для точного соответствия музыке, в оригинальные слайды внесён ряд небольших исправлений.
  • Добавлен эффект плавной смены слайдов (медленный при старте, быстрый при просмотре).
  • Автоматическая подстройка скорости воспроизведения и высоты звука на системах NTSC и PAL для работы как на Dendy.
  • Автоматическое переключение слайдов в такт музыке (каждые 4 удара). Для отключения нажмите любую кнопку после запуска. Для повторного включения автоматического режима нажмите Start.
  • При удержании одной из кнопок направления, слайды меняются в такт музыке (каждый удар) в выбранном направлении.
  • Секретный режим управления Вселенной (только не говорите об этом санитарам).
  • Супер-секретный режим гордой птички со спецэффектами от легендарного Майкла Бэя.
  • И целый ряд других секретных фишек =)

Сравнение HIK 300-in-1, v1.0 и v1.3
















Ссылки

  1. #1
    AJ_Maker

    Евгений, молодец )) не ожида, что ты до сих пор занимаешься этим хаком ))
    Только недавно репостнул видос первой версии, с сылкой на 1.2, а ты уже 1,3 выпустил ))
    Просто молодец )) так держать )

  2. #2
    VEG Автор

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

  3. #3
    VEG Автор

    Релиз Unchained Nostalgia v1.3.1. Исправлена регрессия из v1.3.0, которая приводила к «плавающему» темпу музыки на точных эмуляторах и реальном железе.

  4. #4
    xapuk

    Идея пришла внезапно.
    Ещё лучше то, что идею есть кому воплотить в жизнь.
    Идея в том , чтобы вместо влюблённой пары сделать Россию и Украину - ну и далее на тему примирения наций. Аж прослезился, когда представил, как здорово это будет.
    Думал просто подрисовать имеющиеся изображения и запаковать обратно в ROM. Никогда не задумывался в каком виде в ROM хранятся изображения - но, как оказалось, всё намного сложнее.Поэтому не справлюсь - однозначно.
    Желаю успеха и миллиарда просмотров на ТыТрубе

  5. #5
    VEG Автор

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

  6. #6
    «G~Lí†ch»

    Помнится мне, что при переключении страницы (кнопкой Select или B, или просто перемещая "птичку") затормаживалась музыка. А перед повтором цикла действительно есть задержка! Даже нашёл отдельную NSF'шку, весом в 13 402 байт (то ли zophar.net, то ли http://ftp.modland.com, если не modarchive.org), и при помощи NSFImport'a я закинул в FamiTracker эту NSF'шку с параметрами 144 строк за "такт" (12 нот на Pulse 2 канале в каждом Frame).
    Так вот, если приглядеться, то можно заметить, что на канале Noise попадается разный контур громкости — сначала идут D-B-9-7-5-3-1-0, потом внезапно E-C-A-8-6-4-2-0, или иногда задевает концовку предыдущей ( D-B-9-7-5-3-2-0 или D-B-9-7-5-4-2-0 и т.д.), получается, что в FamiTracker не помещаются все изменения громкости, вписанные в исходном NSF.
    А если промотать ко второму циклу, то повторяемое место уже будет выглядеть немного иначе: все ноты (и их снятие, эффекты) смещены на одну строку (что и создало запаздывание при повторении), в т.ч. по DPCM каналу (точно так же разбросаны "=" (Note Off), непонятно зачем — ни однго звука не прописано же). А эта самая "громкость" по-идее должна быть "с такими же ошибками" и интервалом, но оказывается, E-C-A-8-6-4-2-0 появляется в других местах как будто продолжает глючить дальше! Это может значить, что в NSF на Noise канале записан всего один Pattern, в котором прописан зацикленный звук с изменением громкости (от E до 0), но скорость изменения громкости гораздо быстрее, чем позволяет это сделать FamiTracker (да и DefleMask тоже). Можно конечно в FamiTracker'е просто удалить последний Frame, и экспортировать в NSF, чтобы не было задержки перед повторением, но модуль уже не совпадает с исходным вариантом... А то этот "горе-аранжировщик" походу умудрился воткнуть Pattern Break (или может быть Position Jump) в первую строку после концовки.

  7. #7
    VEG Автор

    «G~Lí†ch»,

    Вы себе неправильно представляете формат NSF. Там внутри находится программа. Она отсылает команды эмулируемому чипу NES APU RP2A03. Тут нет никакого стандартного способа хранения нот. В каждую NSF зашивается код звукового движка из какой-то игры и музыкальные данные из этой же игры, которые понимает именно этот движок. Достоверно импортировать любой NSF в формат FamiTracker нельзя. Можно написать эмулятор, который будет выполнять программу из NSF и запоминать команды, которые она отправляла на NES APU, пытаясь преобразовать их в то что понимает FamiTracker. Но это не одно и то же что банальное «импортирование». В исходных музыкальных данных все ноты и настройки инструментов представлены в очень компактном виде. Чтобы более-менее достоверно это «импортировать» таким образом, нужно запоминать отправляемые в NES APU команды 60 раз в секунду, и наверняка множество неявных трудностей тут тоже есть. Например, в исходных музыкальных данных может быть какой-то один инструмент, который отсылает сразу несколько разных команд в звуковой чип, и движок из соответствующего NSF это понимает. Но при подобном «импортировании» вы получите совсем иную картину, снаружи это будет выглядеть как несколько разных инструментов, играющих одновременно.

    Ещё один момент. Музыка этой менюшки писалась фамиклонов типа Dendy. В Dendy частота обновления была 50Гц, как в NES PAL, но при этом железо было заточено для совместимости с NES NTSC, поскольку для этой версии системы игр было больше, но у NTSC частота обновления 60Гц. Таким образом, Dendy был некоторым гибридом NES NTSC и NES PAL. От NES PAL была частота обновления экрана (и в NES все процессы на это завязаны), от NES NTSC было почти всё остальное, включая высоту тона одних и тех же команд звуковому процессору. Таким образом, если NSF запускается в режиме NTSC на 60Гц, чтобы музыка звучала с нормальной скоростью, программа пропускает каждый шестой кадр, таким образом получается высота звука и скорость воспроизведения как у Dendy. Если же NSF запускается в режиме PAL, то используются другие таблицы преобразования нот в команды звуковому процессору, которые дают похожий по высоте звук на NTSC. Эти адаптации я добавлял в музыкальный движок демки. Оно сразу определяет на чём оно работает, и потом применяет соответствующую адаптацию (или ничего не адаптирует, если определяет что оно работает на настоящей Dendy или в эмуляторе с поддержкой Dendy). NSF-плееры на PC, как правило, запускают движок в режиме NTSC, так что движок пропускает каждый шестой кадр.

    Помнится мне, что при переключении страницы (кнопкой Select или B, или просто перемещая "птичку") затормаживалась музыка.

    Это я исправил в этой демке. Точнее, затормаживание при переключении слайдов всё равно есть, но его нереально услышать, теперь музыка «задерживается» лишь на 1/60 секунды при смене кадра. Это тоже можно было обойти, но пришлось бы сильно усложнять код загрузки новой картинки в видеопамять без реальной на то необходимости.

    Даже нашёл отдельную NSF'шку, весом в 13 402 байт

    В архиве с этой демкой есть и отдельный NSF, гораздо более компактный (всего 2240 байт), но с той же (идентичной) музыкой. Я там оставил только код, который относится к музыкальному движку и сами музыкальные данные, плюс к самим музыкальным данным я применил поддерживаемую движком возможность отсылки на дублирующиеся фрагменты мелодии без их повтора. Можно было сделать ещё меньше немного, если лишить движок возможности проигрывания звуковых эффектов по событиям (в NSF оно не используется). Но я решил оставить полную версию движка, как и в демке, тем более что в демке звуковые эффекты используются в пасхалках :)

  8. #8
    «G~Lí†ch»

    Сравнил эти две NSF'шки, и нашёл в них два сходства, только по разным адресам: Первое сходство: [5C6]h—[6F7]h; второе: [816]h—[8B0]h, кроме байта [8A5]h (03h вместо 06h). Ещё есть немного похожее место с [194]h по [1E6]h, только в 13402-байтной версии (сразу же после 11 тысяч нулей) некоторые байты забиты нулями в таком же промежутке... Дальше ещё больше различий... Видимо, из-за "прописанной адаптации".
    Получается, что ноты там те же (так же, как и лишние «Note Off» на DMC). Но чего только в вашей "версии" темп такой медленный (да-да, знаю, что сама песня ещё медленнее)? Темп почти такой же, как в переключенной в PAL 9999999-in-1.nes! Вот в FCE Ultra 13-килобайтная NSF-шка вообще не реагирует на переключение PAL/NTSC, в отличие от Nestopia. А если вашу редакцию NSF'шки переключить из PAL в NTSC, то темп станет более привычным, но тоном чуть выше. А если открыть как NTSC (в обоих эмуляторах), то можно ЕЩЁ замедлить и понизить, переключив в PAL :D
    Даже NSFImport'ёр из вашей NSF'шки гораздо кривее "извлёк" мелодию, чем из 13-килобайтной с 11 тысячью нулями.

    может быть какой-то один инструмент, который отсылает сразу несколько разных команд в звуковой чип

    Значит, те Note Off, которые я видел на DPCM канале в FamiTracker'е, на самом деле занимают всего один бит в тех байтах, в которых прописаны «звучащие» "ноты" (т.е. размер файла не изменится, если убрать эти комманды)?
    В NES Audio Processor Unit'е должно же быть что-то вроде "указателя зацикливания" (ведь не все же мелодии воспроизводятся сначала), и в этой мелодии надо его как-то сместить (тогда уже придётся либо на слух, либо записывать в аудио, и проверять совпадение атаки прямо по фазе)... Если все остальные NSF-мелодии зацикливаются ровно, почему Unchained Melody в NSF варианте такая ошибка? Вряд ли тут из-за длины трека, поэтому и "обвинил" аранжировщика.
    Вообще, если существует дамп той версии, у которой абсолютно другая мелодия, то надо будет и её всунуть в демку, прописав затухание по вызову (такое в NES APU тоже должно быть, т.к. в Маугли (Jungle Book) такой эффект есть) "секретной комбинации смены трека" =)... Хотя, лучше после трёх циклов просто модуляцию сделать, чтоб не надоедала.

  9. #9
    VEG Автор

    «G~Lí†ch»,

    Получается, что ноты там те же (так же, как и лишние «Note Off» на DMC). Но чего только в вашей "версии" темп такой медленный (да-да, знаю, что сама песня ещё медленнее)?

    С чего вы взяли что он медленный? Я же объяснил, что моя версия играет именно так, как эта мелодия играла на Dendy, на которую и было это рассчитано. То что у вас другой файл играет слишком быстро — это только потому, что он запущен в режиме NTSC, на который он совершенно не рассчитан. Вместо 50 тиков в секунду (как было в Dendy и NES PAL) делается 60 (как было в NES NTSC), и поэтому всё играет сильно быстрее чем должно быть. В моей версии когда мелодия запущена в режиме NTSC, каждый 6-й тик пропускается, поэтому мелодия играет с правильной скоростью, как было задумано авторами.

    Вот в FCE Ultra 13-килобайтная NSF-шка вообще не реагирует на переключение PAL/NTSC, в отличие от Nestopia. А если вашу редакцию NSF'шки переключить из PAL в NTSC, то темп станет более привычным, но тоном чуть выше. А если открыть как NTSC (в обоих эмуляторах), то можно ЕЩЁ замедлить и понизить, переключив в PAL :D

    Не стоит такой ерундой заниматься. Определение что за железо используется идёт при старте, и дальше всё работает так, будто всё время работает именно на этом железе. В случае с NSF тип железа (NTSC или PAL) передаётся отдельным параметром самим эмулятором при старте. То есть возможность дополнительной адаптации при переключении типа на лету в принципе не предусмотрено (и по-хорошему эмулятор обязан делать reset сразу после изменения типа железа, чтобы избежать непонятных эффектов).

    Даже NSFImport'ёр из вашей NSF'шки гораздо кривее "извлёк" мелодию, чем из 13-килобайтной с 11 тысячью нулями.

    Вероятно, пропуск каждого 6 кадра сбивает эту утилиту с толку.

    Значит, те Note Off, которые я видел на DPCM канале в FamiTracker'е, на самом деле занимают всего один бит в тех байтах, в которых прописаны «звучащие» "ноты" (т.е. размер файла не изменится, если убрать эти комманды)?

    Вполне возможно, что это движок синтезатора отсылает эту команду, и в нотах этого в принципе нет.

    В NES Audio Processor Unit'е должно же быть что-то вроде "указателя зацикливания" (ведь не все же мелодии воспроизводятся сначала)

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

    Если все остальные NSF-мелодии зацикливаются ровно, почему Unchained Melody в NSF варианте такая ошибка? Вряд ли тут из-за длины трека, поэтому и "обвинил" аранжировщика.

    Не понимаю о какой именно ошибке речь.

  10. #10
    «G~Lí†ch»

    Ну, посмотрел "исходный код" этой мелодии, удобно расписано для каждого канала:
    sound_notes_0: Pulse 1
    sound_notes_1: Pulse 2
    sound_notes_2: Triangle
    sound_notes_3: Noise.
    С лишней «Note Off» я разборался: во всём виноваты "паузы" в sound_notes_0 и в sound_notes_2, с байтами $81 и $83 — как я понял, после $81 здесь указывается байт с длительностью этой паузы, затем байт $83 — конец паузы (?) ...Да, в данном случае действительно размер файла не изменится, но размер можно уменьшить в других местах, не изменив звучание мелодии.
    Для "треугольника" можно сократить дублирующие ноты (NSFImport'ёр вместо двух нот всё равно одну распознаёт, да и эмулятор играет их "непрерывно"):
    sound_notes_2:
    .BYTE $80, 2
    .BYTE $18, $90, $15, $90, $11, $90, $13, $90, $18, $90, $15, $90, $10, $90, $13, $24
    .BYTE $1F, $24, $23, $24, $26, $24, $1C, $48, $1F, $24, $24, $48, $1C, $24, $21, $24
    .BYTE $24, $48, $1D, $24, $26, $24, $24, $24, $23, $24, $1F, $24, $28, $24, $26, $24
    .BYTE $81, $24, $83, $1C, $24, $1F, $24, $24, $48, $1C, $24, $21, $24, $24, $24, $1F
    .BYTE $90, $26, $90, $24, $90, $23, $24, $1F, $24, $23, $24, $26, $24, $18, $90, $1C
    .BYTE $90, $1D, $90, $1F, $90, $18, $90, $81, $90, $83
    .BYTE $84, 1, @endbass
    .BYTE $18, $48, $16, $48
    .BYTE $84, 1, @endbass
    .BYTE $18, $90
    .BYTE $86

    @endbass:
    .BYTE $11, $48, $13, $48, $15, $48, $16, $48, $11, $48, $13, $48, $85
    Правильно ли я понял, что ещё $85 должно стоять в данном случае?
    И мелодия в sound_notes_0 в этом месте так же повторяется. Правильно ли я "укомпановал" ? .BYTE $81, $06
    .BYTE $84, 1, @ending_volta
    .BYTE $26, $0C, $24, $0C, $28, $0C, $2B, $24, $2D, $0C
    .BYTE $28, $0C, $24, $06, $26, $06, $24, $30, $81, $0C
    .BYTE $84, 1, @ending_volta
    .BYTE $28, $0C, $26, $0C, $24, $90
    .BYTE $86

    @ending_volta:
    .BYTE $83, $1D, $0C, $1F, $24, $21, $0C, $24, $0C, $23, $30, $24, $0C, $23, $0C
    .BYTE $21, $30, $1D, $0C, $21, $0C, $1F, $48
    .BYTE $1D, $0C, $1F, $24, $21, $0C, $24, $0C, $26, $30, $85

  11. #11
    VEG Автор

    «G~Lí†ch», из моих заметок:

    $80 - начало канала, выбор инструмента след байтом?
    $81 - начало блока задержек (по одному байту)
    $82 - следующим байтом задержка
    $83 - конец блока задержек
    $84 - проиграть заданный кусок заданное количество раз
    $85 - конец отдельного куска, вернуться назад где было $84
    $86 - мотай в начало!
    ноты идут по два байта, нота в первом байте, задержка во втором

    Скорее всего разбивать блоки $81 .. $83 нельзя. Вероятно, блоки $81 .. $83 с одним значением между можно заменять одним $82 с параметром. Надо смотреть код движка чтобы понять есть ли там различия. Там ещё иногда блоки $81 .. $83 идут подряд. Непонятно почему их не пообъединяли. Возможно, просто редактор, в котором писалась музыка, сохранял звуковые данные не в самом оптимальном виде.

    Объединять одинаковые команды, которые издают звуки, я не стал, так как моей задачей было добиться идентичного звучания во всех возможных случаях. То есть на оригинальном железе Dendy оно должно звучать так же, как и прежде. Возможно, идущие подряд одинаковые команды со своими задержками давали немного другой звук. Мои адаптации для NES NTSC и NES PAL касаются только того, чтобы сделать звучание как можно ближе к Dendy.

    Примеченные вами повторы фрагментов нот не заметил. Если когда-нибудь вернусь к этому проекту, то приму ваше замечание во внимание и сокращу запись и в этих местах. Вообще я для этого проекта хотел сделать новый алгоритм сжатия данных фоновых картинок. Чисто из спортивного интереса :) Было бы весьма любопытно сделать что-то типа LZ (словарного) сжатия для такого слабого процессора с такими ограничениями по памяти, чтобы оно ещё моментально работало, не медленнее того что есть. Интересный challenge.

    А вы это как-то логично разбили sound_notes_0 и sound_notes_2, типа блоками как оно звучит? Если да, не могли бы вы предоставить полностью разбитые по строкам варианты этих данных — включу в исходник в таком виде, чтобы понятнее выглядело.

    UPD: Проверил в коде. $81 и $83 ещё что-то дополнительное отсылают в APU, в сравнении с просто с $82. Так что заменять на $82 не стоит. $82 вообще не используется конкретно в этой мелодии — в мелодиях из других игр от NTDEC можно глянуть как оно используется :)

    UPD2: В sound_notes_2 ещё два повтора заметил небольших :) Думаю, обновлю всё же файл, раз уж залез.

  12. #12
    «G~Lí†ch»

    типа блоками как оно звучит?

    Я пока не въёхал в вопрос...
    Я сначала думал, что $80 это № паттерна, но потом подумал, что само "название sound_notes_№" и есть паттерн, а на каких каналах этот "блок" играет, должно указываться заранее. Но, скорее всего, я ошибаюсь.
    Если больше пяти нот повторяется, то имеет смысл делать, т.к. сам "повтор" 4 байта занимает, а ещё байт $85 в конце повторяющегося фрагмента вставлять. Ведь недаром в sound_notes_1 есть только два фрагмента, которые ни разу не повторяются, поэтому он не выносил их в отдельные "@part'ы"
    Можно уточнить гармонию, которые воспроизводят эти "парты":
    @part1 — @c (до мажорное трезвучие)
    @part2 — @am (ля минорное трезвучие)
    @part3 — @f (фа мажорное трезвучие)
    @part4 — @g (соль мажорное трезвучие)
    @part5 — @em (ми минорное трезвучие)
    @part6 — @c7 (до мажорный спетаккорд)
    @part7 — @g7 (соль мажорный септаккорд)
    @part8 — @eb (ми-бемоль мажорное трезвучие)
    Кстати, если уж и перерелизить, то с исправленным окончанием в NSF: Перед $86 сократить значение на единицу:
    в sound_notes_0 последняя нота будет: $24, $8F
    в sound_notes_1 предпоследняя строка:
    .BYTE $18, $C, $1C, $C, $1F, $C, $24, $C, $1F, $C, $1C, $B
    в sound_notes_2: .BYTE $18, $8F (или $18 $48 $18 $47)
    после @beat:
    .BYTE $34, $C, $2F, $C, $2F, $C, $2F, $C, $2F, $C, $2F, $C
    .BYTE $84, 62, @beat
    .BYTE $34, $C, $2F, $C, $2F, $C, $2F, $C, $2F, $C, $2F, $B
    .BYTE $86

    Поправил эти байты HEX-editor'ом в 13-килобайтной NSF'шки (там повторы не указаны, просто подряд, как играется, так и написано), потом завёл на эмуляторе — задержки больше нет!
    Однако в этом случае нужно проверить на железном Dendy. Если же там наоборот "ускорится", то придётся возвращать всё обратно, и разбираться как раз именно из-за $86 (а может и $80, ведь он тоже повторяется?). Возможно в нём какой-то код создаёт эту задержку на эмуляторах.

  13. #13
    VEG Автор

    «G~Lí†ch»,

    Я пока не въёхал в вопрос...

    Ну условно то как играет музыка можно разбить на сегменты, отмеренные четырьмя повторами «ударников» (по которым синхронизировано автоматическое переключение слайдов). Данные других каналов можно разбить по строкам соответственно, типа вот это первый сегмент, это второй, это третий и т.д. Я имел в виду это.

    Ведь недаром в sound_notes_1 есть только два фрагмента, которые ни разу не повторяются, поэтому он не выносил их в отдельные "@part'ы"

    Этот некто «он» — это я :) Увидел что движок умеет выносить наружу повторяющиеся части — задействовал эту фишку.

    Поправил эти байты HEX-editor'ом в 13-килобайтной NSF'шки (там повторы не указаны, просто подряд, как играется, так и написано), потом завёл на эмуляторе — задержки больше нет!

    О какой задержке речь? Я ради интереса прокрутил демку десяток раз — не слышу никаких задержек. Не могли бы вы конкретнее описать что именно вы хотите исправить? Или вы хотели просто уменьшить задержку между повторами на один такт? Судя по коду — задержку в один такт создаёт $86. Он очищает все регистры APU и чтение следующей ноты начинается только на следующем такте. $80 же принимается за воспроизведение следующей ноты сразу же. По идее можно обучить $86 начинать проигрывать повтор на этом же такте, но не уверен, действительно ли это нужно :)

    Этот же код умеет воспроизводить и звуковые эффекты, которые по событиям запускаются. Типа звука по Select+Start. Так вот в этом случае $86 значит «конец воспроизведения», то есть зацикливания нет. Переделать так чтобы оно не делало задержку в один такт для музыки здесь кажется просто (сразу вижу 3 места где нужно внести небольшие правки), но это не будет учитывать, что для эффектов мы не должны такого делать, и надо немного глубже вникнуть в код, чтобы добавить проверку, не эффект ли это, и если эффект, то как и прежде завершать работу на этом.

    К слову, из NSF можно ещё вырезать куски кода, которые отвечают за воспроизведение этих эффектов, поскольку в NSF этот код никак не задействован. Но я решил что лучше пускай там будет полная версия движка :) Тем более, что там может каких 100-200 байт на этом можно сэкономить разве что.

    Глянул код. У $86 логика несколько сложнее. Он останавливает звук на канале, но движок ждёт когда на всех каналах будет $86, и только тогда перезапускает воспроизведение. И на этом теряется один такт. В принципе, тоже можно было бы переделать, чтобы воспроизведение начиналось с того же такта, когда везде уже $86, но это уже будет несколько сложнее, чем казалось сразу. Похоже, что игра не стоит свеч, тем более что речь о задержке всего в 1 такт (тут и выше под «тактом» я понимаю «кадр», то есть 1/50 или 1/60 в зависимости от приставки).