Contributor: SCOTT TUNSTALL
{
SPACE LORDS 7 - VGA PC VERSION.
(C) 1995 Scott Tunstall & K. Sillett (BBC Maestro)
3 PLAYER ACTION !!!
Apologies for the swearing in some of my posts Gayle. To make up
for it, I've given ya a QUALITY video game. Seriously!
It certainly looks smart... don't ask me where I got the graphics
from tho' - some folk may complain! ;)
BEFORE YOU RUN THIS PLEASE USE THE XX3402 DECODER ON PART 2 OF
THE SPACE LORDS POST TO CREATE THE FILE IMAGES.ZIP. THEN UNZIP
THE IMAGES FILE INTO WHERE YOUR SPACE LORDS GAME EXECUTABLE FILE
(LORDS.EXE) WILL BE.
THEN, RUN THE EXE AND HAVE FUN! :)
New game requirements:
----------------------
500K of base memory
MCGA/VGA graphics adaptor supporting 320 x 200 x 256 mode
386 SX 25 processor (at worst) - will run VERY SLOWLY ON THIS MACHINE
(Ok on a 486 DX-2)
(Of course, if you are Dave "Stallion Man" Norrie you can use a
8Mb RAM Pentium f***ing 90 - lucky c***!! I'll put one over him
and buy an IBMRISC 400Mhz baby! (No games for it tho' - I'll change
that !)
Most importantly a 101 key keyboard is essential.
PLAYER # UP ROTATE LEFT ROTATE RIGHT FIRE
-----------------------------------------------------------------
1 '1' 'A' 'X' 'LEFT SHIFT'
2 'O' ';' '@' '>'
3 'Home' 'Keypad 9' 'Keypad -' 'Keypad 3'
4 JOYSTICK 1 (Not implemented)
5 JOYSTICK 2 (Not implemented)
6..100 require to be LapLinked (Aye right then)
}
{$DEFINE FULLDISPLAY} { <-- $UNDEF if using a slow 386 }
{$DEFINE BUMPING} { <-- Player to player bumping }
{$DEFINE BONUSES} { <-- Want Any bonuses on screen }
{$DEFINE MESSAGES} { <-- This may be silly of you to $UNDEF. }
{$a+,b-,s-,e+,n+,r-,v-,g+}
Program SPACE_LORDS_7; { 7 editions already - GULP! }
Uses Dos,NEWGRAPH, NwKBDInt, Crt;
{NEWGRAPH is in JUNE 1996 EDITION OF THE SWAG }
{AS IS NEWKBDINT - KEYBOARD HANDLER }
Const TopBoundary = -8; { Top of window }
BottomBoundary = 204;
LeftBoundary = -4;
RightBoundary = 323;
MaxPlayers = 3; { Max no of players on screen at once }
{$IFDEF BONUSES}
MaxBonuses = 6; { Max no of bonuses on screen at once }
{$ENDIF}
MaxAliens = 10; { Getting busy on the screen ! }
MaxStars = 20; { Number of parallax stars }
MaxExplodeWidth = 200; { And how far the explosion circles go }
ShipTurnAngle = 4; { Degrees that ships turn in }
PointsForBumping = 500; { Guess what these are ? }
PointsForShooting = 100;
DeductionForShooting = 10;
{
BIT FLAGS - LEAVE ALONE
}
Dead = 0; { Playerstatus defines }
ShootAble = 1; { This MUST stay at 1 - V. Important }
Warping = 2; { This MUST stay at 2 ! }
Exploding = 4; { This MUST stay at 4 ! }
Spinning = 8; { This MUST stay at 8 ! }
Frozen = 16;
{
Player Speed stuff
}
MaxPlayerSpeed = 4; { This is the MAXIMUM number of
pixels that a player ship jumps
in 1 pass. Pretty fast man }
SlowestPlayerSpeed = 1; { The least number of pixel
jumps }
{
Laser stuff - Alter MaxLasers if you like, leave the rest
}
MaxLasers = (MaxPlayers * 10)+10; { How many lasers allocated }
MaxPlayerLasers = 10; { How many each player has }
MaxLaserPower = 5;
NumLaserTypes = 3; { The current # of laser types }
LaserFree = 0;
NormalLaser = 1; { Lasers stop at edge of screen }
LaserWraps = 2; { Lasers can go off one side &
reappear on the other }
LaserRebound = 3; { Makes lasers bounce off wall }
PlayerLaserSize = 4;
AlienLaserSize = 4;
{
Bonus stuff - don't change the values of the constants
otherwise some strange effects will occur, OK? If you want
to add some more stuff you'll have to update BonusString
too..
}
{$IFDEF BONUSES}
NumberOfBonuses = 13;
{ BONUS NAME POINTS FOR COLLECTING IT
---------- ------------------------
}
SlowDownBonus = 1; SlowDownBonusPointsValue = 100;
EnergyBonus = 2; EnergyBonusPointsValue = 200;
FreezeBonus = 3; FreezeBonusPointsValue = 300;
ReverseBonus = 4; ReverseBonusPointsValue = 400;
DisableBonus = 5; DisableBonusPointsValue = 500;
InvulnerabilityBonus = 6; InvulnerabilityBonusPointsValue = 600;
AssFiringBonus = 7; AssFiringBonusPointsValue = 700;
NormalBonus = 8; NormalBonusPointsValue = 50;
ToodysBonus = 9; ToodysBonusPointsValue = 2000;
LaserBonus = 10; LaserBonusPointsValue = 200;
WarpBonus = 11; WarpBonusPointsValue = 1000;
BounceLaserBonus = 12; BounceLaserBonusPointsValue = 200;
UnknownBonus = 13;
{$ENDIF}
MaxInvulnerableTime = 200;
{$IFDEF BONUSES}
MaxFrozenTime = 100;
MaxFireHaltTime = 100;
MaxKeyReverseTime = 200;
MaxSlowedDownTime = 100;
MaxBanzaiTime = 100;
MaxDisableTime = 100;
{$ENDIF}
EnergyIncrement = 5;
SlowDownIncrement = 10;
NormalMessageTime = 80;
PacDelayConst = 4;
{
And now to define ALL aspects of a player's ship
}
Type PlayerStruct = Record
PlayerStatus: byte; { 0 = Dead, 1 = ShootAble, 2= Exploding,
4 = Spinning, 8 = Frozen }
FrozenTime: word;
ExplodeWidth:byte;
PlayerColour: byte;
PlayerAngle: integer;
SpinAngle: integer;
SpinSpeed: byte;
SpinCount: byte;
PlayerX: integer;
PlayerY: integer;
PlayerWraps : boolean;
PlayerMessage: String[38];
MessageTime: byte;
BanzaiTime: word;
{
Speed stuff
}
PlayerSpeed: byte; { Exceed 3 and ship movement is
quite jerky. }
NormalPlayerSpeed: byte;
SlowedDownTime: word;
PlayerWait: byte;
WaitCount: byte;
MaxWaitCount: byte;
Thrusting: boolean;
PlayerEnergy: integer;
MaxPlayerEnergy: integer;
RechargeTime: byte;
RechargeLatch: byte;
RechargeDeduction: byte;
KeyReverseTime: byte;
AutoFire: boolean;
DisableTime: byte;
AssFiring : boolean;
FireKeyReleased: boolean;
FireDelay:byte;
FireLatch:byte;
LaserDeduction: byte;
CurrentLaserType: byte;
CurrentLaserPower: byte;
CurrentLaserSpeed: byte;
CurrentMaxLaserTravel: byte;
LaserHurts: boolean;
EnemyLaserHurts: boolean;
Invulnerable: boolean;
InvulnerableTime: word;
PlayerScore: LongInt;
End;
Type Laser = Record
LaserType: byte;
FiredBy: byte;
LaserAngle: integer;
LaserX: integer;
LaserY: integer;
LaserColour: byte;
LaserSize: byte;
LaserSpeed: byte;
LaserTravel: byte;
MaxLaserTravel: byte;
LaserPower: byte;
End;
{$IFDEF BONUSES}
{
Yeah! Some Pick - Ups for the players!
}
Type Bonus = Record
BonusType: byte;
BonusX: integer; { Position on screen }
BonusY: integer;
BonusXIncrement: integer;
BonusYIncrement: integer;
End;
Type BonusArray = Array[1..MaxBonuses] of Bonus;
{$ENDIF}
Type PlayerArray = Array[1..MaxPlayers] of PlayerStruct;
Type LaserArray = Array[1..MaxLasers] of Laser;
Var
PlayerRec: PlayerArray;
LaserRec: LaserArray;
TempLaser: Laser;
{$IFDEF BONUSES}
BonusRec: BonusArray;
{$ENDIF}
OldKbdInt: procedure;
PlanetSeg,PlanetOfs: word;
titleBitmapSeg,titleBitmapOfs: word;
EmporerSeg,EmporerOfs: word;
ScratchSeg,ScratchOfs: word;
FontSegment, FontOffset: word;
FontHeight: byte;
PacPointer: Array[0..7] of Pointer;
AlienPointer: Pointer;
AlienShapeSize: word;
DestroyerPalette: PaletteType;
titleBitmapPalette: PaletteType;
EmporerPalette: PaletteType;
TempKey: char;
ColourTable: array[1..MaxPlayers] of byte;
QCos, QSin : array[0..359] of real;
PlayersOn: byte;
PlayersAlive: byte; { How many players are
left on the screen -
initially, PlayersAlive
equals PlayersOn but
as people are killed it
decrements }
LasersFired: byte;
LastLaserIndex: byte;
AlienCount: byte;
{$IFDEF BONUSES}
BonusesOnScreen: byte;
BonusString: string[NumberOfBonuses];
{$ENDIF}
Message: String[40];
Procedure Warp(PlayerNo:byte); Forward;
Procedure LoadGraphics;
Var Count: byte;
Begin
TextMode(CO80);
TextBackGround(Black);
ClrScr;
TextBackGround(Red);
For Count:=0 to 79 do Write(Chr(32));
TextColor(White);
Gotoxy(1,1);
Writeln('SPACE LORDS 7.1.2.3.5.2.9.« (C) 1994,5 Scott Tunstall. Lauder College Version');
Writeln;
Writeln;
TextBackGround(Black);
TextColor(LightGray);
Writeln('Beginning LORDS_INIT Refresh daemon.. OK.');
Writeln;
For Count:=0 to 79 do write('=');
Writeln('THIS VERSION IS PUBLIC DOMAIN AND MAY BE SWAPPED AND COPIED FREELY');
Writeln('YOU MAY NOT DISASSEMBLE, REPLICATE OR ALTER THE PROGRAM CODE IN ANY');
Writeln('WAY UNLESS YOU CONTACT THE AUTHOR.');
For Count:=0 to 79 do write('=');
Writeln('Please wait.. Loading in PCX files from hard disk..');
Writeln;
Bitmap(PlanetSeg, PlanetOfs);
Bitmap(titleBitmapSeg, titleBitmapOfs);
Bitmap(EmporerSeg, EmporerOfs);
Bitmap(ScratchSeg, ScratchOfs);
Write('DESTROYR.PCX .. ');
SetSourceBitmapAddr(PlanetSeg, PlanetOfs);
LoadPCX('DESTROYR.PCX',DestroyerPalette);
Writeln('loaded.'); Write('BACK.PCX .. ');
SetSourceBitmapAddr(titleBitmapSeg, titleBitmapOfs);
LoadPCX('BACK.PCX',titleBitmapPalette);
Writeln('loaded.'); Write('EMPORER.PCX .. ');
SetSourceBitmapAddr(EmporerSeg, EmporerOfs);
LoadPCX('EMPORER.PCX',EmporerPalette);
Writeln('loaded.');
End;
{
Sorry I had to get rid of the Pascal but I was pissed off
with it's slothfulness !
}
Procedure BitMapCopy(TheSegment, TheOffset:word);
Begin
Asm
MOV AX,DS
MOV ES,ScratchSeg
MOV DI,ScratchOfs
MOV SI,TheOffset
MOV DS,TheSegment
MOV CX,16000
REPZ
DB $66
MOVSW
MOV DS,AX
End;
SetSourceBitmapAddr(ScratchSeg,ScratchOfs);
SetDestinationBitmapAddr($a000,0);
End;
{========================================================
This routine could possibly be slowing the system down
quite a lot as it calls the video interrupt which as most
codies know is as slow as a snail on mogadon. Hmm.
I will update this in 1998 when I've got me postgraduate
but right now you'll have to make do with this s**t OK?
}
Procedure SelectFont(FontNo: byte);
Var TempWidth: byte;
Begin
UseFont(FontNo);
GetCurrentFontAddr(FontSegment,FontOffset);
GetCurrentFontSize(TempWidth,FontHeight);
End;
{====================
Display coloured text
}
Procedure TextXY(x,y:integer;txt:string);
Begin
SetColour(254);
OutTextXY(x+1,y+1,txt);
SetColour(255);
OutTextXY(x,y,txt);
End;
{===============================================================
This Bresenham circle routine isn't mine. I nicked it from the
SWAG (the rest of the stuff is 100% mine though) and to be quite
honest I couldn't be bothered converting it to assembler, so if
any gurus out there (like me!) want to then they can convert.
*** You'd be sad tho' !! ***
}
Procedure Circle(X, Y : integer; Radius:byte);
Var
Xs, Ys : Integer;
Da, Db, S : Integer;
TX, TR : word;
begin
if (Radius = 0) then
Exit;
if (Radius = 1) then
begin
PutPixel(X, Y, GetColour);
Exit;
end;
Xs := 0;
Ys := Radius;
Repeat
TX:=Sqr(Xs+1);
TR:=Sqr(Radius);
Da := TX + Sqr(Ys) - TR;
Db := TX + Sqr(Ys - 1) - TR;
S := Da + Db;
Inc(Xs);
if (S > 0) then
Dec(Ys);
PutPixel(X+Xs-1, Y-Ys+1, GetColour);
PutPixel(X-Xs+1, Y-Ys+1, GetColour);
PutPixel(X+Ys-1, Y-Xs+1, GetColour);
PutPixel(X-Ys+1, Y-Xs+1, GetColour);
PutPixel(X+Xs-1, Y+Ys-1, GetColour);
PutPixel(X-Xs+1, Y+Ys-1, GetColour);
PutPixel(X+Ys-1, Y+Xs-1, GetColour);
PutPixel(X-Ys+1, Y+Xs-1, GetColour);
Until (Xs >= Ys);
end;
Procedure InitPlayers;
Var count: byte;
Begin
For count:= 1 to MaxPlayers do
With PlayerRec[count] do
Begin
Warp(Count);
PlayerMessage:='Player '+chr(48+Count)+' ready !';
MessageTime:=NormalMessageTime;
ExplodeWidth:=0;
PlayerColour:=ColourTable[Count];
PlayerWraps:=True;
PlayerSpeed:=4;
NormalPlayerSpeed:=PlayerSpeed;
SlowedDownTime:=0;
PlayerWait:=1;
WaitCount:=15;
MaxWaitCount:=WaitCount;
Thrusting:=False;
InvulnerableTime:=MaxInvulnerableTime; { So if you warp into Paccy you
can still get away }
BanzaiTime:=0;
PlayerEnergy:=20;
MaxPlayerEnergy:=PlayerEnergy;
RechargeTime:=40;
RechargeLatch:=RechargeTime;
RechargeDeduction:=10;
KeyReverseTime:=0;
AssFiring:=False;
DisableTime:=0;
AutoFire:=True;
FireKeyReleased:=true;
FireDelay:=3;
FireLatch:=FireDelay;
CurrentLaserType:=NormalLaser;
CurrentLaserPower:=1;
CurrentLaserSpeed:=8;
CurrentMaxLaserTravel:=80;
LaserDeduction:=1;
LaserHurts:=False;
EnemyLaserHurts:=True;
PlayerScore:=0;
End;
End;
{
Flush laser array
}
Procedure InitLasers;
Var Count: byte;
Begin
LasersFired:=0;
LastLaserIndex:=1;
For Count:=1 to MaxLasers do
With LaserRec[Count] do
LaserType:=LaserFree;
End;
{$IFDEF BONUSES}
Procedure InitBonuses;
Var Count: byte;
Begin
BonusesOnScreen:=0;
BonusString:='SEFRDIANTLWB?'; { Not explaining what this is for }
For Count:= 1 to MaxBonuses do
With BonusRec[Count] do
Begin
BonusType:=0;
End;
End;
{$ENDIF}
Procedure SetUpPlayers;
var Count: word;
keyhit: char;
PromptLatch: byte;
PromptTime: byte;
TextRefreshCount: byte;
Begin
For Count:=0 to 359 do
Begin
QCos[Count]:=Cos(Count * (PI/180));
QSin[Count]:=Sin(Count * (PI/180));
end;
{ Assign player colours }
For Count:=1 to MaxPlayers do
ColourTable[Count]:=256-Count;
Randomize;
PlayersOn:=MaxPlayers;
PlayersAlive:=PlayersOn;
InitPlayers;
InitLasers;
{$IFDEF BONUSES}
InitBonuses;
{$ENDIF}
{
Now draw the title screen
}
PromptLatch:=50;
PromptTime:=PromptLatch;
TextRefreshCount:=0;
SetPalette(254, 63,0,0);
SetPalette(255, 63,63,0);
Repeat
BitMapCopy(titleBitmapSeg,titleBitmapOfs);
SelectFont(6);
TextXY(92,8,'SPACE LORDS 7«');
SelectFont(1);
TextXY(32,70, 'PROGRAMMING BY : Scott Tunstall');
if (TextRefreshCount < 4) Then
Begin
TextXY(32,96, 'VECTOR GFX BY : Scott Tunstall');
TextXY(32,112, 'PAC MAN BY : Namco (tm)');
TextXY(32,128, 'DIRTY WOMEN AT : MarketGait');
end
else
Begin
SelectFont(Font8x16);
TextXY(48,96, 'SO RONNY NOW DO YOU BELIEVE');
TextXY(48,114, 'THAT I WROTE THIS PROGRAM ?');
SelectFont(Int43Font);
End;
Delay(1);
Dec(PromptTime);
If PromptTime=0 Then
Begin
PromptTime:=50;
Inc(TextRefreshCount);
Asm
AND BYTE PTR TextRefreshCount, $7
End;
End;
If (PromptTime > 25) Then
Begin
TextXY(32,162,'PRESS SPACE TO BEGIN THE GAME !');
End;
SelectFont(Font8x16);
TextXY(32,180,'Program (C) 1995 Scott Tunstall.');
CopySourceBitmap ;
if keypressed then
keyhit:=readkey;
Until keyhit = ' ';
End;
Procedure DrawPlayerStuff;
var PlayerCount: byte;
OriginX: integer;
OriginY: integer;
Angle: integer;
LineCount: byte;
CircCount: byte;
TempString: string[6];
Begin
UseFont(1);
For PlayerCount:=1 to PlayersOn do
With PlayerRec[PlayerCount] do
Begin
Str(PlayerScore,TempString);
SetColour(PlayerColour);
OutTextXY(0,192- PlayerCount SHL 3,TempString);
If MessageTime <>0 Then
Begin
Dec(MessageTime);
{$IFDEF FULLDISPLAY}
TextXY(56,192-PlayerCount SHL 3,PlayerMessage);
SetColour(PlayerColour);
{$ELSE}
OutTextXY(56,192-PlayerCount SHL 3,PlayerMessage);
{$ENDIF}
End;
{
Time to draw the ship. I am quite pleased that this
routine is fairly fast.
}
If (PlayerStatus And ShootAble)=ShootAble Then
Begin
If (InvulnerableTime >10) Or
(InvulnerableTime MOD 2 = 1) Then
Circle(PlayerX,PlayerY,12);
If (BanzaiTime = 0) Or ((BanzaiTime MOD 8 )>3 ) Then
Begin
Angle:=PlayerAngle;
{
Nose of ship is 8 pixels away from
the start area at degree
}
OriginX:=PlayerX+ Round(QCos[Angle] * 8);
OriginY:=PlayerY+ Round(QSin[Angle] * 8);
MoveTo(OriginX,OriginY);
Asm
MOV AX,Angle
ADD AX,135
CMP AX,360
JB @ThisAngleIsOK1
SUB AX,360
@ThisAngleIsOK1:
MOV Angle,AX
End;
LineTo(PlayerX+ Round(QCos[Angle] * 8),
PlayerY+ Round(QSin[Angle] * 8));
;
Asm
MOV AX,Angle
ADD AX,45
CMP AX,360
JB @ThisAngleIsOK2
SUB AX,360
@ThisAngleIsOK2:
MOV Angle,AX
End;
LineTo(PlayerX+Round(QCos[Angle] * 2),
PlayerY+Round(QSin[Angle] * 2));
Asm
MOV AX,Angle
ADD AX,45
CMP AX,360
JB @ThisAngleIsOK3
SUB AX,360
@ThisAngleIsOK3:
MOV Angle,AX
End;
LineTo(PlayerX+Round(QCos[Angle] * 8),
PlayerY+Round(QSin[Angle] * 8));
LineTo(OriginX,OriginY);
{$IFDEF FULLDISPLAY}
If Thrusting And (Random(2)=1) Then
Begin
SetColour(Random(255));
Angle:=PlayerAngle;
Asm
MOV AX,Angle { I've tried the other way ! }
ADD AX,150
CMP AX,360
JB @ThisAngleIsOK4
SUB AX,360
@ThisAngleIsOK4:
MOV Angle,AX
End;
MoveTo(PlayerX+Round(QCos[Angle]*5),
PlayerY+Round(QSin[Angle]*5));
Asm
MOV AX,Angle
ADD AX,30
CMP AX,360
JB @ThisAngleIsOK5
SUB AX,360
@ThisAngleIsOK5:
MOV Angle,AX
End;
LineTo(PlayerX+Round(QCos[Angle]*8),
PlayerY+Round(QSin[Angle]*8));
{Inc(Angle,30);
If Angle > 360 Then
Dec(Angle,360);}
Asm
MOV AX,Angle
ADD AX,30
CMP AX,360
JB @ThisAngleIsOK6
SUB AX,360
@ThisAngleIsOK6:
MOV Angle,AX
End;
LineTo(PlayerX+Round(QCos[Angle]*5),PlayerY+Round(QSin[Angle]*5));
End;
{$ENDIF}
SetColour(PlayerColour);
OriginX:=PlayerX-12;
OriginY:=PlayerY+12;
Line(OriginX,OriginY,OriginX + PlayerEnergy,OriginY);
End;
End
Else
If (PlayerStatus = Exploding) Or (PlayerStatus = Warping) Then
Begin
For circcount:=0 to 40 do
PutPixel(PlayerX+Round(QCos[circcount SHL 3]*ExplodeWidth),
PlayerY+Round(QSin[circcount SHL 3]*ExplodeWidth),PlayerColour);
End;
End;
End;
{
Put the lasers on the screen.
}
Procedure DrawLasers;
var LaserCount: byte;
Begin
If LasersFired <>0 Then
For LaserCount:=1 to MaxLasers do
If LaserRec[LaserCount].LaserType <> LaserFree Then
With LaserRec[LaserCount] do
Begin
SetColour(LaserColour);
MoveTo(LaserX,LaserY);
LineRel(Round(QCos[LaserAngle]*LaserSize),
Round(QSin[LaserAngle]*LaserSize));
End;
End;
{$IFDEF BONUSES}
Procedure DrawBonuses;
var BonusCount: byte;
Begin
SetColour(255);
If BonusesOnScreen <>0 Then
For BonusCount:=1 to MaxBonuses do
With BonusRec[BonusCount] do
If BonusType <>0 Then
Begin
Circle(BonusX+4,BonusY+4,12);
{$IFDEF FULLDISPLAY}
UseFont(Font8x14);
TextXY(BonusX,BonusY,BonusString[BonusType]);
{$ELSE}
OutTextXY(BonusX,BonusY,BonusString[BonusType]);
{$ENDIF}
End;
End;
{$ENDIF}
Procedure CheckBounds(Var XPos,YPos:integer;
ObjectWraps: boolean;
Var DidWrap:boolean); Assembler;
Asm
CMP ObjectWraps,1
JNE @ObjectDoesNotWrap
MOV SI,RightBoundary
MOV DI,LeftBoundary
MOV CX,BottomBoundary
MOV DX,TopBoundary
JMP @LetsDoThisshit
@ObjectDoesNotWrap:
MOV SI,LeftBoundary
MOV DI,RightBoundary
MOV CX,TopBoundary
MOV DX,BottomBoundary
@LetsDoThisshit:
XOR AL,AL
LES BX,XPos
MOV BX,[ES:BX]
CMP BX,LeftBoundary
JG @XPosMoreThanLeft
LES DI,XPos
MOV [ES:DI],SI
INC AL
JMP @NowTestVertical
@XPosMoreThanLeft:
CMP BX,RightBoundary
JL @NowTestVertical
LES SI,Xpos
MOV [ES:SI],DI
INC AL
@NowTestVertical:
LES BX,Ypos
MOV BX,[ES:BX]
CMP BX,TopBoundary
JG @YPosMoreThanTop
LES DI,Ypos
MOV [ES:DI],CX
MOV AL,1
JMP @Finito
@YPosMoreThanTop:
CMP BX,BottomBoundary
JL @Finito
LES DI,YPos
MOV [ES:DI],DX
MOV AL,1
@Finito:
LES DI,DidWrap
MOV [ES:DI],AL
End;
Procedure AddLaser(LaserToAdd: Laser);
Var VacantLaserNumber: byte;
LaserCount: byte;
Begin
If LaserRec[LastLaserIndex].LaserType = LaserFree Then
VacantLaserNumber:=LastLaserIndex
Else
Begin
VacantLaserNumber:=$FF;
For LaserCount:=1 to MaxLasers do
Begin
If LaserRec[LaserCount].LaserType = LaserFree Then
Begin
VacantLaserNumber:=LaserCount;
LaserCount:=MaxLasers;
End;
End;
End;
If VacantLaserNumber <> $FF Then
Begin
Inc(LasersFired);
LaserRec[VacantLaserNumber]:=LaserToAdd;
End;
End;
Procedure DoFireRoutine(ShipNo:byte);
Var TAngle: word;
Begin
If LasersFired <> MaxLasers Then
With PlayerRec[ShipNo] do
Begin
TempLaser.LaserType:=CurrentLaserType;
TempLaser.FiredBy:=ShipNo;
If AssFiring Then
Begin
TempLaser.LaserX:=PlayerX-Round(QCos[PlayerAngle] * 6);
TempLaser.LaserY:=PlayerY-Round(QSin[PlayerAngle] * 6);
TAngle:=PlayerAngle+180;
Asm
MOV AX,TAngle
CMP AX,360
JB @NoReset
SUB AX,360
@NoReset:
MOV Tangle,AX
End;
TempLaser.LaserAngle:= TAngle;
End
Else
Begin
Templaser.LaserX:=PlayerX+Round(QCos[PlayerAngle] * 6);
Templaser.LaserY:=PlayerY+Round(QSin[PlayerAngle] * 6);
Templaser.LaserAngle:= PlayerAngle;
End;
{ Make sure you know who fired the laser }
TempLaser.LaserColour:=PlayerColour;
TempLaser.LaserPower:=CurrentLaserPower;
TempLaser.LaserSize:= PlayerLaserSize;
TempLaser.LaserSpeed:=CurrentLaserSpeed;
TempLaser.MaxLaserTravel:=CurrentMaxLaserTravel;
AddLaser(TempLaser);
Dec(PlayerScore,DeductionForShooting);
If PlayerScore < 0 Then PlayerScore:=0;
End;
End;
Procedure AlterShip(ShipNo:byte;UpKey,DownKey,LeftKey,RightKey,FireKey:boolean);
Var DiscardedVar: boolean;
TempKey: boolean;
Begin
With PlayerRec[ShipNo] do
Begin
If UpKey Then
Begin
Thrusting:=True;
If WaitCount > 1 Then
Dec(WaitCount);
End
Else
Begin
Thrusting:=False;
If WaitCount < MaxWaitCount Then
Inc(WaitCount)
Else
Begin
Dec(RechargeTime);
If (RechargeTime = 0) And
(PlayerEnergy < MaxPlayerEnergy) And
(PlayerScore >= RechargeDeduction) Then
Begin
RechargeTime:=RechargeLatch;
Inc(PlayerEnergy);
Dec(PlayerScore, RechargeDeduction);
End;
End;
End;
If KeyReverseTime <>0 Then
Begin
TempKey:=LeftKey;
LeftKey:=RightKey;
RightKey:=TempKey;
End;
If LeftKey Then
Begin
Dec(PlayerAngle,ShipTurnAngle);
If PlayerAngle <1 Then
Inc(PlayerAngle,360);
End;
If RightKey Then
Begin
Inc(PlayerAngle,ShipTurnAngle);
If PlayerAngle > 359 Then
Dec(PlayerAngle,360);
End;
{
Has the player held down the fire button.
}
If FireKey Then
Begin
If (DisableTime=0) Then
Begin
If AutoFire Then
Begin
If FireDelay = 0 Then
Begin
FireDelay:=FireLatch;
DoFireRoutine(ShipNo);
End
Else
Dec(FireDelay);
End
Else
If FireKeyReleased Then
Begin
FireKeyReleased:=False;
DoFireRoutine(ShipNo);
End;
End;
End
Else
FireKeyReleased:=True;
If WaitCount <> MaxWaitCount Then
Begin
Inc(PlayerWait);
If PlayerWait >= WaitCount Then
Begin
PlayerWait:=0;
Inc(PlayerX, Round(Qcos[PlayerAngle]*PlayerSpeed));
Inc(PlayerY, Round(QSin[PlayerAngle]*PlayerSpeed));
CheckBounds(PlayerX,PlayerY,PlayerWraps,DiscardedVar);
End;
End;
End;
End;
Procedure UpDatePlayersSpin(PlayerNo:byte);
Var DiscardedVar: boolean;
Begin
With PlayerRec[PlayerNo] do
Begin
Inc(PlayerAngle,ShipTurnAngle SHL 3);
If PlayerAngle > 359 Then Dec(PlayerAngle,360);
Inc(PlayerX, Round(Qcos[SpinAngle]*SpinSpeed));
Inc(PlayerY, Round(QSin[SpinAngle]*SpinSpeed));
CheckBounds(PlayerX,PlayerY,PlayerWraps,DiscardedVar);
End;
End;
{$IFNDEF BONUSES}
Procedure UpDateBonusTimer(PlayerNo:byte);
Begin
{ Shields }
With PlayerRec[PlayerNo] do
If InvulnerableTime <>0 Then
Begin
Dec(InvulnerableTime);
If InvulnerableTime = 0 Then
Begin
PlayerMessage:='SHIELDS DOWN!';
MessageTime:=NormalMessageTIme;
EnemyLaserHurts:=True;
End;
End;
End;
{$ELSE}
Procedure UpdateBonusTimers(PlayerNo:byte);
Begin
With PlayerRec[PlayerNo] do
Begin
{ Firing }
If DisableTime <>0 Then
Begin
Dec(DisableTime);
If DisableTime = 0 Then
Begin
PlayerMessage:='I CAN SHOOT AGAIN!';
MessageTime:=NormalMessageTime;
End;
End;
{ Slothfullness }
If SlowedDownTime <>0 Then
Begin
Dec(SlowedDownTime);
If SlowedDownTime = 0 Then
PlayerSpeed:=NormalPlayerSpeed;
End;
{ Key reversing, i.e. press key for left and you go right }
If KeyReverseTime <>0 Then
Dec(KeyReverseTime);
{ Shields }
If InvulnerableTime <>0 Then
Begin
Dec(InvulnerableTime);
If InvulnerableTime = 0 Then
Begin
PlayerMessage:='SHIELDS DOWN!';
MessageTime:=NormalMessageTIme;
EnemyLaserHurts:=True;
End;
End;
{ Toody's special bonus }
If BanzaiTime <> 0 Then
Begin
Dec(BanzaiTime);
If BanzaiTime = 0 Then
Begin
PlayerMessage:='TOODY''S POWER GONE!';
MessageTime:=NormalMessageTime;
End;
End;
End;
End;
{$ENDIF}
{
You have to check the player's status byte to determine whether
or not he's spinning, frozen, etc.
}
Procedure CheckPlayerStatusByte(PlayerNo:byte);
Begin
With PlayerRec[PlayerNo] Do
Begin
{
Now service the PlayerStatus bits
}
If (PlayerStatus And Frozen)=Frozen Then
Begin
If FrozenTime > 0 Then
Dec(FrozenTime)
Else
PlayerStatus:=PlayerStatus And (255-Frozen);
End;
If (PlayerStatus And Spinning)=Spinning Then
Begin
Dec(SpinCount);
If SpinCount <>0 Then
UpdatePlayersSpin(PlayerNo)
Else
Begin
PlayerStatus:= ShootAble;
WaitCount:=MaxWaitCount;
End;
End
Else
If PlayerStatus = Exploding Then
Begin
Inc(ExplodeWidth,5);
If ExplodeWidth >= MaxExplodeWidth Then
Begin
PlayerStatus:= Dead;
Dec(PlayersAlive);
End;
End
Else
If PlayerStatus = Warping Then
Begin
Dec(ExplodeWidth,5);
If ExplodeWidth <=5 Then
PlayerStatus:=ShootAble;
End;
End;
End;
{
Update the player's ships.
PlayerStatus is a combination of BIT FLAGS which indicate to the
program the current player status. Doh!
If bit 0 of PlayerStatus is set then the player is still ShootAble. (i.e. Alive)
If bit 1 of PlayerStatus is set then the player is Warping.
If bit 2 of PlayerStatus is set then the player is Exploding.
If bit 3 of PlayerStatus is set then the Player is Spinning.
If bit 4 of PlayerStatus is set the player is Frozen.
Bits 5 - 7 are undefined and should stay that way for now.
}
Procedure MoveShips;
Var PlayerCount: byte;
Begin
For PlayerCount:=1 to PlayersOn do
With PlayerRec[PlayerCount] do
If (PlayerStatus = ShootAble) Then
Begin
Case PlayerCount Of
1: AlterShip(1,keydown[2],keydown[15],keydown[30],keydown[45],keydown[42]);
2: AlterShip(2,keydown[24],keydown[38],keydown[39],keydown[40],keydown[52]);
3: AlterShip(3,keydown[71],keydown[76],keydown[73],keydown[74],keydown[81]);
End;
{$IFNDEF BONUSES}
UpdateBonusTimer(PlayerCount);
{$ELSE}
UpdateBonusTimers(PlayerCount);
{$ENDIF}
End
Else
CheckPlayerStatusByte(PlayerCount);
End;
{
O.K. You've got to update the lasers (and special weapons later
on, perhaps)
}
Procedure MoveLasers;
var playercount: byte;
LaserCount: byte;
ItWrapped: boolean;
Begin
If LasersFired <>0 Then
Begin
For LaserCount:=1 to MaxLasers do
With LaserRec[LaserCount] do
Begin
If LaserType<>LaserFree Then
Begin
Inc(LaserTravel);
If LaserTravel < MaxLaserTravel Then
Begin
Inc(LaserX, Round(Qcos[LaserAngle]*LaserSpeed));
Inc(LaserY, Round(QSin[LaserAngle]*LaserSpeed));
CheckBounds(LaserX,LaserY, LaserType = LaserWraps,ItWrapped);
If ItWrapped Then
Begin
Case LaserType of
NormalLaser: Begin
LaserType:=LaserFree;
LastLaserIndex:=LaserCount;
Dec(LasersFired);
End;
LaserRebound: LaserAngle:=Random(359);
End;
End;
End
Else
Begin
LaserType:=LaserFree;
Dec(LasersFired);
LastLaserIndex:=LaserCount;
End;
End;
End;
End;
End;
{$IFDEF BONUSES}
{
The Bonuses are not player controlled (of course) so therefore
the MoveBonuses routine should initiate some bonuses as well
as move them.
How will the CPU know when to initiate bonuses? Well as you
know, it can't so It'll have to be a purely random thingie.
}
Procedure MoveBonuses;
Var BonusCount: byte;
SearchCount: byte;
BonusDidWrap: boolean;
Begin
If BonusesOnScreen <>0 Then
For BonusCount:=1 to MaxBonuses do
With BonusRec[BonusCount] do
If BonusType <>0 Then
Begin
Inc(BonusX,BonusXIncrement);
Inc(BonusY,BonusYIncrement);
CheckBounds(BonusX,BonusY,true,BonusDidWrap);
End;
{
Of course, some bonuses just have to be initialised as
well !
}
If (BonusesOnScreen <= MaxBonuses) And (Random(80)=40) Then
Begin
SearchCount:=1;
Repeat
With BonusRec[SearchCount] do
If BonusType = 0 Then
Begin
Inc(BonusesOnScreen);
BonusType:=1+(Random(NumberOfBonuses));
BonusX:=Random(319);
Case Random(3) of
0..1: BonusY:=-1;
2..3: BonusY:=200;
End;
Case Random(3) of
0..1: BonusXIncrement:=-1;
2..3: BonusXIncrement:=1;
End;
Case Random(3) of
0..1: BonusYIncrement:=-1;
2..3: BonusYIncrement:=1;
End;
SearchCount:=MaxBonuses;
End;
Inc(SearchCount);
Until SearchCount > MaxBonuses;
End;
End;
{$ENDIF}
Function Collision(X1,Y1,X2,Y2:integer;DistX,DistY:word): boolean; {Assembler;}
Begin
Collision:=(Abs(X2-X1) < DistX) And (Abs(Y2-Y1) < DistY)
End;
{===================================================================
Guess what this routine does ?
}
Procedure UpdatePlayerScore(PlayerNo: byte; HowManyPoints: integer);
Begin
With PlayerRec[PlayerNo] do
Begin
Inc(PlayerScore,HowManyPoints);
If PlayerScore > $7FFFFFFF Then
PlayerScore := $7FFFFFFF;
End;
End;
{=====================================================
I'm gonna have to optimize this one day.. For now tho'
I'll leave it as it is so that the B.Sc chaps can suss
what's happening..
}
Procedure DoPlayerToLaser;
Var PlayerCount: byte;
LaserCount: byte;
Object1X: integer;
Object2X: integer;
Object1Y: integer;
Object2Y: integer;
TempLaserPower: byte;
PersonWhoShot: byte;
Begin
If LasersFired <>0 Then
For PlayerCount:=1 to PlayersOn do
With PlayerRec[PlayerCount] do
If ((PlayerStatus AND Shootable)<>0) Then
Begin
Object2X:=PlayerX;
Object2Y:=PlayerY;
For LaserCount:=1 to MaxLasers do
If (LaserRec[LaserCount].LaserType <> LaserFree) Then
Begin
With LaserRec[LaserCount] do
Begin
Object1X:=LaserX;
Object1Y:=LaserY;
End;
If Collision( Object1X,Object1Y,
Object2X,Object2Y,8,8) Then
Begin
PersonWhoShot:=LaserRec[LaserCount].FiredBy;
With PlayerRec[PersonWhoShot] do
Begin
Inc(PlayerScore,PointsForShooting);
If Playerscore > $7FFFFF Then
PlayerScore:= $7fffff;
End;
{
Player has been hit so make the missile
whack into the ships side and disappear
}
With PlayerRec[PlayerCount] do
If (InvulnerableTime <>0) Then
LaserRec[LaserCount].LaserAngle:=Random(359)
Else
Begin
Dec(LasersFired);
LaserRec[LaserCount].LaserType:=LaserFree;
TempLaserPower:=LaserRec[LaserCount].LaserPower;
If LaserRec[LaserCount].Firedby <> PlayerCount Then
Begin
Dec(PlayerEnergy,TempLaserPower);
If PlayerEnergy <= 0 Then
Begin
PlayerStatus:=Exploding;
ExplodeWidth:=0;
End;
End;
End;
End;
End;
End;
End;
{==========================================================
Guess what this does ?
}
Procedure SpinPlayer( PlayerBumped, PlayerWhoBumped: byte);
Var SpeedVar: byte;
Ratio: byte;
begin
With PlayerRec[PlayerBumped] do
Begin
PlayerStatus:=PlayerStatus OR Spinning;
SpeedVar := PlayerRec[PlayerWhoBumped].WaitCount;
Ratio := PlayerRec[PlayerWhoBumped].MaxWaitCount - SpeedVar;
WaitCount:=SpeedVar;
SpinAngle:=PlayerRec[PlayerWhoBumped].PlayerAngle;
SpinSpeed:= (Ratio SHR 2)+4;
SpinCount:= (Ratio SHL 1)+4;
UpDatePlayersSpin(PlayerBumped);
End
End;
{
Check if two players did bump
}
{$IFDEF BUMPING }
Procedure CheckBump(PlayerCount1, PlayerCount2 : byte);
var
PlayerSpeed1: byte;
PlayerSpeed2: byte;
Begin
If (PlayerRec[PlayerCount1].PlayerStatus = Exploding)
Or (PlayerRec[PlayerCount2].PlayerStatus = Exploding) Then Exit;
If (PlayerRec[PlayerCount1].BanzaiTime <>0) And
(PlayerRec[PlayerCount2].InvulnerableTime = 0) Then
With PlayerRec[PlayerCount2] do
Begin
PlayerStatus:=Exploding;
ExplodeWidth:=0;
Message:='AARGH etc. etc. !!';
MessageTime:=NormalMessageTime;
End
Else
Begin
PlayerSpeed1:= PlayerRec[PlayerCount1].WaitCount;
PlayerSpeed2:= PlayerRec[PlayerCount2].WaitCount;
If (PlayerSpeed2 <= PlayerSpeed1) Then
SpinPlayer(PlayerCount1,PlayerCount2)
Else
UpdatePlayerScore(PlayerCount1,PointsForBumping);
End;
End;
{$ENDIF}
{$IFDEF BUMPING}
Procedure DoPlayerToPlayer;
Var PlayerCount1: byte;
PlayerCount2: byte;
Object1X: integer;
Object2X: integer;
Object1Y: integer;
Object2Y: integer;
Begin
For PlayerCount1:=1 to PlayersOn do
If (PlayerRec[PlayerCount1].PlayerStatus AND Shootable =
ShootAble) Then
Begin
With PlayerRec[PlayerCount1] do
Begin
Object1X:=PlayerX;
Object1Y:=PlayerY;
End;
{
Check if the two ships have bumped into each other.
Not too keen on what I wrote for this part but it works.
As I said when me B.Sc is finished this part will be
upgraded.
}
For PlayerCount2:=1 to PlayersOn do
If (PlayerRec[PlayerCount2].PlayerStatus And
Shootable = Shootable) And
(PlayerCount1 <> PlayerCount2) Then
Begin
{
Check if a collision has occurred.
}
With PlayerRec[PlayerCount2] do
Begin
Object2X:=PlayerX;
Object2Y:=PlayerY;
End;
{
Bumping?
}
If Collision(Object1X,Object1Y,Object2X,Object2Y,12,12)
Then
Begin
CheckBump(PlayerCount1, PlayerCount2);
CheckBump(PlayerCount2, PlayerCount1);
End;
End;
End;
End;
{$ENDIF}
Procedure Warp(PlayerNo:byte);
Begin
With PlayerRec[PlayerNo] do
Begin
PlayerStatus:=Warping;
ExplodeWidth:=MaxExplodeWidth;
PlayerAngle:= Random(359);
PlayerX:=Random(319);
PlayerY:=Random(199);
End;
End;
{$IFDEF BONUSES}
Procedure DoPlayerToBonuses;
Var PlayerCount: byte;
BonusCount: byte;
OtherCount: byte;
Object1X: integer;
Object2X: integer;
Object1Y: integer;
Object2Y: integer;
Begin
For PlayerCount:=1 to PlayersOn do
If (PlayerRec[PlayerCount].PlayerStatus And Shootable) = Shootable
Then Begin
With PlayerRec[PlayerCount] do
Begin
Object1X:=PlayerX;
Object1Y:=PlayerY;
End;
For BonusCount:=1 to MaxBonuses do
If (BonusRec[BonusCount].BonusType <>0 ) Then
Begin
With BonusRec[BonusCount] do
Begin
Object2X:=BonusX;
Object2Y:=BonusY;
End;
If collision( Object1X,Object1Y,
Object2X,Object2Y,12,12) Then
With BonusRec[BonusCount] do
Begin
If BonusType = UnknownBonus Then
BonusType:= Random(NumberOfBonuses-2)+1;
Case BonusType Of
SlowDownBonus: begin
With PlayerRec[PlayerCount] do
Begin
Inc(PlayerScore,SlowDownBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='PICKED UP A SLOWDOWN BONUS !';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
For OtherCount:=1 to PlayersOn do
If OtherCount <> PlayerCount Then
With PlayerRec[OtherCount] do
Begin
If PlayerSpeed <>SlowestPlayerSpeed Then
Dec(PlayerSpeed);
Inc(SlowedDownTime,MaxSlowedDownTime);
End;
End;
EnergyBonus: With PlayerRec[PlayerCount] do
Begin
Inc(PlayerScore,EnergyBonusPointsValue);
Inc(PlayerEnergy,EnergyIncrement);
If PlayerEnergy >MaxPlayerEnergy Then
Begin
PlayerEnergy:=MaxPlayerEnergy;
{$IFDEF MESSAGES}
PlayerMessage:='I DIDN''T NEED THE ENERGY !';
MessageTime:=NormalMessageTime;
{$ENDIF}
{$IFDEF MESSAGES}
End
Else
If PlayerEnergy <= EnergyIncrement Then
Begin
PlayerMessage:='ENERGY JUST IN TIME, TOO !';
MessageTime:=NormalMessageTime;
End
Else
Begin
PlayerMessage:='PICKED UP AN ENERGY BONUS !';
messageTime:=NormalMessageTime;
End;
{$ENDIF}
End;
FreezeBonus: Begin
With PlayerRec[PlayerCount] do
Begin
Inc(PlayerScore,FreezeBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='PICKED UP A FREEZE BONUS !';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
For OtherCount:=1 to PlayersOn do
If OtherCount <> PlayerCount Then
With PlayerRec[OtherCount] do
Begin
PlayerStatus:=PlayerStatus OR Frozen;
Inc(FrozenTime,MaxFrozenTime);
WaitCount:=MaxWaitCount;
End;
End;
ReverseBonus: Begin
With PlayerRec[PlayerCount] do
Begin
Inc(PlayerScore,ReverseBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='PICKED UP A REVERSE BONUS !';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
For OtherCount:=1 to PlayersOn do
If OtherCount <> PlayerCount Then
With PlayerRec[OtherCount] do
Begin
Inc(KeyReverseTime,MaxKeyReverseTime);
PlayerMessage:='OH NO! KEYS ARE REVERSED !';
MessageTime:=NormalMessageTime;
End;
End;
DisableBonus: Begin
With PlayerRec[PlayerCount] do
Begin
Inc(PlayerScore,DisableBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='PICKED UP A DISABLE BONUS !';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
For OtherCount:=1 to PlayersOn do
If OtherCount <> PlayerCount Then
Inc(PlayerRec[OtherCount].DisableTime,MaxDisableTime);
End;
InvulnerabilityBonus: Begin
With PlayerRec[PlayerCount] do
Begin
EnemyLaserHurts:=False;
InvulnerableTime:=MaxInvulnerableTime;
Inc(PlayerScore,InvulnerabilityBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='YEAH! I AM INVULNERABLE !';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
End;
AssFiringBonus: Begin
With PlayerRec[PlayerCount] do
Begin
Inc(PlayerScore,AssFiringBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='PICKED UP AN Ass FIRING BONUS !';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
For OtherCount:=1 to PlayersOn do
If OtherCount <> PlayerCount Then
With PlayerRec[OtherCount] do
Begin
AssFiring:=True;
End;
End;
NormalBonus: Begin
With PlayerRec[Playercount] do
Begin
DisableTime:=1;
KeyReverseTime:=1;
SlowedDownTime:=1;
PlayerSpeed:=NormalPlayerSpeed;
CurrentLaserType:=NormalLaser;
AssFiring:=False;
Inc(PlayerScore,NormalBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='PICKED UP A NORMALITY BONUS.';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
End;
ToodysBonus: Begin
With PlayerRec[PlayerCount] do
begin
Inc(BanzaiTime,MaxBanzaiTime);
Inc(PlayerScore,ToodysBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='BANZAI THE OTHER PLAYERS !';
MessageTime:=MaxBanzaiTime;
{$ENDIF}
End;
For OtherCount:=1 to PlayersOn do
If OtherCount <> PlayerCount Then
With PlayerRec[OtherCount] do
Begin
{$IFDEF MESSAGES}
PlayerMessage:='DO NOT BUMP PLAYER '+chr(48 + PlayerCount)+' !';
MessageTime:=MaxBanzaiTime;
{$ENDIF}
End
End;
LaserBonus: Begin
With PlayerRec[PlayerCount] do
If CurrentLaserPower < MaxLaserPower Then
Begin
Inc(CurrentlaserPower);
Inc(PlayerScore,LaserBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='LASERS ENHANCED !';
MessageTime:=NormalMessageTime;
{$ENDIF}
End
Else
Begin
PlayerMessage:='WRAP AROUND LASERS !';
CurrentLaserType:=LaserWraps;
MessageTime:=NormalMessageTime;
End;
End;
WarpBonus: With PlayerRec[PlayerCount] do
Begin
Warp(PlayerCount);
Inc(PlayerScore,WarpBonusPointsValue);
{$IFDEF MESSAGES}
PlayerMessage:='WARPING !';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
BounceLaserBonus: With PlayerRec[PlayerCount] do
Begin
CurrentLaserType:= LaserRebound;
{$IFDEF MESSAGES}
PlayerMessage:='OOH! BOUNCY LASERS!';
MessageTime:=NormalMessageTime;
{$ENDIF}
End;
End;
{ Indicate bonus has been taken
}
BonusRec[BonusCount].BonusType:=0;
Dec(BonusesOnScreen);
End;
End;
End;
End;
{$ENDIF}
Procedure DoCollisions;
Begin
DoPlayerToLaser;
{$IFDEF BUMPING}
DoPlayerToPlayer;
{$ENDIF}
{$IFDEF BONUSES}
DoPlayerToBonuses;
{$ENDIF}
End;
Begin
LoadGraphics;
If (PlanetSeg <>0) And (titleBitmapSeg<>0)
And (EmporerSeg<>0) And (ScratchSeg<>0) Then
Begin
Repeat
InitVGAMode;
SetAllPalette(titleBitmapPalette);
SetUpPlayers;
SetAllPalette(DestroyerPalette);
SetPalette(253,63,63,63);
SetPalette(254,63,0,0);
SetPalette(255,63,63,0);
HookKeyboardInt;
SelectFont(1);
Repeat
BitmapCopy(PlanetSeg,PlanetOfs);
DrawPlayerStuff;
DrawLasers;
{$IFDEF BONUSES}
DrawBonuses;
{$ENDIF}
Vwait(1);
CopySourceBitmap ;
MoveShips;
MoveLasers;
{$IFDEF BONUSES}
MoveBonuses;
{$ENDIF}
DoCollisions;
delay(1);
Until (keydown[1]) or (PlayersAlive <= 1);
{ back to normal crap DOS key reading }
UnHookKeyboardInt;
If PlayersAlive <= 1 Then
Begin
Memw[$0040:$1a]:=Memw[$0040:$1c];
SetAllPalette(EmporerPalette);
BitMapCopy(EmporerSeg,EmporerOfs);
SelectFont(6);
SetColour(255);
{
El snido messago (Adjust to suit your peer group)
}
Case Random(20) of
0: Message:='Even Paul Langa has scored more !';
1: Message:='Stop drinking and you''ll shoot better !';
2: Message:='Next time, press the fire button !';
3: Message:='Are you sure that you weren''t cheating ?';
4: Message:='Come in and meet my daughter, son!';
5: Message:='Next time SHOOT the other players !!';
6: Message:='Would you like to see my puppies ?';
7: Message:='Ian Makin has eyebrows just like these !';
9: Message:='';
10: Message:='What a waste of good hard disk space !';
11: Message:='Does your maw know you''re here ?';
12: Message:='I bet you''re one of Tunstall''s mates !';
13: Message:='Your performance was pure f***ing crap !';
14: Message:='Come up and see my etchings, young man !';
15: Message:='You sure did kick some ass out there !';
16: Message:='I bet you drink Carling Black Label !';
17: Message:='Err... I love you.';
18: Message:='I never liked Dune that much anyway !';
19: Message:='Your mum looks like Yoda from Star Wars !';
20: Message:='I''m buying the rounds tonight son !';
End;
OutTextXY( ((40 - Length(Message))DIV 2) *8,160,Message);
CopySourceBitmap ;
Delay(2000);
Memw[$0040:$1a]:=Memw[$0040:$1c];
TempKey:=ReadKey;
End;
Until Keydown[1]; { Until key is definitely ESC }
{
Right, deallocate the memory required for the
game & virtual screens.
}
FreeBitmap(PlanetSeg,PlanetOfs);
FreeBitmap(titleBitmapSeg,TitleBitmapOfs);
FreeBitmap(EmporerSeg, EmporerOfs);
FreeBitmap(ScratchSeg,ScratchOfs);
End
Else
Begin
Writeln;
Writeln('Memory allocation error! 400K bytes free on heap needed.');
End;
End.
{ I love you all !!! ;) }