diff options
Diffstat (limited to 'core/divelist.c')
-rw-r--r-- | core/divelist.c | 153 |
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; |