simple.c revision 50141
1/*-
2 * Copyright (c) 1991-1997 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer
10 *    in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software withough specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 *  $Id: simple.c,v 1.1 1997/08/17 21:09:35 sos Exp $
29 */
30
31#include <signal.h>
32#include <machine/console.h>
33#include "vgl.h"
34
35static byte VGLSavePaletteRed[256];
36static byte VGLSavePaletteGreen[256];
37static byte VGLSavePaletteBlue[256];
38
39#define ABS(a)		(((a)<0) ? -(a) : (a))
40#define SGN(a)		(((a)<0) ? -1 : 1)
41
42
43void
44VGLSetXY(VGLBitmap *object, int x, int y, byte color)
45{
46  VGLCheckSwitch();
47  if (x>=0 && x<object->Xsize && y>=0 && y<object->Ysize) {
48    if (!VGLMouseFreeze(x, y, 1, 1, color)) {
49      switch (object->Type) {
50      case MEMBUF:
51      case VIDBUF8:
52        object->Bitmap[y*object->Xsize+x]=(color);
53        break;
54      case VIDBUF8X:
55        outb(0x3c4, 0x02);
56        outb(0x3c5, 0x01 << (x&0x3));
57	object->Bitmap[(unsigned)(object->Xsize/2*y)+(x/4)] = (color);
58	break;
59      case VIDBUF4:
60          outb(0x3c4, 0x02); outb(0x3c5, 0x01);
61          outb(0x3ce, 0x04); outb(0x3cf, 0x00);
62	  object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] =
63            ( object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] & ~(0x80>>(x%8)) )
64             |  ((color & 0x01) ? (0x80>>(x%8)) : 0);
65          outb(0x3c4, 0x02); outb(0x3c5, 0x02);
66          outb(0x3ce, 0x04); outb(0x3cf, 0x01);
67	  object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] =
68            ( object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] & ~(0x80>>(x%8)) )
69             |  ((color & 0x02) ? (0x80>>(x%8)) : 0);
70          outb(0x3c4, 0x02); outb(0x3c5, 0x04);
71          outb(0x3ce, 0x04); outb(0x3cf, 0x02);
72	  object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] =
73            ( object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] & ~(0x80>>(x%8)) )
74             |  ((color & 0x04) ? (0x80>>(x%8)) : 0);
75          outb(0x3c4, 0x02); outb(0x3c5, 0x08);
76          outb(0x3ce, 0x04); outb(0x3cf, 0x03);
77	  object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] =
78            ( object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] & ~(0x80>>(x%8)) )
79             |  ((color & 0x08) ? (0x80>>(x%8)) : 0);
80      }
81    }
82    VGLMouseUnFreeze();
83  }
84}
85
86byte
87VGLGetXY(VGLBitmap *object, int x, int y)
88{
89  VGLCheckSwitch();
90  switch (object->Type) {
91    case MEMBUF:
92    case VIDBUF8:
93      return object->Bitmap[((y*object->Xsize)+x)];
94      break;
95    case VIDBUF8X:
96      outb(0x3ce, 0x04); outb(0x3cf, x & 0x3);
97      return object->Bitmap[(unsigned)(object->Xsize/2*y)+(x/4)];
98      break;
99    case VIDBUF4:
100      return (object->Bitmap[((y*object->Xsize/8)+x/8)]&(0x80>>(x%8))) ? 1 : 0;
101      break;
102  }
103  return 0;
104}
105
106void
107VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color)
108{
109  int d, x, y, ax, ay, sx, sy, dx, dy;
110
111  dx = x2-x1; ax = ABS(dx)<<1; sx = SGN(dx); x = x1;
112  dy = y2-y1; ay = ABS(dy)<<1; sy = SGN(dy); y = y1;
113
114  if (ax>ay) {					/* x dominant */
115    d = ay-(ax>>1);
116    for (;;) {
117      VGLSetXY(object, x, y, color);
118      if (x==x2)
119	break;
120      if (d>=0) {
121	y += sy; d -= ax;
122      }
123      x += sx; d += ay;
124    }
125  }
126  else {					/* y dominant */
127    d = ax-(ay>>1);
128    for (;;) {
129      VGLSetXY(object, x, y, color);
130      if (y==y2)
131	break;
132      if (d>=0) {
133	x += sx; d -= ay;
134      }
135      y += sy; d += ax;
136    }
137  }
138}
139
140void
141VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color)
142{
143  VGLLine(object, x1, y1, x2, y1, color);
144  VGLLine(object, x2, y1, x2, y2, color);
145  VGLLine(object, x2, y2, x1, y2, color);
146  VGLLine(object, x1, y2, x1, y1, color);
147}
148
149void
150VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, byte color)
151{
152  int y;
153
154  for (y=y1; y<=y2; y++) VGLLine(object, x1, y, x2, y, color);
155}
156
157void
158inline set4pixels(VGLBitmap *object, int x, int y, int xc, int yc, byte color)
159{
160  if (x!=0) {
161    VGLSetXY(object, xc+x, yc+y, color);
162    VGLSetXY(object, xc-x, yc+y, color);
163    if (y!=0) {
164      VGLSetXY(object, xc+x, yc-y, color);
165      VGLSetXY(object, xc-x, yc-y, color);
166    }
167  }
168  else {
169    VGLSetXY(object, xc, yc+y, color);
170    if (y!=0)
171      VGLSetXY(object, xc, yc-y, color);
172  }
173}
174
175void
176VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, byte color)
177{
178  int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b;
179  int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b;
180
181  while (dx<dy) {
182    set4pixels(object, x, y, xc, yc, color);
183    if (d>0) {
184      y--; dy-=asq2; d-=dy;
185    }
186    x++; dx+=bsq2; d+=bsq+dx;
187  }
188  d+=(3*(asq-bsq)/2-(dx+dy))/2;
189  while (y>=0) {
190    set4pixels(object, x, y, xc, yc, color);
191    if (d<0) {
192      x++; dx+=bsq2; d+=dx;
193    }
194    y--; dy-=asq2; d+=asq-dy;
195  }
196}
197
198void
199inline set2lines(VGLBitmap *object, int x, int y, int xc, int yc, byte color)
200{
201  if (x!=0) {
202    VGLLine(object, xc+x, yc+y, xc-x, yc+y, color);
203    if (y!=0)
204      VGLLine(object, xc+x, yc-y, xc-x, yc-y, color);
205  }
206  else {
207    VGLLine(object, xc, yc+y, xc, yc-y, color);
208  }
209}
210
211void
212VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, byte color)
213{
214  int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b;
215  int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b;
216
217  while (dx<dy) {
218    set2lines(object, x, y, xc, yc, color);
219    if (d>0) {
220      y--; dy-=asq2; d-=dy;
221    }
222    x++; dx+=bsq2; d+=bsq+dx;
223  }
224  d+=(3*(asq-bsq)/2-(dx+dy))/2;
225  while (y>=0) {
226    set2lines(object, x, y, xc, yc, color);
227    if (d<0) {
228      x++; dx+=bsq2; d+=dx;
229    }
230    y--; dy-=asq2; d+=asq-dy;
231  }
232}
233
234void
235VGLClear(VGLBitmap *object, byte color)
236{
237  VGLCheckSwitch();
238  VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color);
239  switch (object->Type) {
240  case MEMBUF:
241  case VIDBUF8:
242    memset(object->Bitmap, color, object->Xsize*object->Ysize);
243    break;
244  case VIDBUF8X:
245    /* XXX works only for Xsize % 4 = 0 */
246    outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
247    memset(object->Bitmap, color, object->Xsize*object->Ysize/4);
248    break;
249
250  case VIDBUF4:
251    /* XXX works only for Xsize % 8 = 0 */
252    memset(object->Bitmap, color, object->Xsize/8*object->Ysize);
253    break;
254  }
255  VGLMouseUnFreeze();
256}
257
258void
259VGLRestorePalette()
260{
261  int i;
262
263  outb(0x3C6, 0xFF);
264  inb(0x3DA);
265  outb(0x3C8, 0x00);
266  for (i=0; i<256; i++) {
267    outb(0x3C9, VGLSavePaletteRed[i]);
268    inb(0x84);
269    outb(0x3C9, VGLSavePaletteGreen[i]);
270    inb(0x84);
271    outb(0x3C9, VGLSavePaletteBlue[i]);
272    inb(0x84);
273  }
274  inb(0x3DA);
275  outb(0x3C0, 0x20);
276}
277
278void
279VGLSavePalette()
280{
281  int i;
282
283  outb(0x3C6, 0xFF);
284  inb(0x3DA);
285  outb(0x3C7, 0x00);
286  for (i=0; i<256; i++) {
287    VGLSavePaletteRed[i] = inb(0x3C9);
288    inb(0x84);
289    VGLSavePaletteGreen[i] = inb(0x3C9);
290    inb(0x84);
291    VGLSavePaletteBlue[i] = inb(0x3C9);
292    inb(0x84);
293  }
294  inb(0x3DA);
295  outb(0x3C0, 0x20);
296}
297
298void
299VGLSetPalette(byte *red, byte *green, byte *blue)
300{
301  int i;
302
303  for (i=0; i<256; i++) {
304    VGLSavePaletteRed[i] = red[i];
305    VGLSavePaletteGreen[i] = green[i];
306    VGLSavePaletteBlue[i] = blue[i];
307  }
308  VGLCheckSwitch();
309  outb(0x3C6, 0xFF);
310  inb(0x3DA);
311  outb(0x3C8, 0x00);
312  for (i=0; i<256; i++) {
313    outb(0x3C9, VGLSavePaletteRed[i]);
314    inb(0x84);
315    outb(0x3C9, VGLSavePaletteGreen[i]);
316    inb(0x84);
317    outb(0x3C9, VGLSavePaletteBlue[i]);
318    inb(0x84);
319  }
320  inb(0x3DA);
321  outb(0x3C0, 0x20);
322}
323
324void
325VGLSetPaletteIndex(byte color, byte red, byte green, byte blue)
326{
327  VGLSavePaletteRed[color] = red;
328  VGLSavePaletteGreen[color] = green;
329  VGLSavePaletteBlue[color] = blue;
330  VGLCheckSwitch();
331  outb(0x3C6, 0xFF);
332  inb(0x3DA);
333  outb(0x3C8, color);
334  outb(0x3C9, red); outb(0x3C9, green); outb(0x3C9, blue);
335  inb(0x3DA);
336  outb(0x3C0, 0x20);
337}
338
339void
340VGLSetBorder(byte color)
341{
342  VGLCheckSwitch();
343  inb(0x3DA);
344  outb(0x3C0,0x11); outb(0x3C0, color);
345  inb(0x3DA);
346  outb(0x3C0, 0x20);
347}
348
349void
350VGLBlankDisplay(int blank)
351{
352  byte val;
353
354  VGLCheckSwitch();
355  outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01);
356  outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF)));
357}
358