diff --git a/game/Makefile b/game/Makefile index cbbc429..6d4e986 100644 --- a/game/Makefile +++ b/game/Makefile @@ -7,8 +7,8 @@ DEP := $(OBJ:.o=.d) CC := gcc LD := gcc -CFLAGS := -g -Werror -Wextra -Wall -MMD -MP `pkg-config --cflags sdl3 sdl3-image cglm gl glib-2.0` -LDFLAGS := -g -lm `pkg-config --libs sdl3 sdl3-image cglm gl glib-2.0` +CFLAGS := -g -Werror -Wextra -Wall -MMD -MP `pkg-config --cflags sdl3 sdl3-image cglm gl glib-2.0 guile-3.0` +LDFLAGS := -g -lm `pkg-config --libs sdl3 sdl3-image cglm gl glib-2.0 guile-3.0` TARGET := wschod .PHONY: all clean diff --git a/game/res/shaders/uiwidget.frag b/game/res/shaders/uiwidget.frag index 30710d3..124bb25 100644 --- a/game/res/shaders/uiwidget.frag +++ b/game/res/shaders/uiwidget.frag @@ -85,7 +85,7 @@ void main () if (in_progress) { - gl_FragColor = vec4 (1.0, 1.0, 1.0, 1.0); + gl_FragColor = progress_color; return; } } diff --git a/game/shell.nix b/game/shell.nix index 6bb98a7..7715871 100644 --- a/game/shell.nix +++ b/game/shell.nix @@ -11,7 +11,7 @@ pkgs.mkShellNoCC { cglm glew glib - lua + guile gcc pkg-config diff --git a/game/src/main.c b/game/src/main.c index afa67fe..949d81e 100644 --- a/game/src/main.c +++ b/game/src/main.c @@ -1,10 +1,12 @@ #define SDL_MAIN_USE_CALLBACKS 1 #include +#include #include "event/evtman.h" #include "chunk/chunkman.h" #include "entity/templates.h" #include "ui/uiman.h" +#include "ui/widget_guile.h" #include "state.h" #include "resources.h" #include "graphics.h" @@ -17,6 +19,9 @@ SDL_AppInit (void **appstate, int argc, char **argv) UNUSED (appstate, argc, argv); SDL_SetAppMetadata (GAME_NAME, GAME_VERSION, "eur.chopininteractive.wschod-game"); + scm_init_guile (); + widget_guile_register (); + graphics_init (); resources_init (); flags_init (); diff --git a/game/src/ui/uiman.c b/game/src/ui/uiman.c index c553bc2..318aac0 100644 --- a/game/src/ui/uiman.c +++ b/game/src/ui/uiman.c @@ -20,60 +20,17 @@ static Widget *hovered_widget = NULL; static Widget *clicked_widget = NULL; static Widget *focused_widget = NULL; -static Widget *tooltip_widget = NULL; -static Widget *tooltip_text = NULL; +/* static Widget *tooltip_widget = NULL; */ +/* static Widget *tooltip_text = NULL; */ void uiman_init () { ui_widget_mesh_init (); glm_ortho (0.0, sdl_window_w, sdl_window_h, 0.0, -1.0, 1.0, projection); - - tooltip_widget = Widget_flowbox_new (TRUE); - tooltip_widget->visible = FALSE; - tooltip_widget->size[0] = 200; - tooltip_widget->layout_padding = 4; - tooltip_widget->layout_spacing = 8; - tooltip_widget->style = WSTYLE (STYLE_TOOLTIP); - tooltip_text = Widget_multiline_text_new (NULL, 20, TEXT_ALIGN_CENTER); - Widget_add_child_flowbox (tooltip_widget, tooltip_text, 1, 0); - + ui_root = Widget_plain_new (); IVEC2_SETI (ui_root->size, sdl_window_w, sdl_window_h); - - Widget *debug_window = Widget_window_new ("Debug menu", 20); - debug_window->size[0] = 350; - debug_window->window.resizable_v = FALSE; - debug_window->layout_padding = 8; - debug_window->style = WSTYLE (STYLE_WINDOW); - - Widget *debug_menu = Widget_flowbox_new (TRUE); - debug_menu->layout_padding = 8; - debug_menu->layout_spacing = 8; - debug_menu->style = WSTYLE (STYLE_CONTAINER); - - Widget_add_child_flowbox (debug_menu, Widget_label_make_float ("Frame time: %.2f", &delta_time, TEXT_ALIGN_LEFT), 1, 20); - Widget_add_child_flowbox (debug_menu, Widget_label_make_int ("Chunks: %d", &n_frame_chunks, TEXT_ALIGN_LEFT), 1./2., 20); - Widget_add_child_flowbox (debug_menu, Widget_label_make_int ("Entities: %d", &n_frame_ents, TEXT_ALIGN_LEFT), 1./2., 20); - - Widget_add_child_flowbox (debug_menu, Widget_label_make_float ("X: %.1f", &camera_position[0], TEXT_ALIGN_LEFT), 1./3., 20); - Widget_add_child_flowbox (debug_menu, Widget_label_make_float ("Y: %.1f", &camera_position[1], TEXT_ALIGN_CENTER), 1./3., 20); - Widget_add_child_flowbox (debug_menu, Widget_label_make_float ("Z: %.1f", &camera_position[2], TEXT_ALIGN_RIGHT), 1./3., 20); - - Widget *spinner = Widget_composite_spinner_make_int ("Render distance: %d", &render_distance); - spinner->tooltip = g_string_new ("Right click to show a context menu"); - Widget_add_child_flowbox (debug_menu, spinner, 1, 20); - - Widget_add_child_flowbox (debug_menu, Widget_composite_checkbox_make ("Wireframe", "wireframe_enabled"), 1./2., 20); - Widget_add_child_flowbox (debug_menu, Widget_composite_checkbox_make ("Flight", "flight_enabled"), 1./2., 20); - - Widget_add_child_flowbox (debug_menu, Widget_entry_new ("Test entry"), 1, 20); - Widget_add_child_flowbox (debug_menu, Widget_progress_new (TRUE, 0, 0.1, &delta_time), 1, 20); - - Widget_add_child (debug_window, debug_menu); - Widget_add_child (ui_root, debug_window); - - Widget_dump (ui_root, 0); } void @@ -86,7 +43,7 @@ void uiman_render () { Widget_render (ui_root, projection, sdl_window_h); - Widget_render (tooltip_widget, projection, sdl_window_h); + /* Widget_render (tooltip_widget, projection, sdl_window_h); */ } void @@ -150,7 +107,7 @@ uiman_cb_switch_focus (SDL_Event *event, void *data) _uiman_set_clicked (clicked_widget, FALSE); clicked_widget = NULL; - tooltip_widget->visible = FALSE; + /* tooltip_widget->visible = FALSE; */ return TRUE; } @@ -217,13 +174,13 @@ uiman_cb_mouse_motion (SDL_Event *event, void *data) if (tooltip_source && tooltip_source->tooltip && tooltip_source->tooltip->len > 0) { - Widget_multiline_text_set_text (tooltip_text, tooltip_source->tooltip->str); - tooltip_widget->visible = TRUE; - IVEC2_SETI (tooltip_widget->position, pos[0] + 12, pos[1] + 12); + /* Widget_multiline_text_set_text (tooltip_text, tooltip_source->tooltip->str); */ + /* tooltip_widget->visible = TRUE; */ + /* IVEC2_SETI (tooltip_widget->position, pos[0] + 12, pos[1] + 12); */ } else { - tooltip_widget->visible = FALSE; + /* tooltip_widget->visible = FALSE; */ } /* This callback always eats the event, because why would the game diff --git a/game/src/ui/widget_guile.c b/game/src/ui/widget_guile.c new file mode 100644 index 0000000..455312b --- /dev/null +++ b/game/src/ui/widget_guile.c @@ -0,0 +1,131 @@ +#include "widget_guile.h" + +static Widget * +_wgg_build (const char *type) +{ + Widget *e = g_new0 (Widget, 1); + e->children = g_array_new (false, false, sizeof (Widget *)); + e->style = WSTYLE (STYLE_DEFAULT); + + if (g_strcmp0 (type, "plain") == 0) + { + e->kind = WIDGET_PLAIN; + } + + if (g_strcmp0 (type, "label") == 0) + { + e->kind = WIDGET_LABEL; + } + + if (g_strcmp0 (type, "scrollbar") == 0) + { + e->kind = WIDGET_SCROLLBAR; + } + + if (g_strcmp0 (type, "progress") == 0) + { + e->kind = WIDGET_PROGRESS; + } + + if (g_strcmp0 (type, "entry") == 0) + { + e->kind = WIDGET_ENTRY; + } + + if (g_strcmp0 (type, "multiline") == 0) + { + e->kind = WIDGET_MULTILINE_TEXT; + } + + if (g_strcmp0 (type, "container") == 0) + { + e->kind = WIDGET_CONTAINER; + } + + if (g_strcmp0 (type, "scrollable") == 0) + { + e->kind = WIDGET_SCROLLABLE; + } + + if (g_strcmp0 (type, "flowbox") == 0) + { + e->kind = WIDGET_FLOWBOX; + } + + if (g_strcmp0 (type, "window") == 0) + { + e->kind = WIDGET_WINDOW; + } + + return NULL; +} + +static void +_wgg_set_property (Widget *w, const char *key, SCM val) +{ + UNUSED (w, key, val); +} + +// (widget-new TYPE #:PROP1 VALUE1 ... #:PROPN VALUEN child1 ... childn) +static SCM +_wg_widget_new (SCM args) +{ + if (!scm_is_pair (args)) + { + scm_wrong_num_args (SCM_UNDEFINED); + } + + SCM type_sym = scm_car (args); + args = scm_cdr (args); + + const char *type = scm_symbol_to_string (type_sym) ? scm_to_utf8_string (scm_symbol_to_string (type_sym)) : NULL; + if (!type) + { + scm_misc_error ("widget-new", "Invalid widget type symbol", SCM_EOL); + } + + Widget *w = _wgg_build (type); + + if (!w) + { + scm_misc_error ("widget-new", "Unknown widget type", scm_list_1 (type_sym)); + } + + // Parse keyword args + while (scm_is_pair (args)) + { + SCM key = scm_car (args); + args = scm_cdr (args); + + if (!scm_is_keyword (key)) + { + break; + } + + if (!scm_is_pair (args)) + { + scm_misc_error ("widget-new", "Expected value after keyword", SCM_EOL); + } + + SCM val = scm_car (args); + args = scm_cdr (args); + _wgg_set_property (w, scm_to_utf8_string (scm_keyword_to_symbol (key)), val); + } + + // Remaining args = children + while (scm_is_pair (args)) + { + SCM child = scm_car (args); + args = scm_cdr (args); + Widget *cw = scm_to_pointer (child); + Widget_add_child (w, cw); + } + + return scm_from_pointer (w, NULL); +} + +void +widget_guile_register () +{ + scm_c_define_gsubr ("widget-new", 0, 0, 1, _wg_widget_new); +} diff --git a/game/src/ui/widget_guile.h b/game/src/ui/widget_guile.h new file mode 100644 index 0000000..516de34 --- /dev/null +++ b/game/src/ui/widget_guile.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +#include "widget_fw.h" +#include "widget_core.h" + +void widget_guile_register (); diff --git a/game/src/ui/widget_style.h b/game/src/ui/widget_style.h index 0a71424..cf48ba4 100644 --- a/game/src/ui/widget_style.h +++ b/game/src/ui/widget_style.h @@ -67,27 +67,19 @@ static const WidgetStyle widget_styles[NSTYLES] = { }, [STYLE_TOOLTIP] = { - .background_color = COLOR_BLACK, - .background_color_hovered = COLOR_BLACK, - .background_color_clicked = COLOR_BLACK, + .background_color = { 0.1, 0.1, 0.1, 1.0 }, + .background_color_hovered = { 0.1, 0.1, 0.1, 1.0 }, + .background_color_clicked = { 0.1, 0.1, 0.1, 1.0 }, .text_color = COLOR_WHITE, .text_color_hovered = COLOR_WHITE, .text_color_clicked = COLOR_WHITE, - - .border_width = 0, }, [STYLE_ICON_BUTTON] = { - .text_color = { 0.0, 0.0, 0.0, 1.0 }, - .text_color_hovered = { 0.0, 0.0, 0.0, 1.0 }, - .text_color_clicked = { 0.0, 0.0, 0.0, 1.0 }, - .icon_color = COLOR_WHITE, .icon_color_hovered = { 1.0, 1.0, 0.0, 1.0 }, .icon_color_clicked = { 1.0, 0.0, 0.0, 1.0 }, - - .border_width = 0, }, [STYLE_WINDOW] = {