diff options
-rw-r--r-- | dive.c | 14 | ||||
-rw-r--r-- | dive.h | 3 | ||||
-rw-r--r-- | divelist.c | 22 | ||||
-rw-r--r-- | libdivecomputer.c | 2 | ||||
-rw-r--r-- | parse-xml.c | 40 | ||||
-rw-r--r-- | profile.c | 3 | ||||
-rw-r--r-- | save-xml.c | 47 | ||||
-rw-r--r-- | uemis.c | 7 |
8 files changed, 111 insertions, 27 deletions
@@ -237,7 +237,9 @@ static void fixup_pressure(struct dive *dive, struct sample *sample) pressure = sample->cylinderpressure.mbar; if (!pressure) return; - index = sample->cylinderindex; + index = sample->sensor; + + /* FIXME! sensor -> cylinder mapping? */ if (index >= MAX_CYLINDERS) return; cyl = dive->cylinder + index; @@ -427,7 +429,7 @@ struct dive *fixup_dive(struct dive *dive) int depth = sample->depth.mm; int temp = sample->temperature.mkelvin; int pressure = sample->cylinderpressure.mbar; - int index = sample->cylinderindex; + int index = sample->sensor; if (index == lastindex) { /* Remove duplicate redundant pressure information */ @@ -502,7 +504,7 @@ struct dive *fixup_dive(struct dive *dive) if (abs(pressure_delta[j]) != INT_MAX) { cylinder_t *cyl = dive->cylinder + j; for (i = 0; i < dc->samples; i++) - if (dc->sample[i].cylinderindex == j) + if (dc->sample[i].sensor == j) dc->sample[i].cylinderpressure.mbar = 0; if (! cyl->start.mbar) cyl->start.mbar = cyl->sample_start.mbar; @@ -709,8 +711,8 @@ add_sample_b: sample.temperature = as->temperature; if (as->cylinderpressure.mbar) sample.cylinderpressure = as->cylinderpressure; - if (as->cylinderindex) - sample.cylinderindex = as->cylinderindex; + if (as->sensor) + sample.sensor = as->sensor; if (as->cns) sample.cns = as->cns; if (as->po2) @@ -1291,7 +1293,7 @@ static int same_sample(struct sample *a, struct sample *b) return 0; if (a->cylinderpressure.mbar != b->cylinderpressure.mbar) return 0; - return a->cylinderindex == b->cylinderindex; + return a->sensor == b->sensor; } static int same_dc(struct divecomputer *a, struct divecomputer *b) @@ -226,7 +226,7 @@ struct sample { depth_t depth; temperature_t temperature; pressure_t cylinderpressure; - int cylinderindex; + int sensor; /* Cylinder pressure sensor index */ duration_t ndl; duration_t stoptime; depth_t stopdepth; @@ -503,6 +503,7 @@ extern struct dive *try_to_merge(struct dive *a, struct dive *b, gboolean prefer extern void renumber_dives(int nr); +extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx); extern void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name); /* UI related protopypes */ diff --git a/divelist.c b/divelist.c index 316c4d547..2a6829e27 100644 --- a/divelist.c +++ b/divelist.c @@ -715,6 +715,24 @@ static void cns_data_func(GtkTreeViewColumn *col, g_object_set(renderer, "text", buffer, NULL); } +static int active_o2(struct dive *dive, struct divecomputer *dc, duration_t time) +{ + int o2permille = dive->cylinder[0].gasmix.o2.permille; + struct event *event = dc->events; + + if (!o2permille) + o2permille = AIR_PERMILLE; + + for (event = dc->events; event; event = event->next) { + if (event->time.seconds > time.seconds) + break; + if (strcmp(event->name, "gaschange")) + continue; + o2permille = 10*(event->value & 0xffff); + } + return o2permille; +} + /* calculate OTU for a dive */ static int calculate_otu(struct dive *dive, struct divecomputer *dc) { @@ -730,9 +748,7 @@ static int calculate_otu(struct dive *dive, struct divecomputer *dc) if (sample->po2) { po2 = sample->po2; } else { - int o2 = dive->cylinder[sample->cylinderindex].gasmix.o2.permille; - if (!o2) - o2 = AIR_PERMILLE; + int o2 = active_o2(dive, dc, sample->time); po2 = o2 / 1000.0 * depth_to_mbar(sample->depth.mm, dive) / 1000.0; } if (po2 >= 0.5) diff --git a/libdivecomputer.c b/libdivecomputer.c index 6e01ee3a5..47c7b6367 100644 --- a/libdivecomputer.c +++ b/libdivecomputer.c @@ -209,7 +209,7 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata) sample->depth.mm = value.depth * 1000 + 0.5; break; case DC_SAMPLE_PRESSURE: - sample->cylinderindex = value.pressure.tank; + sample->sensor = value.pressure.tank; sample->cylinderpressure.mbar = value.pressure.value * 1000 + 0.5; break; case DC_SAMPLE_TEMPERATURE: diff --git a/parse-xml.c b/parse-xml.c index 8232fb041..a256990b3 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -155,6 +155,7 @@ static gboolean in_settings = FALSE; static struct tm cur_tm; static int cur_cylinder_index, cur_ws_index; static int lastndl, laststoptime, laststopdepth, lastcns, lastpo2, lastindeco; +static int lastcylinderindex, lastsensor; static enum import_source { UNKNOWN, @@ -650,6 +651,39 @@ static void try_to_fill_dc(struct divecomputer *dc, const char *name, char *buf) nonmatch("divecomputer", name, buf); } +void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx) +{ + /* The gas switch event format is insane. It will be fixed, I think */ + int o2 = dive->cylinder[idx].gasmix.o2.permille; + int he = dive->cylinder[idx].gasmix.he.permille; + int value; + + if (!o2) + o2 = AIR_PERMILLE; + o2 = (o2+5) / 10; + he = (he+5) / 10; + value = o2 + (he << 16); + + add_event(dc, seconds, 11, 0, value, "gaschange"); +} + +static void get_cylinderindex(char *buffer, void *_i) +{ + int *i = _i; + *i = atoi(buffer); + if (lastcylinderindex != *i) { + add_gas_switch_event(cur_dive, cur_dc, cur_sample->time.seconds, *i); + lastcylinderindex = *i; + } +} + +static void get_sensor(char *buffer, void *_i) +{ + int *i = _i; + *i = atoi(buffer); + lastsensor = *i; +} + /* We're in samples - try to convert the random xml value to something useful */ static void try_to_fill_sample(struct sample *sample, const char *name, char *buf) { @@ -661,7 +695,9 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu return; if (MATCH(".sample.cylpress", pressure, &sample->cylinderpressure)) return; - if (MATCH(".sample.cylinderindex", get_index, &sample->cylinderindex)) + if (MATCH(".sample.cylinderindex", get_cylinderindex, &sample->sensor)) + return; + if (MATCH(".sample.sensor", get_sensor, &sample->sensor)) return; if (MATCH(".sample.depth", depth, &sample->depth)) return; @@ -1005,6 +1041,7 @@ static gboolean is_dive(void) static void reset_dc_info(struct divecomputer *dc) { lastcns = lastpo2 = lastndl = laststoptime = laststopdepth = lastindeco = 0; + lastsensor = lastcylinderindex = 0; } static void reset_dc_settings(void) @@ -1129,6 +1166,7 @@ static void sample_start(void) cur_sample->stopdepth.mm = laststopdepth; cur_sample->cns = lastcns; cur_sample->po2 = lastpo2; + cur_sample->sensor = lastsensor; } static void sample_end(void) @@ -1644,7 +1644,8 @@ static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer entry->in_deco = in_deco; entry->cns = cns; entry->po2 = po2; - entry->cylinderindex = sample->cylinderindex; + /* FIXME! sensor index -> cylinder index translation! */ + entry->cylinderindex = sample->sensor; SENSOR_PRESSURE(entry) = sample->cylinderpressure.mbar; entry->temperature = sample->temperature.mkelvin; diff --git a/save-xml.c b/save-xml.c index c85f66408..fe663f652 100644 --- a/save-xml.c +++ b/save-xml.c @@ -319,27 +319,50 @@ static void show_index(FILE *f, int value, const char *pre, const char *post) fprintf(f, " %s%d%s", pre, value, post); } -static void save_sample(FILE *f, struct sample *sample, const struct sample *prev) +static void save_sample(FILE *f, struct sample *sample, struct sample *old) { 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); + + /* + * 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) { + fprintf(f, " sensor='%d'", sample->sensor); + old->sensor = sample->sensor; + } + /* the deco/ndl values are stored whenever they change */ - if (sample->ndl.seconds != prev->ndl.seconds) + if (sample->ndl.seconds != old->ndl.seconds) { fprintf(f, " ndl='%u:%02u min'", FRACTION(sample->ndl.seconds, 60)); - if (sample->in_deco != prev->in_deco) + old->ndl = sample->ndl; + } + if (sample->in_deco != old->in_deco) { fprintf(f, " in_deco='%d'", sample->in_deco ? 1 : 0); - if (sample->stoptime.seconds != prev->stoptime.seconds) + old->in_deco = sample->in_deco; + } + if (sample->stoptime.seconds != old->stoptime.seconds) { fprintf(f, " stoptime='%u:%02u min'", FRACTION(sample->stoptime.seconds, 60)); - if (sample->stopdepth.mm != prev->stopdepth.mm) + old->stoptime = sample->stoptime; + } + + if (sample->stopdepth.mm != old->stopdepth.mm) { show_milli(f, " stopdepth='", sample->stopdepth.mm, " m", "'"); - if (sample->cns != prev->cns) + old->stopdepth = sample->stopdepth; + } + + if (sample->cns != old->cns) { fprintf(f, " cns='%u%%'", sample->cns); - if (sample->po2 != prev->po2) + old->cns = sample->cns; + } + + if (sample->po2 != old->po2) { fprintf(f, " po2='%u.%2u bar'", FRACTION(sample->po2, 1000)); + old->po2 = sample->po2; + } fprintf(f, " />\n"); } @@ -376,12 +399,10 @@ static void show_date(FILE *f, timestamp_t when) static void save_samples(FILE *f, int nr, struct sample *s) { - static const struct sample empty_sample; - const struct sample *prev = &empty_sample; + struct sample dummy = { }; while (--nr >= 0) { - save_sample(f, s, prev); - prev = s; + save_sample(f, s, &dummy); s++; } } @@ -291,6 +291,7 @@ void uemis_parse_divelog_binary(char *base64, void *datap) { struct dive *dive = datap; struct divecomputer *dc = &dive->dc; int template, gasoffset; + int active = 0; datalen = uemis_convert_base64(base64, &data); @@ -345,11 +346,15 @@ void uemis_parse_divelog_binary(char *base64, void *datap) { * duration in the header is a) in minutes and b) up to 3 minutes short */ if (u_sample->dive_time > dive->duration.seconds + 180) break; + if (u_sample->active_tank != active) { + active = u_sample->active_tank; + add_gas_switch_event(dive, dc, u_sample->dive_time, active); + } sample = prepare_sample(dc); sample->time.seconds = u_sample->dive_time; sample->depth.mm = rel_mbar_to_depth(u_sample->water_pressure, dive); sample->temperature.mkelvin = (u_sample->dive_temperature * 100) + 273150; - sample->cylinderindex = u_sample->active_tank; + sample->sensor = active; sample->cylinderpressure.mbar = (u_sample->tank_pressure_high * 256 + u_sample->tank_pressure_low) * 10; sample->cns = u_sample->cns; |