00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #include <stdio.h>
00091 #include <stdlib.h>
00092 #include <string.h>
00093
00094 #include "arch.h"
00095 #include "graph.h"
00096 #include "uti.h"
00097
00098
00099
00100 #ifdef __OS_UNIX__
00101
00102 #define GIF
00103 #else
00104 #define BGI
00105 #endif
00106
00107
00108
00109 #define DEFGIF "screen.gif"
00110 #define DEFW 640
00111 #define DEFH 480
00112
00113
00114
00115 void Graph::initgraph( int WW, int HH )
00116 {
00117 W=WW; H=HH;
00118 setdefpalette();
00119 setcolor(GR_WHITE);
00120 setbkcolor(GR_BLACK);
00121 moveto(0,0);
00122 clearviewport();
00123 }
00124
00125 void Graph::setdefpalette( void )
00126 {
00127 static int c[16][3] = {
00128 { 0, 0, 0}, { 0, 0,160}, { 0,167, 0}, { 0,167,160},
00129 {160, 0, 0}, {160, 0,160}, {160, 80, 0}, {160,167,160},
00130 { 80, 80, 80}, { 80, 80,255}, { 80,248, 80}, { 80,248,255},
00131 {255, 80, 80}, {255, 80,255}, {255,248, 80}, {255,255,255}
00132 };
00133 int i;
00134
00135 for (i=0; i<16; i++) setcolorrgb(i,c[i][0],c[i][1],c[i][2]);
00136 }
00137
00138
00139
00140 #ifdef X11
00141
00142 #include "vogle.h"
00143 #include <math.h>
00144
00145 class Vogle: public Graph {
00146 private:
00147 float x2vx( int x ) { return (float)x/(float)W*2. - 1.; };
00148 float y2vy( int y ) { return 1. - (float)y/(float)H*2.; };
00149 int vx2x( float x ) { return (int)((x+1)*0.5*W+0.5); };
00150 int vy2y( float y ) { return (int)((1-y)*0.5*H+0.5); };
00151 int flushstat;
00152 protected:
00153 void initgraph( int W, int H );
00154 void closegraph( void );
00155 public:
00156 Vogle() { };
00157
00158 void setcolor( int color );
00159 int getncolors( void );
00160 void setcolorrgb( int color, int r, int g, int b );
00161
00162 void putpixel( int x, int y, int color=-1 );
00163 void line( int x1, int y1, int x2, int y2, int color=-1 );
00164 void rectangle( int x1, int y1, int x2, int y2, int color=-1 );
00165 void bar( int x1, int y1, int x2, int y2, int color=-1, int bkcolor=-1 );
00166
00167 void ellipse( int x, int y, int rx, int ry, int color=-1 );
00168
00169 void bufferon( void );
00170 void bufferflush( void );
00171 void bufferoff( int reset=0 );
00172
00173 int kbhit( void );
00174 int getkey( void );
00175 };
00176
00177 void Vogle::initgraph( int WW, int HH )
00178 {
00179 W = WW; if (W<2) W=2;
00180 H = HH; if (H<2) H=2;
00181
00182 prefsize(W+16,H+16);
00183 vinit("X11");
00184
00185 float w, h;
00186 getdisplaysize(&w,&h);
00187 if ((w!=W)||(h!=H)) {
00188 vexit();
00189 prefsize(W+16+(W-w),H+16+(H-h));
00190 vinit("X11");
00191 }
00192
00193 expandviewport();
00194 viewport(-1.,1., -1.,1.);
00195 frontbuffer();
00196 font("small");
00197 flushstat=0;
00198 polyfill(0);
00199 Graph::initgraph(W,H);
00200 }
00201
00202 void Vogle::closegraph( void ) { vexit(); }
00203
00204 void Vogle::setcolor( int col ) { color(col); Graph::setcolor(col); };
00205 int Vogle::getncolors( void ) { return 1 << getdepth(); };
00206 void Vogle::setcolorrgb( int color, int r, int g, int b ) { mapcolor(color,r,g,b); };
00207
00208 void Vogle::putpixel( int x, int y, int col )
00209 {
00210 if ((col>=0) && (col!=ccolor)) {
00211 color(col);
00212 point2(x2vx(x),y2vy(y));
00213 color(ccolor);
00214 }
00215 else
00216 point2(x2vx(x),y2vy(y));
00217 }
00218
00219 void Vogle::line( int x1, int y1, int x2, int y2, int col )
00220 {
00221 if ((col>=0) && (col!=ccolor)) {
00222 color(col);
00223 move2(x2vx(x1),y2vy(y1));
00224 draw2(x2vx(x2),y2vy(y2));
00225 color(ccolor);
00226 }
00227 else {
00228 move2(x2vx(x1),y2vy(y1));
00229 draw2(x2vx(x2),y2vy(y2));
00230 }
00231 }
00232
00233 void Vogle::ellipse( int x, int y, int rx, int ry, int col )
00234 {
00235 #define NSEC 32
00236 float fx, fy, frx, fry;
00237 int i;
00238
00239 color((col<0)?ccolor:col);
00240 fx = x2vx(x);
00241 fy = y2vy(y);
00242 frx = x2vx(rx)-x2vx(0);
00243 fry = y2vy(ry)-y2vy(0);
00244 bufferon();
00245 move2(fx+frx,fy);
00246 for (i=1; i<=NSEC; i++) {
00247 float a=((2.*M_PI)/NSEC)*i;
00248 draw2(fx+frx*cos(a),fy+fry*sin(a));
00249 }
00250 bufferoff();
00251 color(ccolor);
00252 #undef NSEC
00253 }
00254
00255 void Vogle::rectangle( int x1, int y1, int x2, int y2, int col )
00256 {
00257 color((col<0)?ccolor:col);
00258 rect(x2vx(x1),y2vy(y1),x2vx(x2),y2vy(y2));
00259 color(ccolor);
00260 }
00261
00262 void Vogle::bar( int x1, int y1, int x2, int y2, int col, int bkcol )
00263 {
00264 float xx1, yy1, xx2, yy2;
00265 color((bkcol<0)?cbkcolor:bkcol);
00266 polyfill(1);
00267 rect(xx1=x2vx(x1),yy1=y2vy(y1),xx2=x2vx(x2),yy2=y2vy(y2));
00268 polyfill(0);
00269 color((col<0)?ccolor:col);
00270 rect(xx1,yy1,xx2,yy2);
00271 color(ccolor);
00272 }
00273
00274 void Vogle::bufferon( void ) { if (!flushstat) vsetflush(0); flushstat++; }
00275 void Vogle::bufferflush( void ) { vflush(0); }
00276 void Vogle::bufferoff( int reset ) {
00277 if (flushstat) flushstat--;
00278 if (reset) flushstat=0;
00279 if (!flushstat) { vflush(0); vsetflush(1); }
00280 }
00281 int Vogle::kbhit( void ) { return checkkey(); };
00282 int Vogle::getkey( void ) { vflush(0); int k = ::getkey(); return k; };
00283
00284 #endif
00285
00286
00287
00288 #ifdef GIF
00289
00290 #include "gd.h"
00291
00292 class Gif: public Graph {
00293 private:
00294 gdImagePtr im;
00295 char *dest;
00296 protected:
00297 void initgraph( int W, int H );
00298 void closegraph( void );
00299 public:
00300 Gif( char *name=0 ) { if (name) dest=strdup(name); else dest=NULL; im=0; };
00301 ~Gif( void ) { closegraph(); setfile(); }
00302
00303 int getncolors( void );
00304 void setcolorrgb( int color, int r, int g, int b );
00305
00306 void putpixel( int x, int y, int color=-1 );
00307 void line( int x1, int y1, int x2, int y2, int color=-1 );
00308 void rectangle( int x1, int y1, int x2, int y2, int color=-1 );
00309 void bar( int x1, int y1, int x2, int y2, int color=-1, int bkcolor=-1 );
00310
00311 void ellipse( int x, int y, int rx, int ry, int color=-1 );
00312
00313 void setfile( const char *dest=NULL );
00314 const char * getfile( void );
00315 void savefile( const char *dest=NULL );
00316
00317 int getkey( void );
00318 };
00319
00320 void Gif::initgraph( int WW, int HH )
00321 {
00322 int i;
00323
00324 fprintf(stderr,"Rendering GIF image.\n");
00325 W = WW; if (W<2) W=2;
00326 H = HH; if (H<2) H=2;
00327
00328 im = gdImageCreate(WW,HH);
00329 gdImageInterlace(im,0);
00330
00331 for (i=0; i<256; i++)
00332 gdImageColorAllocate(im,i,i,i);
00333
00334 Graph::initgraph(W,H);
00335 }
00336
00337 void Gif::closegraph( void )
00338 {
00339 if (!im) return;
00340 savefile();
00341 gdImageDestroy(im);
00342 im=0;
00343 fprintf(stderr,"GIF image closed.\n");
00344 }
00345
00346 int Gif::getncolors( void ) { return 256; };
00347
00348 void Gif::setcolorrgb( int color, int r, int g, int b )
00349 {
00350 gdImageColorDeallocate(im,color);
00351 gdImageColorAllocate(im,r,g,b);
00352 };
00353
00354 void Gif::putpixel( int x, int y, int col )
00355 {
00356 if (col>=0) gdImageSetPixel(im,x,y,col);
00357 else gdImageSetPixel(im,x,y,ccolor);
00358 }
00359
00360 void Gif::line( int x1, int y1, int x2, int y2, int col )
00361 {
00362 if (col>=0) gdImageLine(im,x1,y1,x2,y2,col);
00363 else gdImageLine(im,x1,y1,x2,y2,ccolor);
00364 }
00365
00366 void Gif::rectangle( int x1, int y1, int x2, int y2, int col )
00367 {
00368 if (col>=0) gdImageRectangle(im,x1,y1,x2,y2,col);
00369 else gdImageRectangle(im,x1,y1,x2,y2,ccolor);
00370 }
00371
00372 void Gif::bar( int x1, int y1, int x2, int y2, int col, int bkcol )
00373 {
00374 if (bkcol>=0) gdImageFilledRectangle(im,x1,y1,x2,y2,bkcol);
00375 else gdImageFilledRectangle(im,x1,y1,x2,y2,cbkcolor);
00376
00377 if (col>=0) gdImageRectangle(im,x1,y1,x2,y2,col);
00378 else gdImageRectangle(im,x1,y1,x2,y2,ccolor);
00379 }
00380
00381 void Gif::ellipse( int x, int y, int rx, int ry, int col )
00382 {
00383 if (col>=0) gdImageArc(im,x,y,rx,ry,0,360,col);
00384 else gdImageArc(im,x,y,rx,ry,0,360,ccolor);
00385 }
00386
00387 int Gif::getkey( void )
00388 {
00389 fprintf(stderr,"Current image (%s) being saved...",getfile());
00390 savefile();
00391 fprintf(stderr,"OK!, press KEY and RETURN to continue...");
00392 return getchar();
00393 };
00394
00395 void Gif::setfile( const char *name )
00396 {
00397 if (dest) free(dest);
00398 dest = NULL;
00399 if (name) dest = strdup(name);
00400 }
00401
00402 void Gif::savefile( const char *name )
00403 {
00404 if (name) setfile(name);
00405
00406 FILE * out = fopen((dest?dest:DEFGIF),"wb");
00407 gdImageGif(im, out);
00408 fclose(out);
00409 }
00410
00411 const char *Gif::getfile( void )
00412 {
00413 if (dest) return dest;
00414 return DEFGIF;
00415 }
00416
00417 #endif
00418
00419
00420
00421 #ifdef BGI
00422
00423 #include <graphics.h>
00424 #include <bgi.h>
00425 #include <conio.h>
00426
00427 class Bgi: public Graph {
00428 private:
00429 protected:
00430 void initgraph( int W, int H );
00431 void closegraph( void );
00432 public:
00433 Bgi() { };
00434 void clearviewport( int color=-1 ) { Graph::clearviewport(color); }
00435 void clearviewport( int x1, int y1, int x2, int y2, int color=-1 );
00436
00437 void setcolor( int color );
00438 int getncolors( void );
00439 void setcolorrgb( int color, int r, int g, int b );
00440
00441 void putpixel( int x, int y, int color=-1 );
00442 void line( int x1, int y1, int x2, int y2, int color=-1 );
00443 void rectangle( int x1, int y1, int x2, int y2, int color=-1 );
00444 void bar( int x1, int y1, int x2, int y2, int color=-1, int bkcolor=-1 );
00445 void circle( int x, int y, int r, int color=-1 );
00446 void ellipse( int x, int y, int rx, int ry, int color=-1 );
00447
00448 int kbhit( void );
00449 int getkey( void );
00450 };
00451
00452 void Bgi::initgraph( int WW, int HH )
00453 {
00454 int i;
00455 int gd = VGA;
00456 int gm = VGAHI;
00457
00458 register_VGA();
00459 ::initgraph(&gd,&gm,"");
00460
00461 W = ::getmaxx()+1;
00462 H = ::getmaxy()+1;
00463 if (W>WW) W=WW;
00464 if (H>HH) H=HH;
00465
00466 for (i=0; i<16; i++) ::setpalette(i,i);
00467
00468 Graph::initgraph(W,H);
00469 }
00470
00471 void Bgi::closegraph( void ) { ::closegraph(); }
00472
00473 void Bgi::clearviewport( int x1, int y1, int x2, int y2, int color )
00474 {
00475 if (color>=0) ::setbkcolor(color);
00476 else ::setbkcolor(cbkcolor);
00477
00478 ::setviewport(x1,y1,x2,y2,1);
00479 ::clearviewport();
00480 }
00481
00482 void Bgi::setcolor( int col ) { ::setcolor(col); Graph::setcolor(col); };
00483 int Bgi::getncolors( void ) { return 16; };
00484
00485 void Bgi::setcolorrgb( int color, int r, int g, int b )
00486 {
00487 r=(r+2)>>2;
00488 g=(g+2)>>2;
00489 b=(b+2)>>2;
00490 r=(r<0?0:r);
00491 g=(g<0?0:g);
00492 b=(b<0?0:b);
00493 r=(r>63?63:r);
00494 g=(g>63?63:g);
00495 b=(b>63?63:b);
00496
00497 setrgbpalette(color,r,g,b);
00498 };
00499
00500 void Bgi::putpixel( int x, int y, int col )
00501 {
00502 if (col>=0) ::putpixel(x,y,col);
00503 else ::putpixel(x,y,ccolor);
00504 }
00505
00506 void Bgi::line( int x1, int y1, int x2, int y2, int col )
00507 {
00508 if ((col>=0) && (col!=ccolor)) {
00509 ::setcolor(col);
00510 ::line(x1,y1,x2,y2);
00511 ::setcolor(ccolor);
00512 }
00513 else
00514 ::line(x1,y1,x2,y2);
00515 }
00516
00517 void Bgi::circle( int x, int y, int r, int col )
00518 {
00519 if ((col>=0) && (col!=ccolor)) {
00520 ::setcolor(col);
00521 ::circle(x,y,r);
00522 ::setcolor(ccolor);
00523 }
00524 else
00525 ::circle(x,y,r);
00526 }
00527
00528 void Bgi::ellipse( int x, int y, int rx, int ry, int col )
00529 {
00530 if ((col>=0) && (col!=ccolor)) {
00531 ::setcolor(col);
00532 ::ellipse(x,y,0,360,rx,ry);
00533 ::setcolor(ccolor);
00534 }
00535 else
00536 ::ellipse(x,y,0,360,rx,ry);
00537 }
00538
00539 void Bgi::rectangle( int x1, int y1, int x2, int y2, int col )
00540 {
00541 if ((col>=0) && (col!=ccolor)) {
00542 ::setcolor(col);
00543 ::rectangle(x1,y1,x2,y2);
00544 ::setcolor(ccolor);
00545 }
00546 else
00547 ::rectangle(x1,y1,x2,y2);
00548 }
00549
00550 void Bgi::bar( int x1, int y1, int x2, int y2, int col, int bkcol )
00551 {
00552 if (bkcol>=0) ::setfillstyle(SOLID_FILL,bkcol);
00553 else ::setfillstyle(SOLID_FILL,cbkcolor);
00554 ::bar(x1,y1,x2,y2);
00555
00556 if ((col>=0) && (col!=ccolor)) {
00557 ::setcolor(col);
00558 ::rectangle(x1,y1,x2,y2);
00559 ::setcolor(ccolor);
00560 }
00561 else
00562 ::rectangle(x1,y1,x2,y2);
00563 }
00564
00565 int Bgi::getkey( void ) { return ::getch(); }
00566 int Bgi::kbhit( void ) { return ::kbhit(); }
00567
00568 #endif
00569
00570
00571
00572 class NoGraph: public Graph {
00573 private:
00574 void Msg(VOID) { die_beep("Graphics not initialized"); }
00575 protected:
00576 void closegraph( void ) { Msg(); }
00577 public:
00578 NoGraph() { };
00579 void setcolorrgb( int, int, int, int) { Msg(); }
00580 void putpixel( int, int, int ) { Msg(); }
00581 void line( int, int, int, int, int ) { Msg(); }
00582 void rectangle( int, int, int, int, int ) { Msg(); }
00583 void bar( int, int, int, int, int, int ) { Msg(); }
00584 void circle( int, int, int, int ) { Msg(); }
00585 void ellipse( int, int, int, int, int ) { Msg(); }
00586
00587 int kbhit( void ) { Msg(); return 0; }
00588 int getkey( void ) { Msg(); return 0; }
00589 };
00590
00591
00592
00593 Graph *newGraph( const char *mode, int W, int H )
00594 {
00595 Graph *gr = NULL;
00596 char *dev = NULL;
00597
00598 if (getenv("GR_DISPLAY")) {
00599 char *env=strdup(getenv("GR_DISPLAY"));
00600 char *s=strtok(env," \t\n");
00601 while (s) {
00602 if ((s[0]=='W')&&(s[1]=='=')) { if (!W) W=atoi(s+2); }
00603 else if ((s[0]=='H')&&(s[1]=='=')) { if (!H) H=atoi(s+2); }
00604 else { if (dev) free(dev); dev=strdup(s); }
00605 s=strtok(NULL," \t\n");
00606 }
00607 free(env);
00608 if (mode && (strcmp(mode,"Auto"))) { if (dev) free(dev); dev=strdup(mode); };
00609 }
00610 else if (mode) dev=strdup(mode);
00611
00612 if (!dev || (!strcmp(dev,"Auto"))) {
00613 #ifdef X11
00614 if (!gr) gr = new Vogle;
00615 #endif
00616 #ifdef GIF
00617 if (!gr) gr = new Gif();
00618 #endif
00619 #ifdef BGI
00620 if (!gr) gr = new Bgi();
00621 #endif
00622 }
00623
00624 #ifdef X11
00625 else if (!strcmp(dev,"X11"))
00626 gr = new Vogle;
00627 #endif
00628 #ifdef GIF
00629 else if (!strcmp(dev,"GIF"))
00630 gr = new Gif();
00631 else if (stristr(dev,".gif"))
00632 gr = new Gif(dev);
00633 #endif
00634 #ifdef BGI
00635 else if (!strcmp(dev,"BGI"))
00636 gr = new Bgi();
00637 #endif
00638
00639 if (!gr) {
00640 fprintf(stderr,"Invalid graphic mode (%s)\7\n",dev);
00641 exit(1);
00642 }
00643
00644 if (!H) H=DEFH;
00645 if (!W) W=DEFW;
00646
00647 gr->initgraph(W,H);
00648
00649 return gr;
00650 }
00651
00652 void deleteGraph( Graph *gr )
00653 {
00654 if (gr) {
00655 gr->closegraph();
00656 delete gr;
00657 };
00658 }
00659
00660
00661
00662 static NoGraph nograph;
00663 Graph *_graph_gr= &nograph;
00664
00665 void gr_initgraph( const char *mode, int W, int H )
00666 {
00667 gr_closegraph();
00668 _graph_gr=newGraph(mode,W,H);
00669 }
00670
00671 void gr_closegraph( void )
00672 {
00673 if (_graph_gr!= &nograph)
00674 deleteGraph(_graph_gr);
00675 _graph_gr= &nograph;
00676 }
00677
00678
00679