-
Notifications
You must be signed in to change notification settings - Fork 0
/
Stars.Mod.txt
109 lines (93 loc) · 3.72 KB
/
Stars.Mod.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
MODULE Stars; (*NW 15.1.2013, 15.11.2013*)
IMPORT SYSTEM, Display, Viewers, Texts, Oberon, MenuViewers, TextFrames;
CONST N = 6; (*nof stars*)
w = 16; (*width of star*)
interval = 200; (*millisec*)
TYPE Frame = POINTER TO FrameDesc;
Pos = RECORD x, y, dx, dy: INTEGER END ;
FrameDesc = RECORD (Display.FrameDesc) s: ARRAY N OF Pos END ;
RestoreMsg = RECORD (Display.FrameMsg) END ;
StepMsg = RECORD (Display.FrameMsg) END ;
VAR T: Oberon.Task;
W: Texts.Writer;
PROCEDURE Draw(x, y: INTEGER);
BEGIN Display.CopyPattern(Display.white, Display.star, x, y, Display.invert)
END Draw;
PROCEDURE Restore(F: Frame);
VAR x0, y0: INTEGER;
BEGIN Oberon.RemoveMarks(F.X, F.Y, F.W, F.H);
Display.ReplConst(0, F.X+1, F.Y, F.W-1, F.H, 0);
x0 := F.W DIV 2 + F.X; y0 := F.H DIV 2 + F.Y;
F.s[0].x := x0; F.s[0].y := y0; F.s[0].dx := 2; F.s[0].dy := 4; Draw(F.s[0].x, F.s[0].y);
F.s[1].x := x0; F.s[1].y := y0; F.s[1].dx := 3; F.s[1].dy := 9; Draw(F.s[1].x, F.s[1].y);
F.s[2].x := x0; F.s[2].y := y0; F.s[2].dx := -5; F.s[2].dy := -2; Draw(F.s[2].x, F.s[2].y);
F.s[3].x := x0; F.s[3].y := y0; F.s[3].dx := -10; F.s[3].dy := 8; Draw(F.s[3].x, F.s[3].y);
F.s[4].x := x0; F.s[4].y := y0; F.s[4].dx := -7; F.s[4].dy := -4; Draw(F.s[4].x, F.s[4].y);
F.s[5].x := x0; F.s[5].y := y0; F.s[5].dx := 8; F.s[5].dy := -10; Draw(F.s[5].x, F.s[5].y)
END Restore;
PROCEDURE Move(F: Frame; VAR p: Pos);
VAR X1, Y1: INTEGER;
BEGIN X1 := F.X + F.W - w; Y1 := F.Y + F.H - w;
Draw(p.x, p.y); INC(p.x, p.dx); INC(p.y, p.dy);
IF p.x < F.X THEN p.x := 2*F.X - p.x; p.dx := -p.dx ELSIF p.x >= X1 THEN p.x := 2*X1 - p.x; p.dx := -p.dx END ;
IF p.y < F.Y THEN p.y := 2*F.Y - p.y; p.dy := -p.dy ELSIF p.y >= Y1 THEN p.y := 2*Y1 - p.y; p.dy := -p.dy END ;
Draw(p.x, p.y)
END Move;
PROCEDURE Steps(F: Frame);
VAR i: INTEGER;
BEGIN i := 0;
WHILE i < N DO Move(F, F.s[i]); INC(i) END
END Steps;
PROCEDURE Handle(F: Display.Frame; VAR M: Display.FrameMsg);
VAR F1: Frame;
BEGIN
CASE F OF Frame:
CASE M OF
Oberon.InputMsg:
IF M(Oberon.InputMsg).id = Oberon.track THEN
Oberon.DrawMouseArrow(M(Oberon.InputMsg).X, M(Oberon.InputMsg).Y)
END
| StepMsg: Steps(F)
| RestoreMsg: Restore(F)
| Oberon.CopyMsg: Oberon.Remove(T); NEW(F1); F1^ := F^; M.F := F1
| MenuViewers.ModifyMsg:
IF (M.Y # F.Y) OR (M.H # F.H) THEN F.Y := M.Y; F.H := M.H; Restore(F) END
END
END
END Handle;
PROCEDURE Step*;
VAR k: INTEGER; M: StepMsg;
BEGIN
IF Oberon.Par.vwr.dsc = Oberon.Par.frame THEN Steps(Oberon.Par.frame.next(Frame))
ELSE Viewers.Broadcast(M)
END
END Step;
PROCEDURE Open*;
VAR F: Frame; V: Viewers.Viewer; X, Y: INTEGER;
BEGIN NEW(F); F.handle := Handle;
Oberon.AllocateUserViewer(Oberon.Par.vwr.X, X, Y);
V := MenuViewers.New(
TextFrames.NewMenu("Stars", "Stars.Close System.Grow System.Copy Stars.Step Stars.Run Stars.Stop"),
F, TextFrames.menuH, X, Y)
END Open;
PROCEDURE Run*;
BEGIN Oberon.Install(T)
END Run;
PROCEDURE Stop*;
BEGIN Oberon.Remove(T)
END Stop;
PROCEDURE Close*;
BEGIN
IF Oberon.Par.vwr.dsc = Oberon.Par.frame THEN Stop; Viewers.Close(Oberon.Par.vwr) END
END Close;
PROCEDURE Step1;
VAR M: StepMsg;
BEGIN Viewers.Broadcast(M)
END Step1;
PROCEDURE SetPeriod*;
VAR S: Texts.Scanner;
BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
IF S.class = Texts.Int THEN T.period := S.i END
END SetPeriod;
BEGIN Texts.OpenWriter(W); T := Oberon.NewTask(Step1, interval);
END Stars.