home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / dev / misc / LEDA_src.lha / LEDA-3.1c-source / src / vga.old / _vgadraw.c next >
Encoding:
C/C++ Source or Header  |  1994-11-17  |  18.1 KB  |  928 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _vgadraw.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. /* basic graphic routines of libWx  declared in <LEDA/impl/x_basic.h>) 
  17.  * iplemented for MSDOS using the VGA 640x480x16 color graphics mode
  18.  */
  19.  
  20. #include "vgalib.h"
  21.  
  22. #include "vgafont"
  23.  
  24. static VIDEO_PTR video_buf;
  25. static int COLOR = 1;
  26. static int MODE  = 0;
  27. static int LINEWIDTH = 1;
  28. static int LINESTYLE = 0;
  29.  
  30.  
  31. void flush_display() {}
  32.  
  33. int  new_color(const char*) { return 1; }
  34.  
  35. int  text_height(const char*)  { return FONT_HEIGHT; }
  36. int  text_width(const char* s) { return FONT_WIDTH*strlen(s); }
  37.  
  38. int load_text_font(const char*) { return 0;}
  39. int load_bold_font(const char*) { return 0;}
  40. int load_message_font(const char*) { return 0;}
  41.  
  42. int  set_font(const char*) { return 0;}
  43. void set_text_font() {}
  44. void set_bold_font() {}
  45. void set_message_font() {}
  46.  
  47. int set_line_width(int width)
  48. { int save = LINEWIDTH;
  49.   LINEWIDTH = width;
  50.   return save;
  51. }
  52.  
  53. int set_line_style(int style)
  54. { int save = LINESTYLE;
  55.   LINESTYLE = style;
  56.   return save;
  57. }
  58.  
  59. int set_color(int color)
  60. {  int save = COLOR;
  61.    COLOR = color;
  62.    port_out(0x00, GRA_I );
  63.    port_out(color, GRA_D );
  64.    return save;
  65.  }
  66.  
  67. int set_mode(int mode)
  68. { int save = MODE;
  69.  
  70.   MODE = mode;
  71.  
  72.   if (mode==1)         mode = 3; /* xor */
  73.   else if (mode==2)    mode = 2; /* or  */
  74.      else if (mode==3) mode = 1; /* and */
  75.                   else mode = 0; /* src */
  76.  
  77.   port_out(0x03, GRA_I );
  78.   port_out(mode<<3, GRA_D );
  79.   return save;
  80. }
  81.  
  82.  
  83. static void put_pixel(Window win, int x, int y)
  84. { VIDEO_PTR p;
  85.  
  86.   if (x < 0 || x >= win->width || y < 0 || y >= win->height) return;
  87.  
  88.   x += win->xpos;
  89.   y += win->ypos;
  90.  
  91.   if (VIDEO==0)   /* write into (monochrome) buffer */
  92.      video_buf[y*LINE_BYTES+(x>>3)] |= (0x80 >> (x & 7));
  93.   else
  94.   { p = VIDEO + y*LINE_BYTES + (x>>3);
  95.     port_out(8, GRA_I);
  96.     port_out((0x80 >> (x & 7)), GRA_D);
  97.     *p = *p;
  98.    }
  99. }
  100.  
  101. static void vline(Window win,int x, int y0, int y1)
  102. { register VIDEO_PTR p;
  103.   register VIDEO_PTR last;
  104.  
  105.   if (y0 > y1)
  106.   { int y = y0;
  107.     y0 = y1;
  108.     y1 = y;
  109.    }
  110.  
  111.   if (x < 0 || x >= win->width || y1 < 0 || y0 >= win->height) return;
  112.  
  113.   if (y0 < 0) y0 = 0;
  114.   if (y1 >= win->height) y1 = win->height-1;
  115.  
  116.   x  += win->xpos;
  117.   y0 += win->ypos;
  118.   y1 += win->ypos;
  119.  
  120.   port_out(8, GRA_I);
  121.   port_out(128 >> (x&7), GRA_D);
  122.   last  = VIDEO + LINE_BYTES*y1 + (x>>3);
  123.   for(p = VIDEO + LINE_BYTES*y0 + (x>>3); p <= last; p+=LINE_BYTES)  *p = *p;
  124.  
  125. }
  126.  
  127.  
  128. void hline(Window win, int x0, int x1, int y)
  129. { register VIDEO_PTR p;
  130.   register VIDEO_PTR first;
  131.   register VIDEO_PTR last;
  132.   char byte;
  133.  
  134.   if (x0 > x1)
  135.   { int x = x0;
  136.     x0 = x1;
  137.     x1 = x;
  138.    }
  139.   if (y < 0 || y >= win->height || x1 < 0 || x0 >= win->width) return;
  140.   if (x0 < 0) x0 = 0;
  141.   if (x1 >= win->width) x1 = win->width-1;
  142.  
  143.   x0 += win->xpos;
  144.   x1 += win->xpos;
  145.   y  += win->ypos;
  146.  
  147.  
  148.   if (x0 > DISP_MAX_X  || y > DISP_MAX_Y || y < 0) return;
  149.  
  150.   if (x1 > DISP_MAX_X) x1 = DISP_MAX_X;
  151.   if (x0 < 0) x0 = 0;
  152.  
  153.   first = VIDEO + LINE_BYTES*y + (x0>>3);
  154.   last  = VIDEO + LINE_BYTES*y + (x1>>3);
  155.  
  156.   port_out(8, GRA_I);
  157.  
  158.   if (first == last)
  159.   { byte  = 0xFF>>(x0&7);
  160.     byte &= 0xFF<<((~x1)&7);
  161.     port_out(byte, GRA_D);
  162.     *first = *first;
  163.     return;
  164.    }
  165.  
  166.   port_out(0xFF>>(x0&7), GRA_D);
  167.   *first = *first;
  168.  
  169.   port_out(0xFF<<((~x1)&7), GRA_D);
  170.   *last = *last;
  171.  
  172.   port_out(0xFF, GRA_D);
  173.   for(p=first+1; p<last; p++) *p = *p;
  174.  
  175.  }
  176.  
  177.  
  178. static void Draw_Line(Window win, int x1, int y1, int x2, int y2)
  179. {
  180.   register int sy = 1;
  181.   register int dx = x2 - x1;
  182.   register int dy = y2 - y1;
  183.   register int c;
  184.   int i;
  185.  
  186.   if (dx < 0)
  187.   { int i = x1;
  188.     x1 = x2;
  189.     x2 = i;
  190.     dx = -dx;
  191.     i = y1;
  192.     y1 = y2;
  193.     y2 = i;
  194.     dy = -dy;
  195.    }
  196.   if (dy < 0)
  197.   { dy = -dy;
  198.     sy = -1;
  199.    }
  200.  
  201.   if (dx > dy)
  202.   { c = dx / 2;
  203.     put_pixel(win,x1,y1);
  204.     for (i=1; i<=LINEWIDTH/2; i++)
  205.     { put_pixel(win,x1,y1+i);
  206.       put_pixel(win,x1,y1-i);
  207.      }
  208.     while(x1 != x2)
  209.     { x1++;
  210.       c += dy;
  211.       if (c >= dx)
  212.       { c -= dx;
  213.         y1 += sy;
  214.        }
  215.       put_pixel(win,x1,y1);
  216.       for (i=1; i<=LINEWIDTH/2; i++)
  217.       { put_pixel(win,x1,y1+i);
  218.         put_pixel(win,x1,y1-i);
  219.        }
  220.     }
  221.   }
  222.   else
  223.   { c = dy / 2;
  224.     put_pixel(win,x1,y1);
  225.     for (i=1; i<=LINEWIDTH/2; i++)
  226.     { put_pixel(win,x1+i,y1);
  227.       put_pixel(win,x1-i,y1);
  228.      }
  229.     while(y1 != y2)
  230.     { y1 += sy;
  231.       c += dx;
  232.       if (c >= dy)
  233.       { c -= dy;
  234.         x1++;
  235.        }
  236.       put_pixel(win,x1,y1);
  237.       for (i=1; i<=LINEWIDTH/2; i++)
  238.       { put_pixel(win,x1+i,y1);
  239.         put_pixel(win,x1-i,y1);
  240.        }
  241.     }
  242.   }
  243. }
  244.  
  245. void line(Window win, int x1, int y1, int x2, int y2)
  246. { int i;
  247.  
  248.   if (x1 == x2)
  249.   { vline(win,x1,y1,y2);
  250.     for (i=1; i<=LINEWIDTH/2; i++)
  251.     { vline(win,x1-i,y1,y2);
  252.       vline(win,x1+i,y1,y2);
  253.      }
  254.     return;
  255.    }
  256.  
  257.   if (y1 == y2)
  258.   { hline(win,x1,x2,y1);
  259.     for (i=1; i<=LINEWIDTH/2; i++)
  260.     { hline(win,x1,x2,y1-i);
  261.       hline(win,x1,x2,y1+i);
  262.      }
  263.     return;
  264.    }
  265.  
  266.   Draw_Line(win,x1,y1,x2,y2);
  267. }
  268.  
  269.  
  270.  
  271. #define FILLPUT(pos,byte)\
  272. { p = pos;\
  273.   if ((*p & (byte)) == 0)\
  274.   { *p |= (byte);\
  275.     POS[top] = p; \
  276.     BYTE[top] = byte; \
  277.     top = (top+1) % 512; } else;\
  278. }
  279.  
  280. static  VIDEO_PTR      POS[512];
  281. static  unsigned char  BYTE[512];
  282.  
  283. static void fill_bits(VIDEO_PTR pos,unsigned char byte)
  284. { register int bot = 0;
  285.   register int top = 0;
  286.   register VIDEO_PTR p;
  287.  
  288.   FILLPUT(pos,byte)
  289.  
  290.   while (top != bot)
  291.   { pos  = POS[bot];
  292.     byte = BYTE[bot];
  293.  
  294.     bot = (bot+1) % 512;
  295.  
  296.     if (byte == 128)
  297.        FILLPUT(pos-1,1)
  298.     else
  299.        FILLPUT(pos,byte<<1)
  300.  
  301.     if (byte == 1)
  302.        FILLPUT(pos+1,128)
  303.     else
  304.        FILLPUT(pos,byte>>1)
  305.  
  306.     FILLPUT(pos-LINE_BYTES,byte)
  307.     FILLPUT(pos+LINE_BYTES,byte)
  308.   }
  309. }
  310.  
  311. static  VIDEO_PTR  POS1[512];
  312. static  int pos_top = 0;
  313.  
  314. void fill_bytes(VIDEO_PTR pos, int d)
  315. { VIDEO_PTR p = pos+d;
  316.  
  317.   unsigned char c = *p;
  318.   unsigned char pat = 0xFF;
  319.  
  320.   if (c == 0)
  321.   { *p = 0xFF;
  322.     fill_bytes(p,  1);
  323.     fill_bytes(p, -1);
  324.     fill_bytes(p, LINE_BYTES);
  325.     fill_bytes(p,-LINE_BYTES);
  326.     return;
  327.    }
  328.  
  329.   if (d == -1)
  330.   { while((c&1) == 0)
  331.     { pat <<= 1;
  332.       c >>= 1;
  333.      }
  334.     *p |= ~pat;
  335.    }
  336.  
  337.   if (d == 1)
  338.   { while((c&128) == 0)
  339.     { pat >>= 1;
  340.       c <<= 1;
  341.      }
  342.     *p |= ~pat;
  343.    }
  344.  
  345.   if((c&8) == 0 && (d == LINE_BYTES || d == -LINE_BYTES))   POS1[pos_top++] = p;
  346.  
  347.  }
  348.  
  349.  
  350. void fill_polygon(Window win, int n, int* xcoord, int* ycoord)
  351. {
  352.   register VIDEO_PTR p;
  353.   register VIDEO_PTR q;
  354.   register VIDEO_PTR first;
  355.   register VIDEO_PTR first1;
  356.   register VIDEO_PTR last;
  357.  
  358.   int i,m1,m2;
  359.   int minxi = 0;
  360.   int maxxi = 0;
  361.   int minyi = 0;
  362.   int maxyi = 0;
  363.   int minx,maxx,miny,maxy,x,y;
  364.  
  365.   VIDEO_PTR video_save = VIDEO;
  366.  
  367.   VIDEO = 0;
  368.  
  369.   video_buf = (VIDEO_PTR)malloc(LINE_BYTES*480);
  370.  
  371.  
  372.   for(i=1;i<n;i++)
  373.   { minxi = (xcoord[i] < xcoord[minxi]) ? i : minxi;
  374.     minyi = (ycoord[i] < ycoord[minyi]) ? i : minyi;
  375.     maxxi = (xcoord[i] > xcoord[maxxi]) ? i : maxxi;
  376.     maxyi = (ycoord[i] > ycoord[maxyi]) ? i : maxyi;
  377.    }
  378.  
  379.   minx = (xcoord[minxi] + win->xpos)/8;
  380.   maxx = (xcoord[maxxi] + win->xpos)/8;
  381.   miny = ycoord[minyi] + win->ypos;
  382.   maxy = ycoord[maxyi] + win->ypos;
  383.  
  384.   m1 =  (minxi == 0)   ?  n-1 : minxi-1;
  385.   m2 =  (minxi == n-1) ?  0   : minxi+1;
  386.  
  387.   for(i=miny; i<=maxy; i++)
  388.   { last = video_buf+LINE_BYTES*i + maxx;
  389.     for(p=video_buf+LINE_BYTES*i+minx; p<=last; p++) *p= 0;
  390.    }
  391.  
  392.   for(i=0; i<n-1; i++)
  393.       Draw_Line(win,xcoord[i],ycoord[i],xcoord[i+1],ycoord[i+1]);
  394.  
  395.   Draw_Line(win,xcoord[0],ycoord[0],xcoord[n-1],ycoord[n-1]);
  396.  
  397.   x = (xcoord[m1] + xcoord[m2] + xcoord[minxi])/3 + win->xpos;
  398.   y = (ycoord[m1] + ycoord[m2] + ycoord[minxi])/3 + win->ypos;
  399.  
  400.   pos_top = 0;
  401.   fill_bytes(video_buf + LINE_BYTES*y + x/8,0);
  402.  
  403.   while (pos_top--) fill_bits(POS1[pos_top],8);
  404.  
  405.   fill_bits(video_buf+LINE_BYTES*y+x/8,128>>(x%8));
  406.  
  407.   VIDEO = video_save;
  408.  
  409.   first  = video_buf+LINE_BYTES*miny + minx;
  410.   first1 = VIDEO+LINE_BYTES*miny + minx;
  411.   last   = video_buf+LINE_BYTES*miny + maxx;
  412.  
  413.   port_out(8, GRA_I);
  414.  
  415.   while(miny <= maxy)
  416.   { for(p=first, q = first1; p<=last; p++, q++)
  417.     { port_out(*p, GRA_D);
  418.       *q = *q;
  419.      }
  420.     first  += LINE_BYTES;
  421.     first1 += LINE_BYTES;
  422.     last   += LINE_BYTES;
  423.     miny++;
  424.    }
  425.  
  426.   free((char*)video_buf);
  427. }
  428.  
  429.  
  430. void box(Window win, int x0, int y0, int x1, int y1)
  431. { if (y0 > y1)
  432.   { int y = y0;
  433.     y0 = y1;
  434.     y1 = y;
  435.    }
  436.   while(y0<=y1) hline(win,x0,x1,y0++);
  437.  }
  438.  
  439.  
  440. void  rectangle(Window win, int x0, int y0, int x1, int y1)
  441. { int left  = x0;
  442.   int right = x1;
  443.   int top   = y0;
  444.   int bottom= y1;
  445.  
  446.   if (x0 > x1)
  447.   { left  = x1;
  448.     right = x0;
  449.    }
  450.  
  451.   if (y0 > y1)
  452.   { top  = y1;
  453.     bottom = y0;
  454.    }
  455.  
  456.   line(win,left, top,     right,top);
  457.   line(win,left, bottom,  right,bottom);
  458.   line(win,left, bottom-1,left, top+1);
  459.   line(win,right,bottom-1,right,top+1);
  460. }
  461.  
  462.  
  463. void circle(Window win, int x0,int y0,int r0)
  464. { int r;
  465.  
  466.   for (r = r0-LINEWIDTH/2; r <= r0+LINEWIDTH/2; r++)
  467.   { int y = r;
  468.     int x = 0;
  469.     int e = 3-2*y;
  470.  
  471.     put_pixel(win,x0,y0+r);
  472.     put_pixel(win,x0,y0-r);
  473.     put_pixel(win,x0+r,y0);
  474.     put_pixel(win,x0-r,y0);
  475.  
  476.     for (x=1;x<y;)
  477.       { put_pixel(win,x0+x,y0+y);
  478.         put_pixel(win,x0+x,y0-y);
  479.         put_pixel(win,x0-x,y0+y);
  480.         put_pixel(win,x0-x,y0-y);
  481.         put_pixel(win,x0+y,y0+x);
  482.         put_pixel(win,x0+y,y0-x);
  483.         put_pixel(win,x0-y,y0+x);
  484.         put_pixel(win,x0-y,y0-x);
  485.         x++;
  486.         if (e>=0) { y--; e = e - 4*y; }
  487.         e = e + 4*x + 2;
  488.        }
  489.  
  490.     if (x == y)
  491.     { put_pixel(win,x0+x,y0+y);
  492.       put_pixel(win,x0+x,y0-y);
  493.       put_pixel(win,x0-x,y0+y);
  494.       put_pixel(win,x0-x,y0-y);
  495.      }
  496.   }
  497. }
  498.  
  499.  
  500. void fill_circle(Window win, int x0, int y0, int r)
  501. { int y = 1;
  502.   int x = r;
  503.   int e = 3-2*r;
  504.  
  505.   hline(win,x0-x,x0+x,y0);
  506.  
  507.   while (y<=x)
  508.   { hline(win,x0-x,x0+x,y0+y);
  509.     hline(win,x0-x,x0+x,y0-y);
  510.  
  511.     if (y<x && e>=0)
  512.     { hline(win,x0-y,x0+y,y0+x);
  513.       hline(win,x0-y,x0+y,y0-x);
  514.       x--;
  515.       e = e - 4*x;
  516.      }
  517.     y++;
  518.     e = e + 4*y + 2;
  519.    }
  520. }
  521.  
  522.  
  523.  
  524. static void Put_Text(Window win, int x, int y, const char *str, int bg_col)
  525. { /* bgcol = -1 : transparent */
  526.   register unsigned char *fp1;
  527.   register unsigned char *fp2;
  528.   register unsigned char c;
  529.  
  530.   register VIDEO_PTR start;
  531.   register VIDEO_PTR stop;
  532.   register VIDEO_PTR q;
  533.  
  534.   char text[128];
  535.   int dy,i;
  536.   int len = strlen(str);
  537.   int l = (win->width-x)/text_width("H");
  538.   if (len > l) len = l;
  539.   if (len > 0) strncpy(text,str,len);
  540.   text[len] = 0;
  541.  
  542.  
  543.   if (y < 0 || y >= win->height || x < 0 || x >= win->width) return;
  544.  
  545.   if (bg_col >= 0)
  546.   { int save_color = set_color(bg_col);
  547.     int save_mode = set_mode(0);
  548.     box(win,x,y,x+text_width(text)-1,y+text_height(text)-1);
  549.     set_mode(save_mode);
  550.     set_color(save_color);
  551.    }
  552.  
  553.   dy = win->height - y;
  554.  
  555.   if (dy > FONT_HEIGHT) dy = FONT_HEIGHT;
  556.  
  557.   x += win->xpos;
  558.   y += win->ypos;
  559.  
  560.   fp1 = FONT + FONT_HEIGHT * ' ';
  561.   fp2 = FONT + FONT_HEIGHT * (text[0] & 127);
  562.  
  563.   start = VIDEO + LINE_BYTES*y + x/8;
  564.   stop = start + LINE_BYTES*dy;
  565.  
  566.   x &= 7;
  567.  
  568.   port_out(8, GRA_I);
  569.  
  570.   for(i=0;i<len; i++)
  571.   { for (q = start; q < stop; q+=LINE_BYTES, fp1++,fp2++)
  572.     { c = ((*fp2)>>x) | ((*fp1)<<(8-x));
  573.       port_out(c, GRA_D);
  574.       *q = *q;
  575.      }
  576.     fp1 = FONT + FONT_HEIGHT * (text[i] & 127);
  577.     fp2 = FONT + FONT_HEIGHT * (text[i+1] & 127);
  578.     start++;
  579.     stop++;
  580.    }
  581.  
  582.   if (x > 0)
  583.     for (q = start; q < stop; q+=LINE_BYTES, fp1++,fp2++)
  584.     { c = (*fp1)<<(8-x);
  585.       port_out(c, GRA_D);
  586.       *q = *q;
  587.      }
  588.  
  589. }
  590.  
  591. void put_text(Window win, int x, int y, const char *text, int opaque)
  592. { Put_Text(win,x,y,text,opaque ? win->bg_col : -1); }
  593.  
  594.  
  595. void put_ctext(Window win, int x, int y, const char* str, int opaque)
  596. { put_text(win,x-(text_width(str)-1)/2, y-(text_height(str)-1)/2, str, opaque);
  597.  }
  598.  
  599.  
  600. void show_coordinates(Window win, const char* s)
  601. { int save_mode = set_mode(0);
  602.   int save_col  = set_color(4);
  603.   put_text(win,win->width-138,1,s,1); 
  604.   set_mode(save_mode);
  605.   set_color(save_col);
  606. }
  607.  
  608.  
  609. void clear_window(Window win, int c)
  610. { int save_col  = set_color(win->bg_col);
  611.   int save_mode = set_mode(0);
  612.   box(win,0,0,win->width-1,win->height-1);
  613.   set_color(save_col);
  614.   set_mode(save_mode);
  615.  }
  616.  
  617.  
  618. void pixel(Window win, int x, int y) { put_pixel(win,x,y);}
  619.  
  620. void pixels(Window win, int n, int* x, int* y)
  621. { while(n--) put_pixel(win,x[n],y[n]); }
  622.  
  623.  
  624.  
  625. #define put_arc_pixel(X,Y,x,y,top) { X[top] = x; Y[top] = y; top++; }
  626.  
  627. void arc(Window win, int x0, int y0, int r1, int r2, double start, double angle)
  628. {
  629.  int* X = new int[10*r1];
  630.  int* Y = new int[10*r2];
  631.  int r;
  632.  
  633.  x0 += win->xpos;
  634.  y0 += win->ypos;
  635.  
  636.  if (angle < 0)
  637.  { start += angle;
  638.    angle *= -1;
  639.   }
  640.  
  641.  if (angle > 2*M_PI) angle = 2*M_PI;
  642.  
  643.  while (start < 0) start += 2*M_PI;
  644.  
  645.  for (r = r1-LINEWIDTH/2; r <= r1+LINEWIDTH/2; r++)
  646.  { int y = r;
  647.    int x = 0;
  648.    int e = 3-2*y;
  649.    int top = 0;
  650.    int high;
  651.    int high1;
  652.    int s,l;
  653.    float L;
  654.    int i;
  655.  
  656.    while (x < y)
  657.    { put_arc_pixel(X,Y,x,y,top);
  658.      x++;
  659.      if (e>=0) { y--; e -= 4*y; }
  660.      e += 4*x + 2;
  661.     }
  662.  
  663.    high = top-1;
  664.  
  665.    if (x==y) put_arc_pixel(X,Y,x,y,top);
  666.  
  667.    high1 = top;
  668.  
  669.    for(i = 0;    i < high1; i++) put_arc_pixel(X,Y, Y[i],-X[i],top);
  670.    for(i = high; i > 0;     i--) put_arc_pixel(X,Y, X[i],-Y[i],top);
  671.    for(i = 0;    i < high1; i++) put_arc_pixel(X,Y,-X[i],-Y[i],top);
  672.    for(i = high; i > 0;     i--) put_arc_pixel(X,Y,-Y[i],-X[i],top);
  673.    for(i = 0;    i < high1; i++) put_arc_pixel(X,Y,-Y[i], X[i],top);
  674.    for(i = high; i > 0;     i--) put_arc_pixel(X,Y,-X[i], Y[i],top);
  675.    for(i = 0;    i < high1; i++) put_arc_pixel(X,Y, X[i], Y[i],top);
  676.    for(i = high; i > 0;     i--) put_arc_pixel(X,Y, Y[i], X[i],top);
  677.  
  678.    L = (top - high1)/(2*M_PI);
  679.    s = high1 - 1 + (int)(start*L);
  680.    l = s + (int)(angle*L);
  681.  
  682.    if (l >= top)
  683.    { for(i=s; i < top; i++) put_pixel(win,x0+X[i],y0+Y[i]);
  684.      s = high - 1;
  685.      l = s + l - top;
  686.     }
  687.    for(i=s; i < l; i++) put_pixel(win,x0+X[i],y0+Y[i]);
  688.   }
  689.  
  690.   delete X;
  691.   delete Y;
  692. }
  693.  
  694.  
  695. static void ellipse_point(Window win, int x0, int y0, int x, int y)
  696. { put_pixel(win,x0+x,y0+y);
  697.   put_pixel(win,x0-x,y0+y);
  698.   put_pixel(win,x0+x,y0-y);
  699.   put_pixel(win,x0-x,y0-y);
  700.  }
  701.  
  702.  
  703. void ellipse(Window win, int x0, int y0, int a, int b)
  704.   /* Foley, van Dam, Feiner, Huges: Computer Graphics, page 90 */
  705.  
  706.   double d1,d2;
  707.   int x,y;
  708.   int a_2 = a*a;
  709.   int b_2 = b*b;
  710.  
  711.   put_pixel(win,x0,y0-b);
  712.   put_pixel(win,x0,y0+b);
  713.   put_pixel(win,x0-a,y0);
  714.   put_pixel(win,x0+a,y0);
  715.  
  716.   x = 0;
  717.   y = b;
  718.  
  719.   d1 = b*b + a*a*(0.25 - b); 
  720.    
  721.   while (a_2*(y - 0.5) > b_2*(x+1))
  722.   { if (d1 < 0)
  723.       d1 += b_2*(2*x + 3);
  724.     else
  725.     { d1 += b_2*(2*x + 3) + a_2*(2 - 2*y);
  726.       y--;
  727.      }
  728.     x++;
  729.     ellipse_point(win,x0,y0,x,y);
  730.   }
  731.  
  732.   d2 = b_2*(x+0.5)*(x+0.5) + a_2*(y - 1)*(y - 1) - a_2*b_2;
  733.  
  734.   while (y > 1)
  735.   { if (d2 < 0)
  736.      { d2 += b_2*(2*x+2)+a_2*(3-2*y);
  737.        x++;
  738.       }
  739.     else
  740.        d2 += a*a*(3-2*y);
  741.  
  742.     y--;
  743.  
  744.     ellipse_point(win,x0,y0,x,y);
  745.    }
  746. }
  747.  
  748.  
  749. void fill_ellipse(Window win, int x0, int y0, int a, int b)
  750.   double d1,d2;
  751.   int x,y;
  752.   int a_2 = a*a;
  753.   int b_2 = b*b;
  754.  
  755.   x = 0;
  756.   y = b;
  757.  
  758.   d1 = b*b + a*a*(0.25 - b); 
  759.    
  760.   while (a_2*(y - 0.5) > b_2*(x+1))
  761.   { if (d1 < 0)
  762.       d1 += b_2*(2*x + 3);
  763.     else
  764.     { d1 += b_2*(2*x + 3) + a_2*(2 - 2*y);
  765.       hline(win,x0-x,x0+x,y0+y);
  766.       hline(win,x0-x,x0+x,y0-y);
  767.       y--;
  768.      }
  769.     x++;
  770.   }
  771.   hline(win,x0-x,x0+x,y0+y);
  772.   hline(win,x0-x,x0+x,y0-y);
  773.  
  774.   d2 = b_2*(x+0.5)*(x+0.5) + a_2*(y - 1)*(y - 1) - a_2*b_2;
  775.  
  776.   while (y > 1)
  777.   { if (d2 < 0)
  778.      { d2 += b_2*(2*x+2)+a_2*(3-2*y);
  779.        x++;
  780.       }
  781.     else
  782.        d2 += a*a*(3-2*y);
  783.  
  784.     y--;
  785.  
  786.     hline(win,x0-x,x0+x,y0+y);
  787.     hline(win,x0-x,x0+x,y0-y);
  788.    }
  789.  
  790.   hline(win,x0-x,x0+x,y0);
  791.  
  792. }
  793.  
  794.  
  795. void fill_arc(Window,int,int,int,int,double,double)
  796. { }
  797.  
  798.  
  799. static void copy_box(int left, int top, int width, int height, int x, int y)
  800. {
  801.   register VIDEO_PTR first1;
  802.   register VIDEO_PTR first;
  803.   register VIDEO_PTR last1;
  804.   register VIDEO_PTR last;
  805.   register VIDEO_PTR p;
  806.   register VIDEO_PTR q;
  807.  
  808.   int i;
  809.  
  810.   if(x < 0) 
  811.   { left += x;
  812.     width -= x;
  813.     x = 0;
  814.    }
  815.  
  816.   if(y < 0) 
  817.   { top += y;
  818.     height -= y;
  819.     y = 0;
  820.    }
  821.  
  822.   if(x+width > DISP_MAX_X) width = DISP_MAX_X - x;
  823.  
  824.   if(y+height > DISP_MAX_Y) height = DISP_MAX_Y - y;
  825.  
  826.   /* set write mode 1 */
  827.   port_out(5, GRA_I);
  828.   port_out(1, GRA_D);
  829.  
  830.   if (y <= top)
  831.   { first1 = VIDEO + LINE_BYTES*y + x/8;
  832.     last1  = VIDEO + LINE_BYTES*y + (x+width-1)/8;
  833.     first  = VIDEO + LINE_BYTES*top + left/8;
  834.     last   = VIDEO + LINE_BYTES*top + (left+width-1)/8;
  835.    }
  836.   else
  837.   { first1 = VIDEO + LINE_BYTES*(y+height-1) + x/8;
  838.     last1  = VIDEO + LINE_BYTES*(y+height-1) + (x+width-1)/8;
  839.     first  = VIDEO + LINE_BYTES*(top+height-1) + left/8;
  840.     last   = VIDEO + LINE_BYTES*(top+height-1) + (left+width-1)/8;
  841.    }
  842.  
  843.   for(i=0; i<height; i++)
  844.   { 
  845.     if (x <= left)
  846.       for(q=first, p=first1; q<=last; q++,p++) *p = *q;
  847.     else
  848.       for(q=last, p=last1; q>=first; q--,p--) *p = *q;
  849.  
  850.     if (y <= top)
  851.     { first1 += LINE_BYTES;
  852.       first  += LINE_BYTES;
  853.       last1  += LINE_BYTES;
  854.       last   += LINE_BYTES;
  855.      }
  856.     else
  857.     { first1 -= LINE_BYTES;
  858.       first  -= LINE_BYTES;
  859.       last1  -= LINE_BYTES;
  860.       last   -= LINE_BYTES;
  861.      }
  862.    }
  863.  
  864.   /* set write mode 0 */
  865.   port_out(5, GRA_I);
  866.   port_out(0, GRA_D);
  867.  
  868.  }
  869.  
  870. void copy_rect(Window win, int x1, int y1, int x2, int y2, int x, int y)
  871. { int w = x2-x1+1;
  872.   int h = y2-y1+1;
  873.   x1 += win->xpos; 
  874.   y1 += win->ypos; 
  875.   x  += win->xpos; 
  876.   y  += win->ypos; 
  877.   copy_box(x1,y1,w,h,x,y); 
  878.  }
  879.  
  880.  
  881. static char rev_byte(char c)
  882. { char c1 = 0x00;
  883.    for(int i=0; i<8; i++)
  884.    { c1 <<= 1;
  885.      if (c&1) c1 |= 1;
  886.      c >>= 1;
  887.     }
  888.   return c1;
  889. }
  890.  
  891.  
  892. void insert_bitmap(Window win, int width, int height, char* data)
  893. {
  894.   register VIDEO_PTR first;
  895.   register VIDEO_PTR last;
  896.   register VIDEO_PTR q;
  897.  
  898.   int x = win->x0/8 + 1;
  899.   int y = win->ypos;
  900.  
  901.   int w = (width > win->width) ? win->width : width;
  902.   int h = (height > win->height) ? win->height : height;
  903.  
  904.   first  = VIDEO + LINE_BYTES*y + x;
  905.   last   = VIDEO + LINE_BYTES*y + x + w/8 - 1;
  906.  
  907.   if (width % 8)
  908.      width  = 1+ width/8;
  909.   else
  910.      width  = width/8;
  911.  
  912.   port_out(8, GRA_I);
  913.  
  914.   for(int i=0; i<h; i++)
  915.   { char* p = data + i*width;
  916.     for(q=first; q<=last; q++) 
  917.     { port_out(rev_byte(*p++), GRA_D);
  918.       *q = *q;
  919.      }
  920.     first += LINE_BYTES;
  921.     last  += LINE_BYTES;
  922.    }
  923.  }
  924.  
  925.