summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/dive.c242
-rw-r--r--core/dive.h261
2 files changed, 267 insertions, 236 deletions
diff --git a/core/dive.c b/core/dive.c
index c977183a3..da4b19346 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -4062,3 +4062,245 @@ fraction_t best_he(depth_t depth, struct dive *dive)
fhe.permille = 0;
return fhe;
}
+
+bool gasmix_is_air(const struct gasmix *gasmix)
+{
+ int o2 = gasmix->o2.permille;
+ int he = gasmix->he.permille;
+ return (he == 0) && (o2 == 0 || ((o2 >= O2_IN_AIR - 1) && (o2 <= O2_IN_AIR + 1)));
+}
+
+void invalidate_dive_cache(struct dive *dive)
+{
+ memset(dive->git_id, 0, 20);
+}
+
+bool dive_cache_is_valid(const struct dive *dive)
+{
+ static const unsigned char null_id[20] = { 0, };
+ return !!memcmp(dive->git_id, null_id, 20);
+}
+
+int get_surface_pressure_in_mbar(const struct dive *dive, bool non_null)
+{
+ int mbar = dive->surface_pressure.mbar;
+ if (!mbar && non_null)
+ mbar = SURFACE_PRESSURE;
+ return mbar;
+}
+
+/* Pa = N/m^2 - so we determine the weight (in N) of the mass of 10m
+ * of water (and use standard salt water at 1.03kg per liter if we don't know salinity)
+ * and add that to the surface pressure (or to 1013 if that's unknown) */
+int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity)
+{
+ double specific_weight;
+ int mbar = surface_pressure.mbar;
+
+ if (!mbar)
+ mbar = SURFACE_PRESSURE;
+ if (!salinity)
+ salinity = SEAWATER_SALINITY;
+ if (salinity < 500)
+ salinity += FRESHWATER_SALINITY;
+ specific_weight = salinity / 10000.0 * 0.981;
+ mbar += lrint(depth / 10.0 * specific_weight);
+ return mbar;
+}
+
+int depth_to_mbar(int depth, struct dive *dive)
+{
+ return calculate_depth_to_mbar(depth, dive->surface_pressure, dive->salinity);
+}
+
+double depth_to_bar(int depth, struct dive *dive)
+{
+ return depth_to_mbar(depth, dive) / 1000.0;
+}
+
+double depth_to_atm(int depth, struct dive *dive)
+{
+ return mbar_to_atm(depth_to_mbar(depth, dive));
+}
+
+/* for the inverse calculation we use just the relative pressure
+ * (that's the one that some dive computers like the Uemis Zurich
+ * provide - for the other models that do this libdivecomputer has to
+ * take care of this, but the Uemis we support natively */
+int rel_mbar_to_depth(int mbar, struct dive *dive)
+{
+ int cm;
+ double specific_weight = 1.03 * 0.981;
+ if (dive->dc.salinity)
+ specific_weight = dive->dc.salinity / 10000.0 * 0.981;
+ /* whole mbar gives us cm precision */
+ cm = (int)lrint(mbar / specific_weight);
+ return cm * 10;
+}
+
+int mbar_to_depth(int mbar, struct dive *dive)
+{
+ pressure_t surface_pressure;
+ if (dive->surface_pressure.mbar)
+ surface_pressure = dive->surface_pressure;
+ else
+ surface_pressure.mbar = SURFACE_PRESSURE;
+ return rel_mbar_to_depth(mbar - surface_pressure.mbar, dive);
+}
+
+/* MOD rounded to multiples of roundto mm */
+depth_t gas_mod(struct gasmix *mix, pressure_t po2_limit, struct dive *dive, int roundto)
+{
+ depth_t rounded_depth;
+
+ double depth = (double) mbar_to_depth(po2_limit.mbar * 1000 / get_o2(mix), dive);
+ rounded_depth.mm = (int)lrint(depth / roundto) * roundto;
+ return rounded_depth;
+}
+
+/* Maximum narcotic depth rounded to multiples of roundto mm */
+depth_t gas_mnd(struct gasmix *mix, depth_t end, struct dive *dive, int roundto)
+{
+ depth_t rounded_depth;
+ pressure_t ppo2n2;
+ ppo2n2.mbar = depth_to_mbar(end.mm, dive);
+
+ int maxambient = (int)lrint(ppo2n2.mbar / (1 - get_he(mix) / 1000.0));
+ rounded_depth.mm = (int)lrint(((double)mbar_to_depth(maxambient, dive)) / roundto) * roundto;
+ return rounded_depth;
+}
+
+struct dive *get_dive(int nr)
+{
+ if (nr >= dive_table.nr || nr < 0)
+ return NULL;
+ return dive_table.dives[nr];
+}
+
+struct dive *get_dive_from_table(int nr, struct dive_table *dt)
+{
+ if (nr >= dt->nr || nr < 0)
+ return NULL;
+ return dt->dives[nr];
+}
+
+struct dive_site *get_dive_site_for_dive(struct dive *dive)
+{
+ if (dive)
+ return get_dive_site_by_uuid(dive->dive_site_uuid);
+ return NULL;
+}
+
+const char *get_dive_country(struct dive *dive)
+{
+ struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid);
+ if (ds) {
+ int idx = taxonomy_index_for_category(&ds->taxonomy, TC_COUNTRY);
+ if (idx >= 0)
+ return ds->taxonomy.category[idx].value;
+ }
+ return NULL;
+}
+
+char *get_dive_location(struct dive *dive)
+{
+ struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid);
+ if (ds && ds->name)
+ return ds->name;
+ return NULL;
+}
+
+unsigned int number_of_computers(struct dive *dive)
+{
+ unsigned int total_number = 0;
+ struct divecomputer *dc = &dive->dc;
+
+ if (!dive)
+ return 1;
+
+ do {
+ total_number++;
+ dc = dc->next;
+ } while (dc);
+ return total_number;
+}
+
+struct divecomputer *get_dive_dc(struct dive *dive, int nr)
+{
+ struct divecomputer *dc;
+ if (!dive)
+ return NULL;
+ dc = &dive->dc;
+
+ while (nr-- > 0) {
+ dc = dc->next;
+ if (!dc)
+ return &dive->dc;
+ }
+ return dc;
+}
+
+struct dive *get_dive_by_uniq_id(int id)
+{
+ int i;
+ struct dive *dive = NULL;
+
+ for_each_dive (i, dive) {
+ if (dive->id == id)
+ break;
+ }
+#ifdef DEBUG
+ if (dive == NULL) {
+ fprintf(stderr, "Invalid id %x passed to get_dive_by_diveid, try to fix the code\n", id);
+ exit(1);
+ }
+#endif
+ return dive;
+}
+
+int get_idx_by_uniq_id(int id)
+{
+ int i;
+ struct dive *dive = NULL;
+
+ for_each_dive (i, dive) {
+ if (dive->id == id)
+ break;
+ }
+#ifdef DEBUG
+ if (dive == NULL) {
+ fprintf(stderr, "Invalid id %x passed to get_dive_by_diveid, try to fix the code\n", id);
+ exit(1);
+ }
+#endif
+ return i;
+}
+
+bool dive_site_has_gps_location(struct dive_site *ds)
+{
+ return ds && (ds->latitude.udeg || ds->longitude.udeg);
+}
+
+int dive_has_gps_location(struct dive *dive)
+{
+ if (!dive)
+ return false;
+ return dive_site_has_gps_location(get_dive_site_by_uuid(dive->dive_site_uuid));
+}
+
+struct gasmix *get_gasmix(struct dive *dive, struct divecomputer *dc, int time, struct event **evp, struct gasmix *gasmix)
+{
+ struct event *ev = *evp;
+
+ if (!gasmix) {
+ int cyl = explicit_first_cylinder(dive, dc);
+ gasmix = &dive->cylinder[cyl].gasmix;
+ ev = dc ? get_next_event(dc->events, "gaschange") : NULL;
+ }
+ while (ev && ev->time.seconds < time) {
+ gasmix = get_gasmix_from_event(dive, ev);
+ ev = get_next_event(ev->next, "gaschange");
+ }
+ *evp = ev;
+ return gasmix;
+}
diff --git a/core/dive.h b/core/dive.h
index 569232a38..98ac06fdc 100644
--- a/core/dive.h
+++ b/core/dive.h
@@ -139,12 +139,7 @@ extern void sanitize_gasmix(struct gasmix *mix);
extern int gasmix_distance(const struct gasmix *a, const struct gasmix *b);
extern int find_best_gasmix_match(struct gasmix *mix, cylinder_t array[], unsigned int used);
-static inline bool gasmix_is_air(const struct gasmix *gasmix)
-{
- int o2 = gasmix->o2.permille;
- int he = gasmix->he.permille;
- return (he == 0) && (o2 == 0 || ((o2 >= O2_IN_AIR - 1) && (o2 <= O2_IN_AIR + 1)));
-}
+extern bool gasmix_is_air(const struct gasmix *gasmix);
/* Linear interpolation between 'a' and 'b', when we are 'part'way into the 'whole' distance from a to b */
static inline int interpolate(int a, int b, int part, int whole)
@@ -336,16 +331,8 @@ struct dive {
unsigned char git_id[20];
};
-static inline void invalidate_dive_cache(struct dive *dive)
-{
- memset(dive->git_id, 0, 20);
-}
-
-static inline bool dive_cache_is_valid(const struct dive *dive)
-{
- static const unsigned char null_id[20] = { 0, };
- return !!memcmp(dive->git_id, null_id, 20);
-}
+extern void invalidate_dive_cache(struct dive *dive);
+extern bool dive_cache_is_valid(const struct dive *dive);
extern int get_cylinder_idx_by_use(struct dive *dive, enum cylinderuse cylinder_use_type);
extern void cylinder_renumber(struct dive *dive, int mapping[]);
@@ -402,92 +389,15 @@ extern int get_depth_at_time(struct divecomputer *dc, unsigned int time);
extern fraction_t best_o2(depth_t depth, struct dive *dive);
extern fraction_t best_he(depth_t depth, struct dive *dive);
-static inline int get_surface_pressure_in_mbar(const struct dive *dive, bool non_null)
-{
- int mbar = dive->surface_pressure.mbar;
- if (!mbar && non_null)
- mbar = SURFACE_PRESSURE;
- return mbar;
-}
-
-/* Pa = N/m^2 - so we determine the weight (in N) of the mass of 10m
- * of water (and use standard salt water at 1.03kg per liter if we don't know salinity)
- * and add that to the surface pressure (or to 1013 if that's unknown) */
-static inline int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity)
-{
- double specific_weight;
- int mbar = surface_pressure.mbar;
-
- if (!mbar)
- mbar = SURFACE_PRESSURE;
- if (!salinity)
- salinity = SEAWATER_SALINITY;
- if (salinity < 500)
- salinity += FRESHWATER_SALINITY;
- specific_weight = salinity / 10000.0 * 0.981;
- mbar += lrint(depth / 10.0 * specific_weight);
- return mbar;
-}
-
-static inline int depth_to_mbar(int depth, struct dive *dive)
-{
- return calculate_depth_to_mbar(depth, dive->surface_pressure, dive->salinity);
-}
-
-static inline double depth_to_bar(int depth, struct dive *dive)
-{
- return depth_to_mbar(depth, dive) / 1000.0;
-}
-
-static inline double depth_to_atm(int depth, struct dive *dive)
-{
- return mbar_to_atm(depth_to_mbar(depth, dive));
-}
-
-/* for the inverse calculation we use just the relative pressure
- * (that's the one that some dive computers like the Uemis Zurich
- * provide - for the other models that do this libdivecomputer has to
- * take care of this, but the Uemis we support natively */
-static inline int rel_mbar_to_depth(int mbar, struct dive *dive)
-{
- int cm;
- double specific_weight = 1.03 * 0.981;
- if (dive->dc.salinity)
- specific_weight = dive->dc.salinity / 10000.0 * 0.981;
- /* whole mbar gives us cm precision */
- cm = (int)lrint(mbar / specific_weight);
- return cm * 10;
-}
-
-static inline int mbar_to_depth(int mbar, struct dive *dive)
-{
- pressure_t surface_pressure;
- if (dive->surface_pressure.mbar)
- surface_pressure = dive->surface_pressure;
- else
- surface_pressure.mbar = SURFACE_PRESSURE;
- return rel_mbar_to_depth(mbar - surface_pressure.mbar, dive);
-}
-
-/* MOD rounded to multiples of roundto mm */
-static inline depth_t gas_mod(struct gasmix *mix, pressure_t po2_limit, struct dive *dive, int roundto) {
- depth_t rounded_depth;
-
- double depth = (double) mbar_to_depth(po2_limit.mbar * 1000 / get_o2(mix), dive);
- rounded_depth.mm = (int)lrint(depth / roundto) * roundto;
- return rounded_depth;
-}
-
-/* Maximum narcotic depth rounded to multiples of roundto mm */
-static inline depth_t gas_mnd(struct gasmix *mix, depth_t end, struct dive *dive, int roundto) {
- depth_t rounded_depth;
- pressure_t ppo2n2;
- ppo2n2.mbar = depth_to_mbar(end.mm, dive);
-
- int maxambient = (int)lrint(ppo2n2.mbar / (1 - get_he(mix) / 1000.0));
- rounded_depth.mm = (int)lrint(((double)mbar_to_depth(maxambient, dive)) / roundto) * roundto;
- return rounded_depth;
-}
+extern int get_surface_pressure_in_mbar(const struct dive *dive, bool non_null);
+extern int calculate_depth_to_mbar(int depth, pressure_t surface_pressure, int salinity);
+extern int depth_to_mbar(int depth, struct dive *dive);
+extern double depth_to_bar(int depth, struct dive *dive);
+extern double depth_to_atm(int depth, struct dive *dive);
+extern int rel_mbar_to_depth(int mbar, struct dive *dive);
+extern int mbar_to_depth(int mbar, struct dive *dive);
+extern depth_t gas_mod(struct gasmix *mix, pressure_t po2_limit, struct dive *dive, int roundto);
+extern depth_t gas_mnd(struct gasmix *mix, depth_t end, struct dive *dive, int roundto);
#define SURFACE_THRESHOLD 750 /* somewhat arbitrary: only below 75cm is it really diving */
@@ -530,76 +440,13 @@ extern unsigned int dc_number;
#define current_dc (get_dive_dc(current_dive, dc_number))
#define displayed_dc (get_dive_dc(&displayed_dive, dc_number))
-static inline struct dive *get_dive(int nr)
-{
- if (nr >= dive_table.nr || nr < 0)
- return NULL;
- return dive_table.dives[nr];
-}
-
-static inline struct dive *get_dive_from_table(int nr, struct dive_table *dt)
-{
- if (nr >= dt->nr || nr < 0)
- return NULL;
- return dt->dives[nr];
-}
-
-static inline struct dive_site *get_dive_site_for_dive(struct dive *dive)
-{
- if (dive)
- return get_dive_site_by_uuid(dive->dive_site_uuid);
- return NULL;
-}
-
-static inline const char *get_dive_country(struct dive *dive)
-{
- struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid);
- if (ds) {
- int idx = taxonomy_index_for_category(&ds->taxonomy, TC_COUNTRY);
- if (idx >= 0)
- return ds->taxonomy.category[idx].value;
- }
- return NULL;
-}
-
-static inline char *get_dive_location(struct dive *dive)
-{
- struct dive_site *ds = get_dive_site_by_uuid(dive->dive_site_uuid);
- if (ds && ds->name)
- return ds->name;
- return NULL;
-}
-
-static inline unsigned int number_of_computers(struct dive *dive)
-{
- unsigned int total_number = 0;
- struct divecomputer *dc = &dive->dc;
-
- if (!dive)
- return 1;
-
- do {
- total_number++;
- dc = dc->next;
- } while (dc);
- return total_number;
-}
-
-static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr)
-{
- struct divecomputer *dc;
- if (!dive)
- return NULL;
- dc = &dive->dc;
-
- while (nr-- > 0) {
- dc = dc->next;
- if (!dc)
- return &dive->dc;
- }
- return dc;
-}
-
+extern struct dive *get_dive(int nr);
+extern struct dive *get_dive_from_table(int nr, struct dive_table *dt);
+extern struct dive_site *get_dive_site_for_dive(struct dive *dive);
+extern const char *get_dive_country(struct dive *dive);
+extern char *get_dive_location(struct dive *dive);
+extern unsigned int number_of_computers(struct dive *dive);
+extern struct divecomputer *get_dive_dc(struct dive *dive, int nr);
extern timestamp_t dive_endtime(const struct dive *dive);
extern void make_first_dc(void);
@@ -622,58 +469,15 @@ extern void delete_current_divecomputer(void);
#define for_each_gps_location(_i, _x) \
for ((_i) = 0; ((_x) = get_gps_location(_i, &gps_location_table)) != NULL; (_i)++)
-static inline struct dive *get_dive_by_uniq_id(int id)
-{
- int i;
- struct dive *dive = NULL;
-
- for_each_dive (i, dive) {
- if (dive->id == id)
- break;
- }
-#ifdef DEBUG
- if (dive == NULL) {
- fprintf(stderr, "Invalid id %x passed to get_dive_by_diveid, try to fix the code\n", id);
- exit(1);
- }
-#endif
- return dive;
-}
-
-static inline int get_idx_by_uniq_id(int id)
-{
- int i;
- struct dive *dive = NULL;
-
- for_each_dive (i, dive) {
- if (dive->id == id)
- break;
- }
-#ifdef DEBUG
- if (dive == NULL) {
- fprintf(stderr, "Invalid id %x passed to get_dive_by_diveid, try to fix the code\n", id);
- exit(1);
- }
-#endif
- return i;
-}
-
-static inline bool dive_site_has_gps_location(struct dive_site *ds)
-{
- return ds && (ds->latitude.udeg || ds->longitude.udeg);
-}
-
-static inline int dive_has_gps_location(struct dive *dive)
-{
- if (!dive)
- return false;
- return dive_site_has_gps_location(get_dive_site_by_uuid(dive->dive_site_uuid));
-}
-
#ifdef __cplusplus
extern "C" {
#endif
+extern struct dive *get_dive_by_uniq_id(int id);
+extern int get_idx_by_uniq_id(int id);
+extern bool dive_site_has_gps_location(struct dive_site *ds);
+extern int dive_has_gps_location(struct dive *dive);
+
extern int report_error(const char *fmt, ...);
extern void set_error_cb(void(*cb)(char *)); // Callback takes ownership of passed string
@@ -914,22 +718,7 @@ extern void printdecotable(struct decostop *table);
extern struct event *get_next_event(struct event *event, const char *name);
-static inline struct gasmix *get_gasmix(struct dive *dive, struct divecomputer *dc, int time, struct event **evp, struct gasmix *gasmix)
-{
- struct event *ev = *evp;
-
- if (!gasmix) {
- int cyl = explicit_first_cylinder(dive, dc);
- gasmix = &dive->cylinder[cyl].gasmix;
- ev = dc ? get_next_event(dc->events, "gaschange") : NULL;
- }
- while (ev && ev->time.seconds < time) {
- gasmix = get_gasmix_from_event(dive, ev);
- ev = get_next_event(ev->next, "gaschange");
- }
- *evp = ev;
- return gasmix;
-}
+extern struct gasmix *get_gasmix(struct dive *dive, struct divecomputer *dc, int time, struct event **evp, struct gasmix *gasmix);
/* these structs holds the information that
* describes the cylinders / weight systems.