Merge remote-tracking branch 'origin/GameServer' into Physics

This commit is contained in:
Robin Engman 2014-02-27 09:19:58 +01:00
commit b78bc8c242
64 changed files with 2768 additions and 1670 deletions

View File

@ -776,5 +776,6 @@ Global
{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE} = {1322B12B-5E37-448A-AAAF-F637460DCB23} {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE} = {1322B12B-5E37-448A-AAAF-F637460DCB23}
{604A12A7-07BF-4482-BDF3-7101C811F121} = {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012} {604A12A7-07BF-4482-BDF3-7101C811F121} = {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012}
{C8CBA520-5D7D-4D61-A8DA-6E05FD132BCB} = {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012} {C8CBA520-5D7D-4D61-A8DA-6E05FD132BCB} = {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012}
{67D0FB00-FF1F-4DE4-84BD-664AE93D25EE} = {C83A6FAD-E71F-4B1E-9D63-E93E61DDC012}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -9,73 +9,86 @@
#include "GameClientState\MainState.h" #include "GameClientState\MainState.h"
#include "GameClientState\LanMenuState.h" #include "GameClientState\LanMenuState.h"
#include "GameClientState\NetLoadState.h" #include "GameClientState\NetLoadState.h"
#include "Utilities.h"
#include <Protocols.h> #include <Protocols.h>
#include "NetworkClient.h" #include "NetworkClient.h"
#include <GameServerAPI.h> #include <GameServerAPI.h>
#include "../WindowManager/WindowShell.h" #include "../WindowManager/WindowShell.h"
#include "L_inputClass.h"
#include "WinTimer.h" #include "WinTimer.h"
#include "vld.h" #include "vld.h"
#include "EventHandler/EventHandler.h" #include "EventHandler/EventHandler.h"
#include "GameClientState\SharedStateContent.h" #include "GameClientState/SharedStateContent.h"
#include "Utilities.h"
using namespace ::Oyster; using namespace ::Oyster;
using namespace ::Oyster::Event; using namespace ::Oyster::Event;
using namespace ::Oyster::Network; using namespace ::Oyster::Network;
using namespace ::Utility::DynamicMemory; using namespace ::Utility::DynamicMemory;
using namespace ::DanBias::Client; using namespace ::DanBias::Client;
using namespace ::Utility::DynamicMemory;
LRESULT CALLBACK WindowCallBack(HWND handle, UINT message, WPARAM wParam, LPARAM lParam );
void ClientEventFunction( NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e ); void ClientEventFunction( NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e );
#pragma region Game Data
namespace DanBias namespace DanBias
{ {
#pragma region Game Data
class DanBiasGamePrivateData class DanBiasGamePrivateData
{ {
public: public:
WindowShell* window; WindowShell* window;
InputClass inputObj;
Utility::WinTimer timer; Utility::WinTimer timer;
UniquePointer<Client::GameClientState> state; UniquePointer<Client::GameClientState> state;
SharedStateContent sharedStateContent;
NetworkClient networkClient; NetworkClient networkClient;
SharedStateContent sharedStateContent;
bool serverOwner; bool serverOwner;
float capFrame; float capFrame;
DanBiasGamePrivateData() DanBiasGamePrivateData()
{ {
this->capFrame = 0; this->sharedStateContent.network = nullptr;
this->sharedStateContent.mouseDevice = nullptr;
this->sharedStateContent.keyboardDevice = nullptr;
this->sharedStateContent.mouseSensitivity = Utility::Value::Radian( 0.6f );
this->serverOwner = false;
this->capFrame = 0;
}
~DanBiasGamePrivateData()
{
} }
} data; } data;
}
#pragma endregion #pragma endregion
namespace DanBias
{
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Interface API functions // Interface API functions
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
DanBiasClientReturn DanBiasGame::Initiate(DanBiasGameDesc& desc) DanBiasClientReturn DanBiasGame::Initiate( DanBiasGameDesc& desc )
{ {
WindowShell::CreateConsoleWindow(); WindowShell::CreateConsoleWindow();
//if(! data.window->CreateWin(WindowShell::WINDOW_INIT_DESC(L"Window", cPOINT(1600, 900), cPOINT()))) //if(! data.window->CreateWin(WindowShell::WINDOW_INIT_DESC(L"Window", cPOINT(1600, 900), cPOINT())))
WindowShell::WINDOW_INIT_DESC winDesc; WindowShell::WINDOW_INIT_DESC winDesc;
winDesc.windowSize.x = 1280; winDesc.windowSize.x = 1280;
winDesc.windowSize.y = 720; winDesc.windowSize.y = 720;
winDesc.windowProcCallback = WindowCallBack;
if(! data.window->CreateWin(winDesc) ) if(! data.window->CreateWin(winDesc) )
return DanBiasClientReturn_Error; return DanBiasClientReturn_Error;
if( FAILED( InitDirect3D() ) ) if( FAILED( InitInput(data.window->GetHWND()) ) )
return DanBiasClientReturn_Error; return DanBiasClientReturn_Error;
if( FAILED( InitInput() ) ) if( FAILED( InitDirect3D() ) )
return DanBiasClientReturn_Error; return DanBiasClientReturn_Error;
data.serverOwner = false; data.serverOwner = false;
@ -83,7 +96,6 @@ namespace DanBias
data.networkClient.SetMessagePump( ClientEventFunction ); data.networkClient.SetMessagePump( ClientEventFunction );
data.sharedStateContent.network = &data.networkClient; data.sharedStateContent.network = &data.networkClient;
data.sharedStateContent.input = &data.inputObj;
// Start in main menu state // Start in main menu state
data.state = new Client::MainState(); data.state = new Client::MainState();
@ -138,7 +150,6 @@ namespace DanBias
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
HRESULT DanBiasGame::InitDirect3D() HRESULT DanBiasGame::InitDirect3D()
{ {
Oyster::Graphics::API::Option p; Oyster::Graphics::API::Option p;
p.modelPath = L"..\\Content\\Models\\"; p.modelPath = L"..\\Content\\Models\\";
p.texturePath = L"..\\Content\\Textures\\"; p.texturePath = L"..\\Content\\Textures\\";
@ -154,35 +165,27 @@ namespace DanBias
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Init the input // 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::Mouse*>( ::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; return E_FAIL;
} }
data.sharedStateContent.keyboardDevice= dynamic_cast<Input::Keyboard*>( ::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; return S_OK;
} }
DanBiasGame::Result DanBiasGame::Update(float deltaTime) 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 ) if( data.serverOwner )
{ {
DanBias::GameServerAPI::ServerUpdate(); DanBias::GameServerAPI::ServerUpdate();
@ -252,6 +255,8 @@ namespace DanBias
data.networkClient.Disconnect(); data.networkClient.Disconnect();
data.state = nullptr; data.state = nullptr;
Input::InputManager::DestroyInputManager();
EventHandler::Instance().Clean(); EventHandler::Instance().Clean();
Graphics::API::Clean(); Graphics::API::Clean();
@ -262,6 +267,22 @@ namespace DanBias
} //End 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<NetworkClient*, NetworkClient::ClientEventArgs> e ) void ClientEventFunction( NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e )
{ {
if( DanBias::data.state ) if( DanBias::data.state )

View File

@ -106,7 +106,7 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input\Include;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -123,7 +123,7 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input\Include;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -142,7 +142,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input\Include;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -163,7 +163,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>DANBIAS_GAME_DLL_EXPORT;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc\OysterMath;$(SolutionDir)Misc\Input\Include;$(SolutionDir)OysterGraphics;$(SolutionDir)Misc\Utilities;$(SolutionDir)Game\LevelLoader</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -253,10 +253,12 @@
<ClInclude Include="GameClientState\RespawnUI.h" /> <ClInclude Include="GameClientState\RespawnUI.h" />
<ClInclude Include="GameClientState\SharedStateContent.h" /> <ClInclude Include="GameClientState\SharedStateContent.h" />
<ClInclude Include="GameClientState\StatsUI.h" /> <ClInclude Include="GameClientState\StatsUI.h" />
<ClInclude Include="Include\DanBiasGame.h" />
<ClInclude Include="Include\GameClient.h" /> <ClInclude Include="Include\GameClient.h" />
<ClInclude Include="GameClientState\LobbyState.h" /> <ClInclude Include="GameClientState\LobbyState.h" />
<ClInclude Include="GameClientState\C_Object.h" /> <ClInclude Include="GameClientState\C_Object.h" />
<ClInclude Include="GameClientState\Buttons\TextField.h" /> <ClInclude Include="GameClientState\Buttons\TextField.h" />
<ClInclude Include="Win32Input.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -78,7 +78,7 @@ namespace DanBias { namespace Client
{ {
::Oyster::Math::Float lineStep = this->fontHeight + this->lineSpacing; ::Oyster::Math::Float lineStep = this->fontHeight + this->lineSpacing;
::Oyster::Math::Float2 rowSize = ::Oyster::Math::Float2( this->size.x, this->fontHeight ); ::Oyster::Math::Float2 rowSize = ::Oyster::Math::Float2( this->size.x, this->fontHeight );
::Oyster::Math::Float3 fieldTopLeft = this->pos - Float3( this->size * 0.25f, 0.0f ); ::Oyster::Math::Float3 fieldTopLeft = this->pos - Float3( this->size * 0.25f, 0.001f );
::Oyster::Math::Float3 topLeft = fieldTopLeft; ::Oyster::Math::Float3 topLeft = fieldTopLeft;
if( this->isBottomAligned ) if( this->isBottomAligned )

View File

@ -91,7 +91,10 @@ void C_Object::Render()
{ {
if( this->model ) if( this->model )
{ {
Oyster::Graphics::API::RenderModel(model); if(this->model->Visible)
{
Oyster::Graphics::API::RenderModel(model);
}
} }
} }
void C_Object::Release() void C_Object::Release()

View File

@ -1,9 +1,11 @@
#include "C_StaticObj.h" #include "C_StaticObj.h"
#include "DllInterfaces/GFXAPI.h" #include "DllInterfaces/GFXAPI.h"
using namespace DanBias::Client; using namespace DanBias::Client;
C_StaticObj::C_StaticObj(void) C_StaticObj::C_StaticObj( GameLogic::ObjectSpecialType t )
:C_Object() :C_Object()
,gameObjectType(t)
{ {
} }

View File

@ -1,6 +1,7 @@
#ifndef DANBIAS_CLIENT_CSTATICOBJECT_H #ifndef DANBIAS_CLIENT_CSTATICOBJECT_H
#define DANBIAS_CLIENT_CSTATICOBJECT_H #define DANBIAS_CLIENT_CSTATICOBJECT_H
#include "../C_Object.h" #include "../C_Object.h"
#include "ObjectDefines.h"
namespace DanBias namespace DanBias
{ {
namespace Client namespace Client
@ -8,10 +9,12 @@ namespace DanBias
class C_StaticObj : public C_Object class C_StaticObj : public C_Object
{ {
private: private:
const GameLogic::ObjectSpecialType gameObjectType;
public: public:
C_StaticObj(void); C_StaticObj(GameLogic::ObjectSpecialType type = GameLogic::ObjectSpecialType_Unknown);
virtual ~C_StaticObj(void); virtual ~C_StaticObj(void);
bool Init(ModelInitData modelInit); bool Init(ModelInitData modelInit);
inline GameLogic::ObjectSpecialType GetGameObjectType() const { return this->gameObjectType; }
};};}; };};};
#endif #endif

View File

@ -28,7 +28,8 @@ struct GameState::MyData
MyData(){} MyData(){}
GameClientState::ClientState nextState; GameClientState::ClientState nextState;
NetworkClient *nwClient; NetworkClient *nwClient;
InputClass *input; ::Input::Mouse *mouseInput;
::Input::Keyboard *keyboardInput;
::std::map<int, ::Utility::DynamicMemory::UniquePointer<::DanBias::Client::C_StaticObj>> *staticObjects; ::std::map<int, ::Utility::DynamicMemory::UniquePointer<::DanBias::Client::C_StaticObj>> *staticObjects;
::std::map<int, ::Utility::DynamicMemory::UniquePointer<::DanBias::Client::C_DynamicObj>> *dynamicObjects; ::std::map<int, ::Utility::DynamicMemory::UniquePointer<::DanBias::Client::C_DynamicObj>> *dynamicObjects;
@ -67,7 +68,8 @@ bool GameState::Init( SharedStateContent &shared )
this->privData->nextState = GameClientState::ClientState_Same; this->privData->nextState = GameClientState::ClientState_Same;
this->privData->nwClient = shared.network; 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->staticObjects = &shared.staticObjects;
this->privData->dynamicObjects = &shared.dynamicObjects; this->privData->dynamicObjects = &shared.dynamicObjects;
this->privData->lights = &shared.lights; this->privData->lights = &shared.lights;
@ -81,15 +83,15 @@ bool GameState::Init( SharedStateContent &shared )
gfxOp.GlobalTint = Math::Float3(1,1,1); gfxOp.GlobalTint = Math::Float3(1,1,1);
Graphics::API::SetOptions(gfxOp); Graphics::API::SetOptions(gfxOp);
//tell server ready
this->privData->nwClient->Send( Protocol_General_Status(Protocol_General_Status::States_ready) );
// DEGUG KEYS // DEGUG KEYS
this->key_Reload_Shaders = false; this->key_Reload_Shaders = false;
this->key_Wireframe_Toggle = false; this->key_Wireframe_Toggle = false;
this->renderWhireframe = false; this->renderWhireframe = false;
// !DEGUG KEYS // !DEGUG KEYS
shared.keyboardDevice->ReleaseTextTarget();
//shared.mouseDevice->AddMouseEvent(this);
auto light = this->privData->lights->begin(); auto light = this->privData->lights->begin();
for( ; light != this->privData->lights->end(); ++light ) for( ; light != this->privData->lights->end(); ++light )
{ {
@ -97,7 +99,7 @@ bool GameState::Init( SharedStateContent &shared )
} }
// create UI states // create UI states
this->gameUI = new GamingUI(this->privData->input, this->privData->nwClient, &this->privData->camera); this->gameUI = new GamingUI(&shared, &this->privData->camera);
this->respawnUI = new RespawnUI(this->privData->nwClient, 20); this->respawnUI = new RespawnUI(this->privData->nwClient, 20);
this->statsUI = new StatsUI(); this->statsUI = new StatsUI();
this->currGameUI = gameUI; this->currGameUI = gameUI;
@ -105,6 +107,9 @@ bool GameState::Init( SharedStateContent &shared )
((RespawnUI*)respawnUI)->Init(); ((RespawnUI*)respawnUI)->Init();
((StatsUI*)statsUI)->Init(); ((StatsUI*)statsUI)->Init();
//tell server ready
this->privData->nwClient->Send( Protocol_General_Status(Protocol_General_Status::States_ready) );
return true; return true;
} }
@ -145,27 +150,36 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa
//offset.y = p->getScale().y * 5.0f; //offset.y = p->getScale().y * 5.0f;
//offset.z = p->getScale().z * -5.0f; //offset.z = p->getScale().z * -5.0f;
// !DEBUG // !DEBUG
this->privData->camera.SetHeadOffset( offset ); //this->privData->camera.SetHeadOffset( offset );
this->privData->camera.UpdateOrientation(); //this->privData->camera.UpdateOrientation();
} }
} }
} }
GameClientState::ClientState GameState::Update( float deltaTime ) GameClientState::ClientState GameState::Update( float deltaTime )
{ {
GameStateUI::UIState UIstate = this->currGameUI->Update( deltaTime ); GameStateUI::UIState UIstate = this->gameUI->Update( deltaTime );
switch (UIstate) switch (UIstate)
{ {
case DanBias::Client::GameStateUI::UIState_shut_down:
{
this->privData->nextState = ClientState_Quit;
// disconnect
}
break;
case DanBias::Client::GameStateUI::UIState_same: case DanBias::Client::GameStateUI::UIState_same:
break; break;
case DanBias::Client::GameStateUI::UIState_gaming: case DanBias::Client::GameStateUI::UIState_gaming:
break; break;
case DanBias::Client::GameStateUI::UIState_main_menu: case DanBias::Client::GameStateUI::UIState_main_menu:
//this->privData->nextState = {
break; this->privData->nextState = ClientState_Main;
case DanBias::Client::GameStateUI::UIState_shut_down: // disconnect
this->privData->nextState = ClientState_Quit; }
break; break;
default: default:
break; break;
} }
@ -210,8 +224,7 @@ bool GameState::Render()
} }
} }
#ifdef _DEBUG #ifdef _DEBUG //RB DEBUG render wire frame
//RB DEBUG render wire frame
if(this->renderWhireframe) if(this->renderWhireframe)
{ {
Oyster::Graphics::API::StartRenderWireFrame(); Oyster::Graphics::API::StartRenderWireFrame();
@ -261,8 +274,7 @@ bool GameState::Render()
} }
} }
} }
//!RB DEBUG #endif //!RB DEBUG
#endif
Oyster::Graphics::API::StartGuiRender(); Oyster::Graphics::API::StartGuiRender();
// render gui elemnts // render gui elemnts
@ -328,6 +340,7 @@ bool GameState::Release()
delete respawnUI; delete respawnUI;
respawnUI = NULL; respawnUI = NULL;
} }
if(gameUI) if(gameUI)
{ {
gameUI->Release(); gameUI->Release();
@ -341,7 +354,7 @@ bool GameState::Release()
statsUI = NULL; statsUI = NULL;
} }
currGameUI = NULL; currGameUI = NULL;
return true; return true;
} }
@ -349,18 +362,19 @@ void GameState::ChangeState( ClientState next )
{ {
this->privData->nextState = next; this->privData->nextState = next;
} }
void GameState::ReadKeyInput() void GameState::ReadKeyInput()
{ {
// DEGUG KEYS #ifdef _DEBUG // DEGUG KEYS
// Reload shaders // Reload shaders
if( this->privData->input->IsKeyPressed(DIK_R) ) if( this->privData->keyboardInput->IsKeyDown(::Input::Enum::SAKI_R) )
{ {
if( !this->key_Reload_Shaders ) if( !this->key_Reload_Shaders )
{ {
#ifdef _DEBUG
Oyster::Graphics::API::ReloadShaders(); Graphics::API::ReloadShaders();
#endif
this->key_Reload_Shaders = true; this->key_Reload_Shaders = true;
} }
} }
@ -368,7 +382,7 @@ void GameState::ReadKeyInput()
this->key_Reload_Shaders = false; this->key_Reload_Shaders = false;
// toggle wire frame render // toggle wire frame render
if( this->privData->input->IsKeyPressed(DIK_T) ) if( this->privData->keyboardInput->IsKeyDown(::Input::Enum::SAKI_T) )
{ {
if( !this->key_Wireframe_Toggle ) if( !this->key_Wireframe_Toggle )
{ {
@ -386,9 +400,10 @@ void GameState::ReadKeyInput()
this->currGameUI = gameUI; this->currGameUI = gameUI;
// !DEBUG // !DEBUG
} }
#endif // !DEGUG KEYS
// toggle wire frame render // toggle wire frame render
if( this->privData->input->IsKeyPressed(DIK_TAB) ) if( this->privData->keyboardInput->IsKeyDown(::Input::Enum::SAKI_Tab) )
{ {
if( !this->key_showStats ) if( !this->key_showStats )
{ {
@ -403,6 +418,7 @@ void GameState::ReadKeyInput()
} }
} }
const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState::NetEvent &message ) const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState::NetEvent &message )
{ {
if( message.args.type == NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend ) if( message.args.type == NetworkClient::ClientEventArgs::EventType_ProtocolFailedToSend )
@ -596,6 +612,12 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState
{ {
// if it is not a player // if it is not a player
object = (*this->privData->dynamicObjects)[decoded.objectID]; object = (*this->privData->dynamicObjects)[decoded.objectID];
if(!object)
{
//If it is a static object
object = (*this->privData->staticObjects)[decoded.objectID];
}
} }
if( object ) if( object )
@ -613,6 +635,12 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState
{ {
// if it is not a player // if it is not a player
object = (*this->privData->dynamicObjects)[decoded.objectID]; object = (*this->privData->dynamicObjects)[decoded.objectID];
if(!object)
{
//If it is a static object
object = (*this->privData->staticObjects)[decoded.objectID];
}
} }
if( object ) if( object )
@ -750,6 +778,15 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState
case GameLogic::PlayerAction::PlayerAction_Idle: case GameLogic::PlayerAction::PlayerAction_Idle:
player->playAnimation(L"idle", true); player->playAnimation(L"idle", true);
break; break;
case GameLogic::WeaponAction::WeaponAction_PrimaryShoot:
break;
case GameLogic::WeaponAction::WeaponAction_SecondaryShoot:
break;
case GameLogic::WeaponAction::WeaponAction_Reload:
break;
default: default:
break; break;
} }
@ -757,6 +794,28 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState
} }
} }
return GameClientState::event_processed; return GameClientState::event_processed;
case protocol_Gameplay_ObjectCollision:
{
Protocol_ObjectCollision decoded(data);
C_Object *object;
object = (this->privData->players)[decoded.objectID];
if( !object)
{
// if it is not a player
object = (*this->privData->dynamicObjects)[decoded.objectID];
}
if( object )
{
switch (decoded.collisionID)
{
case GameLogic::CollisionEvent::CollisionEvent_BasicCollision:
break;
default:
break;
}
}
}
return GameClientState::event_processed;
default: break; default: break;
} }
} }
@ -772,3 +831,104 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState
return message; return message;
} }
/* :HACK! */
// TODO: Fix camera movement on client
/*
void GameState::SetUp( DanBias::Client::C_Player* p)
{
Float3 up;
auto it = this->privData->staticObjects->begin();
for (it; it != this->privData->staticObjects->end(); it++)
{
if(it->second->GetGameObjectType() == GameLogic::ObjectSpecialType_World)
{
up = - (p->getPos() - it->second->getPos());
break;
}
}
Quaternion newRotation;
Float3 v1 = this->privData->camera.GetUp();
Float3 v2(up.x, up.y, up.z);
Quaternion q;
Float3 a = v1.Cross(v2);
if (v1.Dot(v2) < -0.999999)
{
Float3 xCrossPre = Float3(1, 0 ,0).Cross(v1);
if(xCrossPre.GetLength() < 0.000001)
xCrossPre = Float3(0, 1 ,0).Cross(v1);
xCrossPre.Normalize();
//q.setRotation(xCrossPre, 3.1415);
}
else if (v1.Dot(v2) > 0.999999)
{
q = Quaternion(Float3(0.0f), 1);
}
else
{
q.imaginary.x = a.x;
q.imaginary.y = a.y;
q.imaginary.z = a.z;
q.real = (1 + v1.Dot(v2));
q.Normalize();
}
//Get Rotation from matrix
//float trace = this->privData->camera..v[0].x + trans.v[1].y + trans.v[2].z;
float trace = trans.v[0].x + trans.v[1].y + trans.v[2].z;
float temp[4];
if (trace > float(0.0))
{
float s = sqrt(trace + float(1.0));
temp[3]=(s * float(0.5));
s = float(0.5) / s;
temp[0]=((trans.v[2].y - trans.v[1].z) * s);
temp[1]=((trans.v[0].z - trans.v[2].x) * s);
temp[2]=((trans.v[1].x - trans.v[0].y) * s);
}
else
{
int i = trans.v[0].x < trans.v[1].y ?
(trans.v[1].y < trans.v[2].z ? 2 : 1) :
(trans.v[0].x < trans.v[2].z ? 2 : 0);
int j = (i + 1) % 3;
int k = (i + 2) % 3;
float s = sqrt(trans.v[i][i] - trans.v[j][j] - trans.v[k][k] + float(1.0));
temp[i] = s * float(0.5);
s = float(0.5) / s;
temp[3] = (trans.v[k][j] - trans.v[j][k]) * s;
temp[j] = (trans.v[j][i] + trans.v[i][j]) * s;
temp[k] = (trans.v[k][i] + trans.v[i][k]) * s;
}
Quaternion n = Quaternion(Float3(temp[0],temp[1],temp[2]),temp[3]);
newRotation = q * n;
this->privData->camera.SetRotation(newRotation);
}
void GameState::OnMouseMoveVelocity ( Input::Struct::SAIPointInt2D coordinate, Input::Mouse* sender )
{
auto it = this->privData->players.begin();
for (it; it != this->privData->players.end(); it++)
{
if(it->second->GetId() == this->privData->myId)
{
this->SetUp(it->second);
return;
}
}
}
*/

View File

@ -4,10 +4,12 @@
#include "OysterMath.h" #include "OysterMath.h"
#include <string> #include <string>
#include "GameStateUI.h" #include "GameStateUI.h"
#include "C_obj\C_Player.h"
namespace DanBias { namespace Client namespace DanBias { namespace Client
{ {
class GameState : public GameClientState class GameState : public GameClientState//, Input::Mouse::MouseEvent
{ {
public: public:
enum gameStateState enum gameStateState
@ -42,6 +44,10 @@ namespace DanBias { namespace Client
bool renderStats; bool renderStats;
// !DEGUG KEYS // !DEGUG KEYS
//:HACK!
//void OnMouseMoveVelocity ( Input::Struct::SAIPointInt2D coordinate, Input::Mouse* sender ) override;
//void SetUp( DanBias::Client::C_Player* p);
}; };
} } } }
#endif #endif

View File

@ -42,17 +42,4 @@ namespace DanBias { namespace Client
}; };
} } } }
namespace Utility { namespace DynamicMemory
{ // template specializationto allowuse of dynamicmemory tools
template<>
inline void SafeDeleteInstance( ::DanBias::Client::GameStateUI *dynamicInstance )
{
if( dynamicInstance )
{
dynamicInstance->Release();
delete dynamicInstance;
}
}
} }
#endif #endif

View File

@ -7,24 +7,25 @@ using namespace ::Oyster::Network;
using namespace ::GameLogic; using namespace ::GameLogic;
using namespace ::Utility::Value; using namespace ::Utility::Value;
using namespace ::Oyster::Math; using namespace ::Oyster::Math;
using namespace ::Input;
GamingUI::GamingUI() : GamingUI::GamingUI() :
GameStateUI() GameStateUI()
{ {
/* Should never be called! */ /* Should never be called! */
this->input = nullptr; this->sharedData = nullptr;
this->netClient = nullptr; this->camera = nullptr;
this->camera = nullptr; this->plane = nullptr;
this->plane = nullptr; this->text = nullptr;
this->text = nullptr; this->nextState = GameStateUI::UIState_same;
} }
GamingUI::GamingUI( InputClass *input, NetworkClient *connection, Camera_FPSV2 *camera ) : GamingUI::GamingUI( SharedStateContent* shared, Camera_FPSV2 *camera ) :
GameStateUI() GameStateUI()
{ {
this->input = input; this->sharedData = shared;
this->netClient = connection;
this->camera = camera; this->camera = camera;
this->nextState = GameStateUI::UIState_same;
} }
GamingUI::~GamingUI() { /* Do nothing */ } GamingUI::~GamingUI() { /* Do nothing */ }
@ -33,7 +34,14 @@ bool GamingUI::Init()
// z value should be between 0.5 - 0.9 so that it will be behind other states // z value should be between 0.5 - 0.9 so that it will be behind other states
// add textures and text // 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->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.3f,0.0f,0.1f), Float2(0.1f,0.1f)); this->text = new Text_UI(L"hej", Float3(0.5f,0.0f,0.1f), Float2(0.1f,0.1f));
this->sharedData = sharedData;
// setting input mode to all raw
this->sharedData->keyboardDevice->Activate();
this->sharedData->mouseDevice->Activate();
this->sharedData->mouseDevice->AddMouseEvent(this);
return true; return true;
} }
@ -70,6 +78,9 @@ bool GamingUI::Release()
delete this->plane; delete this->plane;
if(this->text) if(this->text)
delete this->text; delete this->text;
this->sharedData = 0;
return true; return true;
} }
void GamingUI::SetHPtext( std::wstring hp ) void GamingUI::SetHPtext( std::wstring hp )
@ -78,39 +89,39 @@ void GamingUI::SetHPtext( std::wstring hp )
} }
void GamingUI::ReadKeyInput() void GamingUI::ReadKeyInput()
{ {
if( this->input->IsKeyPressed(DIK_W) ) if( this->sharedData->keyboardDevice->IsKeyDown(::Input::Enum::SAKI_W) )
{ { // move forward
this->netClient->Send( Protocol_PlayerMovementForward() ); this->sharedData->network->Send( Protocol_PlayerMovementForward() );
} }
if( this->input->IsKeyPressed(DIK_S) ) if( this->sharedData->keyboardDevice->IsKeyDown(::Input::Enum::SAKI_S) )
{ { // move backward
this->netClient->Send( Protocol_PlayerMovementBackward() ); this->sharedData->network->Send( Protocol_PlayerMovementBackward() );
} }
if( this->input->IsKeyPressed(DIK_A) ) if( this->sharedData->keyboardDevice->IsKeyDown(::Input::Enum::SAKI_A) )
{ { // strafe left
this->netClient->Send( Protocol_PlayerMovementLeft() ); this->sharedData->network->Send( Protocol_PlayerMovementLeft() );
} }
if( this->input->IsKeyPressed(DIK_D) ) if( this->sharedData->keyboardDevice->IsKeyDown(::Input::Enum::SAKI_D) )
{ { // strafe right
this->netClient->Send( Protocol_PlayerMovementRight() ); this->sharedData->network->Send( Protocol_PlayerMovementRight() );
} }
//send delta mouse movement if( this->sharedData->keyboardDevice->IsKeyDown(::Input::Enum::SAKI_Space) )
{ { // jump
static const float mouseSensitivity = Radian( 1.0f ); if(!this->key_Jump)
this->camera->PitchDown( this->input->GetPitch() * mouseSensitivity );
float yaw = this->input->GetYaw();
//if( yaw != 0.0f ) //This made the camera reset to a specific rotation.
{ {
this->netClient->Send( Protocol_PlayerLeftTurn(yaw * mouseSensitivity, camera->GetLook()) ); this->sharedData->network->Send( Protocol_PlayerJump() );
this->key_Jump = true;
} }
} }
else
this->key_Jump = false;
// shoot // shoot
if( this->input->IsKeyPressed(DIK_Z) ) if( this->sharedData->mouseDevice->IsBtnDown(::Input::Enum::SAMI_MouseLeftBtn) )
{ {
if( !this->key_Shoot ) if( !this->key_Shoot )
{ {
@ -118,13 +129,14 @@ void GamingUI::ReadKeyInput()
playerShot.primaryPressed = true; playerShot.primaryPressed = true;
playerShot.secondaryPressed = false; playerShot.secondaryPressed = false;
playerShot.utilityPressed = false; playerShot.utilityPressed = false;
this->netClient->Send( playerShot ); this->sharedData->network->Send( playerShot );
this->key_Shoot = true; this->key_Shoot = true;
} }
} }
else else
this->key_Shoot = false; this->key_Shoot = false;
if( this->input->IsKeyPressed(DIK_X) )
if( this->sharedData->mouseDevice->IsBtnDown(::Input::Enum::SAMI_MouseRightBtn) )
{ {
if( !this->key_Shoot ) if( !this->key_Shoot )
{ {
@ -132,13 +144,14 @@ void GamingUI::ReadKeyInput()
playerShot.primaryPressed = false; playerShot.primaryPressed = false;
playerShot.secondaryPressed = true; playerShot.secondaryPressed = true;
playerShot.utilityPressed = false; playerShot.utilityPressed = false;
this->netClient->Send( playerShot ); this->sharedData->network->Send( playerShot );
this->key_Shoot = true; this->key_Shoot = true;
} }
} }
else else
this->key_Shoot = false; this->key_Shoot = false;
if( this->input->IsKeyPressed(DIK_C) )
if( this->sharedData->mouseDevice->IsBtnDown(::Input::Enum::SAMI_MouseMiddleBtn) )
{ {
if( !this->key_Shoot ) if( !this->key_Shoot )
{ {
@ -146,30 +159,31 @@ void GamingUI::ReadKeyInput()
playerShot.primaryPressed = false; playerShot.primaryPressed = false;
playerShot.secondaryPressed = false; playerShot.secondaryPressed = false;
playerShot.utilityPressed = true; playerShot.utilityPressed = true;
this->netClient->Send( playerShot ); this->sharedData->network->Send( playerShot );
this->key_Shoot = true; this->key_Shoot = true;
} }
} }
else else
this->key_Shoot = false; this->key_Shoot = false;
// jump if( this->sharedData->keyboardDevice->IsKeyDown(::Input::Enum::SAKI_Escape) )
if( this->input->IsKeyPressed(DIK_SPACE) )
{
if(!this->key_Jump)
{
this->netClient->Send( Protocol_PlayerJump() );
this->key_Jump = true;
}
}
else
this->key_Jump = false;
if( this->input->IsKeyPressed(DIK_ESCAPE) )
{ {
this->nextState = GameStateUI::UIState_shut_down; this->nextState = GameStateUI::UIState_shut_down;
} }
// !DEGUG KEYS
// TODO: implement sub-menu
} }
void GamingUI::OnMouseMoveVelocity ( Input::Struct::SAIPointInt2D coordinate, Input::Mouse* sender )
{
//send delta mouse movement
{
this->camera->PitchDown( (-coordinate.y) * this->sharedData->mouseSensitivity );
//this->camera->YawLeft( (-coordinate.x) * this->sharedData->mouseSensitivity );
//if( deltaPos.x != 0.0f ) //This made the camera reset to a specific rotation. Why?
{
this->sharedData->network->Send( Protocol_PlayerLeftTurn((coordinate.x) * this->sharedData->mouseSensitivity, this->camera->GetLook()) );
}
}
}

View File

@ -2,17 +2,19 @@
#define DANBIAS_CLIENT_GAMING_UI_H #define DANBIAS_CLIENT_GAMING_UI_H
#include "GameStateUI.h" #include "GameStateUI.h"
#include "L_inputClass.h" #include "Input.h"
#include "Camera_FPSV2.h" #include "Camera_FPSV2.h"
#include "Buttons\Text_UI.h" #include "Buttons\Text_UI.h"
#include "Buttons\Plane_UI.h" #include "Buttons\Plane_UI.h"
#include "InputManager.h"
#include "SharedStateContent.h"
namespace DanBias { namespace Client namespace DanBias { namespace Client
{ {
class GamingUI : public GameStateUI class GamingUI : public GameStateUI, Input::Mouse::MouseEvent
{ {
public: public:
GamingUI( InputClass *input, ::Oyster::Network::NetworkClient *connection, Camera_FPSV2 *camera ); GamingUI( SharedStateContent* shared, Camera_FPSV2 *camera );
virtual ~GamingUI(); virtual ~GamingUI();
bool Init(); bool Init();
@ -24,9 +26,17 @@ namespace DanBias { namespace Client
bool Release(); bool Release();
void SetHPtext( std::wstring hp ); void SetHPtext( std::wstring hp );
private: /* Overidden mouse methods */
void OnMouse ( const Input::Struct::MouseEventData& eventData ) override { }
void OnMousePress ( Input::Enum::SAMI key, Input::Mouse* sender ) override { }
void OnMouseDown ( Input::Enum::SAMI key, Input::Mouse* sender ) override { }
void OnMouseRelease ( Input::Enum::SAMI key, Input::Mouse* sender ) override { }
void OnMouseMovePixelPos ( Input::Struct::SAIPointInt2D coordinate, Input::Mouse* sender ) override { }
void OnMouseMoveVelocity ( Input::Struct::SAIPointInt2D coordinate, Input::Mouse* sender ) override;
void OnMouseScroll ( int delta, Input::Mouse* sender ) override { }
private: private:
InputClass *input; SharedStateContent *sharedData;
::Oyster::Network::NetworkClient *netClient;
Camera_FPSV2 *camera; Camera_FPSV2 *camera;
// TODO add multiple UI elements // TODO add multiple UI elements

View File

@ -31,8 +31,10 @@ struct LanMenuState::MyData
GameClientState::ClientState nextState; GameClientState::ClientState nextState;
NetworkClient *nwClient; NetworkClient *nwClient;
InputClass *input; ::Input::Mouse *mouseInput;
Graphics::API::Texture background; ::Input::Keyboard *keyboardInput;
Float3 mousePos;
Graphics::API::Texture background, mouseCursor;
EventButtonCollection guiElements; EventButtonCollection guiElements;
TextField<LanMenuState*> *connectIP; TextField<LanMenuState*> *connectIP;
@ -59,28 +61,29 @@ bool LanMenuState::Init( SharedStateContent &shared )
this->privData->nextState = GameClientState::ClientState_Same; this->privData->nextState = GameClientState::ClientState_Same;
this->privData->nwClient = shared.network; 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" ); this->privData->background = Graphics::API::CreateTexture( L"color_white.png" );
this->privData->mouseCursor = Graphics::API::CreateTexture( L"cursor.png" );
// create guiElements // create guiElements
this->privData->connectIP = new TextField<LanMenuState*>( L"color_white.png", Float4(1.0f), Float4(0.0f), this, Float3(0.5f, 0.3f, 0.5f), Float2(0.8f, 0.09f), ResizeAspectRatio_None ); this->privData->connectIP = new TextField<LanMenuState*>( L"noedge-btn-ipfield.png", Float4(1.0f), Float4(1.0f), this, Float3(0.5f, 0.2f, 0.9f), Float2(0.5f, 0.05f), ResizeAspectRatio_Height );
this->privData->connectIP->ReserveLines( 1 ); this->privData->connectIP->ReserveLines( 1 );
this->privData->connectIP->AppendText( L"127.0.0.1" ); this->privData->connectIP->AppendText( L"127.0.0.1" );
//this->privData->connectIP->AppendText( L"194.47.150.206" ); // HACK: connecting to Dennis's server //this->privData->connectIP->AppendText( L"194.47.150.206" ); // HACK: connecting to Dennis's server
//this->privData->connectIP->AppendText( L"194.47.150.189" ); // HACK: connecting to Robins server //this->privData->connectIP->AppendText( L"194.47.150.189" ); // HACK: connecting to Robins server
this->privData->connectIP->SetFontHeight( 0.035f );
this->privData->connectIP->SetFontHeight( 0.08f );
this->privData->connectIP->SetLineSpacing( 0.005f ); this->privData->connectIP->SetLineSpacing( 0.005f );
this->privData->connectIP->SetTopAligned(); this->privData->connectIP->SetBottomAligned();
this->privData->guiElements.AddButton( this->privData->connectIP ); this->privData->guiElements.AddButton( this->privData->connectIP );
ButtonRectangle<LanMenuState*> *guiElements; ButtonRectangle<LanMenuState*> *guiElements;
guiElements = new ButtonRectangle<LanMenuState*>( L"color_white.png", L"Connect", Float4(1.0f),Float4(0.0f),Float4(0.0f),Float4(0.0f), OnButtonInteract_Connect, this, Float3(0.5f, 0.4f, 0.5f), Float2(0.3f, 0.05f), ResizeAspectRatio_None ); guiElements = new ButtonRectangle<LanMenuState*>( L"noedge-btn-join.png", L"", Float4(1.0f),Float4(1.0f),Float4(1.2f),Float4(1.5f), OnButtonInteract_Connect, this, Float3(0.5f, 0.4f, 0.5f), Float2(0.5f, 0.18f), ResizeAspectRatio_None );
this->privData->guiElements.AddButton( guiElements ); this->privData->guiElements.AddButton( guiElements );
guiElements = new ButtonRectangle<LanMenuState*>( L"color_white.png", L"Exit", Float4(1.0f),Float4(0.0f),Float4(0.0f),Float4(0.0f), OnButtonInteract_Exit, this, Float3(0.5f, 0.5f, 0.5f), Float2(0.3f, 0.05f), ResizeAspectRatio_None ); guiElements = new ButtonRectangle<LanMenuState*>( L"noedge-btn-back.png", L"", Float4(1.0f),Float4(1.0f),Float4(1.2f),Float4(1.5f), OnButtonInteract_Exit, this, Float3(0.5f, 0.8f, 0.5f), Float2(0.5f, 0.18f), ResizeAspectRatio_None );
this->privData->guiElements.AddButton( guiElements ); this->privData->guiElements.AddButton( guiElements );
// bind guiElements collection to the singleton eventhandler // bind guiElements collection to the singleton eventhandler
@ -88,6 +91,9 @@ bool LanMenuState::Init( SharedStateContent &shared )
this->privData->connectPort = 15151; this->privData->connectPort = 15151;
this->privData->keyboardInput->BindTextTarget( &(*this->privData->connectIP)[0] );
this->privData->keyboardInput->Activate();
if(!this->privData->nwClient->StartListeningForBroadcasting(this->privData->connectPort)) if(!this->privData->nwClient->StartListeningForBroadcasting(this->privData->connectPort))
{ {
return false; return false;
@ -100,10 +106,13 @@ GameClientState::ClientState LanMenuState::Update( float deltaTime )
{ {
MouseInput mouseState; MouseInput mouseState;
{ {
this->privData->input->GetMousePos( mouseState.x, mouseState.y ); ::Input::Struct::SAIPointFloat2D pos;
mouseState.mouseButtonPressed = this->privData->input->IsMousePressed(); this->privData->mouseInput->GetNormalizedPosition( pos );
}
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 ); EventHandler::Instance().Update( mouseState );
this->privData->nwClient->Update(); this->privData->nwClient->Update();
@ -117,6 +126,7 @@ bool LanMenuState::Render( )
Graphics::API::StartGuiRender(); Graphics::API::StartGuiRender();
Graphics::API::RenderGuiElement( this->privData->mouseCursor, this->privData->mousePos, Float2(0.15f, 0.24), Float4(1.0f) );
Graphics::API::RenderGuiElement( this->privData->background, Float3(0.5f, 0.5f, 1.0f), Float2(1.0f) ); Graphics::API::RenderGuiElement( this->privData->background, Float3(0.5f, 0.5f, 1.0f), Float2(1.0f) );
this->privData->guiElements.RenderTexture(); this->privData->guiElements.RenderTexture();
@ -142,7 +152,7 @@ void LanMenuState::ChangeState( ClientState next )
{ {
switch( next ) switch( next )
{ {
case GameClientState::ClientState_Lobby: case GameClientState::ClientState_NetLoad:
// attempt to connect to lobby // attempt to connect to lobby
if( !this->privData->nwClient->Connect(this->privData->connectPort, (*this->privData->connectIP)[0]) ) if( !this->privData->nwClient->Connect(this->privData->connectPort, (*this->privData->connectIP)[0]) )
return; return;
@ -150,6 +160,8 @@ void LanMenuState::ChangeState( ClientState next )
default: break; default: break;
} }
this->privData->keyboardInput->ReleaseTextTarget();
this->privData->nextState = next; this->privData->nextState = next;
} }
@ -158,7 +170,7 @@ void OnButtonInteract_Connect( Oyster::Event::ButtonEvent<LanMenuState*>& e )
switch( e.state ) switch( e.state )
{ {
case ButtonState_Released: case ButtonState_Released:
e.owner->ChangeState( GameClientState::ClientState_Lobby ); e.owner->ChangeState( GameClientState::ClientState_NetLoad );
break; break;
default: break; default: break;
} }
@ -211,4 +223,4 @@ const GameClientState::NetEvent& LanMenuState::DataRecieved( const NetEvent &mes
return message; return message;
} }

View File

@ -22,7 +22,7 @@ struct LobbyAdminState::MyData
GameClientState::ClientState nextState; GameClientState::ClientState nextState;
NetworkClient *nwClient; NetworkClient *nwClient;
InputClass *input; ::Input::Mouse *mouseInput;
Graphics::API::Texture background; Graphics::API::Texture background;
EventButtonCollection guiElements; EventButtonCollection guiElements;
} privData; } privData;
@ -43,7 +43,7 @@ bool LobbyAdminState::Init( SharedStateContent &shared )
this->privData->nextState = GameClientState::ClientState_Same; this->privData->nextState = GameClientState::ClientState_Same;
this->privData->nwClient = shared.network; 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" ); 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 ) 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; MouseInput mouseState;
{ {
this->privData->input->GetMousePos( mouseState.x, mouseState.y ); ::Input::Struct::SAIPointInt2D pos;
mouseState.mouseButtonPressed = this->privData->input->IsMousePressed(); 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 ); EventHandler::Instance().Update( mouseState );
return this->privData->nextState; return this->privData->nextState;

View File

@ -22,8 +22,9 @@ struct LobbyState::MyData
GameClientState::ClientState nextState; GameClientState::ClientState nextState;
NetworkClient *nwClient; NetworkClient *nwClient;
InputClass *input; ::Input::Mouse *mouseInput;
Graphics::API::Texture background; Float3 mousePos;
Graphics::API::Texture background, mouseCursor;;
EventButtonCollection guiElements; EventButtonCollection guiElements;
} privData; } privData;
@ -43,9 +44,10 @@ bool LobbyState::Init( SharedStateContent &shared )
this->privData->nextState = GameClientState::ClientState_Same; this->privData->nextState = GameClientState::ClientState_Same;
this->privData->nwClient = shared.network; 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" ); this->privData->background = Graphics::API::CreateTexture( L"grass_md.png" );
this->privData->mouseCursor = Graphics::API::CreateTexture( L"cursor_md.png" );
// create buttons // create buttons
ButtonRectangle<LobbyState*> *button; ButtonRectangle<LobbyState*> *button;
@ -61,21 +63,15 @@ bool LobbyState::Init( SharedStateContent &shared )
GameClientState::ClientState LobbyState::Update( float deltaTime ) 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; MouseInput mouseState;
{ {
this->privData->input->GetMousePos( mouseState.x, mouseState.y ); ::Input::Struct::SAIPointFloat2D pos;
mouseState.mouseButtonPressed = this->privData->input->IsMousePressed(); this->privData->mouseInput->GetNormalizedPosition( pos );
}
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 ); EventHandler::Instance().Update( mouseState );
return this->privData->nextState; return this->privData->nextState;
@ -85,6 +81,7 @@ bool LobbyState::Render( )
Graphics::API::NewFrame(); Graphics::API::NewFrame();
Graphics::API::StartGuiRender(); Graphics::API::StartGuiRender();
Graphics::API::RenderGuiElement( this->privData->mouseCursor, this->privData->mousePos, Float2(0.01f), Float4(1.0f) );
Graphics::API::RenderGuiElement( this->privData->background, Float3(0.5f, 0.5f, 1.0f), Float2(1.0f) ); Graphics::API::RenderGuiElement( this->privData->background, Float3(0.5f, 0.5f, 1.0f), Float2(1.0f) );
this->privData->guiElements.RenderTexture(); this->privData->guiElements.RenderTexture();

View File

@ -9,6 +9,7 @@
#include "EventHandler\EventHandler.h" #include "EventHandler\EventHandler.h"
#include "Buttons\ButtonRectangle.h" #include "Buttons\ButtonRectangle.h"
#include "Buttons\ButtonEllipse.h"
using namespace ::DanBias::Client; using namespace ::DanBias::Client;
using namespace ::Oyster; using namespace ::Oyster;
@ -24,12 +25,14 @@ struct MainState::MyData
GameClientState::ClientState nextState; GameClientState::ClientState nextState;
NetworkClient *nwClient; NetworkClient *nwClient;
InputClass *input; ::Input::Mouse *mouseInput;
Graphics::API::Texture background; Float3 mousePos;
Graphics::API::Texture background, mouseCursor;
EventButtonCollection guiElements; EventButtonCollection guiElements;
}; };
void OnButtonInteract_Create( Oyster::Event::ButtonEvent<MainState*>& e ); void OnButtonInteract_Create( Oyster::Event::ButtonEvent<MainState*>& e );
void OnButtonInteract_Settings( Oyster::Event::ButtonEvent<MainState*>& e );
void OnButtonInteract_Join( Oyster::Event::ButtonEvent<MainState*>& e ); void OnButtonInteract_Join( Oyster::Event::ButtonEvent<MainState*>& e );
void OnButtonInteract_Quit( Oyster::Event::ButtonEvent<MainState*>& e ); void OnButtonInteract_Quit( Oyster::Event::ButtonEvent<MainState*>& e );
@ -47,24 +50,30 @@ bool MainState::Init( SharedStateContent &shared )
this->privData->nextState = GameClientState::ClientState_Same; this->privData->nextState = GameClientState::ClientState_Same;
this->privData->nwClient = shared.network; 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->background = Graphics::API::CreateTexture( L"color_white.png" );
this->privData->mouseCursor = Graphics::API::CreateTexture( L"cursor.png" );
// create buttons // create buttons
ButtonRectangle<MainState*> *button; ButtonRectangle<MainState*> *button;
Float4 TextCol = Float4(1.0f,0.0f,1.0f,1.0f); Float4 TextCol = Float4(0.1f,0.1f,0.1f,1.0f);
Float4 BackCol = Float4(1.0f,1.0f,1.0f,0.5f); Float4 BackCol = Float4(1.0f);
Float4 HoverCol = Float4(0.0f,1.0f,0.0f,1.0f); Float4 HoverCol = Float4(1.2f);
Float4 PressCol = Float4(0.0f,0.0f,1.0f,1.0f); Float4 PressCol = Float4(1.5f);
button = new ButtonRectangle<MainState*>( L"color_white.png", L"Create",TextCol, BackCol, HoverCol, PressCol, OnButtonInteract_Create, this, Float3(0.5f, 0.2f, 0.5f), Float2(0.3f, 0.1f)); //button = new ButtonRectangle<MainState*>( L"color_white.png", L"Create",TextCol, BackCol, HoverCol, PressCol, OnButtonInteract_Create, this, Float3(0.5f, 0.2f, 0.5f), Float2(0.3f, 0.1f));
//this->privData->guiElements.AddButton( button );
button = new ButtonRectangle<MainState*>( L"noedge-btn-lan.png", L"", TextCol, BackCol, HoverCol, PressCol, OnButtonInteract_Join, this, Float3(0.5f, 0.2f, 0.5f), Float2(0.5f, 0.18f));
this->privData->guiElements.AddButton( button ); this->privData->guiElements.AddButton( button );
button = new ButtonRectangle<MainState*>( L"color_white.png", L"Join", TextCol, BackCol, HoverCol, PressCol, OnButtonInteract_Join, this, Float3(0.5f, 0.4f, 0.5f), Float2(0.3f, 0.1f)); button = new ButtonRectangle<MainState*>( L"noedge-btn-settings.png", L"", TextCol, BackCol, HoverCol, PressCol, OnButtonInteract_Settings, this, Float3(0.5f, 0.4f, 0.5f), Float2(0.5f, 0.18f));
this->privData->guiElements.AddButton( button ); this->privData->guiElements.AddButton( button );
button = new ButtonRectangle<MainState*>( L"color_white.png", L"Quit", TextCol, BackCol, HoverCol, PressCol, OnButtonInteract_Quit, this, Float3(0.5f, 0.8f, 0.5f), Float2(0.3f, 0.1f)); button = new ButtonRectangle<MainState*>( L"noedge-btn-quit.png", L"", TextCol, BackCol, HoverCol, PressCol, OnButtonInteract_Quit, this, Float3(0.5f, 0.8f, 0.5f), Float2(0.5f, 0.18f));
this->privData->guiElements.AddButton( button ); this->privData->guiElements.AddButton( button );
// bind button collection to the singleton eventhandler // bind button collection to the singleton eventhandler
@ -77,16 +86,13 @@ GameClientState::ClientState MainState::Update( float deltaTime )
{ {
MouseInput mouseState; MouseInput mouseState;
{ {
bool test = this->privData->input->IsMousePressed(); ::Input::Struct::SAIPointFloat2D pos;
if(test) this->privData->mouseInput->GetNormalizedPosition( pos );
{ // HACK: debug trap still in use?
int i = 0;
};
this->privData->input->GetMousePos( mouseState.x, mouseState.y ); this->privData->mousePos.x = mouseState.x = pos.x;
mouseState.mouseButtonPressed = this->privData->input->IsMousePressed(); this->privData->mousePos.y = mouseState.y = pos.y;
mouseState.mouseButtonPressed = this->privData->mouseInput->IsBtnDown( ::Input::Enum::SAMI_MouseLeftBtn );
} }
EventHandler::Instance().Update( mouseState ); EventHandler::Instance().Update( mouseState );
return this->privData->nextState; return this->privData->nextState;
@ -97,7 +103,12 @@ bool MainState::Render()
Graphics::API::NewFrame(); Graphics::API::NewFrame();
Graphics::API::StartGuiRender(); Graphics::API::StartGuiRender();
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) ); if(this->privData->mouseInput->IsBtnDown(Input::Enum::SAMI_MouseLeftBtn))
Graphics::API::RenderGuiElement( this->privData->mouseCursor, this->privData->mousePos, Float2(0.15f), Float4(1.0f) );
else
Graphics::API::RenderGuiElement( this->privData->mouseCursor, this->privData->mousePos, Float2(0.15f, 0.24), Float4(1.0f) );
Graphics::API::RenderGuiElement( this->privData->background, Float3(0.5f, 0.5f, 0.9f), Float2(1.0f), Float4(0.0f, 0.0f, 0.0f, 1.0f) );
this->privData->guiElements.RenderTexture(); this->privData->guiElements.RenderTexture();
Graphics::API::StartTextRender(); Graphics::API::StartTextRender();
@ -112,6 +123,7 @@ bool MainState::Release()
if( this->privData ) if( this->privData )
{ {
Graphics::API::DeleteTexture( this->privData->background ); Graphics::API::DeleteTexture( this->privData->background );
Graphics::API::DeleteTexture( this->privData->mouseCursor );
EventHandler::Instance().ReleaseCollection( &this->privData->guiElements ); EventHandler::Instance().ReleaseCollection( &this->privData->guiElements );
this->privData = NULL; this->privData = NULL;
@ -136,6 +148,17 @@ void OnButtonInteract_Create( Oyster::Event::ButtonEvent<MainState*>& e )
} }
} }
void OnButtonInteract_Settings( Oyster::Event::ButtonEvent<MainState*>& e )
{
switch( e.state )
{
case ButtonState_Released:
//e.owner->ChangeState( GameClientState::ClientState_LobbyCreate );
break;
default: break;
}
}
void OnButtonInteract_Join( Oyster::Event::ButtonEvent<MainState*>& e ) void OnButtonInteract_Join( Oyster::Event::ButtonEvent<MainState*>& e )
{ {
switch( e.state ) switch( e.state )

View File

@ -144,7 +144,7 @@ void NetLoadState::LoadGame( const ::std::string &fileName )
desc.scale = oh->scale; desc.scale = oh->scale;
desc.visible = true; desc.visible = true;
C_StaticObj *staticObject = new C_StaticObj(); C_StaticObj *staticObject = new C_StaticObj(oh->specialTypeID);
if( staticObject->Init( desc ) ) if( staticObject->Init( desc ) )
{ {

View File

@ -15,7 +15,7 @@
#include "C_obj\C_DynamicObj.h" #include "C_obj\C_DynamicObj.h"
#include "C_Light.h" #include "C_Light.h"
#include "NetworkClient.h" #include "NetworkClient.h"
#include "L_inputClass.h" #include "Input.h"
namespace DanBias { namespace Client namespace DanBias { namespace Client
{ {
@ -26,7 +26,11 @@ namespace DanBias { namespace Client
::std::map<int, ::Utility::DynamicMemory::UniquePointer<::DanBias::Client::C_DynamicObj>> dynamicObjects; ::std::map<int, ::Utility::DynamicMemory::UniquePointer<::DanBias::Client::C_DynamicObj>> dynamicObjects;
::std::map<int, ::Utility::DynamicMemory::UniquePointer<::DanBias::Client::C_Light>> lights; ::std::map<int, ::Utility::DynamicMemory::UniquePointer<::DanBias::Client::C_Light>> lights;
::Oyster::Network::NetworkClient *network; ::Oyster::Network::NetworkClient *network;
InputClass* input;
::Input::Mouse *mouseDevice;
::Input::Keyboard *keyboardDevice;
float mouseSensitivity;
}; };
} } } }

View File

@ -55,7 +55,7 @@ namespace DanBias
}; };
static HRESULT InitDirect3D(); static HRESULT InitDirect3D();
static HRESULT InitInput(); static HRESULT InitInput( HWND handle );
static Result Update(float deltaTime); static Result Update(float deltaTime);
static HRESULT Render(); static HRESULT Render();

View File

@ -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 <vector>
#define NOMINMAX
#include <Windows.h>
#include <map>
/**
* 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<Win32Keyboard*> keyboard;
std::vector<Win32Mouse*> 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

View File

@ -1,7 +1,7 @@
#include "AttatchmentMassDriver.h" #include "AttatchmentMassDriver.h"
#include "PhysicsAPI.h" #include "PhysicsAPI.h"
#include "GameLogicStates.h" #include "GameLogicStates.h"
#include "Game.h"
using namespace GameLogic; using namespace GameLogic;
@ -48,6 +48,8 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage,
{ {
currentEnergy -= 90.0f; currentEnergy -= 90.0f;
ForcePush(usage,dt); ForcePush(usage,dt);
// add CD
((Game*)&Game::Instance())->onActionEventFnc(this->owner, WeaponAction::WeaponAction_PrimaryShoot);
} }
break; break;
@ -55,7 +57,9 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage,
if(currentEnergy >= 1.0f) if(currentEnergy >= 1.0f)
{ {
currentEnergy -= 1.0f; currentEnergy -= 1.0f;
ForcePull(usage,dt); ForcePull(usage,dt);
// add CD
((Game*)&Game::Instance())->onActionEventFnc(this->owner, WeaponAction::WeaponAction_SecondaryShoot);
} }
break; break;
@ -64,6 +68,8 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage,
{ {
currentEnergy -= 90.0f; currentEnergy -= 90.0f;
ForceZip(usage,dt); ForceZip(usage,dt);
// add CD
((Game*)&Game::Instance())->onActionEventFnc(this->owner, WeaponAction::WeaponAction_UtilityActivate);
} }
break; break;
} }

View File

@ -44,7 +44,6 @@ using namespace GameLogic;
realObjB = realObjA; realObjB = realObjA;
} }
switch (realObjB->GetObjectType()) switch (realObjB->GetObjectType())
{ {
case ObjectSpecialType::ObjectSpecialType_Generic: case ObjectSpecialType::ObjectSpecialType_Generic:
@ -69,7 +68,8 @@ using namespace GameLogic;
//player->playerState = PLAYER_STATE::PLAYER_STATE_WALKING; //player->playerState = PLAYER_STATE::PLAYER_STATE_WALKING;
break; break;
} }
// send collision event message
((Game*)&Game::Instance())->onCollisionEventFnc(player, CollisionEvent::CollisionEvent_BasicCollision);
//return Physics::ICustomBody::SubscriptMessage_none; //return Physics::ICustomBody::SubscriptMessage_none;
} }
@ -255,16 +255,18 @@ using namespace GameLogic;
{ {
//realobjA is the affectedObject, transfer this to realobjB //realobjA is the affectedObject, transfer this to realobjB
realObjB->SetAffectedBy(*realObjA->getAffectingPlayer()); realObjB->SetAffectedBy(*realObjA->getAffectingPlayer());
return;
} }
if(realObjB->getAffectingPlayer() != NULL && realObjA->getAffectingPlayer() == NULL) if(realObjB->getAffectingPlayer() != NULL && realObjA->getAffectingPlayer() == NULL)
{ {
//realobjB is the affectedObject, transfer this to realobjA //realobjB is the affectedObject, transfer this to realobjA
realObjA->SetAffectedBy(*realObjB->getAffectingPlayer()); realObjA->SetAffectedBy(*realObjB->getAffectingPlayer());
return;
} }
if(realObjA->getAffectingPlayer() != NULL && realObjB->getAffectingPlayer() != NULL) if(realObjA->getAffectingPlayer() != NULL && realObjB->getAffectingPlayer() != NULL && ( realObjA->getAffectingPlayer()->GetID() != realObjB->getAffectingPlayer()->GetID()))
{ {
//Both objects have a player affecting them, now use the special case //Both objects have a player affecting them, now use the special case
if(realObjA->GetRigidBody()->GetState().previousVelocity.GetMagnitude() > realObjB->GetRigidBody()->GetState().previousVelocity.GetMagnitude() ) if(realObjA->GetRigidBody()->GetState().previousVelocity.GetMagnitude() > realObjB->GetRigidBody()->GetState().previousVelocity.GetMagnitude() )
@ -368,14 +370,19 @@ using namespace GameLogic;
Object* a = (Object*)objA->GetCustomTag(); Object* a = (Object*)objA->GetCustomTag();
Object* b = (Object*)objB->GetCustomTag(); Object* b = (Object*)objB->GetCustomTag();
if(!a) if(!a)
return; return;
if(!b) if(!b)
return; return;
if(b->GetObjectType() == ObjectSpecialType_Player) if(b->GetObjectType() == ObjectSpecialType_Player)
{ {
((Pickup*)a)->OnCollision((Player*)(b)); //Only update if it is active. And if the player is alive
if(((Pickup*)a)->IsActive() && ((Player*)b)->GetState() != PLAYER_STATE_DEAD && ((Player*)b)->GetState() != PLAYER_STATE_DIED)
{
((Pickup*)a)->OnCollision((Player*)(b));
}
return;
} }
else if(a->GetObjectType() != ObjectSpecialType_Player) else if(a->GetObjectType() != ObjectSpecialType_Player)
{ {
@ -383,6 +390,10 @@ using namespace GameLogic;
//Do nothing. //Do nothing.
return; return;
} }
((Pickup*)b)->OnCollision((Player*)a); //Only update if it is active. And if the player is alive
if(((Pickup*)b)->IsActive() && ((Player*)a)->GetState() != PLAYER_STATE_DEAD && ((Player*)a)->GetState() != PLAYER_STATE_DIED)
{
((Pickup*)b)->OnCollision((Player*)a);
}
} }

View File

@ -90,11 +90,6 @@ void DynamicObject::Activate()
void DynamicObject::SetAffectedBy(Player &player) void DynamicObject::SetAffectedBy(Player &player)
{ {
this->affectedBy = &player; this->affectedBy = &player;
if(this->type != ObjectSpecialType::ObjectSpecialType_Player) //should not add itself to its own list if its a player
{
player.AddAffectedObject(*this);
}
} }
Player* DynamicObject::getAffectingPlayer() Player* DynamicObject::getAffectingPlayer()

View File

@ -182,12 +182,16 @@ void Game::SetDeadSubscription(GameEvent::ObjectDeadFunction functionPointer)
} }
void Game::SetActionSubscription(GameEvent::AnimationEventFunction functionPointer) void Game::SetActionSubscription(GameEvent::AnimationEventFunction functionPointer)
{ {
this->onPlayerActionEventFnc = functionPointer; this->onActionEventFnc = functionPointer;
} }
void Game::SetPickupSubscription(GameEvent::PickupEventFunction functionPointer) void Game::SetPickupSubscription(GameEvent::PickupEventFunction functionPointer)
{ {
this->onPickupEventFnc = functionPointer; this->onPickupEventFnc = functionPointer;
} }
void Game::SetCollisionSubscription(GameEvent::CollisionEventFunction functionPointer)
{
this->onCollisionEventFnc = functionPointer;
}
bool Game::Initiate() bool Game::Initiate()
{ {
API::Instance().Init(); API::Instance().Init();

View File

@ -87,6 +87,7 @@ namespace GameLogic
void SetDeadSubscription(GameEvent::ObjectDeadFunction functionPointer) override; void SetDeadSubscription(GameEvent::ObjectDeadFunction functionPointer) override;
void SetActionSubscription(GameEvent::AnimationEventFunction functionPointer) override; void SetActionSubscription(GameEvent::AnimationEventFunction functionPointer) override;
void SetPickupSubscription(GameEvent::PickupEventFunction functionPointer) override; void SetPickupSubscription(GameEvent::PickupEventFunction functionPointer) override;
void SetCollisionSubscription(GameEvent::CollisionEventFunction functionPointer) override;
bool Initiate() override; bool Initiate() override;
float GetFrameTime() const; float GetFrameTime() const;
@ -106,8 +107,9 @@ namespace GameLogic
GameEvent::ObjectHpFunction onDamageTakenFnc; GameEvent::ObjectHpFunction onDamageTakenFnc;
GameEvent::ObjectRespawnedFunction onRespawnFnc; GameEvent::ObjectRespawnedFunction onRespawnFnc;
GameEvent::ObjectDeadFunction onDeadFnc; GameEvent::ObjectDeadFunction onDeadFnc;
GameEvent::AnimationEventFunction onPlayerActionEventFnc; GameEvent::AnimationEventFunction onActionEventFnc;
GameEvent::PickupEventFunction onPickupEventFnc; GameEvent::PickupEventFunction onPickupEventFnc;
GameEvent::CollisionEventFunction onCollisionEventFnc;
}; };
} }

View File

@ -33,6 +33,7 @@ namespace GameLogic
typedef void(*ObjectDeadFunction)(IObjectData* victim, IObjectData* killer, float seconds); // Callback method that sends killer and death timer typedef void(*ObjectDeadFunction)(IObjectData* victim, IObjectData* killer, float seconds); // Callback method that sends killer and death timer
typedef void(*PickupEventFunction)(IObjectData* player, int pickupEffectID ); // Callback method that sends killer and death timer typedef void(*PickupEventFunction)(IObjectData* player, int pickupEffectID ); // Callback method that sends killer and death timer
typedef void(*AnimationEventFunction)(IObjectData* player, int actionID ); // Callback method that sends killer and death timer typedef void(*AnimationEventFunction)(IObjectData* player, int actionID ); // Callback method that sends killer and death timer
typedef void(*CollisionEventFunction)(IObjectData*object, int collisionID);
//etc... //etc...
}; };
@ -188,7 +189,7 @@ namespace GameLogic
virtual void SetDeadSubscription(GameEvent::ObjectDeadFunction functionPointer) = 0; virtual void SetDeadSubscription(GameEvent::ObjectDeadFunction functionPointer) = 0;
virtual void SetActionSubscription(GameEvent::AnimationEventFunction functionPointer) = 0; virtual void SetActionSubscription(GameEvent::AnimationEventFunction functionPointer) = 0;
virtual void SetPickupSubscription(GameEvent::PickupEventFunction functionPointer) = 0; virtual void SetPickupSubscription(GameEvent::PickupEventFunction functionPointer) = 0;
virtual void SetCollisionSubscription(GameEvent::CollisionEventFunction functionPointer) = 0;
}; };
} }

View File

@ -16,12 +16,11 @@ using namespace Oyster::Math;
Level::Level(void) Level::Level(void)
{ {
objID = 100; srand (time(NULL));
objIDCounter = 100;
} }
Level::~Level(void) Level::~Level(void)
{ {
delete this->levelObj;
this->levelObj = NULL;
} }
Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody) Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
{ {
@ -31,7 +30,7 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
{ {
case ObjectSpecialType_None: case ObjectSpecialType_None:
{ {
gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
@ -49,22 +48,22 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
float worldSize = ((WorldAttributes*)obj)->worldSize; float worldSize = ((WorldAttributes*)obj)->worldSize;
float atmosphereSize = ((WorldAttributes*)obj)->atmoSphereSize; float atmosphereSize = ((WorldAttributes*)obj)->atmoSphereSize;
gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_Building: case ObjectSpecialType_Building:
{ {
gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_Stone: case ObjectSpecialType_Stone:
{ {
gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_StandardBox: case ObjectSpecialType_StandardBox:
{ {
gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_RedExplosiveBox: case ObjectSpecialType_RedExplosiveBox:
@ -72,7 +71,7 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
Oyster::Math::Float dmg = 120; Oyster::Math::Float dmg = 120;
Oyster::Math::Float force = 500; Oyster::Math::Float force = 500;
Oyster::Math::Float radie = 3; Oyster::Math::Float radie = 3;
gameObj = new ExplosiveCrate(rigidBody, (ObjectSpecialType)obj->specialTypeID, objID++, dmg, force, radie); gameObj = new ExplosiveCrate(rigidBody, (ObjectSpecialType)obj->specialTypeID, objIDCounter, dmg, force, radie);
} }
break; break;
//case ObjectSpecialType_BlueExplosiveBox: //case ObjectSpecialType_BlueExplosiveBox:
@ -81,24 +80,24 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
// break; // break;
case ObjectSpecialType_SpikeBox: case ObjectSpecialType_SpikeBox:
{ {
gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_Spike: case ObjectSpecialType_Spike:
{ {
gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_CrystalFormation: case ObjectSpecialType_CrystalFormation:
{ {
int dmg = 50; int dmg = 50;
//gameObj = new Crystal(rigidBody); //gameObj = new Crystal(rigidBody);
gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_CrystalShard: case ObjectSpecialType_CrystalShard:
{ {
gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_JumpPad: case ObjectSpecialType_JumpPad:
@ -106,39 +105,28 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
float power = 500; //((JumpPadAttributes*)obj)->power; float power = 500; //((JumpPadAttributes*)obj)->power;
Oyster::Math::Float3 dir = ((JumpPadAttributes*)obj)->direction; Oyster::Math::Float3 dir = ((JumpPadAttributes*)obj)->direction;
Oyster::Math::Float3 pushForce = dir * power; Oyster::Math::Float3 pushForce = dir * power;
gameObj = new JumpPad(rigidBody, (ObjectSpecialType)obj->specialTypeID, objID , pushForce); gameObj = new JumpPad(rigidBody, (ObjectSpecialType)obj->specialTypeID, objIDCounter , pushForce);
} }
break; break;
case ObjectSpecialType_Portal: case ObjectSpecialType_Portal:
{ {
Oyster::Math::Float3 destination = ((PortalAttributes*)obj)->destination; Oyster::Math::Float3 destination = ((PortalAttributes*)obj)->destination;
gameObj = new Portal(rigidBody, (ObjectSpecialType)obj->specialTypeID, objID, destination); gameObj = new Portal(rigidBody, (ObjectSpecialType)obj->specialTypeID, objIDCounter, destination);
}
break;
//case ObjectSpecialType_SpawnPoint:
//{
// save
//}
break;
case ObjectSpecialType_Player:
{
// should not be read from the lvl format
} }
break; break;
case ObjectSpecialType_Generic: case ObjectSpecialType_Generic:
{ {
gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
case ObjectSpecialType_PickupHealth: case ObjectSpecialType_PickupHealth:
{ {
gameObj = new PickupHealth(rigidBody, obj->specialTypeID, objID, ((PickupHealthAttributes*)obj)->spawnTime, ((PickupHealthAttributes*)obj)->healthValue); gameObj = new PickupHealth(rigidBody, obj->specialTypeID, objIDCounter, ((PickupHealthAttributes*)obj)->spawnTime, ((PickupHealthAttributes*)obj)->healthValue);
} }
break; break;
default: default:
{ {
gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); gameObj = new StaticObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objIDCounter);
} }
break; break;
} }
@ -237,7 +225,9 @@ ICustomBody* Level::InitRigidBodyMesh( const ObjectHeader* obj)
//rigidBodyRadius = (obj->scale[0] * obj->scale[1] * obj->scale[2]) * obj->boundingVolume.sphere.radius; //rigidBodyRadius = (obj->scale[0] * obj->scale[1] * obj->scale[2]) * obj->boundingVolume.sphere.radius;
//create the rigid body //create the rigid body
rigidBody = API::Instance().AddTriangleMesh(obj->boundingVolume.cgMesh.filename, rigidWorldRotation , rigidWorldPos , rigidBodyMass, obj->boundingVolume.cgMesh.restitutionCoeff , obj->boundingVolume.cgMesh.frictionCoeffStatic , obj->boundingVolume.cgMesh.frictionCoeffDynamic); std::wstring fname = L"..\\Content\\Worlds\\cgf\\";
fname.append(obj->boundingVolume.cgMesh.filename);
rigidBody = API::Instance().AddTriangleMesh( fname , rigidWorldRotation , rigidWorldPos , rigidBodyMass, obj->boundingVolume.cgMesh.restitutionCoeff , obj->boundingVolume.cgMesh.frictionCoeffStatic , obj->boundingVolume.cgMesh.frictionCoeffDynamic);
return rigidBody; return rigidBody;
} }
bool Level::InitiateLevel(std::wstring levelPath) bool Level::InitiateLevel(std::wstring levelPath)
@ -262,7 +252,7 @@ bool Level::InitiateLevel(std::wstring levelPath)
for (int i = 0; i < objCount; i++) for (int i = 0; i < objCount; i++)
{ {
++this->objID; ++this->objIDCounter;
ObjectTypeHeader* obj = objects.at(i); ObjectTypeHeader* obj = objects.at(i);
switch (obj->typeID) switch (obj->typeID)
{ {
@ -270,6 +260,7 @@ bool Level::InitiateLevel(std::wstring levelPath)
{ {
LevelMetaData* LevelObjData = ((LevelMetaData*)obj); LevelMetaData* LevelObjData = ((LevelMetaData*)obj);
std::string levelName = LevelObjData->levelName; std::string levelName = LevelObjData->levelName;
// LevelObjData->worldSize; // LevelObjData->worldSize;
} }
break; break;
@ -370,71 +361,6 @@ bool Level::InitiateLevel(std::wstring levelPath)
return true; return true;
} }
bool Level::InitiateLevel(float radius)
{
API::Instance().SetGravityPoint(Oyster::Math3D::Float3(0,0,0));
API::Instance().SetGravity(200);
int idCount = 100;
// add level sphere
ICustomBody* rigidBody = API::Instance().AddCollisionSphere(599.2f, Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(0, 0, 0), 0, 0.5f, 0.8f, 0.6f);
levelObj = new StaticObject(rigidBody, LevelCollisionAfter, ObjectSpecialType_World, idCount++);
//this->levelObj->objectID = idCount++;
rigidBody->SetCustomTag(levelObj);
ICustomBody* rigidBody_TestBox;
int nrOfBoxex = 5;
int offset = 0;
for(int i =0; i< nrOfBoxex; i ++)
{
rigidBody_TestBox = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0.0f, 0.0f, 0.0f, 1.0f), Oyster::Math::Float3(0.0f, 605.0f + i*5.0f, 10.0f), 5.0f, 0.5f, 0.8f, 0.6f);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox, Object::DefaultOnCollision, ObjectSpecialType_StandardBox, idCount++));
}
/*offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++)
{
rigidBody_TestBox = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(0,5, -605 -( i*5)), 5);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultOnCollision, OBJECT_TYPE::OBJECT_TYPE_BOX));
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]);
}
offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++)
{
rigidBody_TestBox = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(200, 620 + ( i*7), 0), 5);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultOnCollision, OBJECT_TYPE::OBJECT_TYPE_BOX));
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]);
}
offset += nrOfBoxex;
for(int i =0; i< nrOfBoxex; i ++)
{
rigidBody_TestBox = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(5, 605 + i*5, 0), 5);
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultOnCollision, OBJECT_TYPE::OBJECT_TYPE_BOX));
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]);
}*/
// add crystal
ICustomBody* rigidBody_Crystal = API::Instance().AddCollisionBox(Oyster::Math::Float3(0.5f, 0.5f, 0.5f), Oyster::Math::Float4(0.0f, 0.0f, 0.0f, 1.0f), Oyster::Math::Float3(10.0f, 605.0f, 0.0f), 5.0f, 0.5f, 0.8f, 0.6f);
this->dynamicObjects.Push(new DynamicObject(rigidBody_Crystal, Object::DefaultOnCollision, ObjectSpecialType_StandardBox, idCount++));
// add house
ICustomBody* rigidBody_House =API::Instance().AddCollisionBox(Oyster::Math::Float3(20.0f, 20.0f, 20.0f), Oyster::Math::Float4(0.0f, 0.0f, 0.0f, 1.0f), Oyster::Math::Float3(-50.0f, 590.0f, 0.0f), 0.0f, 0.5f, 0.8f, 0.6f);
this->staticObjects.Push(new StaticObject(rigidBody_House, Object::DefaultOnCollision, ObjectSpecialType_Generic, idCount++));
// add jumppad
ICustomBody* rigidBody_Jumppad = API::Instance().AddCollisionBox(Oyster::Math::Float3(1.0f, 1.0f, 1.0f), Oyster::Math::Float4(0.0f, 0.0f, 0.0f, 1.0f), Oyster::Math::Float3(4.0f, 600.3f, 0.0f), 5.0f, 0.5f, 0.8f, 0.6f);
this->staticObjects.Push(new JumpPad(rigidBody_Jumppad, ObjectSpecialType_JumpPad,idCount++ ,Oyster::Math::Float3(0,2000,0)));
return true;
}
void Level::AddPlayerToTeam(Player *player, int teamID) void Level::AddPlayerToTeam(Player *player, int teamID)
{ {
@ -442,6 +368,15 @@ void Level::AddPlayerToTeam(Player *player, int teamID)
} }
void Level::AddPlayerToGame(Player *player) void Level::AddPlayerToGame(Player *player)
{ {
for(int i = 0; i < (int)this->playerObjects.Size(); i++)
{
if (!this->playerObjects[i])
{
this->playerObjects[i] = player;
return;
}
}
// if no free space, allocate a new spot
this->playerObjects.Push(player); this->playerObjects.Push(player);
} }
void Level::RemovePlayerFromGame(Player *player) void Level::RemovePlayerFromGame(Player *player)
@ -450,7 +385,7 @@ void Level::RemovePlayerFromGame(Player *player)
{ {
if ((Player*)this->playerObjects[i] == player) if ((Player*)this->playerObjects[i] == player)
{ {
//this->playerObjects[i]. this->playerObjects[i] = nullptr;
} }
} }
} }
@ -463,14 +398,22 @@ void Level::RespawnPlayer(Player *player)
{ {
//this->teamManager.RespawnPlayerRandom(player); //this->teamManager.RespawnPlayerRandom(player);
Float3 spawnPoint = spawnPoints[0]; int i = rand() % spawnPoints.Size();
Float3 spawnPoint = spawnPoints[i];
player->Respawn(spawnPoint); player->Respawn(spawnPoint);
} }
void Level::Update(float deltaTime) void Level::Update(float deltaTime)
{ {
// update lvl-things // update lvl-things
for(int i = 0; i < (int)this->playerObjects.Size(); i++) for(int i = 0; i < (int)this->playerObjects.Size(); i++)
{ {
if(this->playerObjects[i]->getAffectingPlayer() != NULL)
{
}
if (this->playerObjects[i]->GetState() == PLAYER_STATE::PLAYER_STATE_DEAD) if (this->playerObjects[i]->GetState() == PLAYER_STATE::PLAYER_STATE_DEAD)
{ {
// true when timer reaches 0 // true when timer reaches 0
@ -481,9 +424,41 @@ void Level::Update(float deltaTime)
{ {
this->playerObjects[i]->setDeathTimer(DEATH_TIMER); this->playerObjects[i]->setDeathTimer(DEATH_TIMER);
// HACK to avoid crasch. affected by tag is NULL // HACK to avoid crasch. affected by tag is NULL
//((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], this->playerObjects[i], DEATH_TIMER); // add killer ID
Player* killer = this->playerObjects[i]->getAffectingPlayer(); Player* killer = this->playerObjects[i]->getAffectingPlayer();
((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], this->playerObjects[i], DEATH_TIMER); // add killer ID if(!killer) //if there is no killer then you commited suicide
//((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], this->playerObjects[i]->getAffectingPlayer(), DEATH_TIMER); // add killer ID {
killer = this->playerObjects[i];
}
((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], killer, DEATH_TIMER); // add killer ID
}
}
for(int i = 0; i < dynamicObjects.Size(); i++)
{
if(dynamicObjects[i]->getAffectingPlayer() != NULL)
{
Oyster::Math::Float vel = dynamicObjects[i]->GetRigidBody()->GetLinearVelocity().GetMagnitude();
if(vel <= 0.1f) // is bearly moving
{
//set the tag AffectedBy to NULL
dynamicObjects[i]->RemoveAffectedBy();
}
}
}
for(int i = 0; i < playerObjects.Size(); i++)
{
if(playerObjects[i]->getAffectingPlayer() != NULL)
{
Oyster::Math::Float vel = playerObjects[i]->GetRigidBody()->GetLinearVelocity().GetMagnitude();
if(vel <= 0.1f) // is bearly moving
{
//set the tag AffectedBy to NULL
playerObjects[i]->RemoveAffectedBy();
}
} }
} }
@ -509,7 +484,7 @@ void Level::PhysicsOnMoveLevel(const ICustomBody *object)
Object* temp = (Object*)object->GetCustomTag(); Object* temp = (Object*)object->GetCustomTag();
((Game*)&Game::Instance())->onMoveFnc(temp); ((Game*)&Game::Instance())->onMoveFnc(temp);
} }
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<Player>> Level::GetPlayers() Utility::DynamicMemory::DynamicArray<Player*> Level::GetPlayers()
{ {
return this->playerObjects; return this->playerObjects;
} }

View File

@ -35,7 +35,6 @@ namespace GameLogic
* @param levelPath: Path to a file that contains all information on the level * @param levelPath: Path to a file that contains all information on the level
********************************************************/ ********************************************************/
bool InitiateLevel(std::wstring levelPath); bool InitiateLevel(std::wstring levelPath);
bool InitiateLevel(float radius);
Oyster::Physics::ICustomBody* InitRigidBodyCube( const ObjectHeader* obj); Oyster::Physics::ICustomBody* InitRigidBodyCube( const ObjectHeader* obj);
Oyster::Physics::ICustomBody* InitRigidBodySphere( const ObjectHeader* obj); Oyster::Physics::ICustomBody* InitRigidBodySphere( const ObjectHeader* obj);
Oyster::Physics::ICustomBody* InitRigidBodyMesh( const ObjectHeader* obj); Oyster::Physics::ICustomBody* InitRigidBodyMesh( const ObjectHeader* obj);
@ -79,19 +78,19 @@ namespace GameLogic
static void PlayerDied( Player* player ); static void PlayerDied( Player* player );
static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object); static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object);
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<Player>> GetPlayers(); Utility::DynamicMemory::DynamicArray<Player*> GetPlayers();
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> GetStaticObjects(); Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> GetStaticObjects();
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> GetDynamicObject(); Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> GetDynamicObject();
private: private:
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<Player>> playerObjects; Utility::DynamicMemory::DynamicArray<Player*> playerObjects;
TeamManager teamManager; TeamManager teamManager;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> staticObjects; Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> staticObjects;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> dynamicObjects; Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> dynamicObjects;
GameModeType gameMode; GameModeType gameMode;
Utility::DynamicMemory::SmartPointer<Oyster::Physics::ICustomBody> rigidBodyLevel; //Utility::DynamicMemory::SmartPointer<Oyster::Physics::ICustomBody> rigidBodyLevel;
StaticObject *levelObj; // //StaticObject *levelObj;
int objID; int objIDCounter;
Utility::DynamicMemory::DynamicArray<Oyster::Math::Float3> spawnPoints; Utility::DynamicMemory::DynamicArray<Oyster::Math::Float3> spawnPoints;
PickupSystem pickupSystem; PickupSystem pickupSystem;

View File

@ -9,6 +9,7 @@ Pickup::Pickup(Oyster::Physics::ICustomBody *rigidBody, EventOnCollision collisi
this->active = true; this->active = true;
this->spawnTime = spawnTime; this->spawnTime = spawnTime;
timer.reset(); timer.reset();
this->GetRigidBody()->MoveToLimbo();
} }
Pickup::~Pickup() Pickup::~Pickup()

View File

@ -1,4 +1,5 @@
#include "PickupHealth.h" #include "PickupHealth.h"
#include "../Game.h"
using namespace GameLogic; using namespace GameLogic;
@ -14,5 +15,8 @@ PickupHealth::~PickupHealth()
void PickupHealth::OnCollision(Player *player) void PickupHealth::OnCollision(Player *player)
{ {
timer.reset(); timer.reset();
((Game*)&Game::Instance())->onDisableFnc(this);
this->active = false;
player->DamageLife(-hpValue); player->DamageLife(-hpValue);
} }

View File

@ -8,11 +8,11 @@ using namespace GameLogic;
using namespace Oyster::Physics; using namespace Oyster::Physics;
const float MOVE_FORCE = 30; const float MOVE_FORCE = 30;
const float KEY_TIMER = 0.03f; const float KEY_TIMER = 0.03f;
const float AFFECTED_TIMER = 1.0f;
Player::Player() Player::Player()
:DynamicObject() :DynamicObject()
{ {
Player::initPlayerData(); Player::initPlayerData();
AffectedObjects.Reserve(15);
this->weapon = NULL; this->weapon = NULL;
this->teamID = -1; this->teamID = -1;
} }
@ -22,7 +22,6 @@ Player::Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision)
{ {
this->weapon = new Weapon(2,this); this->weapon = new Weapon(2,this);
Player::initPlayerData(); Player::initPlayerData();
AffectedObjects.Reserve(15);
this->teamID = teamID; this->teamID = teamID;
} }
@ -31,16 +30,15 @@ Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustom
{ {
this->weapon = new Weapon(2,this); this->weapon = new Weapon(2,this);
Player::initPlayerData(); Player::initPlayerData();
AffectedObjects.Reserve(15);
this->teamID = teamID; this->teamID = teamID;
} }
Player::~Player(void) Player::~Player(void)
{ {
if(weapon) if(this->weapon)
{ {
delete weapon; delete this->weapon;
weapon = NULL; this->weapon = NULL;
} }
} }
void Player::initPlayerData() void Player::initPlayerData()
@ -57,7 +55,7 @@ void Player::initPlayerData()
this->key_strafeRight = 0; this->key_strafeRight = 0;
this->key_strafeLeft = 0; this->key_strafeLeft = 0;
this->key_jump = 0; this->key_jump = 0;
this->invincibleCooldown = 0; this->RecentlyAffected = 0;
this->deathTimer = 0; this->deathTimer = 0;
this->rotationUp = 0; this->rotationUp = 0;
@ -65,16 +63,19 @@ void Player::initPlayerData()
void Player::BeginFrame() void Player::BeginFrame()
{ {
if( this->playerState != PLAYER_STATE_DEAD && PLAYER_STATE_DIED) if( this->playerState != PLAYER_STATE_DEAD && this->playerState != PLAYER_STATE_DIED)
{ {
weapon->Update(0.002f); weapon->Update(0.002f);
Oyster::Math::Float maxSpeed = 30; Oyster::Math::Float maxSpeed = 30;
// Rotate player accordingly // Rotate player accordingly
this->rigidBody->AddRotationAroundY(this->rotationUp); this->rigidBody->AddRotationAroundY(this->rotationUp);
this->rigidBody->SetUp(this->rigidBody->GetState().centerPos.GetNormalized()); this->rigidBody->SetUp(this->rigidBody->GetState().centerPos.GetNormalized());
this->rotationUp = 0;
// Direction data // Direction data
Oyster::Math::Float4x4 xform; Oyster::Math::Float4x4 xform;
xform = this->rigidBody->GetState().GetOrientation(); xform = this->rigidBody->GetState().GetOrientation();
@ -138,7 +139,7 @@ void Player::BeginFrame()
if(this->playerState != PLAYER_STATE::PLAYER_STATE_JUMPING) if(this->playerState != PLAYER_STATE::PLAYER_STATE_JUMPING)
{ {
if(this->playerState != PLAYER_STATE::PLAYER_STATE_IDLE) if(this->playerState != PLAYER_STATE::PLAYER_STATE_IDLE)
this->gameInstance->onPlayerActionEventFnc( this, PlayerAction::PlayerAction_Idle); this->gameInstance->onActionEventFnc( this, PlayerAction::PlayerAction_Idle);
this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
} }
} }
@ -174,7 +175,7 @@ void Player::BeginFrame()
if(this->playerState != PLAYER_STATE::PLAYER_STATE_JUMPING) if(this->playerState != PLAYER_STATE::PLAYER_STATE_JUMPING)
{ {
if(this->playerState != PLAYER_STATE::PLAYER_STATE_WALKING) if(this->playerState != PLAYER_STATE::PLAYER_STATE_WALKING)
this->gameInstance->onPlayerActionEventFnc( this, PlayerAction::PlayerAction_Walk); this->gameInstance->onActionEventFnc( this, PlayerAction::PlayerAction_Walk);
this->playerState = PLAYER_STATE::PLAYER_STATE_WALKING; this->playerState = PLAYER_STATE::PLAYER_STATE_WALKING;
} }
} }
@ -189,14 +190,14 @@ void Player::BeginFrame()
//Jump //Jump
if(key_jump > 0.001) if(key_jump > 0.001)
{ {
this->key_jump -= this->gameInstance->GetFrameTime(); this->key_jump -= this->gameInstance->GetFrameTime();
if(IsWalking()) if(IsWalking())
{ {
Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.GetNormalized(); Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.GetNormalized();
this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass * 20); this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass * 20);
if(this->playerState != PLAYER_STATE::PLAYER_STATE_JUMPING) if(this->playerState != PLAYER_STATE::PLAYER_STATE_JUMPING)
this->gameInstance->onPlayerActionEventFnc( this, PlayerAction::PlayerAction_Jump); this->gameInstance->onActionEventFnc( this, PlayerAction::PlayerAction_Jump);
this->playerState = PLAYER_STATE::PLAYER_STATE_JUMPING; this->playerState = PLAYER_STATE::PLAYER_STATE_JUMPING;
} }
} }
@ -204,7 +205,7 @@ void Player::BeginFrame()
{ {
if(this->playerState == PLAYER_STATE::PLAYER_STATE_JUMPING) if(this->playerState == PLAYER_STATE::PLAYER_STATE_JUMPING)
{ {
this->gameInstance->onPlayerActionEventFnc( this, PlayerAction::PlayerAction_Idle); this->gameInstance->onActionEventFnc( this, PlayerAction::PlayerAction_Idle);
this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
} }
} }
@ -213,16 +214,6 @@ void Player::BeginFrame()
void Player::EndFrame() void Player::EndFrame()
{ {
//check if there are any objects that can be removed from the AffectedObjects list
for(int i = 0; i < this->AffectedObjects.Size(); i++)
{
if(this->AffectedObjects[i] && (this->AffectedObjects[i]->GetRigidBody()->GetState().previousVelocity).GetMagnitude() <= 0.1f)
{
this->AffectedObjects[i]->RemoveAffectedBy();
this->AffectedObjects.Remove(i);
}
}
} }
void Player::Move(const PLAYER_MOVEMENT &movement) void Player::Move(const PLAYER_MOVEMENT &movement)
@ -292,7 +283,7 @@ void Player::SetLookDir(const Oyster::Math3D::Float3& lookDir)
} }
void Player::TurnLeft(Oyster::Math3D::Float deltaRadians) void Player::TurnLeft(Oyster::Math3D::Float deltaRadians)
{ {
this->rotationUp = deltaRadians; this->rotationUp += deltaRadians;
} }
void Player::Jump() void Player::Jump()
@ -341,32 +332,24 @@ PLAYER_STATE Player::GetState() const
void Player::DamageLife(int damage) void Player::DamageLife(int damage)
{ {
this->playerStats.hp -= damage; if(damage != 0)
// send hp to client
this->gameInstance->onDamageTakenFnc( this, this->playerStats.hp);
if(this->playerStats.hp <= 0)
{ {
this->playerStats.hp = 0; this->playerStats.hp -= damage;
this->playerState = PLAYER_STATE_DIED;
}
} if(this->playerStats.hp > 100)
this->playerStats.hp = 100;
void Player::AddAffectedObject(DynamicObject &AffectedObject) // send hp to client
{ this->gameInstance->onDamageTakenFnc( this, this->playerStats.hp);
//check if object already exists in the list, if so then do not add
for(int i = 0; i < AffectedObjects.Size(); i++) if(this->playerStats.hp <= 0)
{
if(AffectedObjects[i]->GetID() == AffectedObject.GetID())
{ {
//object already exists, exit function this->playerStats.hp = 0;
return; this->playerState = PLAYER_STATE_DIED;
} }
} }
//else you add the object to the stack
AffectedObjects.Push(&AffectedObject);
} }
bool Player::deathTimerTick(float dt) bool Player::deathTimerTick(float dt)
{ {
this->deathTimer -= dt; this->deathTimer -= dt;

View File

@ -67,8 +67,6 @@ namespace GameLogic
void SetLookDir(const Oyster::Math3D::Float3& lookDir); void SetLookDir(const Oyster::Math3D::Float3& lookDir);
void TurnLeft(Oyster::Math3D::Float deltaRadians); void TurnLeft(Oyster::Math3D::Float deltaRadians);
void AddAffectedObject(DynamicObject &AffectedObject);
/******************************************************** /********************************************************
* Collision function for player, this is to be sent to physics through the subscribe function with the rigidbody * Collision function for player, this is to be sent to physics through the subscribe function with the rigidbody
@ -90,6 +88,7 @@ namespace GameLogic
Oyster::Math::Float4x4 GetOrientation() const; Oyster::Math::Float4x4 GetOrientation() const;
int GetTeamID() const; int GetTeamID() const;
PLAYER_STATE GetState() const; PLAYER_STATE GetState() const;
Oyster::Math::Float GetRecentlyAffected();
void DamageLife(int damage); void DamageLife(int damage);
void setDeathTimer(float deathTimer); void setDeathTimer(float deathTimer);
@ -104,8 +103,6 @@ namespace GameLogic
void initPlayerData(); void initPlayerData();
private: private:
Utility::DynamicMemory::DynamicArray<DynamicObject*> AffectedObjects;
int teamID; int teamID;
Weapon *weapon; Weapon *weapon;
PLAYER_STATE playerState; PLAYER_STATE playerState;
@ -122,7 +119,7 @@ namespace GameLogic
float deathTimer; float deathTimer;
bool hasTakenDamage; bool hasTakenDamage;
float invincibleCooldown; Oyster::Math::Float RecentlyAffected;
PlayerStats playerStats; PlayerStats playerStats;
PlayerScore playerScore; PlayerScore playerScore;

View File

@ -969,7 +969,7 @@ namespace GameLogic
Oyster::Network::CustomNetProtocol protocol; Oyster::Network::CustomNetProtocol protocol;
}; };
} }
//#define protocol_Gameplay_ObjectAction 369 //#define protocol_Gameplay_ObjectAction 369
struct Protocol_ObjectAction :public Oyster::Network::CustomProtocolObject struct Protocol_ObjectAction :public Oyster::Network::CustomProtocolObject
{ {
short objectID; short objectID;
@ -1010,4 +1010,46 @@ namespace GameLogic
private: private:
Oyster::Network::CustomNetProtocol protocol; Oyster::Network::CustomNetProtocol protocol;
}; };
//#define protocol_Gameplay_ObjectCollision 370
struct Protocol_ObjectCollision :public Oyster::Network::CustomProtocolObject
{
short objectID;
int collisionID;
// TODO: maybe position, impact, and velocity
Protocol_ObjectCollision()
{
this->protocol[0].value = protocol_Gameplay_ObjectCollision;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_Short;
this->protocol[2].type = Oyster::Network::NetAttributeType_Int;
this->objectID = -1;
this->collisionID = -1;
}
Protocol_ObjectCollision(Oyster::Network::CustomNetProtocol& p)
{
this->objectID = p[1].value.netShort;
this->collisionID = p[2].value.netInt;
}
Protocol_ObjectCollision( int id, int collisionID)
{
this->protocol[0].value = protocol_Gameplay_ObjectCollision;
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[1].type = Oyster::Network::NetAttributeType_Short;
this->protocol[2].type = Oyster::Network::NetAttributeType_Int;
this->objectID = id;
this->collisionID = collisionID;
}
Oyster::Network::CustomNetProtocol GetProtocol() override
{
this->protocol[1].value = objectID;
this->protocol[2].value = collisionID;
return protocol;
}
private:
Oyster::Network::CustomNetProtocol protocol;
};
#endif // !GAMELOGIC_PLAYER_PROTOCOLS_H #endif // !GAMELOGIC_PLAYER_PROTOCOLS_H

View File

@ -73,6 +73,7 @@
#define protocol_Gameplay_ObjectDie 367 #define protocol_Gameplay_ObjectDie 367
#define protocol_Gameplay_ObjectDisconnectPlayer 368 #define protocol_Gameplay_ObjectDisconnectPlayer 368
#define protocol_Gameplay_ObjectAction 369 #define protocol_Gameplay_ObjectAction 369
#define protocol_Gameplay_ObjectCollision 370
#define protocol_GameplayMAX 399 #define protocol_GameplayMAX 399

View File

@ -105,6 +105,7 @@ namespace DanBias
static void ObjectDead ( GameLogic::IObjectData* victim, GameLogic::IObjectData* killer, float seconds ); static void ObjectDead ( GameLogic::IObjectData* victim, GameLogic::IObjectData* killer, float seconds );
static void PickupEvent ( GameLogic::IObjectData* movedObject, int pickupEffectID ); static void PickupEvent ( GameLogic::IObjectData* movedObject, int pickupEffectID );
static void ActionEvent ( GameLogic::IObjectData* movedObject , int actionID ); static void ActionEvent ( GameLogic::IObjectData* movedObject , int actionID );
static void CollisionEvent ( GameLogic::IObjectData* Object , int collisionID );
//Private member variables //Private member variables
private: private:
Utility::DynamicMemory::DynamicArray<gClient> gClients; Utility::DynamicMemory::DynamicArray<gClient> gClients;

View File

@ -25,8 +25,7 @@ GameClient::GameClient(Utility::DynamicMemory::SmartPointer<Oyster::Network::Net
} }
GameClient::~GameClient() GameClient::~GameClient()
{ {
if(this->player) delete this->player;
this->player->Inactivate();
this->isReady = false; this->isReady = false;
this->character = L"char_orca.dan"; this->character = L"char_orca.dan";

View File

@ -152,7 +152,7 @@ using namespace DanBias;
} }
void GameSession::ObjectEnabled( GameLogic::IObjectData* movedObject ) void GameSession::ObjectEnabled( GameLogic::IObjectData* movedObject )
{ {
GameSession::gameSession->Send(Protocol_ObjectDisable(movedObject->GetID()).GetProtocol()); GameSession::gameSession->Send(Protocol_ObjectEnable(movedObject->GetID()).GetProtocol());
} }
void GameSession::ObjectDamaged( GameLogic::IObjectData* movedObject, float hp ) void GameSession::ObjectDamaged( GameLogic::IObjectData* movedObject, float hp )
{ {
@ -176,6 +176,11 @@ using namespace DanBias;
// send action protocol // send action protocol
GameSession::gameSession->Send(Protocol_ObjectAction(movedObject->GetID(), actionID).GetProtocol()); GameSession::gameSession->Send(Protocol_ObjectAction(movedObject->GetID(), actionID).GetProtocol());
} }
void GameSession::CollisionEvent( GameLogic::IObjectData* movedObject , int collisionID )
{
// send action protocol
GameSession::gameSession->Send(Protocol_ObjectCollision(movedObject->GetID(), collisionID).GetProtocol());
}
//*****************************************************// //*****************************************************//
//****************** Protocol methods *****************// //****************** Protocol methods *****************//
//******************************************************************************************************************// //******************************************************************************************************************//

View File

@ -114,6 +114,7 @@ bool GameSession::Create(GameDescription& desc, bool forceStart)
this->gameInstance.SetDeadSubscription(GameSession::ObjectDead); this->gameInstance.SetDeadSubscription(GameSession::ObjectDead);
this->gameInstance.SetActionSubscription(GameSession::ActionEvent); this->gameInstance.SetActionSubscription(GameSession::ActionEvent);
this->gameInstance.SetPickupSubscription(GameSession::PickupEvent); this->gameInstance.SetPickupSubscription(GameSession::PickupEvent);
this->gameInstance.SetCollisionSubscription(GameSession::CollisionEvent);
this->gameInstance.SetFPS(60); this->gameInstance.SetFPS(60);
this->description.clients.Clear(); this->description.clients.Clear();

View File

@ -167,6 +167,14 @@ std::vector<SmartPointer<ObjectTypeHeader>> LevelParser::Parse(std::string filen
ParseObject(&buffer[counter], &header->healthValue, 4); ParseObject(&buffer[counter], &header->healthValue, 4);
counter += 4; counter += 4;
// DEBUG
header->position[1] = 150;
header->spawnTime = 5;
header->boundingVolume.box.mass = 0;
header->typeID = ObjectType_Static;
header->healthValue = 50;
// !DEBUG
objects.push_back(header); objects.push_back(header);
break; break;

View File

@ -95,16 +95,26 @@ namespace GameLogic
enum PlayerAction enum PlayerAction
{ {
PlayerAction_Jump, PlayerAction_Jump = 0,
PlayerAction_Walk, PlayerAction_Walk = 1,
PlayerAction_Idle, PlayerAction_Idle = 2,
}; };
// continue ID counting from playerAction
enum WeaponAction enum WeaponAction
{ {
WeaponAtcion_PrimaryShoot, WeaponAction_PrimaryShoot = 3,
WeaponAction_SecondaryShoot WeaponAction_SecondaryShoot = 4,
WeaponAction_UtilityActivate = 5,
WeaponAction_Reload = 6,
WeaponAction_EnergyDepleted = 7,
}; };
// TODO: add more collision Events
enum CollisionEvent
{
CollisionEvent_BasicCollision,
};
enum PickupType enum PickupType
{ {
PickupType_Health, PickupType_Health,

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{32DD438B-8C9C-49EF-9EA5-EB48951D869A}</ProjectGuid>
<RootNamespace>Test</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,243 @@
#include <Windows.h>
const unsigned short raw_input_usage_keyboard = 6;
const unsigned short raw_input_usage_mouse = 2;
HWND winHandle;
bool isPointAndClickMode;
float normalizedMousePosX, normalizedMousePosY;
LRESULT CALLBACK RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l);
LRESULT RawInputParser(HWND h, LPARAM l);
void Update( );
//int main()
int WINAPI WinMain( HINSTANCE hinst, HINSTANCE prevInst, PSTR cmdLine, int cmdShow)
{
WNDCLASSEXW wc;
wc.cbSize = sizeof(WNDCLASSEXW);
wc.hIconSm = NULL;
wc.style = NULL;
wc.lpfnWndProc = RawWindowCallback;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hInstance = hinst;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = L"RawInputTest";
if( !RegisterClassExW(&wc) )
{
const char *breakpoint = "";
}
winHandle = CreateWindowExW( 0, L"RawInputTest", L"RawInputTest", WS_OVERLAPPEDWINDOW | WS_CAPTION, 0, 0, 600, 400, NULL, NULL, hinst, NULL );
ShowWindow( winHandle, cmdShow );
if( !winHandle )
{
const char *breakpoint = "";
}
isPointAndClickMode = true;
normalizedMousePosX =
normalizedMousePosY = 0.5f;
MSG msg = {0};
while( true )
{
if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
{
if (msg.message == WM_QUIT) break;
DispatchMessage(&msg);
}
else
{
Update();
}
}
return 0;
}
LRESULT CALLBACK RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l)
{
LRESULT val = 0;
switch (m)
{
case WM_INPUT:
{
RawInputParser( h, l );
}
break;
case WM_KEYUP:
{
if( w == 16 )
{
const char *breakpoint = "";
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01;
rid.hwndTarget = winHandle;
rid.usUsage = raw_input_usage_keyboard;
rid.dwFlags = RIDEV_NOLEGACY;
if( RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == FALSE )
{
const char *breakpoint = "";
}
}
}
break;
case WM_RBUTTONUP:
{
const char *breakpoint = "";
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01;
rid.hwndTarget = winHandle;
rid.usUsage = raw_input_usage_mouse;
rid.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE;
if( RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == TRUE )
{
ShowCursor( false );
isPointAndClickMode = false;
}
else
{
const char *breakpoint = "";
}
}
break;
case WM_ACTIVATE:
{
const char *breakpoint = "";
}
break;
break;
case WM_CREATE:
{
const char *breakpoint = "";
}
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
default: break;
}
return DefWindowProc(h, m, w, l);
}
LRESULT RawInputParser(HWND h, LPARAM l)
{
//Get The size of the raw data buffer
UINT bufferSize;
GetRawInputData((HRAWINPUT)l, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
if (bufferSize < 1)
{ return 0; }
//Create and read the raw input data
LPBYTE rawBuffer = new BYTE[bufferSize];
UINT readBytes = GetRawInputData((HRAWINPUT)l, RID_INPUT, rawBuffer, &bufferSize, sizeof(RAWINPUTHEADER));
if ( readBytes != bufferSize )
{
delete [] rawBuffer;
return 0;
}
HRESULT result = 0;
RAWINPUT* raw = (RAWINPUT*)rawBuffer;
if( raw->header.dwType == RIM_TYPEKEYBOARD )
{
if( (raw->data.keyboard.Flags & RI_KEY_BREAK) && raw->data.keyboard.VKey == 16 )
{
const char *breakpoint = "";
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01;
rid.hwndTarget = NULL;
rid.usUsage = raw_input_usage_keyboard;
rid.dwFlags = RIDEV_REMOVE;
if( RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == FALSE )
{
const char *breakpoint = "";
}
}
}
else if( raw->header.dwType == RIM_TYPEMOUSE )
{
if( raw->data.mouse.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP )
{
const char *breakpoint = "";
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01;
rid.hwndTarget = NULL;
rid.usUsage = raw_input_usage_mouse;
rid.dwFlags = RIDEV_REMOVE;
if( RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == TRUE )
{
RECT winRect;
GetWindowRect( winHandle, &winRect );
SetCursorPos( (winRect.left + winRect.right) >> 1, (winRect.top + winRect.bottom) >> 1 );
isPointAndClickMode = true;
}
else
{
const char *breakpoint = "";
}
}
}
else result = DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER));
delete [] rawBuffer;
return result;
}
void Update( )
{
if( isPointAndClickMode )
{
{ // Calculating and storing the normalizedMousePos values
POINT clientReach, clientCenter, mousePos;
RECT winRect, clientRect;
GetClientRect( winHandle, &clientRect );
GetWindowRect( winHandle, &winRect );
LONG borderThickness = (winRect.right - winRect.left - clientRect.right) >> 1;
clientReach.x = clientRect.right >> 1;
clientReach.y = clientRect.bottom >> 1;
clientCenter.x = (winRect.left + winRect.right) >> 1;
clientCenter.y = winRect.bottom - clientReach.y - borderThickness;
GetCursorPos( &mousePos );
normalizedMousePosX = ((float)(mousePos.x - clientCenter.x + clientReach.x)) / (float)clientRect.right;
normalizedMousePosY = ((float)(mousePos.y - clientCenter.y + clientReach.y)) / (float)clientRect.bottom;
}
// Check if normalizedMousePos intersects client surface [(0,0), (1,1)]
bool mouseIsNowWithinBounds = true;
if ( normalizedMousePosX < 0.0f ) mouseIsNowWithinBounds = false;
else if( normalizedMousePosX > 1.0f ) mouseIsNowWithinBounds = false;
else if( normalizedMousePosY < 0.0f ) mouseIsNowWithinBounds = false;
else if( normalizedMousePosY > 1.0f ) mouseIsNowWithinBounds = false;
// Detect onEnter or onExit case
static bool mouseWereWithinBounds = false;
if( mouseIsNowWithinBounds & !mouseWereWithinBounds )
{ // onEnter
ShowCursor( false );
mouseWereWithinBounds = mouseIsNowWithinBounds;
}
else if( !mouseIsNowWithinBounds & mouseWereWithinBounds )
{ // onExit
ShowCursor( true );
mouseWereWithinBounds = mouseIsNowWithinBounds;
}
}
}

View File

@ -1,22 +0,0 @@
/////////////////////////////////////////////////////////////////////
// Created by [Dan Andersson] [2014]
/////////////////////////////////////////////////////////////////////
#ifndef INPUT_APPLICATION_KEBOARD_H
#define INPUT_APPLICATION_KEBOARD_H
#include "InputObject.h"
#include <vector>
namespace Input
{
class AplicationKeyboard : public InputObject
{
public:
protected:
AplicationKeyboard();
~AplicationKeyboard();
};
}
#endif // !INPUT_KEBOARD_H

View File

@ -31,20 +31,30 @@ namespace Input
ButtonState_Down, // When the button is held down ButtonState_Down, // When the button is held down
ButtonState_Release, // When button is released (once) ButtonState_Release, // When button is released (once)
ButtonState_Up, // Default state, will not be proccesed as a callback! ButtonState_Up, // Default state, will not be proccesed as a callback!
ButtonState_Unknown,
}; };
} }
/*********************************************************************/ /*********************************************************************/
namespace Struct namespace Struct
{ {
struct SAIPoint2D struct SAIPointInt2D
{ {
int x; int x;
int y; int y;
SAIPoint2D() :x(0), y(0) { } SAIPointInt2D() :x(0), y(0) { }
SAIPoint2D(int _x, int _y) :x(_x), y(_y) { } SAIPointInt2D(int _x, int _y) :x(_x), y(_y) { }
int Length() { return (abs(x) + abs(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; struct InputData;
} }
/*********************************************************************/ /*********************************************************************/

View File

@ -18,12 +18,17 @@ namespace Input
/** /**
* @return Returns an instance of the default input manager. * @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. * @return Returns a new input manager. Should be destroyd with DestroyInputManager function.
*/ */
static InputManager* CreateInputManager (); static InputManager* CreateInputManager ();
/**
* @return Destroys the default input manager.
*/
static void DestroyInputManager ();
/** /**
* @return Destroys a input manager. * @return Destroys a input manager.
@ -37,7 +42,9 @@ namespace Input
* @see InputDescription * @see InputDescription
* @return Returns a handle to a device that can be rethrown to a specific device. * @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. /** Enables or Disables the Input proccessing.
* @param The toggler. * @param The toggler.

View File

@ -13,8 +13,9 @@ namespace Input
public: public:
inline Enum::SAIType Type() { return type; } inline Enum::SAIType Type() { return type; }
virtual inline void Enable () { isEnabled = true; }; virtual void Activate () = 0;
virtual inline void Disable () { isEnabled = false; }; virtual void Deactivate () = 0;
virtual bool IsActive() = 0;
protected: protected:
InputObject(Enum::SAIType type) { this->type = type; } InputObject(Enum::SAIType type) { this->type = type; }
@ -22,9 +23,6 @@ namespace Input
private: private:
Enum::SAIType type; Enum::SAIType type;
protected:
bool isEnabled;
}; };
} }

View File

@ -49,6 +49,10 @@ namespace Input
SAKI_7 , SAKI_7 ,
SAKI_8 , SAKI_8 ,
SAKI_9 , SAKI_9 ,
SAKI_Add ,
SAKI_Comma ,
SAKI_Minus ,
SAKI_Period ,
SAKI_A , SAKI_A ,
SAKI_B , SAKI_B ,
SAKI_C , SAKI_C ,
@ -131,11 +135,23 @@ namespace Input
}; };
} }
//----------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------
namespace Struct
{
struct KeyboardEventData
{
Enum::SAKI key;
Enum::ButtonState state;
Keyboard* sender;
void* tag;
};
}
//-----------------------------------------------------------------------------------------------------------------------------
namespace Typedefs namespace Typedefs
{ {
typedef void(*OnKeyPressCallback)(Enum::SAKI key, const wchar_t[40], Keyboard* sender); typedef void(*OnKeyEventCallback) (const Struct::KeyboardEventData& eventData);
typedef void(*OnKeyDownCallback)(Enum::SAKI key, const wchar_t[40], Keyboard* sender); typedef void(*OnKeyPressCallback) (Enum::SAKI key, Keyboard* sender, void* tag);
typedef void(*OnKeyReleaseCallback)(Enum::SAKI key, const wchar_t[40], Keyboard* sender); typedef void(*OnKeyDownCallback) (Enum::SAKI key, Keyboard* sender, void* tag);
typedef void(*OnKeyReleaseCallback) (Enum::SAKI key, Keyboard* sender, void* tag);
} }
//----------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------
@ -145,68 +161,65 @@ namespace Input
class KeyboardEvent class KeyboardEvent
{ {
public: public:
virtual void OnKeyPress(Enum::SAKI key, const wchar_t[40], Keyboard* sender) { } virtual void OnKeyEvent (const Struct::KeyboardEventData& eventData) { }
virtual void OnKeyDown(Enum::SAKI key, const wchar_t[40], Keyboard* sender) { } virtual void OnKeyPress (Enum::SAKI key, Keyboard* sender) { }
virtual void OnKeyRelease(Enum::SAKI key, const wchar_t[40], Keyboard* sender) { } virtual void OnKeyDown (Enum::SAKI key, Keyboard* sender) { }
virtual void OnKeyRelease (Enum::SAKI key, Keyboard* sender) { }
}; };
public: /* Manual check functions */ public: /* Manual check functions */
virtual ~Keyboard();
virtual bool IsKeyUp (Enum::SAKI key) = 0; virtual bool IsKeyUp (Enum::SAKI key) = 0;
virtual bool IsKeyDown (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: /* object subscribe functions */
void AddKeyboardEvent (KeyboardEvent* object);
void RemoveKeyboardEvent (KeyboardEvent* object);
void operator+= (KeyboardEvent* object);
void operator-= (KeyboardEvent* object);
public: /* global subscribe callback functions */ public: /* global subscribe callback functions */
void AddOnKeyPressCallback (Typedefs::OnKeyPressCallback func); void AddOnKeyEventCallback (Typedefs::OnKeyEventCallback func, void* tag);
void AddOnKeyDownCallback (Typedefs::OnKeyDownCallback func); void AddOnKeyPressCallback (Typedefs::OnKeyPressCallback func, void* tag);
void AddOnKeyReleaseCallback (Typedefs::OnKeyReleaseCallback func); void AddOnKeyDownCallback (Typedefs::OnKeyDownCallback func, void* tag);
void AddOnKeyReleaseCallback (Typedefs::OnKeyReleaseCallback func, void* tag);
void RemoveOnKeyPressCallback (Typedefs::OnKeyPressCallback func); void RemoveOnKeyEventCallback (Typedefs::OnKeyEventCallback func);
void RemoveOnKeyDownCallback (Typedefs::OnKeyDownCallback func); void RemoveOnKeyPressCallback (Typedefs::OnKeyPressCallback func);
void RemoveOnKeyDownCallback (Typedefs::OnKeyDownCallback func);
void RemoveOnKeyReleaseCallback (Typedefs::OnKeyReleaseCallback func); void RemoveOnKeyReleaseCallback (Typedefs::OnKeyReleaseCallback func);
public: public:
void operator+= (KeyboardEvent* object);
void operator-= (KeyboardEvent* object);
void BindTextTarget( ::std::wstring *field );
void ReleaseTextTarget();
public:
struct KeyboardCallbackList;
protected: protected:
Keyboard(); Keyboard();
~Keyboard();
protected: protected: /* Internal event proc */
struct KeyboardCallbackList void InternalOnEvent(Struct::KeyboardEventData& data);
{ void InternalOnKeyPress(Enum::SAKI key);
enum CallbackDataType void InternalOnKeyDown(Enum::SAKI key);
{ void InternalOnKeyRelease(Enum::SAKI key);
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<KeyboardEvent*>& list, KeyboardEvent* data);
protected: protected:
std::vector<KeyboardEvent*> keyEventSubscrivers; std::vector<KeyboardEvent*> keyEventSubscrivers;
KeyboardCallbackList* callbackList; KeyboardCallbackList* callbackList;
::std::wstring* textTarget;
::std::wstring::size_type writePos;
bool active;
}; };
} }

View File

@ -38,16 +38,35 @@ namespace Input
SAMI_MouseBtnX18, SAMI_MouseBtnX18,
SAMI_MouseBtnX19, SAMI_MouseBtnX19,
SAMI_MouseBtnX20, SAMI_MouseBtnX20,
SAMI_MouseMove,
SAMI_MouseScroll,
SAMI_Unknown, SAMI_Unknown,
}; };
} }
//----------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------
namespace Struct
{
struct MouseEventData
{
Enum::SAMI type;
Enum::ButtonState buttonState;
Struct::SAIPointInt2D pixelPos;
Struct::SAIPointFloat2D normalizedPos;
Struct::SAIPointInt2D velocity;
Mouse* sender;
int scrollDelta;
void* tag;
};
}
//-----------------------------------------------------------------------------------------------------------------------------
namespace Typedefs namespace Typedefs
{ {
typedef void(*OnMouseCallback)( const Struct::MouseEventData& eventData );
typedef void(*OnMousePressCallback)(Enum::SAMI btn, Mouse* sender); typedef void(*OnMousePressCallback)(Enum::SAMI btn, Mouse* sender);
typedef void(*OnMouseDownCallback)(Enum::SAMI btn, Mouse* sender); typedef void(*OnMouseDownCallback)(Enum::SAMI btn, Mouse* sender);
typedef void(*OnMouseReleaseCallback)(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); typedef void(*OnMouseScrollCallback)(int delta, Mouse* sender);
} }
//----------------------------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------------------------
@ -55,87 +74,81 @@ namespace Input
class Mouse :public InputObject class Mouse :public InputObject
{ {
public: public:
class MouseEvent class MouseEvent
{ {
public: public:
virtual void OnMousePress ( Enum::SAMI key, Mouse* sender ) { } virtual void OnMouse ( const Struct::MouseEventData& eventData ) { }
virtual void OnMouseDown ( Enum::SAMI key, Mouse* sender ) { } virtual void OnMousePress ( Enum::SAMI key, Mouse* sender ) { }
virtual void OnMouseRelease ( Enum::SAMI key, Mouse* sender ) { } virtual void OnMouseDown ( Enum::SAMI key, Mouse* sender ) { }
virtual void OnMouseMove ( Struct::SAIPoint2D coordinate, Mouse* sender ) { } virtual void OnMouseRelease ( Enum::SAMI key, Mouse* sender ) { }
virtual void OnMouseScroll ( int delta, 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: public: /* Manual check functions */
virtual bool IsBtnUp(Enum::SAMI key) = 0; virtual bool IsBtnUp(Enum::SAMI key) const = 0;
virtual bool IsBtnDown(Enum::SAMI key) = 0; virtual bool IsBtnDown(Enum::SAMI key) const = 0;
virtual int GetWheelDelta() = 0; virtual int GetWheelDelta() const = 0;
virtual Struct::SAIPoint2D GetPixelPosition(Struct::SAIPoint2D targetMem = Struct::SAIPoint2D()) = 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: public: /* From InputObject */
void AddOnMousePressCallback( Typedefs::OnMousePressCallback func); virtual void Activate () override = 0;
void AddOnMouseDownCallback( Typedefs::OnMouseDownCallback func ); virtual void Deactivate () override = 0;
void AddOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func ); virtual bool IsActive() override = 0;
void AddOnMouseMoveCallback( Typedefs::OnMouseMoveCallback func );
void AddOnMouseScrollCallback( Typedefs::OnMouseScrollCallback func );
public: /* global subscribe callback functions */
void AddMouseEvent(MouseEvent* object);
void RemoveMouseEvent(MouseEvent* object);
void operator+= (MouseEvent* object);
void operator-= (MouseEvent* object);
public: /* global subscribe callback functions */
void AddOnMouseCallback( Typedefs::OnMouseCallback func, void* tag);
void AddOnMousePressCallback( Typedefs::OnMousePressCallback func, void* tag);
void AddOnMouseDownCallback( Typedefs::OnMouseDownCallback func, void* tag );
void AddOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func, void* tag );
void AddOnMouseMovePixelPosCallback( Typedefs::OnMouseMovePixelPosCallback func, void* tag );
void AddOnMouseMoveVelocityCallback( Typedefs::OnMouseMoveVelocityCallback func, void* tag );
void AddOnMouseScrollCallback( Typedefs::OnMouseScrollCallback func, void* tag );
void RemoveOnMouseCallback( Typedefs::OnMouseCallback func);
void RemoveOnMousePressCallback( Typedefs::OnMousePressCallback func); void RemoveOnMousePressCallback( Typedefs::OnMousePressCallback func);
void RemoveOnMouseDownCallback( Typedefs::OnMouseDownCallback func ); void RemoveOnMouseDownCallback( Typedefs::OnMouseDownCallback func );
void RemoveOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback 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 ); void RemoveOnMouseScrollCallback( Typedefs::OnMouseScrollCallback func );
void SetPixelPos(int x, int y); void SetPixelPos(int x, int y);
void ToggleCursor(bool toggler); void ToggleCursor(bool toggler);
private: public:
void operator+= (MouseEvent* object); struct MouseCallbackList;
void operator-= (MouseEvent* object);
protected: protected:
Mouse(); Mouse();
~Mouse(); virtual ~Mouse();
protected: protected:
struct MouseCallbackList void InternalOnEvent(Struct::MouseEventData & data);
{ void InternalOnBtnPress(Enum::SAMI key);
enum CallbackDataType void InternalOnBtnDown(Enum::SAMI key);
{ void InternalOnBtnRelease(Enum::SAMI key);
CallbackDataType_OnPress, void InternalOnMove(Struct::SAIPointInt2D pixelPos, Struct::SAIPointInt2D velocity);
CallbackDataType_OnDown, void InternalOnScroll(int delta);
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<MouseEvent*>& list, MouseEvent* data);
protected: protected:
std::vector<MouseEvent*> mouseSubscribers; std::vector<MouseEvent*> mouseSubscribers;
MouseCallbackList* callbackList; MouseCallbackList* callbackList;
Struct::SAIPoint2D pixelPos; Struct::SAIPointInt2D pixelPos;
Struct::SAIPointInt2D velocity;
Struct::SAIPointFloat2D normalPos;
Struct::SAIPointFloat2D deltaPos;
bool isCurorLocked; bool isCurorLocked;
int wheelDelta; int wheelDelta;
}; };

View File

@ -1,24 +0,0 @@
/////////////////////////////////////////////////////////////////////
// Created by [Dan Andersson] [2014]
/////////////////////////////////////////////////////////////////////
#ifndef INPUT_WIN32_APPLICATION_KEBOARD_H
#define INPUT_WIN32_APPLICATION_KEBOARD_H
#include "..\ApplicationKeyboard.h"
//#include <Windows.h>
namespace Input
{
class Win32ApplicationKeyboard :public AplicationKeyboard
{
public:
Win32ApplicationKeyboard();
~Win32ApplicationKeyboard();
private:
};
}
#endif // !INPUT_WIN32_APPLICATION_KEBOARD_H

View File

@ -9,14 +9,15 @@
#include "Win32Keyboard.h" #include "Win32Keyboard.h"
#include "Win32Mouse.h" #include "Win32Mouse.h"
#include <vector> #include <vector>
#define NOMINMAX
#include <Windows.h> #include <Windows.h>
#include <map> #include <map>
/** /**
* TODO: * TODO:
* 1. Cordinate system * 1. Cordinate system
* 1.1. Pixel cordinates * 1.1. Pixel cordinates DONE
* 1.2. 0 - 1 cordinate * 1.2. 0 - 1 cordinate DONW
* 1.3. Origo in middle of the screen ( -1 to 1 ) * 1.3. Origo in middle of the screen ( -1 to 1 )
*/ */
@ -42,46 +43,6 @@ namespace Input
class Win32Input :public InputManager class Win32Input :public InputManager
{ {
// private:
// SubscribeList<INPUT_CALLBACK, const InputData*>* _procInput;
//
// bool _enabled;
// bool _mouseEnabled;
// bool _KeyboardEnabled;
// bool _exclusive;
// List<RawInputDeviceInstance> _deviceList;
//
// List<InputData> _mouseInput;
// List<InputData> _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: public:
Win32Input(); Win32Input();
virtual~Win32Input(); virtual~Win32Input();
@ -95,12 +56,11 @@ namespace Input
std::vector<Win32Mouse*> mouse; std::vector<Win32Mouse*> mouse;
bool enabled; bool enabled;
bool exclusive;
HWND targetHwin; HWND targetHwin;
private: private:
static Win32Input* instance; 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 LRESULT CALLBACK RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l);
static void WindowActivate(bool activate); static void WindowActivate(bool activate);
}; };

View File

@ -5,6 +5,7 @@
#define INPUT_KEYBOARD_H #define INPUT_KEYBOARD_H
#include "..\Keyboard.h" #include "..\Keyboard.h"
#define NOMINMAX
#include <Windows.h> #include <Windows.h>
namespace Input namespace Input
@ -12,24 +13,34 @@ namespace Input
class Win32Keyboard :public Keyboard class Win32Keyboard :public Keyboard
{ {
public: public:
Win32Keyboard(); Win32Keyboard(HWND target);
~Win32Keyboard(); ~Win32Keyboard();
bool IsKeyUp (Enum::SAKI key) override; bool IsKeyUp (Enum::SAKI key) override;
bool IsKeyDown (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: private:
void MapKey(RAWKEYBOARD& rawKB, Enum::SAKI& out_key, bool& isE0);
struct Keys struct Keys
{ {
bool isE0; bool isE0;
bool isDown; bool isDown;
unsigned int makecode; unsigned int makecode;
}; };
RAWINPUTDEVICE device;
static const int MAXKEYS = 256; static const int MAXKEYS = 256;
Keys keys[MAXKEYS]; Keys keys[MAXKEYS];
bool isActive;
}; };
} }

View File

@ -12,15 +12,23 @@ namespace Input
class Win32Mouse :public Mouse class Win32Mouse :public Mouse
{ {
public: public:
Win32Mouse(); Win32Mouse(HWND target);
~Win32Mouse(); ~Win32Mouse();
bool IsBtnUp(Enum::SAMI key) override; bool IsBtnUp(Enum::SAMI key) const override;
bool IsBtnDown(Enum::SAMI key) override; bool IsBtnDown(Enum::SAMI key) const override;
int GetWheelDelta() override; int GetWheelDelta() const override;
Struct::SAIPoint2D GetPixelPosition(Struct::SAIPoint2D targetMem = Struct::SAIPoint2D()) 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( );
void ToggleDefault( bool toggler );
private: private:
struct Buttons struct Buttons
@ -28,8 +36,12 @@ namespace Input
unsigned int makeCode; unsigned int makeCode;
bool isDown; bool isDown;
}; };
static const int MAXBUTTONS = 25; static const int MAXBUTTONS =Enum::SAMI_Unknown;
Buttons buttons[25]; Buttons buttons[MAXBUTTONS];
RAWINPUTDEVICE device;
Struct::SAIPointInt2D windowSize;
bool isActive;
Struct::SAIPointInt2D winCursPos;
}; };
} }

View File

@ -28,7 +28,6 @@
<ClCompile Include="Source\Win32\Win32Mouse.cpp" /> <ClCompile Include="Source\Win32\Win32Mouse.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Include\ApplicationKeyboard.h" />
<ClInclude Include="Include\Common.h" /> <ClInclude Include="Include\Common.h" />
<ClInclude Include="Include\Input.h" /> <ClInclude Include="Include\Input.h" />
<ClInclude Include="Include\InputManager.h" /> <ClInclude Include="Include\InputManager.h" />
@ -36,7 +35,6 @@
<ClInclude Include="Include\Keyboard.h" /> <ClInclude Include="Include\Keyboard.h" />
<ClInclude Include="Include\Mouse.h" /> <ClInclude Include="Include\Mouse.h" />
<ClInclude Include="Include\PreReq.h" /> <ClInclude Include="Include\PreReq.h" />
<ClInclude Include="Include\Win32\Win32ApplicationKeyboard.h" />
<ClInclude Include="Include\Win32\Win32Input.h" /> <ClInclude Include="Include\Win32\Win32Input.h" />
<ClInclude Include="Include\Win32\Win32Keyboard.h" /> <ClInclude Include="Include\Win32\Win32Keyboard.h" />
<ClInclude Include="Include\Win32\Win32Mouse.h" /> <ClInclude Include="Include\Win32\Win32Mouse.h" />
@ -93,28 +91,32 @@
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir> <OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir> <IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName> <TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir> <OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir> <IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName> <TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir> <OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir> <IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName> <TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir> <OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir> <IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName> <TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)Misc\Utilities;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>

View File

@ -1,101 +1,68 @@
#include "RawInput.h" #include <atomic>
// include the basic windows header file #include <vector>
#include <windows.h> #include <iostream>
#include <windowsx.h> #include <chrono>
#include <cassert> #include <ctime>
#include <map>
#include <thread>
#include <chrono>
#include <iomanip>
#include <mutex>
#include <bitset>
#include <Windows.h>
#include "Include\Input.h"
#include "WindowShell.h"
HWND hWnd; using namespace std;
// this is the main message handler for the program using namespace Input;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 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 if(key == SAKI_A)
switch(message) {
{ if(mouse->IsActive()) mouse->Deactivate();
// this message is read when the window is closed else mouse->Activate();
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);
} }
void initWindow(HINSTANCE h, int i)
void MouseVelocity(Input::Struct::SAIPointInt2D vel, Input::Mouse* sender)
{ {
// this struct holds information for the window class int i = vel.Length();
WNDCLASSEX wc; if(abs(i) > 2)
i = 0;
// 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);
} }
void initRaw()
int WINAPI WinMain( HINSTANCE hinst, HINSTANCE prevInst, PSTR cmdLine, int cmdShow)
{ {
//RawInput::Self()->Input_AddDevice(hWnd); std::wstring text;
}
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
initWindow(hInstance, nCmdShow);
initRaw();
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 mouse->AddOnMouseMoveVelocityCallback(MouseVelocity);
MSG msg; keyboard->BindTextTarget( &text );
keyboard->AddOnKeyPressCallback(KeyPress);
// wait for the next message in the queue, store the result in 'msg' int oldLen = 0;
while(GetMessage(&msg, NULL, 0, 0))
{
// translate keystroke messages into the right format
TranslateMessage(&msg);
// send the message to the WindowProc function
DispatchMessage(&msg);
//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;
} }

View File

@ -57,6 +57,14 @@ InputManager* InputManager::CreateInputManager()
{ {
return CreateManager(); return CreateManager();
} }
void InputManager::DestroyInputManager()
{
if(!defaultInstance) return;
defaultInstance->Destroy();
delete defaultInstance;
defaultInstance = 0;
}
void InputManager::DestroyInputManager(InputManager* inputSystem) void InputManager::DestroyInputManager(InputManager* inputSystem)
{ {
if(!inputSystem) return; if(!inputSystem) return;
@ -77,3 +85,4 @@ InputManager::~InputManager()

View File

@ -8,11 +8,37 @@ using namespace Input::Enum;
using namespace Input::Typedefs; using namespace Input::Typedefs;
using namespace Input::Struct; using namespace Input::Struct;
struct Keyboard::KeyboardCallbackList
void Keyboard::ClearList(Keyboard::KeyboardCallbackList* first)
{ {
KeyboardCallbackList* w = first; enum CallbackDataType
KeyboardCallbackList* removee = 0; {
CallbackDataType_OnEvent,
CallbackDataType_OnPress,
CallbackDataType_OnDown,
CallbackDataType_OnRelease
} type;
union CallbackData
{
Typedefs::OnKeyEventCallback keyEventCallback;
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;
void* tag;
KeyboardCallbackList(CallbackData func, CallbackDataType t, void* ct) :function(func), next(0), type(t), tag(ct) { }
};
void ClearList(Keyboard::KeyboardCallbackList* first)
{
Keyboard::KeyboardCallbackList* w = first;
Keyboard::KeyboardCallbackList* removee = 0;
while (w) while (w)
{ {
@ -21,27 +47,27 @@ void Keyboard::ClearList(Keyboard::KeyboardCallbackList* first)
delete removee; 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, void* tag)
{ {
KeyboardCallbackList *w = first; Keyboard::KeyboardCallbackList *w = first;
KeyboardCallbackList *prev = first; Keyboard::KeyboardCallbackList *prev = first;
while (w) while (w)
{ prev = w; w = w->next; } { prev = w; w = w->next; }
KeyboardCallbackList::CallbackData f; Keyboard::KeyboardCallbackList::CallbackData f;
f = data; f = data;
prev->next = new KeyboardCallbackList(f, type); prev->next = new Keyboard::KeyboardCallbackList(f, type, tag);
} }
void Keyboard::RemoveFromList(KeyboardCallbackList* first, KeyboardCallbackList::CallbackData data) void RemoveFromList(Keyboard::KeyboardCallbackList* first, Keyboard::KeyboardCallbackList::CallbackData data)
{ {
KeyboardCallbackList *w = first; Keyboard::KeyboardCallbackList *w = first;
KeyboardCallbackList *prev = first; Keyboard::KeyboardCallbackList *prev = first;
while (w) while (w)
{ {
if(data == w->function) if(data == w->function)
{ {
KeyboardCallbackList *removee = w; Keyboard::KeyboardCallbackList *removee = w;
w = w->next; w = w->next;
prev->next = w; prev->next = w;
delete removee; delete removee;
@ -51,9 +77,9 @@ void Keyboard::RemoveFromList(KeyboardCallbackList* first, KeyboardCallbackList:
w = w->next; 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) while (w)
{ {
if(data == w->function) if(data == w->function)
@ -64,7 +90,7 @@ bool Keyboard::ExistsInList(KeyboardCallbackList* first, KeyboardCallbackList::C
} }
return true; return true;
} }
bool Keyboard::ExistsInList(std::vector<KeyboardEvent*>& list, KeyboardEvent* data) bool ExistsInList(std::vector<Keyboard::KeyboardEvent*>& list, Keyboard::KeyboardEvent* data)
{ {
for (unsigned int i = 0; i < list.size(); i++) for (unsigned int i = 0; i < list.size(); i++)
{ {
@ -74,50 +100,114 @@ bool Keyboard::ExistsInList(std::vector<KeyboardEvent*>& list, KeyboardEvent* da
return false; return false;
} }
Keyboard::Keyboard() Keyboard::Keyboard()
: InputObject(SAIType_Keyboard) : InputObject(SAIType_Keyboard)
, callbackList(0) , callbackList(0)
, active(1)
, textTarget(0)
, writePos(0)
{} {}
Keyboard::~Keyboard() Keyboard::~Keyboard()
{ {
} }
void Keyboard::AddOnKeyPressCallback (OnKeyPressCallback func) void Keyboard::InternalOnEvent(Struct::KeyboardEventData& data)
{ {
KeyboardCallbackList::CallbackData d; for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++)
d.keyPressCallback = func; {
if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnPress); if(this->keyEventSubscrivers[i])
else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnPress); {
this->keyEventSubscrivers[i]->OnKeyEvent(data);
}
}
KeyboardCallbackList *w = this->callbackList;
while (w)
{
if(w->function)
if (w->type == KeyboardCallbackList::CallbackDataType_OnEvent)
{
data.tag = w->tag;
w->function.keyEventCallback(data);
}
w = w->next;
}
} }
void Keyboard::AddOnKeyDownCallback (OnKeyDownCallback func) void Keyboard::InternalOnKeyPress(Enum::SAKI key)
{ {
KeyboardCallbackList::CallbackData d; for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++)
d.keyDownCallback = func; {
if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnDown); if(this->keyEventSubscrivers[i])
else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnDown); {
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->tag);
}
w = w->next;
}
} }
void Keyboard::AddOnKeyReleaseCallback (OnKeyReleaseCallback func) void Keyboard::InternalOnKeyDown(Enum::SAKI key)
{ {
KeyboardCallbackList::CallbackData d; for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++)
d.keyReleaseCallback = func; {
if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnRelease); if(this->keyEventSubscrivers[i])
else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnRelease); {
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->tag);
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->tag);
w = w->next;
}
} }
void Keyboard::RemoveOnKeyPressCallback (OnKeyPressCallback func) void Keyboard::AddKeyboardEvent(KeyboardEvent* object)
{ {
RemoveFromList(this->callbackList, func); if(ExistsInList(this->keyEventSubscrivers, object)) return;
}
void Keyboard::RemoveOnKeyDownCallback (OnKeyDownCallback func)
{
RemoveFromList(this->callbackList, func);
}
void Keyboard::RemoveOnKeyReleaseCallback (OnKeyReleaseCallback func)
{
RemoveFromList(this->callbackList, func);
}
this->keyEventSubscrivers.push_back(object);
}
void Keyboard::RemoveKeyboardEvent(KeyboardEvent* object)
{
int i = -1;
if((i = ExistsInList(this->keyEventSubscrivers, object)))
{
std::swap(this->keyEventSubscrivers[i], this->keyEventSubscrivers[this->keyEventSubscrivers.size() - 1]);
this->keyEventSubscrivers.resize(this->keyEventSubscrivers.size() - 1);
}
}
void Keyboard::operator+= (KeyboardEvent* object) void Keyboard::operator+= (KeyboardEvent* object)
{ {
if(ExistsInList(this->keyEventSubscrivers, object)) return; if(ExistsInList(this->keyEventSubscrivers, object)) return;
@ -134,3 +224,71 @@ void Keyboard::operator-= (KeyboardEvent* object)
} }
} }
void Keyboard::AddOnKeyEventCallback (OnKeyEventCallback func, void* tag)
{
KeyboardCallbackList::CallbackData d;
d.keyEventCallback = func;
if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnEvent, tag);
else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnEvent, tag);
}
void Keyboard::AddOnKeyPressCallback (OnKeyPressCallback func, void* tag)
{
KeyboardCallbackList::CallbackData d;
d.keyPressCallback = func;
if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnPress, tag);
else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnPress, tag);
}
void Keyboard::AddOnKeyDownCallback (OnKeyDownCallback func, void* tag)
{
KeyboardCallbackList::CallbackData d;
d.keyDownCallback = func;
if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnDown, tag);
else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnDown, tag);
}
void Keyboard::AddOnKeyReleaseCallback (OnKeyReleaseCallback func, void* tag)
{
KeyboardCallbackList::CallbackData d;
d.keyReleaseCallback = func;
if(!this->callbackList) this->callbackList = new KeyboardCallbackList(d, KeyboardCallbackList::CallbackDataType_OnRelease, tag);
else AddToList(this->callbackList, d, KeyboardCallbackList::CallbackDataType_OnRelease, tag);
}
void Keyboard::RemoveOnKeyEventCallback (OnKeyEventCallback func)
{
Keyboard::KeyboardCallbackList::CallbackData temp;
temp.keyEventCallback = func;
RemoveFromList(this->callbackList, temp);
}
void Keyboard::RemoveOnKeyPressCallback (OnKeyPressCallback func)
{
RemoveFromList(this->callbackList, func);
}
void Keyboard::RemoveOnKeyDownCallback (OnKeyDownCallback func)
{
RemoveFromList(this->callbackList, func);
}
void Keyboard::RemoveOnKeyReleaseCallback (OnKeyReleaseCallback func)
{
RemoveFromList(this->callbackList, func);
}
void Keyboard::BindTextTarget( ::std::wstring *field )
{
this->textTarget = field;
if( field )
{
this->writePos = field->size();
}
else
{
this->writePos = 0;
}
}
void Keyboard::ReleaseTextTarget( )
{
this->BindTextTarget( nullptr );
}

View File

@ -9,11 +9,44 @@ using namespace Input::Enum;
using namespace Input::Struct; using namespace Input::Struct;
using namespace Input::Typedefs; using namespace Input::Typedefs;
struct Mouse::MouseCallbackList
void Mouse::ClearList(Mouse::MouseCallbackList* first)
{ {
MouseCallbackList* w = first; enum CallbackDataType
MouseCallbackList* removee = 0; {
CallbackDataType_OnEvent,
CallbackDataType_OnPress,
CallbackDataType_OnDown,
CallbackDataType_OnRelease,
CallbackDataType_OnMovePixelPos,
CallbackDataType_OnMoveVelocity,
CallbackDataType_OnScroll,
} type;
union CallbackData
{
Typedefs::OnMouseCallback mouseCallback;
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;
void* tag;
MouseCallbackList(CallbackData func, CallbackDataType t, void* ct) :function(func), next(0), type(t), tag(ct) { }
};
void ClearList(Mouse::MouseCallbackList* first)
{
Mouse::MouseCallbackList* w = first;
Mouse::MouseCallbackList* removee = 0;
while (w) while (w)
{ {
@ -22,27 +55,27 @@ void Mouse::ClearList(Mouse::MouseCallbackList* first)
delete removee; 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, void* tag)
{ {
MouseCallbackList *w = first; Mouse::MouseCallbackList *w = first;
MouseCallbackList *prev = first; Mouse::MouseCallbackList *prev = first;
while (w) while (w)
{ prev = w; w = w->next; } { prev = w; w = w->next; }
MouseCallbackList::CallbackData f; Mouse::MouseCallbackList::CallbackData f;
f = data; f = data;
prev->next = new MouseCallbackList(f, type); prev->next = new Mouse::MouseCallbackList(f, type, tag);
} }
void Mouse::RemoveFromList(MouseCallbackList* first, MouseCallbackList::CallbackData data) void RemoveFromList(Mouse::MouseCallbackList* first, Mouse::MouseCallbackList::CallbackData data)
{ {
MouseCallbackList *w = first; Mouse::MouseCallbackList *w = first;
MouseCallbackList *prev = first; Mouse::MouseCallbackList *prev = first;
while (w) while (w)
{ {
if(data == w->function) if(data == w->function)
{ {
MouseCallbackList *removee = w; Mouse::MouseCallbackList *removee = w;
w = w->next; w = w->next;
prev->next = w; prev->next = w;
delete removee; delete removee;
@ -52,9 +85,9 @@ void Mouse::RemoveFromList(MouseCallbackList* first, MouseCallbackList::Callback
w = w->next; 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) while (w)
{ {
if(data == w->function) if(data == w->function)
@ -65,7 +98,7 @@ bool Mouse::ExistsInList(MouseCallbackList* first, MouseCallbackList::CallbackDa
} }
return true; return true;
} }
bool Mouse::ExistsInList(std::vector<MouseEvent*>& list, MouseEvent* data) bool ExistsInList(std::vector<Mouse::MouseEvent*>& list, Mouse::MouseEvent* data)
{ {
for (unsigned int i = 0; i < list.size(); i++) for (unsigned int i = 0; i < list.size(); i++)
{ {
@ -81,6 +114,7 @@ Mouse::Mouse()
, wheelDelta(0) , wheelDelta(0)
, isCurorLocked(0) , isCurorLocked(0)
, pixelPos() , pixelPos()
, deltaPos()
{ {
} }
Mouse::~Mouse() Mouse::~Mouse()
@ -88,40 +122,190 @@ Mouse::~Mouse()
} }
void Mouse::AddOnMousePressCallback( Typedefs::OnMousePressCallback func) void Mouse::InternalOnEvent(MouseEventData & data)
{
for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++)
{
if(this->mouseSubscribers[i])
this->mouseSubscribers[i]->OnMouse(data);
}
MouseCallbackList *w = this->callbackList;
while (w)
{
if(w->function)
if (w->type == MouseCallbackList::CallbackDataType_OnEvent)
{
data.tag = w->tag;
w->function.mouseCallback(data);
}
w = w->next;
}
}
void Mouse::InternalOnBtnPress(Enum::SAMI btn)
{
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;
}
}
void Mouse::AddMouseEvent(MouseEvent* object)
{
if(ExistsInList(this->mouseSubscribers, object)) return;
this->mouseSubscribers.push_back(object);
}
void Mouse::RemoveMouseEvent(MouseEvent* object)
{
int i = -1;
if((i = ExistsInList(this->mouseSubscribers, object)))
{
std::swap(this->mouseSubscribers[i], this->mouseSubscribers[this->mouseSubscribers.size() - 1]);
this->mouseSubscribers.resize(this->mouseSubscribers.size() - 1);
}
}
void Mouse::operator+= (MouseEvent* object)
{
if(ExistsInList(this->mouseSubscribers, object)) return;
this->mouseSubscribers.push_back(object);
}
void Mouse::operator-= (MouseEvent* object)
{
int i = -1;
if((i = ExistsInList(this->mouseSubscribers, object)))
{
std::swap(this->mouseSubscribers[i], this->mouseSubscribers[this->mouseSubscribers.size() - 1]);
this->mouseSubscribers.resize(this->mouseSubscribers.size() - 1);
}
}
void Mouse::AddOnMouseCallback( Typedefs::OnMouseCallback func, void* tag)
{
MouseCallbackList::CallbackData d;
d.mouseCallback = func;
if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnEvent, tag);
else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnEvent, tag);
}
void Mouse::AddOnMousePressCallback( Typedefs::OnMousePressCallback func, void* tag)
{ {
MouseCallbackList::CallbackData d; MouseCallbackList::CallbackData d;
d.mousePressCallback = func; d.mousePressCallback = func;
if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnPress, tag);
else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnPress, tag);
} }
void Mouse::AddOnMouseDownCallback( Typedefs::OnMouseDownCallback func ) void Mouse::AddOnMouseDownCallback( Typedefs::OnMouseDownCallback func, void* tag )
{ {
MouseCallbackList::CallbackData d; MouseCallbackList::CallbackData d;
d.mouseDownCallback = func; d.mouseDownCallback = func;
if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnDown, tag);
else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnDown, tag);
} }
void Mouse::AddOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func ) void Mouse::AddOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func, void* tag )
{ {
MouseCallbackList::CallbackData d; MouseCallbackList::CallbackData d;
d.mouseReleaseCallback = func; d.mouseReleaseCallback = func;
if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease, tag);
else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease, tag);
} }
void Mouse::AddOnMouseMoveCallback( Typedefs::OnMouseMoveCallback func ) void Mouse::AddOnMouseMovePixelPosCallback( Typedefs::OnMouseMovePixelPosCallback func, void* tag )
{ {
MouseCallbackList::CallbackData d; MouseCallbackList::CallbackData d;
d.mouseMoveCallback = func; d.mouseMovePixelPosCallback = func;
if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnMovePixelPos, tag);
else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnMovePixelPos, tag);
} }
void Mouse::AddOnMouseScrollCallback( Typedefs::OnMouseScrollCallback func ) void Mouse::AddOnMouseMoveVelocityCallback( Typedefs::OnMouseMoveVelocityCallback func, void* tag )
{
MouseCallbackList::CallbackData d;
d.mouseMoveVelocityCallback = func;
if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnMoveVelocity, tag);
else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnMoveVelocity, tag);
}
void Mouse::AddOnMouseScrollCallback( Typedefs::OnMouseScrollCallback func, void* tag )
{ {
MouseCallbackList::CallbackData d; MouseCallbackList::CallbackData d;
d.mouseScrollCallback = func; d.mouseScrollCallback = func;
if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnRelease); if(!this->callbackList) this->callbackList = new MouseCallbackList(d, MouseCallbackList::CallbackDataType_OnScroll, tag);
else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnRelease); else AddToList(this->callbackList, d, MouseCallbackList::CallbackDataType_OnScroll, tag);
} }
void Mouse::RemoveOnMousePressCallback( Typedefs::OnMousePressCallback func) void Mouse::RemoveOnMousePressCallback( Typedefs::OnMousePressCallback func)
@ -136,7 +320,11 @@ void Mouse::RemoveOnMouseReleaseCallback( Typedefs::OnMouseReleaseCallback func
{ {
RemoveFromList(this->callbackList, 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); RemoveFromList(this->callbackList, func);
} }
@ -155,21 +343,6 @@ void Mouse::ToggleCursor(bool toggler)
this->isCurorLocked = toggler; this->isCurorLocked = toggler;
} }
void Mouse::operator+= (MouseEvent* object)
{
if(ExistsInList(this->mouseSubscribers, object)) return;
this->mouseSubscribers.push_back(object);
}
void Mouse::operator-= (MouseEvent* object)
{
int i = -1;
if((i = ExistsInList(this->mouseSubscribers, object)))
{
std::swap(this->mouseSubscribers[i], this->mouseSubscribers[this->mouseSubscribers.size() - 1]);
this->mouseSubscribers.resize(this->mouseSubscribers.size() - 1);
}
}

View File

@ -16,608 +16,17 @@ using namespace Input::Enum;
using namespace Input::Struct; using namespace Input::Struct;
using namespace Input::Typedefs; 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; Win32Input *Win32Input::instance = 0;
void MapKey(RAWKEYBOARD& rawKB, bool& out_isUp, SAKI& out_key, unsigned int& sCode, bool& isE0) TRACKMOUSEEVENT tme;
{
//------------------------------------------------------------------------------------// LRESULT Win32Input::RawInputParser(HWND h, LPARAM l)
// 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)
{ {
LRESULT val = 0;
//Get The size of the raw data buffer //Get The size of the raw data buffer
UINT bufferSize; UINT bufferSize;
GetRawInputData((HRAWINPUT)l, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER)); GetRawInputData((HRAWINPUT)l, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
if (bufferSize < 1) if (bufferSize < 1)
{ { return 0; }
return;
}
//Create and read the raw input data //Create and read the raw input data
LPBYTE rawBufferIn = new BYTE[bufferSize]; LPBYTE rawBufferIn = new BYTE[bufferSize];
@ -625,64 +34,75 @@ void Win32Input::RawInputParser(HWND h, LPARAM l)
if ( readBytes != bufferSize ) if ( readBytes != bufferSize )
{ {
delete [] rawBufferIn; delete [] rawBufferIn;
return; return 0;
} }
RAWINPUT* raw = (RAWINPUT*)rawBufferIn; RAWINPUT* raw = (RAWINPUT*)rawBufferIn;
if(!Win32Input::instance->enabled) if(!Win32Input::instance->enabled)
{ {
if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) ) val = DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER));
{
}
} }
else else
{ {
if(raw->header.dwType == RIM_TYPEMOUSE) if(raw->header.dwType == RIM_TYPEMOUSE)
{ {
bool once = false;
for (unsigned int i = 0; i < Win32Input::instance->mouse.size(); i++) for (unsigned int i = 0; i < Win32Input::instance->mouse.size(); i++)
{ {
bool isUp = true; if(Win32Input::instance->mouse[i]->IsActive())
Enum::SAMI btn = Enum::SAMI_Unknown; {
int delta = 0; Win32Input::instance->mouse[i]->ProccessMouseData(raw->data.mouse);
Struct::SAIPoint2D vel; }
unsigned int mcode = 0; else
MapButton(raw->data.mouse, isUp, btn, delta, vel, mcode); {
if(!once) val = DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER));
Win32Input::instance->mouse[i]->ProccessMouseData(isUp, btn, delta, vel, mcode); }
} }
} }
else if(raw->header.dwType == RIM_TYPEKEYBOARD) else if(raw->header.dwType == RIM_TYPEKEYBOARD)
{ {
bool once = false;
for (unsigned int i = 0; i < Win32Input::instance->keyboard.size(); i++) for (unsigned int i = 0; i < Win32Input::instance->keyboard.size(); i++)
{ {
bool isUp; if(Win32Input::instance->keyboard[i]->IsActive())
SAKI key = SAKI_Unknown; {
unsigned int makeCode; Win32Input::instance->keyboard[i]->ProccessKeyboardData(raw->data.keyboard);
bool isE0; }
MapKey(raw->data.keyboard, isUp, key, makeCode, isE0); else
Win32Input::instance->keyboard[i]->ProccessKeyboardData(isUp, key, makeCode, isE0); {
if(!once) val = DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER));
}
} }
} }
} }
delete raw; delete raw;
return val;
} }
LRESULT CALLBACK Win32Input::RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l) LRESULT CALLBACK Win32Input::RawWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l)
{ {
LRESULT val = 0;
UINT te = 0;
if(m != WM_INPUT)
te = m;
switch (m) switch (m)
{ {
case WM_INPUT: case WM_INPUT:
Win32Input::instance->RawInputParser(h, l); return Win32Input::instance->RawInputParser(h, l);
break; break;
case WM_NCACTIVATE:
case WM_ACTIVATEAPP:
case WM_ACTIVATE: case WM_ACTIVATE:
Win32Input::instance->WindowActivate((w == TRUE)); Win32Input::instance->WindowActivate((w == TRUE));
break; break;
case WM_CREATE: case WM_CREATE:
Win32Input::instance->WindowActivate(true); Win32Input::instance->WindowActivate(true);
break; break;
} }
return DefWindowProc(h, m, w, l); return DefWindowProc(h, m, w, l);
@ -691,17 +111,25 @@ void Win32Input::WindowActivate(bool activate)
{ {
if(activate) if(activate)
{ {
ShowCursor(0); SetCursor(0);
for (unsigned int i = 0; i < Win32Input::instance->mouse.size(); i++)
{
Win32Input::instance->mouse[i]->ToggleDefault(false);
}
} }
else else
{ {
ShowCursor(0); for (unsigned int i = 0; i < Win32Input::instance->mouse.size(); i++)
{
Win32Input::instance->mouse[i]->ToggleDefault(true);
}
} }
} }
Win32Input::Win32Input() Win32Input::Win32Input()
{ {
this->targetHwin = 0;
if(!this->instance) if(!this->instance)
{ {
this->instance = this; this->instance = this;
@ -725,70 +153,82 @@ Win32Input::Win32Input()
{ /*wrong*/ } { /*wrong*/ }
} }
Win32Input::~Win32Input() Win32Input::~Win32Input()
{} { Destroy(); }
InputObject* Win32Input::CreateDevice(const SAIType inputType, Typedefs::WindowHandle targetApplication) InputObject* Win32Input::CreateDevice(const SAIType inputType, Typedefs::WindowHandle targetApplication)
{ {
if(!this->instance->targetHwin) if(!this->instance->targetHwin)
{ {
this->targetHwin = CreateWindowExW( 0, L"RawInputCallbackFunc" , NULL, NULL, NULL, NULL, NULL, RECT rc;
NULL, (HWND)targetApplication, NULL, (HINSTANCE)GetModuleHandle(0), NULL ); 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; InputObject* val = 0;
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01;
rid.hwndTarget = this->instance->targetHwin;
switch (inputType) switch (inputType)
{ {
case SAIType_Keyboard: case SAIType_Keyboard:
{ {
rid.usUsage = RawInput_Usage_keyboard; Win32Keyboard* obj = new Win32Keyboard(this->targetHwin);
rid.dwFlags = RIDEV_NOLEGACY; if(!obj->Create())
if(RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == TRUE)
{
Win32Keyboard* obj = new Win32Keyboard();
this->keyboard.push_back(obj);
val = obj;
}
else
{ {
delete obj;
return 0; return 0;
} }
this->keyboard.push_back(obj);
val = obj;
} }
break; break;
case SAIType_Mouse: case SAIType_Mouse:
{ {
rid.usUsage = RawInput_Usage_mouse; Win32Mouse* obj = new Win32Mouse(this->targetHwin);
rid.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE; if(!obj->Create())
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
{ {
delete obj;
return 0; return 0;
} }
this->mouse.push_back(obj);
val = obj;
} }
break; break;
} }
return val; return val;
} }
void Win32Input::ToggleInputSystem(bool enable) void Win32Input::ToggleInputSystem(bool enable)
{ {
this->enabled = 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 () void Win32Input::Destroy ()
{ {
ShowCursor(true); ShowCursor(true);
RECT r; ClipCursor(0);
GetWindowRect(GetDesktopWindow(), &r);
ClipCursor(&r);
for (unsigned int i = 0; i < this->keyboard.size(); i++) for (unsigned int i = 0; i < this->keyboard.size(); i++)
{ {
@ -802,52 +242,3 @@ void Win32Input::Destroy ()
this->keyboard.resize(0); 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);
}
*/

View File

@ -1,14 +1,23 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// Created by [Dennis Andersen] [2013] // Created by [Dennis Andersen] [2013]
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "..\..\Include\Win32\Win32Keyboard.h" #include "..\..\Include\Win32\Win32Input.h"
#include <algorithm>
#pragma warning ( disable : 4172 ) #pragma warning ( disable : 4172 )
using namespace Input; using namespace Input;
using namespace Input::Enum; 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;
this->writePos = 0;
memset(&this->keys[0], 0, sizeof(Win32Keyboard::Keys) * MAXKEYS); memset(&this->keys[0], 0, sizeof(Win32Keyboard::Keys) * MAXKEYS);
} }
Win32Keyboard::~Win32Keyboard() Win32Keyboard::~Win32Keyboard()
@ -24,115 +33,705 @@ bool Win32Keyboard::IsKeyDown (SAKI key)
{ {
return this->keys[key].isDown; 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; if(Enum::SAKI_Unknown == key) return 0;
// getting a human-readable string // getting a human-readable string
UINT temp = (this->keys[key].makecode << 16) | (this->keys[key].isE0 << 24); UINT temp = (this->keys[key].makecode << 16) | (this->keys[key].isE0 << 24);
wchar_t buff[56] = {0}; wchar_t buff[16] = {0};
GetKeyNameTextW((LONG)temp, buff, 64); GetKeyNameTextW((LONG)temp, buff, 16);
return buff; return buff;
} }
void Win32Keyboard::ProccessKeyboardData (bool isUp, SAKI key, unsigned int makeCode, bool isE0)
void Win32Keyboard::Activate ()
{ {
if(key == SAKI_Unknown) return; if(this->isActive) 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))*/ 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) this->isActive = true;
{ } }
else if(key == SAKI_LeftCtrl) }
{}
else if(key == SAKI_LeftShift) void Win32Keyboard::ProccessKeyboardData (RAWKEYBOARD keyboard)
{} {
else if(key == SAKI_RightAlt) if(!this->active) return;
{}
else if(key == SAKI_RightCtrl) static Struct::KeyboardEventData keyboardEventData;
{} memset(&keyboardEventData, 0, sizeof(Struct::KeyboardEventData));
else if(key == SAKI_RightShift)
{} bool isUp = (( keyboard.Flags & RI_KEY_BREAK) != 0);
else 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].isDown = false;
this->keys[key].isE0 = isE0; this->keys[key].isE0 = isE0;
this->keys[key].makecode = makeCode; this->keys[key].makecode = keyboard.MakeCode;
for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++)
{ keyboardEventData.key = key;
if(this->keyEventSubscrivers[i]) keyboardEventData.sender = this;
{ keyboardEventData.state = Enum::ButtonState_Release;
this->keyEventSubscrivers[i]->OnKeyRelease(key, GetAsText(key), this); InternalOnEvent(keyboardEventData);
}
}
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;
}
} }
//The key is pressed.
//this->_procCollection.kd.key = (RIK)k.VKey; else /*if (k.Flags == RI_KEY_MAKE || k.Flags == (RI_KEY_MAKE | RI_KEY_E0) || k.Flags == (RI_KEY_MAKE | RI_KEY_E1))*/
//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
{ {
if(this->keys[key].isDown) if(this->keys[key].isDown)
{ {
for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++) this->InternalOnKeyDown(key);
{
if(this->keyEventSubscrivers[i]) keyboardEventData.key = key;
{ keyboardEventData.sender = this;
this->keyEventSubscrivers[i]->OnKeyDown(key, GetAsText(key), this); keyboardEventData.state = Enum::ButtonState_Down;
} InternalOnEvent(keyboardEventData);
}
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;
}
} }
else else
{ {
this->InternalOnKeyPress(key);
this->keys[key].isDown = true; this->keys[key].isDown = true;
this->keys[key].isE0 = isE0; this->keys[key].isE0 = isE0;
this->keys[key].makecode = makeCode; this->keys[key].makecode = keyboard.MakeCode;
for (unsigned int i = 0; i < this->keyEventSubscrivers.size(); i++)
{ keyboardEventData.key = key;
if(this->keyEventSubscrivers[i]) keyboardEventData.sender = this;
{ keyboardEventData.state = Enum::ButtonState_Press;
this->keyEventSubscrivers[i]->OnKeyPress(key, GetAsText(key), this); InternalOnEvent(keyboardEventData);
}
}
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;
}
} }
} }
} }
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( ((int)this->writePos) - 1, (int)(wstring::size_type)0 );
}
else if (this->keys[SAKI_Right].isDown)
{
this->writePos = std::min( this->writePos + 1, this->textTarget->size() );
}
else if (this->keys[SAKI_Enter].isDown || this->keys[SAKI_NumpadEnter].isDown)
{
this->textTarget->insert( this->writePos, 1, '\n');
}
else if ( this->keys[SAKI_Tab].isDown )
{
this->textTarget->insert( this->writePos, 1, '\t');
}
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;
else out_key = SAKI_Delete;
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;
else out_key = SAKI_Left;
break;
case VK_RIGHT:
if (!isE0) out_key = SAKI_Numpad6;
else out_key = SAKI_Right;
break;
case VK_UP:
if (!isE0) out_key = SAKI_Numpad8;
else out_key = SAKI_Up;
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;
}

View File

@ -1,82 +1,200 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// Created by [Dennis Andersen] [2013] // Created by [Dennis Andersen] [2013]
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#include "..\..\Include\Win32\Win32Mouse.h" #include "..\..\Include\Win32\Win32Input.h"
using namespace Input; using namespace Input;
using namespace Input::Enum; using namespace Input::Enum;
using namespace Input::Struct; using namespace Input::Struct;
using namespace Input::Typedefs; using namespace Input::Typedefs;
void MapButton(RAWMOUSE& rawMouse, bool &isUp, Enum::SAMI& btn, int& delta, Struct::SAIPointInt2D& vel, unsigned int& mcode)
Win32Mouse::Win32Mouse()
{ {
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); memset(&this->buttons[0], 0, sizeof(Buttons) * MAXBUTTONS);
} }
Win32Mouse::~Win32Mouse() Win32Mouse::~Win32Mouse()
{ { }
}
bool Win32Mouse::IsBtnUp(Enum::SAMI btn) bool Win32Mouse::IsBtnUp(Enum::SAMI btn) const
{ {
if(btn == SAMI_Unknown) return false; if(btn == SAMI_Unknown) return false;
return !this->buttons[btn].isDown; return !this->buttons[btn].isDown;
} }
bool Win32Mouse::IsBtnDown(Enum::SAMI btn) bool Win32Mouse::IsBtnDown(Enum::SAMI btn) const
{ {
if(btn == SAMI_Unknown) return false; if(btn == SAMI_Unknown) return false;
return this->buttons[btn].isDown; return this->buttons[btn].isDown;
} }
int Win32Mouse::GetWheelDelta() int Win32Mouse::GetWheelDelta() const
{ {
return this->wheelDelta; return this->wheelDelta;
} }
Struct::SAIPoint2D Win32Mouse::GetPixelPosition(Struct::SAIPoint2D targetMem) SAIPointInt2D& Win32Mouse::GetPixelPosition( Struct::SAIPointInt2D &targetMem ) const
{ {
targetMem = this->pixelPos; 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; return targetMem;
} }
void Win32Mouse::ProccessMouseData (bool isUp, Enum::SAMI btn, int delta, Struct::SAIPoint2D velocity, unsigned int makeCode) 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)
{
static MouseEventData mouseEventData;
memset(&mouseEventData, 0, sizeof(MouseEventData));
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) if(velocity.Length() != 0)
{ {
this->pixelPos.x += velocity.x; this->pixelPos.x += velocity.x;
this->pixelPos.y += velocity.y; this->pixelPos.y += velocity.y;
for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) ContainPoint(this->pixelPos, this->windowSize);
{
if(this->mouseSubscribers[i]) InternalOnMove(this->pixelPos, velocity);
this->mouseSubscribers[i]->OnMouseMove(this->pixelPos, this);
} GetNormalizedPosition( mouseEventData.normalizedPos );
MouseCallbackList *w = this->callbackList; mouseEventData.pixelPos = this->pixelPos;
while (w) mouseEventData.velocity = velocity;
{ mouseEventData.buttonState = Enum::ButtonState_Unknown;
if(w->function) mouseEventData.scrollDelta = 0;
if (w->type == MouseCallbackList::CallbackDataType_OnMove) mouseEventData.sender = this;
w->function.mouseMoveCallback(this->pixelPos, this); mouseEventData.type = SAMI::SAMI_MouseMove;
w = w->next;
} InternalOnEvent(mouseEventData);
} }
if(delta != 0) if(delta != 0)
{ {
for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) InternalOnScroll(delta);
{
if(this->mouseSubscribers[i]) GetNormalizedPosition( mouseEventData.normalizedPos );
this->mouseSubscribers[i]->OnMouseScroll(delta, this); mouseEventData.pixelPos = this->pixelPos;
} mouseEventData.buttonState = Enum::ButtonState_Unknown;
MouseCallbackList *w = this->callbackList; mouseEventData.scrollDelta = delta;
while (w) mouseEventData.sender = this;
{ mouseEventData.type = SAMI::SAMI_MouseScroll;
if(w->function)
if (w->type == MouseCallbackList::CallbackDataType_OnMove) InternalOnEvent(mouseEventData);
w->function.mouseScrollCallback(delta, this);
w = w->next;
}
} }
@ -88,54 +206,94 @@ void Win32Mouse::ProccessMouseData (bool isUp, Enum::SAMI btn, int delta, Struct
//The btn is released. //The btn is released.
if(isUp) if(isUp)
{ {
for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) InternalOnBtnRelease(btn);
{
if(this->mouseSubscribers[i]) GetNormalizedPosition( mouseEventData.normalizedPos );
this->mouseSubscribers[i]->OnMouseRelease(btn, this); mouseEventData.pixelPos = this->pixelPos;
} mouseEventData.buttonState = Enum::ButtonState_Release;
MouseCallbackList *w = this->callbackList; mouseEventData.type = btn;
while (w) mouseEventData.sender = this;
{
if(w->function) InternalOnEvent(mouseEventData);
if (w->type == MouseCallbackList::CallbackDataType_OnRelease)
w->function.mouseReleaseCallback(btn, this);
w = w->next;
}
} }
//The btn is pressed. //The btn is pressed.
else else
{ {
//The btn is down since last frame
if(this->buttons[btn].isDown) if(this->buttons[btn].isDown)
{ {
for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) InternalOnBtnDown(btn);
{
if(this->mouseSubscribers[i]) GetNormalizedPosition( mouseEventData.normalizedPos );
this->mouseSubscribers[i]->OnMouseDown(btn, this); mouseEventData.pixelPos = this->pixelPos;
} mouseEventData.buttonState = Enum::ButtonState_Down;
MouseCallbackList *w = this->callbackList; mouseEventData.type = btn;
while (w) mouseEventData.sender = this;
{
if(w->function) InternalOnEvent(mouseEventData);
if (w->type == MouseCallbackList::CallbackDataType_OnDown)
w->function.mouseDownCallback(btn, this);
w = w->next;
}
} }
else else
{ {
for (unsigned int i = 0; i < this->mouseSubscribers.size(); i++) InternalOnBtnPress(btn);
{
if(this->mouseSubscribers[i]) GetNormalizedPosition( mouseEventData.normalizedPos );
this->mouseSubscribers[i]->OnMousePress(btn, this); mouseEventData.pixelPos = this->pixelPos;
} mouseEventData.buttonState = Enum::ButtonState_Press;
MouseCallbackList *w = this->callbackList; mouseEventData.type = btn;
while (w) mouseEventData.sender = this;
{
if(w->function) InternalOnEvent(mouseEventData);
if (w->type == MouseCallbackList::CallbackDataType_OnPress)
w->function.mousePressCallback(btn, this);
w = w->next;
}
} }
} }
} }
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;
}
void Win32Mouse::ToggleDefault( bool toggler )
{
if( toggler )
{
SetCursorPos(this->winCursPos.x, this->winCursPos.y);
ShowCursor(TRUE);
}
else
{
POINT p;
GetCursorPos(&p);
this->winCursPos.x = p.x;
this->winCursPos.y = p.y;
ShowCursor(FALSE);
}
}

View File

@ -77,7 +77,6 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc)
if(!desc.hInstance) desc.hInstance = GetModuleHandle(0); if(!desc.hInstance) desc.hInstance = GetModuleHandle(0);
if(desc.windowSize.x <= 0) desc.windowSize.x = 50; if(desc.windowSize.x <= 0) desc.windowSize.x = 50;
if(desc.windowSize.y <= 0) desc.windowSize.y = 50; if(desc.windowSize.y <= 0) desc.windowSize.y = 50;
__windowShellData.parent = desc.parent; __windowShellData.parent = desc.parent;
__windowShellData.hIns = desc.hInstance; __windowShellData.hIns = desc.hInstance;
@ -111,20 +110,14 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc)
RECT rectW; RECT rectW;
int width;
int height;
DWORD style = desc.windowStyle; DWORD style = desc.windowStyle;
bool windowed = false; bool windowed = false;
width = desc.windowSize.x + GetSystemMetrics(SM_CXFIXEDFRAME)*2; rectW.left = 0;
height = desc.windowSize.y + GetSystemMetrics(SM_CYFIXEDFRAME)*2 + GetSystemMetrics(SM_CYCAPTION); 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) if(__windowShellData.parent)
{ {
rectW.left = 0; rectW.left = 0;
@ -135,6 +128,8 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc)
windowed = true; windowed = true;
} }
AdjustWindowRect(& rectW, style, FALSE);
if(windowed) if(windowed)
{ {
__windowShellData.hWnd = CreateWindowExW( __windowShellData.hWnd = CreateWindowExW(
@ -161,8 +156,8 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc)
style, style,
desc.windowPosition.x, desc.windowPosition.x,
desc.windowPosition.y, desc.windowPosition.y,
desc.windowSize.x, rectW.right - rectW.left,
desc.windowSize.y, rectW.bottom - rectW.top,
0, 0,
0, 0,
__windowShellData.hIns, __windowShellData.hIns,
@ -173,7 +168,6 @@ bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc)
if( !__windowShellData.hWnd ) if( !__windowShellData.hWnd )
{ {
printf("Failed to create window handle : Code ( %ul )", GetLastError()); printf("Failed to create window handle : Code ( %ul )", GetLastError());
//MessageBox(0, L"Failed to create window", L"Error!", 0);
return false; return false;
} }
@ -258,3 +252,4 @@ bool WindowShell::Frame()
return true; return true;
} }

View File

@ -40,7 +40,7 @@ public:
POINT _windowSize = cPOINT(800, 600), POINT _windowSize = cPOINT(800, 600),
POINT _windowPosition = cPOINT(0,0), POINT _windowPosition = cPOINT(0,0),
UINT _windowClassStyle = (CS_HREDRAW | CS_VREDRAW | CS_OWNDC), 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), HICON _icon = LoadIcon(0, IDI_APPLICATION),
HCURSOR _cursor = LoadCursor(NULL, IDC_ARROW), HCURSOR _cursor = LoadCursor(NULL, IDC_ARROW),
HBRUSH _background = (HBRUSH)GetStockObject(BLACK_BRUSH) HBRUSH _background = (HBRUSH)GetStockObject(BLACK_BRUSH)

View File

@ -177,7 +177,6 @@ void SimpleRigidBody::AddRotationAroundY(::Oyster::Math::Float angle)
this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w()); this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w());
} }
void SimpleRigidBody::SetAngularFactor(Float factor) void SimpleRigidBody::SetAngularFactor(Float factor)
{ {
this->rigidBody->setAngularFactor(factor); this->rigidBody->setAngularFactor(factor);
@ -246,18 +245,18 @@ void SimpleRigidBody::SetUp(::Oyster::Math::Float3 up)
btQuaternion q; btQuaternion q;
btVector3 a = v1.cross(v2); btVector3 a = v1.cross(v2);
if (v1.dot(v2) < -0.999999) if (v1.dot(v2) < -0.999999)
{ {
btVector3 xCrossPre = btVector3(1, 0 ,0).cross(v1); btVector3 xCrossPre = btVector3(1, 0 ,0).cross(v1);
if(xCrossPre.length() < 0.000001) if(xCrossPre.length() < 0.000001)
xCrossPre = btVector3(0, 1 ,0).cross(v1); xCrossPre = btVector3(0, 1 ,0).cross(v1);
xCrossPre.normalize(); xCrossPre.normalize();
q.setRotation(xCrossPre, 3.1415); q.setRotation(xCrossPre, 3.1415);
} }
else if (v1.dot(v2) > 0.999999) else if (v1.dot(v2) > 0.999999)
{ {
q = btQuaternion(0, 0, 0, 1); q = btQuaternion(0, 0, 0, 1);
} }
else else
{ {

View File

@ -29,7 +29,7 @@ namespace Oyster
void SetRotation(Math::Quaternion quaternion); void SetRotation(Math::Quaternion quaternion);
void SetRotation(Math::Float3 eulerAngles); void SetRotation(Math::Float3 eulerAngles);
void SetRotation(::Oyster::Math::Float4x4 rotation); void SetRotation(::Oyster::Math::Float4x4 rotation);
void AddRotationAroundY(Math::Float angle); void AddRotationAroundY(::Oyster::Math::Float angle);
void SetAngularFactor(Math::Float factor); void SetAngularFactor(Math::Float factor);
void SetMass(Math::Float mass); void SetMass(Math::Float mass);