Движок трекмо
Интересно Ваше мнение на такую тему как движок трекмо.
Я думаю, что движок должен делать следующее:
Итак, по первому пункту нужно отслеживать время, отрабатываемое частью:
По иниталайзу — да, декранч / депак скрина и т.д. — всё что нужно приготовить перед стартом новой части.
Кроме того, думаю что стоит добавить просмотр всего списка для выявления ВСЕХ подпрограмм, которые должны быть вызваны в этот момент демо. Значит, пусть будет заготовлен список вызовов для кернеля. И, возможно, стоит как-то определить их особенности — строчные, фреймовые и т.д. Но это частности, пожалуй.
Итак, вполне возможно что данные для движка должны выглядеть как-то так:
Т.е., при выборе первых значений записываем время выхода в цикл отсчёта, part_code_x в вызовы отображения (вполне возможно это всё использовать в инте), decrunch_code2 прописываем в основной цикл. в decrunch_code_х должны быть проверки на конец задачи с выходом.
Что я не учёл и какие рабочие примеры движка можно привести? Для размышлений и кода.
Прошу поделиться опытом и наработками, и давайте обсудим узкие моменты.
Я думаю, что движок должен делать следующее:
- Отслеживать время перехода от части к части
- Отрабатывать иниталайзы частей
- Отработка декранча следующей части в процессе показа, при необходимости / возможности проца
Итак, по первому пункту нужно отслеживать время, отрабатываемое частью:
- возможно, это количество halt для каждой части;
- возможно — это отслеживание переключения позиции паттернов в плеере.
По иниталайзу — да, декранч / депак скрина и т.д. — всё что нужно приготовить перед стартом новой части.
Кроме того, думаю что стоит добавить просмотр всего списка для выявления ВСЕХ подпрограмм, которые должны быть вызваны в этот момент демо. Значит, пусть будет заготовлен список вызовов для кернеля. И, возможно, стоит как-то определить их особенности — строчные, фреймовые и т.д. Но это частности, пожалуй.
Итак, вполне возможно что данные для движка должны выглядеть как-то так:
dw end_time,part_code0,decrunch_code_part2 ;(либо 0 - если декранч не нужен)
dw end_time,part_code1,0
dw end_time,part_code2,0
dw end_time1,part_code3,decrunch_code_part3
dw end_time1,part_code4,0
Т.е., при выборе первых значений записываем время выхода в цикл отсчёта, part_code_x в вызовы отображения (вполне возможно это всё использовать в инте), decrunch_code2 прописываем в основной цикл. в decrunch_code_х должны быть проверки на конец задачи с выходом.
Что я не учёл и какие рабочие примеры движка можно привести? Для размышлений и кода.
Прошу поделиться опытом и наработками, и давайте обсудим узкие моменты.
20 комментариев
Немного о ядре psndcj . Оно очень шустрое и легковесное. Ядро сидит чуть ниже верхней страницы. Обработчик прерывания находится в ядре и является его ключевой частью. Прерывания разрешены ВСЕГДА. Обработчик считает фреймы и, при достижении различных ключевых моментов в треке, запускает пользовательские коды. Преимущество работы с номерами фреймов (в противоположность номерам паттернов, например) заключается в том, что
1. Это позволяет синхронизироваться не с точностью до паттерна, а точнее, вплоть до каких-то звучков, индивидуально.
2. Вообще говоря, очень часто музыка играется из PSG, т.е. музыка уже полностью потеряла информацию о номерах строк, паттернах и т.д., а синхронизироваться всё ещё нужно.
Кроме этого, в ядре находился декомпрессор, процедура быстрого копирования данных и процедуры для эффективной работы со скрытым экраном. Идея в том, что по окончанию отрисовки в скрытый экран, код может начинать рисовать следующий кадр, а собственно переключение экрана осуществляет само ядро, сразу после прерывания. Это позволяет более эффективно использовать машинные ресурсы.
Недостаток, с моей точки зрения, этого ядра заключался в том, что оно было написано для работы в стиле «распаковали эффект», «показали эффект», «расчиститили место для следующего эффекта». Ядро запускает эффект и пока эффект не закончился, ядро не контролирует процесс. Конечно, так писать в чём-то проще. Но это очень сильно усложняет фикс. Если нам, допустим хочется, что-то поменять в эффекте посередине эффекта, нам придётся внутри эффекта сравнивать счётчик фреймов ядра с какими-то константами, т.е., по сути, дублировать функциональность ядра.
Другим недостатком было то, что скрипт хранился в основной памяти (насколько я знаю, psndcj недавно сделал версию ядра в которой это ограничение было снято).
Женя psndcj , у меня понятно немного пристрастный взгляд на это всё, было бы классно если бы ты прокомментировал, м.б. расставил как-то иначе акценты. Кроме того, очень интересно узнать, что у тебя в ядре пришло в наследство от эксподера.
Какого рода команды есть у меня в скрипте? Самая главная команда: дождаться нужного фрейма:
Некоторые команды чисто утилитарные: например, копирование и распаковка данных.
(копируем упакованную картинку из 0й страницы вниз и потом рапаковываем её в экран на странице 7). Крайне, мегаполезные команды — kPOKE и kPPOKE:
(первая для байтов, вторая для слов). Когда нужно слегка модифицировать эффект для достижения какого-то фикса, нет ничего проще чем добавить простую заглушку (как в первом примере) или подменить адрес данных (как во втором).
Эффекты я обычно стараюсь писать в прерываниях. Обработчик ядра, помимо своих обыкновенных обязанностей, умеет запускать процедуру пользователя. Понятно, задача порубить эффект на фреймы не всегда удобно разрешима, но я стараюсь по возможности это делать, т.к. эффекты в прерываниях позволяют ядру работать параллельно с эффектами, что даёт некую ограниченную форму многозадачности. Типичный план фрейма таков: обработчик прерывания обновляет номер текущего фрейма, играет музыку, затем запускает процедуру пользователя, после чего контроль возвращается ядру. Скрипт может сказать ядру в этом случае ждать пока номер фрейма не достигнет чего-то, т.е. крутиться в холостом цикле до следующего прерывания. Но вполне возможен вариант, когда скрипт говорит ядру распаковать данные, и тогда получается, что каждый свободный такт, оставшийся во фрейме после эффекта, будет потрачен на распаковку. Вот пример достаточно нетривиального кода из Wonderball, для переключения со сцены 2 на сцену 3 (сцена три — это шас с радиальными лучами анимацией):
Поскольку эффект занимается чем-то своим, а ядро — чем-то своим, самой сложной частью для написания такого ядра оказывается менеджер памяти. При работе с таким ядром пользователь не имеет права менять страницы в обход ядра. Ядро ведёт учёт и отличает «страницу ядра», т.е. ту страницу, где хранится скрипт, «страницу музыки» (понятно), «страницу пользователя при работе прерывания» и «страницу пользователя при работе вне прерывания». Есть и другие нюансы, например, моё ядро работает не с реальными, а с виртуальными страницами, благодаря чему на классических машинах я всегда знаю, какие страницы медленные, а какие быстрые. Но я уже устал столько всего писать!
Из внешнего ядра можно вызывать все те же команды, что из внутреннего. Потому, при таком подходе можно так же управлять эффектом из скрипта вызывая kPOKE и т.д.
Ну и надо учесть факт, что в отличие от вас мы почти никогда не упирались на фреймовые эффекты, а всякие мультиколоры вообще были табу )
у меня:
и выборка данных с парсингом,
у тебя:
как сделано?
спасибо
надеюсь на конструктивные комментарии)
после 3вм