profile: convert core/profile.c to C++

This contains mostly string manipulation, so C++ is much more
convenient.

This commit only changes the things that don't compile in C++:
- turn ?alloc/free into std::vector
- use the C++ version of the translation machinery
- add namespace for enum in pl0t_info struct

Contains minor whitespace fixes.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-01-13 12:01:40 +01:00
parent d1b0bba530
commit 199cc61e07
5 changed files with 112 additions and 122 deletions

View File

@ -45,7 +45,7 @@ SOURCES += subsurface-mobile-main.cpp \
core/fulltext.cpp \
core/subsurfacestartup.cpp \
core/pref.c \
core/profile.c \
core/profile.cpp \
core/device.cpp \
core/dive.cpp \
core/divecomputer.c \

View File

@ -146,7 +146,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
plannernotes.c
pref.h
pref.c
profile.c
profile.cpp
profile.h
qt-gui.h
qt-init.cpp

View File

@ -117,7 +117,7 @@ int pscr_o2(const double amb_pressure, struct gasmix mix)
* *pressures = structure for communicating o2 sensor values from and gas pressures to the calling function.
* *mix = structure containing cylinder gas mixture information.
* divemode = the dive mode pertaining to this point in the dive profile.
* This function called by: calculate_gas_information_new() in profile.c; add_segment() in deco.c.
* This function called by: calculate_gas_information_new() in profile.cpp; add_segment() in deco.c.
*/
void fill_pressures(struct gas_pressures *pressures, const double amb_pressure, struct gasmix mix, double po2, enum divemode_t divemode)
{

View File

@ -2,7 +2,7 @@
/* gaspressures.c
* ---------------
* This file contains the routines to calculate the gas pressures in the cylinders.
* The functions below support the code in profile.c.
* The functions below support the code in profile.cpp.
* The high-level function is populate_pressure_information(), called by function
* create_plot_info_new() in profile.c. The other functions below are, in turn,
* called by populate_pressure_information(). The calling sequence is as follows:

View File

@ -1,13 +1,14 @@
// SPDX-License-Identifier: GPL-2.0
/* profile.c */
/* profile.cpp */
/* creates all the necessary data for drawing the dive profile
*/
#include "ssrf.h"
#include "gettext.h"
#include "gettextfromc.h"
#include <limits.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <vector>
#include "dive.h"
#include "divelist.h"
@ -30,7 +31,7 @@
#define MAX_PROFILE_DECO 7200
extern int ascent_velocity(int depth, int avg_depth, int bottom_time);
extern "C" int ascent_velocity(int depth, int avg_depth, int bottom_time);
#ifdef DEBUG_PI
/* debugging tool - not normally used */
@ -66,6 +67,7 @@ static void dump_pi(struct plot_info *pi)
* 30 minutes or 90 ft, just so that small dives show
* up as such unless zoom is enabled.
*/
extern "C"
int get_maxtime(const struct plot_info *pi)
{
int seconds = pi->maxtime;
@ -74,6 +76,7 @@ int get_maxtime(const struct plot_info *pi)
}
/* get the maximum depth to which we want to plot */
extern "C"
int get_maxdepth(const struct plot_info *pi)
{
/* 3m to spare */
@ -185,6 +188,7 @@ static void analyze_plot_info(struct plot_info *pi)
* Some dive computers give cylinder indices, some
* give just the gas mix.
*/
extern "C"
int get_cylinder_index(const struct dive *dive, const struct event *ev)
{
int best;
@ -206,6 +210,7 @@ int get_cylinder_index(const struct dive *dive, const struct event *ev)
return best < 0 ? 0 : best;
}
extern "C"
struct event *get_next_event_mutable(struct event *event, const char *name)
{
if (!name || !*name)
@ -218,6 +223,7 @@ struct event *get_next_event_mutable(struct event *event, const char *name)
return event;
}
extern "C"
const struct event *get_next_event(const struct event *event, const char *name)
{
return get_next_event_mutable((struct event *)event, name);
@ -246,9 +252,8 @@ static int set_setpoint(struct plot_info *pi, int i, int setpoint, int end)
return i;
}
static void check_setpoint_events(const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi)
static void check_setpoint_events(const struct dive *, const struct divecomputer *dc, struct plot_info *pi)
{
UNUSED(dive);
int i = 0;
pressure_t setpoint;
setpoint.mbar = 0;
@ -381,6 +386,7 @@ static void insert_entry(struct plot_info *pi, int idx, int time, int depth, int
entry->bearing = -1;
}
extern "C"
void free_plot_info_data(struct plot_info *pi)
{
free(pi->entry);
@ -390,7 +396,6 @@ void free_plot_info_data(struct plot_info *pi)
static void populate_plot_entries(const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi)
{
UNUSED(dive);
int idx, maxtime, nr, i;
int lastdepth, lasttime, lasttemp = 0;
struct plot_data *plot_data;
@ -407,10 +412,10 @@ static void populate_plot_entries(const struct dive *dive, const struct divecomp
* past "maxtime" in the original sample data)
*/
nr = dc->samples + 6 + maxtime / 10 + count_events(dc);
plot_data = calloc(nr, sizeof(struct plot_data));
plot_data = (struct plot_data *)calloc(nr, sizeof(struct plot_data));
pi->entry = plot_data;
pi->nr_cylinders = dive->cylinders.nr;
pi->pressures = calloc(nr * (size_t)pi->nr_cylinders, sizeof(struct plot_pressure_data));
pi->pressures = (plot_pressure_data *)calloc(nr * (size_t)pi->nr_cylinders, sizeof(struct plot_pressure_data));
if (!plot_data)
return;
pi->nr = nr;
@ -532,7 +537,7 @@ static void populate_plot_entries(const struct dive *dive, const struct divecomp
*
* Everything in between has a cylinder pressure for at least some of the cylinders.
*/
static int sac_between(const struct dive *dive, struct plot_info *pi, int first, int last, const bool gases[])
static int sac_between(const struct dive *dive, struct plot_info *pi, int first, int last, const std::vector<char> &gases)
{
int i, airuse;
double pressuretime;
@ -580,7 +585,7 @@ static int sac_between(const struct dive *dive, struct plot_info *pi, int first,
}
/* Is there pressure data for all gases? */
static bool all_pressures(struct plot_info *pi, int idx, const bool gases[])
static bool all_pressures(struct plot_info *pi, int idx, const std::vector<char> &gases)
{
int i;
@ -593,7 +598,7 @@ static bool all_pressures(struct plot_info *pi, int idx, const bool gases[])
}
/* Which of the set of gases have pressure data? Returns false if none of them. */
static bool filter_pressures(struct plot_info *pi, int idx, const bool gases_in[], bool gases_out[])
static bool filter_pressures(struct plot_info *pi, int idx, const std::vector<char> &gases_in, std::vector<char> &gases_out)
{
int i;
bool has_pressure = false;
@ -612,7 +617,7 @@ static bool filter_pressures(struct plot_info *pi, int idx, const bool gases_in[
* an array of gases, the caller passes in scratch memory in the last
* argument.
*/
static void fill_sac(const struct dive *dive, struct plot_info *pi, int idx, const bool gases_in[], bool gases[])
static void fill_sac(const struct dive *dive, struct plot_info *pi, int idx, const std::vector<char> &gases_in, std::vector<char> &gases)
{
struct plot_data *entry = pi->entry + idx;
int first, last;
@ -670,7 +675,7 @@ static void fill_sac(const struct dive *dive, struct plot_info *pi, int idx, con
/*
* Create a bitmap of cylinders that match our current gasmix
*/
static void matching_gases(const struct dive *dive, struct gasmix gasmix, bool gases[])
static void matching_gases(const struct dive *dive, struct gasmix gasmix, std::vector<char> &gases)
{
int i;
@ -682,13 +687,14 @@ static void calculate_sac(const struct dive *dive, const struct divecomputer *dc
{
struct gasmix gasmix = gasmix_invalid;
const struct event *ev = NULL;
bool *gases, *gases_scratch;
gases = calloc(pi->nr_cylinders, sizeof(*gases));
// Use std::vector<char> instead of std::vector<bool> to avoid silly "optimization"
// by the standard library.
std::vector<char> gases(pi->nr_cylinders, 0);
/* This might be premature optimization, but let's allocate the gas array for
* the fill_sac function only once an not once per sample */
gases_scratch = malloc(pi->nr_cylinders * sizeof(*gases));
std::vector<char>gases_scratch(pi->nr_cylinders, 0);
for (int i = 0; i < pi->nr; i++) {
struct plot_data *entry = pi->entry + i;
@ -700,18 +706,17 @@ static void calculate_sac(const struct dive *dive, const struct divecomputer *dc
fill_sac(dive, pi, i, gases, gases_scratch);
}
free(gases);
free(gases_scratch);
}
static void populate_secondary_sensor_data(const struct divecomputer *dc, struct plot_info *pi)
{
int *seen = calloc(pi->nr_cylinders, sizeof(*seen));
for (int idx = 0; idx < pi->nr; ++idx)
for (int c = 0; c < pi->nr_cylinders; ++c)
std::vector<int> seen(pi->nr_cylinders, 0);
for (int idx = 0; idx < pi->nr; ++idx) {
for (int c = 0; c < pi->nr_cylinders; ++c) {
if (get_plot_pressure_data(pi, idx, SENSOR_PR, c))
++seen[c]; // Count instances so we can differentiate a real sensor from just start and end pressure
}
}
int idx = 0;
/* We should try to see if it has interesting pressure data here */
for (int i = 0; i < dc->samples && idx < pi->nr; i++) {
@ -727,7 +732,6 @@ static void populate_secondary_sensor_data(const struct divecomputer *dc, struct
if (sample->sensor[s] != NO_SENSOR && seen[sample->sensor[s]] < 3 && sample->pressure[s].mbar)
set_plot_pressure_data(pi, idx, SENSOR_PR, sample->sensor[s], sample->pressure[s].mbar);
}
free(seen);
}
/*
@ -754,16 +758,11 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive
/* FIXME: The planner uses a dummy one-past-end cylinder for surface air! */
int num_cyl = pi->nr_cylinders + 1;
int *seen = malloc(num_cyl * sizeof(*seen));
int *first = malloc(num_cyl * sizeof(*first));
int *last = malloc(num_cyl * sizeof(*last));
std::vector<int> seen (num_cyl, 0);
std::vector<int> first(num_cyl, 0);
std::vector<int> last(num_cyl, INT_MAX);
const struct divecomputer *secondary;
for (i = 0; i < num_cyl; i++) {
seen[i] = 0;
first[i] = 0;
last[i] = INT_MAX;
}
prev = explicit_first_cylinder(dive, dc);
seen[prev] = 1;
@ -841,10 +840,6 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive
continue;
populate_secondary_sensor_data(secondary, pi);
} while ((secondary = secondary->next) != NULL);
free(seen);
free(first);
free(last);
}
/* calculate DECO STOP / TTS / NDL */
@ -1058,7 +1053,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
entry->depth < max_ceiling - 100 && entry->sec > 0) {
struct dive *non_const_dive = (struct dive *)dive; // cast away const!
add_event(&non_const_dive->dc, entry->sec, SAMPLE_EVENT_CEILING, -1, max_ceiling / 1000,
translate("gettextFromC", "planned waypoint above ceiling"));
qPrintable(gettextFromC::tr("planned waypoint above ceiling")));
pi->waypoint_above_ceiling = true;
}
@ -1308,6 +1303,7 @@ static void debug_print_profiledata(struct plot_info *pi)
/*
* Initialize a plot_info structure to all-zeroes
*/
extern "C"
void init_plot_info(struct plot_info *pi)
{
memset(pi, 0, sizeof(*pi));
@ -1323,6 +1319,7 @@ void init_plot_info(struct plot_info *pi)
* The old data will be freed. Before the first call, the plot
* info must be initialized with init_plot_info().
*/
extern "C"
void create_plot_info_new(const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi, const struct deco_state *planner_ds)
{
int o2, he, o2max;
@ -1333,14 +1330,14 @@ void create_plot_info_new(const struct dive *dive, const struct divecomputer *dc
calculate_max_limits_new(dive, dc, pi, in_planner);
get_dive_gas(dive, &o2, &he, &o2max);
if (dc->divemode == FREEDIVE) {
pi->dive_type = FREEDIVING;
} else if (he > 0) {
pi->dive_type = TRIMIX;
pi->dive_type = plot_info::FREEDIVING;
} else if (he > 0) {
pi->dive_type = plot_info::TRIMIX;
} else {
if (o2)
pi->dive_type = NITROX;
pi->dive_type = plot_info::NITROX;
else
pi->dive_type = AIR;
pi->dive_type = plot_info::AIR;
}
populate_plot_entries(dive, dc, pi);
@ -1374,63 +1371,63 @@ static void plot_string(const struct dive *d, const struct plot_info *pi, int id
const struct plot_data *entry = pi->entry + idx;
depthvalue = get_depth_units(entry->depth, NULL, &depth_unit);
put_format_loc(b, translate("gettextFromC", "@: %d:%02d\nD: %.1f%s\n"), FRACTION(entry->sec, 60), depthvalue, depth_unit);
put_format_loc(b, qPrintable(gettextFromC::tr("@: %d:%02d\nD: %.1f%s\n")), FRACTION(entry->sec, 60), depthvalue, depth_unit);
for (cyl = 0; cyl < pi->nr_cylinders; cyl++) {
int mbar = get_plot_pressure(pi, idx, cyl);
if (!mbar)
continue;
struct gasmix mix = get_cylinder(d, cyl)->gasmix;
pressurevalue = get_pressure_units(mbar, &pressure_unit);
put_format_loc(b, translate("gettextFromC", "P: %d%s (%s)\n"), pressurevalue, pressure_unit, gasname(mix));
put_format_loc(b, qPrintable(gettextFromC::tr("P: %d%s (%s)\n")), pressurevalue, pressure_unit, gasname(mix));
}
if (entry->temperature) {
tempvalue = get_temp_units(entry->temperature, &temp_unit);
put_format_loc(b, translate("gettextFromC", "T: %.1f%s\n"), tempvalue, temp_unit);
put_format_loc(b, qPrintable(gettextFromC::tr("T: %.1f%s\n")), tempvalue, temp_unit);
}
speedvalue = get_vertical_speed_units(abs(entry->speed), NULL, &vertical_speed_unit);
/* Ascending speeds are positive, descending are negative */
if (entry->speed > 0)
speedvalue *= -1;
put_format_loc(b, translate("gettextFromC", "V: %.1f%s\n"), speedvalue, vertical_speed_unit);
put_format_loc(b, qPrintable(gettextFromC::tr("V: %.1f%s\n")), speedvalue, vertical_speed_unit);
sacvalue = get_volume_units(entry->sac, &decimals, &unit);
if (entry->sac && prefs.show_sac)
put_format_loc(b, translate("gettextFromC", "SAC: %.*f%s/min\n"), decimals, sacvalue, unit);
put_format_loc(b, qPrintable(gettextFromC::tr("SAC: %.*f%s/min\n")), decimals, sacvalue, unit);
if (entry->cns)
put_format_loc(b, translate("gettextFromC", "CNS: %u%%\n"), entry->cns);
put_format_loc(b, qPrintable(gettextFromC::tr("CNS: %u%%\n")), entry->cns);
if (prefs.pp_graphs.po2 && entry->pressures.o2 > 0) {
put_format_loc(b, translate("gettextFromC", "pO₂: %.2fbar\n"), entry->pressures.o2);
put_format_loc(b, qPrintable(gettextFromC::tr("pO₂: %.2fbar\n")), entry->pressures.o2);
if (entry->scr_OC_pO2.mbar)
put_format_loc(b, translate("gettextFromC", "SCR ΔpO₂: %.2fbar\n"), entry->scr_OC_pO2.mbar/1000.0 - entry->pressures.o2);
put_format_loc(b, qPrintable(gettextFromC::tr("SCR ΔpO₂: %.2fbar\n")), entry->scr_OC_pO2.mbar/1000.0 - entry->pressures.o2);
}
if (prefs.pp_graphs.pn2 && entry->pressures.n2 > 0)
put_format_loc(b, translate("gettextFromC", "pN₂: %.2fbar\n"), entry->pressures.n2);
put_format_loc(b, qPrintable(gettextFromC::tr("pN₂: %.2fbar\n")), entry->pressures.n2);
if (prefs.pp_graphs.phe && entry->pressures.he > 0)
put_format_loc(b, translate("gettextFromC", "pHe: %.2fbar\n"), entry->pressures.he);
put_format_loc(b, qPrintable(gettextFromC::tr("pHe: %.2fbar\n")), entry->pressures.he);
if (prefs.mod && entry->mod > 0) {
mod = lrint(get_depth_units(entry->mod, NULL, &depth_unit));
put_format_loc(b, translate("gettextFromC", "MOD: %d%s\n"), mod, depth_unit);
put_format_loc(b, qPrintable(gettextFromC::tr("MOD: %d%s\n")), mod, depth_unit);
}
eadd = lrint(get_depth_units(entry->eadd, NULL, &depth_unit));
if (prefs.ead) {
switch (pi->dive_type) {
case NITROX:
case plot_info::NITROX:
if (entry->ead > 0) {
ead = lrint(get_depth_units(entry->ead, NULL, &depth_unit));
put_format_loc(b, translate("gettextFromC", "EAD: %d%s\nEADD: %d%s / %.1fg/\n"), ead, depth_unit, eadd, depth_unit, entry->density);
put_format_loc(b, qPrintable(gettextFromC::tr("EAD: %d%s\nEADD: %d%s / %.1fg/\n")), ead, depth_unit, eadd, depth_unit, entry->density);
break;
}
case TRIMIX:
case plot_info::TRIMIX:
if (entry->end > 0) {
end = lrint(get_depth_units(entry->end, NULL, &depth_unit));
put_format_loc(b, translate("gettextFromC", "END: %d%s\nEADD: %d%s / %.1fg/\n"), end, depth_unit, eadd, depth_unit, entry->density);
put_format_loc(b, qPrintable(gettextFromC::tr("END: %d%s\nEADD: %d%s / %.1fg/\n")), end, depth_unit, eadd, depth_unit, entry->density);
break;
}
case AIR:
case plot_info::AIR:
if (entry->density > 0) {
put_format_loc(b, translate("gettextFromC", "Density: %.1fg/\n"), entry->density);
put_format_loc(b, qPrintable(gettextFromC::tr("Density: %.1fg/\n")), entry->density);
}
case FREEDIVING:
case plot_info::FREEDIVING:
/* nothing */
break;
}
@ -1440,30 +1437,30 @@ static void plot_string(const struct dive *d, const struct plot_info *pi, int id
if (entry->ndl > 0) {
/* this is a safety stop as we still have ndl */
if (entry->stoptime)
put_format_loc(b, translate("gettextFromC", "Safety stop: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60),
put_format_loc(b, qPrintable(gettextFromC::tr("Safety stop: %umin @ %.0f%s\n")), DIV_UP(entry->stoptime, 60),
depthvalue, depth_unit);
else
put_format_loc(b, translate("gettextFromC", "Safety stop: unknown time @ %.0f%s\n"),
put_format_loc(b, qPrintable(gettextFromC::tr("Safety stop: unknown time @ %.0f%s\n")),
depthvalue, depth_unit);
} else {
/* actual deco stop */
if (entry->stoptime)
put_format_loc(b, translate("gettextFromC", "Deco: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60),
put_format_loc(b, qPrintable(gettextFromC::tr("Deco: %umin @ %.0f%s\n")), DIV_UP(entry->stoptime, 60),
depthvalue, depth_unit);
else
put_format_loc(b, translate("gettextFromC", "Deco: unknown time @ %.0f%s\n"),
put_format_loc(b, qPrintable(gettextFromC::tr("Deco: unknown time @ %.0f%s\n")),
depthvalue, depth_unit);
}
} else if (entry->in_deco) {
put_string(b, translate("gettextFromC", "In deco\n"));
put_string(b, qPrintable(gettextFromC::tr("In deco\n")));
} else if (entry->ndl >= 0) {
put_format_loc(b, translate("gettextFromC", "NDL: %umin\n"), DIV_UP(entry->ndl, 60));
put_format_loc(b, qPrintable(gettextFromC::tr("NDL: %umin\n")), DIV_UP(entry->ndl, 60));
}
if (entry->tts)
put_format_loc(b, translate("gettextFromC", "TTS: %umin\n"), DIV_UP(entry->tts, 60));
put_format_loc(b, qPrintable(gettextFromC::tr("TTS: %umin\n")), DIV_UP(entry->tts, 60));
if (entry->stopdepth_calc && entry->stoptime_calc) {
depthvalue = get_depth_units(entry->stopdepth_calc, NULL, &depth_unit);
put_format_loc(b, translate("gettextFromC", "Deco: %umin @ %.0f%s (calc)\n"), DIV_UP(entry->stoptime_calc, 60),
put_format_loc(b, qPrintable(gettextFromC::tr("Deco: %umin @ %.0f%s (calc)\n")), DIV_UP(entry->stoptime_calc, 60),
depthvalue, depth_unit);
} else if (entry->in_deco_calc) {
/* This means that we have no NDL left,
@ -1471,54 +1468,55 @@ static void plot_string(const struct dive *d, const struct plot_info *pi, int id
* so if we just accend to the surface slowly
* (ascent_mm_per_step / ascent_s_per_step)
* everything will be ok. */
put_string(b, translate("gettextFromC", "In deco (calc)\n"));
put_string(b, qPrintable(gettextFromC::tr("In deco (calc)\n")));
} else if (prefs.calcndltts && entry->ndl_calc != 0) {
if(entry->ndl_calc < MAX_PROFILE_DECO)
put_format_loc(b, translate("gettextFromC", "NDL: %umin (calc)\n"), DIV_UP(entry->ndl_calc, 60));
put_format_loc(b, qPrintable(gettextFromC::tr("NDL: %umin (calc)\n")), DIV_UP(entry->ndl_calc, 60));
else
put_string(b, translate("gettextFromC", "NDL: >2h (calc)\n"));
put_string(b, qPrintable(gettextFromC::tr("NDL: >2h (calc)\n")));
}
if (entry->tts_calc) {
if (entry->tts_calc < MAX_PROFILE_DECO)
put_format_loc(b, translate("gettextFromC", "TTS: %umin (calc)\n"), DIV_UP(entry->tts_calc, 60));
put_format_loc(b, qPrintable(gettextFromC::tr("TTS: %umin (calc)\n")), DIV_UP(entry->tts_calc, 60));
else
put_string(b, translate("gettextFromC", "TTS: >2h (calc)\n"));
put_string(b, qPrintable(gettextFromC::tr("TTS: >2h (calc)\n")));
}
if (entry->rbt)
put_format_loc(b, translate("gettextFromC", "RBT: %umin\n"), DIV_UP(entry->rbt, 60));
put_format_loc(b, qPrintable(gettextFromC::tr("RBT: %umin\n")), DIV_UP(entry->rbt, 60));
if (prefs.decoinfo) {
if (entry->current_gf > 0.0)
put_format(b, translate("gettextFromC", "GF %d%%\n"), (int)(100.0 * entry->current_gf));
put_format(b, qPrintable(gettextFromC::tr("GF %d%%\n")), (int)(100.0 * entry->current_gf));
if (entry->surface_gf > 0.0)
put_format(b, translate("gettextFromC", "Surface GF %.0f%%\n"), entry->surface_gf);
put_format(b, qPrintable(gettextFromC::tr("Surface GF %.0f%%\n")), entry->surface_gf);
if (entry->ceiling) {
depthvalue = get_depth_units(entry->ceiling, NULL, &depth_unit);
put_format_loc(b, translate("gettextFromC", "Calculated ceiling %.1f%s\n"), depthvalue, depth_unit);
put_format_loc(b, qPrintable(gettextFromC::tr("Calculated ceiling %.1f%s\n")), depthvalue, depth_unit);
if (prefs.calcalltissues) {
int k;
for (k = 0; k < 16; k++) {
if (entry->ceilings[k]) {
depthvalue = get_depth_units(entry->ceilings[k], NULL, &depth_unit);
put_format_loc(b, translate("gettextFromC", "Tissue %.0fmin: %.1f%s\n"), buehlmann_N2_t_halflife[k], depthvalue, depth_unit);
put_format_loc(b, qPrintable(gettextFromC::tr("Tissue %.0fmin: %.1f%s\n")), buehlmann_N2_t_halflife[k], depthvalue, depth_unit);
}
}
}
}
}
if (entry->icd_warning)
put_format(b, "%s", translate("gettextFromC", "ICD in leading tissue\n"));
put_format(b, "%s", qPrintable(gettextFromC::tr("ICD in leading tissue\n")));
if (entry->heartbeat && prefs.hrgraph)
put_format_loc(b, translate("gettextFromC", "heart rate: %d\n"), entry->heartbeat);
put_format_loc(b, qPrintable(gettextFromC::tr("heart rate: %d\n")), entry->heartbeat);
if (entry->bearing >= 0)
put_format_loc(b, translate("gettextFromC", "bearing: %d\n"), entry->bearing);
put_format_loc(b, qPrintable(gettextFromC::tr("bearing: %d\n")), entry->bearing);
if (entry->running_sum) {
depthvalue = get_depth_units(entry->running_sum / entry->sec, NULL, &depth_unit);
put_format_loc(b, translate("gettextFromC", "mean depth to here %.1f%s\n"), depthvalue, depth_unit);
put_format_loc(b, qPrintable(gettextFromC::tr("mean depth to here %.1f%s\n")), depthvalue, depth_unit);
}
strip_mb(b);
}
extern "C"
int get_plot_details_new(const struct dive *d, const struct plot_info *pi, int time, struct membuffer *mb)
{
int i;
@ -1535,11 +1533,12 @@ int get_plot_details_new(const struct dive *d, const struct plot_info *pi, int t
}
/* Compare two plot_data entries and writes the results into a string */
extern "C"
void compare_samples(const struct dive *d, const struct plot_info *pi, int idx1, int idx2, char *buf, int bufsize, bool sum)
{
struct plot_data *start, *stop, *data;
const char *depth_unit, *pressure_unit, *vertical_speed_unit;
char *buf2 = malloc(bufsize);
std::vector<char> buf2(bufsize);
int avg_speed, max_asc_speed, max_desc_speed;
int delta_depth, avg_depth, max_depth, min_depth;
int pressurevalue;
@ -1550,7 +1549,6 @@ void compare_samples(const struct dive *d, const struct plot_info *pi, int idx1,
if (bufsize > 0)
buf[0] = '\0';
if (idx1 < 0 || idx2 < 0) {
free(buf2);
return;
}
@ -1559,7 +1557,6 @@ void compare_samples(const struct dive *d, const struct plot_info *pi, int idx1,
idx2 = idx1;
idx1 = tmp;
} else if (pi->entry[idx1].sec == pi->entry[idx2].sec) {
free(buf2);
return;
}
start = pi->entry + idx1;
@ -1578,11 +1575,11 @@ void compare_samples(const struct dive *d, const struct plot_info *pi, int idx1,
last_sec = start->sec;
volume_t cylinder_volume = { .mliter = 0, };
int *start_pressures = calloc((size_t)pi->nr_cylinders, sizeof(int));
int *last_pressures = calloc((size_t)pi->nr_cylinders, sizeof(int));
int *bar_used = calloc((size_t)pi->nr_cylinders, sizeof(int));
int *volumes_used = calloc((size_t)pi->nr_cylinders, sizeof(int));
bool *cylinder_is_used = calloc((size_t)pi->nr_cylinders, sizeof(bool));
std::vector<int> start_pressures(pi->nr_cylinders, 0);
std::vector<int> last_pressures(pi->nr_cylinders, 0);
std::vector<int> bar_used(pi->nr_cylinders, 0);
std::vector<int> volumes_used(pi->nr_cylinders, 0);
std::vector<char> cylinder_is_used(pi->nr_cylinders, 0);
data = start;
for (int i = idx1; i < idx2; ++i) {
@ -1603,7 +1600,7 @@ void compare_samples(const struct dive *d, const struct plot_info *pi, int idx1,
if (data->depth > max_depth)
max_depth = data->depth;
for (unsigned cylinder_index = 0; cylinder_index < pi->nr_cylinders; cylinder_index++) {
for (int cylinder_index = 0; cylinder_index < pi->nr_cylinders; cylinder_index++) {
int next_pressure = get_plot_pressure(pi, i, cylinder_index);
if (next_pressure && !start_pressures[cylinder_index])
start_pressures[cylinder_index] = next_pressure;
@ -1629,47 +1626,44 @@ void compare_samples(const struct dive *d, const struct plot_info *pi, int idx1,
last_sec = data->sec;
}
free(start_pressures);
free(last_pressures);
avg_depth /= stop->sec - start->sec;
avg_speed /= stop->sec - start->sec;
snprintf_loc(buf, bufsize, translate("gettextFromC", "ΔT:%d:%02dmin"), delta_time / 60, delta_time % 60);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("ΔT:%d:%02dmin")), delta_time / 60, delta_time % 60);
memcpy(&buf2[0], buf, bufsize);
depthvalue = get_depth_units(delta_depth, NULL, &depth_unit);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s ΔD:%.1f%s"), buf2, depthvalue, depth_unit);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s ΔD:%.1f%s")), &buf2[0], depthvalue, depth_unit);
memcpy(&buf2[0], buf, bufsize);
depthvalue = get_depth_units(min_depth, NULL, &depth_unit);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s ↓D:%.1f%s"), buf2, depthvalue, depth_unit);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s ↓D:%.1f%s")), &buf2[0], depthvalue, depth_unit);
memcpy(&buf2[0], buf, bufsize);
depthvalue = get_depth_units(max_depth, NULL, &depth_unit);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s ↑D:%.1f%s"), buf2, depthvalue, depth_unit);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s ↑D:%.1f%s")), &buf2[0], depthvalue, depth_unit);
memcpy(&buf2[0], buf, bufsize);
depthvalue = get_depth_units(avg_depth, NULL, &depth_unit);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s øD:%.1f%s\n"), buf2, depthvalue, depth_unit);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s øD:%.1f%s\n")), &buf2[0], depthvalue, depth_unit);
memcpy(&buf2[0], buf, bufsize);
speedvalue = get_vertical_speed_units(abs(max_desc_speed), NULL, &vertical_speed_unit);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s ↓V:%.2f%s"), buf2, speedvalue, vertical_speed_unit);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s ↓V:%.2f%s")), &buf2[0], speedvalue, vertical_speed_unit);
memcpy(&buf2[0], buf, bufsize);
speedvalue = get_vertical_speed_units(abs(max_asc_speed), NULL, &vertical_speed_unit);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s ↑V:%.2f%s"), buf2, speedvalue, vertical_speed_unit);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s ↑V:%.2f%s")), &buf2[0], speedvalue, vertical_speed_unit);
memcpy(&buf2[0], buf, bufsize);
speedvalue = get_vertical_speed_units(abs(avg_speed), NULL, &vertical_speed_unit);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s øV:%.2f%s"), buf2, speedvalue, vertical_speed_unit);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s øV:%.2f%s")), &buf2[0], speedvalue, vertical_speed_unit);
int total_bar_used = 0;
int total_volume_used = 0;
bool cylindersizes_are_identical = true;
bool sac_is_determinable = true;
for (unsigned cylinder_index = 0; cylinder_index < pi->nr_cylinders; cylinder_index++)
for (int cylinder_index = 0; cylinder_index < pi->nr_cylinders; cylinder_index++) {
if (cylinder_is_used[cylinder_index]) {
total_bar_used += bar_used[cylinder_index];
total_volume_used += volumes_used[cylinder_index];
@ -1685,15 +1679,13 @@ void compare_samples(const struct dive *d, const struct plot_info *pi, int idx1,
sac_is_determinable = false;
}
}
free(bar_used);
free(volumes_used);
free(cylinder_is_used);
}
// No point printing 'bar used' if we know it's meaningless because cylinders of different size were used
if (cylindersizes_are_identical && total_bar_used) {
pressurevalue = get_pressure_units(total_bar_used, &pressure_unit);
memcpy(buf2, buf, bufsize);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s ΔP:%d%s"), buf2, pressurevalue, pressure_unit);
memcpy(&buf2[0], buf, bufsize);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s ΔP:%d%s")), &buf2[0], pressurevalue, pressure_unit);
}
// We can't calculate the SAC if the volume for some of the cylinders used is unknown
@ -1707,10 +1699,8 @@ void compare_samples(const struct dive *d, const struct plot_info *pi, int idx1,
/* milliliters per minute */
int sac = lrint(total_volume_used / atm * 60 / delta_time);
memcpy(buf2, buf, bufsize);
memcpy(&buf2[0], buf, bufsize);
volume_value = get_volume_units(sac, &volume_precision, &volume_unit);
snprintf_loc(buf, bufsize, translate("gettextFromC", "%s SAC:%.*f%s/min"), buf2, volume_precision, volume_value, volume_unit);
snprintf_loc(buf, bufsize, qPrintable(gettextFromC::tr("%s SAC:%.*f%s/min")), &buf2[0], volume_precision, volume_value, volume_unit);
}
free(buf2);
}