Category : C Source Code
Archive   : TCBBALL.ZIP
Filename : BBALL.C
Output of file : BBALL.C contained in archive : TCBBALL.ZIP
/* BBALL.C is a translation of the BeachBall program featured in
the March issue of BYTE Magazine, written by Bruce Holloway.
This translation compiles under Turbo C, Version 1.5, and uses
the graphics functions. It should run with an EGA or VGA or
Hercules adapter. It has a bug in the timing routine when using
an 80287 on my Heathkit H-248, and it may act the same on other
80287-augmented machines. The timing routine works fine when
the 80287 is disabled with 87=NO in the environment string,
but of course it takes forever to draw the ball that way.
I'd appreciate any ideas on the bug. Maybe it's in the EMU.LIB
or in the time() routine (although I've substituted more generic
time() routines and it still happens. I think it's EMU.LIB)
translation by:
Rick Martin
Englewood, Colorado
*/
#include
#include
#include
#include
#include
#include
#include
/* special colors for r_palette */
#define r_black 0
#define r_blue 1
#define r_green 2
#define r_cyan 3
#define r_red 4
#define r_purple 5
#define r_brown 6
#define r_amber 7
#define r_gray 8
#define r_lt_blue 9
#define r_lt_green 10
#define r_lt_cyan 11
#define r_lt_red 12
#define r_lt_purple 13
#define r_magenta 13
#define r_lt_yellow 14
#define r_yellow 14
#define r_white 15
struct palettetype r_palette;
void rick_palette(void);
time_t start,end;
struct palettetype r_palette;
struct palettetype ball_palette;
float pi;
int colors[]={3,6,10,13,6,3,10,13,6,3,13,10},d[]={640,350,1},i,k;
int x,y,x_min,x_max,y_min,y_max;
unsigned short random;
int g_error,g_mode,g_driver,height,width;
long pixel_count;
int incomplete;
void main()
{
float a,b,c,l0,l1,l2,ln,ln1,n0,n1,n2,p,q,s,t,r=128.0,v[12][3];
void intro_page(void);
void last_page(void);
pixel_count=0L;
incomplete=0;
registerbgidriver(EGAVGA_driver);
registerbgidriver(Herc_driver);
registerbgidriver(CGA_driver);
registerbgifont(triplex_font);
registerbgifont(sansserif_font);
registerbgifont(small_font);
detectgraph(&g_driver,&g_mode);
if(g_driver==EGA){height=350;width=640;}
if(g_driver==VGA){height=480;width=640;d[1]=480;}
if(g_driver==HERCMONO){height=348;width=720;d[1]=348;d[0]=720;}
initgraph(&g_driver,&g_mode,"");
g_error=graphresult();
if(g_error<0)
{
printf("initgraph error: %s.\n",grapherrormsg(g_error));
exit(1);
}
if(g_driver==EGA)a=1.3;
if(g_driver==VGA)a=1.0;
if(g_driver==HERCMONO)a=1.47;
if(g_driver==VGA)r=175.0;
b=.5*(d[0]-1);
c=.5*(d[1]-1);
l0=-1/sqrt(3.0);
l1=l0;
l2=-l0;
pi=4.0*atan(1.0);
v[0][0]=0;
v[0][1]=0;
v[0][2]=1;
s=sqrt(5.0);
for(i=1;i<11;i++){
p=pi*i/5;
v[i][0]=2*cos(p)/s;
v[i][1]=2*sin(p)/s;
v[i][2]=(1.0-i%2*2)/s;
}
v[11][0]=0;
v[11][1]=0;
v[11][2]=-1;
y_max=c+r;
y_min=2*c-y_max;
/* change the EGA palette to something better, I hate cyan */
getpalette(&r_palette);
r_palette.colors[0]=0;
r_palette.colors[1]=1;
r_palette.colors[2]=16;
r_palette.colors[3]=3;
r_palette.colors[4]=4;
r_palette.colors[5]=13;
r_palette.colors[6]=28;
r_palette.colors[7]=38;
r_palette.colors[8]=7;
r_palette.colors[9]=57;
r_palette.colors[10]=14;
r_palette.colors[11]=31;
r_palette.colors[12]=36;
r_palette.colors[13]=61;
r_palette.colors[14]=62;
r_palette.colors[15]=63;
setallpalette(&r_palette);
intro_page();
getpalette(&ball_palette);
ball_palette.colors[0]=0;
ball_palette.colors[1]=8;
ball_palette.colors[2]=1;
ball_palette.colors[3]=9;
ball_palette.colors[4]=16;
ball_palette.colors[5]=2;
ball_palette.colors[6]=18;
ball_palette.colors[7]=63;
ball_palette.colors[8]=32;
ball_palette.colors[9]=4;
ball_palette.colors[10]=36;
ball_palette.colors[11]=48;
ball_palette.colors[12]=6;
ball_palette.colors[13]=54;
ball_palette.colors[14]=7;
ball_palette.colors[15]=63;
setallpalette(&ball_palette);
time(&start);
for(y=y_min;y<=y_max;y++){
s=(y-c);
n1=s/r;
ln1=l1*n1;
s=(r*r-s*s);
x_max=b+a*sqrt(s);
x_min=2*b-x_max;
for(x=x_min;x<=x_max;x++){
t=(x-b)/a;
n0=t/r;
t=sqrt(s-t*t);
n2=t/r;
ln=l0*n0+ln1+l2*n2;
if(ln<0)ln=0;
t=ln*n2;
t+=t-l2;
t*=t*t;
t*=t*t;
t*=t*t;
for(i=0,p=0;i<11;i++)
if(p<(q=n0*v[i][0]+n1*v[i][1]+n2*v[i][2])){
p=q;
k=colors[i];
}
i=k-2.5+2.5*ln+t+(random=37*random+1)/65536.0;
if(i
putpixel(x,y,i);
pixel_count+=1;
}
if(kbhit()){incomplete=1;break;}
}
time(&end);
last_page();
closegraph();
restorecrtmode();
}
void intro_page(void)
{
settextjustify(CENTER_TEXT,TOP_TEXT);
if(g_driver==EGA)setusercharsize(5,4,5,4);
if(g_driver==VGA)setusercharsize(5,4,17,10);
if(g_driver==HERCMONO)setusercharsize(14,10,5,4);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,0);
if(g_driver!=HERCMONO)setcolor(r_amber);
outtextxy((int)(width/2),(int)(.03*height),"Beach Ball");
if(g_driver==EGA)setusercharsize(3,4,3,4);
if(g_driver==VGA)setusercharsize(3,4,1,1);
if(g_driver==HERCMONO)setusercharsize(84,100,3,4);
settextstyle(SANS_SERIF_FONT,HORIZ_DIR,0);
if(g_driver!=HERCMONO)setcolor(r_red);
outtextxy((int)(width/2),(int)(0.17*height),"rewritten for Turbo C V1.5 by Rick Martin");
settextjustify(LEFT_TEXT,TOP_TEXT);
if(g_driver==EGA)setusercharsize(65,100,3,5);
if(g_driver==VGA)setusercharsize(65,100,82,100);
if(g_driver==HERCMONO)setusercharsize(73,100,3,5);
settextstyle(SANS_SERIF_FONT,HORIZ_DIR,0);
if(g_driver!=HERCMONO)setcolor(r_lt_green);
outtextxy((int)(0.01*width),(int)(0.28*height),"BALL.EXE is a floating point benchmark program written by Bruce");
outtextxy((int)(0.01*width),(int)(0.34*height),"Holloway, appearing in the March 1988 issue of BYTE Magazine.");
outtextxy((int)(0.01*width),(int)(0.40*height),"It draws a very realistic mathematically-created 3-D beach ball");
outtextxy((int)(0.01*width),(int)(0.46*height),"on the screen, using the Phong shading technique to determine");
outtextxy((int)(0.01*width),(int)(0.52*height),"each pixel value. The program uses floating point mathematics");
outtextxy((int)(0.01*width),(int)(0.58*height),"and trigonometric functions extensively, and is thus an");
outtextxy((int)(0.01*width),(int)(0.64*height),"interesting floating point benchmark. After the ball is drawn");
outtextxy((int)(0.01*width),(int)(0.70*height),"(which takes 51.7 minutes on a standard 6 MHz IBM AT), press");
outtextxy((int)(0.01*width),(int)(0.76*height),"any key, and a final screen will show the time your computer");
outtextxy((int)(0.01*width),(int)(0.82*height),"took along with some other machines' times. You may abort the");
outtextxy(0.01*width,0.88*height,"display generation once it has started by hitting any key.");
if(g_driver!=HERCMONO)setcolor(r_lt_blue);
settextjustify(CENTER_TEXT,BOTTOM_TEXT);
settextstyle(SMALL_FONT,HORIZ_DIR,4);
outtextxy((int)(width/2),(int)(0.99*height),"Press any key to start . .");
getch();
clearviewport();
}
void last_page(void)
{
char elapsed_string[10];
char pixel_string[10];
ltoa((long)difftime(end,start),elapsed_string,10);
ltoa(pixel_count,pixel_string,10);
getch();
clearviewport();
setallpalette(&r_palette);
settextjustify(LEFT_TEXT,TOP_TEXT);
if(g_driver==HERCMONO)setusercharsize(1,1,1,2);
if(g_driver==EGA)setusercharsize(88,100,1,2);
if(g_driver==VGA)setusercharsize(88,100,68,100);
settextstyle(SANS_SERIF_FONT,HORIZ_DIR,0);
if(g_driver!=HERCMONO)setcolor(r_gray);
outtext(" Your computer displayed ");
outtext(pixel_string);
outtext(" pixels in");
if(g_driver==HERCMONO)setusercharsize(22,10,15,10);
if(g_driver==EGA)setusercharsize(195,100,15,10);
if(g_driver==VGA)setusercharsize(195,100,205,100);
settextjustify(CENTER_TEXT,TOP_TEXT);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,0);
if(g_driver!=HERCMONO)setcolor(r_amber);
line(0.35*width,0.066*height,0.65*width,0.066*height);
line(0.35*width,0.265*height,0.65*width,0.265*height);
line(0.35*width,0.066*height,0.35*width,0.265*height);
line(0.65*width,0.066*height,0.65*width,0.265*height);
if(g_driver!=HERCMONO)setcolor(r_red);
moveto(0.15*width,0.35*height);
lineto(0.0,0.35*height);
lineto(0.0,0.99*height);
lineto(0.99*width,0.99*height);
lineto(0.99*width,0.35*height);
lineto(0.85*width,0.35*height);
if(g_driver!=HERCMONO)setcolor(r_amber);
outtextxy(width/2,0.06*height,elapsed_string);
if(g_driver==HERCMONO)setusercharsize(1,1,1,2);
if(g_driver==EGA)setusercharsize(88,100,1,2);
if(g_driver==VGA)setusercharsize(88,100,68,100);
settextstyle(SANS_SERIF_FONT,HORIZ_DIR,0);
outtextxy(width/2,0.2*height,"seconds");
if(g_driver==HERCMONO)setusercharsize(1,1,1,1);
if(g_driver==EGA)setusercharsize(88,100,1,1);
if(g_driver==VGA)setusercharsize(88,100,68,50);
settextstyle(SANS_SERIF_FONT,HORIZ_DIR,0);
if(g_driver!=HERCMONO)setcolor(r_red);
moveto(width/2,0.3*height);
outtext("TIMES FOR COMPLETE DISPLAY");
if(g_driver!=HERCMONO)setcolor(r_lt_blue);
moveto(0.82*width,0.3*height);
outtext("*");
if(g_driver==HERCMONO)setusercharsize(1,1,1,1);
if(g_driver==EGA)setusercharsize(88,100,1,1);
if(g_driver==VGA)setusercharsize(88,100,138,100);
settextstyle(SMALL_FONT,HORIZ_DIR,0);
outtextxy(width/2,0.4*height,"*Comparison times are for 640x350 EGA. Multiply by 1.37 to compare with 640x480 VGA or EVA/480");
if(g_driver==HERCMONO)setusercharsize(1,2,1,2);
if(g_driver==EGA)setusercharsize(88,200,1,2);
if(g_driver==VGA)setusercharsize(88,200,68,100);
settextstyle(SANS_SERIF_FONT,HORIZ_DIR,0);
if(g_driver!=HERCMONO)setcolor(r_green);
outtextxy(width*0.25,0.47*height,"Computer");
outtextxy(width*0.75,0.47*height,"Time (seconds)");
if(g_driver==HERCMONO)setusercharsize(2,1,18,10);
if(g_driver==EGA)setusercharsize(177,100,18,10);
if(g_driver==VGA)setusercharsize(177,100,246,100);
settextstyle(SMALL_FONT,HORIZ_DIR,0);
settextjustify(LEFT_TEXT,TOP_TEXT);
if(g_driver!=HERCMONO)setcolor(r_lt_green);
outtextxy(0.1*width,0.55*height,"20 Mhz Compaq 386");
outtextxy(0.1*width,0.60*height,"20 Mhz Compaq 386 w/80387");
outtextxy(0.1*width,0.65*height,"20 Mhz Compaq 386 w/Weitek 1167");
outtextxy(0.1*width,0.70*height,"8 Mhz Heath H-286");
outtextxy(0.1*width,0.75*height,"8 Mhz Heath H-286 w/80287");
outtextxy(0.1*width,0.80*height,"6 Mhz IBM AT");
outtextxy(0.1*width,0.85*height,"YOUR COMPUTER");
settextjustify(RIGHT_TEXT,TOP_TEXT);
outtextxy(0.77*width,0.55*height,"480");
if(g_driver!=HERCMONO)setcolor(r_lt_purple);outtextxy(0.80*width,0.55*height,"*");if(g_driver!=HERCMONO)setcolor(r_lt_green);
outtextxy(0.77*width,0.60*height,"28");
if(g_driver!=HERCMONO)setcolor(r_lt_purple);outtextxy(0.80*width,0.60*height,"*");if(g_driver!=HERCMONO)setcolor(r_lt_green);
outtextxy(0.77*width,0.65*height,"10");
if(g_driver!=HERCMONO)setcolor(r_lt_purple);outtextxy(0.80*width,0.65*height,"*");if(g_driver!=HERCMONO)setcolor(r_lt_green);
outtextxy(0.77*width,0.70*height,"1769");
if(g_driver!=HERCMONO)setcolor(r_blue);outtextxy(0.80*width,0.70*height,"*");if(g_driver!=HERCMONO)setcolor(r_lt_green);
outtextxy(0.77*width,0.75*height,"429");
if(g_driver!=HERCMONO)setcolor(r_blue);outtextxy(0.80*width,0.75*height,"*");if(g_driver!=HERCMONO)setcolor(r_lt_green);
outtextxy(0.77*width,0.80*height,"3102");
if(g_driver!=HERCMONO)setcolor(r_blue);outtextxy(0.80*width,0.80*height,"*");if(g_driver!=HERCMONO)setcolor(r_lt_green);
if(!incomplete){outtextxy(0.77*width,0.85*height,elapsed_string);}
if(incomplete){outtextxy(0.77*width,0.85*height,"PARTIAL DISPLAY");}
if(g_driver!=HERCMONO)setcolor(r_blue);outtextxy(0.80*width,0.85*height,"*");if(g_driver!=HERCMONO)setcolor(r_lt_green);
if(g_driver!=HERCMONO)setcolor(r_lt_purple);settextjustify(CENTER_TEXT,TOP_TEXT);
if(g_driver==HERCMONO)setusercharsize(2,1,10,10);
if(g_driver==EGA)setusercharsize(177,100,10,10);
if(g_driver==VGA)setusercharsize(177,100,136,100);
settextstyle(SMALL_FONT,HORIZ_DIR,0);
outtextxy(width/2,0.90*height,"* time according to article");
if(g_driver!=HERCMONO)setcolor(r_blue);outtextxy(0.415*width,0.93*height,"* time measured");
getch();
clearviewport();
}
(long)difftime(end,start),elaps
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/