Skip to content

Commit 0742d56

Browse files
author
Mathew O'Dwyer
authored
game pad support (#321)
1 parent 695d549 commit 0742d56

File tree

10 files changed

+173
-5
lines changed

10 files changed

+173
-5
lines changed

FinalEngine.Example.Desktop/Startup.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// <copyright file="Startup.cs" company="Software Antics">
2-
// Copyright (c) Software Antics. All rights reserved.
2+
// Copyright (c) Software Antics. All rights reserved.
33
// </copyright>
44

55
namespace FinalEngine.Example.Desktop;
@@ -14,5 +14,6 @@ public void ConfigureServices(IServiceCollection services)
1414
{
1515
ArgumentNullException.ThrowIfNull(services, nameof(services));
1616
services.AddRuntime<Game>();
17+
services.AddSingleton<GameControllerInputEntitySystem>();
1718
}
1819
}

FinalEngine.Example/Game.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,51 @@
11
// <copyright file="Game.cs" company="Software Antics">
2-
// Copyright (c) Software Antics. All rights reserved.
2+
// Copyright (c) Software Antics. All rights reserved.
33
// </copyright>
44

55
namespace FinalEngine.Example;
66

7+
using System;
8+
using System.Collections.Generic;
9+
using System.Diagnostics.CodeAnalysis;
710
using System.Drawing;
811
using System.Numerics;
912
using FinalEngine.ECS;
13+
using FinalEngine.Input.Controllers;
1014
using FinalEngine.Rendering.Components;
1115
using FinalEngine.Rendering.Systems;
1216
using FinalEngine.Rendering.Textures;
1317
using FinalEngine.Runtime;
1418

19+
public class GameControllerInputEntitySystem : EntitySystemBase
20+
{
21+
private readonly IGameController controller;
22+
23+
public GameControllerInputEntitySystem(IGameController controller)
24+
{
25+
this.controller = controller ?? throw new ArgumentNullException(nameof(controller));
26+
}
27+
28+
protected override bool IsMatch([NotNull] IReadOnlyEntity entity)
29+
{
30+
return entity.ContainsComponent<TransformComponent>();
31+
}
32+
33+
protected override void Process([NotNull] IEnumerable<Entity> entities)
34+
{
35+
foreach (var entity in entities)
36+
{
37+
var transform = entity.GetComponent<TransformComponent>();
38+
transform.Translate(movement, 1);
39+
}
40+
}
41+
}
42+
1543
public sealed class Game : GameContainerBase
1644
{
1745
public override void Initialize()
1846
{
1947
this.World.AddSystem<SpriteRenderEntitySystem>();
48+
this.World.AddSystem<GameControllerInputEntitySystem>();
2049

2150
var entity = new Entity();
2251

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// <copyright file="ControllerAxis.cs" company="Software Antics">
2+
// Copyright (c) Software Antics. All rights reserved.
3+
// </copyright>
4+
5+
namespace FinalEngine.Input.Controllers;
6+
7+
public enum ControllerAxis
8+
{
9+
LeftX = 0,
10+
11+
LeftY = 1,
12+
13+
RightX = 2,
14+
15+
RightY = 3,
16+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// <copyright file="ControllerButton.cs" company="Software Antics">
2+
// Copyright (c) Software Antics. All rights reserved.
3+
// </copyright>
4+
5+
namespace FinalEngine.Input.Controllers;
6+
7+
public enum ControllerButton
8+
{
9+
A = 0,
10+
11+
B = 1,
12+
13+
X = 2,
14+
15+
Y = 3,
16+
17+
L1 = 4,
18+
19+
R1 = 5,
20+
21+
Select = 6,
22+
23+
Start = 7,
24+
25+
L3 = 8,
26+
27+
R3 = 9,
28+
29+
PadUp = 10,
30+
31+
PadRight = 11,
32+
33+
PadDown = 12,
34+
35+
PadLeft = 13,
36+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// <copyright file="IGameController.cs" company="Software Antics">
2+
// Copyright (c) Software Antics. All rights reserved.
3+
// </copyright>
4+
5+
namespace FinalEngine.Input.Controllers;
6+
7+
public interface IGameController
8+
{
9+
float GetAxis(int index, ControllerAxis axis);
10+
11+
bool IsButtonDown(int index, ControllerButton button);
12+
13+
bool IsButtonPressed(int index, ControllerButton button);
14+
15+
bool IsButtonReleased(int index, ControllerButton button);
16+
}

FinalEngine.Input/InputDriver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// <copyright file="InputDriver.cs" company="Software Antics">
2-
// Copyright (c) Software Antics. All rights reserved.
2+
// Copyright (c) Software Antics. All rights reserved.
33
// </copyright>
44

55
namespace FinalEngine.Input;

FinalEngine.Platform.Desktop/Extensions/ServiceCollectionExtensions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// <copyright file="ServiceCollectionExtensions.cs" company="Software Antics">
2-
// Copyright (c) Software Antics. All rights reserved.
2+
// Copyright (c) Software Antics. All rights reserved.
33
// </copyright>
44

55
namespace FinalEngine.Platform.Desktop.Extensions;
66

77
using System;
8+
using FinalEngine.Input.Controllers;
89
using FinalEngine.Input.Keyboards;
910
using FinalEngine.Input.Mouses;
1011
using FinalEngine.Platform.Desktop.OpenTK;
@@ -60,6 +61,7 @@ public static IServiceCollection AddPlatform(this IServiceCollection services)
6061

6162
services.AddSingleton<IKeyboardDevice, OpenTKKeyboardDevice>();
6263
services.AddSingleton<IMouseDevice, OpenTKMouseDevice>();
64+
services.AddSingleton<IGameController, OpenTKGameController>();
6365

6466
return services;
6567
}

FinalEngine.Platform.Desktop/OpenTK/Invocation/INativeWindowInvoker.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
namespace FinalEngine.Platform.Desktop.OpenTK.Invocation;
66

77
using System;
8+
using System.Collections.Generic;
89
using System.Diagnostics.CodeAnalysis;
910
using global::OpenTK.Mathematics;
1011
using global::OpenTK.Windowing.Common;
1112
using global::OpenTK.Windowing.Desktop;
13+
using global::OpenTK.Windowing.GraphicsLibraryFramework;
1214

1315
[SuppressMessage("Design", "CA1003:Use generic event handler instances", Justification = "Required by Invocation")]
1416
internal interface INativeWindowInvoker : IDisposable
@@ -37,6 +39,8 @@ internal interface INativeWindowInvoker : IDisposable
3739

3840
bool IsVisible { get; set; }
3941

42+
IReadOnlyList<JoystickState> JoystickStates { get; }
43+
4044
Vector2 MousePosition { get; set; }
4145

4246
IMouseStateInvoker MouseState { get; }
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// <copyright file="OpenTKGameController.cs" company="Software Antics">
2+
// Copyright (c) Software Antics. All rights reserved.
3+
// </copyright>
4+
5+
namespace FinalEngine.Platform.Desktop.OpenTK;
6+
7+
using FinalEngine.Input.Controllers;
8+
using FinalEngine.Platform.Desktop.OpenTK.Invocation;
9+
10+
internal sealed class OpenTKGameController : IGameController
11+
{
12+
private readonly INativeWindowInvoker window;
13+
14+
public OpenTKGameController(INativeWindowInvoker window)
15+
{
16+
this.window = window ?? throw new System.ArgumentNullException(nameof(window));
17+
}
18+
19+
public float GetAxis(int index, ControllerAxis axis)
20+
{
21+
if (!(this.window.JoystickStates.Count >= index))
22+
{
23+
return 0.0f;
24+
}
25+
26+
return this.window.JoystickStates[index].GetAxis((int)axis);
27+
}
28+
29+
public bool IsButtonDown(int index, ControllerButton button)
30+
{
31+
if (!(this.window.JoystickStates.Count >= index))
32+
{
33+
return false;
34+
}
35+
36+
return this.window.JoystickStates[index].IsButtonDown((int)button);
37+
}
38+
39+
public bool IsButtonPressed(int index, ControllerButton button)
40+
{
41+
if (!(this.window.JoystickStates.Count >= index))
42+
{
43+
return false;
44+
}
45+
46+
return this.window.JoystickStates[index].IsButtonPressed((int)button);
47+
}
48+
49+
public bool IsButtonReleased(int index, ControllerButton button)
50+
{
51+
if (!(this.window.JoystickStates.Count >= index))
52+
{
53+
return false;
54+
}
55+
56+
return this.window.JoystickStates[index].IsButtonReleased((int)button);
57+
}
58+
}

FinalEngine.Runtime/GameContainerBase.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// <copyright file="GameContainerBase.cs" company="Software Antics">
2-
// Copyright (c) Software Antics. All rights reserved.
2+
// Copyright (c) Software Antics. All rights reserved.
33
// </copyright>
44

55
namespace FinalEngine.Runtime;
66

77
using System;
8+
using System.Drawing;
89
using FinalEngine.ECS;
10+
using FinalEngine.Input.Controllers;
911
using FinalEngine.Input.Keyboards;
1012
using FinalEngine.Input.Mouses;
1113
using FinalEngine.Platform;
@@ -22,6 +24,7 @@ protected GameContainerBase()
2224
this.Window = ServiceLocator.Provider.GetRequiredService<IWindow>();
2325
this.Keyboard = ServiceLocator.Provider.GetRequiredService<IKeyboard>();
2426
this.Mouse = ServiceLocator.Provider.GetRequiredService<IMouse>();
27+
this.Controller = ServiceLocator.Provider.GetRequiredService<IGameController>();
2528
this.RenderDevice = ServiceLocator.Provider.GetRequiredService<IRenderDevice>();
2629
this.ResourceManager = ServiceLocator.Provider.GetRequiredService<IResourceManager>();
2730
this.Drawer = ServiceLocator.Provider.GetRequiredService<ISpriteDrawer>();
@@ -41,6 +44,8 @@ protected GameContainerBase()
4144
this.Dispose(false);
4245
}
4346

47+
protected IGameController Controller { get; private set; }
48+
4449
protected ISpriteDrawer Drawer { get; private set; }
4550

4651
protected bool IsDisposed { get; private set; }
@@ -78,6 +83,7 @@ public virtual void LoadContent()
7883

7984
public virtual void Render(float delta)
8085
{
86+
this.RenderDevice.Clear(Color.CornflowerBlue);
8187
this.World.ProcessAll(GameLoopType.Render);
8288
}
8389

0 commit comments

Comments
 (0)