diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | color.h | 8 | ||||
| -rw-r--r-- | compressor.h | 10 | ||||
| -rw-r--r--[-rwxr-xr-x] | cwalk.c | 0 | ||||
| -rw-r--r-- | main.c | 16 | ||||
| -rw-r--r-- | renderer.c | 14 | ||||
| -rw-r--r-- | ui.c | 67 | ||||
| -rw-r--r-- | util.h | 9 | ||||
| -rw-r--r-- | widget.c | 21 | ||||
| -rw-r--r-- | widget.h | 4 |
10 files changed, 125 insertions, 26 deletions
@@ -3,7 +3,7 @@ LDFLAGS = -lSDL2 -lSDL2_ttf -lSDL2_image -lm -fopenmp SRC = main.c microui.c renderer.c widget.c ui.c unit.c engine.c compressor.c eprintf.c cwalk.c toml.c util.c OBJ = ${SRC:.c=.o} -HDR = microui.h renderer.h widget.h ui.h unit.h engine.h eprintf.h util.h cwalk.h toml.h +HDR = microui.h renderer.h widget.h ui.h unit.h engine.h eprintf.h util.h cwalk.h toml.h color.h TEST_SRC = test.c test_angular_speed.c test_fraction.c test_pressure.c test_temperature.c test_volume.c test_volume_flow_rate.c test_mass_flow_rate.c test_engine.c unit.c engine.c TEST_OBJ = ${TEST_SRC:.c=.o} @@ -0,0 +1,8 @@ +static const mu_Color BLACK = {0, 0, 0, 255}; +static const mu_Color WHITE = {255, 255, 255, 255}; +static const mu_Color LIGHT_GRAY = {222, 222, 222, 255}; +static const mu_Color DARK_GRAY = {128, 128, 128, 255}; +static const mu_Color RED = {255, 0, 0, 255}; +static const mu_Color GREEN = {0, 255, 0, 255}; +static const mu_Color BLUE = {0, 0, 255, 255}; +static const mu_Color TRANSPARENT = {0, 0, 0, 0}; diff --git a/compressor.h b/compressor.h index 3442545..e394450 100644 --- a/compressor.h +++ b/compressor.h @@ -1,12 +1,14 @@ +typedef enum { + MASS_FLOW, + VOLUME_FLOW, +} FlowType; + typedef struct { union { MassFlowRate mfr; VolumeFlowRate vfr; } u; - enum { - MASS_FLOW, - VOLUME_FLOW - } t; + FlowType t; } Flow; typedef struct { @@ -11,6 +11,8 @@ #include "widget.h" #include "engine.h" #include "ui.h" +#include "color.h" +#include "eprintf.h" /* Macros. */ @@ -26,11 +28,6 @@ enum window { }; -static const mu_Color BLACK = {0, 0, 0, 255}; -static const mu_Color WHITE = {255, 255, 255, 255}; -static const mu_Color LIGHT_GRAY = {222, 222, 222, 255}; -static const mu_Color DARK_GRAY = {128, 128, 128, 255}; - static const mu_Color COLOR_TEXT = BLACK; static const mu_Color COLOR_BORDER = BLACK; static const mu_Color COLOR_WINDOWBG = WHITE; @@ -329,6 +326,7 @@ dup_del_row(mu_Context *ctx, UI *ui) { } if (mu_button(ctx, "Del")) { remove_point(ui, i); + compute_all(ui); } mu_pop_id(ctx); } @@ -390,8 +388,14 @@ mass_flow_rate_corrected_row(mu_Context *ctx, UI *ui) { static void comp_select(mu_Context *ctx, UI *ui) { + const Compressor *comp; + if (w_select_compressor(ctx, &ui->comp_select) & MU_RES_CHANGE) { - /* TODO */ + comp = &ui->comps[ui->comp_select.idx]; + if (w_canvas_set_bg(&ui->comp_img, comp->imgfile) != 0) { + weprintf("failed to set compressor image: %s", comp->imgfile); + } + compute_all(ui); } } @@ -7,15 +7,8 @@ #include <SDL2/SDL_image.h> #include "microui.h" #include "renderer.h" - - -#define expect(x) do { \ - if (!(x)) { \ - fprintf(stderr, "Fatal error: %s:%d: assertion '%s' failed\n", \ - __FILE__, __LINE__, #x); \ - abort(); \ - } \ - } while (0) +#include "color.h" +#include "util.h" #define PIXEL_DEPTH 32 @@ -41,7 +34,7 @@ enum { CIRCLE_RADIUS = 16 }; static const char FONT[] = "font/P052-Roman.ttf"; enum font { FONTSIZE = 14, }; -static const mu_Color bg = {255, 255, 255, 255}; +static const mu_Color bg = WHITE; static const char button_map[256] = { [SDL_BUTTON_LEFT & 0xff] = MU_MOUSE_LEFT, @@ -452,6 +445,7 @@ r_canvas_draw_circle(int id, int x, int y, int r, mu_Color color) { canvas = &canvas_list.items[id]; + #pragma omp parallel for for (dy = -r; dy <= r; dy++) { for (dx = -r; dx <= r; dx++) { if (dx*dx + dy*dy <= r*r) { @@ -12,6 +12,8 @@ #include "engine.h" #include "ui.h" #include "eprintf.h" +#include "color.h" +#include "util.h" #define DEFAULT_DISPLACEMENT (litre(1.5)) @@ -24,6 +26,10 @@ #define DEFAULT_INTERCOOLER_EFFICIENCY (percent(90)) #define DEFAULT_INTERCOOLER_DELTAP (psi(0.2)) +enum { POINT_RADIUS = 6 }; + +static const mu_Color POINT_COLOR = RED; + static void init_displacement(UI *ui); static void init_ambient_temperature(UI *ui); @@ -48,6 +54,10 @@ static void compute_manifold_temperature(UI *ui, int idx); static void compute_volume_flow_rate(UI *ui, int idx); static void compute_mass_flow_rate(UI *ui, int idx); static void compute_mass_flow_rate_corrected(UI *ui, int idx); +static void draw_points(UI *ui); +static void draw_point(UI *ui, int idx, mu_Color color); +static void point_coords(UI *ui, int idx, int *x, int *y); +static const Compressor *selected_compressor(UI *ui); /* Returns non-zero on error. The renderer must already be initialized. */ @@ -433,6 +443,8 @@ compute(UI *ui, int idx) { compute_volume_flow_rate(ui, idx); compute_mass_flow_rate(ui, idx); compute_mass_flow_rate_corrected(ui, idx); + + draw_points(ui); } void @@ -522,6 +534,61 @@ compute_mass_flow_rate_corrected(UI *ui, int idx) { w_set_number(ui->mass_flow_rate_corrected[idx], v); } +static void +draw_points(UI *ui) { + int i; + + w_clear_canvas(&ui->comp_img); + #pragma omp parallel for + for (i = 0; i < ui->npoints; i++) { + draw_point(ui, i, POINT_COLOR); + } +} + +static void +draw_point(UI *ui, int idx, mu_Color color) { + int x, y; + + point_coords(ui, idx, &x, &y); + w_canvas_draw_circle(&ui->comp_img, x, y, POINT_RADIUS, color); +} + +static void +point_coords(UI *ui, int idx, int *x, int *y) { + const Compressor *comp; + const Engine *engine; + double flow, origin_flow, ref_flow, r, pr; + + comp = selected_compressor(ui); + engine = &ui->points[idx]; + + expect(comp->origin.flow.t == comp->ref.flow.t); + switch (comp->origin.flow.t) { + case MASS_FLOW: + flow = mass_flow_rate_corrected(engine); + origin_flow = comp->origin.flow.u.mfr; + ref_flow = comp->ref.flow.u.mfr; + break; case VOLUME_FLOW: + flow = volume_flow_rate(engine); + origin_flow = comp->origin.flow.u.vfr; + ref_flow = comp->ref.flow.u.vfr; + break; default: + eprintf("impossible FlowType: %d", comp->origin.flow.t); + } + + r = (flow - origin_flow) / (ref_flow - origin_flow); + *x = comp->origin.x + r * (comp->ref.x - comp->origin.x); + + pr = pressure_ratio(engine); + r = (pr - comp->origin.pr) / (comp->ref.pr - comp->origin.pr); + *y = comp->origin.y + r * (comp->ref.y - comp->origin.y); +} + +static const Compressor * +selected_compressor(UI *ui) { + return &ui->comps[ui->comp_select.idx]; +} + void insert_point(UI *ui, int idx) { int i; @@ -2,5 +2,14 @@ #define min(a, b) ((a < b) ? a : b) #define max(a, b) ((a > b) ? a : b) +#define expect(x) do { \ + if (!(x)) { \ + fprintf(stderr, "Fatal error: %s:%d: assertion '%s' failed\n", \ + __FILE__, __LINE__, #x); \ + abort(); \ + } \ + } while (0) + + void free_arr(void **arr, int n); int lsearch(const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void *keyval, const void *datum)); @@ -12,12 +12,11 @@ #include "widget.h" #include "util.h" #include "eprintf.h" +#include "color.h" #define FORMAT "%.5g" -static const mu_Color RED = {255, 0, 0, 255}; -static const mu_Color WHITE = {255, 255, 255, 255}; static const char *sc_selected_name(w_Select_Compressor *select); static int select_compressor_active(mu_Context *ctx, w_Select_Compressor *select); @@ -387,6 +386,20 @@ render_canvas(w_Canvas *canvas) { } void -w_canvas_draw_circle(w_Canvas canvas, int x, int y, int r, mu_Color color) { - r_canvas_draw_circle(canvas.id, x, y, r, color); +w_canvas_draw_circle(w_Canvas *canvas, int x, int y, int r, mu_Color color) { + r_canvas_draw_circle(canvas->id, x, y, r, color); + canvas->dirty = 1; +} + +void +w_clear_canvas(w_Canvas *canvas) { + r_clear_canvas(canvas->id); + canvas->dirty = 1; +} + +/* Set the background image of the canvas. Returns non-zero on error. */ +int +w_canvas_set_bg(w_Canvas *canvas, const char *path) { + r_remove_canvas(canvas->id); + return w_init_canvas(canvas, path); } @@ -85,4 +85,6 @@ typedef struct { int w_init_canvas(w_Canvas *c, const char *bg_img_path); void w_free_canvas(w_Canvas *c); void w_canvas(mu_Context *ctx, w_Canvas *canvas); -void w_canvas_draw_circle(w_Canvas canvas, int x, int y, int r, mu_Color color); +void w_canvas_draw_circle(w_Canvas *canvas, int x, int y, int r, mu_Color color); +void w_clear_canvas(w_Canvas *canvas); +int w_canvas_set_bg(w_Canvas *canvas, const char *path); |