]> 4ch.mooo.com Git - 16.git/blob - 16/dos_gfx.cpp
modified: 16/Project 16.bfproject
[16.git] / 16 / dos_gfx.cpp
1 /*\r
2  * LIB.C v1.2a\r
3  *\r
4  * by Robert Schmidt\r
5  * (C)1993 Ztiff Zox Softwear\r
6  *\r
7  * Simple graphics library to accompany the article\r
8  * \r
9  *                                        INTRODUCTION TO MODE X.\r
10  * \r
11  * This library provides the basic functions for initializing and using\r
12  * unchained (planar) 256-color VGA modes.  Currently supported are:\r
13  *\r
14  *        - 320x200\r
15  *        - 320x240\r
16  *\r
17  * Functions are provided for:\r
18  *\r
19  *        - initializing one of the available modes\r
20  *        - setting the start address of the VGA refresh data\r
21  *        - setting active and visible display pages\r
22  *        - writing and reading a single pixel to/from video memory\r
23  *\r
24  * The library is provided as a demonstration only, and is not claimed\r
25  * to be particularly efficient or suited for any purpose.  It has only\r
26  * been tested with Borland C++ 3.1 by the author.  Comments on success\r
27  * or disaster with other compilers are welcome.\r
28  *\r
29  * This file is public domain.  Do with it whatever you'd like, but\r
30  * please don't distribute it without the article.\r
31  *\r
32  * Thanks go out to various helpful netters who spotted the 0xE7 bug\r
33  * in the set320x240x256() function!\r
34  *\r
35  * Modified by sparky4 so it can be compiled in open watcom ^^\r
36  */\r
37 \r
38 \r
39 \r
40 \r
41 /*\r
42  * We 'require' a large data model simply to get rid of explicit 'far'\r
43  * pointers and compiler specific '_fmemset()' functions and the likes.\r
44  */\r
45 #if !defined(__COMPACT__)\r
46 # if !defined(__LARGE__)\r
47 #  if !defined(__HUGE__)\r
48 #   error Large data model required!  Try compiling with 'wcc -0 -ml lib.c'.\r
49 #  endif\r
50 # endif\r
51 #endif\r
52 \r
53 #include <dos.h>\r
54 #include <mem.h>\r
55 #include <conio.h>\r
56 \r
57 //code from old library!\r
58 /*src\lib\*/\r
59 #include "dos_gfx.h"\r
60 #include "lib\x\modex.h"\r
61 \r
62 int old_mode;\r
63 //color \82Ä\82·\82Æ\r
64 int gq = LGQ;\r
65 //\82Ä\82·\82Æ\r
66 int q = 0;\r
67 int bakax = 0, bakay = 0;\r
68 int xx = rand()&0%320, yy = rand()&0%240, sx = 0, sy = 0;\r
69 byte coor;\r
70 \r
71 /*\r
72  * Comment out the following #define if you don't want the testing main()\r
73  * to be included.\r
74  */\r
75 #define TESTING\r
76 \r
77 /*\r
78  * Define the port addresses of some VGA registers.\r
79  */\r
80 #define CRTC_ADDR          0x3d4   /* Base port of the CRT Controller (color) */\r
81 \r
82 #define SEQU_ADDR          0x3c4   /* Base port of the Sequencer */\r
83 #define GRAC_ADDR          0x3ce   /* Base port of the Graphics Controller */\r
84 \r
85 \r
86 /*\r
87  * Make a far pointer to the VGA graphics buffer segment.  Your compiler\r
88  * might not have the MK_FP macro, but you'll figure something out.\r
89  */\r
90 byte *vga = (byte *) MK_FP(0xA000, 0);\r
91 \r
92 //fontAddr = getFont();\r
93 \r
94 /*\r
95  * width and height should specify the mode dimensions.  widthBytes\r
96  * specify the width of a line in addressable bytes.\r
97  */\r
98 unsigned width, height, widthBytes;\r
99 \r
100 /*\r
101  * actStart specifies the start of the page being accessed by\r
102  * drawing operations.  visStart specifies the contents of the Screen\r
103  * Start register, i.e. the start of the visible page.\r
104  */\r
105 unsigned actStart, visStart;\r
106 \r
107 /*\r
108  * set320x200x256_X()\r
109  *        sets mode 13h, then turns it into an unchained (planar), 4-page\r
110  *        320x200x256 mode.\r
111  */\r
112 void set320x200x256_X(void)\r
113                 {\r
114                 union REGS r;\r
115 \r
116                 /* Set VGA BIOS mode 13h: */\r
117                 r.x.ax = 0x0013;\r
118                 int86(0x10, &r, &r);\r
119 \r
120                 /* Turn off the Chain-4 bit (bit 3 at index 4, port 0x3c4): */\r
121                 outpw(SEQU_ADDR, 0x0604);\r
122 \r
123                 /* Turn off word mode, by setting the Mode Control register\r
124                 of the CRT Controller (index 0x17, port 0x3d4): */\r
125                 outpw(CRTC_ADDR, 0xE317);\r
126 \r
127                 /* Turn off doubleword mode, by setting the Underline Location\r
128                    register (index 0x14, port 0x3d4): */\r
129                 outpw(CRTC_ADDR, 0x0014);\r
130 \r
131                 /* Clear entire video memory, by selecting all four planes, then\r
132                    writing 0 to entire segment. */\r
133                 outpw(SEQU_ADDR, 0x0F02);\r
134                 memset(vga+1, 0, 0xffff); /* stupid size_t exactly 1 too small */\r
135                 vga[0] = 0;\r
136 \r
137                 /* Update the global variables to reflect dimensions of this\r
138                    mode.  This is needed by most future drawing operations. */\r
139                 width              = 320;\r
140                 height  = 200;\r
141 \r
142                 /* Each byte addresses four pixels, so the width of a scan line\r
143                    in *bytes* is one fourth of the number of pixels on a line. */\r
144                 widthBytes = width / 4;\r
145 \r
146                 /* By default we want screen refreshing and drawing operations\r
147                    to be based at offset 0 in the video segment. */\r
148                 actStart = visStart = 0;\r
149 \r
150                 /*\r
151 --------------------\r
152 HORIZONTAL SCROLLING\r
153 --------------------\r
154 Horizontal scrolling is essentially the same as vertical scrolling, all\r
155 you do is increment or decrement the VGA offset register by 1 instead of\r
156 80 as with vertical scrolling.\r
157 \r
158 However, horizontal scrolling is complicated by two things\r
159 \r
160   1. Incrementing the offset register by one actually scrolls by FOUR\r
161      pixels (and there are FOUR planes on the VGA, what a coincidence)\r
162 \r
163   2. You can't draw the image off the screen and then scroll it on\r
164      because of the way the VGA wraps to the next row every 80 bytes\r
165      (80 bytes * 4 planes = 320 pixels), if you tried it, you would\r
166      actually be drawing to the other side of the screen (which is\r
167      entirely visible)\r
168 \r
169 I'll solve these problems one at a time.\r
170 \r
171 Firstly, to get the VGA to scroll by only one pixel you use the horizontal\r
172 pixel panning (HPP) register. This register resides at\r
173 \r
174   PORT:     3C0H\r
175   INDEX:    13h\r
176 \r
177 and in real life, you use it like this\r
178 \r
179 ----------------- Pixel Panning ---------------\r
180 IN PORT 3DAH (this clears an internal\r
181   flip-flop of the VGA)\r
182 OUT 13H TO PORT 3C0H\r
183 OUT value TO PORT 3C0H (where "value" is the\r
184   number of pixels to offset)\r
185 -----------------------------------------------\r
186 */\r
187 //\r
188 //      inp(0x3DA);\r
189 //      outp(0x3C0, 0x13);\r
190 \r
191                 }\r
192 \r
193 /*\r
194  * setActiveStart() tells our graphics operations which address in video\r
195  * memory should be considered the top left corner.\r
196  */\r
197 void setActiveStart(unsigned offset)\r
198                 {\r
199                 actStart = offset;\r
200                 }\r
201 \r
202 /*\r
203  * setVisibleStart() tells the VGA from which byte to fetch the first\r
204  * pixel when starting refresh at the top of the screen.  This version\r
205  * won't look very well in time critical situations (games for\r
206  * instance) as the register outputs are not synchronized with the\r
207  * screen refresh.  This refresh might start when the high byte is\r
208  * set, but before the low byte is set, which produces a bad flicker.\r
209  */\r
210 void setVisibleStart(unsigned offset)\r
211                 {\r
212                 visStart = offset;\r
213                 outpw(CRTC_ADDR, 0x0C);          /* set high byte */\r
214                 outpw(CRTC_ADDR+1, visStart >> 8);\r
215                 outpw(CRTC_ADDR, 0x0D);          /* set low byte */\r
216                 outpw(CRTC_ADDR+1, visStart & 0xff);\r
217                 }\r
218 \r
219 /*\r
220  * setXXXPage() sets the specified page by multiplying the page number\r
221  * with the size of one page at the current resolution, then handing the\r
222  * resulting offset value over to the corresponding setXXXStart()\r
223  * function.  The first page is number 0.\r
224  */\r
225 void setActivePage(int page)\r
226                 {\r
227                 setActiveStart(page * widthBytes * height);\r
228                 }\r
229 \r
230 void setVisiblePage(int page)\r
231                 {\r
232                 setVisibleStart(page * widthBytes * height);\r
233                 }\r
234 \r
235 void putPixel_X(int x, int y, byte color)\r
236                 {\r
237                 /* Each address accesses four neighboring pixels, so set\r
238                    Write Plane Enable according to which pixel we want\r
239                    to modify.  The plane is determined by the two least\r
240                    significant bits of the x-coordinate: */\r
241                 outp(0x3c4, 0x02);\r
242                 outp(0x3c5, 0x01 << (x & 3));\r
243 \r
244                 /* The offset of the pixel into the video segment is\r
245                    offset = (width * y + x) / 4, and write the given\r
246                    color to the plane we selected above.  Heed the active\r
247                    page start selection. */\r
248                 vga[(unsigned)(widthBytes * y) + (x / 4) + actStart] = color;\r
249 \r
250                 }\r
251 \r
252 byte getPixel_X(int x, int y)\r
253                 {\r
254                 /* Select the plane from which we must read the pixel color: */\r
255                 outpw(GRAC_ADDR, 0x04);\r
256                 outpw(GRAC_ADDR+1, x & 3);\r
257 \r
258                 return vga[(unsigned)(widthBytes * y) + (x / 4) + actStart];\r
259 \r
260                 }\r
261 \r
262 void set320x240x256_X(void)\r
263                 {\r
264                 /* Set the unchained version of mode 13h: */\r
265                 set320x200x256_X();\r
266 \r
267                 /* Modify the vertical sync polarity bits in the Misc. Output\r
268                    Register to achieve square aspect ratio: */\r
269                 outp(0x3C2, 0xE3);\r
270 \r
271                 /* Modify the vertical timing registers to reflect the increased\r
272                    vertical resolution, and to center the image as good as\r
273                    possible: */\r
274                 outpw(0x3D4, 0x2C11);              /* turn off write protect */\r
275                 outpw(0x3D4, 0x0D06);              /* vertical total */\r
276                 outpw(0x3D4, 0x3E07);              /* overflow register */\r
277                 outpw(0x3D4, 0xEA10);              /* vertical retrace start */\r
278                 outpw(0x3D4, 0xAC11);              /* vertical retrace end AND wr.prot */\r
279                 outpw(0x3D4, 0xDF12);              /* vertical display enable end */\r
280                 outpw(0x3D4, 0xE715);              /* start vertical blanking */\r
281                 outpw(0x3D4, 0x0616);              /* end vertical blanking */\r
282 \r
283                 /* Update mode info, so future operations are aware of the\r
284                    resolution */\r
285                 height = 240;\r
286 \r
287                 }\r
288 \r
289 \r
290 /*-----------XXXX-------------*/
291
292 /////////////////////////////////////////////////////////////////////////////\r
293 //                                                                         //\r
294 // WaitRetrace() - This waits until you are in a Verticle Retrace.         //\r
295 //                                                                         //\r
296 /////////////////////////////////////////////////////////////////////////////\r
297 \r
298 void WaitRetrace() {\r
299 \r
300 //  register char qy;\r
301 \r
302         in.h.dx = 0x03DA;\r
303         in.h.al = in.h.dx;\r
304         \r
305         in.h.al &= 0x08;\r
306         int86(0x10, &in, &out);\r
307 \r
308 \r
309   /*l1: asm {\r
310         in  al,0x03DA;\r
311         and al,0x08;\r
312         jnz  l2;\r
313       }*/\r
314 }
315
316 /////////////////////////////////////////////////////////////////////////////\r
317 //                                                                         //\r
318 // MoveTo() - This moves to position X*4 on a chain 4 screen.              //\r
319 //                Note: As soon as I find documentation, this function     //\r
320 //                will be better documented.  - Snowman                    //\r
321 //                                                                         //\r
322 /////////////////////////////////////////////////////////////////////////////\r
323 \r
324 void MoveTo (word X, word Y) {\r
325 \r
326 //      word O = Y*SIZE*2+X;
327         word O = Y*widthBytes*2+X;\r
328 \r
329   asm {\r
330     mov    bx, [O]\r
331     mov    ah, bh\r
332     mov    al, 0x0C\r
333 \r
334     mov    dx, 0x3D4\r
335     out    dx, ax\r
336 \r
337     mov    ah, bl\r
338     mov    al, 0x0D\r
339     mov    dx, 0x3D4\r
340     out    dx, ax\r
341   }
342
343 ;-----------------------------------------------------------\r
344 ;\r
345 ; MXPN.ASM - Panning function\r
346 ; Copyright (c) 1993,1994 by Alessandro Scotti\r
347 ;\r
348 ;-----------------------------------------------------------\r
349 ;WARN    PRO\r
350 INCLUDE MODEX.DEF\r
351 \r
352 PUBLIC  mxPan\r
353 \r
354 EXTRN   mxWaitDisplay   : FAR\r
355 EXTRN   mxStartAddress  : FAR\r
356 \r
357 MX_TEXT         SEGMENT USE16 PARA PUBLIC 'CODE'\r
358                 ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
359 \r
360 EXTRN   mx_BytesPerLine : WORD\r
361 \r
362 ;-----------------------------------------------------------\r
363 ;\r
364 ; Moves the screen.\r
365 ;\r
366 ; Input:\r
367 ;       X, Y    = new X, Y coordinates of view screen\r
368 ; Output:\r
369 ;       none\r
370 ;\r
371 mxPan           PROC    FAR\r
372         ARG     Y:WORD,                 \\r
373                 X:WORD                  = ARG_SIZE\r
374         ASSUME  ds:NOTHING\r
375         .enter  0\r
376 \r
377         mov     ax, [Y]\r
378         mul     [mx_BytesPerLine]\r
379         mov     dx, [X]\r
380         shr     dx, 1\r
381         shr     dx, 1\r
382         add     ax, dx\r
383         push    ax                      ; Push the start address\r
384         call    mxWaitDisplay\r
385         call    mxStartAddress\r
386 \r
387         mov     dx, 03DAh               ; Set the pixel pan register\r
388         in      al, dx\r
389         mov     dx, 03C0h\r
390         mov     al, 33h\r
391         out     dx, al\r
392         mov     al, BYTE PTR [X]\r
393         and     al, 3\r
394         shl     al, 1\r
395         out     dx, al\r
396 \r
397         xor     ax, ax\r
398         .leave  ARG_SIZE\r
399 mxPan           ENDP\r
400 \r
401 MX_TEXT         ENDS\r
402 END\r
403
404 \r
405 }
406
407 //Procedure Play;\r
408 void Play()\r
409 {\r
410   int loop1,loop2;\r
411   int xpos,ypos,xdir,ydir;\r
412   //int ch;\r
413 //   for(loop1=1;loop1<=62;loop1++)\r
414      //Pal ((char)loop1,(char)loop1,(char)0,(char)(62-loop1)); // { This sets up the pallette for the pic }\r
415 \r
416    moveto(0,0,Size); // { This moves the view to the top left hand corner }\r
417 \r
418 /*   for(loop1=0;loop1<=3;loop1++)\r
419      for(loop2=0;loop2<=5;loop2++)\r
420        Putpic (loop1*160,loop2*66); // { This places the picture all over the\r
421                                     //  chain-4 screen }\r
422    getch();\r
423    ch=0x0;*/\r
424 //   xpos=rand (78)+1;\r
425 //   ypos=rand (198)+1; // { Random start positions for the view }
426         xpos=0;
427         ypos=0;\r
428    xdir=1;\r
429    ydir=1;\r
430 //   while(1)\r
431 //   {\r
432      WaitRetrace();     //     { Take this out and watch the screen go crazy! }\r
433      moveto (xpos,ypos,Size);\r
434      xpos=xpos+xdir;\r
435      ypos=ypos+ydir;\r
436      if( (xpos>79)  || (xpos<1))xdir=-xdir;\r
437      if( (ypos>199) || (ypos<1))ydir=-ydir; // { Hit a boundry, change\r
438                                             //    direction! }\r
439 //     if(_bios_keybrd(_KEYBRD_READY))ch=getch();\r
440 //       if(ch==0x71)break; // 'q'\r
441 //       if(ch==0x1b)break; // 'ESC'\r
442 //   }\r
443 }
444 \r
445 /*tile*/\r
446 //king_crimson's code\r
447 void putColorBox_X(int x, int y, int w, int h, byte color) {\r
448         outp(0x3c4, 0x02);\r
449 \r
450         int curx, cury;\r
451         unsigned drawptr;\r
452         for (curx=x; curx<(x+w); curx++) {\r
453                 outp(0x3c5, 0x01 << (curx & 3));\r
454                 drawptr = (unsigned)(widthBytes * y) + (curx / 4) + actStart;\r
455                 for (cury=0; cury<h; cury++) {\r
456                         vga[drawptr] = color;\r
457                         drawptr += widthBytes;\r
458                 }\r
459         }\r
460 }\r
461 \r
462 void vScroll(int rows)\r
463 {\r
464         // Scrolling = current start + (rows * bytes in a row)\r
465         setVisibleStart(visStart + (rows * width));\r
466 }\r
467 \r
468 void scrolly(int bongy)\r
469 {\r
470         int boingy=0;\r
471         if(bongy<0)\r
472                 boingy=-1;\r
473         else if(bongy>0)\r
474                 boingy=1;\r
475 \r
476         for(int ti=0;ti<TILEWH;ti++)\r
477         {\r
478                 delay(1);\r
479                 vScroll(boingy);\r
480         }\r
481 }\r
482 \r
483 //king_crimson's code\r
484 void hScroll(int Cols) {\r
485         inp(0x3DA);\r
486         outp(0x3C0, 0x13);\r
487         outp(0x3C0, Cols & 3);\r
488         outp(0x3D4, 0x13);\r
489         outp(0x3D5, Cols/* >> 2*/);\r
490         //setVisibleStart(visStart + (Cols * height));\r
491         setVisibleStart(visStart + (Cols * width));\r
492 }\r
493 \r
494 /*To implement smooth horizontal scrolling, you would do the following:\r
495 -------------- Horizontal Scrolling ------------\r
496 FOR X = 0 TO 319 DO\r
497   SET HPP TO ( X MOD 4 )\r
498   SET VGA OFFSET TO ( X/4 )\r
499 END FOR\r
500 ------------------------------------------------\r
501 \r
502 Okay, no problem at all (although I think you might have to fiddle\r
503 around with the HPP a bit to get it right...try different values and\r
504 see what works :).\r
505 \r
506 So, the next problem is with drawing the images off the screen where\r
507 they aren't visible and then scrolling them on!!! As it turns out,\r
508 there's yet ANOTHER register to accomplish this. This one's called the\r
509 offset register (no, not the one I was talking about before, that one\r
510 was actually the "start address" register) and it's at\r
511 \r
512   PORT:     3D4H/3D5H\r
513   OFFSET:   13H\r
514 \r
515 and here's how to use it\r
516 \r
517 -------------- Offset Register ---------------\r
518 OUT 13H TO PORT 3D4H\r
519 OUT value TO PORT 3D5H\r
520 ----------------------------------------------\r
521 \r
522 Now, what my VGA reference says is that this register holds the number\r
523 of bytes (not pixels) difference between the start address of each row.\r
524 So, in X-mode it normally contains the value 80 (as we remember,\r
525 80 bytes * 4 planes = 320 pixels). This register does not affect the\r
526 VISIBLE width of the display, only the difference between addresses on\r
527 each row.\r
528 \r
529 When we scroll horizontally, we need a little bit of extra working space\r
530 so we can draw off the edge of the screen.\r
531 \r
532 Perhaps a little diagram will clarify it. The following picture is of a\r
533 standard X-mode addressing scheme with the OFFSET register set to 80.\r
534 \r
535       ROW    OFFSET\r
536       0         0 ========================\r
537       1        80 [                      ]\r
538       2       160 [                      ]\r
539       ..       .. [       VISIBLE        ]\r
540                   [        SCREEN        ]\r
541                   [                      ]\r
542                   [                      ]\r
543       ..       .. [                      ]\r
544       199   15920 ========================\r
545 \r
546 and the next diagram is of a modified addressing scheme with the OFFSET\r
547 register set to 82 (to give us 4 extra pixels on each side of the screen)\r
548 \r
549 ROW    OFFSET\r
550 0         0 ------========================------\r
551 1        82 |   V [                      ]   V |\r
552 2       164 |   I [                      ]   I |\r
553 ..       .. | N S [      VISIBLE         ] N S |\r
554             | O I [       SCREEN         ] O I |\r
555             | T B [                      ] T B |\r
556             |   L [                      ]   L |\r
557 ..       .. |   E [                      ]   E |\r
558 199   16318 ------========================------\r
559 \r
560 Beautiful!!!\r
561 \r
562 As with vertical scrolling, however, you still have the problem of when\r
563 you reach the bottom of page 4...and it's fixed in the same manner.\r
564 \r
565 I haven't actually managed to get infinite horizontal scrolling working,\r
566 but the method I have just stated will give you a horizontal scrolling\r
567 range of over 200 screens!!!! So if you need more (which is extremely\r
568 unlikely), figure it out yourself.\r
569 \r
570 \r
571 ------------------\r
572 COMBINED SCROLLING\r
573 ------------------\r
574 To do both horizontal and vertical scrolling, all you have to do is combine\r
575 the two methods with a few little extras (it's always the way isn't it).\r
576 \r
577 You have to start off with the original screen on the current page and the\r
578 next page as well. When you scroll horizontally, you have to draw the edge\r
579 that's coming in to the screen to BOTH pages (that means you'll be drawing\r
580 the incoming edge twice, once for each page). You do this so that when you\r
581 have scrolled vertically down through a complete page, you can jump back\r
582 to the first page and it will (hopefully) have an identical copy, and you\r
583 can then continue scrolling again.\r
584 \r
585 I'm sorry about this being so confusing but it's a bit difficult to explain.\r
586 \r
587 \r
588 */\r
589 //---------------------------------------------------\r
590 //\r
591 // Use the bios to get the address of the 8x8 font\r
592 //\r
593 // You need a font if you are going to draw text.\r
594 //\r
595 /*\r
596 int far *\r
597 getFont()\r
598 {\r
599         union REGPACK rg;\r
600         int seg;\r
601         int off;\r
602         memset(&rg, 0, sizeof(rg));\r
603 \r
604         rg.w.ax = 0x1130;\r
605         rg.h.bh = 0x03;\r
606         intr(0x10, &rg);\r
607         seg = rg.w.es;\r
608         off = rg.w.bp;\r
609         \r
610 \r
611         return (int far *)MK_FP(seg, off);\r
612 }\r
613 \r
614 void drawChar(int x, int y, int color, byte c)\r
615 {\r
616                 int i, j;\r
617                 int mask;\r
618                 int far *font = getFont() + (c * 8);\r
619 \r
620                 for (i = 0; i < 8; i++)\r
621                 {\r
622                                 mask = *font;\r
623                                 for (j = 0; j < 8; j++)\r
624                                 {\r
625                                                 if (mask & 0x80)\r
626                                                 {\r
627                                                                 //pixel(x + j, y + i, color);\r
628                                                                 putPixel_X(x + j, y + i, color);\r
629                                                 }\r
630                                                 mask <<= 1;\r
631                                 }\r
632                                 font++;\r
633                 }\r
634 }\r
635 \r
636 void drawText(int x, int y, int color, byte string)\r
637 {\r
638                 while (string)\r
639                 {\r
640                                 drawChar(x, y, color, string);\r
641                                 x += 8;\r
642                                 string++;\r
643                 }\r
644 }\r
645 */\r
646 /////////////////////////////////////////////////////////////////////////////\r
647 //                                                                         //\r
648 // setvideo() - This function Manages the video modes                                     //\r
649 //                                                                         //\r
650 /////////////////////////////////////////////////////////////////////////////\r
651 void setvideo(/*byte mode, */int vq){\r
652                 union REGS in, out;\r
653 \r
654                 if(!vq){ // deinit the video\r
655                                 // change to the video mode we were in before we switched to mode 13h\r
656                                 in.h.ah = 0x00;\r
657                                 in.h.al = old_mode;\r
658                                 int86(0x10, &in, &out);\r
659 \r
660                 }else if(vq == 1){ // init the video\r
661                                 // get old video mode\r
662                                 in.h.ah = 0xf;\r
663                                 int86(0x10, &in, &out);\r
664                                 old_mode = out.h.al;\r
665 \r
666                                 // enter mode\r
667                                 set320x240x256_X();\r
668                 }\r
669 }\r
670 \r
671 /////////////////////////////////////////////////////////////////////////////\r
672 //                                                                                                                                               //\r
673 // cls() - This clears the screen to the specified color, on the VGA or on //\r
674 //               the Virtual screen.                                                                                     //\r
675 //                                                                                                                                               //\r
676 /////////////////////////////////////////////////////////////////////////////\r
677 void cls(byte color, byte *Where){\r
678                 _fmemset(Where, color, width*(height*17));\r
679 }\r
680 \r
681 //color \82Ä\82·\82Æ\r
682 int colortest(){\r
683                 if(gq < NUM_COLORS){\r
684                                 cls(gq, vga);\r
685                                 gq++;\r
686                 }else gq = 0;\r
687                 return gq;\r
688 }\r
689 \r
690 //color \82Ä\82·\82Æ\r
691 int colorz(){\r
692                 if(gq < HGQ){\r
693 //----            cls(gq, vaddr);\r
694                                 cls(gq, vga);\r
695                                 gq++;\r
696                 }else gq = LGQ;\r
697                 return gq;\r
698 }\r
699 \r
700 //slow spectrum down\r
701 void ssd(int svq){\r
702                 if(sy < height+1){\r
703                                 if(sx < width+1){\r
704                                                 //plotpixel(xx, yy, coor, vga);\r
705                                                 //ppf(sx, sy, coor, vga);\r
706                                                 putPixel_X(sx, sy, coor);\r
707                                                 //printf("%d %d %d %d\n", sx, sy, svq, coor);\r
708                                                 sx++;\r
709                                 }else sx = 0;\r
710                                 if(sx == width){\r
711                                                 sy++;\r
712                                                 if(svq == 7) coor++;\r
713                                                 if(sy == height && svq == 8) coor = rand()%NUM_COLORS;\r
714                                 }\r
715                 }else sy = 0;\r
716 }\r
717 \r
718 /*-----------ding-------------*/\r
719 int ding(int q){\r
720 \r
721 //      if(yy<height){\r
722                 setActivePage(0);\r
723                 setVisiblePage(0);\r
724 /*      }\r
725         if((height)<yy<(height*2)){\r
726                 setActivePage(1);\r
727                 setVisiblePage(1);\r
728         }\r
729         if((height*2)<yy<(height*3)){\r
730                 setActivePage(2);\r
731                 setVisiblePage(2);\r
732         }*/\r
733                 int d3y;\r
734 \r
735 //++++  if(q <= 4 && q!=2 && gq == BONK-1) coor = rand()%HGQ;\r
736                 if((q == 2\r
737                 ||q==4\r
738                 ||q==16\r
739                 ) && gq == BONK-1){\r
740                                                 if(coor < HGQ && coor < LGQ) coor = LGQ;\r
741                                                 if(coor < HGQ){\r
742                                                                 coor++;\r
743                                 }else{ coor = LGQ;\r
744                                                 bakax = rand()%3; bakay = rand()%3;\r
745                                 }\r
746                 }\r
747 \r
748                 if(q == 8){ colorz(); return gq; }else\r
749                 if(q == 10){ ssd(q); /*printf("%d\n", coor);*/ }else\r
750                 if(q == 5){ colortest(); return gq; }else\r
751                 if(q == 11){ colorz(); delay(100); return gq; }\r
752                 if(q == 6){\r
753                                 coor = rand()%NUM_COLORS;\r
754 //----            cls(coor, vaddr);\r
755                                 cls(coor, vga);\r
756                                 //updatevbuff();\r
757                 }\r
758 \r
759                 if(q == 7 || q== 9){\r
760                                 if(gq < HGQ){\r
761                                                 if(q == 7) ssd(q);\r
762                                                 if(q == 9){ ssd(q); coor++; }\r
763                                                 gq++;\r
764                                 }else gq = LGQ;\r
765                 }\r
766                 if((q<5 && gq<BONK) || (q==16 && gq<BONK)){ // the number variable make the colors more noticable\r
767                                 if(q==1){\r
768                                                 if(xx==width){bakax=0;}\r
769                                                 if(xx==0){bakax=1;}\r
770                                                 if(yy==height){bakay=0;}\r
771                                                 if(yy==0){bakay=1;}\r
772                                 }else if(q==3){\r
773                                                 if(xx!=width||yy!=height){\r
774                                                                 if(xx==0){bakax=1;bakay=-1;d3y=1;}\r
775                                                                 if(yy==0){bakax=1;bakay=0;d3y=1;}\r
776                                                                 if(xx==width){bakax=-1;bakay=-1;d3y=1;}\r
777                                                                 if(yy==height){bakax=1;bakay=0;d3y=1;}\r
778                                                 }else if(xx==width&&yy==height) xx=yy=0;\r
779                                 }\r
780                                 if(q==3){\r
781                                                 if(d3y){\r
782                                                                 if(bakay<0){\r
783                                                                                 yy--;\r
784                                                                                 d3y--;\r
785                                                                 }else\r
786                                                                 if(bakay>0){\r
787                                                                                 yy++;\r
788                                                                                 d3y--;\r
789                                                                 }\r
790                                                 }\r
791                                                 if(bakax<0){\r
792                                                                 xx--;\r
793                                                 }else\r
794                                                 if(bakax>0){\r
795                                                                 xx++;\r
796                                                 }\r
797                                 }else{\r
798                                                 if(q==16)\r
799                                                 {\r
800                                                                 if(!bakax){\r
801                                                                                 xx--;//=TILEWH;\r
802                                                                 }else if(bakax>0){\r
803                                                                                 xx++;//=TILEWH;\r
804                                                                 }\r
805                                                                 if(!bakay){\r
806                                                                                 yy--;//=TILEWH;\r
807                                                                 }else if(bakay>0){\r
808                                                                                 yy++;//=TILEWH;\r
809                                                                 }\r
810                                                 }else{\r
811                                                                 if(!bakax){\r
812 //                                                                              xx-=TILEWH;\r
813                                                                                 xx--;\r
814                                                                 }else if(bakax>1){\r
815 //                                                                              xx+=TILEWH;\r
816                                                                                 xx++;\r
817                                                                 }\r
818                                                                 if(!bakay){\r
819 //                                                                              yy-=TILEWH;\r
820                                                                                 yy--;\r
821                                                                 }else if(bakay>1){\r
822 //                                                                              yy+=TILEWH;\r
823                                                                                 yy++;\r
824                                                                 }\r
825                                                 }\r
826                                 }\r
827                                 // fixer\r
828 //                              if(q!=16){\r
829 //if(q!=16)\r
830                                                 if(xx<(0/*-TILEWH*/)) xx=(width/*+TILEWH*/);\r
831                                                 if(yy<0) yy=(height*3);\r
832                                                 if(xx>(width/*+TILEWH*/)) xx=(0/*-TILEWH*/);\r
833                                                 if(yy>(height*3)) yy=0;\r
834 //                              }\r
835 \r
836 //interesting effects\r
837                                 if(q==16)\r
838                                 {\r
839                                 int tx=0,ty=0;\r
840                                 tx+=xx+16;\r
841                                 ty+=yy+16;\r
842                                 putPixel_X(tx, ty, coor);\r
843                                 //drawrect(tx, ty, tx+TILEWH, ty+TILEWH, coor);\r
844                                 //printf("%d %d %d %d %d %d\n", xx, yy, tx, ty, TILEWH);\r
845 \r
846                                 // plot the pixel\r
847 //----            ppf(xx, yy, coor, vga);\r
848                                 }else /*if(xx>=0 && xx<width && yy>=0 && yy<(height*3))*/{\r
849 //                                      putColorBox_X(xx, yy, TILEWH, TILEWH, coor);\r
850 //++++0000\r
851                                         putPixel_X(xx, yy, coor);\r
852                                 } \r
853 \r
854 //----            if(q==2) ppf(rand()%, rand()%height, 0, vga);\r
855 //                              if(q==2) putColorBox_X(rand()%width, rand()%(height*3), TILEWH, TILEWH, 0);\r
856 //++++0000\r
857                                 if(q==2) putPixel_X(rand()%width, rand()%(height*3), 0);\r
858                                 if(q==16) putPixel_X(rand()%width, rand()%(height*3), 0);\r
859                                 if(q==2||q==4||q==16){ bakax = rand()%3; bakay = rand()%3; }\r
860                                 gq++;\r
861 //if(xx<0||xx>320||yy<0||yy>(height*3))\r
862 //        printf("%d %d %d %d %d %d\n", xx, yy, coor, bakax, bakay, getPixel_X(xx,yy));\r
863 //        printf("%d\n", getPixel_X(xx,yy));\r
864 //0000\r
865 //        drawText(0, 0, 15, getPixel_X(xx,yy));\r
866                 }else gq = LGQ;\r
867                 return gq;\r
868 }\r
869 \r
870 \r
871 /*\r
872  * The library testing routines follows below.\r
873  */\r
874 \r
875 \r
876 #ifdef TESTING\r
877 \r
878 #include <stdio.h>\r
879 #include <conio.h>\r
880 \r
881 void doTest(void)\r
882                 {\r
883                 int p, x, y, pages;\r
884 \r
885                 /* This is the way to calculate the number of pages available. */\r
886                 pages = 65536L/(widthBytes*height); // apparently this takes the A000 address\r
887 \r
888                 printf("%d\n", pages);\r
889 \r
890                 for (p = 0; p <= pages; ++p)\r
891                                 {\r
892                                 setActivePage(p);\r
893 \r
894                                 /* On each page draw a single colored border, and dump the palette\r
895                                    onto a small square about the middle of the page. */\r
896 \r
897                                    //{\r
898                                                 for (x = 0; x <= width; ++x)\r
899                                                                 {\r
900                                                                 putPixel_X(x, 0, p+1);\r
901                                                                 if(p!=pages) putPixel_X(x, height-1, p+1);\r
902                                                                                 else putPixel_X(x, 99-1, p+1);\r
903                                                                 }\r
904 \r
905                                                 for (y = 0; y <= height; ++y)\r
906                                                                 {\r
907                                                                 putPixel_X(0, y, p+1);\r
908                                                                 if(p!=pages) putPixel_X(width-1, y, p+1);\r
909                                                                                 else putPixel_X(width-1, y, p+1);\r
910                                                                 }\r
911 \r
912                                                 for (x = 0; x < 16; ++x)\r
913                                                                 for (y = 0; y < 16; ++y)\r
914                                                                                 putPixel_X(x+(p+2)*16, y+(p+2)*16, x + y*16);\r
915                                                 //}\r
916 \r
917 //                              drawText(0, 0, 15, p);\r
918 \r
919                                 }\r
920 \r
921                 /* Each pages will now contain a different image.  Let the user cycle\r
922                    through all the pages by pressing a key. */\r
923                 for (p = 0; p <= pages; ++p)\r
924                                 {\r
925                                 setVisiblePage(p);\r
926                                 //drawText(0, 240, 15, "bakapi");\r
927                                 getch();\r
928                                 }\r
929 \r
930                 }\r
931 \r
932 /*\r
933  * Library test (program) entry point.\r
934  */\r
935 \r
936 int main(void)\r
937                 {\r
938                 int key,d;\r
939                 // main variables\r
940                 d=1; // switch variable\r
941                 key=4; // default screensaver number\r
942 //        puts("First, have a look at the 320x200 mode.  I will draw some rubbish");\r
943 //        puts("on all of the four pages, then let you cycle through them by");\r
944 //        puts("hitting a key on each page.");\r
945 //        puts("Press a key when ready...");\r
946 //        getch();\r
947 \r
948 //        doTest();\r
949 \r
950 //        puts("Then, check out Mode X, 320x240 with 3 (and a half) pages.");\r
951 //        puts("Press a key when ready...");\r
952 //        getch();\r
953 \r
954 //++++0000\r
955                 setvideo(1);\r
956 //mxInit();\r
957 // screen savers\r
958 \r
959 /*while(d!=0){ // on!\r
960                                 if(!kbhit()){ // conditions of screen saver\r
961                                                 ding(key);\r
962                                 }else{\r
963                                                 setvideo(0);\r
964                                                 // user imput switch\r
965                                                 printf("Enter 1, 2, 3, 4, or 6 to run a screensaver, or enter 5 to quit.\n", getch());  // prompt the user\r
966                                                 scanf("%d", &key);\r
967                                                 //if(key==3){xx=yy=0;} // crazy screen saver wwww\r
968                                                 if(key==5) d=0;\r
969                                                 setvideo(1);\r
970                                 }\r
971                 }*/ // else off\r
972                 while(!kbhit()){ // conditions of screen saver\r
973                         ding(4);\r
974                 }\r
975                 //end of screen savers\r
976 //              doTest();\r
977                 getch();\r
978 \r
979                 while(!kbhit()){ // conditions of screen saver\r
980 //                      hScroll(1);\r
981 //                      scrolly(1);\r
982 //                      delay(100);
983                         Play();\r
984                 }\r
985 //++++0000\r
986                 setvideo(0);\r
987 //mxTerm();\r
988 //mxGetVersion();\r
989                 puts("Where to next?  It's your move! wwww");\r
990                 printf("bakapi ver. 1.04.09.03\nis made by sparky4\81i\81\86\83Ö\81\85\81j feel free to use it ^^\nLicence: GPL v2\n");\r
991                 return 0;\r
992                 }\r
993 \r
994 #endif\r