| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- /* Object oriented interface to C graphics library. This version suitable
- for interfacing to Modula 2. For demo of this see file MIX_MOD.MOD */
- #include <graph.h>
- #include <gwinc2m.hpp>
- #include <math.h>
- #define ErrUnknownAdapter 1
- #define ErrFewerColors 2
- #define PI 3.141592554
- int GraphErr;
- short GWindow::CurrentMode=_DEFAULTMODE;
- static struct videoconfig far vc;
- GWindow *GWindow::activewindow=0;
- GWindow::GWindow()
- {
- }
- GWindow::GWindow(GCoord X1,GCoord Y1,GCoord X2,GCoord Y2,int ColsReq)
- { ok=0;
- PreviousMode=CurrentMode;
- if (CurrentMode==_DEFAULTMODE)
- { short BestMode=_DEFAULTMODE;
- _getvideoconfig(&vc);
- switch (vc.adapter)
- { case _VGA:
- BestMode=ColsReq>16?_MRES256COLOR:_VRES16COLOR;
- if (ColsReq>256)
- GraphErr=ErrFewerColors;
- break;
- case _EGA:
- BestMode=_ERESCOLOR;
- if (ColsReq>16)
- GraphErr=ErrFewerColors;
- break;
- case _CGA:
- BestMode=ColsReq>2?_MRES4COLOR:_HRESBW;
- if (ColsReq>4)
- GraphErr=ErrFewerColors;
- break;
- case _HGC:
- BestMode=_HERCMONO;
- if (ColsReq>2)
- GraphErr=ErrFewerColors;
- break;
- default:
- GraphErr=ErrUnknownAdapter;
- return;
- }
- if (BestMode!=_DEFAULTMODE)
- { _setvideomode(BestMode);
- _getvideoconfig(&vc); // This info is needed by those who come after
- CurrentMode=BestMode;
- }
- }
- NumColors=vc.numcolors;
- ReSize(X1,Y1,X2,Y2);
- CurrentColor=NumColors-1;
- CurrentBackColor=0;
- ok=1;
- }
- void GWindow::ReSize(GCoord X1,GCoord Y1,GCoord X2,GCoord Y2)
- { XScale=vc.numxpixels;
- YScale=vc.numypixels;
- XL=XReal(X1);
- XR=XReal(X2);
- YT=YReal(Y1);
- YB=YReal(Y2);
- XScale=(vc.numxpixels*long(X2-X1))/1024;
- YScale=(vc.numypixels*long(Y2-Y1))/1024;
- activewindow=0;
- }
- GWindow::~GWindow()
- { ok=0;
- if (PreviousMode!=CurrentMode) // NB This assumes modes nest cleanly
- _setvideomode(PreviousMode);
- }
- void GWindow::AffixColor(int Col,int BkCol)
- { static int CurBackCol=-1;
- /* NB Setting background color is quite dear so avoid if poss */
- int FC=Col==-1?CurrentColor:Col;
- _setcolor(FC%NumColors);
- _settextcolor(FC);
- FC=(Col==-1?CurrentBackColor:BkCol)%NumColors;
- if (FC!=CurBackCol)
- _setbkcolor(CurBackCol=FC);
- activewindow=this;
- }
- void GWindow::Plot(GCoord x,GCoord y,int Col)
- { if (activewindow!=this)
- { AffixColor(Col,-1);
- _setcliprgn(XL,YT,XR,YB);
- }
- _setpixel(XPhys(x),YPhys(y));
- }
- int GWindow::Point(GCoord x,GCoord y)
- { if (activewindow!=this)
- _setcliprgn(XL,YT,XR,YB);
- return _getpixel(XPhys(x),YPhys(y));
- }
- void GWindow::Fill(GCoord x,GCoord y,int Bound,char Flood)
- { if (activewindow!=this)
- { AffixColor(-1,-1);
- _setcliprgn(XL,YT,XR,YB);
- }
- int Col=(Bound==-1?CurrentColor:Bound)%NumColors;
- if (Flood)
- _floodfill(XPhys(x),YPhys(y),Col);
- else
- _stackfill(XPhys(x),YPhys(y),Col);
- }
- void GWindow::SetColor(int Col,int BkCol)
- { if (Col>0)
- CurrentColor=Col;
- if (BkCol>0)
- CurrentBackColor=BkCol;
- if (activewindow==this)
- AffixColor(-1,-1);
- }
- void GWindow::Clear(int BkCol)
- { AffixColor(-1,BkCol);
- _setviewport(XL,YT,XR,YB);
- _clearscreen(_GVIEWPORT);
- _setviewport(0,0,XR,YB);
- _setcliprgn(XL,YT,XR,YB); // Reset origin but correct clipping
- }
- void GWindow::Rectangle(GCoord Left,GCoord Top,GCoord Width,GCoord Height,int Fill)
- { AffixColor(-1,-1);
- _setcliprgn(XL,YT,XR,YB);
- _rectangle(Fill?_GFILLINTERIOR:_GBORDER,
- XPhys(Left),YPhys(Top),XPhys(Left+Width),YPhys(Top+Height));
- }
- void GWindow::Polygon(short nsides,GCoord px[],GCoord py[],int Fill)
- { if (activewindow!=this)
- { AffixColor(-1,-1);
- _setcliprgn(XL,YT,XR,YB);
- }
- GCoord *nx=new GCoord[nsides];
- GCoord *ny=new GCoord[nsides];
- short n=nsides;
- while (nsides--)
- { nx[nsides]=XPhys(px[nsides]);
- ny[nsides]=YPhys(py[nsides]);
- }
- _polygon(Fill?_GFILLINTERIOR:_GBORDER,n,nx,ny);
- delete [] nx;
- delete [] ny;
- }
- void GWindow::Ellipse(GCoord X,GCoord Y,GCoord Major,GCoord Minor,int Fill)
- { AffixColor(-1,-1);
- _setcliprgn(XL,YT,XR,YB);
- _ellipse(Fill?_GFILLINTERIOR:_GBORDER,
- XPhys(X-Major),YPhys(Y-Minor),XPhys(X+Major),YPhys(Y+Minor));
- }
- void GWindow::Line(GCoord X1,GCoord Y1,GCoord X2,GCoord Y2,int Col)
- { Plot(X1,Y1,Col); // This sets colors and clipping region for me
- _lineto(XPhys(X2),YPhys(Y2));
- }
- void GWindow::VectorFromAngle(int Angle,GCoord &X,GCoord &Y)
- { double RA=Angle*PI/180.0;
- X=1024.0*cos(RA);
- Y=-1024.0*sin(RA);
- }
- /* Draw a proportion of an ellipse from starting position and subtended angle
- StartAngle to EndAngle. The angle measurements are in degrees and measured
- from the first quadrant */
- void GWindow::ArcServer(GCoord X,GCoord Y,GCoord Major,GCoord Minor,int StartAngle,int EndAngle,char pie,int Fill)
- { GCoord StartX,StartY,EndX,EndY;
- VectorFromAngle(StartAngle,StartX,StartY);
- VectorFromAngle(EndAngle,EndX,EndY);
- AffixColor(-1,-1);
- _setcliprgn(XL,YT,XR,YB);
- // GCoord p1[8]={XPhys(X-Major),YPhys(Y-Minor),XPhys(X+Major),YPhys(Y+Minor),
- // XPhys(X+StartX),YPhys(Y+StartY),XPhys(X+EndX),YPhys(Y+EndY)};
- if (pie)
- _pie(Fill?_GFILLINTERIOR:_GBORDER,
- XPhys(X-Major),YPhys(Y-Minor),XPhys(X+Major),YPhys(Y+Minor),
- StartX,StartY,EndX,EndY);
- else
- _arc(XPhys(X-Major),YPhys(Y-Minor),XPhys(X+Major),YPhys(Y+Minor),
- XReal(StartX),YReal(StartY),XReal(EndX),YReal(EndY));
- /* if (pie)
- _pie(Fill?_GFILLINTERIOR:_GBORDER,p1[0],p1[1],p1[2],p1[3],p1[4],p1[5],
- p1[6],p1[7]);
- else
- _arc(p1[0],p1[1],p1[2],p1[3],p1[4],p1[5],p1[6],p1[7]);*/
- }
- void GWindow::EllipticArc(GCoord X,GCoord Y,GCoord Major,GCoord Minor,int StartAngle,int EndAngle)
- { ArcServer(X,Y,Major,Minor,StartAngle,EndAngle,0,0);
- }
- void GWindow::EllipticPie(GCoord X,GCoord Y,GCoord Major,GCoord Minor,int StartAngle,int EndAngle,int Fill)
- { ArcServer(X,Y,Major,Minor,StartAngle,EndAngle,1,Fill);
- }
- void GWindow::Cuboid(GCoord X,GCoord Y,GCoord Width,GCoord Height,GCoord Depth,
- int Top,int Fill)
- { AffixColor(-1,-1);
- _setcliprgn(XL,YT,XR,YB);
- _cube(Fill?_GFILLINTERIOR:_GBORDER,Top?_GTOP:_GNOTOP,
- XPhys(X),YPhys(Y),XPhys(X+Width),YPhys(Y+Height),XReal(Depth));
- }
- void GWindow::CursorPosition(GCoord x,GCoord y)
- { /* This procedure is a bit of a swiz as only character position resolution
- exists!!! */
- int rx=int((XPhys(x)*(long)vc.numtextcols)/vc.numxpixels);
- int ry=int((YPhys(y)*(long)vc.numtextrows)/vc.numypixels);
- _settextwindow(1,1,vc.numtextrows,vc.numtextcols);
- _settextposition(ry+1,rx+1);
- AffixColor(-1,-1);
- }
- int GWindow::CharWidth()
- { return 1+int(1024L*vc.numxpixels / ((XR-XL)*vc.numtextcols));
- }
- int GWindow::CharHeight()
- { return 1+int(1024L*vc.numypixels / ((YB-YT)*vc.numtextrows));
- }
|