summaryrefslogtreecommitdiff
path: root/src/scenes
diff options
context:
space:
mode:
Diffstat (limited to 'src/scenes')
-rw-r--r--src/scenes/collectionScene.c16
-rw-r--r--src/scenes/puzzlePreviewScene.c193
-rw-r--r--src/scenes/puzzleScene.c19
-rw-r--r--src/scenes/puzzleSelectionScene.c29
-rw-r--r--src/scenes/resultView.c3
-rw-r--r--src/scenes/scenes.h11
6 files changed, 261 insertions, 10 deletions
diff --git a/src/scenes/collectionScene.c b/src/scenes/collectionScene.c
index 508e4d5..cda6fd1 100644
--- a/src/scenes/collectionScene.c
+++ b/src/scenes/collectionScene.c
@@ -8,6 +8,7 @@
#include "../ui_elements/UI.h"
#include "../resources/resources.h"
#include "../utils/arena.h"
+#include "../resources/TextruesAtlas.h"
static const size_t ARENA_SIZE = 1024 * 64;
@@ -29,8 +30,12 @@ void collectionElement_onSelect(CollectionElement *caller) {
if (caller == NULL) return;
TraceLog(LOG_INFO, "Selected element %s", caller->name);
switch (caller->type) {
- case COLLECTION_ELEMENT_PUZZLE: break;
- case COLLECTION_ELEMENT_COLLECTION: AddScene(CreatePuzzleCollectionScene(caller)); break;
+ case COLLECTION_ELEMENT_PUZZLE:
+ AddScene(CreatePuzzlePreview(ReadPuzzleFromFile(caller->path)));
+ break;
+ case COLLECTION_ELEMENT_COLLECTION:
+ AddScene(CreatePuzzleCollectionScene(caller));
+ break;
default:
TraceLog(LOG_WARNING, "Invalid CollectionElement type for %s", caller->path);
break;
@@ -125,12 +130,7 @@ Scene *CreatePuzzleCollectionScene(CollectionElement *el) {
backButton->parent = outp;
backButton->OnClick = backButton_onClick;
backButton->atlas = GetButtonsAtlas();
- backButton->textrueLocation = (Rectangle) {
- .x = 0,
- .y = 0,
- .width = 32,
- .height = 32,
- };
+ backButton->textrueLocation = BACK_BUTTON_SMALL_LOCATION;
}
data->backButton = backButton;
diff --git a/src/scenes/puzzlePreviewScene.c b/src/scenes/puzzlePreviewScene.c
new file mode 100644
index 0000000..6ce3ba7
--- /dev/null
+++ b/src/scenes/puzzlePreviewScene.c
@@ -0,0 +1,193 @@
+#include <raylib.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "scenes.h"
+#include "../ui_elements/UI.h"
+#include "../resources/resources.h"
+#include "../resources/TextruesAtlas.h"
+
+static const uint8_t MAX_TINT = 96;
+static const float BODY_BUTTON_RATIO = 0.9f;
+static const float BUTTON_PADDING_RATIO = 0.015f;
+
+typedef struct {
+ Puzzle *puzzle;
+ Button *backButton;
+ Button *proceedButton;
+ float scroll_up;
+ float hiding_state;
+ int scroll;
+ PopUpState state;
+} puzzlePreviewData;
+
+void confirmSelemetion(Scene *self) {
+ if (self == NULL) return;
+ puzzlePreviewData *data = ((Scene *)self)->data;
+ if (data == NULL) return;
+ TraceLog(LOG_INFO, "Loading a puzzle %s", data->puzzle->Name);
+ data->state = POPUP_HIDING;
+}
+
+
+void closePreviewWindow(Scene *self) {
+ TraceLog(LOG_INFO, "Closing a preview window");
+ if (self == NULL) return;
+ puzzlePreviewData *data = ((Scene *)self)->data;
+ if (data == NULL) return;
+ data->state = POPUP_HIDING_ALT;
+}
+
+bool updatePuzzlePreview(void *self) {
+ puzzlePreviewData *data = ((Scene *)self)->data;
+ switch (data->state) {
+ case POPUP_REVEALING:
+ data->scroll_up += SCROLL_SPEED * GetFrameTime();
+ if (data->scroll_up >= 1) {
+ data->state = POPUP_ACTIVE;
+ data->scroll_up = 1;
+ }
+ return true;
+
+ case POPUP_HIDING_ALT:
+ data->scroll_up -= SCROLL_SPEED * GetFrameTime();
+ if (data->scroll_up <= 0) {
+ if (data->puzzle != NULL) FreePuzzle(data->puzzle);
+ DeleteSceneFromStack();
+ }
+ return true;
+
+ case POPUP_HIDING:
+ data->hiding_state += BLACKOUT_SPEED * GetFrameTime();
+ if (data->hiding_state >= 2) {
+ DeleteSceneFromStack();
+ AddScene(CreatePuzzleScene(data->puzzle));
+ }
+ return true;
+
+ default: break;
+ }
+ if (data->backButton != NULL) UpdateButton(data->backButton);
+ if (data->proceedButton != NULL) UpdateButton(data->proceedButton);
+ return true;
+}
+
+static Rectangle getBodyRect(puzzlePreviewData *data) {
+ float screen_h = GetScreenHeight();
+ float screen_w = GetScreenWidth();
+ return (Rectangle) {
+ .x = PADDING,
+ .y = PADDING + (screen_h * (1 - data->scroll_up)),
+ .width = screen_w - PADDING * 2,
+ .height = screen_h - PADDING * 2,
+ };
+}
+
+bool drawPuzzlePreview(void *self) {
+ puzzlePreviewData *data = ((Scene *)self)->data;
+ DrawRectangle(0, 0,
+ GetScreenWidth(), GetScreenHeight(),
+ (Color) {0, 0, 0, MAX_TINT * data->scroll_up });
+
+ Rectangle body = getBodyRect(data);
+ Rectangle TextArea = {
+ .x = body.x,
+ .y = body.y,
+ .width = body.width,
+ .height = body.height * BODY_BUTTON_RATIO,
+ };
+
+ DrawRecBordered(TextArea, COLORSCHEME_WHITE, COLORSCHEME_ORANGE, BORDER);
+ if (data->puzzle != NULL) {
+ DrawTextInRec(TextArea, data->puzzle->Description,
+ GetMainFont(), TEXT_FONT_SIZE, COLORSCHEME_BROWN,
+ 3, &data->scroll);
+ }
+
+ float btn_space_height = body.height * (1 - BODY_BUTTON_RATIO);
+ float btn_padding = body.height * BUTTON_PADDING_RATIO;
+ float btn_height = btn_space_height - 2 * btn_padding;
+ float btn_width = btn_height * 2;
+
+ if (data->backButton != NULL) {
+ DrawButton(data->backButton, &(Rectangle) {
+ .x = PADDING,
+ .y = TextArea.y + TextArea.height + btn_padding,
+ .height = btn_height,
+ .width = btn_height * 2,
+ });
+ }
+
+ if (data->proceedButton != NULL) {
+ DrawButton(data->proceedButton, &(Rectangle) {
+ .x = body.x + body.width - btn_width,
+ .y = TextArea.y + TextArea.height + btn_padding,
+ .height = btn_height,
+ .width = btn_height * 2,
+ });
+ }
+
+ if (data->state == POPUP_HIDING) {
+ DrawRectangle(0, 0,
+ GetScreenWidth(), GetScreenHeight(),
+ (Color) {0, 0, 0, 255 * (data->hiding_state >= 1 ? 1 : data->hiding_state) });
+ }
+
+ return true;
+}
+
+/// DOES NOT FREE THE PUZZLE! This should be handled separatly
+void deinitPuzzlePreview(void *self) {
+ TraceLog(LOG_INFO, "Deleting a puzzle preview");
+ if (self == NULL) return;
+ puzzlePreviewData *data = ((Scene *)self)->data;
+ if (data != NULL) {
+ if (data->backButton != NULL) free(data->backButton);
+ if (data->proceedButton != NULL) free(data->proceedButton);
+ }
+ free(self);
+ TraceLog(LOG_INFO, "Deleting a puzzle preview - success");
+}
+
+Scene *CreatePuzzlePreview(Puzzle *puzzle) {
+ if (puzzle == NULL) return NULL;
+ TraceLog(LOG_INFO, "Creating a puzzle preview for a puzzle %s",
+ puzzle->Name);
+ Scene *outp = malloc(sizeof(Scene));
+ outp->Update = updatePuzzlePreview;
+ outp->Draw = drawPuzzlePreview;
+ outp->Deint = deinitPuzzlePreview;
+ outp->IsTransparent = true;
+
+ puzzlePreviewData *data = malloc(sizeof(puzzlePreviewData));
+ if (data == NULL) {
+ free(outp);
+ return NULL;
+ }
+
+ data->puzzle = puzzle;
+ data->state = POPUP_REVEALING;
+ data->scroll_up = 0;
+ data->scroll = 0;
+
+ Button *backButton = malloc(sizeof(Button));
+ if (backButton != NULL) {
+ backButton->parent = outp;
+ backButton->OnClick = closePreviewWindow;
+ backButton->atlas = GetButtonsAtlas();
+ backButton->textrueLocation = BACK_BUTTON_WIDE_LOCATION;
+ }
+ data->backButton = backButton;
+
+ Button *proceedButton = malloc(sizeof(Button));
+ if (proceedButton != NULL) {
+ proceedButton->parent = outp;
+ proceedButton->OnClick = confirmSelemetion;
+ proceedButton->atlas = GetButtonsAtlas();
+ proceedButton->textrueLocation = PROCEED_BUTTON_WIDE_LOCATION;
+ }
+ data->proceedButton = proceedButton;
+
+ outp->data = data;
+
+ return outp;
+}
diff --git a/src/scenes/puzzleScene.c b/src/scenes/puzzleScene.c
index 1671cf8..7f06672 100644
--- a/src/scenes/puzzleScene.c
+++ b/src/scenes/puzzleScene.c
@@ -15,6 +15,8 @@ typedef struct {
size_t distraction_timer;
// Miliseconds elapsed
float time_acc;
+ float blackout_state;
+ PopUpState state;
} puzzleSceneData;
// Time in seconds
@@ -97,6 +99,12 @@ bool drawPuzzleScene(void *self) {
};
DrawControls(self, controls_rect);
+ if (data->state == POPUP_REVEALING) {
+ DrawRectangle(0, 0,
+ GetScreenWidth(), GetScreenHeight(),
+ (Color) {0, 0, 0, 255 * (data->blackout_state >= 1 ? 1 : data->blackout_state) });
+ }
+
return true;
}
@@ -120,6 +128,14 @@ void createDistraction() {
bool updatePuzzleScene(void *self) {
puzzleSceneData *data = ((Scene *)self)->data;
+ if (data->state == POPUP_REVEALING) {
+ data->blackout_state -= BLACKOUT_SPEED * GetFrameTime();
+ if (data->blackout_state <= 0) {
+ data->blackout_state = 0;
+ data->state = POPUP_ACTIVE;
+ }
+ return true;
+ }
Rectangle body = GetBodyRect();
Rectangle pane1, pane2;
@@ -192,6 +208,9 @@ Scene *CreatePuzzleScene(Puzzle *puzzle) {
data->distraction_timer = BASE_TIME_LEFT;
data->time_acc = 0;
+ data->state = POPUP_REVEALING;
+ data->blackout_state = 1;
+
if (puzzle->InitialCode != NULL) {
data->EditorInfo = CreateTextAreaFromText(EditorDisplayParams, puzzle->InitialCode);
} else {
diff --git a/src/scenes/puzzleSelectionScene.c b/src/scenes/puzzleSelectionScene.c
new file mode 100644
index 0000000..8529e35
--- /dev/null
+++ b/src/scenes/puzzleSelectionScene.c
@@ -0,0 +1,29 @@
+#include <raylib.h>
+#include <stdlib.h>
+#include "scenes.h"
+#include "../resources/resources.h"
+
+bool updateMainMenu(void *self) {
+ return true;
+}
+
+bool drawMainMenu(void *self) {
+ DrawBackground();
+ DrawText("Main menu", 0, 0, 100, BLACK);
+ return true;
+}
+
+void deinitMainMenu(void *self) {
+ TraceLog(LOG_INFO, "Deleting a main menu");
+ free((Scene *)self);
+}
+
+Scene *CreateMainMenu() {
+ TraceLog(LOG_INFO, "Creating a main menu");
+ Scene *outp = malloc(sizeof(Scene));
+ outp->Update = updateMainMenu;
+ outp->Draw = drawMainMenu;
+ outp->Deint = deinitMainMenu;
+ outp->IsTransparent = false;
+ return outp;
+}
diff --git a/src/scenes/resultView.c b/src/scenes/resultView.c
index e51898e..0017d5a 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 SCROLL_SPEED = 10;
static const uint8_t MAX_TINT = 96;
typedef struct {
@@ -62,7 +61,7 @@ bool drawResultView(void *self) {
DrawRecBordered(body, WHITE, data->value->result == RESULT_OK ? COLORSCHEME_GREEN : COLORSCHEME_ORANGE, BORDER);
DrawTextInRec(body, data->value->stdout_sb,
- GetMainFont(), 20, COLORSCHEME_BROWN, 3, &data->scroll);
+ GetMainFont(), TEXT_FONT_SIZE, COLORSCHEME_BROWN, 3, &data->scroll);
return true;
}
diff --git a/src/scenes/scenes.h b/src/scenes/scenes.h
index f71c2ee..d705feb 100644
--- a/src/scenes/scenes.h
+++ b/src/scenes/scenes.h
@@ -6,6 +6,16 @@
#define SCENE_STACK_SIZE 16
+typedef enum {
+ POPUP_REVEALING,
+ POPUP_REVEALING_ALT,
+ POPUP_ACTIVE,
+ POPUP_HIDING,
+ POPUP_HIDING_ALT,
+} PopUpState;
+static const int SCROLL_SPEED = 8;
+static const int BLACKOUT_SPEED = 3;
+
/// This structure represents a scene that is stored in a stack.
/// The main appeal of this data type is dynamic creation of different
/// scenes that don't depend on global state
@@ -34,5 +44,6 @@ Scene *CreateDistractionScene(DistractionPuzzle *puzzle, void (*addTime)(Scene *
Scene *CreateResultView(SubmitionResult *result);
Scene *CreatePuzzleCollectionScene(CollectionElement *el);
+Scene *CreatePuzzlePreview(Puzzle *puzzle);
#endif // SCENES_H