]> git.lizzy.rs Git - nothing.git/blob - src/game/level_folder.c
(#1142) Top-left resize snapping
[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/lt_adapters.h"
7 #include "system/nth_alloc.h"
8 #include "system/line_stream.h"
9 #include "system/str.h"
10 #include "system/file.h"
11 #include "dynarray.h"
12 #include "game/level_metadata.h"
13
14 #include "./level_folder.h"
15
16 #define LEVEL_FOLDER_MAX_LENGTH 512
17
18 struct LevelFolder
19 {
20     Lt *lt;
21     Dynarray *filenames;
22     Dynarray *titles;
23 };
24
25 LevelFolder *create_level_folder(const char *dirpath)
26 {
27     trace_assert(dirpath);
28
29     Lt *lt = create_lt();
30
31     LevelFolder *level_folder = PUSH_LT(
32         lt,
33         nth_calloc(1, sizeof(LevelFolder)),
34         free);
35     if (level_folder == NULL) {
36         RETURN_LT(lt, NULL);
37     }
38     level_folder->lt = lt;
39
40     level_folder->filenames = PUSH_LT(
41         lt,
42         create_dynarray(sizeof(const char*)),
43         destroy_dynarray);
44     if (level_folder->filenames == NULL) {
45         RETURN_LT(lt, NULL);
46     }
47
48     level_folder->titles = PUSH_LT(
49         lt,
50         create_dynarray(sizeof(const char*)),
51         destroy_dynarray);
52     if (level_folder->titles == NULL) {
53         RETURN_LT(lt, NULL);
54     }
55
56     char path[LEVEL_FOLDER_MAX_LENGTH];
57     DIR *level_dir = PUSH_LT(lt, opendir(dirpath), closedir_lt);
58
59     for (struct dirent *d = readdir(level_dir);
60          d != NULL;
61          d = readdir(level_dir)) {
62         if (*d->d_name == '.') {
63             continue;
64         }
65
66         snprintf(path, LEVEL_FOLDER_MAX_LENGTH, "%s/%s", dirpath, d->d_name);
67         const char *filepath = PUSH_LT(lt, string_duplicate(trim_endline(path), NULL), free);
68         if (filepath == NULL) {
69             RETURN_LT(lt, NULL);
70         }
71
72         LevelMetadata *level_metadata = create_level_metadata_from_file(filepath);
73         if (level_metadata == NULL) {
74             RETURN_LT(lt, NULL);
75         }
76         const char *title = PUSH_LT(
77             lt,
78             string_duplicate(level_metadata_title(level_metadata), NULL),
79             free);
80         destroy_level_metadata(level_metadata);
81
82         dynarray_push(level_folder->titles, &title);
83         dynarray_push(level_folder->filenames, &filepath);
84     }
85
86     closedir(RELEASE_LT(lt, level_dir));
87
88     return level_folder;
89 }
90
91 void destroy_level_folder(LevelFolder *level_folder)
92 {
93     trace_assert(level_folder);
94     RETURN_LT0(level_folder->lt);
95 }
96
97 const char **level_folder_filenames(const LevelFolder *level_folder)
98 {
99     trace_assert(level_folder);
100     return dynarray_data(level_folder->filenames);
101 }
102
103 const char **level_folder_titles(const LevelFolder *level_folder)
104 {
105     trace_assert(level_folder);
106     return dynarray_data(level_folder->titles);
107 }
108
109 size_t level_folder_count(const LevelFolder *level_folder)
110 {
111     trace_assert(level_folder);
112     return dynarray_count(level_folder->filenames);
113 }