home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* BOLO.PAS *)
- (* Mega-Bolo *)
- (* Turbo Pascal ab 5.5 *)
- (* (c) 1990 Peter Messmer & TOOLBOX *)
- (* ------------------------------------------------------ *)
- {$A+,B-,D-,E-,F-,I-,L-,N-,O-,R-,S-,V-}
- {$M 4092,0,655360}
-
- PROGRAM MegaBolo;
-
- USES
- Crt,Graph,Fonts,Drivers;
-
- TYPE
- Image=RECORD
- Size: INTEGER;
- Ima : Pointer;
- END;
- Sou =RECORD
- Frq:INTEGER;
- Del:INTEGER;
- END;
- Spiel=ARRAY[0..97] OF INTEGER;
- Stri=STRING[80];
-
- CONST
- MaxLevel=9;
- MaxBall=5;
- MaxTon=64;
- xKorr=16; (* x-Korrektur des Block-Feldes *)
- yKorr=30; (* y- " " " " *)
- bx=8; (* x-Ausdehnung des Balles *)
- by=6; (* y- " " " *)
- SoundOn:BOOLEAN=TRUE;
- Dicht:FillPatternType=(170,86,170,86,170,86,170,86);
- SoundLen:ARRAY[1..2] OF INTEGER=(48,64);
- Music:ARRAY[1..2,1..MaxTon] OF INTEGER=
- ((594,440,594,704,660,704,594,440,594,704,660,704,594,468,
- 594,704,660,704,594,468,594,704,660,704,594,468,594,792,704,
- 792,594,468,594,792,704,792,594,440,594,792,704,660,562,440,
- 562,792,704,660,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
- (248,495,594,748,248,594,495,248,187,468,562,660,187,562,
- 468,187,220,440,562,660,220,562,440,220,165,418,495,594,165,
- 495,418,165,198,396,495,594,198,495,396,198,149,374,440,594,
- 149,440,374,149,165,330,396,495,165,396,330,165,187,374,468,
- 562,187,468,374,187));
- EGAColors:ARRAY[0..15] OF BYTE=
- (0,114,126,34,29,97,102,113,37,84,111,115,124,26,102,29);
- BlockColor=100;
- LevelNr:ARRAY[1..MaxLevel] OF Spiel=
- ((2,2,0,0,0,0,0,0,0,0,0,0,2,2, (* 1 *)
- 2,0,0,0,0,2,2,2,0,0,0,0,0,2,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,2,1,1,1,1,1,1,1,1,2,0,0,
- 2,0,0,0,0,0,0,0,0,0,0,0,0,2,
- 2,2,2,0,0,0,0,0,0,0,0,2,2,2,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0),
- (1,1,1,1,1,1,1,1,1,0,0,1,1,1, (* 2 *)
- 1,0,0,2,1,2,0,0,1,0,0,1,1,1,
- 1,0,0,2,4,2,0,0,1,1,1,4,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,0,1,1,
- 0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 0,0,2,2,2,2,2,2,2,2,2,2,2,1),
- (0,2,2,0,0,1,2,2,1,0,0,2,2,0, (* 3 *)
- 0,0,1,1,1,0,0,0,0,1,1,1,0,0,
- 2,2,2,0,0,1,5,6,1,0,0,2,2,2,
- 1,0,0,0,0,2,2,2,2,0,0,0,0,1,
- 1,0,0,2,2,1,1,1,1,2,2,0,0,1,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,2,2,0,0,0,0,0,0,2,2,0,0),
- (0,0,0,0,2,6,0,0,6,2,0,0,0,0, (* 4 *)
- 1,1,1,1,1,2,0,0,2,1,1,1,1,1,
- 1,0,0,0,0,0,0,0,0,0,0,0,0,1,
- 1,0,2,2,2,2,1,1,2,2,2,2,0,1,
- 1,0,0,0,0,0,0,0,0,0,0,0,0,1,
- 1,1,1,1,1,0,0,0,0,1,1,1,1,1,
- 0,0,2,2,2,2,5,5,2,2,2,2,0,0),
- (2,2,2,0,0,0,2,2,0,0,0,2,2,2, (* 5 *)
- 2,2,0,0,0,1,1,1,1,0,0,0,2,2,
- 2,0,0,0,1,2,2,2,1,1,0,0,0,2,
- 0,0,0,4,1,1,1,1,1,1,4,0,0,0,
- 0,0,1,1,1,2,7,2,2,1,1,1,0,0,
- 0,1,1,1,2,2,2,2,2,2,1,1,1,0,
- 8,1,1,1,1,1,1,1,1,1,1,1,1,8),
- (1,2,0,0,0,0,1,0,0,0,0,0,1,1, (* 6 *)
- 0,2,1,0,0,5,1,0,0,0,0,1,1,0,
- 0,0,1,2,1,0,0,3,4,0,1,1,0,0,
- 0,0,0,2,1,0,0,4,0,0,0,0,0,0,
- 0,0,0,0,1,1,0,0,0,0,1,2,0,0,
- 0,0,2,2,2,2,2,2,1,1,1,2,2,2,
- 1,1,1,0,0,0,1,1,0,0,0,0,0,0),
- (2,2,2,2,2,2,2,2,2,2,2,2,2,2, (* 7 *)
- 0,0,0,0,0,1,0,0,0,0,0,0,0,1,
- 2,2,2,2,2,2,1,2,2,2,2,2,0,2,
- 2,8,0,0,0,0,0,0,0,0,7,2,0,2,
- 2,0,0,2,2,2,2,2,2,2,2,2,0,2,
- 2,2,0,0,0,0,0,1,0,0,0,0,0,2,
- 1,2,2,2,2,2,2,2,2,2,2,2,2,2),
- (2,2,2,0,0,0,1,1,0,0,0,2,2,2, (* 8 *)
- 2,2,0,0,0,1,1,1,1,0,0,0,2,2,
- 2,0,0,0,1,1,1,1,1,1,0,0,0,2,
- 0,0,0,2,2,1,1,1,1,2,2,0,0,0,
- 2,0,1,1,2,2,1,3,2,2,1,1,0,2,
- 0,1,1,1,1,2,2,2,2,1,1,1,1,0,
- 1,4,1,1,1,1,2,2,1,1,1,1,4,1),
- (2,2,2,6,2,2,2,1,2,2,2,2,2,2, (* 9 *)
- 4,0,0,0,0,0,0,2,2,0,0,0,1,2,
- 2,2,0,2,2,0,0,2,0,0,2,2,2,2,
- 2,1,1,1,2,1,5,2,0,0,0,0,2,1,
- 2,2,2,2,2,1,0,2,2,0,2,0,2,1,
- 1,8,2,0,0,0,0,8,0,0,2,0,2,0,
- 1,1,2,2,1,2,2,2,2,2,2,0,0,0));
-
- VAR
- Pic1,Pic2,Pic3,Pic4,Pic5,Pic6,Pic7,
- Pic8,Pic9,Pic10,TextBack,BackPic2,BackPic3:Image;
- ATTHelp:Image;
- ATTHelpShow:BOOLEAN;
- BackPic1:ARRAY[1..MaxBall] OF Image;
- Feld:ARRAY[0..13,0..6] OF INTEGER;
- Blocs:INTEGER;
- Lev:Spiel;
- FMiX,FMaX,FMiY:INTEGER;
- BlockX,BlockY:INTEGER;
- MX,MY:INTEGER;
- ch:CHAR;
- Mono,ATT:BOOLEAN;
- Life:INTEGER;
- Level:INTEGER;
- Vel,g:INTEGER;
- ColNorm,ColBlock:INTEGER;
-
- PROCEDURE Init;
- VAR
- dr,mo,x,y,Err:INTEGER;
- p:PaletteType;
- BEGIN
- Err:=RegisterBGIDriver(@EGAVGADriverProc);
- Err:=RegisterBGIDriver(@HercDriverProc);
- Err:=RegisterBGIDriver(@ATTDriverProc);
- Err:=RegisterBGIDriver(@PC3270DriverProc);
- Err:=RegisterBGIFont(@GothicFontProc);
- Err:=RegisterBGIFont(@SansSerifFontProc);
- Err:=RegisterBGIFont(@TriplexFontProc);
- DetectGraph(dr,mo);
- IF dr<EGA THEN
- BEGIN
- dr:=ATT400;
- mo:=ATT400Hi;
- InitGraph(dr,mo,'');
- IF GraphResult<>0 THEN dr:=CGA;
- END;
- IF dr<EGA THEN
- BEGIN
- CloseGraph;
- Write('Sorry, aber mit dieser Grafikkarte ');
- WriteLn('klappts nicht!');
- WriteLn('Mindestens Hercules oder EGA sollte es sein.');
- WriteLn('Tut mir leid...');
- Halt;
- END
- ELSE
- IF (dr=HercMono) OR (dr=ATT400) THEN
- BEGIN
- Mono:=TRUE;
- IF dr=HercMono THEN
- BEGIN
- mo:=HercMonoHi;
- ATT:=FALSE;
- END
- ELSE
- BEGIN
- mo:=ATT400Hi;
- ATT:=TRUE;
- ATTHelpShow:=FALSE;
- END;
- END
- ELSE
- BEGIN
- Mono:=FALSE;
- ATT:=FALSE;
- mo:=EGAHi;
- END;
- InitGraph(dr,mo,'');
- FOR x:=0 TO 13 DO
- FOR y:=0 TO 6 DO
- Feld[x,y]:=0;
- ClearDevice;
- SetVisualPage(0);
- SetActivePage(0);
- IF NOT(Mono) THEN
- BEGIN
- GetPalette(p);
- FOR x:=0 TO 15 DO
- p.Colors[x]:=EGAColors[x];
- SetAllPalette(p);
- ColNorm:=EGAColors[2];
- ColBlock:=BlockColor;
- END;
- MX:=GetMaxX;
- MY:=GetMaxY;
- FMiX:=(MX-448-32-8) SHR 1;
- FMaX:=FMiX+448+32+8;
- FMiY:=50;
- BlockX:=FMiX+xKorr; (* x-Beginn des Block-Feldes *)
- BlockY:=FMiY+yKorr; (* y- " " " " *)
- END;
-
-
- PROCEDURE DelaySec(y:INTEGER);
- VAR
- x:WORD;
- ca:CHAR;
- BEGIN
- x:=y*100;
- REPEAT
- Delay(10);
- Dec(x);
- UNTIL (KeyPressed) OR (x<0);
- IF KeyPressed THEN ca:=ReadKey;
- END;
-
- PROCEDURE CatchImage(x1,y1,x2,y2:INTEGER;VAR Ima:Image);
- BEGIN
- Ima.Size:=ImageSize(x1,y1,x2,y2);
- GetMem(Ima.Ima,Ima.Size);
- GetImage(x1,y1,x2,y2,Ima.Ima^);
- END;
-
- PROCEDURE DelSound(Frq,Del:INTEGER);
- BEGIN
- IF SoundOn THEN
- BEGIN
- Sound(Frq);
- Delay(Del);
- END;
- END;
-
- PROCEDURE Color(c:INTEGER);
- BEGIN
- IF Mono THEN
- SetColor(1)
- ELSE
- SetColor(c);
- END;
-
- PROCEDURE FillStyle(f,c:INTEGER);
- BEGIN
- IF Mono THEN
- SetFillStyle(f,1)
- ELSE
- SetFillStyle(f,c);
- END;
-
- PROCEDURE Fill(x,y,c:INTEGER);
- BEGIN
- IF Mono THEN
- FloodFill(x,y,1)
- ELSE
- FloodFill(x,y,c);
- END;
-
- PROCEDURE SetImage(x,y:INTEGER;Ima:Image;Akt:WORD);
- BEGIN
- PutImage(x,y,Ima.Ima^,Akt);
- END;
-
- PROCEDURE SetBack(x,y:INTEGER;Ima:Image;Akt:WORD);
- BEGIN
- SetImage(x,y,Ima,Akt);
- FreeMem(Ima.Ima,Ima.Size);
- END;
-
- PROCEDURE Picture1; (* Ball *)
- BEGIN
- Color(2);
- Circle(4,4,4);
- Circle(3,3,3);
- FillStyle(1,2);
- Fill(3,3,2);
- CatchImage(0,1,bx,7,Pic1);
- ClearViewPort;
- END;
-
- PROCEDURE Picture2; (* Schläger *)
- BEGIN
- Color(6);
- Rectangle(1,1,64,8);
- SetFillStyle(1,0);
- Fill(5,5,6);
- Color(4);
- Rectangle(2,4,61,6);
- FillStyle(1,4);
- Fill(5,5,4);
- Color(6);
- CatchImage(1,1,64,8,Pic2);
- ClearViewPort;
- END;
-
- PROCEDURE Picture3; (* Block *)
- BEGIN
- Color(15);
- Rectangle(1,1,32,16);
- Rectangle(3,3,28,12);
- FillStyle(1,15);
- Fill(4,4,15);
- CatchImage(1,1,32,16,Pic3);
- ClearViewPort;
- END;
-
- PROCEDURE Picture4; (* Stein *)
- BEGIN
- Color(14);
- Rectangle(1,1,32,16);
- Rectangle(3,3,28,12);
- IF Mono THEN
- SetFillPattern(Dicht,1)
- ELSE
- SetFillPattern(Dicht,14);
- Fill(4,4,14);
- CatchImage(1,1,32,16,Pic4);
- ClearViewPort;
- END;
-
- PROCEDURE Picture5; (* ExtraBall *)
- BEGIN
- Color(13);
- Rectangle(1,1,32,16);
- Rectangle(3,3,28,12);
- CatchImage(1,1,32,16,Pic5);
- ClearViewPort;
- END;
-
- PROCEDURE Picture6; (* MultiBall *)
- BEGIN
- Color(15);
- Rectangle(1,1,32,16);
- Rectangle(3,3,28,13);
- Color(12);
- Circle(16,8,4);
- Circle(15,7,3);
- FillStyle(1,12);
- Fill(14,7,12);
- CatchImage(1,1,32,16,Pic6);
- ClearViewPort;
- END;
-
- PROCEDURE Picture7; (* Gravitation *)
- BEGIN
- Color(15);
- Rectangle(1,1,32,16);
- Rectangle(3,3,28,13);
- Color(11);
- SetLineStyle(0,0,1);
- Line(5,7,5,9);
- Line(5,7,15,7);
- Line(5,9,15,9);
- Line(15,7,15,5);
- Line(15,9,15,11);
- Line(15,11,26,8);
- Line(15,5,26,8);
- SetLineStyle(0,0,1);
- FillStyle(1,11);
- Fill(6,8,11);
- CatchImage(1,1,32,16,Pic7);
- ClearViewPort;
- END;
-
- PROCEDURE Picture8; (* Ende aller Gemeinheiten *)
- BEGIN
- Color(15);
- Rectangle(1,1,32,16);
- Rectangle(3,3,28,13);
- Color(10);
- SetLineStyle(0,0,3);
- Line(3,4,28,12);
- Line(3,12,28,4);
- SetLineStyle(0,0,1);
- CatchImage(1,1,32,16,Pic8);
- ClearViewPort;
- END;
-
- PROCEDURE Picture9; (* Magnet *)
- BEGIN
- Color(9);
- Arc(9,8,90,270,6);
- Arc(9,8,90,270,3);
- Line(9,3,18,3);
- Line(9,6,18,6);
- Line(18,3,18,6);
- Line(9,13,18,13);
- Line(9,10,18,10);
- Line(18,13,18,10);
- FillStyle(1,9);
- Fill(9,5,9);
- CatchImage(1,1,32,16,Pic9);
- ClearViewPort;
- END;
-
- PROCEDURE Picture10; (* Austausch *)
- BEGIN
- Color(15);
- Rectangle(1,1,32,16);
- Color(8);
- Rectangle(3,3,28,13);
- IF NOT(Mono) THEN
- BEGIN
- SetFillStyle(1,8);
- FloodFill(9,4,8);
- END;
- CatchImage(1,1,32,16,Pic10);
- ClearViewPort;
- END;
-
-
- PROCEDURE WriteCenter(St:Stri;x,y:INTEGER);
- BEGIN
- OutTextXY((MX-TextWidth(St)) SHR 1+x,y,St);
- END;
-
- PROCEDURE Pictures;
- CONST
- St:STRING[30]='Ich initialisiere MEGA-BOLO... ';
- BEGIN
- SetTextStyle(1,0,3);
- WriteCenter(St,0,(MY-TextHeight(St)) SHR 1);
- SetActivePage(1);
- SetViewPort(0,0,80,60,TRUE);
- Picture1;
- Picture2;
- Picture3;
- Picture4;
- Picture5;
- Picture6;
- Picture7;
- Picture8;
- Picture9;
- Picture10;
- END;
-
- PROCEDURE PlayMusic(SoundNr:INTEGER); (* Titelmelodie *)
- VAR
- x:INTEGER;
- ch:CHAR;
- BEGIN
- x:=1;
- REPEAT
- DelSound(Music[SoundNr,x],108);
- NoSound;
- Delay(10);
- Inc(x);
- IF x>SoundLen[SoundNr] THEN x:=1;
- UNTIL KeyPressed;
- ch:=ReadKey;
- END;
-
- PROCEDURE Logo; (* Logo ausgeben *)
- CONST
- Titel1='toolbox';
- Titel2='MEGA-BOLO';
- Titel3='(C) Copyright 1991 Peter Messmer & toolbox';
- VAR
- x:INTEGER;
- ca:CHAR;
-
- PROCEDURE Bas;
- BEGIN
- DelSound(70,80);
- NoSound;
- END;
-
- PROCEDURE BreakSound;
- BEGIN
- IF KeyPressed THEN
- BEGIN
- NoSound;
- SoundOn:=FALSE;
- ca:=ReadKey;
- END;
- END;
-
- BEGIN
- FOR x:=0 TO 25 DO (* Rahmen aufbauen *)
- BEGIN
- BreakSound;
- IF Mono THEN
- SetColor(1)
- ELSE
- IF x MOD 2=1 THEN SetColor(4) ELSE SetColor(8);
- Rectangle(x*2+1,x*2+1,MX-x*2,MY-x*2);
- DelSound((x+10)*20,0);
- END;
- SetColor(0);
- FOR x:=25 DOWNTO 4 DO
- BEGIN
- BreakSound;
- Rectangle(x*2+1,x*2+1,MX-x*2,MY-x*2);
- DelSound((x+10)*20,0);
- END;
- NoSound;
- Color(6);
- SetTextStyle(1,0,5);
- WriteCenter(Titel1,-1,29);
- Color(4);
- WriteCenter(Titel1,0,30);
- Bas;
- Color(4);
- SetTextStyle(3,0,3);
- WriteCenter('praesentiert',0,80);
- Bas;
- SetTextStyle(4,0,8);
- Color(6);
- WriteCenter(Titel2,3,112);
- Bas;
- WriteCenter(Titel2,2,111);
- Bas;
- Color(4);
- WriteCenter(Titel2,1,110);
- Bas;
- Color(6);
- SetTextStyle(1,0,3);
- WriteCenter(Titel3,1,251);
- Color(4);
- IF NOT(Mono) THEN
- WriteCenter(Titel3,0,250);
- Bas;
- Delay(700);
- REPEAT
- IF KeyPressed THEN ca:=ReadKey;
- UNTIL NOT(KeyPressed);
- PlayMusic(2);
- IF NOT(SoundOn) THEN
- BEGIN
- IF NOT(Mono) THEN
- BEGIN
- ColNorm:=BlockColor;
- ColBlock:=EGAColors[2];
- SetPalette(2,ColNorm);
- END;
- END;
- END;
-
- PROCEDURE Help;
- CONST
- HT:ARRAY[1..13] OF STRING[80]=(
- 'Halten Sie den Ball mit Hilfe des Schlaegers im Spielfeld',
- 'und raeumen Sie die Steine ab, um in das naechste Bild zu',
- 'gelangen. Neun verschiedene Level warten auf Sie.',
- 'Vorsicht: Der Ball darf nicht unter den Schlaeger geraten!',
- '',
- 'Der Schlaeger wird mit den beiden <Shift>-Tasten gesteuert',
- 'und mit der <Space>-Taste angehalten. <M> schaltet den',
- 'Sound an oder aus. Sollte der Ball in einer Schleife',
- 'haengenbleiben, hilft ein kurzer Gravitationsschub mit <G>.',
- '','',
- 'Viel Spass!','');
-
- VAR
- x,y,y4:INTEGER;
- BEGIN
- Color(4);
- SetViewPort(0,0,MX,MY,TRUE);
- FOR x:=0 TO 2 DO
- Rectangle(x*2+1,x*2+1,MX-x*2,MY-x*2);
- SetTextStyle(3,0,1);
- y:=70;
- FOR x:=1 TO 13 DO
- BEGIN
- IF NOT(x=4) THEN WriteCenter(HT[x],10,y) ELSE y4:=y;
- y:=y+TextHeight(HT[x]);
- END;
- Color(6);
- WriteCenter(HT[4],10,y4);
- SetTextStyle(1,0,4);
- WriteCenter('MEGA-BOLO',0,20);
- SetTextStyle(1,0,2);
- OutTextXY(MX-20-TextWidth('P.M.'),
- MY-6-TextHeight('P.M.'),'P.M.');
- Color(1);
- END;
-
- PROCEDURE GlobHelp;
- BEGIN
- IF NOT(ATT) THEN Help;
- SetActivePage(0);
- SetViewPort(0,0,MX,MY,FALSE);
- ClearViewPort;
- END;
-
- PROCEDURE SetBlocs;
- VAR
- x,y:INTEGER;
- u,v:INTEGER;
- BEGIN
- CatchImage(BlockX,BlockY,
- BlockX+31,BlockY+15,BackPic3);
- FOR y:=0 TO 6 DO
- FOR x:=0 TO 13 DO
- BEGIN
- u:=(x SHL 5)+BlockX;
- v:=(y SHL 4)+BlockY;
- CASE Feld[x,y] OF
- 1: SetImage(u,v,Pic3,0);
- 2: SetImage(u,v,Pic4,0);
- 3: SetImage(u,v,Pic5,0);
- 4: SetImage(u,v,Pic6,0);
- 5: SetImage(u,v,Pic7,0);
- 6: SetImage(u,v,Pic8,0);
- 7: SetImage(u,v,Pic9,2);
- 8: SetImage(u,v,Pic10,0);
- END;
- END;
- END;
-
- PROCEDURE WriteLife;
- VAR
- St:STRING[2];
- BEGIN
- Color(1);
- SetTextStyle(1,0,3);
- Str(Life,St);
- OutTextXY((MX-FMaX-TextWidth('Baelle')) SHR 1+FMaX,
- 100,'Baelle');
- SetTextStyle(1,0,4);
- OutTextXY((MX-FMaX-TextWidth(St)) SHR 1+FMaX,
- 140,St);
- END;
-
- PROCEDURE WriteLevel;
- VAR
- St:STRING[5];
- w:WORD;
- BEGIN
- Color(1);
- SetTextStyle(1,0,3);
- OutTextXY(((FMiX-8-TextWidth('Level')) SHR 1)+8,
- 100,'Level');
- IF Level=MaxLevel THEN
- BEGIN
- SetTextStyle(1,0,3);
- St:='ENDE';
- END
- ELSE
- BEGIN
- SetTextStyle(1,0,4);
- Str(Level,St);
- END;
- OutTextXY(((FMiX-8-TextWidth(St)) SHR 1)+8,140,St);
- END;
-
- PROCEDURE PaintFeld;
- VAR
- x:INTEGER;
- BEGIN
- SetViewPort(10,FMiY,MX-10,330,TRUE);
- ClearViewPort;
- SetViewPort(0,0,MX,MY,TRUE);
- Color(4);
- Rectangle(FMiX,FMiY,FMaX,330);
- Rectangle(FMiX-5,FMiY,FMaX+5,330);
- Color(6);
- Rectangle(FMiX-3,49,FMaX+3,331);
- Color(7);
- FillStyle(11,7);
- Fill(FMiX+1,51,4);
- SetBlocs;
- WriteLife;
- WriteLevel;
- END;
-
- PROCEDURE Title;
- CONST Titel1='MEGA-BOLO';
- VAR
- x:INTEGER;
- BEGIN
- Color(4);
- FOR x:=0 TO 2 DO
- Rectangle(x*2+1,x*2+1,MX-x*2,MY-x*2);
- SetTextStyle(4,0,5);
- Color(6);
- WriteCenter(Titel1,1,1);
- Color(4);
- WriteCenter(Titel1,0,1);
- END;
-
- PROCEDURE CenterText(t:Stri;VAR x,y:INTEGER);
- BEGIN
- x:=(MX-TextWidth(t)) SHR 1;
- y:=((MY-TextHeight(t)) SHR 1)+FMiY;
- CatchImage(x,y,x+TextWidth(t),
- y+TextHeight(t)+30,TextBack);
- OutTextXY(x,y,t);
- END;
-
- PROCEDURE ZoomText(t:Stri;s,c,Font,cl:INTEGER;VAR ca:CHAR);
- VAR
- x,y,Count,Col:INTEGER;
- BEGIN
- IF KeyPressed THEN ca:=ReadKey;
- REPEAT
- Col:=GetColor;
- FOR Count:=s TO c DO
- BEGIN
- SetTextStyle(Font,0,Count);
- Color(cl);
- CenterText(t,x,y);
- Delay(200);
- IF Count=c THEN Delay(400);
- IF s=c THEN REPEAT UNTIL KeyPressed;
- SetBack(x,y,TextBack,0);
- END;
- SetColor(Col);
- UNTIL KeyPressed;
- ca:=ReadKey;
- END;
-
- PROCEDURE Ausstieg;
- VAR
- x,y:INTEGER;
- ca:CHAR;
- St:STRING[3];
- BEGIN
- SetTextStyle(1,0,5);
- CenterText('Abbruch ? (J/N): ',x,y);
- ca:=UpCase(ReadKey);
- IF (ca='Y') OR (ca='J') THEN
- St:='Ja'
- ELSE
- St:='Nein';
- OutTextXY(x+TextWidth('Abbruch ? (J/N):'),y,St);
- Delay(500);
- IF (ca='Y') OR (ca='J') THEN
- BEGIN
- CloseGraph;
- RestoreCrtMode;
- Halt;
- END;
- SetBack(x,y,TextBack,0);
- END;
-
- FUNCTION Restart:BOOLEAN;
- VAR
- St:STRING;
- x,y:INTEGER;
- BEGIN
- SetTextStyle(1,0,5);
- CenterText('Nochmal ? (J/N): ',x,y);
- ch:=UpCase(ReadKey);
- IF ch='N' THEN
- BEGIN
- Restart:=FALSE;
- St:='Nein';
- END
- ELSE
- BEGIN
- Restart:=TRUE;
- St:='Ja';
- END;
- OutTextXY(x+TextWidth('Restart ? (Y/N):'),y,St);
- Delay(500);
- SetBack(x,y,TextBack,0);
- END;
-
- PROCEDURE AllLevels;
- VAR
- x,y:INTEGER;
- BEGIN
- Delay(200);
- Color(6);
- SetTextStyle(1,0,5);
- CenterText('Glueckwunsch !',x,y);
- PlayMusic(1);
- SetBack(x,y,TextBack,0);
- END;
-
- PROCEDURE Go;
- CONST
- vi:INTEGER=4;
- VAR
- xb,yb,yMax,Count,bc,BallCatch:INTEGER;
- x,y:ARRAY[1..MaxBall] OF INTEGER;
- vv,vh:ARRAY[1..MaxBall] OF REAL;
- t,vb:REAL;
- ca:CHAR;
- St:STRING[3];
- Multi:BOOLEAN;
- BallAnz:INTEGER;
-
- PROCEDURE GetKey;
- VAR
- Count:INTEGER;
- BEGIN
- ca:=UpCase(ReadKey);
- IF ca=#0 THEN ca:=UpCase(ReadKey);
- CASE ca OF
- ' ': vb:=0;
- 'G': BEGIN
- IF BallAnz>1 THEN
- FOR Count:=1 TO BallAnz DO
- vv[Count]:=vv[Count]+(-6)*t
- ELSE
- vv[1]:=vv[1]+(-6)*t;
- END;
- 'M',
- 'S',
- 'Q': IF SoundOn THEN
- BEGIN
- SoundOn:=FALSE;
- IF NOT(Mono) THEN
- BEGIN
- ColNorm:=BlockColor;
- ColBlock:=EGAColors[2];
- SetPalette(2,ColNorm);
- END;
- END
- ELSE
- BEGIN
- SoundOn:=TRUE;
- IF NOT(Mono) THEN
- BEGIN
- ColBlock:=BlockColor;
- ColNorm:=EGAColors[2];
- SetPalette(2,ColNorm);
- END;
- END;
- #27: Ausstieg;
- ELSE
- BEGIN
- IF NOT(ATT) THEN (* nicht ATT, andere Seite *)
- BEGIN
- SetVisualPage(1);
- DelaySec(60);
- SetVisualPage(0);
- END
- ELSE
- BEGIN
- CatchImage(0,0,MX,MY,TextBack);
- IF NOT(ATTHelpShow) THEN
- BEGIN (* Help aufbauen *)
- ClearDevice;
- Help;
- DelaySec(60);
- CatchImage(0,0,MX,MY,ATTHelp);
- SetBack(0,0,TextBack,0);
- ATTHelpShow:=TRUE;
- END
- ELSE
- BEGIN (* Help anzeigen *)
- SetImage(0,0,ATTHelp,0);
- DelaySec(60);
- END;
- SetBack(0,0,TextBack,0);
- END;
- END;
- END;
- END;
-
- PROCEDURE GetShiftKey;
- VAR
- Status:BYTE;
- BEGIN
- Status:=Mem[$040:$017] AND 3; (* Tastatur-Status *)
- IF Status<>0 THEN
- CASE Status OF
- 1 : IF vb > 0 THEN
- vb:=vb+vi (* Shift rechts ? *)
- ELSE
- vb:=vi;
- 2 : IF vb < 0 THEN
- vb:=vb-vi (* Shift links ? *)
- ELSE
- vb:=-vi;
- ELSE
- vb:=0; (* beide ? *)
- END;
- END;
-
- PROCEDURE PlopOnBar(VAR yNew:INTEGER);
- BEGIN
- vv[bc]:=(-1)*vv[bc]-0.1*vv[bc];
- vh[bc]:=vh[bc]+vb;
- yNew:=yb-8;
- DelSound(1200,1);
- END;
-
- PROCEDURE AskPlopOnBloc(VAR xNew,yNew:INTEGER);
- VAR
- xp,yp:INTEGER;
-
- PROCEDURE Bloc;
- BEGIN
- SetImage((xp SHL 5)+BlockX,(yp SHL 4)+BlockY,
- BackPic3,0);
- Feld[xp,yp]:=0;
- Dec(Blocs);
- DelSound(1000,10);
- NoSound;
- END;
-
- PROCEDURE Hard;
- BEGIN
- DelSound(1300,10);
- NoSound;
- END;
-
- PROCEDURE Extraball;
- VAR
- Count:INTEGER;
- BEGIN
- SetImage((xp SHL 5)+BlockX,(yp SHL 4)+BlockY,
- BackPic3,0);
- SetColor(0);
- Str(Life,St);
- SetTextStyle(1,0,4);
- OutTextXY(((MX-FMaX-TextWidth(St)) SHR 1)+FMaX,
- 140,St);
- Inc(Life);
- Color(1);
- WriteLife;
- Feld[xp,yp]:=0;
- FOR Count:=1 TO 30 DO
- DelSound(Count*100,10);
- END;
-
- PROCEDURE MultiBall;
- VAR
- Count,Count2:INTEGER;
- nb:INTEGER;
- BEGIN
- SetImage((xp SHL 5)+BlockX,(yp SHL 4)+BlockY,
- BackPic3,0);
- Feld[xp,yp]:=0;
- SetColor(0);
- Str(Life,St);
- SetTextStyle(1,0,4);
- OutTextXY(((MX-FMaX-TextWidth(St)) SHR 1)+FMaX,
- 140,St);
- Inc(Life);
- Color(1);
- WriteLife;
- nb:=BallAnz+1;
- x[nb]:=(xp SHL 5)+BlockX+xKorr;
- y[nb]:=(yp SHL 4)+BlockY+8;
- vv[nb]:=Round((-1)*(vv[bc]/2))+1;
- vh[nb]:=Round((-1)*(vh[bc]/2))+1;
- CatchImage(x[nb],y[nb],
- x[nb]+bx,y[nb]+by,
- BackPic1[nb]);
- SetImage(x[nb],y[nb],Pic1,0);
- FOR Count:=60 TO 62 DO
- BEGIN
- Delay(10);
- FOR Count2:=500 TO Count*10 DO
- DelSound(Count2,1);
- NoSound;
- END;
- Multi:=TRUE;
- END;
-
- PROCEDURE Gravitation;
- VAR
- Count:INTEGER;
- BEGIN
- SetImage((xp SHL 5)+BlockX,(yp SHL 4)+BlockY,
- BackPic3,0);
- Feld[xp,yp]:=0;
- g:=-3;
- FOR Count:=100 DOWNTO 50 DO
- BEGIN
- DelSound(Count*10,5);
- NoSound;
- END;
- FOR Count:=50 TO 100 DO
- BEGIN
- DelSound(Count*10,5);
- NoSound;
- END;
- END;
-
- PROCEDURE EndeGravit;
- VAR
- Count:INTEGER;
- BEGIN
- SetImage((xp SHL 5)+BlockX,(yp SHL 4)+BlockY,
- BackPic3,0);
- Feld[xp,yp]:=0;
- g:=0;
- vi:=4;
- FOR Count:=50 TO 100 DO
- BEGIN
- DelSound(Count*10,5);
- NoSound;
- END;
- FOR Count:=100 DOWNTO 50 DO
- BEGIN
- DelSound(Count*10,5);
- NoSound;
- END;
- END;
-
- PROCEDURE Magnet;
- VAR
- Count:INTEGER;
- BEGIN
- xNew:=(xp SHL 5)+BlockX+20;
- yNew:=(yp SHL 4)+BlockY+4;
- SetImage(xNew,yNew,Pic1,0);
- FOR Count:=100 DOWNTO 50 DO
- BEGIN
- DelSound(Count*10,50);
- NoSound;
- END;
- Inc(BallCatch);
- IF BallAnz-BallCatch=0 THEN
- BEGIN
- Life:=0;
- yMax:=400;
- END
- ELSE
- BEGIN
- vv[bc]:=0;
- vh[bc]:=0;
- ZoomText('Ball futsch!',5,5,1,GetColor,ch);
- END;
- END;
-
- PROCEDURE Umtasten;
- VAR
- Count:INTEGER;
- BEGIN
- SetImage((xp SHL 5)+BlockX,(yp SHL 4)+BlockY,
- BackPic3,0);
- Feld[xp,yp]:=0;
- vi:=-4;
- FOR Count:=1 TO 10 DO
- BEGIN
- DelSound(Count*100,10);
- NoSound;
- Delay(5);
- END;
- END;
-
- PROCEDURE PlopBlocAway;
- VAR
- yz,xz:INTEGER;
- m:REAL;
- BEGIN
- IF xNew=x[bc] THEN (* keine Vertikalbewegung *)
- vv[bc]:=-vv[bc]
- ELSE
- IF yNew=y[bc] THEN (* keine Horizontalbewegung *)
- vh[bc]:=-vh[bc]
- ELSE
- IF Abs(vh[bc])=Abs(vv[bc]) THEN
- (* Diagonalbewegung *)
- BEGIN
- vh[bc]:=-vh[bc];
- vv[bc]:=-vv[bc];
- END
- ELSE
- BEGIN (* Ein bisschen Vektorgeometrie *)
- m:=(yNew-y[bc])/(xNew-x[bc]);
- IF vh[bc]<0 THEN
- (* Horizontal nach links *)
- BEGIN
- yz:=Round(m*(((xp+1) SHL 5)+
- BlockX-xNew)+yNew);
- IF vv[bc]<0 THEN (* nach Unten ? *)
- BEGIN (* Decke oder rechte Seite *)
- IF yz-((yp SHL 4)+BlockY+4)<0 THEN
- BEGIN
- xz:=Round((1/m)*((yp SHL 4)+
- BlockY-by-yNew)+xNew);
- xNew:=xz;
- yNew:=(yp SHL 4)+BlockY-by;
- vv[bc]:=-vv[bc]; (* Decken-Aufprall *)
- END
- ELSE
- BEGIN
- vh[bc]:=-vh[bc]; (* Seiten-Aufprall *)
- xNew:=((xp+1) SHL 5)+BlockX;
- yNew:=yz;
- END;
- END
- ELSE
- BEGIN (* Boden oder rechte Seite *)
- IF yz-(((yp+1) SHL 4)+BlockY)>0 THEN
- BEGIN
- vv[bc]:=-vv[bc]; (* Boden-Aufprall *)
- xz:=Round((1/m)*(((yp+1) SHL 4)
- +BlockY-yNew)+xNew);
- xNew:=xz;
- yNew:=((yp+1) SHL 4)+BlockY;
- END
- ELSE
- BEGIN
- vh[bc]:=-vh[bc]; (* Seiten-Aufprall *)
- xNew:=((xp+1) SHL 5)+BlockX;
- yNew:=yz;
- END;
- END;
- END
- ELSE (* Horizontal nach rechts *)
- BEGIN
- yz:=Round(m*((xp SHL 5)
- +BlockX-by-xNew)+yNew);
- IF vv[bc]<0 THEN
- BEGIN (* Decke oder linke Seite *)
- IF yz-((yp SHL 4)+4+BlockY)<0 THEN
- BEGIN
- vv[bc]:=-vv[bc]; (* Decken-Aufprall *)
- xz:=Round((1/m)*((yp SHL 4)
- +BlockY-by-yNew)+xNew);
- xNew:=xz;
- yNew:=(yp SHL 4)+BlockY-by;
- END
- ELSE
- BEGIN
- vh[bc]:=-vh[bc]; (* Seiten-Aufprall *)
- xNew:=(xp SHL 5)+BlockX-bx;
- yNew:=yz;
- END;
- END
- ELSE
- BEGIN (* Boden oder linke Seite *)
- IF yz-(((yp+1) SHL 4)+BlockY)>0 THEN
- BEGIN
- vv[bc]:=-vv[bc]; (* Boden-Aufprall *)
- xz:=Round((1/m)*(((yp+1) SHL 4)
- +BlockY-yNew)+xNew);
- xNew:=xz;
- yNew:=((yp+1) SHL 4)+BlockY;
- END
- ELSE
- BEGIN
- vh[bc]:=-vh[bc]; (* Seiten-Aufprall *)
- xNew:=(xp SHL 5)+BlockX-bx;
- yNew:=yz;
- END;
- END;
- END;
- END;
- CASE Feld[xp,yp] OF
- 1: Bloc;
- 2: Hard;
- 3: Extraball;
- 4: MultiBall;
- 5: Gravitation;
- 6: EndeGravit;
- 7: Magnet;
- 8: Umtasten;
- END;
- END;
-
- BEGIN (* AskPlopOnBloc-Rumpf *)
- yp:=(yNew-BlockY) DIV 16;
- xp:=(xNew-BlockX) DIV 32;
- IF Feld[xp,yp]<>0 THEN
- PlopBlocAway
- ELSE
- BEGIN
- IF ((yNew+by-BlockY) DIV 16 > yp) AND
- ((yNew+by-BlockY) DIV 16<7) THEN
- BEGIN
- yp:=(yNew+bx-BlockY) DIV 16;
- IF Feld[xp,yp]<>0 THEN
- PlopBlocAway;
- END
- ELSE
- BEGIN
- IF ((xNew+bx-BlockX) DIV 32>xp) AND
- ((xNew+bx-BlockX) DIV 32<14) THEN
- BEGIN
- xp:=(xNew+bx-BlockX) DIV 32;
- IF Feld[xp,yp]<>0 THEN
- PlopBlocAway;
- END;
- END;
- END;
- END;
-
- PROCEDURE RandSound;
- BEGIN
- DelSound(500,10);
- NoSound;
- END;
-
- PROCEDURE SetBar;
- BEGIN
- PutImage(xb,yb,BackPic2.Ima^,0);
- FreeMem(BackPic2.Ima,BackPic2.Size);
- xb:=xb+Round(vb*t);
- IF xb<FMiX THEN
- BEGIN
- vb:=(-1)*vb;
- xb:=FMiX;
- END;
- IF xb+64>FMaX THEN
- BEGIN
- vb:=(-1)*vb;
- xb:=FMaX-64;
- END;
- CatchImage(xb,yb,xb+63,yb+7,BackPic2);
- PutImage(xb,yb,Pic2.Ima^,0);
- END;
-
- PROCEDURE MoveBall(z:INTEGER);
- VAR
- xNew,yNew:INTEGER;
- BEGIN
- PutImage(x[z],y[z],BackPic1[z].Ima^,0);
- FreeMem(BackPic1[z].Ima,BackPic1[z].Size);
- IF z>1 THEN MoveBall(z-1)
- ELSE
- IF vb<>0 THEN
- SetBar;
- bc:=z; (* globale Variable für Ballnummer *)
- (* ist schneller als Parameter !*)
- IF NOT((vv[z]=0) AND (vh[z]=0)) THEN
- BEGIN
- vv[z]:=vv[z]+g*t;
- yNew:=y[z]+Round(((g/2)*t*t)-(vv[z]*t));
- xNew:=x[z]+Round(vh[bc]*t);
- IF xNew+bx>FMaX THEN
- BEGIN
- vh[z]:=(-1)*vh[z];
- RandSound;
- xNew:=FMaX-bx;
- END;
- IF xNew<FMiX THEN
- BEGIN
- vh[z]:=(-1)*vh[z];
- RandSound;
- xNew:=FMiX;
- END;
- IF yNew<FMiY THEN
- BEGIN
- vv[z]:=(-1)*vv[z];
- RandSound;
- yNew:=FMiY;
- END;
- IF (yNew+bx>yb) AND (yNew<yb) AND
- (xNew+bx>xb) AND (xNew<xb+64) THEN
- PlopOnBar(yNew);
- IF (yNew<192) AND (yNew>72) AND
- (xNew>FMiX+bx) AND (xNew<FMiX+448+xKorr) THEN
- AskPlopOnBloc(xNew,yNew);
- IF yNew>yMax THEN yMax:=yNew;
- END;
- CatchImage(xNew,yNew,xNew+bx,yNew+by,BackPic1[z]);
- PutImage(xNew,yNew,Pic1.Ima^,0);
- x[z]:=xNew;
- y[z]:=yNew;
- END;
-
- PROCEDURE InitKonst;
- BEGIN
- Multi:=FALSE;
- BallCatch:=0;
- BallAnz:=1;
- x[1]:=BlockX+by*32+13;
- y[1]:=200;
- vv[1]:=-15;
- vh[1]:=0;
- xb:=BlockX+by*32-16;
- yb:=300;
- vb:=0;
- t:=0.1;
- END;
-
- PROCEDURE LifeLost;
- VAR
- Count:INTEGER;
- BEGIN
- Dec(Life);
- FOR Count:=10 DOWNTO 1 DO
- BEGIN
- DelSound(Count*100,50);
- NoSound;
- END;
- IF Life>=0 THEN
- ZoomText('Ball futsch!',5,5,1,GetColor,ch);
- FOR Count:=1 TO BallAnz DO
- SetBack(x[Count],y[Count],BackPic1[Count],0);
- END;
-
- PROCEDURE AllBlocs;
- VAR
- Count:INTEGER;
- BEGIN
- FOR Count:=1 TO 10 DO
- DelSound(Count*100,50);
- NoSound;
- IF Level=MaxLevel THEN
- AllLevels
- ELSE
- ZoomText('You did it...',1,6,1,GetColor,ch);
- END;
-
- PROCEDURE GetFirstPictures;
- BEGIN
- CatchImage(x[1],y[1],x[1]+bx,y[1]+by,BackPic1[1]);
- SetImage(x[1],y[1],Pic1,0);
- CatchImage(xb,yb,xb+63,yb+7,BackPic2);
- SetImage(xb,yb,Pic2,0);
- END;
-
- BEGIN (* Go-Rumpf *)
- REPEAT
- InitKonst;
- IF KeyPressed THEN ca:=ReadKey;
- PaintFeld;
- GetFirstPictures;
- REPEAT
- Delay(Vel);
- NoSound;
- IF KeyPressed THEN GetKey;
- GetShiftKey;
- yMax:=0;
- MoveBall(BallAnz);
- IF Multi THEN
- BEGIN
- Multi:=FALSE;
- Inc(BallAnz);
- END;
- UNTIL (yMax>320) OR (Blocs=0);
- IF yMax>320 THEN LifeLost;
- UNTIL (Blocs=0) OR (Life<0);
- IF Blocs=0 THEN
- AllBlocs
- ELSE
- BEGIN
- NoSound;
- ZoomText('Game Over',1,6,1,GetColor,ch);
- END;
- NoSound;
- END;
-
- PROCEDURE InitFeld;
- VAR
- x,y:INTEGER;
- BEGIN
- Blocs:=0;
- FOR y:=0 TO 6 DO
- FOR x:=0 TO 13 DO
- BEGIN
- Feld[x,y]:=Lev[y*14+x];
- IF Feld[x,y]=1 THEN Inc(Blocs);
- END;
- END;
-
-
- PROCEDURE Start;
- BEGIN
- SetViewPort(0,0,MX,MY,TRUE);
- ClearViewPort;
- Title;
- REPEAT
- Life:=3;
- Level:=1;
- Vel:=12;
- g:=0;
- REPEAT
- Lev:=LevelNr[Level];
- InitFeld;
- Go;
- Inc(Level);
- UNTIL (Life<0) OR (Level>MaxLevel);
- UNTIL Restart=FALSE;
- END;
-
- BEGIN (* Hauptprogramm *)
- Init;
- Pictures;
- GlobHelp;
- Logo;
- Start;
- CloseGraph;
- RestoreCrtMode;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von BOLO.PAS *)
-