summaryrefslogtreecommitdiffstats
path: root/core/divelist.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/divelist.c')
-rw-r--r--core/divelist.c153
1 files changed, 115 insertions, 38 deletions
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;