示例#1
0
static void save_cylinder_info(struct membuffer *b, struct dive *dive)
{
	int i, nr;

	nr = nr_cylinders(dive);
	for (i = 0; i < nr; i++) {
		cylinder_t *cylinder = dive->cylinder + i;
		int volume = cylinder->type.size.mliter;
		const char *description = cylinder->type.description;
		int o2 = cylinder->gasmix.o2.permille;
		int he = cylinder->gasmix.he.permille;

		put_string(b, "cylinder");
		if (volume)
			put_milli(b, " vol=", volume, "l");
		put_pressure(b, cylinder->type.workingpressure, " workpressure=", "bar");
		show_utf8(b, " description=", description, "");
		strip_mb(b);
		if (o2) {
			put_format(b, " o2=%u.%u%%", FRACTION(o2, 10));
			if (he)
				put_format(b, " he=%u.%u%%", FRACTION(he, 10));
		}
		put_pressure(b, cylinder->start, " start=", "bar");
		put_pressure(b, cylinder->end, " end=", "bar");
		put_string(b, "\n");
	}
}
示例#2
0
static const char *
format_time_interval(unsigned int i)
{
    static char     buf[128];
    char           *p           = buf;
    unsigned int    h           = i / (60 * 60 * 1000);
    unsigned int    m           = (i % (60 * 60 * 1000)) / (60 * 1000);
    unsigned int    s           = (i % (60 * 1000)) / 1000;
    unsigned int    ms          = i % 1000;

#define FRACTION(_prev_sum, _name, _val) \
    do {                                                \
        if ((_val) > 0)                                 \
            p += snprintf(p, sizeof(buf) - (p - buf),   \
                          "%s%u " _name "%s",           \
                          ((_prev_sum) > 0 ? " " : ""), \
                          _val,                         \
                          (((_val) == 1) ? "" : "s"));  \
        if (p >= (buf + sizeof(buf)))                   \
            return buf;                                 \
    } while (0)

    FRACTION(0, "hour", h);
    FRACTION(h, "minute", m);
    FRACTION(h + m, "second", s);
    FRACTION(h + m + s, "millisecond", ms);

#undef FRACTION

    return buf;
}
示例#3
0
static void save_cylinder_info(FILE *f, struct dive *dive)
{
	int i;

	for (i = 0; i < MAX_CYLINDERS; i++) {
		cylinder_t *cylinder = dive->cylinder+i;
		int volume = cylinder->type.size.mliter;
		const char *description = cylinder->type.description;
		int o2 = cylinder->gasmix.o2.permille;
		int he = cylinder->gasmix.he.permille;
		int start = cylinder->start.mbar;
		int end = cylinder->end.mbar;

		/* No cylinder information at all? */
		if (!o2 && !volume && !start && !end)
			return;
		fprintf(f, "  <cylinder");
		if (volume)
			show_milli(f, " size='", volume, " l", "'");
		show_pressure(f, cylinder->type.workingpressure, " workpressure='", "'");
		if (description && *description)
			fprintf(f, " description='%s'", description);
		if (o2) {
			fprintf(f, " o2='%u.%u%%'", FRACTION(o2, 10));
			if (he)
				fprintf(f, " he='%u.%u%%'", FRACTION(he, 10));
		}
		show_pressure(f, cylinder->start, " start='", "'");
		show_pressure(f, cylinder->end, " end='", "'");
		fprintf(f, " />\n");
	}
}
示例#4
0
static void save_cylinder_info(FILE *f, struct dive *dive)
{
	int i, nr;

	nr = nr_cylinders(dive);

	for (i = 0; i < nr; i++) {
		cylinder_t *cylinder = dive->cylinder+i;
		int volume = cylinder->type.size.mliter;
		const char *description = cylinder->type.description;
		int o2 = cylinder->gasmix.o2.permille;
		int he = cylinder->gasmix.he.permille;

		fprintf(f, "  <cylinder");
		if (volume)
			show_milli(f, " size='", volume, " l", "'");
		show_pressure(f, cylinder->type.workingpressure, " workpressure='", "'");
		if (description && *description)
			fprintf(f, " description='%s'", description);
		if (o2) {
			fprintf(f, " o2='%u.%u%%'", FRACTION(o2, 10));
			if (he)
				fprintf(f, " he='%u.%u%%'", FRACTION(he, 10));
		}
		show_pressure(f, cylinder->start, " start='", "'");
		show_pressure(f, cylinder->end, " end='", "'");
		fprintf(f, " />\n");
	}
}
示例#5
0
void DivePlannerPointsModel::computeVariations()
{
	bool oldRecalc = setRecalc(false);
	struct dive *dive = alloc_dive();
	copy_dive(&displayed_dive, dive);
	struct decostop original[60], deeper[60], shallower[60], shorter[60], longer[60];
	struct deco_state *cache = NULL, *save = NULL;
	struct diveplan plan_copy;
	struct divedatapoint *last_segment;

	if(in_planner() && prefs.display_variations) {
		cache_deco_state(&save);
		cloneDiveplan(&plan_copy);
		plan(&plan_copy, dive, 1, original, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);

		last_segment = cloneDiveplan(&plan_copy);
		last_segment->depth.mm += 1000;
		last_segment->next->depth.mm += 1000;
		plan(&plan_copy, dive, 1, deeper, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);

		last_segment = cloneDiveplan(&plan_copy);
		last_segment->depth.mm -= 1000;
		last_segment->next->depth.mm -= 1000;
		plan(&plan_copy, dive, 1, shallower, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);

		last_segment = cloneDiveplan(&plan_copy);
		last_segment->next->time += 60;
		plan(&plan_copy, dive, 1, longer, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);

		last_segment = cloneDiveplan(&plan_copy);
		last_segment->next->time -= 60;
		plan(&plan_copy, dive, 1, shorter, &cache, true, false);
		free_dps(&plan_copy);
		restore_deco_state(save, false);
#ifdef SHOWSTOPVARIATIONS
		printf("\n\n");
#endif

		QString notes(displayed_dive.notes);
		free(displayed_dive.notes);

		char buf[200];
		sprintf(buf, "+ %d:%02d /m + %d:%02d /min", FRACTION(analyzeVariations(shallower, original, deeper, "m"),60),
			FRACTION(analyzeVariations(shorter, original, longer, "min"), 60));

		displayed_dive.notes = strdup(notes.replace("VARIATIONS", QString(buf)).toUtf8().data());
	}
	setRecalc(oldRecalc);
}
示例#6
0
static void put_gasmix(struct membuffer *b, struct gasmix *mix)
{
	int o2 = mix->o2.permille;
	int he = mix->he.permille;

	if (o2) {
		put_format(b, " o2='%u.%u%%'", FRACTION(o2, 10));
		if (he)
			put_format(b, " he='%u.%u%%'", FRACTION(he, 10));
	}
}
示例#7
0
static void save_sample(struct membuffer *b, struct sample *sample, struct sample *old)
{
	put_format(b, "  <sample time='%u:%02u min'", FRACTION(sample->time.seconds, 60));
	put_milli(b, " depth='", sample->depth.mm, " m'");
	put_temperature(b, sample->temperature, " temp='", " C'");
	put_pressure(b, sample->cylinderpressure, " pressure='", " bar'");

	/*
	 * We only show sensor information for samples with pressure, and only if it
	 * changed from the previous sensor we showed.
	 */
	if (sample->cylinderpressure.mbar && sample->sensor != old->sensor) {
		put_format(b, " sensor='%d'", sample->sensor);
		old->sensor = sample->sensor;
	}

	/* the deco/ndl values are stored whenever they change */
	if (sample->ndl.seconds != old->ndl.seconds) {
		put_format(b, " ndl='%u:%02u min'", FRACTION(sample->ndl.seconds, 60));
		old->ndl = sample->ndl;
	}
	if (sample->in_deco != old->in_deco) {
		put_format(b, " in_deco='%d'", sample->in_deco ? 1 : 0);
		old->in_deco = sample->in_deco;
	}
	if (sample->stoptime.seconds != old->stoptime.seconds) {
		put_format(b, " stoptime='%u:%02u min'", FRACTION(sample->stoptime.seconds, 60));
		old->stoptime = sample->stoptime;
	}

	if (sample->stopdepth.mm != old->stopdepth.mm) {
		put_milli(b, " stopdepth='", sample->stopdepth.mm, " m'");
		old->stopdepth = sample->stopdepth;
	}

	if (sample->cns != old->cns) {
		put_format(b, " cns='%u%%'", sample->cns);
		old->cns = sample->cns;
	}

	if (sample->po2 != old->po2) {
		put_milli(b, " po2='", sample->po2, " bar'");
		old->po2 = sample->po2;
	}
	show_index(b, sample->heartbeat, "heartbeat='", "'");
	show_index(b, sample->bearing, "bearing='", "'");
	put_format(b, " />\n");
}
示例#8
0
/*
 * Samples are saved as densely as possible while still being readable,
 * since they are the bulk of the data.
 *
 * For parsing, look at the units to figure out what the numbers are.
 */
static void save_sample(struct membuffer *b, struct sample *sample, struct sample *old)
{
	put_format(b, "%3u:%02u", FRACTION(sample->time.seconds, 60));
	put_milli(b, " ", sample->depth.mm, "m");
	put_temperature(b, sample->temperature, " ", "°C");
	put_pressure(b, sample->cylinderpressure, " ", "bar");

	/*
	 * We only show sensor information for samples with pressure, and only if it
	 * changed from the previous sensor we showed.
	 */
	if (sample->cylinderpressure.mbar && sample->sensor != old->sensor) {
		put_format(b, " sensor=%d", sample->sensor);
		old->sensor = sample->sensor;
	}

	/* the deco/ndl values are stored whenever they change */
	if (sample->ndl.seconds != old->ndl.seconds) {
		put_format(b, " ndl=%u:%02u", FRACTION(sample->ndl.seconds, 60));
		old->ndl = sample->ndl;
	}
	if (sample->in_deco != old->in_deco) {
		put_format(b, " in_deco=%d", sample->in_deco ? 1 : 0);
		old->in_deco = sample->in_deco;
	}
	if (sample->stoptime.seconds != old->stoptime.seconds) {
		put_format(b, " stoptime=%u:%02u", FRACTION(sample->stoptime.seconds, 60));
		old->stoptime = sample->stoptime;
	}

	if (sample->stopdepth.mm != old->stopdepth.mm) {
		put_milli(b, " stopdepth=", sample->stopdepth.mm, "m");
		old->stopdepth = sample->stopdepth;
	}

	if (sample->cns != old->cns) {
		put_format(b, " cns=%u%%", sample->cns);
		old->cns = sample->cns;
	}

	if (sample->po2.mbar != old->po2.mbar) {
		put_milli(b, " po2=", sample->po2.mbar, "bar");
		old->po2 = sample->po2;
	}
	show_index(b, sample->heartbeat, "heartbeat=", "");
	show_index(b, sample->bearing.degrees, "bearing=", "°");
	put_format(b, "\n");
}
示例#9
0
void save_one_dive_to_mb(struct membuffer *b, struct dive *dive)
{
	struct divecomputer *dc;

	put_string(b, "<dive");
	if (dive->number)
		put_format(b, " number='%d'", dive->number);
	if (dive->tripflag == NO_TRIP)
		put_format(b, " tripflag='NOTRIP'");
	if (dive->rating)
		put_format(b, " rating='%d'", dive->rating);
	if (dive->visibility)
		put_format(b, " visibility='%d'", dive->visibility);
	save_tags(b, dive->tag_list);
	if (dive->dive_site_uuid)
		put_format(b, " divesiteid='%8x'", dive->dive_site_uuid);
	show_date(b, dive->when);
	put_format(b, " duration='%u:%02u min'>\n",
		   FRACTION(dive->dc.duration.seconds, 60));
	save_overview(b, dive);
	save_cylinder_info(b, dive);
	save_weightsystem_info(b, dive);
	save_dive_temperature(b, dive);
	/* Save the dive computer data */
	for_each_dc(dive, dc)
		save_dc(b, dive, dc);
	FOR_EACH_PICTURE(dive)
		save_picture(b, picture);
	put_format(b, "</dive>\n");
}
示例#10
0
static void save_dive(FILE *f, struct dive *dive)
{
	int i;
	struct tm tm;

	utc_mkdate(dive->when, &tm);

	fputs("<dive", f);
	if (dive->number)
		fprintf(f, " number='%d'", dive->number);
	if (dive->tripflag != TF_NONE)
		fprintf(f, " tripflag='%s'", tripflag_names[dive->tripflag]);
	if (dive->rating)
		fprintf(f, " rating='%d'", dive->rating);
	fprintf(f, " date='%04u-%02u-%02u'",
		tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday);
	fprintf(f, " time='%02u:%02u:%02u'",
		tm.tm_hour, tm.tm_min, tm.tm_sec);
	fprintf(f, " duration='%u:%02u min'>\n",
		FRACTION(dive->duration.seconds, 60));
	save_overview(f, dive);
	save_cylinder_info(f, dive);
	save_weightsystem_info(f, dive);
	save_events(f, dive->events);
	for (i = 0; i < dive->samples; i++)
		save_sample(f, dive->sample+i);
	fprintf(f, "</dive>\n");
}
示例#11
0
int DivePlannerPointsModel::analyzeVariations(struct decostop *min, struct decostop *mid, struct decostop *max, const char *unit)
{
	int leftsum = 0;
	int rightsum = 0;
	while (mid->depth > min->depth)
		++mid;
	while (max->depth > mid->depth)
		++max;

	while (mid->depth) {
		int left = mid->time - min->time;
		leftsum += left;
		int right = max->time - mid->time;
		rightsum += right;
#ifdef SHOWSTOPVARIATIONS
		if (min->time + mid->time + max->time)
			printf("%dm: %dmin + %ds/%s +- %ds/%s\n", mid->depth / 1000,
			       (mid->time + 1)/60,
			       (left + right) / 2, unit,
			       (right - left) / 2, unit);
#endif
		++min;
		++mid;
		++max;
	}
#ifdef SHOWSTOPVARIATIONS
	printf("Total + %d:%02d/%s +- %d s/%s\n\n", FRACTION((leftsum + rightsum) / 2, 60), unit,
						       (rightsum - leftsum) / 2, unit);
#endif
	return (leftsum + rightsum) / 2;
}
示例#12
0
int put_duration(struct membuffer *b, duration_t duration, const char *pre, const char *post)
{
	if (!duration.seconds)
		return 0;

	put_format(b, "%s%u:%02u%s", pre, FRACTION(duration.seconds, 60), post);
	return 1;
}
示例#13
0
static void save_one_event(struct membuffer *b, struct event *ev)
{
	put_format(b, "  <event time='%d:%02d min'", FRACTION(ev->time.seconds, 60));
	show_index(b, ev->type, "type='", "'");
	show_index(b, ev->flags, "flags='", "'");
	show_index(b, ev->value, "value='", "'");
	show_utf8(b, ev->name, " name='", "'", 1);
	put_format(b, " />\n");
}
示例#14
0
static void save_one_event(FILE *f, struct event *ev)
{
	fprintf(f, "  <event time='%d:%02d min'", FRACTION(ev->time.seconds,60));
	show_index(f, ev->type, "type='", "'");
	show_index(f, ev->flags, "flags='", "'");
	show_index(f, ev->value, "value='", "'");
	show_utf8(f, ev->name, " name='", "'");
	fprintf(f, " />\n");
}
示例#15
0
static void save_one_event(struct membuffer *b, struct event *ev)
{
	put_format(b, "event %d:%02d", FRACTION(ev->time.seconds, 60));
	show_index(b, ev->type, "type=", "");
	show_index(b, ev->flags, "flags=", "");
	show_index(b, ev->value, "value=", "");
	show_utf8(b, " name=", ev->name, "");
	put_string(b, "\n");
}
示例#16
0
static void save_sample(FILE *f, struct sample *sample)
{
	fprintf(f, "  <sample time='%u:%02u min'", FRACTION(sample->time.seconds,60));
	show_milli(f, " depth='", sample->depth.mm, " m", "'");
	show_temperature(f, sample->temperature, " temp='", "'");
	show_pressure(f, sample->cylinderpressure, " pressure='", "'");
	if (sample->cylinderindex)
		fprintf(f, " cylinderindex='%d'", sample->cylinderindex);
	fprintf(f, " />\n");
}
示例#17
0
void put_degrees(struct membuffer *b, degrees_t value, const char *pre, const char *post)
{
	int udeg = value.udeg;
	const char *sign = "";

	if (udeg < 0) {
		udeg = -udeg;
		sign = "-";
	}
	put_format(b,"%s%s%u.%06u%s", pre, sign, FRACTION(udeg, 1000000), post);
}
示例#18
0
/*
 * Note that we don't save the date and time or dive
 * number: they are encoded in the filename.
 */
static void create_dive_buffer(struct dive *dive, struct membuffer *b)
{
	put_format(b, "duration %u:%02u min\n", FRACTION(dive->dc.duration.seconds, 60));
	SAVE("rating", rating);
	SAVE("visibility", visibility);
	cond_put_format(dive->tripflag == NO_TRIP, b, "notrip\n");
	save_tags(b, dive->tag_list);

	save_overview(b, dive);
	save_cylinder_info(b, dive);
	save_weightsystem_info(b, dive);
	save_dive_temperature(b, dive);
}
示例#19
0
static   int  hash2_function(
    hash2_table_struct   *hash_table,
    int                 key1,
    int                 key2 )
{
    int    index;
    Real   v;

    v = (Real) key1 * HASH1_FUNCTION_CONSTANT +
        (Real) key2 * HASH2_FUNCTION_CONSTANT;

    index = (int) (FRACTION(v) * (Real) hash_table->size);

    return( index );
}
示例#20
0
static void save_one_event(struct membuffer *b, struct event *ev)
{
	put_format(b, "  <event time='%d:%02d min'", FRACTION(ev->time.seconds, 60));
	show_index(b, ev->type, "type='", "'");
	show_index(b, ev->flags, "flags='", "'");
	show_index(b, ev->value, "value='", "'");
	show_utf8(b, ev->name, " name='", "'", 1);
	if (event_is_gaschange(ev)) {
		if (ev->gas.index >= 0) {
			show_index(b, ev->gas.index, "cylinder='", "'");
			put_gasmix(b, &ev->gas.mix);
		} else if (!event_gasmix_redundant(ev))
			put_gasmix(b, &ev->gas.mix);
	}
	put_format(b, " />\n");
}
示例#21
0
void dump_plan(struct diveplan *diveplan)
{
	struct divedatapoint *dp;
	struct tm tm;

	if (!diveplan) {
		printf("Diveplan NULL\n");
		return;
	}
	utc_mkdate(diveplan->when, &tm);

	printf("\nDiveplan @ %04d-%02d-%02d %02d:%02d:%02d (surfpres %dmbar):\n",
	       tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
	       tm.tm_hour, tm.tm_min, tm.tm_sec,
	       diveplan->surface_pressure);
	dp = diveplan->dp;
	while (dp) {
		printf("\t%3u:%02u: %dmm gas: %d o2 %d h2\n", FRACTION(dp->time, 60), dp->depth, get_o2(&dp->gasmix), get_he(&dp->gasmix));
		dp = dp->next;
	}
}
示例#22
0
static void save_dive(FILE *f, struct dive *dive)
{
	int i;
	struct tm *tm = gmtime(&dive->when);

	fputs("<dive", f);
	if (dive->number)
		fprintf(f, " number='%d'", dive->number);
	fprintf(f, " date='%04u-%02u-%02u'",
		tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
	fprintf(f, " time='%02u:%02u:%02u'",
		tm->tm_hour, tm->tm_min, tm->tm_sec);
	fprintf(f, " duration='%u:%02u min'>\n",
		FRACTION(dive->duration.seconds, 60));
	save_overview(f, dive);
	save_cylinder_info(f, dive);
	save_events(f, dive->events);
	for (i = 0; i < dive->samples; i++)
		save_sample(f, dive->sample+i);
	fprintf(f, "</dive>\n");
}
示例#23
0
static void save_picture(struct membuffer *b, struct picture *pic)
{
	put_string(b, "  <picture filename='");
	put_quoted(b, pic->filename, true, false);
	put_string(b, "'");
	if (pic->offset.seconds) {
		int offset = pic->offset.seconds;
		char sign = '+';
		if (offset < 0) {
			sign = '-';
			offset = -offset;
		}
		put_format(b, " offset='%c%u:%02u min'", sign, FRACTION(offset, 60));
	}
	if (pic->latitude.udeg || pic->longitude.udeg) {
		put_degrees(b, pic->latitude, " gps='", " ");
		put_degrees(b, pic->longitude, "", "'");
	}
	if (hashstring(pic->filename))
		put_format(b, " hash='%s'", hashstring(pic->filename));

	put_string(b, "/>\n");
}
示例#24
0
static void save_dive(FILE *f, struct dive *dive)
{
	int i;
	struct tm tm;

	utc_mkdate(dive->when, &tm);

	fputs("<dive", f);
	if (dive->number)
		fprintf(f, " number='%d'", dive->number);
	/*
	 * TF_NONE is the default for dives with no trips
	 * IN_TRIP is the default for dives with trips
	 * ASSIGNED_TRIP is an in-memory thing and gets converted
	 *    to IN_TRIP by the save code.
	 */
	if (dive->tripflag != TF_NONE && dive->tripflag != IN_TRIP && dive->tripflag != ASSIGNED_TRIP)
		fprintf(f, " tripflag='%s'", tripflag_names[dive->tripflag]);
	if (dive->rating)
		fprintf(f, " rating='%d'", dive->rating);
	if (dive->visibility)
		fprintf(f, " visibility='%d'", dive->visibility);
	fprintf(f, " date='%04u-%02u-%02u'",
		tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday);
	fprintf(f, " time='%02u:%02u:%02u'",
		tm.tm_hour, tm.tm_min, tm.tm_sec);
	fprintf(f, " duration='%u:%02u min'>\n",
		FRACTION(dive->duration.seconds, 60));
	save_overview(f, dive);
	save_cylinder_info(f, dive);
	save_weightsystem_info(f, dive);
	save_events(f, dive->events);
	for (i = 0; i < dive->samples; i++)
		save_sample(f, dive->sample+i);
	fprintf(f, "</dive>\n");
}
示例#25
0
static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_disclaimer)
{
	char buffer[20000], temp[1000];
	int len, lastdepth = 0, lasttime = 0;
	struct divedatapoint *dp = diveplan->dp;
	bool gaschange = !plan_verbatim;
	struct divedatapoint *nextdp = NULL;

	disclaimer =  translate("gettextFromC", "DISCLAIMER / WARNING: THIS IS A NEW IMPLEMENTATION OF THE BUHLMANN "
				"ALGORITHM AND A DIVE PLANNER IMPLEMENTION BASED ON THAT WHICH HAS "
				"RECEIVED ONLY A LIMITED AMOUNT OF TESTING. WE STRONGLY RECOMMEND NOT TO "
				"PLAN DIVES SIMPLY BASED ON THE RESULTS GIVEN HERE.");

	if (!dp)
		return;

	len = show_disclaimer ? snprintf(buffer, sizeof(buffer), "<div><b>%s<b></div><br>", disclaimer) : 0;
	snprintf(temp, sizeof(temp), translate("gettextFromC", "based on GFlow = %d and GFhigh = %d"),
		 diveplan->gflow, diveplan->gfhigh);
	len += snprintf(buffer + len, sizeof(buffer) - len, "<div><b>%s</b><br>%s</div><br>",
			translate("gettextFromC", "Subsurface dive plan"), temp);

	if (!plan_verbatim) {
		len += snprintf(buffer + len, sizeof(buffer) - len, "<div><table><thead><tr><th>%s</th>",
				translate("gettextFromC", "depth"));
		if (plan_display_runtime)
			len += snprintf(buffer + len, sizeof(buffer) - len, "<th style='padding-left: 10px;'>%s</th>",
					translate("gettextFromC", "runtime"));
		if (plan_display_duration)
			len += snprintf(buffer + len, sizeof(buffer) - len, "<th style='padding-left: 10px;'>%s</th>",
					translate("gettextFromC", "duration"));
		len += snprintf(buffer + len, sizeof(buffer) - len,
				"<th style='padding-left: 10px; float: left;'>%s</th></tr></thead><tbody style='float: left;'>",
				translate("gettextFromC", "gas"));
	}
	do {
		struct gasmix gasmix, newgasmix = {};
		const char *depth_unit;
		double depthvalue;
		int decimals;

		if (dp->time == 0)
			continue;
		gasmix = dp->gasmix;
		depthvalue = get_depth_units(dp->depth, &decimals, &depth_unit);
		/* analyze the dive points ahead */
		nextdp = dp->next;
		while (nextdp && nextdp->time == 0)
			nextdp = nextdp->next;
		if (nextdp)
			newgasmix = nextdp->gasmix;
		/* do we want to skip this leg as it is devoid of anything useful? */
		if (!dp->entered &&
		    gasmix_distance(&gasmix, &newgasmix) == 0 &&
		    nextdp &&
		    dp->depth != lastdepth &&
		    nextdp->depth != dp->depth)
			continue;
		if (dp->time - lasttime < 10 && !(gaschange && dp->next && dp->depth != dp->next->depth))
			continue;

		len = strlen(buffer);
		if (nextdp && gasmix_distance(&gasmix, &newgasmix))
			gaschange = true;
		if (plan_verbatim) {
			if (dp->depth != lastdepth) {
				if (plan_display_transitions || dp->entered || !dp->next || (gaschange && dp->next && dp->depth != nextdp->depth)) {
					snprintf(temp, sizeof(temp), translate("gettextFromC", "Transition to %.*f %s in %d:%02d min - runtime %d:%02u on %s"),
						 decimals, depthvalue, depth_unit,
						 FRACTION(dp->time - lasttime, 60),
						 FRACTION(dp->time, 60),
						 gasname(&gasmix));
					len += snprintf(buffer + len, sizeof(buffer) - len, "%s<br>", temp);
					lasttime = dp->time;
				}
			} else {
				if (dp->depth != nextdp->depth) {
					snprintf(temp, sizeof(temp), translate("gettextFromC", "Stay at %.*f %s for %d:%02d min - runtime %d:%02u on %s"),
							decimals, depthvalue, depth_unit,
							FRACTION(dp->time - lasttime, 60),
							FRACTION(dp->time, 60),
							gasname(&gasmix));
					len += snprintf(buffer + len, sizeof(buffer) - len, "%s<br>", temp);
					lasttime = dp->time;
				}
			}
		} else {
			if ((dp->depth == lastdepth && dp->depth != nextdp->depth) || plan_display_transitions || dp->entered || !dp->next || (gaschange && dp->next && dp->depth != nextdp->depth)) {
				snprintf(temp, sizeof(temp), translate("gettextFromC", "%3.0f%s"), depthvalue, depth_unit);
				len += snprintf(buffer + len, sizeof(buffer) - len, "<tr><td style='padding-left: 10px; float: right;'>%s</td>", temp);
				if (plan_display_runtime) {
					snprintf(temp, sizeof(temp), translate("gettextFromC", "%3dmin"), (dp->time + 30) / 60);
					len += snprintf(buffer + len, sizeof(buffer) - len, "<td style='padding-left: 10px; float: right;'>%s</td>", temp);
				}
				if (plan_display_duration) {
					snprintf(temp, sizeof(temp), translate("gettextFromC", "%3dmin"), (dp->time - lasttime + 30) / 60);
					len += snprintf(buffer + len, sizeof(buffer) - len, "<td style='padding-left: 10px; float: right;'>%s</td>", temp);
				}
				if (gaschange) {
					len += snprintf(buffer + len, sizeof(buffer) - len, "<td style='padding-left: 10px; color: red; float: left;'><b>%s</b></td>", gasname(&newgasmix));
					gaschange = false;
				} else {
					len += snprintf(buffer + len, sizeof(buffer) - len, "<td>&nbsp;</td>");
				}
				len += snprintf(buffer + len, sizeof(buffer) - len, "</tr>");
				lasttime = dp->time;
			}
		}
		if (gaschange) {
			// gas switch at this waypoint
			if (plan_verbatim) {
				snprintf(temp, sizeof(temp), translate("gettextFromC", "Switch gas to %s"), gasname(&newgasmix));
				len += snprintf(buffer + len, sizeof(buffer) - len, "%s<br>", temp);
				gaschange = false;
			}
			gasmix = newgasmix;
		}
		lastdepth = dp->depth;
	} while ((dp = nextdp) != NULL);
	len += snprintf(buffer + len, sizeof(buffer) - len, "</tbody></table></div>");

	dive->cns = 0;
	dive->maxcns = 0;
	update_cylinder_related_info(dive);
	snprintf(temp, sizeof(temp), "%s", translate("gettextFromC", "CNS"));
	len += snprintf(buffer + len, sizeof(buffer) - len, "<div><br>%s: %i%%", temp, dive->cns);
	snprintf(temp, sizeof(temp), "%s", translate("gettextFromC", "OTU"));
	len += snprintf(buffer + len, sizeof(buffer) - len, "<br>%s: %i</div>", temp, dive->otu);

	snprintf(temp, sizeof(temp), "%s", translate("gettextFromC", "Gas consumption:"));
	len += snprintf(buffer + len, sizeof(buffer) - len, "<div><br>%s<br>", temp);
	for (int gasidx = 0; gasidx < MAX_CYLINDERS; gasidx++) {
		double volume, pressure, deco_volume, deco_pressure;
		const char *unit, *pressure_unit;
		char warning[1000] = "";
		cylinder_t *cyl = &dive->cylinder[gasidx];
		if (cylinder_none(cyl))
			break;

		volume = get_volume_units(cyl->gas_used.mliter, NULL, &unit);
		deco_volume = get_volume_units(cyl->deco_gas_used.mliter, NULL, &unit);
		if (cyl->type.size.mliter) {
			deco_pressure = get_pressure_units(1000.0 * cyl->deco_gas_used.mliter / cyl->type.size.mliter, &pressure_unit);
			pressure = get_pressure_units(1000.0 * cyl->gas_used.mliter / cyl->type.size.mliter, &pressure_unit);
			/* Warn if the plan uses more gas than is available in a cylinder
			 * This only works if we have working pressure for the cylinder
			 * 10bar is a made up number - but it seemed silly to pretend you could breathe cylinder down to 0 */
			if (cyl->end.mbar < 10000)
				snprintf(warning, sizeof(warning), " &mdash; <span style='color: red;'>%s </span> %s",
					translate("gettextFromC", "Warning:"),
					translate("gettextFromC", "this is more gas than available in the specified cylinder!"));
			else
				if ((float) cyl->end.mbar * cyl->type.size.mliter / 1000.0 < (float) cyl->deco_gas_used.mliter)
					snprintf(warning, sizeof(warning), " &mdash; <span style='color: red;'>%s </span> %s",
						translate("gettextFromC", "Warning:"),
						translate("gettextFromC", "not enough reserve for gas sharing on ascent!"));

			snprintf(temp, sizeof(temp), translate("gettextFromC", "%.0f%s/%.0f%s of %s (%.0f%s/%.0f%s in planned ascent)"), volume, unit, pressure, pressure_unit, gasname(&cyl->gasmix), deco_volume, unit, deco_pressure, pressure_unit);
		} else {
			snprintf(temp, sizeof(temp), translate("gettextFromC", "%.0f%s (%.0f%s during planned ascent) of %s"), volume, unit, deco_volume, unit, gasname(&cyl->gasmix));
		}
		len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s<br>", temp, warning);
	}
	dp = diveplan->dp;
	while (dp) {
		if (dp->time != 0) {
			int pO2 = depth_to_atm(dp->depth, dive) * get_o2(&dp->gasmix);

			if (pO2 > (dp->entered ? prefs.bottompo2 : prefs.decopo2)) {
				const char *depth_unit;
				int decimals;
				double depth_value = get_depth_units(dp->depth, &decimals, &depth_unit);
				len = strlen(buffer);
				snprintf(temp, sizeof(temp),
					 translate("gettextFromC", "high pO₂ value %.2f at %d:%02u with gas %s at depth %.*f %s"),
					 pO2 / 1000.0, FRACTION(dp->time, 60), gasname(&dp->gasmix), decimals, depth_value, depth_unit);
				len += snprintf(buffer + len, sizeof(buffer) - len, "<span style='color: red;'>%s </span> %s<br>",
						translate("gettextFromC", "Warning:"), temp);
			}
		}
		dp = dp->next;
	}
	snprintf(buffer + len, sizeof(buffer) - len, "</div>");
	dive->notes = strdup(buffer);
}
示例#26
0
void put_duration(struct membuffer *b, duration_t duration, const char *pre, const char *post)
{
	if (duration.seconds)
		put_format(b, "%s%u:%02u%s", pre, FRACTION(duration.seconds, 60), post);
}
示例#27
0
static void show_duration(FILE *f, duration_t duration, const char *pre, const char *post)
{
	if (duration.seconds)
		fprintf(f, "%s%u:%02u min%s", pre, FRACTION(duration.seconds, 60), post);
}
示例#28
0
static void save_sample(struct membuffer *b, struct sample *sample, struct sample *old)
{
	put_format(b, "  <sample time='%u:%02u min'", FRACTION(sample->time.seconds, 60));
	put_milli(b, " depth='", sample->depth.mm, " m'");
	if (sample->temperature.mkelvin && sample->temperature.mkelvin != old->temperature.mkelvin) {
		put_temperature(b, sample->temperature, " temp='", " C'");
		old->temperature = sample->temperature;
	}
	put_pressure(b, sample->cylinderpressure, " pressure='", " bar'");
	put_pressure(b, sample->o2cylinderpressure, " o2pressure='", " bar'");

	/*
	 * We only show sensor information for samples with pressure, and only if it
	 * changed from the previous sensor we showed.
	 */
	if (sample->cylinderpressure.mbar && sample->sensor != old->sensor) {
		put_format(b, " sensor='%d'", sample->sensor);
		old->sensor = sample->sensor;
	}

	/* the deco/ndl values are stored whenever they change */
	if (sample->ndl.seconds != old->ndl.seconds) {
		put_format(b, " ndl='%u:%02u min'", FRACTION(sample->ndl.seconds, 60));
		old->ndl = sample->ndl;
	}
	if (sample->tts.seconds != old->tts.seconds) {
		put_format(b, " tts='%u:%02u min'", FRACTION(sample->tts.seconds, 60));
		old->tts = sample->tts;
	}
	if (sample->rbt.seconds)
		put_format(b, " rbt='%u:%02u min'", FRACTION(sample->rbt.seconds, 60));
	if (sample->in_deco != old->in_deco) {
		put_format(b, " in_deco='%d'", sample->in_deco ? 1 : 0);
		old->in_deco = sample->in_deco;
	}
	if (sample->stoptime.seconds != old->stoptime.seconds) {
		put_format(b, " stoptime='%u:%02u min'", FRACTION(sample->stoptime.seconds, 60));
		old->stoptime = sample->stoptime;
	}

	if (sample->stopdepth.mm != old->stopdepth.mm) {
		put_milli(b, " stopdepth='", sample->stopdepth.mm, " m'");
		old->stopdepth = sample->stopdepth;
	}

	if (sample->cns != old->cns) {
		put_format(b, " cns='%u%%'", sample->cns);
		old->cns = sample->cns;
	}

	if ((sample->o2sensor[0].mbar) && (sample->o2sensor[0].mbar != old->o2sensor[0].mbar)) {
		put_milli(b, " sensor1='", sample->o2sensor[0].mbar, " bar'");
		old->o2sensor[0] = sample->o2sensor[0];
	}

	if ((sample->o2sensor[1].mbar) && (sample->o2sensor[1].mbar != old->o2sensor[1].mbar)) {
		put_milli(b, " sensor2='", sample->o2sensor[1].mbar, " bar'");
		old->o2sensor[1] = sample->o2sensor[1];
	}

	if ((sample->o2sensor[2].mbar) && (sample->o2sensor[2].mbar != old->o2sensor[2].mbar)) {
		put_milli(b, " sensor3='", sample->o2sensor[2].mbar, " bar'");
		old->o2sensor[2] = sample->o2sensor[2];
	}

	if (sample->setpoint.mbar != old->setpoint.mbar) {
		put_milli(b, " po2='", sample->setpoint.mbar, " bar'");
		old->setpoint = sample->setpoint;
	}
	show_index(b, sample->heartbeat, "heartbeat='", "'");
	show_index(b, sample->bearing.degrees, "bearing='", "'");
	put_format(b, " />\n");
}
示例#29
0
static char * get_minutes(int seconds)
{
    static char buf[80];
    snprintf(buf, sizeof(buf), "%d:%.2d", FRACTION(seconds, 60));
    return buf;
}
示例#30
0
static void plot_string(struct plot_info *pi, struct plot_data *entry, struct membuffer *b, bool has_ndl)
{
	int pressurevalue, mod, ead, end, eadd;
	const char *depth_unit, *pressure_unit, *temp_unit, *vertical_speed_unit;
	double depthvalue, tempvalue, speedvalue, sacvalue;
	int decimals;
	const char *unit;

	depthvalue = get_depth_units(entry->depth, NULL, &depth_unit);
	put_format(b, translate("gettextFromC", "@: %d:%02d\nD: %.1f%s\n"), FRACTION(entry->sec, 60), depthvalue, depth_unit);
	if (GET_PRESSURE(entry)) {
		pressurevalue = get_pressure_units(GET_PRESSURE(entry), &pressure_unit);
		put_format(b, translate("gettextFromC", "P: %d%s\n"), pressurevalue, pressure_unit);
	}
	if (entry->temperature) {
		tempvalue = get_temp_units(entry->temperature, &temp_unit);
		put_format(b, translate("gettextFromC", "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(b, translate("gettextFromC", "V: %.1f%s\n"), speedvalue, vertical_speed_unit);
	sacvalue = get_volume_units(entry->sac, &decimals, &unit);
	if (entry->sac && prefs.show_sac)
		put_format(b, translate("gettextFromC", "SAC: %.*f%s/min\n"), decimals, sacvalue, unit);
	if (entry->cns)
		put_format(b, translate("gettextFromC", "CNS: %u%%\n"), entry->cns);
	if (prefs.pp_graphs.po2)
		put_format(b, translate("gettextFromC", "pO%s: %.2fbar\n"), UTF8_SUBSCRIPT_2, entry->pressures.o2);
	if (prefs.pp_graphs.pn2)
		put_format(b, translate("gettextFromC", "pN%s: %.2fbar\n"), UTF8_SUBSCRIPT_2, entry->pressures.n2);
	if (prefs.pp_graphs.phe)
		put_format(b, translate("gettextFromC", "pHe: %.2fbar\n"), entry->pressures.he);
	if (prefs.mod) {
		mod = (int)get_depth_units(entry->mod, NULL, &depth_unit);
		put_format(b, translate("gettextFromC", "MOD: %d%s\n"), mod, depth_unit);
	}
	eadd = (int)get_depth_units(entry->eadd, NULL, &depth_unit);
	if (prefs.ead) {
		switch (pi->dive_type) {
		case NITROX:
			ead = (int)get_depth_units(entry->ead, NULL, &depth_unit);
			put_format(b, translate("gettextFromC", "EAD: %d%s\nEADD: %d%s\n"), ead, depth_unit, eadd, depth_unit);
			break;
		case TRIMIX:
			end = (int)get_depth_units(entry->end, NULL, &depth_unit);
			put_format(b, translate("gettextFromC", "END: %d%s\nEADD: %d%s\n"), end, depth_unit, eadd, depth_unit);
			break;
		case AIR:
		case FREEDIVING:
			/* nothing */
			break;
		}
	}
	if (entry->stopdepth) {
		depthvalue = get_depth_units(entry->stopdepth, NULL, &depth_unit);
		if (entry->ndl) {
			/* this is a safety stop as we still have ndl */
			if (entry->stoptime)
				put_format(b, translate("gettextFromC", "Safetystop: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60),
					   depthvalue, depth_unit);
			else
				put_format(b, translate("gettextFromC", "Safetystop: unkn time @ %.0f%s\n"),
					   depthvalue, depth_unit);
		} else {
			/* actual deco stop */
			if (entry->stoptime)
				put_format(b, translate("gettextFromC", "Deco: %umin @ %.0f%s\n"), DIV_UP(entry->stoptime, 60),
					   depthvalue, depth_unit);
			else
				put_format(b, translate("gettextFromC", "Deco: unkn time @ %.0f%s\n"),
					   depthvalue, depth_unit);
		}
	} else if (entry->in_deco) {
		put_string(b, translate("gettextFromC", "In deco\n"));
	} else if (has_ndl) {
		put_format(b, translate("gettextFromC", "NDL: %umin\n"), DIV_UP(entry->ndl, 60));
	}
	if (entry->tts)
		put_format(b, translate("gettextFromC", "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(b, translate("gettextFromC", "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,
		 * and we have no deco stop,
		 * 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"));
	} else if (prefs.calcndltts && entry->ndl_calc != 0) {
		if(entry->ndl_calc < MAX_PROFILE_DECO)
			put_format(b, translate("gettextFromC", "NDL: %umin (calc)\n"), DIV_UP(entry->ndl_calc, 60));
		else
			put_format(b, "%s", translate("gettextFromC", "NDL: >2h (calc)\n"));
	}
	if (entry->tts_calc) {
		if (entry->tts_calc < MAX_PROFILE_DECO)
			put_format(b, translate("gettextFromC", "TTS: %umin (calc)\n"), DIV_UP(entry->tts_calc, 60));
		else
			put_format(b, "%s", translate("gettextFromC", "TTS: >2h (calc)\n"));
	}
	if (entry->rbt)
		put_format(b, translate("gettextFromC", "RBT: %umin\n"), DIV_UP(entry->rbt, 60));
	if (entry->ceiling) {
		depthvalue = get_depth_units(entry->ceiling, NULL, &depth_unit);
		put_format(b, translate("gettextFromC", "Calculated ceiling %.0f%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(b, translate("gettextFromC", "Tissue %.0fmin: %.1f%s\n"), buehlmann_N2_t_halflife[k], depthvalue, depth_unit);
				}
			}
		}
	}
	if (entry->heartbeat && prefs.hrgraph)
		put_format(b, translate("gettextFromC", "heartbeat: %d\n"), entry->heartbeat);
	if (entry->bearing)
		put_format(b, translate("gettextFromC", "bearing: %d\n"), entry->bearing);
	if (entry->running_sum) {
		depthvalue = get_depth_units(entry->running_sum / entry->sec, NULL, &depth_unit);
		put_format(b, translate("gettextFromC", "mean depth to here %.1f%s\n"), depthvalue, depth_unit);
	}

	strip_mb(b);
}