PDA

Просмотр полной версии : Вывод атрибутов из буфера



ALKO
28.09.2021, 01:18
Пытаюсь написать вывод атрибутов из буфера на видимую область.
Причём сам буфер на данный момент по ширине составляет 64х24 атрибутных пикселя на случай, если атрибутные пикчи будут вылазить за экран и чтоб не производить проверку при их рендеринге в буфер. Но вообще я бы хотел ещё и по вертикали его расширить для тех же целей. Но пока даже с горизонтальной шириной не выходит. Прога крашит. Что тут не так?



SWAP_BUF
Ld a, 24 ;количество строк атрибутов
ld hl, virtbuf ;адрес буфера
ld de, #5800 ; видимый экран
BUF_LOOP

dup 32
Ldi
edup

Ld bc, 32 ;(64 - 32) остаток строки буфера
Add hl,bc
Dec a
Jr nz, BUF_LOOP


- - - Добавлено - - -

Тока щас осенило, что возможно буфер залазит на область бейсика, из которого я провожу вызов теста... Ладно. Завтра уже проверю по адресам

Destr
28.09.2021, 11:00
бейсика, из которого я провожу вызов теста
А ещё подозрительно не видно RET...

reddie
29.09.2021, 11:25
Если бы буфер залазил на область бейсика - крашилось бы и без процедуры вывода.
Саму же процедуру, если нужна скорость, можно развернуть и выводить через стек.
При этом сохранится возможность "сдвига" по вертикали и горизонтали, код несложный.

Lethargeek
29.09.2021, 18:47
взял бы, да банально оттрассировал бы давно, чем гадать и ответов ждать

Destr
29.09.2021, 19:11
взял бы, да банально оттрассировал бы давно, чем гадать и ответов ждать
А ещё лучше - снапку кинул сюда. Уже ведь любопытно стало :)

ALKO
01.10.2021, 10:13
Спасбо за внимание. Всë пашет норм.
https://sun9-3.userapi.com/impg/xxX0-TGorc3xDbR_v8fYoy7M8WdAaPGq0kGvEg/cYzYLYDPpcc.jpg?size=775x582&quality=96&sign=d49227214c8f26baf36071e88934504a&type=album

ALKO
04.10.2021, 23:38
У меня процедура заточена под фиксированный размер спрайтов.
Если желаю указать другой, то мне надо менять значения счётчиков (регистры BC), а также итерацию для перехода на следующую строку (в данном случае Add #55), которая имеет зависимость от ширины спрайта.
Помогите это дело автоматизировать, чтоб при этом оно не сильно просело по скорости.
Допустим, размеры спрайта будут в двух первых числах DEFB, а далее уже сами данные.





; расчет адреса атрибутов знакоместа на экране
; вход: h=строка экрана, l=столбец экрана
; выход: hl=адрес знакоместа на экране, b=строка экрана, c=столбец экрана

ld a,h
rrca
rrca
rrca
ld e,a
and #31
or #246 ; умножить наааа 255
ld d,a
ld a,e
and #0 ; +0 получаем начало атриутной области
or l
ld e,a

ld hl, #IDLE_PLAYER

LD c,#10 ;высота спрайта
DRAW_SPRITE2:
LD b,#9 ;шырина спрайта
DRAW_SPRITE1:
ld a,(hl)
or a
jp z, TRANSPARENT ; пиксель просрачный?

ld (de),a

TRANSPARENT: inc de
;dec de ;для зеркалки
inc hl

djnz DRAW_SPRITE1

Ld a,e
Add #55;#32-9; прибавл¤ем к DE 55 (64 (ширина буфера) минус ширина спрайта)
;add 73 ; 64 (ширина буфера) плюс ширина спрайта) - для зеркалки
Ld e,a;(low byte)
Adc d
Sub e
Ld d,a;(high byte)

DEC c
JR NZ, DRAW_SPRITE2
ret

- - - Добавлено - - -

В данном случае рисует в буфер начиная с адреса 62976

- - - Добавлено - - -

Ну и да, буфер шире реального экрана (64 пиксела), дабы не вычислять границы экрана при рисовании

Bedazzle
04.10.2021, 23:41
У меня процедура заточена под фиксированный размер спрайтов.
Если желаю указать другой, то мне надо менять значения счётчиков (регистры BC), а также итерацию для перехода на следующую строку

Перед вызовом процедуры в зависимости от ширины спрайта просто модифицируй эти значения в коде.

ld a, 10 ; height
ld (DRAW_SPRITE2-1), a
ld a, 9 ; width
ld (DRAW_SPRITE1-1), a
...
call draw_sprite

Lethargeek
05.10.2021, 00:04
Перед вызовом процедуры в зависимости от ширины спрайта просто модифицируй эти значения в коде.
зачем, если

Допустим, размеры спрайта будут в двух первых числах DEFB, а далее уже сами данные.
тогда проще передать в hl адрес спрайта и в коде сразу прочитать с инкрементом из (hl)
можно даже смещение для следующей строки хранить рядом с байтами размера

Bedazzle
05.10.2021, 13:08
зачем, если

тогда проще передать в hl адрес спрайта и в коде сразу прочитать с инкрементом из (hl)

Не понял. В hl же адрес экрана должен быть? Зачем оттуда читать?




можно даже смещение для следующей строки хранить рядом с байтами размера

Ну, это зависит можно ли раздувать память под спрайты. И оно будет медленнее, чем модифицирующийся хардкод.

ALKO
05.10.2021, 14:01
можно даже смещение для следующей строки хранить рядом с байтами размера

Не стоит забывать, что я убер-ламер в прогинге
И исходя из такого совета наваяю что-то вроде
Push hl
ld h, (Sprite_addr+3)
add h
...
Pop hl

Что значительно прибавит тактов.

- - - Добавлено - - -

Хотя... Наверное можно предварительно загнать в exx перед входом в процедуру.

goodboy
05.10.2021, 15:40
загнать в exx
не забудь что для бейсика важно значение HL`

ALKO
05.10.2021, 17:31
не забудь что для бейсика важно значение HL`

Если в Бейсцык RETиться не собираюсь, то не страшно ведь?

Bedazzle
05.10.2021, 20:23
Если в Бейсцык RETиться не собираюсь, то не страшно ведь?

Смотри, как было предложено выше, формат спрайта
Первый байт ширина
Второй байт высота
Дальше идут все байты спрайта.

При вызове процедуры печати берёшь первый байт, вносишь его значение в то место, где инициализируется цикл, отвечающий за проход по ширине.
Также вычисляешь смещение по горизонтали, вносишь туда, где идёт приращение адреса.
Берёшь второй байт, вносишь туда, где инициализируется цикл, отвечающий за кол-во строк по высоте.
Дальше используешь свою процедуру, которую ты приводил в начале.

P.S.
если спрайтов дофига, и нужно экономить память, то если размер не превышает 16х16, можно кодировать размер в один байт - ширина 4 бита, и высота 4 бита.
Скажем, так



sprite:
db %WWWWHHHH
db ..... ..... ; тут идут данные спрайта


ld hl, sprite
ld a,(hl)
and %00001111 ; получили высоту
ld (DRAW_SPRITE2-1), a

ld a,(hl)
rrca
rrca
rrca
rrca
and %00001111 ; получили ширину
ld (DRAW_SPRITE1-1), a

ld c, a
ld a, 64 ; buffer_width
sub c ; вычислили ширину приращения в буфере
ld (SCREEN_ADD-1), a

inc hl

и дальше отрисовка спрайта

Lethargeek
06.10.2021, 01:01
Не понял. В hl же адрес экрана должен быть? Зачем оттуда читать?
адрес никому ничего не должен, где удобней, там и располагаем, можно в de


Ну, это зависит можно ли раздувать память под спрайты.
ох, раздули, плюс один байтик на спрайт, караул!
не волнует, у нас всё-таки не быкашка))


И оно будет медленнее, чем модифицирующийся хардкод.
с чего вдруг? хардкод нужен только где в регистры всё не влезает, например:


; hl - адрес в буфере, de - адрес спрайта

ld a,(de) ; смещение
ld c,a
inc de
ld a,(de) ; ширина
ld (#),a
inc de
ld a,(de) ; высота

_0 exa
ld b,# ; только здесь хардкодим

_1 inc de
ld a,(de)
or a
jr z,_2
ld (hl),a
_2 inc l
djnz _1
add hl,bc
exa
dec a
jp nz,_0
ret

вместо inc de везде можно чуть быстрее inc e если спрайты не пересекают #XX00

но вообще мне что-то кажется, с такой графикой спеку заведомо и памяти хватает, и скорости

ALKO
06.10.2021, 09:11
Усë уже. Разобрался.
Только вместо inc de, я сразу жахнул la a,(addr_spr+1).
Правда не знаю, как воспримет это компиль на уровне маш. кодов.


но вообще мне что-то кажется, с такой графикой спеку заведомо
Очень хотелось бы в это верить...Всë-таки пиксели расходуются слишком расточительно. Целый байт на пиксель слишком жырно. Фактически VGA. А цветопередача на порядок хуже.

reddie
06.10.2021, 11:29
Целый байт на пиксель слишком жырно. Фактически VGA. А цветопередача на порядок хуже.
Зато куча псевдоцветов через шахматку, пусть и ужасными 8х8 квадратами =)
Вот если бы Синклер вместо бесполезного Flash потратил этот бит на яркость бумаги, чтобы яркость INK и PAPER была раздельной - "цветов" было бы еще больше.
Да и вообще, графика в таком режиме довольно интересно смотрится. Дорабатывал свой Скорпион в давние времена, всего-то одна кнопка П2К c фиксацией.

Lethargeek
06.10.2021, 12:24
Только вместо inc de, я сразу жахнул la a,(addr_spr+1).
да нормально должен воспринимать, просто это же и длиньше, и медленней
по возможности структуры данных надо косвенно-последовательно адресовать


Целый байт на пиксель слишком жырно. Фактически VGA.
да не жырно, пикселей намного меньше же общим счётом