1 /*****************************************************************************
2 * This file is part of gfxprim library. *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
19 * Copyright (C) 2009-2015 Cyril Hrubis <metan@ucw.cz> *
21 *****************************************************************************/
27 #include "bogoman_debug.h"
28 #include "bogoman_common.h"
29 #include "bogoman_loader.h"
32 * Counts map w and h by reading number of lines and maximal size of line till
33 * first empty line or EOF.
35 static void get_map_info(FILE *f
, unsigned int *w
, unsigned int *h
)
37 unsigned int curw
= 0;
43 while ((ch
= getc(f
)) != EOF
) {
65 static enum bogoman_map_elem_id
id_from_char(const char ch
)
71 return BOGOMAN_PLAYER
;
79 return BOGOMAN_DIAMOND
;
81 return BOGOMAN_MOVEABLE
;
83 return BOGOMAN_EDIBLE
;
92 return BOGOMAN_PARTICLE
;
95 WARN("Unknown map character '%c'", ch
);
104 unsigned char line
[LINE_MAX
];
105 unsigned char input
[LINE_MAX
];
108 static void get_line(FILE *f
, struct line
*l
)
114 while ((ch
= getc(f
)) != EOF
) {
119 l
->input
[l
->len
] = ch
;
120 l
->line
[l
->len
++] = id_from_char(ch
);
126 static void load_map(FILE *f
, struct bogoman_map
*map
)
128 struct line line_a
, line_b
;
129 struct line
*line_cur
, *line_next
;
131 unsigned int player_found
= 0;
136 get_line(f
, line_cur
);
137 get_line(f
, line_next
);
139 while (line_cur
->len
!= 0) {
142 for (x
= 0; x
< line_cur
->len
; x
++) {
143 struct bogoman_map_elem
*elem
;
145 elem
= bogoman_get_map_elem(map
, x
, y
);
147 elem
->id
= line_cur
->line
[x
];
150 /* Compute wall continuations */
153 line_cur
->line
[x
- 1] == BOGOMAN_WALL
)
154 elem
->flags
|= BOGOMAN_LEFT
;
156 if (x
+ 1 < line_cur
->len
&&
157 line_cur
->line
[x
+ 1] == BOGOMAN_WALL
)
158 elem
->flags
|= BOGOMAN_RIGHT
;
161 bogoman_map_elem_id(map
, x
, y
-1) == BOGOMAN_WALL
)
162 elem
->flags
|= BOGOMAN_UP
;
164 if (x
< line_next
->len
&&
165 line_next
->line
[x
] == BOGOMAN_WALL
)
166 elem
->flags
|= BOGOMAN_DOWN
;
171 WARN("Duplicated player at %ux%u previously at %ux%u\n",
172 x
, y
, map
->player_x
, map
->player_y
);
179 case BOGOMAN_DIAMOND
:
180 map
->diamonds_total
++;
182 case BOGOMAN_PARTICLE
:
183 switch (line_cur
->input
[x
]) {
185 elem
->flags
= BOGOMAN_LEFT
| BOGOMAN_PARTICLE_ROUND
;
188 elem
->flags
= BOGOMAN_RIGHT
| BOGOMAN_PARTICLE_ROUND
;
191 elem
->flags
= BOGOMAN_UP
| BOGOMAN_PARTICLE_ROUND
;
194 elem
->flags
= BOGOMAN_DOWN
| BOGOMAN_PARTICLE_ROUND
;
197 elem
->flags
= BOGOMAN_LEFT
| BOGOMAN_PARTICLE_SQUARE
;
200 elem
->flags
= BOGOMAN_RIGHT
| BOGOMAN_PARTICLE_SQUARE
;
203 elem
->flags
= BOGOMAN_UP
| BOGOMAN_PARTICLE_SQUARE
;
206 elem
->flags
= BOGOMAN_DOWN
| BOGOMAN_PARTICLE_SQUARE
;
215 SWAP(line_cur
, line_next
);
216 get_line(f
, line_next
);
221 WARN("No player found in map\n");
224 struct bogoman_map
*bogoman_load(const char *path
)
226 FILE *f
= fopen(path
, "r");
233 get_map_info(f
, &w
, &h
);
235 DEBUG(1, "Have map %ux%u\n", w
, h
);
237 struct bogoman_map
*map
;
240 map_size
= sizeof(struct bogoman_map
) +
241 w
* h
* sizeof(struct bogoman_map_elem
);
243 map
= malloc(map_size
);
248 memset(map
, 0, map_size
);