summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.c14
-rw-r--r--dive.h3
-rw-r--r--divelist.c22
-rw-r--r--libdivecomputer.c2
-rw-r--r--parse-xml.c40
-rw-r--r--profile.c3
-rw-r--r--save-xml.c47
-rw-r--r--uemis.c7
8 files changed, 111 insertions, 27 deletions
diff --git a/dive.c b/dive.c
index 98b96b3ff..7457cc5fc 100644
--- a/dive.c
+++ b/dive.c
@@ -237,7 +237,9 @@ static void fixup_pressure(struct dive *dive, struct sample *sample)
pressure = sample->cylinderpressure.mbar;
if (!pressure)
return;
- index = sample->cylinderindex;
+ index = sample->sensor;
+
+ /* FIXME! sensor -> cylinder mapping? */
if (index >= MAX_CYLINDERS)
return;
cyl = dive->cylinder + index;
@@ -427,7 +429,7 @@ struct dive *fixup_dive(struct dive *dive)
int depth = sample->depth.mm;
int temp = sample->temperature.mkelvin;
int pressure = sample->cylinderpressure.mbar;
- int index = sample->cylinderindex;
+ int index = sample->sensor;
if (index == lastindex) {
/* Remove duplicate redundant pressure information */
@@ -502,7 +504,7 @@ struct dive *fixup_dive(struct dive *dive)
if (abs(pressure_delta[j]) != INT_MAX) {
cylinder_t *cyl = dive->cylinder + j;
for (i = 0; i < dc->samples; i++)
- if (dc->sample[i].cylinderindex == j)
+ if (dc->sample[i].sensor == j)
dc->sample[i].cylinderpressure.mbar = 0;
if (! cyl->start.mbar)
cyl->start.mbar = cyl->sample_start.mbar;
@@ -709,8 +711,8 @@ add_sample_b:
sample.temperature = as->temperature;
if (as->cylinderpressure.mbar)
sample.cylinderpressure = as->cylinderpressure;
- if (as->cylinderindex)
- sample.cylinderindex = as->cylinderindex;
+ if (as->sensor)
+ sample.sensor = as->sensor;
if (as->cns)
sample.cns = as->cns;
if (as->po2)
@@ -1291,7 +1293,7 @@ static int same_sample(struct sample *a, struct sample *b)
return 0;
if (a->cylinderpressure.mbar != b->cylinderpressure.mbar)
return 0;
- return a->cylinderindex == b->cylinderindex;
+ return a->sensor == b->sensor;
}
static int same_dc(struct divecomputer *a, struct divecomputer *b)
diff --git a/dive.h b/dive.h
index 1028a6919..9914e7d1d 100644
--- a/dive.h
+++ b/dive.h
@@ -226,7 +226,7 @@ struct sample {
depth_t depth;
temperature_t temperature;
pressure_t cylinderpressure;
- int cylinderindex;
+ int sensor; /* Cylinder pressure sensor index */
duration_t ndl;
duration_t stoptime;
depth_t stopdepth;
@@ -503,6 +503,7 @@ extern struct dive *try_to_merge(struct dive *a, struct dive *b, gboolean prefer
extern void renumber_dives(int nr);
+extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx);
extern void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name);
/* UI related protopypes */
diff --git a/divelist.c b/divelist.c
index 316c4d547..2a6829e27 100644
--- a/divelist.c
+++ b/divelist.c
@@ -715,6 +715,24 @@ static void cns_data_func(GtkTreeViewColumn *col,
g_object_set(renderer, "text", buffer, NULL);
}
+static int active_o2(struct dive *dive, struct divecomputer *dc, duration_t time)
+{
+ int o2permille = dive->cylinder[0].gasmix.o2.permille;
+ struct event *event = dc->events;
+
+ if (!o2permille)
+ o2permille = AIR_PERMILLE;
+
+ for (event = dc->events; event; event = event->next) {
+ if (event->time.seconds > time.seconds)
+ break;
+ if (strcmp(event->name, "gaschange"))
+ continue;
+ o2permille = 10*(event->value & 0xffff);
+ }
+ return o2permille;
+}
+
/* calculate OTU for a dive */
static int calculate_otu(struct dive *dive, struct divecomputer *dc)
{
@@ -730,9 +748,7 @@ static int calculate_otu(struct dive *dive, struct divecomputer *dc)
if (sample->po2) {
po2 = sample->po2;
} else {
- int o2 = dive->cylinder[sample->cylinderindex].gasmix.o2.permille;
- if (!o2)
- o2 = AIR_PERMILLE;
+ int o2 = active_o2(dive, dc, sample->time);
po2 = o2 / 1000.0 * depth_to_mbar(sample->depth.mm, dive) / 1000.0;
}
if (po2 >= 0.5)
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 6e01ee3a5..47c7b6367 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -209,7 +209,7 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
sample->depth.mm = value.depth * 1000 + 0.5;
break;
case DC_SAMPLE_PRESSURE:
- sample->cylinderindex = value.pressure.tank;
+ sample->sensor = value.pressure.tank;
sample->cylinderpressure.mbar = value.pressure.value * 1000 + 0.5;
break;
case DC_SAMPLE_TEMPERATURE:
diff --git a/parse-xml.c b/parse-xml.c
index 8232fb041..a256990b3 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -155,6 +155,7 @@ static gboolean in_settings = FALSE;
static struct tm cur_tm;
static int cur_cylinder_index, cur_ws_index;
static int lastndl, laststoptime, laststopdepth, lastcns, lastpo2, lastindeco;
+static int lastcylinderindex, lastsensor;
static enum import_source {
UNKNOWN,
@@ -650,6 +651,39 @@ static void try_to_fill_dc(struct divecomputer *dc, const char *name, char *buf)
nonmatch("divecomputer", name, buf);
}
+void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx)
+{
+ /* The gas switch event format is insane. It will be fixed, I think */
+ int o2 = dive->cylinder[idx].gasmix.o2.permille;
+ int he = dive->cylinder[idx].gasmix.he.permille;
+ int value;
+
+ if (!o2)
+ o2 = AIR_PERMILLE;
+ o2 = (o2+5) / 10;
+ he = (he+5) / 10;
+ value = o2 + (he << 16);
+
+ add_event(dc, seconds, 11, 0, value, "gaschange");
+}
+
+static void get_cylinderindex(char *buffer, void *_i)
+{
+ int *i = _i;
+ *i = atoi(buffer);
+ if (lastcylinderindex != *i) {
+ add_gas_switch_event(cur_dive, cur_dc, cur_sample->time.seconds, *i);
+ lastcylinderindex = *i;
+ }
+}
+
+static void get_sensor(char *buffer, void *_i)
+{
+ int *i = _i;
+ *i = atoi(buffer);
+ lastsensor = *i;
+}
+
/* We're in samples - try to convert the random xml value to something useful */
static void try_to_fill_sample(struct sample *sample, const char *name, char *buf)
{
@@ -661,7 +695,9 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu
return;
if (MATCH(".sample.cylpress", pressure, &sample->cylinderpressure))
return;
- if (MATCH(".sample.cylinderindex", get_index, &sample->cylinderindex))
+ if (MATCH(".sample.cylinderindex", get_cylinderindex, &sample->sensor))
+ return;
+ if (MATCH(".sample.sensor", get_sensor, &sample->sensor))
return;
if (MATCH(".sample.depth", depth, &sample->depth))
return;
@@ -1005,6 +1041,7 @@ static gboolean is_dive(void)
static void reset_dc_info(struct divecomputer *dc)
{
lastcns = lastpo2 = lastndl = laststoptime = laststopdepth = lastindeco = 0;
+ lastsensor = lastcylinderindex = 0;
}
static void reset_dc_settings(void)
@@ -1129,6 +1166,7 @@ static void sample_start(void)
cur_sample->stopdepth.mm = laststopdepth;
cur_sample->cns = lastcns;
cur_sample->po2 = lastpo2;
+ cur_sample->sensor = lastsensor;
}
static void sample_end(void)
diff --git a/profile.c b/profile.c
index 925d50cfb..0962f9ca8 100644
--- a/profile.c
+++ b/profile.c
@@ -1644,7 +1644,8 @@ static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer
entry->in_deco = in_deco;
entry->cns = cns;
entry->po2 = po2;
- entry->cylinderindex = sample->cylinderindex;
+ /* FIXME! sensor index -> cylinder index translation! */
+ entry->cylinderindex = sample->sensor;
SENSOR_PRESSURE(entry) = sample->cylinderpressure.mbar;
entry->temperature = sample->temperature.mkelvin;
diff --git a/save-xml.c b/save-xml.c
index c85f66408..fe663f652 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -319,27 +319,50 @@ static void show_index(FILE *f, int value, const char *pre, const char *post)
fprintf(f, " %s%d%s", pre, value, post);
}
-static void save_sample(FILE *f, struct sample *sample, const struct sample *prev)
+static void save_sample(FILE *f, struct sample *sample, struct sample *old)
{
fprintf(f, " <sample time='%u:%02u min'", FRACTION(sample->time.seconds,60));
show_milli(f, " depth='", sample->depth.mm, " m", "'");
show_temperature(f, sample->temperature, " temp='", "'");
show_pressure(f, sample->cylinderpressure, " pressure='", "'");
- if (sample->cylinderindex)
- fprintf(f, " cylinderindex='%d'", sample->cylinderindex);
+
+ /*
+ * We only show sensor information for samples with pressure, and only if it
+ * changed from the previous sensor we showed.
+ */
+ if (sample->cylinderpressure.mbar && sample->sensor != old->sensor) {
+ fprintf(f, " sensor='%d'", sample->sensor);
+ old->sensor = sample->sensor;
+ }
+
/* the deco/ndl values are stored whenever they change */
- if (sample->ndl.seconds != prev->ndl.seconds)
+ if (sample->ndl.seconds != old->ndl.seconds) {
fprintf(f, " ndl='%u:%02u min'", FRACTION(sample->ndl.seconds, 60));
- if (sample->in_deco != prev->in_deco)
+ old->ndl = sample->ndl;
+ }
+ if (sample->in_deco != old->in_deco) {
fprintf(f, " in_deco='%d'", sample->in_deco ? 1 : 0);
- if (sample->stoptime.seconds != prev->stoptime.seconds)
+ old->in_deco = sample->in_deco;
+ }
+ if (sample->stoptime.seconds != old->stoptime.seconds) {
fprintf(f, " stoptime='%u:%02u min'", FRACTION(sample->stoptime.seconds, 60));
- if (sample->stopdepth.mm != prev->stopdepth.mm)
+ old->stoptime = sample->stoptime;
+ }
+
+ if (sample->stopdepth.mm != old->stopdepth.mm) {
show_milli(f, " stopdepth='", sample->stopdepth.mm, " m", "'");
- if (sample->cns != prev->cns)
+ old->stopdepth = sample->stopdepth;
+ }
+
+ if (sample->cns != old->cns) {
fprintf(f, " cns='%u%%'", sample->cns);
- if (sample->po2 != prev->po2)
+ old->cns = sample->cns;
+ }
+
+ if (sample->po2 != old->po2) {
fprintf(f, " po2='%u.%2u bar'", FRACTION(sample->po2, 1000));
+ old->po2 = sample->po2;
+ }
fprintf(f, " />\n");
}
@@ -376,12 +399,10 @@ static void show_date(FILE *f, timestamp_t when)
static void save_samples(FILE *f, int nr, struct sample *s)
{
- static const struct sample empty_sample;
- const struct sample *prev = &empty_sample;
+ struct sample dummy = { };
while (--nr >= 0) {
- save_sample(f, s, prev);
- prev = s;
+ save_sample(f, s, &dummy);
s++;
}
}
diff --git a/uemis.c b/uemis.c
index ded060b44..d323cd802 100644
--- a/uemis.c
+++ b/uemis.c
@@ -291,6 +291,7 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
struct dive *dive = datap;
struct divecomputer *dc = &dive->dc;
int template, gasoffset;
+ int active = 0;
datalen = uemis_convert_base64(base64, &data);
@@ -345,11 +346,15 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
* duration in the header is a) in minutes and b) up to 3 minutes short */
if (u_sample->dive_time > dive->duration.seconds + 180)
break;
+ if (u_sample->active_tank != active) {
+ active = u_sample->active_tank;
+ add_gas_switch_event(dive, dc, u_sample->dive_time, active);
+ }
sample = prepare_sample(dc);
sample->time.seconds = u_sample->dive_time;
sample->depth.mm = rel_mbar_to_depth(u_sample->water_pressure, dive);
sample->temperature.mkelvin = (u_sample->dive_temperature * 100) + 273150;
- sample->cylinderindex = u_sample->active_tank;
+ sample->sensor = active;
sample->cylinderpressure.mbar =
(u_sample->tank_pressure_high * 256 + u_sample->tank_pressure_low) * 10;
sample->cns = u_sample->cns;