home *** CD-ROM | disk | FTP | other *** search
- MODULE Tetriz;
-
- IMPORT I := Intuition,
- g := Graphics,
- e := Exec,
- d := Dos,
- r := Random,
- au := Audio,
- es := ExecSupport;
-
- CONST
- W = 10; (* Spielfeldgröße *)
- H = 20;
- bw = 20; (* Boxgröße *)
- bh = 8;
- w = bw*W; (* Fenstergröße *)
- h = bh*H;
-
- TYPE
- SteineFeld = ARRAY 7,4 OF SET;
-
- CONST
- S = SteineFeld(
- {0..3}, {0,4,8,12}, {0..3}, {0,4,8,12},
- {0..2,5}, {0,4,5,8}, {1,4..6}, {1,4,5,9},
- {0..2,4}, {0,4,8,9}, {2,4..6}, {0,1,5,9},
- {0..2,6}, {0,1,4,8}, {0,4..6}, {1,5,8,9},
- {0,1,5,6}, {1,4,5,8}, {0,1,5,6}, {1,4,5,8},
- {1,2,4,5}, {0,4,5,9}, {1,2,4,5}, {0,4,5,9},
- {0,1,4,5}, {0,1,4,5}, {0,1,4,5}, {0,1,4,5});
-
- VAR
- Feld: ARRAY W,H OF INTEGER;
-
- textattr: g.TextAttr;
- nw: I.NewWindow;
- window: I.WindowPtr;
-
- rp: g.RastPortPtr;
-
- MyMsgPtr: I.IntuiMessagePtr;
- MyMsg: I.IntuiMessage;
-
- Lines: INTEGER;
- HiScore: INTEGER;
-
- CONST (* $DataChip+ *)
- RectTable = "\x7F\x80";
- RectTableSize = 2;
- AllocationMap = "\x01\x08\x02\x04";
-
- VAR
- AllocPort: e.MsgPortPtr;
- AllocIOB: au.IOAudioPtr;
- AllocMap: UNTRACED POINTER TO ARRAY 4 OF CHAR;
- Rect: UNTRACED POINTER TO ARRAY 2 OF CHAR;
- AudioOpen: BOOLEAN;
-
- TYPE
- DoProc = PROCEDURE(x,y,c: INTEGER);
-
- VAR
- collCnt: INTEGER;
- font: g.TextFontPtr;
-
- (*-------------------------------------------------------------------------*)
- (* $Debug- *)
-
- PROCEDURE * Box(x,y,c: INTEGER);
-
- BEGIN
- IF (x>=0) AND (y>=0) THEN
- g.SetAPen(rp,c);
- x := x*bw; y := y*bh;
- g.RectFill(rp,x+1,y+1,x+(bw-2),y+(bh-1));
- END;
- END Box;
-
- PROCEDURE Do(s: SET; x,y,c: INTEGER; what: DoProc);
- VAR
- i,j: INTEGER;
- X,Y: INTEGER;
- BEGIN
- i := 0;
- REPEAT
- j := 0;
- REPEAT
- IF 4*i+j IN s THEN
- X := x+j; Y := y+i;
- CASE X OF 0..W-1: CASE Y OF 0..H-1: what(X,Y,c) ELSE END ELSE END;
- END;
- INC(j);
- UNTIL j=4;
- INC(i);
- UNTIL i=4;
- END Do;
-
-
- PROCEDURE * CollCnt(x,y,c: INTEGER);
- BEGIN IF Feld[x,y]=0 THEN INC(collCnt) END END CollCnt;
-
- PROCEDURE Collide(s: SET; x,y: INTEGER): BOOLEAN;
- BEGIN
- IF y<0 THEN RETURN FALSE END;
- collCnt := 0;
- Do(s,x,y,0,CollCnt);
- RETURN collCnt#4;
- END Collide;
-
-
- PROCEDURE * AddIt(x,y,c: INTEGER);
- BEGIN Feld[x,y] := c END AddIt;
-
-
- PROCEDURE Draw(s: SET; x,y,c: INTEGER);
- BEGIN Do(s,x,y,c,Box) END Draw;
-
-
- PROCEDURE WriteInt(i: INTEGER);
- VAR
- s: ARRAY 4 OF CHAR;
- c: INTEGER;
- BEGIN
- c := 0;
- REPEAT
- s[3-c] := CHR(30H + i MOD 10);
- i := i DIV 10;
- INC(c);
- UNTIL c=4;
- g.SetAPen(rp,1); g.SetBPen(rp,0); g.SetDrMd(rp,g.jam2);
- g.Text(rp,s,4);
- END WriteInt;
-
-
- PROCEDURE CheckLine();
- VAR
- x,y,y2: INTEGER;
- lines: ARRAY H OF INTEGER;
- lcnt: INTEGER;
- BEGIN
- lcnt := 0;
- y := 0;
- REPEAT
- x := 0;
- LOOP
- IF Feld[x,y]=0 THEN EXIT END;
- INC(x);
- IF x=W THEN lines[lcnt] := 8*y; INC(lcnt); EXIT END;
- END;
- INC(y);
- UNTIL y=H;
- IF lcnt#0 THEN
-
- INC(Lines,lcnt);
- g.Move(rp,56,h+8); WriteInt(Lines);
-
- es.BeginIO(AllocIOB);
- g.SetDrMd(rp,SHORTSET{g.complement});
- x := 0;
- REPEAT
- y := 0;
- REPEAT
- g.RectFill(rp,0,lines[y]+1,w-1,lines[y]+7);
- INC(y);
- UNTIL y=lcnt;
- INC(x);
- d.Delay(3);
- UNTIL x=8;
- g.SetDrMd(rp,g.jam1);
- IF e.WaitIO(AllocIOB)=0 THEN END;
-
- y := 19; y2 := 19; DEC(lcnt);
- LOOP
- IF y2<0 THEN EXIT END;
- WHILE (lcnt>=0) AND (lines[lcnt]=8*y2) DO DEC(y2); DEC(lcnt) END;
- IF y2<0 THEN EXIT END;
- x := 0;
- REPEAT
- Feld[x,y] := Feld[x,y2];
- INC(x);
- UNTIL x=W;
- DEC(y); DEC(y2);
- END;
- WHILE y>=0 DO
- x := 0;
- REPEAT
- Feld[x,y] := 0;
- INC(x);
- UNTIL x=W;
- DEC(y)
- END;
- y := 0;
- REPEAT
- x := 0;
- REPEAT
- Box(x,y,Feld[x,y]);
- INC(x);
- UNTIL x=W;
- INC(y);
- UNTIL y=H;
- END;
- END CheckLine;
-
- (* $Debug= *)
-
-
- PROCEDURE Play(): BOOLEAN; (* TRUE wenn Q gedrückt *)
-
- VAR
- Stein: INTEGER;
- x,x2,y,y2,c: INTEGER;
- TimeCnt: INTEGER;
- Turn,NewTurn: INTEGER;
-
- BEGIN
- g.SetAPen(rp,0);
- g.RectFill(rp,0,0,w,h);
-
- x := 0;
- REPEAT
- y := 0;
- REPEAT
- Feld[x,y] := 0;
- INC(y);
- UNTIL y=H;
- INC(x);
- UNTIL x=W;
-
- Lines := 0; TimeCnt := 0;
-
- REPEAT
- Stein := r.RND(7);
- CASE window.wScreen.bitMap.depth OF
- | 1: c := 1;
- | 2: c := Stein MOD 3 + 1
- ELSE c := Stein + 1
- END;
- Turn := 0;
- x := W DIV 2 - 1; IF Stein=0 THEN DEC(x) END;
- y := 0;
- LOOP
- IF Collide(S[Stein,Turn],x,y) THEN EXIT END;
- Draw(S[Stein,Turn],x,y-1,0);
- Draw(S[Stein,Turn],x,y,c);
- LOOP
- Draw(S[Stein,Turn],x,y,c);
- IF TimeCnt>=100 THEN DEC(TimeCnt,100); EXIT END;
- REPEAT
- e.WaitPort(window.userPort);
- MyMsgPtr := e.GetMsg(window.userPort);
- UNTIL MyMsgPtr#NIL;
- MyMsg := MyMsgPtr^;
- e.ReplyMsg(MyMsgPtr);
- IF I.intuiTicks IN MyMsg.class THEN INC(TimeCnt,15+Lines) END;
- IF I.vanillaKey IN MyMsg.class THEN
- Draw(S[Stein,Turn],x,y,0);
- CASE MyMsg.code OF
- ORD('4'):
- IF (x>0) AND NOT Collide(S[Stein,Turn],x-1,y) THEN DEC(x) END |
- ORD('5'):
- NewTurn := (Turn + 1) MOD 4;
- x2 := x; y2 := y;
- IF Stein=0 THEN
- IF ODD(Turn) THEN IF x2=0 THEN x2 := -1 ELSE DEC(x2); INC(y2) END
- ELSE INC(x2); DEC(y2) END;
- END;
- IF NOT Collide(S[Stein,NewTurn],x2,y2) THEN
- Turn := NewTurn;
- x := x2;
- y := y2;
- END |
- ORD('6'):
- IF NOT Collide(S[Stein,Turn],x+1,y) THEN INC(x) END |
- ORD(' '):
- LOOP
- Draw(S[Stein,Turn],x,y,c);
- IF Collide(S[Stein,Turn],x,y+1) THEN EXIT END;
- d.Delay(1);
- INC(y);
- Draw(S[Stein,Turn],x,y-1,0);
- END;
- EXIT |
- ORD('q'): RETURN TRUE |
- ELSE END;
- END;
- IF I.closeWindow IN MyMsg.class THEN RETURN TRUE END;
- END;
- INC(y);
- END;
- IF y>0 THEN
- Do(S[Stein,Turn],x,y-1,c,AddIt);
- CheckLine;
- END;
- UNTIL y=0;
-
- IF Lines>HiScore THEN HiScore := Lines END;
-
- d.Delay(30);
-
- RETURN FALSE;
- END Play;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- BEGIN
-
- window := NIL; HiScore := 0; AllocPort := NIL; AudioOpen := FALSE;
-
-
- (*------ Open Audio-Device: ------*)
-
- AllocPort := es.CreatePort("",0);
- IF AllocPort=NIL THEN HALT(0) END;
-
- NEW(AllocIOB);
- NEW(AllocMap); AllocMap^ := AllocationMap;
- AllocIOB.request.message.node.pri := -40;
- AllocIOB.request.message.replyPort := AllocPort;
- AllocIOB.data := AllocMap;
- AllocIOB.length := 4;
-
- IF (e.OpenDevice("audio.device",0,AllocIOB,LONGSET{})#0) OR
- (AllocIOB.request.error = au.allocFailed)
- THEN HALT(0) END;
-
- AudioOpen := TRUE;
-
- NEW(Rect); Rect^ := RectTable;
- AllocIOB.request.command := e.write;
- AllocIOB.request.flags := SHORTSET{4};
- AllocIOB.data := Rect;
- AllocIOB.length := RectTableSize;
- AllocIOB.period := 4000;
- AllocIOB.cycles := 200;
- AllocIOB.volume := 64;
-
- (*------ Open Window: ------*)
-
- nw.leftEdge := (g.gfx.normalDisplayColumns - (w+ 8)) DIV 2;
- nw.topEdge := (g.gfx.normalDisplayRows - (h+24)) DIV 2;
- nw.width := w+8;
- nw.height := h+24;
- nw.blockPen := 1;
- nw.idcmpFlags := LONGSET{I.closeWindow,I.vanillaKey,I.intuiTicks};
- nw.flags := LONGSET{I.windowClose,I.windowDepth,I.windowDrag,I.gimmeZeroZero,I.activate};
- nw.type := {I.wbenchScreen};
- NEW(nw.title);
- nw.title^ := "Tetriz";
- IF I.int.libNode.version>=36 THEN
- window := I.OpenWindowTags(nw,I.waInnerWidth, w,
- I.waInnerHeight,h+10,
- 0 (* Utility.done *) );
- ELSE
- window := I.OpenWindow(nw);
- END;
- IF window=NIL THEN HALT(0) END;
- rp := window.rPort;
- NEW(textattr.name); textattr.name^ := "topaz.font";
- textattr.ySize := 8;
- textattr.flags := SHORTSET{};
- textattr.style := SHORTSET{};
- font := g.OpenFont(textattr);
- IF font=NIL THEN HALT(0) END;
- g.SetFont(rp,font);
-
- (*------ Start: ------*)
-
- LOOP
-
- g.SetAPen(rp,0); g.SetDrMd(rp,g.jam1);
- g.RectFill(rp,0,0,w,h);
- g.SetAPen(rp,1);
-
- g.Move(rp, 20,20); g.Text(rp,"S = Start",9);
- g.Move(rp, 20,40); g.Text(rp,"Q = Quit" ,8);
- g.Move(rp, 20,60); g.Text(rp,"© 1989 by F. Siebert",20);
- g.Move(rp, 20,80); g.Text(rp," AMOK Stuttgart",17);
- g.Move(rp, 0,h+8); g.Text(rp,"Lines:" ,6);
- g.Move(rp,108,h+8); g.Text(rp,"Hi:" ,3);
- g.Move(rp,144,h+8); WriteInt(HiScore);
-
- REPEAT
- REPEAT
- e.WaitPort(window.userPort);
- MyMsgPtr := e.GetMsg(window.userPort);
- UNTIL MyMsgPtr#NIL;
- MyMsg := MyMsgPtr^;
- e.ReplyMsg(MyMsgPtr);
- UNTIL LONGSET{I.intuiTicks}#MyMsg.class;
-
- IF I.vanillaKey IN MyMsg.class THEN
- CASE MyMsg.code OF
- ORD('s'): IF Play() THEN EXIT END |
- ORD('q'): EXIT |
- ELSE END;
- ELSIF I.closeWindow IN MyMsg.class THEN
- EXIT
- END;
-
- END;
-
- CLOSE
-
- IF window#NIL THEN I.CloseWindow(window) END;
- IF AudioOpen THEN e.CloseDevice(AllocIOB) END;
- IF AllocPort#NIL THEN es.DeletePort(AllocPort) END;
- IF font#NIL THEN g.CloseFont(font) END;
-
- END Tetriz.
-
-
-
-