-/*\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
+//DOS Graphics thingy by sparky4 licence GPL v2
+//a special thanks to everyone to release source code for mode X
/*src\lib\*/\r
#include "dos_gfx.h"\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
+byte coor;
+
+byte *vga = (byte *) MK_FP(0xA000, 0);\r
\r
/*\r
* Comment out the following #define if you don't want the testing main()\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
-\r
-\r
-/*-----------XXXX-------------*/\r
-\r
-/////////////////////////////////////////////////////////////////////////////\r
-// //\r
-// WaitRetrace() - This waits until you are in a Verticle Retrace. //\r
-// //\r
-/////////////////////////////////////////////////////////////////////////////\r
-void wait_for_retrace(void)\r
-{\r
- while (!(inp(STATUS_ADDR) & 0x08));\r
-}\r
-\r
-/*tile*/\r
-//king_crimson's code\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
- }\r
-}\r
-\r
-void vScroll(int rows)\r
-{\r
- // Scrolling = current start + (rows * bytes in a row)\r
- setVisibleStart(visStart + (rows * width));\r
-}\r
-\r
-void scrolly(int bongy)\r
-{\r
- int boingy=0;\r
- if(bongy<0)\r
- boingy=-1;\r
- else if(bongy>0)\r
- boingy=1;\r
-\r
- for(int ti=0;ti<TILEWH;ti++)\r
- {\r
- delay(1);\r
- vScroll(boingy);\r
- }\r
-}\r
-\r
-//king_crimson's code\r
-void hScroll(int Cols) {\r
- wait_for_retrace();\r
- outp(0x3C0, 0x13);\r
- outp(0x3C0, Cols & 3);\r
- outp(0x3D4, 0x13);\r
- outp(0x3D5, Cols >> 2);\r
- outp(0x3D4, Cols);\r
- //setVisibleStart(visStart + (Cols * height));\r
- setVisibleStart(visStart + (Cols * width));\r
-}\r
-\r
/////////////////////////////////////////////////////////////////////////////\r
// //\r
// setvideo() - This function Manages the video modes //\r
// enter mode\r
mxInit();\r
mxSetMode( MX_320x240 );\r
- width=320;\r
- height=240;\r
-// mxSetVirtualScreen(width+(width/4), height+(height/4));\r
-// mxSetVirtualScreen(width*2, height*2);\r
- //set320x240x256_X();\r
- mxSetVirtualScreen(560,420);\r
-// mxSetVirtualScreen((640-(TILEWH*2)),(480-(TILEWH*2)));\r
+// mxSetVirtualScreen(SW+(SW/4), SH+(SH/4));\r
+// mxSetVirtualScreen(SW*2, SH*2);\r
+ mxSetVirtualScreen(VW,VH);\r
+// mxSetVirtualScreen((640-(TILEWH*4)),(480-(TILEWH*4)));\r
mxSetClip(0);\r
- //mxSetClipRegion(0, 0, width, height);\r
+ //mxSetClipRegion(0, 0, SW, SH);\r
}\r
}\r
\r
// //\r
/////////////////////////////////////////////////////////////////////////////\r
void cls(byte color, byte *Where){\r
- _fmemset(Where, color, width*(height*17));\r
+ _fmemset(Where, color, VW*(VH));\r
}\r
\r
//color \82Ä\82·\82Æ\r
\r
//slow spectrum down\r
void ssd(int svq){\r
- if(sy < height+1){\r
- if(sx < width+1){\r
+ if(sy < SH+1){\r
+ if(sx < SW+1){\r
//plotpixel(xx, yy, coor, vga);\r
//ppf(sx, sy, coor, vga);\r
- putPixel_X(sx, sy, coor);\r
+ mxPutPixel(sx, sy, coor);\r
//printf("%d %d %d %d\n", sx, sy, svq, coor);\r
sx++;\r
}else sx = 0;\r
- if(sx == width){\r
+ if(sx == SW){\r
sy++;\r
if(svq == 7) coor++;\r
- if(sy == height && svq == 8) coor = rand()%NUM_COLORS;\r
+ if(sy == SH && svq == 8) coor = rand()%NUM_COLORS;\r
}\r
}else sy = 0;\r
}\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
||q==16\r
) && gq == BONK){\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
if(q==11){ colorz(); delay(100); return gq; }\r
if(q==6){\r
coor = rand()%NUM_COLORS;\r
-//---- cls(coor, vaddr);\r
cls(coor, vga);\r
//updatevbuff();\r
}\r
}\r
if((q<5 && gq<BONK) || (q==16 && gq<BONK)){ // the number variable make the colors more noticable\r
if(q==1){\r
- if(xx==width){bakax=0;}\r
+ if(xx==SW){bakax=0;}\r
if(xx==0){bakax=1;}\r
- if(yy==height){bakay=0;}\r
+ if(yy==SH){bakay=0;}\r
if(yy==0){bakay=1;}\r
}else if(q==3){\r
- if(xx!=width||yy!=height){\r
+ if(xx!=SW||yy!=SH){\r
if(xx==0){bakax=1;bakay=-1;d3y=1;}\r
if(yy==0){bakax=1;bakay=0;d3y=1;}\r
- if(xx==width){bakax=-1;bakay=-1;d3y=1;}\r
- if(yy==height){bakax=1;bakay=0;d3y=1;}\r
- }else if(xx==width&&yy==height) xx=yy=0;\r
+ if(xx==SW){bakax=-1;bakay=-1;d3y=1;}\r
+ if(yy==SH){bakax=1;bakay=0;d3y=1;}\r
+ }else if(xx==SW&&yy==SH) xx=yy=0;\r
}\r
if(q==3){\r
if(d3y){\r
}\r
}\r
// fixer\r
-// if(q!=16){\r
- if(xx<0) xx=(560/*-TILEWH*/);\r
- if(yy<0) yy=(420/*-TILEWH*/);\r
- if(xx>(560/*-TILEWH*/)) xx=0;\r
- if(yy>(420/*-TILEWH*/)) yy=0;\r
-// }\r
+ if(q!=16){\r
+ if(xx<0) xx=(VW/*-TILEWH*/);\r
+ if(yy<0) yy=(VH/*-TILEWH*/);\r
+ if(xx>(VW/*-TILEWH*/)) xx=0;\r
+ if(yy>(VH/*-TILEWH*/)) yy=0;\r
+ }\r
\r
//interesting effects\r
if(q==16)\r
tx+=xx+16;\r
ty+=yy+16;\r
mxPutPixel(tx, ty, coor);\r
- //drawrect(tx, ty, tx+TILEWH, ty+TILEWH, coor);\r
//printf("%d %d %d %d %d %d\n", xx, yy, tx, ty, TILEWH);\r
\r
// plot the pixel\r
-//---- ppf(xx, yy, coor, vga);\r
- }else /*if(xx>=0 && xx<width && yy>=0 && yy<(height*3))*/{\r
+ }else{\r
// mxFillBox(xx, yy, TILEWH, TILEWH, coor, 0);\r
-//++++0000\r
-// putPixel_X(xx, yy, coor);\r
mxPutPixel(xx, yy, coor);\r
} \r
\r
-//---- if(q==2) ppf(rand()%, rand()%height, 0, vga);\r
-// if(q==2) putColorBox_X(rand()%width, rand()%(height*3), TILEWH, TILEWH, 0);\r
-//++++0000\r
- if(q==2) mxPutPixel(rand()%width, rand()%(height*3), 0);\r
- if(q==16) mxPutPixel(rand()%width, rand()%(height*3), 0);\r
+ if(q==2) mxPutPixel(rand()%SW, rand()%(SH*3), 0);\r
+ if(q==16) mxPutPixel(rand()%SW, rand()%(SH*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>(height*3))\r
+//if(xx<0||xx>320||yy<0||yy>(SH*3))\r
// printf("%d %d %d %d %d %d\n", xx, yy, coor, bakax, bakay, getPixel_X(xx,yy));\r
// printf("%d\n", getPixel_X(xx,yy));\r
}else gq = LGQ;\r
* The library testing routines follows below.\r
*/\r
\r
-\r
#ifdef TESTING\r
\r
-#include <stdio.h>\r
-#include <conio.h>\r
-\r
-void doTest(void)\r
- {\r
- int p, x, y, pages;\r
-\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
- setActivePage(p);\r
-\r
- /* On each page draw a single colored border, and dump the palette\r
- onto a small square about the middle of the page. */\r
-\r
- //{\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
- }\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
- }\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
- //}\r
-\r
- }\r
-\r
- /* Each pages will now contain a different image. Let the user cycle\r
- through all the pages by pressing a key. */\r
- for (p = 0; p < pages; ++p)\r
- {\r
- setVisiblePage(p);\r
- getch();\r
- }\r
-\r
- }\r
-\r
/*\r
* Library test (program) entry point.\r
*/\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
-// puts("Press a key when ready...");\r
-// getch();\r
-\r
-// doTest();\r
-\r
-// puts("Then, check out Mode X, 320x240 with 3 (and a half) pages.");\r
-// puts("Press a key when ready...");\r
-// getch();\r
-\r
-//++++0000\r
setvideo(1);\r
// screen savers\r
\r
}\r
//end of screen savers\r
//doTest();\r
- for (int x = 0; x < width; ++x)\r
+ for (int x = 0; x < VW; ++x)\r
{\r
mxPutPixel(x, 0, 15);\r
- mxPutPixel(x, height-1, 15);\r
+ mxPutPixel(x, SH-1, 15);\r
}\r
- for (int y = 0; y < height; ++y)\r
+ for (int y = 0; y < VH; ++y)\r
{\r
mxPutPixel(0, y, 15);\r
- mxPutPixel(width-1, y, 15);\r
+ mxPutPixel(SW-1, y, 15);\r
+ }
+\r
+ getch();
+ for (int x = 320; x < VW; ++x)\r
+ {\r
+ mxPutPixel(x, 0, 15);\r
+ mxPutPixel(x, VH-1, 15);\r
}\r
+ for (int y = 240; y < VH; ++y)\r
+ {\r
+ mxPutPixel(0, y, 15);\r
+ mxPutPixel(VW-1, y, 15);\r
+ }
getch();\r
while(!kbhit()){\r
// hScroll(1);\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
+ //mxWaitRetrace();\r
+ xpos+=xdir;\r
+ ypos+=ydir;\r
+ if( (xpos>(VW-SW-1)) || (xpos<1)){xdir=-xdir;}\r
+ if( (ypos>(VH-SH-1)) || (ypos<1)){ydir=-ydir;} // { Hit a boundry, change\r
// direction! }\r
//}\r
}\r
setvideo(0);\r
- printf("wwww\n%dx%d\n", width,height);\r
- printf("[%d]\n", mxGetVersion());\r
- puts("where to next? It's your move! wwww");\r
+ printf("wwww\nResolution: %dx%d\n", SW,SH);\r
+ printf("Mode X Library Version: %d\n", mxGetVersion());\r
+ //puts("where to next? It's your move! wwww");\r
printf("bakapi ver. 1.04.09.04\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
+ * 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
\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
//{\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
\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
// puts("Press a key when ready...");\r
// getch();\r
\r
-//++++0000\r
setvideo(1);\r
// screen savers\r
\r
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