home *** CD-ROM | disk | FTP | other *** search
- /*
- * balls2.c - Attempt to draw balls in VGA256 mode
- *
- * Uses BGI interface
- *
- * Adapted by: Scott J. Walter (GEnie: S.Walter4)
- *
- */
-
- /* INCLUDES */
-
- #include <stdio.h>
- #include <dos.h>
- #include <math.h>
- #include <graphics.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <alloc.h>
- #include <bios.h>
- #include <time.h>
-
-
-
- /* DEFINES */
-
- #define DIM 3 /* number of dimensions */
- #define TRUE 1
- #define FALSE 0
-
- typedef unsigned char UBYTE;
-
- typedef double VECTOR [DIM];
-
- typedef struct {
- UBYTE Rvalue;
- UBYTE Gvalue;
- UBYTE Bvalue;
- } ColorValue;
-
-
-
- /* PROTOTYPES */
-
- int huge DetectVGA256(void);
- void VGASetAllPalette(UBYTE far *pal);
- void Hsi2Rgb(float H, float S, float I, ColorValue *C);
- void normalize (VECTOR this_vec);
- double dot_prod (VECTOR vec1, VECTOR vec2);
- void put_atom(int R, int index, int xc, int yc, VECTOR l_source);
-
-
-
-
-
-
- void put_atom(int R, int index, int xc, int yc, VECTOR l_source)
- {
- VECTOR s_point;
- int R2, color = 0;
- double x,y,z,r,intensity;
-
-
- normalize(l_source); /* normalize the light source */
- R2=R*R; /* only calculate R*R once */
- for (x=-R;x<=+R;x=x+1) /* scan an area 2R x 2R */
- {
- for (y=-R;y<=+R;y=y+1)
- {
- r=(x*x)+(y*y); /* check that the pixel is within a */
- if (r <= R2) /* circle of radius R */
- {
- z=sqrt((R2)-r); /* calculate the altitude of the point */
- s_point[0]= x; /* set the normal surface vector to the */
- s_point[1]= y; /* coordinates of the point */
- s_point[2]= z;
-
- intensity = random(100);
- intensity /= 100;
-
- intensity += 64 * dot_prod(s_point,l_source)/R;
-
- color = (int)intensity;
-
- color = color<0 ? 0 : (color> 63 ? 63 : color);
-
- putpixel(x+xc,y+yc,index*64 + color);
- }
- }
- }
- }
-
-
-
- /*
- * Normalize a vector to unit magnitude. Calculate the magnitude as:
- *
- * magnitude = sqrt ( x^2 + y^2 + z^2 )
- *
- * Normalize the vector by dividing each coordinate by the magnitude.
- * FOR loops are used to maintain generality--any dimension vector may
- * be normalized by changing DIM.
- */
- void normalize (VECTOR this_vec)
- {
- double mag;
- int count;
-
-
- mag = 0.0;
-
- for (count = 0; count < DIM; count++)
- mag = mag + (this_vec [count] * this_vec [count]);
-
- mag = sqrt(mag);
-
- for (count = 0; count < DIM; count++)
- this_vec [count] = this_vec [count]/mag;
- }
-
-
-
- /* Calculate the cosine of the angle between two vectors.
- *
- * dot product = (x1 * x2) + (y1 * y2) + (z1 * z2)
- */
- double dot_prod (VECTOR vec1, VECTOR vec2)
- {
- double COSINE;
- int count;
-
-
- COSINE = 0.0;
-
- for (count = 0; count < DIM; count++)
- COSINE += vec1 [count] * vec2 [count];
-
- return (COSINE);
- }
-
-
-
- void VGASetAllPalette(pal)
- UBYTE far *pal;
- {
- struct REGPACK r;
-
-
- r.r_ax = 0x1012;
- r.r_bx = 0x0000;
- r.r_cx = 0x0100;
- r.r_es = FP_SEG(pal);
- r.r_dx = FP_OFF(pal);
-
- intr(0x10, &r);
- }
-
-
-
- void Hsi2Rgb(float H, float S, float I, ColorValue *C)
- {
- float T, Rv, Gv, Bv;
- float Pi = 3.14159265358979;
-
-
- if(H<0.0)
- H = 1.0 + H;
-
- if(H>1.0)
- H = H - 1.0;
-
- T = 2.0 * Pi * H;
-
- Rv = 1 + S * sin(T - 2 * Pi / 3);
- Gv = 1 + S * sin(T);
- Bv = 1 + S * sin(T + 2 * Pi / 3);
-
- T = 63.999 * I / 2;
-
- C->Rvalue = (UBYTE)(Rv * T);
- C->Gvalue = (UBYTE)(Gv * T);
- C->Bvalue = (UBYTE)(Bv * T);
- }
-
-
-
- int huge DetectVGA256()
- {
- int gdriver, gmode;
-
-
- detectgraph(&gdriver, &gmode);
-
- if((gdriver==VGA)||(gdriver==MCGA))
- return 0; /* Default video mode = 0 */
- else
- return grError; /* Couldn't detect hardware */
- }
-
-
-
-
- /* MAIN */
-
- void main()
- {
- int Y, Z, ErrorCode, Driver = DETECT, Mode;
- int radius = 40;
- VECTOR light = { -2.0, -2.0, 3.0 }; /* light source from upper left */
- UBYTE far *pal;
- float off, hue;
- ColorValue C;
-
-
- installuserdriver("VGA256", DetectVGA256);
-
- initgraph(&Driver, &Mode, "");
-
- ErrorCode = graphresult();
-
- if(ErrorCode!=grOk)
- {
- printf("Error: %s\n", grapherrormsg(ErrorCode));
- exit(1);
- }
-
- randomize();
-
- pal = (UBYTE far *)farmalloc(768);
-
- for(Y=0;Y<5;Y++)
- for(Z=0;Z<64;Z++)
- {
- Hsi2Rgb(0.25+(float)Y/5.0, 1.0, (float)Z/64.0, &C);
-
- *(pal+Y*192+Z*3+0) = C.Rvalue;
- *(pal+Y*192+Z*3+1) = C.Gvalue;
- *(pal+Y*192+Z*3+2) = C.Bvalue;
- }
-
- VGASetAllPalette(pal);
-
- for(Y=0;Y<2;Y++)
- for(Z=0;Z<2;Z++)
- put_atom(radius, Y*2+Z, 80+160*Z, 50+100*Y, light);
-
- off = 0.30;
-
- do
- {
- for(Y=0;Y<5;Y++)
- for(Z=0;Z<64;Z++)
- {
- hue = off+(float)Y/5.0;
- if(hue>1.0)
- hue = hue - 1.0;
-
- Hsi2Rgb(hue, 1.0, (float)Z/64.0, &C);
-
- *(pal+Y*192+Z*3+0) = C.Rvalue;
- *(pal+Y*192+Z*3+1) = C.Gvalue;
- *(pal+Y*192+Z*3+2) = C.Bvalue;
- }
-
- VGASetAllPalette(pal);
-
- off += 0.05;
- if(off>1.0)
- off = off - 1.0;
- } while(!bioskey(1));
-
- getch();
-
- farfree((void far *)pal);
-
- closegraph();
- }
-