diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2020-04-27 21:12:24 +0200 |
---|---|---|
committer | Robert C. Helling <helling@atdotde.de> | 2020-05-01 12:36:28 +0200 |
commit | ffc3e598faa5d986d78e9a275c48193a3a835cfe (patch) | |
tree | 33430b39d93cf0f96cdb6eca09c7d12ab182e648 /core | |
parent | b949bad026c8bab7611998fb0fcf9f6008dbd7e9 (diff) | |
download | subsurface-ffc3e598faa5d986d78e9a275c48193a3a835cfe.tar.gz |
core: create fake cylinder at end of cylinder table (hack!)
When we had fixed-sized cylinder arrays, the planner used the last
empty cylinder for "surface air". This was not recognized by the UI
as a separate cylinder, because "empty cylinder" was the sentinel for
the end of the table. The conversion to dynamically sized cylinder
tables broke this code: everytime the surface segment is changed,
a new dummy cylinder is added, which is visible in the UI.
As a very temporary stop-gap fix, emulate the old code by creating
a cylinder and then setting the end-of-table to before that cylinder.
This means that we have to loosen the out-of-bound checks.
That's all very scary and should be removed as soon as possible.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core')
-rw-r--r-- | core/dive.c | 5 | ||||
-rw-r--r-- | core/equipment.c | 5 | ||||
-rw-r--r-- | core/planner.c | 18 |
3 files changed, 19 insertions, 9 deletions
diff --git a/core/dive.c b/core/dive.c index 89e090165..b4fa22d24 100644 --- a/core/dive.c +++ b/core/dive.c @@ -227,7 +227,10 @@ struct event *add_event(struct divecomputer *dc, unsigned int time, int type, in void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx) { /* sanity check so we don't crash */ - if (idx < 0 || idx >= dive->cylinders.nr) { + /* FIXME: The planner uses a dummy cylinder one past the official number of cylinders + * in the table to mark no-cylinder surface interavals. This is horrendous. Fix ASAP. */ + //if (idx < 0 || idx >= dive->cylinders.nr) { + if (idx < 0 || idx >= dive->cylinders.nr + 1 || idx >= dive->cylinders.allocated) { report_error("Unknown cylinder index: %d", idx); return; } diff --git a/core/equipment.c b/core/equipment.c index 8d169d8d2..a5acb776d 100644 --- a/core/equipment.c +++ b/core/equipment.c @@ -368,7 +368,10 @@ cylinder_t *add_empty_cylinder(struct cylinder_table *t) */ cylinder_t *get_cylinder(const struct dive *d, int idx) { - if (idx < 0 || idx >= d->cylinders.nr) { + /* FIXME: The planner uses a dummy cylinder one past the official number of cylinders + * in the table to mark no-cylinder surface interavals. This is horrendous. Fix ASAP. */ + // if (idx < 0 || idx >= d->cylinders.nr) { + if (idx < 0 || idx >= d->cylinders.nr + 1 || idx >= d->cylinders.allocated) { fprintf(stderr, "Warning: accessing invalid cylinder %d (%d existing)\n", idx, d->cylinders.nr); return NULL; } diff --git a/core/planner.c b/core/planner.c index 8cadaca01..f4fb9ee80 100644 --- a/core/planner.c +++ b/core/planner.c @@ -272,7 +272,11 @@ static void create_dive_from_plan(struct diveplan *diveplan, struct dive *dive, if (dp->cylinderid != lastcylid) { /* need to insert a first sample for the new gas */ add_gas_switch_event(dive, dc, lasttime + 1, dp->cylinderid); - cyl = get_or_create_cylinder(dive, dp->cylinderid); + cyl = get_cylinder(dive, dp->cylinderid); // FIXME: This actually may get one past the last cylinder for "surface air". + if (!cyl) { + report_error("Invalid cylinder in create_dive_from_plan(): %d", dp->cylinderid); + continue; + } sample = prepare_sample(dc); sample[-1].setpoint.mbar = po2; sample->time.seconds = lasttime + 1; @@ -1070,12 +1074,12 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i } if (prefs.surface_segment != 0) { - // Switch to an empty air cylinder for breathing air at the surface - // If no empty cylinder is found, keep using last deco gas - cylinder_t cyl = empty_cylinder; - cyl.cylinder_use = NOT_USED; - add_cylinder(&dive->cylinders, dive->cylinders.nr, cyl); - current_cylinder = dive->cylinders.nr - 1; + // Switch to an empty air cylinder for breathing air at the surface. + // FIXME: This is incredibly silly and emulates the old code when + // we had a fixed cylinder table: It uses an extra fake cylinder + // past the regular cylinder table, which is not visible to the UI. + // Fix this as soon as possible! + current_cylinder = dive->cylinders.nr; plan_add_segment(diveplan, prefs.surface_segment, 0, current_cylinder, 0, false, OC); } create_dive_from_plan(diveplan, dive, is_planner); |