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> 3680b4b86eSBruce Evans #include <sys/kbio.h> 375cf92d7aSBruce Evans #include <sys/endian.h> 389a57b7d2SSøren Schmidt #include "vgl.h" 399a57b7d2SSøren Schmidt 40e848f3d1SBruce Evans static int VGLBlank; 41e848f3d1SBruce Evans static byte VGLBorderColor; 429a57b7d2SSøren Schmidt static byte VGLSavePaletteRed[256]; 439a57b7d2SSøren Schmidt static byte VGLSavePaletteGreen[256]; 449a57b7d2SSøren Schmidt static byte VGLSavePaletteBlue[256]; 459a57b7d2SSøren Schmidt 469a57b7d2SSøren Schmidt #define ABS(a) (((a)<0) ? -(a) : (a)) 479a57b7d2SSøren Schmidt #define SGN(a) (((a)<0) ? -1 : 1) 485acf51eaSKazutaka YOKOTA #define min(x, y) (((x) < (y)) ? (x) : (y)) 495acf51eaSKazutaka YOKOTA #define max(x, y) (((x) > (y)) ? (x) : (y)) 509a57b7d2SSøren Schmidt 519a57b7d2SSøren Schmidt void 52933d455fSNicolas Souchu VGLSetXY(VGLBitmap *object, int x, int y, u_long color) 539a57b7d2SSøren Schmidt { 545acf51eaSKazutaka YOKOTA int offset; 555acf51eaSKazutaka YOKOTA 569a57b7d2SSøren Schmidt VGLCheckSwitch(); 575acf51eaSKazutaka YOKOTA if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) { 58*1fa51420SBruce Evans if (object == VGLDisplay) 59*1fa51420SBruce Evans VGLSetXY(&VGLVDisplay, x, y, color); 60014ddcbcSBruce Evans if (object->Type == MEMBUF || 61014ddcbcSBruce Evans !VGLMouseFreeze(x, y, 1, 1, 0x80000000 | color)) { 625cf92d7aSBruce Evans offset = (y * object->VXsize + x) * object->PixelBytes; 639a57b7d2SSøren Schmidt switch (object->Type) { 645acf51eaSKazutaka YOKOTA case VIDBUF8S: 65933d455fSNicolas Souchu case VIDBUF16S: 66933d455fSNicolas Souchu case VIDBUF24S: 67933d455fSNicolas Souchu case VIDBUF32S: 685cf92d7aSBruce Evans offset = VGLSetSegment(offset); 695cf92d7aSBruce Evans /* FALLTHROUGH */ 705cf92d7aSBruce Evans case MEMBUF: 715cf92d7aSBruce Evans case VIDBUF8: 725cf92d7aSBruce Evans case VIDBUF16: 735cf92d7aSBruce Evans case VIDBUF24: 745cf92d7aSBruce Evans case VIDBUF32: 755cf92d7aSBruce Evans color = htole32(color); 765cf92d7aSBruce Evans switch (object->PixelBytes) { 775cf92d7aSBruce Evans case 1: 785cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 1); 795cf92d7aSBruce Evans break; 805cf92d7aSBruce Evans case 2: 815cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 2); 825cf92d7aSBruce Evans break; 835cf92d7aSBruce Evans case 3: 845cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 3); 855cf92d7aSBruce Evans break; 865cf92d7aSBruce Evans case 4: 875cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 4); 885cf92d7aSBruce Evans break; 895cf92d7aSBruce Evans } 909a57b7d2SSøren Schmidt break; 919a57b7d2SSøren Schmidt case VIDBUF8X: 929a57b7d2SSøren Schmidt outb(0x3c4, 0x02); 939a57b7d2SSøren Schmidt outb(0x3c5, 0x01 << (x&0x3)); 94933d455fSNicolas Souchu object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = ((byte)color); 959a57b7d2SSøren Schmidt break; 965acf51eaSKazutaka YOKOTA case VIDBUF4S: 975acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 985acf51eaSKazutaka YOKOTA goto set_planar; 999a57b7d2SSøren Schmidt case VIDBUF4: 1005acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 1015acf51eaSKazutaka YOKOTA set_planar: 1025acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 103933d455fSNicolas Souchu outb(0x3ce, 0x00); outb(0x3cf, (byte)color & 0x0f); /* set/reset */ 1045acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x0f); /* set/reset enable */ 1055acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8)); /* bit mask */ 106933d455fSNicolas Souchu object->Bitmap[offset] |= (byte)color; 1079a57b7d2SSøren Schmidt } 1089a57b7d2SSøren Schmidt } 109014ddcbcSBruce Evans if (object->Type != MEMBUF) 1109a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 1119a57b7d2SSøren Schmidt } 1129a57b7d2SSøren Schmidt } 1139a57b7d2SSøren Schmidt 114014ddcbcSBruce Evans static u_long 115014ddcbcSBruce Evans __VGLGetXY(VGLBitmap *object, int x, int y) 1169a57b7d2SSøren Schmidt { 1175acf51eaSKazutaka YOKOTA int offset; 118933d455fSNicolas Souchu u_long color; 1195acf51eaSKazutaka YOKOTA 1205cf92d7aSBruce Evans offset = (y * object->VXsize + x) * object->PixelBytes; 1215cf92d7aSBruce Evans switch (object->PixelBytes) { 1225cf92d7aSBruce Evans case 1: 1235cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 1); 1245cf92d7aSBruce Evans return le32toh(color) & 0xff; 1255cf92d7aSBruce Evans case 2: 1265cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 2); 1275cf92d7aSBruce Evans return le32toh(color) & 0xffff; 1285cf92d7aSBruce Evans case 3: 1295cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 3); 1305cf92d7aSBruce Evans return le32toh(color) & 0xffffff; 1315cf92d7aSBruce Evans case 4: 1325cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 4); 1335cf92d7aSBruce Evans return le32toh(color); 1345cf92d7aSBruce Evans } 135*1fa51420SBruce Evans return 0; /* invalid */ 1369a57b7d2SSøren Schmidt } 1379a57b7d2SSøren Schmidt 138014ddcbcSBruce Evans u_long 139014ddcbcSBruce Evans VGLGetXY(VGLBitmap *object, int x, int y) 140014ddcbcSBruce Evans { 141014ddcbcSBruce Evans VGLCheckSwitch(); 142014ddcbcSBruce Evans if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize) 143014ddcbcSBruce Evans return 0; 144*1fa51420SBruce Evans if (object == VGLDisplay) 145*1fa51420SBruce Evans object = &VGLVDisplay; 146014ddcbcSBruce Evans if (object->Type != MEMBUF) 147*1fa51420SBruce Evans return 0; /* invalid */ 148*1fa51420SBruce Evans return __VGLGetXY(object, x, y); 149014ddcbcSBruce Evans } 150014ddcbcSBruce Evans 1514c995944SPedro F. Giffuni /* 1524c995944SPedro F. Giffuni * Symmetric Double Step Line Algorithm by Brian Wyvill from 1534c995944SPedro F. Giffuni * "Graphics Gems", Academic Press, 1990. 1544c995944SPedro F. Giffuni */ 1554c995944SPedro F. Giffuni 1564c995944SPedro F. Giffuni #define SL_SWAP(a,b) {a^=b; b^=a; a^=b;} 1574c995944SPedro F. Giffuni #define SL_ABSOLUTE(i,j,k) ( (i-j)*(k = ( (i-j)<0 ? -1 : 1))) 1584c995944SPedro F. Giffuni 1594c995944SPedro F. Giffuni void 1605ee94e99SBruce Evans plot(VGLBitmap * object, int x, int y, int flag, u_long color) 1614c995944SPedro F. Giffuni { 1624c995944SPedro F. Giffuni /* non-zero flag indicates the pixels need swapping back. */ 1634c995944SPedro F. Giffuni if (flag) 1644c995944SPedro F. Giffuni VGLSetXY(object, y, x, color); 1654c995944SPedro F. Giffuni else 1664c995944SPedro F. Giffuni VGLSetXY(object, x, y, color); 1674c995944SPedro F. Giffuni } 1684c995944SPedro F. Giffuni 1694c995944SPedro F. Giffuni 1709a57b7d2SSøren Schmidt void 171933d455fSNicolas Souchu VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 1729a57b7d2SSøren Schmidt { 1734c995944SPedro F. Giffuni int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left; 1744c995944SPedro F. Giffuni int sign_x, sign_y, step, reverse, i; 1759a57b7d2SSøren Schmidt 1764c995944SPedro F. Giffuni dx = SL_ABSOLUTE(x2, x1, sign_x); 1774c995944SPedro F. Giffuni dy = SL_ABSOLUTE(y2, y1, sign_y); 1784c995944SPedro F. Giffuni /* decide increment sign by the slope sign */ 1794c995944SPedro F. Giffuni if (sign_x == sign_y) 1804c995944SPedro F. Giffuni step = 1; 1814c995944SPedro F. Giffuni else 1824c995944SPedro F. Giffuni step = -1; 1839a57b7d2SSøren Schmidt 1844c995944SPedro F. Giffuni if (dy > dx) { /* chooses axis of greatest movement (make dx) */ 1854c995944SPedro F. Giffuni SL_SWAP(x1, y1); 1864c995944SPedro F. Giffuni SL_SWAP(x2, y2); 1874c995944SPedro F. Giffuni SL_SWAP(dx, dy); 1884c995944SPedro F. Giffuni reverse = 1; 1894c995944SPedro F. Giffuni } else 1904c995944SPedro F. Giffuni reverse = 0; 1914c995944SPedro F. Giffuni /* note error check for dx==0 should be included here */ 1924c995944SPedro F. Giffuni if (x1 > x2) { /* start from the smaller coordinate */ 1934c995944SPedro F. Giffuni x = x2; 1944c995944SPedro F. Giffuni y = y2; 19583057bafSPedro F. Giffuni /* x1 = x1; 19683057bafSPedro F. Giffuni y1 = y1; */ 1974c995944SPedro F. Giffuni } else { 1984c995944SPedro F. Giffuni x = x1; 1994c995944SPedro F. Giffuni y = y1; 2004c995944SPedro F. Giffuni x1 = x2; 2014c995944SPedro F. Giffuni y1 = y2; 2029a57b7d2SSøren Schmidt } 2034c995944SPedro F. Giffuni 2044c995944SPedro F. Giffuni 2054c995944SPedro F. Giffuni /* Note dx=n implies 0 - n or (dx+1) pixels to be set */ 2064c995944SPedro F. Giffuni /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */ 2074c995944SPedro F. Giffuni /* In fact (dx-1)/4 as 2 pixels are already plotted */ 2084c995944SPedro F. Giffuni xend = (dx - 1) / 4; 2094c995944SPedro F. Giffuni pixels_left = (dx - 1) % 4; /* number of pixels left over at the 2104c995944SPedro F. Giffuni * end */ 2114c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2124c995944SPedro F. Giffuni if (pixels_left < 0) 2134c995944SPedro F. Giffuni return; /* plot only one pixel for zero length 2144c995944SPedro F. Giffuni * vectors */ 2154c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); /* plot first two points */ 2164c995944SPedro F. Giffuni incr2 = 4 * dy - 2 * dx; 2174c995944SPedro F. Giffuni if (incr2 < 0) { /* slope less than 1/2 */ 2184c995944SPedro F. Giffuni c = 2 * dy; 2194c995944SPedro F. Giffuni incr1 = 2 * c; 2204c995944SPedro F. Giffuni D = incr1 - dx; 2214c995944SPedro F. Giffuni 2224c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { /* plotting loop */ 2234c995944SPedro F. Giffuni ++x; 2244c995944SPedro F. Giffuni --x1; 2254c995944SPedro F. Giffuni if (D < 0) { 2264c995944SPedro F. Giffuni /* pattern 1 forwards */ 2274c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2284c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2294c995944SPedro F. Giffuni /* pattern 1 backwards */ 2304c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2314c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2324c995944SPedro F. Giffuni D += incr1; 2334c995944SPedro F. Giffuni } else { 2344c995944SPedro F. Giffuni if (D < c) { 2354c995944SPedro F. Giffuni /* pattern 2 forwards */ 2364c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2374c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 2384c995944SPedro F. Giffuni color); 2394c995944SPedro F. Giffuni /* pattern 2 backwards */ 2404c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2414c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 2424c995944SPedro F. Giffuni color); 2434c995944SPedro F. Giffuni } else { 2444c995944SPedro F. Giffuni /* pattern 3 forwards */ 2454c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 2464c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2474c995944SPedro F. Giffuni /* pattern 3 backwards */ 2484c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, 2494c995944SPedro F. Giffuni color); 2504c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2514c995944SPedro F. Giffuni } 2524c995944SPedro F. Giffuni D += incr2; 2534c995944SPedro F. Giffuni } 2544c995944SPedro F. Giffuni } /* end for */ 2554c995944SPedro F. Giffuni 2564c995944SPedro F. Giffuni /* plot last pattern */ 2574c995944SPedro F. Giffuni if (pixels_left) { 2584c995944SPedro F. Giffuni if (D < 0) { 2594c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 1 */ 2604c995944SPedro F. Giffuni if (pixels_left > 1) 2614c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2624c995944SPedro F. Giffuni if (pixels_left > 2) 2634c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2644c995944SPedro F. Giffuni } else { 2654c995944SPedro F. Giffuni if (D < c) { 2664c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 2674c995944SPedro F. Giffuni if (pixels_left > 1) 2684c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 2694c995944SPedro F. Giffuni if (pixels_left > 2) 2704c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2714c995944SPedro F. Giffuni } else { 2724c995944SPedro F. Giffuni /* pattern 3 */ 2734c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 2744c995944SPedro F. Giffuni if (pixels_left > 1) 2754c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2764c995944SPedro F. Giffuni if (pixels_left > 2) 2774c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 2789a57b7d2SSøren Schmidt } 2799a57b7d2SSøren Schmidt } 2804c995944SPedro F. Giffuni } /* end if pixels_left */ 2819a57b7d2SSøren Schmidt } 2824c995944SPedro F. Giffuni /* end slope < 1/2 */ 2834c995944SPedro F. Giffuni else { /* slope greater than 1/2 */ 2844c995944SPedro F. Giffuni c = 2 * (dy - dx); 2854c995944SPedro F. Giffuni incr1 = 2 * c; 2864c995944SPedro F. Giffuni D = incr1 + dx; 2874c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { 2884c995944SPedro F. Giffuni ++x; 2894c995944SPedro F. Giffuni --x1; 2904c995944SPedro F. Giffuni if (D > 0) { 2914c995944SPedro F. Giffuni /* pattern 4 forwards */ 2924c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 2934c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 2944c995944SPedro F. Giffuni /* pattern 4 backwards */ 2954c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 2964c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 2974c995944SPedro F. Giffuni D += incr1; 2984c995944SPedro F. Giffuni } else { 2994c995944SPedro F. Giffuni if (D < c) { 3004c995944SPedro F. Giffuni /* pattern 2 forwards */ 3014c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3024c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3034c995944SPedro F. Giffuni color); 3044c995944SPedro F. Giffuni 3054c995944SPedro F. Giffuni /* pattern 2 backwards */ 3064c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 3074c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3084c995944SPedro F. Giffuni color); 3094c995944SPedro F. Giffuni } else { 3104c995944SPedro F. Giffuni /* pattern 3 forwards */ 3114c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3124c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3134c995944SPedro F. Giffuni /* pattern 3 backwards */ 3144c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3154c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3164c995944SPedro F. Giffuni } 3174c995944SPedro F. Giffuni D += incr2; 3184c995944SPedro F. Giffuni } 3194c995944SPedro F. Giffuni } /* end for */ 3204c995944SPedro F. Giffuni /* plot last pattern */ 3214c995944SPedro F. Giffuni if (pixels_left) { 3224c995944SPedro F. Giffuni if (D > 0) { 3234c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); /* pattern 4 */ 3244c995944SPedro F. Giffuni if (pixels_left > 1) 3254c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3264c995944SPedro F. Giffuni color); 3274c995944SPedro F. Giffuni if (pixels_left > 2) 3284c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3294c995944SPedro F. Giffuni color); 3304c995944SPedro F. Giffuni } else { 3314c995944SPedro F. Giffuni if (D < c) { 3324c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 3334c995944SPedro F. Giffuni if (pixels_left > 1) 3344c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3354c995944SPedro F. Giffuni if (pixels_left > 2) 3364c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3374c995944SPedro F. Giffuni } else { 3384c995944SPedro F. Giffuni /* pattern 3 */ 3394c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3404c995944SPedro F. Giffuni if (pixels_left > 1) 3414c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3424c995944SPedro F. Giffuni if (pixels_left > 2) { 3434c995944SPedro F. Giffuni if (D > c) /* step 3 */ 3444c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3454c995944SPedro F. Giffuni else /* step 2 */ 3464c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3474c995944SPedro F. Giffuni } 3484c995944SPedro F. Giffuni } 3494c995944SPedro F. Giffuni } 3509a57b7d2SSøren Schmidt } 3519a57b7d2SSøren Schmidt } 3529a57b7d2SSøren Schmidt } 3539a57b7d2SSøren Schmidt 3549a57b7d2SSøren Schmidt void 355933d455fSNicolas Souchu VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 3569a57b7d2SSøren Schmidt { 3579a57b7d2SSøren Schmidt VGLLine(object, x1, y1, x2, y1, color); 3589a57b7d2SSøren Schmidt VGLLine(object, x2, y1, x2, y2, color); 3599a57b7d2SSøren Schmidt VGLLine(object, x2, y2, x1, y2, color); 3609a57b7d2SSøren Schmidt VGLLine(object, x1, y2, x1, y1, color); 3619a57b7d2SSøren Schmidt } 3629a57b7d2SSøren Schmidt 3639a57b7d2SSøren Schmidt void 364933d455fSNicolas Souchu VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 3659a57b7d2SSøren Schmidt { 3669a57b7d2SSøren Schmidt int y; 3679a57b7d2SSøren Schmidt 3689a57b7d2SSøren Schmidt for (y=y1; y<=y2; y++) VGLLine(object, x1, y, x2, y, color); 3699a57b7d2SSøren Schmidt } 3709a57b7d2SSøren Schmidt 371e7032b4cSDimitry Andric static inline void 372e7032b4cSDimitry Andric set4pixels(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 3739a57b7d2SSøren Schmidt { 3749a57b7d2SSøren Schmidt if (x!=0) { 3759a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc+y, color); 3769a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc+y, color); 3779a57b7d2SSøren Schmidt if (y!=0) { 3789a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc-y, color); 3799a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc-y, color); 3809a57b7d2SSøren Schmidt } 3819a57b7d2SSøren Schmidt } 3829a57b7d2SSøren Schmidt else { 3839a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc+y, color); 3849a57b7d2SSøren Schmidt if (y!=0) 3859a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc-y, color); 3869a57b7d2SSøren Schmidt } 3879a57b7d2SSøren Schmidt } 3889a57b7d2SSøren Schmidt 3899a57b7d2SSøren Schmidt void 390933d455fSNicolas Souchu VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 3919a57b7d2SSøren Schmidt { 3929a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 3939a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 3949a57b7d2SSøren Schmidt 3959a57b7d2SSøren Schmidt while (dx<dy) { 3969a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 3979a57b7d2SSøren Schmidt if (d>0) { 3989a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 3999a57b7d2SSøren Schmidt } 4009a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4019a57b7d2SSøren Schmidt } 4029a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4039a57b7d2SSøren Schmidt while (y>=0) { 4049a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4059a57b7d2SSøren Schmidt if (d<0) { 4069a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4079a57b7d2SSøren Schmidt } 4089a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4099a57b7d2SSøren Schmidt } 4109a57b7d2SSøren Schmidt } 4119a57b7d2SSøren Schmidt 412e7032b4cSDimitry Andric static inline void 413e7032b4cSDimitry Andric set2lines(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 4149a57b7d2SSøren Schmidt { 4159a57b7d2SSøren Schmidt if (x!=0) { 4169a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc+y, xc-x, yc+y, color); 4179a57b7d2SSøren Schmidt if (y!=0) 4189a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc-y, xc-x, yc-y, color); 4199a57b7d2SSøren Schmidt } 4209a57b7d2SSøren Schmidt else { 4219a57b7d2SSøren Schmidt VGLLine(object, xc, yc+y, xc, yc-y, color); 4229a57b7d2SSøren Schmidt } 4239a57b7d2SSøren Schmidt } 4249a57b7d2SSøren Schmidt 4259a57b7d2SSøren Schmidt void 426933d455fSNicolas Souchu VGLFilledEllipse(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 set2lines(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 set2lines(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 4489a57b7d2SSøren Schmidt void 449933d455fSNicolas Souchu VGLClear(VGLBitmap *object, u_long color) 4509a57b7d2SSøren Schmidt { 4515cf92d7aSBruce Evans VGLBitmap src; 4525acf51eaSKazutaka YOKOTA int offset; 4535acf51eaSKazutaka YOKOTA int len; 4545cf92d7aSBruce Evans int i; 4555acf51eaSKazutaka YOKOTA 4569a57b7d2SSøren Schmidt VGLCheckSwitch(); 457*1fa51420SBruce Evans if (object == VGLDisplay) { 458014ddcbcSBruce Evans VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color); 459*1fa51420SBruce Evans VGLClear(&VGLVDisplay, color); 460*1fa51420SBruce Evans } else if (object->Type != MEMBUF) 461*1fa51420SBruce Evans return; /* invalid */ 4629a57b7d2SSøren Schmidt switch (object->Type) { 4639a57b7d2SSøren Schmidt case MEMBUF: 4649a57b7d2SSøren Schmidt case VIDBUF8: 4655acf51eaSKazutaka YOKOTA case VIDBUF8S: 466933d455fSNicolas Souchu case VIDBUF16: 467933d455fSNicolas Souchu case VIDBUF16S: 4685cf92d7aSBruce Evans case VIDBUF24: 469933d455fSNicolas Souchu case VIDBUF24S: 4705cf92d7aSBruce Evans case VIDBUF32: 471933d455fSNicolas Souchu case VIDBUF32S: 4725cf92d7aSBruce Evans src.Type = MEMBUF; 4735cf92d7aSBruce Evans src.Xsize = object->Xsize; 4745cf92d7aSBruce Evans src.VXsize = object->VXsize; 4755cf92d7aSBruce Evans src.Ysize = 1; 4765cf92d7aSBruce Evans src.VYsize = 1; 4775cf92d7aSBruce Evans src.Xorigin = 0; 4785cf92d7aSBruce Evans src.Yorigin = 0; 4795cf92d7aSBruce Evans src.Bitmap = alloca(object->VXsize * object->PixelBytes); 4805cf92d7aSBruce Evans src.PixelBytes = object->PixelBytes; 4815cf92d7aSBruce Evans color = htole32(color); 4825cf92d7aSBruce Evans for (i = 0; i < object->VXsize; i++) 4835cf92d7aSBruce Evans bcopy(&color, src.Bitmap + i * object->PixelBytes, object->PixelBytes); 4845cf92d7aSBruce Evans for (i = 0; i < object->VYsize; i++) 4859db56319SBruce Evans __VGLBitmapCopy(&src, 0, 0, object, 0, i, object->VXsize, 1); 4865acf51eaSKazutaka YOKOTA break; 4875acf51eaSKazutaka YOKOTA 4889a57b7d2SSøren Schmidt case VIDBUF8X: 4899a57b7d2SSøren Schmidt /* XXX works only for Xsize % 4 = 0 */ 4905acf51eaSKazutaka YOKOTA outb(0x3c6, 0xff); 4919a57b7d2SSøren Schmidt outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 492933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, VGLAdpInfo.va_line_width*object->VYsize); 4939a57b7d2SSøren Schmidt break; 4949a57b7d2SSøren Schmidt 4959a57b7d2SSøren Schmidt case VIDBUF4: 4965acf51eaSKazutaka YOKOTA case VIDBUF4S: 4979a57b7d2SSøren Schmidt /* XXX works only for Xsize % 8 = 0 */ 4985acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 4995acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */ 5005acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 5015acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 5025acf51eaSKazutaka YOKOTA for (offset = 0; offset < VGLAdpInfo.va_line_width*object->VYsize; ) { 5035acf51eaSKazutaka YOKOTA VGLSetSegment(offset); 5045acf51eaSKazutaka YOKOTA len = min(object->VXsize*object->VYsize - offset, 5055acf51eaSKazutaka YOKOTA VGLAdpInfo.va_window_size); 506933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, len); 5075acf51eaSKazutaka YOKOTA offset += len; 5085acf51eaSKazutaka YOKOTA } 5095acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x00); 5109a57b7d2SSøren Schmidt break; 5119a57b7d2SSøren Schmidt } 512*1fa51420SBruce Evans if (object == VGLDisplay) 5139a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 5149a57b7d2SSøren Schmidt } 5159a57b7d2SSøren Schmidt 5169a57b7d2SSøren Schmidt void 5179a57b7d2SSøren Schmidt VGLRestorePalette() 5189a57b7d2SSøren Schmidt { 5199a57b7d2SSøren Schmidt int i; 5209a57b7d2SSøren Schmidt 52180b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 52280b4b86eSBruce Evans return; 5239a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5249a57b7d2SSøren Schmidt inb(0x3DA); 5259a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 5269a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5279a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 5289a57b7d2SSøren Schmidt inb(0x84); 5299a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 5309a57b7d2SSøren Schmidt inb(0x84); 5319a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 5329a57b7d2SSøren Schmidt inb(0x84); 5339a57b7d2SSøren Schmidt } 5349a57b7d2SSøren Schmidt inb(0x3DA); 5359a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 5369a57b7d2SSøren Schmidt } 5379a57b7d2SSøren Schmidt 5389a57b7d2SSøren Schmidt void 5399a57b7d2SSøren Schmidt VGLSavePalette() 5409a57b7d2SSøren Schmidt { 5419a57b7d2SSøren Schmidt int i; 5429a57b7d2SSøren Schmidt 54380b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 54480b4b86eSBruce Evans return; 5459a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5469a57b7d2SSøren Schmidt inb(0x3DA); 5479a57b7d2SSøren Schmidt outb(0x3C7, 0x00); 5489a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5499a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = inb(0x3C9); 5509a57b7d2SSøren Schmidt inb(0x84); 5519a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = inb(0x3C9); 5529a57b7d2SSøren Schmidt inb(0x84); 5539a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = inb(0x3C9); 5549a57b7d2SSøren Schmidt inb(0x84); 5559a57b7d2SSøren Schmidt } 5569a57b7d2SSøren Schmidt inb(0x3DA); 5579a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 5589a57b7d2SSøren Schmidt } 5599a57b7d2SSøren Schmidt 5609a57b7d2SSøren Schmidt void 5619a57b7d2SSøren Schmidt VGLSetPalette(byte *red, byte *green, byte *blue) 5629a57b7d2SSøren Schmidt { 5639a57b7d2SSøren Schmidt int i; 5649a57b7d2SSøren Schmidt 56580b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 56680b4b86eSBruce Evans return; 5679a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5689a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = red[i]; 5699a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = green[i]; 5709a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = blue[i]; 5719a57b7d2SSøren Schmidt } 5729a57b7d2SSøren Schmidt VGLCheckSwitch(); 5739a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5749a57b7d2SSøren Schmidt inb(0x3DA); 5759a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 5769a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5779a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 5789a57b7d2SSøren Schmidt inb(0x84); 5799a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 5809a57b7d2SSøren Schmidt inb(0x84); 5819a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 5829a57b7d2SSøren Schmidt inb(0x84); 5839a57b7d2SSøren Schmidt } 5849a57b7d2SSøren Schmidt inb(0x3DA); 5859a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 5869a57b7d2SSøren Schmidt } 5879a57b7d2SSøren Schmidt 5889a57b7d2SSøren Schmidt void 5899a57b7d2SSøren Schmidt VGLSetPaletteIndex(byte color, byte red, byte green, byte blue) 5909a57b7d2SSøren Schmidt { 59180b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 59280b4b86eSBruce Evans return; 5939a57b7d2SSøren Schmidt VGLSavePaletteRed[color] = red; 5949a57b7d2SSøren Schmidt VGLSavePaletteGreen[color] = green; 5959a57b7d2SSøren Schmidt VGLSavePaletteBlue[color] = blue; 5969a57b7d2SSøren Schmidt VGLCheckSwitch(); 5979a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5989a57b7d2SSøren Schmidt inb(0x3DA); 5999a57b7d2SSøren Schmidt outb(0x3C8, color); 6009a57b7d2SSøren Schmidt outb(0x3C9, red); outb(0x3C9, green); outb(0x3C9, blue); 6019a57b7d2SSøren Schmidt inb(0x3DA); 6029a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6039a57b7d2SSøren Schmidt } 6049a57b7d2SSøren Schmidt 6059a57b7d2SSøren Schmidt void 606e848f3d1SBruce Evans VGLRestoreBorder(void) 607e848f3d1SBruce Evans { 608e848f3d1SBruce Evans VGLSetBorder(VGLBorderColor); 609e848f3d1SBruce Evans } 610e848f3d1SBruce Evans 611e848f3d1SBruce Evans void 6129a57b7d2SSøren Schmidt VGLSetBorder(byte color) 6139a57b7d2SSøren Schmidt { 61480b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0)) 61580b4b86eSBruce Evans return; 6169a57b7d2SSøren Schmidt VGLCheckSwitch(); 6179a57b7d2SSøren Schmidt inb(0x3DA); 6189a57b7d2SSøren Schmidt outb(0x3C0,0x11); outb(0x3C0, color); 6199a57b7d2SSøren Schmidt inb(0x3DA); 6209a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 621e848f3d1SBruce Evans VGLBorderColor = color; 62280b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 62380b4b86eSBruce Evans ioctl(0, KDDISABIO, 0); 6249a57b7d2SSøren Schmidt } 6259a57b7d2SSøren Schmidt 6269a57b7d2SSøren Schmidt void 627e848f3d1SBruce Evans VGLRestoreBlank(void) 628e848f3d1SBruce Evans { 629e848f3d1SBruce Evans VGLBlankDisplay(VGLBlank); 630e848f3d1SBruce Evans } 631e848f3d1SBruce Evans 632e848f3d1SBruce Evans void 6339a57b7d2SSøren Schmidt VGLBlankDisplay(int blank) 6349a57b7d2SSøren Schmidt { 6359a57b7d2SSøren Schmidt byte val; 6369a57b7d2SSøren Schmidt 63780b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0)) 63880b4b86eSBruce Evans return; 6399a57b7d2SSøren Schmidt VGLCheckSwitch(); 6409a57b7d2SSøren Schmidt outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01); 6419a57b7d2SSøren Schmidt outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF))); 642e848f3d1SBruce Evans VGLBlank = blank; 64380b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 64480b4b86eSBruce Evans ioctl(0, KDDISABIO, 0); 6459a57b7d2SSøren Schmidt } 646