initial commit

This commit is contained in:
Phantop 2023-12-14 17:21:22 -05:00
commit d397789bb7
1482 changed files with 254936 additions and 0 deletions

17
Base/Basics.cs Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);
}
}
}

View 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
View 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

File diff suppressed because it is too large Load diff

BIN
Content/Editor/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

BIN
Content/Editor/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

BIN
Content/Editor/eye_open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

BIN
Content/Editor/select.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View 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>&#32;</Start>
<End>&#126;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>

View 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>&#32;</Start>
<End>&#126;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>

View 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>&#32;</Start>
<End>&#126;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
Content/Fonts/smallFont.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -0,0 +1,3 @@
1
2
doorLight:0,0,48,48,24,24

BIN
Content/Light/doorLight.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
Content/Light/dungeon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
Content/Light/light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

2
Content/Light/readme.txt Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
Content/Menu/copyIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

BIN
Content/Menu/gearIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

BIN
Content/Menu/trashIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

BIN
Content/Objects/fog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

61
Content/Shader/BBlurH.fx Normal file
View 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
View 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
View 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
View 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();
}
}

View 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();
}
};

View 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();
}
}

View 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();
}
};

View 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();
}
}

View 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();
}
}

View 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();
}
};

View 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();
}
}

View 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();
}
}

View 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();
}
};

View 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();
}
}

View 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();
}
}

View 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();
}
};

View 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();
}
}

View 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();
}
};

View 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();
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more