19a57b7d2SSøren Schmidt /*- 25e53a4f9SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 35e53a4f9SPedro F. Giffuni * 4bf3f9db6SUlrich Spörlein * Copyright (c) 1991-1997 Søren Schmidt 59a57b7d2SSøren Schmidt * All rights reserved. 69a57b7d2SSøren Schmidt * 79a57b7d2SSøren Schmidt * Redistribution and use in source and binary forms, with or without 89a57b7d2SSøren Schmidt * modification, are permitted provided that the following conditions 99a57b7d2SSøren Schmidt * are met: 109a57b7d2SSøren Schmidt * 1. Redistributions of source code must retain the above copyright 119a57b7d2SSøren Schmidt * notice, this list of conditions and the following disclaimer 129a57b7d2SSøren Schmidt * in this position and unchanged. 139a57b7d2SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 149a57b7d2SSøren Schmidt * notice, this list of conditions and the following disclaimer in the 159a57b7d2SSøren Schmidt * documentation and/or other materials provided with the distribution. 169a57b7d2SSøren Schmidt * 3. The name of the author may not be used to endorse or promote products 1721dc7d4fSJens Schweikhardt * derived from this software without specific prior written permission 189a57b7d2SSøren Schmidt * 199a57b7d2SSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 209a57b7d2SSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 219a57b7d2SSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 229a57b7d2SSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 239a57b7d2SSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 249a57b7d2SSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 259a57b7d2SSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 269a57b7d2SSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 279a57b7d2SSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 289a57b7d2SSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 299a57b7d2SSøren Schmidt */ 309a57b7d2SSøren Schmidt 31e67f5b9fSMatthew Dillon #include <sys/cdefs.h> 32e67f5b9fSMatthew Dillon __FBSDID("$FreeBSD$"); 33e67f5b9fSMatthew Dillon 349a57b7d2SSøren Schmidt #include <signal.h> 3500d25f51SPoul-Henning Kamp #include <sys/fbio.h> 369a57b7d2SSøren Schmidt #include "vgl.h" 379a57b7d2SSøren Schmidt 389a57b7d2SSøren Schmidt static byte VGLSavePaletteRed[256]; 399a57b7d2SSøren Schmidt static byte VGLSavePaletteGreen[256]; 409a57b7d2SSøren Schmidt static byte VGLSavePaletteBlue[256]; 419a57b7d2SSøren Schmidt 429a57b7d2SSøren Schmidt #define ABS(a) (((a)<0) ? -(a) : (a)) 439a57b7d2SSøren Schmidt #define SGN(a) (((a)<0) ? -1 : 1) 445acf51eaSKazutaka YOKOTA #define min(x, y) (((x) < (y)) ? (x) : (y)) 455acf51eaSKazutaka YOKOTA #define max(x, y) (((x) > (y)) ? (x) : (y)) 469a57b7d2SSøren Schmidt 47933d455fSNicolas Souchu static void 48933d455fSNicolas Souchu color2mem(u_long color, byte *b, int len) 49933d455fSNicolas Souchu { 50933d455fSNicolas Souchu switch (len) { 51933d455fSNicolas Souchu case 4: 52933d455fSNicolas Souchu b[3] = (color >> 24) & 0xff; 53933d455fSNicolas Souchu /* fallthrough */ 54933d455fSNicolas Souchu case 3: 55933d455fSNicolas Souchu b[2] = (color >> 16) & 0xff; 56933d455fSNicolas Souchu /* fallthrough */ 57933d455fSNicolas Souchu case 2: 58933d455fSNicolas Souchu b[1] = (color >> 8) & 0xff; 59933d455fSNicolas Souchu /* fallthrough */ 60933d455fSNicolas Souchu case 1: 61933d455fSNicolas Souchu default: 62933d455fSNicolas Souchu b[0] = color & 0xff; 63933d455fSNicolas Souchu break; 64933d455fSNicolas Souchu } 65933d455fSNicolas Souchu 66933d455fSNicolas Souchu return; 67933d455fSNicolas Souchu } 68933d455fSNicolas Souchu 69933d455fSNicolas Souchu static u_long 70933d455fSNicolas Souchu mem2color(byte *b, int len) 71933d455fSNicolas Souchu { 72933d455fSNicolas Souchu u_long color = 0; 73933d455fSNicolas Souchu 74933d455fSNicolas Souchu switch (len) { 75933d455fSNicolas Souchu case 4: 76933d455fSNicolas Souchu color |= (b[3] & 0xff) << 24; 77933d455fSNicolas Souchu /* fallthrough */ 78933d455fSNicolas Souchu case 3: 79933d455fSNicolas Souchu color |= (b[2] & 0xff) << 16; 80933d455fSNicolas Souchu /* fallthrough */ 81933d455fSNicolas Souchu case 2: 82933d455fSNicolas Souchu color |= (b[1] & 0xff) << 8; 83933d455fSNicolas Souchu /* fallthrough */ 84933d455fSNicolas Souchu case 1: 85933d455fSNicolas Souchu default: 86933d455fSNicolas Souchu color |= (b[0] & 0xff); 87933d455fSNicolas Souchu break; 88933d455fSNicolas Souchu } 89933d455fSNicolas Souchu 90933d455fSNicolas Souchu return color; 91933d455fSNicolas Souchu } 92933d455fSNicolas Souchu 939a57b7d2SSøren Schmidt void 94933d455fSNicolas Souchu VGLSetXY(VGLBitmap *object, int x, int y, u_long color) 959a57b7d2SSøren Schmidt { 965acf51eaSKazutaka YOKOTA int offset; 97933d455fSNicolas Souchu byte b[4]; 985acf51eaSKazutaka YOKOTA 999a57b7d2SSøren Schmidt VGLCheckSwitch(); 1005acf51eaSKazutaka YOKOTA if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) { 101014ddcbcSBruce Evans if (object->Type == MEMBUF || 102014ddcbcSBruce Evans !VGLMouseFreeze(x, y, 1, 1, 0x80000000 | color)) { 1039a57b7d2SSøren Schmidt switch (object->Type) { 1049a57b7d2SSøren Schmidt case MEMBUF: 105baca0ce6SBruce Evans switch (object->PixelBytes) { 106baca0ce6SBruce Evans case 2: 107baca0ce6SBruce Evans goto vidbuf16; 108baca0ce6SBruce Evans case 3: 109baca0ce6SBruce Evans goto vidbuf24; 110baca0ce6SBruce Evans case 4: 111baca0ce6SBruce Evans goto vidbuf32; 112baca0ce6SBruce Evans } 113baca0ce6SBruce Evans /* fallthrough */ 1149a57b7d2SSøren Schmidt case VIDBUF8: 115933d455fSNicolas Souchu object->Bitmap[y*object->VXsize+x]=((byte)color); 1165acf51eaSKazutaka YOKOTA break; 1175acf51eaSKazutaka YOKOTA case VIDBUF8S: 118933d455fSNicolas Souchu object->Bitmap[VGLSetSegment(y*object->VXsize+x)]=((byte)color); 119933d455fSNicolas Souchu break; 120933d455fSNicolas Souchu case VIDBUF16: 121baca0ce6SBruce Evans vidbuf16: 122933d455fSNicolas Souchu case VIDBUF24: 123baca0ce6SBruce Evans vidbuf24: 124933d455fSNicolas Souchu case VIDBUF32: 125baca0ce6SBruce Evans vidbuf32: 126933d455fSNicolas Souchu color2mem(color, b, object->PixelBytes); 127933d455fSNicolas Souchu bcopy(b, &object->Bitmap[(y*object->VXsize+x) * object->PixelBytes], 128933d455fSNicolas Souchu object->PixelBytes); 129933d455fSNicolas Souchu break; 130933d455fSNicolas Souchu case VIDBUF16S: 131933d455fSNicolas Souchu case VIDBUF24S: 132933d455fSNicolas Souchu case VIDBUF32S: 133933d455fSNicolas Souchu color2mem(color, b, object->PixelBytes); 134933d455fSNicolas Souchu offset = VGLSetSegment((y*object->VXsize+x) * object->PixelBytes); 135933d455fSNicolas Souchu bcopy(b, &object->Bitmap[offset], object->PixelBytes); 1369a57b7d2SSøren Schmidt break; 1379a57b7d2SSøren Schmidt case VIDBUF8X: 1389a57b7d2SSøren Schmidt outb(0x3c4, 0x02); 1399a57b7d2SSøren Schmidt outb(0x3c5, 0x01 << (x&0x3)); 140933d455fSNicolas Souchu object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = ((byte)color); 1419a57b7d2SSøren Schmidt break; 1425acf51eaSKazutaka YOKOTA case VIDBUF4S: 1435acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 1445acf51eaSKazutaka YOKOTA goto set_planar; 1459a57b7d2SSøren Schmidt case VIDBUF4: 1465acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 1475acf51eaSKazutaka YOKOTA set_planar: 1485acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 149933d455fSNicolas Souchu outb(0x3ce, 0x00); outb(0x3cf, (byte)color & 0x0f); /* set/reset */ 1505acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x0f); /* set/reset enable */ 1515acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8)); /* bit mask */ 152933d455fSNicolas Souchu object->Bitmap[offset] |= (byte)color; 1539a57b7d2SSøren Schmidt } 1549a57b7d2SSøren Schmidt } 155014ddcbcSBruce Evans if (object->Type != MEMBUF) 1569a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 1579a57b7d2SSøren Schmidt } 1589a57b7d2SSøren Schmidt } 1599a57b7d2SSøren Schmidt 160014ddcbcSBruce Evans static u_long 161014ddcbcSBruce Evans __VGLGetXY(VGLBitmap *object, int x, int y) 1629a57b7d2SSøren Schmidt { 1635acf51eaSKazutaka YOKOTA int offset; 164933d455fSNicolas Souchu byte b[4]; 1655acf51eaSKazutaka YOKOTA int i; 166933d455fSNicolas Souchu u_long color; 1675acf51eaSKazutaka YOKOTA byte mask; 1685acf51eaSKazutaka YOKOTA 1699a57b7d2SSøren Schmidt switch (object->Type) { 1709a57b7d2SSøren Schmidt case MEMBUF: 171baca0ce6SBruce Evans switch (object->PixelBytes) { 172baca0ce6SBruce Evans case 2: 173baca0ce6SBruce Evans goto vidbuf16; 174baca0ce6SBruce Evans case 3: 175baca0ce6SBruce Evans goto vidbuf24; 176baca0ce6SBruce Evans case 4: 177baca0ce6SBruce Evans goto vidbuf32; 178baca0ce6SBruce Evans } 179baca0ce6SBruce Evans /* fallthrough */ 1809a57b7d2SSøren Schmidt case VIDBUF8: 1815acf51eaSKazutaka YOKOTA return object->Bitmap[((y*object->VXsize)+x)]; 1825acf51eaSKazutaka YOKOTA case VIDBUF8S: 1835acf51eaSKazutaka YOKOTA return object->Bitmap[VGLSetSegment(y*object->VXsize+x)]; 184933d455fSNicolas Souchu case VIDBUF16: 185baca0ce6SBruce Evans vidbuf16: 186933d455fSNicolas Souchu case VIDBUF24: 187baca0ce6SBruce Evans vidbuf24: 188933d455fSNicolas Souchu case VIDBUF32: 189baca0ce6SBruce Evans vidbuf32: 190933d455fSNicolas Souchu bcopy(&object->Bitmap[(y*object->VXsize+x) * object->PixelBytes], 191933d455fSNicolas Souchu b, object->PixelBytes); 192933d455fSNicolas Souchu return (mem2color(b, object->PixelBytes)); 193933d455fSNicolas Souchu case VIDBUF16S: 194933d455fSNicolas Souchu case VIDBUF24S: 195933d455fSNicolas Souchu case VIDBUF32S: 196933d455fSNicolas Souchu offset = VGLSetSegment((y*object->VXsize+x) * object->PixelBytes); 197933d455fSNicolas Souchu bcopy(&object->Bitmap[offset], b, object->PixelBytes); 198933d455fSNicolas Souchu 199933d455fSNicolas Souchu return (mem2color(b, object->PixelBytes)); 2009a57b7d2SSøren Schmidt case VIDBUF8X: 2019a57b7d2SSøren Schmidt outb(0x3ce, 0x04); outb(0x3cf, x & 0x3); 2025acf51eaSKazutaka YOKOTA return object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)]; 2035acf51eaSKazutaka YOKOTA case VIDBUF4S: 2045acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 2055acf51eaSKazutaka YOKOTA goto get_planar; 2069a57b7d2SSøren Schmidt case VIDBUF4: 2075acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 2085acf51eaSKazutaka YOKOTA get_planar: 2095acf51eaSKazutaka YOKOTA color = 0; 2105acf51eaSKazutaka YOKOTA mask = 0x80 >> (x%8); 2115acf51eaSKazutaka YOKOTA for (i = 0; i < VGLModeInfo.vi_planes; i++) { 2125acf51eaSKazutaka YOKOTA outb(0x3ce, 0x04); outb(0x3cf, i); 2131382e2a9SBruce Evans color |= (((volatile VGLBitmap *)object)->Bitmap[offset] & mask) ? 2141382e2a9SBruce Evans (1 << i) : 0; 2155acf51eaSKazutaka YOKOTA } 2165acf51eaSKazutaka YOKOTA return color; 2179a57b7d2SSøren Schmidt } 218933d455fSNicolas Souchu return 0; /* XXX black? */ 2199a57b7d2SSøren Schmidt } 2209a57b7d2SSøren Schmidt 221014ddcbcSBruce Evans u_long 222014ddcbcSBruce Evans VGLGetXY(VGLBitmap *object, int x, int y) 223014ddcbcSBruce Evans { 224014ddcbcSBruce Evans u_long color; 225014ddcbcSBruce Evans 226014ddcbcSBruce Evans VGLCheckSwitch(); 227014ddcbcSBruce Evans if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize) 228014ddcbcSBruce Evans return 0; 229014ddcbcSBruce Evans if (object->Type != MEMBUF) { 230014ddcbcSBruce Evans color = VGLMouseFreeze(x, y, 1, 1, 0x40000000); 231014ddcbcSBruce Evans if (color & 0x40000000) { 232014ddcbcSBruce Evans VGLMouseUnFreeze(); 233014ddcbcSBruce Evans return color & 0xffffff; 234014ddcbcSBruce Evans } 235014ddcbcSBruce Evans } 236014ddcbcSBruce Evans color = __VGLGetXY(object, x, y); 237014ddcbcSBruce Evans if (object->Type != MEMBUF) 238014ddcbcSBruce Evans VGLMouseUnFreeze(); 239014ddcbcSBruce Evans return color; 240014ddcbcSBruce Evans } 241014ddcbcSBruce Evans 2424c995944SPedro F. Giffuni /* 2434c995944SPedro F. Giffuni * Symmetric Double Step Line Algorithm by Brian Wyvill from 2444c995944SPedro F. Giffuni * "Graphics Gems", Academic Press, 1990. 2454c995944SPedro F. Giffuni */ 2464c995944SPedro F. Giffuni 2474c995944SPedro F. Giffuni #define SL_SWAP(a,b) {a^=b; b^=a; a^=b;} 2484c995944SPedro F. Giffuni #define SL_ABSOLUTE(i,j,k) ( (i-j)*(k = ( (i-j)<0 ? -1 : 1))) 2494c995944SPedro F. Giffuni 2504c995944SPedro F. Giffuni void 251*5ee94e99SBruce Evans plot(VGLBitmap * object, int x, int y, int flag, u_long color) 2524c995944SPedro F. Giffuni { 2534c995944SPedro F. Giffuni /* non-zero flag indicates the pixels need swapping back. */ 2544c995944SPedro F. Giffuni if (flag) 2554c995944SPedro F. Giffuni VGLSetXY(object, y, x, color); 2564c995944SPedro F. Giffuni else 2574c995944SPedro F. Giffuni VGLSetXY(object, x, y, color); 2584c995944SPedro F. Giffuni } 2594c995944SPedro F. Giffuni 2604c995944SPedro F. Giffuni 2619a57b7d2SSøren Schmidt void 262933d455fSNicolas Souchu VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 2639a57b7d2SSøren Schmidt { 2644c995944SPedro F. Giffuni int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left; 2654c995944SPedro F. Giffuni int sign_x, sign_y, step, reverse, i; 2669a57b7d2SSøren Schmidt 2674c995944SPedro F. Giffuni dx = SL_ABSOLUTE(x2, x1, sign_x); 2684c995944SPedro F. Giffuni dy = SL_ABSOLUTE(y2, y1, sign_y); 2694c995944SPedro F. Giffuni /* decide increment sign by the slope sign */ 2704c995944SPedro F. Giffuni if (sign_x == sign_y) 2714c995944SPedro F. Giffuni step = 1; 2724c995944SPedro F. Giffuni else 2734c995944SPedro F. Giffuni step = -1; 2749a57b7d2SSøren Schmidt 2754c995944SPedro F. Giffuni if (dy > dx) { /* chooses axis of greatest movement (make dx) */ 2764c995944SPedro F. Giffuni SL_SWAP(x1, y1); 2774c995944SPedro F. Giffuni SL_SWAP(x2, y2); 2784c995944SPedro F. Giffuni SL_SWAP(dx, dy); 2794c995944SPedro F. Giffuni reverse = 1; 2804c995944SPedro F. Giffuni } else 2814c995944SPedro F. Giffuni reverse = 0; 2824c995944SPedro F. Giffuni /* note error check for dx==0 should be included here */ 2834c995944SPedro F. Giffuni if (x1 > x2) { /* start from the smaller coordinate */ 2844c995944SPedro F. Giffuni x = x2; 2854c995944SPedro F. Giffuni y = y2; 28683057bafSPedro F. Giffuni /* x1 = x1; 28783057bafSPedro F. Giffuni y1 = y1; */ 2884c995944SPedro F. Giffuni } else { 2894c995944SPedro F. Giffuni x = x1; 2904c995944SPedro F. Giffuni y = y1; 2914c995944SPedro F. Giffuni x1 = x2; 2924c995944SPedro F. Giffuni y1 = y2; 2939a57b7d2SSøren Schmidt } 2944c995944SPedro F. Giffuni 2954c995944SPedro F. Giffuni 2964c995944SPedro F. Giffuni /* Note dx=n implies 0 - n or (dx+1) pixels to be set */ 2974c995944SPedro F. Giffuni /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */ 2984c995944SPedro F. Giffuni /* In fact (dx-1)/4 as 2 pixels are already plotted */ 2994c995944SPedro F. Giffuni xend = (dx - 1) / 4; 3004c995944SPedro F. Giffuni pixels_left = (dx - 1) % 4; /* number of pixels left over at the 3014c995944SPedro F. Giffuni * end */ 3024c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3034c995944SPedro F. Giffuni if (pixels_left < 0) 3044c995944SPedro F. Giffuni return; /* plot only one pixel for zero length 3054c995944SPedro F. Giffuni * vectors */ 3064c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); /* plot first two points */ 3074c995944SPedro F. Giffuni incr2 = 4 * dy - 2 * dx; 3084c995944SPedro F. Giffuni if (incr2 < 0) { /* slope less than 1/2 */ 3094c995944SPedro F. Giffuni c = 2 * dy; 3104c995944SPedro F. Giffuni incr1 = 2 * c; 3114c995944SPedro F. Giffuni D = incr1 - dx; 3124c995944SPedro F. Giffuni 3134c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { /* plotting loop */ 3144c995944SPedro F. Giffuni ++x; 3154c995944SPedro F. Giffuni --x1; 3164c995944SPedro F. Giffuni if (D < 0) { 3174c995944SPedro F. Giffuni /* pattern 1 forwards */ 3184c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3194c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3204c995944SPedro F. Giffuni /* pattern 1 backwards */ 3214c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 3224c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3234c995944SPedro F. Giffuni D += incr1; 3244c995944SPedro F. Giffuni } else { 3254c995944SPedro F. Giffuni if (D < c) { 3264c995944SPedro F. Giffuni /* pattern 2 forwards */ 3274c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3284c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3294c995944SPedro F. Giffuni color); 3304c995944SPedro F. Giffuni /* pattern 2 backwards */ 3314c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 3324c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3334c995944SPedro F. Giffuni color); 3344c995944SPedro F. Giffuni } else { 3354c995944SPedro F. Giffuni /* pattern 3 forwards */ 3364c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3374c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3384c995944SPedro F. Giffuni /* pattern 3 backwards */ 3394c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, 3404c995944SPedro F. Giffuni color); 3414c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3424c995944SPedro F. Giffuni } 3434c995944SPedro F. Giffuni D += incr2; 3444c995944SPedro F. Giffuni } 3454c995944SPedro F. Giffuni } /* end for */ 3464c995944SPedro F. Giffuni 3474c995944SPedro F. Giffuni /* plot last pattern */ 3484c995944SPedro F. Giffuni if (pixels_left) { 3494c995944SPedro F. Giffuni if (D < 0) { 3504c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 1 */ 3514c995944SPedro F. Giffuni if (pixels_left > 1) 3524c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3534c995944SPedro F. Giffuni if (pixels_left > 2) 3544c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3554c995944SPedro F. Giffuni } else { 3564c995944SPedro F. Giffuni if (D < c) { 3574c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 3584c995944SPedro F. Giffuni if (pixels_left > 1) 3594c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3604c995944SPedro F. Giffuni if (pixels_left > 2) 3614c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3624c995944SPedro F. Giffuni } else { 3634c995944SPedro F. Giffuni /* pattern 3 */ 3644c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3654c995944SPedro F. Giffuni if (pixels_left > 1) 3664c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3674c995944SPedro F. Giffuni if (pixels_left > 2) 3684c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3699a57b7d2SSøren Schmidt } 3709a57b7d2SSøren Schmidt } 3714c995944SPedro F. Giffuni } /* end if pixels_left */ 3729a57b7d2SSøren Schmidt } 3734c995944SPedro F. Giffuni /* end slope < 1/2 */ 3744c995944SPedro F. Giffuni else { /* slope greater than 1/2 */ 3754c995944SPedro F. Giffuni c = 2 * (dy - dx); 3764c995944SPedro F. Giffuni incr1 = 2 * c; 3774c995944SPedro F. Giffuni D = incr1 + dx; 3784c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { 3794c995944SPedro F. Giffuni ++x; 3804c995944SPedro F. Giffuni --x1; 3814c995944SPedro F. Giffuni if (D > 0) { 3824c995944SPedro F. Giffuni /* pattern 4 forwards */ 3834c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3844c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3854c995944SPedro F. Giffuni /* pattern 4 backwards */ 3864c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3874c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3884c995944SPedro F. Giffuni D += incr1; 3894c995944SPedro F. Giffuni } else { 3904c995944SPedro F. Giffuni if (D < c) { 3914c995944SPedro F. Giffuni /* pattern 2 forwards */ 3924c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3934c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3944c995944SPedro F. Giffuni color); 3954c995944SPedro F. Giffuni 3964c995944SPedro F. Giffuni /* pattern 2 backwards */ 3974c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 3984c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3994c995944SPedro F. Giffuni color); 4004c995944SPedro F. Giffuni } else { 4014c995944SPedro F. Giffuni /* pattern 3 forwards */ 4024c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 4034c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 4044c995944SPedro F. Giffuni /* pattern 3 backwards */ 4054c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 4064c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 4074c995944SPedro F. Giffuni } 4084c995944SPedro F. Giffuni D += incr2; 4094c995944SPedro F. Giffuni } 4104c995944SPedro F. Giffuni } /* end for */ 4114c995944SPedro F. Giffuni /* plot last pattern */ 4124c995944SPedro F. Giffuni if (pixels_left) { 4134c995944SPedro F. Giffuni if (D > 0) { 4144c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); /* pattern 4 */ 4154c995944SPedro F. Giffuni if (pixels_left > 1) 4164c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 4174c995944SPedro F. Giffuni color); 4184c995944SPedro F. Giffuni if (pixels_left > 2) 4194c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 4204c995944SPedro F. Giffuni color); 4214c995944SPedro F. Giffuni } else { 4224c995944SPedro F. Giffuni if (D < c) { 4234c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 4244c995944SPedro F. Giffuni if (pixels_left > 1) 4254c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 4264c995944SPedro F. Giffuni if (pixels_left > 2) 4274c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 4284c995944SPedro F. Giffuni } else { 4294c995944SPedro F. Giffuni /* pattern 3 */ 4304c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 4314c995944SPedro F. Giffuni if (pixels_left > 1) 4324c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 4334c995944SPedro F. Giffuni if (pixels_left > 2) { 4344c995944SPedro F. Giffuni if (D > c) /* step 3 */ 4354c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 4364c995944SPedro F. Giffuni else /* step 2 */ 4374c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 4384c995944SPedro F. Giffuni } 4394c995944SPedro F. Giffuni } 4404c995944SPedro F. Giffuni } 4419a57b7d2SSøren Schmidt } 4429a57b7d2SSøren Schmidt } 4439a57b7d2SSøren Schmidt } 4449a57b7d2SSøren Schmidt 4459a57b7d2SSøren Schmidt void 446933d455fSNicolas Souchu VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 4479a57b7d2SSøren Schmidt { 4489a57b7d2SSøren Schmidt VGLLine(object, x1, y1, x2, y1, color); 4499a57b7d2SSøren Schmidt VGLLine(object, x2, y1, x2, y2, color); 4509a57b7d2SSøren Schmidt VGLLine(object, x2, y2, x1, y2, color); 4519a57b7d2SSøren Schmidt VGLLine(object, x1, y2, x1, y1, color); 4529a57b7d2SSøren Schmidt } 4539a57b7d2SSøren Schmidt 4549a57b7d2SSøren Schmidt void 455933d455fSNicolas Souchu VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 4569a57b7d2SSøren Schmidt { 4579a57b7d2SSøren Schmidt int y; 4589a57b7d2SSøren Schmidt 4599a57b7d2SSøren Schmidt for (y=y1; y<=y2; y++) VGLLine(object, x1, y, x2, y, color); 4609a57b7d2SSøren Schmidt } 4619a57b7d2SSøren Schmidt 462e7032b4cSDimitry Andric static inline void 463e7032b4cSDimitry Andric set4pixels(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 4649a57b7d2SSøren Schmidt { 4659a57b7d2SSøren Schmidt if (x!=0) { 4669a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc+y, color); 4679a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc+y, color); 4689a57b7d2SSøren Schmidt if (y!=0) { 4699a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc-y, color); 4709a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc-y, color); 4719a57b7d2SSøren Schmidt } 4729a57b7d2SSøren Schmidt } 4739a57b7d2SSøren Schmidt else { 4749a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc+y, color); 4759a57b7d2SSøren Schmidt if (y!=0) 4769a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc-y, color); 4779a57b7d2SSøren Schmidt } 4789a57b7d2SSøren Schmidt } 4799a57b7d2SSøren Schmidt 4809a57b7d2SSøren Schmidt void 481933d455fSNicolas Souchu VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 4829a57b7d2SSøren Schmidt { 4839a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 4849a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 4859a57b7d2SSøren Schmidt 4869a57b7d2SSøren Schmidt while (dx<dy) { 4879a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4889a57b7d2SSøren Schmidt if (d>0) { 4899a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4909a57b7d2SSøren Schmidt } 4919a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4929a57b7d2SSøren Schmidt } 4939a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4949a57b7d2SSøren Schmidt while (y>=0) { 4959a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4969a57b7d2SSøren Schmidt if (d<0) { 4979a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4989a57b7d2SSøren Schmidt } 4999a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 5009a57b7d2SSøren Schmidt } 5019a57b7d2SSøren Schmidt } 5029a57b7d2SSøren Schmidt 503e7032b4cSDimitry Andric static inline void 504e7032b4cSDimitry Andric set2lines(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 5059a57b7d2SSøren Schmidt { 5069a57b7d2SSøren Schmidt if (x!=0) { 5079a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc+y, xc-x, yc+y, color); 5089a57b7d2SSøren Schmidt if (y!=0) 5099a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc-y, xc-x, yc-y, color); 5109a57b7d2SSøren Schmidt } 5119a57b7d2SSøren Schmidt else { 5129a57b7d2SSøren Schmidt VGLLine(object, xc, yc+y, xc, yc-y, color); 5139a57b7d2SSøren Schmidt } 5149a57b7d2SSøren Schmidt } 5159a57b7d2SSøren Schmidt 5169a57b7d2SSøren Schmidt void 517933d455fSNicolas Souchu VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 5189a57b7d2SSøren Schmidt { 5199a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 5209a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 5219a57b7d2SSøren Schmidt 5229a57b7d2SSøren Schmidt while (dx<dy) { 5239a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 5249a57b7d2SSøren Schmidt if (d>0) { 5259a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 5269a57b7d2SSøren Schmidt } 5279a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 5289a57b7d2SSøren Schmidt } 5299a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 5309a57b7d2SSøren Schmidt while (y>=0) { 5319a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 5329a57b7d2SSøren Schmidt if (d<0) { 5339a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 5349a57b7d2SSøren Schmidt } 5359a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 5369a57b7d2SSøren Schmidt } 5379a57b7d2SSøren Schmidt } 5389a57b7d2SSøren Schmidt 5399a57b7d2SSøren Schmidt void 540933d455fSNicolas Souchu VGLClear(VGLBitmap *object, u_long color) 5419a57b7d2SSøren Schmidt { 5425acf51eaSKazutaka YOKOTA int offset; 5435acf51eaSKazutaka YOKOTA int len; 544933d455fSNicolas Souchu int i, total = 0; 545933d455fSNicolas Souchu byte b[4]; 5465acf51eaSKazutaka YOKOTA 5479a57b7d2SSøren Schmidt VGLCheckSwitch(); 548014ddcbcSBruce Evans if (object->Type != MEMBUF) 549014ddcbcSBruce Evans VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color); 5509a57b7d2SSøren Schmidt switch (object->Type) { 5519a57b7d2SSøren Schmidt case MEMBUF: 552baca0ce6SBruce Evans switch (object->PixelBytes) { 553baca0ce6SBruce Evans case 2: 554baca0ce6SBruce Evans goto vidbuf16; 555baca0ce6SBruce Evans case 3: 556baca0ce6SBruce Evans goto vidbuf24; 557baca0ce6SBruce Evans case 4: 558baca0ce6SBruce Evans goto vidbuf32; 559baca0ce6SBruce Evans } 560baca0ce6SBruce Evans /* fallthrough */ 5619a57b7d2SSøren Schmidt case VIDBUF8: 562933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, object->VXsize*object->VYsize); 5639a57b7d2SSøren Schmidt break; 5645acf51eaSKazutaka YOKOTA 5655acf51eaSKazutaka YOKOTA case VIDBUF8S: 5665acf51eaSKazutaka YOKOTA for (offset = 0; offset < object->VXsize*object->VYsize; ) { 5675acf51eaSKazutaka YOKOTA VGLSetSegment(offset); 5685acf51eaSKazutaka YOKOTA len = min(object->VXsize*object->VYsize - offset, 5695acf51eaSKazutaka YOKOTA VGLAdpInfo.va_window_size); 570933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, len); 571933d455fSNicolas Souchu offset += len; 572933d455fSNicolas Souchu } 573933d455fSNicolas Souchu break; 574933d455fSNicolas Souchu case VIDBUF16: 575baca0ce6SBruce Evans vidbuf16: 576933d455fSNicolas Souchu case VIDBUF24: 577baca0ce6SBruce Evans vidbuf24: 578933d455fSNicolas Souchu case VIDBUF32: 579baca0ce6SBruce Evans vidbuf32: 580933d455fSNicolas Souchu color2mem(color, b, object->PixelBytes); 581933d455fSNicolas Souchu total = object->VXsize*object->VYsize*object->PixelBytes; 582933d455fSNicolas Souchu for (i = 0; i < total; i += object->PixelBytes) 583933d455fSNicolas Souchu bcopy(b, object->Bitmap + i, object->PixelBytes); 584933d455fSNicolas Souchu break; 585933d455fSNicolas Souchu 586933d455fSNicolas Souchu case VIDBUF16S: 587933d455fSNicolas Souchu case VIDBUF24S: 588933d455fSNicolas Souchu case VIDBUF32S: 589933d455fSNicolas Souchu color2mem(color, b, object->PixelBytes); 590933d455fSNicolas Souchu total = object->VXsize*object->VYsize*object->PixelBytes; 591933d455fSNicolas Souchu for (offset = 0; offset < total; ) { 592933d455fSNicolas Souchu VGLSetSegment(offset); 593933d455fSNicolas Souchu len = min(total - offset, VGLAdpInfo.va_window_size); 594933d455fSNicolas Souchu for (i = 0; i < len; i += object->PixelBytes) 595fa68d9b9SBruce Evans bcopy(b, object->Bitmap + (offset + i) % VGLAdpInfo.va_window_size, 596dac776fdSBruce Evans object->PixelBytes); 5975acf51eaSKazutaka YOKOTA offset += len; 5985acf51eaSKazutaka YOKOTA } 5995acf51eaSKazutaka YOKOTA break; 6005acf51eaSKazutaka YOKOTA 6019a57b7d2SSøren Schmidt case VIDBUF8X: 6029a57b7d2SSøren Schmidt /* XXX works only for Xsize % 4 = 0 */ 6035acf51eaSKazutaka YOKOTA outb(0x3c6, 0xff); 6049a57b7d2SSøren Schmidt outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 605933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, VGLAdpInfo.va_line_width*object->VYsize); 6069a57b7d2SSøren Schmidt break; 6079a57b7d2SSøren Schmidt 6089a57b7d2SSøren Schmidt case VIDBUF4: 6095acf51eaSKazutaka YOKOTA case VIDBUF4S: 6109a57b7d2SSøren Schmidt /* XXX works only for Xsize % 8 = 0 */ 6115acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 6125acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */ 6135acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 6145acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 6155acf51eaSKazutaka YOKOTA for (offset = 0; offset < VGLAdpInfo.va_line_width*object->VYsize; ) { 6165acf51eaSKazutaka YOKOTA VGLSetSegment(offset); 6175acf51eaSKazutaka YOKOTA len = min(object->VXsize*object->VYsize - offset, 6185acf51eaSKazutaka YOKOTA VGLAdpInfo.va_window_size); 619933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, len); 6205acf51eaSKazutaka YOKOTA offset += len; 6215acf51eaSKazutaka YOKOTA } 6225acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x00); 6239a57b7d2SSøren Schmidt break; 6249a57b7d2SSøren Schmidt } 625014ddcbcSBruce Evans if (object->Type != MEMBUF) 6269a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 6279a57b7d2SSøren Schmidt } 6289a57b7d2SSøren Schmidt 6299a57b7d2SSøren Schmidt void 6309a57b7d2SSøren Schmidt VGLRestorePalette() 6319a57b7d2SSøren Schmidt { 6329a57b7d2SSøren Schmidt int i; 6339a57b7d2SSøren Schmidt 6349a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6359a57b7d2SSøren Schmidt inb(0x3DA); 6369a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 6379a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6389a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 6399a57b7d2SSøren Schmidt inb(0x84); 6409a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 6419a57b7d2SSøren Schmidt inb(0x84); 6429a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 6439a57b7d2SSøren Schmidt inb(0x84); 6449a57b7d2SSøren Schmidt } 6459a57b7d2SSøren Schmidt inb(0x3DA); 6469a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6479a57b7d2SSøren Schmidt } 6489a57b7d2SSøren Schmidt 6499a57b7d2SSøren Schmidt void 6509a57b7d2SSøren Schmidt VGLSavePalette() 6519a57b7d2SSøren Schmidt { 6529a57b7d2SSøren Schmidt int i; 6539a57b7d2SSøren Schmidt 6549a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6559a57b7d2SSøren Schmidt inb(0x3DA); 6569a57b7d2SSøren Schmidt outb(0x3C7, 0x00); 6579a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6589a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = inb(0x3C9); 6599a57b7d2SSøren Schmidt inb(0x84); 6609a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = inb(0x3C9); 6619a57b7d2SSøren Schmidt inb(0x84); 6629a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = inb(0x3C9); 6639a57b7d2SSøren Schmidt inb(0x84); 6649a57b7d2SSøren Schmidt } 6659a57b7d2SSøren Schmidt inb(0x3DA); 6669a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6679a57b7d2SSøren Schmidt } 6689a57b7d2SSøren Schmidt 6699a57b7d2SSøren Schmidt void 6709a57b7d2SSøren Schmidt VGLSetPalette(byte *red, byte *green, byte *blue) 6719a57b7d2SSøren Schmidt { 6729a57b7d2SSøren Schmidt int i; 6739a57b7d2SSøren Schmidt 6749a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6759a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = red[i]; 6769a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = green[i]; 6779a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = blue[i]; 6789a57b7d2SSøren Schmidt } 6799a57b7d2SSøren Schmidt VGLCheckSwitch(); 6809a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6819a57b7d2SSøren Schmidt inb(0x3DA); 6829a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 6839a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6849a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 6859a57b7d2SSøren Schmidt inb(0x84); 6869a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 6879a57b7d2SSøren Schmidt inb(0x84); 6889a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 6899a57b7d2SSøren Schmidt inb(0x84); 6909a57b7d2SSøren Schmidt } 6919a57b7d2SSøren Schmidt inb(0x3DA); 6929a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6939a57b7d2SSøren Schmidt } 6949a57b7d2SSøren Schmidt 6959a57b7d2SSøren Schmidt void 6969a57b7d2SSøren Schmidt VGLSetPaletteIndex(byte color, byte red, byte green, byte blue) 6979a57b7d2SSøren Schmidt { 6989a57b7d2SSøren Schmidt VGLSavePaletteRed[color] = red; 6999a57b7d2SSøren Schmidt VGLSavePaletteGreen[color] = green; 7009a57b7d2SSøren Schmidt VGLSavePaletteBlue[color] = blue; 7019a57b7d2SSøren Schmidt VGLCheckSwitch(); 7029a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 7039a57b7d2SSøren Schmidt inb(0x3DA); 7049a57b7d2SSøren Schmidt outb(0x3C8, color); 7059a57b7d2SSøren Schmidt outb(0x3C9, red); outb(0x3C9, green); outb(0x3C9, blue); 7069a57b7d2SSøren Schmidt inb(0x3DA); 7079a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 7089a57b7d2SSøren Schmidt } 7099a57b7d2SSøren Schmidt 7109a57b7d2SSøren Schmidt void 7119a57b7d2SSøren Schmidt VGLSetBorder(byte color) 7129a57b7d2SSøren Schmidt { 7139a57b7d2SSøren Schmidt VGLCheckSwitch(); 7149a57b7d2SSøren Schmidt inb(0x3DA); 7159a57b7d2SSøren Schmidt outb(0x3C0,0x11); outb(0x3C0, color); 7169a57b7d2SSøren Schmidt inb(0x3DA); 7179a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 7189a57b7d2SSøren Schmidt } 7199a57b7d2SSøren Schmidt 7209a57b7d2SSøren Schmidt void 7219a57b7d2SSøren Schmidt VGLBlankDisplay(int blank) 7229a57b7d2SSøren Schmidt { 7239a57b7d2SSøren Schmidt byte val; 7249a57b7d2SSøren Schmidt 7259a57b7d2SSøren Schmidt VGLCheckSwitch(); 7269a57b7d2SSøren Schmidt outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01); 7279a57b7d2SSøren Schmidt outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF))); 7289a57b7d2SSøren Schmidt } 729