aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/dive.c52
-rw-r--r--core/dive.h1
-rw-r--r--core/divelist.c6
-rw-r--r--core/plannernotes.c12
-rw-r--r--core/profile.c19
5 files changed, 28 insertions, 62 deletions
diff --git a/core/dive.c b/core/dive.c
index ac34be7f4..950f4b336 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -241,44 +241,23 @@ void add_extra_data(struct divecomputer *dc, const char *key, const char *value)
}
}
-struct event *get_next_divemodechange(struct event **evd, bool update_pointer)
-{ /* Starting at the event pointed to by evd, find the next divemode change event and initialise its
- * type and divemode. Requires an external pointer (evd) to a divemode change event, usually
- * a copy of dc->events. This function is self-tracking if update_pointer is TRUE and the value
- * of evd needs no manipulation outside of this function. If update_pointer is FALSE, pointer evd
- * is NOT updated with the address of the last examined event in the while() loop. */
- struct event *ev = *evd;
- while (ev) { // Step through the events.
- for (int i=0; i<3; i++) { // For each event name search for one of the above strings
- if (!strcmp(ev->name,divemode_text[i])) { // if the event name is one of the divemode names
- ev->divemode = i; // set the event type to the dive mode
- if (update_pointer)
- *evd = ev->next;
- return (ev);
- }
- }
- ev = ev->next;
+/* Find the divemode at time 'time' (in seconds) into the dive. Sequentially step through the divemode-change events,
+ * saving the dive mode for each event. When the events occur AFTER 'time' seconds, the last stored divemode
+ * is returned. This function is self-tracking, relying on setting the event pointer 'evp' so that, in each iteration
+ * that calls this function, the search does not have to begin at the first event of the dive */
+enum dive_comp_type get_current_divemode(struct divecomputer *dc, int time, struct event **evp, enum dive_comp_type *divemode)
+{
+ struct event *ev = *evp;
+ if (*divemode == UNDEF_COMP_TYPE) {
+ *divemode = dc->divemode;
+ ev = dc ? dc->events : NULL;
}
- if (update_pointer)
- *evd = NULL;
- return (NULL);
-}
-
-enum dive_comp_type get_divemode_at_time(struct divecomputer *dc, int dtime, struct event **ev_dmc)
-{ /* For a particular dive computer and its linked list of events, find the divemode dtime seconds
- * into the dive. Requires an external pointer (ev_dmc) to a divemode change event, usually
- * initialised by a call to get_next_divemodechange(&copy-of-dc->events). This function is self-tracking
- * and the value of ev_dmc needs no manipulation outside of this function. */
- enum dive_comp_type mode = dc->divemode;
- struct event *ev_last = *ev_dmc, *ev = *ev_dmc; // ev_dmc points to event initialised by get_next_divemodechange()
- while (ev && (dtime >= ev->time.seconds)) { // If dtime is AFTER this event time, store divemode
- mode = ev->divemode;
- ev_last = ev;
-// ev = peek_next_divemodechange(ev->next); // peek at the time of the following divemode change event
- ev = get_next_divemodechange(&ev->next, FALSE);
+ while (ev && ev->time.seconds < time) {
+ *divemode = (enum dive_comp_type) ev->value;
+ ev = get_next_event(ev->next, "modechange");
}
- *ev_dmc = ev_last;
- return (mode);
+ *evp = ev;
+ return *divemode;
}
/* this returns a pointer to static variable - so use it right away after calling */
@@ -291,7 +270,6 @@ struct gasmix *get_gasmix_from_event(struct dive *dive, struct event *ev)
return &dive->cylinder[index].gasmix;
return &ev->gas.mix;
}
-
return &dummy;
}
diff --git a/core/dive.h b/core/dive.h
index d336318d5..75f042790 100644
--- a/core/dive.h
+++ b/core/dive.h
@@ -362,6 +362,7 @@ struct dive_components {
unsigned int weights : 1;
};
+extern enum dive_comp_type get_current_divemode(struct divecomputer *dc, int time, struct event **evp, enum dive_comp_type *divemode);
extern struct event *get_next_divemodechange(struct event **evd, bool update_pointer);
extern enum dive_comp_type get_divemode_at_time(struct divecomputer *dc, int dtime, struct event **ev_dmc);
diff --git a/core/divelist.c b/core/divelist.c
index d70130b31..acac8ec6b 100644
--- a/core/divelist.c
+++ b/core/divelist.c
@@ -414,9 +414,9 @@ static void add_dive_to_deco(struct deco_state *ds, struct dive *dive)
{
struct divecomputer *dc = &dive->dc;
struct gasmix *gasmix = NULL;
- struct event *ev = NULL;
- struct event *ev_dmc = dc->events, *ev_dmt = get_next_divemodechange(&ev_dmc, TRUE);
int i;
+ struct event *ev = NULL, *evd = NULL;
+ enum dive_comp_type current_divemode = UNDEF_COMP_TYPE;
if (!dc)
return;
@@ -432,7 +432,7 @@ static void add_dive_to_deco(struct deco_state *ds, struct dive *dive)
int depth = interpolate(psample->depth.mm, sample->depth.mm, j - t0, t1 - t0);
gasmix = get_gasmix(dive, dc, j, &ev, gasmix);
add_segment(ds, depth_to_bar(depth, dive), gasmix, 1, sample->setpoint.mbar,
- get_divemode_at_time(dc, j, &ev_dmt), dive->sac);
+ get_current_divemode(&dive->dc, j, &evd, &current_divemode), dive->sac);
}
}
}
diff --git a/core/plannernotes.c b/core/plannernotes.c
index 4d70b9af9..9927ad26a 100644
--- a/core/plannernotes.c
+++ b/core/plannernotes.c
@@ -539,10 +539,8 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
bool o2warning_exist = false;
enum dive_comp_type current_divemode;
double amb;
- struct event *nextev, *evd = dive->dc.events;
-
- current_divemode = dive->dc.divemode;
- nextev = get_next_divemodechange(&evd, TRUE);
+ struct event *evd = NULL;
+ current_divemode = UNDEF_COMP_TYPE;
if (dive->dc.divemode != CCR) {
while (dp) {
@@ -550,11 +548,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
struct gas_pressures pressures;
struct gasmix *gasmix = &dive->cylinder[dp->cylinderid].gasmix;
- if (nextev && (dp->time >= nextev->time.seconds)) { // If there are divemode changes and divedatapoint time
- current_divemode = nextev->divemode; // has reached that of the current divemode event, then set the
- nextev = get_next_divemodechange(&evd, TRUE); // current divemode and find the next divemode event
- }
-
+ current_divemode = get_current_divemode(&dive->dc, dp->time, &evd, &current_divemode);
amb = depth_to_atm(dp->depth.mm, dive);
fill_pressures(&pressures, amb, gasmix, (current_divemode == OC) ? 0.0 : amb * gasmix->o2.permille / 1000.0, current_divemode);
diff --git a/core/profile.c b/core/profile.c
index 789727635..be20c7ac7 100644
--- a/core/profile.c
+++ b/core/profile.c
@@ -996,7 +996,6 @@ void calculate_deco_information(struct deco_state *ds, struct deco_state *planne
double surface_pressure = (dc->surface_pressure.mbar ? dc->surface_pressure.mbar : get_surface_pressure_in_mbar(dive, true)) / 1000.0;
bool first_iteration = true;
int prev_deco_time = 10000000, time_deep_ceiling = 0;
- enum dive_comp_type current_divemode;
if (!in_planner()) {
ds->deco_time = 0;
@@ -1018,16 +1017,16 @@ void calculate_deco_information(struct deco_state *ds, struct deco_state *planne
if (decoMode() == VPMB)
ds->first_ceiling_pressure.mbar = depth_to_mbar(first_ceiling, dive);
struct gasmix *gasmix = NULL;
- struct event *ev = NULL, *ev_dmc = dc->events, *ev_dmt = get_next_divemodechange(&ev_dmc, TRUE);
+ struct event *ev = NULL, *evd = NULL;
+ enum dive_comp_type current_divemode = UNDEF_COMP_TYPE;
for (i = 1; i < pi->nr; i++) {
struct plot_data *entry = pi->entry + i;
int j, t0 = (entry - 1)->sec, t1 = entry->sec;
int time_stepsize = 20;
- current_divemode = get_divemode_at_time(dc, entry->sec, &ev_dmt);
+ current_divemode = get_current_divemode(dc, entry->sec, &evd, &current_divemode);
gasmix = get_gasmix(dive, dc, t1, &ev, gasmix);
-
entry->ambpressure = depth_to_bar(entry->depth, dive);
entry->gfline = get_gf(ds, entry->ambpressure, dive) * (100.0 - AMB_PERCENTAGE) + AMB_PERCENTAGE;
if (t0 > t1) {
@@ -1205,24 +1204,18 @@ static int calculate_ccr_po2(struct plot_data *entry, struct divecomputer *dc)
static void calculate_gas_information_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
{
int i;
- enum dive_comp_type current_divemode;
double amb_pressure;
struct gasmix *gasmix = NULL;
- struct event *nextev, *evg = NULL, *evd = dc->events;
-
- current_divemode = dc->divemode;
- nextev = get_next_divemodechange(&evd, TRUE);
+ struct event *evg = NULL, *evd = NULL;
+ enum dive_comp_type current_divemode = UNDEF_COMP_TYPE;
for (i = 1; i < pi->nr; i++) {
int fn2, fhe;
struct plot_data *entry = pi->entry + i;
gasmix = get_gasmix(dive, dc, entry->sec, &evg, gasmix);
- if (nextev && (entry->sec > nextev->time.seconds)) { // If there are divemode changes and sample time
- current_divemode = nextev->divemode; // has reached that of the current divemode event, then set the
- nextev = get_next_divemodechange(&evd, TRUE); // current divemode and find the next divemode event
- }
amb_pressure = depth_to_bar(entry->depth, dive);
+ current_divemode = get_current_divemode(dc, entry->sec, &evd, &current_divemode);
fill_pressures(&entry->pressures, amb_pressure, gasmix, (current_divemode == OC) ? 0.0 : entry->o2pressure.mbar / 1000.0, current_divemode);
fn2 = (int)(1000.0 * entry->pressures.n2 / amb_pressure);
fhe = (int)(1000.0 * entry->pressures.he / amb_pressure);