]> 4ch.mooo.com Git - 16.git/blobdiff - 16/dos_gfx.cpp
modified: 16/DOS_GFX.EXE
[16.git] / 16 / dos_gfx.cpp
index e5e4c6ed237822777572bfde8f84b8acc5bc3616..360137edaa436ca905a306b68281dec220c0bee3 100644 (file)
@@ -32,7 +32,7 @@
  * 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
+ * Modified by sparky4 so it can be compiled in open watcom ^^\r
  */\r
 \r
 \r
@@ -45,7 +45,7 @@
 #if !defined(__COMPACT__)\r
 # if !defined(__LARGE__)\r
 #  if !defined(__HUGE__)\r
-#   error Large data model required!  Try compiling with 'bcc -ml lib.c'.\r
+#   error Large data model required!  Try compiling with 'wcc -0 -ml lib.c'.\r
 #  endif\r
 # endif\r
 #endif\r
@@ -57,6 +57,7 @@
 //code from old library!\r
 /*src\lib\*/\r
 #include "dos_gfx.h"\r
+#include "lib\x\modex.h"\r
 \r
 int old_mode;\r
 //color \82Ä\82·\82Æ\r
@@ -144,7 +145,49 @@ void set320x200x256_X(void)
 \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
+               actStart = visStart = 0;
+
+               /*
+--------------------
+HORIZONTAL SCROLLING
+--------------------
+Horizontal scrolling is essentially the same as vertical scrolling, all
+you do is increment or decrement the VGA offset register by 1 instead of
+80 as with vertical scrolling.
+
+However, horizontal scrolling is complicated by two things
+
+  1. Incrementing the offset register by one actually scrolls by FOUR
+     pixels (and there are FOUR planes on the VGA, what a coincidence)
+
+  2. You can't draw the image off the screen and then scroll it on
+     because of the way the VGA wraps to the next row every 80 bytes
+     (80 bytes * 4 planes = 320 pixels), if you tried it, you would
+     actually be drawing to the other side of the screen (which is
+     entirely visible)
+
+I'll solve these problems one at a time.
+
+Firstly, to get the VGA to scroll by only one pixel you use the horizontal
+pixel panning (HPP) register. This register resides at
+
+  PORT:     3C0H
+  INDEX:    13h
+
+and in real life, you use it like this
+
+----------------- Pixel Panning ---------------
+IN PORT 3DAH (this clears an internal
+  flip-flop of the VGA)
+OUT 13H TO PORT 3C0H
+OUT value TO PORT 3C0H (where "value" is the
+  number of pixels to offset)
+-----------------------------------------------
+*/
+               inp(0x3DA)
+               outpw(0x3C0, 0x13);
+               outpw(0x3C0, 0x58);
+\r
                }\r
 \r
 /*\r
@@ -235,8 +278,8 @@ void set320x240x256_X(void)
                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
+               outpw(0x3D4, 0x0616);              /* end vertical blanking */
+
                /* Update mode info, so future operations are aware of the\r
                   resolution */\r
                height = 240;\r
@@ -244,79 +287,148 @@ void set320x240x256_X(void)
                }\r
 \r
 \r
+/*-----------XXXX-------------*/\r
 /*tile*/\r
-// This is Bresenham's Line Drawing Algorithm\r
-void drawline(int x1, int y1, int x2, int y2, char col)\r
-{\r
-               int d, x, y, ax, ay, sx, sy, dx, dy;\r
-\r
-               dx = x2-x1;\r
-               ax = ABS(dx) << 1;\r
-               sx = SGN(dx);\r
-               dy = y2-y1;\r
-               ay = ABS(dy) << 1;\r
-               sy = SGN(dy);\r
-\r
-               x = x1;\r
-               y = y1;\r
-               if( ax > ay )\r
-               {\r
-                               d = ay - (ax >> 1);\r
-                               while( x != x2 )\r
-                               {\r
-                                               putPixel_X( x, y, col );\r
-                                               if( d >= 0 )\r
-                                               {\r
-                                                               y += sy;\r
-                                                               d -= ax;\r
-                                               }\r
-                               x += sx;\r
-                               d += ay;\r
-                               }\r
-               }\r
-               else\r
-               {\r
-                               d = ax - (ay >> 1);\r
-                               while( y != y2 )\r
-                               {\r
-                                               putPixel_X( x, y, col );\r
-                                               if( d >= 0 )\r
-                                               {\r
-                                                               x += sx;\r
-                                                               d -= ay;\r
-                                               }\r
-                                               y += sy;\r
-                                               d += ax;\r
-                               }\r
+void putColorBox_X(int x, int y, int w, int h, byte color) {\r
+       outp(0x3c4, 0x02);\r
+\r
+       int curx, cury;\r
+       unsigned drawptr;\r
+       for (curx=x; curx<(x+w); curx++) {\r
+               outp(0x3c5, 0x01 << (curx & 3));\r
+               drawptr = (unsigned)(widthBytes * y) + (curx / 4) + actStart;\r
+               for (cury=0; cury<h; cury++) {\r
+                       vga[drawptr] = color;\r
+                       drawptr += widthBytes;\r
                }\r
-               return;\r
+       }\r
 }\r
 \r
-void drawrect(int x1, int y1, int x2, int y2, char color)\r
+void vScroll(int rows)\r
 {\r
-       drawline(x1,y1,x2,y1,color);\r
-       drawline(x1,y2,x2,y2,color);\r
-       drawline(x1,y1,x1,y2,color);\r
-       drawline(x2,y1,x2,y2+1,color);
-       /*byte far *p;
-       
-       p=vga+y1*width+x1;  // make p point to the start of the line
-       while((y2-y1))                  // repeat for entire line height
-               {
-               _fmemset(vga, color, x2-x1);    // set one line
-               p+=width;               // move down one row
-               }*/\r
+       // Scrolling = current start + (rows * bytes in a row)\r
+       setVisibleStart(visStart + (rows * width));\r
 }\r
-\r
-\r
-/*-----------XXXX-------------*/\r
+
+void scrolly(int bong)\r
+{
+       int boing=0;\r
+       if(bong<0)
+               boing=-1;
+       else if(bong>0)
+               boing=1;
+       else break;
+\r
+       for(int i=0;i<TILEWH;i++)
+               vScroll(boing)
+}
+\r
+/*
+\r
+
+To implement smooth horizontal scrolling, you would do the following:
+
+-------------- Horizontal Scrolling ------------
+FOR X = 0 TO 319 DO
+  SET HPP TO ( X MOD 4 )
+  SET VGA OFFSET TO ( X/4 )
+END FOR
+------------------------------------------------
+
+Okay, no problem at all (although I think you might have to fiddle
+around with the HPP a bit to get it right...try different values and
+see what works :).
+
+So, the next problem is with drawing the images off the screen where
+they aren't visible and then scrolling them on!!! As it turns out,
+there's yet ANOTHER register to accomplish this. This one's called the
+offset register (no, not the one I was talking about before, that one
+was actually the "start address" register) and it's at
+
+  PORT:     3D4H/3D5H
+  OFFSET:   13H
+
+and here's how to use it
+
+-------------- Offset Register ---------------
+OUT 13H TO PORT 3D4H
+OUT value TO PORT 3D5H
+----------------------------------------------
+
+Now, what my VGA reference says is that this register holds the number
+of bytes (not pixels) difference between the start address of each row.
+So, in X-mode it normally contains the value 80 (as we remember,
+80 bytes * 4 planes = 320 pixels). This register does not affect the
+VISIBLE width of the display, only the difference between addresses on
+each row.
+
+When we scroll horizontally, we need a little bit of extra working space
+so we can draw off the edge of the screen.
+
+Perhaps a little diagram will clarify it. The following picture is of a
+standard X-mode addressing scheme with the OFFSET register set to 80.
+
+      ROW    OFFSET
+      0         0 ========================
+      1        80 [                      ]
+      2       160 [                      ]
+      ..       .. [       VISIBLE        ]
+                  [        SCREEN        ]
+                  [                      ]
+                  [                      ]
+      ..       .. [                      ]
+      199   15920 ========================
+
+and the next diagram is of a modified addressing scheme with the OFFSET
+register set to 82 (to give us 4 extra pixels on each side of the screen)
+
+ROW    OFFSET
+0         0 ------========================------
+1        82 |   V [                      ]   V |
+2       164 |   I [                      ]   I |
+..       .. | N S [      VISIBLE         ] N S |
+            | O I [       SCREEN         ] O I |
+            | T B [                      ] T B |
+            |   L [                      ]   L |
+..       .. |   E [                      ]   E |
+199   16318 ------========================------
+
+Beautiful!!!
+
+As with vertical scrolling, however, you still have the problem of when
+you reach the bottom of page 4...and it's fixed in the same manner.
+
+I haven't actually managed to get infinite horizontal scrolling working,
+but the method I have just stated will give you a horizontal scrolling
+range of over 200 screens!!!! So if you need more (which is extremely
+unlikely), figure it out yourself.
+
+
+------------------
+COMBINED SCROLLING
+------------------
+To do both horizontal and vertical scrolling, all you have to do is combine
+the two methods with a few little extras (it's always the way isn't it).
+
+You have to start off with the original screen on the current page and the
+next page as well. When you scroll horizontally, you have to draw the edge
+that's coming in to the screen to BOTH pages (that means you'll be drawing
+the incoming edge twice, once for each page). You do this so that when you
+have scrolled vertically down through a complete page, you can jump back
+to the first page and it will (hopefully) have an identical copy, and you
+can then continue scrolling again.
+
+I'm sorry about this being so confusing but it's a bit difficult to explain.
+
+\r
+*/\r
 //---------------------------------------------------\r
 //\r
 // Use the bios to get the address of the 8x8 font\r
 //\r
 // You need a font if you are going to draw text.\r
 //\r
-\r
+/*\r
 int far *\r
 getFont()\r
 {\r
@@ -366,11 +478,11 @@ void drawText(int x, int y, int color, byte string)
                                string++;\r
                }\r
 }\r
-\r
+*/\r
 /////////////////////////////////////////////////////////////////////////////\r
-//                                                                                                                                              //\r
+//                                                                         //\r
 // setvideo() - This function Manages the video modes                                    //\r
-//                                                                                                                                              //\r
+//                                                                         //\r
 /////////////////////////////////////////////////////////////////////////////\r
 void setvideo(/*byte mode, */int vq){\r
                union REGS in, out;\r
@@ -399,7 +511,7 @@ void setvideo(/*byte mode, */int vq){
 //                                                                                                                                              //\r
 /////////////////////////////////////////////////////////////////////////////\r
 void cls(byte color, byte *Where){\r
-               _fmemset(Where, color, width*(height*17));
+               _fmemset(Where, color, width*(height*17));\r
 }\r
 \r
 //color \82Ä\82·\82Æ\r
@@ -441,8 +553,19 @@ void ssd(int svq){
 \r
 /*-----------ding-------------*/\r
 int ding(int q){\r
+\r
+       if(yy<height){\r
                setActivePage(0);\r
                setVisiblePage(0);\r
+       }\r
+       if((height)<yy<(height*2)){\r
+               setActivePage(1);\r
+               setVisiblePage(1);\r
+       }\r
+       if((height*2)<yy<(height*3)){\r
+               setActivePage(2);\r
+               setVisiblePage(2);\r
+       }\r
                int d3y;\r
 \r
 //++++  if(q <= 4 && q!=2 && gq == BONK-1) coor = rand()%HGQ;\r
@@ -451,17 +574,17 @@ int ding(int q){
                ||q==16\r
                ) && gq == BONK-1){\r
                                                if(coor < HGQ && coor < LGQ) coor = LGQ;\r
-                                               if(coor < HGQ-1){\r
+                                               if(coor < HGQ){\r
                                                                coor++;\r
                                }else{ coor = LGQ;\r
                                                bakax = rand()%3; bakay = rand()%3;\r
                                }\r
                }\r
 \r
-               if(q == 5){ colortest(); return gq; }\r
-               if(q == 10){ colorz(); return gq; }\r
+               if(q == 8){ colorz(); return gq; }else\r
+               if(q == 10){ ssd(q); /*printf("%d\n", coor);*/ }else\r
+               if(q == 5){ colortest(); return gq; }else\r
                if(q == 11){ colorz(); delay(100); return gq; }\r
-               if(q == 8){ ssd(q); /*printf("%d\n", coor);*/ }\r
                if(q == 6){\r
                                coor = rand()%NUM_COLORS;\r
 //----           cls(coor, vaddr);\r
@@ -534,12 +657,13 @@ int ding(int q){
                                                }\r
                                }\r
                                // fixer\r
-                               if(q!=16){\r
+//                             if(q!=16){\r
+//if(q!=16)\r
                                                if(xx<0) xx=width;\r
-                                               if(yy<0) yy=height;\r
+                                               if(yy<0) yy=(height*3);\r
                                                if(xx>width) xx=0;\r
-                                               if(yy>height) yy=0;\r
-                               }\r
+                                               if(yy>(height*3)) yy=0;\r
+//                             }\r
 \r
 //interesting effects\r
                                if(q==16)\r
@@ -553,10 +677,14 @@ int ding(int q){
 \r
                                // plot the pixel\r
 //----           ppf(xx, yy, coor, vga);\r
-//++++0000                       putPixel_X(xx, yy, coor);\r
-                               }else drawrect(xx, yy, xx+TILEWH-1, yy+TILEWH-1, coor);\r
+                               }else /*if(xx>=0 && xx<width && yy>=0 && yy<(height*3))*/{\r
+                                       putColorBox_X(xx, yy, TILEWH, TILEWH, coor);\r
+//++++0000                                     putPixel_X(xx, yy, coor);\r
+                               } \r
+\r
 //----           if(q==2) ppf(rand()%, rand()%height, 0, vga);\r
-                               if(q==2||q==16) putPixel_X(rand()%width, rand()%height, 0);\r
+                               if(q==2) putColorBox_X(rand()%width, rand()%(height*3), TILEWH, TILEWH, 0);\r
+                               if(q==16) putPixel_X(rand()%width, rand()%(height*3), 0);\r
                                if(q==2||q==4||q==16){ bakax = rand()%3; bakay = rand()%3; }\r
                                gq++;\r
 //if(xx<0||xx>320||yy<0||yy>240)\r
@@ -615,7 +743,7 @@ void doTest(void)
                                                                                putPixel_X(x+(p+2)*16, y+(p+2)*16, x + y*16);\r
                                                //}\r
 \r
-                               drawText(0, 0, 15, p);\r
+//                             drawText(0, 0, 15, p);\r
 \r
                                }\r
 \r
@@ -652,7 +780,9 @@ int main(void)
 //       puts("Press a key when ready...");\r
 //       getch();\r
 \r
+//++++0000\r
                setvideo(1);\r
+//mxInit();\r
 // screen savers\r
 \r
 /*while(d!=0){ // on!\r
@@ -669,13 +799,20 @@ int main(void)
                                }\r
                }*/ // else off\r
                while(!kbhit()){ // conditions of screen saver\r
-                               ding(4);\r
+                       ding(4);\r
                }\r
                //end of screen savers\r
                doTest();\r
+\r
+               while(!kbhit()){ // conditions of screen saver\r
+                       vScroll(-1);\r
+               }\r
+//++++0000\r
                setvideo(0);\r
+//mxTerm();\r
+//mxGetVersion();\r
                puts("Where to next?  It's your move! wwww");\r
-               printf("bakapi ver. 1.04.09a\nis made by sparky4\81i\81\86\83Ö\81\85\81j feel free to use it ^^\nLicence: GPL v2\n");\r
+               printf("bakapi ver. 1.04.09.02\nis made by sparky4\81i\81\86\83Ö\81\85\81j feel free to use it ^^\nLicence: GPL v2\n");\r
                return 0;\r
                }\r
 \r