f2e79224fff8f4bf8e60ca0c89bc9290340b7252
3 * $Id: level.c,v 1.1 2003/12/12 10:55:30 mdw Exp $
5 * Level I/O and handling
7 * (c) 2003 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of XOR.
14 * XOR is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * XOR is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with XOR; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.1 2003/12/12 10:55:30 mdw
33 * Initial checkin. Not there yet.
37 /*----- Header files ------------------------------------------------------*/
41 /*----- Data structures ---------------------------------------------------*/
45 /*----- Main code ---------------------------------------------------------*/
47 int lev_findnext(const level
*l
, int c
, int *x
, int *y
)
52 for (i
= *y
* l
->w
+ *x
+ 1; i
< n
; i
++) {
53 if ((l
->d
[i
] & CF_CELLMASK
) == c
) {
62 int lev_findcell(const level
*l
, int c
, int *x
, int *y
)
67 for (i
= 0; i
< n
; i
++) {
68 if ((l
->d
[i
] & CF_CELLMASK
) == c
) {
77 level
*lev_read(FILE *fp
)
79 level
*l
= CREATE(level
);
80 dstr d
= DSTR_INIT
, dd
= DSTR_INIT
;
89 /* --- Basic initialization --- */
91 l
->name
= xstrdup("<untitled>");
103 /* --- Read the preamble --- */
105 while (dstr_reset(&d
), dstr_putline(&d
, fp
) != EOF
) {
107 q
= str_qword(&p
, 0);
108 if (!q
|| *q
== '#' || *q
== ';')
110 if (strcmp(q
, "name") == 0 && (q
= str_qword(&p
, STRF_QUOTE
)) != 0) {
112 l
->name
= xstrdup(q
);
113 } else if (strcmp(q
, "flags") == 0 && (q
= str_qword(&p
, 0)) != 0) {
116 const char *lfmap
= LF_MAP
;
117 if ((r
= strchr(lfmap
, *q
)) == 0)
119 f
|= 1 << (r
- lfmap
);
122 } else if (strcmp(q
, "masks-collected") == 0 &&
123 (q
= str_qword(&p
, 0)) != 0)
125 else if (strcmp(q
, "masks-total") == 0 &&
126 (q
= str_qword(&p
, 0)) != 0)
128 else if (strcmp(q
, "moves-made") == 0 &&
129 (q
= str_qword(&p
, 0)) != 0)
131 else if (strcmp(q
, "moves-allowed") == 0 &&
132 (q
= str_qword(&p
, 0)) != 0)
134 else if (strcmp(q
, "data") == 0) {
136 while (dstr_reset(&d
), dstr_putline(&d
, fp
) != EOF
) {
137 if (strstr("end", d
.buf
)) break;
139 while (d
.buf
[i
] == C_EMPTY
) i
++;
140 if (ind
== -1 || i
< ind
) ind
= i
;
141 while (d
.buf
[d
.len
- 1] == C_EMPTY
) d
.len
--;
142 if (d
.len
> max
) max
= d
.len
;
148 l
->d
= xmalloc(l
->h
* l
->w
* sizeof(*l
->d
));
149 for (i
= 0; i
< l
->w
* l
->h
; i
++)
152 for (i
= 0; i
< l
->h
; i
++) {
154 p
= dd
.buf
+ n
+ ind
;
156 pp
= l
->d
+ l
->w
* i
;
157 while (p
< q
) *pp
++ = *p
++;
168 while (lev_findcell(l
, C_UKMAP
, &x
, &y
)) {
169 for (i
= C_NWMAP
; lev_findcell(l
, i
, 0, 0); i
++) ;
170 CELLREF(l
, x
, y
) = i
;
172 for (i
= 0; i
< l
->w
* l
->h
; i
++) {
173 if (!cellmap
[l
->d
[i
]]) {
174 fprintf(stderr
, "warning: unknown map item: killing\n");
178 if (l
->v
> l
->vtot
) {
179 fprintf(stderr
, "warning: too many moves already: locking\n");
182 if (lev_findcell(l
, C_PLAYER
, &x
, &y
)) {
183 CELLREF(l
, x
, y
) = C_SPARE
;
184 if (lev_findcell(l
, C_PLAYER
, &xx
, &yy
)) {
185 fprintf(stderr
, "warning: multiple active players: deactivating\n");
187 CELLREF(l
, xx
, yy
) = C_SPARE
;
188 while (lev_findcell(l
, C_PLAYER
, &xx
, &yy
));
190 CELLREF(l
, x
, y
) = C_PLAYER
;
191 } else if (lev_findcell(l
, C_SPARE
, &x
, &y
)) {
192 fprintf(stderr
, "warning: no active player: activating a spare\n");
193 CELLREF(l
, x
, y
) = C_SPARE
;
195 fprintf(stderr
, "warning: no player found: hoping for the best\n");
196 for (i
= 0; i
< l
->w
* l
->h
; i
++)
197 if (cellmap
[l
->d
[i
] & CF_CELLMASK
]->f
& CF_MASK
) n
++;
207 void lev_write(const level
*l
, FILE *fp
)
209 const char *p
= LF_MAP
;
214 fprintf(fp
, "name \"%s\"\n", l
->name
);
215 fprintf(fp
, "flags ");
218 if (f
& 1) putc(*p
, fp
);
223 fprintf(fp
, "masks-collected %d\n", l
->m
);
224 fprintf(fp
, "masks-total %d\n", l
->mtot
);
225 fprintf(fp
, "size = %d x %d\n", l
->w
, l
->h
);
226 fprintf(fp
, "data\n");
227 for (i
= 0, pp
= l
->d
; i
< l
->h
; i
++) {
228 for (j
= 0; j
< l
->w
; j
++) putc(*pp
++, fp
);
231 fprintf(fp
, "end\n");
234 void lev_free(level
*l
)
241 level
*lev_copy(const level
*l
)
243 level
*ll
= CREATE(level
);
245 ll
->name
= xstrdup(l
->name
);
246 ll
->d
= xmalloc(l
->w
* l
->h
* sizeof(*l
->d
));
247 memcpy(ll
->d
, l
->d
, l
->w
* l
->h
* sizeof(*l
->d
));
251 /*----- That's all, folks -------------------------------------------------*/