Browse Source

Graphical version

marco 25 years ago
parent
commit
ddbb4377dd
1 changed files with 212 additions and 44 deletions
  1. 212 44
      install/demo/samegame.pp

+ 212 - 44
install/demo/samegame.pp

@@ -6,10 +6,12 @@
 
 
     SameGame is a standard game in GNOME and KDE. I liked it, and I
     SameGame is a standard game in GNOME and KDE. I liked it, and I
     automatically brainstormed how I would implement it.
     automatically brainstormed how I would implement it.
-    It turned out to be really easy, and is basically only 100 lines or so.
+    It turned out to be really easy, and is basically only 100 lines or so,
+    the rest is scorekeeping, helptext, menu etc.
 
 
     The game demonstrates some features of the MSMOUSE unit, and some of
     The game demonstrates some features of the MSMOUSE unit, and some of
-    the Crt unit.
+    the Crt and Graph units. (depending whether it is compiled with
+    UseGraphics or not)
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -20,19 +22,66 @@
 
 
  **********************************************************************}
  **********************************************************************}
 PROGRAM SameGame;
 PROGRAM SameGame;
-Uses Crt,GameUnit;
 
 
-CONST   FieldX                            = 10; {Top left playfield coordinates}
+Uses Crt,Dos,
+{$IFDEF UseGraphics}
+ Graph,
+{$ENDIF}
+ GameUnit;
+
+CONST
+        GrFieldX                          = 10; {X topleft of playfield}
+        GrFieldY                          = 70; {Y topleft of playfield}
+        ScalerX                           = 22; {ScalerX x Scaler y dots
+                                                  must be approx a square}
+        ScalerY                           = 20;
+        FieldX                            = 10; {Top left playfield
+                                                 coordinates in squares(textmode)}
         FieldY                            =  3; {Top left playfield coordinates}
         FieldY                            =  3; {Top left playfield coordinates}
         PlayFieldXDimension               = 20; {Dimensions of playfield}
         PlayFieldXDimension               = 20; {Dimensions of playfield}
         PlayFieldYDimension               = 15;
         PlayFieldYDimension               = 15;
+        RowDispl                          = 15;
+        MenuX                             = 480;
+        MenuY                             = 120;
+        grNewGameLine                     = 'NEW GAME';
+        grHelpLine                        = 'HELP';
+        grEndGame                         = 'END GAME';
+
 
 
        {Used colors. Colors[0..2] are the colors used on the playfield, Colors[3]
        {Used colors. Colors[0..2] are the colors used on the playfield, Colors[3]
           is the background and Colors[4] is the color used to mark the pieces}
           is the background and Colors[4] is the color used to mark the pieces}
         Colors : ARRAY [0..4] OF LONGINT  = (White,Blue,Red,Black,LightMagenta);
         Colors : ARRAY [0..4] OF LONGINT  = (White,Blue,Red,Black,LightMagenta);
 
 
+
 TYPE PlayFieldType=ARRAY[0..PlayFieldXDimension-1,0..PlayFieldYDimension-1] OF BYTE;
 TYPE PlayFieldType=ARRAY[0..PlayFieldXDimension-1,0..PlayFieldYDimension-1] OF BYTE;
 
 
+{$IFDEF UseGraphics}
+PROCEDURE DisplayPlayField(CONST PlayField:PlayFieldType);
+{Screen routine, simply puts the array Playfield on screen.
+Both used for displaying the normal grid as the grid with a certain area marked}
+
+VAR X,Y : LONGINT;
+    LastOne,
+    NumbLast : LONGINT;
+
+BEGIN
+ HideMouse;
+ FOR Y:=0 TO PlayFieldYDimension-1 DO
+  BEGIN
+   X:=0;
+   REPEAT
+    LastOne:=PlayField[X,Y];
+    NumbLast:=X;
+    WHILE (PlayField[X,Y]=LastOne) AND (X<(PlayFieldXDimension-1))DO
+     INC(X);
+    SetFillStyle(SolidFill,Colors[LastOne]);
+    Bar(GrFieldX+NumbLast*ScalerX,GrFieldY+Y*ScalerY,GrFieldX+X*ScalerX-1,GrFieldY+(Y+1)*ScalerY-1);
+   UNTIL X>=(PlayFieldXDimension-1);
+  END;
+ ShowMouse;
+END;
+{$ELSE}
+
 PROCEDURE DisplayPlayField(CONST PlayField:PlayFieldType);
 PROCEDURE DisplayPlayField(CONST PlayField:PlayFieldType);
 {Screen routine, simply puts the array Playfield on screen.
 {Screen routine, simply puts the array Playfield on screen.
 Both used for displaying the normal grid as the grid with a certain area marked}
 Both used for displaying the normal grid as the grid with a certain area marked}
@@ -50,6 +99,7 @@ BEGIN
     END;
     END;
    END;
    END;
 END;
 END;
+{$ENDIF}
 
 
 PROCEDURE ShowHelp;
 PROCEDURE ShowHelp;
 {Shows some explanation of the game and waits for a key}
 {Shows some explanation of the game and waits for a key}
@@ -57,34 +107,59 @@ PROCEDURE ShowHelp;
 VAR I : LONGINT;
 VAR I : LONGINT;
 
 
 BEGIN
 BEGIN
- FOR I:=2 TO 24 DO
-  BEGIN
-   GotoXY(1,I);
-   ClrEol;
-  END;
- GotoXY(1,3); TextColor(White);
- Write('SAMEGAME');
- SetDefaultColor;
- WriteLn(' is a small game, with a principle copied from some KDE game');
- WriteLn;
- WriteLn('I tried to implement it under Go32V2 to demonstrate the MsMouse unit');
- Writeln('When it worked, I tried to get it running under Linux. I succeeded,');
- Writeln('but the mouse unit of the API doesn'#39't work with GPM 1.17');
- Writeln;
- WriteLn('If you move over the playfield, aggregates of one color will be marked');
- Writeln('in purple. If you then press the left mouse button, that aggregate will');
- Writeln('disappear, and the playfield will collapse to the bottom-left. Please');
- Writeln('keep in mind that only an aggregate of two blocks or more will disappear.');
- Writeln;
- Writeln('For every aggregate you let disappear you get points, but the score is');
- Writeln('quadratic proportional to the number of blocks killed. So 4 times killing');
- Writeln(' a 4 block aggregate scores 4 points, and one time 16 blocks will score 64');
- Writeln('blocks. The purpose of the game is obtaining the highscore');
- Writeln;
- Writeln('If you manage to kill the entire playfield, you'#39'll get a bonus');
- Writeln;
- WriteLn('Press any key to get back to the game');
- GetKey;
+ {$IFDEF UseGraphics}
+  HideMouse;
+  SetbkColor(black);
+  SetViewPort(0,0,getmaxx,getmaxy,clipoff);
+  ClearViewPort;
+  SetTextStyle(0,Horizdir,2);
+  OutTextXY(220,10,'SAMEGAME');
+  SetTextStyle(0,Horizdir,1);
+  OutTextXY(5,40+1*LineDistY,' is a small game, with a principle copied from some KDE game');
+  OutTextXY(5,40+3*LineDistY,'I tried to implement it under Go32V2 to demonstrate the MsMouse unit');
+  OutTextXY(5,40+4*LineDistY,'When it worked, I tried to get it running under Linux. I succeeded,');
+  OutTextXY(5,40+5*LineDistY,'but the mouse unit of the API doesn'#39't work with GPM 1.17');
+  OutTextXY(5,40+7*LineDistY,'If you move over the playfield, aggregates of one color will be marked');
+  OutTextXY(5,40+8*LineDistY,'in purple. If you then press the left mouse button, that aggregate will');
+  OutTextXY(5,40+9*LineDistY,'disappear, and the playfield will collapse to the bottom-left. Please');
+  OutTextXY(5,40+10*LineDistY,'keep in mind that only an aggregate of two blocks or more will disappear.');
+  OutTextXY(5,40+12*LineDistY,'For every aggregate you let disappear you get points, but the score is');
+  OutTextXY(5,40+13*LineDistY,'quadratic proportional to the number of blocks killed. So 4 times killing');
+  OutTextXY(5,40+14*LineDistY,' a 4 block aggregate scores 4 points, and one time 16 blocks will score 64');
+  OutTextXY(5,40+15*LineDistY,'blocks. The purpose of the game is obtaining the highscore');
+  OutTextXY(5,40+17*LineDistY,'If you manage to empty the entire playfield, you'#39'll get a bonus');
+  OutTextXY(5,40+19*LineDistY,'Press any key to get back to the game');
+  ShowMouse;
+ {$ELSE}
+  FOR I:=2 TO 24 DO
+   BEGIN
+    GotoXY(1,I);
+    ClrEol;
+   END;
+  GotoXY(1,3); TextColor(White);
+  Write('SAMEGAME');
+  SetDefaultColor;
+  WriteLn(' is a small game, with a principle copied from some KDE game');
+  WriteLn;
+  WriteLn('I tried to implement it under Go32V2 to demonstrate the MsMouse unit');
+  Writeln('When it worked, I tried to get it running under Linux. I succeeded,');
+  Writeln('but the mouse unit of the API doesn'#39't work with GPM 1.17');
+  Writeln;
+  WriteLn('If you move over the playfield, aggregates of one color will be marked');
+  Writeln('in purple. If you then press the left mouse button, that aggregate will');
+  Writeln('disappear, and the playfield will collapse to the bottom-left. Please');
+  Writeln('keep in mind that only an aggregate of two blocks or more will disappear.');
+  Writeln;
+  Writeln('For every aggregate you let disappear you get points, but the score is');
+  Writeln('quadratic proportional to the number of blocks killed. So 4 times killing');
+  Writeln(' a 4 block aggregate scores 4 points, and one time 16 blocks will score 64');
+  Writeln('blocks. The purpose of the game is obtaining the highscore');
+  Writeln;
+  Writeln('If you manage to empty the entire playfield, you'#39'll get a bonus');
+  Writeln;
+  WriteLn('Press any key to get back to the game');
+ {$ENDIF}
+  GetKey;
 END;
 END;
 
 
 VAR MarkField,PlayField : PlayFieldType; {The playfield, and the marked form}
 VAR MarkField,PlayField : PlayFieldType; {The playfield, and the marked form}
@@ -96,6 +171,7 @@ PROCEDURE ShowButtons;
 {Shows the clickable buttons}
 {Shows the clickable buttons}
 
 
 BEGIN
 BEGIN
+ {$IFNDEF UseGraphics}
  TextColor(Yellow); TextBackGround(Blue);
  TextColor(Yellow); TextBackGround(Blue);
  GotoXY(60,5);   Write('NEW game');
  GotoXY(60,5);   Write('NEW game');
  GotoXY(60,6);   Write('HELP');
  GotoXY(60,6);   Write('HELP');
@@ -103,7 +179,14 @@ BEGIN
  {$IFDEF Linux}
  {$IFDEF Linux}
   GotoXY(60,8);   Write('Force IBM charset');
   GotoXY(60,8);   Write('Force IBM charset');
  {$ENDIF}
  {$ENDIF}
- SetDefaultColor;
+  SetDefaultColor;
+ {$ELSE}
+ SetTextStyle(0,Horizdir,1);
+ OutTextXY(MenuX,MenuY,grNewGameLine);
+ OutTextXY(MenuX,MenuY+RowDispl,grHelpLine);
+ OutTextXY(MenuX,MenuY+2*RowDispl,grEndGame);
+  {$ENDIF}
+
 END;
 END;
 
 
 FUNCTION PlayFieldPiecesLeft:LONGINT;
 FUNCTION PlayFieldPiecesLeft:LONGINT;
@@ -123,11 +206,20 @@ END;
 PROCEDURE ShowScore;
 PROCEDURE ShowScore;
 {Simply procedure to update the score}
 {Simply procedure to update the score}
 
 
+ VAR S : String;
+
 BEGIN
 BEGIN
+ {$IFDEF UseGraphics}
+  Str(Score:5,S);
+  SetFillStyle(SolidFill,0);
+  Bar(300,440,450,458);
+  OutTextXY(300,440,'Score :'+S);
+ {$ELSE}
  TextColor(White);
  TextColor(White);
  GotoXY(20,23);   Write(' ':20);
  GotoXY(20,23);   Write(' ':20);
  GotoXY(20,23);   Write('Score : ',Score);
  GotoXY(20,23);   Write('Score : ',Score);
  SetDefaultColor;
  SetDefaultColor;
+ {$ENDIF}
 END;
 END;
 
 
 FUNCTION CubesToScore : LONGINT;
 FUNCTION CubesToScore : LONGINT;
@@ -237,11 +329,25 @@ PROCEDURE BuildScreen;
 {Some procedures that build the screen}
 {Some procedures that build the screen}
 
 
 BEGIN
 BEGIN
-  ClrScr; Score:=0;
+  {$IFDEF UseGraphics}
+   setbkcolor(black);
+   setviewport(0,0,getmaxx,getmaxy,clipoff);
+   clearviewport;
+  {$ELSE}
+   ClrScr;
+  {$ENDIF}
+  Score:=0;
   ShowScore;
   ShowScore;
   ShowButtons;
   ShowButtons;
   ShowHighScore;
   ShowHighScore;
   ShowMouse;
   ShowMouse;
+  {$IFDEF UseGraphics}
+
+   SetTextStyle(0,Horizdir,2);
+   OuttextXY(10,10,'SameGame v0.03, (C) by Marco v/d Voort. ');
+   SetTextStyle(0,Horizdir,1);
+   OuttextXY(50,40,'A demo for the FPC RTL and API units Crt,(MS)Mouse and Graph');
+  {$ELSE}
   GotoXY(1,1);
   GotoXY(1,1);
   TextColor(Yellow);
   TextColor(Yellow);
   Write('SameGame v0.02');
   Write('SameGame v0.02');
@@ -250,6 +356,7 @@ BEGIN
   TextColor(Yellow); Write('FPC');
   TextColor(Yellow); Write('FPC');
   TextColor(White); Write(' API or MsMouse unit. By Marco van de Voort');
   TextColor(White); Write(' API or MsMouse unit. By Marco van de Voort');
   SetDefaultColor;
   SetDefaultColor;
+  {$ENDIF}
   IF LastScore<>0 THEN
   IF LastScore<>0 THEN
    BEGIN
    BEGIN
     GotoXY(10,20);
     GotoXY(10,20);
@@ -267,6 +374,7 @@ VAR X,Y,
     MX,MY,MState,Dummy : LONGINT;
     MX,MY,MState,Dummy : LONGINT;
     EndOfGame          : LONGINT;
     EndOfGame          : LONGINT;
     S                  : String;
     S                  : String;
+    DoneSomething      : BOOLEAN;
 
 
 BEGIN
 BEGIN
  RANDOMIZE;
  RANDOMIZE;
@@ -276,8 +384,14 @@ BEGIN
   EndOfGame:=0;
   EndOfGame:=0;
   REPEAT
   REPEAT
    GetMouseState(MX,MY,MState);
    GetMouseState(MX,MY,MState);
-   X:=MX SHR 3;
-   Y:=MY SHR 3;
+   {$IFDEF UseGraphics}
+    X:=2*((MX-GrFieldX) DIV ScalerX) +FieldX;
+    Y:=((MY-GrFieldY) DIV ScalerY) +FieldY-1;
+   {$ELSE}
+    X:=MX SHR 3;
+    Y:=MY SHR 3;
+   {$ENDIF}
+   DoneSomething:=FALSE;
    IF PlayFieldPiecesLeft=0 THEN
    IF PlayFieldPiecesLeft=0 THEN
     BEGIN
     BEGIN
      INC(Score,1000);
      INC(Score,1000);
@@ -285,10 +399,21 @@ BEGIN
     END
     END
    ELSE
    ELSE
     BEGIN
     BEGIN
+     {$IFDEF UseGraphics}
+      IF (MX>=MenuX) AND (MX<(MenuX+16*Length(GrNewGameLine))) THEN
+       BEGIN {X in clickable area}
+        IF (MY>=MenuY) AND (MY<(MenuY+RowDispl*3+2)) THEN
+         BEGIN
+          X:=65; {X doesn't matter as long as it is 60..69}
+          Y:=((MY-MenuY) DIV RowDispl)+4;
+         END;
+       END;
+     {$ENDIF}
      IF (X>=60) AND (X<=69) THEN
      IF (X>=60) AND (X<=69) THEN
       BEGIN
       BEGIN
          IF (MState AND LButton) <>0 THEN {If leftbutton pressed,}
          IF (MState AND LButton) <>0 THEN {If leftbutton pressed,}
           BEGIN
           BEGIN
+           DoneSomething:=TRUE;
            IF Y=4 THEN
            IF Y=4 THEN
             EndOfGame:=1;
             EndOfGame:=1;
            IF Y=6 THEN
            IF Y=6 THEN
@@ -311,12 +436,15 @@ BEGIN
       END;
       END;
     IF (X>=(FieldX-2)) AND (Y>=(FieldY-2)) THEN
     IF (X>=(FieldX-2)) AND (Y>=(FieldY-2)) THEN
      BEGIN
      BEGIN
-      DEC(X,FieldX-1); DEC(Y,FieldY-1);
+
+      DEC(X,FieldX-1);
+      DEC(Y,FieldY-1);
       X:=X SHR 1;
       X:=X SHR 1;
       IF (X<PlayFieldXDimension) AND (Y<PlayFieldYDimension) THEN
       IF (X<PlayFieldXDimension) AND (Y<PlayFieldYDimension) THEN
        BEGIN
        BEGIN
         IF MarkField[X,Y]<>4 THEN
         IF MarkField[X,Y]<>4 THEN
          BEGIN
          BEGIN
+          DoneSomething:=TRUE;
           MarkField:=PlayField;
           MarkField:=PlayField;
           MarkAfield(X,Y);
           MarkAfield(X,Y);
           DisplayPlayField(MarkField);
           DisplayPlayField(MarkField);
@@ -326,8 +454,10 @@ BEGIN
           GotoXY(20,22);
           GotoXY(20,22);
           Write('Marked :',CubesToScore);
           Write('Marked :',CubesToScore);
          END;
          END;
-        IF (MState AND LButton) <>0 THEN {If leftbutton pressed,}
+        IF (MarkField[X,Y]=4) AND ((MState AND LButton) <>0) THEN
+                                   {If leftbutton pressed,}
          BEGIN
          BEGIN
+          DoneSomething:=TRUE;
           REPEAT                            {wait untill it's released.
           REPEAT                            {wait untill it's released.
                                            The moment of pressing counts}
                                            The moment of pressing counts}
            GetMouseState(X,Y,Dummy);
            GetMouseState(X,Y,Dummy);
@@ -335,13 +465,13 @@ BEGIN
           Colapse;
           Colapse;
           MarkField:=PlayField;
           MarkField:=PlayField;
           DisplayPlayField(MarkField);
           DisplayPlayField(MarkField);
-        END;
-      END;
+        END
+      END
     END;
     END;
    IF KeyPressed THEN
    IF KeyPressed THEN
     BEGIN
     BEGIN
      X:=GetKey;
      X:=GetKey;
-     IF (X=ORD('X')) OR (X=ORD('x'))  THEN
+     IF (CHR(X) IN ['X','x','Q','q']) OR (X=27) THEN
       EndOfGame:=2;
       EndOfGame:=2;
     END;
     END;
    END;
    END;
@@ -350,9 +480,17 @@ BEGIN
   X:=SlipInScore(Score);
   X:=SlipInScore(Score);
   IF X<>0 THEN
   IF X<>0 THEN
    BEGIN
    BEGIN
+    HideMouse;
     ShowHighScore;
     ShowHighScore;
-    InputStr(S,HighX,HighY+12-X,10,FALSE,AlfaBeta);
+    {$IFDEF UseGraphics}
+     Str(Score:5,S);
+     OutTextXY(HighX+150,HighY+LineDistY*(10-X),S);
+     GrInputStr(S,HighX,HighY+LineDistY*(10-X),16,12,10,FALSE,AlfaBeta);
+    {$ELSE}
+     InputStr(S,HighX,HighY+12-X,10,FALSE,AlfaBeta);
+    {$ENDIF}
     HighScore[X-1].Name:=S;
     HighScore[X-1].Name:=S;
+    ShowMouse;
    END;
    END;
   LastScore:=Score;
   LastScore:=Score;
   UNTIL EndOFGame=2;
   UNTIL EndOFGame=2;
@@ -361,8 +499,26 @@ END;
 CONST FileName='samegame.scr';
 CONST FileName='samegame.scr';
 
 
 VAR I : LONGINT;
 VAR I : LONGINT;
+    Error : LONGINT;
+    {$IFDEF UseGraphics}
+    gd,gm : INTEGER;
+    Pal   : PaletteType;
+    {$ENDIF}
 
 
 BEGIN
 BEGIN
+ {$IFDEF UseGraphics}
+  gm:=vgahi;
+  gd:=vga;
+  InitGraph(gd,gm,'');
+  if GraphResult <> grOk then
+    begin
+      Writeln('Graph driver ',gd,' graph mode ',gm,' not supported');
+      Halt(1);
+    end;
+  SetFillStyle(SolidFill,1);
+  GetDefaultPalette(Pal);
+  SetAllPalette(Pal);
+ {$ENDIF}
   IF NOT MousePresent THEN
   IF NOT MousePresent THEN
    BEGIN
    BEGIN
     Writeln('No mouse found. A mouse is required!');
     Writeln('No mouse found. A mouse is required!');
@@ -373,7 +529,11 @@ BEGIN
   LoadHighScore(FileName);
   LoadHighScore(FileName);
   InitMouse;
   InitMouse;
   CursorOff;
   CursorOff;
-  HighX:=52;   HighY:=10; {the position of the highscore table}
+ {$IFDEF UseGraphics}
+    HighX:=450;   HighY:=220; {the position of the highscore table}
+ {$else}
+    HighX:=52;   HighY:=10; {the position of the highscore table}
+  {$endif}
 
 
   DoMainLoopMouse;
   DoMainLoopMouse;
 
 
@@ -381,13 +541,21 @@ BEGIN
   DoneMouse;
   DoneMouse;
   CursorOn;
   CursorOn;
   SaveHighScore;
   SaveHighScore;
+  {$IFDEF UseGraphics}
+   CloseGraph;
+  {$ENDIF}
   ClrScr;
   ClrScr;
   Writeln;
   Writeln;
   Writeln('Last games'#39' score was : ',Score);
   Writeln('Last games'#39' score was : ',Score);
 END.
 END.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  1999-06-01 19:24:33  peter
+  Revision 1.3  1999-12-31 17:04:22  marco
+
+
+  Graphical version
+
+  Revision 1.2  1999/06/01 19:24:33  peter
     * updates from marco
     * updates from marco
 
 
   Revision 1.1  1999/05/27 21:36:34  peter
   Revision 1.1  1999/05/27 21:36:34  peter