]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/mahjongg/mahjongg.c
audiohda: fix syntax error
[plan9front.git] / sys / src / games / mahjongg / mahjongg.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <event.h>
5 #include <stdio.h>
6 #include "mahjongg.h"
7
8 #define MJDIR "/sys/games/lib/mahjongg/"
9
10 char *Border    = MJDIR "images/border.bit";
11 char *Mask      = MJDIR "images/mask.bit";
12 char *Gameover  = MJDIR "images/gameover.bit";
13
14 char *deftileset= MJDIR "tilesets/default.tileset";
15 char *defbackgr = MJDIR "backgrounds/default.bit";
16 char *deflayout = MJDIR "layouts/default.layout";
17
18 ulong defchan;
19 int trace;
20
21 char *buttons[] =
22 {
23         "deselect",
24         "new",
25         "restart",
26         "resize",
27         "exit",
28         0
29 };
30
31 Menu menu =
32 {
33         buttons
34 };
35
36 void
37 usage(void)
38 {
39         fprint(2, "usage: %s [-cf] [-b bg] [-l layout] [-t tileset]\n", argv0);
40         exits("usage");
41 }
42
43 Image *
44 eallocimage(Rectangle r, int repl, uint chan, uint color)
45 {
46         Image *tmp;
47
48         tmp = allocimage(display, r, chan, repl, color);
49         if(tmp == nil)
50                 sysfatal("cannot allocate buffer image: %r");
51         return tmp;
52 }
53
54 Image *
55 eloadfile(char *path)
56 {
57         Image *img;
58         int fd;
59
60         fd = open(path, OREAD);
61         if(fd < 0) {
62                 fprint(2, "cannot open image file %s: %r\n", path);
63                 exits("image");
64         }
65         img = readimage(display, fd, 0);
66         if(img == nil)
67                 sysfatal("cannot load image: %r");
68         close(fd);
69
70         return img;
71 }
72
73 void
74 allocimages(void)
75 {
76         Rectangle one = Rect(0, 0, 1, 1);
77
78         selected = eallocimage(one, 1, RGBA32, setalpha(DPalebluegreen, 0x5f));
79         litbrdr = eallocimage(one, 1, RGBA32, DGreen);
80         img = eallocimage(Rect(0, 0, Sizex, Sizey), 0,
81                 defchan? defchan: screen->chan, DBlack);
82         textcol = eallocimage(one, 1, RGBA32, DWhite);
83
84         background = eloadfile(defbackgr);
85         replclipr(background, 1, img->r);
86
87         mask = eloadfile(Mask);
88         gameover = eloadfile(Gameover);
89         tileset = eloadfile(deftileset);
90 }
91
92
93 void
94 eresized(int new)
95 {
96         if(new && getwindow(display, Refnone) < 0)
97                 sysfatal("can't reattach to window");
98         drawlevel();
99 }
100
101 void
102 main(int argc, char **argv)
103 {
104         int clickety = 0;
105         Mouse m;
106         Event e;
107         Point origin = Pt(Bord, Bord);
108
109         ARGBEGIN{
110         case 'b':
111                 defbackgr = EARGF(usage());
112                 break;
113         case 'c':
114                 defchan = RGBA32;
115                 break;
116         case 'f':
117                 trace = 1;
118                 break;
119         case 'l':
120                 deflayout = EARGF(usage());
121                 break;
122         case 't':
123                 deftileset = EARGF(usage());
124                 break;
125         default:
126                 usage();
127         }ARGEND
128
129         if(argc > 0)
130                 usage();
131
132         if(! parse(deflayout)) {
133                 fprint(2, "usage: %s [levelfile]\n", argv[0]);
134                 exits("usage");
135         }
136
137         if(initdraw(nil, nil, "mahjongg") < 0)
138                 sysfatal("initdraw failed: %r");
139         einit(Emouse|Ekeyboard);
140
141         allocimages();
142
143         /* resize to the size of the current level */
144         resize(img->r.max);
145
146         generate(time(0));
147         drawlevel();
148         for(;;) {
149                 if(level.remaining == 0 && !level.done)
150                         done();
151                 switch(event(&e)) {
152                 case Emouse:
153                         m = e.mouse;
154                         if(m.buttons&1) {
155                                 if(level.done)
156                                         break;
157                                 if(!clickety && level.remaining > 0) {
158                                         clickety = 1;
159                                         clicked(subpt(m.xy, addpt(screen->r.min,
160                                                 origin)));
161                                 }
162                         } else {
163                                 clickety = 0;
164                                 if(trace)
165                                         light(subpt(m.xy, addpt(screen->r.min,
166                                                 origin)));
167                         }
168                         if(m.buttons&2) {
169                                 /* nothing here for the moment */
170                         }
171                         if(m.buttons&4)
172                                 switch(emenuhit(3, &m, &menu)) {
173                                 case 0:
174                                         deselect();
175                                         break;
176                                 case 1:
177                                         generate(time(0));
178                                         drawlevel();
179                                         break;
180                                 case 2:
181                                         level = orig;
182                                         drawlevel();
183                                         break;
184                                 case 3:
185                                         resize(img->r.max);
186                                         break;
187                                 case 4:
188                                         exits(nil);
189                                 }
190                         break;
191                 case 2:
192                         switch(e.kbdc) {
193                         case 127:
194                         case 'q':
195                         case 'Q':
196                                 exits(nil);
197                         case 'h':
198                         case 'H':
199                                 if(!level.done)
200                                         hint();
201                                 break;
202                         case 'n':
203                         case 'N':
204                                 /* new */
205                                 generate(time(0));
206                                 drawlevel();
207                                 break;
208                         case 'r':
209                         case 'R':
210                                 level = orig;
211                                 drawlevel();
212                                 break;
213                         case 'c':
214                         case 'C':
215                                 if(!level.done) {
216                                         clearlevel();
217                                         done();
218                                 }
219                                 break;
220                         case 8:
221                         case 'u':
222                         case 'U':
223                                 if(level.done) {
224                                         level.done = 0;
225                                         drawlevel();
226                                 }
227                                 undo();
228                                 break;
229                         }
230                         break;
231                 }
232         }
233 }