Debian packaging patches are maintained in Git.
--- openbve-1.4.0.10.orig/openBVE/OpenBve/Audio/Sounds.Update.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/Audio/Sounds.Update.cs
@@ -1,12 +1,24 @@
 ﻿using System;
+using System.Collections.Generic;
 using Tao.OpenAl;
 
 namespace OpenBve {
 	internal static partial class Sounds {
+
+		/// <summary>Updates the sound component. Should be called every frame.</summary>
+		/// <param name="timeElapsed">The time in seconds that elapsed since the last call to this function.</param>
+		/// <param name="mode">The sound model.</param>
+		internal static void Update(double timeElapsed, SoundModels model) {
+			if (model == SoundModels.Linear) {
+				UpdateLinearModel(timeElapsed);
+			} else {
+				UpdateInverseModel(timeElapsed);
+			}
+		}
 		
 		/// <summary>Updates the sound component. Should be called every frame.</summary>
 		/// <param name="timeElapsed">The time in seconds that elapsed since the last call to this function.</param>
-		internal static void Update(double timeElapsed) {
+		private static void UpdateLinearModel(double timeElapsed) {
 			/*
 			 * Set up the listener
 			 * */
@@ -97,24 +109,7 @@ namespace OpenBve {
 					double gain;
 					if (GlobalMute) {
 						gain = 0.0;
-					} else if (Interface.CurrentOptions.SoundModel == SoundModels.Experimental) {
-						// --- inverse distance clamped model (experimental) ---
-						double distance = positionDifference.Norm();
-						double radius = Sources[i].Radius;
-						if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead) {
-							if (Sources[i].Train != TrainManager.PlayerTrain || Sources[i].Car != TrainManager.PlayerTrain.DriverCar) {
-								radius *= 0.5;
-							}
-						}
-						if (distance < 2.0 * radius) {
-							gain = 1.0 - distance * distance * (4.0 * radius - distance) / (16.0 * radius * radius * radius);
-						} else {
-							gain = radius / distance;
-						}
-						gain -= Math.Exp(ClampFactorLogarithm) * distance * distance;
-						gain *= Sources[i].Volume;
 					} else {
-						// --- linear distance clamped model (default) ---
 						double distance = positionDifference.Norm();
 						double innerRadius = Sources[i].Radius;
 						if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead) {
@@ -208,101 +203,316 @@ namespace OpenBve {
 			/*
 			 * Adjust the outer radius factor / the clamp factor.
 			 * */
-			if (Interface.CurrentOptions.SoundModel == SoundModels.Experimental) {
-				const double slowSpeed = 1.0;
-				const double fastSpeed = 5.0;
-				if (actuallyPlaying > Interface.CurrentOptions.SoundNumber) {
-					ClampFactorLogarithmSpeed += fastSpeed * timeElapsed;
-					if (ClampFactorLogarithmSpeed > fastSpeed) {
-						ClampFactorLogarithmSpeed = fastSpeed;
-					}
-				} else if (actuallyPlaying > Interface.CurrentOptions.SoundNumber - 2) {
-					ClampFactorLogarithmSpeed += timeElapsed;
-					if (ClampFactorLogarithmSpeed > slowSpeed) {
-						ClampFactorLogarithmSpeed = slowSpeed;
-					}
-				} else if (actuallyPlaying > Interface.CurrentOptions.SoundNumber - 8) {
-					if (ClampFactorLogarithmSpeed < 0.0) {
-						if (ClampFactorLogarithmSpeed < -fastSpeed) {
-							ClampFactorLogarithmSpeed = -fastSpeed;
-						} else {
-							ClampFactorLogarithmSpeed += timeElapsed;
-							if (ClampFactorLogarithmSpeed > 0.0) {
-								ClampFactorLogarithmSpeed = 0.0;
-							}
-						}
-					} else if (ClampFactorLogarithmSpeed > 0.0) {
-						if (ClampFactorLogarithmSpeed > fastSpeed) {
-							ClampFactorLogarithmSpeed = fastSpeed;
-						} else {
-							ClampFactorLogarithmSpeed -= timeElapsed;
-							if (ClampFactorLogarithmSpeed < 0.0) {
-								ClampFactorLogarithmSpeed = 0.0;
-							}
-						}
-					}
-				} else if (actuallyPlaying > Interface.CurrentOptions.SoundNumber - 10) {
-					ClampFactorLogarithmSpeed -= timeElapsed;
-					if (ClampFactorLogarithmSpeed < -slowSpeed) {
-						ClampFactorLogarithmSpeed = -slowSpeed;
+			if (actuallyPlaying >= Interface.CurrentOptions.SoundNumber - 2) {
+				/*
+				 * Too many sounds are playing.
+				 * Reduce the outer radius factor.
+				 * */
+				OuterRadiusFactorSpeed -= timeElapsed;
+				if (OuterRadiusFactorSpeed < -OuterRadiusFactorMaximumSpeed) {
+					OuterRadiusFactorSpeed = -OuterRadiusFactorMaximumSpeed;
+				}
+			} else if (actuallyPlaying <= Interface.CurrentOptions.SoundNumber - 6) {
+				/*
+				 * Only few sounds are playing.
+				 * Increase the outer radius factor.
+				 * */
+				OuterRadiusFactorSpeed += timeElapsed;
+				if (OuterRadiusFactorSpeed > OuterRadiusFactorMaximumSpeed) {
+					OuterRadiusFactorSpeed = OuterRadiusFactorMaximumSpeed;
+				}
+			} else {
+				/*
+				 * Neither too many nor too few sounds are playing.
+				 * Stabilize the outer radius factor.
+				 * */
+				if (OuterRadiusFactorSpeed < 0.0) {
+					OuterRadiusFactorSpeed += timeElapsed;
+					if (OuterRadiusFactorSpeed > 0.0) {
+						OuterRadiusFactorSpeed = 0.0;
 					}
 				} else {
-					ClampFactorLogarithmSpeed -= timeElapsed;
-					if (ClampFactorLogarithmSpeed < -fastSpeed) {
-						ClampFactorLogarithmSpeed = -fastSpeed;
+					OuterRadiusFactorSpeed -= timeElapsed;
+					if (OuterRadiusFactorSpeed < 0.0) {
+						OuterRadiusFactorSpeed = 0.0;
 					}
 				}
-				ClampFactorLogarithm += timeElapsed * ClampFactorLogarithmSpeed;
-				if (ClampFactorLogarithm < ClampFactorLogarithmMinimum) {
-					ClampFactorLogarithm = ClampFactorLogarithmMinimum;
-					ClampFactorLogarithmSpeed = 0.0;
-				} else if (ClampFactorLogarithm > ClampFactorLogarithmMaximum) {
-					ClampFactorLogarithm = ClampFactorLogarithmMaximum;
-					ClampFactorLogarithmSpeed = 0.0;
-				}
+			}
+			OuterRadiusFactor += OuterRadiusFactorSpeed * timeElapsed;
+			if (OuterRadiusFactor < OuterRadiusFactorMinimum) {
+				OuterRadiusFactor = OuterRadiusFactorMinimum;
+				OuterRadiusFactorSpeed = 0.0;
+			} else if (OuterRadiusFactor > OuterRadiusFactorMaximum) {
+				OuterRadiusFactor = OuterRadiusFactorMaximum;
+				OuterRadiusFactorSpeed = 0.0;
+			}
+		}
+		
+		private class SoundSourceAttenuation : IComparable<SoundSourceAttenuation> {
+			internal SoundSource Source;
+			internal double Gain;
+			internal double Distance;
+			internal SoundSourceAttenuation(SoundSource source, double gain, double distance) {
+				this.Source = source;
+				this.Gain = gain;
+				this.Distance = distance;
+			}
+			int IComparable<SoundSourceAttenuation>.CompareTo(SoundSourceAttenuation other) {
+				return other.Gain.CompareTo(this.Gain);
+			}
+		}
+		
+		/// <summary>Updates the sound component. Should be called every frame.</summary>
+		/// <param name="timeElapsed">The time in seconds that elapsed since the last call to this function.</param>
+		private static void UpdateInverseModel(double timeElapsed) {
+			/*
+			 * Set up the listener.
+			 * */
+			OpenBveApi.Math.Vector3 listenerPosition = World.AbsoluteCameraPosition;
+			OpenBveApi.Math.Orientation3 listenerOrientation = new OpenBveApi.Math.Orientation3(World.AbsoluteCameraSide, World.AbsoluteCameraUp, World.AbsoluteCameraDirection);
+			OpenBveApi.Math.Vector3 listenerVelocity;
+			if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead | World.CameraMode == World.CameraViewMode.Exterior) {
+				TrainManager.Car car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar];
+				OpenBveApi.Math.Vector3 diff = car.FrontAxle.Follower.WorldPosition - car.RearAxle.Follower.WorldPosition;
+				listenerVelocity = car.Specs.CurrentSpeed * OpenBveApi.Math.Vector3.Normalize(diff);
 			} else {
-				if (actuallyPlaying >= Interface.CurrentOptions.SoundNumber - 2) {
+				listenerVelocity = OpenBveApi.Math.Vector3.Null;
+			}
+			Al.alListener3f(Al.AL_POSITION, 0.0f, 0.0f, 0.0f);
+			Al.alListener3f(Al.AL_VELOCITY, (float)listenerVelocity.X, (float)listenerVelocity.Y, (float)listenerVelocity.Z);
+			Al.alListenerfv(Al.AL_ORIENTATION, new float[] { (float)listenerOrientation.Z.X, (float)listenerOrientation.Z.Y, (float)listenerOrientation.Z.Z, -(float)listenerOrientation.Y.X, -(float)listenerOrientation.Y.Y, -(float)listenerOrientation.Y.Z });
+			/*
+			 * Set up the atmospheric attributes.
+			 * */
+			double elevation = World.AbsoluteCameraPosition.Y + Game.RouteInitialElevation;
+			double airTemperature = Game.GetAirTemperature(elevation);
+			double airPressure = Game.GetAirPressure(elevation, airTemperature);
+			double airDensity = Game.GetAirDensity(airPressure, airTemperature);
+			double speedOfSound = Game.GetSpeedOfSound(airPressure, airTemperature);
+			try {
+				Al.alSpeedOfSound((float)speedOfSound);
+			} catch { }
+			/*
+			 * Collect all sounds that are to be played
+			 * and ensure that all others are stopped.
+			 * */
+			List<SoundSourceAttenuation> toBePlayed = new List<SoundSourceAttenuation>();
+			for (int i = 0; i < SourceCount; i++) {
+				if (Sources[i].State == SoundSourceState.StopPending) {
 					/*
-					 * Too many sounds are playing.
-					 * Reduce the outer radius factor.
+					 * The sound is still playing but is to be stopped.
+					 * Stop the sound, then remove it from the list of
+					 * sound sources.
 					 * */
-					OuterRadiusFactorSpeed -= timeElapsed;
-					if (OuterRadiusFactorSpeed < -OuterRadiusFactorMaximumSpeed) {
-						OuterRadiusFactorSpeed = -OuterRadiusFactorMaximumSpeed;
-					}
-				} else if (actuallyPlaying <= Interface.CurrentOptions.SoundNumber - 6) {
+					Al.alDeleteSources(1, ref Sources[i].OpenAlSourceName);
+					Sources[i].State = SoundSourceState.Stopped;
+					Sources[i].OpenAlSourceName = 0;
+					Sources[i] = Sources[SourceCount - 1];
+					SourceCount--;
+					i--;
+				} else if (Sources[i].State == SoundSourceState.Stopped) {
 					/*
-					 * Only few sounds are playing.
-					 * Increase the outer radius factor.
+					 * The sound was already stopped. Remove it from
+					 * the list of sound sources.
 					 * */
-					OuterRadiusFactorSpeed += timeElapsed;
-					if (OuterRadiusFactorSpeed > OuterRadiusFactorMaximumSpeed) {
-						OuterRadiusFactorSpeed = OuterRadiusFactorMaximumSpeed;
+					Sources[i] = Sources[SourceCount - 1];
+					SourceCount--;
+					i--;
+				} else if (GlobalMute) {
+					/*
+					 * The sound is playing or about to be played, but
+					 * the global mute option is enabled. Stop the sound
+					 * sound if necessary, then remove it from the list
+					 * of sound sources if the sound is not looping.
+					 * */
+					if (Sources[i].State == SoundSourceState.Playing) {
+						Al.alDeleteSources(1, ref Sources[i].OpenAlSourceName);
+						Sources[i].State = SoundSourceState.PlayPending;
+						Sources[i].OpenAlSourceName = 0;
+					}
+					if (!Sources[i].Looped) {
+						Sources[i].State = SoundSourceState.Stopped;
+						Sources[i].OpenAlSourceName = 0;
+						Sources[i] = Sources[SourceCount - 1];
+						SourceCount--;
+						i--;
 					}
 				} else {
 					/*
-					 * Neither too many nor too few sounds are playing.
-					 * Stabilize the outer radius factor.
+					 * The sound is to be played or is already playing.
 					 * */
-					if (OuterRadiusFactorSpeed < 0.0) {
-						OuterRadiusFactorSpeed += timeElapsed;
-						if (OuterRadiusFactorSpeed > 0.0) {
-							OuterRadiusFactorSpeed = 0.0;
+					if (Sources[i].State == SoundSourceState.Playing) {
+						int state;
+						Al.alGetSourcei(Sources[i].OpenAlSourceName, Al.AL_SOURCE_STATE, out state);
+						if (state != Al.AL_INITIAL & state != Al.AL_PLAYING) {
+							/*
+							 * The sound is not playing any longer.
+							 * Remove it from the list of sound sources.
+							 * */
+							Al.alDeleteSources(1, ref Sources[i].OpenAlSourceName);
+							Sources[i].State = SoundSourceState.Stopped;
+							Sources[i].OpenAlSourceName = 0;
+							Sources[i] = Sources[SourceCount - 1];
+							SourceCount--;
+							i--;
+							continue;
 						}
+					}
+					/*
+					 * Calculate the gain, then add the sound
+					 * to the list of sounds to be played.
+					 * */
+					OpenBveApi.Math.Vector3 position;
+					if (Sources[i].Train != null) {
+						OpenBveApi.Math.Vector3 direction;
+						TrainManager.CreateWorldCoordinates(Sources[i].Train, Sources[i].Car, Sources[i].Position.X, Sources[i].Position.Y, Sources[i].Position.Z, out position.X, out position.Y, out position.Z, out direction.X, out direction.Y, out direction.Z);
 					} else {
-						OuterRadiusFactorSpeed -= timeElapsed;
-						if (OuterRadiusFactorSpeed < 0.0) {
-							OuterRadiusFactorSpeed = 0.0;
+						position = Sources[i].Position;
+					}
+					OpenBveApi.Math.Vector3 positionDifference = position - listenerPosition;
+					double distance = positionDifference.Norm();
+					double radius = Sources[i].Radius;
+					if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead) {
+						if (Sources[i].Train != TrainManager.PlayerTrain || Sources[i].Car != TrainManager.PlayerTrain.DriverCar) {
+							radius *= 0.5;
 						}
 					}
+					double gain;
+					if (distance < 2.0 * radius) {
+						gain = 1.0 - distance * distance * (4.0 * radius - distance) / (16.0 * radius * radius * radius);
+					} else {
+						gain = radius / distance;
+					}
+					gain *= Sources[i].Volume;
+					if (gain <= 0.0) {
+						/*
+						 * The gain is too low. Stop the sound if playing,
+						 * but keep looping sounds pending.
+						 * */
+						if (Sources[i].State == SoundSourceState.Playing) {
+							Al.alDeleteSources(1, ref Sources[i].OpenAlSourceName);
+							Sources[i].State = SoundSourceState.PlayPending;
+							Sources[i].OpenAlSourceName = 0;
+						}
+						if (!Sources[i].Looped) {
+							Sources[i].State = SoundSourceState.Stopped;
+							Sources[i].OpenAlSourceName = 0;
+							Sources[i] = Sources[SourceCount - 1];
+							SourceCount--;
+							i--;
+						}
+					} else {
+						/*
+						 * Add the source.
+						 * */
+						toBePlayed.Add(new SoundSourceAttenuation(Sources[i], gain, distance));
+					}
+				}
+			}
+			/*
+			 * Now that we have the list of sounds that are to be played,
+			 * sort them by their gain so that we can determine and
+			 * adjust the clamp factor.
+			 * */
+			double clampFactor = Math.Exp(LogClampFactor);
+			for (int i = 0; i < toBePlayed.Count; i++) {
+				toBePlayed[i].Gain -= clampFactor * toBePlayed[i].Distance * toBePlayed[i].Distance;
+			}
+			toBePlayed.Sort();
+			for (int i = 0; i < toBePlayed.Count; i++) {
+				toBePlayed[i].Gain += clampFactor * toBePlayed[i].Distance * toBePlayed[i].Distance;
+			}
+			double desiredLogClampFactor;
+			int index = Interface.CurrentOptions.SoundNumber;
+			if (toBePlayed.Count <= index) {
+				desiredLogClampFactor = MinLogClampFactor;
+			} else {
+				double cutoffDistance = toBePlayed[index].Distance;
+				if (cutoffDistance <= 0.0) {
+					desiredLogClampFactor = MaxLogClampFactor;
+				} else {
+					double cutoffGain = toBePlayed[index].Gain;
+					desiredLogClampFactor = Math.Log(cutoffGain / (cutoffDistance * cutoffDistance));
+					if (desiredLogClampFactor < MinLogClampFactor) {
+						desiredLogClampFactor = MinLogClampFactor;
+					} else if (desiredLogClampFactor > MaxLogClampFactor) {
+						desiredLogClampFactor = MaxLogClampFactor;
+					}
+				}
+			}
+			const double rate = 3.0;
+			if (LogClampFactor < desiredLogClampFactor) {
+				LogClampFactor += timeElapsed * rate;
+				if (LogClampFactor > desiredLogClampFactor) {
+					LogClampFactor = desiredLogClampFactor;
 				}
-				OuterRadiusFactor += OuterRadiusFactorSpeed * timeElapsed;
-				if (OuterRadiusFactor < OuterRadiusFactorMinimum) {
-					OuterRadiusFactor = OuterRadiusFactorMinimum;
-					OuterRadiusFactorSpeed = 0.0;
-				} else if (OuterRadiusFactor > OuterRadiusFactorMaximum) {
-					OuterRadiusFactor = OuterRadiusFactorMaximum;
-					OuterRadiusFactorSpeed = 0.0;
+			} else if (LogClampFactor > desiredLogClampFactor) {
+				LogClampFactor -= timeElapsed * rate;
+				if (LogClampFactor < desiredLogClampFactor) {
+					LogClampFactor = desiredLogClampFactor;
+				}
+			}
+			/*
+			 * Play the sounds.
+			 * */
+			clampFactor = Math.Exp(LogClampFactor);
+			for (int i = index; i < toBePlayed.Count; i++) {
+				toBePlayed[i].Gain = 0.0;
+			}
+			for (int i = 0; i < toBePlayed.Count; i++) {
+				SoundSource source = toBePlayed[i].Source;
+				double gain = toBePlayed[i].Gain - clampFactor * toBePlayed[i].Distance * toBePlayed[i].Distance;
+				if (gain <= 0.0) {
+					/*
+					 * Stop the sound.
+					 * */
+					if (source.State == SoundSourceState.Playing) {
+						Al.alDeleteSources(1, ref source.OpenAlSourceName);
+						source.State = SoundSourceState.PlayPending;
+						source.OpenAlSourceName = 0;
+					}
+					if (!source.Looped) {
+						source.State = SoundSourceState.Stopped;
+						source.OpenAlSourceName = 0;
+					}
+				} else {
+					/*
+					 * Ensure the buffer is loaded, then play the sound.
+					 * */
+					if (source.State != SoundSourceState.Playing) {
+						LoadBuffer(source.Buffer);
+						if (source.Buffer.Loaded) {
+							Al.alGenSources(1, out source.OpenAlSourceName);
+							Al.alSourcei(source.OpenAlSourceName, Al.AL_BUFFER, source.Buffer.OpenAlBufferName);
+						} else {
+							/*
+							 * We cannot play the sound because
+							 * the buffer could not be loaded.
+							 * */
+							source.State = SoundSourceState.Stopped;
+							continue;
+						}
+					}
+					OpenBveApi.Math.Vector3 position;
+					OpenBveApi.Math.Vector3 velocity;
+					if (source.Train != null) {
+						OpenBveApi.Math.Vector3 direction;
+						TrainManager.CreateWorldCoordinates(source.Train, source.Car, source.Position.X, source.Position.Y, source.Position.Z, out position.X, out position.Y, out position.Z, out direction.X, out direction.Y, out direction.Z);
+						velocity = source.Train.Cars[source.Car].Specs.CurrentSpeed * direction;
+					} else {
+						position = source.Position;
+						velocity = OpenBveApi.Math.Vector3.Null;
+					}
+					position -= listenerPosition;
+					Al.alSource3f(source.OpenAlSourceName, Al.AL_POSITION, (float)position.X, (float)position.Y, (float)position.Z);
+					Al.alSource3f(source.OpenAlSourceName, Al.AL_VELOCITY, (float)velocity.X, (float)velocity.Y, (float)velocity.Z);
+					Al.alSourcef(source.OpenAlSourceName, Al.AL_PITCH, (float)source.Pitch);
+					Al.alSourcef(source.OpenAlSourceName, Al.AL_GAIN, (float)gain);
+					if (source.State != SoundSourceState.Playing) {
+						Al.alSourcei(source.OpenAlSourceName, Al.AL_LOOPING, source.Looped ? Al.AL_TRUE : Al.AL_FALSE);
+						Al.alSourcePlay(source.OpenAlSourceName);
+						source.State = SoundSourceState.Playing;
+					}
 				}
 			}
 		}
--- openbve-1.4.0.10.orig/openBVE/OpenBve/Audio/Sounds.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/Audio/Sounds.cs
@@ -9,10 +9,10 @@ namespace OpenBve {
 
 		/// <summary>Represents different sound distance attenuation models.</summary>
 		internal enum SoundModels {
-			/// <summary>Represents the default Linear Distance Clamped Model.</summary>
-			Default = 0,
-			/// <summary>Represents the experimental Inverse Distance Clamped Model.</summary>
-			Experimental = 1
+			/// <summary>Represents the new Inverse Distance Clamped Model.</summary>
+			Inverse = 0,
+			/// <summary>Represents the old Linear Distance Clamped Model.</summary>
+			Linear = -1
 		}
 		
 		
@@ -55,10 +55,9 @@ namespace OpenBve {
 		
 		// --- inverse distance clamp model ---
 		
-		internal static double ClampFactorLogarithm = -18.4206807439524;
-		internal static double ClampFactorLogarithmSpeed = 0.0;
-		internal const double ClampFactorLogarithmMinimum = -27.6310211159285;
-		internal const double ClampFactorLogarithmMaximum = -4.60517018598809;
+		internal static double LogClampFactor = -15.0;
+		internal const double MinLogClampFactor = -30.0;
+		internal const double MaxLogClampFactor = -1.0;
 
 		
 		// --- initialization and deinitialization ---
--- openbve-1.4.0.10.orig/openBVE/OpenBve/Graphics/Textures.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/Graphics/Textures.cs
@@ -127,6 +127,11 @@ namespace OpenBve {
 						handle.Height = texture.Height;
 						handle.Transparency = texture.GetTransparencyType();
 						texture = UpsizeToPowerOfTwo(texture);
+						
+//						int newWidth = Math.Min(texture.Width, 256);
+//						int newHeight = Math.Min(texture.Height, 256);
+//						texture = Resize(texture, newWidth, newHeight);
+						
 						switch (Interface.CurrentOptions.Interpolation) {
 							case Interface.InterpolationMode.NearestNeighbor:
 								Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/Interface.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/Interface.cs
@@ -140,7 +140,7 @@ namespace OpenBve {
 				this.JoystickAxisThreshold = 0.0;
 				this.KeyRepeatDelay = 0.5;
 				this.KeyRepeatInterval = 0.1;
-				this.SoundModel = Sounds.SoundModels.Default;
+				this.SoundModel = Sounds.SoundModels.Inverse;
 				this.SoundRange = SoundRange.Low;
 				this.SoundNumber = 16;
 				this.ShowWarningMessages = true;
@@ -387,8 +387,8 @@ namespace OpenBve {
 									switch (Key) {
 										case "model":
 											switch (Value.ToLowerInvariant()) {
-													case "experimental": Interface.CurrentOptions.SoundModel = Sounds.SoundModels.Experimental; break;
-													default: Interface.CurrentOptions.SoundModel = Sounds.SoundModels.Default; break;
+													case "linear": Interface.CurrentOptions.SoundModel = Sounds.SoundModels.Linear; break;
+													default: Interface.CurrentOptions.SoundModel = Sounds.SoundModels.Inverse; break;
 											}
 											break;
 										case "range":
@@ -565,8 +565,8 @@ namespace OpenBve {
 			Builder.AppendLine("[sound]");
 			Builder.Append("model = ");
 			switch (CurrentOptions.SoundModel) {
-					case Sounds.SoundModels.Experimental: Builder.AppendLine("experimental"); break;
-					default: Builder.AppendLine("default"); break;
+					case Sounds.SoundModels.Linear: Builder.AppendLine("linear"); break;
+					default: Builder.AppendLine("inverse"); break;
 			}
 			Builder.Append("range = ");
 			switch (CurrentOptions.SoundRange) {
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/MainLoop.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/MainLoop.cs
@@ -339,7 +339,7 @@ namespace OpenBve {
 				Game.UpdateScore(TimeElapsed);
 				Game.UpdateMessages();
 				Game.UpdateScoreMessages(TimeElapsed);
-				Sounds.Update(TimeElapsed);
+				Sounds.Update(TimeElapsed, Interface.CurrentOptions.SoundModel);
 				Renderer.RenderScene(TimeElapsed);
 				Sdl.SDL_GL_SwapBuffers();
 				Game.UpdateBlackBox();
@@ -621,7 +621,7 @@ namespace OpenBve {
 										break;
 									case Interface.Command.MiscMute:
 										Sounds.GlobalMute = !Sounds.GlobalMute;
-										Sounds.Update(TimeElapsed);
+										Sounds.Update(TimeElapsed, Interface.CurrentOptions.SoundModel);
 										break;
 								}
 							}
@@ -753,7 +753,7 @@ namespace OpenBve {
 									case Interface.Command.MiscMute:
 										// mute
 										Sounds.GlobalMute = !Sounds.GlobalMute;
-										Sounds.Update(TimeElapsed);
+										Sounds.Update(TimeElapsed, Interface.CurrentOptions.SoundModel);
 										break;
 
 								}
@@ -1641,7 +1641,7 @@ namespace OpenBve {
 									case Interface.Command.MiscMute:
 										// mute
 										Sounds.GlobalMute = !Sounds.GlobalMute;
-										Sounds.Update(TimeElapsed);
+										Sounds.Update(TimeElapsed, Interface.CurrentOptions.SoundModel);
 										break;
 								}
 							} else if (Interface.CurrentControls[i].DigitalState == Interface.DigitalControlState.Released) {
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/PluginManager.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/PluginManager.cs
@@ -455,6 +455,14 @@ namespace OpenBve {
 		/// <returns>Whether the plugin was loaded successfully.</returns>
 		internal static bool LoadDefaultPlugin(TrainManager.Train train, string trainFolder) {
 			string file = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Plugins"), "OpenBveAts.dll");
+			// Executable data (== .dlls) may need to live somewhere else, so such an
+			// option probably may need adding to 'filesystem.cfg' in the future. -sladen
+			// Note that should path determination logic may want to be shared with
+			// the similiar statement in System/Plugins.cs
+			if(!System.IO.File.Exists(file))
+				file = OpenBveApi.Path.CombineFile(OpenBveApi.Path.CombineDirectory(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Plugins"), "OpenBveAts.dll");
+			// Or ... just hard code it as a massive kludge -sladen
+			//file = "/usr/lib/openbve/Plugins/OpenBveAts.dll";
 			bool success = LoadPlugin(train, file, trainFolder);
 			if (success) {
 				train.Plugin.IsDefault = true;
@@ -522,17 +530,14 @@ namespace OpenBve {
 					return false;
 				}
 				foreach (Type type in types) {
-					if (type.IsPublic && (type.Attributes & TypeAttributes.Abstract) == 0) {
-						object instance = assembly.CreateInstance(type.FullName);
-						IRuntime api = instance as IRuntime;
-						if (api != null) {
-							train.Plugin = new NetPlugin(pluginFile, trainFolder, api, train);
-							if (train.Plugin.Load(specs, mode)) {
-								return true;
-							} else {
-								train.Plugin = null;
-								return false;
-							}
+					if (typeof(IRuntime).IsAssignableFrom(type)) {
+						IRuntime api = assembly.CreateInstance(type.FullName) as IRuntime;
+						train.Plugin = new NetPlugin(pluginFile, trainFolder, api, train);
+						if (train.Plugin.Load(specs, mode)) {
+							return true;
+						} else {
+							train.Plugin = null;
+							return false;
 						}
 					}
 				}
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/Program.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/Program.cs
@@ -6,6 +6,8 @@ using System.Reflection;
 using System.Windows.Forms;
 using Tao.OpenGl;
 using Tao.Sdl;
+using System.Threading;
+using System.Windows.Forms;
 
 namespace OpenBve {
 	public static partial class Program {
@@ -21,6 +23,15 @@ namespace OpenBve {
 		private static bool SdlWindowCreated = false;
 		internal static Host CurrentHost = new Host();
 
+		internal static void WatchdogExit()
+		{
+			int delay = 5000; // milliseconds
+			Console.Error.WriteLine("WatchdogExit: starting timer");
+			System.Threading.Thread.Sleep(delay);
+			Console.Error.WriteLine("WatchdogExit: Something did not shutdown quickly enough, forcing exit");
+			Environment.FailFast("WatchdogExit: Something did not shutdown quickly enough, forcing exit");
+		}
+
 		// main
 		[STAThread]
 		private static void Main(string[] args) {
@@ -74,6 +85,13 @@ namespace OpenBve {
 			if(SdlWindowCreated & Interface.CurrentOptions.FullscreenMode) {
 				Sdl.SDL_SetVideoMode(Interface.CurrentOptions.WindowWidth, Interface.CurrentOptions.WindowHeight, 32, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF);
 			}
+
+			// Start a watchdog timer, so that even if SDL/OpenAL hang freeing buffers,
+			// the program will still successfully force a quit.
+			Thread Watchdog = new Thread(new ThreadStart(WatchdogExit));
+			Watchdog.IsBackground = true;
+			Watchdog.Start();
+
 			Renderer.Deinitialize();
 			Textures.Deinitialize();
 			Plugins.UnloadPlugins();
@@ -103,6 +121,7 @@ namespace OpenBve {
 					MessageBox.Show(ex.Message + "\n\nProcess = " + FileSystem.RestartProcess + "\nArguments = " + arguments, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
 				}
 			}
+			Environment.Exit(0);
 		}
 
 		// get exception text
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/Renderer.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/Renderer.cs
@@ -277,7 +277,7 @@ namespace OpenBve {
 			Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
 			Gl.glDisable(Gl.GL_BLEND); BlendEnabled = false;
 			Gl.glEnable(Gl.GL_DEPTH_TEST);
-			Gl.glDepthMask(Gl.GL_TRUE);
+			Gl.glDepthMask(true);
 			Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0.0f, 0.0f, 0.0f, 1.0f }); EmissiveEnabled = false;
 			SetAlphaFunc(Gl.GL_GREATER, 0.9f);
 		}
@@ -435,7 +435,7 @@ namespace OpenBve {
 			SortPolygons(DynamicAlpha);
 			if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance) {
 				Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
-				Gl.glDepthMask(Gl.GL_FALSE);
+				Gl.glDepthMask(false);
 				SetAlphaFunc(Gl.GL_GREATER, 0.0f);
 				for (int i = 0; i < DynamicAlpha.FaceCount; i++) {
 					RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz);
@@ -443,7 +443,7 @@ namespace OpenBve {
 			} else {
 				Gl.glDisable(Gl.GL_BLEND); BlendEnabled = false;
 				SetAlphaFunc(Gl.GL_EQUAL, 1.0f);
-				Gl.glDepthMask(Gl.GL_TRUE);
+				Gl.glDepthMask(true);
 				for (int i = 0; i < DynamicAlpha.FaceCount; i++) {
 					int r = (int)ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Faces[DynamicAlpha.Faces[i].FaceIndex].Material;
 					if (ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Normal & ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].GlowAttenuationData == 0) {
@@ -454,7 +454,7 @@ namespace OpenBve {
 				}
 				Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
 				SetAlphaFunc(Gl.GL_LESS, 1.0f);
-				Gl.glDepthMask(Gl.GL_FALSE);
+				Gl.glDepthMask(false);
 				bool additive = false;
 				for (int i = 0; i < DynamicAlpha.FaceCount; i++) {
 					int r = (int)ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Faces[DynamicAlpha.Faces[i].FaceIndex].Material;
@@ -475,7 +475,7 @@ namespace OpenBve {
 			}
 			// motion blur
 			Gl.glDisable(Gl.GL_DEPTH_TEST);
-			Gl.glDepthMask(Gl.GL_FALSE);
+			Gl.glDepthMask(false);
 			SetAlphaFunc(Gl.GL_GREATER, 0.0f);
 			if (Interface.CurrentOptions.MotionBlur != Interface.MotionBlurMode.None) {
 				if (LightingEnabled) {
@@ -493,7 +493,7 @@ namespace OpenBve {
 			Glu.gluLookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz);
 			if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) {
 				// 3d cab
-				Gl.glDepthMask(Gl.GL_TRUE);
+				Gl.glDepthMask(true);
 				Gl.glEnable(Gl.GL_DEPTH_TEST);
 				Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT);
 				if (!LightingEnabled) {
@@ -511,7 +511,7 @@ namespace OpenBve {
 				SortPolygons(OverlayAlpha);
 				if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance) {
 					Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
-					Gl.glDepthMask(Gl.GL_FALSE);
+					Gl.glDepthMask(false);
 					SetAlphaFunc(Gl.GL_GREATER, 0.0f);
 					for (int i = 0; i < OverlayAlpha.FaceCount; i++) {
 						RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz);
@@ -519,7 +519,7 @@ namespace OpenBve {
 				} else {
 					Gl.glDisable(Gl.GL_BLEND); BlendEnabled = false;
 					SetAlphaFunc(Gl.GL_EQUAL, 1.0f);
-					Gl.glDepthMask(Gl.GL_TRUE);
+					Gl.glDepthMask(true);
 					for (int i = 0; i < OverlayAlpha.FaceCount; i++) {
 						int r = (int)ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Faces[OverlayAlpha.Faces[i].FaceIndex].Material;
 						if (ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Normal & ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].GlowAttenuationData == 0) {
@@ -530,7 +530,7 @@ namespace OpenBve {
 					}
 					Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
 					SetAlphaFunc(Gl.GL_LESS, 1.0f);
-					Gl.glDepthMask(Gl.GL_FALSE);
+					Gl.glDepthMask(false);
 					bool additive = false;
 					for (int i = 0; i < OverlayAlpha.FaceCount; i++) {
 						int r = (int)ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Faces[OverlayAlpha.Faces[i].FaceIndex].Material;
@@ -558,7 +558,7 @@ namespace OpenBve {
 				if (!BlendEnabled) {
 					Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
 				}
-				Gl.glDepthMask(Gl.GL_FALSE);
+				Gl.glDepthMask(false);
 				Gl.glDisable(Gl.GL_DEPTH_TEST);
 				UnsetAlphaFunc();
 				SortPolygons(OverlayAlpha);
@@ -2357,7 +2357,7 @@ namespace OpenBve {
 					"=sound",
 					"sound buffers: " + soundBuffersLoaded.ToString(Culture) + " / " + soundBuffersRegistered.ToString(Culture),
 					"sound sources: " + soundSourcesPlaying.ToString(Culture) + " / " + soundSourcesRegistered.ToString(Culture),
-					(Interface.CurrentOptions.SoundModel == Sounds.SoundModels.Experimental ? "log clamp factor: " + Sounds.ClampFactorLogarithm.ToString("0.00") : "outer radius factor: " + Sounds.OuterRadiusFactor.ToString("0.00", Culture)),
+					(Interface.CurrentOptions.SoundModel == Sounds.SoundModels.Inverse ? "log clamp factor: " + Sounds.LogClampFactor.ToString("0.00") : "outer radius factor: " + Sounds.OuterRadiusFactor.ToString("0.00", Culture)),
 					"",
 					"=debug",
 					"train plugin status: " + (TrainManager.PlayerTrain.Plugin != null ? (TrainManager.PlayerTrain.Plugin.PluginValid ? "ok" : "error") : "n/a"),
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/TrainManager.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/TrainManager.cs
@@ -852,7 +852,7 @@ namespace OpenBve {
 				 * there will be additional flange noise.
 				 * */
 				double cdti = Math.Abs(Train.Cars[CarIndex].FrontAxle.Follower.CantDueToInaccuracy) + Math.Abs(Train.Cars[CarIndex].RearAxle.Follower.CantDueToInaccuracy);
-				basegain += 15.0 * spd * cdti * cdti;
+				basegain += 0.5 * spd * spd * cdti * cdti;
 				/*
 				 * This applies the settings.
 				 * */
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/formMain.Designer.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/formMain.Designer.cs
@@ -1251,7 +1251,7 @@
         	this.panelOptionsRight.Controls.Add(this.groupboxSound);
         	this.panelOptionsRight.Location = new System.Drawing.Point(332, 72);
         	this.panelOptionsRight.Name = "panelOptionsRight";
-        	this.panelOptionsRight.Size = new System.Drawing.Size(316, 416);
+        	this.panelOptionsRight.Size = new System.Drawing.Size(316, 384);
         	this.panelOptionsRight.TabIndex = 17;
         	// 
         	// groupboxDistance
@@ -1346,7 +1346,7 @@
         	this.groupboxControls.Controls.Add(this.checkboxJoysticksUsed);
         	this.groupboxControls.Controls.Add(this.labelJoystickAxisThreshold);
         	this.groupboxControls.ForeColor = System.Drawing.Color.Black;
-        	this.groupboxControls.Location = new System.Drawing.Point(0, 176);
+        	this.groupboxControls.Location = new System.Drawing.Point(0, 144);
         	this.groupboxControls.Name = "groupboxControls";
         	this.groupboxControls.Size = new System.Drawing.Size(316, 80);
         	this.groupboxControls.TabIndex = 10;
@@ -1394,7 +1394,7 @@
         	this.groupboxVerbosity.Controls.Add(this.checkboxErrorMessages);
         	this.groupboxVerbosity.Controls.Add(this.checkboxWarningMessages);
         	this.groupboxVerbosity.ForeColor = System.Drawing.Color.Black;
-        	this.groupboxVerbosity.Location = new System.Drawing.Point(0, 352);
+        	this.groupboxVerbosity.Location = new System.Drawing.Point(0, 320);
         	this.groupboxVerbosity.Name = "groupboxVerbosity";
         	this.groupboxVerbosity.Size = new System.Drawing.Size(316, 64);
         	this.groupboxVerbosity.TabIndex = 12;
@@ -1430,7 +1430,7 @@
         	this.groupboxSimulation.Controls.Add(this.checkboxCollisions);
         	this.groupboxSimulation.Controls.Add(this.checkboxToppling);
         	this.groupboxSimulation.ForeColor = System.Drawing.Color.Black;
-        	this.groupboxSimulation.Location = new System.Drawing.Point(0, 264);
+        	this.groupboxSimulation.Location = new System.Drawing.Point(0, 232);
         	this.groupboxSimulation.Name = "groupboxSimulation";
         	this.groupboxSimulation.Size = new System.Drawing.Size(316, 80);
         	this.groupboxSimulation.TabIndex = 11;
@@ -1493,7 +1493,7 @@
         	this.groupboxSound.ForeColor = System.Drawing.Color.Black;
         	this.groupboxSound.Location = new System.Drawing.Point(0, 88);
         	this.groupboxSound.Name = "groupboxSound";
-        	this.groupboxSound.Size = new System.Drawing.Size(316, 80);
+        	this.groupboxSound.Size = new System.Drawing.Size(316, 48);
         	this.groupboxSound.TabIndex = 9;
         	this.groupboxSound.TabStop = false;
         	this.groupboxSound.Text = "Sound";
@@ -1501,7 +1501,7 @@
         	// updownSoundNumber
         	// 
         	this.updownSoundNumber.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-        	this.updownSoundNumber.Location = new System.Drawing.Point(156, 48);
+        	this.updownSoundNumber.Location = new System.Drawing.Point(152, 16);
         	this.updownSoundNumber.Minimum = new decimal(new int[] {
         	        	        	8,
         	        	        	0,
@@ -1521,28 +1521,30 @@
         	this.comboboxSoundRange.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
         	this.comboboxSoundRange.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
         	this.comboboxSoundRange.FormattingEnabled = true;
-        	this.comboboxSoundRange.Location = new System.Drawing.Point(156, 24);
+        	this.comboboxSoundRange.Location = new System.Drawing.Point(152, 40);
         	this.comboboxSoundRange.Name = "comboboxSoundRange";
         	this.comboboxSoundRange.Size = new System.Drawing.Size(152, 21);
         	this.comboboxSoundRange.TabIndex = 1;
+        	this.comboboxSoundRange.Visible = false;
         	// 
         	// labelSoundRange
         	// 
         	this.labelSoundRange.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
         	        	        	| System.Windows.Forms.AnchorStyles.Right)));
         	this.labelSoundRange.AutoEllipsis = true;
-        	this.labelSoundRange.Location = new System.Drawing.Point(8, 24);
+        	this.labelSoundRange.Location = new System.Drawing.Point(4, 40);
         	this.labelSoundRange.Name = "labelSoundRange";
         	this.labelSoundRange.Size = new System.Drawing.Size(148, 16);
         	this.labelSoundRange.TabIndex = 0;
         	this.labelSoundRange.Text = "Effective range:";
         	this.labelSoundRange.TextAlign = System.Drawing.ContentAlignment.TopRight;
+        	this.labelSoundRange.Visible = false;
         	// 
         	// labelSoundNumber
         	// 
         	this.labelSoundNumber.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
         	        	        	| System.Windows.Forms.AnchorStyles.Right)));
-        	this.labelSoundNumber.Location = new System.Drawing.Point(8, 50);
+        	this.labelSoundNumber.Location = new System.Drawing.Point(4, 18);
         	this.labelSoundNumber.Name = "labelSoundNumber";
         	this.labelSoundNumber.Size = new System.Drawing.Size(148, 14);
         	this.labelSoundNumber.TabIndex = 2;
@@ -3379,11 +3381,11 @@
         	this.Controls.Add(this.labelFillerOne);
         	this.Controls.Add(this.labelFillerTwo);
         	this.Controls.Add(this.labelFillerThree);
-        	this.Controls.Add(this.panelStart);
-        	this.Controls.Add(this.panelGetAddOns);
         	this.Controls.Add(this.panelOptions);
         	this.Controls.Add(this.panelControls);
         	this.Controls.Add(this.panelReview);
+        	this.Controls.Add(this.panelStart);
+        	this.Controls.Add(this.panelGetAddOns);
         	this.KeyPreview = true;
         	this.Name = "formMain";
         	this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/formMain.GetAddOns.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/formMain.GetAddOns.cs
@@ -168,7 +168,9 @@ namespace OpenBve {
 		
 		
 		// --- show database ---
-
+		
+		private class RemoveIfPossibleAttribute { }
+		
 		/// <summary>Shows the list of available packages.</summary>
 		private void ShowDatabase(bool expand) {
 			if (CurrentDatabase != null & !IsBusy()) {
@@ -241,6 +243,26 @@ namespace OpenBve {
 					node = node.Nodes.Add(operatorx);
 					node.ImageKey = "folder";
 					node.SelectedImageKey = "folder";
+					switch (type.ToLowerInvariant()) {
+						case "route":
+							node = node.Nodes.Add(checkboxFilterRoutes.Text);
+							break;
+						case "train":
+							node = node.Nodes.Add(checkboxFilterTrains.Text);
+							break;
+						case "library":
+							node = node.Nodes.Add(checkboxFilterLibraries.Text);
+							break;
+						case "shared library":
+							node = node.Nodes.Add(checkboxFilterSharedLibraries.Text);
+							break;
+						default:
+							node = node.Nodes.Add(type);
+							break;
+					}
+					node.ImageKey = "folder";
+					node.SelectedImageKey = "folder";
+					node.Tag = new RemoveIfPossibleAttribute();
 					node = node.Nodes.Add(caption);
 					string imageKey;
 					if (ManagedContent.IsInstalledPackageProtected(package.Name)) {
@@ -259,14 +281,16 @@ namespace OpenBve {
 				Group(treeviewPackages.Nodes);
 				if (keywords.Length == 0) {
 					foreach (TreeNode node in treeviewPackages.Nodes) {
-						Flatten(node.Nodes);
+						Flatten(node.Nodes, false);
 					}
 				} else {
-					Flatten(treeviewPackages.Nodes);
+					Flatten(treeviewPackages.Nodes, false);
 				}
 				treeviewPackages.Sort();
 				if (expand) {
 					treeviewPackages.ExpandAll();
+				} else {
+					Expand(treeviewPackages.Nodes, treeviewPackages.Height / treeviewPackages.ItemHeight - 1);
 				}
 				treeviewPackages.EndUpdate();
 				buttonPackageInstall.Enabled = false;
@@ -314,9 +338,9 @@ namespace OpenBve {
 		private void Group(TreeNodeCollection collection) {
 			/* Group folders that have same text */
 			for (int i = 1; i < collection.Count; i++) {
-				if (collection[i].Tag == null) {
+				if (collection[i].Tag == null | collection[i].Tag is RemoveIfPossibleAttribute) {
 					for (int j = 0; j < i; j++) {
-						if (collection[j].Tag == null) {
+						if (collection[j].Tag == null | collection[j].Tag is RemoveIfPossibleAttribute) {
 							if (collection[i].Text == collection[j].Text) {
 								TreeNodeCollection elements = collection[i].Nodes;
 								collection.RemoveAt(i);
@@ -336,19 +360,10 @@ namespace OpenBve {
 			}
 		}
 		
-		private void Flatten(TreeNodeCollection collection) {
+		private void Flatten(TreeNodeCollection collection, bool shortify) {
 			/* Recursion */
 			foreach (TreeNode node in collection) {
-				Flatten(node.Nodes);
-			}
-			/* Flatten out folders that contain only one element */
-			for (int i = 0; i < collection.Count; i++) {
-				if (collection[i].Nodes.Count == 1) {
-					TreeNode element = collection[i].Nodes[0];
-					collection.RemoveAt(i);
-					collection.Add(element);
-					i--;
-				}
+				Flatten(node.Nodes, shortify);
 			}
 			/* Remove empty folders from the collection */
 			for (int i = 0; i < collection.Count; i++) {
@@ -357,16 +372,50 @@ namespace OpenBve {
 					i--;
 				}
 			}
-			/* Flatten out the only element if it is a folder */
-			if (collection.Count == 1 && collection[0].Tag == null) {
-				TreeNodeCollection elements = collection[0].Nodes;
-				collection.RemoveAt(0);
-				foreach (TreeNode node in elements) {
-					collection.Add(node);
+			if (!shortify) {
+				/* If only element is Route/Train/Library/SharedLibrary, then remove it */
+				if (collection.Count == 1 && collection[0].Tag is RemoveIfPossibleAttribute) {
+					TreeNodeCollection elements = collection[0].Nodes;
+					collection.RemoveAt(0);
+					foreach (TreeNode element in elements) {
+						collection.Add(element);
+					}
+				}
+				/* Expand folders that only contain one element */
+				if (collection.Count == 1) {
+					if (collection[0].Nodes.Count != 0) {
+						collection[0].Expand();
+					}
+				}
+			} else {
+				/* Flatten out folders that contain only one element */
+				if (collection.Count == 1 && collection[0].Tag == null) {
+					TreeNodeCollection elements = collection[0].Nodes;
+					collection.RemoveAt(0);
+					foreach (TreeNode element in elements) {
+						collection.Add(element);
+					}
 				}
 			}
 		}
 		
+		private int Count(TreeNodeCollection collection) {
+			int count = collection.Count;
+			foreach (TreeNode node in collection) {
+				count += Count(node.Nodes);
+			}
+			return count;
+		}
+		
+		private void Expand(TreeNodeCollection collection, int total) {
+			int count = Count(collection);
+			if (count <= total) {
+				foreach (TreeNode node in collection) {
+					node.ExpandAll();
+				}
+			}
+		}	
+		
 		
 		// --- functions ---
 		
@@ -458,7 +507,7 @@ namespace OpenBve {
 		private void TreeviewPackagesAfterSelect(object sender, TreeViewEventArgs e) {
 			if (treeviewPackages.SelectedNode == null || treeviewPackages.SelectedNode.Tag == null) {
 				ClearPackageDetails();
-			} else {
+			} else if (treeviewPackages.SelectedNode.Tag is ManagedContent.Version) {
 				ManagedContent.Version version = (ManagedContent.Version)treeviewPackages.SelectedNode.Tag;
 				string currentVersion = ManagedContent.GetInstalledPackageVersion(version.Name);
 				string caption = version.GetMetadata("caption", CurrentLanguageCode, null);
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OldCode/formMain.Start.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/OldCode/formMain.Start.cs
@@ -61,11 +61,12 @@ namespace OpenBve {
 			Group(treeviewRouteAddOns.Nodes);
 			if (keywords.Length == 0) {
 				foreach (TreeNode node in treeviewRouteAddOns.Nodes) {
-					Flatten(node.Nodes);
+					Flatten(node.Nodes, true);
 				}
 			} else {
-				Flatten(treeviewRouteAddOns.Nodes);
+				Flatten(treeviewRouteAddOns.Nodes, true);
 			}
+			Expand(treeviewRouteAddOns.Nodes, treeviewRouteAddOns.Height / treeviewRouteAddOns.ItemHeight - 1);
 			treeviewRouteAddOns.Sort();
 			treeviewRouteAddOns.EndUpdate();
 		}
@@ -179,11 +180,12 @@ namespace OpenBve {
 			Group(treeviewTrainAddOns.Nodes);
 			if (keywords.Length == 0) {
 				foreach (TreeNode node in treeviewTrainAddOns.Nodes) {
-					Flatten(node.Nodes);
+					Flatten(node.Nodes, true);
 				}
 			} else {
-				Flatten(treeviewTrainAddOns.Nodes);
+				Flatten(treeviewTrainAddOns.Nodes, true);
 			}
+			Expand(treeviewTrainAddOns.Nodes, treeviewTrainAddOns.Height / treeviewTrainAddOns.ItemHeight - 1);
 			treeviewTrainAddOns.Sort();
 			treeviewTrainAddOns.EndUpdate();
 		}
--- openbve-1.4.0.10.orig/openBVE/OpenBve/OpenBve.csproj
+++ openbve-1.4.0.10/openBVE/OpenBve/OpenBve.csproj
@@ -13,14 +13,14 @@
     <NoStdLib>False</NoStdLib>
     <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
     <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile></TargetFrameworkProfile>
     <SignAssembly>False</SignAssembly>
     <DelaySign>False</DelaySign>
     <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
     <RunCodeAnalysis>False</RunCodeAnalysis>
     <RunSourceAnalysis>False</RunSourceAnalysis>
     <ApplicationIcon>..\icon.ico</ApplicationIcon>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -33,7 +33,8 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>None</DebugType>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>PdbOnly</DebugType>
     <Optimize>true</Optimize>
     <PlatformTarget>x86</PlatformTarget>
     <OutputPath>bin\Release\</OutputPath>
@@ -215,4 +216,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
\ No newline at end of file
+</Project>
--- openbve-1.4.0.10.orig/openBVE/OpenBve/Properties/AssemblyInfo.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/Properties/AssemblyInfo.cs
@@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyProduct("openBVE")]
 [assembly: AssemblyCopyright("(Public Domain) http://trainsimframework.org/")]
 [assembly: ComVisible(false)]
-[assembly: AssemblyVersion("1.4.0.10")]
-[assembly: AssemblyFileVersion("1.4.0.10")]
+[assembly: AssemblyVersion("1.4.1.0")]
+[assembly: AssemblyFileVersion("1.4.1.0")]
 [assembly: CLSCompliant(true)]
 
 namespace OpenBve {
--- openbve-1.4.0.10.orig/openBVE/OpenBve/System/Internet.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/System/Internet.cs
@@ -11,7 +11,7 @@ namespace OpenBve {
 		/// <param name="client">The web client.</param>
 		/// <param name="url">The URL to be accessed.</param>
 		private static void AddWebClientHeaders(WebClient client, string url) {
-			const string agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0";
+			const string agent = "Mozilla/5.0 (Windows NT 6.2; rv:9.0.1) Gecko/20100101 Firefox/9.0.1";
 			try {
 				client.Headers.Add(HttpRequestHeader.UserAgent, agent);
 			} catch { }
--- openbve-1.4.0.10.orig/openBVE/OpenBve/System/Joysticks.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/System/Joysticks.cs
@@ -54,7 +54,15 @@ namespace OpenBve {
 							characters[2 * j + 0] = (char)(value & 0xFF);
 							characters[2 * j + 1] = (char)(value >> 8);
 						}
-						AttachedJoysticks[i].Name = new string(characters);
+						AttachedJoysticks[i].Name = null;
+						for (int j = 0; j < characters.Length; j++) {
+							if (characters[j] == '\0') {
+								AttachedJoysticks[i].Name = new string(characters, 0, j);
+							}
+						}
+						if (AttachedJoysticks[i].Name == null) {
+							AttachedJoysticks[i].Name = new string(characters);
+						}
 						AttachedJoysticks[i].SdlHandle = Sdl.SDL_JoystickOpen(i);
 					}
 					Initialized = true;
--- openbve-1.4.0.10.orig/openBVE/OpenBve/System/ManagedContent.Install.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/System/ManagedContent.Install.cs
@@ -180,7 +180,10 @@ namespace OpenBve {
 											}
 											builder.AppendLine();
 											foreach (KeyValuePair pair in version.Metadata) {
-												if (!string.Equals(pair.Key, "protected", StringComparison.OrdinalIgnoreCase)) {
+												if (
+													!string.Equals(pair.Key, "protected", StringComparison.OrdinalIgnoreCase) &&
+													!string.Equals(pair.Key, "wip", StringComparison.OrdinalIgnoreCase)
+												) {
 													builder.AppendLine(pair.ToString());
 												}
 											}
--- openbve-1.4.0.10.orig/openBVE/OpenBve/System/Plugins.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/System/Plugins.cs
@@ -75,6 +75,13 @@ namespace OpenBve {
 		internal static bool LoadPlugins() {
 			UnloadPlugins();
 			string folder = Program.FileSystem.GetDataFolder("Plugins");
+			// Executable data (== .dlls) may need to live somewhere else, so such an
+			// option probably may need adding to 'filesystem.cfg' in the future. -sladen
+			if(!System.IO.Directory.Exists(folder))
+				folder = OpenBveApi.Path.CombineDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Plugins");
+			// And if that doesn't work, just hard code it. -sladen
+			//if(!System.IO.Directory.Exists(folder))
+			//  folder = "/usr/lib/openbve/Plugins";
 			string[] files = Directory.GetFiles(folder);
 			List<Plugin> list = new List<Plugin>();
 			StringBuilder builder = new StringBuilder();
@@ -86,6 +93,7 @@ namespace OpenBve {
 						Plugin plugin = new Plugin(file);
 						Assembly assembly = Assembly.LoadFile(file);
 						Type[] types = assembly.GetTypes();
+						bool iruntime = false;
 						foreach (Type type in types) {
 							if (type.IsSubclassOf(typeof(OpenBveApi.Textures.TextureInterface))) {
 								plugin.Texture = (OpenBveApi.Textures.TextureInterface)assembly.CreateInstance(type.FullName);
@@ -96,10 +104,16 @@ namespace OpenBve {
 							if (type.IsSubclassOf(typeof(OpenBveApi.Objects.ObjectInterface))) {
 								plugin.Object = (OpenBveApi.Objects.ObjectInterface)assembly.CreateInstance(type.FullName);
 							}
+							if (typeof(OpenBveApi.Runtime.IRuntime).IsAssignableFrom(type)) {
+								iruntime = true;
+							}
 						}
 						if (plugin.Texture != null | plugin.Sound != null | plugin.Object != null) {
 							plugin.Load();
 							list.Add(plugin);
+						} else if (!iruntime) {
+							builder.Append("Plugin ").Append(Path.GetFileName(file)).AppendLine(" does not implement compatible interfaces.");
+							builder.AppendLine();
 						}
 						#if !DEBUG
 					} catch (Exception ex) {
--- openbve-1.4.0.10.orig/openBVE/OpenBve/System/Program.cs
+++ openbve-1.4.0.10/openBVE/OpenBve/System/Program.cs
@@ -3,7 +3,6 @@ using System.Drawing;
 using System.Drawing.Imaging;
 using System.Runtime.InteropServices;
 using System.Windows.Forms;
-
 using Tao.Sdl;
 
 namespace OpenBve {
--- openbve-1.4.0.10.orig/openBVE/OpenBveApi/OpenBveApi.csproj
+++ openbve-1.4.0.10/openBVE/OpenBveApi/OpenBveApi.csproj
@@ -7,7 +7,7 @@
     <OutputType>Library</OutputType>
     <RootNamespace>OpenBveApi</RootNamespace>
     <AssemblyName>OpenBveApi</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <SourceAnalysisOverrideSettingsFile>C:\Documents and Settings\Administrator\Application Data\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
     <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
@@ -15,7 +15,8 @@
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
     <DocumentationFile>bin\Release\OpenBveApi.xml</DocumentationFile>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Platform)' == 'x86' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -34,8 +35,8 @@
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
     <OutputPath>bin\Release\</OutputPath>
-    <DebugSymbols>false</DebugSymbols>
-    <DebugType>None</DebugType>
+    <DebugSymbols>True</DebugSymbols>
+    <DebugType>PdbOnly</DebugType>
     <Optimize>True</Optimize>
     <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
     <DefineConstants>TRACE</DefineConstants>
@@ -75,4 +76,4 @@
       <DependentUpon>Math.cs</DependentUpon>
     </Compile>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
--- openbve-1.4.0.10.orig/openBVE/OpenBveAts/AI.cs
+++ openbve-1.4.0.10/openBVE/OpenBveAts/AI.cs
@@ -9,6 +9,8 @@ namespace Plugin {
 		/// <summary>The underlying train.</summary>
 		private Train Train;
 		
+		private bool AtcProbing;
+		
 		
 		// --- constructors ---
 		
@@ -80,7 +82,7 @@ namespace Plugin {
 			// --- ats-p ---
 			if (this.Train.AtsP != null) {
 				if (this.Train.AtsP.State == AtsP.States.Disabled) {
-					this.Train.KeyDown(VirtualKeys.E);
+					this.Train.KeyDown(VirtualKeys.D);
 					data.Response = AIResponse.Long;
 					return;
 				} else if (this.Train.AtsP.State == AtsP.States.Pattern) {
@@ -140,18 +142,36 @@ namespace Plugin {
 			}
 			// --- atc ---
 			if (this.Train.Atc != null) {
-				if (this.Train.Atc.State == Atc.States.Disabled) {
-					this.Train.KeyDown(VirtualKeys.G);
-					data.Response = AIResponse.Long;
-					return;
-				} else if (this.Train.Atc.ShouldSwitchToAts()) {
-					this.Train.KeyDown(VirtualKeys.C1);
-					data.Response = AIResponse.Long;
-					return;
+				if (this.Train.Atc.ShouldSwitchToAts()) {
+					if (this.Train.AtsSx != null | this.Train.AtsP != null) {
+						if (this.Train.Atc.State == Atc.States.Normal | this.Train.Atc.State == Atc.States.Service | this.Train.Atc.State == Atc.States.Emergency) {
+							this.Train.KeyDown(VirtualKeys.C1);
+							data.Response = AIResponse.Long;
+							return;
+						}
+					} else if (this.Train.Atc.State != Atc.States.Disabled) {
+						this.Train.KeyDown(VirtualKeys.E);
+						data.Response = AIResponse.Long;
+						return;
+					}
 				} else if (this.Train.Atc.ShouldSwitchToAtc()) {
-					this.Train.KeyDown(VirtualKeys.C2);
+					if (this.Train.Atc.State == Atc.States.Disabled) {
+						this.Train.KeyDown(VirtualKeys.D);
+						this.AtcProbing = this.Train.State.Speed.MetersPerSecond < 0.1 / 3.6;
+						data.Response = AIResponse.Long;
+						return;
+					} else {
+						this.Train.KeyDown(VirtualKeys.C2);
+						data.Response = AIResponse.Long;
+						return;
+					}
+				} else if (this.Train.Atc.State == Atc.States.Disabled & this.Train.State.Speed.MetersPerSecond < 0.1 / 3.6 & !this.AtcProbing) {
+					this.Train.KeyDown(VirtualKeys.D);
+					this.AtcProbing = true;
 					data.Response = AIResponse.Long;
 					return;
+				} else if (this.AtcProbing & this.Train.State.Speed.MetersPerSecond > 10.0 / 3.6) {
+					this.AtcProbing = false;
 				} else if (this.Train.Atc.State == Atc.States.Normal | this.Train.Atc.State == Atc.States.Service) {
 					if (this.Train.State.Speed.KilometersPerHour > 15.0) {
 						if (this.Train.State.Speed.MetersPerSecond > this.Train.Atc.CurrentAtcSpeed - 5.0 / 3.6) {
--- openbve-1.4.0.10.orig/openBVE/OpenBveAts/Atc.cs
+++ openbve-1.4.0.10/openBVE/OpenBveAts/Atc.cs
@@ -269,7 +269,11 @@ namespace Plugin {
 			}
 			if (this.State == States.Suppressed) {
 				if (data.Handles.BrakeNotch <= this.Train.Specs.BrakeNotches) {
-					this.State = States.Ats;
+					if (this.Train.AtsSx != null | this.Train.AtsP != null) {
+						this.State = States.Ats;
+					} else {
+						this.State = States.Normal;
+					}
 				}
 			}
 			if (blocking) {
@@ -373,8 +377,10 @@ namespace Plugin {
 				case VirtualKeys.C1:
 					// --- switch to ats ---
 					if (this.State == States.Normal | this.State == States.Service | this.State == States.Emergency) {
-						this.State = States.Ats;
-						this.Train.Sounds.ToAts.Play();
+						if (this.Train.AtsSx != null | this.Train.AtsP != null) {
+							this.State = States.Ats;
+							this.Train.Sounds.ToAts.Play();
+						}
 					}
 					break;
 				case VirtualKeys.C2:
--- openbve-1.4.0.10.orig/openBVE/OpenBveAts/OpenBveAts.csproj
+++ openbve-1.4.0.10/openBVE/OpenBveAts/OpenBveAts.csproj
@@ -7,14 +7,15 @@
     <OutputType>Library</OutputType>
     <RootNamespace>OpenBveAts</RootNamespace>
     <AssemblyName>OpenBveAts</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <SourceAnalysisOverrideSettingsFile>C:\Documents and Settings\Administrator\Application Data\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
     <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
     <NoStdLib>False</NoStdLib>
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <OutputPath>bin\Debug\</OutputPath>
@@ -62,4 +63,4 @@
       <Private>False</Private>
     </ProjectReference>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
--- openbve-1.4.0.10.orig/openBVE/Sound.Flac/Sound.Flac.csproj
+++ openbve-1.4.0.10/openBVE/Sound.Flac/Sound.Flac.csproj
@@ -7,14 +7,15 @@
     <OutputType>Library</OutputType>
     <RootNamespace>Sound.Flac</RootNamespace>
     <AssemblyName>Sound.Flac</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <SourceAnalysisOverrideSettingsFile>C:\Documents and Settings\Administrator\Application Data\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
     <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
     <NoStdLib>False</NoStdLib>
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Platform)' == 'x86' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -58,4 +59,4 @@
       <Private>False</Private>
     </ProjectReference>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
--- openbve-1.4.0.10.orig/openBVE/Sound.RiffWave/Sound.RiffWave.csproj
+++ openbve-1.4.0.10/openBVE/Sound.RiffWave/Sound.RiffWave.csproj
@@ -7,14 +7,15 @@
     <OutputType>Library</OutputType>
     <RootNamespace>Plugin</RootNamespace>
     <AssemblyName>Sound.RiffWave</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <SourceAnalysisOverrideSettingsFile>C:\Documents and Settings\Administrator\Application Data\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
     <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
     <NoStdLib>False</NoStdLib>
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Platform)' == 'x86' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -57,4 +58,4 @@
       <Private>False</Private>
     </ProjectReference>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
--- openbve-1.4.0.10.orig/openBVE/Texture.Ace/Texture.Ace.csproj
+++ openbve-1.4.0.10/openBVE/Texture.Ace/Texture.Ace.csproj
@@ -7,14 +7,15 @@
     <OutputType>Library</OutputType>
     <RootNamespace>Texture.Ace</RootNamespace>
     <AssemblyName>Texture.Ace</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <SourceAnalysisOverrideSettingsFile>C:\Documents and Settings\Administrator\Application Data\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
     <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
     <NoStdLib>False</NoStdLib>
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Platform)' == 'x86' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -57,4 +58,4 @@
       <Private>False</Private>
     </ProjectReference>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
--- openbve-1.4.0.10.orig/openBVE/Texture.BmpGifJpegPngTiff/Texture.BmpGifJpegPngTiff.csproj
+++ openbve-1.4.0.10/openBVE/Texture.BmpGifJpegPngTiff/Texture.BmpGifJpegPngTiff.csproj
@@ -7,14 +7,15 @@
     <OutputType>Library</OutputType>
     <RootNamespace>Plugin</RootNamespace>
     <AssemblyName>Texture.BmpGifJpegPngTiff</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <SourceAnalysisOverrideSettingsFile>C:\Documents and Settings\Administrator\Application Data\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
     <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
     <NoStdLib>False</NoStdLib>
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Platform)' == 'x86' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -58,4 +59,4 @@
       <Private>False</Private>
     </ProjectReference>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
