1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <draw.h>
5
6 #include "sokoban.h"
7
8 void
consumeline(Biobuf * b)9 consumeline(Biobuf *b)
10 {
11 while(Bgetc(b) != '\n')
12 ;
13 }
14
15 /* parse a level file */
16 int
loadlevels(char * path)17 loadlevels(char *path)
18 {
19 Biobuf *b;
20 int x = 0, y = 0, lnum = 0;
21 char c;
22
23 if(path == nil)
24 return 0;
25
26 b = Bopen(path, OREAD);
27 if(b == nil) {
28 fprint(2, "could not open file %s: %r\n", path);
29 return 0;
30 }
31
32 memset(levels, 0, Maxlevels*sizeof(Level));
33
34 while((c = Bgetc(b)) > 0) {
35 switch(c) {
36 case ';':
37 consumeline(b); /* no ';'-comments in the middle of a level */
38 break;
39 case '\n':
40 levels[lnum].index = lnum;
41 levels[lnum].done = 0;
42 x = 0;
43 levels[lnum].max.y = ++y;
44
45 c = Bgetc(b);
46 if(c == '\n' || c == Beof) {
47 /* end of level */
48 if(++lnum == Maxlevels)
49 goto Done;
50
51 x = 0;
52 y = 0;
53 } else
54 Bungetc(b);
55 break;
56 case '#':
57 levels[lnum].board[x][y] = Wall;
58 x++;
59 break;
60 case ' ':
61 levels[lnum].board[x][y] = Empty;
62 x++;
63 break;
64 case '$':
65 levels[lnum].board[x][y] = Cargo;
66 x++;
67 break;
68 case '*':
69 levels[lnum].board[x][y] = GoalCargo;
70 x++;
71 break;
72 case '.':
73 levels[lnum].board[x][y] = Goal;
74 x++;
75 break;
76 case '@':
77 levels[lnum].board[x][y] = Empty;
78 levels[lnum].glenda = Pt(x, y);
79 x++;
80 break;
81 case '+':
82 levels[lnum].board[x][y] = Goal;
83 levels[lnum].glenda = Pt(x, y);
84 x++;
85 break;
86 default:
87 fprint(2, "impossible character for level %d: %c\n", lnum+1, c);
88 return 0;
89 }
90 if(x > levels[lnum].max.x)
91 levels[lnum].max.x = x;
92 levels[lnum].max.y = y;
93 }
94 Done:
95 Bterm(b);
96
97 level = levels[0];
98 numlevels = lnum;
99
100 return 1;
101 }
102