]> 4ch.mooo.com Git - 16.git/blob - 16/PCGPE10/TUT4.TXT
modified: 16/modex16/scroll.c
[16.git] / 16 / PCGPE10 / TUT4.TXT
1 \r
2                    ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸\r
3                    ³         W E L C O M E         ³\r
4                    ³  To the VGA Trainer Program   ³ ³\r
5                    ³              By               ³ ³\r
6                    ³      DENTHOR of ASPHYXIA      ³ ³ ³\r
7                    ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ³ ³\r
8                      ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³\r
9                        ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
10 \r
11                            --==[ PART 4 ]==--\r
12 \r
13 \r
14 \r
15 þ Introduction\r
16 \r
17 \r
18 Howdy all! Welcome to the fourth part of this trainer series! It's a\r
19 little late, but I am sure you will find that the wait was worth it,\r
20 becase today I am going to show you how to use a very powerful tool :\r
21 Virtual Screens.\r
22 \r
23 If you would like to contact me, or the team, there are many ways you\r
24 can do it : 1) Write a message to Grant Smith in private mail here on\r
25                   the Mailbox BBS.\r
26             2) Write a message here in the Programming conference here\r
27                   on the Mailbox (Preferred if you have a general\r
28                   programming query or problem others would benefit from)\r
29             3) Write to ASPHYXIA on the ASPHYXIA BBS.\r
30             4) Write to Denthor, Eze or Livewire on Connectix.\r
31             5) Write to :  Grant Smith\r
32                            P.O.Box 270 Kloof\r
33                            3640\r
34             6) Call me (Grant Smith) at 73 2129 (leave a message if you\r
35                   call during varsity)\r
36 \r
37 NB : If you are a representative of a company or BBS, and want ASPHYXIA\r
38        to do you a demo, leave mail to me; we can discuss it.\r
39 NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling\r
40         quite lonely and want to meet/help out/exchange code with other demo\r
41         groups. What do you have to lose? Leave a message here and we can work\r
42         out how to transfer it. We really want to hear from you!\r
43 \r
44 \r
45 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
46 þ  What is a Virtual Screen and why do we need it?\r
47 \r
48 Let us say you are generating a complex screen numerous times on the fly\r
49 (for example scrolling up the screen then redrawing all the sprites for\r
50 each frame of a game you are writing.) Do you have any idea how awful it\r
51 would look if the user could actually see you erasing and redrawing each\r
52 sprite for each frame? Can you visualise the flicker effect this would\r
53 give off? Do you realise that there would be a "sprite doubling" effect\r
54 (where you see two copies of the same sprite next to each other)? In the\r
55 sample program I have included a part where I do not use virtual screens\r
56 to demonstrate these problems. Virtual screens are not the only way to\r
57 solve these problems, but they are definately the easiest to code in.\r
58 \r
59 A virtual screen is this : a section of memory set aside that is exactly\r
60 like the VGA screen on which you do all your working, then "flip" it\r
61 on to your true screen. In EGA 640x350x16 you automatically have a\r
62 virtual page, and it is possible to have up to four on the MCGA using a\r
63 particular tweaked mode, but for our puposes we will set one up using base\r
64 memory.\r
65 \r
66 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
67 þ  Setting up a virtual screen\r
68 \r
69 As you will have seen in the first part of this trainer series, the MCGA\r
70 screen is 64000 bytes big (320x200=64000). You may also have noticed that\r
71 in TP 6.0 you arn't allowed too much space for normal variables. For\r
72 example, saying :\r
73 \r
74 VAR Virtual : Array [1..64000] of byte;\r
75 \r
76 would be a no-no, as you wouldn't have any space for your other variables.\r
77 What is the solution? I hear you enquiring minds cry. The answer : pointers!\r
78 Pointers to not use up the base 64k allocated to you by TP 6.0, it gets\r
79 space from somewhere else in the base 640k memory of your computer. Here is\r
80 how you set them up :\r
81 \r
82 Type Virtual = Array [1..64000] of byte;  { The size of our Virtual Screen }\r
83      VirtPtr = ^Virtual;                  { Pointer to the virtual screen }\r
84 \r
85 VAR Virscr : VirtPtr;                      { Our first Virtual screen }\r
86     Vaddr  : word;                        { The segment of our virtual screen}\r
87 \r
88 If you put this in a program as it stands, and try to acess VirScr, your\r
89 machine will probably crash. Why? Because you have to get the memory for\r
90 your pointers before you can acess them! You do that as follows :\r
91 \r
92 Procedure SetUpVirtual;\r
93 BEGIN\r
94   GetMem (VirScr,64000);\r
95   vaddr := seg (virscr^);\r
96 END;\r
97 \r
98 This procedure has got the memory for the screen, then set vaddr to the\r
99 screens segment. DON'T EVER LEAVE THIS PROCEDURE OUT OF YOUR PROGRAM!\r
100 If you leave it out, when you write to your virtual screen you will probably\r
101 be writing over DOS or some such thing. Not a good plan ;-).\r
102 \r
103 When you have finished your program, you will want to free the memory\r
104 taken up by the virtual screen by doing the following :\r
105 \r
106 Procedure ShutDown;\r
107 BEGIN\r
108   FreeMem (VirScr,64000);\r
109 END;\r
110 \r
111 If you don't do this your other programs will have less memory to use for\r
112 themselves.\r
113 \r
114 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
115 þ  Putting a pixel to your virtual screen\r
116 \r
117 This is very similar to putting a pixel to your normal MCGA screen, as\r
118 discussed in part one... here is our origonal putpixel :\r
119 \r
120 Procedure PutPixel (X,Y : Integer; Col : Byte);\r
121 BEGIN\r
122   Mem [VGA:X+(Y*320)]:=col;\r
123 END;\r
124 \r
125 For our virtual screen, we do the following :\r
126 \r
127 Procedure VirtPutPixel (X,Y : Integer; Col : Byte);\r
128 BEGIN\r
129   Mem [Vaddr:X+(Y*320)]:=col;\r
130 END;\r
131 \r
132 It seems quite wasteful to have two procedures doing exactly the same thing,\r
133 just to different screens, doesn't it? So why don't we combine the two like\r
134 this :\r
135 \r
136 Procedure PutPixel (X,Y : Integer; Col : Byte; Where : Word);\r
137 BEGIN\r
138   Mem [Where:X+(Y*320)]:=col;\r
139 END;\r
140 \r
141 To use this, you will say something like :\r
142 \r
143 Putpixel (20,20,32,VGA);\r
144 PutPixel (30,30,64,Vaddr);\r
145 \r
146 These two statements draw two pixels ... one to the VGA screen and one to\r
147 the virtual screen! Doesn't that make you jump  with joy! ;-) You will\r
148 have noticed that we still can't actually SEE the virtual screen, so on to\r
149 the next part ...\r
150 \r
151 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
152 þ  How to "Flip" your virtual screen on to the true screen\r
153 \r
154 You in fact already have to tools to do this yourselves from information\r
155 in the previous parts of this trainer series. We will of course use the\r
156 Move command, like so :\r
157 \r
158 Move (Virscr^,mem [VGA:0],64000);\r
159 \r
160 simple, eh? Yuo may want to wait for a verticle retrace (Part 2) before you\r
161 do that, as it may make the flip much smoother (and, alas, slower).\r
162 \r
163 Note that most of our other procedures may be altered to support the\r
164 virtual screen, such as Cls etc. (see Part 1 of this series), using the\r
165 methoods described above (I have altered the CLS procedure in the sample\r
166 program given at the end of this Part.)\r
167 \r
168 We of ASPHYXIA have used virtual screens in almost all of our demos.\r
169 Can you imagine how awful the SoftelDemo would have looked if you had to\r
170 watch us redrawing the moving background, text and vectorballs for EACH\r
171 FRAME? The flicker, doubling effects etc would have made it awful! So\r
172 we used a virtual screen, and are very pleased with the result.\r
173 Note, though, that to get the speed we needed to get the demo fast enough,\r
174 we wrote our sprites routines, flip routines, pallette routines etc. all\r
175 in assembly. The move command is very fast, but not as fast as ASM ;-)\r
176 \r
177 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
178 þ  In closing\r
179 \r
180 I am writing this on the varsity computers in between lectures. I prefer\r
181 writing & coding between 6pm and 4am, but it isn't a good plan when\r
182 varsity is on ;-), so this is the first part of the trainer series ever\r
183 written before 9pm.\r
184 \r
185 I have been asked to do a part on scrolling the screen, so that is\r
186 probably what I will do for next week. Also, ASPHYXIA will soon be putting\r
187 up a small demo with source on the local boards. It will use routines\r
188 that we have discussed in this series, and demonstrate how powerful these\r
189 routines can be if used in the correct manner.\r
190 \r
191 Some projects for you to do :\r
192   1) Rewrite the flip statement so that you can say :\r
193         flip (Vaddr,VGA);\r
194         flip (VGA,Vaddr);\r
195       ( This is how ASPHYXIAS one works )\r
196 \r
197   2) Put most of the routines (putpixel, cls, pal etc.) into a unit,\r
198      so that you do not need to duplicate the procedures in each program\r
199      you write. If you need help, leave me mail.\r
200 \r
201 \r
202 See you next week\r
203    - Denthor\r
204 \r
205 \r
206 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
207 ³ TUTPROG4.PAS ³\r
208 ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
209 \r
210 {$X+}   (* This is a handy little trick to know. If you put this at the top\r
211            of your program, you do not have to set a variable when calling\r
212            a function, i.e. you may just say 'READKEY' instead of\r
213            'CH:=READKEY'                                                *)\r
214 \r
215 USES Crt;           (* This has a few nice functions in it, such as the\r
216                        READKEY command.                                 *)\r
217 \r
218 CONST VGA = $a000;  (* This sets the constant VGA to the segment of the\r
219                        VGA screen.                                      *)\r
220 \r
221 Type Virtual = Array [1..64000] of byte;  { The size of our Virtual Screen }\r
222      VirtPtr = ^Virtual;                  { Pointer to the virtual screen }\r
223 \r
224 VAR Virscr : VirtPtr;                      { Our first Virtual screen }\r
225     Vaddr  : word;                        { The segment of our virtual screen}\r
226 \r
227 \r
228 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
229 Procedure SetMCGA;  { This procedure gets you into 320x200x256 mode. }\r
230 BEGIN\r
231   asm\r
232      mov        ax,0013h\r
233      int        10h\r
234   end;\r
235 END;\r
236 \r
237 \r
238 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
239 Procedure SetText;  { This procedure returns you to text mode.  }\r
240 BEGIN\r
241   asm\r
242      mov        ax,0003h\r
243      int        10h\r
244   end;\r
245 END;\r
246 \r
247 \r
248 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
249 Procedure Cls (Col : Byte; Where:Word);\r
250    { This clears the screen to the specified color, on the VGA or on the\r
251         virtual screen }\r
252 BEGIN\r
253   Fillchar (Mem [where:0],64000,col);\r
254 END;\r
255 \r
256 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
257 procedure WaitRetrace; assembler;\r
258   { This waits until you are in a Verticle Retrace ... this means that all\r
259     screen manipulation you do only appears on screen in the next verticle\r
260     retrace ... this removes most of the "fuzz" that you see on the screen\r
261     when changing the pallette. It unfortunately slows down your program\r
262     by "synching" your program with your monitor card ... it does mean\r
263     that the program will run at almost the same speed on different\r
264     speeds of computers which have similar monitors. In our SilkyDemo,\r
265     we used a WaitRetrace, and it therefore runs at the same (fairly\r
266     fast) speed when Turbo is on or off. }\r
267 \r
268 label\r
269   l1, l2;\r
270 asm\r
271     mov dx,3DAh\r
272 l1:\r
273     in al,dx\r
274     and al,08h\r
275     jnz l1\r
276 l2:\r
277     in al,dx\r
278     and al,08h\r
279     jz  l2\r
280 end;\r
281 \r
282 \r
283 \r
284 \r
285 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
286 Procedure SetUpVirtual;\r
287    { This sets up the memory needed for the virtual screen }\r
288 BEGIN\r
289   GetMem (VirScr,64000);\r
290   vaddr := seg (virscr^);\r
291 END;\r
292 \r
293 \r
294 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
295 Procedure ShutDown;\r
296    { This frees the memory used by the virtual screen }\r
297 BEGIN\r
298   FreeMem (VirScr,64000);\r
299 END;\r
300 \r
301 \r
302 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
303 Procedure PutPixel (X,Y : Integer; Col : Byte; Where : Word);\r
304    { This puts a pixel at X,Y using color col, on VGA or the Virtual Screen}\r
305 BEGIN\r
306   Mem [Where:X+(Y*320)]:=col;\r
307 END;\r
308 \r
309 \r
310 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
311 Procedure Flip;\r
312    { This flips the virtual screen to the VGA screen. }\r
313 BEGIN\r
314   Move (Virscr^,mem [VGA:0],64000);\r
315 END;\r
316 \r
317 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
318 Procedure BlockMove;\r
319    { This tests various ways of moving a block around the screen }\r
320 VAR loop1,loop2,loop3:Integer;\r
321 BEGIN\r
322   For loop1:=1 to 50 do BEGIN                     { This draw a block    }\r
323     for loop2:=1 to 50 do                         {  directly to VGA, no }\r
324       for loop3:=1 to 50 do                       {  flipping            }\r
325         putpixel (loop1+loop2,loop3,32,VGA);\r
326     cls (0,VGA);\r
327   END;\r
328 \r
329   For loop1:=1 to 50 do BEGIN                     { This draws a block     }\r
330     for loop2:=1 to 50 do                         { to the virtual screen, }\r
331       for loop3:=1 to 50 do                       { then flips it to VGA   }\r
332         putpixel (loop1+loop2,loop3,32,Vaddr);\r
333     flip;\r
334     cls (0,Vaddr);\r
335   END;\r
336 \r
337   For loop1:=1 to 50 do BEGIN                     { This draws a block     }\r
338     for loop2:=1 to 50 do                         { to the virtual screen, }\r
339       for loop3:=1 to 50 do                       { waits for a retrace,   }\r
340         putpixel (loop1+loop2,loop3,32,Vaddr);    { then flips it to VGA   }\r
341     waitretrace;\r
342     flip;\r
343     cls (0,Vaddr);\r
344   END;\r
345 END;\r
346 \r
347 \r
348 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}\r
349 Procedure PatternDraw;\r
350    { This test the speed of flipping by drawing two patterns and flipping\r
351      them }\r
352 VAR loop1,loop2:integer;\r
353 BEGIN\r
354   for loop1:=1 to 100 do                        { This draws pattern one }\r
355     for loop2:=1 to 100 do                      { to the virtual screen  }\r
356       putpixel (loop1,loop2,loop1,Vaddr);       { then flips it to VGA   }\r
357   flip;\r
358 \r
359   for loop1:=1 to 100 do                        { This draws pattern two }\r
360     for loop2:=1 to 100 do                      { to the virtual screen  }\r
361       putpixel (loop1,loop2,loop2,Vaddr);       { then flips it to VGA   }\r
362   flip;\r
363 END;\r
364 \r
365 \r
366 BEGIN\r
367   ClrScr;\r
368   Writeln ('This program will demonstrate the power of virtual screens.');\r
369   Writeln ('A block will firstly move across the screen, being drawn and');\r
370   Writeln ('erased totally on the VGA. Then the same block will move');\r
371   Writeln ('across, but will be drawn on the virtual screen and flipped');\r
372   Writeln ('to the VGA screen without a retrace (see part 2). The the');\r
373   Writeln ('block will go again, with flipping and a retrace.');\r
374   Writeln;\r
375   Writeln ('I will then draw a pattern, flip it to VGA, draw another');\r
376   Writeln ('pattern, flip it to VGA, and repeat that until a key is pressed.');\r
377   Writeln ('This will demonstrate that even when I put down 10000 pixels,');\r
378   Writeln ('then flip them to the VGA, it is still relatively fast.      ');\r
379   Writeln; Writeln;\r
380   Writeln ('Hit any key to continue ...');\r
381   readkey;\r
382   setmcga;\r
383   setupvirtual;\r
384   cls (0,vaddr);    { After you have got the memory for the virtual screen,\r
385                       it is usually filled with random garbage. It is always\r
386                       wise to clear the virtual screen directly afterwards }\r
387   BlockMove;\r
388 \r
389   Repeat\r
390     PatternDraw;\r
391   Until keypressed;\r
392 \r
393   Readkey;\r
394   settext;\r
395   shutdown;\r
396   Writeln ('All done. This concludes the fourth sample program in the ASPHYXIA');\r
397   Writeln ('Training series. You may reach DENTHOR under the name of GRANT');\r
398   Writeln ('SMITH on the MailBox BBS, or leave a message to ASPHYXIA on the');\r
399   Writeln ('ASPHYXIA BBS. Get the numbers from Roblist, or write to :');\r
400   Writeln ('             Grant Smith');\r
401   Writeln ('             P.O. Box 270');\r
402   Writeln ('             Kloof');\r
403   Writeln ('             3640');\r
404   Writeln ('I hope to hear from you soon!');\r
405   Writeln; Writeln;\r
406   Write   ('Hit any key to exit ...');\r
407   Readkey;\r
408 END.\r