1 /*
2    GRAPHICS DEMO FOR Borland C++
3 
4    Copyright (c) 1987,88,91 Borland International. All rights reserved.
5 */
6 
7 /* Partially copyrighted (c) 1993-97 by Hartmut Schirmer */
8 
9 #ifdef __TINY__
10 #error BGIDEMO will not run in the tiny model.
11 #endif
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <math.h>
16 #include <string.h>
17 #include <stdarg.h>
18 #include "libbcc.h"
19 #include "bgiext.h"
20 #include "stdfun.h"
21 
22 #include "../rand.h"
23 #define Random(r) ((unsigned) (((RND() % (r)) + 1)))
24 #define Seed(s) SRND(s)
25 
26 #if defined(__MSDOS__) || defined(__WIN32__)
27 #define BGI_PATH "..\\..\\chr"
28 #else
29 #define BGI_PATH "../../chr"
30 #endif
31 
32 #define itoa(value,str,radix) sprintf((str),"%d",(value))
33 #define getch() getkey()
34 
35 #define ESC     0x1b                    /* Define the escape key        */
36 #ifndef TRUE
37 #  define TRUE  1                       /* Define some handy constants  */
38 #endif
39 #ifndef FALSE
40 #  define FALSE 0                       /* Define some handy constants  */
41 #endif
42 #ifndef PI
43 #  define PI    3.14159                 /* Define a value for PI        */
44 #endif
45 #define ON      1                       /* Define some handy constants  */
46 #define OFF     0                       /* Define some handy constants  */
47 
48 #define NFONTS 11
49 
50 char *Fonts[] = {
51   "DefaultFont",   "TriplexFont",   "SmallFont",
52   "SansSerifFont", "GothicFont", "ScriptFont", "SimplexFont", "TriplexScriptFont",
53   "ComplexFont", "EuropeanFont", "BoldFont"
54 };
55 
56 char *LineStyles[] = {
57   "SolidLn",  "DottedLn",  "CenterLn",  "DashedLn",  "UserBitLn"
58 };
59 
60 char *FillStyles[] = {
61   "EmptyFill",  "SolidFill",      "LineFill",      "LtSlashFill",
62   "SlashFill",  "BkSlashFill",    "LtBkSlashFill", "HatchFill",
63   "XHatchFill", "InterleaveFill", "WideDotFill",   "CloseDotFill"
64 };
65 
66 char *TextDirect[] = {
67   "HorizDir",  "VertDir"
68 };
69 
70 char *HorizJust[] = {
71   "LeftText",   "CenterText",   "RightText"
72 };
73 
74 char *VertJust[] = {
75   "BottomText",  "CenterText",  "TopText"
76 };
77 
78 struct PTS {
79   int x, y;
80 };      /* Structure to hold vertex points      */
81 
82 int    GraphDriver;             /* The Graphics device driver           */
83 int    GraphMode;               /* The Graphics mode value              */
84 double AspectRatio;             /* Aspect ratio of a pixel on the screen*/
85 int    MaxX, MaxY;              /* The maximum resolution of the screen */
86 int    MaxColors;               /* The maximum # of colors available    */
87 int    ErrorCode;               /* Reports any graphics errors          */
88 struct palettetype palette;             /* Used to read palette info    */
89 static char PauseMsg[] = "Esc aborts or press a key...";
90 static char StopMsg[]  = "ESC Aborts - Press a Key to stop";
91 
92 /*                                                                      */
93 /*      GPRINTF: Used like PRINTF except the output is sent to the      */
94 /*      screen in graphics mode at the specified co-ordinate.           */
95 /*                                                                      */
96 
gprintf(int * xloc,int * yloc,char * fmt,...)97 int gprintf( int *xloc, int *yloc, char *fmt, ... )
98 {
99   va_list  argptr;                      /* Argument list pointer        */
100   char str[140];                        /* Buffer to build sting into   */
101   int cnt;                              /* Result of SPRINTF for return */
102 
103   va_start( argptr, fmt );              /* Initialize va_ functions     */
104 
105   cnt = vsprintf( str, fmt, argptr );   /* prints string to buffer      */
106   outtextxy( *xloc, *yloc, str );       /* Send string in graphics mode */
107   *yloc += textheight( "H" ) + 2;       /* Advance to next line         */
108 
109   va_end( argptr );                     /* Close va_ functions          */
110 
111   return( cnt );                        /* Return the conversion count  */
112 
113 }
114 
115 /*                                                                      */
116 /*      CHANGETEXTSTYLE: similar to settextstyle, but checks for        */
117 /*      errors that might occur whil loading the font file.             */
118 /*                                                                      */
119 
changetextstyle(int font,int direction,int charsize)120 void changetextstyle(int font, int direction, int charsize)
121 {
122   int ErrorCode;
123 
124   graphresult();                        /* clear error code             */
125   settextstyle(font, direction, charsize);
126   ErrorCode = graphresult();            /* check result                 */
127   if( ErrorCode != grOk ){              /* if error occured             */
128 #if 0
129     closegraph();
130     printf(" Graphics System Error: %s\n", grapherrormsg( ErrorCode ) );
131     exit( 1 );
132 #else
133     settextstyle(DEFAULT_FONT, direction, charsize);
134 #endif
135   }
136 }
137 
138 /*                                                                      */
139 /*      DRAWBORDER: Draw a solid single line around the current         */
140 /*      viewport.                                                       */
141 /*                                                                      */
142 
DrawBorder(int color)143 void DrawBorder(int color)
144 {
145   struct viewporttype vp;
146 
147   setcolor( color);
148 
149   setlinestyle( SOLID_LINE, 0, NORM_WIDTH );
150 
151   getviewsettings( &vp );
152   rectangle( 0, 0, vp.right-vp.left, vp.bottom-vp.top);
153 
154 }
155 
156 /*                                                                      */
157 /*      STATUSLINE: Display a status line at the bottom of the screen.  */
158 /*                                                                      */
159 
StatusLineColor(char * msg,int color)160 void StatusLineColor( char *msg, int color )
161 {
162   int height;
163 
164   setviewport( 0, 0, MaxX, MaxY, 1 );   /* Open port to full screen     */
165   setcolor( color);                     /* Set requested color          */
166 
167   changetextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );
168   settextjustify( CENTER_TEXT, TOP_TEXT );
169   setlinestyle( SOLID_LINE, 0, NORM_WIDTH );
170   setfillstyle( EMPTY_FILL, 0 );
171 
172   height = textheight( "H" );           /* Detemine current height      */
173   bar( 0, MaxY-(height+4), MaxX, MaxY );
174   rectangle( 0, MaxY-(height+4), MaxX, MaxY );
175   outtextxy( MaxX/2, MaxY-(height+2), msg );
176   setviewport( 1, height+5, MaxX-1, MaxY-(height+5), 1 );
177 }
178 
StatusLine(char * msg)179 void StatusLine( char *msg )
180 {
181   StatusLineColor(msg, WHITE);
182 }
183 
184 /*                                                                      */
185 /*      MAINWINDOW: Establish the main window for the demo and set      */
186 /*      a viewport for the demo code.                                   */
187 /*                                                                      */
188 
DisplayTitle(char * header,int color)189 void DisplayTitle(char *header, int color) {
190   struct viewporttype vp;
191 
192   getviewsettings( &vp );
193   setcolor( color);                     /* Set current requested color  */
194   setviewport( 0, 0, MaxX, MaxY, 1 );   /* Open port to full screen     */
195   changetextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );
196   settextjustify( CENTER_TEXT, TOP_TEXT );
197   outtextxy( MaxX/2, 2, header );
198   setviewport(vp.left, vp.top, vp.right, vp.bottom, vp.clip);
199 }
200 
MainWindowColor(char * header,int color)201 void MainWindowColor( char *header, int color)
202 {
203   int height;
204 
205   cleardevice();                        /* Clear graphics screen        */
206   setcolor( color);                     /* Set current requested color  */
207   setviewport( 0, 0, MaxX, MaxY, 1 );   /* Open port to full screen     */
208 
209   height = textheight( "H" );           /* Get basic text height        */
210 
211   DisplayTitle(header, color);
212   setviewport( 0, height+4, MaxX, MaxY-(height+4), 1 );
213   DrawBorder(color);
214   setviewport( 1, height+5, MaxX-1, MaxY-(height+5), 1 );
215 
216 }
217 
MainWindow(char * header)218 void MainWindow( char *header )
219 {
220   MainWindowColor( header, WHITE);
221 }
222 
223 /*                                                                      */
224 /*      PAUSE: Pause until the user enters a keystroke. If the          */
225 /*      key is an ESC, then exit program, else simply return.           */
226 /*                                                                      */
227 
228 
NewPause(int clear)229 void NewPause(int clear)
230 {
231   int c;
232 
233   StatusLine( PauseMsg );               /* Put msg at bottom of screen  */
234 
235   c = getch();                          /* Read a character from kbd    */
236 
237   if( ESC == c ){                       /* Does user wish to leave?     */
238     closegraph();                       /* Change to text mode          */
239     exit( 1 );                          /* Return to OS                 */
240   }
241 
242   if( 0 == c ){                         /* Did use hit a non-ASCII key? */
243     c = getch();                        /* Read scan code for keyboard  */
244   }
245 
246   if (clear)
247     cleardevice();                      /* Clear the screen             */
248 }
249 
250 #define Pause() NewPause(TRUE)
251 
252 /*                                                                      */
253 /*      INITIALIZE: Initializes the graphics system and reports         */
254 /*      any errors which occured.                                       */
255 /*                                                                      */
256 
Initialize(void)257 void Initialize(void)
258 {
259   int xasp, yasp;
260 
261   GraphDriver = DETECT;                 /* Request auto-detection       */
262 #ifdef __GNUC__
263 /*  set_BGI_mode_whc(&GraphDriver, &GraphMode, 640, 480, 16); */
264     set_BGI_mode_pages(2);
265 #endif
266   initgraph( &GraphDriver, &GraphMode, BGI_PATH );
267   ErrorCode = graphresult();            /* Read result of initialization*/
268   if( ErrorCode != grOk ){              /* Error occured during init    */
269     printf(" Graphics System Error: %s\n", grapherrormsg( ErrorCode ) );
270     exit( 1 );
271   }
272 
273   getpalette( &palette );               /* Read the palette from board  */
274   MaxColors = getmaxcolor() + 1;        /* Read maximum number of colors*/
275   if (MaxColors == 256)
276     setrgbdefaults();
277 
278   MaxX = getmaxx();
279   MaxY = getmaxy();                     /* Read size of screen          */
280 
281   getaspectratio( &xasp, &yasp );       /* read the hardware aspect     */
282   AspectRatio = (double)xasp / (double)yasp; /* Get correction factor   */
283 
284 }
285 
286 
287 /*                                                                      */
288 /*      REPORTSTATUS: Report the current configuration of the system    */
289 /*      after the auto-detect initialization.                           */
290 /*                                                                      */
291 
ReportStatus(void)292 void ReportStatus(void)
293 {
294   struct viewporttype     viewinfo;     /* Params for inquiry procedures*/
295   struct linesettingstype lineinfo;
296   struct fillsettingstype fillinfo;
297   struct textsettingstype textinfo;
298   struct palettetype      palette;
299 
300   char *driver, *mode, *fmt;            /* Strings for driver and mode  */
301   int x, y, mno;
302 
303   getviewsettings( &viewinfo );
304   getlinesettings( &lineinfo );
305   getfillsettings( &fillinfo );
306   gettextsettings( &textinfo );
307   getpalette( &palette );
308 
309   x = 5;
310   y = 4;
311 
312   MainWindow( "Status report after InitGraph" );
313   settextjustify( LEFT_TEXT, TOP_TEXT );
314 
315   driver = getdrivername();
316   mode = getmodename(GraphMode);        /* get current setting          */
317 
318   gprintf( &x, &y, "Graphics device    : %-20s (%d)", driver, GraphDriver );
319   gprintf( &x, &y, "Graphics mode      : %-20s (%d)", mode, GraphMode );
320 #ifdef __GNUC__
321   gprintf( &x, &y, "Available pages    : %d", get_BGI_mode_pages() );
322 #endif
323   gprintf( &x, &y, "Screen resolution  : ( 0, 0, %d, %d )", getmaxx(), getmaxy() );
324   gprintf( &x, &y, "Current view port  : ( %d, %d, %d, %d )",
325   viewinfo.left, viewinfo.top, viewinfo.right, viewinfo.bottom );
326   gprintf( &x, &y, "Clipping           : %s", viewinfo.clip ? "ON" : "OFF" );
327 
328   gprintf( &x, &y, "Current position   : ( %d, %d )", getx(), gety() );
329   gprintf( &x, &y, "Colors available   : %d", MaxColors );
330   gprintf( &x, &y, "Current color      : %d", getcolor() );
331 
332   gprintf( &x, &y, "Line style         : %s", LineStyles[ lineinfo.linestyle ] );
333   gprintf( &x, &y, "Line thickness     : %d", lineinfo.thickness );
334 
335   gprintf( &x, &y, "Current fill style : %s", FillStyles[ fillinfo.pattern ] );
336   gprintf( &x, &y, "Current fill color : %d", fillinfo.color );
337 
338   gprintf( &x, &y, "Current font       : %s", Fonts[ textinfo.font ] );
339   gprintf( &x, &y, "Text direction     : %s", TextDirect[ textinfo.direction ] );
340   gprintf( &x, &y, "Character size     : %d", textinfo.charsize );
341   gprintf( &x, &y, "Horizontal justify : %s", HorizJust[ textinfo.horiz ] );
342   gprintf( &x, &y, "Vertical justify   : %s", VertJust[ textinfo.vert ] );
343 
344   gprintf( &x, &y, "Aspect ratio       : %lf", AspectRatio);
345 
346   getviewsettings( &viewinfo );
347   {
348     int ybase;
349     setfillstyle(SOLID_FILL, BLACK);
350     if (MaxY<350-1) {
351       x = 400;
352       y = 4;
353       fmt = "#%-3d: %s";
354     } else {
355       y += 5;
356       fmt = " Mode #%-3d : %s";
357     }
358     gprintf( &x, &y, "Available modes :");
359     y += 5;
360     ybase = y;
361     for (mno = 0; mno <= getmaxmode(); ++mno) {
362       char sp[100];
363       sprintf(sp, fmt, mno, getmodename(mno));
364       bar(x-4, y + textheight(sp), x+textwidth(sp)+4, y);
365       gprintf( &x, &y, "%s", sp);
366       if (y+viewinfo.top>viewinfo.bottom-8) {
367 	y = ybase;
368 	x += (viewinfo.right-viewinfo.left) / 2;
369       }
370     }
371   }
372 
373   Pause();                              /* Pause for user to read screen*/
374 
375 }
376 
377 /*                                                                      */
378 /*      TEXTDUMP: Display the all the characters in each of the         */
379 /*      available fonts.                                                */
380 /*                                                                      */
381 
TextDump(void)382 void TextDump(void)
383 {
384   static int CGASizes[]  = {
385     1, 3, 7, 3, 3, 2, 2, 2, 2, 2, 2  };
386   static int NormSizes[] = {
387     1, 4, 7, 4, 4, 2, 2, 2, 2, 2, 2  };
388 
389   char buffer[80];
390   int font, ch, wwidth, lwidth, size;
391   struct viewporttype vp;
392 
393   for( font=0 ; font<NFONTS ; ++font ){ /* For each available font      */
394     sprintf( buffer, "%s Character Set", Fonts[font] );
395     MainWindow( buffer );               /* Display fontname as banner   */
396     getviewsettings( &vp );             /* read current viewport        */
397 
398     settextjustify( LEFT_TEXT, TOP_TEXT );
399     moveto( 5, 3 );
400 
401     buffer[1] = '\0';                   /* Terminate string             */
402     wwidth = vp.right - vp.left;        /* Determine the window width   */
403 
404     if( font == DEFAULT_FONT ){
405       changetextstyle( font, HORIZ_DIR, 1 );
406       lwidth = textwidth( "H" );        /* Get average letter width     */
407       ch = 0;
408       while( ch < 256 ){                /* For each possible character  */
409 	buffer[0] = ch;                 /* Put character into a string  */
410 	if( (getx() + lwidth) > wwidth-3)
411 	  moveto( 5, gety() + textheight("H") + 3 );
412 	outtext( buffer );              /* send string to screen        */
413 	++ch;                           /* Goto the next character      */
414       }
415     }
416     else{
417 
418       size = (MaxY < 200) ? CGASizes[font] : NormSizes[font];
419       changetextstyle( font, HORIZ_DIR, size );
420 
421       ch = '!';                         /* Begin at 1st printable       */
422       while( ch < 256 ){                /* For each printable character */
423 	buffer[0] = ch;                 /* Put character into a string  */
424 	lwidth = textwidth( buffer);    /* Get letter width             */
425 	if( (lwidth+getx()) > wwidth-3) /* Are we still in window?      */
426 	  moveto( 5, gety()+textheight("H")+3 );
427 	outtext( buffer );              /* send string to screen        */
428 	++ch;                           /* Goto the next character      */
429       }
430 
431     }
432 
433     Pause();                            /* Pause until user acks        */
434 
435   }                                     /* End of FONT loop             */
436 
437 }
438 
439 /*                                                                      */
440 /*      BAR3DDEMO: Display a 3-D bar chart on the screen.               */
441 /*                                                                      */
442 
Bar3DDemo(void)443 void Bar3DDemo(void)
444 {
445   static int barheight[] = {
446     1, 3, 5, 4, 3, 2, 1, 5, 4, 2, 3   };
447   struct viewporttype vp;
448   int xstep, ystep, deepth;
449   int i, j, h, color, bheight;
450   char buffer[10];
451 
452   MainWindow( "Bar 3-D / Rectangle Demonstration" );
453 
454   h = 3 * textheight( "H" );
455   getviewsettings( &vp );
456   settextjustify( CENTER_TEXT, TOP_TEXT );
457   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 4 );
458   outtextxy( MaxX/2, 6, "These are 3-D Bars" );
459   changetextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );
460   setviewport( vp.left+50, vp.top+40, vp.right-50, vp.bottom-10, 1 );
461   getviewsettings( &vp );
462 
463   line( h, h, h, vp.bottom-vp.top-h );
464   line( h, (vp.bottom-vp.top)-h, (vp.right-vp.left)-h, (vp.bottom-vp.top)-h );
465   xstep = ((vp.right-vp.left) - (2*h)) / 10;
466   ystep = ((vp.bottom-vp.top) - (2*h)) / 5;
467   j = (vp.bottom-vp.top) - h;
468   deepth = (getmaxx() <= 400) ? 7 : 15;
469   settextjustify( LEFT_TEXT, CENTER_TEXT );
470 
471   for( i=0 ; i<6 ; ++i ){
472     line( h/2, j, h, j );
473     itoa( i, buffer, 10 );
474     outtextxy( 0, j, buffer );
475     j -= ystep;
476   }
477 
478   j = h;
479   settextjustify( CENTER_TEXT, TOP_TEXT );
480 
481   for( i=0 ; i<11 ; ++i ){
482     color = Random( MaxColors-1 ) + 1;
483     setfillstyle( i+1, color );
484     line( j, (vp.bottom-vp.top)-h, j, (vp.bottom-vp.top-3)-(h/2) );
485     itoa( i, buffer, 10 );
486     outtextxy( j, (vp.bottom-vp.top)-(h/2), buffer );
487     if( i != 10 ){
488       bheight = (vp.bottom-vp.top) - h - 1;
489       bar3d( j, (vp.bottom-vp.top-h)-(barheight[i]*ystep), j+xstep-deepth, bheight, deepth, 1 );
490     }
491     j += xstep;
492   }
493 
494   Pause();                              /* Pause for user's response    */
495 
496 }
497 
498 /*                                                                      */
499 /*      RandomBARS: Display random bars                                 */
500 /*                                                                      */
501 
RandomBars(void)502 void RandomBars(void)
503 {
504   int color;
505 
506   MainWindow( "Random Bars" );
507   StatusLine( PauseMsg );               /* Put msg at bottom of screen   */
508   while( !kbhit() ){                    /* Until user enters a key...   */
509     color = Random( MaxColors-1 )+1;
510     setcolor( color );
511     setfillstyle( Random(11)+1, color );
512     bar3d( Random( getmaxx() ), Random( getmaxy() ),
513        Random( getmaxx() ), Random( getmaxy() ), 0, OFF);
514   }
515 
516   Pause();                              /* Pause for user's response    */
517 
518 }
519 
520 
521 /*                                                                      */
522 /*      TEXTDEMO: Show each font in several sizes to the user.          */
523 /*                                                                      */
524 
TextDemo(void)525 void TextDemo(void)
526 {
527   int charsize[] = {
528     1, 3, 7, 3, 4, 2, 2, 2, 2, 2, 2   };
529   int font, size;
530   int h, x, y, i;
531   struct viewporttype vp;
532   char buffer[80];
533 
534   for( font=0 ; font<NFONTS ; ++font ){ /* For each of the avail. fonts */
535 
536     sprintf( buffer, "%s Demonstration", Fonts[font] );
537     MainWindow( buffer );
538     getviewsettings( &vp );
539 
540     changetextstyle( font, VERT_DIR, charsize[font] );
541     settextjustify( CENTER_TEXT, BOTTOM_TEXT );
542     outtextxy( 2*textwidth("M"), vp.bottom - 2*textheight("M"), "Vertical" );
543 
544     changetextstyle( font, HORIZ_DIR, charsize[font] );
545     settextjustify( LEFT_TEXT, TOP_TEXT );
546     outtextxy( 2*textwidth("M"), 2, "Horizontal" );
547 
548     settextjustify( CENTER_TEXT, CENTER_TEXT );
549     x = (vp.right - vp.left) / 2;
550     y = textheight( "H" );
551 
552     for( i=1 ; i<5 ; ++i ){             /* For each of the sizes */
553       size = (font == SMALL_FONT) ? i+3 : i;
554       changetextstyle( font, HORIZ_DIR, size );
555       h = textheight( "H" );
556       y += h;
557       sprintf( buffer, "Size %d", size );
558       outtextxy( x, y, buffer );
559 
560     }
561 
562     if( font != DEFAULT_FONT ){         /* Show user declared font size */
563       y += h / 2;                       /* Move down the screen         */
564       settextjustify( CENTER_TEXT, TOP_TEXT );
565       setusercharsize( 5, 6, 3, 2 );
566       changetextstyle( font, HORIZ_DIR, USER_CHAR_SIZE );
567       outtextxy( (vp.right-vp.left)/2, y, "User Defined Size" );
568     }
569 
570     Pause();                            /* Pause to let user look       */
571 
572   }                                     /* End of FONT loop             */
573 
574 }
575 
576 /*                                                                      */
577 /*      COLORDEMO: Display the current color palette on the screen.     */
578 /*                                                                      */
579 
ColorDemo(void)580 void ColorDemo(void)
581 {
582   struct viewporttype vp;
583   int color, height, width, ec;
584   int x, y, i, j;
585   char cnum[5];
586 
587   MainWindow( "Color Demonstration" );  /* Show demonstration name      */
588 
589   color = 1;
590   getviewsettings( &vp );               /* Get the current window size  */
591   width  = 2 * ( (vp.right+1) / 16 );      /* Get box dimensions           */
592   height = 2 * ( (vp.bottom-10) / 10 );
593 
594   x = width / 2;
595   y = height / 2;       /* Leave 1/2 box border         */
596 
597   for( j=0 ; j<3 ; ++j ){               /* Row loop                     */
598 
599     for( i=0 ; i<5 ; ++i ){             /* Column loop                  */
600 
601       ec = _ega_color(color);
602       setfillstyle(SOLID_FILL, ec);     /* Set to solid fill in color   */
603       setcolor( ec );                   /* Set the same border color    */
604 
605       bar( x, y, x+width, y+height );   /* Draw the rectangle           */
606       rectangle( x, y, x+width, y+height );  /* outline the rectangle   */
607 
608       if( color == BLACK ){             /* If box was black...          */
609 	setcolor( _ega_color(WHITE) );  /* Set drawing color to white   */
610 	rectangle( x, y, x+width, y+height );  /* Outline black in white*/
611       }
612 
613       itoa( color, cnum, 10 );          /* Convert # to ASCII           */
614       outtextxy( x+(width/2), y+height+4, cnum );  /* Show color #      */
615 
616       color = (color + 1) % MaxColors;  /* Advance to the next color    */
617       x += (width / 2) * 3;             /* move the column base         */
618     }                           /* End of Column loop           */
619 
620     y += (height / 2) * 3;              /* move the row base            */
621     x = width / 2;                      /* reset column base            */
622   }                                     /* End of Row loop              */
623 
624   Pause();                              /* Pause for user's response    */
625 
626 }
627 
628 /*                                                                      */
629 /*      ARCDEMO: Display a random pattern of arcs on the screen */
630 /*      until the user says enough.                                     */
631 /*                                                                      */
632 
ArcDemo(void)633 void ArcDemo(void)
634 {
635   int mradius;                          /* Maximum radius allowed       */
636   int eangle;                           /* Random end angle of Arc      */
637   struct arccoordstype ai;              /* Used to read Arc Cord info   */
638 
639   MainWindow( "Arc Demonstration" );
640   StatusLine( StopMsg);
641 
642   mradius = (int)(MaxY / (10.0*AspectRatio));  /* Determine the maximum radius */
643 
644   while( !kbhit() ){                    /* Repeat until a key is hit    */
645     setcolor( Random( MaxColors - 1 ) + 1 );    /* randomly select a color      */
646     eangle = Random( 358 ) + 1;         /* Select an end angle          */
647     arc( Random(MaxX), Random(MaxY), Random(eangle), eangle, mradius );
648     getarccoords( &ai );                /* Read Cord data               */
649     line( ai.x, ai.y, ai.xstart, ai.ystart ); /* line from start to center */
650     line( ai.x, ai.y, ai.xend,   ai.yend );   /* line from end to center   */
651   }                                     /* End of WHILE not KBHIT       */
652 
653   Pause();                              /* Wait for user's response     */
654 
655 }
656 
657 /*                                                                      */
658 /*      CIRCLEDEMO: Display a random pattern of circles on the screen   */
659 /*      until the user says enough.                                     */
660 /*                                                                      */
661 
CircleDemo(void)662 void CircleDemo(void)
663 {
664   int mradius;                          /* Maximum radius allowed       */
665 
666   MainWindow( "Circle Demonstration" );
667   StatusLine( StopMsg);
668 
669   mradius = (int)(MaxY / (10.0*AspectRatio));  /* Determine the maximum radius */
670 
671   while( !kbhit() ){                    /* Repeat until a key is hit    */
672     setcolor( Random( MaxColors - 1 ) + 1 );    /* Randomly select a color      */
673     circle( Random(MaxX), Random(MaxY), Random(mradius) );
674   }                                     /* End of WHILE not KBHIT       */
675 
676   Pause();                              /* Wait for user's response     */
677 
678 }
679 
680 /*                                                                      */
681 /*      PIEDEMO: Display a pie chart on the screen.                     */
682 /*                                                                      */
683 
684 #define adjasp( y )     ((int)(AspectRatio * (double)(y)))
685 #define torad( d )      (( (double)(d) * PI ) / 180.0 )
686 
PieDemo(void)687 void PieDemo(void)
688 {
689   struct viewporttype vp;
690   int xcenter, ycenter, radius, lradius;
691   int x, y;
692   double radians, piesize;
693 
694   MainWindow( "Pie Chart Demonstration" );
695 
696   getviewsettings( &vp );               /* Get the current viewport     */
697   xcenter = (vp.right - vp.left) / 2;   /* Center the Pie horizontally  */
698   ycenter = (vp.bottom - vp.top) / 2+20;/* Center the Pie vertically    */
699   radius  = (vp.bottom - vp.top) / 3;   /* It will cover 2/3rds screen  */
700   piesize = (vp.bottom - vp.top) / 4.0; /* Optimum height ratio of pie  */
701 
702   if (AspectRatio >= 1.0)
703     radius = (int)(radius / AspectRatio);
704   while( (AspectRatio*radius) < piesize ) ++radius;
705 
706   lradius = radius + ( radius / 5 );    /* Labels placed 20% farther    */
707 
708   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 4 );
709   settextjustify( CENTER_TEXT, TOP_TEXT );
710   outtextxy( MaxX/2, 6, "This is a Pie Chart" );
711   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 1 );
712   settextjustify( CENTER_TEXT, TOP_TEXT );
713 
714   setfillstyle( SOLID_FILL, _ega_color(RED) );
715   pieslice( xcenter+10, ycenter-adjasp(10), 0, 90, radius );
716   radians = torad( 45 );
717   x = xcenter + (int)( cos( radians ) * (double)lradius );
718   y = ycenter - (int)( sin( radians ) * (double)lradius * AspectRatio );
719   settextjustify( LEFT_TEXT, BOTTOM_TEXT );
720   outtextxy( x, y, "25 %" );
721 
722   setfillstyle( WIDE_DOT_FILL, _ega_color(GREEN) );
723   pieslice( xcenter, ycenter, 90, 135, radius );
724   radians = torad( 113 );
725   x = xcenter + (int)( cos( radians ) * (double)lradius );
726   y = ycenter - (int)( sin( radians ) * (double)lradius * AspectRatio );
727   settextjustify( RIGHT_TEXT, BOTTOM_TEXT );
728   outtextxy( x, y, "12.5 %" );
729 
730   setfillstyle( INTERLEAVE_FILL, _ega_color(YELLOW) );
731   settextjustify( RIGHT_TEXT, CENTER_TEXT );
732   pieslice( xcenter-10, ycenter, 135, 225, radius );
733   radians = torad( 180 );
734   x = xcenter + (int)( cos( radians ) * (double)lradius );
735   y = ycenter - (int)( sin( radians ) * (double)lradius * AspectRatio );
736   settextjustify( RIGHT_TEXT, CENTER_TEXT );
737   outtextxy( x, y, "25 %" );
738 
739   setfillstyle( HATCH_FILL, _ega_color(BLUE) );
740   pieslice( xcenter, ycenter, 225, 360, radius );
741   radians = torad( 293 );
742   x = xcenter + (int)( cos( radians ) * (double)lradius );
743   y = ycenter - (int)( sin( radians ) * (double)lradius * AspectRatio );
744   settextjustify( LEFT_TEXT, TOP_TEXT );
745   outtextxy( x, y, "37.5 %" );
746 
747   Pause();                              /* Pause for user's response    */
748 
749 }
750 
751 /*                                                                      */
752 /*      BARDEMO: Draw a 2-D bar chart using Bar and Rectangle.          */
753 /*                                                                      */
754 
BarDemo(void)755 void BarDemo(void)
756 {
757   int barheight[] = {
758     1, 3, 5, 2, 4   };
759   int styles[]    = {
760     1, 3, 10, 5, 9, 1   };
761   int xstep, ystep;
762   int sheight, swidth;
763   int i, j, h;
764   struct viewporttype vp;
765   char buffer[40];
766 
767   MainWindow( "Bar / Rectangle demonstration" );
768   h = 3 * textheight( "H" );
769   getviewsettings( &vp );
770   settextjustify( CENTER_TEXT, TOP_TEXT );
771   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 4 );
772   outtextxy( MaxX /2, 6, "These are 2-D Bars" );
773   changetextstyle( DEFAULT_FONT, HORIZ_DIR, 1 );
774   setviewport( vp.left+50, vp.top+30, vp.right-50, vp.bottom-10, 1 );
775 
776   getviewsettings( &vp );
777   sheight = vp.bottom - vp.top;
778   swidth  = vp.right  - vp.left;
779 
780   line( h, h, h, sheight-h );
781   line( h, sheight-h, sheight-h, sheight-h );
782   ystep = (sheight - (2*h) ) / 5;
783   xstep = (swidth  - (2*h) ) / 5;
784   j = sheight - h;
785   settextjustify( LEFT_TEXT, CENTER_TEXT );
786 
787   for( i=0 ; i<6 ; ++i ){
788     line( h/2, j, h, j );
789     itoa( i, buffer, 10 );
790     outtextxy( 0, j, buffer );
791     j -= ystep;
792   }
793 
794   j = h;
795   settextjustify( CENTER_TEXT, TOP_TEXT );
796   for( i=0 ; i<6 ; ++i ){
797     setfillstyle( styles[i], Random(MaxColors-1)+1 );
798     line( j, sheight - h, j, sheight- 3 - (h/2) );
799     itoa( i, buffer, 10 );
800     outtextxy( j, sheight - (h/2), buffer );
801     if( i != 5 ){
802       bar( j, (sheight-h)-(barheight[i] * ystep), j+xstep, sheight-h-1 );
803       rectangle( j, (sheight-h)-(barheight[i] * ystep), j+xstep, sheight-h);
804     }
805     j += xstep;
806   }
807 
808   Pause();
809 
810 }
811 
812 /*                                                                      */
813 /*      LINERELDEMO: Display pattern using moverel and linerel cmds.    */
814 /*                                                                      */
815 
LineRelDemo(void)816 void LineRelDemo(void)
817 {
818   struct viewporttype vp;
819   int h, w, dx, dy, cx, cy;
820   struct PTS outs[7];
821 
822 
823   MainWindow( "MoveRel / LineRel Demonstration" );
824   StatusLine( StopMsg);
825 
826   getviewsettings( &vp );
827   cx = (vp.right  - vp.left) / 2;       /* Center of the screen coords  */
828   cy = (vp.bottom - vp.top ) / 2;
829 
830   h  = (vp.bottom - vp.top ) / 8;
831   w  = (vp.right  - vp.left) / 9;
832 
833   dx = 2 * w;
834   dy = 2 * h;
835 
836   setcolor( BLACK );
837 
838   setfillstyle( SOLID_FILL, _ega_color(BLUE) );
839   bar( 0, 0, vp.right-vp.left, vp.bottom-vp.top );      /* Draw backgnd */
840 
841   outs[0].x = cx -  dx;
842   outs[0].y = cy -  dy;
843   outs[1].x = cx - (dx-w);
844   outs[1].y = cy - (dy+h);
845   outs[2].x = cx +  dx;
846   outs[2].y = cy - (dy+h);
847   outs[3].x = cx +  dx;
848   outs[3].y = cy +  dy;
849   outs[4].x = cx + (dx-w);
850   outs[4].y = cy + (dy+h);
851   outs[5].x = cx -  dx;
852   outs[5].y = cy + (dy+h);
853   outs[6].x = cx -  dx;
854   outs[6].y = cy -  dy;
855 
856   setfillstyle( SOLID_FILL, WHITE );
857   fillpoly( 7, (int far *)outs );
858 
859   outs[0].x = cx - (w/2);
860   outs[0].y = cy + h;
861   outs[1].x = cx + (w/2);
862   outs[1].y = cy + h;
863   outs[2].x = cx + (w/2);
864   outs[2].y = cy - h;
865   outs[3].x = cx - (w/2);
866   outs[3].y = cy - h;
867   outs[4].x = cx - (w/2);
868   outs[4].y = cy + h;
869 
870   setfillstyle( SOLID_FILL, _ega_color(BLUE) );
871   fillpoly( 5, (int far *)outs );
872 
873   /*    Draw a Tesseract object on the screen using the LineRel and     */
874   /*    MoveRel drawing commands.                                       */
875 
876   moveto( cx-dx, cy-dy );
877   linerel(  w, -h );
878   linerel(  3*w,        0 );
879   linerel(   0,  5*h );
880   linerel( -w,  h );
881   linerel( -3*w,        0 );
882   linerel(   0, -5*h );
883 
884   moverel( w, -h );
885   linerel(   0,  5*h );
886   linerel( w+(w/2), 0 );
887   linerel(   0, -3*h );
888   linerel( w/2,   -h );
889   linerel( 0, 5*h );
890 
891   moverel(  0, -5*h );
892   linerel( -(w+(w/2)), 0 );
893   linerel( 0, 3*h );
894   linerel( -w/2, h );
895 
896   moverel( w/2, -h );
897   linerel( w, 0 );
898 
899   moverel( 0, -2*h );
900   linerel( -w, 0 );
901 
902   Pause();                              /* Wait for user's response     */
903 
904 }
905 
906 /*                                                                      */
907 /*      PUTPIXELDEMO: Display a pattern of random dots on the screen    */
908 /*      and pick them back up again.                                    */
909 /*                                                                      */
910 
PutPixelDemo(void)911 void PutPixelDemo(void)
912 {
913   int seed = 1958;
914   int i, x, y, h, w, color;
915   struct viewporttype vp;
916 
917   MainWindow( "PutPixel / GetPixel Demonstration" );
918   StatusLine( PauseMsg);                /* Put msg at bottom of screen   */
919 
920   getviewsettings( &vp );
921   h = vp.bottom - vp.top;
922   w = vp.right  - vp.left;
923 
924   do {
925     Seed( seed );                          /* Restart random # function    */
926 
927     for( i=0 ; i<5000 ; ++i ){             /* Put 5000 pixels on screen    */
928       x = 1 + Random( w - 1 );             /* Generate a random location   */
929       y = 1 + Random( h - 1 );
930       color = Random( MaxColors-1 ) + 1;
931       putpixel( x, y, color );
932     }
933 
934     Seed( seed );                          /* Restart random # at same #   */
935     for( i=0 ; i<5000 ; ++i ){             /* Take the 5000 pixels off      */
936       x = 1 + Random( w - 1 );             /* Generate a random location   */
937       y = 1 + Random( h - 1 );
938       color = getpixel( x, y );            /* Read the color pixel          */
939       if( color==Random(MaxColors-1)+1 )   /* Used to keep random in sync   */
940 	putpixel( x, y, BLACK );           /* Write pixel to BLACK          */
941     }
942     if (!kbhit())
943       delay(400);
944   } while ( !kbhit());
945 
946   Pause();                              /* Wait for user's response     */
947 
948 }
949 
950 /*                                                                      */
951 /*   PUTIMAGEDEMO                                                       */
952 /*                                                                      */
953 #define PAUSETIME 20
954 #define PID_r     20
955 #define StartX    100
956 #define StartY    50
957 #define MAXXSTEP  (2*PID_r/3)
958 #define MAXYSTEP  (PID_r/2)
959 #define PID_STEPS 250
960 
SaucerMoveX(int * dx,int x)961 int SaucerMoveX(int *dx, int x) {
962 //    *dx += (Random( 2*MAXXSTEP+1) - MAXXSTEP + (MAXXSTEP*(MaxX/2-x))/MaxX) / 10;
963     *dx += Random( 2*MAXXSTEP) - MAXXSTEP;
964     if ( *dx >  MAXXSTEP) *dx =  MAXXSTEP; else
965     if ( *dx < -MAXXSTEP) *dx = -MAXXSTEP;
966     return *dx;
967 }
SaucerMoveY(int * dy,int y)968 int SaucerMoveY(int *dy, int y) {
969 //    *dy += (Random( 2*MAXYSTEP+1) - MAXYSTEP + (MAXYSTEP*(MaxY/2-y))/MaxY) / 10;
970     *dy += Random( 2*MAXYSTEP) - MAXYSTEP;
971     if ( *dy >  MAXYSTEP) *dy =  MAXYSTEP; else
972     if ( *dy < -MAXYSTEP) *dy = -MAXYSTEP;
973     return *dy;
974 }
975 
976 #define SaucerLimitX() do {                             \
977     if (vp.left + nx + width - 1 > vp.right)            \
978       nx = vp.right-vp.left-width + 1;                  \
979     else                                                \
980       if (nx < 0)                                       \
981 	nx = 0;                                         \
982 } while (0)
983 
984 #define SaucerLimitY() do {                             \
985     if (vp.top + ny + height - 1 > vp.bottom)           \
986       ny = vp.bottom-vp.top-height + 1;                 \
987     else                                                \
988       if (ny < 0)                                       \
989 	ny = 0;                                         \
990 } while (0)
991 
PutImageDemo(void)992 void PutImageDemo(void)
993 {
994   struct viewporttype vp;
995   int    x, y, ulx, uly, lrx, lry, size, i, width, height;
996   int    nx, ny, dx, dy;
997   void   *Saucer;
998   int    old_xasp, old_yasp;
999 
1000   MainWindow("GetImage / PutImage Demonstration");
1001   getviewsettings( &vp );
1002 
1003   /* DrawSaucer */
1004   getaspectratio(&old_xasp, &old_yasp);
1005   setaspectratio(1, 1);
1006   ellipse(StartX, StartY, 0, 360, PID_r, PID_r / 3 + 2);
1007   ellipse(StartX, StartY - 4, 190, 357, PID_r, PID_r / 3);
1008   line(StartX + 7, StartY - 6, StartX + 10, StartY - 12);
1009   circle(StartX + 10, StartY - 12, 2);
1010   line(StartX - 7, StartY - 6, StartX - 10, StartY - 12);
1011   circle(StartX - 10, StartY - 12, 2);
1012   setfillstyle(SOLID_FILL, WHITE);
1013   floodfill(StartX + 1, StartY + 4, getcolor());
1014   setaspectratio(old_xasp, old_yasp);
1015 
1016   /* Read saucer image */
1017   ulx = StartX-(PID_r+1);
1018   uly = StartY-14;
1019   lrx = StartX+(PID_r+1);
1020   lry = StartY+(PID_r/3)+3;
1021   width = lrx - ulx + 1;
1022   height = lry - uly + 1;
1023   size = imagesize(ulx, uly, lrx, lry);
1024   Saucer = malloc( size );
1025   if (Saucer == NULL) return;
1026   getimage(ulx, uly, lrx, lry, Saucer);
1027   putimage(ulx, uly, Saucer, XOR_PUT);
1028 
1029   /* Plot some "stars"  */
1030   for ( i=0 ; i<1000; ++i )
1031     putpixel(Random(MaxX), Random(MaxY), Random( MaxColors-1 )+1);
1032   x = MaxX / 2;
1033   y = MaxY / 2;
1034   dx = 1;
1035   dy = 0;
1036 
1037   StatusLine( PauseMsg);                /* Put msg at bottom of screen   */
1038 
1039   /* until a key is hit */
1040   while ( !kbhit() ) {
1041 
1042     /* Draw the Saucer */
1043     if (dx != 0 || dy != 0)
1044       putimage(x, y, Saucer, XOR_PUT);                /*  draw image  */
1045     delay(PAUSETIME);
1046     nx = x + SaucerMoveX(&dx,x);
1047     ny = y + SaucerMoveY(&dy,y);
1048     SaucerLimitX();
1049     SaucerLimitY();
1050     dx = nx-x;
1051     dy = ny-y;
1052     if (dx != 0 || dy != 0)
1053       putimage(x, y, Saucer, XOR_PUT);               /* erase image  */
1054     x = nx;
1055     y = ny;
1056   }
1057 
1058 #ifdef __GNUC__
1059   if (get_BGI_mode_pages()>1) {
1060     int ActPage = 0;
1061     void *Screen = NULL;
1062 
1063     size = imagesize(0, 0, MaxX, MaxY);
1064     Screen = malloc( size );
1065     if (Screen != NULL) {
1066       if ( getch() == ESC) {
1067 	closegraph();
1068 	exit(1);
1069       }
1070       setviewport(0, 0, MaxX, MaxY, 1);
1071       getimage(0, 0, MaxX, MaxY, Screen);
1072       while ( !kbhit() ) {
1073 	ActPage = (ActPage+1)&1;
1074 	setactivepage(ActPage);
1075 	putimage(0, 0, Screen, COPY_PUT);
1076 	putimage(vp.left+x, vp.top+y, Saucer, XOR_PUT );
1077 	setvisualpage(ActPage);
1078 	nx = x + SaucerMoveX(&dx, x);
1079 	ny = y + SaucerMoveY(&dy, y);
1080 	SaucerLimitX();
1081 	SaucerLimitY();
1082 	dx = nx-x;
1083 	dy = ny-y;
1084 	x = nx;
1085 	y = ny;
1086       }
1087       setactivepage(0);
1088       putimage(0, 0, Screen, COPY_PUT);
1089       setvisualpage(0);
1090       setactivepage(1);
1091       cleardevice();
1092       setactivepage(0);
1093       setviewport(vp.left, vp.top, vp.right, vp.bottom, vp.clip);
1094       free(Screen);
1095     }
1096   }
1097 #endif
1098 
1099   free( Saucer );
1100   Pause();
1101 }
1102 #undef PAUSETIME
1103 #undef PID_r
1104 #undef StartX
1105 #undef StartY
1106 #undef MAXXSTEP
1107 #undef MAXYSTEP
1108 #undef PID_STEPS
1109 
1110 /*                                                                      */
1111 /*      LINETODEMO: Display a pattern using moveto and lineto commands. */
1112 /*                                                                      */
1113 
1114 #define MAXPTS  15
1115 
LineToDemo(void)1116 void LineToDemo(void)
1117 {
1118   struct viewporttype vp;
1119   struct PTS points[MAXPTS];
1120   int i, j, h, w, xcenter, ycenter;
1121   int radius, angle, step;
1122   double  rads;
1123 
1124   MainWindow( "MoveTo / LineTo Demonstration" );
1125 
1126   getviewsettings( &vp );
1127   h = vp.bottom - vp.top;
1128   w = vp.right  - vp.left;
1129 
1130   xcenter = w / 2;                      /* Determine the center of circle */
1131   ycenter = h / 2;
1132   radius  = (int)( (h-30) / (AspectRatio*2) );
1133   step    = 360 / MAXPTS;               /* Determine # of increments    */
1134 
1135   angle = 0;                            /* Begin at zero degrees        */
1136   for( i=0 ; i<MAXPTS ; ++i ){          /* Determine circle intercepts  */
1137     rads = (double)angle * PI / 180.0;  /* Convert angle to radians     */
1138     points[i].x = xcenter + (int)( cos(rads) * radius );
1139     points[i].y = ycenter - (int)( sin(rads) * radius * AspectRatio );
1140     angle += step;                      /* Move to next increment       */
1141   }
1142 
1143   circle( xcenter, ycenter, radius );   /* Draw bounding circle         */
1144 
1145   for( i=0 ; i<MAXPTS ; ++i ){          /* Draw the cords to the circle */
1146     for( j=i ; j<MAXPTS ; ++j ){        /* For each remaining intersect */
1147       moveto(points[i].x, points[i].y); /* Move to beginning of cord    */
1148       lineto(points[j].x, points[j].y); /* Draw the cord                */
1149     }
1150   }
1151 
1152   Pause();                              /* Wait for user's response     */
1153 
1154 }
1155 
1156 /*                                                                      */
1157 /*      LINESTYLEDEMO: Display a pattern using all of the standard      */
1158 /*      line styles that are available.                                 */
1159 /*                                                                      */
1160 
LineStyleDemo(void)1161 void LineStyleDemo(void)
1162 {
1163   int style, step;
1164   int x, y, w;
1165   struct viewporttype vp;
1166   char buffer[40];
1167 
1168   MainWindow( "Pre-defined line styles" );
1169 
1170   getviewsettings( &vp );
1171   w = vp.right  - vp.left;
1172 
1173   x = 35;
1174   y = 10;
1175   step = w / 11;
1176 
1177   settextjustify( LEFT_TEXT, TOP_TEXT );
1178   outtextxy( x, y, "Normal Width" );
1179 
1180   settextjustify( CENTER_TEXT, TOP_TEXT );
1181 
1182   for( style=0 ; style<4 ; ++style ){
1183     setlinestyle( style, 0, NORM_WIDTH );
1184     line( x, y+20, x, vp.bottom-40 );
1185     itoa( style, buffer, 10 );
1186     outtextxy( x, vp.bottom-30, buffer );
1187     x += step;
1188   }
1189 
1190   x += 2 * step;
1191 
1192   settextjustify( LEFT_TEXT, TOP_TEXT );
1193   outtextxy( x, y, "Thick Width" );
1194   settextjustify( CENTER_TEXT, TOP_TEXT );
1195 
1196   for( style=0 ; style<4 ; ++style ){
1197     setlinestyle( style, 0, THICK_WIDTH );
1198     line( x, y+20, x, vp.bottom-40 );
1199     itoa( style, buffer, 10 );
1200     outtextxy( x, vp.bottom-30, buffer );
1201     x += step;
1202   }
1203 
1204   settextjustify( LEFT_TEXT, TOP_TEXT );
1205 
1206   Pause();                              /* Wait for user's response     */
1207 
1208 }
1209 
1210 /*                                                                      */
1211 /*      CRTMODEDEMO: Demonstrate the effects of the change mode         */
1212 /*      commands on the current screen.                                 */
1213 /*                                                                      */
1214 
CRTModeDemo(void)1215 void CRTModeDemo(void)
1216 {
1217   struct viewporttype vp;
1218   int mode;
1219   char m[41];
1220 
1221   MainWindow( "SetGraphMode / RestoreCRTMode demo" );
1222   getviewsettings( &vp );
1223   mode = getgraphmode();
1224   settextjustify( CENTER_TEXT, CENTER_TEXT );
1225 
1226   outtextxy( (vp.right-vp.left)/2, (vp.bottom-vp.top)/2,
1227   "Now you are in graphics mode..." );
1228   StatusLine( "Press any key for text mode..." );
1229   getch();
1230 
1231   restorecrtmode();
1232   printf( "Now you are in text mode.\n\n" );
1233   printf( "Press <CR> to go back to graphics..." );
1234   fflush(stdout);
1235   fgets(m,40,stdin);
1236 
1237   setgraphmode( mode );
1238   MainWindow( "SetGraphMode / RestoreCRTMode demo" );
1239   settextjustify( CENTER_TEXT, CENTER_TEXT );
1240   outtextxy( (vp.right-vp.left)/2, (vp.bottom-vp.top)/2,
1241   "Back in Graphics Mode..." );
1242 
1243   Pause();                              /* Wait for user's response     */
1244 
1245 }
1246 
1247 /*                                                                      */
1248 /*      USERLINESTYLEDEMO: Display line styles showing the user         */
1249 /*      defined line style functions.                                   */
1250 /*                                                                      */
1251 
UserLineStyleDemo(void)1252 void UserLineStyleDemo(void)
1253 {
1254   static unsigned msk_or[3]  = { 0x0000, 0x0000, 0x8001 };
1255   static unsigned msk_and[3] = { 0xFFFF, 0x7FFE, 0xFFFF };
1256   int x, y, i, h, flag;
1257   unsigned int style, msk_cnt;
1258   struct viewporttype vp;
1259 
1260   MainWindow( "User defined line styles" );
1261 
1262   getviewsettings( &vp );
1263   h = vp.bottom - vp.top;
1264 
1265   x = 4;
1266   y = 10;
1267   style = 0;
1268   msk_cnt = 0;
1269   i = 0;
1270 
1271   settextjustify( CENTER_TEXT, TOP_TEXT );
1272   flag = TRUE;                          /* Set the bits in this pass    */
1273 
1274   while( x < vp.right-2 ){              /* Draw lines across the screen */
1275 
1276     if( flag )                          /* If flag, set bits...         */
1277       style |= (1 << i);                /*    Set the Ith bit in word   */
1278     else                                /* If no flag, clear bits       */
1279       style &= ~(1<<i);                 /*    Clear the Ith bit in word */
1280 
1281     setlinestyle( USERBIT_LINE,
1282 		  (style|msk_or[msk_cnt])&msk_and[msk_cnt],
1283 		  NORM_WIDTH );
1284     line( x, y, x, h-y );               /* Draw the new line pattern    */
1285 
1286     x += 5;                             /* Move the X location of line  */
1287     i = (i + 1) % 16;                   /* Advance to next bit pattern  */
1288 
1289     if( style == 0xffff ){              /* Are all bits set?            */
1290       flag = FALSE;                     /*   begin removing bits        */
1291       i = 0;                            /* Start with whole pattern     */
1292     }
1293     else {                              /* Bits not all set...          */
1294       if( style == 0 ) {                /* Are all bits clear?          */
1295 	flag = TRUE;                    /*   begin setting bits         */
1296 	i = 0;
1297 	if (++msk_cnt >= 3) msk_cnt = 0;
1298       }
1299     }
1300   }
1301 
1302   settextjustify( LEFT_TEXT, TOP_TEXT );
1303 
1304   Pause();                              /* Wait for user's response     */
1305 
1306 }
1307 
1308 /*                                                                      */
1309 /*      FILLSTYLEDEMO: Display the standard fill patterns available.    */
1310 /*                                                                      */
1311 
FillStyleDemo(void)1312 void FillStyleDemo(void)
1313 {
1314   int h, w, style;
1315   int i, j, x, y;
1316   struct viewporttype vp;
1317   char buffer[40];
1318 
1319   MainWindow( "Pre-defined Fill Styles" );
1320 
1321   getviewsettings( &vp );
1322   w = 2 * ((vp.right  +  1) / 13);
1323   h = 2 * ((vp.bottom - 10) / 10);
1324 
1325   x = w / 2;
1326   y = h / 2;            /* Leave 1/2 blk margin         */
1327   style = 0;
1328 
1329   for( j=0 ; j<3 ; ++j ){               /* Three rows of boxes          */
1330     for( i=0 ; i<4 ; ++i ){             /* Four column of boxes         */
1331       setfillstyle(style, WHITE);       /* Set the fill style and WHITE */
1332       bar( x, y, x+w, y+h );            /* Draw the actual box          */
1333       rectangle( x, y, x+w, y+h );      /* Outline the box              */
1334       itoa( style, buffer, 10 );        /* Convert style 3 to ASCII     */
1335       outtextxy( x+(w / 2), y+h+4, buffer );
1336       ++style;                          /* Go on to next style #        */
1337       x += (w / 2) * 3;                 /* Go to next column            */
1338     }                           /* End of coulmn loop           */
1339     x = w / 2;                          /* Put base back to 1st column  */
1340     y += (h / 2) * 3;                   /* Advance to next row          */
1341   }                                     /* End of Row loop              */
1342 
1343   settextjustify( LEFT_TEXT, TOP_TEXT );
1344 
1345   Pause();                              /* Wait for user's response     */
1346 
1347 }
1348 
1349 /*                                                                      */
1350 /*      FILLPATTERNDEMO: Demonstrate how to use the user definable      */
1351 /*      fill patterns.                                                  */
1352 /*                                                                      */
1353 
FillPatternDemo(void)1354 void FillPatternDemo(void)
1355 {
1356   int style;
1357   int h, w;
1358   int x, y, i, j;
1359   char buffer[40];
1360   struct viewporttype vp;
1361   static char patterns[][8] = {
1362     { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
1363     { 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC },
1364     { 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F },
1365     { 0x00, 0x10, 0x28, 0x44, 0x28, 0x10, 0x00, 0x00 },
1366     { 0x00, 0x70, 0x20, 0x27, 0x24, 0x24, 0x07, 0x00 },
1367     { 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 },
1368     { 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 },
1369     { 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00 },
1370     { 0x00, 0x00, 0x22, 0x08, 0x00, 0x22, 0x1C, 0x00 },
1371     { 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x3C, 0x7E, 0xFF },
1372     { 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00 },
1373     { 0x00, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x00 }
1374   };
1375 
1376   MainWindow( "User Defined Fill Styles" );
1377 
1378   getviewsettings( &vp );
1379   w = 2 * ((vp.right  +  1) / 13);
1380   h = 2 * ((vp.bottom - 10) / 10);
1381 
1382   x = w / 2;
1383   y = h / 2;            /* Leave 1/2 blk margin         */
1384   style = 0;
1385 
1386   for( j=0 ; j<3 ; ++j ){               /* Three rows of boxes          */
1387     for( i=0 ; i<4 ; ++i ){             /* Four column of boxes         */
1388       setfillpattern( &patterns[style][0], WHITE);
1389       bar( x, y, x+w, y+h );            /* Draw the actual box          */
1390       rectangle( x, y, x+w, y+h );      /* Outline the box              */
1391       itoa( style, buffer, 10 );        /* Convert style 3 to ASCII     */
1392       outtextxy( x+(w / 2), y+h+4, buffer );
1393       ++style;                          /* Go on to next style #        */
1394       x += (w / 2) * 3;                 /* Go to next column            */
1395     }                           /* End of coulmn loop           */
1396     x = w / 2;                          /* Put base back to 1st column  */
1397     y += (h / 2) * 3;                   /* Advance to next row          */
1398   }                                     /* End of Row loop              */
1399 
1400   settextjustify( LEFT_TEXT, TOP_TEXT );
1401 
1402   Pause();                              /* Wait for user's response     */
1403 
1404 }
1405 
1406 /*                                                                      */
1407 /*      POLYDEMO: Display a random pattern of polygons on the screen    */
1408 /*      until the user says enough.                                     */
1409 /*                                                                      */
PaletteDemo(void)1410 void PaletteDemo(void)
1411 {
1412   int i, j, x, y, color, cols;
1413   struct viewporttype vp;
1414   int height, width;
1415 
1416   if (MaxColors > 16)
1417     return;
1418   MainWindow( "Palette Demonstration" );
1419   StatusLine( StopMsg);
1420 
1421   getviewsettings( &vp );
1422   width  = (vp.right - vp.left) / 15;   /* get width of the box         */
1423   height = (vp.bottom - vp.top) / 10;   /* Get the height of the box    */
1424 
1425   x = y = 0;                            /* Start in upper corner        */
1426   color = 1;                            /* Begin at 1st color           */
1427   cols = 16;
1428   if (MaxColors < cols) cols = MaxColors;
1429 
1430   for( j=0 ; j<10 ; ++j ){              /* For 10 rows of boxes         */
1431     for( i=0 ; i<15 ; ++i ){            /* For 15 columns of boxes      */
1432       setfillstyle( SOLID_FILL, color++ );      /* Set the color of box */
1433       bar( x, y, x+width, y+height );           /* Draw the box         */
1434       x += width + 1;                           /* Advance to next col  */
1435       color = 1 + (color % (cols- 2));          /* Set new color        */
1436     }                                   /* End of COLUMN loop           */
1437     x = 0;                              /* Goto 1st column              */
1438     y += height + 1;                    /* Goto next row                */
1439   }                                     /* End of ROW loop              */
1440 
1441   while( !kbhit() ){                    /* Until user enters a key...   */
1442     setpalette( 1+Random(cols - 2), Random(64) );
1443   }
1444 
1445   setallpalette( &palette );
1446 
1447   Pause();                              /* Wait for user's response     */
1448 
1449 }
1450 
1451 /*                                                                      */
1452 /*      POLYDEMO: Display a random pattern of polygons on the screen    */
1453 /*      until the user says enough.                                     */
1454 /*                                                                      */
1455 
1456 #define MaxPts          6               /* Maximum # of pts in polygon  */
1457 
PolyDemo(void)1458 void PolyDemo(void)
1459 {
1460   struct PTS poly[ MaxPts ];            /* Space to hold datapoints     */
1461   int color;                            /* Current drawing color        */
1462   int i;
1463 
1464   MainWindow( "DrawPoly / FillPoly Demonstration" );
1465   StatusLine( StopMsg);
1466 
1467   while( !kbhit() ){                    /* Repeat until a key is hit    */
1468 
1469     color = 1 + Random( MaxColors-1 );  /* Get a random color # (no blk)*/
1470     setfillstyle( Random(10), color );  /* Set a random line style      */
1471     setcolor( color );                  /* Set the desired color        */
1472 
1473     for( i=0 ; i<(MaxPts-1) ; i++ ){    /* Determine a random polygon   */
1474       poly[i].x = Random( MaxX );       /* Set the x coord of point     */
1475       poly[i].y = Random( MaxY );       /* Set the y coord of point     */
1476     }
1477 
1478     poly[i].x = poly[0].x;              /* last point = first point     */
1479     poly[i].y = poly[1].y;
1480 
1481     fillpoly( MaxPts, (int far *)poly );    /* Draw the actual polygon      */
1482   }                                     /* End of WHILE not KBHIT       */
1483 
1484   Pause();                              /* Wait for user's response     */
1485 
1486 }
1487 
1488 
1489 /*                                                                      */
1490 /*      SAYGOODBYE: Give a closing screen to the user before leaving.   */
1491 /*                                                                      */
1492 
SayGoodbye(void)1493 void SayGoodbye(void)
1494 {
1495   struct viewporttype viewinfo;         /* Structure to read viewport   */
1496   int h, w;
1497 
1498   MainWindow( "== Finale ==" );
1499 
1500   getviewsettings( &viewinfo );         /* Read viewport settings       */
1501   changetextstyle( TRIPLEX_FONT, HORIZ_DIR, 4 );
1502   settextjustify( CENTER_TEXT, CENTER_TEXT );
1503 
1504   h = viewinfo.bottom - viewinfo.top;
1505   w = viewinfo.right  - viewinfo.left;
1506   outtextxy( w/2, h/2, "That's all, folks!" );
1507 
1508   StatusLine( "Press any key to EXIT" );
1509   getch();
1510 
1511   cleardevice();                        /* Clear the graphics screen    */
1512 
1513 }
1514 
1515 /* ------------------------------------------------------------------- */
1516 /* ----                     New demo routines                     ---- */
1517 /* ------------------------------------------------------------------- */
1518 
1519 #ifdef __GNUC__
1520 #define rgb2col(r,g,b) setrgbcolor((r),(g),(b))
1521 #else
rgb2color_15(int r,int g,int b)1522 unsigned long rgb2color_15(int r, int g, int b) {
1523   return   ((r&0xf8)<<7)
1524 	 | ((g&0xf8)<<2)
1525 	 | ((b&0xf8)>>3);
1526 }
rgb2color_16(int r,int g,int b)1527 unsigned long rgb2color_16(int r, int g, int b) {
1528   return   ((r&0xf8)<<8)
1529 	 | ((g&0xfc)<<3)
1530 	 | ((b&0xf8)>>3);
1531 }
rgb2color_24(int r,int g,int b)1532 unsigned long rgb2color_24(int r, int g, int b) {
1533   return   ((r&0xff)<<16)
1534 	 | ((g&0xff)<< 8)
1535 	 | ((b&0xff)    );
1536 }
1537 #endif
1538 
BigColorDemo(void)1539 void BigColorDemo(void) {
1540   struct viewporttype vp;
1541   unsigned long tc;
1542   int color, height, width;
1543   int x, y;
1544 
1545 #ifdef __GNUC__
1546   MainWindow("High Color/True Color demonstration");
1547 
1548   getviewsettings( &vp );               /* Get the current window size  */
1549   height = (vp.bottom-vp.top)/4 - 1;
1550   width  = vp.right-vp.left;
1551   if (width < 1) width = 1;
1552 
1553   y = 1;
1554   for (x=width-1; x > 0; --x) {
1555     color = (x-1)*256/(width-1);
1556     /* red */
1557     tc = rgb2col(color,0,0);
1558     setcolor((int)tc);
1559     line(x,y,x,y+height-1);
1560     /* green */
1561     tc = rgb2col(0,color,0);
1562     setcolor((int)tc);
1563     line(x,y+height,x,y+2*height-1);
1564     /* blue */
1565     tc = rgb2col(0,0,color);
1566     setcolor((int)tc);
1567     line(x,y+2*height,x,y+3*height-1);
1568     /* gray */
1569     tc = rgb2col(color,color,color);
1570     setcolor((int)tc);
1571     line(x,y+3*height,x,y+4*height-1);
1572   }
1573   setcolor(WHITE);
1574 
1575   Pause();                              /* Pause for user's response    */
1576 #endif
1577 }
1578 
_max(int a,int b)1579 int _max(int a, int b)
1580 {
1581   return ( a>b ? a : b );
1582 }
1583 
_min(int a,int b)1584 int _min(int a, int b)
1585 {
1586   return ( a<b ? a : b );
1587 }
1588 
ShiftDac(char pal[][3])1589 void ShiftDac(char pal[][3])
1590 {
1591   int r,g,b;
1592   int k, l;
1593 
1594   for (k=0;k<=1;k++) {
1595     r=pal[254][0];
1596     g=pal[254][1];
1597     b=pal[254][2];
1598     for (l=254;l>=1;l--) {
1599       pal[l][0]=pal[l-1][0];
1600       pal[l][1]=pal[l-1][1];
1601       pal[l][2]=pal[l-1][2];
1602     }
1603     pal[1][0]=r;
1604     pal[1][1]=g;
1605     pal[1][2]=b;
1606   }
1607   for (k=0;k<=255;k++)
1608     setrgbpalette(k,pal[k][0],pal[k][1],pal[k][2]);
1609 }
1610 
PlayRGBpalette(void)1611 void PlayRGBpalette(void)
1612 /* This is partially copyrighted by COPYRIGHT(C) 1990 by H+BEDV  */
1613 {
1614   typedef char _PAL[256][3];
1615 
1616   int x,c, m, maxx, maxy, radius, height, ycenter;
1617   double pc;
1618   _PAL cpal;
1619   struct viewporttype     viewinfo;
1620 
1621   if ( getmaxcolor() != 255) return;
1622 
1623   for (c=1;c<=254;c++) {
1624     m= (c*3)>>1;
1625     if ((m<64)) {
1626       cpal[c][0]=63;
1627       cpal[c][1]=m;
1628       cpal[c][2]=0;
1629     }
1630     if ((m>63) && (m<128)) {
1631       cpal[c][0]=127-m;
1632       cpal[c][1]=63;
1633       cpal[c][2]=0;
1634     }
1635     if ((m>127) && (m<192)) {
1636       cpal[c][0]=0;
1637       cpal[c][1]=63;
1638       cpal[c][2]=m-128;
1639     }
1640     if ((m>191) && (m<256)) {
1641       cpal[c][0]=0;
1642       cpal[c][1]=255-m;
1643       cpal[c][2]=63;
1644     }
1645     if ((m>255) && (m<320)) {
1646       cpal[c][0]=m-256;
1647       cpal[c][1]=0;
1648       cpal[c][2]=63;
1649     }
1650     if ((m>319)) {
1651       cpal[c][0]=63;
1652       cpal[c][1]=0;
1653       cpal[c][2]=383-m;
1654     }
1655   }
1656   cpal[0][0]=0;
1657   cpal[0][1]=0;
1658   cpal[0][2]=0;
1659   cpal[255][0]=63;
1660   cpal[255][1]=63;
1661   cpal[255][2]=63;
1662   ShiftDac( cpal);
1663 
1664   MainWindowColor( "Play RGB palette", 255);
1665   getviewsettings( &viewinfo );
1666   maxx = abs(viewinfo.right-viewinfo.left)-1;
1667   maxy = abs(viewinfo.top-viewinfo.bottom)-1;
1668   setcolor(255);
1669 
1670   height = maxy/8;
1671   c=1;
1672   for (x=5; x <= maxx+1-5; ++x) {
1673     setcolor(c);
1674     if (++c > 254) c = 1;
1675     line(x,maxy-5,x,maxy-5-height);
1676   }
1677 
1678   pc=1.0;
1679   ycenter = (maxy-5-height) / 2;
1680   radius = _min((int)((maxy-5-height)/AspectRatio), maxx)*9/20;
1681   for (x=0;x<=356;x++) {
1682     setcolor((int)pc);
1683     setfillstyle(SOLID_FILL,(int)pc);
1684     pieslice(maxx/2,ycenter,x,x+4,radius);
1685     pc=pc+254.0/360.0;
1686   }
1687 
1688   StatusLineColor( StopMsg, 255);
1689 
1690   do {
1691     ShiftDac(cpal);
1692   } while (!(kbhit()));
1693   if ( getch() == ESC) {
1694     closegraph();
1695     exit(1);
1696   }
1697   for (c=1; c < 255; ++c) {
1698     cpal[c][0] = _dac_g256[c][0];
1699     cpal[c][1] = _dac_g256[c][1];
1700     cpal[c][2] = _dac_g256[c][2];
1701   }
1702 
1703   StatusLineColor( PauseMsg, 255);
1704   do {
1705     ShiftDac(cpal);
1706   } while (!(kbhit()));
1707 
1708   setbkcolor(BLACK);
1709   clearviewport();
1710   setrgbdefaults();
1711   Pause();                              /* Pause for user to read screen*/
1712 }
1713 
1714 /* The Sierpinski demo was mainly taken from
1715    N. Wirth: Algorithmen und Datenstrukturen  */
1716 #define SIRP_N     4
1717 #define SIRP_H0    320
1718 
1719 static int SIRP_x, SIRP_y, h;
1720 
1721 static void SIRP_a(int i);
1722 static void SIRP_b(int i);
1723 static void SIRP_c(int i);
1724 static void SIRP_d(int i);
1725 
SIRP_a(int i)1726 static void SIRP_a(int i)
1727 {
1728   if (i>0) {
1729     SIRP_a(i-1); SIRP_x += h;   SIRP_y -= h; lineto( SIRP_x, SIRP_y);
1730     SIRP_b(i-1); SIRP_x += 2*h;              lineto( SIRP_x, SIRP_y);
1731     SIRP_d(i-1); SIRP_x += h;   SIRP_y += h; lineto( SIRP_x, SIRP_y);
1732     SIRP_a(i-1);
1733   }
1734 }
1735 
SIRP_b(int i)1736 static void SIRP_b(int i)
1737 {
1738   if (i>0) {
1739     SIRP_b(i-1); SIRP_x -= h; SIRP_y -= h;   lineto( SIRP_x, SIRP_y);
1740     SIRP_c(i-1);              SIRP_y -= 2*h; lineto( SIRP_x, SIRP_y);
1741     SIRP_a(i-1); SIRP_x += h; SIRP_y -= h;   lineto( SIRP_x, SIRP_y);
1742     SIRP_b(i-1);
1743   }
1744 }
1745 
SIRP_c(int i)1746 static void SIRP_c(int i)
1747 {
1748   if (i>0) {
1749     SIRP_c(i-1); SIRP_x -= h;   SIRP_y += h; lineto( SIRP_x, SIRP_y);
1750     SIRP_d(i-1); SIRP_x -= 2*h;              lineto( SIRP_x, SIRP_y);
1751     SIRP_b(i-1); SIRP_x -= h;   SIRP_y -= h; lineto( SIRP_x, SIRP_y);
1752     SIRP_c(i-1);
1753   }
1754 }
1755 
SIRP_d(int i)1756 static void SIRP_d(int i)
1757 {
1758   if (i>0) {
1759     SIRP_d(i-1); SIRP_x += h; SIRP_y += h;   lineto( SIRP_x, SIRP_y);
1760     SIRP_a(i-1);              SIRP_y += 2*h; lineto( SIRP_x, SIRP_y);
1761     SIRP_c(i-1); SIRP_x -= h; SIRP_y += h;   lineto( SIRP_x, SIRP_y);
1762     SIRP_d(i-1);
1763   }
1764 }
1765 
sierpinski(void)1766 void sierpinski(void)
1767 {
1768   int i, h0, x0, y0, bx, by;
1769   int color, border;
1770   struct viewporttype vp;
1771   struct fillsettingstype fs;
1772 
1773   if (MaxColors < 16)
1774     return;
1775 
1776   MainWindow( "Floodfill demo");
1777   StatusLine(PauseMsg);
1778   getviewsettings( &vp);
1779   getfillsettings( &fs);
1780 
1781   setviewport( (bx=_max((getmaxx() - SIRP_H0) / 2, vp.left)),
1782 	       (by=_max((getmaxy() - SIRP_H0) / 2, vp.top)),
1783 	       _min((getmaxx() + SIRP_H0) / 2 + 5, vp.right),
1784 	       _min((getmaxy() + SIRP_H0) / 2 + 5, vp.bottom),
1785 	       TRUE );
1786 
1787   border = _ega_color(YELLOW);
1788   setcolor( border);
1789   h0 = SIRP_H0;
1790   h = h0 / 4;
1791   x0 = 2*h;
1792   y0 = 3*h;
1793   for (i=1; i <= SIRP_N; ++i) {
1794     x0 -= h;
1795     h /= 2;
1796     y0 += h;
1797     SIRP_x = x0; SIRP_y = y0;
1798     moveto( SIRP_x, SIRP_y);
1799     SIRP_a(i); SIRP_x += h; SIRP_y -= h; lineto(SIRP_x,SIRP_y);
1800     SIRP_b(i); SIRP_x -= h; SIRP_y -= h; lineto(SIRP_x,SIRP_y);
1801     SIRP_c(i); SIRP_x -= h; SIRP_y += h; lineto(SIRP_x,SIRP_y);
1802     SIRP_d(i); SIRP_x += h; SIRP_y += h; lineto(SIRP_x,SIRP_y);
1803   }
1804   setviewport( vp.left, vp.top, vp.right, vp.bottom, vp.clip);
1805   bx += h0/2 - vp.left;
1806   by += h0/2 - vp.top;
1807   color = BLUE-1;
1808   do {
1809     if (++color >= YELLOW) color = BLUE;
1810     setfillstyle(Random(USER_FILL-1)+1, _ega_color(color));
1811     floodfill( bx, by, border);
1812     if (kbhit()) break;
1813     floodfill(  1,  1, border);
1814   } while ( !kbhit());
1815   setfillstyle( fs.pattern, fs.color);
1816 
1817   Pause();                              /* Pause for user to read screen*/
1818 }
1819 
1820 #ifdef __GNUC__
1821 /* Borland C died frequently on this demo */
snake(void)1822 void snake(void)
1823 {
1824   int i, x0, y0, x1, y1, x, y;
1825   int color, border;
1826   struct viewporttype vp;
1827   struct fillsettingstype fs;
1828   int dx, dy;
1829 
1830   if (MaxColors < 16)
1831     return;
1832 
1833   MainWindow( "Floodfill demo 2");
1834   StatusLine(PauseMsg);
1835   getviewsettings( &vp);
1836   getfillsettings( &fs);
1837 
1838   x0 = 0; y0 = 0;
1839   x1 = getmaxx(); y1 = getmaxy();
1840   if (x1-x0 < y1-y0) {
1841     dx = (x1-x0) / 24;
1842     dy = (int)(dx*AspectRatio + 0.5);
1843   } else {
1844     dy = (y1-y0) / 24;
1845     dx = (int)(dy/AspectRatio + 0.5);
1846   }
1847 
1848   border = _ega_color(YELLOW);
1849   setcolor( border);
1850 
1851   moveto(x=(x1-x0)/2, y=(y1-y0)/2);
1852   i = 0;
1853   while (x0<x && x<x1 && y0<y && y<y1) {
1854     ++i;
1855     if ((i&1) != 0) {
1856       y -= i*dy; lineto(x, y);
1857       x -= i*dx; lineto(x, y);
1858     } else {
1859       y += i*dy; lineto(x, y);
1860       x += i*dx; lineto(x, y);
1861     }
1862   }
1863 
1864   x = (x1-x0 - dx)/2;
1865   y = (y1-y0 + dy)/2;
1866   color = BLUE-1;
1867   do {
1868     if (++color >= YELLOW) color = BLUE;
1869     setfillstyle(Random(USER_FILL-1)+1, _ega_color(color));
1870     floodfill( x, y, border);
1871     delay(500);
1872   } while ( !kbhit());
1873   setfillstyle( fs.pattern, fs.color);
1874 
1875   Pause();                              /* Pause for user to read screen*/
1876 }
1877 #endif
1878 
RandomSolidBars(void)1879 void RandomSolidBars(void)
1880 {
1881   int color;
1882 
1883   MainWindow( "Random Solid/Line Bars" );
1884   StatusLine( PauseMsg );               /* Put msg at bottom of screen   */
1885   while( !kbhit() ){                    /* Until user enters a key...   */
1886     color = Random( MaxColors-1 )+1;
1887     setcolor( color );
1888     /* SOLID_FILL && LINE_FILL are much faster */
1889     setfillstyle( SOLID_FILL+Random(2), color );
1890     bar3d( Random( getmaxx() ), Random( getmaxy() ),
1891 	   Random( getmaxx() ), Random( getmaxy() ), 0, OFF);
1892   }
1893 
1894   Pause();                              /* Pause for user's response    */
1895 
1896 }
1897 
1898 #define Memory          100
1899 #define Windows         4
1900 
1901 typedef int ColorList[Windows];
1902 
1903 
1904 typedef struct _REC_Line {
1905   int LX1, LY1, LX2, LY2;
1906   ColorList LColor;
1907 } _REC_Line;
1908 
1909 /* Local variables for LinePlay: */
1910 struct LOC_LinePlay {
1911   int ViewXmax, ViewYmax;
1912   _REC_Line Line[Memory];
1913   int X1, X2, Y1, Y2, CurrentLine, ColorCount, IncrementCount, DeltaX1,
1914       DeltaY1, DeltaX2, DeltaY2;
1915   ColorList Colors;
1916   int MaxDelta;
1917 } ;
1918 
AdjustX(int * X,int * DeltaX,struct LOC_LinePlay * LINK)1919 void AdjustX(int *X, int *DeltaX, struct LOC_LinePlay *LINK)
1920 {
1921   int TestX;
1922 
1923   TestX = *X + *DeltaX;
1924   if (TestX < 1 || TestX > LINK->ViewXmax) {
1925     TestX = *X;
1926     *DeltaX = -*DeltaX;
1927   }
1928   *X = TestX;
1929 }
1930 
AdjustY(int * Y,int * DeltaY,struct LOC_LinePlay * LINK)1931 void AdjustY(int *Y, int *DeltaY, struct LOC_LinePlay *LINK)
1932 {
1933   int TestY;
1934 
1935   TestY = *Y + *DeltaY;
1936   if (TestY < 1 || TestY > LINK->ViewYmax) {
1937     TestY = *Y;
1938     *DeltaY = -*DeltaY;
1939   }
1940   *Y = TestY;
1941 }
1942 
RandColor(void)1943 int RandColor(void)
1944 {
1945   return Random(MaxColors-1) + 1;
1946 }
1947 
SelectNewColors(struct LOC_LinePlay * LINK)1948 void SelectNewColors(struct LOC_LinePlay *LINK)
1949 {
1950   LINK->Colors[0] = RandColor();
1951   LINK->Colors[1] = RandColor();
1952   LINK->Colors[2] = RandColor();
1953   LINK->Colors[3] = RandColor();
1954   LINK->ColorCount = (Random(5) + 1) * 3;
1955 }
1956 
SelectNewDeltaValues(struct LOC_LinePlay * LINK)1957 void SelectNewDeltaValues(struct LOC_LinePlay *LINK)
1958 {
1959   LINK->DeltaX1 = Random(LINK->MaxDelta) - LINK->MaxDelta / 2;
1960   LINK->DeltaX2 = Random(LINK->MaxDelta) - LINK->MaxDelta / 2;
1961   LINK->DeltaY1 = Random(LINK->MaxDelta) - LINK->MaxDelta / 2;
1962   LINK->DeltaY2 = Random(LINK->MaxDelta) - LINK->MaxDelta / 2;
1963   LINK->IncrementCount = (Random(4) + 1) * 2;
1964 }
1965 
SaveCurrentLine(int * CurrentColors,struct LOC_LinePlay * LINK)1966 void SaveCurrentLine(int *CurrentColors, struct LOC_LinePlay *LINK)
1967 {
1968   _REC_Line *WITH;
1969 
1970   WITH = &LINK->Line[LINK->CurrentLine - 1];
1971   WITH->LX1 = LINK->X1;
1972   WITH->LY1 = LINK->Y1;
1973   WITH->LX2 = LINK->X2;
1974   WITH->LY2 = LINK->Y2;
1975   memcpy(WITH->LColor, CurrentColors, sizeof(ColorList));
1976 }
1977 
Draw(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short color)1978 void Draw(unsigned short x1, unsigned short y1, unsigned short x2,
1979 		unsigned short y2, unsigned short color)
1980 {
1981   setcolor(color);
1982   line(x1, y1, x2, y2);
1983 }
1984 
Updateline(struct LOC_LinePlay * LINK)1985 void Updateline(struct LOC_LinePlay *LINK)
1986 {
1987   LINK->CurrentLine++;
1988   if (LINK->CurrentLine > Memory)
1989     LINK->CurrentLine = 1;
1990   LINK->ColorCount--;
1991   LINK->IncrementCount--;
1992 }
1993 
DrawCurrentLine(struct LOC_LinePlay * LINK)1994 void DrawCurrentLine(struct LOC_LinePlay *LINK)
1995 {
1996   Draw(LINK->X1, LINK->Y1, LINK->X2, LINK->Y2, LINK->Colors[0]);
1997   Draw(LINK->ViewXmax - LINK->X1, LINK->Y1, LINK->ViewXmax - LINK->X2,
1998        LINK->Y2, LINK->Colors[1]);
1999   Draw(LINK->X1, LINK->ViewYmax - LINK->Y1, LINK->X2,
2000        LINK->ViewYmax - LINK->Y2, LINK->Colors[2]);
2001   Draw(LINK->ViewXmax - LINK->X1, LINK->ViewYmax - LINK->Y1,
2002        LINK->ViewXmax - LINK->X2, LINK->ViewYmax - LINK->Y2, LINK->Colors[3]);
2003   SaveCurrentLine(LINK->Colors, LINK);
2004 }
2005 
EraseCurrentLine(struct LOC_LinePlay * LINK)2006 void EraseCurrentLine(struct LOC_LinePlay *LINK)
2007 {
2008   _REC_Line *WITH;
2009 
2010   WITH = &LINK->Line[LINK->CurrentLine - 1];
2011   Draw(WITH->LX1, WITH->LY1, WITH->LX2, WITH->LY2, 0);
2012   Draw(LINK->ViewXmax - WITH->LX1, WITH->LY1, LINK->ViewXmax - WITH->LX2,
2013        WITH->LY2, 0);
2014   Draw(WITH->LX1, LINK->ViewYmax - WITH->LY1, WITH->LX2,
2015        LINK->ViewYmax - WITH->LY2, 0);
2016   Draw(LINK->ViewXmax - WITH->LX1, LINK->ViewYmax - WITH->LY1,
2017        LINK->ViewXmax - WITH->LX2, LINK->ViewYmax - WITH->LY2, 0);
2018 }
2019 
DoArt(struct LOC_LinePlay * LINK)2020 void DoArt(struct LOC_LinePlay *LINK)
2021 {
2022   SelectNewColors(LINK);
2023   do {
2024     EraseCurrentLine(LINK);
2025     if (LINK->ColorCount == 0)
2026       SelectNewColors(LINK);
2027     if (LINK->IncrementCount == 0)
2028       SelectNewDeltaValues(LINK);
2029     AdjustX(&LINK->X1, &LINK->DeltaX1, LINK);
2030     AdjustX(&LINK->X2, &LINK->DeltaX2, LINK);
2031     AdjustY(&LINK->Y1, &LINK->DeltaY1, LINK);
2032     AdjustY(&LINK->Y2, &LINK->DeltaY2, LINK);
2033     if (Random(5) == 3) {
2034       LINK->X1 = (LINK->X1 + LINK->X2) / 2;   /* shorten the lines */
2035       LINK->Y2 = (LINK->Y1 + LINK->Y2) / 2;
2036     }
2037     DrawCurrentLine(LINK);
2038     Updateline(LINK);
2039   } while (!kbhit());
2040 }
2041 
2042 
LinePlay(void)2043 void LinePlay(void)
2044 {
2045   struct LOC_LinePlay V;
2046   struct viewporttype ViewInfo;
2047   int StartX, StartY, I;
2048   _REC_Line *WITH;
2049 
2050   MainWindow("Line demonstration");
2051   StatusLine("Esc aborts or press a key ...");
2052   getviewsettings(&ViewInfo);
2053   V.CurrentLine = 1;
2054   V.ColorCount = 0;
2055   V.IncrementCount = 0;
2056   V.MaxDelta = 16;
2057   V.ViewXmax = ViewInfo.right - 1;
2058   V.ViewYmax = ViewInfo.bottom - 3;
2059   StartX = ViewInfo.right / 2;
2060   StartY = ViewInfo.bottom / 2;
2061   for (I = 0; I < Memory; I++) {
2062     WITH = &V.Line[I];
2063     WITH->LX1 = StartX;
2064     WITH->LX2 = StartX;
2065     WITH->LY1 = StartY;
2066     WITH->LY2 = StartY;
2067   }
2068   V.X1 = StartX;
2069   V.X2 = StartX;
2070   V.Y1 = StartY;
2071   V.Y2 = StartY;
2072   DoArt(&V);
2073   Pause();
2074 }
2075 
2076 #undef Memory
2077 #undef Windows
2078 
2079 /* Local variables for ColorPlay: */
2080 struct LOC_ColorPlay {
2081   unsigned short Color, Width, Height;
2082   struct viewporttype ViewInfo;
2083 } ;
2084 
Int2Str(char * Result,long L)2085 char *Int2Str(char *Result, long L)
2086 {
2087   /* Converts an integer to a string for use with OutText, OutTextXY */
2088   char S[256];
2089 
2090   sprintf(S, "%ld", L);
2091   return strcpy(Result, S);
2092 }  /* Int2Str */
2093 
2094 
DrawBox__(unsigned short X,unsigned short Y,struct LOC_ColorPlay * LINK)2095 void DrawBox__(unsigned short X, unsigned short Y,
2096 		     struct LOC_ColorPlay *LINK)
2097 {
2098   int bottom;
2099   char STR1[256];
2100 
2101   setfillstyle(SOLID_FILL, LINK->Color);
2102   setcolor(LINK->Color);
2103   if (LINK->Height / 2 >= textheight("M") + 4)
2104     bottom = Y + LINK->Height;
2105   else
2106     bottom = Y + LINK->Height / 2 * 3 - textheight("M") - 5;
2107   bar(X, Y, X + LINK->Width, bottom);
2108   rectangle(X, Y, X + LINK->Width, bottom);
2109   LINK->Color = getcolor();
2110   if (LINK->Color == 0) {
2111     setcolor(MaxColors);
2112     rectangle(X, Y, X + LINK->Width, bottom);
2113   }
2114   setcolor(WHITE);
2115   outtextxy(X + LINK->Width / 2, bottom + 3, Int2Str(STR1, LINK->Color));
2116   LINK->Color = (LINK->Color + 1) % (MaxColors + 1);
2117 }  /* DrawBox */
2118 
2119 
ColorPlay(void)2120 void ColorPlay(void)
2121 {
2122   /* Display all of the colors available for the current driver and mode */
2123   struct LOC_ColorPlay V;
2124   unsigned short X, Y, I, J;
2125 
2126   if (MaxColors != 256) {
2127     ColorDemo();
2128     if (MaxColors < 256)
2129       return;
2130   }
2131   if (MaxColors > 256) {
2132     BigColorDemo();
2133     return;
2134   }
2135   MainWindow("Color demonstration");
2136   V.Color = 1;
2137   getviewsettings(&V.ViewInfo);
2138   V.Width = (V.ViewInfo.right + 1) / 53 * 2;
2139   V.Height = (V.ViewInfo.bottom - 10) / 47 * 2;
2140   if (V.Height < textheight("M") + 4)
2141     V.Height = textheight("M") + 4;
2142   if (V.Width < textwidth("M") * 2)
2143     V.Width = textwidth("M") * 2;
2144   X = V.Width / 2;
2145   Y = V.Height / 2;
2146   for (J = 1; J <= 15; J++) {
2147     for (I = 1; I <= 17; I++) {
2148       if (!kbhit())
2149 	DrawBox__(X, Y, &V);
2150       X += V.Width / 2 * 3;
2151     }
2152     X = V.Width / 2;
2153     Y += V.Height / 2 * 3;
2154   }
2155   Pause();
2156 }  /* ColorPlay */
2157 
2158 
2159 
2160 
2161 /*                                                                      */
2162 /*      Begin main function                                             */
2163 /*                                                                      */
2164 
main(void)2165 int main(void)
2166 {
2167 
2168 #if 0 && defined(__GNUC__)
2169   registerbgifont( &_bold_font);
2170   registerbgifont( &_euro_font);
2171   registerbgifont( &_goth_font);
2172   registerbgifont( &_lcom_font);
2173   registerbgifont( &_litt_font);
2174   registerbgifont( &_sans_font);
2175   registerbgifont( &_scri_font);
2176   registerbgifont( &_simp_font);
2177   registerbgifont( &_trip_font);
2178   registerbgifont( &_tscr_font);
2179 #endif
2180   Initialize();                 /* Set system into Graphics mode        */
2181   ReportStatus();               /* Report results of the initialization */
2182   ColorPlay();                  /* Begin actual demonstration           */
2183   if( GraphDriver==EGA || GraphDriver==EGA64 || GraphDriver==VGA )
2184     PaletteDemo();
2185   PutPixelDemo();
2186   PutImageDemo();
2187   Bar3DDemo();
2188   BarDemo();
2189   RandomBars();
2190   RandomSolidBars();
2191   sierpinski();
2192 #ifdef __GNUC__
2193   snake();
2194 #endif
2195   ArcDemo();
2196   CircleDemo();
2197   PieDemo();
2198   PlayRGBpalette();
2199   LinePlay();
2200   LineRelDemo();
2201   LineToDemo();
2202   LineStyleDemo();
2203   UserLineStyleDemo();
2204   TextDump();
2205   TextDemo();
2206   CRTModeDemo();
2207   FillStyleDemo();
2208   FillPatternDemo();
2209   PolyDemo();
2210   SayGoodbye();                 /* Give user the closing screen         */
2211   closegraph();                 /* Return the system to text mode       */
2212   return(0);
2213 }
2214 
2215