language-Modula2-0.1: examples/Modula-2_Libraries/PMOS/sources/games/pong/pong.mod
MODULE Pong;
(****************************************************************)
(* *)
(* Original author: probably Michael Walsh *)
(* (The copy I got came without comments) *)
(* Debugging by: Peter Moylan *)
(* Last edited: 7 December 1993 *)
(* Status: *)
(* - not yet clear what this program is supposed *)
(* to do. It makes pretty pictures on the *)
(* screen, but purpose is unclear. *)
(* - apparently not responding to keyboard. *)
(* *)
(****************************************************************)
FROM Storage IMPORT
ALLOCATE,DEALLOCATE;
FROM SoundEffects IMPORT
(* proc *) Beep;
FROM Graphics IMPORT
(* type *) ColourType,
(* proc *) Fill,SetMode,PlotMark,PlotLine,GetScreenShape;
FROM Keyboard IMPORT
(* proc *) InKey, KeyPressed;
CONST
Up = 'k';
Down = 'm';
NewBall = ' ';
Quit = 'q';
None = 'a';
PaddleSpeed = 1;
SpeedOfBall = 1;
TYPE
BallPtr=POINTER TO Ball;
Ball=RECORD
Xcoord:CARDINAL;
Ycoord:CARDINAL;
Xdir:INTEGER;
Ydir:INTEGER;
Colour:ColourType;
NextBall:BallPtr;
END; (*Ball Record*)
VAR
Balls,LastBall:BallPtr;
KeyIn:CHAR;
Xmax,Ymax,PaddlePos,PaddleMoveCount:CARDINAL;
LastColour,LastCol,ColourMax:ColourType;
DirLast:INTEGER;
EndOfGame,FirstBall:BOOLEAN;
PROCEDURE MovePaddle(Direction:CHAR; VAR Position:CARDINAL);
VAR
Dir:INTEGER;
BEGIN
IF Direction = Up
THEN
Dir := 5;
ELSE
Dir := -5;
END(*IF*);
IF NOT (((Position <= 5) AND (Direction = Down))
OR ((Position + 55 >= Ymax) AND (Direction = Up)))
THEN
Fill(10,Position,10,Position + 50,0);
IF Dir > 0 THEN
Position := Position + ORD(Dir);
ELSE
Position := Position - ORD(Dir);
END(*iF*);
Fill(10,Position,10,Position + 50,3);
END(*IF*);
END MovePaddle;
PROCEDURE EraseBall(Ball:BallPtr);
BEGIN
Fill(Ball^.Xcoord,Ball^.Ycoord,(Ball^.Xcoord + 10),(Ball^.Ycoord + 10),0);
END EraseBall;
PROCEDURE DrawBall(Ball:BallPtr);
BEGIN
Fill(Ball^.Xcoord,Ball^.Ycoord,(Ball^.Xcoord + 10),(Ball^.Ycoord + 10),(Ball^.Colour));
END DrawBall;
PROCEDURE CreateNewBall(VAR BallList,LastBallOnList:BallPtr;
VAR First:BOOLEAN;
VAR LastDir:INTEGER;
VAR LastCol:ColourType);
BEGIN
IF First THEN
NEW ( LastBall );
BallList := LastBallOnList;
First := FALSE;
ELSE
NEW ( LastBallOnList^.NextBall );
LastBallOnList := LastBallOnList^.NextBall;
END; (* if *)
WITH LastBallOnList^ DO
NextBall := NIL;
Xcoord := Xmax DIV 2;
Ycoord := Ymax DIV 2;
Xdir := ((LastDir MOD 2) *2) -1;
Ydir := ((LastDir DIV 2) * 2) -1;
Colour := LastCol;
LastCol:= (((LastCol + 3) MOD 7) + 1);
END (*WITH*);
DirLast :=(DirLast +1) MOD 4;
END CreateNewBall;
PROCEDURE MoveBalls(StartOfList:BallPtr;PaddlePosition,BallSpeed:CARDINAL);
VAR
CurrentBall:BallPtr;
BEGIN
CurrentBall := StartOfList;
WHILE CurrentBall <> NIL
DO
WITH CurrentBall^ DO
IF (Xcoord >= 2*Xmax - 10 - BallSpeed) OR (Xcoord <= BallSpeed)
THEN
Xdir := -(Xdir);
Colour := ((Colour +1) MOD 7) + 1;
END (*IF*);
IF (Ycoord >= (Ymax -10 - BallSpeed)) OR (Ycoord <= BallSpeed)
THEN
Ydir := -(Ydir);
Colour := ((Colour + 1) MOD 7) + 1;
END(*IF*);
IF ((Ycoord+10 > PaddlePosition)
AND (Ycoord < PaddlePosition + 50)
AND (Xcoord <= 10 + BallSpeed)
AND (Xdir = -1))
THEN
Xdir := -(Xdir);
END(*IF*);
END(*WITH*);
EraseBall(CurrentBall);
WITH CurrentBall^ DO
IF Xdir > 0 THEN
Xcoord := Xcoord + BallSpeed;
ELSE
Xcoord := Xcoord - BallSpeed;
END(*IF*);
IF Ydir > 0 THEN
Ycoord := Ycoord + BallSpeed;
ELSE
Ycoord := Ycoord - BallSpeed;
END(*IF*);
END(*WITH*);
DrawBall(CurrentBall);
CurrentBall := CurrentBall^.NextBall;
END (*DO*);
END MoveBalls;
(****************************************************************)
PROCEDURE RunTheGame;
BEGIN
PlotLine(0,0,0,Ymax,3);
PlotLine(0,Ymax,Xmax,Ymax,3);
PlotLine(Xmax,Ymax,Xmax,0,3);
PlotLine(Xmax,0,0,0,3);
FirstBall := TRUE;
Balls := NIL;
DirLast := 0;
LastColour := 5;
PaddlePos := 1;
KeyIn := None;
REPEAT
(*PaddleMoveCount := 0;
REPEAT
CASE KeyIn OF
Up : MovePaddle(Up,PaddlePos);|
Down : MovePaddle(Down,PaddlePos);|
Quit : EndOfGame := TRUE;|
NewBall : CreateNewBall(Balls,LastBall,FirstBall,DirLast,LastColour);|
None : |
ELSE
CreateNewBall(Balls,LastBall,FirstBall,DirLast,LastColour);
END(*CASE*);
IF KeyPressed() THEN
Beep; KeyIn := InKey();
ELSE
KeyIn := None;
END(*IF*);
PaddleMoveCount := PaddleMoveCount + 1;
UNTIL (EndOfGame) OR (PaddleMoveCount = PaddleSpeed);*)
CreateNewBall(Balls,LastBall,FirstBall,DirLast,LastColour);
MoveBalls(Balls,PaddlePos,SpeedOfBall);
UNTIL EndOfGame;
END RunTheGame;
(****************************************************************)
BEGIN
SetMode(16, TRUE);
GetScreenShape(Xmax,Ymax,ColourMax);
RunTheGame;
END Pong.