mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	Merge branch 'atdotde'
Signed-off-by: Dirk Hohndel <dirk@hohndel.org> Conflicts: qt-ui/diveplanner.cpp qt-ui/models.cpp
This commit is contained in:
		
						commit
						cfe865dd0c
					
				
					 4 changed files with 48 additions and 36 deletions
				
			
		
							
								
								
									
										4
									
								
								dive.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								dive.c
									
										
									
									
									
								
							|  | @ -520,7 +520,7 @@ static int same_rounded_pressure(pressure_t a, pressure_t b) | ||||||
| 	return abs(a.mbar - b.mbar) <= 500; | 	return abs(a.mbar - b.mbar) <= 500; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void sanitize_gasmix(struct gasmix *mix) | void sanitize_gasmix(struct gasmix *mix) | ||||||
| { | { | ||||||
| 	unsigned int o2, he; | 	unsigned int o2, he; | ||||||
| 
 | 
 | ||||||
|  | @ -1253,7 +1253,7 @@ static void merge_weightsystem_info(weightsystem_t *res, weightsystem_t *a, weig | ||||||
| 	*res = *a; | 	*res = *a; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int gasmix_distance(const struct gasmix *a, const struct gasmix *b) | int gasmix_distance(const struct gasmix *a, const struct gasmix *b) | ||||||
| { | { | ||||||
| 	int a_o2 = get_o2(a), b_o2 = get_o2(b); | 	int a_o2 = get_o2(a), b_o2 = get_o2(b); | ||||||
| 	int a_he = get_he(a), b_he = get_he(b); | 	int a_he = get_he(a), b_he = get_he(b); | ||||||
|  |  | ||||||
							
								
								
									
										3
									
								
								dive.h
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								dive.h
									
										
									
									
									
								
							|  | @ -91,6 +91,9 @@ static inline int get_he(const struct gasmix *mix) | ||||||
| 	return mix->he.permille; | 	return mix->he.permille; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | extern void sanitize_gasmix(struct gasmix *mix); | ||||||
|  | extern int gasmix_distance(const struct gasmix *a, const struct gasmix *b); | ||||||
|  | 
 | ||||||
| static inline bool is_air(int o2, int he) | static inline bool is_air(int o2, int he) | ||||||
| { | { | ||||||
| 	return (he == 0) && (o2 == 0 || ((o2 >= O2_IN_AIR - 1) && (o2 <= O2_IN_AIR + 1))); | 	return (he == 0) && (o2 == 0 || ((o2 >= O2_IN_AIR - 1) && (o2 <= O2_IN_AIR + 1))); | ||||||
|  |  | ||||||
							
								
								
									
										54
									
								
								planner.c
									
										
									
									
									
								
							
							
						
						
									
										54
									
								
								planner.c
									
										
									
									
									
								
							|  | @ -72,23 +72,19 @@ void get_gas_from_events(struct divecomputer *dc, int time, int *o2, int *he) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* simple helper function to compare two permille values with
 |  | ||||||
|  * (rounded) percent granularity */ |  | ||||||
| static inline bool match_percent(int a, int b) |  | ||||||
| { |  | ||||||
| 	return (a + 5) / 10 == (b + 5) / 10; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int get_gasidx(struct dive *dive, int o2, int he) | int get_gasidx(struct dive *dive, int o2, int he) | ||||||
| { | { | ||||||
| 	int gasidx = -1; | 	int gasidx = -1; | ||||||
|  | 	struct gasmix mix; | ||||||
|  | 
 | ||||||
|  | 	mix.o2.permille = o2; | ||||||
|  | 	mix.he.permille = he; | ||||||
| 
 | 
 | ||||||
| 	/* we treat air as 0/0 because it is special */ | 	/* we treat air as 0/0 because it is special */ | ||||||
| 	if (is_air(o2, he)) | 	//if (is_air(o2, he))
 | ||||||
| 		o2 = 0; | 	//	o2 = 0;
 | ||||||
| 	while (++gasidx < MAX_CYLINDERS) | 	while (++gasidx < MAX_CYLINDERS) | ||||||
| 		if (match_percent(dive->cylinder[gasidx].gasmix.o2.permille, o2) && | 		if (gasmix_distance(&dive->cylinder[gasidx].gasmix, &mix) < 200) | ||||||
| 		    match_percent(dive->cylinder[gasidx].gasmix.he.permille, he)) |  | ||||||
| 			return gasidx; | 			return gasidx; | ||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  | @ -138,8 +134,8 @@ double tissue_at_end(struct dive *dive, char **cached_datap) | ||||||
| 	psample = sample = dc->sample; | 	psample = sample = dc->sample; | ||||||
| 	lastdepth = t0 = 0; | 	lastdepth = t0 = 0; | ||||||
| 	/* we always start with gas 0 (unless an event tells us otherwise) */ | 	/* we always start with gas 0 (unless an event tells us otherwise) */ | ||||||
| 	o2 = dive->cylinder[0].gasmix.o2.permille; | 	o2 = get_o2(&dive->cylinder[0].gasmix); | ||||||
| 	he = dive->cylinder[0].gasmix.he.permille; | 	he = get_he(&dive->cylinder[0].gasmix); | ||||||
| 	for (i = 0; i < dc->samples; i++, sample++) { | 	for (i = 0; i < dc->samples; i++, sample++) { | ||||||
| 		t1 = sample->time.seconds; | 		t1 = sample->time.seconds; | ||||||
| 		get_gas_from_events(&dive->dc, t0, &o2, &he); | 		get_gas_from_events(&dive->dc, t0, &o2, &he); | ||||||
|  | @ -189,14 +185,17 @@ static int add_gas(struct dive *dive, int o2, int he) | ||||||
| { | { | ||||||
| 	int i; | 	int i; | ||||||
| 	struct gasmix *mix; | 	struct gasmix *mix; | ||||||
|  | 	struct gasmix mix_in; | ||||||
| 	cylinder_t *cyl; | 	cylinder_t *cyl; | ||||||
| 
 | 
 | ||||||
|  | 	mix_in.o2.permille = o2; | ||||||
|  | 	mix_in.he.permille = he; | ||||||
| 	for (i = 0; i < MAX_CYLINDERS; i++) { | 	for (i = 0; i < MAX_CYLINDERS; i++) { | ||||||
| 		cyl = dive->cylinder + i; | 		cyl = dive->cylinder + i; | ||||||
| 		mix = &cyl->gasmix; | 		mix = &cyl->gasmix; | ||||||
| 		if (cylinder_nodata(cyl)) | 		if (cylinder_nodata(cyl)) | ||||||
| 			break; | 			break; | ||||||
| 		if (match_percent(o2, mix->o2.permille) && match_percent(he, mix->he.permille)) | 		if (gasmix_distance(mix, &mix_in) < 200) | ||||||
| 			return i; | 			return i; | ||||||
| 	} | 	} | ||||||
| 	if (i == MAX_CYLINDERS) { | 	if (i == MAX_CYLINDERS) { | ||||||
|  | @ -206,6 +205,7 @@ static int add_gas(struct dive *dive, int o2, int he) | ||||||
| 	fill_default_cylinder(cyl); | 	fill_default_cylinder(cyl); | ||||||
| 	mix->o2.permille = o2; | 	mix->o2.permille = o2; | ||||||
| 	mix->he.permille = he; | 	mix->he.permille = he; | ||||||
|  | 	sanitize_gasmix(mix); | ||||||
| 	return i; | 	return i; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -388,6 +388,7 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, struct dive | ||||||
| 	int nr = 0; | 	int nr = 0; | ||||||
| 	struct gaschanges *gaschanges = NULL; | 	struct gaschanges *gaschanges = NULL; | ||||||
| 	struct divedatapoint *dp = diveplan->dp; | 	struct divedatapoint *dp = diveplan->dp; | ||||||
|  | 	struct gasmix mix; | ||||||
| 
 | 
 | ||||||
| 	while (dp) { | 	while (dp) { | ||||||
| 		if (dp->time == 0 && dp->depth <= depth) { | 		if (dp->time == 0 && dp->depth <= depth) { | ||||||
|  | @ -403,9 +404,10 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, struct dive | ||||||
| 			} | 			} | ||||||
| 			gaschanges[i].depth = dp->depth; | 			gaschanges[i].depth = dp->depth; | ||||||
| 			gaschanges[i].gasidx = -1; | 			gaschanges[i].gasidx = -1; | ||||||
|  | 			mix.o2.permille = dp->o2; | ||||||
|  | 			mix.he.permille = dp->he; | ||||||
| 			do { | 			do { | ||||||
| 				if (dive->cylinder[j].gasmix.o2.permille == dp->o2 && | 				if (!gasmix_distance(&dive->cylinder[j].gasmix, &mix)) { | ||||||
| 				    dive->cylinder[j].gasmix.he.permille == dp->he) { |  | ||||||
| 					gaschanges[i].gasidx = j; | 					gaschanges[i].gasidx = j; | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
|  | @ -419,8 +421,8 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, struct dive | ||||||
| #if DEBUG_PLAN & 16 | #if DEBUG_PLAN & 16 | ||||||
| 	for (nr = 0; nr < *gaschangenr; nr++) | 	for (nr = 0; nr < *gaschangenr; nr++) | ||||||
| 		printf("gaschange nr %d: @ %5.2lfm gasidx %d (%d/%d)\n", nr, gaschanges[nr].depth / 1000.0, | 		printf("gaschange nr %d: @ %5.2lfm gasidx %d (%d/%d)\n", nr, gaschanges[nr].depth / 1000.0, | ||||||
| 		       gaschanges[nr].gasidx, (dive->cylinder[gaschanges[nr].gasidx].gasmix.o2.permille + 5) / 10, | 		       gaschanges[nr].gasidx, (get_o2(&dive->cylinder[gaschanges[nr].gasidx].gasmix) + 5) / 10, | ||||||
| 		       (dive->cylinder[gaschanges[nr].gasidx].gasmix.he.permille + 5) / 10); | 		       (get_he(&dive->cylinder[gaschanges[nr].gasidx].gasmix) + 5) / 10); | ||||||
| #endif | #endif | ||||||
| 	return gaschanges; | 	return gaschanges; | ||||||
| } | } | ||||||
|  | @ -493,8 +495,8 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive) | ||||||
| 	snprintf(buffer, sizeof(buffer), translate("gettextFromC", "%s\nSubsurface dive plan\nbased on GFlow = %.0f and GFhigh = %.0f\n\n"), | 	snprintf(buffer, sizeof(buffer), translate("gettextFromC", "%s\nSubsurface dive plan\nbased on GFlow = %.0f and GFhigh = %.0f\n\n"), | ||||||
| 		 disclaimer, plangflow * 100, plangfhigh * 100); | 		 disclaimer, plangflow * 100, plangfhigh * 100); | ||||||
| 	/* we start with gas 0, then check if that was changed */ | 	/* we start with gas 0, then check if that was changed */ | ||||||
| 	o2 = dive->cylinder[0].gasmix.o2.permille; | 	o2 = get_o2(&dive->cylinder[0].gasmix); | ||||||
| 	he = dive->cylinder[0].gasmix.he.permille; | 	he = get_he(&dive->cylinder[0].gasmix); | ||||||
| 	do { | 	do { | ||||||
| 		const char *depth_unit; | 		const char *depth_unit; | ||||||
| 		char gas[64]; | 		char gas[64]; | ||||||
|  | @ -568,8 +570,8 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive) | ||||||
| 			continue; | 			continue; | ||||||
| 		len = strlen(buffer); | 		len = strlen(buffer); | ||||||
| 		volume = get_volume_units(consumption[gasidx], NULL, &unit); | 		volume = get_volume_units(consumption[gasidx], NULL, &unit); | ||||||
| 		get_gas_string(dive->cylinder[gasidx].gasmix.o2.permille, | 		get_gas_string(get_o2(&dive->cylinder[gasidx].gasmix), | ||||||
| 			       dive->cylinder[gasidx].gasmix.he.permille, gas, sizeof(gas)); | 			       get_he(&dive->cylinder[gasidx].gasmix), gas, sizeof(gas)); | ||||||
| 		snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC", "%.0f%s of %s\n"), volume, unit, gas); | 		snprintf(buffer + len, sizeof(buffer) - len, translate("gettextFromC", "%.0f%s of %s\n"), volume, unit, gas); | ||||||
| 	} | 	} | ||||||
| 	dive->notes = strdup(buffer); | 	dive->notes = strdup(buffer); | ||||||
|  | @ -625,8 +627,8 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b | ||||||
| 	/* Let's start at the last 'sample', i.e. the last manually entered waypoint. */ | 	/* Let's start at the last 'sample', i.e. the last manually entered waypoint. */ | ||||||
| 	sample = &dive->dc.sample[dive->dc.samples - 1]; | 	sample = &dive->dc.sample[dive->dc.samples - 1]; | ||||||
| 	/* we start with gas 0, then check if that was changed */ | 	/* we start with gas 0, then check if that was changed */ | ||||||
| 	o2 = dive->cylinder[0].gasmix.o2.permille; | 	o2 = get_o2(&dive->cylinder[0].gasmix); | ||||||
| 	he = dive->cylinder[0].gasmix.he.permille; | 	he = get_he(&dive->cylinder[0].gasmix); | ||||||
| 	get_gas_from_events(&dive->dc, sample->time.seconds, &o2, &he); | 	get_gas_from_events(&dive->dc, sample->time.seconds, &o2, &he); | ||||||
| 	po2 = dive->dc.sample[dive->dc.samples - 1].po2; | 	po2 = dive->dc.sample[dive->dc.samples - 1].po2; | ||||||
| 	if ((current_cylinder = get_gasidx(dive, o2, he)) == -1) { | 	if ((current_cylinder = get_gasidx(dive, o2, he)) == -1) { | ||||||
|  | @ -704,8 +706,8 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b | ||||||
| 			stopping = true; | 			stopping = true; | ||||||
| 
 | 
 | ||||||
| 			current_cylinder = gaschanges[gi].gasidx; | 			current_cylinder = gaschanges[gi].gasidx; | ||||||
| 			o2 = dive->cylinder[current_cylinder].gasmix.o2.permille; | 			o2 = get_o2(&dive->cylinder[current_cylinder].gasmix); | ||||||
| 			he = dive->cylinder[current_cylinder].gasmix.he.permille; | 			he = get_he(&dive->cylinder[current_cylinder].gasmix); | ||||||
| #if DEBUG_PLAN & 16 | #if DEBUG_PLAN & 16 | ||||||
| 			printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx, | 			printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx, | ||||||
| 				       (o2 + 5) / 10, (he + 5) / 10, gaschanges[gi].depth / 1000.0); | 				       (o2 + 5) / 10, (he + 5) / 10, gaschanges[gi].depth / 1000.0); | ||||||
|  |  | ||||||
|  | @ -79,8 +79,8 @@ void DivePlannerPointsModel::loadFromDive(dive *d) | ||||||
| 	CylindersModel::instance()->setDive(stagingDive); | 	CylindersModel::instance()->setDive(stagingDive); | ||||||
| 	int lasttime = 0; | 	int lasttime = 0; | ||||||
| 	// we start with the first gas and see if it was changed
 | 	// we start with the first gas and see if it was changed
 | ||||||
| 	int o2 = backupDive.cylinder[0].gasmix.o2.permille; | 	int o2 = get_o2(&backupDive.cylinder[0].gasmix); | ||||||
| 	int he = backupDive.cylinder[0].gasmix.he.permille; | 	int he = get_he(&backupDive.cylinder[0].gasmix); | ||||||
| 	for (int i = 0; i < backupDive.dc.samples - 1; i++) { | 	for (int i = 0; i < backupDive.dc.samples - 1; i++) { | ||||||
| 		const sample &s = backupDive.dc.sample[i]; | 		const sample &s = backupDive.dc.sample[i]; | ||||||
| 		if (s.time.seconds == 0) | 		if (s.time.seconds == 0) | ||||||
|  | @ -118,7 +118,7 @@ QStringList &DivePlannerPointsModel::getGasList() | ||||||
| 			cylinder_t *cyl = &activeDive->cylinder[i]; | 			cylinder_t *cyl = &activeDive->cylinder[i]; | ||||||
| 			if (cylinder_nodata(cyl)) | 			if (cylinder_nodata(cyl)) | ||||||
| 				break; | 				break; | ||||||
| 			list.push_back(gasToStr(cyl->gasmix.o2.permille, cyl->gasmix.he.permille)); | 			list.push_back(gasToStr(get_o2(&cyl->gasmix), get_he(&cyl->gasmix))); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return list; | 	return list; | ||||||
|  | @ -488,6 +488,12 @@ bool divePointsLessThan(const divedatapoint &p1, const divedatapoint &p2) | ||||||
| 
 | 
 | ||||||
| bool DivePlannerPointsModel::addGas(int o2, int he) | bool DivePlannerPointsModel::addGas(int o2, int he) | ||||||
| { | { | ||||||
|  | 	struct gasmix mix; | ||||||
|  | 
 | ||||||
|  | 	mix.o2.permille = o2; | ||||||
|  | 	mix.he.permille = he; | ||||||
|  | 	sanitize_gasmix(&mix); | ||||||
|  | 
 | ||||||
| 	if (is_air(o2, he)) | 	if (is_air(o2, he)) | ||||||
| 		o2 = 0; | 		o2 = 0; | ||||||
| 
 | 
 | ||||||
|  | @ -497,6 +503,7 @@ bool DivePlannerPointsModel::addGas(int o2, int he) | ||||||
| 			fill_default_cylinder(cyl); | 			fill_default_cylinder(cyl); | ||||||
| 			cyl->gasmix.o2.permille = o2; | 			cyl->gasmix.o2.permille = o2; | ||||||
| 			cyl->gasmix.he.permille = he; | 			cyl->gasmix.he.permille = he; | ||||||
|  | 			sanitize_gasmix(&cyl->gasmix); | ||||||
| 			/* The depth to change to that gas is given by the depth where its pO2 is 1.6 bar.
 | 			/* The depth to change to that gas is given by the depth where its pO2 is 1.6 bar.
 | ||||||
| 			 * The user should be able to change this depth manually. */ | 			 * The user should be able to change this depth manually. */ | ||||||
| 			pressure_t modppO2; | 			pressure_t modppO2; | ||||||
|  | @ -505,7 +512,7 @@ bool DivePlannerPointsModel::addGas(int o2, int he) | ||||||
| 			CylindersModel::instance()->setDive(stagingDive); | 			CylindersModel::instance()->setDive(stagingDive); | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 		if (cyl->gasmix.o2.permille == o2 && cyl->gasmix.he.permille == he) | 		if (!gasmix_distance(&cyl->gasmix, &mix)) | ||||||
| 			return true; | 			return true; | ||||||
| 	} | 	} | ||||||
| 	qDebug("too many gases"); | 	qDebug("too many gases"); | ||||||
|  | @ -540,8 +547,8 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int o2, int he, | ||||||
| 		//Default to the first defined gas, if we got one.
 | 		//Default to the first defined gas, if we got one.
 | ||||||
| 		cylinder_t *cyl = &stagingDive->cylinder[0]; | 		cylinder_t *cyl = &stagingDive->cylinder[0]; | ||||||
| 		if (cyl) { | 		if (cyl) { | ||||||
| 			o2 = cyl->gasmix.o2.permille; | 			o2 = get_o2(&cyl->gasmix); | ||||||
| 			he = cyl->gasmix.he.permille; | 			he = get_he(&cyl->gasmix); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (o2 != -1) | 	if (o2 != -1) | ||||||
|  | @ -661,7 +668,7 @@ QVector<QPair<int, int> > DivePlannerPointsModel::collectGases(struct dive *d) | ||||||
| 	for (int i = 0; i < MAX_CYLINDERS; i++) { | 	for (int i = 0; i < MAX_CYLINDERS; i++) { | ||||||
| 		cylinder_t *cyl = &d->cylinder[i]; | 		cylinder_t *cyl = &d->cylinder[i]; | ||||||
| 		if (!cylinder_nodata(cyl)) | 		if (!cylinder_nodata(cyl)) | ||||||
| 			l.push_back(qMakePair(cyl->gasmix.o2.permille, cyl->gasmix.he.permille)); | 			l.push_back(qMakePair(get_o2(&cyl->gasmix), get_he(&cyl->gasmix))); | ||||||
| 	} | 	} | ||||||
| 	return l; | 	return l; | ||||||
| } | } | ||||||
|  | @ -761,7 +768,7 @@ void DivePlannerPointsModel::createTemporaryPlan() | ||||||
| 	for (int i = 0; i < MAX_CYLINDERS; i++) { | 	for (int i = 0; i < MAX_CYLINDERS; i++) { | ||||||
| 		cylinder_t *cyl = &stagingDive->cylinder[i]; | 		cylinder_t *cyl = &stagingDive->cylinder[i]; | ||||||
| 		if (cyl->depth.mm) { | 		if (cyl->depth.mm) { | ||||||
| 			dp = create_dp(0, cyl->depth.mm, cyl->gasmix.o2.permille, cyl->gasmix.he.permille, 0); | 			dp = create_dp(0, cyl->depth.mm, get_o2(&cyl->gasmix), get_he(&cyl->gasmix), 0); | ||||||
| 			if (diveplan.dp) { | 			if (diveplan.dp) { | ||||||
| 				dp->next = diveplan.dp->next; | 				dp->next = diveplan.dp->next; | ||||||
| 				diveplan.dp->next = dp; | 				diveplan.dp->next = dp; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue