initial commit
17
Base/Basics.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
internal class Basics
|
||||
{
|
||||
public static void DrawStringCenter(SpriteFont font, string text, Rectangle position, Color color)
|
||||
{
|
||||
var textSize = font.MeasureString(text);
|
||||
var drawPosition = new Vector2(
|
||||
(int)(position.X + position.Width / 2 - textSize.X / 2),
|
||||
(int)(position.Y + position.Height / 2 - textSize.Y / 2));
|
||||
Game1.SpriteBatch.DrawString(font, text, drawPosition, color);
|
||||
}
|
||||
}
|
||||
}
|
73
Base/Box.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
public struct Box
|
||||
{
|
||||
public static readonly Box Empty = new Box();
|
||||
|
||||
public float X;
|
||||
public float Y;
|
||||
public float Z;
|
||||
|
||||
public float Width;
|
||||
public float Height;
|
||||
public float Depth;
|
||||
|
||||
public float Left => X;
|
||||
public float Right => X + Width;
|
||||
|
||||
public float Back => Y;
|
||||
public float Front => Y + Height;
|
||||
|
||||
public float Top => Z + Depth;
|
||||
public float Bottom => Z;
|
||||
|
||||
public Vector2 Center => new Vector2(X + Width / 2, Y + Height / 2);
|
||||
|
||||
public RectangleF Rectangle() => new RectangleF(X, Y, Width, Height);
|
||||
|
||||
public Box(float x, float y, float z, float width, float height, float depth)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
|
||||
Width = width;
|
||||
Height = height;
|
||||
Depth = depth;
|
||||
}
|
||||
|
||||
public bool Intersects(Box value)
|
||||
{
|
||||
return value.Left < Right && Left < value.Right &&
|
||||
value.Back < Front && Back < value.Front &&
|
||||
value.Bottom < Top && Bottom < value.Top;
|
||||
}
|
||||
|
||||
public bool Contains(Box value)
|
||||
{
|
||||
return Left <= value.Left && value.Right <= Right &&
|
||||
Back <= value.Back && value.Front <= Front &&
|
||||
Bottom <= value.Bottom && value.Top <= Top;
|
||||
}
|
||||
|
||||
public bool Contains(Vector2 value)
|
||||
{
|
||||
return Left <= value.X && value.X <= Right &&
|
||||
Back <= value.Y && value.Y <= Front;
|
||||
}
|
||||
|
||||
public static bool operator ==(Box a, Box b)
|
||||
{
|
||||
return a.X == b.X && a.Y == b.Y && a.Z == b.Z &&
|
||||
a.Width == b.Width && a.Height == b.Height && a.Depth == b.Depth;
|
||||
}
|
||||
|
||||
public static bool operator !=(Box a, Box b)
|
||||
{
|
||||
return a.X != b.X || a.Y != b.Y || a.Z != b.Z &&
|
||||
a.Width != b.Width || a.Height != b.Height || a.Depth != b.Depth;
|
||||
}
|
||||
}
|
||||
}
|
28
Base/DoubleAverage.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
public class DoubleAverage
|
||||
{
|
||||
public double Average;
|
||||
|
||||
private readonly double[] _timeCounts;
|
||||
private int _currentIndex;
|
||||
|
||||
public DoubleAverage(int size)
|
||||
{
|
||||
_timeCounts = new double[size];
|
||||
}
|
||||
|
||||
public void AddValue(double value)
|
||||
{
|
||||
_timeCounts[_currentIndex] = value;
|
||||
|
||||
_currentIndex++;
|
||||
if (_currentIndex >= _timeCounts.Length)
|
||||
_currentIndex = 0;
|
||||
|
||||
Average = _timeCounts.Average();
|
||||
}
|
||||
}
|
||||
}
|
376
Base/InputHandler.cs
Normal file
|
@ -0,0 +1,376 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
#region InputCharacter
|
||||
|
||||
internal class InputCharacter
|
||||
{
|
||||
private readonly string _upper;
|
||||
private readonly string _lower;
|
||||
private readonly string _alt;
|
||||
|
||||
private readonly Keys _code;
|
||||
|
||||
public InputCharacter(string upper, string lower, string alt, Keys code)
|
||||
{
|
||||
_upper = upper;
|
||||
_lower = lower;
|
||||
_alt = alt;
|
||||
_code = code;
|
||||
}
|
||||
|
||||
public InputCharacter(string upper, string lower, Keys code) :
|
||||
this(upper, lower, lower, code)
|
||||
{ }
|
||||
|
||||
public string ReturnCharacter(bool shiftDown, bool altDown)
|
||||
{
|
||||
return altDown ? _alt : shiftDown ? _upper : _lower;
|
||||
}
|
||||
|
||||
public Keys ReturnKey()
|
||||
{
|
||||
return _code;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
internal class InputHandler : GameComponent
|
||||
{
|
||||
private static List<InputCharacter> _alphabet;
|
||||
|
||||
public static KeyboardState KeyboardState => _keyboardState;
|
||||
|
||||
public static KeyboardState LastKeyboardState => _lastKeyboardState;
|
||||
|
||||
public static MouseState MouseState => _mouseState;
|
||||
|
||||
public static MouseState LastMousState => _lastMouseState;
|
||||
|
||||
private static KeyboardState _keyboardState;
|
||||
private static KeyboardState _lastKeyboardState;
|
||||
|
||||
private static MouseState _mouseState;
|
||||
private static MouseState _lastMouseState;
|
||||
|
||||
private static GamePadState _gamePadState;
|
||||
private static GamePadState _lastGamePadState;
|
||||
private static float _gamePadAccuracy = 0.2f;
|
||||
|
||||
#region Constructor Region
|
||||
|
||||
public InputHandler(Game game)
|
||||
: base(game)
|
||||
{
|
||||
_keyboardState = Keyboard.GetState();
|
||||
_mouseState = Mouse.GetState();
|
||||
|
||||
_alphabet = new List<InputCharacter>();
|
||||
|
||||
// TODO_End: Important! Replace this method to support different keyboard layouts
|
||||
/* Alphabet. */
|
||||
_alphabet.Add(new InputCharacter("A", "a", Keys.A));
|
||||
_alphabet.Add(new InputCharacter("B", "b", Keys.B));
|
||||
_alphabet.Add(new InputCharacter("C", "c", Keys.C));
|
||||
_alphabet.Add(new InputCharacter("D", "d", Keys.D));
|
||||
_alphabet.Add(new InputCharacter("E", "e", "€", Keys.E));
|
||||
_alphabet.Add(new InputCharacter("F", "f", Keys.F));
|
||||
_alphabet.Add(new InputCharacter("G", "g", Keys.G));
|
||||
_alphabet.Add(new InputCharacter("H", "h", Keys.H));
|
||||
_alphabet.Add(new InputCharacter("I", "i", Keys.I));
|
||||
_alphabet.Add(new InputCharacter("J", "j", Keys.J));
|
||||
_alphabet.Add(new InputCharacter("K", "k", Keys.K));
|
||||
_alphabet.Add(new InputCharacter("L", "l", Keys.L));
|
||||
_alphabet.Add(new InputCharacter("M", "m", "µ", Keys.M));
|
||||
_alphabet.Add(new InputCharacter("N", "n", Keys.N));
|
||||
_alphabet.Add(new InputCharacter("O", "o", Keys.O));
|
||||
_alphabet.Add(new InputCharacter("P", "p", Keys.P));
|
||||
_alphabet.Add(new InputCharacter("Q", "q", "@", Keys.Q));
|
||||
_alphabet.Add(new InputCharacter("R", "r", Keys.R));
|
||||
_alphabet.Add(new InputCharacter("S", "s", Keys.S));
|
||||
_alphabet.Add(new InputCharacter("T", "t", Keys.T));
|
||||
_alphabet.Add(new InputCharacter("U", "u", Keys.U));
|
||||
_alphabet.Add(new InputCharacter("V", "v", Keys.V));
|
||||
_alphabet.Add(new InputCharacter("W", "w", Keys.W));
|
||||
_alphabet.Add(new InputCharacter("X", "x", Keys.X));
|
||||
_alphabet.Add(new InputCharacter("Y", "y", Keys.Y));
|
||||
_alphabet.Add(new InputCharacter("Z", "z", Keys.Z));
|
||||
|
||||
/* Dezimalzahlen. */
|
||||
_alphabet.Add(new InputCharacter("!", "1", Keys.D1));
|
||||
_alphabet.Add(new InputCharacter("\"", "2", "²", Keys.D2));
|
||||
_alphabet.Add(new InputCharacter("§", "3", "³", Keys.D3));
|
||||
_alphabet.Add(new InputCharacter("$", "4", Keys.D4));
|
||||
_alphabet.Add(new InputCharacter("%", "5", Keys.D5));
|
||||
_alphabet.Add(new InputCharacter("&", "6", "|", Keys.D6));
|
||||
_alphabet.Add(new InputCharacter("/", "7", "{", Keys.D7));
|
||||
_alphabet.Add(new InputCharacter("(", "8", "[", Keys.D8));
|
||||
_alphabet.Add(new InputCharacter(")", "9", "]", Keys.D9));
|
||||
_alphabet.Add(new InputCharacter("=", "0", "}", Keys.D0));
|
||||
|
||||
|
||||
/* Sonderelemente. */
|
||||
_alphabet.Add(new InputCharacter(" ", " ", Keys.Space));
|
||||
//InputHandler.alphabet.Add(new InputCharacter("Ü", "ü", Keys.OemSemicolon));
|
||||
//InputHandler.alphabet.Add(new InputCharacter("Ö", "ö", Keys.OemTilde));
|
||||
//InputHandler.alphabet.Add(new InputCharacter("Ä", "ä", Keys.OemQuotes));
|
||||
_alphabet.Add(new InputCharacter(";", ",", Keys.OemComma));
|
||||
_alphabet.Add(new InputCharacter("*", "+", "~", Keys.OemPlus));
|
||||
_alphabet.Add(new InputCharacter("'", "#", Keys.OemQuestion));
|
||||
_alphabet.Add(new InputCharacter(":", ".", Keys.OemPeriod));
|
||||
_alphabet.Add(new InputCharacter("_", "-", Keys.OemMinus));
|
||||
_alphabet.Add(new InputCharacter("?", "", Keys.OemOpenBrackets));
|
||||
_alphabet.Add(new InputCharacter(">", "<", "|", Keys.OemBackslash));
|
||||
//InputHandler.alphabet.Add(new InputCharacter("`", "´", Keys.OemCloseBrackets));
|
||||
|
||||
//InputHandler.alphabet.Add(new InputCharacter("°", "^", Keys.OemPipe));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override void Update(GameTime gameTime)
|
||||
{
|
||||
_lastKeyboardState = _keyboardState;
|
||||
_keyboardState = Keyboard.GetState();
|
||||
|
||||
_lastMouseState = _mouseState;
|
||||
_mouseState = Mouse.GetState();
|
||||
|
||||
_lastGamePadState = _gamePadState;
|
||||
_gamePadState = GamePad.GetState(0);
|
||||
|
||||
// if the game was not active the last mousestate is uninteresting
|
||||
if (!Game1.WasActive)
|
||||
ResetInputState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// set the last input state to the current state
|
||||
/// </summary>
|
||||
public static void ResetInputState()
|
||||
{
|
||||
_lastKeyboardState = _keyboardState;
|
||||
_lastMouseState = _mouseState;
|
||||
_lastGamePadState = _gamePadState;
|
||||
}
|
||||
|
||||
public static bool LastKeyDown(Keys key)
|
||||
{
|
||||
return _lastKeyboardState.IsKeyDown(key);
|
||||
}
|
||||
|
||||
public static bool KeyDown(Keys key)
|
||||
{
|
||||
return _keyboardState.IsKeyDown(key);
|
||||
}
|
||||
|
||||
public static bool KeyPressed(Keys key)
|
||||
{
|
||||
return _keyboardState.IsKeyDown(key) &&
|
||||
_lastKeyboardState.IsKeyUp(key);
|
||||
}
|
||||
|
||||
public static bool KeyReleased(Keys key)
|
||||
{
|
||||
return _keyboardState.IsKeyUp(key) &&
|
||||
_lastKeyboardState.IsKeyDown(key);
|
||||
}
|
||||
|
||||
public static List<Keys> GetPressedKeys()
|
||||
{
|
||||
var pressedKeys = new List<Keys>();
|
||||
var downKeys = _keyboardState.GetPressedKeys();
|
||||
|
||||
for (var i = 0; i < downKeys.Length; i++)
|
||||
{
|
||||
if (KeyPressed(downKeys[i]))
|
||||
pressedKeys.Add(downKeys[i]);
|
||||
}
|
||||
|
||||
return pressedKeys;
|
||||
}
|
||||
|
||||
public static List<Buttons> GetPressedButtons()
|
||||
{
|
||||
var pressedKeys = new List<Buttons>();
|
||||
|
||||
foreach (Buttons button in Enum.GetValues(typeof(Buttons)))
|
||||
{
|
||||
if (GamePadPressed(button))
|
||||
pressedKeys.Add(button);
|
||||
}
|
||||
|
||||
return pressedKeys;
|
||||
}
|
||||
|
||||
public static bool LastGamePadDown(Buttons button)
|
||||
{
|
||||
return _lastGamePadState.IsButtonDown(button);
|
||||
}
|
||||
|
||||
public static bool GamePadDown(Buttons button)
|
||||
{
|
||||
return _gamePadState.IsButtonDown(button);
|
||||
}
|
||||
|
||||
public static bool GamePadPressed(Buttons button)
|
||||
{
|
||||
return _gamePadState.IsButtonDown(button) &&
|
||||
_lastGamePadState.IsButtonUp(button);
|
||||
}
|
||||
|
||||
public static bool GamePadReleased(Buttons button)
|
||||
{
|
||||
return _gamePadState.IsButtonUp(button) &&
|
||||
_lastGamePadState.IsButtonDown(button);
|
||||
}
|
||||
|
||||
|
||||
public static bool GamePadLeftStick(Vector2 dir)
|
||||
{
|
||||
return ((dir.X < 0 && _gamePadState.ThumbSticks.Left.X < -_gamePadAccuracy) || (dir.X > 0 && _gamePadState.ThumbSticks.Left.X > _gamePadAccuracy) ||
|
||||
(dir.Y < 0 && _gamePadState.ThumbSticks.Left.Y < -_gamePadAccuracy) || (dir.Y > 0 && _gamePadState.ThumbSticks.Left.Y > _gamePadAccuracy));
|
||||
}
|
||||
public static bool LastGamePadLeftStick(Vector2 dir)
|
||||
{
|
||||
return ((dir.X < 0 && _lastGamePadState.ThumbSticks.Left.X < -_gamePadAccuracy) || (dir.X > 0 && _lastGamePadState.ThumbSticks.Left.X > _gamePadAccuracy) ||
|
||||
(dir.Y < 0 && _lastGamePadState.ThumbSticks.Left.Y < -_gamePadAccuracy) || (dir.Y > 0 && _lastGamePadState.ThumbSticks.Left.Y > _gamePadAccuracy));
|
||||
}
|
||||
|
||||
public static bool GamePadRightStick(Vector2 dir)
|
||||
{
|
||||
return ((dir.X < 0 && _gamePadState.ThumbSticks.Right.X < -_gamePadAccuracy) || (dir.X > 0 && _gamePadState.ThumbSticks.Right.X > _gamePadAccuracy) ||
|
||||
(dir.Y < 0 && _gamePadState.ThumbSticks.Right.Y < -_gamePadAccuracy) || (dir.Y > 0 && _gamePadState.ThumbSticks.Right.Y > _gamePadAccuracy));
|
||||
}
|
||||
|
||||
#region Mouse Region
|
||||
|
||||
//scroll
|
||||
public static bool MouseWheelUp()
|
||||
{
|
||||
return _mouseState.ScrollWheelValue > _lastMouseState.ScrollWheelValue;
|
||||
}
|
||||
public static bool MouseWheelDown()
|
||||
{
|
||||
return _mouseState.ScrollWheelValue < _lastMouseState.ScrollWheelValue;
|
||||
}
|
||||
|
||||
//down
|
||||
public static bool MouseLeftDown()
|
||||
{
|
||||
return _mouseState.LeftButton == ButtonState.Pressed;
|
||||
}
|
||||
public static bool MouseLeftDown(Rectangle rectangle)
|
||||
{
|
||||
return MouseIntersect(rectangle) && MouseLeftDown();
|
||||
}
|
||||
public static bool MouseRightDown()
|
||||
{
|
||||
return _mouseState.RightButton == ButtonState.Pressed;
|
||||
}
|
||||
public static bool MouseMiddleDown()
|
||||
{
|
||||
return _mouseState.MiddleButton == ButtonState.Pressed;
|
||||
}
|
||||
|
||||
//start
|
||||
public static bool MouseLeftStart()
|
||||
{
|
||||
return _mouseState.LeftButton == ButtonState.Pressed && _lastMouseState.LeftButton == ButtonState.Released;
|
||||
}
|
||||
public static bool MouseRightStart()
|
||||
{
|
||||
return _mouseState.RightButton == ButtonState.Pressed && _lastMouseState.RightButton == ButtonState.Released;
|
||||
}
|
||||
public static bool MouseMiddleStart()
|
||||
{
|
||||
return _mouseState.MiddleButton == ButtonState.Pressed && _lastMouseState.MiddleButton == ButtonState.Released;
|
||||
}
|
||||
|
||||
//released
|
||||
public static bool MouseLeftReleased()
|
||||
{
|
||||
return _mouseState.LeftButton == ButtonState.Released && _lastMouseState.LeftButton == ButtonState.Pressed;
|
||||
}
|
||||
public static bool MouseRightReleased()
|
||||
{
|
||||
return _mouseState.RightButton == ButtonState.Released && _lastMouseState.RightButton == ButtonState.Pressed;
|
||||
}
|
||||
|
||||
//pressed
|
||||
public static bool MouseLeftPressed()
|
||||
{
|
||||
return _mouseState.LeftButton == ButtonState.Pressed && _lastMouseState.LeftButton == ButtonState.Released;
|
||||
}
|
||||
public static bool MouseLeftPressed(Rectangle rectangle)
|
||||
{
|
||||
return rectangle.Contains(MousePosition()) && MouseLeftPressed();
|
||||
}
|
||||
|
||||
public static bool MouseRightPressed()
|
||||
{
|
||||
return _mouseState.RightButton == ButtonState.Pressed && _lastMouseState.RightButton == ButtonState.Released;
|
||||
}
|
||||
public static bool MouseRightPressed(Rectangle rectangle)
|
||||
{
|
||||
return MouseIntersect(rectangle) && MouseRightPressed();
|
||||
}
|
||||
|
||||
public static bool MouseIntersect(Rectangle rectangle)
|
||||
{
|
||||
return rectangle.Contains(MousePosition());
|
||||
}
|
||||
|
||||
public static Point MousePosition()
|
||||
{
|
||||
return _mouseState.Position;
|
||||
}
|
||||
public static Point LastMousePosition()
|
||||
{
|
||||
return _lastMouseState.Position;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region return text + return number
|
||||
|
||||
/// <summary>
|
||||
/// returns the pressed keys if they are in the InputHandler.alphabet
|
||||
/// only returns one key at a time
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string ReturnCharacter()
|
||||
{
|
||||
var shiftDown = _keyboardState.IsKeyDown(Keys.LeftShift) || _keyboardState.IsKeyDown(Keys.RightShift);
|
||||
var altDown = _keyboardState.IsKeyDown(Keys.LeftAlt) || _keyboardState.IsKeyDown(Keys.RightAlt);
|
||||
|
||||
//var pressedKeys = _keyboardState.GetPressedKeys();
|
||||
|
||||
foreach (var character in _alphabet)
|
||||
{
|
||||
if (KeyPressed(character.ReturnKey()))
|
||||
return character.ReturnCharacter(shiftDown, altDown);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns pressed number from d0-d9 and numpad0-numpad9
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int ReturnNumber()
|
||||
{
|
||||
for (var i = 0; i < 10; i++)
|
||||
if (KeyPressed(Keys.D0 + i) || KeyPressed(Keys.NumPad0 + i))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
47
Base/ObjActivator.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
public class ObjActivator
|
||||
{
|
||||
public delegate T ObjectActivator<T>(params object[] args);
|
||||
|
||||
public static ObjectActivator<T> GetActivator<T>(ConstructorInfo ctor)
|
||||
{
|
||||
var paramsInfo = ctor.GetParameters();
|
||||
|
||||
//create a single param of type object[]
|
||||
var param = Expression.Parameter(typeof(object[]), "args");
|
||||
|
||||
var argsExp = new Expression[paramsInfo.Length];
|
||||
|
||||
//pick each arg from the params array
|
||||
//and create a typed expression of them
|
||||
for (var i = 0; i < paramsInfo.Length; i++)
|
||||
{
|
||||
Expression index = Expression.Constant(i);
|
||||
Type paramType = paramsInfo[i].ParameterType;
|
||||
|
||||
Expression paramAccessorExp = Expression.ArrayIndex(param, index);
|
||||
|
||||
Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType);
|
||||
|
||||
argsExp[i] = paramCastExp;
|
||||
}
|
||||
|
||||
//make a NewExpression that calls the
|
||||
//ctor with the args we just created
|
||||
var newExp = Expression.New(ctor, argsExp);
|
||||
|
||||
//create a lambda with the New
|
||||
//Expression as body and our param object[] as arg
|
||||
var lambda = Expression.Lambda(typeof(ObjectActivator<T>), newExp, param);
|
||||
|
||||
//compile it
|
||||
ObjectActivator<T> compiled = (ObjectActivator<T>)lambda.Compile();
|
||||
return compiled;
|
||||
}
|
||||
}
|
||||
}
|
69
Base/RectangleF.cs
Normal file
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
public struct RectangleF
|
||||
{
|
||||
public static readonly RectangleF Empty = new RectangleF();
|
||||
|
||||
public float X;
|
||||
|
||||
public float Y;
|
||||
|
||||
public float Width;
|
||||
|
||||
public float Height;
|
||||
|
||||
public float Left => X;
|
||||
|
||||
public float Right => X + Width;
|
||||
|
||||
public float Top => Y;
|
||||
|
||||
public float Bottom => Y + Height;
|
||||
|
||||
public Vector2 Center => new Vector2(X + Width / 2, Y + Height / 2);
|
||||
|
||||
public RectangleF(float x, float y, float width, float height)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public bool Intersects(RectangleF second)
|
||||
{
|
||||
return second.Left < Right && Left < second.Right &&
|
||||
second.Top < Bottom && Top < second.Bottom;
|
||||
}
|
||||
|
||||
public bool Contains(RectangleF second)
|
||||
{
|
||||
return Left <= second.Left && second.Right <= Right &&
|
||||
Top <= second.Top && second.Bottom <= Bottom;
|
||||
}
|
||||
|
||||
public bool Contains(Vector2 position)
|
||||
{
|
||||
return Left <= position.X && position.X <= Right &&
|
||||
Top <= position.Y && position.Y <= Bottom;
|
||||
}
|
||||
|
||||
public RectangleF GetIntersection(RectangleF second)
|
||||
{
|
||||
var left = Math.Max(Left, second.Left);
|
||||
var right = Math.Min(Right, second.Right);
|
||||
var top = Math.Max(Top, second.Top);
|
||||
var down = Math.Min(Bottom, second.Bottom);
|
||||
|
||||
return new RectangleF(left, top, right - left, down - top);
|
||||
}
|
||||
|
||||
public static implicit operator RectangleF(Rectangle rectangle)
|
||||
{
|
||||
return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
|
||||
}
|
||||
}
|
||||
}
|
47
Base/SimpleFps.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
// source:
|
||||
// http://community.monogame.net/t/a-simple-monogame-fps-display-class/10545
|
||||
|
||||
public class SimpleFps
|
||||
{
|
||||
public double MsgFrequency = 1.0f;
|
||||
public string Msg = "";
|
||||
|
||||
private double _frames;
|
||||
private double _updates;
|
||||
private double _elapsed;
|
||||
private double _last;
|
||||
private double _now;
|
||||
|
||||
/// <summary>
|
||||
/// The msgFrequency here is the reporting time to update the message.
|
||||
/// </summary>
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
_now = gameTime.TotalGameTime.TotalSeconds;
|
||||
_elapsed = _now - _last;
|
||||
|
||||
if (_elapsed > MsgFrequency)
|
||||
{
|
||||
Msg = $"fps: {_frames / _elapsed,7:N3}" +
|
||||
$"\nupdates: {_updates,3:N0}" +
|
||||
$"\nframes: {_frames,3:N0}" +
|
||||
$"\nelapsed time: {_elapsed,7:N3}";
|
||||
|
||||
_frames = 0;
|
||||
_updates = 0;
|
||||
_last = _now;
|
||||
}
|
||||
|
||||
_updates++;
|
||||
}
|
||||
|
||||
public void CountDraw()
|
||||
{
|
||||
_frames++;
|
||||
}
|
||||
}
|
||||
}
|
56
Base/StopWatchTracker.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
public class StopWatchTracker
|
||||
{
|
||||
private readonly Dictionary<string, TickCounter> _timespans = new Dictionary<string, TickCounter>();
|
||||
private readonly Stopwatch _stopWatch = new Stopwatch();
|
||||
|
||||
private string _timespanName;
|
||||
private readonly int _averageSize;
|
||||
|
||||
public StopWatchTracker(int averageSize)
|
||||
{
|
||||
_averageSize = averageSize;
|
||||
}
|
||||
|
||||
public void Start(string timespanName)
|
||||
{
|
||||
if (_timespanName != null)
|
||||
Stop();
|
||||
|
||||
_timespanName = timespanName;
|
||||
|
||||
_stopWatch.Reset();
|
||||
_stopWatch.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (_timespanName == null)
|
||||
return;
|
||||
|
||||
_stopWatch.Stop();
|
||||
|
||||
// add a new entry if the counter does not already exists
|
||||
if (!_timespans.ContainsKey(_timespanName))
|
||||
_timespans.Add(_timespanName, new TickCounter(_averageSize));
|
||||
|
||||
_timespans[_timespanName].AddTick(_stopWatch.ElapsedTicks);
|
||||
|
||||
_timespanName = null;
|
||||
}
|
||||
|
||||
public string GetString()
|
||||
{
|
||||
var strCounter = "";
|
||||
|
||||
foreach (var tickCounter in _timespans)
|
||||
strCounter += (strCounter == "" ? "" : "\n") + tickCounter.Key + ":\t" + tickCounter.Value.AverageTime;
|
||||
|
||||
return strCounter;
|
||||
}
|
||||
}
|
||||
}
|
28
Base/TickCount.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace ProjectZ.Base
|
||||
{
|
||||
public class TickCounter
|
||||
{
|
||||
public int AverageTime;
|
||||
|
||||
private readonly int[] _timeCounts;
|
||||
private int _currentIndex;
|
||||
|
||||
public TickCounter(int average)
|
||||
{
|
||||
_timeCounts = new int[average];
|
||||
}
|
||||
|
||||
public void AddTick(long tick)
|
||||
{
|
||||
_timeCounts[_currentIndex] = (int)tick;
|
||||
|
||||
_currentIndex++;
|
||||
if (_currentIndex >= _timeCounts.Length)
|
||||
_currentIndex = 0;
|
||||
|
||||
AverageTime = (int)_timeCounts.Average();
|
||||
}
|
||||
}
|
||||
}
|
76
Base/UI/UIManager.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiManager
|
||||
{
|
||||
public string CurrentScreen
|
||||
{
|
||||
get => _currentScreen;
|
||||
set => _currentScreen = value.ToUpper();
|
||||
}
|
||||
|
||||
private readonly List<UiElement> _elementList = new List<UiElement>();
|
||||
|
||||
private string _currentScreen;
|
||||
|
||||
public void Update()
|
||||
{
|
||||
//remove elements
|
||||
_elementList.RemoveAll(element => element.Remove);
|
||||
|
||||
foreach (var element in _elementList)
|
||||
if (element.Screens.Contains(_currentScreen))
|
||||
element.Update();
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
for (var i = 0; i < _elementList.Count; i++)
|
||||
if (_elementList[i].Screens.Contains(_currentScreen))
|
||||
if (_elementList[i].IsVisible)
|
||||
_elementList[i].Draw(spriteBatch);
|
||||
}
|
||||
|
||||
public void DrawBlur(SpriteBatch spriteBatch)
|
||||
{
|
||||
for (var i = 0; i < _elementList.Count; i++)
|
||||
if (_elementList[i].Screens.Contains(_currentScreen))
|
||||
if (_elementList[i].IsVisible)
|
||||
_elementList[i].DrawBlur(spriteBatch);
|
||||
}
|
||||
|
||||
public void SizeChanged()
|
||||
{
|
||||
foreach (var uiElement in _elementList)
|
||||
uiElement.SizeUpdate?.Invoke(uiElement);
|
||||
}
|
||||
|
||||
public UiElement AddElement(UiElement element)
|
||||
{
|
||||
if (element != null)
|
||||
_elementList.Add(element);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public UiElement GetElement(string elementId)
|
||||
{
|
||||
//search for the elementId
|
||||
for (var i = 0; i < _elementList.Count; i++)
|
||||
if (_elementList[i].ElementId == elementId)
|
||||
return _elementList[i];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveElement(string elementId, string screenId)
|
||||
{
|
||||
for (var i = 0; i < _elementList.Count; i++)
|
||||
if (_elementList[i].ElementId.Contains(elementId) && _elementList[i].Screens.Contains(screenId))
|
||||
_elementList[i].Remove = true;
|
||||
}
|
||||
}
|
||||
}
|
71
Base/UI/UiButton.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiButton : UiElement
|
||||
{
|
||||
public Texture2D ButtonIcon
|
||||
{
|
||||
get => _buttonIcon;
|
||||
set
|
||||
{
|
||||
_buttonIcon = value;
|
||||
UpdateIconRectangle();
|
||||
}
|
||||
}
|
||||
public bool Marked;
|
||||
|
||||
private Texture2D _buttonIcon;
|
||||
private Rectangle _iconRectangle;
|
||||
|
||||
public UiButton(Rectangle rectangle, SpriteFont font, string text, string elementId, string screen, UiFunction update, UiFunction click)
|
||||
: base(elementId, screen)
|
||||
{
|
||||
Rectangle = rectangle;
|
||||
Label = text;
|
||||
UpdateFunction = update;
|
||||
ClickFunction = click;
|
||||
|
||||
Font = font;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (!Selected || ClickFunction == null || !InputHandler.MouseLeftPressed()) return;
|
||||
|
||||
ClickFunction(this);
|
||||
InputHandler.ResetInputState();
|
||||
}
|
||||
|
||||
private void UpdateIconRectangle()
|
||||
{
|
||||
var widthScale = (float)Rectangle.Width / ButtonIcon.Width;
|
||||
var heightScale = (float)Rectangle.Height / ButtonIcon.Height;
|
||||
|
||||
var imageScale = MathHelper.Min(widthScale, heightScale);
|
||||
_iconRectangle = new Rectangle(Rectangle.X, Rectangle.Y,
|
||||
(int)(ButtonIcon.Width * imageScale), (int)(ButtonIcon.Height * imageScale));
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
// draw the button background
|
||||
spriteBatch.Draw(Resources.SprWhite, Rectangle, (Selected || Marked) ? FontColor : BackgroundColor);
|
||||
|
||||
var labelSize = Font.MeasureString(Label);
|
||||
var textLeft = ButtonIcon != null ? _iconRectangle.Right : Rectangle.X;
|
||||
var textPosition = new Vector2(
|
||||
(int)(textLeft + (Rectangle.Width - _iconRectangle.Width) / 2 - labelSize.X / 2),
|
||||
(int)(Rectangle.Y + Rectangle.Height / 2 - labelSize.Y / 2));
|
||||
|
||||
spriteBatch.DrawString(Font, Label, textPosition, (Selected || Marked) ? BackgroundColor : FontColor);
|
||||
|
||||
if (ButtonIcon != null)
|
||||
spriteBatch.Draw(ButtonIcon, _iconRectangle, (Selected || Marked) ? BackgroundColor : FontColor);
|
||||
}
|
||||
}
|
||||
}
|
65
Base/UI/UiCheckBox.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiCheckBox : UiElement
|
||||
{
|
||||
public bool CurrentState;
|
||||
|
||||
private readonly Rectangle _checkBox;
|
||||
private readonly Rectangle _checkBoxFill;
|
||||
private readonly Vector2 _textBoxPosition;
|
||||
private int _border = 4;
|
||||
|
||||
public UiCheckBox(Rectangle rectangle, SpriteFont font, string text, string elementId, string screen, bool currentState, UiFunction update, UiFunction click)
|
||||
: base(elementId, screen)
|
||||
{
|
||||
Rectangle = new Rectangle(rectangle.X + rectangle.Height + 5, rectangle.Y, rectangle.Width - rectangle.Height - 5, rectangle.Height);
|
||||
_checkBox = new Rectangle(rectangle.X, rectangle.Y, rectangle.Height, rectangle.Height);
|
||||
|
||||
_checkBoxFill = new Rectangle(
|
||||
_checkBox.X + _border, _checkBox.Y + _border,
|
||||
_checkBox.Width - _border * 2, _checkBox.Height - _border * 2);
|
||||
|
||||
Label = text;
|
||||
CurrentState = currentState;
|
||||
UpdateFunction = update;
|
||||
ClickFunction = click;
|
||||
|
||||
Font = font;
|
||||
|
||||
var labelSize = Font.MeasureString(Label);
|
||||
_textBoxPosition = new Vector2(
|
||||
(int)(Rectangle.X + Rectangle.Width / 2 - labelSize.X / 2),
|
||||
(int)(Rectangle.Y + Rectangle.Height / 2 - labelSize.Y / 2));
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (ClickFunction != null && InputHandler.MouseLeftPressed() && Selected)
|
||||
{
|
||||
CurrentState = !CurrentState;
|
||||
ClickFunction(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
// draw the background
|
||||
spriteBatch.Draw(Resources.SprWhite, Rectangle, Selected ? FontColor : BackgroundColor);
|
||||
|
||||
spriteBatch.Draw(Resources.SprWhite, _checkBox, BackgroundColor);
|
||||
|
||||
// draw the selection
|
||||
if (CurrentState)
|
||||
spriteBatch.Draw(Resources.SprWhite, _checkBoxFill, FontColor);
|
||||
|
||||
// draw the label
|
||||
spriteBatch.DrawString(Font, Label, _textBoxPosition, Selected ? BackgroundColor : FontColor);
|
||||
}
|
||||
}
|
||||
}
|
129
Base/UI/UiEditList.cs
Normal file
|
@ -0,0 +1,129 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiEditList<T> : UiElement
|
||||
{
|
||||
public int SelectedEntry;
|
||||
|
||||
private readonly List<T> _list;
|
||||
|
||||
private const int Padding = 5;
|
||||
private const int ButtonDistance = 1;
|
||||
private const int ButtonHeight = 16;
|
||||
|
||||
private int _currentSelection = -1;
|
||||
private int _startSelection = -1;
|
||||
|
||||
private int _scrollPosition;
|
||||
|
||||
private bool _isSwapping;
|
||||
|
||||
public UiEditList(Rectangle rectangle, SpriteFont font, List<T> list, string elementId, string screen, UiFunction update)
|
||||
: base(elementId, screen)
|
||||
{
|
||||
Rectangle = rectangle;
|
||||
_list = list;
|
||||
|
||||
UpdateFunction = update;
|
||||
|
||||
Font = font;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
var listEntrySize = (ButtonHeight + ButtonDistance);
|
||||
|
||||
_currentSelection = -1;
|
||||
if (InputHandler.MouseIntersect(Rectangle))
|
||||
{
|
||||
// scroll through the list
|
||||
{
|
||||
if (InputHandler.MouseWheelUp())
|
||||
_scrollPosition--;
|
||||
if (InputHandler.MouseWheelDown())
|
||||
_scrollPosition++;
|
||||
|
||||
var maxVisibleEntries = Rectangle.Height / listEntrySize;
|
||||
var maxScrollPosition = maxVisibleEntries >= _list.Count ? 0 : _list.Count - maxVisibleEntries;
|
||||
|
||||
_scrollPosition = Math.Clamp(_scrollPosition, 0, maxScrollPosition);
|
||||
}
|
||||
|
||||
_currentSelection = (InputHandler.MouseState.Y - Rectangle.Y + _scrollPosition * listEntrySize) / listEntrySize;
|
||||
|
||||
if (_currentSelection < _list.Count && InputHandler.MouseLeftStart())
|
||||
{
|
||||
_isSwapping = true;
|
||||
SelectedEntry = _currentSelection;
|
||||
_startSelection = _currentSelection;
|
||||
}
|
||||
|
||||
if (_isSwapping && InputHandler.MouseLeftDown())
|
||||
{
|
||||
// swap entries?
|
||||
if (_startSelection != _currentSelection && _currentSelection < _list.Count)
|
||||
{
|
||||
var copy = _list[_startSelection];
|
||||
_list[_startSelection] = _list[_currentSelection];
|
||||
_list[_currentSelection] = copy;
|
||||
|
||||
_startSelection = _currentSelection;
|
||||
SelectedEntry = _currentSelection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!InputHandler.MouseLeftDown())
|
||||
_isSwapping = false;
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
var posY = Rectangle.Y;
|
||||
for (var i = _scrollPosition; i < _list.Count; i++)
|
||||
{
|
||||
var marked = _currentSelection == i || SelectedEntry == i;
|
||||
|
||||
// draw the background
|
||||
var buttonRectangle = new Rectangle(Rectangle.X + Padding, posY + Padding, Rectangle.Width - Padding * 2, ButtonHeight);
|
||||
spriteBatch.Draw(Resources.SprWhite, buttonRectangle, marked ? FontColor : BackgroundColor);
|
||||
|
||||
// draw the text
|
||||
var text = _list[i].ToString();
|
||||
var labelSize = Font.MeasureString(text);
|
||||
var textPosition = new Vector2((int)(Rectangle.X + Rectangle.Width / 2 - labelSize.X / 2), (int)(posY + ButtonDistance + ButtonHeight / 2 - labelSize.Y / 2 + 2));
|
||||
spriteBatch.DrawString(Font, text, textPosition, marked ? BackgroundColor : FontColor);
|
||||
|
||||
posY += ButtonHeight + ButtonDistance;
|
||||
}
|
||||
|
||||
// draw the scrollbar
|
||||
if(_list.Count > 0)
|
||||
{
|
||||
var listEntrySize = (ButtonHeight + ButtonDistance);
|
||||
var maxVisibleEntries = Rectangle.Height / listEntrySize;
|
||||
var maxScrollPosition = maxVisibleEntries >= _list.Count ? 0 : _list.Count - maxVisibleEntries;
|
||||
var scrollBarHeight = (int)((maxVisibleEntries / (float)_list.Count) * Rectangle.Height);
|
||||
|
||||
if (maxScrollPosition > 0)
|
||||
{
|
||||
// draw the bar background
|
||||
spriteBatch.Draw(Resources.SprWhite,
|
||||
new Rectangle(Rectangle.Right - Padding + 1, Rectangle.Y, Padding - 2, Rectangle.Height), Values.ColorBackgroundLight);
|
||||
|
||||
// draw the bar
|
||||
spriteBatch.Draw(Resources.SprWhite,
|
||||
new Rectangle(Rectangle.Right - Padding + 1,
|
||||
Rectangle.Y + (int)((_scrollPosition / (float)maxScrollPosition) * (Rectangle.Height - scrollBarHeight)), Padding - 2, scrollBarHeight), BackgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
46
Base/UI/UiElement.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiElement
|
||||
{
|
||||
public delegate void UiFunction(UiElement uiElement);
|
||||
|
||||
public UiFunction ClickFunction;
|
||||
public UiFunction UpdateFunction;
|
||||
public UiFunction SizeUpdate;
|
||||
|
||||
public SpriteFont Font;
|
||||
public Rectangle Rectangle;
|
||||
public Color BackgroundColor = Values.ColorUiEditor;
|
||||
public Color FontColor = new Color(255, 255, 255);
|
||||
|
||||
public string[] Screens;
|
||||
public string ElementId;
|
||||
public virtual string Label { get; set; }
|
||||
public bool IsVisible = true;
|
||||
public bool Selected;
|
||||
public bool Remove;
|
||||
|
||||
public UiElement(string elementId, string screen)
|
||||
{
|
||||
ElementId = elementId;
|
||||
Screens = screen.ToUpper().Split(':');
|
||||
Font = Resources.EditorFont;
|
||||
}
|
||||
|
||||
public virtual void Update()
|
||||
{
|
||||
// select the element if the mouse if cursor is hovering over it
|
||||
Selected = InputHandler.MouseIntersect(Rectangle);
|
||||
// call the update function of the element
|
||||
UpdateFunction?.Invoke(this);
|
||||
}
|
||||
|
||||
public virtual void Draw(SpriteBatch spriteBatch) { }
|
||||
|
||||
public virtual void DrawBlur(SpriteBatch spriteBatch) { }
|
||||
}
|
||||
}
|
27
Base/UI/UiImage.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiImage : UiElement
|
||||
{
|
||||
public Texture2D SprImage;
|
||||
public Rectangle SourceRectangle;
|
||||
|
||||
public UiImage(Texture2D sprImage, Rectangle drawRectangle, Rectangle sourceRectangle, string elementId, string screen, Color color, UiFunction update)
|
||||
: base(elementId, screen)
|
||||
{
|
||||
SprImage = sprImage;
|
||||
Rectangle = drawRectangle;
|
||||
SourceRectangle = sourceRectangle;
|
||||
BackgroundColor = color;
|
||||
UpdateFunction = update;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (SprImage != null)
|
||||
spriteBatch.Draw(SprImage, Rectangle, SourceRectangle, BackgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
56
Base/UI/UiLabel.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiLabel : UiElement
|
||||
{
|
||||
private string _label;
|
||||
public sealed override string Label
|
||||
{
|
||||
get => _label;
|
||||
set { _label = value; UpdateLabelPosition(); }
|
||||
}
|
||||
|
||||
private Vector2 _textPosition;
|
||||
|
||||
public UiLabel(Rectangle rectangle, SpriteFont font, string text, string elementId, string screen, UiFunction update, Color backgroundColor)
|
||||
: base(elementId, screen)
|
||||
{
|
||||
Rectangle = rectangle;
|
||||
UpdateFunction = update;
|
||||
|
||||
BackgroundColor = backgroundColor;
|
||||
Font = font;
|
||||
|
||||
Label = text;
|
||||
}
|
||||
|
||||
public UiLabel(Rectangle rectangle, SpriteFont font, string text, string elementId, string screen, UiFunction update) :
|
||||
this(rectangle, font, text, elementId, screen, update, Color.Transparent)
|
||||
{ }
|
||||
|
||||
public UiLabel(Rectangle rectangle, string text, string screen) : base("", screen)
|
||||
{
|
||||
BackgroundColor = Color.Transparent;
|
||||
Rectangle = rectangle;
|
||||
Label = text;
|
||||
}
|
||||
|
||||
public void UpdateLabelPosition()
|
||||
{
|
||||
_textPosition = new Vector2(
|
||||
(int)(Rectangle.X + Rectangle.Width / 2 - Font.MeasureString(_label).X / 2),
|
||||
(int)(Rectangle.Y + Rectangle.Height / 2 - Font.MeasureString(_label).Y / 2));
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
// draw the background
|
||||
spriteBatch.Draw(Resources.SprWhite, Rectangle, BackgroundColor);
|
||||
// draw the label
|
||||
spriteBatch.DrawString(Font, _label, _textPosition, FontColor);
|
||||
}
|
||||
}
|
||||
}
|
111
Base/UI/UiNumberInput.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
using System.Globalization;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiNumberInput : UiElement
|
||||
{
|
||||
public float MinValue;
|
||||
public float MaxValue;
|
||||
public float Value;
|
||||
public float OldValue;
|
||||
|
||||
private readonly UiFunction _onNumberUpdate;
|
||||
private string _strValue;
|
||||
private string _strNewValue;
|
||||
private readonly float _stepSize;
|
||||
private int _mouseWheel;
|
||||
|
||||
public UiNumberInput(Rectangle rectangle, SpriteFont font, float value, float minValue, float maxValue,
|
||||
float stepSize, string elementId, string screen, UiFunction update, UiFunction onNumberUpdate)
|
||||
: base(elementId, screen)
|
||||
{
|
||||
Rectangle = rectangle;
|
||||
UpdateFunction = update;
|
||||
_onNumberUpdate = onNumberUpdate;
|
||||
|
||||
Value = value;
|
||||
_strValue = value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
MinValue = minValue;
|
||||
MaxValue = maxValue;
|
||||
|
||||
_stepSize = stepSize;
|
||||
|
||||
Font = font;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
OldValue = Value;
|
||||
_strValue = Value.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (Selected)
|
||||
{
|
||||
_strNewValue = _strValue == "0" ? "" : _strValue;
|
||||
|
||||
var returnNumber = InputHandler.ReturnNumber();
|
||||
if (returnNumber >= 0)
|
||||
_strNewValue += returnNumber.ToString();
|
||||
|
||||
// delete last position
|
||||
if (InputHandler.KeyPressed(Keys.Back) || InputHandler.MouseRightPressed(Rectangle))
|
||||
_strNewValue = _strValue.Substring(0, _strValue.Length - 1);
|
||||
|
||||
// if everything was delete
|
||||
if (_strNewValue == "")
|
||||
_strNewValue = "0";
|
||||
|
||||
// add .
|
||||
if (_stepSize % 1 > 0 && (InputHandler.KeyPressed(Keys.OemPeriod) || InputHandler.KeyPressed(Keys.OemComma)) && !_strValue.Contains("."))
|
||||
_strNewValue += ".";
|
||||
|
||||
// change value when scrolling
|
||||
if (InputHandler.MouseState.ScrollWheelValue > _mouseWheel && float.Parse(_strNewValue, CultureInfo.InvariantCulture) + _stepSize <= MaxValue)
|
||||
_strNewValue = (float.Parse(_strNewValue, CultureInfo.InvariantCulture) + _stepSize).ToString(CultureInfo.InvariantCulture);
|
||||
if (InputHandler.MouseState.ScrollWheelValue < _mouseWheel && float.Parse(_strNewValue, CultureInfo.InvariantCulture) - _stepSize >= MinValue)
|
||||
_strNewValue = (float.Parse(_strNewValue, CultureInfo.InvariantCulture) - _stepSize).ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
InputHandler.ResetInputState();
|
||||
|
||||
float.TryParse(_strNewValue, NumberStyles.Float, CultureInfo.InvariantCulture, out var newValue);
|
||||
if (newValue <= MaxValue &&
|
||||
(!_strNewValue.Contains(".") || _strNewValue.Split('.')[1].Length <= (_stepSize % 1).ToString(CultureInfo.InvariantCulture).Length - 2))
|
||||
_strValue = _strNewValue;
|
||||
|
||||
float.TryParse(_strValue, NumberStyles.Float, CultureInfo.InvariantCulture, out Value);
|
||||
|
||||
if (OldValue != Value && Value >= MinValue)
|
||||
_onNumberUpdate?.Invoke(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Value != (int)(Value / _stepSize) * _stepSize)
|
||||
{
|
||||
Value = (int)(Value / _stepSize) * _stepSize;
|
||||
_strValue = Value.ToString(CultureInfo.InvariantCulture);
|
||||
_onNumberUpdate(this);
|
||||
}
|
||||
}
|
||||
|
||||
_mouseWheel = InputHandler.MouseState.ScrollWheelValue;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
// draw the background
|
||||
spriteBatch.Draw(Resources.SprWhite, Rectangle, BackgroundColor);
|
||||
|
||||
Label = _strValue + (Selected ? "|" : "");
|
||||
|
||||
// draw the value
|
||||
var textPosition = new Vector2(Rectangle.X + 5, (int)(Rectangle.Y + Rectangle.Height / 2 - Font.MeasureString(Label).Y / 2));
|
||||
spriteBatch.DrawString(Font, Label, textPosition, FontColor);
|
||||
}
|
||||
}
|
||||
}
|
33
Base/UI/UiRectangle.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiRectangle : UiElement
|
||||
{
|
||||
public Color BlurColor;
|
||||
public float Radius = 0;
|
||||
|
||||
public UiRectangle(Rectangle rectangle, string elementId, string screen, Color color, Color blurColor, UiFunction update)
|
||||
: base(elementId, screen)
|
||||
{
|
||||
Rectangle = rectangle;
|
||||
BackgroundColor = color;
|
||||
BlurColor = blurColor;
|
||||
UpdateFunction = update;
|
||||
}
|
||||
|
||||
public override void DrawBlur(SpriteBatch spriteBatch)
|
||||
{
|
||||
Resources.RoundedCornerBlurEffect.Parameters["scale"].SetValue(Game1.UiScale);
|
||||
Resources.RoundedCornerBlurEffect.Parameters["blurColor"].SetValue(BlurColor.ToVector4());
|
||||
Resources.RoundedCornerBlurEffect.Parameters["radius"].SetValue(Radius);
|
||||
Resources.RoundedCornerBlurEffect.Parameters["width"].SetValue(Rectangle.Width / Game1.UiScale);
|
||||
Resources.RoundedCornerBlurEffect.Parameters["height"].SetValue(Rectangle.Height / Game1.UiScale);
|
||||
|
||||
// draw the blur texture
|
||||
spriteBatch.Draw(Resources.SprWhite, Rectangle, BackgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
91
Base/UI/UiScrollableList.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiScrollableList : UiElement
|
||||
{
|
||||
public string[] ItemList = new string[0];
|
||||
public int SelectionListItemHeight = 20;
|
||||
public int? Selection;
|
||||
public int? MouseOverSelection;
|
||||
|
||||
public int MaxLength;
|
||||
public int ListLength;
|
||||
public int ListPositionY;
|
||||
|
||||
public int SelectionListState
|
||||
{
|
||||
get => MathHelper.Clamp(_selectionListState, 0, ItemList.Length - (Rectangle.Height) / SelectionListItemHeight);
|
||||
set => _selectionListState = value;
|
||||
}
|
||||
|
||||
private int _selectionListState;
|
||||
|
||||
public UiScrollableList(Rectangle rectangle, string elementId, string screen, UiFunction update)
|
||||
: base(elementId, screen)
|
||||
{
|
||||
Rectangle = rectangle;
|
||||
UpdateFunction = update;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Selection = null;
|
||||
MouseOverSelection = null;
|
||||
|
||||
var scrollDirection = MathHelper.Clamp(InputHandler.LastMousState.ScrollWheelValue - InputHandler.MouseState.ScrollWheelValue, -1, 1);
|
||||
if (InputHandler.MouseIntersect(Rectangle))
|
||||
SelectionListState += scrollDirection;
|
||||
|
||||
MaxLength = Rectangle.Height / SelectionListItemHeight;
|
||||
ListLength = MathHelper.Min(ItemList.Length, MaxLength);
|
||||
ListPositionY = Rectangle.Height / 2 - (MaxLength * SelectionListItemHeight) / 2;
|
||||
|
||||
if (InputHandler.MouseIntersect(new Rectangle(Rectangle.X, Rectangle.Y + ListPositionY, Rectangle.Width, ListLength * SelectionListItemHeight)))
|
||||
{
|
||||
var selection = (InputHandler.MousePosition().Y - Rectangle.Y - ListPositionY) / SelectionListItemHeight;
|
||||
|
||||
if (!(selection == 0 && selection + SelectionListState > 0) && !(selection == ListLength - 1 && selection + SelectionListState != ItemList.Length - 1))
|
||||
MouseOverSelection = selection + SelectionListState;
|
||||
if (InputHandler.MouseLeftPressed())
|
||||
{
|
||||
MouseOverSelection = null;
|
||||
|
||||
if (selection == 0 && selection + SelectionListState > 0)
|
||||
SelectionListState = 0;
|
||||
else if (selection == ListLength - 1 && selection + SelectionListState != ItemList.Length - 1)
|
||||
SelectionListState = ItemList.Length - Rectangle.Height / SelectionListItemHeight;
|
||||
else
|
||||
Selection = selection + SelectionListState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
for (var i = 0; i < ListLength; i++)
|
||||
{
|
||||
string strText;
|
||||
if (i == 0 && i + SelectionListState > 0)
|
||||
strText = "▲";
|
||||
else if (i == ListLength - 1 && i + SelectionListState != ItemList.Length - 1)
|
||||
strText = "▼";
|
||||
else
|
||||
strText = ItemList[i + SelectionListState];
|
||||
|
||||
var drawRectangle = new Rectangle(Rectangle.X, Rectangle.Y +
|
||||
i * SelectionListItemHeight + ListPositionY, Rectangle.Width, SelectionListItemHeight);
|
||||
//mark if the mouse is over
|
||||
if (InputHandler.MouseIntersect(drawRectangle))
|
||||
spriteBatch.Draw(Resources.SprWhite, drawRectangle, Color.Black * 0.25f);
|
||||
|
||||
Basics.DrawStringCenter(Font, strText,
|
||||
new Rectangle(Rectangle.X, Rectangle.Y + i * SelectionListItemHeight + ListPositionY, Rectangle.Width, SelectionListItemHeight), Color.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
402
Base/UI/UiTextInput.cs
Normal file
|
@ -0,0 +1,402 @@
|
|||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using ProjectZ.InGame.Things;
|
||||
|
||||
namespace ProjectZ.Base.UI
|
||||
{
|
||||
public class UiTextInput : UiElement
|
||||
{
|
||||
public Type InputType;
|
||||
public float MaxLength;
|
||||
|
||||
public string StrValue
|
||||
{
|
||||
get => _strValue;
|
||||
set
|
||||
{
|
||||
_strValue = value;
|
||||
_cursorIndex = StrValue.Length;
|
||||
_selectionStart = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly UiFunction _onTextUpdate;
|
||||
private string _strValue = "";
|
||||
|
||||
private int _cursorIndex;
|
||||
|
||||
private int _selectionStart = -1;
|
||||
private int _selectionEnd = -1;
|
||||
private bool _mouseSelecting;
|
||||
|
||||
private float _buttonDownCounter;
|
||||
private int _buttonResetTime = 35;
|
||||
private int _buttonResetInitTime = 250;
|
||||
|
||||
private int _maxCharacterCount;
|
||||
private float _cursorCounter;
|
||||
private Vector2 _fontSize;
|
||||
|
||||
private double _lastMouseClick;
|
||||
|
||||
public UiTextInput(Rectangle rectangle, SpriteFont font, float maxLength,
|
||||
string elementId, string screen, UiFunction update, UiFunction onTextUpdate) : base(elementId, screen)
|
||||
{
|
||||
Rectangle = rectangle;
|
||||
UpdateFunction = update;
|
||||
_onTextUpdate = onTextUpdate;
|
||||
MaxLength = maxLength;
|
||||
Font = font;
|
||||
|
||||
_fontSize = font.MeasureString("A");
|
||||
_maxCharacterCount = (int)((rectangle.Width - 10) / _fontSize.X);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
_cursorCounter += Game1.DeltaTime;
|
||||
|
||||
if (InputHandler.KeyDown(Keys.Left) || InputHandler.KeyDown(Keys.Right) ||
|
||||
InputHandler.KeyDown(Keys.Up) || InputHandler.KeyDown(Keys.Down) ||
|
||||
InputHandler.KeyDown(Keys.Back) || InputHandler.KeyDown(Keys.Delete))
|
||||
{
|
||||
_buttonDownCounter -= Game1.DeltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
_buttonDownCounter = _buttonResetInitTime;
|
||||
}
|
||||
|
||||
if (!Selected) return;
|
||||
|
||||
var mousePosition = InputHandler.MousePosition().ToVector2();
|
||||
var newCursorIndex = SetCursor(mousePosition);
|
||||
var mouseReleased = InputHandler.MouseLeftReleased();
|
||||
|
||||
if (InputHandler.MouseLeftPressed())
|
||||
{
|
||||
// set the cursor to the position the user clicked on
|
||||
if (_lastMouseClick < Game1.TotalGameTime - 550 || newCursorIndex != _cursorIndex)
|
||||
{
|
||||
_mouseSelecting = false;
|
||||
_lastMouseClick = Game1.TotalGameTime;
|
||||
_cursorIndex = newCursorIndex;
|
||||
_selectionStart = -1;
|
||||
}
|
||||
// select the word the user clicked on
|
||||
else
|
||||
{
|
||||
_selectionStart = CursorPositionSkip(-1);
|
||||
_selectionEnd = CursorPositionSkip(1);
|
||||
_cursorIndex = _selectionEnd;
|
||||
}
|
||||
}
|
||||
else if (InputHandler.MouseLeftDown() &&
|
||||
(_mouseSelecting || (_selectionStart == -1 && newCursorIndex != _cursorIndex)))
|
||||
{
|
||||
_mouseSelecting = true;
|
||||
_selectionStart = Math.Min(_cursorIndex, newCursorIndex);
|
||||
_selectionEnd = Math.Max(_cursorIndex, newCursorIndex);
|
||||
}
|
||||
|
||||
if (_mouseSelecting && InputHandler.MouseLeftReleased())
|
||||
{
|
||||
_mouseSelecting = false;
|
||||
_cursorIndex = newCursorIndex;
|
||||
}
|
||||
|
||||
var inputString = InputHandler.ReturnCharacter();
|
||||
if (_strValue.Length < MaxLength && inputString != "")
|
||||
{
|
||||
// delete the selection first
|
||||
if (_selectionStart != -1)
|
||||
DeleteSelection();
|
||||
|
||||
_strValue = _strValue.Substring(0, _cursorIndex) + inputString +
|
||||
_strValue.Substring(_cursorIndex, _strValue.Length - _cursorIndex);
|
||||
|
||||
_cursorIndex++;
|
||||
}
|
||||
|
||||
//delete last position
|
||||
if ((InputHandler.KeyPressed(Keys.Back) || InputHandler.KeyDown(Keys.Back) &&
|
||||
_buttonDownCounter <= 0) && _strValue.Length > 0 && _cursorIndex > 0)
|
||||
{
|
||||
// delete selection
|
||||
if (_selectionStart != -1)
|
||||
{
|
||||
DeleteSelection();
|
||||
}
|
||||
else
|
||||
{
|
||||
_strValue = _strValue.Remove(_cursorIndex - 1, 1);
|
||||
_cursorIndex--;
|
||||
}
|
||||
|
||||
_buttonDownCounter += _buttonResetTime;
|
||||
_cursorCounter = 0;
|
||||
}
|
||||
|
||||
if ((InputHandler.KeyPressed(Keys.Delete) || InputHandler.KeyDown(Keys.Delete) &&
|
||||
_buttonDownCounter <= 0) && _strValue.Length > 0)
|
||||
{
|
||||
// delete selection
|
||||
if (_selectionStart != -1)
|
||||
DeleteSelection();
|
||||
else if (_cursorIndex < _strValue.Length)
|
||||
_strValue = _strValue.Remove(_cursorIndex, 1);
|
||||
|
||||
_buttonDownCounter += _buttonResetTime;
|
||||
_cursorCounter = 0;
|
||||
}
|
||||
|
||||
if (InputHandler.KeyPressed(Keys.Up))
|
||||
{
|
||||
_cursorIndex = 0;
|
||||
_cursorCounter = 0;
|
||||
}
|
||||
|
||||
if (InputHandler.KeyDown(Keys.Down))
|
||||
{
|
||||
_cursorIndex = _strValue.Length;
|
||||
_cursorCounter = 0;
|
||||
}
|
||||
|
||||
// move the cursor to the end of the word
|
||||
if (InputHandler.KeyPressed(Keys.Left) || InputHandler.KeyDown(Keys.Left) && _buttonDownCounter <= 0)
|
||||
{
|
||||
if (InputHandler.KeyDown(Keys.LeftControl))
|
||||
_cursorIndex = CursorPositionSkip(-1);
|
||||
else
|
||||
MoveCursor(-1);
|
||||
|
||||
if (!InputHandler.KeyDown(Keys.LeftShift))
|
||||
_selectionStart = -1;
|
||||
|
||||
ResetCursorTimer();
|
||||
}
|
||||
|
||||
if (InputHandler.KeyPressed(Keys.Right) || InputHandler.KeyDown(Keys.Right) && _buttonDownCounter <= 0)
|
||||
{
|
||||
if (InputHandler.KeyDown(Keys.LeftControl))
|
||||
_cursorIndex = CursorPositionSkip(1);
|
||||
else
|
||||
MoveCursor(1);
|
||||
|
||||
if (!InputHandler.KeyDown(Keys.LeftShift))
|
||||
_selectionStart = -1;
|
||||
|
||||
ResetCursorTimer();
|
||||
}
|
||||
|
||||
if (InputType == typeof(int))
|
||||
{
|
||||
if (InputHandler.MouseWheelDown())
|
||||
AddValue(-1);
|
||||
if (InputHandler.MouseWheelUp())
|
||||
AddValue(1);
|
||||
}
|
||||
if (InputType == typeof(bool))
|
||||
{
|
||||
if (InputHandler.MouseWheelDown() || InputHandler.MouseWheelUp())
|
||||
ToggleBool();
|
||||
}
|
||||
|
||||
_cursorIndex = MathHelper.Clamp(_cursorIndex, 0, _strValue.Length);
|
||||
|
||||
InputHandler.ResetInputState();
|
||||
|
||||
_onTextUpdate?.Invoke(this);
|
||||
}
|
||||
|
||||
private void DeleteSelection()
|
||||
{
|
||||
_strValue = _strValue.Remove(_selectionStart, _selectionEnd - _selectionStart);
|
||||
|
||||
if (_cursorIndex > _selectionStart)
|
||||
_cursorIndex -= _selectionEnd - _selectionStart;
|
||||
|
||||
_selectionStart = -1;
|
||||
}
|
||||
|
||||
private int SetCursor(Vector2 position)
|
||||
{
|
||||
var textPosition = GetTextPosition();
|
||||
|
||||
// cursor will be set in front or behind the character depending on where you click
|
||||
var posX = (int)((position.X - textPosition.X + _fontSize.X / 2) / _fontSize.X);
|
||||
var posY = (int)(position.Y - textPosition.Y) / (int)_fontSize.Y;
|
||||
|
||||
var xIndex = MathHelper.Clamp(posX, 0, _maxCharacterCount);
|
||||
var yIndex = MathHelper.Clamp(posY, 0, _maxCharacterCount);
|
||||
|
||||
var positionIndex = xIndex + yIndex * _maxCharacterCount;
|
||||
|
||||
_cursorCounter = 0;
|
||||
return MathHelper.Clamp(positionIndex, 0, _strValue.Length);
|
||||
}
|
||||
|
||||
private void MoveCursor(int offset)
|
||||
{
|
||||
_cursorIndex += offset;
|
||||
}
|
||||
|
||||
private void ResetCursorTimer()
|
||||
{
|
||||
_buttonDownCounter += _buttonResetTime;
|
||||
_cursorCounter = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move the cursor in the given direction.
|
||||
/// This will try to skip over words.
|
||||
/// </summary>
|
||||
/// <param name="direction"></param>
|
||||
private int CursorPositionSkip(int direction)
|
||||
{
|
||||
if (_strValue.Length == 0)
|
||||
return 0;
|
||||
|
||||
var offset = direction < 0 ? -1 : 0;
|
||||
var characterIndex = _cursorIndex + offset;
|
||||
var lastCharacter = -1;
|
||||
|
||||
while (0 <= characterIndex && characterIndex < _strValue.Length)
|
||||
{
|
||||
var characterType = GetCharacterType(_strValue[characterIndex]);
|
||||
// we break if there is a new character type at the cursor position
|
||||
if (lastCharacter != -1 && characterType != 0 && lastCharacter != characterType)
|
||||
{
|
||||
characterIndex -= offset;
|
||||
return characterIndex;
|
||||
}
|
||||
lastCharacter = characterType;
|
||||
|
||||
characterIndex += direction;
|
||||
}
|
||||
|
||||
return direction < 0 ? 0 : _strValue.Length;
|
||||
}
|
||||
|
||||
private int GetCharacterType(char character)
|
||||
{
|
||||
if (character == ' ')
|
||||
return 0;
|
||||
|
||||
if (('a' <= character && character <= 'z') ||
|
||||
('A' <= character && character <= 'Z') ||
|
||||
('0' <= character && character <= '9') ||
|
||||
character == '_')
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
public void AddValue(int diff)
|
||||
{
|
||||
var converted = ConvertToType();
|
||||
|
||||
if (converted == null) return;
|
||||
|
||||
var intValue = (int)converted + diff;
|
||||
_strValue = intValue.ToString();
|
||||
}
|
||||
|
||||
public void ToggleBool()
|
||||
{
|
||||
var converted = ConvertToType();
|
||||
|
||||
if (converted == null) return;
|
||||
|
||||
var boolValue = !(bool)converted;
|
||||
_strValue = boolValue.ToString();
|
||||
}
|
||||
|
||||
public object ConvertToType()
|
||||
{
|
||||
object output = null;
|
||||
|
||||
if (InputType == typeof(int))
|
||||
{
|
||||
int.TryParse(_strValue, out var intResult);
|
||||
output = intResult;
|
||||
}
|
||||
else if (InputType == typeof(bool))
|
||||
{
|
||||
bool.TryParse(_strValue, out var boolResult);
|
||||
output = boolResult;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
spriteBatch.Draw(Resources.SprWhite, Rectangle, BackgroundColor);
|
||||
|
||||
Label = StrValue;
|
||||
|
||||
// add line breaks if needed
|
||||
if (_maxCharacterCount >= 1)
|
||||
{
|
||||
var breakCount = 1;
|
||||
var length = Label.Length;
|
||||
while (length > _maxCharacterCount)
|
||||
{
|
||||
length -= _maxCharacterCount;
|
||||
Label = Label.Insert(breakCount * _maxCharacterCount + breakCount - 1, "\n");
|
||||
breakCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// draw the text
|
||||
var textPosition = GetTextPosition();
|
||||
|
||||
// draw the selection
|
||||
if (Selected && _selectionStart != -1)
|
||||
{
|
||||
var drawIndex = _selectionStart;
|
||||
|
||||
// draw the selection line by line
|
||||
while (drawIndex < _selectionEnd)
|
||||
{
|
||||
var drawIndexEnd = MathHelper.Min(
|
||||
drawIndex + _maxCharacterCount - (drawIndex % _maxCharacterCount), _selectionEnd);
|
||||
var drawPosition = new Vector2(
|
||||
(drawIndex % _maxCharacterCount) * _fontSize.X,
|
||||
(drawIndex / _maxCharacterCount) * _fontSize.Y);
|
||||
spriteBatch.Draw(Resources.SprWhite,
|
||||
new Rectangle(
|
||||
(int)(textPosition.X + drawPosition.X), (int)(textPosition.Y + drawPosition.Y),
|
||||
(drawIndexEnd - drawIndex) * (int)_fontSize.X, (int)_fontSize.Y), Color.Blue);
|
||||
drawIndex = drawIndexEnd;
|
||||
}
|
||||
}
|
||||
|
||||
spriteBatch.DrawString(Font, Label, textPosition, FontColor);
|
||||
|
||||
// draw the cursor
|
||||
if (Selected && _cursorCounter % 700 < 350 && _maxCharacterCount > 0)
|
||||
{
|
||||
var offset = _cursorIndex != 0 && _cursorIndex % _maxCharacterCount == 0 ? 1 : 0;
|
||||
var cursorPosition = new Vector2(
|
||||
textPosition.X + (_cursorIndex % _maxCharacterCount + offset * _maxCharacterCount) * _fontSize.X - 3,
|
||||
textPosition.Y + (_cursorIndex / _maxCharacterCount - offset) * _fontSize.Y);
|
||||
|
||||
spriteBatch.DrawString(Font, "|", cursorPosition, FontColor);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 GetTextPosition()
|
||||
{
|
||||
var label = Label.Length > 0 ? Label : "0";
|
||||
return new Vector2(Rectangle.X + 5, (int)(Rectangle.Y + Rectangle.Height / 2 - Font.MeasureString(label).Y / 2));
|
||||
}
|
||||
}
|
||||
}
|
1366
Content/Content.mgcb
Normal file
BIN
Content/Editor/delete.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
Content/Editor/edit.png
Normal file
After Width: | Height: | Size: 269 B |
BIN
Content/Editor/eye_closed.png
Normal file
After Width: | Height: | Size: 216 B |
BIN
Content/Editor/eye_open.png
Normal file
After Width: | Height: | Size: 236 B |
BIN
Content/Editor/select.png
Normal file
After Width: | Height: | Size: 270 B |
BIN
Content/Fonts/credits font.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
Content/Fonts/credits header font.png
Normal file
After Width: | Height: | Size: 18 KiB |
60
Content/Fonts/editor font.spritefont
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file contains an xml description of a font, and will be read by the XNA
|
||||
Framework Content Pipeline. Follow the comments to customize the appearance
|
||||
of the font in your game, and to change the characters which are available to draw
|
||||
with.
|
||||
-->
|
||||
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
|
||||
<Asset Type="Graphics:FontDescription">
|
||||
|
||||
<!--
|
||||
Modify this string to change the font that will be imported.
|
||||
-->
|
||||
<FontName>Segoe UI</FontName>
|
||||
|
||||
<!--
|
||||
Size is a float value, measured in points. Modify this value to change
|
||||
the size of the font.
|
||||
-->
|
||||
<Size>12</Size>
|
||||
|
||||
<!--
|
||||
Spacing is a float value, measured in pixels. Modify this value to change
|
||||
the amount of spacing in between characters.
|
||||
-->
|
||||
<Spacing>0</Spacing>
|
||||
|
||||
<!--
|
||||
UseKerning controls the layout of the font. If this value is true, kerning information
|
||||
will be used when placing characters.
|
||||
-->
|
||||
<UseKerning>true</UseKerning>
|
||||
|
||||
<!--
|
||||
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
|
||||
and "Bold, Italic", and are case sensitive.
|
||||
-->
|
||||
<Style>Regular</Style>
|
||||
|
||||
<!--
|
||||
If you uncomment this line, the default character will be substituted if you draw
|
||||
or measure text that contains characters which were not included in the font.
|
||||
-->
|
||||
<!-- <DefaultCharacter>*</DefaultCharacter> -->
|
||||
|
||||
<!--
|
||||
CharacterRegions control what letters are available in the font. Every
|
||||
character from Start to End will be built and made available for drawing. The
|
||||
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
|
||||
character set. The characters are ordered according to the Unicode standard.
|
||||
See the documentation for more information.
|
||||
-->
|
||||
<CharacterRegions>
|
||||
<CharacterRegion>
|
||||
<Start> </Start>
|
||||
<End>~</End>
|
||||
</CharacterRegion>
|
||||
</CharacterRegions>
|
||||
</Asset>
|
||||
</XnaContent>
|
60
Content/Fonts/editor mono font.spritefont
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file contains an xml description of a font, and will be read by the XNA
|
||||
Framework Content Pipeline. Follow the comments to customize the appearance
|
||||
of the font in your game, and to change the characters which are available to draw
|
||||
with.
|
||||
-->
|
||||
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
|
||||
<Asset Type="Graphics:FontDescription">
|
||||
|
||||
<!--
|
||||
Modify this string to change the font that will be imported.
|
||||
-->
|
||||
<FontName>Courier New</FontName>
|
||||
|
||||
<!--
|
||||
Size is a float value, measured in points. Modify this value to change
|
||||
the size of the font.
|
||||
-->
|
||||
<Size>11</Size>
|
||||
|
||||
<!--
|
||||
Spacing is a float value, measured in pixels. Modify this value to change
|
||||
the amount of spacing in between characters.
|
||||
-->
|
||||
<Spacing>0</Spacing>
|
||||
|
||||
<!--
|
||||
UseKerning controls the layout of the font. If this value is true, kerning information
|
||||
will be used when placing characters.
|
||||
-->
|
||||
<UseKerning>true</UseKerning>
|
||||
|
||||
<!--
|
||||
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
|
||||
and "Bold, Italic", and are case sensitive.
|
||||
-->
|
||||
<Style>Regular</Style>
|
||||
|
||||
<!--
|
||||
If you uncomment this line, the default character will be substituted if you draw
|
||||
or measure text that contains characters which were not included in the font.
|
||||
-->
|
||||
<!-- <DefaultCharacter>*</DefaultCharacter> -->
|
||||
|
||||
<!--
|
||||
CharacterRegions control what letters are available in the font. Every
|
||||
character from Start to End will be built and made available for drawing. The
|
||||
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
|
||||
character set. The characters are ordered according to the Unicode standard.
|
||||
See the documentation for more information.
|
||||
-->
|
||||
<CharacterRegions>
|
||||
<CharacterRegion>
|
||||
<Start> </Start>
|
||||
<End>~</End>
|
||||
</CharacterRegion>
|
||||
</CharacterRegions>
|
||||
</Asset>
|
||||
</XnaContent>
|
60
Content/Fonts/editor small mono font.spritefont
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file contains an xml description of a font, and will be read by the XNA
|
||||
Framework Content Pipeline. Follow the comments to customize the appearance
|
||||
of the font in your game, and to change the characters which are available to draw
|
||||
with.
|
||||
-->
|
||||
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
|
||||
<Asset Type="Graphics:FontDescription">
|
||||
|
||||
<!--
|
||||
Modify this string to change the font that will be imported.
|
||||
-->
|
||||
<FontName>Courier New</FontName>
|
||||
|
||||
<!--
|
||||
Size is a float value, measured in points. Modify this value to change
|
||||
the size of the font.
|
||||
-->
|
||||
<Size>8</Size>
|
||||
|
||||
<!--
|
||||
Spacing is a float value, measured in pixels. Modify this value to change
|
||||
the amount of spacing in between characters.
|
||||
-->
|
||||
<Spacing>0</Spacing>
|
||||
|
||||
<!--
|
||||
UseKerning controls the layout of the font. If this value is true, kerning information
|
||||
will be used when placing characters.
|
||||
-->
|
||||
<UseKerning>true</UseKerning>
|
||||
|
||||
<!--
|
||||
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
|
||||
and "Bold, Italic", and are case sensitive.
|
||||
-->
|
||||
<Style>Regular</Style>
|
||||
|
||||
<!--
|
||||
If you uncomment this line, the default character will be substituted if you draw
|
||||
or measure text that contains characters which were not included in the font.
|
||||
-->
|
||||
<!-- <DefaultCharacter>*</DefaultCharacter> -->
|
||||
|
||||
<!--
|
||||
CharacterRegions control what letters are available in the font. Every
|
||||
character from Start to End will be built and made available for drawing. The
|
||||
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
|
||||
character set. The characters are ordered according to the Unicode standard.
|
||||
See the documentation for more information.
|
||||
-->
|
||||
<CharacterRegions>
|
||||
<CharacterRegion>
|
||||
<Start> </Start>
|
||||
<End>~</End>
|
||||
</CharacterRegion>
|
||||
</CharacterRegions>
|
||||
</Asset>
|
||||
</XnaContent>
|
BIN
Content/Fonts/headerFont.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
Content/Fonts/newHeaderFont.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
Content/Fonts/smallFont.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
Content/Fonts/smallFontOld.png
Normal file
After Width: | Height: | Size: 28 KiB |
3
Content/Light/doorLight.atlas
Normal file
|
@ -0,0 +1,3 @@
|
|||
1
|
||||
2
|
||||
doorLight:0,0,48,48,24,24
|
BIN
Content/Light/doorLight.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Content/Light/dungeon.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
Content/Light/light.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
Content/Light/ligth room vertical.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
Content/Light/ligth room.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
2
Content/Light/readme.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
the light sprites will get preprocessed to contain preprocessed alphase (?)
|
||||
so they can not just get loaded like the other sprites that do not have transparency values other than 0 or 1
|
BIN
Content/Light/shadow.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
Content/Menu/copyIcon.png
Normal file
After Width: | Height: | Size: 273 B |
BIN
Content/Menu/gearIcon.png
Normal file
After Width: | Height: | Size: 266 B |
BIN
Content/Menu/menuBackground.png
Normal file
After Width: | Height: | Size: 506 B |
BIN
Content/Menu/trashIcon.png
Normal file
After Width: | Height: | Size: 285 B |
BIN
Content/Objects/fog.png
Normal file
After Width: | Height: | Size: 35 KiB |
61
Content/Shader/BBlurH.fx
Normal file
|
@ -0,0 +1,61 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_1
|
||||
#endif
|
||||
|
||||
sampler s0;
|
||||
|
||||
float pixelX;
|
||||
float mult0 = 0.25;
|
||||
float mult1 = 0.125;
|
||||
float mult2 = 0.075;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float val0 = tex2D(s0, float2(coords.x, coords.y)).a;
|
||||
|
||||
if (val0 == 1)
|
||||
return float4(0, 0, 0, val0);
|
||||
|
||||
float val1 = tex2D(s0, float2(coords.x - pixelX * 1, coords.y)).a;
|
||||
float val2 = tex2D(s0, float2(coords.x - pixelX * 2, coords.y)).a;
|
||||
float val3 = tex2D(s0, float2(coords.x - pixelX * 3, coords.y)).a;
|
||||
|
||||
float val4 = tex2D(s0, float2(coords.x + pixelX * 1, coords.y)).a;
|
||||
float val5 = tex2D(s0, float2(coords.x + pixelX * 2, coords.y)).a;
|
||||
float val6 = tex2D(s0, float2(coords.x + pixelX * 3, coords.y)).a;
|
||||
|
||||
float valOut = val0;
|
||||
|
||||
if (val1 == 1 || val4 == 1)
|
||||
valOut = max(max(val1 * mult0, val4 * mult0), valOut);
|
||||
else if (val2 == 1 || val5 == 1)
|
||||
valOut = max(max(val2 * mult1, val5 * mult1), valOut);
|
||||
else if (val3 == 1 || val6 == 1)
|
||||
valOut = max(max(val3 * mult2, val6 * mult2), valOut);
|
||||
else
|
||||
{
|
||||
float mult = 1.95f;
|
||||
valOut = max(val1 * mult0 * mult, valOut);
|
||||
valOut = max(val2 * mult1 * mult, valOut);
|
||||
valOut = max(val3 * mult2 * mult, valOut);
|
||||
|
||||
valOut = max(val4 * mult0 * mult, valOut);
|
||||
valOut = max(val5 * mult1 * mult, valOut);
|
||||
valOut = max(val6 * mult2 * mult, valOut);
|
||||
}
|
||||
|
||||
return float4(0, 0, 0, valOut);
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
42
Content/Shader/BBlurV.fx
Normal file
|
@ -0,0 +1,42 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
sampler s0;
|
||||
|
||||
float pixelY;
|
||||
float mult0 = 0.25;
|
||||
float mult1 = 0.125;
|
||||
float mult2 = 0.075;
|
||||
|
||||
// float mult0 = 0.45;
|
||||
// float mult1 = 0.25;
|
||||
// float mult2 = 0.075;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float valMax = tex2D(s0, float2(coords.x, coords.y)).a;
|
||||
|
||||
valMax = max(tex2D(s0, float2(coords.x, coords.y - pixelY * 1)).a * mult0, valMax);
|
||||
valMax = max(tex2D(s0, float2(coords.x, coords.y - pixelY * 2)).a * mult1, valMax);
|
||||
valMax = max(tex2D(s0, float2(coords.x, coords.y - pixelY * 3)).a * mult2, valMax);
|
||||
|
||||
valMax = max(tex2D(s0, float2(coords.x, coords.y + pixelY * 1)).a * mult0, valMax);
|
||||
valMax = max(tex2D(s0, float2(coords.x, coords.y + pixelY * 2)).a * mult1, valMax);
|
||||
valMax = max(tex2D(s0, float2(coords.x, coords.y + pixelY * 3)).a * mult2, valMax);
|
||||
|
||||
return float4(0, 0, 0, valMax);
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
33
Content/Shader/BlurH.fx
Normal file
|
@ -0,0 +1,33 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
sampler s0;
|
||||
|
||||
float pixelX;
|
||||
float mult0;
|
||||
float mult1;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 sideColors
|
||||
= tex2D(s0, float2(coords.x - pixelX * 0.5, coords.y)) * mult0;
|
||||
sideColors += tex2D(s0, float2(coords.x + pixelX * 0.5, coords.y)) * mult0;
|
||||
sideColors += tex2D(s0, float2(coords.x - pixelX * 2.5, coords.y)) * mult1;
|
||||
sideColors += tex2D(s0, float2(coords.x + pixelX * 2.5, coords.y)) * mult1;
|
||||
|
||||
return sideColors;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
33
Content/Shader/BlurV.fx
Normal file
|
@ -0,0 +1,33 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
sampler s0;
|
||||
|
||||
float pixelY;
|
||||
float mult0;
|
||||
float mult1;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 sideColors
|
||||
= tex2D(s0, float2(coords.x, coords.y - pixelY * 0.5)) * mult0;
|
||||
sideColors += tex2D(s0, float2(coords.x, coords.y + pixelY * 0.5)) * mult0;
|
||||
sideColors += tex2D(s0, float2(coords.x, coords.y - pixelY * 2.5)) * mult1;
|
||||
sideColors += tex2D(s0, float2(coords.x, coords.y + pixelY * 2.5)) * mult1;
|
||||
|
||||
return sideColors;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
48
Content/Shader/CircleShader.fx
Normal file
|
@ -0,0 +1,48 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0
|
||||
#endif
|
||||
|
||||
Texture2D SpriteTexture;
|
||||
|
||||
float softRad = 30;
|
||||
float size;
|
||||
float centerX, centerY;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
sampler2D SpriteTextureSampler = sampler_state
|
||||
{
|
||||
Texture = <SpriteTexture>;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
float4 MainPS(VertexShaderOutput input) : COLOR
|
||||
{
|
||||
float2 pos = float2(input.TexCoord.x * width - centerX, input.TexCoord.y * height - centerY);
|
||||
float white = length(pos);
|
||||
|
||||
white = clamp((size - white) / softRad, 0, 1);
|
||||
float black = 1 - white;
|
||||
|
||||
return (input.Color * float4(1, 1, 1, 1)) * (black * black * black);
|
||||
}
|
||||
|
||||
technique SpriteDrawing
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL MainPS();
|
||||
}
|
||||
};
|
43
Content/Shader/ColorCloud.fx
Normal file
|
@ -0,0 +1,43 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_1
|
||||
#endif
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
|
||||
sampler sampler0 : register(s0) { };
|
||||
|
||||
float scale;
|
||||
float scaleX;
|
||||
float scaleY;
|
||||
|
||||
float4 color0 = float4(1, 0, 0, 1);
|
||||
float4 color1 = float4(1, 1, 1, 1);
|
||||
|
||||
float2 offset;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 texColor = tex2D(sampler0, coords);
|
||||
|
||||
float4 insideColor = color0;
|
||||
if (((int)(((pos.x / scaleX + offset.x / scale)) / 4) +
|
||||
(int)(((pos.y / scaleY + offset.y / scale)) / 4)) % 2 == 0)
|
||||
insideColor = color1;
|
||||
|
||||
return insideColor * texColor;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
39
Content/Shader/ColorShader.fx
Normal file
|
@ -0,0 +1,39 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
Texture2D SpriteTexture;
|
||||
|
||||
sampler2D SpriteTextureSampler = sampler_state
|
||||
{
|
||||
Texture = <SpriteTexture>;
|
||||
};
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TextureCoordinates : TEXCOORD0;
|
||||
};
|
||||
|
||||
float4 MainPS(VertexShaderOutput input) : COLOR
|
||||
{
|
||||
float4 color = tex2D(SpriteTextureSampler,input.TextureCoordinates);
|
||||
// replace pink with the color
|
||||
if (color.r == 1 && color.g == 0 && color.b)
|
||||
return input.Color;
|
||||
return color;
|
||||
}
|
||||
|
||||
technique SpriteDrawing
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL MainPS();
|
||||
}
|
||||
};
|
38
Content/Shader/DamageShader.fx
Normal file
|
@ -0,0 +1,38 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
float mark0 = 0.0;
|
||||
float mark1 = 0.0;
|
||||
|
||||
#define c0 float4(1.000, 0.710, 0.192, 1.000)
|
||||
#define c1 float4(0.871, 0.000, 0.000, 1.000)
|
||||
#define c2 float4(0.000, 0.000, 0.000, 1.000)
|
||||
|
||||
sampler s0;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 color = tex2D(s0, coords) * color1;
|
||||
float sum = 0.333f * color.r + 0.333f * color.g + 0.333f * color.b;
|
||||
|
||||
if(sum < mark0)
|
||||
return c0 * color.a * color1.a;
|
||||
if(sum < mark1)
|
||||
return c1 * color.a * color1.a;
|
||||
|
||||
return c2 * color.a * color1.a;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
38
Content/Shader/EffectBlur.fx
Normal file
|
@ -0,0 +1,38 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_1
|
||||
#endif
|
||||
|
||||
Texture2D sprBlur;
|
||||
|
||||
sampler sampler0 : register(s0) {
|
||||
Filter = POINT;
|
||||
};
|
||||
sampler sampler1 : register(s1) {
|
||||
Texture = (sprBlur);
|
||||
};
|
||||
|
||||
int width, height;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
#if OPENGL
|
||||
pos.y = height - pos.y;
|
||||
#endif
|
||||
|
||||
float4 textureSample = tex2D(sampler0, float2(coords.x, coords.y));
|
||||
|
||||
return tex2D(sampler1, float2(pos.x / width, pos.y / height)) * color1 * textureSample.r + textureSample * (1 - textureSample.r) * color1;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
78
Content/Shader/FullShadowEffect.fx
Normal file
|
@ -0,0 +1,78 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
float4x4 xViewProjection;
|
||||
|
||||
Texture2D SpriteTexture;
|
||||
|
||||
sampler2D SpriteTextureSampler = sampler_state
|
||||
{
|
||||
Texture = <SpriteTexture>;
|
||||
};
|
||||
|
||||
sampler s0;
|
||||
|
||||
float pixelWidth;
|
||||
|
||||
float rotation = 1.5;
|
||||
|
||||
float offsetX;
|
||||
float height;
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Pos : SV_Position;
|
||||
float2 TextureCoordinates : TEXCOORD0;
|
||||
float2 DrawPosition : TEXCOORD1;
|
||||
float2 SourceSize : TEXCOORD2;
|
||||
float4 Color: COLOR0;
|
||||
};
|
||||
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 Pos : SV_Position;
|
||||
float2 TextureCoordinates : TEXCOORD0;
|
||||
float2 DrawPosition : TEXCOORD1;
|
||||
float2 SourceSize : TEXCOORD2;
|
||||
float2 RealCoord : TEXCOORD3;
|
||||
float4 Color: COLOR0;
|
||||
};
|
||||
|
||||
PixelShaderInput SpriteVertexShader(VertexShaderOutput input)
|
||||
{
|
||||
PixelShaderInput Output = (PixelShaderInput)0;
|
||||
|
||||
input.Pos.x += ((input.SourceSize.y - input.Pos.y + input.DrawPosition.y) * offsetX);
|
||||
input.Pos.y -= ((-(input.DrawPosition.y + input.SourceSize.y) + input.Pos.y) * (1 - height));
|
||||
|
||||
Output.RealCoord = float2(
|
||||
(input.Pos.x - input.DrawPosition.x) / input.SourceSize.x,
|
||||
(input.Pos.y - input.DrawPosition.y - (input.SourceSize.y * (1 - height))) / (input.SourceSize.y * height));
|
||||
|
||||
Output.Pos = mul(input.Pos, xViewProjection);
|
||||
Output.TextureCoordinates = input.TextureCoordinates;
|
||||
Output.Color = input.Color;
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
float4 MainPS(PixelShaderInput input) : COLOR
|
||||
{
|
||||
float4 texColor = tex2D(s0, float2(input.TextureCoordinates.x, input.TextureCoordinates.y));
|
||||
return texColor.a * input.Color;
|
||||
}
|
||||
|
||||
technique SpriteDrawing
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
VertexShader = compile VS_SHADERMODEL SpriteVertexShader();
|
||||
PixelShader = compile PS_SHADERMODEL MainPS();
|
||||
}
|
||||
};
|
29
Content/Shader/LightFadeShader.fx
Normal file
|
@ -0,0 +1,29 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_1
|
||||
#endif
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
|
||||
sampler s0;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 texColor = tex2D(s0, coords);
|
||||
float dist = 1.0 - clamp(((0.05 + texColor.a * 0.95) - color.a) / 0.05, 0, 1);
|
||||
return float4(0, 0, 0, dist);
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
47
Content/Shader/LightShader.fx
Normal file
|
@ -0,0 +1,47 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_1
|
||||
#endif
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
|
||||
Texture2D sprLight;
|
||||
|
||||
sampler sampler0 : register(s0) { };
|
||||
sampler sampler1 : register(s1)
|
||||
{
|
||||
Texture = (sprLight);
|
||||
};
|
||||
|
||||
float lightState = 0;
|
||||
int mode = 0;
|
||||
int width, height;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 texColor = tex2D(sampler0, coords);
|
||||
float4 lightColor = tex2D(sampler1, float2(pos.x / width, pos.y / height));// * float4(1.963, 1.0, 5.149, 1);
|
||||
|
||||
lightColor.r = clamp(lightColor.r, 0, 1);
|
||||
lightColor.b = clamp(lightColor.b, 0, 1);
|
||||
|
||||
float3 lerpTarget = float3(1, 1, 1);
|
||||
if (mode == 1)
|
||||
lerpTarget = texColor.rgb;
|
||||
|
||||
return float4(lerp(texColor.rgb * lightColor.rgb, lerpTarget, lightState), texColor.a) * color1;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
61
Content/Shader/RoundedCorner.fx
Normal file
|
@ -0,0 +1,61 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0
|
||||
#endif
|
||||
|
||||
const float PI = 3.14159265f;
|
||||
|
||||
float radius = 2.5f;
|
||||
float scale = 1;
|
||||
float centerX, centerY;
|
||||
|
||||
int width, height;
|
||||
|
||||
sampler sampler0 : register(s0) { };
|
||||
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
};
|
||||
|
||||
float4 MainPS(VertexShaderOutput input) : COLOR
|
||||
{
|
||||
float4 texColor = tex2D(sampler0, input.TexCoord);
|
||||
|
||||
float posX = input.TexCoord.x * width;
|
||||
float posY = input.TexCoord.y * height;
|
||||
|
||||
float distX = min(posX, abs(posX - width));
|
||||
float distY = min(posY, abs(posY - height));
|
||||
|
||||
float circle = 1;
|
||||
|
||||
if (distX < radius && distY < radius)
|
||||
{
|
||||
float a = radius - distX;
|
||||
float b = radius - distY;
|
||||
float dist = clamp((radius - sqrt(a * a + b * b)) * scale, 0, 1);
|
||||
circle = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
float distEdge = clamp(min(distX, distY) * scale, 0, 1);
|
||||
circle = distEdge;
|
||||
}
|
||||
|
||||
return texColor * input.Color * circle;
|
||||
}
|
||||
|
||||
technique SpriteDrawing
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL MainPS();
|
||||
}
|
||||
};
|
69
Content/Shader/RoundedCornerEffectBlur.fx
Normal file
|
@ -0,0 +1,69 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_1
|
||||
#endif
|
||||
|
||||
Texture2D sprBlur;
|
||||
|
||||
sampler sampler0 : register(s0) {
|
||||
Filter = POINT;
|
||||
};
|
||||
sampler sampler1 : register(s1) {
|
||||
Texture = (sprBlur);
|
||||
};
|
||||
|
||||
float4 blurColor;
|
||||
|
||||
float radius = 2.5f;
|
||||
float scale = 1;
|
||||
|
||||
int width, height;
|
||||
int textureWidth, textureHeight;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
#if OPENGL
|
||||
pos.y = height - pos.y;
|
||||
#endif
|
||||
|
||||
float posX = coords.x * width;
|
||||
float posY = coords.y * height;
|
||||
|
||||
float distX = min(posX, abs(posX - width));
|
||||
float distY = min(posY, abs(posY - height));
|
||||
|
||||
float circle = 1;
|
||||
|
||||
if (distX < radius && distY < radius)
|
||||
{
|
||||
float a = radius - distX;
|
||||
float b = radius - distY;
|
||||
float dist = clamp((radius - sqrt(a * a + b * b)) * scale, 0, 1);
|
||||
circle = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
float distEdge = clamp(min(distX, distY) * scale, 0, 1);
|
||||
circle = distEdge;
|
||||
}
|
||||
|
||||
if (radius == 0)
|
||||
circle = 1;
|
||||
|
||||
float4 textureSample = tex2D(sampler0, float2(coords.x, coords.y));
|
||||
float4 blurSample = tex2D(sampler1, float2(pos.x / textureWidth, pos.y / textureHeight));
|
||||
|
||||
return ((blurSample * blurColor * (1 - color1.a) + color1) * textureSample.r + textureSample * (1 - textureSample.r) * blurColor) * circle;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
33
Content/Shader/SaturationFilter.fx
Normal file
|
@ -0,0 +1,33 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
|
||||
sampler s0;
|
||||
|
||||
float3 W = float3(0.3, 0.59, 0.11);
|
||||
float percentage;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color0 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 color = tex2D(s0, float2(coords.x, coords.y));
|
||||
float intensity = dot(color.rgb, W);
|
||||
float4 grayscale = float4(intensity, intensity, intensity, color.a);
|
||||
return lerp(color, grayscale, percentage) * color0;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
41
Content/Shader/ShockEffect.fx
Normal file
|
@ -0,0 +1,41 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
float mark0 = 0.0;
|
||||
float mark1 = 0.0;
|
||||
float mark2 = 0.0;
|
||||
|
||||
#define c0 float4(1.000, 1.000, 0.482, 1.000)
|
||||
#define c1 float4(0.063, 0.129, 0.192, 1.000)
|
||||
#define c2 float4(1.000, 1.000, 1.000, 1.000)
|
||||
|
||||
sampler s0;
|
||||
|
||||
float4 MainPS(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 color = tex2D(s0, coords) * color1;
|
||||
float sum = 0.4f * color.r + 0.2f * color.g + 0.4f * color.b;
|
||||
|
||||
if(sum <= mark0)
|
||||
return color;
|
||||
if(sum <= mark1)
|
||||
return c0 * color.a * color1.a;
|
||||
if(sum <= mark2)
|
||||
return c1 * color.a * color1.a;
|
||||
|
||||
return c2 * color.a * color1.a;
|
||||
}
|
||||
|
||||
technique BasicColorDrawing
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL MainPS();
|
||||
}
|
||||
};
|
44
Content/Shader/ThanosShader.fx
Normal file
|
@ -0,0 +1,44 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_1
|
||||
#endif
|
||||
|
||||
float4x4 World;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
|
||||
Texture2D SpriteTexture;
|
||||
sampler2D sampler0 : register(s0)
|
||||
{
|
||||
};
|
||||
|
||||
Texture2D NoiceTexture;
|
||||
sampler sampler1 : register(s1)
|
||||
{
|
||||
Texture = (NoiceTexture);
|
||||
Filter = POINT;
|
||||
};
|
||||
|
||||
float Percentage;
|
||||
float2 Scale;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color1 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
float4 texColor = tex2D(sampler0, coords);
|
||||
if ((Percentage > 0 && Percentage >= tex2D(sampler1, coords * Scale).r) || Percentage == 1)
|
||||
return float4(0, 0, 0, 0);
|
||||
else
|
||||
return texColor * color1;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|
29
Content/Shader/WaleShader.fx
Normal file
|
@ -0,0 +1,29 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
sampler s0;
|
||||
|
||||
float Offset;
|
||||
float Period;
|
||||
float Time;
|
||||
|
||||
float4 MainPS(float4 pos : SV_Position, float4 color0 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
coords.x += sin(coords.y * Period + Time) * Offset;
|
||||
float4 color = tex2D(s0, coords);
|
||||
return color * color0;
|
||||
}
|
||||
|
||||
technique BasicColorDrawing
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL MainPS();
|
||||
}
|
||||
};
|
36
Content/Shader/WobbleShader.fx
Normal file
|
@ -0,0 +1,36 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
#define PI 3.1415926538
|
||||
|
||||
sampler s0;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
float scale;
|
||||
float brightness;
|
||||
float offset;
|
||||
|
||||
float offsetWidth;
|
||||
float offsetHeight;
|
||||
|
||||
float4 PixelShaderFunction(float4 pos : SV_Position, float4 color0 : COLOR0, float2 coords : TEXCOORD0) : COLOR0
|
||||
{
|
||||
// offset
|
||||
float offsetX = sin(offset + coords.y * (height / scale) / offsetHeight * PI + PI / 2) * (offsetWidth / (width / scale));
|
||||
return tex2D(s0, float2(coords.x + offsetX, coords.y)) * (1 - brightness) + float4(1, 1, 1, 1) * brightness;
|
||||
}
|
||||
|
||||
technique Technique1
|
||||
{
|
||||
pass Pass1
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
|
||||
}
|
||||
}
|