summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2012-12-30 18:11:01 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2012-12-30 18:17:21 -0800
commite3ab1c0701fceffa370d56bff187d0c0e90d5d21 (patch)
treea4c3dec2c1de47494f4ceec9e82b8f994c596455
parent46b64d8e21bd770c908cc883f3627f4f08a2c0a7 (diff)
downloadsubsurface-e3ab1c0701fceffa370d56bff187d0c0e90d5d21.tar.gz
Update deco handling
This commit makes deco handling in Subsurface more compatible with the way libdivecomputer creates the data. Previously we assumed that having a stopdepth or stoptime and no ndl meant that we were in deco. But libdivecomputer supports many dive computers that provide the deco state of the diver but with no information about the next stop or the time needed there. In order to be able to model this in Subsurface this adds an in_deco flag to the samples. This is only stored to the XML file when it changes so it doesn't add much overhead but will allow us to display some deco information on dive computers like the Atomic Aquatics Cobalt or many of the Suuntos (among others). The commit also removes the old event based deco code that was commented out already. And fixes the code so that the deco / ndl information is stored for the very last sample as well. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--dive.c2
-rw-r--r--dive.h1
-rw-r--r--libdivecomputer.c36
-rw-r--r--parse-xml.c11
-rw-r--r--profile.c12
-rw-r--r--save-xml.c2
-rw-r--r--uemis.c3
7 files changed, 40 insertions, 27 deletions
diff --git a/dive.c b/dive.c
index 1c7e140d4..081c7eb25 100644
--- a/dive.c
+++ b/dive.c
@@ -721,6 +721,8 @@ add_sample_b:
sample.stoptime = as->stoptime;
if (as->stopdepth.mm)
sample.stopdepth = as->stopdepth;
+ if (as->in_deco)
+ sample.in_deco = TRUE;
merge_one_sample(&sample, at, res);
diff --git a/dive.h b/dive.h
index 1191ec6b6..34b1ec549 100644
--- a/dive.h
+++ b/dive.h
@@ -230,6 +230,7 @@ struct sample {
duration_t ndl;
duration_t stoptime;
depth_t stopdepth;
+ gboolean in_deco;
int cns;
int po2;
};
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 01639e5e5..6e01ee3a5 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -23,6 +23,7 @@
static const char *progress_bar_text = "";
static double progress_bar_fraction = 0.0;
static int stoptime, stopdepth, ndl, po2, cns;
+static gboolean in_deco;
static GError *error(const char *fmt, ...)
{
@@ -162,27 +163,6 @@ static void handle_event(struct divecomputer *dc, struct sample *sample, dc_samp
if (value.event.type == SAMPLE_EVENT_SURFACE)
return;
- /* an early development version of libdivecomputer 0.3 provided us with deco / ndl information for
- * a couple of dive computers through events; this got fixed later in the release cycle but for a
- * short while I'll keep the code around that converts the events into our preferred sample format here */
-#if 0
- if (value.event.type == SAMPLE_EVENT_DECOSTOP) {
- /* packed value - time in seconds in high 16 bit
- * depth in m(!) in low 16 bits */
- stoptime = value.event.value >> 16;
- stopdepth = (value.event.value & 0xFFFF) * 1000;
- ndl = 0;
- }
- if (value.event.type == SAMPLE_EVENT_NDL) {
- stopdepth = 0;
- stoptime = 0;
- ndl = value.event.value;
- }
- if (value.event.type == SAMPLE_EVENT_DECOSTOP || value.event.type == SAMPLE_EVENT_NDL)
- /* don't create a Subsurface event for these */
- return;
-#endif
-
/*
* Other evens might be more interesting, but for now we just print them out.
*/
@@ -214,6 +194,7 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
switch (type) {
case DC_SAMPLE_TIME:
if (sample) {
+ sample->in_deco = in_deco;
sample->ndl.seconds = ndl;
sample->stoptime.seconds = stoptime;
sample->stopdepth.mm = stopdepth;
@@ -266,12 +247,18 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
break;
case DC_SAMPLE_DECO:
if (value.deco.type == DC_DECO_NDL) {
- ndl = value.deco.time;
+ sample->ndl.seconds = ndl = value.deco.time;
+ sample->in_deco = in_deco = FALSE;
} else if (value.deco.type == DC_DECO_DECOSTOP ||
value.deco.type == DC_DECO_DEEPSTOP) {
- stopdepth = value.deco.depth * 1000.0 + 0.5;
- stoptime = value.deco.time;
+ sample->in_deco = in_deco = TRUE;
+ sample->stopdepth.mm = stopdepth = value.deco.depth * 1000.0 + 0.5;
+ sample->stoptime.seconds = stoptime = value.deco.time;
ndl = 0;
+ } else if (value.deco.type == DC_DECO_SAFETYSTOP) {
+ sample->in_deco = in_deco = FALSE;
+ sample->stopdepth.mm = stopdepth = value.deco.depth * 1000.0 + 0.5;
+ sample->stoptime.seconds = stoptime = value.deco.time;
}
#endif
default:
@@ -408,6 +395,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
/* reset the deco / ndl data */
ndl = stoptime = stopdepth = 0;
+ in_deco = FALSE;
rc = create_parser(devdata, &parser);
if (rc != DC_STATUS_SUCCESS) {
diff --git a/parse-xml.c b/parse-xml.c
index aa9d5e0f5..8232fb041 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -154,7 +154,7 @@ struct {
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;
+static int lastndl, laststoptime, laststopdepth, lastcns, lastpo2, lastindeco;
static enum import_source {
UNKNOWN,
@@ -654,6 +654,7 @@ static void try_to_fill_dc(struct divecomputer *dc, const char *name, char *buf)
static void try_to_fill_sample(struct sample *sample, const char *name, char *buf)
{
int len = strlen(name);
+ int in_deco;
start_match("sample", name, buf);
if (MATCH(".sample.pressure", pressure, &sample->cylinderpressure))
@@ -674,6 +675,10 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu
return;
if (MATCH(".sample.ndl", sampletime, &sample->ndl))
return;
+ if (MATCH(".sample.in_deco", get_index, &in_deco)) {
+ sample->in_deco = (in_deco == 1);
+ return;
+ }
if (MATCH(".sample.stoptime", sampletime, &sample->stoptime))
return;
if (MATCH(".sample.stopdepth", depth, &sample->stopdepth))
@@ -999,7 +1004,7 @@ static gboolean is_dive(void)
static void reset_dc_info(struct divecomputer *dc)
{
- lastcns = lastpo2 = lastndl = laststoptime = laststopdepth = 0;
+ lastcns = lastpo2 = lastndl = laststoptime = laststopdepth = lastindeco = 0;
}
static void reset_dc_settings(void)
@@ -1119,6 +1124,7 @@ static void sample_start(void)
{
cur_sample = prepare_sample(get_dc());
cur_sample->ndl.seconds = lastndl;
+ cur_sample->in_deco = lastindeco;
cur_sample->stoptime.seconds = laststoptime;
cur_sample->stopdepth.mm = laststopdepth;
cur_sample->cns = lastcns;
@@ -1132,6 +1138,7 @@ static void sample_end(void)
finish_sample(get_dc());
lastndl = cur_sample->ndl.seconds;
+ lastindeco = cur_sample->in_deco;
laststoptime = cur_sample->stoptime.seconds;
laststopdepth = cur_sample->stopdepth.mm;
lastcns = cur_sample->cns;
diff --git a/profile.c b/profile.c
index bd78c85da..925d50cfb 100644
--- a/profile.c
+++ b/profile.c
@@ -31,7 +31,7 @@ static struct plot_data *last_pi_entry = NULL;
typedef enum { STABLE, SLOW, MODERATE, FAST, CRAZY } velocity_t;
struct plot_data {
- unsigned int same_cylinder:1;
+ unsigned int same_cylinder:1, in_deco:1;
unsigned int cylinderindex;
int sec;
/* pressure[0] is sensor pressure
@@ -1531,6 +1531,7 @@ static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer
int cylinderindex = -1;
int lastdepth, lastindex;
int i, pi_idx, nr, sec, cyl, stoptime, ndl, stopdepth, cns;
+ gboolean in_deco;
struct plot_info *pi;
pr_track_t *track_pr[MAX_CYLINDERS] = {NULL, };
pr_track_t *pr_track, *current;
@@ -1578,6 +1579,7 @@ static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer
continue;
}
entry = pi->entry + i + pi_idx;
+ in_deco = sample->in_deco;
ndl = sample->ndl.seconds;
pi->has_ndl |= ndl;
stopdepth = sample->stopdepth.mm;
@@ -1606,9 +1608,11 @@ static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer
entry->ndl = ndl;
entry->cns = cns;
entry->po2 = po2;
+ entry->in_deco = in_deco;
(entry + 1)->stopdepth = stopdepth;
(entry + 1)->stoptime = stoptime;
(entry + 1)->ndl = ndl;
+ (entry + 1)->in_deco = in_deco;
(entry + 1)->cns = cns;
(entry + 1)->po2 = po2;
pi_idx += 2;
@@ -1624,6 +1628,7 @@ static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer
entry->stopdepth = stopdepth;
entry->stoptime = stoptime;
entry->ndl = ndl;
+ entry->in_deco = in_deco;
entry->cns = cns;
entry->po2 = po2;
pi_idx++;
@@ -1636,6 +1641,7 @@ static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer
entry->stopdepth = stopdepth;
entry->stoptime = stoptime;
entry->ndl = ndl;
+ entry->in_deco = in_deco;
entry->cns = cns;
entry->po2 = po2;
entry->cylinderindex = sample->cylinderindex;
@@ -1965,6 +1971,10 @@ static void plot_string(struct plot_data *entry, char *buf, size_t bufsize,
snprintf(buf, bufsize, "%s\nDeco:unkn time @ %.0f %s", buf2,
depthvalue, depth_unit);
}
+ } else if (entry->in_deco) {
+ /* this means we had in_deco set but don't have a stop depth */
+ memcpy(buf2, buf, bufsize);
+ snprintf(buf, bufsize, "%s\nIn deco", buf2);
} else if (has_ndl) {
memcpy(buf2, buf, bufsize);
snprintf(buf, bufsize, "%s\nNDL:%umin", buf2, entry->ndl / 60);
diff --git a/save-xml.c b/save-xml.c
index 45caefe4c..61469e9ce 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -330,6 +330,8 @@ static void save_sample(FILE *f, struct sample *sample, const struct sample *pre
/* the deco/ndl values are stored whenever they change */
if (sample->ndl.seconds != prev->ndl.seconds)
fprintf(f, " ndl='%u:%02u min'", FRACTION(sample->ndl.seconds, 60));
+ if (sample->in_deco != prev->in_deco)
+ fprintf(f, " in_deco='%d'", sample->in_deco ? 1 : 0);
if (sample->stoptime.seconds != prev->stoptime.seconds)
fprintf(f, " stoptime='%u:%02u min'", FRACTION(sample->stoptime.seconds, 60));
if (sample->stopdepth.mm != prev->stopdepth.mm)
diff --git a/uemis.c b/uemis.c
index 8d05a99f9..ded060b44 100644
--- a/uemis.c
+++ b/uemis.c
@@ -254,17 +254,20 @@ static void uemis_event(struct dive *dive, struct divecomputer *dc, struct sampl
stopdepth = rel_mbar_to_depth(u_sample->hold_depth, dive);
if ((flags[3] & 1) | (flags[5] & 2)) {
/* deco */
+ sample->in_deco = TRUE;
sample->stopdepth.mm = stopdepth;
sample->stoptime.seconds = u_sample->hold_time *60;
sample->ndl.seconds = 0;
} else if (flags[0] & 128) {
/* safety stop - distinguished from deco stop by having
* both ndl and stop information */
+ sample->in_deco = FALSE;
sample->stopdepth.mm = stopdepth;
sample->stoptime.seconds = u_sample->hold_time *60;
sample->ndl.seconds = lastndl;
} else {
/* NDL */
+ sample->in_deco = FALSE;
lastndl = sample->ndl.seconds = u_sample->hold_time *60;
sample->stopdepth.mm = 0;
sample->stoptime.seconds = 0;