1 ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
\r
3 ³ To the VGA Trainer Program ³ ³
\r
5 ³ DENTHOR of ASPHYXIA ³ ³ ³
\r
6 ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; ³ ³
\r
7 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
\r
8 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
\r
14 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
\r
17 Hi there! ASPHYXIA is BACK with our first MegaDemo, Psycho Neurosis! A
\r
18 paltry 1.3MB download is all it takes to see the group from Durbs first
\r
19 major production! We are quite proud of it, and think you should see it
\r
22 Secondly, I released a small little trainer (a trainerette ;-)) on
\r
23 RsaPROG and Connexctix BBS mail, also on the ASPHYXIA BBS as COPPERS.ZIP
\r
24 It is a small Pascal program demonstrating how to display copper bars in
\r
25 text mode. Also includes a check for horizontal retrace (A lot of people
\r
26 wanted it, that is why I wrote the program) (ASPHYXIA ... first with the
\r
27 trainer goodies ;-) aargh, sorry, had to be done ))
\r
29 Thirdly, sorry about the problems with Tut 8! If you had all the
\r
30 checking on, the tutorial would probably die on the first points. The
\r
31 reason is this : in the first loop, we have DrawPoints then
\r
32 RotatePoints. The variables used in DrawPoints are set in RotatePoints,
\r
33 so if you put RotatePoints before DrawPoints, the program should work
\r
34 fine. Alternatively, turn off error checking 8-)
\r
36 Fourthly, I have had a surprisingly large number of people saying that
\r
37 "I get this, like, strange '286 instructions not enabled' message!
\r
38 What's wrong with your code, dude?" To all of you, get into Pascal, hit
\r
39 Alt-O (for options), hit enter and a 2 (for Enable 286 instructions). Hard
\r
40 hey? Doesn't anyone EVER set up their version of Pascal?
\r
42 Now, on to todays tutorial! 3D solids. That is what the people wanted,
\r
43 that is what the people get! This tutorial is mainly on how to draw the
\r
44 polygon on screen. For details on how the 3D stuff works, check out tut
\r
49 If you would like to contact me, or the team, there are many ways you
\r
50 can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
\r
51 on the ASPHYXIA BBS.
\r
52 2) Write to Denthor, EzE or Goth on Connectix.
\r
53 3) Write to : Grant Smith
\r
57 4) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
\r
58 call during varsity)
\r
59 5) Write to mcphail@beastie.cs.und.ac.za on InterNet, and
\r
60 mention the word Denthor near the top of the letter.
\r
62 NB : If you are a representative of a company or BBS, and want ASPHYXIA
\r
63 to do you a demo, leave mail to me; we can discuss it.
\r
64 NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
\r
65 quite lonely and want to meet/help out/exchange code with other demo
\r
66 groups. What do you have to lose? Leave a message here and we can work
\r
67 out how to transfer it. We really want to hear from you!
\r
71 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
\r
72 þ How to draw a polygon
\r
74 Sounds easy enough, right? WRONG! There are many, many different ways to
\r
75 go about this, and today I'll only be showing you one. Please don't take
\r
76 what is written here as anything approaching the best method, it is just
\r
77 here to get you on your way...
\r
79 The procedure I will be using here is based on something most of us
\r
80 learned in standard eight ... I think. I seem to recall doing something
\r
81 like this in Mrs. Reids maths class all those years ago ;)
\r
83 Take two points, x1,y1 and x2,y2. Draw them :
\r
87 \ <-- Point a somewhere along the line
\r
91 Right, so what we have to do is this : if we know the y-coord of a, what
\r
92 is it's x-coord? To prove the method we will give the points random
\r
101 Right. Simple enough problem. This is how we do it :
\r
102 (a.y-y1) = (12 - 10) {to get a.y as though y1 was zero}
\r
103 *(x2-x1) = *(15 - 2) {the total x-length of the line}
\r
104 /(y2-y1) = /(30 - 10) {the total y-length of the line}
\r
105 +x1 = +2 { to get the equation back to real coords}
\r
107 So our equation is : (a.y-y1)*(x2-x1)/(y2-y1)+x4 or
\r
108 (12-10)*(15-2)/(30-10)+2
\r
110 2*13/20+2 = 26/20+2
\r
113 That means that along the line with y=12, x is equal to 3.3. Since we
\r
114 are not concerned with the decimal place, we replace the / with a div,
\r
115 which in Pascal gives us an integer result, and is faster too. All well
\r
116 and good, I hear you cry, but what does this have to do with life and
\r
117 how it relates to polygons in general. The answer is simple. For each of
\r
118 the four sides of the polygon we do the above test for each y line. We
\r
119 store the smallest and the largest x values into separate variables for
\r
120 each line, and draw a horizontal line between them. Ta-Dah! We have a
\r
123 For example : Two lines going down :
\r
126 / <-x1 x2->| <--For this y line
\r
130 Find x1 and x2 for that y, then draw a line between them. Repeat for all
\r
133 Of course, it's not as simple as that. We have to make sure we only
\r
134 check those y lines that contain the polygon (a simple min y, max y test
\r
135 for all the points). We also have to check that the line we are
\r
136 calculating actually extends as far as where our current y is (check
\r
137 that the point is between both y's). We have to compare each x to see
\r
138 weather it is smaller then the minimum x value so far, or bigger then
\r
139 the maximum (the original x min is set as a high number, and the x max
\r
140 is set as a small number). We must also check that we only draw to the
\r
141 place that we can see ( 0-319 on the x ; 0-199 on the y (the size of the
\r
144 To see how this looks in practice, have a look at the sample code
\r
145 provided. (Mrs. Reid would probably kill me for the above explanation,
\r
146 so when you learn it in school, split it up into thousands of smaller
\r
147 equations to get the same answer ;))
\r
149 Okay, that's it! What's that? How do you draw a vertical line? Thats
\r
152 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
\r
153 þ Drawing a vertical line
\r
155 Right, this is a lot easier than drawing a normal line (Tut 5 .. I
\r
156 think), because you stay on the same y value. So, what you do is you set
\r
157 ES to the screen you want to write to, and get DI to the start of the
\r
158 y-line (see earlier trainers for a description of how SEGMENT:OFFSET
\r
161 IN : x1 , x2, y, color, where
\r
168 shl di,8 { di:=di*256 }
\r
169 shl ax,6 { ax:=ax*64 }
\r
170 add di,ax { di := (y*256)+(y*64) := y*320 Faster then a
\r
171 straight multiplication }
\r
173 Right, now you add the first x value to get your startoff.
\r
175 Move the color to store into ah and al
\r
177 mov ah,al { ah:=al:=color }
\r
178 then get CX equal to how many pixels across you want to go
\r
180 sub cx,x1 { cx:=x2-x1 }
\r
181 Okay, as we all know, moving a word is a lot faster then moving a byte,
\r
183 shr cx,1 { cx:=cx/2 }
\r
184 but what happens if CX was an odd number. After a shift, the value of
\r
185 the last number is placed in the carry flag, so what we do is jump over
\r
186 a single byte move if the carry flag is zero, or execute it if it is
\r
188 jnc @Start { If there is no carry, jump to label Start }
\r
189 stosb { ES:[DI]:=al ; increment DI }
\r
190 @Start : { Label Start }
\r
191 rep stosw { ES:[DI]:=ax ; DI:=DI+2; repeat CX times }
\r
193 Right, the finished product looks like this :
\r
195 Procedure Hline (x1,x2,y:word;col:byte;where:word); assembler;
\r
196 { This draws a horizontal line from x1 to x2 on line y in color col }
\r
220 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
\r
223 This 3D system is still not perfect. It needs to be faster, and now I
\r
224 have also dumped the problem of face-sorting on you! Nyahahahaha!
\r
226 [ My sister and I were driving along the other day when she
\r
227 asked me, what would I like for my computer.
\r
228 I thought long and hard about it, and came up with the
\r
229 following hypothesis. When a girl gets a Barbie doll, she
\r
230 then wants the extra ballgown for the doll, then the
\r
231 hairbrush, and the car, and the house, and the friends
\r
233 When a guy gets a computer, he wants the extra memory, the
\r
234 bigger hard drive, the maths co-pro, the better
\r
235 motherboard, the latest software, and the bigger monitor
\r
237 I told my sister all of this, and finished up with : "So as
\r
238 you can see, computers are Barbie dolls for MEN!"
\r
239 She called me a chauvinist. And hit me. Hard.
\r
248 These fine BBS's carry the ASPHYXIA DEMO TRAINER SERIES : (alphabetical)
\r
250 ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍËÍÍÍËÍÍÍÍËÍÍÍÍ»
\r
251 ºBBS Name ºTelephone No. ºOpen ºMsgºFileºPastº
\r
252 ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÎÍÍÍÎÍÍÍÍÎÍÍÍ͹
\r
253 ºASPHYXIA BBS #1 º(031) 765-5312 ºALL º * º * º * º
\r
254 ºASPHYXIA BBS #2 º(031) 765-6293 ºALL º * º * º * º
\r
255 ºConnectix BBS º(031) 266-9992 ºALL º º * º * º
\r
256 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÊÍÍÍÊÍÍÍÍÊÍÍÍͼ
\r
258 Open = Open at all times or only A/H
\r
259 Msg = Available in message base
\r
260 File = Available in file base
\r
261 Past = Previous Parts available
\r
263 Does no other BBS's ANYWHERE carry the trainer? Am I writing this for
\r
264 three people who get it from one of these BBS's each week? Should I go
\r
265 on? (Hehehehe ... I was pleased to note that Tut 8 was THE most
\r
266 downloaded file from ASPHYXIA BBS last month ... )
\r
269 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
\r
278 A : Array [1..maxpolys,1..4,1..3] of integer =
\r
280 ((-10,10,0),(-2,-10,0),(0,-10,0),(-5,10,0)),
\r
281 ((10,10,0),(2,-10,0),(0,-10,0),(5,10,0)),
\r
282 ((-2,-10,0),(2,-10,0),(2,-5,0),(-2,-5,0)),
\r
283 ((-6,0,0),(6,0,0),(7,5,0),(-7,5,0)),
\r
284 ((0,0,0),(0,0,0),(0,0,0),(0,0,0))
\r
285 ); { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
\r
286 { (X2,Y2,Z2) ... for the 4 points of a poly }
\r
287 S : Array [1..maxpolys,1..4,1..3] of integer =
\r
289 ((-10,-10,0),(10,-10,0),(10,-7,0),(-10,-7,0)),
\r
290 ((-10,10,0),(10,10,0),(10,7,0),(-10,7,0)),
\r
291 ((-10,1,0),(10,1,0),(10,-2,0),(-10,-2,0)),
\r
292 ((-10,-8,0),(-7,-8,0),(-7,0,0),(-10,0,0)),
\r
293 ((10,8,0),(7,8,0),(7,0,0),(10,0,0))
\r
294 ); { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
\r
295 { (X2,Y2,Z2) ... for the 4 points of a poly }
\r
296 P : Array [1..maxpolys,1..4,1..3] of integer =
\r
298 ((-10,-10,0),(-7,-10,0),(-7,10,0),(-10,10,0)),
\r
299 ((10,-10,0),(7,-10,0),(7,0,0),(10,0,0)),
\r
300 ((-9,-10,0),(9,-10,0),(9,-7,0),(-9,-7,0)),
\r
301 ((-9,-1,0),(9,-1,0),(9,2,0),(-9,2,0)),
\r
302 ((0,0,0),(0,0,0),(0,0,0),(0,0,0))
\r
303 ); { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
\r
304 { (X2,Y2,Z2) ... for the 4 points of a poly }
\r
305 H : Array [1..maxpolys,1..4,1..3] of integer =
\r
307 ((-10,-10,0),(-7,-10,0),(-7,10,0),(-10,10,0)),
\r
308 ((10,-10,0),(7,-10,0),(7,10,0),(10,10,0)),
\r
309 ((-9,-1,0),(9,-1,0),(9,2,0),(-9,2,0)),
\r
310 ((0,0,0),(0,0,0),(0,0,0),(0,0,0)),
\r
311 ((0,0,0),(0,0,0),(0,0,0),(0,0,0))
\r
312 ); { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
\r
313 { (X2,Y2,Z2) ... for the 4 points of a poly }
\r
314 Y : Array [1..maxpolys,1..4,1..3] of integer =
\r
316 ((-7,-10,0),(0,-3,0),(0,0,0),(-10,-7,0)),
\r
317 ((7,-10,0),(0,-3,0),(0,0,0),(10,-7,0)),
\r
318 ((-2,-3,0),(2,-3,0),(2,10,0),(-2,10,0)),
\r
319 ((0,0,0),(0,0,0),(0,0,0),(0,0,0)),
\r
320 ((0,0,0),(0,0,0),(0,0,0),(0,0,0))
\r
321 ); { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
\r
322 { (X2,Y2,Z2) ... for the 4 points of a poly }
\r
323 X : Array [1..maxpolys,1..4,1..3] of integer =
\r
325 ((-7,-10,0),(10,7,0),(7,10,0),(-10,-7,0)),
\r
326 ((7,-10,0),(-10,7,0),(-7,10,0),(10,-7,0)),
\r
327 ((0,0,0),(0,0,0),(0,0,0),(0,0,0)),
\r
328 ((0,0,0),(0,0,0),(0,0,0),(0,0,0)),
\r
329 ((0,0,0),(0,0,0),(0,0,0),(0,0,0))
\r
330 ); { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
\r
331 { (X2,Y2,Z2) ... for the 4 points of a poly }
\r
332 I : Array [1..maxpolys,1..4,1..3] of integer =
\r
334 ((-10,-10,0),(10,-10,0),(10,-7,0),(-10,-7,0)),
\r
335 ((-10,10,0),(10,10,0),(10,7,0),(-10,7,0)),
\r
336 ((-2,-9,0),(2,-9,0),(2,9,0),(-2,9,0)),
\r
337 ((0,0,0),(0,0,0),(0,0,0),(0,0,0)),
\r
338 ((0,0,0),(0,0,0),(0,0,0),(0,0,0))
\r
339 ); { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
\r
340 { (X2,Y2,Z2) ... for the 4 points of a poly }
\r
343 Type Point = Record
\r
344 x,y,z:real; { The data on every point we rotate}
\r
346 Virtual = Array [1..64000] of byte; { The size of our Virtual Screen }
\r
347 VirtPtr = ^Virtual; { Pointer to the virtual screen }
\r
350 VAR Lines : Array [1..maxpolys,1..4] of Point; { The base object rotated }
\r
351 Translated : Array [1..maxpolys,1..4] of Point; { The rotated object }
\r
352 Xoff,Yoff,Zoff:Integer; { Used for movement of the object }
\r
353 lookup : Array [0..360,1..2] of real; { Our sin and cos lookup table }
\r
354 Virscr : VirtPtr; { Our first Virtual screen }
\r
355 Vaddr : word; { The segment of our virtual screen}
\r
358 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
359 Procedure SetMCGA; { This procedure gets you into 320x200x256 mode. }
\r
368 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
369 Procedure SetText; { This procedure returns you to text mode. }
\r
377 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
378 Procedure Cls (Where:word;Col : Byte);
\r
379 { This clears the screen to the specified color }
\r
393 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
394 Procedure SetUpVirtual;
\r
395 { This sets up the memory needed for the virtual screen }
\r
397 GetMem (VirScr,64000);
\r
398 vaddr := seg (virscr^);
\r
402 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
403 Procedure ShutDown;
\r
404 { This frees the memory used by the virtual screen }
\r
406 FreeMem (VirScr,64000);
\r
410 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
411 procedure flip(source,dest:Word);
\r
412 { This copies the entire screen at "source" to destination }
\r
429 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
430 Procedure Pal(Col,R,G,B : Byte);
\r
431 { This sets the Red, Green and Blue values of a certain color }
\r
448 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
449 Procedure Hline (x1,x2,y:word;col:byte;where:word); assembler;
\r
450 { This draws a horizontal line from x1 to x2 on line y in color col }
\r
473 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
474 Procedure DrawPoly(x1,y1,x2,y2,x3,y3,x4,y4:integer;color:byte;where:word);
\r
475 { This draw a polygon with 4 points at x1,y1 , x2,y2 , x3,y3 , x4,y4
\r
480 mnx,mxx,yc:integer;
\r
488 if y2<mny then mny:=y2;
\r
489 if y2>mxy then mxy:=y2;
\r
490 if y3<mny then mny:=y3;
\r
491 if y3>mxy then mxy:=y3; { Choose the min y mny and max y mxy }
\r
492 if y4<mny then mny:=y4;
\r
493 if y4>mxy then mxy:=y4;
\r
495 if mny<0 then mny:=0;
\r
496 if mxy>199 then mxy:=199;
\r
497 if mny>199 then exit;
\r
498 if mxy<0 then exit; { Verticle range checking }
\r
500 mul1:=x1-x4; div1:=y1-y4;
\r
501 mul2:=x2-x1; div2:=y2-y1;
\r
502 mul3:=x3-x2; div3:=y3-y2;
\r
503 mul4:=x4-x3; div4:=y4-y3; { Constansts needed for intersection calc }
\r
505 for yc:=mny to mxy do
\r
509 if (y4>=yc) or (y1>=yc) then
\r
510 if (y4<=yc) or (y1<=yc) then { Check that yc is between y1 and y4 }
\r
513 x:=(yc-y4)*mul1 div div1+x4; { Point of intersection on x axis }
\r
517 mxx:=x; { Set point as start or end of horiz line }
\r
519 if (y1>=yc) or (y2>=yc) then
\r
520 if (y1<=yc) or (y2<=yc) then { Check that yc is between y1 and y2 }
\r
523 x:=(yc-y1)*mul2 div div2+x1; { Point of intersection on x axis }
\r
527 mxx:=x; { Set point as start or end of horiz line }
\r
529 if (y2>=yc) or (y3>=yc) then
\r
530 if (y2<=yc) or (y3<=yc) then { Check that yc is between y2 and y3 }
\r
533 x:=(yc-y2)*mul3 div div3+x2; { Point of intersection on x axis }
\r
537 mxx:=x; { Set point as start or end of horiz line }
\r
539 if (y3>=yc) or (y4>=yc) then
\r
540 if (y3<=yc) or (y4<=yc) then { Check that yc is between y3 and y4 }
\r
543 x:=(yc-y3)*mul4 div div4+x3; { Point of intersection on x axis }
\r
547 mxx:=x; { Set point as start or end of horiz line }
\r
552 mxx:=319; { Range checking on horizontal line }
\r
554 hline (mnx,mxx,yc,color,where); { Draw the horizontal line }
\r
560 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
561 Function rad (theta : real) : real;
\r
562 { This calculates the degrees of an angle }
\r
564 rad := theta * pi / 180
\r
568 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
569 Procedure SetUpPoints;
\r
570 { This creates the lookup table }
\r
571 VAR loop1,loop2:integer;
\r
573 For loop1:=0 to 360 do BEGIN
\r
574 lookup [loop1,1]:=sin (rad (loop1));
\r
575 lookup [loop1,2]:=cos (rad (loop1));
\r
580 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
581 Procedure Putpixel (X,Y : Integer; Col : Byte; where:word);
\r
582 { This puts a pixel on the screen by writing directly to memory. }
\r
590 mov bx, dx {; bx = dx}
\r
593 add dx, bx {; dx = dx + bx (ie y*320)}
\r
594 add di, dx {; finalise location}
\r
602 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
603 Procedure RotatePoints (X,Y,Z:Integer);
\r
604 { This rotates object lines by X,Y and Z; then places the result in
\r
606 VAR loop1,loop2:integer;
\r
609 For loop1:=1 to maxpolys do BEGIN
\r
610 For loop2:=1 to 4 do BEGIN
\r
611 temp.x:=lines[loop1,loop2].x;
\r
612 temp.y:=lookup[x,2]*lines[loop1,loop2].y - lookup[x,1]*lines[loop1,loop2].z;
\r
613 temp.z:=lookup[x,1]*lines[loop1,loop2].y + lookup[x,2]*lines[loop1,loop2].z;
\r
615 translated[loop1,loop2]:=temp;
\r
618 temp.x:=lookup[y,2]*translated[loop1,loop2].x - lookup[y,1]*translated[loop1,loop2].y;
\r
619 temp.y:=lookup[y,1]*translated[loop1,loop2].x + lookup[y,2]*translated[loop1,loop2].y;
\r
620 temp.z:=translated[loop1,loop2].z;
\r
621 translated[loop1,loop2]:=temp;
\r
625 temp.x:=lookup[z,2]*translated[loop1,loop2].x + lookup[z,1]*translated[loop1,loop2].z;
\r
626 temp.y:=translated[loop1,loop2].y;
\r
627 temp.z:=-lookup[z,1]*translated[loop1,loop2].x + lookup[z,2]*translated[loop1,loop2].z;
\r
628 translated[loop1,loop2]:=temp;
\r
636 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
637 Procedure DrawPoints;
\r
638 { This draws the translated object to the virtual screen }
\r
640 nx,ny,nx2,ny2,nx3,ny3,nx4,ny4:integer;
\r
643 For loop1:=1 to maxpolys do BEGIN
\r
644 If (translated[loop1,1].z+zoff<0) and (translated[loop1,2].z+zoff<0) and
\r
645 (translated[loop1,3].z+zoff<0) and (translated[loop1,4].z+zoff<0) then BEGIN
\r
646 temp:=round (translated[loop1,1].z+zoff);
\r
647 nx :=round (256*translated[loop1,1].X) div temp+xoff;
\r
648 ny :=round (256*translated[loop1,1].Y) div temp+yoff;
\r
649 temp:=round (translated[loop1,2].z+zoff);
\r
650 nx2:=round (256*translated[loop1,2].X) div temp+xoff;
\r
651 ny2:=round (256*translated[loop1,2].Y) div temp+yoff;
\r
652 temp:=round (translated[loop1,3].z+zoff);
\r
653 nx3:=round (256*translated[loop1,3].X) div temp+xoff;
\r
654 ny3:=round (256*translated[loop1,3].Y) div temp+yoff;
\r
655 temp:=round (translated[loop1,4].z+zoff);
\r
656 nx4:=round (256*translated[loop1,4].X) div temp+xoff;
\r
657 ny4:=round (256*translated[loop1,4].Y) div temp+yoff;
\r
658 drawpoly (nx,ny,nx2,ny2,nx3,ny3,nx4,ny4,13,vaddr);
\r
665 {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
\r
666 Procedure MoveAround;
\r
667 { This is the main display procedure. Firstly it brings the object towards
\r
668 the viewer by increasing the Zoff, then passes control to the user }
\r
669 VAR deg,loop1,loop2:integer;
\r
672 Procedure Whizz (sub:boolean);
\r
675 For loop1:=-64 to -5 do BEGIN
\r
677 if sub then xoff:=xoff-7 else xoff:=xoff+7;
\r
678 RotatePoints (deg,deg,deg);
\r
682 deg:=(deg+5) mod 360;
\r
692 For loop1:=1 to maxpolys do
\r
693 For loop2:=1 to 4 do BEGIN
\r
694 Lines [loop1,loop2].x:=a [loop1,loop2,1];
\r
695 Lines [loop1,loop2].y:=a [loop1,loop2,2];
\r
696 Lines [loop1,loop2].z:=a [loop1,loop2,3];
\r
700 For loop1:=1 to maxpolys do
\r
701 For loop2:=1 to 4 do BEGIN
\r
702 Lines [loop1,loop2].x:=s [loop1,loop2,1];
\r
703 Lines [loop1,loop2].y:=s [loop1,loop2,2];
\r
704 Lines [loop1,loop2].z:=s [loop1,loop2,3];
\r
708 For loop1:=1 to maxpolys do
\r
709 For loop2:=1 to 4 do BEGIN
\r
710 Lines [loop1,loop2].x:=p [loop1,loop2,1];
\r
711 Lines [loop1,loop2].y:=p [loop1,loop2,2];
\r
712 Lines [loop1,loop2].z:=p [loop1,loop2,3];
\r
716 For loop1:=1 to maxpolys do
\r
717 For loop2:=1 to 4 do BEGIN
\r
718 Lines [loop1,loop2].x:=h [loop1,loop2,1];
\r
719 Lines [loop1,loop2].y:=h [loop1,loop2,2];
\r
720 Lines [loop1,loop2].z:=h [loop1,loop2,3];
\r
724 For loop1:=1 to maxpolys do
\r
725 For loop2:=1 to 4 do BEGIN
\r
726 Lines [loop1,loop2].x:=y [loop1,loop2,1];
\r
727 Lines [loop1,loop2].y:=y [loop1,loop2,2];
\r
728 Lines [loop1,loop2].z:=y [loop1,loop2,3];
\r
732 For loop1:=1 to maxpolys do
\r
733 For loop2:=1 to 4 do BEGIN
\r
734 Lines [loop1,loop2].x:=x [loop1,loop2,1];
\r
735 Lines [loop1,loop2].y:=x [loop1,loop2,2];
\r
736 Lines [loop1,loop2].z:=x [loop1,loop2,3];
\r
740 For loop1:=1 to maxpolys do
\r
741 For loop2:=1 to 4 do BEGIN
\r
742 Lines [loop1,loop2].x:=i [loop1,loop2,1];
\r
743 Lines [loop1,loop2].y:=i [loop1,loop2,2];
\r
744 Lines [loop1,loop2].z:=i [loop1,loop2,3];
\r
748 For loop1:=1 to maxpolys do
\r
749 For loop2:=1 to 4 do BEGIN
\r
750 Lines [loop1,loop2].x:=a [loop1,loop2,1];
\r
751 Lines [loop1,loop2].y:=a [loop1,loop2,2];
\r
752 Lines [loop1,loop2].z:=a [loop1,loop2,3];
\r
761 if keypressed then BEGIN
\r
762 ch:=upcase (Readkey);
\r
763 Case ch of 'A' : zoff:=zoff+5;
\r
764 'Z' : zoff:=zoff-5;
\r
765 ',' : xoff:=xoff-5;
\r
766 '.' : xoff:=xoff+5;
\r
767 'S' : yoff:=yoff-5;
\r
768 'X' : yoff:=yoff+5;
\r
774 RotatePoints (deg,deg,deg);
\r
775 deg:=(deg+5) mod 360;
\r
783 Writeln ('Hello there! Varsity has begun once again, so it is once again');
\r
784 Writeln ('back to the grindstone ;-) ... anyway, this tutorial is, by');
\r
785 Writeln ('popular demand, on poly-filling, in relation to 3-D solids.');
\r
787 Writeln ('In this program, the letters of ASPHYXIA will fly past you. As you');
\r
788 Writeln ('will see, they are solid, not wireframe. After the last letter has');
\r
789 Writeln ('flown by, a large A will be left in the middle of the screen.');
\r
791 Writeln ('You will be able to move it around the screen, and you will notice');
\r
792 Writeln ('that it may have bits only half on the screen, i.e. clipping is');
\r
793 Writeln ('perfomed. To control it use the following : "A" and "Z" control the Z');
\r
794 Writeln ('movement, "," and "." control the X movement, and "S" and "X"');
\r
795 Writeln ('control the Y movement. I have not included rotation control, but');
\r
796 Writeln ('it should be easy enough to put in yourself ... if you have any');
\r
797 Writeln ('hassles, leave me mail.');
\r
799 Writeln ('I hope this is what you wanted...leave me mail for new ideas.');
\r
802 Write (' Hit any key to contine ...');
\r
809 Writeln ('All done. This concludes the ninth sample program in the ASPHYXIA');
\r
810 Writeln ('Training series. You may reach DENTHOR under the names of GRANT');
\r
811 Writeln ('SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid');
\r
812 Writeln ('Connectix BBS user, and occasionally read RSAProg.');
\r
813 Writeln ('The numbers are available in the main text. You may also write to me at:');
\r
814 Writeln (' Grant Smith');
\r
815 Writeln (' P.O. Box 270');
\r
816 Writeln (' Kloof');
\r
818 Writeln ('I hope to hear from you soon!');
\r
820 Write ('Hit any key to exit ...');
\r