Mercurial > molko
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 |
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 } |