using System;
using System.Collections.Generic;
using System.Drawing;
using GLFW;
namespace OpenGLTutorial.GameLoop {
public class Input {
///
/// Get the state of a key
/// Usage: Input.Keys[Keys.W]
///
public static Dict Keys { get; } = new (false);
///
/// Get the state of a mouse button
/// Usage: Input.MouseButtons[MouseButton.Button1]
///
public static Dict MouseButtons { get; } = new (false);
///
/// The screen position of the Mouse
///
public static Point MousePosition { get; set; } = new (0, 0);
///
/// The relative scroll offset from last frame
///
public static float MouseScroll { get; set; } = 0.0f;
///
/// Get the state of a joystick button
/// Usage: Input.JoystickButtons[Joystick.Joystick1][JoystickButton.A]
///
public static Dict> JoystickButtons { get; } = new(new Dict(false));
///
/// Get the state of a joystick axis
/// Usage: JoystickAxis[Joystick.Joystick1][JoystickAxis.LeftJoystickX]
///
public static Dict> JoystickAxis { get; } = new(new Dict(0.0f));
///
/// Get the state of the given axis
///
/// The axis
/// (OPTIONAL) The joystick to use
/// A value between -1 and 1
/// Throws an exception if the given axis does not exist
public static float GetAxis(Axis axis, Joystick joystick = Joystick.Joystick1) {
switch (axis) {
case Axis.Horizontal:
float x = JoystickAxis[joystick][GameLoop.JoystickAxis.LeftJoystickX];
if (Keys[GLFW.Keys.A]) x += -1.0f;
if (Keys[GLFW.Keys.D]) x += 1.0f;
return Math.Clamp(x, -1, 1);
case Axis.Vertical:
float y = JoystickAxis[joystick][GameLoop.JoystickAxis.LeftJoystickY];
if (Keys[GLFW.Keys.S]) y += -1.0f;
if (Keys[GLFW.Keys.W]) y += 1.0f;
return Math.Clamp(y, -1, 1);
case Axis.Junp:
float jump = JoystickButtons[joystick][JoystickButton.A] ? 1.0f : 0.0f;
if (Keys[GLFW.Keys.Space]) jump = 1.0f;
return jump;
default:
throw new System.Exception("Unexpected Token: '" + axis + "'. That Axis does not exist");
}
}
///
/// SYSTEM INTERNAL
///
public static void Update() {
UpdateJoystick(Joystick.Joystick1);
UpdateJoystick(Joystick.Joystick2);
UpdateJoystick(Joystick.Joystick3);
UpdateJoystick(Joystick.Joystick4);
UpdateJoystick(Joystick.Joystick5);
UpdateJoystick(Joystick.Joystick6);
UpdateJoystick(Joystick.Joystick7);
UpdateJoystick(Joystick.Joystick8);
UpdateJoystick(Joystick.Joystick9);
UpdateJoystick(Joystick.Joystick10);
UpdateJoystick(Joystick.Joystick11);
UpdateJoystick(Joystick.Joystick12);
UpdateJoystick(Joystick.Joystick13);
UpdateJoystick(Joystick.Joystick14);
UpdateJoystick(Joystick.Joystick15);
UpdateJoystick(Joystick.Joystick16);
}
private static void UpdateJoystick(Joystick joystick) {
if (!Glfw.JoystickPresent(joystick)) return;
float[] axis = Glfw.GetJoystickAxes(joystick);
JoystickAxis[joystick][GameLoop.JoystickAxis.LeftJoystickX] = ClampAxis(axis[0]);
JoystickAxis[joystick][GameLoop.JoystickAxis.LeftJoystickY] = -ClampAxis(axis[1]);
JoystickAxis[joystick][GameLoop.JoystickAxis.RightJoystickX] = ClampAxis(axis[2]);
JoystickAxis[joystick][GameLoop.JoystickAxis.RightJoystickY] = -ClampAxis(axis[3]);
JoystickAxis[joystick][GameLoop.JoystickAxis.LeftTrigger] = ClampAxis(axis[4]);
JoystickAxis[joystick][GameLoop.JoystickAxis.RightTrigger] = ClampAxis(axis[5]);
InputState[] buttons = Glfw.GetJoystickButtons(joystick);
JoystickButtons[joystick][JoystickButton.A] = buttons[0] != InputState.Release;
JoystickButtons[joystick][JoystickButton.B] = buttons[1] != InputState.Release;
JoystickButtons[joystick][JoystickButton.X] = buttons[2] != InputState.Release;
JoystickButtons[joystick][JoystickButton.Y] = buttons[3] != InputState.Release;
JoystickButtons[joystick][JoystickButton.Lb] = buttons[4] != InputState.Release;
JoystickButtons[joystick][JoystickButton.Rb] = buttons[5] != InputState.Release;
JoystickButtons[joystick][JoystickButton.Back] = buttons[6] != InputState.Release;
JoystickButtons[joystick][JoystickButton.Start] = buttons[7] != InputState.Release;
JoystickButtons[joystick][JoystickButton.Left] = buttons[8] != InputState.Release;
JoystickButtons[joystick][JoystickButton.Right] = buttons[9] != InputState.Release;
JoystickButtons[joystick][JoystickButton.DpadUp] = buttons[10] != InputState.Release;
JoystickButtons[joystick][JoystickButton.DpadRight] = buttons[11] != InputState.Release;
JoystickButtons[joystick][JoystickButton.DpadDown] = buttons[12] != InputState.Release;
JoystickButtons[joystick][JoystickButton.DpadLeft] = buttons[13] != InputState.Release;
}
private static float ClampAxis(float value) {
if (value < 0.15f && value > -0.15f)
value = 0;
return value;
}
}
public class Dict : Dictionary {
public TValue DefaultValue { get; set; }
public Dict(TValue defaultValue) => DefaultValue = defaultValue;
public new TValue this[TKey key] {
get => TryGetValue(key, out TValue t) ? t : DefaultValue;
set => base[key] = value;
}
}
public enum JoystickButton {
A,
B,
X,
Y,
Start,
Back,
Lb,
Rb,
Left,
Right,
DpadUp,
DpadDown,
DpadRight,
DpadLeft
}
public enum JoystickAxis {
LeftJoystickX,
LeftJoystickY,
RightJoystickX,
RightJoystickY,
LeftTrigger,
RightTrigger
}
public enum Axis {
Horizontal,
Vertical,
Junp
}
}