]> git.tdb.fi Git - ext/subsurface.git/blobdiff - profile.c
Don't test for liquid Helium
[ext/subsurface.git] / profile.c
index a7ea885a1200bcbaa42dcddae915565665bdd01f..e5d8aa9b9065d5cc335e9a74413da3bd2eae1aae 100644 (file)
--- a/profile.c
+++ b/profile.c
@@ -96,6 +96,24 @@ void set_source_rgb(struct graphics_context *gc, double r, double g, double b)
 
 #define ROUND_UP(x,y) ((((x)+(y)-1)/(y))*(y))
 
+/* debugging tool - not normally used */
+static void dump_pi (struct plot_info *pi)
+{
+       int i;
+
+       printf("pi:{nr:%d maxtime:%d meandepth:%d maxdepth:%d \n"
+               "    minpressure:%d maxpressure:%d endpressure:%d mintemp:%d maxtemp:%d\n",
+               pi->nr, pi->maxtime, pi->meandepth, pi->maxdepth,
+               pi->minpressure, pi->maxpressure, pi->endpressure, pi->mintemp, pi->maxtemp);
+       for (i = 0; i < pi->nr; i++)
+               printf("    entry[%d]:{same_cylinder:%d cylinderindex:%d sec:%d pressure:{%d,%d}\n"
+                       "                temperature:%d depth:%d smoothed:%d}\n",
+                       i, pi->entry[i].same_cylinder, pi->entry[i].cylinderindex, pi->entry[i].sec,
+                       pi->entry[i].pressure[0], pi->entry[i].pressure[1],
+                       pi->entry[i].temperature, pi->entry[i].depth, pi->entry[i].smoothed);
+       printf("   }\n");
+}
+
 /*
  * When showing dive profiles, we scale things to the
  * current dive. However, we don't scale past less than
@@ -276,6 +294,7 @@ static void plot_text_samples(struct graphics_context *gc, struct plot_info *pi)
        static const text_render_options_t deep = {14, 1.0, 0.2, 0.2, CENTER, TOP};
        static const text_render_options_t shallow = {14, 1.0, 0.2, 0.2, CENTER, BOTTOM};
        int i;
+       int last = -1;
 
        for (i = 0; i < pi->nr; i++) {
                struct plot_data *entry = pi->entry + i;
@@ -283,11 +302,18 @@ static void plot_text_samples(struct graphics_context *gc, struct plot_info *pi)
                if (entry->depth < 2000)
                        continue;
 
-               if (entry == entry->max[2])
+               if ((entry == entry->max[2]) && entry->depth != last) {
                        render_depth_sample(gc, entry, &deep);
+                       last = entry->depth;
+               }
 
-               if (entry == entry->min[2])
+               if ((entry == entry->min[2]) && entry->depth != last) {
                        render_depth_sample(gc, entry, &shallow);
+                       last = entry->depth;
+               }
+
+               if (entry->depth != last)
+                       last = -1;
        }
 }
 
@@ -485,19 +511,13 @@ static int setup_temperature_limits(struct graphics_context *gc, struct plot_inf
 
 static void plot_single_temp_text(struct graphics_context *gc, int sec, int mkelvin)
 {
-       int deg;
+       double deg;
        const char *unit;
        static const text_render_options_t tro = {12, 0.2, 0.2, 1.0, LEFT, TOP};
-       temperature_t temperature = { mkelvin };
 
-       if (output_units.temperature == FAHRENHEIT) {
-               deg = to_F(temperature);
-               unit = UTF8_DEGREE "F";
-       } else {
-               deg = to_C(temperature);
-               unit = UTF8_DEGREE "C";
-       }
-       plot_text(gc, &tro, sec, temperature.mkelvin, "%d%s", deg, unit);
+       deg = get_temp_units(mkelvin, &unit);
+
+       plot_text(gc, &tro, sec, mkelvin, "%d%s", (int)(deg + 0.5), unit);
 }
 
 static void plot_temperature_text(struct graphics_context *gc, struct plot_info *pi)
@@ -617,32 +637,13 @@ static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info
        plot_pressure_helper(gc, pi, INTERPOLATED_PR);
 }
 
-static int mbar_to_PSI(int mbar)
-{
-       pressure_t p = {mbar};
-       return to_PSI(p);
-}
-
 static void plot_pressure_value(struct graphics_context *gc, int mbar, int sec,
                                int xalign, int yalign)
 {
        int pressure;
        const char *unit;
 
-       switch (output_units.pressure) {
-       case PASCAL:
-               pressure = mbar * 100;
-               unit = "pascal";
-               break;
-       case BAR:
-               pressure = (mbar + 500) / 1000;
-               unit = "bar";
-               break;
-       case PSI:
-               pressure = mbar_to_PSI(mbar);
-               unit = "psi";
-               break;
-       }
+       pressure = get_pressure_units(mbar, &unit);
        text_render_options_t tro = {10, 0.2, 1.0, 0.2, xalign, yalign};
        plot_text(gc, &tro, sec, mbar, "%d %s", pressure, unit);
 }
@@ -995,6 +996,19 @@ static void check_gas_change_events(struct dive *dive, struct plot_info *pi)
        set_cylinder_index(pi, i, cylinderindex, ~0u);
 }
 
+/* for computers that track gas changes through events */
+static int count_gas_change_events(struct dive *dive)
+{
+       int count = 0;
+       struct event *ev = get_next_gaschange(dive->events);
+
+       while (ev) {
+               count++;
+               ev = get_next_gaschange(ev->next);
+       }
+       return count;
+}
+
 /*
  * Create a plot-info with smoothing and ranged min/max
  *
@@ -1006,41 +1020,96 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
 {
        int cylinderindex = -1;
        int lastdepth, lastindex;
-       int i, nr = nr_samples + 4, sec, cyl;
-       size_t alloc_size = plot_info_size(nr);
+       int i, pi_idx, nr, sec, cyl;
+       size_t alloc_size;
        struct plot_info *pi;
        pr_track_t *track_pr[MAX_CYLINDERS] = {NULL, };
        pr_track_t *pr_track, *current;
        gboolean missing_pr = FALSE;
        struct plot_data *entry = NULL;
+       struct event *ev;
 
+       /* we want to potentially add synthetic plot_info elements for the gas changes */
+       nr = nr_samples + 4 + 2 * count_gas_change_events(dive);
+       alloc_size = plot_info_size(nr);
        pi = malloc(alloc_size);
        if (!pi)
                return pi;
        memset(pi, 0, alloc_size);
        pi->nr = nr;
+       pi_idx = 2; /* the two extra events at the start */
+       /* check for gas changes before the samples start */
+       ev = get_next_gaschange(dive->events);
+       while (ev && ev->time.seconds < dive_sample->time.seconds) {
+               entry = pi->entry + pi_idx;
+               entry->sec = ev->time.seconds;
+               entry->depth = 0; /* is that always correct ? */
+               pi_idx++;
+               ev = get_next_gaschange(ev->next);
+       }
+       if (ev && ev->time.seconds == dive_sample->time.seconds) {
+               /* we already have a sample at the time of the event */
+               ev = get_next_gaschange(ev->next);
+       }
        sec = 0;
        lastindex = 0;
        lastdepth = -1;
        for (i = 0; i < nr_samples; i++) {
                int depth;
+               int delay = 0;
                struct sample *sample = dive_sample+i;
 
-               entry = pi->entry + i + 2;
-               sec = entry->sec = sample->time.seconds;
+               entry = pi->entry + i + pi_idx;
+               while (ev && ev->time.seconds < sample->time.seconds) {
+                       /* insert two fake plot info structures for the end of
+                        * the old tank and the start of the new tank */
+                       entry->sec = ev->time.seconds;
+                       (entry+1)->sec = ev->time.seconds + 1;
+                       /* we need a fake depth - let's interpolate */
+                       if (i) {
+                               entry->depth = sample->depth.mm -
+                                       (sample->depth.mm - (sample-1)->depth.mm) / 2;
+                       } else
+                               entry->depth = sample->depth.mm;
+                       (entry+1)->depth = entry->depth;
+                       pi_idx += 2;
+                       entry = pi->entry + i + pi_idx;
+                       ev = get_next_gaschange(ev->next);
+               }
+               if (ev && ev->time.seconds == sample->time.seconds) {
+                       /* we already have a sample at the time of the event
+                        * just add a new one for the old tank and delay the
+                        * real even by one second (to keep time monotonous) */
+                       entry->sec = ev->time.seconds;
+                       entry->depth = sample->depth.mm;
+                       pi_idx++;
+                       entry = pi->entry + i + pi_idx;
+                       ev = get_next_gaschange(ev->next);
+                       delay = 1;
+               }
+               sec = entry->sec = sample->time.seconds + delay;
                depth = entry->depth = sample->depth.mm;
                entry->cylinderindex = sample->cylinderindex;
                SENSOR_PRESSURE(entry) = sample->cylinderpressure.mbar;
                entry->temperature = sample->temperature.mkelvin;
 
                if (depth || lastdepth)
-                       lastindex = i+2;
+                       lastindex = i+pi_idx;
 
                lastdepth = depth;
                if (depth > pi->maxdepth)
                        pi->maxdepth = depth;
        }
-
+       entry = pi->entry + i + pi_idx;
+       /* are there still unprocessed gas changes? that would be very strange */
+       while (ev) {
+               entry->sec = ev->time.seconds;
+               entry->depth = 0; /* why are there gas changes after the dive is over? */
+               pi_idx++;
+               entry = pi->entry + i + pi_idx;
+               ev = get_next_gaschange(ev->next);
+       }
+       nr_samples += pi_idx - 2;
        check_gas_change_events(dive, pi);
 
        for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) /* initialize the start pressures */
@@ -1089,6 +1158,8 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
        i = nr_samples + 2;
        pi->entry[i].sec = sec + 20;
        pi->entry[i+1].sec = sec + 40;
+       /* the number of actual entries - we may have allocated more if there
+        * were gas change events, but this is how many were filled */
        pi->nr = lastindex+1;
        pi->maxtime = pi->entry[lastindex].sec;
 
@@ -1102,6 +1173,8 @@ static struct plot_info *create_plot_info(struct dive *dive, int nr_samples, str
        }
        for (cyl = 0; cyl < MAX_CYLINDERS; cyl++)
                list_free(track_pr[cyl]);
+       if (0) /* awesome for debugging - not useful otherwise */
+               dump_pi(pi);
        return analyze_plot_info(pi);
 }