OSDN Git Service

ddb6527c61f6164398250b1dc1ce3a20a02ac4f1
[proj16/16.git] / 16 / PCGPE10 / STARS.TXT
1 ----------------------------- VLA.NFO -----------------------------------\r
2         ÖÄÄÄÄÄÄÄÄÄÄ (% VLA Presents Intro To Starfields %) ÄÄÄÄÄÄÄÄÄÄ·\r
3         º                                                            º\r
4         ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Written áy : Draeden ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ\r
5 \r
6 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \ 4 VLA Members Are \ 4 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
7 \r
8 \r
9                         (© Draeden - Main Coder ª)\r
10                   (© Lithium - Coder/Ideas/Ray Tracing ª)\r
11                    (© The Kabal - Coder/Ideas/Artwork ª)\r
12                       (© Desolation - Artwork/Ideas ª)\r
13 \r
14 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The Finn - Mods/Sounds ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
15 \r
16 \r
17    ÖÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Contact Us On These Boards: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ·\r
18    º                                                                      º\r
19    ³   % Phantasm BBS .................................. (206) 232-5912   ³\r
20    ³   * The Deep ...................................... (305) 888-7724   ³\r
21    ³   * Dark Tanget Systems ........................... (206) 722-7357   ³\r
22    ³   * Metro Holografix .............................. (619) 277-9016   ³\r
23    ³                                                                      ³\r
24    º       % - World Head Quarters      * - Distribution Site             º\r
25    ÓÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĽ\r
26 \r
27      Or Via Internet Mail For The Group : tkabal@carson.u.washington.edu\r
28 \r
29                       Or to reach the other members :\r
30 \r
31                        - draeden@u.washington.edu -\r
32 \r
33                        - lithium@u.washington.edu -\r
34 \r
35                      - desolation@u.washington.edu -\r
36 \r
37 \r
38 \r
39 ÚÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
40 ³ STARS.TXT ³\r
41 ÀÄÄÄÄÄÄÄÄÄÄÄÙ\r
42 \r
43 \r
44 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
45 ;\r
46 ;     TITLE: Star field\r
47 ;WRITTEN BY: DRAEDEN\r
48 ;      DATE: 03/15/93\r
49 ;\r
50 ;     NOTES:\r
51 ;\r
52 ;ASSOCIATED FILES:\r
53 ;\r
54 ;       STARGEN.BAS =>  Basic program that generates a set of 'randomized'\r
55 ;                       numbers.  Creates STARRND.DW\r
56 ;\r
57 ;       STARS.ASM   =>  The asm file.\r
58 ;\r
59 ;       STARRND.DW  =>  File that contains a set of shuffled numbers order.\r
60 ;                       Used to create 'random' star field.\r
61 ;\r
62 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
63 \r
64     A star field is just a series of 3d point plotted onto a 2d plane (your\r
65 screen).  The movement effect is achieved by simply decreasing the Z\r
66 cordinate and redisplaying the results.  The formula for the 3d to 2d\r
67 conversion is:\r
68 \r
69 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
70     ScreenX = ScreenDist * Xpos / Zpos\r
71     ScreenY = ScreenDist * Ypos / Zpos\r
72 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
73 \r
74     This should make perfect sense.  As the object gets futher away, (X,Y)\r
75 cordinates converge to (0,0).  The screen dist is how far away the 'eye' is\r
76 from the screen, or, as I like to think of it, the window.  Naturally, as you\r
77 get closer to the window, your field of view is greatly enhanced (you can see\r
78 more).  But, because we can't make the monitor bigger, we have to shrink the\r
79 data that is being displayed.  And when we have a large screen distance, we\r
80 should see less of the virtual world, and the objects should appear bigger.\r
81 When this formula is translated into assembler, you would immediatly decide\r
82 that 256 is the best screen distance.  Why?  Multiplying by 256 on the 386 is\r
83 as simple as this:\r
84 \r
85 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
86 ;we want to multiply ax by 256 and put it into dx:ax to set up for division\r
87 \r
88     movsx   dx,ah   ;3 cycles\r
89     shl     ax,8    ;3 cycles -- total 6\r
90 \r
91 ;or we could do it the 'normal way'...\r
92 \r
93     mov     dx,256  ;2 cycles, but we can have any screen distance\r
94     imul    dx      ;9-22 cycles on a 386, 13-26 on a 486\r
95                     ;a total of 11-28 cycles!\r
96 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
97 \r
98     If you'll take note, the 6 cycle trick is AT LEAST 5 cycles faster than\r
99 the imul.  Anyway... I bet you really don't care about a few cycles at this\r
100 point, so I won't spend much more time on it... \r
101     So, as you can see, the math part of it is easy..  the hard part is the\r
102 what's left.  You need a routine that creates a star, presumably random, and\r
103 another routine that displays all the stars and advances them.  Well, that's\r
104 how I broke it into subroutines...\r
105 \r
106     For the routine that creates the star you need it to:\r
107 \r
108     1)  See if we already have enough stars going (is NUMSTARS > MAXSTARS ?)\r
109     2)  If there's room, scan for the first open slot... \r
110     3)  Now that we've found where to put it, create a star by getting a set\r
111         of random numbers for the (X,Y) and setting the Z to the maximum.\r
112         Also select a color for the star.\r
113 \r
114     The display routine would need to:\r
115 \r
116     1)  Erase the old star.\r
117     2)  Calculate the screen X & Y positions for the new position.  Are they \r
118         inside the screen boundries?  If not, 'kill' the star, otherwise \r
119         display it.  The shade of the color to use must be calculated by \r
120         using the Z cordinate. Color = BaseColor + Zpos / 256\r
121     3)  Decrease the Zpos.\r
122 \r
123     And the main routine would:\r
124 \r
125     1)  Call MakeStars\r
126     2)  Wait for verticle retrace\r
127     3)  Call DisplayStars\r
128     4)  Check for keypress, if there is one, handle it, if its not one we're\r
129         looking for then exit program.\r
130     5)  Loop to step 1\r
131 \r
132     To impliment this, we need to create an array of records which has enough\r
133 room for MAXSTARS.  The record would contain the (X,Y,Z) cordinates, the\r
134 OldDi and the base color for the star.  To create a star, it first checks to\r
135 see if there is room.  If there is, then we scan through the array\r
136 looking%wor an open slot.  If we don't find an empty space, then we don't\r
137 create a star.  We create the star by grabbing a pair of (X,Y) cordinates\r
138 from the list of 'random' numbers and set the Z to MAXZPOS.  Then, increase\r
139 NUMSTARS and return.\r
140 \r
141     In displaying the star, we would like to only have to calculate DI once.\r
142 So we save off a copy of DI in an array after we calculate it for the drawing\r
143 so that erasing the dot is really quick.  Next we calculate the new DI for\r
144 the dot.  This is done by using the formula mentioned above and this one: \r
145 \r
146 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
147 \r
148     DI = ScreenY * ScreenWidth + ScreenX\r
149 \r
150 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
151 \r
152     When doing the math, care must be taken to make sure that:\r
153 \r
154         a) the Zpos is not zero and X*256/ZPOS is not greater than 32767.\r
155             will cause a DIVIDE BY ZERO or a DIVIDE OVERFLOW\r
156 \r
157         b) SY and SX do not go outside the border of the screen.\r
158 \r
159     If either of these conditions are broken, the star must be terminated and\r
160 calculations for that star must be aborted.  Actually, Zpos = 0 is used to\r
161 signify a nonactive star.  To terminate the star, you'd simply change its\r
162 zpos to 0 and decrease NUMSTARS.\r
163 \r
164     To create the different shades, I used:\r
165 \r
166 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
167 \r
168   Color = BaseColor + Zpos/256\r
169 \r
170 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
171 \r
172     I used 256 as the number to divide by because that enables me to do no\r
173 dividing at all- I just use AH, because AH = AX / 256 (AH is the upper 8 bits\r
174 of AX). This relation suggests that the MAXZPOS shoul be 16*256 for 16\r
175 shades.  So, the MAXZPOS = 4096.  The palette will have to be set up so that\r
176 the shades go from light to black (lower # is lighter).  Simple enough. (I\r
177 hope.)\r
178 \r
179 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
180         RANDOM NUMBERS\r
181 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
182 \r
183     Well, not truly random numbers, but random enough for a starfield.\r
184 \r
185     The problem:\r
186         There is no way on a PC to create truly random numbers with \r
187         great speed.\r
188 \r
189     Solution:\r
190         Don't use truly random numbers.  Use a chart of non-repeating,\r
191         shuffled numbers that fall within your desired range.  That way\r
192         the stars will be evenly spread out and the creation of a new star\r
193         is incredably fast. ( A few MOV instructions) All you have to is grab\r
194         the number and increase the NEXTRANDOM pointer.  I chose to fill in\r
195         the array half with positive numbers, half with negative with a\r
196         minimum distance of 10 from 0.  I did this so that no stars will\r
197         'hit' the screen and just vanish.  That doesn't look too good.\r
198 \r
199     Here's the BASIC file that made my numbers for me...\r
200 \r
201 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
202 \r
203 \r
204     NumStars = 400\r
205     dim     RndArray(NumStars)\r
206     randomize (timer)\r
207 \r
208     'fill the array with numbers from -Numstars/2 to -10\r
209     'and from 10 to Numstars/2\r
210 \r
211     i=10\r
212     for r = 0 to NumStars/2\r
213         RndArray(r)=i\r
214         i=i+1\r
215     next\r
216 \r
217     i=-10\r
218     for r = NumStars/2 to NumStars\r
219         RndArray(r)=i\r
220         i=i-1\r
221     next\r
222 \r
223     'randomly shuffle them..\r
224 \r
225     print "Total numbers: ";NumStars\r
226     print "Shuffling - Please wait... "\r
227 \r
228     for q = 1 to numstars/5\r
229         for r = 0 to NumStars\r
230             swnum1 = int(rnd*NumStars+.5)\r
231             swap RndArray(swnum1),RndArray(r)\r
232         next\r
233     next\r
234 \r
235     'write the numbers neatly to a file\r
236 \r
237     open "starrnd.dw" for output as 1\r
238     cc= 0          ' CC is my "Column Control"\r
239     print#1, "StarRnd dw ";:print#1, using"####";RndArray(0)\r
240     for r = 1 to NumStars\r
241 \r
242         IF cc=0 THEN   ' is this the first one on the line?\r
243             print#1, "dw ";:print#1, using"####" ;RndArray(r);\r
244         ELSE \r
245             print#1, ",";:print#1, using"####"; RndArray(r);\r
246         END IF\r
247 \r
248         cc=cc+1:if cc= 10 then cc=0:print#1," "   'goto the next line\r
249     next\r
250     close #1\r
251 \r
252 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ \r
253 \r
254     This brings up another point.  Whenever you can write a program in a\r
255 higher level language to create data for you, do it.  It sure beats typing\r
256 then in by hand.  For instance, the palette was made using the REPT macro,\r
257 the actual data is created by the compiler at compile time.  Doing it that \r
258 way happens to be a whole lot easier than typing in every byte.\r
259 \r
260     Last minute note: I rigged the plus and minus keys up so that they\r
261 control the 'Warpspeed' can be from 0 - MaxWarp, which I set to 90 or \r
262 something like that.\r
263 \r
264 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
265 \r
266    Well, that's it for now.  See INFO.VLA for information on contacting us.\r
267 \r
268    I would like some suggestions on what to write code for.  What would you\r
269    like to see done?  What code would you like to get your hands on?\r
270 \r
271    Send question, comments, suggestions to draeden@u.washington.edu or post\r
272     on Phantasm BBS.\r
273 \r
274 \r
275 ÚÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
276 ³ STARS.ASM ³\r
277 ÀÄÄÄÄÄÄÄÄÄÄÄÙ\r
278 \r
279 \r
280 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
281 ;\r
282 ;     TITLE: Star field\r
283 ;WRITTEN BY: DRAEDEN\r
284 ;      DATE: 03/15/93\r
285 ;\r
286 ;     NOTES: Need 386 to execute.\r
287 ;\r
288 ;ASSOCIATED FILES:\r
289 ;\r
290 ;       STARGEN.BAS =>  Basic program that generates a set of 'randomized'\r
291 ;                       numbers.  Creates STARRND.DW\r
292 ;\r
293 ;       STARS.TXT   =>  The text file that explains starfields...\r
294 ;\r
295 ;       STARRND.DW  =>  File that contains a set of shuffled numbers.\r
296 ;                       Used to create 'random' star field.\r
297 ;\r
298 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
299 \r
300     DOSSEG\r
301     .MODEL SMALL\r
302     .STACK 200h\r
303     .CODE\r
304     .386\r
305     ASSUME CS:@CODE, DS:@CODE\r
306     LOCALS\r
307 \r
308 ;=== GLOBALS\r
309 ;=== Data Includes\r
310 \r
311 INCLUDE starrnd.dw      ;file that has label StarRnd numbers\r
312 \r
313 ;=== DATA Structures\r
314 \r
315     Star_Struc      STRUC\r
316         X       dw  0\r
317         Y       dw  0\r
318         Z       dw  0\r
319         OldDi   dw  0       ;where to erase last dot\r
320         Color   db  0       ;BASE color. a number 0-16 is added to it\r
321     Star_Struc      ENDS\r
322 \r
323     StarStrucSize = 9       ;number of bytes per entry\r
324 \r
325 ;=== DATA\r
326 \r
327 ScreenWidth EQU 320\r
328 ScreenHeight EQU 200\r
329 \r
330 NumRnds     EQU 400     ;number of random numbers defined\r
331 \r
332 MaxZpos     EQU 4096\r
333 MinZpos     EQU 2\r
334 MaxStars    EQU 190\r
335 NumColors   EQU 5       ;number of Base colors in the Color Chart\r
336 \r
337 WarpSpeed   dw  15      ;how quickly the stars move toward ya\r
338 MaxWarp     EQU 90\r
339 \r
340 Xindex      dw  30      ;index into the StarRnd chart for X & Y\r
341 Yindex      dw  230     ; -note they must be different; set em the same to\r
342                         ;see why\r
343 Cindex      dw  0       ;index into ColorChart\r
344 \r
345 ColorChart  db  0,16,32,48,64,80    ;a list of base colors (-1)\r
346 \r
347 Stars       Star_Struc MaxStars DUP (<>) ;where all the data is held\r
348 NumActive   dw  0       ;number of stars active\r
349 \r
350 Palette     db  3 dup (0)   ;the palette.. first entrie is BG color (black)\r
351     i = 15\r
352     REPT    16\r
353             db  2*i,3*i,4*i\r
354         i=i-1\r
355     ENDM\r
356     i = 15\r
357     REPT    16\r
358             db  2*i,2*i,4*i\r
359         i=i-1\r
360     ENDM\r
361     i = 15\r
362     REPT    16\r
363             db  3*i,3*i,4*i\r
364         i=i-1\r
365     ENDM\r
366     i = 15\r
367     REPT    16\r
368             db  3*i,2*i,4*i\r
369         i=i-1\r
370     ENDM\r
371     i = 15\r
372     REPT    16\r
373             db  3*i,3*i,3*i\r
374         i=i-1\r
375     ENDM\r
376     i = 15\r
377     REPT    16\r
378             db  2*i,4*i,3*i\r
379         i=i-1\r
380     ENDM\r
381 \r
382 ;=== Code Includes\r
383 ;=== SUBROUTINES\r
384 \r
385     ;finds 1st available slot for a star and puts it there\r
386 MakeStar PROC NEAR\r
387     pusha\r
388     mov     ax,cs\r
389     mov     es,ax\r
390     mov     ds,ax\r
391 \r
392     cmp     [NumActive],MaxStars    ;is there room for another star?\r
393     jae     NoEmptySpace            \r
394 \r
395     ;search for 1st available slot\r
396 \r
397     mov     si,0\r
398 TryAgain:\r
399     cmp     word ptr [Stars.Z+si],0     ;is this slot empty?\r
400     je      GotOne                      ;yes, go fill it\r
401 \r
402     add     si,StarStrucSize\r
403     cmp     si,MaxStars*StarStrucSize\r
404     jb      TryAgain\r
405     jmp     NoEmptySpace\r
406 \r
407 GotOne:         ;si points to the record for the star to fill\r
408     mov     di,[Yindex]         ;grab index for Ypos\r
409     add     di,di               ;multiply by 2 to make it a WORD index\r
410     mov     ax,[StarRnd+di]     ;get the number\r
411     shl     ax,3                ;multiply by 8- could been done in BAS file\r
412     mov     [Stars.Y+si],ax     ;and save off the number\r
413     \r
414     mov     di,[Xindex]         ;grab index for Xpos\r
415     add     di,di               ;... same as above, but for Xpos\r
416     mov     ax,[StarRnd+di]\r
417     shl     ax,3\r
418     mov     [Stars.X+si],ax\r
419 \r
420     mov     [Stars.Z+si],MaxZpos    ;reset Zpos to the max\r
421     inc     [NumActive]             ;we added a star so increase the counter\r
422 \r
423     mov     di,[Cindex]             ;grab the color index\r
424     mov     al,[ColorChart+di]      ;grab the BaseColor for the star\r
425     mov     [Stars.Color+si],al     ;save it in the record\r
426 \r
427     ;increase all the index pointers\r
428 \r
429     inc     [Cindex]                ;increases the color counter\r
430     cmp     [Cindex],NumColors\r
431     jb      OkColor\r
432     mov     [Cindex],0\r
433 OkColor:\r
434     inc     [Yindex]                ;increases Yindex\r
435     cmp     [Yindex],NumRnds        ;note that for this one we\r
436     jb      YindNotZero             ; subtract NumRnds from Yindex if we\r
437     sub     [Yindex],NumRnds        ; go off the end of the chart\r
438 YindNotZero:\r
439     inc     [Xindex]                ;increase Xindex\r
440     cmp     [Xindex],NumRnds        ;have we gone through the entire chart?\r
441     jb      XindNotZero             ;nope...\r
442 \r
443 ;This clever bit of code makes more use out of the chart by increasing Yindex\r
444 ; one additional unit each time Xindex goes through the entire chart... the\r
445 ; result is nearly NumRND^2 random non-repeating points\r
446         \r
447     inc     [Yindex]                ;yes, so change Yindex so that we get a\r
448     mov     ax,[Yindex]             ;new set of random (x,y)\r
449     cmp     ax,[Xindex]             ;does Xindex = Yindex?\r
450     jne     NotTheSame              ;if the index were the same, you'd see \r
451                                     ;a graph of the line Y = X, not good...\r
452     inc     [Yindex]                ;if they are the same, inc Yindex again\r
453 NotTheSame:\r
454     mov     [Xindex],0              ;reset Xindex to 0\r
455 XindNotZero:                        ;all done making the star...\r
456 \r
457 NoEmptySpace:\r
458     popa\r
459     ret\r
460 MakeStar ENDP\r
461 \r
462 DisplayStars PROC NEAR\r
463     pusha\r
464     mov     ax,cs\r
465     mov     ds,ax\r
466     mov     ax,0a000h\r
467     mov     es,ax\r
468 \r
469     mov     si,0\r
470 DispLoop:\r
471     mov     cx,[Stars.Z+si]\r
472     or      cx,cx                   ;if Zpos = 0 then this star is dead...\r
473     je      Cont                    ;continue to the next one- skip this one\r
474 \r
475     mov     di,[Stars.OldDi+si]     ;grab old Di\r
476     mov     byte ptr es:[di],0      ;erase the star\r
477     \r
478     cmp     cx,MinZpos\r
479     jl      TermStar                ;if Zpos < MinZpos then kill the star\r
480 \r
481     mov     ax,[Stars.Y+si]\r
482     movsx   dx,ah                   ;'multiply' Ypos by 256\r
483     shl     ax,8\r
484     \r
485     idiv    cx                      ;and divide by Zpos\r
486     add     ax,ScreenHeight/2       ;center it on the screen\r
487     mov     di,ax\r
488     cmp     di,ScreenHeight         ;see if the star is in range. \r
489     jae     PreTermStar             ; If not, kill it\r
490     imul    di,ScreenWidth          ; DI = Y*ScreenWidth\r
491 \r
492     mov     ax,[Stars.X+si]\r
493     movsx   dx,ah                   ;multiply Xpos by 256\r
494     shl     ax,8\r
495 \r
496     idiv    cx                      ;and divide by Zpos\r
497     add     ax,ScreenWidth/2        ;center it on the screen\r
498     cmp     ax,ScreenWidth          ;are we inside the screen boundries?\r
499     jae     PreTermStar\r
500     add     di,ax                   ; DI = Y * ScreenWidth + X\r
501 \r
502     mov     [Stars.OldDi+si],di     ;save old di\r
503 \r
504     ;calculate the color below\r
505 \r
506     add     ch,cs:[Stars.Color+si]  ;i'm dividing cx (the zpos) by 256 and\r
507                                     ; putting the result in ch and adding\r
508                                     ; the base color to it in one instruction\r
509     mov     es:[di],ch              ;put the dot on the screen\r
510 \r
511     mov     ax,cs:[WarpSpeed]\r
512     sub     cs:[Stars.Z+si],ax      ;move the stars inward at WarpSpeed\r
513 \r
514 Cont:\r
515     add     si,StarStrucSize        ;point to next record\r
516     cmp     si,MaxStars*StarStrucSize   ;are we done yet?\r
517     jb      DispLoop\r
518     popa\r
519     ret\r
520 \r
521 PreTermStar:\r
522     mov     [Stars.Z+si],1  ;this is here so that the star will get erased\r
523     jmp     short Cont      ;next time through if I just went off and killed\r
524                             ;the star, it would leave a dot on the screen\r
525 TermStar:\r
526     mov     [Stars.Z+si],0  ;this actually kills the star, after it has\r
527     dec     [NumActive]     ;been erased\r
528     jmp     short Cont\r
529 \r
530 DisplayStars ENDP\r
531 \r
532 ;=== CODE\r
533 \r
534 START:\r
535     mov     ax,cs\r
536     mov     ds,ax\r
537     mov     es,ax\r
538 \r
539     mov     ax,0013h                ;set vid mode 320x200x256 graph\r
540     int     10h\r
541     \r
542     mov     dx,offset Palette\r
543     mov     ax,1012h                ; WRITE palette \r
544     mov     bx,0                    \r
545     mov     cx,256                  ;write entire palette\r
546     int     10h                     ;doesn't matter if we didnt define it all\r
547 \r
548 StarLoop:\r
549     call    MakeStar        ;make stars 2x as thick\r
550     call    MakeStar\r
551 \r
552     mov     dx,3dah\r
553 VRT:\r
554     in      al,dx\r
555     test    al,8\r
556     jnz     VRT             ;wait until Verticle Retrace starts\r
557 \r
558 NoVRT:\r
559     in      al,dx\r
560     test    al,8\r
561     jz      NoVRT           ;wait until Verticle Retrace Ends\r
562 \r
563     call    DisplayStars\r
564 \r
565     mov     ah,1            ;check to see if a char is ready\r
566     int     16h\r
567     jz      StarLoop        ;nope, continue\r
568     \r
569     mov     ah,0\r
570     int     16h             ;get the character & put in AX\r
571 \r
572     cmp     al,"+"          ;compare ASCII part (al) to see what was pressed\r
573     jne     NotPlus\r
574 \r
575     inc     [WarpSpeed]\r
576     cmp     [WarpSpeed],MaxWarp\r
577     jbe     StarLoop\r
578 \r
579     mov     [WarpSpeed],MaxWarp\r
580     jmp     StarLoop\r
581 \r
582 NotPlus:\r
583     cmp     al,"-"\r
584     jne     NotMinus\r
585 \r
586     dec     [WarpSpeed]\r
587     cmp     [WarpSpeed],0\r
588     jge     StarLoop\r
589 \r
590     mov     [WarpSpeed],0\r
591     Jmp     StarLoop\r
592 \r
593 NotMinus:\r
594 \r
595     mov     ax,0003h        ;set 80x25x16 char mode\r
596     int     10h\r
597     mov     ax,4c00h        ;return control to DOS\r
598     int     21h\r
599 END START\r
600 \r
601 \r
602 \r
603 ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
604 ³ STARRND.DW ³\r
605 ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
606 \r
607 \r
608 StarRnd dw  166\r
609 dw   67, 102,  46,-173,-154,-210,-192, 173,-196, -81 \r
610 dw  -50,  36,  50,-200, -95, 209, -16,-179, -30,  18 \r
611 dw  174, 197, 127,  71,  29,-121,-160,-176,  19, -52 \r
612 dw -185,  89, 172,  74,-156, 157,-125, 144, -34,  69 \r
613 dw   17, -40,  64, -98,-153, 125, 160, 140,-204, 141 \r
614 dw  137,-165, -14, 154,-146, 119, 123, 165,-130, 168 \r
615 dw -180, 143,  52, 107,-107,-102,  57,  27, 117,  37 \r
616 dw  126,  15, -89, 184, 116, 183, -99,-139, 150, 188 \r
617 dw   38,  90,  93,-194, 207,-187,  62,  59, 196,  12 \r
618 dw -174,  54, 146,-137, 198, 162, 155,-163, -77,-144 \r
619 dw  191,-132, -43, 151,-103,  20, -46,  13,-140,  31 \r
620 dw  130,-169,-188, 109, -33,-150,-170,  68, -75,-201 \r
621 dw -100,-171, -19, -61,-206, 149,  99, -76,-186, -44 \r
622 dw -178,  34,  61,  28, 114, 199, 201, -83, -27,  63 \r
623 dw  -38, 204, 208,-112,-208, 122, -90,  23,-122, 161 \r
624 dw   35,-168, 170,-164,-151,  75, -60,-109,  85, 193 \r
625 dw   45,-175,-134, 205, -21,  49, 133, -85, -47, -37 \r
626 dw  -29, -96, -66,  73,-118, 147, -53, 120, 153,-155 \r
627 dw  -11,  11,  95, -26, 134,-145, -49, -74,  42,-124\r
628 dw  189, -42,  92,-167,  88,-126,-129,-108,-193, 195 \r
629 dw  190,-106,-117, 203,  84, 139,-123, -94, -88,-158 \r
630 dw  181, -97, -20,  82, -57, 112, -35,  14, -56, -58 \r
631 dw  200,  80,-183, 106,  87,  30,  51, -28,  98, -12 \r
632 dw -191,-128, -13,-184, 136,  43,-166, -62, -73,-116 \r
633 dw  -31,-135,-101,  25,  41, -82, 110,  10, -45, -41 \r
634 dw   97, 175, 138, 171,  72,-133,-157,  58,-104, 187 \r
635 dw  192, -68, -87, 169,-110,  91, 129, 104, -70,-114 \r
636 dw -138,-115,-141, -67,-195, -79, -69,  40,-147, -80 \r
637 dw -119, 128, 152,-209,  83,  53, 159,  66,-190,  81 \r
638 dw  -92, -10,-181, 135,  60,  33, -25,  70,  22, -72 \r
639 dw  103, -23, 131,  79, -64,  55, -86, -32,-182,-136 \r
640 dw   26, -54,-172,-148, 148, -65,-152,-207, -39, -71 \r
641 dw   65, 179,-177,  24, 118, -59, -63,  44, 105, 206 \r
642 dw  178, -84,-202, 132, 186, -17,  76, 176, -22, 177 \r
643 dw -198,-159,-162,  78,  77, -55,-120,-203,-113, 156 \r
644 dw -189,-197, 124, 121,-142, -15,-205,  56, 158, -18 \r
645 dw  -93,-161,  39,  48, 101, -91, 182,-127, 108, 111 \r
646 dw  -36,-143,  21,-149, -78, -48, 164, 202, 185, 180 \r
647 dw  -51,-199, 100, 194,  32, -24, 142,  86,-111,  47\r
648 dw  115,-105,  16, 167,  94, 163,  96, 113,-131, 145\r
649 \r
650 \r
651 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r
652 ³ STARGEN.BAS ³\r
653 ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\r
654 \r
655 \r
656 '\r
657 'Written by: Draeden /VLA\r
658 '      Date: 03/15/93\r
659 '\r
660 '     Notes: Used for generating 'random' data for Stars.asm\r
661 '\r
662 \r
663 \r
664         NumStars = 400\r
665         dim     RndArray(NumStars)\r
666         randomize (timer)\r
667 \r
668         'fill the array with numbers from -Numstars/2 to -10\r
669         'and from 10 to Numstars/2\r
670 \r
671         i=10\r
672         for r = 0 to NumStars/2\r
673                 RndArray(r)=i\r
674                 i=i+1\r
675         next\r
676         i=-10\r
677         for r = NumStars/2 to NumStars\r
678                 RndArray(r)=i\r
679                 i=i-1\r
680         next\r
681 \r
682         'randomly shuffle them..\r
683 \r
684         print "Total numbers: ";NumStars\r
685         print "Shuffling - Please wait... "\r
686 \r
687         for q = 1 to numstars/5\r
688                 for r = 0 to NumStars\r
689                         swnum1 = int(rnd*NumStars+.5)\r
690                         swap RndArray(swnum1),RndArray(r)\r
691                 next\r
692         next\r
693 \r
694         'write the numbers neatly to a file\r
695 \r
696         open "starrnd.dw" for output as 1\r
697         cc= 0\r
698         print#1, "StarRnd dw ";:print#1, using"####";RndArray(0)\r
699         for r = 1 to NumStars\r
700 \r
701                 IF cc=0 THEN\r
702                         print#1, "dw ";:print#1, using"####" ;RndArray(r);\r
703                 ELSE \r
704                         print#1, ",";:print#1, using"####"; RndArray(r);\r
705                 END IF\r
706 \r
707                 cc=cc+1:if cc= 10 then cc=0:print#1," "\r
708         next\r
709         close #1\r
710 \r