GWINC2M.CPP 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /* Object oriented interface to C graphics library. This version suitable
  2. for interfacing to Modula 2. For demo of this see file MIX_MOD.MOD */
  3. #include <graph.h>
  4. #include <gwinc2m.hpp>
  5. #include <math.h>
  6. #define ErrUnknownAdapter 1
  7. #define ErrFewerColors 2
  8. #define PI 3.141592554
  9. int GraphErr;
  10. short GWindow::CurrentMode=_DEFAULTMODE;
  11. static struct videoconfig far vc;
  12. GWindow *GWindow::activewindow=0;
  13. GWindow::GWindow()
  14. {
  15. }
  16. GWindow::GWindow(GCoord X1,GCoord Y1,GCoord X2,GCoord Y2,int ColsReq)
  17. { ok=0;
  18. PreviousMode=CurrentMode;
  19. if (CurrentMode==_DEFAULTMODE)
  20. { short BestMode=_DEFAULTMODE;
  21. _getvideoconfig(&vc);
  22. switch (vc.adapter)
  23. { case _VGA:
  24. BestMode=ColsReq>16?_MRES256COLOR:_VRES16COLOR;
  25. if (ColsReq>256)
  26. GraphErr=ErrFewerColors;
  27. break;
  28. case _EGA:
  29. BestMode=_ERESCOLOR;
  30. if (ColsReq>16)
  31. GraphErr=ErrFewerColors;
  32. break;
  33. case _CGA:
  34. BestMode=ColsReq>2?_MRES4COLOR:_HRESBW;
  35. if (ColsReq>4)
  36. GraphErr=ErrFewerColors;
  37. break;
  38. case _HGC:
  39. BestMode=_HERCMONO;
  40. if (ColsReq>2)
  41. GraphErr=ErrFewerColors;
  42. break;
  43. default:
  44. GraphErr=ErrUnknownAdapter;
  45. return;
  46. }
  47. if (BestMode!=_DEFAULTMODE)
  48. { _setvideomode(BestMode);
  49. _getvideoconfig(&vc); // This info is needed by those who come after
  50. CurrentMode=BestMode;
  51. }
  52. }
  53. NumColors=vc.numcolors;
  54. ReSize(X1,Y1,X2,Y2);
  55. CurrentColor=NumColors-1;
  56. CurrentBackColor=0;
  57. ok=1;
  58. }
  59. void GWindow::ReSize(GCoord X1,GCoord Y1,GCoord X2,GCoord Y2)
  60. { XScale=vc.numxpixels;
  61. YScale=vc.numypixels;
  62. XL=XReal(X1);
  63. XR=XReal(X2);
  64. YT=YReal(Y1);
  65. YB=YReal(Y2);
  66. XScale=(vc.numxpixels*long(X2-X1))/1024;
  67. YScale=(vc.numypixels*long(Y2-Y1))/1024;
  68. activewindow=0;
  69. }
  70. GWindow::~GWindow()
  71. { ok=0;
  72. if (PreviousMode!=CurrentMode) // NB This assumes modes nest cleanly
  73. _setvideomode(PreviousMode);
  74. }
  75. void GWindow::AffixColor(int Col,int BkCol)
  76. { static int CurBackCol=-1;
  77. /* NB Setting background color is quite dear so avoid if poss */
  78. int FC=Col==-1?CurrentColor:Col;
  79. _setcolor(FC%NumColors);
  80. _settextcolor(FC);
  81. FC=(Col==-1?CurrentBackColor:BkCol)%NumColors;
  82. if (FC!=CurBackCol)
  83. _setbkcolor(CurBackCol=FC);
  84. activewindow=this;
  85. }
  86. void GWindow::Plot(GCoord x,GCoord y,int Col)
  87. { if (activewindow!=this)
  88. { AffixColor(Col,-1);
  89. _setcliprgn(XL,YT,XR,YB);
  90. }
  91. _setpixel(XPhys(x),YPhys(y));
  92. }
  93. int GWindow::Point(GCoord x,GCoord y)
  94. { if (activewindow!=this)
  95. _setcliprgn(XL,YT,XR,YB);
  96. return _getpixel(XPhys(x),YPhys(y));
  97. }
  98. void GWindow::Fill(GCoord x,GCoord y,int Bound,char Flood)
  99. { if (activewindow!=this)
  100. { AffixColor(-1,-1);
  101. _setcliprgn(XL,YT,XR,YB);
  102. }
  103. int Col=(Bound==-1?CurrentColor:Bound)%NumColors;
  104. if (Flood)
  105. _floodfill(XPhys(x),YPhys(y),Col);
  106. else
  107. _stackfill(XPhys(x),YPhys(y),Col);
  108. }
  109. void GWindow::SetColor(int Col,int BkCol)
  110. { if (Col>0)
  111. CurrentColor=Col;
  112. if (BkCol>0)
  113. CurrentBackColor=BkCol;
  114. if (activewindow==this)
  115. AffixColor(-1,-1);
  116. }
  117. void GWindow::Clear(int BkCol)
  118. { AffixColor(-1,BkCol);
  119. _setviewport(XL,YT,XR,YB);
  120. _clearscreen(_GVIEWPORT);
  121. _setviewport(0,0,XR,YB);
  122. _setcliprgn(XL,YT,XR,YB); // Reset origin but correct clipping
  123. }
  124. void GWindow::Rectangle(GCoord Left,GCoord Top,GCoord Width,GCoord Height,int Fill)
  125. { AffixColor(-1,-1);
  126. _setcliprgn(XL,YT,XR,YB);
  127. _rectangle(Fill?_GFILLINTERIOR:_GBORDER,
  128. XPhys(Left),YPhys(Top),XPhys(Left+Width),YPhys(Top+Height));
  129. }
  130. void GWindow::Polygon(short nsides,GCoord px[],GCoord py[],int Fill)
  131. { if (activewindow!=this)
  132. { AffixColor(-1,-1);
  133. _setcliprgn(XL,YT,XR,YB);
  134. }
  135. GCoord *nx=new GCoord[nsides];
  136. GCoord *ny=new GCoord[nsides];
  137. short n=nsides;
  138. while (nsides--)
  139. { nx[nsides]=XPhys(px[nsides]);
  140. ny[nsides]=YPhys(py[nsides]);
  141. }
  142. _polygon(Fill?_GFILLINTERIOR:_GBORDER,n,nx,ny);
  143. delete [] nx;
  144. delete [] ny;
  145. }
  146. void GWindow::Ellipse(GCoord X,GCoord Y,GCoord Major,GCoord Minor,int Fill)
  147. { AffixColor(-1,-1);
  148. _setcliprgn(XL,YT,XR,YB);
  149. _ellipse(Fill?_GFILLINTERIOR:_GBORDER,
  150. XPhys(X-Major),YPhys(Y-Minor),XPhys(X+Major),YPhys(Y+Minor));
  151. }
  152. void GWindow::Line(GCoord X1,GCoord Y1,GCoord X2,GCoord Y2,int Col)
  153. { Plot(X1,Y1,Col); // This sets colors and clipping region for me
  154. _lineto(XPhys(X2),YPhys(Y2));
  155. }
  156. void GWindow::VectorFromAngle(int Angle,GCoord &X,GCoord &Y)
  157. { double RA=Angle*PI/180.0;
  158. X=1024.0*cos(RA);
  159. Y=-1024.0*sin(RA);
  160. }
  161. /* Draw a proportion of an ellipse from starting position and subtended angle
  162. StartAngle to EndAngle. The angle measurements are in degrees and measured
  163. from the first quadrant */
  164. void GWindow::ArcServer(GCoord X,GCoord Y,GCoord Major,GCoord Minor,int StartAngle,int EndAngle,char pie,int Fill)
  165. { GCoord StartX,StartY,EndX,EndY;
  166. VectorFromAngle(StartAngle,StartX,StartY);
  167. VectorFromAngle(EndAngle,EndX,EndY);
  168. AffixColor(-1,-1);
  169. _setcliprgn(XL,YT,XR,YB);
  170. // GCoord p1[8]={XPhys(X-Major),YPhys(Y-Minor),XPhys(X+Major),YPhys(Y+Minor),
  171. // XPhys(X+StartX),YPhys(Y+StartY),XPhys(X+EndX),YPhys(Y+EndY)};
  172. if (pie)
  173. _pie(Fill?_GFILLINTERIOR:_GBORDER,
  174. XPhys(X-Major),YPhys(Y-Minor),XPhys(X+Major),YPhys(Y+Minor),
  175. StartX,StartY,EndX,EndY);
  176. else
  177. _arc(XPhys(X-Major),YPhys(Y-Minor),XPhys(X+Major),YPhys(Y+Minor),
  178. XReal(StartX),YReal(StartY),XReal(EndX),YReal(EndY));
  179. /* if (pie)
  180. _pie(Fill?_GFILLINTERIOR:_GBORDER,p1[0],p1[1],p1[2],p1[3],p1[4],p1[5],
  181. p1[6],p1[7]);
  182. else
  183. _arc(p1[0],p1[1],p1[2],p1[3],p1[4],p1[5],p1[6],p1[7]);*/
  184. }
  185. void GWindow::EllipticArc(GCoord X,GCoord Y,GCoord Major,GCoord Minor,int StartAngle,int EndAngle)
  186. { ArcServer(X,Y,Major,Minor,StartAngle,EndAngle,0,0);
  187. }
  188. void GWindow::EllipticPie(GCoord X,GCoord Y,GCoord Major,GCoord Minor,int StartAngle,int EndAngle,int Fill)
  189. { ArcServer(X,Y,Major,Minor,StartAngle,EndAngle,1,Fill);
  190. }
  191. void GWindow::Cuboid(GCoord X,GCoord Y,GCoord Width,GCoord Height,GCoord Depth,
  192. int Top,int Fill)
  193. { AffixColor(-1,-1);
  194. _setcliprgn(XL,YT,XR,YB);
  195. _cube(Fill?_GFILLINTERIOR:_GBORDER,Top?_GTOP:_GNOTOP,
  196. XPhys(X),YPhys(Y),XPhys(X+Width),YPhys(Y+Height),XReal(Depth));
  197. }
  198. void GWindow::CursorPosition(GCoord x,GCoord y)
  199. { /* This procedure is a bit of a swiz as only character position resolution
  200. exists!!! */
  201. int rx=int((XPhys(x)*(long)vc.numtextcols)/vc.numxpixels);
  202. int ry=int((YPhys(y)*(long)vc.numtextrows)/vc.numypixels);
  203. _settextwindow(1,1,vc.numtextrows,vc.numtextcols);
  204. _settextposition(ry+1,rx+1);
  205. AffixColor(-1,-1);
  206. }
  207. int GWindow::CharWidth()
  208. { return 1+int(1024L*vc.numxpixels / ((XR-XL)*vc.numtextcols));
  209. }
  210. int GWindow::CharHeight()
  211. { return 1+int(1024L*vc.numypixels / ((YB-YT)*vc.numtextrows));
  212. }