19a57b7d2SSøren Schmidt /*- 29a57b7d2SSøren Schmidt * Copyright (c) 1991-1997 S�ren Schmidt 39a57b7d2SSøren Schmidt * All rights reserved. 49a57b7d2SSøren Schmidt * 59a57b7d2SSøren Schmidt * Redistribution and use in source and binary forms, with or without 69a57b7d2SSøren Schmidt * modification, are permitted provided that the following conditions 79a57b7d2SSøren Schmidt * are met: 89a57b7d2SSøren Schmidt * 1. Redistributions of source code must retain the above copyright 99a57b7d2SSøren Schmidt * notice, this list of conditions and the following disclaimer 109a57b7d2SSøren Schmidt * in this position and unchanged. 119a57b7d2SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 129a57b7d2SSøren Schmidt * notice, this list of conditions and the following disclaimer in the 139a57b7d2SSøren Schmidt * documentation and/or other materials provided with the distribution. 149a57b7d2SSøren Schmidt * 3. The name of the author may not be used to endorse or promote products 1521dc7d4fSJens Schweikhardt * derived from this software without specific prior written permission 169a57b7d2SSøren Schmidt * 179a57b7d2SSøren Schmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 189a57b7d2SSøren Schmidt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 199a57b7d2SSøren Schmidt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 209a57b7d2SSøren Schmidt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 219a57b7d2SSøren Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 229a57b7d2SSøren Schmidt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239a57b7d2SSøren Schmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249a57b7d2SSøren Schmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259a57b7d2SSøren Schmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 269a57b7d2SSøren Schmidt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279a57b7d2SSøren Schmidt */ 289a57b7d2SSøren Schmidt 29e67f5b9fSMatthew Dillon #include <sys/cdefs.h> 30e67f5b9fSMatthew Dillon __FBSDID("$FreeBSD$"); 31e67f5b9fSMatthew Dillon 329a57b7d2SSøren Schmidt #include <signal.h> 3300d25f51SPoul-Henning Kamp #include <sys/fbio.h> 349a57b7d2SSøren Schmidt #include "vgl.h" 359a57b7d2SSøren Schmidt 369a57b7d2SSøren Schmidt static byte VGLSavePaletteRed[256]; 379a57b7d2SSøren Schmidt static byte VGLSavePaletteGreen[256]; 389a57b7d2SSøren Schmidt static byte VGLSavePaletteBlue[256]; 399a57b7d2SSøren Schmidt 409a57b7d2SSøren Schmidt #define ABS(a) (((a)<0) ? -(a) : (a)) 419a57b7d2SSøren Schmidt #define SGN(a) (((a)<0) ? -1 : 1) 425acf51eaSKazutaka YOKOTA #define min(x, y) (((x) < (y)) ? (x) : (y)) 435acf51eaSKazutaka YOKOTA #define max(x, y) (((x) > (y)) ? (x) : (y)) 449a57b7d2SSøren Schmidt 45933d455fSNicolas Souchu static void 46933d455fSNicolas Souchu color2mem(u_long color, byte *b, int len) 47933d455fSNicolas Souchu { 48933d455fSNicolas Souchu switch (len) { 49933d455fSNicolas Souchu case 4: 50933d455fSNicolas Souchu b[3] = (color >> 24) & 0xff; 51933d455fSNicolas Souchu /* fallthrough */ 52933d455fSNicolas Souchu case 3: 53933d455fSNicolas Souchu b[2] = (color >> 16) & 0xff; 54933d455fSNicolas Souchu /* fallthrough */ 55933d455fSNicolas Souchu case 2: 56933d455fSNicolas Souchu b[1] = (color >> 8) & 0xff; 57933d455fSNicolas Souchu /* fallthrough */ 58933d455fSNicolas Souchu case 1: 59933d455fSNicolas Souchu default: 60933d455fSNicolas Souchu b[0] = color & 0xff; 61933d455fSNicolas Souchu break; 62933d455fSNicolas Souchu } 63933d455fSNicolas Souchu 64933d455fSNicolas Souchu return; 65933d455fSNicolas Souchu } 66933d455fSNicolas Souchu 67933d455fSNicolas Souchu static u_long 68933d455fSNicolas Souchu mem2color(byte *b, int len) 69933d455fSNicolas Souchu { 70933d455fSNicolas Souchu u_long color = 0; 71933d455fSNicolas Souchu 72933d455fSNicolas Souchu switch (len) { 73933d455fSNicolas Souchu case 4: 74933d455fSNicolas Souchu color |= (b[3] & 0xff) << 24; 75933d455fSNicolas Souchu /* fallthrough */ 76933d455fSNicolas Souchu case 3: 77933d455fSNicolas Souchu color |= (b[2] & 0xff) << 16; 78933d455fSNicolas Souchu /* fallthrough */ 79933d455fSNicolas Souchu case 2: 80933d455fSNicolas Souchu color |= (b[1] & 0xff) << 8; 81933d455fSNicolas Souchu /* fallthrough */ 82933d455fSNicolas Souchu case 1: 83933d455fSNicolas Souchu default: 84933d455fSNicolas Souchu color |= (b[0] & 0xff); 85933d455fSNicolas Souchu break; 86933d455fSNicolas Souchu } 87933d455fSNicolas Souchu 88933d455fSNicolas Souchu return color; 89933d455fSNicolas Souchu } 90933d455fSNicolas Souchu 919a57b7d2SSøren Schmidt void 92933d455fSNicolas Souchu VGLSetXY(VGLBitmap *object, int x, int y, u_long color) 939a57b7d2SSøren Schmidt { 945acf51eaSKazutaka YOKOTA int offset; 95933d455fSNicolas Souchu byte b[4]; 965acf51eaSKazutaka YOKOTA 979a57b7d2SSøren Schmidt VGLCheckSwitch(); 985acf51eaSKazutaka YOKOTA if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) { 999a57b7d2SSøren Schmidt if (!VGLMouseFreeze(x, y, 1, 1, color)) { 1009a57b7d2SSøren Schmidt switch (object->Type) { 1019a57b7d2SSøren Schmidt case MEMBUF: 1029a57b7d2SSøren Schmidt case VIDBUF8: 103933d455fSNicolas Souchu object->Bitmap[y*object->VXsize+x]=((byte)color); 1045acf51eaSKazutaka YOKOTA break; 1055acf51eaSKazutaka YOKOTA case VIDBUF8S: 106933d455fSNicolas Souchu object->Bitmap[VGLSetSegment(y*object->VXsize+x)]=((byte)color); 107933d455fSNicolas Souchu break; 108933d455fSNicolas Souchu case VIDBUF16: 109933d455fSNicolas Souchu case VIDBUF24: 110933d455fSNicolas Souchu case VIDBUF32: 111933d455fSNicolas Souchu color2mem(color, b, object->PixelBytes); 112933d455fSNicolas Souchu bcopy(b, &object->Bitmap[(y*object->VXsize+x) * object->PixelBytes], 113933d455fSNicolas Souchu object->PixelBytes); 114933d455fSNicolas Souchu break; 115933d455fSNicolas Souchu case VIDBUF16S: 116933d455fSNicolas Souchu case VIDBUF24S: 117933d455fSNicolas Souchu case VIDBUF32S: 118933d455fSNicolas Souchu color2mem(color, b, object->PixelBytes); 119933d455fSNicolas Souchu offset = VGLSetSegment((y*object->VXsize+x) * object->PixelBytes); 120933d455fSNicolas Souchu bcopy(b, &object->Bitmap[offset], object->PixelBytes); 1219a57b7d2SSøren Schmidt break; 1229a57b7d2SSøren Schmidt case VIDBUF8X: 1239a57b7d2SSøren Schmidt outb(0x3c4, 0x02); 1249a57b7d2SSøren Schmidt outb(0x3c5, 0x01 << (x&0x3)); 125933d455fSNicolas Souchu object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = ((byte)color); 1269a57b7d2SSøren Schmidt break; 1275acf51eaSKazutaka YOKOTA case VIDBUF4S: 1285acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 1295acf51eaSKazutaka YOKOTA goto set_planar; 1309a57b7d2SSøren Schmidt case VIDBUF4: 1315acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 1325acf51eaSKazutaka YOKOTA set_planar: 1335acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 134933d455fSNicolas Souchu outb(0x3ce, 0x00); outb(0x3cf, (byte)color & 0x0f); /* set/reset */ 1355acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x0f); /* set/reset enable */ 1365acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8)); /* bit mask */ 137933d455fSNicolas Souchu object->Bitmap[offset] |= (byte)color; 1389a57b7d2SSøren Schmidt } 1399a57b7d2SSøren Schmidt } 1409a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 1419a57b7d2SSøren Schmidt } 1429a57b7d2SSøren Schmidt } 1439a57b7d2SSøren Schmidt 144933d455fSNicolas Souchu u_long 1459a57b7d2SSøren Schmidt VGLGetXY(VGLBitmap *object, int x, int y) 1469a57b7d2SSøren Schmidt { 1475acf51eaSKazutaka YOKOTA int offset; 148933d455fSNicolas Souchu byte b[4]; 1495acf51eaSKazutaka YOKOTA #if 0 1505acf51eaSKazutaka YOKOTA int i; 151933d455fSNicolas Souchu u_long color; 1525acf51eaSKazutaka YOKOTA byte mask; 1535acf51eaSKazutaka YOKOTA #endif 1545acf51eaSKazutaka YOKOTA 1559a57b7d2SSøren Schmidt VGLCheckSwitch(); 1565acf51eaSKazutaka YOKOTA if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize) 1575acf51eaSKazutaka YOKOTA return 0; 1589a57b7d2SSøren Schmidt switch (object->Type) { 1599a57b7d2SSøren Schmidt case MEMBUF: 1609a57b7d2SSøren Schmidt case VIDBUF8: 1615acf51eaSKazutaka YOKOTA return object->Bitmap[((y*object->VXsize)+x)]; 1625acf51eaSKazutaka YOKOTA case VIDBUF8S: 1635acf51eaSKazutaka YOKOTA return object->Bitmap[VGLSetSegment(y*object->VXsize+x)]; 164933d455fSNicolas Souchu case VIDBUF16: 165933d455fSNicolas Souchu case VIDBUF24: 166933d455fSNicolas Souchu case VIDBUF32: 167933d455fSNicolas Souchu bcopy(&object->Bitmap[(y*object->VXsize+x) * object->PixelBytes], 168933d455fSNicolas Souchu b, object->PixelBytes); 169933d455fSNicolas Souchu return (mem2color(b, object->PixelBytes)); 170933d455fSNicolas Souchu case VIDBUF16S: 171933d455fSNicolas Souchu case VIDBUF24S: 172933d455fSNicolas Souchu case VIDBUF32S: 173933d455fSNicolas Souchu offset = VGLSetSegment((y*object->VXsize+x) * object->PixelBytes); 174933d455fSNicolas Souchu bcopy(&object->Bitmap[offset], b, object->PixelBytes); 175933d455fSNicolas Souchu 176933d455fSNicolas Souchu return (mem2color(b, object->PixelBytes)); 1779a57b7d2SSøren Schmidt case VIDBUF8X: 1789a57b7d2SSøren Schmidt outb(0x3ce, 0x04); outb(0x3cf, x & 0x3); 1795acf51eaSKazutaka YOKOTA return object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)]; 1805acf51eaSKazutaka YOKOTA case VIDBUF4S: 1815acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 1825acf51eaSKazutaka YOKOTA goto get_planar; 1839a57b7d2SSøren Schmidt case VIDBUF4: 1845acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 1855acf51eaSKazutaka YOKOTA get_planar: 1865acf51eaSKazutaka YOKOTA #if 1 1875acf51eaSKazutaka YOKOTA return (object->Bitmap[offset]&(0x80>>(x%8))) ? 1 : 0; /* XXX */ 1885acf51eaSKazutaka YOKOTA #else 1895acf51eaSKazutaka YOKOTA color = 0; 1905acf51eaSKazutaka YOKOTA mask = 0x80 >> (x%8); 1915acf51eaSKazutaka YOKOTA for (i = 0; i < VGLModeInfo.vi_planes; i++) { 1925acf51eaSKazutaka YOKOTA outb(0x3ce, 0x04); outb(0x3cf, i); 1935acf51eaSKazutaka YOKOTA color |= (object->Bitmap[offset] & mask) ? (1 << i) : 0; 1945acf51eaSKazutaka YOKOTA } 1955acf51eaSKazutaka YOKOTA return color; 1965acf51eaSKazutaka YOKOTA #endif 1979a57b7d2SSøren Schmidt } 198933d455fSNicolas Souchu return 0; /* XXX black? */ 1999a57b7d2SSøren Schmidt } 2009a57b7d2SSøren Schmidt 2014c995944SPedro F. Giffuni /* 2024c995944SPedro F. Giffuni * Symmetric Double Step Line Algorithm by Brian Wyvill from 2034c995944SPedro F. Giffuni * "Graphics Gems", Academic Press, 1990. 2044c995944SPedro F. Giffuni */ 2054c995944SPedro F. Giffuni 2064c995944SPedro F. Giffuni #define SL_SWAP(a,b) {a^=b; b^=a; a^=b;} 2074c995944SPedro F. Giffuni #define SL_ABSOLUTE(i,j,k) ( (i-j)*(k = ( (i-j)<0 ? -1 : 1))) 2084c995944SPedro F. Giffuni 2094c995944SPedro F. Giffuni void 2104c995944SPedro F. Giffuni plot(VGLBitmap * object, int x, int y, int flag, byte color) 2114c995944SPedro F. Giffuni { 2124c995944SPedro F. Giffuni /* non-zero flag indicates the pixels need swapping back. */ 2134c995944SPedro F. Giffuni if (flag) 2144c995944SPedro F. Giffuni VGLSetXY(object, y, x, color); 2154c995944SPedro F. Giffuni else 2164c995944SPedro F. Giffuni VGLSetXY(object, x, y, color); 2174c995944SPedro F. Giffuni } 2184c995944SPedro F. Giffuni 2194c995944SPedro F. Giffuni 2209a57b7d2SSøren Schmidt void 221933d455fSNicolas Souchu VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 2229a57b7d2SSøren Schmidt { 2234c995944SPedro F. Giffuni int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left; 2244c995944SPedro F. Giffuni int sign_x, sign_y, step, reverse, i; 2259a57b7d2SSøren Schmidt 2264c995944SPedro F. Giffuni dx = SL_ABSOLUTE(x2, x1, sign_x); 2274c995944SPedro F. Giffuni dy = SL_ABSOLUTE(y2, y1, sign_y); 2284c995944SPedro F. Giffuni /* decide increment sign by the slope sign */ 2294c995944SPedro F. Giffuni if (sign_x == sign_y) 2304c995944SPedro F. Giffuni step = 1; 2314c995944SPedro F. Giffuni else 2324c995944SPedro F. Giffuni step = -1; 2339a57b7d2SSøren Schmidt 2344c995944SPedro F. Giffuni if (dy > dx) { /* chooses axis of greatest movement (make dx) */ 2354c995944SPedro F. Giffuni SL_SWAP(x1, y1); 2364c995944SPedro F. Giffuni SL_SWAP(x2, y2); 2374c995944SPedro F. Giffuni SL_SWAP(dx, dy); 2384c995944SPedro F. Giffuni reverse = 1; 2394c995944SPedro F. Giffuni } else 2404c995944SPedro F. Giffuni reverse = 0; 2414c995944SPedro F. Giffuni /* note error check for dx==0 should be included here */ 2424c995944SPedro F. Giffuni if (x1 > x2) { /* start from the smaller coordinate */ 2434c995944SPedro F. Giffuni x = x2; 2444c995944SPedro F. Giffuni y = y2; 245*83057bafSPedro F. Giffuni /* x1 = x1; 246*83057bafSPedro F. Giffuni y1 = y1; */ 2474c995944SPedro F. Giffuni } else { 2484c995944SPedro F. Giffuni x = x1; 2494c995944SPedro F. Giffuni y = y1; 2504c995944SPedro F. Giffuni x1 = x2; 2514c995944SPedro F. Giffuni y1 = y2; 2529a57b7d2SSøren Schmidt } 2534c995944SPedro F. Giffuni 2544c995944SPedro F. Giffuni 2554c995944SPedro F. Giffuni /* Note dx=n implies 0 - n or (dx+1) pixels to be set */ 2564c995944SPedro F. Giffuni /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */ 2574c995944SPedro F. Giffuni /* In fact (dx-1)/4 as 2 pixels are already plotted */ 2584c995944SPedro F. Giffuni xend = (dx - 1) / 4; 2594c995944SPedro F. Giffuni pixels_left = (dx - 1) % 4; /* number of pixels left over at the 2604c995944SPedro F. Giffuni * end */ 2614c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2624c995944SPedro F. Giffuni if (pixels_left < 0) 2634c995944SPedro F. Giffuni return; /* plot only one pixel for zero length 2644c995944SPedro F. Giffuni * vectors */ 2654c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); /* plot first two points */ 2664c995944SPedro F. Giffuni incr2 = 4 * dy - 2 * dx; 2674c995944SPedro F. Giffuni if (incr2 < 0) { /* slope less than 1/2 */ 2684c995944SPedro F. Giffuni c = 2 * dy; 2694c995944SPedro F. Giffuni incr1 = 2 * c; 2704c995944SPedro F. Giffuni D = incr1 - dx; 2714c995944SPedro F. Giffuni 2724c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { /* plotting loop */ 2734c995944SPedro F. Giffuni ++x; 2744c995944SPedro F. Giffuni --x1; 2754c995944SPedro F. Giffuni if (D < 0) { 2764c995944SPedro F. Giffuni /* pattern 1 forwards */ 2774c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2784c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2794c995944SPedro F. Giffuni /* pattern 1 backwards */ 2804c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2814c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2824c995944SPedro F. Giffuni D += incr1; 2834c995944SPedro F. Giffuni } else { 2844c995944SPedro F. Giffuni if (D < c) { 2854c995944SPedro F. Giffuni /* pattern 2 forwards */ 2864c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2874c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 2884c995944SPedro F. Giffuni color); 2894c995944SPedro F. Giffuni /* pattern 2 backwards */ 2904c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2914c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 2924c995944SPedro F. Giffuni color); 2934c995944SPedro F. Giffuni } else { 2944c995944SPedro F. Giffuni /* pattern 3 forwards */ 2954c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 2964c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2974c995944SPedro F. Giffuni /* pattern 3 backwards */ 2984c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, 2994c995944SPedro F. Giffuni color); 3004c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3014c995944SPedro F. Giffuni } 3024c995944SPedro F. Giffuni D += incr2; 3034c995944SPedro F. Giffuni } 3044c995944SPedro F. Giffuni } /* end for */ 3054c995944SPedro F. Giffuni 3064c995944SPedro F. Giffuni /* plot last pattern */ 3074c995944SPedro F. Giffuni if (pixels_left) { 3084c995944SPedro F. Giffuni if (D < 0) { 3094c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 1 */ 3104c995944SPedro F. Giffuni if (pixels_left > 1) 3114c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3124c995944SPedro F. Giffuni if (pixels_left > 2) 3134c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3144c995944SPedro F. Giffuni } else { 3154c995944SPedro F. Giffuni if (D < c) { 3164c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 3174c995944SPedro F. Giffuni if (pixels_left > 1) 3184c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3194c995944SPedro F. Giffuni if (pixels_left > 2) 3204c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3214c995944SPedro F. Giffuni } else { 3224c995944SPedro F. Giffuni /* pattern 3 */ 3234c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3244c995944SPedro F. Giffuni if (pixels_left > 1) 3254c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3264c995944SPedro F. Giffuni if (pixels_left > 2) 3274c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3289a57b7d2SSøren Schmidt } 3299a57b7d2SSøren Schmidt } 3304c995944SPedro F. Giffuni } /* end if pixels_left */ 3319a57b7d2SSøren Schmidt } 3324c995944SPedro F. Giffuni /* end slope < 1/2 */ 3334c995944SPedro F. Giffuni else { /* slope greater than 1/2 */ 3344c995944SPedro F. Giffuni c = 2 * (dy - dx); 3354c995944SPedro F. Giffuni incr1 = 2 * c; 3364c995944SPedro F. Giffuni D = incr1 + dx; 3374c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { 3384c995944SPedro F. Giffuni ++x; 3394c995944SPedro F. Giffuni --x1; 3404c995944SPedro F. Giffuni if (D > 0) { 3414c995944SPedro F. Giffuni /* pattern 4 forwards */ 3424c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3434c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3444c995944SPedro F. Giffuni /* pattern 4 backwards */ 3454c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3464c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3474c995944SPedro F. Giffuni D += incr1; 3484c995944SPedro F. Giffuni } else { 3494c995944SPedro F. Giffuni if (D < c) { 3504c995944SPedro F. Giffuni /* pattern 2 forwards */ 3514c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3524c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3534c995944SPedro F. Giffuni color); 3544c995944SPedro F. Giffuni 3554c995944SPedro F. Giffuni /* pattern 2 backwards */ 3564c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 3574c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3584c995944SPedro F. Giffuni color); 3594c995944SPedro F. Giffuni } else { 3604c995944SPedro F. Giffuni /* pattern 3 forwards */ 3614c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3624c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3634c995944SPedro F. Giffuni /* pattern 3 backwards */ 3644c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3654c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3664c995944SPedro F. Giffuni } 3674c995944SPedro F. Giffuni D += incr2; 3684c995944SPedro F. Giffuni } 3694c995944SPedro F. Giffuni } /* end for */ 3704c995944SPedro F. Giffuni /* plot last pattern */ 3714c995944SPedro F. Giffuni if (pixels_left) { 3724c995944SPedro F. Giffuni if (D > 0) { 3734c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); /* pattern 4 */ 3744c995944SPedro F. Giffuni if (pixels_left > 1) 3754c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3764c995944SPedro F. Giffuni color); 3774c995944SPedro F. Giffuni if (pixels_left > 2) 3784c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3794c995944SPedro F. Giffuni color); 3804c995944SPedro F. Giffuni } else { 3814c995944SPedro F. Giffuni if (D < c) { 3824c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 3834c995944SPedro F. Giffuni if (pixels_left > 1) 3844c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3854c995944SPedro F. Giffuni if (pixels_left > 2) 3864c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3874c995944SPedro F. Giffuni } else { 3884c995944SPedro F. Giffuni /* pattern 3 */ 3894c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3904c995944SPedro F. Giffuni if (pixels_left > 1) 3914c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3924c995944SPedro F. Giffuni if (pixels_left > 2) { 3934c995944SPedro F. Giffuni if (D > c) /* step 3 */ 3944c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3954c995944SPedro F. Giffuni else /* step 2 */ 3964c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3974c995944SPedro F. Giffuni } 3984c995944SPedro F. Giffuni } 3994c995944SPedro F. Giffuni } 4009a57b7d2SSøren Schmidt } 4019a57b7d2SSøren Schmidt } 4029a57b7d2SSøren Schmidt } 4039a57b7d2SSøren Schmidt 4049a57b7d2SSøren Schmidt void 405933d455fSNicolas Souchu VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 4069a57b7d2SSøren Schmidt { 4079a57b7d2SSøren Schmidt VGLLine(object, x1, y1, x2, y1, color); 4089a57b7d2SSøren Schmidt VGLLine(object, x2, y1, x2, y2, color); 4099a57b7d2SSøren Schmidt VGLLine(object, x2, y2, x1, y2, color); 4109a57b7d2SSøren Schmidt VGLLine(object, x1, y2, x1, y1, color); 4119a57b7d2SSøren Schmidt } 4129a57b7d2SSøren Schmidt 4139a57b7d2SSøren Schmidt void 414933d455fSNicolas Souchu VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 4159a57b7d2SSøren Schmidt { 4169a57b7d2SSøren Schmidt int y; 4179a57b7d2SSøren Schmidt 4189a57b7d2SSøren Schmidt for (y=y1; y<=y2; y++) VGLLine(object, x1, y, x2, y, color); 4199a57b7d2SSøren Schmidt } 4209a57b7d2SSøren Schmidt 421e7032b4cSDimitry Andric static inline void 422e7032b4cSDimitry Andric set4pixels(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 4239a57b7d2SSøren Schmidt { 4249a57b7d2SSøren Schmidt if (x!=0) { 4259a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc+y, color); 4269a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc+y, color); 4279a57b7d2SSøren Schmidt if (y!=0) { 4289a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc-y, color); 4299a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc-y, color); 4309a57b7d2SSøren Schmidt } 4319a57b7d2SSøren Schmidt } 4329a57b7d2SSøren Schmidt else { 4339a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc+y, color); 4349a57b7d2SSøren Schmidt if (y!=0) 4359a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc-y, color); 4369a57b7d2SSøren Schmidt } 4379a57b7d2SSøren Schmidt } 4389a57b7d2SSøren Schmidt 4399a57b7d2SSøren Schmidt void 440933d455fSNicolas Souchu VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 4419a57b7d2SSøren Schmidt { 4429a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 4439a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 4449a57b7d2SSøren Schmidt 4459a57b7d2SSøren Schmidt while (dx<dy) { 4469a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4479a57b7d2SSøren Schmidt if (d>0) { 4489a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4499a57b7d2SSøren Schmidt } 4509a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4519a57b7d2SSøren Schmidt } 4529a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4539a57b7d2SSøren Schmidt while (y>=0) { 4549a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4559a57b7d2SSøren Schmidt if (d<0) { 4569a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4579a57b7d2SSøren Schmidt } 4589a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4599a57b7d2SSøren Schmidt } 4609a57b7d2SSøren Schmidt } 4619a57b7d2SSøren Schmidt 462e7032b4cSDimitry Andric static inline void 463e7032b4cSDimitry Andric set2lines(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 VGLLine(object, xc+x, yc+y, xc-x, yc+y, color); 4679a57b7d2SSøren Schmidt if (y!=0) 4689a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc-y, xc-x, yc-y, color); 4699a57b7d2SSøren Schmidt } 4709a57b7d2SSøren Schmidt else { 4719a57b7d2SSøren Schmidt VGLLine(object, xc, yc+y, xc, yc-y, color); 4729a57b7d2SSøren Schmidt } 4739a57b7d2SSøren Schmidt } 4749a57b7d2SSøren Schmidt 4759a57b7d2SSøren Schmidt void 476933d455fSNicolas Souchu VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 4779a57b7d2SSøren Schmidt { 4789a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 4799a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 4809a57b7d2SSøren Schmidt 4819a57b7d2SSøren Schmidt while (dx<dy) { 4829a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 4839a57b7d2SSøren Schmidt if (d>0) { 4849a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4859a57b7d2SSøren Schmidt } 4869a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4879a57b7d2SSøren Schmidt } 4889a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4899a57b7d2SSøren Schmidt while (y>=0) { 4909a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 4919a57b7d2SSøren Schmidt if (d<0) { 4929a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4939a57b7d2SSøren Schmidt } 4949a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4959a57b7d2SSøren Schmidt } 4969a57b7d2SSøren Schmidt } 4979a57b7d2SSøren Schmidt 4989a57b7d2SSøren Schmidt void 499933d455fSNicolas Souchu VGLClear(VGLBitmap *object, u_long color) 5009a57b7d2SSøren Schmidt { 5015acf51eaSKazutaka YOKOTA int offset; 5025acf51eaSKazutaka YOKOTA int len; 503933d455fSNicolas Souchu int i, total = 0; 504933d455fSNicolas Souchu byte b[4]; 5055acf51eaSKazutaka YOKOTA 5069a57b7d2SSøren Schmidt VGLCheckSwitch(); 507933d455fSNicolas Souchu VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color); /* XXX */ 5089a57b7d2SSøren Schmidt switch (object->Type) { 5099a57b7d2SSøren Schmidt case MEMBUF: 5109a57b7d2SSøren Schmidt case VIDBUF8: 511933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, object->VXsize*object->VYsize); 5129a57b7d2SSøren Schmidt break; 5135acf51eaSKazutaka YOKOTA 5145acf51eaSKazutaka YOKOTA case VIDBUF8S: 5155acf51eaSKazutaka YOKOTA for (offset = 0; offset < object->VXsize*object->VYsize; ) { 5165acf51eaSKazutaka YOKOTA VGLSetSegment(offset); 5175acf51eaSKazutaka YOKOTA len = min(object->VXsize*object->VYsize - offset, 5185acf51eaSKazutaka YOKOTA VGLAdpInfo.va_window_size); 519933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, len); 520933d455fSNicolas Souchu offset += len; 521933d455fSNicolas Souchu } 522933d455fSNicolas Souchu break; 523933d455fSNicolas Souchu case VIDBUF16: 524933d455fSNicolas Souchu case VIDBUF24: 525933d455fSNicolas Souchu case VIDBUF32: 526933d455fSNicolas Souchu color2mem(color, b, object->PixelBytes); 527933d455fSNicolas Souchu total = object->VXsize*object->VYsize*object->PixelBytes; 528933d455fSNicolas Souchu for (i = 0; i < total; i += object->PixelBytes) 529933d455fSNicolas Souchu bcopy(b, object->Bitmap + i, object->PixelBytes); 530933d455fSNicolas Souchu break; 531933d455fSNicolas Souchu 532933d455fSNicolas Souchu case VIDBUF16S: 533933d455fSNicolas Souchu case VIDBUF24S: 534933d455fSNicolas Souchu case VIDBUF32S: 535933d455fSNicolas Souchu color2mem(color, b, object->PixelBytes); 536933d455fSNicolas Souchu total = object->VXsize*object->VYsize*object->PixelBytes; 537933d455fSNicolas Souchu for (offset = 0; offset < total; ) { 538933d455fSNicolas Souchu VGLSetSegment(offset); 539933d455fSNicolas Souchu len = min(total - offset, VGLAdpInfo.va_window_size); 540933d455fSNicolas Souchu for (i = 0; i < len; i += object->PixelBytes) 541933d455fSNicolas Souchu bcopy(b, object->Bitmap + offset + i, object->PixelBytes); 5425acf51eaSKazutaka YOKOTA offset += len; 5435acf51eaSKazutaka YOKOTA } 5445acf51eaSKazutaka YOKOTA break; 5455acf51eaSKazutaka YOKOTA 5469a57b7d2SSøren Schmidt case VIDBUF8X: 5479a57b7d2SSøren Schmidt /* XXX works only for Xsize % 4 = 0 */ 5485acf51eaSKazutaka YOKOTA outb(0x3c6, 0xff); 5499a57b7d2SSøren Schmidt outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 550933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, VGLAdpInfo.va_line_width*object->VYsize); 5519a57b7d2SSøren Schmidt break; 5529a57b7d2SSøren Schmidt 5539a57b7d2SSøren Schmidt case VIDBUF4: 5545acf51eaSKazutaka YOKOTA case VIDBUF4S: 5559a57b7d2SSøren Schmidt /* XXX works only for Xsize % 8 = 0 */ 5565acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 5575acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */ 5585acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 5595acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 5605acf51eaSKazutaka YOKOTA for (offset = 0; offset < VGLAdpInfo.va_line_width*object->VYsize; ) { 5615acf51eaSKazutaka YOKOTA VGLSetSegment(offset); 5625acf51eaSKazutaka YOKOTA len = min(object->VXsize*object->VYsize - offset, 5635acf51eaSKazutaka YOKOTA VGLAdpInfo.va_window_size); 564933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, len); 5655acf51eaSKazutaka YOKOTA offset += len; 5665acf51eaSKazutaka YOKOTA } 5675acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x00); 5689a57b7d2SSøren Schmidt break; 5699a57b7d2SSøren Schmidt } 5709a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 5719a57b7d2SSøren Schmidt } 5729a57b7d2SSøren Schmidt 5739a57b7d2SSøren Schmidt void 5749a57b7d2SSøren Schmidt VGLRestorePalette() 5759a57b7d2SSøren Schmidt { 5769a57b7d2SSøren Schmidt int i; 5779a57b7d2SSøren Schmidt 5789a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5799a57b7d2SSøren Schmidt inb(0x3DA); 5809a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 5819a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5829a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 5839a57b7d2SSøren Schmidt inb(0x84); 5849a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 5859a57b7d2SSøren Schmidt inb(0x84); 5869a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 5879a57b7d2SSøren Schmidt inb(0x84); 5889a57b7d2SSøren Schmidt } 5899a57b7d2SSøren Schmidt inb(0x3DA); 5909a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 5919a57b7d2SSøren Schmidt } 5929a57b7d2SSøren Schmidt 5939a57b7d2SSøren Schmidt void 5949a57b7d2SSøren Schmidt VGLSavePalette() 5959a57b7d2SSøren Schmidt { 5969a57b7d2SSøren Schmidt int i; 5979a57b7d2SSøren Schmidt 5989a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5999a57b7d2SSøren Schmidt inb(0x3DA); 6009a57b7d2SSøren Schmidt outb(0x3C7, 0x00); 6019a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6029a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = inb(0x3C9); 6039a57b7d2SSøren Schmidt inb(0x84); 6049a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = inb(0x3C9); 6059a57b7d2SSøren Schmidt inb(0x84); 6069a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = inb(0x3C9); 6079a57b7d2SSøren Schmidt inb(0x84); 6089a57b7d2SSøren Schmidt } 6099a57b7d2SSøren Schmidt inb(0x3DA); 6109a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6119a57b7d2SSøren Schmidt } 6129a57b7d2SSøren Schmidt 6139a57b7d2SSøren Schmidt void 6149a57b7d2SSøren Schmidt VGLSetPalette(byte *red, byte *green, byte *blue) 6159a57b7d2SSøren Schmidt { 6169a57b7d2SSøren Schmidt int i; 6179a57b7d2SSøren Schmidt 6189a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6199a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = red[i]; 6209a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = green[i]; 6219a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = blue[i]; 6229a57b7d2SSøren Schmidt } 6239a57b7d2SSøren Schmidt VGLCheckSwitch(); 6249a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6259a57b7d2SSøren Schmidt inb(0x3DA); 6269a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 6279a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6289a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 6299a57b7d2SSøren Schmidt inb(0x84); 6309a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 6319a57b7d2SSøren Schmidt inb(0x84); 6329a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 6339a57b7d2SSøren Schmidt inb(0x84); 6349a57b7d2SSøren Schmidt } 6359a57b7d2SSøren Schmidt inb(0x3DA); 6369a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6379a57b7d2SSøren Schmidt } 6389a57b7d2SSøren Schmidt 6399a57b7d2SSøren Schmidt void 6409a57b7d2SSøren Schmidt VGLSetPaletteIndex(byte color, byte red, byte green, byte blue) 6419a57b7d2SSøren Schmidt { 6429a57b7d2SSøren Schmidt VGLSavePaletteRed[color] = red; 6439a57b7d2SSøren Schmidt VGLSavePaletteGreen[color] = green; 6449a57b7d2SSøren Schmidt VGLSavePaletteBlue[color] = blue; 6459a57b7d2SSøren Schmidt VGLCheckSwitch(); 6469a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6479a57b7d2SSøren Schmidt inb(0x3DA); 6489a57b7d2SSøren Schmidt outb(0x3C8, color); 6499a57b7d2SSøren Schmidt outb(0x3C9, red); outb(0x3C9, green); outb(0x3C9, blue); 6509a57b7d2SSøren Schmidt inb(0x3DA); 6519a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6529a57b7d2SSøren Schmidt } 6539a57b7d2SSøren Schmidt 6549a57b7d2SSøren Schmidt void 6559a57b7d2SSøren Schmidt VGLSetBorder(byte color) 6569a57b7d2SSøren Schmidt { 6579a57b7d2SSøren Schmidt VGLCheckSwitch(); 6589a57b7d2SSøren Schmidt inb(0x3DA); 6599a57b7d2SSøren Schmidt outb(0x3C0,0x11); outb(0x3C0, color); 6609a57b7d2SSøren Schmidt inb(0x3DA); 6619a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6629a57b7d2SSøren Schmidt } 6639a57b7d2SSøren Schmidt 6649a57b7d2SSøren Schmidt void 6659a57b7d2SSøren Schmidt VGLBlankDisplay(int blank) 6669a57b7d2SSøren Schmidt { 6679a57b7d2SSøren Schmidt byte val; 6689a57b7d2SSøren Schmidt 6699a57b7d2SSøren Schmidt VGLCheckSwitch(); 6709a57b7d2SSøren Schmidt outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01); 6719a57b7d2SSøren Schmidt outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF))); 6729a57b7d2SSøren Schmidt } 673