diff options
author | Tim Segers <tsegers@pm.me> | 2022-10-10 18:37:28 +0200 |
---|---|---|
committer | Tim Segers <tsegers@pm.me> | 2022-10-10 18:39:41 +0200 |
commit | 8c5571544169a4095ceebf5f6d6b5b9caf09c59b (patch) | |
tree | 08c8b44616ce4785d821db48fbbd0c5bf4421a75 /opendeco.c | |
parent | 2337828095920b8debdb0f8e0337a9d6aad6b55c (diff) | |
download | opendeco-8c5571544169a4095ceebf5f6d6b5b9caf09c59b.tar.gz |
Move sources into src
Diffstat (limited to 'opendeco.c')
-rw-r--r-- | opendeco.c | 208 |
1 files changed, 0 insertions, 208 deletions
diff --git a/opendeco.c b/opendeco.c deleted file mode 100644 index 9231ab3..0000000 --- a/opendeco.c +++ /dev/null @@ -1,208 +0,0 @@ -/* SPDX-License-Identifier: MIT-0 */ - -#include <argp.h> -#include <locale.h> -#include <math.h> -#include <stdlib.h> -#include <string.h> -#include <wchar.h> - -#include "deco.h" -#include "schedule.h" -#include "output.h" - -#define MOD_OXY (abs_depth(msw_to_bar(6))) - -#ifndef VERSION -#define VERSION "unknown version" -#endif - -/* argp settings */ -static char args_doc[] = ""; -static char doc[] = "Implementation of Buhlmann ZH-L16 with Gradient Factors:" - "\vExamples:\n\n" - "\t./opendeco -d 18 -t 60 -g Air\n" - "\t./opendeco -d 30 -t 60 -g EAN32\n" - "\t./opendeco -d 40 -t 120 -g 21/35 -l 20 -h 80 --decogasses Oxygen,EAN50\n"; -const char *argp_program_bug_address = "<~tsegers/opendeco@lists.sr.ht> or https://todo.sr.ht/~tsegers/opendeco"; -const char *argp_program_version = "opendeco " VERSION; - -static struct argp_option options[] = { - {"depth", 'd', "NUMBER", 0, "Set the depth of the dive in meters", 0}, - {"time", 't', "NUMBER", 0, "Set the time of the dive in minutes", 1}, - {"gas", 'g', "STRING", 0, "Set the bottom gas used during the dive, defaults to Air", 2}, - {"gflow", 'l', "NUMBER", 0, "Set the gradient factor at the first stop, defaults to 30", 3}, - {"gfhigh", 'h', "NUMBER", 0, "Set the gradient factor at the surface, defaults to 75", 4}, - {"decogasses", 'G', "LIST", 0, "Set the gasses available for deco", 5}, - {0, 0, 0, 0, 0, 0} -}; - -struct arguments { - double depth; - double time; - char *gas; - int gflow; - int gfhigh; - char *decogasses; -}; - -static error_t parse_opt(int key, char *arg, struct argp_state *state) -{ - struct arguments *arguments = state->input; - - switch (key) { - case 'd': - arguments->depth = arg ? atof(arg) : -1; - break; - case 't': - arguments->time = arg ? atof(arg) : -1; - break; - case 'g': - arguments->gas = arg; - break; - case 'G': - arguments->decogasses = arg; - break; - case 'l': - arguments->gflow = arg ? atoi(arg) : 100; - break; - case 'h': - arguments->gfhigh = arg ? atoi(arg) : 100; - break; - case ARGP_KEY_END: - if (arguments->depth < 0 || arguments->time < 0) { - argp_state_help(state, stderr, ARGP_HELP_USAGE); - argp_failure(state, 1, 0, "Options -d and -t are required. See --help for more information"); - exit(ARGP_ERR_UNKNOWN); - } - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; -} - -static struct argp argp = {options, parse_opt, args_doc, doc, 0, 0, 0}; - -void print_segment_callback(const decostate_t *ds, const waypoint_t wp, segtype_t type) -{ - static double last_depth; - static double runtime; - - wchar_t sign; - - runtime += wp.time; - - if (wp.depth < last_depth) - sign = ASC; - else if (wp.depth > last_depth) - sign = DEC; - else - sign = LVL; - - if (type != SEG_TRAVEL) - print_planline(sign, wp.depth, wp.time, runtime, wp.gas); - - last_depth = wp.depth; -} - -int parse_gasses(gas_t **gasses, char *str) -{ - if (!str) { - *gasses = NULL; - return 0; - } - - /* count number of gasses in string */ - int nof_gasses = 1; - - for (int c = 0; str[c]; c++) - if (str[c] == ',') - nof_gasses++; - - /* allocate gas array */ - gas_t *deco_gasses = malloc(nof_gasses * sizeof(gas_t)); - - /* fill gas array */ - char *gas_str = NULL; - int gas_idx = 0; - - while (1) { - if (!gas_str) - gas_str = strtok(str, ","); - else - gas_str = strtok(NULL, ","); - - if (!gas_str) - break; - - scan_gas(&deco_gasses[gas_idx], gas_str); - gas_idx++; - } - - *gasses = deco_gasses; - return nof_gasses; -} - -int main(int argc, char *argv[]) -{ - setlocale(LC_ALL, "en_US.utf8"); - - /* argp */ - struct arguments arguments; - - arguments.depth = -1; - arguments.time = -1; - arguments.gas = "Air"; - arguments.gflow = 30; - arguments.gfhigh = 75; - arguments.decogasses = ""; - - argp_parse(&argp, argc, argv, 0, 0, &arguments); - - /* setup */ - decostate_t ds; - init_decostate(&ds, arguments.gflow, arguments.gfhigh, msw_to_bar(3)); - double dec_per_min = msw_to_bar(9); - - gas_t bottom_gas; - scan_gas(&bottom_gas, arguments.gas); - - gas_t *deco_gasses; - int nof_gasses = parse_gasses(&deco_gasses, arguments.decogasses); - - /* override oxygen mod */ - for (int i = 0; i < nof_gasses; i++) - if (gas_o2(&deco_gasses[i]) == 100) - deco_gasses[i].mod = MOD_OXY; - - /* simulate dive */ - double descent_time = msw_to_bar(arguments.depth) / dec_per_min; - double bottom_time = max(1, arguments.time - descent_time); - - waypoint_t waypoints[] = { - {.depth = abs_depth(msw_to_bar(arguments.depth)), .time = descent_time, &bottom_gas}, - {.depth = abs_depth(msw_to_bar(arguments.depth)), .time = bottom_time, &bottom_gas}, - }; - - print_planhead(); - simulate_dive(&ds, waypoints, len(waypoints), &print_segment_callback); - - /* generate deco schedule */ - double depth = waypoints[len(waypoints) - 1].depth; - const gas_t *gas = waypoints[len(waypoints) - 1].gas; - - /* determine @+5 TTS */ - decostate_t ds_ = ds; - add_segment_const(&ds_, depth, 5, gas); - decoinfo_t di_plus5 = calc_deco(&ds_, depth, gas, deco_gasses, nof_gasses, NULL); - - /* print actual deco schedule */ - decoinfo_t di = calc_deco(&ds, depth, gas, deco_gasses, nof_gasses, &print_segment_callback); - - /* output deco info and disclaimer */ - wprintf(L"\nNDL: %i TTS: %i TTS @+5: %i\n", (int) floor(di.ndl), (int) ceil(di.tts), (int) ceil(di_plus5.tts)); - print_planfoot(&ds); - - return 0; -} |