Просмотр полной версии : Вывод атрибутов из буфера
Пытаюсь написать вывод атрибутов из буфера на видимую область.
Причём сам буфер на данный момент по ширине составляет 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
- - - Добавлено - - -
Тока щас осенило, что возможно буфер залазит на область бейсика, из которого я провожу вызов теста... Ладно. Завтра уже проверю по адресам
бейсика, из которого я провожу вызов теста
А ещё подозрительно не видно RET...
Если бы буфер залазил на область бейсика - крашилось бы и без процедуры вывода.
Саму же процедуру, если нужна скорость, можно развернуть и выводить через стек.
При этом сохранится возможность "сдвига" по вертикали и горизонтали, код несложный.
Lethargeek
29.09.2021, 18:47
взял бы, да банально оттрассировал бы давно, чем гадать и ответов ждать
взял бы, да банально оттрассировал бы давно, чем гадать и ответов ждать
А ещё лучше - снапку кинул сюда. Уже ведь любопытно стало :)
Спасбо за внимание. Всë пашет норм.
https://sun9-3.userapi.com/impg/xxX0-TGorc3xDbR_v8fYoy7M8WdAaPGq0kGvEg/cYzYLYDPpcc.jpg?size=775x582&quality=96&sign=d49227214c8f26baf36071e88934504a&type=album
У меня процедура заточена под фиксированный размер спрайтов.
Если желаю указать другой, то мне надо менять значения счётчиков (регистры 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 же адрес экрана должен быть? Зачем оттуда читать?
можно даже смещение для следующей строки хранить рядом с байтами размера
Ну, это зависит можно ли раздувать память под спрайты. И оно будет медленнее, чем модифицирующийся хардкод.
можно даже смещение для следующей строки хранить рядом с байтами размера
Не стоит забывать, что я убер-ламер в прогинге
И исходя из такого совета наваяю что-то вроде
Push hl
ld h, (Sprite_addr+3)
add h
...
Pop hl
Что значительно прибавит тактов.
- - - Добавлено - - -
Хотя... Наверное можно предварительно загнать в exx перед входом в процедуру.
загнать в exx
не забудь что для бейсика важно значение HL`
не забудь что для бейсика важно значение 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
но вообще мне что-то кажется, с такой графикой спеку заведомо и памяти хватает, и скорости
Усë уже. Разобрался.
Только вместо inc de, я сразу жахнул la a,(addr_spr+1).
Правда не знаю, как воспримет это компиль на уровне маш. кодов.
но вообще мне что-то кажется, с такой графикой спеку заведомо
Очень хотелось бы в это верить...Всë-таки пиксели расходуются слишком расточительно. Целый байт на пиксель слишком жырно. Фактически VGA. А цветопередача на порядок хуже.
Целый байт на пиксель слишком жырно. Фактически VGA. А цветопередача на порядок хуже.
Зато куча псевдоцветов через шахматку, пусть и ужасными 8х8 квадратами =)
Вот если бы Синклер вместо бесполезного Flash потратил этот бит на яркость бумаги, чтобы яркость INK и PAPER была раздельной - "цветов" было бы еще больше.
Да и вообще, графика в таком режиме довольно интересно смотрится. Дорабатывал свой Скорпион в давние времена, всего-то одна кнопка П2К c фиксацией.
Lethargeek
06.10.2021, 12:24
Только вместо inc de, я сразу жахнул la a,(addr_spr+1).
да нормально должен воспринимать, просто это же и длиньше, и медленней
по возможности структуры данных надо косвенно-последовательно адресовать
Целый байт на пиксель слишком жырно. Фактически VGA.
да не жырно, пикселей намного меньше же общим счётом
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot