annotate librpg/rpg/map-file.c @ 212:ddfe0a211169

rpg: experiment with map teleport
author David Demelier <markand@malikania.fr>
date Mon, 16 Nov 2020 14:26:13 +0100
parents adcbb7ccfdee
children 64f24b482722
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * map-file.c -- map file loader
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #define _XOPEN_SOURCE 700
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <assert.h>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <errno.h>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 #include <libgen.h>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include <limits.h>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 #include <stddef.h>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #include <stdio.h>
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
26 #include <stdlib.h>
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include <string.h>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 #include <core/alloc.h>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 #include <core/error.h>
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 #include <core/image.h>
212
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
32 #include <core/trace.h>
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 #include "map-file.h"
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
35
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 /* Create %<v>c string literal for scanf */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 #define MAX_F(v) MAX_F_(v)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 #define MAX_F_(v) "%" #v "c"
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
39
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 struct parser {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
41 struct map_file *mf; /* Map loader. */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 struct map *map; /* Map object to fill. */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 FILE *fp; /* Map file pointer. */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 char basedir[PATH_MAX]; /* Parent map directory */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 };
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
46
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
47 static int
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
48 tiledef_cmp(const void *d1, const void *d2)
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
49 {
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
50 const struct map_tiledef *mtd1 = d1;
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
51 const struct map_tiledef *mtd2 = d2;
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
52
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
53 if (mtd1->id < mtd2->id)
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
54 return -1;
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
55 if (mtd1->id > mtd2->id)
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
56 return 1;
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
57
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
58 return 0;
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
59 }
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
60
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
61 static bool
212
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
62 parse_tiles(struct parser *ps, const char *layer_name)
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 enum map_layer_type layer_type;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 size_t amount, current;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
66
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 if (strcmp(layer_name, "background") == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 layer_type = MAP_LAYER_TYPE_BACKGROUND;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 else if (strcmp(layer_name, "foreground") == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 layer_type = MAP_LAYER_TYPE_FOREGROUND;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 else
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 return errorf("invalid layer type: %s", layer_name);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
73
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 amount = ps->map->w * ps->map->h;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 current = 0;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
76
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 /*
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 * The next line after a layer declaration is a list of plain integer
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 * that fill the layer tiles.
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 if (!(ps->mf->layers[layer_type].tiles = alloc_zero(amount, sizeof (unsigned short))))
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 return false;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
83
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
84 for (int tile; fscanf(ps->fp, "%d\n", &tile) && current < amount; ++current)
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 ps->mf->layers[layer_type].tiles[current] = tile;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
86
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 ps->map->layers[layer_type].tiles = ps->mf->layers[layer_type].tiles;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
88
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
91
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 static bool
212
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
93 parse_actions(struct parser *ps)
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
94 {
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
95 char exec[128 + 1];
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
96 int x = 0, y = 0;
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
97 unsigned int w = 0, h = 0;
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
98
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
99 while (fscanf(ps->fp, "%d|%d|%u|%u|%128[^\n]\n", &x, &y, &w, &h, exec) == 5) {
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
100 struct action *act;
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
101
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
102 if (!ps->mf->load_action) {
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
103 tracef("ignoring action %d,%d,%u,%u,%s", x, y, w, h, exec);
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
104 continue;
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
105 }
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
106
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
107 if ((act = ps->mf->load_action(ps->map, x, y, w, h, exec)))
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
108 action_stack_add(&ps->map->actions, act);
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
109 }
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
110
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
111 return true;
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
112 }
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
113
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
114 static bool
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
115 parse_layer(struct parser *ps, const char *line)
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
116 {
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
117 char layer_name[32 + 1] = {0};
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
118
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
119 /* Check if weight/height has been specified. */
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
120 if (ps->map->w == 0 || ps->map->h == 0)
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
121 return errorf("missing map dimensions before layer");
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
122
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
123 /* Determine layer type. */
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
124 if (sscanf(line, "layer|%32s", layer_name) <= 0)
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
125 return errorf("missing layer type definition");
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
126
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
127 if (strcmp(layer_name, "actions") == 0)
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
128 return parse_actions(ps);
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
129
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
130 return parse_tiles(ps, layer_name);
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
131 }
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
132
ddfe0a211169 rpg: experiment with map teleport
David Demelier <markand@malikania.fr>
parents: 211
diff changeset
133 static bool
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 parse_tileset(struct parser *ps, const char *line)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 char filename[FILENAME_MAX + 1] = {0};
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 char filepath[PATH_MAX];
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 int ret;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
139
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 if (ps->map->tile_w == 0 || ps->map->tile_h == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 return errorf("missing map dimensions before tileset");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
142
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 if ((ret = sscanf(line, "tileset|" MAX_F(FILENAME_MAX), filename)) == 1) {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 snprintf(filepath, sizeof (filepath), "%s/%s", ps->basedir, filename);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
145
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 if (!image_open(&ps->mf->tileset, filepath))
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 return false;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
149
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 /* Initialize sprite. */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 sprite_init(&ps->mf->sprite, &ps->mf->tileset, ps->map->tile_w, ps->map->tile_h);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 ps->map->tileset = &ps->mf->sprite;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
153
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
156
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 static bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 parse_title(struct parser *ps, const char *line)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 if (sscanf(line, "title|" MAX_F(MAP_FILE_TITLE_MAX), ps->mf->title) != 1 || strlen(ps->mf->title) == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 return errorf("null map title");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
162
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 ps->map->title = ps->mf->title;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
164
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
167
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 static bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 parse_width(struct parser *ps, const char *line)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 if (sscanf(line, "width|%u", &ps->map->w) != 1 || ps->map->w == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 return errorf("null map width");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
173
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
176
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 static bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 parse_height(struct parser *ps, const char *line)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 if (sscanf(line, "height|%u", &ps->map->h) != 1 || ps->map->h == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 return errorf("null map height");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
182
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
185
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 static bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 parse_tilewidth(struct parser *ps, const char *line)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 if (sscanf(line, "tilewidth|%hu", &ps->map->tile_w) != 1 || ps->map->tile_w == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 return errorf("null map tile width");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 if (ps->map->w == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 return errorf("missing map width before tilewidth");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
193
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 ps->map->real_w = ps->map->w * ps->map->tile_w;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
195
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
198
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 static bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 parse_tileheight(struct parser *ps, const char *line)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 if (sscanf(line, "tileheight|%hu", &ps->map->tile_h) != 1 || ps->map->tile_h == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 return errorf("null map tile height");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 if (ps->map->h == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 return errorf("missing map height before tileheight");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
206
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 ps->map->real_h = ps->map->h * ps->map->tile_h;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
208
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
211
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 static bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 parse_origin(struct parser *ps, const char *line)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 if (sscanf(line, "origin|%d|%d", &ps->map->origin_x, &ps->map->origin_y) != 2)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 return errorf("invalid origin");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
217
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
218 /*
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 * We adjust the player position here because it should not be done in
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 * the map_init function. This is because the player should not move
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 * magically each time we re-use the map (saving position).
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
222 */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 ps->map->player_x = ps->map->origin_x;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 ps->map->player_y = ps->map->origin_y;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
225
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
228
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 static bool
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
230 parse_tiledefs(struct parser *ps, const char *line)
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
231 {
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
232 (void)line;
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
233
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
234 short x, y;
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
235 unsigned short id, w, h;
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
236 struct map_tiledef *tiledefs = NULL;
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
237 size_t tiledefsz = 0;
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
238
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
239 while (fscanf(ps->fp, "%hu|%hd|%hd|%hu|%hu\n", &id, &x, &y, &w, &h) == 5) {
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
240 tiledefs = allocator.realloc(tiledefs, ++tiledefsz * sizeof (*tiledefs));
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
241 tiledefs[tiledefsz - 1].id = id;
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
242 tiledefs[tiledefsz - 1].x = x;
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
243 tiledefs[tiledefsz - 1].y = y;
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
244 tiledefs[tiledefsz - 1].w = w;
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
245 tiledefs[tiledefsz - 1].h = h;
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
246 }
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
247
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
248 qsort(tiledefs, tiledefsz, sizeof (*tiledefs), tiledef_cmp);
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
249 ps->map->tiledefs = ps->mf->tiledefs = tiledefs;
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
250 ps->map->tiledefsz = tiledefsz;
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
251
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
252 return true;
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
253 }
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
254
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
255 static bool
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 parse_line(struct parser *ps, const char *line)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 static const struct {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 const char *property;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 bool (*read)(struct parser *, const char *);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 } props[] = {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 { "title", parse_title },
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 { "width", parse_width },
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 { "height", parse_height },
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 { "tilewidth", parse_tilewidth },
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 { "tileheight", parse_tileheight },
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 { "tileset", parse_tileset },
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 { "origin", parse_origin },
210
70e6ed74940d rpg: attempt of collide detection in map
David Demelier <markand@malikania.fr>
parents: 197
diff changeset
269 { "layer", parse_layer },
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
270 { "tiledefs", parse_tiledefs }
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 };
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
272
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 for (size_t i = 0; i < NELEM(props); ++i)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 if (strncmp(line, props[i].property, strlen(props[i].property)) == 0)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 return props[i].read(ps, line);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
276
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
279
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 static bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 parse(struct map_file *loader, const char *path, struct map *map, FILE *fp)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 char line[1024];
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 struct parser ps = {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 .mf = loader,
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 .map = map,
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 .fp = fp
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
288 };
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
289
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
290 /*
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 * Even though dirname(3) usually not modify the path as argument it may
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 * do according to POSIX specification, as such we still need a
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 * temporary buffer.
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 snprintf(ps.basedir, sizeof (ps.basedir), "%s", path);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 snprintf(ps.basedir, sizeof (ps.basedir), "%s", dirname(ps.basedir));
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
297
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 while (fgets(line, sizeof (line), fp)) {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 /* Remove \n if any */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 line[strcspn(line, "\n")] = '\0';
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
301
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
302 if (!parse_line(&ps, line))
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 return false;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
304 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
305
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
306 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
308
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 static bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 check(struct map *map)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
311 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
312 /*
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 * Check that we have parsed every required components.
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 if (!map->title)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
316 return errorf("missing title");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
317
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 /*
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
319 * We don't need to check width/height because parsing layers and
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 * tilesets already check for their presence, so only check layers.
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
321 */
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
322 if (!map->layers[0].tiles)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
323 return errorf("missing background layer");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
324 if (!map->layers[1].tiles)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
325 return errorf("missing foreground layer");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
326 if (!sprite_ok(map->tileset))
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
327 return errorf("missing tileset");
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
328
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
329 return true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
330 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
331
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
332 bool
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
333 map_file_open(struct map_file *file, const char *path, struct map *map)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
334 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
335 assert(file);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
336 assert(path);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
337 assert(map);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
338
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
339 FILE *fp;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
340 bool ret = true;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
341
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
342 memset(map, 0, sizeof (*map));
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
343
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
344 if (!(fp = fopen(path, "r")))
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
345 return errorf("%s", strerror(errno));
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
346
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
347 if (!(ret = parse(file, path, map, fp)) || !(ret = check(map))) {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
348 map_finish(map);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
349 map_file_finish(file);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
350 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
351
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
352 fclose(fp);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
353
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
354 return ret;
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
355 }
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
356
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
357 void
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
358 map_file_finish(struct map_file *file)
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
359 {
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
360 assert(file);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
361
211
adcbb7ccfdee rpg: some refactoring
David Demelier <markand@malikania.fr>
parents: 210
diff changeset
362 free(file->tiledefs);
197
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
363 texture_finish(&file->tileset);
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
364 memset(file, 0, sizeof (*file));
852d0b7817ce rpg: map, extreme cleanup, closes #2508 @4h
David Demelier <markand@malikania.fr>
parents:
diff changeset
365 }