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> 36*5cf92d7aSBruce Evans #include <sys/endian.h> 379a57b7d2SSøren Schmidt #include "vgl.h" 389a57b7d2SSøren Schmidt 399a57b7d2SSøren Schmidt static byte VGLSavePaletteRed[256]; 409a57b7d2SSøren Schmidt static byte VGLSavePaletteGreen[256]; 419a57b7d2SSøren Schmidt static byte VGLSavePaletteBlue[256]; 429a57b7d2SSøren Schmidt 439a57b7d2SSøren Schmidt #define ABS(a) (((a)<0) ? -(a) : (a)) 449a57b7d2SSøren Schmidt #define SGN(a) (((a)<0) ? -1 : 1) 455acf51eaSKazutaka YOKOTA #define min(x, y) (((x) < (y)) ? (x) : (y)) 465acf51eaSKazutaka YOKOTA #define max(x, y) (((x) > (y)) ? (x) : (y)) 479a57b7d2SSøren Schmidt 489a57b7d2SSøren Schmidt void 49933d455fSNicolas Souchu VGLSetXY(VGLBitmap *object, int x, int y, u_long color) 509a57b7d2SSøren Schmidt { 515acf51eaSKazutaka YOKOTA int offset; 525acf51eaSKazutaka YOKOTA 539a57b7d2SSøren Schmidt VGLCheckSwitch(); 545acf51eaSKazutaka YOKOTA if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) { 55014ddcbcSBruce Evans if (object->Type == MEMBUF || 56014ddcbcSBruce Evans !VGLMouseFreeze(x, y, 1, 1, 0x80000000 | color)) { 57*5cf92d7aSBruce Evans offset = (y * object->VXsize + x) * object->PixelBytes; 589a57b7d2SSøren Schmidt switch (object->Type) { 595acf51eaSKazutaka YOKOTA case VIDBUF8S: 60933d455fSNicolas Souchu case VIDBUF16S: 61933d455fSNicolas Souchu case VIDBUF24S: 62933d455fSNicolas Souchu case VIDBUF32S: 63*5cf92d7aSBruce Evans offset = VGLSetSegment(offset); 64*5cf92d7aSBruce Evans /* FALLTHROUGH */ 65*5cf92d7aSBruce Evans case MEMBUF: 66*5cf92d7aSBruce Evans case VIDBUF8: 67*5cf92d7aSBruce Evans case VIDBUF16: 68*5cf92d7aSBruce Evans case VIDBUF24: 69*5cf92d7aSBruce Evans case VIDBUF32: 70*5cf92d7aSBruce Evans color = htole32(color); 71*5cf92d7aSBruce Evans switch (object->PixelBytes) { 72*5cf92d7aSBruce Evans case 1: 73*5cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 1); 74*5cf92d7aSBruce Evans break; 75*5cf92d7aSBruce Evans case 2: 76*5cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 2); 77*5cf92d7aSBruce Evans break; 78*5cf92d7aSBruce Evans case 3: 79*5cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 3); 80*5cf92d7aSBruce Evans break; 81*5cf92d7aSBruce Evans case 4: 82*5cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 4); 83*5cf92d7aSBruce Evans break; 84*5cf92d7aSBruce Evans } 859a57b7d2SSøren Schmidt break; 869a57b7d2SSøren Schmidt case VIDBUF8X: 879a57b7d2SSøren Schmidt outb(0x3c4, 0x02); 889a57b7d2SSøren Schmidt outb(0x3c5, 0x01 << (x&0x3)); 89933d455fSNicolas Souchu object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = ((byte)color); 909a57b7d2SSøren Schmidt break; 915acf51eaSKazutaka YOKOTA case VIDBUF4S: 925acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 935acf51eaSKazutaka YOKOTA goto set_planar; 949a57b7d2SSøren Schmidt case VIDBUF4: 955acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 965acf51eaSKazutaka YOKOTA set_planar: 975acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 98933d455fSNicolas Souchu outb(0x3ce, 0x00); outb(0x3cf, (byte)color & 0x0f); /* set/reset */ 995acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x0f); /* set/reset enable */ 1005acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8)); /* bit mask */ 101933d455fSNicolas Souchu object->Bitmap[offset] |= (byte)color; 1029a57b7d2SSøren Schmidt } 1039a57b7d2SSøren Schmidt } 104014ddcbcSBruce Evans if (object->Type != MEMBUF) 1059a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 1069a57b7d2SSøren Schmidt } 1079a57b7d2SSøren Schmidt } 1089a57b7d2SSøren Schmidt 109014ddcbcSBruce Evans static u_long 110014ddcbcSBruce Evans __VGLGetXY(VGLBitmap *object, int x, int y) 1119a57b7d2SSøren Schmidt { 1125acf51eaSKazutaka YOKOTA int offset; 1135acf51eaSKazutaka YOKOTA int i; 114933d455fSNicolas Souchu u_long color; 1155acf51eaSKazutaka YOKOTA byte mask; 1165acf51eaSKazutaka YOKOTA 117*5cf92d7aSBruce Evans offset = (y * object->VXsize + x) * object->PixelBytes; 1189a57b7d2SSøren Schmidt switch (object->Type) { 1195acf51eaSKazutaka YOKOTA case VIDBUF8S: 120933d455fSNicolas Souchu case VIDBUF16S: 121933d455fSNicolas Souchu case VIDBUF24S: 122933d455fSNicolas Souchu case VIDBUF32S: 123*5cf92d7aSBruce Evans offset = VGLSetSegment(offset); 124*5cf92d7aSBruce Evans /* FALLTHROUGH */ 125*5cf92d7aSBruce Evans case MEMBUF: 126*5cf92d7aSBruce Evans case VIDBUF8: 127*5cf92d7aSBruce Evans case VIDBUF16: 128*5cf92d7aSBruce Evans case VIDBUF24: 129*5cf92d7aSBruce Evans case VIDBUF32: 130*5cf92d7aSBruce Evans switch (object->PixelBytes) { 131*5cf92d7aSBruce Evans case 1: 132*5cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 1); 133*5cf92d7aSBruce Evans return le32toh(color) & 0xff; 134*5cf92d7aSBruce Evans case 2: 135*5cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 2); 136*5cf92d7aSBruce Evans return le32toh(color) & 0xffff; 137*5cf92d7aSBruce Evans case 3: 138*5cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 3); 139*5cf92d7aSBruce Evans return le32toh(color) & 0xffffff; 140*5cf92d7aSBruce Evans case 4: 141*5cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 4); 142*5cf92d7aSBruce Evans return le32toh(color); 143*5cf92d7aSBruce Evans } 144*5cf92d7aSBruce Evans break; 1459a57b7d2SSøren Schmidt case VIDBUF8X: 1469a57b7d2SSøren Schmidt outb(0x3ce, 0x04); outb(0x3cf, x & 0x3); 1475acf51eaSKazutaka YOKOTA return object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)]; 1485acf51eaSKazutaka YOKOTA case VIDBUF4S: 1495acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 1505acf51eaSKazutaka YOKOTA goto get_planar; 1519a57b7d2SSøren Schmidt case VIDBUF4: 1525acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 1535acf51eaSKazutaka YOKOTA get_planar: 1545acf51eaSKazutaka YOKOTA color = 0; 1555acf51eaSKazutaka YOKOTA mask = 0x80 >> (x%8); 1565acf51eaSKazutaka YOKOTA for (i = 0; i < VGLModeInfo.vi_planes; i++) { 1575acf51eaSKazutaka YOKOTA outb(0x3ce, 0x04); outb(0x3cf, i); 1581382e2a9SBruce Evans color |= (((volatile VGLBitmap *)object)->Bitmap[offset] & mask) ? 1591382e2a9SBruce Evans (1 << i) : 0; 1605acf51eaSKazutaka YOKOTA } 1615acf51eaSKazutaka YOKOTA return color; 1629a57b7d2SSøren Schmidt } 163933d455fSNicolas Souchu return 0; /* XXX black? */ 1649a57b7d2SSøren Schmidt } 1659a57b7d2SSøren Schmidt 166014ddcbcSBruce Evans u_long 167014ddcbcSBruce Evans VGLGetXY(VGLBitmap *object, int x, int y) 168014ddcbcSBruce Evans { 169014ddcbcSBruce Evans u_long color; 170014ddcbcSBruce Evans 171014ddcbcSBruce Evans VGLCheckSwitch(); 172014ddcbcSBruce Evans if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize) 173014ddcbcSBruce Evans return 0; 174014ddcbcSBruce Evans if (object->Type != MEMBUF) { 175014ddcbcSBruce Evans color = VGLMouseFreeze(x, y, 1, 1, 0x40000000); 176014ddcbcSBruce Evans if (color & 0x40000000) { 177014ddcbcSBruce Evans VGLMouseUnFreeze(); 178014ddcbcSBruce Evans return color & 0xffffff; 179014ddcbcSBruce Evans } 180014ddcbcSBruce Evans } 181014ddcbcSBruce Evans color = __VGLGetXY(object, x, y); 182014ddcbcSBruce Evans if (object->Type != MEMBUF) 183014ddcbcSBruce Evans VGLMouseUnFreeze(); 184014ddcbcSBruce Evans return color; 185014ddcbcSBruce Evans } 186014ddcbcSBruce Evans 1874c995944SPedro F. Giffuni /* 1884c995944SPedro F. Giffuni * Symmetric Double Step Line Algorithm by Brian Wyvill from 1894c995944SPedro F. Giffuni * "Graphics Gems", Academic Press, 1990. 1904c995944SPedro F. Giffuni */ 1914c995944SPedro F. Giffuni 1924c995944SPedro F. Giffuni #define SL_SWAP(a,b) {a^=b; b^=a; a^=b;} 1934c995944SPedro F. Giffuni #define SL_ABSOLUTE(i,j,k) ( (i-j)*(k = ( (i-j)<0 ? -1 : 1))) 1944c995944SPedro F. Giffuni 1954c995944SPedro F. Giffuni void 1965ee94e99SBruce Evans plot(VGLBitmap * object, int x, int y, int flag, u_long color) 1974c995944SPedro F. Giffuni { 1984c995944SPedro F. Giffuni /* non-zero flag indicates the pixels need swapping back. */ 1994c995944SPedro F. Giffuni if (flag) 2004c995944SPedro F. Giffuni VGLSetXY(object, y, x, color); 2014c995944SPedro F. Giffuni else 2024c995944SPedro F. Giffuni VGLSetXY(object, x, y, color); 2034c995944SPedro F. Giffuni } 2044c995944SPedro F. Giffuni 2054c995944SPedro F. Giffuni 2069a57b7d2SSøren Schmidt void 207933d455fSNicolas Souchu VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 2089a57b7d2SSøren Schmidt { 2094c995944SPedro F. Giffuni int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left; 2104c995944SPedro F. Giffuni int sign_x, sign_y, step, reverse, i; 2119a57b7d2SSøren Schmidt 2124c995944SPedro F. Giffuni dx = SL_ABSOLUTE(x2, x1, sign_x); 2134c995944SPedro F. Giffuni dy = SL_ABSOLUTE(y2, y1, sign_y); 2144c995944SPedro F. Giffuni /* decide increment sign by the slope sign */ 2154c995944SPedro F. Giffuni if (sign_x == sign_y) 2164c995944SPedro F. Giffuni step = 1; 2174c995944SPedro F. Giffuni else 2184c995944SPedro F. Giffuni step = -1; 2199a57b7d2SSøren Schmidt 2204c995944SPedro F. Giffuni if (dy > dx) { /* chooses axis of greatest movement (make dx) */ 2214c995944SPedro F. Giffuni SL_SWAP(x1, y1); 2224c995944SPedro F. Giffuni SL_SWAP(x2, y2); 2234c995944SPedro F. Giffuni SL_SWAP(dx, dy); 2244c995944SPedro F. Giffuni reverse = 1; 2254c995944SPedro F. Giffuni } else 2264c995944SPedro F. Giffuni reverse = 0; 2274c995944SPedro F. Giffuni /* note error check for dx==0 should be included here */ 2284c995944SPedro F. Giffuni if (x1 > x2) { /* start from the smaller coordinate */ 2294c995944SPedro F. Giffuni x = x2; 2304c995944SPedro F. Giffuni y = y2; 23183057bafSPedro F. Giffuni /* x1 = x1; 23283057bafSPedro F. Giffuni y1 = y1; */ 2334c995944SPedro F. Giffuni } else { 2344c995944SPedro F. Giffuni x = x1; 2354c995944SPedro F. Giffuni y = y1; 2364c995944SPedro F. Giffuni x1 = x2; 2374c995944SPedro F. Giffuni y1 = y2; 2389a57b7d2SSøren Schmidt } 2394c995944SPedro F. Giffuni 2404c995944SPedro F. Giffuni 2414c995944SPedro F. Giffuni /* Note dx=n implies 0 - n or (dx+1) pixels to be set */ 2424c995944SPedro F. Giffuni /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */ 2434c995944SPedro F. Giffuni /* In fact (dx-1)/4 as 2 pixels are already plotted */ 2444c995944SPedro F. Giffuni xend = (dx - 1) / 4; 2454c995944SPedro F. Giffuni pixels_left = (dx - 1) % 4; /* number of pixels left over at the 2464c995944SPedro F. Giffuni * end */ 2474c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2484c995944SPedro F. Giffuni if (pixels_left < 0) 2494c995944SPedro F. Giffuni return; /* plot only one pixel for zero length 2504c995944SPedro F. Giffuni * vectors */ 2514c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); /* plot first two points */ 2524c995944SPedro F. Giffuni incr2 = 4 * dy - 2 * dx; 2534c995944SPedro F. Giffuni if (incr2 < 0) { /* slope less than 1/2 */ 2544c995944SPedro F. Giffuni c = 2 * dy; 2554c995944SPedro F. Giffuni incr1 = 2 * c; 2564c995944SPedro F. Giffuni D = incr1 - dx; 2574c995944SPedro F. Giffuni 2584c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { /* plotting loop */ 2594c995944SPedro F. Giffuni ++x; 2604c995944SPedro F. Giffuni --x1; 2614c995944SPedro F. Giffuni if (D < 0) { 2624c995944SPedro F. Giffuni /* pattern 1 forwards */ 2634c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2644c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2654c995944SPedro F. Giffuni /* pattern 1 backwards */ 2664c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2674c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2684c995944SPedro F. Giffuni D += incr1; 2694c995944SPedro F. Giffuni } else { 2704c995944SPedro F. Giffuni if (D < c) { 2714c995944SPedro F. Giffuni /* pattern 2 forwards */ 2724c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2734c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 2744c995944SPedro F. Giffuni color); 2754c995944SPedro F. Giffuni /* pattern 2 backwards */ 2764c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2774c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 2784c995944SPedro F. Giffuni color); 2794c995944SPedro F. Giffuni } else { 2804c995944SPedro F. Giffuni /* pattern 3 forwards */ 2814c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 2824c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2834c995944SPedro F. Giffuni /* pattern 3 backwards */ 2844c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, 2854c995944SPedro F. Giffuni color); 2864c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2874c995944SPedro F. Giffuni } 2884c995944SPedro F. Giffuni D += incr2; 2894c995944SPedro F. Giffuni } 2904c995944SPedro F. Giffuni } /* end for */ 2914c995944SPedro F. Giffuni 2924c995944SPedro F. Giffuni /* plot last pattern */ 2934c995944SPedro F. Giffuni if (pixels_left) { 2944c995944SPedro F. Giffuni if (D < 0) { 2954c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 1 */ 2964c995944SPedro F. Giffuni if (pixels_left > 1) 2974c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2984c995944SPedro F. Giffuni if (pixels_left > 2) 2994c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3004c995944SPedro F. Giffuni } else { 3014c995944SPedro F. Giffuni if (D < c) { 3024c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 3034c995944SPedro F. Giffuni if (pixels_left > 1) 3044c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3054c995944SPedro F. Giffuni if (pixels_left > 2) 3064c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3074c995944SPedro F. Giffuni } else { 3084c995944SPedro F. Giffuni /* pattern 3 */ 3094c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 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 -= step, reverse, color); 3149a57b7d2SSøren Schmidt } 3159a57b7d2SSøren Schmidt } 3164c995944SPedro F. Giffuni } /* end if pixels_left */ 3179a57b7d2SSøren Schmidt } 3184c995944SPedro F. Giffuni /* end slope < 1/2 */ 3194c995944SPedro F. Giffuni else { /* slope greater than 1/2 */ 3204c995944SPedro F. Giffuni c = 2 * (dy - dx); 3214c995944SPedro F. Giffuni incr1 = 2 * c; 3224c995944SPedro F. Giffuni D = incr1 + dx; 3234c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { 3244c995944SPedro F. Giffuni ++x; 3254c995944SPedro F. Giffuni --x1; 3264c995944SPedro F. Giffuni if (D > 0) { 3274c995944SPedro F. Giffuni /* pattern 4 forwards */ 3284c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3294c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3304c995944SPedro F. Giffuni /* pattern 4 backwards */ 3314c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3324c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3334c995944SPedro F. Giffuni D += incr1; 3344c995944SPedro F. Giffuni } else { 3354c995944SPedro F. Giffuni if (D < c) { 3364c995944SPedro F. Giffuni /* pattern 2 forwards */ 3374c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3384c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3394c995944SPedro F. Giffuni color); 3404c995944SPedro F. Giffuni 3414c995944SPedro F. Giffuni /* pattern 2 backwards */ 3424c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 3434c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3444c995944SPedro F. Giffuni color); 3454c995944SPedro F. Giffuni } else { 3464c995944SPedro F. Giffuni /* pattern 3 forwards */ 3474c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3484c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3494c995944SPedro F. Giffuni /* pattern 3 backwards */ 3504c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3514c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3524c995944SPedro F. Giffuni } 3534c995944SPedro F. Giffuni D += incr2; 3544c995944SPedro F. Giffuni } 3554c995944SPedro F. Giffuni } /* end for */ 3564c995944SPedro F. Giffuni /* plot last pattern */ 3574c995944SPedro F. Giffuni if (pixels_left) { 3584c995944SPedro F. Giffuni if (D > 0) { 3594c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); /* pattern 4 */ 3604c995944SPedro F. Giffuni if (pixels_left > 1) 3614c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3624c995944SPedro F. Giffuni color); 3634c995944SPedro F. Giffuni if (pixels_left > 2) 3644c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3654c995944SPedro F. Giffuni color); 3664c995944SPedro F. Giffuni } else { 3674c995944SPedro F. Giffuni if (D < c) { 3684c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 3694c995944SPedro F. Giffuni if (pixels_left > 1) 3704c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3714c995944SPedro F. Giffuni if (pixels_left > 2) 3724c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3734c995944SPedro F. Giffuni } else { 3744c995944SPedro F. Giffuni /* pattern 3 */ 3754c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3764c995944SPedro F. Giffuni if (pixels_left > 1) 3774c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3784c995944SPedro F. Giffuni if (pixels_left > 2) { 3794c995944SPedro F. Giffuni if (D > c) /* step 3 */ 3804c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3814c995944SPedro F. Giffuni else /* step 2 */ 3824c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3834c995944SPedro F. Giffuni } 3844c995944SPedro F. Giffuni } 3854c995944SPedro F. Giffuni } 3869a57b7d2SSøren Schmidt } 3879a57b7d2SSøren Schmidt } 3889a57b7d2SSøren Schmidt } 3899a57b7d2SSøren Schmidt 3909a57b7d2SSøren Schmidt void 391933d455fSNicolas Souchu VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 3929a57b7d2SSøren Schmidt { 3939a57b7d2SSøren Schmidt VGLLine(object, x1, y1, x2, y1, color); 3949a57b7d2SSøren Schmidt VGLLine(object, x2, y1, x2, y2, color); 3959a57b7d2SSøren Schmidt VGLLine(object, x2, y2, x1, y2, color); 3969a57b7d2SSøren Schmidt VGLLine(object, x1, y2, x1, y1, color); 3979a57b7d2SSøren Schmidt } 3989a57b7d2SSøren Schmidt 3999a57b7d2SSøren Schmidt void 400933d455fSNicolas Souchu VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 4019a57b7d2SSøren Schmidt { 4029a57b7d2SSøren Schmidt int y; 4039a57b7d2SSøren Schmidt 4049a57b7d2SSøren Schmidt for (y=y1; y<=y2; y++) VGLLine(object, x1, y, x2, y, color); 4059a57b7d2SSøren Schmidt } 4069a57b7d2SSøren Schmidt 407e7032b4cSDimitry Andric static inline void 408e7032b4cSDimitry Andric set4pixels(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 4099a57b7d2SSøren Schmidt { 4109a57b7d2SSøren Schmidt if (x!=0) { 4119a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc+y, color); 4129a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc+y, color); 4139a57b7d2SSøren Schmidt if (y!=0) { 4149a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc-y, color); 4159a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc-y, color); 4169a57b7d2SSøren Schmidt } 4179a57b7d2SSøren Schmidt } 4189a57b7d2SSøren Schmidt else { 4199a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc+y, color); 4209a57b7d2SSøren Schmidt if (y!=0) 4219a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc-y, color); 4229a57b7d2SSøren Schmidt } 4239a57b7d2SSøren Schmidt } 4249a57b7d2SSøren Schmidt 4259a57b7d2SSøren Schmidt void 426933d455fSNicolas Souchu VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 4279a57b7d2SSøren Schmidt { 4289a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 4299a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 4309a57b7d2SSøren Schmidt 4319a57b7d2SSøren Schmidt while (dx<dy) { 4329a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4339a57b7d2SSøren Schmidt if (d>0) { 4349a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4359a57b7d2SSøren Schmidt } 4369a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4379a57b7d2SSøren Schmidt } 4389a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4399a57b7d2SSøren Schmidt while (y>=0) { 4409a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4419a57b7d2SSøren Schmidt if (d<0) { 4429a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4439a57b7d2SSøren Schmidt } 4449a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4459a57b7d2SSøren Schmidt } 4469a57b7d2SSøren Schmidt } 4479a57b7d2SSøren Schmidt 448e7032b4cSDimitry Andric static inline void 449e7032b4cSDimitry Andric set2lines(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 4509a57b7d2SSøren Schmidt { 4519a57b7d2SSøren Schmidt if (x!=0) { 4529a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc+y, xc-x, yc+y, color); 4539a57b7d2SSøren Schmidt if (y!=0) 4549a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc-y, xc-x, yc-y, color); 4559a57b7d2SSøren Schmidt } 4569a57b7d2SSøren Schmidt else { 4579a57b7d2SSøren Schmidt VGLLine(object, xc, yc+y, xc, yc-y, color); 4589a57b7d2SSøren Schmidt } 4599a57b7d2SSøren Schmidt } 4609a57b7d2SSøren Schmidt 4619a57b7d2SSøren Schmidt void 462933d455fSNicolas Souchu VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 4639a57b7d2SSøren Schmidt { 4649a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 4659a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 4669a57b7d2SSøren Schmidt 4679a57b7d2SSøren Schmidt while (dx<dy) { 4689a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 4699a57b7d2SSøren Schmidt if (d>0) { 4709a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4719a57b7d2SSøren Schmidt } 4729a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4739a57b7d2SSøren Schmidt } 4749a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4759a57b7d2SSøren Schmidt while (y>=0) { 4769a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 4779a57b7d2SSøren Schmidt if (d<0) { 4789a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4799a57b7d2SSøren Schmidt } 4809a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4819a57b7d2SSøren Schmidt } 4829a57b7d2SSøren Schmidt } 4839a57b7d2SSøren Schmidt 4849a57b7d2SSøren Schmidt void 485933d455fSNicolas Souchu VGLClear(VGLBitmap *object, u_long color) 4869a57b7d2SSøren Schmidt { 487*5cf92d7aSBruce Evans VGLBitmap src; 4885acf51eaSKazutaka YOKOTA int offset; 4895acf51eaSKazutaka YOKOTA int len; 490*5cf92d7aSBruce Evans int i; 4915acf51eaSKazutaka YOKOTA 4929a57b7d2SSøren Schmidt VGLCheckSwitch(); 493014ddcbcSBruce Evans if (object->Type != MEMBUF) 494014ddcbcSBruce Evans VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color); 4959a57b7d2SSøren Schmidt switch (object->Type) { 4969a57b7d2SSøren Schmidt case MEMBUF: 4979a57b7d2SSøren Schmidt case VIDBUF8: 4985acf51eaSKazutaka YOKOTA case VIDBUF8S: 499933d455fSNicolas Souchu case VIDBUF16: 500933d455fSNicolas Souchu case VIDBUF16S: 501*5cf92d7aSBruce Evans case VIDBUF24: 502933d455fSNicolas Souchu case VIDBUF24S: 503*5cf92d7aSBruce Evans case VIDBUF32: 504933d455fSNicolas Souchu case VIDBUF32S: 505*5cf92d7aSBruce Evans src.Type = MEMBUF; 506*5cf92d7aSBruce Evans src.Xsize = object->Xsize; 507*5cf92d7aSBruce Evans src.VXsize = object->VXsize; 508*5cf92d7aSBruce Evans src.Ysize = 1; 509*5cf92d7aSBruce Evans src.VYsize = 1; 510*5cf92d7aSBruce Evans src.Xorigin = 0; 511*5cf92d7aSBruce Evans src.Yorigin = 0; 512*5cf92d7aSBruce Evans src.Bitmap = alloca(object->VXsize * object->PixelBytes); 513*5cf92d7aSBruce Evans src.PixelBytes = object->PixelBytes; 514*5cf92d7aSBruce Evans color = htole32(color); 515*5cf92d7aSBruce Evans for (i = 0; i < object->VXsize; i++) 516*5cf92d7aSBruce Evans bcopy(&color, src.Bitmap + i * object->PixelBytes, object->PixelBytes); 517*5cf92d7aSBruce Evans for (i = 0; i < object->VYsize; i++) 518*5cf92d7aSBruce Evans __VGLBitmapCopy(&src, 0, 0, object, 0, i, object->VYsize, 1); 5195acf51eaSKazutaka YOKOTA break; 5205acf51eaSKazutaka YOKOTA 5219a57b7d2SSøren Schmidt case VIDBUF8X: 5229a57b7d2SSøren Schmidt /* XXX works only for Xsize % 4 = 0 */ 5235acf51eaSKazutaka YOKOTA outb(0x3c6, 0xff); 5249a57b7d2SSøren Schmidt outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 525933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, VGLAdpInfo.va_line_width*object->VYsize); 5269a57b7d2SSøren Schmidt break; 5279a57b7d2SSøren Schmidt 5289a57b7d2SSøren Schmidt case VIDBUF4: 5295acf51eaSKazutaka YOKOTA case VIDBUF4S: 5309a57b7d2SSøren Schmidt /* XXX works only for Xsize % 8 = 0 */ 5315acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 5325acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */ 5335acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 5345acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 5355acf51eaSKazutaka YOKOTA for (offset = 0; offset < VGLAdpInfo.va_line_width*object->VYsize; ) { 5365acf51eaSKazutaka YOKOTA VGLSetSegment(offset); 5375acf51eaSKazutaka YOKOTA len = min(object->VXsize*object->VYsize - offset, 5385acf51eaSKazutaka YOKOTA VGLAdpInfo.va_window_size); 539933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, len); 5405acf51eaSKazutaka YOKOTA offset += len; 5415acf51eaSKazutaka YOKOTA } 5425acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x00); 5439a57b7d2SSøren Schmidt break; 5449a57b7d2SSøren Schmidt } 545014ddcbcSBruce Evans if (object->Type != MEMBUF) 5469a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 5479a57b7d2SSøren Schmidt } 5489a57b7d2SSøren Schmidt 5499a57b7d2SSøren Schmidt void 5509a57b7d2SSøren Schmidt VGLRestorePalette() 5519a57b7d2SSøren Schmidt { 5529a57b7d2SSøren Schmidt int i; 5539a57b7d2SSøren Schmidt 5549a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5559a57b7d2SSøren Schmidt inb(0x3DA); 5569a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 5579a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5589a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 5599a57b7d2SSøren Schmidt inb(0x84); 5609a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 5619a57b7d2SSøren Schmidt inb(0x84); 5629a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 5639a57b7d2SSøren Schmidt inb(0x84); 5649a57b7d2SSøren Schmidt } 5659a57b7d2SSøren Schmidt inb(0x3DA); 5669a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 5679a57b7d2SSøren Schmidt } 5689a57b7d2SSøren Schmidt 5699a57b7d2SSøren Schmidt void 5709a57b7d2SSøren Schmidt VGLSavePalette() 5719a57b7d2SSøren Schmidt { 5729a57b7d2SSøren Schmidt int i; 5739a57b7d2SSøren Schmidt 5749a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5759a57b7d2SSøren Schmidt inb(0x3DA); 5769a57b7d2SSøren Schmidt outb(0x3C7, 0x00); 5779a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5789a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = inb(0x3C9); 5799a57b7d2SSøren Schmidt inb(0x84); 5809a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = inb(0x3C9); 5819a57b7d2SSøren Schmidt inb(0x84); 5829a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = inb(0x3C9); 5839a57b7d2SSøren Schmidt inb(0x84); 5849a57b7d2SSøren Schmidt } 5859a57b7d2SSøren Schmidt inb(0x3DA); 5869a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 5879a57b7d2SSøren Schmidt } 5889a57b7d2SSøren Schmidt 5899a57b7d2SSøren Schmidt void 5909a57b7d2SSøren Schmidt VGLSetPalette(byte *red, byte *green, byte *blue) 5919a57b7d2SSøren Schmidt { 5929a57b7d2SSøren Schmidt int i; 5939a57b7d2SSøren Schmidt 5949a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5959a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = red[i]; 5969a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = green[i]; 5979a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = blue[i]; 5989a57b7d2SSøren Schmidt } 5999a57b7d2SSøren Schmidt VGLCheckSwitch(); 6009a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6019a57b7d2SSøren Schmidt inb(0x3DA); 6029a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 6039a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6049a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 6059a57b7d2SSøren Schmidt inb(0x84); 6069a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 6079a57b7d2SSøren Schmidt inb(0x84); 6089a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 6099a57b7d2SSøren Schmidt inb(0x84); 6109a57b7d2SSøren Schmidt } 6119a57b7d2SSøren Schmidt inb(0x3DA); 6129a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6139a57b7d2SSøren Schmidt } 6149a57b7d2SSøren Schmidt 6159a57b7d2SSøren Schmidt void 6169a57b7d2SSøren Schmidt VGLSetPaletteIndex(byte color, byte red, byte green, byte blue) 6179a57b7d2SSøren Schmidt { 6189a57b7d2SSøren Schmidt VGLSavePaletteRed[color] = red; 6199a57b7d2SSøren Schmidt VGLSavePaletteGreen[color] = green; 6209a57b7d2SSøren Schmidt VGLSavePaletteBlue[color] = blue; 6219a57b7d2SSøren Schmidt VGLCheckSwitch(); 6229a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6239a57b7d2SSøren Schmidt inb(0x3DA); 6249a57b7d2SSøren Schmidt outb(0x3C8, color); 6259a57b7d2SSøren Schmidt outb(0x3C9, red); outb(0x3C9, green); outb(0x3C9, blue); 6269a57b7d2SSøren Schmidt inb(0x3DA); 6279a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6289a57b7d2SSøren Schmidt } 6299a57b7d2SSøren Schmidt 6309a57b7d2SSøren Schmidt void 6319a57b7d2SSøren Schmidt VGLSetBorder(byte color) 6329a57b7d2SSøren Schmidt { 6339a57b7d2SSøren Schmidt VGLCheckSwitch(); 6349a57b7d2SSøren Schmidt inb(0x3DA); 6359a57b7d2SSøren Schmidt outb(0x3C0,0x11); outb(0x3C0, color); 6369a57b7d2SSøren Schmidt inb(0x3DA); 6379a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6389a57b7d2SSøren Schmidt } 6399a57b7d2SSøren Schmidt 6409a57b7d2SSøren Schmidt void 6419a57b7d2SSøren Schmidt VGLBlankDisplay(int blank) 6429a57b7d2SSøren Schmidt { 6439a57b7d2SSøren Schmidt byte val; 6449a57b7d2SSøren Schmidt 6459a57b7d2SSøren Schmidt VGLCheckSwitch(); 6469a57b7d2SSøren Schmidt outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01); 6479a57b7d2SSøren Schmidt outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF))); 6489a57b7d2SSøren Schmidt } 649