diff --git a/game/res/manifest.cfg b/game/res/manifest.cfg index 2f32e92..c117973 100644 --- a/game/res/manifest.cfg +++ b/game/res/manifest.cfg @@ -19,10 +19,18 @@ uidummy=res/shaders/uidummy.vert;res/shaders/uidummy.frag # referenced from Guile, and some of these are referenced in C (all # the terrains, font0 and icons). [Textures] -font0=res/textures/font_9x20.png -icons=res/textures/icons.png logo=res/textures/logo.png +font0=res/textures/ui/font_9x20.png +arrow_down=res/textures/ui/arrow_down.png +arrow_up=res/textures/ui/arrow_up.png +arrow_left=res/textures/ui/arrow_left.png +arrow_right=res/textures/ui/arrow_right.png +checkbox_off=res/textures/ui/checkbox_off.png +checkbox_on=res/textures/ui/checkbox_on.png +spinner_minus=res/textures/ui/spinner_minus.png +spinner_plus=res/textures/ui/spinner_plus.png + terrain0=res/textures/dirt.png terrain1=res/textures/drygrass.png terrain2=res/textures/grass.png diff --git a/game/res/scripts/g_styles.scm b/game/res/scripts/g_styles.scm index f8db6dd..c50db58 100644 --- a/game/res/scripts/g_styles.scm +++ b/game/res/scripts/g_styles.scm @@ -7,9 +7,9 @@ #:text-color-hovered COLOR_WHITE #:text-color-clicked COLOR_WHITE #:ghost-text-color '(1.0 1.0 1.0 0.5) - #:icon-color COLOR_WHITE - #:icon-color-hovered COLOR_WHITE - #:icon-color-clicked COLOR_WHITE + #:image-color COLOR_WHITE + #:image-color-hovered COLOR_WHITE + #:image-color-clicked COLOR_WHITE #:scrollbar-color COLOR_WHITE #:scrollbar-color-hovered COLOR_WHITE #:scrollbar-color-clicked COLOR_WHITE @@ -36,14 +36,14 @@ #:border-width 2)) (define style-icon-button - (style-new #: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))) + (style-new #:image-color COLOR_WHITE + #:image-color-hovered '(1.0 1.0 0.0 1.0) + #:image-color-clicked '(1.0 0.0 0.0 1.0))) (define style-button - (style-new #:background-color '(0.1 0.1 0.1 1.0) - #:background-color-hovered '(0.4 0.4 0.4 1.0) - #:background-color-clicked '(0.2 0.2 0.2 1.0) + (style-new #:background-color '(0.15 0.15 0.15 1.0) + #:background-color-hovered '(0.2 0.2 0.2 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)) diff --git a/game/res/scripts/g_uielements.scm b/game/res/scripts/g_uielements.scm index edc0307..3bfa42c 100644 --- a/game/res/scripts/g_uielements.scm +++ b/game/res/scripts/g_uielements.scm @@ -1,9 +1,9 @@ (use-modules (ice-9 format)) (define (widget-checkbox-icon-switch widget event) - (if (= (widget-get-icon widget) 1) - (widget-set-icon! widget 2) - (widget-set-icon! widget 1))) + (if (= (widget-get-image widget) (pak-texture "base" "checkbox_off")) + (widget-set-image! widget (pak-texture "base" "checkbox_on")) + (widget-set-image! widget (pak-texture "base" "checkbox_off")))) (define (widget-checkbox text flag . args) (apply @@ -12,7 +12,7 @@ (list 'container #:horizontal #t #:layout-spacing 8) args (list - (widget-new 'plain #:style style-icon-button #:icon 1 #:aspect-ratio 1 + (widget-new 'plain #:style style-icon-button #:image (pak-texture "base" "checkbox_off") #:aspect-ratio 1 #:on-click (lambda (w e) (widget-checkbox-icon-switch w e) (flag-switch flag))) (widget-new 'label #:style style-default #:text text #:layout-weight 1))))) @@ -29,13 +29,13 @@ (list 'container #:horizontal #t #:layout-spacing 8) args (list - (widget-new 'plain #:style style-icon-button #:icon 3 #:aspect-ratio 1 + (widget-new 'plain #:style style-icon-button #:image (pak-texture "base" "spinner_minus") #:aspect-ratio 1 #:on-click (lambda (w e) (gvar-set gvar (- (gvar-get gvar) 1)))) (widget-new 'label #:style style-default #:layout-weight 1 #:text-alignment 'center #:on-tick (lambda (w e) (widget-set-text! w (apply format #f fmt (list (coerce type (gvar-get gvar))))))) - (widget-new 'plain #:style style-icon-button #:icon 4 #:aspect-ratio 1 + (widget-new 'plain #:style style-icon-button #:image (pak-texture "base" "spinner_plus") #:aspect-ratio 1 #:on-click (lambda (w e) (gvar-set gvar (+ (gvar-get gvar) 1)))))))) diff --git a/game/res/scripts/u_main_menu.scm b/game/res/scripts/u_main_menu.scm index e520a7e..2c96cbf 100644 --- a/game/res/scripts/u_main_menu.scm +++ b/game/res/scripts/u_main_menu.scm @@ -1,14 +1,16 @@ (widget-new - 'plain + 'centerer (widget-new 'flowbox #:style style-container - #:w 300 + #:w 379 #:layout-padding 8 #:layout-spacing 8 #:horizontal #t - (widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "New game" + (widget-new 'plain #:style style-default #:image (pak-texture "base" "logo") #:layout-weight 1 #:h 200) + (widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "Play!" #:on-click (lambda (w e) (switch-stage "ingame"))) + (widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "Map editor") (widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "Options") (widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "Quit game"))) diff --git a/game/res/shaders/uiwidget.frag b/game/res/shaders/uiwidget.frag index 124bb25..2748139 100644 --- a/game/res/shaders/uiwidget.frag +++ b/game/res/shaders/uiwidget.frag @@ -2,8 +2,7 @@ precision mediump float; -uniform bool has_background_image; -uniform bool has_icon; +uniform bool has_image; uniform bool has_scrollbar; uniform bool has_progress; uniform bool has_resize_handle; @@ -14,7 +13,7 @@ uniform float border_width; uniform vec4 border_color; uniform vec4 background_color; -uniform vec4 icon_color; +uniform vec4 image_color; uniform vec4 scrollbar_color; uniform vec4 progress_color; uniform vec4 resize_handle_color; @@ -23,11 +22,9 @@ uniform vec2 scrollbar_position; uniform vec2 scrollbar_size; uniform vec2 progress_size; -uniform sampler2D background_image; -uniform sampler2D icons; +uniform sampler2D image; varying vec2 f_uv; -varying vec2 f_icon_uv; const float resize_handle_size = 10.0; @@ -39,7 +36,7 @@ void main () float y_border = step (f_uv.y, border_uv.y) + step (1.0 - border_uv.y, f_uv.y); float is_border = clamp (x_border + y_border, 0.0, 1.0); - vec4 bgc = has_background_image ? texture2D (background_image, f_uv) : background_color; + vec4 bgc = background_color; vec4 base_color = mix (bgc, border_color, is_border); if (has_resize_handle) @@ -90,9 +87,9 @@ void main () } } - if (has_icon) + if (has_image) { - vec4 fg = texture2D (icons, f_icon_uv) * icon_color; + vec4 fg = texture2D (image, f_uv) * image_color; base_color = mix (base_color, fg, fg.a); } diff --git a/game/res/shaders/uiwidget.vert b/game/res/shaders/uiwidget.vert index f836ec4..16744aa 100644 --- a/game/res/shaders/uiwidget.vert +++ b/game/res/shaders/uiwidget.vert @@ -9,26 +9,10 @@ uniform mat4 projection; uniform float icon_index; varying vec2 f_uv; -varying vec2 f_icon_uv; void main () { - float tex_w = 40.0; - float tex_h = 80.0; - - float icon_w = 20.0; - float icon_h = 20.0; - - float icons_per_row = tex_w / icon_w; - - float x = mod (icon_index, icons_per_row); - float y = floor (icon_index / icons_per_row); - - vec2 icon_offset = vec2 (x * icon_w / tex_w, y * icon_h / tex_h); - vec2 icon_size = vec2 (icon_w / tex_w, icon_h / tex_h); - - f_icon_uv = icon_offset + uv * icon_size; f_uv = uv; gl_Position = projection * vec4 (model * vec3 (position.xy, 1.0), 1.0); } diff --git a/game/res/textures/icons.png b/game/res/textures/icons.png deleted file mode 100644 index 0016319..0000000 Binary files a/game/res/textures/icons.png and /dev/null differ diff --git a/game/res/textures/icons.xcf b/game/res/textures/icons.xcf deleted file mode 100644 index 2761990..0000000 Binary files a/game/res/textures/icons.xcf and /dev/null differ diff --git a/game/res/textures/logo.png b/game/res/textures/logo.png index 9d07bea..43f1232 100644 Binary files a/game/res/textures/logo.png and b/game/res/textures/logo.png differ diff --git a/game/res/textures/ui/arrow_down.png b/game/res/textures/ui/arrow_down.png new file mode 100644 index 0000000..79603b1 Binary files /dev/null and b/game/res/textures/ui/arrow_down.png differ diff --git a/game/res/textures/ui/arrow_left.png b/game/res/textures/ui/arrow_left.png new file mode 100644 index 0000000..ab5f905 Binary files /dev/null and b/game/res/textures/ui/arrow_left.png differ diff --git a/game/res/textures/ui/arrow_right.png b/game/res/textures/ui/arrow_right.png new file mode 100644 index 0000000..03f0145 Binary files /dev/null and b/game/res/textures/ui/arrow_right.png differ diff --git a/game/res/textures/ui/arrow_up.png b/game/res/textures/ui/arrow_up.png new file mode 100644 index 0000000..1610480 Binary files /dev/null and b/game/res/textures/ui/arrow_up.png differ diff --git a/game/res/textures/ui/checkbox_off.png b/game/res/textures/ui/checkbox_off.png new file mode 100644 index 0000000..7138ab8 Binary files /dev/null and b/game/res/textures/ui/checkbox_off.png differ diff --git a/game/res/textures/ui/checkbox_on.png b/game/res/textures/ui/checkbox_on.png new file mode 100644 index 0000000..c0b0ada Binary files /dev/null and b/game/res/textures/ui/checkbox_on.png differ diff --git a/game/res/textures/font_9x20.png b/game/res/textures/ui/font_9x20.png similarity index 100% rename from game/res/textures/font_9x20.png rename to game/res/textures/ui/font_9x20.png diff --git a/game/res/textures/font_9x20.xcf b/game/res/textures/ui/font_9x20.xcf similarity index 100% rename from game/res/textures/font_9x20.xcf rename to game/res/textures/ui/font_9x20.xcf diff --git a/game/res/textures/ui/spinner_minus.png b/game/res/textures/ui/spinner_minus.png new file mode 100644 index 0000000..0a97f23 Binary files /dev/null and b/game/res/textures/ui/spinner_minus.png differ diff --git a/game/res/textures/ui/spinner_plus.png b/game/res/textures/ui/spinner_plus.png new file mode 100644 index 0000000..b1e20ab Binary files /dev/null and b/game/res/textures/ui/spinner_plus.png differ diff --git a/game/src/camera.c b/game/src/camera.c index 4243065..e98c33d 100644 --- a/game/src/camera.c +++ b/game/src/camera.c @@ -1,8 +1,5 @@ #include "camera.h" -vec3 camera_position; -vec3 camera_rotation; - void Camera_get_direction (Camera *camera, vec3 dest) { @@ -33,7 +30,7 @@ Camera_get_view (Camera *camera, mat4 dest) void Camera_get_projection (Camera *camera, float aspect, mat4 dest) { - (void) camera; + UNUSED (camera); glm_perspective (glm_rad (70), aspect, 0.01, 7000.0, dest); } diff --git a/game/src/camera.h b/game/src/camera.h index 91b6366..7754f1d 100644 --- a/game/src/camera.h +++ b/game/src/camera.h @@ -2,6 +2,8 @@ #include +#include "util.h" + typedef struct Camera { vec3 position, rotation; @@ -11,8 +13,3 @@ void Camera_get_direction (Camera *camera, vec3 dest); void Camera_get_right (Camera *camera, vec3 dest); void Camera_get_view (Camera *camera, mat4 dest); void Camera_get_projection (Camera *camera, float aspect, mat4 dest); - -void camera_get_direction (vec3 dest); -void camera_get_right (vec3 dest); -void camera_get_view (mat4 dest); -void camera_get_projection (float aspect, mat4 dest); diff --git a/game/src/entity/entity.h b/game/src/entity/entity.h index 835a5de..3f200ca 100644 --- a/game/src/entity/entity.h +++ b/game/src/entity/entity.h @@ -9,7 +9,7 @@ #include "../gl/program.h" #include "../gl/texture.h" -struct World; /* Forward declaration. */ +struct World; typedef struct Entity { @@ -25,6 +25,7 @@ typedef struct Entity void *userdata; void (*on_tick) (struct Entity *self, struct World *world); + gboolean i_said_tick_me_youre_beautiful; vec3 position; vec3 rotation; diff --git a/game/src/pakman.c b/game/src/pakman.c index 9af7cf5..35096e0 100644 --- a/game/src/pakman.c +++ b/game/src/pakman.c @@ -97,7 +97,10 @@ pakman_load_pak (const char *path) PakFile *pak = g_new0 (PakFile, 1); pak->programs = g_hash_table_new (g_str_hash, g_str_equal); pak->textures = g_hash_table_new (g_str_hash, g_str_equal); - pak->uidefs = g_hash_table_new (g_str_hash, g_str_equal); + pak->uidefs = g_hash_table_new (g_str_hash, g_str_equal); + + char *id = g_key_file_get_string (key_file, "Metadata", "id", &err); + g_hash_table_insert (paks, g_strdup (id), pak); char **programs = g_key_file_get_keys (key_file, "Programs", NULL, &err); @@ -142,9 +145,6 @@ pakman_load_pak (const char *path) g_hash_table_insert (pak->uidefs, g_strdup (*u), uidef); } - char *id = g_key_file_get_string (key_file, "Metadata", "id", &err); - g_hash_table_insert (paks, g_strdup (id), pak); - /* Some hacks. */ program_use (pakman_pak_program (id, "chunk")); program_set_int_array (pakman_pak_program (id, "chunk"), "materials", 5, (int[5]) { 0, 1, 2, 3, 4 }); diff --git a/game/src/stage/stage_common.c b/game/src/stage/stage_common.c index 07d93a3..1398009 100644 --- a/game/src/stage/stage_common.c +++ b/game/src/stage/stage_common.c @@ -8,7 +8,6 @@ GameStage_new () g->ui_context->tooltip = PMUID ("tooltip"); g->world = World_new (); - g->camera = g_new0 (Camera, 1); return g; } diff --git a/game/src/stage/stage_common.h b/game/src/stage/stage_common.h index 8689515..24069ea 100644 --- a/game/src/stage/stage_common.h +++ b/game/src/stage/stage_common.h @@ -7,7 +7,6 @@ #include "../util.h" #include "../gvar.h" -#include "../camera.h" #include "../world.h" typedef struct { @@ -21,7 +20,6 @@ typedef struct { typedef struct GameStage { UIContext *ui_context; /* Could be NULL... */ - Camera *camera; /* Doesn't have to be defined. */ World *world; GList *event_handlers; diff --git a/game/src/stage/stage_ingame.c b/game/src/stage/stage_ingame.c index 82c0263..b81e940 100644 --- a/game/src/stage/stage_ingame.c +++ b/game/src/stage/stage_ingame.c @@ -21,101 +21,27 @@ _on_enter (GameStage *self) static void _on_update (GameStage *self) { + Camera *cam = self->world->camera; + /* We pin the camera to the player position, with eye level 20 centimeters below the height. */ - glm_vec3_copy (player_entity->position, self->camera->position); - self->camera->position[1] += player_entity->scale[1] - 0.2; - player_entity->rotation[1] = self->camera->rotation[1]; + glm_vec3_copy (player_entity->position, cam->position); + cam->position[1] += player_entity->scale[1] - 0.2; + player_entity->rotation[1] = cam->rotation[1]; /* The sky needs to be in the center of the world all the time, otherwise, as we explore the world, we might reach the end of the sky. */ - sky_entity->position[0] = self->camera->position[0]; - sky_entity->position[2] = self->camera->position[2]; - - World_update (self->world, self->camera->position); - - int speed = 5; - float delta_time = gvar_get ("delta_time"); - - if (FLAG_GET ("flight_enabled") && FLAG_GET ("flying_fast")) - { - speed = 15; - } - - if (FLAG_GET ("moving_forward")) - { - vec3 dir, change, new_pos; - Camera_get_direction (self->camera, dir); - glm_vec3_scale (dir, delta_time * speed, change); - glm_vec3_add (player_entity->position, change, new_pos); - glm_vec3_copy (new_pos, player_entity->position); - } - - if (FLAG_GET ("moving_backward")) - { - vec3 dir, change, new_pos; - Camera_get_direction (self->camera, dir); - glm_vec3_scale (dir, delta_time * speed, change); - glm_vec3_sub (player_entity->position, change, new_pos); - glm_vec3_copy (new_pos, player_entity->position); - } - - if (FLAG_GET ("moving_right")) - { - vec3 right, change, new_pos; - Camera_get_right (self->camera, right); - glm_vec3_scale (right, delta_time * speed, change); - glm_vec3_add (player_entity->position, change, new_pos); - glm_vec3_copy (new_pos, player_entity->position); - } - - if (FLAG_GET ("moving_left")) - { - vec3 right, change, new_pos; - Camera_get_right (self->camera, right); - glm_vec3_scale (right, delta_time * speed, change); - glm_vec3_sub (player_entity->position, change, new_pos); - glm_vec3_copy (new_pos, player_entity->position); - } - - if (FLAG_GET ("flying_up") && FLAG_GET ("flight_enabled")) - { - vec3 change, new_pos; - glm_vec3_scale (GLM_YUP, delta_time * speed, change); - glm_vec3_add (player_entity->position, change, new_pos); - glm_vec3_copy (new_pos, player_entity->position); - } - - if (FLAG_GET ("flying_down") && FLAG_GET ("flight_enabled")) - { - vec3 change, new_pos; - glm_vec3_scale (GLM_YUP, delta_time * speed, change); - glm_vec3_sub (player_entity->position, change, new_pos); - glm_vec3_copy (new_pos, player_entity->position); - } + sky_entity->position[0] = cam->position[0]; + sky_entity->position[2] = cam->position[2]; + World_update (self->world); } static void _on_render (GameStage *self) { Profiler_begin (&profiler); - - mat4 projection, view; - Camera_get_projection (self->camera, gvar_get ("window_width") / gvar_get ("window_height"), projection); - Camera_get_view (self->camera, view); - - pakman_all_paks_set_mat4 ("projection", projection); - pakman_all_paks_set_mat4 ("view", view); - pakman_all_paks_set_float ("time", gvar_get ("last_time")); - - vec4 planes[6]; - mat4 view_proj; - glm_mat4_mul (projection, view, view_proj); - glm_frustum_planes (view_proj, planes); - - World_render (self->world, self->camera->position, view, planes); - + World_render (self->world); Profiler_sample (&profiler); if (Profiler_should_check (&profiler, profiler_check_freq_s)) @@ -162,6 +88,66 @@ _freelook_camera (SDL_Event *event, void *userdata) void _temporary_player_tick (Entity *self, World *world) { + int speed = 5; + float delta_time = gvar_get ("delta_time"); + + if (FLAG_GET ("flight_enabled") && FLAG_GET ("flying_fast")) + { + speed = 15; + } + + if (FLAG_GET ("moving_forward")) + { + vec3 dir, change, new_pos; + Camera_get_direction (world->camera, dir); + glm_vec3_scale (dir, delta_time * speed, change); + glm_vec3_add (self->position, change, new_pos); + glm_vec3_copy (new_pos, self->position); + } + + if (FLAG_GET ("moving_backward")) + { + vec3 dir, change, new_pos; + Camera_get_direction (world->camera, dir); + glm_vec3_scale (dir, delta_time * speed, change); + glm_vec3_sub (self->position, change, new_pos); + glm_vec3_copy (new_pos, self->position); + } + + if (FLAG_GET ("moving_right")) + { + vec3 right, change, new_pos; + Camera_get_right (world->camera, right); + glm_vec3_scale (right, delta_time * speed, change); + glm_vec3_add (self->position, change, new_pos); + glm_vec3_copy (new_pos, self->position); + } + + if (FLAG_GET ("moving_left")) + { + vec3 right, change, new_pos; + Camera_get_right (world->camera, right); + glm_vec3_scale (right, delta_time * speed, change); + glm_vec3_sub (self->position, change, new_pos); + glm_vec3_copy (new_pos, self->position); + } + + if (FLAG_GET ("flying_up") && FLAG_GET ("flight_enabled")) + { + vec3 change, new_pos; + glm_vec3_scale (GLM_YUP, delta_time * speed, change); + glm_vec3_add (self->position, change, new_pos); + glm_vec3_copy (new_pos, self->position); + } + + if (FLAG_GET ("flying_down") && FLAG_GET ("flight_enabled")) + { + vec3 change, new_pos; + glm_vec3_scale (GLM_YUP, delta_time * speed, change); + glm_vec3_sub (self->position, change, new_pos); + glm_vec3_copy (new_pos, self->position); + } + if (!FLAG_GET ("flight_enabled")) { self->position[1] = World_get_height_at (world, self->position[0], self->position[2]); @@ -182,7 +168,7 @@ stage_ingame_new () GAEH (self, 0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_TAB), _switch_ui_focus, self->ui_context); - GAEH (self, 0, SDL_EVENT_MOUSE_MOTION, NULL, NULL, _freelook_camera, self->camera); + GAEH (self, 0, SDL_EVENT_MOUSE_MOTION, NULL, NULL, _freelook_camera, self->world->camera); GAEH (self, 0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_W), evt_cb_flag_on, "moving_forward"); GAEH (self, 0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_W), evt_cb_flag_off, "moving_forward"); @@ -210,7 +196,6 @@ stage_ingame_new () player_entity->visible = false; player_entity->on_tick = _temporary_player_tick; glm_vec3_copy ((vec3) { 1.0, 1.8, 1.0 }, player_entity->scale); - /* player_entity->on_tick = character_on_tick; */ World_add_Entity (self->world, player_entity); sky_entity = Entity_new (); diff --git a/game/src/stage/stage_ingame.h b/game/src/stage/stage_ingame.h index f6c52c0..e424967 100644 --- a/game/src/stage/stage_ingame.h +++ b/game/src/stage/stage_ingame.h @@ -3,9 +3,7 @@ #include "stage_common.h" #include "../gvar.h" -#include "../camera.h" #include "../profiler.h" #include "../graphics.h" - GameStage *stage_ingame_new (); diff --git a/game/src/stage/stage_mapeditor.c b/game/src/stage/stage_mapeditor.c new file mode 100644 index 0000000..6f01f34 --- /dev/null +++ b/game/src/stage/stage_mapeditor.c @@ -0,0 +1,14 @@ +#include "stage_mapeditor.h" + +/* static void */ +/* _on_enter (GameStage *self) */ +/* { */ +/* UNUSED (self); */ +/* gvar_set ("ui_has_focus", TRUE); */ +/* } */ + +/* static void */ +/* _on_update (GameStage *self) */ +/* { */ +/* World_update (self->world); */ +/* } */ diff --git a/game/src/stage/stage_mapeditor.h b/game/src/stage/stage_mapeditor.h new file mode 100644 index 0000000..6e7e26a --- /dev/null +++ b/game/src/stage/stage_mapeditor.h @@ -0,0 +1,8 @@ +#include "stage_common.h" + +#include "../gvar.h" +#include "../camera.h" +#include "../profiler.h" +#include "../graphics.h" + +GameStage *stage_mapeditor_new (); diff --git a/game/src/ui/widget_core.h b/game/src/ui/widget_core.h index 77b0063..701e987 100644 --- a/game/src/ui/widget_core.h +++ b/game/src/ui/widget_core.h @@ -34,23 +34,11 @@ typedef enum WidgetKind WIDGET_CONTAINER, WIDGET_SCROLLABLE, WIDGET_FLOWBOX, - + WIDGET_CENTERER, + WIDGET_WINDOW } WidgetKind; -typedef enum WidgetIcon - { - ICON_NONE, - ICON_CHECKBOX_UNCHECKED, - ICON_CHECKBOX_CHECKED, - ICON_MINUS, - ICON_PLUS, - ICON_ARROW_LEFT, - ICON_ARROW_RIGHT, - ICON_ARROW_UP, - ICON_ARROW_DOWN - } WidgetIcon; - typedef enum WidgetEvent { EVENT_TICK, @@ -174,7 +162,7 @@ typedef struct Widget float layout_weight, aspect_ratio; const WidgetStyle *style; - WidgetIcon icon; + unsigned int image; GString *tooltip; diff --git a/game/src/ui/widget_guile.c b/game/src/ui/widget_guile.c index 3a6fe5b..e71ded7 100644 --- a/game/src/ui/widget_guile.c +++ b/game/src/ui/widget_guile.c @@ -77,19 +77,19 @@ _wg_style_new (SCM args) scm_vec4_to_float_array (val, s->ghost_text_color); } - if (!strcmp (k, "icon-color")) + if (!strcmp (k, "image-color")) { - scm_vec4_to_float_array (val, s->icon_color); + scm_vec4_to_float_array (val, s->image_color); } - if (!strcmp (k, "icon-color-hovered")) + if (!strcmp (k, "image-color-hovered")) { - scm_vec4_to_float_array (val, s->icon_color_hovered); + scm_vec4_to_float_array (val, s->image_color_hovered); } - if (!strcmp (k, "icon-color-clicked")) + if (!strcmp (k, "image-color-clicked")) { - scm_vec4_to_float_array (val, s->icon_color_clicked); + scm_vec4_to_float_array (val, s->image_color_clicked); } if (!strcmp (k, "scrollbar-color")) @@ -210,6 +210,12 @@ _wgg_build (const char *type) w->do_layout = Widget_layout_flowbox; } + if (!g_strcmp0 (type, "centerer")) + { + w->kind = WIDGET_CENTERER; + w->do_layout = Widget_layout_centerer; + } + if (!g_strcmp0 (type, "window")) { w->kind = WIDGET_WINDOW; @@ -351,11 +357,6 @@ _wgg_set_property (Widget *w, const char *key, SCM val) w->style = (const WidgetStyle *) scm_to_pointer (val); } - if (!g_strcmp0 (key, "icon")) - { - w->icon = scm_to_int (val); - } - if (!g_strcmp0 (key, "text")) { switch (w->kind) @@ -396,6 +397,11 @@ _wgg_set_property (Widget *w, const char *key, SCM val) g_string_assign (w->tooltip, scm_to_utf8_string (val)); } + if (!g_strcmp0 (key, "image")) + { + w->image = scm_to_int (val); + } + if (!g_strcmp0 (key, "on-tick")) { if (!scm_is_true (scm_procedure_p (val))) @@ -485,22 +491,6 @@ _wg_widget_new (SCM args) return scm_from_pointer (w, NULL); } -static SCM -_wg_get_icon (SCM widget_ptr) -{ - Widget *w = (Widget *) scm_to_pointer (widget_ptr); - return scm_from_int (w->icon); -} - -static SCM -_wg_set_icon (SCM widget_ptr, SCM icon_val) -{ - Widget *w = (Widget *) scm_to_pointer (widget_ptr); - int icon = scm_to_int (icon_val); - w->icon = icon; - return SCM_UNSPECIFIED; -} - static SCM _wg_set_text (SCM widget_ptr, SCM val) { @@ -526,14 +516,29 @@ _wg_set_text (SCM widget_ptr, SCM val) return SCM_UNSPECIFIED; } +static SCM +_wg_get_image (SCM widget_ptr) +{ + Widget *w = (Widget *) scm_to_pointer (widget_ptr); + return scm_from_int (w->image); +} + +static SCM +_wg_set_image (SCM widget_ptr, SCM val) +{ + Widget *w = (Widget *) scm_to_pointer (widget_ptr); + w->image = scm_to_int (val); + return SCM_UNSPECIFIED; +} + void widget_guile_register () { scm_c_define_gsubr ("widget-new", 0, 0, 1, _wg_widget_new); scm_c_define_gsubr ("style-new", 0, 0, 1, _wg_style_new); - - scm_c_define_gsubr ("widget-get-icon", 1, 0, 0, _wg_get_icon); - scm_c_define_gsubr ("widget-set-icon!", 2, 0, 0, _wg_set_icon); + scm_c_define_gsubr ("widget-get-image", 1, 0, 0, _wg_get_image); + scm_c_define_gsubr ("widget-set-image!", 2, 0, 0, _wg_set_image); + scm_c_define_gsubr ("widget-set-text!", 2, 0, 0, _wg_set_text); } diff --git a/game/src/ui/widget_layout.c b/game/src/ui/widget_layout.c index fb361ef..90d88ca 100644 --- a/game/src/ui/widget_layout.c +++ b/game/src/ui/widget_layout.c @@ -225,7 +225,7 @@ Widget_layout_flowbox (Widget *self) int space = self->layout_spacing; /* The biggest widght/height of the widget on the cross axis. */ - int last_cross_max = 0.0; + int last_cross_max = 0; /* Where we position the widget on the main axis. Indeed it also is the total size of the widgets we put on the main axis. */ int offset_main = pad; @@ -263,7 +263,7 @@ Widget_layout_flowbox (Widget *self) offset_main = pad; /* Since we're on the next row/column, we reset the maximum encountered widget size. */ - last_cross_max = 0.0; + last_cross_max = 0; } /* If the current widget's cross axis size is bigger than the @@ -282,6 +282,18 @@ Widget_layout_flowbox (Widget *self) self->size[cross_axis] = offset_cross + last_cross_max + pad; } +void +Widget_layout_centerer (Widget *self) +{ + /* This "container" only cares about the first child. But we loop + over all of them anyway. */ + WFOREACH (self, child) + { + child->position[0] = (self->size[0] / 2) - (child->size[0] / 2); + child->position[1] = (self->size[1] / 2) - (child->size[1] / 2); + } +} + void Widget_layout_window (Widget *self) { diff --git a/game/src/ui/widget_layout.h b/game/src/ui/widget_layout.h index 2205107..873a2d3 100644 --- a/game/src/ui/widget_layout.h +++ b/game/src/ui/widget_layout.h @@ -7,4 +7,5 @@ void Widget_layout_container (Widget *self); void Widget_layout_scrollable (Widget *self); void Widget_layout_multiline_text (Widget *self); void Widget_layout_flowbox (Widget *self); +void Widget_layout_centerer (Widget *self); void Widget_layout_window (Widget *self); diff --git a/game/src/ui/widget_render.c b/game/src/ui/widget_render.c index d2de2f6..073dc84 100644 --- a/game/src/ui/widget_render.c +++ b/game/src/ui/widget_render.c @@ -70,31 +70,28 @@ Widget_render_base (Widget *self, mat4 projection, int window_height) program_use (PMPRG ("uiwidget")); - texture_use (style->background_image, 0); /* If it doesn't have a texture, it'll be 0 anyway. */ - texture_use (PMTEX ("icons"), 1); + texture_use (self->image, 0); - program_set_int (PMPRG ("uiwidget"), "has_background_image", style->background_image != 0); - program_set_int (PMPRG ("uiwidget"), "has_icon", self->icon != ICON_NONE); program_set_int (PMPRG ("uiwidget"), "has_resize_handle", self->kind == WIDGET_WINDOW); + program_set_int (PMPRG ("uiwidget"), "has_image", self->image != 0); program_set_vec2 (PMPRG ("uiwidget"), "widget_size", (vec2) { self->size[0], self->size[1] }); program_set_float (PMPRG ("uiwidget"), "border_width", style->border_width); - program_set_float (PMPRG ("uiwidget"), "icon_index", self->icon - 1); + program_set_vec4 (PMPRG ("uiwidget"), "image_color", style->image_color); program_set_vec4 (PMPRG ("uiwidget"), "background_color", style->background_color); - program_set_vec4 (PMPRG ("uiwidget"), "icon_color", style->icon_color); program_set_vec4 (PMPRG ("uiwidget"), "border_color", style->border_color); program_set_vec4 (PMPRG ("uiwidget"), "resize_handle_color", style->resize_handle_color); if (self->clicked) { + program_set_vec4 (PMPRG ("uiwidget"), "image_color", style->image_color_clicked); program_set_vec4 (PMPRG ("uiwidget"), "background_color", style->background_color_clicked); - program_set_vec4 (PMPRG ("uiwidget"), "icon_color", style->icon_color_clicked); } else if (self->hovered) { + program_set_vec4 (PMPRG ("uiwidget"), "image_color", style->image_color_hovered); program_set_vec4 (PMPRG ("uiwidget"), "background_color", style->background_color_hovered); - program_set_vec4 (PMPRG ("uiwidget"), "icon_color", style->icon_color_hovered); } mat3 model; diff --git a/game/src/ui/widget_style.h b/game/src/ui/widget_style.h index 63cb171..4aadfe3 100644 --- a/game/src/ui/widget_style.h +++ b/game/src/ui/widget_style.h @@ -13,9 +13,9 @@ typedef struct WidgetStyle vec4 text_color_clicked; vec4 ghost_text_color; - vec4 icon_color; - vec4 icon_color_hovered; - vec4 icon_color_clicked; + vec4 image_color; + vec4 image_color_hovered; + vec4 image_color_clicked; vec4 scrollbar_color; vec4 scrollbar_color_hovered; diff --git a/game/src/world.c b/game/src/world.c index 40d3016..18a45ad 100644 --- a/game/src/world.c +++ b/game/src/world.c @@ -1,7 +1,7 @@ #include "world.h" static Profiler profiler = { 0 }; -static const int us_budget = 100; +static const int us_budget = 500; guint _ivec2_hash (gconstpointer key) @@ -32,6 +32,8 @@ World_new () { World *w = g_new0 (World, 1); + w->camera = g_new0 (Camera, 1); + w->entities = g_array_new (FALSE, FALSE, sizeof (Entity *)); w->chunks = g_hash_table_new_full (_ivec2_hash, _ivec2_equal, free, (GDestroyNotify) Chunk_free); @@ -54,11 +56,11 @@ _world_to_chunk (float x, float z, int *cx, int *cz) } void -World_update (World *w, vec3 position) +World_update (World *w) { int render_distance = gvar_get ("render_distance"); int cx, cz; - _world_to_chunk (position[0], position[2], &cx, &cz); + _world_to_chunk (w->camera->position[0], w->camera->position[2], &cx, &cz); for (int z = cz - render_distance - 1; z <= cz + render_distance + 1; ++z) { @@ -113,16 +115,16 @@ World_update (World *w, vec3 position) { break; } + + ivec2 key = { task->x, task->z }; if (task->is_mesh) { - ivec2 key = { task->x, task->z }; World_generate_ChunkMesh_at (w, task->x, task->z); g_hash_table_remove (w->pending_chunk_meshes, &key); } else { - ivec2 key = { task->x, task->z }; World_generate_Chunk_at (w, task->x, task->z); g_hash_table_remove (w->pending_chunks, &key); } @@ -130,6 +132,7 @@ World_update (World *w, vec3 position) g_free (task); } +#ifndef SKIP_ENTITIES while (!g_queue_is_empty (w->entity_queue)) { if (Profiler_sample (&profiler) > us_budget) @@ -162,14 +165,32 @@ World_update (World *w, vec3 position) { e->on_tick (e, w); } - } + } +#endif } void -World_render (World *w, vec3 position, mat4 view, vec4 planes[6]) +World_render (World *w) { +#ifdef SKIP_ENTITIES + UNUSED (view); +#endif + + mat4 projection, view; + Camera_get_projection (w->camera, gvar_get ("window_width") / gvar_get ("window_height"), projection); + Camera_get_view (w->camera, view); + + pakman_all_paks_set_mat4 ("projection", projection); + pakman_all_paks_set_mat4 ("view", view); + pakman_all_paks_set_float ("time", gvar_get ("last_time")); + + vec4 planes[6]; + mat4 view_proj; + glm_mat4_mul (projection, view, view_proj); + glm_frustum_planes (view_proj, planes); + int cx = 0, cz = 0; - _world_to_chunk (position[0], position[2], &cx, &cz); + _world_to_chunk (w->camera->position[0], w->camera->position[2], &cx, &cz); program_use (PMPRG ("chunk")); @@ -214,17 +235,20 @@ World_render (World *w, vec3 position, mat4 view, vec4 planes[6]) } } +#ifndef SKIP_ENTITIES for (guint i = 0; i < w->entities->len; ++i) { Entity *ent = g_array_index (w->entities, Entity*, i); - frame_entities += Entity_render (ent, position, view, planes, render_distance, wireframe_enabled) ? 1 : 0; + frame_entities += Entity_render (ent, w->camera->position, view, planes, render_distance, wireframe_enabled) ? 1 : 0; } +#endif gvar_set ("frame_chunks", frame_chunks); gvar_set ("frame_entities", frame_entities); } /* Entity-specific */ + void World_add_Entity (World *w, Entity *e) { @@ -232,6 +256,7 @@ World_add_Entity (World *w, Entity *e) } /* Chunk-specific */ + static inline float _Chunk_get_height (Chunk *c, int x, int z) { @@ -353,7 +378,8 @@ World_generate_Chunk_at (World *w, int cx, int cz) chunk->materialmap[INDEX (x, z)] = (int) (glm_perlin_vec2 ((vec2) { (x + xoffset + 0.333) / 20.0, (z + zoffset + 0.333) / 20.0 }) + 0.6 * 5) % 5; - if (rand() % 100 < 2) +#ifndef SKIP_ENTITIES + if (rand() % 100 < 7) { EntityTask *t = g_new (EntityTask, 1); t->template = g_strdup ("tree"); @@ -362,8 +388,7 @@ World_generate_Chunk_at (World *w, int cx, int cz) glm_vec3_copy ((vec3) { 3.0, (rand () % 5) + 5, 3.0 }, t->scale); g_queue_push_tail (w->entity_queue, t); } - - if (rand() % 100 < 10) + else if (rand() % 100 < 10) { EntityTask *t = g_new (EntityTask, 1); t->template = g_strdup ("grass"); @@ -372,6 +397,7 @@ World_generate_Chunk_at (World *w, int cx, int cz) glm_vec3_copy ((vec3) { 1.0, 1.0, 1.0 }, t->scale); g_queue_push_tail (w->entity_queue, t); } +#endif } } @@ -381,24 +407,10 @@ World_generate_Chunk_at (World *w, int cx, int cz) void World_generate_ChunkMesh_at (World *w, int cx, int cz) { - if (World_get_ChunkMesh_at (w, cx, cz)) - { - return; - } - - if (!World_get_Chunk_at (w, cx, cz)) - { - return; - } - Chunk *nr, *nd, *nc; World_get_Chunk_neighbors_at (w, cx, cz, &nr, &nd, &nc); - if (!nr || !nd || !nc) - { - g_info ("ChunkMesh did not have neighbors. Not generating."); - return; - } + g_assert (nr != NULL && nd != NULL && nc != NULL); World_set_ChunkMesh_at (w, cx, cz, ChunkMesh_build (World_get_Chunk_at (w, cx, cz), nr, nd, nc)); diff --git a/game/src/world.h b/game/src/world.h index 91056b9..8f0ecd7 100644 --- a/game/src/world.h +++ b/game/src/world.h @@ -6,14 +6,17 @@ #include "util.h" #include "gvar.h" #include "pakman.h" +#include "profiler.h" +#include "camera.h" #include "entity/entity.h" #include "entity/templates.h" #include "chunk/chunk.h" #include "chunk/chunkmesh.h" -#include "profiler.h" #define TERRAIN_HEIGHT 8.0 +/* #define SKIP_ENTITIES */ +#undef SKIP_ENTITIES typedef struct ChunkTask { gboolean is_mesh; @@ -30,6 +33,8 @@ typedef struct EntityTask { typedef struct World { + Camera *camera; + GArray *entities; GHashTable *chunks, *chunk_meshes; @@ -38,8 +43,8 @@ typedef struct World } World; World *World_new (); -void World_update (World *w, vec3 position); -void World_render (World *w, vec3 position, mat4 view, vec4 frustum[6]); +void World_update (World *w); +void World_render (World *w); /* Entity-specific */ void World_add_Entity (World *w, Entity *e);