diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2016-04-04 22:02:03 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2016-04-04 22:33:58 -0700 |
commit | 7be962bfc2879a72c32ff67518731347dcdff6de (patch) | |
tree | d05bf7ab234a448ee37a15b608e2b939f2285d07 /core/equipment.c | |
parent | 2d760a7bff71c46c5aeba37c40d236ea16eefea2 (diff) | |
download | subsurface-7be962bfc2879a72c32ff67518731347dcdff6de.tar.gz |
Move subsurface-core to core and qt-mobile to mobile-widgets
Having subsurface-core as a directory name really messes with
autocomplete and is obviously redundant. Simmilarly, qt-mobile caused an
autocomplete conflict and also was inconsistent with the desktop-widget
name for the directory containing the "other" UI.
And while cleaning up the resulting change in the path name for include
files, I decided to clean up those even more to make them consistent
overall.
This could have been handled in more commits, but since this requires a
make clean before the build, it seemed more sensible to do it all in one.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'core/equipment.c')
-rw-r--r-- | core/equipment.c | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/core/equipment.c b/core/equipment.c new file mode 100644 index 000000000..9f3e49039 --- /dev/null +++ b/core/equipment.c @@ -0,0 +1,238 @@ +// Clang has a bug on zero-initialization of C structs. +#pragma clang diagnostic ignored "-Wmissing-field-initializers" + +/* equipment.c */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include <time.h> +#include "gettext.h" +#include "dive.h" +#include "display.h" +#include "divelist.h" + +/* placeholders for a few functions that we need to redesign for the Qt UI */ +void add_cylinder_description(cylinder_type_t *type) +{ + const char *desc; + int i; + + desc = type->description; + if (!desc) + return; + for (i = 0; i < 100 && tank_info[i].name != NULL; i++) { + if (strcmp(tank_info[i].name, desc) == 0) + return; + } + if (i < 100) { + // FIXME: leaked on exit + tank_info[i].name = strdup(desc); + tank_info[i].ml = type->size.mliter; + tank_info[i].bar = type->workingpressure.mbar / 1000; + } +} +void add_weightsystem_description(weightsystem_t *weightsystem) +{ + const char *desc; + int i; + + desc = weightsystem->description; + if (!desc) + return; + for (i = 0; i < 100 && ws_info[i].name != NULL; i++) { + if (strcmp(ws_info[i].name, desc) == 0) { + ws_info[i].grams = weightsystem->weight.grams; + return; + } + } + if (i < 100) { + // FIXME: leaked on exit + ws_info[i].name = strdup(desc); + ws_info[i].grams = weightsystem->weight.grams; + } +} + +bool cylinder_nodata(cylinder_t *cyl) +{ + return !cyl->type.size.mliter && + !cyl->type.workingpressure.mbar && + !cyl->type.description && + !cyl->gasmix.o2.permille && + !cyl->gasmix.he.permille && + !cyl->start.mbar && + !cyl->end.mbar && + !cyl->gas_used.mliter && + !cyl->deco_gas_used.mliter; +} + +static bool cylinder_nosamples(cylinder_t *cyl) +{ + return !cyl->sample_start.mbar && + !cyl->sample_end.mbar; +} + +bool cylinder_none(void *_data) +{ + cylinder_t *cyl = _data; + return cylinder_nodata(cyl) && cylinder_nosamples(cyl); +} + +void get_gas_string(const struct gasmix *gasmix, char *text, int len) +{ + if (gasmix_is_air(gasmix)) + snprintf(text, len, "%s", translate("gettextFromC", "air")); + else if (get_he(gasmix) == 0 && get_o2(gasmix) < 1000) + snprintf(text, len, translate("gettextFromC", "EAN%d"), (get_o2(gasmix) + 5) / 10); + else if (get_he(gasmix) == 0 && get_o2(gasmix) == 1000) + snprintf(text, len, "%s", translate("gettextFromC", "oxygen")); + else + snprintf(text, len, "(%d/%d)", (get_o2(gasmix) + 5) / 10, (get_he(gasmix) + 5) / 10); +} + +/* Returns a static char buffer - only good for immediate use by printf etc */ +const char *gasname(const struct gasmix *gasmix) +{ + static char gas[64]; + get_gas_string(gasmix, gas, sizeof(gas)); + return gas; +} + +bool weightsystem_none(void *_data) +{ + weightsystem_t *ws = _data; + return !ws->weight.grams && !ws->description; +} + +bool no_weightsystems(weightsystem_t *ws) +{ + int i; + + for (i = 0; i < MAX_WEIGHTSYSTEMS; i++) + if (!weightsystem_none(ws + i)) + return false; + return true; +} + +static bool one_weightsystem_equal(weightsystem_t *ws1, weightsystem_t *ws2) +{ + return ws1->weight.grams == ws2->weight.grams && + same_string(ws1->description, ws2->description); +} + +bool weightsystems_equal(weightsystem_t *ws1, weightsystem_t *ws2) +{ + int i; + + for (i = 0; i < MAX_WEIGHTSYSTEMS; i++) + if (!one_weightsystem_equal(ws1 + i, ws2 + i)) + return false; + return true; +} + +/* + * We hardcode the most common standard cylinders, + * we should pick up any other names from the dive + * logs directly. + */ +struct tank_info_t tank_info[100] = { + /* Need an empty entry for the no-cylinder case */ + { "", }, + + /* Size-only metric cylinders */ + { "10.0ℓ", .ml = 10000 }, + { "11.1ℓ", .ml = 11100 }, + + /* Most common AL cylinders */ + { "AL40", .cuft = 40, .psi = 3000 }, + { "AL50", .cuft = 50, .psi = 3000 }, + { "AL63", .cuft = 63, .psi = 3000 }, + { "AL72", .cuft = 72, .psi = 3000 }, + { "AL80", .cuft = 80, .psi = 3000 }, + { "AL100", .cuft = 100, .psi = 3300 }, + + /* Metric AL cylinders */ + { "ALU7", .ml = 7000, .bar = 200 }, + + /* Somewhat common LP steel cylinders */ + { "LP85", .cuft = 85, .psi = 2640 }, + { "LP95", .cuft = 95, .psi = 2640 }, + { "LP108", .cuft = 108, .psi = 2640 }, + { "LP121", .cuft = 121, .psi = 2640 }, + + /* Somewhat common HP steel cylinders */ + { "HP65", .cuft = 65, .psi = 3442 }, + { "HP80", .cuft = 80, .psi = 3442 }, + { "HP100", .cuft = 100, .psi = 3442 }, + { "HP119", .cuft = 119, .psi = 3442 }, + { "HP130", .cuft = 130, .psi = 3442 }, + + /* Common European steel cylinders */ + { "3ℓ 232 bar", .ml = 3000, .bar = 232 }, + { "3ℓ 300 bar", .ml = 3000, .bar = 300 }, + { "10ℓ 300 bar", .ml = 10000, .bar = 300 }, + { "12ℓ 200 bar", .ml = 12000, .bar = 200 }, + { "12ℓ 232 bar", .ml = 12000, .bar = 232 }, + { "12ℓ 300 bar", .ml = 12000, .bar = 300 }, + { "15ℓ 200 bar", .ml = 15000, .bar = 200 }, + { "15ℓ 232 bar", .ml = 15000, .bar = 232 }, + { "D7 300 bar", .ml = 14000, .bar = 300 }, + { "D8.5 232 bar", .ml = 17000, .bar = 232 }, + { "D12 232 bar", .ml = 24000, .bar = 232 }, + { "D13 232 bar", .ml = 26000, .bar = 232 }, + { "D15 232 bar", .ml = 30000, .bar = 232 }, + { "D16 232 bar", .ml = 32000, .bar = 232 }, + { "D18 232 bar", .ml = 36000, .bar = 232 }, + { "D20 232 bar", .ml = 40000, .bar = 232 }, + + /* We'll fill in more from the dive log dynamically */ + { NULL, } +}; + +/* + * We hardcode the most common weight system types + * This is a bit odd as the weight system types don't usually encode weight + */ +struct ws_info_t ws_info[100] = { + { QT_TRANSLATE_NOOP("gettextFromC", "integrated"), 0 }, + { QT_TRANSLATE_NOOP("gettextFromC", "belt"), 0 }, + { QT_TRANSLATE_NOOP("gettextFromC", "ankle"), 0 }, + { QT_TRANSLATE_NOOP("gettextFromC", "backplate weight"), 0 }, + { QT_TRANSLATE_NOOP("gettextFromC", "clip-on"), 0 }, +}; + +void remove_cylinder(struct dive *dive, int idx) +{ + cylinder_t *cyl = dive->cylinder + idx; + int nr = MAX_CYLINDERS - idx - 1; + memmove(cyl, cyl + 1, nr * sizeof(*cyl)); + memset(cyl + nr, 0, sizeof(*cyl)); +} + +void remove_weightsystem(struct dive *dive, int idx) +{ + weightsystem_t *ws = dive->weightsystem + idx; + int nr = MAX_WEIGHTSYSTEMS - idx - 1; + memmove(ws, ws + 1, nr * sizeof(*ws)); + memset(ws + nr, 0, sizeof(*ws)); +} + +/* when planning a dive we need to make sure that all cylinders have a sane depth assigned + * and if we are tracking gas consumption the pressures need to be reset to start = end = workingpressure */ +void reset_cylinders(struct dive *dive, bool track_gas) +{ + int i; + pressure_t decopo2 = {.mbar = prefs.decopo2}; + + for (i = 0; i < MAX_CYLINDERS; i++) { + cylinder_t *cyl = &dive->cylinder[i]; + if (cylinder_none(cyl)) + continue; + if (cyl->depth.mm == 0) /* if the gas doesn't give a mod, calculate based on prefs */ + cyl->depth = gas_mod(&cyl->gasmix, decopo2, dive, M_OR_FT(3,10)); + if (track_gas) + cyl->start.mbar = cyl->end.mbar = cyl->type.workingpressure.mbar; + cyl->gas_used.mliter = 0; + cyl->deco_gas_used.mliter = 0; + } +} |