home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
GRAPHICS
/
PLASMA3.ZIP
/
PLASMA.C
< prev
next >
Wrap
Text File
|
1994-02-05
|
14KB
|
496 lines
/*
Plasma by Jan Mller & Erik Hansen. (& rewrite by Karl Weller)
It was compiled in Borland c++, in ANSI mode, using the HUGE memory model.
Feel free to use it as you desire, you may even name it after your
grandmother. We don't care.
The reason why we made it? Well... First of all we wanted to make some
plasma, just for fun. But when we had finished it turned out to be much
faster than the plasma we have seen in intros, demos etc...
Normally the color-cells are 2x4 4x4 or even larger, the 2x4 cell-plasma
was awfully slow, bot ours ain't, even though it is 2x2 cells.
Well how can that be??? ^^^^^^^^^
Our secret lies in the plasma-calculation!
(I assume you have guessed that part already)
We simply calculate as much as possible before we start showing the goddies.
The table 'Tab1' is a simple table (320x200 yields 64k) with the distance
from (x,y) to the center (rounded off to char by simple overflow). The second
table 'Tab2' is similar to 'Tab1', except we molested it with sine.
In the mainloop we calculate a body (160x100) by accessing the two tables
with different pairs of (x,y) and add them.
(see for yourself in 'CalculateBody')
And KaPoW. We have the fastest plasma...
(i.e. the fastest we have ever seen.(on a 486)) If I am not correct then please notify me.
If you have any questions, comments or whips, then we would be happy to answer.
Contact us trough E-Mail:
fwiffo@daimi.aau.dk
or
martino@daimi.aau.dk
(If you can optimize it (e.g. write it in asm) we would be very interested
to see the results!)
Modified by: Karl Weller CI$ 74620,2112
to work with all VGA screens and eliminate startup calculations!
Final version uses VGA 320x256 x 4 pages (kind of like MODE-X)
02-04-94 (KAW) Final tweaking of program! finish vga page swapping & got
palette cycling working again (faster)!
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <conio.h>
#include <math.h>
#include <fcntl.h>
#include <io.h>
#include <dos.h>
#define uchar unsigned char
#define ulong unsigned long
#define uint unsigned int
#define box_w 160
#define box_h 100
double pi=3.141592654;
//-------------------------------------------------
uchar far *body; // buffer for the bitmap body
//char far *body = (char far *)0xa0000000;
extern uchar tab1[]; // table one for thr plasma
extern uchar tab2[]; // table two for the plasma
extern unsigned char far pal[]; // palette
unsigned char pal2[800];
//-------------------------------------------------
void SetMode(char mode)
{
_asm {
mov ah,0x00
mov al,mode
int 0x10
}
}
char GetMode(void )
{
char mode;
_asm {
mov ah,0x0f
int 0x10
mov mode,al
}
return (mode);
}
void waitvrt(void )
{
_asm {
mov dx,0x3da ; wait for retrace
bra1:
in al,dx
and al,8
jnz bra1
bra2:
in al,dx
and al,8
jz bra2
}
}
void setpal(void) {
unsigned int sg,of;
char far *p = (char far *)pal2;
sg = FP_SEG(p);
of = FP_OFF(p);
_asm {
push ds
push es
push si
push di
pushf
cld
mov cx,sg
mov si,of
mov dx,03C8h ;port address of DAC register
mov bx,0 ;first register to update
mov ax,bx
cli
out dx,al ;start with this DAC
inc dx ;port address where RGB info is written
mov ds,cx
mov cx,256 ;number of DAC registers to update
setdacloop:
lodsb
out dx,al
lodsb
out dx,al
lodsb
out dx,al
loop setdacloop
sti
popf
pop di
pop si
pop es
pop ds
}
}
static double r=1.0/6.0*3.141592654,g=3.0/6.0*3.141592654,b=5.0/6.0*3.141592654;
int palcnt = 1;
int pald = 1;
void CalculateColors()
{
int i=0,j,k,l;
#if 0
double u,v;
while(i<256)
{
u=2*pi/256*i;
//#define mycol(u,a) (max(0.0,cos((u)+(a))))*63 // try this line instead
#define mycol(u,a) (cos((u)+(a))+1)*31
pal[i*3] = mycol(u,r);
pal[i*3+1] = mycol(u,g);
pal[i*3+2] = mycol(u,b);
/*
SetPal(i,mycol(u,r),mycol(u,g),mycol(u,b));
*/
i++;
}
/*
waitvrt();
setpal();
*/
r+=0.05;
g-=0.05;
b+=0.1;
#else
memcpy(pal2,pal+(palcnt*768),768);
palcnt += pald;
if (palcnt < 1) {
pald = 1;
palcnt = 2;
}
else if (palcnt >= 49) {
pald = -1;
palcnt = 48;
}
#endif
}
void CalculateBody(unsigned x1,unsigned y1,unsigned x2,unsigned y2,unsigned x3,unsigned y3,unsigned x4,unsigned y4,unsigned roll)
{
unsigned int i=0,j,x=0,t1,t2,t3,t4;
uchar b,c;
while(i<box_h) {
j=0;
t1 = 320*(i+y1)+x1;
t2 = 320*(i+y2)+x2;
t3 = 320*(i+y3)+x3;
t4 = 320*(i+y4)+x4;
while(j<box_w) { // this is the heart of the plasma
b= tab1[t1++]+roll+tab2[t2++]+tab2[t3++]+tab2[t4++];
c= tab1[t1++]+roll+tab2[t2++]+tab2[t3++]+tab2[t4++];
body[x] = body[x+80] = body[x+16000] = body[x+16080] = b;
body[x+32000] = body[x+48000] = body[x+32080] = body[x+48080] = c;
j+=2;
x++;
}
x+=80;
i++;
}
}
void outdisp(int page)
{
unsigned char far *addr = (unsigned char far*) (0xA0000000+(0x8000000*page) );
unsigned int sg,of,ad;
sg = FP_SEG(body);
of = FP_OFF(body);
ad = FP_SEG(addr);
outp(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
outp(0x3C5,1);
_asm {
push ds
push es
push si
push di
mov cx,sg
mov dx,of
mov ax,ad ; destination screen address.
mov es,ax ; into ES
xor ax,ax
mov di,ax
mov si,dx
mov ds,cx
mov cx,8000
rep movsw ; move image to screen
pop di
pop si
pop es
pop ds
}
// memcpy(addr,body,16000);
outp(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
outp(0x3C5,2);
_asm {
push ds
push es
push si
push di
mov cx,sg
mov dx,of
add dx,16000
mov ax,ad ; destination screen address.
mov es,ax ; into ES
xor ax,ax
mov di,ax
mov si,dx
mov ds,cx
mov cx,8000
rep movsw ; move image to screen
pop di
pop si
pop es
pop ds
}
// memcpy(addr,body+(unsigned)16000,16000);
outp(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
outp(0x3C5,4);
_asm {
push ds
push es
push si
push di
mov cx,sg
mov dx,of
add dx,32000
mov ax,ad ; destination screen address.
mov es,ax ; into ES
xor ax,ax
mov di,ax
mov si,dx
mov ds,cx
mov cx,8000
rep movsw ; move image to screen
pop di
pop si
pop es
pop ds
}
// memcpy(addr,body+(unsigned)32000,16000);
outp(0x3C4, 2); /* point Sequence Controller to Map Mask reg. */
outp(0x3C5,8);
_asm {
push ds
push es
push si
push di
mov cx,sg
mov dx,of
add dx,48000
mov ax,ad ; destination screen address.
mov es,ax ; into ES
xor ax,ax
mov di,ax
mov si,dx
mov ds,cx
mov cx,8000
rep movsw ; move image to screen
pop di
pop si
pop es
pop ds
}
// memcpy(addr,body+(unsigned)48000,16000);
}
int _cdecl main(void)
{
double circle1=0,circle2=0,circle3=0,circle4=0,circle5=0,circle6=0,circle7=0,circle8=0;
unsigned int x1,y1,x2,y2,x3,y3,x4,y4,roll=0,bh,bw;
unsigned int fnd,j,i=0;
int which=1;
char oldmode;
oldmode=GetMode();
body = malloc((unsigned)65000);
memset(body,0,(unsigned int)65000);
SetMode(19);
_asm {
mov dx, 3CEh ; Tell the Graphics Controller
mov al, 5 ; to change the graphics mode
out dx, al ; (register 5) to use linear
inc dx ; addresses instead of seperating
in al, dx ; the odd and even addresses.
and al, 11101111b ;
out dx, al ;
dec dx ;
mov al, 6 ; Tell the Graphics Controller
out dx, al ; to change the misc. register
inc dx ; (register 6) to use linear
in al, dx ; addresses instead of seperating
and al, 11111101b ; the odd and even addresses.
out dx, al ;
mov dx, 3C4h ; Tell the Sequencer Controller
mov al, 4 ; to change the memory mode
out dx, al ; (register 4) to disable chain4
inc dx ; mode, and allow linear
in al, dx ; processing on a bitplane.
and al, 11110111b ;
or al, 4 ;
out dx, al ;
mov ax, 0A000h ; Clear the screen.
mov es, ax ;
xor di, di ;
mov ax, di ;
mov cx, 8000h ;
rep stosw ;
mov dx, 3D4h ; Tell the CRT Controller to
mov al, 14h ; change the underline location
out dx, al ; (register 14h) to turn off
inc dx ; the double word mode.
in al, dx ;
and al, 10111111b ;
out dx, al ;
dec dx ;
mov al, 17h ; Tell the CRT Controller to
out dx, al ; change the mode control
inc dx ; (register 17h) to switch
in al, dx ; to byte mode.
or al, 01000000b ;
out dx, al ;
}
bh = box_h/2;
bw = box_w/2;
while(1)
{
CalculateColors();
setpal();
circle1+=0.01416666666666;
circle2-=0.01666666666666;
circle3+=0.050;
circle4-=0.03333333333333;
circle5+=0.06666666666666;
circle6-=0.0250;
circle7+=0.05833333333333;
circle8-=0.00833333333333;
x2=(bw)+(bw)*sin(circle1);
y2=(bh)+(bh)*cos(circle2);
x1=(bw)+(bw)*cos(circle3);
y1=(bh)+(bh)*sin(circle4);
x3=(bw)+(bw)*cos(circle5);
y3=(bh)+(bh)*sin(circle6);
x4=(bw)+(bw)*cos(circle7);
y4=(bh)+(bh)*sin(circle8);
CalculateBody(x1,y1,x2,y2,x3,y3,x4,y4,roll+=5);
if (which++ % 2) {
outdisp(1);
_asm {
mov dx,0x3da ; wait for retrace
bra1:
in al,dx
and al,8
jnz bra1
bra2:
in al,dx
and al,8
jz bra2
mov dx,0x3d4
mov ax,0x800c
out dx,ax
}
// outpw(0x3D4, 0x800C); /* Flip to other page, */
}
else {
outdisp(0);
if (kbhit()) break;
_asm {
mov dx,0x3da ; wait for retrace
bra1a:
in al,dx
and al,8
jnz bra1a
bra2a:
in al,dx
and al,8
jz bra2a
mov dx,0x3d4
mov ax,0x0c
out dx,ax
}
// outpw(0x3D4, 0x0C); /* Flip to other page, */
}
}
while(kbhit()) getch();
free(body);
/************************************/
/* A Clean ending is a nice ending! */
/* (K.W.) */
/************************************/
memset(body,0,(unsigned)64000);
for(i=0;i<256;++i) {
if (kbhit()) break;
fnd=0;
for(j=0;j<771;++j) {
if (pal2[j]>=2) {
pal2[j]-=2;
++fnd;
}
}
waitvrt();
setpal(); /* fade the pal */
if (!fnd) break;
}
memset(pal2,0,771);
waitvrt();
setpal(); /* blank the pal */
waitvrt();
outpw(0x3D4, 0x0C);
outdisp(1); /* blank page 1 */
outpw(0x3D4, 0x800C);
outdisp(0); /* blank page 0 */
outpw(0x3D4, 0x0C);
SetMode(oldmode);
waitvrt();
return 0;
}