PDA

Просмотр полной версии : Атрибутный Fade in/Fade out



newart
06.08.2008, 16:44
Subj не у кого не завалялся? (для картинки)

Желательно фремовый.

rasmer
06.08.2008, 17:32
Subj не у кого не завалялся?

Желательно фремовый.Слава... в ревюхе даже конкурс был на самый быстрый/маленький сабж... так что там найдёшь штук 10 процедурок... :) к сожалению год не помню...

scl^mc
06.08.2008, 22:28
1994. одно время там в лидерах была процедура из terminator-2 длиной 11 байт. щас посмотрю точно скажу

млин, 2 раза ошибся. 1995 год, 2й номер, процедура длиной 33 байта :) а из терминатора - 39 байт

org 40000
ent
ei
ld e,255
l1 ld hl,25528
ld bc,768
and a
rr e
l2 ld a,(hl)
xor e
and e
xor e
ld (hl),a
inc hl
dec bc
ld a,b
or с
jr nz,l2
ld b,4
l3 halt
djnz l3
xor a
cp e
jr nz,l1
ret

rasmer
07.08.2008, 00:58
а так ещё автор IceClimber хвалился, что у него самая фастовая и манюсенькая...

Sinus
07.08.2008, 01:48
а нахрена в вышеприведённой процедуре?


xor e
and e
xor e

это можно спотойно заменить на просто


and e

ибо


xor e : and e : xor e == xor a,e : and a,e : xor a,e == ((a ^ e) & e) ^ e

a : 0 : 1 : 0 : 1
e : 0 : 0 : 1 : 1
((a^e)&e)^e : 0 : 0 : 0 : 1
a&e : 0 : 0 : 0 : 1


и ещё одно: все эти процедурки по 30 байт будут не очень красиво затемнять картинку, если на ней есть и пэйпер, и инк, и брайт.

я вот в таргете делал с табличкой в 256 байт, это конечно не 33 байта, но зато сверхфастово, правильно и красиво выглядит :)

rasmer
07.08.2008, 02:56
LD B,8
F_OUT04
LD HL,#5800
F_OUT03
LD A,(HL)
AND %11000000
LD E,A

LD A,(HL)
AND %00000111
JR Z,F_OUT01
DEC A
F_OUT01 LD D,A

LD A,(HL)
RRCA
RRCA
RRCA
AND %00000111
JR Z,F_OUT02
DEC A
F_OUT02 RLCA
RLCA
RLCA
OR D
OR E

LD (HL),A

INC HL
LD A,H
CP #5B
JR NZ,F_OUT03

HALT
DJNZ F_OUT04

Сорри за кривость и ламость - писалось наживую прям тут в посте /и все это нехило оптимизируемо и по скорости, и по размеру/...
уважаемый Sinus - почему фэйдоут сделанный по подобию будет работать криво?

newart
07.08.2008, 16:12
я вот в таргете делал с табличкой в 256 байт, это конечно не 33 байта, но зато сверхфастово, правильно и красиво выглядит
Поделись?

Sinus
07.08.2008, 18:22
Поделись?

идея такая (пишу прямо тут, ничего не проверял, и в оригинальный код не смотрел):


LD LX,8

ONCE HALT
LD H,'ATTR_TABLE
LD DE,#5800

LOOP DUP 32
LD A,(DE)
LD L,A
LDI
EDUP
JP NZ,LOOP

DEC LX
JP NZ,ONCE


табличка ATTR_TABLE должна быть расположена по круглому адресу.
есть одна проблема: если аттрибут будет #FF (хотя нах кому нужет белый папер, белый инк с брайтом и с флэшэм :) ? ), то после LDI рег. H перескочит на другой адрес. но эта проблема надуманная, ибо такое нигде не встречается.

самая главная фишка это конечно таблички :) но я сейчас так не вспомню что я там писал в них. надо код искать.

зы. от DUP 32 можно избавится, это значительно сократит размер процедуры, но зато будет не мега фастово :)

Добавлено через 3 минуты

уважаемый Sinus - почему фэйдоут сделанный по подобию будет работать криво?

твой фэйд будет работать прямо, но очень не быстро.
а если сделать его быстро, то он хорошо вырастет в размере :)

NovaStorm
07.08.2008, 19:30
А так ли важна тут быстрота то? Ведь аттрибуты за фрейм хоть как кидай, опоздать к инту невозможно. Или при этом ещё что-то считается?

rasmer
07.08.2008, 20:40
твой фэйд будет работать прямо, но очень не быстро.
а если сделать его быстро, то он хорошо вырастет в размере :)ну уж все равно ИМХА будет занимать меньше чем твой плюс табличка

Sinus
08.08.2008, 00:00
кстати, а вот может взять и посчитать сколько тактов (хотя бы примерно, по бордюру) занимают эти маленькие фэйдилки?
у меня просто нет времени, а было бы интересно :)

Добавлено через 1 минуту

ну уж все равно ИМХА будет занимать меньше чем твой плюс табличка
вообще если flash не используется, то табличка может занимать 128 байт, и 21 байт сама процедура (можно сократить ещё если использовать JR а не JP, но будет медленнее)

rasmer
08.08.2008, 00:25
вообще если flash не используется, то табличка может занимать 128 байт, и 21 байт сама процедура (можно сократить ещё если использовать JR а не JP, но будет медленнее)1) при чомтут флэш если он даже не успеет мигнуть... так что флэш в расчот можно не брать ВООБЩЕ
2.

LOOP DUP 32
LD A,(DE)
LD L,A
LDI
EDUP
какой тут нафиг 21 байт?

Sinus
08.08.2008, 14:02
DUP убери, и будет 21

scl^mc
09.08.2008, 00:15
а нахрена в вышеприведённой процедуре?
это копипаст, если что :rolleyes:

GriV
09.08.2008, 17:35
Самая правильная и быстрая процедура была из терминатора, на которой столько копьев ревюшники сломали.
первой была в этюдах (номер 3 от 94 г):


DI
LD BC,#0000
LD D,#5B
AGAIN
LD HL,#5800
NEXT_A
LD A,(HL)
CP С
JR Z,NEXT_B
DEC (HL)
NEXT_B
INC HL
LD A,H
CP D
JR NZ,NEXT_A
DJNZ AGAIN
EI
RET

длина:

номер 4 за 94 (цитата из терминатора):


LD B,7
L4
HALT
LD HL,SPEED
L0
DEC HL
LD A,L
OR H
JR NZ,L0
LD HL,22528
L3
LD A,(HL)
AND 56
JR Z,L1
SUB 8
L1
LD C,A
LD A,(HL)
AND 7
JR Z,L2
DEC A
L2
OR C
LD (HL),A
INC HL
LD A,H
CP 91
JR NZ,L3
DJNZ L4
RET

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

номер 6 за 94г:


LD B,8
LD C,#C7
LOOP
LD A,C
SUB 8
LD (COM),A
LD C,A
LD HL,22528
LD DE,768
L1
LD A,(HL)
DEFB #C9 ; тут собирается команда res n,(hl)
COM
DEFB 0
LD (HL),A
INC HL
DEC DE
LD A,D
OR E
JR NZ,L1
PUSH BC
LD BC,#1800
L2
DEC BC
LD A,B
OR C
JR NZ,L2
POP BC
DJNZ LOOP
RET

Длина: 40 байт

номер 2 за 95г.:


EI
LD E,255
L1
LD HL,22528
LD BC,768
AND A
RR E
L2
LD A,(HL)
XOR E
AND E
XOR E
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,L2
LD B,4
L3
HALT
DJNZ L3
XOR A
CP E
JR NZ,L1
RET

длина: 33 байта

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


INC HL
LD A,H
CP #5B
JR NZ,L2

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


PAUSE EQU 4
LD B,8
L1
LD HL,#5800
L2
SRL (HL)
INC HL
LD A,H
CP #5B
JR NZ,L2
LD C,PAUSE
L3
HALT
DEC C
JR NZ,L3
DJNZ L1
RET

длина: 22 байта

лучшая читательская процедура - длина 24 байта, оптимизация достигнута изменением расположения фрагмента задержки:


PAUSE EQU 4
LD B,%01111111
L1
LD L,PAUSE
L3
HALT
DEC L
JR NZ,L3
LD H,#58
L2
LD A,(HL)
AND B
LD (HL),A
INC HL
LD A,H
CP #5B
JR NZ,L2
SRL B
JR C,L1
RET


номер 4 от 95г.:


PAUSE EQU 4
CLRSCR
LD C,127
L1
LD HL,23295
L2
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 3,H
JR NZ,L2
LD B,PAUSE
L3
HALT
DJNZ L3
RRC C
JR C,L1
RET

длина: 23 байта

номер 5 от 95г.:


PAUSE EQU 5
LD C,#FF
L1
LD H,#5A
L2
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 2,H
JR Z,L2
SRL C
RET NC
LD B,PAUSE
L3
HALT
DJNZ L3
JR L1

в этой процедуре используется пара HL на уменьшение, благодарая чему не портится (как при увеличении) лишняя область памяти, кроме того не задаётся содержимое регистра L (собственно длина 22 байта), ведь всё равно этот первый бит отдаётся на мерцание (которое редко используется и находиться должно в нижней части экрана), и кроме того при повторном проходе он будет обнулён.

далее процедура от редакции (длина 21 байт):


PAUSE EQU 5
LD C,#FF
L3
LD B,PAUSE
L2
LD H,#5A
L1
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 3,H
JR NZ,L1
DJNZ L2
SRL C
JR C,L3
RET

Эта процедура не зависит от прерываний (EI|DI), так как задержка происходит не через HALT а посредством многократных проходов с одним и тем же байтом-маской.

тут видимо была поставлена большая жирная если не точка, то точка с запятой точно, потому что следующая гасилочка была только в 4-5 от 96г.:


PREPARE
LD HL,DAL_TBL
PREP_T
LD A,L
AND 7
JR Z,$+3
DEC A
LD E,A
LD A,L
AND #38
JR Z,$+4
SUB 8
OR E
LD (HL),A
INC L
JR NZ,PREP_T
FADEOUT
LD D,DAL_TBL/256 ; старший байт расположения таблицы DAL_TBL, сама таблица должна быть по ровному адресу
LD B,7
W_RAY
HALT
LD HL,#5800
ATR_DEC
LD E,(HL)
LD A,(DE)
LD (HL),A
INC HL
LD A,H
CP #5B
JR C,ATR_DEC
DJNZ W_RAY
RET
DAL_TBL
DEFS 256

длина самого вывода (начинается с метки FADEOUT) - 20 байт, что само по себе рекордно, правда требуется навесок в виде процедуры подготовки данных (DAL_TBL), кроме того это "правильная" процедура вывода - она гасит как в терминаторе, а не упрощённо по битам.

и тут же процедура-рекордсмен, того же автора, длина аж 19 байт (опять же исключая процедуру подготовки), тоже по терминаторскому алгоритму:


PAL_TBL EQU 0-(256*8)
FADEOUT
LD D,PAL_TBL/256 ; старший байт расположения таблицы DAL_TBL, сама таблица должна быть по ровному адресу
W_RAY
HALT
LD H,#5A
ATR_DEC
LD E,(HL)
LD A,(DE)
LD (HL),A
DEC HL
BIT 3,H
JR NZ,ATR_DEC
INC D
JR NZ W_RAY
RET

PREPARE
LD HL,PAL_TBL
LD BC,#800
FILL_T
LD A,L
AND 7
JR Z,$+3
DEC A
LD E,A
LD A,L
AND #38
JR Z,$+4
SUB 8
OR E
LD (HL),A
CPI
JP PE,FILL_T
RET

newart
09.08.2008, 21:16
А к чему такая

Самая правильная и быстрая процедура была из терминатора, на которой столько копьев ревюшники сломали.
первой была в этюдах (номер 3 от 94 г):
C Fade Out действительно все просто, другое дело Fade In...

GriV
10.08.2008, 10:40
самый лучщий набор зажигалок был в моей View. (смотрите подпись или ищите на zx.da.ru). Код приложен. Я выдёргивал все эти зажигалки из тех же ревюшек, де факто перебрал все какие мог, это лучшие.

Ага, забыл добавить. Там названия зажигалок SCR1, SCR2,... SCR8.
В программе они по рандомайзу запускаются. Где картинка должна лежать очевидно переменная BUFF. Оттуда она дёргается. Большинство зажигалок привязаны к ровным адресам картинки, поэтому адреса для BUFF брать кратные #200.

axor
19.08.2008, 13:41
Хоть бы рассказали, для таких неучей как я, принцип Треминатора что ли...

GriV
23.08.2008, 18:19
Ну у меня под рукой всегда ревюшки да и знаю я их почти наизусть :-)
В отечественных "гасилках" "гасили" просто:
ld b,#ff - маска гашения
...
ld a,(hl)
and b - нафигарили по маске
ld (hl),a
...
and a - сбросили флаг переноса
rrc b - вставили его в старший бит, так и получается 255->127->63->...->3->1->0 - то есть 8 (или 9) циклов.
...
jr nz,start

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

в терминаторе было круче
там было хитрое гашение - там учитывалось что атрибуты идут последовательно, вначале гашение чернил, потом (раз в цикл гашения чернил) гашение фона, делается простым уменьшением байта атрибута. Какие то объекты сразу "погаснут" так как их атрибут сразу станет 0, какие то будут достаточно долго (у которых включена яркость и фон). Итого максимум 256 циклов (djnz в оригинальном алгоритме при установке B в 0).

Даже на ходу соптимизировав код терминатора можно получить такое:


LD DE,#0001
LD B,D
AGAIN
LD HL,#5AFF
NEXT_A
LD A,(HL)
SUB E
ADC A,D
LD (HL),A
NEXT_B
DEC HL
BIT 2,H
JR Z,NEXT_A
HALT
DJNZ AGAIN
RET

Длина - 20 байт :-)
Можно на 1 байт сколбасить (19 байт по терминаторскому алгоритму!!!), сделав LD H,#5B вместо LD HL,#5AFF. Всё равно идёт на уменьшение, всё равно проверка идёт на Bit 2,H, однако может испортиться область #5b00-#5bff (так как L может быть равной и 255), однако не надо никаких буферов и предварительных подготовок.

Особое внимание на конструкцию

SUB E
ADC A,D

Её нужно трактовать как

SUB 1
ADC A,0

Она уменьшает аккумулятор на 1 но не меньше 0.

GriV
08.10.2008, 13:35
LD B,0
AGAIN
LD HL,#5AFF
NEXT_A
XOR A
ADD A,(HL)
JR Z,$+3
DEC (HL)
NEXT_B
DEC HL
BIT 2,H
JR Z,NEXT_A
HALT
DJNZ AGAIN
RET
19 байт :-) можно сократить до 18 сделав то самое LD A,#5B :-)
Ревюшниками и не снилось :-) Правда а тактах чуток длиннее

kotsoft
09.04.2009, 23:31
А что можете подсказать по поводу пиксельного FADE_IN.
сейчас попробовал делать тупо:
---
AND (IX)
INC IX
OR (HL)
LD (DE),A
----
где IX - адреса из ПЗУ. но получается некрасиво

Kurles
10.04.2009, 13:28
А что можете подсказать по поводу пиксельного FADE_IN.
сейчас попробовал делать тупо:
---
AND (IX)
INC IX
OR (HL)
LD (DE),A
----
где IX - адреса из ПЗУ. но получается некрасивоПопробуй просто следить за тем, что бы ix не выходил за пределы относительно нормального рандомного битового поля ПЗУ, например:


....
;инициализация ix, что бы каждую итерацию адрес был разный
ld a,r
ld xl,a
;в районе адреса #0600 в пзу 48-го бейсика относительно хорошие "рандомные" данные для нашего случая
ld xh,#06
....

inc ix
ld a,xh
cp 9
;что бы ix далеко не убегал
jr nz,met1
ld xh,#06
met1 ....
Оптимально, имхо, 5 таких итераций, затем ldir-ом оригинальную картинку в экран/буфер. Можно еще массив случайных чисел самому генерировать в озу перед выводом на экран картинки. Ну и, естественно, если целый экран фейдится, желательно использовать промежуточный буфер и последующий быстрый вывод на экран, что бы не было заметно, как фазы прорисовываются.

newart
13.04.2009, 20:06
А что можете подсказать по поводу пиксельного FADE_IN.
сейчас попробовал делать тупо:
Только что добили все эклетронные номера ZX Ревю (http://http://zxpress.ru/issue.php?id=277) , там в этюдах дофига всяких проявлялок экрана.

kotsoft
13.04.2009, 23:17
2Kurles: Спасибо, идею понял, реализовал, то что надо!
2newart: Вам отдельный респект, отличный проект, давно читаю. Одного только не хватает у вас, (или я не нашел?) поиска по сайту (по текстам статей). Облако тегов - не то

newart
13.04.2009, 23:32
поиска по сайту (по текстам статей).
Я расчитывал сделать его с помощью гуглу, да он всё ни как не может толком сайт проиндексировать.