]> 4ch.mooo.com Git - 16.git/blobdiff - 16/w_modex/XPRIM.CPP
modified: 16/DOS_GFX.EXE
[16.git] / 16 / w_modex / XPRIM.CPP
diff --git a/16/w_modex/XPRIM.CPP b/16/w_modex/XPRIM.CPP
new file mode 100644 (file)
index 0000000..66e2f72
--- /dev/null
@@ -0,0 +1,561 @@
+#include <conio.h>\r
+#include <dos.h>\r
+#include <mem.h>\r
+#include <stdio.h>\r
+\r
+#include "modex.hpp"\r
+#include "xprim.hpp"\r
+\r
+#define SEQU_ADDR       0x3C4\r
+#define GRACON_ADDR     0x3CE\r
+#define CRTC_ADDR       0x3D4\r
+#define STATUS_ADDR     0x3DA\r
+\r
+BYTE Xfont[2048];\r
+\r
+\r
+void\r
+wait_for_retrace(void)\r
+{\r
+    while (!(inp(STATUS_ADDR) & 0x08));\r
+}\r
+\r
+\r
+void\r
+setDrawPage(unsigned int page)\r
+{\r
+    activeStart = page_offset[page];\r
+}\r
+\r
+\r
+void\r
+setVisiblePage(unsigned int page)\r
+{\r
+    // setVisibleStart() tells the VGA from which byte to fetch the first\r
+    // pixel when starting refresh at the top of the screen.\r
+    visibleStart = page_offset[page];\r
+\r
+    // set high byte\r
+    outpw(CRTC_ADDR, page_mask_high[page]);\r
+\r
+    // set low byte\r
+    outpw(CRTC_ADDR, page_mask_low[page]);\r
+}\r
+\r
+\r
+void\r
+clearX(BYTE color)\r
+{\r
+    outpw(SEQU_ADDR, 0x0F02);\r
+    memset((unsigned char *)(0xA000 << 4) + activeStart, color, 0x00010000);\r
+}\r
+\r
+\r
+void\r
+putpixelX(COORD x, COORD y, BYTE color)\r
+{\r
+    BYTE temp;\r
+\r
+    if (write_plane != (temp = (x & 3))) {\r
+        write_plane = temp;\r
+        outpw(SEQU_ADDR, plane_mask[temp]);\r
+    }\r
+\r
+    *(RowsX[y] + (x >> 2) + activeStart) = color;\r
+}\r
+\r
+\r
+BYTE\r
+getpixelX(COORD x, COORD y)\r
+{\r
+    BYTE temp;\r
+\r
+    if (read_plane != (temp = (x & 3))) {\r
+        read_plane = temp;\r
+        outpw(GRACON_ADDR, read_mask[temp]);\r
+    }\r
+\r
+    return (*(RowsX[y] + (x >> 2) + activeStart));\r
+}\r
+\r
+\r
+void\r
+internal_vert_lineX(COORD x, COORD top_y, int len, BYTE color)\r
+{\r
+    BYTE *ptr;\r
+    BYTE temp;\r
+\r
+    if (write_plane != (temp = (x & 3))) {\r
+        write_plane = temp;\r
+        outpw(SEQU_ADDR, plane_mask[temp]);\r
+    }\r
+\r
+    ptr = RowsX[top_y] + (x >> 2) + activeStart;\r
+\r
+    while (len--) {\r
+        *ptr = color;\r
+        ptr += widthBytes;\r
+    }\r
+}\r
+\r
+\r
+void\r
+internal_horiz_lineX(COORD left_x, COORD y, int len, BYTE color)\r
+{\r
+    BYTE *ptr;\r
+    BYTE temp;\r
+\r
+    ptr = RowsX[y] + (left_x >> 2) + activeStart;\r
+\r
+    // Set current plane to invalid value\r
+    write_plane = -1;\r
+\r
+    if (temp = (left_x & 3)) {\r
+        outp(SEQU_ADDR, 0x02);\r
+        outp(0x3C5, line_head[temp]);\r
+        *ptr++ = color;\r
+        len -= (4 - temp);\r
+    }\r
+\r
+    if (temp = (len >> 2)) {\r
+        outpw(SEQU_ADDR, 0x0F02);\r
+\r
+        len &= 3;\r
+\r
+        memset(ptr, color, temp);\r
+        ptr += temp;\r
+    }\r
+\r
+    if (len) {\r
+        outp(SEQU_ADDR, 0x02);\r
+        outp(0x3C5, line_tail[len]);\r
+        *ptr = color;\r
+    }\r
+}\r
+\r
+\r
+void\r
+boxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
+{\r
+    int xsize, ysize;\r
+\r
+    xsize = (x2 - x1) + 1;\r
+    internal_horiz_lineX(x1, y1, xsize, color);\r
+    internal_horiz_lineX(x1, y2, xsize, color);\r
+\r
+    y1++;\r
+    ysize = (y2 - y1);\r
+\r
+    internal_vert_lineX(x1, y1, ysize, color);\r
+    internal_vert_lineX(x2, y1, ysize, color);\r
+}\r
+\r
+\r
+void\r
+filledboxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
+{\r
+    BYTE *base_ptr;\r
+    BYTE *ptr;\r
+    BYTE temp;\r
+    short int i, xsize, ysize;\r
+\r
+    // Set current plane to invalid value\r
+    write_plane = -1;\r
+\r
+    xsize = (x2 - x1) + 1;\r
+    ysize = (y2 - y1) + 1;\r
+\r
+    if (ysize == 1) {\r
+        internal_horiz_lineX(x1, y1, xsize, color);\r
+        return;\r
+    }\r
+\r
+    base_ptr = RowsX[y1] + (x1 >> 2) + activeStart;\r
+\r
+    if (temp = (x1 & 3)) {\r
+        outp(SEQU_ADDR, 0x02);\r
+        outp(0x3C5, line_head[temp]);\r
+        ptr = base_ptr;\r
+        i=ysize;\r
+        while (i--) {\r
+            *ptr = color;\r
+            ptr += widthBytes;\r
+        }\r
+        xsize -= (4 - temp);\r
+        base_ptr++;\r
+    }\r
+\r
+    if (temp = (xsize >> 2)) {\r
+        outpw(SEQU_ADDR, 0x0F02);\r
+\r
+        xsize &= 3;\r
+        ptr = base_ptr;\r
+        i=ysize;\r
+        while (i--) {\r
+            memset(ptr, color, temp);\r
+            ptr += widthBytes;\r
+        }\r
+        base_ptr += temp;\r
+    }\r
+\r
+    if (xsize) {\r
+        outp(SEQU_ADDR, 0x02);\r
+        outp(0x3C5, line_tail[xsize]);\r
+        while (ysize--) {\r
+            *base_ptr = color;\r
+            base_ptr += widthBytes;\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void\r
+circleX(COORD x, COORD y, DIST r, BYTE color)\r
+{\r
+    int ix, iy, d, deltaE, deltaSE;\r
+\r
+    ix = 0;\r
+    iy = r;\r
+    d = 1 - r;\r
+    deltaE = 3;\r
+    deltaSE = (-2 * r) + 5;\r
+\r
+    putpixelX(x + ix, y + iy, color);\r
+    putpixelX(x + ix, y - iy, color);\r
+    putpixelX(x + iy, y + ix, color);\r
+    putpixelX(x + iy, y - ix, color);\r
+    putpixelX(x - ix, y + iy, color);\r
+    putpixelX(x - ix, y - iy, color);\r
+    putpixelX(x - iy, y + ix, color);\r
+    putpixelX(x - iy, y - ix, color);\r
+\r
+    while (iy > ix++) {\r
+        if (d < 0) {\r
+            d += deltaE;\r
+            deltaE += 2;\r
+            deltaSE += 2;\r
+        } else {\r
+            d += deltaSE;\r
+            deltaE += 2;\r
+            deltaSE += 4;\r
+            iy--;\r
+        }\r
+\r
+        putpixelX(x + ix, y + iy, color);\r
+        putpixelX(x + ix, y - iy, color);\r
+        putpixelX(x + iy, y + ix, color);\r
+        putpixelX(x + iy, y - ix, color);\r
+        putpixelX(x - ix, y + iy, color);\r
+        putpixelX(x - ix, y - iy, color);\r
+        putpixelX(x - iy, y + ix, color);\r
+        putpixelX(x - iy, y - ix, color);\r
+    }\r
+}\r
+\r
+\r
+void\r
+filledcircleX(COORD x, COORD y, DIST r, BYTE color)\r
+{\r
+    int ix, iy, d, deltaE, deltaSE;\r
+\r
+    ix = 0;\r
+    iy = r;\r
+    d = 1 - r;\r
+    deltaE = 3;\r
+    deltaSE = (-2 * r) + 5;\r
+\r
+    internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color);\r
+    internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color);\r
+    internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color);\r
+    internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color);\r
+\r
+    while (iy > ix++) {\r
+        if (d < 0) {\r
+            d += deltaE;\r
+            deltaE += 2;\r
+            deltaSE += 2;\r
+        } else {\r
+            d += deltaSE;\r
+            deltaE += 2;\r
+            deltaSE += 4;\r
+            iy--;\r
+        }\r
+\r
+        internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color);\r
+        internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color);\r
+        internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color);\r
+        internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color);\r
+    }\r
+}\r
+\r
+\r
+void\r
+internal_xmajor(BYTE *vga_ptr, short int len, short int yskip,\r
+    unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
+{\r
+    if (len) {\r
+        len--;\r
+        while (len--) {\r
+            *vga_ptr++ = color;\r
+            ErrorAcc += ErrorAdj;\r
+\r
+            if (ErrorAcc & ~0xFFFFL) {\r
+                ErrorAcc &= 0xFFFFL;\r
+                vga_ptr += yskip;\r
+            }\r
+        }\r
+        *vga_ptr = color;\r
+    }\r
+}\r
+\r
+\r
+void\r
+internal_middle(BYTE *vga_ptr, short int len, short int yskip,\r
+    unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
+{\r
+    if (len) {\r
+        len--;\r
+        while (len--) {\r
+            *vga_ptr++ = color;\r
+            ErrorAcc += ErrorAdj;\r
+            vga_ptr += (yskip * (ErrorAcc >> 16));\r
+            ErrorAcc &= 0xFFFFL;\r
+        }\r
+        *vga_ptr = color;\r
+    }\r
+}\r
+\r
+\r
+void\r
+internal_ymajor(BYTE *vga_ptr, short int len, short int yskip,\r
+    unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
+{\r
+    unsigned long TinyAdj;\r
+    short int i;\r
+\r
+    if (len) {\r
+        TinyAdj = (ErrorAdj >> 2);\r
+        ErrorAdj -= TinyAdj;\r
+\r
+        len--;\r
+        while (len--) {\r
+            ErrorAcc += TinyAdj;\r
+            i = (ErrorAcc >> 16);\r
+            ErrorAcc &= 0xFFFFL;\r
+\r
+            while (i--) {\r
+                *vga_ptr = color;\r
+                vga_ptr += yskip;\r
+            }\r
+\r
+            ErrorAcc += ErrorAdj;\r
+            vga_ptr += (yskip * (ErrorAcc >> 16)) + 1;\r
+            ErrorAcc &= 0xFFFFL;\r
+        }\r
+        ErrorAcc += TinyAdj;\r
+        i = (ErrorAcc >> 16);\r
+        while (i--) {\r
+            *vga_ptr = color;\r
+            vga_ptr += yskip;\r
+        }\r
+    }\r
+}\r
+\r
+\r
+void\r
+lineX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
+{\r
+    unsigned long ErrorAcc, ErrorAdj, TinyAdj;\r
+    short int i, DeltaX, DeltaY, yskip;\r
+    short int len[4];\r
+    BYTE *vga_ptr;\r
+    COORD temp;\r
+\r
+    // Mode X 4-way folded Bresenham line function - by David Boeren\r
+\r
+    // Set invalid plane, because we're screwing with the plane mask\r
+    write_plane = -1;\r
+\r
+    // Make sure the line runs left to right\r
+    if (x1 > x2) {\r
+        temp = x1; x1 = x2; x2 = temp;\r
+        temp = y1; y1 = y2; y2 = temp;\r
+    }\r
+\r
+    DeltaX = (x2 - x1);\r
+    DeltaY = (y2 - y1);\r
+\r
+    if (DeltaY >= 0) {\r
+        yskip = widthBytes;\r
+    } else {\r
+        DeltaY = -DeltaY;  // Make DeltaY positive\r
+        yskip = -widthBytes;\r
+    }\r
+\r
+    if (DeltaX == 0) {\r
+        // Vertical Line (and one pixel lines)\r
+        if (yskip > 0) {\r
+            internal_vert_lineX(x1, y1, (DeltaY + 1), color);\r
+        } else {\r
+            internal_vert_lineX(x1, y2, (DeltaY + 1), color);\r
+        }\r
+        return;\r
+    }\r
+\r
+    if (DeltaY == 0) {\r
+        // Horizontal Line\r
+        internal_horiz_lineX(x1, y1, (DeltaX + 1), color);\r
+        return;\r
+    }\r
+\r
+    vga_ptr = RowsX[y1] + (x1 >> 2) + activeStart;\r
+    ErrorAcc = 0x8000;\r
+\r
+    // Length of sub-line in each plane\r
+    temp = (x1 & 3);\r
+    i = DeltaX + temp;\r
+    len[0] = ((i--) >> 2);\r
+    len[1] = ((i--) >> 2);\r
+    len[2] = ((i--) >> 2);\r
+    len[3] = (i >> 2) + 1;\r
+\r
+    for (i=temp; i < 3; i++) {\r
+        len[i]++;\r
+    }\r
+\r
+    if ((DeltaX >> 2) >= DeltaY) {\r
+        // X-Major line (0.00 < slope <= 0.25)\r
+        ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));\r
+        TinyAdj = (ErrorAdj >> 2);\r
+        while (i--) {\r
+            outpw(SEQU_ADDR, plane_mask[temp]);\r
+            internal_xmajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
+            if (temp == 4) {\r
+                temp = 0;\r
+                vga_ptr++;\r
+            }\r
+            ErrorAcc += TinyAdj;\r
+            if (ErrorAcc & ~0xFFFFL) {\r
+                ErrorAcc &= 0xFFFFL;\r
+                vga_ptr += yskip;\r
+            }\r
+        }\r
+        outpw(SEQU_ADDR, plane_mask[temp]);\r
+        internal_xmajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
+    } else if (DeltaX >= DeltaY) {\r
+        // Middle line (0.25 < slope <= 1.00)\r
+        ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));\r
+        TinyAdj = (ErrorAdj >> 2);\r
+        while (i--) {\r
+            outpw(SEQU_ADDR, plane_mask[temp]);\r
+            internal_middle(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
+            if (temp == 4) {\r
+                temp = 0;\r
+                vga_ptr++;\r
+            }\r
+            ErrorAcc += TinyAdj;\r
+            if (ErrorAcc & ~0xFFFFL) {\r
+                vga_ptr += yskip;\r
+                ErrorAcc &= 0xFFFFL;\r
+            }\r
+        }\r
+        outpw(SEQU_ADDR, plane_mask[temp]);\r
+        internal_middle(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
+    } else {\r
+        // Y-Major line (slope > 1)\r
+        ErrorAdj = ((((unsigned long)(DeltaY+1) << 18) /\r
+                      (unsigned long)(DeltaX+1)));\r
+        TinyAdj = (ErrorAdj >> 2);\r
+        while (i--) {\r
+            outpw(SEQU_ADDR, plane_mask[temp]);\r
+            internal_ymajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
+            if (temp == 4) {\r
+                temp = 0;\r
+                vga_ptr++;\r
+            }\r
+            ErrorAcc += TinyAdj;\r
+            vga_ptr += (yskip * (ErrorAcc >> 16));\r
+            ErrorAcc &= 0xFFFFL;\r
+        }\r
+        outpw(SEQU_ADDR, plane_mask[temp]);\r
+        internal_ymajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
+    }\r
+}\r
+\r
+\r
+int\r
+loadfontX(char *fname)\r
+{\r
+    FILE *fp;\r
+\r
+    fp = fopen(fname, "rb");\r
+\r
+    if (fp == NULL) {\r
+        return 0;\r
+    } else {\r
+        fread(Xfont, 8, 256, fp);\r
+        fclose(fp);\r
+        return 1;\r
+    }\r
+}\r
+\r
+\r
+void\r
+putchX(COORD x, COORD y, char c, BYTE color)\r
+{\r
+    int i;\r
+    BYTE *vga_ptr;\r
+    BYTE *font_ptr;\r
+    BYTE temp;\r
+\r
+    // 8x8 font\r
+    vga_ptr = RowsX[y << 3] + (x << 1) + activeStart;\r
+    write_plane = -1;\r
+\r
+    font_ptr = Xfont + (c << 3);\r
+\r
+    i=8;\r
+    while (i--) {\r
+        temp = *font_ptr++;\r
+        outpw(SEQU_ADDR, text_mask[temp & 0x0F]);\r
+        *vga_ptr++ = color;\r
+\r
+        outpw(SEQU_ADDR, text_mask[temp >> 4]);\r
+        *vga_ptr-- = color;\r
+        vga_ptr += widthBytes;\r
+    }\r
+}\r
+\r
+\r
+void\r
+putstringX(COORD x, COORD y, char *str, BYTE color)\r
+{\r
+    int i, skip;\r
+    BYTE *vga_ptr;\r
+    BYTE *font_ptr;\r
+    BYTE c, temp;\r
+\r
+    // 8x8 font\r
+    vga_ptr = RowsX[y << 3] + (x << 1) + activeStart;\r
+    write_plane = -1;\r
+\r
+    skip = 2 - (widthBytes << 3);\r
+\r
+    while (c = *str++) {\r
+        font_ptr = Xfont + (c << 3);\r
+\r
+        i=8;\r
+        while (i--) {\r
+            temp = *font_ptr++;\r
+            outpw(SEQU_ADDR, text_mask[temp & 0x0F]);\r
+            *vga_ptr++ = color;\r
+\r
+            outpw(SEQU_ADDR, text_mask[temp >> 4]);\r
+            *vga_ptr-- = color;\r
+            vga_ptr += widthBytes;\r
+        }\r
+\r
+        vga_ptr += skip;\r
+    }\r
+}\r
+\r