diff options
| -rw-r--r-- | build.zig | 1 | ||||
| -rw-r--r-- | src/main.c | 9 | ||||
| -rw-r--r-- | src/puzzles/parser.c | 55 | ||||
| -rw-r--r-- | src/scenes/collectionScene.c | 74 | ||||
| -rw-r--r-- | src/scenes/distractionScene.c | 2 | ||||
| -rw-r--r-- | src/scenes/puzzleScene.c | 5 | ||||
| -rw-r--r-- | src/scenes/resultView.c | 1 | ||||
| -rw-r--r-- | src/scenes/scenes.h | 2 | ||||
| -rw-r--r-- | src/ui_elements/UI.c | 30 | ||||
| -rw-r--r-- | src/ui_elements/UI.h | 14 |
10 files changed, 172 insertions, 21 deletions
@@ -36,6 +36,7 @@ pub fn build(b: *std.Build) void { "src/scenes/resultView.c", "src/scenes/puzzleScene.c", "src/scenes/distractionScene.c", + "src/scenes/collectionScene.c", "src/puzzles/puzzle.c", "src/puzzles/parser.c", "src/puzzles/distractions.c", @@ -22,10 +22,15 @@ int main(void) { return 1; } - if (!AddScene(CreatePuzzleScene(puzzle))) { - printf("Failed to create a puzzle menu\n"); + if (!AddScene(CreatePuzzleCollectionScene("puzzles"))) { + printf("Failed to create a collection scene\n"); return 1; } + + // if (!AddScene(CreatePuzzleScene(puzzle))) { + // printf("Failed to create a puzzle menu\n"); + // return 1; + // } SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(800, 600, "Programming game"); diff --git a/src/puzzles/parser.c b/src/puzzles/parser.c index 0f539b8..c88442b 100644 --- a/src/puzzles/parser.c +++ b/src/puzzles/parser.c @@ -61,7 +61,7 @@ typedef enum { TYPE_LIST = 4, } V1_IO_TYPE; -void ReadPuzzleIO_V1(FILE *file, PuzzleIO *io) { +bool ReadPuzzleIO_V1(FILE *file, PuzzleIO *io) { uint8_t type = read_u8(file); switch (type) { @@ -73,6 +73,7 @@ void ReadPuzzleIO_V1(FILE *file, PuzzleIO *io) { case TYPE_BOOL: { bool *outp = malloc(sizeof(bool)); + if (outp == NULL) return false; *outp = read_u8(file) != 0; io->type = WREN_TYPE_BOOL; io->value = outp; @@ -82,6 +83,7 @@ void ReadPuzzleIO_V1(FILE *file, PuzzleIO *io) { case TYPE_NUM: { double *outp = malloc(sizeof(double)); + if (outp == NULL) return false; *outp = read_double(file); io->type = WREN_TYPE_NUM; io->value = outp; @@ -93,28 +95,56 @@ void ReadPuzzleIO_V1(FILE *file, PuzzleIO *io) { io->value = read_string(file); break; - case TYPE_LIST: - TraceLog(LOG_ERROR, "The arrays are not yet supported"); - io->type = WREN_TYPE_NULL; - io->value = NULL; - break; + case TYPE_LIST: + { + PuzzleListIO *outp = malloc(sizeof(PuzzleListIO)); + if (outp == NULL) return false; + + outp->length = read_u32(file); + outp->elements = malloc(sizeof(PuzzleIO) * outp->length); + if (outp->elements == NULL) { + free(outp); + return false; + } + + for (size_t i = 0; i < outp->length; i++) { + if (!ReadPuzzleIO_V1(file, &outp->elements[i])) { + free(outp); + return false; + } + } + + io->type = WREN_TYPE_LIST; + io->value = outp; + break; + } default: - return; + return true; } + return true; } -void readTestV1(FILE *file, Test *outp) { +bool readTestV1(FILE *file, Test *outp) { outp->RecieverName = read_string(file); outp->MainMethodSignature = read_string(file); outp->argc = read_u32(file); outp->argv = malloc(sizeof(PuzzleIO) * outp->argc); + if (outp->argv == NULL) return false; for (size_t i = 0; i < outp->argc; i++) { - ReadPuzzleIO_V1(file, &outp->argv[i]); + if (!ReadPuzzleIO_V1(file, &outp->argv[i])) { + free(outp->argv); + return false; + } + } + + if (!ReadPuzzleIO_V1(file, &outp->ExpectedResult)) { + free(outp->argv); + return false; } - ReadPuzzleIO_V1(file, &outp->ExpectedResult); + return true; } // Reads file with the specification from puzzle_specs_v1.md. @@ -130,7 +160,10 @@ Puzzle *parseFileV1(FILE *file) { outp->Tests = malloc(sizeof(Test) * outp->TestC); for (size_t i = 0; i < outp->TestC; i++) { - readTestV1(file, &outp->Tests[i]); + if (!readTestV1(file, &outp->Tests[i])) { + FreePuzzle(outp); + return NULL; + } } return outp; diff --git a/src/scenes/collectionScene.c b/src/scenes/collectionScene.c new file mode 100644 index 0000000..2173619 --- /dev/null +++ b/src/scenes/collectionScene.c @@ -0,0 +1,74 @@ +#include "scenes.h" +#include <raylib.h> +#include <string.h> +#include "../ui_elements/UI.h" +#include "../resources/resources.h" + +typedef struct { + char *DirPath; + char *Name; +} CollectionSceneData; + +CollectionSceneData *getData(void *self) { + return ((Scene *)self)->data; +} + +void DrawCollectionName(char *name) { + Vector2 width = MeasureTextEx(*GetMainFont(), name, 50, 1); + int screen_width = GetScreenWidth(); + Vector2 pos = { .y = 20, .x = (screen_width - width.x) / 2, }; + DrawTextEx(*GetMainFont(), name, pos, HEADER_FONT_SIZE, 1, COLORSCHEME_BROWN); +} + +// Does not allocate the memory +char *getCollectionName(char *path) { + char *outp = path; + size_t len = strlen(path); + for (size_t i = 0; i < len; ++i) { + if ((path[i] == '/' || path[i] == '\\') && path[i+1] != 0x0) { + outp = path + i + 1; + } + } + return outp; +} + +bool updateCollectionScene(void *self) { + return true; +} + +bool drawCollectionScene(void *self) { + CollectionSceneData *data = getData(self); + DrawBackground(); + DrawCollectionName(data->Name); + DrawPageView(GetScreenHeight() - 60, 5, 2); + return true; +} + +void deinitCollectionScene(void *self) { + TraceLog(LOG_INFO, "Deleting a collection scene"); + CollectionSceneData *data = getData(self); + if (data != NULL) free(data); + free((Scene *)self); +} + +Scene *CreatePuzzleCollectionScene(char *path) { + TraceLog(LOG_INFO, "Creating a collection scene"); + Scene *outp = malloc(sizeof(Scene)); + if (outp == NULL) return NULL; + outp->Update = updateCollectionScene; + outp->Draw = drawCollectionScene; + outp->Deint = deinitCollectionScene; + outp->IsTransparent = false; + + CollectionSceneData *data = malloc(sizeof(CollectionSceneData)); + if (data == NULL) { + free(outp); + return NULL; + } + data->DirPath = strdup(path); + data->Name = getCollectionName(path); + + outp->data = data; + + return outp; +} diff --git a/src/scenes/distractionScene.c b/src/scenes/distractionScene.c index 1f12aae..f249b53 100644 --- a/src/scenes/distractionScene.c +++ b/src/scenes/distractionScene.c @@ -5,8 +5,6 @@ #include "../resources/resources.h" static const float BODY_PADDING = 0.05f; -static const int BORDER = 2; -static const int EDITOR_PADDING = 3; typedef struct { DistractionPuzzle *puzzle; diff --git a/src/scenes/puzzleScene.c b/src/scenes/puzzleScene.c index c3e48c1..1671cf8 100644 --- a/src/scenes/puzzleScene.c +++ b/src/scenes/puzzleScene.c @@ -17,11 +17,6 @@ typedef struct { float time_acc; } puzzleSceneData; -const int HEADER_FONT_SIZE = 50; -const int EDITOR_PADDING = 3; -const int BORDER = 2; -const int FOOTER_HEIGHT = 30; - // Time in seconds const size_t BASE_TIME_LEFT = 1; // 5 * 60; diff --git a/src/scenes/resultView.c b/src/scenes/resultView.c index 1cbc182..e51898e 100644 --- a/src/scenes/resultView.c +++ b/src/scenes/resultView.c @@ -7,7 +7,6 @@ #include "../ui_elements/UI.h" #include "../resources/resources.h" -static const int BORDER = 2; static const int SCROLL_SPEED = 10; static const uint8_t MAX_TINT = 96; diff --git a/src/scenes/scenes.h b/src/scenes/scenes.h index 335a139..828f2f3 100644 --- a/src/scenes/scenes.h +++ b/src/scenes/scenes.h @@ -33,4 +33,6 @@ Scene *CreatePuzzleScene(Puzzle *puzzle); Scene *CreateDistractionScene(DistractionPuzzle *puzzle, void (*addTime)(Scene *, size_t)); Scene *CreateResultView(SubmitionResult *result); +Scene *CreatePuzzleCollectionScene(char *path); + #endif // SCENES_H diff --git a/src/ui_elements/UI.c b/src/ui_elements/UI.c index e3a0048..9daed74 100644 --- a/src/ui_elements/UI.c +++ b/src/ui_elements/UI.c @@ -1,5 +1,6 @@ #include "UI.h" #include <raylib.h> +#include "../resources/resources.h" const int MAX_LINES = 8192; const int SPACING_H = 1; @@ -106,3 +107,32 @@ void GetPanesSplit(Rectangle *pane1, Rectangle *pane2, Rectangle body, float pro pane2->width = (body.width - PADDING) * (1 - proportion_h); } +void DrawPageView(int y, unsigned int pages, unsigned int current_page) { + if (pages == 0) return; + float width = 2 * PAGE_DOTS_PADDING + + PAGE_DOTS_RADIUS * 2 * pages + + PAGE_DOTS_SPACING * (pages - 1); + + Rectangle rec = { + .x = (GetScreenWidth() - width) / 2, // TODO + .y = y, + .height = PAGE_DOTS_RADIUS * 2 + 2 * PAGE_DOTS_PADDING, + .width = width, + }; + + Color color = { + .r = COLORSCHEME_WHITE.r, + .g = COLORSCHEME_WHITE.g, + .b = COLORSCHEME_WHITE.b, + .a = COLORSCHEME_WHITE.a & PAGE_DOTS_TRANSPARENCY }; + + DrawRectangleRounded(rec, 0.15f, 8, color); + + int x_pos = (int)rec.x + PAGE_DOTS_PADDING + PAGE_DOTS_RADIUS; + int y_pos = (int)rec.y + PAGE_DOTS_PADDING + PAGE_DOTS_RADIUS; + for (int i = 0; i < pages; ++i) { + Color color = i == current_page ? COLORSCHEME_ORANGE : COLORSCHEME_BROWN; + DrawCircle(x_pos, y_pos, PAGE_DOTS_RADIUS, color); + x_pos += PAGE_DOTS_SPACING + PAGE_DOTS_RADIUS * 2; + } +} diff --git a/src/ui_elements/UI.h b/src/ui_elements/UI.h index d3af014..8754329 100644 --- a/src/ui_elements/UI.h +++ b/src/ui_elements/UI.h @@ -9,6 +9,11 @@ static const float SCROLL_SENC = 10; static const float TAB_WIDTH = 4; static const int PADDING = 10; +static const int HEADER_FONT_SIZE = 50; +static const int EDITOR_PADDING = 3; +static const int BORDER = 2; +static const int FOOTER_HEIGHT = 30; + // Sure about this value static const int MIN_FONT_SIZE = 10; // Unsure about this value @@ -32,6 +37,15 @@ typedef struct { void UpdateButton(Button *btn); void DrawButton(Button *btn, Rectangle *location); +// ========== PAGE VIEW ========== + +static const int PAGE_DOTS_SPACING = 15; +static const int PAGE_DOTS_PADDING = 15; +static const int PAGE_DOTS_RADIUS = 3; +static const char PAGE_DOTS_TRANSPARENCY = (char)192; + +void DrawPageView(int y, unsigned int pages, unsigned int current_page); + // ========== TEXT EDITOR ========== static const size_t DEFAULT_TEXT_NODE_SIZE = 256; |
