diff options
| author | Paweł Redman <pawel.redman@gmail.com> | 2016-04-06 00:26:28 +0200 | 
|---|---|---|
| committer | Paweł Redman <pawel.redman@gmail.com> | 2016-04-06 00:26:28 +0200 | 
| commit | 5659a1baba94d10f76e72c8bbb9fa7576ab4f19b (patch) | |
| tree | 1f096951e2233dc897c5c083eac3a700fa27ecca /src | |
| parent | c7acaee6651a84ef9102b29350c37803c8f435a9 (diff) | |
Proper console, run-time sim editing.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common.h | 1 | ||||
| -rw-r--r-- | src/console.c | 222 | ||||
| -rw-r--r-- | src/console.h | 11 | ||||
| -rw-r--r-- | src/main.c | 39 | ||||
| -rw-r--r-- | src/physics.c | 110 | ||||
| -rw-r--r-- | src/physics.h | 15 | ||||
| -rw-r--r-- | src/renderer.c | 12 | ||||
| -rw-r--r-- | src/ui.c | 152 | ||||
| -rw-r--r-- | 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 <stdio.h>  #include <stdlib.h>  #include <inttypes.h> 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 <readline/readline.h> +#include <ctype.h> +#include <errno.h> -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 @@ -7,12 +7,22 @@  #include "ui.h"  #include "console.h" + +//TEST +#include <readline/readline.h> +  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; @@ -152,21 +138,53 @@ 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) { @@ -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; @@ -4,6 +4,7 @@  #include "common.h"  #include "renderer.h"  #include "physics.h" +#include "console.h"  int ui_init(void);  void ui_quit(void);  | 
