diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-07-18 20:47:19 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-07-21 07:46:44 -0700 |
commit | f23425c5587327620281519a4e4cf53286e4eac2 (patch) | |
tree | 34d185d86d6a03adfe6ad8ee79e9d6c6df67adba /core/dive.c | |
parent | 6b9380efb04adfd321f7a0609bf940ab7b51bac4 (diff) | |
download | subsurface-f23425c5587327620281519a4e4cf53286e4eac2.tar.gz |
Uninline functions in dive.h
There were numerous inlined functions in dive.h. For many of them
inlining is dubious. Let's uninline most of them, with the exception
of trivial accessors and interpolate().
On current master, this gave a size reduction of 5 pages:
-rwxrwxr-x 1 bs bs 5863656 Jul 18 20:57 subsurface-inline
-rwxrwxr-x 1 bs bs 5843176 Jul 18 20:48 subsurface-noinline
-----------------------------------------------------------
20480
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core/dive.c')
-rw-r--r-- | core/dive.c | 242 |
1 files changed, 242 insertions, 0 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; +} |