-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap_builder.c
146 lines (129 loc) · 3.48 KB
/
map_builder.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//
// Compile with : clang -std=c11 -Weverything -I./include map_builder.c -o
// map_builder
//
#include "cdefs.h"
#include "map_binary.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//
// You MUST compile this file with your own map.c
// Your file MUST declare the following symbols
//
extern uint32_t const wolfasm_map_width;
extern uint32_t const wolfasm_map_height;
extern wolfasm_map_case_t const wolfasm_map[];
extern char const wolfasm_map_name[255];
extern wolfasm_map_item_t wolfasm_items[];
extern uint32_t const wolfasm_items_nb;
//
// Create the file
//
static int32_t create_map_header(int32_t const fd) {
int32_t rc = 0;
wolfasm_map_header_t header = {
WOLFASM_MAP_MAGIC, wolfasm_map_width, wolfasm_map_height, {0}};
strncpy(header.name, wolfasm_map_name, sizeof(header.name) - 1);
do {
rc = (int32_t)write(fd, &header, sizeof(header));
} while (rc == -1 && errno == EAGAIN);
if (rc == -1) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
#define MAP_CHECK_ERR(member) \
if (!wolfasm_map[y * wolfasm_map_width + x].member) { \
fprintf(stderr, "Invalid " #member " at [x:%d][y:%d]", x, y); \
return EXIT_FAILURE; \
}
static int32_t create_map(int32_t const fd) {
int32_t rc = 0;
// Write map header
if (create_map_header(fd) != EXIT_SUCCESS) {
return EXIT_FAILURE;
}
// Check map
for (uint32_t x = 0; x < wolfasm_map_width; ++x) {
for (uint32_t y = 0; y < wolfasm_map_height; ++y) {
MAP_CHECK_ERR(item)
MAP_CHECK_ERR(enemy)
MAP_CHECK_ERR(padding)
}
}
// Write map
do {
rc = (int32_t)write(fd, wolfasm_map,
sizeof(wolfasm_map[0]) * wolfasm_map_width *
wolfasm_map_height);
} while (rc == -1 && errno == EAGAIN);
if (rc == -1) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
#undef MAP_CHECK_ERR
static int32_t create_items(int32_t const fd) {
int32_t rc = 0;
// Write items header
wolfasm_map_items_header header = {wolfasm_items_nb};
do {
rc = (int32_t)write(fd, &header, sizeof(header));
} while (rc == -1 && errno == EAGAIN);
if (rc == -1) {
return EXIT_FAILURE;
}
// Write items
do {
rc = (int32_t)write(fd, wolfasm_items,
sizeof(wolfasm_items[0]) * wolfasm_items_nb);
} while (rc == -1 && errno == EAGAIN);
if (rc == -1) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
static int32_t create_map_file(char const *output_file) {
// Create file
int32_t rc = 0;
int32_t fd = open(output_file, O_WRONLY | O_TRUNC | O_CREAT, 0664);
if (fd == -1) {
goto err;
}
// Write map to file
if (create_map(fd) != EXIT_SUCCESS) {
goto err;
}
// Write items to file
if (create_items(fd) != EXIT_SUCCESS) {
goto err;
}
// We're done with generating the map
do {
rc = close(fd);
} while (rc == -1 && errno == EAGAIN);
if (rc == -1) {
goto err;
}
return EXIT_SUCCESS;
// In case of error
err:
fprintf(stderr, "[Err] Cannot create map '%s': %s\n", output_file,
strerror(errno));
return EXIT_FAILURE;
}
int main(int ac, char **av) {
int32_t ret = EXIT_SUCCESS;
if (ac != 2) {
fprintf(stderr, "Usage: %s output_file\n", *av);
ret = EXIT_FAILURE;
} else {
ret = create_map_file(*(av + 1));
}
return ret;
}