Всё, пашыт. Я просто старую версию Im2 процедурки Reobne брал.
Вид для печати
Всё, пашыт. Я просто старую версию Im2 процедурки Reobne брал.
Музыку лучше добавлять в уже скомпилированный файл asm, т.к. Паскаль библиотеку добавляет в самый конец - моя недодумка.
Какой-то заскок у паскаля
Сперва всё шло норм.
А в какой-то момент он перестал добавлять процедурки вывода спрайтов. Хотя пишет, что компиляция успешна, ошибок нет.
Дублирующихся лейблов старался не делать
- - - Добавлено - - -
А по каким конкретно адресам он добавляет либы?
- - - Добавлено - - -
У меня музыка как раз расположена в самом конце.
Но с ней компилилось норм.
А потом вот такая борода произошла.
Пробовал вернуть всё взад - бестолку.
Пробовал музыку вообще убрать. Те же эрроры.
Пасцал не генерит никаких TEMP файлов, где эта чача могла бы засесть ? non_opt_code.txt и error.prg удалял, всё равно те же ошибки.
- - - Добавлено - - -
Сама процедурка put_spr_put добавляется в сурс.
И внутри неё метки put_spr_put_03 put_spr_put_04
а 02 нет.
Чё это такое? :(((((((((((((((((((((((
- - - Добавлено - - -
как мне кажется, какая-то байда с кодировками полученного ASM-а и компилятора EmuZwin.
Часть кода уехало в комментарии, там же оказался и put_spr_put_02
Но когда я раскомментил то, что обнаружил, частично заработало, однако процедура вывода спрайтов бажит сильно, чё-то где-то поехало...
- - - Добавлено - - -
Ага. Преобразовал ASM в ANSI, всё заработало. Хух. Аж отлегло.
У меня часть асмовых вставок задана железно (процедура плеера, хз как его дизассемблировать из вортекса с сохранением всех лейблов, поэтому там строго прописаны адреса в call jr jp и тд)
И вот я щас как раз столкнулся с проблемой такой.
У меня ещё 9 кб пустует до плеера+модуля. А паскаль жахает свои либы после него. Особенно прожорливое вышел Random(). Стоит мне его добавить в прогу - висняк, ибо под самое FFFF лезет, грубо говоря. Ну, стек коцается, возможно.
Random() - короткая процедура.
Ты музыку добавляй уже в откомпилированный асм.
Можно ли как-то объявить процедуру на строки до её вызова, а само тело прописать уже ниже?
Блин, отсутствие модульности это жесть как неудобно.
Т.е. forward? Нет. Тело процедуры должно быть раньше ее вызова.
На днях выпускаю новую версию, где пользовательский код идет в самом конце после всех библиотек. Плюс изменения по выводу спрайтов. Теперь единый формат будет, вне зависимости от флага атрибутов. А цвет спрайта задается в операторе вывода.
Круто!
А per-pixel позиционирование спрайтов будет? Хотя бы OR без маски
Или подскажите, где откопать хороших asm процедурок.
- - - Добавлено - - -
Т.е. в одном коде можно будет как одноцветные спрайты использовать, так и предварительно разукрашенные массивом в DEFB?Цитата:
А цвет спрайта задается в операторе вывода.
Как одноцветные спрайты будут взаимодействовать с уже имеющимся paper-ом фона? Будут затирать своим? Или ink свой, а paper берется из области размещения? Тут бы тоже флаг на выбор не помешал.
Пиксел-позиционирования пока не будет, но подумываю. Т.к. мне писать игру Z, где возможно сделаю попиксельный скроллинг.
Процедуры я обычно выискиваю здесь
Теперь в массиве DEFB вообще не будет атрибутов. Формат спрайтов всегда один и тот же будет, во всех программах. Цвет FLASH+BRIGHT+PAPER+INK задается только в операторах SpritePut, новый однобайтовый параметр. Правда, из-за этого спрайт может быть только одноцветным (один ink и один paper). Цвет спрайта можно менять в операторе SpritePut - это арифметическое выражение, можно подставлять переменные, константы, выражения. Раньше можно было только жестко задавать в DEFB.
Будут затирать своими атрибутами. Но это не печально, т.к. цвет можно рассчитывать в параметре SpritePut, обычное арифметическое выражение.
А также, если не используются атрибуты в программе (выключен флаг атрибутов), то цвета спрайтов игнорируются.
Карочь, решили свести универсальность среды на минимум.Цитата:
. Правда, из-за этого спрайт может быть только одноцветным
AGD стиль тоже ни к чему.Цитата:
.А также, если не используются атрибуты в программе (выключен флаг атрибутов), то цвета спрайтов игнорируются.
Фишка с "цвет (ink) спрайта, пейпер фона" куда полезнее.
Так как поверх одного и того же фона бегают спрайты разной окраски, зачастую.
Да. Но тоже есть сомнения, нужно ли это. На днях сделал универсальность еще большую - оставил атрибуты в DEFB, как было, а также добавил задание цвета в SpritePut. Если в SpritePut задан 0, то цвет спрайта берется из DEFB (можно делать разноцветные знакоместа спрайта). Если не 0, то берется цвет из оператора. Но посчитал это сложным для программиста. Может всё-таки оставить?
Еще я сократил количество флагов компиляции с 8 до 3 для упрощения:
- атрибуты (вся программа либо цветная, либо монохромная. Раньше можно было отдельно задавать цветность для текста, окон, спрайтов и карт);
- проверка краев спрайтов (оставил, как было. Но подумывал снести и жестко проверять всегда. Но ухудшилось бы быстродействие для программ, где проверка краев спрайтов не нужна);
- виртуальный экран (теперь действует на всех сразу, а не по отдельности для текстов, спрайтов и карт).
А как восстанавливать изображение фона и цвет фона после прохождения спрайта? Для этого в Паскале имеются операторы WindowGet, WindowPut (запомнить окно экрана до вывода спрайта; вывести обратно окно после прохождения спрайта). Либо, если много движущихся спрайтов, использовать виртуальный экран с полной перестройкой изображения экрана.
Свершилось! Наконец спустя более 5 лет после начала разработки я выпускаю официальную версию 1.0, можно скачать в первом посте.
По сравнению с версией 0.909 изменения:
- сокращение флагов компиляции с 8 до 3 для упрощения: флаг использования атрибутов, флаг отслеживания краев спрайтов, флаг вывода на виртуальный экран;
- цвет спрайта задается теперь только в операторах вывода спрайта новым параметром, формат кодов спрайтов теперь един и для монохромных, и для цветных спрайтов;
- компиляция пользовательского кода в PRG после последнего "end" программы на Паскале в самом конце файла ASM.
Исправлены обнаруженные баги:
- сложение с константой;
- вывод констант на экран;
- вывод ячейки строкового массива;
- 8-я пиксельная строка зеркальных спрайтов.
Что тут поменять, чтоб оно выплёскивало не в 16384, а в виртуальный экран?
Проверка границ не помешала бы
Код:PUTIMAGE1
ld de,(_WINX) ; e=col_win, d=row_window
ld a,(_WINH)
ld b,a
putimage_011 push bc
push de
LD A,D
RRCA
RRCA
RRCA
AND A,224
ADD A,E
LD E,A
LD A,D
AND 24
OR 64
LD D,A
dup 8
push de
ld bc,(_WINW)
ld b,0
ldir
pop de
inc d
edup
pop de
inc d
pop bc
djnz putimage_011
; +++++ _flag_attr_window +++++
ld de,(_WINX) ; e=col_win, d=row_window
ld a,(_WINH)
ld b,a
putimage_021 push bc
push de
LD A,D
RRCA
RRCA
RRCA
LD C,A
AND 31
OR 88
LD B,A
LD A,C
AND 252
OR E
LD C,A
ld d,b
ld e,c
ld bc,(_WINH)
ld b,0
ldir
pop de
inc d
pop bc
djnz putimage_021
ret
вроде OR 64/ OR 88 , pixel/attr
Ещё по схожему принципу пытаюсь копировать заданную область виртуалки на экран
Но в итоге получаю мусор
По дефолту лайк паскаль переносит фулл-скрин.
а мне надо бы с отступом 5 знакомест сверху, и 6 знакомест снизу.
Код:
row_win equ 5
col_win equ 0
height_win equ 12
width_win equ 31
PIMAGE ld hl,addr_virt_screen+2
ld de,col_win+2
ldi
ldi
ld d,(col_win)
ld e, (row_win) ; e=col_win, d=row_window
ld a,(height_win)
ld b,a
pimage_01 push bc
push de
LD A,D
RRCA
RRCA
RRCA
AND A,224
ADD A,E
LD E,A
LD A,D
AND 24
OR 64
LD D,A
dup 8
push de
ld bc,(width_win)
ld b,0
ldir
pop de
inc d
edup
pop de
inc d
pop bc
djnz pimage_01
; +++++ _flag_attr_window +++++
ld de,(col_win) ; e=col_win, d=row_window
ld a,(height_win)
ld b,a
pimage_02 push bc
push de
LD A,D
RRCA
RRCA
RRCA
LD C,A
AND 31
OR 88
LD B,A
LD A,C
AND 252
OR E
LD C,A
ld d,b
ld e,c
ld bc,(width_win)
ld b,0
ldir
pop de
inc d
pop bc
djnz pimage_02
ret
Процедуры сохранения окна в виртуальном экране и вывода окна из виртуального экрана на экран ниже.
Перед вызовом задать параметры: col_window (столбец окна), row_window (строка окна), width_window (ширина окна), height_window (высота окна).
Если же это нужно в программе на ZX Like Pascal, то эти процедуры вызывать операторами WindowSet (установка параметров), WindowGet (вывод окна в память), WindowPut (вывод окна из памяти на экран), свои писать не надо.
- - - Добавлено - - -Код:
virt_screen_high equ 160 ; старший байт смещения вирт.экрана
addr_virt_screen equ 57344 ; адрес вирт.экрана
col_window defb 0 ; столбец окна
row_window defb 0 ; строка окна
width_window defb 0 ; ширина окна
height_window defb 0 ; высота окна
; сохранение окна в памяти
; вход: нет
; выход: нет
getimage ld de,addr_virt_screen
ld hl,col_window
ldi
ldi
ldi
ldi
ld hl,(col_window) ; l=col_window, h=row_window
ld a,(height_window)
ld b,a
getimage_01 push bc
push hl
LD A,H ; расчет адреса первого байта знакоместа в HL
RRCA
RRCA
RRCA
AND A,224
ADD A,L
LD L,A
LD A,H
AND 24
OR 64
LD H,A
dup 8
push hl
ld bc,(width_window)
ld b,0
ldir
pop hl
inc h
edup
pop hl
inc h
pop bc
djnz getimage_01
; +++++ _flag_attr_window +++++
ld hl,(col_window) ; l=col_window, h=row_window
ld a,(height_window)
ld b,a
getimage_02 push bc
push hl
LD A,H ; расчет адреса атрибутов знакоместа в BC
RRCA
RRCA
RRCA
LD C,A
AND 31
OR 88
LD B,A
LD A,C
AND 252
OR L
LD C,A
ld h,b
ld l,c
ld bc,(width_window)
ld b,0
ldir
pop hl
inc h
pop bc
djnz getimage_02
; ----- _flag_attr_window -----
ret
; вывод окна из памяти
; вход: нет
; выход: нет
putimage ld hl,addr_virt_screen+2
ld de,col_window+2
ldi
ldi
ld de,(col_window) ; e=col_window, d=row_window
ld a,(height_window)
ld b,a
putimage_01 push bc
push de
LD A,D ; расчет адреса первого байта знакоместа в DE
RRCA
RRCA
RRCA
AND A,224
ADD A,E
LD E,A
LD A,D
AND 24
OR 64
LD D,A
dup 8
push de
ld bc,(width_window)
ld b,0
ldir
pop de
inc d
edup
pop de
inc d
pop bc
djnz putimage_01
; +++++ _flag_attr_window +++++
ld de,(col_window) ; e=col_window, d=row_window
ld a,(height_window)
ld b,a
putimage_02 push bc
push de
LD A,D ; расчет адреса атрибутов знакоместа в BC
RRCA
RRCA
RRCA
LD C,A
AND 31
OR 88
LD B,A
LD A,C
AND 252
OR E
LD C,A
ld d,b
ld e,c
ld bc,(width_window)
ld b,0
ldir
pop de
inc d
pop bc
djnz putimage_02
; ----- _flag_attr_window -----
ret
ALKO, тебе что конкретно надо? Из целого виртуального экрана вырезать область и вывести на экран?
да, оно. Только без проверки границ по краям возникают артефакты при перемещении, и заодно таблицу зеркальных спрайтов кромсает.
- - - Добавлено - - -
Именно.
При условии если будет выигрыш в тактах.
Просто в фуллскрине монолитный цикл, а при разбивке на области если будет ущерб производительности, то лучше тогда не надо...
- - - Добавлено - - -
WindowGet копирует адрес #4000 в виртуалку, а у меня же напротив, всё сразу в виртуалке рендерится, а оттуда уже готовое надо выплёскивать.
Вообще процедура PUTIMAGE1 c проверкой намного ли быстрее спрайтовой с проверкой ?
Прост у меня большинство тайлов квадратные, и было бы рациональнее их выводить не спрайтами, а PUTIMAGE-ми. Но вот насколько будет выигрыш в скорости.
- - - Добавлено - - -
Да, в основном именно такая область рабочая.
Быстрее намного, потому что вычисляется только первое знакоместо в каждой линии и далее ldir всей линии, а в выводе спрайтов - каждое знакоместо вычисляется и выводится.
- - - Добавлено - - -
Таблица адресов всех пиксельных строк экрана ниже, можешь нужные строки отлдирить тупо :)
Код:table_addr_scr defw #4000,#4100,#4200,#4300,#4400,#4500,#4600,#4700
defw #4020,#4120,#4220,#4320,#4420,#4520,#4620,#4720
defw #4040,#4140,#4240,#4340,#4440,#4540,#4640,#4740
defw #4060,#4160,#4260,#4360,#4460,#4560,#4660,#4760
defw #4080,#4180,#4280,#4380,#4480,#4580,#4680,#4780
defw #40a0,#41a0,#42a0,#43a0,#44a0,#45a0,#46a0,#47a0
defw #40c0,#41c0,#42c0,#43c0,#44c0,#45c0,#46c0,#47c0
defw #40e0,#41e0,#42e0,#43e0,#44e0,#45e0,#46e0,#47e0
defw #4800,#4900,#4a00,#4b00,#4c00,#4d00,#4e00,#4f00
defw #4820,#4920,#4a20,#4b20,#4c20,#4d20,#4e20,#4f20
defw #4840,#4940,#4a40,#4b40,#4c40,#4d40,#4e40,#4f40
defw #4860,#4960,#4a60,#4b60,#4c60,#4d60,#4e60,#4f60
defw #4880,#4980,#4a80,#4b80,#4c80,#4d80,#4e80,#4f80
defw #48a0,#49a0,#4aa0,#4ba0,#4ca0,#4da0,#4ea0,#4fa0
defw #48c0,#49c0,#4ac0,#4bc0,#4cc0,#4dc0,#4ec0,#4fc0
defw #48e0,#49e0,#4ae0,#4be0,#4ce0,#4de0,#4ee0,#4fe0
defw #5000,#5100,#5200,#5300,#5400,#5500,#5600,#5700
defw #5020,#5120,#5220,#5320,#5420,#5520,#5620,#5720
defw #5040,#5140,#5240,#5340,#5440,#5540,#5640,#5740
defw #5060,#5160,#5260,#5360,#5460,#5560,#5660,#5760
defw #5080,#5180,#5280,#5380,#5480,#5580,#5680,#5780
defw #50a0,#51a0,#52a0,#53a0,#54a0,#55a0,#56a0,#57a0
defw #50c0,#51c0,#52c0,#53c0,#54c0,#55c0,#56c0,#57c0
defw #50e0,#51e0,#52e0,#53e0,#54e0,#55e0,#56e0,#57e0
Яжламер :v2_dizzy_coder:
Так-то я в курсе, что такое LDIR и что он гоняет блоки данных.
Но как сделать так, чтоб он опирался именно на таблицу в качестве входных параметров, этого я пока не умею.
- - - Добавлено - - -
Что касается логики ЯВУ, что быстрее работает последовательность if else или switch case ?
case
Можно тупо в лоб, если не жалко нескольких сотен байтов, зато быстродействие будет максимальное:
Код:copy_virt_to_scr ld hl,#4080+addr_virt_scr-#4000 ; остаток первой трети экрана с 5-й строки
ld de,#4080
ld bc,32
ldir
ld hl,#4180+addr_virt_scr-#4000
ld de,#4180
ld bc,32
ldir
...
ld hl,#4800+addr_virt_scr-#4000 ; вся вторая треть
ld de,#4800
ld bc,2048
ldir
ld hl,#5000+addr_virt_scr-#4000 ; часть третьей трети до 6-й строки снизу
ld de,#5000
ld bc,32
ldir
ld hl,#5100+addr_virt_scr-#4000
ld de,#5100
ld bc,32
ldir
...
ld hl,#5740+addr_virt_scr-#4000
ld de,#5740
ld bc,32
ldir
ret
Не... На данный момент putimage у меня касается вывода тайлов (как альтернатива спрайтам), а не в качестве переброски виртуального экрана на реальный.
Переброску я пока ещё не трогал. Пока ещё она фуллскриновая, тормозная.
- - - Добавлено - - -
Хотя можно как вариант отрисовывать тайлы в более узком диапазоне, не заходя за края. А сами края захайдить атрибутами. Но не хочется урезать обзор.
А вот это не оно? Уже обсуждали
- - - Добавлено - - -
Края не получится проверять в выводах линий. Нужно сначала вычислять длину линии тогда.
3х3 нету, но можно переделать из 4х4 (сократить). А одномерный массив - это двумерный с одной стороной равной 1 :)
Там нужно будет вычислять длину строки до ldir, что может убить всю выгоду от ldir-а. Я пытался так сделать, хотел сделать спрайты в Паскале только прямоугольные для экономии места и ускорения процедур, но ускорения не получается, отказался из-за этого. Так что, лучше на спрайты вернуться.
Ищё такой вопрос, если спрайт 8х8 он по скорости же будет тождественен линейной процедуре Putimage?
И ищё такой вопрос. В паскале этой выводилка спрайтов максимально быстрая? Или возможны варианты ещё быстрее ?(с использованием стека (наличие проверки границ экрана обязательно, разумеется))
Памяти пока не жалко, поэтому готов пожертвовать во благо скорости.
В текущей демке фпс в принципе устраивает, но я опасаюсь жоской просадки, когда будет дофига логики в ЯВУ.(к тому же тут пока ещё нет хальта для верт. синхры)
https://media.giphy.com/media/ZBzp09...Hj72/giphy.gif
да.
С использованием стека быстрее, но опять же, проверки границ притормаживают. И процедуры сложнее по кодированию. У меня таких нету.
Еще есть промежуточный вариант - вместо ldir (21 такт на байт) использовать в цикле много ldi (16 тактов на байт). Это используется в процедуре копирования вирт.экрана на реальный.
я уже думаю про вирт. экран 128к, но я совсем не умею им пользоваться.
Почему
работает как положено.Код:for i:=campos/3 to 10+campos/3 do
begin
...
А это:
ведёт себя так, будто i всегда равно нулю?Код:kampos:=campos/3;
for i:=kampos to 10+kampos do
begin
...
kampos объявлял как word и byte.
- - - Добавлено - - -
вообще у меня там часто встречается campos/3.
Было бы неплохо её единожды за фрейм вычислить максимально быстро.