From 5659a1baba94d10f76e72c8bbb9fa7576ab4f19b Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Wed, 6 Apr 2016 00:26:28 +0200 Subject: Proper console, run-time sim editing. --- src/common.h | 1 + src/console.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++------- src/console.h | 11 ++- src/main.c | 39 +++++----- src/physics.c | 110 +++++++++++++++++++--------- src/physics.h | 15 ++-- src/renderer.c | 12 ++++ src/ui.c | 152 +++++++++++++++++++++++++++++++-------- src/ui.h | 1 + 9 files changed, 449 insertions(+), 114 deletions(-) diff --git a/src/common.h b/src/common.h index 9dc85e9..86d98ad 100644 --- a/src/common.h +++ b/src/common.h @@ -1,6 +1,7 @@ #ifndef _COMMON_H #define _COMMON_H +#define _GNU_SOURCE #include #include #include diff --git a/src/console.c b/src/console.c index 13e33f7..d415500 100644 --- a/src/console.c +++ b/src/console.c @@ -1,14 +1,37 @@ #include "console.h" -#include +#include +#include -typedef struct con_var_s con_var_t; +typedef struct con_var_s con_var; struct con_var_s { char *name; char *value; - con_var_t *next; + con_var *next; }; -con_var_t *con_vars[256]; +con_var *con_vars[256]; +phy_sim *con_sim; + +int con_init(phy_sim *sim) +{ + con_var_set("test", "7"); + con_sim = sim; + return 0; +} + +void con_quit(void) +{ + size_t i; + con_var *var, *next; + + for (i = 0; i < 256; i++) + for (var = con_vars[i]; var; var = next) { + next = var->next; + free(var->name); + free(var->value); + free(var); + } +} size_t con_var_hash(char *text) { @@ -21,10 +44,10 @@ size_t con_var_hash(char *text) return rv & 0xFF; } -con_var_t *con_var_find(char *name, size_t *ret_hash) +con_var *con_var_find(char *name, size_t *ret_hash) { size_t hash; - con_var_t *var; + con_var *var; hash = con_var_hash(name); @@ -38,16 +61,16 @@ con_var_t *con_var_find(char *name, size_t *ret_hash) return NULL; } -con_var_t *con_var_add(char *name) +con_var *con_var_add(char *name) { - con_var_t *var; + con_var *var; size_t hash; var = con_var_find(name, &hash); if (var) return var; - var = malloc(sizeof(con_var_t)); + var = malloc(sizeof(con_var)); assert(var); var->next = con_vars[hash]; @@ -63,7 +86,7 @@ con_var_t *con_var_add(char *name) void con_var_set(char *name, char *value) { - con_var_t *var; + con_var *var; var = con_var_add(name); @@ -78,7 +101,7 @@ void con_var_set(char *name, char *value) char *con_var_get(char *name) { - con_var_t *var; + con_var *var; var = con_var_find(name, NULL); if (!var) @@ -106,32 +129,183 @@ size_t con_var_get_size(char *name) if (!str) return 0; - return strtoul(name, NULL, 10); + return strtoul(str, NULL, 10); } -int con_init(void) +typedef struct { + char *name; + + char *(*func)(char*); +} con_cmd; + +char *cmd_load(char *arg) { - con_var_set("kurwa", "chuj"); - return 0; + FILE *fp; + char line[1024]; + + fp = fopen(arg, "r"); + if (!fp) + return va("%s: %s", arg, strerror(errno)); + + while (fgets(line, sizeof(line), fp)) { + con_exec(line, NULL); + } + + fclose(fp); + return va("Załadowano plik %s", arg); } +char *cmd_get(char *arg) +{ + if (!arg) + return "Brak argumentu"; -void con_quit(void) + return va("%s = \"%s\"", arg, con_var_get(arg)); +} + +char *cmd_getf(char *arg) +{ + if (!arg) + return "Brak argumentu"; + + return va("%s = %f", arg, con_var_get_float(arg)); +} + +char *cmd_getz(char *arg) +{ + if (!arg) + return "Brak argumentu"; + + return va("%s = %zu", arg, con_var_get_size(arg)); +} + +char *cmd_pause(char *arg) { + itc_chan_push(&con_sim->ctl, PHY_CMD_PAUSE, NULL); + return "Symulacja wstrzymana"; } +char *cmd_reset(char *arg) +{ + itc_chan_push(&con_sim->ctl, PHY_CMD_RESET, NULL); + return "Symulacja ustawiona ponownie"; +} +char *cmd_resume(char *arg) +{ + itc_chan_push(&con_sim->ctl, PHY_CMD_RESUME, NULL); + return "Symulacja wznowiona"; +} -int con_thread_f(phy_sim *sim) +char *cmd_zero(char *arg) { - printf("%f\n", con_var_get_float("kurwa")); + itc_chan_push(&con_sim->ctl, PHY_CMD_ZERO, NULL); + return "Symulacja wyzerowana"; +} + + +static const con_cmd con_cmds[] = { + {"get", cmd_get}, + {"getf", cmd_getf}, + {"getz", cmd_getz}, + {"load", cmd_load}, + {"pause", cmd_pause}, + {"reset", cmd_reset}, + {"resume", cmd_resume}, + {"zero", cmd_zero}, +}; + +int con_cmd_cmp(const void *a, const void *b) +{ + return strcmp(a, ((const con_cmd*)b)->name); +} + +void con_exec(char *str, itc_chan *feedback) +{ + char *p, *r, *cmd_str, *arg, *response = NULL; + con_cmd *cmd; + char *(*func)(char*) = NULL; + + p = str; + while (*p && isspace(*p)) + p++; + + if (!*p) + return; - while (1) { - char *line; + r = p; - line = readline("(cem) "); - printf("line=%s\n", line); + while (*p && !isspace(*p)) + p++; + + cmd_str = strndup(r, p - r); + assert(cmd_str); + + while (*p && isspace(*p)) + p++; + + if (!*p) + arg = NULL; + else { + int len; + + len = strlen(p); + + if (p[len - 1] == '\n') + arg = strndup(p, len - 1); + else + arg = strndup(p, len); + + assert(arg); } - - return 0; + + cmd = bsearch(cmd_str, con_cmds, sizeof(con_cmds) / sizeof(con_cmd), + sizeof(con_cmd), con_cmd_cmp); + + if (!cmd) { + con_var *var; + + var = con_var_find(cmd_str, NULL); + if (!var) + assert(asprintf(&response, "Nieznane polecenie: %s", + cmd_str) != -1); + else if (arg) { + con_var_set(cmd_str, arg); + assert(asprintf(&response, "%s <- %s", cmd_str, arg) + != -1); + } + else { + void *tmp; + + func = cmd_get; + + tmp = cmd_str; + cmd_str = arg; + arg = tmp; + } + } else + func = cmd->func; + + if (func) { + response = func(arg); + if (response) { + response = strdup(response); + assert(response); + } + } + + if (response) { + if (cmd) + printf("con_exec: %s: %s\n", cmd_str, response); + else + printf("con_exec: %s\n", response); + + if (feedback) + itc_chan_push(feedback, CMD_CON_FEEDBACK, response); + else + free(response); + } + + free(cmd_str); + free(arg); } diff --git a/src/console.h b/src/console.h index 2204ce9..5086906 100644 --- a/src/console.h +++ b/src/console.h @@ -1,6 +1,13 @@ #include "common.h" #include "physics.h" -int con_init(void); +int con_init(phy_sim *sim); void con_quit(void); -int con_thread_f(phy_sim *sim); + +void con_var_set(char *name, char *value); +char *con_var_get(char *name); +float con_var_get_float(char *name); +size_t con_var_get_size(char *name); + +void con_exec(char *str, itc_chan *feedback); +#define CMD_CON_FEEDBACK 1337 diff --git a/src/main.c b/src/main.c index f30238c..84ec3eb 100644 --- a/src/main.c +++ b/src/main.c @@ -7,12 +7,22 @@ #include "ui.h" #include "console.h" + +//TEST +#include + int main(void) { int rv = 0; r_window *first_window; phy_sim sim; - SDL_Thread *sim_thread, *con_thread; + SDL_Thread *sim_thread = NULL; + + if (con_init(&sim)) { + con_printf("fatal error: console initialization failed\n"); + rv = 1; + goto quit; + } if (r_init()) { con_printf("fatal error: renderer initialization failed\n"); @@ -53,21 +63,6 @@ int main(void) goto quit; } - if (con_init()) { - con_printf("fatal error: console initialization failed\n"); - rv = 1; - goto quit; - } - - con_thread = SDL_CreateThread((SDL_ThreadFunction)con_thread_f, - "con_thread", &sim); - if (!con_thread) { - con_printf("fatal error: SDL_CreateThread failed: %s\n", - SDL_GetError()); - rv = 1; - goto quit; - } - while (1) { SDL_Event event; @@ -84,12 +79,16 @@ int main(void) quit: con_printf("main: exitting, rv=%i\n", rv); - itc_chan_push(&sim.ctl, PHY_CMD_QUIT, NULL); - SDL_WaitThread(sim_thread, NULL); - phy_sim_destroy(&sim); - ui_quit(); r_quit(); + + if (sim_thread) { + itc_chan_push(&sim.ctl, PHY_CMD_QUIT, NULL); + SDL_WaitThread(sim_thread, NULL); + } + + phy_sim_destroy(&sim); + con_quit(); SDL_Quit(); return rv; } diff --git a/src/physics.c b/src/physics.c index 0925664..fedc4c4 100644 --- a/src/physics.c +++ b/src/physics.c @@ -2,20 +2,6 @@ #include "itc.h" #include "physics.h" -void phy_sim_destroy(phy_sim *sim) -{ - size_t i; - - SDL_DestroyMutex(sim->rotate_lock); - - itc_chan_destroy(&sim->ctl); - - for (i = 0; i < 3; i++) { - free(sim->fields[i].E); - free(sim->fields[i].H); - } -} - static void phy_calc_fc(float *fc, size_t *x, size_t *widths, size_t *dims, float dt, float offset) { @@ -74,7 +60,7 @@ static float remap(float x, float a0, float b0, float a1, float b1) return (x - a0) * (b1 - a1) / (b0 - a0) + a1; } -void phy_sim_reset_aux(phy_sim *sim) +static void phy_sim_zero_aux(phy_sim *sim) { size_t x[3]; phy_field_info *fi = &sim->field_info; @@ -131,7 +117,7 @@ void phy_sim_reset_aux(phy_sim *sim) } } -void phy_sim_reset(phy_sim *sim) +static void phy_sim_zero(phy_sim *sim) { size_t i; phy_field_info *fi; @@ -143,7 +129,7 @@ void phy_sim_reset(phy_sim *sim) memset(sim->fields[i].H, 0, fi->size * sizeof(float)); } - phy_sim_reset_aux(sim); + phy_sim_zero_aux(sim); sim->time = 0; sim->running = false; @@ -151,22 +137,54 @@ void phy_sim_reset(phy_sim *sim) } int phy_sim_create(phy_sim *sim) +{ + memset(sim, 0, sizeof(phy_sim)); + + sim->rotate_lock = SDL_CreateMutex(); + assert(sim->rotate_lock); + itc_chan_create(&sim->ctl); + + con_var_set("width", "50"); + con_var_set("height", "50"); + con_var_set("depth", "50"); + con_var_set("scale", "7e+9"); + con_var_set("time_delta", "0.1"); + + phy_sim_create_fields(sim); + + return 0; +} + +void phy_sim_destroy(phy_sim *sim) { size_t i; - phy_field_info *fi; - memset(sim, 0, sizeof(phy_sim)); + SDL_DestroyMutex(sim->rotate_lock); + + itc_chan_destroy(&sim->ctl); + + for (i = 0; i < 3; i++) { + free(sim->fields[i].E); + free(sim->fields[i].H); + } +} + +int phy_sim_create_fields(phy_sim *sim) +{ + size_t i; + phy_field_info *fi; fi = &sim->field_info; - fi->dims[0] = 50; - fi->dims[1] = 50; - fi->dims[2] = 50; - fi->spacing = 7e+9f / min3(fi->dims[0], fi->dims[1], fi->dims[2]); - sim->time_delta = 0.10f; + fi->dims[0] = con_var_get_size("width"); + fi->dims[1] = con_var_get_size("height"); + fi->dims[2] = con_var_get_size("depth"); + fi->spacing = con_var_get_float("scale") / + min3(fi->dims[0], fi->dims[1], fi->dims[2]); + sim->time_delta = con_var_get_float("time_delta"); - printf("phy_sim_create: Courant number is %f\n", - 3 * LIGHT_SPEED * sim->time_delta / fi->spacing); + con_var_set("courant", va("%f", 3 * LIGHT_SPEED * sim->time_delta / + fi->spacing)); #if 0 sim->pml_widths[0] = 0; @@ -199,31 +217,46 @@ int phy_sim_create(phy_sim *sim) sim->fields[i].E = malloc(fi->size * sizeof(float)); sim->fields[i].H = malloc(fi->size * sizeof(float)); if (!sim->fields[i].E || !sim->fields[i].H) { - con_printf("phy_sim_create: out of memory\n"); + con_printf("phy_sim_create_fields: out of memory\n"); goto error; } } sim->aux = malloc(fi->size1 * sizeof(phy_field_aux_point)); if (!sim->aux) { - con_printf("phy_sim_create: out of memory\n"); + con_printf("phy_sim_create_fields: out of memory\n"); goto error; } - phy_sim_reset(sim); + phy_sim_zero(sim); - itc_chan_create(&sim->ctl); sim->running = false; + sim->valid = true; - sim->rotate_lock = SDL_CreateMutex(); - assert(sim->rotate_lock); return 0; error: - phy_sim_destroy(sim); + phy_sim_destroy_fields(sim); return 1; } +void phy_sim_destroy_fields(phy_sim *sim) +{ + size_t i; + + for (i = 0; i < 3; i++) { + free(sim->fields[i].E); + sim->fields[i].E = NULL; + free(sim->fields[i].H); + sim->fields[i].H = NULL; + } + + free(sim->aux); + sim->aux = NULL; + + sim->valid = false; +} + static float gauss(phy_source_xyplane *s, float t) { return sin(t); //exp(-s->lambda * sq(t - s->time)); @@ -494,14 +527,21 @@ void phy_run_command(phy_sim *sim, int number, void *data) phy_sim_step(sim); break; - case PHY_CMD_RESET: - phy_sim_reset(sim); + case PHY_CMD_ZERO: + phy_sim_zero(sim); break; case PHY_CMD_DEBUG: phy_sim_debug(sim, data); free(data); break; + + case PHY_CMD_RESET: + SDL_LockMutex(sim->rotate_lock); + phy_sim_destroy_fields(sim); + phy_sim_create_fields(sim); + SDL_UnlockMutex(sim->rotate_lock); + break; } } diff --git a/src/physics.h b/src/physics.h index 04744ee..60db8bf 100644 --- a/src/physics.h +++ b/src/physics.h @@ -2,7 +2,7 @@ #define _PHYSICS_H #include "common.h" -#include "itc.h" +#include "itc.h" #define LIGHT_SPEED (299792458.0f) #define MU_ZERO (4.0f * M_PI * 1e-7f) @@ -47,11 +47,14 @@ enum { PHY_CMD_PAUSE, PHY_CMD_RESUME, PHY_CMD_STEP, - PHY_CMD_RESET, - PHY_CMD_DEBUG + PHY_CMD_ZERO, + PHY_CMD_DEBUG, + PHY_CMD_RESET }; typedef struct { + bool valid; + phy_field_info field_info; phy_field_em fields[3]; phy_field_aux_point *aux; @@ -68,8 +71,12 @@ typedef struct { int64_t step_real_time; } phy_sim; -void phy_sim_destroy(phy_sim *sim); +#include "console.h" + int phy_sim_create(phy_sim *sim); +void phy_sim_destroy(phy_sim *sim); +int phy_sim_create_fields(phy_sim *sim); +void phy_sim_destroy_fields(phy_sim *sim); void phy_sim_compute_const_fields(phy_sim *sim); void phy_sim_step(phy_sim *sim); diff --git a/src/renderer.c b/src/renderer.c index 3f01e88..d68287c 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -327,6 +327,12 @@ static int r_xsection_alloc(SDL_Renderer *renderer, SDL_Texture **texture, int old_width, old_height; if (*texture) { + if (!width || !height) { + SDL_DestroyTexture(*texture); + *texture = NULL; + return 0; + } + SDL_QueryTexture(*texture, NULL, NULL, &old_width, &old_height); if (old_width != width || old_height != height) { @@ -335,6 +341,9 @@ static int r_xsection_alloc(SDL_Renderer *renderer, SDL_Texture **texture, } } + if (!width || !height) + return 0; + if (!*texture) { *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGR888, SDL_TEXTUREACCESS_STREAMING, @@ -405,6 +414,9 @@ int r_xsection_update(r_window *rw, r_xsection *xsection, phy_sim *sim, return 1; } + if (!width || !height) + return 0; + SDL_LockTexture(xsection->texture, NULL, (void**)&pixels, &pitch); if (flags & XSECTION_XY) { diff --git a/src/ui.c b/src/ui.c index 4c02e53..5b58be7 100644 --- a/src/ui.c +++ b/src/ui.c @@ -8,7 +8,8 @@ struct { float color_main[4]; float color_light[4]; float color_info[4]; - float color_select[4]; + float color_select[4]; + float color_background_console[4]; } theme = { .font_size = 20, @@ -18,10 +19,12 @@ struct { .color_main = {0.75, 0.75, 0.75, 1}, .color_light = {0.85, 0.85, 0.85, 1}, .color_info = {1, 1, 1, 1}, - .color_select = {1, 0, 0, 1} + .color_select = {1, 0, 0, 1}, + .color_background_console = {1.0, 0.7, 0.0, 0.6} }; #define MAX_INFO 1024 +#define MAX_CONSOLE 1023 typedef struct { phy_sim *sim; @@ -32,9 +35,6 @@ typedef struct { bool select_valid; vec3_t select; - int64_t info_time; - char info[MAX_INFO]; - float margin_bottom, margin_top; mst2_t origin, scale; // in virtual space @@ -59,6 +59,14 @@ struct ui_window_s { ui_window_type type; ui_simview simview; + + itc_chan ctl; + char console[MAX_CONSOLE + 1]; + int console_len; + bool show_console; + + int64_t info_time; + char info[MAX_INFO]; }; static struct { @@ -87,6 +95,7 @@ static void ui_window_destroy(ui_window *uiw) uis.windows = uiw->next; r_xsection_destroy(&uiw->simview.xsection); + itc_chan_destroy(&uiw->ctl); free(uiw); } @@ -117,6 +126,7 @@ void ui_renderer_window_register(r_window *rw) ", uiw = %p\n", SDL_GetWindowID(rw->window), uiw); r_xsection_create(&uiw->simview.xsection); + itc_chan_create(&uiw->ctl); } static ui_window *ui_find_window(int id) @@ -135,10 +145,67 @@ void ui_infof(ui_window *uiw, const char *fmt, ...) va_list vl; va_start(vl, fmt); - vsnprintf(uiw->simview.info, MAX_INFO, fmt, vl); + vsnprintf(uiw->info, MAX_INFO, fmt, vl); va_end(vl); - uiw->simview.info_time = get_time(); + uiw->info_time = get_time(); +} + +void ui_console_add(ui_window *uiw, char *ch) +{ + int add_len; + + add_len = strlen(ch); + + if (!add_len || *ch == 1) // wtf is \x01 ? + return; + + if (uiw->console_len + add_len > MAX_CONSOLE) + return; + + memcpy(uiw->console + uiw->console_len, ch, add_len); + uiw->console_len += add_len; + uiw->console[uiw->console_len] = 0; +} + +void ui_console_erase(ui_window *uiw) +{ + char *p; + + if (!uiw->console_len) + return; + + p = uiw->console + uiw->console_len - 1; + + while (p > uiw->console && ((*p) & 0b11000000) == 0b10000000) + p--; + + uiw->console_len = p - uiw->console; + *p = 0; +} + +void ui_event_console(SDL_Event *event, ui_window *uiw) +{ + switch (event->type) { + case SDL_KEYDOWN: + switch (event->key.keysym.sym) { + case SDLK_BACKSPACE: + ui_console_erase(uiw); + break; + + case SDLK_RETURN: + con_exec(uiw->console, &uiw->ctl); + uiw->console[0] = 0; + uiw->console_len = 0; + uiw->show_console = false; + SDL_StopTextInput(); + break; + } + + case SDL_TEXTINPUT: + ui_console_add(uiw, event->text.text); + break; + } } void ui_event_window(SDL_Event *event, ui_window *uiw) @@ -148,6 +215,20 @@ void ui_event_window(SDL_Event *event, ui_window *uiw) if (!uiw->initialized) return; + if (uiw->show_console) { + ui_event_console(event, uiw); + return; + } + + if (event->type == SDL_KEYDOWN && + event->key.keysym.sym == SDLK_RETURN) { + uiw->show_console = true; + SDL_StartTextInput(); + } + + if (!uiw->simview.sim->valid) + return; + switch (event->type) { case SDL_MOUSEWHEEL: { @@ -255,11 +336,6 @@ void ui_event_window(SDL_Event *event, ui_window *uiw) itc_chan_push(&sv->sim->ctl, PHY_CMD_STEP, NULL); break; - case SDLK_r: - ui_infof(uiw, "Symulacja wyzerowana"); - itc_chan_push(&sv->sim->ctl, PHY_CMD_RESET, NULL); - break; - case SDLK_4: ui_infof(uiw, "Przekrój: pola elektrycznego"); sv->xsection_flags &= ~XSECTION_H; @@ -287,8 +363,8 @@ void ui_event_window(SDL_Event *event, ui_window *uiw) itc_chan_push(&sv->sim->ctl, PHY_CMD_DEBUG, coords); - break; } + break; } } } @@ -296,7 +372,7 @@ void ui_event_window(SDL_Event *event, ui_window *uiw) void ui_event(SDL_Event *event) { if (event->type == SDL_KEYDOWN && - event->key.keysym.sym == SDLK_RETURN) { + event->key.keysym.sym == SDLK_F3) { if (!uis.use_window_open_timer || uis.window_open_timer + 500000000 <= get_time()) { @@ -333,11 +409,6 @@ void ui_event(SDL_Event *event) } } -void ui_animate_exp(float *val, float targ, float lambda, float dt) -{ - *val = targ + (*val - targ) * exp(-lambda * dt); -} - void ui_draw_simview_xsection(ui_window *uiw) { ui_simview *sv = &uiw->simview; @@ -515,18 +586,16 @@ void ui_draw_simview_bars(ui_window *uiw, float dt) SDL_mutexV(sim->rotate_lock); } -void ui_draw_simview_info(ui_window *uiw, int64_t time) +void ui_draw_info(ui_window *uiw, int64_t time) { - ui_simview *sv = &uiw->simview; - - if (sv->info_time && sv->info_time + 2000000000ll > time) + if (uiw->info_time && uiw->info_time + 3000000000ll > time) { vec4_t color; - if (sv->info_time + 1000000000ll >= time) + if (uiw->info_time + 2000000000ll >= time) color[3] = 1.0f; else - color[3] = 1.0f - (time - sv->info_time - 1000000000ll) + color[3] = 1.0f - (time - uiw->info_time - 2000000000ll) / 1.0e9f; v3_copy(color, theme.color_info); @@ -537,16 +606,31 @@ void ui_draw_simview_info(ui_window *uiw, int64_t time) v3_copy(color, theme.color_text); r_draw_text(uiw->rw, uiw->w / 2.0f, theme.font_size, - theme.font_size, sv->info, color, TEXT_CENTERX); + theme.font_size, uiw->info, color, TEXT_CENTERX); } } void ui_draw_simview(ui_window *uiw, int64_t time, float dt) { + if (!uiw->simview.sim->valid) + return; + ui_draw_simview_xsection(uiw); ui_draw_simview_selection(uiw); ui_draw_simview_bars(uiw, dt); - ui_draw_simview_info(uiw, time); +} + +void ui_draw_console(ui_window *uiw) +{ + float y; + + y = uiw->h / 2 - theme.font_size / 2; + + r_draw_rect(uiw->rw, 0, y, uiw->w, theme.font_size, + theme.color_background_console); + + r_draw_text(uiw->rw, 0, y, theme.font_size, uiw->console, + theme.color_text, 0); } void ui_draw_window(ui_window *uiw) @@ -554,9 +638,18 @@ void ui_draw_window(ui_window *uiw) ui_simview *sv = &uiw->simview; int64_t time; float dt; + int cmd_num; + char *cmd_data; time = get_time(); + while (!itc_chan_pop(&uiw->ctl, &cmd_num, (void**)&cmd_data)) { + if (cmd_num == CMD_CON_FEEDBACK) { + ui_infof(uiw, "%s", cmd_data); + free(cmd_data); + } + } + if (!uiw->initialized) { uiw->initialized = true; uiw->last_frame = time; @@ -570,8 +663,6 @@ void ui_draw_window(ui_window *uiw) sv->margin_top = theme.font_size; sv->margin_bottom = 0; - sv->info_time = 0; - r_clear(uiw->rw, r_color_black); return; } @@ -580,6 +671,9 @@ void ui_draw_window(ui_window *uiw) r_clear(uiw->rw, r_color_black); ui_draw_simview(uiw, time, dt); + if (uiw->show_console) + ui_draw_console(uiw); + ui_draw_info(uiw, time); r_flip(uiw->rw); uiw->last_frame = time; diff --git a/src/ui.h b/src/ui.h index 73b355b..e114560 100644 --- a/src/ui.h +++ b/src/ui.h @@ -4,6 +4,7 @@ #include "common.h" #include "renderer.h" #include "physics.h" +#include "console.h" int ui_init(void); void ui_quit(void); -- cgit