diff --git a/Subsurface/Content/Items/Electricity/signalitems.xml b/Subsurface/Content/Items/Electricity/signalitems.xml index c42fd6b19..8e64051b4 100644 --- a/Subsurface/Content/Items/Electricity/signalitems.xml +++ b/Subsurface/Content/Items/Electricity/signalitems.xml @@ -19,6 +19,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + - diff --git a/Subsurface/Content/Items/Weapons/railgunbase.png b/Subsurface/Content/Items/Weapons/railgunbase.png index bf2ef92f7..00350556c 100644 Binary files a/Subsurface/Content/Items/Weapons/railgunbase.png and b/Subsurface/Content/Items/Weapons/railgunbase.png differ diff --git a/Subsurface/Content/watershader.mgfx b/Subsurface/Content/watershader.mgfx new file mode 100644 index 000000000..492637759 Binary files /dev/null and b/Subsurface/Content/watershader.mgfx differ diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs index 719a3ee08..e6fcaac09 100644 --- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs @@ -17,12 +17,12 @@ namespace Subsurface public BackgroundSpriteManager(string configPath) { - XDocument doc = ToolBox.TryLoadXml(configPath); - if (doc == null) return; - activeSprites = new List(); prefabs = new List(); + XDocument doc = ToolBox.TryLoadXml(configPath); + if (doc == null) return; + foreach (XElement element in doc.Root.Elements()) { prefabs.Add(new BackgroundSpritePrefab(element)); @@ -31,10 +31,13 @@ namespace Subsurface public void SpawnSprites(int count) { - count = Math.Min(count, MaxSprites); activeSprites.Clear(); + if (prefabs.Count == 0) return; + + count = Math.Min(count, MaxSprites); + for (int i = 0; i < count; i++ ) { Vector2 pos = Vector2.Zero; diff --git a/Subsurface/Source/EventInput/EventInput.cs b/Subsurface/Source/EventInput/EventInput.cs index 62bb51bf7..331c8c5d2 100644 --- a/Subsurface/Source/EventInput/EventInput.cs +++ b/Subsurface/Source/EventInput/EventInput.cs @@ -167,6 +167,12 @@ namespace EventInput initialized = true; } + public static void OnCharEntered(char character) + { + if (CharEntered != null) + CharEntered(null, new CharacterEventArgs(character, 0)); + } + static IntPtr HookProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { IntPtr returnCode = CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam); diff --git a/Subsurface/Source/GUI/TitleScreen.cs b/Subsurface/Source/GUI/TitleScreen.cs index 7379d5fb3..842e51bc1 100644 --- a/Subsurface/Source/GUI/TitleScreen.cs +++ b/Subsurface/Source/GUI/TitleScreen.cs @@ -72,7 +72,7 @@ namespace Subsurface new Vector3(Game1.GraphicsWidth / 2.0f, Game1.GraphicsHeight / 2.0f, 0)); - Hull.renderer.RenderBack(graphics, renderTarget, transform); + Hull.renderer.RenderBack(spriteBatch, renderTarget, transform); spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied); diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index b36ad9bd7..441bb0ccb 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -303,7 +303,7 @@ namespace Subsurface public void Render(GraphicsDevice graphicsDevice, Camera cam) { - if (renderer.positionInBuffer > renderer.vertices.Length - 6) return; + if (renderer.PositionInBuffer > renderer.vertices.Length - 6) return; //calculate where the surface should be based on the water volume float top = rect.Y; @@ -313,30 +313,37 @@ namespace Subsurface //interpolate the position of the rendered surface towards the "target surface" surface = surface + (surfaceY - surface) / 10.0f; - Matrix transform = - cam.Transform - * Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f; + Matrix transform = cam.Transform * Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f; if (bottom > cam.WorldView.Y || top < cam.WorldView.Y - cam.WorldView.Height) return; if (!update) { // create the four corners of our triangle. - Vector3 p1 = new Vector3(rect.X, top, 0.0f); - Vector3 p2 = new Vector3(rect.X + rect.Width, top, 0.0f); - Vector3 p3 = new Vector3(p2.X, bottom, 0.0f); - Vector3 p4 = new Vector3(p1.X, bottom, 0.0f); + Vector3[] corners = new Vector3[4]; - renderer.vertices[renderer.positionInBuffer] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform); - renderer.vertices[renderer.positionInBuffer + 1] = new WaterVertex(p2, new Vector2(p2.X, -p2.Y), transform); - renderer.vertices[renderer.positionInBuffer + 2] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform); + corners[0] = new Vector3(rect.X, top, 0.0f); + corners[1] = new Vector3(rect.X + rect.Width, top, 0.0f); - renderer.vertices[renderer.positionInBuffer + 3] = new WaterVertex(p1, new Vector2(p1.X, -p1.Y), transform); - renderer.vertices[renderer.positionInBuffer + 4] = new WaterVertex(p3, new Vector2(p3.X, -p3.Y), transform); - renderer.vertices[renderer.positionInBuffer + 5] = new WaterVertex(p4, new Vector2(p4.X, -p4.Y), transform); + corners[2] = new Vector3(corners[1].X, bottom, 0.0f); + corners[3] = new Vector3(corners[0].X, bottom, 0.0f); - renderer.positionInBuffer += 6; + Vector2[] uvCoords = new Vector2[4]; + for (int i = 0; i < 4; i++ ) + { + uvCoords[i] = Vector2.Transform(new Vector2(corners[i].X, -corners[i].Y), transform); + } + + renderer.vertices[renderer.PositionInBuffer] = new VertexPositionTexture(corners[0], uvCoords[0]); + renderer.vertices[renderer.PositionInBuffer + 1] = new VertexPositionTexture(corners[1], uvCoords[1]); + renderer.vertices[renderer.PositionInBuffer + 2] = new VertexPositionTexture(corners[2], uvCoords[2]); + + renderer.vertices[renderer.PositionInBuffer + 3] = new VertexPositionTexture(corners[0], uvCoords[0]); + renderer.vertices[renderer.PositionInBuffer + 4] = new VertexPositionTexture(corners[2], uvCoords[2]); + renderer.vertices[renderer.PositionInBuffer + 5] = new VertexPositionTexture(corners[3], uvCoords[3]); + + renderer.PositionInBuffer += 6; return; } @@ -353,31 +360,39 @@ namespace Subsurface for (int i = start; i < end; i++) { - if (renderer.positionInBuffer > renderer.vertices.Length - 6) return; + if (renderer.PositionInBuffer > renderer.vertices.Length - 6) return; - Vector3 p1 = new Vector3(x, top, 0.0f); - Vector3 p4 = new Vector3(p1.X, surface + waveY[i], 0.0f); + Vector3[] corners = new Vector3[4]; + + corners[0] = new Vector3(x, top, 0.0f); + corners[3] = new Vector3(corners[0].X, surface + waveY[i], 0.0f); //skip adjacent "water rects" if the surface of the water is roughly at the same position int width = WaveWidth; - while (i("effects"); #if WINDOWS - byte[] bytecode = File.ReadAllBytes("Content/effects.mgfx"); + byte[] bytecode = File.ReadAllBytes("Content/watershader.mgfx"); #endif #if LINUX byte[] bytecode = File.ReadAllBytes("Content/effects_linux.mgfx"); #endif - effect = new Effect(graphicsDevice, bytecode); + waterEffect = new Effect(graphicsDevice, bytecode); - //Texture2D waterBumpMap = Game1.textureLoader.FromFile("Content/waterbump.jpg"); - //effect.Parameters["xBump"].SetValue(waterBumpMap); - //effect.Parameters["xWaveLength"].SetValue(0.5f); - //effect.Parameters["xWaveHeight"].SetValue(0.03f); - effect.Parameters["xProjection"].SetValue(Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1)); - effect.Parameters["xColor"].SetValue(new Vector4(0.75f, 0.8f, 0.9f, 1.0f)); - effect.Parameters["xBlurDistance"].SetValue(0.0005f); + waterTexture = Game1.TextureLoader.FromFile("Content/waterbump.jpg"); + waterEffect.Parameters["xWaveWidth"].SetValue(0.1f); + waterEffect.Parameters["xWaveHeight"].SetValue(0.1f); + waterEffect.Parameters["xBlurDistance"].SetValue(0.0007f); - effect.Parameters["xWaterBumpMap"].SetValue(Game1.TextureLoader.FromFile("Content/waterbump.jpg")); - effect.Parameters["xWaveWidth"].SetValue(0.1f); - effect.Parameters["xWaveHeight"].SetValue(0.1f); + if (basicEffect==null) + { + basicEffect = new BasicEffect(Game1.CurrGraphicsDevice); + basicEffect.VertexColorEnabled = false; - vertexBuffer = new VertexBuffer(graphicsDevice, WaterVertex.VertexDeclaration, DefaultBufferSize, BufferUsage.WriteOnly); + basicEffect.TextureEnabled = true; + } } - public void RenderBack(GraphicsDevice graphicsDevice, RenderTarget2D texture, Matrix transform) - { - WaterVertex[] verts = new WaterVertex[6]; + public void RenderBack (SpriteBatch spriteBatch, RenderTarget2D texture, Matrix transform) + { + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearWrap); - // create the four corners of our triangle. - Vector3 p1 = new Vector3(-graphicsDevice.Viewport.Width / 2.0f, graphicsDevice.Viewport.Height / 2.0f, 0.0f); - Vector3 p2 = new Vector3(-p1.X, p1.Y, 0.0f); - - Vector3 p3 = new Vector3(p2.X, -p1.Y, 0.0f); - Vector3 p4 = new Vector3(p1.X, -p1.Y, 0.0f); - - verts[0] = new WaterVertex(p1, new Vector2(0, 0)); - verts[1] = new WaterVertex(p2, new Vector2(1, 0)); - verts[2] = new WaterVertex(p3, new Vector2(1, 1)); - - verts[3] = new WaterVertex(p1, new Vector2(0, 0)); - verts[4] = new WaterVertex(p3, new Vector2(1, 1)); - verts[5] = new WaterVertex(p4, new Vector2(0, 1)); - - vertexBuffer.SetData(verts); + waterEffect.CurrentTechnique = waterEffect.Techniques["WaterShader"]; + waterEffect.Parameters["xTexture"].SetValue(texture); + waterEffect.Parameters["xWavePos"].SetValue(wavePos); + waterEffect.CurrentTechnique.Passes[0].Apply(); wavePos.X += 0.0001f; wavePos.Y += 0.0001f; - effect.Parameters["xWavePos"].SetValue(wavePos); + spriteBatch.Draw(waterTexture, new Rectangle(0,0,Game1.GraphicsWidth, Game1.GraphicsHeight), Color.White); - effect.CurrentTechnique = effect.Techniques["WaterShader"]; - effect.Parameters["xTexture"].SetValue(texture); - effect.Parameters["xView"].SetValue(Matrix.Identity); - - foreach (EffectPass pass in effect.CurrentTechnique.Passes) - { - pass.Apply(); - -#if WINDOWS - graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, verts, 0, verts.Length / 3, WaterVertex.VertexDeclaration); -#endif -#if LINUX - //graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, verts, 0, verts.Length / 3, WaterVertex.VertexDeclaration, ); -#endif - } + spriteBatch.End(); } public void Render(GraphicsDevice graphicsDevice, Camera cam, RenderTarget2D texture, Matrix transform) @@ -128,22 +67,16 @@ namespace Subsurface if (vertices == null) return; if (vertices.Length < 0) return; - vertexBuffer.SetData(vertices); + basicEffect.Texture = texture; - effect.Parameters["xBumpPos"].SetValue(cam.Position / Game1.GraphicsWidth / cam.Zoom); + basicEffect.View = Matrix.Identity; + basicEffect.World = cam.ShaderTransform + * Matrix.CreateOrthographic(Game1.GraphicsWidth, Game1.GraphicsHeight, -1, 1) * 0.5f; + + basicEffect.CurrentTechnique.Passes[0].Apply(); - effect.CurrentTechnique = effect.Techniques["EmptyShader"]; - effect.Parameters["xTexture"].SetValue(texture); - effect.Parameters["xView"].SetValue(transform); - - foreach (EffectPass pass in effect.CurrentTechnique.Passes) - { - pass.Apply(); - -#if WINDOWS - graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length / 3, WaterVertex.VertexDeclaration); -#endif - } + graphicsDevice.SamplerStates[0] = SamplerState.LinearWrap; + graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length / 3); } public void Dispose() @@ -154,22 +87,20 @@ namespace Subsurface protected virtual void Dispose(bool disposing) { - if (disposing) + if (!disposing) return; + + if (waterEffect != null) { - if (vertexBuffer != null) - { - vertexBuffer.Dispose(); - vertexBuffer = null; - } - - if (effect != null) - { - effect.Dispose(); - effect = null; - } + waterEffect.Dispose(); + waterEffect = null; } - } + if (basicEffect != null) + { + basicEffect.Dispose(); + basicEffect = null; + } + } } } diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index df8d0947b..eb175592c 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -571,7 +571,6 @@ namespace Subsurface.Networking client.characterInfo.Job = new Job(client.assignedJob); } - //todo: fix if (characterInfo != null) { characterInfo.Job = new Job(Game1.NetLobbyScreen.JobPreferences[0]); diff --git a/Subsurface/Source/PlayerInput.cs b/Subsurface/Source/PlayerInput.cs index a6427ac94..913144525 100644 --- a/Subsurface/Source/PlayerInput.cs +++ b/Subsurface/Source/PlayerInput.cs @@ -56,10 +56,6 @@ namespace Subsurface stateQueue = false; return value; } - //set - //{ - // stateQueue = value; - //} } public void Reset() @@ -168,6 +164,23 @@ namespace Subsurface if (timeSinceClick < doubleClickDelay) doubleClicked = true; timeSinceClick = 0.0; } + +#if LINUX + foreach (Keys key in keyboardState.GetPressedKeys()) + { + if (!oldKeyboardState.IsKeyUp(key)) continue; + + char character = (char)key; + + if (keyboardState.IsKeyUp(Keys.LeftShift) && keyboardState.IsKeyUp(Keys.RightShift)) + { + character = char.ToLower(character); + } + + EventInput.EventInput.OnCharEntered(character); + } +#endif + } } } diff --git a/Subsurface/Source/Program.cs b/Subsurface/Source/Program.cs index 0ee45e543..278d37812 100644 --- a/Subsurface/Source/Program.cs +++ b/Subsurface/Source/Program.cs @@ -5,8 +5,10 @@ using System.IO; using System.Reflection; using System.Text; +#if WINDOWS using System.Management; using System.Windows.Forms; +#endif #endregion @@ -70,7 +72,6 @@ namespace Subsurface sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); - sb.AppendLine(" Graphics device handle: " + game.GraphicsDevice.Handle.ToString()); sb.AppendLine("\n"); sb.AppendLine("Exception: "+exception.Message); sb.AppendLine("Target site: " +exception.TargetSite.ToString()); @@ -86,10 +87,11 @@ namespace Subsurface sw.WriteLine(sb.ToString()); - + #if WINDOWS MessageBox.Show( "A crash report (''crashreport.txt'') was saved in the root folder of the game."+ " If you'd like to help fix this bug, please make a bug report on the Undertow Games forum with the report attached.", "Oops! Subsurface just crashed.", MessageBoxButtons.OK, MessageBoxIcon.Error); + #endif sw.Close(); } diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index e51680264..a7f20762d 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -208,7 +208,7 @@ namespace Subsurface spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend); - spriteBatch.Draw(renderTarget, new Rectangle(0, 0, Game1.GraphicsWidth, Game1.GraphicsHeight), Color.White); + spriteBatch.Draw(renderTarget, new Rectangle(0, 0, Game1.GraphicsWidth, Game1.GraphicsHeight), new Color(0.75f, 0.8f, 0.9f, 1.0f)); spriteBatch.End(); BlendState blend = new BlendState(); @@ -246,10 +246,10 @@ namespace Subsurface //2. pass the renderTarget to the water shader to do the water effect //---------------------------------------------------------------------------------------- - Hull.renderer.RenderBack(graphics, renderTargetWater, Cam.ShaderTransform); + Hull.renderer.RenderBack(spriteBatch, renderTargetWater, Cam.ShaderTransform); Array.Clear(Hull.renderer.vertices, 0, Hull.renderer.vertices.Length); - Hull.renderer.positionInBuffer = 0; + Hull.renderer.PositionInBuffer = 0; foreach (Hull hull in Hull.hullList) { hull.Render(graphics, cam); diff --git a/Subsurface/Source/Utils/TextureLoader.cs b/Subsurface/Source/Utils/TextureLoader.cs index 0533f07e4..229261e98 100644 --- a/Subsurface/Source/Utils/TextureLoader.cs +++ b/Subsurface/Source/Utils/TextureLoader.cs @@ -51,7 +51,11 @@ namespace Subsurface #endif #if LINUX using (Stream fileStream = File.OpenRead(path)) - return Texture2D.FromStream(_graphicsDevice, fileStream);// .FromStream(fileStream, preMultiplyAlpha); + { + var texture = Texture2D.FromStream(_graphicsDevice, fileStream); + texture = PreMultiplyAlpha(texture); + return texture; + } #endif } @@ -87,43 +91,46 @@ namespace Subsurface texture = Texture2D.FromStream(_graphicsDevice, stream); } - if (preMultiplyAlpha) - { - // Setup a render target to hold our final texture which will have premulitplied alpha values - using (RenderTarget2D renderTarget = new RenderTarget2D(_graphicsDevice, texture.Width, texture.Height)) - { - Viewport viewportBackup = _graphicsDevice.Viewport; - _graphicsDevice.SetRenderTarget(renderTarget); - _graphicsDevice.Clear(Color.Black); - - // Multiply each color by the source alpha, and write in just the color values into the final texture - _spriteBatch.Begin(SpriteSortMode.Immediate, BlendColorBlendState); - _spriteBatch.Draw(texture, texture.Bounds, Color.White); - _spriteBatch.End(); - - // Now copy over the alpha values from the source texture to the final one, without multiplying them - _spriteBatch.Begin(SpriteSortMode.Immediate, BlendAlphaBlendState); - _spriteBatch.Draw(texture, texture.Bounds, Color.White); - _spriteBatch.End(); - - // Release the GPU back to drawing to the screen - _graphicsDevice.SetRenderTarget(null); - _graphicsDevice.Viewport = viewportBackup; - - // Store data from render target because the RenderTarget2D is volatile - Color[] data = new Color[texture.Width * texture.Height]; - renderTarget.GetData(data); - - // Unset texture from graphic device and set modified data back to it - _graphicsDevice.Textures[0] = null; - texture.SetData(data); - } - - } + if (preMultiplyAlpha) texture = PreMultiplyAlpha(texture); return texture; } #endif + + private Texture2D PreMultiplyAlpha(Texture2D texture) + { + // Setup a render target to hold our final texture which will have premulitplied alpha values + using (RenderTarget2D renderTarget = new RenderTarget2D(_graphicsDevice, texture.Width, texture.Height)) + { + Viewport viewportBackup = _graphicsDevice.Viewport; + _graphicsDevice.SetRenderTarget(renderTarget); + _graphicsDevice.Clear(Color.Black); + + // Multiply each color by the source alpha, and write in just the color values into the final texture + _spriteBatch.Begin(SpriteSortMode.Immediate, BlendColorBlendState); + _spriteBatch.Draw(texture, texture.Bounds, Color.White); + _spriteBatch.End(); + + // Now copy over the alpha values from the source texture to the final one, without multiplying them + _spriteBatch.Begin(SpriteSortMode.Immediate, BlendAlphaBlendState); + _spriteBatch.Draw(texture, texture.Bounds, Color.White); + _spriteBatch.End(); + + // Release the GPU back to drawing to the screen + _graphicsDevice.SetRenderTarget(null); + _graphicsDevice.Viewport = viewportBackup; + + // Store data from render target because the RenderTarget2D is volatile + Color[] data = new Color[texture.Width * texture.Height]; + renderTarget.GetData(data); + + // Unset texture from graphic device and set modified data back to it + _graphicsDevice.Textures[0] = null; + texture.SetData(data); + } + + return texture; + } private static readonly BlendState BlendColorBlendState; diff --git a/Subsurface/Subsurface.csproj b/Subsurface/Subsurface.csproj index 26e46c3d1..12ee8651d 100644 --- a/Subsurface/Subsurface.csproj +++ b/Subsurface/Subsurface.csproj @@ -943,6 +943,9 @@ PreserveNewest + + PreserveNewest + diff --git a/Subsurface/Subsurface.csproj.user b/Subsurface/Subsurface.csproj.user index 505c3a0bf..693505ea4 100644 --- a/Subsurface/Subsurface.csproj.user +++ b/Subsurface/Subsurface.csproj.user @@ -9,6 +9,6 @@ en-US false - ProjectFiles + ShowAllFiles \ No newline at end of file diff --git a/Subsurface_Solution.sln b/Subsurface_Solution.sln index 9d5b8a22c..09f07cf09 100644 --- a/Subsurface_Solution.sln +++ b/Subsurface_Solution.sln @@ -307,7 +307,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection EndGlobal diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 67016dc49..bd0ea0d9c 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ