aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/dive.h2
-rw-r--r--core/divelist.c153
-rw-r--r--core/divelist.h2
-rw-r--r--core/planner.c4
-rw-r--r--core/plannernotes.c23
-rw-r--r--qt-models/diveplannermodel.cpp1
6 files changed, 136 insertions, 49 deletions
diff --git a/core/dive.h b/core/dive.h
index 74404a223..8e862f691 100644
--- a/core/dive.h
+++ b/core/dive.h
@@ -911,7 +911,7 @@ struct diveplan {
short vpmb_conservatism;
struct divedatapoint *dp;
int eff_gflow, eff_gfhigh;
- unsigned int surface_interval;
+ int surface_interval;
};
struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, int cylinderid, int po2, bool entered);
diff --git a/core/divelist.c b/core/divelist.c
index d079b11bf..162d87614 100644
--- a/core/divelist.c
+++ b/core/divelist.c
@@ -11,7 +11,7 @@
* void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2low_p)
* int total_weight(struct dive *dive)
* int get_divenr(struct dive *dive)
- * double init_decompression(struct dive *dive)
+ * int init_decompression(struct dive *dive)
* void update_cylinder_related_info(struct dive *dive)
* void dump_trip_list(void)
* dive_trip_t *find_matching_trip(timestamp_t when)
@@ -367,92 +367,169 @@ int get_divesite_idx(struct dive_site *ds)
static struct gasmix air = { .o2.permille = O2_IN_AIR, .he.permille = 0 };
/* take into account previous dives until there is a 48h gap between dives */
-/* return true if this is a repetitive dive */
-unsigned int init_decompression(struct dive *dive)
+/* return last surface time before this dive or dummy value of 48h */
+/* return negative surface time if dives are overlapping */
+int init_decompression(struct dive *dive)
{
int i, divenr = -1;
- unsigned int surface_time = 0;
- timestamp_t when, lasttime = 0, laststart = 0;
+ int surface_time = 48 * 60 * 60;
+ timestamp_t last_endtime = 0, last_starttime = 0;
bool deco_init = false;
double surface_pressure;
if (!dive)
return false;
- surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0;
divenr = get_divenr(dive);
- when = dive->when;
- i = divenr;
- if (i < 0) {
- i = dive_table.nr - 1;
- while (i >= 0 && get_dive(i)->when > when)
- --i;
+ i = divenr >= 0 ? divenr : dive_table.nr;
+#if DECO_CALC_DEBUG & 2
+ if (i >= 0 && i < dive_table.nr)
+ printf("\n\n*** Init deco for dive #%d %d\n", i, get_dive(i)->number);
+ else
+ printf("\n\n*** Init deco for dive #%d\n", i);
+#endif
+ /* Look at next dive in dive list table and correct i when needed */
+ while (i < dive_table.nr - 1) {
+ struct dive *pdive = get_dive(i);
+ if (!pdive || pdive->when > dive->when)
+ break;
i++;
}
+ /* Look at previous dive in dive list table and correct i when needed */
+ while (i > 0) {
+ struct dive *pdive = get_dive(i - 1);
+ if (!pdive || pdive->when < dive->when)
+ break;
+ i--;
+ }
+#if DECO_CALC_DEBUG & 2
+ printf("Dive number corrected to #%d\n", i);
+#endif
+ last_starttime = dive->when;
+ /* Walk backwards to check previous dives - how far do we need to go back? */
while (i--) {
+ if (i == divenr && i > 0)
+ i--;
+#if DECO_CALC_DEBUG & 2
+ printf("Check if dive #%d %d has to be considered as prev dive: ", i, get_dive(i)->number);
+#endif
struct dive *pdive = get_dive(i);
/* we don't want to mix dives from different trips as we keep looking
* for how far back we need to go */
- if (dive->divetrip && pdive->divetrip != dive->divetrip)
+ if (dive->divetrip && pdive->divetrip != dive->divetrip) {
+#if DECO_CALC_DEBUG & 2
+ printf("No - other dive trip\n");
+#endif
continue;
- if (!pdive || pdive->when >= when || dive_endtime(pdive) + 48 * 60 * 60 < when)
+ }
+ if (!pdive || pdive->when >= dive->when || dive_endtime(pdive) + 48 * 60 * 60 < last_starttime) {
+#if DECO_CALC_DEBUG & 2
+ printf("No\n");
+#endif
break;
- /* For simultaneous dives, only consider the first */
- if (pdive->when == laststart)
- continue;
- lasttime = dive_endtime(pdive);
+ }
+ last_starttime = pdive->when;
+#if DECO_CALC_DEBUG & 2
+ printf("Yes\n");
+#endif
}
- while (++i < (divenr >= 0 ? divenr : dive_table.nr)) {
+ /* Walk forward an add dives and surface intervals to deco */
+ while (++i < dive_table.nr) {
+#if DECO_CALC_DEBUG & 2
+ printf("Check if dive #%d %d will be really added to deco calc: ", i, get_dive(i)->number);
+#endif
struct dive *pdive = get_dive(i);
/* again skip dives from different trips */
- if (dive->divetrip && dive->divetrip != pdive->divetrip)
+ if (dive->divetrip && dive->divetrip != pdive->divetrip) {
+#if DECO_CALC_DEBUG & 2
+ printf("No - other dive trip\n");
+#endif
continue;
+ }
/* Don't add future dives */
- if (pdive->when > dive->when)
- continue; /* This could be break if the divelist is always sorted */
+ if (pdive->when >= dive->when) {
+#if DECO_CALC_DEBUG & 2
+ printf("No - future or same dive\n");
+#endif
+ break;
+ }
+ /* Don't add the copy of the dive itself */
+ if (i == divenr) {
+#if DECO_CALC_DEBUG & 2
+ printf("No - copy of dive\n");
+#endif
+ continue;
+ }
+#if DECO_CALC_DEBUG & 2
+ printf("Yes\n");
+#endif
+
surface_pressure = get_surface_pressure_in_mbar(pdive, true) / 1000.0;
+ /* Is it the first dive we add? */
if (!deco_init) {
+#if DECO_CALC_DEBUG & 2
+ printf("Init deco\n");
+#endif
clear_deco(surface_pressure);
deco_init = true;
#if DECO_CALC_DEBUG & 2
+ printf("Tissues after init:\n");
dump_tissues();
#endif
}
- if (pdive->when > lasttime) {
- surface_time = pdive->when - lasttime;
- lasttime = dive_endtime(pdive);
+ else {
+ surface_time = pdive->when - last_endtime;
+ if (surface_time < 0) {
+#if DECO_CALC_DEBUG & 2
+ printf("Exit because surface intervall is %d\n", surface_time);
+#endif
+ return surface_time;
+ }
add_segment(surface_pressure, &air, surface_time, 0, dive, prefs.decosac);
#if DECO_CALC_DEBUG & 2
- printf("after surface intervall of %d:%02u\n", FRACTION(surface_time, 60));
+ printf("Tissues after surface intervall of %d:%02u:\n", FRACTION(surface_time, 60));
dump_tissues();
#endif
}
+
add_dive_to_deco(pdive);
- laststart = pdive->when;
+
+ last_starttime = pdive->when;
+ last_endtime = dive_endtime(pdive);
clear_vpmb_state();
#if DECO_CALC_DEBUG & 2
- printf("added dive #%d\n", pdive->number);
+ printf("Tissues after added dive #%d:\n", pdive->number);
dump_tissues();
#endif
}
- /* add the final surface time */
- if (lasttime && dive->when > lasttime) {
- surface_time = dive->when - lasttime;
- surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0;
- add_segment(surface_pressure, &air, surface_time, 0, dive, prefs.decosac);
+
+ surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0;
+ /* We don't have had a previous dive at all? */
+ if (!deco_init) {
+#if DECO_CALC_DEBUG & 2
+ printf("Init deco\n");
+#endif
+ clear_deco(surface_pressure);
#if DECO_CALC_DEBUG & 2
- printf("after surface intervall of %d:%02u\n", FRACTION(surface_time, 60));
+ printf("Tissues after no previous dive, surface time set to 48h:\n");
dump_tissues();
#endif
}
- if (!deco_init) {
- surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0;
- clear_deco(surface_pressure);
+ else {
+ surface_time = dive->when - last_endtime;
+ if (surface_time < 0) {
#if DECO_CALC_DEBUG & 2
- printf("no previous dive\n");
+ printf("Exit because surface intervall is %d\n", surface_time);
+#endif
+ return surface_time;
+ }
+ add_segment(surface_pressure, &air, surface_time, 0, dive, prefs.decosac);
+#if DECO_CALC_DEBUG & 2
+ printf("Tissues after surface intervall of %d:%02u:\n", FRACTION(surface_time, 60));
dump_tissues();
#endif
}
+
// I do not dare to remove this call. We don't need the result but it might have side effects. Bummer.
tissue_tolerance_calc(dive, surface_pressure);
return surface_time;
diff --git a/core/divelist.h b/core/divelist.h
index 74b616890..44f0bf0b0 100644
--- a/core/divelist.h
+++ b/core/divelist.h
@@ -15,7 +15,7 @@ extern void update_cylinder_related_info(struct dive *);
extern void mark_divelist_changed(int);
extern int unsaved_changes(void);
extern void remove_autogen_trips(void);
-extern unsigned int init_decompression(struct dive *dive);
+extern int init_decompression(struct dive *dive);
/* divelist core logic functions */
extern void process_dives(bool imported, bool prefer_imported);
diff --git a/core/planner.c b/core/planner.c
index 8010979d9..18f3c8701 100644
--- a/core/planner.c
+++ b/core/planner.c
@@ -127,7 +127,7 @@ void interpolate_transition(struct dive *dive, duration_t t0, duration_t t1, dep
}
/* returns the tissue tolerance at the end of this (partial) dive */
-unsigned int tissue_at_end(struct dive *dive, struct deco_state **cached_datap)
+int tissue_at_end(struct dive *dive, struct deco_state **cached_datap)
{
struct divecomputer *dc;
struct sample *sample, *psample;
@@ -135,7 +135,7 @@ unsigned int tissue_at_end(struct dive *dive, struct deco_state **cached_datap)
depth_t lastdepth = {};
duration_t t0 = {}, t1 = {};
struct gasmix gas;
- unsigned int surface_interval = 0;
+ int surface_interval = 0;
if (!dive)
return 0;
diff --git a/core/plannernotes.c b/core/plannernotes.c
index ffbf0b1cb..131820a5b 100644
--- a/core/plannernotes.c
+++ b/core/plannernotes.c
@@ -85,20 +85,29 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
len = show_disclaimer ? snprintf(buffer, sz_buffer, "<div><b>%s</b><br></div>", disclaimer) : 0;
- if (diveplan->surface_interval > 60) {
- len += snprintf(buffer + len, sz_buffer - len, "<div><b>%s (%s) %s %d:%02d) %s %s<br>",
+ if (diveplan->surface_interval < 0) {
+ len += snprintf(buffer + len, sz_buffer - len, "<div><b>%s (%s) %s<br>",
translate("gettextFromC", "Subsurface"),
subsurface_canonical_version(),
- translate("gettextFromC", "dive plan</b> (surface interval "),
- FRACTION(diveplan->surface_interval / 60, 60),
- translate("gettextFromC", "created on"),
- get_current_date());
- } else {
+ translate("gettextFromC", "dive plan</b> (Overlapping dives detected)"));
+ dive->notes = strdup(buffer);
+ free((void *)buffer);
+ free((void *)temp);
+ return;
+ } else if (diveplan->surface_interval >= 48 * 60 *60) {
len += snprintf(buffer + len, sz_buffer - len, "<div><b>%s (%s) %s %s</b><br>",
translate("gettextFromC", "Subsurface"),
subsurface_canonical_version(),
translate("gettextFromC", "dive plan</b> created on"),
get_current_date());
+ } else {
+ len += snprintf(buffer + len, sz_buffer - len, "<div><b>%s (%s) %s %d:%02d) %s %s<br>",
+ translate("gettextFromC", "Subsurface"),
+ subsurface_canonical_version(),
+ translate("gettextFromC", "dive plan</b> (surface interval "),
+ FRACTION(diveplan->surface_interval / 60, 60),
+ translate("gettextFromC", "created on"),
+ get_current_date());
}
if (prefs.display_variations)
diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp
index 0c90b0a48..10d912846 100644
--- a/qt-models/diveplannermodel.cpp
+++ b/qt-models/diveplannermodel.cpp
@@ -1101,6 +1101,7 @@ void DivePlannerPointsModel::createPlan(bool replanCopy)
copy_dive(&displayed_dive, current_dive);
}
mark_divelist_changed(true);
+ sort_table(&dive_table);
// Remove and clean the diveplan, so we don't delete
// the dive by mistake.