mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 06:53:43 +00:00
XInput support
This commit is contained in:
@@ -31,6 +31,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GpDisplayDriver_D3D11", "Gp
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImportCharSet", "ImportCharSet\ImportCharSet.vcxproj", "{B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GpInputDriver_XInput", "GpInputDriver_XInput\GpInputDriver_XInput.vcxproj", "{17B96F07-EF92-47CD-95A5-8E6EE38AB564}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -151,6 +153,14 @@ Global
|
||||
{B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Release|x64.Build.0 = Release|x64
|
||||
{B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B3D152CB-CD52-4CD6-9213-710ADE1B8EB0}.Release|x86.Build.0 = Release|Win32
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Debug|x64.Build.0 = Debug|x64
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Debug|x86.Build.0 = Debug|Win32
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Release|x64.ActiveCfg = Release|x64
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Release|x64.Build.0 = Release|x64
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Release|x86.ActiveCfg = Release|Win32
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@@ -89,6 +89,10 @@ typedef struct
|
||||
// long encrypted, fakeLong;
|
||||
long wasLeftMap, wasRightMap;
|
||||
long wasBattMap, wasBandMap;
|
||||
long wasGPLeftMap, wasGPRightMap;
|
||||
long wasGPBattMap, wasGPBandMap;
|
||||
long wasGPFlipMap;
|
||||
long wasGPFaceLeftMap, wasGPFaceRightMap;
|
||||
short wasVolume;
|
||||
short prefVersion;
|
||||
short wasMaxFiles;
|
||||
|
@@ -551,8 +551,8 @@
|
||||
#define kGliderBurningHigh 26
|
||||
#define kShadowHigh 9
|
||||
#define kShadowTop 306
|
||||
#define kFaceRight TRUE
|
||||
#define kFaceLeft FALSE
|
||||
static const Boolean kFaceRight = TRUE; // Conflicts with GP input driver
|
||||
static const Boolean kFaceLeft = FALSE; // Conflicts with GP input driver
|
||||
#define kPlayer1 TRUE
|
||||
#define kPlayer2 FALSE
|
||||
#define kNumGliderSrcRects 31
|
||||
@@ -623,3 +623,5 @@
|
||||
#define kScoreboardPictID 1997
|
||||
|
||||
#define kDemoLength 6702
|
||||
|
||||
#define kGamepadDeadzone 4096 // Out of 32768
|
||||
|
@@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
#include "PLQDOffscreen.h"
|
||||
|
||||
#include "GpVOSEvent.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -208,6 +208,10 @@ typedef struct
|
||||
Rect clip, enteredRect;
|
||||
Int32 leftKey, rightKey;
|
||||
Int32 battKey, bandKey;
|
||||
Int32 gamepadLeftKey, gamepadRightKey;
|
||||
Int32 gamepadBattKey, gamepadBandKey;
|
||||
Int32 gamepadFlipKey;
|
||||
Int32 gamepadFaceLeftKey, gamepadFaceRightKey;
|
||||
short hVel, vVel;
|
||||
short wasHVel, wasVVel;
|
||||
short vDesiredVel, hDesiredVel;
|
||||
@@ -215,7 +219,7 @@ typedef struct
|
||||
Boolean facing, tipped;
|
||||
Boolean sliding, ignoreLeft, ignoreRight;
|
||||
Boolean fireHeld, which;
|
||||
Boolean heldLeft, heldRight;
|
||||
Boolean heldLeft, heldRight, heldFlip;
|
||||
Boolean dontDraw, ignoreGround;
|
||||
} gliderType, *gliderPtr;
|
||||
|
||||
|
103
GpApp/Input.cpp
103
GpApp/Input.cpp
@@ -9,6 +9,7 @@
|
||||
#include "PLDialogs.h"
|
||||
#include "PLKeyEncoding.h"
|
||||
#include "Externs.h"
|
||||
#include "InputManager.h"
|
||||
#include "MainWindow.h"
|
||||
#include "RectUtils.h"
|
||||
|
||||
@@ -198,9 +199,13 @@ void DoHeliumEngaged (gliderPtr thisGlider)
|
||||
#if BUILD_ARCADE_VERSION
|
||||
|
||||
if ((BitTst(theKeys, thisGlider->leftKey)) ||
|
||||
(BitTst(theKeys, thisGlider->gamepadLeftKey)) ||
|
||||
(BitTst(theKeys, thisGlider->rightKey)) ||
|
||||
(BitTst(theKeys, thisGlider->gamepadRightKey)) ||
|
||||
(BitTst(theKeys, thisGlider->battKey)) ||
|
||||
(BitTst(theKeys, thisGlider->bandKey)))
|
||||
(BitTst(theKeys, thisGlider->gamepadBattKey)) ||
|
||||
(BitTst(theKeys, thisGlider->bandKey)) ||
|
||||
(BitTst(theKeys, thisGlider->gamepadBandKey)))
|
||||
{
|
||||
playing = false;
|
||||
paused = false;
|
||||
@@ -302,38 +307,96 @@ void GetInput (gliderPtr thisGlider)
|
||||
}
|
||||
else
|
||||
{
|
||||
bool continuousFlipState = false;
|
||||
bool holdFlipState = false;
|
||||
bool leftState = false;
|
||||
bool rightState = false;
|
||||
|
||||
if (BitTst(theKeys, thisGlider->rightKey) || BitTst(theKeys, thisGlider->gamepadRightKey)) // right key
|
||||
{
|
||||
PL_NotYetImplemented_TODO("FixDemo"); // Flips aren't recorded in the demo properly
|
||||
|
||||
if (BitTst(theKeys, thisGlider->leftKey) || BitTst(theKeys, thisGlider->gamepadLeftKey))
|
||||
continuousFlipState = true;
|
||||
else
|
||||
rightState = true;
|
||||
}
|
||||
else if (BitTst(theKeys, thisGlider->leftKey) || BitTst(theKeys, thisGlider->gamepadLeftKey)) // left key
|
||||
leftState = true;
|
||||
else
|
||||
thisGlider->tipped = false;
|
||||
|
||||
if (BitTst(theKeys, thisGlider->gamepadRightKey))
|
||||
rightState = true;
|
||||
|
||||
if (BitTst(theKeys, thisGlider->gamepadLeftKey))
|
||||
leftState = true;
|
||||
|
||||
if (BitTst(theKeys, thisGlider->gamepadFaceLeftKey) && thisGlider->facing == kFaceRight)
|
||||
continuousFlipState = true;
|
||||
|
||||
if (BitTst(theKeys, thisGlider->gamepadFaceRightKey) && thisGlider->facing == kFaceLeft)
|
||||
continuousFlipState = true;
|
||||
|
||||
if (BitTst(theKeys, thisGlider->gamepadFlipKey))
|
||||
holdFlipState = true;
|
||||
|
||||
if (thisGlider->which == kPlayer1 || thisGlider->which == kPlayer2)
|
||||
{
|
||||
unsigned int playerNum = 0;
|
||||
if (thisGlider->which == kPlayer1)
|
||||
playerNum = 0;
|
||||
else if (thisGlider->which == kPlayer2)
|
||||
playerNum = 1;
|
||||
|
||||
int16_t inputAxis = PortabilityLayer::InputManager::GetInstance()->GetGamepadAxis(playerNum, GpGamepadAxes::kLeftStickX);
|
||||
if (inputAxis <= -kGamepadDeadzone)
|
||||
leftState = true;
|
||||
else if (inputAxis >= kGamepadDeadzone)
|
||||
rightState = true;
|
||||
}
|
||||
|
||||
// gamepad flip key
|
||||
//if (BitTst(theKeys, thisGlider->gamepadFlipKey))
|
||||
// holdFlipState = true;
|
||||
|
||||
thisGlider->heldLeft = false;
|
||||
thisGlider->heldRight = false;
|
||||
if (BitTst(theKeys, thisGlider->rightKey)) // right key
|
||||
if (continuousFlipState)
|
||||
{
|
||||
#ifdef CREATEDEMODATA
|
||||
LogDemoKey(0);
|
||||
#endif
|
||||
if (BitTst(theKeys, thisGlider->leftKey))
|
||||
leftState = false;
|
||||
rightState = false;
|
||||
ToggleGliderFacing(thisGlider);
|
||||
}
|
||||
else if (holdFlipState)
|
||||
{
|
||||
if (!thisGlider->heldFlip)
|
||||
{
|
||||
ToggleGliderFacing(thisGlider);
|
||||
thisGlider->heldLeft = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
thisGlider->hDesiredVel += kNormalThrust;
|
||||
thisGlider->tipped = (thisGlider->facing == kFaceLeft);
|
||||
thisGlider->heldRight = true;
|
||||
thisGlider->heldFlip = true;
|
||||
}
|
||||
}
|
||||
else if (BitTst(theKeys, thisGlider->leftKey)) // left key
|
||||
else
|
||||
thisGlider->heldFlip = false;
|
||||
|
||||
if (rightState && !leftState)
|
||||
{
|
||||
thisGlider->hDesiredVel += kNormalThrust;
|
||||
thisGlider->tipped = (thisGlider->facing == kFaceLeft);
|
||||
thisGlider->heldRight = true;
|
||||
}
|
||||
|
||||
if (leftState && !rightState)
|
||||
{
|
||||
#ifdef CREATEDEMODATA
|
||||
LogDemoKey(1);
|
||||
#endif
|
||||
thisGlider->hDesiredVel -= kNormalThrust;
|
||||
thisGlider->tipped = (thisGlider->facing == kFaceRight);
|
||||
thisGlider->heldLeft = true;
|
||||
}
|
||||
else
|
||||
|
||||
if (!leftState && !rightState)
|
||||
thisGlider->tipped = false;
|
||||
|
||||
if ((BitTst(theKeys, thisGlider->battKey)) && (batteryTotal != 0) &&
|
||||
if ((BitTst(theKeys, thisGlider->battKey) || BitTst(theKeys, thisGlider->gamepadBattKey)) && (batteryTotal != 0) &&
|
||||
(thisGlider->mode == kGliderNormal))
|
||||
{
|
||||
#ifdef CREATEDEMODATA
|
||||
@@ -347,7 +410,7 @@ void GetInput (gliderPtr thisGlider)
|
||||
else
|
||||
batteryWasEngaged = false;
|
||||
|
||||
if ((BitTst(theKeys, thisGlider->bandKey)) && (bandsTotal > 0) &&
|
||||
if ((BitTst(theKeys, thisGlider->bandKey) || BitTst(theKeys, thisGlider->gamepadBandKey)) && (bandsTotal > 0) &&
|
||||
(thisGlider->mode == kGliderNormal))
|
||||
{
|
||||
#ifdef CREATEDEMODATA
|
||||
|
@@ -140,6 +140,10 @@ void VariableInit (void)
|
||||
theGlider2.rightKey = PL_KEY_ASCII('D');
|
||||
theGlider2.battKey = PL_KEY_ASCII('S');
|
||||
theGlider2.bandKey = PL_KEY_ASCII('W');
|
||||
theGlider2.gamepadLeftKey = PL_KEY_GAMEPAD_BUTTON(kDPadLeft, 1);
|
||||
theGlider2.gamepadRightKey = PL_KEY_GAMEPAD_BUTTON(kDPadRight, 1);
|
||||
theGlider2.gamepadBandKey = PL_KEY_GAMEPAD_BUTTON(kFaceDown, 1);
|
||||
theGlider2.gamepadBattKey = PL_KEY_GAMEPAD_BUTTON(kFaceLeft, 1);
|
||||
theGlider2.which = kPlayer2;
|
||||
|
||||
theMode = kSplashMode;
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#include "House.h"
|
||||
|
||||
|
||||
#define kPrefsVersion 0x0034
|
||||
#define kPrefsVersion 0x0035
|
||||
|
||||
|
||||
void ReadInPrefs (void);
|
||||
@@ -72,6 +72,13 @@ void ReadInPrefs (void)
|
||||
theGlider.rightKey = thePrefs.wasRightMap;
|
||||
theGlider.battKey = thePrefs.wasBattMap;
|
||||
theGlider.bandKey = thePrefs.wasBandMap;
|
||||
theGlider.gamepadLeftKey = thePrefs.wasGPLeftMap;
|
||||
theGlider.gamepadRightKey = thePrefs.wasGPRightMap;
|
||||
theGlider.gamepadBandKey = thePrefs.wasGPBandMap;
|
||||
theGlider.gamepadBattKey = thePrefs.wasGPBattMap;
|
||||
theGlider.gamepadFlipKey = thePrefs.wasGPFlipMap;
|
||||
theGlider.gamepadFaceRightKey = thePrefs.wasGPFaceRightMap;
|
||||
theGlider.gamepadFaceLeftKey = thePrefs.wasGPFaceLeftMap;
|
||||
#ifndef COMPILEDEMO
|
||||
#ifndef COMPILENOCP
|
||||
encryptedNumber = thePrefs.encrypted;
|
||||
@@ -138,6 +145,13 @@ void ReadInPrefs (void)
|
||||
theGlider.rightKey = PL_KEY_SPECIAL(kRightArrow);
|
||||
theGlider.battKey = PL_KEY_SPECIAL(kDownArrow);
|
||||
theGlider.bandKey = PL_KEY_SPECIAL(kUpArrow);
|
||||
theGlider.gamepadLeftKey = PL_KEY_GAMEPAD_BUTTON(kDPadLeft, 0);
|
||||
theGlider.gamepadRightKey = PL_KEY_GAMEPAD_BUTTON(kDPadRight, 0);
|
||||
theGlider.gamepadBandKey = PL_KEY_GAMEPAD_BUTTON(kFaceDown, 0);
|
||||
theGlider.gamepadBattKey = PL_KEY_GAMEPAD_BUTTON(kFaceLeft, 0);
|
||||
theGlider.gamepadFlipKey = PL_KEY_GAMEPAD_BUTTON(kFaceUp, 0);
|
||||
theGlider.gamepadFaceRightKey = PL_KEY_GAMEPAD_BUTTON(kRightBumper, 0);
|
||||
theGlider.gamepadFaceLeftKey = PL_KEY_GAMEPAD_BUTTON(kLeftBumper, 0);
|
||||
|
||||
UnivGetSoundVolume(&isVolume, thisMac.hasSM3);
|
||||
if (isVolume < 1)
|
||||
@@ -228,6 +242,13 @@ void WriteOutPrefs (void)
|
||||
thePrefs.wasRightMap = theGlider.rightKey;
|
||||
thePrefs.wasBattMap = theGlider.battKey;
|
||||
thePrefs.wasBandMap = theGlider.bandKey;
|
||||
thePrefs.wasGPLeftMap = theGlider.gamepadLeftKey;
|
||||
thePrefs.wasGPRightMap = theGlider.gamepadRightKey;
|
||||
thePrefs.wasGPBattMap = theGlider.gamepadBattKey;
|
||||
thePrefs.wasGPBandMap = theGlider.gamepadBandKey;
|
||||
thePrefs.wasGPFlipMap = theGlider.gamepadFlipKey;
|
||||
thePrefs.wasGPFaceLeftMap = theGlider.gamepadFaceLeftKey;
|
||||
thePrefs.wasGPFaceRightMap = theGlider.gamepadFaceRightKey;
|
||||
#ifndef COMPILEDEMO
|
||||
#ifndef COMPILENOCP
|
||||
thePrefs.encrypted = encryptedNumber;
|
||||
|
@@ -1225,6 +1225,13 @@ void SetAllDefaults (void)
|
||||
theGlider.rightKey = PL_KEY_SPECIAL(kRightArrow);
|
||||
theGlider.battKey = PL_KEY_SPECIAL(kDownArrow);
|
||||
theGlider.bandKey = PL_KEY_SPECIAL(kUpArrow);
|
||||
theGlider.gamepadLeftKey = PL_KEY_GAMEPAD_BUTTON(kDPadLeft, 0);
|
||||
theGlider.gamepadRightKey = PL_KEY_GAMEPAD_BUTTON(kDPadRight, 0);
|
||||
theGlider.gamepadBandKey = PL_KEY_GAMEPAD_BUTTON(kFaceDown, 0);
|
||||
theGlider.gamepadBattKey = PL_KEY_GAMEPAD_BUTTON(kFaceLeft, 0);
|
||||
theGlider.gamepadFlipKey = PL_KEY_GAMEPAD_BUTTON(kFaceUp, 0);
|
||||
theGlider.gamepadFaceRightKey = PL_KEY_GAMEPAD_BUTTON(kRightBumper, 0);
|
||||
theGlider.gamepadFaceLeftKey = PL_KEY_GAMEPAD_BUTTON(kLeftBumper, 0);
|
||||
isEscPauseKey = false;
|
||||
// Default sound settings
|
||||
isPlayMusicIdle = true;
|
||||
|
8
GpCommon/EGpInputDriverType.h
Normal file
8
GpCommon/EGpInputDriverType.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
enum EGpInputDriverType
|
||||
{
|
||||
EGpInputDriverType_XInput,
|
||||
|
||||
EGpInputDriverType_Count,
|
||||
};
|
13
GpCommon/GpInputDriverProperties.h
Normal file
13
GpCommon/GpInputDriverProperties.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "EGpInputDriverType.h"
|
||||
|
||||
struct IGpAudioDriver;
|
||||
struct IGpVOSEventQueue;
|
||||
|
||||
struct GpInputDriverProperties
|
||||
{
|
||||
EGpInputDriverType m_type;
|
||||
|
||||
IGpVOSEventQueue *m_eventQueue;
|
||||
};
|
@@ -21,11 +21,62 @@ namespace GpKeyIDSubsets
|
||||
kNumPadNumber,
|
||||
kNumPadSpecial,
|
||||
kFKey, // Key value is a raw F number
|
||||
kGamepadButton,
|
||||
|
||||
kCount,
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpKeyIDSubsets::GpKeyIDSubset GpKeyIDSubset_t;
|
||||
|
||||
namespace GpGamepadButtons
|
||||
{
|
||||
enum GpGamepadButton
|
||||
{
|
||||
kDPadUp,
|
||||
kDPadDown,
|
||||
kDPadLeft,
|
||||
kDPadRight,
|
||||
|
||||
kFaceUp,
|
||||
kFaceDown,
|
||||
kFaceLeft,
|
||||
kFaceRight,
|
||||
|
||||
kLeftStick,
|
||||
kRightStick,
|
||||
|
||||
kLeftBumper,
|
||||
kRightBumper,
|
||||
|
||||
kMisc1,
|
||||
kMisc2,
|
||||
|
||||
kCount,
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpGamepadButtons::GpGamepadButton GpGamepadButton_t;
|
||||
|
||||
namespace GpGamepadAxes
|
||||
{
|
||||
enum GpGamepadAxis
|
||||
{
|
||||
kLeftStickX,
|
||||
kLeftStickY,
|
||||
|
||||
kRightStickX,
|
||||
kRightStickY,
|
||||
|
||||
kLeftTrigger,
|
||||
kRightTrigger,
|
||||
|
||||
kCount,
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpGamepadAxes::GpGamepadAxis GpGamepadAxis_t;
|
||||
|
||||
namespace GpKeySpecials
|
||||
{
|
||||
enum GpKeySpecial
|
||||
@@ -90,6 +141,22 @@ namespace GpKeyboardInputEventTypes
|
||||
|
||||
typedef GpKeyboardInputEventTypes::GpKeyboardInputEventType GpKeyboardInputEventType_t;
|
||||
|
||||
namespace GpGamepadInputEventTypes
|
||||
{
|
||||
enum GpGamepadInputEventType
|
||||
{
|
||||
kAnalogAxisChanged,
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpGamepadInputEventTypes::GpGamepadInputEventType GpGamepadInputEventTypes_t;
|
||||
|
||||
struct GpGamepadButtonAndPlayer
|
||||
{
|
||||
GpGamepadButton_t m_button;
|
||||
uint8_t m_player;
|
||||
};
|
||||
|
||||
struct GpKeyboardInputEvent
|
||||
{
|
||||
union KeyUnion
|
||||
@@ -100,6 +167,7 @@ struct GpKeyboardInputEvent
|
||||
char m_asciiChar;
|
||||
uint32_t m_unicodeChar;
|
||||
unsigned char m_fKey;
|
||||
GpGamepadButtonAndPlayer m_gamepadKey;
|
||||
};
|
||||
|
||||
GpKeyboardInputEventType_t m_eventType;
|
||||
@@ -107,6 +175,24 @@ struct GpKeyboardInputEvent
|
||||
KeyUnion m_key;
|
||||
};
|
||||
|
||||
struct GpGamepadAnalogAxisEvent
|
||||
{
|
||||
GpGamepadAxis_t m_axis;
|
||||
int16_t m_state; // Ranges from -32767 to 32767, is never -32768
|
||||
uint8_t m_player;
|
||||
};
|
||||
|
||||
struct GpGamepadInputEvent
|
||||
{
|
||||
union EventUnion
|
||||
{
|
||||
GpGamepadAnalogAxisEvent m_analogAxisEvent;
|
||||
};
|
||||
|
||||
GpGamepadInputEventTypes_t m_eventType;
|
||||
EventUnion m_event;
|
||||
};
|
||||
|
||||
namespace GpMouseEventTypes
|
||||
{
|
||||
enum GpMouseEventType
|
||||
@@ -149,6 +235,7 @@ namespace GpVOSEventTypes
|
||||
{
|
||||
kKeyboardInput,
|
||||
kMouseInput,
|
||||
kGamepadInput,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -160,6 +247,7 @@ struct GpVOSEvent
|
||||
{
|
||||
GpKeyboardInputEvent m_keyboardInputEvent;
|
||||
GpMouseInputEvent m_mouseInputEvent;
|
||||
GpGamepadInputEvent m_gamepadInputEvent;
|
||||
};
|
||||
|
||||
EventUnion m_event;
|
||||
|
@@ -2,4 +2,6 @@
|
||||
|
||||
struct IGpInputDriver
|
||||
{
|
||||
virtual void ProcessInput() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
};
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include "GpPLGlueDisplayDriver.h"
|
||||
#include "HostSuspendCallArgument.h"
|
||||
#include "IGpFiber.h"
|
||||
#include "IGpInputDriver.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -13,6 +14,8 @@ GpAppEnvironment::GpAppEnvironment()
|
||||
: m_applicationState(ApplicationState_NotStarted)
|
||||
, m_displayDriver(nullptr)
|
||||
, m_audioDriver(nullptr)
|
||||
, m_inputDrivers(nullptr)
|
||||
, m_numInputDrivers(0)
|
||||
, m_fontHandler(nullptr)
|
||||
, m_vosEventQueue(nullptr)
|
||||
, m_applicationFiber(nullptr)
|
||||
@@ -53,6 +56,7 @@ void GpAppEnvironment::Tick(IGpFiber *vosFiber)
|
||||
case ApplicationState_WaitingForEvents:
|
||||
return;
|
||||
case ApplicationState_Running:
|
||||
SynchronizeState();
|
||||
m_applicationFiber->YieldTo();
|
||||
break;
|
||||
case ApplicationState_SystemCall:
|
||||
@@ -96,6 +100,12 @@ void GpAppEnvironment::SetAudioDriver(IGpAudioDriver *audioDriver)
|
||||
m_audioDriver = audioDriver;
|
||||
}
|
||||
|
||||
void GpAppEnvironment::SetInputDrivers(IGpInputDriver *const* inputDrivers, size_t numDrivers)
|
||||
{
|
||||
m_inputDrivers = inputDrivers;
|
||||
m_numInputDrivers = numDrivers;
|
||||
}
|
||||
|
||||
void GpAppEnvironment::SetFontHandler(PortabilityLayer::HostFontHandler *fontHandler)
|
||||
{
|
||||
m_fontHandler = fontHandler;
|
||||
@@ -125,13 +135,15 @@ void GpAppEnvironment::InitializeApplicationState()
|
||||
GpAppInterface_Get()->PL_HostFontHandler_SetInstance(m_fontHandler);
|
||||
GpAppInterface_Get()->PL_HostVOSEventQueue_SetInstance(m_vosEventQueue);
|
||||
|
||||
SynchronizeState();
|
||||
GpPLGlueDisplayDriver::GetInstance()->SetGpDisplayDriver(m_displayDriver);
|
||||
GpPLGlueAudioDriver::GetInstance()->SetGpAudioDriver(m_audioDriver);
|
||||
}
|
||||
|
||||
void GpAppEnvironment::SynchronizeState()
|
||||
{
|
||||
GpPLGlueDisplayDriver::GetInstance()->SetGpDisplayDriver(m_displayDriver);
|
||||
GpPLGlueAudioDriver::GetInstance()->SetGpAudioDriver(m_audioDriver);
|
||||
const size_t numInputDrivers = m_numInputDrivers;
|
||||
for (size_t i = 0; i < numInputDrivers; i++)
|
||||
m_inputDrivers[i]->ProcessInput();
|
||||
}
|
||||
|
||||
void GpAppEnvironment::StaticSuspendHookFunc(void *context, PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
|
||||
|
@@ -14,6 +14,7 @@ namespace PortabilityLayer
|
||||
|
||||
struct IGpDisplayDriver;
|
||||
struct IGpAudioDriver;
|
||||
struct IGpInputDriver;
|
||||
struct IGpFiber;
|
||||
|
||||
class GpAppEnvironment
|
||||
@@ -29,6 +30,7 @@ public:
|
||||
|
||||
void SetDisplayDriver(IGpDisplayDriver *displayDriver);
|
||||
void SetAudioDriver(IGpAudioDriver *audioDriver);
|
||||
void SetInputDrivers(IGpInputDriver *const* inputDrivers, size_t numDrivers);
|
||||
void SetFontHandler(PortabilityLayer::HostFontHandler *fontHandler);
|
||||
void SetVOSEventQueue(GpVOSEventQueue *eventQueue);
|
||||
|
||||
@@ -54,12 +56,14 @@ private:
|
||||
ApplicationState m_applicationState;
|
||||
IGpDisplayDriver *m_displayDriver;
|
||||
IGpAudioDriver *m_audioDriver;
|
||||
IGpInputDriver *const* m_inputDrivers;
|
||||
PortabilityLayer::HostFontHandler *m_fontHandler;
|
||||
GpVOSEventQueue *m_vosEventQueue;
|
||||
IGpFiber *m_applicationFiber;
|
||||
IGpFiber *m_vosFiber;
|
||||
|
||||
uint32_t m_delaySuspendTicks;
|
||||
size_t m_numInputDrivers;
|
||||
|
||||
PortabilityLayer::HostSuspendCallID m_suspendCallID;
|
||||
const PortabilityLayer::HostSuspendCallArgument *m_suspendArgs;
|
||||
|
@@ -153,6 +153,7 @@
|
||||
<ClCompile Include="GpFontHandlerFactory.cpp" />
|
||||
<ClCompile Include="GpFontHandler_FreeType2.cpp" />
|
||||
<ClCompile Include="GpGlobalConfig.cpp" />
|
||||
<ClCompile Include="GpInputDriverFactory.cpp" />
|
||||
<ClCompile Include="GpMain.cpp" />
|
||||
<ClCompile Include="GpMain_Win32.cpp" />
|
||||
<ClCompile Include="GpMemoryBuffer.cpp" />
|
||||
@@ -166,20 +167,18 @@
|
||||
<ClCompile Include="GpVOSEventQueue.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\GpCommon\EGpInputDriverType.h" />
|
||||
<ClInclude Include="..\GpCommon\EGpStandardCursor.h" />
|
||||
<ClInclude Include="..\GpCommon\GpInputDriverProperties.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpColorCursor.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpAudioChannelCallbacks.h" />
|
||||
<ClInclude Include="..\GpCommon\GpColorCursor_Win32.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpDisplayDriverSurface.h" />
|
||||
<ClInclude Include="EGpAudioDriverType.h" />
|
||||
<ClInclude Include="EGpDisplayDriverType.h" />
|
||||
<ClInclude Include="GpAppEnvironment.h" />
|
||||
<ClInclude Include="GpAudioDriverFactory.h" />
|
||||
<ClInclude Include="GpAudioDriverProperties.h" />
|
||||
<ClInclude Include="GpComPtr.h" />
|
||||
<ClInclude Include="GpCoreDefs.h" />
|
||||
<ClInclude Include="GpDisplayDriverFactory.h" />
|
||||
<ClInclude Include="GpDisplayDriverProperties.h" />
|
||||
<ClInclude Include="GpFiber.h" />
|
||||
<ClInclude Include="GpFiber_Win32.h" />
|
||||
<ClInclude Include="GpFileStream_Win32.h" />
|
||||
@@ -187,6 +186,7 @@
|
||||
<ClInclude Include="GpFontHandler_FreeType2.h" />
|
||||
<ClInclude Include="GpFontHandlerFactory.h" />
|
||||
<ClInclude Include="GpGlobalConfig.h" />
|
||||
<ClInclude Include="GpInputDriverFactory.h" />
|
||||
<ClInclude Include="GpMain.h" />
|
||||
<ClInclude Include="GpMemoryBuffer.h" />
|
||||
<ClInclude Include="GpMutex_Win32.h" />
|
||||
@@ -217,6 +217,9 @@
|
||||
<ProjectReference Include="..\GpDisplayDriver_D3D11\GpDisplayDriver_D3D11.vcxproj">
|
||||
<Project>{ffc961ac-55b4-4a38-a83e-06ae98f59acc}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GpInputDriver_XInput\GpInputDriver_XInput.vcxproj">
|
||||
<Project>{17b96f07-ef92-47cd-95a5-8e6ee38ab564}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="GpD3D.rc" />
|
||||
|
@@ -78,6 +78,9 @@
|
||||
<ClCompile Include="GpColorCursor_Win32.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GpInputDriverFactory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GpWindows.h">
|
||||
@@ -92,12 +95,6 @@
|
||||
<ClInclude Include="GpMain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EGpDisplayDriverType.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GpDisplayDriverProperties.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GpGlobalConfig.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -140,12 +137,6 @@
|
||||
<ClInclude Include="GpAudioDriverFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EGpAudioDriverType.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GpAudioDriverProperties.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GpPLGlueAudioDriver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -191,6 +182,15 @@
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GpInputDriverFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\EGpInputDriverType.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\GpInputDriverProperties.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="GpD3D.rc">
|
||||
|
@@ -7,8 +7,8 @@ IGpDisplayDriver *GpDisplayDriverFactory::CreateDisplayDriver(const GpDisplayDri
|
||||
{
|
||||
assert(properties.m_type < EGpDisplayDriverType_Count);
|
||||
|
||||
if (ms_Registry[properties.m_type])
|
||||
return ms_Registry[properties.m_type](properties);
|
||||
if (ms_registry[properties.m_type])
|
||||
return ms_registry[properties.m_type](properties);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
@@ -17,7 +17,7 @@ void GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType t
|
||||
{
|
||||
assert(type < EGpDisplayDriverType_Count);
|
||||
|
||||
ms_Registry[type] = func;
|
||||
ms_registry[type] = func;
|
||||
}
|
||||
|
||||
GpDisplayDriverFactory::FactoryFunc_t GpDisplayDriverFactory::ms_Registry[EGpDisplayDriverType_Count];
|
||||
GpDisplayDriverFactory::FactoryFunc_t GpDisplayDriverFactory::ms_registry[EGpDisplayDriverType_Count];
|
||||
|
@@ -14,5 +14,5 @@ public:
|
||||
static void RegisterDisplayDriverFactory(EGpDisplayDriverType type, FactoryFunc_t func);
|
||||
|
||||
private:
|
||||
static FactoryFunc_t ms_Registry[EGpDisplayDriverType_Count];
|
||||
static FactoryFunc_t ms_registry[EGpDisplayDriverType_Count];
|
||||
};
|
||||
|
@@ -1,10 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "EGpDisplayDriverType.h"
|
||||
#include "EGpAudioDriverType.h"
|
||||
#include "EGpInputDriverType.h"
|
||||
|
||||
struct GpGlobalConfig
|
||||
{
|
||||
EGpDisplayDriverType m_displayDriverType;
|
||||
EGpAudioDriverType m_audioDriverType;
|
||||
const EGpInputDriverType *m_inputDriverTypes;
|
||||
size_t m_numInputDrivers;
|
||||
|
||||
void *m_osGlobals;
|
||||
};
|
||||
|
||||
|
23
GpD3D/GpInputDriverFactory.cpp
Normal file
23
GpD3D/GpInputDriverFactory.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "GpInputDriverFactory.h"
|
||||
#include "GpInputDriverProperties.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
IGpInputDriver *GpInputDriverFactory::CreateInputDriver(const GpInputDriverProperties &properties)
|
||||
{
|
||||
assert(properties.m_type < EGpInputDriverType_Count);
|
||||
|
||||
if (ms_registry[properties.m_type])
|
||||
return ms_registry[properties.m_type](properties);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GpInputDriverFactory::RegisterInputDriverFactory(EGpInputDriverType type, FactoryFunc_t func)
|
||||
{
|
||||
assert(type < EGpInputDriverType_Count);
|
||||
|
||||
ms_registry[type] = func;
|
||||
}
|
||||
|
||||
GpInputDriverFactory::FactoryFunc_t GpInputDriverFactory::ms_registry[EGpInputDriverType_Count];
|
18
GpD3D/GpInputDriverFactory.h
Normal file
18
GpD3D/GpInputDriverFactory.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "EGpInputDriverType.h"
|
||||
|
||||
struct IGpInputDriver;
|
||||
struct GpInputDriverProperties;
|
||||
|
||||
class GpInputDriverFactory
|
||||
{
|
||||
public:
|
||||
typedef IGpInputDriver *(*FactoryFunc_t)(const GpInputDriverProperties &properties);
|
||||
|
||||
static IGpInputDriver *CreateInputDriver(const GpInputDriverProperties &properties);
|
||||
static void RegisterInputDriverFactory(EGpInputDriverType type, FactoryFunc_t func);
|
||||
|
||||
private:
|
||||
static FactoryFunc_t ms_registry[EGpInputDriverType_Count];
|
||||
};
|
@@ -4,12 +4,16 @@
|
||||
#include "GpFontHandlerFactory.h"
|
||||
#include "GpDisplayDriverFactory.h"
|
||||
#include "GpDisplayDriverProperties.h"
|
||||
#include "GpInputDriverFactory.h"
|
||||
#include "GpInputDriverProperties.h"
|
||||
#include "GpGlobalConfig.h"
|
||||
#include "GpAppEnvironment.h"
|
||||
#include "IGpAudioDriver.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
#include "IGpInputDriver.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -32,8 +36,6 @@ int GpMain::Run()
|
||||
GpDisplayDriverProperties ddProps;
|
||||
memset(&ddProps, 0, sizeof(ddProps));
|
||||
|
||||
ddProps.m_type = EGpDisplayDriverType_D3D11;
|
||||
|
||||
ddProps.m_frameTimeLockNumerator = 1;
|
||||
ddProps.m_frameTimeLockDenominator = 60;
|
||||
|
||||
@@ -58,10 +60,28 @@ int GpMain::Run()
|
||||
|
||||
// The sample rate used in all of Glider PRO's sound is 0x56ee8ba3
|
||||
// This appears to be the "standard" Mac sample rate, probably rounded from 244800/11.
|
||||
adProps.m_type = EGpAudioDriverType_XAudio2;
|
||||
adProps.m_type = g_gpGlobalConfig.m_audioDriverType;
|
||||
adProps.m_sampleRate = (244800 * 2 + 11) / (11 * 2);
|
||||
adProps.m_debug = true;
|
||||
|
||||
IGpInputDriver **inputDrivers = static_cast<IGpInputDriver**>(malloc(sizeof(IGpInputDriver*) * g_gpGlobalConfig.m_numInputDrivers));
|
||||
|
||||
size_t numCreatedInputDrivers = 0;
|
||||
if (inputDrivers)
|
||||
{
|
||||
for (size_t i = 0; i < g_gpGlobalConfig.m_numInputDrivers; i++)
|
||||
{
|
||||
GpInputDriverProperties inputProps;
|
||||
memset(&inputProps, 0, sizeof(inputProps));
|
||||
|
||||
inputProps.m_type = g_gpGlobalConfig.m_inputDriverTypes[i];
|
||||
inputProps.m_eventQueue = eventQueue;
|
||||
|
||||
if (IGpInputDriver *driver = GpInputDriverFactory::CreateInputDriver(inputProps))
|
||||
inputDrivers[numCreatedInputDrivers++] = driver;
|
||||
}
|
||||
}
|
||||
|
||||
IGpDisplayDriver *displayDriver = GpDisplayDriverFactory::CreateDisplayDriver(ddProps);
|
||||
IGpAudioDriver *audioDriver = GpAudioDriverFactory::CreateAudioDriver(adProps);
|
||||
PortabilityLayer::HostFontHandler *fontHandler = GpFontHandlerFactory::Create();
|
||||
@@ -70,11 +90,23 @@ int GpMain::Run()
|
||||
|
||||
appEnvironment->SetDisplayDriver(displayDriver);
|
||||
appEnvironment->SetAudioDriver(audioDriver);
|
||||
appEnvironment->SetInputDrivers(inputDrivers, numCreatedInputDrivers);
|
||||
appEnvironment->SetFontHandler(fontHandler);
|
||||
appEnvironment->SetVOSEventQueue(eventQueue);
|
||||
|
||||
// Start the display loop
|
||||
displayDriver->Run();
|
||||
|
||||
// Clean up
|
||||
if (inputDrivers)
|
||||
{
|
||||
for (size_t i = 0; i < numCreatedInputDrivers; i++)
|
||||
inputDrivers[i]->Shutdown();
|
||||
|
||||
free(inputDrivers);
|
||||
}
|
||||
|
||||
// GP TODO: Cleanup
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include "GpGlobalConfig.h"
|
||||
#include "GpFiber_Win32.h"
|
||||
#include "GpFileSystem_Win32.h"
|
||||
#include "GpInputDriverFactory.h"
|
||||
#include "GpAppInterface.h"
|
||||
#include "GpSystemServices_Win32.h"
|
||||
#include "GpVOSEvent.h"
|
||||
@@ -21,6 +22,7 @@ GpWindowsGlobals g_gpWindowsGlobals;
|
||||
|
||||
extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAudio2(const GpAudioDriverProperties &properties);
|
||||
extern "C" __declspec(dllimport) IGpDisplayDriver *GpDriver_CreateDisplayDriver_D3D11(const GpDisplayDriverProperties &properties);
|
||||
extern "C" __declspec(dllimport) IGpInputDriver *GpDriver_CreateInputDriver_XInput(const GpInputDriverProperties &properties);
|
||||
|
||||
static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y)
|
||||
{
|
||||
@@ -372,10 +374,21 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
g_gpWindowsGlobals.m_translateWindowsMessageFunc = TranslateWindowsMessage;
|
||||
|
||||
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11;
|
||||
g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_XAudio2;
|
||||
|
||||
EGpInputDriverType inputDrivers[] =
|
||||
{
|
||||
EGpInputDriverType_XInput
|
||||
};
|
||||
|
||||
g_gpGlobalConfig.m_inputDriverTypes = inputDrivers;
|
||||
g_gpGlobalConfig.m_numInputDrivers = sizeof(inputDrivers) / sizeof(inputDrivers[0]);
|
||||
|
||||
g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals;
|
||||
|
||||
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDriver_CreateDisplayDriver_D3D11);
|
||||
GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_XAudio2, GpDriver_CreateAudioDriver_XAudio2);
|
||||
GpInputDriverFactory::RegisterInputDriverFactory(EGpInputDriverType_XInput, GpDriver_CreateInputDriver_XInput);
|
||||
|
||||
return GpMain::Run();
|
||||
}
|
||||
|
183
GpInputDriver_XInput/GpInputDriverXInput.cpp
Normal file
183
GpInputDriver_XInput/GpInputDriverXInput.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
#include "GpInputDriverXInput.h"
|
||||
#include "GpVOSEvent.h"
|
||||
#include "GpWindows.h"
|
||||
#include "IGpVOSEventQueue.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <new>
|
||||
|
||||
#pragma comment(lib, "xinput.lib")
|
||||
|
||||
void GpInputDriverXInput::ProcessInput()
|
||||
{
|
||||
for (DWORD i = 0; i < XUSER_MAX_COUNT; i++)
|
||||
{
|
||||
XINPUT_STATE newState;
|
||||
memset(&newState, 0, sizeof(newState));
|
||||
|
||||
DWORD result = XInputGetState(i, &newState);
|
||||
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
bool isNewState = false;
|
||||
unsigned int playerNumber = 0;
|
||||
if (m_xUserToPlayerNumber[i] < 0)
|
||||
{
|
||||
// Newly-connected player
|
||||
|
||||
for (int i = 0; i < XUSER_MAX_COUNT; i++)
|
||||
{
|
||||
if (!m_playerNumberIsConnected[i])
|
||||
{
|
||||
playerNumber = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_xUserToPlayerNumber[i] = playerNumber;
|
||||
m_playerNumberIsConnected[playerNumber] = true;
|
||||
|
||||
isNewState = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerNumber = m_xUserToPlayerNumber[i];
|
||||
isNewState = (newState.dwPacketNumber != m_controllerStates[i].dwPacketNumber);
|
||||
}
|
||||
|
||||
if (isNewState)
|
||||
{
|
||||
this->ProcessControllerStateChange(playerNumber, m_controllerStates[i], newState);
|
||||
m_controllerStates[i] = newState;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_xUserToPlayerNumber[i] >= 0)
|
||||
{
|
||||
// Was connected last frame, process as a blank state and then free the player slot
|
||||
memset(&newState, 0, sizeof(newState));
|
||||
|
||||
const unsigned int playerNumber = m_xUserToPlayerNumber[i];
|
||||
|
||||
this->ProcessControllerStateChange(playerNumber, m_controllerStates[i], newState);
|
||||
|
||||
m_controllerStates[i] = newState;
|
||||
m_playerNumberIsConnected[playerNumber] = false;
|
||||
m_xUserToPlayerNumber[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GpInputDriverXInput::Shutdown()
|
||||
{
|
||||
this->~GpInputDriverXInput();
|
||||
free(this);
|
||||
}
|
||||
|
||||
GpInputDriverXInput *GpInputDriverXInput::Create(const GpInputDriverProperties &props)
|
||||
{
|
||||
void *storage = malloc(sizeof(GpInputDriverXInput));
|
||||
if (!storage)
|
||||
return nullptr;
|
||||
|
||||
return new (storage) GpInputDriverXInput(props);
|
||||
}
|
||||
|
||||
GpInputDriverXInput::GpInputDriverXInput(const GpInputDriverProperties &props)
|
||||
: m_properties(props)
|
||||
{
|
||||
for (int i = 0; i < XUSER_MAX_COUNT; i++)
|
||||
m_xUserToPlayerNumber[i] = -1;
|
||||
|
||||
memset(m_controllerStates, 0, sizeof(m_controllerStates));
|
||||
memset(m_playerNumberIsConnected, 0, sizeof(m_playerNumberIsConnected));
|
||||
}
|
||||
|
||||
GpInputDriverXInput::~GpInputDriverXInput()
|
||||
{
|
||||
}
|
||||
|
||||
void GpInputDriverXInput::ProcessControllerStateChange(unsigned int playerNumber, const XINPUT_STATE &prevState, const XINPUT_STATE &newState)
|
||||
{
|
||||
const XINPUT_GAMEPAD &prevGamepad = prevState.Gamepad;
|
||||
const XINPUT_GAMEPAD &newGamepad = newState.Gamepad;
|
||||
|
||||
DWORD prevButtons = prevGamepad.wButtons;
|
||||
DWORD newButtons = newGamepad.wButtons;
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_START, playerNumber, GpGamepadButtons::kMisc1);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_BACK, playerNumber, GpGamepadButtons::kMisc2);
|
||||
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_DPAD_UP, playerNumber, GpGamepadButtons::kDPadUp);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_DPAD_DOWN, playerNumber, GpGamepadButtons::kDPadDown);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_DPAD_LEFT, playerNumber, GpGamepadButtons::kDPadLeft);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_DPAD_RIGHT, playerNumber, GpGamepadButtons::kDPadRight);
|
||||
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_LEFT_THUMB, playerNumber, GpGamepadButtons::kLeftStick);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_RIGHT_THUMB, playerNumber, GpGamepadButtons::kRightStick);
|
||||
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_LEFT_SHOULDER, playerNumber, GpGamepadButtons::kLeftBumper);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_RIGHT_SHOULDER, playerNumber, GpGamepadButtons::kRightBumper);
|
||||
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_Y, playerNumber, GpGamepadButtons::kFaceUp);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_A, playerNumber, GpGamepadButtons::kFaceDown);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_X, playerNumber, GpGamepadButtons::kFaceLeft);
|
||||
ProcessButtonStateChange(prevButtons, newButtons, XINPUT_GAMEPAD_B, playerNumber, GpGamepadButtons::kFaceRight);
|
||||
|
||||
ProcessAxisStateChange(ConvertTriggerValue(prevState.Gamepad.bLeftTrigger), ConvertTriggerValue(newState.Gamepad.bLeftTrigger), playerNumber, GpGamepadAxes::kLeftTrigger);
|
||||
ProcessAxisStateChange(ConvertTriggerValue(prevState.Gamepad.bRightTrigger), ConvertTriggerValue(newState.Gamepad.bRightTrigger), playerNumber, GpGamepadAxes::kRightTrigger);
|
||||
ProcessAxisStateChange(prevState.Gamepad.sThumbLX, newState.Gamepad.sThumbLX, playerNumber, GpGamepadAxes::kLeftStickX);
|
||||
ProcessAxisStateChange(prevState.Gamepad.sThumbLY, newState.Gamepad.sThumbLY, playerNumber, GpGamepadAxes::kLeftStickY);
|
||||
ProcessAxisStateChange(prevState.Gamepad.sThumbRX, newState.Gamepad.sThumbRX, playerNumber, GpGamepadAxes::kRightStickX);
|
||||
ProcessAxisStateChange(prevState.Gamepad.sThumbRY, newState.Gamepad.sThumbRY, playerNumber, GpGamepadAxes::kRightStickY);
|
||||
}
|
||||
|
||||
void GpInputDriverXInput::ProcessButtonStateChange(DWORD prevState, DWORD newState, DWORD deltaBit, unsigned int playerNum, GpGamepadButton_t gamepadButton)
|
||||
{
|
||||
DWORD deltaState = prevState ^ newState;
|
||||
|
||||
if ((deltaState & deltaBit) == 0)
|
||||
return;
|
||||
|
||||
const GpKeyboardInputEventType_t eventType = ((prevState & deltaBit) == 0) ? GpKeyboardInputEventTypes::kDown : GpKeyboardInputEventTypes::kUp;
|
||||
|
||||
if (GpVOSEvent *evt = m_properties.m_eventQueue->QueueEvent())
|
||||
{
|
||||
evt->m_eventType = GpVOSEventTypes::kKeyboardInput;
|
||||
evt->m_event.m_keyboardInputEvent.m_eventType = eventType;
|
||||
evt->m_event.m_keyboardInputEvent.m_keyIDSubset = GpKeyIDSubsets::kGamepadButton;
|
||||
evt->m_event.m_keyboardInputEvent.m_key.m_gamepadKey.m_button = gamepadButton;
|
||||
evt->m_event.m_keyboardInputEvent.m_key.m_gamepadKey.m_player = playerNum;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t GpInputDriverXInput::ConvertTriggerValue(uint8_t v)
|
||||
{
|
||||
return static_cast<int16_t>((v * 257) >> 1);
|
||||
}
|
||||
|
||||
void GpInputDriverXInput::ProcessAxisStateChange(int16_t prevState, int16_t newState, unsigned int playerNum, GpGamepadAxis_t gamepadAxis)
|
||||
{
|
||||
if (prevState != newState)
|
||||
{
|
||||
if (prevState == -32768)
|
||||
prevState = -32767;
|
||||
if (newState == -32768)
|
||||
newState = -32767;
|
||||
|
||||
if (GpVOSEvent *evt = m_properties.m_eventQueue->QueueEvent())
|
||||
{
|
||||
evt->m_eventType = GpVOSEventTypes::kGamepadInput;
|
||||
evt->m_event.m_gamepadInputEvent.m_eventType = GpGamepadInputEventTypes::kAnalogAxisChanged;
|
||||
evt->m_event.m_gamepadInputEvent.m_event.m_analogAxisEvent.m_axis = gamepadAxis;
|
||||
evt->m_event.m_gamepadInputEvent.m_event.m_analogAxisEvent.m_state = newState;
|
||||
evt->m_event.m_gamepadInputEvent.m_event.m_analogAxisEvent.m_player = playerNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) IGpInputDriver *GpDriver_CreateInputDriver_XInput(const GpInputDriverProperties &properties)
|
||||
{
|
||||
return GpInputDriverXInput::Create(properties);
|
||||
}
|
32
GpInputDriver_XInput/GpInputDriverXInput.h
Normal file
32
GpInputDriver_XInput/GpInputDriverXInput.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "IGpInputDriver.h"
|
||||
#include "GpInputDriverProperties.h"
|
||||
#include "GpVOSEvent.h"
|
||||
#include "GpWindows.h"
|
||||
|
||||
#include <Xinput.h>
|
||||
|
||||
class GpInputDriverXInput final : public IGpInputDriver
|
||||
{
|
||||
public:
|
||||
void ProcessInput() override;
|
||||
void Shutdown() override;
|
||||
|
||||
static GpInputDriverXInput *Create(const GpInputDriverProperties &props);
|
||||
|
||||
private:
|
||||
GpInputDriverXInput(const GpInputDriverProperties &props);
|
||||
~GpInputDriverXInput();
|
||||
|
||||
void ProcessControllerStateChange(unsigned int playerNumber, const XINPUT_STATE &prevState, const XINPUT_STATE &newState);
|
||||
void ProcessButtonStateChange(DWORD prevState, DWORD newState, DWORD deltaBit, unsigned int playerNum, GpGamepadButton_t gamepadButton);
|
||||
void ProcessAxisStateChange(int16_t prevState, int16_t newState, unsigned int playerNum, GpGamepadAxis_t gamepadAxis);
|
||||
|
||||
static int16_t ConvertTriggerValue(uint8_t v);
|
||||
|
||||
GpInputDriverProperties m_properties;
|
||||
int m_xUserToPlayerNumber[XUSER_MAX_COUNT];
|
||||
bool m_playerNumberIsConnected[XUSER_MAX_COUNT];
|
||||
XINPUT_STATE m_controllerStates[XUSER_MAX_COUNT];
|
||||
};
|
130
GpInputDriver_XInput/GpInputDriver_XInput.vcxproj
Normal file
130
GpInputDriver_XInput/GpInputDriver_XInput.vcxproj
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{17B96F07-EF92-47CD-95A5-8E6EE38AB564}</ProjectGuid>
|
||||
<RootNamespace>GpInputDriverXInput</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\GpCommon.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GpInputDriverXInput.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GpInputDriverXInput.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
27
GpInputDriver_XInput/GpInputDriver_XInput.vcxproj.filters
Normal file
27
GpInputDriver_XInput/GpInputDriver_XInput.vcxproj.filters
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GpInputDriverXInput.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GpInputDriverXInput.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -13,13 +13,18 @@ namespace PortabilityLayer
|
||||
InputManagerImpl();
|
||||
|
||||
void GetKeys(KeyMap &keyMap) const override;
|
||||
void ApplyEvent(const GpKeyboardInputEvent &vosEvent) override;
|
||||
void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) override;
|
||||
void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) override;
|
||||
int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) override;
|
||||
|
||||
static InputManagerImpl *GetInstance();
|
||||
|
||||
private:
|
||||
void ApplyEventAsKey(const GpKeyboardInputEvent &vosEvent, bool bit);
|
||||
void ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent);
|
||||
|
||||
KeyMap m_keyMap;
|
||||
int16_t m_axisStates[PL_INPUT_MAX_PLAYERS][GpGamepadAxes::kCount];
|
||||
|
||||
static InputManagerImpl ms_instance;
|
||||
};
|
||||
@@ -29,7 +34,7 @@ namespace PortabilityLayer
|
||||
keyMap = m_keyMap;
|
||||
}
|
||||
|
||||
void InputManagerImpl::ApplyEvent(const GpKeyboardInputEvent &vosEvent)
|
||||
void InputManagerImpl::ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent)
|
||||
{
|
||||
if (vosEvent.m_eventType == GpKeyboardInputEventTypes::kDown)
|
||||
ApplyEventAsKey(vosEvent, true);
|
||||
@@ -37,6 +42,19 @@ namespace PortabilityLayer
|
||||
ApplyEventAsKey(vosEvent, false);
|
||||
}
|
||||
|
||||
void InputManagerImpl::ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent)
|
||||
{
|
||||
if (vosEvent.m_eventType == GpGamepadInputEventTypes::kAnalogAxisChanged)
|
||||
ApplyAnalogAxisEvent(vosEvent.m_event.m_analogAxisEvent);
|
||||
}
|
||||
|
||||
int16_t InputManagerImpl::GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis)
|
||||
{
|
||||
assert(playerNum < PL_INPUT_MAX_PLAYERS);
|
||||
|
||||
return m_axisStates[playerNum][gamepadAxis];
|
||||
}
|
||||
|
||||
void InputManagerImpl::ApplyEventAsKey(const GpKeyboardInputEvent &vosEvent, bool bit)
|
||||
{
|
||||
switch (vosEvent.m_keyIDSubset)
|
||||
@@ -70,12 +88,22 @@ namespace PortabilityLayer
|
||||
case GpKeyIDSubsets::kFKey:
|
||||
m_keyMap.m_fKey.Set(vosEvent.m_key.m_fKey - 1, bit);
|
||||
break;
|
||||
case GpKeyIDSubsets::kGamepadButton:
|
||||
if (vosEvent.m_key.m_gamepadKey.m_player < PL_INPUT_MAX_PLAYERS)
|
||||
m_keyMap.m_gamepadButtons[vosEvent.m_key.m_gamepadKey.m_player].Set(vosEvent.m_key.m_gamepadKey.m_button, bit);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InputManagerImpl::ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent)
|
||||
{
|
||||
if (axisEvent.m_player < PL_INPUT_MAX_PLAYERS)
|
||||
m_axisStates[axisEvent.m_player][axisEvent.m_axis] = axisEvent.m_state;
|
||||
}
|
||||
|
||||
InputManagerImpl *InputManagerImpl::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
@@ -83,6 +111,7 @@ namespace PortabilityLayer
|
||||
|
||||
InputManagerImpl::InputManagerImpl()
|
||||
{
|
||||
memset(m_axisStates, 0, sizeof(m_axisStates));
|
||||
}
|
||||
|
||||
InputManagerImpl InputManagerImpl::ms_instance;
|
||||
|
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "GpVOSEvent.h"
|
||||
|
||||
struct GpKeyboardInputEvent;
|
||||
struct GpGamepadInputEvent;
|
||||
struct KeyMap;
|
||||
|
||||
namespace PortabilityLayer
|
||||
@@ -9,7 +12,9 @@ namespace PortabilityLayer
|
||||
{
|
||||
public:
|
||||
virtual void GetKeys(KeyMap &keys16) const = 0;
|
||||
virtual void ApplyEvent(const GpKeyboardInputEvent &vosEvent) = 0;
|
||||
virtual void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) = 0;
|
||||
virtual void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) = 0;
|
||||
virtual int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) = 0;
|
||||
|
||||
static InputManager *GetInstance();
|
||||
};
|
||||
|
@@ -98,12 +98,24 @@ static void TranslateMouseInputEvent(const GpMouseInputEvent &vosEvent, Portabil
|
||||
}
|
||||
}
|
||||
|
||||
static void TranslateKeyboardInputEvent(const GpKeyboardInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)
|
||||
static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)
|
||||
{
|
||||
PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance();
|
||||
|
||||
inputManager->ApplyGamepadEvent(vosEvent);
|
||||
|
||||
PL_DEAD(queue);
|
||||
}
|
||||
|
||||
static void TranslateKeyboardInputEvent(const GpKeyboardInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)
|
||||
{
|
||||
PL_STATIC_ASSERT((1 << PL_INPUT_PLAYER_INDEX_BITS) >= PL_INPUT_MAX_PLAYERS);
|
||||
PL_STATIC_ASSERT((1 << PL_INPUT_TYPE_CODE_BITS) >= KeyEventType_Count);
|
||||
|
||||
PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance();
|
||||
|
||||
if (vosEvent.m_eventType == GpKeyboardInputEventTypes::kUp || vosEvent.m_eventType == GpKeyboardInputEventTypes::kDown)
|
||||
inputManager->ApplyEvent(vosEvent);
|
||||
inputManager->ApplyKeyboardEvent(vosEvent);
|
||||
|
||||
intptr_t msg = 0;
|
||||
|
||||
@@ -134,6 +146,9 @@ static void TranslateKeyboardInputEvent(const GpKeyboardInputEvent &vosEvent, Po
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GpKeyIDSubsets::kGamepadButton:
|
||||
msg = PL_KEY_GAMEPAD_BUTTON_ENCODE(vosEvent.m_key.m_gamepadKey.m_button, vosEvent.m_key.m_gamepadKey.m_player);
|
||||
break;
|
||||
default:
|
||||
PL_NotYetImplemented();
|
||||
}
|
||||
@@ -171,6 +186,9 @@ static void TranslateVOSEvent(const GpVOSEvent *vosEvent, PortabilityLayer::Even
|
||||
case GpVOSEventTypes::kKeyboardInput:
|
||||
TranslateKeyboardInputEvent(vosEvent->m_event.m_keyboardInputEvent, queue);
|
||||
break;
|
||||
case GpVOSEventTypes::kGamepadInput:
|
||||
TranslateGamepadInputEvent(vosEvent->m_event.m_gamepadInputEvent, queue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,6 +539,15 @@ bool BitTst(const KeyMap &keyMap, int encodedKey)
|
||||
return keyMap.m_fKey.Get(evtValue - 1);
|
||||
case KeyEventType_EitherSpecial:
|
||||
return BitTestEitherSpecial(keyMap, evtValue);
|
||||
case KeyEventType_GamepadButton:
|
||||
{
|
||||
unsigned int playerNum = evtValue & ((1 << PL_INPUT_PLAYER_INDEX_BITS) - 1);
|
||||
assert(playerNum < PL_INPUT_MAX_PLAYERS);
|
||||
unsigned int button = evtValue >> PL_INPUT_PLAYER_INDEX_BITS;
|
||||
|
||||
return keyMap.m_gamepadButtons[playerNum].Get(button);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
return false;
|
||||
|
@@ -11,8 +11,10 @@ enum KeyEventType
|
||||
KeyEventType_NumPadNumber,
|
||||
KeyEventType_NumPadSpecial,
|
||||
KeyEventType_FKey,
|
||||
|
||||
KeyEventType_EitherSpecial,
|
||||
KeyEventType_GamepadButton,
|
||||
|
||||
KeyEventType_Count,
|
||||
};
|
||||
|
||||
namespace KeyEventEitherSpecialCategories
|
||||
@@ -25,18 +27,25 @@ namespace KeyEventEitherSpecialCategories
|
||||
};
|
||||
}
|
||||
|
||||
#define PL_KEY_SPECIAL(k) ((KeyEventType_Special) | (GpKeySpecials::k) << 3)
|
||||
#define PL_KEY_SPECIAL_ENCODE(k) ((KeyEventType_Special) | (k) << 3)
|
||||
#define PL_KEY_ASCII(k) ((KeyEventType_ASCII) | (k) << 3)
|
||||
#define PL_KEY_MACROMAN(k) ((KeyEventType_MacRoman) | (k) << 3)
|
||||
#define PL_KEY_NUMPAD_NUMBER(k) ((KeyEventType_NumPadNumber) | (k) << 3)
|
||||
#define PL_KEY_NUMPAD_SPECIAL(k) ((KeyEventType_NumPadSpecial) | (GpKeySpecials::k) << 3)
|
||||
#define PL_KEY_NUMPAD_SPECIAL_ENCODE(k) ((KeyEventType_NumPadSpecial) | (k) << 3)
|
||||
#define PL_KEY_FKEY(k) ((KeyEventType_FKey) | (k) << 3)
|
||||
#define PL_KEY_EITHER_SPECIAL(k) ((KeyEventType_EitherSpecial) | (KeyEventEitherSpecialCategories::k) << 3)
|
||||
#define PL_INPUT_MAX_PLAYERS 2
|
||||
#define PL_INPUT_PLAYER_INDEX_BITS 1
|
||||
|
||||
#define PL_KEY_GET_EVENT_TYPE(k) (static_cast<KeyEventType>(k & 7))
|
||||
#define PL_KEY_GET_VALUE(k) ((k) >> 3)
|
||||
#define PL_INPUT_TYPE_CODE_BITS 3
|
||||
|
||||
#define PL_KEY_SPECIAL(k) ((KeyEventType_Special) | ((GpKeySpecials::k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_SPECIAL_ENCODE(k) ((KeyEventType_Special) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_ASCII(k) ((KeyEventType_ASCII) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_MACROMAN(k) ((KeyEventType_MacRoman) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_NUMPAD_NUMBER(k) ((KeyEventType_NumPadNumber) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_NUMPAD_SPECIAL(k) ((KeyEventType_NumPadSpecial) | ((GpKeySpecials::k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_NUMPAD_SPECIAL_ENCODE(k) ((KeyEventType_NumPadSpecial) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_FKEY(k) ((KeyEventType_FKey) | ((k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_EITHER_SPECIAL(k) ((KeyEventType_EitherSpecial) | ((KeyEventEitherSpecialCategories::k) << PL_INPUT_TYPE_CODE_BITS))
|
||||
#define PL_KEY_GAMEPAD_BUTTON(k, pl) ((KeyEventType_GamepadButton) | (pl << PL_INPUT_TYPE_CODE_BITS) | ((GpGamepadButtons::k) << (PL_INPUT_TYPE_CODE_BITS + PL_INPUT_PLAYER_INDEX_BITS)))
|
||||
#define PL_KEY_GAMEPAD_BUTTON_ENCODE(k, pl) ((KeyEventType_GamepadButton) | (pl << PL_INPUT_TYPE_CODE_BITS) | ((k) << (PL_INPUT_TYPE_CODE_BITS + PL_INPUT_PLAYER_INDEX_BITS)))
|
||||
|
||||
#define PL_KEY_GET_EVENT_TYPE(k) (static_cast<KeyEventType>(k & ((1 << PL_INPUT_TYPE_CODE_BITS) - 1)))
|
||||
#define PL_KEY_GET_VALUE(k) ((k) >> PL_INPUT_TYPE_CODE_BITS)
|
||||
|
||||
struct KeyMap
|
||||
{
|
||||
@@ -46,4 +55,5 @@ struct KeyMap
|
||||
GpBitfield<10> m_numPadNumber;
|
||||
GpBitfield<GpNumPadSpecials::kCount> m_numPadSpecial;
|
||||
GpBitfield<GpFKeyMaximumInclusive> m_fKey;
|
||||
GpBitfield<GpGamepadButtons::kCount> m_gamepadButtons[PL_INPUT_MAX_PLAYERS];
|
||||
};
|
||||
|
Reference in New Issue
Block a user