Speccy - наш выбор!

Speccy - наш выбор! (http://zx-pk.ru/index.php)
-   Программирование (http://zx-pk.ru/forumdisplay.php?f=14)
-   -   Обрезание спрайта на краю экрана. (http://zx-pk.ru/showthread.php?t=2540)

moroz1999 21st February 2006 15:51

Обрезание спрайта на краю экрана.
 
Я достаточно мало знаю теории по этому вопросу, может быть кто-то подскажет какие-то хитрые решения по следующему вопросу:

Имеется процедура вывода спрайтов на экран со следующими параметрами:
координаты вывода - попиксельные,
X-размеры спрайта кратны 8 пикселям, Y-размеры кратны 2 пикселям.

вывод на экран ведется т.н. "змейкой", т.е нечетные выводятся слева направо, четные для скорости справа налево.

вывод ведется напрямую в видеообласть памяти.

вопрос: как в теории проще/быстрее/хитрее/оптимальнее обрезать спрайт, заступающий за край экрана?

Sinus 21st February 2006 16:31

размеры спрайта какие? все спрайты разных размеров или одинаковых?
если не очень большие и одинаковые, то можно (читать нужно) раздекрянчить смещая по X и создать несколько процедур вывода (кстати выводя "змейкой" особо не ускоришь).

допустим есть max размер по X в знакоместах будет 4, то создаёшь следующие процедуры для вывода

X <= (-4*8) : нафуй
X > (-4*8) && X < (-3*8) : proc_m1
.....
X>=0 && X<255 : proc_normal
...
X>255 && X<(255+8) : proc_p1

вот.
оч. быстро ;)
но не оптимально по памяти.

------

или так: есть 3 процедуры, спрайты покрянчены

1) спрайт залазит влево
2) спрайт полностью на экране
3) спрайт залазит вправо

если спрайт на экране, то всё очевидно.

допустим, спрайт залазит вправо.

если вывод 2х строк такой:

Code:

line_1:
ld a,(bc)
inc с
ld d,a
dup max_width-1
  ld a,(de)
  and (hl)
  inc hl
  or (hl)
  inc hl
  ld (de),a
  inc e
edup
  ld a,(de)
  and (hl)
  inc hl
  or (hl)
  inc hl
  ld (de),a
  ret

line_2:
ld a,(bc)
inc с
ld d,a
ld a,<mod_this_value>
add a,l
ld l,a
dup max_width-1
  ld a,(de)
  and (hl)
  inc hl
  or (hl)
  inc hl
  ld (de),a
  dec e
edup
  ld a,(de)
  and (hl)
  inc hl
  or (hl)
  inc hl
  ld (de),a
  ret

то можно просчитать где поставить нужный ret (чтоб лишнего не выводить), замодифицировать line_1 и line_2 для этих целей, так же пропишем <mod_this_value>

обрежем по Y и далее

Code:

; b - кол-во 2x линий для вывода
; hl' - указывает на нужное место спрайта
; e' - колонка в экране
; c' - номер линии в экране
; b' - адрес таблички адресов
  ld hl,retaddr
  push hl
  ld hl,line_2
  ld de,line_1
lp0:
  push hl
  push de
  djnz lp0
  ret

retaddr:
  ....

! код работать не будет !
тут есть проёб с тем что выводится "змейкой"- тогда не получится так просто доставать адреса из таблички.
лучше без змейки. и из таблички надо доставать не только старшую часть адреса (в данном случае D) но и младшую (E) и добавлять к ней смещение

в общем идея думаю ясна.

moroz1999 21st February 2006 16:40

спасибо за инфу.
извиняюсь, мой прокол - не все требования выложил.

итак, размер спрайта сильно произвольный, я уже думал над тем, чтобы написать под каждый размер свой вывод, но их ооочень много разных.

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

кстати, на крайний случай от змейки отказаться несложно.

Sinus 21st February 2006 16:48

спрайт хранится правильно (маска - спр.)
а вот что покрянчить не можешь это плохо...
а зачем кил 8 на табличку?

Code:

RRtab:
  DB %00000000,%00000000    ; %00000000
  DB %00000000,%10000000    ; %00000001
  DB %00000001,%00000000    ; %00000010
  .... 256 раз
.... .... и всё это 9 раз (для смещений 0-8)

около 4 кил получается.

кстати можешь прооптимизировать вывод спрайта если смещение==0, но думаю смысла не имеет.

а "змейку" ты так выводишь?
Code:

.... вывод 1 линии ....
 CALL DOWN_DE
 .... вывод 2 линии ....
 CALL DOWN_DE

если да, то замени DOWN_DE на выборку из таблички, но тогда со змейкой туго будет ;)

Sinus 21st February 2006 16:50

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

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

(или ты не игру делаешь?)

... ну думаю меня поймут ...

Wlodek 21st February 2006 19:14

Общая идея такова: использовать для вывода спрайта таблицу (или две таблицы :) ) адресов видеопамяти и в каждой из них предусмотреть несколько байт или слов холостых адресов за пределами экрана, в зависимости от максимального размера спрайта. Ещё в 1989 году я это успешно использовал в "Приключении в метро" :) .

Sinus 21st February 2006 19:27

Wlodek: это если по вертикали спрайт вылазит, то можно в ПЗУ позапихивать ;)

а если по горизонтали?
или ты предлагаешь каждый байт из таблички доставать? это ж тормозно.

Wlodek 21st February 2006 20:41

По горизонтали можно представить, что экран представляет из себя не 32, а 33, 34 и т.д. знакоместа (в зависимости от реального максимального размера спрайта). По вертикали же - верно, сколько "лишних" строк, столько и "лишних" ссылок из таблиц адресов. Говорю, реально просто и элементарно. Процедура вывода спрайтов даже не задумывается над тем, что она на самом деле ряд пиксельных элементов выводит не на экран, а, например, в область адресов ПЗУ. Никаких переходов по "если", никаких ветвлений. Говорю, я это использовал и доволен ;) . А таблица адресов в памяти - ну, так нынче минимум 128К! А я в 1989 году всё в 48К упихнул и без проблем ;) . Всего 41К, со всеми таблицами, образами спрайтов, графикой и, конечно, кодом программы. Сейчас всё намного комфортнее ;) .

axor 21st February 2006 21:01

Можно сделать экран не во всю ширину, а по краям поставить атрибуты (ширина этой полоски зависит от max ширины спрайта), у которых совпадает ink и paper.

Т.е. печатаем как обычно, а пользователь видит, что спрайт ушел вправо/влево. Ну а выход за реальные размеры экрана отрабатывать уж как придется.

Sinus 21st February 2006 21:12

По горизонтали можно представить, что экран представляет из себя не 32, а 33, 34 и т.д. знакоместа

это то понятно, как говорится не в первый раз замужем.
я вот люблю цитировать себя же в таких случаях:
Quote:

или ты предлагаешь каждый байт из таблички доставать? это ж тормозно.
т.е. ты на каждый выводимый байт берёшь адрес из таблички.
а я говорю, что это ТОРМОЗНО! ;)


All times are GMT +4. The time now is 21:03.

Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.