From 1e7ec08dc9c62df43940d00c1fae4a6e54464b86 Mon Sep 17 00:00:00 2001 From: physick Date: Sun, 30 Aug 2026 16:14:59 +0500 Subject: puzzle collection rewrite --- src/puzzles/collection.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++ src/puzzles/puzzle.h | 18 +++++++ 2 files changed, 144 insertions(+) create mode 100644 src/puzzles/collection.c (limited to 'src/puzzles') diff --git a/src/puzzles/collection.c b/src/puzzles/collection.c new file mode 100644 index 0000000..bb95eba --- /dev/null +++ b/src/puzzles/collection.c @@ -0,0 +1,126 @@ +#include +#include "puzzle.h" +#include +#include +#include +#include +#include "../utils/arena.h" +#include + +static const char *IMAGE_NAME = "icon.png"; + +CollectionElementType getTypeFromPath(char *fullPath) { + struct stat st; + if (stat(fullPath, &st) != 0) return COLLECTION_ELEMENT_UNKNOWN; + + if (S_ISDIR(st.st_mode)) { + return COLLECTION_ELEMENT_COLLECTION; + } else if (S_ISREG(st.st_mode)) { + return COLLECTION_ELEMENT_PUZZLE; + } + return COLLECTION_ELEMENT_UNKNOWN; +} + +bool isIcon(struct dirent *entry) { + return strncmp(entry->d_name, IMAGE_NAME, strlen(IMAGE_NAME)) == 0; +} + +void addIcon(CollectionElement *el, struct dirent *entry) { + if (el == NULL || entry == NULL) return; + char fullPath[1024]; +} + +bool isElement(struct dirent *entry, char *basePath) { + if (entry == NULL) return false; + if (strncmp(".", entry->d_name, 1) == 0) return false; + if (isIcon(entry)) return false; + + char full_path_buf[1024]; + snprintf(full_path_buf, sizeof(full_path_buf), "%s/%s", basePath, entry->d_name); + struct stat st; + if (stat(full_path_buf, &st) != 0) return false; + if (S_ISDIR(st.st_mode)) return true; + + size_t entry_name_len = strlen(entry->d_name); + if (entry_name_len < 4) return false; + char *last_bytes = entry->d_name + entry_name_len - 3; + if (strncmp(last_bytes, ".pz", 3) != 0) return false; + + return true; +} + +size_t getElementCount(DIR *dir, CollectionElement *el) { + struct dirent *entry; + size_t outp = 0; + while ((entry = readdir(dir)) != NULL) { + if (isElement(entry, el->path)) outp += 1; + } + rewinddir(dir); + return outp; +} + +void initCollectionFromDir(CollectionElement *el) { + if (el == NULL) return; + + TraceLog(LOG_INFO, "Initializing a collection element from %s/", el->path); + DIR *dir = opendir(el->path); + if (dir == NULL) { + TraceLog(LOG_ERROR, "Failed to open the directory"); + return; + } + + el->childCount = getElementCount(dir, el); + el->children = malloc(sizeof(CollectionElement) * el->childCount); + // printf("element count: %zu\n", el->childCount); + if (el->children == NULL) { + TraceLog(LOG_ERROR, "Failed to allocate the collection element children array"); + closedir(dir); + return; + } + + struct dirent *entry; + char full_path_buf[1024]; + size_t idx = 0; + + while ((entry = readdir(dir)) != NULL) { + if (isIcon(entry)) { + addIcon(el, entry); + continue; + } + if (!isElement(entry, el->path)) continue; + snprintf(full_path_buf, sizeof(full_path_buf), "%s/%s", el->path, entry->d_name); + + struct stat st; + if (stat(full_path_buf, &st) != 0) continue; + + CollectionElement *read_el = &el->children[idx]; + // printf("idx = %zu\n", idx); + if (S_ISDIR(st.st_mode)) { + read_el->type = COLLECTION_ELEMENT_COLLECTION; + } else if (S_ISREG(st.st_mode)) { + read_el->type = COLLECTION_ELEMENT_PUZZLE; + } + read_el->IsInitialized = false; + read_el->path = strdup(full_path_buf); + + idx += 1; + } + + closedir(dir); +} + +void InitializeCollection(CollectionElement *el) { + if (el == NULL) { + TraceLog(LOG_ERROR, "Failed to initialize collection element: the element is NULL"); + return; + } + switch (el->type) { + case COLLECTION_ELEMENT_PUZZLE: break; + case COLLECTION_ELEMENT_COLLECTION: + initCollectionFromDir(el); + break; + default: + TraceLog(LOG_WARNING, "Invalid CollectionElement type"); + break; + } +} diff --git a/src/puzzles/puzzle.h b/src/puzzles/puzzle.h index e8180e1..90ee160 100644 --- a/src/puzzles/puzzle.h +++ b/src/puzzles/puzzle.h @@ -1,5 +1,6 @@ #include #include +#include #ifndef PUZZLE_H #define PUZZLE_H @@ -92,4 +93,21 @@ typedef struct { DistractionPuzzle *GetRandomDistraction(); void FreeDistrationPuzzle(DistractionPuzzle *puzzle); +typedef enum { + COLLECTION_ELEMENT_PUZZLE, + COLLECTION_ELEMENT_COLLECTION, + COLLECTION_ELEMENT_UNKNOWN +} CollectionElementType; + +typedef struct CollectionElement { + char *path; + struct CollectionElement *children; + size_t childCount; + Texture2D *icon; + bool IsInitialized; + CollectionElementType type; +} CollectionElement; + +void InitializeCollection(CollectionElement *el); + #endif // PUZZLE_H -- cgit v1.3