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 { 54*c7432537SBruce Evans int offset, undermouse; 555acf51eaSKazutaka YOKOTA 569a57b7d2SSøren Schmidt VGLCheckSwitch(); 575acf51eaSKazutaka YOKOTA if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) { 58*c7432537SBruce Evans if (object == VGLDisplay) { 59*c7432537SBruce Evans undermouse = VGLMouseFreezeXY(x, y); 601fa51420SBruce Evans VGLSetXY(&VGLVDisplay, x, y, color); 61*c7432537SBruce Evans } else if (object->Type != MEMBUF) 62*c7432537SBruce Evans return; /* invalid */ 63*c7432537SBruce Evans else 64*c7432537SBruce Evans undermouse = 0; 65*c7432537SBruce Evans if (!undermouse) { 665cf92d7aSBruce Evans offset = (y * object->VXsize + x) * object->PixelBytes; 679a57b7d2SSøren Schmidt switch (object->Type) { 685acf51eaSKazutaka YOKOTA case VIDBUF8S: 69933d455fSNicolas Souchu case VIDBUF16S: 70933d455fSNicolas Souchu case VIDBUF24S: 71933d455fSNicolas Souchu case VIDBUF32S: 725cf92d7aSBruce Evans offset = VGLSetSegment(offset); 735cf92d7aSBruce Evans /* FALLTHROUGH */ 745cf92d7aSBruce Evans case MEMBUF: 755cf92d7aSBruce Evans case VIDBUF8: 765cf92d7aSBruce Evans case VIDBUF16: 775cf92d7aSBruce Evans case VIDBUF24: 785cf92d7aSBruce Evans case VIDBUF32: 795cf92d7aSBruce Evans color = htole32(color); 805cf92d7aSBruce Evans switch (object->PixelBytes) { 815cf92d7aSBruce Evans case 1: 825cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 1); 835cf92d7aSBruce Evans break; 845cf92d7aSBruce Evans case 2: 855cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 2); 865cf92d7aSBruce Evans break; 875cf92d7aSBruce Evans case 3: 885cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 3); 895cf92d7aSBruce Evans break; 905cf92d7aSBruce Evans case 4: 915cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 4); 925cf92d7aSBruce Evans break; 935cf92d7aSBruce Evans } 949a57b7d2SSøren Schmidt break; 959a57b7d2SSøren Schmidt case VIDBUF8X: 969a57b7d2SSøren Schmidt outb(0x3c4, 0x02); 979a57b7d2SSøren Schmidt outb(0x3c5, 0x01 << (x&0x3)); 98933d455fSNicolas Souchu object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = ((byte)color); 999a57b7d2SSøren Schmidt break; 1005acf51eaSKazutaka YOKOTA case VIDBUF4S: 1015acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 1025acf51eaSKazutaka YOKOTA goto set_planar; 1039a57b7d2SSøren Schmidt case VIDBUF4: 1045acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 1055acf51eaSKazutaka YOKOTA set_planar: 1065acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 107933d455fSNicolas Souchu outb(0x3ce, 0x00); outb(0x3cf, (byte)color & 0x0f); /* set/reset */ 1085acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x0f); /* set/reset enable */ 1095acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8)); /* bit mask */ 110933d455fSNicolas Souchu object->Bitmap[offset] |= (byte)color; 1119a57b7d2SSøren Schmidt } 1129a57b7d2SSøren Schmidt } 113*c7432537SBruce Evans if (object == VGLDisplay) 1149a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 1159a57b7d2SSøren Schmidt } 1169a57b7d2SSøren Schmidt } 1179a57b7d2SSøren Schmidt 118014ddcbcSBruce Evans static u_long 119014ddcbcSBruce Evans __VGLGetXY(VGLBitmap *object, int x, int y) 1209a57b7d2SSøren Schmidt { 1215acf51eaSKazutaka YOKOTA int offset; 122933d455fSNicolas Souchu u_long color; 1235acf51eaSKazutaka YOKOTA 1245cf92d7aSBruce Evans offset = (y * object->VXsize + x) * object->PixelBytes; 1255cf92d7aSBruce Evans switch (object->PixelBytes) { 1265cf92d7aSBruce Evans case 1: 1275cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 1); 1285cf92d7aSBruce Evans return le32toh(color) & 0xff; 1295cf92d7aSBruce Evans case 2: 1305cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 2); 1315cf92d7aSBruce Evans return le32toh(color) & 0xffff; 1325cf92d7aSBruce Evans case 3: 1335cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 3); 1345cf92d7aSBruce Evans return le32toh(color) & 0xffffff; 1355cf92d7aSBruce Evans case 4: 1365cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 4); 1375cf92d7aSBruce Evans return le32toh(color); 1385cf92d7aSBruce Evans } 1391fa51420SBruce Evans return 0; /* invalid */ 1409a57b7d2SSøren Schmidt } 1419a57b7d2SSøren Schmidt 142014ddcbcSBruce Evans u_long 143014ddcbcSBruce Evans VGLGetXY(VGLBitmap *object, int x, int y) 144014ddcbcSBruce Evans { 145014ddcbcSBruce Evans VGLCheckSwitch(); 146014ddcbcSBruce Evans if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize) 147014ddcbcSBruce Evans return 0; 1481fa51420SBruce Evans if (object == VGLDisplay) 1491fa51420SBruce Evans object = &VGLVDisplay; 150*c7432537SBruce Evans else if (object->Type != MEMBUF) 1511fa51420SBruce Evans return 0; /* invalid */ 1521fa51420SBruce Evans return __VGLGetXY(object, x, y); 153014ddcbcSBruce Evans } 154014ddcbcSBruce Evans 1554c995944SPedro F. Giffuni /* 1564c995944SPedro F. Giffuni * Symmetric Double Step Line Algorithm by Brian Wyvill from 1574c995944SPedro F. Giffuni * "Graphics Gems", Academic Press, 1990. 1584c995944SPedro F. Giffuni */ 1594c995944SPedro F. Giffuni 1604c995944SPedro F. Giffuni #define SL_SWAP(a,b) {a^=b; b^=a; a^=b;} 1614c995944SPedro F. Giffuni #define SL_ABSOLUTE(i,j,k) ( (i-j)*(k = ( (i-j)<0 ? -1 : 1))) 1624c995944SPedro F. Giffuni 1634c995944SPedro F. Giffuni void 1645ee94e99SBruce Evans plot(VGLBitmap * object, int x, int y, int flag, u_long color) 1654c995944SPedro F. Giffuni { 1664c995944SPedro F. Giffuni /* non-zero flag indicates the pixels need swapping back. */ 1674c995944SPedro F. Giffuni if (flag) 1684c995944SPedro F. Giffuni VGLSetXY(object, y, x, color); 1694c995944SPedro F. Giffuni else 1704c995944SPedro F. Giffuni VGLSetXY(object, x, y, color); 1714c995944SPedro F. Giffuni } 1724c995944SPedro F. Giffuni 1734c995944SPedro F. Giffuni 1749a57b7d2SSøren Schmidt void 175933d455fSNicolas Souchu VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 1769a57b7d2SSøren Schmidt { 1774c995944SPedro F. Giffuni int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left; 1784c995944SPedro F. Giffuni int sign_x, sign_y, step, reverse, i; 1799a57b7d2SSøren Schmidt 1804c995944SPedro F. Giffuni dx = SL_ABSOLUTE(x2, x1, sign_x); 1814c995944SPedro F. Giffuni dy = SL_ABSOLUTE(y2, y1, sign_y); 1824c995944SPedro F. Giffuni /* decide increment sign by the slope sign */ 1834c995944SPedro F. Giffuni if (sign_x == sign_y) 1844c995944SPedro F. Giffuni step = 1; 1854c995944SPedro F. Giffuni else 1864c995944SPedro F. Giffuni step = -1; 1879a57b7d2SSøren Schmidt 1884c995944SPedro F. Giffuni if (dy > dx) { /* chooses axis of greatest movement (make dx) */ 1894c995944SPedro F. Giffuni SL_SWAP(x1, y1); 1904c995944SPedro F. Giffuni SL_SWAP(x2, y2); 1914c995944SPedro F. Giffuni SL_SWAP(dx, dy); 1924c995944SPedro F. Giffuni reverse = 1; 1934c995944SPedro F. Giffuni } else 1944c995944SPedro F. Giffuni reverse = 0; 1954c995944SPedro F. Giffuni /* note error check for dx==0 should be included here */ 1964c995944SPedro F. Giffuni if (x1 > x2) { /* start from the smaller coordinate */ 1974c995944SPedro F. Giffuni x = x2; 1984c995944SPedro F. Giffuni y = y2; 19983057bafSPedro F. Giffuni /* x1 = x1; 20083057bafSPedro F. Giffuni y1 = y1; */ 2014c995944SPedro F. Giffuni } else { 2024c995944SPedro F. Giffuni x = x1; 2034c995944SPedro F. Giffuni y = y1; 2044c995944SPedro F. Giffuni x1 = x2; 2054c995944SPedro F. Giffuni y1 = y2; 2069a57b7d2SSøren Schmidt } 2074c995944SPedro F. Giffuni 2084c995944SPedro F. Giffuni 2094c995944SPedro F. Giffuni /* Note dx=n implies 0 - n or (dx+1) pixels to be set */ 2104c995944SPedro F. Giffuni /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */ 2114c995944SPedro F. Giffuni /* In fact (dx-1)/4 as 2 pixels are already plotted */ 2124c995944SPedro F. Giffuni xend = (dx - 1) / 4; 2134c995944SPedro F. Giffuni pixels_left = (dx - 1) % 4; /* number of pixels left over at the 2144c995944SPedro F. Giffuni * end */ 2154c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2164c995944SPedro F. Giffuni if (pixels_left < 0) 2174c995944SPedro F. Giffuni return; /* plot only one pixel for zero length 2184c995944SPedro F. Giffuni * vectors */ 2194c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); /* plot first two points */ 2204c995944SPedro F. Giffuni incr2 = 4 * dy - 2 * dx; 2214c995944SPedro F. Giffuni if (incr2 < 0) { /* slope less than 1/2 */ 2224c995944SPedro F. Giffuni c = 2 * dy; 2234c995944SPedro F. Giffuni incr1 = 2 * c; 2244c995944SPedro F. Giffuni D = incr1 - dx; 2254c995944SPedro F. Giffuni 2264c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { /* plotting loop */ 2274c995944SPedro F. Giffuni ++x; 2284c995944SPedro F. Giffuni --x1; 2294c995944SPedro F. Giffuni if (D < 0) { 2304c995944SPedro F. Giffuni /* pattern 1 forwards */ 2314c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2324c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2334c995944SPedro F. Giffuni /* pattern 1 backwards */ 2344c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2354c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2364c995944SPedro F. Giffuni D += incr1; 2374c995944SPedro F. Giffuni } else { 2384c995944SPedro F. Giffuni if (D < c) { 2394c995944SPedro F. Giffuni /* pattern 2 forwards */ 2404c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2414c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 2424c995944SPedro F. Giffuni color); 2434c995944SPedro F. Giffuni /* pattern 2 backwards */ 2444c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2454c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 2464c995944SPedro F. Giffuni color); 2474c995944SPedro F. Giffuni } else { 2484c995944SPedro F. Giffuni /* pattern 3 forwards */ 2494c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 2504c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2514c995944SPedro F. Giffuni /* pattern 3 backwards */ 2524c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, 2534c995944SPedro F. Giffuni color); 2544c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2554c995944SPedro F. Giffuni } 2564c995944SPedro F. Giffuni D += incr2; 2574c995944SPedro F. Giffuni } 2584c995944SPedro F. Giffuni } /* end for */ 2594c995944SPedro F. Giffuni 2604c995944SPedro F. Giffuni /* plot last pattern */ 2614c995944SPedro F. Giffuni if (pixels_left) { 2624c995944SPedro F. Giffuni if (D < 0) { 2634c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 1 */ 2644c995944SPedro F. Giffuni if (pixels_left > 1) 2654c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2664c995944SPedro F. Giffuni if (pixels_left > 2) 2674c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2684c995944SPedro F. Giffuni } else { 2694c995944SPedro F. Giffuni if (D < c) { 2704c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 2714c995944SPedro F. Giffuni if (pixels_left > 1) 2724c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 2734c995944SPedro F. Giffuni if (pixels_left > 2) 2744c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2754c995944SPedro F. Giffuni } else { 2764c995944SPedro F. Giffuni /* pattern 3 */ 2774c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 2784c995944SPedro F. Giffuni if (pixels_left > 1) 2794c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2804c995944SPedro F. Giffuni if (pixels_left > 2) 2814c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 2829a57b7d2SSøren Schmidt } 2839a57b7d2SSøren Schmidt } 2844c995944SPedro F. Giffuni } /* end if pixels_left */ 2859a57b7d2SSøren Schmidt } 2864c995944SPedro F. Giffuni /* end slope < 1/2 */ 2874c995944SPedro F. Giffuni else { /* slope greater than 1/2 */ 2884c995944SPedro F. Giffuni c = 2 * (dy - dx); 2894c995944SPedro F. Giffuni incr1 = 2 * c; 2904c995944SPedro F. Giffuni D = incr1 + dx; 2914c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { 2924c995944SPedro F. Giffuni ++x; 2934c995944SPedro F. Giffuni --x1; 2944c995944SPedro F. Giffuni if (D > 0) { 2954c995944SPedro F. Giffuni /* pattern 4 forwards */ 2964c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 2974c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 2984c995944SPedro F. Giffuni /* pattern 4 backwards */ 2994c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3004c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3014c995944SPedro F. Giffuni D += incr1; 3024c995944SPedro F. Giffuni } else { 3034c995944SPedro F. Giffuni if (D < c) { 3044c995944SPedro F. Giffuni /* pattern 2 forwards */ 3054c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3064c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3074c995944SPedro F. Giffuni color); 3084c995944SPedro F. Giffuni 3094c995944SPedro F. Giffuni /* pattern 2 backwards */ 3104c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 3114c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3124c995944SPedro F. Giffuni color); 3134c995944SPedro F. Giffuni } else { 3144c995944SPedro F. Giffuni /* pattern 3 forwards */ 3154c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3164c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3174c995944SPedro F. Giffuni /* pattern 3 backwards */ 3184c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3194c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3204c995944SPedro F. Giffuni } 3214c995944SPedro F. Giffuni D += incr2; 3224c995944SPedro F. Giffuni } 3234c995944SPedro F. Giffuni } /* end for */ 3244c995944SPedro F. Giffuni /* plot last pattern */ 3254c995944SPedro F. Giffuni if (pixels_left) { 3264c995944SPedro F. Giffuni if (D > 0) { 3274c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); /* pattern 4 */ 3284c995944SPedro F. Giffuni if (pixels_left > 1) 3294c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3304c995944SPedro F. Giffuni color); 3314c995944SPedro F. Giffuni if (pixels_left > 2) 3324c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3334c995944SPedro F. Giffuni color); 3344c995944SPedro F. Giffuni } else { 3354c995944SPedro F. Giffuni if (D < c) { 3364c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 3374c995944SPedro F. Giffuni if (pixels_left > 1) 3384c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3394c995944SPedro F. Giffuni if (pixels_left > 2) 3404c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3414c995944SPedro F. Giffuni } else { 3424c995944SPedro F. Giffuni /* pattern 3 */ 3434c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3444c995944SPedro F. Giffuni if (pixels_left > 1) 3454c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3464c995944SPedro F. Giffuni if (pixels_left > 2) { 3474c995944SPedro F. Giffuni if (D > c) /* step 3 */ 3484c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3494c995944SPedro F. Giffuni else /* step 2 */ 3504c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3514c995944SPedro F. Giffuni } 3524c995944SPedro F. Giffuni } 3534c995944SPedro F. Giffuni } 3549a57b7d2SSøren Schmidt } 3559a57b7d2SSøren Schmidt } 3569a57b7d2SSøren Schmidt } 3579a57b7d2SSøren Schmidt 3589a57b7d2SSøren Schmidt void 359933d455fSNicolas Souchu VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 3609a57b7d2SSøren Schmidt { 3619a57b7d2SSøren Schmidt VGLLine(object, x1, y1, x2, y1, color); 3629a57b7d2SSøren Schmidt VGLLine(object, x2, y1, x2, y2, color); 3639a57b7d2SSøren Schmidt VGLLine(object, x2, y2, x1, y2, color); 3649a57b7d2SSøren Schmidt VGLLine(object, x1, y2, x1, y1, color); 3659a57b7d2SSøren Schmidt } 3669a57b7d2SSøren Schmidt 3679a57b7d2SSøren Schmidt void 368933d455fSNicolas Souchu VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 3699a57b7d2SSøren Schmidt { 3709a57b7d2SSøren Schmidt int y; 3719a57b7d2SSøren Schmidt 3729a57b7d2SSøren Schmidt for (y=y1; y<=y2; y++) VGLLine(object, x1, y, x2, y, color); 3739a57b7d2SSøren Schmidt } 3749a57b7d2SSøren Schmidt 375e7032b4cSDimitry Andric static inline void 376e7032b4cSDimitry Andric set4pixels(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 3779a57b7d2SSøren Schmidt { 3789a57b7d2SSøren Schmidt if (x!=0) { 3799a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc+y, color); 3809a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc+y, color); 3819a57b7d2SSøren Schmidt if (y!=0) { 3829a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc-y, color); 3839a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc-y, color); 3849a57b7d2SSøren Schmidt } 3859a57b7d2SSøren Schmidt } 3869a57b7d2SSøren Schmidt else { 3879a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc+y, color); 3889a57b7d2SSøren Schmidt if (y!=0) 3899a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc-y, color); 3909a57b7d2SSøren Schmidt } 3919a57b7d2SSøren Schmidt } 3929a57b7d2SSøren Schmidt 3939a57b7d2SSøren Schmidt void 394933d455fSNicolas Souchu VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 3959a57b7d2SSøren Schmidt { 3969a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 3979a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 3989a57b7d2SSøren Schmidt 3999a57b7d2SSøren Schmidt while (dx<dy) { 4009a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4019a57b7d2SSøren Schmidt if (d>0) { 4029a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4039a57b7d2SSøren Schmidt } 4049a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4059a57b7d2SSøren Schmidt } 4069a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4079a57b7d2SSøren Schmidt while (y>=0) { 4089a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4099a57b7d2SSøren Schmidt if (d<0) { 4109a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4119a57b7d2SSøren Schmidt } 4129a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4139a57b7d2SSøren Schmidt } 4149a57b7d2SSøren Schmidt } 4159a57b7d2SSøren Schmidt 416e7032b4cSDimitry Andric static inline void 417e7032b4cSDimitry Andric set2lines(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 4189a57b7d2SSøren Schmidt { 4199a57b7d2SSøren Schmidt if (x!=0) { 4209a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc+y, xc-x, yc+y, color); 4219a57b7d2SSøren Schmidt if (y!=0) 4229a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc-y, xc-x, yc-y, color); 4239a57b7d2SSøren Schmidt } 4249a57b7d2SSøren Schmidt else { 4259a57b7d2SSøren Schmidt VGLLine(object, xc, yc+y, xc, yc-y, color); 4269a57b7d2SSøren Schmidt } 4279a57b7d2SSøren Schmidt } 4289a57b7d2SSøren Schmidt 4299a57b7d2SSøren Schmidt void 430933d455fSNicolas Souchu VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 4319a57b7d2SSøren Schmidt { 4329a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 4339a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 4349a57b7d2SSøren Schmidt 4359a57b7d2SSøren Schmidt while (dx<dy) { 4369a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 4379a57b7d2SSøren Schmidt if (d>0) { 4389a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4399a57b7d2SSøren Schmidt } 4409a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4419a57b7d2SSøren Schmidt } 4429a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4439a57b7d2SSøren Schmidt while (y>=0) { 4449a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 4459a57b7d2SSøren Schmidt if (d<0) { 4469a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4479a57b7d2SSøren Schmidt } 4489a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4499a57b7d2SSøren Schmidt } 4509a57b7d2SSøren Schmidt } 4519a57b7d2SSøren Schmidt 4529a57b7d2SSøren Schmidt void 453933d455fSNicolas Souchu VGLClear(VGLBitmap *object, u_long color) 4549a57b7d2SSøren Schmidt { 4555cf92d7aSBruce Evans VGLBitmap src; 456*c7432537SBruce Evans int i, len, mouseoverlap, offset; 4575acf51eaSKazutaka YOKOTA 4589a57b7d2SSøren Schmidt VGLCheckSwitch(); 4591fa51420SBruce Evans if (object == VGLDisplay) { 460*c7432537SBruce Evans VGLMouseFreeze(); 461*c7432537SBruce Evans mouseoverlap = VGLMouseOverlap(0, 0, object->Xsize, object->Ysize); 462*c7432537SBruce Evans if (mouseoverlap) 463*c7432537SBruce Evans VGLMousePointerHide(); 4641fa51420SBruce Evans VGLClear(&VGLVDisplay, color); 4651fa51420SBruce Evans } else if (object->Type != MEMBUF) 4661fa51420SBruce Evans return; /* invalid */ 4679a57b7d2SSøren Schmidt switch (object->Type) { 4689a57b7d2SSøren Schmidt case MEMBUF: 4699a57b7d2SSøren Schmidt case VIDBUF8: 4705acf51eaSKazutaka YOKOTA case VIDBUF8S: 471933d455fSNicolas Souchu case VIDBUF16: 472933d455fSNicolas Souchu case VIDBUF16S: 4735cf92d7aSBruce Evans case VIDBUF24: 474933d455fSNicolas Souchu case VIDBUF24S: 4755cf92d7aSBruce Evans case VIDBUF32: 476933d455fSNicolas Souchu case VIDBUF32S: 4775cf92d7aSBruce Evans src.Type = MEMBUF; 4785cf92d7aSBruce Evans src.Xsize = object->Xsize; 4795cf92d7aSBruce Evans src.VXsize = object->VXsize; 4805cf92d7aSBruce Evans src.Ysize = 1; 4815cf92d7aSBruce Evans src.VYsize = 1; 4825cf92d7aSBruce Evans src.Xorigin = 0; 4835cf92d7aSBruce Evans src.Yorigin = 0; 4845cf92d7aSBruce Evans src.Bitmap = alloca(object->VXsize * object->PixelBytes); 4855cf92d7aSBruce Evans src.PixelBytes = object->PixelBytes; 4865cf92d7aSBruce Evans color = htole32(color); 4875cf92d7aSBruce Evans for (i = 0; i < object->VXsize; i++) 4885cf92d7aSBruce Evans bcopy(&color, src.Bitmap + i * object->PixelBytes, object->PixelBytes); 4895cf92d7aSBruce Evans for (i = 0; i < object->VYsize; i++) 4909db56319SBruce Evans __VGLBitmapCopy(&src, 0, 0, object, 0, i, object->VXsize, 1); 4915acf51eaSKazutaka YOKOTA break; 4925acf51eaSKazutaka YOKOTA 4939a57b7d2SSøren Schmidt case VIDBUF8X: 4949a57b7d2SSøren Schmidt /* XXX works only for Xsize % 4 = 0 */ 4955acf51eaSKazutaka YOKOTA outb(0x3c6, 0xff); 4969a57b7d2SSøren Schmidt outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 497933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, VGLAdpInfo.va_line_width*object->VYsize); 4989a57b7d2SSøren Schmidt break; 4999a57b7d2SSøren Schmidt 5009a57b7d2SSøren Schmidt case VIDBUF4: 5015acf51eaSKazutaka YOKOTA case VIDBUF4S: 5029a57b7d2SSøren Schmidt /* XXX works only for Xsize % 8 = 0 */ 5035acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 5045acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */ 5055acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 5065acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 5075acf51eaSKazutaka YOKOTA for (offset = 0; offset < VGLAdpInfo.va_line_width*object->VYsize; ) { 5085acf51eaSKazutaka YOKOTA VGLSetSegment(offset); 5095acf51eaSKazutaka YOKOTA len = min(object->VXsize*object->VYsize - offset, 5105acf51eaSKazutaka YOKOTA VGLAdpInfo.va_window_size); 511933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, len); 5125acf51eaSKazutaka YOKOTA offset += len; 5135acf51eaSKazutaka YOKOTA } 5145acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x00); 5159a57b7d2SSøren Schmidt break; 5169a57b7d2SSøren Schmidt } 517*c7432537SBruce Evans if (object == VGLDisplay) { 518*c7432537SBruce Evans if (mouseoverlap) 519*c7432537SBruce Evans VGLMousePointerShow(); 5209a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 5219a57b7d2SSøren Schmidt } 522*c7432537SBruce Evans } 5239a57b7d2SSøren Schmidt 524a93ca07aSBruce Evans static inline u_long 525a93ca07aSBruce Evans VGLrgbToNative(uint16_t r, uint16_t g, uint16_t b) 526a93ca07aSBruce Evans { 527a93ca07aSBruce Evans int nr, ng, nb; 528a93ca07aSBruce Evans 529a93ca07aSBruce Evans nr = VGLModeInfo.vi_pixel_fsizes[2]; 530a93ca07aSBruce Evans ng = VGLModeInfo.vi_pixel_fsizes[1]; 531a93ca07aSBruce Evans nb = VGLModeInfo.vi_pixel_fsizes[0]; 532a93ca07aSBruce Evans return (r >> (16 - nr) << (ng + nb)) | (g >> (16 - ng) << nb) | 533a93ca07aSBruce Evans (b >> (16 - nb) << 0); 534a93ca07aSBruce Evans } 535a93ca07aSBruce Evans 536a93ca07aSBruce Evans u_long 537a93ca07aSBruce Evans VGLrgb332ToNative(byte c) 538a93ca07aSBruce Evans { 539a93ca07aSBruce Evans uint16_t r, g, b; 540a93ca07aSBruce Evans 541a93ca07aSBruce Evans /* 3:3:2 to 16:16:16 */ 542a93ca07aSBruce Evans r = ((c & 0xe0) >> 5) * 0xffff / 7; 543a93ca07aSBruce Evans g = ((c & 0x1c) >> 2) * 0xffff / 7; 544a93ca07aSBruce Evans b = ((c & 0x03) >> 0) * 0xffff / 3; 545a93ca07aSBruce Evans 546a93ca07aSBruce Evans return VGLrgbToNative(r, g, b); 547a93ca07aSBruce Evans } 548a93ca07aSBruce Evans 5499a57b7d2SSøren Schmidt void 5509a57b7d2SSøren Schmidt VGLRestorePalette() 5519a57b7d2SSøren Schmidt { 5529a57b7d2SSøren Schmidt int i; 5539a57b7d2SSøren Schmidt 55480b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 55580b4b86eSBruce Evans return; 5569a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5579a57b7d2SSøren Schmidt inb(0x3DA); 5589a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 5599a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5609a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 5619a57b7d2SSøren Schmidt inb(0x84); 5629a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 5639a57b7d2SSøren Schmidt inb(0x84); 5649a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 5659a57b7d2SSøren Schmidt inb(0x84); 5669a57b7d2SSøren Schmidt } 5679a57b7d2SSøren Schmidt inb(0x3DA); 5689a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 5699a57b7d2SSøren Schmidt } 5709a57b7d2SSøren Schmidt 5719a57b7d2SSøren Schmidt void 5729a57b7d2SSøren Schmidt VGLSavePalette() 5739a57b7d2SSøren Schmidt { 5749a57b7d2SSøren Schmidt int i; 5759a57b7d2SSøren Schmidt 57680b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 57780b4b86eSBruce Evans return; 5789a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5799a57b7d2SSøren Schmidt inb(0x3DA); 5809a57b7d2SSøren Schmidt outb(0x3C7, 0x00); 5819a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5829a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = inb(0x3C9); 5839a57b7d2SSøren Schmidt inb(0x84); 5849a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = inb(0x3C9); 5859a57b7d2SSøren Schmidt inb(0x84); 5869a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = inb(0x3C9); 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 VGLSetPalette(byte *red, byte *green, byte *blue) 5959a57b7d2SSøren Schmidt { 5969a57b7d2SSøren Schmidt int i; 5979a57b7d2SSøren Schmidt 59880b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 59980b4b86eSBruce Evans return; 6009a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6019a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = red[i]; 6029a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = green[i]; 6039a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = blue[i]; 6049a57b7d2SSøren Schmidt } 6059a57b7d2SSøren Schmidt VGLCheckSwitch(); 6069a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6079a57b7d2SSøren Schmidt inb(0x3DA); 6089a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 6099a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6109a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 6119a57b7d2SSøren Schmidt inb(0x84); 6129a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 6139a57b7d2SSøren Schmidt inb(0x84); 6149a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 6159a57b7d2SSøren Schmidt inb(0x84); 6169a57b7d2SSøren Schmidt } 6179a57b7d2SSøren Schmidt inb(0x3DA); 6189a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6199a57b7d2SSøren Schmidt } 6209a57b7d2SSøren Schmidt 6219a57b7d2SSøren Schmidt void 6229a57b7d2SSøren Schmidt VGLSetPaletteIndex(byte color, byte red, byte green, byte blue) 6239a57b7d2SSøren Schmidt { 62480b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 62580b4b86eSBruce Evans return; 6269a57b7d2SSøren Schmidt VGLSavePaletteRed[color] = red; 6279a57b7d2SSøren Schmidt VGLSavePaletteGreen[color] = green; 6289a57b7d2SSøren Schmidt VGLSavePaletteBlue[color] = blue; 6299a57b7d2SSøren Schmidt VGLCheckSwitch(); 6309a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6319a57b7d2SSøren Schmidt inb(0x3DA); 6329a57b7d2SSøren Schmidt outb(0x3C8, color); 6339a57b7d2SSøren Schmidt outb(0x3C9, red); outb(0x3C9, green); outb(0x3C9, blue); 6349a57b7d2SSøren Schmidt inb(0x3DA); 6359a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6369a57b7d2SSøren Schmidt } 6379a57b7d2SSøren Schmidt 6389a57b7d2SSøren Schmidt void 639e848f3d1SBruce Evans VGLRestoreBorder(void) 640e848f3d1SBruce Evans { 641e848f3d1SBruce Evans VGLSetBorder(VGLBorderColor); 642e848f3d1SBruce Evans } 643e848f3d1SBruce Evans 644e848f3d1SBruce Evans void 6459a57b7d2SSøren Schmidt VGLSetBorder(byte color) 6469a57b7d2SSøren Schmidt { 64780b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0)) 64880b4b86eSBruce Evans return; 6499a57b7d2SSøren Schmidt VGLCheckSwitch(); 6509a57b7d2SSøren Schmidt inb(0x3DA); 6519a57b7d2SSøren Schmidt outb(0x3C0,0x11); outb(0x3C0, color); 6529a57b7d2SSøren Schmidt inb(0x3DA); 6539a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 654e848f3d1SBruce Evans VGLBorderColor = color; 65580b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 65680b4b86eSBruce Evans ioctl(0, KDDISABIO, 0); 6579a57b7d2SSøren Schmidt } 6589a57b7d2SSøren Schmidt 6599a57b7d2SSøren Schmidt void 660e848f3d1SBruce Evans VGLRestoreBlank(void) 661e848f3d1SBruce Evans { 662e848f3d1SBruce Evans VGLBlankDisplay(VGLBlank); 663e848f3d1SBruce Evans } 664e848f3d1SBruce Evans 665e848f3d1SBruce Evans void 6669a57b7d2SSøren Schmidt VGLBlankDisplay(int blank) 6679a57b7d2SSøren Schmidt { 6689a57b7d2SSøren Schmidt byte val; 6699a57b7d2SSøren Schmidt 67080b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0)) 67180b4b86eSBruce Evans return; 6729a57b7d2SSøren Schmidt VGLCheckSwitch(); 6739a57b7d2SSøren Schmidt outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01); 6749a57b7d2SSøren Schmidt outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF))); 675e848f3d1SBruce Evans VGLBlank = blank; 67680b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 67780b4b86eSBruce Evans ioctl(0, KDDISABIO, 0); 6789a57b7d2SSøren Schmidt } 679