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