]> git.lizzy.rs Git - nothing.git/blob - src/game/level_folder.c
(#842) edit_field positioning, Esc button support
[nothing.git] / src / game / level_folder.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include "system/stacktrace.h"
5 #include "system/lt.h"
6 #include "system/nth_alloc.h"
7 #include "system/line_stream.h"
8 #include "system/str.h"
9 #include "dynarray.h"
10 #include "game/level_metadata.h"
11
12 #include "./level_folder.h"
13
14 #define LEVEL_FOLDER_MAX_LENGTH 512
15
16 struct LevelFolder
17 {
18     Lt *lt;
19     Dynarray *filenames;
20     Dynarray *titles;
21 };
22
23 LevelFolder *create_level_folder(const char *dirpath)
24 {
25     trace_assert(dirpath);
26
27     Lt *lt = create_lt();
28
29     LevelFolder *level_folder = PUSH_LT(
30         lt,
31         nth_calloc(1, sizeof(LevelFolder)),
32         free);
33     if (level_folder == NULL) {
34         RETURN_LT(lt, NULL);
35     }
36     level_folder->lt = lt;
37
38     level_folder->filenames = PUSH_LT(
39         lt,
40         create_dynarray(sizeof(const char*)),
41         destroy_dynarray);
42     if (level_folder->filenames == NULL) {
43         RETURN_LT(lt, NULL);
44     }
45
46     level_folder->titles = PUSH_LT(
47         lt,
48         create_dynarray(sizeof(const char*)),
49         destroy_dynarray);
50     if (level_folder->titles == NULL) {
51         RETURN_LT(lt, NULL);
52     }
53
54     char path[LEVEL_FOLDER_MAX_LENGTH];
55     snprintf(path, LEVEL_FOLDER_MAX_LENGTH, "%s/meta.txt", dirpath);
56
57     LineStream *meta = PUSH_LT(
58         lt,
59         create_line_stream(
60             path,
61             "r",
62             LEVEL_FOLDER_MAX_LENGTH),
63         destroy_line_stream);
64     if (meta == NULL) {
65         RETURN_LT(lt, NULL);
66     }
67
68     const char *line = line_stream_next(meta);
69     while (line) {
70         snprintf(path, LEVEL_FOLDER_MAX_LENGTH, "%s/%s", dirpath, line);
71         line = PUSH_LT(lt, string_duplicate(trim_endline(path), NULL), free);
72         if (line == NULL) {
73             RETURN_LT(lt, NULL);
74         }
75
76         LevelMetadata *level_metadata = create_level_metadata_from_file(line);
77         if (level_metadata == NULL) {
78             RETURN_LT(lt, NULL);
79         }
80         const char *title = PUSH_LT(
81             lt,
82             string_duplicate(level_metadata_title(level_metadata), NULL),
83             free);
84         destroy_level_metadata(level_metadata);
85
86         dynarray_push(level_folder->titles, &title);
87         dynarray_push(level_folder->filenames, &line);
88
89         line = line_stream_next(meta);
90     }
91
92     destroy_line_stream(RELEASE_LT(lt, meta));
93
94     return level_folder;
95 }
96
97 void destroy_level_folder(LevelFolder *level_folder)
98 {
99     trace_assert(level_folder);
100     RETURN_LT0(level_folder->lt);
101 }
102
103 const char **level_folder_filenames(const LevelFolder *level_folder)
104 {
105     trace_assert(level_folder);
106     return dynarray_data(level_folder->filenames);
107 }
108
109 const char **level_folder_titles(const LevelFolder *level_folder)
110 {
111     trace_assert(level_folder);
112     return dynarray_data(level_folder->titles);
113 }
114
115 size_t level_folder_count(const LevelFolder *level_folder)
116 {
117     trace_assert(level_folder);
118     return dynarray_count(level_folder->filenames);
119 }