А какая проблема с фоном по знакоместам?
- - - Добавлено - - -
Ссылка есть?
Вид для печати
ZXInno_0.1
Про бочки на полу там же на картинке, и сразу далее мы обсуждаем.
Готовая(запечёная) графика, сразу с клешингом.
...на колу мочало, начиная сначала :v2_dizzy_facepalm:
а повышенная частота памяти, чтобы в кадре их успеть прочитать - это не больший аппаратный ресурс?
или неведомая схема "внутреннего z-буфера" - это не больший аппаратный ресурс?
Только для нескольких удобных для схемы случаев. Причём в их удобстве надо убедиться, копаясь в логике.
Цветов меньше, фон и спрайты только двухцветные.
Кем, как именно? Если как:
- то лично я уже с постановкой не соглашусь (даже не касаясь пока что не доказанной "минимальности")
Мне вот хочется плавной регулируемости усилий (и результатов, соответствующих усилиям).
Без клэшинга - уже значит не "как на Спектруме". Если речь об обязательной двухцветности объектов - то с какой стати?
Не "потом", а польза блиттера несомненна и в деле ускорения старых игр.
Это мы еще посмотрим, насколько точно. :v2_dizzy_coder:
Нет, невыгодно. "Таким образом" получаем процессорное время в КАЖДОМ игровом кадре на КАЖДЫЙ спрайт = SaveBack + PutSprite + RestoreBack. Если же "чистый" фон заранее единожды создан в буфере, получается только PutSprite + RestoreBack (с незаметной ОДНОКРАТНОЙ задержкой только при переходе в новый экран). Что экономичнее для процессора?
По максимальному общему размеру максимального числа спрайтов, способных оказаться на экране одновременно.
Причём в случае разного размера и формы спрайтов и код сложнее, и возможно, памяти нужно больше.
И с чего бы вдруг процу-то не успевать? При не совсем уж мелких объектах расход времени на поиск нужных тайлов будет меньше времени SaveBack. Расход памяти также будет скорее меньше - не нужны буфера для фона под каждым спрайтом.
Хехехе, но ведь "существующие игры так делают" :D В основном потому, что (даже без прокрутки фона) не успевают обновить все спрайты и прочие объекты игрового логического кадра за тв-кадр (и даже за несколько тв-кадров). Вот и приходится сначала сначала рисовать в буфер, а потом перебрасывать весь буфер на экран синхронно с лучом, чтобы ничего не мерцало. Также в буфере может адресация быть другой, не совпадающей с экранной спектрумовской раскладкой.
Ответ был таков же, как и вопрос, но кое-кто, похоже, его не понял :rolleyes:
Сферическая процедура в вакууме. На практике может оказаться совсем не так. Ну да ладно, можно и такой пример обсудить.
...даже не подозревая, что прерывание нагадило в слой №1 с непредсказуемыми последствиями или вместо нужных данных прочло нули :p
А я вообще не буду адаптировать алгоритм и старый код совсем никак не буду менять))) Адаптировать следует конфигурацию (не путать с прошивкой) видеодевайса к этому коду. Достаточно сообщить видеокарте основные ключевые точки графпроцедур, типо: здесь читается полоска фона, здесь маска спрайта, а здесь обратная запись байта фона с кусочком спрайта. Фактически сообщаем смысл сигналов системной шины при выполнении процессором команды с этого адреса. Реализовать возможно по-разному, например, как массив кодов внутренних (немногочисленных и простых) команд видеокарты, осуществляющих аналогичные операции над полосками полноцветных пикселей и внутренним аналогом атрибутов. Основную часть массива заполнить "нопами", а команды загрузить перед игрой спецпроцедурой-конфигуратором (можно даже до загрузки самой игры).
Вот на что ресурсы ПЛИС потратить имеет смысл, вместо имитации пачки Спектрумов! :v2_dizzy_roll:
- - - Добавлено - - -
Атрибутные эффекты?.. но это мелочь, основные недостатки zx-poly и подобных решений - нерациональность и неудобство расширения-улучшения.
"Абсолютно для всего" (ну, разве что, кроме слишком хитро самоизменяющегося кода) подойдёт подход, только что описанный мной чуть выше ^
Скрытый текст
(вообще, кстати, применимый при любой структуре внешней видеопамяти, в том числе при б-гомерзкой многослойной... :v2_dizzy_biggrin2: только зачем?) :v2_sick:[свернуть]
Зачем? ну зачем переделывать старые добрые игры на ZX, их не хватает в цвете на других платформах? откуда они портированы, Вы по сути делаете 4 шага назад и 0 вперед.
забачно, zx-poly и "ему подобные решения" единственные кто сохраняет обратную совместимость и дает программеру возможность самостоятельно делать решения (в отличии от решений видеокарт где мы дадим мегажелезо и протокол, а делать всё будет видяха гдет внутри) и при этом упрекается в неудобстве расширения-улучшения :) ну дак спектрум вообще то это платформа которая вообще не предназначена к расширению-улучшению еще на старте, это её фича, что там всё расширение не благодаря, а вопрекиЦитата:
zx-poly и подобных решений - нерациональность и неудобство расширения-улучшения.
И в чем же (якобы) "несовместимость" других решений?
Какой-то бессмысленный набор слов. Что такого "несамостоятельного" в управлении девайсом по протоколу? Чем оно принципиально отлично от управления процессором Z80 через протокол его машинного языка (вместо, скажем, непосредственного контроля над его четырёхбитным АЛУ)))
А разъём Expansion фирменного Спектрума, стало быть, назвали так шутки ради? :D
7 МБайт/с для восьми слоев, которых по-уши хватит, чтобы расклэшить практически все - это много?
Так. Отставить. Цифра 250 была приведена чисто показать, что фантастические требования к памяти - это не соответствует действительности. Необходимости в таком количестве слоев просто нет, хотя и его можно реализовать без фантастических запросов к объему и быстродействию памяти.
Кстати, а вам сколько ресурсов понадобится, чтобы реализовать соответствие "буфер - экран" и отслеживать шину? Я так подозреваю, что мелкой логикой тут не обойдешся..
Для остальных вариантов удобных случаев еще меньше.
Потому, что с перерисовкой графики уже соовсем другая песня. Добавляются такие непростые вопросы "где хранить?", "как загружать?", "как выводить?". И да, есть ZX-Poly/Spec256 и это направление, имхо лучший вариант в таком случае.
Как раз сомнительно, что старые игры нужно ускорять, но это дело хозяйское..
Нужен отдельный буфер для хранения фона. Даже для 2/3 экрана - это 10% от имеющейся памяти.
С чего бы это меньше? Фон обычно хранится не сплошняком, а как список тайлов с координатами их вывода. Так просто компактнее. "Дерево, x=2, y=5", "Кустик, x=10, y=12", "Лестница, x=8, y=3, длина=10". Правда думаете, что процедить такой список совсем просто?
Не спорю. Но в подавляющем большинстве существующих игр спрайты можно пересчитать по пальцам.
С чего бы это? Найти начало и конец обработчика прерывания и выставить там нужный слой - задача совсем не сложная.
Согласен, тяжелый случай. В буфере нет информации, о том, какому объекту какой пиксель принадлежит. В любом случае потребуется более глобальная переделка.
Ответ был в стиле "С точки зрения банальной эрудиции.." Похоже вы сами не совсем понимаете, как это можно сделать..
Это правильно. Но это только уровень общения игры, её доработки и карты. Игра остаётся фактически не тронутой и ничего не знает о карте. Конкретная доработка, в загрузчике, обучает карту работе с конкретной игрой. Карта-же способна смотреть все события на шинах и интерпретировать. Это почти ZX-prop, не хватает ещё способности в нужный момент выдать нужные данные на шину данных вместо данных из ОЗУ, и как код_операции и как данные.
В этой-же теме, "новый принцип устранения клешинга", интересен уровень рассмотрения возможностей карты для устранения клешинга.
И Lethargeek, и inozemcew предложили свои наборы возможностей, это хорошо, но зачем-то цепляются к друг другу, это плохо. Скучно вас читать, когда вы пытаетесь доказать что другой не прав.
Слои Иноземцева, это хорошо. Это понятно программисту и хакеру. Это требует нетрудного хакерского внедрения в программу.
Есть затык с играми, бросающими на экран кадр из буфера. Пока просто не берём такие игры, и всего делов-то. :)
Есть затык с передачей самой маски в карту, общего решения нет, придётся попыхтеть.
Идея Lethargeek-а.
Восстановление фона через ту-же процедуру, что и рисует фон... это занятно, но ИМХО слишком специфично, либо требует серьёзной переделки большинства игр. А поскольку это специфично, это более отпугивает от начала работы. Хакеру-же нужно преодолеть некоторый порог уверенности в успехе. Побоится, что вот он вроде посмотрит, всё тайлами смотрится, всё вроде получается переделать, он проделает работу, а возле финального боса какой нибудь спецэффект не получится переделать, и он войдёт в эстетический диссонанс с проделанной переделкой, и впечатление смажется.
во-1 для двухбитнопиксельных (это если с маской) слоёв - вдвое больше
во-2 не хватит: сходу контрпример из классики - Cybernoid, в котором по экрану мало что летают тучи мелких объектов (притом часть - с непостоянными атрибутами), так еще и бонусы падают на землю и там накапливаются :v2_dizzy_rain:
Ну как же нет)) для того же киберноида дофига понадобится слоёв, если (как предложено было ранее) после каждого спрайта брать чистый слой. А иначе - долго возиться в коде и пилить динамический диспетчер спрайтов для "нефантастического" числа, а потом еще упихивать его в память и следить, чтоб не было побочных эффектов.
"Похоже вы сами не совсем понимаете, как это можно сделать.." (с)
да уж точно меньше, чем для многослойной схемы схожих возможностей
какой "мелкой"? на дворе 2016 год!
"остальные" с киберноидом лучше справятся :p
а что, есть какие-то варианты, кроме памяти видеокарты (лучше уж на это её потратить, чем на полсотни унылых монотонных слоёв, всё равно которых где-нибудь, да не хватит)
молча, блин! (вот каков вопрос, таков и ответ!) ...что конкретно кажется "непростым"?
Лучший разве что по критерию "как бы применить побольше аппаратных ресурсов, но при этом так и не решить проблему клэшинга во всех случаях". Эмулировать кучу параллельных синхронных Спектрумов ради этого ну совершенно необязательно.
минус память, которая нужна была бы на куски фона, так что меньше (и порою весьма существенно)
думаю, что проще брать адрес тайла по двум координатам карты экрана (формируемой при переходе в другую комнату, заодно выполняющей и функцию карты проходимости, например)
уточняю: в подавляющем большинстве игр в персональной выборке Иноземцева :)
при несложных обработчике и контексте... и выглядит гораздо менее "минимально"
и не надо, хватит и цвета пикселя, получаемого видеодевайсом при отрисовке (безразлично - в буфер или в экран)
переделка мЫшления потребуется, чтоб понять, что переделка кода вообще не требуется :v2_dizzy_turn:
похоже, кое-кто здесь не понимает, что мои сообщения следует дочитывать до конца :rolleyes:
(и ведь не впервые уже такое, начинает даже на умышленную тактику походить)
- - - Добавлено - - -
На самом деле лучше, чем "ZX-prop" (ZX-poly?) именно потому, что видеокарта не обязана выполнять точные аналоги оригинальных "однобитнопиксельных" команд (что позволит, в частности, бороться с глюками ксорок).
Чисто для обесклэшивания игр чтение с девайса совсем не нужно, да и новые эффектные игродемы вполне можно без него делать. Зато полностью пассивный девайс попроще и не требует лезть с ножом и паяльником в потроха компов.
Ну, вот он я, программист и немножко "хакер" :) (покопавшийся когда-то в коде игрушек в ходе написания эмулятора) - и не могу придумать ну вот никак, за каким бы хреном мне могли бы понадобиться слои, и зачем вообще в программу что-то "внедрять", если можно этого избежать.
Ты о чём, какой еще "переделки"? Старый код необязательно трогать же. Только сообщить видеокарте, где подменить несколько команд пересылки и обработки пикселей (таковых команд в типичных играх совсем немного)
Прости, вообще не понимаю. Разжуй пожалуйста на примере. Вот допустим у нас некий Lode Runer. В пиксельном плане персонажи рисуются и стираются по XOR. В атрибутном плане цвет персонажа красит знакоместа в режиме "моляр", восстанавливается из 768 байтного буфера.
ВОПРОС. Как будет работать переделка, того типа как ты описываешь?
Вот моё недоумение. Старый код не трогаем, кода восстановления фона под спрайтами не было изначально, так откуда он возьмётся и восстановит нам фон?
Надо разбираться с конкретным кодом. Лодераннер я поверхностно посмотрел. Вообще можно с ксорками по-разному поступать.
1) Просто побитно ксорить многобитные пиксели, результат примерно будет похож на spec256 или zx-poly (смотря по кодированию цвета, индекс или непосредственно RGB). То есть на чёрном фоне - правильные цвета, при накладках - разноцветное месиво. Зато проще всего вспомогательный код в памяти видеокарты, и сами команды этого кода - аналоги спектрумовских чтения, записи и ксорки.
2) Та же самая побитная ксорка пикселей, но только с индексированным цветом и особенным подбором палитры - цвет определяется несколькими старшими битами для всех возможных комбинаций значений младших бит. (Фактически так имитируются слои)))
Для простой игры типа лодераннера второй способ вполне достаточен, но просто "повторить возможности слоёв без самих слоёв" не так уж интересно, и к тому же в более сложных случаях может не хватить цветов на все спрайты, потому что их слишком много, или хочется улучшить расцветку спрайтов. Тут возможны компромиссные варианты, например, однотипные объекты могут грязно ксориться друг с другом по первому способу, но не с фоном и не с объектами других типов. Или же -
3) Условная замена пикселя вместо ксора. В том же лодераннере в процедуре обновления человечка сначала старый спрайт стирается ксоркой, а потом сразу же выводится новый спрайт, и так поочерёдно все человечки. То есть, если бы не ксором печатать их, а нормальным наложением сверху, да еще разными цветами, то в конце могли получить картинку, когда от самого первого человечка видно только несколько пикселей. Вот их-то в следующем игровом кадре и нужно чистить, не трогая остальные, - по условию попадания индекса в определённый диапазон. Таким образом можно выделить на каждый спрайт десяток-другой цветов и накладывать хоть сотни поочерёдно.
Причем "чистить" - значит, заменять на пиксели неподвижного фона. Получить его можно тоже разными способами, например, еще в коде формирования фона находим место, где байт фона выводится в экран (а видеокарта параллельно пишет полоску пикселей), и во вспомогательном коде ставим следующей командой - "и скопировать, что только что записали, в такой же адрес видеопамяти, сдвинутый на константу" (мы же можем в пару спектрумовским командам поставить любые вспомогательные). Вот и получили копию фона и потом, при чистке пикселей по условию, можно так же со сдвигом на константу от текущего адреса экрана читать её.
На правах примера) Варианты разные могут быть, всё же ксорки - это самый неприятный и трудный случай, если ставится задача убрать дырявость.
- - - Добавлено - - -
Полагаю, ненамного. Так избавимся только от повтора блока ветвлений и частично флагов, а все регистры, пересылки, логика и арифметика повторяются.
Фу, ясно. Я уж думал твой метод, когда фон под персонажем восстанавливается тем-же кодом, что и строит фон - универсальный "философский грааль" для всех спрайтовых игр, непонятный мне. Ан нет, это просто вы с Иноземцевым в порыве софистического азарта начинаете требовать от оппонента, чтобы методика того работала почти всегда... Да не нужно нам всего. Давайте хоть Dizzy, Lode Runer расклешуем для начала. А там посмотрим.
Предлагаю о легендарных, но примитивных играх вообще не заморачиваться (лоде рунер, джет сет вилли и т.п. маникминеры). Не надо их трогать. Предлагаю вообще забить на игры 82-85 гг., рассматривать только начиная с 86 г. В нормальных играх ксор редко встречается, на ум токо диззи-1 приходит.
ZX_NOVOSIB, просто для отработки технологии. Потренируемся на кошках.
Порисовал Lode Runer-а. Какой он есть, и каким я его хочу видеть. Задумывался о спецэффекте исчезновения экрана...
- - - Добавлено - - -
Порисовал Dizzy 5.
Как он есть, и каким он смог-бы стать.
С красными конечностями, конечно, при перерисовке графики (хакер-художник нужен :) ) и трёхцветных слоях, как в Метеоре у zst.
А по простому - с белыми конечностями, просто хакерскими методами. Дозволяла-бы карта, например, включить второй слой Иноземцева, и рисовать ГГ на нём.
- - - - - - - - -
Хотел 2 поста сделать, каждый со своими картинками, но робот сайта всё слепил в кучу.
таким хватит и второго метода, есичо
В тех же киберноидах тоже ксор. Он оправдан, если много мелких движущихся объектов, их тогда можно в разных кадрах перемещать, глюки-дырки из-за быстрого движения малозаметны (сильно режет глаз только на упавших призах).
да не нужны ни слои для такой картинки, ни тем более переписывание кода (особенно как метеора)
ЧТО "зачем"? Зачем слои НЕ нужны? И при чём тут мегагерцы каких-то клонов. Даже не касаясь переделки старья, сколько новых игр выходит сейчас на Спеке? Ведь весьма прилично! А какие нестандартные режимы они поддерживают? Да практически никакие, разве только ULA+ у буржуев, а почему? Потому что людям лень фактически пилить две игры, под стандартный Спектрум и под расширенный (а выпускать только под расширенный смысла нет, аудитория никакая). Потому новая графическая железка получит софт лишь когда к ней (как к вышеупомянутой ULA+) легко и быстро можно адаптировать версию для голого стандартного Спека. А это значит - скорость и способ обработки пикселей должны быть аналогичны оригиналу.
Интересная мысль - zx-pk.ru/threads/915-interesnaya-mysl.html
Если делать устройство, не требующее изменение кода игры, а отслеживающее рисование спрайта и подставляющее нужную маску, по заранее загруженной конфигурации, то для получения маски можно поступить следующим образом:
1) делаем себе копию Z80 и его памяти и выполняем программу параллельно с ним, чтобы знать состояние внутренних регистров
2) в момент начала рисования спрайта(это определяем в конфигурации) делаем две копии памяти RAM0 и RAM1 и две копии Z80 - CPU0 и CPU1
3) для всех ячеек RAM0 и RAM1 устанавливаем битовые флаги, означающие что записи в ячейку с момента создания копий еще не было
4) запускаем CPU0 и CPU1 в ускоренном режиме до окончания функции рисования спрайта(тоже определяем в конфигурации)
5) при записи ячейки в RAM0 или RAM1 устанавливается соответствующий этой ячейке флаг
6) если CPU0 читают ячейку с экрана и в неё не было записи, то ему подсовывается 00, иначе данные берутся из RAM0
7) если CPU1 читают ячейку с экрана и в неё не было записи, то ему подсовывается FF, иначе данные берутся из RAM1
8) когда Z80 будет что-то записывать в некоторую ячейку экрана, смотрим соответствующие ячейки в RAM0 и RAM1, единицы в RAM0 и нули в RAM1 означают что эти точки были перезаписаны точками спрайта, значит их и нужно будет выводить.
В реальности полные копии памяти можно не создавать, можно сделать многоуровневые флаги, например 256 бит отвечающих за блоки ячеек по 256 байт и на втором уровне 256x256 бит отвечающих за отдельные ячейки. Очистили глобальные 256 флагов, значит память копии совпадает с памятью Z80, записываем что-то в ячейку, проверяем глобальный флаг, если еще не установлен, значит чистим 256 флагов на втором уровне, потом устанавливаем флаг ячейки. При чтении если флаг установлен, читаем данные из копии, если нет, то читаем из памяти Z80 или выдаём 00 или FF, если это чтение экранной области и в неё не было записи. Если Z80 что-то записывает в ячейку не попадающую в экранную область, которую CPU0 и CPU1 не перезаписывали, значит данные из неё нужно перенести в RAM0 и RAM1 и тоже поставить флаги.
В общем смысл в том, что при рисовании спрайта создаются два клона, один быстро рисует спрайт на экране из нулей, а другой на экране из 1, а когда дойдёт очередь до реального спрайта, уже будет ясно какие точки относятся к спрайту, а какие к фону. Возможно данный алгоритм сможет победить и рисование одиночных объектов в буфере, если можно пометить область откуда читается фон чтобы подсовывать 00 или FF, и перенос на экран будет достаточно оперативным.
ну в zxpoly создаются четыре клона, при таких объемах памяти и раскрашивании старых игр нет смысла париться с флагами и бороться с дубликацией, так как старая игра новые возможности юзать не начнетЦитата:
Если делать устройство, не требующее изменение кода игры, а отслеживающее рисование спрайта и подставляющее нужную маску, по заранее загруженной конфигурации, то для получения маски можно поступить следующим образом:
Ну зачем так сложно-то, ё-моё... :v2_dizzy_facepalm: Ведь достаточно одной лишь только "заранее загруженной конфигурации", где по найденным (весьма немногочисленным) адресам прописаны расширенные "восьмипиксельные" команды для выполнения устройством вместо оригинальных "восьмибитных" команд z80 (в том числе - любых команд отрисовки в буфер и переброски буфера на экран)
Затем, что минимизируется ПЗК (предварительно загруженная конфигурация). Нужно знать только адреса начала и конца вывода спрайта.
Но возрастает потребная вычислительная мощь карты.
- - - Добавлено - - -
Если-же расчитывать на более слабую карту. С неким навороченым, но ещё не придуманным, ПЗК 8-битных команд.
То и тут предложение blackmirror можно использовать в инструментах кроссплатформенной доработки игры. Я уже писал о мечте об инструменте, который позволит дорабатывать игру не программисту и не хакеру и даже не особо художнику, просто тыкая мышкой в экран.
вряд ли разница даже в несколько десятков байт (да и то не факт) имеет какое-то значение
а тем более - ценой потери тонкого контроля над отрисовкой на уровне пиксельных операций
важней время на работу по адаптации (и в основном оно уйдёт на трассировку и поиск кода)
вот тут неясно, что считать "началом и концом вывода"
у кода собс-но "вывода" может быть много веток, входов и выходов
если подниматься выше - дольше разбираться в коде придётся
и нагрузка на железо тоже растёт
как минимум до уровня непрактичности (если не до невозможности вообще)
чего стоит одна только операция "сделать две копии памяти в момент начала рисования спрайта"
это как? если предварительно как раз и потребуется хакерскими способами найти "адреса начала и конца вывода" :)
в общем же на примере эмулей с раскрасками видно, что "нехакерская" доработка в принципе не всегда возможна
и может времени потребовать больше "хакерской"; а для начинающего хакера есть снапшоты и визуализация памяти
(вот где стоит поработать над большей наглядностью и удобством)
ну дак в zxpoly я так и раскрашивалЦитата:
То и тут предложение blackmirror можно использовать в инструментах кроссплатформенной доработки игры. Я уже писал о мечте об инструменте, который позволит дорабатывать игру не программисту и не хакеру и даже не особо художнику, просто тыкая мышкой в экран.
https://raw.githubusercontent.com/ra...ite_editor.gif
Не знаю на счёт мелкой логики, а для ПЛИС или программной эмуляции операция вполне реальная, чистить ведь только нужно флаги верхнего уровня, копировать небольшой блок памяти, чистить и устанавливать флаги на следующем уровне потребуется только при записи одним из процессоров. Для эмуляции на x86 очистка 256 флагов потребует всего трёх SSE-команд. При чтении нужно проверить два уровня флагов, чтобы определить можно ли брать данные из памяти клона, еще один флаг чтобы проверить не нужно ли подменить данные на 00 или FF и тремя командами cmov выбрать нужное значение. При записи проверяем флаг верхнего уровня, если не установлен, то ставим и очищаем 256 флагов нижнего уровня, потом проверяем флаг нижнего уровня, если не установлен, значит ставим и копируем ячейку в память клонов(возможно с подменой на 00 и FF), после чего спокойно записываем что собирались.
Но два клона для адаптации конечно слишком мало, если идти по пути ZX-poly, то инструмент для адаптации должен позволять сделать примерно следующее:
1) запускаем автоматическую трассировку, которая для каждой ячейки запомнит адрес команды которая её читала или записывала, после чего смотрим какие команды записывали в видеопамять.
2) смотрим код и находим начало и конец функций записывающих видеопамять, может тут придётся походить по шагам чтобы понять куда мы вернёмся и откуда оно вызывается.
3) просматриваем буфер трассировки и выясняем, какие ячейки читались командами относящимися к нашей функции, из них выкидываем все ячейки с переменными способными повлиять на выполнение функции, оставляем помеченными только массивы в которых могут быть спрайты.
4) создаём пару десятков клонов в зависимости от того, сколько требуется разрядов чтобы можно было адресовать все биты эмулируемого адресного пространства(если у нас 64К, нам достаточно 16+3 клонов, если 1Мб, значит 20+3)
5) в те биты, которые мы пометили как потенциальные спрайты, мы записываем их номера, по одному биту номера в соответствующий бит клона
6) запускаем клоны до конца функции и собираем из видеопамяти номера оказавшихся там бит, то есть ткнув в некоторую точку на экране мы можем определить откуда она здесь взялась
7) если на экран данные рисуются из какого либо буфера, значит по результатам трассировки нужно смотреть где он записывается, потом выяснять откуда, ну а дальше править биты, чтобы понять какие из них попадут на экран
В общем трассировка должна давать возможность для любой области памяти отслеживать откуда она читалась и/или записывалась, для группы или отдельных команд отслеживать откуда они читают и куда пишут. Еще нужно производить над полученными множествами логические операции, добавлять и удалять элементы, а так же создавать клоны и нумеровать биты из некоторого множества, чтобы можно было отслеживать их перемещения. В тот момент, когда мы смогли пометить все ячейки занимаемые спрайтами и пронумеровали их биты, для точки на экране можно определить откуда она взялась и перекрасить её в нужном спрайте.
Второй уровень уже придётся в память писать, это 32 байта разом только для одного клона, а их ведь несколько, а потом при почти каждой записи кроме собс-но записи байта данных нужно соответственный байт флагов второго уровня прочитать-модифицировать-записать, да еще "в ускоренном режиме" (насколько ускоренном?), да еще для кучки клонов одновременно, а ведь всем им мало в плисину поместиться (кстати, сколько полных клонов z80 может влезть в недорогую сегодня?), шину-то одну на всех придётся делить. Нереально, даже эмуляция под вопросом.
И самое главное - зачем весь этот путь боли ради поиска графики в игре (да еще и с точностью до бита), когда уже после второго шага:
...нам известны адреса отдельных команд, пишущих или читающих байты графики - "переводим" их в расширенную форму для "ПЗК" и в эмуле логируем адреса, с которыми они отработали (если графику потом раскрашивать захотим)
- - - Добавлено - - -
Уже были - ксорки, атрибутные перекраски, set/res еще. Не, формально "доработка" возможна - в смысле просто цветов добавить, но результат выходит неполноценным.
в целом процедурная графика: генерация кустов-травы, например, или фоновой текстуры чисто из регистров; динамичные эффекты; возможно, grax
Lethargeek, для плис можно увеличить количество уровней, а блоки флагов во внешней памяти уменьшить хоть до байта, остальные флаги хранить в блоках памяти внутри плис, скажем на нижнем уровне 8192 блока по 8 флагов, остальное уже в плис - 512 блоков по 16 флагов, далее 32 блока по 16 флагов, а на верхнем уровне регистр в 32 бита. Доступ к памяти без клонирования будет требовать дополнительно(кроме операций внутри плис) только прочитать байт флагов, а запись с клонированием будет требовать RW для флагов и RWW или RWWW(если пишет Z80) для данных, то есть 5 или 6 операций. Цифра на первый взгляд дикая, но столько операций делает только один из клонов, остальные только две, поэтому если поделить на троих, получится в среднем около 3х операций.
Что касается количества клонов Z80 влезающих в плис, то реально требуется один полноценный клон, полноценный в том смысле, что выполняет программу параллельно с Z80, мы всегда знаем что у него в регистрах и можем создавать в нужный момент еще два клона CPU0 и CPU1 которые будут рисовать на фоне из 0 и 1 соответственно. Можно попробовать обойтись и одним клоном, который будет рисовать на инверсном фоне, и считать что к спрайту относятся совпавшие точки, но в этом случае будут сложности с определением спрайтов рисуемых в режиме XOR. Что касается того, насколько быстро должен работать клон, то это требуется только если из-за изменения фона выполнение программы пойдёт другим путём, например после сдвига перенос бита в другой регистр делается не через ADC, а через условный переход и INC, хорошо если к моменту записи на экран клоны тоже успели до этого дойти и мы знаем какие из записанных точек фон, а какие спрайт.
В реальности такой путь боли конечно не нужен, поскольку есть zx-poly и spec256, а эмуляция двух десятков клонов позволит отслеживать точки и раскрашивать для них спрайты прямо на экране. Можно даже попробовать отслеживать точки не изучая код игры:
0) запоминаем начальное состояние нашей системы
1) эмулятор выполняет программу и записывает в лог все выполненные инструкции и обращения к памяти(чтобы потом было проще, можно записывать полный адрес, с учётом всяких страниц)
2) далее начиная с начального состояния, эмулятор запускается в режиме воспроизведения лога, выполняя только операции записи в память, а когда в буфере экрана появится интересная нам картинка воспроизведение останавливаем
3) создаём 32 клона и в каждый бит записываем его номер (кроме тех областей из которых судя по логу выполнялся код) умноженный на некоторую константу, допустим на 419, чтобы нумерация поместилась в 32 бита, но не имела в памяти клонов регулярной структуры
4) в памяти сначала располагаем нулевые байты всех клонов, потом первые, вторые и так далее до конца их адресного пространства
5) запускаем воспроизведение лога, при этом для всех клонов повторяем указанные в логе команды используя SSE регистры, но для команд читающих и записывающих память используем адреса из лога
6) из флагов при воспроизведении можно эмулировать только флаг переноса, поскольку нужен для всяких ADC, а остальное слишком сложно поэтому нафиг
7) когда мы дойдём до интересной нам точки, то для каждого бита извлекаем из памяти клонов его номер умноженный на нашу магическую константу 419 и если полученное число нацело не делится, значит нельзя сказать откуда оно взялось, если число не менялось, значит в этот бит программа еще ничего не записывала, ну а если число изменилось, но делится на 419, значит мы точно знаем откуда оно здесь взялось
8) конечно, при таком упрощённом подходе, спрайт отражённый через таблицу отследить мы не сможем, но с другой стороны где-то он наверно выводился и в нормальном виде и воспроизведя лог до другой точки может получиться раскрасить и его