more guile features
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
(use-modules (ice-9 format))
|
||||
|
||||
(define (widget-checkbox-icon-switch widget event)
|
||||
(if (= (widget-get-icon widget) 1)
|
||||
(widget-set-icon! widget 2)
|
||||
@@ -14,13 +16,35 @@
|
||||
#: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)))))
|
||||
|
||||
(define (widget-spinner . args)
|
||||
(define (coerce type val)
|
||||
(cond
|
||||
((eq? type 'int) (inexact->exact (round val)))
|
||||
((eq? type 'bool) (if (> val 0.5) #t #f))
|
||||
(else val)))
|
||||
|
||||
(define (widget-spinner type fmt gvar . args)
|
||||
(apply
|
||||
widget-new
|
||||
(append
|
||||
(list 'container #:horizontal #t #:layout-spacing 8)
|
||||
args
|
||||
(list
|
||||
(widget-new 'plain #:style style-icon-button #:icon 3 #:aspect-ratio 1)
|
||||
(widget-new 'label #:style style-default #:layout-weight 1)
|
||||
(widget-new 'plain #:style style-icon-button #:icon 4 #:aspect-ratio 1)))))
|
||||
(widget-new 'plain #:style style-icon-button #:icon 3 #: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
|
||||
#:on-click (lambda (w e)
|
||||
(gvar-set gvar (+ (gvar-get gvar) 1))))))))
|
||||
|
||||
(define (widget-label-gvar type fmt gvar . args)
|
||||
(apply
|
||||
widget-new
|
||||
(append
|
||||
(list 'label
|
||||
#:on-tick
|
||||
(lambda (w e)
|
||||
(widget-set-text! w (apply format #f fmt (list (coerce type (gvar-get gvar)))))))
|
||||
args)))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(use-modules (ice-9 format))
|
||||
;; The function is evaulated and returns a pointer, the game eats it
|
||||
;; and adds it to the UI root. Boom.
|
||||
(gvar-set "Some crap" 100.0)
|
||||
|
||||
(widget-new
|
||||
'window
|
||||
#:style style-window
|
||||
@@ -17,9 +16,9 @@
|
||||
#:layout-padding 8
|
||||
#:layout-spacing 8
|
||||
#:horizontal #t
|
||||
(widget-label-gvar 'float "Delta time: ~,2f" "delta_time" #:style style-default #:layout-weight 1 #:h 20 #:text-alignment 'center)
|
||||
(widget-label-gvar 'int "Chunks: ~d" "frame_chunks" #:style style-default #:layout-weight 0.5 #:h 20)
|
||||
(widget-label-gvar 'int "Entities: ~d" "frame_entities" #:style style-default #:layout-weight 0.5 #:h 20)
|
||||
(widget-checkbox "Flight" "flight_enabled" #:layout-weight 0.5 #:h 20)
|
||||
(widget-checkbox "Wireframe" "wireframe_enabled" #:layout-weight 0.5 #:h 20)
|
||||
(widget-new 'label #:style style-default #:layout-weight 1 #:h 20
|
||||
#:on-tick (lambda (w e) (widget-set-text! w (number->string (gvar-get "Some crap")))))
|
||||
(widget-spinner #:layout-weight 1 #:h 20)
|
||||
(widget-new 'entry #:style style-default #:layout-weight 1 #:h 20 #:text "Enter text...")))
|
||||
(widget-spinner 'int "Render distance: ~d" "render_distance" #:layout-weight 1 #:h 20)))
|
||||
|
||||
+12
-12
@@ -1,9 +1,5 @@
|
||||
#include "chunkman.h"
|
||||
|
||||
extern int render_distance;
|
||||
|
||||
int n_frame_chunks;
|
||||
|
||||
static GHashTable *chunks;
|
||||
static GHashTable *chunk_meshes;
|
||||
|
||||
@@ -112,6 +108,8 @@ chunkman_tick (vec3 position)
|
||||
uint64_t start = SDL_GetPerformanceCounter ();
|
||||
uint64_t freq = SDL_GetPerformanceFrequency ();
|
||||
double elapsed_us = 0;
|
||||
|
||||
int render_distance = gvar_get ("render_distance");
|
||||
|
||||
for (int z = cz - render_distance - 1; z <= cz + render_distance + 1; ++z)
|
||||
{
|
||||
@@ -148,9 +146,9 @@ chunkman_tick (vec3 position)
|
||||
{
|
||||
chunkman_generate_ChunkMesh_at (x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
chunkman_render (vec3 position, vec4 planes[6])
|
||||
@@ -170,7 +168,8 @@ chunkman_render (vec3 position, vec4 planes[6])
|
||||
texture_use (RESTEX ("terrain3"), 3);
|
||||
texture_use (RESTEX ("terrain4"), 4);
|
||||
|
||||
n_frame_chunks = 0;
|
||||
int render_distance = gvar_get ("render_distance");
|
||||
int frame_chunks = 0;
|
||||
|
||||
for (int z = cz - render_distance; z <= cz + render_distance; ++z)
|
||||
{
|
||||
@@ -178,9 +177,9 @@ chunkman_render (vec3 position, vec4 planes[6])
|
||||
{
|
||||
/* Render in a circle instead of a square. */
|
||||
if ((x - cx) * (x - cx) + (z - cz) * (z - cz) > render_distance*render_distance)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ChunkMesh *mesh = chunkman_get_ChunkMesh_at (x, z);
|
||||
if (mesh != NULL)
|
||||
@@ -205,12 +204,13 @@ chunkman_render (vec3 position, vec4 planes[6])
|
||||
|
||||
program_set_vec3_ind (RESPRG ("chunk"), "chunk_position", x * CHUNK_DIM, 0.0, z * CHUNK_DIM);
|
||||
ChunkMesh_render (mesh, FLAG_GET ("wireframe_enabled"));
|
||||
n_frame_chunks++;
|
||||
frame_chunks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bound = false;
|
||||
bound = false;
|
||||
gvar_set ("frame_chunks", frame_chunks);
|
||||
}
|
||||
|
||||
Chunk *
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
seperately somehow. */
|
||||
|
||||
extern vec3 camera_position;
|
||||
extern int render_distance;
|
||||
|
||||
Entity *player_entity, *sky_entity;
|
||||
int n_frame_ents;
|
||||
|
||||
/* The GArray is the fastest of all sequence types. Should work fine
|
||||
for a billion entities. */
|
||||
@@ -108,7 +106,7 @@ entman_tick ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gboolean
|
||||
entman_render_entity (Entity *entity, void *userdata)
|
||||
{
|
||||
struct {
|
||||
@@ -120,9 +118,10 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
|
||||
if (!entity->visible)
|
||||
{
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int render_distance = gvar_get ("render_distance");
|
||||
/* Why an int, why int division? It's simply much faster than
|
||||
floating point operations. No need to have super accurate cull
|
||||
distance anyway, and might as well save a lot when rendering entities. */
|
||||
@@ -136,7 +135,7 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
|
||||
if (glm_vec2_distance2 (c_xz, e_xz) > cull_dist*cull_dist && !entity->dont_cull)
|
||||
{
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if FRUSTUM_CULL
|
||||
@@ -145,7 +144,7 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
|
||||
if (!glm_aabb_frustum (aabb, *vp->frustum_planes))
|
||||
{
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -234,7 +233,7 @@ entman_render_entity (Entity *entity, void *userdata)
|
||||
}
|
||||
|
||||
SimpleMesh_render (&to_render, FLAG_GET ("wireframe_enabled"));
|
||||
n_frame_ents++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -247,7 +246,6 @@ entman_render (mat4 *view, vec4 planes[6])
|
||||
last_program = -1;
|
||||
last_texture = -1;
|
||||
last_type = -1;
|
||||
n_frame_ents = 0;
|
||||
|
||||
struct {
|
||||
mat4 *view;
|
||||
@@ -261,11 +259,15 @@ entman_render (mat4 *view, vec4 planes[6])
|
||||
#endif
|
||||
};
|
||||
|
||||
int frame_entities = 0;
|
||||
|
||||
for (guint i = 0; i < entities->len; ++i)
|
||||
{
|
||||
Entity *e = g_array_index (entities, Entity*, i);
|
||||
entman_render_entity (e, &data);
|
||||
frame_entities += entman_render_entity (e, &data) ? 1 : 0;
|
||||
}
|
||||
|
||||
gvar_set ("frame_entities", frame_entities);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+15
-9
@@ -1,11 +1,8 @@
|
||||
#include "graphics.h"
|
||||
|
||||
extern vec3 camera_position;
|
||||
extern int last_time;
|
||||
|
||||
SDL_Window *sdl_window;
|
||||
int sdl_window_w = 800, sdl_window_h = 600;
|
||||
int render_distance = 2;
|
||||
|
||||
static SDL_GLContext gl_context;
|
||||
static uint64_t last_check_perf = 0;
|
||||
@@ -15,12 +12,16 @@ static double avg_elapsed = 0;
|
||||
void
|
||||
graphics_init ()
|
||||
{
|
||||
gvar_set ("render_distance", 2);
|
||||
gvar_set ("window_width", 800);
|
||||
gvar_set ("window_height", 600);
|
||||
|
||||
if (!SDL_Init (SDL_INIT_VIDEO))
|
||||
{
|
||||
g_error ("Couldn't initialize SDL: %s", SDL_GetError ());
|
||||
}
|
||||
|
||||
sdl_window = SDL_CreateWindow (GAME_NAME, sdl_window_w, sdl_window_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||
sdl_window = SDL_CreateWindow (GAME_NAME, gvar_get ("window_width"), gvar_get ("window_height"), SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||
|
||||
if (!sdl_window)
|
||||
{
|
||||
@@ -50,7 +51,7 @@ graphics_init ()
|
||||
g_info ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
|
||||
g_info ("Max vertex attributes: %d", GL_MAX_VERTEX_ATTRIBS);
|
||||
|
||||
glViewport (0, 0, sdl_window_w, sdl_window_h);
|
||||
glViewport (0, 0, gvar_get ("window_width"), gvar_get ("window_height"));
|
||||
glClearColor (0, 0.3, 0.8, 1);
|
||||
|
||||
glEnable (GL_CULL_FACE);
|
||||
@@ -68,12 +69,12 @@ graphics_render ()
|
||||
uint64_t freq = SDL_GetPerformanceFrequency ();
|
||||
|
||||
mat4 projection, view;
|
||||
camera_get_projection ((float) sdl_window_w / (float) sdl_window_h, projection);
|
||||
camera_get_projection (gvar_get ("window_width") / gvar_get ("window_height"), projection);
|
||||
camera_get_view (view);
|
||||
|
||||
resources_programs_set_mat4 ("projection", &projection);
|
||||
resources_programs_set_mat4 ("view", &view);
|
||||
resources_programs_set_float ("time", last_time);
|
||||
resources_programs_set_float ("time", gvar_get ("last_time"));
|
||||
|
||||
vec4 planes[6];
|
||||
#if FRUSTUM_CULL
|
||||
@@ -102,17 +103,19 @@ graphics_render ()
|
||||
avg_elapsed += elapsed_us;
|
||||
avg_counter++;
|
||||
|
||||
int render_distance = gvar_get ("render_distance");
|
||||
|
||||
if ((now - last_check_perf) >= freq * RENDER_AVG_FREQ_S)
|
||||
{
|
||||
double avg = avg_elapsed / avg_counter;
|
||||
|
||||
if (avg < RENDER_FRAME_BUDGET_US && render_distance < RENDER_DISTANCE_MAX)
|
||||
{
|
||||
render_distance++;
|
||||
gvar_set ("render_distance", ++render_distance);
|
||||
}
|
||||
else if (avg > RENDER_FRAME_BUDGET_US && render_distance > RENDER_DISTANCE_MIN)
|
||||
{
|
||||
render_distance--;
|
||||
gvar_set ("render_distance", --render_distance);
|
||||
}
|
||||
|
||||
avg_elapsed = 0;
|
||||
@@ -133,8 +136,11 @@ gboolean
|
||||
graphics_cb_window_resize (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (event, data);
|
||||
int sdl_window_w, sdl_window_h;
|
||||
SDL_GetWindowSizeInPixels (sdl_window, &sdl_window_w, &sdl_window_h);
|
||||
glViewport (0, 0, sdl_window_w, sdl_window_h);
|
||||
gvar_set ("window_width", sdl_window_w);
|
||||
gvar_set ("window_height", sdl_window_h);
|
||||
/* Since other subsystems might want to use the event. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "state.h"
|
||||
#include "resources.h"
|
||||
#include "util.h"
|
||||
#include "gvar.h"
|
||||
|
||||
#define FRUSTUM_CULL 1
|
||||
|
||||
|
||||
+2
-2
@@ -23,10 +23,10 @@ SDL_AppInit (void **appstate, int argc, char **argv)
|
||||
scm_init_guile ();
|
||||
gvar_guile_register ();
|
||||
widget_guile_register ();
|
||||
|
||||
|
||||
gvar_init ();
|
||||
graphics_init ();
|
||||
resources_init ();
|
||||
gvar_init ();
|
||||
evtman_init ();
|
||||
uiman_init ();
|
||||
chunkman_init ();
|
||||
|
||||
+5
-6
@@ -4,22 +4,21 @@ extern vec3 camera_position;
|
||||
extern vec3 camera_rotation;
|
||||
extern Entity *player_entity, *sky_entity;
|
||||
|
||||
float delta_time;
|
||||
int last_time;
|
||||
|
||||
void
|
||||
game_state_init (int ticks)
|
||||
{
|
||||
last_time = ticks;
|
||||
gvar_set ("last_time", ticks);
|
||||
}
|
||||
|
||||
void
|
||||
game_state_tick (int ticks)
|
||||
{
|
||||
/* Caluclate stuff per frame. */
|
||||
delta_time = (ticks - last_time) / 1000.0;
|
||||
last_time = ticks;
|
||||
gvar_set ("delta_time", (ticks - gvar_get ("last_time")) / 1000.0);
|
||||
gvar_set ("last_time", ticks);
|
||||
|
||||
float delta_time = gvar_get ("delta_time");
|
||||
|
||||
/* We pin the camera to the player position, with eye level 20
|
||||
centimeters below the height. */
|
||||
glm_vec3_copy (player_entity->position, camera_position);
|
||||
|
||||
+6
-7
@@ -1,7 +1,6 @@
|
||||
#include "uiman.h"
|
||||
|
||||
extern SDL_Window *sdl_window;
|
||||
extern int sdl_window_w, sdl_window_h;
|
||||
|
||||
/* UI global state variables. */
|
||||
|
||||
@@ -19,10 +18,10 @@ void
|
||||
uiman_init ()
|
||||
{
|
||||
ui_widget_mesh_init ();
|
||||
glm_ortho (0.0, sdl_window_w, sdl_window_h, 0.0, -1.0, 1.0, projection);
|
||||
glm_ortho (0.0, gvar_get ("window_width"), gvar_get ("window_height"), 0.0, -1.0, 1.0, projection);
|
||||
|
||||
ui_root = Widget_new ();
|
||||
IVEC2_SETI (ui_root->size, sdl_window_w, sdl_window_h);
|
||||
IVEC2_SETI (ui_root->size, gvar_get ("window_width"), gvar_get ("window_height"));
|
||||
|
||||
scm_c_primitive_load ("res/scripts/global/ui_styles.scm");
|
||||
scm_c_primitive_load ("res/scripts/global/ui_composites.scm");
|
||||
@@ -45,8 +44,8 @@ uiman_tick ()
|
||||
void
|
||||
uiman_render ()
|
||||
{
|
||||
Widget_render (ui_root, projection, sdl_window_h);
|
||||
Widget_render (tooltip_widget, projection, sdl_window_h);
|
||||
Widget_render (ui_root, projection, gvar_get ("window_height"));
|
||||
Widget_render (tooltip_widget, projection, gvar_get ("window_height"));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -120,8 +119,8 @@ gboolean
|
||||
uiman_cb_window_resize (SDL_Event *event, void *data)
|
||||
{
|
||||
UNUSED (event, data);
|
||||
glm_ortho (0.0, sdl_window_w, sdl_window_h, 0.0, -1.0, 1.0, projection);
|
||||
IVEC2_SETI (ui_root->size, sdl_window_w, sdl_window_h);
|
||||
glm_ortho (0.0, gvar_get ("window_width"), gvar_get ("window_height"), 0.0, -1.0, 1.0, projection);
|
||||
IVEC2_SETI (ui_root->size, gvar_get ("window_width"), gvar_get ("window_height"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
+40
-19
@@ -235,6 +235,22 @@ _wgcb_event (Widget *w, SDL_Event *event, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static inline TextAlignment
|
||||
_str_to_textalignment (const char *str)
|
||||
{
|
||||
if (!g_strcmp0 (str, "center"))
|
||||
{
|
||||
return TEXT_ALIGN_CENTER;
|
||||
}
|
||||
|
||||
if (!g_strcmp0 (str, "right"))
|
||||
{
|
||||
return TEXT_ALIGN_RIGHT;
|
||||
}
|
||||
|
||||
return TEXT_ALIGN_LEFT;
|
||||
}
|
||||
|
||||
static void
|
||||
_wgg_set_property (Widget *w, const char *key, SCM val)
|
||||
{
|
||||
@@ -345,24 +361,39 @@ _wgg_set_property (Widget *w, const char *key, SCM val)
|
||||
switch (w->kind)
|
||||
{
|
||||
case WIDGET_LABEL:
|
||||
g_string_overwrite (w->label.text, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->label.text, scm_to_utf8_string (val));
|
||||
break;
|
||||
case WIDGET_MULTILINE_TEXT:
|
||||
g_string_overwrite (w->multiline_text.text, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->multiline_text.text, scm_to_utf8_string (val));
|
||||
break;
|
||||
case WIDGET_WINDOW:
|
||||
g_string_overwrite (w->window.title, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->window.title, scm_to_utf8_string (val));
|
||||
break;
|
||||
case WIDGET_ENTRY:
|
||||
g_string_overwrite (w->entry.ghost_text, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->entry.ghost_text, scm_to_utf8_string (val));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_strcmp0 (key, "text-alignment"))
|
||||
{
|
||||
const char *s = scm_symbol_to_string (val) ? scm_to_utf8_string (scm_symbol_to_string (val)) : NULL;
|
||||
|
||||
if (s != NULL && w->kind == WIDGET_LABEL)
|
||||
{
|
||||
w->label.text_alignment = _str_to_textalignment (s);
|
||||
}
|
||||
|
||||
if (s != NULL && w->kind == WIDGET_MULTILINE_TEXT)
|
||||
{
|
||||
w->multiline_text.text_alignment = _str_to_textalignment (s);
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_strcmp0 (key, "tooltip"))
|
||||
{
|
||||
g_string_overwrite (w->tooltip, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->tooltip, scm_to_utf8_string (val));
|
||||
}
|
||||
|
||||
if (!g_strcmp0 (key, "on-tick"))
|
||||
@@ -470,14 +501,6 @@ _wg_set_icon (SCM widget_ptr, SCM icon_val)
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
static SCM
|
||||
_wg_get_child (SCM widget_ptr, SCM index_val)
|
||||
{
|
||||
Widget *w = (Widget *) scm_to_pointer (widget_ptr);
|
||||
int index = scm_to_int (index_val);
|
||||
return scm_from_pointer (g_array_index (w->children, Widget *, index), NULL);
|
||||
}
|
||||
|
||||
static SCM
|
||||
_wg_set_text (SCM widget_ptr, SCM val)
|
||||
{
|
||||
@@ -486,16 +509,16 @@ _wg_set_text (SCM widget_ptr, SCM val)
|
||||
switch (w->kind)
|
||||
{
|
||||
case WIDGET_LABEL:
|
||||
g_string_overwrite (w->label.text, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->label.text, scm_to_utf8_string (val));
|
||||
break;
|
||||
case WIDGET_MULTILINE_TEXT:
|
||||
g_string_overwrite (w->multiline_text.text, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->multiline_text.text, scm_to_utf8_string (val));
|
||||
break;
|
||||
case WIDGET_WINDOW:
|
||||
g_string_overwrite (w->window.title, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->window.title, scm_to_utf8_string (val));
|
||||
break;
|
||||
case WIDGET_ENTRY:
|
||||
g_string_overwrite (w->entry.ghost_text, 0, scm_to_utf8_string (val));
|
||||
g_string_assign (w->entry.ghost_text, scm_to_utf8_string (val));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -512,7 +535,5 @@ widget_guile_register ()
|
||||
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-child", 2, 0, 0, _wg_get_child);
|
||||
|
||||
scm_c_define_gsubr ("widget-set-text!", 2, 0, 0, _wg_set_text);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user