]> 4ch.mooo.com Git - 16.git/blobdiff - 16/lib/intro/lib.c
removed duplicates!! wwww
[16.git] / 16 / lib / intro / lib.c
old mode 100644 (file)
new mode 100755 (executable)
index 2ee3966..d0e7a83
@@ -1,3 +1,249 @@
+/*\r
+ * LIB.C v1.2a\r
+ *\r
+ * by Robert Schmidt\r
+ * (C)1993 Ztiff Zox Softwear\r
+ *\r
+ * Simple graphics library to accompany the article\r
+ * \r
+ *                                       INTRODUCTION TO MODE X.\r
+ * \r
+ * This library provides the basic functions for initializing and using\r
+ * unchained (planar) 256-color VGA modes.  Currently supported are:\r
+ *\r
+ *       - 320x200\r
+ *       - 320x240\r
+ *\r
+ * Functions are provided for:\r
+ *\r
+ *       - initializing one of the available modes\r
+ *       - setting the start address of the VGA refresh data\r
+ *       - setting active and visible display pages\r
+ *       - writing and reading a single pixel to/from video memory\r
+ *\r
+ * The library is provided as a demonstration only, and is not claimed\r
+ * to be particularly efficient or suited for any purpose.  It has only\r
+ * been tested with Borland C++ 3.1 by the author.  Comments on success\r
+ * or disaster with other compilers are welcome.\r
+ *\r
+ * This file is public domain.  Do with it whatever you'd like, but\r
+ * please don't distribute it without the article.\r
+ *\r
+ * Thanks go out to various helpful netters who spotted the 0xE7 bug\r
+ * in the set320x240x256() function!\r
+ *\r
+ * Modified by sparky4 so it can be compiled in open watcom ^^\r
+ */\r
+\r
+\r
+\r
+\r
+/*\r
+ * We 'require' a large data model simply to get rid of explicit 'far'\r
+ * pointers and compiler specific '_fmemset()' functions and the likes.\r
+ */\r
+#if !defined(__COMPACT__)\r
+# if !defined(__LARGE__)\r
+#  if !defined(__HUGE__)\r
+#   error Large data model required!  Try compiling with 'wcc -0 -ml lib.c'.\r
+#  endif\r
+# endif\r
+#endif\r
+\r
+#include <dos.h>\r
+#include <mem.h>\r
+#include <conio.h>\r
+\r
+//code from old library!\r
+/*src¥lib¥*/\r
+#include "dos_gfx.h"\r
+\r
+int old_mode;\r
+//color てすと\r
+int gq = LGQ;\r
+//てすと\r
+int q = 0;\r
+int bakax = 0, bakay = 0;\r
+cord xx = rand()&0%320, yy = rand()&0%240, sx = 0, sy = 0;\r
+byte coor;\r
+\r
+/*\r
+ * Comment out the following #define if you don't want the testing main()\r
+ * to be included.\r
+ */\r
+#define TESTING\r
+\r
+/*\r
+ * Define the port addresses of some VGA registers.\r
+ */\r
+#define CRTC_ADDR         0x3d4   /* Base port of the CRT Controller (color) */\r
+\r
+#define SEQU_ADDR         0x3c4   /* Base port of the Sequencer */\r
+#define GRAC_ADDR         0x3ce   /* Base port of the Graphics Controller */\r
+#define STATUS_ADDR     0x3DA\r
+\r
+\r
+/*\r
+ * Make a far pointer to the VGA graphics buffer segment.  Your compiler\r
+ * might not have the MK_FP macro, but you'll figure something out.\r
+ */\r
+byte *vga = (byte *) MK_FP(0xA000, 0);\r
+\r
+\r
+/*\r
+ * width and height should specify the mode dimensions.  widthBytes\r
+ * specify the width of a line in addressable bytes.\r
+ */\r
+unsigned width, height, widthBytes;\r
+\r
+/*\r
+ * actStart specifies the start of the page being accessed by\r
+ * drawing operations.  visStart specifies the contents of the Screen\r
+ * Start register, i.e. the start of the visible page.\r
+ */\r
+unsigned actStart, visStart;\r
+\r
+/*\r
+ * set320x200x256_X()\r
+ *       sets mode 13h, then turns it into an unchained (planar), 4-page\r
+ *       320x200x256 mode.\r
+ */\r
+void set320x200x256_X(void)\r
+               {\r
+               union REGS r;\r
+\r
+               /* Set VGA BIOS mode 13h: */\r
+               r.x.ax = 0x0013;\r
+               int86(0x10, &r, &r);\r
+\r
+               /* Turn off the Chain-4 bit (bit 3 at index 4, port 0x3c4): */\r
+               outpw(SEQU_ADDR, 0x0604);\r
+\r
+               /* Turn off word mode, by setting the Mode Control register\r
+               of the CRT Controller (index 0x17, port 0x3d4): */\r
+               outpw(CRTC_ADDR, 0xE317);\r
+\r
+               /* Turn off doubleword mode, by setting the Underline Location\r
+                  register (index 0x14, port 0x3d4): */\r
+               outpw(CRTC_ADDR, 0x0014);\r
+\r
+               /* Clear entire video memory, by selecting all four planes, then\r
+                  writing 0 to entire segment. */\r
+               outpw(SEQU_ADDR, 0x0F02);\r
+               memset(vga+1, 0, 0xffff); /* stupid size_t exactly 1 too small */\r
+               vga[0] = 0;\r
+\r
+               /* Update the global variables to reflect dimensions of this\r
+                  mode.  This is needed by most future drawing operations. */\r
+               width              = 320;\r
+               height  = 200;\r
+\r
+               /* Each byte addresses four pixels, so the width of a scan line\r
+                  in *bytes* is one fourth of the number of pixels on a line. */\r
+               widthBytes = width / 4;\r
+\r
+               /* By default we want screen refreshing and drawing operations\r
+                  to be based at offset 0 in the video segment. */\r
+               actStart = visStart = 0;\r
+\r
+               }\r
+\r
+/*\r
+ * setActiveStart() tells our graphics operations which address in video\r
+ * memory should be considered the top left corner.\r
+ */\r
+void setActiveStart(unsigned offset)\r
+               {\r
+               actStart = offset;\r
+               }\r
+\r
+/*\r
+ * setVisibleStart() tells the VGA from which byte to fetch the first\r
+ * pixel when starting refresh at the top of the screen.  This version\r
+ * won't look very well in time critical situations (games for\r
+ * instance) as the register outputs are not synchronized with the\r
+ * screen refresh.  This refresh might start when the high byte is\r
+ * set, but before the low byte is set, which produces a bad flicker.\r
+ */\r
+void setVisibleStart(unsigned offset)\r
+               {\r
+               visStart = offset;\r
+               outpw(CRTC_ADDR, 0x0C);          /* set high byte */\r
+               outpw(CRTC_ADDR+1, visStart >> 8);\r
+               outpw(CRTC_ADDR, 0x0D);          /* set low byte */\r
+               outpw(CRTC_ADDR+1, visStart & 0xff);\r
+               }\r
+\r
+/*\r
+ * setXXXPage() sets the specified page by multiplying the page number\r
+ * with the size of one page at the current resolution, then handing the\r
+ * resulting offset value over to the corresponding setXXXStart()\r
+ * function.  The first page is number 0.\r
+ */\r
+void setActivePage(int page)\r
+               {\r
+               setActiveStart(page * widthBytes * height);\r
+               }\r
+\r
+void setVisiblePage(int page)\r
+               {\r
+               setVisibleStart(page * widthBytes * height);\r
+               }\r
+\r
+void putPixel_X(int x, int y, byte color)\r
+               {\r
+               /* Each address accesses four neighboring pixels, so set\r
+                  Write Plane Enable according to which pixel we want\r
+                  to modify.  The plane is determined by the two least\r
+                  significant bits of the x-coordinate: */\r
+               outp(0x3c4, 0x02);\r
+               outp(0x3c5, 0x01 << (x & 3));\r
+\r
+               /* The offset of the pixel into the video segment is\r
+                  offset = (width * y + x) / 4, and write the given\r
+                  color to the plane we selected above.  Heed the active\r
+                  page start selection. */\r
+               vga[(unsigned)(widthBytes * y) + (x / 4) + actStart] = color;\r
+\r
+               }\r
+\r
+byte getPixel_X(int x, int y)\r
+               {\r
+               /* Select the plane from which we must read the pixel color: */\r
+               outpw(GRAC_ADDR, 0x04);\r
+               outpw(GRAC_ADDR+1, x & 3);\r
+\r
+               return vga[(unsigned)(widthBytes * y) + (x / 4) + actStart];\r
+\r
+               }\r
+\r
+void set320x240x256_X(void)\r
+               {\r
+               /* Set the unchained version of mode 13h: */\r
+               set320x200x256_X();\r
+\r
+               /* Modify the vertical sync polarity bits in the Misc. Output\r
+                  Register to achieve square aspect ratio: */\r
+               outp(0x3C2, 0xE3);\r
+\r
+               /* Modify the vertical timing registers to reflect the increased\r
+                  vertical resolution, and to center the image as good as\r
+                  possible: */\r
+               outpw(0x3D4, 0x2C11);              /* turn off write protect */\r
+               outpw(0x3D4, 0x0D06);              /* vertical total */\r
+               outpw(0x3D4, 0x3E07);              /* overflow register */\r
+               outpw(0x3D4, 0xEA10);              /* vertical retrace start */\r
+               outpw(0x3D4, 0xAC11);              /* vertical retrace end AND wr.prot */\r
+               outpw(0x3D4, 0xDF12);              /* vertical display enable end */\r
+               outpw(0x3D4, 0xE715);              /* start vertical blanking */\r
+               outpw(0x3D4, 0x0616);              /* end vertical blanking */\r
+\r
+               /* Update mode info, so future operations are aware of the\r
+                  resolution */\r
+               height = 240;\r
+\r
+               }
+
 /*\r
  * The library testing routines follows below.\r
  */\r
@@ -14,9 +260,6 @@ void doTest(void)
 \r
                /* This is the way to calculate the number of pages available. */\r
                pages = 65536L/(widthBytes*height); // apparently this takes the A000 address\r
-//             if(height==240) pages++;\r
-\r
-//             printf("%d¥n", pages);\r
 \r
                for (p = 0; p <= pages; ++p)\r
                                {\r
@@ -28,22 +271,21 @@ void doTest(void)
                                   //{\r
                                                for (x = 0; x <= width; ++x)\r
                                                                {\r
-//                                                             putPixel_X(x, 0, p+1);\r
-                                                               mxPutPixel(x, 0, p+1);\r
-                                                               if(p!=pages) mxPutPixel(x, height-1, p+1);\r
-                                                                               else if(height==240) mxPutPixel(x, 99-1, p+1);\r
+                                                               putPixel_X(x, 0, p+1);\r
+                                                               if(p!=pages) putPixel_X(x, height-1, p+1);\r
+                                                                               else if(height==240) putPixel_X(x, 99-1, p+1);\r
                                                                }\r
 \r
                                                for (y = 0; y <= height; ++y)\r
                                                                {\r
-                                                               mxPutPixel(0, y, p+1);\r
-                                                               if(p!=pages) mxPutPixel(width-1, y, p+1);\r
-                                                                               else if(height==240) mxPutPixel(width-1, y, p+1);\r
+                                                               putPixel_X(0, y, p+1);\r
+                                                               if(p!=pages) putPixel_X(width-1, y, p+1);\r
+                                                                               else if(height==240) putPixel_X(width-1, y, p+1);\r
                                                                }\r
 \r
                                                for (x = 0; x < TILEWH; ++x)\r
                                                                for (y = 0; y < TILEWH; ++y)\r
-                                                                               mxPutPixel(x+(p+2)*16, y+(p+2)*TILEWH, x + y*TILEWH);\r
+                                                                               putPixel_X(x+(p+2)*16, y+(p+2)*TILEWH, x + y*TILEWH);\r
                                                //}\r
 \r
                                }\r
@@ -64,15 +306,11 @@ void doTest(void)
 \r
 int main(void)\r
                {\r
-               int key,d,xpos,ypos,xdir,ydir;\r
+               int key,d;\r
                //short int temp;\r
                // main variables\r
                d=1; // switch variable\r
                key=4; // default screensaver number\r
-               xpos=0;\r
-               ypos=0;
-               xdir=1;\r
-               ydir=1;\r
 //       puts("First, have a look at the 320x200 mode.  I will draw some rubbish");\r
 //       puts("on all of the four pages, then let you cycle through them by");\r
 //       puts("hitting a key on each page.");\r
@@ -85,7 +323,6 @@ int main(void)
 //       puts("Press a key when ready...");\r
 //       getch();\r
 \r
-//++++0000\r
                setvideo(1);\r
 // screen savers\r
 \r
@@ -106,33 +343,9 @@ int main(void)
                        ding(key);\r
                }\r
                //end of screen savers\r
-               //doTest();\r
-               for (int x = 0; x < width; ++x)\r
-                       {\r
-                               mxPutPixel(x, 0, 15);\r
-                               mxPutPixel(x, height-1, 15);\r
-                       }\r
-               for (int y = 0; y < height; ++y)\r
-                       {\r
-                               mxPutPixel(0, y, 15);\r
-                               mxPutPixel(width-1, y, 15);\r
-                       }\r
-               getch();\r
+               doTest();\r
                while(!kbhit()){\r
-//                     hScroll(1);\r
-//                     scrolly(1);\r
-//                     vScroll(1);\r
-//                     delay(100);\r
-                       //for(int i=0;i<TILEWH;i++){\r
-                               ding(key);\r
-                               mxPan(xpos,ypos);\r
-                               mxWaitRetrace();\r
-                               xpos=xpos+xdir;\r
-                               ypos=ypos+ydir;\r
-                               if( (xpos>239)  || (xpos<1))xdir=-xdir;\r
-                               if( (ypos>179) || (ypos<1))ydir=-ydir; // { Hit a boundry, change\r
-                       //    direction! }\r
-                       //}\r
+\r
                }\r
                setvideo(0);\r
                printf("wwww¥n%dx%d¥n", width,height);\r