Copy Link
Add to Bookmark
Report

VGA Trainer Program: part 15

eZine's profile picture
Published in 
VGA Trainer Program
 · 4 Aug 2024

                   Õ-------------------------------¸ 
| W E L C O M E |
| To the VGA Trainer Program | |
| By | |
| DENTHOR of ASPHYXIA | | |
Ô-------------------------------¾ | |
--------------------------------Ù |
--------------------------------Ù

--==[ PART 15 ]==--

Introduction


Hello again. As you can see, this tut is very soon after the last one. This is because of two reasons ... 1) The PCGPE ][ will be out soon, so I thought I would make sure I have more then just four new trainers for it, and 2) I am usually so late between tuts, I thought I would make up for it.

There is a discussion going on in Usenet, mostly saying that trainers etc. should be written a bit more formally and none of this gay banter and familiar language should be used. My "quotes" would definitely be out ;-) But, until I get paid for doing this (and there don't seem to be any takers on that score), I will continue to write in this manner. My apologies to those who don't like this, but hey, its free, what did you expect?

This trainer is on plasmas, and the sample program actually became quite large, mostly due to the fact that there was some plasma stuff I wanted to try out.

The concept is very simple, at least for this plasma, so you shouldn't have any problems understanding it ... AFTER you have read the text file ... jumping straight into the source may be hazardous to your brain.

Plasmas are a great way to wow your friends by their weird shapes and forms. I was at one stage going to write a game where the bad guy just had two circular plasmas instead of eyes... I am sure you will find creative and inventive new ways of doing and using plasmas.


If you would like to contact me, or the team, there are many ways you can do it :

  1. Write a message to Grant Smith/Denthor/Asphyxia in private mail on the ASPHYXIA BBS.
  2. Write to : Grant Smith P.O.Box 270 Kloof 3640 Natal South Africa
  3. Call me (Grant Smith) at (031) 73 2129 (leave a message if you call during varsity). Call +27-31-73-2129 if you call from outside South Africa. (It's YOUR phone bill ;-))
  4. Write to denthor@beastie.cs.und.ac.za in E-Mail.
  5. Write to asphyxia@beastie.cs.und.ac.za to get to all of us at once.

NB : If you are a representative of a company or BBS, and want ASPHYXIA to do you a demo, leave mail to me; we can discuss it.
NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling quite lonely and want to meet/help out/exchange code with other demo groups. What do you have to lose? Leave a message here and we can work out how to transfer it. We really want to hear from you!

How do plasmas work?

I will only cover one type of plasma here ... a realtime plasma of course. Other types of plasmas include a static picture with a pallette rotation...

When you get right down to it, this method of realtime plasmas is merely an intersection of four COS waves. We get our color at a particular point by saying :

      col := costbl[one]+costbl[two]+costbl[three]+costbl[four];

The trick is getting the four indexes of that cos table array to create something that looks nice. This is how we organise it : Have two of them being indexes for vertical movement and two of them being indexes for horizontal movement.

This means that by changing these values we can move along the plasma. To draw an individual screen, we pass the values of the four to another four so that we do not disturb the original values. For every pixel across, we add values to the first two indexes, then display the next pixel. For every row down, we add values to the second two indexes. Sound complex enough? Good, because that what we want, a complex shape on the screen.

By altering the original four values, we can get all sorts of cool movement and cycling of the plasma. The reason we use a cos table is as follows : a cos table has a nice curve in the value of the numbers ... when you put two or more together, it is possible to get circular pictures ... circles are hard to do on a computer, so this makes it a lot easier...

Okay, now you can have a look at the source file, all I do is put the above into practice. I did add one or two things though ...

  • Background : This is just a large array, with the values in the array being added to the plasma at that pixel.
  • Psychadelic : This cycles through about 7000 colors instead of just rotating through the base 256.

Clever fading

You will notice when the sample program fades in and out that the colors all reach their destination at the same time ... it other words, they don't all increment by one until they hit the right color then stop. When done in that way the fading does not look as professional.

Here is how we do a step-crossfade.

Each r,g,b value can be between 0 and 64. Have the pallette we want to get to in bob and the temporary pallette in bob2. For each step, from 0 to 63 do the following :

     bob2[loop1].r:=bob[loop1].r*step/64;

That means if we are halfway through the crossfade (step=32) and the red value is meant to get to 16, our equation looks like this :

    r:=16*32/64 
r=8

Which is half of the way to where it wants to be. This means all colors will fade in/out with the same ratios... and look nicer.

Rotating the pallette

I have done this one before I think .. here it is ...

move color 0 into temp 

move color 1 into color 0
move color 2 into color 1
move color 3 into color 2
and so on till color 255

move temp into color 255

And you pallette is rotating. Easy huh? Recheck tut 2 for more info on pallette rotation

In closing

The text file was a bit short this time, but that is mostly because the sample file is self explanitory. The file can however be speeded up, and of course you can add certain things which will totally change the look of the plasma.

As always, I am on the lookout for more ideas for future tuts, if you have some, mail me!

No quote today, this lan doesn't encourage creative thinking ;) However, there will be quotes in future as I have been told that some people like them. Even Pipsy said this while we were playing Ctrl-Alt-Del (two player game, one has to hit ctrl and alt as the other hits del, and the person hitting the del has to do it quickly so that the computer doesn't reboot. If the computer reboots the person who was hitting ctrl and alt has won. I thought I was doing really badly against Pipsy until I found out that the computer had frozen ;-))

Byeeee....
- Denthor
14:11
16-9-94


The following are official ASPHYXIA distribution sites :

É--------------------------Ë----------------Ë-----» 
|BBS Name |Telephone No. |Open |
Ì--------------------------Î----------------Î-----¹
|ASPHYXIA BBS #1 |+27-31-765-5312 |ALL |
|ASPHYXIA BBS #2 |+27-31-765-6293 |ALL |
|C-Spam BBS |410-531-5886 |ALL |
|POP! |+27-12-661-1257 |ALL |
|Soul Asylum |+358-0-5055041 |ALL |
|Wasted Image |407-838-4525 |ALL |
È--------------------------Ê----------------Ê-----¼

Leave me mail if you want to become an official Asphyxia BBS distribution site.

TUTPRO15.PAS

{$X+} 
USES crt;

TYPE RGBType = Record
R, G, B : Byte;
End;
PalType = Array[0..255] of RGBType;

VAR bob,bob2:paltype; { Two pallettes, current and temporary }
biiiigpallette : array [1..6656] of RGBType; { A massive pallette for the
psychadelic effect }
start:integer; { Where in the Biiiig pallette are we? }
Effect,Background:Boolean; { Configuration of effects }

costbl : Array [0..255] of byte; { cos table lookup }
mov1,mov2,mov3,mov4 : byte; { current positions }
bkg : array [1..50,1..80] of byte; { The pic in the background }


{--------------------------------------------------------------------------}
procedure PAL(Col,R,G,B : Byte); assembler;
{ This sets the Red, Green and Blue values of a certain color }
asm
mov dx,3c8h
mov al,[col]
out dx,al
inc dx
mov al,[r]
out dx,al
mov al,[g]
out dx,al
mov al,[b]
out dx,al
end;

{--------------------------------------------------------------------------}
Procedure SetAllPal(Var Palette : PalType); Assembler;
{ This dumps the pallette in our variable onto the screen, fast }
Asm
push ds
lds si, Palette
mov dx, 3c8h
mov al, 0
out dx, al
inc dx
mov cx, 768
rep outsb
pop ds
End;

{--------------------------------------------------------------------------}
Procedure Makerun (r,g,b:integer);
{ This creates a ramp of colors and puts them into biiiigpallette }
VAR loop1:integer;
BEGIN
for loop1:=start to start+127 do BEGIN
if r=1 then
biiiigpallette[loop1].r:=63-(loop1-start) div 4 else
if r=2 then
biiiigpallette[loop1].r:=(loop1-start) div 4 else
biiiigpallette[loop1].r:=0;

if g=1 then
biiiigpallette[loop1].g:=63-(loop1-start) div 4 else
if g=2 then
biiiigpallette[loop1].g:=(loop1-start) div 4 else
biiiigpallette[loop1].g:=0;

if b=1 then
biiiigpallette[loop1].b:=63-(loop1-start) div 4 else
if b=2 then
biiiigpallette[loop1].b:=(loop1-start) div 4 else
biiiigpallette[loop1].b:=0;
END;

for loop1:=start+128 to start+255 do BEGIN
if r=2 then
biiiigpallette[loop1].r:=63-(loop1-start) div 4 else
if r=1 then
biiiigpallette[loop1].r:=(loop1-start) div 4 else
biiiigpallette[loop1].r:=0;

if g=2 then
biiiigpallette[loop1].g:=63-(loop1-start) div 4 else
if g=1 then
biiiigpallette[loop1].g:=(loop1-start) div 4 else
biiiigpallette[loop1].g:=0;

if b=2 then
biiiigpallette[loop1].b:=63-(loop1-start) div 4 else
if b=1 then
biiiigpallette[loop1].b:=(loop1-start) div 4 else
biiiigpallette[loop1].b:=0;
END;
start:=start+256;
END;


{--------------------------------------------------------------------------}
Procedure init;
VAR loop1,loop2,r,g,b:integer;
f:text;
ch:char;

Function rad (theta : real) : real; { Converts degrees to radians }
BEGIN
rad := theta * pi / 180
END;

BEGIN
write ('Do you want the Psychadelic effect? ');
repeat
ch:=upcase(readkey);
until ch in ['Y','N'];
if ch='Y' then BEGIN
Writeln ('Yeah!');
effect:=true;
END else BEGIN
Writeln ('Nah');
effect:=false;
END;
writeln;
while keypressed do readkey;
write ('Do you want the background? ');
repeat
ch:=upcase(readkey);
until ch in ['Y','N'];
if ch='Y' then BEGIN
Writeln ('Yeah!');
background:=true;
END else BEGIN
Writeln ('Nah');
background:=false;
END;
writeln;
while keypressed do readkey;
writeln ('Hit any key to continue...');
readkey;
while keypressed do readkey;
asm
mov ax,0013h
int 10h { Enter mode 13 }
cli
mov dx,3c4h
mov ax,604h { Enter unchained mode }
out dx,ax
mov ax,0F02h { All planes}
out dx,ax

mov dx,3D4h
mov ax,14h { Disable dword mode}
out dx,ax
mov ax,0E317h { Enable byte mode.}
out dx,ax
mov al,9
out dx,al
inc dx
in al,dx
and al,0E0h { Duplicate each scan 8 times.}
add al,7
out dx,al
end;

fillchar (bob2,sizeof(bob2),0); { Clear pallette bob2 }
setallpal (bob2);

start:=0;
r:=0;
g:=0;
b:=0;
Repeat
makerun (r,g,b);
b:=b+1;
if b=3 then BEGIN
b:=0;
g:=g+1;
END;
if g=3 then BEGIN
g:=0;
r:=r+1;
END;
until (r=2) and (g=2) and (b=2);
{ Set up our major run of colors }

start:=0;
if not effect then BEGIN
for loop1:=0 to 128 do BEGIN
bob[loop1].r:=63-loop1 div 4;
bob[loop1].g:=0;
bob[loop1].b:=loop1 div 4;
END;
for loop1:=129 to 255 do BEGIN
bob[loop1].r:=loop1 div 4;
bob[loop1].g:=0;
bob[loop1].b:=63-loop1 div 4;
END;
END else
for loop1:=0 to 255 do bob[loop1]:=biiiigpallette[loop1];

{ Set up a nice looking pallette ... we alter color 0, so the border will
be altered. }

For loop1:=0 to 255 do
costbl[loop1]:=round (cos (rad (loop1/360*255*2))*31)+32;
{ Set up our lookup table...}

fillchar (bkg,sizeof(bkg),0);
assign (f,'a:bkg.dat');
reset (f);
for loop1:=1 to 50 do BEGIN
for loop2:=1 to 80 do BEGIN
read (f,ch);
if ord (ch)<>48 then
bkg[loop1,loop2]:=ord (ch)-28;
END;
readln (f);
END;
close (f);
{ Here we read in our background from the file bkg.dat }
END;


{--------------------------------------------------------------------------}
Procedure DrawPlasma;
{ This procedure draws the plasma onto the screen }
VAR loop1,loop2:integer;
tmov1,tmov2,tmov3,tmov4:byte; { Temporary variables, so we dont destroy
the values of our main variables }
col:byte;
where:word;
BEGIN
tmov3:=mov3;
tmov4:=mov4;
where:=0;
asm
mov ax,0a000h
mov es,ax { In the two loops that follow, ES is not altered so
we just set it once, now }
end;
For loop1:=1 to 50 do BEGIN { Fifty rows down }
tmov1:=mov1;
tmov2:=mov2;
for loop2:=1 to 80 do BEGIN { Eighty columns across }
if background then
col:=costbl[tmov1]+costbl[tmov2]+costbl[tmov3]+costbl[tmov4]+costbl[loop1]+costbl[loop2]+bkg[loop1,loop2]
else
col:=costbl[tmov1]+costbl[tmov2]+costbl[tmov3]+costbl[tmov4]+costbl[loop1]+costbl[loop2];
{ col = Intersection of numerous cos waves }
asm
mov di,where { di is killed elsewhere, so we need to restore it}
mov al,col
mov es:[di],al { Place col at ES:DI ... sequential across the screen}
end;
where:=where+1; { Inc the place to put the pixel }
tmov1:=tmov1+4;
tmov2:=tmov2+3; { Arb numbers ... replace to zoom in/out }
END;
tmov3:=tmov3+4;
tmov4:=tmov4+5; { Arb numbers ... replace to zoom in/out }
END;
END;


{--------------------------------------------------------------------------}
Procedure MovePlasma;
{ This procedure moves the plasma left/right/up/down }
BEGIN
mov1:=mov1-4;
mov3:=mov3+4;
mov1:=mov1+random (1);
mov2:=mov2-random (2);
mov3:=mov3+random (1);
mov4:=mov4-random (2); { Movement along the plasma + noise}
END;

{--------------------------------------------------------------------------}
procedure WaitRetrace; assembler;
{ This waits for a vertical retrace to reduce snow on the screen }
label
l1, l2;
asm
mov dx,3DAh
l1:
in al,dx
test al,8
jnz l1
l2:
in al,dx
test al,8
jz l2
end;

{--------------------------------------------------------------------------}
Procedure fadeupone (stage:integer);
{ This procedure fades up the pallette bob2 by one increment and sets the
onscreen pallette. Colors are increased proportionally, do that all colors
reach their destonation at the same time }
VAR loop1:integer;
temp:rgbtype;
BEGIN
if not effect then move (bob[0],temp,3);
move (bob[1],bob[0],765);
if effect then move (biiiigpallette[start],bob[255],3) else
move (temp,bob[255],3);
start:=start+1;
if start=6657 then start:=0;
{ Rotate the pallette }

for loop1:=0 to 255 do BEGIN
bob2[loop1].r:=integer(bob[loop1].r*stage div 64);
bob2[loop1].g:=integer(bob[loop1].g*stage div 64);
bob2[loop1].b:=integer(bob[loop1].b*stage div 64);
END; { Fade up the pallette }
setallpal (bob2);
END;


{--------------------------------------------------------------------------}
Procedure Shiftpallette;
{ This rotates the pallette, and introduces new colors if the psychadelic
effect has been chosen }
VAR loop1:integer;
temp:rgbtype;
BEGIN
if not effect then move (bob2[0],temp,3);
move (bob2[1],bob2[0],765);
if effect then move (biiiigpallette[start],bob2[255],3) else
move (temp,bob2[255],3);
start:=start+1;
if start=6657 then start:=0;
setallpal (bob2);
END;


{--------------------------------------------------------------------------}
Procedure Play;
VAR loop1:integer;
BEGIN
start:=256;
for loop1:=1 to 64 do BEGIN
fadeupone(loop1);
drawplasma;
moveplasma;
END; { Fade up the plasma }
while keypressed do readkey;
Repeat
shiftpallette;
drawplasma;
moveplasma;
Until keypressed; { Do the plasma }
move (bob2,bob,768);
for loop1:=1 to 64 do BEGIN
fadeupone(64-loop1);
drawplasma;
moveplasma;
END; { fade down the plasma }
while keypressed do readkey;
END;

BEGIN
clrscr;
writeln ('Hi there ... here is a tut on plasmas! (By popular demand). The');
writeln ('program will ask you weather you want the Psychadelic effect, in');
writeln ('which the pallette does strange things (otherwise the pallette');
writeln ('remains constant), and it will ask weather you want a background');
writeln ('(a static pic behind the plasma). Try them both!');
writeln;
writeln ('The thing about plasmas is that they are very easy to change/modify');
writeln ('and this one is no exception .. you can even change the background');
writeln ('with minimum hassle. Try adding and deleting things, you will be');
writeln ('surprised by the results!');
writeln;
writeln ('This is by no means the only way to do plasmas, and there are other');
writeln ('sample programs out there. Have fun with this one though! ;-)');
writeln;
writeln;
init;
play;
asm
mov ax,0003h
int 10h
end;
Writeln ('All done. This concludes the fifteenth sample program in the ASPHYXIA');
Writeln ('Training series. You may reach DENTHOR under the names of GRANT');
Writeln ('SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS.I also occasinally');
Writeln ('RSAProg, comp.lang.pascal and comp.sys.ibm.pc.demos. E-mail me at :');
Writeln (' denthor@beastie.cs.und.ac.za');
Writeln ('The numbers are available in the main text. You may also write to me at:');
Writeln (' Grant Smith');
Writeln (' P.O. Box 270');
Writeln (' Kloof');
Writeln (' 3640');
Writeln (' Natal');
Writeln (' South Africa');
Writeln ('I hope to hear from you soon!');
Writeln; Writeln;
Write ('Hit any key to exit ...');
readkey;
END.

BKG.DAT

00000000000000000000000000000000000000000000000000000000000000000000000000000000 
00099000000000000000000000000090000000000000000000000000000000009000000000000000
00900900000000000000000000000090000000000000000000000000000000000000000000000000
09000090000099999900999999000090999900009000000900900000090000099000000099990900
90000009000900000000900000900099000090009000000900090000900000009000000900009900
90000009009000000000900000090090000009009000000900009009000000009000009000000900
90000009000900000000900000090090000009009000000900000990000000009000009000000900
99999999000099990000900000090090000009009000000900000990000000009000009000000900
90000009000000009000900000090090000009009000000900000990000000009000009000000900
90000009000000000900900000090090000009009000000900009009000000009000009000000900
90000009000000009000900000900090000009000900000900090000900000009000000900009900
90000009009999990000999999000090000009000099999900900000090000099900000099990900
00000000000000000000900000000000000000000000000900000000000000000000000000000000
00000000000000000000900000000000000000000000000900000000000000000000000000000000
00000000000000000000900000000000000000000000000900000000000000000000000000000000
00000000000000000000900000000000000000000000000900000000000000000000000000000000
00000000000000000000900000000000000000009000009000000000000000000000000000000000
00000000000000000000900000000000000000000999990000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
66666666660006660000000000000000660000000000000000006660000000066600000660000000
69999999996006960000000000000006996000000006666666666960000000069600006996000000
69666666669606960000000000000069669600000069999999996996000000699600069669600000
69600000006966960000000000000696006960000696666666666999600006999600696006960000
69600000000696960000000000006960000696006996000000006969960069969606960000696000
69600000000696960000000000069600000069606960000000006966960069669669600000069600
69600000000696960000000000696000000006969600000000006966996699669696000000006960
69600000000696960000000000696000000006969600000000006960699996069696000000006960
69600000000696960000000000696000000006966960000000006960069960069696000000006960
69600000000696960000000000696000000006966996000000006960066660069696000000006960
69600000000696960000000000696000000006960696666600006960000000069696000000006960
69600000006966960000000000696000000006960069999960006960000000069696000000006960
69666666669606960000000000696666666666960006666696006960000000069696666666666960
69999999996006960000000000699999999999960000000699606960000000069699999999999960
69666666660006960000000000696666666666960000000069606960000000069696666666666960
69600000000006960000000000696000000006960000000006966960000000069696000000006960
69600000000006960000000000696000000006960000000006966960000000069696000000006960
69600000000006960000000000696000000006960000000069606960000000069696000000006960
69600000000006960000000000696000000006960000000699606960000000069696000000006960
69600000000006966666666666696000000006966666666696006960000000069696000000006960
69600000000006999999999999696000000006969999999996006960000000069696000000006960
66600000000006666666666666666000000006666666666660006660000000066666000000006660
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000009999009000900000099990099999090009099999090009009990099990000000000000
00000000009000900909000000090009090000099009000900090009090009090009000000000000
00000000009099000090000000090009099900090909000900099999090009099990000000000000
00000000009000900090000000090009090000090099000900090009090009090090000000000000
00000000009999000090000000099990099999090009000900090009009990090009000000000000

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT