#pragma once #define DIRECTINPUT_VERSION 0x0800 #include #include #include "InputMap.h" #include "common/ICriticalSection.h" void Hooks_DirectInput_Commit(void); class DIHookControl : public ISingleton { public: enum { // data sources kFlag_GameState = 1 << 0, // input passed to game post-filtering kFlag_RawState = 1 << 1, // user input kFlag_InsertedState = 1 << 2, // keydown was inserted by script // modifiers kFlag_IgnoreDisabled_User = 1 << 3, // ignore user-disabled keys kFlag_IgnoreDisabled_Script = 1 << 4, // ignore script-disabled keys kFlag_DefaultBackCompat = kFlag_GameState, }; enum { kDisable_User = 1 << 0, kDisable_Script = 1 << 1, kDisable_All = kDisable_User | kDisable_Script, }; DIHookControl(); bool IsKeyPressed(UInt32 keycode, UInt32 flags = 0); bool IsKeyDisabled(UInt32 keycode); bool IsKeyHeld(UInt32 keycode); bool IsKeyTapped(UInt32 keycode); UInt32 GetNumKeysPressed(); SInt32 GetNthKeyPressed(UInt32 n); void SetKeyDisableState(UInt32 keycode, bool bDisable, UInt32 mask); void SetKeyHeldState(UInt32 keycode, bool bHold); void TapKey(UInt32 keycode); void BufferedKeyTap(UInt32 key); void BufferedKeyPress(UInt32 key); void BufferedKeyRelease(UInt32 key); // hook interface void ProcessKeyboardData(UInt8 * data); void ProcessMouseData(DIMOUSESTATE2 * data); HRESULT ProcessBufferedData(IDirectInputDevice8 * device, DWORD dataSize, DIDEVICEOBJECTDATA * outData, DWORD * outDataLen, DWORD flags); private: struct KeyInfo { bool rawState; // state from dinput last update bool gameState; // state sent to the game last update bool insertedState; // true if a script pushed/held this key down last update bool hold; // key is held down bool tap; // key is being tapped bool userDisable; // key cannot be pressed by user bool scriptDisable; // key cannot be pressed by script bool Process(bool keyDown, UInt32 idx); }; bool _IsKeyPressed(KeyInfo* info, UInt32 flags); KeyInfo m_keys[InputMap::kMaxMacros]; ICriticalSection m_bufferedPressesLock; // hold this when modifying m_bufferedPresses typedef std::queue BufferedPressQueue; BufferedPressQueue m_bufferedPresses; }; class FramerateTracker { public: FramerateTracker(); void Update(void); private: enum { kFrameTimeHistoryLength = 32 }; UInt32 m_lastTime; float m_lastFrameLength; // frametime in seconds float m_frameTimeHistory[kFrameTimeHistoryLength]; // last kFrameTimeHistoryLength frametimes UInt32 m_frameTimeHistoryIdx; // slot that will be filled on the next update call bool m_frameTimeHistoryPrimed; // true after history buffer is full float m_averageFrameTime; // average of m_frameTimeHistory }; extern FramerateTracker g_framerateTracker;