levelz-c 0.1.0
Loading...
Searching...
No Matches
levelz.h
1#ifndef LEVELZ_MAIN_H
2#define LEVELZ_MAIN_H
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <ctype.h>
8
9#include "levelz/coordinate.h"
10#include "levelz/block.h"
11#include "levelz/level.h"
12#include "levelz/matrix.h"
13
17const char* LEVELZ_HEADER_END = "---";
18
22const char* LEVELZ_END = "end";
23
24// Internal
25
26char* __trim(const char* str) {
27 char* str0 = (char*) malloc(strlen(str) + 1);
28 strcpy(str0, str);
29
30 int i = 0;
31 while (isspace(str0[i])) i++;
32
33 int j = strlen(str0) - 1;
34 while (isspace(str0[j])) j--;
35
36 char* str1 = (char*) malloc(j - i + 2);
37 strncpy(str1, str0 + i, j - i + 1);
38 str1[j - i + 1] = '\0';
39
40 return str1;
41}
42
43LevelHeader** __readHeaders(char** input) {
44 LevelHeader** headers = 0;
45
46 int index = 0;
47 while (1) {
48 char* line = input[index];
49 if (line == 0) break;
50
51 LevelHeader* header = LevelHeader_fromString(__trim(line));
52 if (headers == 0)
53 headers = (LevelHeader**) malloc(2 * sizeof(LevelHeader*));
54 else
55 headers = (LevelHeader**) realloc(headers, (index + 2) * sizeof(LevelHeader*));
56
57 headers[index] = header;
58 headers[index + 1] = 0;
59 index++;
60 }
61
62 return headers;
63}
64
65Coordinate2D** __read2DPoints(const char* input) {
66 Coordinate2D** points = 0;
67
68 char* trimmed = __trim(input);
69 char* str0 = (char*) malloc(strlen(trimmed) + 1);
70 strcpy(str0, trimmed);
71
72 char* start = str0;
73 char* end;
74 while (*start) {
75 end = start;
76 while (*end && *end != '*') end++;
77 char* token = (char*) malloc(end - start + 1);
78 strncpy(token, start, end - start);
79 token[end - start] = '\0';
80
81 if (token[0] == '(') {
82 CoordinateMatrix2D* matrix = CoordinateMatrix2D_fromString(token);
83 if (matrix == 0) {
84 free(str0);
85 return 0;
86 }
87
88 int size = CoordinateMatrix2D_size(matrix);
89
90 if (points == 0)
91 points = CoordinateMatrix2D_coordinates(matrix);
92 else {
93 int length = 0;
94 while (points[length] != 0) length++;
95
96 points = (Coordinate2D**) realloc(points, (length + size + 1) * sizeof(Coordinate2D));
97
98 Coordinate2D** matrixPoints = CoordinateMatrix2D_coordinates(matrix);
99 for (int i = 0; i < size; i++) {
100 points[length + i] = matrixPoints[i];
101 }
102
103 points[length + size] = 0;
104 }
105 } else {
106 Coordinate2D* point = Coordinate2D_fromString(token);
107
108 if (point == 0) {
109 free(str0);
110 return 0;
111 }
112
113 if (points == 0) {
114 points = (Coordinate2D**) malloc(2 * sizeof(Coordinate2D));
115 points[0] = point;
116 points[1] = 0;
117 } else {
118 int length = 0;
119 while (points[length] != 0) length++;
120
121 points = (Coordinate2D**) realloc(points, (length + 2) * sizeof(Coordinate2D));
122
123 points[length] = point;
124 points[length + 1] = 0;
125 }
126 }
127
128 start = (*end) ? end + 1 : end;
129 }
130
131 free(str0);
132 return points;
133}
134
135Coordinate3D** __read3DPoints(char* input) {
136 Coordinate3D** points = 0;
137
138 char* trimmed = __trim(input);
139 char* str0 = (char*) malloc(strlen(trimmed) + 1);
140 strcpy(str0, trimmed);
141
142 char* start = str0;
143 char* end;
144 while (*start) {
145 end = start;
146 while (*end && *end != '*') end++;
147 char* token = (char*) malloc(end - start + 1);
148 strncpy(token, start, end - start);
149 token[end - start] = '\0';
150
151 if (token[0] == '(') {
152 CoordinateMatrix3D* matrix = CoordinateMatrix3D_fromString(token);
153 if (matrix == 0) {
154 free(str0);
155 return 0;
156 }
157
158 int size = CoordinateMatrix3D_size(matrix);
159
160 if (points == 0)
161 points = CoordinateMatrix3D_coordinates(matrix);
162 else {
163 int length = 0;
164 while (points[length] != 0) length++;
165
166 points = (Coordinate3D**) realloc(points, (length + size + 1) * sizeof(Coordinate3D));
167
168 Coordinate3D** matrixPoints = CoordinateMatrix3D_coordinates(matrix);
169 for (int i = 0; i < size; i++) {
170 points[length + i] = matrixPoints[i];
171 }
172
173 points[length + size] = 0;
174 }
175 } else {
176 Coordinate3D* point = Coordinate3D_fromString(token);
177
178 if (point == 0) {
179 free(str0);
180 return 0;
181 }
182
183 if (points == 0) {
184 points = (Coordinate3D**) malloc(2 * sizeof(Coordinate3D));
185 points[0] = point;
186 points[1] = 0;
187 } else {
188 int length = 0;
189 while (points[length] != 0) length++;
190
191 points = (Coordinate3D**) realloc(points, (length + 2) * sizeof(Coordinate3D));
192
193 points[length] = point;
194 points[length + 1] = 0;
195 }
196 }
197
198 start = (*end) ? end + 1 : end;
199 }
200
201 return points;
202}
203
204typedef struct LevelZLine2D {
205 Block* block;
206 Coordinate2D** coordinates;
208
209LevelZLine2D* __read2DLine(const char* input) {
210 LevelZLine2D* line = (LevelZLine2D*) malloc(sizeof(LevelZLine2D));
211
212 char* str0 = (char*) malloc(strlen(input) + 1);
213 strcpy(str0, input);
214
215 char* blockStr = __trim(strtok(str0, ":"));
216 char* coordinateStr = __trim(strtok(0, ":"));
217
218 Block* block = Block_fromString(blockStr);
219 Coordinate2D** coordinates = __read2DPoints(coordinateStr);
220
221 line->block = block;
222 line->coordinates = coordinates;
223
224 free(str0);
225 return line;
226}
227
228typedef struct LevelZLine3D {
229 Block* block;
230 Coordinate3D** coordinates;
232
233LevelZLine3D* __read3DLine(const char* input) {
234 LevelZLine3D* line = (LevelZLine3D*) malloc(sizeof(LevelZLine3D));
235
236 char* str0 = (char*) malloc(strlen(input) + 1);
237 strcpy(str0, input);
238
239 char* blockStr = __trim(strtok(str0, ":"));
240 char* coordinateStr = __trim(strtok(0, ":"));
241
242 Block* block = Block_fromString(blockStr);
243 Coordinate3D** coordinates = __read3DPoints(coordinateStr);
244 line->block = block;
245 line->coordinates = coordinates;
246
247 free(str0);
248 return line;
249}
250
251// Implementation
252
258Level2D* readLevel2D(const char* str) {
259 Level2D* level = (Level2D*) malloc(sizeof(Level2D));
260
261 char* str0 = (char*) malloc(strlen(str) + 1);
262 strcpy(str0, str);
263
264 char* token = strtok(str0, "\n");
265 while (token != 0) {
266 if (strcmp(token, LEVELZ_HEADER_END) == 0) {
267 break;
268 }
269
270 LevelHeader* header = LevelHeader_fromString(__trim(token));
271 if (header->name == "type" && header->value != "2") {
272 free(str0);
273 return 0;
274 }
275
276 Level2D_addHeader(level, header->name, header->value);
277
278 if (header->name == "spawn") {
279 Coordinate2D* spawn = Coordinate2D_fromString(header->value);
280 level->spawn = spawn;
281 }
282
283 token = strtok(0, "\n");
284 }
285
286 token = strtok(0, "\n");
287 while (token != 0) {
288 if (strcmp(token, LEVELZ_END) == 0) {
289 break;
290 }
291
292 LevelZLine2D* line = __read2DLine(__trim(token));
293
294 for (int i = 0; i < sizeof(line->coordinates) / sizeof(Coordinate2D); i++) {
295 LevelObject2D* obj = createLevelObject2D(line->block, line->coordinates[i]);
296 Level2D_addBlock(level, obj);
297 }
298
299 token = strtok(0, "\n");
300 }
301
302 free(str0);
303 return level;
304}
305
311Level3D* readLevel3D(const char* str) {
312 Level3D* level = createLevel3D(createCoordinate3D(0, 0, 0));
313
314 char* str0 = (char*) malloc(strlen(str) + 1);
315 strcpy(str0, str);
316
317 char* token = strtok(str0, "\n");
318 while (token != 0) {
319 if (strcmp(token, LEVELZ_HEADER_END) == 0) {
320 break;
321 }
322
323 LevelHeader* header = LevelHeader_fromString(__trim(token));
324 if (header->name == "type" && header->value != "3") {
325 free(str0);
326 return 0;
327 }
328
329 Level3D_addHeader(level, header->name, header->value);
330
331 if (header->name == "spawn") {
332 Coordinate3D* spawn = Coordinate3D_fromString(header->value);
333 level->spawn = spawn;
334 }
335
336 token = strtok(0, "\n");
337 }
338
339 token = strtok(0, "\n");
340 while (token != 0) {
341 if (strcmp(token, LEVELZ_END) == 0) {
342 break;
343 }
344
345 LevelZLine3D* line = __read3DLine(__trim(token));
346
347 for (int i = 0; i < sizeof(line->coordinates) / sizeof(Coordinate3D); i++) {
348 LevelObject3D* obj = createLevelObject3D(line->block, line->coordinates[i]);
349 Level3D_addBlock(level, obj);
350 }
351
352 token = strtok(0, "\n");
353 }
354
355 free(str0);
356 return level;
357}
358
364Level2D* parseFile2D(const char* path) {
365 FILE* file = fopen(path, "r");
366 if (file == 0) return 0;
367
368 fseek(file, 0, SEEK_END);
369 long length = ftell(file);
370 fseek(file, 0, SEEK_SET);
371
372 char* buffer = (char*) malloc(length);
373 fread(buffer, 1, length, file);
374 fclose(file);
375
376 Level2D* level = readLevel2D(buffer);
377 free(buffer);
378
379 return level;
380}
381
387Level3D* parseFile3D(const char* path) {
388 FILE* file = fopen(path, "r");
389 if (file == 0) return 0;
390
391 fseek(file, 0, SEEK_END);
392 long length = ftell(file);
393 fseek(file, 0, SEEK_SET);
394
395 char* buffer = (char*) malloc(length);
396 fread(buffer, 1, length, file);
397 fclose(file);
398
399 Level3D* level = readLevel3D(buffer);
400 free(buffer);
401
402 return level;
403}
404
405#endif
Definition block.h:30
Definition coordinate.h:11
Definition coordinate.h:108
Definition matrix.h:13
Definition matrix.h:154
Definition level.h:74
Coordinate2D * spawn
Definition level.h:88
Definition level.h:353
Coordinate3D * spawn
Definition level.h:367
Definition level.h:15
char * name
Definition level.h:19
char * value
Definition level.h:24
Definition block.h:241
Definition block.h:300
Definition levelz.h:204
Definition levelz.h:228