diff --git a/Code/Game/GameClient/DanBiasGame_Impl.cpp b/Code/Game/GameClient/DanBiasGame_Impl.cpp index 2a46b8d6..f5ff4232 100644 --- a/Code/Game/GameClient/DanBiasGame_Impl.cpp +++ b/Code/Game/GameClient/DanBiasGame_Impl.cpp @@ -14,68 +14,81 @@ #include #include "../WindowManager/WindowShell.h" -#include "L_inputClass.h" #include "WinTimer.h" #include "vld.h" #include "EventHandler/EventHandler.h" -#include "GameClientState\SharedStateContent.h" +#include "GameClientState/SharedStateContent.h" +#include "Utilities.h" using namespace ::Oyster; using namespace ::Oyster::Event; using namespace ::Oyster::Network; using namespace ::Utility::DynamicMemory; using namespace ::DanBias::Client; +using namespace ::Utility::DynamicMemory; +LRESULT CALLBACK WindowCallBack(HWND handle, UINT message, WPARAM wParam, LPARAM lParam ); void ClientEventFunction( NetEvent e ); +#pragma region Game Data namespace DanBias { -#pragma region Game Data class DanBiasGamePrivateData { public: WindowShell* window; - InputClass inputObj; Utility::WinTimer timer; UniquePointer state; - SharedStateContent sharedStateContent; NetworkClient networkClient; + SharedStateContent sharedStateContent; bool serverOwner; float capFrame; DanBiasGamePrivateData() { - this->capFrame = 0; + this->sharedStateContent.network = nullptr; + this->sharedStateContent.mouseDevice = nullptr; + this->sharedStateContent.keyboardDevice = nullptr; + this->serverOwner = false; + this->capFrame = 0; + } + + ~DanBiasGamePrivateData() + { + //SafeDeleteInstance( this->sharedStateContent.mouseDevice ); + //SafeDeleteInstance( this->sharedStateContent.keyboardDevice ); } } data; - +} #pragma endregion - +namespace DanBias +{ //-------------------------------------------------------------------------------------- // Interface API functions //-------------------------------------------------------------------------------------- - DanBiasClientReturn DanBiasGame::Initiate(DanBiasGameDesc& desc) + DanBiasClientReturn DanBiasGame::Initiate( DanBiasGameDesc& desc ) { WindowShell::CreateConsoleWindow(); //if(! data.window->CreateWin(WindowShell::WINDOW_INIT_DESC(L"Window", cPOINT(1600, 900), cPOINT()))) WindowShell::WINDOW_INIT_DESC winDesc; - winDesc.windowSize.x = 1280; - winDesc.windowSize.y = 720; - + winDesc.windowSize.x = 1280; + winDesc.windowSize.y = 720; + winDesc.windowProcCallback = WindowCallBack; + if(! data.window->CreateWin(winDesc) ) return DanBiasClientReturn_Error; - if( FAILED( InitDirect3D() ) ) + if( FAILED( InitInput(data.window->GetHWND()) ) ) return DanBiasClientReturn_Error; - if( FAILED( InitInput() ) ) + if( FAILED( InitDirect3D() ) ) return DanBiasClientReturn_Error; data.serverOwner = false; @@ -83,7 +96,6 @@ namespace DanBias data.networkClient.SetMessagePump( ClientEventFunction ); data.sharedStateContent.network = &data.networkClient; - data.sharedStateContent.input = &data.inputObj; // Start in main menu state data.state = new Client::MainState(); @@ -137,7 +149,6 @@ namespace DanBias //-------------------------------------------------------------------------------------- HRESULT DanBiasGame::InitDirect3D() { - Oyster::Graphics::API::Option p; p.modelPath = L"..\\Content\\Models\\"; p.texturePath = L"..\\Content\\Textures\\"; @@ -153,35 +164,27 @@ namespace DanBias //-------------------------------------------------------------------------------------- // Init the input //------------------------------------------------------------------------------------- - HRESULT DanBiasGame::InitInput() + HRESULT DanBiasGame::InitInput( HWND handle ) { - if(!data.inputObj.Initialize(data.window->GetHINSTANCE(), data.window->GetHWND(), data.window->GetHeight(), data.window->GetWidth())) + data.sharedStateContent.mouseDevice = dynamic_cast( ::Input::InputManager::Instance()->CreateDevice(Input::Enum::SAIType_Mouse, handle) ); + if( !data.sharedStateContent.mouseDevice ) { - MessageBox(0, L"Could not initialize the input object.", L"Error", MB_OK); + MessageBox( 0, L"Could not initialize the mouseDevice.", L"Error", MB_OK ); return E_FAIL; } + + data.sharedStateContent.keyboardDevice= dynamic_cast( ::Input::InputManager::Instance()->CreateDevice(Input::Enum::SAIType_Keyboard, handle) ); + if( !data.sharedStateContent.keyboardDevice ) + { + MessageBox( 0, L"Could not initialize the raw keyboard device.", L"Error", MB_OK ); + return E_FAIL; + } + return S_OK; } DanBiasGame::Result DanBiasGame::Update(float deltaTime) { - { // updating mouse input - // TODO: Is obosolete when Dennis's input system is wired in - POINT mousePos; - GetCursorPos( &mousePos ); - - RECT windowVertex; - GetWindowRect( data.window->GetHWND(), &windowVertex ); - - float mouseNormalisedX = (float)(mousePos.x - windowVertex.left); - mouseNormalisedX /= (float)(windowVertex.right - windowVertex.left); - - float mouseNormalisedY = (float)(mousePos.y - windowVertex.top); - mouseNormalisedY /= (float)(windowVertex.bottom - windowVertex.top); - - data.inputObj.Update( mouseNormalisedX, mouseNormalisedY ); - } - if( data.serverOwner ) { DanBias::GameServerAPI::ServerUpdate(); @@ -251,6 +254,8 @@ namespace DanBias data.networkClient.Disconnect(); data.state = nullptr; + SafeDeleteInstance( data.sharedStateContent.network ); + EventHandler::Instance().Clean(); Graphics::API::Clean(); @@ -261,6 +266,22 @@ namespace DanBias } //End namespace DanBias +LRESULT CALLBACK WindowCallBack(HWND handle, UINT message, WPARAM wParam, LPARAM lParam ) +{ + switch ( message ) + { + case WM_DESTROY: + PostQuitMessage( 0 ); + break; + case WM_INPUT: + message = 0; + break; + default: break; + } + + return DefWindowProc( handle, message, wParam, lParam ); +} + void ClientEventFunction( NetEvent e ) { if( DanBias::data.state ) diff --git a/Code/Game/GameClient/GameClient.vcxproj b/Code/Game/GameClient/GameClient.vcxproj index c084532d..1693576a 100644 --- a/Code/Game/GameClient/GameClient.vcxproj +++ b/Code/Game/GameClient/GameClient.vcxproj @@ -106,7 +106,7 @@ Disabled DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true - $(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader + $(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input\Include;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader Windows @@ -123,7 +123,7 @@ Disabled DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true - $(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader + $(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input\Include;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader Windows @@ -142,7 +142,7 @@ true DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true - $(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader + $(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input\Include;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader Windows @@ -163,7 +163,7 @@ true DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true - $(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader + $(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input\Include;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader Windows @@ -224,8 +224,11 @@ + + + @@ -249,10 +252,13 @@ + + + diff --git a/Code/Game/GameClient/GameClient.vcxproj.user b/Code/Game/GameClient/GameClient.vcxproj.user index 4b847ee6..2e28d6f7 100644 --- a/Code/Game/GameClient/GameClient.vcxproj.user +++ b/Code/Game/GameClient/GameClient.vcxproj.user @@ -1,7 +1,7 @@  - false + true $(OutDir) diff --git a/Code/Game/GameClient/GameClientState/Buttons/EventButtonGUI.h b/Code/Game/GameClient/GameClientState/Buttons/EventButtonGUI.h index c14d24f2..e598a790 100644 --- a/Code/Game/GameClient/GameClientState/Buttons/EventButtonGUI.h +++ b/Code/Game/GameClient/GameClientState/Buttons/EventButtonGUI.h @@ -113,7 +113,7 @@ namespace DanBias { if(buttonText.size() > 0) { - Oyster::Graphics::API::RenderText(buttonText, pos - Float3(size.x * 0.5f, size.y * 0.25f, -0.001f), size, size.y * 0.5f, textColor); + Oyster::Graphics::API::RenderText(buttonText, pos - Float3(size.x * 0.5f, size.y * 0.25f, +0.001f), size, size.y * 0.5f, textColor); } } diff --git a/Code/Game/GameClient/GameClientState/Buttons/Plane_UI.h b/Code/Game/GameClient/GameClientState/Buttons/Plane_UI.h new file mode 100644 index 00000000..8293eeb1 --- /dev/null +++ b/Code/Game/GameClient/GameClientState/Buttons/Plane_UI.h @@ -0,0 +1,51 @@ +#ifndef DANBIAS_CLIENT_PLANE_UI_H +#define DANBIAS_CLIENT_PLANE_UI_H + +#include "DllInterfaces/GFXAPI.h" + +namespace DanBias +{ + namespace Client + { + class Plane_UI + { + public: + Plane_UI( ) + { + pos = Oyster::Math::Float3::null; + size = Oyster::Math::Float2::null; + tintColor = Oyster::Math::Float4(1); + texture = NULL; + } + Plane_UI( std::wstring textureName, Oyster::Math::Float3 pos, Oyster::Math::Float2 size, Oyster::Math::Float4 tintColor = Oyster::Math::Float4(1)) + : pos(pos), size(size), tintColor(tintColor) + { + CreateTexture(textureName); + } + virtual ~Plane_UI() + { + Oyster::Graphics::API::DeleteTexture(texture); + texture = NULL; + } + void CreateTexture(std::wstring textureName) + { + //Create texture + texture = Oyster::Graphics::API::CreateTexture(textureName); + } + + virtual void RenderTexture() const + { + if(texture) + Oyster::Graphics::API::RenderGuiElement(texture, pos, size, tintColor); + } + private: + Oyster::Math::Float3 pos; + Oyster::Math::Float2 size; + + Oyster::Graphics::API::Texture texture; + Oyster::Math::Float4 tintColor; + }; + } +} + +#endif \ No newline at end of file diff --git a/Code/Game/GameClient/GameClientState/Buttons/Text_UI.h b/Code/Game/GameClient/GameClientState/Buttons/Text_UI.h new file mode 100644 index 00000000..d37b347e --- /dev/null +++ b/Code/Game/GameClient/GameClientState/Buttons/Text_UI.h @@ -0,0 +1,45 @@ +#ifndef DANBIAS_CLIENT_TEXT_UI_H +#define DANBIAS_CLIENT_TEXT_UI_H + +#include "DllInterfaces/GFXAPI.h" + +namespace DanBias +{ + namespace Client + { + class Text_UI + { + public: + Text_UI( ) + { + pos = Oyster::Math::Float3::null; + size = Oyster::Math::Float2::null; + text = L""; + textColor = Oyster::Math::Float4(1); + } + Text_UI(std::wstring text, Oyster::Math::Float3 pos, Oyster::Math::Float2 size, Oyster::Math::Float4 textColor = Oyster::Math::Float4(1)) + : pos(pos), size(size), text(text), textColor(textColor) + { + } + void setText(std::wstring text) + { + this->text = text; + } + void RenderText() const + { + if(text.size() > 0) + { + Oyster::Graphics::API::RenderText(text, pos, size, size.y * 0.5f, textColor); + } + } + private: + Oyster::Math::Float3 pos; + Oyster::Math::Float2 size; + + std::wstring text; + Oyster::Math::Float4 textColor; + }; + } +} + +#endif \ No newline at end of file diff --git a/Code/Game/GameClient/GameClientState/C_Object.cpp b/Code/Game/GameClient/GameClientState/C_Object.cpp index b4f18d34..67146770 100644 --- a/Code/Game/GameClient/GameClientState/C_Object.cpp +++ b/Code/Game/GameClient/GameClientState/C_Object.cpp @@ -138,9 +138,9 @@ bool C_Object::InitRB(RBInitData RBInit) } void C_Object::updateRBWorld() { - Oyster::Math3D::Float4x4 translation = Oyster::Math3D::TranslationMatrix(this->position); - Oyster::Math3D::Float4x4 rot = Oyster::Math3D::RotationMatrix(this->rotation); - Oyster::Math3D::Float4x4 scale = Oyster::Math3D::ScalingMatrix(this->scale); + Oyster::Math3D::Float4x4 translation = Oyster::Math3D::TranslationMatrix(this->RBposition); + Oyster::Math3D::Float4x4 rot = Oyster::Math3D::RotationMatrix(this->RBrotation); + Oyster::Math3D::Float4x4 scale = Oyster::Math3D::ScalingMatrix(this->RBscale); RBworld = translation * rot * scale; } Oyster::Math::Float4x4 C_Object::getRBWorld() const diff --git a/Code/Game/GameClient/GameClientState/GameState.cpp b/Code/Game/GameClient/GameClientState/GameState.cpp index 532bd29d..bb0bdc90 100644 --- a/Code/Game/GameClient/GameClientState/GameState.cpp +++ b/Code/Game/GameClient/GameClientState/GameState.cpp @@ -9,6 +9,9 @@ #include "C_obj/C_DynamicObj.h" #include "C_obj/C_StaticObj.h" #include "Utilities.h" +#include "GamingUI.h" +#include "RespawnUI.h" +#include "StatsUI.h" using namespace ::DanBias::Client; using namespace ::Oyster; @@ -24,25 +27,13 @@ struct GameState::MyData MyData(){} GameClientState::ClientState nextState; NetworkClient *nwClient; - InputClass *input; + ::Input::Mouse *mouseInput; + ::Input::Keyboard *keyboardInput; ::std::map> *staticObjects; ::std::map> *dynamicObjects; ::std::map> *lights; - bool key_forward; - bool key_backward; - bool key_strafeRight; - bool key_strafeLeft; - bool key_Shoot; - bool key_Jump; - - // DEGUG KEYS - bool key_Reload_Shaders; - bool key_Wireframe_Toggle; - bool renderWhireframe; - // !DEGUG KEYS - C_Player player; Camera_FPSV2 camera; @@ -73,14 +64,10 @@ bool GameState::Init( SharedStateContent &shared ) this->privData = new MyData(); - this->privData->key_forward = false; - this->privData->key_backward = false; - this->privData->key_strafeRight = false; - this->privData->key_strafeLeft = false; - this->privData->nextState = GameClientState::ClientState_Same; this->privData->nwClient = shared.network; - this->privData->input = shared.input; + this->privData->mouseInput = shared.mouseDevice; + this->privData->keyboardInput = shared.keyboardDevice; this->privData->staticObjects = &shared.staticObjects; this->privData->dynamicObjects = &shared.dynamicObjects; this->privData->lights = &shared.lights; @@ -89,16 +76,18 @@ bool GameState::Init( SharedStateContent &shared ) Float aspectRatio = gfxOp.Resolution.x / gfxOp.Resolution.y; this->privData->camera.SetPerspectiveProjection( Utility::Value::Radian(90.0f), aspectRatio, 0.1f, 1000.0f ); Graphics::API::SetProjection( this->privData->camera.GetProjectionMatrix() ); - gfxOp.AmbientValue = 1.0f; + gfxOp.AmbientValue = 0.5f; + gfxOp.GlobalGlowTint = Math::Float3(2,1,1); + gfxOp.GlobalTint = Math::Float3(1,1,1); Graphics::API::SetOptions(gfxOp); //tell server ready this->privData->nwClient->Send( Protocol_General_Status(Protocol_General_Status::States_ready) ); // DEGUG KEYS - this->privData->key_Reload_Shaders = false; - this->privData->key_Wireframe_Toggle = false; - this->privData->renderWhireframe = false; + this->key_Reload_Shaders = false; + this->key_Wireframe_Toggle = false; + this->renderWhireframe = false; // !DEGUG KEYS auto light = this->privData->lights->begin(); @@ -107,6 +96,14 @@ bool GameState::Init( SharedStateContent &shared ) light->second->Render(); } + // create UI states + this->gameUI = new GamingUI(this->privData->mouseInput, this->privData->keyboardInput, this->privData->nwClient, &this->privData->camera); + this->respawnUI = new RespawnUI(this->privData->nwClient, 20); + this->statsUI = new StatsUI(); + this->currGameUI = gameUI; + ((GamingUI*)gameUI)->Init(); + ((RespawnUI*)respawnUI)->Init(); + ((StatsUI*)statsUI)->Init(); return true; } @@ -140,8 +137,8 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa this->privData->camera.SetPosition( this->privData->player.getPos() ); Float3 offset = Float3( 0.0f ); // DEBUG position of camera so we can see the player model - offset.y = this->privData->player.getScale().y * 5.0f; - offset.z = this->privData->player.getScale().z * -5.0f; + //offset.y = this->privData->player.getScale().y * 5.0f; + //offset.z = this->privData->player.getScale().z * -5.0f; // !DEBUG this->privData->camera.SetHeadOffset( offset ); this->privData->camera.UpdateOrientation(); @@ -163,7 +160,25 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa GameClientState::ClientState GameState::Update( float deltaTime ) { - this->ReadKeyInput(); + GameStateUI::UIState UIstate = this->currGameUI->Update( deltaTime ); + switch (UIstate) + { + case DanBias::Client::GameStateUI::UIState_same: + break; + case DanBias::Client::GameStateUI::UIState_gaming: + break; + case DanBias::Client::GameStateUI::UIState_main_menu: + //this->privData->nextState = + break; + case DanBias::Client::GameStateUI::UIState_shut_down: + this->privData->nextState = ClientState_Quit; + break; + default: + break; + } + // DEBUG keybindings + ReadKeyInput(); + return this->privData->nextState; } @@ -188,19 +203,12 @@ bool GameState::Render() if( dynamicObject->second ) { dynamicObject->second->Render(); + } } - - /*auto light = this->privData->lights->begin(); - for( ; light != this->privData->lights->end(); ++light ) - { - light->second->Render(); - }*/ - -#ifdef _DEBUG - //RB DEBUG render wire frame - if(this->privData->renderWhireframe) +#ifdef _DEBUG //RB DEBUG render wire frame + if(this->renderWhireframe) { Oyster::Graphics::API::StartRenderWireFrame(); @@ -239,8 +247,25 @@ bool GameState::Render() } } } - //!RB DEBUG -#endif +#endif //!RB DEBUG + + Oyster::Graphics::API::StartGuiRender(); + // render gui elemnts + if(currGameUI->HaveGUIRender()) + currGameUI->RenderGUI(); + if(renderStats) + { + if(statsUI->HaveGUIRender()) + statsUI->RenderGUI(); + } + Oyster::Graphics::API::StartTextRender(); + if(currGameUI->HaveTextRender()) + currGameUI->RenderText(); + if(renderStats) + { + if(statsUI->HaveTextRender()) + statsUI->RenderText(); + } Oyster::Graphics::API::EndFrame(); return true; @@ -275,6 +300,28 @@ bool GameState::Release() privData = NULL; } + + if(respawnUI) + { + respawnUI->Release(); + delete respawnUI; + respawnUI = NULL; + } + + if(gameUI) + { + gameUI->Release(); + delete gameUI; + gameUI = NULL; + } + if(statsUI) + { + statsUI->Release(); + delete statsUI; + statsUI = NULL; + } + currGameUI = NULL; + return true; } @@ -285,147 +332,57 @@ void GameState::ChangeState( ClientState next ) void GameState::ReadKeyInput() { - if( this->privData->input->IsKeyPressed(DIK_W) ) - { - //if(!this->privData->key_forward) - { - this->privData->nwClient->Send( Protocol_PlayerMovementForward() ); - this->privData->key_forward = true; - } - } - else - this->privData->key_forward = false; - - if( this->privData->input->IsKeyPressed(DIK_S) ) - { - //if( !this->privData->key_backward ) - { - this->privData->nwClient->Send( Protocol_PlayerMovementBackward() ); - this->privData->key_backward = true; - } - } - else - this->privData->key_backward = false; - - if( this->privData->input->IsKeyPressed(DIK_A) ) - { - //if( !this->privData->key_strafeLeft ) - { - this->privData->nwClient->Send( Protocol_PlayerMovementLeft() ); - this->privData->key_strafeLeft = true; - } - } - else - this->privData->key_strafeLeft = false; - - if( this->privData->input->IsKeyPressed(DIK_D) ) - { - //if( !this->privData->key_strafeRight ) - { - this->privData->nwClient->Send( Protocol_PlayerMovementRight() ); - this->privData->key_strafeRight = true; - } - } - else - this->privData->key_strafeRight = false; - - //send delta mouse movement - { - static const float mouseSensitivity = Radian( 1.0f ); - this->privData->camera.PitchDown( this->privData->input->GetPitch() * mouseSensitivity ); - float yaw = this->privData->input->GetYaw(); - //if( yaw != 0.0f ) //This made the camera reset to a specific rotation. - { - this->privData->nwClient->Send( Protocol_PlayerLeftTurn(yaw * mouseSensitivity) ); - } - } - - // shoot - if( this->privData->input->IsKeyPressed(DIK_Z) ) - { - if( !this->privData->key_Shoot ) - { - Protocol_PlayerShot playerShot; - playerShot.primaryPressed = true; - playerShot.secondaryPressed = false; - playerShot.utilityPressed = false; - this->privData->nwClient->Send( playerShot ); - this->privData->key_Shoot = true; - } - } - else - this->privData->key_Shoot = false; - if( this->privData->input->IsKeyPressed(DIK_X) ) - { - if( !this->privData->key_Shoot ) - { - Protocol_PlayerShot playerShot; - playerShot.primaryPressed = false; - playerShot.secondaryPressed = true; - playerShot.utilityPressed = false; - this->privData->nwClient->Send( playerShot ); - this->privData->key_Shoot = true; - } - } - else - this->privData->key_Shoot = false; - if( this->privData->input->IsKeyPressed(DIK_C) ) - { - if( !this->privData->key_Shoot ) - { - Protocol_PlayerShot playerShot; - playerShot.primaryPressed = false; - playerShot.secondaryPressed = false; - playerShot.utilityPressed = true; - this->privData->nwClient->Send( playerShot ); - this->privData->key_Shoot = true; - } - } - else - this->privData->key_Shoot = false; - - // jump - if( this->privData->input->IsKeyPressed(DIK_SPACE) ) - { - if(!this->privData->key_Jump) - { - this->privData->nwClient->Send( Protocol_PlayerJump() ); - this->privData->key_Jump = true; - } - } - else - this->privData->key_Jump = false; - - - // DEGUG KEYS +#ifdef _DEBUG // DEGUG KEYS // Reload shaders - if( this->privData->input->IsKeyPressed(DIK_R) ) + if( this->privData->keyboardInput->IsKeyDown(::Input::Enum::SAKI_R) ) { - if( !this->privData->key_Reload_Shaders ) + if( !this->key_Reload_Shaders ) { -#ifdef _DEBUG + Graphics::API::ReloadShaders(); -#endif - this->privData->key_Reload_Shaders = true; + + this->key_Reload_Shaders = true; } } else - this->privData->key_Reload_Shaders = false; + this->key_Reload_Shaders = false; // toggle wire frame render - if( this->privData->input->IsKeyPressed(DIK_T) ) + if( this->privData->keyboardInput->IsKeyDown(::Input::Enum::SAKI_T) ) { - if( !this->privData->key_Wireframe_Toggle ) + if( !this->key_Wireframe_Toggle ) { - this->privData->renderWhireframe = !this->privData->renderWhireframe; - this->privData->key_Wireframe_Toggle = true; + this->renderWhireframe = !this->renderWhireframe; + this->key_Wireframe_Toggle = true; + // DEBUG set you as dead when render wireframe + this->currGameUI = respawnUI; + // !DEBUG } } else - this->privData->key_Wireframe_Toggle = false; - // !DEGUG KEYS - // TODO: implement sub-menu + { + this->key_Wireframe_Toggle = false; + // DEBUG set you as dead when render wireframe + this->currGameUI = gameUI; + // !DEBUG + } +#endif // !DEGUG KEYS + + // toggle wire frame render + if( this->privData->keyboardInput->IsKeyDown(::Input::Enum::SAKI_Tab) ) + { + if( !this->key_showStats ) + { + this->renderStats = true; + this->key_showStats = true; + } + } + else + { + this->renderStats = false; + this->key_showStats = false; + } } const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState::NetEvent &message ) @@ -447,8 +404,22 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState switch(ID) { case protocol_Gameplay_ObjectPickup: break; /** @todo TODO: implement */ - case protocol_Gameplay_ObjectDamage: break; /** @todo TODO: implement */ - case protocol_Gameplay_ObjectHealthStatus: break; /** @todo TODO: implement */ + case protocol_Gameplay_ObjectDamage: + { + Protocol_ObjectDamage decoded(data); + if( this->privData->myId == decoded.object_ID ) + { + if(currGameUI == gameUI) + { + ((GamingUI*)currGameUI)->SetHPtext(std::to_wstring(decoded.healthLost)); + } + } + } + return GameClientState::event_processed; + case protocol_Gameplay_ObjectHealthStatus: + { + } + return GameClientState::event_processed; case protocol_Gameplay_ObjectPosition: { Protocol_ObjectPosition decoded(data); @@ -513,19 +484,21 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState this->privData->player.updateRBWorld(); // !RB DEBUG } - - C_DynamicObj *object = (*this->privData->dynamicObjects)[decoded.object_ID]; - - if( object ) + else { - object->setPos( position ); - object->setRot( rotation ); - object->updateWorld(); - // RB DEBUG - object->setRBPos ( position ); - object->setRBRot ( rotation ); - object->updateRBWorld(); - // !RB DEBUG + C_DynamicObj *object = (*this->privData->dynamicObjects)[decoded.object_ID]; + + if( object ) + { + object->setPos( position ); + object->setRot( rotation ); + object->updateWorld(); + // RB DEBUG + object->setRBPos ( position ); + object->setRBRot ( rotation ); + object->updateRBWorld(); + // !RB DEBUG + } } } return GameClientState::event_processed; @@ -582,8 +555,46 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState case protocol_Gameplay_ObjectLeaveTeam: break; /** @todo TODO: implement */ case protocol_Gameplay_ObjectWeaponCooldown: break; /** @todo TODO: implement */ case protocol_Gameplay_ObjectWeaponEnergy: break; /** @todo TODO: implement */ - case protocol_Gameplay_ObjectRespawn: break; /** @todo TODO: implement */ - case protocol_Gameplay_ObjectDie: break; /** @todo TODO: implement */ + case protocol_Gameplay_ObjectRespawn: + { + // set player pos + Protocol_ObjectRespawn decoded(data); + // move player. Remember to change camera + this->privData->camera.SetPosition( decoded.position ); + this->privData->player.setPos( decoded.position ); + this->privData->player.updateWorld(); + // RB DEBUG + this->privData->player.setRBPos ( decoded.position ); + this->privData->player.updateRBWorld(); + // !RB DEBUG + + this->currGameUI = this->gameUI; + } + return GameClientState::event_processed; + case protocol_Gameplay_ObjectDie: + { + Protocol_ObjectDie decoded(data); + // if is this player. Remember to change camera + if( this->privData->myId == decoded.objectID ) + { + this->currGameUI = this->respawnUI; + // set countdown + ((RespawnUI*)currGameUI)->SetCountdown( decoded.seconds ); + } + } + return GameClientState::event_processed; + case protocol_Gameplay_ObjectDisconnectPlayer: + { + //Removes + Protocol_ObjectDisconnectPlayer decoded(data); + auto object = this->privData->dynamicObjects->find( decoded.objectID ); + if( object != this->privData->dynamicObjects->end() ) + { + object->second = nullptr; + this->privData->dynamicObjects->erase( object ); + } + } + return GameClientState::event_processed; default: break; } } diff --git a/Code/Game/GameClient/GameClientState/GameState.h b/Code/Game/GameClient/GameClientState/GameState.h index 8c5ca64e..8342d558 100644 --- a/Code/Game/GameClient/GameClientState/GameState.h +++ b/Code/Game/GameClient/GameClientState/GameState.h @@ -3,6 +3,7 @@ #include "GameClientState.h" #include "OysterMath.h" #include +#include "GameStateUI.h" namespace DanBias { namespace Client { @@ -31,6 +32,16 @@ namespace DanBias { namespace Client private: struct MyData; ::Utility::DynamicMemory::UniquePointer privData; + GameStateUI *currGameUI, *gameUI, *respawnUI, *statsUI; + + // DEGUG KEYS + bool key_Reload_Shaders; + bool key_Wireframe_Toggle; + bool renderWhireframe; + bool key_showStats; + bool renderStats; + // !DEGUG KEYS + }; } } #endif \ No newline at end of file diff --git a/Code/Game/GameClient/GameClientState/GameStateUI.h b/Code/Game/GameClient/GameClientState/GameStateUI.h index 40350211..152a7f04 100644 --- a/Code/Game/GameClient/GameClientState/GameStateUI.h +++ b/Code/Game/GameClient/GameClientState/GameStateUI.h @@ -1,5 +1,5 @@ -#ifndef DANBIAS_CLIENT_GAMECLIENTSTATE_H -#define DANBIAS_CLIENT_GAMECLIENTSTATE_H +#ifndef DANBIAS_CLIENT_GAMESTATEUI_H +#define DANBIAS_CLIENT_GAMESTATEUI_H #include "Utilities.h" #include "NetworkClient.h" diff --git a/Code/Game/GameClient/GameClientState/GamingUI.cpp b/Code/Game/GameClient/GameClientState/GamingUI.cpp index 8ff43d88..56b8f98f 100644 --- a/Code/Game/GameClient/GameClientState/GamingUI.cpp +++ b/Code/Game/GameClient/GameClientState/GamingUI.cpp @@ -6,148 +6,174 @@ using namespace ::DanBias::Client; using namespace ::Oyster::Network; using namespace ::GameLogic; using namespace ::Utility::Value; +using namespace ::Oyster::Math; +using namespace ::Input; GamingUI::GamingUI() : GameStateUI() { /* Should never be called! */ - this->input = nullptr; + this->mouseInput = nullptr; + this->keyboardInput = nullptr; this->netClient = nullptr; this->camera = nullptr; + this->plane = nullptr; + this->text = nullptr; } -GamingUI::GamingUI( InputClass *input, NetworkClient *connection, Camera_FPSV2 *camera ) : +GamingUI::GamingUI( Mouse *mouseInput, Keyboard *keyboardInput, NetworkClient *connection, Camera_FPSV2 *camera ) : GameStateUI() { - this->input = input; + this->mouseInput = mouseInput; + this->keyboardInput = keyboardInput; this->netClient = connection; this->camera = camera; } GamingUI::~GamingUI() { /* Do nothing */ } +bool GamingUI::Init() +{ + // z value should be between 0.5 - 0.9 so that it will be behind other states + // add textures and text + this->plane = new Plane_UI(L"box_tex.png", Float3(0.5f, 0.0f, 0.5f), Float2(0.3f, 0.1f)); + this->text = new Text_UI(L"hej", Float3(0.5f,0.0f,0.1f), Float2(0.1f,0.1f)); + return true; +} GameStateUI::UIState GamingUI::Update( float deltaTime ) { + ReadKeyInput(); return this->nextState; } bool GamingUI::HaveGUIRender() const { - return false; // TODO: change to true when we want UI elements like a crosshair + return true; } bool GamingUI::HaveTextRender() const { - return false; // TODO: change to true when we want UI elements like a chat window + return true; } void GamingUI::RenderGUI() const { - // TODO: Render crosshairs and such here. Don't forget to adjust GamingUI::HaveGUIRender + this->plane->RenderTexture(); } void GamingUI::RenderText() const { - // TODO: Render chattext and such here. Don't forget to adjust GamingUI::HaveGUIRender + this->text->RenderText(); } bool GamingUI::Release() { // TODO: Release UI components here. + if(this->plane) + delete this->plane; + if(this->text) + delete this->text; return true; } - +void GamingUI::SetHPtext( std::wstring hp ) +{ + this->text->setText(hp); +} void GamingUI::ReadKeyInput() { - if( this->input->IsKeyPressed(DIK_W) ) - { + if( this->keyboardInput->IsKeyDown(::Input::Enum::SAKI_W) ) + { // move forward this->netClient->Send( Protocol_PlayerMovementForward() ); } - if( this->input->IsKeyPressed(DIK_S) ) - { + if( this->keyboardInput->IsKeyDown(::Input::Enum::SAKI_S) ) + { // move backward this->netClient->Send( Protocol_PlayerMovementBackward() ); } - if( this->input->IsKeyPressed(DIK_A) ) - { + if( this->keyboardInput->IsKeyDown(::Input::Enum::SAKI_A) ) + { // strafe left this->netClient->Send( Protocol_PlayerMovementLeft() ); } - if( this->input->IsKeyPressed(DIK_D) ) - { + if( this->keyboardInput->IsKeyDown(::Input::Enum::SAKI_D) ) + { // strafe right this->netClient->Send( Protocol_PlayerMovementRight() ); } -// if( this->input->IsKeyPressed(DIK_R) ) -// { -// if( !this->key_Reload_Shaders ) -// { -//#ifdef _DEBUG -// Graphics::API::ReloadShaders(); -//#endif -// this->key_Reload_Shaders = true; -// } -// } -// else -// this->key_Reload_Shaders = false; + if( this->keyboardInput->IsKeyDown(::Input::Enum::SAKI_Space) ) + { // jump + if(!this->key_Jump) + { + this->netClient->Send( Protocol_PlayerJump() ); + this->key_Jump = true; + } + } + else + this->key_Jump = false; + + // shoot + if( this->mouseInput->IsBtnDown(::Input::Enum::SAMI_MouseLeftBtn) ) + { + if( !this->key_Shoot ) + { + Protocol_PlayerShot playerShot; + playerShot.primaryPressed = true; + playerShot.secondaryPressed = false; + playerShot.utilityPressed = false; + this->netClient->Send( playerShot ); + this->key_Shoot = true; + } + } + else + this->key_Shoot = false; + + if( this->mouseInput->IsBtnDown(::Input::Enum::SAMI_MouseRightBtn) ) + { + if( !this->key_Shoot ) + { + Protocol_PlayerShot playerShot; + playerShot.primaryPressed = false; + playerShot.secondaryPressed = true; + playerShot.utilityPressed = false; + this->netClient->Send( playerShot ); + this->key_Shoot = true; + } + } + else + this->key_Shoot = false; + + if( this->mouseInput->IsBtnDown(::Input::Enum::SAMI_MouseMiddleBtn) ) + { + if( !this->key_Shoot ) + { + Protocol_PlayerShot playerShot; + playerShot.primaryPressed = false; + playerShot.secondaryPressed = false; + playerShot.utilityPressed = true; + this->netClient->Send( playerShot ); + this->key_Shoot = true; + } + } + else + this->key_Shoot = false; //send delta mouse movement { static const float mouseSensitivity = Radian( 1.0f ); - this->camera->PitchDown( this->input->GetPitch() * mouseSensitivity ); - this->netClient->Send( Protocol_PlayerLeftTurn(this->input->GetYaw() * mouseSensitivity) ); + ::Input::Struct::SAIPointFloat2D deltaPos; + this->mouseInput->GetDeltaPosition( deltaPos ); + + this->camera->PitchDown( deltaPos.y * mouseSensitivity );; + //if( deltaPos.x != 0.0f ) //This made the camera reset to a specific rotation. Why? + { + this->netClient->Send( Protocol_PlayerLeftTurn(deltaPos.x * mouseSensitivity) ); + } } - // shoot - //if( this->input->IsKeyPressed(DIK_Z) ) - //{ - // if( !this->key_Shoot ) - // { - // Protocol_PlayerShot playerShot; - // playerShot.primaryPressed = true; - // playerShot.secondaryPressed = false; - // playerShot.utilityPressed = false; - // this->netClient->Send( playerShot ); - // this->key_Shoot = true; - // } - //} - //else - // this->key_Shoot = false; - - //if( this->input->IsKeyPressed(DIK_X) ) - //{ - // if( !this->key_Shoot ) - // { - // Protocol_PlayerShot playerShot; - // playerShot.primaryPressed = false; - // playerShot.secondaryPressed = true; - // playerShot.utilityPressed = false; - // this->netClient->Send( playerShot ); - // this->key_Shoot = true; - // } - //} - //else - // this->key_Shoot = false; - - //if( this->input->IsKeyPressed(DIK_C) ) - //{ - // if( !this->key_Shoot ) - // { - // Protocol_PlayerShot playerShot; - // playerShot.primaryPressed = false; - // playerShot.secondaryPressed = false; - // playerShot.utilityPressed = true; - // this->netClient->Send( playerShot ); - // this->key_Shoot = true; - // } - //} - //else - // this->key_Shoot = false; - - // jump - if( this->input->IsKeyPressed(DIK_SPACE) ) + if( this->keyboardInput->IsKeyDown(::Input::Enum::SAKI_Escape) ) { - this->netClient->Send( Protocol_PlayerJump() ); - } -} \ No newline at end of file + this->nextState = GameStateUI::UIState_shut_down; + } +} + diff --git a/Code/Game/GameClient/GameClientState/GamingUI.h b/Code/Game/GameClient/GameClientState/GamingUI.h index 9f93674b..c5346004 100644 --- a/Code/Game/GameClient/GameClientState/GamingUI.h +++ b/Code/Game/GameClient/GameClientState/GamingUI.h @@ -2,16 +2,19 @@ #define DANBIAS_CLIENT_GAMING_UI_H #include "GameStateUI.h" -#include "L_inputClass.h" +#include "Input.h" #include "Camera_FPSV2.h" +#include "Buttons\Text_UI.h" +#include "Buttons\Plane_UI.h" namespace DanBias { namespace Client { class GamingUI : public GameStateUI { public: - GamingUI( InputClass *input, ::Oyster::Network::NetworkClient *connection, Camera_FPSV2 *camera ); + GamingUI( ::Input::Mouse *mouseInput, ::Input::Keyboard *keyboardInput, ::Oyster::Network::NetworkClient *connection, Camera_FPSV2 *camera ); virtual ~GamingUI(); + bool Init(); UIState Update( float deltaTime ); bool HaveGUIRender() const; @@ -19,12 +22,25 @@ namespace DanBias { namespace Client void RenderGUI() const; void RenderText() const; bool Release(); + void SetHPtext( std::wstring hp ); private: - InputClass *input; + ::Input::Mouse *mouseInput; + ::Input::Keyboard *keyboardInput; ::Oyster::Network::NetworkClient *netClient; Camera_FPSV2 *camera; + // TODO add multiple UI elements + Text_UI* text; + Plane_UI* plane; + + bool key_forward; + bool key_backward; + bool key_strafeRight; + bool key_strafeLeft; + bool key_Shoot; + bool key_Jump; + GamingUI(); void ReadKeyInput(); }; diff --git a/Code/Game/GameClient/GameClientState/LanMenuState.cpp b/Code/Game/GameClient/GameClientState/LanMenuState.cpp index 8c096617..8cca6cf4 100644 --- a/Code/Game/GameClient/GameClientState/LanMenuState.cpp +++ b/Code/Game/GameClient/GameClientState/LanMenuState.cpp @@ -28,7 +28,8 @@ struct LanMenuState::MyData GameClientState::ClientState nextState; NetworkClient *nwClient; - InputClass *input; + ::Input::Mouse *mouseInput; + ::Input::Keyboard *keyboardInput; Graphics::API::Texture background; EventButtonCollection guiElements; @@ -53,7 +54,8 @@ bool LanMenuState::Init( SharedStateContent &shared ) this->privData->nextState = GameClientState::ClientState_Same; this->privData->nwClient = shared.network; - this->privData->input = shared.input; + this->privData->mouseInput = shared.mouseDevice; + this->privData->keyboardInput = shared.keyboardDevice; this->privData->background = Graphics::API::CreateTexture( L"color_white.png" ); @@ -80,6 +82,9 @@ bool LanMenuState::Init( SharedStateContent &shared ) this->privData->connectPort = 15151; + this->privData->keyboardInput->BindTextTarget( &(*this->privData->connectIP)[0] ); + this->privData->keyboardInput->Activate(); + return true; } @@ -87,10 +92,13 @@ GameClientState::ClientState LanMenuState::Update( float deltaTime ) { MouseInput mouseState; { - this->privData->input->GetMousePos( mouseState.x, mouseState.y ); - mouseState.mouseButtonPressed = this->privData->input->IsMousePressed(); - } + ::Input::Struct::SAIPointInt2D pos; + this->privData->mouseInput->GetPixelPosition( pos ); + mouseState.x = pos.x; + mouseState.y = pos.y; + mouseState.mouseButtonPressed = this->privData->mouseInput->IsBtnDown( ::Input::Enum::SAMI_MouseLeftBtn ); + } EventHandler::Instance().Update( mouseState ); return this->privData->nextState; diff --git a/Code/Game/GameClient/GameClientState/LobbyAdminState.cpp b/Code/Game/GameClient/GameClientState/LobbyAdminState.cpp index 43419e88..312f1c41 100644 --- a/Code/Game/GameClient/GameClientState/LobbyAdminState.cpp +++ b/Code/Game/GameClient/GameClientState/LobbyAdminState.cpp @@ -22,7 +22,7 @@ struct LobbyAdminState::MyData GameClientState::ClientState nextState; NetworkClient *nwClient; - InputClass *input; + ::Input::Mouse *mouseInput; Graphics::API::Texture background; EventButtonCollection guiElements; } privData; @@ -43,7 +43,7 @@ bool LobbyAdminState::Init( SharedStateContent &shared ) this->privData->nextState = GameClientState::ClientState_Same; this->privData->nwClient = shared.network; - this->privData->input = shared.input; + this->privData->mouseInput = shared.mouseDevice; this->privData->background = Graphics::API::CreateTexture( L"grass_md.png" ); @@ -61,21 +61,15 @@ bool LobbyAdminState::Init( SharedStateContent &shared ) GameClientState::ClientState LobbyAdminState::Update( float deltaTime ) { - // Wishlist: - // picking - // mouse events - // different menus - // play sounds - // update animation - // send data to server - // check data from server - MouseInput mouseState; { - this->privData->input->GetMousePos( mouseState.x, mouseState.y ); - mouseState.mouseButtonPressed = this->privData->input->IsMousePressed(); - } + ::Input::Struct::SAIPointInt2D pos; + this->privData->mouseInput->GetPixelPosition( pos ); + mouseState.x = pos.x; + mouseState.y = pos.y; + mouseState.mouseButtonPressed = this->privData->mouseInput->IsBtnDown( ::Input::Enum::SAMI_MouseLeftBtn ); + } EventHandler::Instance().Update( mouseState ); return this->privData->nextState; diff --git a/Code/Game/GameClient/GameClientState/LobbyState.cpp b/Code/Game/GameClient/GameClientState/LobbyState.cpp index 0b117016..c47febbe 100644 --- a/Code/Game/GameClient/GameClientState/LobbyState.cpp +++ b/Code/Game/GameClient/GameClientState/LobbyState.cpp @@ -22,7 +22,7 @@ struct LobbyState::MyData GameClientState::ClientState nextState; NetworkClient *nwClient; - InputClass *input; + ::Input::Mouse *mouseInput; Graphics::API::Texture background; EventButtonCollection guiElements; } privData; @@ -43,7 +43,7 @@ bool LobbyState::Init( SharedStateContent &shared ) this->privData->nextState = GameClientState::ClientState_Same; this->privData->nwClient = shared.network; - this->privData->input = shared.input; + this->privData->mouseInput = shared.mouseDevice; this->privData->background = Graphics::API::CreateTexture( L"grass_md.png" ); @@ -61,21 +61,15 @@ bool LobbyState::Init( SharedStateContent &shared ) GameClientState::ClientState LobbyState::Update( float deltaTime ) { - // Wishlist: - // picking - // mouse events - // different menus - // play sounds - // update animation - // send data to server - // check data from server - MouseInput mouseState; { - this->privData->input->GetMousePos( mouseState.x, mouseState.y ); - mouseState.mouseButtonPressed = this->privData->input->IsMousePressed(); - } + ::Input::Struct::SAIPointInt2D pos; + this->privData->mouseInput->GetPixelPosition( pos ); + mouseState.x = pos.x; + mouseState.y = pos.y; + mouseState.mouseButtonPressed = this->privData->mouseInput->IsBtnDown( ::Input::Enum::SAMI_MouseLeftBtn ); + } EventHandler::Instance().Update( mouseState ); return this->privData->nextState; diff --git a/Code/Game/GameClient/GameClientState/MainState.cpp b/Code/Game/GameClient/GameClientState/MainState.cpp index 5b96b385..a057ab74 100644 --- a/Code/Game/GameClient/GameClientState/MainState.cpp +++ b/Code/Game/GameClient/GameClientState/MainState.cpp @@ -24,8 +24,9 @@ struct MainState::MyData GameClientState::ClientState nextState; NetworkClient *nwClient; - InputClass *input; - Graphics::API::Texture background; + ::Input::Mouse *mouseInput; + Float3 mousePos; + Graphics::API::Texture background, mouseCursor; EventButtonCollection guiElements; }; @@ -47,9 +48,12 @@ bool MainState::Init( SharedStateContent &shared ) this->privData->nextState = GameClientState::ClientState_Same; this->privData->nwClient = shared.network; - this->privData->input = shared.input; + this->privData->mouseInput = shared.mouseDevice; + //this->privData->mouseInput-> + this->privData->mousePos = Float3( 0.0f ); this->privData->background = Graphics::API::CreateTexture( L"color_white.png" ); + this->privData->mouseCursor = Graphics::API::CreateTexture( L"cursor_md.png" ); // create buttons ButtonRectangle *button; @@ -77,16 +81,13 @@ GameClientState::ClientState MainState::Update( float deltaTime ) { MouseInput mouseState; { - bool test = this->privData->input->IsMousePressed(); - if(test) - { // HACK: debug trap still in use? - int i = 0; - }; + ::Input::Struct::SAIPointFloat2D pos; + this->privData->mouseInput->GetNormalizedPosition( pos ); - this->privData->input->GetMousePos( mouseState.x, mouseState.y ); - mouseState.mouseButtonPressed = this->privData->input->IsMousePressed(); + this->privData->mousePos.x = mouseState.x = pos.x; + this->privData->mousePos.y = mouseState.y = pos.y; + mouseState.mouseButtonPressed = this->privData->mouseInput->IsBtnDown( ::Input::Enum::SAMI_MouseLeftBtn ); } - EventHandler::Instance().Update( mouseState ); return this->privData->nextState; @@ -97,6 +98,7 @@ bool MainState::Render() Graphics::API::NewFrame(); Graphics::API::StartGuiRender(); + Graphics::API::RenderGuiElement( this->privData->mouseCursor, this->privData->mousePos, Float2(0.1f), Float4(1.0f) ); Graphics::API::RenderGuiElement( this->privData->background, Float3(0.5f, 0.5f, 0.9f), Float2(1.0f), Float4(63.0f/255.0f,73.0f/255.0f,127.0f/255.0f,0.6f) ); this->privData->guiElements.RenderTexture(); @@ -112,6 +114,7 @@ bool MainState::Release() if( this->privData ) { Graphics::API::DeleteTexture( this->privData->background ); + Graphics::API::DeleteTexture( this->privData->mouseCursor ); EventHandler::Instance().ReleaseCollection( &this->privData->guiElements ); this->privData = NULL; diff --git a/Code/Game/GameClient/GameClientState/RespawnUI.cpp b/Code/Game/GameClient/GameClientState/RespawnUI.cpp index 4588d367..21732df6 100644 --- a/Code/Game/GameClient/GameClientState/RespawnUI.cpp +++ b/Code/Game/GameClient/GameClientState/RespawnUI.cpp @@ -3,6 +3,7 @@ using namespace ::DanBias::Client; using namespace ::Oyster::Network; using namespace ::Utility::Value; +using namespace ::Oyster::Math; RespawnUI::RespawnUI() : GameStateUI() @@ -17,13 +18,23 @@ RespawnUI::RespawnUI( NetworkClient *connection, float delay ) : { this->netClient = connection; this->countDown = delay; + this->text = nullptr; } RespawnUI::~RespawnUI() { /* Do nothing */ } +bool RespawnUI::Init() +{ + // z value should be between 0.5 - 0.9 so that it will be behind other states + // add textures and text + this->text = new Text_UI(L"DEAD", Float3(0.5f,0.0f,0.5f), Float2(0.2f,0.2f)); + return true; +} GameStateUI::UIState RespawnUI::Update( float deltaTime ) { this->countDown = Max( this->countDown - deltaTime, 0.0f ); + // countDown == 0 + // return UIState_gaming state; return this->nextState; } @@ -34,25 +45,32 @@ bool RespawnUI::HaveGUIRender() const bool RespawnUI::HaveTextRender() const { - return false; // TODO: change to true when we want UI elements like a chat window + return true; // TODO: change to true when we want UI elements like a chat window } void RespawnUI::RenderGUI() const { - // TODO: We need? + // TODO:BLOODY SCREEN } void RespawnUI::RenderText() const { + this->text->RenderText(); // TODO: Text countdown somewhere on screen would be nice } bool RespawnUI::Release() { // TODO: Release UI components here. + if(this->text) + delete this->text; return true; } +void RespawnUI::SetCountdown( float cd ) +{ + this->countDown = cd; + // this text should be rendered +} - diff --git a/Code/Game/GameClient/GameClientState/RespawnUI.h b/Code/Game/GameClient/GameClientState/RespawnUI.h index c45616b7..6e5df64e 100644 --- a/Code/Game/GameClient/GameClientState/RespawnUI.h +++ b/Code/Game/GameClient/GameClientState/RespawnUI.h @@ -2,6 +2,8 @@ #define DANBIAS_CLIENT_RESPAWN_UI_H #include "GameStateUI.h" +#include "Buttons\Text_UI.h" +#include "Buttons\Plane_UI.h" namespace DanBias { namespace Client { @@ -10,18 +12,23 @@ namespace DanBias { namespace Client public: RespawnUI( ::Oyster::Network::NetworkClient *connection, float delay ); virtual ~RespawnUI(); + bool Init(); + // TODO countdown UIState Update( float deltaTime ); bool HaveGUIRender() const; bool HaveTextRender() const; void RenderGUI() const; void RenderText() const; bool Release(); + void SetCountdown( float cd ); private: ::Oyster::Network::NetworkClient *netClient; float countDown; + // TODO add multiple UI elements + Text_UI* text; RespawnUI(); }; } } diff --git a/Code/Game/GameClient/GameClientState/SharedStateContent.h b/Code/Game/GameClient/GameClientState/SharedStateContent.h index 49d01775..cb722cec 100644 --- a/Code/Game/GameClient/GameClientState/SharedStateContent.h +++ b/Code/Game/GameClient/GameClientState/SharedStateContent.h @@ -15,7 +15,7 @@ #include "C_obj\C_DynamicObj.h" #include "C_Light.h" #include "NetworkClient.h" -#include "L_inputClass.h" +#include "Input.h" namespace DanBias { namespace Client { @@ -26,7 +26,9 @@ namespace DanBias { namespace Client ::std::map> dynamicObjects; ::std::map> lights; ::Oyster::Network::NetworkClient *network; - InputClass* input; + + ::Input::Mouse *mouseDevice; + ::Input::Keyboard *keyboardDevice; }; } } diff --git a/Code/Game/GameClient/GameClientState/StatsUI.cpp b/Code/Game/GameClient/GameClientState/StatsUI.cpp new file mode 100644 index 00000000..ab07b89d --- /dev/null +++ b/Code/Game/GameClient/GameClientState/StatsUI.cpp @@ -0,0 +1,65 @@ +#include "StatsUI.h" +#include +#include "Utilities.h" + +using namespace ::DanBias::Client; +using namespace ::GameLogic; +using namespace ::Utility::Value; +using namespace ::Oyster::Math; + +StatsUI::StatsUI() : + GameStateUI() +{ + /* Should never be called! */ + this->plane = nullptr; + this->text = nullptr; +} + +StatsUI::~StatsUI() { /* Do nothing */ } +bool StatsUI::Init() +{ + // z value should be between 0.1 - 0.5 so that it will be in front of other states + // add textures and text for player stats + this->plane = new Plane_UI(L"box_tex.png", Float3(0.0f, 0.0f, 0.5f), Float2(0.3f, 0.1f)); + this->text = new Text_UI(L"Stats", Float3(0.0f,0.0f,0.1f), Float2(0.1f,0.1f)); + + return true; +} +GameStateUI::UIState StatsUI::Update( float deltaTime ) +{ + return this->nextState; +} + +bool StatsUI::HaveGUIRender() const +{ + // Set true if UIstate have any plane to render + return true; +} + +bool StatsUI::HaveTextRender() const +{ + // Set true if UIstate have any text to render + return true; +} + +void StatsUI::RenderGUI() const +{ + // render all the planes + this->plane->RenderTexture(); +} + +void StatsUI::RenderText() const +{ + // render all the text + this->text->RenderText(); +} + +bool StatsUI::Release() +{ + // TODO: Release UI components here. + if(this->plane) + delete this->plane; + if(this->text) + delete this->text; + return true; +} diff --git a/Code/Game/GameClient/GameClientState/StatsUI.h b/Code/Game/GameClient/GameClientState/StatsUI.h new file mode 100644 index 00000000..589f956b --- /dev/null +++ b/Code/Game/GameClient/GameClientState/StatsUI.h @@ -0,0 +1,34 @@ +#ifndef DANBIAS_CLIENT_STATS_UI_H +#define DANBIAS_CLIENT_STATS_UI_H + +#include "GameStateUI.h" +#include "Buttons\Text_UI.h" +#include "Buttons\Plane_UI.h" + +namespace DanBias { namespace Client +{ + class StatsUI : public GameStateUI + { + public: + StatsUI(); + virtual ~StatsUI(); + bool Init(); + + UIState Update( float deltaTime ); + bool HaveGUIRender() const; + bool HaveTextRender() const; + void RenderGUI() const; + void RenderText() const; + bool Release(); + // TODO add function to add a new players statistics + // TODO add function to remove a players statistics + + private: + // TODO add multiple UI elements + // one for each player ingame + Text_UI* text; + Plane_UI* plane; + }; +} } + +#endif \ No newline at end of file diff --git a/Code/Game/GameClient/Include/DanBiasGame.h b/Code/Game/GameClient/Include/DanBiasGame.h index 74248d47..f6f0cdee 100644 --- a/Code/Game/GameClient/Include/DanBiasGame.h +++ b/Code/Game/GameClient/Include/DanBiasGame.h @@ -55,7 +55,7 @@ namespace DanBias }; static HRESULT InitDirect3D(); - static HRESULT InitInput(); + static HRESULT InitInput( HWND handle ); static Result Update(float deltaTime); static HRESULT Render(); diff --git a/Code/Game/GameClient/Win32Input.h b/Code/Game/GameClient/Win32Input.h new file mode 100644 index 00000000..1d2605cf --- /dev/null +++ b/Code/Game/GameClient/Win32Input.h @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// +#ifndef INCLUDE_GUARD_RAW_INPUT_H +#define INCLUDE_GUARD_RAW_INPUT_H + + +#include "..\InputManager.h" +#include "Win32Keyboard.h" +#include "Win32Mouse.h" +#include +#define NOMINMAX +#include +#include + +/** +* TODO: +* 1. Cordinate system +* 1.1. Pixel cordinates DONE +* 1.2. 0 - 1 cordinate DONW +* 1.3. Origo in middle of the screen ( -1 to 1 ) +*/ + +//RIDEV_INPUTSINK to receive all keyboard input regardless of focus + +//dx = +2*(x/w) -1 +//dx = -2*(y/h) +1 + + +namespace Input +{ + enum RawInput_Usage + { + RawInput_Usage_pointer = 1, + RawInput_Usage_mouse = 2, + RawInput_Usage_joystick = 4, + RawInput_Usage_gamepad = 5, + RawInput_Usage_keyboard = 6, + RawInput_Usage_keypad = 7, + RawInput_Usage_multiAxisController = 8, + RawInput_Usage_TabletPCcontrols = 9, + }; + + class Win32Input :public InputManager + { + public: + Win32Input(); + virtual~Win32Input(); + + InputObject* CreateDevice(const Enum::SAIType inputType, Typedefs::WindowHandle targetApplication) override; + void ToggleInputSystem(bool enable) override; + void Destroy() override; + + private: + std::vector keyboard; + std::vector mouse; + + bool enabled; + bool exclusive; + HWND targetHwin; + + private: + static Win32Input* instance; + static LRESULT RawInputParser(HWND h, LPARAM l); + static LRESULT CALLBACK RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l); + static void WindowActivate(bool activate); + }; +} +#endif + diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index 3102b9f2..89de1f3e 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -106,6 +106,8 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float args.pushForce = pushForce; Oyster::Physics::API::Instance().ApplyEffect(hitCone,&args,ForcePushAction); + + if(hitCone) delete hitCone; } /******************************************************** @@ -141,6 +143,8 @@ void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt) args.pushForce = -pushForce; Oyster::Physics::API::Instance().ApplyEffect(hitCone,&args,ForcePushAction); + + if(hitCone) delete hitCone; } void AttatchmentMassDriver::PickUpObject(const WEAPON_FIRE &usage, float dt) @@ -150,5 +154,5 @@ void AttatchmentMassDriver::PickUpObject(const WEAPON_FIRE &usage, float dt) Oyster::Physics::API::Instance().ApplyEffect(hitSphere,this,AttemptPickUp); - delete hitSphere; + if(hitSphere) delete hitSphere; } diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 848c528a..5b855785 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -79,99 +79,133 @@ void Player::BeginFrame() Oyster::Math::Float maxSpeed = 30; + // Rotate player accordingly + this->rigidBody->SetUp(this->rigidBody->GetState().centerPos.GetNormalized()); + Oyster::Math::Quaternion firstUp = this->rigidBody->GetState().quaternion; + this->rigidBody->SetRotationAsAngularAxis(Oyster::Math3D::Float4(this->rigidBody->GetState().centerPos.GetNormalized(), this->rotationUp)); + Oyster::Math::Quaternion secondTurn = this->rigidBody->GetState().quaternion; + + this->rigidBody->SetRotation(secondTurn*firstUp); + + // Direction data Oyster::Math::Float4x4 xform; xform = this->rigidBody->GetState().GetOrientation(); - /* Handle turning */ - /*if (left) - m_turnAngle -= dt * m_turnVelocity; - if (right) - m_turnAngle += dt * m_turnVelocity; - - xform.setRotation (btQuaternion (btVector3(0.0, 1.0, 0.0), m_turnAngle));*/ - - Oyster::Math::Float3 linearVelocity = this->rigidBody->GetLinearVelocity(); - Oyster::Math::Float speed = this->rigidBody->GetLinearVelocity().GetLength(); - Oyster::Math::Float3 forwardDir = xform.v[2]; + Oyster::Math::Float3 upDir = xform.v[1]; Oyster::Math::Float3 rightDir = xform.v[0]; forwardDir.Normalize(); + upDir.Normalize(); rightDir.Normalize(); + + // Previous velocities data + Oyster::Math::Float3 linearVelocity = this->rigidBody->GetLinearVelocity(); + Oyster::Math::Float3 forwardVelocity = linearVelocity*Oyster::Math::Float3(fabs(forwardDir.x), fabs(forwardDir.y), fabs(forwardDir.z)); + Oyster::Math::Float forwardSpeed = (linearVelocity*forwardDir).GetLength(); + Oyster::Math::Float3 rightVelocity = linearVelocity*Oyster::Math::Float3(fabs(rightDir.x), fabs(rightDir.y), fabs(rightDir.z)); + Oyster::Math::Float rightSpeed = (linearVelocity*rightDir).GetLength(); + Oyster::Math::Float3 upVelocity = linearVelocity*Oyster::Math::Float3(fabs(upDir.x), fabs(upDir.y), fabs(upDir.z)); + + // Walking data Oyster::Math::Float3 walkDirection = Oyster::Math::Float3(0.0, 0.0, 0.0); Oyster::Math::Float walkSpeed = this->moveSpeed*0.2f; - if (key_forward > 0.001) + // Check for input + if(key_forward > 0.001) { key_forward -= gameInstance->GetFrameTime(); walkDirection += forwardDir; - walkDirection.Normalize(); } - if (key_backward > 0.001) + if(key_backward > 0.001) { key_backward -= gameInstance->GetFrameTime(); walkDirection -= forwardDir; - walkDirection.Normalize(); } - if (key_strafeRight > 0.001) + if(key_strafeRight > 0.001) { key_strafeRight -= gameInstance->GetFrameTime(); - walkDirection -= rightDir; - walkDirection.Normalize(); + walkDirection += rightDir; } - if (key_strafeLeft > 0.001) + if(key_strafeLeft > 0.001) { key_strafeLeft -= gameInstance->GetFrameTime(); - walkDirection += rightDir; - walkDirection.Normalize(); - maxSpeed = 40; + walkDirection -= rightDir; } - - if (key_forward <= 0.001 && key_backward <= 0.001 && key_strafeRight <= 0.001 && key_strafeLeft <= 0.001 && key_jump <= 0.001 && this->rigidBody->GetLambda() < 0.7f) + // Dampen velocity if certain keys are not pressed + if(key_jump <= 0.001 && this->rigidBody->GetLambda() < 0.9f) { - /* Dampen when on the ground and not being moved by the player */ - linearVelocity *= 0.2f; - this->rigidBody->SetLinearVelocity (linearVelocity); - } - else - { - if (speed < maxSpeed && this->rigidBody->GetLambda() < 1.0f) + if(key_forward <= 0.001 && key_backward <= 0.001) { - Oyster::Math::Float3 velocity = linearVelocity + walkDirection * walkSpeed; - this->rigidBody->SetLinearVelocity(velocity); + forwardVelocity *= Oyster::Math::Float3(0.2f*fabs(forwardDir.x), 0.2f*fabs(forwardDir.y), 0.2f*fabs(forwardDir.z)); } - else if(speed < maxSpeed) + if(key_strafeRight <= 0.001 && key_strafeLeft <= 0.001) { - Oyster::Math::Float3 velocity = linearVelocity + (walkDirection * walkSpeed)*0.2f; - this->rigidBody->SetLinearVelocity(velocity); + rightVelocity *= Oyster::Math::Float3(0.2f*fabs(rightDir.x), 0.2f*fabs(rightDir.y), 0.2f*fabs(rightDir.z)); + } + } + + // Walk if walkdirection is something + if(walkDirection != Oyster::Math::Float3::null) + { + walkDirection.Normalize(); + + // If on the ground, accelerate normally + if(this->rigidBody->GetLambda() < 0.9f) + { + if(forwardSpeed < maxSpeed) + { + forwardVelocity += walkDirection*Oyster::Math::Float3(fabs(forwardDir.x), fabs(forwardDir.y), fabs(forwardDir.z)) * walkSpeed; + } + if(rightSpeed < maxSpeed) + { + rightVelocity += walkDirection*Oyster::Math::Float3(fabs(rightDir.x), abs(rightDir.y), fabs(rightDir.z)) * walkSpeed; + } + } + // If in the air, accelerate slower + if(this->rigidBody->GetLambda() >= 0.9f) + { + if(forwardSpeed < maxSpeed) + { + forwardVelocity += walkDirection*Oyster::Math::Float3(fabs(forwardDir.x), fabs(forwardDir.y), fabs(forwardDir.z)) * walkSpeed*0.2f; + } + if(rightSpeed < maxSpeed) + { + rightVelocity += walkDirection*Oyster::Math::Float3(fabs(rightDir.x), fabs(rightDir.y), fabs(rightDir.z)) * walkSpeed*0.2f; + } } } - if (key_jump > 0.001) + // Adjust velocities so no squaring occurs + forwardVelocity *= Oyster::Math::Float3(fabs(forwardDir.x), fabs(forwardDir.y), fabs(forwardDir.z)); + rightVelocity *= Oyster::Math::Float3(fabs(rightDir.x), fabs(rightDir.y), fabs(rightDir.z)); + upVelocity *= Oyster::Math::Float3(fabs(upDir.x), fabs(upDir.y), fabs(upDir.z)); + + this->rigidBody->SetLinearVelocity(forwardVelocity+rightVelocity+upVelocity); + + //Jump + if(key_jump > 0.001) { this->key_jump -= this->gameInstance->GetFrameTime(); - if(this->rigidBody->GetLambda() < 1.0f) + if(this->rigidBody->GetLambda() < 0.9f) { - Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1].GetNormalized(); + Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.GetNormalized(); this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass*20); this->playerState = PLAYER_STATE::PLAYER_STATE_JUMPING; } } - Oyster::Math::Float3 pos = this->rigidBody->GetState().centerPos; - if(pos == Oyster::Math::Float3(0,0,0)) - int i =0; + + + //this->weapon->Update(0.01f); } void Player::EndFrame() { - // snap to axis - Oyster::Math::Float4 rotation; - - this->rigidBody->SetUp(this->rigidBody->GetState().centerPos.GetNormalized()); //Object::EndFrame(); + } void Player::Move(const PLAYER_MOVEMENT &movement) @@ -235,13 +269,10 @@ void Player::Rotate(const Oyster::Math3D::Float3& lookDir, const Oyster::Math3D: // this is the camera right vector this->lookDir = lookDir; - //Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1]; - //this->rigidBody->SetUpAndRight(up, right); } void Player::TurnLeft(Oyster::Math3D::Float deltaRadians) { this->rotationUp += deltaRadians; - this->rigidBody->SetRotationAsAngularAxis(Oyster::Math3D::Float4(this->rigidBody->GetState().centerPos.GetNormalized(), this->rotationUp)); } void Player::Jump() diff --git a/Code/Game/GameProtocols/ObjectProtocols.h b/Code/Game/GameProtocols/ObjectProtocols.h index fc02a4bd..cae7c7f5 100644 --- a/Code/Game/GameProtocols/ObjectProtocols.h +++ b/Code/Game/GameProtocols/ObjectProtocols.h @@ -892,6 +892,38 @@ namespace GameLogic Oyster::Network::CustomNetProtocol protocol; }; + //#define protocol_Gameplay_ObjectDisconnectPlayer 367 + struct Protocol_ObjectDisconnectPlayer :public Oyster::Network::CustomProtocolObject + { + int objectID; + + Protocol_ObjectDisconnectPlayer() + { + this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + this->protocol[0].value.netShort = protocol_Gameplay_ObjectDisconnectPlayer; + this->protocol[1].type = Oyster::Network::NetAttributeType_Int; + this->objectID = 0; + } + Protocol_ObjectDisconnectPlayer(int objectID) + { + this->protocol[0].type = Oyster::Network::NetAttributeType_Short; + this->protocol[0].value.netShort = protocol_Gameplay_ObjectDisconnectPlayer; + this->protocol[1].type = Oyster::Network::NetAttributeType_Int; + this->objectID = objectID; + } + Protocol_ObjectDisconnectPlayer(Oyster::Network::CustomNetProtocol& p) + { + this->objectID = p[1].value.netInt; + } + Oyster::Network::CustomNetProtocol GetProtocol() override + { + this->protocol[1].value = this->objectID; + return protocol; + } + + private: + Oyster::Network::CustomNetProtocol protocol; + }; } #endif // !GAMELOGIC_PLAYER_PROTOCOLS_H \ No newline at end of file diff --git a/Code/Game/GameProtocols/ProtocolIdentificationID.h b/Code/Game/GameProtocols/ProtocolIdentificationID.h index 4394a1a1..cb630012 100644 --- a/Code/Game/GameProtocols/ProtocolIdentificationID.h +++ b/Code/Game/GameProtocols/ProtocolIdentificationID.h @@ -69,6 +69,8 @@ #define protocol_Gameplay_ObjectWeaponEnergy 364 #define protocol_Gameplay_ObjectRespawn 365 #define protocol_Gameplay_ObjectDie 366 +//Disconnect +#define protocol_Gameplay_ObjectDisconnectPlayer 367 #define protocol_GameplayMAX 399 diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index e2a2961d..0c52dfff 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -61,8 +61,19 @@ using namespace DanBias; switch (e.args.type) { case NetworkClient::ClientEventArgs::EventType_Disconnect: + { + //Send disconnect message to all the other players so the player can be removed from the client. + Protocol_ObjectDisconnectPlayer dp(cl->GetClient()->GetID()); + for(int i = 0; i < this->gClients.Size(); i++) + { + if(this->gClients[i] && this->gClients[i] != cl) + { + this->gClients[i]->GetClient()->Send(dp); + } + } printf("\t(%i : %s) - EventType_Disconnect\n", cl->GetClient()->GetID(), e.sender->GetIpAddress().c_str()); this->gClients[temp]->Invalidate(); + } break; case NetworkClient::ClientEventArgs::EventType_ProtocolFailedToRecieve: break; diff --git a/Code/Game/GameServer/Implementation/GameSession_General.cpp b/Code/Game/GameServer/Implementation/GameSession_General.cpp index 30eabed2..2b8a7d5c 100644 --- a/Code/Game/GameServer/Implementation/GameSession_General.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_General.cpp @@ -234,7 +234,7 @@ bool GameSession::Join(gClient gameClient) { //Protocol_ObjectPosition p(movedObject->GetPosition(), id); Protocol_ObjectPositionRotation p(objects[i]->GetPosition(), objects[i]->GetRotation(), objects[i]->GetID()); - GameSession::gameSession->Send(p.GetProtocol()); + nwClient->Send(p.GetProtocol()); } } diff --git a/Code/Misc/Input/Include/ApplicationKeyboard.h b/Code/Misc/Input/Include/ApplicationKeyboard.h index d28140b3..b03e5abb 100644 --- a/Code/Misc/Input/Include/ApplicationKeyboard.h +++ b/Code/Misc/Input/Include/ApplicationKeyboard.h @@ -12,6 +12,8 @@ namespace Input class ApplicationKeyboard : public InputObject { public: + virtual ~ApplicationKeyboard(); + bool IsActive() const; void Activate(); @@ -25,7 +27,6 @@ namespace Input ::std::wstring::size_type writePos; ApplicationKeyboard(); - ~ApplicationKeyboard(); private: bool active; diff --git a/Code/Misc/Input/Include/Common.h b/Code/Misc/Input/Include/Common.h index a82ad47b..694001a3 100644 --- a/Code/Misc/Input/Include/Common.h +++ b/Code/Misc/Input/Include/Common.h @@ -21,11 +21,16 @@ namespace Input { SAIType_Keyboard, SAIType_Mouse, - SAIType_ApplicationKeyboard, + //SAIType_ApplicationKeyboard, SAIType_futureExample1, SAIType_futureExample2, SAIType_futureExample3, }; + enum InputOptionType + { + InputOptionType_RawInput, + InputOptionType_PlatformDefault, + }; enum ButtonState { ButtonState_Press, // When button is pressed (once) @@ -37,15 +42,24 @@ namespace Input /*********************************************************************/ namespace Struct { - struct SAIPoint2D + struct SAIPointInt2D { int x; int y; - SAIPoint2D() :x(0), y(0) { } - SAIPoint2D(int _x, int _y) :x(_x), y(_y) { } + SAIPointInt2D() :x(0), y(0) { } + SAIPointInt2D(int _x, int _y) :x(_x), y(_y) { } int Length() { return (abs(x) + abs(y)); } }; + struct SAIPointFloat2D + { + float x; + float y; + SAIPointFloat2D() :x(0.0f), y(0.0f) { } + SAIPointFloat2D(float _x, float _y) :x(_x), y(_y) { } + float Length() { return (fabs(x) + fabs(y)); } + }; + struct InputData; } /*********************************************************************/ diff --git a/Code/Misc/Input/Include/InputManager.h b/Code/Misc/Input/Include/InputManager.h index ee037563..1feff9cf 100644 --- a/Code/Misc/Input/Include/InputManager.h +++ b/Code/Misc/Input/Include/InputManager.h @@ -18,12 +18,12 @@ namespace Input /** * @return Returns an instance of the default input manager. */ - static InputManager* Instance (); + static InputManager* Instance (); /** * @return Returns a new input manager. Should be destroyd with DestroyInputManager function. */ - static InputManager* CreateInputManager (); + static InputManager* CreateInputManager (); /** * @return Destroys a input manager. @@ -37,7 +37,9 @@ namespace Input * @see InputDescription * @return Returns a handle to a device that can be rethrown to a specific device. */ - virtual InputObject* CreateDevice (const Enum::SAIType inputType, Typedefs::WindowHandle targetApplication = 0) = 0; + virtual InputObject* CreateDevice ( const Enum::SAIType inputType, Typedefs::WindowHandle targetApplication ) = 0; + virtual Keyboard* CreateKeyboardDevice ( Typedefs::WindowHandle targetApplication ) { return (Keyboard*)CreateDevice(Enum::SAIType_Keyboard, targetApplication); } + virtual Mouse* CreateMouseDevice ( Typedefs::WindowHandle targetApplication ) { return (Mouse*)CreateDevice(Enum::SAIType_Mouse, targetApplication); } /** Enables or Disables the Input proccessing. * @param The toggler. diff --git a/Code/Misc/Input/Include/InputObject.h b/Code/Misc/Input/Include/InputObject.h index 75dea07b..3536730b 100644 --- a/Code/Misc/Input/Include/InputObject.h +++ b/Code/Misc/Input/Include/InputObject.h @@ -13,8 +13,9 @@ namespace Input public: inline Enum::SAIType Type() { return type; } - virtual inline void Enable () { isEnabled = true; }; - virtual inline void Disable () { isEnabled = false; }; + virtual void Activate () = 0; + virtual void Deactivate () = 0; + virtual bool IsActive() = 0; protected: InputObject(Enum::SAIType type) { this->type = type; } @@ -22,9 +23,6 @@ namespace Input private: Enum::SAIType type; - - protected: - bool isEnabled; }; } diff --git a/Code/Misc/Input/Include/Keyboard.h b/Code/Misc/Input/Include/Keyboard.h index 6f561eba..4db0bce6 100644 --- a/Code/Misc/Input/Include/Keyboard.h +++ b/Code/Misc/Input/Include/Keyboard.h @@ -49,6 +49,10 @@ namespace Input SAKI_7 , SAKI_8 , SAKI_9 , + SAKI_Add , + SAKI_Comma , + SAKI_Minus , + SAKI_Period , SAKI_A , SAKI_B , SAKI_C , @@ -133,9 +137,9 @@ namespace Input //----------------------------------------------------------------------------------------------------------------------------- namespace Typedefs { - typedef void(*OnKeyPressCallback)(Enum::SAKI key, const wchar_t[40], Keyboard* sender); - typedef void(*OnKeyDownCallback)(Enum::SAKI key, const wchar_t[40], Keyboard* sender); - typedef void(*OnKeyReleaseCallback)(Enum::SAKI key, const wchar_t[40], Keyboard* sender); + typedef void(*OnKeyPressCallback)(Enum::SAKI key, Keyboard* sender); + typedef void(*OnKeyDownCallback)(Enum::SAKI key, Keyboard* sender); + typedef void(*OnKeyReleaseCallback)(Enum::SAKI key, Keyboard* sender); } //----------------------------------------------------------------------------------------------------------------------------- @@ -145,15 +149,22 @@ namespace Input class KeyboardEvent { public: - virtual void OnKeyPress(Enum::SAKI key, const wchar_t[40], Keyboard* sender) { } - virtual void OnKeyDown(Enum::SAKI key, const wchar_t[40], Keyboard* sender) { } - virtual void OnKeyRelease(Enum::SAKI key, const wchar_t[40], Keyboard* sender) { } + virtual void OnKeyPress(Enum::SAKI key, Keyboard* sender) { } + virtual void OnKeyDown(Enum::SAKI key, Keyboard* sender) { } + virtual void OnKeyRelease(Enum::SAKI key, Keyboard* sender) { } }; public: /* Manual check functions */ + virtual ~Keyboard(); + virtual bool IsKeyUp (Enum::SAKI key) = 0; virtual bool IsKeyDown (Enum::SAKI key) = 0; - virtual const wchar_t* GetAsText(Enum::SAKI key) = 0; + virtual wchar_t* GetAsText(Enum::SAKI key) = 0; + + public: /* From InputObject */ + virtual void Activate () override = 0; + virtual void Deactivate () override = 0; + virtual bool IsActive() override = 0; public: /* global subscribe callback functions */ void AddOnKeyPressCallback (Typedefs::OnKeyPressCallback func); @@ -168,45 +179,27 @@ namespace Input void operator+= (KeyboardEvent* object); void operator-= (KeyboardEvent* object); + void BindTextTarget( ::std::wstring *field ); + void ReleaseTextTarget(); + + public: + struct KeyboardCallbackList; + protected: Keyboard(); - ~Keyboard(); - protected: - struct KeyboardCallbackList - { - enum CallbackDataType - { - CallbackDataType_OnPress, - CallbackDataType_OnDown, - CallbackDataType_OnRelease - } type; - union CallbackData - { - Typedefs::OnKeyPressCallback keyPressCallback; - Typedefs::OnKeyDownCallback keyDownCallback; - Typedefs::OnKeyReleaseCallback keyReleaseCallback; - - CallbackData (){ memset(this, 0, sizeof(CallbackData)); } - CallbackData (Typedefs::OnKeyPressCallback o){ keyPressCallback = o; } - bool operator ==(CallbackData o){ return o.keyDownCallback == keyDownCallback; } - bool operator ==(Typedefs::OnKeyPressCallback o ){ return o == keyPressCallback; } - operator bool(){ return this->keyDownCallback != 0; } - } function; - KeyboardCallbackList *next; - KeyboardCallbackList(CallbackData func, CallbackDataType t) :function(func), next(0), type(t) { } - }; - - protected: - void ClearList(KeyboardCallbackList* first); - void AddToList(Keyboard::KeyboardCallbackList* first, KeyboardCallbackList::CallbackData data, KeyboardCallbackList::CallbackDataType type); - void RemoveFromList(KeyboardCallbackList* first, KeyboardCallbackList::CallbackData data); - bool ExistsInList(KeyboardCallbackList* first, KeyboardCallbackList::CallbackData data); - bool ExistsInList(std::vector& list, KeyboardEvent* data); + protected: /* Internal event proc */ + void InternalOnKeyPress(Enum::SAKI key); + void InternalOnKeyDown(Enum::SAKI key); + void InternalOnKeyRelease(Enum::SAKI key); protected: std::vector keyEventSubscrivers; KeyboardCallbackList* callbackList; + ::std::wstring* textTarget; + ::std::wstring::size_type writePos; + bool active; + Enum::InputOptionType inputMode; }; } diff --git a/Code/Misc/Input/Include/Mouse.h b/Code/Misc/Input/Include/Mouse.h index 510fe3a9..f83a71a5 100644 --- a/Code/Misc/Input/Include/Mouse.h +++ b/Code/Misc/Input/Include/Mouse.h @@ -47,7 +47,8 @@ namespace Input typedef void(*OnMousePressCallback)(Enum::SAMI btn, Mouse* sender); typedef void(*OnMouseDownCallback)(Enum::SAMI btn, Mouse* sender); typedef void(*OnMouseReleaseCallback)(Enum::SAMI btn, Mouse* sender); - typedef void(*OnMouseMoveCallback)(Struct::SAIPoint2D, Mouse* sender); + typedef void(*OnMouseMovePixelPosCallback)(Struct::SAIPointInt2D cord, Mouse* sender); + typedef void(*OnMouseMoveVelocityCallback)(Struct::SAIPointInt2D cord, Mouse* sender); typedef void(*OnMouseScrollCallback)(int delta, Mouse* sender); } //----------------------------------------------------------------------------------------------------------------------------- @@ -55,91 +56,78 @@ namespace Input class Mouse :public InputObject { public: + class MouseEvent { public: - virtual void OnMousePress ( Enum::SAMI key, Mouse* sender ) { } - virtual void OnMouseDown ( Enum::SAMI key, Mouse* sender ) { } - virtual void OnMouseRelease ( Enum::SAMI key, Mouse* sender ) { } - virtual void OnMouseMove ( Struct::SAIPoint2D coordinate, Mouse* sender ) { } - virtual void OnMouseScroll ( int delta, Mouse* sender ) { } + virtual void OnMousePress ( Enum::SAMI key, Mouse* sender ) { } + virtual void OnMouseDown ( Enum::SAMI key, Mouse* sender ) { } + virtual void OnMouseRelease ( Enum::SAMI key, Mouse* sender ) { } + virtual void OnMouseMovePixelPos ( Struct::SAIPointInt2D coordinate, Mouse* sender ) { } + virtual void OnMouseMoveVelocity ( Struct::SAIPointInt2D coordinate, Mouse* sender ) { } + virtual void OnMouseScroll ( int delta, Mouse* sender ) { } }; - public: - virtual bool IsBtnUp(Enum::SAMI key) = 0; - virtual bool IsBtnDown(Enum::SAMI key) = 0; - - public: - int GetWheelDelta() const; - Struct::SAIPoint2D & GetPixelPosition( Struct::SAIPoint2D &targetMem = Struct::SAIPoint2D() ) const; - Struct::SAIPoint2D & GetDeltaPosition( Struct::SAIPoint2D &targetMem = Struct::SAIPoint2D() ) const; + public: /* Manual check functions */ + virtual bool IsBtnUp(Enum::SAMI key) const = 0; + virtual bool IsBtnDown(Enum::SAMI key) const = 0; + virtual int GetWheelDelta() const = 0; + virtual Struct::SAIPointInt2D& GetPixelPosition(Struct::SAIPointInt2D& targetMem = Struct::SAIPointInt2D()) const = 0; + virtual Struct::SAIPointFloat2D& GetNormalizedPosition(Struct::SAIPointFloat2D& targetMem = Struct::SAIPointFloat2D()) = 0; + virtual Struct::SAIPointFloat2D& GetDeltaPosition(Struct::SAIPointFloat2D& targetMem = Struct::SAIPointFloat2D()) const = 0; + public: /* From InputObject */ + virtual void Activate () override = 0; + virtual void Deactivate () override = 0; + virtual bool IsActive() override = 0; + + public: /* global subscribe callback functions */ void AddOnMousePressCallback( Typedefs::OnMousePressCallback func); void AddOnMouseDownCallback( Typedefs::OnMouseDownCallback func ); void AddOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func ); - void AddOnMouseMoveCallback( Typedefs::OnMouseMoveCallback func ); + void AddOnMouseMovePixelPosCallback( Typedefs::OnMouseMovePixelPosCallback func ); + void AddOnMouseMoveVelocityCallback( Typedefs::OnMouseMoveVelocityCallback func ); void AddOnMouseScrollCallback( Typedefs::OnMouseScrollCallback func ); void RemoveOnMousePressCallback( Typedefs::OnMousePressCallback func); void RemoveOnMouseDownCallback( Typedefs::OnMouseDownCallback func ); void RemoveOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func ); - void RemoveOnMouseMoveCallback( Typedefs::OnMouseMoveCallback func ); + void RemoveOnMouseMovePixelPosCallback( Typedefs::OnMouseMovePixelPosCallback func ); + void RemoveOnMouseMoveVelocityCallback( Typedefs::OnMouseMoveVelocityCallback func ); void RemoveOnMouseScrollCallback( Typedefs::OnMouseScrollCallback func ); + public: + void operator+= (MouseEvent* object); + void operator-= (MouseEvent* object); + void SetPixelPos(int x, int y); void ToggleCursor(bool toggler); - private: - void operator+= (MouseEvent* object); - void operator-= (MouseEvent* object); + public: + struct MouseCallbackList; protected: Mouse(); - ~Mouse(); + virtual ~Mouse(); protected: - struct MouseCallbackList - { - enum CallbackDataType - { - CallbackDataType_OnPress, - CallbackDataType_OnDown, - CallbackDataType_OnRelease, - CallbackDataType_OnMove, - CallbackDataType_OnScroll, - } type; - union CallbackData - { - Typedefs::OnMousePressCallback mousePressCallback; - Typedefs::OnMouseDownCallback mouseDownCallback; - Typedefs::OnMouseReleaseCallback mouseReleaseCallback; - Typedefs::OnMouseMoveCallback mouseMoveCallback; - Typedefs::OnMouseScrollCallback mouseScrollCallback; - void* dummy; - - CallbackData (){ memset(this, 0, sizeof(CallbackData)); } - CallbackData (void* d){ dummy = d; } - bool operator ==(CallbackData o){ return o.dummy == dummy; } - bool operator ==(void* o ){ return o == dummy; } - operator bool(){ return this->dummy != 0; } - } function; - MouseCallbackList *next; - MouseCallbackList(CallbackData func, CallbackDataType t) :function(func), next(0), type(t) { } - }; - - protected: - void ClearList(MouseCallbackList* first); - void AddToList(MouseCallbackList* first, MouseCallbackList::CallbackData data, MouseCallbackList::CallbackDataType type); - void RemoveFromList(MouseCallbackList* first, MouseCallbackList::CallbackData data); - bool ExistsInList(MouseCallbackList* first, MouseCallbackList::CallbackData data); - bool ExistsInList(std::vector& list, MouseEvent* data); + void InternalOnBtnPress(Enum::SAMI key); + void InternalOnBtnDown(Enum::SAMI key); + void InternalOnBtnRelease(Enum::SAMI key); + void InternalOnMove(Struct::SAIPointInt2D pixelPos, Struct::SAIPointInt2D velocity); + void InternalOnScroll(int delta); protected: std::vector mouseSubscribers; MouseCallbackList* callbackList; - Struct::SAIPoint2D pixelPos, deltaPos; + Struct::SAIPointInt2D pixelPos; + Struct::SAIPointInt2D velocity; + Struct::SAIPointFloat2D normalPos; + Struct::SAIPointFloat2D deltaPos; + bool isCurorLocked; int wheelDelta; + Enum::InputOptionType inputMode; }; } diff --git a/Code/Misc/Input/Include/Win32/Win32Input.h b/Code/Misc/Input/Include/Win32/Win32Input.h index b7a41ce0..fb3fe4ec 100644 --- a/Code/Misc/Input/Include/Win32/Win32Input.h +++ b/Code/Misc/Input/Include/Win32/Win32Input.h @@ -8,16 +8,16 @@ #include "..\InputManager.h" #include "Win32Keyboard.h" #include "Win32Mouse.h" -#include "Win32ApplicationKeyboard.h" #include +#define NOMINMAX #include #include /** * TODO: * 1. Cordinate system -* 1.1. Pixel cordinates -* 1.2. 0 - 1 cordinate +* 1.1. Pixel cordinates DONE +* 1.2. 0 - 1 cordinate DONW * 1.3. Origo in middle of the screen ( -1 to 1 ) */ @@ -43,46 +43,6 @@ namespace Input class Win32Input :public InputManager { - // private: - // SubscribeList* _procInput; - // - // bool _enabled; - // bool _mouseEnabled; - // bool _KeyboardEnabled; - // bool _exclusive; - // List _deviceList; - // - // List _mouseInput; - // List _keyboardInput; - // - // HHOOK _msgHook; - // - // private: - // Win32Input (); - // ~Win32Input (); - // - // bool _addDevice (const RAWINPUTDEVICE* k, const int& count); - // RAWINPUT*_TranslateRawInput (LPARAM l); - // void _proccessRawMouseData (RAWMOUSE&); - // void _proccessRawKeyboardData (RAWKEYBOARD&); - // - // static LRESULT CALLBACK WM_INPUT_TRANSLATE (int nCode, WPARAM wParam, LPARAM lParam); - // - // public: - // - // static Win32Input* Self (); - // static void Destroy (); - // - // const wchar_t* Input_GetError () const; - // - // bool Input_AddDevice (IN const HWND& targetApplication); - // bool Input_AddDevice (IN const RAWINPUTDEVICE*, IN const int&); - // - // void Input_Subscribe (IN INPUT_CALLBACK fnc); - // void Input_Unsubscribe (IN INPUT_CALLBACK fnc); - // - // void Input_Disable (); - // void Input_Enable (); public: Win32Input(); virtual~Win32Input(); @@ -96,12 +56,11 @@ namespace Input std::vector mouse; bool enabled; - bool exclusive; HWND targetHwin; private: static Win32Input* instance; - static void RawInputParser(HWND h, LPARAM l); + static LRESULT RawInputParser(HWND h, LPARAM l); static LRESULT CALLBACK RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l); static void WindowActivate(bool activate); }; diff --git a/Code/Misc/Input/Include/Win32/Win32Keyboard.h b/Code/Misc/Input/Include/Win32/Win32Keyboard.h index 8a8638a4..8e9b2e7d 100644 --- a/Code/Misc/Input/Include/Win32/Win32Keyboard.h +++ b/Code/Misc/Input/Include/Win32/Win32Keyboard.h @@ -5,6 +5,7 @@ #define INPUT_KEYBOARD_H #include "..\Keyboard.h" +#define NOMINMAX #include namespace Input @@ -12,24 +13,34 @@ namespace Input class Win32Keyboard :public Keyboard { public: - Win32Keyboard(); + Win32Keyboard(HWND target); ~Win32Keyboard(); bool IsKeyUp (Enum::SAKI key) override; bool IsKeyDown (Enum::SAKI key) override; - const wchar_t* GetAsText(Enum::SAKI key) override; + wchar_t* GetAsText(Enum::SAKI key) override; - void ProccessKeyboardData (bool isUp, Enum::SAKI key, unsigned int makeCode, bool isE0); + public: /* From InputObject */ + void Activate () override; + void Deactivate () override; + inline bool IsActive() override { return this->isActive; } + + void ProccessKeyboardData (RAWKEYBOARD keyboard); + bool Create( ); private: + void MapKey(RAWKEYBOARD& rawKB, Enum::SAKI& out_key, bool& isE0); + struct Keys { bool isE0; bool isDown; unsigned int makecode; }; + RAWINPUTDEVICE device; static const int MAXKEYS = 256; Keys keys[MAXKEYS]; + bool isActive; }; } diff --git a/Code/Misc/Input/Include/Win32/Win32Mouse.h b/Code/Misc/Input/Include/Win32/Win32Mouse.h index 3f1c0f10..d0ecd2ca 100644 --- a/Code/Misc/Input/Include/Win32/Win32Mouse.h +++ b/Code/Misc/Input/Include/Win32/Win32Mouse.h @@ -12,13 +12,22 @@ namespace Input class Win32Mouse :public Mouse { public: - Win32Mouse(); + Win32Mouse(HWND target); ~Win32Mouse(); - bool IsBtnUp(Enum::SAMI key) override; - bool IsBtnDown(Enum::SAMI key) override; + bool IsBtnUp(Enum::SAMI key) const override; + bool IsBtnDown(Enum::SAMI key) const override; + int GetWheelDelta() const override; + Struct::SAIPointInt2D& GetPixelPosition(Struct::SAIPointInt2D &targetMem = Struct::SAIPointInt2D()) const override; + Struct::SAIPointFloat2D& GetNormalizedPosition(Struct::SAIPointFloat2D &targetMem = Struct::SAIPointFloat2D()) override; + Struct::SAIPointFloat2D& GetDeltaPosition(Struct::SAIPointFloat2D& targetMem = Struct::SAIPointFloat2D()) const override; + + void Activate () override; + void Deactivate () override; + inline bool IsActive() override { return this->isActive; } - void ProccessMouseData (bool isDown, Enum::SAMI btn, int delta, Struct::SAIPoint2D velocity, unsigned int makeCode); + void ProccessMouseData (RAWMOUSE mouse); + bool Create( ); private: struct Buttons @@ -26,8 +35,12 @@ namespace Input unsigned int makeCode; bool isDown; }; - static const int MAXBUTTONS = 25; - Buttons buttons[25]; + static const int MAXBUTTONS =Enum::SAMI_Unknown; + Buttons buttons[MAXBUTTONS]; + RAWINPUTDEVICE device; + Struct::SAIPointInt2D windowSize; + bool isActive; + Struct::SAIPointInt2D winCursPos; }; } diff --git a/Code/Misc/Input/Input.vcxproj b/Code/Misc/Input/Input.vcxproj index d930acdb..d8aeb72d 100644 --- a/Code/Misc/Input/Input.vcxproj +++ b/Code/Misc/Input/Input.vcxproj @@ -20,17 +20,14 @@ - - - @@ -38,17 +35,11 @@ - - - - {2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee} - - {7E3990D2-3D94-465C-B58D-64A74B3ECF9B} Input @@ -136,7 +127,7 @@ Level3 Disabled true - $(SolutionDir)Misc\Utilities;%(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) true @@ -149,7 +140,7 @@ true true true - $(SolutionDir)Misc\Utilities;%(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) true @@ -164,7 +155,7 @@ true true true - $(SolutionDir)Misc\Utilities;%(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) true diff --git a/Code/Misc/Input/Main.cpp b/Code/Misc/Input/Main.cpp index 65a468d1..eab968aa 100644 --- a/Code/Misc/Input/Main.cpp +++ b/Code/Misc/Input/Main.cpp @@ -1,101 +1,68 @@ -#include "RawInput.h" -// include the basic windows header file -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Include\Input.h" +#include "WindowShell.h" -HWND hWnd; -// this is the main message handler for the program -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +using namespace std; +using namespace Input; +using namespace Input::Enum; + +Input::Keyboard* keyboard = 0; +Input::Mouse* mouse = 0; + +void KeyPress(Input::Enum::SAKI key, Input::Keyboard* sender) { - // sort through and find what code to run for the message given - switch(message) - { - // this message is read when the window is closed - case WM_DESTROY: - { - // close the application entirely - PostQuitMessage(0); - return 0; - } break; - case WM_KEYUP: - MessageBox(0, L"WM_KEYUP", L"", 0); - break; - case WM_KEYDOWN: - MessageBox(0, L"WM_KEYDOWN", L"", 0); - break; - //case WM_INPUT: - // MessageBox(0, L"WM_INPUT_MAIN", L"", 0); - //break; - } - - // Handle any messages the switch statement didn't - return DefWindowProc (hWnd, message, wParam, lParam); + if(key == SAKI_A) + { + if(mouse->IsActive()) mouse->Deactivate(); + else mouse->Activate(); + + } } -void initWindow(HINSTANCE h, int i) + +void MouseVelocity(Input::Struct::SAIPointInt2D vel, Input::Mouse* sender) { - // this struct holds information for the window class - WNDCLASSEX wc; - - // clear out the window class for use - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - - // fill in the struct with the needed information - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = h; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - - // register the window class - RegisterClassEx(&wc); - - // create the window and use the result as the handle - hWnd = CreateWindowEx(NULL, - L"WindowClass1", // name of the window class - L"Our First Windowed Program", // title of the window - WS_OVERLAPPEDWINDOW, // window style - 300, // x-position of the window - 300, // y-position of the window - 500, // width of the window - 400, // height of the window - NULL, // we have no parent window, NULL - NULL, // we aren't using menus, NULL - h, // application handle - NULL); // used with multiple windows, NULL - - // display the window on the screen - ShowWindow(hWnd, i); + int i = vel.Length(); + if(abs(i) > 2) + i = 0; } -void initRaw() + +int WINAPI WinMain( HINSTANCE hinst, HINSTANCE prevInst, PSTR cmdLine, int cmdShow) { - //RawInput::Self()->Input_AddDevice(hWnd); -} -// the entry point for any Windows program -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - initWindow(hInstance, nCmdShow); - initRaw(); + std::wstring text; + WindowShell::CreateWin(WindowShell::WINDOW_INIT_DESC()); + WindowShell::CreateConsoleWindow(); + keyboard = Input::InputManager::Instance()->CreateKeyboardDevice(WindowShell::GetHWND()); + mouse = Input::InputManager::Instance()->CreateMouseDevice(WindowShell::GetHWND()); - // this struct holds Windows event messages - MSG msg; + mouse->AddOnMouseMoveVelocityCallback(MouseVelocity); + keyboard->BindTextTarget( &text ); + keyboard->AddOnKeyPressCallback(KeyPress); - // wait for the next message in the queue, store the result in 'msg' - while(GetMessage(&msg, NULL, 0, 0)) - { - // translate keystroke messages into the right format - TranslateMessage(&msg); - // send the message to the WindowProc function - DispatchMessage(&msg); + int oldLen = 0; - //RawInput::Self()->Input_Read(); - } + while (WindowShell::Frame()) + { + if(text.length() != oldLen) + { + wprintf(text.c_str()); + oldLen =text.length(); + } + } - RawInput::Destroy(); + system("pause"); - return msg.wParam; + return cmdShow; } \ No newline at end of file diff --git a/Code/Misc/Input/Source/Keyboard.cpp b/Code/Misc/Input/Source/Keyboard.cpp index fa3423d8..a35f75a5 100644 --- a/Code/Misc/Input/Source/Keyboard.cpp +++ b/Code/Misc/Input/Source/Keyboard.cpp @@ -8,11 +8,34 @@ using namespace Input::Enum; using namespace Input::Typedefs; using namespace Input::Struct; - -void Keyboard::ClearList(Keyboard::KeyboardCallbackList* first) +struct Keyboard::KeyboardCallbackList { - KeyboardCallbackList* w = first; - KeyboardCallbackList* removee = 0; + enum CallbackDataType + { + CallbackDataType_OnPress, + CallbackDataType_OnDown, + CallbackDataType_OnRelease + } type; + union CallbackData + { + Typedefs::OnKeyPressCallback keyPressCallback; + Typedefs::OnKeyDownCallback keyDownCallback; + Typedefs::OnKeyReleaseCallback keyReleaseCallback; + + CallbackData (){ memset(this, 0, sizeof(CallbackData)); } + CallbackData (Typedefs::OnKeyPressCallback o){ keyPressCallback = o; } + bool operator ==(CallbackData o){ return o.keyDownCallback == keyDownCallback; } + bool operator ==(Typedefs::OnKeyPressCallback o ){ return o == keyPressCallback; } + operator bool(){ return this->keyDownCallback != 0; } + } function; + KeyboardCallbackList *next; + KeyboardCallbackList(CallbackData func, CallbackDataType t) :function(func), next(0), type(t) { } +}; + +void ClearList(Keyboard::KeyboardCallbackList* first) +{ + Keyboard::KeyboardCallbackList* w = first; + Keyboard::KeyboardCallbackList* removee = 0; while (w) { @@ -21,27 +44,27 @@ void Keyboard::ClearList(Keyboard::KeyboardCallbackList* first) delete removee; } } -void Keyboard::AddToList(Keyboard::KeyboardCallbackList* first, KeyboardCallbackList::CallbackData data, KeyboardCallbackList::CallbackDataType type) +void AddToList(Keyboard::KeyboardCallbackList* first, Keyboard::KeyboardCallbackList::CallbackData data, Keyboard::KeyboardCallbackList::CallbackDataType type) { - KeyboardCallbackList *w = first; - KeyboardCallbackList *prev = first; + Keyboard::KeyboardCallbackList *w = first; + Keyboard::KeyboardCallbackList *prev = first; while (w) { prev = w; w = w->next; } - KeyboardCallbackList::CallbackData f; + Keyboard::KeyboardCallbackList::CallbackData f; f = data; - prev->next = new KeyboardCallbackList(f, type); + prev->next = new Keyboard::KeyboardCallbackList(f, type); } -void Keyboard::RemoveFromList(KeyboardCallbackList* first, KeyboardCallbackList::CallbackData data) +void RemoveFromList(Keyboard::KeyboardCallbackList* first, Keyboard::KeyboardCallbackList::CallbackData data) { - KeyboardCallbackList *w = first; - KeyboardCallbackList *prev = first; + Keyboard::KeyboardCallbackList *w = first; + Keyboard::KeyboardCallbackList *prev = first; while (w) { if(data == w->function) { - KeyboardCallbackList *removee = w; + Keyboard::KeyboardCallbackList *removee = w; w = w->next; prev->next = w; delete removee; @@ -51,9 +74,9 @@ void Keyboard::RemoveFromList(KeyboardCallbackList* first, KeyboardCallbackList: w = w->next; } } -bool Keyboard::ExistsInList(KeyboardCallbackList* first, KeyboardCallbackList::CallbackData data) +bool ExistsInList(Keyboard::KeyboardCallbackList* first, Keyboard::KeyboardCallbackList::CallbackData data) { - KeyboardCallbackList *w = first; + Keyboard::KeyboardCallbackList *w = first; while (w) { if(data == w->function) @@ -64,7 +87,7 @@ bool Keyboard::ExistsInList(KeyboardCallbackList* first, KeyboardCallbackList::C } return true; } -bool Keyboard::ExistsInList(std::vector& list, KeyboardEvent* data) +bool ExistsInList(std::vector& list, Keyboard::KeyboardEvent* data) { for (unsigned int i = 0; i < list.size(); i++) { @@ -74,15 +97,76 @@ bool Keyboard::ExistsInList(std::vector& list, KeyboardEvent* da return false; } + + + Keyboard::Keyboard() : InputObject(SAIType_Keyboard) , callbackList(0) + , active(1) + , textTarget(0) + , writePos(0) {} Keyboard::~Keyboard() { } +void Keyboard::InternalOnKeyPress(Enum::SAKI key) +{ + for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) + { + if(this->keyEventSubscrivers[i]) + { + this->keyEventSubscrivers[i]->OnKeyPress(key, this); + } + } + KeyboardCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == KeyboardCallbackList::CallbackDataType_OnPress) + w->function.keyPressCallback(key, this); + w = w->next; + } +} +void Keyboard::InternalOnKeyDown(Enum::SAKI key) +{ + for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) + { + if(this->keyEventSubscrivers[i]) + { + this->keyEventSubscrivers[i]->OnKeyDown(key, this); + } + } + KeyboardCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == KeyboardCallbackList::CallbackDataType_OnDown) + w->function.keyDownCallback(key, this); + w = w->next; + } +} +void Keyboard::InternalOnKeyRelease(Enum::SAKI key) +{ + for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) + { + if(this->keyEventSubscrivers[i]) + { + this->keyEventSubscrivers[i]->OnKeyRelease(key, this); + } + } + KeyboardCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == KeyboardCallbackList::CallbackDataType_OnRelease) + w->function.keyReleaseCallback(key, this); + w = w->next; + } +} + void Keyboard::AddOnKeyPressCallback (OnKeyPressCallback func) { KeyboardCallbackList::CallbackData d; @@ -134,3 +218,17 @@ void Keyboard::operator-= (KeyboardEvent* object) } } +void Keyboard::BindTextTarget( ::std::wstring *field ) +{ + this->textTarget = field; + + if( field ) + { + this->writePos = field->size(); + } +} +void Keyboard::ReleaseTextTarget( ) +{ + this->BindTextTarget( nullptr ); +} + diff --git a/Code/Misc/Input/Source/Mouse.cpp b/Code/Misc/Input/Source/Mouse.cpp index f0eaba3b..b3cebbc4 100644 --- a/Code/Misc/Input/Source/Mouse.cpp +++ b/Code/Misc/Input/Source/Mouse.cpp @@ -9,11 +9,41 @@ using namespace Input::Enum; using namespace Input::Struct; using namespace Input::Typedefs; - -void Mouse::ClearList(Mouse::MouseCallbackList* first) +struct Mouse::MouseCallbackList { - MouseCallbackList* w = first; - MouseCallbackList* removee = 0; + enum CallbackDataType + { + CallbackDataType_OnPress, + CallbackDataType_OnDown, + CallbackDataType_OnRelease, + CallbackDataType_OnMovePixelPos, + CallbackDataType_OnMoveVelocity, + CallbackDataType_OnScroll, + } type; + union CallbackData + { + Typedefs::OnMousePressCallback mousePressCallback; + Typedefs::OnMouseDownCallback mouseDownCallback; + Typedefs::OnMouseReleaseCallback mouseReleaseCallback; + Typedefs::OnMouseMovePixelPosCallback mouseMovePixelPosCallback; + Typedefs::OnMouseMoveVelocityCallback mouseMoveVelocityCallback; + Typedefs::OnMouseScrollCallback mouseScrollCallback; + void* dummy; + + CallbackData (){ memset(this, 0, sizeof(CallbackData)); } + CallbackData (void* d){ dummy = d; } + bool operator ==(CallbackData o){ return o.dummy == dummy; } + bool operator ==(void* o ){ return o == dummy; } + operator bool(){ return this->dummy != 0; } + } function; + MouseCallbackList *next; + MouseCallbackList(CallbackData func, CallbackDataType t) :function(func), next(0), type(t) { } +}; + +void ClearList(Mouse::MouseCallbackList* first) +{ + Mouse::MouseCallbackList* w = first; + Mouse::MouseCallbackList* removee = 0; while (w) { @@ -22,27 +52,27 @@ void Mouse::ClearList(Mouse::MouseCallbackList* first) delete removee; } } -void Mouse::AddToList(Mouse::MouseCallbackList* first, MouseCallbackList::CallbackData data, MouseCallbackList::CallbackDataType type) +void AddToList(Mouse::MouseCallbackList* first, Mouse::MouseCallbackList::CallbackData data, Mouse::MouseCallbackList::CallbackDataType type) { - MouseCallbackList *w = first; - MouseCallbackList *prev = first; + Mouse::MouseCallbackList *w = first; + Mouse::MouseCallbackList *prev = first; while (w) { prev = w; w = w->next; } - MouseCallbackList::CallbackData f; + Mouse::MouseCallbackList::CallbackData f; f = data; - prev->next = new MouseCallbackList(f, type); + prev->next = new Mouse::MouseCallbackList(f, type); } -void Mouse::RemoveFromList(MouseCallbackList* first, MouseCallbackList::CallbackData data) +void RemoveFromList(Mouse::MouseCallbackList* first, Mouse::MouseCallbackList::CallbackData data) { - MouseCallbackList *w = first; - MouseCallbackList *prev = first; + Mouse::MouseCallbackList *w = first; + Mouse::MouseCallbackList *prev = first; while (w) { if(data == w->function) { - MouseCallbackList *removee = w; + Mouse::MouseCallbackList *removee = w; w = w->next; prev->next = w; delete removee; @@ -52,9 +82,9 @@ void Mouse::RemoveFromList(MouseCallbackList* first, MouseCallbackList::Callback w = w->next; } } -bool Mouse::ExistsInList(MouseCallbackList* first, MouseCallbackList::CallbackData data) +bool ExistsInList(Mouse::MouseCallbackList* first, Mouse::MouseCallbackList::CallbackData data) { - MouseCallbackList *w = first; + Mouse::MouseCallbackList *w = first; while (w) { if(data == w->function) @@ -65,7 +95,7 @@ bool Mouse::ExistsInList(MouseCallbackList* first, MouseCallbackList::CallbackDa } return true; } -bool Mouse::ExistsInList(std::vector& list, MouseEvent* data) +bool ExistsInList(std::vector& list, Mouse::MouseEvent* data) { for (unsigned int i = 0; i < list.size(); i++) { @@ -89,38 +119,107 @@ Mouse::~Mouse() } -int Mouse::GetWheelDelta() const +void Mouse::InternalOnBtnPress(Enum::SAMI btn) { - return this->wheelDelta; + for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) + { + if(this->mouseSubscribers[i]) + this->mouseSubscribers[i]->OnMousePress(btn, this); + } + MouseCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == MouseCallbackList::CallbackDataType_OnPress) + w->function.mousePressCallback(btn, this); + w = w->next; + } +} +void Mouse::InternalOnBtnDown(Enum::SAMI btn) +{ + for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) + { + if(this->mouseSubscribers[i]) + this->mouseSubscribers[i]->OnMouseDown(btn, this); + } + MouseCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == MouseCallbackList::CallbackDataType_OnDown) + w->function.mouseDownCallback(btn, this); + w = w->next; + } +} +void Mouse::InternalOnBtnRelease(Enum::SAMI btn) +{ + for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) + { + if(this->mouseSubscribers[i]) + this->mouseSubscribers[i]->OnMouseRelease(btn, this); + } + MouseCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == MouseCallbackList::CallbackDataType_OnRelease) + w->function.mouseReleaseCallback(btn, this); + w = w->next; + } +} +void Mouse::InternalOnMove(Struct::SAIPointInt2D pixelPos, Struct::SAIPointInt2D velocity) +{ + for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) + { + if(this->mouseSubscribers[i]) + { + this->mouseSubscribers[i]->OnMouseMovePixelPos(pixelPos, this); + this->mouseSubscribers[i]->OnMouseMoveVelocity(velocity, this); + } + } + MouseCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == MouseCallbackList::CallbackDataType_OnMovePixelPos) + w->function.mouseMovePixelPosCallback(pixelPos, this); + else if (w->type == MouseCallbackList::CallbackDataType_OnMoveVelocity) + w->function.mouseMoveVelocityCallback(velocity, this); + w = w->next; + } +} +void Mouse::InternalOnScroll(int delta) +{ + for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) + { + if(this->mouseSubscribers[i]) + this->mouseSubscribers[i]->OnMouseScroll(delta, this); + } + MouseCallbackList *w = this->callbackList; + while (w) + { + if(w->function) + if (w->type == MouseCallbackList::CallbackDataType_OnScroll) + w->function.mouseScrollCallback(delta, this); + w = w->next; + } } -SAIPoint2D & Mouse::GetPixelPosition( Struct::SAIPoint2D &targetMem ) const -{ - targetMem.x = this->pixelPos.x; - targetMem.y = this->pixelPos.y; - return targetMem; -} -SAIPoint2D & Mouse::GetDeltaPosition( Struct::SAIPoint2D &targetMem ) const -{ - targetMem.x = this->deltaPos.x; - targetMem.y = this->deltaPos.y; - return targetMem; -} void Mouse::AddOnMousePressCallback( Typedefs::OnMousePressCallback func) { MouseCallbackList::CallbackData d; d.mousePressCallback = func; - if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); - else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); + if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnPress); + else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnPress); } void Mouse::AddOnMouseDownCallback( Typedefs::OnMouseDownCallback func ) { MouseCallbackList::CallbackData d; d.mouseDownCallback = func; - if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); - else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); + if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnDown); + else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnDown); } void Mouse::AddOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func ) { @@ -129,19 +228,26 @@ void Mouse::AddOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func ) if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); } -void Mouse::AddOnMouseMoveCallback( Typedefs::OnMouseMoveCallback func ) +void Mouse::AddOnMouseMovePixelPosCallback( Typedefs::OnMouseMovePixelPosCallback func ) { MouseCallbackList::CallbackData d; - d.mouseMoveCallback = func; - if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); - else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); + d.mouseMovePixelPosCallback = func; + if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnMovePixelPos); + else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnMovePixelPos); +} +void Mouse::AddOnMouseMoveVelocityCallback( Typedefs::OnMouseMoveVelocityCallback func ) +{ + MouseCallbackList::CallbackData d; + d.mouseMoveVelocityCallback = func; + if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnMoveVelocity); + else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnMoveVelocity); } void Mouse::AddOnMouseScrollCallback( Typedefs::OnMouseScrollCallback func ) { MouseCallbackList::CallbackData d; d.mouseScrollCallback = func; - if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); - else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); + if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnScroll); + else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnScroll); } void Mouse::RemoveOnMousePressCallback( Typedefs::OnMousePressCallback func) @@ -156,7 +262,11 @@ void Mouse::RemoveOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func { RemoveFromList(this->callbackList, func); } -void Mouse::RemoveOnMouseMoveCallback( Typedefs::OnMouseMoveCallback func ) +void Mouse::RemoveOnMouseMovePixelPosCallback( Typedefs::OnMouseMovePixelPosCallback func ) +{ + RemoveFromList(this->callbackList, func); +} +void Mouse::RemoveOnMouseMoveVelocityCallback( Typedefs::OnMouseMoveVelocityCallback func ) { RemoveFromList(this->callbackList, func); } diff --git a/Code/Misc/Input/Source/Win32/Win32Input.cpp b/Code/Misc/Input/Source/Win32/Win32Input.cpp index 28032070..30ebf7ab 100644 --- a/Code/Misc/Input/Source/Win32/Win32Input.cpp +++ b/Code/Misc/Input/Source/Win32/Win32Input.cpp @@ -16,608 +16,17 @@ using namespace Input::Enum; using namespace Input::Struct; using namespace Input::Typedefs; -/* -bool Win32Input::Input_AddDevice(IN const HWND& targetApplication) -{ - assert(targetApplication != 0); - static const UINT c = 2; - RAWINPUTDEVICE devices[c] = - { - { 0x01, RawInput_Usage_keyboard, RIDEV_NOLEGACY, targetApplication }, - { 0x01, RawInput_Usage_mouse, RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE, targetApplication } - }; - - if(! _addDevice( devices , c ) ) return false; - - ShowCursor(FALSE); - //RECT r; - //GetWindow - //GetWindowRect( - - return true; -} -bool Win32Input::Input_AddDevice(IN const RAWINPUTDEVICE* d, const int& count) -{ - for (int i = 0; i < count; i++) - if(!d[i].hwndTarget) - { - this->_errorMsg = L"Must specify target application"; - return false; - } - if(! _addDevice( d, count ) ) return false; - - return true; -} - -//Win32InputDEVICE d = { 0x01, type, RIDEV_REMOVE, NULL }; -//this->_errorMsg = L"Failed to unregister device"; - - -void Win32Input::Input_Disable() -{ - this->_enabled = false; -} -void Win32Input::Input_Enable() -{ - this->_enabled = true; -} - -void Win32Input::Input_Read() -{ - //for (int i = 0; i < this->_idleKeyData.size(); i++) - // this->_proccessRawKeyboardData(this->_idleKeyData.pop()); - //for (int i = 0; i < this->_idleMouseData.size(); i++) - // this->_proccessRawMouseData(this->_idleMouseData.pop()); - // - //this->_idleKeyData.clear(); - //this->_idleMouseData.clear(); -} - - -bool Win32Input::_addDevice (const RAWINPUTDEVICE* k, const int& count) -{ - if(RegisterRawInputDevices(k, count, sizeof(RAWINPUTDEVICE)) == FALSE) - { - DWORD h = GetLastError(); - INPUT_EXCEPT( L"Failed to register device" ); - return false; - } - - for (int q = 0; q < count; q++) - { - RawInputDeviceInstance i; - memcpy(&i.description, &k[q], sizeof(RAWINPUTDEVICE)); - this->_deviceList.push(i); - } - - return true; -} -*/ - Win32Input *Win32Input::instance = 0; -void MapKey(RAWKEYBOARD& rawKB, bool& out_isUp, SAKI& out_key, unsigned int& sCode, bool& isE0) -{ - //------------------------------------------------------------------------------------// - // http://molecularmusings.wordpress.com/2011/09/05/properly-handling-keyboard-input/ // - //------------------------------------------------------------------------------------// - - UINT virtualKey = rawKB.VKey; - UINT scanCode = rawKB.MakeCode; - UINT flags = rawKB.Flags; - - if (virtualKey == 255) - { - // discard "fake keys" which are part of an escaped sequence - return; - } - else if (virtualKey == VK_SHIFT) - { - // correct left-hand / right-hand SHIFT - virtualKey = MapVirtualKey(scanCode, MAPVK_VSC_TO_VK_EX); - } - else if (virtualKey == VK_NUMLOCK) - { - // correct PAUSE/BREAK and NUM LOCK silliness, and set the extended bit - scanCode = (MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC) | 0x100); - } - - // e0 and e1 are escape sequences used for certain special keys, such as PRINT and PAUSE/BREAK. - // see http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html - isE0 = ((flags & RI_KEY_E0) != 0); - const bool isE1 = ((flags & RI_KEY_E1) != 0); - - if (isE1) - { - // for escaped sequences, turn the virtual key into the correct scan code using MapVirtualKey. - // however, MapVirtualKey is unable to map VK_PAUSE (this is a known bug), hence we map that by hand. - if (virtualKey == VK_PAUSE) scanCode = 0x45; - else scanCode = MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC); - } - - switch (virtualKey) - { - // right-hand CONTROL and ALT have their e0 bit set - case VK_CONTROL: - if (isE0) out_key = SAKI_RightCtrl; - else out_key = SAKI_LeftCtrl; - break; - - case VK_MENU: - if (isE0) out_key = SAKI_RightAlt; - else out_key = SAKI_LeftAlt; - break; - - // NUMPAD ENTER has its e0 bit set - case VK_RETURN: - if (isE0) out_key = SAKI_NumpadEnter; - break; - - // the standard INSERT, DELETE, HOME, END, PRIOR and NEXT keys will always have their e0 bit set, but the - // corresponding keys on the NUMPAD will not. - case VK_INSERT: - if (!isE0) out_key = SAKI_Numpad0; - break; - - case VK_DELETE: - if (!isE0) out_key = SAKI_NumpadDecimal; - break; - - case VK_HOME: - if (!isE0) out_key = SAKI_Numpad7; - break; - - case VK_END: - if (!isE0) out_key = SAKI_Numpad1; - break; - - case VK_PRIOR: - if (!isE0) out_key = SAKI_Numpad9; - break; - - case VK_NEXT: - if (!isE0) out_key = SAKI_Numpad3; - break; - - // the standard arrow keys will always have their e0 bit set, but the - // corresponding keys on the NUMPAD will not. - case VK_LEFT: - if (!isE0) out_key = SAKI_Numpad4; - break; - - case VK_RIGHT: - if (!isE0) out_key = SAKI_Numpad6; - break; - - case VK_UP: - if (!isE0) out_key = SAKI_Numpad8; - break; - - case VK_DOWN: - if (!isE0) out_key = SAKI_Numpad2; - break; - - // NUMPAD 5 doesn't have its e0 bit set - case VK_CLEAR: - if (!isE0) out_key = SAKI_Numpad5; - break; - case 0x03 : //VK_CANCEL - break; - case 0x08 : //VK_BACK - out_key = SAKI_Backspace; - break; - case 0x09 : //VK_TAB - out_key = SAKI_Tab; - break; - case 0x10 : //VK_SHIFT - out_key = SAKI_LeftShift; - out_key = SAKI_RightShift; - break; - case 0x13 : //VK_PAUSE - out_key = SAKI_Pause; - break; - case 0x14 : //VK_CAPITAL - out_key = SAKI_CapsLock; - break; - case 0x15 : //VK_KANA - break; - case 0x1B : //VK_ESCAPE - out_key = SAKI_Escape; - break; - case 0x1C : //VK_CONVERT - break; - case 0x1D : //VK_NONCONVERT - break; - case 0x1E : //VK_ACCEPT - break; - case 0x1F : //VK_MODECHANGE - break; - case 0x20 : //VK_SPACE - out_key = SAKI_Space; - break; - case 0x29 : //VK_SELECT - break; - case 0x2A : //VK_PRINT - out_key = SAKI_PrintScreen; - break; - case 0x2B : //VK_EXECUTE - break; - case 0x2C : //VK_SNAPSHOT - break; - case 0x2F : //VK_HELP - break; - case 0x30 : //0 key - out_key = SAKI_0; - break; - case 0x31 : //1 key - out_key = SAKI_1; - break; - case 0x32 : //2 key - out_key = SAKI_2; - break; - case 0x33 : //3 key - out_key = SAKI_3; - break; - case 0x34 : //4 key - out_key = SAKI_4; - break; - case 0x35 : //5 key - out_key = SAKI_5; - break; - case 0x36 : //6 key - out_key = SAKI_6; - break; - case 0x37 : //7 key - out_key = SAKI_7; - break; - case 0x38 : //8 key - out_key = SAKI_8; - break; - case 0x39 : //9 key - out_key = SAKI_9; - break; - case 0x41 : //A key - out_key = SAKI_A; - break; - case 0x42 : //B key - out_key = SAKI_B; - break; - case 0x43 : //C key - out_key = SAKI_C; - break; - case 0x44 : //D key - out_key = SAKI_D; - break; - case 0x45 : //E key - out_key = SAKI_E; - break; - case 0x46 : //F key - out_key = SAKI_F; - break; - case 0x47 : //G key - out_key = SAKI_G; - break; - case 0x48 : //H key - out_key = SAKI_H; - break; - case 0x49 : //I key - out_key = SAKI_I; - break; - case 0x4A : //J key - out_key = SAKI_J; - break; - case 0x4B : //K key - out_key = SAKI_K; - break; - case 0x4C : //L key - out_key = SAKI_L; - break; - case 0x4D : //M key - out_key = SAKI_M; - break; - case 0x4E : //N key - out_key = SAKI_N; - break; - case 0x4F : //O key - out_key = SAKI_O; - break; - case 0x50 : //P key - out_key = SAKI_P; - break; - case 0x51 : //Q key - out_key = SAKI_Q; - break; - case 0x52 : //R key - out_key = SAKI_R; - break; - case 0x53 : //S key - out_key = SAKI_S; - break; - case 0x54 : //T key - out_key = SAKI_T; - break; - case 0x55 : //U key - out_key = SAKI_U; - break; - case 0x56 : //V key - out_key = SAKI_V; - break; - case 0x57 : //W key - out_key = SAKI_W; - break; - case 0x58 : //X key - out_key = SAKI_X; - break; - case 0x59 : //Y key - out_key = SAKI_Y; - break; - case 0x5A : //Z key - out_key = SAKI_Z; - break; - case 0x5B : //VK_LWIN - break; - case 0x5C : //VK_RWIN - break; - case 0x5D : //VK_APPS - break; - case 0x5F : //VK_SLEEP - break; - case 0x60 : //VK_NUMPAD0 - out_key = SAKI_Numpad0; - break; - case 0x61 : //VK_NUMPAD1 - out_key = SAKI_Numpad1; - break; - case 0x62 : //VK_NUMPAD2 - out_key = SAKI_Numpad2; - break; - case 0x63 : //VK_NUMPAD3 - out_key = SAKI_Numpad3; - break; - case 0x64 : //VK_NUMPAD4 - out_key = SAKI_Numpad4; - break; - case 0x65 : //VK_NUMPAD5 - out_key = SAKI_Numpad5; - break; - case 0x66 : //VK_NUMPAD6 - out_key = SAKI_Numpad6; - break; - case 0x67 : //VK_NUMPAD7 - out_key = SAKI_Numpad7; - break; - case 0x68 : //VK_NUMPAD8 - out_key = SAKI_Numpad8; - break; - case 0x69 : //VK_NUMPAD9 - out_key = SAKI_Numpad9; - break; - case 0x6A : //VK_MULTIPLY - out_key = SAKI_NumpadMultiply; - break; - case 0x6B : //VK_ADD - out_key = SAKI_NumpadPlus; - break; - case 0x6C : //VK_SEPARATOR - break; - case 0x6D : //VK_SUBTRACT - out_key = SAKI_NumpadSubtract; - break; - case 0x6E : //VK_DECIMAL - out_key = SAKI_NumpadDecimal; - break; - case 0x6F : //VK_DIVIDE - out_key = SAKI_NumpadDivide; - break; - case 0x70 : //VK_F1 - out_key = SAKI_F1; - break; - case 0x71 : //VK_F2 - out_key = SAKI_F2; - break; - case 0x72 : //VK_F3 - out_key = SAKI_F3; - break; - case 0x73 : //VK_F4 - out_key = SAKI_F4; - break; - case 0x74 : //VK_F5 - out_key = SAKI_F5; - break; - case 0x75 : //VK_F6 - out_key = SAKI_F6; - break; - case 0x76 : //VK_F7 - out_key = SAKI_F7; - break; - case 0x77 : //VK_F8 - out_key = SAKI_F8; - break; - case 0x78 : //VK_F9 - out_key = SAKI_F9; - break; - case 0x79 : //VK_F10 - out_key = SAKI_F10; - break; - case 0x7A : //VK_F11 - out_key = SAKI_F11; - break; - case 0x7B : //VK_F12 - out_key = SAKI_F12; - break; - case 0x7C : //VK_F13 - out_key = SAKI_F13; - break; - case 0x7D : //VK_F14 - out_key = SAKI_F14; - break; - case 0x7E : //VK_F15 - out_key = SAKI_F15; - break; - case 0x7F : //VK_F16 - out_key = SAKI_F16; - break; - case 0x80 : //VK_F17 - out_key = SAKI_F17; - break; - case 0x81 : //VK_F18 - out_key = SAKI_F18; - break; - case 0x82 : //VK_F19 - out_key = SAKI_F19; - break; - case 0x83 : //VK_F20 - out_key = SAKI_F20; - break; - case 0x84 : //VK_F21 - out_key = SAKI_F21; - break; - case 0x85 : //VK_F22 - out_key = SAKI_F22; - break; - case 0x86 : //VK_F23 - out_key = SAKI_F23; - break; - case 0x87 : //VK_F24 - out_key = SAKI_F24; - break; - case 0x90 : //VK_NUMLOCK - out_key = SAKI_Numlock; - break; - case 0x91 : //VK_SCROLL - out_key = SAKI_ScrlLock; - break; - case 0xA0 : //VK_LSHIFT - out_key = SAKI_LeftShift; - break; - case 0xA1 : //VK_RSHIFT - out_key = SAKI_RightShift; - break; - case 0xA2 : //VK_LCONTROL - out_key = SAKI_LeftCtrl; - break; - case 0xA3 : //VK_RCONTROL - out_key = SAKI_RightCtrl; - break; - case 0xA4 : //VK_LMENU - out_key = SAKI_LeftAlt; - break; - case 0xA5 : //VK_RMENU - out_key = SAKI_RightCtrl; - break; - case 0xAD : //VK_VOLUME_MUTE - out_key = SAKI_VolumeMute; - break; - case 0xAE : //VK_VOLUME_DOWN - out_key = SAKI_VolumeDown; - break; - case 0xAF : //VK_VOLUME_UP - out_key = SAKI_VolumeUp; - break; - case 0xB0 : //VK_MEDIA_NEXT_TRACK - out_key = SAKI_MediaNext; - break; - case 0xB1 : //VK_MEDIA_PREV_TRACK - out_key = SAKI_MediaPrev; - break; - case 0xB2 : //VK_MEDIA_STOP - out_key = SAKI_MediaStop; - break; - case 0xB3 : //VK_MEDIA_PLAY_PAUSE - out_key = SAKI_MediaPlayPause; - break; - - case 0xBB://VK_OEM_PLUS - break; - case 0xBC://VK_OEM_COMMA - break; - case 0xBD://VK_OEM_MINUS - break; - case 0xBE://VK_OEM_PERIOD - break; - case 0xBA://VK_OEM_1 - break; - case 0xBF://VK_OEM_2 - break; - case 0xC0://VK_OEM_3 - break; - case 0xDB://VK_OEM_4 - break; - case 0xDC://VK_OEM_5 - break; - case 0xDD://VK_OEM_6 - break; - case 0xDE://VK_OEM_7 - break; - case 0xDF://VK_OEM_8 - break; - } - - out_isUp = ((flags & RI_KEY_BREAK) != 0); - rawKB.MakeCode = scanCode; - sCode = scanCode; -} -void MapButton(RAWMOUSE& rawMouse, bool &isUp, Enum::SAMI& btn, int& delta, Struct::SAIPoint2D& vel, unsigned int& mcode) -{ - if(rawMouse.lLastX != 0 || rawMouse.lLastY != 0) - { - vel.x = rawMouse.lLastX; - vel.y = rawMouse.lLastY; - } - if( rawMouse.usButtonFlags > 0 ) - { -//-------------------------------------------------------------------------------------- - //Mouse button pressed - if(rawMouse.usButtonFlags == RI_MOUSE_LEFT_BUTTON_DOWN) - { - btn = SAMI_MouseLeftBtn; - isUp = false; - } - else if(rawMouse.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_DOWN) - { - btn = SAMI_MouseMiddleBtn; - isUp = false; - } - else if(rawMouse.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_DOWN) - { - btn = SAMI_MouseRightBtn; - isUp = false; - } -//-------------------------------------------------------------------------------------- - //Mouse button Released - else if(rawMouse.usButtonFlags == RI_MOUSE_LEFT_BUTTON_UP) - { - btn = SAMI_MouseLeftBtn; - isUp = true; - } - else if(rawMouse.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_UP) - { - btn = SAMI_MouseMiddleBtn; - isUp = true; - } - else if(rawMouse.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_UP) - { - btn = SAMI_MouseRightBtn; - isUp = true; - } -//-------------------------------------------------------------------------------------- - else if (rawMouse.usButtonFlags == RI_MOUSE_WHEEL) - { - delta = ((int)rawMouse.usButtonData); - - if(delta > 120) delta = -1; - else delta = 1; - } - } -} -void Win32Input::RawInputParser(HWND h, LPARAM l) +TRACKMOUSEEVENT tme; + +LRESULT Win32Input::RawInputParser(HWND h, LPARAM l) { + LRESULT val = 0; //Get The size of the raw data buffer UINT bufferSize; GetRawInputData((HRAWINPUT)l, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER)); if (bufferSize < 1) - { - return; - } + { return 0; } //Create and read the raw input data LPBYTE rawBufferIn = new BYTE[bufferSize]; @@ -625,63 +34,78 @@ void Win32Input::RawInputParser(HWND h, LPARAM l) if ( readBytes != bufferSize ) { delete [] rawBufferIn; - return; + return 0; } RAWINPUT* raw = (RAWINPUT*)rawBufferIn; - if(!Win32Input::instance->enabled) { - if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) ) - { - - } + val = DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)); } else { if(raw->header.dwType == RIM_TYPEMOUSE) { + bool once = false; for (unsigned int i = 0; i < Win32Input::instance->mouse.size(); i++) { - bool isUp = true; - Enum::SAMI btn = Enum::SAMI_Unknown; - int delta = 0; - Struct::SAIPoint2D vel; - unsigned int mcode = 0; - MapButton(raw->data.mouse, isUp, btn, delta, vel, mcode); - - Win32Input::instance->mouse[i]->ProccessMouseData(isUp, btn, delta, vel, mcode); + if(Win32Input::instance->mouse[i]->IsActive()) + { + Win32Input::instance->mouse[i]->ProccessMouseData(raw->data.mouse); + } + else + { + if(!once) val = DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)); + } } } else if(raw->header.dwType == RIM_TYPEKEYBOARD) { + bool once = false; for (unsigned int i = 0; i < Win32Input::instance->keyboard.size(); i++) { - bool isUp; - SAKI key = SAKI_Unknown; - unsigned int makeCode; - bool isE0; - MapKey(raw->data.keyboard, isUp, key, makeCode, isE0); - Win32Input::instance->keyboard[i]->ProccessKeyboardData(isUp, key, makeCode, isE0); + if(Win32Input::instance->keyboard[i]->IsActive()) + { + Win32Input::instance->keyboard[i]->ProccessKeyboardData(raw->data.keyboard); + } + else + { + if(!once) val = DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)); + } } } } delete raw; + return val; } LRESULT CALLBACK Win32Input::RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l) { + LRESULT val = 0; switch (m) { case WM_INPUT: - Win32Input::instance->RawInputParser(h, l); + return Win32Input::instance->RawInputParser(h, l); break; + case WM_ACTIVATE: Win32Input::instance->WindowActivate((w == TRUE)); break; case WM_CREATE: Win32Input::instance->WindowActivate(true); + //tme.cbSize=sizeof(tme); + //tme.dwFlags=TME_HOVER; + //tme.hwndTrack=h;//hanlde of window you want the mouse over message for. + //tme.dwHoverTime=HOVER_DEFAULT; + //if(TrackMouseEvent(&tme) == FALSE) + //{ } + break; + case WM_MOUSEHOVER: + //val = 0; + break; + case WM_MOUSELEAVE: + //val = 0; break; } @@ -689,19 +113,20 @@ LRESULT CALLBACK Win32Input::RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM } void Win32Input::WindowActivate(bool activate) { - if(activate) - { - ShowCursor(0); - } - else - { - ShowCursor(0); - } + //if(activate) + //{ + // ShowCursor(0); + //} + //else + //{ + // ShowCursor(1); + //} } Win32Input::Win32Input() { + this->targetHwin = 0; if(!this->instance) { this->instance = this; @@ -730,62 +155,72 @@ InputObject* Win32Input::CreateDevice(const SAIType inputType, Typedefs::WindowH { if(!this->instance->targetHwin) { - this->targetHwin = CreateWindowExW( 0, L"RawInputCallbackFunc" , NULL, NULL, NULL, NULL, NULL, - NULL, (HWND)targetApplication, NULL, (HINSTANCE)GetModuleHandle(0), NULL ); + RECT rc; + GetClientRect((HWND)targetApplication, &rc); + + AdjustWindowRect(&rc, GetWindowStyle((HWND)targetApplication), FALSE); + + rc.right = rc.right - rc.left; + rc.bottom = rc.bottom - rc.top; + + this->targetHwin = CreateWindowExW( 0, L"RawInputCallbackFunc" , NULL, NULL, rc.left, rc.top, rc.right, rc.bottom, + (HWND)targetApplication, NULL, (HINSTANCE)GetModuleHandle(0), NULL ); } + InputObject* val = 0; - RAWINPUTDEVICE rid; - rid.usUsagePage = 0x01; - rid.hwndTarget = this->instance->targetHwin; switch (inputType) { case SAIType_Keyboard: { - rid.usUsage = RawInput_Usage_keyboard; - rid.dwFlags = RIDEV_NOLEGACY; - if(RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == TRUE) - { - Win32Keyboard* obj = new Win32Keyboard(); - this->keyboard.push_back(obj); - val = obj; - } - else + Win32Keyboard* obj = new Win32Keyboard(this->targetHwin); + if(!obj->Create()) { + delete obj; return 0; } + + this->keyboard.push_back(obj); + val = obj; } break; case SAIType_Mouse: { - rid.usUsage = RawInput_Usage_mouse; - rid.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE; - if(RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == TRUE) - { - int i = 0; - val = (InputObject*)1; - Win32Mouse* obj = new Win32Mouse(); - this->mouse.push_back(obj); - val = obj; - } - else + Win32Mouse* obj = new Win32Mouse(this->targetHwin); + if(!obj->Create()) { + delete obj; return 0; } + + this->mouse.push_back(obj); + val = obj; } break; - - case SAIType_ApplicationKeyboard: - val = new Win32ApplicationKeyboard(); - break; } return val; } + void Win32Input::ToggleInputSystem(bool enable) { this->enabled = enable; + + if(this->enabled) + { + for (unsigned int i = 0; i < this->mouse.size(); i++) + { this->mouse[i]->Deactivate(); } + for (unsigned int i = 0; i < this->keyboard.size(); i++) + { this->keyboard[i]->Deactivate(); } + } + else + { + for (unsigned int i = 0; i < this->mouse.size(); i++) + { this->mouse[i]->Activate(); } + for (unsigned int i = 0; i < this->keyboard.size(); i++) + { this->keyboard[i]->Activate(); } + } } void Win32Input::Destroy () { @@ -806,52 +241,3 @@ void Win32Input::Destroy () this->keyboard.resize(0); } - -/* This method is used with hooks! - -LRESULT CALLBACK RawInput::WM_INPUT_TRANSLATE (int nCode, WPARAM wParam, LPARAM lparam) -{ - if (nCode < 0) return CallNextHookEx(RawInput::Self()->_msgHook, nCode, wParam, lparam); - - - MSG *m = (MSG*)lparam; - - if(m->message == WM_INPUT) - { - RAWINPUT* raw = RawInput::Self()->_TranslateRawInput(m->lParam); - - if(!raw) goto nextHook; - if(!RawInput::Self()->Self()->_enabled) - { - if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) ) - RawInput::Self()->_errorMsg = L"Failed to proccess default raw input"; - goto _final; - } - // if(raw->header.dwType == RIM_TYPEMOUSE) RawInput::Self()->_idleMouseData.insert(raw->data.mouse); - //else if(raw->header.dwType == RIM_TYPEKEYBOARD) RawInput::Self()->_proccessRawKeyboardData(raw->data.keyboard); - - - _final: - - //if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) ) - // RawInput::Self()->_errorMsg = L"Failed to proccess default raw input"; - - delete raw; - } - else if (m->message == WM_QUIT) - { - if(UnhookWindowsHookEx(RawInput::Self()->_msgHook) == FALSE) - { - RawInput::Self()->_errorMsg = L"Failed to unhook message hook!"; - } - } - - - nextHook: - return CallNextHookEx(RawInput::Self()->_msgHook, nCode, wParam, lparam); -} -*/ - - - - diff --git a/Code/Misc/Input/Source/Win32/Win32Keyboard.cpp b/Code/Misc/Input/Source/Win32/Win32Keyboard.cpp index 771f4134..475a9e85 100644 --- a/Code/Misc/Input/Source/Win32/Win32Keyboard.cpp +++ b/Code/Misc/Input/Source/Win32/Win32Keyboard.cpp @@ -1,14 +1,22 @@ ///////////////////////////////////////////////////////////////////// // Created by [Dennis Andersen] [2013] ///////////////////////////////////////////////////////////////////// -#include "..\..\Include\Win32\Win32Keyboard.h" +#include "..\..\Include\Win32\Win32Input.h" +#include #pragma warning ( disable : 4172 ) using namespace Input; using namespace Input::Enum; +using namespace std; -Win32Keyboard::Win32Keyboard() + +Win32Keyboard::Win32Keyboard(HWND target) { + this->isActive = false; + this->device.usUsagePage = 0x01; + this->device.hwndTarget = target; + this->device.usUsage = RawInput_Usage_keyboard; + this->device.dwFlags = RIDEV_NOLEGACY; memset(&this->keys[0], 0, sizeof(Win32Keyboard::Keys) * MAXKEYS); } Win32Keyboard::~Win32Keyboard() @@ -24,115 +32,680 @@ bool Win32Keyboard::IsKeyDown (SAKI key) { return this->keys[key].isDown; } -const wchar_t* Win32Keyboard::GetAsText(Enum::SAKI key) +wchar_t* Win32Keyboard::GetAsText(Enum::SAKI key) { if(Enum::SAKI_Unknown == key) return 0; // getting a human-readable string UINT temp = (this->keys[key].makecode << 16) | (this->keys[key].isE0 << 24); - wchar_t buff[56] = {0}; - GetKeyNameTextW((LONG)temp, buff, 64); + wchar_t buff[16] = {0}; + GetKeyNameTextW((LONG)temp, buff, 16); return buff; } -void Win32Keyboard::ProccessKeyboardData (bool isUp, SAKI key, unsigned int makeCode, bool isE0) + +void Win32Keyboard::Activate () { - if(key == SAKI_Unknown) return; - //The key is released. - if(isUp)/*(k.Flags == RI_KEY_BREAK || k.Flags == (RI_KEY_BREAK | RI_KEY_E0) || k.Flags == (RI_KEY_BREAK | RI_KEY_E1))*/ + if(this->isActive) return; + + this->Create(); +} +void Win32Keyboard::Deactivate () +{ + if(!this->isActive) return; + + RAWINPUTDEVICE d; + d.dwFlags = RIDEV_REMOVE; + d.hwndTarget = 0; + d.usUsage = RawInput_Usage_keyboard; + d.usUsagePage = 0x01; + if(RegisterRawInputDevices(&d, 1, sizeof(RAWINPUTDEVICE))) { - if(key == SAKI_LeftAlt) - { } - else if(key == SAKI_LeftCtrl) - {} - else if(key == SAKI_LeftShift) - {} - else if(key == SAKI_RightAlt) - {} - else if(key == SAKI_RightCtrl) - {} - else if(key == SAKI_RightShift) - {} - else + this->isActive = true; + } +} + +void Win32Keyboard::ProccessKeyboardData (RAWKEYBOARD keyboard) +{ + if(!this->active) + { + return; + } + + bool isUp = (( keyboard.Flags & RI_KEY_BREAK) != 0); + SAKI key = SAKI_Unknown; + bool isE0; + + MapKey(keyboard, key, isE0); + + if(key != SAKI_Unknown) + { + //The key is released. + if(isUp)/*(k.Flags == RI_KEY_BREAK || k.Flags == (RI_KEY_BREAK | RI_KEY_E0) || k.Flags == (RI_KEY_BREAK | RI_KEY_E1))*/ { + InternalOnKeyRelease(key); this->keys[key].isDown = false; this->keys[key].isE0 = isE0; - this->keys[key].makecode = makeCode; - for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) - { - if(this->keyEventSubscrivers[i]) - { - this->keyEventSubscrivers[i]->OnKeyRelease(key, GetAsText(key), this); - } - } - KeyboardCallbackList *w = this->callbackList; - while (w) - { - if(w->function) - if (w->type == KeyboardCallbackList::CallbackDataType_OnRelease) - w->function.keyReleaseCallback(key, GetAsText(key), this); - w = w->next; - } + this->keys[key].makecode = keyboard.MakeCode; } - - //this->_procCollection.kd.key = (RIK)k.VKey; - //this->_procCollection.kd.released = true; - } - //The key is pressed. - else /*if (k.Flags == RI_KEY_MAKE || k.Flags == (RI_KEY_MAKE | RI_KEY_E0) || k.Flags == (RI_KEY_MAKE | RI_KEY_E1))*/ - { - if(key == SAKI_LeftAlt) - {} - else if(key == SAKI_LeftCtrl) - {} - else if(key == SAKI_LeftShift) - {} - else if(key == SAKI_RightAlt) - {} - else if(key == SAKI_RightCtrl) - {} - else if(key == SAKI_RightShift) - {} - else + //The key is pressed. + else /*if (k.Flags == RI_KEY_MAKE || k.Flags == (RI_KEY_MAKE | RI_KEY_E0) || k.Flags == (RI_KEY_MAKE | RI_KEY_E1))*/ { if(this->keys[key].isDown) { - for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) - { - if(this->keyEventSubscrivers[i]) - { - this->keyEventSubscrivers[i]->OnKeyDown(key, GetAsText(key), this); - } - } - KeyboardCallbackList *w = this->callbackList; - while (w) - { - if(w->function) - if (w->type == KeyboardCallbackList::CallbackDataType_OnDown) - w->function.keyDownCallback(key, GetAsText(key), this); - w = w->next; - } + this->InternalOnKeyDown(key); } else { + this->InternalOnKeyPress(key); this->keys[key].isDown = true; this->keys[key].isE0 = isE0; - this->keys[key].makecode = makeCode; - for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) - { - if(this->keyEventSubscrivers[i]) - { - this->keyEventSubscrivers[i]->OnKeyPress(key, GetAsText(key), this); - } - } - KeyboardCallbackList *w = this->callbackList; - while (w) - { - if(w->function) - if (w->type == KeyboardCallbackList::CallbackDataType_OnPress) - w->function.keyPressCallback(key, GetAsText(key), this); - w = w->next; - } + this->keys[key].makecode = keyboard.MakeCode; } } } + + if(this->textTarget) + { //Parse text + UINT virtualKey = MapVirtualKey(keyboard.VKey, MAPVK_VK_TO_CHAR); + + if(this->keys[SAKI_Backspace].isDown) + { + if( this->writePos > 0 ) + { + --this->writePos; + this->textTarget->erase( this->writePos, 1 ); + } + } + else if (this->keys[SAKI_Delete].isDown) + { + if( this->writePos < this->textTarget->size() ) + { + this->textTarget->erase( this->writePos, 1 ); + } + } + else if (this->keys[SAKI_Left].isDown) + { + this->writePos = std::max( this->writePos - 1, (wstring::size_type)0 ); + } + else if (this->keys[SAKI_Right].isDown) + { + this->writePos = std::min( this->writePos + 1, this->textTarget->size() ); + } + else if (virtualKey && !isUp) + { + wchar_t test = towlower((wchar_t)virtualKey); + if( this->keys[SAKI_LeftShift].isDown || this->keys[SAKI_RightShift].isDown ) + { + if(key == SAKI_0) test = L'='; + else if(key == SAKI_1) test = L'!'; + else if(key == SAKI_2) test = L'"'; + else if(key == SAKI_3) test = L'#'; + else if(key == SAKI_4) test = L'¤'; + else if(key == SAKI_5) test = L'%'; + else if(key == SAKI_6) test = L'&'; + else if(key == SAKI_7) test = L'/'; + else if(key == SAKI_8) test = L'('; + else if(key == SAKI_9) test = L')'; + else if(key == SAKI_Add) test = L'?'; + test = towupper(test); + } + else if( this->keys[SAKI_LeftAlt].isDown || this->keys[SAKI_RightAlt].isDown ) + { + if(key == SAKI_2) test = L'@'; + else if(key == SAKI_3) test = L'£'; + else if(key == SAKI_4) test = L'$'; + else if(key == SAKI_5) test = L'€'; + else if(key == SAKI_7) test = L'{'; + else if(key == SAKI_8) test = L'['; + else if(key == SAKI_9) test = L']'; + else if(key == SAKI_0) test = L'}'; + else if(key == SAKI_Add) test = L'\\'; + } + this->textTarget->insert( this->writePos, 1, test); + ++this->writePos; + } + } } + + +void Win32Keyboard::MapKey(RAWKEYBOARD& rawKB, SAKI& out_key, bool& isE0) +{ + //------------------------------------------------------------------------------------// + // http://molecularmusings.wordpress.com/2011/09/05/properly-handling-keyboard-input/ // + //------------------------------------------------------------------------------------// + + UINT virtualKey = rawKB.VKey; + UINT scanCode = rawKB.MakeCode; + UINT flags = rawKB.Flags; + + if (virtualKey == 255) + { + // discard "fake keys" which are part of an escaped sequence + return; + } + else if (virtualKey == VK_SHIFT) + { + // correct left-hand / right-hand SHIFT + virtualKey = MapVirtualKey(scanCode, MAPVK_VSC_TO_VK_EX); + } + else if (virtualKey == VK_NUMLOCK) + { + // correct PAUSE/BREAK and NUM LOCK silliness, and set the extended bit + scanCode = (MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC) | 0x100); + } + + // e0 and e1 are escape sequences used for certain special keys, such as PRINT and PAUSE/BREAK. + // see http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html + isE0 = ((flags & RI_KEY_E0) != 0); + const bool isE1 = ((flags & RI_KEY_E1) != 0); + + if (isE1) + { + // for escaped sequences, turn the virtual key into the correct scan code using MapVirtualKey. + // however, MapVirtualKey is unable to map VK_PAUSE (this is a known bug), hence we map that by hand. + if (virtualKey == VK_PAUSE) scanCode = 0x45; + else scanCode = MapVirtualKey(virtualKey, MAPVK_VK_TO_VSC); + } + + + + switch (virtualKey) + { + // right-hand CONTROL and ALT have their e0 bit set + case VK_CONTROL: + if (isE0) out_key = SAKI_RightCtrl; + else out_key = SAKI_LeftCtrl; + break; + + case VK_MENU: + if (isE0) out_key = SAKI_RightAlt; + else out_key = SAKI_LeftAlt; + break; + + // NUMPAD ENTER has its e0 bit set + case VK_RETURN: + if (isE0) out_key = SAKI_NumpadEnter; + break; + + // the standard INSERT, DELETE, HOME, END, PRIOR and NEXT keys will always have their e0 bit set, but the + // corresponding keys on the NUMPAD will not. + case VK_INSERT: + if (!isE0) out_key = SAKI_Numpad0; + + break; + + case VK_DELETE: + if (!isE0) out_key = SAKI_NumpadDecimal; + + break; + + case VK_HOME: + if (!isE0) out_key = SAKI_Numpad7; + + break; + + case VK_END: + if (!isE0) out_key = SAKI_Numpad1; + + break; + + case VK_PRIOR: + if (!isE0) out_key = SAKI_Numpad9; + + break; + + case VK_NEXT: + if (!isE0) out_key = SAKI_Numpad3; + + break; + + // the standard arrow keys will always have their e0 bit set, but the + // corresponding keys on the NUMPAD will not. + case VK_LEFT: + if (!isE0) out_key = SAKI_Numpad4; + + break; + + case VK_RIGHT: + if (!isE0) out_key = SAKI_Numpad6; + + break; + + case VK_UP: + if (!isE0) out_key = SAKI_Numpad8; + + break; + + case VK_DOWN: + if (!isE0) out_key = SAKI_Numpad2; + + break; + + // NUMPAD 5 doesn't have its e0 bit set + case VK_CLEAR: + if (!isE0) out_key = SAKI_Numpad5; + + break; + case 0x03 : //VK_CANCEL + break; + case 0x08 : //VK_BACK + out_key = SAKI_Backspace; + break; + case 0x09 : //VK_TAB + out_key = SAKI_Tab; + break; + case 0x10 : //VK_SHIFT + out_key = SAKI_LeftShift; + out_key = SAKI_RightShift; + break; + case 0x13 : //VK_PAUSE + out_key = SAKI_Pause; + break; + case 0x14 : //VK_CAPITAL + out_key = SAKI_CapsLock; + break; + case 0x15 : //VK_KANA + break; + case 0x1B : //VK_ESCAPE + out_key = SAKI_Escape; + break; + case 0x1C : //VK_CONVERT + break; + case 0x1D : //VK_NONCONVERT + break; + case 0x1E : //VK_ACCEPT + break; + case 0x1F : //VK_MODECHANGE + break; + case 0x20 : //VK_SPACE + out_key = SAKI_Space; + + break; + case 0x29 : //VK_SELECT + break; + case 0x2A : //VK_PRINT + out_key = SAKI_PrintScreen; + break; + case 0x2B : //VK_EXECUTE + break; + case 0x2C : //VK_SNAPSHOT + break; + case 0x2F : //VK_HELP + break; + case 0x30 : //0 key + out_key = SAKI_0; + + break; + case 0x31 : //1 key + out_key = SAKI_1; + + break; + case 0x32 : //2 key + out_key = SAKI_2; + + break; + case 0x33 : //3 key + out_key = SAKI_3; + + break; + case 0x34 : //4 key + out_key = SAKI_4; + + break; + case 0x35 : //5 key + out_key = SAKI_5; + + break; + case 0x36 : //6 key + out_key = SAKI_6; + + break; + case 0x37 : //7 key + out_key = SAKI_7; + + break; + case 0x38 : //8 key + out_key = SAKI_8; + + break; + case 0x39 : //9 key + out_key = SAKI_9; + + break; + case 0x41 : //A key + out_key = SAKI_A; + + break; + case 0x42 : //B key + out_key = SAKI_B; + + break; + case 0x43 : //C key + out_key = SAKI_C; + + break; + case 0x44 : //D key + out_key = SAKI_D; + + break; + case 0x45 : //E key + out_key = SAKI_E; + + break; + case 0x46 : //F key + out_key = SAKI_F; + + break; + case 0x47 : //G key + out_key = SAKI_G; + + break; + case 0x48 : //H key + out_key = SAKI_H; + + break; + case 0x49 : //I key + out_key = SAKI_I; + + break; + case 0x4A : //J key + out_key = SAKI_J; + + break; + case 0x4B : //K key + out_key = SAKI_K; + + break; + case 0x4C : //L key + out_key = SAKI_L; + + break; + case 0x4D : //M key + out_key = SAKI_M; + + break; + case 0x4E : //N key + out_key = SAKI_N; + + break; + case 0x4F : //O key + out_key = SAKI_O; + + break; + case 0x50 : //P key + out_key = SAKI_P; + + break; + case 0x51 : //Q key + out_key = SAKI_Q; + + break; + case 0x52 : //R key + out_key = SAKI_R; + + break; + case 0x53 : //S key + out_key = SAKI_S; + + break; + case 0x54 : //T key + out_key = SAKI_T; + + break; + case 0x55 : //U key + out_key = SAKI_U; + + break; + case 0x56 : //V key + out_key = SAKI_V; + + break; + case 0x57 : //W key + out_key = SAKI_W; + + break; + case 0x58 : //X key + out_key = SAKI_X; + + break; + case 0x59 : //Y key + out_key = SAKI_Y; + + break; + case 0x5A : //Z key + out_key = SAKI_Z; + + break; + case 0x5B : //VK_LWIN + break; + case 0x5C : //VK_RWIN + break; + case 0x5D : //VK_APPS + break; + case 0x5F : //VK_SLEEP + break; + case 0x60 : //VK_NUMPAD0 + out_key = SAKI_Numpad0; + + break; + case 0x61 : //VK_NUMPAD1 + out_key = SAKI_Numpad1; + + break; + case 0x62 : //VK_NUMPAD2 + out_key = SAKI_Numpad2; + + break; + case 0x63 : //VK_NUMPAD3 + out_key = SAKI_Numpad3; + + break; + case 0x64 : //VK_NUMPAD4 + out_key = SAKI_Numpad4; + + break; + case 0x65 : //VK_NUMPAD5 + out_key = SAKI_Numpad5; + + break; + case 0x66 : //VK_NUMPAD6 + out_key = SAKI_Numpad6; + + break; + case 0x67 : //VK_NUMPAD7 + out_key = SAKI_Numpad7; + + break; + case 0x68 : //VK_NUMPAD8 + out_key = SAKI_Numpad8; + + break; + case 0x69 : //VK_NUMPAD9 + out_key = SAKI_Numpad9; + + break; + case 0x6A : //VK_MULTIPLY + out_key = SAKI_NumpadMultiply; + + break; + case 0x6B : //VK_ADD + out_key = SAKI_NumpadPlus; + + break; + case 0x6C : //VK_SEPARATOR + break; + case 0x6D : //VK_SUBTRACT + out_key = SAKI_NumpadSubtract; + + break; + case 0x6E : //VK_DECIMAL + out_key = SAKI_NumpadDecimal; + + break; + case 0x6F : //VK_DIVIDE + out_key = SAKI_NumpadDivide; + + break; + case 0x70 : //VK_F1 + out_key = SAKI_F1; + break; + case 0x71 : //VK_F2 + out_key = SAKI_F2; + break; + case 0x72 : //VK_F3 + out_key = SAKI_F3; + break; + case 0x73 : //VK_F4 + out_key = SAKI_F4; + break; + case 0x74 : //VK_F5 + out_key = SAKI_F5; + break; + case 0x75 : //VK_F6 + out_key = SAKI_F6; + break; + case 0x76 : //VK_F7 + out_key = SAKI_F7; + break; + case 0x77 : //VK_F8 + out_key = SAKI_F8; + break; + case 0x78 : //VK_F9 + out_key = SAKI_F9; + break; + case 0x79 : //VK_F10 + out_key = SAKI_F10; + break; + case 0x7A : //VK_F11 + out_key = SAKI_F11; + break; + case 0x7B : //VK_F12 + out_key = SAKI_F12; + break; + case 0x7C : //VK_F13 + out_key = SAKI_F13; + break; + case 0x7D : //VK_F14 + out_key = SAKI_F14; + break; + case 0x7E : //VK_F15 + out_key = SAKI_F15; + break; + case 0x7F : //VK_F16 + out_key = SAKI_F16; + break; + case 0x80 : //VK_F17 + out_key = SAKI_F17; + break; + case 0x81 : //VK_F18 + out_key = SAKI_F18; + break; + case 0x82 : //VK_F19 + out_key = SAKI_F19; + break; + case 0x83 : //VK_F20 + out_key = SAKI_F20; + break; + case 0x84 : //VK_F21 + out_key = SAKI_F21; + break; + case 0x85 : //VK_F22 + out_key = SAKI_F22; + break; + case 0x86 : //VK_F23 + out_key = SAKI_F23; + break; + case 0x87 : //VK_F24 + out_key = SAKI_F24; + break; + case 0x90 : //VK_NUMLOCK + out_key = SAKI_Numlock; + break; + case 0x91 : //VK_SCROLL + out_key = SAKI_ScrlLock; + break; + case 0xA0 : //VK_LSHIFT + out_key = SAKI_LeftShift; + break; + case 0xA1 : //VK_RSHIFT + out_key = SAKI_RightShift; + break; + case 0xA2 : //VK_LCONTROL + out_key = SAKI_LeftCtrl; + break; + case 0xA3 : //VK_RCONTROL + out_key = SAKI_RightCtrl; + break; + case 0xA4 : //VK_LMENU + out_key = SAKI_LeftAlt; + break; + case 0xA5 : //VK_RMENU + out_key = SAKI_RightCtrl; + break; + case 0xAD : //VK_VOLUME_MUTE + out_key = SAKI_VolumeMute; + break; + case 0xAE : //VK_VOLUME_DOWN + out_key = SAKI_VolumeDown; + break; + case 0xAF : //VK_VOLUME_UP + out_key = SAKI_VolumeUp; + break; + case 0xB0 : //VK_MEDIA_NEXT_TRACK + out_key = SAKI_MediaNext; + break; + case 0xB1 : //VK_MEDIA_PREV_TRACK + out_key = SAKI_MediaPrev; + break; + case 0xB2 : //VK_MEDIA_STOP + out_key = SAKI_MediaStop; + break; + case 0xB3 : //VK_MEDIA_PLAY_PAUSE + out_key = SAKI_MediaPlayPause; + break; + + case 0xBB://VK_OEM_PLUS + out_key = SAKI_Add; + break; + case 0xBC://VK_OEM_COMMA + out_key = SAKI_Comma; + break; + case 0xBD://VK_OEM_MINUS + out_key = SAKI_Minus; + break; + case 0xBE://VK_OEM_PERIOD + out_key = SAKI_Period; + break; + case 0xBA://VK_OEM_1 + break; + case 0xBF://VK_OEM_2 + break; + case 0xC0://VK_OEM_3 + break; + case 0xDB://VK_OEM_4 + break; + case 0xDC://VK_OEM_5 + break; + case 0xDD://VK_OEM_6 + break; + case 0xDE://VK_OEM_7 + break; + case 0xDF://VK_OEM_8 + break; + } +} +bool Win32Keyboard::Create() +{ + if(RegisterRawInputDevices(&this->device, 1, sizeof(RAWINPUTDEVICE)) == TRUE) + { + this->isActive = true; + return true; + } + + return false; +} + + + + + diff --git a/Code/Misc/Input/Source/Win32/Win32Mouse.cpp b/Code/Misc/Input/Source/Win32/Win32Mouse.cpp index 8bf22972..c7bc9bf2 100644 --- a/Code/Misc/Input/Source/Win32/Win32Mouse.cpp +++ b/Code/Misc/Input/Source/Win32/Win32Mouse.cpp @@ -1,73 +1,177 @@ ///////////////////////////////////////////////////////////////////// // Created by [Dennis Andersen] [2013] ///////////////////////////////////////////////////////////////////// -#include "..\..\Include\Win32\Win32Mouse.h" +#include "..\..\Include\Win32\Win32Input.h" using namespace Input; using namespace Input::Enum; using namespace Input::Struct; using namespace Input::Typedefs; - -Win32Mouse::Win32Mouse() +void MapButton(RAWMOUSE& rawMouse, bool &isUp, Enum::SAMI& btn, int& delta, Struct::SAIPointInt2D& vel, unsigned int& mcode) { + if(rawMouse.lLastX != 0 || rawMouse.lLastY != 0) + { + vel.x = rawMouse.lLastX; + vel.y = rawMouse.lLastY; + } + if( rawMouse.usButtonFlags > 0 ) + { +//-------------------------------------------------------------------------------------- + //Mouse button pressed + if(rawMouse.usButtonFlags == RI_MOUSE_LEFT_BUTTON_DOWN) + { + btn = SAMI_MouseLeftBtn; + isUp = false; + } + else if(rawMouse.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_DOWN) + { + btn = SAMI_MouseMiddleBtn; + isUp = false; + } + else if(rawMouse.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_DOWN) + { + btn = SAMI_MouseRightBtn; + isUp = false; + } +//-------------------------------------------------------------------------------------- + //Mouse button Released + else if(rawMouse.usButtonFlags == RI_MOUSE_LEFT_BUTTON_UP) + { + btn = SAMI_MouseLeftBtn; + isUp = true; + } + else if(rawMouse.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_UP) + { + btn = SAMI_MouseMiddleBtn; + isUp = true; + } + else if(rawMouse.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_UP) + { + btn = SAMI_MouseRightBtn; + isUp = true; + } +//-------------------------------------------------------------------------------------- + else if (rawMouse.usButtonFlags == RI_MOUSE_WHEEL) + { + delta = ((int)rawMouse.usButtonData); + + if(delta > 120) delta = -1; + else delta = 1; + } + } +} + +void ContainPoint(Struct::SAIPointInt2D& pixelPos, Struct::SAIPointInt2D& windowSize) +{ + if(pixelPos.x < 0) { pixelPos.x = 0; } + else if(pixelPos.x > windowSize.x) { pixelPos.x = windowSize.x; } + if(pixelPos.y < 0) { pixelPos.y = 0; } + else if(pixelPos.y > windowSize.y) { pixelPos.y = windowSize.y; } +} + +Win32Mouse::Win32Mouse(HWND target) +{ + this->isActive = false; + this->device.usUsagePage = 0x01; + this->device.hwndTarget = target; + this->device.usUsage = RawInput_Usage_mouse; + this->device.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE; memset(&this->buttons[0], 0, sizeof(Buttons) * MAXBUTTONS); } Win32Mouse::~Win32Mouse() -{ -} +{ } -bool Win32Mouse::IsBtnUp(Enum::SAMI btn) +bool Win32Mouse::IsBtnUp(Enum::SAMI btn) const { if(btn == SAMI_Unknown) return false; return !this->buttons[btn].isDown; } -bool Win32Mouse::IsBtnDown(Enum::SAMI btn) +bool Win32Mouse::IsBtnDown(Enum::SAMI btn) const { if(btn == SAMI_Unknown) return false; return this->buttons[btn].isDown; } - -void Win32Mouse::ProccessMouseData (bool isUp, Enum::SAMI btn, int delta, Struct::SAIPoint2D velocity, unsigned int makeCode) +int Win32Mouse::GetWheelDelta() const { + return this->wheelDelta; +} +SAIPointInt2D& Win32Mouse::GetPixelPosition( Struct::SAIPointInt2D &targetMem ) const +{ + memcpy(&targetMem, &this->pixelPos, sizeof(SAIPointFloat2D)); + + return targetMem; +} +SAIPointFloat2D& Win32Mouse::GetNormalizedPosition(Struct::SAIPointFloat2D& targetMem) +{ + RECT windowVertex; + GetWindowRect( this->device.hwndTarget, &windowVertex ); + + this->normalPos.x = (float)(pixelPos.x - windowVertex.left); + this->normalPos.x /= (float)(windowVertex.right - windowVertex.left); + + this->normalPos.y = (float)(pixelPos.y - windowVertex.top); + this->normalPos.y /= (float)(windowVertex.bottom - windowVertex.top); + + memcpy(&targetMem, &this->normalPos, sizeof(SAIPointFloat2D)); + + return targetMem; +} +SAIPointFloat2D& Win32Mouse::GetDeltaPosition(Struct::SAIPointFloat2D& targetMem) const +{ + memcpy(&targetMem, &this->deltaPos, sizeof(SAIPointFloat2D)); + + return targetMem; +} + +void Win32Mouse::Activate () +{ + if(this->isActive) return; + + this->Create(); +} +void Win32Mouse::Deactivate () +{ + if(!this->isActive) return; + + RAWINPUTDEVICE d; + d.dwFlags = RIDEV_REMOVE; + d.hwndTarget = 0; + d.usUsage = RawInput_Usage_mouse; + d.usUsagePage = 0x01; + if(RegisterRawInputDevices(&d, 1, sizeof(RAWINPUTDEVICE))) + { + this->isActive = false; + SetCursorPos(this->winCursPos.x, this->winCursPos.y); + ShowCursor(TRUE); + } +} + +void Win32Mouse::ProccessMouseData (RAWMOUSE mouse) +{ + bool isUp = true; + Enum::SAMI btn = Enum::SAMI_Unknown; + int delta = 0; + Struct::SAIPointInt2D velocity; + unsigned int makeCode = 0; + MapButton(mouse, isUp, btn, delta, velocity, makeCode); + if(velocity.Length() != 0) { - this->pixelPos.x += this->deltaPos.x = velocity.x; - this->pixelPos.y += this->deltaPos.y = velocity.y; + this->pixelPos.x += velocity.x; + this->pixelPos.y += velocity.y; - for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) - { - if(this->mouseSubscribers[i]) - this->mouseSubscribers[i]->OnMouseMove(this->pixelPos, this); - } - MouseCallbackList *w = this->callbackList; - while (w) - { - if(w->function) - if (w->type == MouseCallbackList::CallbackDataType_OnMove) - w->function.mouseMoveCallback(this->pixelPos, this); - w = w->next; - } + ContainPoint(this->pixelPos, this->windowSize); + + InternalOnMove(this->pixelPos, velocity); } if(delta != 0) { - for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) - { - if(this->mouseSubscribers[i]) - this->mouseSubscribers[i]->OnMouseScroll(delta, this); - } - MouseCallbackList *w = this->callbackList; - while (w) - { - if(w->function) - if (w->type == MouseCallbackList::CallbackDataType_OnMove) - w->function.mouseScrollCallback(delta, this); - w = w->next; - } + InternalOnScroll(delta); } @@ -79,54 +183,54 @@ void Win32Mouse::ProccessMouseData (bool isUp, Enum::SAMI btn, int delta, Struct //The btn is released. if(isUp) { - for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) - { - if(this->mouseSubscribers[i]) - this->mouseSubscribers[i]->OnMouseRelease(btn, this); - } - MouseCallbackList *w = this->callbackList; - while (w) - { - if(w->function) - if (w->type == MouseCallbackList::CallbackDataType_OnRelease) - w->function.mouseReleaseCallback(btn, this); - w = w->next; - } + InternalOnBtnRelease(btn); } //The btn is pressed. else { + //The btn is down since last frame if(this->buttons[btn].isDown) { - for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) - { - if(this->mouseSubscribers[i]) - this->mouseSubscribers[i]->OnMouseDown(btn, this); - } - MouseCallbackList *w = this->callbackList; - while (w) - { - if(w->function) - if (w->type == MouseCallbackList::CallbackDataType_OnDown) - w->function.mouseDownCallback(btn, this); - w = w->next; - } + InternalOnBtnDown(btn); } else { - for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) - { - if(this->mouseSubscribers[i]) - this->mouseSubscribers[i]->OnMousePress(btn, this); - } - MouseCallbackList *w = this->callbackList; - while (w) - { - if(w->function) - if (w->type == MouseCallbackList::CallbackDataType_OnPress) - w->function.mousePressCallback(btn, this); - w = w->next; - } + InternalOnBtnPress(btn); } } -} \ No newline at end of file +} +bool Win32Mouse::Create() +{ + if(!this->device.hwndTarget) + { + RECT desktop; + const HWND hDesktop = GetDesktopWindow(); + GetClientRect(hDesktop, &desktop); + windowSize.x = desktop.right; + windowSize.y = desktop.bottom; + this->device.dwFlags = 0; + } + else + { + RECT re; + GetClientRect(this->device.hwndTarget, &re); + windowSize.x = re.right - re.left; + windowSize.y = re.bottom - re.top; + } + + if(RegisterRawInputDevices(&this->device, 1, sizeof(RAWINPUTDEVICE)) == TRUE) + { + this->isActive = true; + POINT p; + GetCursorPos(&p); + this->winCursPos.x = p.x; + this->winCursPos.y = p.y; + ShowCursor(FALSE); + + return true; + } + + return false; +} + + diff --git a/Code/Misc/WindowManager/WindowShell.cpp b/Code/Misc/WindowManager/WindowShell.cpp index 308e610f..97e3bbe0 100644 --- a/Code/Misc/WindowManager/WindowShell.cpp +++ b/Code/Misc/WindowManager/WindowShell.cpp @@ -77,7 +77,6 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc) if(!desc.hInstance) desc.hInstance = GetModuleHandle(0); if(desc.windowSize.x <= 0) desc.windowSize.x = 50; if(desc.windowSize.y <= 0) desc.windowSize.y = 50; - __windowShellData.parent = desc.parent; __windowShellData.hIns = desc.hInstance; @@ -111,20 +110,14 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc) RECT rectW; - int width; - int height; DWORD style = desc.windowStyle; bool windowed = false; - width = desc.windowSize.x + GetSystemMetrics(SM_CXFIXEDFRAME)*2; - height = desc.windowSize.y + GetSystemMetrics(SM_CYFIXEDFRAME)*2 + GetSystemMetrics(SM_CYCAPTION); + rectW.left = 0; + rectW.top = 0; + rectW.right = desc.windowSize.x; + rectW.bottom = desc.windowSize.y; - rectW.left=(GetSystemMetrics(SM_CXSCREEN)-width)/2; - rectW.top=(GetSystemMetrics(SM_CYSCREEN)-height)/2; - rectW.right=rectW.left+width; - rectW.bottom=rectW.top+height; - - if(__windowShellData.parent) { rectW.left = 0; @@ -135,6 +128,8 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc) windowed = true; } + AdjustWindowRect(& rectW, style, FALSE); + if(windowed) { __windowShellData.hWnd = CreateWindowExW( @@ -161,8 +156,8 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc) style, desc.windowPosition.x, desc.windowPosition.y, - desc.windowSize.x, - desc.windowSize.y, + rectW.right - rectW.left, + rectW.bottom - rectW.top, 0, 0, __windowShellData.hIns, @@ -173,7 +168,6 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc) if( !__windowShellData.hWnd ) { printf("Failed to create window handle : Code ( %ul )", GetLastError()); - //MessageBox(0, L"Failed to create window", L"Error!", 0); return false; } @@ -258,3 +252,4 @@ bool WindowShell::Frame() return true; } + diff --git a/Code/Misc/WindowManager/WindowShell.h b/Code/Misc/WindowManager/WindowShell.h index 04bb9931..458debd7 100644 --- a/Code/Misc/WindowManager/WindowShell.h +++ b/Code/Misc/WindowManager/WindowShell.h @@ -40,7 +40,7 @@ public: POINT _windowSize = cPOINT(800, 600), POINT _windowPosition = cPOINT(0,0), UINT _windowClassStyle = (CS_HREDRAW | CS_VREDRAW | CS_OWNDC), - UINT _windowStyle = (WS_POPUPWINDOW|WS_SYSMENU|WS_CAPTION), + UINT _windowStyle = (WS_POPUPWINDOW|WS_CAPTION), HICON _icon = LoadIcon(0, IDI_APPLICATION), HCURSOR _cursor = LoadCursor(NULL, IDC_ARROW), HBRUSH _background = (HBRUSH)GetStockObject(BLACK_BRUSH) diff --git a/Code/OysterGraphics/Definitions/GraphicalDefinition.h b/Code/OysterGraphics/Definitions/GraphicalDefinition.h index c9b42c00..f6a6431c 100644 --- a/Code/OysterGraphics/Definitions/GraphicalDefinition.h +++ b/Code/OysterGraphics/Definitions/GraphicalDefinition.h @@ -62,6 +62,9 @@ namespace Oyster struct PostData { float Amb; + Math::Float3 Tint; + Math::Float3 GlowTint; + float PAD; }; struct Text2D diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp index 41063265..8f01bea4 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp @@ -123,6 +123,8 @@ namespace Oyster Definitions::PostData pd; pd.Amb = option.AmbientValue; + pd.Tint = option.GlobalTint; + pd.GlowTint = option.GlobalGlowTint; void* data = Render::Resources::Post::Data.Map(); memcpy(data,&pd,sizeof(Definitions::PostData)); diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.h b/Code/OysterGraphics/DllInterfaces/GFXAPI.h index 827f639f..795f649a 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.h +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.h @@ -30,6 +30,9 @@ namespace Oyster //between 0-1 float AmbientValue; + Math::Float3 GlobalTint; + Math::Float3 GlobalGlowTint; + Math::Float2 Resolution; //Bytes on the GPU diff --git a/Code/OysterGraphics/OysterGraphics.vcxproj.user b/Code/OysterGraphics/OysterGraphics.vcxproj.user index 9a0b0ae0..3f030911 100644 --- a/Code/OysterGraphics/OysterGraphics.vcxproj.user +++ b/Code/OysterGraphics/OysterGraphics.vcxproj.user @@ -1,6 +1,6 @@  - true + false \ No newline at end of file diff --git a/Code/OysterGraphics/Render/GuiRenderer.cpp b/Code/OysterGraphics/Render/GuiRenderer.cpp index b71be6d7..98642604 100644 --- a/Code/OysterGraphics/Render/GuiRenderer.cpp +++ b/Code/OysterGraphics/Render/GuiRenderer.cpp @@ -56,8 +56,8 @@ namespace Oyster //size.x = size.x / (text.length() * TEXT_SPACING /2); - pos *= 2; - pos -= 1; + pos.xy *= 2; + pos.xy -= 1; pos.y *= -1; diff --git a/Code/OysterGraphics/Shader/Passes/Gather/GatherPixel.hlsl b/Code/OysterGraphics/Shader/Passes/Gather/GatherPixel.hlsl index af095acf..11447238 100644 --- a/Code/OysterGraphics/Shader/Passes/Gather/GatherPixel.hlsl +++ b/Code/OysterGraphics/Shader/Passes/Gather/GatherPixel.hlsl @@ -41,8 +41,8 @@ PixelOut main(VertexOut input) { PixelOut output; float4 DiffGlow = Diffuse.Sample(S1, input.UV); - float3 tint = Color*(1-DiffGlow) + GlowColor * DiffGlow; - tint = tint / 2; + float3 tint = Color*(1-DiffGlow.w) + GlowColor * DiffGlow.w; + tint = Color*(1-DiffGlow.w) + GlowColor * DiffGlow.w; output.DiffuseGlow = DiffGlow * float4(tint,1); //NORMALIZE diff --git a/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl b/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl index 96b8ab69..89ed06d3 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl +++ b/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl @@ -47,7 +47,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) DepthBase = DepthBase /4; Ambient[DTid.xy/2] = float4(DiffBase.xyz, AmbValue); Ambient[DTid.xy/2 + float2(Pixels.x/2, 0)] = GUI[DTid.xy]; - Ambient[DTid.xy/2 + float2(0, Pixels.y/2)] = float4(DiffBase.xyz * DiffBase.w * 10 /* * (2-DepthBase) */,1); + Ambient[DTid.xy/2 + float2(0, Pixels.y/2)] = float4(DiffBase.xyz * DiffBase.w /* * (2-DepthBase) */,DiffBase.w); Ambient[DTid.xy/2 + Pixels/2] = float4(NormalSpec[DTid.xy].xyz * float3(1,1,-1),1); } diff --git a/Code/OysterGraphics/Shader/Passes/Light/SSAO.hlsli b/Code/OysterGraphics/Shader/Passes/Light/SSAO.hlsli index f2258905..c71cb4d5 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/SSAO.hlsli +++ b/Code/OysterGraphics/Shader/Passes/Light/SSAO.hlsli @@ -1,7 +1,7 @@ #include "Defines.hlsli" #include "PosManipulation.hlsli" -static float Radius = 10; +static float Radius = 1; float GetSSAO(float3 pos, float2 uv, int2 texCoord2, uint2 rndID) { diff --git a/Code/OysterGraphics/Shader/Passes/Post/PostPass.hlsl b/Code/OysterGraphics/Shader/Passes/Post/PostPass.hlsl index 258d0f25..c3f7e69e 100644 --- a/Code/OysterGraphics/Shader/Passes/Post/PostPass.hlsl +++ b/Code/OysterGraphics/Shader/Passes/Post/PostPass.hlsl @@ -9,6 +9,8 @@ SamplerState S1 : register(s0); cbuffer Size : register(b0) { float AmbFactor; + float3 Color; + float3 GlowColor; } [numthreads(16, 16, 1)] @@ -26,9 +28,10 @@ void main( uint3 DTid : SV_DispatchThreadID ) SSAO = SSAO / 16; float4 Light = Diffuse[DTid.xy] + saturate(Specular[DTid.xy]); - float3 Amb = Ambient[DTid.xy/2].xyz * SSAO; + float3 Amb = Ambient[DTid.xy/2].xyz * SSAO * Color; - float3 Glow = Ambient[DTid.xy/2 + uint2(0,Output.Length.y/2)].xyz; + float4 Glow = Ambient[DTid.xy/2 + uint2(0,Output.Length.y/2)]; + Glow = float4(Glow.xyz * GlowColor, 1); float4 GUI; uint2 index = DTid.xy/2 + uint2((uint)Output.Length.x/(uint)2,0); @@ -40,4 +43,5 @@ void main( uint3 DTid : SV_DispatchThreadID ) //Output[DTid.xy] = float4(Ambient[DTid.xy/2 + uint2(Output.Length*0.5f)].xyz,1); //Output[DTid.xy] = SSAO * float4(1,1,1,1); + //Output[DTid.xy] = Ambient[DTid.xy]; } \ No newline at end of file diff --git a/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.cpp index ef003d7f..e2d87ce7 100644 --- a/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -168,9 +168,15 @@ void SimpleRigidBody::SetRotationAsAngularAxis(::Oyster::Math::Float4 angularAxi return; } + float s = sin(angularAxis.w/2); + float x = angularAxis.x * s; + float y = angularAxis.y * s; + float z = angularAxis.z * s; + float w = cos(angularAxis.w/2); + btTransform trans; btVector3 vector(angularAxis.x, angularAxis.y, angularAxis.z); - btQuaternion quaternion(vector, angularAxis.w); + btQuaternion quaternion(x,y,z,w); trans = this->rigidBody->getWorldTransform(); trans.setRotation(quaternion); @@ -263,22 +269,11 @@ Float4x4 SimpleRigidBody::GetRotation() const Float4 SimpleRigidBody::GetRotationAsAngularAxis() { Float4 axis = Float4::null; - Float s = sqrtf(1 - this->state.quaternion.real*this->state.quaternion.real); + btTransform trans; - axis.w = 2*acos(this->state.quaternion.real*this->state.quaternion.real); - - if(1 - this->state.quaternion.real > 0.001f) - { - axis.x = this->state.quaternion.imaginary.x/s; - axis.y = this->state.quaternion.imaginary.y/s; - axis.z = this->state.quaternion.imaginary.z/s; - } - else - { - axis.x = this->state.quaternion.imaginary.x; - axis.y = this->state.quaternion.imaginary.y; - axis.z = this->state.quaternion.imaginary.z; - } + trans = this->rigidBody->getWorldTransform(); + axis.xyz = trans.getRotation().getAxis(); + axis.w = trans.getRotation().getAngle(); return axis; } @@ -353,7 +348,8 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld) { btTransform xform; xform = this->rigidBody->getWorldTransform (); - btVector3 down = -xform.getBasis()[1]; + Float3 normalDown = -this->state.centerPos.GetNormalized(); + btVector3 down(normalDown.x, normalDown.y, normalDown.z); btVector3 forward = xform.getBasis()[2]; down.normalize (); forward.normalize(); @@ -361,12 +357,17 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld) this->raySource[0] = xform.getOrigin(); this->raySource[1] = xform.getOrigin(); + if(this->state.reach.y < 1.0f) + + Float angle = acos(Float3(0, 1, 0).Dot(this->state.centerPos.GetNormalized())); - down.setZ(-down.z()); - down.setX(-down.x()); + //down.setZ(-down.z()); btVector3 targetPlus = down * this->state.reach.y * btScalar(1.1); - + if(this->state.mass == 40) + { + const char* breakpoint = "STOP"; + } this->rayTarget[0] = this->raySource[0] + targetPlus; this->rayTarget[1] = this->raySource[1] + forward * this->state.reach.y * btScalar(1.1); @@ -383,7 +384,6 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld) { if (rayResult.m_collisionObject == m_me) return 1.0; - return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace); } protected: @@ -412,4 +412,14 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld) float SimpleRigidBody::GetLambda() const { return this->rayLambda[0]; +} + +void SimpleRigidBody::MoveToLimbo() +{ + this->rigidBody->setCollisionFlags(this->rigidBody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); +} + +void SimpleRigidBody::ReleaseFromLimbo() +{ + this->rigidBody->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); } \ No newline at end of file diff --git a/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.h b/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.h index effd123d..4290b540 100644 --- a/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.h @@ -69,6 +69,9 @@ namespace Oyster float GetLambda() const; + void MoveToLimbo(); + void ReleaseFromLimbo(); + private: btCollisionShape* collisionShape; diff --git a/Code/Physics/GamePhysics/PhysicsAPI.h b/Code/Physics/GamePhysics/PhysicsAPI.h index 72d4a8c6..33dc24a8 100644 --- a/Code/Physics/GamePhysics/PhysicsAPI.h +++ b/Code/Physics/GamePhysics/PhysicsAPI.h @@ -169,6 +169,9 @@ namespace Oyster virtual void CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Math::Float kineticEnergyLoss) = 0; virtual void CallSubscription_Move() = 0; + virtual void MoveToLimbo() = 0; + virtual void ReleaseFromLimbo() = 0; + /******************************************************** * @return the void pointer set by SetCustomTag. * nullptr if none is set.