Main menu changes
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))))))))
|
||||
|
||||
|
||||
@@ -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")))
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 533 B |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 180 B |
|
After Width: | Height: | Size: 261 B |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 192 B |
|
After Width: | Height: | Size: 211 B |
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <cglm/cglm.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -8,7 +8,6 @@ GameStage_new ()
|
||||
g->ui_context->tooltip = PMUID ("tooltip");
|
||||
|
||||
g->world = World_new ();
|
||||
g->camera = g_new0 (Camera, 1);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
#include "stage_common.h"
|
||||
|
||||
#include "../gvar.h"
|
||||
#include "../camera.h"
|
||||
#include "../profiler.h"
|
||||
#include "../graphics.h"
|
||||
|
||||
|
||||
GameStage *stage_ingame_new ();
|
||||
|
||||
@@ -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); */
|
||||
/* } */
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "stage_common.h"
|
||||
|
||||
#include "../gvar.h"
|
||||
#include "../camera.h"
|
||||
#include "../profiler.h"
|
||||
#include "../graphics.h"
|
||||
|
||||
GameStage *stage_mapeditor_new ();
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||