Na, ilyesmi van pl. a Dos Navigator screen saverei között, meg egy Fake demoban is láttam. Szóval adva vagyon egy textúra, amit a képernyőn össze vissza kell hullámoztatni, meg egy kicsit árnyékolni, meg egy kicsit megbugázni, hogy valami féle térbeli illúziót keltsen.

Ahhoz, hogy működjön, először is szükség van egy textúrára (továbbiakban map), ami egy egyszerű zászló, meg egy palettára, ami olyan színskálát tartalmaz, amivel ki lehet hozni az árnyékolást. Ha mondjuk 16 fázisú sötétítést akarunk csinálni(most akarjunk azt) , akkor a map összesen 16 színű lehet (illetve 15, mert egy háttérszínt is kell hagyni). Hiszen mind a 16 színhez kell egy 16-os skála. Ez a 16 nekem még sok is volt. Elég 3 meg 1 (a háttér). Tehát:


Ez maga a MAP.
A flag.dat-ban van eltárolva.
Simán, bytefolytonosan.


Ilyen színeket takar a paletta
A flag.pal-ban van eltárolva

Pratkikus okokból a map 256*100-as mátrix. A kihasznált méret, vagyis a textura méretei 160*100. Mivel minden szélen kell hagyni a hullámzásnak megfelelő 'holtjátékot', a széleken 16 pixel széles üres sáv van.

A palettán 64 színt használuk ki. A 4 szín 16 fázisa.

Miután ezek az adatok megvannak, már csak mozgatni kell. A legegyszerűbb dolog amit csinálni kell, egy kis torzítás. Nem kell mást csinálni, mint minden negyedik, vagy második oszlopot egy pixellel lejjeb csúsztatni. Ettől lesz lefelé ferde az egész. Térbelinek tűnik.

A következő dolog a vertikális és horizontális hullámzás. Ehhez két táblázatra lesz szükségünk. Egy kis szögfüggvényhasználat.

procedure FillTab; var c : integer;begin   for c:=0 to 255 do Htab[c]:=round(7.5*sin(c/32*Pi)+7.5);   for c:=0 to 255 do Vtab[c]:=round(7.5*sin(c/64*Pi)+7.5); end;

A táblázat értékei így 0-15-ig változnak, ilyen értékekkel fogunk eltolni, mind x, mind y irányban. Mivel ugye mint említettem, minden negyedik oszlopot egy pixellel lejjebb fogunk tolni, a képet elég bonyolult lenne scanline-okbol felépíteni. A rutin oszlopról oszlopra fogja kirakni a cuccot.

Nagyon egyszerű. Először a Vertikális eltolást kiszedjük a táblázatból, ennyiedik sorra pozícionálunk a texturán:

texty=Vtab[x+fazis]

Innen rakjuk ki az oszlopot. Az oszlopon belül pedig:

color=map[x+Htab[y+fazis],y+texty]

árnyékolás és kirakás:

screen[x+xpos,y+ypos]=color+Vtab[Htab[y+fazis]+x]

Eddig volt az egyszerű megoldás. (HEHE.........)

A kicsit bonyolultabb (és szebb), ha beleviszünk egy kis szabálytalanságot. Nagyon unalmas tud lenni az az állandó pontos színusz ritmus. Borítsuk fel, mondjuk azzal, hogy a két táblázat számtani közepét vesszük. Ezt könnyű kiszámolni. Tehát itt a rutin amolyan Pascal-C keverék nyelvezettel. Mert ugye az algoritmus a lényeg!

for x=0 to mapwidth-16
{
  texty=(Vtab[x+fazis]+Htab[x+fazis])/2
  for y=0 to mapheight-16
  {
    color=map[x+(Htab[y+fazis]+Vtab[x+fazis])/2,texty+y]
    color=color+(Vtab[(Htab[y+fazis]+Vtab[x+fazis])/2+x]+ 

Vtab[(Htab[y+fazis]+Vtab[x+fazis])/2+x])/2
    screen[x+xpos,y+ypos]=color
  }
  if x and 3=3 ypos=ypos+1 (egy sorral lejjebb leptetes)
}

Igen. A leíró nyelvem nem valami szabványos, de remélem a lényeg látszik. Akkor nézzük mindezt asm-ben.

procedure DoFlag;assembler; var x: byte;asm   mov ax,0a000h   mov es,ax   mov di,ypos*maxwidth+xpos   mov cx,mapwidth-16   lea si,map   mov dl,Vpos {dl=X fazis}   xor bh,bh @Xloop:   push si   push di   push cx   mov bl,dl   xor al,al   mov ah,[offset Vtab+bx] {ax=256*Vtab[X]}   mov dh,ah {dh=Vtab[X]}   add ah,[offset Htab+bx]   shr ah,1 {ah=(Vtab[X]+Htab[X])/2}   add si,ax {si: oszlop kezdocime}   mov cx,mapheight-16 {hullam miatt -16}   mov ah,Hpos {ah=Y fazis} @Yloop:   mov bl,ah   mov bl,[offset Htab+bx]   add bl,dh   shr bl,1   mov al,[si+bx] {bl=(Htab[ah]+dh)/2}   mov x,al   add bl,dl {bl=(Htab[ah]+dh)/2+Y}   mov al,[offset Vtab+bx]   add al,[offset Htab+bx]   shr al,1   add al,x {al=color+(Vtab[bl]+Htab[bl])/2}   mov es:[di],al {put pixel}   add si,256 {texturan egy sorral lejjeb}   add di,maxwidth {kepernyon '' }   inc ah {Y fazis arreb}   loop @Yloop   pop cx   pop di   pop si   test cl,3 {minden 4. oszlop 1 pixellel lejjeb megy}   jne @nemtol   add di,maxwidth @nemtol:   inc si   inc di   inc dl   loop @Xloop end;

Egy kicsit hosszab ugyan, de ugyanazt jelenti.

A forráskód pascalos assemblyben sikerült.

NA CSÁ!