mirror of
https://github.com/Ed94/HandmadeHero.git
synced 2024-11-10 03:44:53 -08:00
97 lines
2.9 KiB
Markdown
97 lines
2.9 KiB
Markdown
# Day 13
|
|
|
|
Started to lifting input, not happy about my abstraction to gamepad state in hindsight. Which is kinda lead by how Casey is doing it.
|
|
|
|
The reality of how input is actually done in the games; that I've worked on; is we don't abstract the gamepad.
|
|
We just make a layout per device we decide to support (Dualsense/shock, xinput, nintendo, etc) and then just see what device is mapped to what player. This allows us to have a tailored layout to the device. Doing otherwise usually leads to some discrepancy in the UX for that layout for the user.
|
|
|
|
Casey has no concept of a player nor a device beyond xinput for this engine (at least up to this point), which is most likely fine for the scope of this project.
|
|
|
|
For the purposes of my version of Handmade I will make 3 devices that could be mapped to a `Controller` struct: `Keyboard & Mouse`, `Dualsense`, and `XInput`.
|
|
This is to retain implementation Casey is already making while also natively supporting the Dualsense controller from sony which I personally perfer to use.
|
|
|
|
From the 3 layer abstraction (platform/engine/game):
|
|
Platform will deal with the raw polling (and most likely down the line have a thread dedicated to running it as fast as possible).
|
|
It will provide the engine layer the pad states in the following struct:
|
|
|
|
```cpp
|
|
struct InputState
|
|
{
|
|
ControllerState Controllers[4];
|
|
};
|
|
```
|
|
|
|
There can only be four controllers available at a time and are equivalnet to the input aspect of a local player in Unreal.
|
|
(Sort of)
|
|
Each controller can be assigned the following:
|
|
|
|
```cpp
|
|
struct ControllerState
|
|
{
|
|
KeyboardState* Keyboard;
|
|
MousesState* Mouse;
|
|
XInputPadState* XPad;
|
|
DualsensePadState* DSPad;
|
|
};
|
|
```
|
|
|
|
If any are null that means the controller has no assignment.
|
|
Each pad state is the latest state but the platform keeps a record of the previous frame's state to compare against.
|
|
|
|
Exmaple for Dualsense:
|
|
|
|
```cpp
|
|
struct DualsensePadState
|
|
{
|
|
struct
|
|
{
|
|
AnalogStick Left;
|
|
AnalogStick Right;
|
|
} Stick;
|
|
|
|
AnalogAxis L2;
|
|
AnalogAxis R2;
|
|
|
|
union {
|
|
DigitalBtn Btns[14];
|
|
struct {
|
|
struct {
|
|
DigitalBtn Up;
|
|
DigitalBtn Down;
|
|
DigitalBtn Left;
|
|
DigitalBtn Right;
|
|
} DPad;
|
|
DigitalBtn X;
|
|
DigitalBtn Circle;
|
|
DigitalBtn Square;
|
|
DigitalBtn Triangle;
|
|
DigitalBtn Share;
|
|
DigitalBtn Options;
|
|
DigitalBtn L1;
|
|
DigitalBtn R1;
|
|
};
|
|
};
|
|
|
|
b32 using_analog()
|
|
{
|
|
return true;
|
|
};
|
|
};
|
|
```
|
|
|
|
The game layer handles mapping an input state of a controller to an action binding.
|
|
Possible action binding when we get to that point:
|
|
|
|
```cpp
|
|
struct ActionBinding
|
|
{
|
|
String InternalName;
|
|
StringCached LocalizedName;
|
|
|
|
DigitalBtnBinding* BtnBinds;
|
|
AxisBinding* AxisBinds;
|
|
StickBinding* StickBinds;
|
|
MouseBinding* MouseBinds;
|
|
};
|
|
```
|