summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2014-10-28 13:48:15 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2014-10-28 14:04:19 -0700
commite32ba4d6d8115176e1ce0f4960926985b52164ca (patch)
tree8b45963724d70eaf69d2af61b81c27c836a1213e
parent874754e22b8678ab3d5314c56fda860ea844fc55 (diff)
downloadsubsurface-e32ba4d6d8115176e1ce0f4960926985b52164ca.tar.gz
Improve tank handling for Cobalt
This isn't Cobalt specific, this is specific to dive computers that indicate the first tank that's in use with a gaschange event that coincides with the first sample. We need to make sure that we suppress showing that gas change event (regardless which cylinder it goes to) and instead set the correct cylinder index from the very start of the dive. This works with the test data I have and doesn't seem to break thing with any of the files that I tried... but I'm worried that this is not the right way to do things. Fixes #742 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--dive.c25
-rw-r--r--dive.h1
-rw-r--r--profile.c18
-rw-r--r--qt-ui/profile/diveeventitem.cpp15
-rw-r--r--statistics.c2
5 files changed, 50 insertions, 11 deletions
diff --git a/dive.c b/dive.c
index 9395c93f9..9f4df56dc 100644
--- a/dive.c
+++ b/dive.c
@@ -782,6 +782,19 @@ static int same_rounded_pressure(pressure_t a, pressure_t b)
return abs(a.mbar - b.mbar) <= 500;
}
+/* Some dive computers (Cobalt) don't start the dive with cylinder 0 but explicitly
+ * tell us what the first gas is with a gas change event in the first sample.
+ * Sneakily we'll use a return value of 0 (or FALSE) when there is no explicit
+ * first cylinder - in which case cylinder 0 is indeed the first cylinder */
+int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc)
+{
+ struct event *ev = get_next_event(dc->events, "gaschange");
+ if (ev && ev->time.seconds == dc->sample[0].time.seconds)
+ return get_cylinder_index(dive, ev);
+ else
+ return 0;
+}
+
void sanitize_gasmix(struct gasmix *mix)
{
unsigned int o2, he;
@@ -1095,10 +1108,14 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
int lasto2val[3] = { 0, 0, 0 };
int lasttemp = 0, lastpressure = 0, lastdiluentpressure = 0;
int pressure_delta[MAX_CYLINDERS] = { INT_MAX, };
+ int first_cylinder;
/* Fixup duration and mean depth */
fixup_dc_duration(dc);
update_min_max_temperatures(dive, dc->watertemp);
+
+ /* make sure we know for which tank the pressure values are intended */
+ first_cylinder = explicit_first_cylinder(dive, dc);
for (i = 0; i < dc->samples; i++) {
struct sample *sample = dc->sample + i;
int time = sample->time.seconds;
@@ -1106,7 +1123,13 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
int temp = sample->temperature.mkelvin;
int pressure = sample->cylinderpressure.mbar;
int diluent_pressure = sample->diluentpressure.mbar;
- int index = sample->sensor;
+ int index;
+
+ /* if we have an explicit first cylinder */
+ if (sample->sensor == 0 && first_cylinder != 0)
+ sample->sensor = first_cylinder;
+
+ index = sample->sensor;
if (index == lastindex) {
/* Remove duplicate redundant pressure information */
diff --git a/dive.h b/dive.h
index ca81a4c88..6809d8384 100644
--- a/dive.h
+++ b/dive.h
@@ -360,6 +360,7 @@ extern unsigned int dive_get_picture_count(struct dive *d);
extern void picture_load_exif_data(struct picture *p, timestamp_t *timestamp);
extern void dive_set_geodata_from_picture(struct dive *d, struct picture *pic);
+extern int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc);
static inline int dive_has_gps_location(struct dive *dive)
{
diff --git a/profile.c b/profile.c
index f0b7041ee..4bc94220b 100644
--- a/profile.c
+++ b/profile.c
@@ -378,6 +378,19 @@ static int set_cylinder_index(struct plot_info *pi, int i, int cylinderindex, un
return i;
}
+/* normally the first cylinder has index 0... if not, we need to fix this up here */
+static int set_first_cylinder_index(struct plot_info *pi, int i, int cylinderindex, unsigned int end)
+{
+ while (i < pi->nr) {
+ struct plot_data *entry = pi->entry + i;
+ if (entry->sec > end)
+ break;
+ entry->cylinderindex = cylinderindex;
+ i++;
+ }
+ return i;
+}
+
static void check_gas_change_events(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
{
int i = 0, cylinderindex = 0;
@@ -386,6 +399,11 @@ static void check_gas_change_events(struct dive *dive, struct divecomputer *dc,
if (!ev)
return;
+ // for dive computers that tell us their first gas as an event on the first sample
+ // we need to make sure things are setup correctly
+ if ((cylinderindex = explicit_first_cylinder(dive, dc)) != 0)
+ set_first_cylinder_index(pi, 0, cylinderindex, ~0u);
+
do {
i = set_cylinder_index(pi, i, cylinderindex, ev->time.seconds);
cylinderindex = get_cylinder_index(dive, ev);
diff --git a/qt-ui/profile/diveeventitem.cpp b/qt-ui/profile/diveeventitem.cpp
index bd22c0db9..bd9735a96 100644
--- a/qt-ui/profile/diveeventitem.cpp
+++ b/qt-ui/profile/diveeventitem.cpp
@@ -127,16 +127,13 @@ bool DiveEventItem::shouldBeHidden()
struct event *event = internalEvent;
/*
- * Gas change events - particularly at the beginning of a dive - are
- * special. It's just the dive computer specifying the initial gas.
- *
- * Don't bother showing them if they match the first gas already
+ * Some gas change events are special. Some dive computers just tell us the initial gas this way.
+ * Don't bother showing those
*/
- if (!strcmp(event->name, "gaschange") && event->time.seconds <= 30) {
- struct dive *dive = &displayed_dive;
- if (dive && get_cylinder_index(dive, event) == 0)
- return true;
- }
+ struct sample *first_sample = &get_dive_dc(&displayed_dive, dc_number)->sample[0];
+ if (!strcmp(event->name, "gaschange") && (event->time.seconds < 30 || event->time.seconds == first_sample->time.seconds))
+ return true;
+
for (int i = 0; i < evn_used; i++) {
if (!strcmp(event->name, ev_namelist[i].ev_name) && ev_namelist[i].plot_ev == false)
return true;
diff --git a/statistics.c b/statistics.c
index 01adf4f14..d78e4a862 100644
--- a/statistics.c
+++ b/statistics.c
@@ -302,7 +302,7 @@ bool is_cylinder_used(struct dive *dive, int idx)
for_each_dc(dive, dc) {
struct event *event = get_next_event(dc->events, "gaschange");
while (event) {
- if (event->time.seconds < 30)
+ if (event->time.seconds < 30 || event->time.seconds == dc->sample[0].time.seconds)
firstGasExplicit = true;
if (get_cylinder_index(dive, event) == idx)
return true;