home *** CD-ROM | disk | FTP | other *** search
- {$IFDEF Ver70}
- { Compiler directives for Turbo Pascal 7.0 }
- {$A+,B-,D+,E-,F-,I-,L+,N-,O-,P+,Q-,R-,S-,T-,V-,X+}
- {$IFDEF DPMI} {$G+} {$ELSE} {$G-} {$ENDIF}
- {$M 16384,0,655360}
- {$ENDIF}
-
- {$IFDEF Ver60}
- { Compiler directives for Turbo Pascal 6.0 }
- {$A+,B-,D+,E-,F-,G-,I-,L+,N-,O-,R-,S-,V-,X+}
- {$M 16384,0,655360}
- {$ENDIF}
-
- program StarDrek;
-
- { FastVGA v1.0, (C)1993 by Tal Cohen }
-
- uses FastVGA,FastKeys,FastTimer,PCXUnit,DemoSprites,AimSprUnit,Crt;
-
- type StarRec = record
- x,y,a,d:Real;
- C:Byte;
- end;
-
- var Star:array [1..25] of StarRec;
- i,ShipImage,Er:Byte;
- Ship,Aim:Sprite;
- ShipMvX,ShipMvY,AimMvX,AimMvY:ShortInt;
- Temp,PitchDir:Integer;
- Pitch:Word;
- Pal:PaletteType;
- Shots,Hits:LongInt;
- Noisy,SDown:Boolean;
-
- begin
- TextAttr:=Cyan;
- Write ('Fast');
- TextAttr:=LightCyan;
- Write ('VGA');
- TextAttr:=LightGray;
- WriteLn (' v1.0: "Star Drek" Game Demo');
- WriteLn;
- if TestVGA=0 then
- begin
- WriteLn ('This program requires a VGA/MCGA card.');
- Halt;
- end;
- WriteLn ('In the following game, move the aim (looks like a plus sign) using the numeric');
- WriteLn ('keypad, and press space to fire. Try to maintain a high hit ratio!');
- WriteLn;
- WriteLn ('Use "P" to pause the game, "S" to toggle the sound on/off, and Esc to quit.');
- Write ('Press any key to begin ... ');
- ReadKey;
- Randomize;
- InstallFastKeys;
- GoVGA256;
- FillChar (Pal,SizeOf(Pal),0); { Zero the Pal variable }
- SetActivePalette (Pal,0,255); { Make all colors black,
- so nothing is visible }
- LoadPCXPage2 ('DREK1.PCX',Pal,Er); { Load PCX into page 2 }
- if Er<>0 then { Check for errors }
- begin
- TextMode (Co80);
- WriteLn ('Error reading image file DREK1.PCX. Program halted.');
- end;
- CopyFromPage2; { Copy image to page 1. All colors are black, so nothing
- is really seen on-screen }
- TextAttr:=64; { In this PCX's palette, color #64 is white }
- DirectVideo:=False; { This MUST be done to write on the graphical screen }
- GotoXY (1,25);
- Write (' Version 1.0 Press Space ...'); { All black, so it's unseen }
- FadeToPalette (Pal,0,255,12); { Make real colors visible, with a fade }
- repeat until Key[scSpace]; { Wait for a Space press ... }
- FadeOut (12); { Fade to black }
- ClrVGAScr; ClrPage2Scr; { Clear both screens }
- LoadPCXPage2 ('DREK2.PCX',Pal,Er); { Load new image }
- if Er<>0 then { Check for errors }
- begin
- TextMode (Co80);
- WriteLn ('Bad or missing DREK2.PCX. Program terminated.');
- end;
- SetActivePalette (Pal,0,255); { Activate palette. Page 1 is still cleared,
- so nothing is visible }
- Shots:=1; Hits:=0; { Zero variables. Shots is set to one to prevent
- division-by-zero errors }
- for i:=1 to 25 do { Select random stars }
- with Star[i] do
- begin
- x:=Random (20)+150;
- y:=Random (20)+65;
- if x=160 then a:=1e8 else a:=(y-75)/(x-160);
- C:=Random (10)+64;
- Page2^[Round(y)][Round(x)]:=C; { Put Pixel on Page 2 }
- end;
- CopyFromPage2; { Copy Page 2, making the complete picture visible }
- ShipImage:=1; { There are 4 different ship sprites; use #1 now }
- AssignSprite (@Ship,@ShipBMP[1]); { Assign the bitmap to the sprite }
- PutSprite (@Ship,120,70); { Show the sprite }
- { Assign and show the aim sprite: }
- AssignSprite (@Aim,@AimSprite);
- PutSprite (@Aim,137,47);
-
- { Initialize some variables: }
- Pitch:=0;
- Noisy:=True;
- SDown:=True; { When SDown is true, "S" can be used to toggle sound }
-
- { Zero on-screen counters: }
-
- GotoXY (10,20); Write (0:10);
- GotoXY (10,24); Write (0:10);
- GotoXY (26,22); Write (0.0:5:1,'%');
-
- repeat { Main loop }
-
- StartTimer;
-
- { READY Step: }
-
- ReadyMoveSprite (@Aim);
- ReadyMoveSprite (@Ship);
-
- { Make changes to background, ONLY to page 2: }
-
- for i:=1 to 25 do
- with Star[i] do
- begin
- Page2^ [Round(y)][Round(x)]:=0; { Clear old star position }
- x:=x-160;
- x:=x*1.1;
- y:=a*x+75;
- x:=x+160;
- if (x<70) or (x>250) or (y<20) or (y>130) then
- begin
- x:=Random (20)+150; if Round(x)=160 then x:=161;
- y:=Random (20)+65;
- if x=160 then a:=1e8 else a:=(y-75)/(x-160);
- C:=Random (10)+64;
- end;
- Page2^ [Round(y)][Round(x)]:=C;
- end;
-
- { The 72,152 to 239,191 block contains the counters (Shots, Hits, and
- Ratio). For syncronizing the two pages, we copy from page 1 (where
- the text was written) to page 2: }
-
- CopyBlockToPage2 (72,152,247,191);
-
- { Calculate sprite movements }
-
- AimMvX:=0; AimMvY:=0;
-
- if Key[scLeft] or Key[scHome] or Key[scEnd] then Dec(AimMvX,2);
- if Key[scRight] or Key[scPgUp] or Key[scPgDn] then Inc(AimMvX,2);
- if Key[scUp] or Key[scHome] or Key[scPgUp] then Dec(AimMvY,2);
- if Key[scDown] or Key[scEnd] or Key[scPgDn] then Inc(AimMvY,2);
-
- if (Aim.X<53) and (AimMvX<0) then AimMvX:=0 else
- if (Aim.X>222) and (AimMvX>0) then AimMvX:=0;
-
- if (Aim.Y<-5) and (AimMvY<0) then AimMvY:=0 else
- if (Aim.Y>94) and (AimMvY>0) then AimMvY:=0;
-
- if Random<0.1 then ShipMvX:=Random(7)-3; { 10% likely to change X speed }
-
- { Check we're not out-of-bound in the X axis: }
- Temp:=Ship.X+ShipMvX;
- if (Temp<70) or (Temp>200) then ShipMvX:=0;
-
- if Random<0.1 then ShipMvY:=Random(7)-3; { 10% likely to change Y speed }
-
- { Check we're not out-of-bound in the Y axis: }
- Temp:=Ship.Y+ShipMvY;
- if (Temp<3) or (Temp>90) then ShipMvY:=0;
-
- { SET Step: }
-
- SetMoveSprite (@Ship,ShipMvX,ShipMvY);
- SetMoveSprite (@Aim,AimMvX,AimMvY);
-
- { When calling GoMoveSprites, we'd like the program to update the entire
- 70,20 to 251,131 block (this is the "Main Screen".) So, we set LoX and
- co: }
-
- LoX:=70;
- LoY:=20;
- HiX:=251-SprXLen;
- HiY:=131-SprYLen;
-
- { GO Step: }
-
- GoMoveSprites;
-
- if (Key[scSpace]) then { If Space is pressed, the player FIRED }
- begin
- Inc (Shots);
- GotoXY (10,20);
- Write (Shots:10);
-
- { We check for a hit by checking the color. The ship's color values
- are all greater than 50: }
- if VGAScreen[Aim.Y+31][Aim.X+23]>50 then { Hit }
- begin
- { All those settings to Pitch and PitchDir simply set the sound }
- PitchDir:=15;
- if Pitch>150 then Pitch:=100;
- Inc (Hits);
- GotoXY (10,24);
- Write (Hits:10);
- end
- else { Shot, but no hit }
- begin
- if Pitch<475 then Pitch:=500;
- PitchDir:=-10;
- end;
-
- { Display new ratio: }
- GotoXY (26,22);
- Write ((Hits/Shots)*100:5:1);
-
- { We draw the "lasers" on page 1, so they'll soon be erased: }
-
- VGAColor:=Random(256);
- Line (250,130,Aim.X+23,Aim.Y+31);
- Line (071,130,Aim.X+23,Aim.Y+31);
- end;
-
- { Assign new ship image: }
-
- Inc (ShipImage);
- if ShipImage=5 then ShipImage:=1;
- AssignSprite (@Ship,@ShipBMP[ShipImage]);
-
- { Wait for a clocktick to pass since the call to StartTimer: }
-
- WaitFor (1);
-
- { Check for Pause: }
-
- if Key[scP] then
- begin
- NoSound; { Leaving the Buzzer on can be a nightmare ... }
- repeat until not Key[scP]; { Wait for key release }
- repeat until Key[scP]; { Wait for another press ... }
- repeat until not Key[scP]; { and release }
- end;
-
- { Check for sound toggle: }
-
- if not Key[scS] then SDown:=True; { If the S key was released, we can
- accept sound-toggle commands }
- if Key[scS] and SDown then
- begin
- Noisy:=not Noisy; { Sound mode is toggled }
- if not Noisy then NoSound; { Silence speaker if needed }
- SDown:=False; { Until the S key is released, further S pressed should
- be ignored }
- end;
-
- if Noisy then
- if ((Pitch<450) and (PitchDir<0)) or ((Pitch>200) and (PitchDir>0)) then
- begin
- NoSound;
- Pitch:=0;
- PitchDir:=0;
- end
- else
- begin
- Sound(Pitch);
- Inc (Pitch,PitchDir);
- end;
-
- until Key[scEsc]; { Only the Esc key breaks this loop }
-
- { Wind down: }
-
- RestoreKeyboard;
- NoSound;
- TextMode (Co80);
- end.
-