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