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 { 54ea0a9905SBruce Evans int offset, soffset, undermouse; 555acf51eaSKazutaka YOKOTA 569a57b7d2SSøren Schmidt VGLCheckSwitch(); 575acf51eaSKazutaka YOKOTA if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) { 58c7432537SBruce Evans if (object == VGLDisplay) { 59c7432537SBruce Evans undermouse = VGLMouseFreezeXY(x, y); 601fa51420SBruce Evans VGLSetXY(&VGLVDisplay, x, y, color); 61c7432537SBruce Evans } else if (object->Type != MEMBUF) 62c7432537SBruce Evans return; /* invalid */ 63c7432537SBruce Evans else 64c7432537SBruce Evans undermouse = 0; 65c7432537SBruce 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 VIDBUF32S: 715cf92d7aSBruce Evans offset = VGLSetSegment(offset); 725cf92d7aSBruce Evans /* FALLTHROUGH */ 735cf92d7aSBruce Evans case MEMBUF: 745cf92d7aSBruce Evans case VIDBUF8: 755cf92d7aSBruce Evans case VIDBUF16: 765cf92d7aSBruce Evans case VIDBUF24: 775cf92d7aSBruce Evans case VIDBUF32: 785cf92d7aSBruce Evans color = htole32(color); 795cf92d7aSBruce Evans switch (object->PixelBytes) { 805cf92d7aSBruce Evans case 1: 815cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 1); 825cf92d7aSBruce Evans break; 835cf92d7aSBruce Evans case 2: 845cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 2); 855cf92d7aSBruce Evans break; 865cf92d7aSBruce Evans case 3: 875cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 3); 885cf92d7aSBruce Evans break; 895cf92d7aSBruce Evans case 4: 905cf92d7aSBruce Evans memcpy(&object->Bitmap[offset], &color, 4); 915cf92d7aSBruce Evans break; 925cf92d7aSBruce Evans } 939a57b7d2SSøren Schmidt break; 94ea0a9905SBruce Evans case VIDBUF24S: 95ea0a9905SBruce Evans soffset = VGLSetSegment(offset); 96ea0a9905SBruce Evans color = htole32(color); 97ea0a9905SBruce Evans switch (VGLAdpInfo.va_window_size - soffset) { 98ea0a9905SBruce Evans case 1: 99ea0a9905SBruce Evans memcpy(&object->Bitmap[soffset], &color, 1); 100ea0a9905SBruce Evans soffset = VGLSetSegment(offset + 1); 101ea0a9905SBruce Evans memcpy(&object->Bitmap[soffset], (byte *)&color + 1, 2); 102ea0a9905SBruce Evans break; 103ea0a9905SBruce Evans case 2: 104ea0a9905SBruce Evans memcpy(&object->Bitmap[soffset], &color, 2); 105ea0a9905SBruce Evans soffset = VGLSetSegment(offset + 2); 106ea0a9905SBruce Evans memcpy(&object->Bitmap[soffset], (byte *)&color + 2, 1); 107ea0a9905SBruce Evans break; 108ea0a9905SBruce Evans default: 109ea0a9905SBruce Evans memcpy(&object->Bitmap[soffset], &color, 3); 110ea0a9905SBruce Evans break; 111ea0a9905SBruce Evans } 112ea0a9905SBruce Evans break; 1139a57b7d2SSøren Schmidt case VIDBUF8X: 1149a57b7d2SSøren Schmidt outb(0x3c4, 0x02); 1159a57b7d2SSøren Schmidt outb(0x3c5, 0x01 << (x&0x3)); 116933d455fSNicolas Souchu object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = ((byte)color); 1179a57b7d2SSøren Schmidt break; 1185acf51eaSKazutaka YOKOTA case VIDBUF4S: 1195acf51eaSKazutaka YOKOTA offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8); 1205acf51eaSKazutaka YOKOTA goto set_planar; 1219a57b7d2SSøren Schmidt case VIDBUF4: 1225acf51eaSKazutaka YOKOTA offset = y*VGLAdpInfo.va_line_width + x/8; 1235acf51eaSKazutaka YOKOTA set_planar: 1245acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 125933d455fSNicolas Souchu outb(0x3ce, 0x00); outb(0x3cf, (byte)color & 0x0f); /* set/reset */ 1265acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x0f); /* set/reset enable */ 1275acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8)); /* bit mask */ 128933d455fSNicolas Souchu object->Bitmap[offset] |= (byte)color; 1299a57b7d2SSøren Schmidt } 1309a57b7d2SSøren Schmidt } 131c7432537SBruce Evans if (object == VGLDisplay) 1329a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 1339a57b7d2SSøren Schmidt } 1349a57b7d2SSøren Schmidt } 1359a57b7d2SSøren Schmidt 136d6003dd3SBruce Evans u_long 137d6003dd3SBruce Evans VGLGetXY(VGLBitmap *object, int x, int y) 1389a57b7d2SSøren Schmidt { 139933d455fSNicolas Souchu u_long color; 140d6003dd3SBruce Evans int offset; 1415acf51eaSKazutaka YOKOTA 142d6003dd3SBruce Evans VGLCheckSwitch(); 143d6003dd3SBruce Evans if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize) 144d6003dd3SBruce Evans return 0; 145d6003dd3SBruce Evans if (object == VGLDisplay) 146d6003dd3SBruce Evans object = &VGLVDisplay; 147d6003dd3SBruce Evans else if (object->Type != MEMBUF) 148d6003dd3SBruce Evans return 0; /* invalid */ 1495cf92d7aSBruce Evans offset = (y * object->VXsize + x) * object->PixelBytes; 1505cf92d7aSBruce Evans switch (object->PixelBytes) { 1515cf92d7aSBruce Evans case 1: 1525cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 1); 1535cf92d7aSBruce Evans return le32toh(color) & 0xff; 1545cf92d7aSBruce Evans case 2: 1555cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 2); 1565cf92d7aSBruce Evans return le32toh(color) & 0xffff; 1575cf92d7aSBruce Evans case 3: 1585cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 3); 1595cf92d7aSBruce Evans return le32toh(color) & 0xffffff; 1605cf92d7aSBruce Evans case 4: 1615cf92d7aSBruce Evans memcpy(&color, &object->Bitmap[offset], 4); 1625cf92d7aSBruce Evans return le32toh(color); 1635cf92d7aSBruce Evans } 1641fa51420SBruce Evans return 0; /* invalid */ 1659a57b7d2SSøren Schmidt } 1669a57b7d2SSøren Schmidt 1674c995944SPedro F. Giffuni /* 1684c995944SPedro F. Giffuni * Symmetric Double Step Line Algorithm by Brian Wyvill from 1694c995944SPedro F. Giffuni * "Graphics Gems", Academic Press, 1990. 1704c995944SPedro F. Giffuni */ 1714c995944SPedro F. Giffuni 1724c995944SPedro F. Giffuni #define SL_SWAP(a,b) {a^=b; b^=a; a^=b;} 1734c995944SPedro F. Giffuni #define SL_ABSOLUTE(i,j,k) ( (i-j)*(k = ( (i-j)<0 ? -1 : 1))) 1744c995944SPedro F. Giffuni 1754c995944SPedro F. Giffuni void 1765ee94e99SBruce Evans plot(VGLBitmap * object, int x, int y, int flag, u_long color) 1774c995944SPedro F. Giffuni { 1784c995944SPedro F. Giffuni /* non-zero flag indicates the pixels need swapping back. */ 1794c995944SPedro F. Giffuni if (flag) 1804c995944SPedro F. Giffuni VGLSetXY(object, y, x, color); 1814c995944SPedro F. Giffuni else 1824c995944SPedro F. Giffuni VGLSetXY(object, x, y, color); 1834c995944SPedro F. Giffuni } 1844c995944SPedro F. Giffuni 1854c995944SPedro F. Giffuni 1869a57b7d2SSøren Schmidt void 187933d455fSNicolas Souchu VGLLine(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 1889a57b7d2SSøren Schmidt { 1894c995944SPedro F. Giffuni int dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left; 1904c995944SPedro F. Giffuni int sign_x, sign_y, step, reverse, i; 1919a57b7d2SSøren Schmidt 1924c995944SPedro F. Giffuni dx = SL_ABSOLUTE(x2, x1, sign_x); 1934c995944SPedro F. Giffuni dy = SL_ABSOLUTE(y2, y1, sign_y); 1944c995944SPedro F. Giffuni /* decide increment sign by the slope sign */ 1954c995944SPedro F. Giffuni if (sign_x == sign_y) 1964c995944SPedro F. Giffuni step = 1; 1974c995944SPedro F. Giffuni else 1984c995944SPedro F. Giffuni step = -1; 1999a57b7d2SSøren Schmidt 2004c995944SPedro F. Giffuni if (dy > dx) { /* chooses axis of greatest movement (make dx) */ 2014c995944SPedro F. Giffuni SL_SWAP(x1, y1); 2024c995944SPedro F. Giffuni SL_SWAP(x2, y2); 2034c995944SPedro F. Giffuni SL_SWAP(dx, dy); 2044c995944SPedro F. Giffuni reverse = 1; 2054c995944SPedro F. Giffuni } else 2064c995944SPedro F. Giffuni reverse = 0; 2074c995944SPedro F. Giffuni /* note error check for dx==0 should be included here */ 2084c995944SPedro F. Giffuni if (x1 > x2) { /* start from the smaller coordinate */ 2094c995944SPedro F. Giffuni x = x2; 2104c995944SPedro F. Giffuni y = y2; 21183057bafSPedro F. Giffuni /* x1 = x1; 21283057bafSPedro F. Giffuni y1 = y1; */ 2134c995944SPedro F. Giffuni } else { 2144c995944SPedro F. Giffuni x = x1; 2154c995944SPedro F. Giffuni y = y1; 2164c995944SPedro F. Giffuni x1 = x2; 2174c995944SPedro F. Giffuni y1 = y2; 2189a57b7d2SSøren Schmidt } 2194c995944SPedro F. Giffuni 2204c995944SPedro F. Giffuni 2214c995944SPedro F. Giffuni /* Note dx=n implies 0 - n or (dx+1) pixels to be set */ 2224c995944SPedro F. Giffuni /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */ 2234c995944SPedro F. Giffuni /* In fact (dx-1)/4 as 2 pixels are already plotted */ 2244c995944SPedro F. Giffuni xend = (dx - 1) / 4; 2254c995944SPedro F. Giffuni pixels_left = (dx - 1) % 4; /* number of pixels left over at the 2264c995944SPedro F. Giffuni * end */ 2274c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2284c995944SPedro F. Giffuni if (pixels_left < 0) 2294c995944SPedro F. Giffuni return; /* plot only one pixel for zero length 2304c995944SPedro F. Giffuni * vectors */ 2314c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); /* plot first two points */ 2324c995944SPedro F. Giffuni incr2 = 4 * dy - 2 * dx; 2334c995944SPedro F. Giffuni if (incr2 < 0) { /* slope less than 1/2 */ 2344c995944SPedro F. Giffuni c = 2 * dy; 2354c995944SPedro F. Giffuni incr1 = 2 * c; 2364c995944SPedro F. Giffuni D = incr1 - dx; 2374c995944SPedro F. Giffuni 2384c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { /* plotting loop */ 2394c995944SPedro F. Giffuni ++x; 2404c995944SPedro F. Giffuni --x1; 2414c995944SPedro F. Giffuni if (D < 0) { 2424c995944SPedro F. Giffuni /* pattern 1 forwards */ 2434c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2444c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2454c995944SPedro F. Giffuni /* pattern 1 backwards */ 2464c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2474c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2484c995944SPedro F. Giffuni D += incr1; 2494c995944SPedro F. Giffuni } else { 2504c995944SPedro F. Giffuni if (D < c) { 2514c995944SPedro F. Giffuni /* pattern 2 forwards */ 2524c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 2534c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 2544c995944SPedro F. Giffuni color); 2554c995944SPedro F. Giffuni /* pattern 2 backwards */ 2564c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 2574c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 2584c995944SPedro F. Giffuni color); 2594c995944SPedro F. Giffuni } else { 2604c995944SPedro F. Giffuni /* pattern 3 forwards */ 2614c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 2624c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2634c995944SPedro F. Giffuni /* pattern 3 backwards */ 2644c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, 2654c995944SPedro F. Giffuni color); 2664c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2674c995944SPedro F. Giffuni } 2684c995944SPedro F. Giffuni D += incr2; 2694c995944SPedro F. Giffuni } 2704c995944SPedro F. Giffuni } /* end for */ 2714c995944SPedro F. Giffuni 2724c995944SPedro F. Giffuni /* plot last pattern */ 2734c995944SPedro F. Giffuni if (pixels_left) { 2744c995944SPedro F. Giffuni if (D < 0) { 2754c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 1 */ 2764c995944SPedro F. Giffuni if (pixels_left > 1) 2774c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2784c995944SPedro F. Giffuni if (pixels_left > 2) 2794c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2804c995944SPedro F. Giffuni } else { 2814c995944SPedro F. Giffuni if (D < c) { 2824c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 2834c995944SPedro F. Giffuni if (pixels_left > 1) 2844c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 2854c995944SPedro F. Giffuni if (pixels_left > 2) 2864c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 2874c995944SPedro F. Giffuni } else { 2884c995944SPedro F. Giffuni /* pattern 3 */ 2894c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 2904c995944SPedro F. Giffuni if (pixels_left > 1) 2914c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 2924c995944SPedro F. Giffuni if (pixels_left > 2) 2934c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 2949a57b7d2SSøren Schmidt } 2959a57b7d2SSøren Schmidt } 2964c995944SPedro F. Giffuni } /* end if pixels_left */ 2979a57b7d2SSøren Schmidt } 2984c995944SPedro F. Giffuni /* end slope < 1/2 */ 2994c995944SPedro F. Giffuni else { /* slope greater than 1/2 */ 3004c995944SPedro F. Giffuni c = 2 * (dy - dx); 3014c995944SPedro F. Giffuni incr1 = 2 * c; 3024c995944SPedro F. Giffuni D = incr1 + dx; 3034c995944SPedro F. Giffuni for (i = 0; i < xend; i++) { 3044c995944SPedro F. Giffuni ++x; 3054c995944SPedro F. Giffuni --x1; 3064c995944SPedro F. Giffuni if (D > 0) { 3074c995944SPedro F. Giffuni /* pattern 4 forwards */ 3084c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3094c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3104c995944SPedro F. Giffuni /* pattern 4 backwards */ 3114c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3124c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3134c995944SPedro F. Giffuni D += incr1; 3144c995944SPedro F. Giffuni } else { 3154c995944SPedro F. Giffuni if (D < c) { 3164c995944SPedro F. Giffuni /* pattern 2 forwards */ 3174c995944SPedro F. Giffuni plot(object, x, y, reverse, color); 3184c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3194c995944SPedro F. Giffuni color); 3204c995944SPedro F. Giffuni 3214c995944SPedro F. Giffuni /* pattern 2 backwards */ 3224c995944SPedro F. Giffuni plot(object, x1, y1, reverse, color); 3234c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3244c995944SPedro F. Giffuni color); 3254c995944SPedro F. Giffuni } else { 3264c995944SPedro F. Giffuni /* pattern 3 forwards */ 3274c995944SPedro F. Giffuni plot(object, x, y += step, reverse, color); 3284c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3294c995944SPedro F. Giffuni /* pattern 3 backwards */ 3304c995944SPedro F. Giffuni plot(object, x1, y1 -= step, reverse, color); 3314c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3324c995944SPedro F. Giffuni } 3334c995944SPedro F. Giffuni D += incr2; 3344c995944SPedro F. Giffuni } 3354c995944SPedro F. Giffuni } /* end for */ 3364c995944SPedro F. Giffuni /* plot last pattern */ 3374c995944SPedro F. Giffuni if (pixels_left) { 3384c995944SPedro F. Giffuni if (D > 0) { 3394c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); /* pattern 4 */ 3404c995944SPedro F. Giffuni if (pixels_left > 1) 3414c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, 3424c995944SPedro F. Giffuni color); 3434c995944SPedro F. Giffuni if (pixels_left > 2) 3444c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, 3454c995944SPedro F. Giffuni color); 3464c995944SPedro F. Giffuni } else { 3474c995944SPedro F. Giffuni if (D < c) { 3484c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); /* pattern 2 */ 3494c995944SPedro F. Giffuni if (pixels_left > 1) 3504c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3514c995944SPedro F. Giffuni if (pixels_left > 2) 3524c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3534c995944SPedro F. Giffuni } else { 3544c995944SPedro F. Giffuni /* pattern 3 */ 3554c995944SPedro F. Giffuni plot(object, ++x, y += step, reverse, color); 3564c995944SPedro F. Giffuni if (pixels_left > 1) 3574c995944SPedro F. Giffuni plot(object, ++x, y, reverse, color); 3584c995944SPedro F. Giffuni if (pixels_left > 2) { 3594c995944SPedro F. Giffuni if (D > c) /* step 3 */ 3604c995944SPedro F. Giffuni plot(object, --x1, y1 -= step, reverse, color); 3614c995944SPedro F. Giffuni else /* step 2 */ 3624c995944SPedro F. Giffuni plot(object, --x1, y1, reverse, color); 3634c995944SPedro F. Giffuni } 3644c995944SPedro F. Giffuni } 3654c995944SPedro F. Giffuni } 3669a57b7d2SSøren Schmidt } 3679a57b7d2SSøren Schmidt } 3689a57b7d2SSøren Schmidt } 3699a57b7d2SSøren Schmidt 3709a57b7d2SSøren Schmidt void 371933d455fSNicolas Souchu VGLBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 3729a57b7d2SSøren Schmidt { 3739a57b7d2SSøren Schmidt VGLLine(object, x1, y1, x2, y1, color); 3749a57b7d2SSøren Schmidt VGLLine(object, x2, y1, x2, y2, color); 3759a57b7d2SSøren Schmidt VGLLine(object, x2, y2, x1, y2, color); 3769a57b7d2SSøren Schmidt VGLLine(object, x1, y2, x1, y1, color); 3779a57b7d2SSøren Schmidt } 3789a57b7d2SSøren Schmidt 3799a57b7d2SSøren Schmidt void 380933d455fSNicolas Souchu VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long color) 3819a57b7d2SSøren Schmidt { 3829a57b7d2SSøren Schmidt int y; 3839a57b7d2SSøren Schmidt 3849a57b7d2SSøren Schmidt for (y=y1; y<=y2; y++) VGLLine(object, x1, y, x2, y, color); 3859a57b7d2SSøren Schmidt } 3869a57b7d2SSøren Schmidt 387e7032b4cSDimitry Andric static inline void 388e7032b4cSDimitry Andric set4pixels(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 3899a57b7d2SSøren Schmidt { 3909a57b7d2SSøren Schmidt if (x!=0) { 3919a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc+y, color); 3929a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc+y, color); 3939a57b7d2SSøren Schmidt if (y!=0) { 3949a57b7d2SSøren Schmidt VGLSetXY(object, xc+x, yc-y, color); 3959a57b7d2SSøren Schmidt VGLSetXY(object, xc-x, yc-y, color); 3969a57b7d2SSøren Schmidt } 3979a57b7d2SSøren Schmidt } 3989a57b7d2SSøren Schmidt else { 3999a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc+y, color); 4009a57b7d2SSøren Schmidt if (y!=0) 4019a57b7d2SSøren Schmidt VGLSetXY(object, xc, yc-y, color); 4029a57b7d2SSøren Schmidt } 4039a57b7d2SSøren Schmidt } 4049a57b7d2SSøren Schmidt 4059a57b7d2SSøren Schmidt void 406933d455fSNicolas Souchu VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 4079a57b7d2SSøren Schmidt { 4089a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 4099a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 4109a57b7d2SSøren Schmidt 4119a57b7d2SSøren Schmidt while (dx<dy) { 4129a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4139a57b7d2SSøren Schmidt if (d>0) { 4149a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4159a57b7d2SSøren Schmidt } 4169a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4179a57b7d2SSøren Schmidt } 4189a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4199a57b7d2SSøren Schmidt while (y>=0) { 4209a57b7d2SSøren Schmidt set4pixels(object, x, y, xc, yc, color); 4219a57b7d2SSøren Schmidt if (d<0) { 4229a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4239a57b7d2SSøren Schmidt } 4249a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4259a57b7d2SSøren Schmidt } 4269a57b7d2SSøren Schmidt } 4279a57b7d2SSøren Schmidt 428e7032b4cSDimitry Andric static inline void 429e7032b4cSDimitry Andric set2lines(VGLBitmap *object, int x, int y, int xc, int yc, u_long color) 4309a57b7d2SSøren Schmidt { 4319a57b7d2SSøren Schmidt if (x!=0) { 4329a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc+y, xc-x, yc+y, color); 4339a57b7d2SSøren Schmidt if (y!=0) 4349a57b7d2SSøren Schmidt VGLLine(object, xc+x, yc-y, xc-x, yc-y, color); 4359a57b7d2SSøren Schmidt } 4369a57b7d2SSøren Schmidt else { 4379a57b7d2SSøren Schmidt VGLLine(object, xc, yc+y, xc, yc-y, color); 4389a57b7d2SSøren Schmidt } 4399a57b7d2SSøren Schmidt } 4409a57b7d2SSøren Schmidt 4419a57b7d2SSøren Schmidt void 442933d455fSNicolas Souchu VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color) 4439a57b7d2SSøren Schmidt { 4449a57b7d2SSøren Schmidt int x = 0, y = b, asq = a*a, asq2 = a*a*2, bsq = b*b; 4459a57b7d2SSøren Schmidt int bsq2 = b*b*2, d = bsq-asq*b+asq/4, dx = 0, dy = asq2*b; 4469a57b7d2SSøren Schmidt 4479a57b7d2SSøren Schmidt while (dx<dy) { 4489a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 4499a57b7d2SSøren Schmidt if (d>0) { 4509a57b7d2SSøren Schmidt y--; dy-=asq2; d-=dy; 4519a57b7d2SSøren Schmidt } 4529a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=bsq+dx; 4539a57b7d2SSøren Schmidt } 4549a57b7d2SSøren Schmidt d+=(3*(asq-bsq)/2-(dx+dy))/2; 4559a57b7d2SSøren Schmidt while (y>=0) { 4569a57b7d2SSøren Schmidt set2lines(object, x, y, xc, yc, color); 4579a57b7d2SSøren Schmidt if (d<0) { 4589a57b7d2SSøren Schmidt x++; dx+=bsq2; d+=dx; 4599a57b7d2SSøren Schmidt } 4609a57b7d2SSøren Schmidt y--; dy-=asq2; d+=asq-dy; 4619a57b7d2SSøren Schmidt } 4629a57b7d2SSøren Schmidt } 4639a57b7d2SSøren Schmidt 4649a57b7d2SSøren Schmidt void 465933d455fSNicolas Souchu VGLClear(VGLBitmap *object, u_long color) 4669a57b7d2SSøren Schmidt { 4675cf92d7aSBruce Evans VGLBitmap src; 468*c0ce6f7dSBruce Evans int i, len, mousemode, offset; 4695acf51eaSKazutaka YOKOTA 4709a57b7d2SSøren Schmidt VGLCheckSwitch(); 4711fa51420SBruce Evans if (object == VGLDisplay) { 472c7432537SBruce Evans VGLMouseFreeze(); 4731fa51420SBruce Evans VGLClear(&VGLVDisplay, color); 4741fa51420SBruce Evans } else if (object->Type != MEMBUF) 4751fa51420SBruce Evans return; /* invalid */ 4769a57b7d2SSøren Schmidt switch (object->Type) { 4779a57b7d2SSøren Schmidt case MEMBUF: 4789a57b7d2SSøren Schmidt case VIDBUF8: 4795acf51eaSKazutaka YOKOTA case VIDBUF8S: 480933d455fSNicolas Souchu case VIDBUF16: 481933d455fSNicolas Souchu case VIDBUF16S: 4825cf92d7aSBruce Evans case VIDBUF24: 483933d455fSNicolas Souchu case VIDBUF24S: 4845cf92d7aSBruce Evans case VIDBUF32: 485933d455fSNicolas Souchu case VIDBUF32S: 4865cf92d7aSBruce Evans src.Type = MEMBUF; 4875cf92d7aSBruce Evans src.Xsize = object->Xsize; 4885cf92d7aSBruce Evans src.VXsize = object->VXsize; 4895cf92d7aSBruce Evans src.Ysize = 1; 4905cf92d7aSBruce Evans src.VYsize = 1; 4915cf92d7aSBruce Evans src.Xorigin = 0; 4925cf92d7aSBruce Evans src.Yorigin = 0; 4935cf92d7aSBruce Evans src.Bitmap = alloca(object->VXsize * object->PixelBytes); 4945cf92d7aSBruce Evans src.PixelBytes = object->PixelBytes; 4955cf92d7aSBruce Evans color = htole32(color); 4965cf92d7aSBruce Evans for (i = 0; i < object->VXsize; i++) 4975cf92d7aSBruce Evans bcopy(&color, src.Bitmap + i * object->PixelBytes, object->PixelBytes); 4985cf92d7aSBruce Evans for (i = 0; i < object->VYsize; i++) 4999db56319SBruce Evans __VGLBitmapCopy(&src, 0, 0, object, 0, i, object->VXsize, 1); 5005acf51eaSKazutaka YOKOTA break; 5015acf51eaSKazutaka YOKOTA 5029a57b7d2SSøren Schmidt case VIDBUF8X: 503*c0ce6f7dSBruce Evans mousemode = __VGLMouseMode(VGL_MOUSEHIDE); 5049a57b7d2SSøren Schmidt /* XXX works only for Xsize % 4 = 0 */ 5055acf51eaSKazutaka YOKOTA outb(0x3c6, 0xff); 5069a57b7d2SSøren Schmidt outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 507933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, VGLAdpInfo.va_line_width*object->VYsize); 508*c0ce6f7dSBruce Evans __VGLMouseMode(mousemode); 5099a57b7d2SSøren Schmidt break; 5109a57b7d2SSøren Schmidt 5119a57b7d2SSøren Schmidt case VIDBUF4: 5125acf51eaSKazutaka YOKOTA case VIDBUF4S: 513*c0ce6f7dSBruce Evans mousemode = __VGLMouseMode(VGL_MOUSEHIDE); 5149a57b7d2SSøren Schmidt /* XXX works only for Xsize % 8 = 0 */ 5155acf51eaSKazutaka YOKOTA outb(0x3c4, 0x02); outb(0x3c5, 0x0f); 5165acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */ 5175acf51eaSKazutaka YOKOTA outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 5185acf51eaSKazutaka YOKOTA outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 5195acf51eaSKazutaka YOKOTA for (offset = 0; offset < VGLAdpInfo.va_line_width*object->VYsize; ) { 5205acf51eaSKazutaka YOKOTA VGLSetSegment(offset); 5215acf51eaSKazutaka YOKOTA len = min(object->VXsize*object->VYsize - offset, 5225acf51eaSKazutaka YOKOTA VGLAdpInfo.va_window_size); 523933d455fSNicolas Souchu memset(object->Bitmap, (byte)color, len); 5245acf51eaSKazutaka YOKOTA offset += len; 5255acf51eaSKazutaka YOKOTA } 5265acf51eaSKazutaka YOKOTA outb(0x3ce, 0x05); outb(0x3cf, 0x00); 527*c0ce6f7dSBruce Evans __VGLMouseMode(mousemode); 5289a57b7d2SSøren Schmidt break; 5299a57b7d2SSøren Schmidt } 530*c0ce6f7dSBruce Evans if (object == VGLDisplay) 5319a57b7d2SSøren Schmidt VGLMouseUnFreeze(); 5329a57b7d2SSøren Schmidt } 5339a57b7d2SSøren Schmidt 534a93ca07aSBruce Evans static inline u_long 535a93ca07aSBruce Evans VGLrgbToNative(uint16_t r, uint16_t g, uint16_t b) 536a93ca07aSBruce Evans { 537a93ca07aSBruce Evans int nr, ng, nb; 538a93ca07aSBruce Evans 539a93ca07aSBruce Evans nr = VGLModeInfo.vi_pixel_fsizes[2]; 540a93ca07aSBruce Evans ng = VGLModeInfo.vi_pixel_fsizes[1]; 541a93ca07aSBruce Evans nb = VGLModeInfo.vi_pixel_fsizes[0]; 542a93ca07aSBruce Evans return (r >> (16 - nr) << (ng + nb)) | (g >> (16 - ng) << nb) | 543a93ca07aSBruce Evans (b >> (16 - nb) << 0); 544a93ca07aSBruce Evans } 545a93ca07aSBruce Evans 546a93ca07aSBruce Evans u_long 547a93ca07aSBruce Evans VGLrgb332ToNative(byte c) 548a93ca07aSBruce Evans { 549a93ca07aSBruce Evans uint16_t r, g, b; 550a93ca07aSBruce Evans 551a93ca07aSBruce Evans /* 3:3:2 to 16:16:16 */ 552a93ca07aSBruce Evans r = ((c & 0xe0) >> 5) * 0xffff / 7; 553a93ca07aSBruce Evans g = ((c & 0x1c) >> 2) * 0xffff / 7; 554a93ca07aSBruce Evans b = ((c & 0x03) >> 0) * 0xffff / 3; 555a93ca07aSBruce Evans 556a93ca07aSBruce Evans return VGLrgbToNative(r, g, b); 557a93ca07aSBruce Evans } 558a93ca07aSBruce Evans 5599a57b7d2SSøren Schmidt void 5609a57b7d2SSøren Schmidt VGLRestorePalette() 5619a57b7d2SSøren Schmidt { 5629a57b7d2SSøren Schmidt int i; 5639a57b7d2SSøren Schmidt 56480b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 56580b4b86eSBruce Evans return; 5669a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5679a57b7d2SSøren Schmidt inb(0x3DA); 5689a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 5699a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5709a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 5719a57b7d2SSøren Schmidt inb(0x84); 5729a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 5739a57b7d2SSøren Schmidt inb(0x84); 5749a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 5759a57b7d2SSøren Schmidt inb(0x84); 5769a57b7d2SSøren Schmidt } 5779a57b7d2SSøren Schmidt inb(0x3DA); 5789a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 5799a57b7d2SSøren Schmidt } 5809a57b7d2SSøren Schmidt 5819a57b7d2SSøren Schmidt void 5829a57b7d2SSøren Schmidt VGLSavePalette() 5839a57b7d2SSøren Schmidt { 5849a57b7d2SSøren Schmidt int i; 5859a57b7d2SSøren Schmidt 58680b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 58780b4b86eSBruce Evans return; 5889a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 5899a57b7d2SSøren Schmidt inb(0x3DA); 5909a57b7d2SSøren Schmidt outb(0x3C7, 0x00); 5919a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 5929a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = inb(0x3C9); 5939a57b7d2SSøren Schmidt inb(0x84); 5949a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = inb(0x3C9); 5959a57b7d2SSøren Schmidt inb(0x84); 5969a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = inb(0x3C9); 5979a57b7d2SSøren Schmidt inb(0x84); 5989a57b7d2SSøren Schmidt } 5999a57b7d2SSøren Schmidt inb(0x3DA); 6009a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6019a57b7d2SSøren Schmidt } 6029a57b7d2SSøren Schmidt 6039a57b7d2SSøren Schmidt void 6049a57b7d2SSøren Schmidt VGLSetPalette(byte *red, byte *green, byte *blue) 6059a57b7d2SSøren Schmidt { 6069a57b7d2SSøren Schmidt int i; 6079a57b7d2SSøren Schmidt 60880b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 60980b4b86eSBruce Evans return; 6109a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6119a57b7d2SSøren Schmidt VGLSavePaletteRed[i] = red[i]; 6129a57b7d2SSøren Schmidt VGLSavePaletteGreen[i] = green[i]; 6139a57b7d2SSøren Schmidt VGLSavePaletteBlue[i] = blue[i]; 6149a57b7d2SSøren Schmidt } 6159a57b7d2SSøren Schmidt VGLCheckSwitch(); 6169a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6179a57b7d2SSøren Schmidt inb(0x3DA); 6189a57b7d2SSøren Schmidt outb(0x3C8, 0x00); 6199a57b7d2SSøren Schmidt for (i=0; i<256; i++) { 6209a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteRed[i]); 6219a57b7d2SSøren Schmidt inb(0x84); 6229a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteGreen[i]); 6239a57b7d2SSøren Schmidt inb(0x84); 6249a57b7d2SSøren Schmidt outb(0x3C9, VGLSavePaletteBlue[i]); 6259a57b7d2SSøren Schmidt inb(0x84); 6269a57b7d2SSøren Schmidt } 6279a57b7d2SSøren Schmidt inb(0x3DA); 6289a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6299a57b7d2SSøren Schmidt } 6309a57b7d2SSøren Schmidt 6319a57b7d2SSøren Schmidt void 6329a57b7d2SSøren Schmidt VGLSetPaletteIndex(byte color, byte red, byte green, byte blue) 6339a57b7d2SSøren Schmidt { 63480b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 63580b4b86eSBruce Evans return; 6369a57b7d2SSøren Schmidt VGLSavePaletteRed[color] = red; 6379a57b7d2SSøren Schmidt VGLSavePaletteGreen[color] = green; 6389a57b7d2SSøren Schmidt VGLSavePaletteBlue[color] = blue; 6399a57b7d2SSøren Schmidt VGLCheckSwitch(); 6409a57b7d2SSøren Schmidt outb(0x3C6, 0xFF); 6419a57b7d2SSøren Schmidt inb(0x3DA); 6429a57b7d2SSøren Schmidt outb(0x3C8, color); 6439a57b7d2SSøren Schmidt outb(0x3C9, red); outb(0x3C9, green); outb(0x3C9, blue); 6449a57b7d2SSøren Schmidt inb(0x3DA); 6459a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 6469a57b7d2SSøren Schmidt } 6479a57b7d2SSøren Schmidt 6489a57b7d2SSøren Schmidt void 649e848f3d1SBruce Evans VGLRestoreBorder(void) 650e848f3d1SBruce Evans { 651e848f3d1SBruce Evans VGLSetBorder(VGLBorderColor); 652e848f3d1SBruce Evans } 653e848f3d1SBruce Evans 654e848f3d1SBruce Evans void 6559a57b7d2SSøren Schmidt VGLSetBorder(byte color) 6569a57b7d2SSøren Schmidt { 65780b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0)) 65880b4b86eSBruce Evans return; 6599a57b7d2SSøren Schmidt VGLCheckSwitch(); 6609a57b7d2SSøren Schmidt inb(0x3DA); 6619a57b7d2SSøren Schmidt outb(0x3C0,0x11); outb(0x3C0, color); 6629a57b7d2SSøren Schmidt inb(0x3DA); 6639a57b7d2SSøren Schmidt outb(0x3C0, 0x20); 664e848f3d1SBruce Evans VGLBorderColor = color; 66580b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 66680b4b86eSBruce Evans ioctl(0, KDDISABIO, 0); 6679a57b7d2SSøren Schmidt } 6689a57b7d2SSøren Schmidt 6699a57b7d2SSøren Schmidt void 670e848f3d1SBruce Evans VGLRestoreBlank(void) 671e848f3d1SBruce Evans { 672e848f3d1SBruce Evans VGLBlankDisplay(VGLBlank); 673e848f3d1SBruce Evans } 674e848f3d1SBruce Evans 675e848f3d1SBruce Evans void 6769a57b7d2SSøren Schmidt VGLBlankDisplay(int blank) 6779a57b7d2SSøren Schmidt { 6789a57b7d2SSøren Schmidt byte val; 6799a57b7d2SSøren Schmidt 68080b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT && ioctl(0, KDENABIO, 0)) 68180b4b86eSBruce Evans return; 6829a57b7d2SSøren Schmidt VGLCheckSwitch(); 6839a57b7d2SSøren Schmidt outb(0x3C4, 0x01); val = inb(0x3C5); outb(0x3C4, 0x01); 6849a57b7d2SSøren Schmidt outb(0x3C5, ((blank) ? (val |= 0x20) : (val &= 0xDF))); 685e848f3d1SBruce Evans VGLBlank = blank; 68680b4b86eSBruce Evans if (VGLModeInfo.vi_mem_model == V_INFO_MM_DIRECT) 68780b4b86eSBruce Evans ioctl(0, KDDISABIO, 0); 6889a57b7d2SSøren Schmidt } 689