diff --git a/CMakeLists.txt b/CMakeLists.txt index c76bc4a..5647d93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ set(RAYLIB_VERSION 5.5) find_package(raylib ${RAYLIB_VERSION} REQUIRED) set(SOURCES + kubo_command.c kubo_bar.c kubo_wall.c kubo_window.c diff --git a/kubo_bar.c b/kubo_bar.c index 0606e8b..9ea994b 100644 --- a/kubo_bar.c +++ b/kubo_bar.c @@ -18,19 +18,30 @@ #include "kubo_bar.h" -static inline int push_text(int x, int y, const char *text) { - DrawText(text, x, y + (KUBO_BAR_PADDING / 2), - KUBO_BAR_HEIGHT - KUBO_BAR_PADDING, WHITE); - return x + MeasureText(text, KUBO_BAR_HEIGHT); +static inline int push_text(int x, int y, const char *text, Color bg_color) { + + int font_size = KUBO_BAR_HEIGHT - KUBO_BAR_PADDING; + int text_width = MeasureText(text, font_size); + + DrawRectangle(x - KUBO_BAR_PADDING, y, text_width + (2 * KUBO_BAR_PADDING), + KUBO_BAR_HEIGHT, bg_color); + DrawText(text, x, y + (KUBO_BAR_PADDING / 2), font_size, WHITE); + return x + text_width; } void kubo_bar_render(struct kubo_context *context) { - const int bar_y = GetScreenHeight() - KUBO_BAR_HEIGHT; int bar_text_x = 10; - DrawRectangle(0, bar_y, GetScreenWidth(), KUBO_BAR_HEIGHT, - kubo_context_get_color(context->state)); + DrawRectangle(0, bar_y, GetScreenWidth(), KUBO_BAR_HEIGHT, BLACK); bar_text_x = - push_text(bar_text_x, bar_y, kubo_context_get_label(context->state)); + push_text(bar_text_x, bar_y, kubo_context_get_label(context->state), + kubo_context_get_color(context->state)); + + bar_text_x += 2 * KUBO_BAR_PADDING; + + if (context->state == KUBO_CONTEXT_COMMAND) { + kubo_command_render(context, bar_text_x, bar_y + (KUBO_BAR_PADDING / 2), + KUBO_BAR_HEIGHT - KUBO_BAR_PADDING); + } } diff --git a/kubo_bar.h b/kubo_bar.h index 1a29d7d..1eddab0 100644 --- a/kubo_bar.h +++ b/kubo_bar.h @@ -25,9 +25,10 @@ #include #include "kubo_context.h" +#include "kubo_command.h" void kubo_bar_render(struct kubo_context *context); -static inline int push_text(int x, int y, const char *text); +static inline int push_text(int x, int y, const char *text, Color bg_color); #endif diff --git a/kubo_command.c b/kubo_command.c new file mode 100644 index 0000000..385cb6a --- /dev/null +++ b/kubo_command.c @@ -0,0 +1,32 @@ +/* + * Copyright Luka Jankovic 2025 + * + * This file is part of Kubo. + * + * Kubo is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Kubo is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Kubo. If not, see . + */ + +#include "kubo_command.h" + +static char *kubo_char_arr_build_str(struct kubo_char_arr *arr) { + char *res = malloc(arr->count + 1); + for (int i = 0; i < arr->count; i++) { + res[i] = kubo_char_arr_get(arr, i); + } + res[arr->count] = '\0'; + return res; +} + +void kubo_command_render(struct kubo_context *context, int x, int y, int font_size) { + DrawText(kubo_char_arr_build_str(&context->command), x, y, font_size, WHITE); +} diff --git a/kubo_command.h b/kubo_command.h new file mode 100644 index 0000000..99a1362 --- /dev/null +++ b/kubo_command.h @@ -0,0 +1,29 @@ +/* + * Copyright Luka Jankovic 2025 + * + * This file is part of Kubo. + * + * Kubo is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Kubo is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Kubo. If not, see . + */ + +#ifndef KUBO_COMMAND_H +#define KUBO_COMMAND_H + +#include + +#include "kubo_context.h" + +void kubo_command_render(struct kubo_context *context, int x, int y, + int font_size); + +#endif diff --git a/kubo_context.c b/kubo_context.c index be01f9a..f79f17c 100644 --- a/kubo_context.c +++ b/kubo_context.c @@ -24,11 +24,14 @@ void kubo_context_init(struct kubo_context *context) { } kubo_wall_arr_init(&context->walls); + kubo_char_arr_init(&context->command); context->wall_select_index = 0; + context->exit_pending = false; } void kubo_context_cleanup(struct kubo_context *context) { kubo_wall_arr_free(&context->walls); + kubo_char_arr_free(&context->command); } void kubo_context_set_state(struct kubo_context *context, @@ -36,6 +39,10 @@ void kubo_context_set_state(struct kubo_context *context, context->state = state; switch (context->state) { + case KUBO_CONTEXT_COMMAND: + kubo_char_arr_add(&context->command, ':'); + break; + case KUBO_CONTEXT_WALL_NEW: break; diff --git a/kubo_context.h b/kubo_context.h index 3e77518..1214eda 100644 --- a/kubo_context.h +++ b/kubo_context.h @@ -27,21 +27,27 @@ #include "kubo_wall.h" KUBO_DYNARRAY_REGISTER(kubo_wall_arr, struct kubo_wall *); +KUBO_DYNARRAY_REGISTER(kubo_char_arr, char); enum kubo_context_state { + KUBO_CONTEXT_NORMAL, + KUBO_CONTEXT_COMMAND, KUBO_CONTEXT_WALL_NEW, KUBO_CONTEXT_WALL_SELECT, }; -static const char *kubo_context_labels[] = {"Wall New", "Wall Select"}; +static const char *kubo_context_labels[] = {"Normal", "Command", "Wall New", "Wall Select"}; -static const Color kubo_context_colors[] = {BLACK, BLUE}; +static const Color kubo_context_colors[] = {BLACK, RED, GREEN, BLUE}; struct kubo_context { bool exit_pending; struct kubo_wall_arr walls; enum kubo_context_state state; + // KUBO_CONTEXT_COMMAND + struct kubo_char_arr command; + // KUBO_CONTEXT_WALL_SELECT size_t wall_select_index; }; diff --git a/kubo_dynarray.h b/kubo_dynarray.h index 6fd597b..e51648d 100644 --- a/kubo_dynarray.h +++ b/kubo_dynarray.h @@ -63,6 +63,12 @@ static inline type name##_get(struct name *arr, size_t index) { \ assert(index < arr->count); \ return arr->data[index]; \ + } \ + \ + static inline void name##_set(struct name *arr, type new_val, \ + size_t index) { \ + assert(index < arr->count); \ + arr->data[index] = new_val; \ } #endif diff --git a/kubo_window.c b/kubo_window.c index 5f55ff0..b91e545 100644 --- a/kubo_window.c +++ b/kubo_window.c @@ -21,6 +21,7 @@ void kubo_window_init(struct kubo_context *context) { SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(KUBO_WINDOW_WIDTH, KUBO_WINDOW_HEIGHT, "Kubo"); + SetExitKey(0); } void kubo_window_cleanup(struct kubo_context *context) { CloseWindow(); } @@ -63,6 +64,8 @@ static void window_left_mouse(struct kubo_context *context) { break; case KUBO_CONTEXT_WALL_SELECT: break; + default: + break; } } @@ -73,20 +76,28 @@ static void window_right_mouse(struct kubo_context *context) { break; case KUBO_CONTEXT_WALL_SELECT: break; + default: + break; } } static void window_key_input(struct kubo_context *context) { + + window_char_input(context); + int key_code = GetKeyPressed(); - if (!key_code) { + if (key_code == KEY_ESCAPE) { + kubo_context_set_state(context, KUBO_CONTEXT_NORMAL); + } + + if (!key_code || context->state == KUBO_CONTEXT_COMMAND) { return; } switch (key_code) { case KEY_Q: - context->exit_pending = true; - break; + kubo_context_set_state(context, KUBO_CONTEXT_NORMAL); case KEY_W: kubo_context_set_state(context, KUBO_CONTEXT_WALL_NEW); @@ -115,6 +126,20 @@ static void window_key_input(struct kubo_context *context) { } } +static void window_char_input(struct kubo_context *context) { + + int char_code; + do { + char_code = GetCharPressed(); + + if (char_code && context->state == KUBO_CONTEXT_COMMAND) { + kubo_char_arr_add(&context->command, char_code); + } else if (char_code == ':') { + kubo_context_set_state(context, KUBO_CONTEXT_COMMAND); + } + } while (char_code > 0); +} + static void new_wall_click(struct kubo_context *context) { struct kubo_wall *current_wall = kubo_context_get_pending_wall(context); diff --git a/kubo_window.h b/kubo_window.h index 57c1d79..3e45973 100644 --- a/kubo_window.h +++ b/kubo_window.h @@ -39,6 +39,7 @@ static void window_render(struct kubo_context *context); static void window_left_mouse(struct kubo_context *context); static void window_right_mouse(struct kubo_context *context); static void window_key_input(struct kubo_context *context); +static void window_char_input(struct kubo_context *context); static void new_wall_click(struct kubo_context *context); static void new_wall_end(struct kubo_context *context);