Просмотр полной версии : Вывод спрайта любой ширины с точностью до пикселя.
Написал процедуру вывода спрайта в линейный буфер, возможно кто-нибудь предложит вариант оптимизации по скорости выполнения:)
Процедура состоит из 8 почти идентичных блоков, различие в величине смещения. Все показывать смысла нет, вот самый медленный кусок, смещение = 4
;смещение 4
;HL - адрес в буфере экрана vscreen
;DE - данные спрайта [байт маски, байт данных]
;B - ширина спрайта в символах
;C - высота спрайта в пикселях
;vscreen.len - ширина строки в буфере экрана
drw_sprite_sm4 ld a,b
ld (drw_sprite_sm4_loop1+1),a
neg
add a,vscreen.len
ld (drw_sprite_sm4_offsetx+1),a
ld a,c
exx
ld c,a
exx
drw_sprite_sm4_loop1 ld a,0
ld bc,#ff00
drw_sprite_sm4_loop2 exa
ld a,(de)
inc de
dup 4
rr b
rra
edup
rr b
and (hl)
ld (hl),a
ld a,b
dup 4
rrca
edup
ld b,a
ld a,(de)
inc de
dup 4
rr c
rra
edup
rr c
or (hl)
ld (hl),a
ld a,c
dup 4
rrca
edup
ld c,a
inc hl
exa
dec a
jp nz,drw_sprite_sm4_loop2
ld a,b
dup 4
rrca
edup
or #0f
ld b,a
ld a,c
dup 4
rrca
edup
and #f0
ld c,a
ld a,(hl)
and b
or c
ld (hl),a
drw_sprite_sm4_offsetx ld a,0
add a,l
ld l,a
jp nc,$+4
inc h
exx
dec c
exx
jp nz,drw_sprite_sm4_loop1
ret
SaNchez, поменяй формат маски
с маски AND OR
на маску OR XOR
будет проще.
через таблицу не хочешь выводить?
будет всего 2 процедуры
со смещением/без смещения
А в чём выигрыш OR/XOR? :)
Через таблицу - хорошая идея, надо обдумать...
SaNchez, ну например для того же табличного метода надо хранить 2 варианта таблиц - для маски и для спрайта а так только 1
второй момент SRL r 7ой бит не устанавливает
Bedazzle
02.01.2017, 16:15
А тупых нубов в тему пускаете?
Дайте подсказку про таблицы, не понял, что имеется в виду... :|
Можно сделать таблицу подготовленных значений сдвигов 4кб длинной, и потенциально это позволит ускорить вывод спрайта.
Табличный способ особо выигрыша на даёт. Плавали, знаем... :)
Если в сравнении с реальным смещением в 4 пикселя, табличный способ даст хотя-бы двукратный прирост скорости, то он имеет право на жизнь;)
SaNchez, я тоже отказался от реального в пользу табличного, но причины были иные, не из-за скорости. В реальности табличный способ имеет более громоздкий код и тащит за собой таблицы в 4Кб.
;в данном случае концепт для спрайта 2 байта шириной
;de - адрес на экране
;hl ссылка на таблицу
;sp спрайт
ld a,(de)
;левый байт
pop bc
ld l,c
or (hl)
ld l,b
xor (hl)
ld (de),a
inc h
inc e
ld a,(de)
ld l,c
or (hl)
ld l,b
xor (hl)
dec h
;правый байт
pop bc
ld l,c
or (hl)
ld l,b
xor (hl)
ld (de),a
inc h
inc e
;остаток правого байта переносим на экран
ld a,(de)
ld l,c
or (hl)
ld l,b
xor (hl)
ld (de),a
;далее пересчитываем адрес на экране, размер по вертикали и ссылку на таблицу
dec h
Bedazzle
02.01.2017, 18:49
Можно сделать таблицу подготовленных значений сдвигов
не, это я понял, не понял про оры-ксоры
Можно сделать классическую маску - AND/OR, а можно OR/XOR, где данные будут инвертированы, но в итоге получится та-же картинка на экране. Выигрыш - не нужно делать две 4kb таблицы, хватит одной. Дальше думай сам ;)
В общем, переделал процедуру на работу с таблицами. Получил хорошие показатели: 116 тактов на один байт с маской. По сравнению с реальными сдвигами - 110 тактов сдвиг в 1 пиксель, 214 тактов сдвиг в 4 пикселя.
;ix - данные спрайта
;de - адрес на экране
;h - старший байт адреса таблицы для соответствующего сдвига
;bc - предыдущие значения маски/данных, в начале прорисовки строки = 0
ld l,(ix)
inc ix
ld a,(de)
or (hl)
or b
xor c
inc h
ld b,(hl)
ld l,(ix)
inc ix
ld c,(hl)
dec h
xor (hl)
ld (de),a
SaNchez, и итоге всё сильно будет зависеть от кол-ва памяти в игре.
Давно я выкладывал пример (http://zx-pk.ru/threads/23544-vyvod-sprajta-po-x-y.html) без таблиц который. Если интересно поизучай. Самые медленные сдвиги на 3 и 5 в итоге.
Всё сильно зависит от условий, какие спрайты будут по размерам, способ и место хранения графики... Изменение горизонтальных размеров в процессе вывода итд... Вся обвеска в итоге сводит на нет любую оптимизацию, и память... когда она заканчивается уже не до скорости :)
Bedazzle
05.01.2017, 22:43
Давно я выкладывал пример (http://zx-pk.ru/threads/23544-vyvod-sprajta-po-x-y.html) без таблиц который.
О, интересно!
Можно глупый вопрос задать? Уже не напрямую к выводу относящийся, но тем не менее с ним связанный. Про экономию памяти. Знаю, что для этого часто прибегали к трюку, когда часть спрайта оставалась неизменяемая (туловище), а часть с анимацией (ноги) при движении. А что если сделать немного по-другому (это больше подойдёт к способу вывода без таблиц) - поскольку обычно анимация различных действий непрерывная и зацикленная, то что мешает делать как в запиляторе\видеокодеках - первый кадр спрайта основной, а остальное последовательные диффы (биты\маска)? Интересно насколько это выгоднее (придётся ведь оффсет всё-равно какой-то от начального кадра хранить дополнительно для каждого из блоков изменений и между ними)?
И сразу же возникнет проблема - композинг спрайтов на экране когда они друг на дружку налезают. Ведь для каждого придётся отдельный буфер иметь иначе на что изменения накладывать?
PheeL, спрайты — это 10% кода игры. Способов вывода придумано много, таблицы движения, прекалькуляция движения, мегакод итд... Любая упаковка дельта кадрами это драгоценные такты, а их терять никто не хочет. Композинг тоже всяко делают, кто-то весь экран из буфера рисует, а кто-то подложку под спрайтом... или по XOR'у выводят.
PheeL, Walker используется подобная технология для ГГ
остальные увы - так делать неэфективно
SaNchez, и итоге всё сильно будет зависеть от кол-ва памяти в игре.
Давно я выкладывал пример (http://zx-pk.ru/threads/23544-vyvod-sprajta-po-x-y.html) без таблиц который. Если интересно поизучай. Самые медленные сдвиги на 3 и 5 в итоге.
Глянул исходники, скроллировать спрайт в буфере - идея не очень... До размеров 32х32 лучше двигать прямо в регистрах. Я обычно затягивал в стек спрайт из нужной банки, а потом pop-ами кидал в регистры. Это очень хорошо сочеталось с работой с двумя экранами.
Сейчас меня волнуют спрайты с любой шириной, и в итоге таблицы подошли идеально, спасибо jerri за идею.
PheeL, Walker используется подобная технология для ГГ
остальные увы - так делать неэфективно
Да, конечно, такой вариант предпочтительнее для средних и крупных спрайтов.
Ещё одну проблему нашёл при таком способе - очень сильно будет скакать скорость вывода в зависимости от кол-ва спрайтов на экране и их текущих кадров. Т.е. при синхронизации фреймрейта либо сразу на худший вариант закладываться, либо как-то динамически распределять остаток времени после вывода придётся.
Короче, ясно, довольно муторное это дело при несильно большом выигрыше в памяти.
FYI, Jerri удалось максимально оптимизировать вывод спрайтов любой ширины, со сдвигом от 1 до 7, через таблицу длинной 3584 (#0e00) байт.
Инициализация таблицы смещений:
init_offset_tab ld hl,offset_tab
ld b,1
init_offset_tab_1 push bc
ld d,l,e,0
init_offset_tab_2 srl d
rr e
djnz init_offset_tab_2
ld (hl),d
inc h
ld (hl),e
dec h
inc l
pop bc
jr nz,init_offset_tab_1
inc h,h,b
ld a,b
cp 8
jr nz,init_offset_tab_1
ret
Вывод одного байта с маской:
HL = адрес на экране
HL' = адрес спрайта
D' = старший байт адреса таблицы смещений offset_tab
BC' = данные предыдущего байта (в начале каждой линии нужно обнулять)
ld a,(hl)
exx
or c
xor b
ld e,(hl)
inc hl ;в частном случае можно inc l
ld b,(hl)
inc hl ;в частном случае можно inc l
ex de,hl
or (hl)
inc h
ld c,(hl)
ld l,b
ld b,(hl)
dec h
xor (hl)
ex de,hl
exx
ld (hl),a
В конце линии нужно вывести остатки из BC'
ld a,(hl)
exx
or c
xor b
exx
ld (hl),a
Итого: 104 такта на один байт с маской (100 тактов в частном случае).
YI, Jerri удалось максимально оптимизировать вывод спрайтов любой ширины, со сдвигом от 1 до 7, через таблицу длинной 3584 (#0e00) байт.
Полезная процедурка, был бы клипинг можно было бы Star Wars возродить попробовать ))
Можешь спрайты расположить на "ковре", как этот способ называет Jerri. В общем, спрайты на холсте 256х64 байта, ничего клиппить не надо, рисуешь только необходимый кусок.
SaNchez, кучу таков сожрёт "обвязка" вывода байта.. к сожалению чудес не бывает :( + считай максимальную нагрузку в отдельном пакете процедур зеркального вывода.
Построение таблиц с адреса #5С00 из Диззика:
XOR A
LD L,A
LD B,A
LD DE,#6907
T_L1 LD C,B
LD B,E
LD H,D
LD A,L
T_L2 ADD A,A
RL C
LD (HL),A
DEC H
LD (HL),C
DEC H
DJNZ T_L2
INC L
JR NZ,T_L1
drbars, обвязка все равно жрет меньше чем сам вывод
и обвязка будет всегда.
с быстрой процедурой или с медленной.
Можешь спрайты расположить на "ковре", как этот способ называет Jerri. В общем, спрайты на холсте 256х64 байта, ничего клиппить не надо, рисуешь только необходимый кусок.
Не понял. Откуда 256 и 64.
Смотри. 256х64 байта потому-что это 16Кб, одна страница. Спрайты в странице лежат не линейно, а вот так (пример для спрайта 32х32 в верхнем левом углу холста/ковра):
#c000: mask000, data000, mask001, data001, mask002, data002, mask003, data003
#c100: mask004, data004, mask005, data005, mask006, data006, mask007, data007
.....
#df00: mask124, data124, mask125, data125, mask126, data126, mask127, data127
А какие есть способы генерации масок спрайта? с TommyGun слишком мудрено.
Я в своём редакторе черновую маску формирую так: сдвигаю спрайт с наложением вверх, вниз, влево и вправо, потом делаю заливку начиная с верхнего левого угла, всё что залилось - и есть маска. Способ не идеальный, иногда требуется ручками кое-что подправить.
Ну да, слышал про этот способ. Поэтому я добавил функцию в Screen Optimizer=) а у Tommy Gun есть другие способы создания маски.
Не понял. Откуда 256 и 64.
64 максимальная высота спрайта в странице
вот тебе 2 ковра для примера
ковер 1 (https://www.dropbox.com/s/wh8nfgjf60rictx/carpet.png?dl=0)
ковер 2 (https://www.dropbox.com/sh/e2tbf33hdy0icyv/AACebk6HCQrjPzEEpTH8YDo3a?dl=0)
64 максимальная высота спрайта в странице
вот тебе 2 ковра для примера
ковер 1
ковер 2
В современном геймдеве это принято называть атласами.
Однако я все равно не понял, как это мне поможет с выводом спрайтов за пределы экрана (со всех 4-х сторон).
newart,
ты выводишь спрайт шириной 1 2 3 ... много
если твой спрайт надо урезать справа или слева. то просто задаешь уменьшеную ширину а указатель смещаешь вправо (если надо)
Смотри. 256х64 байта потому-что это 16Кб, одна страница. Спрайты в странице лежат не линейно, а вот так (пример для спрайта 32х32 в верхнем левом углу холста/ковра):
#c000: mask000, data000, mask001, data001, mask002, data002, mask003, data003
#c100: mask004, data004, mask005, data005, mask006, data006, mask007, data007
.....
#df00: mask124, data124, mask125, data125, mask126, data126, mask127, data127
Круто! Получается, при выводе спрайта, для перехода на следующую строку графики, нужно просто инкрементировать старший байт.
А если произошло переполнение (или обнуление), значит банка закончилась, подключаем следующую банку со спрайтами (продолжение ковра), ставим в старший байт #c0 и продолжаем читать спрайт.
А как этот способ увязать с выводом на экран? Затягивать в буфер в среднюю память (#8000), если надо, зеркалить, затем переключать верхнюю память (#c000) на экранную банку и туда уже выводить с применением таблицы скролла?
DragonsLord
15.03.2021, 07:44
удалось максимально оптимизировать вывод спрайтов любой ширины, со сдвигом от 1 до 7, через таблицу длинной 3584 (#0e00) байт
SaNchez, а можно попросить экземпл в исходнике, демонстрирующий обвязку к этим процедурам и метод хранения данных?
SaNchez, а можно попросить экземпл в исходнике, демонстрирующий обвязку к этим процедурам и метод хранения данных?
он не ответит
https://github.com/Jerri1977/___core48
здесь посмотри
ZX_NOVOSIB
15.03.2021, 11:15
он не ответит
Обиделся?
Обиделся?
он тут с 2018 не появляется
некогда ему трепаться и не нужно.
Ещё пример вывода спрайта, но когда памяти мало :)
https://zx-pk.ru/threads/23544-vyvod-sprajta-po-x-y.html
DragonsLord
21.03.2021, 20:40
здесь посмотри
Там обвязка к ЭТИМ таблицам Санчеза, или другие таблицы и другая обвязка?
Есть на форуме ветка твоего core48? Чтобы внятно описалово почитать, что умеет и как конкретно реализован.
Там обвязка к ЭТИМ таблицам Санчеза, или другие таблицы и другая обвязка?
Есть на форуме ветка твоего core48? Чтобы внятно описалово почитать, что умеет и как конкретно реализован.
Нет.
Просто посмотри на Гитхабе.
там есть снап с демонстратором.
DragonsLord
21.03.2021, 22:43
Тот снап тупо не работает. Всё, что он может - это челиком налево/направо в пределах экрана ходить. Всё!
Хотя я посмотрел скрины в gfx, этого хождения явно маловато для демонстрации...
Я уже Алония задолбал, и тебя теперь задолблю: экземплы к движку должны показывать в работе ВСЕ возможности ВСЕХ процедур движка. Ибо пользователи не обязаны обладать телепатией, чтобы догадываться, что движок может и как и какими конструкторами эти функции вызываются.
Иначе, любой такой недокументированный движок, как бы он не был крут, никуда дальше автора не пойдёт никогда.
DragonsLord
22.03.2021, 10:36
Кстати, а не тот ли это движок, над которым Алоний пыхтел на последних стримах и больше 6 спрайтов 2х2 с маской в прерывание вывести так и не смог?
Тот снап тупо не работает. Всё, что он может - это челиком налево/направо в пределах экрана ходить. Всё!
Хотя я посмотрел скрины в gfx, этого хождения явно маловато для демонстрации...
Я уже Алония задолбал, и тебя теперь задолблю: экземплы к движку должны показывать в работе ВСЕ возможности ВСЕХ процедур движка. Ибо пользователи не обязаны обладать телепатией, чтобы догадываться, что движок может и как и какими конструкторами эти функции вызываются.
Иначе, любой такой недокументированный движок, как бы он не был крут, никуда дальше автора не пойдёт никогда.
А оно не для пользователей. Да и от автора движок уже ушел.
и да. он показывает все что умеет движок.
DragonsLord
22.03.2021, 21:03
И что он умеет? Вверх/вниз/удар якобы переопределяются, но ничего не происходит.
Как посмотреть то, что он умеет?
И что он умеет? Вверх/вниз/удар якобы переопределяются, но ничего не происходит.
Как посмотреть то, что он умеет?
он умеет рисовать спрайты четырех видов, освежать фон, опрашивать клавиатуру и джойстик.
Определять Бакграунд и Фореграунд.
Есть дополнительный модуль анимации фона.
а то что на экране это эксперименты
DragonsLord
22.03.2021, 22:14
То есть снапшот это не у меня глючит, а он такой никакой и задумывался? Я этого добиваюсь узнать.
- Если да, тогда сам полезу копать.
- - - Добавлено - - -
он умеет рисовать спрайты четырех видов
Он это делает хотя бы наравне с табличным методом Санчеза?
По скорости. Или медленнее?
То есть снапшот это не у меня глючит, а он такой никакой и задумывался? Я этого добиваюсь узнать.
- Если да, тогда сам полезу копать.
- - - Добавлено - - -
Он это делает хотя бы наравне с табличным методом Санчеза?
По скорости. Или медленнее?
именно таким методом он и делает.
DragonsLord
23.03.2021, 00:40
Клипинг есть/нет?
Если есть, то какой:
- сверху
- слева
- справа
- снизу
Я про сдвиговый вывод имею в виду.
- - - Добавлено - - -
Данные чёрно белых спрайтов как хранятся?
Как/чем их к этому виду нарезать/привести?
Клипинг есть/нет?
Если есть, то какой:
- сверху
- слева
- справа
- снизу
Я про сдвиговый вывод имею в виду.
- - - Добавлено - - -
Данные чёрно белых спрайтов как хранятся?
Как/чем их к этому виду нарезать/привести?
структура движка подразумевает клиппирование по умодчанию
нарезалка входит в состав комплекта
DragonsLord
23.03.2021, 13:55
структура движка подразумевает клиппирование по умодчанию
Что-то мне это не нравится. Попахивает лишним теневым буфером и лишней перекидывалкой графики, которой хотелось бы избежать чуть больше, чем полностью.
Значит, говорю ясно и чётко, что мне нужно:
- кидалки из памяти на экран со сдвигами по таблицам чёрно белых спрайтов 2х2 и 3х3 знакоместа
- кидалки должны уметь кинуть в #4000 пятой банки и в #C000 седьмой банки по моему желанию
- никаких промежуточных экранных буферов быть не должно
Этот движок соответствует моим запросам? Ну, или хотя бы может быть допилен до кондиции, отвечая требованиям ТЗ?
Что-то мне это не нравится. Попахивает лишним теневым буфером и лишней перекидывалкой графики, которой хотелось бы избежать чуть больше, чем полностью.
Значит, говорю ясно и чётко, что мне нужно:
- кидалки из памяти на экран со сдвигами по таблицам чёрно белых спрайтов 2х2 и 3х3 знакоместа
- кидалки должны уметь кинуть в #4000 пятой банки и в #C000 седьмой банки по моему желанию
- никаких промежуточных экранных буферов быть не должно
Этот движок соответствует моим запросам? Ну, или хотя бы может быть допилен до кондиции, отвечая требованиям ТЗ?
под твои хотелки требуется абсолютно другой движок.
с учетом забросов на 5/7 экран рекомендую взять процедуру Barsа она больше соответствует твоему ТЗ.
- - - Добавлено - - -
вот оно
https://zx-pk.ru/threads/23544-vyvod-sprajta-po-x-y.html
DragonsLord
23.03.2021, 16:10
Барс, наверное, ликует :biggrin:
Только вот зачем там ЭТО:
— Буфер подложки 256 байт?
Также мне не нужно:
— Есть возможность зеркалирования и изменения спрайта "на лету";
— Таблица зеркалирования 256 байт
Хотелось бы максимально оптимизированный на скорость мегабыстрый вывод без излишеств.
А также в предложенной демке НЕТ клипирования от слова совсем. Именно поэтому я успешно игнорировал этот код до сих пор. Клиппинг полюбасу нужен.
Хотелось бы максимально оптимизированный на скорость мегабыстрый вывод без излишеств.
А также в предложенной демке НЕТ клипирования от слова совсем. Именно поэтому я успешно игнорировал этот код до сих пор. Клиппинг полюбасу нужен.
Убери лишнее да и всё. Клиппирование в общем-то легко сделать. Надо допилить всего лишь одну процедуру SHOW_MOVE_BUF.
Вот, какую-то процедуру делал с клипированием, но оно под другие задачи. В новой диззи на ней интро сделано, буковки где вылетают)
https://zx-pk.ru/threads/20554-vyvodim-sprajt-s-proverkoj-granits-ekrana.html
- - - Добавлено - - -
Хотелось бы максимально оптимизированный на скорость мегабыстрый вывод без излишеств.
Эт достаточно быстрый вывод без таблиц движения.. упор на размер кода. Было бы прикольно если кто-то бы смог убыстрить :)\
Буфер нужен, чтобы восстановить фон затираемый спрайтом, а изменение спрайта это для анимации.
Пихаешь процедуре свой спрайт, она сама просчитывает фазу смещения, и рисует всё на экран. Без таблиц, с таблицами по скорости почти также, только памяти ещё +3Кб под таблицы, что в играх лютая роскошь.
DragonsLord
23.03.2021, 19:48
В RTS лютая роскошь - это игнорировать потребности в максимально возможной скорости.
Санчез давал растактовку своих табличных процедур. Я конечно такты считать не умею, но на мой ламерский взгляд, я насчитал, что вывод Санчеза в 1,68 раз быстрее Аллодовского вывода Алония. А Алоний жутко гордился, что сделал быстрее Медноногова. Делайте выводы.
В код барса трудно лапы свои пихать, потому что у него мания объединять ВСЁ в одну процедуру. В результате, только автор и понимает, как сие работает. Плюс нигде не озвучены такты. Посему никак не могу прикинуть, подходит ли мне это или нет.
Чтобы вы понимали, на сколько я жажду скорости, то я готов держать две копии процедур и таблиц, для кидания в 5 и 7 банку. Если уж не будет возможно как-то впихнуть адрес вывода в одну версию подпрограмм.
Был бы признателен Джери за труды следующего характера:
- Взять выводилку Санчеза с табличным методом из этой ветки
- Набросить на неё поверх предпросчёт входящих параметров, выхватив его из core_48 (как ты сказал, они совместимы по логике)
- По дороге добавив кидание в 5 и 7 банку.
- Выводить маску НЕ НАДО (но оставить возможность выбора типа вывода: or xor and). Посему, можно уложиться в малое количество регистров и хорошо оптимизировать на скорость.
- Клипирование быть обязано.
И выдать всё это хозяйство мне в виде исходников с маленьким экземплом, демонстрирующим как эти процедуры юзаются. И я начну собирать WarCraft.
http://risovach.ru/upload/2017/03/mem/dazhe-krestnyy-otec_140767659_orig_.png
NEO SPECTRUMAN
23.03.2021, 23:24
а если так?
https://gta.com.ua/userfiles6/thumb_1_11.jpg
DragonsLord
24.03.2021, 12:37
Ты забыл, что Капоне требовал в обмен на свои услуги? Дружбу я тебе давно кинул и ты её принял :biggrin:
P.S.: Тут Алоний просит дать ему мой 3D уровень + исходник. Типа в новый журнал опубликовать. И я ему конечно же их дам. Я добро помню.
Ты был моим первым другом здесь. Так что уважение максимальное :v2_dizzy_vodka2:
речь не о том
в твоей логике есть огромные дыры. и это неуважение.
теперь по дырам.
- По дороге добавив кидание в 5 и 7 банку.
бросание спрайта на экран 7 - это вообще ниачем.
у тебя есть тайлы местности - ты их держишь в странице
у тебя есть спрайты персонажей - ты их держишь в страницах тоже
Экран 7 это тоже страница.
как ты собрался с одной страницы в другую кидать спрайты и тайлы БЫСТРО?
рисуй распределение памяти - иначе сам ничего не поймешь.
- Выводить маску НЕ НАДО (но оставить возможность выбора типа вывода: or xor and). Посему, можно уложиться в малое количество регистров и хорошо оптимизировать на скорость.
или спрайт с маской или без. с маской но без маски не бывает.
DragonsLord
24.03.2021, 16:54
бросание спрайта на экран 7 - это вообще ниачем.
Плохо считаешь. Гиморойно и необычно не означает медленнее. Метода такая - переключиться в банку со спрайтом, взять в буфер (в регистры, в стэк, - как угодно). Максимально много, сколько можно. Переключить на банку 7. Выкинуть из буфера на экран. Повторять до полного иступления :)
Совокупные времянки работы с теневым экраном в классике ВЫШЕ времянок указанного гиморойного кидания сразу в экран. Потому что площадь, занимаемая выводимыми спрайтами, на порядок меньше всей площади экрана.
Мы так решили со Слипом и будем делать именно, как я говорю. И никак иначе.
С тайлами такой проблемы нет, они на 7 странице и лежат.
или спрайт с маской или без. с маской но без маски не бывает.
Я же говорю, сделать кидалку БЕЗ маски. Нам не нужна маска. У нас нет в памяти масок. Спрайты хранятся в 4х банках верхней памяти. Маски не нужны. Пиши в процедурах вывод по AND. Если мне надо я сам потом поменяю.
как ты собрался с одной страницы в другую кидать спрайты и тайлы БЫСТРО?
Да, да, кстати) У меня там реализовано как раз перекидывание спрайта из страницы в буфер со сдвигом на бит, чтобы ну хоть как-то побыстрее. Не знаю что там может быть кому-то непонятно, тут не матан и не лин.алгебра же) В теории можно ему как в Диззи сделать, спрайты по таблицам двигаются, а хранятся в 7ой банке с $db00... но там всего 9кб. Что-то быстрее и универсальнее уже сложно придумать...
DragonsLord
24.03.2021, 17:05
Предлагаю перенести обсуждение в тему Варика. Ссылка в моей подписи.
Я не делаю секрета из методик реализации проекта, посему могу свободно обсуждать что и как сделано. Более того, могу в конце дать исходник. Всем.
- - - Добавлено - - -
спрайты по таблицам двигаются, а хранятся в 7ой банке
Никаких копий. Всё делать в реалтайме.
- - - Добавлено - - -
Не знаю что там может быть кому-то непонятно, тут не матан и не лин.алгебра же)
Я 25 лет асм в глаза не видел. Уже привык кодить на языках с классами. Мне ваши крокозяблики в асме, как китайская грамота...
Да кодю помаленьку... да вспоминаю... но пока только самые базовые команды.
Так что - писалово низкоуровневых процедур и раньше было "не моё", а сейчас и подавно :)
В код барса трудно лапы свои пихать, потому что у него мания объединять ВСЁ в одну процедуру. В результате, только автор и понимает, как сие работает. Плюс нигде не озвучены такты. Посему никак не могу прикинуть, подходит ли мне это или нет.
Посчитать, наверное, не трудно... но мне лень честно) Пример этот экспериментальный, получился как побочный продукт и в релиз игры не пошел. Выложил как пример, может кому интересно тот разберётся.
- - - Добавлено - - -
Никаких копий. Всё делать в реалтайме.
У меня всё в реалтайме делается.
DragonsLord
24.03.2021, 17:11
У меня всё в реалтайме делается.
Нужен трезвый расчёт в цифрах. Если "по таблицам" будет быстрее - я выбираю таблицы.
Если разница вывода "по таблицам" и "реалтайм расчёт со сдвигами" не превысит 10% по времени, тогда без таблиц.
Нужен трезвый расчёт в цифрах. Если "по таблицам" будет быстрее - я выбираю таблицы.
Если разница вывода "по таблицам" и "реалтайм расчёт со сдвигами" не превысти 10% по времени, тогда без таблиц.
Я прикидывал, реалтайм немного медленее выходит. Тестить надо, сравнивать. Мне процедура не подошла по причине, что под каждую ширину спрайта 1,2,3,4 знакоместа надо было отдельную процедуру делать, чтобы быстро. Поэтому сделал универсальную себе с таблицами, а эту отдал в паблик.
- - - Добавлено - - -
Будет время может сделаю набор библиотек с примерами и демкой типа LaserBasic.
- - - Добавлено - - -
Ещё в Диззи там трюки с балансировкой есть, чтобы пиковые нагрузки исключить координаты особым образом задаются.
Нужен трезвый расчёт в цифрах. Если "по таблицам" будет быстрее - я выбираю таблицы.
Если разница вывода "по таблицам" и "реалтайм расчёт со сдвигами" не превысит 10% по времени, тогда без таблиц.
ну так посчитай.
У тебя все данные, а примерные цифры в тактах на байт тебе уже озвучили не раз.
- - - Добавлено - - -
Плохо считаешь. Гиморойно и необычно не означает медленнее. Метода такая - переключиться в банку со спрайтом, взять в буфер (в регистры, в стэк, - как угодно). Максимально много, сколько можно. Переключить на банку 7. Выкинуть из буфера на экран. Повторять до полного иступления :)
не максимально много, а один спрайт за раз.
как мышой рулить будешь?
Совокупные времянки работы с теневым экраном в классике ВЫШЕ времянок указанного гиморойного кидания сразу в экран. Потому что площадь, занимаемая выводимыми спрайтами, на порядок меньше всей площади экрана.
зависит от количества обьектов.
С тайлами такой проблемы нет, они на 7 странице и лежат.
а хватит?
Я же говорю, сделать кидалку БЕЗ маски. Нам не нужна маска. У нас нет в памяти масок. Спрайты хранятся в 4х банках верхней памяти. Маски не нужны. Пиши в процедурах вывод по AND. Если мне надо я сам потом поменяю.
смотрется будет как мазня.
DragonsLord
24.03.2021, 19:24
Ответ здесь:
https://zx-pk.ru/threads/32718-warcraft-1-pod-klassicheskij-128-tr-dos.html?p=1110069&viewfull=1#post1110069
Плохо считаешь. Гиморойно и необычно не означает медленнее. Метода такая - переключиться в банку со спрайтом, взять в буфер (в регистры, в стэк, - как угодно). Максимально много, сколько можно. Переключить на банку 7. Выкинуть из буфера на экран. Повторять до полного иступления :)
А смысл тут в стеке? Получается точно такой же буфер. Да, скопировать данные быстрее получится, а вот подготовить к выводу на экран уже заморочки. Либо сразу стеком рисуют на экраны, либо копируют в буфер, его обрадатывают и выводят на экран.
Все сдвиги спрайтов это расчет фазы сдвига от 0 до 7 точек.
Есть 3 популярных способа.
1) Прекалькуляция, т.е. в памяти мы храним 7 сдвинутых копий. Но тут если сам спрайт имеет анимацию, то она получится гвоздями прибитой к фазам сдвига и должна иметь соответствующую раскадровку.
2) Команды сдвига. Моя процедура использует небольшой трюк при работе с буфером спрайта, чтобы потом его быстро вывести процедурой вывода. Наборы спрайтов лежат в заданном банке памяти. Принцип сдвигов такой:
0 px - просто копируем спрайт в буфер, выводим.
1 px - копируем в буфер со сдвигом вправо на 1px, выводим.
2 px - копируем в буфер со сдвигом вправо на 1px, сдвигаем буфер на 1px вправо, выводим.
3 px - копируем в буфер со сдвигом влево на 1px, сдвигаем буфер на 4px влево (RLD), выводим. (+изначальное смещение в буфере на знакоместо)
4 px - просто копируем спрайт в буфер, сдвигаем буфер на 4px вправо (RRD), выводим.
5 px - копируем в буфер со сдвигом вправо на 1px, сдвигаем буфер на 4px вправо (RRD), выводим.
6 px - копируем в буфер со сдвигом влево на 1px, сдвигаем буфер на 1px влево, выводим. (+изначальное смещение в буфере на знакоместо)
7 px - копируем в буфер со сдвигом влево на 1px, выводим. (+изначальное смещение в буфере на знакоместо)
Из списка видно, что самые нагруженные части это сдвиг на 3 и 5 точек. RRD/RLD команды довольно быстрые, удобно ими пользоваться.
3) Таблицы движения. Тут принцип простой, есть таблица в 3+ Кб из фаз сдвигов. Нужно расчитать байт из спрайта в соответствии с фазой сдвига по таблице.
Берём данные спрайта, берем данные таблицы, полученный результат из регистра выводим на экран. Довольно быстро работает, но теряется память под хранение таблицы. Буфер не нужен.
Что же касается клиппинга, то тут удобнее спрайты хранить дампом (2048х64px), расчёт строки спрайта будет очень быстрым при клиппинге сверху экрана, но можно и умножением в общем-то.. по скорости может и быстрее будет. Клиппинг снизу это просто отсекаем строки вывода уходящие за границы экрана. А вот слева и справа уже сложнее без дампа, тут нужно считать сколько и каких столбцов спрайта не рисовать.
Bedazzle
25.03.2021, 11:19
Все сдвиги спрайтов это расчет фазы сдвига от 0 до 7 точек.
Может быть два набора 0 и 3. Тогда крутить меньше - максимум на +2/-2.
Может быть два набора 0 и 3. Тогда крутить меньше - максимум на +2/-2.
Можно и так, обычный и сдвинутый на полубайт. Но и памяти в два раза больше под спрайты тогда.
DragonsLord
25.03.2021, 12:58
А смысл тут в стеке? Получается точно такой же буфер.
Я не знаю, что Джерри выберет в качестве реализации. Пусть сам тестит разные подходы на скорость исполнения.
Ты зашорено смотришь на проблему, например в Аллодах Алония стэк используется не так, как ты привык.
Andrew771
26.03.2021, 14:57
3) Таблицы движения. Тут принцип простой, есть таблица в 3+ Кб из фаз сдвигов. Нужно расчитать байт из спрайта в соответствии с фазой сдвига по таблице.
Берём данные спрайта, берем данные таблицы, полученный результат из регистра выводим на экран. Довольно быстро работает, но теряется память под хранение таблицы. Буфер не нужен.
Умножаю 256 на 7, получаю 1792 байта таблицу. Откуда 3к?
Умножаю 256 на 7, получаю 1792 байта таблицу. Откуда 3к?
В самом начале этой темы описан пример от jerri.
DragonsLord
11.04.2021, 20:09
Глубоко проанализировал все "предложения на рынке", причём уже по третьему кругу :) Пришёл к выводу - НИЧТО НЕ ПОДХОДИТ. Подходят только процедуры Санчеза, причём ИДЕАЛЬНО. Где или как связаться с мистером Александром, чтобы выциганить обвязку к табличному методу?
Заодно мож и кидалку-спрайтовалку на 5 и 7 страницы даст, он писал, что у него они уже написаны и отлично работают со спрайтами до 4х4.
ZX_NOVOSIB
11.04.2021, 20:09
Где или как связаться с мистером Александром
в ВК
DragonsLord
11.04.2021, 21:04
Ну дык, дайте ссылку на профиль.
ZX_NOVOSIB
11.04.2021, 21:08
DragonsLord, https://vk.com/id198939133
DragonsLord
11.04.2021, 21:23
Страница полностью закрыта от внешних воздействий. Невозможно даже написать сообщение в личку.
ZX_NOVOSIB
11.04.2021, 21:32
DragonsLord, а када заявку отправляешь, то там будет "заявка отправлена", ещё раз жмёшь и будет "новое сообщение".
DragonsLord
11.04.2021, 23:20
Спасибо. Отправил. Подождёмс...
DragonsLord
12.04.2021, 09:42
Написал свою обвязку. И вижу определённые траблы в предложенной Санчезом процедуре спрайтовалки по таблице. Результат:
https://b.radikal.ru/b34/2104/e1/0378a2183898.png
Первый косяк - видимо, где то ошибается на один бит в сдвигах в его процедуре, потому что самый левым выводит тот, который должен быть самым правым (в пределах 8 бит). Видно на образе мышки, как две вертикальные полоски в начале знакомест. Возможно также не правильно генерится сама таблица. Таблицу положил по красивому адресу #c000. А в своём коде я уверен на 100%. Кто разберётся, в чём проблема?
Второй косяк ещё более неожиданный. Заявлено, что спрайтоваться будет в любое место в пределах координат 0..255,0..191. И фигушки. По горизонтали не может вывести в диапазоне 247...255, т.е. в последнем правом знакоместе экрана нет попиксельного позиционирования. На любой Х в последнем знакоместе выводит всегда в координату 247 без сдвига.
Третий косяк, - нифига не пойму в каком виде нужно пихать спрайт на вход, с этими новомодными выпендрёжами. Скормил стандартные маску и спрайт - не правильно выводит. Проинвертировал маску и спрайт, - снова не правильно выводит (как на картинке). Так как надо то?
Что, никто не тестил сие произведение?
Вот код без клипинга. Всё чётко и понятно:
;вывод спрайтов любой ширины, со сдвигом от 1 до 7
;104 такта на один байт с маской, 71680/104 = 689 байт за кадр
;Вывод одного байта с маской:
;HL' = адрес спрайта
;D' = старший байт адреса таблицы смещений offset_tab
;BC' = данные предыдущего байта (в начале каждой линии нужно обнулять)
;HL = адрес на экране
;6656 тактов вывод 2х2 стрелки с маской + небольшой обвес
ld hl,mouse_Spr
ld d,#c0 ;offset_tab
ld bc,0
exx
ld hl,(XYMOUSE) ;кладём в hl X и Y мышки
call SCRADR ;получаем на выходе в hl адрес в экранной области
ld b,16
loopspr call sprite
inc hl
call sprite
exx
ld bc,0 ;на это, кстати, никак не реагирует, хотя написано, что должно
exx
call SCRAD3 ;down_hl
dec hl ;по сути перевели на следующую строчку в экране
djnz loopspr
Помогайте разобраться, а то Санчеза ждать можно годами, и так и не дождаться.
- - - Добавлено - - -
Ща обратил внимание,что мы не передаём в коде точного позиционирования по Х. Посему "второй косяк" это не косяк. Надо научиться передавать подпрограмме спрайтовалки СДВИГ. Как? Через регистр D' может? И я не правильно понял по описанию для чего он нужен. И не правильно закодировал. Тогда, что в него надо правильно передавать и в каком формате?
Проинвертировал маску и спрайт, - снова не правильно выводит (как на картинке). Так как надо то?
Сложно конечно догадаться без исходников что ТАМ, но предположу формат спрайта OR/XOR.
Если на входе у тебя стандартная маска/спрайт, то байт маски инвертируешь, а байт спрайта ксоришь с полученной маской.
DragonsLord
12.04.2021, 17:35
Я так и предположил, как самый вероятный вариант. Потому что в Аллодах Алония так, как ты говоришь. Сегодня попробую.
По коду обвязки есть мысли? Как передавать внутрь смещение в байте?
Я так и предположил, как самый вероятный вариант. Потому что в Аллодах Алония так, как ты говоришь. Сегодня попробую.
По коду обвязки есть мысли? Как передавать внутрь смещение в байте?
а ты как передаешь?
ld d,#c0 ;offset_tab
вот так ты передаешь
DragonsLord
12.04.2021, 19:30
Я вот чёт не понял нифига. 3584/7 = 512 байт в таблице для одного сдвига. НАФИГА? Если должно быть 256. 256 - это же все возможные значения, встречающиеся внутри байта. Нахрена ещё столько же в таблице держать непонятно чего? Сказали же чётко, что масковые и спрайтовые сдвиги объединены за счёт изменения формата хранения и вывода.
DragonsLord
15.04.2021, 06:17
Или не объединены, и там всётаки две таблицы раздельно для маски и спрайта?
Я вот чёт не понял нифига. 3584/7 = 512 байт в таблице для одного сдвига. НАФИГА? Если должно быть 256. 256 - это же все возможные значения, встречающиеся внутри байта. Нахрена ещё столько же в таблице держать непонятно чего? Сказали же чётко, что масковые и спрайтовые сдвиги объединены за счёт изменения формата хранения и вывода.Думай ещё
Вот байт 01101001
Вот байт со сдвигом
_0110100 1_______
Итд
он не ответит
https://github.com/Jerri1977/___core48
здесь посмотри
Какой версией sjasmplus собирается проект?
Какой версией sjasmplus собирается проект?
а вот этой. (https://zx-pk.ru/threads/30314-sjasmplus-ot-z00m.html)
Подскажите по вопросу.
Есть спрайт 16х16 пикселей. Если использовать маску и хранение (байт маски, байт спрайта), то получается фактический размер спрайта 14х14 и должен быть отцентрован?
Подскажите по вопросу.
Есть спрайт 16х16 пикселей. Если использовать маску и хранение (байт маски, байт спрайта), то получается фактический размер спрайта 14х14 и должен быть отцентрован?
Непонятен вопрос.
если ты хочешь контур вокруг всего спрайта то да
а если ноги будут твердо стоять на земле то можно 15*14 рисовать.
если ты хочешь контур вокруг всего спрайта то да.
Отлично, тогда если спрайт будет 16x16. То, чтобы был контур вокруг, то получится 3 байта по горизонтали и 18 по вертикали, плюс его нужно будет по горизонтали центровать (размер по Х указывать в пикселях). При крайнем смещении по горизонтали он будет по 4 байта. Так правильно?
Отлично, тогда если спрайт будет 16x16. То, чтобы был контур вокруг, то получится 3 байта по горизонтали и 18 по вертикали, плюс его нужно будет по горизонтали центровать (размер по Х указывать в пикселях). При крайнем смещении по горизонтали он будет по 4 байта. Так правильно?
Вообще не понял к чему ты.
сначала ты рисуешь спрайт который ТЕБЯ устроит
потом ты пишешь к нему процедуру вывода
например вот спрайт
82011
красное маска - черно белое спрайт.
для удобства моего я буду выводить его адрессуя от верхнего левого угла.
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot