]> 4ch.mooo.com Git - 16.git/blob - 16/PCGPE10/TUT2.TXT
modified: 16/DOS_GFX.EXE
[16.git] / 16 / PCGPE10 / TUT2.TXT
1                    ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸\r
2                    ³         W E L C O M E         ³\r
3                    ³  To the VGA Trainer Program   ³ ³\r
4                    ³              By               ³ ³\r
5                    ³      DENTHOR of ASPHYXIA      ³ ³ ³\r
6                    ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ³ ³\r
7                      ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³\r
8                        ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
9 \r
10                            --==[ PART 2 ]==--\r
11 \r
12 \r
13 \r
14 þ Introduction\r
15 \r
16 \r
17 \r
18 Hi there again! This is Grant Smith, AKA Denthor of ASPHYXIA. This is the\r
19 second part of my Training Program for new programmers. I have only had a\r
20 lukewarm response to my first part of the trainer series ... remember, if\r
21 I don't hear from you, I will assume that you are all dead and will stop\r
22 writing the series ;-). Also, if you do get in contact with me I will give\r
23 you some of our fast assembly routines which will speed up your demos no\r
24 end. So go on, leave mail to GRANT SMITH in the main section of the\r
25 MailBox BBS, start up a discussion or ask a few questions in this Conference,\r
26 leave mail to ASPHYXIA on the ASPHYXIA BBS, leave mail to Denthor on\r
27 Connectix, or write to Grant Smith,\r
28                        P.O.Box 270\r
29                        Kloof\r
30                        3640\r
31 See, there are many ways you can get in contact with me! Use one of them!\r
32 \r
33 In this part, I will put the Pallette through it's paces. What the hell is\r
34 a pallette? How do I find out what it is? How do I set it? How do I stop\r
35 the "fuzz" that appears on the screen when I change the pallette? How do\r
36 I black out the screen using the pallette? How do I fade in a screen?\r
37 How do I fade out a screen? Why are telephone calls so expensive?\r
38 Most of these quesions will be answered in this, the second part of my\r
39 Trainer Series for Pascal.\r
40 \r
41 \r
42 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
43 þ  What is the Pallette?\r
44 \r
45 A few weeks ago a friend of mine was playing a computer game. In the game\r
46 there was a machine with stripes of blue running across it. When the\r
47 machine was activated, while half of the the blue stripes stayed the same,\r
48 the other half started to change color and glow. He asked me how two stripes\r
49 of the same color suddenly become different like that. The answer is simple:\r
50 the program was changing the pallette. As you know from Part 1, there are\r
51 256 colors in MCGA mode, numbered 0 to 255. What you don't know is that each\r
52 if those colors is made up of different intensities of Red, Green and Blue,\r
53 the primary colors (you should have learned about the primary colors at\r
54 school). These intensities are numbers between 0 and 63. The color of\r
55 bright red would for example be obtained by setting red intensity to 63,\r
56 green intensity to 0, and blue intensity to 0. This means that two colors\r
57 can look exactly the same, eg you can set color 10 to bright red and color\r
58 78 to color bright red. If you draw a picture using both of those colors,\r
59 no-one will be able to tell the difference between the two.. It is only\r
60 when you again change the pallette of either of them will they be able to\r
61 tell the difference. Also, by changing the whole pallette, you can obtain\r
62 the "Fade in" and "Fade out" effects found in many demos and games.\r
63 Pallette manipulation can become quite confusing to some people, because\r
64 colors that look the same are in fact totally seperate.\r
65 \r
66 \r
67 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
68 þ  How do I read in the pallette value of a color?\r
69 \r
70 This is very easy to do. To read in the pallette value, you enter in the\r
71 number of the color you want into port $3c7, then read in the values of\r
72 red, green and blue respectively from port $3c9. Simple, huh? Here is a\r
73 procedure that does it for you :\r
74 \r
75 Procedure GetPal(ColorNo : Byte; Var R,G,B : Byte);\r
76   { This reads the values of the Red, Green and Blue values of a certain\r
77     color and returns them to you. }\r
78 Begin\r
79    Port[$3c7] := ColorNo;\r
80    R := Port[$3c9];\r
81    G := Port[$3c9];\r
82    B := Port[$3c9];\r
83 End;\r
84 \r
85 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
86 þ  How do I set the pallette value of a color?\r
87 \r
88 This is also as easy as 3.1415926535897932385. What you do is you enter in\r
89 the number of the color you want to change into port $3c8, then enter the\r
90 values of red, green and blue respectively into port $3c9. Because you are\r
91 all so lazy I have written the procedure for you ;-)\r
92 \r
93 \r
94 Procedure Pal(ColorNo : Byte; R,G,B : Byte);\r
95   { This sets the Red, Green and Blue values of a certain color }\r
96 Begin\r
97    Port[$3c8] := ColorNo;\r
98    Port[$3c9] := R;\r
99    Port[$3c9] := G;\r
100    Port[$3c9] := B;\r
101 End;\r
102 \r
103 \r
104 Asphyxia doesn't use the above pallete procedures, we use assembler versions,\r
105 which will be given to PEOPLE WHO RESPOND TO THIS TRAINER SERIES (HINT,\r
106 HINT)\r
107 \r
108 \r
109 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
110 þ  How do I stop the "fuzz" that appears on my screen when I change the\r
111         pallette?\r
112 \r
113 If you have used the pallette before, you will have noticed that there is\r
114 quite a bit of "fuzz" on the screen when you change it. The way we counter\r
115 this is as follows : There is an elctron beam on your monitor that is\r
116 constantly updating your screen from top to bottom. As it gets to the\r
117 bottom of the screen, it takes a while for it to get back up to the top of\r
118 the screen to start updating the screen again. The period where it moves\r
119 from the bottom to the top is called the Verticle Retrace. During the\r
120 verticle retrace you may change the pallette without affecting what is\r
121 on the screen. What we do is that we wait until a verticle retrace has\r
122 started by calling a certain procedure; this means that everything we do\r
123 now will only be shown after the verticle retrace, so we can do all sorts\r
124 of strange and unusual things to the screen during this retrace and only\r
125 the results will be shown when the retrace is finished. This is way cool,\r
126 as it means that when we change the pallette, the fuzz doesn't appear on\r
127 the screen, only the result (the changed pallette), is seen after the\r
128 retrace! Neat, huh? ;-) I have put the purely assembler WaitRetrace routine\r
129 in the sample code that follows this message. Use it wisely, my son.\r
130 \r
131 NOTE : WaitRetrace can be a great help to your coding ... code that fits\r
132        into one retrace will mean that the demo will run at the same\r
133        speed no matter what your computer speed (unless you are doing a lot\r
134        during the WaitRetrace and the computer is slooooow). Note that in\r
135        the following sample program and in our SilkyDemo, the thing will run\r
136        at the same speed whether turbo is on or off.\r
137 \r
138 \r
139 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
140 þ  How do I black out the screen using the pallette?\r
141 \r
142 This is basic : just set the Red, Green and Blue values of all colors to\r
143 zero intensity, like so :\r
144 \r
145 Procedure Blackout;\r
146   { This procedure blackens the screen by setting the pallette values of\r
147     all the colors to zero. }\r
148 VAR loop1:integer;\r
149 BEGIN\r
150   WaitRetrace;\r
151   For loop1:=0 to 255 do\r
152     Pal (loop1,0,0,0);\r
153 END;\r
154 \r
155 \r
156 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
157 þ  How do I fade in a screen?\r
158 \r
159 Okay, this can be VERY effective. What you must first do is grab the\r
160 pallette into a variable, like so :\r
161 \r
162    VAR Pall := Array [0.255,1..3] of BYTE;\r
163 \r
164 0 to 255 is for the 256 colors in MCGA mode, 1 to 3 is red, green and blue\r
165 intensity values;\r
166 \r
167 Procedure GrabPallette;\r
168 VAR loop1:integer;\r
169 BEGIN\r
170   For loop1:=0 to 255 do\r
171     Getpal (loop1,pall[loop1,1],pall[loop1,2],pall[loop1,3]);\r
172 END;\r
173 \r
174 This loads the entire pallette into variable pall. Then you must blackout\r
175 the screen (see above), and draw what you want to screen without the\r
176 construction being shown. Then what you do is go throgh the pallette. For\r
177 each color, you see if the individual intensities are what they should be.\r
178 If not, you increase them by one unit until they are. Beacuse intensites\r
179 are in a range from 0 to 63, you only need do this a maximum of 64 times.\r
180 \r
181 Procedure Fadeup;\r
182 VAR loop1,loop2:integer;\r
183     Tmp : Array [1..3] of byte;\r
184       { This is temporary storage for the values of a color }\r
185 BEGIN\r
186   For loop1:=1 to 64 do BEGIN\r
187       { A color value for Red, green or blue is 0 to 63, so this loop only\r
188         need be executed a maximum of 64 times }\r
189     WaitRetrace;\r
190     For loop2:=0 to 255 do BEGIN\r
191       Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);\r
192       If Tmp[1]<Pall[loop2,1] then inc (Tmp[1]);\r
193       If Tmp[2]<Pall[loop2,2] then inc (Tmp[2]);\r
194       If Tmp[3]<Pall[loop2,3] then inc (Tmp[3]);\r
195         { If the Red, Green or Blue values of color loop2 are less then they\r
196           should be, increase them by one. }\r
197       Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);\r
198         { Set the new, altered pallette color. }\r
199     END;\r
200   END;\r
201 END;\r
202 \r
203 Hey-presto! The screen fades up. You can just add in a delay before the\r
204 waitretrace if you feel it is too fast. Cool, no?\r
205 \r
206 \r
207 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
208 þ  How do I fade out a screen?\r
209 \r
210 This is just like the fade in of a screen, just in the opposite direction.\r
211 What you do is you check each color intensity. If it is not yet zero, you\r
212 decrease it by one until it is. BAAASIIIC!\r
213 \r
214 Procedure FadeDown;\r
215 VAR loop1,loop2:integer;\r
216     Tmp : Array [1..3] of byte;\r
217       { This is temporary storage for the values of a color }\r
218 BEGIN\r
219   For loop1:=1 to 64 do BEGIN\r
220     WaitRetrace;\r
221     For loop2:=0 to 255 do BEGIN\r
222       Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);\r
223       If Tmp[1]>0 then dec (Tmp[1]);\r
224       If Tmp[2]>0 then dec (Tmp[2]);\r
225       If Tmp[3]>0 then dec (Tmp[3]);\r
226         { If the Red, Green or Blue values of color loop2 are not yet zero,\r
227           then, decrease them by one. }\r
228       Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);\r
229         { Set the new, altered pallette color. }\r
230     END;\r
231   END;\r
232 END;\r
233 \r
234 Again, to slow the above down, put in a delay above the WaitRetrace. Fading\r
235 out the screen looks SO much more impressive then just clearing the screen;\r
236 it can make a world of difference in the impression your demo etc will\r
237 leave on the people viewing it. To restore the pallette, just do this :\r
238 \r
239 Procedure RestorePallette;\r
240 VAR loop1:integer;\r
241 BEGIN\r
242   WaitRetrace;\r
243   For loop1:=0 to 255 do\r
244     pal (loop1,Pall[loop1,1],Pall[loop1,2],Pall[loop1,3]);\r
245 END;\r
246 \r
247 \r
248 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
249 þ  In closing\r
250 \r
251 Well, there are most of those origional questions answered ;-) The following\r
252 sample program is quite big, so it might take you a while to get around it.\r
253 Persevere and thou shalt overcome. Pallette manipulation has been a thorn\r
254 in many coders sides for quite some time, yet hopefully I have shown you\r
255 all how amazingly simple it is once you have grasped the basics.\r
256 \r
257 I need more feedback! In which direction would you like me to head? Is there\r
258 any particular section you would like more info on? Also, upload me your\r
259 demo's, however trivial they might seem. We really want to get in contact\r
260 with/help out new and old coders alike, but you have to leave us that message\r
261 telling us about yourself and what you have done or want to do.\r
262 \r
263 IS THERE ANYBODY OUT THERE!?!\r
264 \r
265 P.S. Our new demo should be out soon ... it is going to be GOOOD ... keep\r
266      an eye out for it.\r
267 \r
268           [ And so she came across him, slumped over his keyboard\r
269             yet again . 'It's three in the morning' she whispered.\r
270             'Let's get you to bed'. He stirred, his face bathed in\r
271             the dull light of his monitor. He mutters something.\r
272             As she leans across him to disconnect the power, she\r
273             asks him; 'Was it worth it?'. His answer surprises her.\r
274             'No.' he says. In his caffiene-enduced haze, he smiles.\r
275             'But it sure is a great way to relax.'                  ]\r
276                                            - Grant Smith\r
277                                               Tue 13 July, 1993\r
278                                                2:23 am.\r
279 \r
280 See you next week!\r
281    - Denthor\r
282 \r
283 \r
284 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
285 ³ TUTPROG2.PAS ³\r
286 ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
287 \r
288 {$X+}\r
289 \r
290 Uses Crt;\r
291 \r
292 CONST VGA=$a000;\r
293 \r
294 Var Pall,Pall2 : Array[0..255,1..3] of Byte;\r
295      { This declares the PALL variable. 0 to 255 signify the colors of the\r
296        pallette, 1 to 3 signifies the Red, Green and Blue values. I am\r
297        going to use this as a sort of "virtual pallette", and alter it\r
298        as much as I want, then suddenly bang it to screen. Pall2 is used\r
299        to "remember" the origional pallette so that we can restore it at\r
300        the end of the program. }\r
301 \r
302 \r
303 \r
304 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
305 Procedure SetMCGA;  { This procedure gets you into 320x200x256 mode. }\r
306 BEGIN\r
307   asm\r
308      mov        ax,0013h\r
309      int        10h\r
310   end;\r
311 END;\r
312 \r
313 \r
314 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
315 Procedure SetText;  { This procedure returns you to text mode.  }\r
316 BEGIN\r
317   asm\r
318      mov        ax,0003h\r
319      int        10h\r
320   end;\r
321 END;\r
322 \r
323 \r
324 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
325 procedure WaitRetrace; assembler;\r
326   { This waits until you are in a Verticle Retrace ... this means that all\r
327     screen manipulation you do only appears on screen in the next verticle\r
328     retrace ... this removes most of the "fuzz" that you see on the screen\r
329     when changing the pallette. It unfortunately slows down your program\r
330     by "synching" your program with your monitor card ... it does mean\r
331     that the program will run at almost the same speed on different\r
332     speeds of computers which have similar monitors. In our SilkyDemo,\r
333     we used a WaitRetrace, and it therefore runs at the same (fairly\r
334     fast) speed when Turbo is on or off. }\r
335 \r
336 label\r
337   l1, l2;\r
338 asm\r
339     mov dx,3DAh\r
340 l1:\r
341     in al,dx\r
342     and al,08h\r
343     jnz l1\r
344 l2:\r
345     in al,dx\r
346     and al,08h\r
347     jz  l2\r
348 end;\r
349 \r
350 \r
351 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
352 Procedure GetPal(ColorNo : Byte; Var R,G,B : Byte);\r
353   { This reads the values of the Red, Green and Blue values of a certain\r
354     color and returns them to you. }\r
355 Begin\r
356    Port[$3c7] := ColorNo;\r
357    R := Port[$3c9];\r
358    G := Port[$3c9];\r
359    B := Port[$3c9];\r
360 End;\r
361 \r
362 \r
363 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
364 Procedure Pal(ColorNo : Byte; R,G,B : Byte);\r
365   { This sets the Red, Green and Blue values of a certain color }\r
366 Begin\r
367    Port[$3c8] := ColorNo;\r
368    Port[$3c9] := R;\r
369    Port[$3c9] := G;\r
370    Port[$3c9] := B;\r
371 End;\r
372 \r
373 \r
374 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
375 Procedure Putpixel (X,Y : Integer; Col : Byte);\r
376   { This puts a pixel on the screen by writing directly to memory. }\r
377 BEGIN\r
378   Mem [VGA:X+(Y*320)]:=Col;\r
379 END;\r
380 \r
381 \r
382 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
383 Procedure line(a,b,c,d,col:integer);\r
384   { This draws a line from a,b to c,d of color col. }\r
385    Function sgn(a:real):integer;\r
386    BEGIN\r
387         if a>0 then sgn:=+1;\r
388         if a<0 then sgn:=-1;\r
389         if a=0 then sgn:=0;\r
390    END;\r
391 var u,s,v,d1x,d1y,d2x,d2y,m,n:real;\r
392     i:integer;\r
393 BEGIN\r
394      u:= c - a;\r
395      v:= d - b;\r
396      d1x:= SGN(u);\r
397      d1y:= SGN(v);\r
398      d2x:= SGN(u);\r
399      d2y:= 0;\r
400      m:= ABS(u);\r
401      n := ABS(v);\r
402      IF NOT (M>N) then\r
403      BEGIN\r
404           d2x := 0 ;\r
405           d2y := SGN(v);\r
406           m := ABS(v);\r
407           n := ABS(u);\r
408      END;\r
409      s := INT(m / 2);\r
410      FOR i := 0 TO round(m) DO\r
411      BEGIN\r
412           putpixel(a,b,col);\r
413           s := s + n;\r
414           IF not (s<m) THEN\r
415           BEGIN\r
416                s := s - m;\r
417                a:= a +round(d1x);\r
418                b := b + round(d1y);\r
419           END\r
420           ELSE\r
421           BEGIN\r
422                a := a + round(d2x);\r
423                b := b + round(d2y);\r
424           END;\r
425      END;\r
426 END;\r
427 \r
428 \r
429 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
430 Procedure PalPlay;\r
431   { This procedure mucks about with our "virtual pallette", then shoves it\r
432     to screen. }\r
433 Var Tmp : Array[1..3] of Byte;\r
434   { This is used as a "temporary color" in our pallette }\r
435     loop1 : Integer;\r
436 BEGIN\r
437    Move(Pall[200],Tmp,3);\r
438      { This copies color 200 from our virtual pallette to the Tmp variable }\r
439    Move(Pall[0],Pall[1],200*3);\r
440      { This moves the entire virtual pallette up one color }\r
441    Move(Tmp,Pall[0],3);\r
442      { This copies the Tmp variable to the bottom of the virtual pallette }\r
443    WaitRetrace;\r
444    For loop1:=1 to 255 do\r
445      pal (loop1,pall[loop1,1],pall[loop1,2],pall[loop1,3]);\r
446 END;\r
447 \r
448 \r
449 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
450 Procedure SetUpScreen;\r
451   { This gets our screen ready but setting up the pallette and drawing\r
452     the lines. }\r
453 Var Loop : Integer;\r
454 BEGIN\r
455    FillChar(Pall,SizeOf(Pall),0);\r
456        { Clear the entire PALL variable to zero. }\r
457    For Loop := 0 to 200 do BEGIN\r
458       Pall[Loop,1] := Loop mod 64;\r
459    END;\r
460        { This sets colors 0 to 200 in the PALL variable to values between\r
461          0 to 63. the MOD function gives you the remainder of a division,\r
462          ie. 105 mod 10 = 5 }\r
463 \r
464    For Loop := 1 to 320 do BEGIN\r
465       Line(319,199,320-Loop,0,(Loop Mod 199)+1);\r
466       Line(0,0,Loop,199,(Loop Mod 199)+1);\r
467        { These two lines start drawing lines from the left and the right\r
468          hand sides of the screen, using colors 1 to 199. Look at these\r
469          two lines and understand them. }\r
470       PalPlay;\r
471         { This calls the PalPlay procedure }\r
472    END;\r
473 END;\r
474 \r
475 \r
476 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
477 Procedure GrabPallette;\r
478 VAR loop1:integer;\r
479 BEGIN\r
480   For loop1:=0 to 255 do\r
481     Getpal (loop1,pall2[loop1,1],pall2[loop1,2],pall2[loop1,3]);\r
482 END;\r
483 \r
484 \r
485 \r
486 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
487 Procedure Blackout;\r
488   { This procedure blackens the screen by setting the pallette values of\r
489     all the colors to zero. }\r
490 VAR loop1:integer;\r
491 BEGIN\r
492   WaitRetrace;\r
493   For loop1:=0 to 255 do\r
494     Pal (loop1,0,0,0);\r
495 END;\r
496 \r
497 \r
498 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
499 Procedure HiddenScreenSetup;\r
500   { This procedure sets up the screen while it is blacked out, so that the\r
501     user can't see what is happening. }\r
502 VAR loop1,loop2:integer;\r
503 BEGIN\r
504   For loop1:=0 to 319 do\r
505     For loop2:=0 to 199 do\r
506       PutPixel (loop1,loop2,Random (256));\r
507 END;\r
508 \r
509 \r
510 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
511 Procedure Fadeup;\r
512   { This procedure slowly fades up the new screen }\r
513 VAR loop1,loop2:integer;\r
514     Tmp : Array [1..3] of byte;\r
515       { This is temporary storage for the values of a color }\r
516 BEGIN\r
517   For loop1:=1 to 64 do BEGIN\r
518       { A color value for Red, green or blue is 0 to 63, so this loop only\r
519         need be executed a maximum of 64 times }\r
520     WaitRetrace;\r
521     For loop2:=0 to 255 do BEGIN\r
522       Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);\r
523       If Tmp[1]<Pall2[loop2,1] then inc (Tmp[1]);\r
524       If Tmp[2]<Pall2[loop2,2] then inc (Tmp[2]);\r
525       If Tmp[3]<Pall2[loop2,3] then inc (Tmp[3]);\r
526         { If the Red, Green or Blue values of color loop2 are less then they\r
527           should be, increase them by one. }\r
528       Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);\r
529         { Set the new, altered pallette color. }\r
530     END;\r
531   END;\r
532 END;\r
533 \r
534 \r
535 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
536 Procedure FadeDown;\r
537   { This procedure fades the screen out to black. }\r
538 VAR loop1,loop2:integer;\r
539     Tmp : Array [1..3] of byte;\r
540       { This is temporary storage for the values of a color }\r
541 BEGIN\r
542   For loop1:=1 to 64 do BEGIN\r
543     WaitRetrace;\r
544     For loop2:=0 to 255 do BEGIN\r
545       Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);\r
546       If Tmp[1]>0 then dec (Tmp[1]);\r
547       If Tmp[2]>0 then dec (Tmp[2]);\r
548       If Tmp[3]>0 then dec (Tmp[3]);\r
549         { If the Red, Green or Blue values of color loop2 are not yet zero,\r
550           then, decrease them by one. }\r
551       Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);\r
552         { Set the new, altered pallette color. }\r
553     END;\r
554   END;\r
555 END;\r
556 \r
557 \r
558 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
559 Procedure RestorePallette;\r
560   { This procedure restores the origional pallette }\r
561 VAR loop1:integer;\r
562 BEGIN\r
563   WaitRetrace;\r
564   For loop1:=0 to 255 do\r
565     pal (loop1,Pall2[loop1,1],Pall2[loop1,2],Pall2[loop1,3]);\r
566 END;\r
567 \r
568 \r
569 BEGIN\r
570   ClrScr;\r
571   Writeln ('This program will draw lines of different colors across the');\r
572   Writeln ('screen and change them only by changing their pallette values.');\r
573   Writeln ('The nice thing about using the pallette is that one pallette');\r
574   Writeln ('change changes the same color over the whole screen, without');\r
575   Writeln ('you having to redraw it. Because I am using a WaitRetrace');\r
576   Writeln ('command, turning on and off your turbo during the demonstration');\r
577   Writeln ('should have no effect.');\r
578   Writeln;\r
579   Writeln ('The second part of the demo blacks out the screen using the');\r
580   Writeln ('pallette, fades in the screen, waits for a keypress, then fades');\r
581   Writeln ('it out again. I haven''t put in any delays for the fadein/out,');\r
582   Writeln ('so you will have to put ''em in yourself to get it to the speed you');\r
583   Writeln ('like. Have fun and enjoy! ;-)');\r
584   Writeln; Writeln;\r
585   Writeln ('Hit any key to continue ...');\r
586   Readkey;\r
587   SetMCGA;\r
588   GrabPallette;\r
589   SetUpScreen;\r
590   repeat\r
591      PalPlay;\r
592        { Call the PalPlay procedure repeatedly until a key is pressed. }\r
593   Until Keypressed;\r
594   Readkey;\r
595     { Read in the key pressed otherwise it is left in the keyboard buffer }\r
596   Blackout;\r
597   HiddenScreenSetup;\r
598   FadeUp;\r
599   Readkey;\r
600   FadeDown;\r
601   Readkey;\r
602   RestorePallette;\r
603   SetText;\r
604   Writeln ('All done. This concludes the second sample program in the ASPHYXIA');\r
605   Writeln ('Training series. You may reach DENTHOR under the name of GRANT');\r
606   Writeln ('SMITH on the MailBox BBS, or leave a message to ASPHYXIA on the');\r
607   Writeln ('ASPHYXIA BBS. Get the numbers from Roblist, or write to :');\r
608   Writeln ('             Grant Smith');\r
609   Writeln ('             P.O. Box 270');\r
610   Writeln ('             Kloof');\r
611   Writeln ('             3640');\r
612   Writeln ('I hope to hear from you soon!');\r
613   Writeln; Writeln;\r
614   Write   ('Hit any key to exit ...');\r
615   Readkey;\r
616 END.\r