bool DivePlannerPointsModel::addGas(struct gasmix mix) { sanitize_gasmix(&mix); for (int i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = &displayed_dive.cylinder[i]; if (cylinder_nodata(cyl)) { fill_default_cylinder(cyl); cyl->gasmix = mix; /* The depth to change to that gas is given by the depth where its pO₂ is 1.6 bar. * The user should be able to change this depth manually. */ pressure_t modpO2; modpO2.mbar = prefs.decopo2; cyl->depth = gas_mod(&mix, modpO2, M_OR_FT(3,10)); // FIXME -- need to get rid of stagingDIve // the following now uses displayed_dive !!!! CylindersModel::instance()->updateDive(); return true; } if (!gasmix_distance(&cyl->gasmix, &mix)) return true; } qDebug("too many gases"); return false; }
QVector<QPair<int, int> > DivePlannerPointsModel::collectGases(struct dive *d) { QVector<QPair<int, int> > l; for (int i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = &d->cylinder[i]; if (!cylinder_nodata(cyl)) l.push_back(qMakePair(get_o2(&cyl->gasmix), get_he(&cyl->gasmix))); } return l; }
static int nr_cylinders(struct dive *dive) { int nr; for (nr = MAX_CYLINDERS; nr; --nr) { cylinder_t *cylinder = dive->cylinder+nr-1; if (!cylinder_nodata(cylinder)) break; } return nr; }
QStringList &DivePlannerPointsModel::getGasList() { static QStringList list; list.clear(); for (int i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = &displayed_dive.cylinder[i]; if (cylinder_nodata(cyl)) break; list.push_back(get_gas_string(cyl->gasmix)); } return list; }
/* if a default cylinder is set, use that */ void fill_default_cylinder(cylinder_t *cyl) { const char *cyl_name = prefs.default_cylinder; struct tank_info_t *ti = tank_info; pressure_t pO2 = {.mbar = 1600}; if (!cyl_name) return; while (ti->name != NULL) { if (strcmp(ti->name, cyl_name) == 0) break; ti++; } if (ti->name == NULL) /* didn't find it */ return; cyl->type.description = strdup(ti->name); if (ti->ml) { cyl->type.size.mliter = ti->ml; cyl->type.workingpressure.mbar = ti->bar * 1000; } else { cyl->type.workingpressure.mbar = psi_to_mbar(ti->psi); if (ti->psi) cyl->type.size.mliter = cuft_to_l(ti->cuft) * 1000 / bar_to_atm(psi_to_bar(ti->psi)); } // MOD of air cyl->depth = gas_mod(&cyl->gasmix, pO2, 1); } /* make sure that the gas we are switching to is represented in our * list of cylinders */ static int verify_gas_exists(struct gasmix mix_in) { int i; cylinder_t *cyl; for (i = 0; i < MAX_CYLINDERS; i++) { cyl = displayed_dive.cylinder + i; if (cylinder_nodata(cyl)) continue; if (gasmix_distance(&cyl->gasmix, &mix_in) < 200) return i; } fprintf(stderr, "this gas %s should have been on the cylinder list\nThings will fail now\n", gasname(&mix_in)); return -1; }
/* * If the event has an explicit cylinder index, * we return that. If it doesn't, we return the best * match based on the gasmix. * * Some dive computers give cylinder indexes, some * give just the gas mix. */ int get_cylinder_index(struct dive *dive, struct event *ev) { int i; int best = 0, score = INT_MAX; int target_o2, target_he; struct gasmix *g; if (ev->gas.index >= 0) return ev->gas.index; g = get_gasmix_from_event(ev); target_o2 = get_o2(g); target_he = get_he(g); /* * Try to find a cylinder that best matches the target gas * mix. */ for (i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = dive->cylinder + i; int delta_o2, delta_he, distance; if (cylinder_nodata(cyl)) continue; delta_o2 = get_o2(&cyl->gasmix) - target_o2; delta_he = get_he(&cyl->gasmix) - target_he; distance = delta_o2 * delta_o2; distance += delta_he * delta_he; if (distance >= score) continue; score = distance; best = i; } return best; }
bool cylinder_none(void *_data) { cylinder_t *cyl = _data; return cylinder_nodata(cyl) && cylinder_nosamples(cyl); }