Index: player/simplay.cc
===================================================================
--- player/simplay.cc	(revision 2830)
+++ player/simplay.cc	(working copy)
@@ -237,6 +237,21 @@
 
 
 
+/**
+ * Encapsulate margin calculation  (Operating_Profit / Income)
+ * @author Ben Love
+ */
+sint64
+spieler_t::calc_margin(sint64 operating_profit, sint64 proceeds)
+{
+	if (proceeds == 0) {
+		return 0;
+	}
+	return (100 * operating_profit) / proceeds;
+}
+
+
+
 void spieler_t::set_player_color(uint8 col1, uint8 col2)
 {
 	kennfarbe1 = col1;
@@ -392,20 +407,12 @@
 	finance_history_year[0][COST_NETWEALTH] = finance_history_year[0][COST_ASSETS] + konto;
 	finance_history_year[0][COST_CASH] = konto;
 	finance_history_year[0][COST_OPERATING_PROFIT] = finance_history_year[0][COST_INCOME] + finance_history_year[0][COST_VEHICLE_RUN] + finance_history_year[0][COST_MAINTENANCE];
-	sint64 margin_div = (finance_history_year[0][COST_VEHICLE_RUN] + finance_history_year[0][COST_MAINTENANCE]);
-	if(margin_div<0) {
-		margin_div = -margin_div;
-	}
-	finance_history_year[0][COST_MARGIN] = margin_div!= 0 ? (100*finance_history_year[0][COST_OPERATING_PROFIT]) / margin_div : 0;
+	finance_history_year[0][COST_MARGIN] = calc_margin(finance_history_year[0][COST_OPERATING_PROFIT], finance_history_year[0][COST_INCOME]);
 
 	finance_history_month[0][COST_NETWEALTH] = finance_history_month[0][COST_ASSETS] + konto;
 	finance_history_month[0][COST_CASH] = konto;
 	finance_history_month[0][COST_OPERATING_PROFIT] = finance_history_month[0][COST_INCOME] + finance_history_month[0][COST_VEHICLE_RUN] + finance_history_month[0][COST_MAINTENANCE];
-	margin_div = (finance_history_month[0][COST_VEHICLE_RUN] + finance_history_month[0][COST_MAINTENANCE]);
-	if(margin_div<0) {
-		margin_div = -margin_div;
-	}
-	finance_history_month[0][COST_MARGIN] = margin_div!=0 ? (100*finance_history_month[0][COST_OPERATING_PROFIT]) / margin_div : 0;
+	finance_history_month[0][COST_MARGIN] = calc_margin(finance_history_month[0][COST_OPERATING_PROFIT], finance_history_month[0][COST_INCOME]);
 	finance_history_month[0][COST_SCENARIO_COMPLETED] = finance_history_year[0][COST_SCENARIO_COMPLETED] = welt->get_scenario()->completed(player_nr);
 }
 
@@ -654,18 +661,10 @@
 					// for old savegames only load 9 types and calculate the 10th; for new savegames load all 10 values
 					if (cost_type < 9) {
 						file->rdwr_longlong(finance_history_year[year][cost_type], " ");
-					} else {
-						sint64 tmp = finance_history_year[year][COST_VEHICLE_RUN] + finance_history_year[year][COST_MAINTENANCE];
-						if(tmp<0) { tmp = -tmp; }
-						finance_history_year[year][COST_MARGIN] = (tmp== 0) ? 0 : (finance_history_year[year][COST_OPERATING_PROFIT] * 100) / tmp;
 					}
 				} else {
 					if (cost_type < 10) {
 						file->rdwr_longlong(finance_history_year[year][cost_type], " ");
-					} else {
-						sint64 tmp = finance_history_year[year][COST_VEHICLE_RUN] + finance_history_year[year][COST_MAINTENANCE];
-						if(tmp<0) { tmp = -tmp; }
-						finance_history_year[year][COST_MARGIN] = (tmp==0) ? 0 : (finance_history_year[year][COST_OPERATING_PROFIT] * 100) / tmp;
 					}
 				}
 			}
@@ -677,18 +676,12 @@
 			for (int cost_type = 0; cost_type<10; cost_type++) {
 				file->rdwr_longlong(finance_history_year[year][cost_type], " ");
 			}
-			sint64 tmp = finance_history_year[year][COST_VEHICLE_RUN] + finance_history_year[year][COST_MAINTENANCE];
-			if(tmp<0) { tmp = -tmp; }
-			finance_history_year[year][COST_MARGIN] = (tmp== 0) ? 0 : (finance_history_year[year][COST_OPERATING_PROFIT] * 100) / tmp;
 		}
 		// in 84008 monthly finance history was introduced
 		for (int month = 0;month<MAX_PLAYER_HISTORY_MONTHS;month++) {
 			for (int cost_type = 0; cost_type<10; cost_type++) {
 				file->rdwr_longlong(finance_history_month[month][cost_type], " ");
 			}
-			sint64 tmp = finance_history_month[month][COST_VEHICLE_RUN] + finance_history_month[month][COST_MAINTENANCE];
-			if(tmp<0) { tmp = -tmp; }
-			finance_history_month[month][COST_MARGIN] = (tmp==0) ? 0 : (finance_history_month[month][COST_OPERATING_PROFIT] * 100) / tmp;
 		}
 	}
 	else if (file->get_version() < 99011) {
@@ -730,6 +723,15 @@
 			}
 		}
 	}
+	if (file->get_version() < 102003) {
+		// prior versions calculated margin incorrectly.
+		for (int year = 0;year<MAX_PLAYER_HISTORY_YEARS;year++) {
+			finance_history_year[year][COST_MARGIN] = calc_margin(finance_history_year[year][COST_OPERATING_PROFIT], finance_history_year[year][COST_INCOME]);
+		}
+		for (int month = 0;month<MAX_PLAYER_HISTORY_MONTHS;month++) {
+			finance_history_month[month][COST_MARGIN] = calc_margin(finance_history_month[month][COST_OPERATING_PROFIT], finance_history_month[month][COST_INCOME]);
+		}
+	}
 	// we have to pay maintenance at the beginning of a month
 	if(file->get_version()<99018  &&  file->is_loading()) {
 		buche( -finance_history_month[1][COST_MAINTENANCE], COST_MAINTENANCE );
Index: player/simplay.h
===================================================================
--- player/simplay.h	(revision 2830)
+++ player/simplay.h	(working copy)
@@ -30,7 +30,7 @@
 	COST_NETWEALTH,     // Total Cash + Assets
 	COST_PROFIT,        // COST_POWERLINES+COST_INCOME-(COST_CONSTRUCTION+COST_VEHICLE_RUN+COST_NEW_VEHICLE+COST_MAINTENANCE)
 	COST_OPERATING_PROFIT, // COST_POWERLINES+COST_INCOME-(COST_VEHICLE_RUN+COST_MAINTENANCE)
-	COST_MARGIN,        // COST_OPERATING_PROFIT/(COST_VEHICLE_RUN+COST_MAINTENANCE)
+	COST_MARGIN,        // COST_OPERATING_PROFIT/COST_INCOME
 	COST_ALL_TRANSPORTED, // all transported goods
 	COST_POWERLINES,	  // revenue from the power grid
 	COST_TRANSPORTED_PAS,	// number of passengers that actually reached destination
@@ -159,6 +159,8 @@
 	 */
 	bool automat;
 
+	sint64 calc_margin(sint64 operating_profit, sint64 proceeds);
+
 public:
 	virtual bool set_active( bool b ) { return automat = b; }
 
