summaryrefslogtreecommitdiffstats
path: root/profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'profile.c')
-rw-r--r--profile.c105
1 files changed, 82 insertions, 23 deletions
diff --git a/profile.c b/profile.c
index 9b0dcb600..7902560f3 100644
--- a/profile.c
+++ b/profile.c
@@ -15,6 +15,7 @@
#include "display-gtk.h"
#include "divelist.h"
#include "color.h"
+#include "libdivecomputer/parser.h"
int selected_dive = 0;
char zoomed_plot = 0;
@@ -44,6 +45,7 @@ struct plot_info {
int temperature;
/* Depth info */
int depth;
+ int ceiling;
int smoothed;
double po2, pn2, phe;
velocity_t velocity;
@@ -77,7 +79,8 @@ typedef enum {
/* Other colors */
TEXT_BACKGROUND, ALERT_BG, ALERT_FG, EVENTS, SAMPLE_DEEP, SAMPLE_SHALLOW,
SMOOTHED, MINUTE, TIME_GRID, TIME_TEXT, DEPTH_GRID, MEAN_DEPTH, DEPTH_TOP,
- DEPTH_BOTTOM, TEMP_TEXT, TEMP_PLOT, SAC_DEFAULT, BOUNDING_BOX, PRESSURE_TEXT, BACKGROUND
+ DEPTH_BOTTOM, TEMP_TEXT, TEMP_PLOT, SAC_DEFAULT, BOUNDING_BOX, PRESSURE_TEXT, BACKGROUND,
+ CEILING_SHALLOW, CEILING_DEEP
} color_indice_t;
typedef struct {
@@ -129,6 +132,9 @@ static const color_t profile_color[] = {
[BOUNDING_BOX] = {{WHITE1, BLACK1_LOW_TRANS}},
[PRESSURE_TEXT] = {{KILLARNEY1, BLACK1_LOW_TRANS}},
[BACKGROUND] = {{SPRINGWOOD1, BLACK1_LOW_TRANS}},
+ [CEILING_SHALLOW] = {{REDORANGE1_HIGH_TRANS, REDORANGE1_HIGH_TRANS}},
+ [CEILING_DEEP] = {{RED1_MED_TRANS, RED1_MED_TRANS}},
+
};
#define plot_info_size(nr) (sizeof(struct plot_info) + (nr)*sizeof(struct plot_data))
@@ -185,11 +191,11 @@ static void dump_pi (struct plot_info *pi)
pi->maxpressure, pi->mintemp, pi->maxtemp);
for (i = 0; i < pi->nr; i++)
printf(" entry[%d]:{same_cylinder:%d cylinderindex:%d sec:%d pressure:{%d,%d}\n"
- " time:%d:%02d temperature:%d depth:%d smoothed:%d po2:%lf phe:%lf pn2:%lf sum-pp %lf}\n",
+ " time:%d:%02d temperature:%d depth:%d ceiling:%d smoothed:%d po2:%lf phe:%lf pn2:%lf sum-pp %lf}\n",
i, pi->entry[i].same_cylinder, pi->entry[i].cylinderindex, pi->entry[i].sec,
pi->entry[i].pressure[0], pi->entry[i].pressure[1],
pi->entry[i].sec / 60, pi->entry[i].sec % 60,
- pi->entry[i].temperature, pi->entry[i].depth, pi->entry[i].smoothed,
+ pi->entry[i].temperature, pi->entry[i].depth, pi->entry[i].ceiling, pi->entry[i].smoothed,
pi->entry[i].po2, pi->entry[i].phe, pi->entry[i].pn2,
pi->entry[i].po2 + pi->entry[i].phe + pi->entry[i].pn2);
printf(" }\n");
@@ -294,6 +300,7 @@ static void plot_text(struct graphics_context *gc, const text_render_options_t *
cairo_show_text(cr, buffer);
}
+/* collect all event names and whether we display them */
struct ev_select {
char *ev_name;
gboolean plot_ev;
@@ -314,12 +321,12 @@ void evn_foreach(void (*callback)(const char *, int *, void *), void *data)
void remember_event(const char *eventname)
{
- int i=0, len;
+ int i = 0, len;
if (!eventname || (len = strlen(eventname)) == 0)
return;
while (i < evn_used) {
- if (!strncmp(eventname,ev_namelist[i].ev_name,len))
+ if (!strncmp(eventname, ev_namelist[i].ev_name, len))
return;
i++;
}
@@ -339,6 +346,7 @@ static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, st
{
int i, depth = 0;
int x,y;
+ char buffer[80];
/* is plotting this event disabled? */
if (event->name) {
@@ -374,7 +382,11 @@ static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, st
cairo_line_to(gc->cr, x-9, y+4);
cairo_stroke(gc->cr);
/* we display the event on screen - so translate */
- attach_tooltip(x-15, y-6, 12, 12, _(event->name));
+ if (event->value)
+ snprintf(buffer, sizeof(buffer), "%s: %d", _(event->name), event->value);
+ else
+ snprintf(buffer, sizeof(buffer), "%s", _(event->name));
+ attach_tooltip(x-15, y-6, 12, 12, buffer);
}
static void plot_events(struct graphics_context *gc, struct plot_info *pi, struct dive *dive)
@@ -386,7 +398,8 @@ static void plot_events(struct graphics_context *gc, struct plot_info *pi, struc
return;
while (event) {
- plot_one_event(gc, pi, event, &tro);
+ if (event->flags != SAMPLE_FLAGS_BEGIN && event->flags != SAMPLE_FLAGS_END)
+ plot_one_event(gc, pi, event, &tro);
event = event->next;
}
}
@@ -928,8 +941,37 @@ static void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi
move_to(gc, 0, 0);
for (i = 0; i < pi->nr; i++, entry++)
line_to(gc, entry->sec, entry->depth);
+
+ /* Show any ceiling we may have encountered */
+ for (i = pi->nr - 1; i >= 0; i--, entry--) {
+ if (entry->ceiling < entry->depth) {
+ line_to(gc, entry->sec, entry->ceiling);
+ } else {
+ line_to(gc, entry->sec, entry->depth);
+ }
+ }
cairo_close_path(gc->cr);
+ cairo_fill(gc->cr);
+
+ /* next show where we have been bad and crossed the ceiling */
+ pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale);
+ pattern_add_color_stop_rgba (gc, pat, 0, CEILING_SHALLOW);
+ pattern_add_color_stop_rgba (gc, pat, 1, CEILING_DEEP);
+ cairo_set_source(gc->cr, pat);
+ cairo_pattern_destroy(pat);
+ entry = pi->entry;
+ move_to(gc, 0, 0);
+ for (i = 0; i < pi->nr; i++, entry++)
+ line_to(gc, entry->sec, entry->depth);
+ for (i = pi->nr - 1; i >= 0; i--, entry--) {
+ if (entry->ceiling > entry->depth) {
+ line_to(gc, entry->sec, entry->ceiling);
+ } else {
+ line_to(gc, entry->sec, entry->depth);
+ }
+ }
+ cairo_close_path(gc->cr);
cairo_fill(gc->cr);
/* Now do it again for the velocity colors */
@@ -1509,10 +1551,12 @@ static int get_cylinder_index(struct dive *dive, struct event *ev)
return 0;
}
-static struct event *get_next_gaschange(struct event *event)
+static struct event *get_next_event(struct event *event, char *name)
{
+ if (!name || !*name)
+ return NULL;
while (event) {
- if (!strcmp(event->name, "gaschange"))
+ if (!strcmp(event->name, name))
return event;
event = event->next;
}
@@ -1537,7 +1581,7 @@ static int set_cylinder_index(struct plot_info *pi, int i, int cylinderindex, un
static void check_gas_change_events(struct dive *dive, struct plot_info *pi)
{
int i = 0, cylinderindex = 0;
- struct event *ev = get_next_gaschange(dive->events);
+ struct event *ev = get_next_event(dive->events, "gaschange");
if (!ev)
return;
@@ -1545,7 +1589,7 @@ static void check_gas_change_events(struct dive *dive, struct plot_info *pi)
do {
i = set_cylinder_index(pi, i, cylinderindex, ev->time.seconds);
cylinderindex = get_cylinder_index(dive, ev);
- ev = get_next_gaschange(ev->next);
+ ev = get_next_event(ev->next, "gaschange");
} while (ev);
set_cylinder_index(pi, i, cylinderindex, ~0u);
}
@@ -1554,11 +1598,11 @@ static void check_gas_change_events(struct dive *dive, struct plot_info *pi)
static int count_gas_change_events(struct dive *dive)
{
int count = 0;
- struct event *ev = get_next_gaschange(dive->events);
+ struct event *ev = get_next_event(dive->events, "gaschange");
while (ev) {
count++;
- ev = get_next_gaschange(ev->next);
+ ev = get_next_event(ev->next, "gaschange");
}
return count;
}
@@ -1574,14 +1618,14 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
{
int cylinderindex = -1;
int lastdepth, lastindex;
- int i, pi_idx, nr, sec, cyl;
+ int i, pi_idx, nr, sec, cyl, ceiling = 0;
size_t alloc_size;
struct plot_info *pi;
pr_track_t *track_pr[MAX_CYLINDERS] = {NULL, };
pr_track_t *pr_track, *current;
gboolean missing_pr = FALSE;
struct plot_data *entry = NULL;
- struct event *ev;
+ struct event *ev, *ceil_ev;
/* we want to potentially add synthetic plot_info elements for the gas changes */
nr = nr_samples + 4 + 2 * count_gas_change_events(dive);
@@ -1593,18 +1637,20 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
pi->nr = nr;
pi_idx = 2; /* the two extra events at the start */
/* check for gas changes before the samples start */
- ev = get_next_gaschange(dive->events);
+ ev = get_next_event(dive->events, "gaschange");
while (ev && ev->time.seconds < dive_sample->time.seconds) {
entry = pi->entry + pi_idx;
entry->sec = ev->time.seconds;
entry->depth = 0; /* is that always correct ? */
pi_idx++;
- ev = get_next_gaschange(ev->next);
+ ev = get_next_event(ev->next, "gaschange");
}
if (ev && ev->time.seconds == dive_sample->time.seconds) {
/* we already have a sample at the time of the event */
- ev = get_next_gaschange(ev->next);
+ ev = get_next_event(ev->next, "gaschange");
}
+ /* find the first deco/ceiling event (if any) */
+ ceil_ev = get_next_event(dive->events, "ceiling");
sec = 0;
lastindex = 0;
lastdepth = -1;
@@ -1614,13 +1660,22 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
struct sample *sample = dive_sample+i;
entry = pi->entry + i + pi_idx;
+ while (ceil_ev && ceil_ev->time.seconds <= sample->time.seconds) {
+ struct event *next_ceil_ev = get_next_event(ceil_ev->next, "ceiling");
+ if (!next_ceil_ev || next_ceil_ev->time.seconds > sample->time.seconds)
+ break;
+ ceil_ev = next_ceil_ev;
+ }
+ if (ceil_ev && ceil_ev->time.seconds <= sample->time.seconds) {
+ ceiling = ceil_ev->value;
+ ceil_ev = get_next_event(ceil_ev->next, "ceiling");
+ }
while (ev && ev->time.seconds < sample->time.seconds) {
/* insert two fake plot info structures for the end of
* the old tank and the start of the new tank */
if (ev->time.seconds == sample->time.seconds - 1) {
entry->sec = ev->time.seconds - 1;
(entry+1)->sec = ev->time.seconds;
- } else {
entry->sec = ev->time.seconds;
(entry+1)->sec = ev->time.seconds + 1;
}
@@ -1630,10 +1685,12 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
(sample->depth.mm - (sample-1)->depth.mm) / 2;
} else
entry->depth = sample->depth.mm;
- (entry+1)->depth = entry->depth;
+ (entry + 1)->depth = entry->depth;
+ entry->ceiling = ceiling;
+ (entry + 1)->ceiling = ceiling;
pi_idx += 2;
entry = pi->entry + i + pi_idx;
- ev = get_next_gaschange(ev->next);
+ ev = get_next_event(ev->next, "gaschange");
}
if (ev && ev->time.seconds == sample->time.seconds) {
/* we already have a sample at the time of the event
@@ -1641,13 +1698,15 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
* real even by one second (to keep time monotonous) */
entry->sec = ev->time.seconds;
entry->depth = sample->depth.mm;
+ entry->ceiling = ceiling;
pi_idx++;
entry = pi->entry + i + pi_idx;
- ev = get_next_gaschange(ev->next);
+ ev = get_next_event(ev->next, "gaschange");
delay = 1;
}
sec = entry->sec = sample->time.seconds + delay;
depth = entry->depth = sample->depth.mm;
+ entry->ceiling = ceiling;
entry->cylinderindex = sample->cylinderindex;
SENSOR_PRESSURE(entry) = sample->cylinderpressure.mbar;
entry->temperature = sample->temperature.mkelvin;
@@ -1666,7 +1725,7 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
entry->depth = 0; /* why are there gas changes after the dive is over? */
pi_idx++;
entry = pi->entry + i + pi_idx;
- ev = get_next_gaschange(ev->next);
+ ev = get_next_event(ev->next, "gaschange");
}
nr = nr_samples + pi_idx - 2;
check_gas_change_events(dive, pi);