
               \                             /
                                       
                                      
                                                 /
                               
                                       
                             ۲۲            
                        ۱۲                      
                             ۲          
                           ۱         
                              
                                                        \
                                                       
        /                                          
                                        
                                   
                                
                                                     \
                                    
                                
                         

       

                        -=> 2D-Fake-Blobs V1.0e <=-
                      -=> Date: October 26th 1997 <=-
                 -=> by: Shadow Bandit^Diabolic Force <=-
------------------------------------------------------------------------------
ahh, back again, yesZ, even woke up and have download the newest info-file
for mekka '98...excellent..hmmmm.. time to write text.. before you sleep... :)
ok.. today daddy's present is a docu about 2D-Blobs. This effect is very
very simple to code... principicle you just add pixel-values and write
the sum on dA screen. ok!
Now let's do that effect. For the lazy one of yours i will write some pascal-
code, because pascal is easier to understand.... :)
At first you have to calculate some circles, the brightest is in the center.
This algorithm' is very easy, because I think that Blobs, especially 2D-Blobs
should not be bigger than 80*80 Pixel. I hope that you had some Trigonomenty
at your school. 
             
           /
         /  
    c  /     b
     /        
   /       
  ͼ
       a 

If you want to calculate alpha, then you use dA cosinus, because:

        a
cos =  
        c

But when c=1 then "a" is the X-Coordinate and "b" is the Y-Coordinate.
Ok, now let's use that for our algorithm'...
You know surely that the value of a Sinus and Cosinus, is from 0-1. Ok, so we
have to grow the Ampitude of the curves. Ok...the next thing we do is to
think about the degrees. Pascal, C a.s.o. want to have the values in radiants.
VERY big problem to convert that into degree's ;). A circle has 360 degrees,
but we don't think so that we need to use so much. A value of 255 should be
enough. Ok, you convert the radiants over the formula:

=> degree * PI / 180  or:  degree*2*pi/360 <=

But we wanna only 255 degrees, so the new formula is: => degree * PI / 128 <=
Ok, let's start to calculate that shit here. Define two arrays of int's for
Sin and Cosin.

var
s:array[0..255] of integer;
c:array[0..255] of integer;
i:longint;
amp:integer; { Ampitude }

procedure calculate;
begin
amp:=1;
for i:=0 to 255 do s[i]:=round(sin(i*pi/128)*amp);
for i:=0 to 255 do c[i]:=round(cos(i*pi/128)*amp);
end;

Hey, what makes the "Amp"-Var here in dA code? Simple, I had tell you that
we have to grow the curves, because they usually  have a value from 0-1.
check..ok! But that is only one simple, very small, fucking amazing circle :).
Ok, let's define a virtual screen for the Blob:

type dst_=array[0..63999] of byte;

var
dst:^dst_;
dst_Seg,w:word;

begin
calculate;
new(dst);
dst_seg:=seg(dst^);
w:=0;
while w<64000 do begin
inc(w);
mem[dst_seg:w]:=0;
end;

Now you have a clear virtual screen. Now you can calculate the blob on the
screen. For a test you should also write it on VGA...

amp:=1;
w:=255;
while amp<21 do begin
inc(amp);
dec(w,10);
for i:=0 to 255 do s[i]:=round(sin(i*pi/128)*amp);
for i:=0 to 255 do c[i]:=round(cos(i*pi/128)*amp);

for i:=0 to 255 do begin
mem[$a000:(100+s[i])*320+(160+c[i])]:=w;
mem[dst_Seg:(100+s[i])*320+(160+c[i])]:=w;
end;
end;

ahhh...a nice sweeet blob... grrrr... there are no nice color-shadings in
that fuckin' blob. Ok, let's shoot up that BIG problem ;).

proedure setpal(c,r,g,b:byte);
begin
port[$3c8]:=c;
port[$3c9]:=r;
port[$3c9]:=g;
port[$3c9]:=b;
end;

for i:=0 to 255 do setpal(i,0,0,i div 4);

check...ok! Now implementate this here in your code and.... ahh very good.. :)
ok, now we can code the blob-effect. It's better to draw the Blob in
the first offset's of the virtual screen, for eg. at x=1 and y=1.
For the Blob-Effect you need of cource at least two blobs...
I think, that you wanna a flicker-free effect, so it's better to define
another virtual-screen. You now know how to do that. check...ok!
Then you read the Blob, wich you have calculated in for eg. in the screen 1
and write it to a defined position on screen 2. But how to do that? Simple,
When you read the Blob (the color-values) you add the value from your blob
in screen 1 and the value from the destination screen (2) and write the sum
to screen 2. Now you read again the blob from (1) and if it's next to the
other blob you have the blob-effect. Nice and simple :), you only must check
if the sum is greater than 255. If all blobs are drawn, then you flip the
screen 2 to VGA ($a000) and for the next loop you clear screen 2 and do
dA shit again. Cool..check ok! For the lazy ones of you...here'S da
complete example-codE:

------------------------------=> Code <=---------------------------------------
uses crt;

type
one_=array[0..63999] of byte;
two_=array[0..63999] of byte;

var
s:array[0..255] of integer;
c:array[0..255] of integer;
i:longint;
amp:integer;
one:^one_;
one_Seg,w:word;
two:^two_;
two_seg:word;

procedure calculate; { Example how to calc circles, not optimized :) }
begin
amp:=1;
for i:=0 to 255 do s[i]:=round(sin(i*pi/128)*amp);
for i:=0 to 255 do c[i]:=round(cos(i*pi/128)*amp);
end;

procedure setpal(c,r,g,b:byte);
begin
port[$3c8]:=c;
port[$3c9]:=r;
port[$3c9]:=g;
port[$3c9]:=b;
end;

procedure copyvirtscr(fromseg,toseg:word);assembler;
asm
push ds
mov es,[toseg]
mov ds,[fromseg]
xor si,si
xor di,di
mov cx,16000
db 66h
rep movsw
pop ds
end;

procedure clrvirtscr(scrseg:word);assembler;
asm
xor di,di
mov es,[scrseg]
mov cx,16000
db 66h;
xor ax, ax
db 66h;
rep stosw
end;

procedure blob(xx,yy,xrg,yrg:word); { Here is the main stuph :) }
var col,col2:longint;
cg:longint;
x,y:word;
begin
for y:=0 to yrg do begin
for x:=0 to xrg do begin
col:=mem[one_seg:y*320+x];
if col>0 then begin
col2:=mem[two_seg:yy*320+xx+(y*320+x)];
cg:=col+col2;
if cg<255 then mem[two_Seg:yy*320+xx+(y*320+x)]:=cg;
if cg>=255 then mem[two_Seg:yy*320+xx+(y*320+x)]:=254;
end;
end;
end;
end;

begin
calculate;
new(one);
one_seg:=seg(one^);
new(two);
two_Seg:=seg(two^);
w:=0;
asm mov ax,13h; int 10h end;

for i:=0 to 255 do setpal(i,0,0,i div 4);

while w<64000 do begin { Clear all virtual screens }
inc(w);
mem[one_seg:w]:=0;
mem[two_seg:w]:=0;
end;

amp:=1;
w:=220;

while amp<21 do begin { Calculate the blob }
inc(amp);
dec(w,11);
for i:=0 to 255 do s[i]:=round(sin(i*pi/128)*amp);
for i:=0 to 255 do c[i]:=round(cos(i*pi/128)*amp);
for i:=0 to 255 do begin
mem[$a000:(100+s[i])*320+(160+c[i])]:=w;
mem[one_Seg:(100+s[i])*320+(160+c[i])]:=w;
end;
end;

repeat until keypressed;
readkey;
readkey;
clrvirtscr(one_seg);
clrvirtscr(two_seg);
clrvirtscr(sega000);

{ That was the first part - now comes the real effect... }

for i:=0 to 220 do setpal(i,0,0,i div 4);
for i:=221 to 255 do setpal(i,i-200,i-200,63);
while w<64000 do begin
inc(w);
mem[one_seg:w]:=0;
mem[two_seg:w]:=0;
end;
amp:=1;
w:=220;
while amp<21 do begin
inc(amp);
dec(w,11);
for i:=0 to 255 do s[i]:=round(sin(i*pi/128)*amp); { Calulate Blob }
for i:=0 to 255 do c[i]:=round(cos(i*pi/128)*amp);
for i:=0 to 255 do begin
mem[one_seg:(20+s[i])*320+(20+c[i])]:=w;
end;
end;
mem[one_seg:20*320+20]:=220; { Kick off da black pixels on the blob }
mem[one_seg:19*320+20]:=220;
mem[one_seg:20*320+21]:=220;
mem[one_seg:20*320+19]:=220;
mem[one_seg:21*320+20]:=220;
for i:=0 to 255 do s[i]:=round(sin(i*pi/128)*35); { For animating the blobs }
for i:=0 to 255 do c[i]:=round(cos(i*pi/128)*35);
i:=0;
repeat
inc(i);
if i=255 then dec(i,255);
blob(160+s[i],100,40,40);
blob(160-s[i],100,40,40);
blob(160,100+c[i],40,40);
blob(160,100-c[i],40,40);
copyvirtscr(two_seg,sega000);
clrvirtscr(two_Seg);
until keypressed;
asm mov ax,3; int 10h end;
dispose(one);
dispose(two);
end.
----------------------------------=> EOC <=-----------------------------------
ahhhh... sweet.. I've used 40*40 Blobs, you see.....you can code much more
things with this princip. For eg. a Star-Blob Effect with Motion-Blur... very
nice and a logo like in the Intro "Ah!" from Pulse... ok...but optimize this
lame code a bit... :) Now it's 2:10 am and I'm tired writing docus and do
lame ansi's like above :].

For questions and talking about bullshit, a.s.o. contact me:

Michael Horstmann
Masteweg 14
58640 Iserlohn
Germany
Phone: +49/2371/42938
            or: 42923 

GreetinX:
alL Diabolic Force-Chaots (don't forget your Train-Yoga-practice Cati H. :]),
Teasy^Sympathy, Panther^Sympathy, Magic^Ethos9, Lure^Finix, MadMan^Finix,
Assign^Ethos9, Timo,BaC, RiPmasTer, Fireball, Daniella S., Westbam...
and all I forgot.
